From 2e24036ff51f1e4c87bfd01bb376b9719a71ce6d Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 11 Aug 2023 13:58:07 +0400 Subject: [PATCH 001/349] move cert structures into separate module --- rust/json-gen/src/main.rs | 2 + rust/src/error.rs | 7 + rust/src/lib.rs | 624 +---------- .../certificates/certificate.rs | 164 +++ .../certificates/genesis_key_delegation.rs | 49 + rust/src/protocol_types/certificates/mod.rs | 26 + .../move_instantaneous_rewards_cert.rs | 217 ++++ .../certificates/pool_registration.rs | 159 +++ .../certificates/pool_retirement.rs | 39 + .../certificates/stake_delegation.rs | 43 + .../certificates/stake_deregistration.rs | 37 + .../certificates/stake_registration.rs | 33 + rust/src/protocol_types/governance/mod.rs | 2 + rust/src/protocol_types/mod.rs | 9 +- rust/src/ser_info/mod.rs | 1 - .../serialization/certificates/certificate.rs | 149 +++ .../certificates/genesis_key_delegation.rs | 84 ++ rust/src/serialization/certificates/mod.rs | 26 + .../move_instantaneous_rewards_cert.rs | 177 ++++ .../certificates/pool_registration.rs | 216 ++++ .../certificates/pool_retirement.rs | 78 ++ .../certificates/stake_delegation.rs | 79 ++ .../certificates/stake_deregistration.rs | 72 ++ .../certificates/stake_registration.rs | 72 ++ .../general.rs} | 995 +----------------- rust/src/serialization/governance/mod.rs | 2 + rust/src/serialization/mod.rs | 14 + rust/src/serialization/ser_info/mod.rs | 2 + .../src/{ => serialization}/ser_info/types.rs | 0 .../serialization_macros.rs | 2 +- 30 files changed, 1801 insertions(+), 1579 deletions(-) create mode 100644 rust/src/protocol_types/certificates/certificate.rs create mode 100644 rust/src/protocol_types/certificates/genesis_key_delegation.rs create mode 100644 rust/src/protocol_types/certificates/mod.rs create mode 100644 rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs create mode 100644 rust/src/protocol_types/certificates/pool_registration.rs create mode 100644 rust/src/protocol_types/certificates/pool_retirement.rs create mode 100644 rust/src/protocol_types/certificates/stake_delegation.rs create mode 100644 rust/src/protocol_types/certificates/stake_deregistration.rs create mode 100644 rust/src/protocol_types/certificates/stake_registration.rs create mode 100644 rust/src/protocol_types/governance/mod.rs delete mode 100644 rust/src/ser_info/mod.rs create mode 100644 rust/src/serialization/certificates/certificate.rs create mode 100644 rust/src/serialization/certificates/genesis_key_delegation.rs create mode 100644 rust/src/serialization/certificates/mod.rs create mode 100644 rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs create mode 100644 rust/src/serialization/certificates/pool_registration.rs create mode 100644 rust/src/serialization/certificates/pool_retirement.rs create mode 100644 rust/src/serialization/certificates/stake_delegation.rs create mode 100644 rust/src/serialization/certificates/stake_deregistration.rs create mode 100644 rust/src/serialization/certificates/stake_registration.rs rename rust/src/{serialization.rs => serialization/general.rs} (84%) create mode 100644 rust/src/serialization/governance/mod.rs create mode 100644 rust/src/serialization/mod.rs create mode 100644 rust/src/serialization/ser_info/mod.rs rename rust/src/{ => serialization}/ser_info/types.rs (100%) rename rust/src/{ => serialization}/serialization_macros.rs (99%) diff --git a/rust/json-gen/src/main.rs b/rust/json-gen/src/main.rs index 59d656ae..45e12782 100644 --- a/rust/json-gen/src/main.rs +++ b/rust/json-gen/src/main.rs @@ -156,4 +156,6 @@ fn main() { gen_json_schema!(Value); gen_json_schema!(TransactionUnspentOutput); gen_json_schema!(TransactionUnspentOutputs); + + gen_json_schema!(DRep); } diff --git a/rust/src/error.rs b/rust/src/error.rs index 6a209ce7..61133a76 100644 --- a/rust/src/error.rs +++ b/rust/src/error.rs @@ -34,6 +34,10 @@ pub enum DeserializeFailure { found: Key, expected: Key, }, + FixedValuesMismatch { + found: Key, + expected: Vec, + }, MandatoryFieldMissing(Key), Metadata(JsError), NoVariantMatched, @@ -104,6 +108,9 @@ impl std::fmt::Display for DeserializeError { DeserializeFailure::FixedValueMismatch { found, expected } => { write!(f, "Expected fixed value {} found {}", expected, found) } + DeserializeFailure::FixedValuesMismatch { found, expected } => { + write!(f, "Expected fixed value {:?} found {}", expected, found) + } DeserializeFailure::MandatoryFieldMissing(key) => { write!(f, "Mandatory field {} not found", key) } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index f10515a2..88f2de4f 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -47,18 +47,16 @@ pub mod legacy_address; pub mod metadata; pub mod output_builder; pub mod plutus; -pub mod serialization; pub mod traits; pub mod tx_builder; pub mod tx_builder_constants; pub mod typed_bytes; -pub mod protocol_types; -pub mod ser_info; +mod protocol_types; #[macro_use] pub mod utils; mod fakes; -mod serialization_macros; mod serialization_tools; +mod serialization; use crate::traits::NoneOrEmpty; use address::*; @@ -72,7 +70,8 @@ use std::collections::BTreeSet; use std::fmt::Display; use std::fmt; use utils::*; -use ser_info::types::*; +use serialization::*; +use protocol_types::*; type DeltaCoin = Int; @@ -695,89 +694,6 @@ impl PartialEq for TransactionOutput { } } -#[wasm_bindgen] -#[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct StakeRegistration { - stake_credential: StakeCredential, -} - -impl_to_from!(StakeRegistration); - -#[wasm_bindgen] -impl StakeRegistration { - pub fn stake_credential(&self) -> StakeCredential { - self.stake_credential.clone() - } - - pub fn new(stake_credential: &StakeCredential) -> Self { - Self { - stake_credential: stake_credential.clone(), - } - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct StakeDeregistration { - pub(crate) stake_credential: StakeCredential, -} - -impl_to_from!(StakeDeregistration); - -#[wasm_bindgen] -impl StakeDeregistration { - pub fn stake_credential(&self) -> StakeCredential { - self.stake_credential.clone() - } - - pub fn new(stake_credential: &StakeCredential) -> Self { - Self { - stake_credential: stake_credential.clone(), - } - } - - pub fn has_script_credentials(&self) -> bool { - self.stake_credential.has_script_hash() - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct StakeDelegation { - stake_credential: StakeCredential, - pool_keyhash: Ed25519KeyHash, -} - -impl_to_from!(StakeDelegation); - -#[wasm_bindgen] -impl StakeDelegation { - pub fn stake_credential(&self) -> StakeCredential { - self.stake_credential.clone() - } - - pub fn pool_keyhash(&self) -> Ed25519KeyHash { - self.pool_keyhash.clone() - } - - pub fn new(stake_credential: &StakeCredential, pool_keyhash: &Ed25519KeyHash) -> Self { - Self { - stake_credential: stake_credential.clone(), - pool_keyhash: pool_keyhash.clone(), - } - } - - pub fn has_script_credentials(&self) -> bool { - self.stake_credential.has_script_hash() - } -} - #[wasm_bindgen] #[derive( Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, @@ -822,538 +738,6 @@ impl IntoIterator for Ed25519KeyHashes { } } -#[wasm_bindgen] -#[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct Relays(Vec); - -impl_to_from!(Relays); - -#[wasm_bindgen] -impl Relays { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> Relay { - self.0[index].clone() - } - - pub fn add(&mut self, elem: &Relay) { - self.0.push(elem.clone()); - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct PoolParams { - operator: Ed25519KeyHash, - vrf_keyhash: VRFKeyHash, - pledge: Coin, - cost: Coin, - margin: UnitInterval, - reward_account: RewardAddress, - pool_owners: Ed25519KeyHashes, - relays: Relays, - pool_metadata: Option, -} - -impl_to_from!(PoolParams); - -#[wasm_bindgen] -impl PoolParams { - pub fn operator(&self) -> Ed25519KeyHash { - self.operator.clone() - } - - pub fn vrf_keyhash(&self) -> VRFKeyHash { - self.vrf_keyhash.clone() - } - - pub fn pledge(&self) -> Coin { - self.pledge.clone() - } - - pub fn cost(&self) -> Coin { - self.cost.clone() - } - - pub fn margin(&self) -> UnitInterval { - self.margin.clone() - } - - pub fn reward_account(&self) -> RewardAddress { - self.reward_account.clone() - } - - pub fn pool_owners(&self) -> Ed25519KeyHashes { - self.pool_owners.clone() - } - - pub fn relays(&self) -> Relays { - self.relays.clone() - } - - pub fn pool_metadata(&self) -> Option { - self.pool_metadata.clone() - } - - pub fn new( - operator: &Ed25519KeyHash, - vrf_keyhash: &VRFKeyHash, - pledge: &Coin, - cost: &Coin, - margin: &UnitInterval, - reward_account: &RewardAddress, - pool_owners: &Ed25519KeyHashes, - relays: &Relays, - pool_metadata: Option, - ) -> Self { - Self { - operator: operator.clone(), - vrf_keyhash: vrf_keyhash.clone(), - pledge: pledge.clone(), - cost: cost.clone(), - margin: margin.clone(), - reward_account: reward_account.clone(), - pool_owners: pool_owners.clone(), - relays: relays.clone(), - pool_metadata: pool_metadata.clone(), - } - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct PoolRegistration { - pool_params: PoolParams, -} - -impl_to_from!(PoolRegistration); - -#[wasm_bindgen] -impl PoolRegistration { - pub fn pool_params(&self) -> PoolParams { - self.pool_params.clone() - } - - pub fn new(pool_params: &PoolParams) -> Self { - Self { - pool_params: pool_params.clone(), - } - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct PoolRetirement { - pool_keyhash: Ed25519KeyHash, - epoch: Epoch, -} - -impl_to_from!(PoolRetirement); - -#[wasm_bindgen] -impl PoolRetirement { - pub fn pool_keyhash(&self) -> Ed25519KeyHash { - self.pool_keyhash.clone() - } - - pub fn epoch(&self) -> Epoch { - self.epoch.clone() - } - - pub fn new(pool_keyhash: &Ed25519KeyHash, epoch: Epoch) -> Self { - Self { - pool_keyhash: pool_keyhash.clone(), - epoch: epoch, - } - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct GenesisKeyDelegation { - genesishash: GenesisHash, - genesis_delegate_hash: GenesisDelegateHash, - vrf_keyhash: VRFKeyHash, -} - -impl_to_from!(GenesisKeyDelegation); - -#[wasm_bindgen] -impl GenesisKeyDelegation { - pub fn genesishash(&self) -> GenesisHash { - self.genesishash.clone() - } - - pub fn genesis_delegate_hash(&self) -> GenesisDelegateHash { - self.genesis_delegate_hash.clone() - } - - pub fn vrf_keyhash(&self) -> VRFKeyHash { - self.vrf_keyhash.clone() - } - - pub fn new( - genesishash: &GenesisHash, - genesis_delegate_hash: &GenesisDelegateHash, - vrf_keyhash: &VRFKeyHash, - ) -> Self { - Self { - genesishash: genesishash.clone(), - genesis_delegate_hash: genesis_delegate_hash.clone(), - vrf_keyhash: vrf_keyhash.clone(), - } - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct MoveInstantaneousRewardsCert { - move_instantaneous_reward: MoveInstantaneousReward, -} - -impl_to_from!(MoveInstantaneousRewardsCert); - -#[wasm_bindgen] -impl MoveInstantaneousRewardsCert { - pub fn move_instantaneous_reward(&self) -> MoveInstantaneousReward { - self.move_instantaneous_reward.clone() - } - - pub fn new(move_instantaneous_reward: &MoveInstantaneousReward) -> Self { - Self { - move_instantaneous_reward: move_instantaneous_reward.clone(), - } - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub enum CertificateKind { - StakeRegistration, - StakeDeregistration, - StakeDelegation, - PoolRegistration, - PoolRetirement, - GenesisKeyDelegation, - MoveInstantaneousRewardsCert, -} - -#[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub enum CertificateEnum { - StakeRegistration(StakeRegistration), - StakeDeregistration(StakeDeregistration), - StakeDelegation(StakeDelegation), - PoolRegistration(PoolRegistration), - PoolRetirement(PoolRetirement), - GenesisKeyDelegation(GenesisKeyDelegation), - MoveInstantaneousRewardsCert(MoveInstantaneousRewardsCert), -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct Certificate(CertificateEnum); - -impl_to_from!(Certificate); - -#[wasm_bindgen] -impl Certificate { - pub fn new_stake_registration(stake_registration: &StakeRegistration) -> Self { - Self(CertificateEnum::StakeRegistration( - stake_registration.clone(), - )) - } - - pub fn new_stake_deregistration(stake_deregistration: &StakeDeregistration) -> Self { - Self(CertificateEnum::StakeDeregistration( - stake_deregistration.clone(), - )) - } - - pub fn new_stake_delegation(stake_delegation: &StakeDelegation) -> Self { - Self(CertificateEnum::StakeDelegation(stake_delegation.clone())) - } - - pub fn new_pool_registration(pool_registration: &PoolRegistration) -> Self { - Self(CertificateEnum::PoolRegistration(pool_registration.clone())) - } - - pub fn new_pool_retirement(pool_retirement: &PoolRetirement) -> Self { - Self(CertificateEnum::PoolRetirement(pool_retirement.clone())) - } - - pub fn new_genesis_key_delegation(genesis_key_delegation: &GenesisKeyDelegation) -> Self { - Self(CertificateEnum::GenesisKeyDelegation( - genesis_key_delegation.clone(), - )) - } - - pub fn new_move_instantaneous_rewards_cert( - move_instantaneous_rewards_cert: &MoveInstantaneousRewardsCert, - ) -> Self { - Self(CertificateEnum::MoveInstantaneousRewardsCert( - move_instantaneous_rewards_cert.clone(), - )) - } - - pub fn kind(&self) -> CertificateKind { - match &self.0 { - CertificateEnum::StakeRegistration(_) => CertificateKind::StakeRegistration, - CertificateEnum::StakeDeregistration(_) => CertificateKind::StakeDeregistration, - CertificateEnum::StakeDelegation(_) => CertificateKind::StakeDelegation, - CertificateEnum::PoolRegistration(_) => CertificateKind::PoolRegistration, - CertificateEnum::PoolRetirement(_) => CertificateKind::PoolRetirement, - CertificateEnum::GenesisKeyDelegation(_) => CertificateKind::GenesisKeyDelegation, - CertificateEnum::MoveInstantaneousRewardsCert(_) => { - CertificateKind::MoveInstantaneousRewardsCert - } - } - } - - pub fn as_stake_registration(&self) -> Option { - match &self.0 { - CertificateEnum::StakeRegistration(x) => Some(x.clone()), - _ => None, - } - } - - pub fn as_stake_deregistration(&self) -> Option { - match &self.0 { - CertificateEnum::StakeDeregistration(x) => Some(x.clone()), - _ => None, - } - } - - pub fn as_stake_delegation(&self) -> Option { - match &self.0 { - CertificateEnum::StakeDelegation(x) => Some(x.clone()), - _ => None, - } - } - - pub fn as_pool_registration(&self) -> Option { - match &self.0 { - CertificateEnum::PoolRegistration(x) => Some(x.clone()), - _ => None, - } - } - - pub fn as_pool_retirement(&self) -> Option { - match &self.0 { - CertificateEnum::PoolRetirement(x) => Some(x.clone()), - _ => None, - } - } - - pub fn as_genesis_key_delegation(&self) -> Option { - match &self.0 { - CertificateEnum::GenesisKeyDelegation(x) => Some(x.clone()), - _ => None, - } - } - - pub fn as_move_instantaneous_rewards_cert(&self) -> Option { - match &self.0 { - CertificateEnum::MoveInstantaneousRewardsCert(x) => Some(x.clone()), - _ => None, - } - } - - pub fn has_required_script_witness(&self) -> bool { - match &self.0 { - CertificateEnum::StakeDeregistration(x) => x.has_script_credentials(), - CertificateEnum::StakeDelegation(x) => x.has_script_credentials(), - _ => false, - } - } -} - -#[wasm_bindgen] -#[derive( - Clone, - Copy, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub enum MIRPot { - Reserves, - Treasury, -} - -#[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub enum MIREnum { - ToOtherPot(Coin), - ToStakeCredentials(MIRToStakeCredentials), -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub enum MIRKind { - ToOtherPot, - ToStakeCredentials, -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)] -pub struct MIRToStakeCredentials { - rewards: linked_hash_map::LinkedHashMap, -} - -impl_to_from!(MIRToStakeCredentials); - -#[wasm_bindgen] -impl MIRToStakeCredentials { - pub fn new() -> Self { - Self { - rewards: linked_hash_map::LinkedHashMap::new(), - } - } - - pub fn len(&self) -> usize { - self.rewards.len() - } - - pub fn insert(&mut self, cred: &StakeCredential, delta: &DeltaCoin) -> Option { - self.rewards.insert(cred.clone(), delta.clone()) - } - - pub fn get(&self, cred: &StakeCredential) -> Option { - self.rewards.get(cred).map(|v| v.clone()) - } - - pub fn keys(&self) -> StakeCredentials { - StakeCredentials( - self.rewards - .iter() - .map(|(k, _v)| k.clone()) - .collect::>(), - ) - } -} - -impl serde::Serialize for MIRToStakeCredentials { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let map = self - .rewards - .iter() - .collect::>(); - map.serialize(serializer) - } -} - -impl<'de> serde::de::Deserialize<'de> for MIRToStakeCredentials { - fn deserialize(deserializer: D) -> Result - where - D: serde::de::Deserializer<'de>, - { - let map = as serde::de::Deserialize>::deserialize( - deserializer, - )?; - Ok(Self { - rewards: map.into_iter().collect(), - }) - } -} - -impl JsonSchema for MIRToStakeCredentials { - fn schema_name() -> String { - String::from("MIRToStakeCredentials") - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - std::collections::BTreeMap::::json_schema(gen) - } - fn is_referenceable() -> bool { - std::collections::BTreeMap::::is_referenceable() - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct MoveInstantaneousReward { - pot: MIRPot, - variant: MIREnum, -} - -impl_to_from!(MoveInstantaneousReward); - -#[wasm_bindgen] -impl MoveInstantaneousReward { - pub fn new_to_other_pot(pot: MIRPot, amount: &Coin) -> Self { - Self { - pot, - variant: MIREnum::ToOtherPot(amount.clone()), - } - } - - pub fn new_to_stake_creds(pot: MIRPot, amounts: &MIRToStakeCredentials) -> Self { - Self { - pot, - variant: MIREnum::ToStakeCredentials(amounts.clone()), - } - } - - pub fn pot(&self) -> MIRPot { - self.pot - } - - pub fn kind(&self) -> MIRKind { - match &self.variant { - MIREnum::ToOtherPot(_) => MIRKind::ToOtherPot, - MIREnum::ToStakeCredentials(_) => MIRKind::ToStakeCredentials, - } - } - - pub fn as_to_other_pot(&self) -> Option { - match &self.variant { - MIREnum::ToOtherPot(amount) => Some(amount.clone()), - MIREnum::ToStakeCredentials(_) => None, - } - } - - pub fn as_to_stake_creds(&self) -> Option { - match &self.variant { - MIREnum::ToOtherPot(_) => None, - MIREnum::ToStakeCredentials(amounts) => Some(amounts.clone()), - } - } -} type Port = u16; diff --git a/rust/src/protocol_types/certificates/certificate.rs b/rust/src/protocol_types/certificates/certificate.rs new file mode 100644 index 00000000..cb1af3a7 --- /dev/null +++ b/rust/src/protocol_types/certificates/certificate.rs @@ -0,0 +1,164 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub enum CertificateKind { + StakeRegistration, + StakeDeregistration, + StakeDelegation, + PoolRegistration, + PoolRetirement, + GenesisKeyDelegation, + MoveInstantaneousRewardsCert, +} + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub enum CertificateEnum { + StakeRegistration(StakeRegistration), + StakeDeregistration(StakeDeregistration), + StakeDelegation(StakeDelegation), + PoolRegistration(PoolRegistration), + PoolRetirement(PoolRetirement), + GenesisKeyDelegation(GenesisKeyDelegation), + MoveInstantaneousRewardsCert(MoveInstantaneousRewardsCert), +} + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct Certificate(pub(crate) CertificateEnum); + +impl_to_from!(Certificate); + +#[wasm_bindgen] +impl Certificate { + pub fn new_stake_registration(stake_registration: &StakeRegistration) -> Self { + Self(CertificateEnum::StakeRegistration( + stake_registration.clone(), + )) + } + + pub fn new_stake_deregistration(stake_deregistration: &StakeDeregistration) -> Self { + Self(CertificateEnum::StakeDeregistration( + stake_deregistration.clone(), + )) + } + + pub fn new_stake_delegation(stake_delegation: &StakeDelegation) -> Self { + Self(CertificateEnum::StakeDelegation(stake_delegation.clone())) + } + + pub fn new_pool_registration(pool_registration: &PoolRegistration) -> Self { + Self(CertificateEnum::PoolRegistration(pool_registration.clone())) + } + + pub fn new_pool_retirement(pool_retirement: &PoolRetirement) -> Self { + Self(CertificateEnum::PoolRetirement(pool_retirement.clone())) + } + + pub fn new_genesis_key_delegation(genesis_key_delegation: &GenesisKeyDelegation) -> Self { + Self(CertificateEnum::GenesisKeyDelegation( + genesis_key_delegation.clone(), + )) + } + + pub fn new_move_instantaneous_rewards_cert( + move_instantaneous_rewards_cert: &MoveInstantaneousRewardsCert, + ) -> Self { + Self(CertificateEnum::MoveInstantaneousRewardsCert( + move_instantaneous_rewards_cert.clone(), + )) + } + + pub fn kind(&self) -> CertificateKind { + match &self.0 { + CertificateEnum::StakeRegistration(_) => CertificateKind::StakeRegistration, + CertificateEnum::StakeDeregistration(_) => CertificateKind::StakeDeregistration, + CertificateEnum::StakeDelegation(_) => CertificateKind::StakeDelegation, + CertificateEnum::PoolRegistration(_) => CertificateKind::PoolRegistration, + CertificateEnum::PoolRetirement(_) => CertificateKind::PoolRetirement, + CertificateEnum::GenesisKeyDelegation(_) => CertificateKind::GenesisKeyDelegation, + CertificateEnum::MoveInstantaneousRewardsCert(_) => { + CertificateKind::MoveInstantaneousRewardsCert + } + } + } + + pub fn as_stake_registration(&self) -> Option { + match &self.0 { + CertificateEnum::StakeRegistration(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_stake_deregistration(&self) -> Option { + match &self.0 { + CertificateEnum::StakeDeregistration(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_stake_delegation(&self) -> Option { + match &self.0 { + CertificateEnum::StakeDelegation(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_pool_registration(&self) -> Option { + match &self.0 { + CertificateEnum::PoolRegistration(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_pool_retirement(&self) -> Option { + match &self.0 { + CertificateEnum::PoolRetirement(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_genesis_key_delegation(&self) -> Option { + match &self.0 { + CertificateEnum::GenesisKeyDelegation(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_move_instantaneous_rewards_cert(&self) -> Option { + match &self.0 { + CertificateEnum::MoveInstantaneousRewardsCert(x) => Some(x.clone()), + _ => None, + } + } + + pub fn has_required_script_witness(&self) -> bool { + match &self.0 { + CertificateEnum::StakeDeregistration(x) => x.has_script_credentials(), + CertificateEnum::StakeDelegation(x) => x.has_script_credentials(), + _ => false, + } + } +} diff --git a/rust/src/protocol_types/certificates/genesis_key_delegation.rs b/rust/src/protocol_types/certificates/genesis_key_delegation.rs new file mode 100644 index 00000000..93a118ad --- /dev/null +++ b/rust/src/protocol_types/certificates/genesis_key_delegation.rs @@ -0,0 +1,49 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct GenesisKeyDelegation { + pub(crate) genesishash: GenesisHash, + pub(crate) genesis_delegate_hash: GenesisDelegateHash, + pub(crate) vrf_keyhash: VRFKeyHash, +} + +impl_to_from!(GenesisKeyDelegation); + +#[wasm_bindgen] +impl GenesisKeyDelegation { + pub fn genesishash(&self) -> GenesisHash { + self.genesishash.clone() + } + + pub fn genesis_delegate_hash(&self) -> GenesisDelegateHash { + self.genesis_delegate_hash.clone() + } + + pub fn vrf_keyhash(&self) -> VRFKeyHash { + self.vrf_keyhash.clone() + } + + pub fn new( + genesishash: &GenesisHash, + genesis_delegate_hash: &GenesisDelegateHash, + vrf_keyhash: &VRFKeyHash, + ) -> Self { + Self { + genesishash: genesishash.clone(), + genesis_delegate_hash: genesis_delegate_hash.clone(), + vrf_keyhash: vrf_keyhash.clone(), + } + } +} diff --git a/rust/src/protocol_types/certificates/mod.rs b/rust/src/protocol_types/certificates/mod.rs new file mode 100644 index 00000000..09ba72fa --- /dev/null +++ b/rust/src/protocol_types/certificates/mod.rs @@ -0,0 +1,26 @@ +mod certificate; +pub use certificate::*; + +mod genesis_key_delegation; +pub use genesis_key_delegation::*; + +mod move_instantaneous_rewards_cert; +pub use move_instantaneous_rewards_cert::*; + +mod pool_registration; +pub use pool_registration::*; + +mod pool_retirement; +pub use pool_retirement::*; + +mod stake_delegation; +pub use stake_delegation::*; + +mod stake_deregistration; +pub use stake_deregistration::*; + +mod stake_registration; +pub use stake_registration::*; + +mod vote_delegation; +pub use vote_delegation::*; \ No newline at end of file diff --git a/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs b/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs new file mode 100644 index 00000000..28a5556f --- /dev/null +++ b/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs @@ -0,0 +1,217 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct MoveInstantaneousRewardsCert { + pub(crate) move_instantaneous_reward: MoveInstantaneousReward, +} + +impl_to_from!(MoveInstantaneousRewardsCert); + +#[wasm_bindgen] +impl MoveInstantaneousRewardsCert { + pub fn move_instantaneous_reward(&self) -> MoveInstantaneousReward { + self.move_instantaneous_reward.clone() + } + + pub fn new(move_instantaneous_reward: &MoveInstantaneousReward) -> Self { + Self { + move_instantaneous_reward: move_instantaneous_reward.clone(), + } + } +} + +#[wasm_bindgen] +#[derive( + Clone, + Copy, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub enum MIRPot { + Reserves, + Treasury, +} + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub enum MIREnum { + ToOtherPot(Coin), + ToStakeCredentials(MIRToStakeCredentials), +} + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub enum MIRKind { + ToOtherPot, + ToStakeCredentials, +} + +#[wasm_bindgen] +#[derive(Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)] +pub struct MIRToStakeCredentials { + pub(crate) rewards: linked_hash_map::LinkedHashMap, +} + +impl_to_from!(MIRToStakeCredentials); + +#[wasm_bindgen] +impl MIRToStakeCredentials { + pub fn new() -> Self { + Self { + rewards: linked_hash_map::LinkedHashMap::new(), + } + } + + pub fn len(&self) -> usize { + self.rewards.len() + } + + pub fn insert(&mut self, cred: &StakeCredential, delta: &DeltaCoin) -> Option { + self.rewards.insert(cred.clone(), delta.clone()) + } + + pub fn get(&self, cred: &StakeCredential) -> Option { + self.rewards.get(cred).map(|v| v.clone()) + } + + pub fn keys(&self) -> StakeCredentials { + StakeCredentials( + self.rewards + .iter() + .map(|(k, _v)| k.clone()) + .collect::>(), + ) + } +} + +impl serde::Serialize for MIRToStakeCredentials { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let map = self + .rewards + .iter() + .collect::>(); + map.serialize(serializer) + } +} + +impl<'de> serde::de::Deserialize<'de> for MIRToStakeCredentials { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let map = as serde::de::Deserialize>::deserialize( + deserializer, + )?; + Ok(Self { + rewards: map.into_iter().collect(), + }) + } +} + +impl JsonSchema for MIRToStakeCredentials { + fn schema_name() -> String { + String::from("MIRToStakeCredentials") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + std::collections::BTreeMap::::json_schema(gen) + } + fn is_referenceable() -> bool { + std::collections::BTreeMap::::is_referenceable() + } +} + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct MoveInstantaneousReward { + pub(crate) pot: MIRPot, + pub(crate) variant: MIREnum, +} + +impl_to_from!(MoveInstantaneousReward); + +#[wasm_bindgen] +impl MoveInstantaneousReward { + pub fn new_to_other_pot(pot: MIRPot, amount: &Coin) -> Self { + Self { + pot, + variant: MIREnum::ToOtherPot(amount.clone()), + } + } + + pub fn new_to_stake_creds(pot: MIRPot, amounts: &MIRToStakeCredentials) -> Self { + Self { + pot, + variant: MIREnum::ToStakeCredentials(amounts.clone()), + } + } + + pub fn pot(&self) -> MIRPot { + self.pot + } + + pub fn kind(&self) -> MIRKind { + match &self.variant { + MIREnum::ToOtherPot(_) => MIRKind::ToOtherPot, + MIREnum::ToStakeCredentials(_) => MIRKind::ToStakeCredentials, + } + } + + pub fn as_to_other_pot(&self) -> Option { + match &self.variant { + MIREnum::ToOtherPot(amount) => Some(amount.clone()), + MIREnum::ToStakeCredentials(_) => None, + } + } + + pub fn as_to_stake_creds(&self) -> Option { + match &self.variant { + MIREnum::ToOtherPot(_) => None, + MIREnum::ToStakeCredentials(amounts) => Some(amounts.clone()), + } + } +} diff --git a/rust/src/protocol_types/certificates/pool_registration.rs b/rust/src/protocol_types/certificates/pool_registration.rs new file mode 100644 index 00000000..80904fd8 --- /dev/null +++ b/rust/src/protocol_types/certificates/pool_registration.rs @@ -0,0 +1,159 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct PoolRegistration { + pub(crate) pool_params: PoolParams, +} + +impl_to_from!(PoolRegistration); + +#[wasm_bindgen] +impl PoolRegistration { + pub fn pool_params(&self) -> PoolParams { + self.pool_params.clone() + } + + pub fn new(pool_params: &PoolParams) -> Self { + Self { + pool_params: pool_params.clone(), + } + } +} + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct Relays(pub(crate) Vec); + +impl_to_from!(Relays); + +#[wasm_bindgen] +impl Relays { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> Relay { + self.0[index].clone() + } + + pub fn add(&mut self, elem: &Relay) { + self.0.push(elem.clone()); + } +} + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct PoolParams { + pub(crate) operator: Ed25519KeyHash, + pub(crate) vrf_keyhash: VRFKeyHash, + pub(crate) pledge: Coin, + pub(crate) cost: Coin, + pub(crate) margin: UnitInterval, + pub(crate) reward_account: RewardAddress, + pub(crate) pool_owners: Ed25519KeyHashes, + pub(crate) relays: Relays, + pub(crate) pool_metadata: Option, +} + +impl_to_from!(PoolParams); + +#[wasm_bindgen] +impl PoolParams { + pub fn operator(&self) -> Ed25519KeyHash { + self.operator.clone() + } + + pub fn vrf_keyhash(&self) -> VRFKeyHash { + self.vrf_keyhash.clone() + } + + pub fn pledge(&self) -> Coin { + self.pledge.clone() + } + + pub fn cost(&self) -> Coin { + self.cost.clone() + } + + pub fn margin(&self) -> UnitInterval { + self.margin.clone() + } + + pub fn reward_account(&self) -> RewardAddress { + self.reward_account.clone() + } + + pub fn pool_owners(&self) -> Ed25519KeyHashes { + self.pool_owners.clone() + } + + pub fn relays(&self) -> Relays { + self.relays.clone() + } + + pub fn pool_metadata(&self) -> Option { + self.pool_metadata.clone() + } + + pub fn new( + operator: &Ed25519KeyHash, + vrf_keyhash: &VRFKeyHash, + pledge: &Coin, + cost: &Coin, + margin: &UnitInterval, + reward_account: &RewardAddress, + pool_owners: &Ed25519KeyHashes, + relays: &Relays, + pool_metadata: Option, + ) -> Self { + Self { + operator: operator.clone(), + vrf_keyhash: vrf_keyhash.clone(), + pledge: pledge.clone(), + cost: cost.clone(), + margin: margin.clone(), + reward_account: reward_account.clone(), + pool_owners: pool_owners.clone(), + relays: relays.clone(), + pool_metadata: pool_metadata.clone(), + } + } +} diff --git a/rust/src/protocol_types/certificates/pool_retirement.rs b/rust/src/protocol_types/certificates/pool_retirement.rs new file mode 100644 index 00000000..f8eb060e --- /dev/null +++ b/rust/src/protocol_types/certificates/pool_retirement.rs @@ -0,0 +1,39 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct PoolRetirement { + pub(crate) pool_keyhash: Ed25519KeyHash, + pub(crate) epoch: Epoch, +} + +impl_to_from!(PoolRetirement); + +#[wasm_bindgen] +impl PoolRetirement { + pub fn pool_keyhash(&self) -> Ed25519KeyHash { + self.pool_keyhash.clone() + } + + pub fn epoch(&self) -> Epoch { + self.epoch.clone() + } + + pub fn new(pool_keyhash: &Ed25519KeyHash, epoch: Epoch) -> Self { + Self { + pool_keyhash: pool_keyhash.clone(), + epoch: epoch, + } + } +} diff --git a/rust/src/protocol_types/certificates/stake_delegation.rs b/rust/src/protocol_types/certificates/stake_delegation.rs new file mode 100644 index 00000000..4224e26c --- /dev/null +++ b/rust/src/protocol_types/certificates/stake_delegation.rs @@ -0,0 +1,43 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct StakeDelegation { + pub(crate) stake_credential: StakeCredential, + pub(crate) pool_keyhash: Ed25519KeyHash, +} + +impl_to_from!(StakeDelegation); + +#[wasm_bindgen] +impl StakeDelegation { + pub fn stake_credential(&self) -> StakeCredential { + self.stake_credential.clone() + } + + pub fn pool_keyhash(&self) -> Ed25519KeyHash { + self.pool_keyhash.clone() + } + + pub fn new(stake_credential: &StakeCredential, pool_keyhash: &Ed25519KeyHash) -> Self { + Self { + stake_credential: stake_credential.clone(), + pool_keyhash: pool_keyhash.clone(), + } + } + + pub fn has_script_credentials(&self) -> bool { + self.stake_credential.has_script_hash() + } +} diff --git a/rust/src/protocol_types/certificates/stake_deregistration.rs b/rust/src/protocol_types/certificates/stake_deregistration.rs new file mode 100644 index 00000000..5963d651 --- /dev/null +++ b/rust/src/protocol_types/certificates/stake_deregistration.rs @@ -0,0 +1,37 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct StakeDeregistration { + pub(crate) stake_credential: StakeCredential, +} + +impl_to_from!(StakeDeregistration); + +#[wasm_bindgen] +impl StakeDeregistration { + pub fn stake_credential(&self) -> StakeCredential { + self.stake_credential.clone() + } + + pub fn new(stake_credential: &StakeCredential) -> Self { + Self { + stake_credential: stake_credential.clone(), + } + } + + pub fn has_script_credentials(&self) -> bool { + self.stake_credential.has_script_hash() + } +} diff --git a/rust/src/protocol_types/certificates/stake_registration.rs b/rust/src/protocol_types/certificates/stake_registration.rs new file mode 100644 index 00000000..0d024d29 --- /dev/null +++ b/rust/src/protocol_types/certificates/stake_registration.rs @@ -0,0 +1,33 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct StakeRegistration { + pub(crate) stake_credential: StakeCredential, +} + +impl_to_from!(StakeRegistration); + +#[wasm_bindgen] +impl StakeRegistration { + pub fn stake_credential(&self) -> StakeCredential { + self.stake_credential.clone() + } + + pub fn new(stake_credential: &StakeCredential) -> Self { + Self { + stake_credential: stake_credential.clone(), + } + } +} diff --git a/rust/src/protocol_types/governance/mod.rs b/rust/src/protocol_types/governance/mod.rs new file mode 100644 index 00000000..8774ed02 --- /dev/null +++ b/rust/src/protocol_types/governance/mod.rs @@ -0,0 +1,2 @@ +mod drep; +pub use drep::*; \ No newline at end of file diff --git a/rust/src/protocol_types/mod.rs b/rust/src/protocol_types/mod.rs index 7eac86ae..70def29e 100644 --- a/rust/src/protocol_types/mod.rs +++ b/rust/src/protocol_types/mod.rs @@ -1,5 +1,12 @@ //TODO: move all protocol types to this module -pub mod fixed_tx; +mod fixed_tx; +pub use fixed_tx::*; + +mod certificates; +pub use certificates::*; + +mod governance; +pub use governance::*; #[cfg(test)] mod tests; \ No newline at end of file diff --git a/rust/src/ser_info/mod.rs b/rust/src/ser_info/mod.rs deleted file mode 100644 index dd198c6d..00000000 --- a/rust/src/ser_info/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod types; \ No newline at end of file diff --git a/rust/src/serialization/certificates/certificate.rs b/rust/src/serialization/certificates/certificate.rs new file mode 100644 index 00000000..2bc2ee92 --- /dev/null +++ b/rust/src/serialization/certificates/certificate.rs @@ -0,0 +1,149 @@ +use crate::*; +use std::io::{Seek, SeekFrom}; + +impl cbor_event::se::Serialize for CertificateEnum { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + match self { + CertificateEnum::StakeRegistration(x) => x.serialize(serializer), + CertificateEnum::StakeDeregistration(x) => x.serialize(serializer), + CertificateEnum::StakeDelegation(x) => x.serialize(serializer), + CertificateEnum::PoolRegistration(x) => x.serialize(serializer), + CertificateEnum::PoolRetirement(x) => x.serialize(serializer), + CertificateEnum::GenesisKeyDelegation(x) => x.serialize(serializer), + CertificateEnum::MoveInstantaneousRewardsCert(x) => x.serialize(serializer), + } + } +} + +impl Deserialize for CertificateEnum { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let ret = Self::deserialize_as_embedded_group(raw, len); + match len { + cbor_event::Len::Len(_) => + /* TODO: check finite len somewhere */ + { + () + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("CertificateEnum")) + } +} + +impl DeserializeEmbeddedGroup for CertificateEnum { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + let initial_position = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(StakeRegistration::deserialize_as_embedded_group(raw, len)?) + })(raw) + { + Ok(variant) => return Ok(CertificateEnum::StakeRegistration(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(StakeDeregistration::deserialize_as_embedded_group( + raw, len, + )?) + })(raw) + { + Ok(variant) => return Ok(CertificateEnum::StakeDeregistration(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(StakeDelegation::deserialize_as_embedded_group(raw, len)?) + })(raw) + { + Ok(variant) => return Ok(CertificateEnum::StakeDelegation(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(PoolRegistration::deserialize_as_embedded_group(raw, len)?) + })(raw) + { + Ok(variant) => return Ok(CertificateEnum::PoolRegistration(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(PoolRetirement::deserialize_as_embedded_group(raw, len)?) + })(raw) + { + Ok(variant) => return Ok(CertificateEnum::PoolRetirement(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(GenesisKeyDelegation::deserialize_as_embedded_group( + raw, len, + )?) + })(raw) + { + Ok(variant) => return Ok(CertificateEnum::GenesisKeyDelegation(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(MoveInstantaneousRewardsCert::deserialize_as_embedded_group( + raw, len, + )?) + })(raw) + { + Ok(variant) => return Ok(CertificateEnum::MoveInstantaneousRewardsCert(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + Err(DeserializeError::new( + "CertificateEnum", + DeserializeFailure::NoVariantMatched.into(), + )) + } +} + +impl cbor_event::se::Serialize for Certificate { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + self.0.serialize(serializer) + } +} + +impl Deserialize for Certificate { + fn deserialize(raw: &mut Deserializer) -> Result { + Ok(Self(CertificateEnum::deserialize(raw)?)) + } +} diff --git a/rust/src/serialization/certificates/genesis_key_delegation.rs b/rust/src/serialization/certificates/genesis_key_delegation.rs new file mode 100644 index 00000000..6b37758d --- /dev/null +++ b/rust/src/serialization/certificates/genesis_key_delegation.rs @@ -0,0 +1,84 @@ +use crate::*; + +impl cbor_event::se::Serialize for GenesisKeyDelegation { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(4))?; + self.serialize_as_embedded_group(serializer) + } +} + +impl SerializeEmbeddedGroup for GenesisKeyDelegation { + fn serialize_as_embedded_group<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_unsigned_integer(5u64)?; + self.genesishash.serialize(serializer)?; + self.genesis_delegate_hash.serialize(serializer)?; + self.vrf_keyhash.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for GenesisKeyDelegation { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let ret = Self::deserialize_as_embedded_group(raw, len); + match len { + cbor_event::Len::Len(_) => + /* TODO: check finite len somewhere */ + { + () + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("GenesisKeyDelegation")) + } +} + +impl DeserializeEmbeddedGroup for GenesisKeyDelegation { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + _: cbor_event::Len, + ) -> Result { + (|| -> Result<_, DeserializeError> { + let index_0_value = raw.unsigned_integer()?; + if index_0_value != 5 { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(index_0_value), + expected: Key::Uint(5), + } + .into()); + } + Ok(()) + })() + .map_err(|e| e.annotate("index_0"))?; + let genesishash = + (|| -> Result<_, DeserializeError> { Ok(GenesisHash::deserialize(raw)?) })() + .map_err(|e| e.annotate("genesishash"))?; + let genesis_delegate_hash = + (|| -> Result<_, DeserializeError> { Ok(GenesisDelegateHash::deserialize(raw)?) })() + .map_err(|e| e.annotate("genesis_delegate_hash"))?; + let vrf_keyhash = + (|| -> Result<_, DeserializeError> { Ok(VRFKeyHash::deserialize(raw)?) })() + .map_err(|e| e.annotate("vrf_keyhash"))?; + Ok(GenesisKeyDelegation { + genesishash, + genesis_delegate_hash, + vrf_keyhash, + }) + } +} diff --git a/rust/src/serialization/certificates/mod.rs b/rust/src/serialization/certificates/mod.rs new file mode 100644 index 00000000..09ba72fa --- /dev/null +++ b/rust/src/serialization/certificates/mod.rs @@ -0,0 +1,26 @@ +mod certificate; +pub use certificate::*; + +mod genesis_key_delegation; +pub use genesis_key_delegation::*; + +mod move_instantaneous_rewards_cert; +pub use move_instantaneous_rewards_cert::*; + +mod pool_registration; +pub use pool_registration::*; + +mod pool_retirement; +pub use pool_retirement::*; + +mod stake_delegation; +pub use stake_delegation::*; + +mod stake_deregistration; +pub use stake_deregistration::*; + +mod stake_registration; +pub use stake_registration::*; + +mod vote_delegation; +pub use vote_delegation::*; \ No newline at end of file diff --git a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs new file mode 100644 index 00000000..7f1d1c28 --- /dev/null +++ b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs @@ -0,0 +1,177 @@ +use crate::*; + +impl cbor_event::se::Serialize for MIRToStakeCredentials { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_map(cbor_event::Len::Len(self.rewards.len() as u64))?; + for (key, value) in &self.rewards { + key.serialize(serializer)?; + value.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for MIRToStakeCredentials { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let mut table = linked_hash_map::LinkedHashMap::new(); + let len = raw.map()?; + while match len { + cbor_event::Len::Len(n) => table.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + let key = StakeCredential::deserialize(raw)?; + let value = DeltaCoin::deserialize(raw)?; + if table.insert(key.clone(), value).is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Str(format!( + "StakeCred: {} (hex bytes)", + hex::encode(key.to_bytes()) + ))) + .into()); + } + } + Ok(Self { rewards: table }) + })() + .map_err(|e| e.annotate("MIRToStakeCredentials")) + } +} + +impl cbor_event::se::Serialize for MoveInstantaneousReward { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + match self.pot { + MIRPot::Reserves => serializer.write_unsigned_integer(0u64), + MIRPot::Treasury => serializer.write_unsigned_integer(1u64), + }?; + match &self.variant { + MIREnum::ToOtherPot(amount) => amount.serialize(serializer), + MIREnum::ToStakeCredentials(amounts) => amounts.serialize(serializer), + } + } +} + +impl Deserialize for MoveInstantaneousReward { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let outer_len = raw.array()?; + let pot = match raw.unsigned_integer()? { + 0 => MIRPot::Reserves, + 1 => MIRPot::Treasury, + n => return Err(DeserializeFailure::UnknownKey(Key::Uint(n)).into()), + }; + let variant = match raw.cbor_type()? { + CBORType::UnsignedInteger => MIREnum::ToOtherPot(Coin::deserialize(raw)?), + CBORType::Map => { + MIREnum::ToStakeCredentials(MIRToStakeCredentials::deserialize(raw)?) + } + _ => return Err(DeserializeFailure::NoVariantMatched.into()), + }; + match outer_len { + cbor_event::Len::Len(n) => { + if n != 2 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + n, + outer_len, + "MoveInstantaneousReward", + )) + .into()); + } + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + }; + Ok(Self { pot, variant }) + })() + .map_err(|e| e.annotate("MoveInstantaneousReward")) + } +} + +impl cbor_event::se::Serialize for MoveInstantaneousRewardsCert { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.serialize_as_embedded_group(serializer) + } +} + +impl SerializeEmbeddedGroup for MoveInstantaneousRewardsCert { + fn serialize_as_embedded_group<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_unsigned_integer(6u64)?; + self.move_instantaneous_reward.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for MoveInstantaneousRewardsCert { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let ret = Self::deserialize_as_embedded_group(raw, len); + match len { + cbor_event::Len::Len(_) => + /* TODO: check finite len somewhere */ + { + () + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("MoveInstantaneousRewardsCert")) + } +} + +impl DeserializeEmbeddedGroup for MoveInstantaneousRewardsCert { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + _: cbor_event::Len, + ) -> Result { + (|| -> Result<_, DeserializeError> { + let index_0_value = raw.unsigned_integer()?; + if index_0_value != 6 { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(index_0_value), + expected: Key::Uint(6), + } + .into()); + } + Ok(()) + })() + .map_err(|e| e.annotate("index_0"))?; + let move_instantaneous_reward = + (|| -> Result<_, DeserializeError> { Ok(MoveInstantaneousReward::deserialize(raw)?) })( + ) + .map_err(|e| e.annotate("move_instantaneous_reward"))?; + Ok(MoveInstantaneousRewardsCert { + move_instantaneous_reward, + }) + } +} diff --git a/rust/src/serialization/certificates/pool_registration.rs b/rust/src/serialization/certificates/pool_registration.rs new file mode 100644 index 00000000..012dbfed --- /dev/null +++ b/rust/src/serialization/certificates/pool_registration.rs @@ -0,0 +1,216 @@ +use crate::*; + +impl cbor_event::se::Serialize for Relays { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for Relays { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(Relay::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("Relays"))?; + Ok(Self(arr)) + } +} + +impl cbor_event::se::Serialize for PoolParams { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(9))?; + self.serialize_as_embedded_group(serializer) + } +} + +impl SerializeEmbeddedGroup for PoolParams { + fn serialize_as_embedded_group<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + self.operator.serialize(serializer)?; + self.vrf_keyhash.serialize(serializer)?; + self.pledge.serialize(serializer)?; + self.cost.serialize(serializer)?; + self.margin.serialize(serializer)?; + self.reward_account.serialize(serializer)?; + self.pool_owners.serialize(serializer)?; + self.relays.serialize(serializer)?; + match &self.pool_metadata { + Some(x) => x.serialize(serializer), + None => serializer.write_special(CBORSpecial::Null), + }?; + Ok(serializer) + } +} + +impl Deserialize for PoolParams { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let ret = Self::deserialize_as_embedded_group(raw, len); + match len { + cbor_event::Len::Len(_) => + /* TODO: check finite len somewhere */ + { + () + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("PoolParams")) + } +} + +impl DeserializeEmbeddedGroup for PoolParams { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + _: cbor_event::Len, + ) -> Result { + let operator = + (|| -> Result<_, DeserializeError> { Ok(Ed25519KeyHash::deserialize(raw)?) })() + .map_err(|e| e.annotate("operator"))?; + let vrf_keyhash = + (|| -> Result<_, DeserializeError> { Ok(VRFKeyHash::deserialize(raw)?) })() + .map_err(|e| e.annotate("vrf_keyhash"))?; + let pledge = (|| -> Result<_, DeserializeError> { Ok(Coin::deserialize(raw)?) })() + .map_err(|e| e.annotate("pledge"))?; + let cost = (|| -> Result<_, DeserializeError> { Ok(Coin::deserialize(raw)?) })() + .map_err(|e| e.annotate("cost"))?; + let margin = (|| -> Result<_, DeserializeError> { Ok(UnitInterval::deserialize(raw)?) })() + .map_err(|e| e.annotate("margin"))?; + let reward_account = + (|| -> Result<_, DeserializeError> { Ok(RewardAddress::deserialize(raw)?) })() + .map_err(|e| e.annotate("reward_account"))?; + let pool_owners = + (|| -> Result<_, DeserializeError> { Ok(Ed25519KeyHashes::deserialize(raw)?) })() + .map_err(|e| e.annotate("pool_owners"))?; + let relays = (|| -> Result<_, DeserializeError> { Ok(Relays::deserialize(raw)?) })() + .map_err(|e| e.annotate("relays"))?; + let pool_metadata = (|| -> Result<_, DeserializeError> { + Ok(match raw.cbor_type()? != CBORType::Special { + true => Some(PoolMetadata::deserialize(raw)?), + false => { + if raw.special()? != CBORSpecial::Null { + return Err(DeserializeFailure::ExpectedNull.into()); + } + None + } + }) + })() + .map_err(|e| e.annotate("pool_metadata"))?; + Ok(PoolParams { + operator, + vrf_keyhash, + pledge, + cost, + margin, + reward_account, + pool_owners, + relays, + pool_metadata, + }) + } +} + +impl cbor_event::se::Serialize for PoolRegistration { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(10))?; + self.serialize_as_embedded_group(serializer) + } +} + +impl SerializeEmbeddedGroup for PoolRegistration { + fn serialize_as_embedded_group<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_unsigned_integer(3u64)?; + self.pool_params.serialize_as_embedded_group(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for PoolRegistration { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let ret = Self::deserialize_as_embedded_group(raw, len); + match len { + cbor_event::Len::Len(_) => + /* TODO: check finite len somewhere */ + { + () + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("PoolRegistration")) + } +} + +impl DeserializeEmbeddedGroup for PoolRegistration { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + (|| -> Result<_, DeserializeError> { + let index_0_value = raw.unsigned_integer()?; + if index_0_value != 3 { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(index_0_value), + expected: Key::Uint(3), + } + .into()); + } + Ok(()) + })() + .map_err(|e| e.annotate("index_0"))?; + let pool_params = (|| -> Result<_, DeserializeError> { + Ok(PoolParams::deserialize_as_embedded_group(raw, len)?) + })() + .map_err(|e| e.annotate("pool_params"))?; + Ok(PoolRegistration { pool_params }) + } +} diff --git a/rust/src/serialization/certificates/pool_retirement.rs b/rust/src/serialization/certificates/pool_retirement.rs new file mode 100644 index 00000000..dda03415 --- /dev/null +++ b/rust/src/serialization/certificates/pool_retirement.rs @@ -0,0 +1,78 @@ +use crate::*; + +impl cbor_event::se::Serialize for PoolRetirement { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(3))?; + self.serialize_as_embedded_group(serializer) + } +} + +impl SerializeEmbeddedGroup for PoolRetirement { + fn serialize_as_embedded_group<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_unsigned_integer(4u64)?; + self.pool_keyhash.serialize(serializer)?; + self.epoch.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for PoolRetirement { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let ret = Self::deserialize_as_embedded_group(raw, len); + match len { + cbor_event::Len::Len(_) => + /* TODO: check finite len somewhere */ + { + () + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("PoolRetirement")) + } +} + +impl DeserializeEmbeddedGroup for PoolRetirement { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + _: cbor_event::Len, + ) -> Result { + (|| -> Result<_, DeserializeError> { + let index_0_value = raw.unsigned_integer()?; + if index_0_value != 4 { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(index_0_value), + expected: Key::Uint(4), + } + .into()); + } + Ok(()) + })() + .map_err(|e| e.annotate("index_0"))?; + let pool_keyhash = + (|| -> Result<_, DeserializeError> { Ok(Ed25519KeyHash::deserialize(raw)?) })() + .map_err(|e| e.annotate("pool_keyhash"))?; + let epoch = (|| -> Result<_, DeserializeError> { Ok(Epoch::deserialize(raw)?) })() + .map_err(|e| e.annotate("epoch"))?; + Ok(PoolRetirement { + pool_keyhash, + epoch, + }) + } +} diff --git a/rust/src/serialization/certificates/stake_delegation.rs b/rust/src/serialization/certificates/stake_delegation.rs new file mode 100644 index 00000000..4775918a --- /dev/null +++ b/rust/src/serialization/certificates/stake_delegation.rs @@ -0,0 +1,79 @@ +use crate::*; + +impl cbor_event::se::Serialize for StakeDelegation { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(3))?; + self.serialize_as_embedded_group(serializer) + } +} + +impl SerializeEmbeddedGroup for StakeDelegation { + fn serialize_as_embedded_group<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_unsigned_integer(2u64)?; + self.stake_credential.serialize(serializer)?; + self.pool_keyhash.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for StakeDelegation { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let ret = Self::deserialize_as_embedded_group(raw, len); + match len { + cbor_event::Len::Len(_) => + /* TODO: check finite len somewhere */ + { + () + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("StakeDelegation")) + } +} + +impl DeserializeEmbeddedGroup for StakeDelegation { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + _: cbor_event::Len, + ) -> Result { + (|| -> Result<_, DeserializeError> { + let index_0_value = raw.unsigned_integer()?; + if index_0_value != 2 { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(index_0_value), + expected: Key::Uint(2), + } + .into()); + } + Ok(()) + })() + .map_err(|e| e.annotate("index_0"))?; + let stake_credential = + (|| -> Result<_, DeserializeError> { Ok(StakeCredential::deserialize(raw)?) })() + .map_err(|e| e.annotate("stake_credential"))?; + let pool_keyhash = + (|| -> Result<_, DeserializeError> { Ok(Ed25519KeyHash::deserialize(raw)?) })() + .map_err(|e| e.annotate("pool_keyhash"))?; + Ok(StakeDelegation { + stake_credential, + pool_keyhash, + }) + } +} diff --git a/rust/src/serialization/certificates/stake_deregistration.rs b/rust/src/serialization/certificates/stake_deregistration.rs new file mode 100644 index 00000000..85ab6314 --- /dev/null +++ b/rust/src/serialization/certificates/stake_deregistration.rs @@ -0,0 +1,72 @@ +use crate::*; + +impl cbor_event::se::Serialize for StakeDeregistration { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.serialize_as_embedded_group(serializer) + } +} + +impl SerializeEmbeddedGroup for StakeDeregistration { + fn serialize_as_embedded_group<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_unsigned_integer(1u64)?; + self.stake_credential.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for StakeDeregistration { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let ret = Self::deserialize_as_embedded_group(raw, len); + match len { + cbor_event::Len::Len(_) => + /* TODO: check finite len somewhere */ + { + () + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("StakeDeregistration")) + } +} + +impl DeserializeEmbeddedGroup for StakeDeregistration { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + _: cbor_event::Len, + ) -> Result { + (|| -> Result<_, DeserializeError> { + let index_0_value = raw.unsigned_integer()?; + if index_0_value != 1 { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(index_0_value), + expected: Key::Uint(1), + } + .into()); + } + Ok(()) + })() + .map_err(|e| e.annotate("index_0"))?; + let stake_credential = + (|| -> Result<_, DeserializeError> { Ok(StakeCredential::deserialize(raw)?) })() + .map_err(|e| e.annotate("stake_credential"))?; + Ok(StakeDeregistration { stake_credential }) + } +} diff --git a/rust/src/serialization/certificates/stake_registration.rs b/rust/src/serialization/certificates/stake_registration.rs new file mode 100644 index 00000000..26d16a00 --- /dev/null +++ b/rust/src/serialization/certificates/stake_registration.rs @@ -0,0 +1,72 @@ +use crate::*; + +impl cbor_event::se::Serialize for StakeRegistration { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.serialize_as_embedded_group(serializer) + } +} + +impl SerializeEmbeddedGroup for StakeRegistration { + fn serialize_as_embedded_group<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_unsigned_integer(0u64)?; + self.stake_credential.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for StakeRegistration { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let ret = Self::deserialize_as_embedded_group(raw, len); + match len { + cbor_event::Len::Len(_) => + /* TODO: check finite len somewhere */ + { + () + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("StakeRegistration")) + } +} + +impl DeserializeEmbeddedGroup for StakeRegistration { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + _: cbor_event::Len, + ) -> Result { + (|| -> Result<_, DeserializeError> { + let index_0_value = raw.unsigned_integer()?; + if index_0_value != 0 { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(index_0_value), + expected: Key::Uint(0), + } + .into()); + } + Ok(()) + })() + .map_err(|e| e.annotate("index_0"))?; + let stake_credential = + (|| -> Result<_, DeserializeError> { Ok(StakeCredential::deserialize(raw)?) })() + .map_err(|e| e.annotate("stake_credential"))?; + Ok(StakeRegistration { stake_credential }) + } +} diff --git a/rust/src/serialization.rs b/rust/src/serialization/general.rs similarity index 84% rename from rust/src/serialization.rs rename to rust/src/serialization/general.rs index 6431741f..1fd79831 100644 --- a/rust/src/serialization.rs +++ b/rust/src/serialization/general.rs @@ -1,8 +1,4 @@ -use super::*; -use crate::utils::*; -use address::*; -use crypto::*; -use error::*; +use crate::*; use std::io::{Seek, SeekFrom}; // This file was code-generated using an experimental CDDL to rust tool: @@ -1099,858 +1095,7 @@ impl cbor_event::se::Serialize for ScriptRef { } } -impl cbor_event::se::Serialize for StakeRegistration { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - self.serialize_as_embedded_group(serializer) - } -} - -impl SerializeEmbeddedGroup for StakeRegistration { - fn serialize_as_embedded_group<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(0u64)?; - self.stake_credential.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for StakeRegistration { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("StakeRegistration")) - } -} - -impl DeserializeEmbeddedGroup for StakeRegistration { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - _: cbor_event::Len, - ) -> Result { - (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 0 { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(0), - } - .into()); - } - Ok(()) - })() - .map_err(|e| e.annotate("index_0"))?; - let stake_credential = - (|| -> Result<_, DeserializeError> { Ok(StakeCredential::deserialize(raw)?) })() - .map_err(|e| e.annotate("stake_credential"))?; - Ok(StakeRegistration { stake_credential }) - } -} - -impl cbor_event::se::Serialize for StakeDeregistration { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - self.serialize_as_embedded_group(serializer) - } -} - -impl SerializeEmbeddedGroup for StakeDeregistration { - fn serialize_as_embedded_group<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(1u64)?; - self.stake_credential.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for StakeDeregistration { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("StakeDeregistration")) - } -} - -impl DeserializeEmbeddedGroup for StakeDeregistration { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - _: cbor_event::Len, - ) -> Result { - (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 1 { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(1), - } - .into()); - } - Ok(()) - })() - .map_err(|e| e.annotate("index_0"))?; - let stake_credential = - (|| -> Result<_, DeserializeError> { Ok(StakeCredential::deserialize(raw)?) })() - .map_err(|e| e.annotate("stake_credential"))?; - Ok(StakeDeregistration { stake_credential }) - } -} - -impl cbor_event::se::Serialize for StakeDelegation { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(3))?; - self.serialize_as_embedded_group(serializer) - } -} - -impl SerializeEmbeddedGroup for StakeDelegation { - fn serialize_as_embedded_group<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(2u64)?; - self.stake_credential.serialize(serializer)?; - self.pool_keyhash.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for StakeDelegation { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("StakeDelegation")) - } -} - -impl DeserializeEmbeddedGroup for StakeDelegation { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - _: cbor_event::Len, - ) -> Result { - (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 2 { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(2), - } - .into()); - } - Ok(()) - })() - .map_err(|e| e.annotate("index_0"))?; - let stake_credential = - (|| -> Result<_, DeserializeError> { Ok(StakeCredential::deserialize(raw)?) })() - .map_err(|e| e.annotate("stake_credential"))?; - let pool_keyhash = - (|| -> Result<_, DeserializeError> { Ok(Ed25519KeyHash::deserialize(raw)?) })() - .map_err(|e| e.annotate("pool_keyhash"))?; - Ok(StakeDelegation { - stake_credential, - pool_keyhash, - }) - } -} - -impl cbor_event::se::Serialize for Ed25519KeyHashes { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for Ed25519KeyHashes { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(Ed25519KeyHash::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("Ed25519KeyHashes"))?; - Ok(Self(arr)) - } -} - -impl cbor_event::se::Serialize for Relays { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for Relays { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(Relay::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("Relays"))?; - Ok(Self(arr)) - } -} - -impl cbor_event::se::Serialize for PoolParams { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(9))?; - self.serialize_as_embedded_group(serializer) - } -} - -impl SerializeEmbeddedGroup for PoolParams { - fn serialize_as_embedded_group<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - self.operator.serialize(serializer)?; - self.vrf_keyhash.serialize(serializer)?; - self.pledge.serialize(serializer)?; - self.cost.serialize(serializer)?; - self.margin.serialize(serializer)?; - self.reward_account.serialize(serializer)?; - self.pool_owners.serialize(serializer)?; - self.relays.serialize(serializer)?; - match &self.pool_metadata { - Some(x) => x.serialize(serializer), - None => serializer.write_special(CBORSpecial::Null), - }?; - Ok(serializer) - } -} - -impl Deserialize for PoolParams { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("PoolParams")) - } -} - -impl DeserializeEmbeddedGroup for PoolParams { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - _: cbor_event::Len, - ) -> Result { - let operator = - (|| -> Result<_, DeserializeError> { Ok(Ed25519KeyHash::deserialize(raw)?) })() - .map_err(|e| e.annotate("operator"))?; - let vrf_keyhash = - (|| -> Result<_, DeserializeError> { Ok(VRFKeyHash::deserialize(raw)?) })() - .map_err(|e| e.annotate("vrf_keyhash"))?; - let pledge = (|| -> Result<_, DeserializeError> { Ok(Coin::deserialize(raw)?) })() - .map_err(|e| e.annotate("pledge"))?; - let cost = (|| -> Result<_, DeserializeError> { Ok(Coin::deserialize(raw)?) })() - .map_err(|e| e.annotate("cost"))?; - let margin = (|| -> Result<_, DeserializeError> { Ok(UnitInterval::deserialize(raw)?) })() - .map_err(|e| e.annotate("margin"))?; - let reward_account = - (|| -> Result<_, DeserializeError> { Ok(RewardAddress::deserialize(raw)?) })() - .map_err(|e| e.annotate("reward_account"))?; - let pool_owners = - (|| -> Result<_, DeserializeError> { Ok(Ed25519KeyHashes::deserialize(raw)?) })() - .map_err(|e| e.annotate("pool_owners"))?; - let relays = (|| -> Result<_, DeserializeError> { Ok(Relays::deserialize(raw)?) })() - .map_err(|e| e.annotate("relays"))?; - let pool_metadata = (|| -> Result<_, DeserializeError> { - Ok(match raw.cbor_type()? != CBORType::Special { - true => Some(PoolMetadata::deserialize(raw)?), - false => { - if raw.special()? != CBORSpecial::Null { - return Err(DeserializeFailure::ExpectedNull.into()); - } - None - } - }) - })() - .map_err(|e| e.annotate("pool_metadata"))?; - Ok(PoolParams { - operator, - vrf_keyhash, - pledge, - cost, - margin, - reward_account, - pool_owners, - relays, - pool_metadata, - }) - } -} - -impl cbor_event::se::Serialize for PoolRegistration { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(10))?; - self.serialize_as_embedded_group(serializer) - } -} - -impl SerializeEmbeddedGroup for PoolRegistration { - fn serialize_as_embedded_group<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(3u64)?; - self.pool_params.serialize_as_embedded_group(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for PoolRegistration { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("PoolRegistration")) - } -} - -impl DeserializeEmbeddedGroup for PoolRegistration { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - len: cbor_event::Len, - ) -> Result { - (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 3 { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(3), - } - .into()); - } - Ok(()) - })() - .map_err(|e| e.annotate("index_0"))?; - let pool_params = (|| -> Result<_, DeserializeError> { - Ok(PoolParams::deserialize_as_embedded_group(raw, len)?) - })() - .map_err(|e| e.annotate("pool_params"))?; - Ok(PoolRegistration { pool_params }) - } -} - -impl cbor_event::se::Serialize for PoolRetirement { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(3))?; - self.serialize_as_embedded_group(serializer) - } -} - -impl SerializeEmbeddedGroup for PoolRetirement { - fn serialize_as_embedded_group<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(4u64)?; - self.pool_keyhash.serialize(serializer)?; - self.epoch.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for PoolRetirement { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("PoolRetirement")) - } -} - -impl DeserializeEmbeddedGroup for PoolRetirement { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - _: cbor_event::Len, - ) -> Result { - (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 4 { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(4), - } - .into()); - } - Ok(()) - })() - .map_err(|e| e.annotate("index_0"))?; - let pool_keyhash = - (|| -> Result<_, DeserializeError> { Ok(Ed25519KeyHash::deserialize(raw)?) })() - .map_err(|e| e.annotate("pool_keyhash"))?; - let epoch = (|| -> Result<_, DeserializeError> { Ok(Epoch::deserialize(raw)?) })() - .map_err(|e| e.annotate("epoch"))?; - Ok(PoolRetirement { - pool_keyhash, - epoch, - }) - } -} - -impl cbor_event::se::Serialize for GenesisKeyDelegation { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(4))?; - self.serialize_as_embedded_group(serializer) - } -} - -impl SerializeEmbeddedGroup for GenesisKeyDelegation { - fn serialize_as_embedded_group<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(5u64)?; - self.genesishash.serialize(serializer)?; - self.genesis_delegate_hash.serialize(serializer)?; - self.vrf_keyhash.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for GenesisKeyDelegation { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("GenesisKeyDelegation")) - } -} - -impl DeserializeEmbeddedGroup for GenesisKeyDelegation { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - _: cbor_event::Len, - ) -> Result { - (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 5 { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(5), - } - .into()); - } - Ok(()) - })() - .map_err(|e| e.annotate("index_0"))?; - let genesishash = - (|| -> Result<_, DeserializeError> { Ok(GenesisHash::deserialize(raw)?) })() - .map_err(|e| e.annotate("genesishash"))?; - let genesis_delegate_hash = - (|| -> Result<_, DeserializeError> { Ok(GenesisDelegateHash::deserialize(raw)?) })() - .map_err(|e| e.annotate("genesis_delegate_hash"))?; - let vrf_keyhash = - (|| -> Result<_, DeserializeError> { Ok(VRFKeyHash::deserialize(raw)?) })() - .map_err(|e| e.annotate("vrf_keyhash"))?; - Ok(GenesisKeyDelegation { - genesishash, - genesis_delegate_hash, - vrf_keyhash, - }) - } -} - -impl cbor_event::se::Serialize for MoveInstantaneousRewardsCert { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - self.serialize_as_embedded_group(serializer) - } -} - -impl SerializeEmbeddedGroup for MoveInstantaneousRewardsCert { - fn serialize_as_embedded_group<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(6u64)?; - self.move_instantaneous_reward.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for MoveInstantaneousRewardsCert { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("MoveInstantaneousRewardsCert")) - } -} - -impl DeserializeEmbeddedGroup for MoveInstantaneousRewardsCert { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - _: cbor_event::Len, - ) -> Result { - (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 6 { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(6), - } - .into()); - } - Ok(()) - })() - .map_err(|e| e.annotate("index_0"))?; - let move_instantaneous_reward = - (|| -> Result<_, DeserializeError> { Ok(MoveInstantaneousReward::deserialize(raw)?) })( - ) - .map_err(|e| e.annotate("move_instantaneous_reward"))?; - Ok(MoveInstantaneousRewardsCert { - move_instantaneous_reward, - }) - } -} - -impl cbor_event::se::Serialize for CertificateEnum { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - match self { - CertificateEnum::StakeRegistration(x) => x.serialize(serializer), - CertificateEnum::StakeDeregistration(x) => x.serialize(serializer), - CertificateEnum::StakeDelegation(x) => x.serialize(serializer), - CertificateEnum::PoolRegistration(x) => x.serialize(serializer), - CertificateEnum::PoolRetirement(x) => x.serialize(serializer), - CertificateEnum::GenesisKeyDelegation(x) => x.serialize(serializer), - CertificateEnum::MoveInstantaneousRewardsCert(x) => x.serialize(serializer), - } - } -} - -impl Deserialize for CertificateEnum { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("CertificateEnum")) - } -} - -impl DeserializeEmbeddedGroup for CertificateEnum { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - len: cbor_event::Len, - ) -> Result { - let initial_position = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(StakeRegistration::deserialize_as_embedded_group(raw, len)?) - })(raw) - { - Ok(variant) => return Ok(CertificateEnum::StakeRegistration(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(StakeDeregistration::deserialize_as_embedded_group( - raw, len, - )?) - })(raw) - { - Ok(variant) => return Ok(CertificateEnum::StakeDeregistration(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(StakeDelegation::deserialize_as_embedded_group(raw, len)?) - })(raw) - { - Ok(variant) => return Ok(CertificateEnum::StakeDelegation(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(PoolRegistration::deserialize_as_embedded_group(raw, len)?) - })(raw) - { - Ok(variant) => return Ok(CertificateEnum::PoolRegistration(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(PoolRetirement::deserialize_as_embedded_group(raw, len)?) - })(raw) - { - Ok(variant) => return Ok(CertificateEnum::PoolRetirement(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(GenesisKeyDelegation::deserialize_as_embedded_group( - raw, len, - )?) - })(raw) - { - Ok(variant) => return Ok(CertificateEnum::GenesisKeyDelegation(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(MoveInstantaneousRewardsCert::deserialize_as_embedded_group( - raw, len, - )?) - })(raw) - { - Ok(variant) => return Ok(CertificateEnum::MoveInstantaneousRewardsCert(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - Err(DeserializeError::new( - "CertificateEnum", - DeserializeFailure::NoVariantMatched.into(), - )) - } -} - -impl cbor_event::se::Serialize for Certificate { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - self.0.serialize(serializer) - } -} - -impl Deserialize for Certificate { - fn deserialize(raw: &mut Deserializer) -> Result { - Ok(Self(CertificateEnum::deserialize(raw)?)) - } -} - -impl cbor_event::se::Serialize for StakeCredentials { +impl cbor_event::se::Serialize for Ed25519KeyHashes { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, @@ -1963,7 +1108,7 @@ impl cbor_event::se::Serialize for StakeCredentials { } } -impl Deserialize for StakeCredentials { +impl Deserialize for Ed25519KeyHashes { fn deserialize(raw: &mut Deserializer) -> Result { let mut arr = Vec::new(); (|| -> Result<_, DeserializeError> { @@ -1976,114 +1121,47 @@ impl Deserialize for StakeCredentials { assert_eq!(raw.special()?, CBORSpecial::Break); break; } - arr.push(StakeCredential::deserialize(raw)?); + arr.push(Ed25519KeyHash::deserialize(raw)?); } Ok(()) })() - .map_err(|e| e.annotate("StakeCredentials"))?; + .map_err(|e| e.annotate("Ed25519KeyHashes"))?; Ok(Self(arr)) } } -impl cbor_event::se::Serialize for MIRToStakeCredentials { +impl cbor_event::se::Serialize for StakeCredentials { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_map(cbor_event::Len::Len(self.rewards.len() as u64))?; - for (key, value) in &self.rewards { - key.serialize(serializer)?; - value.serialize(serializer)?; + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; } Ok(serializer) } } -impl Deserialize for MIRToStakeCredentials { +impl Deserialize for StakeCredentials { fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); (|| -> Result<_, DeserializeError> { - let mut table = linked_hash_map::LinkedHashMap::new(); - let len = raw.map()?; + let len = raw.array()?; while match len { - cbor_event::Len::Len(n) => table.len() < n as usize, + cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { if raw.cbor_type()? == CBORType::Special { assert_eq!(raw.special()?, CBORSpecial::Break); break; } - let key = StakeCredential::deserialize(raw)?; - let value = DeltaCoin::deserialize(raw)?; - if table.insert(key.clone(), value).is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Str(format!( - "StakeCred: {} (hex bytes)", - hex::encode(key.to_bytes()) - ))) - .into()); - } + arr.push(StakeCredential::deserialize(raw)?); } - Ok(Self { rewards: table }) - })() - .map_err(|e| e.annotate("MIRToStakeCredentials")) - } -} - -impl cbor_event::se::Serialize for MoveInstantaneousReward { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - match self.pot { - MIRPot::Reserves => serializer.write_unsigned_integer(0u64), - MIRPot::Treasury => serializer.write_unsigned_integer(1u64), - }?; - match &self.variant { - MIREnum::ToOtherPot(amount) => amount.serialize(serializer), - MIREnum::ToStakeCredentials(amounts) => amounts.serialize(serializer), - } - } -} - -impl Deserialize for MoveInstantaneousReward { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let outer_len = raw.array()?; - let pot = match raw.unsigned_integer()? { - 0 => MIRPot::Reserves, - 1 => MIRPot::Treasury, - n => return Err(DeserializeFailure::UnknownKey(Key::Uint(n)).into()), - }; - let variant = match raw.cbor_type()? { - CBORType::UnsignedInteger => MIREnum::ToOtherPot(Coin::deserialize(raw)?), - CBORType::Map => { - MIREnum::ToStakeCredentials(MIRToStakeCredentials::deserialize(raw)?) - } - _ => return Err(DeserializeFailure::NoVariantMatched.into()), - }; - match outer_len { - cbor_event::Len::Len(n) => { - if n != 2 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - n, - outer_len, - "MoveInstantaneousReward", - )) - .into()); - } - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - }; - Ok(Self { pot, variant }) + Ok(()) })() - .map_err(|e| e.annotate("MoveInstantaneousReward")) + .map_err(|e| e.annotate("StakeCredentials"))?; + Ok(Self(arr)) } } @@ -4940,7 +4018,7 @@ mod tests { amount: val.clone(), plutus_data: None, script_ref: None, - serialization_format: None + serialization_format: None, }; let mut txo_dh = txo.clone(); txo_dh.set_data_hash(&DataHash::from([47u8; DataHash::BYTE_COUNT])); @@ -4966,7 +4044,7 @@ mod tests { amount: val.clone(), plutus_data: None, script_ref: None, - serialization_format: None + serialization_format: None, }; let mut txo_dh = txo.clone(); txo_dh.set_plutus_data(&PlutusData::new_bytes(fake_bytes_32(11))); @@ -4995,7 +4073,7 @@ mod tests { amount: val.clone(), plutus_data: None, script_ref: None, - serialization_format: None + serialization_format: None, }; let mut txo_dh = txo.clone(); txo_dh.set_script_ref(&ScriptRef::new_plutus_script(&PlutusScript::new( @@ -5023,7 +4101,7 @@ mod tests { amount: val.clone(), plutus_data: None, script_ref: None, - serialization_format: None + serialization_format: None, }; let mut txo_dh = txo.clone(); txo_dh.set_plutus_data(&PlutusData::new_bytes(fake_bytes_32(11))); @@ -5049,7 +4127,7 @@ mod tests { amount: val.clone(), plutus_data: None, script_ref: None, - serialization_format: None + serialization_format: None, }; let mut txo_dh = txo.clone(); let native_script = NativeScript::new_timelock_start(&TimelockStart::new(20)); @@ -5077,7 +4155,7 @@ mod tests { amount: val.clone(), plutus_data: None, script_ref: None, - serialization_format: None + serialization_format: None, }; let mut txo_dh = txo.clone(); let native_script = NativeScript::new_timelock_start(&TimelockStart::new(20)); @@ -5104,7 +4182,7 @@ mod tests { amount: val.clone(), plutus_data: None, script_ref: None, - serialization_format: None + serialization_format: None, }; let mut txo_dh = txo.clone(); let native_script = NativeScript::new_timelock_start(&TimelockStart::new(20)); @@ -5137,7 +4215,7 @@ mod tests { amount: val.clone(), plutus_data: None, script_ref: None, - serialization_format: None + serialization_format: None, }; let mut txo_dh = txo.clone(); txo_dh.set_data_hash(&DataHash::from([47u8; DataHash::BYTE_COUNT])); @@ -5164,7 +4242,7 @@ mod tests { amount: val.clone(), plutus_data: None, script_ref: None, - serialization_format: None + serialization_format: None, }; let mut txo_dh = txo.clone(); txo_dh.set_plutus_data(&PlutusData::new_bytes(fake_bytes_32(11))); @@ -5194,7 +4272,7 @@ mod tests { amount: val.clone(), plutus_data: None, script_ref: None, - serialization_format: None + serialization_format: None, }; let mut txo_dh = txo.clone(); txo_dh.set_script_ref(&ScriptRef::new_plutus_script(&PlutusScript::new( @@ -5223,7 +4301,7 @@ mod tests { amount: val.clone(), plutus_data: None, script_ref: None, - serialization_format: None + serialization_format: None, }; let mut txo_dh = txo.clone(); txo_dh.set_plutus_data(&PlutusData::new_bytes(fake_bytes_32(11))); @@ -5250,7 +4328,7 @@ mod tests { amount: val.clone(), plutus_data: None, script_ref: None, - serialization_format: None + serialization_format: None, }; let mut txo_dh = txo.clone(); let native_script = NativeScript::new_timelock_start(&TimelockStart::new(20)); @@ -5279,7 +4357,7 @@ mod tests { amount: val.clone(), plutus_data: None, script_ref: None, - serialization_format: None + serialization_format: None, }; let mut txo_dh = txo.clone(); let native_script = NativeScript::new_timelock_start(&TimelockStart::new(20)); @@ -5307,7 +4385,7 @@ mod tests { amount: val.clone(), plutus_data: None, script_ref: None, - serialization_format: None + serialization_format: None, }; let mut txo_dh = txo.clone(); let native_script = NativeScript::new_timelock_start(&TimelockStart::new(20)); @@ -5529,8 +4607,13 @@ mod tests { fn tx_output_ser_type() { let array_tx_output = TransactionOutput::from_hex("8258390000efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee16400efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee1641a000f4240").unwrap(); let map_tx_output = TransactionOutput::from_hex("a30058390000efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee16400efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee164011a00039447028201d81844d9052380").unwrap(); - assert_eq!(array_tx_output.serialization_format().unwrap(), CborContainerType::Array); - assert_eq!(map_tx_output.serialization_format().unwrap(), CborContainerType::Map); - + assert_eq!( + array_tx_output.serialization_format().unwrap(), + CborContainerType::Array + ); + assert_eq!( + map_tx_output.serialization_format().unwrap(), + CborContainerType::Map + ); } } diff --git a/rust/src/serialization/governance/mod.rs b/rust/src/serialization/governance/mod.rs new file mode 100644 index 00000000..8774ed02 --- /dev/null +++ b/rust/src/serialization/governance/mod.rs @@ -0,0 +1,2 @@ +mod drep; +pub use drep::*; \ No newline at end of file diff --git a/rust/src/serialization/mod.rs b/rust/src/serialization/mod.rs new file mode 100644 index 00000000..2d6f1240 --- /dev/null +++ b/rust/src/serialization/mod.rs @@ -0,0 +1,14 @@ +mod general; +pub use general::*; + +mod serialization_macros; +pub use serialization_macros::*; + +mod certificates; +pub use certificates::*; + +mod ser_info; +pub use ser_info::*; + +mod governance; +pub use governance::*; \ No newline at end of file diff --git a/rust/src/serialization/ser_info/mod.rs b/rust/src/serialization/ser_info/mod.rs new file mode 100644 index 00000000..70a69db7 --- /dev/null +++ b/rust/src/serialization/ser_info/mod.rs @@ -0,0 +1,2 @@ +mod types; +pub use types::*; \ No newline at end of file diff --git a/rust/src/ser_info/types.rs b/rust/src/serialization/ser_info/types.rs similarity index 100% rename from rust/src/ser_info/types.rs rename to rust/src/serialization/ser_info/types.rs diff --git a/rust/src/serialization_macros.rs b/rust/src/serialization/serialization_macros.rs similarity index 99% rename from rust/src/serialization_macros.rs rename to rust/src/serialization/serialization_macros.rs index fa0ba8e0..ef98741a 100644 --- a/rust/src/serialization_macros.rs +++ b/rust/src/serialization/serialization_macros.rs @@ -134,4 +134,4 @@ macro_rules! impl_to_from { to_from_bytes!($name); to_from_json!($name); }; -} \ No newline at end of file +} From 40b07ec47efff04ae7d2657b8f1005762c71757a Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 11 Aug 2023 13:58:18 +0400 Subject: [PATCH 002/349] add drep type --- rust/src/protocol_types/governance/drep.rs | 88 ++++++++++++++++++++++ rust/src/serialization/governance/drep.rs | 79 +++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 rust/src/protocol_types/governance/drep.rs create mode 100644 rust/src/serialization/governance/drep.rs diff --git a/rust/src/protocol_types/governance/drep.rs b/rust/src/protocol_types/governance/drep.rs new file mode 100644 index 00000000..95a5b620 --- /dev/null +++ b/rust/src/protocol_types/governance/drep.rs @@ -0,0 +1,88 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub(crate) enum DRepEnum { + KeyHash(Ed25519KeyHash), + ScriptHash(ScriptHash), + AlwaysAbstain, + AlwaysNoConfidence, +} + +#[wasm_bindgen] +#[derive(Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)] +pub enum DRepKind { + KeyHash, + ScriptHash, + AlwaysAbstain, + AlwaysNoConfidence, +} + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct DRep(pub(crate) DRepEnum); + +impl_to_from!(DRep); + +impl DRep { + pub fn new_key_hash(key_hash: &Ed25519KeyHash) -> Self { + Self(DRepEnum::KeyHash(key_hash.clone())) + } + + pub fn new_script_hash(script_hash: &ScriptHash) -> Self { + Self(DRepEnum::ScriptHash(script_hash.clone())) + } + + pub fn new_always_abstain() -> Self { + Self(DRepEnum::AlwaysAbstain) + } + + pub fn new_always_no_confidence() -> Self { + Self(DRepEnum::AlwaysNoConfidence) + } + + pub fn kind(&self) -> DRepKind { + match &self.0 { + DRepEnum::KeyHash(_) => DRepKind::KeyHash, + DRepEnum::ScriptHash(_) => DRepKind::ScriptHash, + DRepEnum::AlwaysAbstain => DRepKind::AlwaysAbstain, + DRepEnum::AlwaysNoConfidence => DRepKind::AlwaysNoConfidence, + } + } + + pub fn get_key_hash(&self) -> Option { + match &self.0 { + DRepEnum::KeyHash(keyhash) => Some(keyhash.clone()), + _ => None, + } + } + + pub fn get_script_hash(&self) -> Option { + match &self.0 { + DRepEnum::ScriptHash(scripthash) => Some(scripthash.clone()), + _ => None, + } + } +} diff --git a/rust/src/serialization/governance/drep.rs b/rust/src/serialization/governance/drep.rs new file mode 100644 index 00000000..801eccb3 --- /dev/null +++ b/rust/src/serialization/governance/drep.rs @@ -0,0 +1,79 @@ +use crate::*; + +impl cbor_event::se::Serialize for DRep { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + self.0.serialize(serializer) + } +} + +impl Deserialize for DRep { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let drep_enum = DRepEnum::deserialize(raw)?; + Ok(Self(drep_enum)) + })() + .map_err(|e| e.annotate("DRep")) + } +} + +impl cbor_event::se::Serialize for DRepEnum { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + match &self { + DRepEnum::KeyHash(keyhash) => { + serializer.write_unsigned_integer(0u64)?; + serializer.write_bytes(keyhash.to_bytes()) + } + DRepEnum::ScriptHash(scripthash) => { + serializer.write_unsigned_integer(1u64)?; + serializer.write_bytes(scripthash.to_bytes()) + } + DRepEnum::AlwaysAbstain => serializer.write_unsigned_integer(2u64), + DRepEnum::AlwaysNoConfidence => serializer.write_unsigned_integer(3u64), + } + } +} + +impl Deserialize for DRepEnum { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + if let cbor_event::Len::Len(n) = len { + if n != 2 && n != 1 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 2, + len, + "[id, hash] or [id] (for abstain and no confidence)", + )) + .into()); + } + } + let drep = match raw.unsigned_integer()? { + 0 => DRepEnum::KeyHash(Ed25519KeyHash::deserialize(raw)?), + 1 => DRepEnum::ScriptHash(ScriptHash::deserialize(raw)?), + 2 => DRepEnum::AlwaysAbstain, + 3 => DRepEnum::AlwaysNoConfidence, + n => { + return Err(DeserializeFailure::FixedValuesMismatch { + found: Key::Uint(n), + expected: vec![Key::Uint(0), Key::Uint(1), Key::Uint(2), Key::Uint(3)], + } + .into()) + } + }; + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + Ok(drep) + })() + .map_err(|e| e.annotate("DRepEnum")) + } +} From 5f72ebe20158054e1a932d2aa4765d143ce0323d Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 11 Aug 2023 13:58:35 +0400 Subject: [PATCH 003/349] add vote delegation cert --- .../certificates/vote_delegation.rs | 43 +++++++++++++ .../certificates/vote_delegation.rs | 61 +++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 rust/src/protocol_types/certificates/vote_delegation.rs create mode 100644 rust/src/serialization/certificates/vote_delegation.rs diff --git a/rust/src/protocol_types/certificates/vote_delegation.rs b/rust/src/protocol_types/certificates/vote_delegation.rs new file mode 100644 index 00000000..b75ff4f6 --- /dev/null +++ b/rust/src/protocol_types/certificates/vote_delegation.rs @@ -0,0 +1,43 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct VoteDelegation { + pub(crate) stake_credential: StakeCredential, + pub(crate) drep: DRep, +} + +impl_to_from!(VoteDelegation); + +#[wasm_bindgen] +impl VoteDelegation { + pub fn stake_credential(&self) -> StakeCredential { + self.stake_credential.clone() + } + + pub fn drep(&self) -> DRep { + self.drep.clone() + } + + pub fn new(stake_credential: &StakeCredential, drep: &DRep) -> Self { + Self { + stake_credential: stake_credential.clone(), + drep: drep.clone(), + } + } + + pub fn has_script_credentials(&self) -> bool { + self.stake_credential.has_script_hash() + } +} diff --git a/rust/src/serialization/certificates/vote_delegation.rs b/rust/src/serialization/certificates/vote_delegation.rs new file mode 100644 index 00000000..e6297022 --- /dev/null +++ b/rust/src/serialization/certificates/vote_delegation.rs @@ -0,0 +1,61 @@ +use crate::*; + +const VOTE_CERT_INDEX: u64 = 9; + +impl cbor_event::se::Serialize for VoteDelegation { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(3))?; + serializer.write_unsigned_integer(VOTE_CERT_INDEX)?; + self.stake_credential.serialize(serializer)?; + self.drep.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for VoteDelegation { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + + if let cbor_event::Len::Len(n) = len { + if n != 3 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 3, + len, + "(cert_index, stake_credential, drep)", + )) + .into()); + } + } + + let cert_index = raw.unsigned_integer()?; + if cert_index != VOTE_CERT_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(VOTE_CERT_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + + let stake_credential = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + + let drep = DRep::deserialize(raw).map_err(|e| e.annotate("drep"))?; + + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + + return Ok(VoteDelegation { + stake_credential, + drep, + }); + })() + .map_err(|e| e.annotate("StakeDelegation")) + } +} From bb8e6e5847579781f4f7336e2a5029649c7d3324 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 00:29:46 +0400 Subject: [PATCH 004/349] add anchor --- rust/src/protocol_types/governance/anchor.rs | 37 +++++++++++++++ rust/src/serialization/governance/anchor.rs | 49 ++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 rust/src/protocol_types/governance/anchor.rs create mode 100644 rust/src/serialization/governance/anchor.rs diff --git a/rust/src/protocol_types/governance/anchor.rs b/rust/src/protocol_types/governance/anchor.rs new file mode 100644 index 00000000..a131f6ce --- /dev/null +++ b/rust/src/protocol_types/governance/anchor.rs @@ -0,0 +1,37 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct Anchor { + pub(crate) anchor_url: URL, + pub(crate) anchor_data_hash: AnchorDataHash, +} + +#[wasm_bindgen] +impl Anchor { + pub fn anchor_url(&self) -> URL { + self.anchor_url.clone() + } + + pub fn anchor_data_hash(&self) -> AnchorDataHash { + self.anchor_data_hash.clone() + } + + pub fn new(anchor_url: &URL, anchor_data_hash: &AnchorDataHash) -> Self { + Self { + anchor_url: anchor_url.clone(), + anchor_data_hash: anchor_data_hash.clone(), + } + } +} diff --git a/rust/src/serialization/governance/anchor.rs b/rust/src/serialization/governance/anchor.rs new file mode 100644 index 00000000..c3924581 --- /dev/null +++ b/rust/src/serialization/governance/anchor.rs @@ -0,0 +1,49 @@ +use crate::*; + +impl cbor_event::se::Serialize for Anchor { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.anchor_url.serialize(serializer)?; + self.anchor_data_hash.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for Anchor { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + + if let cbor_event::Len::Len(n) = len { + if n != 2 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 2, + len, + "(anchor_url, anchor_data_hash)", + )) + .into()); + } + } + + let anchor_url = URL::deserialize(raw).map_err(|e| e.annotate("anchor_url"))?; + + let anchor_data_hash = + AnchorDataHash::deserialize(raw).map_err(|e| e.annotate("anchor_data_hash"))?; + + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + + return Ok(Anchor { + anchor_url, + anchor_data_hash, + }); + })() + .map_err(|e| e.annotate("Anchor")) + } +} From 81ed36766260cf040247424d07aab5197ef2a227 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 00:29:58 +0400 Subject: [PATCH 005/349] add reg_committee_hot_key_cert --- .../committee_hot_key_deregistration.rs | 35 ++++++++++++ .../committee_hot_key_deregistration.rs | 57 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs create mode 100644 rust/src/serialization/certificates/committee_hot_key_deregistration.rs diff --git a/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs b/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs new file mode 100644 index 00000000..bbf9bca5 --- /dev/null +++ b/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs @@ -0,0 +1,35 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct CommitteeHotKeyDeregistration { + pub(crate) committee_cold_keyhash: Ed25519KeyHash, +} + +impl_to_from!(CommitteeHotKeyDeregistration); + +#[wasm_bindgen] +impl CommitteeHotKeyDeregistration { + pub fn committee_cold_keyhash(&self) -> Ed25519KeyHash { + self.committee_cold_keyhash.clone() + } + + pub fn new( + committee_cold_keyhash: &Ed25519KeyHash, + ) -> Self { + Self { + committee_cold_keyhash: committee_cold_keyhash.clone(), + } + } +} diff --git a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs new file mode 100644 index 00000000..66911978 --- /dev/null +++ b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs @@ -0,0 +1,57 @@ +use crate::*; + +const UNREG_COMMITTEE_HOT_KEY_CERT: u64 = 15; + +impl cbor_event::se::Serialize for CommitteeHotKeyDeregistration { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + serializer.write_unsigned_integer(UNREG_COMMITTEE_HOT_KEY_CERT)?; + self.committee_cold_keyhash.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for CommitteeHotKeyDeregistration { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + + if let cbor_event::Len::Len(n) = len { + if n != 2 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 2, + len, + "(cert_index, committee_cold_keyhash)", + )) + .into()); + } + } + + let cert_index = raw.unsigned_integer()?; + if cert_index != UNREG_COMMITTEE_HOT_KEY_CERT { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(UNREG_COMMITTEE_HOT_KEY_CERT), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + + let committee_cold_keyhash = Ed25519KeyHash::deserialize(raw) + .map_err(|e| e.annotate("committee_cold_keyhash"))?; + + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + + return Ok(CommitteeHotKeyDeregistration { + committee_cold_keyhash, + }); + })() + .map_err(|e| e.annotate("CommitteeHotKeyDeregistration")) + } +} From 231c5abd19cf39607c3b21e83c91e2bc9cc78665 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 00:30:10 +0400 Subject: [PATCH 006/349] add unreg_committee_hot_key_cert --- .../committee_hot_key_registration.rs | 42 +++++++++++++ .../committee_hot_key_registration.rs | 62 +++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 rust/src/protocol_types/certificates/committee_hot_key_registration.rs create mode 100644 rust/src/serialization/certificates/committee_hot_key_registration.rs diff --git a/rust/src/protocol_types/certificates/committee_hot_key_registration.rs b/rust/src/protocol_types/certificates/committee_hot_key_registration.rs new file mode 100644 index 00000000..70610657 --- /dev/null +++ b/rust/src/protocol_types/certificates/committee_hot_key_registration.rs @@ -0,0 +1,42 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct CommitteeHotKeyRegistration { + pub(crate) committee_cold_keyhash: Ed25519KeyHash, + pub(crate) committee_hot_keyhash: Ed25519KeyHash, +} + +impl_to_from!(CommitteeHotKeyRegistration); + +#[wasm_bindgen] +impl CommitteeHotKeyRegistration { + pub fn committee_cold_keyhash(&self) -> Ed25519KeyHash { + self.committee_cold_keyhash.clone() + } + + pub fn committee_hot_keyhash(&self) -> Ed25519KeyHash { + self.committee_hot_keyhash.clone() + } + + pub fn new( + committee_cold_keyhash: &Ed25519KeyHash, + committee_hot_keyhash: &Ed25519KeyHash, + ) -> Self { + Self { + committee_cold_keyhash: committee_cold_keyhash.clone(), + committee_hot_keyhash: committee_hot_keyhash.clone(), + } + } +} diff --git a/rust/src/serialization/certificates/committee_hot_key_registration.rs b/rust/src/serialization/certificates/committee_hot_key_registration.rs new file mode 100644 index 00000000..c6a48b74 --- /dev/null +++ b/rust/src/serialization/certificates/committee_hot_key_registration.rs @@ -0,0 +1,62 @@ +use crate::*; + +const REG_COMMITTEE_HOT_KEY_CERT: u64 = 14; + +impl cbor_event::se::Serialize for CommitteeHotKeyRegistration { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(3))?; + serializer.write_unsigned_integer(REG_COMMITTEE_HOT_KEY_CERT)?; + self.committee_cold_keyhash.serialize(serializer)?; + self.committee_hot_keyhash.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for CommitteeHotKeyRegistration { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + + if let cbor_event::Len::Len(n) = len { + if n != 3 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 3, + len, + "(cert_index, committee_cold_keyhash, committee_hot_keyhash)", + )) + .into()); + } + } + + let cert_index = raw.unsigned_integer()?; + if cert_index != REG_COMMITTEE_HOT_KEY_CERT { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(REG_COMMITTEE_HOT_KEY_CERT), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + + let committee_cold_keyhash = Ed25519KeyHash::deserialize(raw) + .map_err(|e| e.annotate("committee_cold_keyhash"))?; + + let committee_hot_keyhash = Ed25519KeyHash::deserialize(raw) + .map_err(|e| e.annotate("committee_hot_keyhash"))?; + + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + + return Ok(CommitteeHotKeyRegistration { + committee_cold_keyhash, + committee_hot_keyhash, + }); + })() + .map_err(|e| e.annotate("CommitteeHotKeyRegistration")) + } +} From fb7a6cb84e2b545b822f208178a4f91c9d4cd53c Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 00:30:44 +0400 Subject: [PATCH 007/349] add unreg_drep_cert --- .../certificates/drep_deregistration.rs | 43 +++++++++++++ .../certificates/drep_deregistration.rs | 61 +++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 rust/src/protocol_types/certificates/drep_deregistration.rs create mode 100644 rust/src/serialization/certificates/drep_deregistration.rs diff --git a/rust/src/protocol_types/certificates/drep_deregistration.rs b/rust/src/protocol_types/certificates/drep_deregistration.rs new file mode 100644 index 00000000..6d0a1305 --- /dev/null +++ b/rust/src/protocol_types/certificates/drep_deregistration.rs @@ -0,0 +1,43 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct DrepDeregistration { + pub(crate) voting_credential: StakeCredential, + pub(crate) coin: Coin, +} + +impl_to_from!(DrepDeregistration); + +#[wasm_bindgen] +impl DrepDeregistration { + pub fn voting_credential(&self) -> StakeCredential { + self.voting_credential.clone() + } + + pub fn coin(&self) -> Coin { + self.coin.clone() + } + + pub fn new(voting_credential: &StakeCredential, coin: Coin) -> Self { + Self { + voting_credential: voting_credential.clone(), + coin: coin.clone(), + } + } + + pub fn has_script_credentials(&self) -> bool { + self.voting_credential.has_script_hash() + } +} diff --git a/rust/src/serialization/certificates/drep_deregistration.rs b/rust/src/serialization/certificates/drep_deregistration.rs new file mode 100644 index 00000000..6512005d --- /dev/null +++ b/rust/src/serialization/certificates/drep_deregistration.rs @@ -0,0 +1,61 @@ +use crate::*; + +const DEREG_DREP_CERT_INDEX: u64 = 17; + +impl cbor_event::se::Serialize for DrepDeregistration { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(3))?; + serializer.write_unsigned_integer(DEREG_DREP_CERT_INDEX)?; + self.voting_credential.serialize(serializer)?; + self.coin.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for DrepDeregistration { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + + if let cbor_event::Len::Len(n) = len { + if n != 3 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 3, + len, + "(cert_index, voting_credential, coin)", + )) + .into()); + } + } + + let cert_index = raw.unsigned_integer()?; + if cert_index != DEREG_DREP_CERT_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(DEREG_DREP_CERT_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + + let voting_credential = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("voting_credential"))?; + + let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; + + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + + return Ok(DrepDeregistration { + voting_credential, + coin, + }); + })() + .map_err(|e| e.annotate("DrepDeregistration")) + } +} From 4a27015e10970d14ac1dab467d00fc6d162e2cf1 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 00:30:54 +0400 Subject: [PATCH 008/349] add reg_drep_cert --- .../certificates/drep_registration.rs | 45 +++++++++++ .../certificates/drep_registration.rs | 78 +++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 rust/src/protocol_types/certificates/drep_registration.rs create mode 100644 rust/src/serialization/certificates/drep_registration.rs diff --git a/rust/src/protocol_types/certificates/drep_registration.rs b/rust/src/protocol_types/certificates/drep_registration.rs new file mode 100644 index 00000000..76865d0b --- /dev/null +++ b/rust/src/protocol_types/certificates/drep_registration.rs @@ -0,0 +1,45 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct DrepRegistration { + pub(crate) voting_credential: StakeCredential, + pub(crate) coin: Coin, + pub(crate) anchor: Option, +} + +impl_to_from!(DrepRegistration); + +#[wasm_bindgen] +impl DrepRegistration { + pub fn voting_credential(&self) -> StakeCredential { + self.voting_credential.clone() + } + + pub fn coin(&self) -> Coin { + self.coin.clone() + } + + pub fn anchor(&self) -> Option { + self.anchor.clone() + } + + pub fn new(voting_credential: &StakeCredential, coin: Coin, anchor: Option) -> Self { + Self { + voting_credential: voting_credential.clone(), + coin: coin.clone(), + anchor: anchor.clone(), + } + } +} diff --git a/rust/src/serialization/certificates/drep_registration.rs b/rust/src/serialization/certificates/drep_registration.rs new file mode 100644 index 00000000..e0def46c --- /dev/null +++ b/rust/src/serialization/certificates/drep_registration.rs @@ -0,0 +1,78 @@ +use crate::*; + +const REG_DREP_CERT_INDEX: u64 = 16; + +impl cbor_event::se::Serialize for DrepRegistration { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(4))?; + serializer.write_unsigned_integer(REG_DREP_CERT_INDEX)?; + self.voting_credential.serialize(serializer)?; + self.coin.serialize(serializer)?; + match &self.anchor { + Some(anchor) => anchor.serialize(serializer), + None => serializer.write_special(CBORSpecial::Null), + }?; + Ok(serializer) + } +} + +impl Deserialize for DrepRegistration { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + + if let cbor_event::Len::Len(n) = len { + if n != 4 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 4, + len, + "(cert_index, voting_credential, coin, anchor / null)", + )) + .into()); + } + } + + let cert_index = raw.unsigned_integer()?; + if cert_index != REG_DREP_CERT_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(REG_DREP_CERT_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + + let voting_credential = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("voting_credential"))?; + + let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; + + let anchor = (|| -> Result<_, DeserializeError> { + if raw.cbor_type()? == CBORType::Special { + if raw.special()? != CBORSpecial::Null { + return Err(DeserializeFailure::ExpectedNull.into()); + } + Ok(None) + } + else { + Ok(Some(Anchor::deserialize(raw)?)) + } + })().map_err(|e| e.annotate("anchor"))?; + + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + + return Ok(DrepRegistration { + voting_credential, + coin, + anchor, + }); + })() + .map_err(|e| e.annotate("DrepRegistration")) + } +} From 9050140384b9423a82f5a78957d200c20c791171 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 00:31:05 +0400 Subject: [PATCH 009/349] add update_drep_cert --- .../certificates/drep_update.rs | 43 +++++++++++ .../serialization/certificates/drep_update.rs | 74 +++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 rust/src/protocol_types/certificates/drep_update.rs create mode 100644 rust/src/serialization/certificates/drep_update.rs diff --git a/rust/src/protocol_types/certificates/drep_update.rs b/rust/src/protocol_types/certificates/drep_update.rs new file mode 100644 index 00000000..c1b9f16f --- /dev/null +++ b/rust/src/protocol_types/certificates/drep_update.rs @@ -0,0 +1,43 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct DrepUpdate { + pub(crate) voting_credential: StakeCredential, + pub(crate) anchor: Option, +} + +impl_to_from!(DrepUpdate); + +#[wasm_bindgen] +impl DrepUpdate { + pub fn voting_credential(&self) -> StakeCredential { + self.voting_credential.clone() + } + + pub fn anchor(&self) -> Option { + self.anchor.clone() + } + + pub fn new(voting_credential: &StakeCredential, anchor: Option) -> Self { + Self { + voting_credential: voting_credential.clone(), + anchor: anchor.clone(), + } + } + + pub fn has_script_credentials(&self) -> bool { + self.voting_credential.has_script_hash() + } +} diff --git a/rust/src/serialization/certificates/drep_update.rs b/rust/src/serialization/certificates/drep_update.rs new file mode 100644 index 00000000..d12894c3 --- /dev/null +++ b/rust/src/serialization/certificates/drep_update.rs @@ -0,0 +1,74 @@ +use crate::*; + +const UPDATE_DREP_CERT_INDEX: u64 = 18; + +impl cbor_event::se::Serialize for DrepUpdate { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(3))?; + serializer.write_unsigned_integer(UPDATE_DREP_CERT_INDEX)?; + self.voting_credential.serialize(serializer)?; + match &self.anchor { + Some(anchor) => anchor.serialize(serializer), + None => serializer.write_special(CBORSpecial::Null), + }?; + Ok(serializer) + } +} + +impl Deserialize for DrepUpdate { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + + if let cbor_event::Len::Len(n) = len { + if n != 3 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 3, + len, + "(cert_index, voting_credential, anchor / null)", + )) + .into()); + } + } + + let cert_index = raw.unsigned_integer()?; + if cert_index != UPDATE_DREP_CERT_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(UPDATE_DREP_CERT_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + + let voting_credential = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("voting_credential"))?; + + let anchor = (|| -> Result<_, DeserializeError> { + if raw.cbor_type()? == CBORType::Special { + if raw.special()? != CBORSpecial::Null { + return Err(DeserializeFailure::ExpectedNull.into()); + } + Ok(None) + } + else { + Ok(Some(Anchor::deserialize(raw)?)) + } + })().map_err(|e| e.annotate("anchor"))?; + + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + + return Ok(DrepUpdate { + voting_credential, + anchor, + }); + })() + .map_err(|e| e.annotate("DrepUpdate")) + } +} From 6d9b110e5665463cd13629e908aa34bbf84e6b2a Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 00:31:24 +0400 Subject: [PATCH 010/349] add stake_vote_deleg_cert --- .../certificates/stake_and_vote_delegation.rs | 53 +++++++++++++++ .../certificates/stake_and_vote_delegation.rs | 66 +++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 rust/src/protocol_types/certificates/stake_and_vote_delegation.rs create mode 100644 rust/src/serialization/certificates/stake_and_vote_delegation.rs diff --git a/rust/src/protocol_types/certificates/stake_and_vote_delegation.rs b/rust/src/protocol_types/certificates/stake_and_vote_delegation.rs new file mode 100644 index 00000000..d78478f9 --- /dev/null +++ b/rust/src/protocol_types/certificates/stake_and_vote_delegation.rs @@ -0,0 +1,53 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct StakeAndVoteDelegation { + pub(crate) stake_credential: StakeCredential, + pub(crate) pool_keyhash: Ed25519KeyHash, + pub(crate) drep: DRep, +} + +impl_to_from!(StakeAndVoteDelegation); + +#[wasm_bindgen] +impl StakeAndVoteDelegation { + pub fn stake_credential(&self) -> StakeCredential { + self.stake_credential.clone() + } + + pub fn pool_keyhash(&self) -> Ed25519KeyHash { + self.pool_keyhash.clone() + } + + pub fn drep(&self) -> DRep { + self.drep.clone() + } + + pub fn new( + stake_credential: &StakeCredential, + pool_keyhash: &Ed25519KeyHash, + drep: &DRep, + ) -> Self { + Self { + stake_credential: stake_credential.clone(), + pool_keyhash: pool_keyhash.clone(), + drep: drep.clone(), + } + } + + pub fn has_script_credentials(&self) -> bool { + self.stake_credential.has_script_hash() + } +} diff --git a/rust/src/serialization/certificates/stake_and_vote_delegation.rs b/rust/src/serialization/certificates/stake_and_vote_delegation.rs new file mode 100644 index 00000000..fea24e6a --- /dev/null +++ b/rust/src/serialization/certificates/stake_and_vote_delegation.rs @@ -0,0 +1,66 @@ +use crate::*; + +const STAKE_VOTE_DELEG_CERT_INDEX: u64 = 10; + +impl cbor_event::se::Serialize for StakeAndVoteDelegation { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(4))?; + serializer.write_unsigned_integer(STAKE_VOTE_DELEG_CERT_INDEX)?; + self.stake_credential.serialize(serializer)?; + self.pool_keyhash.serialize(serializer)?; + self.drep.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for StakeAndVoteDelegation { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + + if let cbor_event::Len::Len(n) = len { + if n != 4 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 4, + len, + "(cert_index, stake_credential, pool_keyhash, drep)", + )) + .into()); + } + } + + let cert_index = raw.unsigned_integer()?; + if cert_index != STAKE_VOTE_DELEG_CERT_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(STAKE_VOTE_DELEG_CERT_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + + let stake_credential = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + + let pool_keyhash = + Ed25519KeyHash::deserialize(raw).map_err(|e| e.annotate("pool_keyhash"))?; + + let drep = DRep::deserialize(raw).map_err(|e| e.annotate("drep"))?; + + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + + return Ok(StakeAndVoteDelegation { + stake_credential, + pool_keyhash, + drep, + }); + })() + .map_err(|e| e.annotate("StakeAndVoteDelegation")) + } +} From 390c257d0f005e1ced8d05a789c56d7a6121f8be Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 00:31:34 +0400 Subject: [PATCH 011/349] add stake_reg_deleg_cert --- .../stake_registration_and_delegation.rs | 53 +++++++++++++++ .../stake_registration_and_delegation.rs | 66 +++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 rust/src/protocol_types/certificates/stake_registration_and_delegation.rs create mode 100644 rust/src/serialization/certificates/stake_registration_and_delegation.rs diff --git a/rust/src/protocol_types/certificates/stake_registration_and_delegation.rs b/rust/src/protocol_types/certificates/stake_registration_and_delegation.rs new file mode 100644 index 00000000..ca0fc446 --- /dev/null +++ b/rust/src/protocol_types/certificates/stake_registration_and_delegation.rs @@ -0,0 +1,53 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct StakeRegistrationAndDelegation { + pub(crate) stake_credential: StakeCredential, + pub(crate) pool_keyhash: Ed25519KeyHash, + pub(crate) coin: Coin, +} + +impl_to_from!(StakeRegistrationAndDelegation); + +#[wasm_bindgen] +impl StakeRegistrationAndDelegation { + pub fn stake_credential(&self) -> StakeCredential { + self.stake_credential.clone() + } + + pub fn pool_keyhash(&self) -> Ed25519KeyHash { + self.pool_keyhash.clone() + } + + pub fn coin(&self) -> Coin { + self.coin.clone() + } + + pub fn new( + stake_credential: &StakeCredential, + pool_keyhash: &Ed25519KeyHash, + coin: &Coin, + ) -> Self { + Self { + stake_credential: stake_credential.clone(), + pool_keyhash: pool_keyhash.clone(), + coin: coin.clone(), + } + } + + pub fn has_script_credentials(&self) -> bool { + self.stake_credential.has_script_hash() + } +} diff --git a/rust/src/serialization/certificates/stake_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_registration_and_delegation.rs new file mode 100644 index 00000000..da6c2ad9 --- /dev/null +++ b/rust/src/serialization/certificates/stake_registration_and_delegation.rs @@ -0,0 +1,66 @@ +use crate::*; + +const STAKE_REG_DELEG_CERT_INDEX: u64 = 11; + +impl cbor_event::se::Serialize for StakeRegistrationAndDelegation { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(4))?; + serializer.write_unsigned_integer(STAKE_REG_DELEG_CERT_INDEX)?; + self.stake_credential.serialize(serializer)?; + self.pool_keyhash.serialize(serializer)?; + self.coin.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for StakeRegistrationAndDelegation { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + + if let cbor_event::Len::Len(n) = len { + if n != 4 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 4, + len, + "(cert_index, stake_credential, pool_keyhash, coin)", + )) + .into()); + } + } + + let cert_index = raw.unsigned_integer()?; + if cert_index != STAKE_REG_DELEG_CERT_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(STAKE_REG_DELEG_CERT_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + + let stake_credential = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + + let pool_keyhash = + Ed25519KeyHash::deserialize(raw).map_err(|e| e.annotate("pool_keyhash"))?; + + let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; + + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + + return Ok(StakeRegistrationAndDelegation { + stake_credential, + pool_keyhash, + coin, + }); + })() + .map_err(|e| e.annotate("StakeRegistrationAndDelegation")) + } +} \ No newline at end of file From 6c4a732df1f0ad37ace2a56576a4e7e17343ce2e Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 00:31:43 +0400 Subject: [PATCH 012/349] add stake_vote_reg_deleg_cert --- .../stake_vote_registration_and_delegation.rs | 60 ++++++++++++++++ .../stake_vote_registration_and_delegation.rs | 70 +++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 rust/src/protocol_types/certificates/stake_vote_registration_and_delegation.rs create mode 100644 rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs diff --git a/rust/src/protocol_types/certificates/stake_vote_registration_and_delegation.rs b/rust/src/protocol_types/certificates/stake_vote_registration_and_delegation.rs new file mode 100644 index 00000000..fb8b8d82 --- /dev/null +++ b/rust/src/protocol_types/certificates/stake_vote_registration_and_delegation.rs @@ -0,0 +1,60 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct StakeVoteRegistrationAndDelegation { + pub(crate) stake_credential: StakeCredential, + pub(crate) pool_keyhash: Ed25519KeyHash, + pub(crate) drep: DRep, + pub(crate) coin: Coin, +} + +impl_to_from!(StakeVoteRegistrationAndDelegation); + +#[wasm_bindgen] +impl StakeVoteRegistrationAndDelegation { + pub fn stake_credential(&self) -> StakeCredential { + self.stake_credential.clone() + } + + pub fn pool_keyhash(&self) -> Ed25519KeyHash { + self.pool_keyhash.clone() + } + + pub fn drep(&self) -> DRep { + self.drep.clone() + } + + pub fn coin(&self) -> Coin { + self.coin.clone() + } + + pub fn new( + stake_credential: &StakeCredential, + pool_keyhash: &Ed25519KeyHash, + drep: &DRep, + coin: &Coin, + ) -> Self { + Self { + stake_credential: stake_credential.clone(), + pool_keyhash: pool_keyhash.clone(), + drep: drep.clone(), + coin: coin.clone(), + } + } + + pub fn has_script_credentials(&self) -> bool { + self.stake_credential.has_script_hash() + } +} diff --git a/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs new file mode 100644 index 00000000..500e67a3 --- /dev/null +++ b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs @@ -0,0 +1,70 @@ +use crate::*; + +const STAKE_VOTE_REG_DELEG_CERT_INDEX: u64 = 13; + +impl cbor_event::se::Serialize for StakeVoteRegistrationAndDelegation { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(5))?; + serializer.write_unsigned_integer(STAKE_VOTE_REG_DELEG_CERT_INDEX)?; + self.stake_credential.serialize(serializer)?; + self.pool_keyhash.serialize(serializer)?; + self.drep.serialize(serializer)?; + self.coin.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for StakeVoteRegistrationAndDelegation { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + + if let cbor_event::Len::Len(n) = len { + if n != 5 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 5, + len, + "(cert_index, stake_credential, pool_keyhash, drep, coin)", + )) + .into()); + } + } + + let cert_index = raw.unsigned_integer()?; + if cert_index != STAKE_VOTE_REG_DELEG_CERT_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(STAKE_VOTE_REG_DELEG_CERT_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + + let stake_credential = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + + let pool_keyhash = + Ed25519KeyHash::deserialize(raw).map_err(|e| e.annotate("pool_keyhash"))?; + + let drep = DRep::deserialize(raw).map_err(|e| e.annotate("drep"))?; + + let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; + + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + + return Ok(StakeVoteRegistrationAndDelegation { + stake_credential, + pool_keyhash, + drep, + coin, + }); + })() + .map_err(|e| e.annotate("StakeVoteRegistrationAndDelegation")) + } +} \ No newline at end of file From 47da1992ddb4bc3b5dc578958b38345604d14567 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 00:31:53 +0400 Subject: [PATCH 013/349] add vote_reg_deleg_cert --- .../vote_registration_and_delegation.rs | 49 ++++++++++++++ .../vote_registration_and_delegation.rs | 65 +++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 rust/src/protocol_types/certificates/vote_registration_and_delegation.rs create mode 100644 rust/src/serialization/certificates/vote_registration_and_delegation.rs diff --git a/rust/src/protocol_types/certificates/vote_registration_and_delegation.rs b/rust/src/protocol_types/certificates/vote_registration_and_delegation.rs new file mode 100644 index 00000000..6ab63cf6 --- /dev/null +++ b/rust/src/protocol_types/certificates/vote_registration_and_delegation.rs @@ -0,0 +1,49 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct VoteRegistrationAndDelegation { + pub(crate) stake_credential: StakeCredential, + pub(crate) drep: DRep, + pub(crate) coin: Coin, +} + +impl_to_from!(VoteRegistrationAndDelegation); + +#[wasm_bindgen] +impl VoteRegistrationAndDelegation { + pub fn stake_credential(&self) -> StakeCredential { + self.stake_credential.clone() + } + + pub fn drep(&self) -> DRep { + self.drep.clone() + } + + pub fn coin(&self) -> Coin { + self.coin.clone() + } + + pub fn new(stake_credential: &StakeCredential, drep: &DRep, coin: &Coin) -> Self { + Self { + stake_credential: stake_credential.clone(), + drep: drep.clone(), + coin: coin.clone(), + } + } + + pub fn has_script_credentials(&self) -> bool { + self.stake_credential.has_script_hash() + } +} diff --git a/rust/src/serialization/certificates/vote_registration_and_delegation.rs b/rust/src/serialization/certificates/vote_registration_and_delegation.rs new file mode 100644 index 00000000..bc5414fe --- /dev/null +++ b/rust/src/serialization/certificates/vote_registration_and_delegation.rs @@ -0,0 +1,65 @@ +use crate::*; + +const VOTE_REG_DELEG_CERT_INDEX: u64 = 12; + +impl cbor_event::se::Serialize for VoteRegistrationAndDelegation { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(4))?; + serializer.write_unsigned_integer(VOTE_REG_DELEG_CERT_INDEX)?; + self.stake_credential.serialize(serializer)?; + self.drep.serialize(serializer)?; + self.coin.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for VoteRegistrationAndDelegation { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + + if let cbor_event::Len::Len(n) = len { + if n != 4 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 4, + len, + "(cert_index, stake_credential, drep, coin)", + )) + .into()); + } + } + + let cert_index = raw.unsigned_integer()?; + if cert_index != VOTE_REG_DELEG_CERT_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(VOTE_REG_DELEG_CERT_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + + let stake_credential = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + + let drep = DRep::deserialize(raw).map_err(|e| e.annotate("drep"))?; + + let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; + + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + + return Ok(VoteRegistrationAndDelegation { + stake_credential, + drep, + coin, + }); + })() + .map_err(|e| e.annotate("VoteRegistrationAndDelegation")) + } +} \ No newline at end of file From 95dd88b7415a441897d31f061d64dfe0d9c70158 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 00:32:17 +0400 Subject: [PATCH 014/349] update vote deleg cert --- rust/src/serialization/certificates/vote_delegation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/src/serialization/certificates/vote_delegation.rs b/rust/src/serialization/certificates/vote_delegation.rs index e6297022..0934954a 100644 --- a/rust/src/serialization/certificates/vote_delegation.rs +++ b/rust/src/serialization/certificates/vote_delegation.rs @@ -56,6 +56,6 @@ impl Deserialize for VoteDelegation { drep, }); })() - .map_err(|e| e.annotate("StakeDelegation")) + .map_err(|e| e.annotate("VoteDelegation")) } } From 7a370af476f1c3822b57900248fe0c0f827965aa Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 00:32:25 +0400 Subject: [PATCH 015/349] update drep --- rust/src/protocol_types/governance/drep.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/src/protocol_types/governance/drep.rs b/rust/src/protocol_types/governance/drep.rs index 95a5b620..7510bf33 100644 --- a/rust/src/protocol_types/governance/drep.rs +++ b/rust/src/protocol_types/governance/drep.rs @@ -46,6 +46,7 @@ pub struct DRep(pub(crate) DRepEnum); impl_to_from!(DRep); +#[wasm_bindgen] impl DRep { pub fn new_key_hash(key_hash: &Ed25519KeyHash) -> Self { Self(DRepEnum::KeyHash(key_hash.clone())) From 13818992d10892ffbbc340ae409e7e1a461c45cc Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 00:32:55 +0400 Subject: [PATCH 016/349] add anchor data hash --- rust/src/crypto.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/src/crypto.rs b/rust/src/crypto.rs index 38ba0254..e2de5655 100644 --- a/rust/src/crypto.rs +++ b/rust/src/crypto.rs @@ -1095,6 +1095,7 @@ impl LegacyDaedalusPrivateKey { impl_hash_type!(Ed25519KeyHash, 28); impl_hash_type!(ScriptHash, 28); +impl_hash_type!(AnchorDataHash, 32); impl_hash_type!(TransactionHash, 32); impl_hash_type!(GenesisDelegateHash, 28); impl_hash_type!(GenesisHash, 28); From 55755537b354a99990b4f636c1907a05636b4957 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 00:33:10 +0400 Subject: [PATCH 017/349] update mod files --- rust/src/protocol_types/certificates/mod.rs | 29 ++++++++++++++++++++- rust/src/protocol_types/governance/mod.rs | 5 +++- rust/src/serialization/certificates/mod.rs | 29 ++++++++++++++++++++- rust/src/serialization/governance/mod.rs | 5 +++- 4 files changed, 64 insertions(+), 4 deletions(-) diff --git a/rust/src/protocol_types/certificates/mod.rs b/rust/src/protocol_types/certificates/mod.rs index 09ba72fa..ef3fdd67 100644 --- a/rust/src/protocol_types/certificates/mod.rs +++ b/rust/src/protocol_types/certificates/mod.rs @@ -23,4 +23,31 @@ mod stake_registration; pub use stake_registration::*; mod vote_delegation; -pub use vote_delegation::*; \ No newline at end of file +pub use vote_delegation::*; + +mod stake_and_vote_delegation; +pub use stake_and_vote_delegation::*; + +mod stake_registration_and_delegation; +pub use stake_registration_and_delegation::*; + +mod stake_vote_registration_and_delegation; +pub use stake_vote_registration_and_delegation::*; + +mod vote_registration_and_delegation; +pub use vote_registration_and_delegation::*; + +mod committee_hot_key_registration; +pub use committee_hot_key_registration::*; + +mod committee_hot_key_deregistration; +pub use committee_hot_key_deregistration::*; + +mod drep_registration; +pub use drep_registration::*; + +mod drep_deregistration; +pub use drep_deregistration::*; + +mod drep_update; +pub use drep_update::*; diff --git a/rust/src/protocol_types/governance/mod.rs b/rust/src/protocol_types/governance/mod.rs index 8774ed02..0f1657d7 100644 --- a/rust/src/protocol_types/governance/mod.rs +++ b/rust/src/protocol_types/governance/mod.rs @@ -1,2 +1,5 @@ mod drep; -pub use drep::*; \ No newline at end of file +pub use drep::*; + +mod anchor; +pub use anchor::*; \ No newline at end of file diff --git a/rust/src/serialization/certificates/mod.rs b/rust/src/serialization/certificates/mod.rs index 09ba72fa..ef3fdd67 100644 --- a/rust/src/serialization/certificates/mod.rs +++ b/rust/src/serialization/certificates/mod.rs @@ -23,4 +23,31 @@ mod stake_registration; pub use stake_registration::*; mod vote_delegation; -pub use vote_delegation::*; \ No newline at end of file +pub use vote_delegation::*; + +mod stake_and_vote_delegation; +pub use stake_and_vote_delegation::*; + +mod stake_registration_and_delegation; +pub use stake_registration_and_delegation::*; + +mod stake_vote_registration_and_delegation; +pub use stake_vote_registration_and_delegation::*; + +mod vote_registration_and_delegation; +pub use vote_registration_and_delegation::*; + +mod committee_hot_key_registration; +pub use committee_hot_key_registration::*; + +mod committee_hot_key_deregistration; +pub use committee_hot_key_deregistration::*; + +mod drep_registration; +pub use drep_registration::*; + +mod drep_deregistration; +pub use drep_deregistration::*; + +mod drep_update; +pub use drep_update::*; diff --git a/rust/src/serialization/governance/mod.rs b/rust/src/serialization/governance/mod.rs index 8774ed02..0f1657d7 100644 --- a/rust/src/serialization/governance/mod.rs +++ b/rust/src/serialization/governance/mod.rs @@ -1,2 +1,5 @@ mod drep; -pub use drep::*; \ No newline at end of file +pub use drep::*; + +mod anchor; +pub use anchor::*; \ No newline at end of file From c1a69b75a591dfbf65e55fb288cacd76cd365c86 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 00:37:35 +0400 Subject: [PATCH 018/349] new types to json schema gen --- rust/json-gen/src/main.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rust/json-gen/src/main.rs b/rust/json-gen/src/main.rs index 45e12782..d8750e6c 100644 --- a/rust/json-gen/src/main.rs +++ b/rust/json-gen/src/main.rs @@ -116,6 +116,7 @@ fn main() { gen_json_schema!(BlockHash); gen_json_schema!(DataHash); gen_json_schema!(ScriptDataHash); + gen_json_schema!(AnchorDataHash); gen_json_schema!(VRFVKey); gen_json_schema!(KESVKey); gen_json_schema!(Nonce); @@ -158,4 +159,15 @@ fn main() { gen_json_schema!(TransactionUnspentOutputs); gen_json_schema!(DRep); + gen_json_schema!(Anchor); + gen_json_schema!(CommitteeHotKeyDeregistration); + gen_json_schema!(CommitteeHotKeyRegistration); + gen_json_schema!(DrepDeregistration); + gen_json_schema!(DrepRegistration); + gen_json_schema!(DrepUpdate); + gen_json_schema!(StakeAndVoteDelegation); + gen_json_schema!(StakeRegistrationAndDelegation); + gen_json_schema!(StakeVoteRegistrationAndDelegation); + gen_json_schema!(VoteDelegation); + gen_json_schema!(VoteRegistrationAndDelegation); } From ec590098fc8e8910d986d2434709260fdd3bc8c7 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 00:52:21 +0400 Subject: [PATCH 019/349] type and naming fix --- .../committee_hot_key_deregistration.rs | 10 +++++----- .../committee_hot_key_registration.rs | 20 +++++++++---------- .../committee_hot_key_deregistration.rs | 10 +++++----- .../committee_hot_key_registration.rs | 18 ++++++++--------- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs b/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs index bbf9bca5..24f505bb 100644 --- a/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs +++ b/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs @@ -14,22 +14,22 @@ use crate::*; )] #[wasm_bindgen] pub struct CommitteeHotKeyDeregistration { - pub(crate) committee_cold_keyhash: Ed25519KeyHash, + pub(crate) committee_cold_key: StakeCredential, } impl_to_from!(CommitteeHotKeyDeregistration); #[wasm_bindgen] impl CommitteeHotKeyDeregistration { - pub fn committee_cold_keyhash(&self) -> Ed25519KeyHash { - self.committee_cold_keyhash.clone() + pub fn committee_cold_key(&self) -> StakeCredential { + self.committee_cold_key.clone() } pub fn new( - committee_cold_keyhash: &Ed25519KeyHash, + committee_cold_key: &StakeCredential, ) -> Self { Self { - committee_cold_keyhash: committee_cold_keyhash.clone(), + committee_cold_key: committee_cold_key.clone(), } } } diff --git a/rust/src/protocol_types/certificates/committee_hot_key_registration.rs b/rust/src/protocol_types/certificates/committee_hot_key_registration.rs index 70610657..c2ca952a 100644 --- a/rust/src/protocol_types/certificates/committee_hot_key_registration.rs +++ b/rust/src/protocol_types/certificates/committee_hot_key_registration.rs @@ -14,29 +14,29 @@ use crate::*; )] #[wasm_bindgen] pub struct CommitteeHotKeyRegistration { - pub(crate) committee_cold_keyhash: Ed25519KeyHash, - pub(crate) committee_hot_keyhash: Ed25519KeyHash, + pub(crate) committee_cold_key: StakeCredential, + pub(crate) committee_hot_key: StakeCredential, } impl_to_from!(CommitteeHotKeyRegistration); #[wasm_bindgen] impl CommitteeHotKeyRegistration { - pub fn committee_cold_keyhash(&self) -> Ed25519KeyHash { - self.committee_cold_keyhash.clone() + pub fn committee_cold_keyhash(&self) -> StakeCredential { + self.committee_cold_key.clone() } - pub fn committee_hot_keyhash(&self) -> Ed25519KeyHash { - self.committee_hot_keyhash.clone() + pub fn committee_hot_keyhash(&self) -> StakeCredential { + self.committee_hot_key.clone() } pub fn new( - committee_cold_keyhash: &Ed25519KeyHash, - committee_hot_keyhash: &Ed25519KeyHash, + committee_cold_key: &StakeCredential, + committee_hot_key: &StakeCredential, ) -> Self { Self { - committee_cold_keyhash: committee_cold_keyhash.clone(), - committee_hot_keyhash: committee_hot_keyhash.clone(), + committee_cold_key: committee_cold_key.clone(), + committee_hot_key: committee_hot_key.clone(), } } } diff --git a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs index 66911978..af5c4d69 100644 --- a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs @@ -9,7 +9,7 @@ impl cbor_event::se::Serialize for CommitteeHotKeyDeregistration { ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(2))?; serializer.write_unsigned_integer(UNREG_COMMITTEE_HOT_KEY_CERT)?; - self.committee_cold_keyhash.serialize(serializer)?; + self.committee_cold_key.serialize(serializer)?; Ok(serializer) } } @@ -24,7 +24,7 @@ impl Deserialize for CommitteeHotKeyDeregistration { return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( 2, len, - "(cert_index, committee_cold_keyhash)", + "(cert_index, committee_cold_key)", )) .into()); } @@ -39,8 +39,8 @@ impl Deserialize for CommitteeHotKeyDeregistration { .map_err(|e| DeserializeError::from(e).annotate("cert_index")); } - let committee_cold_keyhash = Ed25519KeyHash::deserialize(raw) - .map_err(|e| e.annotate("committee_cold_keyhash"))?; + let committee_cold_key = StakeCredential::deserialize(raw) + .map_err(|e| e.annotate("committee_cold_key"))?; if let cbor_event::Len::Indefinite = len { if raw.special()? != CBORSpecial::Break { @@ -49,7 +49,7 @@ impl Deserialize for CommitteeHotKeyDeregistration { } return Ok(CommitteeHotKeyDeregistration { - committee_cold_keyhash, + committee_cold_key, }); })() .map_err(|e| e.annotate("CommitteeHotKeyDeregistration")) diff --git a/rust/src/serialization/certificates/committee_hot_key_registration.rs b/rust/src/serialization/certificates/committee_hot_key_registration.rs index c6a48b74..e95353d5 100644 --- a/rust/src/serialization/certificates/committee_hot_key_registration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_registration.rs @@ -9,8 +9,8 @@ impl cbor_event::se::Serialize for CommitteeHotKeyRegistration { ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(3))?; serializer.write_unsigned_integer(REG_COMMITTEE_HOT_KEY_CERT)?; - self.committee_cold_keyhash.serialize(serializer)?; - self.committee_hot_keyhash.serialize(serializer)?; + self.committee_cold_key.serialize(serializer)?; + self.committee_hot_key.serialize(serializer)?; Ok(serializer) } } @@ -25,7 +25,7 @@ impl Deserialize for CommitteeHotKeyRegistration { return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( 3, len, - "(cert_index, committee_cold_keyhash, committee_hot_keyhash)", + "(cert_index, committee_cold_key, committee_hot_key)", )) .into()); } @@ -40,11 +40,11 @@ impl Deserialize for CommitteeHotKeyRegistration { .map_err(|e| DeserializeError::from(e).annotate("cert_index")); } - let committee_cold_keyhash = Ed25519KeyHash::deserialize(raw) - .map_err(|e| e.annotate("committee_cold_keyhash"))?; + let committee_cold_key = StakeCredential::deserialize(raw) + .map_err(|e| e.annotate("committee_cold_key"))?; - let committee_hot_keyhash = Ed25519KeyHash::deserialize(raw) - .map_err(|e| e.annotate("committee_hot_keyhash"))?; + let committee_hot_key = StakeCredential::deserialize(raw) + .map_err(|e| e.annotate("committee_hot_key"))?; if let cbor_event::Len::Indefinite = len { if raw.special()? != CBORSpecial::Break { @@ -53,8 +53,8 @@ impl Deserialize for CommitteeHotKeyRegistration { } return Ok(CommitteeHotKeyRegistration { - committee_cold_keyhash, - committee_hot_keyhash, + committee_cold_key, + committee_hot_key, }); })() .map_err(|e| e.annotate("CommitteeHotKeyRegistration")) From c1ef2daf10f3061b5ab7e039c49c6fe7e4a0fc8e Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 01:24:02 +0400 Subject: [PATCH 020/349] add voter type --- rust/src/protocol_types/governance/mod.rs | 5 +- rust/src/protocol_types/governance/voter.rs | 97 +++++++++++++++++ rust/src/serialization/governance/mod.rs | 5 +- rust/src/serialization/governance/voter.rs | 109 ++++++++++++++++++++ 4 files changed, 214 insertions(+), 2 deletions(-) create mode 100644 rust/src/protocol_types/governance/voter.rs create mode 100644 rust/src/serialization/governance/voter.rs diff --git a/rust/src/protocol_types/governance/mod.rs b/rust/src/protocol_types/governance/mod.rs index 0f1657d7..12eeca06 100644 --- a/rust/src/protocol_types/governance/mod.rs +++ b/rust/src/protocol_types/governance/mod.rs @@ -2,4 +2,7 @@ mod drep; pub use drep::*; mod anchor; -pub use anchor::*; \ No newline at end of file +pub use anchor::*; + +mod voter; +pub use voter::*; \ No newline at end of file diff --git a/rust/src/protocol_types/governance/voter.rs b/rust/src/protocol_types/governance/voter.rs new file mode 100644 index 00000000..7bcf8101 --- /dev/null +++ b/rust/src/protocol_types/governance/voter.rs @@ -0,0 +1,97 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub(crate) enum VoterEnum { + ConstitutionalCommitteeHotKey(StakeCredential), + DRep(StakeCredential), + StakingPool(Ed25519KeyHash), +} + +#[wasm_bindgen] +#[derive(Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)] +pub enum VoterKind { + ConstitutionalCommitteeHotKeyHash, + ConstitutionalCommitteeHotScriptHash, + DRepKeyHash, + DRepScriptHash, + StakingPoolKeyHash, +} + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct Voter(pub(crate) VoterEnum); + +impl_to_from!(Voter); + +#[wasm_bindgen] +impl Voter { + pub fn new_constitutional_committee_hot_key(cred: &StakeCredential) -> Self { + Self(VoterEnum::ConstitutionalCommitteeHotKey(cred.clone())) + } + + pub fn new_drep(cred: &StakeCredential) -> Self { + Self(VoterEnum::DRep(cred.clone())) + } + + pub fn new_staking_pool(key_hash: &Ed25519KeyHash) -> Self { + Self(VoterEnum::StakingPool(key_hash.clone())) + } + + pub fn kind(&self) -> VoterKind { + match &self.0 { + VoterEnum::ConstitutionalCommitteeHotKey(cred) => match cred.kind() { + StakeCredKind::Key => VoterKind::ConstitutionalCommitteeHotKeyHash, + StakeCredKind::Script => VoterKind::ConstitutionalCommitteeHotScriptHash, + }, + VoterEnum::DRep(cred) => match cred.kind() { + StakeCredKind::Key => VoterKind::DRepKeyHash, + StakeCredKind::Script => VoterKind::DRepScriptHash, + }, + VoterEnum::StakingPool(_) => VoterKind::StakingPoolKeyHash, + } + } + + pub fn to_constitutional_committee_hot_key(&self) -> Option { + match &self.0 { + VoterEnum::ConstitutionalCommitteeHotKey(cred) => Some(cred.clone()), + _ => None, + } + } + + pub fn to_drep(&self) -> Option { + match &self.0 { + VoterEnum::DRep(cred) => Some(cred.clone()), + _ => None, + } + } + + pub fn to_staking_pool(&self) -> Option { + match &self.0 { + VoterEnum::StakingPool(key_hash) => Some(key_hash.clone()), + _ => None, + } + } +} diff --git a/rust/src/serialization/governance/mod.rs b/rust/src/serialization/governance/mod.rs index 0f1657d7..12eeca06 100644 --- a/rust/src/serialization/governance/mod.rs +++ b/rust/src/serialization/governance/mod.rs @@ -2,4 +2,7 @@ mod drep; pub use drep::*; mod anchor; -pub use anchor::*; \ No newline at end of file +pub use anchor::*; + +mod voter; +pub use voter::*; \ No newline at end of file diff --git a/rust/src/serialization/governance/voter.rs b/rust/src/serialization/governance/voter.rs new file mode 100644 index 00000000..848337b9 --- /dev/null +++ b/rust/src/serialization/governance/voter.rs @@ -0,0 +1,109 @@ +use crate::*; + +impl cbor_event::se::Serialize for Voter { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + self.0.serialize(serializer) + } +} + +impl Deserialize for Voter { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let voter_enum = VoterEnum::deserialize(raw)?; + Ok(Self(voter_enum)) + })() + .map_err(|e| e.annotate("Voter")) + } +} + +impl cbor_event::se::Serialize for VoterEnum { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + match &self { + VoterEnum::ConstitutionalCommitteeHotKey(cred) => match &cred.0 { + StakeCredType::Key(key_hash) => { + serializer.write_unsigned_integer(0u64)?; + key_hash.serialize(serializer)?; + } + StakeCredType::Script(script_hash) => { + serializer.write_unsigned_integer(1u64)?; + script_hash.serialize(serializer)?; + } + }, + VoterEnum::DRep(cred) => match &cred.0 { + StakeCredType::Key(key_hash) => { + serializer.write_unsigned_integer(2u64)?; + key_hash.serialize(serializer)?; + } + StakeCredType::Script(script_hash) => { + serializer.write_unsigned_integer(3u64)?; + script_hash.serialize(serializer)?; + } + }, + VoterEnum::StakingPool(scripthash) => { + serializer.write_unsigned_integer(4u64)?; + scripthash.serialize(serializer)?; + } + }; + Ok(serializer) + } +} + +impl Deserialize for VoterEnum { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + if let cbor_event::Len::Len(n) = len { + if n != 2 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 2, + len, + "[id, hash]", + )) + .into()); + } + } + let voter = match raw.unsigned_integer()? { + 0 => VoterEnum::ConstitutionalCommitteeHotKey(StakeCredential(StakeCredType::Key( + Ed25519KeyHash::deserialize(raw)?, + ))), + 1 => VoterEnum::ConstitutionalCommitteeHotKey(StakeCredential( + StakeCredType::Script(ScriptHash::deserialize(raw)?), + )), + 2 => VoterEnum::DRep(StakeCredential(StakeCredType::Key( + Ed25519KeyHash::deserialize(raw)?, + ))), + 3 => VoterEnum::DRep(StakeCredential(StakeCredType::Script( + ScriptHash::deserialize(raw)?, + ))), + 4 => VoterEnum::StakingPool(Ed25519KeyHash::deserialize(raw)?), + n => { + return Err(DeserializeFailure::FixedValuesMismatch { + found: Key::Uint(n), + expected: vec![ + Key::Uint(0), + Key::Uint(1), + Key::Uint(2), + Key::Uint(3), + Key::Uint(4), + ], + } + .into()) + } + }; + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + Ok(voter) + })() + .map_err(|e| e.annotate("VoterEnum")) + } +} From 58a6c94c732ad160607139c83e6dffd8a8ab9b8f Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 01:24:19 +0400 Subject: [PATCH 021/349] fix drep naming --- rust/src/protocol_types/governance/drep.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rust/src/protocol_types/governance/drep.rs b/rust/src/protocol_types/governance/drep.rs index 7510bf33..953abe64 100644 --- a/rust/src/protocol_types/governance/drep.rs +++ b/rust/src/protocol_types/governance/drep.rs @@ -29,7 +29,6 @@ pub enum DRepKind { AlwaysNoConfidence, } -#[wasm_bindgen] #[derive( Clone, Debug, @@ -42,6 +41,7 @@ pub enum DRepKind { serde::Deserialize, JsonSchema, )] +#[wasm_bindgen] pub struct DRep(pub(crate) DRepEnum); impl_to_from!(DRep); @@ -73,14 +73,14 @@ impl DRep { } } - pub fn get_key_hash(&self) -> Option { + pub fn to_key_hash(&self) -> Option { match &self.0 { DRepEnum::KeyHash(keyhash) => Some(keyhash.clone()), _ => None, } } - pub fn get_script_hash(&self) -> Option { + pub fn to_script_hash(&self) -> Option { match &self.0 { DRepEnum::ScriptHash(scripthash) => Some(scripthash.clone()), _ => None, From 9049399cded3011d4e4ab8fed9933b04ad84a166 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 01:26:59 +0400 Subject: [PATCH 022/349] fix wasm exports --- rust/src/protocol_types/governance/drep.rs | 1 - rust/src/protocol_types/governance/voter.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/rust/src/protocol_types/governance/drep.rs b/rust/src/protocol_types/governance/drep.rs index 953abe64..8ed8825c 100644 --- a/rust/src/protocol_types/governance/drep.rs +++ b/rust/src/protocol_types/governance/drep.rs @@ -1,6 +1,5 @@ use crate::*; -#[wasm_bindgen] #[derive( Clone, Debug, diff --git a/rust/src/protocol_types/governance/voter.rs b/rust/src/protocol_types/governance/voter.rs index 7bcf8101..3bf5eeb0 100644 --- a/rust/src/protocol_types/governance/voter.rs +++ b/rust/src/protocol_types/governance/voter.rs @@ -1,6 +1,5 @@ use crate::*; -#[wasm_bindgen] #[derive( Clone, Debug, From 6ff3551caacc35d379cab44b7104cc9d104ee709 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 02:40:39 +0400 Subject: [PATCH 023/349] add voting_procedure --- .../governance/voting_procedure.rs | 58 ++++++++++++++++ .../governance/voting_procedure.rs | 68 +++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 rust/src/protocol_types/governance/voting_procedure.rs create mode 100644 rust/src/serialization/governance/voting_procedure.rs diff --git a/rust/src/protocol_types/governance/voting_procedure.rs b/rust/src/protocol_types/governance/voting_procedure.rs new file mode 100644 index 00000000..1d55a1fc --- /dev/null +++ b/rust/src/protocol_types/governance/voting_procedure.rs @@ -0,0 +1,58 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub enum VoteKind { + No = 0, + Yes = 1, + Abstain = 2, +} + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct VotingProcedure { + pub(crate) vote: VoteKind, + pub(crate) anchor: Anchor, +} + +impl_to_from!(VotingProcedure); + +#[wasm_bindgen] +impl VotingProcedure { + pub fn new(vote: VoteKind, anchor: &Anchor) -> Self { + Self { + vote, + anchor: anchor.clone(), + } + } + + pub fn vote(&self) -> VoteKind { + self.vote.clone() + } + + pub fn anchor(&self) -> Anchor { + self.anchor.clone() + } +} diff --git a/rust/src/serialization/governance/voting_procedure.rs b/rust/src/serialization/governance/voting_procedure.rs new file mode 100644 index 00000000..8ad22040 --- /dev/null +++ b/rust/src/serialization/governance/voting_procedure.rs @@ -0,0 +1,68 @@ +use crate::*; + +impl cbor_event::se::Serialize for VotingProcedure { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + match self.vote { + VoteKind::No => { + serializer.write_unsigned_integer(0u64)?; + } + VoteKind::Yes => { + serializer.write_unsigned_integer(1u64)?; + } + VoteKind::Abstain => { + serializer.write_unsigned_integer(2u64)?; + } + }; + self.anchor.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for VotingProcedure { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + if let cbor_event::Len::Len(n) = len { + if n != 2 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 2, + len, + "[vote, anchor]", + )) + .into()); + } + } + + let vote = match raw.unsigned_integer()? { + 0 => VoteKind::No, + 1 => VoteKind::Yes, + 2 => VoteKind::Abstain, + n => { + return Err( + DeserializeError::from(DeserializeFailure::FixedValuesMismatch { + found: Key::Uint(n), + expected: vec![Key::Uint(0), Key::Uint(1), Key::Uint(2)], + }).annotate("vote") + ) + } + }; + + let anchor = Anchor::deserialize(raw).map_err( + |e| e.annotate("anchor") + )?; + + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + + Ok(Self { vote, anchor }) + })() + .map_err(|e| e.annotate("VotingProcedure")) + } +} From 8b50053317666d59c8176d949f0585ac2cee3229 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 02:40:43 +0400 Subject: [PATCH 024/349] add voting_procedures --- .../governance/voting_procedures.rs | 50 +++++++++++ .../governance/voting_procedures.rs | 89 +++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 rust/src/protocol_types/governance/voting_procedures.rs create mode 100644 rust/src/serialization/governance/voting_procedures.rs diff --git a/rust/src/protocol_types/governance/voting_procedures.rs b/rust/src/protocol_types/governance/voting_procedures.rs new file mode 100644 index 00000000..51e81858 --- /dev/null +++ b/rust/src/protocol_types/governance/voting_procedures.rs @@ -0,0 +1,50 @@ +use crate::*; +use std::collections::BTreeMap; + +#[derive( + Clone, + Debug, + Eq, + Ord, + PartialEq, + PartialOrd, + Hash, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct VotingProcedures(pub(crate) BTreeMap>); + +impl_to_from!(VotingProcedures); + +#[wasm_bindgen] +impl VotingProcedures { + pub fn new() -> Self { + Self(BTreeMap::new()) + } + + pub fn get( + &self, + voter: &Voter, + governance_action_id: &GovernanceActionId, + ) -> Option { + self.0 + .get(voter) + .and_then(|v| v.get(governance_action_id)) + .cloned() + } + + pub fn get_voters(&self) -> Voters { + Voters(self.0.keys().cloned().collect()) + } + + pub fn get_governance_action_ids_by_voter(&self, voter: &Voter) -> GovernanceActionIds { + GovernanceActionIds( + self.0 + .get(voter) + .map(|v| v.keys().cloned().collect()) + .unwrap_or_default(), + ) + } +} diff --git a/rust/src/serialization/governance/voting_procedures.rs b/rust/src/serialization/governance/voting_procedures.rs new file mode 100644 index 00000000..8780b7af --- /dev/null +++ b/rust/src/serialization/governance/voting_procedures.rs @@ -0,0 +1,89 @@ +use crate::*; +use std::collections::BTreeMap; + +impl cbor_event::se::Serialize for VotingProcedures { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?; + + for (voter, votes) in &self.0 { + voter.serialize(serializer)?; + serializer.write_map(cbor_event::Len::Len(votes.len() as u64))?; + for (governance_action_id, voting_procedure) in votes { + governance_action_id.serialize(serializer)?; + voting_procedure.serialize(serializer)?; + } + } + Ok(serializer) + } +} + +impl Deserialize for VotingProcedures { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut voter_to_vote = BTreeMap::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.map()?; + while match len { + cbor_event::Len::Len(n) => voter_to_vote.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + return Err( + DeserializeError::from(DeserializeFailure::EndingBreakMissing) + .annotate("voting_procedure map"), + ); + } + + let key = Voter::deserialize(raw).map_err(|e| e.annotate("voter"))?; + + let value = deserialize_internal_map(raw) + .map_err(|e| e.annotate("voting_procedure map"))?; + + if voter_to_vote.insert(key.clone(), value).is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Str(String::from( + "some complicated/unsupported type", + ))) + .into()); + } + } + Ok(Self(voter_to_vote)) + })() + .map_err(|e| e.annotate("VotingProcedures")) + } +} + +fn deserialize_internal_map( + raw: &mut Deserializer, +) -> Result, DeserializeError> { + let mut gov_act_id_to_vote = BTreeMap::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.map()?; + while match len { + cbor_event::Len::Len(n) => gov_act_id_to_vote.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + return Err( + DeserializeError::from(DeserializeFailure::EndingBreakMissing) + .annotate("gov_act_id_to_vote map"), + ); + } + + let key = GovernanceActionId::deserialize(raw).map_err(|e| e.annotate("gov_act_id"))?; + + let value = + VotingProcedure::deserialize(raw).map_err(|e| e.annotate("voting_procedure"))?; + + if gov_act_id_to_vote.insert(key.clone(), value).is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Str(String::from( + "some complicated/unsupported type", + ))) + .into()); + } + } + Ok(gov_act_id_to_vote) + })() + .map_err(|e| e.annotate("VotingProcedures (gov_act_id to vote_procedure map)")) +} From c4cb9519350241638d57793b9af865ac1bd95157 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 02:41:09 +0400 Subject: [PATCH 025/349] add governance_action_id --- .../governance/governance_action_id.rs | 39 ++++++++++++++ .../governance/governance_action_id.rs | 52 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 rust/src/protocol_types/governance/governance_action_id.rs create mode 100644 rust/src/serialization/governance/governance_action_id.rs diff --git a/rust/src/protocol_types/governance/governance_action_id.rs b/rust/src/protocol_types/governance/governance_action_id.rs new file mode 100644 index 00000000..53269038 --- /dev/null +++ b/rust/src/protocol_types/governance/governance_action_id.rs @@ -0,0 +1,39 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Eq, + Ord, + PartialEq, + PartialOrd, + Hash, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct GovernanceActionId { + pub(crate) transaction_id: TransactionHash, + pub(crate) index: GovernanceActionIndex, +} + +impl_to_from!(GovernanceActionId); + +#[wasm_bindgen] +impl GovernanceActionId { + pub fn transaction_id(&self) -> TransactionHash { + self.transaction_id.clone() + } + + pub fn index(&self) -> GovernanceActionIndex { + self.index.clone() + } + + pub fn new(transaction_id: &TransactionHash, index: GovernanceActionIndex) -> Self { + Self { + transaction_id: transaction_id.clone(), + index: index, + } + } +} diff --git a/rust/src/serialization/governance/governance_action_id.rs b/rust/src/serialization/governance/governance_action_id.rs new file mode 100644 index 00000000..d7859fa1 --- /dev/null +++ b/rust/src/serialization/governance/governance_action_id.rs @@ -0,0 +1,52 @@ +use crate::*; + +impl cbor_event::se::Serialize for GovernanceActionId { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.transaction_id.serialize(serializer)?; + self.index.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for GovernanceActionId { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + if let cbor_event::Len::Len(n) = len { + if n != 2 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 2, + len, + "[transaction_id, gov_action_index]", + )) + .into()); + } + } + + let transaction_id = TransactionHash::deserialize(raw).map_err( + |e| e.annotate("transaction_id") + )?; + + let index = GovernanceActionIndex::deserialize(raw).map_err( + |e| e.annotate("index") + )?; + + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + + Ok(Self { + transaction_id, + index, + }) + + })() + .map_err(|e| e.annotate("GovernanceActionId")) + } +} \ No newline at end of file From 673b45b891847cb08f66cc244b8d5d2970384deb Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 02:41:12 +0400 Subject: [PATCH 026/349] add governance_action_ids --- .../governance/governance_action_ids.rs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 rust/src/protocol_types/governance/governance_action_ids.rs diff --git a/rust/src/protocol_types/governance/governance_action_ids.rs b/rust/src/protocol_types/governance/governance_action_ids.rs new file mode 100644 index 00000000..d3a1e70f --- /dev/null +++ b/rust/src/protocol_types/governance/governance_action_ids.rs @@ -0,0 +1,33 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Eq, + Ord, + PartialEq, + PartialOrd, + Hash, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct GovernanceActionIds(pub(crate) Vec); + +to_from_json!(GovernanceActionIds); + +#[wasm_bindgen] +impl GovernanceActionIds { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn get(&self, index: usize) -> Option { + self.0.get(index).cloned() + } + + pub fn len(&self) -> usize { + self.0.len() + } +} \ No newline at end of file From 3dedb5d45a741c49bcee6ed941777841ddcd818f Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 02:41:27 +0400 Subject: [PATCH 027/349] add gov action index --- rust/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 88f2de4f..1eca0e89 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -161,6 +161,7 @@ impl Transaction { type TransactionIndex = u32; // index of a cert within a tx type CertificateIndex = u32; +type GovernanceActionIndex = u32; #[wasm_bindgen] #[derive( From 132b47fa20174706f877d3f0cf094840137372a5 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 02:41:44 +0400 Subject: [PATCH 028/349] add voters --- rust/src/protocol_types/governance/voters.rs | 33 ++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 rust/src/protocol_types/governance/voters.rs diff --git a/rust/src/protocol_types/governance/voters.rs b/rust/src/protocol_types/governance/voters.rs new file mode 100644 index 00000000..6a8f437f --- /dev/null +++ b/rust/src/protocol_types/governance/voters.rs @@ -0,0 +1,33 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Eq, + Ord, + PartialEq, + PartialOrd, + Hash, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct Voters(pub(crate) Vec); + +to_from_json!(Voters); + +#[wasm_bindgen] +impl Voters { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn get(&self, index: usize) -> Option { + self.0.get(index).cloned() + } + + pub fn len(&self) -> usize { + self.0.len() + } +} \ No newline at end of file From 0f1a1a4fc322f773a0b905d5d48768d368be0b91 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 02:41:58 +0400 Subject: [PATCH 029/349] update imports --- rust/src/protocol_types/governance/mod.rs | 17 ++++++++++++++++- rust/src/serialization/governance/mod.rs | 11 ++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/rust/src/protocol_types/governance/mod.rs b/rust/src/protocol_types/governance/mod.rs index 12eeca06..19be23a6 100644 --- a/rust/src/protocol_types/governance/mod.rs +++ b/rust/src/protocol_types/governance/mod.rs @@ -5,4 +5,19 @@ mod anchor; pub use anchor::*; mod voter; -pub use voter::*; \ No newline at end of file +pub use voter::*; + +mod voters; +pub use voters::*; + +mod voting_procedure; +pub use voting_procedure::*; + +mod voting_procedures; +pub use voting_procedures::*; + +mod governance_action_id; +pub use governance_action_id::*; + +mod governance_action_ids; +pub use governance_action_ids::*; \ No newline at end of file diff --git a/rust/src/serialization/governance/mod.rs b/rust/src/serialization/governance/mod.rs index 12eeca06..42cf5277 100644 --- a/rust/src/serialization/governance/mod.rs +++ b/rust/src/serialization/governance/mod.rs @@ -5,4 +5,13 @@ mod anchor; pub use anchor::*; mod voter; -pub use voter::*; \ No newline at end of file +pub use voter::*; + +mod voting_procedure; +pub use voting_procedure::*; + +mod voting_procedures; +pub use voting_procedures::*; + +mod governance_action_id; +pub use governance_action_id::*; \ No newline at end of file From 51df90cec30e1b043591a389192a4a4893f74d29 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 12 Aug 2023 10:20:57 +0400 Subject: [PATCH 030/349] add optional coin to stake reg --- .../certificates/stake_deregistration.rs | 13 +++++++++++++ .../certificates/stake_registration.rs | 13 +++++++++++++ .../certificates/stake_deregistration.rs | 5 ++++- .../certificates/stake_registration.rs | 5 ++++- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/rust/src/protocol_types/certificates/stake_deregistration.rs b/rust/src/protocol_types/certificates/stake_deregistration.rs index 5963d651..80bb5c3a 100644 --- a/rust/src/protocol_types/certificates/stake_deregistration.rs +++ b/rust/src/protocol_types/certificates/stake_deregistration.rs @@ -15,6 +15,7 @@ use crate::*; )] pub struct StakeDeregistration { pub(crate) stake_credential: StakeCredential, + pub(crate) coin: Option } impl_to_from!(StakeDeregistration); @@ -25,9 +26,21 @@ impl StakeDeregistration { self.stake_credential.clone() } + pub fn coin(&self) -> Option { + self.coin.clone() + } + pub fn new(stake_credential: &StakeCredential) -> Self { Self { stake_credential: stake_credential.clone(), + coin: None, + } + } + + pub fn new_with_coin(stake_credential: &StakeCredential, coin: &Coin) -> Self { + Self { + stake_credential: stake_credential.clone(), + coin: Some(coin.clone()) } } diff --git a/rust/src/protocol_types/certificates/stake_registration.rs b/rust/src/protocol_types/certificates/stake_registration.rs index 0d024d29..6900f445 100644 --- a/rust/src/protocol_types/certificates/stake_registration.rs +++ b/rust/src/protocol_types/certificates/stake_registration.rs @@ -15,6 +15,7 @@ use crate::*; )] pub struct StakeRegistration { pub(crate) stake_credential: StakeCredential, + pub(crate) coin: Option } impl_to_from!(StakeRegistration); @@ -25,9 +26,21 @@ impl StakeRegistration { self.stake_credential.clone() } + pub fn coin(&self) -> Option { + self.coin.clone() + } + pub fn new(stake_credential: &StakeCredential) -> Self { Self { stake_credential: stake_credential.clone(), + coin: None + } + } + + pub fn new_with_coin(stake_credential: &StakeCredential, coin: &Coin) -> Self { + Self { + stake_credential: stake_credential.clone(), + coin: Some(coin.clone()) } } } diff --git a/rust/src/serialization/certificates/stake_deregistration.rs b/rust/src/serialization/certificates/stake_deregistration.rs index 85ab6314..aac57700 100644 --- a/rust/src/serialization/certificates/stake_deregistration.rs +++ b/rust/src/serialization/certificates/stake_deregistration.rs @@ -67,6 +67,9 @@ impl DeserializeEmbeddedGroup for StakeDeregistration { let stake_credential = (|| -> Result<_, DeserializeError> { Ok(StakeCredential::deserialize(raw)?) })() .map_err(|e| e.annotate("stake_credential"))?; - Ok(StakeDeregistration { stake_credential }) + Ok(StakeDeregistration { + stake_credential, + coin: None, + }) } } diff --git a/rust/src/serialization/certificates/stake_registration.rs b/rust/src/serialization/certificates/stake_registration.rs index 26d16a00..f436c2e3 100644 --- a/rust/src/serialization/certificates/stake_registration.rs +++ b/rust/src/serialization/certificates/stake_registration.rs @@ -67,6 +67,9 @@ impl DeserializeEmbeddedGroup for StakeRegistration { let stake_credential = (|| -> Result<_, DeserializeError> { Ok(StakeCredential::deserialize(raw)?) })() .map_err(|e| e.annotate("stake_credential"))?; - Ok(StakeRegistration { stake_credential }) + Ok(StakeRegistration { + stake_credential, + coin: None, + }) } } From 96aafa440bb61320ed945140e28793c1fd166a0a Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 13 Aug 2023 00:31:16 +0400 Subject: [PATCH 031/349] update main certificate struct --- .../certificates/certificate.rs | 119 +++++++++++++++++- .../serialization/certificates/certificate.rs | 10 ++ 2 files changed, 126 insertions(+), 3 deletions(-) diff --git a/rust/src/protocol_types/certificates/certificate.rs b/rust/src/protocol_types/certificates/certificate.rs index cb1af3a7..ab5b7427 100644 --- a/rust/src/protocol_types/certificates/certificate.rs +++ b/rust/src/protocol_types/certificates/certificate.rs @@ -10,6 +10,16 @@ pub enum CertificateKind { PoolRetirement, GenesisKeyDelegation, MoveInstantaneousRewardsCert, + CommitteeHotKeyRegistration, + CommitteeHotKeyDeregistration, + DrepDeregistration, + DrepRegistration, + DrepUpdate, + StakeAndVoteDelegation, + StakeRegistrationAndDelegation, + StakeVoteRegistrationAndDelegation, + VoteDelegation, + VoteRegistrationAndDelegation, } #[derive( @@ -32,6 +42,16 @@ pub enum CertificateEnum { PoolRetirement(PoolRetirement), GenesisKeyDelegation(GenesisKeyDelegation), MoveInstantaneousRewardsCert(MoveInstantaneousRewardsCert), + CommitteeHotKeyRegistration(CommitteeHotKeyRegistration), + CommitteeHotKeyDeregistration(CommitteeHotKeyDeregistration), + DrepDeregistration(DrepDeregistration), + DrepRegistration(DrepRegistration), + DrepUpdate(DrepUpdate), + StakeAndVoteDelegation(StakeAndVoteDelegation), + StakeRegistrationAndDelegation(StakeRegistrationAndDelegation), + StakeVoteRegistrationAndDelegation(StakeVoteRegistrationAndDelegation), + VoteDelegation(VoteDelegation), + VoteRegistrationAndDelegation(VoteRegistrationAndDelegation), } #[wasm_bindgen] @@ -99,9 +119,23 @@ impl Certificate { CertificateEnum::PoolRegistration(_) => CertificateKind::PoolRegistration, CertificateEnum::PoolRetirement(_) => CertificateKind::PoolRetirement, CertificateEnum::GenesisKeyDelegation(_) => CertificateKind::GenesisKeyDelegation, - CertificateEnum::MoveInstantaneousRewardsCert(_) => { - CertificateKind::MoveInstantaneousRewardsCert - } + CertificateEnum::MoveInstantaneousRewardsCert(_) => + CertificateKind::MoveInstantaneousRewardsCert, + CertificateEnum::CommitteeHotKeyRegistration(_) => + CertificateKind::CommitteeHotKeyRegistration, + CertificateEnum::CommitteeHotKeyDeregistration(_) => + CertificateKind::CommitteeHotKeyDeregistration, + CertificateEnum::DrepDeregistration(_) => CertificateKind::DrepDeregistration, + CertificateEnum::DrepRegistration(_) => CertificateKind::DrepRegistration, + CertificateEnum::DrepUpdate(_) => CertificateKind::DrepUpdate, + CertificateEnum::StakeAndVoteDelegation(_) => CertificateKind::StakeAndVoteDelegation, + CertificateEnum::StakeRegistrationAndDelegation(_) => + CertificateKind::StakeRegistrationAndDelegation, + CertificateEnum::StakeVoteRegistrationAndDelegation(_) => + CertificateKind::StakeVoteRegistrationAndDelegation, + CertificateEnum::VoteDelegation(_) => CertificateKind::VoteDelegation, + CertificateEnum::VoteRegistrationAndDelegation(_) => + CertificateKind::VoteRegistrationAndDelegation } } @@ -154,10 +188,89 @@ impl Certificate { } } + pub fn as_committee_hot_key_registration(&self) -> Option { + match &self.0 { + CertificateEnum::CommitteeHotKeyRegistration(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_committee_hot_key_deregistration(&self) -> Option { + match &self.0 { + CertificateEnum::CommitteeHotKeyDeregistration(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_drep_deregistration(&self) -> Option { + match &self.0 { + CertificateEnum::DrepDeregistration(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_drep_registration(&self) -> Option { + match &self.0 { + CertificateEnum::DrepRegistration(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_drep_update(&self) -> Option { + match &self.0 { + CertificateEnum::DrepUpdate(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_stake_and_vote_delegation(&self) -> Option { + match &self.0 { + CertificateEnum::StakeAndVoteDelegation(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_stake_registration_and_delegation(&self) -> Option { + match &self.0 { + CertificateEnum::StakeRegistrationAndDelegation(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_stake_vote_registration_and_delegation(&self) -> Option { + match &self.0 { + CertificateEnum::StakeVoteRegistrationAndDelegation(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_vote_delegation(&self) -> Option { + match &self.0 { + CertificateEnum::VoteDelegation(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_vote_registration_and_delegation(&self) -> Option { + match &self.0 { + CertificateEnum::VoteRegistrationAndDelegation(x) => Some(x.clone()), + _ => None, + } + } + pub fn has_required_script_witness(&self) -> bool { match &self.0 { CertificateEnum::StakeDeregistration(x) => x.has_script_credentials(), CertificateEnum::StakeDelegation(x) => x.has_script_credentials(), + CertificateEnum::VoteDelegation(x) => x.has_script_credentials(), + CertificateEnum::StakeAndVoteDelegation(x) => x.has_script_credentials(), + CertificateEnum::StakeRegistrationAndDelegation(x) => x.has_script_credentials(), + CertificateEnum::StakeVoteRegistrationAndDelegation(x) => x.has_script_credentials(), + CertificateEnum::VoteRegistrationAndDelegation(x) => x.has_script_credentials(), + CertificateEnum::CommitteeHotKeyRegistration(x) => x.has_script_credentials(), + CertificateEnum::CommitteeHotKeyDeregistration(x) => x.has_script_credentials(), + CertificateEnum::DrepDeregistration(x) => x.has_script_credentials(), + CertificateEnum::DrepUpdate(x) => x.has_script_credentials(), _ => false, } } diff --git a/rust/src/serialization/certificates/certificate.rs b/rust/src/serialization/certificates/certificate.rs index 2bc2ee92..a1b50527 100644 --- a/rust/src/serialization/certificates/certificate.rs +++ b/rust/src/serialization/certificates/certificate.rs @@ -14,6 +14,16 @@ impl cbor_event::se::Serialize for CertificateEnum { CertificateEnum::PoolRetirement(x) => x.serialize(serializer), CertificateEnum::GenesisKeyDelegation(x) => x.serialize(serializer), CertificateEnum::MoveInstantaneousRewardsCert(x) => x.serialize(serializer), + CertificateEnum::CommitteeHotKeyRegistration(x) => x.serialize(serializer), + CertificateEnum::CommitteeHotKeyDeregistration(x) => x.serialize(serializer), + CertificateEnum::DrepRegistration(x) => x.serialize(serializer), + CertificateEnum::DrepDeregistration(x) => x.serialize(serializer), + CertificateEnum::DrepUpdate(x) => x.serialize(serializer), + CertificateEnum::StakeAndVoteDelegation(x) => x.serialize(serializer), + CertificateEnum::StakeRegistrationAndDelegation(x) => x.serialize(serializer), + CertificateEnum::StakeVoteRegistrationAndDelegation(x) => x.serialize(serializer), + CertificateEnum::VoteDelegation(x) => x.serialize(serializer), + CertificateEnum::VoteRegistrationAndDelegation(x) => x.serialize(serializer), } } } From efb9bacfbeab0f658fddffb694a49aaf27b52ea4 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 13 Aug 2023 00:32:08 +0400 Subject: [PATCH 032/349] update committee certs --- .../certificates/committee_hot_key_deregistration.rs | 4 ++++ .../certificates/committee_hot_key_registration.rs | 8 ++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs b/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs index 24f505bb..f1fbbe12 100644 --- a/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs +++ b/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs @@ -32,4 +32,8 @@ impl CommitteeHotKeyDeregistration { committee_cold_key: committee_cold_key.clone(), } } + + pub fn has_script_credentials(&self) -> bool { + self.committee_cold_key.has_script_hash() + } } diff --git a/rust/src/protocol_types/certificates/committee_hot_key_registration.rs b/rust/src/protocol_types/certificates/committee_hot_key_registration.rs index c2ca952a..ec18463f 100644 --- a/rust/src/protocol_types/certificates/committee_hot_key_registration.rs +++ b/rust/src/protocol_types/certificates/committee_hot_key_registration.rs @@ -22,11 +22,11 @@ impl_to_from!(CommitteeHotKeyRegistration); #[wasm_bindgen] impl CommitteeHotKeyRegistration { - pub fn committee_cold_keyhash(&self) -> StakeCredential { + pub fn committee_cold_key(&self) -> StakeCredential { self.committee_cold_key.clone() } - pub fn committee_hot_keyhash(&self) -> StakeCredential { + pub fn committee_hot_key(&self) -> StakeCredential { self.committee_hot_key.clone() } @@ -39,4 +39,8 @@ impl CommitteeHotKeyRegistration { committee_hot_key: committee_hot_key.clone(), } } + + pub fn has_script_credentials(&self) -> bool { + self.committee_cold_key.has_script_hash() + } } From 5bab2efc97f8be98b7a0b20213fd7412a18d753c Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 13 Aug 2023 00:32:21 +0400 Subject: [PATCH 033/349] update cert builder for new types --- rust/src/tx_builder/certificates_builder.rs | 81 +++++++++++++++++++-- 1 file changed, 75 insertions(+), 6 deletions(-) diff --git a/rust/src/tx_builder/certificates_builder.rs b/rust/src/tx_builder/certificates_builder.rs index 789d4aad..930bfab5 100644 --- a/rust/src/tx_builder/certificates_builder.rs +++ b/rust/src/tx_builder/certificates_builder.rs @@ -145,12 +145,19 @@ impl CertificatesBuilder { let mut refund = Coin::zero(); for (cert, _) in &self.certs { match &cert.0 { - CertificateEnum::StakeDeregistration(_cert) => { - refund = refund.checked_add(&key_deposit)?; + CertificateEnum::StakeDeregistration(cert) => { + if let Some(coin) = cert.coin { + refund = refund.checked_add(&coin)?; + } else { + refund = refund.checked_add(&key_deposit)?; + } } CertificateEnum::PoolRetirement(_cert) => { refund = refund.checked_add(&pool_deposit)?; } + CertificateEnum::DrepDeregistration(cert) => { + refund = refund.checked_add(&cert.coin)?; + } _ => {} } } @@ -168,8 +175,24 @@ impl CertificatesBuilder { CertificateEnum::PoolRegistration(_cert) => { deposit = deposit.checked_add(&pool_deposit)?; } - CertificateEnum::StakeRegistration(_cert) => { - deposit = deposit.checked_add(&key_deposit)?; + CertificateEnum::StakeRegistration(cert) => { + if let Some(coin) = cert.coin { + deposit = deposit.checked_add(&coin)?; + } else { + deposit = deposit.checked_add(&key_deposit)?; + } + } + CertificateEnum::DrepRegistration(cert) => { + deposit = deposit.checked_add(&cert.coin)?; + } + CertificateEnum::StakeRegistrationAndDelegation(cert) => { + deposit = deposit.checked_add(&cert.coin)?; + } + CertificateEnum::VoteRegistrationAndDelegation(cert) => { + deposit = deposit.checked_add(&cert.coin)?; + } + CertificateEnum::StakeVoteRegistrationAndDelegation(cert) => { + deposit = deposit.checked_add(&cert.coin)?; } _ => {} } @@ -212,16 +235,62 @@ fn witness_keys_for_cert(cert_enum: &Certificate) -> RequiredSigners { for owner in &cert.pool_params().pool_owners().0 { set.add(&owner.clone()); } - set.add(&Ed25519KeyHash::from_bytes(cert.pool_params().operator().to_bytes()).unwrap()); + set.add(&cert.pool_params().operator()); } CertificateEnum::PoolRetirement(cert) => { - set.add(&Ed25519KeyHash::from_bytes(cert.pool_keyhash().to_bytes()).unwrap()); + set.add(&cert.pool_keyhash()); } CertificateEnum::GenesisKeyDelegation(cert) => { set.add(&Ed25519KeyHash::from_bytes(cert.genesis_delegate_hash().to_bytes()).unwrap()); } // not witness as there is no single core node or genesis key that posts the certificate CertificateEnum::MoveInstantaneousRewardsCert(_cert) => {} + CertificateEnum::CommitteeHotKeyRegistration(cert) => { + if let StakeCredType::Key(key_hash) = &cert.committee_cold_key.0 { + set.add(key_hash); + } + } + CertificateEnum::CommitteeHotKeyDeregistration(cert) => { + if let StakeCredType::Key(key_hash) = &cert.committee_cold_key.0 { + set.add(key_hash); + } + } + CertificateEnum::DrepUpdate(cert) => { + if let StakeCredType::Key(key_hash) = &cert.voting_credential.0 { + set.add(key_hash); + } + } + CertificateEnum::DrepDeregistration(cert) => { + if let StakeCredType::Key(key_hash) = &cert.voting_credential.0 { + set.add(key_hash); + } + } + CertificateEnum::StakeAndVoteDelegation(cert) => { + if let StakeCredType::Key(key_hash) = &cert.stake_credential.0 { + set.add(key_hash); + } + } + CertificateEnum::VoteDelegation(cert) => { + if let StakeCredType::Key(key_hash) = &cert.stake_credential.0 { + set.add(key_hash); + } + } + CertificateEnum::StakeRegistrationAndDelegation(cert) => { + if let StakeCredType::Key(key_hash) = &cert.stake_credential.0 { + set.add(key_hash); + } + } + CertificateEnum::VoteRegistrationAndDelegation(cert) => { + if let StakeCredType::Key(key_hash) = &cert.stake_credential.0 { + set.add(key_hash); + } + } + CertificateEnum::StakeVoteRegistrationAndDelegation(cert) => { + if let StakeCredType::Key(key_hash) = &cert.stake_credential.0 { + set.add(key_hash); + } + } + CertificateEnum::DrepRegistration(_) => {} } set } From e854c8d9efb490c2d6d260a07b93b47a17eed061 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 14 Aug 2023 17:23:00 +0400 Subject: [PATCH 034/349] add voting procedures field to tx body --- rust/src/lib.rs | 10 ++++++++++ rust/src/serialization/general.rs | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index b06bca25..b540661a 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -332,6 +332,7 @@ pub struct TransactionBody { collateral_return: Option, total_collateral: Option, reference_inputs: Option, + voting_procedures: Option, } impl_to_from!(TransactionBody); @@ -518,6 +519,14 @@ impl TransactionBody { self.total_collateral.clone() } + pub fn set_voting_procedures(&mut self, voting_procedures: &VotingProcedures) { + self.voting_procedures = Some(voting_procedures.clone()); + } + + pub fn voting_procedures(&self) -> Option { + self.voting_procedures.clone() + } + /// !!! DEPRECATED !!! /// This constructor uses outdated slot number format for the ttl value. /// Use `.new_tx_body` and then `.set_ttl` instead @@ -564,6 +573,7 @@ impl TransactionBody { collateral_return: None, total_collateral: None, reference_inputs: None, + voting_procedures: None, } } } diff --git a/rust/src/serialization/general.rs b/rust/src/serialization/general.rs index 1fd79831..fe2be4a8 100644 --- a/rust/src/serialization/general.rs +++ b/rust/src/serialization/general.rs @@ -362,6 +362,10 @@ impl cbor_event::se::Serialize for TransactionBody { serializer.write_unsigned_integer(18)?; field.serialize(serializer)?; } + if let Some(field) = &self.voting_procedures { + serializer.write_unsigned_integer(19)?; + field.serialize(serializer)?; + } Ok(serializer) } } @@ -389,6 +393,7 @@ impl Deserialize for TransactionBody { let mut collateral_return = None; let mut total_collateral = None; let mut reference_inputs = None; + let mut voting_procedures = None; let mut read = 0; while match len { cbor_event::Len::Len(n) => read < n as usize, @@ -598,6 +603,18 @@ impl Deserialize for TransactionBody { .map_err(|e| e.annotate("reference_inputs"))?, ); } + 19 => { + if voting_procedures.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(19)).into()); + } + voting_procedures = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(VotingProcedures::deserialize(raw)?) + })() + .map_err(|e| e.annotate("voting_procedures"))?, + ); + } unknown_key => { return Err( DeserializeFailure::UnknownKey(Key::Uint(unknown_key)).into() @@ -658,6 +675,7 @@ impl Deserialize for TransactionBody { collateral_return, total_collateral, reference_inputs, + voting_procedures, }) })() .map_err(|e| e.annotate("TransactionBody")) From 4fbbe6e6d85fe42646abb226e8e339b7cc04fcec Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 14 Aug 2023 17:24:07 +0400 Subject: [PATCH 035/349] add new redeemer type for voting --- rust/src/plutus.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rust/src/plutus.rs b/rust/src/plutus.rs index e1fca2e7..00cd831d 100644 --- a/rust/src/plutus.rs +++ b/rust/src/plutus.rs @@ -979,6 +979,7 @@ pub enum RedeemerTagKind { Mint, Cert, Reward, + Vote, } #[wasm_bindgen] @@ -1007,6 +1008,10 @@ impl RedeemerTag { Self(RedeemerTagKind::Reward) } + pub fn new_vote() -> Self { + Self(RedeemerTagKind::Vote) + } + pub fn kind(&self) -> RedeemerTagKind { self.0 } @@ -1966,6 +1971,7 @@ impl cbor_event::se::Serialize for RedeemerTagKind { RedeemerTagKind::Mint => serializer.write_unsigned_integer(1u64), RedeemerTagKind::Cert => serializer.write_unsigned_integer(2u64), RedeemerTagKind::Reward => serializer.write_unsigned_integer(3u64), + RedeemerTagKind::Vote => serializer.write_unsigned_integer(4u64), } } } @@ -1978,6 +1984,7 @@ impl Deserialize for RedeemerTagKind { Ok(1) => Ok(RedeemerTagKind::Mint), Ok(2) => Ok(RedeemerTagKind::Cert), Ok(3) => Ok(RedeemerTagKind::Reward), + Ok(4) => Ok(RedeemerTagKind::Vote), Ok(_) | Err(_) => Err(DeserializeFailure::NoVariantMatched.into()), } })() From d91874a31334c747f61546107f3ae300eb9e990f Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 14 Aug 2023 17:24:42 +0400 Subject: [PATCH 036/349] fix formating --- rust/src/protocol_types/governance/voting_procedures.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rust/src/protocol_types/governance/voting_procedures.rs b/rust/src/protocol_types/governance/voting_procedures.rs index 51e81858..b58e305c 100644 --- a/rust/src/protocol_types/governance/voting_procedures.rs +++ b/rust/src/protocol_types/governance/voting_procedures.rs @@ -14,7 +14,9 @@ use std::collections::BTreeMap; JsonSchema, )] #[wasm_bindgen] -pub struct VotingProcedures(pub(crate) BTreeMap>); +pub struct VotingProcedures( + pub(crate) BTreeMap>, +); impl_to_from!(VotingProcedures); From 49339acacdaf6ef136001a374bcb5ddb1438f34b Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 14 Aug 2023 17:24:59 +0400 Subject: [PATCH 037/349] update voter type --- rust/src/protocol_types/governance/voter.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/rust/src/protocol_types/governance/voter.rs b/rust/src/protocol_types/governance/voter.rs index 3bf5eeb0..3213f184 100644 --- a/rust/src/protocol_types/governance/voter.rs +++ b/rust/src/protocol_types/governance/voter.rs @@ -93,4 +93,21 @@ impl Voter { _ => None, } } + + pub fn has_script_credentials(&self) -> bool { + match &self.0 { + VoterEnum::ConstitutionalCommitteeHotKey(cred) => + cred.has_script_hash(), + VoterEnum::DRep(cred) => cred.has_script_hash(), + VoterEnum::StakingPool(_) => false, + } + } + + pub fn to_keyhash(&self) -> Option { + match &self.0 { + VoterEnum::ConstitutionalCommitteeHotKey(cred) => cred.to_keyhash(), + VoterEnum::DRep(cred) => cred.to_keyhash(), + VoterEnum::StakingPool(key_hash) => Some(key_hash.clone()), + } + } } From 9f821b8caa2a7623ced2a32e705ef57edf1cead6 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 14 Aug 2023 17:25:13 +0400 Subject: [PATCH 038/349] add voter builder --- rust/src/tx_builder/vote_builder.rs | 195 ++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 rust/src/tx_builder/vote_builder.rs diff --git a/rust/src/tx_builder/vote_builder.rs b/rust/src/tx_builder/vote_builder.rs new file mode 100644 index 00000000..4207c932 --- /dev/null +++ b/rust/src/tx_builder/vote_builder.rs @@ -0,0 +1,195 @@ +use crate::tx_builder::script_structs::*; +use crate::*; +use std::collections::BTreeMap; + +#[derive(Clone, Debug)] +struct VoterVotes { + script_witness: Option, + votes: BTreeMap, +} + +#[wasm_bindgen] +#[derive(Clone, Debug)] +pub struct VotingBuilder { + votes: BTreeMap, +} + +#[wasm_bindgen] +impl VotingBuilder { + pub fn new() -> Self { + Self { + votes: BTreeMap::new(), + } + } + + pub fn add( + &mut self, + voter: Voter, + gov_action_id: GovernanceActionId, + voting_procedure: VotingProcedure, + ) -> Result<(), JsError> { + if voter.has_script_credentials() { + return Err(JsError::from_str( + "Your voter has a required script witness.\ + Please use .add_with_plutus_witness or .add_with_native_script instead.", + )); + } + + let voter_votes = self.votes.entry(voter).or_insert(VoterVotes { + script_witness: None, + votes: BTreeMap::new(), + }); + + voter_votes.votes.insert(gov_action_id, voting_procedure); + + Ok(()) + } + + pub fn add_with_plutus_witness( + &mut self, + voter: Voter, + gov_action_id: GovernanceActionId, + voting_procedure: VotingProcedure, + witness: &PlutusWitness, + ) -> Result<(), JsError> { + if !voter.has_script_credentials() { + return Err(JsError::from_str( + "Your voter does not have a required script witness.\ + Please use .add instead.", + )); + } + + let voter_votes = self.votes.entry(voter).or_insert(VoterVotes { + script_witness: Some(ScriptWitnessType::PlutusScriptWitness(witness.clone())), + votes: BTreeMap::new(), + }); + + voter_votes.votes.insert(gov_action_id, voting_procedure); + + Ok(()) + } + + pub fn add_with_native_script( + &mut self, + voter: Voter, + gov_action_id: GovernanceActionId, + voting_procedure: VotingProcedure, + native_script_source: &NativeScriptSource, + ) -> Result<(), JsError> { + if !voter.has_script_credentials() { + return Err(JsError::from_str( + "Your voter does not have a required script witness.\ + Please use .add instead.", + )); + } + + let voter_votes = self.votes.entry(voter).or_insert(VoterVotes { + script_witness: Some(ScriptWitnessType::NativeScriptWitness( + native_script_source.0.clone(), + )), + votes: BTreeMap::new(), + }); + + voter_votes.votes.insert(gov_action_id, voting_procedure); + + Ok(()) + } + + pub(crate) fn get_required_signers(&self) -> RequiredSignersSet { + let mut set = RequiredSignersSet::new(); + for (voter, voter_votes) in &self.votes { + let req_signature = voter.to_keyhash(); + if let Some(req_signature) = req_signature { + set.insert(req_signature); + } + + if let Some(ScriptWitnessType::NativeScriptWitness(script_source)) = + &voter_votes.script_witness + { + set.extend(script_source.required_signers()); + } + } + set + } + + pub fn get_plutus_witnesses(&self) -> PlutusWitnesses { + let tag = RedeemerTag::new_vote(); + let mut scripts = PlutusWitnesses::new(); + for (i, (_, voter_votes)) in self.votes.iter().enumerate() { + if let Some(ScriptWitnessType::PlutusScriptWitness(s)) = &voter_votes.script_witness { + let index = BigNum::from(i); + scripts.add(&s.clone_with_redeemer_index_and_tag(&index, &tag)); + } + } + scripts + } + + pub fn get_ref_inputs(&self) -> TransactionInputs { + let mut inputs = Vec::new(); + for (_, voter_votes) in &self.votes { + match &voter_votes.script_witness { + Some(ScriptWitnessType::NativeScriptWitness(script_source)) => { + if let NativeScriptSourceEnum::RefInput(input, _, _) = script_source { + inputs.push(input.clone()); + } + } + Some(ScriptWitnessType::PlutusScriptWitness(plutus_witness)) => { + if let Some(DatumSourceEnum::RefInput(input)) = &plutus_witness.datum { + inputs.push(input.clone()); + } + if let PlutusScriptSourceEnum::RefInput(input, _, _) = &plutus_witness.script { + inputs.push(input.clone()); + } + } + None => {} + } + } + TransactionInputs(inputs) + } + + pub fn get_native_scripts(&self) -> NativeScripts { + let mut scripts = NativeScripts::new(); + for (_, voter_votes) in &self.votes { + if let Some(ScriptWitnessType::NativeScriptWitness( + NativeScriptSourceEnum::NativeScript(script), + )) = &voter_votes.script_witness + { + scripts.add(script); + } + } + scripts + } + + pub(crate) fn get_used_plutus_lang_versions(&self) -> BTreeSet { + let mut used_langs = BTreeSet::new(); + for (_, voter_votes) in &self.votes { + if let Some(ScriptWitnessType::PlutusScriptWitness(s)) = &voter_votes.script_witness { + if let Some(lang) = s.script.language() { + used_langs.insert(lang.clone()); + } + } + } + used_langs + } + + pub fn has_plutus_scripts(&self) -> bool { + for (_, voter_votes) in &self.votes { + if let Some(ScriptWitnessType::PlutusScriptWitness(_)) = voter_votes.script_witness { + return true; + } + } + false + } + + pub fn build(&self) -> VotingProcedures { + let mut voters = BTreeMap::new(); + for (voter, voter_votes) in &self.votes { + let mut votes = BTreeMap::new(); + for (action, voting_procedure) in &voter_votes.votes { + votes.insert(action.clone(), voting_procedure.clone()); + } + voters.insert(voter.clone(), votes); + } + VotingProcedures(voters) + } +} From 2ea02ca376aa7d7bbe555f4c4d0fea32a1d6ff6d Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 14 Aug 2023 17:25:18 +0400 Subject: [PATCH 039/349] add voter builder to tx builder --- rust/src/tx_builder.rs | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/rust/src/tx_builder.rs b/rust/src/tx_builder.rs index 460585ae..4a0308c6 100644 --- a/rust/src/tx_builder.rs +++ b/rust/src/tx_builder.rs @@ -8,6 +8,7 @@ pub mod tx_batch_builder; pub mod mint_builder; pub mod certificates_builder; pub mod withdrawals_builder; +pub mod vote_builder; mod batch_tools; mod script_structs; @@ -22,6 +23,7 @@ use crate::tx_builder::certificates_builder::CertificatesBuilder; use crate::tx_builder::withdrawals_builder::WithdrawalsBuilder; use crate::tx_builder::script_structs::{PlutusWitness, PlutusWitnesses}; use crate::tx_builder::mint_builder::{MintBuilder, MintWitness}; +use crate::tx_builder::vote_builder::VotingBuilder; pub(crate) fn fake_private_key() -> Bip32PrivateKey { Bip32PrivateKey::from_bytes(&[ @@ -67,6 +69,9 @@ fn count_needed_vkeys(tx_builder: &TransactionBuilder) -> usize { if let Some(certs_builder) = &tx_builder.certs { input_hashes.extend(certs_builder.get_required_signers()); } + if let Some(voting_builder) = &tx_builder.voting { + input_hashes.extend(voting_builder.get_required_signers()); + } input_hashes.len() } @@ -343,6 +348,7 @@ pub struct TransactionBuilder { collateral_return: Option, total_collateral: Option, reference_inputs: HashSet, + voting: Option, } #[wasm_bindgen] @@ -998,6 +1004,10 @@ impl TransactionBuilder { self.withdrawals = Some(withdrawals.clone()); } + pub fn set_voting(&mut self, voting: &VotingBuilder) { + self.voting = Some(voting.clone()); + } + pub fn get_auxiliary_data(&self) -> Option { self.auxiliary_data.clone() } @@ -1253,6 +1263,7 @@ impl TransactionBuilder { collateral_return: None, total_collateral: None, reference_inputs: HashSet::new(), + voting: None, } } @@ -1280,6 +1291,12 @@ impl TransactionBuilder { } } + if let Some(votig) = &self.voting { + for input in votig.get_ref_inputs().0 { + inputs.insert(input); + } + } + let vec_inputs = inputs.into_iter().collect(); TransactionInputs(vec_inputs) } @@ -1771,6 +1788,10 @@ impl TransactionBuilder { used_langs.append(&mut withdrawals_builder.get_used_plutus_lang_versions()); plutus_witnesses.0.append(&mut withdrawals_builder.get_plutus_witnesses().0) } + if let Some(voting_builder) = self.voting.clone() { + used_langs.append(&mut voting_builder.get_used_plutus_lang_versions()); + plutus_witnesses.0.append(&mut voting_builder.get_plutus_witnesses().0) + } if plutus_witnesses.len() > 0 { let (_scripts, datums, redeemers) = plutus_witnesses.collect(); @@ -1836,6 +1857,7 @@ impl TransactionBuilder { collateral_return: self.collateral_return.clone(), total_collateral: self.total_collateral.clone(), reference_inputs: self.get_reference_inputs().to_option(), + voting_procedures: self.voting.as_ref().map(|x| x.build()), }; // we must build a tx with fake data (of correct size) to check the final Transaction size let full_tx = fake_full_tx(self, built)?; @@ -1893,6 +1915,11 @@ impl TransactionBuilder { ns.add(s); }); } + if let Some(voting_builder) = &self.voting { + voting_builder.get_native_scripts().0.iter().for_each(|s| { + ns.add(s); + }); + } if ns.len() > 0 { Some(ns) @@ -1928,6 +1955,11 @@ impl TransactionBuilder { res.add(s); }) } + if let Some(voting_builder) = &self.voting { + voting_builder.get_plutus_witnesses().0.iter().for_each(|s| { + res.add(s); + }) + } if res.len() > 0 { Some(res) } else { @@ -1968,6 +2000,9 @@ impl TransactionBuilder { if self.withdrawals.as_ref().map_or(false, |w| w.has_plutus_scripts()) { return true; } + if self.voting.as_ref().map_or(false, |w| w.has_plutus_scripts()) { + return true; + } return false; From 42b9b7df3756a9bf2b845e5dfb379aa37db87b8e Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 14 Aug 2023 17:39:37 +0400 Subject: [PATCH 040/349] fix naming in cert builder --- rust/src/tx_builder/certificates_builder.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rust/src/tx_builder/certificates_builder.rs b/rust/src/tx_builder/certificates_builder.rs index 930bfab5..e7728f1d 100644 --- a/rust/src/tx_builder/certificates_builder.rs +++ b/rust/src/tx_builder/certificates_builder.rs @@ -152,7 +152,7 @@ impl CertificatesBuilder { refund = refund.checked_add(&key_deposit)?; } } - CertificateEnum::PoolRetirement(_cert) => { + CertificateEnum::PoolRetirement(_) => { refund = refund.checked_add(&pool_deposit)?; } CertificateEnum::DrepDeregistration(cert) => { @@ -172,7 +172,7 @@ impl CertificatesBuilder { let mut deposit = Coin::zero(); for (cert, _) in &self.certs { match &cert.0 { - CertificateEnum::PoolRegistration(_cert) => { + CertificateEnum::PoolRegistration(_) => { deposit = deposit.checked_add(&pool_deposit)?; } CertificateEnum::StakeRegistration(cert) => { @@ -220,7 +220,7 @@ fn witness_keys_for_cert(cert_enum: &Certificate) -> RequiredSigners { let mut set = RequiredSigners::new(); match &cert_enum.0 { // stake key registrations do not require a witness - CertificateEnum::StakeRegistration(_cert) => {} + CertificateEnum::StakeRegistration(_) => {} CertificateEnum::StakeDeregistration(cert) => { if let Some(key) = cert.stake_credential().to_keyhash() { set.add(&key); From e941d88ff419faf84e07f4c5e30b721525323d3c Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 14 Aug 2023 17:40:30 +0400 Subject: [PATCH 041/349] deposit/refund calculator update --- rust/src/utils.rs | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/rust/src/utils.rs b/rust/src/utils.rs index 0d403ec3..81df8518 100644 --- a/rust/src/utils.rs +++ b/rust/src/utils.rs @@ -1306,8 +1306,15 @@ pub fn internal_get_implicit_input( .0 .iter() .try_fold(to_bignum(0), |acc, ref cert| match &cert.0 { - CertificateEnum::PoolRetirement(_cert) => acc.checked_add(&pool_deposit), - CertificateEnum::StakeDeregistration(_cert) => acc.checked_add(&key_deposit), + CertificateEnum::StakeDeregistration(cert) => { + if let Some(coin) = cert.coin { + acc.checked_add(&coin) + } else { + acc.checked_add(&key_deposit) + } + } + CertificateEnum::PoolRetirement(_) => acc.checked_add(&pool_deposit), + CertificateEnum::DrepDeregistration(cert) => acc.checked_add(&cert.coin), _ => Ok(acc), })?, }; @@ -1328,8 +1335,18 @@ pub fn internal_get_deposit( .0 .iter() .try_fold(to_bignum(0), |acc, ref cert| match &cert.0 { - CertificateEnum::PoolRegistration(_cert) => acc.checked_add(&pool_deposit), - CertificateEnum::StakeRegistration(_cert) => acc.checked_add(&key_deposit), + CertificateEnum::PoolRegistration(_) => acc.checked_add(&pool_deposit), + CertificateEnum::StakeRegistration(cert) => { + if let Some(coin) = cert.coin { + acc.checked_add(&coin) + } else { + acc.checked_add(&key_deposit) + } + } + CertificateEnum::DrepRegistration(cert) => acc.checked_add(&cert.coin), + CertificateEnum::StakeRegistrationAndDelegation(cert) => acc.checked_add(&cert.coin), + CertificateEnum::VoteRegistrationAndDelegation(cert) => acc.checked_add(&cert.coin), + CertificateEnum::StakeVoteRegistrationAndDelegation(cert) => acc.checked_add(&cert.coin), _ => Ok(acc), })?, }; From 66e13ba36c1a8d86e841adde12bf7b09ab43beda Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 15 Aug 2023 00:11:32 +0400 Subject: [PATCH 042/349] add index const --- .../committee_hot_key_deregistration.rs | 14 +++++++++---- .../committee_hot_key_registration.rs | 14 +++++++++---- .../certificates/drep_deregistration.rs | 6 ++++++ .../certificates/drep_registration.rs | 6 ++++++ .../serialization/certificates/drep_update.rs | 6 ++++++ .../certificates/genesis_key_delegation.rs | 20 +++++++++++++------ .../move_instantaneous_rewards_cert.rs | 20 +++++++++++++------ .../certificates/pool_registration.rs | 20 +++++++++++++------ .../certificates/pool_retirement.rs | 20 +++++++++++++------ .../certificates/stake_and_vote_delegation.rs | 6 ++++++ .../certificates/stake_delegation.rs | 20 +++++++++++++------ .../certificates/stake_deregistration.rs | 20 +++++++++++++------ .../stake_registration_and_delegation.rs | 6 ++++++ .../stake_vote_registration_and_delegation.rs | 6 ++++++ .../certificates/vote_delegation.rs | 6 ++++++ .../vote_registration_and_delegation.rs | 6 ++++++ 16 files changed, 152 insertions(+), 44 deletions(-) diff --git a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs index af5c4d69..8cd7cdc2 100644 --- a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs @@ -1,6 +1,12 @@ use crate::*; -const UNREG_COMMITTEE_HOT_KEY_CERT: u64 = 15; +const UNREG_COMMITTEE_HOT_KEY_CERT_INDEX: u64 = 15; + +impl CommitteeHotKeyDeregistration { + pub(crate) const fn serialization_index() -> u64 { + UNREG_COMMITTEE_HOT_KEY_CERT_INDEX + } +} impl cbor_event::se::Serialize for CommitteeHotKeyDeregistration { fn serialize<'se, W: Write>( @@ -8,7 +14,7 @@ impl cbor_event::se::Serialize for CommitteeHotKeyDeregistration { serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(2))?; - serializer.write_unsigned_integer(UNREG_COMMITTEE_HOT_KEY_CERT)?; + serializer.write_unsigned_integer(UNREG_COMMITTEE_HOT_KEY_CERT_INDEX)?; self.committee_cold_key.serialize(serializer)?; Ok(serializer) } @@ -31,10 +37,10 @@ impl Deserialize for CommitteeHotKeyDeregistration { } let cert_index = raw.unsigned_integer()?; - if cert_index != UNREG_COMMITTEE_HOT_KEY_CERT { + if cert_index != UNREG_COMMITTEE_HOT_KEY_CERT_INDEX { return Err(DeserializeFailure::FixedValueMismatch { found: Key::Uint(cert_index), - expected: Key::Uint(UNREG_COMMITTEE_HOT_KEY_CERT), + expected: Key::Uint(UNREG_COMMITTEE_HOT_KEY_CERT_INDEX), }) .map_err(|e| DeserializeError::from(e).annotate("cert_index")); } diff --git a/rust/src/serialization/certificates/committee_hot_key_registration.rs b/rust/src/serialization/certificates/committee_hot_key_registration.rs index e95353d5..1f231cf9 100644 --- a/rust/src/serialization/certificates/committee_hot_key_registration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_registration.rs @@ -1,6 +1,12 @@ use crate::*; -const REG_COMMITTEE_HOT_KEY_CERT: u64 = 14; +const REG_COMMITTEE_HOT_KEY_CERT_INDEX: u64 = 14; + +impl CommitteeHotKeyRegistration { + pub(crate) const fn serialization_index() -> u64 { + REG_COMMITTEE_HOT_KEY_CERT_INDEX + } +} impl cbor_event::se::Serialize for CommitteeHotKeyRegistration { fn serialize<'se, W: Write>( @@ -8,7 +14,7 @@ impl cbor_event::se::Serialize for CommitteeHotKeyRegistration { serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(3))?; - serializer.write_unsigned_integer(REG_COMMITTEE_HOT_KEY_CERT)?; + serializer.write_unsigned_integer(REG_COMMITTEE_HOT_KEY_CERT_INDEX)?; self.committee_cold_key.serialize(serializer)?; self.committee_hot_key.serialize(serializer)?; Ok(serializer) @@ -32,10 +38,10 @@ impl Deserialize for CommitteeHotKeyRegistration { } let cert_index = raw.unsigned_integer()?; - if cert_index != REG_COMMITTEE_HOT_KEY_CERT { + if cert_index != REG_COMMITTEE_HOT_KEY_CERT_INDEX { return Err(DeserializeFailure::FixedValueMismatch { found: Key::Uint(cert_index), - expected: Key::Uint(REG_COMMITTEE_HOT_KEY_CERT), + expected: Key::Uint(REG_COMMITTEE_HOT_KEY_CERT_INDEX), }) .map_err(|e| DeserializeError::from(e).annotate("cert_index")); } diff --git a/rust/src/serialization/certificates/drep_deregistration.rs b/rust/src/serialization/certificates/drep_deregistration.rs index 6512005d..f4884dfe 100644 --- a/rust/src/serialization/certificates/drep_deregistration.rs +++ b/rust/src/serialization/certificates/drep_deregistration.rs @@ -2,6 +2,12 @@ use crate::*; const DEREG_DREP_CERT_INDEX: u64 = 17; +impl DrepDeregistration { + pub(crate) const fn serialization_index() -> u64 { + DEREG_DREP_CERT_INDEX + } +} + impl cbor_event::se::Serialize for DrepDeregistration { fn serialize<'se, W: Write>( &self, diff --git a/rust/src/serialization/certificates/drep_registration.rs b/rust/src/serialization/certificates/drep_registration.rs index e0def46c..401de7a0 100644 --- a/rust/src/serialization/certificates/drep_registration.rs +++ b/rust/src/serialization/certificates/drep_registration.rs @@ -2,6 +2,12 @@ use crate::*; const REG_DREP_CERT_INDEX: u64 = 16; +impl DrepRegistration { + pub(crate) const fn serialization_index() -> u64 { + REG_DREP_CERT_INDEX + } +} + impl cbor_event::se::Serialize for DrepRegistration { fn serialize<'se, W: Write>( &self, diff --git a/rust/src/serialization/certificates/drep_update.rs b/rust/src/serialization/certificates/drep_update.rs index d12894c3..c93aaf20 100644 --- a/rust/src/serialization/certificates/drep_update.rs +++ b/rust/src/serialization/certificates/drep_update.rs @@ -2,6 +2,12 @@ use crate::*; const UPDATE_DREP_CERT_INDEX: u64 = 18; +impl DrepUpdate { + pub(crate) const fn serialization_index() -> u64 { + UPDATE_DREP_CERT_INDEX + } +} + impl cbor_event::se::Serialize for DrepUpdate { fn serialize<'se, W: Write>( &self, diff --git a/rust/src/serialization/certificates/genesis_key_delegation.rs b/rust/src/serialization/certificates/genesis_key_delegation.rs index 6b37758d..f7ce72e8 100644 --- a/rust/src/serialization/certificates/genesis_key_delegation.rs +++ b/rust/src/serialization/certificates/genesis_key_delegation.rs @@ -1,5 +1,13 @@ use crate::*; +const GENESIS_KEY_DELEGATION_INDEX: u64 = 5; + +impl GenesisKeyDelegation { + pub(crate) const fn serialization_index() -> u64 { + GENESIS_KEY_DELEGATION_INDEX + } +} + impl cbor_event::se::Serialize for GenesisKeyDelegation { fn serialize<'se, W: Write>( &self, @@ -15,7 +23,7 @@ impl SerializeEmbeddedGroup for GenesisKeyDelegation { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(5u64)?; + serializer.write_unsigned_integer(GENESIS_KEY_DELEGATION_INDEX)?; self.genesishash.serialize(serializer)?; self.genesis_delegate_hash.serialize(serializer)?; self.vrf_keyhash.serialize(serializer)?; @@ -55,17 +63,17 @@ impl DeserializeEmbeddedGroup for GenesisKeyDelegation { _: cbor_event::Len, ) -> Result { (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 5 { + let cert_index = raw.unsigned_integer()?; + if cert_index != GENESIS_KEY_DELEGATION_INDEX { return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(5), + found: Key::Uint(cert_index), + expected: Key::Uint(GENESIS_KEY_DELEGATION_INDEX), } .into()); } Ok(()) })() - .map_err(|e| e.annotate("index_0"))?; + .map_err(|e| e.annotate("cert_index"))?; let genesishash = (|| -> Result<_, DeserializeError> { Ok(GenesisHash::deserialize(raw)?) })() .map_err(|e| e.annotate("genesishash"))?; diff --git a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs index 7f1d1c28..4616d5af 100644 --- a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs +++ b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs @@ -1,5 +1,13 @@ use crate::*; +const MIR_CERT_INDEX: u64 = 6; + +impl MoveInstantaneousRewardsCert { + pub(crate) const fn serialization_index() -> u64 { + MIR_CERT_INDEX + } +} + impl cbor_event::se::Serialize for MIRToStakeCredentials { fn serialize<'se, W: Write>( &self, @@ -117,7 +125,7 @@ impl SerializeEmbeddedGroup for MoveInstantaneousRewardsCert { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(6u64)?; + serializer.write_unsigned_integer(MIR_CERT_INDEX)?; self.move_instantaneous_reward.serialize(serializer)?; Ok(serializer) } @@ -155,17 +163,17 @@ impl DeserializeEmbeddedGroup for MoveInstantaneousRewardsCert { _: cbor_event::Len, ) -> Result { (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 6 { + let cert_index = raw.unsigned_integer()?; + if cert_index != MIR_CERT_INDEX { return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(6), + found: Key::Uint(cert_index), + expected: Key::Uint(MIR_CERT_INDEX), } .into()); } Ok(()) })() - .map_err(|e| e.annotate("index_0"))?; + .map_err(|e| e.annotate("cert_index"))?; let move_instantaneous_reward = (|| -> Result<_, DeserializeError> { Ok(MoveInstantaneousReward::deserialize(raw)?) })( ) diff --git a/rust/src/serialization/certificates/pool_registration.rs b/rust/src/serialization/certificates/pool_registration.rs index 012dbfed..4bec1fd7 100644 --- a/rust/src/serialization/certificates/pool_registration.rs +++ b/rust/src/serialization/certificates/pool_registration.rs @@ -1,5 +1,13 @@ use crate::*; +const REG_POOL_CERT_INDEX: u64 = 3; + +impl PoolRegistration { + pub(crate) const fn serialization_index() -> u64 { + REG_POOL_CERT_INDEX + } +} + impl cbor_event::se::Serialize for Relays { fn serialize<'se, W: Write>( &self, @@ -158,7 +166,7 @@ impl SerializeEmbeddedGroup for PoolRegistration { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(3u64)?; + serializer.write_unsigned_integer(REG_POOL_CERT_INDEX)?; self.pool_params.serialize_as_embedded_group(serializer)?; Ok(serializer) } @@ -196,17 +204,17 @@ impl DeserializeEmbeddedGroup for PoolRegistration { len: cbor_event::Len, ) -> Result { (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 3 { + let cert_index = raw.unsigned_integer()?; + if cert_index != REG_POOL_CERT_INDEX { return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(3), + found: Key::Uint(cert_index), + expected: Key::Uint(REG_POOL_CERT_INDEX), } .into()); } Ok(()) })() - .map_err(|e| e.annotate("index_0"))?; + .map_err(|e| e.annotate("cert_index"))?; let pool_params = (|| -> Result<_, DeserializeError> { Ok(PoolParams::deserialize_as_embedded_group(raw, len)?) })() diff --git a/rust/src/serialization/certificates/pool_retirement.rs b/rust/src/serialization/certificates/pool_retirement.rs index dda03415..c7cc4c0f 100644 --- a/rust/src/serialization/certificates/pool_retirement.rs +++ b/rust/src/serialization/certificates/pool_retirement.rs @@ -1,5 +1,13 @@ use crate::*; +const RETIRE_POOL_CERT_INDEX: u64 = 4; + +impl PoolRetirement { + pub(crate) const fn serialization_index() -> u64 { + RETIRE_POOL_CERT_INDEX + } +} + impl cbor_event::se::Serialize for PoolRetirement { fn serialize<'se, W: Write>( &self, @@ -15,7 +23,7 @@ impl SerializeEmbeddedGroup for PoolRetirement { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(4u64)?; + serializer.write_unsigned_integer(RETIRE_POOL_CERT_INDEX)?; self.pool_keyhash.serialize(serializer)?; self.epoch.serialize(serializer)?; Ok(serializer) @@ -54,17 +62,17 @@ impl DeserializeEmbeddedGroup for PoolRetirement { _: cbor_event::Len, ) -> Result { (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 4 { + let cert_index = raw.unsigned_integer()?; + if cert_index != RETIRE_POOL_CERT_INDEX { return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(4), + found: Key::Uint(cert_index), + expected: Key::Uint(RETIRE_POOL_CERT_INDEX), } .into()); } Ok(()) })() - .map_err(|e| e.annotate("index_0"))?; + .map_err(|e| e.annotate("cert_index"))?; let pool_keyhash = (|| -> Result<_, DeserializeError> { Ok(Ed25519KeyHash::deserialize(raw)?) })() .map_err(|e| e.annotate("pool_keyhash"))?; diff --git a/rust/src/serialization/certificates/stake_and_vote_delegation.rs b/rust/src/serialization/certificates/stake_and_vote_delegation.rs index fea24e6a..b61e5839 100644 --- a/rust/src/serialization/certificates/stake_and_vote_delegation.rs +++ b/rust/src/serialization/certificates/stake_and_vote_delegation.rs @@ -2,6 +2,12 @@ use crate::*; const STAKE_VOTE_DELEG_CERT_INDEX: u64 = 10; +impl StakeAndVoteDelegation { + pub(crate) const fn serialization_index() -> u64 { + STAKE_VOTE_DELEG_CERT_INDEX + } +} + impl cbor_event::se::Serialize for StakeAndVoteDelegation { fn serialize<'se, W: Write>( &self, diff --git a/rust/src/serialization/certificates/stake_delegation.rs b/rust/src/serialization/certificates/stake_delegation.rs index 4775918a..631423dc 100644 --- a/rust/src/serialization/certificates/stake_delegation.rs +++ b/rust/src/serialization/certificates/stake_delegation.rs @@ -1,5 +1,13 @@ use crate::*; +const STAKE_DELEGATION_CERT_INDEX: u64 = 2; + +impl StakeDelegation { + pub(crate) const fn serialization_index() -> u64 { + STAKE_DELEGATION_CERT_INDEX + } +} + impl cbor_event::se::Serialize for StakeDelegation { fn serialize<'se, W: Write>( &self, @@ -15,7 +23,7 @@ impl SerializeEmbeddedGroup for StakeDelegation { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(2u64)?; + serializer.write_unsigned_integer(STAKE_DELEGATION_CERT_INDEX)?; self.stake_credential.serialize(serializer)?; self.pool_keyhash.serialize(serializer)?; Ok(serializer) @@ -54,17 +62,17 @@ impl DeserializeEmbeddedGroup for StakeDelegation { _: cbor_event::Len, ) -> Result { (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 2 { + let cert_index = raw.unsigned_integer()?; + if cert_index != STAKE_DELEGATION_CERT_INDEX { return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(2), + found: Key::Uint(cert_index), + expected: Key::Uint(STAKE_DELEGATION_CERT_INDEX), } .into()); } Ok(()) })() - .map_err(|e| e.annotate("index_0"))?; + .map_err(|e| e.annotate("cert_index"))?; let stake_credential = (|| -> Result<_, DeserializeError> { Ok(StakeCredential::deserialize(raw)?) })() .map_err(|e| e.annotate("stake_credential"))?; diff --git a/rust/src/serialization/certificates/stake_deregistration.rs b/rust/src/serialization/certificates/stake_deregistration.rs index aac57700..e74f35d8 100644 --- a/rust/src/serialization/certificates/stake_deregistration.rs +++ b/rust/src/serialization/certificates/stake_deregistration.rs @@ -1,5 +1,13 @@ use crate::*; +pub(super) const DEREG_STAKE_CERT_INDEX: u64 = 1; + +impl StakeDeregistration { + pub(crate) const fn serialization_index() -> u64 { + DEREG_STAKE_CERT_INDEX + } +} + impl cbor_event::se::Serialize for StakeDeregistration { fn serialize<'se, W: Write>( &self, @@ -15,7 +23,7 @@ impl SerializeEmbeddedGroup for StakeDeregistration { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(1u64)?; + serializer.write_unsigned_integer(DEREG_STAKE_CERT_INDEX)?; self.stake_credential.serialize(serializer)?; Ok(serializer) } @@ -53,17 +61,17 @@ impl DeserializeEmbeddedGroup for StakeDeregistration { _: cbor_event::Len, ) -> Result { (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 1 { + let cert_index = raw.unsigned_integer()?; + if cert_index != DEREG_STAKE_CERT_INDEX { return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(1), + found: Key::Uint(cert_index), + expected: Key::Uint(DEREG_STAKE_CERT_INDEX), } .into()); } Ok(()) })() - .map_err(|e| e.annotate("index_0"))?; + .map_err(|e| e.annotate("cert_index"))?; let stake_credential = (|| -> Result<_, DeserializeError> { Ok(StakeCredential::deserialize(raw)?) })() .map_err(|e| e.annotate("stake_credential"))?; diff --git a/rust/src/serialization/certificates/stake_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_registration_and_delegation.rs index da6c2ad9..8a5a6403 100644 --- a/rust/src/serialization/certificates/stake_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/stake_registration_and_delegation.rs @@ -2,6 +2,12 @@ use crate::*; const STAKE_REG_DELEG_CERT_INDEX: u64 = 11; +impl StakeRegistrationAndDelegation { + pub(crate) const fn serialization_index() -> u64 { + STAKE_REG_DELEG_CERT_INDEX + } +} + impl cbor_event::se::Serialize for StakeRegistrationAndDelegation { fn serialize<'se, W: Write>( &self, diff --git a/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs index 500e67a3..614e4a38 100644 --- a/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs @@ -2,6 +2,12 @@ use crate::*; const STAKE_VOTE_REG_DELEG_CERT_INDEX: u64 = 13; +impl StakeRegistrationAndDelegation { + pub(crate) const fn serialization_index() -> u64 { + STAKE_VOTE_REG_DELEG_CERT_INDEX + } +} + impl cbor_event::se::Serialize for StakeVoteRegistrationAndDelegation { fn serialize<'se, W: Write>( &self, diff --git a/rust/src/serialization/certificates/vote_delegation.rs b/rust/src/serialization/certificates/vote_delegation.rs index 0934954a..aab93f23 100644 --- a/rust/src/serialization/certificates/vote_delegation.rs +++ b/rust/src/serialization/certificates/vote_delegation.rs @@ -2,6 +2,12 @@ use crate::*; const VOTE_CERT_INDEX: u64 = 9; +impl VoteDelegation { + pub(crate) const fn serialization_index() -> u64 { + VOTE_CERT_INDEX + } +} + impl cbor_event::se::Serialize for VoteDelegation { fn serialize<'se, W: Write>( &self, diff --git a/rust/src/serialization/certificates/vote_registration_and_delegation.rs b/rust/src/serialization/certificates/vote_registration_and_delegation.rs index bc5414fe..f8651cac 100644 --- a/rust/src/serialization/certificates/vote_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/vote_registration_and_delegation.rs @@ -2,6 +2,12 @@ use crate::*; const VOTE_REG_DELEG_CERT_INDEX: u64 = 12; +impl VoteRegistrationAndDelegation { + pub(crate) const fn serialization_index() -> u64 { + VOTE_REG_DELEG_CERT_INDEX + } +} + impl cbor_event::se::Serialize for VoteRegistrationAndDelegation { fn serialize<'se, W: Write>( &self, From 92770c899966bed7a26532406506628fcb235e56 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 15 Aug 2023 00:17:30 +0400 Subject: [PATCH 043/349] naming fix --- .../certificates/stake_vote_registration_and_delegation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs index 614e4a38..19046ba4 100644 --- a/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs @@ -2,7 +2,7 @@ use crate::*; const STAKE_VOTE_REG_DELEG_CERT_INDEX: u64 = 13; -impl StakeRegistrationAndDelegation { +impl StakeVoteRegistrationAndDelegation { pub(crate) const fn serialization_index() -> u64 { STAKE_VOTE_REG_DELEG_CERT_INDEX } From 5c2e08400e1737b4f7e30425341257d4ea396a35 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 15 Aug 2023 19:04:18 +0400 Subject: [PATCH 044/349] update consts --- .../certificates/committee_hot_key_deregistration.rs | 8 +------- .../certificates/committee_hot_key_registration.rs | 8 +------- .../src/serialization/certificates/drep_deregistration.rs | 8 +------- rust/src/serialization/certificates/drep_registration.rs | 8 +------- rust/src/serialization/certificates/drep_update.rs | 8 +------- .../serialization/certificates/genesis_key_delegation.rs | 8 +------- .../certificates/move_instantaneous_rewards_cert.rs | 8 +------- rust/src/serialization/certificates/pool_registration.rs | 8 +------- rust/src/serialization/certificates/pool_retirement.rs | 8 +------- .../certificates/stake_and_vote_delegation.rs | 8 +------- rust/src/serialization/certificates/stake_delegation.rs | 8 +------- .../serialization/certificates/stake_deregistration.rs | 6 ------ rust/src/serialization/certificates/stake_registration.rs | 4 ++++ .../certificates/stake_registration_and_delegation.rs | 8 +------- .../stake_vote_registration_and_delegation.rs | 8 +------- rust/src/serialization/certificates/vote_delegation.rs | 8 +------- .../certificates/vote_registration_and_delegation.rs | 8 +------- 17 files changed, 19 insertions(+), 111 deletions(-) diff --git a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs index 8cd7cdc2..0523d208 100644 --- a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs @@ -1,12 +1,6 @@ use crate::*; -const UNREG_COMMITTEE_HOT_KEY_CERT_INDEX: u64 = 15; - -impl CommitteeHotKeyDeregistration { - pub(crate) const fn serialization_index() -> u64 { - UNREG_COMMITTEE_HOT_KEY_CERT_INDEX - } -} +pub(super) const UNREG_COMMITTEE_HOT_KEY_CERT_INDEX: u64 = 15; impl cbor_event::se::Serialize for CommitteeHotKeyDeregistration { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/committee_hot_key_registration.rs b/rust/src/serialization/certificates/committee_hot_key_registration.rs index 1f231cf9..d1242497 100644 --- a/rust/src/serialization/certificates/committee_hot_key_registration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_registration.rs @@ -1,12 +1,6 @@ use crate::*; -const REG_COMMITTEE_HOT_KEY_CERT_INDEX: u64 = 14; - -impl CommitteeHotKeyRegistration { - pub(crate) const fn serialization_index() -> u64 { - REG_COMMITTEE_HOT_KEY_CERT_INDEX - } -} +pub(super) const REG_COMMITTEE_HOT_KEY_CERT_INDEX: u64 = 14; impl cbor_event::se::Serialize for CommitteeHotKeyRegistration { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/drep_deregistration.rs b/rust/src/serialization/certificates/drep_deregistration.rs index f4884dfe..077c7691 100644 --- a/rust/src/serialization/certificates/drep_deregistration.rs +++ b/rust/src/serialization/certificates/drep_deregistration.rs @@ -1,12 +1,6 @@ use crate::*; -const DEREG_DREP_CERT_INDEX: u64 = 17; - -impl DrepDeregistration { - pub(crate) const fn serialization_index() -> u64 { - DEREG_DREP_CERT_INDEX - } -} +pub(super) const DEREG_DREP_CERT_INDEX: u64 = 17; impl cbor_event::se::Serialize for DrepDeregistration { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/drep_registration.rs b/rust/src/serialization/certificates/drep_registration.rs index 401de7a0..6b7828b9 100644 --- a/rust/src/serialization/certificates/drep_registration.rs +++ b/rust/src/serialization/certificates/drep_registration.rs @@ -1,12 +1,6 @@ use crate::*; -const REG_DREP_CERT_INDEX: u64 = 16; - -impl DrepRegistration { - pub(crate) const fn serialization_index() -> u64 { - REG_DREP_CERT_INDEX - } -} +pub(super) const REG_DREP_CERT_INDEX: u64 = 16; impl cbor_event::se::Serialize for DrepRegistration { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/drep_update.rs b/rust/src/serialization/certificates/drep_update.rs index c93aaf20..4a9c187f 100644 --- a/rust/src/serialization/certificates/drep_update.rs +++ b/rust/src/serialization/certificates/drep_update.rs @@ -1,12 +1,6 @@ use crate::*; -const UPDATE_DREP_CERT_INDEX: u64 = 18; - -impl DrepUpdate { - pub(crate) const fn serialization_index() -> u64 { - UPDATE_DREP_CERT_INDEX - } -} +pub(super) const UPDATE_DREP_CERT_INDEX: u64 = 18; impl cbor_event::se::Serialize for DrepUpdate { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/genesis_key_delegation.rs b/rust/src/serialization/certificates/genesis_key_delegation.rs index f7ce72e8..7055fd13 100644 --- a/rust/src/serialization/certificates/genesis_key_delegation.rs +++ b/rust/src/serialization/certificates/genesis_key_delegation.rs @@ -1,12 +1,6 @@ use crate::*; -const GENESIS_KEY_DELEGATION_INDEX: u64 = 5; - -impl GenesisKeyDelegation { - pub(crate) const fn serialization_index() -> u64 { - GENESIS_KEY_DELEGATION_INDEX - } -} +pub(super) const GENESIS_KEY_DELEGATION_INDEX: u64 = 5; impl cbor_event::se::Serialize for GenesisKeyDelegation { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs index 4616d5af..121fa993 100644 --- a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs +++ b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs @@ -1,12 +1,6 @@ use crate::*; -const MIR_CERT_INDEX: u64 = 6; - -impl MoveInstantaneousRewardsCert { - pub(crate) const fn serialization_index() -> u64 { - MIR_CERT_INDEX - } -} +pub(super) const MIR_CERT_INDEX: u64 = 6; impl cbor_event::se::Serialize for MIRToStakeCredentials { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/pool_registration.rs b/rust/src/serialization/certificates/pool_registration.rs index 4bec1fd7..34b622ad 100644 --- a/rust/src/serialization/certificates/pool_registration.rs +++ b/rust/src/serialization/certificates/pool_registration.rs @@ -1,12 +1,6 @@ use crate::*; -const REG_POOL_CERT_INDEX: u64 = 3; - -impl PoolRegistration { - pub(crate) const fn serialization_index() -> u64 { - REG_POOL_CERT_INDEX - } -} +pub (super) const REG_POOL_CERT_INDEX: u64 = 3; impl cbor_event::se::Serialize for Relays { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/pool_retirement.rs b/rust/src/serialization/certificates/pool_retirement.rs index c7cc4c0f..b6aaa26b 100644 --- a/rust/src/serialization/certificates/pool_retirement.rs +++ b/rust/src/serialization/certificates/pool_retirement.rs @@ -1,12 +1,6 @@ use crate::*; -const RETIRE_POOL_CERT_INDEX: u64 = 4; - -impl PoolRetirement { - pub(crate) const fn serialization_index() -> u64 { - RETIRE_POOL_CERT_INDEX - } -} +pub(super) const RETIRE_POOL_CERT_INDEX: u64 = 4; impl cbor_event::se::Serialize for PoolRetirement { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/stake_and_vote_delegation.rs b/rust/src/serialization/certificates/stake_and_vote_delegation.rs index b61e5839..9af29372 100644 --- a/rust/src/serialization/certificates/stake_and_vote_delegation.rs +++ b/rust/src/serialization/certificates/stake_and_vote_delegation.rs @@ -1,12 +1,6 @@ use crate::*; -const STAKE_VOTE_DELEG_CERT_INDEX: u64 = 10; - -impl StakeAndVoteDelegation { - pub(crate) const fn serialization_index() -> u64 { - STAKE_VOTE_DELEG_CERT_INDEX - } -} +pub(super) const STAKE_VOTE_DELEG_CERT_INDEX: u64 = 10; impl cbor_event::se::Serialize for StakeAndVoteDelegation { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/stake_delegation.rs b/rust/src/serialization/certificates/stake_delegation.rs index 631423dc..5bf59cb2 100644 --- a/rust/src/serialization/certificates/stake_delegation.rs +++ b/rust/src/serialization/certificates/stake_delegation.rs @@ -1,12 +1,6 @@ use crate::*; -const STAKE_DELEGATION_CERT_INDEX: u64 = 2; - -impl StakeDelegation { - pub(crate) const fn serialization_index() -> u64 { - STAKE_DELEGATION_CERT_INDEX - } -} +pub(super) const STAKE_DELEGATION_CERT_INDEX: u64 = 2; impl cbor_event::se::Serialize for StakeDelegation { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/stake_deregistration.rs b/rust/src/serialization/certificates/stake_deregistration.rs index e74f35d8..c87ef68b 100644 --- a/rust/src/serialization/certificates/stake_deregistration.rs +++ b/rust/src/serialization/certificates/stake_deregistration.rs @@ -2,12 +2,6 @@ use crate::*; pub(super) const DEREG_STAKE_CERT_INDEX: u64 = 1; -impl StakeDeregistration { - pub(crate) const fn serialization_index() -> u64 { - DEREG_STAKE_CERT_INDEX - } -} - impl cbor_event::se::Serialize for StakeDeregistration { fn serialize<'se, W: Write>( &self, diff --git a/rust/src/serialization/certificates/stake_registration.rs b/rust/src/serialization/certificates/stake_registration.rs index f436c2e3..391f8751 100644 --- a/rust/src/serialization/certificates/stake_registration.rs +++ b/rust/src/serialization/certificates/stake_registration.rs @@ -1,4 +1,8 @@ use crate::*; +use cbor_event::Len; + +pub(super) const STAKE_REG_LEGACY_INDEX: u64 = 0; +pub(super) const STAKE_REG_CONWAY_INDEX: u64 = 7; impl cbor_event::se::Serialize for StakeRegistration { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/stake_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_registration_and_delegation.rs index 8a5a6403..7181eeb5 100644 --- a/rust/src/serialization/certificates/stake_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/stake_registration_and_delegation.rs @@ -1,12 +1,6 @@ use crate::*; -const STAKE_REG_DELEG_CERT_INDEX: u64 = 11; - -impl StakeRegistrationAndDelegation { - pub(crate) const fn serialization_index() -> u64 { - STAKE_REG_DELEG_CERT_INDEX - } -} +pub(super) const STAKE_REG_DELEG_CERT_INDEX: u64 = 11; impl cbor_event::se::Serialize for StakeRegistrationAndDelegation { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs index 19046ba4..2bd0dea4 100644 --- a/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs @@ -1,12 +1,6 @@ use crate::*; -const STAKE_VOTE_REG_DELEG_CERT_INDEX: u64 = 13; - -impl StakeVoteRegistrationAndDelegation { - pub(crate) const fn serialization_index() -> u64 { - STAKE_VOTE_REG_DELEG_CERT_INDEX - } -} +pub(super) const STAKE_VOTE_REG_DELEG_CERT_INDEX: u64 = 13; impl cbor_event::se::Serialize for StakeVoteRegistrationAndDelegation { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/vote_delegation.rs b/rust/src/serialization/certificates/vote_delegation.rs index aab93f23..bd91415e 100644 --- a/rust/src/serialization/certificates/vote_delegation.rs +++ b/rust/src/serialization/certificates/vote_delegation.rs @@ -1,12 +1,6 @@ use crate::*; -const VOTE_CERT_INDEX: u64 = 9; - -impl VoteDelegation { - pub(crate) const fn serialization_index() -> u64 { - VOTE_CERT_INDEX - } -} +pub(super) const VOTE_CERT_INDEX: u64 = 9; impl cbor_event::se::Serialize for VoteDelegation { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/vote_registration_and_delegation.rs b/rust/src/serialization/certificates/vote_registration_and_delegation.rs index f8651cac..a39090b8 100644 --- a/rust/src/serialization/certificates/vote_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/vote_registration_and_delegation.rs @@ -1,12 +1,6 @@ use crate::*; -const VOTE_REG_DELEG_CERT_INDEX: u64 = 12; - -impl VoteRegistrationAndDelegation { - pub(crate) const fn serialization_index() -> u64 { - VOTE_REG_DELEG_CERT_INDEX - } -} +pub(super) const VOTE_REG_DELEG_CERT_INDEX: u64 = 12; impl cbor_event::se::Serialize for VoteRegistrationAndDelegation { fn serialize<'se, W: Write>( From e53a1b2e4a362c70791dddadc3d959af1dafff7e Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 15 Aug 2023 19:05:57 +0400 Subject: [PATCH 045/349] add stake reg serialisation logic --- .../certificates/stake_registration.rs | 149 +++++++++++++----- 1 file changed, 112 insertions(+), 37 deletions(-) diff --git a/rust/src/serialization/certificates/stake_registration.rs b/rust/src/serialization/certificates/stake_registration.rs index 391f8751..409a89a3 100644 --- a/rust/src/serialization/certificates/stake_registration.rs +++ b/rust/src/serialization/certificates/stake_registration.rs @@ -9,20 +9,35 @@ impl cbor_event::se::Serialize for StakeRegistration { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - self.serialize_as_embedded_group(serializer) + if self.coin.is_some() { + serialize_as_conway(self, serializer) + } else { + serialize_as_legacy(self, serializer) + } } } -impl SerializeEmbeddedGroup for StakeRegistration { - fn serialize_as_embedded_group<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(0u64)?; - self.stake_credential.serialize(serializer)?; - Ok(serializer) +fn serialize_as_legacy<'se, W: Write>( + cert: &StakeRegistration, + serializer: &'se mut Serializer, +) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + serializer.write_unsigned_integer(STAKE_REG_LEGACY_INDEX)?; + cert.stake_credential.serialize(serializer)?; + Ok(serializer) +} + +fn serialize_as_conway<'se, W: Write>( + cert: &StakeRegistration, + serializer: &'se mut Serializer, +) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(3))?; + serializer.write_unsigned_integer(STAKE_REG_CONWAY_INDEX)?; + cert.stake_credential.serialize(serializer)?; + if let Some(coin) = cert.coin { + coin.serialize(serializer)?; } + Ok(serializer) } impl Deserialize for StakeRegistration { @@ -31,19 +46,11 @@ impl Deserialize for StakeRegistration { let len = raw.array()?; let ret = Self::deserialize_as_embedded_group(raw, len); match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } + Len::Indefinite => match raw.special()? { + CBORSpecial::Break => {} _ => return Err(DeserializeFailure::EndingBreakMissing.into()), }, + _ => {} } ret })() @@ -54,26 +61,94 @@ impl Deserialize for StakeRegistration { impl DeserializeEmbeddedGroup for StakeRegistration { fn deserialize_as_embedded_group( raw: &mut Deserializer, - _: cbor_event::Len, + len: Len, ) -> Result { - (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 0 { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(0), - } + let cert_index = raw.unsigned_integer()?; + match cert_index { + STAKE_REG_LEGACY_INDEX => deserialize_legacy(raw, cert_index, len), + STAKE_REG_CONWAY_INDEX => deserialize_conway(raw, cert_index, len), + _ => Err(DeserializeFailure::FixedValuesMismatch { + found: Key::Uint(cert_index), + expected: vec![ + Key::Uint(STAKE_REG_LEGACY_INDEX), + Key::Uint(STAKE_REG_CONWAY_INDEX), + ], + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")), + } + } +} + +fn deserialize_legacy( + raw: &mut Deserializer, + cert_index: u64, + len: Len, +) -> Result { + (|| -> Result<_, DeserializeError> { + if let Len::Len(n) = len { + if n != 2 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 2, + len, + "(cert_index, stake_credential)", + )) .into()); } - Ok(()) - })() - .map_err(|e| e.annotate("index_0"))?; + } + + if cert_index != STAKE_REG_LEGACY_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(STAKE_REG_LEGACY_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + let stake_credential = - (|| -> Result<_, DeserializeError> { Ok(StakeCredential::deserialize(raw)?) })() - .map_err(|e| e.annotate("stake_credential"))?; - Ok(StakeRegistration { + StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + + return Ok(StakeRegistration { stake_credential, coin: None, - }) - } + }); + })() + .map_err(|e| e.annotate("StakeRegistration (legacy)")) +} + +fn deserialize_conway( + raw: &mut Deserializer, + cert_index: u64, + len: Len, +) -> Result { + (|| -> Result<_, DeserializeError> { + if let Len::Len(n) = len { + if n != 3 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 3, + len, + "(cert_index, stake_credential, coin)", + )) + .into()); + } + } + + if cert_index != STAKE_REG_CONWAY_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(STAKE_REG_CONWAY_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + + let stake_credential = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + + let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; + + return Ok(StakeRegistration { + stake_credential, + coin: Some(coin), + }); + })() + .map_err(|e| e.annotate("StakeRegistration (conway)")) } From 4a95bf1bb4a235fff896cedd32e0b5561f56468d Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 15 Aug 2023 19:22:31 +0400 Subject: [PATCH 046/349] add deserialize_as_embedded_group --- .../committee_hot_key_deregistration.rs | 61 ++++++------ .../committee_hot_key_registration.rs | 69 ++++++++------ .../certificates/drep_deregistration.rs | 68 ++++++++------ .../certificates/drep_registration.rs | 92 +++++++++++-------- .../serialization/certificates/drep_update.rs | 86 +++++++++-------- .../certificates/stake_and_vote_delegation.rs | 75 ++++++++------- .../stake_registration_and_delegation.rs | 76 ++++++++------- .../stake_vote_registration_and_delegation.rs | 81 +++++++++------- .../certificates/vote_delegation.rs | 67 ++++++++------ .../vote_registration_and_delegation.rs | 74 ++++++++------- 10 files changed, 431 insertions(+), 318 deletions(-) diff --git a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs index 0523d208..e590e251 100644 --- a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs @@ -19,39 +19,48 @@ impl Deserialize for CommitteeHotKeyDeregistration { (|| -> Result<_, DeserializeError> { let len = raw.array()?; - if let cbor_event::Len::Len(n) = len { - if n != 2 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 2, - len, - "(cert_index, committee_cold_key)", - )) - .into()); - } - } - - let cert_index = raw.unsigned_integer()?; - if cert_index != UNREG_COMMITTEE_HOT_KEY_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(UNREG_COMMITTEE_HOT_KEY_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } - - let committee_cold_key = StakeCredential::deserialize(raw) - .map_err(|e| e.annotate("committee_cold_key"))?; - + let committee_dereg = + Self::deserialize_as_embedded_group(raw, len)?; if let cbor_event::Len::Indefinite = len { if raw.special()? != CBORSpecial::Break { return Err(DeserializeFailure::EndingBreakMissing.into()); } } - return Ok(CommitteeHotKeyDeregistration { - committee_cold_key, - }); + Ok(committee_dereg) })() .map_err(|e| e.annotate("CommitteeHotKeyDeregistration")) } } + +impl DeserializeEmbeddedGroup for CommitteeHotKeyDeregistration { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + if let cbor_event::Len::Len(n) = len { + if n != 2 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 2, + len, + "(cert_index, committee_cold_key)", + )) + .into()); + } + } + + let cert_index = raw.unsigned_integer()?; + if cert_index != UNREG_COMMITTEE_HOT_KEY_CERT_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(UNREG_COMMITTEE_HOT_KEY_CERT_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + + let committee_cold_key = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("committee_cold_key"))?; + + Ok(CommitteeHotKeyDeregistration { committee_cold_key }) + } +} diff --git a/rust/src/serialization/certificates/committee_hot_key_registration.rs b/rust/src/serialization/certificates/committee_hot_key_registration.rs index d1242497..71674754 100644 --- a/rust/src/serialization/certificates/committee_hot_key_registration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_registration.rs @@ -20,31 +20,7 @@ impl Deserialize for CommitteeHotKeyRegistration { (|| -> Result<_, DeserializeError> { let len = raw.array()?; - if let cbor_event::Len::Len(n) = len { - if n != 3 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 3, - len, - "(cert_index, committee_cold_key, committee_hot_key)", - )) - .into()); - } - } - - let cert_index = raw.unsigned_integer()?; - if cert_index != REG_COMMITTEE_HOT_KEY_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(REG_COMMITTEE_HOT_KEY_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } - - let committee_cold_key = StakeCredential::deserialize(raw) - .map_err(|e| e.annotate("committee_cold_key"))?; - - let committee_hot_key = StakeCredential::deserialize(raw) - .map_err(|e| e.annotate("committee_hot_key"))?; + let cert = Self::deserialize_as_embedded_group(raw, len)?; if let cbor_event::Len::Indefinite = len { if raw.special()? != CBORSpecial::Break { @@ -52,11 +28,46 @@ impl Deserialize for CommitteeHotKeyRegistration { } } - return Ok(CommitteeHotKeyRegistration { - committee_cold_key, - committee_hot_key, - }); + Ok(cert) })() .map_err(|e| e.annotate("CommitteeHotKeyRegistration")) } } + +impl DeserializeEmbeddedGroup for CommitteeHotKeyRegistration { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + if let cbor_event::Len::Len(n) = len { + if n != 3 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 3, + len, + "(cert_index, committee_cold_key, committee_hot_key)", + )) + .into()); + } + } + + let cert_index = raw.unsigned_integer()?; + if cert_index != REG_COMMITTEE_HOT_KEY_CERT_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(REG_COMMITTEE_HOT_KEY_CERT_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + + let committee_cold_key = StakeCredential::deserialize(raw) + .map_err(|e| e.annotate("committee_cold_key"))?; + + let committee_hot_key = StakeCredential::deserialize(raw) + .map_err(|e| e.annotate("committee_hot_key"))?; + + return Ok(CommitteeHotKeyRegistration { + committee_cold_key, + committee_hot_key, + }); + } +} diff --git a/rust/src/serialization/certificates/drep_deregistration.rs b/rust/src/serialization/certificates/drep_deregistration.rs index 077c7691..46633f39 100644 --- a/rust/src/serialization/certificates/drep_deregistration.rs +++ b/rust/src/serialization/certificates/drep_deregistration.rs @@ -20,30 +20,7 @@ impl Deserialize for DrepDeregistration { (|| -> Result<_, DeserializeError> { let len = raw.array()?; - if let cbor_event::Len::Len(n) = len { - if n != 3 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 3, - len, - "(cert_index, voting_credential, coin)", - )) - .into()); - } - } - - let cert_index = raw.unsigned_integer()?; - if cert_index != DEREG_DREP_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(DEREG_DREP_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } - - let voting_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("voting_credential"))?; - - let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; + let cert = Self::deserialize_as_embedded_group(raw, len)?; if let cbor_event::Len::Indefinite = len { if raw.special()? != CBORSpecial::Break { @@ -51,11 +28,46 @@ impl Deserialize for DrepDeregistration { } } - return Ok(DrepDeregistration { - voting_credential, - coin, - }); + Ok(cert) })() .map_err(|e| e.annotate("DrepDeregistration")) } } + +impl DeserializeEmbeddedGroup for DrepDeregistration { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + + if let cbor_event::Len::Len(n) = len { + if n != 3 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 3, + len, + "(cert_index, voting_credential, coin)", + )) + .into()); + } + } + + let cert_index = raw.unsigned_integer()?; + if cert_index != DEREG_DREP_CERT_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(DEREG_DREP_CERT_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + + let voting_credential = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("voting_credential"))?; + + let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; + + Ok(DrepDeregistration { + voting_credential, + coin, + }) + } +} diff --git a/rust/src/serialization/certificates/drep_registration.rs b/rust/src/serialization/certificates/drep_registration.rs index 6b7828b9..f073fed3 100644 --- a/rust/src/serialization/certificates/drep_registration.rs +++ b/rust/src/serialization/certificates/drep_registration.rs @@ -24,55 +24,67 @@ impl Deserialize for DrepRegistration { (|| -> Result<_, DeserializeError> { let len = raw.array()?; - if let cbor_event::Len::Len(n) = len { - if n != 4 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 4, - len, - "(cert_index, voting_credential, coin, anchor / null)", - )) - .into()); + let cert = Self::deserialize_as_embedded_group(raw, len)?; + + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); } } - let cert_index = raw.unsigned_integer()?; - if cert_index != REG_DREP_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(REG_DREP_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + Ok(cert) + })() + .map_err(|e| e.annotate("DrepRegistration")) + } +} + +impl DeserializeEmbeddedGroup for DrepRegistration { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + + if let cbor_event::Len::Len(n) = len { + if n != 4 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 4, + len, + "(cert_index, voting_credential, coin, anchor / null)", + )) + .into()); } + } - let voting_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("voting_credential"))?; + let cert_index = raw.unsigned_integer()?; + if cert_index != REG_DREP_CERT_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(REG_DREP_CERT_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } - let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; + let voting_credential = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("voting_credential"))?; - let anchor = (|| -> Result<_, DeserializeError> { - if raw.cbor_type()? == CBORType::Special { - if raw.special()? != CBORSpecial::Null { - return Err(DeserializeFailure::ExpectedNull.into()); - } - Ok(None) - } - else { - Ok(Some(Anchor::deserialize(raw)?)) - } - })().map_err(|e| e.annotate("anchor"))?; + let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; - if let cbor_event::Len::Indefinite = len { - if raw.special()? != CBORSpecial::Break { - return Err(DeserializeFailure::EndingBreakMissing.into()); + let anchor = (|| -> Result<_, DeserializeError> { + if raw.cbor_type()? == CBORType::Special { + if raw.special()? != CBORSpecial::Null { + return Err(DeserializeFailure::ExpectedNull.into()); } + Ok(None) } + else { + Ok(Some(Anchor::deserialize(raw)?)) + } + })().map_err(|e| e.annotate("anchor"))?; - return Ok(DrepRegistration { - voting_credential, - coin, - anchor, - }); - })() - .map_err(|e| e.annotate("DrepRegistration")) + Ok(DrepRegistration { + voting_credential, + coin, + anchor, + }) } -} +} \ No newline at end of file diff --git a/rust/src/serialization/certificates/drep_update.rs b/rust/src/serialization/certificates/drep_update.rs index 4a9c187f..d5683d39 100644 --- a/rust/src/serialization/certificates/drep_update.rs +++ b/rust/src/serialization/certificates/drep_update.rs @@ -23,52 +23,64 @@ impl Deserialize for DrepUpdate { (|| -> Result<_, DeserializeError> { let len = raw.array()?; - if let cbor_event::Len::Len(n) = len { - if n != 3 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 3, - len, - "(cert_index, voting_credential, anchor / null)", - )) - .into()); + let cert = Self::deserialize_as_embedded_group(raw, len)?; + + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); } } - let cert_index = raw.unsigned_integer()?; - if cert_index != UPDATE_DREP_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(UPDATE_DREP_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + Ok(cert) + })() + .map_err(|e| e.annotate("DrepUpdate")) + } +} + +impl DeserializeEmbeddedGroup for DrepUpdate { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + + if let cbor_event::Len::Len(n) = len { + if n != 3 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 3, + len, + "(cert_index, voting_credential, anchor / null)", + )) + .into()); } + } - let voting_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("voting_credential"))?; + let cert_index = raw.unsigned_integer()?; + if cert_index != UPDATE_DREP_CERT_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(UPDATE_DREP_CERT_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } - let anchor = (|| -> Result<_, DeserializeError> { - if raw.cbor_type()? == CBORType::Special { - if raw.special()? != CBORSpecial::Null { - return Err(DeserializeFailure::ExpectedNull.into()); - } - Ok(None) - } - else { - Ok(Some(Anchor::deserialize(raw)?)) - } - })().map_err(|e| e.annotate("anchor"))?; + let voting_credential = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("voting_credential"))?; - if let cbor_event::Len::Indefinite = len { - if raw.special()? != CBORSpecial::Break { - return Err(DeserializeFailure::EndingBreakMissing.into()); + let anchor = (|| -> Result<_, DeserializeError> { + if raw.cbor_type()? == CBORType::Special { + if raw.special()? != CBORSpecial::Null { + return Err(DeserializeFailure::ExpectedNull.into()); } + Ok(None) + } + else { + Ok(Some(Anchor::deserialize(raw)?)) } + })().map_err(|e| e.annotate("anchor"))?; - return Ok(DrepUpdate { - voting_credential, - anchor, - }); - })() - .map_err(|e| e.annotate("DrepUpdate")) + Ok(DrepUpdate { + voting_credential, + anchor, + }) } } diff --git a/rust/src/serialization/certificates/stake_and_vote_delegation.rs b/rust/src/serialization/certificates/stake_and_vote_delegation.rs index 9af29372..9c106e68 100644 --- a/rust/src/serialization/certificates/stake_and_vote_delegation.rs +++ b/rust/src/serialization/certificates/stake_and_vote_delegation.rs @@ -21,33 +21,7 @@ impl Deserialize for StakeAndVoteDelegation { (|| -> Result<_, DeserializeError> { let len = raw.array()?; - if let cbor_event::Len::Len(n) = len { - if n != 4 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 4, - len, - "(cert_index, stake_credential, pool_keyhash, drep)", - )) - .into()); - } - } - - let cert_index = raw.unsigned_integer()?; - if cert_index != STAKE_VOTE_DELEG_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(STAKE_VOTE_DELEG_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } - - let stake_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; - - let pool_keyhash = - Ed25519KeyHash::deserialize(raw).map_err(|e| e.annotate("pool_keyhash"))?; - - let drep = DRep::deserialize(raw).map_err(|e| e.annotate("drep"))?; + let cert = Self::deserialize_as_embedded_group(raw, len)?; if let cbor_event::Len::Indefinite = len { if raw.special()? != CBORSpecial::Break { @@ -55,12 +29,49 @@ impl Deserialize for StakeAndVoteDelegation { } } - return Ok(StakeAndVoteDelegation { - stake_credential, - pool_keyhash, - drep, - }); + Ok(cert) })() .map_err(|e| e.annotate("StakeAndVoteDelegation")) } } + +impl DeserializeEmbeddedGroup for StakeAndVoteDelegation { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + if let cbor_event::Len::Len(n) = len { + if n != 4 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 4, + len, + "(cert_index, stake_credential, pool_keyhash, drep)", + )) + .into()); + } + } + + let cert_index = raw.unsigned_integer()?; + if cert_index != STAKE_VOTE_DELEG_CERT_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(STAKE_VOTE_DELEG_CERT_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + + let stake_credential = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + + let pool_keyhash = + Ed25519KeyHash::deserialize(raw).map_err(|e| e.annotate("pool_keyhash"))?; + + let drep = DRep::deserialize(raw).map_err(|e| e.annotate("drep"))?; + + Ok(StakeAndVoteDelegation { + stake_credential, + pool_keyhash, + drep, + }) + } +} diff --git a/rust/src/serialization/certificates/stake_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_registration_and_delegation.rs index 7181eeb5..8af48de7 100644 --- a/rust/src/serialization/certificates/stake_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/stake_registration_and_delegation.rs @@ -21,33 +21,7 @@ impl Deserialize for StakeRegistrationAndDelegation { (|| -> Result<_, DeserializeError> { let len = raw.array()?; - if let cbor_event::Len::Len(n) = len { - if n != 4 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 4, - len, - "(cert_index, stake_credential, pool_keyhash, coin)", - )) - .into()); - } - } - - let cert_index = raw.unsigned_integer()?; - if cert_index != STAKE_REG_DELEG_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(STAKE_REG_DELEG_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } - - let stake_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; - - let pool_keyhash = - Ed25519KeyHash::deserialize(raw).map_err(|e| e.annotate("pool_keyhash"))?; - - let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; + let cert = Self::deserialize_as_embedded_group(raw, len)?; if let cbor_event::Len::Indefinite = len { if raw.special()? != CBORSpecial::Break { @@ -55,12 +29,50 @@ impl Deserialize for StakeRegistrationAndDelegation { } } - return Ok(StakeRegistrationAndDelegation { - stake_credential, - pool_keyhash, - coin, - }); + Ok(cert) })() .map_err(|e| e.annotate("StakeRegistrationAndDelegation")) } +} + +impl DeserializeEmbeddedGroup for StakeRegistrationAndDelegation { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + + if let cbor_event::Len::Len(n) = len { + if n != 4 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 4, + len, + "(cert_index, stake_credential, pool_keyhash, coin)", + )) + .into()); + } + } + + let cert_index = raw.unsigned_integer()?; + if cert_index != STAKE_REG_DELEG_CERT_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(STAKE_REG_DELEG_CERT_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + + let stake_credential = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + + let pool_keyhash = + Ed25519KeyHash::deserialize(raw).map_err(|e| e.annotate("pool_keyhash"))?; + + let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; + + Ok(StakeRegistrationAndDelegation { + stake_credential, + pool_keyhash, + coin, + }) + } } \ No newline at end of file diff --git a/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs index 2bd0dea4..8dcb52e2 100644 --- a/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs @@ -22,49 +22,60 @@ impl Deserialize for StakeVoteRegistrationAndDelegation { (|| -> Result<_, DeserializeError> { let len = raw.array()?; - if let cbor_event::Len::Len(n) = len { - if n != 5 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 5, - len, - "(cert_index, stake_credential, pool_keyhash, drep, coin)", - )) - .into()); + let cert = Self::deserialize_as_embedded_group(raw, len)?; + + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); } } - let cert_index = raw.unsigned_integer()?; - if cert_index != STAKE_VOTE_REG_DELEG_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(STAKE_VOTE_REG_DELEG_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + Ok(cert) + })() + .map_err(|e| e.annotate("StakeVoteRegistrationAndDelegation")) + } +} + +impl DeserializeEmbeddedGroup for StakeVoteRegistrationAndDelegation { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + if let cbor_event::Len::Len(n) = len { + if n != 5 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 5, + len, + "(cert_index, stake_credential, pool_keyhash, drep, coin)", + )) + .into()); } + } - let stake_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + let cert_index = raw.unsigned_integer()?; + if cert_index != STAKE_VOTE_REG_DELEG_CERT_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(STAKE_VOTE_REG_DELEG_CERT_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } - let pool_keyhash = - Ed25519KeyHash::deserialize(raw).map_err(|e| e.annotate("pool_keyhash"))?; + let stake_credential = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; - let drep = DRep::deserialize(raw).map_err(|e| e.annotate("drep"))?; + let pool_keyhash = + Ed25519KeyHash::deserialize(raw).map_err(|e| e.annotate("pool_keyhash"))?; - let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; + let drep = DRep::deserialize(raw).map_err(|e| e.annotate("drep"))?; - if let cbor_event::Len::Indefinite = len { - if raw.special()? != CBORSpecial::Break { - return Err(DeserializeFailure::EndingBreakMissing.into()); - } - } + let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; - return Ok(StakeVoteRegistrationAndDelegation { - stake_credential, - pool_keyhash, - drep, - coin, - }); - })() - .map_err(|e| e.annotate("StakeVoteRegistrationAndDelegation")) + Ok(StakeVoteRegistrationAndDelegation { + stake_credential, + pool_keyhash, + drep, + coin, + }) } -} \ No newline at end of file +} diff --git a/rust/src/serialization/certificates/vote_delegation.rs b/rust/src/serialization/certificates/vote_delegation.rs index bd91415e..57a82a61 100644 --- a/rust/src/serialization/certificates/vote_delegation.rs +++ b/rust/src/serialization/certificates/vote_delegation.rs @@ -20,30 +20,7 @@ impl Deserialize for VoteDelegation { (|| -> Result<_, DeserializeError> { let len = raw.array()?; - if let cbor_event::Len::Len(n) = len { - if n != 3 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 3, - len, - "(cert_index, stake_credential, drep)", - )) - .into()); - } - } - - let cert_index = raw.unsigned_integer()?; - if cert_index != VOTE_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(VOTE_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } - - let stake_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; - - let drep = DRep::deserialize(raw).map_err(|e| e.annotate("drep"))?; + let cert = Self::deserialize_as_embedded_group(raw, len)?; if let cbor_event::Len::Indefinite = len { if raw.special()? != CBORSpecial::Break { @@ -51,11 +28,45 @@ impl Deserialize for VoteDelegation { } } - return Ok(VoteDelegation { - stake_credential, - drep, - }); + Ok(cert) })() .map_err(|e| e.annotate("VoteDelegation")) } } + +impl DeserializeEmbeddedGroup for VoteDelegation { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + if let cbor_event::Len::Len(n) = len { + if n != 3 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 3, + len, + "(cert_index, stake_credential, drep)", + )) + .into()); + } + } + + let cert_index = raw.unsigned_integer()?; + if cert_index != VOTE_CERT_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(VOTE_CERT_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + + let stake_credential = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + + let drep = DRep::deserialize(raw).map_err(|e| e.annotate("drep"))?; + + Ok(VoteDelegation { + stake_credential, + drep, + }) + } +} diff --git a/rust/src/serialization/certificates/vote_registration_and_delegation.rs b/rust/src/serialization/certificates/vote_registration_and_delegation.rs index a39090b8..8f765076 100644 --- a/rust/src/serialization/certificates/vote_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/vote_registration_and_delegation.rs @@ -21,32 +21,7 @@ impl Deserialize for VoteRegistrationAndDelegation { (|| -> Result<_, DeserializeError> { let len = raw.array()?; - if let cbor_event::Len::Len(n) = len { - if n != 4 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 4, - len, - "(cert_index, stake_credential, drep, coin)", - )) - .into()); - } - } - - let cert_index = raw.unsigned_integer()?; - if cert_index != VOTE_REG_DELEG_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(VOTE_REG_DELEG_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } - - let stake_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; - - let drep = DRep::deserialize(raw).map_err(|e| e.annotate("drep"))?; - - let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; + let cert = Self::deserialize_as_embedded_group(raw, len)?; if let cbor_event::Len::Indefinite = len { if raw.special()? != CBORSpecial::Break { @@ -54,12 +29,49 @@ impl Deserialize for VoteRegistrationAndDelegation { } } - return Ok(VoteRegistrationAndDelegation { - stake_credential, - drep, - coin, - }); + Ok(cert) })() .map_err(|e| e.annotate("VoteRegistrationAndDelegation")) } +} + +impl DeserializeEmbeddedGroup for VoteRegistrationAndDelegation { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + + if let cbor_event::Len::Len(n) = len { + if n != 4 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 4, + len, + "(cert_index, stake_credential, drep, coin)", + )) + .into()); + } + } + + let cert_index = raw.unsigned_integer()?; + if cert_index != VOTE_REG_DELEG_CERT_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(VOTE_REG_DELEG_CERT_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + + let stake_credential = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + + let drep = DRep::deserialize(raw).map_err(|e| e.annotate("drep"))?; + + let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; + + Ok(VoteRegistrationAndDelegation { + stake_credential, + drep, + coin, + }) + } } \ No newline at end of file From c44d53ccc8a8a71efc73e3d70fded473bdd7cdbf Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 15 Aug 2023 19:30:09 +0400 Subject: [PATCH 047/349] add error --- rust/src/error.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rust/src/error.rs b/rust/src/error.rs index 61133a76..392956ac 100644 --- a/rust/src/error.rs +++ b/rust/src/error.rs @@ -55,6 +55,7 @@ pub enum DeserializeFailure { UnknownKey(Key), UnexpectedKeyType(cbor_event::Type), VariableLenNatDecodeFailed, + IoError(String), } #[derive(Debug)] @@ -133,6 +134,7 @@ impl std::fmt::Display for DeserializeError { DeserializeFailure::VariableLenNatDecodeFailed => { write!(f, "Variable length natural number decode failed") } + DeserializeFailure::IoError(e) => write!(f, "IO error: {}", e), } } } From 53b5ab81f154f3944b7c6cc734ce2dd831a00831 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 15 Aug 2023 19:44:03 +0400 Subject: [PATCH 048/349] update stake dereg serialisation --- .../certificates/stake_deregistration.rs | 156 +++++++++++++----- 1 file changed, 117 insertions(+), 39 deletions(-) diff --git a/rust/src/serialization/certificates/stake_deregistration.rs b/rust/src/serialization/certificates/stake_deregistration.rs index c87ef68b..993003fd 100644 --- a/rust/src/serialization/certificates/stake_deregistration.rs +++ b/rust/src/serialization/certificates/stake_deregistration.rs @@ -1,26 +1,43 @@ +use cbor_event::Len; use crate::*; -pub(super) const DEREG_STAKE_CERT_INDEX: u64 = 1; +pub(super) const DEREG_STAKE_CERT_LEGACY_INDEX: u64 = 1; +pub(super) const DEREG_STAKE_CERT_CONWAY_INDEX: u64 = 8; impl cbor_event::se::Serialize for StakeDeregistration { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - self.serialize_as_embedded_group(serializer) + if self.coin.is_some() { + serialize_as_conway(self, serializer) + } else { + serialize_as_legacy(self, serializer) + } } } -impl SerializeEmbeddedGroup for StakeDeregistration { - fn serialize_as_embedded_group<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(DEREG_STAKE_CERT_INDEX)?; - self.stake_credential.serialize(serializer)?; - Ok(serializer) +fn serialize_as_legacy<'se, W: Write>( + cert: &StakeDeregistration, + serializer: &'se mut Serializer, +) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + serializer.write_unsigned_integer(DEREG_STAKE_CERT_LEGACY_INDEX)?; + cert.stake_credential.serialize(serializer)?; + Ok(serializer) +} + +fn serialize_as_conway<'se, W: Write>( + cert: &StakeDeregistration, + serializer: &'se mut Serializer, +) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(3))?; + serializer.write_unsigned_integer(DEREG_STAKE_CERT_CONWAY_INDEX)?; + cert.stake_credential.serialize(serializer)?; + if let Some(coin) = cert.coin { + coin.serialize(serializer)?; } + Ok(serializer) } impl Deserialize for StakeDeregistration { @@ -29,19 +46,11 @@ impl Deserialize for StakeDeregistration { let len = raw.array()?; let ret = Self::deserialize_as_embedded_group(raw, len); match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } + Len::Indefinite => match raw.special()? { + CBORSpecial::Break => {} _ => return Err(DeserializeFailure::EndingBreakMissing.into()), }, + _ => {} } ret })() @@ -52,26 +61,95 @@ impl Deserialize for StakeDeregistration { impl DeserializeEmbeddedGroup for StakeDeregistration { fn deserialize_as_embedded_group( raw: &mut Deserializer, - _: cbor_event::Len, + len: Len, ) -> Result { - (|| -> Result<_, DeserializeError> { - let cert_index = raw.unsigned_integer()?; - if cert_index != DEREG_STAKE_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(DEREG_STAKE_CERT_INDEX), - } - .into()); + let cert_index = raw.unsigned_integer()?; + match cert_index { + DEREG_STAKE_CERT_LEGACY_INDEX => deserialize_legacy(raw, cert_index, len), + DEREG_STAKE_CERT_CONWAY_INDEX => deserialize_conway(raw, cert_index, len), + _ => Err(DeserializeFailure::FixedValuesMismatch { + found: Key::Uint(cert_index), + expected: vec![ + Key::Uint(DEREG_STAKE_CERT_LEGACY_INDEX), + Key::Uint(DEREG_STAKE_CERT_CONWAY_INDEX), + ], + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")), + } + } +} + +fn deserialize_legacy( + raw: &mut Deserializer, + cert_index: u64, + len: Len, +) -> Result { + (|| -> Result<_, DeserializeError> { + if let Len::Len(n) = len { + if n != 2 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 2, + len, + "(cert_index, stake_credential)", + )) + .into()); } - Ok(()) - })() - .map_err(|e| e.annotate("cert_index"))?; + } + + if cert_index != DEREG_STAKE_CERT_LEGACY_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(DEREG_STAKE_CERT_LEGACY_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + let stake_credential = - (|| -> Result<_, DeserializeError> { Ok(StakeCredential::deserialize(raw)?) })() - .map_err(|e| e.annotate("stake_credential"))?; - Ok(StakeDeregistration { + StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + + return Ok(StakeDeregistration { stake_credential, coin: None, - }) - } + }); + })() + .map_err(|e| e.annotate("StakeDeregistration (legacy)")) +} + +fn deserialize_conway( + raw: &mut Deserializer, + cert_index: u64, + len: Len, +) -> Result { + (|| -> Result<_, DeserializeError> { + if let Len::Len(n) = len { + if n != 3 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 3, + len, + "(cert_index, stake_credential, coin)", + )) + .into()); + } + } + + if cert_index != DEREG_STAKE_CERT_CONWAY_INDEX { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(cert_index), + expected: Key::Uint(DEREG_STAKE_CERT_CONWAY_INDEX), + }) + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + } + + let stake_credential = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + + let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; + + return Ok(StakeDeregistration { + stake_credential, + coin: Some(coin), + }); + })() + .map_err(|e| e.annotate("StakeDeregistration (conway)")) } + From e72b311349c4d4c30d53954c4039b08ef5e48203 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 15 Aug 2023 19:44:14 +0400 Subject: [PATCH 049/349] update cert serialization --- .../serialization/certificates/certificate.rs | 194 ++++++++++-------- 1 file changed, 113 insertions(+), 81 deletions(-) diff --git a/rust/src/serialization/certificates/certificate.rs b/rust/src/serialization/certificates/certificate.rs index a1b50527..3900fc35 100644 --- a/rust/src/serialization/certificates/certificate.rs +++ b/rust/src/serialization/certificates/certificate.rs @@ -59,87 +59,110 @@ impl DeserializeEmbeddedGroup for CertificateEnum { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - let initial_position = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(StakeRegistration::deserialize_as_embedded_group(raw, len)?) - })(raw) - { - Ok(variant) => return Ok(CertificateEnum::StakeRegistration(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(StakeDeregistration::deserialize_as_embedded_group( - raw, len, - )?) - })(raw) - { - Ok(variant) => return Ok(CertificateEnum::StakeDeregistration(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(StakeDelegation::deserialize_as_embedded_group(raw, len)?) - })(raw) - { - Ok(variant) => return Ok(CertificateEnum::StakeDelegation(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(PoolRegistration::deserialize_as_embedded_group(raw, len)?) - })(raw) - { - Ok(variant) => return Ok(CertificateEnum::PoolRegistration(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(PoolRetirement::deserialize_as_embedded_group(raw, len)?) - })(raw) - { - Ok(variant) => return Ok(CertificateEnum::PoolRetirement(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(GenesisKeyDelegation::deserialize_as_embedded_group( - raw, len, - )?) - })(raw) - { - Ok(variant) => return Ok(CertificateEnum::GenesisKeyDelegation(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(MoveInstantaneousRewardsCert::deserialize_as_embedded_group( - raw, len, - )?) - })(raw) - { - Ok(variant) => return Ok(CertificateEnum::MoveInstantaneousRewardsCert(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - Err(DeserializeError::new( - "CertificateEnum", - DeserializeFailure::NoVariantMatched.into(), - )) + + let cert_index = get_cert_index(raw)?; + + match cert_index { + super::stake_registration::STAKE_REG_LEGACY_INDEX => { + Ok(CertificateEnum::StakeRegistration( + StakeRegistration::deserialize_as_embedded_group(raw, len)?, + )) + } + super::stake_registration::STAKE_REG_CONWAY_INDEX => { + Ok(CertificateEnum::StakeRegistration( + StakeRegistration::deserialize_as_embedded_group(raw, len)?, + )) + } + super::stake_deregistration::DEREG_STAKE_CERT_LEGACY_INDEX => { + Ok(CertificateEnum::StakeDeregistration( + StakeDeregistration::deserialize_as_embedded_group(raw, len)?, + )) + } + super::stake_deregistration::DEREG_STAKE_CERT_CONWAY_INDEX => { + Ok(CertificateEnum::StakeDeregistration( + StakeDeregistration::deserialize_as_embedded_group(raw, len)?, + )) + } + super::stake_delegation::STAKE_DELEGATION_CERT_INDEX => { + Ok(CertificateEnum::StakeDelegation( + StakeDelegation::deserialize_as_embedded_group(raw, len)?, + )) + } + super::pool_registration::REG_POOL_CERT_INDEX => { + Ok(CertificateEnum::PoolRegistration( + PoolRegistration::deserialize_as_embedded_group(raw, len)?, + )) + } + super::pool_retirement::RETIRE_POOL_CERT_INDEX => { + Ok(CertificateEnum::PoolRetirement( + PoolRetirement::deserialize_as_embedded_group(raw, len)?, + )) + } + super::genesis_key_delegation::GENESIS_KEY_DELEGATION_INDEX => { + Ok(CertificateEnum::GenesisKeyDelegation( + GenesisKeyDelegation::deserialize_as_embedded_group(raw, len)?, + )) + } + super::move_instantaneous_rewards_cert::MIR_CERT_INDEX => { + Ok(CertificateEnum::MoveInstantaneousRewardsCert( + MoveInstantaneousRewardsCert::deserialize_as_embedded_group(raw, len)?, + )) + } + super::committee_hot_key_registration::REG_COMMITTEE_HOT_KEY_CERT_INDEX => { + Ok(CertificateEnum::CommitteeHotKeyRegistration( + CommitteeHotKeyRegistration::deserialize_as_embedded_group(raw, len)?, + )) + } + super::committee_hot_key_deregistration::UNREG_COMMITTEE_HOT_KEY_CERT_INDEX => { + Ok(CertificateEnum::CommitteeHotKeyDeregistration( + CommitteeHotKeyDeregistration::deserialize_as_embedded_group(raw, len)?, + )) + } + super::drep_registration::REG_DREP_CERT_INDEX => { + Ok(CertificateEnum::DrepRegistration( + DrepRegistration::deserialize_as_embedded_group(raw, len)?, + )) + } + super::drep_deregistration::DEREG_DREP_CERT_INDEX => { + Ok(CertificateEnum::DrepDeregistration( + DrepDeregistration::deserialize_as_embedded_group(raw, len)?, + )) + } + super::drep_update::UPDATE_DREP_CERT_INDEX => { + Ok(CertificateEnum::DrepUpdate( + DrepUpdate::deserialize_as_embedded_group(raw, len)?, + )) + } + super::stake_and_vote_delegation::STAKE_VOTE_DELEG_CERT_INDEX => { + Ok(CertificateEnum::StakeAndVoteDelegation( + StakeAndVoteDelegation::deserialize_as_embedded_group(raw, len)?, + )) + } + super::stake_registration_and_delegation::STAKE_REG_DELEG_CERT_INDEX => { + Ok(CertificateEnum::StakeRegistrationAndDelegation( + StakeRegistrationAndDelegation::deserialize_as_embedded_group(raw, len)?, + )) + } + super::stake_vote_registration_and_delegation::STAKE_VOTE_REG_DELEG_CERT_INDEX => { + Ok(CertificateEnum::StakeVoteRegistrationAndDelegation( + StakeVoteRegistrationAndDelegation::deserialize_as_embedded_group(raw, len)?, + )) + } + super::vote_delegation::VOTE_CERT_INDEX => { + Ok(CertificateEnum::VoteDelegation( + VoteDelegation::deserialize_as_embedded_group(raw, len)?, + )) + } + super::vote_registration_and_delegation::VOTE_REG_DELEG_CERT_INDEX => { + Ok(CertificateEnum::VoteRegistrationAndDelegation( + VoteRegistrationAndDelegation::deserialize_as_embedded_group(raw, len)?, + )) + } + _ => Err(DeserializeError::new( + "CertificateEnum", + DeserializeFailure::UnknownKey(Key::Uint(cert_index)), + )), + } } } @@ -157,3 +180,12 @@ impl Deserialize for Certificate { Ok(Self(CertificateEnum::deserialize(raw)?)) } } + +fn get_cert_index(raw: &mut Deserializer) -> Result { + let initial_position = raw.as_mut_ref().seek(SeekFrom::Current(0)) + .map_err(|err| DeserializeFailure::IoError(err.to_string()))?; + let index = raw.unsigned_integer()?; + raw.as_mut_ref().seek(SeekFrom::Start(initial_position)) + .map_err(|err| DeserializeFailure::IoError(err.to_string()))?; + Ok(index) +} From 074fee57c9264599e43f4f2214a64f2e7096059c Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 15 Aug 2023 19:44:38 +0400 Subject: [PATCH 050/349] update mod file --- rust/src/serialization/certificates/mod.rs | 33 +--------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/rust/src/serialization/certificates/mod.rs b/rust/src/serialization/certificates/mod.rs index ef3fdd67..6544629c 100644 --- a/rust/src/serialization/certificates/mod.rs +++ b/rust/src/serialization/certificates/mod.rs @@ -2,52 +2,21 @@ mod certificate; pub use certificate::*; mod genesis_key_delegation; -pub use genesis_key_delegation::*; mod move_instantaneous_rewards_cert; -pub use move_instantaneous_rewards_cert::*; mod pool_registration; -pub use pool_registration::*; - mod pool_retirement; -pub use pool_retirement::*; - mod stake_delegation; -pub use stake_delegation::*; - mod stake_deregistration; -pub use stake_deregistration::*; - mod stake_registration; -pub use stake_registration::*; - mod vote_delegation; -pub use vote_delegation::*; - mod stake_and_vote_delegation; -pub use stake_and_vote_delegation::*; - mod stake_registration_and_delegation; -pub use stake_registration_and_delegation::*; - mod stake_vote_registration_and_delegation; -pub use stake_vote_registration_and_delegation::*; - mod vote_registration_and_delegation; -pub use vote_registration_and_delegation::*; - mod committee_hot_key_registration; -pub use committee_hot_key_registration::*; - mod committee_hot_key_deregistration; -pub use committee_hot_key_deregistration::*; - mod drep_registration; -pub use drep_registration::*; - mod drep_deregistration; -pub use drep_deregistration::*; - -mod drep_update; -pub use drep_update::*; +mod drep_update; \ No newline at end of file From e4d760fb45d5359f78b2743d33b1882b94131364 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 15 Aug 2023 19:49:24 +0400 Subject: [PATCH 051/349] add new cert constructors --- .../certificates/certificate.rs | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/rust/src/protocol_types/certificates/certificate.rs b/rust/src/protocol_types/certificates/certificate.rs index ab5b7427..fe842a2a 100644 --- a/rust/src/protocol_types/certificates/certificate.rs +++ b/rust/src/protocol_types/certificates/certificate.rs @@ -111,6 +111,86 @@ impl Certificate { )) } + pub fn new_committee_hot_key_registration( + committee_hot_key_registration: &CommitteeHotKeyRegistration, + ) -> Self { + Self(CertificateEnum::CommitteeHotKeyRegistration( + committee_hot_key_registration.clone(), + )) + } + + pub fn new_committee_hot_key_deregistration( + committee_hot_key_deregistration: &CommitteeHotKeyDeregistration, + ) -> Self { + Self(CertificateEnum::CommitteeHotKeyDeregistration( + committee_hot_key_deregistration.clone(), + )) + } + + pub fn new_drep_deregistration( + drep_deregistration: &DrepDeregistration, + ) -> Self { + Self(CertificateEnum::DrepDeregistration( + drep_deregistration.clone(), + )) + } + + pub fn new_drep_registration( + drep_registration: &DrepRegistration, + ) -> Self { + Self(CertificateEnum::DrepRegistration( + drep_registration.clone(), + )) + } + + pub fn new_drep_update( + drep_update: &DrepUpdate, + ) -> Self { + Self(CertificateEnum::DrepUpdate( + drep_update.clone(), + )) + } + + pub fn new_stake_and_vote_delegation( + stake_and_vote_delegation: &StakeAndVoteDelegation, + ) -> Self { + Self(CertificateEnum::StakeAndVoteDelegation( + stake_and_vote_delegation.clone(), + )) + } + + pub fn new_stake_registration_and_delegation( + stake_registration_and_delegation: &StakeRegistrationAndDelegation, + ) -> Self { + Self(CertificateEnum::StakeRegistrationAndDelegation( + stake_registration_and_delegation.clone(), + )) + } + + pub fn new_stake_vote_registration_and_delegation( + stake_vote_registration_and_delegation: &StakeVoteRegistrationAndDelegation, + ) -> Self { + Self(CertificateEnum::StakeVoteRegistrationAndDelegation( + stake_vote_registration_and_delegation.clone(), + )) + } + + pub fn new_vote_delegation( + vote_delegation: &VoteDelegation, + ) -> Self { + Self(CertificateEnum::VoteDelegation( + vote_delegation.clone(), + )) + } + + pub fn new_vote_registration_and_delegation( + vote_registration_and_delegation: &VoteRegistrationAndDelegation, + ) -> Self { + Self(CertificateEnum::VoteRegistrationAndDelegation( + vote_registration_and_delegation.clone(), + )) + } + pub fn kind(&self) -> CertificateKind { match &self.0 { CertificateEnum::StakeRegistration(_) => CertificateKind::StakeRegistration, From 9d1030ab61333472cfe66136c9019cc4eda1e0f1 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 15 Aug 2023 19:58:25 +0400 Subject: [PATCH 052/349] add len check --- .../certificates/genesis_key_delegation.rs | 25 +++++++++++-------- .../move_instantaneous_rewards_cert.rs | 24 ++++++++++-------- .../certificates/pool_registration.rs | 25 +++++++++++-------- .../certificates/pool_retirement.rs | 24 ++++++++++-------- .../certificates/stake_delegation.rs | 25 +++++++++++-------- 5 files changed, 68 insertions(+), 55 deletions(-) diff --git a/rust/src/serialization/certificates/genesis_key_delegation.rs b/rust/src/serialization/certificates/genesis_key_delegation.rs index 7055fd13..da35100e 100644 --- a/rust/src/serialization/certificates/genesis_key_delegation.rs +++ b/rust/src/serialization/certificates/genesis_key_delegation.rs @@ -31,19 +31,11 @@ impl Deserialize for GenesisKeyDelegation { let len = raw.array()?; let ret = Self::deserialize_as_embedded_group(raw, len); match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } + CBORSpecial::Break => {} _ => return Err(DeserializeFailure::EndingBreakMissing.into()), }, + _ => {} } ret })() @@ -54,9 +46,20 @@ impl Deserialize for GenesisKeyDelegation { impl DeserializeEmbeddedGroup for GenesisKeyDelegation { fn deserialize_as_embedded_group( raw: &mut Deserializer, - _: cbor_event::Len, + len: cbor_event::Len, ) -> Result { (|| -> Result<_, DeserializeError> { + if let cbor_event::Len::Len(n) = len { + if n != 4 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 4, + len, + "(cert_index, genesishash, genesis_delegate_hash, vrf_keyhash)", + )) + .into()); + } + } + let cert_index = raw.unsigned_integer()?; if cert_index != GENESIS_KEY_DELEGATION_INDEX { return Err(DeserializeFailure::FixedValueMismatch { diff --git a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs index 121fa993..e47acff5 100644 --- a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs +++ b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs @@ -131,19 +131,11 @@ impl Deserialize for MoveInstantaneousRewardsCert { let len = raw.array()?; let ret = Self::deserialize_as_embedded_group(raw, len); match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } + CBORSpecial::Break => {} _ => return Err(DeserializeFailure::EndingBreakMissing.into()), }, + _ => {} } ret })() @@ -154,9 +146,19 @@ impl Deserialize for MoveInstantaneousRewardsCert { impl DeserializeEmbeddedGroup for MoveInstantaneousRewardsCert { fn deserialize_as_embedded_group( raw: &mut Deserializer, - _: cbor_event::Len, + len: cbor_event::Len, ) -> Result { (|| -> Result<_, DeserializeError> { + if let cbor_event::Len::Len(n) = len { + if n != 2 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 2, + len, + "(cert_index, move_instantaneous_reward)", + )) + .into()); + } + } let cert_index = raw.unsigned_integer()?; if cert_index != MIR_CERT_INDEX { return Err(DeserializeFailure::FixedValueMismatch { diff --git a/rust/src/serialization/certificates/pool_registration.rs b/rust/src/serialization/certificates/pool_registration.rs index 34b622ad..ee5458a3 100644 --- a/rust/src/serialization/certificates/pool_registration.rs +++ b/rust/src/serialization/certificates/pool_registration.rs @@ -1,6 +1,6 @@ use crate::*; -pub (super) const REG_POOL_CERT_INDEX: u64 = 3; +pub(super) const REG_POOL_CERT_INDEX: u64 = 3; impl cbor_event::se::Serialize for Relays { fn serialize<'se, W: Write>( @@ -172,19 +172,11 @@ impl Deserialize for PoolRegistration { let len = raw.array()?; let ret = Self::deserialize_as_embedded_group(raw, len); match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } + CBORSpecial::Break => {} _ => return Err(DeserializeFailure::EndingBreakMissing.into()), }, + _ => {} } ret })() @@ -198,6 +190,17 @@ impl DeserializeEmbeddedGroup for PoolRegistration { len: cbor_event::Len, ) -> Result { (|| -> Result<_, DeserializeError> { + if let cbor_event::Len::Len(n) = len { + if n != 2 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 2, + len, + "(cert_index, pool_params)", + )) + .into()); + } + } + let cert_index = raw.unsigned_integer()?; if cert_index != REG_POOL_CERT_INDEX { return Err(DeserializeFailure::FixedValueMismatch { diff --git a/rust/src/serialization/certificates/pool_retirement.rs b/rust/src/serialization/certificates/pool_retirement.rs index b6aaa26b..929e4518 100644 --- a/rust/src/serialization/certificates/pool_retirement.rs +++ b/rust/src/serialization/certificates/pool_retirement.rs @@ -30,19 +30,11 @@ impl Deserialize for PoolRetirement { let len = raw.array()?; let ret = Self::deserialize_as_embedded_group(raw, len); match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } + CBORSpecial::Break => {} _ => return Err(DeserializeFailure::EndingBreakMissing.into()), }, + _ => {} } ret })() @@ -53,9 +45,19 @@ impl Deserialize for PoolRetirement { impl DeserializeEmbeddedGroup for PoolRetirement { fn deserialize_as_embedded_group( raw: &mut Deserializer, - _: cbor_event::Len, + len: cbor_event::Len, ) -> Result { (|| -> Result<_, DeserializeError> { + if let cbor_event::Len::Len(n) = len { + if n != 3 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 3, + len, + "(cert_index, pool_keyhash, epoch)", + )) + .into()); + } + } let cert_index = raw.unsigned_integer()?; if cert_index != RETIRE_POOL_CERT_INDEX { return Err(DeserializeFailure::FixedValueMismatch { diff --git a/rust/src/serialization/certificates/stake_delegation.rs b/rust/src/serialization/certificates/stake_delegation.rs index 5bf59cb2..66336e96 100644 --- a/rust/src/serialization/certificates/stake_delegation.rs +++ b/rust/src/serialization/certificates/stake_delegation.rs @@ -30,19 +30,11 @@ impl Deserialize for StakeDelegation { let len = raw.array()?; let ret = Self::deserialize_as_embedded_group(raw, len); match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } + CBORSpecial::Break => {} _ => return Err(DeserializeFailure::EndingBreakMissing.into()), }, + _ => {} } ret })() @@ -53,9 +45,20 @@ impl Deserialize for StakeDelegation { impl DeserializeEmbeddedGroup for StakeDelegation { fn deserialize_as_embedded_group( raw: &mut Deserializer, - _: cbor_event::Len, + len: cbor_event::Len, ) -> Result { (|| -> Result<_, DeserializeError> { + if let cbor_event::Len::Len(n) = len { + if n != 3 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 3, + len, + "(cert_index, stake_credential, pool_keyhash)", + )) + .into()); + } + } + let cert_index = raw.unsigned_integer()?; if cert_index != STAKE_DELEGATION_CERT_INDEX { return Err(DeserializeFailure::FixedValueMismatch { From 3c1f7688999233af2bf6fc005427a9f05c32931c Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 15 Aug 2023 20:00:15 +0400 Subject: [PATCH 053/349] fmt --- .../serialization/certificates/certificate.rs | 48 ++++++++----------- .../committee_hot_key_deregistration.rs | 3 +- .../committee_hot_key_registration.rs | 8 ++-- .../certificates/drep_deregistration.rs | 7 ++- .../certificates/drep_registration.rs | 15 +++--- .../serialization/certificates/drep_update.rs | 15 +++--- .../certificates/stake_deregistration.rs | 17 ++++--- .../stake_registration_and_delegation.rs | 9 ++-- .../vote_registration_and_delegation.rs | 9 ++-- 9 files changed, 58 insertions(+), 73 deletions(-) diff --git a/rust/src/serialization/certificates/certificate.rs b/rust/src/serialization/certificates/certificate.rs index 3900fc35..47334de4 100644 --- a/rust/src/serialization/certificates/certificate.rs +++ b/rust/src/serialization/certificates/certificate.rs @@ -59,7 +59,6 @@ impl DeserializeEmbeddedGroup for CertificateEnum { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - let cert_index = get_cert_index(raw)?; match cert_index { @@ -88,16 +87,12 @@ impl DeserializeEmbeddedGroup for CertificateEnum { StakeDelegation::deserialize_as_embedded_group(raw, len)?, )) } - super::pool_registration::REG_POOL_CERT_INDEX => { - Ok(CertificateEnum::PoolRegistration( - PoolRegistration::deserialize_as_embedded_group(raw, len)?, - )) - } - super::pool_retirement::RETIRE_POOL_CERT_INDEX => { - Ok(CertificateEnum::PoolRetirement( - PoolRetirement::deserialize_as_embedded_group(raw, len)?, - )) - } + super::pool_registration::REG_POOL_CERT_INDEX => Ok(CertificateEnum::PoolRegistration( + PoolRegistration::deserialize_as_embedded_group(raw, len)?, + )), + super::pool_retirement::RETIRE_POOL_CERT_INDEX => Ok(CertificateEnum::PoolRetirement( + PoolRetirement::deserialize_as_embedded_group(raw, len)?, + )), super::genesis_key_delegation::GENESIS_KEY_DELEGATION_INDEX => { Ok(CertificateEnum::GenesisKeyDelegation( GenesisKeyDelegation::deserialize_as_embedded_group(raw, len)?, @@ -118,21 +113,17 @@ impl DeserializeEmbeddedGroup for CertificateEnum { CommitteeHotKeyDeregistration::deserialize_as_embedded_group(raw, len)?, )) } - super::drep_registration::REG_DREP_CERT_INDEX => { - Ok(CertificateEnum::DrepRegistration( - DrepRegistration::deserialize_as_embedded_group(raw, len)?, - )) - } + super::drep_registration::REG_DREP_CERT_INDEX => Ok(CertificateEnum::DrepRegistration( + DrepRegistration::deserialize_as_embedded_group(raw, len)?, + )), super::drep_deregistration::DEREG_DREP_CERT_INDEX => { Ok(CertificateEnum::DrepDeregistration( DrepDeregistration::deserialize_as_embedded_group(raw, len)?, )) } - super::drep_update::UPDATE_DREP_CERT_INDEX => { - Ok(CertificateEnum::DrepUpdate( - DrepUpdate::deserialize_as_embedded_group(raw, len)?, - )) - } + super::drep_update::UPDATE_DREP_CERT_INDEX => Ok(CertificateEnum::DrepUpdate( + DrepUpdate::deserialize_as_embedded_group(raw, len)?, + )), super::stake_and_vote_delegation::STAKE_VOTE_DELEG_CERT_INDEX => { Ok(CertificateEnum::StakeAndVoteDelegation( StakeAndVoteDelegation::deserialize_as_embedded_group(raw, len)?, @@ -148,11 +139,9 @@ impl DeserializeEmbeddedGroup for CertificateEnum { StakeVoteRegistrationAndDelegation::deserialize_as_embedded_group(raw, len)?, )) } - super::vote_delegation::VOTE_CERT_INDEX => { - Ok(CertificateEnum::VoteDelegation( - VoteDelegation::deserialize_as_embedded_group(raw, len)?, - )) - } + super::vote_delegation::VOTE_CERT_INDEX => Ok(CertificateEnum::VoteDelegation( + VoteDelegation::deserialize_as_embedded_group(raw, len)?, + )), super::vote_registration_and_delegation::VOTE_REG_DELEG_CERT_INDEX => { Ok(CertificateEnum::VoteRegistrationAndDelegation( VoteRegistrationAndDelegation::deserialize_as_embedded_group(raw, len)?, @@ -182,10 +171,13 @@ impl Deserialize for Certificate { } fn get_cert_index(raw: &mut Deserializer) -> Result { - let initial_position = raw.as_mut_ref().seek(SeekFrom::Current(0)) + let initial_position = raw + .as_mut_ref() + .seek(SeekFrom::Current(0)) .map_err(|err| DeserializeFailure::IoError(err.to_string()))?; let index = raw.unsigned_integer()?; - raw.as_mut_ref().seek(SeekFrom::Start(initial_position)) + raw.as_mut_ref() + .seek(SeekFrom::Start(initial_position)) .map_err(|err| DeserializeFailure::IoError(err.to_string()))?; Ok(index) } diff --git a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs index e590e251..133f989b 100644 --- a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs @@ -19,8 +19,7 @@ impl Deserialize for CommitteeHotKeyDeregistration { (|| -> Result<_, DeserializeError> { let len = raw.array()?; - let committee_dereg = - Self::deserialize_as_embedded_group(raw, len)?; + let committee_dereg = Self::deserialize_as_embedded_group(raw, len)?; if let cbor_event::Len::Indefinite = len { if raw.special()? != CBORSpecial::Break { return Err(DeserializeFailure::EndingBreakMissing.into()); diff --git a/rust/src/serialization/certificates/committee_hot_key_registration.rs b/rust/src/serialization/certificates/committee_hot_key_registration.rs index 71674754..b7faf50b 100644 --- a/rust/src/serialization/certificates/committee_hot_key_registration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_registration.rs @@ -59,11 +59,11 @@ impl DeserializeEmbeddedGroup for CommitteeHotKeyRegistration { .map_err(|e| DeserializeError::from(e).annotate("cert_index")); } - let committee_cold_key = StakeCredential::deserialize(raw) - .map_err(|e| e.annotate("committee_cold_key"))?; + let committee_cold_key = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("committee_cold_key"))?; - let committee_hot_key = StakeCredential::deserialize(raw) - .map_err(|e| e.annotate("committee_hot_key"))?; + let committee_hot_key = + StakeCredential::deserialize(raw).map_err(|e| e.annotate("committee_hot_key"))?; return Ok(CommitteeHotKeyRegistration { committee_cold_key, diff --git a/rust/src/serialization/certificates/drep_deregistration.rs b/rust/src/serialization/certificates/drep_deregistration.rs index 46633f39..6353e783 100644 --- a/rust/src/serialization/certificates/drep_deregistration.rs +++ b/rust/src/serialization/certificates/drep_deregistration.rs @@ -30,7 +30,7 @@ impl Deserialize for DrepDeregistration { Ok(cert) })() - .map_err(|e| e.annotate("DrepDeregistration")) + .map_err(|e| e.annotate("DrepDeregistration")) } } @@ -39,7 +39,6 @@ impl DeserializeEmbeddedGroup for DrepDeregistration { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - if let cbor_event::Len::Len(n) = len { if n != 3 { return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( @@ -47,7 +46,7 @@ impl DeserializeEmbeddedGroup for DrepDeregistration { len, "(cert_index, voting_credential, coin)", )) - .into()); + .into()); } } @@ -57,7 +56,7 @@ impl DeserializeEmbeddedGroup for DrepDeregistration { found: Key::Uint(cert_index), expected: Key::Uint(DEREG_DREP_CERT_INDEX), }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); } let voting_credential = diff --git a/rust/src/serialization/certificates/drep_registration.rs b/rust/src/serialization/certificates/drep_registration.rs index f073fed3..7b2802b8 100644 --- a/rust/src/serialization/certificates/drep_registration.rs +++ b/rust/src/serialization/certificates/drep_registration.rs @@ -34,7 +34,7 @@ impl Deserialize for DrepRegistration { Ok(cert) })() - .map_err(|e| e.annotate("DrepRegistration")) + .map_err(|e| e.annotate("DrepRegistration")) } } @@ -43,7 +43,6 @@ impl DeserializeEmbeddedGroup for DrepRegistration { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - if let cbor_event::Len::Len(n) = len { if n != 4 { return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( @@ -51,7 +50,7 @@ impl DeserializeEmbeddedGroup for DrepRegistration { len, "(cert_index, voting_credential, coin, anchor / null)", )) - .into()); + .into()); } } @@ -61,7 +60,7 @@ impl DeserializeEmbeddedGroup for DrepRegistration { found: Key::Uint(cert_index), expected: Key::Uint(REG_DREP_CERT_INDEX), }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); } let voting_credential = @@ -75,11 +74,11 @@ impl DeserializeEmbeddedGroup for DrepRegistration { return Err(DeserializeFailure::ExpectedNull.into()); } Ok(None) - } - else { + } else { Ok(Some(Anchor::deserialize(raw)?)) } - })().map_err(|e| e.annotate("anchor"))?; + })() + .map_err(|e| e.annotate("anchor"))?; Ok(DrepRegistration { voting_credential, @@ -87,4 +86,4 @@ impl DeserializeEmbeddedGroup for DrepRegistration { anchor, }) } -} \ No newline at end of file +} diff --git a/rust/src/serialization/certificates/drep_update.rs b/rust/src/serialization/certificates/drep_update.rs index d5683d39..0a1cb151 100644 --- a/rust/src/serialization/certificates/drep_update.rs +++ b/rust/src/serialization/certificates/drep_update.rs @@ -31,9 +31,9 @@ impl Deserialize for DrepUpdate { } } - Ok(cert) + Ok(cert) })() - .map_err(|e| e.annotate("DrepUpdate")) + .map_err(|e| e.annotate("DrepUpdate")) } } @@ -42,7 +42,6 @@ impl DeserializeEmbeddedGroup for DrepUpdate { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - if let cbor_event::Len::Len(n) = len { if n != 3 { return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( @@ -50,7 +49,7 @@ impl DeserializeEmbeddedGroup for DrepUpdate { len, "(cert_index, voting_credential, anchor / null)", )) - .into()); + .into()); } } @@ -60,7 +59,7 @@ impl DeserializeEmbeddedGroup for DrepUpdate { found: Key::Uint(cert_index), expected: Key::Uint(UPDATE_DREP_CERT_INDEX), }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); } let voting_credential = @@ -72,11 +71,11 @@ impl DeserializeEmbeddedGroup for DrepUpdate { return Err(DeserializeFailure::ExpectedNull.into()); } Ok(None) - } - else { + } else { Ok(Some(Anchor::deserialize(raw)?)) } - })().map_err(|e| e.annotate("anchor"))?; + })() + .map_err(|e| e.annotate("anchor"))?; Ok(DrepUpdate { voting_credential, diff --git a/rust/src/serialization/certificates/stake_deregistration.rs b/rust/src/serialization/certificates/stake_deregistration.rs index 993003fd..a6eddcc1 100644 --- a/rust/src/serialization/certificates/stake_deregistration.rs +++ b/rust/src/serialization/certificates/stake_deregistration.rs @@ -1,5 +1,5 @@ -use cbor_event::Len; use crate::*; +use cbor_event::Len; pub(super) const DEREG_STAKE_CERT_LEGACY_INDEX: u64 = 1; pub(super) const DEREG_STAKE_CERT_CONWAY_INDEX: u64 = 8; @@ -74,7 +74,7 @@ impl DeserializeEmbeddedGroup for StakeDeregistration { Key::Uint(DEREG_STAKE_CERT_CONWAY_INDEX), ], }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")), + .map_err(|e| DeserializeError::from(e).annotate("cert_index")), } } } @@ -92,7 +92,7 @@ fn deserialize_legacy( len, "(cert_index, stake_credential)", )) - .into()); + .into()); } } @@ -101,7 +101,7 @@ fn deserialize_legacy( found: Key::Uint(cert_index), expected: Key::Uint(DEREG_STAKE_CERT_LEGACY_INDEX), }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); } let stake_credential = @@ -112,7 +112,7 @@ fn deserialize_legacy( coin: None, }); })() - .map_err(|e| e.annotate("StakeDeregistration (legacy)")) + .map_err(|e| e.annotate("StakeDeregistration (legacy)")) } fn deserialize_conway( @@ -128,7 +128,7 @@ fn deserialize_conway( len, "(cert_index, stake_credential, coin)", )) - .into()); + .into()); } } @@ -137,7 +137,7 @@ fn deserialize_conway( found: Key::Uint(cert_index), expected: Key::Uint(DEREG_STAKE_CERT_CONWAY_INDEX), }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); } let stake_credential = @@ -150,6 +150,5 @@ fn deserialize_conway( coin: Some(coin), }); })() - .map_err(|e| e.annotate("StakeDeregistration (conway)")) + .map_err(|e| e.annotate("StakeDeregistration (conway)")) } - diff --git a/rust/src/serialization/certificates/stake_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_registration_and_delegation.rs index 8af48de7..315fa1bf 100644 --- a/rust/src/serialization/certificates/stake_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/stake_registration_and_delegation.rs @@ -31,7 +31,7 @@ impl Deserialize for StakeRegistrationAndDelegation { Ok(cert) })() - .map_err(|e| e.annotate("StakeRegistrationAndDelegation")) + .map_err(|e| e.annotate("StakeRegistrationAndDelegation")) } } @@ -40,7 +40,6 @@ impl DeserializeEmbeddedGroup for StakeRegistrationAndDelegation { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - if let cbor_event::Len::Len(n) = len { if n != 4 { return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( @@ -48,7 +47,7 @@ impl DeserializeEmbeddedGroup for StakeRegistrationAndDelegation { len, "(cert_index, stake_credential, pool_keyhash, coin)", )) - .into()); + .into()); } } @@ -58,7 +57,7 @@ impl DeserializeEmbeddedGroup for StakeRegistrationAndDelegation { found: Key::Uint(cert_index), expected: Key::Uint(STAKE_REG_DELEG_CERT_INDEX), }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); } let stake_credential = @@ -75,4 +74,4 @@ impl DeserializeEmbeddedGroup for StakeRegistrationAndDelegation { coin, }) } -} \ No newline at end of file +} diff --git a/rust/src/serialization/certificates/vote_registration_and_delegation.rs b/rust/src/serialization/certificates/vote_registration_and_delegation.rs index 8f765076..727ae30e 100644 --- a/rust/src/serialization/certificates/vote_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/vote_registration_and_delegation.rs @@ -31,7 +31,7 @@ impl Deserialize for VoteRegistrationAndDelegation { Ok(cert) })() - .map_err(|e| e.annotate("VoteRegistrationAndDelegation")) + .map_err(|e| e.annotate("VoteRegistrationAndDelegation")) } } @@ -40,7 +40,6 @@ impl DeserializeEmbeddedGroup for VoteRegistrationAndDelegation { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - if let cbor_event::Len::Len(n) = len { if n != 4 { return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( @@ -48,7 +47,7 @@ impl DeserializeEmbeddedGroup for VoteRegistrationAndDelegation { len, "(cert_index, stake_credential, drep, coin)", )) - .into()); + .into()); } } @@ -58,7 +57,7 @@ impl DeserializeEmbeddedGroup for VoteRegistrationAndDelegation { found: Key::Uint(cert_index), expected: Key::Uint(VOTE_REG_DELEG_CERT_INDEX), }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); + .map_err(|e| DeserializeError::from(e).annotate("cert_index")); } let stake_credential = @@ -74,4 +73,4 @@ impl DeserializeEmbeddedGroup for VoteRegistrationAndDelegation { coin, }) } -} \ No newline at end of file +} From 61e3a115197cd2daa4b788f91740d4d3558c9ca1 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 18 Aug 2023 00:10:21 +0400 Subject: [PATCH 054/349] move map names --- .../map_names/certificate_index_names.rs | 22 ++++++++++ rust/src/serialization/map_names/mod.rs | 11 +++++ .../serialization/map_names/tx_body_names.rs | 20 +++++++++ .../map_names/voting_proposal_index_names.rs | 10 +++++ .../map_names/witness_set_names.rs | 11 +++++ rust/src/serialization_tools/map_names.rs | 44 ------------------- rust/src/serialization_tools/mod.rs | 1 - 7 files changed, 74 insertions(+), 45 deletions(-) create mode 100644 rust/src/serialization/map_names/certificate_index_names.rs create mode 100644 rust/src/serialization/map_names/mod.rs create mode 100644 rust/src/serialization/map_names/tx_body_names.rs create mode 100644 rust/src/serialization/map_names/voting_proposal_index_names.rs create mode 100644 rust/src/serialization/map_names/witness_set_names.rs delete mode 100644 rust/src/serialization_tools/map_names.rs delete mode 100644 rust/src/serialization_tools/mod.rs diff --git a/rust/src/serialization/map_names/certificate_index_names.rs b/rust/src/serialization/map_names/certificate_index_names.rs new file mode 100644 index 00000000..64cc9a95 --- /dev/null +++ b/rust/src/serialization/map_names/certificate_index_names.rs @@ -0,0 +1,22 @@ +#[derive(Eq, Hash, PartialEq, Clone, Debug, FromPrimitive, ToPrimitive)] +pub(crate) enum CertificateIndexNames { + StakeRegistrationLegacy = 0, + StakeDeregistrationLegacy = 1, + StakeDelegation = 2, + PoolRegistration = 3, + PoolRetirement = 4, + GenesisKeyDelegation = 5, + MoveInstantaneousRewardsCert = 6, + StakeRegistrationConway = 7, + StakeDeregistrationConway = 8, + VoteDelegation = 9, + StakeAndVoteDelegation = 10, + StakeRegistrationAndDelegation = 11, + VoteRegistrationAndDelegation = 12, + StakeVoteRegistrationAndDelegation = 13, + CommitteeHotKeyRegistration = 14, + CommitteeHotKeyDeregistration = 15, + DrepRegistration = 16, + DrepDeregistration = 17, + DrepUpdate = 18, +} diff --git a/rust/src/serialization/map_names/mod.rs b/rust/src/serialization/map_names/mod.rs new file mode 100644 index 00000000..2654c3bb --- /dev/null +++ b/rust/src/serialization/map_names/mod.rs @@ -0,0 +1,11 @@ +mod tx_body_names; +pub(crate) use tx_body_names::*; + +mod witness_set_names; +pub(crate) use witness_set_names::*; + +mod certificate_index_names; +pub(crate) use certificate_index_names::*; + +mod voting_proposal_index_names; +pub(crate) use voting_proposal_index_names::*; \ No newline at end of file diff --git a/rust/src/serialization/map_names/tx_body_names.rs b/rust/src/serialization/map_names/tx_body_names.rs new file mode 100644 index 00000000..3cf71392 --- /dev/null +++ b/rust/src/serialization/map_names/tx_body_names.rs @@ -0,0 +1,20 @@ +#[derive(Eq, Hash, PartialEq, Clone, Debug, FromPrimitive, ToPrimitive)] +pub(crate) enum TxBodyNames { + Inputs = 0, + Outputs = 1, + Fee = 2, + Ttl = 3, + Certs = 4, + Withdrawals = 5, + Update = 6, + AuxiliaryDataHash = 7, + ValidityStartInterval = 8, + Mint = 9, + ScriptDataHash = 11, + Collateral = 13, + RequiredSigners = 14, + NetworkId = 15, + CollateralReturn = 16, + TotalCollateral = 17, + ReferenceInputs = 18, +} \ No newline at end of file diff --git a/rust/src/serialization/map_names/voting_proposal_index_names.rs b/rust/src/serialization/map_names/voting_proposal_index_names.rs new file mode 100644 index 00000000..f1d20f0d --- /dev/null +++ b/rust/src/serialization/map_names/voting_proposal_index_names.rs @@ -0,0 +1,10 @@ +#[derive(Eq, Hash, PartialEq, Clone, Debug , FromPrimitive, ToPrimitive)] +pub(crate) enum VotingProposalIndexNames { + ParameterChangeAction = 0, + HardForkInitiationAction = 1, + TreasuryWithdrawalsAction = 2, + NoConfidenceAction = 3, + NewCommitteeAction = 4, + NewConstitutionAction = 5, + InfoAction = 6, +} diff --git a/rust/src/serialization/map_names/witness_set_names.rs b/rust/src/serialization/map_names/witness_set_names.rs new file mode 100644 index 00000000..26bc6631 --- /dev/null +++ b/rust/src/serialization/map_names/witness_set_names.rs @@ -0,0 +1,11 @@ +#[derive(Eq, Hash, PartialEq, Clone, Debug, FromPrimitive, ToPrimitive)] +pub(crate) enum WitnessSetNames { + Vkeys = 0, + NativeScripts = 1, + Bootstraps = 2, + PlutusScriptsV1 = 3, + PlutusData = 4, + Redeemers = 5, + PlutusScriptsV2 = 6, + PlutusScriptsV3 = 7, +} \ No newline at end of file diff --git a/rust/src/serialization_tools/map_names.rs b/rust/src/serialization_tools/map_names.rs deleted file mode 100644 index 1b4000cf..00000000 --- a/rust/src/serialization_tools/map_names.rs +++ /dev/null @@ -1,44 +0,0 @@ - -#[derive(Eq, Hash, PartialEq, Clone, Debug)] -pub enum TxBodyNames { - Inputs = 0, - Outputs = 1, - Fee = 2, - // Ttl = 3, - // Certs = 4, - // Withdrawals = 5, - // Update = 6, - // AuxiliaryDataHash = 7, - // ValidityStartInterval = 8, - // Mint = 9, - // ScriptDataHash = 11, - // Collateral = 13, - // RequiredSigners = 14, - // NetworkId = 15, - // CollateralReturn = 16, - // TotalCollateral = 17, - // ReferenceInputs = 18, -} - -impl TxBodyNames { - pub fn to_number(&self) -> u64 { - self.clone() as u64 - } -} - -#[derive(Eq, Hash, PartialEq, Clone, Debug)] -pub enum WitnessSetNames { - Vkeys = 0, - // NativeScripts = 1, - Bootstraps = 2, - // PlutusScriptsV1 = 3, - // PlutusData = 4, - // Redeemers = 5, - // PlutusScriptsV2 = 6, -} - -impl WitnessSetNames { - pub fn to_number(&self) -> u64 { - self.clone() as u64 - } -} \ No newline at end of file diff --git a/rust/src/serialization_tools/mod.rs b/rust/src/serialization_tools/mod.rs deleted file mode 100644 index 06cc18f2..00000000 --- a/rust/src/serialization_tools/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod map_names; \ No newline at end of file From 35150d7dfc8b98285b65a6f6011c9dfef08cb4ce Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 18 Aug 2023 00:17:17 +0400 Subject: [PATCH 055/349] update serialization tools --- .../src/serialization/serialization_macros.rs | 23 ++++++ rust/src/serialization/struct_checks.rs | 76 +++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 rust/src/serialization/struct_checks.rs diff --git a/rust/src/serialization/serialization_macros.rs b/rust/src/serialization/serialization_macros.rs index ef98741a..de4ca060 100644 --- a/rust/src/serialization/serialization_macros.rs +++ b/rust/src/serialization/serialization_macros.rs @@ -135,3 +135,26 @@ macro_rules! impl_to_from { to_from_json!($name); }; } + +#[macro_export] +macro_rules! impl_deserialize_for_tuple { + ($type:ty) => { + impl Deserialize for $type { + fn deserialize( + raw: &mut Deserializer, + ) -> Result { + (|| -> Result<_, DeserializeError> { + use crate::serialization::struct_checks::check_len_indefinite; + let len = raw.array()?; + + let cert = Self::deserialize_as_embedded_group(raw, len)?; + + check_len_indefinite(raw, len)?; + + Ok(cert) + })() + .map_err(|e| e.annotate(stringify!($type))) + } + } + }; +} diff --git a/rust/src/serialization/struct_checks.rs b/rust/src/serialization/struct_checks.rs new file mode 100644 index 00000000..ef54dd42 --- /dev/null +++ b/rust/src/serialization/struct_checks.rs @@ -0,0 +1,76 @@ +use crate::*; + +pub(super) fn deserialize_and_check_index( + raw: &mut Deserializer, + desired_index: Option, + name: &'static str, +) -> Result { + let actual_index = raw.unsigned_integer()?; + check_index(actual_index, desired_index, name)?; + Ok(actual_index) +} + +pub(super) fn check_index( + actual_index: u64, + desired_index: Option, + name: &'static str, +) -> Result<(), DeserializeError> { + let desired_index = desired_index + .ok_or(DeserializeFailure::CustomError( + "unknown desired index".to_string(), + )) + .map_err(|e| DeserializeError::from(e))?; + if actual_index != desired_index { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(actual_index), + expected: Key::Uint(desired_index), + }) + .map_err(|e| DeserializeError::from(e).annotate(name)); + } + + Ok(()) +} + +pub(super) fn serialize_and_check_index<'se, W: Write>( + serializer: &'se mut Serializer, + index: Option, + name: &'static str, +) -> cbor_event::Result<&'se mut Serializer> { + match index { + Some(index) => serializer.write_unsigned_integer(index), + None => Err(cbor_event::Error::CustomError(format!( + "unknown index of {}", + name + ))), + } +} + +pub(super) fn check_len( + len: cbor_event::Len, + expected: u64, + struct_description: &'static str, +) -> Result<(), DeserializeError> { + if let cbor_event::Len::Len(n) = len { + if n != expected { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + expected as u64, + len, + struct_description, + )) + .into()); + } + } + Ok(()) +} + +pub(super) fn check_len_indefinite( + raw: &mut Deserializer, + len: cbor_event::Len, +) -> Result<(), DeserializeError> { + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + Ok(()) +} From 206263df53fba350d19d1cb774a8cf2173296a5d Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 18 Aug 2023 00:17:30 +0400 Subject: [PATCH 056/349] add ser traits file --- rust/src/serialization/traits.rs | 79 ++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 rust/src/serialization/traits.rs diff --git a/rust/src/serialization/traits.rs b/rust/src/serialization/traits.rs new file mode 100644 index 00000000..f0a45cc8 --- /dev/null +++ b/rust/src/serialization/traits.rs @@ -0,0 +1,79 @@ +use crate::*; +// we use the cbor_event::Serialize trait directly + +// This is only for use for plain cddl groups who need to be embedded within outer groups. +pub(crate) trait SerializeEmbeddedGroup { + fn serialize_as_embedded_group<'a, W: Write + Sized>( + &self, + serializer: &'a mut Serializer, + ) -> cbor_event::Result<&'a mut Serializer>; +} + +// same as cbor_event::de::Deserialize but with our DeserializeError +pub trait Deserialize { + fn deserialize(raw: &mut Deserializer) -> Result + where + Self: Sized; +} + +// auto-implement for all cbor_event Deserialize implementors +impl Deserialize for T { + fn deserialize(raw: &mut Deserializer) -> Result { + T::deserialize(raw).map_err(|e| DeserializeError::from(e)) + } +} + +// This is only for use for plain cddl groups who need to be embedded within outer groups. +pub trait DeserializeEmbeddedGroup { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result + where + Self: Sized; +} + +pub trait DeserializeNullable { + fn deserialize_nullable( + raw: &mut Deserializer, + ) -> Result, DeserializeError> + where + Self: Sized; +} + +impl DeserializeNullable for T { + fn deserialize_nullable( + raw: &mut Deserializer, + ) -> Result, DeserializeError> + where + Self: Sized, + { + if raw.cbor_type()? == CBORType::Special { + if raw.special()? != CBORSpecial::Null { + return Err(DeserializeFailure::ExpectedNull.into()); + } + Ok(None) + } else { + Ok(Some(T::deserialize(raw)?)) + } + } +} + +pub trait SerializeNullable { + fn serialize_nullable<'a, W: Write + Sized>( + &self, + serializer: &'a mut Serializer, + ) -> cbor_event::Result<&'a mut Serializer>; +} + +impl SerializeNullable for Option { + fn serialize_nullable<'a, W: Write + Sized>( + &self, + serializer: &'a mut Serializer, + ) -> cbor_event::Result<&'a mut Serializer> { + match self { + Some(x) => x.serialize(serializer), + None => serializer.write_special(CBORSpecial::Null), + } + } +} \ No newline at end of file From 50e52fa52be0cf9731da5423cb1b950d7cdb98f3 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 18 Aug 2023 00:18:17 +0400 Subject: [PATCH 057/349] update certificate serialization code --- .../serialization/certificates/certificate.rs | 64 ++++++------- .../committee_hot_key_deregistration.rs | 50 +++------- .../committee_hot_key_registration.rs | 51 +++------- .../certificates/drep_deregistration.rs | 50 +++------- .../certificates/drep_registration.rs | 62 +++---------- .../serialization/certificates/drep_update.rs | 62 +++---------- .../certificates/genesis_key_delegation.rs | 55 +++-------- .../move_instantaneous_rewards_cert.rs | 56 +++-------- .../certificates/pool_registration.rs | 80 +++------------- .../certificates/pool_retirement.rs | 54 +++-------- .../certificates/stake_and_vote_delegation.rs | 51 +++------- .../certificates/stake_delegation.rs | 54 +++-------- .../certificates/stake_deregistration.rs | 93 ++++++------------- .../certificates/stake_registration.rs | 89 +++++------------- .../stake_registration_and_delegation.rs | 51 +++------- .../stake_vote_registration_and_delegation.rs | 51 +++------- .../certificates/vote_delegation.rs | 51 +++------- .../vote_registration_and_delegation.rs | 50 +++------- 18 files changed, 265 insertions(+), 809 deletions(-) diff --git a/rust/src/serialization/certificates/certificate.rs b/rust/src/serialization/certificates/certificate.rs index 47334de4..bec1984b 100644 --- a/rust/src/serialization/certificates/certificate.rs +++ b/rust/src/serialization/certificates/certificate.rs @@ -1,4 +1,6 @@ +use crate::serialization::map_names::CertificateIndexNames; use crate::*; +use num_traits::FromPrimitive; use std::io::{Seek, SeekFrom}; impl cbor_event::se::Serialize for CertificateEnum { @@ -60,97 +62,95 @@ impl DeserializeEmbeddedGroup for CertificateEnum { len: cbor_event::Len, ) -> Result { let cert_index = get_cert_index(raw)?; + let index_enum = + CertificateIndexNames::from_u64(cert_index).ok_or(DeserializeError::new( + "CertificateEnum", + DeserializeFailure::UnknownKey(Key::Uint(cert_index), + )))?; - match cert_index { - super::stake_registration::STAKE_REG_LEGACY_INDEX => { + match index_enum { + CertificateIndexNames::StakeRegistrationLegacy => { Ok(CertificateEnum::StakeRegistration( StakeRegistration::deserialize_as_embedded_group(raw, len)?, )) } - super::stake_registration::STAKE_REG_CONWAY_INDEX => { + CertificateIndexNames::StakeRegistrationConway => { Ok(CertificateEnum::StakeRegistration( StakeRegistration::deserialize_as_embedded_group(raw, len)?, )) } - super::stake_deregistration::DEREG_STAKE_CERT_LEGACY_INDEX => { + CertificateIndexNames::StakeDeregistrationLegacy => { Ok(CertificateEnum::StakeDeregistration( StakeDeregistration::deserialize_as_embedded_group(raw, len)?, )) } - super::stake_deregistration::DEREG_STAKE_CERT_CONWAY_INDEX => { + CertificateIndexNames::StakeDeregistrationConway => { Ok(CertificateEnum::StakeDeregistration( StakeDeregistration::deserialize_as_embedded_group(raw, len)?, )) } - super::stake_delegation::STAKE_DELEGATION_CERT_INDEX => { - Ok(CertificateEnum::StakeDelegation( - StakeDelegation::deserialize_as_embedded_group(raw, len)?, - )) - } - super::pool_registration::REG_POOL_CERT_INDEX => Ok(CertificateEnum::PoolRegistration( + CertificateIndexNames::StakeDelegation => Ok(CertificateEnum::StakeDelegation( + StakeDelegation::deserialize_as_embedded_group(raw, len)?, + )), + + CertificateIndexNames::PoolRegistration => Ok(CertificateEnum::PoolRegistration( PoolRegistration::deserialize_as_embedded_group(raw, len)?, )), - super::pool_retirement::RETIRE_POOL_CERT_INDEX => Ok(CertificateEnum::PoolRetirement( + CertificateIndexNames::PoolRetirement => Ok(CertificateEnum::PoolRetirement( PoolRetirement::deserialize_as_embedded_group(raw, len)?, )), - super::genesis_key_delegation::GENESIS_KEY_DELEGATION_INDEX => { + CertificateIndexNames::GenesisKeyDelegation => { Ok(CertificateEnum::GenesisKeyDelegation( GenesisKeyDelegation::deserialize_as_embedded_group(raw, len)?, )) } - super::move_instantaneous_rewards_cert::MIR_CERT_INDEX => { + CertificateIndexNames::MoveInstantaneousRewardsCert => { Ok(CertificateEnum::MoveInstantaneousRewardsCert( MoveInstantaneousRewardsCert::deserialize_as_embedded_group(raw, len)?, )) } - super::committee_hot_key_registration::REG_COMMITTEE_HOT_KEY_CERT_INDEX => { + CertificateIndexNames::CommitteeHotKeyRegistration => { Ok(CertificateEnum::CommitteeHotKeyRegistration( CommitteeHotKeyRegistration::deserialize_as_embedded_group(raw, len)?, )) } - super::committee_hot_key_deregistration::UNREG_COMMITTEE_HOT_KEY_CERT_INDEX => { + CertificateIndexNames::CommitteeHotKeyDeregistration => { Ok(CertificateEnum::CommitteeHotKeyDeregistration( CommitteeHotKeyDeregistration::deserialize_as_embedded_group(raw, len)?, )) } - super::drep_registration::REG_DREP_CERT_INDEX => Ok(CertificateEnum::DrepRegistration( + CertificateIndexNames::DrepRegistration => Ok(CertificateEnum::DrepRegistration( DrepRegistration::deserialize_as_embedded_group(raw, len)?, )), - super::drep_deregistration::DEREG_DREP_CERT_INDEX => { - Ok(CertificateEnum::DrepDeregistration( - DrepDeregistration::deserialize_as_embedded_group(raw, len)?, - )) - } - super::drep_update::UPDATE_DREP_CERT_INDEX => Ok(CertificateEnum::DrepUpdate( + CertificateIndexNames::DrepDeregistration => Ok(CertificateEnum::DrepDeregistration( + DrepDeregistration::deserialize_as_embedded_group(raw, len)?, + )), + CertificateIndexNames::DrepUpdate => Ok(CertificateEnum::DrepUpdate( DrepUpdate::deserialize_as_embedded_group(raw, len)?, )), - super::stake_and_vote_delegation::STAKE_VOTE_DELEG_CERT_INDEX => { + CertificateIndexNames::StakeAndVoteDelegation => { Ok(CertificateEnum::StakeAndVoteDelegation( StakeAndVoteDelegation::deserialize_as_embedded_group(raw, len)?, )) } - super::stake_registration_and_delegation::STAKE_REG_DELEG_CERT_INDEX => { + CertificateIndexNames::StakeRegistrationAndDelegation => { Ok(CertificateEnum::StakeRegistrationAndDelegation( StakeRegistrationAndDelegation::deserialize_as_embedded_group(raw, len)?, )) } - super::stake_vote_registration_and_delegation::STAKE_VOTE_REG_DELEG_CERT_INDEX => { + CertificateIndexNames::StakeVoteRegistrationAndDelegation => { Ok(CertificateEnum::StakeVoteRegistrationAndDelegation( StakeVoteRegistrationAndDelegation::deserialize_as_embedded_group(raw, len)?, )) } - super::vote_delegation::VOTE_CERT_INDEX => Ok(CertificateEnum::VoteDelegation( + CertificateIndexNames::VoteDelegation => Ok(CertificateEnum::VoteDelegation( VoteDelegation::deserialize_as_embedded_group(raw, len)?, )), - super::vote_registration_and_delegation::VOTE_REG_DELEG_CERT_INDEX => { + CertificateIndexNames::VoteRegistrationAndDelegation => { Ok(CertificateEnum::VoteRegistrationAndDelegation( VoteRegistrationAndDelegation::deserialize_as_embedded_group(raw, len)?, )) } - _ => Err(DeserializeError::new( - "CertificateEnum", - DeserializeFailure::UnknownKey(Key::Uint(cert_index)), - )), } } } diff --git a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs index 133f989b..4ddba355 100644 --- a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs @@ -1,6 +1,7 @@ +use num_traits::ToPrimitive; use crate::*; - -pub(super) const UNREG_COMMITTEE_HOT_KEY_CERT_INDEX: u64 = 15; +use crate::serialization::map_names::CertificateIndexNames; +use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; impl cbor_event::se::Serialize for CommitteeHotKeyDeregistration { fn serialize<'se, W: Write>( @@ -8,54 +9,27 @@ impl cbor_event::se::Serialize for CommitteeHotKeyDeregistration { serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(2))?; - serializer.write_unsigned_integer(UNREG_COMMITTEE_HOT_KEY_CERT_INDEX)?; + let proposal_index = CertificateIndexNames::CommitteeHotKeyDeregistration.to_u64(); + serialize_and_check_index(serializer, proposal_index, "CommitteeHotKeyDeregistration")?; + self.committee_cold_key.serialize(serializer)?; Ok(serializer) } } -impl Deserialize for CommitteeHotKeyDeregistration { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - - let committee_dereg = Self::deserialize_as_embedded_group(raw, len)?; - if let cbor_event::Len::Indefinite = len { - if raw.special()? != CBORSpecial::Break { - return Err(DeserializeFailure::EndingBreakMissing.into()); - } - } - - Ok(committee_dereg) - })() - .map_err(|e| e.annotate("CommitteeHotKeyDeregistration")) - } -} +impl_deserialize_for_tuple!(CommitteeHotKeyDeregistration); impl DeserializeEmbeddedGroup for CommitteeHotKeyDeregistration { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - if let cbor_event::Len::Len(n) = len { - if n != 2 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 2, - len, - "(cert_index, committee_cold_key)", - )) - .into()); - } - } - let cert_index = raw.unsigned_integer()?; - if cert_index != UNREG_COMMITTEE_HOT_KEY_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(UNREG_COMMITTEE_HOT_KEY_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } + check_len(len, 2, "(cert_index, committee_cold_key)")?; + + let cert_index = CertificateIndexNames::CommitteeHotKeyDeregistration.to_u64(); + deserialize_and_check_index(raw, cert_index, "cert_index")?; + let committee_cold_key = StakeCredential::deserialize(raw).map_err(|e| e.annotate("committee_cold_key"))?; diff --git a/rust/src/serialization/certificates/committee_hot_key_registration.rs b/rust/src/serialization/certificates/committee_hot_key_registration.rs index b7faf50b..8118743f 100644 --- a/rust/src/serialization/certificates/committee_hot_key_registration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_registration.rs @@ -1,6 +1,7 @@ +use num_traits::ToPrimitive; use crate::*; - -pub(super) const REG_COMMITTEE_HOT_KEY_CERT_INDEX: u64 = 14; +use crate::serialization::map_names::CertificateIndexNames; +use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; impl cbor_event::se::Serialize for CommitteeHotKeyRegistration { fn serialize<'se, W: Write>( @@ -8,56 +9,28 @@ impl cbor_event::se::Serialize for CommitteeHotKeyRegistration { serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(3))?; - serializer.write_unsigned_integer(REG_COMMITTEE_HOT_KEY_CERT_INDEX)?; + + let proposal_index = CertificateIndexNames::CommitteeHotKeyRegistration.to_u64(); + serialize_and_check_index(serializer, proposal_index, "CommitteeHotKeyRegistration")?; + self.committee_cold_key.serialize(serializer)?; self.committee_hot_key.serialize(serializer)?; Ok(serializer) } } -impl Deserialize for CommitteeHotKeyRegistration { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - - let cert = Self::deserialize_as_embedded_group(raw, len)?; - - if let cbor_event::Len::Indefinite = len { - if raw.special()? != CBORSpecial::Break { - return Err(DeserializeFailure::EndingBreakMissing.into()); - } - } - - Ok(cert) - })() - .map_err(|e| e.annotate("CommitteeHotKeyRegistration")) - } -} +impl_deserialize_for_tuple!(CommitteeHotKeyRegistration); impl DeserializeEmbeddedGroup for CommitteeHotKeyRegistration { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - if let cbor_event::Len::Len(n) = len { - if n != 3 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 3, - len, - "(cert_index, committee_cold_key, committee_hot_key)", - )) - .into()); - } - } - let cert_index = raw.unsigned_integer()?; - if cert_index != REG_COMMITTEE_HOT_KEY_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(REG_COMMITTEE_HOT_KEY_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } + check_len(len, 3, "(cert_index, committee_cold_key, committee_hot_key)")?; + + let cert_index = CertificateIndexNames::CommitteeHotKeyRegistration.to_u64(); + deserialize_and_check_index(raw, cert_index, "cert_index")?; let committee_cold_key = StakeCredential::deserialize(raw).map_err(|e| e.annotate("committee_cold_key"))?; diff --git a/rust/src/serialization/certificates/drep_deregistration.rs b/rust/src/serialization/certificates/drep_deregistration.rs index 6353e783..05aa2b19 100644 --- a/rust/src/serialization/certificates/drep_deregistration.rs +++ b/rust/src/serialization/certificates/drep_deregistration.rs @@ -1,6 +1,7 @@ +use num_traits::ToPrimitive; use crate::*; - -pub(super) const DEREG_DREP_CERT_INDEX: u64 = 17; +use crate::serialization::map_names::CertificateIndexNames; +use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; impl cbor_event::se::Serialize for DrepDeregistration { fn serialize<'se, W: Write>( @@ -8,56 +9,27 @@ impl cbor_event::se::Serialize for DrepDeregistration { serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(3))?; - serializer.write_unsigned_integer(DEREG_DREP_CERT_INDEX)?; + + let proposal_index = CertificateIndexNames::DrepDeregistration.to_u64(); + serialize_and_check_index(serializer, proposal_index, "DrepDeregistration")?; + self.voting_credential.serialize(serializer)?; self.coin.serialize(serializer)?; Ok(serializer) } } -impl Deserialize for DrepDeregistration { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - - let cert = Self::deserialize_as_embedded_group(raw, len)?; - - if let cbor_event::Len::Indefinite = len { - if raw.special()? != CBORSpecial::Break { - return Err(DeserializeFailure::EndingBreakMissing.into()); - } - } - - Ok(cert) - })() - .map_err(|e| e.annotate("DrepDeregistration")) - } -} +impl_deserialize_for_tuple!(DrepDeregistration); impl DeserializeEmbeddedGroup for DrepDeregistration { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - if let cbor_event::Len::Len(n) = len { - if n != 3 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 3, - len, - "(cert_index, voting_credential, coin)", - )) - .into()); - } - } + check_len(len, 3, "(cert_index, voting_credential, coin)")?; - let cert_index = raw.unsigned_integer()?; - if cert_index != DEREG_DREP_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(DEREG_DREP_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } + let cert_index = CertificateIndexNames::DrepDeregistration.to_u64(); + deserialize_and_check_index(raw, cert_index, "cert_index")?; let voting_credential = StakeCredential::deserialize(raw).map_err(|e| e.annotate("voting_credential"))?; diff --git a/rust/src/serialization/certificates/drep_registration.rs b/rust/src/serialization/certificates/drep_registration.rs index 7b2802b8..54a3de74 100644 --- a/rust/src/serialization/certificates/drep_registration.rs +++ b/rust/src/serialization/certificates/drep_registration.rs @@ -1,6 +1,7 @@ +use num_traits::ToPrimitive; use crate::*; - -pub(super) const REG_DREP_CERT_INDEX: u64 = 16; +use crate::serialization::map_names::CertificateIndexNames; +use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; impl cbor_event::se::Serialize for DrepRegistration { fn serialize<'se, W: Write>( @@ -8,7 +9,10 @@ impl cbor_event::se::Serialize for DrepRegistration { serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(4))?; - serializer.write_unsigned_integer(REG_DREP_CERT_INDEX)?; + + let proposal_index = CertificateIndexNames::DrepRegistration.to_u64(); + serialize_and_check_index(serializer, proposal_index, "DrepRegistration")?; + self.voting_credential.serialize(serializer)?; self.coin.serialize(serializer)?; match &self.anchor { @@ -19,66 +23,24 @@ impl cbor_event::se::Serialize for DrepRegistration { } } -impl Deserialize for DrepRegistration { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - - let cert = Self::deserialize_as_embedded_group(raw, len)?; - - if let cbor_event::Len::Indefinite = len { - if raw.special()? != CBORSpecial::Break { - return Err(DeserializeFailure::EndingBreakMissing.into()); - } - } - - Ok(cert) - })() - .map_err(|e| e.annotate("DrepRegistration")) - } -} +impl_deserialize_for_tuple!(DrepRegistration); impl DeserializeEmbeddedGroup for DrepRegistration { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - if let cbor_event::Len::Len(n) = len { - if n != 4 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 4, - len, - "(cert_index, voting_credential, coin, anchor / null)", - )) - .into()); - } - } + check_len(len, 4, "(cert_index, voting_credential, coin, anchor / null)")?; - let cert_index = raw.unsigned_integer()?; - if cert_index != REG_DREP_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(REG_DREP_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } + let cert_index = CertificateIndexNames::DrepRegistration.to_u64(); + deserialize_and_check_index(raw, cert_index, "cert_index")?; let voting_credential = StakeCredential::deserialize(raw).map_err(|e| e.annotate("voting_credential"))?; let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; - let anchor = (|| -> Result<_, DeserializeError> { - if raw.cbor_type()? == CBORType::Special { - if raw.special()? != CBORSpecial::Null { - return Err(DeserializeFailure::ExpectedNull.into()); - } - Ok(None) - } else { - Ok(Some(Anchor::deserialize(raw)?)) - } - })() - .map_err(|e| e.annotate("anchor"))?; + let anchor = Anchor::deserialize_nullable(raw).map_err(|e| e.annotate("anchor"))?; Ok(DrepRegistration { voting_credential, diff --git a/rust/src/serialization/certificates/drep_update.rs b/rust/src/serialization/certificates/drep_update.rs index 0a1cb151..42bd2895 100644 --- a/rust/src/serialization/certificates/drep_update.rs +++ b/rust/src/serialization/certificates/drep_update.rs @@ -1,6 +1,7 @@ +use num_traits::ToPrimitive; use crate::*; - -pub(super) const UPDATE_DREP_CERT_INDEX: u64 = 18; +use crate::serialization::map_names::CertificateIndexNames; +use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; impl cbor_event::se::Serialize for DrepUpdate { fn serialize<'se, W: Write>( @@ -8,7 +9,10 @@ impl cbor_event::se::Serialize for DrepUpdate { serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(3))?; - serializer.write_unsigned_integer(UPDATE_DREP_CERT_INDEX)?; + + let proposal_index = CertificateIndexNames::DrepUpdate.to_u64(); + serialize_and_check_index(serializer, proposal_index, "DrepUpdate")?; + self.voting_credential.serialize(serializer)?; match &self.anchor { Some(anchor) => anchor.serialize(serializer), @@ -18,64 +22,22 @@ impl cbor_event::se::Serialize for DrepUpdate { } } -impl Deserialize for DrepUpdate { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - - let cert = Self::deserialize_as_embedded_group(raw, len)?; - - if let cbor_event::Len::Indefinite = len { - if raw.special()? != CBORSpecial::Break { - return Err(DeserializeFailure::EndingBreakMissing.into()); - } - } - - Ok(cert) - })() - .map_err(|e| e.annotate("DrepUpdate")) - } -} +impl_deserialize_for_tuple!(DrepUpdate); impl DeserializeEmbeddedGroup for DrepUpdate { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - if let cbor_event::Len::Len(n) = len { - if n != 3 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 3, - len, - "(cert_index, voting_credential, anchor / null)", - )) - .into()); - } - } + check_len(len, 3, "(cert_index, voting_credential, anchor / null)")?; - let cert_index = raw.unsigned_integer()?; - if cert_index != UPDATE_DREP_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(UPDATE_DREP_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } + let cert_index = CertificateIndexNames::DrepUpdate.to_u64(); + deserialize_and_check_index(raw, cert_index, "cert_index")?; let voting_credential = StakeCredential::deserialize(raw).map_err(|e| e.annotate("voting_credential"))?; - let anchor = (|| -> Result<_, DeserializeError> { - if raw.cbor_type()? == CBORType::Special { - if raw.special()? != CBORSpecial::Null { - return Err(DeserializeFailure::ExpectedNull.into()); - } - Ok(None) - } else { - Ok(Some(Anchor::deserialize(raw)?)) - } - })() - .map_err(|e| e.annotate("anchor"))?; + let anchor = Anchor::deserialize_nullable(raw).map_err(|e| e.annotate("anchor"))?; Ok(DrepUpdate { voting_credential, diff --git a/rust/src/serialization/certificates/genesis_key_delegation.rs b/rust/src/serialization/certificates/genesis_key_delegation.rs index da35100e..6f7691fe 100644 --- a/rust/src/serialization/certificates/genesis_key_delegation.rs +++ b/rust/src/serialization/certificates/genesis_key_delegation.rs @@ -1,6 +1,7 @@ +use num_traits::ToPrimitive; use crate::*; - -pub(super) const GENESIS_KEY_DELEGATION_INDEX: u64 = 5; +use crate::serialization::map_names::CertificateIndexNames; +use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; impl cbor_event::se::Serialize for GenesisKeyDelegation { fn serialize<'se, W: Write>( @@ -17,7 +18,10 @@ impl SerializeEmbeddedGroup for GenesisKeyDelegation { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(GENESIS_KEY_DELEGATION_INDEX)?; + + let proposal_index = CertificateIndexNames::GenesisKeyDelegation.to_u64(); + serialize_and_check_index(serializer, proposal_index, "GenesisKeyDelegation")?; + self.genesishash.serialize(serializer)?; self.genesis_delegate_hash.serialize(serializer)?; self.vrf_keyhash.serialize(serializer)?; @@ -25,52 +29,19 @@ impl SerializeEmbeddedGroup for GenesisKeyDelegation { } } -impl Deserialize for GenesisKeyDelegation { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => {} - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - _ => {} - } - ret - })() - .map_err(|e| e.annotate("GenesisKeyDelegation")) - } -} +impl_deserialize_for_tuple!(GenesisKeyDelegation); impl DeserializeEmbeddedGroup for GenesisKeyDelegation { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - (|| -> Result<_, DeserializeError> { - if let cbor_event::Len::Len(n) = len { - if n != 4 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 4, - len, - "(cert_index, genesishash, genesis_delegate_hash, vrf_keyhash)", - )) - .into()); - } - } - let cert_index = raw.unsigned_integer()?; - if cert_index != GENESIS_KEY_DELEGATION_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(GENESIS_KEY_DELEGATION_INDEX), - } - .into()); - } - Ok(()) - })() - .map_err(|e| e.annotate("cert_index"))?; + check_len(len, 4, "(cert_index, genesishash, genesis_delegate_hash, vrf_keyhash)")?; + + let cert_index = CertificateIndexNames::GenesisKeyDelegation.to_u64(); + deserialize_and_check_index(raw, cert_index, "cert_index")?; + let genesishash = (|| -> Result<_, DeserializeError> { Ok(GenesisHash::deserialize(raw)?) })() .map_err(|e| e.annotate("genesishash"))?; diff --git a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs index e47acff5..cd6317e0 100644 --- a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs +++ b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs @@ -1,6 +1,7 @@ +use num_traits::ToPrimitive; use crate::*; - -pub(super) const MIR_CERT_INDEX: u64 = 6; +use crate::serialization::map_names::CertificateIndexNames; +use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; impl cbor_event::se::Serialize for MIRToStakeCredentials { fn serialize<'se, W: Write>( @@ -119,57 +120,28 @@ impl SerializeEmbeddedGroup for MoveInstantaneousRewardsCert { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(MIR_CERT_INDEX)?; + + let proposal_index = CertificateIndexNames::MoveInstantaneousRewardsCert.to_u64(); + serialize_and_check_index(serializer, proposal_index, "MoveInstantaneousRewardsCert")?; + self.move_instantaneous_reward.serialize(serializer)?; Ok(serializer) } } -impl Deserialize for MoveInstantaneousRewardsCert { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => {} - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - _ => {} - } - ret - })() - .map_err(|e| e.annotate("MoveInstantaneousRewardsCert")) - } -} +impl_deserialize_for_tuple!(MoveInstantaneousRewardsCert); impl DeserializeEmbeddedGroup for MoveInstantaneousRewardsCert { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - (|| -> Result<_, DeserializeError> { - if let cbor_event::Len::Len(n) = len { - if n != 2 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 2, - len, - "(cert_index, move_instantaneous_reward)", - )) - .into()); - } - } - let cert_index = raw.unsigned_integer()?; - if cert_index != MIR_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(MIR_CERT_INDEX), - } - .into()); - } - Ok(()) - })() - .map_err(|e| e.annotate("cert_index"))?; + + check_len(len, 2, "(cert_index, move_instantaneous_reward)")?; + + let cert_index = CertificateIndexNames::MoveInstantaneousRewardsCert.to_u64(); + deserialize_and_check_index(raw, cert_index, "cert_index")?; + let move_instantaneous_reward = (|| -> Result<_, DeserializeError> { Ok(MoveInstantaneousReward::deserialize(raw)?) })( ) diff --git a/rust/src/serialization/certificates/pool_registration.rs b/rust/src/serialization/certificates/pool_registration.rs index ee5458a3..b1261de8 100644 --- a/rust/src/serialization/certificates/pool_registration.rs +++ b/rust/src/serialization/certificates/pool_registration.rs @@ -1,6 +1,7 @@ +use crate::serialization::map_names::CertificateIndexNames; +use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; use crate::*; - -pub(super) const REG_POOL_CERT_INDEX: u64 = 3; +use num_traits::ToPrimitive; impl cbor_event::se::Serialize for Relays { fn serialize<'se, W: Write>( @@ -68,31 +69,7 @@ impl SerializeEmbeddedGroup for PoolParams { } } -impl Deserialize for PoolParams { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("PoolParams")) - } -} +impl_deserialize_for_tuple!(PoolParams); impl DeserializeEmbeddedGroup for PoolParams { fn deserialize_as_embedded_group( @@ -160,58 +137,27 @@ impl SerializeEmbeddedGroup for PoolRegistration { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(REG_POOL_CERT_INDEX)?; + let proposal_index = CertificateIndexNames::PoolRegistration.to_u64(); + serialize_and_check_index(serializer, proposal_index, "PoolRegistration")?; + self.pool_params.serialize_as_embedded_group(serializer)?; Ok(serializer) } } -impl Deserialize for PoolRegistration { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => {} - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - _ => {} - } - ret - })() - .map_err(|e| e.annotate("PoolRegistration")) - } -} +impl_deserialize_for_tuple!(PoolRegistration); impl DeserializeEmbeddedGroup for PoolRegistration { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - (|| -> Result<_, DeserializeError> { - if let cbor_event::Len::Len(n) = len { - if n != 2 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 2, - len, - "(cert_index, pool_params)", - )) - .into()); - } - } - let cert_index = raw.unsigned_integer()?; - if cert_index != REG_POOL_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(REG_POOL_CERT_INDEX), - } - .into()); - } - Ok(()) - })() - .map_err(|e| e.annotate("cert_index"))?; + check_len(len, 2, "(cert_index, pool_params)")?; + + let cert_index = CertificateIndexNames::PoolRegistration.to_u64(); + deserialize_and_check_index(raw, cert_index, "cert_index")?; + let pool_params = (|| -> Result<_, DeserializeError> { Ok(PoolParams::deserialize_as_embedded_group(raw, len)?) })() diff --git a/rust/src/serialization/certificates/pool_retirement.rs b/rust/src/serialization/certificates/pool_retirement.rs index 929e4518..75d40d29 100644 --- a/rust/src/serialization/certificates/pool_retirement.rs +++ b/rust/src/serialization/certificates/pool_retirement.rs @@ -1,6 +1,7 @@ +use num_traits::ToPrimitive; use crate::*; - -pub(super) const RETIRE_POOL_CERT_INDEX: u64 = 4; +use crate::serialization::map_names::CertificateIndexNames; +use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; impl cbor_event::se::Serialize for PoolRetirement { fn serialize<'se, W: Write>( @@ -17,58 +18,27 @@ impl SerializeEmbeddedGroup for PoolRetirement { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(RETIRE_POOL_CERT_INDEX)?; + + let proposal_index = CertificateIndexNames::PoolRetirement.to_u64(); + serialize_and_check_index(serializer, proposal_index, "PoolRetirement")?; + self.pool_keyhash.serialize(serializer)?; self.epoch.serialize(serializer)?; Ok(serializer) } } -impl Deserialize for PoolRetirement { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => {} - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - _ => {} - } - ret - })() - .map_err(|e| e.annotate("PoolRetirement")) - } -} +impl_deserialize_for_tuple!(PoolRetirement); impl DeserializeEmbeddedGroup for PoolRetirement { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - (|| -> Result<_, DeserializeError> { - if let cbor_event::Len::Len(n) = len { - if n != 3 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 3, - len, - "(cert_index, pool_keyhash, epoch)", - )) - .into()); - } - } - let cert_index = raw.unsigned_integer()?; - if cert_index != RETIRE_POOL_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(RETIRE_POOL_CERT_INDEX), - } - .into()); - } - Ok(()) - })() - .map_err(|e| e.annotate("cert_index"))?; + check_len(len, 3, "(cert_index, pool_keyhash, epoch)")?; + let cert_index = CertificateIndexNames::PoolRetirement.to_u64(); + deserialize_and_check_index(raw, cert_index, "cert_index")?; + let pool_keyhash = (|| -> Result<_, DeserializeError> { Ok(Ed25519KeyHash::deserialize(raw)?) })() .map_err(|e| e.annotate("pool_keyhash"))?; diff --git a/rust/src/serialization/certificates/stake_and_vote_delegation.rs b/rust/src/serialization/certificates/stake_and_vote_delegation.rs index 9c106e68..ffd8071c 100644 --- a/rust/src/serialization/certificates/stake_and_vote_delegation.rs +++ b/rust/src/serialization/certificates/stake_and_vote_delegation.rs @@ -1,6 +1,7 @@ +use num_traits::ToPrimitive; use crate::*; - -pub(super) const STAKE_VOTE_DELEG_CERT_INDEX: u64 = 10; +use crate::serialization::map_names::CertificateIndexNames; +use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; impl cbor_event::se::Serialize for StakeAndVoteDelegation { fn serialize<'se, W: Write>( @@ -8,7 +9,10 @@ impl cbor_event::se::Serialize for StakeAndVoteDelegation { serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(4))?; - serializer.write_unsigned_integer(STAKE_VOTE_DELEG_CERT_INDEX)?; + + let proposal_index = CertificateIndexNames::StakeAndVoteDelegation.to_u64(); + serialize_and_check_index(serializer, proposal_index, "StakeAndVoteDelegation")?; + self.stake_credential.serialize(serializer)?; self.pool_keyhash.serialize(serializer)?; self.drep.serialize(serializer)?; @@ -16,49 +20,16 @@ impl cbor_event::se::Serialize for StakeAndVoteDelegation { } } -impl Deserialize for StakeAndVoteDelegation { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - - let cert = Self::deserialize_as_embedded_group(raw, len)?; - - if let cbor_event::Len::Indefinite = len { - if raw.special()? != CBORSpecial::Break { - return Err(DeserializeFailure::EndingBreakMissing.into()); - } - } - - Ok(cert) - })() - .map_err(|e| e.annotate("StakeAndVoteDelegation")) - } -} +impl_deserialize_for_tuple!(StakeAndVoteDelegation); impl DeserializeEmbeddedGroup for StakeAndVoteDelegation { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - if let cbor_event::Len::Len(n) = len { - if n != 4 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 4, - len, - "(cert_index, stake_credential, pool_keyhash, drep)", - )) - .into()); - } - } - - let cert_index = raw.unsigned_integer()?; - if cert_index != STAKE_VOTE_DELEG_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(STAKE_VOTE_DELEG_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } + check_len(len, 4, "(cert_index, stake_credential, pool_keyhash, drep)")?; + let cert_index = CertificateIndexNames::StakeAndVoteDelegation.to_u64(); + deserialize_and_check_index(raw, cert_index, "cert_index")?; let stake_credential = StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; diff --git a/rust/src/serialization/certificates/stake_delegation.rs b/rust/src/serialization/certificates/stake_delegation.rs index 66336e96..7a9bb3ff 100644 --- a/rust/src/serialization/certificates/stake_delegation.rs +++ b/rust/src/serialization/certificates/stake_delegation.rs @@ -1,6 +1,7 @@ +use num_traits::ToPrimitive; use crate::*; - -pub(super) const STAKE_DELEGATION_CERT_INDEX: u64 = 2; +use crate::serialization::map_names::CertificateIndexNames; +use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; impl cbor_event::se::Serialize for StakeDelegation { fn serialize<'se, W: Write>( @@ -17,59 +18,28 @@ impl SerializeEmbeddedGroup for StakeDelegation { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(STAKE_DELEGATION_CERT_INDEX)?; + + let proposal_index = CertificateIndexNames::StakeDelegation.to_u64(); + serialize_and_check_index(serializer, proposal_index, "StakeDelegation")?; + self.stake_credential.serialize(serializer)?; self.pool_keyhash.serialize(serializer)?; Ok(serializer) } } -impl Deserialize for StakeDelegation { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => {} - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - _ => {} - } - ret - })() - .map_err(|e| e.annotate("StakeDelegation")) - } -} +impl_deserialize_for_tuple!(StakeDelegation); impl DeserializeEmbeddedGroup for StakeDelegation { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - (|| -> Result<_, DeserializeError> { - if let cbor_event::Len::Len(n) = len { - if n != 3 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 3, - len, - "(cert_index, stake_credential, pool_keyhash)", - )) - .into()); - } - } - let cert_index = raw.unsigned_integer()?; - if cert_index != STAKE_DELEGATION_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(STAKE_DELEGATION_CERT_INDEX), - } - .into()); - } - Ok(()) - })() - .map_err(|e| e.annotate("cert_index"))?; + check_len(len, 3, "(cert_index, stake_credential, pool_keyhash)")?; + let cert_index = CertificateIndexNames::StakeDelegation.to_u64(); + deserialize_and_check_index(raw, cert_index, "cert_index")?; + let stake_credential = (|| -> Result<_, DeserializeError> { Ok(StakeCredential::deserialize(raw)?) })() .map_err(|e| e.annotate("stake_credential"))?; diff --git a/rust/src/serialization/certificates/stake_deregistration.rs b/rust/src/serialization/certificates/stake_deregistration.rs index a6eddcc1..54f2eeef 100644 --- a/rust/src/serialization/certificates/stake_deregistration.rs +++ b/rust/src/serialization/certificates/stake_deregistration.rs @@ -1,8 +1,10 @@ +use crate::serialization::map_names::CertificateIndexNames; +use crate::serialization::struct_checks::{ + check_index, check_len, serialize_and_check_index, +}; use crate::*; use cbor_event::Len; - -pub(super) const DEREG_STAKE_CERT_LEGACY_INDEX: u64 = 1; -pub(super) const DEREG_STAKE_CERT_CONWAY_INDEX: u64 = 8; +use num_traits::{FromPrimitive, ToPrimitive}; impl cbor_event::se::Serialize for StakeDeregistration { fn serialize<'se, W: Write>( @@ -22,7 +24,10 @@ fn serialize_as_legacy<'se, W: Write>( serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(2))?; - serializer.write_unsigned_integer(DEREG_STAKE_CERT_LEGACY_INDEX)?; + + let proposal_index = CertificateIndexNames::StakeDeregistrationLegacy.to_u64(); + serialize_and_check_index(serializer, proposal_index, "StakeDeregistrationLegacy")?; + cert.stake_credential.serialize(serializer)?; Ok(serializer) } @@ -32,7 +37,10 @@ fn serialize_as_conway<'se, W: Write>( serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(3))?; - serializer.write_unsigned_integer(DEREG_STAKE_CERT_CONWAY_INDEX)?; + + let proposal_index = CertificateIndexNames::StakeDeregistrationConway.to_u64(); + serialize_and_check_index(serializer, proposal_index, "StakeDeregistrationConway")?; + cert.stake_credential.serialize(serializer)?; if let Some(coin) = cert.coin { coin.serialize(serializer)?; @@ -40,23 +48,7 @@ fn serialize_as_conway<'se, W: Write>( Ok(serializer) } -impl Deserialize for StakeDeregistration { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - Len::Indefinite => match raw.special()? { - CBORSpecial::Break => {} - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - _ => {} - } - ret - })() - .map_err(|e| e.annotate("StakeDeregistration")) - } -} +impl_deserialize_for_tuple!(StakeDeregistration); impl DeserializeEmbeddedGroup for StakeDeregistration { fn deserialize_as_embedded_group( @@ -64,14 +56,19 @@ impl DeserializeEmbeddedGroup for StakeDeregistration { len: Len, ) -> Result { let cert_index = raw.unsigned_integer()?; - match cert_index { - DEREG_STAKE_CERT_LEGACY_INDEX => deserialize_legacy(raw, cert_index, len), - DEREG_STAKE_CERT_CONWAY_INDEX => deserialize_conway(raw, cert_index, len), + let index_enum = CertificateIndexNames::from_u64(cert_index); + match index_enum { + Some(CertificateIndexNames::StakeDeregistrationLegacy) => { + deserialize_legacy(raw, cert_index, len) + } + Some(CertificateIndexNames::StakeDeregistrationConway) => { + deserialize_conway(raw, cert_index, len) + } _ => Err(DeserializeFailure::FixedValuesMismatch { found: Key::Uint(cert_index), expected: vec![ - Key::Uint(DEREG_STAKE_CERT_LEGACY_INDEX), - Key::Uint(DEREG_STAKE_CERT_CONWAY_INDEX), + Key::OptUint(CertificateIndexNames::StakeDeregistrationLegacy.to_u64()), + Key::OptUint(CertificateIndexNames::StakeDeregistrationConway.to_u64()), ], }) .map_err(|e| DeserializeError::from(e).annotate("cert_index")), @@ -85,24 +82,9 @@ fn deserialize_legacy( len: Len, ) -> Result { (|| -> Result<_, DeserializeError> { - if let Len::Len(n) = len { - if n != 2 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 2, - len, - "(cert_index, stake_credential)", - )) - .into()); - } - } - - if cert_index != DEREG_STAKE_CERT_LEGACY_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(DEREG_STAKE_CERT_LEGACY_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } + check_len(len, 2, "(cert_index, stake_credential)")?; + let desired_index = CertificateIndexNames::StakeDeregistrationLegacy.to_u64(); + check_index(cert_index, desired_index, "cert_index")?; let stake_credential = StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; @@ -121,24 +103,9 @@ fn deserialize_conway( len: Len, ) -> Result { (|| -> Result<_, DeserializeError> { - if let Len::Len(n) = len { - if n != 3 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 3, - len, - "(cert_index, stake_credential, coin)", - )) - .into()); - } - } - - if cert_index != DEREG_STAKE_CERT_CONWAY_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(DEREG_STAKE_CERT_CONWAY_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } + check_len(len, 3, "(cert_index, stake_credential, coin)")?; + let desired_index = CertificateIndexNames::StakeDeregistrationConway.to_u64(); + check_index(cert_index, desired_index, "cert_index")?; let stake_credential = StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; diff --git a/rust/src/serialization/certificates/stake_registration.rs b/rust/src/serialization/certificates/stake_registration.rs index 409a89a3..45d40d73 100644 --- a/rust/src/serialization/certificates/stake_registration.rs +++ b/rust/src/serialization/certificates/stake_registration.rs @@ -1,8 +1,8 @@ use crate::*; use cbor_event::Len; - -pub(super) const STAKE_REG_LEGACY_INDEX: u64 = 0; -pub(super) const STAKE_REG_CONWAY_INDEX: u64 = 7; +use num_traits::{FromPrimitive, ToPrimitive}; +use crate::serialization::map_names::CertificateIndexNames; +use crate::serialization::struct_checks::{check_index, check_len, serialize_and_check_index}; impl cbor_event::se::Serialize for StakeRegistration { fn serialize<'se, W: Write>( @@ -22,7 +22,10 @@ fn serialize_as_legacy<'se, W: Write>( serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(2))?; - serializer.write_unsigned_integer(STAKE_REG_LEGACY_INDEX)?; + + let proposal_index = CertificateIndexNames::StakeRegistrationLegacy.to_u64(); + serialize_and_check_index(serializer, proposal_index, "StakeRegistrationLegacy")?; + cert.stake_credential.serialize(serializer)?; Ok(serializer) } @@ -32,7 +35,10 @@ fn serialize_as_conway<'se, W: Write>( serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(3))?; - serializer.write_unsigned_integer(STAKE_REG_CONWAY_INDEX)?; + + let proposal_index = CertificateIndexNames::StakeRegistrationConway.to_u64(); + serialize_and_check_index(serializer, proposal_index, "StakeRegistrationConway")?; + cert.stake_credential.serialize(serializer)?; if let Some(coin) = cert.coin { coin.serialize(serializer)?; @@ -40,23 +46,7 @@ fn serialize_as_conway<'se, W: Write>( Ok(serializer) } -impl Deserialize for StakeRegistration { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - Len::Indefinite => match raw.special()? { - CBORSpecial::Break => {} - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - _ => {} - } - ret - })() - .map_err(|e| e.annotate("StakeRegistration")) - } -} +impl_deserialize_for_tuple!(StakeRegistration); impl DeserializeEmbeddedGroup for StakeRegistration { fn deserialize_as_embedded_group( @@ -64,17 +54,18 @@ impl DeserializeEmbeddedGroup for StakeRegistration { len: Len, ) -> Result { let cert_index = raw.unsigned_integer()?; - match cert_index { - STAKE_REG_LEGACY_INDEX => deserialize_legacy(raw, cert_index, len), - STAKE_REG_CONWAY_INDEX => deserialize_conway(raw, cert_index, len), + let index_enum = CertificateIndexNames::from_u64(cert_index); + match index_enum { + Some(CertificateIndexNames::StakeRegistrationLegacy) => deserialize_legacy(raw, cert_index, len), + Some(CertificateIndexNames::StakeRegistrationConway) => deserialize_conway(raw, cert_index, len), _ => Err(DeserializeFailure::FixedValuesMismatch { found: Key::Uint(cert_index), expected: vec![ - Key::Uint(STAKE_REG_LEGACY_INDEX), - Key::Uint(STAKE_REG_CONWAY_INDEX), + Key::OptUint(CertificateIndexNames::StakeRegistrationLegacy.to_u64()), + Key::OptUint(CertificateIndexNames::StakeRegistrationConway.to_u64()), ], }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")), + .map_err(|e| DeserializeError::from(e).annotate("cert_index")), } } } @@ -85,24 +76,9 @@ fn deserialize_legacy( len: Len, ) -> Result { (|| -> Result<_, DeserializeError> { - if let Len::Len(n) = len { - if n != 2 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 2, - len, - "(cert_index, stake_credential)", - )) - .into()); - } - } - - if cert_index != STAKE_REG_LEGACY_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(STAKE_REG_LEGACY_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } + check_len(len, 2, "(cert_index, stake_credential)")?; + let desired_index = CertificateIndexNames::StakeRegistrationLegacy.to_u64(); + check_index(cert_index, desired_index, "cert_index")?; let stake_credential = StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; @@ -121,24 +97,9 @@ fn deserialize_conway( len: Len, ) -> Result { (|| -> Result<_, DeserializeError> { - if let Len::Len(n) = len { - if n != 3 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 3, - len, - "(cert_index, stake_credential, coin)", - )) - .into()); - } - } - - if cert_index != STAKE_REG_CONWAY_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(STAKE_REG_CONWAY_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } + check_len(len, 3, "(cert_index, stake_credential, coin)")?; + let desired_index = CertificateIndexNames::StakeRegistrationConway.to_u64(); + check_index(cert_index, desired_index, "cert_index")?; let stake_credential = StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; diff --git a/rust/src/serialization/certificates/stake_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_registration_and_delegation.rs index 315fa1bf..c4baeda1 100644 --- a/rust/src/serialization/certificates/stake_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/stake_registration_and_delegation.rs @@ -1,6 +1,7 @@ +use num_traits::ToPrimitive; use crate::*; - -pub(super) const STAKE_REG_DELEG_CERT_INDEX: u64 = 11; +use crate::serialization::map_names::CertificateIndexNames; +use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; impl cbor_event::se::Serialize for StakeRegistrationAndDelegation { fn serialize<'se, W: Write>( @@ -8,7 +9,10 @@ impl cbor_event::se::Serialize for StakeRegistrationAndDelegation { serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(4))?; - serializer.write_unsigned_integer(STAKE_REG_DELEG_CERT_INDEX)?; + + let proposal_index = CertificateIndexNames::StakeRegistrationAndDelegation.to_u64(); + serialize_and_check_index(serializer, proposal_index, "StakeRegistrationAndDelegation")?; + self.stake_credential.serialize(serializer)?; self.pool_keyhash.serialize(serializer)?; self.coin.serialize(serializer)?; @@ -16,49 +20,16 @@ impl cbor_event::se::Serialize for StakeRegistrationAndDelegation { } } -impl Deserialize for StakeRegistrationAndDelegation { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - - let cert = Self::deserialize_as_embedded_group(raw, len)?; - - if let cbor_event::Len::Indefinite = len { - if raw.special()? != CBORSpecial::Break { - return Err(DeserializeFailure::EndingBreakMissing.into()); - } - } - - Ok(cert) - })() - .map_err(|e| e.annotate("StakeRegistrationAndDelegation")) - } -} +impl_deserialize_for_tuple!(StakeRegistrationAndDelegation); impl DeserializeEmbeddedGroup for StakeRegistrationAndDelegation { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - if let cbor_event::Len::Len(n) = len { - if n != 4 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 4, - len, - "(cert_index, stake_credential, pool_keyhash, coin)", - )) - .into()); - } - } - - let cert_index = raw.unsigned_integer()?; - if cert_index != STAKE_REG_DELEG_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(STAKE_REG_DELEG_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } + check_len(len, 4, "(cert_index, stake_credential, pool_keyhash, coin)")?; + let cert_index = CertificateIndexNames::StakeRegistrationAndDelegation.to_u64(); + deserialize_and_check_index(raw, cert_index, "cert_index")?; let stake_credential = StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; diff --git a/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs index 8dcb52e2..bab8f3a3 100644 --- a/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs @@ -1,6 +1,7 @@ +use num_traits::ToPrimitive; use crate::*; - -pub(super) const STAKE_VOTE_REG_DELEG_CERT_INDEX: u64 = 13; +use crate::serialization::map_names::CertificateIndexNames; +use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; impl cbor_event::se::Serialize for StakeVoteRegistrationAndDelegation { fn serialize<'se, W: Write>( @@ -8,7 +9,10 @@ impl cbor_event::se::Serialize for StakeVoteRegistrationAndDelegation { serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(5))?; - serializer.write_unsigned_integer(STAKE_VOTE_REG_DELEG_CERT_INDEX)?; + + let proposal_index = CertificateIndexNames::StakeVoteRegistrationAndDelegation.to_u64(); + serialize_and_check_index(serializer, proposal_index, "StakeVoteRegistrationAndDelegation")?; + self.stake_credential.serialize(serializer)?; self.pool_keyhash.serialize(serializer)?; self.drep.serialize(serializer)?; @@ -17,49 +21,16 @@ impl cbor_event::se::Serialize for StakeVoteRegistrationAndDelegation { } } -impl Deserialize for StakeVoteRegistrationAndDelegation { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - - let cert = Self::deserialize_as_embedded_group(raw, len)?; - - if let cbor_event::Len::Indefinite = len { - if raw.special()? != CBORSpecial::Break { - return Err(DeserializeFailure::EndingBreakMissing.into()); - } - } - - Ok(cert) - })() - .map_err(|e| e.annotate("StakeVoteRegistrationAndDelegation")) - } -} +impl_deserialize_for_tuple!(StakeVoteRegistrationAndDelegation); impl DeserializeEmbeddedGroup for StakeVoteRegistrationAndDelegation { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - if let cbor_event::Len::Len(n) = len { - if n != 5 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 5, - len, - "(cert_index, stake_credential, pool_keyhash, drep, coin)", - )) - .into()); - } - } - - let cert_index = raw.unsigned_integer()?; - if cert_index != STAKE_VOTE_REG_DELEG_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(STAKE_VOTE_REG_DELEG_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } + check_len(len, 5, "(cert_index, stake_credential, pool_keyhash, drep, coin)")?; + let cert_index = CertificateIndexNames::StakeVoteRegistrationAndDelegation.to_u64(); + deserialize_and_check_index(raw, cert_index, "cert_index")?; let stake_credential = StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; diff --git a/rust/src/serialization/certificates/vote_delegation.rs b/rust/src/serialization/certificates/vote_delegation.rs index 57a82a61..3e9efd3d 100644 --- a/rust/src/serialization/certificates/vote_delegation.rs +++ b/rust/src/serialization/certificates/vote_delegation.rs @@ -1,6 +1,7 @@ +use num_traits::ToPrimitive; use crate::*; - -pub(super) const VOTE_CERT_INDEX: u64 = 9; +use crate::serialization::map_names::CertificateIndexNames; +use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; impl cbor_event::se::Serialize for VoteDelegation { fn serialize<'se, W: Write>( @@ -8,56 +9,26 @@ impl cbor_event::se::Serialize for VoteDelegation { serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(3))?; - serializer.write_unsigned_integer(VOTE_CERT_INDEX)?; + + let proposal_index = CertificateIndexNames::VoteDelegation.to_u64(); + serialize_and_check_index(serializer, proposal_index, "VoteDelegation")?; + self.stake_credential.serialize(serializer)?; self.drep.serialize(serializer)?; Ok(serializer) } } -impl Deserialize for VoteDelegation { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - - let cert = Self::deserialize_as_embedded_group(raw, len)?; - - if let cbor_event::Len::Indefinite = len { - if raw.special()? != CBORSpecial::Break { - return Err(DeserializeFailure::EndingBreakMissing.into()); - } - } - - Ok(cert) - })() - .map_err(|e| e.annotate("VoteDelegation")) - } -} +impl_deserialize_for_tuple!(VoteDelegation); impl DeserializeEmbeddedGroup for VoteDelegation { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - if let cbor_event::Len::Len(n) = len { - if n != 3 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 3, - len, - "(cert_index, stake_credential, drep)", - )) - .into()); - } - } - - let cert_index = raw.unsigned_integer()?; - if cert_index != VOTE_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(VOTE_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } + check_len(len, 3, "(cert_index, stake_credential, drep)")?; + let cert_index = CertificateIndexNames::VoteDelegation.to_u64(); + deserialize_and_check_index(raw, cert_index, "cert_index")?; let stake_credential = StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; diff --git a/rust/src/serialization/certificates/vote_registration_and_delegation.rs b/rust/src/serialization/certificates/vote_registration_and_delegation.rs index 727ae30e..f120fbb5 100644 --- a/rust/src/serialization/certificates/vote_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/vote_registration_and_delegation.rs @@ -1,6 +1,7 @@ +use crate::serialization::map_names::CertificateIndexNames; +use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; use crate::*; - -pub(super) const VOTE_REG_DELEG_CERT_INDEX: u64 = 12; +use num_traits::ToPrimitive; impl cbor_event::se::Serialize for VoteRegistrationAndDelegation { fn serialize<'se, W: Write>( @@ -8,7 +9,10 @@ impl cbor_event::se::Serialize for VoteRegistrationAndDelegation { serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(4))?; - serializer.write_unsigned_integer(VOTE_REG_DELEG_CERT_INDEX)?; + + let proposal_index = CertificateIndexNames::VoteRegistrationAndDelegation.to_u64(); + serialize_and_check_index(serializer, proposal_index, "VoteRegistrationAndDelegation")?; + self.stake_credential.serialize(serializer)?; self.drep.serialize(serializer)?; self.coin.serialize(serializer)?; @@ -16,49 +20,17 @@ impl cbor_event::se::Serialize for VoteRegistrationAndDelegation { } } -impl Deserialize for VoteRegistrationAndDelegation { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - - let cert = Self::deserialize_as_embedded_group(raw, len)?; - - if let cbor_event::Len::Indefinite = len { - if raw.special()? != CBORSpecial::Break { - return Err(DeserializeFailure::EndingBreakMissing.into()); - } - } - - Ok(cert) - })() - .map_err(|e| e.annotate("VoteRegistrationAndDelegation")) - } -} +impl_deserialize_for_tuple!(VoteRegistrationAndDelegation); impl DeserializeEmbeddedGroup for VoteRegistrationAndDelegation { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - if let cbor_event::Len::Len(n) = len { - if n != 4 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 4, - len, - "(cert_index, stake_credential, drep, coin)", - )) - .into()); - } - } + check_len(len, 4, "(cert_index, stake_credential, drep, coin)")?; - let cert_index = raw.unsigned_integer()?; - if cert_index != VOTE_REG_DELEG_CERT_INDEX { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(cert_index), - expected: Key::Uint(VOTE_REG_DELEG_CERT_INDEX), - }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")); - } + let desired_index = CertificateIndexNames::VoteRegistrationAndDelegation.to_u64(); + deserialize_and_check_index(raw, desired_index, "cert_index")?; let stake_credential = StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; From d1e131def56a8eda0b2ed68ca94eea0c05d1fdef Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 18 Aug 2023 00:19:01 +0400 Subject: [PATCH 058/349] extend errors --- rust/src/error.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rust/src/error.rs b/rust/src/error.rs index 392956ac..79dc9917 100644 --- a/rust/src/error.rs +++ b/rust/src/error.rs @@ -9,6 +9,7 @@ use cbor_event::{self}; pub enum Key { Str(String), Uint(u64), + OptUint(Option), } impl std::fmt::Display for Key { @@ -16,6 +17,8 @@ impl std::fmt::Display for Key { match self { Key::Str(x) => write!(f, "\"{}\"", x), Key::Uint(x) => write!(f, "{}", x), + Key::OptUint(Some(x)) => write!(f, "{}", x), + Key::OptUint(None) => write!(f, "null"), } } } @@ -56,6 +59,7 @@ pub enum DeserializeFailure { UnexpectedKeyType(cbor_event::Type), VariableLenNatDecodeFailed, IoError(String), + CustomError(String), } #[derive(Debug)] @@ -135,6 +139,7 @@ impl std::fmt::Display for DeserializeError { write!(f, "Variable length natural number decode failed") } DeserializeFailure::IoError(e) => write!(f, "IO error: {}", e), + DeserializeFailure::CustomError(e) => write!(f, "Deserialize error: {}", e), } } } From 6c1e39726f6824d37729b470ad05f596073765db Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 18 Aug 2023 00:19:22 +0400 Subject: [PATCH 059/349] remove moved code from utils --- rust/src/utils.rs | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/rust/src/utils.rs b/rust/src/utils.rs index 81df8518..dc94bd9c 100644 --- a/rust/src/utils.rs +++ b/rust/src/utils.rs @@ -1118,39 +1118,7 @@ impl From for BigInt } } -// we use the cbor_event::Serialize trait directly -// This is only for use for plain cddl groups who need to be embedded within outer groups. -pub(crate) trait SerializeEmbeddedGroup { - fn serialize_as_embedded_group<'a, W: Write + Sized>( - &self, - serializer: &'a mut Serializer, - ) -> cbor_event::Result<&'a mut Serializer>; -} - -// same as cbor_event::de::Deserialize but with our DeserializeError -pub trait Deserialize { - fn deserialize(raw: &mut Deserializer) -> Result - where - Self: Sized; -} - -// auto-implement for all cbor_event Deserialize implementors -impl Deserialize for T { - fn deserialize(raw: &mut Deserializer) -> Result { - T::deserialize(raw).map_err(|e| DeserializeError::from(e)) - } -} - -// This is only for use for plain cddl groups who need to be embedded within outer groups. -pub trait DeserializeEmbeddedGroup { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - len: cbor_event::Len, - ) -> Result - where - Self: Sized; -} pub struct CBORReadLen { deser_len: cbor_event::Len, From e624c37371f96d603df52c435da3d8a6477ac9b3 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 18 Aug 2023 00:20:03 +0400 Subject: [PATCH 060/349] update batch builder after index name moving --- rust/src/tx_builder/batch_tools/cbor_calculator.rs | 7 ++++--- rust/src/tx_builder/batch_tools/proposals.rs | 2 +- rust/src/tx_builder/batch_tools/witnesses_calculator.rs | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/rust/src/tx_builder/batch_tools/cbor_calculator.rs b/rust/src/tx_builder/batch_tools/cbor_calculator.rs index 841a2c80..d97b83af 100644 --- a/rust/src/tx_builder/batch_tools/cbor_calculator.rs +++ b/rust/src/tx_builder/batch_tools/cbor_calculator.rs @@ -1,5 +1,6 @@ +use num_traits::ToPrimitive; use crate::fees::{LinearFee, min_fee_for_size}; -use crate::serialization_tools::map_names::{TxBodyNames, WitnessSetNames}; +use crate::serialization::map_names::{TxBodyNames, WitnessSetNames}; use super::super::*; pub(super) struct CborCalculator(); @@ -69,7 +70,7 @@ impl CborCalculator { pub(super) fn get_bare_tx_body_size(body_fields: &HashSet) -> usize { let mut size = CborCalculator::get_struct_size(body_fields.len() as u64); for field in body_fields { - size += CborCalculator::get_struct_size(field.to_number()); + size += CborCalculator::get_struct_size(field.to_u64().unwrap()); } size } @@ -77,7 +78,7 @@ impl CborCalculator { pub(super) fn get_wintnesses_set_struct_size(witnesses_fields: &HashSet) -> usize { let mut size = CborCalculator::get_struct_size(witnesses_fields.len() as u64); for field in witnesses_fields { - size += CborCalculator::get_struct_size(field.to_number()); + size += CborCalculator::get_struct_size(field.to_u64().unwrap()); } size } diff --git a/rust/src/tx_builder/batch_tools/proposals.rs b/rust/src/tx_builder/batch_tools/proposals.rs index f711805d..26eb3710 100644 --- a/rust/src/tx_builder/batch_tools/proposals.rs +++ b/rust/src/tx_builder/batch_tools/proposals.rs @@ -1,5 +1,5 @@ use std::collections::HashMap; -use crate::serialization_tools::map_names::TxBodyNames; +use crate::serialization::map_names::TxBodyNames; use super::super::*; use super::indexes::{UtxoIndex, AssetIndex, PolicyIndex}; use super::asset_categorizer::AssetCategorizer; diff --git a/rust/src/tx_builder/batch_tools/witnesses_calculator.rs b/rust/src/tx_builder/batch_tools/witnesses_calculator.rs index 550412ad..b545bdcb 100644 --- a/rust/src/tx_builder/batch_tools/witnesses_calculator.rs +++ b/rust/src/tx_builder/batch_tools/witnesses_calculator.rs @@ -1,4 +1,4 @@ -use crate::serialization_tools::map_names::WitnessSetNames; +use crate::serialization::map_names::WitnessSetNames; use crate::tx_builder::batch_tools::cbor_calculator::CborCalculator; use super::super::*; From 41495cbc86f700fcd41cb61558b60a7966f31b01 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 18 Aug 2023 00:32:11 +0400 Subject: [PATCH 061/349] run fmt --- .../serialization/certificates/certificate.rs | 4 ++-- .../committee_hot_key_deregistration.rs | 10 +++++----- .../committee_hot_key_registration.rs | 15 +++++++++----- .../certificates/drep_deregistration.rs | 8 +++++--- .../certificates/drep_registration.rs | 14 +++++++++---- .../serialization/certificates/drep_update.rs | 8 +++++--- .../certificates/genesis_key_delegation.rs | 16 +++++++++------ rust/src/serialization/certificates/mod.rs | 14 ++++++------- .../move_instantaneous_rewards_cert.rs | 10 +++++----- .../certificates/pool_registration.rs | 5 +++-- .../certificates/pool_retirement.rs | 9 +++++---- .../certificates/stake_and_vote_delegation.rs | 8 +++++--- .../certificates/stake_delegation.rs | 10 +++++----- .../certificates/stake_deregistration.rs | 4 +--- .../certificates/stake_registration.rs | 14 ++++++++----- .../stake_registration_and_delegation.rs | 8 +++++--- .../stake_vote_registration_and_delegation.rs | 20 ++++++++++++++----- .../certificates/vote_delegation.rs | 8 +++++--- .../vote_registration_and_delegation.rs | 4 +++- 19 files changed, 115 insertions(+), 74 deletions(-) diff --git a/rust/src/serialization/certificates/certificate.rs b/rust/src/serialization/certificates/certificate.rs index bec1984b..94cc2d99 100644 --- a/rust/src/serialization/certificates/certificate.rs +++ b/rust/src/serialization/certificates/certificate.rs @@ -65,8 +65,8 @@ impl DeserializeEmbeddedGroup for CertificateEnum { let index_enum = CertificateIndexNames::from_u64(cert_index).ok_or(DeserializeError::new( "CertificateEnum", - DeserializeFailure::UnknownKey(Key::Uint(cert_index), - )))?; + DeserializeFailure::UnknownKey(Key::Uint(cert_index)), + ))?; match index_enum { CertificateIndexNames::StakeRegistrationLegacy => { diff --git a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs index 4ddba355..3f77ad56 100644 --- a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs @@ -1,7 +1,9 @@ -use num_traits::ToPrimitive; -use crate::*; use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; +use crate::serialization::struct_checks::{ + check_len, deserialize_and_check_index, serialize_and_check_index, +}; +use crate::*; +use num_traits::ToPrimitive; impl cbor_event::se::Serialize for CommitteeHotKeyDeregistration { fn serialize<'se, W: Write>( @@ -24,13 +26,11 @@ impl DeserializeEmbeddedGroup for CommitteeHotKeyDeregistration { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - check_len(len, 2, "(cert_index, committee_cold_key)")?; let cert_index = CertificateIndexNames::CommitteeHotKeyDeregistration.to_u64(); deserialize_and_check_index(raw, cert_index, "cert_index")?; - let committee_cold_key = StakeCredential::deserialize(raw).map_err(|e| e.annotate("committee_cold_key"))?; diff --git a/rust/src/serialization/certificates/committee_hot_key_registration.rs b/rust/src/serialization/certificates/committee_hot_key_registration.rs index 8118743f..a9f921f0 100644 --- a/rust/src/serialization/certificates/committee_hot_key_registration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_registration.rs @@ -1,7 +1,9 @@ -use num_traits::ToPrimitive; -use crate::*; use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; +use crate::serialization::struct_checks::{ + check_len, deserialize_and_check_index, serialize_and_check_index, +}; +use crate::*; +use num_traits::ToPrimitive; impl cbor_event::se::Serialize for CommitteeHotKeyRegistration { fn serialize<'se, W: Write>( @@ -26,8 +28,11 @@ impl DeserializeEmbeddedGroup for CommitteeHotKeyRegistration { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - - check_len(len, 3, "(cert_index, committee_cold_key, committee_hot_key)")?; + check_len( + len, + 3, + "(cert_index, committee_cold_key, committee_hot_key)", + )?; let cert_index = CertificateIndexNames::CommitteeHotKeyRegistration.to_u64(); deserialize_and_check_index(raw, cert_index, "cert_index")?; diff --git a/rust/src/serialization/certificates/drep_deregistration.rs b/rust/src/serialization/certificates/drep_deregistration.rs index 05aa2b19..d9eee988 100644 --- a/rust/src/serialization/certificates/drep_deregistration.rs +++ b/rust/src/serialization/certificates/drep_deregistration.rs @@ -1,7 +1,9 @@ -use num_traits::ToPrimitive; -use crate::*; use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; +use crate::serialization::struct_checks::{ + check_len, deserialize_and_check_index, serialize_and_check_index, +}; +use crate::*; +use num_traits::ToPrimitive; impl cbor_event::se::Serialize for DrepDeregistration { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/drep_registration.rs b/rust/src/serialization/certificates/drep_registration.rs index 54a3de74..563bac37 100644 --- a/rust/src/serialization/certificates/drep_registration.rs +++ b/rust/src/serialization/certificates/drep_registration.rs @@ -1,7 +1,9 @@ -use num_traits::ToPrimitive; -use crate::*; use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; +use crate::serialization::struct_checks::{ + check_len, deserialize_and_check_index, serialize_and_check_index, +}; +use crate::*; +use num_traits::ToPrimitive; impl cbor_event::se::Serialize for DrepRegistration { fn serialize<'se, W: Write>( @@ -30,7 +32,11 @@ impl DeserializeEmbeddedGroup for DrepRegistration { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - check_len(len, 4, "(cert_index, voting_credential, coin, anchor / null)")?; + check_len( + len, + 4, + "(cert_index, voting_credential, coin, anchor / null)", + )?; let cert_index = CertificateIndexNames::DrepRegistration.to_u64(); deserialize_and_check_index(raw, cert_index, "cert_index")?; diff --git a/rust/src/serialization/certificates/drep_update.rs b/rust/src/serialization/certificates/drep_update.rs index 42bd2895..c9cec21e 100644 --- a/rust/src/serialization/certificates/drep_update.rs +++ b/rust/src/serialization/certificates/drep_update.rs @@ -1,7 +1,9 @@ -use num_traits::ToPrimitive; -use crate::*; use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; +use crate::serialization::struct_checks::{ + check_len, deserialize_and_check_index, serialize_and_check_index, +}; +use crate::*; +use num_traits::ToPrimitive; impl cbor_event::se::Serialize for DrepUpdate { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/genesis_key_delegation.rs b/rust/src/serialization/certificates/genesis_key_delegation.rs index 6f7691fe..b27b8598 100644 --- a/rust/src/serialization/certificates/genesis_key_delegation.rs +++ b/rust/src/serialization/certificates/genesis_key_delegation.rs @@ -1,7 +1,9 @@ -use num_traits::ToPrimitive; -use crate::*; use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; +use crate::serialization::struct_checks::{ + check_len, deserialize_and_check_index, serialize_and_check_index, +}; +use crate::*; +use num_traits::ToPrimitive; impl cbor_event::se::Serialize for GenesisKeyDelegation { fn serialize<'se, W: Write>( @@ -18,7 +20,6 @@ impl SerializeEmbeddedGroup for GenesisKeyDelegation { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - let proposal_index = CertificateIndexNames::GenesisKeyDelegation.to_u64(); serialize_and_check_index(serializer, proposal_index, "GenesisKeyDelegation")?; @@ -36,8 +37,11 @@ impl DeserializeEmbeddedGroup for GenesisKeyDelegation { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - - check_len(len, 4, "(cert_index, genesishash, genesis_delegate_hash, vrf_keyhash)")?; + check_len( + len, + 4, + "(cert_index, genesishash, genesis_delegate_hash, vrf_keyhash)", + )?; let cert_index = CertificateIndexNames::GenesisKeyDelegation.to_u64(); deserialize_and_check_index(raw, cert_index, "cert_index")?; diff --git a/rust/src/serialization/certificates/mod.rs b/rust/src/serialization/certificates/mod.rs index 6544629c..c5814548 100644 --- a/rust/src/serialization/certificates/mod.rs +++ b/rust/src/serialization/certificates/mod.rs @@ -5,18 +5,18 @@ mod genesis_key_delegation; mod move_instantaneous_rewards_cert; +mod committee_hot_key_deregistration; +mod committee_hot_key_registration; +mod drep_deregistration; +mod drep_registration; +mod drep_update; mod pool_registration; mod pool_retirement; +mod stake_and_vote_delegation; mod stake_delegation; mod stake_deregistration; mod stake_registration; -mod vote_delegation; -mod stake_and_vote_delegation; mod stake_registration_and_delegation; mod stake_vote_registration_and_delegation; +mod vote_delegation; mod vote_registration_and_delegation; -mod committee_hot_key_registration; -mod committee_hot_key_deregistration; -mod drep_registration; -mod drep_deregistration; -mod drep_update; \ No newline at end of file diff --git a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs index cd6317e0..a5c2dc17 100644 --- a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs +++ b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs @@ -1,7 +1,9 @@ -use num_traits::ToPrimitive; -use crate::*; use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; +use crate::serialization::struct_checks::{ + check_len, deserialize_and_check_index, serialize_and_check_index, +}; +use crate::*; +use num_traits::ToPrimitive; impl cbor_event::se::Serialize for MIRToStakeCredentials { fn serialize<'se, W: Write>( @@ -120,7 +122,6 @@ impl SerializeEmbeddedGroup for MoveInstantaneousRewardsCert { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - let proposal_index = CertificateIndexNames::MoveInstantaneousRewardsCert.to_u64(); serialize_and_check_index(serializer, proposal_index, "MoveInstantaneousRewardsCert")?; @@ -136,7 +137,6 @@ impl DeserializeEmbeddedGroup for MoveInstantaneousRewardsCert { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - check_len(len, 2, "(cert_index, move_instantaneous_reward)")?; let cert_index = CertificateIndexNames::MoveInstantaneousRewardsCert.to_u64(); diff --git a/rust/src/serialization/certificates/pool_registration.rs b/rust/src/serialization/certificates/pool_registration.rs index b1261de8..407c95dc 100644 --- a/rust/src/serialization/certificates/pool_registration.rs +++ b/rust/src/serialization/certificates/pool_registration.rs @@ -1,5 +1,7 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; +use crate::serialization::struct_checks::{ + check_len, deserialize_and_check_index, serialize_and_check_index, +}; use crate::*; use num_traits::ToPrimitive; @@ -152,7 +154,6 @@ impl DeserializeEmbeddedGroup for PoolRegistration { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - check_len(len, 2, "(cert_index, pool_params)")?; let cert_index = CertificateIndexNames::PoolRegistration.to_u64(); diff --git a/rust/src/serialization/certificates/pool_retirement.rs b/rust/src/serialization/certificates/pool_retirement.rs index 75d40d29..effca1da 100644 --- a/rust/src/serialization/certificates/pool_retirement.rs +++ b/rust/src/serialization/certificates/pool_retirement.rs @@ -1,7 +1,9 @@ -use num_traits::ToPrimitive; -use crate::*; use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; +use crate::serialization::struct_checks::{ + check_len, deserialize_and_check_index, serialize_and_check_index, +}; +use crate::*; +use num_traits::ToPrimitive; impl cbor_event::se::Serialize for PoolRetirement { fn serialize<'se, W: Write>( @@ -18,7 +20,6 @@ impl SerializeEmbeddedGroup for PoolRetirement { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - let proposal_index = CertificateIndexNames::PoolRetirement.to_u64(); serialize_and_check_index(serializer, proposal_index, "PoolRetirement")?; diff --git a/rust/src/serialization/certificates/stake_and_vote_delegation.rs b/rust/src/serialization/certificates/stake_and_vote_delegation.rs index ffd8071c..fa7dd3ab 100644 --- a/rust/src/serialization/certificates/stake_and_vote_delegation.rs +++ b/rust/src/serialization/certificates/stake_and_vote_delegation.rs @@ -1,7 +1,9 @@ -use num_traits::ToPrimitive; -use crate::*; use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; +use crate::serialization::struct_checks::{ + check_len, deserialize_and_check_index, serialize_and_check_index, +}; +use crate::*; +use num_traits::ToPrimitive; impl cbor_event::se::Serialize for StakeAndVoteDelegation { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/stake_delegation.rs b/rust/src/serialization/certificates/stake_delegation.rs index 7a9bb3ff..bea77b56 100644 --- a/rust/src/serialization/certificates/stake_delegation.rs +++ b/rust/src/serialization/certificates/stake_delegation.rs @@ -1,7 +1,9 @@ -use num_traits::ToPrimitive; -use crate::*; use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; +use crate::serialization::struct_checks::{ + check_len, deserialize_and_check_index, serialize_and_check_index, +}; +use crate::*; +use num_traits::ToPrimitive; impl cbor_event::se::Serialize for StakeDelegation { fn serialize<'se, W: Write>( @@ -18,7 +20,6 @@ impl SerializeEmbeddedGroup for StakeDelegation { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - let proposal_index = CertificateIndexNames::StakeDelegation.to_u64(); serialize_and_check_index(serializer, proposal_index, "StakeDelegation")?; @@ -35,7 +36,6 @@ impl DeserializeEmbeddedGroup for StakeDelegation { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - check_len(len, 3, "(cert_index, stake_credential, pool_keyhash)")?; let cert_index = CertificateIndexNames::StakeDelegation.to_u64(); deserialize_and_check_index(raw, cert_index, "cert_index")?; diff --git a/rust/src/serialization/certificates/stake_deregistration.rs b/rust/src/serialization/certificates/stake_deregistration.rs index 54f2eeef..404ab8e4 100644 --- a/rust/src/serialization/certificates/stake_deregistration.rs +++ b/rust/src/serialization/certificates/stake_deregistration.rs @@ -1,7 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{ - check_index, check_len, serialize_and_check_index, -}; +use crate::serialization::struct_checks::{check_index, check_len, serialize_and_check_index}; use crate::*; use cbor_event::Len; use num_traits::{FromPrimitive, ToPrimitive}; diff --git a/rust/src/serialization/certificates/stake_registration.rs b/rust/src/serialization/certificates/stake_registration.rs index 45d40d73..2e4ce59c 100644 --- a/rust/src/serialization/certificates/stake_registration.rs +++ b/rust/src/serialization/certificates/stake_registration.rs @@ -1,8 +1,8 @@ +use crate::serialization::map_names::CertificateIndexNames; +use crate::serialization::struct_checks::{check_index, check_len, serialize_and_check_index}; use crate::*; use cbor_event::Len; use num_traits::{FromPrimitive, ToPrimitive}; -use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{check_index, check_len, serialize_and_check_index}; impl cbor_event::se::Serialize for StakeRegistration { fn serialize<'se, W: Write>( @@ -56,8 +56,12 @@ impl DeserializeEmbeddedGroup for StakeRegistration { let cert_index = raw.unsigned_integer()?; let index_enum = CertificateIndexNames::from_u64(cert_index); match index_enum { - Some(CertificateIndexNames::StakeRegistrationLegacy) => deserialize_legacy(raw, cert_index, len), - Some(CertificateIndexNames::StakeRegistrationConway) => deserialize_conway(raw, cert_index, len), + Some(CertificateIndexNames::StakeRegistrationLegacy) => { + deserialize_legacy(raw, cert_index, len) + } + Some(CertificateIndexNames::StakeRegistrationConway) => { + deserialize_conway(raw, cert_index, len) + } _ => Err(DeserializeFailure::FixedValuesMismatch { found: Key::Uint(cert_index), expected: vec![ @@ -65,7 +69,7 @@ impl DeserializeEmbeddedGroup for StakeRegistration { Key::OptUint(CertificateIndexNames::StakeRegistrationConway.to_u64()), ], }) - .map_err(|e| DeserializeError::from(e).annotate("cert_index")), + .map_err(|e| DeserializeError::from(e).annotate("cert_index")), } } } diff --git a/rust/src/serialization/certificates/stake_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_registration_and_delegation.rs index c4baeda1..1424d28d 100644 --- a/rust/src/serialization/certificates/stake_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/stake_registration_and_delegation.rs @@ -1,7 +1,9 @@ -use num_traits::ToPrimitive; -use crate::*; use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; +use crate::serialization::struct_checks::{ + check_len, deserialize_and_check_index, serialize_and_check_index, +}; +use crate::*; +use num_traits::ToPrimitive; impl cbor_event::se::Serialize for StakeRegistrationAndDelegation { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs index bab8f3a3..6fd1b891 100644 --- a/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs @@ -1,7 +1,9 @@ -use num_traits::ToPrimitive; -use crate::*; use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; +use crate::serialization::struct_checks::{ + check_len, deserialize_and_check_index, serialize_and_check_index, +}; +use crate::*; +use num_traits::ToPrimitive; impl cbor_event::se::Serialize for StakeVoteRegistrationAndDelegation { fn serialize<'se, W: Write>( @@ -11,7 +13,11 @@ impl cbor_event::se::Serialize for StakeVoteRegistrationAndDelegation { serializer.write_array(cbor_event::Len::Len(5))?; let proposal_index = CertificateIndexNames::StakeVoteRegistrationAndDelegation.to_u64(); - serialize_and_check_index(serializer, proposal_index, "StakeVoteRegistrationAndDelegation")?; + serialize_and_check_index( + serializer, + proposal_index, + "StakeVoteRegistrationAndDelegation", + )?; self.stake_credential.serialize(serializer)?; self.pool_keyhash.serialize(serializer)?; @@ -28,7 +34,11 @@ impl DeserializeEmbeddedGroup for StakeVoteRegistrationAndDelegation { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - check_len(len, 5, "(cert_index, stake_credential, pool_keyhash, drep, coin)")?; + check_len( + len, + 5, + "(cert_index, stake_credential, pool_keyhash, drep, coin)", + )?; let cert_index = CertificateIndexNames::StakeVoteRegistrationAndDelegation.to_u64(); deserialize_and_check_index(raw, cert_index, "cert_index")?; diff --git a/rust/src/serialization/certificates/vote_delegation.rs b/rust/src/serialization/certificates/vote_delegation.rs index 3e9efd3d..e2fbf482 100644 --- a/rust/src/serialization/certificates/vote_delegation.rs +++ b/rust/src/serialization/certificates/vote_delegation.rs @@ -1,7 +1,9 @@ -use num_traits::ToPrimitive; -use crate::*; use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; +use crate::serialization::struct_checks::{ + check_len, deserialize_and_check_index, serialize_and_check_index, +}; +use crate::*; +use num_traits::ToPrimitive; impl cbor_event::se::Serialize for VoteDelegation { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/certificates/vote_registration_and_delegation.rs b/rust/src/serialization/certificates/vote_registration_and_delegation.rs index f120fbb5..d5360491 100644 --- a/rust/src/serialization/certificates/vote_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/vote_registration_and_delegation.rs @@ -1,5 +1,7 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{check_len, deserialize_and_check_index, serialize_and_check_index}; +use crate::serialization::struct_checks::{ + check_len, deserialize_and_check_index, serialize_and_check_index, +}; use crate::*; use num_traits::ToPrimitive; From e0b187e67634d07c55aadb51090d5dffddabb6b1 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 18 Aug 2023 00:34:38 +0400 Subject: [PATCH 062/349] optional anchor in votin procedure --- .../governance/voting_procedure.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/rust/src/protocol_types/governance/voting_procedure.rs b/rust/src/protocol_types/governance/voting_procedure.rs index 1d55a1fc..1d33c346 100644 --- a/rust/src/protocol_types/governance/voting_procedure.rs +++ b/rust/src/protocol_types/governance/voting_procedure.rs @@ -34,17 +34,24 @@ pub enum VoteKind { #[wasm_bindgen] pub struct VotingProcedure { pub(crate) vote: VoteKind, - pub(crate) anchor: Anchor, + pub(crate) anchor: Option, } impl_to_from!(VotingProcedure); #[wasm_bindgen] impl VotingProcedure { - pub fn new(vote: VoteKind, anchor: &Anchor) -> Self { + pub fn new(vote: &VoteKind) -> Self { Self { - vote, - anchor: anchor.clone(), + vote: vote.clone(), + anchor: None, + } + } + + pub fn new_with_anchor(vote: &VoteKind, anchor: &Anchor) -> Self { + Self { + vote: vote.clone(), + anchor: Some(anchor.clone()), } } @@ -52,7 +59,7 @@ impl VotingProcedure { self.vote.clone() } - pub fn anchor(&self) -> Anchor { + pub fn anchor(&self) -> Option { self.anchor.clone() } } From 32adf02c1c9c5524d5e8b8f14d439c59f0994c25 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 18 Aug 2023 00:34:55 +0400 Subject: [PATCH 063/349] add voting proposal types --- rust/src/protocol_types/governance/mod.rs | 5 +- .../governance/proposals/committee.rs | 49 ++++++++++++++++++ .../governance/proposals/constitution.rs | 46 +++++++++++++++++ .../hard_fork_initiation_proposal.rs | 40 +++++++++++++++ .../governance/proposals/info_proposal.rs | 14 ++++++ .../governance/proposals/mod.rs | 29 +++++++++++ .../proposals/new_committee_proposal.rs | 50 +++++++++++++++++++ .../proposals/new_constitution_proposal.rs | 46 +++++++++++++++++ .../proposals/no_confidence_proposal.rs | 18 +++++++ .../proposals/parameter_change_proposal.rs | 40 +++++++++++++++ .../proposals/treasury_withdrawals.rs | 42 ++++++++++++++++ .../treasury_withdrawals_proposal.rs | 33 ++++++++++++ 12 files changed, 411 insertions(+), 1 deletion(-) create mode 100644 rust/src/protocol_types/governance/proposals/committee.rs create mode 100644 rust/src/protocol_types/governance/proposals/constitution.rs create mode 100644 rust/src/protocol_types/governance/proposals/hard_fork_initiation_proposal.rs create mode 100644 rust/src/protocol_types/governance/proposals/info_proposal.rs create mode 100644 rust/src/protocol_types/governance/proposals/mod.rs create mode 100644 rust/src/protocol_types/governance/proposals/new_committee_proposal.rs create mode 100644 rust/src/protocol_types/governance/proposals/new_constitution_proposal.rs create mode 100644 rust/src/protocol_types/governance/proposals/no_confidence_proposal.rs create mode 100644 rust/src/protocol_types/governance/proposals/parameter_change_proposal.rs create mode 100644 rust/src/protocol_types/governance/proposals/treasury_withdrawals.rs create mode 100644 rust/src/protocol_types/governance/proposals/treasury_withdrawals_proposal.rs diff --git a/rust/src/protocol_types/governance/mod.rs b/rust/src/protocol_types/governance/mod.rs index 19be23a6..b0ffbabf 100644 --- a/rust/src/protocol_types/governance/mod.rs +++ b/rust/src/protocol_types/governance/mod.rs @@ -20,4 +20,7 @@ mod governance_action_id; pub use governance_action_id::*; mod governance_action_ids; -pub use governance_action_ids::*; \ No newline at end of file +pub use governance_action_ids::*; + +mod proposals; +pub use proposals::*; diff --git a/rust/src/protocol_types/governance/proposals/committee.rs b/rust/src/protocol_types/governance/proposals/committee.rs new file mode 100644 index 00000000..a2cf6e49 --- /dev/null +++ b/rust/src/protocol_types/governance/proposals/committee.rs @@ -0,0 +1,49 @@ +use crate::*; +use std::collections::BTreeMap; + +#[derive( + Clone, + Debug, + Eq, + Ord, + PartialEq, + PartialOrd, + Hash, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct Committee { + pub(crate) members: BTreeMap, + pub(crate) quorum_threshold: UnitInterval, +} + +impl_to_from!(Committee); + +#[wasm_bindgen] +impl Committee { + pub fn new(quorum_threshold: &UnitInterval) -> Self { + Self { + members: BTreeMap::new(), + quorum_threshold: quorum_threshold.clone(), + } + } + + pub fn members_keys(&self) -> StakeCredentials { + StakeCredentials(self.members.keys().cloned().collect()) + } + + pub fn quorum_threshold(&self) -> UnitInterval { + self.quorum_threshold.clone() + } + + pub fn add_member(&mut self, committee_cold_credential: &StakeCredential, epoch: &Epoch) { + self.members + .insert(committee_cold_credential.clone(), epoch.clone()); + } + + pub fn get_member_epoch(&self, committee_cold_credential: &StakeCredential) -> Option { + self.members.get(committee_cold_credential).cloned() + } +} diff --git a/rust/src/protocol_types/governance/proposals/constitution.rs b/rust/src/protocol_types/governance/proposals/constitution.rs new file mode 100644 index 00000000..b273b4be --- /dev/null +++ b/rust/src/protocol_types/governance/proposals/constitution.rs @@ -0,0 +1,46 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Eq, + Ord, + PartialEq, + PartialOrd, + Hash, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct Constitution { + pub(crate) anchor: Anchor, + pub(crate) script_hash: Option, +} + +impl_to_from!(Constitution); + +#[wasm_bindgen] +impl Constitution { + pub fn anchor(&self) -> Anchor { + self.anchor.clone() + } + + pub fn script_hash(&self) -> Option { + self.script_hash.clone() + } + + pub fn new(anchor: &Anchor) -> Self { + Self { + anchor: anchor.clone(), + script_hash: None, + } + } + + pub fn new_with_script_hash(anchor: &Anchor, script_hash: &ScriptHash) -> Self { + Self { + anchor: anchor.clone(), + script_hash: Some(script_hash.clone()), + } + } +} diff --git a/rust/src/protocol_types/governance/proposals/hard_fork_initiation_proposal.rs b/rust/src/protocol_types/governance/proposals/hard_fork_initiation_proposal.rs new file mode 100644 index 00000000..0b3927bb --- /dev/null +++ b/rust/src/protocol_types/governance/proposals/hard_fork_initiation_proposal.rs @@ -0,0 +1,40 @@ +use crate::*; + +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +#[wasm_bindgen] +pub struct HardForkInitiationProposal { + pub(crate) gov_action_id: Option, + pub(crate) protocol_version: ProtocolVersion, +} + +impl_to_from!(HardForkInitiationProposal); + +#[wasm_bindgen] +impl HardForkInitiationProposal { + pub fn gov_action_id(&self) -> Option { + self.gov_action_id.clone() + } + + pub fn protocol_version(&self) -> ProtocolVersion { + self.protocol_version.clone() + } + + pub fn new(protocol_version: &ProtocolVersion) -> Self { + Self { + gov_action_id: None, + protocol_version: protocol_version.clone(), + } + } + + pub fn new_with_action_id( + gov_action_id: &GovernanceActionId, + protocol_version: &ProtocolVersion, + ) -> Self { + Self { + gov_action_id: Some(gov_action_id.clone()), + protocol_version: protocol_version.clone(), + } + } +} diff --git a/rust/src/protocol_types/governance/proposals/info_proposal.rs b/rust/src/protocol_types/governance/proposals/info_proposal.rs new file mode 100644 index 00000000..85baf836 --- /dev/null +++ b/rust/src/protocol_types/governance/proposals/info_proposal.rs @@ -0,0 +1,14 @@ +use crate::*; + +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +#[wasm_bindgen] +pub struct InfoProposal(); + +#[wasm_bindgen] +impl InfoProposal { + pub fn new() -> Self { + Self() + } +} diff --git a/rust/src/protocol_types/governance/proposals/mod.rs b/rust/src/protocol_types/governance/proposals/mod.rs new file mode 100644 index 00000000..375d66e0 --- /dev/null +++ b/rust/src/protocol_types/governance/proposals/mod.rs @@ -0,0 +1,29 @@ +mod parameter_change_proposal; +pub use parameter_change_proposal::*; + +mod hard_fork_initiation_proposal; +pub use hard_fork_initiation_proposal::*; + +mod treasury_withdrawals_proposal; +pub use treasury_withdrawals_proposal::*; + +mod treasury_withdrawals; +pub use treasury_withdrawals::*; + +mod no_confidence_proposal; +pub use no_confidence_proposal::*; + +mod committee; +pub use committee::*; + +mod new_committee_proposal; +pub use new_committee_proposal::*; + +mod constitution; +pub use constitution::*; + +mod new_constitution_proposal; +pub use new_constitution_proposal::*; + +mod info_proposal; +pub use info_proposal::*; diff --git a/rust/src/protocol_types/governance/proposals/new_committee_proposal.rs b/rust/src/protocol_types/governance/proposals/new_committee_proposal.rs new file mode 100644 index 00000000..2916ff11 --- /dev/null +++ b/rust/src/protocol_types/governance/proposals/new_committee_proposal.rs @@ -0,0 +1,50 @@ +use crate::*; + +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +#[wasm_bindgen] +pub struct NewCommitteeProposal { + pub(crate) gov_action_id: Option, + pub(crate) committee: Committee, + pub(crate) members_to_remove: BTreeSet, +} + +impl_to_from!(NewCommitteeProposal); + +#[wasm_bindgen] +impl NewCommitteeProposal { + pub fn gov_action_id(&self) -> Option { + self.gov_action_id.clone() + } + + pub fn committee(&self) -> Committee { + self.committee.clone() + } + + pub fn members_to_remove(&self) -> StakeCredentials { + StakeCredentials(self.members_to_remove.iter().cloned().collect()) + } + + pub fn new(committee: &Committee, members_to_remove: &StakeCredentials) -> Self { + let members_to_remove = members_to_remove.0.iter().cloned().collect(); + Self { + gov_action_id: None, + committee: committee.clone(), + members_to_remove, + } + } + + pub fn new_with_action_id( + gov_action_id: &GovernanceActionId, + committee: &Committee, + members_to_remove: &StakeCredentials, + ) -> Self { + let members_to_remove = members_to_remove.0.iter().cloned().collect(); + Self { + gov_action_id: Some(gov_action_id.clone()), + committee: committee.clone(), + members_to_remove, + } + } +} diff --git a/rust/src/protocol_types/governance/proposals/new_constitution_proposal.rs b/rust/src/protocol_types/governance/proposals/new_constitution_proposal.rs new file mode 100644 index 00000000..25866804 --- /dev/null +++ b/rust/src/protocol_types/governance/proposals/new_constitution_proposal.rs @@ -0,0 +1,46 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Eq, + Ord, + PartialEq, + PartialOrd, + Hash, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct NewConstitutionProposal { + pub(crate) gov_action_id: Option, + pub(crate) constitution: Constitution, +} + +impl NewConstitutionProposal { + pub fn gov_action_id(&self) -> Option { + self.gov_action_id.clone() + } + + pub fn constitution(&self) -> Constitution { + self.constitution.clone() + } + + pub fn new(constitution: &Constitution) -> Self { + Self { + gov_action_id: None, + constitution: constitution.clone(), + } + } + + pub fn new_with_action_id( + gov_action_id: &GovernanceActionId, + constitution: &Constitution, + ) -> Self { + Self { + gov_action_id: Some(gov_action_id.clone()), + constitution: constitution.clone(), + } + } +} diff --git a/rust/src/protocol_types/governance/proposals/no_confidence_proposal.rs b/rust/src/protocol_types/governance/proposals/no_confidence_proposal.rs new file mode 100644 index 00000000..efecd859 --- /dev/null +++ b/rust/src/protocol_types/governance/proposals/no_confidence_proposal.rs @@ -0,0 +1,18 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Eq, + Ord, + PartialEq, + PartialOrd, + Hash, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct NoConfidenceProposal { + pub(crate) gov_action_id: Option, +} diff --git a/rust/src/protocol_types/governance/proposals/parameter_change_proposal.rs b/rust/src/protocol_types/governance/proposals/parameter_change_proposal.rs new file mode 100644 index 00000000..7c5fc654 --- /dev/null +++ b/rust/src/protocol_types/governance/proposals/parameter_change_proposal.rs @@ -0,0 +1,40 @@ +use crate::*; + +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +#[wasm_bindgen] +pub struct ParameterChangeProposal { + pub(crate) gov_action_id: Option, + pub(crate) protocol_param_updates: ProtocolParamUpdate, +} + +impl_to_from!(ParameterChangeProposal); + +#[wasm_bindgen] +impl ParameterChangeProposal { + pub fn gov_action_id(&self) -> Option { + self.gov_action_id.clone() + } + + pub fn protocol_param_updates(&self) -> ProtocolParamUpdate { + self.protocol_param_updates.clone() + } + + pub fn new(protocol_param_updates: &ProtocolParamUpdate) -> Self { + Self { + gov_action_id: None, + protocol_param_updates: protocol_param_updates.clone(), + } + } + + pub fn new_with_action_id( + gov_action_id: &GovernanceActionId, + protocol_param_updates: &ProtocolParamUpdate, + ) -> Self { + Self { + gov_action_id: Some(gov_action_id.clone()), + protocol_param_updates: protocol_param_updates.clone(), + } + } +} diff --git a/rust/src/protocol_types/governance/proposals/treasury_withdrawals.rs b/rust/src/protocol_types/governance/proposals/treasury_withdrawals.rs new file mode 100644 index 00000000..04322057 --- /dev/null +++ b/rust/src/protocol_types/governance/proposals/treasury_withdrawals.rs @@ -0,0 +1,42 @@ +use crate::*; +use std::collections::BTreeMap; + +#[derive( + Clone, + Debug, + Eq, + Ord, + PartialEq, + PartialOrd, + Hash, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct TreasuryWithdrawals(pub(crate) BTreeMap); + +to_from_json!(TreasuryWithdrawals); + +#[wasm_bindgen] +impl TreasuryWithdrawals { + pub fn new() -> Self { + Self(BTreeMap::new()) + } + + pub fn get(&self, key: &RewardAddress) -> Option { + self.0.get(key).cloned() + } + + pub fn insert(&mut self, key: &RewardAddress, value: &Coin) { + self.0.insert(key.clone(), value.clone()); + } + + pub fn keys(&self) -> RewardAddresses { + RewardAddresses(self.0.keys().cloned().collect()) + } + + pub fn len(&self) -> usize { + self.0.len() + } +} diff --git a/rust/src/protocol_types/governance/proposals/treasury_withdrawals_proposal.rs b/rust/src/protocol_types/governance/proposals/treasury_withdrawals_proposal.rs new file mode 100644 index 00000000..11ab2233 --- /dev/null +++ b/rust/src/protocol_types/governance/proposals/treasury_withdrawals_proposal.rs @@ -0,0 +1,33 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Eq, + Ord, + PartialEq, + PartialOrd, + Hash, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct TreasuryWithdrawalsProposal { + pub(crate) withdrawals: TreasuryWithdrawals, +} + +impl_to_from!(TreasuryWithdrawalsProposal); + +#[wasm_bindgen] +impl TreasuryWithdrawalsProposal { + pub fn withdrawals(&self) -> TreasuryWithdrawals { + self.withdrawals.clone() + } + + pub fn new(withdrawals: TreasuryWithdrawals) -> Self { + Self { + withdrawals: withdrawals.clone(), + } + } +} From ae5687891773125b39919955cf13e4cf83bcf813 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 18 Aug 2023 00:35:40 +0400 Subject: [PATCH 064/349] add voting proposals serialization --- rust/src/serialization/governance/mod.rs | 5 +- .../governance/proposals/committee.rs | 55 +++++++++++++++ .../governance/proposals/constitution.rs | 32 +++++++++ .../hard_fork_initiation_proposal.rs | 69 +++++++++++++++++++ .../serialization/governance/proposals/mod.rs | 26 +++++++ .../proposals/new_committee_proposal.rs | 58 ++++++++++++++++ .../proposals/new_constitution_proposal.rs | 52 ++++++++++++++ .../proposals/no_confidence_proposal.rs | 40 +++++++++++ .../proposals/parameter_change_proposal.rs | 51 ++++++++++++++ .../proposals/treasury_withdrawals.rs | 45 ++++++++++++ .../treasury_withdrawals_proposal.rs | 39 +++++++++++ rust/src/serialization/mod.rs | 9 ++- 12 files changed, 479 insertions(+), 2 deletions(-) create mode 100644 rust/src/serialization/governance/proposals/committee.rs create mode 100644 rust/src/serialization/governance/proposals/constitution.rs create mode 100644 rust/src/serialization/governance/proposals/hard_fork_initiation_proposal.rs create mode 100644 rust/src/serialization/governance/proposals/mod.rs create mode 100644 rust/src/serialization/governance/proposals/new_committee_proposal.rs create mode 100644 rust/src/serialization/governance/proposals/new_constitution_proposal.rs create mode 100644 rust/src/serialization/governance/proposals/no_confidence_proposal.rs create mode 100644 rust/src/serialization/governance/proposals/parameter_change_proposal.rs create mode 100644 rust/src/serialization/governance/proposals/treasury_withdrawals.rs create mode 100644 rust/src/serialization/governance/proposals/treasury_withdrawals_proposal.rs diff --git a/rust/src/serialization/governance/mod.rs b/rust/src/serialization/governance/mod.rs index 42cf5277..c1c9c6b6 100644 --- a/rust/src/serialization/governance/mod.rs +++ b/rust/src/serialization/governance/mod.rs @@ -14,4 +14,7 @@ mod voting_procedures; pub use voting_procedures::*; mod governance_action_id; -pub use governance_action_id::*; \ No newline at end of file +pub use governance_action_id::*; + +mod proposals; +pub use proposals::*; \ No newline at end of file diff --git a/rust/src/serialization/governance/proposals/committee.rs b/rust/src/serialization/governance/proposals/committee.rs new file mode 100644 index 00000000..365ef8aa --- /dev/null +++ b/rust/src/serialization/governance/proposals/committee.rs @@ -0,0 +1,55 @@ +use crate::serialization::struct_checks::check_len; +use crate::*; +use std::collections::BTreeMap; + +impl Serialize for Committee { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.quorum_threshold.serialize(serializer)?; + serializer.write_map(cbor_event::Len::Len(self.members.len() as u64))?; + for (key, value) in &self.members { + key.serialize(serializer)?; + value.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl_deserialize_for_tuple!(Committee); + +impl DeserializeEmbeddedGroup for Committee { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + check_len(len, 2, "(quorum_threshold, members)")?; + let quorum_threshold = UnitInterval::deserialize(raw)?; + + let mut table = BTreeMap::new(); + let map_len = raw.map()?; + while match map_len { + cbor_event::Len::Len(n) => table.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + let key = StakeCredential::deserialize(raw)?; + let value = Epoch::deserialize(raw)?; + if table.insert(key.clone(), value).is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Str(String::from( + "some complicated/unsupported type", + ))) + .into()); + } + } + Ok(Committee { + quorum_threshold, + members: table, + }) + } +} diff --git a/rust/src/serialization/governance/proposals/constitution.rs b/rust/src/serialization/governance/proposals/constitution.rs new file mode 100644 index 00000000..52ec63d3 --- /dev/null +++ b/rust/src/serialization/governance/proposals/constitution.rs @@ -0,0 +1,32 @@ +use crate::serialization::struct_checks::check_len; +use crate::*; + +impl Serialize for Constitution { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.anchor.serialize(serializer)?; + self.script_hash.serialize_nullable(serializer)?; + Ok(serializer) + } +} + +impl_deserialize_for_tuple!(Constitution); + +impl DeserializeEmbeddedGroup for Constitution { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + check_len(len, 2, "(anchor, scripthash / null)")?; + let anchor = Anchor::deserialize(raw)?; + let script_hash = ScriptHash::deserialize_nullable(raw)?; + + Ok(Constitution { + anchor, + script_hash, + }) + } +} diff --git a/rust/src/serialization/governance/proposals/hard_fork_initiation_proposal.rs b/rust/src/serialization/governance/proposals/hard_fork_initiation_proposal.rs new file mode 100644 index 00000000..8435f782 --- /dev/null +++ b/rust/src/serialization/governance/proposals/hard_fork_initiation_proposal.rs @@ -0,0 +1,69 @@ +use crate::serialization::struct_checks::{check_len_indefinite, serialize_and_check_index}; +use crate::serialization::{check_len, deserialize_and_check_index}; +use crate::*; +use map_names::VotingProposalIndexNames; +use num_traits::ToPrimitive; + +impl cbor_event::se::Serialize for HardForkInitiationProposal { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(3))?; + + let proposal_index = VotingProposalIndexNames::HardForkInitiationAction.to_u64(); + serialize_and_check_index(serializer, proposal_index, "HardForkInitiationAction")?; + + if let Some(gov_id) = &self.gov_action_id { + gov_id.serialize(serializer)?; + } else { + serializer.write_special(CBORSpecial::Null)?; + } + + serializer.write_array(cbor_event::Len::Len(1))?; + self.protocol_version.serialize(serializer)?; + + Ok(serializer) + } +} + +impl_deserialize_for_tuple!(HardForkInitiationProposal); + +impl DeserializeEmbeddedGroup for HardForkInitiationProposal { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + check_len( + len, + 3, + "(proposal_index, gov_action_id // null, protocol_version)", + )?; + + let desired_index = VotingProposalIndexNames::HardForkInitiationAction.to_u64(); + deserialize_and_check_index(raw, desired_index, "proposal_index")?; + + let gov_action_id = GovernanceActionId::deserialize_nullable(raw) + .map_err(|e| e.annotate("gov_action_id"))?; + + let protocol_version = deserialize_embedded_protocol_version(raw)?; + + return Ok(HardForkInitiationProposal { + gov_action_id, + protocol_version, + }); + } +} + +fn deserialize_embedded_protocol_version( + raw: &mut Deserializer, +) -> Result { + let len = raw.array()?; + + check_len(len, 1, "(protocol_version)")?; + + let protocol_version = + ProtocolVersion::deserialize(raw).map_err(|e| e.annotate("protocol_version"))?; + check_len_indefinite(raw, len)?; + Ok(protocol_version) +} diff --git a/rust/src/serialization/governance/proposals/mod.rs b/rust/src/serialization/governance/proposals/mod.rs new file mode 100644 index 00000000..6f96c28c --- /dev/null +++ b/rust/src/serialization/governance/proposals/mod.rs @@ -0,0 +1,26 @@ +mod parameter_change_proposal; +pub use parameter_change_proposal::*; + +mod hard_fork_initiation_proposal; +pub use hard_fork_initiation_proposal::*; + +mod treasury_withdrawals_proposal; +pub use treasury_withdrawals_proposal::*; + +mod treasury_withdrawals; +pub use treasury_withdrawals::*; + +mod no_confidence_proposal; +pub use no_confidence_proposal::*; + +mod committee; +pub use committee::*; + +mod new_committee_proposal; +pub use new_committee_proposal::*; + +mod constitution; +pub use constitution::*; + +mod new_constitution_proposal; +pub use new_constitution_proposal::*; diff --git a/rust/src/serialization/governance/proposals/new_committee_proposal.rs b/rust/src/serialization/governance/proposals/new_committee_proposal.rs new file mode 100644 index 00000000..d0645c0c --- /dev/null +++ b/rust/src/serialization/governance/proposals/new_committee_proposal.rs @@ -0,0 +1,58 @@ +use crate::serialization::struct_checks::serialize_and_check_index; +use crate::serialization::{check_len, deserialize_and_check_index}; +use crate::*; +use map_names::VotingProposalIndexNames; +use num_traits::ToPrimitive; + +impl Serialize for NewCommitteeProposal { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(4))?; + + let proposal_index = VotingProposalIndexNames::NewCommitteeAction.to_u64(); + serialize_and_check_index(serializer, proposal_index, "NewCommitteeAction")?; + + self.gov_action_id.serialize_nullable(serializer)?; + + let members_to_remove = StakeCredentials(self.members_to_remove.iter().cloned().collect()); + members_to_remove.serialize(serializer)?; + + self.committee.serialize(serializer)?; + + Ok(serializer) + } +} + +impl_deserialize_for_tuple!(NewCommitteeProposal); + +impl DeserializeEmbeddedGroup for NewCommitteeProposal { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + check_len( + len, + 4, + "(proposal_index, gov_action_id / null, set<$committee_cold_credential>, committee)", + )?; + + let desired_index = VotingProposalIndexNames::NewCommitteeAction.to_u64(); + deserialize_and_check_index(raw, desired_index, "proposal_index")?; + + let gov_action_id = GovernanceActionId::deserialize_nullable(raw) + .map_err(|e| e.annotate("gov_action_id"))?; + + let members_to_remove = + StakeCredentials::deserialize(raw).map_err(|e| e.annotate("members_to_remove"))?; + + let committee = Committee::deserialize(raw).map_err(|e| e.annotate("committee"))?; + + return Ok(NewCommitteeProposal { + gov_action_id, + members_to_remove: members_to_remove.0.iter().cloned().collect(), + committee, + }); + } +} diff --git a/rust/src/serialization/governance/proposals/new_constitution_proposal.rs b/rust/src/serialization/governance/proposals/new_constitution_proposal.rs new file mode 100644 index 00000000..24d3fe3f --- /dev/null +++ b/rust/src/serialization/governance/proposals/new_constitution_proposal.rs @@ -0,0 +1,52 @@ +use crate::*; + +use crate::serialization::struct_checks::serialize_and_check_index; +use crate::serialization::{check_len, deserialize_and_check_index}; +use map_names::VotingProposalIndexNames; +use num_traits::ToPrimitive; + +impl Serialize for NewConstitutionProposal { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(3))?; + + let proposal_index = VotingProposalIndexNames::NewConstitutionAction.to_u64(); + serialize_and_check_index(serializer, proposal_index, "NewConstitutionAction")?; + + self.gov_action_id.serialize_nullable(serializer)?; + self.constitution.serialize(serializer)?; + + Ok(serializer) + } +} + +impl_deserialize_for_tuple!(NewConstitutionProposal); + +impl DeserializeEmbeddedGroup for NewConstitutionProposal { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + check_len( + len, + 3, + "(proposal_index, gov_action_id / null, constitution)", + )?; + + let desired_index = VotingProposalIndexNames::NewConstitutionAction.to_u64(); + deserialize_and_check_index(raw, desired_index, "proposal_index")?; + + let gov_action_id = GovernanceActionId::deserialize_nullable(raw) + .map_err(|e| e.annotate("gov_action_id"))?; + + let constitution = + Constitution::deserialize(raw).map_err(|e| e.annotate("constitution"))?; + + return Ok(NewConstitutionProposal { + gov_action_id, + constitution, + }); + } +} diff --git a/rust/src/serialization/governance/proposals/no_confidence_proposal.rs b/rust/src/serialization/governance/proposals/no_confidence_proposal.rs new file mode 100644 index 00000000..07f69a76 --- /dev/null +++ b/rust/src/serialization/governance/proposals/no_confidence_proposal.rs @@ -0,0 +1,40 @@ +use crate::serialization::struct_checks::serialize_and_check_index; +use crate::serialization::{check_len, deserialize_and_check_index}; +use crate::*; +use map_names::VotingProposalIndexNames; +use num_traits::ToPrimitive; + +impl cbor_event::se::Serialize for NoConfidenceProposal { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + + let proposal_index = VotingProposalIndexNames::NoConfidenceAction.to_u64(); + serialize_and_check_index(serializer, proposal_index, "NoConfidenceAction")?; + + self.gov_action_id.serialize_nullable(serializer)?; + + Ok(serializer) + } +} + +impl_deserialize_for_tuple!(NoConfidenceProposal); + +impl DeserializeEmbeddedGroup for NoConfidenceProposal { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + check_len(len, 2, "(proposal_index, gov_action_id // null)")?; + + let desired_index = VotingProposalIndexNames::NoConfidenceAction.to_u64(); + deserialize_and_check_index(raw, desired_index, "proposal_index")?; + + let gov_action_id = GovernanceActionId::deserialize_nullable(raw) + .map_err(|e| e.annotate("gov_action_id"))?; + + return Ok(NoConfidenceProposal { gov_action_id }); + } +} diff --git a/rust/src/serialization/governance/proposals/parameter_change_proposal.rs b/rust/src/serialization/governance/proposals/parameter_change_proposal.rs new file mode 100644 index 00000000..7af4c19c --- /dev/null +++ b/rust/src/serialization/governance/proposals/parameter_change_proposal.rs @@ -0,0 +1,51 @@ +use crate::serialization::struct_checks::serialize_and_check_index; +use crate::serialization::{check_len, deserialize_and_check_index}; +use crate::*; +use map_names::VotingProposalIndexNames; +use num_traits::ToPrimitive; + +impl cbor_event::se::Serialize for ParameterChangeProposal { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(3))?; + + let proposal_index = VotingProposalIndexNames::ParameterChangeAction.to_u64(); + serialize_and_check_index(serializer, proposal_index, "ParameterChangeAction")?; + + self.gov_action_id.serialize_nullable(serializer)?; + self.protocol_param_updates.serialize(serializer)?; + + Ok(serializer) + } +} + +impl_deserialize_for_tuple!(ParameterChangeProposal); + +impl DeserializeEmbeddedGroup for ParameterChangeProposal { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + check_len( + len, + 3, + "(proposal_index, gov_action_id // null), protocol_param_updates", + )?; + + let desired_index = VotingProposalIndexNames::ParameterChangeAction.to_u64(); + deserialize_and_check_index(raw, desired_index, "proposal_index")?; + + let gov_action_id = GovernanceActionId::deserialize_nullable(raw) + .map_err(|e| e.annotate("gov_action_id"))?; + + let protocol_param_updates = ProtocolParamUpdate::deserialize(raw) + .map_err(|e| e.annotate("protocol_param_updates"))?; + + return Ok(ParameterChangeProposal { + gov_action_id, + protocol_param_updates, + }); + } +} diff --git a/rust/src/serialization/governance/proposals/treasury_withdrawals.rs b/rust/src/serialization/governance/proposals/treasury_withdrawals.rs new file mode 100644 index 00000000..2f622b95 --- /dev/null +++ b/rust/src/serialization/governance/proposals/treasury_withdrawals.rs @@ -0,0 +1,45 @@ +use crate::*; +use std::collections::BTreeMap; + +impl Serialize for TreasuryWithdrawals { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?; + for (key, value) in &self.0 { + key.serialize(serializer)?; + value.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for TreasuryWithdrawals { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut table = BTreeMap::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.map()?; + while match len { + cbor_event::Len::Len(n) => table.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + let key = RewardAddress::deserialize(raw)?; + let value = Coin::deserialize(raw)?; + if table.insert(key.clone(), value).is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Str(String::from( + "some complicated/unsupported type", + ))) + .into()); + } + } + Ok(()) + })() + .map_err(|e| e.annotate("TreasuryWithdrawals"))?; + Ok(Self(table)) + } +} diff --git a/rust/src/serialization/governance/proposals/treasury_withdrawals_proposal.rs b/rust/src/serialization/governance/proposals/treasury_withdrawals_proposal.rs new file mode 100644 index 00000000..b13f1471 --- /dev/null +++ b/rust/src/serialization/governance/proposals/treasury_withdrawals_proposal.rs @@ -0,0 +1,39 @@ +use crate::serialization::struct_checks::serialize_and_check_index; +use crate::serialization::{check_len, deserialize_and_check_index}; +use crate::*; +use map_names::VotingProposalIndexNames; +use num_traits::ToPrimitive; + +impl Serialize for TreasuryWithdrawalsProposal { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + + let proposal_index = VotingProposalIndexNames::TreasuryWithdrawalsAction.to_u64(); + serialize_and_check_index(serializer, proposal_index, "TreasuryWithdrawalsAction")?; + + self.withdrawals.serialize(serializer)?; + + Ok(serializer) + } +} + +impl_deserialize_for_tuple!(TreasuryWithdrawalsProposal); + +impl DeserializeEmbeddedGroup for TreasuryWithdrawalsProposal { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + check_len(len, 2, "(proposal_index, withdrawals)")?; + + let desired_index = VotingProposalIndexNames::TreasuryWithdrawalsAction.to_u64(); + deserialize_and_check_index(raw, desired_index, "proposal_index")?; + + let withdrawals = TreasuryWithdrawals::deserialize(raw)?; + + return Ok(TreasuryWithdrawalsProposal { withdrawals }); + } +} diff --git a/rust/src/serialization/mod.rs b/rust/src/serialization/mod.rs index 2d6f1240..e1ac9e48 100644 --- a/rust/src/serialization/mod.rs +++ b/rust/src/serialization/mod.rs @@ -11,4 +11,11 @@ mod ser_info; pub use ser_info::*; mod governance; -pub use governance::*; \ No newline at end of file +pub use governance::*; + +pub mod map_names; +pub mod traits; +pub(super) use traits::*; + +mod struct_checks; +use struct_checks::*; From 849ab3bab2c9f958e391277641790a90a08b610c Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 18 Aug 2023 00:36:03 +0400 Subject: [PATCH 065/349] optional anchor vor voting procedure --- rust/src/serialization/governance/voting_procedure.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/src/serialization/governance/voting_procedure.rs b/rust/src/serialization/governance/voting_procedure.rs index 8ad22040..a12c0c1d 100644 --- a/rust/src/serialization/governance/voting_procedure.rs +++ b/rust/src/serialization/governance/voting_procedure.rs @@ -51,7 +51,7 @@ impl Deserialize for VotingProcedure { } }; - let anchor = Anchor::deserialize(raw).map_err( + let anchor = Anchor::deserialize_nullable(raw).map_err( |e| e.annotate("anchor") )?; From b29950a34110672bfe68bd974daa6cfe0df0c1a4 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 18 Aug 2023 16:39:06 +0400 Subject: [PATCH 066/349] bingen fix --- rust/src/protocol_types/governance/proposals/committee.rs | 4 ++-- rust/src/protocol_types/governance/voting_procedure.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rust/src/protocol_types/governance/proposals/committee.rs b/rust/src/protocol_types/governance/proposals/committee.rs index a2cf6e49..4fa1207f 100644 --- a/rust/src/protocol_types/governance/proposals/committee.rs +++ b/rust/src/protocol_types/governance/proposals/committee.rs @@ -38,9 +38,9 @@ impl Committee { self.quorum_threshold.clone() } - pub fn add_member(&mut self, committee_cold_credential: &StakeCredential, epoch: &Epoch) { + pub fn add_member(&mut self, committee_cold_credential: &StakeCredential, epoch: Epoch) { self.members - .insert(committee_cold_credential.clone(), epoch.clone()); + .insert(committee_cold_credential.clone(), epoch); } pub fn get_member_epoch(&self, committee_cold_credential: &StakeCredential) -> Option { diff --git a/rust/src/protocol_types/governance/voting_procedure.rs b/rust/src/protocol_types/governance/voting_procedure.rs index 1d33c346..66acc585 100644 --- a/rust/src/protocol_types/governance/voting_procedure.rs +++ b/rust/src/protocol_types/governance/voting_procedure.rs @@ -41,14 +41,14 @@ impl_to_from!(VotingProcedure); #[wasm_bindgen] impl VotingProcedure { - pub fn new(vote: &VoteKind) -> Self { + pub fn new(vote: VoteKind) -> Self { Self { vote: vote.clone(), anchor: None, } } - pub fn new_with_anchor(vote: &VoteKind, anchor: &Anchor) -> Self { + pub fn new_with_anchor(vote: VoteKind, anchor: &Anchor) -> Self { Self { vote: vote.clone(), anchor: Some(anchor.clone()), From d8acda7dd164ab1821dd1cf9b08162aeaf22469b Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 18 Aug 2023 16:42:33 +0400 Subject: [PATCH 067/349] import fix --- rust/src/lib.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index b540661a..15573374 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -15,6 +15,9 @@ extern crate quickcheck; extern crate quickcheck_macros; extern crate hex; +#[macro_use] +extern crate num_derive; + use std::convert::TryInto; use std::io::{BufRead, Seek, Write}; @@ -52,10 +55,10 @@ pub mod tx_builder; pub mod tx_builder_constants; pub mod typed_bytes; mod protocol_types; +pub use protocol_types::*; #[macro_use] pub mod utils; mod fakes; -mod serialization_tools; mod serialization; use crate::traits::NoneOrEmpty; From e0c318358ce2fdfd05cf7572178867e22ed22a56 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 21 Aug 2023 13:59:07 +0400 Subject: [PATCH 068/349] update cargo file --- rust/Cargo.toml | 3 ++ rust/json-gen/Cargo.lock | 64 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/rust/Cargo.toml b/rust/Cargo.toml index ffe667c7..d426d450 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -35,6 +35,9 @@ itertools = "0.10.1" rand = "0.8.4" schemars = "0.8.8" serde = { version = "1.0", features = ["derive"] } +num-derive = "0.4.0" +num-traits = "0.2.16" +num = "0.4.1" # non-wasm [target.'cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))'.dependencies] diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index fa3b06c4..34c27f0f 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -52,8 +52,11 @@ dependencies = [ "js-sys", "linked-hash-map", "noop_proc_macro", + "num", "num-bigint", + "num-derive", "num-integer", + "num-traits", "rand", "rand_os", "schemars", @@ -240,6 +243,20 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" +[[package]] +name = "num" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + [[package]] name = "num-bigint" version = "0.4.3" @@ -251,6 +268,26 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-complex" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e6a0fd4f737c707bd9086cc16c925f294943eb62eb71499e9fd4cf71f8b9f4e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.23", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -261,11 +298,34 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] From a143ada0f67f4acdbeca521108e7e997e17f6cb5 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 21 Aug 2023 13:59:39 +0400 Subject: [PATCH 069/349] add voting proposal file --- .../governance/proposals/mod.rs | 6 + .../governance/proposals/voting_proposal.rs | 182 ++++++++++++++++++ .../governance/proposals/voting_proposals.rs | 20 ++ 3 files changed, 208 insertions(+) create mode 100644 rust/src/protocol_types/governance/proposals/voting_proposal.rs create mode 100644 rust/src/protocol_types/governance/proposals/voting_proposals.rs diff --git a/rust/src/protocol_types/governance/proposals/mod.rs b/rust/src/protocol_types/governance/proposals/mod.rs index 375d66e0..eac460af 100644 --- a/rust/src/protocol_types/governance/proposals/mod.rs +++ b/rust/src/protocol_types/governance/proposals/mod.rs @@ -27,3 +27,9 @@ pub use new_constitution_proposal::*; mod info_proposal; pub use info_proposal::*; + +mod voting_proposal; +pub use voting_proposal::*; + +mod voting_proposals; +pub use voting_proposals::*; \ No newline at end of file diff --git a/rust/src/protocol_types/governance/proposals/voting_proposal.rs b/rust/src/protocol_types/governance/proposals/voting_proposal.rs new file mode 100644 index 00000000..38b76823 --- /dev/null +++ b/rust/src/protocol_types/governance/proposals/voting_proposal.rs @@ -0,0 +1,182 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub(crate) enum VotingProposalEnum { + ParameterChangeProposal(ParameterChangeProposal), + HardForkInitiationProposal(HardForkInitiationProposal), + TreasuryWithdrawalsProposal(TreasuryWithdrawalsProposal), + NoConfidenceProposal(NoConfidenceProposal), + NewCommitteeProposal(NewCommitteeProposal), + NewConstitutionProposal(NewConstitutionProposal), + InfoProposal(InfoProposal), +} + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub enum VotingProposalKind { + ParameterChangeProposal = 0, + HardForkInitiationProposal = 1, + TreasuryWithdrawalsProposal = 2, + NoConfidenceProposal = 3, + NewCommitteeProposal = 4, + NewConstitutionProposal = 5, + InfoProposal = 6, +} + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct VotingProposal(VotingProposalEnum); + +impl_to_from!(VotingProposal); + +impl VotingProposal { + pub fn new_parameter_change_proposal( + parameter_change_proposal: &ParameterChangeProposal, + ) -> Self { + Self(VotingProposalEnum::ParameterChangeProposal( + parameter_change_proposal.clone(), + )) + } + + pub fn new_hard_fork_initiation_proposal( + hard_fork_initiation_proposal: &HardForkInitiationProposal, + ) -> Self { + Self(VotingProposalEnum::HardForkInitiationProposal( + hard_fork_initiation_proposal.clone(), + )) + } + + pub fn new_treasury_withdrawals_proposal( + treasury_withdrawals_proposal: &TreasuryWithdrawalsProposal, + ) -> Self { + Self(VotingProposalEnum::TreasuryWithdrawalsProposal( + treasury_withdrawals_proposal.clone(), + )) + } + + pub fn new_no_confidence_proposal(no_confidence_proposal: &NoConfidenceProposal) -> Self { + Self(VotingProposalEnum::NoConfidenceProposal( + no_confidence_proposal.clone(), + )) + } + + pub fn new_new_committee_proposal(new_committee_proposal: &NewCommitteeProposal) -> Self { + Self(VotingProposalEnum::NewCommitteeProposal( + new_committee_proposal.clone(), + )) + } + + pub fn new_new_constitution_proposal( + new_constitution_proposal: &NewConstitutionProposal, + ) -> Self { + Self(VotingProposalEnum::NewConstitutionProposal( + new_constitution_proposal.clone(), + )) + } + + pub fn new_info_proposal(info_proposal: &InfoProposal) -> Self { + Self(VotingProposalEnum::InfoProposal(info_proposal.clone())) + } + + pub fn kind(&self) -> VotingProposalKind { + match &self.0 { + VotingProposalEnum::ParameterChangeProposal(_) => { + VotingProposalKind::ParameterChangeProposal + } + VotingProposalEnum::HardForkInitiationProposal(_) => { + VotingProposalKind::HardForkInitiationProposal + } + VotingProposalEnum::TreasuryWithdrawalsProposal(_) => { + VotingProposalKind::TreasuryWithdrawalsProposal + } + VotingProposalEnum::NoConfidenceProposal(_) => VotingProposalKind::NoConfidenceProposal, + VotingProposalEnum::NewCommitteeProposal(_) => VotingProposalKind::NewCommitteeProposal, + VotingProposalEnum::NewConstitutionProposal(_) => { + VotingProposalKind::NewConstitutionProposal + } + VotingProposalEnum::InfoProposal(_) => VotingProposalKind::InfoProposal, + } + } + + pub fn as_parameter_change_proposal(&self) -> Option { + match &self.0 { + VotingProposalEnum::ParameterChangeProposal(p) => Some(p.clone()), + _ => None, + } + } + + pub fn as_hard_fork_initiation_proposal(&self) -> Option { + match &self.0 { + VotingProposalEnum::HardForkInitiationProposal(p) => Some(p.clone()), + _ => None, + } + } + + pub fn as_treasury_withdrawals_proposal(&self) -> Option { + match &self.0 { + VotingProposalEnum::TreasuryWithdrawalsProposal(p) => Some(p.clone()), + _ => None, + } + } + + pub fn as_no_confidence_proposal(&self) -> Option { + match &self.0 { + VotingProposalEnum::NoConfidenceProposal(p) => Some(p.clone()), + _ => None, + } + } + + pub fn as_new_committee_proposal(&self) -> Option { + match &self.0 { + VotingProposalEnum::NewCommitteeProposal(p) => Some(p.clone()), + _ => None, + } + } + + pub fn as_new_constitution_proposal(&self) -> Option { + match &self.0 { + VotingProposalEnum::NewConstitutionProposal(p) => Some(p.clone()), + _ => None, + } + } + + pub fn as_info_proposal(&self) -> Option { + match &self.0 { + VotingProposalEnum::InfoProposal(p) => Some(p.clone()), + _ => None, + } + } +} diff --git a/rust/src/protocol_types/governance/proposals/voting_proposals.rs b/rust/src/protocol_types/governance/proposals/voting_proposals.rs new file mode 100644 index 00000000..7a51e670 --- /dev/null +++ b/rust/src/protocol_types/governance/proposals/voting_proposals.rs @@ -0,0 +1,20 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct VotingProposals { + pub(crate) proposals: Vec, +} + +impl_to_from!(VotingProposals); \ No newline at end of file From 958379c5ad04ba859f45008a6ab905686acabf24 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 21 Aug 2023 18:28:30 +0400 Subject: [PATCH 070/349] add hash --- .../hard_fork_initiation_proposal.rs | 11 ++++++++- .../governance/proposals/info_proposal.rs | 11 ++++++++- .../proposals/new_committee_proposal.rs | 11 ++++++++- .../proposals/new_constitution_proposal.rs | 4 +++- .../proposals/no_confidence_proposal.rs | 22 ++++++++++++++++- .../proposals/parameter_change_proposal.rs | 11 ++++++++- .../treasury_withdrawals_proposal.rs | 2 +- .../governance/proposals/voting_proposal.rs | 2 +- .../governance/proposals/voting_proposals.rs | 24 +++++++++++++++---- 9 files changed, 86 insertions(+), 12 deletions(-) diff --git a/rust/src/protocol_types/governance/proposals/hard_fork_initiation_proposal.rs b/rust/src/protocol_types/governance/proposals/hard_fork_initiation_proposal.rs index 0b3927bb..37adf457 100644 --- a/rust/src/protocol_types/governance/proposals/hard_fork_initiation_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/hard_fork_initiation_proposal.rs @@ -1,7 +1,16 @@ use crate::*; #[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] #[wasm_bindgen] pub struct HardForkInitiationProposal { diff --git a/rust/src/protocol_types/governance/proposals/info_proposal.rs b/rust/src/protocol_types/governance/proposals/info_proposal.rs index 85baf836..4fd2ac93 100644 --- a/rust/src/protocol_types/governance/proposals/info_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/info_proposal.rs @@ -1,7 +1,16 @@ use crate::*; #[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] #[wasm_bindgen] pub struct InfoProposal(); diff --git a/rust/src/protocol_types/governance/proposals/new_committee_proposal.rs b/rust/src/protocol_types/governance/proposals/new_committee_proposal.rs index 2916ff11..c7216526 100644 --- a/rust/src/protocol_types/governance/proposals/new_committee_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/new_committee_proposal.rs @@ -1,7 +1,16 @@ use crate::*; #[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] #[wasm_bindgen] pub struct NewCommitteeProposal { diff --git a/rust/src/protocol_types/governance/proposals/new_constitution_proposal.rs b/rust/src/protocol_types/governance/proposals/new_constitution_proposal.rs index 25866804..93ae3f18 100644 --- a/rust/src/protocol_types/governance/proposals/new_constitution_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/new_constitution_proposal.rs @@ -3,11 +3,11 @@ use crate::*; #[derive( Clone, Debug, + Hash, Eq, Ord, PartialEq, PartialOrd, - Hash, serde::Serialize, serde::Deserialize, JsonSchema, @@ -18,6 +18,8 @@ pub struct NewConstitutionProposal { pub(crate) constitution: Constitution, } +impl_to_from!(NewConstitutionProposal); + impl NewConstitutionProposal { pub fn gov_action_id(&self) -> Option { self.gov_action_id.clone() diff --git a/rust/src/protocol_types/governance/proposals/no_confidence_proposal.rs b/rust/src/protocol_types/governance/proposals/no_confidence_proposal.rs index efecd859..9c46ffca 100644 --- a/rust/src/protocol_types/governance/proposals/no_confidence_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/no_confidence_proposal.rs @@ -3,11 +3,11 @@ use crate::*; #[derive( Clone, Debug, + Hash, Eq, Ord, PartialEq, PartialOrd, - Hash, serde::Serialize, serde::Deserialize, JsonSchema, @@ -16,3 +16,23 @@ use crate::*; pub struct NoConfidenceProposal { pub(crate) gov_action_id: Option, } + +impl_to_from!(NoConfidenceProposal); + +impl NoConfidenceProposal { + pub fn gov_action_id(&self) -> Option { + self.gov_action_id.clone() + } + + pub fn new() -> Self { + Self { + gov_action_id: None, + } + } + + pub fn new_with_action_id(gov_action_id: &GovernanceActionId) -> Self { + Self { + gov_action_id: Some(gov_action_id.clone()), + } + } +} diff --git a/rust/src/protocol_types/governance/proposals/parameter_change_proposal.rs b/rust/src/protocol_types/governance/proposals/parameter_change_proposal.rs index 7c5fc654..fdebeb34 100644 --- a/rust/src/protocol_types/governance/proposals/parameter_change_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/parameter_change_proposal.rs @@ -1,7 +1,16 @@ use crate::*; #[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] #[wasm_bindgen] pub struct ParameterChangeProposal { diff --git a/rust/src/protocol_types/governance/proposals/treasury_withdrawals_proposal.rs b/rust/src/protocol_types/governance/proposals/treasury_withdrawals_proposal.rs index 11ab2233..9f96307f 100644 --- a/rust/src/protocol_types/governance/proposals/treasury_withdrawals_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/treasury_withdrawals_proposal.rs @@ -3,11 +3,11 @@ use crate::*; #[derive( Clone, Debug, + Hash, Eq, Ord, PartialEq, PartialOrd, - Hash, serde::Serialize, serde::Deserialize, JsonSchema, diff --git a/rust/src/protocol_types/governance/proposals/voting_proposal.rs b/rust/src/protocol_types/governance/proposals/voting_proposal.rs index 38b76823..c46ad3ce 100644 --- a/rust/src/protocol_types/governance/proposals/voting_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/voting_proposal.rs @@ -58,7 +58,7 @@ pub enum VotingProposalKind { JsonSchema, )] #[wasm_bindgen] -pub struct VotingProposal(VotingProposalEnum); +pub struct VotingProposal(pub(crate) VotingProposalEnum); impl_to_from!(VotingProposal); diff --git a/rust/src/protocol_types/governance/proposals/voting_proposals.rs b/rust/src/protocol_types/governance/proposals/voting_proposals.rs index 7a51e670..729a5998 100644 --- a/rust/src/protocol_types/governance/proposals/voting_proposals.rs +++ b/rust/src/protocol_types/governance/proposals/voting_proposals.rs @@ -13,8 +13,24 @@ use crate::*; JsonSchema, )] #[wasm_bindgen] -pub struct VotingProposals { - pub(crate) proposals: Vec, -} +pub struct VotingProposals(pub(crate) Vec); + +impl_to_from!(VotingProposals); + +impl VotingProposals { + pub fn new() -> Self { + Self(Vec::new()) + } -impl_to_from!(VotingProposals); \ No newline at end of file + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> VotingProposal { + self.0[index].clone() + } + + pub fn add(&mut self, proposal: &VotingProposal) { + self.0.push(proposal.clone()); + } +} From 89d78bc1d49e5fe5922fdd048c0beac53302864b Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 21 Aug 2023 18:28:44 +0400 Subject: [PATCH 071/349] add hash --- rust/src/crypto.rs | 2 +- rust/src/lib.rs | 5 ++--- rust/src/plutus.rs | 10 ++++++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/rust/src/crypto.rs b/rust/src/crypto.rs index e2de5655..df6c4519 100644 --- a/rust/src/crypto.rs +++ b/rust/src/crypto.rs @@ -1217,7 +1217,7 @@ impl JsonSchema for KESSignature { // Evolving nonce type (used for Update's crypto) #[wasm_bindgen] #[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, )] pub struct Nonce { hash: Option<[u8; 32]>, diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 15573374..a5e22c96 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -74,7 +74,6 @@ use std::fmt::Display; use std::fmt; use utils::*; use serialization::*; -use protocol_types::*; type DeltaCoin = Int; @@ -1920,7 +1919,7 @@ impl ProposedProtocolParameterUpdates { #[wasm_bindgen] #[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, )] pub struct ProtocolVersion { major: u32, @@ -1946,7 +1945,7 @@ impl ProtocolVersion { #[wasm_bindgen] #[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, )] pub struct ProtocolParamUpdate { minfee_a: Option, diff --git a/rust/src/plutus.rs b/rust/src/plutus.rs index 00cd831d..61ccf956 100644 --- a/rust/src/plutus.rs +++ b/rust/src/plutus.rs @@ -271,7 +271,7 @@ impl ConstrPlutusData { #[wasm_bindgen] #[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, )] pub struct CostModel(Vec); @@ -324,7 +324,7 @@ impl From> for CostModel { #[wasm_bindgen] #[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, )] pub struct Costmdls(std::collections::BTreeMap); @@ -412,7 +412,7 @@ impl Costmdls { #[wasm_bindgen] #[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, )] pub struct ExUnitPrices { mem_price: SubCoin, @@ -441,7 +441,7 @@ impl ExUnitPrices { #[wasm_bindgen] #[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, )] pub struct ExUnits { mem: BigNum, @@ -473,6 +473,7 @@ impl ExUnits { Clone, Copy, Debug, + Hash, Eq, Ord, PartialEq, @@ -501,6 +502,7 @@ impl LanguageKind { Clone, Copy, Debug, + Hash, Eq, Ord, PartialEq, From 296f0e8c676eb3937ba3f9a582440026bd2e2976 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 21 Aug 2023 18:29:22 +0400 Subject: [PATCH 072/349] add voting proposal serialisation --- .../serialization/governance/proposals/mod.rs | 6 + .../proposals/parameter_change_proposal.rs | 2 +- .../governance/proposals/voting_proposal.rs | 120 ++++++++++++++++++ .../governance/proposals/voting_proposals.rs | 36 ++++++ 4 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 rust/src/serialization/governance/proposals/voting_proposal.rs create mode 100644 rust/src/serialization/governance/proposals/voting_proposals.rs diff --git a/rust/src/serialization/governance/proposals/mod.rs b/rust/src/serialization/governance/proposals/mod.rs index 6f96c28c..64a9f601 100644 --- a/rust/src/serialization/governance/proposals/mod.rs +++ b/rust/src/serialization/governance/proposals/mod.rs @@ -24,3 +24,9 @@ pub use constitution::*; mod new_constitution_proposal; pub use new_constitution_proposal::*; + +mod voting_proposal; +pub use voting_proposal::*; + +mod voting_proposals; +pub use voting_proposals::*; diff --git a/rust/src/serialization/governance/proposals/parameter_change_proposal.rs b/rust/src/serialization/governance/proposals/parameter_change_proposal.rs index 7af4c19c..e502ddda 100644 --- a/rust/src/serialization/governance/proposals/parameter_change_proposal.rs +++ b/rust/src/serialization/governance/proposals/parameter_change_proposal.rs @@ -31,7 +31,7 @@ impl DeserializeEmbeddedGroup for ParameterChangeProposal { check_len( len, 3, - "(proposal_index, gov_action_id // null), protocol_param_updates", + "(proposal_index, gov_action_id // null, protocol_param_updates)", )?; let desired_index = VotingProposalIndexNames::ParameterChangeAction.to_u64(); diff --git a/rust/src/serialization/governance/proposals/voting_proposal.rs b/rust/src/serialization/governance/proposals/voting_proposal.rs new file mode 100644 index 00000000..44d6f8ee --- /dev/null +++ b/rust/src/serialization/governance/proposals/voting_proposal.rs @@ -0,0 +1,120 @@ +use crate::serialization::map_names::VotingProposalIndexNames; +use crate::serialization::struct_checks::{check_len_indefinite, serialize_and_check_index}; +use crate::*; +use num_traits::{FromPrimitive, ToPrimitive}; +use std::io::{Seek, SeekFrom}; + +impl Serialize for VotingProposal { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + match &self.0 { + VotingProposalEnum::ParameterChangeProposal(x) => x.serialize(serializer), + VotingProposalEnum::HardForkInitiationProposal(x) => x.serialize(serializer), + VotingProposalEnum::TreasuryWithdrawalsProposal(x) => x.serialize(serializer), + VotingProposalEnum::NoConfidenceProposal(x) => x.serialize(serializer), + VotingProposalEnum::NewCommitteeProposal(x) => x.serialize(serializer), + VotingProposalEnum::NewConstitutionProposal(x) => x.serialize(serializer), + VotingProposalEnum::InfoProposal(_) => { + let index = VotingProposalIndexNames::InfoAction.to_u64(); + serialize_and_check_index(serializer, index, "VotingProposalEnum::InfoProposal") + } + } + } +} + +impl Deserialize for VotingProposal { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + if let Ok(index) = raw.unsigned_integer() { + let expected_index = VotingProposalIndexNames::InfoAction.to_u64().ok_or( + DeserializeFailure::CustomError( + "unknown index of VotingProposalEnum::InfoProposal".to_string(), + ), + )?; + if index != expected_index { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(index), + expected: Key::Uint(expected_index), + } + .into()); + } + } + + let len = raw.array()?; + let ret = Self::deserialize_as_embedded_group(raw, len); + check_len_indefinite(raw, len)?; + ret + })() + .map_err(|e| e.annotate("VotingProposal")) + } +} + +impl DeserializeEmbeddedGroup for VotingProposal { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + let cert_index = get_proposal_index(raw)?; + let index_enum = + VotingProposalIndexNames::from_u64(cert_index).ok_or(DeserializeError::new( + "VotingProposal", + DeserializeFailure::UnknownKey(Key::Uint(cert_index)), + ))?; + + let proposal_enum = match index_enum { + VotingProposalIndexNames::ParameterChangeAction => { + Ok::( + VotingProposalEnum::ParameterChangeProposal( + ParameterChangeProposal::deserialize_as_embedded_group(raw, len)?, + ), + ) + } + VotingProposalIndexNames::HardForkInitiationAction => { + Ok(VotingProposalEnum::HardForkInitiationProposal( + HardForkInitiationProposal::deserialize_as_embedded_group(raw, len)?, + )) + } + VotingProposalIndexNames::TreasuryWithdrawalsAction => { + Ok(VotingProposalEnum::TreasuryWithdrawalsProposal( + TreasuryWithdrawalsProposal::deserialize_as_embedded_group(raw, len)?, + )) + } + VotingProposalIndexNames::NoConfidenceAction => { + Ok(VotingProposalEnum::NoConfidenceProposal( + NoConfidenceProposal::deserialize_as_embedded_group(raw, len)?, + )) + } + VotingProposalIndexNames::NewCommitteeAction => { + Ok(VotingProposalEnum::NewCommitteeProposal( + NewCommitteeProposal::deserialize_as_embedded_group(raw, len)?, + )) + } + VotingProposalIndexNames::NewConstitutionAction => { + Ok(VotingProposalEnum::NewConstitutionProposal( + NewConstitutionProposal::deserialize_as_embedded_group(raw, len)?, + )) + } + VotingProposalIndexNames::InfoAction => { + Ok(VotingProposalEnum::InfoProposal(InfoProposal::new())) + } + }?; + + Ok(Self(proposal_enum)) + } +} + +fn get_proposal_index( + raw: &mut Deserializer, +) -> Result { + let initial_position = raw + .as_mut_ref() + .seek(SeekFrom::Current(0)) + .map_err(|err| DeserializeFailure::IoError(err.to_string()))?; + let index = raw.unsigned_integer()?; + raw.as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .map_err(|err| DeserializeFailure::IoError(err.to_string()))?; + Ok(index) +} diff --git a/rust/src/serialization/governance/proposals/voting_proposals.rs b/rust/src/serialization/governance/proposals/voting_proposals.rs new file mode 100644 index 00000000..3fc2aa28 --- /dev/null +++ b/rust/src/serialization/governance/proposals/voting_proposals.rs @@ -0,0 +1,36 @@ +use crate::*; + +impl cbor_event::se::Serialize for VotingProposals { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for VotingProposals { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(VotingProposal::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("VotingProposals"))?; + Ok(Self(arr)) + } +} From 35928e0bd84317dd2dbceb6be89a8c66f67e7be8 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 21 Aug 2023 19:13:50 +0400 Subject: [PATCH 073/349] add voting proposal builder --- rust/src/lib.rs | 2 + rust/src/serialization/general.rs | 22 +++- rust/src/tx_builder.rs | 78 ++++++++++--- rust/src/tx_builder/test_batch.rs | 13 +++ .../{vote_builder.rs => voting_builder.rs} | 0 .../src/tx_builder/voting_proposal_builder.rs | 108 ++++++++++++++++++ 6 files changed, 207 insertions(+), 16 deletions(-) rename rust/src/tx_builder/{vote_builder.rs => voting_builder.rs} (100%) create mode 100644 rust/src/tx_builder/voting_proposal_builder.rs diff --git a/rust/src/lib.rs b/rust/src/lib.rs index a5e22c96..7c78470c 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -335,6 +335,7 @@ pub struct TransactionBody { total_collateral: Option, reference_inputs: Option, voting_procedures: Option, + voting_proposals: Option, } impl_to_from!(TransactionBody); @@ -576,6 +577,7 @@ impl TransactionBody { total_collateral: None, reference_inputs: None, voting_procedures: None, + voting_proposals: None, } } } diff --git a/rust/src/serialization/general.rs b/rust/src/serialization/general.rs index fe2be4a8..5ace82ef 100644 --- a/rust/src/serialization/general.rs +++ b/rust/src/serialization/general.rs @@ -298,7 +298,9 @@ impl cbor_event::se::Serialize for TransactionBody { + opt64(&self.network_id) + opt64(&self.collateral_return) + opt64(&self.total_collateral) - + opt64(&self.reference_inputs), + + opt64(&self.reference_inputs) + + opt64(&self.voting_procedures) + + opt64(&self.voting_proposals), ))?; serializer.write_unsigned_integer(0)?; self.inputs.serialize(serializer)?; @@ -366,6 +368,10 @@ impl cbor_event::se::Serialize for TransactionBody { serializer.write_unsigned_integer(19)?; field.serialize(serializer)?; } + if let Some(field) = &self.voting_proposals { + serializer.write_unsigned_integer(20)?; + field.serialize(serializer)?; + } Ok(serializer) } } @@ -394,6 +400,7 @@ impl Deserialize for TransactionBody { let mut total_collateral = None; let mut reference_inputs = None; let mut voting_procedures = None; + let mut voting_proposals = None; let mut read = 0; while match len { cbor_event::Len::Len(n) => read < n as usize, @@ -615,6 +622,18 @@ impl Deserialize for TransactionBody { .map_err(|e| e.annotate("voting_procedures"))?, ); } + 20 => { + if voting_proposals.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(20)).into()); + } + voting_proposals = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(VotingProposals::deserialize(raw)?) + })() + .map_err(|e| e.annotate("voting_proposals"))?, + ); + } unknown_key => { return Err( DeserializeFailure::UnknownKey(Key::Uint(unknown_key)).into() @@ -676,6 +695,7 @@ impl Deserialize for TransactionBody { total_collateral, reference_inputs, voting_procedures, + voting_proposals, }) })() .map_err(|e| e.annotate("TransactionBody")) diff --git a/rust/src/tx_builder.rs b/rust/src/tx_builder.rs index 4a0308c6..3031d2b7 100644 --- a/rust/src/tx_builder.rs +++ b/rust/src/tx_builder.rs @@ -8,10 +8,12 @@ pub mod tx_batch_builder; pub mod mint_builder; pub mod certificates_builder; pub mod withdrawals_builder; -pub mod vote_builder; +pub mod voting_proposal_builder; +pub mod voting_builder; mod batch_tools; mod script_structs; + use super::fees; use super::output_builder::TransactionOutputAmountBuilder; use super::utils; @@ -23,7 +25,8 @@ use crate::tx_builder::certificates_builder::CertificatesBuilder; use crate::tx_builder::withdrawals_builder::WithdrawalsBuilder; use crate::tx_builder::script_structs::{PlutusWitness, PlutusWitnesses}; use crate::tx_builder::mint_builder::{MintBuilder, MintWitness}; -use crate::tx_builder::vote_builder::VotingBuilder; +use crate::tx_builder::voting_builder::VotingBuilder; +use crate::tx_builder::voting_proposal_builder::VotingProposalBuilder; pub(crate) fn fake_private_key() -> Bip32PrivateKey { Bip32PrivateKey::from_bytes(&[ @@ -69,7 +72,7 @@ fn count_needed_vkeys(tx_builder: &TransactionBuilder) -> usize { if let Some(certs_builder) = &tx_builder.certs { input_hashes.extend(certs_builder.get_required_signers()); } - if let Some(voting_builder) = &tx_builder.voting { + if let Some(voting_builder) = &tx_builder.voting_procedures { input_hashes.extend(voting_builder.get_required_signers()); } input_hashes.len() @@ -201,6 +204,7 @@ pub struct TransactionBuilderConfig { fee_algo: fees::LinearFee, pool_deposit: Coin, // protocol parameter key_deposit: Coin, // protocol parameter + voting_proposal_deposit: Coin, // protocol parameter max_value_size: u32, // protocol parameter max_tx_size: u32, // protocol parameter data_cost: DataCost, // protocol parameter @@ -220,6 +224,7 @@ pub struct TransactionBuilderConfigBuilder { fee_algo: Option, pool_deposit: Option, // protocol parameter key_deposit: Option, // protocol parameter + voting_proposal_deposit: Option, // protocol parameter max_value_size: Option, // protocol parameter max_tx_size: Option, // protocol parameter data_cost: Option, // protocol parameter @@ -234,6 +239,7 @@ impl TransactionBuilderConfigBuilder { fee_algo: None, pool_deposit: None, key_deposit: None, + voting_proposal_deposit: None, max_value_size: None, max_tx_size: None, data_cost: None, @@ -302,6 +308,12 @@ impl TransactionBuilderConfigBuilder { cfg } + pub fn voting_proposal_deposit(&self, voting_proposal_deposit: &Coin) -> Self { + let mut cfg = self.clone(); + cfg.voting_proposal_deposit = Some(voting_proposal_deposit.clone()); + cfg + } + pub fn build(&self) -> Result { let cfg: Self = self.clone(); Ok(TransactionBuilderConfig { @@ -311,6 +323,11 @@ impl TransactionBuilderConfigBuilder { pool_deposit: cfg .pool_deposit .ok_or(JsError::from_str("uninitialized field: pool_deposit"))?, + voting_proposal_deposit: cfg + .voting_proposal_deposit + .ok_or(JsError::from_str( + "uninitialized field: voting_proposal_deposit", + ))?, key_deposit: cfg .key_deposit .ok_or(JsError::from_str("uninitialized field: key_deposit"))?, @@ -348,7 +365,8 @@ pub struct TransactionBuilder { collateral_return: Option, total_collateral: Option, reference_inputs: HashSet, - voting: Option, + voting_procedures: Option, + voting_proposals: Option, } #[wasm_bindgen] @@ -1004,8 +1022,12 @@ impl TransactionBuilder { self.withdrawals = Some(withdrawals.clone()); } - pub fn set_voting(&mut self, voting: &VotingBuilder) { - self.voting = Some(voting.clone()); + pub fn set_voting_builder(&mut self, voting_builder: &VotingBuilder) { + self.voting_procedures = Some(voting_builder.clone()); + } + + pub fn set_voting_proposal_builder(&mut self, voting_proposal_builder: &VotingProposalBuilder) { + self.voting_proposals = Some(voting_proposal_builder.clone()); } pub fn get_auxiliary_data(&self) -> Option { @@ -1263,7 +1285,8 @@ impl TransactionBuilder { collateral_return: None, total_collateral: None, reference_inputs: HashSet::new(), - voting: None, + voting_procedures: None, + voting_proposals: None, } } @@ -1291,8 +1314,14 @@ impl TransactionBuilder { } } - if let Some(votig) = &self.voting { - for input in votig.get_ref_inputs().0 { + if let Some(voting_procedures) = &self.voting_procedures { + for input in voting_procedures.get_ref_inputs().0 { + inputs.insert(input); + } + } + + if let Some(voting_proposals) = &self.voting_proposals { + for input in voting_proposals.get_ref_inputs().0 { inputs.insert(input); } } @@ -1784,15 +1813,20 @@ impl TransactionBuilder { used_langs.append(&mut certs_builder.get_used_plutus_lang_versions()); plutus_witnesses.0.append(&mut certs_builder.get_plutus_witnesses().0) } - if let Some(withdrawals_builder) = self.withdrawals.clone() { + if let Some(withdrawals_builder) = &self.withdrawals { used_langs.append(&mut withdrawals_builder.get_used_plutus_lang_versions()); plutus_witnesses.0.append(&mut withdrawals_builder.get_plutus_witnesses().0) } - if let Some(voting_builder) = self.voting.clone() { + if let Some(voting_builder) = &self.voting_procedures { used_langs.append(&mut voting_builder.get_used_plutus_lang_versions()); plutus_witnesses.0.append(&mut voting_builder.get_plutus_witnesses().0) } + if let Some(voting_proposal_builder) = &self.voting_proposals { + used_langs.append(&mut voting_proposal_builder.get_used_plutus_lang_versions()); + plutus_witnesses.0.append(&mut voting_proposal_builder.get_plutus_witnesses().0) + } + if plutus_witnesses.len() > 0 { let (_scripts, datums, redeemers) = plutus_witnesses.collect(); for lang in used_langs { @@ -1857,7 +1891,8 @@ impl TransactionBuilder { collateral_return: self.collateral_return.clone(), total_collateral: self.total_collateral.clone(), reference_inputs: self.get_reference_inputs().to_option(), - voting_procedures: self.voting.as_ref().map(|x| x.build()), + voting_procedures: self.voting_procedures.as_ref().map(|x| x.build()), + voting_proposals: self.voting_proposals.as_ref().map(|x| x.build()), }; // we must build a tx with fake data (of correct size) to check the final Transaction size let full_tx = fake_full_tx(self, built)?; @@ -1915,7 +1950,7 @@ impl TransactionBuilder { ns.add(s); }); } - if let Some(voting_builder) = &self.voting { + if let Some(voting_builder) = &self.voting_procedures { voting_builder.get_native_scripts().0.iter().for_each(|s| { ns.add(s); }); @@ -1955,11 +1990,16 @@ impl TransactionBuilder { res.add(s); }) } - if let Some(voting_builder) = &self.voting { + if let Some(voting_builder) = &self.voting_procedures { voting_builder.get_plutus_witnesses().0.iter().for_each(|s| { res.add(s); }) } + if let Some(voting_proposal_builder) = &self.voting_proposals { + voting_proposal_builder.get_plutus_witnesses().0.iter().for_each(|s| { + res.add(s); + }) + } if res.len() > 0 { Some(res) } else { @@ -2000,7 +2040,10 @@ impl TransactionBuilder { if self.withdrawals.as_ref().map_or(false, |w| w.has_plutus_scripts()) { return true; } - if self.voting.as_ref().map_or(false, |w| w.has_plutus_scripts()) { + if self.voting_procedures.as_ref().map_or(false, |w| w.has_plutus_scripts()) { + return true; + } + if self.voting_proposals.as_ref().map_or(false, |w| w.has_plutus_scripts()) { return true; } @@ -2123,6 +2166,7 @@ mod tests { .fee_algo(linear_fee) .pool_deposit(&to_bignum(pool_deposit)) .key_deposit(&to_bignum(key_deposit)) + .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(max_val_size) .max_tx_size(MAX_TX_SIZE) .coins_per_utxo_word(&to_bignum(coins_per_utxo_word)) @@ -2176,6 +2220,7 @@ mod tests { .fee_algo(linear_fee) .pool_deposit(&to_bignum(1)) .key_deposit(&to_bignum(1)) + .voting_proposal_deposit(&to_bignum(1)) .max_value_size(MAX_VALUE_SIZE) .max_tx_size(MAX_TX_SIZE) .coins_per_utxo_word(&to_bignum(8)) @@ -4648,6 +4693,7 @@ mod tests { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(0)) .key_deposit(&to_bignum(0)) + .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(9999) .max_tx_size(9999) .coins_per_utxo_word(&Coin::zero()) @@ -4687,6 +4733,7 @@ mod tests { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(0)) .key_deposit(&to_bignum(0)) + .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(9999) .max_tx_size(9999) .coins_per_utxo_word(&Coin::zero()) @@ -5012,6 +5059,7 @@ mod tests { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(0)) .key_deposit(&to_bignum(0)) + .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(max_value_size) .max_tx_size(MAX_TX_SIZE) .coins_per_utxo_word(&to_bignum(8)) diff --git a/rust/src/tx_builder/test_batch.rs b/rust/src/tx_builder/test_batch.rs index 951d2168..7e762d64 100644 --- a/rust/src/tx_builder/test_batch.rs +++ b/rust/src/tx_builder/test_batch.rs @@ -245,6 +245,7 @@ mod test { .max_value_size(4000) .max_tx_size(8000) .coins_per_utxo_word(&to_bignum(34_482)) + .voting_proposal_deposit(&to_bignum(500000000)) .ex_unit_prices(&ExUnitPrices::new( &SubCoin::new(&to_bignum(577), &to_bignum(10000)), &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), @@ -274,6 +275,7 @@ mod test { .max_value_size(4000) .max_tx_size(8000) .coins_per_utxo_word(&to_bignum(34_482)) + .voting_proposal_deposit(&to_bignum(500000000)) .ex_unit_prices(&ExUnitPrices::new( &SubCoin::new(&to_bignum(577), &to_bignum(10000)), &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), @@ -313,8 +315,10 @@ mod test { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(4000) .max_tx_size(8000) + .voting_proposal_deposit(&to_bignum(500000000)) .coins_per_utxo_word(&to_bignum(34_482)) .ex_unit_prices(&ExUnitPrices::new( &SubCoin::new(&to_bignum(577), &to_bignum(10000)), @@ -377,6 +381,7 @@ mod test { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(80) .max_tx_size(8000) .coins_per_utxo_word(&to_bignum(34_482)) @@ -453,6 +458,7 @@ mod test { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(80) .max_tx_size(300) .coins_per_utxo_word(&to_bignum(34_482)) @@ -508,6 +514,7 @@ mod test { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(4000) .max_tx_size(8000) .coins_per_utxo_word(&to_bignum(34_482)) @@ -550,6 +557,7 @@ mod test { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(4000) .max_tx_size(8000) .coins_per_utxo_word(&to_bignum(34_482)) @@ -585,6 +593,7 @@ mod test { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(10) .max_tx_size(8000000) .coins_per_utxo_word(&to_bignum(34_482)) @@ -620,6 +629,7 @@ mod test { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(100) .max_tx_size(2000) .coins_per_utxo_word(&to_bignum(34_482)) @@ -643,6 +653,7 @@ mod test { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(10) .max_tx_size(8000000) .coins_per_utxo_word(&to_bignum(34_482)) @@ -682,6 +693,7 @@ mod test { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(10) .max_tx_size(8000000) .coins_per_utxo_word(&to_bignum(34_482)) @@ -739,6 +751,7 @@ mod test { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(4000) .max_tx_size(8000) .coins_per_utxo_word(&to_bignum(34_482)) diff --git a/rust/src/tx_builder/vote_builder.rs b/rust/src/tx_builder/voting_builder.rs similarity index 100% rename from rust/src/tx_builder/vote_builder.rs rename to rust/src/tx_builder/voting_builder.rs diff --git a/rust/src/tx_builder/voting_proposal_builder.rs b/rust/src/tx_builder/voting_proposal_builder.rs new file mode 100644 index 00000000..13f8b56c --- /dev/null +++ b/rust/src/tx_builder/voting_proposal_builder.rs @@ -0,0 +1,108 @@ +use crate::tx_builder::script_structs::*; +use crate::*; +use std::collections::BTreeMap; + +#[wasm_bindgen] +#[derive(Clone, Debug)] +pub struct VotingProposalBuilder { + votes: BTreeMap>, +} + +#[wasm_bindgen] +impl VotingProposalBuilder { + pub fn new() -> Self { + Self { + votes: BTreeMap::new(), + } + } + + pub fn add( + &mut self, + proposal: VotingProposal, + ) -> Result<(), JsError> { + + self.votes.insert( + proposal, + None, + ); + + Ok(()) + } + + pub fn add_with_plutus_witness( + &mut self, + proposal: VotingProposal, + witness: &PlutusWitness, + ) -> Result<(), JsError> { + + self.votes.insert( + proposal, + Some(ScriptWitnessType::PlutusScriptWitness(witness.clone())), + ); + Ok(()) + } + + pub fn get_plutus_witnesses(&self) -> PlutusWitnesses { + let tag = RedeemerTag::new_vote(); + let mut scripts = PlutusWitnesses::new(); + for (i, (_, script_wit)) in self.votes.iter().enumerate() { + if let Some(ScriptWitnessType::PlutusScriptWitness(s)) = script_wit { + let index = BigNum::from(i); + scripts.add(&s.clone_with_redeemer_index_and_tag(&index, &tag)); + } + } + scripts + } + + pub fn get_ref_inputs(&self) -> TransactionInputs { + let mut inputs = Vec::new(); + for (_, script_wit) in &self.votes { + match script_wit { + Some(ScriptWitnessType::NativeScriptWitness(script_source)) => { + if let NativeScriptSourceEnum::RefInput(input, _, _) = script_source { + inputs.push(input.clone()); + } + } + Some(ScriptWitnessType::PlutusScriptWitness(plutus_witness)) => { + if let Some(DatumSourceEnum::RefInput(input)) = &plutus_witness.datum { + inputs.push(input.clone()); + } + if let PlutusScriptSourceEnum::RefInput(input, _, _) = &plutus_witness.script { + inputs.push(input.clone()); + } + } + None => {} + } + } + TransactionInputs(inputs) + } + + pub(crate) fn get_used_plutus_lang_versions(&self) -> BTreeSet { + let mut used_langs = BTreeSet::new(); + for (_, script_wit) in &self.votes { + if let Some(ScriptWitnessType::PlutusScriptWitness(s)) = script_wit { + if let Some(lang) = s.script.language() { + used_langs.insert(lang.clone()); + } + } + } + used_langs + } + + pub fn has_plutus_scripts(&self) -> bool { + for (_, script_wit) in &self.votes { + if let Some(ScriptWitnessType::PlutusScriptWitness(_)) = script_wit { + return true; + } + } + false + } + + pub fn build(&self) -> VotingProposals { + let mut proposals = Vec::new(); + for (voter, _) in &self.votes { + proposals.push(voter.clone()); + } + VotingProposals(proposals) + } +} From 4827fe985d7525c7aa9e2d79bee0de38c0bbb130 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 21 Aug 2023 19:20:57 +0400 Subject: [PATCH 074/349] update schema gen --- rust/json-gen/src/main.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/rust/json-gen/src/main.rs b/rust/json-gen/src/main.rs index d8750e6c..400c617e 100644 --- a/rust/json-gen/src/main.rs +++ b/rust/json-gen/src/main.rs @@ -160,6 +160,10 @@ fn main() { gen_json_schema!(DRep); gen_json_schema!(Anchor); + gen_json_schema!(Voter); + gen_json_schema!(GovernanceActionId); + gen_json_schema!(VotingProcedure); + gen_json_schema!(VotingProcedures); gen_json_schema!(CommitteeHotKeyDeregistration); gen_json_schema!(CommitteeHotKeyRegistration); gen_json_schema!(DrepDeregistration); @@ -170,4 +174,16 @@ fn main() { gen_json_schema!(StakeVoteRegistrationAndDelegation); gen_json_schema!(VoteDelegation); gen_json_schema!(VoteRegistrationAndDelegation); + + gen_json_schema!(VotingProposal); + gen_json_schema!(VotingProposals); + gen_json_schema!(HardForkInitiationProposal); + gen_json_schema!(NewCommitteeProposal); + gen_json_schema!(NewConstitutionProposal); + gen_json_schema!(NoConfidenceProposal); + gen_json_schema!(ParameterChangeProposal); + gen_json_schema!(TreasuryWithdrawals); + gen_json_schema!(TreasuryWithdrawalsProposal); + gen_json_schema!(Committee); + gen_json_schema!(Constitution); } From 278b6d998d218dc4c8bc3fb398fc9309329ea0d9 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 21 Aug 2023 19:21:06 +0400 Subject: [PATCH 075/349] update js flow --- rust/pkg/cardano_serialization_lib.js.flow | 10633 ++++++++++++------- 1 file changed, 6623 insertions(+), 4010 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 83827fb1..104bbe76 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -6,28 +6,31 @@ */ /** - * @param {string} password - * @param {string} salt - * @param {string} nonce - * @param {string} data - * @returns {string} + * @param {Transaction} tx + * @param {LinearFee} linear_fee + * @returns {BigNum} */ -declare export function encrypt_with_password( - password: string, - salt: string, - nonce: string, - data: string -): string; +declare export function min_fee(tx: Transaction, linear_fee: LinearFee): BigNum; /** - * @param {string} password - * @param {string} data - * @returns {string} + * @param {ExUnits} ex_units + * @param {ExUnitPrices} ex_unit_prices + * @returns {BigNum} */ -declare export function decrypt_with_password( - password: string, - data: string -): string; +declare export function calculate_ex_units_ceil_cost( + ex_units: ExUnits, + ex_unit_prices: ExUnitPrices +): BigNum; + +/** + * @param {Transaction} tx + * @param {ExUnitPrices} ex_unit_prices + * @returns {BigNum} + */ +declare export function min_script_fee( + tx: Transaction, + ex_unit_prices: ExUnitPrices +): BigNum; /** * @param {Address} address @@ -179,6 +182,30 @@ declare export function encode_json_str_to_native_script( schema: number ): NativeScript; +/** + * @param {string} password + * @param {string} salt + * @param {string} nonce + * @param {string} data + * @returns {string} + */ +declare export function encrypt_with_password( + password: string, + salt: string, + nonce: string, + data: string +): string; + +/** + * @param {string} password + * @param {string} data + * @returns {string} + */ +declare export function decrypt_with_password( + password: string, + data: string +): string; + /** * @param {string} json * @param {number} schema @@ -236,43 +263,55 @@ declare export function decode_metadatum_to_json_str( ): string; /** - * @param {Transaction} tx - * @param {LinearFee} linear_fee - * @returns {BigNum} */ -declare export function min_fee(tx: Transaction, linear_fee: LinearFee): BigNum; + +declare export var RelayKind: {| + +SingleHostAddr: 0, // 0 + +SingleHostName: 1, // 1 + +MultiHostName: 2, // 2 +|}; /** - * @param {ExUnits} ex_units - * @param {ExUnitPrices} ex_unit_prices - * @returns {BigNum} */ -declare export function calculate_ex_units_ceil_cost( - ex_units: ExUnits, - ex_unit_prices: ExUnitPrices -): BigNum; + +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 +|}; /** - * @param {Transaction} tx - * @param {ExUnitPrices} ex_unit_prices - * @returns {BigNum} + * Each new language uses a different namespace for hashing its script + * This is because you could have a language where the same bytes have different semantics + * So this avoids scripts in different languages mapping to the same hash + * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export function min_script_fee( - tx: Transaction, - ex_unit_prices: ExUnitPrices -): BigNum; + +declare export var ScriptHashNamespace: {| + +NativeScript: 0, // 0 + +PlutusScript: 1, // 1 + +PlutusScriptV2: 2, // 2 +|}; /** */ -declare export var CertificateKind: {| - +StakeRegistration: 0, // 0 - +StakeDeregistration: 1, // 1 - +StakeDelegation: 2, // 2 - +PoolRegistration: 3, // 3 - +PoolRetirement: 4, // 4 - +GenesisKeyDelegation: 5, // 5 - +MoveInstantaneousRewardsCert: 6, // 6 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 +|}; + +/** + */ + +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 |}; /** @@ -294,52 +333,79 @@ declare export var MIRKind: {| /** */ -declare export var RelayKind: {| - +SingleHostAddr: 0, // 0 - +SingleHostName: 1, // 1 - +MultiHostName: 2, // 2 +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 |}; /** */ -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 |}; /** - * Each new language uses a different namespace for hashing its script - * This is because you could have a language where the same bytes have different semantics - * So this avoids scripts in different languages mapping to the same hash - * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var ScriptHashNamespace: {| - +NativeScript: 0, // 0 - +PlutusScript: 1, // 1 - +PlutusScriptV2: 2, // 2 +declare export var StakeCredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** + * Used to choosed the schema for a script JSON string */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** - * Used to choosed the schema for a script JSON string */ -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 +|}; + +/** + */ + +declare export var CertificateKind: {| + +StakeRegistration: 0, // 0 + +StakeDeregistration: 1, // 1 + +StakeDelegation: 2, // 2 + +PoolRegistration: 3, // 3 + +PoolRetirement: 4, // 4 + +GenesisKeyDelegation: 5, // 5 + +MoveInstantaneousRewardsCert: 6, // 6 + +CommitteeHotKeyRegistration: 7, // 7 + +CommitteeHotKeyDeregistration: 8, // 8 + +DrepDeregistration: 9, // 9 + +DrepRegistration: 10, // 10 + +DrepUpdate: 11, // 11 + +StakeAndVoteDelegation: 12, // 12 + +StakeRegistrationAndDelegation: 13, // 13 + +StakeVoteRegistrationAndDelegation: 14, // 14 + +VoteDelegation: 15, // 15 + +VoteRegistrationAndDelegation: 16, // 16 +|}; + +/** + */ + +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** @@ -369,6 +435,7 @@ declare export var RedeemerTagKind: {| +Mint: 1, // 1 +Cert: 2, // 2 +Reward: 3, // 3 + +Vote: 4, // 4 |}; /** @@ -411,27 +478,14 @@ declare export var MetadataJsonSchema: {| /** */ -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 -|}; - -/** - */ - -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 -|}; - -/** - */ - -declare export var StakeCredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 +declare export var VotingProposalKind: {| + +ParameterChangeProposal: 0, // 0 + +HardForkInitiationProposal: 1, // 1 + +TreasuryWithdrawalsProposal: 2, // 2 + +NoConfidenceProposal: 3, // 3 + +NewCommitteeProposal: 4, // 4 + +NewConstitutionProposal: 5, // 5 + +InfoProposal: 6, // 6 |}; /** @@ -494,6 +548,67 @@ declare export class Address { */ network_id(): number; } +/** + */ +declare export class Anchor { + free(): void; + + /** + * @returns {URL} + */ + anchor_url(): URL; + + /** + * @returns {AnchorDataHash} + */ + anchor_data_hash(): AnchorDataHash; + + /** + * @param {URL} anchor_url + * @param {AnchorDataHash} anchor_data_hash + * @returns {Anchor} + */ + static new(anchor_url: URL, anchor_data_hash: AnchorDataHash): Anchor; +} +/** + */ +declare export class AnchorDataHash { + free(): void; + + /** + * @param {Uint8Array} bytes + * @returns {AnchorDataHash} + */ + static from_bytes(bytes: Uint8Array): AnchorDataHash; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {string} prefix + * @returns {string} + */ + to_bech32(prefix: string): string; + + /** + * @param {string} bech_str + * @returns {AnchorDataHash} + */ + static from_bech32(bech_str: string): AnchorDataHash; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex + * @returns {AnchorDataHash} + */ + static from_hex(hex: string): AnchorDataHash; +} /** */ declare export class AssetName { @@ -1684,14 +1799,90 @@ declare export class Certificate { ): Certificate; /** - * @returns {number} + * @param {CommitteeHotKeyRegistration} committee_hot_key_registration + * @returns {Certificate} */ - kind(): number; + static new_committee_hot_key_registration( + committee_hot_key_registration: CommitteeHotKeyRegistration + ): Certificate; /** - * @returns {StakeRegistration | void} + * @param {CommitteeHotKeyDeregistration} committee_hot_key_deregistration + * @returns {Certificate} */ - as_stake_registration(): StakeRegistration | void; + static new_committee_hot_key_deregistration( + committee_hot_key_deregistration: CommitteeHotKeyDeregistration + ): Certificate; + + /** + * @param {DrepDeregistration} drep_deregistration + * @returns {Certificate} + */ + static new_drep_deregistration( + drep_deregistration: DrepDeregistration + ): Certificate; + + /** + * @param {DrepRegistration} drep_registration + * @returns {Certificate} + */ + static new_drep_registration( + drep_registration: DrepRegistration + ): Certificate; + + /** + * @param {DrepUpdate} drep_update + * @returns {Certificate} + */ + static new_drep_update(drep_update: DrepUpdate): Certificate; + + /** + * @param {StakeAndVoteDelegation} stake_and_vote_delegation + * @returns {Certificate} + */ + static new_stake_and_vote_delegation( + stake_and_vote_delegation: StakeAndVoteDelegation + ): Certificate; + + /** + * @param {StakeRegistrationAndDelegation} stake_registration_and_delegation + * @returns {Certificate} + */ + static new_stake_registration_and_delegation( + stake_registration_and_delegation: StakeRegistrationAndDelegation + ): Certificate; + + /** + * @param {StakeVoteRegistrationAndDelegation} stake_vote_registration_and_delegation + * @returns {Certificate} + */ + static new_stake_vote_registration_and_delegation( + stake_vote_registration_and_delegation: StakeVoteRegistrationAndDelegation + ): Certificate; + + /** + * @param {VoteDelegation} vote_delegation + * @returns {Certificate} + */ + static new_vote_delegation(vote_delegation: VoteDelegation): Certificate; + + /** + * @param {VoteRegistrationAndDelegation} vote_registration_and_delegation + * @returns {Certificate} + */ + static new_vote_registration_and_delegation( + vote_registration_and_delegation: VoteRegistrationAndDelegation + ): Certificate; + + /** + * @returns {number} + */ + kind(): number; + + /** + * @returns {StakeRegistration | void} + */ + as_stake_registration(): StakeRegistration | void; /** * @returns {StakeDeregistration | void} @@ -1722,6 +1913,61 @@ declare export class Certificate { * @returns {MoveInstantaneousRewardsCert | void} */ as_move_instantaneous_rewards_cert(): MoveInstantaneousRewardsCert | void; + + /** + * @returns {CommitteeHotKeyRegistration | void} + */ + as_committee_hot_key_registration(): CommitteeHotKeyRegistration | void; + + /** + * @returns {CommitteeHotKeyDeregistration | void} + */ + as_committee_hot_key_deregistration(): CommitteeHotKeyDeregistration | void; + + /** + * @returns {DrepDeregistration | void} + */ + as_drep_deregistration(): DrepDeregistration | void; + + /** + * @returns {DrepRegistration | void} + */ + as_drep_registration(): DrepRegistration | void; + + /** + * @returns {DrepUpdate | void} + */ + as_drep_update(): DrepUpdate | void; + + /** + * @returns {StakeAndVoteDelegation | void} + */ + as_stake_and_vote_delegation(): StakeAndVoteDelegation | void; + + /** + * @returns {StakeRegistrationAndDelegation | void} + */ + as_stake_registration_and_delegation(): StakeRegistrationAndDelegation | void; + + /** + * @returns {StakeVoteRegistrationAndDelegation | void} + */ + as_stake_vote_registration_and_delegation(): StakeVoteRegistrationAndDelegation | void; + + /** + * @returns {VoteDelegation | void} + */ + as_vote_delegation(): VoteDelegation | void; + + /** + * @returns {VoteRegistrationAndDelegation | void} + */ + as_vote_registration_and_delegation(): VoteRegistrationAndDelegation | void; + + /** + * @returns {boolean} + */ + has_required_script_witness(): boolean; } /** */ @@ -1789,51 +2035,76 @@ declare export class Certificates { } /** */ -declare export class ConstrPlutusData { +declare export class CertificatesBuilder { free(): void; /** - * @returns {Uint8Array} + * @returns {CertificatesBuilder} */ - to_bytes(): Uint8Array; + static new(): CertificatesBuilder; /** - * @param {Uint8Array} bytes - * @returns {ConstrPlutusData} + * @param {Certificate} cert */ - static from_bytes(bytes: Uint8Array): ConstrPlutusData; + add(cert: Certificate): void; /** - * @returns {string} + * @param {Certificate} cert + * @param {PlutusWitness} witness */ - to_hex(): string; + add_with_plutus_witness(cert: Certificate, witness: PlutusWitness): void; /** - * @param {string} hex_str - * @returns {ConstrPlutusData} + * @param {Certificate} cert + * @param {NativeScriptSource} native_script_source */ - static from_hex(hex_str: string): ConstrPlutusData; + add_with_native_script( + cert: Certificate, + native_script_source: NativeScriptSource + ): void; + + /** + * @returns {PlutusWitnesses} + */ + get_plutus_witnesses(): PlutusWitnesses; + + /** + * @returns {TransactionInputs} + */ + get_ref_inputs(): TransactionInputs; + + /** + * @returns {NativeScripts} + */ + get_native_scripts(): NativeScripts; + + /** + * @param {BigNum} pool_deposit + * @param {BigNum} key_deposit + * @returns {Value} + */ + get_certificates_refund(pool_deposit: BigNum, key_deposit: BigNum): Value; /** + * @param {BigNum} pool_deposit + * @param {BigNum} key_deposit * @returns {BigNum} */ - alternative(): BigNum; + get_certificates_deposit(pool_deposit: BigNum, key_deposit: BigNum): BigNum; /** - * @returns {PlutusList} + * @returns {boolean} */ - data(): PlutusList; + has_plutus_scripts(): boolean; /** - * @param {BigNum} alternative - * @param {PlutusList} data - * @returns {ConstrPlutusData} + * @returns {Certificates} */ - static new(alternative: BigNum, data: PlutusList): ConstrPlutusData; + build(): Certificates; } /** */ -declare export class CostModel { +declare export class Committee { free(): void; /** @@ -1843,9 +2114,9 @@ declare export class CostModel { /** * @param {Uint8Array} bytes - * @returns {CostModel} + * @returns {Committee} */ - static from_bytes(bytes: Uint8Array): CostModel; + static from_bytes(bytes: Uint8Array): Committee; /** * @returns {string} @@ -1854,9 +2125,9 @@ declare export class CostModel { /** * @param {string} hex_str - * @returns {CostModel} + * @returns {Committee} */ - static from_hex(hex_str: string): CostModel; + static from_hex(hex_str: string): Committee; /** * @returns {string} @@ -1864,46 +2135,47 @@ declare export class CostModel { to_json(): string; /** - * @returns {CostModelJSON} + * @returns {CommitteeJSON} */ - to_js_value(): CostModelJSON; + to_js_value(): CommitteeJSON; /** * @param {string} json - * @returns {CostModel} + * @returns {Committee} */ - static from_json(json: string): CostModel; + static from_json(json: string): Committee; /** - * Creates a new CostModels instance of an unrestricted length - * @returns {CostModel} + * @param {UnitInterval} quorum_threshold + * @returns {Committee} */ - static new(): CostModel; + static new(quorum_threshold: UnitInterval): Committee; /** - * Sets the cost at the specified index to the specified value. - * In case the operation index is larger than the previous largest used index, - * it will fill any inbetween indexes with zeroes - * @param {number} operation - * @param {Int} cost - * @returns {Int} + * @returns {StakeCredentials} */ - set(operation: number, cost: Int): Int; + members_keys(): StakeCredentials; /** - * @param {number} operation - * @returns {Int} + * @returns {UnitInterval} */ - get(operation: number): Int; + quorum_threshold(): UnitInterval; /** - * @returns {number} + * @param {StakeCredential} committee_cold_credential + * @param {number} epoch */ - len(): number; + add_member(committee_cold_credential: StakeCredential, epoch: number): void; + + /** + * @param {StakeCredential} committee_cold_credential + * @returns {number | void} + */ + get_member_epoch(committee_cold_credential: StakeCredential): number | void; } /** */ -declare export class Costmdls { +declare export class CommitteeHotKeyDeregistration { free(): void; /** @@ -1913,9 +2185,9 @@ declare export class Costmdls { /** * @param {Uint8Array} bytes - * @returns {Costmdls} + * @returns {CommitteeHotKeyDeregistration} */ - static from_bytes(bytes: Uint8Array): Costmdls; + static from_bytes(bytes: Uint8Array): CommitteeHotKeyDeregistration; /** * @returns {string} @@ -1924,9 +2196,9 @@ declare export class Costmdls { /** * @param {string} hex_str - * @returns {Costmdls} + * @returns {CommitteeHotKeyDeregistration} */ - static from_hex(hex_str: string): Costmdls; + static from_hex(hex_str: string): CommitteeHotKeyDeregistration; /** * @returns {string} @@ -1934,53 +2206,37 @@ declare export class Costmdls { to_json(): string; /** - * @returns {CostmdlsJSON} + * @returns {CommitteeHotKeyDeregistrationJSON} */ - to_js_value(): CostmdlsJSON; + to_js_value(): CommitteeHotKeyDeregistrationJSON; /** * @param {string} json - * @returns {Costmdls} - */ - static from_json(json: string): Costmdls; - - /** - * @returns {Costmdls} - */ - static new(): Costmdls; - - /** - * @returns {number} - */ - len(): number; - - /** - * @param {Language} key - * @param {CostModel} value - * @returns {CostModel | void} + * @returns {CommitteeHotKeyDeregistration} */ - insert(key: Language, value: CostModel): CostModel | void; + static from_json(json: string): CommitteeHotKeyDeregistration; /** - * @param {Language} key - * @returns {CostModel | void} + * @returns {StakeCredential} */ - get(key: Language): CostModel | void; + committee_cold_key(): StakeCredential; /** - * @returns {Languages} + * @param {StakeCredential} committee_cold_key + * @returns {CommitteeHotKeyDeregistration} */ - keys(): Languages; + static new( + committee_cold_key: StakeCredential + ): CommitteeHotKeyDeregistration; /** - * @param {Languages} languages - * @returns {Costmdls} + * @returns {boolean} */ - retain_language_versions(languages: Languages): Costmdls; + has_script_credentials(): boolean; } /** */ -declare export class DNSRecordAorAAAA { +declare export class CommitteeHotKeyRegistration { free(): void; /** @@ -1990,9 +2246,9 @@ declare export class DNSRecordAorAAAA { /** * @param {Uint8Array} bytes - * @returns {DNSRecordAorAAAA} + * @returns {CommitteeHotKeyRegistration} */ - static from_bytes(bytes: Uint8Array): DNSRecordAorAAAA; + static from_bytes(bytes: Uint8Array): CommitteeHotKeyRegistration; /** * @returns {string} @@ -2001,9 +2257,9 @@ declare export class DNSRecordAorAAAA { /** * @param {string} hex_str - * @returns {DNSRecordAorAAAA} + * @returns {CommitteeHotKeyRegistration} */ - static from_hex(hex_str: string): DNSRecordAorAAAA; + static from_hex(hex_str: string): CommitteeHotKeyRegistration; /** * @returns {string} @@ -2011,30 +2267,44 @@ declare export class DNSRecordAorAAAA { to_json(): string; /** - * @returns {DNSRecordAorAAAAJSON} + * @returns {CommitteeHotKeyRegistrationJSON} */ - to_js_value(): DNSRecordAorAAAAJSON; + to_js_value(): CommitteeHotKeyRegistrationJSON; /** * @param {string} json - * @returns {DNSRecordAorAAAA} + * @returns {CommitteeHotKeyRegistration} */ - static from_json(json: string): DNSRecordAorAAAA; + static from_json(json: string): CommitteeHotKeyRegistration; /** - * @param {string} dns_name - * @returns {DNSRecordAorAAAA} + * @returns {StakeCredential} */ - static new(dns_name: string): DNSRecordAorAAAA; + committee_cold_key(): StakeCredential; /** - * @returns {string} + * @returns {StakeCredential} */ - record(): string; + committee_hot_key(): StakeCredential; + + /** + * @param {StakeCredential} committee_cold_key + * @param {StakeCredential} committee_hot_key + * @returns {CommitteeHotKeyRegistration} + */ + static new( + committee_cold_key: StakeCredential, + committee_hot_key: StakeCredential + ): CommitteeHotKeyRegistration; + + /** + * @returns {boolean} + */ + has_script_credentials(): boolean; } /** */ -declare export class DNSRecordSRV { +declare export class Constitution { free(): void; /** @@ -2044,9 +2314,9 @@ declare export class DNSRecordSRV { /** * @param {Uint8Array} bytes - * @returns {DNSRecordSRV} + * @returns {Constitution} */ - static from_bytes(bytes: Uint8Array): DNSRecordSRV; + static from_bytes(bytes: Uint8Array): Constitution; /** * @returns {string} @@ -2055,9 +2325,9 @@ declare export class DNSRecordSRV { /** * @param {string} hex_str - * @returns {DNSRecordSRV} + * @returns {Constitution} */ - static from_hex(hex_str: string): DNSRecordSRV; + static from_hex(hex_str: string): Constitution; /** * @returns {string} @@ -2065,149 +2335,159 @@ declare export class DNSRecordSRV { to_json(): string; /** - * @returns {DNSRecordSRVJSON} + * @returns {ConstitutionJSON} */ - to_js_value(): DNSRecordSRVJSON; + to_js_value(): ConstitutionJSON; /** * @param {string} json - * @returns {DNSRecordSRV} - */ - static from_json(json: string): DNSRecordSRV; - - /** - * @param {string} dns_name - * @returns {DNSRecordSRV} + * @returns {Constitution} */ - static new(dns_name: string): DNSRecordSRV; + static from_json(json: string): Constitution; /** - * @returns {string} + * @returns {Anchor} */ - record(): string; -} -/** - */ -declare export class DataCost { - free(): void; + anchor(): Anchor; /** - * !!! DEPRECATED !!! - * Since babbage era we should use coins per byte. Use `.new_coins_per_byte` instead. - * @param {BigNum} coins_per_word - * @returns {DataCost} + * @returns {ScriptHash | void} */ - static new_coins_per_word(coins_per_word: BigNum): DataCost; + script_hash(): ScriptHash | void; /** - * @param {BigNum} coins_per_byte - * @returns {DataCost} + * @param {Anchor} anchor + * @returns {Constitution} */ - static new_coins_per_byte(coins_per_byte: BigNum): DataCost; + static new(anchor: Anchor): Constitution; /** - * @returns {BigNum} + * @param {Anchor} anchor + * @param {ScriptHash} script_hash + * @returns {Constitution} */ - coins_per_byte(): BigNum; + static new_with_script_hash( + anchor: Anchor, + script_hash: ScriptHash + ): Constitution; } /** */ -declare export class DataHash { +declare export class ConstrPlutusData { free(): void; /** - * @param {Uint8Array} bytes - * @returns {DataHash} + * @returns {Uint8Array} */ - static from_bytes(bytes: Uint8Array): DataHash; + to_bytes(): Uint8Array; /** - * @returns {Uint8Array} + * @param {Uint8Array} bytes + * @returns {ConstrPlutusData} */ - to_bytes(): Uint8Array; + static from_bytes(bytes: Uint8Array): ConstrPlutusData; /** - * @param {string} prefix * @returns {string} */ - to_bech32(prefix: string): string; + to_hex(): string; /** - * @param {string} bech_str - * @returns {DataHash} + * @param {string} hex_str + * @returns {ConstrPlutusData} */ - static from_bech32(bech_str: string): DataHash; + static from_hex(hex_str: string): ConstrPlutusData; /** - * @returns {string} + * @returns {BigNum} */ - to_hex(): string; + alternative(): BigNum; /** - * @param {string} hex - * @returns {DataHash} + * @returns {PlutusList} */ - static from_hex(hex: string): DataHash; + data(): PlutusList; + + /** + * @param {BigNum} alternative + * @param {PlutusList} data + * @returns {ConstrPlutusData} + */ + static new(alternative: BigNum, data: PlutusList): ConstrPlutusData; } /** */ -declare export class DatumSource { +declare export class CostModel { free(): void; /** - * @param {PlutusData} datum - * @returns {DatumSource} + * @returns {Uint8Array} */ - static new(datum: PlutusData): DatumSource; + to_bytes(): Uint8Array; /** - * @param {TransactionInput} input - * @returns {DatumSource} + * @param {Uint8Array} bytes + * @returns {CostModel} */ - static new_ref_input(input: TransactionInput): DatumSource; -} -/** - */ -declare export class Ed25519KeyHash { - free(): void; + static from_bytes(bytes: Uint8Array): CostModel; /** - * @param {Uint8Array} bytes - * @returns {Ed25519KeyHash} + * @returns {string} */ - static from_bytes(bytes: Uint8Array): Ed25519KeyHash; + to_hex(): string; /** - * @returns {Uint8Array} + * @param {string} hex_str + * @returns {CostModel} */ - to_bytes(): Uint8Array; + static from_hex(hex_str: string): CostModel; /** - * @param {string} prefix * @returns {string} */ - to_bech32(prefix: string): string; + to_json(): string; /** - * @param {string} bech_str - * @returns {Ed25519KeyHash} + * @returns {CostModelJSON} */ - static from_bech32(bech_str: string): Ed25519KeyHash; + to_js_value(): CostModelJSON; /** - * @returns {string} + * @param {string} json + * @returns {CostModel} */ - to_hex(): string; + static from_json(json: string): CostModel; /** - * @param {string} hex - * @returns {Ed25519KeyHash} + * Creates a new CostModels instance of an unrestricted length + * @returns {CostModel} */ - static from_hex(hex: string): Ed25519KeyHash; + static new(): CostModel; + + /** + * Sets the cost at the specified index to the specified value. + * In case the operation index is larger than the previous largest used index, + * it will fill any inbetween indexes with zeroes + * @param {number} operation + * @param {Int} cost + * @returns {Int} + */ + set(operation: number, cost: Int): Int; + + /** + * @param {number} operation + * @returns {Int} + */ + get(operation: number): Int; + + /** + * @returns {number} + */ + len(): number; } /** */ -declare export class Ed25519KeyHashes { +declare export class Costmdls { free(): void; /** @@ -2217,9 +2497,9 @@ declare export class Ed25519KeyHashes { /** * @param {Uint8Array} bytes - * @returns {Ed25519KeyHashes} + * @returns {Costmdls} */ - static from_bytes(bytes: Uint8Array): Ed25519KeyHashes; + static from_bytes(bytes: Uint8Array): Costmdls; /** * @returns {string} @@ -2228,9 +2508,9 @@ declare export class Ed25519KeyHashes { /** * @param {string} hex_str - * @returns {Ed25519KeyHashes} + * @returns {Costmdls} */ - static from_hex(hex_str: string): Ed25519KeyHashes; + static from_hex(hex_str: string): Costmdls; /** * @returns {string} @@ -2238,20 +2518,20 @@ declare export class Ed25519KeyHashes { to_json(): string; /** - * @returns {Ed25519KeyHashesJSON} + * @returns {CostmdlsJSON} */ - to_js_value(): Ed25519KeyHashesJSON; + to_js_value(): CostmdlsJSON; /** * @param {string} json - * @returns {Ed25519KeyHashes} + * @returns {Costmdls} */ - static from_json(json: string): Ed25519KeyHashes; + static from_json(json: string): Costmdls; /** - * @returns {Ed25519KeyHashes} + * @returns {Costmdls} */ - static new(): Ed25519KeyHashes; + static new(): Costmdls; /** * @returns {number} @@ -2259,24 +2539,32 @@ declare export class Ed25519KeyHashes { len(): number; /** - * @param {number} index - * @returns {Ed25519KeyHash} + * @param {Language} key + * @param {CostModel} value + * @returns {CostModel | void} */ - get(index: number): Ed25519KeyHash; + insert(key: Language, value: CostModel): CostModel | void; /** - * @param {Ed25519KeyHash} elem + * @param {Language} key + * @returns {CostModel | void} */ - add(elem: Ed25519KeyHash): void; + get(key: Language): CostModel | void; /** - * @returns {Ed25519KeyHashes | void} + * @returns {Languages} */ - to_option(): Ed25519KeyHashes | void; + keys(): Languages; + + /** + * @param {Languages} languages + * @returns {Costmdls} + */ + retain_language_versions(languages: Languages): Costmdls; } /** */ -declare export class Ed25519Signature { +declare export class DNSRecordAorAAAA { free(): void; /** @@ -2285,9 +2573,10 @@ declare export class Ed25519Signature { to_bytes(): Uint8Array; /** - * @returns {string} + * @param {Uint8Array} bytes + * @returns {DNSRecordAorAAAA} */ - to_bech32(): string; + static from_bytes(bytes: Uint8Array): DNSRecordAorAAAA; /** * @returns {string} @@ -2295,54 +2584,41 @@ declare export class Ed25519Signature { to_hex(): string; /** - * @param {string} bech32_str - * @returns {Ed25519Signature} - */ - static from_bech32(bech32_str: string): Ed25519Signature; - - /** - * @param {string} input - * @returns {Ed25519Signature} + * @param {string} hex_str + * @returns {DNSRecordAorAAAA} */ - static from_hex(input: string): Ed25519Signature; + static from_hex(hex_str: string): DNSRecordAorAAAA; /** - * @param {Uint8Array} bytes - * @returns {Ed25519Signature} + * @returns {string} */ - static from_bytes(bytes: Uint8Array): Ed25519Signature; -} -/** - */ -declare export class EnterpriseAddress { - free(): void; + to_json(): string; /** - * @param {number} network - * @param {StakeCredential} payment - * @returns {EnterpriseAddress} + * @returns {DNSRecordAorAAAAJSON} */ - static new(network: number, payment: StakeCredential): EnterpriseAddress; + to_js_value(): DNSRecordAorAAAAJSON; /** - * @returns {StakeCredential} + * @param {string} json + * @returns {DNSRecordAorAAAA} */ - payment_cred(): StakeCredential; + static from_json(json: string): DNSRecordAorAAAA; /** - * @returns {Address} + * @param {string} dns_name + * @returns {DNSRecordAorAAAA} */ - to_address(): Address; + static new(dns_name: string): DNSRecordAorAAAA; /** - * @param {Address} addr - * @returns {EnterpriseAddress | void} + * @returns {string} */ - static from_address(addr: Address): EnterpriseAddress | void; + record(): string; } /** */ -declare export class ExUnitPrices { +declare export class DNSRecordSRV { free(): void; /** @@ -2352,9 +2628,9 @@ declare export class ExUnitPrices { /** * @param {Uint8Array} bytes - * @returns {ExUnitPrices} + * @returns {DNSRecordSRV} */ - static from_bytes(bytes: Uint8Array): ExUnitPrices; + static from_bytes(bytes: Uint8Array): DNSRecordSRV; /** * @returns {string} @@ -2363,9 +2639,9 @@ declare export class ExUnitPrices { /** * @param {string} hex_str - * @returns {ExUnitPrices} + * @returns {DNSRecordSRV} */ - static from_hex(hex_str: string): ExUnitPrices; + static from_hex(hex_str: string): DNSRecordSRV; /** * @returns {string} @@ -2373,36 +2649,30 @@ declare export class ExUnitPrices { to_json(): string; /** - * @returns {ExUnitPricesJSON} + * @returns {DNSRecordSRVJSON} */ - to_js_value(): ExUnitPricesJSON; + to_js_value(): DNSRecordSRVJSON; /** * @param {string} json - * @returns {ExUnitPrices} - */ - static from_json(json: string): ExUnitPrices; - - /** - * @returns {UnitInterval} + * @returns {DNSRecordSRV} */ - mem_price(): UnitInterval; + static from_json(json: string): DNSRecordSRV; /** - * @returns {UnitInterval} + * @param {string} dns_name + * @returns {DNSRecordSRV} */ - step_price(): UnitInterval; + static new(dns_name: string): DNSRecordSRV; /** - * @param {UnitInterval} mem_price - * @param {UnitInterval} step_price - * @returns {ExUnitPrices} + * @returns {string} */ - static new(mem_price: UnitInterval, step_price: UnitInterval): ExUnitPrices; + record(): string; } /** */ -declare export class ExUnits { +declare export class DRep { free(): void; /** @@ -2412,9 +2682,9 @@ declare export class ExUnits { /** * @param {Uint8Array} bytes - * @returns {ExUnits} + * @returns {DRep} */ - static from_bytes(bytes: Uint8Array): ExUnits; + static from_bytes(bytes: Uint8Array): DRep; /** * @returns {string} @@ -2423,9 +2693,9 @@ declare export class ExUnits { /** * @param {string} hex_str - * @returns {ExUnits} + * @returns {DRep} */ - static from_hex(hex_str: string): ExUnits; + static from_hex(hex_str: string): DRep; /** * @returns {string} @@ -2433,144 +2703,136 @@ declare export class ExUnits { to_json(): string; /** - * @returns {ExUnitsJSON} + * @returns {DRepJSON} */ - to_js_value(): ExUnitsJSON; + to_js_value(): DRepJSON; /** * @param {string} json - * @returns {ExUnits} + * @returns {DRep} */ - static from_json(json: string): ExUnits; + static from_json(json: string): DRep; /** - * @returns {BigNum} + * @param {Ed25519KeyHash} key_hash + * @returns {DRep} */ - mem(): BigNum; + static new_key_hash(key_hash: Ed25519KeyHash): DRep; /** - * @returns {BigNum} + * @param {ScriptHash} script_hash + * @returns {DRep} */ - steps(): BigNum; + static new_script_hash(script_hash: ScriptHash): DRep; /** - * @param {BigNum} mem - * @param {BigNum} steps - * @returns {ExUnits} + * @returns {DRep} */ - static new(mem: BigNum, steps: BigNum): ExUnits; -} -/** - */ -declare export class FixedTransaction { - free(): void; + static new_always_abstain(): DRep; /** - * @returns {Uint8Array} + * @returns {DRep} */ - to_bytes(): Uint8Array; + static new_always_no_confidence(): DRep; /** - * @param {Uint8Array} bytes - * @returns {FixedTransaction} - */ - static from_bytes(bytes: Uint8Array): FixedTransaction; - - /** - * @returns {string} - */ - to_hex(): string; - - /** - * @param {string} hex_str - * @returns {FixedTransaction} + * @returns {number} */ - static from_hex(hex_str: string): FixedTransaction; + kind(): number; /** - * @param {Uint8Array} raw_body - * @param {Uint8Array} raw_witness_set - * @param {boolean} is_valid - * @returns {FixedTransaction} + * @returns {Ed25519KeyHash | void} */ - static new( - raw_body: Uint8Array, - raw_witness_set: Uint8Array, - is_valid: boolean - ): FixedTransaction; + to_key_hash(): Ed25519KeyHash | void; /** - * @param {Uint8Array} raw_body - * @param {Uint8Array} raw_witness_set - * @param {Uint8Array} raw_auxiliary_data - * @param {boolean} is_valid - * @returns {FixedTransaction} + * @returns {ScriptHash | void} */ - static new_with_auxiliary( - raw_body: Uint8Array, - raw_witness_set: Uint8Array, - raw_auxiliary_data: Uint8Array, - is_valid: boolean - ): FixedTransaction; + to_script_hash(): ScriptHash | void; +} +/** + */ +declare export class DataCost { + free(): void; /** - * @returns {TransactionBody} + * !!! DEPRECATED !!! + * Since babbage era we should use coins per byte. Use `.new_coins_per_byte` instead. + * @param {BigNum} coins_per_word + * @returns {DataCost} */ - body(): TransactionBody; + static new_coins_per_word(coins_per_word: BigNum): DataCost; /** - * @returns {Uint8Array} + * @param {BigNum} coins_per_byte + * @returns {DataCost} */ - raw_body(): Uint8Array; + static new_coins_per_byte(coins_per_byte: BigNum): DataCost; /** - * @param {Uint8Array} raw_body + * @returns {BigNum} */ - set_body(raw_body: Uint8Array): void; + coins_per_byte(): BigNum; +} +/** + */ +declare export class DataHash { + free(): void; /** - * @param {Uint8Array} raw_witness_set + * @param {Uint8Array} bytes + * @returns {DataHash} */ - set_witness_set(raw_witness_set: Uint8Array): void; + static from_bytes(bytes: Uint8Array): DataHash; /** - * @returns {TransactionWitnessSet} + * @returns {Uint8Array} */ - witness_set(): TransactionWitnessSet; + to_bytes(): Uint8Array; /** - * @returns {Uint8Array} + * @param {string} prefix + * @returns {string} */ - raw_witness_set(): Uint8Array; + to_bech32(prefix: string): string; /** - * @param {boolean} valid + * @param {string} bech_str + * @returns {DataHash} */ - set_is_valid(valid: boolean): void; + static from_bech32(bech_str: string): DataHash; /** - * @returns {boolean} + * @returns {string} */ - is_valid(): boolean; + to_hex(): string; /** - * @param {Uint8Array} raw_auxiliary_data + * @param {string} hex + * @returns {DataHash} */ - set_auxiliary_data(raw_auxiliary_data: Uint8Array): void; + static from_hex(hex: string): DataHash; +} +/** + */ +declare export class DatumSource { + free(): void; /** - * @returns {AuxiliaryData | void} + * @param {PlutusData} datum + * @returns {DatumSource} */ - auxiliary_data(): AuxiliaryData | void; + static new(datum: PlutusData): DatumSource; /** - * @returns {Uint8Array | void} + * @param {TransactionInput} input + * @returns {DatumSource} */ - raw_auxiliary_data(): Uint8Array | void; + static new_ref_input(input: TransactionInput): DatumSource; } /** */ -declare export class GeneralTransactionMetadata { +declare export class DrepDeregistration { free(): void; /** @@ -2580,9 +2842,9 @@ declare export class GeneralTransactionMetadata { /** * @param {Uint8Array} bytes - * @returns {GeneralTransactionMetadata} + * @returns {DrepDeregistration} */ - static from_bytes(bytes: Uint8Array): GeneralTransactionMetadata; + static from_bytes(bytes: Uint8Array): DrepDeregistration; /** * @returns {string} @@ -2591,9 +2853,9 @@ declare export class GeneralTransactionMetadata { /** * @param {string} hex_str - * @returns {GeneralTransactionMetadata} + * @returns {DrepDeregistration} */ - static from_hex(hex_str: string): GeneralTransactionMetadata; + static from_hex(hex_str: string): DrepDeregistration; /** * @returns {string} @@ -2601,125 +2863,114 @@ declare export class GeneralTransactionMetadata { to_json(): string; /** - * @returns {GeneralTransactionMetadataJSON} + * @returns {DrepDeregistrationJSON} */ - to_js_value(): GeneralTransactionMetadataJSON; + to_js_value(): DrepDeregistrationJSON; /** * @param {string} json - * @returns {GeneralTransactionMetadata} - */ - static from_json(json: string): GeneralTransactionMetadata; - - /** - * @returns {GeneralTransactionMetadata} + * @returns {DrepDeregistration} */ - static new(): GeneralTransactionMetadata; + static from_json(json: string): DrepDeregistration; /** - * @returns {number} + * @returns {StakeCredential} */ - len(): number; + voting_credential(): StakeCredential; /** - * @param {BigNum} key - * @param {TransactionMetadatum} value - * @returns {TransactionMetadatum | void} + * @returns {BigNum} */ - insert(key: BigNum, value: TransactionMetadatum): TransactionMetadatum | void; + coin(): BigNum; /** - * @param {BigNum} key - * @returns {TransactionMetadatum | void} + * @param {StakeCredential} voting_credential + * @param {BigNum} coin + * @returns {DrepDeregistration} */ - get(key: BigNum): TransactionMetadatum | void; + static new( + voting_credential: StakeCredential, + coin: BigNum + ): DrepDeregistration; /** - * @returns {TransactionMetadatumLabels} + * @returns {boolean} */ - keys(): TransactionMetadatumLabels; + has_script_credentials(): boolean; } /** */ -declare export class GenesisDelegateHash { +declare export class DrepRegistration { free(): void; - /** - * @param {Uint8Array} bytes - * @returns {GenesisDelegateHash} - */ - static from_bytes(bytes: Uint8Array): GenesisDelegateHash; - /** * @returns {Uint8Array} */ to_bytes(): Uint8Array; /** - * @param {string} prefix - * @returns {string} + * @param {Uint8Array} bytes + * @returns {DrepRegistration} */ - to_bech32(prefix: string): string; + static from_bytes(bytes: Uint8Array): DrepRegistration; /** - * @param {string} bech_str - * @returns {GenesisDelegateHash} + * @returns {string} */ - static from_bech32(bech_str: string): GenesisDelegateHash; + to_hex(): string; /** - * @returns {string} + * @param {string} hex_str + * @returns {DrepRegistration} */ - to_hex(): string; + static from_hex(hex_str: string): DrepRegistration; /** - * @param {string} hex - * @returns {GenesisDelegateHash} + * @returns {string} */ - static from_hex(hex: string): GenesisDelegateHash; -} -/** - */ -declare export class GenesisHash { - free(): void; + to_json(): string; /** - * @param {Uint8Array} bytes - * @returns {GenesisHash} + * @returns {DrepRegistrationJSON} */ - static from_bytes(bytes: Uint8Array): GenesisHash; + to_js_value(): DrepRegistrationJSON; /** - * @returns {Uint8Array} + * @param {string} json + * @returns {DrepRegistration} */ - to_bytes(): Uint8Array; + static from_json(json: string): DrepRegistration; /** - * @param {string} prefix - * @returns {string} + * @returns {StakeCredential} */ - to_bech32(prefix: string): string; + voting_credential(): StakeCredential; /** - * @param {string} bech_str - * @returns {GenesisHash} + * @returns {BigNum} */ - static from_bech32(bech_str: string): GenesisHash; + coin(): BigNum; /** - * @returns {string} + * @returns {Anchor | void} */ - to_hex(): string; + anchor(): Anchor | void; /** - * @param {string} hex - * @returns {GenesisHash} + * @param {StakeCredential} voting_credential + * @param {BigNum} coin + * @param {Anchor | void} anchor + * @returns {DrepRegistration} */ - static from_hex(hex: string): GenesisHash; + static new( + voting_credential: StakeCredential, + coin: BigNum, + anchor?: Anchor + ): DrepRegistration; } /** */ -declare export class GenesisHashes { +declare export class DrepUpdate { free(): void; /** @@ -2729,9 +2980,9 @@ declare export class GenesisHashes { /** * @param {Uint8Array} bytes - * @returns {GenesisHashes} + * @returns {DrepUpdate} */ - static from_bytes(bytes: Uint8Array): GenesisHashes; + static from_bytes(bytes: Uint8Array): DrepUpdate; /** * @returns {string} @@ -2740,9 +2991,9 @@ declare export class GenesisHashes { /** * @param {string} hex_str - * @returns {GenesisHashes} + * @returns {DrepUpdate} */ - static from_hex(hex_str: string): GenesisHashes; + static from_hex(hex_str: string): DrepUpdate; /** * @returns {string} @@ -2750,110 +3001,149 @@ declare export class GenesisHashes { to_json(): string; /** - * @returns {GenesisHashesJSON} + * @returns {DrepUpdateJSON} */ - to_js_value(): GenesisHashesJSON; + to_js_value(): DrepUpdateJSON; /** * @param {string} json - * @returns {GenesisHashes} + * @returns {DrepUpdate} */ - static from_json(json: string): GenesisHashes; + static from_json(json: string): DrepUpdate; /** - * @returns {GenesisHashes} + * @returns {StakeCredential} */ - static new(): GenesisHashes; + voting_credential(): StakeCredential; /** - * @returns {number} + * @returns {Anchor | void} */ - len(): number; + anchor(): Anchor | void; /** - * @param {number} index - * @returns {GenesisHash} + * @param {StakeCredential} voting_credential + * @param {Anchor | void} anchor + * @returns {DrepUpdate} */ - get(index: number): GenesisHash; + static new(voting_credential: StakeCredential, anchor?: Anchor): DrepUpdate; /** - * @param {GenesisHash} elem + * @returns {boolean} */ - add(elem: GenesisHash): void; + has_script_credentials(): boolean; } /** */ -declare export class GenesisKeyDelegation { +declare export class Ed25519KeyHash { free(): void; /** - * @returns {Uint8Array} + * @param {Uint8Array} bytes + * @returns {Ed25519KeyHash} */ - to_bytes(): Uint8Array; + static from_bytes(bytes: Uint8Array): Ed25519KeyHash; /** - * @param {Uint8Array} bytes - * @returns {GenesisKeyDelegation} + * @returns {Uint8Array} */ - static from_bytes(bytes: Uint8Array): GenesisKeyDelegation; + to_bytes(): Uint8Array; /** + * @param {string} prefix * @returns {string} */ - to_hex(): string; + to_bech32(prefix: string): string; /** - * @param {string} hex_str - * @returns {GenesisKeyDelegation} + * @param {string} bech_str + * @returns {Ed25519KeyHash} */ - static from_hex(hex_str: string): GenesisKeyDelegation; + static from_bech32(bech_str: string): Ed25519KeyHash; /** * @returns {string} */ - to_json(): string; + to_hex(): string; /** - * @returns {GenesisKeyDelegationJSON} + * @param {string} hex + * @returns {Ed25519KeyHash} */ - to_js_value(): GenesisKeyDelegationJSON; + static from_hex(hex: string): Ed25519KeyHash; +} +/** + */ +declare export class Ed25519KeyHashes { + free(): void; /** - * @param {string} json - * @returns {GenesisKeyDelegation} + * @returns {Uint8Array} */ - static from_json(json: string): GenesisKeyDelegation; + to_bytes(): Uint8Array; /** - * @returns {GenesisHash} + * @param {Uint8Array} bytes + * @returns {Ed25519KeyHashes} */ - genesishash(): GenesisHash; + static from_bytes(bytes: Uint8Array): Ed25519KeyHashes; /** - * @returns {GenesisDelegateHash} + * @returns {string} */ - genesis_delegate_hash(): GenesisDelegateHash; + to_hex(): string; /** - * @returns {VRFKeyHash} + * @param {string} hex_str + * @returns {Ed25519KeyHashes} */ - vrf_keyhash(): VRFKeyHash; + static from_hex(hex_str: string): Ed25519KeyHashes; /** - * @param {GenesisHash} genesishash - * @param {GenesisDelegateHash} genesis_delegate_hash - * @param {VRFKeyHash} vrf_keyhash - * @returns {GenesisKeyDelegation} + * @returns {string} */ - static new( - genesishash: GenesisHash, - genesis_delegate_hash: GenesisDelegateHash, - vrf_keyhash: VRFKeyHash - ): GenesisKeyDelegation; + to_json(): string; + + /** + * @returns {Ed25519KeyHashesJSON} + */ + to_js_value(): Ed25519KeyHashesJSON; + + /** + * @param {string} json + * @returns {Ed25519KeyHashes} + */ + static from_json(json: string): Ed25519KeyHashes; + + /** + * @returns {Ed25519KeyHashes} + */ + static new(): Ed25519KeyHashes; + + /** + * @returns {number} + */ + len(): number; + + /** + * @param {number} index + * @returns {Ed25519KeyHash} + */ + get(index: number): Ed25519KeyHash; + + /** + * @param {Ed25519KeyHash} elem + */ + add(elem: Ed25519KeyHash): void; + + /** + * @returns {Ed25519KeyHashes | void} + */ + to_option(): Ed25519KeyHashes | void; } /** */ -declare export class Header { +declare export class Ed25519Signature { free(): void; /** @@ -2862,10 +3152,9 @@ declare export class Header { to_bytes(): Uint8Array; /** - * @param {Uint8Array} bytes - * @returns {Header} + * @returns {string} */ - static from_bytes(bytes: Uint8Array): Header; + to_bech32(): string; /** * @returns {string} @@ -2873,47 +3162,54 @@ declare export class Header { to_hex(): string; /** - * @param {string} hex_str - * @returns {Header} + * @param {string} bech32_str + * @returns {Ed25519Signature} */ - static from_hex(hex_str: string): Header; + static from_bech32(bech32_str: string): Ed25519Signature; /** - * @returns {string} + * @param {string} input + * @returns {Ed25519Signature} */ - to_json(): string; + static from_hex(input: string): Ed25519Signature; /** - * @returns {HeaderJSON} + * @param {Uint8Array} bytes + * @returns {Ed25519Signature} */ - to_js_value(): HeaderJSON; + static from_bytes(bytes: Uint8Array): Ed25519Signature; +} +/** + */ +declare export class EnterpriseAddress { + free(): void; /** - * @param {string} json - * @returns {Header} + * @param {number} network + * @param {StakeCredential} payment + * @returns {EnterpriseAddress} */ - static from_json(json: string): Header; + static new(network: number, payment: StakeCredential): EnterpriseAddress; /** - * @returns {HeaderBody} + * @returns {StakeCredential} */ - header_body(): HeaderBody; + payment_cred(): StakeCredential; /** - * @returns {KESSignature} + * @returns {Address} */ - body_signature(): KESSignature; + to_address(): Address; /** - * @param {HeaderBody} header_body - * @param {KESSignature} body_signature - * @returns {Header} + * @param {Address} addr + * @returns {EnterpriseAddress | void} */ - static new(header_body: HeaderBody, body_signature: KESSignature): Header; + static from_address(addr: Address): EnterpriseAddress | void; } /** */ -declare export class HeaderBody { +declare export class ExUnitPrices { free(): void; /** @@ -2923,9 +3219,9 @@ declare export class HeaderBody { /** * @param {Uint8Array} bytes - * @returns {HeaderBody} + * @returns {ExUnitPrices} */ - static from_bytes(bytes: Uint8Array): HeaderBody; + static from_bytes(bytes: Uint8Array): ExUnitPrices; /** * @returns {string} @@ -2934,9 +3230,9 @@ declare export class HeaderBody { /** * @param {string} hex_str - * @returns {HeaderBody} + * @returns {ExUnitPrices} */ - static from_hex(hex_str: string): HeaderBody; + static from_hex(hex_str: string): ExUnitPrices; /** * @returns {string} @@ -2944,216 +3240,204 @@ declare export class HeaderBody { to_json(): string; /** - * @returns {HeaderBodyJSON} + * @returns {ExUnitPricesJSON} */ - to_js_value(): HeaderBodyJSON; + to_js_value(): ExUnitPricesJSON; /** * @param {string} json - * @returns {HeaderBody} + * @returns {ExUnitPrices} */ - static from_json(json: string): HeaderBody; + static from_json(json: string): ExUnitPrices; /** - * @returns {number} + * @returns {UnitInterval} */ - block_number(): number; + mem_price(): UnitInterval; /** - * !!! DEPRECATED !!! - * Returns a Slot32 (u32) value in case the underlying original BigNum (u64) value is within the limits. - * Otherwise will just raise an error. - * @returns {number} + * @returns {UnitInterval} */ - slot(): number; + step_price(): UnitInterval; /** - * @returns {BigNum} + * @param {UnitInterval} mem_price + * @param {UnitInterval} step_price + * @returns {ExUnitPrices} */ - slot_bignum(): BigNum; + static new(mem_price: UnitInterval, step_price: UnitInterval): ExUnitPrices; +} +/** + */ +declare export class ExUnits { + free(): void; /** - * @returns {BlockHash | void} + * @returns {Uint8Array} */ - prev_hash(): BlockHash | void; + to_bytes(): Uint8Array; /** - * @returns {Vkey} + * @param {Uint8Array} bytes + * @returns {ExUnits} */ - issuer_vkey(): Vkey; + static from_bytes(bytes: Uint8Array): ExUnits; /** - * @returns {VRFVKey} + * @returns {string} */ - vrf_vkey(): VRFVKey; + to_hex(): string; /** - * If this function returns true, the `.nonce_vrf_or_nothing` - * and the `.leader_vrf_or_nothing` functions will return - * non-empty results - * @returns {boolean} + * @param {string} hex_str + * @returns {ExUnits} */ - has_nonce_and_leader_vrf(): boolean; + static from_hex(hex_str: string): ExUnits; /** - * Might return nothing in case `.has_nonce_and_leader_vrf` returns false - * @returns {VRFCert | void} + * @returns {string} */ - nonce_vrf_or_nothing(): VRFCert | void; + to_json(): string; /** - * Might return nothing in case `.has_nonce_and_leader_vrf` returns false - * @returns {VRFCert | void} + * @returns {ExUnitsJSON} */ - leader_vrf_or_nothing(): VRFCert | void; + to_js_value(): ExUnitsJSON; /** - * If this function returns true, the `.vrf_result_or_nothing` - * function will return a non-empty result - * @returns {boolean} + * @param {string} json + * @returns {ExUnits} */ - has_vrf_result(): boolean; + static from_json(json: string): ExUnits; /** - * Might return nothing in case `.has_vrf_result` returns false - * @returns {VRFCert | void} + * @returns {BigNum} */ - vrf_result_or_nothing(): VRFCert | void; + mem(): BigNum; /** - * @returns {number} + * @returns {BigNum} */ - block_body_size(): number; + steps(): BigNum; /** - * @returns {BlockHash} + * @param {BigNum} mem + * @param {BigNum} steps + * @returns {ExUnits} */ - block_body_hash(): BlockHash; + static new(mem: BigNum, steps: BigNum): ExUnits; +} +/** + */ +declare export class FixedTransaction { + free(): void; /** - * @returns {OperationalCert} + * @returns {Uint8Array} */ - operational_cert(): OperationalCert; + to_bytes(): Uint8Array; /** - * @returns {ProtocolVersion} + * @param {Uint8Array} bytes + * @returns {FixedTransaction} */ - protocol_version(): ProtocolVersion; + static from_bytes(bytes: Uint8Array): FixedTransaction; /** - * !!! DEPRECATED !!! - * This constructor uses outdated slot number format. - * Use `.new_headerbody` instead - * @param {number} block_number - * @param {number} slot - * @param {BlockHash | void} prev_hash - * @param {Vkey} issuer_vkey - * @param {VRFVKey} vrf_vkey - * @param {VRFCert} vrf_result - * @param {number} block_body_size - * @param {BlockHash} block_body_hash - * @param {OperationalCert} operational_cert - * @param {ProtocolVersion} protocol_version - * @returns {HeaderBody} + * @returns {string} */ - static new( - block_number: number, - slot: number, - prev_hash: BlockHash | void, - issuer_vkey: Vkey, - vrf_vkey: VRFVKey, - vrf_result: VRFCert, - block_body_size: number, - block_body_hash: BlockHash, - operational_cert: OperationalCert, - protocol_version: ProtocolVersion - ): HeaderBody; + to_hex(): string; /** - * @param {number} block_number - * @param {BigNum} slot - * @param {BlockHash | void} prev_hash - * @param {Vkey} issuer_vkey - * @param {VRFVKey} vrf_vkey - * @param {VRFCert} vrf_result - * @param {number} block_body_size - * @param {BlockHash} block_body_hash - * @param {OperationalCert} operational_cert - * @param {ProtocolVersion} protocol_version - * @returns {HeaderBody} + * @param {string} hex_str + * @returns {FixedTransaction} */ - static new_headerbody( - block_number: number, - slot: BigNum, - prev_hash: BlockHash | void, - issuer_vkey: Vkey, - vrf_vkey: VRFVKey, - vrf_result: VRFCert, - block_body_size: number, - block_body_hash: BlockHash, - operational_cert: OperationalCert, - protocol_version: ProtocolVersion - ): HeaderBody; -} -/** - */ -declare export class InputWithScriptWitness { - free(): void; + static from_hex(hex_str: string): FixedTransaction; /** - * @param {TransactionInput} input - * @param {NativeScript} witness - * @returns {InputWithScriptWitness} + * @param {Uint8Array} raw_body + * @param {Uint8Array} raw_witness_set + * @param {boolean} is_valid + * @returns {FixedTransaction} */ - static new_with_native_script_witness( - input: TransactionInput, - witness: NativeScript - ): InputWithScriptWitness; + static new( + raw_body: Uint8Array, + raw_witness_set: Uint8Array, + is_valid: boolean + ): FixedTransaction; /** - * @param {TransactionInput} input - * @param {PlutusWitness} witness - * @returns {InputWithScriptWitness} + * @param {Uint8Array} raw_body + * @param {Uint8Array} raw_witness_set + * @param {Uint8Array} raw_auxiliary_data + * @param {boolean} is_valid + * @returns {FixedTransaction} */ - static new_with_plutus_witness( - input: TransactionInput, - witness: PlutusWitness - ): InputWithScriptWitness; + static new_with_auxiliary( + raw_body: Uint8Array, + raw_witness_set: Uint8Array, + raw_auxiliary_data: Uint8Array, + is_valid: boolean + ): FixedTransaction; /** - * @returns {TransactionInput} + * @returns {TransactionBody} */ - input(): TransactionInput; -} -/** - */ -declare export class InputsWithScriptWitness { - free(): void; + body(): TransactionBody; /** - * @returns {InputsWithScriptWitness} + * @returns {Uint8Array} */ - static new(): InputsWithScriptWitness; + raw_body(): Uint8Array; /** - * @param {InputWithScriptWitness} input + * @param {Uint8Array} raw_body */ - add(input: InputWithScriptWitness): void; + set_body(raw_body: Uint8Array): void; /** - * @param {number} index - * @returns {InputWithScriptWitness} + * @param {Uint8Array} raw_witness_set */ - get(index: number): InputWithScriptWitness; + set_witness_set(raw_witness_set: Uint8Array): void; /** - * @returns {number} + * @returns {TransactionWitnessSet} */ - len(): number; + witness_set(): TransactionWitnessSet; + + /** + * @returns {Uint8Array} + */ + raw_witness_set(): Uint8Array; + + /** + * @param {boolean} valid + */ + set_is_valid(valid: boolean): void; + + /** + * @returns {boolean} + */ + is_valid(): boolean; + + /** + * @param {Uint8Array} raw_auxiliary_data + */ + set_auxiliary_data(raw_auxiliary_data: Uint8Array): void; + + /** + * @returns {AuxiliaryData | void} + */ + auxiliary_data(): AuxiliaryData | void; + + /** + * @returns {Uint8Array | void} + */ + raw_auxiliary_data(): Uint8Array | void; } /** */ -declare export class Int { +declare export class GeneralTransactionMetadata { free(): void; /** @@ -3163,9 +3447,9 @@ declare export class Int { /** * @param {Uint8Array} bytes - * @returns {Int} + * @returns {GeneralTransactionMetadata} */ - static from_bytes(bytes: Uint8Array): Int; + static from_bytes(bytes: Uint8Array): GeneralTransactionMetadata; /** * @returns {string} @@ -3174,9 +3458,9 @@ declare export class Int { /** * @param {string} hex_str - * @returns {Int} + * @returns {GeneralTransactionMetadata} */ - static from_hex(hex_str: string): Int; + static from_hex(hex_str: string): GeneralTransactionMetadata; /** * @returns {string} @@ -3184,153 +3468,125 @@ declare export class Int { to_json(): string; /** - * @returns {IntJSON} + * @returns {GeneralTransactionMetadataJSON} */ - to_js_value(): IntJSON; + to_js_value(): GeneralTransactionMetadataJSON; /** * @param {string} json - * @returns {Int} + * @returns {GeneralTransactionMetadata} */ - static from_json(json: string): Int; + static from_json(json: string): GeneralTransactionMetadata; /** - * @param {BigNum} x - * @returns {Int} + * @returns {GeneralTransactionMetadata} */ - static new(x: BigNum): Int; + static new(): GeneralTransactionMetadata; /** - * @param {BigNum} x - * @returns {Int} + * @returns {number} */ - static new_negative(x: BigNum): Int; + len(): number; /** - * @param {number} x - * @returns {Int} + * @param {BigNum} key + * @param {TransactionMetadatum} value + * @returns {TransactionMetadatum | void} */ - static new_i32(x: number): Int; + insert(key: BigNum, value: TransactionMetadatum): TransactionMetadatum | void; /** - * @returns {boolean} + * @param {BigNum} key + * @returns {TransactionMetadatum | void} */ - is_positive(): boolean; + get(key: BigNum): TransactionMetadatum | void; /** - * BigNum can only contain unsigned u64 values - * - * This function will return the BigNum representation - * only in case the underlying i128 value is positive. - * - * Otherwise nothing will be returned (undefined). - * @returns {BigNum | void} + * @returns {TransactionMetadatumLabels} */ - as_positive(): BigNum | void; + keys(): TransactionMetadatumLabels; +} +/** + */ +declare export class GenesisDelegateHash { + free(): void; /** - * BigNum can only contain unsigned u64 values - * - * This function will return the *absolute* BigNum representation - * only in case the underlying i128 value is negative. - * - * Otherwise nothing will be returned (undefined). - * @returns {BigNum | void} + * @param {Uint8Array} bytes + * @returns {GenesisDelegateHash} */ - as_negative(): BigNum | void; + static from_bytes(bytes: Uint8Array): GenesisDelegateHash; /** - * !!! DEPRECATED !!! - * Returns an i32 value in case the underlying original i128 value is within the limits. - * Otherwise will just return an empty value (undefined). - * @returns {number | void} + * @returns {Uint8Array} */ - as_i32(): number | void; + to_bytes(): Uint8Array; /** - * Returns the underlying value converted to i32 if possible (within limits) - * Otherwise will just return an empty value (undefined). - * @returns {number | void} + * @param {string} prefix + * @returns {string} */ - as_i32_or_nothing(): number | void; + to_bech32(prefix: string): string; /** - * Returns the underlying value converted to i32 if possible (within limits) - * JsError in case of out of boundary overflow - * @returns {number} + * @param {string} bech_str + * @returns {GenesisDelegateHash} */ - as_i32_or_fail(): number; + static from_bech32(bech_str: string): GenesisDelegateHash; /** - * Returns string representation of the underlying i128 value directly. - * Might contain the minus sign (-) in case of negative value. * @returns {string} */ - to_str(): string; + to_hex(): string; /** - * @param {string} string - * @returns {Int} + * @param {string} hex + * @returns {GenesisDelegateHash} */ - static from_str(string: string): Int; + static from_hex(hex: string): GenesisDelegateHash; } /** */ -declare export class Ipv4 { +declare export class GenesisHash { free(): void; - /** - * @returns {Uint8Array} - */ - to_bytes(): Uint8Array; - /** * @param {Uint8Array} bytes - * @returns {Ipv4} - */ - static from_bytes(bytes: Uint8Array): Ipv4; - - /** - * @returns {string} + * @returns {GenesisHash} */ - to_hex(): string; + static from_bytes(bytes: Uint8Array): GenesisHash; /** - * @param {string} hex_str - * @returns {Ipv4} + * @returns {Uint8Array} */ - static from_hex(hex_str: string): Ipv4; + to_bytes(): Uint8Array; /** + * @param {string} prefix * @returns {string} */ - to_json(): string; - - /** - * @returns {Ipv4JSON} - */ - to_js_value(): Ipv4JSON; + to_bech32(prefix: string): string; /** - * @param {string} json - * @returns {Ipv4} + * @param {string} bech_str + * @returns {GenesisHash} */ - static from_json(json: string): Ipv4; + static from_bech32(bech_str: string): GenesisHash; /** - * @param {Uint8Array} data - * @returns {Ipv4} + * @returns {string} */ - static new(data: Uint8Array): Ipv4; + to_hex(): string; /** - * @returns {Uint8Array} + * @param {string} hex + * @returns {GenesisHash} */ - ip(): Uint8Array; + static from_hex(hex: string): GenesisHash; } /** */ -declare export class Ipv6 { +declare export class GenesisHashes { free(): void; /** @@ -3340,9 +3596,9 @@ declare export class Ipv6 { /** * @param {Uint8Array} bytes - * @returns {Ipv6} + * @returns {GenesisHashes} */ - static from_bytes(bytes: Uint8Array): Ipv6; + static from_bytes(bytes: Uint8Array): GenesisHashes; /** * @returns {string} @@ -3351,9 +3607,9 @@ declare export class Ipv6 { /** * @param {string} hex_str - * @returns {Ipv6} + * @returns {GenesisHashes} */ - static from_hex(hex_str: string): Ipv6; + static from_hex(hex_str: string): GenesisHashes; /** * @returns {string} @@ -3361,30 +3617,40 @@ declare export class Ipv6 { to_json(): string; /** - * @returns {Ipv6JSON} + * @returns {GenesisHashesJSON} */ - to_js_value(): Ipv6JSON; + to_js_value(): GenesisHashesJSON; /** * @param {string} json - * @returns {Ipv6} + * @returns {GenesisHashes} */ - static from_json(json: string): Ipv6; + static from_json(json: string): GenesisHashes; /** - * @param {Uint8Array} data - * @returns {Ipv6} + * @returns {GenesisHashes} */ - static new(data: Uint8Array): Ipv6; + static new(): GenesisHashes; /** - * @returns {Uint8Array} + * @returns {number} */ - ip(): Uint8Array; + len(): number; + + /** + * @param {number} index + * @returns {GenesisHash} + */ + get(index: number): GenesisHash; + + /** + * @param {GenesisHash} elem + */ + add(elem: GenesisHash): void; } /** */ -declare export class KESSignature { +declare export class GenesisKeyDelegation { free(): void; /** @@ -3394,52 +3660,67 @@ declare export class KESSignature { /** * @param {Uint8Array} bytes - * @returns {KESSignature} + * @returns {GenesisKeyDelegation} */ - static from_bytes(bytes: Uint8Array): KESSignature; -} -/** - */ -declare export class KESVKey { - free(): void; + static from_bytes(bytes: Uint8Array): GenesisKeyDelegation; /** - * @param {Uint8Array} bytes - * @returns {KESVKey} + * @returns {string} */ - static from_bytes(bytes: Uint8Array): KESVKey; + to_hex(): string; /** - * @returns {Uint8Array} + * @param {string} hex_str + * @returns {GenesisKeyDelegation} */ - to_bytes(): Uint8Array; + static from_hex(hex_str: string): GenesisKeyDelegation; /** - * @param {string} prefix * @returns {string} */ - to_bech32(prefix: string): string; + to_json(): string; /** - * @param {string} bech_str - * @returns {KESVKey} + * @returns {GenesisKeyDelegationJSON} */ - static from_bech32(bech_str: string): KESVKey; + to_js_value(): GenesisKeyDelegationJSON; /** - * @returns {string} + * @param {string} json + * @returns {GenesisKeyDelegation} */ - to_hex(): string; + static from_json(json: string): GenesisKeyDelegation; /** - * @param {string} hex - * @returns {KESVKey} + * @returns {GenesisHash} */ - static from_hex(hex: string): KESVKey; + genesishash(): GenesisHash; + + /** + * @returns {GenesisDelegateHash} + */ + genesis_delegate_hash(): GenesisDelegateHash; + + /** + * @returns {VRFKeyHash} + */ + vrf_keyhash(): VRFKeyHash; + + /** + * @param {GenesisHash} genesishash + * @param {GenesisDelegateHash} genesis_delegate_hash + * @param {VRFKeyHash} vrf_keyhash + * @returns {GenesisKeyDelegation} + */ + static new( + genesishash: GenesisHash, + genesis_delegate_hash: GenesisDelegateHash, + vrf_keyhash: VRFKeyHash + ): GenesisKeyDelegation; } /** */ -declare export class Language { +declare export class GovernanceActionId { free(): void; /** @@ -3449,9 +3730,9 @@ declare export class Language { /** * @param {Uint8Array} bytes - * @returns {Language} + * @returns {GovernanceActionId} */ - static from_bytes(bytes: Uint8Array): Language; + static from_bytes(bytes: Uint8Array): GovernanceActionId; /** * @returns {string} @@ -3460,9 +3741,9 @@ declare export class Language { /** * @param {string} hex_str - * @returns {Language} + * @returns {GovernanceActionId} */ - static from_hex(hex_str: string): Language; + static from_hex(hex_str: string): GovernanceActionId; /** * @returns {string} @@ -3470,108 +3751,76 @@ declare export class Language { to_json(): string; /** - * @returns {LanguageJSON} + * @returns {GovernanceActionIdJSON} */ - to_js_value(): LanguageJSON; + to_js_value(): GovernanceActionIdJSON; /** * @param {string} json - * @returns {Language} - */ - static from_json(json: string): Language; - - /** - * @returns {Language} - */ - static new_plutus_v1(): Language; - - /** - * @returns {Language} - */ - static new_plutus_v2(): Language; - - /** - * @returns {number} + * @returns {GovernanceActionId} */ - kind(): number; -} -/** - */ -declare export class Languages { - free(): void; + static from_json(json: string): GovernanceActionId; /** - * @returns {Languages} + * @returns {TransactionHash} */ - static new(): Languages; + transaction_id(): TransactionHash; /** * @returns {number} */ - len(): number; + index(): number; /** + * @param {TransactionHash} transaction_id * @param {number} index - * @returns {Language} - */ - get(index: number): Language; - - /** - * @param {Language} elem - */ - add(elem: Language): void; - - /** - * @returns {Languages} + * @returns {GovernanceActionId} */ - static list(): Languages; + static new( + transaction_id: TransactionHash, + index: number + ): GovernanceActionId; } /** */ -declare export class LegacyDaedalusPrivateKey { +declare export class GovernanceActionIds { free(): void; /** - * @param {Uint8Array} bytes - * @returns {LegacyDaedalusPrivateKey} + * @returns {string} */ - static from_bytes(bytes: Uint8Array): LegacyDaedalusPrivateKey; + to_json(): string; /** - * @returns {Uint8Array} + * @returns {GovernanceActionIdsJSON} */ - as_bytes(): Uint8Array; + to_js_value(): GovernanceActionIdsJSON; /** - * @returns {Uint8Array} + * @param {string} json + * @returns {GovernanceActionIds} */ - chaincode(): Uint8Array; -} -/** - */ -declare export class LinearFee { - free(): void; + static from_json(json: string): GovernanceActionIds; /** - * @returns {BigNum} + * @returns {GovernanceActionIds} */ - constant(): BigNum; + static new(): GovernanceActionIds; /** - * @returns {BigNum} + * @param {number} index + * @returns {GovernanceActionId | void} */ - coefficient(): BigNum; + get(index: number): GovernanceActionId | void; /** - * @param {BigNum} coefficient - * @param {BigNum} constant - * @returns {LinearFee} + * @returns {number} */ - static new(coefficient: BigNum, constant: BigNum): LinearFee; + len(): number; } /** */ -declare export class MIRToStakeCredentials { +declare export class HardForkInitiationProposal { free(): void; /** @@ -3581,9 +3830,9 @@ declare export class MIRToStakeCredentials { /** * @param {Uint8Array} bytes - * @returns {MIRToStakeCredentials} + * @returns {HardForkInitiationProposal} */ - static from_bytes(bytes: Uint8Array): MIRToStakeCredentials; + static from_bytes(bytes: Uint8Array): HardForkInitiationProposal; /** * @returns {string} @@ -3592,9 +3841,9 @@ declare export class MIRToStakeCredentials { /** * @param {string} hex_str - * @returns {MIRToStakeCredentials} + * @returns {HardForkInitiationProposal} */ - static from_hex(hex_str: string): MIRToStakeCredentials; + static from_hex(hex_str: string): HardForkInitiationProposal; /** * @returns {string} @@ -3602,47 +3851,45 @@ declare export class MIRToStakeCredentials { to_json(): string; /** - * @returns {MIRToStakeCredentialsJSON} + * @returns {HardForkInitiationProposalJSON} */ - to_js_value(): MIRToStakeCredentialsJSON; + to_js_value(): HardForkInitiationProposalJSON; /** * @param {string} json - * @returns {MIRToStakeCredentials} - */ - static from_json(json: string): MIRToStakeCredentials; - - /** - * @returns {MIRToStakeCredentials} + * @returns {HardForkInitiationProposal} */ - static new(): MIRToStakeCredentials; + static from_json(json: string): HardForkInitiationProposal; /** - * @returns {number} + * @returns {GovernanceActionId | void} */ - len(): number; + gov_action_id(): GovernanceActionId | void; /** - * @param {StakeCredential} cred - * @param {Int} delta - * @returns {Int | void} + * @returns {ProtocolVersion} */ - insert(cred: StakeCredential, delta: Int): Int | void; + protocol_version(): ProtocolVersion; /** - * @param {StakeCredential} cred - * @returns {Int | void} + * @param {ProtocolVersion} protocol_version + * @returns {HardForkInitiationProposal} */ - get(cred: StakeCredential): Int | void; + static new(protocol_version: ProtocolVersion): HardForkInitiationProposal; /** - * @returns {StakeCredentials} + * @param {GovernanceActionId} gov_action_id + * @param {ProtocolVersion} protocol_version + * @returns {HardForkInitiationProposal} */ - keys(): StakeCredentials; + static new_with_action_id( + gov_action_id: GovernanceActionId, + protocol_version: ProtocolVersion + ): HardForkInitiationProposal; } /** */ -declare export class MetadataList { +declare export class Header { free(): void; /** @@ -3652,9 +3899,9 @@ declare export class MetadataList { /** * @param {Uint8Array} bytes - * @returns {MetadataList} + * @returns {Header} */ - static from_bytes(bytes: Uint8Array): MetadataList; + static from_bytes(bytes: Uint8Array): Header; /** * @returns {string} @@ -3663,34 +3910,46 @@ declare export class MetadataList { /** * @param {string} hex_str - * @returns {MetadataList} + * @returns {Header} */ - static from_hex(hex_str: string): MetadataList; + static from_hex(hex_str: string): Header; /** - * @returns {MetadataList} + * @returns {string} */ - static new(): MetadataList; + to_json(): string; /** - * @returns {number} + * @returns {HeaderJSON} */ - len(): number; + to_js_value(): HeaderJSON; /** - * @param {number} index - * @returns {TransactionMetadatum} + * @param {string} json + * @returns {Header} */ - get(index: number): TransactionMetadatum; + static from_json(json: string): Header; /** - * @param {TransactionMetadatum} elem + * @returns {HeaderBody} */ - add(elem: TransactionMetadatum): void; + header_body(): HeaderBody; + + /** + * @returns {KESSignature} + */ + body_signature(): KESSignature; + + /** + * @param {HeaderBody} header_body + * @param {KESSignature} body_signature + * @returns {Header} + */ + static new(header_body: HeaderBody, body_signature: KESSignature): Header; } /** */ -declare export class MetadataMap { +declare export class HeaderBody { free(): void; /** @@ -3700,9 +3959,9 @@ declare export class MetadataMap { /** * @param {Uint8Array} bytes - * @returns {MetadataMap} + * @returns {HeaderBody} */ - static from_bytes(bytes: Uint8Array): MetadataMap; + static from_bytes(bytes: Uint8Array): HeaderBody; /** * @returns {string} @@ -3711,306 +3970,359 @@ declare export class MetadataMap { /** * @param {string} hex_str - * @returns {MetadataMap} + * @returns {HeaderBody} */ - static from_hex(hex_str: string): MetadataMap; + static from_hex(hex_str: string): HeaderBody; /** - * @returns {MetadataMap} + * @returns {string} */ - static new(): MetadataMap; + to_json(): string; /** - * @returns {number} + * @returns {HeaderBodyJSON} */ - len(): number; + to_js_value(): HeaderBodyJSON; /** - * @param {TransactionMetadatum} key - * @param {TransactionMetadatum} value - * @returns {TransactionMetadatum | void} - */ - insert( - key: TransactionMetadatum, - value: TransactionMetadatum - ): TransactionMetadatum | void; - - /** - * @param {string} key - * @param {TransactionMetadatum} value - * @returns {TransactionMetadatum | void} - */ - insert_str( - key: string, - value: TransactionMetadatum - ): TransactionMetadatum | void; - - /** - * @param {number} key - * @param {TransactionMetadatum} value - * @returns {TransactionMetadatum | void} + * @param {string} json + * @returns {HeaderBody} */ - insert_i32( - key: number, - value: TransactionMetadatum - ): TransactionMetadatum | void; + static from_json(json: string): HeaderBody; /** - * @param {TransactionMetadatum} key - * @returns {TransactionMetadatum} + * @returns {number} */ - get(key: TransactionMetadatum): TransactionMetadatum; + block_number(): number; /** - * @param {string} key - * @returns {TransactionMetadatum} + * !!! DEPRECATED !!! + * Returns a Slot32 (u32) value in case the underlying original BigNum (u64) value is within the limits. + * Otherwise will just raise an error. + * @returns {number} */ - get_str(key: string): TransactionMetadatum; + slot(): number; /** - * @param {number} key - * @returns {TransactionMetadatum} + * @returns {BigNum} */ - get_i32(key: number): TransactionMetadatum; + slot_bignum(): BigNum; /** - * @param {TransactionMetadatum} key - * @returns {boolean} + * @returns {BlockHash | void} */ - has(key: TransactionMetadatum): boolean; + prev_hash(): BlockHash | void; /** - * @returns {MetadataList} + * @returns {Vkey} */ - keys(): MetadataList; -} -/** - */ -declare export class Mint { - free(): void; + issuer_vkey(): Vkey; /** - * @returns {Uint8Array} + * @returns {VRFVKey} */ - to_bytes(): Uint8Array; + vrf_vkey(): VRFVKey; /** - * @param {Uint8Array} bytes - * @returns {Mint} + * If this function returns true, the `.nonce_vrf_or_nothing` + * and the `.leader_vrf_or_nothing` functions will return + * non-empty results + * @returns {boolean} */ - static from_bytes(bytes: Uint8Array): Mint; + has_nonce_and_leader_vrf(): boolean; /** - * @returns {string} + * Might return nothing in case `.has_nonce_and_leader_vrf` returns false + * @returns {VRFCert | void} */ - to_hex(): string; + nonce_vrf_or_nothing(): VRFCert | void; /** - * @param {string} hex_str - * @returns {Mint} + * Might return nothing in case `.has_nonce_and_leader_vrf` returns false + * @returns {VRFCert | void} */ - static from_hex(hex_str: string): Mint; + leader_vrf_or_nothing(): VRFCert | void; /** - * @returns {string} + * If this function returns true, the `.vrf_result_or_nothing` + * function will return a non-empty result + * @returns {boolean} */ - to_json(): string; + has_vrf_result(): boolean; /** - * @returns {MintJSON} + * Might return nothing in case `.has_vrf_result` returns false + * @returns {VRFCert | void} */ - to_js_value(): MintJSON; + vrf_result_or_nothing(): VRFCert | void; /** - * @param {string} json - * @returns {Mint} + * @returns {number} */ - static from_json(json: string): Mint; + block_body_size(): number; /** - * @returns {Mint} + * @returns {BlockHash} */ - static new(): Mint; + block_body_hash(): BlockHash; /** - * @param {ScriptHash} key - * @param {MintAssets} value - * @returns {Mint} + * @returns {OperationalCert} */ - static new_from_entry(key: ScriptHash, value: MintAssets): Mint; + operational_cert(): OperationalCert; /** - * @returns {number} + * @returns {ProtocolVersion} */ - len(): number; + protocol_version(): ProtocolVersion; /** - * @param {ScriptHash} key - * @param {MintAssets} value - * @returns {MintAssets | void} + * !!! DEPRECATED !!! + * This constructor uses outdated slot number format. + * Use `.new_headerbody` instead + * @param {number} block_number + * @param {number} slot + * @param {BlockHash | void} prev_hash + * @param {Vkey} issuer_vkey + * @param {VRFVKey} vrf_vkey + * @param {VRFCert} vrf_result + * @param {number} block_body_size + * @param {BlockHash} block_body_hash + * @param {OperationalCert} operational_cert + * @param {ProtocolVersion} protocol_version + * @returns {HeaderBody} */ - insert(key: ScriptHash, value: MintAssets): MintAssets | void; + static new( + block_number: number, + slot: number, + prev_hash: BlockHash | void, + issuer_vkey: Vkey, + vrf_vkey: VRFVKey, + vrf_result: VRFCert, + block_body_size: number, + block_body_hash: BlockHash, + operational_cert: OperationalCert, + protocol_version: ProtocolVersion + ): HeaderBody; /** - * !!! DEPRECATED !!! - * Mint can store multiple entries for the same policy id. - * Use `.get_all` instead. - * @param {ScriptHash} key - * @returns {MintAssets | void} + * @param {number} block_number + * @param {BigNum} slot + * @param {BlockHash | void} prev_hash + * @param {Vkey} issuer_vkey + * @param {VRFVKey} vrf_vkey + * @param {VRFCert} vrf_result + * @param {number} block_body_size + * @param {BlockHash} block_body_hash + * @param {OperationalCert} operational_cert + * @param {ProtocolVersion} protocol_version + * @returns {HeaderBody} */ - get(key: ScriptHash): MintAssets | void; + static new_headerbody( + block_number: number, + slot: BigNum, + prev_hash: BlockHash | void, + issuer_vkey: Vkey, + vrf_vkey: VRFVKey, + vrf_result: VRFCert, + block_body_size: number, + block_body_hash: BlockHash, + operational_cert: OperationalCert, + protocol_version: ProtocolVersion + ): HeaderBody; +} +/** + */ +declare export class InfoProposal { + free(): void; /** - * @param {ScriptHash} key - * @returns {MintsAssets | void} + * @returns {InfoProposal} */ - get_all(key: ScriptHash): MintsAssets | void; + static new(): InfoProposal; +} +/** + */ +declare export class InputWithScriptWitness { + free(): void; /** - * @returns {ScriptHashes} + * @param {TransactionInput} input + * @param {NativeScript} witness + * @returns {InputWithScriptWitness} */ - keys(): ScriptHashes; + static new_with_native_script_witness( + input: TransactionInput, + witness: NativeScript + ): InputWithScriptWitness; /** - * Returns the multiasset where only positive (minting) entries are present - * @returns {MultiAsset} + * @param {TransactionInput} input + * @param {PlutusWitness} witness + * @returns {InputWithScriptWitness} */ - as_positive_multiasset(): MultiAsset; + static new_with_plutus_witness( + input: TransactionInput, + witness: PlutusWitness + ): InputWithScriptWitness; /** - * Returns the multiasset where only negative (burning) entries are present - * @returns {MultiAsset} + * @returns {TransactionInput} */ - as_negative_multiasset(): MultiAsset; + input(): TransactionInput; } /** */ -declare export class MintAssets { +declare export class InputsWithScriptWitness { free(): void; /** - * @returns {MintAssets} + * @returns {InputsWithScriptWitness} */ - static new(): MintAssets; + static new(): InputsWithScriptWitness; /** - * @param {AssetName} key - * @param {Int} value - * @returns {MintAssets} + * @param {InputWithScriptWitness} input */ - static new_from_entry(key: AssetName, value: Int): MintAssets; + add(input: InputWithScriptWitness): void; + + /** + * @param {number} index + * @returns {InputWithScriptWitness} + */ + get(index: number): InputWithScriptWitness; /** * @returns {number} */ len(): number; +} +/** + */ +declare export class Int { + free(): void; /** - * @param {AssetName} key - * @param {Int} value - * @returns {Int | void} + * @returns {Uint8Array} */ - insert(key: AssetName, value: Int): Int | void; + to_bytes(): Uint8Array; /** - * @param {AssetName} key - * @returns {Int | void} + * @param {Uint8Array} bytes + * @returns {Int} */ - get(key: AssetName): Int | void; + static from_bytes(bytes: Uint8Array): Int; /** - * @returns {AssetNames} + * @returns {string} */ - keys(): AssetNames; -} -/** - */ -declare export class MintBuilder { - free(): void; + to_hex(): string; /** - * @returns {MintBuilder} + * @param {string} hex_str + * @returns {Int} */ - static new(): MintBuilder; + static from_hex(hex_str: string): Int; /** - * @param {MintWitness} mint - * @param {AssetName} asset_name - * @param {Int} amount + * @returns {string} */ - add_asset(mint: MintWitness, asset_name: AssetName, amount: Int): void; + to_json(): string; /** - * @param {MintWitness} mint - * @param {AssetName} asset_name - * @param {Int} amount + * @returns {IntJSON} */ - set_asset(mint: MintWitness, asset_name: AssetName, amount: Int): void; + to_js_value(): IntJSON; /** - * @returns {Mint} + * @param {string} json + * @returns {Int} */ - build(): Mint; + static from_json(json: string): Int; /** - * @returns {NativeScripts} + * @param {BigNum} x + * @returns {Int} */ - get_native_scripts(): NativeScripts; + static new(x: BigNum): Int; /** - * @returns {PlutusWitnesses} + * @param {BigNum} x + * @returns {Int} */ - get_plutus_witnesses(): PlutusWitnesses; + static new_negative(x: BigNum): Int; /** - * @returns {TransactionInputs} + * @param {number} x + * @returns {Int} */ - get_ref_inputs(): TransactionInputs; + static new_i32(x: number): Int; /** - * @returns {Redeemers} + * @returns {boolean} */ - get_redeeemers(): Redeemers; + is_positive(): boolean; /** - * @returns {boolean} + * BigNum can only contain unsigned u64 values + * + * This function will return the BigNum representation + * only in case the underlying i128 value is positive. + * + * Otherwise nothing will be returned (undefined). + * @returns {BigNum | void} */ - has_plutus_scripts(): boolean; + as_positive(): BigNum | void; /** - * @returns {boolean} + * BigNum can only contain unsigned u64 values + * + * This function will return the *absolute* BigNum representation + * only in case the underlying i128 value is negative. + * + * Otherwise nothing will be returned (undefined). + * @returns {BigNum | void} */ - has_native_scripts(): boolean; -} -/** - */ -declare export class MintWitness { - free(): void; + as_negative(): BigNum | void; /** - * @param {NativeScript} native_script - * @returns {MintWitness} + * !!! DEPRECATED !!! + * Returns an i32 value in case the underlying original i128 value is within the limits. + * Otherwise will just return an empty value (undefined). + * @returns {number | void} */ - static new_native_script(native_script: NativeScript): MintWitness; + as_i32(): number | void; /** - * @param {PlutusScriptSource} plutus_script - * @param {Redeemer} redeemer - * @returns {MintWitness} + * Returns the underlying value converted to i32 if possible (within limits) + * Otherwise will just return an empty value (undefined). + * @returns {number | void} */ - static new_plutus_script( - plutus_script: PlutusScriptSource, - redeemer: Redeemer - ): MintWitness; -} -/** - */ -declare export class MintsAssets { - free(): void; + as_i32_or_nothing(): number | void; + + /** + * Returns the underlying value converted to i32 if possible (within limits) + * JsError in case of out of boundary overflow + * @returns {number} + */ + as_i32_or_fail(): number; + + /** + * Returns string representation of the underlying i128 value directly. + * Might contain the minus sign (-) in case of negative value. + * @returns {string} + */ + to_str(): string; + + /** + * @param {string} string + * @returns {Int} + */ + static from_str(string: string): Int; } /** */ -declare export class MoveInstantaneousReward { +declare export class Ipv4 { free(): void; /** @@ -4020,9 +4332,9 @@ declare export class MoveInstantaneousReward { /** * @param {Uint8Array} bytes - * @returns {MoveInstantaneousReward} + * @returns {Ipv4} */ - static from_bytes(bytes: Uint8Array): MoveInstantaneousReward; + static from_bytes(bytes: Uint8Array): Ipv4; /** * @returns {string} @@ -4031,9 +4343,9 @@ declare export class MoveInstantaneousReward { /** * @param {string} hex_str - * @returns {MoveInstantaneousReward} + * @returns {Ipv4} */ - static from_hex(hex_str: string): MoveInstantaneousReward; + static from_hex(hex_str: string): Ipv4; /** * @returns {string} @@ -4041,56 +4353,30 @@ declare export class MoveInstantaneousReward { to_json(): string; /** - * @returns {MoveInstantaneousRewardJSON} + * @returns {Ipv4JSON} */ - to_js_value(): MoveInstantaneousRewardJSON; + to_js_value(): Ipv4JSON; /** * @param {string} json - * @returns {MoveInstantaneousReward} - */ - static from_json(json: string): MoveInstantaneousReward; - - /** - * @param {number} pot - * @param {BigNum} amount - * @returns {MoveInstantaneousReward} - */ - static new_to_other_pot(pot: number, amount: BigNum): MoveInstantaneousReward; - - /** - * @param {number} pot - * @param {MIRToStakeCredentials} amounts - * @returns {MoveInstantaneousReward} - */ - static new_to_stake_creds( - pot: number, - amounts: MIRToStakeCredentials - ): MoveInstantaneousReward; - - /** - * @returns {number} - */ - pot(): number; - - /** - * @returns {number} + * @returns {Ipv4} */ - kind(): number; + static from_json(json: string): Ipv4; /** - * @returns {BigNum | void} + * @param {Uint8Array} data + * @returns {Ipv4} */ - as_to_other_pot(): BigNum | void; + static new(data: Uint8Array): Ipv4; /** - * @returns {MIRToStakeCredentials | void} + * @returns {Uint8Array} */ - as_to_stake_creds(): MIRToStakeCredentials | void; + ip(): Uint8Array; } /** */ -declare export class MoveInstantaneousRewardsCert { +declare export class Ipv6 { free(): void; /** @@ -4100,9 +4386,9 @@ declare export class MoveInstantaneousRewardsCert { /** * @param {Uint8Array} bytes - * @returns {MoveInstantaneousRewardsCert} + * @returns {Ipv6} */ - static from_bytes(bytes: Uint8Array): MoveInstantaneousRewardsCert; + static from_bytes(bytes: Uint8Array): Ipv6; /** * @returns {string} @@ -4111,9 +4397,9 @@ declare export class MoveInstantaneousRewardsCert { /** * @param {string} hex_str - * @returns {MoveInstantaneousRewardsCert} + * @returns {Ipv6} */ - static from_hex(hex_str: string): MoveInstantaneousRewardsCert; + static from_hex(hex_str: string): Ipv6; /** * @returns {string} @@ -4121,32 +4407,30 @@ declare export class MoveInstantaneousRewardsCert { to_json(): string; /** - * @returns {MoveInstantaneousRewardsCertJSON} + * @returns {Ipv6JSON} */ - to_js_value(): MoveInstantaneousRewardsCertJSON; + to_js_value(): Ipv6JSON; /** * @param {string} json - * @returns {MoveInstantaneousRewardsCert} + * @returns {Ipv6} */ - static from_json(json: string): MoveInstantaneousRewardsCert; + static from_json(json: string): Ipv6; /** - * @returns {MoveInstantaneousReward} + * @param {Uint8Array} data + * @returns {Ipv6} */ - move_instantaneous_reward(): MoveInstantaneousReward; + static new(data: Uint8Array): Ipv6; /** - * @param {MoveInstantaneousReward} move_instantaneous_reward - * @returns {MoveInstantaneousRewardsCert} + * @returns {Uint8Array} */ - static new( - move_instantaneous_reward: MoveInstantaneousReward - ): MoveInstantaneousRewardsCert; + ip(): Uint8Array; } /** */ -declare export class MultiAsset { +declare export class KESSignature { free(): void; /** @@ -4156,290 +4440,283 @@ declare export class MultiAsset { /** * @param {Uint8Array} bytes - * @returns {MultiAsset} + * @returns {KESSignature} */ - static from_bytes(bytes: Uint8Array): MultiAsset; + static from_bytes(bytes: Uint8Array): KESSignature; +} +/** + */ +declare export class KESVKey { + free(): void; /** - * @returns {string} + * @param {Uint8Array} bytes + * @returns {KESVKey} */ - to_hex(): string; + static from_bytes(bytes: Uint8Array): KESVKey; /** - * @param {string} hex_str - * @returns {MultiAsset} + * @returns {Uint8Array} */ - static from_hex(hex_str: string): MultiAsset; + to_bytes(): Uint8Array; /** + * @param {string} prefix * @returns {string} */ - to_json(): string; + to_bech32(prefix: string): string; /** - * @returns {MultiAssetJSON} + * @param {string} bech_str + * @returns {KESVKey} */ - to_js_value(): MultiAssetJSON; + static from_bech32(bech_str: string): KESVKey; /** - * @param {string} json - * @returns {MultiAsset} + * @returns {string} */ - static from_json(json: string): MultiAsset; + to_hex(): string; /** - * @returns {MultiAsset} + * @param {string} hex + * @returns {KESVKey} */ - static new(): MultiAsset; + static from_hex(hex: string): KESVKey; +} +/** + */ +declare export class Language { + free(): void; /** - * the number of unique policy IDs in the multiasset - * @returns {number} + * @returns {Uint8Array} */ - len(): number; + to_bytes(): Uint8Array; /** - * set (and replace if it exists) all assets with policy {policy_id} to a copy of {assets} - * @param {ScriptHash} policy_id - * @param {Assets} assets - * @returns {Assets | void} + * @param {Uint8Array} bytes + * @returns {Language} */ - insert(policy_id: ScriptHash, assets: Assets): Assets | void; + static from_bytes(bytes: Uint8Array): Language; /** - * all assets under {policy_id}, if any exist, or else None (undefined in JS) - * @param {ScriptHash} policy_id - * @returns {Assets | void} + * @returns {string} */ - get(policy_id: ScriptHash): Assets | void; + to_hex(): string; /** - * sets the asset {asset_name} to {value} under policy {policy_id} - * returns the previous amount if it was set, or else None (undefined in JS) - * @param {ScriptHash} policy_id - * @param {AssetName} asset_name - * @param {BigNum} value - * @returns {BigNum | void} - */ - set_asset( - policy_id: ScriptHash, - asset_name: AssetName, - value: BigNum - ): BigNum | void; - - /** - * returns the amount of asset {asset_name} under policy {policy_id} - * If such an asset does not exist, 0 is returned. - * @param {ScriptHash} policy_id - * @param {AssetName} asset_name - * @returns {BigNum} + * @param {string} hex_str + * @returns {Language} */ - get_asset(policy_id: ScriptHash, asset_name: AssetName): BigNum; + static from_hex(hex_str: string): Language; /** - * returns all policy IDs used by assets in this multiasset - * @returns {ScriptHashes} + * @returns {string} */ - keys(): ScriptHashes; + to_json(): string; /** - * removes an asset from the list if the result is 0 or less - * does not modify this object, instead the result is returned - * @param {MultiAsset} rhs_ma - * @returns {MultiAsset} + * @returns {LanguageJSON} */ - sub(rhs_ma: MultiAsset): MultiAsset; -} -/** - */ -declare export class MultiHostName { - free(): void; + to_js_value(): LanguageJSON; /** - * @returns {Uint8Array} + * @param {string} json + * @returns {Language} */ - to_bytes(): Uint8Array; + static from_json(json: string): Language; /** - * @param {Uint8Array} bytes - * @returns {MultiHostName} + * @returns {Language} */ - static from_bytes(bytes: Uint8Array): MultiHostName; + static new_plutus_v1(): Language; /** - * @returns {string} + * @returns {Language} */ - to_hex(): string; + static new_plutus_v2(): Language; /** - * @param {string} hex_str - * @returns {MultiHostName} + * @returns {number} */ - static from_hex(hex_str: string): MultiHostName; + kind(): number; +} +/** + */ +declare export class Languages { + free(): void; /** - * @returns {string} + * @returns {Languages} */ - to_json(): string; + static new(): Languages; /** - * @returns {MultiHostNameJSON} + * @returns {number} */ - to_js_value(): MultiHostNameJSON; + len(): number; /** - * @param {string} json - * @returns {MultiHostName} + * @param {number} index + * @returns {Language} */ - static from_json(json: string): MultiHostName; + get(index: number): Language; /** - * @returns {DNSRecordSRV} + * @param {Language} elem */ - dns_name(): DNSRecordSRV; + add(elem: Language): void; /** - * @param {DNSRecordSRV} dns_name - * @returns {MultiHostName} + * @returns {Languages} */ - static new(dns_name: DNSRecordSRV): MultiHostName; + static list(): Languages; } /** */ -declare export class NativeScript { +declare export class LegacyDaedalusPrivateKey { free(): void; /** - * @returns {Uint8Array} + * @param {Uint8Array} bytes + * @returns {LegacyDaedalusPrivateKey} */ - to_bytes(): Uint8Array; + static from_bytes(bytes: Uint8Array): LegacyDaedalusPrivateKey; /** - * @param {Uint8Array} bytes - * @returns {NativeScript} + * @returns {Uint8Array} */ - static from_bytes(bytes: Uint8Array): NativeScript; + as_bytes(): Uint8Array; /** - * @returns {string} + * @returns {Uint8Array} */ - to_hex(): string; + chaincode(): Uint8Array; +} +/** + */ +declare export class LinearFee { + free(): void; /** - * @param {string} hex_str - * @returns {NativeScript} + * @returns {BigNum} */ - static from_hex(hex_str: string): NativeScript; + constant(): BigNum; /** - * @returns {string} + * @returns {BigNum} */ - to_json(): string; + coefficient(): BigNum; /** - * @returns {NativeScriptJSON} + * @param {BigNum} coefficient + * @param {BigNum} constant + * @returns {LinearFee} */ - to_js_value(): NativeScriptJSON; + static new(coefficient: BigNum, constant: BigNum): LinearFee; +} +/** + */ +declare export class MIRToStakeCredentials { + free(): void; /** - * @param {string} json - * @returns {NativeScript} + * @returns {Uint8Array} */ - static from_json(json: string): NativeScript; + to_bytes(): Uint8Array; /** - * @returns {ScriptHash} + * @param {Uint8Array} bytes + * @returns {MIRToStakeCredentials} */ - hash(): ScriptHash; + static from_bytes(bytes: Uint8Array): MIRToStakeCredentials; /** - * @param {ScriptPubkey} script_pubkey - * @returns {NativeScript} + * @returns {string} */ - static new_script_pubkey(script_pubkey: ScriptPubkey): NativeScript; + to_hex(): string; /** - * @param {ScriptAll} script_all - * @returns {NativeScript} + * @param {string} hex_str + * @returns {MIRToStakeCredentials} */ - static new_script_all(script_all: ScriptAll): NativeScript; + static from_hex(hex_str: string): MIRToStakeCredentials; /** - * @param {ScriptAny} script_any - * @returns {NativeScript} + * @returns {string} */ - static new_script_any(script_any: ScriptAny): NativeScript; + to_json(): string; /** - * @param {ScriptNOfK} script_n_of_k - * @returns {NativeScript} + * @returns {MIRToStakeCredentialsJSON} */ - static new_script_n_of_k(script_n_of_k: ScriptNOfK): NativeScript; + to_js_value(): MIRToStakeCredentialsJSON; /** - * @param {TimelockStart} timelock_start - * @returns {NativeScript} + * @param {string} json + * @returns {MIRToStakeCredentials} */ - static new_timelock_start(timelock_start: TimelockStart): NativeScript; + static from_json(json: string): MIRToStakeCredentials; /** - * @param {TimelockExpiry} timelock_expiry - * @returns {NativeScript} + * @returns {MIRToStakeCredentials} */ - static new_timelock_expiry(timelock_expiry: TimelockExpiry): NativeScript; + static new(): MIRToStakeCredentials; /** * @returns {number} */ - kind(): number; + len(): number; /** - * @returns {ScriptPubkey | void} + * @param {StakeCredential} cred + * @param {Int} delta + * @returns {Int | void} */ - as_script_pubkey(): ScriptPubkey | void; + insert(cred: StakeCredential, delta: Int): Int | void; /** - * @returns {ScriptAll | void} + * @param {StakeCredential} cred + * @returns {Int | void} */ - as_script_all(): ScriptAll | void; + get(cred: StakeCredential): Int | void; /** - * @returns {ScriptAny | void} + * @returns {StakeCredentials} */ - as_script_any(): ScriptAny | void; + keys(): StakeCredentials; +} +/** + */ +declare export class MetadataList { + free(): void; /** - * @returns {ScriptNOfK | void} + * @returns {Uint8Array} */ - as_script_n_of_k(): ScriptNOfK | void; + to_bytes(): Uint8Array; /** - * @returns {TimelockStart | void} + * @param {Uint8Array} bytes + * @returns {MetadataList} */ - as_timelock_start(): TimelockStart | void; + static from_bytes(bytes: Uint8Array): MetadataList; /** - * @returns {TimelockExpiry | void} + * @returns {string} */ - as_timelock_expiry(): TimelockExpiry | void; + to_hex(): string; /** - * Returns an array of unique Ed25519KeyHashes - * contained within this script recursively on any depth level. - * The order of the keys in the result is not determined in any way. - * @returns {Ed25519KeyHashes} + * @param {string} hex_str + * @returns {MetadataList} */ - get_required_signers(): Ed25519KeyHashes; -} -/** - */ -declare export class NativeScripts { - free(): void; + static from_hex(hex_str: string): MetadataList; /** - * @returns {NativeScripts} + * @returns {MetadataList} */ - static new(): NativeScripts; + static new(): MetadataList; /** * @returns {number} @@ -4448,18 +4725,18 @@ declare export class NativeScripts { /** * @param {number} index - * @returns {NativeScript} + * @returns {TransactionMetadatum} */ - get(index: number): NativeScript; + get(index: number): TransactionMetadatum; /** - * @param {NativeScript} elem + * @param {TransactionMetadatum} elem */ - add(elem: NativeScript): void; + add(elem: TransactionMetadatum): void; } /** */ -declare export class NetworkId { +declare export class MetadataMap { free(): void; /** @@ -4469,9 +4746,9 @@ declare export class NetworkId { /** * @param {Uint8Array} bytes - * @returns {NetworkId} + * @returns {MetadataMap} */ - static from_bytes(bytes: Uint8Array): NetworkId; + static from_bytes(bytes: Uint8Array): MetadataMap; /** * @returns {string} @@ -4480,88 +4757,82 @@ declare export class NetworkId { /** * @param {string} hex_str - * @returns {NetworkId} + * @returns {MetadataMap} */ - static from_hex(hex_str: string): NetworkId; + static from_hex(hex_str: string): MetadataMap; /** - * @returns {string} + * @returns {MetadataMap} */ - to_json(): string; + static new(): MetadataMap; /** - * @returns {NetworkIdJSON} + * @returns {number} */ - to_js_value(): NetworkIdJSON; + len(): number; /** - * @param {string} json - * @returns {NetworkId} + * @param {TransactionMetadatum} key + * @param {TransactionMetadatum} value + * @returns {TransactionMetadatum | void} */ - static from_json(json: string): NetworkId; + insert( + key: TransactionMetadatum, + value: TransactionMetadatum + ): TransactionMetadatum | void; /** - * @returns {NetworkId} - */ - static testnet(): NetworkId; - - /** - * @returns {NetworkId} - */ - static mainnet(): NetworkId; - - /** - * @returns {number} - */ - kind(): number; -} -/** - */ -declare export class NetworkInfo { - free(): void; - - /** - * @param {number} network_id - * @param {number} protocol_magic - * @returns {NetworkInfo} + * @param {string} key + * @param {TransactionMetadatum} value + * @returns {TransactionMetadatum | void} */ - static new(network_id: number, protocol_magic: number): NetworkInfo; + insert_str( + key: string, + value: TransactionMetadatum + ): TransactionMetadatum | void; /** - * @returns {number} + * @param {number} key + * @param {TransactionMetadatum} value + * @returns {TransactionMetadatum | void} */ - network_id(): number; + insert_i32( + key: number, + value: TransactionMetadatum + ): TransactionMetadatum | void; /** - * @returns {number} + * @param {TransactionMetadatum} key + * @returns {TransactionMetadatum} */ - protocol_magic(): number; + get(key: TransactionMetadatum): TransactionMetadatum; /** - * @returns {NetworkInfo} + * @param {string} key + * @returns {TransactionMetadatum} */ - static testnet_preview(): NetworkInfo; + get_str(key: string): TransactionMetadatum; /** - * @returns {NetworkInfo} + * @param {number} key + * @returns {TransactionMetadatum} */ - static testnet_preprod(): NetworkInfo; + get_i32(key: number): TransactionMetadatum; /** - * !!! DEPRECATED !!! - * This network does not exist anymore. Use `.testnet_preview()` or `.testnet_preprod()` - * @returns {NetworkInfo} + * @param {TransactionMetadatum} key + * @returns {boolean} */ - static testnet(): NetworkInfo; + has(key: TransactionMetadatum): boolean; /** - * @returns {NetworkInfo} + * @returns {MetadataList} */ - static mainnet(): NetworkInfo; + keys(): MetadataList; } /** */ -declare export class Nonce { +declare export class Mint { free(): void; /** @@ -4571,9 +4842,9 @@ declare export class Nonce { /** * @param {Uint8Array} bytes - * @returns {Nonce} + * @returns {Mint} */ - static from_bytes(bytes: Uint8Array): Nonce; + static from_bytes(bytes: Uint8Array): Mint; /** * @returns {string} @@ -4582,9 +4853,9 @@ declare export class Nonce { /** * @param {string} hex_str - * @returns {Nonce} + * @returns {Mint} */ - static from_hex(hex_str: string): Nonce; + static from_hex(hex_str: string): Mint; /** * @returns {string} @@ -4592,264 +4863,280 @@ declare export class Nonce { to_json(): string; /** - * @returns {NonceJSON} + * @returns {MintJSON} */ - to_js_value(): NonceJSON; + to_js_value(): MintJSON; /** * @param {string} json - * @returns {Nonce} + * @returns {Mint} */ - static from_json(json: string): Nonce; + static from_json(json: string): Mint; /** - * @returns {Nonce} + * @returns {Mint} */ - static new_identity(): Nonce; + static new(): Mint; /** - * @param {Uint8Array} hash - * @returns {Nonce} + * @param {ScriptHash} key + * @param {MintAssets} value + * @returns {Mint} */ - static new_from_hash(hash: Uint8Array): Nonce; + static new_from_entry(key: ScriptHash, value: MintAssets): Mint; /** - * @returns {Uint8Array | void} + * @returns {number} */ - get_hash(): Uint8Array | void; -} -/** - */ -declare export class OperationalCert { - free(): void; + len(): number; /** - * @returns {Uint8Array} + * @param {ScriptHash} key + * @param {MintAssets} value + * @returns {MintAssets | void} */ - to_bytes(): Uint8Array; + insert(key: ScriptHash, value: MintAssets): MintAssets | void; /** - * @param {Uint8Array} bytes - * @returns {OperationalCert} + * !!! DEPRECATED !!! + * Mint can store multiple entries for the same policy id. + * Use `.get_all` instead. + * @param {ScriptHash} key + * @returns {MintAssets | void} */ - static from_bytes(bytes: Uint8Array): OperationalCert; + get(key: ScriptHash): MintAssets | void; /** - * @returns {string} + * @param {ScriptHash} key + * @returns {MintsAssets | void} */ - to_hex(): string; + get_all(key: ScriptHash): MintsAssets | void; /** - * @param {string} hex_str - * @returns {OperationalCert} + * @returns {ScriptHashes} */ - static from_hex(hex_str: string): OperationalCert; + keys(): ScriptHashes; /** - * @returns {string} + * Returns the multiasset where only positive (minting) entries are present + * @returns {MultiAsset} */ - to_json(): string; + as_positive_multiasset(): MultiAsset; /** - * @returns {OperationalCertJSON} + * Returns the multiasset where only negative (burning) entries are present + * @returns {MultiAsset} */ - to_js_value(): OperationalCertJSON; + as_negative_multiasset(): MultiAsset; +} +/** + */ +declare export class MintAssets { + free(): void; /** - * @param {string} json - * @returns {OperationalCert} + * @returns {MintAssets} */ - static from_json(json: string): OperationalCert; + static new(): MintAssets; /** - * @returns {KESVKey} + * @param {AssetName} key + * @param {Int} value + * @returns {MintAssets} */ - hot_vkey(): KESVKey; + static new_from_entry(key: AssetName, value: Int): MintAssets; /** * @returns {number} */ - sequence_number(): number; + len(): number; /** - * @returns {number} + * @param {AssetName} key + * @param {Int} value + * @returns {Int | void} */ - kes_period(): number; + insert(key: AssetName, value: Int): Int | void; /** - * @returns {Ed25519Signature} + * @param {AssetName} key + * @returns {Int | void} */ - sigma(): Ed25519Signature; + get(key: AssetName): Int | void; /** - * @param {KESVKey} hot_vkey - * @param {number} sequence_number - * @param {number} kes_period - * @param {Ed25519Signature} sigma - * @returns {OperationalCert} + * @returns {AssetNames} */ - static new( - hot_vkey: KESVKey, - sequence_number: number, - kes_period: number, - sigma: Ed25519Signature - ): OperationalCert; + keys(): AssetNames; } /** */ -declare export class OutputDatum { +declare export class MintBuilder { free(): void; /** - * @param {DataHash} data_hash - * @returns {OutputDatum} + * @returns {MintBuilder} */ - static new_data_hash(data_hash: DataHash): OutputDatum; + static new(): MintBuilder; /** - * @param {PlutusData} data - * @returns {OutputDatum} + * @param {MintWitness} mint + * @param {AssetName} asset_name + * @param {Int} amount */ - static new_data(data: PlutusData): OutputDatum; + add_asset(mint: MintWitness, asset_name: AssetName, amount: Int): void; /** - * @returns {DataHash | void} + * @param {MintWitness} mint + * @param {AssetName} asset_name + * @param {Int} amount */ - data_hash(): DataHash | void; + set_asset(mint: MintWitness, asset_name: AssetName, amount: Int): void; /** - * @returns {PlutusData | void} + * @returns {Mint} */ - data(): PlutusData | void; -} -/** - */ -declare export class PlutusData { - free(): void; + build(): Mint; /** - * @returns {Uint8Array} + * @returns {NativeScripts} */ - to_bytes(): Uint8Array; + get_native_scripts(): NativeScripts; /** - * @param {Uint8Array} bytes - * @returns {PlutusData} + * @returns {PlutusWitnesses} */ - static from_bytes(bytes: Uint8Array): PlutusData; + get_plutus_witnesses(): PlutusWitnesses; /** - * @returns {string} + * @returns {TransactionInputs} */ - to_hex(): string; + get_ref_inputs(): TransactionInputs; /** - * @param {string} hex_str - * @returns {PlutusData} + * @returns {Redeemers} */ - static from_hex(hex_str: string): PlutusData; + get_redeeemers(): Redeemers; /** - * @param {ConstrPlutusData} constr_plutus_data - * @returns {PlutusData} + * @returns {boolean} */ - static new_constr_plutus_data( - constr_plutus_data: ConstrPlutusData - ): PlutusData; + has_plutus_scripts(): boolean; /** - * Same as `.new_constr_plutus_data` but creates constr with empty data list - * @param {BigNum} alternative - * @returns {PlutusData} + * @returns {boolean} */ - static new_empty_constr_plutus_data(alternative: BigNum): PlutusData; + has_native_scripts(): boolean; +} +/** + */ +declare export class MintWitness { + free(): void; /** - * @param {BigNum} alternative - * @param {PlutusData} plutus_data - * @returns {PlutusData} + * @param {NativeScript} native_script + * @returns {MintWitness} */ - static new_single_value_constr_plutus_data( - alternative: BigNum, - plutus_data: PlutusData - ): PlutusData; + static new_native_script(native_script: NativeScript): MintWitness; /** - * @param {PlutusMap} map - * @returns {PlutusData} + * @param {PlutusScriptSource} plutus_script + * @param {Redeemer} redeemer + * @returns {MintWitness} */ - static new_map(map: PlutusMap): PlutusData; + static new_plutus_script( + plutus_script: PlutusScriptSource, + redeemer: Redeemer + ): MintWitness; +} +/** + */ +declare export class MintsAssets { + free(): void; +} +/** + */ +declare export class MoveInstantaneousReward { + free(): void; /** - * @param {PlutusList} list - * @returns {PlutusData} + * @returns {Uint8Array} */ - static new_list(list: PlutusList): PlutusData; + to_bytes(): Uint8Array; /** - * @param {BigInt} integer - * @returns {PlutusData} + * @param {Uint8Array} bytes + * @returns {MoveInstantaneousReward} */ - static new_integer(integer: BigInt): PlutusData; + static from_bytes(bytes: Uint8Array): MoveInstantaneousReward; /** - * @param {Uint8Array} bytes - * @returns {PlutusData} + * @returns {string} */ - static new_bytes(bytes: Uint8Array): PlutusData; + to_hex(): string; /** - * @returns {number} + * @param {string} hex_str + * @returns {MoveInstantaneousReward} */ - kind(): number; + static from_hex(hex_str: string): MoveInstantaneousReward; /** - * @returns {ConstrPlutusData | void} + * @returns {string} */ - as_constr_plutus_data(): ConstrPlutusData | void; + to_json(): string; /** - * @returns {PlutusMap | void} + * @returns {MoveInstantaneousRewardJSON} */ - as_map(): PlutusMap | void; + to_js_value(): MoveInstantaneousRewardJSON; /** - * @returns {PlutusList | void} + * @param {string} json + * @returns {MoveInstantaneousReward} */ - as_list(): PlutusList | void; + static from_json(json: string): MoveInstantaneousReward; /** - * @returns {BigInt | void} + * @param {number} pot + * @param {BigNum} amount + * @returns {MoveInstantaneousReward} */ - as_integer(): BigInt | void; + static new_to_other_pot(pot: number, amount: BigNum): MoveInstantaneousReward; /** - * @returns {Uint8Array | void} + * @param {number} pot + * @param {MIRToStakeCredentials} amounts + * @returns {MoveInstantaneousReward} */ - as_bytes(): Uint8Array | void; + static new_to_stake_creds( + pot: number, + amounts: MIRToStakeCredentials + ): MoveInstantaneousReward; /** - * @param {number} schema - * @returns {string} + * @returns {number} */ - to_json(schema: number): string; + pot(): number; /** - * @param {string} json - * @param {number} schema - * @returns {PlutusData} + * @returns {number} */ - static from_json(json: string, schema: number): PlutusData; + kind(): number; /** - * @param {Address} address - * @returns {PlutusData} + * @returns {BigNum | void} */ - static from_address(address: Address): PlutusData; + as_to_other_pot(): BigNum | void; + + /** + * @returns {MIRToStakeCredentials | void} + */ + as_to_stake_creds(): MIRToStakeCredentials | void; } /** */ -declare export class PlutusList { +declare export class MoveInstantaneousRewardsCert { free(): void; /** @@ -4859,9 +5146,9 @@ declare export class PlutusList { /** * @param {Uint8Array} bytes - * @returns {PlutusList} + * @returns {MoveInstantaneousRewardsCert} */ - static from_bytes(bytes: Uint8Array): PlutusList; + static from_bytes(bytes: Uint8Array): MoveInstantaneousRewardsCert; /** * @returns {string} @@ -4870,34 +5157,42 @@ declare export class PlutusList { /** * @param {string} hex_str - * @returns {PlutusList} + * @returns {MoveInstantaneousRewardsCert} */ - static from_hex(hex_str: string): PlutusList; + static from_hex(hex_str: string): MoveInstantaneousRewardsCert; /** - * @returns {PlutusList} + * @returns {string} */ - static new(): PlutusList; + to_json(): string; /** - * @returns {number} + * @returns {MoveInstantaneousRewardsCertJSON} */ - len(): number; + to_js_value(): MoveInstantaneousRewardsCertJSON; /** - * @param {number} index - * @returns {PlutusData} + * @param {string} json + * @returns {MoveInstantaneousRewardsCert} */ - get(index: number): PlutusData; + static from_json(json: string): MoveInstantaneousRewardsCert; /** - * @param {PlutusData} elem + * @returns {MoveInstantaneousReward} */ - add(elem: PlutusData): void; + move_instantaneous_reward(): MoveInstantaneousReward; + + /** + * @param {MoveInstantaneousReward} move_instantaneous_reward + * @returns {MoveInstantaneousRewardsCert} + */ + static new( + move_instantaneous_reward: MoveInstantaneousReward + ): MoveInstantaneousRewardsCert; } /** */ -declare export class PlutusMap { +declare export class MultiAsset { free(): void; /** @@ -4907,9 +5202,9 @@ declare export class PlutusMap { /** * @param {Uint8Array} bytes - * @returns {PlutusMap} + * @returns {MultiAsset} */ - static from_bytes(bytes: Uint8Array): PlutusMap; + static from_bytes(bytes: Uint8Array): MultiAsset; /** * @returns {string} @@ -4918,41 +5213,92 @@ declare export class PlutusMap { /** * @param {string} hex_str - * @returns {PlutusMap} + * @returns {MultiAsset} */ - static from_hex(hex_str: string): PlutusMap; + static from_hex(hex_str: string): MultiAsset; /** - * @returns {PlutusMap} + * @returns {string} */ - static new(): PlutusMap; + to_json(): string; + + /** + * @returns {MultiAssetJSON} + */ + to_js_value(): MultiAssetJSON; + + /** + * @param {string} json + * @returns {MultiAsset} + */ + static from_json(json: string): MultiAsset; + + /** + * @returns {MultiAsset} + */ + static new(): MultiAsset; /** + * the number of unique policy IDs in the multiasset * @returns {number} */ len(): number; /** - * @param {PlutusData} key - * @param {PlutusData} value - * @returns {PlutusData | void} + * set (and replace if it exists) all assets with policy {policy_id} to a copy of {assets} + * @param {ScriptHash} policy_id + * @param {Assets} assets + * @returns {Assets | void} */ - insert(key: PlutusData, value: PlutusData): PlutusData | void; + insert(policy_id: ScriptHash, assets: Assets): Assets | void; /** - * @param {PlutusData} key - * @returns {PlutusData | void} + * all assets under {policy_id}, if any exist, or else None (undefined in JS) + * @param {ScriptHash} policy_id + * @returns {Assets | void} */ - get(key: PlutusData): PlutusData | void; + get(policy_id: ScriptHash): Assets | void; /** - * @returns {PlutusList} + * sets the asset {asset_name} to {value} under policy {policy_id} + * returns the previous amount if it was set, or else None (undefined in JS) + * @param {ScriptHash} policy_id + * @param {AssetName} asset_name + * @param {BigNum} value + * @returns {BigNum | void} */ - keys(): PlutusList; + set_asset( + policy_id: ScriptHash, + asset_name: AssetName, + value: BigNum + ): BigNum | void; + + /** + * returns the amount of asset {asset_name} under policy {policy_id} + * If such an asset does not exist, 0 is returned. + * @param {ScriptHash} policy_id + * @param {AssetName} asset_name + * @returns {BigNum} + */ + get_asset(policy_id: ScriptHash, asset_name: AssetName): BigNum; + + /** + * returns all policy IDs used by assets in this multiasset + * @returns {ScriptHashes} + */ + keys(): ScriptHashes; + + /** + * removes an asset from the list if the result is 0 or less + * does not modify this object, instead the result is returned + * @param {MultiAsset} rhs_ma + * @returns {MultiAsset} + */ + sub(rhs_ma: MultiAsset): MultiAsset; } /** */ -declare export class PlutusScript { +declare export class MultiHostName { free(): void; /** @@ -4962,9 +5308,9 @@ declare export class PlutusScript { /** * @param {Uint8Array} bytes - * @returns {PlutusScript} + * @returns {MultiHostName} */ - static from_bytes(bytes: Uint8Array): PlutusScript; + static from_bytes(bytes: Uint8Array): MultiHostName; /** * @returns {string} @@ -4973,262 +5319,196 @@ declare export class PlutusScript { /** * @param {string} hex_str - * @returns {PlutusScript} + * @returns {MultiHostName} */ - static from_hex(hex_str: string): PlutusScript; + static from_hex(hex_str: string): MultiHostName; /** - * - * * Creates a new Plutus script from the RAW bytes of the compiled script. - * * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) - * * If you creating this from those you should use PlutusScript::from_bytes() instead. - * @param {Uint8Array} bytes - * @returns {PlutusScript} + * @returns {string} */ - static new(bytes: Uint8Array): PlutusScript; + to_json(): string; /** - * - * * Creates a new Plutus script from the RAW bytes of the compiled script. - * * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) - * * If you creating this from those you should use PlutusScript::from_bytes() instead. - * @param {Uint8Array} bytes - * @returns {PlutusScript} + * @returns {MultiHostNameJSON} */ - static new_v2(bytes: Uint8Array): PlutusScript; + to_js_value(): MultiHostNameJSON; /** - * - * * Creates a new Plutus script from the RAW bytes of the compiled script. - * * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) - * * If you creating this from those you should use PlutusScript::from_bytes() instead. - * @param {Uint8Array} bytes - * @param {Language} language - * @returns {PlutusScript} + * @param {string} json + * @returns {MultiHostName} */ - static new_with_version(bytes: Uint8Array, language: Language): PlutusScript; + static from_json(json: string): MultiHostName; /** - * - * * The raw bytes of this compiled Plutus script. - * * If you need "cborBytes" for cardano-cli use PlutusScript::to_bytes() instead. - * @returns {Uint8Array} + * @returns {DNSRecordSRV} */ - bytes(): Uint8Array; + dns_name(): DNSRecordSRV; /** - * Same as `.from_bytes` but will consider the script as requiring the Plutus Language V2 - * @param {Uint8Array} bytes - * @returns {PlutusScript} - */ - static from_bytes_v2(bytes: Uint8Array): PlutusScript; - - /** - * Same as `.from_bytes` but will consider the script as requiring the specified language version - * @param {Uint8Array} bytes - * @param {Language} language - * @returns {PlutusScript} + * @param {DNSRecordSRV} dns_name + * @returns {MultiHostName} */ - static from_bytes_with_version( - bytes: Uint8Array, - language: Language - ): PlutusScript; + static new(dns_name: DNSRecordSRV): MultiHostName; +} +/** + */ +declare export class NativeScript { + free(): void; /** - * Same as .from_hex but will consider the script as requiring the specified language version - * @param {string} hex_str - * @param {Language} language - * @returns {PlutusScript} + * @returns {Uint8Array} */ - static from_hex_with_version( - hex_str: string, - language: Language - ): PlutusScript; + to_bytes(): Uint8Array; /** - * @returns {ScriptHash} + * @param {Uint8Array} bytes + * @returns {NativeScript} */ - hash(): ScriptHash; + static from_bytes(bytes: Uint8Array): NativeScript; /** - * @returns {Language} + * @returns {string} */ - language_version(): Language; -} -/** - */ -declare export class PlutusScriptSource { - free(): void; + to_hex(): string; /** - * @param {PlutusScript} script - * @returns {PlutusScriptSource} + * @param {string} hex_str + * @returns {NativeScript} */ - static new(script: PlutusScript): PlutusScriptSource; + static from_hex(hex_str: string): NativeScript; /** - * !!! DEPRECATED !!! - * This constructor has missed information about plutus script language vesrion. That can affect - * the script data hash calculation. - * Use `.new_ref_input_with_lang_ver` instead - * @param {ScriptHash} script_hash - * @param {TransactionInput} input - * @returns {PlutusScriptSource} + * @returns {string} */ - static new_ref_input( - script_hash: ScriptHash, - input: TransactionInput - ): PlutusScriptSource; + to_json(): string; /** - * @param {ScriptHash} script_hash - * @param {TransactionInput} input - * @param {Language} lang_ver - * @returns {PlutusScriptSource} + * @returns {NativeScriptJSON} */ - static new_ref_input_with_lang_ver( - script_hash: ScriptHash, - input: TransactionInput, - lang_ver: Language - ): PlutusScriptSource; -} -/** - */ -declare export class PlutusScripts { - free(): void; + to_js_value(): NativeScriptJSON; /** - * @returns {Uint8Array} + * @param {string} json + * @returns {NativeScript} */ - to_bytes(): Uint8Array; + static from_json(json: string): NativeScript; /** - * @param {Uint8Array} bytes - * @returns {PlutusScripts} + * @returns {ScriptHash} */ - static from_bytes(bytes: Uint8Array): PlutusScripts; + hash(): ScriptHash; /** - * @returns {string} + * @param {ScriptPubkey} script_pubkey + * @returns {NativeScript} */ - to_hex(): string; + static new_script_pubkey(script_pubkey: ScriptPubkey): NativeScript; /** - * @param {string} hex_str - * @returns {PlutusScripts} + * @param {ScriptAll} script_all + * @returns {NativeScript} */ - static from_hex(hex_str: string): PlutusScripts; + static new_script_all(script_all: ScriptAll): NativeScript; /** - * @returns {string} + * @param {ScriptAny} script_any + * @returns {NativeScript} */ - to_json(): string; + static new_script_any(script_any: ScriptAny): NativeScript; /** - * @returns {PlutusScriptsJSON} + * @param {ScriptNOfK} script_n_of_k + * @returns {NativeScript} */ - to_js_value(): PlutusScriptsJSON; + static new_script_n_of_k(script_n_of_k: ScriptNOfK): NativeScript; /** - * @param {string} json - * @returns {PlutusScripts} + * @param {TimelockStart} timelock_start + * @returns {NativeScript} */ - static from_json(json: string): PlutusScripts; + static new_timelock_start(timelock_start: TimelockStart): NativeScript; /** - * @returns {PlutusScripts} + * @param {TimelockExpiry} timelock_expiry + * @returns {NativeScript} */ - static new(): PlutusScripts; + static new_timelock_expiry(timelock_expiry: TimelockExpiry): NativeScript; /** * @returns {number} */ - len(): number; + kind(): number; /** - * @param {number} index - * @returns {PlutusScript} + * @returns {ScriptPubkey | void} */ - get(index: number): PlutusScript; + as_script_pubkey(): ScriptPubkey | void; /** - * @param {PlutusScript} elem + * @returns {ScriptAll | void} */ - add(elem: PlutusScript): void; -} -/** - */ -declare export class PlutusWitness { - free(): void; + as_script_all(): ScriptAll | void; /** - * @param {PlutusScript} script - * @param {PlutusData} datum - * @param {Redeemer} redeemer - * @returns {PlutusWitness} + * @returns {ScriptAny | void} */ - static new( - script: PlutusScript, - datum: PlutusData, - redeemer: Redeemer - ): PlutusWitness; + as_script_any(): ScriptAny | void; /** - * @param {PlutusScriptSource} script - * @param {DatumSource} datum - * @param {Redeemer} redeemer - * @returns {PlutusWitness} + * @returns {ScriptNOfK | void} */ - static new_with_ref( - script: PlutusScriptSource, - datum: DatumSource, - redeemer: Redeemer - ): PlutusWitness; + as_script_n_of_k(): ScriptNOfK | void; /** - * @param {PlutusScript} script - * @param {Redeemer} redeemer - * @returns {PlutusWitness} + * @returns {TimelockStart | void} */ - static new_without_datum( - script: PlutusScript, - redeemer: Redeemer - ): PlutusWitness; + as_timelock_start(): TimelockStart | void; /** - * @param {PlutusScriptSource} script - * @param {Redeemer} redeemer - * @returns {PlutusWitness} + * @returns {TimelockExpiry | void} */ - static new_with_ref_without_datum( - script: PlutusScriptSource, - redeemer: Redeemer - ): PlutusWitness; + as_timelock_expiry(): TimelockExpiry | void; /** - * @returns {PlutusScript | void} + * Returns an array of unique Ed25519KeyHashes + * contained within this script recursively on any depth level. + * The order of the keys in the result is not determined in any way. + * @returns {Ed25519KeyHashes} */ - script(): PlutusScript | void; + get_required_signers(): Ed25519KeyHashes; +} +/** + */ +declare export class NativeScriptSource { + free(): void; /** - * @returns {PlutusData | void} + * @param {NativeScript} script + * @returns {NativeScriptSource} */ - datum(): PlutusData | void; + static new(script: NativeScript): NativeScriptSource; /** - * @returns {Redeemer} + * @param {ScriptHash} script_hash + * @param {TransactionInput} input + * @param {Ed25519KeyHashes} required_signers + * @returns {NativeScriptSource} */ - redeemer(): Redeemer; + static new_ref_input( + script_hash: ScriptHash, + input: TransactionInput, + required_signers: Ed25519KeyHashes + ): NativeScriptSource; } /** */ -declare export class PlutusWitnesses { +declare export class NativeScripts { free(): void; /** - * @returns {PlutusWitnesses} + * @returns {NativeScripts} */ - static new(): PlutusWitnesses; + static new(): NativeScripts; /** * @returns {number} @@ -5237,114 +5517,120 @@ declare export class PlutusWitnesses { /** * @param {number} index - * @returns {PlutusWitness} + * @returns {NativeScript} */ - get(index: number): PlutusWitness; + get(index: number): NativeScript; /** - * @param {PlutusWitness} elem + * @param {NativeScript} elem */ - add(elem: PlutusWitness): void; + add(elem: NativeScript): void; } /** */ -declare export class Pointer { +declare export class NetworkId { free(): void; /** - * !!! DEPRECATED !!! - * This constructor uses outdated slot number format for the ttl value, tx_index and cert_index. - * Use `.new_pointer` instead - * @param {number} slot - * @param {number} tx_index - * @param {number} cert_index - * @returns {Pointer} + * @returns {Uint8Array} */ - static new(slot: number, tx_index: number, cert_index: number): Pointer; + to_bytes(): Uint8Array; /** - * @param {BigNum} slot - * @param {BigNum} tx_index - * @param {BigNum} cert_index - * @returns {Pointer} + * @param {Uint8Array} bytes + * @returns {NetworkId} */ - static new_pointer( - slot: BigNum, - tx_index: BigNum, - cert_index: BigNum - ): Pointer; + static from_bytes(bytes: Uint8Array): NetworkId; /** - * @returns {number} + * @returns {string} */ - slot(): number; + to_hex(): string; /** - * @returns {number} + * @param {string} hex_str + * @returns {NetworkId} */ - tx_index(): number; + static from_hex(hex_str: string): NetworkId; /** - * @returns {number} + * @returns {string} */ - cert_index(): number; + to_json(): string; /** - * @returns {BigNum} + * @returns {NetworkIdJSON} */ - slot_bignum(): BigNum; + to_js_value(): NetworkIdJSON; /** - * @returns {BigNum} - */ - tx_index_bignum(): BigNum; + * @param {string} json + * @returns {NetworkId} + */ + static from_json(json: string): NetworkId; /** - * @returns {BigNum} + * @returns {NetworkId} */ - cert_index_bignum(): BigNum; + static testnet(): NetworkId; + + /** + * @returns {NetworkId} + */ + static mainnet(): NetworkId; + + /** + * @returns {number} + */ + kind(): number; } /** */ -declare export class PointerAddress { +declare export class NetworkInfo { free(): void; /** - * @param {number} network - * @param {StakeCredential} payment - * @param {Pointer} stake - * @returns {PointerAddress} + * @param {number} network_id + * @param {number} protocol_magic + * @returns {NetworkInfo} */ - static new( - network: number, - payment: StakeCredential, - stake: Pointer - ): PointerAddress; + static new(network_id: number, protocol_magic: number): NetworkInfo; /** - * @returns {StakeCredential} + * @returns {number} */ - payment_cred(): StakeCredential; + network_id(): number; /** - * @returns {Pointer} + * @returns {number} */ - stake_pointer(): Pointer; + protocol_magic(): number; /** - * @returns {Address} + * @returns {NetworkInfo} */ - to_address(): Address; + static testnet_preview(): NetworkInfo; /** - * @param {Address} addr - * @returns {PointerAddress | void} + * @returns {NetworkInfo} */ - static from_address(addr: Address): PointerAddress | void; + static testnet_preprod(): NetworkInfo; + + /** + * !!! DEPRECATED !!! + * This network does not exist anymore. Use `.testnet_preview()` or `.testnet_preprod()` + * @returns {NetworkInfo} + */ + static testnet(): NetworkInfo; + + /** + * @returns {NetworkInfo} + */ + static mainnet(): NetworkInfo; } /** */ -declare export class PoolMetadata { +declare export class NewCommitteeProposal { free(): void; /** @@ -5354,9 +5640,9 @@ declare export class PoolMetadata { /** * @param {Uint8Array} bytes - * @returns {PoolMetadata} + * @returns {NewCommitteeProposal} */ - static from_bytes(bytes: Uint8Array): PoolMetadata; + static from_bytes(bytes: Uint8Array): NewCommitteeProposal; /** * @returns {string} @@ -5365,9 +5651,9 @@ declare export class PoolMetadata { /** * @param {string} hex_str - * @returns {PoolMetadata} + * @returns {NewCommitteeProposal} */ - static from_hex(hex_str: string): PoolMetadata; + static from_hex(hex_str: string): NewCommitteeProposal; /** * @returns {string} @@ -5375,75 +5661,56 @@ declare export class PoolMetadata { to_json(): string; /** - * @returns {PoolMetadataJSON} + * @returns {NewCommitteeProposalJSON} */ - to_js_value(): PoolMetadataJSON; + to_js_value(): NewCommitteeProposalJSON; /** * @param {string} json - * @returns {PoolMetadata} - */ - static from_json(json: string): PoolMetadata; - - /** - * @returns {URL} - */ - url(): URL; - - /** - * @returns {PoolMetadataHash} - */ - pool_metadata_hash(): PoolMetadataHash; - - /** - * @param {URL} url - * @param {PoolMetadataHash} pool_metadata_hash - * @returns {PoolMetadata} - */ - static new(url: URL, pool_metadata_hash: PoolMetadataHash): PoolMetadata; -} -/** - */ -declare export class PoolMetadataHash { - free(): void; - - /** - * @param {Uint8Array} bytes - * @returns {PoolMetadataHash} + * @returns {NewCommitteeProposal} */ - static from_bytes(bytes: Uint8Array): PoolMetadataHash; + static from_json(json: string): NewCommitteeProposal; /** - * @returns {Uint8Array} + * @returns {GovernanceActionId | void} */ - to_bytes(): Uint8Array; + gov_action_id(): GovernanceActionId | void; /** - * @param {string} prefix - * @returns {string} + * @returns {Committee} */ - to_bech32(prefix: string): string; + committee(): Committee; /** - * @param {string} bech_str - * @returns {PoolMetadataHash} + * @returns {StakeCredentials} */ - static from_bech32(bech_str: string): PoolMetadataHash; + members_to_remove(): StakeCredentials; /** - * @returns {string} + * @param {Committee} committee + * @param {StakeCredentials} members_to_remove + * @returns {NewCommitteeProposal} */ - to_hex(): string; + static new( + committee: Committee, + members_to_remove: StakeCredentials + ): NewCommitteeProposal; /** - * @param {string} hex - * @returns {PoolMetadataHash} + * @param {GovernanceActionId} gov_action_id + * @param {Committee} committee + * @param {StakeCredentials} members_to_remove + * @returns {NewCommitteeProposal} */ - static from_hex(hex: string): PoolMetadataHash; + static new_with_action_id( + gov_action_id: GovernanceActionId, + committee: Committee, + members_to_remove: StakeCredentials + ): NewCommitteeProposal; } /** */ -declare export class PoolParams { +declare export class NewConstitutionProposal { free(): void; /** @@ -5453,9 +5720,9 @@ declare export class PoolParams { /** * @param {Uint8Array} bytes - * @returns {PoolParams} + * @returns {NewConstitutionProposal} */ - static from_bytes(bytes: Uint8Array): PoolParams; + static from_bytes(bytes: Uint8Array): NewConstitutionProposal; /** * @returns {string} @@ -5464,9 +5731,9 @@ declare export class PoolParams { /** * @param {string} hex_str - * @returns {PoolParams} + * @returns {NewConstitutionProposal} */ - static from_hex(hex_str: string): PoolParams; + static from_hex(hex_str: string): NewConstitutionProposal; /** * @returns {string} @@ -5474,88 +5741,62 @@ declare export class PoolParams { to_json(): string; /** - * @returns {PoolParamsJSON} + * @returns {NewConstitutionProposalJSON} */ - to_js_value(): PoolParamsJSON; + to_js_value(): NewConstitutionProposalJSON; /** * @param {string} json - * @returns {PoolParams} - */ - static from_json(json: string): PoolParams; - - /** - * @returns {Ed25519KeyHash} + * @returns {NewConstitutionProposal} */ - operator(): Ed25519KeyHash; - - /** - * @returns {VRFKeyHash} - */ - vrf_keyhash(): VRFKeyHash; - - /** - * @returns {BigNum} - */ - pledge(): BigNum; + static from_json(json: string): NewConstitutionProposal; +} +/** + */ +declare export class NoConfidenceProposal { + free(): void; /** - * @returns {BigNum} + * @returns {Uint8Array} */ - cost(): BigNum; + to_bytes(): Uint8Array; /** - * @returns {UnitInterval} + * @param {Uint8Array} bytes + * @returns {NoConfidenceProposal} */ - margin(): UnitInterval; + static from_bytes(bytes: Uint8Array): NoConfidenceProposal; /** - * @returns {RewardAddress} + * @returns {string} */ - reward_account(): RewardAddress; + to_hex(): string; /** - * @returns {Ed25519KeyHashes} + * @param {string} hex_str + * @returns {NoConfidenceProposal} */ - pool_owners(): Ed25519KeyHashes; + static from_hex(hex_str: string): NoConfidenceProposal; /** - * @returns {Relays} + * @returns {string} */ - relays(): Relays; + to_json(): string; /** - * @returns {PoolMetadata | void} + * @returns {NoConfidenceProposalJSON} */ - pool_metadata(): PoolMetadata | void; + to_js_value(): NoConfidenceProposalJSON; /** - * @param {Ed25519KeyHash} operator - * @param {VRFKeyHash} vrf_keyhash - * @param {BigNum} pledge - * @param {BigNum} cost - * @param {UnitInterval} margin - * @param {RewardAddress} reward_account - * @param {Ed25519KeyHashes} pool_owners - * @param {Relays} relays - * @param {PoolMetadata | void} pool_metadata - * @returns {PoolParams} + * @param {string} json + * @returns {NoConfidenceProposal} */ - static new( - operator: Ed25519KeyHash, - vrf_keyhash: VRFKeyHash, - pledge: BigNum, - cost: BigNum, - margin: UnitInterval, - reward_account: RewardAddress, - pool_owners: Ed25519KeyHashes, - relays: Relays, - pool_metadata?: PoolMetadata - ): PoolParams; + static from_json(json: string): NoConfidenceProposal; } /** */ -declare export class PoolRegistration { +declare export class Nonce { free(): void; /** @@ -5565,9 +5806,9 @@ declare export class PoolRegistration { /** * @param {Uint8Array} bytes - * @returns {PoolRegistration} + * @returns {Nonce} */ - static from_bytes(bytes: Uint8Array): PoolRegistration; + static from_bytes(bytes: Uint8Array): Nonce; /** * @returns {string} @@ -5576,9 +5817,9 @@ declare export class PoolRegistration { /** * @param {string} hex_str - * @returns {PoolRegistration} + * @returns {Nonce} */ - static from_hex(hex_str: string): PoolRegistration; + static from_hex(hex_str: string): Nonce; /** * @returns {string} @@ -5586,30 +5827,35 @@ declare export class PoolRegistration { to_json(): string; /** - * @returns {PoolRegistrationJSON} + * @returns {NonceJSON} */ - to_js_value(): PoolRegistrationJSON; + to_js_value(): NonceJSON; /** * @param {string} json - * @returns {PoolRegistration} + * @returns {Nonce} */ - static from_json(json: string): PoolRegistration; + static from_json(json: string): Nonce; /** - * @returns {PoolParams} + * @returns {Nonce} */ - pool_params(): PoolParams; + static new_identity(): Nonce; /** - * @param {PoolParams} pool_params - * @returns {PoolRegistration} + * @param {Uint8Array} hash + * @returns {Nonce} */ - static new(pool_params: PoolParams): PoolRegistration; + static new_from_hash(hash: Uint8Array): Nonce; + + /** + * @returns {Uint8Array | void} + */ + get_hash(): Uint8Array | void; } /** */ -declare export class PoolRetirement { +declare export class OperationalCert { free(): void; /** @@ -5619,9 +5865,9 @@ declare export class PoolRetirement { /** * @param {Uint8Array} bytes - * @returns {PoolRetirement} + * @returns {OperationalCert} */ - static from_bytes(bytes: Uint8Array): PoolRetirement; + static from_bytes(bytes: Uint8Array): OperationalCert; /** * @returns {string} @@ -5630,9 +5876,9 @@ declare export class PoolRetirement { /** * @param {string} hex_str - * @returns {PoolRetirement} + * @returns {OperationalCert} */ - static from_hex(hex_str: string): PoolRetirement; + static from_hex(hex_str: string): OperationalCert; /** * @returns {string} @@ -5640,109 +5886,80 @@ declare export class PoolRetirement { to_json(): string; /** - * @returns {PoolRetirementJSON} + * @returns {OperationalCertJSON} */ - to_js_value(): PoolRetirementJSON; + to_js_value(): OperationalCertJSON; /** * @param {string} json - * @returns {PoolRetirement} + * @returns {OperationalCert} */ - static from_json(json: string): PoolRetirement; + static from_json(json: string): OperationalCert; /** - * @returns {Ed25519KeyHash} + * @returns {KESVKey} */ - pool_keyhash(): Ed25519KeyHash; + hot_vkey(): KESVKey; /** * @returns {number} */ - epoch(): number; + sequence_number(): number; /** - * @param {Ed25519KeyHash} pool_keyhash - * @param {number} epoch - * @returns {PoolRetirement} + * @returns {number} */ - static new(pool_keyhash: Ed25519KeyHash, epoch: number): PoolRetirement; -} -/** - */ -declare export class PrivateKey { - free(): void; + kes_period(): number; /** - * @returns {PublicKey} + * @returns {Ed25519Signature} */ - to_public(): PublicKey; - - /** - * @returns {PrivateKey} - */ - static generate_ed25519(): PrivateKey; - - /** - * @returns {PrivateKey} - */ - static generate_ed25519extended(): PrivateKey; - - /** - * Get private key from its bech32 representation - * ```javascript - * PrivateKey.from_bech32('ed25519_sk1ahfetf02qwwg4dkq7mgp4a25lx5vh9920cr5wnxmpzz9906qvm8qwvlts0'); - * ``` - * For an extended 25519 key - * ```javascript - * PrivateKey.from_bech32('ed25519e_sk1gqwl4szuwwh6d0yk3nsqcc6xxc3fpvjlevgwvt60df59v8zd8f8prazt8ln3lmz096ux3xvhhvm3ca9wj2yctdh3pnw0szrma07rt5gl748fp'); - * ``` - * @param {string} bech32_str - * @returns {PrivateKey} - */ - static from_bech32(bech32_str: string): PrivateKey; - - /** - * @returns {string} - */ - to_bech32(): string; - - /** - * @returns {Uint8Array} - */ - as_bytes(): Uint8Array; + sigma(): Ed25519Signature; /** - * @param {Uint8Array} bytes - * @returns {PrivateKey} + * @param {KESVKey} hot_vkey + * @param {number} sequence_number + * @param {number} kes_period + * @param {Ed25519Signature} sigma + * @returns {OperationalCert} */ - static from_extended_bytes(bytes: Uint8Array): PrivateKey; + static new( + hot_vkey: KESVKey, + sequence_number: number, + kes_period: number, + sigma: Ed25519Signature + ): OperationalCert; +} +/** + */ +declare export class OutputDatum { + free(): void; /** - * @param {Uint8Array} bytes - * @returns {PrivateKey} + * @param {DataHash} data_hash + * @returns {OutputDatum} */ - static from_normal_bytes(bytes: Uint8Array): PrivateKey; + static new_data_hash(data_hash: DataHash): OutputDatum; /** - * @param {Uint8Array} message - * @returns {Ed25519Signature} + * @param {PlutusData} data + * @returns {OutputDatum} */ - sign(message: Uint8Array): Ed25519Signature; + static new_data(data: PlutusData): OutputDatum; /** - * @returns {string} + * @returns {DataHash | void} */ - to_hex(): string; + data_hash(): DataHash | void; /** - * @param {string} hex_str - * @returns {PrivateKey} + * @returns {PlutusData | void} */ - static from_hex(hex_str: string): PrivateKey; + data(): PlutusData | void; } /** */ -declare export class ProposedProtocolParameterUpdates { +declare export class ParameterChangeProposal { free(): void; /** @@ -5752,9 +5969,9 @@ declare export class ProposedProtocolParameterUpdates { /** * @param {Uint8Array} bytes - * @returns {ProposedProtocolParameterUpdates} + * @returns {ParameterChangeProposal} */ - static from_bytes(bytes: Uint8Array): ProposedProtocolParameterUpdates; + static from_bytes(bytes: Uint8Array): ParameterChangeProposal; /** * @returns {string} @@ -5763,9 +5980,9 @@ declare export class ProposedProtocolParameterUpdates { /** * @param {string} hex_str - * @returns {ProposedProtocolParameterUpdates} + * @returns {ParameterChangeProposal} */ - static from_hex(hex_str: string): ProposedProtocolParameterUpdates; + static from_hex(hex_str: string): ParameterChangeProposal; /** * @returns {string} @@ -5773,50 +5990,47 @@ declare export class ProposedProtocolParameterUpdates { to_json(): string; /** - * @returns {ProposedProtocolParameterUpdatesJSON} + * @returns {ParameterChangeProposalJSON} */ - to_js_value(): ProposedProtocolParameterUpdatesJSON; + to_js_value(): ParameterChangeProposalJSON; /** * @param {string} json - * @returns {ProposedProtocolParameterUpdates} - */ - static from_json(json: string): ProposedProtocolParameterUpdates; - - /** - * @returns {ProposedProtocolParameterUpdates} + * @returns {ParameterChangeProposal} */ - static new(): ProposedProtocolParameterUpdates; + static from_json(json: string): ParameterChangeProposal; /** - * @returns {number} + * @returns {GovernanceActionId | void} */ - len(): number; + gov_action_id(): GovernanceActionId | void; /** - * @param {GenesisHash} key - * @param {ProtocolParamUpdate} value - * @returns {ProtocolParamUpdate | void} + * @returns {ProtocolParamUpdate} */ - insert( - key: GenesisHash, - value: ProtocolParamUpdate - ): ProtocolParamUpdate | void; + protocol_param_updates(): ProtocolParamUpdate; /** - * @param {GenesisHash} key - * @returns {ProtocolParamUpdate | void} + * @param {ProtocolParamUpdate} protocol_param_updates + * @returns {ParameterChangeProposal} */ - get(key: GenesisHash): ProtocolParamUpdate | void; + static new( + protocol_param_updates: ProtocolParamUpdate + ): ParameterChangeProposal; /** - * @returns {GenesisHashes} + * @param {GovernanceActionId} gov_action_id + * @param {ProtocolParamUpdate} protocol_param_updates + * @returns {ParameterChangeProposal} */ - keys(): GenesisHashes; + static new_with_action_id( + gov_action_id: GovernanceActionId, + protocol_param_updates: ProtocolParamUpdate + ): ParameterChangeProposal; } /** */ -declare export class ProtocolParamUpdate { +declare export class PlutusData { free(): void; /** @@ -5826,9 +6040,9 @@ declare export class ProtocolParamUpdate { /** * @param {Uint8Array} bytes - * @returns {ProtocolParamUpdate} + * @returns {PlutusData} */ - static from_bytes(bytes: Uint8Array): ProtocolParamUpdate; + static from_bytes(bytes: Uint8Array): PlutusData; /** * @returns {string} @@ -5837,268 +6051,356 @@ declare export class ProtocolParamUpdate { /** * @param {string} hex_str - * @returns {ProtocolParamUpdate} + * @returns {PlutusData} */ - static from_hex(hex_str: string): ProtocolParamUpdate; + static from_hex(hex_str: string): PlutusData; /** - * @returns {string} + * @param {ConstrPlutusData} constr_plutus_data + * @returns {PlutusData} */ - to_json(): string; + static new_constr_plutus_data( + constr_plutus_data: ConstrPlutusData + ): PlutusData; /** - * @returns {ProtocolParamUpdateJSON} + * Same as `.new_constr_plutus_data` but creates constr with empty data list + * @param {BigNum} alternative + * @returns {PlutusData} */ - to_js_value(): ProtocolParamUpdateJSON; + static new_empty_constr_plutus_data(alternative: BigNum): PlutusData; /** - * @param {string} json - * @returns {ProtocolParamUpdate} + * @param {BigNum} alternative + * @param {PlutusData} plutus_data + * @returns {PlutusData} */ - static from_json(json: string): ProtocolParamUpdate; + static new_single_value_constr_plutus_data( + alternative: BigNum, + plutus_data: PlutusData + ): PlutusData; /** - * @param {BigNum} minfee_a + * @param {PlutusMap} map + * @returns {PlutusData} */ - set_minfee_a(minfee_a: BigNum): void; + static new_map(map: PlutusMap): PlutusData; /** - * @returns {BigNum | void} + * @param {PlutusList} list + * @returns {PlutusData} */ - minfee_a(): BigNum | void; + static new_list(list: PlutusList): PlutusData; /** - * @param {BigNum} minfee_b + * @param {BigInt} integer + * @returns {PlutusData} */ - set_minfee_b(minfee_b: BigNum): void; + static new_integer(integer: BigInt): PlutusData; /** - * @returns {BigNum | void} + * @param {Uint8Array} bytes + * @returns {PlutusData} */ - minfee_b(): BigNum | void; + static new_bytes(bytes: Uint8Array): PlutusData; /** - * @param {number} max_block_body_size + * @returns {number} */ - set_max_block_body_size(max_block_body_size: number): void; + kind(): number; /** - * @returns {number | void} + * @returns {ConstrPlutusData | void} */ - max_block_body_size(): number | void; + as_constr_plutus_data(): ConstrPlutusData | void; /** - * @param {number} max_tx_size + * @returns {PlutusMap | void} */ - set_max_tx_size(max_tx_size: number): void; + as_map(): PlutusMap | void; /** - * @returns {number | void} + * @returns {PlutusList | void} */ - max_tx_size(): number | void; + as_list(): PlutusList | void; /** - * @param {number} max_block_header_size + * @returns {BigInt | void} */ - set_max_block_header_size(max_block_header_size: number): void; + as_integer(): BigInt | void; /** - * @returns {number | void} + * @returns {Uint8Array | void} */ - max_block_header_size(): number | void; + as_bytes(): Uint8Array | void; /** - * @param {BigNum} key_deposit + * @param {number} schema + * @returns {string} */ - set_key_deposit(key_deposit: BigNum): void; + to_json(schema: number): string; /** - * @returns {BigNum | void} + * @param {string} json + * @param {number} schema + * @returns {PlutusData} */ - key_deposit(): BigNum | void; + static from_json(json: string, schema: number): PlutusData; /** - * @param {BigNum} pool_deposit + * @param {Address} address + * @returns {PlutusData} */ - set_pool_deposit(pool_deposit: BigNum): void; + static from_address(address: Address): PlutusData; +} +/** + */ +declare export class PlutusList { + free(): void; /** - * @returns {BigNum | void} + * @returns {Uint8Array} */ - pool_deposit(): BigNum | void; + to_bytes(): Uint8Array; /** - * @param {number} max_epoch + * @param {Uint8Array} bytes + * @returns {PlutusList} */ - set_max_epoch(max_epoch: number): void; + static from_bytes(bytes: Uint8Array): PlutusList; /** - * @returns {number | void} + * @returns {string} */ - max_epoch(): number | void; + to_hex(): string; /** - * @param {number} n_opt + * @param {string} hex_str + * @returns {PlutusList} */ - set_n_opt(n_opt: number): void; + static from_hex(hex_str: string): PlutusList; /** - * @returns {number | void} + * @returns {PlutusList} */ - n_opt(): number | void; + static new(): PlutusList; /** - * @param {UnitInterval} pool_pledge_influence + * @returns {number} */ - set_pool_pledge_influence(pool_pledge_influence: UnitInterval): void; + len(): number; /** - * @returns {UnitInterval | void} + * @param {number} index + * @returns {PlutusData} */ - pool_pledge_influence(): UnitInterval | void; + get(index: number): PlutusData; /** - * @param {UnitInterval} expansion_rate + * @param {PlutusData} elem */ - set_expansion_rate(expansion_rate: UnitInterval): void; + add(elem: PlutusData): void; +} +/** + */ +declare export class PlutusMap { + free(): void; /** - * @returns {UnitInterval | void} + * @returns {Uint8Array} */ - expansion_rate(): UnitInterval | void; + to_bytes(): Uint8Array; /** - * @param {UnitInterval} treasury_growth_rate + * @param {Uint8Array} bytes + * @returns {PlutusMap} */ - set_treasury_growth_rate(treasury_growth_rate: UnitInterval): void; + static from_bytes(bytes: Uint8Array): PlutusMap; /** - * @returns {UnitInterval | void} + * @returns {string} */ - treasury_growth_rate(): UnitInterval | void; + to_hex(): string; /** - * !!! DEPRECATED !!! - * Since babbage era this param is outdated. But this param you can meet in a pre-babbage block. - * @returns {UnitInterval | void} - */ - d(): UnitInterval | void; - - /** - * !!! DEPRECATED !!! - * Since babbage era this param is outdated. But this param you can meet in a pre-babbage block. - * @returns {Nonce | void} + * @param {string} hex_str + * @returns {PlutusMap} */ - extra_entropy(): Nonce | void; + static from_hex(hex_str: string): PlutusMap; /** - * @param {ProtocolVersion} protocol_version + * @returns {PlutusMap} */ - set_protocol_version(protocol_version: ProtocolVersion): void; + static new(): PlutusMap; /** - * @returns {ProtocolVersion | void} + * @returns {number} */ - protocol_version(): ProtocolVersion | void; + len(): number; /** - * @param {BigNum} min_pool_cost + * @param {PlutusData} key + * @param {PlutusData} value + * @returns {PlutusData | void} */ - set_min_pool_cost(min_pool_cost: BigNum): void; + insert(key: PlutusData, value: PlutusData): PlutusData | void; /** - * @returns {BigNum | void} + * @param {PlutusData} key + * @returns {PlutusData | void} */ - min_pool_cost(): BigNum | void; + get(key: PlutusData): PlutusData | void; /** - * @param {BigNum} ada_per_utxo_byte + * @returns {PlutusList} */ - set_ada_per_utxo_byte(ada_per_utxo_byte: BigNum): void; + keys(): PlutusList; +} +/** + */ +declare export class PlutusScript { + free(): void; /** - * @returns {BigNum | void} + * @returns {Uint8Array} */ - ada_per_utxo_byte(): BigNum | void; + to_bytes(): Uint8Array; /** - * @param {Costmdls} cost_models + * @param {Uint8Array} bytes + * @returns {PlutusScript} */ - set_cost_models(cost_models: Costmdls): void; + static from_bytes(bytes: Uint8Array): PlutusScript; /** - * @returns {Costmdls | void} + * @returns {string} */ - cost_models(): Costmdls | void; + to_hex(): string; /** - * @param {ExUnitPrices} execution_costs + * @param {string} hex_str + * @returns {PlutusScript} */ - set_execution_costs(execution_costs: ExUnitPrices): void; + static from_hex(hex_str: string): PlutusScript; /** - * @returns {ExUnitPrices | void} + * + * * Creates a new Plutus script from the RAW bytes of the compiled script. + * * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) + * * If you creating this from those you should use PlutusScript::from_bytes() instead. + * @param {Uint8Array} bytes + * @returns {PlutusScript} */ - execution_costs(): ExUnitPrices | void; + static new(bytes: Uint8Array): PlutusScript; /** - * @param {ExUnits} max_tx_ex_units + * + * * Creates a new Plutus script from the RAW bytes of the compiled script. + * * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) + * * If you creating this from those you should use PlutusScript::from_bytes() instead. + * @param {Uint8Array} bytes + * @returns {PlutusScript} */ - set_max_tx_ex_units(max_tx_ex_units: ExUnits): void; + static new_v2(bytes: Uint8Array): PlutusScript; /** - * @returns {ExUnits | void} + * + * * Creates a new Plutus script from the RAW bytes of the compiled script. + * * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) + * * If you creating this from those you should use PlutusScript::from_bytes() instead. + * @param {Uint8Array} bytes + * @param {Language} language + * @returns {PlutusScript} */ - max_tx_ex_units(): ExUnits | void; + static new_with_version(bytes: Uint8Array, language: Language): PlutusScript; /** - * @param {ExUnits} max_block_ex_units + * + * * The raw bytes of this compiled Plutus script. + * * If you need "cborBytes" for cardano-cli use PlutusScript::to_bytes() instead. + * @returns {Uint8Array} */ - set_max_block_ex_units(max_block_ex_units: ExUnits): void; + bytes(): Uint8Array; /** - * @returns {ExUnits | void} + * Same as `.from_bytes` but will consider the script as requiring the Plutus Language V2 + * @param {Uint8Array} bytes + * @returns {PlutusScript} */ - max_block_ex_units(): ExUnits | void; + static from_bytes_v2(bytes: Uint8Array): PlutusScript; /** - * @param {number} max_value_size + * Same as `.from_bytes` but will consider the script as requiring the specified language version + * @param {Uint8Array} bytes + * @param {Language} language + * @returns {PlutusScript} */ - set_max_value_size(max_value_size: number): void; + static from_bytes_with_version( + bytes: Uint8Array, + language: Language + ): PlutusScript; /** - * @returns {number | void} + * Same as .from_hex but will consider the script as requiring the specified language version + * @param {string} hex_str + * @param {Language} language + * @returns {PlutusScript} */ - max_value_size(): number | void; + static from_hex_with_version( + hex_str: string, + language: Language + ): PlutusScript; /** - * @param {number} collateral_percentage + * @returns {ScriptHash} */ - set_collateral_percentage(collateral_percentage: number): void; + hash(): ScriptHash; /** - * @returns {number | void} + * @returns {Language} */ - collateral_percentage(): number | void; + language_version(): Language; +} +/** + */ +declare export class PlutusScriptSource { + free(): void; /** - * @param {number} max_collateral_inputs + * @param {PlutusScript} script + * @returns {PlutusScriptSource} */ - set_max_collateral_inputs(max_collateral_inputs: number): void; + static new(script: PlutusScript): PlutusScriptSource; /** - * @returns {number | void} + * !!! DEPRECATED !!! + * This constructor has missed information about plutus script language vesrion. That can affect + * the script data hash calculation. + * Use `.new_ref_input_with_lang_ver` instead + * @param {ScriptHash} script_hash + * @param {TransactionInput} input + * @returns {PlutusScriptSource} */ - max_collateral_inputs(): number | void; + static new_ref_input( + script_hash: ScriptHash, + input: TransactionInput + ): PlutusScriptSource; /** - * @returns {ProtocolParamUpdate} + * @param {ScriptHash} script_hash + * @param {TransactionInput} input + * @param {Language} lang_ver + * @returns {PlutusScriptSource} */ - static new(): ProtocolParamUpdate; + static new_ref_input_with_lang_ver( + script_hash: ScriptHash, + input: TransactionInput, + lang_ver: Language + ): PlutusScriptSource; } /** */ -declare export class ProtocolVersion { +declare export class PlutusScripts { free(): void; /** @@ -6108,9 +6410,9 @@ declare export class ProtocolVersion { /** * @param {Uint8Array} bytes - * @returns {ProtocolVersion} + * @returns {PlutusScripts} */ - static from_bytes(bytes: Uint8Array): ProtocolVersion; + static from_bytes(bytes: Uint8Array): PlutusScripts; /** * @returns {string} @@ -6119,9 +6421,9 @@ declare export class ProtocolVersion { /** * @param {string} hex_str - * @returns {ProtocolVersion} + * @returns {PlutusScripts} */ - static from_hex(hex_str: string): ProtocolVersion; + static from_hex(hex_str: string): PlutusScripts; /** * @returns {string} @@ -6129,194 +6431,226 @@ declare export class ProtocolVersion { to_json(): string; /** - * @returns {ProtocolVersionJSON} + * @returns {PlutusScriptsJSON} */ - to_js_value(): ProtocolVersionJSON; + to_js_value(): PlutusScriptsJSON; /** * @param {string} json - * @returns {ProtocolVersion} + * @returns {PlutusScripts} */ - static from_json(json: string): ProtocolVersion; + static from_json(json: string): PlutusScripts; /** - * @returns {number} + * @returns {PlutusScripts} */ - major(): number; + static new(): PlutusScripts; /** * @returns {number} */ - minor(): number; + len(): number; /** - * @param {number} major - * @param {number} minor - * @returns {ProtocolVersion} + * @param {number} index + * @returns {PlutusScript} */ - static new(major: number, minor: number): ProtocolVersion; + get(index: number): PlutusScript; + + /** + * @param {PlutusScript} elem + */ + add(elem: PlutusScript): void; } /** - * ED25519 key used as public key */ -declare export class PublicKey { +declare export class PlutusWitness { free(): void; /** - * Get public key from its bech32 representation - * Example: - * ```javascript - * const pkey = PublicKey.from_bech32('ed25519_pk1dgaagyh470y66p899txcl3r0jaeaxu6yd7z2dxyk55qcycdml8gszkxze2'); - * ``` - * @param {string} bech32_str - * @returns {PublicKey} + * @param {PlutusScript} script + * @param {PlutusData} datum + * @param {Redeemer} redeemer + * @returns {PlutusWitness} */ - static from_bech32(bech32_str: string): PublicKey; + static new( + script: PlutusScript, + datum: PlutusData, + redeemer: Redeemer + ): PlutusWitness; /** - * @returns {string} + * @param {PlutusScriptSource} script + * @param {DatumSource} datum + * @param {Redeemer} redeemer + * @returns {PlutusWitness} */ - to_bech32(): string; + static new_with_ref( + script: PlutusScriptSource, + datum: DatumSource, + redeemer: Redeemer + ): PlutusWitness; /** - * @returns {Uint8Array} + * @param {PlutusScript} script + * @param {Redeemer} redeemer + * @returns {PlutusWitness} */ - as_bytes(): Uint8Array; + static new_without_datum( + script: PlutusScript, + redeemer: Redeemer + ): PlutusWitness; /** - * @param {Uint8Array} bytes - * @returns {PublicKey} + * @param {PlutusScriptSource} script + * @param {Redeemer} redeemer + * @returns {PlutusWitness} */ - static from_bytes(bytes: Uint8Array): PublicKey; + static new_with_ref_without_datum( + script: PlutusScriptSource, + redeemer: Redeemer + ): PlutusWitness; /** - * @param {Uint8Array} data - * @param {Ed25519Signature} signature - * @returns {boolean} + * @returns {PlutusScript | void} */ - verify(data: Uint8Array, signature: Ed25519Signature): boolean; + script(): PlutusScript | void; /** - * @returns {Ed25519KeyHash} - */ - hash(): Ed25519KeyHash; - - /** - * @returns {string} + * @returns {PlutusData | void} */ - to_hex(): string; + datum(): PlutusData | void; /** - * @param {string} hex_str - * @returns {PublicKey} + * @returns {Redeemer} */ - static from_hex(hex_str: string): PublicKey; + redeemer(): Redeemer; } /** */ -declare export class PublicKeys { +declare export class PlutusWitnesses { free(): void; /** + * @returns {PlutusWitnesses} */ - constructor(): this; + static new(): PlutusWitnesses; /** * @returns {number} */ - size(): number; + len(): number; /** * @param {number} index - * @returns {PublicKey} + * @returns {PlutusWitness} */ - get(index: number): PublicKey; + get(index: number): PlutusWitness; /** - * @param {PublicKey} key + * @param {PlutusWitness} elem */ - add(key: PublicKey): void; + add(elem: PlutusWitness): void; } /** */ -declare export class Redeemer { +declare export class Pointer { free(): void; /** - * @returns {Uint8Array} + * !!! DEPRECATED !!! + * This constructor uses outdated slot number format for the ttl value, tx_index and cert_index. + * Use `.new_pointer` instead + * @param {number} slot + * @param {number} tx_index + * @param {number} cert_index + * @returns {Pointer} */ - to_bytes(): Uint8Array; + static new(slot: number, tx_index: number, cert_index: number): Pointer; /** - * @param {Uint8Array} bytes - * @returns {Redeemer} + * @param {BigNum} slot + * @param {BigNum} tx_index + * @param {BigNum} cert_index + * @returns {Pointer} */ - static from_bytes(bytes: Uint8Array): Redeemer; + static new_pointer( + slot: BigNum, + tx_index: BigNum, + cert_index: BigNum + ): Pointer; /** - * @returns {string} + * @returns {number} */ - to_hex(): string; + slot(): number; /** - * @param {string} hex_str - * @returns {Redeemer} + * @returns {number} */ - static from_hex(hex_str: string): Redeemer; + tx_index(): number; /** - * @returns {string} + * @returns {number} */ - to_json(): string; + cert_index(): number; /** - * @returns {RedeemerJSON} + * @returns {BigNum} */ - to_js_value(): RedeemerJSON; + slot_bignum(): BigNum; /** - * @param {string} json - * @returns {Redeemer} + * @returns {BigNum} */ - static from_json(json: string): Redeemer; + tx_index_bignum(): BigNum; /** - * @returns {RedeemerTag} + * @returns {BigNum} */ - tag(): RedeemerTag; + cert_index_bignum(): BigNum; +} +/** + */ +declare export class PointerAddress { + free(): void; /** - * @returns {BigNum} + * @param {number} network + * @param {StakeCredential} payment + * @param {Pointer} stake + * @returns {PointerAddress} */ - index(): BigNum; + static new( + network: number, + payment: StakeCredential, + stake: Pointer + ): PointerAddress; /** - * @returns {PlutusData} + * @returns {StakeCredential} */ - data(): PlutusData; + payment_cred(): StakeCredential; /** - * @returns {ExUnits} + * @returns {Pointer} */ - ex_units(): ExUnits; + stake_pointer(): Pointer; /** - * @param {RedeemerTag} tag - * @param {BigNum} index - * @param {PlutusData} data - * @param {ExUnits} ex_units - * @returns {Redeemer} + * @returns {Address} */ - static new( - tag: RedeemerTag, - index: BigNum, - data: PlutusData, - ex_units: ExUnits - ): Redeemer; + to_address(): Address; + + /** + * @param {Address} addr + * @returns {PointerAddress | void} + */ + static from_address(addr: Address): PointerAddress | void; } /** */ -declare export class RedeemerTag { +declare export class PoolMetadata { free(): void; /** @@ -6326,9 +6660,9 @@ declare export class RedeemerTag { /** * @param {Uint8Array} bytes - * @returns {RedeemerTag} + * @returns {PoolMetadata} */ - static from_bytes(bytes: Uint8Array): RedeemerTag; + static from_bytes(bytes: Uint8Array): PoolMetadata; /** * @returns {string} @@ -6337,9 +6671,9 @@ declare export class RedeemerTag { /** * @param {string} hex_str - * @returns {RedeemerTag} + * @returns {PoolMetadata} */ - static from_hex(hex_str: string): RedeemerTag; + static from_hex(hex_str: string): PoolMetadata; /** * @returns {string} @@ -6347,113 +6681,75 @@ declare export class RedeemerTag { to_json(): string; /** - * @returns {RedeemerTagJSON} + * @returns {PoolMetadataJSON} */ - to_js_value(): RedeemerTagJSON; + to_js_value(): PoolMetadataJSON; /** * @param {string} json - * @returns {RedeemerTag} - */ - static from_json(json: string): RedeemerTag; - - /** - * @returns {RedeemerTag} - */ - static new_spend(): RedeemerTag; - - /** - * @returns {RedeemerTag} + * @returns {PoolMetadata} */ - static new_mint(): RedeemerTag; + static from_json(json: string): PoolMetadata; /** - * @returns {RedeemerTag} + * @returns {URL} */ - static new_cert(): RedeemerTag; + url(): URL; /** - * @returns {RedeemerTag} + * @returns {PoolMetadataHash} */ - static new_reward(): RedeemerTag; + pool_metadata_hash(): PoolMetadataHash; /** - * @returns {number} + * @param {URL} url + * @param {PoolMetadataHash} pool_metadata_hash + * @returns {PoolMetadata} */ - kind(): number; + static new(url: URL, pool_metadata_hash: PoolMetadataHash): PoolMetadata; } /** */ -declare export class Redeemers { +declare export class PoolMetadataHash { free(): void; - /** - * @returns {Uint8Array} - */ - to_bytes(): Uint8Array; - /** * @param {Uint8Array} bytes - * @returns {Redeemers} - */ - static from_bytes(bytes: Uint8Array): Redeemers; - - /** - * @returns {string} + * @returns {PoolMetadataHash} */ - to_hex(): string; + static from_bytes(bytes: Uint8Array): PoolMetadataHash; /** - * @param {string} hex_str - * @returns {Redeemers} + * @returns {Uint8Array} */ - static from_hex(hex_str: string): Redeemers; + to_bytes(): Uint8Array; /** + * @param {string} prefix * @returns {string} */ - to_json(): string; - - /** - * @returns {RedeemersJSON} - */ - to_js_value(): RedeemersJSON; - - /** - * @param {string} json - * @returns {Redeemers} - */ - static from_json(json: string): Redeemers; - - /** - * @returns {Redeemers} - */ - static new(): Redeemers; - - /** - * @returns {number} - */ - len(): number; + to_bech32(prefix: string): string; /** - * @param {number} index - * @returns {Redeemer} + * @param {string} bech_str + * @returns {PoolMetadataHash} */ - get(index: number): Redeemer; + static from_bech32(bech_str: string): PoolMetadataHash; /** - * @param {Redeemer} elem + * @returns {string} */ - add(elem: Redeemer): void; + to_hex(): string; /** - * @returns {ExUnits} + * @param {string} hex + * @returns {PoolMetadataHash} */ - total_ex_units(): ExUnits; + static from_hex(hex: string): PoolMetadataHash; } /** */ -declare export class Relay { +declare export class PoolParams { free(): void; /** @@ -6463,9 +6759,9 @@ declare export class Relay { /** * @param {Uint8Array} bytes - * @returns {Relay} + * @returns {PoolParams} */ - static from_bytes(bytes: Uint8Array): Relay; + static from_bytes(bytes: Uint8Array): PoolParams; /** * @returns {string} @@ -6474,9 +6770,9 @@ declare export class Relay { /** * @param {string} hex_str - * @returns {Relay} + * @returns {PoolParams} */ - static from_hex(hex_str: string): Relay; + static from_hex(hex_str: string): PoolParams; /** * @returns {string} @@ -6484,57 +6780,88 @@ declare export class Relay { to_json(): string; /** - * @returns {RelayJSON} + * @returns {PoolParamsJSON} */ - to_js_value(): RelayJSON; + to_js_value(): PoolParamsJSON; /** * @param {string} json - * @returns {Relay} + * @returns {PoolParams} */ - static from_json(json: string): Relay; + static from_json(json: string): PoolParams; /** - * @param {SingleHostAddr} single_host_addr - * @returns {Relay} + * @returns {Ed25519KeyHash} */ - static new_single_host_addr(single_host_addr: SingleHostAddr): Relay; + operator(): Ed25519KeyHash; /** - * @param {SingleHostName} single_host_name - * @returns {Relay} + * @returns {VRFKeyHash} */ - static new_single_host_name(single_host_name: SingleHostName): Relay; + vrf_keyhash(): VRFKeyHash; /** - * @param {MultiHostName} multi_host_name - * @returns {Relay} + * @returns {BigNum} */ - static new_multi_host_name(multi_host_name: MultiHostName): Relay; + pledge(): BigNum; /** - * @returns {number} + * @returns {BigNum} */ - kind(): number; + cost(): BigNum; /** - * @returns {SingleHostAddr | void} + * @returns {UnitInterval} */ - as_single_host_addr(): SingleHostAddr | void; + margin(): UnitInterval; /** - * @returns {SingleHostName | void} + * @returns {RewardAddress} */ - as_single_host_name(): SingleHostName | void; + reward_account(): RewardAddress; /** - * @returns {MultiHostName | void} + * @returns {Ed25519KeyHashes} */ - as_multi_host_name(): MultiHostName | void; + pool_owners(): Ed25519KeyHashes; + + /** + * @returns {Relays} + */ + relays(): Relays; + + /** + * @returns {PoolMetadata | void} + */ + pool_metadata(): PoolMetadata | void; + + /** + * @param {Ed25519KeyHash} operator + * @param {VRFKeyHash} vrf_keyhash + * @param {BigNum} pledge + * @param {BigNum} cost + * @param {UnitInterval} margin + * @param {RewardAddress} reward_account + * @param {Ed25519KeyHashes} pool_owners + * @param {Relays} relays + * @param {PoolMetadata | void} pool_metadata + * @returns {PoolParams} + */ + static new( + operator: Ed25519KeyHash, + vrf_keyhash: VRFKeyHash, + pledge: BigNum, + cost: BigNum, + margin: UnitInterval, + reward_account: RewardAddress, + pool_owners: Ed25519KeyHashes, + relays: Relays, + pool_metadata?: PoolMetadata + ): PoolParams; } /** */ -declare export class Relays { +declare export class PoolRegistration { free(): void; /** @@ -6544,9 +6871,9 @@ declare export class Relays { /** * @param {Uint8Array} bytes - * @returns {Relays} + * @returns {PoolRegistration} */ - static from_bytes(bytes: Uint8Array): Relays; + static from_bytes(bytes: Uint8Array): PoolRegistration; /** * @returns {string} @@ -6555,9 +6882,9 @@ declare export class Relays { /** * @param {string} hex_str - * @returns {Relays} + * @returns {PoolRegistration} */ - static from_hex(hex_str: string): Relays; + static from_hex(hex_str: string): PoolRegistration; /** * @returns {string} @@ -6565,68 +6892,30 @@ declare export class Relays { to_json(): string; /** - * @returns {RelaysJSON} + * @returns {PoolRegistrationJSON} */ - to_js_value(): RelaysJSON; + to_js_value(): PoolRegistrationJSON; /** * @param {string} json - * @returns {Relays} - */ - static from_json(json: string): Relays; - - /** - * @returns {Relays} - */ - static new(): Relays; - - /** - * @returns {number} - */ - len(): number; - - /** - * @param {number} index - * @returns {Relay} - */ - get(index: number): Relay; - - /** - * @param {Relay} elem - */ - add(elem: Relay): void; -} -/** - */ -declare export class RewardAddress { - free(): void; - - /** - * @param {number} network - * @param {StakeCredential} payment - * @returns {RewardAddress} - */ - static new(network: number, payment: StakeCredential): RewardAddress; - - /** - * @returns {StakeCredential} + * @returns {PoolRegistration} */ - payment_cred(): StakeCredential; + static from_json(json: string): PoolRegistration; /** - * @returns {Address} + * @returns {PoolParams} */ - to_address(): Address; + pool_params(): PoolParams; /** - * @param {Address} addr - * @returns {RewardAddress | void} + * @param {PoolParams} pool_params + * @returns {PoolRegistration} */ - static from_address(addr: Address): RewardAddress | void; + static new(pool_params: PoolParams): PoolRegistration; } /** */ -declare export class RewardAddresses { +declare export class PoolRetirement { free(): void; /** @@ -6636,9 +6925,9 @@ declare export class RewardAddresses { /** * @param {Uint8Array} bytes - * @returns {RewardAddresses} + * @returns {PoolRetirement} */ - static from_bytes(bytes: Uint8Array): RewardAddresses; + static from_bytes(bytes: Uint8Array): PoolRetirement; /** * @returns {string} @@ -6647,9 +6936,9 @@ declare export class RewardAddresses { /** * @param {string} hex_str - * @returns {RewardAddresses} + * @returns {PoolRetirement} */ - static from_hex(hex_str: string): RewardAddresses; + static from_hex(hex_str: string): PoolRetirement; /** * @returns {string} @@ -6657,94 +6946,109 @@ declare export class RewardAddresses { to_json(): string; /** - * @returns {RewardAddressesJSON} + * @returns {PoolRetirementJSON} */ - to_js_value(): RewardAddressesJSON; + to_js_value(): PoolRetirementJSON; /** * @param {string} json - * @returns {RewardAddresses} + * @returns {PoolRetirement} */ - static from_json(json: string): RewardAddresses; + static from_json(json: string): PoolRetirement; /** - * @returns {RewardAddresses} + * @returns {Ed25519KeyHash} */ - static new(): RewardAddresses; + pool_keyhash(): Ed25519KeyHash; /** * @returns {number} */ - len(): number; - - /** - * @param {number} index - * @returns {RewardAddress} - */ - get(index: number): RewardAddress; + epoch(): number; /** - * @param {RewardAddress} elem + * @param {Ed25519KeyHash} pool_keyhash + * @param {number} epoch + * @returns {PoolRetirement} */ - add(elem: RewardAddress): void; + static new(pool_keyhash: Ed25519KeyHash, epoch: number): PoolRetirement; } /** */ -declare export class ScriptAll { +declare export class PrivateKey { free(): void; /** - * @returns {Uint8Array} + * @returns {PublicKey} */ - to_bytes(): Uint8Array; + to_public(): PublicKey; /** - * @param {Uint8Array} bytes - * @returns {ScriptAll} + * @returns {PrivateKey} */ - static from_bytes(bytes: Uint8Array): ScriptAll; + static generate_ed25519(): PrivateKey; /** - * @returns {string} + * @returns {PrivateKey} */ - to_hex(): string; + static generate_ed25519extended(): PrivateKey; /** - * @param {string} hex_str - * @returns {ScriptAll} + * Get private key from its bech32 representation + * ```javascript + * PrivateKey.from_bech32('ed25519_sk1ahfetf02qwwg4dkq7mgp4a25lx5vh9920cr5wnxmpzz9906qvm8qwvlts0'); + * ``` + * For an extended 25519 key + * ```javascript + * PrivateKey.from_bech32('ed25519e_sk1gqwl4szuwwh6d0yk3nsqcc6xxc3fpvjlevgwvt60df59v8zd8f8prazt8ln3lmz096ux3xvhhvm3ca9wj2yctdh3pnw0szrma07rt5gl748fp'); + * ``` + * @param {string} bech32_str + * @returns {PrivateKey} */ - static from_hex(hex_str: string): ScriptAll; + static from_bech32(bech32_str: string): PrivateKey; /** * @returns {string} */ - to_json(): string; + to_bech32(): string; /** - * @returns {ScriptAllJSON} + * @returns {Uint8Array} */ - to_js_value(): ScriptAllJSON; + as_bytes(): Uint8Array; /** - * @param {string} json - * @returns {ScriptAll} + * @param {Uint8Array} bytes + * @returns {PrivateKey} */ - static from_json(json: string): ScriptAll; + static from_extended_bytes(bytes: Uint8Array): PrivateKey; /** - * @returns {NativeScripts} + * @param {Uint8Array} bytes + * @returns {PrivateKey} */ - native_scripts(): NativeScripts; + static from_normal_bytes(bytes: Uint8Array): PrivateKey; /** - * @param {NativeScripts} native_scripts - * @returns {ScriptAll} + * @param {Uint8Array} message + * @returns {Ed25519Signature} */ - static new(native_scripts: NativeScripts): ScriptAll; + sign(message: Uint8Array): Ed25519Signature; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {PrivateKey} + */ + static from_hex(hex_str: string): PrivateKey; } /** */ -declare export class ScriptAny { +declare export class ProposedProtocolParameterUpdates { free(): void; /** @@ -6754,9 +7058,9 @@ declare export class ScriptAny { /** * @param {Uint8Array} bytes - * @returns {ScriptAny} + * @returns {ProposedProtocolParameterUpdates} */ - static from_bytes(bytes: Uint8Array): ScriptAny; + static from_bytes(bytes: Uint8Array): ProposedProtocolParameterUpdates; /** * @returns {string} @@ -6765,9 +7069,9 @@ declare export class ScriptAny { /** * @param {string} hex_str - * @returns {ScriptAny} + * @returns {ProposedProtocolParameterUpdates} */ - static from_hex(hex_str: string): ScriptAny; + static from_hex(hex_str: string): ProposedProtocolParameterUpdates; /** * @returns {string} @@ -6775,427 +7079,332 @@ declare export class ScriptAny { to_json(): string; /** - * @returns {ScriptAnyJSON} + * @returns {ProposedProtocolParameterUpdatesJSON} */ - to_js_value(): ScriptAnyJSON; + to_js_value(): ProposedProtocolParameterUpdatesJSON; /** * @param {string} json - * @returns {ScriptAny} + * @returns {ProposedProtocolParameterUpdates} */ - static from_json(json: string): ScriptAny; + static from_json(json: string): ProposedProtocolParameterUpdates; /** - * @returns {NativeScripts} + * @returns {ProposedProtocolParameterUpdates} */ - native_scripts(): NativeScripts; + static new(): ProposedProtocolParameterUpdates; /** - * @param {NativeScripts} native_scripts - * @returns {ScriptAny} + * @returns {number} */ - static new(native_scripts: NativeScripts): ScriptAny; -} -/** - */ -declare export class ScriptDataHash { - free(): void; + len(): number; /** - * @param {Uint8Array} bytes - * @returns {ScriptDataHash} + * @param {GenesisHash} key + * @param {ProtocolParamUpdate} value + * @returns {ProtocolParamUpdate | void} */ - static from_bytes(bytes: Uint8Array): ScriptDataHash; - - /** - * @returns {Uint8Array} - */ - to_bytes(): Uint8Array; - - /** - * @param {string} prefix - * @returns {string} - */ - to_bech32(prefix: string): string; - - /** - * @param {string} bech_str - * @returns {ScriptDataHash} - */ - static from_bech32(bech_str: string): ScriptDataHash; + insert( + key: GenesisHash, + value: ProtocolParamUpdate + ): ProtocolParamUpdate | void; /** - * @returns {string} + * @param {GenesisHash} key + * @returns {ProtocolParamUpdate | void} */ - to_hex(): string; + get(key: GenesisHash): ProtocolParamUpdate | void; /** - * @param {string} hex - * @returns {ScriptDataHash} + * @returns {GenesisHashes} */ - static from_hex(hex: string): ScriptDataHash; + keys(): GenesisHashes; } /** */ -declare export class ScriptHash { +declare export class ProtocolParamUpdate { free(): void; /** - * @param {Uint8Array} bytes - * @returns {ScriptHash} + * @returns {Uint8Array} */ - static from_bytes(bytes: Uint8Array): ScriptHash; + to_bytes(): Uint8Array; /** - * @returns {Uint8Array} + * @param {Uint8Array} bytes + * @returns {ProtocolParamUpdate} */ - to_bytes(): Uint8Array; + static from_bytes(bytes: Uint8Array): ProtocolParamUpdate; /** - * @param {string} prefix * @returns {string} */ - to_bech32(prefix: string): string; + to_hex(): string; /** - * @param {string} bech_str - * @returns {ScriptHash} + * @param {string} hex_str + * @returns {ProtocolParamUpdate} */ - static from_bech32(bech_str: string): ScriptHash; + static from_hex(hex_str: string): ProtocolParamUpdate; /** * @returns {string} */ - to_hex(): string; + to_json(): string; /** - * @param {string} hex - * @returns {ScriptHash} + * @returns {ProtocolParamUpdateJSON} */ - static from_hex(hex: string): ScriptHash; -} -/** - */ -declare export class ScriptHashes { - free(): void; + to_js_value(): ProtocolParamUpdateJSON; /** - * @returns {Uint8Array} + * @param {string} json + * @returns {ProtocolParamUpdate} */ - to_bytes(): Uint8Array; + static from_json(json: string): ProtocolParamUpdate; /** - * @param {Uint8Array} bytes - * @returns {ScriptHashes} + * @param {BigNum} minfee_a */ - static from_bytes(bytes: Uint8Array): ScriptHashes; + set_minfee_a(minfee_a: BigNum): void; /** - * @returns {string} + * @returns {BigNum | void} */ - to_hex(): string; + minfee_a(): BigNum | void; /** - * @param {string} hex_str - * @returns {ScriptHashes} + * @param {BigNum} minfee_b */ - static from_hex(hex_str: string): ScriptHashes; + set_minfee_b(minfee_b: BigNum): void; /** - * @returns {string} + * @returns {BigNum | void} */ - to_json(): string; + minfee_b(): BigNum | void; /** - * @returns {ScriptHashesJSON} + * @param {number} max_block_body_size */ - to_js_value(): ScriptHashesJSON; + set_max_block_body_size(max_block_body_size: number): void; /** - * @param {string} json - * @returns {ScriptHashes} + * @returns {number | void} */ - static from_json(json: string): ScriptHashes; + max_block_body_size(): number | void; /** - * @returns {ScriptHashes} + * @param {number} max_tx_size */ - static new(): ScriptHashes; + set_max_tx_size(max_tx_size: number): void; /** - * @returns {number} + * @returns {number | void} */ - len(): number; + max_tx_size(): number | void; /** - * @param {number} index - * @returns {ScriptHash} + * @param {number} max_block_header_size */ - get(index: number): ScriptHash; + set_max_block_header_size(max_block_header_size: number): void; /** - * @param {ScriptHash} elem + * @returns {number | void} */ - add(elem: ScriptHash): void; -} -/** - */ -declare export class ScriptNOfK { - free(): void; + max_block_header_size(): number | void; /** - * @returns {Uint8Array} + * @param {BigNum} key_deposit */ - to_bytes(): Uint8Array; + set_key_deposit(key_deposit: BigNum): void; /** - * @param {Uint8Array} bytes - * @returns {ScriptNOfK} + * @returns {BigNum | void} */ - static from_bytes(bytes: Uint8Array): ScriptNOfK; + key_deposit(): BigNum | void; /** - * @returns {string} + * @param {BigNum} pool_deposit */ - to_hex(): string; + set_pool_deposit(pool_deposit: BigNum): void; /** - * @param {string} hex_str - * @returns {ScriptNOfK} + * @returns {BigNum | void} */ - static from_hex(hex_str: string): ScriptNOfK; + pool_deposit(): BigNum | void; /** - * @returns {string} + * @param {number} max_epoch */ - to_json(): string; + set_max_epoch(max_epoch: number): void; /** - * @returns {ScriptNOfKJSON} + * @returns {number | void} */ - to_js_value(): ScriptNOfKJSON; + max_epoch(): number | void; /** - * @param {string} json - * @returns {ScriptNOfK} + * @param {number} n_opt */ - static from_json(json: string): ScriptNOfK; + set_n_opt(n_opt: number): void; /** - * @returns {number} + * @returns {number | void} */ - n(): number; + n_opt(): number | void; /** - * @returns {NativeScripts} + * @param {UnitInterval} pool_pledge_influence */ - native_scripts(): NativeScripts; + set_pool_pledge_influence(pool_pledge_influence: UnitInterval): void; /** - * @param {number} n - * @param {NativeScripts} native_scripts - * @returns {ScriptNOfK} + * @returns {UnitInterval | void} */ - static new(n: number, native_scripts: NativeScripts): ScriptNOfK; -} -/** - */ -declare export class ScriptPubkey { - free(): void; + pool_pledge_influence(): UnitInterval | void; /** - * @returns {Uint8Array} + * @param {UnitInterval} expansion_rate */ - to_bytes(): Uint8Array; + set_expansion_rate(expansion_rate: UnitInterval): void; /** - * @param {Uint8Array} bytes - * @returns {ScriptPubkey} + * @returns {UnitInterval | void} */ - static from_bytes(bytes: Uint8Array): ScriptPubkey; + expansion_rate(): UnitInterval | void; /** - * @returns {string} + * @param {UnitInterval} treasury_growth_rate */ - to_hex(): string; + set_treasury_growth_rate(treasury_growth_rate: UnitInterval): void; /** - * @param {string} hex_str - * @returns {ScriptPubkey} + * @returns {UnitInterval | void} */ - static from_hex(hex_str: string): ScriptPubkey; + treasury_growth_rate(): UnitInterval | void; /** - * @returns {string} + * !!! DEPRECATED !!! + * Since babbage era this param is outdated. But this param you can meet in a pre-babbage block. + * @returns {UnitInterval | void} */ - to_json(): string; + d(): UnitInterval | void; /** - * @returns {ScriptPubkeyJSON} + * !!! DEPRECATED !!! + * Since babbage era this param is outdated. But this param you can meet in a pre-babbage block. + * @returns {Nonce | void} */ - to_js_value(): ScriptPubkeyJSON; + extra_entropy(): Nonce | void; /** - * @param {string} json - * @returns {ScriptPubkey} + * @param {ProtocolVersion} protocol_version */ - static from_json(json: string): ScriptPubkey; + set_protocol_version(protocol_version: ProtocolVersion): void; /** - * @returns {Ed25519KeyHash} + * @returns {ProtocolVersion | void} */ - addr_keyhash(): Ed25519KeyHash; + protocol_version(): ProtocolVersion | void; /** - * @param {Ed25519KeyHash} addr_keyhash - * @returns {ScriptPubkey} + * @param {BigNum} min_pool_cost */ - static new(addr_keyhash: Ed25519KeyHash): ScriptPubkey; -} -/** - */ -declare export class ScriptRef { - free(): void; + set_min_pool_cost(min_pool_cost: BigNum): void; /** - * @returns {Uint8Array} + * @returns {BigNum | void} */ - to_bytes(): Uint8Array; + min_pool_cost(): BigNum | void; /** - * @param {Uint8Array} bytes - * @returns {ScriptRef} + * @param {BigNum} ada_per_utxo_byte */ - static from_bytes(bytes: Uint8Array): ScriptRef; + set_ada_per_utxo_byte(ada_per_utxo_byte: BigNum): void; /** - * @returns {string} + * @returns {BigNum | void} */ - to_hex(): string; + ada_per_utxo_byte(): BigNum | void; /** - * @param {string} hex_str - * @returns {ScriptRef} + * @param {Costmdls} cost_models */ - static from_hex(hex_str: string): ScriptRef; + set_cost_models(cost_models: Costmdls): void; /** - * @returns {string} + * @returns {Costmdls | void} */ - to_json(): string; + cost_models(): Costmdls | void; /** - * @returns {ScriptRefJSON} + * @param {ExUnitPrices} execution_costs */ - to_js_value(): ScriptRefJSON; + set_execution_costs(execution_costs: ExUnitPrices): void; /** - * @param {string} json - * @returns {ScriptRef} + * @returns {ExUnitPrices | void} */ - static from_json(json: string): ScriptRef; + execution_costs(): ExUnitPrices | void; /** - * @param {NativeScript} native_script - * @returns {ScriptRef} + * @param {ExUnits} max_tx_ex_units */ - static new_native_script(native_script: NativeScript): ScriptRef; + set_max_tx_ex_units(max_tx_ex_units: ExUnits): void; /** - * @param {PlutusScript} plutus_script - * @returns {ScriptRef} + * @returns {ExUnits | void} */ - static new_plutus_script(plutus_script: PlutusScript): ScriptRef; + max_tx_ex_units(): ExUnits | void; /** - * @returns {boolean} - */ - is_native_script(): boolean; - - /** - * @returns {boolean} - */ - is_plutus_script(): boolean; - - /** - * @returns {NativeScript | void} - */ - native_script(): NativeScript | void; - - /** - * @returns {PlutusScript | void} - */ - plutus_script(): PlutusScript | void; -} -/** - */ -declare export class SingleHostAddr { - free(): void; - - /** - * @returns {Uint8Array} - */ - to_bytes(): Uint8Array; - - /** - * @param {Uint8Array} bytes - * @returns {SingleHostAddr} - */ - static from_bytes(bytes: Uint8Array): SingleHostAddr; - - /** - * @returns {string} + * @param {ExUnits} max_block_ex_units */ - to_hex(): string; + set_max_block_ex_units(max_block_ex_units: ExUnits): void; /** - * @param {string} hex_str - * @returns {SingleHostAddr} + * @returns {ExUnits | void} */ - static from_hex(hex_str: string): SingleHostAddr; + max_block_ex_units(): ExUnits | void; /** - * @returns {string} + * @param {number} max_value_size */ - to_json(): string; + set_max_value_size(max_value_size: number): void; /** - * @returns {SingleHostAddrJSON} + * @returns {number | void} */ - to_js_value(): SingleHostAddrJSON; + max_value_size(): number | void; /** - * @param {string} json - * @returns {SingleHostAddr} + * @param {number} collateral_percentage */ - static from_json(json: string): SingleHostAddr; + set_collateral_percentage(collateral_percentage: number): void; /** * @returns {number | void} */ - port(): number | void; + collateral_percentage(): number | void; /** - * @returns {Ipv4 | void} + * @param {number} max_collateral_inputs */ - ipv4(): Ipv4 | void; + set_max_collateral_inputs(max_collateral_inputs: number): void; /** - * @returns {Ipv6 | void} + * @returns {number | void} */ - ipv6(): Ipv6 | void; + max_collateral_inputs(): number | void; /** - * @param {number | void} port - * @param {Ipv4 | void} ipv4 - * @param {Ipv6 | void} ipv6 - * @returns {SingleHostAddr} + * @returns {ProtocolParamUpdate} */ - static new(port?: number, ipv4?: Ipv4, ipv6?: Ipv6): SingleHostAddr; + static new(): ProtocolParamUpdate; } /** */ -declare export class SingleHostName { +declare export class ProtocolVersion { free(): void; /** @@ -7205,9 +7414,9 @@ declare export class SingleHostName { /** * @param {Uint8Array} bytes - * @returns {SingleHostName} + * @returns {ProtocolVersion} */ - static from_bytes(bytes: Uint8Array): SingleHostName; + static from_bytes(bytes: Uint8Array): ProtocolVersion; /** * @returns {string} @@ -7216,9 +7425,9 @@ declare export class SingleHostName { /** * @param {string} hex_str - * @returns {SingleHostName} + * @returns {ProtocolVersion} */ - static from_hex(hex_str: string): SingleHostName; + static from_hex(hex_str: string): ProtocolVersion; /** * @returns {string} @@ -7226,75 +7435,77 @@ declare export class SingleHostName { to_json(): string; /** - * @returns {SingleHostNameJSON} + * @returns {ProtocolVersionJSON} */ - to_js_value(): SingleHostNameJSON; + to_js_value(): ProtocolVersionJSON; /** * @param {string} json - * @returns {SingleHostName} + * @returns {ProtocolVersion} */ - static from_json(json: string): SingleHostName; + static from_json(json: string): ProtocolVersion; /** - * @returns {number | void} + * @returns {number} */ - port(): number | void; + major(): number; /** - * @returns {DNSRecordAorAAAA} + * @returns {number} */ - dns_name(): DNSRecordAorAAAA; + minor(): number; /** - * @param {number | void} port - * @param {DNSRecordAorAAAA} dns_name - * @returns {SingleHostName} + * @param {number} major + * @param {number} minor + * @returns {ProtocolVersion} */ - static new(port: number | void, dns_name: DNSRecordAorAAAA): SingleHostName; + static new(major: number, minor: number): ProtocolVersion; } /** + * ED25519 key used as public key */ -declare export class StakeCredential { +declare export class PublicKey { free(): void; /** - * @param {Ed25519KeyHash} hash - * @returns {StakeCredential} - */ - static from_keyhash(hash: Ed25519KeyHash): StakeCredential; - - /** - * @param {ScriptHash} hash - * @returns {StakeCredential} + * Get public key from its bech32 representation + * Example: + * ```javascript + * const pkey = PublicKey.from_bech32('ed25519_pk1dgaagyh470y66p899txcl3r0jaeaxu6yd7z2dxyk55qcycdml8gszkxze2'); + * ``` + * @param {string} bech32_str + * @returns {PublicKey} */ - static from_scripthash(hash: ScriptHash): StakeCredential; + static from_bech32(bech32_str: string): PublicKey; /** - * @returns {Ed25519KeyHash | void} + * @returns {string} */ - to_keyhash(): Ed25519KeyHash | void; + to_bech32(): string; /** - * @returns {ScriptHash | void} + * @returns {Uint8Array} */ - to_scripthash(): ScriptHash | void; + as_bytes(): Uint8Array; /** - * @returns {number} + * @param {Uint8Array} bytes + * @returns {PublicKey} */ - kind(): number; + static from_bytes(bytes: Uint8Array): PublicKey; /** - * @returns {Uint8Array} + * @param {Uint8Array} data + * @param {Ed25519Signature} signature + * @returns {boolean} */ - to_bytes(): Uint8Array; + verify(data: Uint8Array, signature: Ed25519Signature): boolean; /** - * @param {Uint8Array} bytes - * @returns {StakeCredential} + * @returns {Ed25519KeyHash} */ - static from_bytes(bytes: Uint8Array): StakeCredential; + hash(): Ed25519KeyHash; /** * @returns {string} @@ -7303,29 +7514,38 @@ declare export class StakeCredential { /** * @param {string} hex_str - * @returns {StakeCredential} + * @returns {PublicKey} */ - static from_hex(hex_str: string): StakeCredential; + static from_hex(hex_str: string): PublicKey; +} +/** + */ +declare export class PublicKeys { + free(): void; /** - * @returns {string} */ - to_json(): string; + constructor(): this; /** - * @returns {StakeCredentialJSON} + * @returns {number} */ - to_js_value(): StakeCredentialJSON; + size(): number; /** - * @param {string} json - * @returns {StakeCredential} + * @param {number} index + * @returns {PublicKey} */ - static from_json(json: string): StakeCredential; + get(index: number): PublicKey; + + /** + * @param {PublicKey} key + */ + add(key: PublicKey): void; } /** */ -declare export class StakeCredentials { +declare export class Redeemer { free(): void; /** @@ -7335,9 +7555,9 @@ declare export class StakeCredentials { /** * @param {Uint8Array} bytes - * @returns {StakeCredentials} + * @returns {Redeemer} */ - static from_bytes(bytes: Uint8Array): StakeCredentials; + static from_bytes(bytes: Uint8Array): Redeemer; /** * @returns {string} @@ -7346,9 +7566,9 @@ declare export class StakeCredentials { /** * @param {string} hex_str - * @returns {StakeCredentials} + * @returns {Redeemer} */ - static from_hex(hex_str: string): StakeCredentials; + static from_hex(hex_str: string): Redeemer; /** * @returns {string} @@ -7356,40 +7576,53 @@ declare export class StakeCredentials { to_json(): string; /** - * @returns {StakeCredentialsJSON} + * @returns {RedeemerJSON} */ - to_js_value(): StakeCredentialsJSON; + to_js_value(): RedeemerJSON; /** * @param {string} json - * @returns {StakeCredentials} + * @returns {Redeemer} */ - static from_json(json: string): StakeCredentials; + static from_json(json: string): Redeemer; /** - * @returns {StakeCredentials} + * @returns {RedeemerTag} */ - static new(): StakeCredentials; + tag(): RedeemerTag; /** - * @returns {number} + * @returns {BigNum} */ - len(): number; + index(): BigNum; /** - * @param {number} index - * @returns {StakeCredential} + * @returns {PlutusData} */ - get(index: number): StakeCredential; + data(): PlutusData; /** - * @param {StakeCredential} elem + * @returns {ExUnits} */ - add(elem: StakeCredential): void; + ex_units(): ExUnits; + + /** + * @param {RedeemerTag} tag + * @param {BigNum} index + * @param {PlutusData} data + * @param {ExUnits} ex_units + * @returns {Redeemer} + */ + static new( + tag: RedeemerTag, + index: BigNum, + data: PlutusData, + ex_units: ExUnits + ): Redeemer; } /** */ -declare export class StakeDelegation { +declare export class RedeemerTag { free(): void; /** @@ -7399,9 +7632,9 @@ declare export class StakeDelegation { /** * @param {Uint8Array} bytes - * @returns {StakeDelegation} + * @returns {RedeemerTag} */ - static from_bytes(bytes: Uint8Array): StakeDelegation; + static from_bytes(bytes: Uint8Array): RedeemerTag; /** * @returns {string} @@ -7410,9 +7643,9 @@ declare export class StakeDelegation { /** * @param {string} hex_str - * @returns {StakeDelegation} + * @returns {RedeemerTag} */ - static from_hex(hex_str: string): StakeDelegation; + static from_hex(hex_str: string): RedeemerTag; /** * @returns {string} @@ -7420,39 +7653,49 @@ declare export class StakeDelegation { to_json(): string; /** - * @returns {StakeDelegationJSON} + * @returns {RedeemerTagJSON} */ - to_js_value(): StakeDelegationJSON; + to_js_value(): RedeemerTagJSON; /** * @param {string} json - * @returns {StakeDelegation} + * @returns {RedeemerTag} */ - static from_json(json: string): StakeDelegation; + static from_json(json: string): RedeemerTag; /** - * @returns {StakeCredential} + * @returns {RedeemerTag} */ - stake_credential(): StakeCredential; + static new_spend(): RedeemerTag; /** - * @returns {Ed25519KeyHash} + * @returns {RedeemerTag} */ - pool_keyhash(): Ed25519KeyHash; + static new_mint(): RedeemerTag; /** - * @param {StakeCredential} stake_credential - * @param {Ed25519KeyHash} pool_keyhash - * @returns {StakeDelegation} + * @returns {RedeemerTag} */ - static new( - stake_credential: StakeCredential, - pool_keyhash: Ed25519KeyHash - ): StakeDelegation; + static new_cert(): RedeemerTag; + + /** + * @returns {RedeemerTag} + */ + static new_reward(): RedeemerTag; + + /** + * @returns {RedeemerTag} + */ + static new_vote(): RedeemerTag; + + /** + * @returns {number} + */ + kind(): number; } /** */ -declare export class StakeDeregistration { +declare export class Redeemers { free(): void; /** @@ -7462,9 +7705,9 @@ declare export class StakeDeregistration { /** * @param {Uint8Array} bytes - * @returns {StakeDeregistration} + * @returns {Redeemers} */ - static from_bytes(bytes: Uint8Array): StakeDeregistration; + static from_bytes(bytes: Uint8Array): Redeemers; /** * @returns {string} @@ -7473,9 +7716,9 @@ declare export class StakeDeregistration { /** * @param {string} hex_str - * @returns {StakeDeregistration} + * @returns {Redeemers} */ - static from_hex(hex_str: string): StakeDeregistration; + static from_hex(hex_str: string): Redeemers; /** * @returns {string} @@ -7483,30 +7726,45 @@ declare export class StakeDeregistration { to_json(): string; /** - * @returns {StakeDeregistrationJSON} + * @returns {RedeemersJSON} */ - to_js_value(): StakeDeregistrationJSON; + to_js_value(): RedeemersJSON; /** * @param {string} json - * @returns {StakeDeregistration} + * @returns {Redeemers} */ - static from_json(json: string): StakeDeregistration; + static from_json(json: string): Redeemers; /** - * @returns {StakeCredential} + * @returns {Redeemers} */ - stake_credential(): StakeCredential; + static new(): Redeemers; /** - * @param {StakeCredential} stake_credential - * @returns {StakeDeregistration} + * @returns {number} */ - static new(stake_credential: StakeCredential): StakeDeregistration; + len(): number; + + /** + * @param {number} index + * @returns {Redeemer} + */ + get(index: number): Redeemer; + + /** + * @param {Redeemer} elem + */ + add(elem: Redeemer): void; + + /** + * @returns {ExUnits} + */ + total_ex_units(): ExUnits; } /** */ -declare export class StakeRegistration { +declare export class Relay { free(): void; /** @@ -7516,9 +7774,9 @@ declare export class StakeRegistration { /** * @param {Uint8Array} bytes - * @returns {StakeRegistration} + * @returns {Relay} */ - static from_bytes(bytes: Uint8Array): StakeRegistration; + static from_bytes(bytes: Uint8Array): Relay; /** * @returns {string} @@ -7527,9 +7785,9 @@ declare export class StakeRegistration { /** * @param {string} hex_str - * @returns {StakeRegistration} + * @returns {Relay} */ - static from_hex(hex_str: string): StakeRegistration; + static from_hex(hex_str: string): Relay; /** * @returns {string} @@ -7537,56 +7795,57 @@ declare export class StakeRegistration { to_json(): string; /** - * @returns {StakeRegistrationJSON} + * @returns {RelayJSON} */ - to_js_value(): StakeRegistrationJSON; + to_js_value(): RelayJSON; /** * @param {string} json - * @returns {StakeRegistration} + * @returns {Relay} */ - static from_json(json: string): StakeRegistration; + static from_json(json: string): Relay; /** - * @returns {StakeCredential} + * @param {SingleHostAddr} single_host_addr + * @returns {Relay} */ - stake_credential(): StakeCredential; + static new_single_host_addr(single_host_addr: SingleHostAddr): Relay; /** - * @param {StakeCredential} stake_credential - * @returns {StakeRegistration} + * @param {SingleHostName} single_host_name + * @returns {Relay} */ - static new(stake_credential: StakeCredential): StakeRegistration; -} -/** - */ -declare export class Strings { - free(): void; + static new_single_host_name(single_host_name: SingleHostName): Relay; /** - * @returns {Strings} + * @param {MultiHostName} multi_host_name + * @returns {Relay} */ - static new(): Strings; + static new_multi_host_name(multi_host_name: MultiHostName): Relay; /** * @returns {number} */ - len(): number; + kind(): number; /** - * @param {number} index - * @returns {string} + * @returns {SingleHostAddr | void} */ - get(index: number): string; + as_single_host_addr(): SingleHostAddr | void; /** - * @param {string} elem + * @returns {SingleHostName | void} */ - add(elem: string): void; + as_single_host_name(): SingleHostName | void; + + /** + * @returns {MultiHostName | void} + */ + as_multi_host_name(): MultiHostName | void; } /** */ -declare export class TimelockExpiry { +declare export class Relays { free(): void; /** @@ -7596,9 +7855,9 @@ declare export class TimelockExpiry { /** * @param {Uint8Array} bytes - * @returns {TimelockExpiry} + * @returns {Relays} */ - static from_bytes(bytes: Uint8Array): TimelockExpiry; + static from_bytes(bytes: Uint8Array): Relays; /** * @returns {string} @@ -7607,9 +7866,9 @@ declare export class TimelockExpiry { /** * @param {string} hex_str - * @returns {TimelockExpiry} + * @returns {Relays} */ - static from_hex(hex_str: string): TimelockExpiry; + static from_hex(hex_str: string): Relays; /** * @returns {string} @@ -7617,44 +7876,68 @@ declare export class TimelockExpiry { to_json(): string; /** - * @returns {TimelockExpiryJSON} + * @returns {RelaysJSON} */ - to_js_value(): TimelockExpiryJSON; + to_js_value(): RelaysJSON; /** * @param {string} json - * @returns {TimelockExpiry} + * @returns {Relays} */ - static from_json(json: string): TimelockExpiry; + static from_json(json: string): Relays; + + /** + * @returns {Relays} + */ + static new(): Relays; /** * @returns {number} */ - slot(): number; + len(): number; /** - * @returns {BigNum} + * @param {number} index + * @returns {Relay} */ - slot_bignum(): BigNum; + get(index: number): Relay; /** - * !!! DEPRECATED !!! - * This constructor uses outdated slot number format. - * Use `.new_timelockexpiry` instead - * @param {number} slot - * @returns {TimelockExpiry} + * @param {Relay} elem */ - static new(slot: number): TimelockExpiry; + add(elem: Relay): void; +} +/** + */ +declare export class RewardAddress { + free(): void; /** - * @param {BigNum} slot - * @returns {TimelockExpiry} + * @param {number} network + * @param {StakeCredential} payment + * @returns {RewardAddress} */ - static new_timelockexpiry(slot: BigNum): TimelockExpiry; + static new(network: number, payment: StakeCredential): RewardAddress; + + /** + * @returns {StakeCredential} + */ + payment_cred(): StakeCredential; + + /** + * @returns {Address} + */ + to_address(): Address; + + /** + * @param {Address} addr + * @returns {RewardAddress | void} + */ + static from_address(addr: Address): RewardAddress | void; } /** */ -declare export class TimelockStart { +declare export class RewardAddresses { free(): void; /** @@ -7664,9 +7947,9 @@ declare export class TimelockStart { /** * @param {Uint8Array} bytes - * @returns {TimelockStart} + * @returns {RewardAddresses} */ - static from_bytes(bytes: Uint8Array): TimelockStart; + static from_bytes(bytes: Uint8Array): RewardAddresses; /** * @returns {string} @@ -7675,9 +7958,9 @@ declare export class TimelockStart { /** * @param {string} hex_str - * @returns {TimelockStart} + * @returns {RewardAddresses} */ - static from_hex(hex_str: string): TimelockStart; + static from_hex(hex_str: string): RewardAddresses; /** * @returns {string} @@ -7685,48 +7968,40 @@ declare export class TimelockStart { to_json(): string; /** - * @returns {TimelockStartJSON} + * @returns {RewardAddressesJSON} */ - to_js_value(): TimelockStartJSON; + to_js_value(): RewardAddressesJSON; /** * @param {string} json - * @returns {TimelockStart} + * @returns {RewardAddresses} */ - static from_json(json: string): TimelockStart; + static from_json(json: string): RewardAddresses; /** - * !!! DEPRECATED !!! - * Returns a Slot32 (u32) value in case the underlying original BigNum (u64) value is within the limits. - * Otherwise will just raise an error. - * Use `.slot_bignum` instead - * @returns {number} + * @returns {RewardAddresses} */ - slot(): number; + static new(): RewardAddresses; /** - * @returns {BigNum} + * @returns {number} */ - slot_bignum(): BigNum; + len(): number; /** - * !!! DEPRECATED !!! - * This constructor uses outdated slot number format. - * Use `.new_timelockstart` instead. - * @param {number} slot - * @returns {TimelockStart} + * @param {number} index + * @returns {RewardAddress} */ - static new(slot: number): TimelockStart; + get(index: number): RewardAddress; /** - * @param {BigNum} slot - * @returns {TimelockStart} + * @param {RewardAddress} elem */ - static new_timelockstart(slot: BigNum): TimelockStart; + add(elem: RewardAddress): void; } /** */ -declare export class Transaction { +declare export class ScriptAll { free(): void; /** @@ -7736,9 +8011,9 @@ declare export class Transaction { /** * @param {Uint8Array} bytes - * @returns {Transaction} + * @returns {ScriptAll} */ - static from_bytes(bytes: Uint8Array): Transaction; + static from_bytes(bytes: Uint8Array): ScriptAll; /** * @returns {string} @@ -7747,9 +8022,9 @@ declare export class Transaction { /** * @param {string} hex_str - * @returns {Transaction} + * @returns {ScriptAll} */ - static from_hex(hex_str: string): Transaction; + static from_hex(hex_str: string): ScriptAll; /** * @returns {string} @@ -7757,88 +8032,162 @@ declare export class Transaction { to_json(): string; /** - * @returns {TransactionJSON} + * @returns {ScriptAllJSON} */ - to_js_value(): TransactionJSON; + to_js_value(): ScriptAllJSON; /** * @param {string} json - * @returns {Transaction} + * @returns {ScriptAll} */ - static from_json(json: string): Transaction; + static from_json(json: string): ScriptAll; /** - * @returns {TransactionBody} + * @returns {NativeScripts} */ - body(): TransactionBody; + native_scripts(): NativeScripts; /** - * @returns {TransactionWitnessSet} + * @param {NativeScripts} native_scripts + * @returns {ScriptAll} */ - witness_set(): TransactionWitnessSet; - + static new(native_scripts: NativeScripts): ScriptAll; +} +/** + */ +declare export class ScriptAny { + free(): void; + /** - * @returns {boolean} + * @returns {Uint8Array} */ - is_valid(): boolean; + to_bytes(): Uint8Array; /** - * @returns {AuxiliaryData | void} + * @param {Uint8Array} bytes + * @returns {ScriptAny} */ - auxiliary_data(): AuxiliaryData | void; + static from_bytes(bytes: Uint8Array): ScriptAny; /** - * @param {boolean} valid + * @returns {string} */ - set_is_valid(valid: boolean): void; + to_hex(): string; /** - * @param {TransactionBody} body - * @param {TransactionWitnessSet} witness_set - * @param {AuxiliaryData | void} auxiliary_data - * @returns {Transaction} + * @param {string} hex_str + * @returns {ScriptAny} */ - static new( - body: TransactionBody, - witness_set: TransactionWitnessSet, - auxiliary_data?: AuxiliaryData - ): Transaction; + static from_hex(hex_str: string): ScriptAny; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {ScriptAnyJSON} + */ + to_js_value(): ScriptAnyJSON; + + /** + * @param {string} json + * @returns {ScriptAny} + */ + static from_json(json: string): ScriptAny; + + /** + * @returns {NativeScripts} + */ + native_scripts(): NativeScripts; + + /** + * @param {NativeScripts} native_scripts + * @returns {ScriptAny} + */ + static new(native_scripts: NativeScripts): ScriptAny; } /** */ -declare export class TransactionBatch { +declare export class ScriptDataHash { free(): void; /** - * @returns {number} + * @param {Uint8Array} bytes + * @returns {ScriptDataHash} */ - len(): number; + static from_bytes(bytes: Uint8Array): ScriptDataHash; /** - * @param {number} index - * @returns {Transaction} + * @returns {Uint8Array} */ - get(index: number): Transaction; + to_bytes(): Uint8Array; + + /** + * @param {string} prefix + * @returns {string} + */ + to_bech32(prefix: string): string; + + /** + * @param {string} bech_str + * @returns {ScriptDataHash} + */ + static from_bech32(bech_str: string): ScriptDataHash; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex + * @returns {ScriptDataHash} + */ + static from_hex(hex: string): ScriptDataHash; } /** */ -declare export class TransactionBatchList { +declare export class ScriptHash { free(): void; /** - * @returns {number} + * @param {Uint8Array} bytes + * @returns {ScriptHash} */ - len(): number; + static from_bytes(bytes: Uint8Array): ScriptHash; /** - * @param {number} index - * @returns {TransactionBatch} + * @returns {Uint8Array} */ - get(index: number): TransactionBatch; + to_bytes(): Uint8Array; + + /** + * @param {string} prefix + * @returns {string} + */ + to_bech32(prefix: string): string; + + /** + * @param {string} bech_str + * @returns {ScriptHash} + */ + static from_bech32(bech_str: string): ScriptHash; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex + * @returns {ScriptHash} + */ + static from_hex(hex: string): ScriptHash; } /** */ -declare export class TransactionBodies { +declare export class ScriptHashes { free(): void; /** @@ -7848,9 +8197,9 @@ declare export class TransactionBodies { /** * @param {Uint8Array} bytes - * @returns {TransactionBodies} + * @returns {ScriptHashes} */ - static from_bytes(bytes: Uint8Array): TransactionBodies; + static from_bytes(bytes: Uint8Array): ScriptHashes; /** * @returns {string} @@ -7859,9 +8208,9 @@ declare export class TransactionBodies { /** * @param {string} hex_str - * @returns {TransactionBodies} + * @returns {ScriptHashes} */ - static from_hex(hex_str: string): TransactionBodies; + static from_hex(hex_str: string): ScriptHashes; /** * @returns {string} @@ -7869,20 +8218,20 @@ declare export class TransactionBodies { to_json(): string; /** - * @returns {TransactionBodiesJSON} + * @returns {ScriptHashesJSON} */ - to_js_value(): TransactionBodiesJSON; + to_js_value(): ScriptHashesJSON; /** * @param {string} json - * @returns {TransactionBodies} + * @returns {ScriptHashes} */ - static from_json(json: string): TransactionBodies; + static from_json(json: string): ScriptHashes; /** - * @returns {TransactionBodies} + * @returns {ScriptHashes} */ - static new(): TransactionBodies; + static new(): ScriptHashes; /** * @returns {number} @@ -7891,18 +8240,18 @@ declare export class TransactionBodies { /** * @param {number} index - * @returns {TransactionBody} + * @returns {ScriptHash} */ - get(index: number): TransactionBody; + get(index: number): ScriptHash; /** - * @param {TransactionBody} elem + * @param {ScriptHash} elem */ - add(elem: TransactionBody): void; + add(elem: ScriptHash): void; } /** */ -declare export class TransactionBody { +declare export class ScriptNOfK { free(): void; /** @@ -7912,9 +8261,9 @@ declare export class TransactionBody { /** * @param {Uint8Array} bytes - * @returns {TransactionBody} + * @returns {ScriptNOfK} */ - static from_bytes(bytes: Uint8Array): TransactionBody; + static from_bytes(bytes: Uint8Array): ScriptNOfK; /** * @returns {string} @@ -7923,9 +8272,9 @@ declare export class TransactionBody { /** * @param {string} hex_str - * @returns {TransactionBody} + * @returns {ScriptNOfK} */ - static from_hex(hex_str: string): TransactionBody; + static from_hex(hex_str: string): ScriptNOfK; /** * @returns {string} @@ -7933,903 +8282,2829 @@ declare export class TransactionBody { to_json(): string; /** - * @returns {TransactionBodyJSON} + * @returns {ScriptNOfKJSON} */ - to_js_value(): TransactionBodyJSON; + to_js_value(): ScriptNOfKJSON; /** * @param {string} json - * @returns {TransactionBody} + * @returns {ScriptNOfK} */ - static from_json(json: string): TransactionBody; + static from_json(json: string): ScriptNOfK; /** - * @returns {TransactionInputs} + * @returns {number} */ - inputs(): TransactionInputs; + n(): number; /** - * @returns {TransactionOutputs} + * @returns {NativeScripts} */ - outputs(): TransactionOutputs; + native_scripts(): NativeScripts; /** - * @returns {BigNum} + * @param {number} n + * @param {NativeScripts} native_scripts + * @returns {ScriptNOfK} */ - fee(): BigNum; + static new(n: number, native_scripts: NativeScripts): ScriptNOfK; +} +/** + */ +declare export class ScriptPubkey { + free(): void; /** - * !!! DEPRECATED !!! - * Returns a Slot32 (u32) value in case the underlying original BigNum (u64) value is within the limits. - * Otherwise will just raise an error. - * @returns {number | void} + * @returns {Uint8Array} */ - ttl(): number | void; + to_bytes(): Uint8Array; /** - * @returns {BigNum | void} + * @param {Uint8Array} bytes + * @returns {ScriptPubkey} */ - ttl_bignum(): BigNum | void; + static from_bytes(bytes: Uint8Array): ScriptPubkey; /** - * @param {BigNum} ttl + * @returns {string} */ - set_ttl(ttl: BigNum): void; + to_hex(): string; /** + * @param {string} hex_str + * @returns {ScriptPubkey} */ - remove_ttl(): void; + static from_hex(hex_str: string): ScriptPubkey; /** - * @param {Certificates} certs + * @returns {string} */ - set_certs(certs: Certificates): void; + to_json(): string; /** - * @returns {Certificates | void} + * @returns {ScriptPubkeyJSON} */ - certs(): Certificates | void; + to_js_value(): ScriptPubkeyJSON; /** - * @param {Withdrawals} withdrawals + * @param {string} json + * @returns {ScriptPubkey} */ - set_withdrawals(withdrawals: Withdrawals): void; + static from_json(json: string): ScriptPubkey; /** - * @returns {Withdrawals | void} + * @returns {Ed25519KeyHash} */ - withdrawals(): Withdrawals | void; + addr_keyhash(): Ed25519KeyHash; /** - * @param {Update} update + * @param {Ed25519KeyHash} addr_keyhash + * @returns {ScriptPubkey} */ - set_update(update: Update): void; + static new(addr_keyhash: Ed25519KeyHash): ScriptPubkey; +} +/** + */ +declare export class ScriptRef { + free(): void; /** - * @returns {Update | void} + * @returns {Uint8Array} */ - update(): Update | void; + to_bytes(): Uint8Array; /** - * @param {AuxiliaryDataHash} auxiliary_data_hash + * @param {Uint8Array} bytes + * @returns {ScriptRef} */ - set_auxiliary_data_hash(auxiliary_data_hash: AuxiliaryDataHash): void; + static from_bytes(bytes: Uint8Array): ScriptRef; /** - * @returns {AuxiliaryDataHash | void} + * @returns {string} */ - auxiliary_data_hash(): AuxiliaryDataHash | void; + to_hex(): string; /** - * !!! DEPRECATED !!! - * Uses outdated slot number format. - * @param {number} validity_start_interval + * @param {string} hex_str + * @returns {ScriptRef} */ - set_validity_start_interval(validity_start_interval: number): void; + static from_hex(hex_str: string): ScriptRef; /** - * @param {BigNum} validity_start_interval + * @returns {string} */ - set_validity_start_interval_bignum(validity_start_interval: BigNum): void; + to_json(): string; /** - * @returns {BigNum | void} + * @returns {ScriptRefJSON} */ - validity_start_interval_bignum(): BigNum | void; + to_js_value(): ScriptRefJSON; /** - * !!! DEPRECATED !!! - * Returns a Option (u32) value in case the underlying original Option (u64) value is within the limits. - * Otherwise will just raise an error. - * Use `.validity_start_interval_bignum` instead. - * @returns {number | void} + * @param {string} json + * @returns {ScriptRef} */ - validity_start_interval(): number | void; + static from_json(json: string): ScriptRef; /** - * @param {Mint} mint + * @param {NativeScript} native_script + * @returns {ScriptRef} */ - set_mint(mint: Mint): void; + static new_native_script(native_script: NativeScript): ScriptRef; /** - * @returns {Mint | void} + * @param {PlutusScript} plutus_script + * @returns {ScriptRef} */ - mint(): Mint | void; + static new_plutus_script(plutus_script: PlutusScript): ScriptRef; /** - * This function returns the mint value of the transaction - * Use `.mint()` instead. - * @returns {Mint | void} + * @returns {boolean} */ - multiassets(): Mint | void; + is_native_script(): boolean; /** - * @param {TransactionInputs} reference_inputs + * @returns {boolean} */ - set_reference_inputs(reference_inputs: TransactionInputs): void; + is_plutus_script(): boolean; /** - * @returns {TransactionInputs | void} + * @returns {NativeScript | void} */ - reference_inputs(): TransactionInputs | void; + native_script(): NativeScript | void; /** - * @param {ScriptDataHash} script_data_hash + * @returns {PlutusScript | void} */ - set_script_data_hash(script_data_hash: ScriptDataHash): void; + plutus_script(): PlutusScript | void; +} +/** + */ +declare export class SingleHostAddr { + free(): void; /** - * @returns {ScriptDataHash | void} + * @returns {Uint8Array} */ - script_data_hash(): ScriptDataHash | void; + to_bytes(): Uint8Array; /** - * @param {TransactionInputs} collateral + * @param {Uint8Array} bytes + * @returns {SingleHostAddr} */ - set_collateral(collateral: TransactionInputs): void; + static from_bytes(bytes: Uint8Array): SingleHostAddr; /** - * @returns {TransactionInputs | void} + * @returns {string} */ - collateral(): TransactionInputs | void; + to_hex(): string; /** - * @param {Ed25519KeyHashes} required_signers + * @param {string} hex_str + * @returns {SingleHostAddr} */ - set_required_signers(required_signers: Ed25519KeyHashes): void; + static from_hex(hex_str: string): SingleHostAddr; /** - * @returns {Ed25519KeyHashes | void} + * @returns {string} */ - required_signers(): Ed25519KeyHashes | void; + to_json(): string; /** - * @param {NetworkId} network_id + * @returns {SingleHostAddrJSON} */ - set_network_id(network_id: NetworkId): void; + to_js_value(): SingleHostAddrJSON; /** - * @returns {NetworkId | void} + * @param {string} json + * @returns {SingleHostAddr} */ - network_id(): NetworkId | void; + static from_json(json: string): SingleHostAddr; /** - * @param {TransactionOutput} collateral_return + * @returns {number | void} */ - set_collateral_return(collateral_return: TransactionOutput): void; + port(): number | void; /** - * @returns {TransactionOutput | void} + * @returns {Ipv4 | void} */ - collateral_return(): TransactionOutput | void; + ipv4(): Ipv4 | void; /** - * @param {BigNum} total_collateral + * @returns {Ipv6 | void} */ - set_total_collateral(total_collateral: BigNum): void; + ipv6(): Ipv6 | void; /** - * @returns {BigNum | void} + * @param {number | void} port + * @param {Ipv4 | void} ipv4 + * @param {Ipv6 | void} ipv6 + * @returns {SingleHostAddr} */ - total_collateral(): BigNum | void; + static new(port?: number, ipv4?: Ipv4, ipv6?: Ipv6): SingleHostAddr; +} +/** + */ +declare export class SingleHostName { + free(): void; /** - * !!! DEPRECATED !!! - * This constructor uses outdated slot number format for the ttl value. - * Use `.new_tx_body` and then `.set_ttl` instead - * @param {TransactionInputs} inputs - * @param {TransactionOutputs} outputs - * @param {BigNum} fee - * @param {number | void} ttl - * @returns {TransactionBody} + * @returns {Uint8Array} */ - static new( - inputs: TransactionInputs, - outputs: TransactionOutputs, - fee: BigNum, - ttl?: number - ): TransactionBody; + to_bytes(): Uint8Array; /** - * Returns a new TransactionBody. - * In the new version of "new" we removed optional ttl for support it by wasm_bingen. - * Your can use "set_ttl" and "remove_ttl" to set a new value for ttl or set it as None. - * @param {TransactionInputs} inputs - * @param {TransactionOutputs} outputs - * @param {BigNum} fee - * @returns {TransactionBody} + * @param {Uint8Array} bytes + * @returns {SingleHostName} */ - static new_tx_body( - inputs: TransactionInputs, - outputs: TransactionOutputs, - fee: BigNum - ): TransactionBody; -} -/** - */ -declare export class TransactionBuilder { - free(): void; + static from_bytes(bytes: Uint8Array): SingleHostName; /** - * This automatically selects and adds inputs from {inputs} consisting of just enough to cover - * the outputs that have already been added. - * This should be called after adding all certs/outputs/etc and will be an error otherwise. - * Uses CIP2: https://github.com/cardano-foundation/CIPs/blob/master/CIP-0002/CIP-0002.md - * Adding a change output must be called after via TransactionBuilder::add_change_if_needed() - * This function, diverging from CIP2, takes into account fees and will attempt to add additional - * inputs to cover the minimum fees. This does not, however, set the txbuilder's fee. - * @param {TransactionUnspentOutputs} inputs - * @param {number} strategy + * @returns {string} */ - add_inputs_from(inputs: TransactionUnspentOutputs, strategy: number): void; + to_hex(): string; /** - * @param {TxInputsBuilder} inputs + * @param {string} hex_str + * @returns {SingleHostName} */ - set_inputs(inputs: TxInputsBuilder): void; + static from_hex(hex_str: string): SingleHostName; /** - * @param {TxInputsBuilder} collateral + * @returns {string} */ - set_collateral(collateral: TxInputsBuilder): void; + to_json(): string; /** - * @param {TransactionOutput} collateral_return + * @returns {SingleHostNameJSON} */ - set_collateral_return(collateral_return: TransactionOutput): void; + to_js_value(): SingleHostNameJSON; /** - * This function will set the collateral-return value and then auto-calculate and assign - * the total collateral coin value. Will raise an error in case no collateral inputs are set - * or in case the total collateral value will have any assets in it except coin. - * @param {TransactionOutput} collateral_return + * @param {string} json + * @returns {SingleHostName} */ - set_collateral_return_and_total(collateral_return: TransactionOutput): void; + static from_json(json: string): SingleHostName; /** - * @param {BigNum} total_collateral + * @returns {number | void} */ - set_total_collateral(total_collateral: BigNum): void; + port(): number | void; /** - * This function will set the total-collateral coin and then auto-calculate and assign - * the collateral return value. Will raise an error in case no collateral inputs are set. - * The specified address will be the received of the collateral return - * @param {BigNum} total_collateral - * @param {Address} return_address + * @returns {DNSRecordAorAAAA} */ - set_total_collateral_and_return( - total_collateral: BigNum, - return_address: Address - ): void; + dns_name(): DNSRecordAorAAAA; /** - * @param {TransactionInput} reference_input + * @param {number | void} port + * @param {DNSRecordAorAAAA} dns_name + * @returns {SingleHostName} */ - add_reference_input(reference_input: TransactionInput): void; + static new(port: number | void, dns_name: DNSRecordAorAAAA): SingleHostName; +} +/** + */ +declare export class StakeAndVoteDelegation { + free(): void; /** - * We have to know what kind of inputs these are to know what kind of mock witnesses to create since - * 1) mock witnesses have different lengths depending on the type which changes the expecting fee - * 2) Witnesses are a set so we need to get rid of duplicates to avoid over-estimating the fee - * @param {Ed25519KeyHash} hash - * @param {TransactionInput} input - * @param {Value} amount + * @returns {Uint8Array} */ - add_key_input( - hash: Ed25519KeyHash, - input: TransactionInput, - amount: Value - ): void; + to_bytes(): Uint8Array; /** - * This method adds the input to the builder BUT leaves a missing spot for the witness native script - * - * After adding the input with this method, use `.add_required_native_input_scripts` - * and `.add_required_plutus_input_scripts` to add the witness scripts - * - * Or instead use `.add_native_script_input` and `.add_plutus_script_input` - * to add inputs right along with the script, instead of the script hash - * @param {ScriptHash} hash - * @param {TransactionInput} input - * @param {Value} amount + * @param {Uint8Array} bytes + * @returns {StakeAndVoteDelegation} */ - add_script_input( - hash: ScriptHash, - input: TransactionInput, - amount: Value - ): void; + static from_bytes(bytes: Uint8Array): StakeAndVoteDelegation; /** - * This method will add the input to the builder and also register the required native script witness - * @param {NativeScript} script - * @param {TransactionInput} input - * @param {Value} amount + * @returns {string} */ - add_native_script_input( - script: NativeScript, - input: TransactionInput, - amount: Value - ): void; + to_hex(): string; /** - * This method will add the input to the builder and also register the required plutus witness - * @param {PlutusWitness} witness - * @param {TransactionInput} input - * @param {Value} amount + * @param {string} hex_str + * @returns {StakeAndVoteDelegation} */ - add_plutus_script_input( - witness: PlutusWitness, - input: TransactionInput, - amount: Value - ): void; + static from_hex(hex_str: string): StakeAndVoteDelegation; /** - * @param {ByronAddress} hash - * @param {TransactionInput} input - * @param {Value} amount + * @returns {string} */ - add_bootstrap_input( - hash: ByronAddress, - input: TransactionInput, - amount: Value - ): void; + to_json(): string; /** - * Note that for script inputs this method will use underlying generic `.add_script_input` - * which leaves a required empty spot for the script witness (or witnesses in case of Plutus). - * You can use `.add_native_script_input` or `.add_plutus_script_input` directly to register the input along with the witness. - * @param {Address} address - * @param {TransactionInput} input - * @param {Value} amount + * @returns {StakeAndVoteDelegationJSON} */ - add_input(address: Address, input: TransactionInput, amount: Value): void; + to_js_value(): StakeAndVoteDelegationJSON; /** - * Returns the number of still missing input scripts (either native or plutus) - * Use `.add_required_native_input_scripts` or `.add_required_plutus_input_scripts` to add the missing scripts - * @returns {number} + * @param {string} json + * @returns {StakeAndVoteDelegation} */ - count_missing_input_scripts(): number; + static from_json(json: string): StakeAndVoteDelegation; /** - * Try adding the specified scripts as witnesses for ALREADY ADDED script inputs - * Any scripts that don't match any of the previously added inputs will be ignored - * Returns the number of remaining required missing witness scripts - * Use `.count_missing_input_scripts` to find the number of still missing scripts - * @param {NativeScripts} scripts - * @returns {number} + * @returns {StakeCredential} */ - add_required_native_input_scripts(scripts: NativeScripts): number; + stake_credential(): StakeCredential; /** - * Try adding the specified scripts as witnesses for ALREADY ADDED script inputs - * Any scripts that don't match any of the previously added inputs will be ignored - * Returns the number of remaining required missing witness scripts - * Use `.count_missing_input_scripts` to find the number of still missing scripts - * @param {PlutusWitnesses} scripts - * @returns {number} + * @returns {Ed25519KeyHash} */ - add_required_plutus_input_scripts(scripts: PlutusWitnesses): number; + pool_keyhash(): Ed25519KeyHash; /** - * Returns a copy of the current script input witness scripts in the builder - * @returns {NativeScripts | void} + * @returns {DRep} */ - get_native_input_scripts(): NativeScripts | void; + drep(): DRep; /** - * Returns a copy of the current plutus input witness scripts in the builder. - * NOTE: each plutus witness will be cloned with a specific corresponding input index - * @returns {PlutusWitnesses | void} + * @param {StakeCredential} stake_credential + * @param {Ed25519KeyHash} pool_keyhash + * @param {DRep} drep + * @returns {StakeAndVoteDelegation} */ - get_plutus_input_scripts(): PlutusWitnesses | void; + static new( + stake_credential: StakeCredential, + pool_keyhash: Ed25519KeyHash, + drep: DRep + ): StakeAndVoteDelegation; /** - * calculates how much the fee would increase if you added a given output - * @param {Address} address - * @param {TransactionInput} input - * @param {Value} amount - * @returns {BigNum} + * @returns {boolean} */ - fee_for_input( - address: Address, - input: TransactionInput, - amount: Value - ): BigNum; + has_script_credentials(): boolean; +} +/** + */ +declare export class StakeCredential { + free(): void; /** - * Add explicit output via a TransactionOutput object - * @param {TransactionOutput} output + * @param {Ed25519KeyHash} hash + * @returns {StakeCredential} */ - add_output(output: TransactionOutput): void; + static from_keyhash(hash: Ed25519KeyHash): StakeCredential; /** - * calculates how much the fee would increase if you added a given output - * @param {TransactionOutput} output - * @returns {BigNum} + * @param {ScriptHash} hash + * @returns {StakeCredential} */ - fee_for_output(output: TransactionOutput): BigNum; + static from_scripthash(hash: ScriptHash): StakeCredential; /** - * @param {BigNum} fee + * @returns {Ed25519KeyHash | void} */ - set_fee(fee: BigNum): void; + to_keyhash(): Ed25519KeyHash | void; /** - * !!! DEPRECATED !!! - * Set ttl value. - * @param {number} ttl + * @returns {ScriptHash | void} */ - set_ttl(ttl: number): void; + to_scripthash(): ScriptHash | void; /** - * @param {BigNum} ttl + * @returns {number} */ - set_ttl_bignum(ttl: BigNum): void; + kind(): number; /** - * !!! DEPRECATED !!! - * Uses outdated slot number format. - * @param {number} validity_start_interval + * @returns {boolean} */ - set_validity_start_interval(validity_start_interval: number): void; + has_script_hash(): boolean; /** - * @param {BigNum} validity_start_interval + * @returns {Uint8Array} */ - set_validity_start_interval_bignum(validity_start_interval: BigNum): void; + to_bytes(): Uint8Array; /** - * @param {Certificates} certs + * @param {Uint8Array} bytes + * @returns {StakeCredential} */ - set_certs(certs: Certificates): void; + static from_bytes(bytes: Uint8Array): StakeCredential; /** - * @param {Withdrawals} withdrawals + * @returns {string} */ - set_withdrawals(withdrawals: Withdrawals): void; + to_hex(): string; /** - * @returns {AuxiliaryData | void} + * @param {string} hex_str + * @returns {StakeCredential} */ - get_auxiliary_data(): AuxiliaryData | void; + static from_hex(hex_str: string): StakeCredential; /** - * Set explicit auxiliary data via an AuxiliaryData object - * It might contain some metadata plus native or Plutus scripts - * @param {AuxiliaryData} auxiliary_data + * @returns {string} */ - set_auxiliary_data(auxiliary_data: AuxiliaryData): void; + to_json(): string; /** - * Set metadata using a GeneralTransactionMetadata object - * It will be set to the existing or new auxiliary data in this builder - * @param {GeneralTransactionMetadata} metadata + * @returns {StakeCredentialJSON} */ - set_metadata(metadata: GeneralTransactionMetadata): void; + to_js_value(): StakeCredentialJSON; /** - * Add a single metadatum using TransactionMetadatumLabel and TransactionMetadatum objects - * It will be securely added to existing or new metadata in this builder - * @param {BigNum} key - * @param {TransactionMetadatum} val + * @param {string} json + * @returns {StakeCredential} */ - add_metadatum(key: BigNum, val: TransactionMetadatum): void; + static from_json(json: string): StakeCredential; +} +/** + */ +declare export class StakeCredentials { + free(): void; /** - * Add a single JSON metadatum using a TransactionMetadatumLabel and a String - * It will be securely added to existing or new metadata in this builder - * @param {BigNum} key - * @param {string} val + * @returns {Uint8Array} */ - add_json_metadatum(key: BigNum, val: string): void; + to_bytes(): Uint8Array; /** - * Add a single JSON metadatum using a TransactionMetadatumLabel, a String, and a MetadataJsonSchema object - * It will be securely added to existing or new metadata in this builder - * @param {BigNum} key - * @param {string} val - * @param {number} schema + * @param {Uint8Array} bytes + * @returns {StakeCredentials} */ - add_json_metadatum_with_schema( - key: BigNum, - val: string, - schema: number - ): void; + static from_bytes(bytes: Uint8Array): StakeCredentials; /** - * @param {MintBuilder} mint_builder + * @returns {string} */ - set_mint_builder(mint_builder: MintBuilder): void; + to_hex(): string; /** - * @returns {MintBuilder | void} + * @param {string} hex_str + * @returns {StakeCredentials} */ - get_mint_builder(): MintBuilder | void; + static from_hex(hex_str: string): StakeCredentials; /** - * !!! DEPRECATED !!! - * Mints are defining by MintBuilder now. - * Use `.set_mint_builder()` and `MintBuilder` instead. - * Set explicit Mint object and the required witnesses to this builder - * it will replace any previously existing mint and mint scripts - * NOTE! Error will be returned in case a mint policy does not have a matching script - * @param {Mint} mint - * @param {NativeScripts} mint_scripts + * @returns {string} */ - set_mint(mint: Mint, mint_scripts: NativeScripts): void; + to_json(): string; /** - * !!! DEPRECATED !!! - * Mints are defining by MintBuilder now. - * Use `.get_mint_builder()` and `.build()` instead. - * Returns a copy of the current mint state in the builder - * @returns {Mint | void} + * @returns {StakeCredentialsJSON} */ - get_mint(): Mint | void; + to_js_value(): StakeCredentialsJSON; /** - * Returns a copy of the current mint witness scripts in the builder - * @returns {NativeScripts | void} + * @param {string} json + * @returns {StakeCredentials} */ - get_mint_scripts(): NativeScripts | void; + static from_json(json: string): StakeCredentials; /** - * !!! DEPRECATED !!! - * Mints are defining by MintBuilder now. - * Use `.set_mint_builder()` and `MintBuilder` instead. - * Add a mint entry to this builder using a PolicyID and MintAssets object - * It will be securely added to existing or new Mint in this builder - * It will replace any existing mint assets with the same PolicyID - * @param {NativeScript} policy_script - * @param {MintAssets} mint_assets + * @returns {StakeCredentials} */ - set_mint_asset(policy_script: NativeScript, mint_assets: MintAssets): void; + static new(): StakeCredentials; /** - * !!! DEPRECATED !!! - * Mints are defining by MintBuilder now. - * Use `.set_mint_builder()` and `MintBuilder` instead. - * Add a mint entry to this builder using a PolicyID, AssetName, and Int object for amount - * It will be securely added to existing or new Mint in this builder - * It will replace any previous existing amount same PolicyID and AssetName - * @param {NativeScript} policy_script - * @param {AssetName} asset_name - * @param {Int} amount + * @returns {number} */ - add_mint_asset( - policy_script: NativeScript, - asset_name: AssetName, - amount: Int - ): void; + len(): number; /** - * Add a mint entry together with an output to this builder - * Using a PolicyID, AssetName, Int for amount, Address, and Coin (BigNum) objects - * The asset will be securely added to existing or new Mint in this builder - * A new output will be added with the specified Address, the Coin value, and the minted asset - * @param {NativeScript} policy_script - * @param {AssetName} asset_name - * @param {Int} amount - * @param {TransactionOutputAmountBuilder} output_builder - * @param {BigNum} output_coin + * @param {number} index + * @returns {StakeCredential} */ - add_mint_asset_and_output( - policy_script: NativeScript, - asset_name: AssetName, - amount: Int, - output_builder: TransactionOutputAmountBuilder, - output_coin: BigNum - ): void; + get(index: number): StakeCredential; /** - * Add a mint entry together with an output to this builder - * Using a PolicyID, AssetName, Int for amount, and Address objects - * The asset will be securely added to existing or new Mint in this builder - * A new output will be added with the specified Address and the minted asset - * The output will be set to contain the minimum required amount of Coin - * @param {NativeScript} policy_script - * @param {AssetName} asset_name - * @param {Int} amount - * @param {TransactionOutputAmountBuilder} output_builder + * @param {StakeCredential} elem */ - add_mint_asset_and_output_min_required_coin( - policy_script: NativeScript, - asset_name: AssetName, - amount: Int, - output_builder: TransactionOutputAmountBuilder - ): void; + add(elem: StakeCredential): void; +} +/** + */ +declare export class StakeDelegation { + free(): void; /** - * @param {TransactionBuilderConfig} cfg - * @returns {TransactionBuilder} + * @returns {Uint8Array} */ - static new(cfg: TransactionBuilderConfig): TransactionBuilder; + to_bytes(): Uint8Array; /** - * @returns {TransactionInputs} + * @param {Uint8Array} bytes + * @returns {StakeDelegation} */ - get_reference_inputs(): TransactionInputs; + static from_bytes(bytes: Uint8Array): StakeDelegation; /** - * does not include refunds or withdrawals - * @returns {Value} + * @returns {string} */ - get_explicit_input(): Value; + to_hex(): string; /** - * withdrawals and refunds - * @returns {Value} + * @param {string} hex_str + * @returns {StakeDelegation} */ - get_implicit_input(): Value; + static from_hex(hex_str: string): StakeDelegation; /** - * Return explicit input plus implicit input plus mint - * @returns {Value} + * @returns {string} */ - get_total_input(): Value; + to_json(): string; /** - * Return explicit output plus deposit plus burn - * @returns {Value} + * @returns {StakeDelegationJSON} */ - get_total_output(): Value; + to_js_value(): StakeDelegationJSON; /** - * does not include fee - * @returns {Value} + * @param {string} json + * @returns {StakeDelegation} */ - get_explicit_output(): Value; + static from_json(json: string): StakeDelegation; /** - * @returns {BigNum} + * @returns {StakeCredential} */ - get_deposit(): BigNum; + stake_credential(): StakeCredential; /** - * @returns {BigNum | void} + * @returns {Ed25519KeyHash} */ - get_fee_if_set(): BigNum | void; + pool_keyhash(): Ed25519KeyHash; /** - * Warning: this function will mutate the /fee/ field - * Make sure to call this function last after setting all other tx-body properties - * Editing inputs, outputs, mint, etc. after change been calculated - * might cause a mismatch in calculated fee versus the required fee - * @param {Address} address - * @returns {boolean} + * @param {StakeCredential} stake_credential + * @param {Ed25519KeyHash} pool_keyhash + * @returns {StakeDelegation} */ - add_change_if_needed(address: Address): boolean; + static new( + stake_credential: StakeCredential, + pool_keyhash: Ed25519KeyHash + ): StakeDelegation; /** - * @param {Address} address - * @param {OutputDatum} plutus_data * @returns {boolean} */ - add_change_if_needed_with_datum( - address: Address, - plutus_data: OutputDatum - ): boolean; + has_script_credentials(): boolean; +} +/** + */ +declare export class StakeDeregistration { + free(): void; /** - * This method will calculate the script hash data - * using the plutus datums and redeemers already present in the builder - * along with the provided cost model, and will register the calculated value - * in the builder to be used when building the tx body. - * In case there are no plutus input witnesses present - nothing will change - * You can set specific hash value using `.set_script_data_hash` - * NOTE: this function will check which language versions are used in the present scripts - * and will assert and require for a corresponding cost-model to be present in the passed map. - * Only the cost-models for the present language versions will be used in the hash calculation. - * @param {Costmdls} cost_models + * @returns {Uint8Array} */ - calc_script_data_hash(cost_models: Costmdls): void; + to_bytes(): Uint8Array; /** - * Sets the specified hash value. - * Alternatively you can use `.calc_script_data_hash` to calculate the hash automatically. - * Or use `.remove_script_data_hash` to delete the previously set value - * @param {ScriptDataHash} hash + * @param {Uint8Array} bytes + * @returns {StakeDeregistration} */ - set_script_data_hash(hash: ScriptDataHash): void; + static from_bytes(bytes: Uint8Array): StakeDeregistration; /** - * Deletes any previously set plutus data hash value. - * Use `.set_script_data_hash` or `.calc_script_data_hash` to set it. + * @returns {string} */ - remove_script_data_hash(): void; + to_hex(): string; /** - * @param {Ed25519KeyHash} key + * @param {string} hex_str + * @returns {StakeDeregistration} */ - add_required_signer(key: Ed25519KeyHash): void; + static from_hex(hex_str: string): StakeDeregistration; /** - * @returns {number} + * @returns {string} */ - full_size(): number; + to_json(): string; /** - * @returns {Uint32Array} + * @returns {StakeDeregistrationJSON} */ - output_sizes(): Uint32Array; + to_js_value(): StakeDeregistrationJSON; /** - * Returns object the body of the new transaction - * Auxiliary data itself is not included - * You can use `get_auxiliary_data` or `build_tx` - * @returns {TransactionBody} + * @param {string} json + * @returns {StakeDeregistration} */ - build(): TransactionBody; + static from_json(json: string): StakeDeregistration; /** - * Returns full Transaction object with the body and the auxiliary data - * NOTE: witness_set will contain all mint_scripts if any been added or set - * NOTE: is_valid set to true - * NOTE: Will fail in case there are any script inputs added with no corresponding witness - * @returns {Transaction} + * @returns {StakeCredential} */ - build_tx(): Transaction; + stake_credential(): StakeCredential; /** - * Similar to `.build_tx()` but will NOT fail in case there are missing script witnesses - * @returns {Transaction} + * @returns {BigNum | void} */ - build_tx_unsafe(): Transaction; + coin(): BigNum | void; /** - * warning: sum of all parts of a transaction must equal 0. You cannot just set the fee to the min value and forget about it - * warning: min_fee may be slightly larger than the actual minimum fee (ex: a few lovelaces) - * this is done to simplify the library code, but can be fixed later - * @returns {BigNum} + * @param {StakeCredential} stake_credential + * @returns {StakeDeregistration} */ - min_fee(): BigNum; + static new(stake_credential: StakeCredential): StakeDeregistration; + + /** + * @param {StakeCredential} stake_credential + * @param {BigNum} coin + * @returns {StakeDeregistration} + */ + static new_with_coin( + stake_credential: StakeCredential, + coin: BigNum + ): StakeDeregistration; + + /** + * @returns {boolean} + */ + has_script_credentials(): boolean; } /** */ -declare export class TransactionBuilderConfig { +declare export class StakeRegistration { free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {StakeRegistration} + */ + static from_bytes(bytes: Uint8Array): StakeRegistration; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {StakeRegistration} + */ + static from_hex(hex_str: string): StakeRegistration; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {StakeRegistrationJSON} + */ + to_js_value(): StakeRegistrationJSON; + + /** + * @param {string} json + * @returns {StakeRegistration} + */ + static from_json(json: string): StakeRegistration; + + /** + * @returns {StakeCredential} + */ + stake_credential(): StakeCredential; + + /** + * @returns {BigNum | void} + */ + coin(): BigNum | void; + + /** + * @param {StakeCredential} stake_credential + * @returns {StakeRegistration} + */ + static new(stake_credential: StakeCredential): StakeRegistration; + + /** + * @param {StakeCredential} stake_credential + * @param {BigNum} coin + * @returns {StakeRegistration} + */ + static new_with_coin( + stake_credential: StakeCredential, + coin: BigNum + ): StakeRegistration; } /** */ -declare export class TransactionBuilderConfigBuilder { +declare export class StakeRegistrationAndDelegation { free(): void; /** - * @returns {TransactionBuilderConfigBuilder} + * @returns {Uint8Array} */ - static new(): TransactionBuilderConfigBuilder; + to_bytes(): Uint8Array; /** - * @param {LinearFee} fee_algo - * @returns {TransactionBuilderConfigBuilder} + * @param {Uint8Array} bytes + * @returns {StakeRegistrationAndDelegation} */ - fee_algo(fee_algo: LinearFee): TransactionBuilderConfigBuilder; + static from_bytes(bytes: Uint8Array): StakeRegistrationAndDelegation; /** - * !!! DEPRECATED !!! - * Since babbage era cardano nodes use coins per byte. Use '.coins_per_utxo_byte' instead. - * @param {BigNum} coins_per_utxo_word - * @returns {TransactionBuilderConfigBuilder} + * @returns {string} */ - coins_per_utxo_word( - coins_per_utxo_word: BigNum - ): TransactionBuilderConfigBuilder; + to_hex(): string; /** - * @param {BigNum} coins_per_utxo_byte - * @returns {TransactionBuilderConfigBuilder} + * @param {string} hex_str + * @returns {StakeRegistrationAndDelegation} */ - coins_per_utxo_byte( - coins_per_utxo_byte: BigNum - ): TransactionBuilderConfigBuilder; + static from_hex(hex_str: string): StakeRegistrationAndDelegation; /** - * @param {ExUnitPrices} ex_unit_prices - * @returns {TransactionBuilderConfigBuilder} + * @returns {string} + */ + to_json(): string; + + /** + * @returns {StakeRegistrationAndDelegationJSON} + */ + to_js_value(): StakeRegistrationAndDelegationJSON; + + /** + * @param {string} json + * @returns {StakeRegistrationAndDelegation} + */ + static from_json(json: string): StakeRegistrationAndDelegation; + + /** + * @returns {StakeCredential} + */ + stake_credential(): StakeCredential; + + /** + * @returns {Ed25519KeyHash} + */ + pool_keyhash(): Ed25519KeyHash; + + /** + * @returns {BigNum} + */ + coin(): BigNum; + + /** + * @param {StakeCredential} stake_credential + * @param {Ed25519KeyHash} pool_keyhash + * @param {BigNum} coin + * @returns {StakeRegistrationAndDelegation} + */ + static new( + stake_credential: StakeCredential, + pool_keyhash: Ed25519KeyHash, + coin: BigNum + ): StakeRegistrationAndDelegation; + + /** + * @returns {boolean} + */ + has_script_credentials(): boolean; +} +/** + */ +declare export class StakeVoteRegistrationAndDelegation { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {StakeVoteRegistrationAndDelegation} + */ + static from_bytes(bytes: Uint8Array): StakeVoteRegistrationAndDelegation; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {StakeVoteRegistrationAndDelegation} + */ + static from_hex(hex_str: string): StakeVoteRegistrationAndDelegation; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {StakeVoteRegistrationAndDelegationJSON} + */ + to_js_value(): StakeVoteRegistrationAndDelegationJSON; + + /** + * @param {string} json + * @returns {StakeVoteRegistrationAndDelegation} + */ + static from_json(json: string): StakeVoteRegistrationAndDelegation; + + /** + * @returns {StakeCredential} + */ + stake_credential(): StakeCredential; + + /** + * @returns {Ed25519KeyHash} + */ + pool_keyhash(): Ed25519KeyHash; + + /** + * @returns {DRep} + */ + drep(): DRep; + + /** + * @returns {BigNum} + */ + coin(): BigNum; + + /** + * @param {StakeCredential} stake_credential + * @param {Ed25519KeyHash} pool_keyhash + * @param {DRep} drep + * @param {BigNum} coin + * @returns {StakeVoteRegistrationAndDelegation} + */ + static new( + stake_credential: StakeCredential, + pool_keyhash: Ed25519KeyHash, + drep: DRep, + coin: BigNum + ): StakeVoteRegistrationAndDelegation; + + /** + * @returns {boolean} + */ + has_script_credentials(): boolean; +} +/** + */ +declare export class Strings { + free(): void; + + /** + * @returns {Strings} + */ + static new(): Strings; + + /** + * @returns {number} + */ + len(): number; + + /** + * @param {number} index + * @returns {string} + */ + get(index: number): string; + + /** + * @param {string} elem + */ + add(elem: string): void; +} +/** + */ +declare export class TimelockExpiry { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {TimelockExpiry} + */ + static from_bytes(bytes: Uint8Array): TimelockExpiry; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {TimelockExpiry} + */ + static from_hex(hex_str: string): TimelockExpiry; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {TimelockExpiryJSON} + */ + to_js_value(): TimelockExpiryJSON; + + /** + * @param {string} json + * @returns {TimelockExpiry} + */ + static from_json(json: string): TimelockExpiry; + + /** + * @returns {number} + */ + slot(): number; + + /** + * @returns {BigNum} + */ + slot_bignum(): BigNum; + + /** + * !!! DEPRECATED !!! + * This constructor uses outdated slot number format. + * Use `.new_timelockexpiry` instead + * @param {number} slot + * @returns {TimelockExpiry} + */ + static new(slot: number): TimelockExpiry; + + /** + * @param {BigNum} slot + * @returns {TimelockExpiry} + */ + static new_timelockexpiry(slot: BigNum): TimelockExpiry; +} +/** + */ +declare export class TimelockStart { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {TimelockStart} + */ + static from_bytes(bytes: Uint8Array): TimelockStart; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {TimelockStart} + */ + static from_hex(hex_str: string): TimelockStart; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {TimelockStartJSON} + */ + to_js_value(): TimelockStartJSON; + + /** + * @param {string} json + * @returns {TimelockStart} + */ + static from_json(json: string): TimelockStart; + + /** + * !!! DEPRECATED !!! + * Returns a Slot32 (u32) value in case the underlying original BigNum (u64) value is within the limits. + * Otherwise will just raise an error. + * Use `.slot_bignum` instead + * @returns {number} + */ + slot(): number; + + /** + * @returns {BigNum} + */ + slot_bignum(): BigNum; + + /** + * !!! DEPRECATED !!! + * This constructor uses outdated slot number format. + * Use `.new_timelockstart` instead. + * @param {number} slot + * @returns {TimelockStart} + */ + static new(slot: number): TimelockStart; + + /** + * @param {BigNum} slot + * @returns {TimelockStart} + */ + static new_timelockstart(slot: BigNum): TimelockStart; +} +/** + */ +declare export class Transaction { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {Transaction} + */ + static from_bytes(bytes: Uint8Array): Transaction; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {Transaction} + */ + static from_hex(hex_str: string): Transaction; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {TransactionJSON} + */ + to_js_value(): TransactionJSON; + + /** + * @param {string} json + * @returns {Transaction} + */ + static from_json(json: string): Transaction; + + /** + * @returns {TransactionBody} + */ + body(): TransactionBody; + + /** + * @returns {TransactionWitnessSet} + */ + witness_set(): TransactionWitnessSet; + + /** + * @returns {boolean} + */ + is_valid(): boolean; + + /** + * @returns {AuxiliaryData | void} + */ + auxiliary_data(): AuxiliaryData | void; + + /** + * @param {boolean} valid + */ + set_is_valid(valid: boolean): void; + + /** + * @param {TransactionBody} body + * @param {TransactionWitnessSet} witness_set + * @param {AuxiliaryData | void} auxiliary_data + * @returns {Transaction} + */ + static new( + body: TransactionBody, + witness_set: TransactionWitnessSet, + auxiliary_data?: AuxiliaryData + ): Transaction; +} +/** + */ +declare export class TransactionBatch { + free(): void; + + /** + * @returns {number} + */ + len(): number; + + /** + * @param {number} index + * @returns {Transaction} + */ + get(index: number): Transaction; +} +/** + */ +declare export class TransactionBatchList { + free(): void; + + /** + * @returns {number} + */ + len(): number; + + /** + * @param {number} index + * @returns {TransactionBatch} + */ + get(index: number): TransactionBatch; +} +/** + */ +declare export class TransactionBodies { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {TransactionBodies} + */ + static from_bytes(bytes: Uint8Array): TransactionBodies; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {TransactionBodies} + */ + static from_hex(hex_str: string): TransactionBodies; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {TransactionBodiesJSON} + */ + to_js_value(): TransactionBodiesJSON; + + /** + * @param {string} json + * @returns {TransactionBodies} + */ + static from_json(json: string): TransactionBodies; + + /** + * @returns {TransactionBodies} + */ + static new(): TransactionBodies; + + /** + * @returns {number} + */ + len(): number; + + /** + * @param {number} index + * @returns {TransactionBody} + */ + get(index: number): TransactionBody; + + /** + * @param {TransactionBody} elem + */ + add(elem: TransactionBody): void; +} +/** + */ +declare export class TransactionBody { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {TransactionBody} + */ + static from_bytes(bytes: Uint8Array): TransactionBody; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {TransactionBody} + */ + static from_hex(hex_str: string): TransactionBody; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {TransactionBodyJSON} + */ + to_js_value(): TransactionBodyJSON; + + /** + * @param {string} json + * @returns {TransactionBody} + */ + static from_json(json: string): TransactionBody; + + /** + * @returns {TransactionInputs} + */ + inputs(): TransactionInputs; + + /** + * @returns {TransactionOutputs} + */ + outputs(): TransactionOutputs; + + /** + * @returns {BigNum} + */ + fee(): BigNum; + + /** + * !!! DEPRECATED !!! + * Returns a Slot32 (u32) value in case the underlying original BigNum (u64) value is within the limits. + * Otherwise will just raise an error. + * @returns {number | void} + */ + ttl(): number | void; + + /** + * @returns {BigNum | void} + */ + ttl_bignum(): BigNum | void; + + /** + * @param {BigNum} ttl + */ + set_ttl(ttl: BigNum): void; + + /** + */ + remove_ttl(): void; + + /** + * @param {Certificates} certs + */ + set_certs(certs: Certificates): void; + + /** + * @returns {Certificates | void} + */ + certs(): Certificates | void; + + /** + * @param {Withdrawals} withdrawals + */ + set_withdrawals(withdrawals: Withdrawals): void; + + /** + * @returns {Withdrawals | void} + */ + withdrawals(): Withdrawals | void; + + /** + * @param {Update} update + */ + set_update(update: Update): void; + + /** + * @returns {Update | void} + */ + update(): Update | void; + + /** + * @param {AuxiliaryDataHash} auxiliary_data_hash + */ + set_auxiliary_data_hash(auxiliary_data_hash: AuxiliaryDataHash): void; + + /** + * @returns {AuxiliaryDataHash | void} + */ + auxiliary_data_hash(): AuxiliaryDataHash | void; + + /** + * !!! DEPRECATED !!! + * Uses outdated slot number format. + * @param {number} validity_start_interval + */ + set_validity_start_interval(validity_start_interval: number): void; + + /** + * @param {BigNum} validity_start_interval + */ + set_validity_start_interval_bignum(validity_start_interval: BigNum): void; + + /** + * @returns {BigNum | void} + */ + validity_start_interval_bignum(): BigNum | void; + + /** + * !!! DEPRECATED !!! + * Returns a Option (u32) value in case the underlying original Option (u64) value is within the limits. + * Otherwise will just raise an error. + * Use `.validity_start_interval_bignum` instead. + * @returns {number | void} + */ + validity_start_interval(): number | void; + + /** + * @param {Mint} mint + */ + set_mint(mint: Mint): void; + + /** + * @returns {Mint | void} + */ + mint(): Mint | void; + + /** + * This function returns the mint value of the transaction + * Use `.mint()` instead. + * @returns {Mint | void} + */ + multiassets(): Mint | void; + + /** + * @param {TransactionInputs} reference_inputs + */ + set_reference_inputs(reference_inputs: TransactionInputs): void; + + /** + * @returns {TransactionInputs | void} + */ + reference_inputs(): TransactionInputs | void; + + /** + * @param {ScriptDataHash} script_data_hash + */ + set_script_data_hash(script_data_hash: ScriptDataHash): void; + + /** + * @returns {ScriptDataHash | void} + */ + script_data_hash(): ScriptDataHash | void; + + /** + * @param {TransactionInputs} collateral + */ + set_collateral(collateral: TransactionInputs): void; + + /** + * @returns {TransactionInputs | void} + */ + collateral(): TransactionInputs | void; + + /** + * @param {Ed25519KeyHashes} required_signers + */ + set_required_signers(required_signers: Ed25519KeyHashes): void; + + /** + * @returns {Ed25519KeyHashes | void} + */ + required_signers(): Ed25519KeyHashes | void; + + /** + * @param {NetworkId} network_id + */ + set_network_id(network_id: NetworkId): void; + + /** + * @returns {NetworkId | void} + */ + network_id(): NetworkId | void; + + /** + * @param {TransactionOutput} collateral_return + */ + set_collateral_return(collateral_return: TransactionOutput): void; + + /** + * @returns {TransactionOutput | void} + */ + collateral_return(): TransactionOutput | void; + + /** + * @param {BigNum} total_collateral + */ + set_total_collateral(total_collateral: BigNum): void; + + /** + * @returns {BigNum | void} + */ + total_collateral(): BigNum | void; + + /** + * @param {VotingProcedures} voting_procedures + */ + set_voting_procedures(voting_procedures: VotingProcedures): void; + + /** + * @returns {VotingProcedures | void} + */ + voting_procedures(): VotingProcedures | void; + + /** + * !!! DEPRECATED !!! + * This constructor uses outdated slot number format for the ttl value. + * Use `.new_tx_body` and then `.set_ttl` instead + * @param {TransactionInputs} inputs + * @param {TransactionOutputs} outputs + * @param {BigNum} fee + * @param {number | void} ttl + * @returns {TransactionBody} + */ + static new( + inputs: TransactionInputs, + outputs: TransactionOutputs, + fee: BigNum, + ttl?: number + ): TransactionBody; + + /** + * Returns a new TransactionBody. + * In the new version of "new" we removed optional ttl for support it by wasm_bingen. + * Your can use "set_ttl" and "remove_ttl" to set a new value for ttl or set it as None. + * @param {TransactionInputs} inputs + * @param {TransactionOutputs} outputs + * @param {BigNum} fee + * @returns {TransactionBody} + */ + static new_tx_body( + inputs: TransactionInputs, + outputs: TransactionOutputs, + fee: BigNum + ): TransactionBody; +} +/** + */ +declare export class TransactionBuilder { + free(): void; + + /** + * This automatically selects and adds inputs from {inputs} consisting of just enough to cover + * the outputs that have already been added. + * This should be called after adding all certs/outputs/etc and will be an error otherwise. + * Uses CIP2: https://github.com/cardano-foundation/CIPs/blob/master/CIP-0002/CIP-0002.md + * Adding a change output must be called after via TransactionBuilder::add_change_if_needed() + * This function, diverging from CIP2, takes into account fees and will attempt to add additional + * inputs to cover the minimum fees. This does not, however, set the txbuilder's fee. + * @param {TransactionUnspentOutputs} inputs + * @param {number} strategy + */ + add_inputs_from(inputs: TransactionUnspentOutputs, strategy: number): void; + + /** + * @param {TxInputsBuilder} inputs + */ + set_inputs(inputs: TxInputsBuilder): void; + + /** + * @param {TxInputsBuilder} collateral + */ + set_collateral(collateral: TxInputsBuilder): void; + + /** + * @param {TransactionOutput} collateral_return + */ + set_collateral_return(collateral_return: TransactionOutput): void; + + /** + * This function will set the collateral-return value and then auto-calculate and assign + * the total collateral coin value. Will raise an error in case no collateral inputs are set + * or in case the total collateral value will have any assets in it except coin. + * @param {TransactionOutput} collateral_return + */ + set_collateral_return_and_total(collateral_return: TransactionOutput): void; + + /** + * @param {BigNum} total_collateral + */ + set_total_collateral(total_collateral: BigNum): void; + + /** + * This function will set the total-collateral coin and then auto-calculate and assign + * the collateral return value. Will raise an error in case no collateral inputs are set. + * The specified address will be the received of the collateral return + * @param {BigNum} total_collateral + * @param {Address} return_address + */ + set_total_collateral_and_return( + total_collateral: BigNum, + return_address: Address + ): void; + + /** + * @param {TransactionInput} reference_input + */ + add_reference_input(reference_input: TransactionInput): void; + + /** + * We have to know what kind of inputs these are to know what kind of mock witnesses to create since + * 1) mock witnesses have different lengths depending on the type which changes the expecting fee + * 2) Witnesses are a set so we need to get rid of duplicates to avoid over-estimating the fee + * @param {Ed25519KeyHash} hash + * @param {TransactionInput} input + * @param {Value} amount + */ + add_key_input( + hash: Ed25519KeyHash, + input: TransactionInput, + amount: Value + ): void; + + /** + * This method adds the input to the builder BUT leaves a missing spot for the witness native script + * + * After adding the input with this method, use `.add_required_native_input_scripts` + * and `.add_required_plutus_input_scripts` to add the witness scripts + * + * Or instead use `.add_native_script_input` and `.add_plutus_script_input` + * to add inputs right along with the script, instead of the script hash + * @param {ScriptHash} hash + * @param {TransactionInput} input + * @param {Value} amount + */ + add_script_input( + hash: ScriptHash, + input: TransactionInput, + amount: Value + ): void; + + /** + * This method will add the input to the builder and also register the required native script witness + * @param {NativeScript} script + * @param {TransactionInput} input + * @param {Value} amount + */ + add_native_script_input( + script: NativeScript, + input: TransactionInput, + amount: Value + ): void; + + /** + * This method will add the input to the builder and also register the required plutus witness + * @param {PlutusWitness} witness + * @param {TransactionInput} input + * @param {Value} amount + */ + add_plutus_script_input( + witness: PlutusWitness, + input: TransactionInput, + amount: Value + ): void; + + /** + * @param {ByronAddress} hash + * @param {TransactionInput} input + * @param {Value} amount + */ + add_bootstrap_input( + hash: ByronAddress, + input: TransactionInput, + amount: Value + ): void; + + /** + * Note that for script inputs this method will use underlying generic `.add_script_input` + * which leaves a required empty spot for the script witness (or witnesses in case of Plutus). + * You can use `.add_native_script_input` or `.add_plutus_script_input` directly to register the input along with the witness. + * @param {Address} address + * @param {TransactionInput} input + * @param {Value} amount + */ + add_input(address: Address, input: TransactionInput, amount: Value): void; + + /** + * Returns the number of still missing input scripts (either native or plutus) + * Use `.add_required_native_input_scripts` or `.add_required_plutus_input_scripts` to add the missing scripts + * @returns {number} + */ + count_missing_input_scripts(): number; + + /** + * Try adding the specified scripts as witnesses for ALREADY ADDED script inputs + * Any scripts that don't match any of the previously added inputs will be ignored + * Returns the number of remaining required missing witness scripts + * Use `.count_missing_input_scripts` to find the number of still missing scripts + * @param {NativeScripts} scripts + * @returns {number} + */ + add_required_native_input_scripts(scripts: NativeScripts): number; + + /** + * Try adding the specified scripts as witnesses for ALREADY ADDED script inputs + * Any scripts that don't match any of the previously added inputs will be ignored + * Returns the number of remaining required missing witness scripts + * Use `.count_missing_input_scripts` to find the number of still missing scripts + * @param {PlutusWitnesses} scripts + * @returns {number} + */ + add_required_plutus_input_scripts(scripts: PlutusWitnesses): number; + + /** + * Returns a copy of the current script input witness scripts in the builder + * @returns {NativeScripts | void} + */ + get_native_input_scripts(): NativeScripts | void; + + /** + * Returns a copy of the current plutus input witness scripts in the builder. + * NOTE: each plutus witness will be cloned with a specific corresponding input index + * @returns {PlutusWitnesses | void} + */ + get_plutus_input_scripts(): PlutusWitnesses | void; + + /** + * calculates how much the fee would increase if you added a given output + * @param {Address} address + * @param {TransactionInput} input + * @param {Value} amount + * @returns {BigNum} + */ + fee_for_input( + address: Address, + input: TransactionInput, + amount: Value + ): BigNum; + + /** + * Add explicit output via a TransactionOutput object + * @param {TransactionOutput} output + */ + add_output(output: TransactionOutput): void; + + /** + * calculates how much the fee would increase if you added a given output + * @param {TransactionOutput} output + * @returns {BigNum} + */ + fee_for_output(output: TransactionOutput): BigNum; + + /** + * @param {BigNum} fee + */ + set_fee(fee: BigNum): void; + + /** + * !!! DEPRECATED !!! + * Set ttl value. + * @param {number} ttl + */ + set_ttl(ttl: number): void; + + /** + * @param {BigNum} ttl + */ + set_ttl_bignum(ttl: BigNum): void; + + /** + * !!! DEPRECATED !!! + * Uses outdated slot number format. + * @param {number} validity_start_interval + */ + set_validity_start_interval(validity_start_interval: number): void; + + /** + * @param {BigNum} validity_start_interval + */ + set_validity_start_interval_bignum(validity_start_interval: BigNum): void; + + /** + * !!! DEPRECATED !!! + * Can emit error if add a cert with script credential. + * Use set_certs_builder instead. + * @param {Certificates} certs + */ + set_certs(certs: Certificates): void; + + /** + * @param {CertificatesBuilder} certs + */ + set_certs_builder(certs: CertificatesBuilder): void; + + /** + * !!! DEPRECATED !!! + * Can emit error if add a withdrawal with script credential. + * Use set_withdrawals_builder instead. + * @param {Withdrawals} withdrawals + */ + set_withdrawals(withdrawals: Withdrawals): void; + + /** + * @param {WithdrawalsBuilder} withdrawals + */ + set_withdrawals_builder(withdrawals: WithdrawalsBuilder): void; + + /** + * @param {VotingBuilder} voting_builder + */ + set_voting_builder(voting_builder: VotingBuilder): void; + + /** + * @param {VotingProposalBuilder} voting_proposal_builder + */ + set_voting_proposal_builder( + voting_proposal_builder: VotingProposalBuilder + ): void; + + /** + * @returns {AuxiliaryData | void} + */ + get_auxiliary_data(): AuxiliaryData | void; + + /** + * Set explicit auxiliary data via an AuxiliaryData object + * It might contain some metadata plus native or Plutus scripts + * @param {AuxiliaryData} auxiliary_data + */ + set_auxiliary_data(auxiliary_data: AuxiliaryData): void; + + /** + * Set metadata using a GeneralTransactionMetadata object + * It will be set to the existing or new auxiliary data in this builder + * @param {GeneralTransactionMetadata} metadata + */ + set_metadata(metadata: GeneralTransactionMetadata): void; + + /** + * Add a single metadatum using TransactionMetadatumLabel and TransactionMetadatum objects + * It will be securely added to existing or new metadata in this builder + * @param {BigNum} key + * @param {TransactionMetadatum} val + */ + add_metadatum(key: BigNum, val: TransactionMetadatum): void; + + /** + * Add a single JSON metadatum using a TransactionMetadatumLabel and a String + * It will be securely added to existing or new metadata in this builder + * @param {BigNum} key + * @param {string} val + */ + add_json_metadatum(key: BigNum, val: string): void; + + /** + * Add a single JSON metadatum using a TransactionMetadatumLabel, a String, and a MetadataJsonSchema object + * It will be securely added to existing or new metadata in this builder + * @param {BigNum} key + * @param {string} val + * @param {number} schema + */ + add_json_metadatum_with_schema( + key: BigNum, + val: string, + schema: number + ): void; + + /** + * @param {MintBuilder} mint_builder + */ + set_mint_builder(mint_builder: MintBuilder): void; + + /** + * @returns {MintBuilder | void} + */ + get_mint_builder(): MintBuilder | void; + + /** + * !!! DEPRECATED !!! + * Mints are defining by MintBuilder now. + * Use `.set_mint_builder()` and `MintBuilder` instead. + * Set explicit Mint object and the required witnesses to this builder + * it will replace any previously existing mint and mint scripts + * NOTE! Error will be returned in case a mint policy does not have a matching script + * @param {Mint} mint + * @param {NativeScripts} mint_scripts + */ + set_mint(mint: Mint, mint_scripts: NativeScripts): void; + + /** + * !!! DEPRECATED !!! + * Mints are defining by MintBuilder now. + * Use `.get_mint_builder()` and `.build()` instead. + * Returns a copy of the current mint state in the builder + * @returns {Mint | void} + */ + get_mint(): Mint | void; + + /** + * Returns a copy of the current mint witness scripts in the builder + * @returns {NativeScripts | void} + */ + get_mint_scripts(): NativeScripts | void; + + /** + * !!! DEPRECATED !!! + * Mints are defining by MintBuilder now. + * Use `.set_mint_builder()` and `MintBuilder` instead. + * Add a mint entry to this builder using a PolicyID and MintAssets object + * It will be securely added to existing or new Mint in this builder + * It will replace any existing mint assets with the same PolicyID + * @param {NativeScript} policy_script + * @param {MintAssets} mint_assets + */ + set_mint_asset(policy_script: NativeScript, mint_assets: MintAssets): void; + + /** + * !!! DEPRECATED !!! + * Mints are defining by MintBuilder now. + * Use `.set_mint_builder()` and `MintBuilder` instead. + * Add a mint entry to this builder using a PolicyID, AssetName, and Int object for amount + * It will be securely added to existing or new Mint in this builder + * It will replace any previous existing amount same PolicyID and AssetName + * @param {NativeScript} policy_script + * @param {AssetName} asset_name + * @param {Int} amount + */ + add_mint_asset( + policy_script: NativeScript, + asset_name: AssetName, + amount: Int + ): void; + + /** + * Add a mint entry together with an output to this builder + * Using a PolicyID, AssetName, Int for amount, Address, and Coin (BigNum) objects + * The asset will be securely added to existing or new Mint in this builder + * A new output will be added with the specified Address, the Coin value, and the minted asset + * @param {NativeScript} policy_script + * @param {AssetName} asset_name + * @param {Int} amount + * @param {TransactionOutputAmountBuilder} output_builder + * @param {BigNum} output_coin + */ + add_mint_asset_and_output( + policy_script: NativeScript, + asset_name: AssetName, + amount: Int, + output_builder: TransactionOutputAmountBuilder, + output_coin: BigNum + ): void; + + /** + * Add a mint entry together with an output to this builder + * Using a PolicyID, AssetName, Int for amount, and Address objects + * The asset will be securely added to existing or new Mint in this builder + * A new output will be added with the specified Address and the minted asset + * The output will be set to contain the minimum required amount of Coin + * @param {NativeScript} policy_script + * @param {AssetName} asset_name + * @param {Int} amount + * @param {TransactionOutputAmountBuilder} output_builder + */ + add_mint_asset_and_output_min_required_coin( + policy_script: NativeScript, + asset_name: AssetName, + amount: Int, + output_builder: TransactionOutputAmountBuilder + ): void; + + /** + * @param {TransactionBuilderConfig} cfg + * @returns {TransactionBuilder} + */ + static new(cfg: TransactionBuilderConfig): TransactionBuilder; + + /** + * @returns {TransactionInputs} + */ + get_reference_inputs(): TransactionInputs; + + /** + * does not include refunds or withdrawals + * @returns {Value} + */ + get_explicit_input(): Value; + + /** + * withdrawals and refunds + * @returns {Value} + */ + get_implicit_input(): Value; + + /** + * Return explicit input plus implicit input plus mint + * @returns {Value} + */ + get_total_input(): Value; + + /** + * Return explicit output plus deposit plus burn + * @returns {Value} + */ + get_total_output(): Value; + + /** + * does not include fee + * @returns {Value} + */ + get_explicit_output(): Value; + + /** + * @returns {BigNum} + */ + get_deposit(): BigNum; + + /** + * @returns {BigNum | void} + */ + get_fee_if_set(): BigNum | void; + + /** + * Warning: this function will mutate the /fee/ field + * Make sure to call this function last after setting all other tx-body properties + * Editing inputs, outputs, mint, etc. after change been calculated + * might cause a mismatch in calculated fee versus the required fee + * @param {Address} address + * @returns {boolean} + */ + add_change_if_needed(address: Address): boolean; + + /** + * @param {Address} address + * @param {OutputDatum} plutus_data + * @returns {boolean} + */ + add_change_if_needed_with_datum( + address: Address, + plutus_data: OutputDatum + ): boolean; + + /** + * This method will calculate the script hash data + * using the plutus datums and redeemers already present in the builder + * along with the provided cost model, and will register the calculated value + * in the builder to be used when building the tx body. + * In case there are no plutus input witnesses present - nothing will change + * You can set specific hash value using `.set_script_data_hash` + * NOTE: this function will check which language versions are used in the present scripts + * and will assert and require for a corresponding cost-model to be present in the passed map. + * Only the cost-models for the present language versions will be used in the hash calculation. + * @param {Costmdls} cost_models + */ + calc_script_data_hash(cost_models: Costmdls): void; + + /** + * Sets the specified hash value. + * Alternatively you can use `.calc_script_data_hash` to calculate the hash automatically. + * Or use `.remove_script_data_hash` to delete the previously set value + * @param {ScriptDataHash} hash + */ + set_script_data_hash(hash: ScriptDataHash): void; + + /** + * Deletes any previously set plutus data hash value. + * Use `.set_script_data_hash` or `.calc_script_data_hash` to set it. + */ + remove_script_data_hash(): void; + + /** + * @param {Ed25519KeyHash} key + */ + add_required_signer(key: Ed25519KeyHash): void; + + /** + * @returns {number} + */ + full_size(): number; + + /** + * @returns {Uint32Array} + */ + output_sizes(): Uint32Array; + + /** + * Returns object the body of the new transaction + * Auxiliary data itself is not included + * You can use `get_auxiliary_data` or `build_tx` + * @returns {TransactionBody} + */ + build(): TransactionBody; + + /** + * Returns full Transaction object with the body and the auxiliary data + * NOTE: witness_set will contain all mint_scripts if any been added or set + * NOTE: is_valid set to true + * NOTE: Will fail in case there are any script inputs added with no corresponding witness + * @returns {Transaction} + */ + build_tx(): Transaction; + + /** + * Similar to `.build_tx()` but will NOT fail in case there are missing script witnesses + * @returns {Transaction} + */ + build_tx_unsafe(): Transaction; + + /** + * warning: sum of all parts of a transaction must equal 0. You cannot just set the fee to the min value and forget about it + * warning: min_fee may be slightly larger than the actual minimum fee (ex: a few lovelaces) + * this is done to simplify the library code, but can be fixed later + * @returns {BigNum} + */ + min_fee(): BigNum; +} +/** + */ +declare export class TransactionBuilderConfig { + free(): void; +} +/** + */ +declare export class TransactionBuilderConfigBuilder { + free(): void; + + /** + * @returns {TransactionBuilderConfigBuilder} + */ + static new(): TransactionBuilderConfigBuilder; + + /** + * @param {LinearFee} fee_algo + * @returns {TransactionBuilderConfigBuilder} + */ + fee_algo(fee_algo: LinearFee): TransactionBuilderConfigBuilder; + + /** + * !!! DEPRECATED !!! + * Since babbage era cardano nodes use coins per byte. Use '.coins_per_utxo_byte' instead. + * @param {BigNum} coins_per_utxo_word + * @returns {TransactionBuilderConfigBuilder} + */ + coins_per_utxo_word( + coins_per_utxo_word: BigNum + ): TransactionBuilderConfigBuilder; + + /** + * @param {BigNum} coins_per_utxo_byte + * @returns {TransactionBuilderConfigBuilder} + */ + coins_per_utxo_byte( + coins_per_utxo_byte: BigNum + ): TransactionBuilderConfigBuilder; + + /** + * @param {ExUnitPrices} ex_unit_prices + * @returns {TransactionBuilderConfigBuilder} + */ + ex_unit_prices(ex_unit_prices: ExUnitPrices): TransactionBuilderConfigBuilder; + + /** + * @param {BigNum} pool_deposit + * @returns {TransactionBuilderConfigBuilder} + */ + pool_deposit(pool_deposit: BigNum): TransactionBuilderConfigBuilder; + + /** + * @param {BigNum} key_deposit + * @returns {TransactionBuilderConfigBuilder} + */ + key_deposit(key_deposit: BigNum): TransactionBuilderConfigBuilder; + + /** + * @param {number} max_value_size + * @returns {TransactionBuilderConfigBuilder} + */ + max_value_size(max_value_size: number): TransactionBuilderConfigBuilder; + + /** + * @param {number} max_tx_size + * @returns {TransactionBuilderConfigBuilder} + */ + max_tx_size(max_tx_size: number): TransactionBuilderConfigBuilder; + + /** + * @param {boolean} prefer_pure_change + * @returns {TransactionBuilderConfigBuilder} + */ + prefer_pure_change( + prefer_pure_change: boolean + ): TransactionBuilderConfigBuilder; + + /** + * @param {BigNum} voting_proposal_deposit + * @returns {TransactionBuilderConfigBuilder} + */ + voting_proposal_deposit( + voting_proposal_deposit: BigNum + ): TransactionBuilderConfigBuilder; + + /** + * @returns {TransactionBuilderConfig} + */ + build(): TransactionBuilderConfig; +} +/** + */ +declare export class TransactionHash { + free(): void; + + /** + * @param {Uint8Array} bytes + * @returns {TransactionHash} + */ + static from_bytes(bytes: Uint8Array): TransactionHash; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {string} prefix + * @returns {string} + */ + to_bech32(prefix: string): string; + + /** + * @param {string} bech_str + * @returns {TransactionHash} + */ + static from_bech32(bech_str: string): TransactionHash; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex + * @returns {TransactionHash} + */ + static from_hex(hex: string): TransactionHash; +} +/** + */ +declare export class TransactionInput { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {TransactionInput} + */ + static from_bytes(bytes: Uint8Array): TransactionInput; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {TransactionInput} + */ + static from_hex(hex_str: string): TransactionInput; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {TransactionInputJSON} + */ + to_js_value(): TransactionInputJSON; + + /** + * @param {string} json + * @returns {TransactionInput} + */ + static from_json(json: string): TransactionInput; + + /** + * @returns {TransactionHash} + */ + transaction_id(): TransactionHash; + + /** + * @returns {number} + */ + index(): number; + + /** + * @param {TransactionHash} transaction_id + * @param {number} index + * @returns {TransactionInput} + */ + static new(transaction_id: TransactionHash, index: number): TransactionInput; +} +/** + */ +declare export class TransactionInputs { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {TransactionInputs} + */ + static from_bytes(bytes: Uint8Array): TransactionInputs; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {TransactionInputs} + */ + static from_hex(hex_str: string): TransactionInputs; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {TransactionInputsJSON} + */ + to_js_value(): TransactionInputsJSON; + + /** + * @param {string} json + * @returns {TransactionInputs} + */ + static from_json(json: string): TransactionInputs; + + /** + * @returns {TransactionInputs} + */ + static new(): TransactionInputs; + + /** + * @returns {number} + */ + len(): number; + + /** + * @param {number} index + * @returns {TransactionInput} + */ + get(index: number): TransactionInput; + + /** + * @param {TransactionInput} elem + */ + add(elem: TransactionInput): void; + + /** + * @returns {TransactionInputs | void} + */ + to_option(): TransactionInputs | void; +} +/** + */ +declare export class TransactionMetadatum { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {TransactionMetadatum} + */ + static from_bytes(bytes: Uint8Array): TransactionMetadatum; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {TransactionMetadatum} + */ + static from_hex(hex_str: string): TransactionMetadatum; + + /** + * @param {MetadataMap} map + * @returns {TransactionMetadatum} + */ + static new_map(map: MetadataMap): TransactionMetadatum; + + /** + * @param {MetadataList} list + * @returns {TransactionMetadatum} + */ + static new_list(list: MetadataList): TransactionMetadatum; + + /** + * @param {Int} int + * @returns {TransactionMetadatum} + */ + static new_int(int: Int): TransactionMetadatum; + + /** + * @param {Uint8Array} bytes + * @returns {TransactionMetadatum} + */ + static new_bytes(bytes: Uint8Array): TransactionMetadatum; + + /** + * @param {string} text + * @returns {TransactionMetadatum} + */ + static new_text(text: string): TransactionMetadatum; + + /** + * @returns {number} + */ + kind(): number; + + /** + * @returns {MetadataMap} + */ + as_map(): MetadataMap; + + /** + * @returns {MetadataList} + */ + as_list(): MetadataList; + + /** + * @returns {Int} + */ + as_int(): Int; + + /** + * @returns {Uint8Array} + */ + as_bytes(): Uint8Array; + + /** + * @returns {string} + */ + as_text(): string; +} +/** + */ +declare export class TransactionMetadatumLabels { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {TransactionMetadatumLabels} + */ + static from_bytes(bytes: Uint8Array): TransactionMetadatumLabels; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {TransactionMetadatumLabels} + */ + static from_hex(hex_str: string): TransactionMetadatumLabels; + + /** + * @returns {TransactionMetadatumLabels} + */ + static new(): TransactionMetadatumLabels; + + /** + * @returns {number} + */ + len(): number; + + /** + * @param {number} index + * @returns {BigNum} + */ + get(index: number): BigNum; + + /** + * @param {BigNum} elem + */ + add(elem: BigNum): void; +} +/** + */ +declare export class TransactionOutput { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {TransactionOutput} + */ + static from_bytes(bytes: Uint8Array): TransactionOutput; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {TransactionOutput} + */ + static from_hex(hex_str: string): TransactionOutput; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {TransactionOutputJSON} + */ + to_js_value(): TransactionOutputJSON; + + /** + * @param {string} json + * @returns {TransactionOutput} + */ + static from_json(json: string): TransactionOutput; + + /** + * @returns {Address} + */ + address(): Address; + + /** + * @returns {Value} + */ + amount(): Value; + + /** + * @returns {DataHash | void} + */ + data_hash(): DataHash | void; + + /** + * @returns {PlutusData | void} + */ + plutus_data(): PlutusData | void; + + /** + * @returns {ScriptRef | void} + */ + script_ref(): ScriptRef | void; + + /** + * @param {ScriptRef} script_ref + */ + set_script_ref(script_ref: ScriptRef): void; + + /** + * @param {PlutusData} data + */ + set_plutus_data(data: PlutusData): void; + + /** + * @param {DataHash} data_hash + */ + set_data_hash(data_hash: DataHash): void; + + /** + * @returns {boolean} + */ + has_plutus_data(): boolean; + + /** + * @returns {boolean} + */ + has_data_hash(): boolean; + + /** + * @returns {boolean} + */ + has_script_ref(): boolean; + + /** + * @param {Address} address + * @param {Value} amount + * @returns {TransactionOutput} + */ + static new(address: Address, amount: Value): TransactionOutput; + + /** + * @returns {number | void} + */ + serialization_format(): number | void; +} +/** + */ +declare export class TransactionOutputAmountBuilder { + free(): void; + + /** + * @param {Value} amount + * @returns {TransactionOutputAmountBuilder} + */ + with_value(amount: Value): TransactionOutputAmountBuilder; + + /** + * @param {BigNum} coin + * @returns {TransactionOutputAmountBuilder} + */ + with_coin(coin: BigNum): TransactionOutputAmountBuilder; + + /** + * @param {BigNum} coin + * @param {MultiAsset} multiasset + * @returns {TransactionOutputAmountBuilder} + */ + with_coin_and_asset( + coin: BigNum, + multiasset: MultiAsset + ): TransactionOutputAmountBuilder; + + /** + * !!! DEPRECATED !!! + * Since babbage era cardano nodes use coins per byte. Use '.with_asset_and_min_required_coin_by_utxo_cost' instead. + * @param {MultiAsset} multiasset + * @param {BigNum} coins_per_utxo_word + * @returns {TransactionOutputAmountBuilder} + */ + with_asset_and_min_required_coin( + multiasset: MultiAsset, + coins_per_utxo_word: BigNum + ): TransactionOutputAmountBuilder; + + /** + * @param {MultiAsset} multiasset + * @param {DataCost} data_cost + * @returns {TransactionOutputAmountBuilder} + */ + with_asset_and_min_required_coin_by_utxo_cost( + multiasset: MultiAsset, + data_cost: DataCost + ): TransactionOutputAmountBuilder; + + /** + * @returns {TransactionOutput} + */ + build(): TransactionOutput; +} +/** + * We introduce a builder-pattern format for creating transaction outputs + * This is because: + * 1. Some fields (i.e. data hash) are optional, and we can't easily expose Option<> in WASM + * 2. Some fields like amounts have many ways it could be set (some depending on other field values being known) + * 3. Easier to adapt as the output format gets more complicated in future Cardano releases + */ +declare export class TransactionOutputBuilder { + free(): void; + + /** + * @returns {TransactionOutputBuilder} + */ + static new(): TransactionOutputBuilder; + + /** + * @param {Address} address + * @returns {TransactionOutputBuilder} + */ + with_address(address: Address): TransactionOutputBuilder; + + /** + * @param {DataHash} data_hash + * @returns {TransactionOutputBuilder} + */ + with_data_hash(data_hash: DataHash): TransactionOutputBuilder; + + /** + * @param {PlutusData} data + * @returns {TransactionOutputBuilder} + */ + with_plutus_data(data: PlutusData): TransactionOutputBuilder; + + /** + * @param {ScriptRef} script_ref + * @returns {TransactionOutputBuilder} + */ + with_script_ref(script_ref: ScriptRef): TransactionOutputBuilder; + + /** + * @returns {TransactionOutputAmountBuilder} + */ + next(): TransactionOutputAmountBuilder; +} +/** + */ +declare export class TransactionOutputs { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {TransactionOutputs} + */ + static from_bytes(bytes: Uint8Array): TransactionOutputs; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {TransactionOutputs} + */ + static from_hex(hex_str: string): TransactionOutputs; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {TransactionOutputsJSON} + */ + to_js_value(): TransactionOutputsJSON; + + /** + * @param {string} json + * @returns {TransactionOutputs} + */ + static from_json(json: string): TransactionOutputs; + + /** + * @returns {TransactionOutputs} + */ + static new(): TransactionOutputs; + + /** + * @returns {number} + */ + len(): number; + + /** + * @param {number} index + * @returns {TransactionOutput} + */ + get(index: number): TransactionOutput; + + /** + * @param {TransactionOutput} elem + */ + add(elem: TransactionOutput): void; +} +/** + */ +declare export class TransactionUnspentOutput { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {TransactionUnspentOutput} + */ + static from_bytes(bytes: Uint8Array): TransactionUnspentOutput; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {TransactionUnspentOutput} */ - ex_unit_prices(ex_unit_prices: ExUnitPrices): TransactionBuilderConfigBuilder; + static from_hex(hex_str: string): TransactionUnspentOutput; /** - * @param {BigNum} pool_deposit - * @returns {TransactionBuilderConfigBuilder} + * @returns {string} */ - pool_deposit(pool_deposit: BigNum): TransactionBuilderConfigBuilder; + to_json(): string; /** - * @param {BigNum} key_deposit - * @returns {TransactionBuilderConfigBuilder} + * @returns {TransactionUnspentOutputJSON} */ - key_deposit(key_deposit: BigNum): TransactionBuilderConfigBuilder; + to_js_value(): TransactionUnspentOutputJSON; /** - * @param {number} max_value_size - * @returns {TransactionBuilderConfigBuilder} + * @param {string} json + * @returns {TransactionUnspentOutput} */ - max_value_size(max_value_size: number): TransactionBuilderConfigBuilder; + static from_json(json: string): TransactionUnspentOutput; /** - * @param {number} max_tx_size - * @returns {TransactionBuilderConfigBuilder} + * @param {TransactionInput} input + * @param {TransactionOutput} output + * @returns {TransactionUnspentOutput} */ - max_tx_size(max_tx_size: number): TransactionBuilderConfigBuilder; + static new( + input: TransactionInput, + output: TransactionOutput + ): TransactionUnspentOutput; /** - * @param {boolean} prefer_pure_change - * @returns {TransactionBuilderConfigBuilder} + * @returns {TransactionInput} */ - prefer_pure_change( - prefer_pure_change: boolean - ): TransactionBuilderConfigBuilder; + input(): TransactionInput; /** - * @returns {TransactionBuilderConfig} + * @returns {TransactionOutput} */ - build(): TransactionBuilderConfig; + output(): TransactionOutput; } /** */ -declare export class TransactionHash { +declare export class TransactionUnspentOutputs { free(): void; /** - * @param {Uint8Array} bytes - * @returns {TransactionHash} + * @returns {string} */ - static from_bytes(bytes: Uint8Array): TransactionHash; + to_json(): string; /** - * @returns {Uint8Array} + * @returns {TransactionUnspentOutputsJSON} */ - to_bytes(): Uint8Array; + to_js_value(): TransactionUnspentOutputsJSON; /** - * @param {string} prefix - * @returns {string} + * @param {string} json + * @returns {TransactionUnspentOutputs} */ - to_bech32(prefix: string): string; + static from_json(json: string): TransactionUnspentOutputs; /** - * @param {string} bech_str - * @returns {TransactionHash} + * @returns {TransactionUnspentOutputs} */ - static from_bech32(bech_str: string): TransactionHash; + static new(): TransactionUnspentOutputs; /** - * @returns {string} + * @returns {number} */ - to_hex(): string; + len(): number; /** - * @param {string} hex - * @returns {TransactionHash} + * @param {number} index + * @returns {TransactionUnspentOutput} */ - static from_hex(hex: string): TransactionHash; + get(index: number): TransactionUnspentOutput; + + /** + * @param {TransactionUnspentOutput} elem + */ + add(elem: TransactionUnspentOutput): void; } /** */ -declare export class TransactionInput { +declare export class TransactionWitnessSet { free(): void; /** @@ -8839,9 +11114,9 @@ declare export class TransactionInput { /** * @param {Uint8Array} bytes - * @returns {TransactionInput} + * @returns {TransactionWitnessSet} */ - static from_bytes(bytes: Uint8Array): TransactionInput; + static from_bytes(bytes: Uint8Array): TransactionWitnessSet; /** * @returns {string} @@ -8850,9 +11125,9 @@ declare export class TransactionInput { /** * @param {string} hex_str - * @returns {TransactionInput} + * @returns {TransactionWitnessSet} */ - static from_hex(hex_str: string): TransactionInput; + static from_hex(hex_str: string): TransactionWitnessSet; /** * @returns {string} @@ -8860,105 +11135,84 @@ declare export class TransactionInput { to_json(): string; /** - * @returns {TransactionInputJSON} + * @returns {TransactionWitnessSetJSON} */ - to_js_value(): TransactionInputJSON; + to_js_value(): TransactionWitnessSetJSON; /** * @param {string} json - * @returns {TransactionInput} - */ - static from_json(json: string): TransactionInput; - - /** - * @returns {TransactionHash} - */ - transaction_id(): TransactionHash; - - /** - * @returns {number} + * @returns {TransactionWitnessSet} */ - index(): number; + static from_json(json: string): TransactionWitnessSet; /** - * @param {TransactionHash} transaction_id - * @param {number} index - * @returns {TransactionInput} + * @param {Vkeywitnesses} vkeys */ - static new(transaction_id: TransactionHash, index: number): TransactionInput; -} -/** - */ -declare export class TransactionInputs { - free(): void; + set_vkeys(vkeys: Vkeywitnesses): void; /** - * @returns {Uint8Array} + * @returns {Vkeywitnesses | void} */ - to_bytes(): Uint8Array; + vkeys(): Vkeywitnesses | void; /** - * @param {Uint8Array} bytes - * @returns {TransactionInputs} + * @param {NativeScripts} native_scripts */ - static from_bytes(bytes: Uint8Array): TransactionInputs; + set_native_scripts(native_scripts: NativeScripts): void; /** - * @returns {string} + * @returns {NativeScripts | void} */ - to_hex(): string; + native_scripts(): NativeScripts | void; /** - * @param {string} hex_str - * @returns {TransactionInputs} + * @param {BootstrapWitnesses} bootstraps */ - static from_hex(hex_str: string): TransactionInputs; + set_bootstraps(bootstraps: BootstrapWitnesses): void; /** - * @returns {string} + * @returns {BootstrapWitnesses | void} */ - to_json(): string; + bootstraps(): BootstrapWitnesses | void; /** - * @returns {TransactionInputsJSON} + * @param {PlutusScripts} plutus_scripts */ - to_js_value(): TransactionInputsJSON; + set_plutus_scripts(plutus_scripts: PlutusScripts): void; /** - * @param {string} json - * @returns {TransactionInputs} + * @returns {PlutusScripts | void} */ - static from_json(json: string): TransactionInputs; + plutus_scripts(): PlutusScripts | void; /** - * @returns {TransactionInputs} + * @param {PlutusList} plutus_data */ - static new(): TransactionInputs; + set_plutus_data(plutus_data: PlutusList): void; /** - * @returns {number} + * @returns {PlutusList | void} */ - len(): number; + plutus_data(): PlutusList | void; /** - * @param {number} index - * @returns {TransactionInput} + * @param {Redeemers} redeemers */ - get(index: number): TransactionInput; + set_redeemers(redeemers: Redeemers): void; /** - * @param {TransactionInput} elem + * @returns {Redeemers | void} */ - add(elem: TransactionInput): void; + redeemers(): Redeemers | void; /** - * @returns {TransactionInputs | void} + * @returns {TransactionWitnessSet} */ - to_option(): TransactionInputs | void; + static new(): TransactionWitnessSet; } /** */ -declare export class TransactionMetadatum { +declare export class TransactionWitnessSets { free(): void; /** @@ -8968,9 +11222,9 @@ declare export class TransactionMetadatum { /** * @param {Uint8Array} bytes - * @returns {TransactionMetadatum} + * @returns {TransactionWitnessSets} */ - static from_bytes(bytes: Uint8Array): TransactionMetadatum; + static from_bytes(bytes: Uint8Array): TransactionWitnessSets; /** * @returns {string} @@ -8979,121 +11233,98 @@ declare export class TransactionMetadatum { /** * @param {string} hex_str - * @returns {TransactionMetadatum} - */ - static from_hex(hex_str: string): TransactionMetadatum; - - /** - * @param {MetadataMap} map - * @returns {TransactionMetadatum} + * @returns {TransactionWitnessSets} */ - static new_map(map: MetadataMap): TransactionMetadatum; + static from_hex(hex_str: string): TransactionWitnessSets; /** - * @param {MetadataList} list - * @returns {TransactionMetadatum} + * @returns {string} */ - static new_list(list: MetadataList): TransactionMetadatum; + to_json(): string; /** - * @param {Int} int - * @returns {TransactionMetadatum} + * @returns {TransactionWitnessSetsJSON} */ - static new_int(int: Int): TransactionMetadatum; + to_js_value(): TransactionWitnessSetsJSON; /** - * @param {Uint8Array} bytes - * @returns {TransactionMetadatum} + * @param {string} json + * @returns {TransactionWitnessSets} */ - static new_bytes(bytes: Uint8Array): TransactionMetadatum; + static from_json(json: string): TransactionWitnessSets; /** - * @param {string} text - * @returns {TransactionMetadatum} + * @returns {TransactionWitnessSets} */ - static new_text(text: string): TransactionMetadatum; + static new(): TransactionWitnessSets; /** * @returns {number} */ - kind(): number; - - /** - * @returns {MetadataMap} - */ - as_map(): MetadataMap; - - /** - * @returns {MetadataList} - */ - as_list(): MetadataList; - - /** - * @returns {Int} - */ - as_int(): Int; + len(): number; /** - * @returns {Uint8Array} + * @param {number} index + * @returns {TransactionWitnessSet} */ - as_bytes(): Uint8Array; + get(index: number): TransactionWitnessSet; /** - * @returns {string} + * @param {TransactionWitnessSet} elem */ - as_text(): string; + add(elem: TransactionWitnessSet): void; } /** */ -declare export class TransactionMetadatumLabels { +declare export class TreasuryWithdrawals { free(): void; /** - * @returns {Uint8Array} + * @returns {string} */ - to_bytes(): Uint8Array; + to_json(): string; /** - * @param {Uint8Array} bytes - * @returns {TransactionMetadatumLabels} + * @returns {TreasuryWithdrawalsJSON} */ - static from_bytes(bytes: Uint8Array): TransactionMetadatumLabels; + to_js_value(): TreasuryWithdrawalsJSON; /** - * @returns {string} + * @param {string} json + * @returns {TreasuryWithdrawals} */ - to_hex(): string; + static from_json(json: string): TreasuryWithdrawals; /** - * @param {string} hex_str - * @returns {TransactionMetadatumLabels} + * @returns {TreasuryWithdrawals} */ - static from_hex(hex_str: string): TransactionMetadatumLabels; + static new(): TreasuryWithdrawals; /** - * @returns {TransactionMetadatumLabels} + * @param {RewardAddress} key + * @returns {BigNum | void} */ - static new(): TransactionMetadatumLabels; + get(key: RewardAddress): BigNum | void; /** - * @returns {number} + * @param {RewardAddress} key + * @param {BigNum} value */ - len(): number; + insert(key: RewardAddress, value: BigNum): void; /** - * @param {number} index - * @returns {BigNum} + * @returns {RewardAddresses} */ - get(index: number): BigNum; + keys(): RewardAddresses; /** - * @param {BigNum} elem + * @returns {number} */ - add(elem: BigNum): void; + len(): number; } /** */ -declare export class TransactionOutput { +declare export class TreasuryWithdrawalsProposal { free(): void; /** @@ -9103,9 +11334,9 @@ declare export class TransactionOutput { /** * @param {Uint8Array} bytes - * @returns {TransactionOutput} + * @returns {TreasuryWithdrawalsProposal} */ - static from_bytes(bytes: Uint8Array): TransactionOutput; + static from_bytes(bytes: Uint8Array): TreasuryWithdrawalsProposal; /** * @returns {string} @@ -9114,9 +11345,9 @@ declare export class TransactionOutput { /** * @param {string} hex_str - * @returns {TransactionOutput} + * @returns {TreasuryWithdrawalsProposal} */ - static from_hex(hex_str: string): TransactionOutput; + static from_hex(hex_str: string): TreasuryWithdrawalsProposal; /** * @returns {string} @@ -9124,184 +11355,282 @@ declare export class TransactionOutput { to_json(): string; /** - * @returns {TransactionOutputJSON} + * @returns {TreasuryWithdrawalsProposalJSON} */ - to_js_value(): TransactionOutputJSON; + to_js_value(): TreasuryWithdrawalsProposalJSON; /** * @param {string} json - * @returns {TransactionOutput} + * @returns {TreasuryWithdrawalsProposal} */ - static from_json(json: string): TransactionOutput; + static from_json(json: string): TreasuryWithdrawalsProposal; /** - * @returns {Address} + * @returns {TreasuryWithdrawals} */ - address(): Address; + withdrawals(): TreasuryWithdrawals; /** - * @returns {Value} + * @param {TreasuryWithdrawals} withdrawals + * @returns {TreasuryWithdrawalsProposal} */ - amount(): Value; + static new(withdrawals: TreasuryWithdrawals): TreasuryWithdrawalsProposal; +} +/** + */ +declare export class TxBuilderConstants { + free(): void; /** - * @returns {DataHash | void} + * @returns {Costmdls} */ - data_hash(): DataHash | void; + static plutus_default_cost_models(): Costmdls; /** - * @returns {PlutusData | void} + * @returns {Costmdls} */ - plutus_data(): PlutusData | void; + static plutus_alonzo_cost_models(): Costmdls; /** - * @returns {ScriptRef | void} + * @returns {Costmdls} */ - script_ref(): ScriptRef | void; + static plutus_vasil_cost_models(): Costmdls; +} +/** + */ +declare export class TxInputsBuilder { + free(): void; /** - * @param {ScriptRef} script_ref + * @returns {TxInputsBuilder} */ - set_script_ref(script_ref: ScriptRef): void; + static new(): TxInputsBuilder; /** - * @param {PlutusData} data + * We have to know what kind of inputs these are to know what kind of mock witnesses to create since + * 1) mock witnesses have different lengths depending on the type which changes the expecting fee + * 2) Witnesses are a set so we need to get rid of duplicates to avoid over-estimating the fee + * @param {Ed25519KeyHash} hash + * @param {TransactionInput} input + * @param {Value} amount */ - set_plutus_data(data: PlutusData): void; + add_key_input( + hash: Ed25519KeyHash, + input: TransactionInput, + amount: Value + ): void; /** - * @param {DataHash} data_hash + * !!! DEPRECATED !!! + * This function can make a mistake in choosing right input index. Use `.add_native_script_input` or `.add_plutus_script_input` instead. + * This method adds the input to the builder BUT leaves a missing spot for the witness native script + * + * After adding the input with this method, use `.add_required_native_input_scripts` + * and `.add_required_plutus_input_scripts` to add the witness scripts + * + * Or instead use `.add_native_script_input` and `.add_plutus_script_input` + * to add inputs right along with the script, instead of the script hash + * @param {ScriptHash} hash + * @param {TransactionInput} input + * @param {Value} amount */ - set_data_hash(data_hash: DataHash): void; + add_script_input( + hash: ScriptHash, + input: TransactionInput, + amount: Value + ): void; /** - * @returns {boolean} + * This method will add the input to the builder and also register the required native script witness + * @param {NativeScript} script + * @param {TransactionInput} input + * @param {Value} amount */ - has_plutus_data(): boolean; + add_native_script_input( + script: NativeScript, + input: TransactionInput, + amount: Value + ): void; /** - * @returns {boolean} + * This method will add the input to the builder and also register the required plutus witness + * @param {PlutusWitness} witness + * @param {TransactionInput} input + * @param {Value} amount */ - has_data_hash(): boolean; + add_plutus_script_input( + witness: PlutusWitness, + input: TransactionInput, + amount: Value + ): void; /** - * @returns {boolean} + * @param {ByronAddress} hash + * @param {TransactionInput} input + * @param {Value} amount */ - has_script_ref(): boolean; + add_bootstrap_input( + hash: ByronAddress, + input: TransactionInput, + amount: Value + ): void; /** + * Note that for script inputs this method will use underlying generic `.add_script_input` + * which leaves a required empty spot for the script witness (or witnesses in case of Plutus). + * You can use `.add_native_script_input` or `.add_plutus_script_input` directly to register the input along with the witness. * @param {Address} address + * @param {TransactionInput} input * @param {Value} amount - * @returns {TransactionOutput} */ - static new(address: Address, amount: Value): TransactionOutput; + add_input(address: Address, input: TransactionInput, amount: Value): void; /** - * @returns {number | void} + * Returns the number of still missing input scripts (either native or plutus) + * Use `.add_required_native_input_scripts` or `.add_required_plutus_input_scripts` to add the missing scripts + * @returns {number} */ - serialization_format(): number | void; -} -/** - */ -declare export class TransactionOutputAmountBuilder { - free(): void; + count_missing_input_scripts(): number; /** - * @param {Value} amount - * @returns {TransactionOutputAmountBuilder} + * Try adding the specified scripts as witnesses for ALREADY ADDED script inputs + * Any scripts that don't match any of the previously added inputs will be ignored + * Returns the number of remaining required missing witness scripts + * Use `.count_missing_input_scripts` to find the number of still missing scripts + * @param {NativeScripts} scripts + * @returns {number} */ - with_value(amount: Value): TransactionOutputAmountBuilder; + add_required_native_input_scripts(scripts: NativeScripts): number; /** - * @param {BigNum} coin - * @returns {TransactionOutputAmountBuilder} + * !!! DEPRECATED !!! + * This function can make a mistake in choosing right input index. Use `.add_required_script_input_witnesses` instead. + * Try adding the specified scripts as witnesses for ALREADY ADDED script inputs + * Any scripts that don't match any of the previously added inputs will be ignored + * Returns the number of remaining required missing witness scripts + * Use `.count_missing_input_scripts` to find the number of still missing scripts + * @param {PlutusWitnesses} scripts + * @returns {number} */ - with_coin(coin: BigNum): TransactionOutputAmountBuilder; + add_required_plutus_input_scripts(scripts: PlutusWitnesses): number; /** - * @param {BigNum} coin - * @param {MultiAsset} multiasset - * @returns {TransactionOutputAmountBuilder} + * Try adding the specified scripts as witnesses for ALREADY ADDED script inputs + * Any scripts that don't match any of the previously added inputs will be ignored + * Returns the number of remaining required missing witness scripts + * Use `.count_missing_input_scripts` to find the number of still missing scripts + * @param {InputsWithScriptWitness} inputs_with_wit + * @returns {number} */ - with_coin_and_asset( - coin: BigNum, - multiasset: MultiAsset - ): TransactionOutputAmountBuilder; + add_required_script_input_witnesses( + inputs_with_wit: InputsWithScriptWitness + ): number; /** - * !!! DEPRECATED !!! - * Since babbage era cardano nodes use coins per byte. Use '.with_asset_and_min_required_coin_by_utxo_cost' instead. - * @param {MultiAsset} multiasset - * @param {BigNum} coins_per_utxo_word - * @returns {TransactionOutputAmountBuilder} + * @returns {TransactionInputs} */ - with_asset_and_min_required_coin( - multiasset: MultiAsset, - coins_per_utxo_word: BigNum - ): TransactionOutputAmountBuilder; + get_ref_inputs(): TransactionInputs; /** - * @param {MultiAsset} multiasset - * @param {DataCost} data_cost - * @returns {TransactionOutputAmountBuilder} + * Returns a copy of the current script input witness scripts in the builder + * @returns {NativeScripts | void} */ - with_asset_and_min_required_coin_by_utxo_cost( - multiasset: MultiAsset, - data_cost: DataCost - ): TransactionOutputAmountBuilder; + get_native_input_scripts(): NativeScripts | void; /** - * @returns {TransactionOutput} + * Returns a copy of the current plutus input witness scripts in the builder. + * NOTE: each plutus witness will be cloned with a specific corresponding input index + * @returns {PlutusWitnesses | void} */ - build(): TransactionOutput; + get_plutus_input_scripts(): PlutusWitnesses | void; + + /** + * @returns {number} + */ + len(): number; + + /** + * @param {Ed25519KeyHash} key + */ + add_required_signer(key: Ed25519KeyHash): void; + + /** + * @param {Ed25519KeyHashes} keys + */ + add_required_signers(keys: Ed25519KeyHashes): void; + + /** + * @returns {Value} + */ + total_value(): Value; + + /** + * @returns {TransactionInputs} + */ + inputs(): TransactionInputs; + + /** + * @returns {TransactionInputs | void} + */ + inputs_option(): TransactionInputs | void; } /** - * We introduce a builder-pattern format for creating transaction outputs - * This is because: - * 1. Some fields (i.e. data hash) are optional, and we can't easily expose Option<> in WASM - * 2. Some fields like amounts have many ways it could be set (some depending on other field values being known) - * 3. Easier to adapt as the output format gets more complicated in future Cardano releases */ -declare export class TransactionOutputBuilder { +declare export class URL { free(): void; /** - * @returns {TransactionOutputBuilder} + * @returns {Uint8Array} */ - static new(): TransactionOutputBuilder; + to_bytes(): Uint8Array; /** - * @param {Address} address - * @returns {TransactionOutputBuilder} + * @param {Uint8Array} bytes + * @returns {URL} */ - with_address(address: Address): TransactionOutputBuilder; + static from_bytes(bytes: Uint8Array): URL; /** - * @param {DataHash} data_hash - * @returns {TransactionOutputBuilder} + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {URL} + */ + static from_hex(hex_str: string): URL; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {URLJSON} */ - with_data_hash(data_hash: DataHash): TransactionOutputBuilder; + to_js_value(): URLJSON; /** - * @param {PlutusData} data - * @returns {TransactionOutputBuilder} + * @param {string} json + * @returns {URL} */ - with_plutus_data(data: PlutusData): TransactionOutputBuilder; + static from_json(json: string): URL; /** - * @param {ScriptRef} script_ref - * @returns {TransactionOutputBuilder} + * @param {string} url + * @returns {URL} */ - with_script_ref(script_ref: ScriptRef): TransactionOutputBuilder; + static new(url: string): URL; /** - * @returns {TransactionOutputAmountBuilder} + * @returns {string} */ - next(): TransactionOutputAmountBuilder; + url(): string; } /** */ -declare export class TransactionOutputs { +declare export class UnitInterval { free(): void; /** @@ -9311,9 +11640,9 @@ declare export class TransactionOutputs { /** * @param {Uint8Array} bytes - * @returns {TransactionOutputs} + * @returns {UnitInterval} */ - static from_bytes(bytes: Uint8Array): TransactionOutputs; + static from_bytes(bytes: Uint8Array): UnitInterval; /** * @returns {string} @@ -9322,9 +11651,9 @@ declare export class TransactionOutputs { /** * @param {string} hex_str - * @returns {TransactionOutputs} + * @returns {UnitInterval} */ - static from_hex(hex_str: string): TransactionOutputs; + static from_hex(hex_str: string): UnitInterval; /** * @returns {string} @@ -9332,40 +11661,36 @@ declare export class TransactionOutputs { to_json(): string; /** - * @returns {TransactionOutputsJSON} + * @returns {UnitIntervalJSON} */ - to_js_value(): TransactionOutputsJSON; + to_js_value(): UnitIntervalJSON; /** * @param {string} json - * @returns {TransactionOutputs} - */ - static from_json(json: string): TransactionOutputs; - - /** - * @returns {TransactionOutputs} + * @returns {UnitInterval} */ - static new(): TransactionOutputs; + static from_json(json: string): UnitInterval; /** - * @returns {number} + * @returns {BigNum} */ - len(): number; + numerator(): BigNum; /** - * @param {number} index - * @returns {TransactionOutput} + * @returns {BigNum} */ - get(index: number): TransactionOutput; + denominator(): BigNum; /** - * @param {TransactionOutput} elem + * @param {BigNum} numerator + * @param {BigNum} denominator + * @returns {UnitInterval} */ - add(elem: TransactionOutput): void; + static new(numerator: BigNum, denominator: BigNum): UnitInterval; } /** */ -declare export class TransactionUnspentOutput { +declare export class Update { free(): void; /** @@ -9375,9 +11700,9 @@ declare export class TransactionUnspentOutput { /** * @param {Uint8Array} bytes - * @returns {TransactionUnspentOutput} + * @returns {Update} */ - static from_bytes(bytes: Uint8Array): TransactionUnspentOutput; + static from_bytes(bytes: Uint8Array): Update; /** * @returns {string} @@ -9386,9 +11711,9 @@ declare export class TransactionUnspentOutput { /** * @param {string} hex_str - * @returns {TransactionUnspentOutput} + * @returns {Update} */ - static from_hex(hex_str: string): TransactionUnspentOutput; + static from_hex(hex_str: string): Update; /** * @returns {string} @@ -9396,451 +11721,434 @@ declare export class TransactionUnspentOutput { to_json(): string; /** - * @returns {TransactionUnspentOutputJSON} + * @returns {UpdateJSON} */ - to_js_value(): TransactionUnspentOutputJSON; + to_js_value(): UpdateJSON; /** * @param {string} json - * @returns {TransactionUnspentOutput} + * @returns {Update} */ - static from_json(json: string): TransactionUnspentOutput; + static from_json(json: string): Update; /** - * @param {TransactionInput} input - * @param {TransactionOutput} output - * @returns {TransactionUnspentOutput} + * @returns {ProposedProtocolParameterUpdates} */ - static new( - input: TransactionInput, - output: TransactionOutput - ): TransactionUnspentOutput; + proposed_protocol_parameter_updates(): ProposedProtocolParameterUpdates; /** - * @returns {TransactionInput} + * @returns {number} */ - input(): TransactionInput; + epoch(): number; /** - * @returns {TransactionOutput} + * @param {ProposedProtocolParameterUpdates} proposed_protocol_parameter_updates + * @param {number} epoch + * @returns {Update} */ - output(): TransactionOutput; + static new( + proposed_protocol_parameter_updates: ProposedProtocolParameterUpdates, + epoch: number + ): Update; } /** */ -declare export class TransactionUnspentOutputs { +declare export class VRFCert { free(): void; + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {VRFCert} + */ + static from_bytes(bytes: Uint8Array): VRFCert; + /** * @returns {string} */ - to_json(): string; + to_hex(): string; /** - * @returns {TransactionUnspentOutputsJSON} + * @param {string} hex_str + * @returns {VRFCert} */ - to_js_value(): TransactionUnspentOutputsJSON; + static from_hex(hex_str: string): VRFCert; /** - * @param {string} json - * @returns {TransactionUnspentOutputs} + * @returns {string} */ - static from_json(json: string): TransactionUnspentOutputs; + to_json(): string; /** - * @returns {TransactionUnspentOutputs} + * @returns {VRFCertJSON} */ - static new(): TransactionUnspentOutputs; + to_js_value(): VRFCertJSON; /** - * @returns {number} + * @param {string} json + * @returns {VRFCert} */ - len(): number; + static from_json(json: string): VRFCert; /** - * @param {number} index - * @returns {TransactionUnspentOutput} + * @returns {Uint8Array} */ - get(index: number): TransactionUnspentOutput; + output(): Uint8Array; /** - * @param {TransactionUnspentOutput} elem + * @returns {Uint8Array} */ - add(elem: TransactionUnspentOutput): void; + proof(): Uint8Array; + + /** + * @param {Uint8Array} output + * @param {Uint8Array} proof + * @returns {VRFCert} + */ + static new(output: Uint8Array, proof: Uint8Array): VRFCert; } /** */ -declare export class TransactionWitnessSet { +declare export class VRFKeyHash { free(): void; /** - * @returns {Uint8Array} + * @param {Uint8Array} bytes + * @returns {VRFKeyHash} */ - to_bytes(): Uint8Array; + static from_bytes(bytes: Uint8Array): VRFKeyHash; /** - * @param {Uint8Array} bytes - * @returns {TransactionWitnessSet} + * @returns {Uint8Array} */ - static from_bytes(bytes: Uint8Array): TransactionWitnessSet; + to_bytes(): Uint8Array; /** + * @param {string} prefix * @returns {string} */ - to_hex(): string; + to_bech32(prefix: string): string; /** - * @param {string} hex_str - * @returns {TransactionWitnessSet} + * @param {string} bech_str + * @returns {VRFKeyHash} */ - static from_hex(hex_str: string): TransactionWitnessSet; + static from_bech32(bech_str: string): VRFKeyHash; /** * @returns {string} */ - to_json(): string; + to_hex(): string; /** - * @returns {TransactionWitnessSetJSON} + * @param {string} hex + * @returns {VRFKeyHash} */ - to_js_value(): TransactionWitnessSetJSON; + static from_hex(hex: string): VRFKeyHash; +} +/** + */ +declare export class VRFVKey { + free(): void; /** - * @param {string} json - * @returns {TransactionWitnessSet} + * @param {Uint8Array} bytes + * @returns {VRFVKey} */ - static from_json(json: string): TransactionWitnessSet; + static from_bytes(bytes: Uint8Array): VRFVKey; /** - * @param {Vkeywitnesses} vkeys + * @returns {Uint8Array} */ - set_vkeys(vkeys: Vkeywitnesses): void; + to_bytes(): Uint8Array; /** - * @returns {Vkeywitnesses | void} + * @param {string} prefix + * @returns {string} */ - vkeys(): Vkeywitnesses | void; + to_bech32(prefix: string): string; /** - * @param {NativeScripts} native_scripts + * @param {string} bech_str + * @returns {VRFVKey} */ - set_native_scripts(native_scripts: NativeScripts): void; + static from_bech32(bech_str: string): VRFVKey; /** - * @returns {NativeScripts | void} + * @returns {string} */ - native_scripts(): NativeScripts | void; + to_hex(): string; /** - * @param {BootstrapWitnesses} bootstraps + * @param {string} hex + * @returns {VRFVKey} */ - set_bootstraps(bootstraps: BootstrapWitnesses): void; + static from_hex(hex: string): VRFVKey; +} +/** + */ +declare export class Value { + free(): void; /** - * @returns {BootstrapWitnesses | void} + * @returns {Uint8Array} */ - bootstraps(): BootstrapWitnesses | void; + to_bytes(): Uint8Array; /** - * @param {PlutusScripts} plutus_scripts + * @param {Uint8Array} bytes + * @returns {Value} */ - set_plutus_scripts(plutus_scripts: PlutusScripts): void; + static from_bytes(bytes: Uint8Array): Value; /** - * @returns {PlutusScripts | void} + * @returns {string} */ - plutus_scripts(): PlutusScripts | void; + to_hex(): string; /** - * @param {PlutusList} plutus_data + * @param {string} hex_str + * @returns {Value} */ - set_plutus_data(plutus_data: PlutusList): void; + static from_hex(hex_str: string): Value; /** - * @returns {PlutusList | void} + * @returns {string} */ - plutus_data(): PlutusList | void; + to_json(): string; /** - * @param {Redeemers} redeemers + * @returns {ValueJSON} */ - set_redeemers(redeemers: Redeemers): void; + to_js_value(): ValueJSON; /** - * @returns {Redeemers | void} + * @param {string} json + * @returns {Value} */ - redeemers(): Redeemers | void; + static from_json(json: string): Value; /** - * @returns {TransactionWitnessSet} + * @param {BigNum} coin + * @returns {Value} */ - static new(): TransactionWitnessSet; -} -/** - */ -declare export class TransactionWitnessSets { - free(): void; + static new(coin: BigNum): Value; /** - * @returns {Uint8Array} + * @param {MultiAsset} multiasset + * @returns {Value} */ - to_bytes(): Uint8Array; + static new_from_assets(multiasset: MultiAsset): Value; /** - * @param {Uint8Array} bytes - * @returns {TransactionWitnessSets} + * @param {BigNum} coin + * @param {MultiAsset} multiasset + * @returns {Value} */ - static from_bytes(bytes: Uint8Array): TransactionWitnessSets; + static new_with_assets(coin: BigNum, multiasset: MultiAsset): Value; /** - * @returns {string} + * @returns {Value} */ - to_hex(): string; + static zero(): Value; /** - * @param {string} hex_str - * @returns {TransactionWitnessSets} + * @returns {boolean} */ - static from_hex(hex_str: string): TransactionWitnessSets; + is_zero(): boolean; /** - * @returns {string} + * @returns {BigNum} */ - to_json(): string; + coin(): BigNum; /** - * @returns {TransactionWitnessSetsJSON} + * @param {BigNum} coin */ - to_js_value(): TransactionWitnessSetsJSON; + set_coin(coin: BigNum): void; /** - * @param {string} json - * @returns {TransactionWitnessSets} + * @returns {MultiAsset | void} */ - static from_json(json: string): TransactionWitnessSets; + multiasset(): MultiAsset | void; /** - * @returns {TransactionWitnessSets} + * @param {MultiAsset} multiasset */ - static new(): TransactionWitnessSets; + set_multiasset(multiasset: MultiAsset): void; /** - * @returns {number} + * @param {Value} rhs + * @returns {Value} */ - len(): number; + checked_add(rhs: Value): Value; /** - * @param {number} index - * @returns {TransactionWitnessSet} + * @param {Value} rhs_value + * @returns {Value} */ - get(index: number): TransactionWitnessSet; + checked_sub(rhs_value: Value): Value; /** - * @param {TransactionWitnessSet} elem + * @param {Value} rhs_value + * @returns {Value} */ - add(elem: TransactionWitnessSet): void; + clamped_sub(rhs_value: Value): Value; + + /** + * note: values are only partially comparable + * @param {Value} rhs_value + * @returns {number | void} + */ + compare(rhs_value: Value): number | void; } /** */ -declare export class TxBuilderConstants { +declare export class Vkey { free(): void; /** - * @returns {Costmdls} + * @returns {Uint8Array} */ - static plutus_default_cost_models(): Costmdls; + to_bytes(): Uint8Array; /** - * @returns {Costmdls} + * @param {Uint8Array} bytes + * @returns {Vkey} */ - static plutus_alonzo_cost_models(): Costmdls; + static from_bytes(bytes: Uint8Array): Vkey; /** - * @returns {Costmdls} + * @returns {string} */ - static plutus_vasil_cost_models(): Costmdls; -} -/** - */ -declare export class TxInputsBuilder { - free(): void; + to_hex(): string; /** - * @returns {TxInputsBuilder} + * @param {string} hex_str + * @returns {Vkey} */ - static new(): TxInputsBuilder; + static from_hex(hex_str: string): Vkey; /** - * We have to know what kind of inputs these are to know what kind of mock witnesses to create since - * 1) mock witnesses have different lengths depending on the type which changes the expecting fee - * 2) Witnesses are a set so we need to get rid of duplicates to avoid over-estimating the fee - * @param {Ed25519KeyHash} hash - * @param {TransactionInput} input - * @param {Value} amount + * @returns {string} */ - add_key_input( - hash: Ed25519KeyHash, - input: TransactionInput, - amount: Value - ): void; + to_json(): string; /** - * !!! DEPRECATED !!! - * This function can make a mistake in choosing right input index. Use `.add_native_script_input` or `.add_plutus_script_input` instead. - * This method adds the input to the builder BUT leaves a missing spot for the witness native script - * - * After adding the input with this method, use `.add_required_native_input_scripts` - * and `.add_required_plutus_input_scripts` to add the witness scripts - * - * Or instead use `.add_native_script_input` and `.add_plutus_script_input` - * to add inputs right along with the script, instead of the script hash - * @param {ScriptHash} hash - * @param {TransactionInput} input - * @param {Value} amount + * @returns {VkeyJSON} */ - add_script_input( - hash: ScriptHash, - input: TransactionInput, - amount: Value - ): void; + to_js_value(): VkeyJSON; /** - * This method will add the input to the builder and also register the required native script witness - * @param {NativeScript} script - * @param {TransactionInput} input - * @param {Value} amount + * @param {string} json + * @returns {Vkey} */ - add_native_script_input( - script: NativeScript, - input: TransactionInput, - amount: Value - ): void; + static from_json(json: string): Vkey; /** - * This method will add the input to the builder and also register the required plutus witness - * @param {PlutusWitness} witness - * @param {TransactionInput} input - * @param {Value} amount + * @param {PublicKey} pk + * @returns {Vkey} */ - add_plutus_script_input( - witness: PlutusWitness, - input: TransactionInput, - amount: Value - ): void; + static new(pk: PublicKey): Vkey; /** - * @param {ByronAddress} hash - * @param {TransactionInput} input - * @param {Value} amount + * @returns {PublicKey} */ - add_bootstrap_input( - hash: ByronAddress, - input: TransactionInput, - amount: Value - ): void; + public_key(): PublicKey; +} +/** + */ +declare export class Vkeys { + free(): void; /** - * Note that for script inputs this method will use underlying generic `.add_script_input` - * which leaves a required empty spot for the script witness (or witnesses in case of Plutus). - * You can use `.add_native_script_input` or `.add_plutus_script_input` directly to register the input along with the witness. - * @param {Address} address - * @param {TransactionInput} input - * @param {Value} amount + * @returns {Vkeys} */ - add_input(address: Address, input: TransactionInput, amount: Value): void; + static new(): Vkeys; /** - * Returns the number of still missing input scripts (either native or plutus) - * Use `.add_required_native_input_scripts` or `.add_required_plutus_input_scripts` to add the missing scripts * @returns {number} */ - count_missing_input_scripts(): number; + len(): number; /** - * Try adding the specified scripts as witnesses for ALREADY ADDED script inputs - * Any scripts that don't match any of the previously added inputs will be ignored - * Returns the number of remaining required missing witness scripts - * Use `.count_missing_input_scripts` to find the number of still missing scripts - * @param {NativeScripts} scripts - * @returns {number} + * @param {number} index + * @returns {Vkey} */ - add_required_native_input_scripts(scripts: NativeScripts): number; + get(index: number): Vkey; /** - * !!! DEPRECATED !!! - * This function can make a mistake in choosing right input index. Use `.add_required_script_input_witnesses` instead. - * Try adding the specified scripts as witnesses for ALREADY ADDED script inputs - * Any scripts that don't match any of the previously added inputs will be ignored - * Returns the number of remaining required missing witness scripts - * Use `.count_missing_input_scripts` to find the number of still missing scripts - * @param {PlutusWitnesses} scripts - * @returns {number} + * @param {Vkey} elem */ - add_required_plutus_input_scripts(scripts: PlutusWitnesses): number; + add(elem: Vkey): void; +} +/** + */ +declare export class Vkeywitness { + free(): void; /** - * Try adding the specified scripts as witnesses for ALREADY ADDED script inputs - * Any scripts that don't match any of the previously added inputs will be ignored - * Returns the number of remaining required missing witness scripts - * Use `.count_missing_input_scripts` to find the number of still missing scripts - * @param {InputsWithScriptWitness} inputs_with_wit - * @returns {number} + * @returns {Uint8Array} */ - add_required_script_input_witnesses( - inputs_with_wit: InputsWithScriptWitness - ): number; + to_bytes(): Uint8Array; /** - * @returns {TransactionInputs} + * @param {Uint8Array} bytes + * @returns {Vkeywitness} */ - get_ref_inputs(): TransactionInputs; + static from_bytes(bytes: Uint8Array): Vkeywitness; /** - * Returns a copy of the current script input witness scripts in the builder - * @returns {NativeScripts | void} + * @returns {string} */ - get_native_input_scripts(): NativeScripts | void; + to_hex(): string; /** - * Returns a copy of the current plutus input witness scripts in the builder. - * NOTE: each plutus witness will be cloned with a specific corresponding input index - * @returns {PlutusWitnesses | void} + * @param {string} hex_str + * @returns {Vkeywitness} */ - get_plutus_input_scripts(): PlutusWitnesses | void; + static from_hex(hex_str: string): Vkeywitness; /** - * @returns {number} + * @returns {string} */ - len(): number; + to_json(): string; /** - * @param {Ed25519KeyHash} key + * @returns {VkeywitnessJSON} */ - add_required_signer(key: Ed25519KeyHash): void; + to_js_value(): VkeywitnessJSON; /** - * @param {Ed25519KeyHashes} keys + * @param {string} json + * @returns {Vkeywitness} */ - add_required_signers(keys: Ed25519KeyHashes): void; + static from_json(json: string): Vkeywitness; /** - * @returns {Value} + * @param {Vkey} vkey + * @param {Ed25519Signature} signature + * @returns {Vkeywitness} */ - total_value(): Value; + static new(vkey: Vkey, signature: Ed25519Signature): Vkeywitness; /** - * @returns {TransactionInputs} + * @returns {Vkey} */ - inputs(): TransactionInputs; + vkey(): Vkey; /** - * @returns {TransactionInputs | void} + * @returns {Ed25519Signature} */ - inputs_option(): TransactionInputs | void; + signature(): Ed25519Signature; } /** */ -declare export class URL { +declare export class Vkeywitnesses { free(): void; /** @@ -9850,9 +12158,9 @@ declare export class URL { /** * @param {Uint8Array} bytes - * @returns {URL} + * @returns {Vkeywitnesses} */ - static from_bytes(bytes: Uint8Array): URL; + static from_bytes(bytes: Uint8Array): Vkeywitnesses; /** * @returns {string} @@ -9861,9 +12169,9 @@ declare export class URL { /** * @param {string} hex_str - * @returns {URL} + * @returns {Vkeywitnesses} */ - static from_hex(hex_str: string): URL; + static from_hex(hex_str: string): Vkeywitnesses; /** * @returns {string} @@ -9871,30 +12179,40 @@ declare export class URL { to_json(): string; /** - * @returns {URLJSON} + * @returns {VkeywitnessesJSON} */ - to_js_value(): URLJSON; + to_js_value(): VkeywitnessesJSON; /** * @param {string} json - * @returns {URL} + * @returns {Vkeywitnesses} */ - static from_json(json: string): URL; + static from_json(json: string): Vkeywitnesses; /** - * @param {string} url - * @returns {URL} + * @returns {Vkeywitnesses} */ - static new(url: string): URL; + static new(): Vkeywitnesses; /** - * @returns {string} + * @returns {number} */ - url(): string; + len(): number; + + /** + * @param {number} index + * @returns {Vkeywitness} + */ + get(index: number): Vkeywitness; + + /** + * @param {Vkeywitness} elem + */ + add(elem: Vkeywitness): void; } /** */ -declare export class UnitInterval { +declare export class VoteDelegation { free(): void; /** @@ -9904,9 +12222,9 @@ declare export class UnitInterval { /** * @param {Uint8Array} bytes - * @returns {UnitInterval} + * @returns {VoteDelegation} */ - static from_bytes(bytes: Uint8Array): UnitInterval; + static from_bytes(bytes: Uint8Array): VoteDelegation; /** * @returns {string} @@ -9915,9 +12233,9 @@ declare export class UnitInterval { /** * @param {string} hex_str - * @returns {UnitInterval} + * @returns {VoteDelegation} */ - static from_hex(hex_str: string): UnitInterval; + static from_hex(hex_str: string): VoteDelegation; /** * @returns {string} @@ -9925,36 +12243,41 @@ declare export class UnitInterval { to_json(): string; /** - * @returns {UnitIntervalJSON} + * @returns {VoteDelegationJSON} */ - to_js_value(): UnitIntervalJSON; + to_js_value(): VoteDelegationJSON; /** * @param {string} json - * @returns {UnitInterval} + * @returns {VoteDelegation} */ - static from_json(json: string): UnitInterval; + static from_json(json: string): VoteDelegation; /** - * @returns {BigNum} + * @returns {StakeCredential} */ - numerator(): BigNum; + stake_credential(): StakeCredential; /** - * @returns {BigNum} + * @returns {DRep} */ - denominator(): BigNum; + drep(): DRep; /** - * @param {BigNum} numerator - * @param {BigNum} denominator - * @returns {UnitInterval} + * @param {StakeCredential} stake_credential + * @param {DRep} drep + * @returns {VoteDelegation} */ - static new(numerator: BigNum, denominator: BigNum): UnitInterval; + static new(stake_credential: StakeCredential, drep: DRep): VoteDelegation; + + /** + * @returns {boolean} + */ + has_script_credentials(): boolean; } /** */ -declare export class Update { +declare export class VoteRegistrationAndDelegation { free(): void; /** @@ -9964,9 +12287,9 @@ declare export class Update { /** * @param {Uint8Array} bytes - * @returns {Update} + * @returns {VoteRegistrationAndDelegation} */ - static from_bytes(bytes: Uint8Array): Update; + static from_bytes(bytes: Uint8Array): VoteRegistrationAndDelegation; /** * @returns {string} @@ -9975,9 +12298,9 @@ declare export class Update { /** * @param {string} hex_str - * @returns {Update} + * @returns {VoteRegistrationAndDelegation} */ - static from_hex(hex_str: string): Update; + static from_hex(hex_str: string): VoteRegistrationAndDelegation; /** * @returns {string} @@ -9985,39 +12308,51 @@ declare export class Update { to_json(): string; /** - * @returns {UpdateJSON} + * @returns {VoteRegistrationAndDelegationJSON} */ - to_js_value(): UpdateJSON; + to_js_value(): VoteRegistrationAndDelegationJSON; /** * @param {string} json - * @returns {Update} + * @returns {VoteRegistrationAndDelegation} */ - static from_json(json: string): Update; + static from_json(json: string): VoteRegistrationAndDelegation; /** - * @returns {ProposedProtocolParameterUpdates} + * @returns {StakeCredential} */ - proposed_protocol_parameter_updates(): ProposedProtocolParameterUpdates; + stake_credential(): StakeCredential; /** - * @returns {number} + * @returns {DRep} */ - epoch(): number; + drep(): DRep; /** - * @param {ProposedProtocolParameterUpdates} proposed_protocol_parameter_updates - * @param {number} epoch - * @returns {Update} + * @returns {BigNum} + */ + coin(): BigNum; + + /** + * @param {StakeCredential} stake_credential + * @param {DRep} drep + * @param {BigNum} coin + * @returns {VoteRegistrationAndDelegation} */ static new( - proposed_protocol_parameter_updates: ProposedProtocolParameterUpdates, - epoch: number - ): Update; + stake_credential: StakeCredential, + drep: DRep, + coin: BigNum + ): VoteRegistrationAndDelegation; + + /** + * @returns {boolean} + */ + has_script_credentials(): boolean; } /** */ -declare export class VRFCert { +declare export class Voter { free(): void; /** @@ -10027,9 +12362,9 @@ declare export class VRFCert { /** * @param {Uint8Array} bytes - * @returns {VRFCert} + * @returns {Voter} */ - static from_bytes(bytes: Uint8Array): VRFCert; + static from_bytes(bytes: Uint8Array): Voter; /** * @returns {string} @@ -10038,9 +12373,9 @@ declare export class VRFCert { /** * @param {string} hex_str - * @returns {VRFCert} + * @returns {Voter} */ - static from_hex(hex_str: string): VRFCert; + static from_hex(hex_str: string): Voter; /** * @returns {string} @@ -10048,231 +12383,242 @@ declare export class VRFCert { to_json(): string; /** - * @returns {VRFCertJSON} + * @returns {VoterJSON} */ - to_js_value(): VRFCertJSON; + to_js_value(): VoterJSON; /** * @param {string} json - * @returns {VRFCert} + * @returns {Voter} */ - static from_json(json: string): VRFCert; + static from_json(json: string): Voter; /** - * @returns {Uint8Array} + * @param {StakeCredential} cred + * @returns {Voter} */ - output(): Uint8Array; + static new_constitutional_committee_hot_key(cred: StakeCredential): Voter; /** - * @returns {Uint8Array} + * @param {StakeCredential} cred + * @returns {Voter} */ - proof(): Uint8Array; + static new_drep(cred: StakeCredential): Voter; /** - * @param {Uint8Array} output - * @param {Uint8Array} proof - * @returns {VRFCert} + * @param {Ed25519KeyHash} key_hash + * @returns {Voter} */ - static new(output: Uint8Array, proof: Uint8Array): VRFCert; -} -/** - */ -declare export class VRFKeyHash { - free(): void; + static new_staking_pool(key_hash: Ed25519KeyHash): Voter; /** - * @param {Uint8Array} bytes - * @returns {VRFKeyHash} + * @returns {number} */ - static from_bytes(bytes: Uint8Array): VRFKeyHash; + kind(): number; /** - * @returns {Uint8Array} + * @returns {StakeCredential | void} */ - to_bytes(): Uint8Array; + to_constitutional_committee_hot_key(): StakeCredential | void; /** - * @param {string} prefix - * @returns {string} + * @returns {StakeCredential | void} */ - to_bech32(prefix: string): string; + to_drep(): StakeCredential | void; /** - * @param {string} bech_str - * @returns {VRFKeyHash} + * @returns {Ed25519KeyHash | void} */ - static from_bech32(bech_str: string): VRFKeyHash; + to_staking_pool(): Ed25519KeyHash | void; /** - * @returns {string} + * @returns {boolean} */ - to_hex(): string; + has_script_credentials(): boolean; /** - * @param {string} hex - * @returns {VRFKeyHash} + * @returns {Ed25519KeyHash | void} */ - static from_hex(hex: string): VRFKeyHash; + to_keyhash(): Ed25519KeyHash | void; } /** */ -declare export class VRFVKey { +declare export class Voters { free(): void; /** - * @param {Uint8Array} bytes - * @returns {VRFVKey} + * @returns {string} */ - static from_bytes(bytes: Uint8Array): VRFVKey; + to_json(): string; /** - * @returns {Uint8Array} + * @returns {VotersJSON} */ - to_bytes(): Uint8Array; + to_js_value(): VotersJSON; /** - * @param {string} prefix - * @returns {string} + * @param {string} json + * @returns {Voters} */ - to_bech32(prefix: string): string; + static from_json(json: string): Voters; /** - * @param {string} bech_str - * @returns {VRFVKey} + * @returns {Voters} */ - static from_bech32(bech_str: string): VRFVKey; + static new(): Voters; /** - * @returns {string} + * @param {number} index + * @returns {Voter | void} */ - to_hex(): string; + get(index: number): Voter | void; /** - * @param {string} hex - * @returns {VRFVKey} + * @returns {number} */ - static from_hex(hex: string): VRFVKey; + len(): number; } /** */ -declare export class Value { +declare export class VotingBuilder { free(): void; /** - * @returns {Uint8Array} + * @returns {VotingBuilder} */ - to_bytes(): Uint8Array; + static new(): VotingBuilder; /** - * @param {Uint8Array} bytes - * @returns {Value} + * @param {Voter} voter + * @param {GovernanceActionId} gov_action_id + * @param {VotingProcedure} voting_procedure */ - static from_bytes(bytes: Uint8Array): Value; + add( + voter: Voter, + gov_action_id: GovernanceActionId, + voting_procedure: VotingProcedure + ): void; /** - * @returns {string} + * @param {Voter} voter + * @param {GovernanceActionId} gov_action_id + * @param {VotingProcedure} voting_procedure + * @param {PlutusWitness} witness */ - to_hex(): string; + add_with_plutus_witness( + voter: Voter, + gov_action_id: GovernanceActionId, + voting_procedure: VotingProcedure, + witness: PlutusWitness + ): void; /** - * @param {string} hex_str - * @returns {Value} + * @param {Voter} voter + * @param {GovernanceActionId} gov_action_id + * @param {VotingProcedure} voting_procedure + * @param {NativeScriptSource} native_script_source */ - static from_hex(hex_str: string): Value; + add_with_native_script( + voter: Voter, + gov_action_id: GovernanceActionId, + voting_procedure: VotingProcedure, + native_script_source: NativeScriptSource + ): void; /** - * @returns {string} + * @returns {PlutusWitnesses} */ - to_json(): string; + get_plutus_witnesses(): PlutusWitnesses; /** - * @returns {ValueJSON} + * @returns {TransactionInputs} */ - to_js_value(): ValueJSON; + get_ref_inputs(): TransactionInputs; /** - * @param {string} json - * @returns {Value} + * @returns {NativeScripts} */ - static from_json(json: string): Value; + get_native_scripts(): NativeScripts; /** - * @param {BigNum} coin - * @returns {Value} + * @returns {boolean} */ - static new(coin: BigNum): Value; + has_plutus_scripts(): boolean; /** - * @param {MultiAsset} multiasset - * @returns {Value} + * @returns {VotingProcedures} */ - static new_from_assets(multiasset: MultiAsset): Value; + build(): VotingProcedures; +} +/** + */ +declare export class VotingProcedure { + free(): void; /** - * @param {BigNum} coin - * @param {MultiAsset} multiasset - * @returns {Value} + * @returns {Uint8Array} */ - static new_with_assets(coin: BigNum, multiasset: MultiAsset): Value; + to_bytes(): Uint8Array; /** - * @returns {Value} + * @param {Uint8Array} bytes + * @returns {VotingProcedure} */ - static zero(): Value; + static from_bytes(bytes: Uint8Array): VotingProcedure; /** - * @returns {boolean} + * @returns {string} */ - is_zero(): boolean; + to_hex(): string; /** - * @returns {BigNum} + * @param {string} hex_str + * @returns {VotingProcedure} */ - coin(): BigNum; + static from_hex(hex_str: string): VotingProcedure; /** - * @param {BigNum} coin + * @returns {string} */ - set_coin(coin: BigNum): void; + to_json(): string; /** - * @returns {MultiAsset | void} + * @returns {VotingProcedureJSON} */ - multiasset(): MultiAsset | void; + to_js_value(): VotingProcedureJSON; /** - * @param {MultiAsset} multiasset + * @param {string} json + * @returns {VotingProcedure} */ - set_multiasset(multiasset: MultiAsset): void; + static from_json(json: string): VotingProcedure; /** - * @param {Value} rhs - * @returns {Value} + * @param {number} vote + * @returns {VotingProcedure} */ - checked_add(rhs: Value): Value; + static new(vote: number): VotingProcedure; /** - * @param {Value} rhs_value - * @returns {Value} + * @param {number} vote + * @param {Anchor} anchor + * @returns {VotingProcedure} */ - checked_sub(rhs_value: Value): Value; + static new_with_anchor(vote: number, anchor: Anchor): VotingProcedure; /** - * @param {Value} rhs_value - * @returns {Value} + * @returns {number} */ - clamped_sub(rhs_value: Value): Value; + vote(): number; /** - * note: values are only partially comparable - * @param {Value} rhs_value - * @returns {number | void} + * @returns {Anchor | void} */ - compare(rhs_value: Value): number | void; + anchor(): Anchor | void; } /** */ -declare export class Vkey { +declare export class VotingProcedures { free(): void; /** @@ -10282,9 +12628,9 @@ declare export class Vkey { /** * @param {Uint8Array} bytes - * @returns {Vkey} + * @returns {VotingProcedures} */ - static from_bytes(bytes: Uint8Array): Vkey; + static from_bytes(bytes: Uint8Array): VotingProcedures; /** * @returns {string} @@ -10293,66 +12639,55 @@ declare export class Vkey { /** * @param {string} hex_str - * @returns {Vkey} - */ - static from_hex(hex_str: string): Vkey; - - /** - * @returns {string} + * @returns {VotingProcedures} */ - to_json(): string; - - /** - * @returns {VkeyJSON} - */ - to_js_value(): VkeyJSON; + static from_hex(hex_str: string): VotingProcedures; /** - * @param {string} json - * @returns {Vkey} + * @returns {string} */ - static from_json(json: string): Vkey; + to_json(): string; /** - * @param {PublicKey} pk - * @returns {Vkey} + * @returns {VotingProceduresJSON} */ - static new(pk: PublicKey): Vkey; + to_js_value(): VotingProceduresJSON; /** - * @returns {PublicKey} + * @param {string} json + * @returns {VotingProcedures} */ - public_key(): PublicKey; -} -/** - */ -declare export class Vkeys { - free(): void; + static from_json(json: string): VotingProcedures; /** - * @returns {Vkeys} + * @returns {VotingProcedures} */ - static new(): Vkeys; + static new(): VotingProcedures; /** - * @returns {number} + * @param {Voter} voter + * @param {GovernanceActionId} governance_action_id + * @returns {VotingProcedure | void} */ - len(): number; + get( + voter: Voter, + governance_action_id: GovernanceActionId + ): VotingProcedure | void; /** - * @param {number} index - * @returns {Vkey} + * @returns {Voters} */ - get(index: number): Vkey; + get_voters(): Voters; /** - * @param {Vkey} elem + * @param {Voter} voter + * @returns {GovernanceActionIds} */ - add(elem: Vkey): void; + get_governance_action_ids_by_voter(voter: Voter): GovernanceActionIds; } /** */ -declare export class Vkeywitness { +declare export class VotingProposal { free(): void; /** @@ -10362,9 +12697,9 @@ declare export class Vkeywitness { /** * @param {Uint8Array} bytes - * @returns {Vkeywitness} + * @returns {VotingProposal} */ - static from_bytes(bytes: Uint8Array): Vkeywitness; + static from_bytes(bytes: Uint8Array): VotingProposal; /** * @returns {string} @@ -10373,9 +12708,9 @@ declare export class Vkeywitness { /** * @param {string} hex_str - * @returns {Vkeywitness} + * @returns {VotingProposal} */ - static from_hex(hex_str: string): Vkeywitness; + static from_hex(hex_str: string): VotingProposal; /** * @returns {string} @@ -10383,36 +12718,63 @@ declare export class Vkeywitness { to_json(): string; /** - * @returns {VkeywitnessJSON} + * @returns {VotingProposalJSON} */ - to_js_value(): VkeywitnessJSON; + to_js_value(): VotingProposalJSON; /** * @param {string} json - * @returns {Vkeywitness} + * @returns {VotingProposal} */ - static from_json(json: string): Vkeywitness; + static from_json(json: string): VotingProposal; +} +/** + */ +declare export class VotingProposalBuilder { + free(): void; /** - * @param {Vkey} vkey - * @param {Ed25519Signature} signature - * @returns {Vkeywitness} + * @returns {VotingProposalBuilder} */ - static new(vkey: Vkey, signature: Ed25519Signature): Vkeywitness; + static new(): VotingProposalBuilder; /** - * @returns {Vkey} + * @param {VotingProposal} proposal */ - vkey(): Vkey; + add(proposal: VotingProposal): void; /** - * @returns {Ed25519Signature} + * @param {VotingProposal} proposal + * @param {PlutusWitness} witness */ - signature(): Ed25519Signature; + add_with_plutus_witness( + proposal: VotingProposal, + witness: PlutusWitness + ): void; + + /** + * @returns {PlutusWitnesses} + */ + get_plutus_witnesses(): PlutusWitnesses; + + /** + * @returns {TransactionInputs} + */ + get_ref_inputs(): TransactionInputs; + + /** + * @returns {boolean} + */ + has_plutus_scripts(): boolean; + + /** + * @returns {VotingProposals} + */ + build(): VotingProposals; } /** */ -declare export class Vkeywitnesses { +declare export class VotingProposals { free(): void; /** @@ -10422,9 +12784,9 @@ declare export class Vkeywitnesses { /** * @param {Uint8Array} bytes - * @returns {Vkeywitnesses} + * @returns {VotingProposals} */ - static from_bytes(bytes: Uint8Array): Vkeywitnesses; + static from_bytes(bytes: Uint8Array): VotingProposals; /** * @returns {string} @@ -10433,9 +12795,9 @@ declare export class Vkeywitnesses { /** * @param {string} hex_str - * @returns {Vkeywitnesses} + * @returns {VotingProposals} */ - static from_hex(hex_str: string): Vkeywitnesses; + static from_hex(hex_str: string): VotingProposals; /** * @returns {string} @@ -10443,36 +12805,15 @@ declare export class Vkeywitnesses { to_json(): string; /** - * @returns {VkeywitnessesJSON} + * @returns {VotingProposalsJSON} */ - to_js_value(): VkeywitnessesJSON; + to_js_value(): VotingProposalsJSON; /** * @param {string} json - * @returns {Vkeywitnesses} - */ - static from_json(json: string): Vkeywitnesses; - - /** - * @returns {Vkeywitnesses} - */ - static new(): Vkeywitnesses; - - /** - * @returns {number} - */ - len(): number; - - /** - * @param {number} index - * @returns {Vkeywitness} - */ - get(index: number): Vkeywitness; - - /** - * @param {Vkeywitness} elem + * @returns {VotingProposals} */ - add(elem: Vkeywitness): void; + static from_json(json: string): VotingProposals; } /** */ @@ -10545,7 +12886,80 @@ declare export class Withdrawals { */ keys(): RewardAddresses; } +/** + */ +declare export class WithdrawalsBuilder { + free(): void; + + /** + * @returns {WithdrawalsBuilder} + */ + static new(): WithdrawalsBuilder; + + /** + * @param {RewardAddress} address + * @param {BigNum} coin + */ + add(address: RewardAddress, coin: BigNum): void; + + /** + * @param {RewardAddress} address + * @param {BigNum} coin + * @param {PlutusWitness} witness + */ + add_with_plutus_witness( + address: RewardAddress, + coin: BigNum, + witness: PlutusWitness + ): void; + + /** + * @param {RewardAddress} address + * @param {BigNum} coin + * @param {NativeScriptSource} native_script_source + */ + add_with_native_script( + address: RewardAddress, + coin: BigNum, + native_script_source: NativeScriptSource + ): void; + + /** + * @returns {PlutusWitnesses} + */ + get_plutus_witnesses(): PlutusWitnesses; + + /** + * @returns {TransactionInputs} + */ + get_ref_inputs(): TransactionInputs; + + /** + * @returns {NativeScripts} + */ + get_native_scripts(): NativeScripts; + + /** + * @returns {Value} + */ + get_total_withdrawals(): Value; + + /** + * @returns {boolean} + */ + has_plutus_scripts(): boolean; + + /** + * @returns {Withdrawals} + */ + build(): Withdrawals; +} export type AddressJSON = string; +export interface AnchorJSON { + anchor_data_hash: string; + anchor_url: URLJSON; +} +export type AnchorDataHashJSON = string; export type AssetNameJSON = string; export type AssetNamesJSON = string[]; export interface AssetsJSON { @@ -10611,14 +13025,82 @@ export type CertificateEnumJSON = | { MoveInstantaneousRewardsCertJSON: MoveInstantaneousRewardsCert, ... + } + | { + CommitteeHotKeyRegistrationJSON: CommitteeHotKeyRegistration, + ... + } + | { + CommitteeHotKeyDeregistrationJSON: CommitteeHotKeyDeregistration, + ... + } + | { + DrepDeregistrationJSON: DrepDeregistration, + ... + } + | { + DrepRegistrationJSON: DrepRegistration, + ... + } + | { + DrepUpdateJSON: DrepUpdate, + ... + } + | { + StakeAndVoteDelegationJSON: StakeAndVoteDelegation, + ... + } + | { + StakeRegistrationAndDelegationJSON: StakeRegistrationAndDelegation, + ... + } + | { + StakeVoteRegistrationAndDelegationJSON: StakeVoteRegistrationAndDelegation, + ... + } + | { + VoteDelegationJSON: VoteDelegation, + ... + } + | { + VoteRegistrationAndDelegationJSON: VoteRegistrationAndDelegation, + ... }; export type CertificatesJSON = CertificateJSON[]; +export interface CommitteeJSON { + members: { + [k: string]: number, + }; + quorum_threshold: UnitIntervalJSON; +} +export interface CommitteeHotKeyDeregistrationJSON { + committee_cold_key: StakeCredTypeJSON; +} +export interface CommitteeHotKeyRegistrationJSON { + committee_cold_key: StakeCredTypeJSON; + committee_hot_key: StakeCredTypeJSON; +} +export interface ConstitutionJSON { + anchor: AnchorJSON; + script_hash?: string | null; +} export type CostModelJSON = string[]; export interface CostmdlsJSON { [k: string]: CostModelJSON; } export type DNSRecordAorAAAAJSON = string; export type DNSRecordSRVJSON = string; +export type DRepJSON = DRepEnumJSON; +export type DRepEnumJSON = + | ("AlwaysAbstain" | "AlwaysNoConfidence") + | { + KeyHash: string, + ... + } + | { + ScriptHashJSON: string, + ... + }; export type DataHashJSON = string; export type DataOptionJSON = | { @@ -10629,6 +13111,19 @@ export type DataOptionJSON = Data: string, ... }; +export interface DrepDeregistrationJSON { + coin: string; + voting_credential: StakeCredTypeJSON; +} +export interface DrepRegistrationJSON { + anchor?: AnchorJSON | null; + coin: string; + voting_credential: StakeCredTypeJSON; +} +export interface DrepUpdateJSON { + anchor?: AnchorJSON | null; + voting_credential: StakeCredTypeJSON; +} export type Ed25519KeyHashJSON = string; export type Ed25519KeyHashesJSON = string[]; export type Ed25519SignatureJSON = string; @@ -10651,6 +13146,14 @@ export interface GenesisKeyDelegationJSON { genesishash: string; vrf_keyhash: string; } +export interface GovernanceActionIdJSON { + index: number; + transaction_id: string; +} +export interface HardForkInitiationProposalJSON { + gov_action_id?: GovernanceActionIdJSON | null; + protocol_version: ProtocolVersionJSON; +} export interface HeaderJSON { body_signature: string; header_body: HeaderBodyJSON; @@ -10761,6 +13264,18 @@ export type NativeScript1JSON = export type NativeScriptsJSON = NativeScriptJSON[]; export type NetworkIdJSON = NetworkIdKindJSON; export type NetworkIdKindJSON = "Testnet" | "Mainnet"; +export interface NewCommitteeProposalJSON { + committee: CommitteeJSON; + gov_action_id?: GovernanceActionIdJSON | null; + members_to_remove: StakeCredTypeJSON[]; +} +export interface NewConstitutionProposalJSON { + constitution: ConstitutionJSON; + gov_action_id?: GovernanceActionIdJSON | null; +} +export interface NoConfidenceProposalJSON { + gov_action_id?: GovernanceActionIdJSON | null; +} export interface NonceJSON { hash?: | [ @@ -10805,6 +13320,10 @@ export interface OperationalCertJSON { sequence_number: number; sigma: string; } +export interface ParameterChangeProposalJSON { + gov_action_id?: GovernanceActionIdJSON | null; + protocol_param_updates: ProtocolParamUpdateJSON; +} export type PlutusScriptJSON = string; export type PlutusScriptsJSON = string[]; export interface PoolMetadataJSON { @@ -10871,7 +13390,12 @@ export interface RedeemerJSON { tag: RedeemerTagJSON; } export type RedeemerTagJSON = RedeemerTagKindJSON; -export type RedeemerTagKindJSON = "Spend" | "MintJSON" | "Cert" | "Reward"; +export type RedeemerTagKindJSON = + | "Spend" + | "MintJSON" + | "Cert" + | "Reward" + | "Vote"; export type RedeemersJSON = RedeemerJSON[]; export type RelayJSON = RelayEnumJSON; export type RelayEnumJSON = @@ -10925,6 +13449,11 @@ export interface SingleHostNameJSON { dns_name: DNSRecordAorAAAAJSON; port?: number | null; } +export interface StakeAndVoteDelegationJSON { + drep: DRepJSON; + pool_keyhash: string; + stake_credential: StakeCredTypeJSON; +} export type StakeCredTypeJSON = | { Key: string, @@ -10941,9 +13470,22 @@ export interface StakeDelegationJSON { stake_credential: StakeCredTypeJSON; } export interface StakeDeregistrationJSON { + coin?: string | null; stake_credential: StakeCredTypeJSON; } export interface StakeRegistrationJSON { + coin?: string | null; + stake_credential: StakeCredTypeJSON; +} +export interface StakeRegistrationAndDelegationJSON { + coin: string; + pool_keyhash: string; + stake_credential: StakeCredTypeJSON; +} +export interface StakeVoteRegistrationAndDelegationJSON { + coin: string; + drep: DRepJSON; + pool_keyhash: string; stake_credential: StakeCredTypeJSON; } export interface TimelockExpiryJSON { @@ -10976,6 +13518,8 @@ export interface TransactionBodyJSON { ttl?: string | null; update?: UpdateJSON | null; validity_start_interval?: string | null; + voting_procedures?: VotingProceduresJSON | null; + voting_proposals?: VotingProposalsJSON | null; withdrawals?: { [k: string]: ProtocolParamUpdateJSON, } | null; @@ -11008,6 +13552,12 @@ export interface TransactionWitnessSetJSON { vkeys?: VkeywitnessesJSON | null; } export type TransactionWitnessSetsJSON = TransactionWitnessSetJSON[]; +export interface TreasuryWithdrawalsJSON { + [k: string]: string; +} +export interface TreasuryWithdrawalsProposalJSON { + withdrawals: TreasuryWithdrawalsJSON; +} export type URLJSON = string; export interface UnitIntervalJSON { denominator: string; @@ -11035,6 +13585,69 @@ export interface VkeywitnessJSON { vkey: VkeyJSON; } export type VkeywitnessesJSON = VkeywitnessJSON[]; +export interface VoteDelegationJSON { + drep: DRepJSON; + stake_credential: StakeCredTypeJSON; +} +export interface VoteRegistrationAndDelegationJSON { + coin: string; + drep: DRepJSON; + stake_credential: StakeCredTypeJSON; +} +export type VoterJSON = VoterEnumJSON; +export type VoterEnumJSON = + | { + ConstitutionalCommitteeHotKey: StakeCredTypeJSON, + ... + } + | { + DRepJSON: StakeCredTypeJSON, + ... + } + | { + StakingPool: string, + ... + }; +export interface VotingProcedureJSON { + anchor?: AnchorJSON | null; + vote: $Values; +} +export interface VotingProceduresJSON { + [k: string]: { + [k: string]: VotingProcedureJSON, + }; +} +export type VotingProposalJSON = VotingProposalEnumJSON; +export type VotingProposalEnumJSON = + | { + ParameterChangeProposalJSON: ParameterChangeProposal, + ... + } + | { + HardForkInitiationProposalJSON: HardForkInitiationProposal, + ... + } + | { + TreasuryWithdrawalsProposalJSON: TreasuryWithdrawalsProposal, + ... + } + | { + NoConfidenceProposalJSON: NoConfidenceProposal, + ... + } + | { + NewCommitteeProposalJSON: NewCommitteeProposal, + ... + } + | { + NewConstitutionProposalJSON: NewConstitutionProposal, + ... + } + | { + InfoProposal: InfoProposal, + ... + }; +export type VotingProposalsJSON = VotingProposalJSON[]; export interface WithdrawalsJSON { [k: string]: ProtocolParamUpdateJSON; } From a14631877f1ef47c04c8d82c16b22f7cc3249f35 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 21 Aug 2023 19:32:10 +0400 Subject: [PATCH 076/349] add voting proposal tag --- rust/src/plutus.rs | 7 +++++++ rust/src/tx_builder/voting_proposal_builder.rs | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/rust/src/plutus.rs b/rust/src/plutus.rs index 61ccf956..6cd013a8 100644 --- a/rust/src/plutus.rs +++ b/rust/src/plutus.rs @@ -982,6 +982,7 @@ pub enum RedeemerTagKind { Cert, Reward, Vote, + VotingProposal, } #[wasm_bindgen] @@ -1014,6 +1015,10 @@ impl RedeemerTag { Self(RedeemerTagKind::Vote) } + pub fn new_voting_proposal() -> Self { + Self(RedeemerTagKind::VotingProposal) + } + pub fn kind(&self) -> RedeemerTagKind { self.0 } @@ -1974,6 +1979,7 @@ impl cbor_event::se::Serialize for RedeemerTagKind { RedeemerTagKind::Cert => serializer.write_unsigned_integer(2u64), RedeemerTagKind::Reward => serializer.write_unsigned_integer(3u64), RedeemerTagKind::Vote => serializer.write_unsigned_integer(4u64), + RedeemerTagKind::VotingProposal => serializer.write_unsigned_integer(5u64), } } } @@ -1987,6 +1993,7 @@ impl Deserialize for RedeemerTagKind { Ok(2) => Ok(RedeemerTagKind::Cert), Ok(3) => Ok(RedeemerTagKind::Reward), Ok(4) => Ok(RedeemerTagKind::Vote), + Ok(5) => Ok(RedeemerTagKind::VotingProposal), Ok(_) | Err(_) => Err(DeserializeFailure::NoVariantMatched.into()), } })() diff --git a/rust/src/tx_builder/voting_proposal_builder.rs b/rust/src/tx_builder/voting_proposal_builder.rs index 13f8b56c..0780fda9 100644 --- a/rust/src/tx_builder/voting_proposal_builder.rs +++ b/rust/src/tx_builder/voting_proposal_builder.rs @@ -43,7 +43,7 @@ impl VotingProposalBuilder { } pub fn get_plutus_witnesses(&self) -> PlutusWitnesses { - let tag = RedeemerTag::new_vote(); + let tag = RedeemerTag::new_voting_proposal(); let mut scripts = PlutusWitnesses::new(); for (i, (_, script_wit)) in self.votes.iter().enumerate() { if let Some(ScriptWitnessType::PlutusScriptWitness(s)) = script_wit { From 23ce464fd10b653c8d29ec34dabae7ce5d37d6a3 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 21 Aug 2023 19:33:42 +0400 Subject: [PATCH 077/349] flow update --- rust/pkg/cardano_serialization_lib.js.flow | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 104bbe76..ca50eebd 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -436,6 +436,7 @@ declare export var RedeemerTagKind: {| +Cert: 2, // 2 +Reward: 3, // 3 +Vote: 4, // 4 + +VotingProposal: 5, // 5 |}; /** @@ -7688,6 +7689,11 @@ declare export class RedeemerTag { */ static new_vote(): RedeemerTag; + /** + * @returns {RedeemerTag} + */ + static new_voting_proposal(): RedeemerTag; + /** * @returns {number} */ @@ -13395,7 +13401,8 @@ export type RedeemerTagKindJSON = | "MintJSON" | "Cert" | "Reward" - | "Vote"; + | "Vote" + | "VotingProposalJSON"; export type RedeemersJSON = RedeemerJSON[]; export type RelayJSON = RelayEnumJSON; export type RelayEnumJSON = From 03ad420fea0bb4799d82e0b3d8dd94f39c8b531b Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 22 Aug 2023 13:19:21 +0400 Subject: [PATCH 078/349] update deposit logic --- rust/src/tx_builder.rs | 23 ++++++++++++++----- .../src/tx_builder/voting_proposal_builder.rs | 5 ++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/rust/src/tx_builder.rs b/rust/src/tx_builder.rs index 3031d2b7..473864a2 100644 --- a/rust/src/tx_builder.rs +++ b/rust/src/tx_builder.rs @@ -1395,14 +1395,25 @@ impl TransactionBuilder { } pub fn get_deposit(&self) -> Result { + let mut total_deposit = Coin::zero(); if let Some(certs) = &self.certs { - Ok(certs.get_certificates_deposit( - &self.config.pool_deposit, - &self.config.key_deposit, - )?) - } else { - Ok(Coin::zero()) + total_deposit = total_deposit.checked_add( + &certs.get_certificates_deposit( + &self.config.pool_deposit, + &self.config.key_deposit, + )?, + )?; + } + + if let Some(voting_proposal_builder) = &self.voting_proposals { + total_deposit = total_deposit.checked_add( + &voting_proposal_builder.get_total_deposit( + &self.config.voting_proposal_deposit, + )?, + )?; } + + Ok(total_deposit) } pub fn get_fee_if_set(&self) -> Option { diff --git a/rust/src/tx_builder/voting_proposal_builder.rs b/rust/src/tx_builder/voting_proposal_builder.rs index 0780fda9..57dcae20 100644 --- a/rust/src/tx_builder/voting_proposal_builder.rs +++ b/rust/src/tx_builder/voting_proposal_builder.rs @@ -77,6 +77,11 @@ impl VotingProposalBuilder { TransactionInputs(inputs) } + pub(crate) fn get_total_deposit(&self, proposal_deposit: &Coin) -> Result { + proposal_deposit.checked_mul(&Coin::from(self.votes.len())) + .ok_or_else(|| JsError::from_str("Overflow when calculating total deposit")) + } + pub(crate) fn get_used_plutus_lang_versions(&self) -> BTreeSet { let mut used_langs = BTreeSet::new(); for (_, script_wit) in &self.votes { From cea1646a9419903b6465c13ddea03b8b70ffee7b Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 22 Aug 2023 15:59:10 +0400 Subject: [PATCH 079/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index cbaa0f06..3d3a91fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "11.4.1-beta.1", + "version": "12.0.0-alpha.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index aca57b7a..e145aecf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "11.4.1-beta.1", + "version": "12.0.0-alpha.1", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index d426d450..e8e7d395 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "11.4.1-beta.1" +version = "12.0.0-alpha.1" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 34c27f0f..f0799b25 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -37,7 +37,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "11.4.1-beta.1" +version = "12.0.0-alpha.1" dependencies = [ "bech32", "cbor_event", From 6105627be5d037e100847e50700f36e15a1661f9 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 22 Aug 2023 16:03:12 +0400 Subject: [PATCH 080/349] fix error map --- rust/src/tx_builder/voting_proposal_builder.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rust/src/tx_builder/voting_proposal_builder.rs b/rust/src/tx_builder/voting_proposal_builder.rs index 57dcae20..e5523525 100644 --- a/rust/src/tx_builder/voting_proposal_builder.rs +++ b/rust/src/tx_builder/voting_proposal_builder.rs @@ -79,7 +79,8 @@ impl VotingProposalBuilder { pub(crate) fn get_total_deposit(&self, proposal_deposit: &Coin) -> Result { proposal_deposit.checked_mul(&Coin::from(self.votes.len())) - .ok_or_else(|| JsError::from_str("Overflow when calculating total deposit")) + .or_else(|e| + Err(JsError::from_str("Overflow when calculating total deposit"))) } pub(crate) fn get_used_plutus_lang_versions(&self) -> BTreeSet { From edf1487c8d8a44c18ec93d0e42e00c0707ecd9cb Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 22 Aug 2023 16:03:45 +0400 Subject: [PATCH 081/349] warn fix --- rust/src/tx_builder/voting_proposal_builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/src/tx_builder/voting_proposal_builder.rs b/rust/src/tx_builder/voting_proposal_builder.rs index e5523525..ef9b97d0 100644 --- a/rust/src/tx_builder/voting_proposal_builder.rs +++ b/rust/src/tx_builder/voting_proposal_builder.rs @@ -79,7 +79,7 @@ impl VotingProposalBuilder { pub(crate) fn get_total_deposit(&self, proposal_deposit: &Coin) -> Result { proposal_deposit.checked_mul(&Coin::from(self.votes.len())) - .or_else(|e| + .or_else(|_| Err(JsError::from_str("Overflow when calculating total deposit"))) } From 0c22fda446a3f86256fcf6ac36b04a8fc1d93fb2 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 22 Aug 2023 19:00:47 +0400 Subject: [PATCH 082/349] add missed bingen --- .../governance/proposals/new_constitution_proposal.rs | 1 + .../governance/proposals/no_confidence_proposal.rs | 1 + rust/src/protocol_types/governance/proposals/voting_proposal.rs | 1 + rust/src/protocol_types/governance/proposals/voting_proposals.rs | 1 + 4 files changed, 4 insertions(+) diff --git a/rust/src/protocol_types/governance/proposals/new_constitution_proposal.rs b/rust/src/protocol_types/governance/proposals/new_constitution_proposal.rs index 93ae3f18..427524ae 100644 --- a/rust/src/protocol_types/governance/proposals/new_constitution_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/new_constitution_proposal.rs @@ -20,6 +20,7 @@ pub struct NewConstitutionProposal { impl_to_from!(NewConstitutionProposal); +#[wasm_bindgen] impl NewConstitutionProposal { pub fn gov_action_id(&self) -> Option { self.gov_action_id.clone() diff --git a/rust/src/protocol_types/governance/proposals/no_confidence_proposal.rs b/rust/src/protocol_types/governance/proposals/no_confidence_proposal.rs index 9c46ffca..0e14d1be 100644 --- a/rust/src/protocol_types/governance/proposals/no_confidence_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/no_confidence_proposal.rs @@ -19,6 +19,7 @@ pub struct NoConfidenceProposal { impl_to_from!(NoConfidenceProposal); +#[wasm_bindgen] impl NoConfidenceProposal { pub fn gov_action_id(&self) -> Option { self.gov_action_id.clone() diff --git a/rust/src/protocol_types/governance/proposals/voting_proposal.rs b/rust/src/protocol_types/governance/proposals/voting_proposal.rs index c46ad3ce..3160a972 100644 --- a/rust/src/protocol_types/governance/proposals/voting_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/voting_proposal.rs @@ -62,6 +62,7 @@ pub struct VotingProposal(pub(crate) VotingProposalEnum); impl_to_from!(VotingProposal); +#[wasm_bindgen] impl VotingProposal { pub fn new_parameter_change_proposal( parameter_change_proposal: &ParameterChangeProposal, diff --git a/rust/src/protocol_types/governance/proposals/voting_proposals.rs b/rust/src/protocol_types/governance/proposals/voting_proposals.rs index 729a5998..f7a7aa1d 100644 --- a/rust/src/protocol_types/governance/proposals/voting_proposals.rs +++ b/rust/src/protocol_types/governance/proposals/voting_proposals.rs @@ -17,6 +17,7 @@ pub struct VotingProposals(pub(crate) Vec); impl_to_from!(VotingProposals); +#[wasm_bindgen] impl VotingProposals { pub fn new() -> Self { Self(Vec::new()) From 85f7ba5efbad3cc7e5bed9ddfd92d7d8d714e742 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 22 Aug 2023 19:00:54 +0400 Subject: [PATCH 083/349] flow update --- rust/pkg/cardano_serialization_lib.js.flow | 265 ++++++++++++++++----- 1 file changed, 212 insertions(+), 53 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index ca50eebd..9c6449c8 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -206,26 +206,6 @@ declare export function decrypt_with_password( data: string ): string; -/** - * @param {string} json - * @param {number} schema - * @returns {PlutusData} - */ -declare export function encode_json_str_to_plutus_datum( - json: string, - schema: number -): PlutusData; - -/** - * @param {PlutusData} datum - * @param {number} schema - * @returns {string} - */ -declare export function decode_plutus_datum_to_json_str( - datum: PlutusData, - schema: number -): string; - /** * @param {Uint8Array} bytes * @returns {TransactionMetadatum} @@ -262,6 +242,26 @@ declare export function decode_metadatum_to_json_str( schema: number ): string; +/** + * @param {string} json + * @param {number} schema + * @returns {PlutusData} + */ +declare export function encode_json_str_to_plutus_datum( + json: string, + schema: number +): PlutusData; + +/** + * @param {PlutusData} datum + * @param {number} schema + * @returns {string} + */ +declare export function decode_plutus_datum_to_json_str( + datum: PlutusData, + schema: number +): string; + /** */ @@ -408,6 +408,39 @@ declare export var VoteKind: {| +Abstain: 2, // 2 |}; +/** + */ + +declare export var VotingProposalKind: {| + +ParameterChangeProposal: 0, // 0 + +HardForkInitiationProposal: 1, // 1 + +TreasuryWithdrawalsProposal: 2, // 2 + +NoConfidenceProposal: 3, // 3 + +NewCommitteeProposal: 4, // 4 + +NewConstitutionProposal: 5, // 5 + +InfoProposal: 6, // 6 +|}; + +/** + */ + +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 +|}; + +/** + */ + +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 +|}; + /** */ @@ -456,39 +489,6 @@ declare export var PlutusDatumSchema: {| +DetailedSchema: 1, // 1 |}; -/** - */ - -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 -|}; - -/** - */ - -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 -|}; - -/** - */ - -declare export var VotingProposalKind: {| - +ParameterChangeProposal: 0, // 0 - +HardForkInitiationProposal: 1, // 1 - +TreasuryWithdrawalsProposal: 2, // 2 - +NoConfidenceProposal: 3, // 3 - +NewCommitteeProposal: 4, // 4 - +NewConstitutionProposal: 5, // 5 - +InfoProposal: 6, // 6 -|}; - /** */ declare export class Address { @@ -5751,6 +5751,32 @@ declare export class NewConstitutionProposal { * @returns {NewConstitutionProposal} */ static from_json(json: string): NewConstitutionProposal; + + /** + * @returns {GovernanceActionId | void} + */ + gov_action_id(): GovernanceActionId | void; + + /** + * @returns {Constitution} + */ + constitution(): Constitution; + + /** + * @param {Constitution} constitution + * @returns {NewConstitutionProposal} + */ + static new(constitution: Constitution): NewConstitutionProposal; + + /** + * @param {GovernanceActionId} gov_action_id + * @param {Constitution} constitution + * @returns {NewConstitutionProposal} + */ + static new_with_action_id( + gov_action_id: GovernanceActionId, + constitution: Constitution + ): NewConstitutionProposal; } /** */ @@ -5794,6 +5820,24 @@ declare export class NoConfidenceProposal { * @returns {NoConfidenceProposal} */ static from_json(json: string): NoConfidenceProposal; + + /** + * @returns {GovernanceActionId | void} + */ + gov_action_id(): GovernanceActionId | void; + + /** + * @returns {NoConfidenceProposal} + */ + static new(): NoConfidenceProposal; + + /** + * @param {GovernanceActionId} gov_action_id + * @returns {NoConfidenceProposal} + */ + static new_with_action_id( + gov_action_id: GovernanceActionId + ): NoConfidenceProposal; } /** */ @@ -12733,6 +12777,100 @@ declare export class VotingProposal { * @returns {VotingProposal} */ static from_json(json: string): VotingProposal; + + /** + * @param {ParameterChangeProposal} parameter_change_proposal + * @returns {VotingProposal} + */ + static new_parameter_change_proposal( + parameter_change_proposal: ParameterChangeProposal + ): VotingProposal; + + /** + * @param {HardForkInitiationProposal} hard_fork_initiation_proposal + * @returns {VotingProposal} + */ + static new_hard_fork_initiation_proposal( + hard_fork_initiation_proposal: HardForkInitiationProposal + ): VotingProposal; + + /** + * @param {TreasuryWithdrawalsProposal} treasury_withdrawals_proposal + * @returns {VotingProposal} + */ + static new_treasury_withdrawals_proposal( + treasury_withdrawals_proposal: TreasuryWithdrawalsProposal + ): VotingProposal; + + /** + * @param {NoConfidenceProposal} no_confidence_proposal + * @returns {VotingProposal} + */ + static new_no_confidence_proposal( + no_confidence_proposal: NoConfidenceProposal + ): VotingProposal; + + /** + * @param {NewCommitteeProposal} new_committee_proposal + * @returns {VotingProposal} + */ + static new_new_committee_proposal( + new_committee_proposal: NewCommitteeProposal + ): VotingProposal; + + /** + * @param {NewConstitutionProposal} new_constitution_proposal + * @returns {VotingProposal} + */ + static new_new_constitution_proposal( + new_constitution_proposal: NewConstitutionProposal + ): VotingProposal; + + /** + * @param {InfoProposal} info_proposal + * @returns {VotingProposal} + */ + static new_info_proposal(info_proposal: InfoProposal): VotingProposal; + + /** + * @returns {number} + */ + kind(): number; + + /** + * @returns {ParameterChangeProposal | void} + */ + as_parameter_change_proposal(): ParameterChangeProposal | void; + + /** + * @returns {HardForkInitiationProposal | void} + */ + as_hard_fork_initiation_proposal(): HardForkInitiationProposal | void; + + /** + * @returns {TreasuryWithdrawalsProposal | void} + */ + as_treasury_withdrawals_proposal(): TreasuryWithdrawalsProposal | void; + + /** + * @returns {NoConfidenceProposal | void} + */ + as_no_confidence_proposal(): NoConfidenceProposal | void; + + /** + * @returns {NewCommitteeProposal | void} + */ + as_new_committee_proposal(): NewCommitteeProposal | void; + + /** + * @returns {NewConstitutionProposal | void} + */ + as_new_constitution_proposal(): NewConstitutionProposal | void; + + /** + * @returns {InfoProposal | void} + */ + as_info_proposal(): InfoProposal | void; } /** */ @@ -12820,6 +12958,27 @@ declare export class VotingProposals { * @returns {VotingProposals} */ static from_json(json: string): VotingProposals; + + /** + * @returns {VotingProposals} + */ + static new(): VotingProposals; + + /** + * @returns {number} + */ + len(): number; + + /** + * @param {number} index + * @returns {VotingProposal} + */ + get(index: number): VotingProposal; + + /** + * @param {VotingProposal} proposal + */ + add(proposal: VotingProposal): void; } /** */ From 0fb6adac8abc45e2482efa1cdcd9241a0753ecca Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 22 Aug 2023 19:01:47 +0400 Subject: [PATCH 084/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3d3a91fc..c34b0051 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.1", + "version": "12.0.0-alpha.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index e145aecf..e6d4e509 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.1", + "version": "12.0.0-alpha.2", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index e8e7d395..38c3cd4f 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.1" +version = "12.0.0-alpha.2" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index f0799b25..0fe15e14 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -37,7 +37,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.1" +version = "12.0.0-alpha.2" dependencies = [ "bech32", "cbor_event", From 9da4b564765544f7dca3d186bcbc6a8e066afd33 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 23 Aug 2023 00:33:28 +0400 Subject: [PATCH 085/349] fix serialization --- .../governance/voting_procedures.rs | 90 +++++++++++++++++++ rust/src/serialization/governance/anchor.rs | 12 +-- .../governance/voting_procedure.rs | 4 +- 3 files changed, 94 insertions(+), 12 deletions(-) diff --git a/rust/src/protocol_types/governance/voting_procedures.rs b/rust/src/protocol_types/governance/voting_procedures.rs index b58e305c..f2809202 100644 --- a/rust/src/protocol_types/governance/voting_procedures.rs +++ b/rust/src/protocol_types/governance/voting_procedures.rs @@ -1,5 +1,9 @@ use crate::*; +use schemars::gen::SchemaGenerator; +use schemars::schema::Schema; use std::collections::BTreeMap; +use std::vec::Vec; +use serde::ser::SerializeSeq; #[derive( Clone, @@ -13,6 +17,37 @@ use std::collections::BTreeMap; serde::Deserialize, JsonSchema, )] +struct VoterVotes { + voter: Voter, + votes: BTreeSet, +} + +#[derive( + Clone, + Debug, + Eq, + Ord, + PartialEq, + PartialOrd, + Hash, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +struct Vote { + action_id: GovernanceActionId, + voting_procedure: VotingProcedure, +} + +#[derive( + Clone, + Debug, + Eq, + Ord, + PartialEq, + PartialOrd, + Hash, +)] #[wasm_bindgen] pub struct VotingProcedures( pub(crate) BTreeMap>, @@ -50,3 +85,58 @@ impl VotingProcedures { ) } } + +impl JsonSchema for VotingProcedures { + fn is_referenceable() -> bool { + Vec::::is_referenceable() + } + + fn schema_name() -> String { + "VotingProcedures".to_string() + } + + fn json_schema(gen: &mut SchemaGenerator) -> Schema { + Vec::::json_schema(gen) + } +} + +impl serde::ser::Serialize for VotingProcedures { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + let mut seq = serializer.serialize_seq(Some(self.0.len()))?; + for (voter, votes) in &self.0 { + let voterVotes = VoterVotes { + voter: voter.clone(), + votes: votes + .iter() + .map(|(action_id, voting_procedure)| Vote { + action_id: action_id.clone(), + voting_procedure: voting_procedure.clone(), + }) + .collect(), + }; + seq.serialize_element(&voterVotes)?; + } + seq.end() + } +} + +impl<'de> serde::de::Deserialize<'de> for VotingProcedures { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let all_votes: Vec = serde::de::Deserialize::deserialize(deserializer)?; + let mut voting_procedures = VotingProcedures::new(); + for votes in all_votes { + let mut voter_votes = BTreeMap::new(); + for vote in votes.votes { + voter_votes.insert(vote.action_id, vote.voting_procedure); + } + voting_procedures.0.insert(votes.voter, voter_votes); + } + Ok(voting_procedures) + } +} diff --git a/rust/src/serialization/governance/anchor.rs b/rust/src/serialization/governance/anchor.rs index c3924581..dc3d93e3 100644 --- a/rust/src/serialization/governance/anchor.rs +++ b/rust/src/serialization/governance/anchor.rs @@ -1,4 +1,5 @@ use crate::*; +use crate::serialization::struct_checks::check_len; impl cbor_event::se::Serialize for Anchor { fn serialize<'se, W: Write>( @@ -17,16 +18,7 @@ impl Deserialize for Anchor { (|| -> Result<_, DeserializeError> { let len = raw.array()?; - if let cbor_event::Len::Len(n) = len { - if n != 2 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 2, - len, - "(anchor_url, anchor_data_hash)", - )) - .into()); - } - } + check_len(len, 2, "(anchor_url, anchor_data_hash)")?; let anchor_url = URL::deserialize(raw).map_err(|e| e.annotate("anchor_url"))?; diff --git a/rust/src/serialization/governance/voting_procedure.rs b/rust/src/serialization/governance/voting_procedure.rs index a12c0c1d..5ce30c10 100644 --- a/rust/src/serialization/governance/voting_procedure.rs +++ b/rust/src/serialization/governance/voting_procedure.rs @@ -17,7 +17,7 @@ impl cbor_event::se::Serialize for VotingProcedure { serializer.write_unsigned_integer(2u64)?; } }; - self.anchor.serialize(serializer)?; + self.anchor.serialize_nullable(serializer)?; Ok(serializer) } } @@ -31,7 +31,7 @@ impl Deserialize for VotingProcedure { return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( 2, len, - "[vote, anchor]", + "[vote, anchor / null]", )) .into()); } From 6a107a1aea557146af3f8ba6bb3768d358319981 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 23 Aug 2023 00:34:43 +0400 Subject: [PATCH 086/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index c34b0051..78e7eb29 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.2", + "version": "12.0.0-alpha.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index e6d4e509..76874168 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.2", + "version": "12.0.0-alpha.3", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 38c3cd4f..e3d37785 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.2" +version = "12.0.0-alpha.3" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 0fe15e14..4d309b4d 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -37,7 +37,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.2" +version = "12.0.0-alpha.3" dependencies = [ "bech32", "cbor_event", From b98ed543a05db176cddb972315fe7539d95d738b Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 29 Aug 2023 18:41:16 +0500 Subject: [PATCH 087/349] move address tests --- rust/src/address.rs | 595 +------------------------------------- rust/src/tests/address.rs | 573 ++++++++++++++++++++++++++++++++++++ 2 files changed, 582 insertions(+), 586 deletions(-) create mode 100644 rust/src/tests/address.rs diff --git a/rust/src/address.rs b/rust/src/address.rs index 59d8009a..0c7c2b22 100644 --- a/rust/src/address.rs +++ b/rust/src/address.rs @@ -5,7 +5,7 @@ use ed25519_bip32::XPub; // returns (Number represented, bytes read) if valid encoding // or None if decoding prematurely finished -fn variable_nat_decode(bytes: &[u8]) -> Option<(u64, usize)> { +pub(crate) fn variable_nat_decode(bytes: &[u8]) -> Option<(u64, usize)> { let mut output = 0u128; let mut bytes_read = 0; for byte in bytes { @@ -21,7 +21,7 @@ fn variable_nat_decode(bytes: &[u8]) -> Option<(u64, usize)> { None } -fn variable_nat_encode(mut num: u64) -> Vec { +pub(crate) fn variable_nat_encode(mut num: u64) -> Vec { let mut output = vec![num as u8 & 0x7F]; num /= 128; while num > 0 { @@ -811,9 +811,9 @@ impl Deserialize for RewardAddress { #[wasm_bindgen] #[derive(Debug, Clone, Eq, Ord, PartialEq, PartialOrd)] pub struct Pointer { - slot: BigNum, - tx_index: BigNum, - cert_index: BigNum, + pub(crate) slot: BigNum, + pub(crate) tx_index: BigNum, + pub(crate) cert_index: BigNum, } #[wasm_bindgen] @@ -869,9 +869,9 @@ impl Pointer { #[wasm_bindgen] #[derive(Debug, Clone, Eq, Ord, PartialEq, PartialOrd)] pub struct PointerAddress { - network: u8, - payment: StakeCredential, - stake: Pointer, + pub(crate) network: u8, + pub(crate) payment: StakeCredential, + pub(crate) stake: Pointer, } #[wasm_bindgen] @@ -902,581 +902,4 @@ impl PointerAddress { _ => None, } } -} - -#[cfg(test)] -mod tests { - use super::*; - use crypto::*; - - #[test] - fn variable_nat_encoding() { - let cases = [0u64, 127u64, 128u64, 255u64, 256275757658493284u64]; - for case in cases.iter() { - let encoded = variable_nat_encode(*case); - let decoded = variable_nat_decode(&encoded).unwrap().0; - assert_eq!(*case, decoded); - } - } - - #[test] - fn variable_nat_decode_too_big() { - let too_big = [129, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127]; - assert_eq!(None, variable_nat_decode(&too_big)); - } - - #[test] - fn base_serialize_consistency() { - let base = BaseAddress::new( - 5, - &StakeCredential::from_keyhash(&Ed25519KeyHash::from([23; Ed25519KeyHash::BYTE_COUNT])), - &StakeCredential::from_scripthash(&ScriptHash::from([42; ScriptHash::BYTE_COUNT])), - ); - let addr = base.to_address(); - let addr2 = Address::from_bytes(addr.to_bytes()).unwrap(); - assert_eq!(addr.to_bytes(), addr2.to_bytes()); - } - - #[test] - fn ptr_serialize_consistency() { - let ptr = PointerAddress::new( - 25, - &StakeCredential::from_keyhash(&Ed25519KeyHash::from([23; Ed25519KeyHash::BYTE_COUNT])), - &Pointer::new_pointer(&to_bignum(2354556573), &to_bignum(127), &to_bignum(0)), - ); - let addr = ptr.to_address(); - let addr2 = Address::from_bytes(addr.to_bytes()).unwrap(); - assert_eq!(addr.to_bytes(), addr2.to_bytes()); - } - - #[test] - fn enterprise_serialize_consistency() { - let enterprise = EnterpriseAddress::new( - 64, - &StakeCredential::from_keyhash(&Ed25519KeyHash::from([23; Ed25519KeyHash::BYTE_COUNT])), - ); - let addr = enterprise.to_address(); - let addr2 = Address::from_bytes(addr.to_bytes()).unwrap(); - assert_eq!(addr.to_bytes(), addr2.to_bytes()); - } - - #[test] - fn reward_serialize_consistency() { - let reward = RewardAddress::new( - 9, - &StakeCredential::from_scripthash(&ScriptHash::from([127; Ed25519KeyHash::BYTE_COUNT])), - ); - let addr = reward.to_address(); - let addr2 = Address::from_bytes(addr.to_bytes()).unwrap(); - assert_eq!(addr.to_bytes(), addr2.to_bytes()); - } - - fn root_key_12() -> Bip32PrivateKey { - // test walk nut penalty hip pave soap entry language right filter choice - let entropy = [ - 0xdf, 0x9e, 0xd2, 0x5e, 0xd1, 0x46, 0xbf, 0x43, 0x33, 0x6a, 0x5d, 0x7c, 0xf7, 0x39, - 0x59, 0x94, - ]; - Bip32PrivateKey::from_bip39_entropy(&entropy, &[]) - } - - fn root_key_15() -> Bip32PrivateKey { - // art forum devote street sure rather head chuckle guard poverty release quote oak craft enemy - let entropy = [ - 0x0c, 0xcb, 0x74, 0xf3, 0x6b, 0x7d, 0xa1, 0x64, 0x9a, 0x81, 0x44, 0x67, 0x55, 0x22, - 0xd4, 0xd8, 0x09, 0x7c, 0x64, 0x12, - ]; - Bip32PrivateKey::from_bip39_entropy(&entropy, &[]) - } - - fn root_key_24() -> Bip32PrivateKey { - let entropy = [ - 0x4e, 0x82, 0x8f, 0x9a, 0x67, 0xdd, 0xcf, 0xf0, 0xe6, 0x39, 0x1a, 0xd4, 0xf2, 0x6d, - 0xdb, 0x75, 0x79, 0xf5, 0x9b, 0xa1, 0x4b, 0x6d, 0xd4, 0xba, 0xf6, 0x3d, 0xcf, 0xdb, - 0x9d, 0x24, 0x20, 0xda, - ]; - Bip32PrivateKey::from_bip39_entropy(&entropy, &[]) - } - - fn harden(index: u32) -> u32 { - index | 0x80_00_00_00 - } - - #[test] - fn bech32_parsing() { - let addr = - Address::from_bech32("addr1u8pcjgmx7962w6hey5hhsd502araxp26kdtgagakhaqtq8sxy9w7g") - .unwrap(); - assert_eq!( - addr.to_bech32(Some("foobar".to_string())).unwrap(), - "foobar1u8pcjgmx7962w6hey5hhsd502araxp26kdtgagakhaqtq8s92n4tm" - ); - } - - #[test] - fn byron_magic_parsing() { - // mainnet address w/ protocol magic omitted - let addr = ByronAddress::from_base58( - "Ae2tdPwUPEZ4YjgvykNpoFeYUxoyhNj2kg8KfKWN2FizsSpLUPv68MpTVDo", - ) - .unwrap(); - assert_eq!( - addr.byron_protocol_magic(), - NetworkInfo::mainnet().protocol_magic() - ); - assert_eq!( - addr.network_id().unwrap(), - NetworkInfo::mainnet().network_id() - ); - - // original Byron testnet address - let addr = ByronAddress::from_base58( - "2cWKMJemoBaipzQe9BArYdo2iPUfJQdZAjm4iCzDA1AfNxJSTgm9FZQTmFCYhKkeYrede", - ) - .unwrap(); - assert_eq!( - addr.byron_protocol_magic(), - NetworkInfo::testnet().protocol_magic() - ); - assert_eq!( - addr.network_id().unwrap(), - NetworkInfo::testnet().network_id() - ); - } - - #[test] - fn bip32_12_base() { - let spend = root_key_12() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let stake = root_key_12() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - assert_eq!(addr_net_0.to_bech32(None).unwrap(), "addr_test1qz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3jcu5d8ps7zex2k2xt3uqxgjqnnj83ws8lhrn648jjxtwq2ytjqp"); - let addr_net_3 = BaseAddress::new( - NetworkInfo::mainnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - assert_eq!(addr_net_3.to_bech32(None).unwrap(), "addr1qx2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3jcu5d8ps7zex2k2xt3uqxgjqnnj83ws8lhrn648jjxtwqfjkjv7"); - } - - #[test] - fn bip32_12_enterprise() { - let spend = root_key_12() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let addr_net_0 = - EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(); - assert_eq!( - addr_net_0.to_bech32(None).unwrap(), - "addr_test1vz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzerspjrlsz" - ); - let addr_net_3 = - EnterpriseAddress::new(NetworkInfo::mainnet().network_id(), &spend_cred).to_address(); - assert_eq!( - addr_net_3.to_bech32(None).unwrap(), - "addr1vx2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzers66hrl8" - ); - } - - #[test] - fn bip32_12_pointer() { - let spend = root_key_12() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let addr_net_0 = PointerAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &Pointer::new_pointer(&to_bignum(1), &to_bignum(2), &to_bignum(3)), - ) - .to_address(); - assert_eq!( - addr_net_0.to_bech32(None).unwrap(), - "addr_test1gz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzerspqgpsqe70et" - ); - let addr_net_3 = PointerAddress::new( - NetworkInfo::mainnet().network_id(), - &spend_cred, - &Pointer::new_pointer(&to_bignum(24157), &to_bignum(177), &to_bignum(42)), - ) - .to_address(); - assert_eq!( - addr_net_3.to_bech32(None).unwrap(), - "addr1gx2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer5ph3wczvf2w8lunk" - ); - } - - #[test] - fn bip32_15_base() { - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - assert_eq!(addr_net_0.to_bech32(None).unwrap(), "addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w"); - let addr_net_3 = BaseAddress::new( - NetworkInfo::mainnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - assert_eq!(addr_net_3.to_bech32(None).unwrap(), "addr1q9u5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qld6xc3"); - } - - #[test] - fn bip32_15_enterprise() { - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let addr_net_0 = - EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(); - assert_eq!( - addr_net_0.to_bech32(None).unwrap(), - "addr_test1vpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5eg57c2qv" - ); - let addr_net_3 = - EnterpriseAddress::new(NetworkInfo::mainnet().network_id(), &spend_cred).to_address(); - assert_eq!( - addr_net_3.to_bech32(None).unwrap(), - "addr1v9u5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5eg0kvk0f" - ); - } - - #[test] - fn bip32_15_pointer() { - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let addr_net_0 = PointerAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &Pointer::new_pointer(&to_bignum(1), &to_bignum(2), &to_bignum(3)), - ) - .to_address(); - assert_eq!( - addr_net_0.to_bech32(None).unwrap(), - "addr_test1gpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5egpqgpsdhdyc0" - ); - let addr_net_3 = PointerAddress::new( - NetworkInfo::mainnet().network_id(), - &spend_cred, - &Pointer::new_pointer(&to_bignum(24157), &to_bignum(177), &to_bignum(42)), - ) - .to_address(); - assert_eq!( - addr_net_3.to_bech32(None).unwrap(), - "addr1g9u5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5evph3wczvf2kd5vam" - ); - } - - #[test] - fn parse_redeem_address() { - assert!(ByronAddress::is_valid( - "Ae2tdPwUPEZ3MHKkpT5Bpj549vrRH7nBqYjNXnCV8G2Bc2YxNcGHEa8ykDp" - )); - let byron_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZ3MHKkpT5Bpj549vrRH7nBqYjNXnCV8G2Bc2YxNcGHEa8ykDp", - ) - .unwrap(); - assert_eq!( - byron_addr.to_base58(), - "Ae2tdPwUPEZ3MHKkpT5Bpj549vrRH7nBqYjNXnCV8G2Bc2YxNcGHEa8ykDp" - ); - let byron_addr2 = ByronAddress::from_bytes(byron_addr.to_bytes()).unwrap(); - assert_eq!( - byron_addr2.to_base58(), - "Ae2tdPwUPEZ3MHKkpT5Bpj549vrRH7nBqYjNXnCV8G2Bc2YxNcGHEa8ykDp" - ); - } - - #[test] - fn bip32_15_byron() { - let byron_key = root_key_15() - .derive(harden(44)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let byron_addr = - ByronAddress::icarus_from_key(&byron_key, NetworkInfo::mainnet().protocol_magic()); - assert_eq!( - byron_addr.to_base58(), - "Ae2tdPwUPEZHtBmjZBF4YpMkK9tMSPTE2ADEZTPN97saNkhG78TvXdp3GDk" - ); - assert!(ByronAddress::is_valid( - "Ae2tdPwUPEZHtBmjZBF4YpMkK9tMSPTE2ADEZTPN97saNkhG78TvXdp3GDk" - )); - assert_eq!(byron_addr.network_id().unwrap(), 0b0001); - - let byron_addr_2 = - ByronAddress::from_address(&Address::from_bytes(byron_addr.to_bytes()).unwrap()) - .unwrap(); - assert_eq!(byron_addr.to_base58(), byron_addr_2.to_base58()); - } - - #[test] - fn bip32_24_base() { - let spend = root_key_24() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let stake = root_key_24() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - assert_eq!(addr_net_0.to_bech32(None).unwrap(), "addr_test1qqy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmn8k8ttq8f3gag0h89aepvx3xf69g0l9pf80tqv7cve0l33sw96paj"); - let addr_net_3 = BaseAddress::new( - NetworkInfo::mainnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - assert_eq!(addr_net_3.to_bech32(None).unwrap(), "addr1qyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmn8k8ttq8f3gag0h89aepvx3xf69g0l9pf80tqv7cve0l33sdn8p3d"); - } - - #[test] - fn bip32_24_enterprise() { - let spend = root_key_24() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let addr_net_0 = - EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(); - assert_eq!( - addr_net_0.to_bech32(None).unwrap(), - "addr_test1vqy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqtjtf68" - ); - let addr_net_3 = - EnterpriseAddress::new(NetworkInfo::mainnet().network_id(), &spend_cred).to_address(); - assert_eq!( - addr_net_3.to_bech32(None).unwrap(), - "addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z" - ); - } - - #[test] - fn bip32_24_pointer() { - let spend = root_key_24() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let addr_net_0 = PointerAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &Pointer::new_pointer(&to_bignum(1), &to_bignum(2), &to_bignum(3)), - ) - .to_address(); - assert_eq!( - addr_net_0.to_bech32(None).unwrap(), - "addr_test1gqy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqpqgps5mee0p" - ); - let addr_net_3 = PointerAddress::new( - NetworkInfo::mainnet().network_id(), - &spend_cred, - &Pointer::new_pointer(&to_bignum(24157), &to_bignum(177), &to_bignum(42)), - ) - .to_address(); - assert_eq!( - addr_net_3.to_bech32(None).unwrap(), - "addr1gyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnyph3wczvf2dqflgt" - ); - } - - #[test] - fn bip32_12_reward() { - let staking_key = root_key_12() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - let staking_cred = StakeCredential::from_keyhash(&staking_key.to_raw_key().hash()); - let addr_net_0 = - RewardAddress::new(NetworkInfo::testnet().network_id(), &staking_cred).to_address(); - assert_eq!( - addr_net_0.to_bech32(None).unwrap(), - "stake_test1uqevw2xnsc0pvn9t9r9c7qryfqfeerchgrlm3ea2nefr9hqp8n5xl" - ); - let addr_net_3 = - RewardAddress::new(NetworkInfo::mainnet().network_id(), &staking_cred).to_address(); - assert_eq!( - addr_net_3.to_bech32(None).unwrap(), - "stake1uyevw2xnsc0pvn9t9r9c7qryfqfeerchgrlm3ea2nefr9hqxdekzz" - ); - } - - #[test] - fn bip32_24_base_multisig_hd_derivation() { - let spend = root_key_24() - .derive(harden(1854)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let stake = root_key_24() - .derive(harden(1854)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - assert_eq!(addr_net_0.to_bech32(None).unwrap(), "addr_test1qz8fg2e9yn0ga6sav0760cxmx0antql96mfuhqgzcc5swugw2jqqlugnx9qjep9xvcx40z0zfyep55r2t3lav5smyjrs96cusg"); - let addr_net_3 = BaseAddress::new( - NetworkInfo::mainnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - assert_eq!(addr_net_3.to_bech32(None).unwrap(), "addr1qx8fg2e9yn0ga6sav0760cxmx0antql96mfuhqgzcc5swugw2jqqlugnx9qjep9xvcx40z0zfyep55r2t3lav5smyjrsxv9uuh"); - } - - #[test] - fn multisig_from_script() { - let spend = root_key_24() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - - let mut pubkey_native_scripts = NativeScripts::new(); - - let spending_hash = spend.to_raw_key().hash(); - pubkey_native_scripts.add(&NativeScript::new_script_pubkey(&ScriptPubkey::new( - &spending_hash, - ))); - let oneof_native_script = - NativeScript::new_script_n_of_k(&ScriptNOfK::new(1, &pubkey_native_scripts)); - - let script_hash = ScriptHash::from_bytes(oneof_native_script.hash().to_bytes()).unwrap(); - - let spend_cred = StakeCredential::from_scripthash(&script_hash); - let stake_cred = StakeCredential::from_scripthash(&script_hash); - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - assert_eq!(addr_net_0.to_bech32(None).unwrap(), "addr_test1xr0de0mz3m9xmgtlmqqzu06s0uvfsczskdec8k7v4jhr7077mjlk9rk2dkshlkqq9cl4qlccnps9pvmns0duet9w8uls8flvxc"); - let addr_net_3 = BaseAddress::new( - NetworkInfo::mainnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - assert_eq!(addr_net_3.to_bech32(None).unwrap(), "addr1x80de0mz3m9xmgtlmqqzu06s0uvfsczskdec8k7v4jhr7077mjlk9rk2dkshlkqq9cl4qlccnps9pvmns0duet9w8ulsylzv28"); - } - - #[test] - fn pointer_address_big() { - let addr = Address::from_bech32("addr_test1grqe6lg9ay8wkcu5k5e38lne63c80h3nq6xxhqfmhewf645pllllllllllll7lupllllllllllll7lupllllllllllll7lc9wayvj").unwrap(); - let ptr = PointerAddress::from_address(&addr).unwrap().stake; - assert_eq!(u64::MAX, from_bignum(&ptr.slot)); - assert_eq!(u64::MAX, from_bignum(&ptr.tx_index)); - assert_eq!(u64::MAX, from_bignum(&ptr.cert_index)); - } - - #[test] - fn point_address_old() { - let p1 = Pointer::new(10, 20, 30); - let p2 = Pointer::new_pointer(&to_bignum(10), &to_bignum(20), &to_bignum(30)); - assert_eq!(p1, p2); - } - - #[test] - fn prepod_network_id_test() { - let address = "KjgoiXJS2coTnqpCLHXFtd89Hv9ttjsE6yW4msyLXFNkykUpTsyBs85r2rDDia2uKrhdpGKCJnmFXwvPSWLe75564ixZWdTxRh7TnuaDLnHx"; - let network_id = ByronAddress::from_base58(address).unwrap().to_address().network_id().unwrap(); - assert_eq!(network_id, NetworkInfo::testnet_preprod().network_id()); - } -} +} \ No newline at end of file diff --git a/rust/src/tests/address.rs b/rust/src/tests/address.rs new file mode 100644 index 00000000..34bd63c1 --- /dev/null +++ b/rust/src/tests/address.rs @@ -0,0 +1,573 @@ +use crate::*; +use crypto::*; + +#[test] +fn variable_nat_encoding() { + let cases = [0u64, 127u64, 128u64, 255u64, 256275757658493284u64]; + for case in cases.iter() { + let encoded = variable_nat_encode(*case); + let decoded = variable_nat_decode(&encoded).unwrap().0; + assert_eq!(*case, decoded); + } +} + +#[test] +fn variable_nat_decode_too_big() { + let too_big = [129, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127]; + assert_eq!(None, variable_nat_decode(&too_big)); +} + +#[test] +fn base_serialize_consistency() { + let base = BaseAddress::new( + 5, + &StakeCredential::from_keyhash(&Ed25519KeyHash::from([23; Ed25519KeyHash::BYTE_COUNT])), + &StakeCredential::from_scripthash(&ScriptHash::from([42; ScriptHash::BYTE_COUNT])), + ); + let addr = base.to_address(); + let addr2 = Address::from_bytes(addr.to_bytes()).unwrap(); + assert_eq!(addr.to_bytes(), addr2.to_bytes()); +} + +#[test] +fn ptr_serialize_consistency() { + let ptr = PointerAddress::new( + 25, + &StakeCredential::from_keyhash(&Ed25519KeyHash::from([23; Ed25519KeyHash::BYTE_COUNT])), + &Pointer::new_pointer(&to_bignum(2354556573), &to_bignum(127), &to_bignum(0)), + ); + let addr = ptr.to_address(); + let addr2 = Address::from_bytes(addr.to_bytes()).unwrap(); + assert_eq!(addr.to_bytes(), addr2.to_bytes()); +} + +#[test] +fn enterprise_serialize_consistency() { + let enterprise = EnterpriseAddress::new( + 64, + &StakeCredential::from_keyhash(&Ed25519KeyHash::from([23; Ed25519KeyHash::BYTE_COUNT])), + ); + let addr = enterprise.to_address(); + let addr2 = Address::from_bytes(addr.to_bytes()).unwrap(); + assert_eq!(addr.to_bytes(), addr2.to_bytes()); +} + +#[test] +fn reward_serialize_consistency() { + let reward = RewardAddress::new( + 9, + &StakeCredential::from_scripthash(&ScriptHash::from([127; Ed25519KeyHash::BYTE_COUNT])), + ); + let addr = reward.to_address(); + let addr2 = Address::from_bytes(addr.to_bytes()).unwrap(); + assert_eq!(addr.to_bytes(), addr2.to_bytes()); +} + +fn root_key_12() -> Bip32PrivateKey { + // test walk nut penalty hip pave soap entry language right filter choice + let entropy = [ + 0xdf, 0x9e, 0xd2, 0x5e, 0xd1, 0x46, 0xbf, 0x43, 0x33, 0x6a, 0x5d, 0x7c, 0xf7, 0x39, 0x59, + 0x94, + ]; + Bip32PrivateKey::from_bip39_entropy(&entropy, &[]) +} + +fn root_key_15() -> Bip32PrivateKey { + // art forum devote street sure rather head chuckle guard poverty release quote oak craft enemy + let entropy = [ + 0x0c, 0xcb, 0x74, 0xf3, 0x6b, 0x7d, 0xa1, 0x64, 0x9a, 0x81, 0x44, 0x67, 0x55, 0x22, 0xd4, + 0xd8, 0x09, 0x7c, 0x64, 0x12, + ]; + Bip32PrivateKey::from_bip39_entropy(&entropy, &[]) +} + +fn root_key_24() -> Bip32PrivateKey { + let entropy = [ + 0x4e, 0x82, 0x8f, 0x9a, 0x67, 0xdd, 0xcf, 0xf0, 0xe6, 0x39, 0x1a, 0xd4, 0xf2, 0x6d, 0xdb, + 0x75, 0x79, 0xf5, 0x9b, 0xa1, 0x4b, 0x6d, 0xd4, 0xba, 0xf6, 0x3d, 0xcf, 0xdb, 0x9d, 0x24, + 0x20, 0xda, + ]; + Bip32PrivateKey::from_bip39_entropy(&entropy, &[]) +} + +fn harden(index: u32) -> u32 { + index | 0x80_00_00_00 +} + +#[test] +fn bech32_parsing() { + let addr = + Address::from_bech32("addr1u8pcjgmx7962w6hey5hhsd502araxp26kdtgagakhaqtq8sxy9w7g").unwrap(); + assert_eq!( + addr.to_bech32(Some("foobar".to_string())).unwrap(), + "foobar1u8pcjgmx7962w6hey5hhsd502araxp26kdtgagakhaqtq8s92n4tm" + ); +} + +#[test] +fn byron_magic_parsing() { + // mainnet address w/ protocol magic omitted + let addr = + ByronAddress::from_base58("Ae2tdPwUPEZ4YjgvykNpoFeYUxoyhNj2kg8KfKWN2FizsSpLUPv68MpTVDo") + .unwrap(); + assert_eq!( + addr.byron_protocol_magic(), + NetworkInfo::mainnet().protocol_magic() + ); + assert_eq!( + addr.network_id().unwrap(), + NetworkInfo::mainnet().network_id() + ); + + // original Byron testnet address + let addr = ByronAddress::from_base58( + "2cWKMJemoBaipzQe9BArYdo2iPUfJQdZAjm4iCzDA1AfNxJSTgm9FZQTmFCYhKkeYrede", + ) + .unwrap(); + assert_eq!( + addr.byron_protocol_magic(), + NetworkInfo::testnet().protocol_magic() + ); + assert_eq!( + addr.network_id().unwrap(), + NetworkInfo::testnet().network_id() + ); +} + +#[test] +fn bip32_12_base() { + let spend = root_key_12() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let stake = root_key_12() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + assert_eq!(addr_net_0.to_bech32(None).unwrap(), "addr_test1qz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3jcu5d8ps7zex2k2xt3uqxgjqnnj83ws8lhrn648jjxtwq2ytjqp"); + let addr_net_3 = BaseAddress::new( + NetworkInfo::mainnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + assert_eq!(addr_net_3.to_bech32(None).unwrap(), "addr1qx2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3jcu5d8ps7zex2k2xt3uqxgjqnnj83ws8lhrn648jjxtwqfjkjv7"); +} + +#[test] +fn bip32_12_enterprise() { + let spend = root_key_12() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); + let addr_net_0 = + EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(); + assert_eq!( + addr_net_0.to_bech32(None).unwrap(), + "addr_test1vz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzerspjrlsz" + ); + let addr_net_3 = + EnterpriseAddress::new(NetworkInfo::mainnet().network_id(), &spend_cred).to_address(); + assert_eq!( + addr_net_3.to_bech32(None).unwrap(), + "addr1vx2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzers66hrl8" + ); +} + +#[test] +fn bip32_12_pointer() { + let spend = root_key_12() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); + let addr_net_0 = PointerAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &Pointer::new_pointer(&to_bignum(1), &to_bignum(2), &to_bignum(3)), + ) + .to_address(); + assert_eq!( + addr_net_0.to_bech32(None).unwrap(), + "addr_test1gz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzerspqgpsqe70et" + ); + let addr_net_3 = PointerAddress::new( + NetworkInfo::mainnet().network_id(), + &spend_cred, + &Pointer::new_pointer(&to_bignum(24157), &to_bignum(177), &to_bignum(42)), + ) + .to_address(); + assert_eq!( + addr_net_3.to_bech32(None).unwrap(), + "addr1gx2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer5ph3wczvf2w8lunk" + ); +} + +#[test] +fn bip32_15_base() { + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + assert_eq!(addr_net_0.to_bech32(None).unwrap(), "addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w"); + let addr_net_3 = BaseAddress::new( + NetworkInfo::mainnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + assert_eq!(addr_net_3.to_bech32(None).unwrap(), "addr1q9u5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qld6xc3"); +} + +#[test] +fn bip32_15_enterprise() { + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); + let addr_net_0 = + EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(); + assert_eq!( + addr_net_0.to_bech32(None).unwrap(), + "addr_test1vpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5eg57c2qv" + ); + let addr_net_3 = + EnterpriseAddress::new(NetworkInfo::mainnet().network_id(), &spend_cred).to_address(); + assert_eq!( + addr_net_3.to_bech32(None).unwrap(), + "addr1v9u5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5eg0kvk0f" + ); +} + +#[test] +fn bip32_15_pointer() { + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); + let addr_net_0 = PointerAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &Pointer::new_pointer(&to_bignum(1), &to_bignum(2), &to_bignum(3)), + ) + .to_address(); + assert_eq!( + addr_net_0.to_bech32(None).unwrap(), + "addr_test1gpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5egpqgpsdhdyc0" + ); + let addr_net_3 = PointerAddress::new( + NetworkInfo::mainnet().network_id(), + &spend_cred, + &Pointer::new_pointer(&to_bignum(24157), &to_bignum(177), &to_bignum(42)), + ) + .to_address(); + assert_eq!( + addr_net_3.to_bech32(None).unwrap(), + "addr1g9u5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5evph3wczvf2kd5vam" + ); +} + +#[test] +fn parse_redeem_address() { + assert!(ByronAddress::is_valid( + "Ae2tdPwUPEZ3MHKkpT5Bpj549vrRH7nBqYjNXnCV8G2Bc2YxNcGHEa8ykDp" + )); + let byron_addr = + ByronAddress::from_base58("Ae2tdPwUPEZ3MHKkpT5Bpj549vrRH7nBqYjNXnCV8G2Bc2YxNcGHEa8ykDp") + .unwrap(); + assert_eq!( + byron_addr.to_base58(), + "Ae2tdPwUPEZ3MHKkpT5Bpj549vrRH7nBqYjNXnCV8G2Bc2YxNcGHEa8ykDp" + ); + let byron_addr2 = ByronAddress::from_bytes(byron_addr.to_bytes()).unwrap(); + assert_eq!( + byron_addr2.to_base58(), + "Ae2tdPwUPEZ3MHKkpT5Bpj549vrRH7nBqYjNXnCV8G2Bc2YxNcGHEa8ykDp" + ); +} + +#[test] +fn bip32_15_byron() { + let byron_key = root_key_15() + .derive(harden(44)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let byron_addr = + ByronAddress::icarus_from_key(&byron_key, NetworkInfo::mainnet().protocol_magic()); + assert_eq!( + byron_addr.to_base58(), + "Ae2tdPwUPEZHtBmjZBF4YpMkK9tMSPTE2ADEZTPN97saNkhG78TvXdp3GDk" + ); + assert!(ByronAddress::is_valid( + "Ae2tdPwUPEZHtBmjZBF4YpMkK9tMSPTE2ADEZTPN97saNkhG78TvXdp3GDk" + )); + assert_eq!(byron_addr.network_id().unwrap(), 0b0001); + + let byron_addr_2 = + ByronAddress::from_address(&Address::from_bytes(byron_addr.to_bytes()).unwrap()).unwrap(); + assert_eq!(byron_addr.to_base58(), byron_addr_2.to_base58()); +} + +#[test] +fn bip32_24_base() { + let spend = root_key_24() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let stake = root_key_24() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + assert_eq!(addr_net_0.to_bech32(None).unwrap(), "addr_test1qqy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmn8k8ttq8f3gag0h89aepvx3xf69g0l9pf80tqv7cve0l33sw96paj"); + let addr_net_3 = BaseAddress::new( + NetworkInfo::mainnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + assert_eq!(addr_net_3.to_bech32(None).unwrap(), "addr1qyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmn8k8ttq8f3gag0h89aepvx3xf69g0l9pf80tqv7cve0l33sdn8p3d"); +} + +#[test] +fn bip32_24_enterprise() { + let spend = root_key_24() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); + let addr_net_0 = + EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(); + assert_eq!( + addr_net_0.to_bech32(None).unwrap(), + "addr_test1vqy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqtjtf68" + ); + let addr_net_3 = + EnterpriseAddress::new(NetworkInfo::mainnet().network_id(), &spend_cred).to_address(); + assert_eq!( + addr_net_3.to_bech32(None).unwrap(), + "addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z" + ); +} + +#[test] +fn bip32_24_pointer() { + let spend = root_key_24() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); + let addr_net_0 = PointerAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &Pointer::new_pointer(&to_bignum(1), &to_bignum(2), &to_bignum(3)), + ) + .to_address(); + assert_eq!( + addr_net_0.to_bech32(None).unwrap(), + "addr_test1gqy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqpqgps5mee0p" + ); + let addr_net_3 = PointerAddress::new( + NetworkInfo::mainnet().network_id(), + &spend_cred, + &Pointer::new_pointer(&to_bignum(24157), &to_bignum(177), &to_bignum(42)), + ) + .to_address(); + assert_eq!( + addr_net_3.to_bech32(None).unwrap(), + "addr1gyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnyph3wczvf2dqflgt" + ); +} + +#[test] +fn bip32_12_reward() { + let staking_key = root_key_12() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + let staking_cred = StakeCredential::from_keyhash(&staking_key.to_raw_key().hash()); + let addr_net_0 = + RewardAddress::new(NetworkInfo::testnet().network_id(), &staking_cred).to_address(); + assert_eq!( + addr_net_0.to_bech32(None).unwrap(), + "stake_test1uqevw2xnsc0pvn9t9r9c7qryfqfeerchgrlm3ea2nefr9hqp8n5xl" + ); + let addr_net_3 = + RewardAddress::new(NetworkInfo::mainnet().network_id(), &staking_cred).to_address(); + assert_eq!( + addr_net_3.to_bech32(None).unwrap(), + "stake1uyevw2xnsc0pvn9t9r9c7qryfqfeerchgrlm3ea2nefr9hqxdekzz" + ); +} + +#[test] +fn bip32_24_base_multisig_hd_derivation() { + let spend = root_key_24() + .derive(harden(1854)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let stake = root_key_24() + .derive(harden(1854)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + assert_eq!(addr_net_0.to_bech32(None).unwrap(), "addr_test1qz8fg2e9yn0ga6sav0760cxmx0antql96mfuhqgzcc5swugw2jqqlugnx9qjep9xvcx40z0zfyep55r2t3lav5smyjrs96cusg"); + let addr_net_3 = BaseAddress::new( + NetworkInfo::mainnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + assert_eq!(addr_net_3.to_bech32(None).unwrap(), "addr1qx8fg2e9yn0ga6sav0760cxmx0antql96mfuhqgzcc5swugw2jqqlugnx9qjep9xvcx40z0zfyep55r2t3lav5smyjrsxv9uuh"); +} + +#[test] +fn multisig_from_script() { + let spend = root_key_24() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + + let mut pubkey_native_scripts = NativeScripts::new(); + + let spending_hash = spend.to_raw_key().hash(); + pubkey_native_scripts.add(&NativeScript::new_script_pubkey(&ScriptPubkey::new( + &spending_hash, + ))); + let oneof_native_script = + NativeScript::new_script_n_of_k(&ScriptNOfK::new(1, &pubkey_native_scripts)); + + let script_hash = ScriptHash::from_bytes(oneof_native_script.hash().to_bytes()).unwrap(); + + let spend_cred = StakeCredential::from_scripthash(&script_hash); + let stake_cred = StakeCredential::from_scripthash(&script_hash); + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + assert_eq!(addr_net_0.to_bech32(None).unwrap(), "addr_test1xr0de0mz3m9xmgtlmqqzu06s0uvfsczskdec8k7v4jhr7077mjlk9rk2dkshlkqq9cl4qlccnps9pvmns0duet9w8uls8flvxc"); + let addr_net_3 = BaseAddress::new( + NetworkInfo::mainnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + assert_eq!(addr_net_3.to_bech32(None).unwrap(), "addr1x80de0mz3m9xmgtlmqqzu06s0uvfsczskdec8k7v4jhr7077mjlk9rk2dkshlkqq9cl4qlccnps9pvmns0duet9w8ulsylzv28"); +} + +#[test] +fn pointer_address_big() { + let addr = Address::from_bech32("addr_test1grqe6lg9ay8wkcu5k5e38lne63c80h3nq6xxhqfmhewf645pllllllllllll7lupllllllllllll7lupllllllllllll7lc9wayvj").unwrap(); + let ptr = PointerAddress::from_address(&addr).unwrap().stake; + assert_eq!(u64::MAX, from_bignum(&ptr.slot)); + assert_eq!(u64::MAX, from_bignum(&ptr.tx_index)); + assert_eq!(u64::MAX, from_bignum(&ptr.cert_index)); +} + +#[test] +fn point_address_old() { + let p1 = Pointer::new(10, 20, 30); + let p2 = Pointer::new_pointer(&to_bignum(10), &to_bignum(20), &to_bignum(30)); + assert_eq!(p1, p2); +} + +#[test] +fn prepod_network_id_test() { + let address = "KjgoiXJS2coTnqpCLHXFtd89Hv9ttjsE6yW4msyLXFNkykUpTsyBs85r2rDDia2uKrhdpGKCJnmFXwvPSWLe75564ixZWdTxRh7TnuaDLnHx"; + let network_id = ByronAddress::from_base58(address) + .unwrap() + .to_address() + .network_id() + .unwrap(); + assert_eq!(network_id, NetworkInfo::testnet_preprod().network_id()); +} From 8f4fab3d052108fd21379dce08ec5ad3f8bf9a24 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 29 Aug 2023 18:41:39 +0500 Subject: [PATCH 088/349] add anchor serialization functions --- rust/src/protocol_types/governance/anchor.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rust/src/protocol_types/governance/anchor.rs b/rust/src/protocol_types/governance/anchor.rs index a131f6ce..32ae595e 100644 --- a/rust/src/protocol_types/governance/anchor.rs +++ b/rust/src/protocol_types/governance/anchor.rs @@ -18,6 +18,8 @@ pub struct Anchor { pub(crate) anchor_data_hash: AnchorDataHash, } +impl_to_from!(Anchor); + #[wasm_bindgen] impl Anchor { pub fn anchor_url(&self) -> URL { From 9903ef5b67f63a55b7d11690ce27f016dd1efe38 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 29 Aug 2023 18:47:18 +0500 Subject: [PATCH 089/349] add cert serialization tests --- rust/src/tests/serialization/certificates.rs | 358 +++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 rust/src/tests/serialization/certificates.rs diff --git a/rust/src/tests/serialization/certificates.rs b/rust/src/tests/serialization/certificates.rs new file mode 100644 index 00000000..40c4fa1a --- /dev/null +++ b/rust/src/tests/serialization/certificates.rs @@ -0,0 +1,358 @@ +use crate::fakes::{ + fake_anchor_data_hash, fake_genesis_delegate_hash, fake_genesis_hash, fake_key_hash, + fake_pool_metadata_hash, fake_script_hash, fake_vrf_key_hash, +}; +use crate::*; + +macro_rules! to_from_test { + ($cert_type: ty, $variable_name: ident, $variable_wrapped_name: ident) => { + let json = $variable_name.to_json().unwrap(); + let cbor = $variable_name.to_bytes(); + let hex_cbor = $variable_name.to_hex(); + + assert_eq!($variable_name, <$cert_type>::from_json(&json).unwrap()); + assert_eq!($variable_name, <$cert_type>::from_bytes(cbor).unwrap()); + assert_eq!($variable_name, <$cert_type>::from_hex(&hex_cbor).unwrap()); + + let json_wrapped = $variable_wrapped_name.to_json().unwrap(); + let cbor_wrapped = $variable_wrapped_name.to_bytes(); + let hex_cbor_wrapped = $variable_wrapped_name.to_hex(); + + assert_eq!( + $variable_wrapped_name, + Certificate::from_json(&json_wrapped).unwrap() + ); + assert_eq!( + $variable_wrapped_name, + Certificate::from_bytes(cbor_wrapped).unwrap() + ); + assert_eq!( + $variable_wrapped_name, + Certificate::from_hex(&hex_cbor_wrapped).unwrap() + ); + }; +} + +#[test] +fn committee_hot_key_deregistration_key_hash_ser_round_trip() { + let cert = + CommitteeHotKeyDeregistration::new(&StakeCredential::from_keyhash(&fake_key_hash(1))); + let cert_wrapped = Certificate::new_committee_hot_key_deregistration(&cert); + to_from_test!(CommitteeHotKeyDeregistration, cert, cert_wrapped); + assert_eq!( + cert, + cert_wrapped.as_committee_hot_key_deregistration().unwrap() + ); +} + +#[test] +fn committee_hot_key_deregistration_script_hash_ser_round_trip() { + let cert = + CommitteeHotKeyDeregistration::new(&StakeCredential::from_scripthash(&fake_script_hash(1))); + let cert_wrapped = Certificate::new_committee_hot_key_deregistration(&cert); + to_from_test!(CommitteeHotKeyDeregistration, cert, cert_wrapped); + assert_eq!( + cert, + cert_wrapped.as_committee_hot_key_deregistration().unwrap() + ); +} + +#[test] +fn committee_hot_key_registration_ser_round_trip() { + let cert = CommitteeHotKeyRegistration::new( + &StakeCredential::from_keyhash(&fake_key_hash(1)), + &StakeCredential::from_keyhash(&fake_key_hash(2)), + ); + let cert_wrapped = Certificate::new_committee_hot_key_registration(&cert); + to_from_test!(CommitteeHotKeyRegistration, cert, cert_wrapped); + assert_eq!( + cert, + cert_wrapped.as_committee_hot_key_registration().unwrap() + ); +} + +#[test] +fn drep_registration_ser_round_trip() { + let cert = DrepRegistration::new( + &StakeCredential::from_keyhash(&fake_key_hash(1)), + &Coin::from(100u64), + ); + let cert_wrapped = Certificate::new_drep_registration(&cert); + to_from_test!(DrepRegistration, cert, cert_wrapped); + assert_eq!(cert, cert_wrapped.as_drep_registration().unwrap()); +} + +#[test] +fn drep_registration_with_anchor_ser_round_trip() { + let url = URL::new("https://iohk.io".to_string()).unwrap(); + let anchor = Anchor::new(&url, &fake_anchor_data_hash(255)); + + let cert = DrepRegistration::new_with_anchor( + &StakeCredential::from_keyhash(&fake_key_hash(1)), + &Coin::from(100u64), + &anchor, + ); + let cert_wrapped = Certificate::new_drep_registration(&cert); + to_from_test!(DrepRegistration, cert, cert_wrapped); + assert_eq!(cert, cert_wrapped.as_drep_registration().unwrap()); +} + +#[test] +fn drep_deregistration_ser_round_trip() { + let cert = DrepDeregistration::new( + &StakeCredential::from_keyhash(&fake_key_hash(1)), + &Coin::from(100u64), + ); + let cert_wrapped = Certificate::new_drep_deregistration(&cert); + to_from_test!(DrepDeregistration, cert, cert_wrapped); + assert_eq!(cert, cert_wrapped.as_drep_deregistration().unwrap()); +} + +#[test] +fn drep_update_ser_round_trip() { + let cert = DrepUpdate::new(&StakeCredential::from_keyhash(&fake_key_hash(1))); + let cert_wrapped = Certificate::new_drep_update(&cert); + to_from_test!(DrepUpdate, cert, cert_wrapped); + assert_eq!(cert, cert_wrapped.as_drep_update().unwrap()); +} + +#[test] +fn drep_update_with_anchor_ser_round_trip() { + let url = URL::new("https://iohk.io".to_string()).unwrap(); + let anchor = Anchor::new(&url, &fake_anchor_data_hash(255)); + let cert = + DrepUpdate::new_with_anchor(&StakeCredential::from_keyhash(&fake_key_hash(1)), &anchor); + let cert_wrapped = Certificate::new_drep_update(&cert); + to_from_test!(DrepUpdate, cert, cert_wrapped); + assert_eq!(cert, cert_wrapped.as_drep_update().unwrap()); +} + +#[test] +fn genesis_key_delegation_ser_round_trip() { + let cert = GenesisKeyDelegation::new( + &fake_genesis_hash(1), + &fake_genesis_delegate_hash(2), + &fake_vrf_key_hash(3), + ); + let cert_wrapped = Certificate::new_genesis_key_delegation(&cert); + to_from_test!(GenesisKeyDelegation, cert, cert_wrapped); + assert_eq!(cert, cert_wrapped.as_genesis_key_delegation().unwrap()); +} + +#[test] +fn move_instantaneous_reward_to_pot_ser_round_trip() { + let cert = MoveInstantaneousReward::new_to_other_pot(MIRPot::Reserves, &Coin::from(100u64)); + let cert_wrapped = + Certificate::new_move_instantaneous_rewards_cert(&MoveInstantaneousRewardsCert::new(&cert)); + to_from_test!(MoveInstantaneousReward, cert, cert_wrapped); + assert_eq!( + cert, + cert_wrapped + .as_move_instantaneous_rewards_cert() + .unwrap() + .move_instantaneous_reward + ); +} + +//#[test] +fn move_instantaneous_reward_to_stake_creds_ser_round_trip() { + let mut amounts = MIRToStakeCredentials::new(); + amounts.insert( + &StakeCredential::from_keyhash(&fake_key_hash(1)), + &DeltaCoin::new(&BigNum::from(100u64)), + ); + let mut amounts = MIRToStakeCredentials::new(); + amounts.insert( + &StakeCredential::from_keyhash(&fake_key_hash(2)), + &DeltaCoin::new(&BigNum::from(1200u64)), + ); + let cert = MoveInstantaneousReward::new_to_stake_creds(MIRPot::Treasury, &amounts); + let cert_wrapped = + Certificate::new_move_instantaneous_rewards_cert(&MoveInstantaneousRewardsCert::new(&cert)); + to_from_test!(MoveInstantaneousReward, cert, cert_wrapped); + assert_eq!( + cert, + cert_wrapped + .as_move_instantaneous_rewards_cert() + .unwrap() + .move_instantaneous_reward + ); +} + +#[test] +fn pool_registration_ser_round_trip() { + let staking_cred = StakeCredential::from_keyhash(&fake_key_hash(1)); + let reward_address = RewardAddress::new(NetworkInfo::testnet().network_id(), &staking_cred); + let mut owners = Ed25519KeyHashes::new(); + owners.add(&fake_key_hash(2)); + owners.add(&fake_key_hash(3)); + let mut relays = Relays::new(); + relays.add(&Relay::new_single_host_addr(&SingleHostAddr::new( + Some(123), + Some(Ipv4::new([127u8, 0, 0, 1].to_vec()).unwrap()), + Some(Ipv6::new([127u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1].to_vec()).unwrap()), + ))); + relays.add(&Relay::new_multi_host_name(&MultiHostName::new( + &DNSRecordSRV::new("hi there".to_string()).unwrap(), + ))); + relays.add(&Relay::new_single_host_name(&SingleHostName::new( + Some(123), + &DNSRecordAorAAAA::new("hi there".to_string()).unwrap(), + ))); + let matadata = PoolMetadata::new( + &URL::new("https://iohk.io".to_string()).unwrap(), + &fake_pool_metadata_hash(5), + ); + + let params = PoolParams::new( + &fake_key_hash(1), + &fake_vrf_key_hash(2), + &Coin::from(100u64), + &Coin::from(200u64), + &UnitInterval::new(&BigNum::from(110u64), &BigNum::from(220u64)), + &reward_address, + &owners, + &relays, + Some(matadata), + ); + + let cert = PoolRegistration::new(¶ms); + let cert_wrapped = Certificate::new_pool_registration(&cert); + to_from_test!(PoolRegistration, cert, cert_wrapped); + assert_eq!(cert, cert_wrapped.as_pool_registration().unwrap()); +} + +#[test] +fn pool_retirement_ser_round_trip() { + let cert = PoolRetirement::new(&fake_key_hash(1), Epoch::from(100u32)); + let cert_wrapped = Certificate::new_pool_retirement(&cert); + to_from_test!(PoolRetirement, cert, cert_wrapped); + assert_eq!(cert, cert_wrapped.as_pool_retirement().unwrap()); +} + +#[test] +fn stake_and_vote_delegation_ser_round_trip() { + let drep = DRep::new_key_hash(&fake_key_hash(3)); + + let cert = StakeAndVoteDelegation::new( + &StakeCredential::from_keyhash(&fake_key_hash(1)), + &fake_key_hash(2), + &drep, + ); + let cert_wrapped = Certificate::new_stake_and_vote_delegation(&cert); + to_from_test!(StakeAndVoteDelegation, cert, cert_wrapped); + assert_eq!(cert, cert_wrapped.as_stake_and_vote_delegation().unwrap()); +} + +#[test] +fn stake_delegation_ser_round_trip() { + let cert = StakeDelegation::new( + &StakeCredential::from_keyhash(&fake_key_hash(1)), + &fake_key_hash(2), + ); + let cert_wrapped = Certificate::new_stake_delegation(&cert); + to_from_test!(StakeDelegation, cert, cert_wrapped); + assert_eq!(cert, cert_wrapped.as_stake_delegation().unwrap()); +} + +#[test] +fn stake_deregistration_ser_round_trip() { + let cert = StakeDeregistration::new(&StakeCredential::from_keyhash(&fake_key_hash(1))); + let cert_wrapped = Certificate::new_stake_deregistration(&cert); + to_from_test!(StakeDeregistration, cert, cert_wrapped); + assert_eq!(cert, cert_wrapped.as_stake_deregistration().unwrap()); +} + +#[test] +fn stake_deregistration_with_coin_ser_round_trip() { + let cert = StakeDeregistration::new_with_coin( + &StakeCredential::from_keyhash(&fake_key_hash(1)), + &Coin::from(100u64), + ); + let cert_wrapped = Certificate::new_stake_deregistration(&cert); + to_from_test!(StakeDeregistration, cert, cert_wrapped); + assert_eq!(cert, cert_wrapped.as_stake_deregistration().unwrap()); +} + +#[test] +fn stake_registration_ser_round_trip() { + let cert = StakeRegistration::new(&StakeCredential::from_keyhash(&fake_key_hash(1))); + let cert_wrapped = Certificate::new_stake_registration(&cert); + to_from_test!(StakeRegistration, cert, cert_wrapped); + assert_eq!(cert, cert_wrapped.as_stake_registration().unwrap()); +} + +#[test] +fn stake_registration_with_coin_ser_round_trip() { + let cert = StakeRegistration::new_with_coin( + &StakeCredential::from_keyhash(&fake_key_hash(1)), + &Coin::from(100u64), + ); + let cert_wrapped = Certificate::new_stake_registration(&cert); + to_from_test!(StakeRegistration, cert, cert_wrapped); + assert_eq!(cert, cert_wrapped.as_stake_registration().unwrap()); +} + +#[test] +fn stake_registration_and_delegation_ser_round_trip() { + let cert = StakeRegistrationAndDelegation::new( + &StakeCredential::from_keyhash(&fake_key_hash(1)), + &fake_key_hash(2), + &Coin::from(100u64), + ); + let cert_wrapped = Certificate::new_stake_registration_and_delegation(&cert); + to_from_test!(StakeRegistrationAndDelegation, cert, cert_wrapped); + assert_eq!( + cert, + cert_wrapped.as_stake_registration_and_delegation().unwrap() + ); +} + +#[test] +fn stake_vote_registration_and_delegation_ser_round_trip() { + let drep = DRep::new_key_hash(&fake_key_hash(3)); + let cert = StakeVoteRegistrationAndDelegation::new( + &StakeCredential::from_keyhash(&fake_key_hash(1)), + &fake_key_hash(2), + &drep, + &Coin::from(100u64), + ); + let cert_wrapped = Certificate::new_stake_vote_registration_and_delegation(&cert); + to_from_test!(StakeVoteRegistrationAndDelegation, cert, cert_wrapped); + assert_eq!( + cert, + cert_wrapped + .as_stake_vote_registration_and_delegation() + .unwrap() + ); +} + +#[test] +fn vote_delegation_ser_round_trip() { + let drep = DRep::new_key_hash(&fake_key_hash(3)); + let cert = VoteDelegation::new( + &StakeCredential::from_keyhash(&fake_key_hash(1)), + &drep + ); + let cert_wrapped = Certificate::new_vote_delegation(&cert); + to_from_test!(VoteDelegation, cert, cert_wrapped); + assert_eq!(cert, cert_wrapped.as_vote_delegation().unwrap()); +} + +#[test] +fn vote_registration_and_delegation_ser_round_trip() { + let drep = DRep::new_key_hash(&fake_key_hash(3)); + let cert = VoteRegistrationAndDelegation::new( + &StakeCredential::from_keyhash(&fake_key_hash(1)), + &drep, + &Coin::from(100u64), + ); + let cert_wrapped = Certificate::new_vote_registration_and_delegation(&cert); + to_from_test!(VoteRegistrationAndDelegation, cert, cert_wrapped); + assert_eq!( + cert, + cert_wrapped + .as_vote_registration_and_delegation() + .unwrap() + ); +} \ No newline at end of file From 8b4ffe67b5bf32e3474b1e74d43aec26cb2efaaa Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 29 Aug 2023 18:47:39 +0500 Subject: [PATCH 090/349] add gov structs tests --- .../tests/serialization/governance/common.rs | 295 ++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 rust/src/tests/serialization/governance/common.rs diff --git a/rust/src/tests/serialization/governance/common.rs b/rust/src/tests/serialization/governance/common.rs new file mode 100644 index 00000000..3bf1dffb --- /dev/null +++ b/rust/src/tests/serialization/governance/common.rs @@ -0,0 +1,295 @@ +use crate::fakes::{fake_anchor_data_hash, fake_key_hash, fake_script_hash, fake_tx_hash}; +use crate::*; + +#[test] +fn anchor_ser_round_trip() { + let anchor = Anchor::new( + &URL::new("https://iohk.io".to_string()).unwrap(), + &fake_anchor_data_hash(1), + ); + + let cbor = anchor.to_bytes(); + let cbor_hex = anchor.to_hex(); + let json = anchor.to_json().unwrap(); + + assert_eq!(anchor, Anchor::from_bytes(cbor).unwrap()); + assert_eq!(anchor, Anchor::from_hex(&cbor_hex).unwrap()); + assert_eq!(anchor, Anchor::from_json(&json).unwrap()); +} + +#[test] +fn drep_key_hash_ser_round_trip() { + let drep = DRep::new_key_hash(&fake_key_hash(1)); + + let cbor = drep.to_bytes(); + let cbor_hex = drep.to_hex(); + let json = drep.to_json().unwrap(); + + assert_eq!(drep, DRep::from_bytes(cbor).unwrap()); + assert_eq!(drep, DRep::from_hex(&cbor_hex).unwrap()); + assert_eq!(drep, DRep::from_json(&json).unwrap()); + assert_eq!(drep.kind(), DRepKind::KeyHash); +} + +#[test] +fn drep_script_hash_ser_round_trip() { + let drep = DRep::new_script_hash(&fake_script_hash(1)); + + let cbor = drep.to_bytes(); + let cbor_hex = drep.to_hex(); + let json = drep.to_json().unwrap(); + + assert_eq!(drep, DRep::from_bytes(cbor).unwrap()); + assert_eq!(drep, DRep::from_hex(&cbor_hex).unwrap()); + assert_eq!(drep, DRep::from_json(&json).unwrap()); + assert_eq!(drep.kind(), DRepKind::ScriptHash); +} + +#[test] +fn drep_always_abstain_ser_round_trip() { + let drep = DRep::new_always_abstain(); + + let cbor = drep.to_bytes(); + let cbor_hex = drep.to_hex(); + let json = drep.to_json().unwrap(); + + assert_eq!(drep, DRep::from_bytes(cbor).unwrap()); + assert_eq!(drep, DRep::from_hex(&cbor_hex).unwrap()); + assert_eq!(drep, DRep::from_json(&json).unwrap()); + assert_eq!(drep.kind(), DRepKind::AlwaysAbstain); +} + +#[test] +fn drep_always_no_confidence_ser_round_trip() { + let drep = DRep::new_always_no_confidence(); + + let cbor = drep.to_bytes(); + let cbor_hex = drep.to_hex(); + let json = drep.to_json().unwrap(); + + assert_eq!(drep, DRep::from_bytes(cbor).unwrap()); + assert_eq!(drep, DRep::from_hex(&cbor_hex).unwrap()); + assert_eq!(drep, DRep::from_json(&json).unwrap()); + assert_eq!(drep.kind(), DRepKind::AlwaysNoConfidence); +} + +#[test] +fn governance_action_id_ser_round_trip() { + let gov_action_id = + GovernanceActionId::new(&fake_tx_hash(1), GovernanceActionIndex::from(42u32)); + + let cbor = gov_action_id.to_bytes(); + let cbor_hex = gov_action_id.to_hex(); + let json = gov_action_id.to_json().unwrap(); + + assert_eq!(gov_action_id, GovernanceActionId::from_bytes(cbor).unwrap()); + assert_eq!( + gov_action_id, + GovernanceActionId::from_hex(&cbor_hex).unwrap() + ); + assert_eq!(gov_action_id, GovernanceActionId::from_json(&json).unwrap()); +} + +#[test] +fn voter_constitutional_committee_hot_key_hash_ser_round_trip() { + let voter = Voter::new_constitutional_committee_hot_key(&StakeCredential::from_keyhash( + &fake_key_hash(1), + )); + + let cbor = voter.to_bytes(); + let cbor_hex = voter.to_hex(); + let json = voter.to_json().unwrap(); + + assert_eq!(voter, Voter::from_bytes(cbor).unwrap()); + assert_eq!(voter, Voter::from_hex(&cbor_hex).unwrap()); + assert_eq!(voter, Voter::from_json(&json).unwrap()); + assert_eq!(voter.kind(), VoterKind::ConstitutionalCommitteeHotKeyHash); +} + +#[test] +fn voter_constitutional_committee_hot_script_hash_ser_round_trip() { + let voter = Voter::new_constitutional_committee_hot_key(&StakeCredential::from_scripthash( + &fake_script_hash(1), + )); + + let cbor = voter.to_bytes(); + let cbor_hex = voter.to_hex(); + let json = voter.to_json().unwrap(); + + assert_eq!(voter, Voter::from_bytes(cbor).unwrap()); + assert_eq!(voter, Voter::from_hex(&cbor_hex).unwrap()); + assert_eq!(voter, Voter::from_json(&json).unwrap()); + assert_eq!( + voter.kind(), + VoterKind::ConstitutionalCommitteeHotScriptHash + ); +} + +#[test] +fn voter_drep_key_hash_ser_round_trip() { + let voter = Voter::new_drep(&StakeCredential::from_keyhash(&fake_key_hash(1))); + + let cbor = voter.to_bytes(); + let cbor_hex = voter.to_hex(); + let json = voter.to_json().unwrap(); + + assert_eq!(voter, Voter::from_bytes(cbor).unwrap()); + assert_eq!(voter, Voter::from_hex(&cbor_hex).unwrap()); + assert_eq!(voter, Voter::from_json(&json).unwrap()); + assert_eq!(voter.kind(), VoterKind::DRepKeyHash); +} + +#[test] +fn voter_drep_script_hash_ser_round_trip() { + let voter = Voter::new_drep(&StakeCredential::from_scripthash(&fake_script_hash(1))); + + let cbor = voter.to_bytes(); + let cbor_hex = voter.to_hex(); + let json = voter.to_json().unwrap(); + + assert_eq!(voter, Voter::from_bytes(cbor).unwrap()); + assert_eq!(voter, Voter::from_hex(&cbor_hex).unwrap()); + assert_eq!(voter, Voter::from_json(&json).unwrap()); + assert_eq!(voter.kind(), VoterKind::DRepScriptHash); +} + +#[test] +fn voter_staking_pool_ser_round_trip() { + let voter = Voter::new_staking_pool(&fake_key_hash(1)); + + let cbor = voter.to_bytes(); + let cbor_hex = voter.to_hex(); + let json = voter.to_json().unwrap(); + + assert_eq!(voter, Voter::from_bytes(cbor).unwrap()); + assert_eq!(voter, Voter::from_hex(&cbor_hex).unwrap()); + assert_eq!(voter, Voter::from_json(&json).unwrap()); + assert_eq!(voter.kind(), VoterKind::StakingPoolKeyHash); +} + +#[test] +fn voting_procedure_no_ser_round_trip() { + let voting_procedure = VotingProcedure::new(VoteKind::No); + + let cbor = voting_procedure.to_bytes(); + let cbor_hex = voting_procedure.to_hex(); + let json = voting_procedure.to_json().unwrap(); + + assert_eq!(voting_procedure, VotingProcedure::from_bytes(cbor).unwrap()); + assert_eq!( + voting_procedure, + VotingProcedure::from_hex(&cbor_hex).unwrap() + ); + assert_eq!(voting_procedure, VotingProcedure::from_json(&json).unwrap()); + assert_eq!(voting_procedure.vote_kind(), VoteKind::No); +} + +#[test] +fn voting_procedure_yes_ser_round_trip() { + let voting_procedure = VotingProcedure::new(VoteKind::Yes); + + let cbor = voting_procedure.to_bytes(); + let cbor_hex = voting_procedure.to_hex(); + let json = voting_procedure.to_json().unwrap(); + + assert_eq!(voting_procedure, VotingProcedure::from_bytes(cbor).unwrap()); + assert_eq!( + voting_procedure, + VotingProcedure::from_hex(&cbor_hex).unwrap() + ); + assert_eq!(voting_procedure, VotingProcedure::from_json(&json).unwrap()); + assert_eq!(voting_procedure.vote_kind(), VoteKind::Yes); +} + +#[test] +fn voting_procedure_abstain_ser_round_trip() { + let voting_procedure = VotingProcedure::new(VoteKind::Abstain); + + let cbor = voting_procedure.to_bytes(); + let cbor_hex = voting_procedure.to_hex(); + let json = voting_procedure.to_json().unwrap(); + + assert_eq!(voting_procedure, VotingProcedure::from_bytes(cbor).unwrap()); + assert_eq!( + voting_procedure, + VotingProcedure::from_hex(&cbor_hex).unwrap() + ); + assert_eq!(voting_procedure, VotingProcedure::from_json(&json).unwrap()); + assert_eq!(voting_procedure.vote_kind(), VoteKind::Abstain); +} + +#[test] +fn voting_procedures_single_item_ser_round_trip() { + let mut voting_procedures = VotingProcedures::new(); + + voting_procedures.insert( + &Voter::new_constitutional_committee_hot_key(&StakeCredential::from_keyhash( + &fake_key_hash(1), + )), + &GovernanceActionId::new(&fake_tx_hash(1), GovernanceActionIndex::from(42u32)), + &VotingProcedure::new(VoteKind::Yes), + ); + + let cbor = voting_procedures.to_bytes(); + let cbor_hex = voting_procedures.to_hex(); + let json = voting_procedures.to_json().unwrap(); + + assert_eq!( + voting_procedures, + VotingProcedures::from_bytes(cbor).unwrap() + ); + assert_eq!( + voting_procedures, + VotingProcedures::from_hex(&cbor_hex).unwrap() + ); + assert_eq!( + voting_procedures, + VotingProcedures::from_json(&json).unwrap() + ); +} + +#[test] +fn voting_procedures_muiltiple_items_ser_round_trip() { + let mut voting_procedures = VotingProcedures::new(); + + voting_procedures.insert( + &Voter::new_constitutional_committee_hot_key(&StakeCredential::from_keyhash( + &fake_key_hash(1), + )), + &GovernanceActionId::new(&fake_tx_hash(1), GovernanceActionIndex::from(42u32)), + &VotingProcedure::new(VoteKind::Yes), + ); + + voting_procedures.insert( + &Voter::new_constitutional_committee_hot_key(&StakeCredential::from_keyhash( + &fake_key_hash(2), + )), + &GovernanceActionId::new(&fake_tx_hash(2), GovernanceActionIndex::from(43u32)), + &VotingProcedure::new(VoteKind::No), + ); + + voting_procedures.insert( + &Voter::new_constitutional_committee_hot_key(&StakeCredential::from_keyhash( + &fake_key_hash(3), + )), + &GovernanceActionId::new(&fake_tx_hash(3), GovernanceActionIndex::from(44u32)), + &VotingProcedure::new(VoteKind::Abstain), + ); + + let cbor = voting_procedures.to_bytes(); + let cbor_hex = voting_procedures.to_hex(); + let json = voting_procedures.to_json().unwrap(); + + assert_eq!( + voting_procedures, + VotingProcedures::from_bytes(cbor).unwrap() + ); + assert_eq!( + voting_procedures, + VotingProcedures::from_hex(&cbor_hex).unwrap() + ); + assert_eq!( + voting_procedures, + VotingProcedures::from_json(&json).unwrap() + ); +} From f624839c8dea7ae49a8fe8d94f82b3c6558479ef Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 29 Aug 2023 18:48:27 +0500 Subject: [PATCH 091/349] update cert types --- .../certificates/drep_deregistration.rs | 2 +- .../certificates/drep_registration.rs | 16 ++++++++++++++-- .../protocol_types/certificates/drep_update.rs | 14 ++++++++++++-- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/rust/src/protocol_types/certificates/drep_deregistration.rs b/rust/src/protocol_types/certificates/drep_deregistration.rs index 6d0a1305..1e64271d 100644 --- a/rust/src/protocol_types/certificates/drep_deregistration.rs +++ b/rust/src/protocol_types/certificates/drep_deregistration.rs @@ -30,7 +30,7 @@ impl DrepDeregistration { self.coin.clone() } - pub fn new(voting_credential: &StakeCredential, coin: Coin) -> Self { + pub fn new(voting_credential: &StakeCredential, coin: &Coin) -> Self { Self { voting_credential: voting_credential.clone(), coin: coin.clone(), diff --git a/rust/src/protocol_types/certificates/drep_registration.rs b/rust/src/protocol_types/certificates/drep_registration.rs index 76865d0b..1fa5ce28 100644 --- a/rust/src/protocol_types/certificates/drep_registration.rs +++ b/rust/src/protocol_types/certificates/drep_registration.rs @@ -35,11 +35,23 @@ impl DrepRegistration { self.anchor.clone() } - pub fn new(voting_credential: &StakeCredential, coin: Coin, anchor: Option) -> Self { + pub fn new(voting_credential: &StakeCredential, coin: &Coin) -> Self { Self { voting_credential: voting_credential.clone(), coin: coin.clone(), - anchor: anchor.clone(), + anchor: None, + } + } + + pub fn new_with_anchor( + voting_credential: &StakeCredential, + coin: &Coin, + anchor: &Anchor, + ) -> Self { + Self { + voting_credential: voting_credential.clone(), + coin: coin.clone(), + anchor: Some(anchor.clone()), } } } diff --git a/rust/src/protocol_types/certificates/drep_update.rs b/rust/src/protocol_types/certificates/drep_update.rs index c1b9f16f..7931f71b 100644 --- a/rust/src/protocol_types/certificates/drep_update.rs +++ b/rust/src/protocol_types/certificates/drep_update.rs @@ -30,10 +30,20 @@ impl DrepUpdate { self.anchor.clone() } - pub fn new(voting_credential: &StakeCredential, anchor: Option) -> Self { + pub fn new(voting_credential: &StakeCredential) -> Self { Self { voting_credential: voting_credential.clone(), - anchor: anchor.clone(), + anchor: None, + } + } + + pub fn new_with_anchor( + voting_credential: &StakeCredential, + anchor: &Anchor, + ) -> Self { + Self { + voting_credential: voting_credential.clone(), + anchor: Some(anchor.clone()), } } From 75b781cc26d1814ad2df8ee6cfc7f6c366f54021 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 29 Aug 2023 18:48:52 +0500 Subject: [PATCH 092/349] update proposal types --- .../governance/proposals/committee.rs | 77 +++++++++++++++++++ .../governance/voting_procedure.rs | 2 +- .../governance/voting_procedures.rs | 16 +++- 3 files changed, 92 insertions(+), 3 deletions(-) diff --git a/rust/src/protocol_types/governance/proposals/committee.rs b/rust/src/protocol_types/governance/proposals/committee.rs index 4fa1207f..651a45fc 100644 --- a/rust/src/protocol_types/governance/proposals/committee.rs +++ b/rust/src/protocol_types/governance/proposals/committee.rs @@ -1,4 +1,6 @@ use crate::*; +use schemars::gen::SchemaGenerator; +use schemars::schema::Schema; use std::collections::BTreeMap; #[derive( @@ -13,6 +15,29 @@ use std::collections::BTreeMap; serde::Deserialize, JsonSchema, )] +struct CommitteeMember { + stake_credential: StakeCredential, + term_limit: Epoch, +} + +#[derive( + Clone, + Debug, + Eq, + Ord, + PartialEq, + PartialOrd, + Hash, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +struct CommitteeJsonStruct { + members: Vec, + quorum_threshold: UnitInterval, +} + +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] #[wasm_bindgen] pub struct Committee { pub(crate) members: BTreeMap, @@ -47,3 +72,55 @@ impl Committee { self.members.get(committee_cold_credential).cloned() } } + +impl JsonSchema for Committee { + fn is_referenceable() -> bool { + CommitteeJsonStruct::is_referenceable() + } + + fn schema_name() -> String { + "Committee".to_string() + } + + fn json_schema(gen: &mut SchemaGenerator) -> Schema { + CommitteeJsonStruct::json_schema(gen) + } +} + +impl serde::ser::Serialize for Committee { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + let committee = CommitteeJsonStruct { + members: self + .members + .iter() + .map(|(k, v)| CommitteeMember { + stake_credential: k.clone(), + term_limit: v.clone(), + }) + .collect(), + quorum_threshold: self.quorum_threshold.clone(), + }; + + committee.serialize(serializer) + } +} + +impl<'de> serde::de::Deserialize<'de> for Committee { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let committee_json: CommitteeJsonStruct = + serde::de::Deserialize::deserialize(deserializer)?; + let mut committee = Committee::new(&committee_json.quorum_threshold); + let mut members = BTreeMap::new(); + for member in committee_json.members { + members.insert(member.stake_credential, member.term_limit); + } + committee.members = members; + Ok(committee) + } +} diff --git a/rust/src/protocol_types/governance/voting_procedure.rs b/rust/src/protocol_types/governance/voting_procedure.rs index 66acc585..46989bc5 100644 --- a/rust/src/protocol_types/governance/voting_procedure.rs +++ b/rust/src/protocol_types/governance/voting_procedure.rs @@ -55,7 +55,7 @@ impl VotingProcedure { } } - pub fn vote(&self) -> VoteKind { + pub fn vote_kind(&self) -> VoteKind { self.vote.clone() } diff --git a/rust/src/protocol_types/governance/voting_procedures.rs b/rust/src/protocol_types/governance/voting_procedures.rs index f2809202..ece3e64e 100644 --- a/rust/src/protocol_types/governance/voting_procedures.rs +++ b/rust/src/protocol_types/governance/voting_procedures.rs @@ -61,6 +61,18 @@ impl VotingProcedures { Self(BTreeMap::new()) } + pub fn insert( + &mut self, + voter: &Voter, + governance_action_id: &GovernanceActionId, + voting_procedure: &VotingProcedure, + ) { + self.0 + .entry(voter.clone()) + .or_insert_with(BTreeMap::new) + .insert(governance_action_id.clone(), voting_procedure.clone()); + } + pub fn get( &self, voter: &Voter, @@ -107,7 +119,7 @@ impl serde::ser::Serialize for VotingProcedures { { let mut seq = serializer.serialize_seq(Some(self.0.len()))?; for (voter, votes) in &self.0 { - let voterVotes = VoterVotes { + let voter_votes = VoterVotes { voter: voter.clone(), votes: votes .iter() @@ -117,7 +129,7 @@ impl serde::ser::Serialize for VotingProcedures { }) .collect(), }; - seq.serialize_element(&voterVotes)?; + seq.serialize_element(&voter_votes)?; } seq.end() } From 92f29bb2fba881d9c65ccc3081d743ae91770b6b Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 29 Aug 2023 18:49:02 +0500 Subject: [PATCH 093/349] update proposal types --- .../governance/proposals/treasury_withdrawals_proposal.rs | 2 +- rust/src/serialization/governance/proposals/voting_proposal.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/rust/src/protocol_types/governance/proposals/treasury_withdrawals_proposal.rs b/rust/src/protocol_types/governance/proposals/treasury_withdrawals_proposal.rs index 9f96307f..120be62d 100644 --- a/rust/src/protocol_types/governance/proposals/treasury_withdrawals_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/treasury_withdrawals_proposal.rs @@ -25,7 +25,7 @@ impl TreasuryWithdrawalsProposal { self.withdrawals.clone() } - pub fn new(withdrawals: TreasuryWithdrawals) -> Self { + pub fn new(withdrawals: &TreasuryWithdrawals) -> Self { Self { withdrawals: withdrawals.clone(), } diff --git a/rust/src/serialization/governance/proposals/voting_proposal.rs b/rust/src/serialization/governance/proposals/voting_proposal.rs index 44d6f8ee..e491afd2 100644 --- a/rust/src/serialization/governance/proposals/voting_proposal.rs +++ b/rust/src/serialization/governance/proposals/voting_proposal.rs @@ -40,6 +40,8 @@ impl Deserialize for VotingProposal { } .into()); } + + return Ok(Self(VotingProposalEnum::InfoProposal(InfoProposal::new()))); } let len = raw.array()?; From 2f1a40616bf884e0437d893b41a3d7bc458991dd Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 29 Aug 2023 18:49:29 +0500 Subject: [PATCH 094/349] fix pool reg check --- rust/src/serialization/certificates/pool_registration.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/src/serialization/certificates/pool_registration.rs b/rust/src/serialization/certificates/pool_registration.rs index 407c95dc..75315244 100644 --- a/rust/src/serialization/certificates/pool_registration.rs +++ b/rust/src/serialization/certificates/pool_registration.rs @@ -154,7 +154,7 @@ impl DeserializeEmbeddedGroup for PoolRegistration { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - check_len(len, 2, "(cert_index, pool_params)")?; + check_len(len, 10, "(cert_index, pool_params (without array) )")?; let cert_index = CertificateIndexNames::PoolRegistration.to_u64(); deserialize_and_check_index(raw, cert_index, "cert_index")?; From 77e7809fd5f090acb388f2ba45ba4c6b410e739e Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 29 Aug 2023 18:50:00 +0500 Subject: [PATCH 095/349] add new fakes functions --- rust/src/fakes.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/rust/src/fakes.rs b/rust/src/fakes.rs index c846f876..d422f507 100644 --- a/rust/src/fakes.rs +++ b/rust/src/fakes.rs @@ -1,6 +1,6 @@ #![allow(dead_code)] use crate::{to_bignum, Address, BaseAddress, Bip32PrivateKey, DataHash, Ed25519KeyHash, Ed25519Signature, NetworkInfo, StakeCredential, TransactionHash, TransactionIndex, TransactionInput, TransactionOutput, Value, Vkey, PolicyID}; -use crate::crypto::ScriptHash; +use crate::crypto::{AnchorDataHash, GenesisDelegateHash, GenesisHash, PoolMetadataHash, ScriptHash, VRFKeyHash}; pub(crate) fn fake_bytes_32(x: u8) -> Vec { vec![ @@ -13,6 +13,26 @@ pub(crate) fn fake_data_hash(x: u8) -> DataHash { DataHash::from_bytes(fake_bytes_32(x)).unwrap() } +pub(crate) fn fake_anchor_data_hash(x: u8) -> AnchorDataHash { + AnchorDataHash::from_bytes(fake_bytes_32(x)).unwrap() +} + +pub(crate) fn fake_pool_metadata_hash(x: u8) -> PoolMetadataHash { + PoolMetadataHash::from_bytes(fake_bytes_32(x)).unwrap() +} + +pub(crate) fn fake_genesis_hash(x: u8) -> GenesisHash { + GenesisHash::from_bytes((&fake_bytes_32(x)[0..28]).to_vec()).unwrap() +} + +pub(crate) fn fake_genesis_delegate_hash(x: u8) -> GenesisDelegateHash { + GenesisDelegateHash::from_bytes((&fake_bytes_32(x)[0..28]).to_vec()).unwrap() +} + +pub(crate) fn fake_vrf_key_hash(x: u8) -> VRFKeyHash { + VRFKeyHash::from_bytes(fake_bytes_32(x)).unwrap() +} + pub(crate) fn fake_key_hash(x: u8) -> Ed25519KeyHash { Ed25519KeyHash::from_bytes((&fake_bytes_32(x)[0..28]).to_vec()).unwrap() } From 0712218dcf19d4d7f6d4c85e0a77ae44f0e3ea72 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 29 Aug 2023 18:50:21 +0500 Subject: [PATCH 096/349] move tests from lib.rs --- rust/src/lib.rs | 293 +------------------------------------- rust/src/tests/general.rs | 291 +++++++++++++++++++++++++++++++++++++ 2 files changed, 294 insertions(+), 290 deletions(-) create mode 100644 rust/src/tests/general.rs diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 7c78470c..81a6ac37 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -15,6 +15,9 @@ extern crate quickcheck; extern crate quickcheck_macros; extern crate hex; +#[cfg(test)] +mod tests; + #[macro_use] extern crate num_derive; @@ -3168,293 +3171,3 @@ impl From<&NativeScripts> for RequiredSignersSet { } } -#[cfg(test)] -mod tests { - use crate::tx_builder_constants::TxBuilderConstants; - use super::*; - - #[test] - fn native_script_hash() { - let keyhash = Ed25519KeyHash::from_bytes(vec![ - 143, 180, 186, 93, 223, 42, 243, 7, 81, 98, 86, 125, 97, 69, 110, 52, 130, 243, 244, - 98, 246, 13, 33, 212, 128, 168, 136, 40, - ]) - .unwrap(); - assert_eq!( - hex::encode(&keyhash.to_bytes()), - "8fb4ba5ddf2af3075162567d61456e3482f3f462f60d21d480a88828" - ); - - let script = NativeScript::new_script_pubkey(&ScriptPubkey::new(&keyhash)); - - let script_hash = script.hash(); - - assert_eq!( - hex::encode(&script_hash.to_bytes()), - "187b8d3ddcb24013097c003da0b8d8f7ddcf937119d8f59dccd05a0f" - ); - } - - #[test] - fn asset_name_ord() { - let name1 = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - let name11 = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - - let name2 = AssetName::new(vec![0u8, 4, 5, 6]).unwrap(); - let name22 = AssetName::new(vec![0u8, 4, 5, 6]).unwrap(); - - let name3 = AssetName::new(vec![0u8, 7, 8]).unwrap(); - let name33 = AssetName::new(vec![0u8, 7, 8]).unwrap(); - - assert_eq!(name1.cmp(&name2), Ordering::Less); - assert_eq!(name2.cmp(&name1), Ordering::Greater); - assert_eq!(name1.cmp(&name3), Ordering::Greater); - assert_eq!(name2.cmp(&name3), Ordering::Greater); - assert_eq!(name3.cmp(&name1), Ordering::Less); - assert_eq!(name3.cmp(&name2), Ordering::Less); - - assert_eq!(name1.cmp(&name11), Ordering::Equal); - assert_eq!(name2.cmp(&name22), Ordering::Equal); - assert_eq!(name3.cmp(&name33), Ordering::Equal); - - let mut map = Assets::new(); - map.insert(&name2, &to_bignum(1)); - map.insert(&name1, &to_bignum(1)); - map.insert(&name3, &to_bignum(1)); - - assert_eq!(map.keys(), AssetNames(vec![name3, name1, name2])); - - let mut map2 = MintAssets::new(); - map2.insert(&name11, Int::new_i32(1)); - map2.insert(&name33, Int::new_i32(1)); - map2.insert(&name22, Int::new_i32(1)); - - assert_eq!(map2.keys(), AssetNames(vec![name33, name11, name22])); - } - - #[test] - fn mint_to_multiasset() { - let policy_id1 = PolicyID::from([0u8; 28]); - let policy_id2 = PolicyID::from([1u8; 28]); - let name1 = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - let name2 = AssetName::new(vec![0u8, 4, 5, 6]).unwrap(); - let amount1 = BigNum::from_str("1234").unwrap(); - let amount2 = BigNum::from_str("5678").unwrap(); - - let mut mass1 = MintAssets::new(); - mass1.insert(&name1, Int::new(&amount1)); - mass1.insert(&name2, Int::new(&amount2)); - - let mut mass2 = MintAssets::new(); - mass2.insert(&name1, Int::new(&amount2)); - mass2.insert(&name2, Int::new(&amount1)); - - let mut mint = Mint::new(); - mint.insert(&policy_id1, &mass1); - mint.insert(&policy_id2, &mass2); - - let multiasset = mint.as_positive_multiasset(); - assert_eq!(multiasset.len(), 2); - - let ass1 = multiasset.get(&policy_id1).unwrap(); - let ass2 = multiasset.get(&policy_id2).unwrap(); - - assert_eq!(ass1.len(), 2); - assert_eq!(ass2.len(), 2); - - assert_eq!(ass1.get(&name1).unwrap(), amount1); - assert_eq!(ass1.get(&name2).unwrap(), amount2); - - assert_eq!(ass2.get(&name1).unwrap(), amount2); - assert_eq!(ass2.get(&name2).unwrap(), amount1); - } - - #[test] - fn mint_to_negative_multiasset() { - let policy_id1 = PolicyID::from([0u8; 28]); - let policy_id2 = PolicyID::from([1u8; 28]); - let name1 = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - let name2 = AssetName::new(vec![0u8, 4, 5, 6]).unwrap(); - let amount1 = BigNum::from_str("1234").unwrap(); - let amount2 = BigNum::from_str("5678").unwrap(); - - let mut mass1 = MintAssets::new(); - mass1.insert(&name1, Int::new(&amount1)); - mass1.insert(&name2, Int::new_negative(&amount2)); - - let mut mass2 = MintAssets::new(); - mass2.insert(&name1, Int::new_negative(&amount1)); - mass2.insert(&name2, Int::new(&amount2)); - - let mut mint = Mint::new(); - mint.insert(&policy_id1, &mass1); - mint.insert(&policy_id2, &mass2); - - let p_multiasset = mint.as_positive_multiasset(); - let n_multiasset = mint.as_negative_multiasset(); - - assert_eq!(p_multiasset.len(), 2); - assert_eq!(n_multiasset.len(), 2); - - let p_ass1 = p_multiasset.get(&policy_id1).unwrap(); - let p_ass2 = p_multiasset.get(&policy_id2).unwrap(); - - let n_ass1 = n_multiasset.get(&policy_id1).unwrap(); - let n_ass2 = n_multiasset.get(&policy_id2).unwrap(); - - assert_eq!(p_ass1.len(), 1); - assert_eq!(p_ass2.len(), 1); - assert_eq!(n_ass1.len(), 1); - assert_eq!(n_ass2.len(), 1); - - assert_eq!(p_ass1.get(&name1).unwrap(), amount1); - assert!(p_ass1.get(&name2).is_none()); - - assert!(p_ass2.get(&name1).is_none()); - assert_eq!(p_ass2.get(&name2).unwrap(), amount2); - - assert!(n_ass1.get(&name1).is_none()); - assert_eq!(n_ass1.get(&name2).unwrap(), amount2); - - assert_eq!(n_ass2.get(&name1).unwrap(), amount1); - assert!(n_ass2.get(&name2).is_none()); - } - - #[test] - fn mint_to_negative_multiasset_empty() { - let policy_id1 = PolicyID::from([0u8; 28]); - let name1 = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - let amount1 = BigNum::from_str("1234").unwrap(); - - let mut mass1 = MintAssets::new(); - mass1.insert(&name1, Int::new(&amount1)); - - let mut mass2 = MintAssets::new(); - mass2.insert(&name1, Int::new_negative(&amount1)); - - let mut mint1 = Mint::new(); - mint1.insert(&policy_id1, &mass1); - - let mut mint2 = Mint::new(); - mint2.insert(&policy_id1, &mass2); - - let p_multiasset_some = mint1.as_positive_multiasset(); - let p_multiasset_none = mint2.as_positive_multiasset(); - - let n_multiasset_none = mint1.as_negative_multiasset(); - let n_multiasset_some = mint2.as_negative_multiasset(); - - assert_eq!(p_multiasset_some.len(), 1); - assert_eq!(p_multiasset_none.len(), 0); - - assert_eq!(n_multiasset_some.len(), 1); - assert_eq!(n_multiasset_none.len(), 0); - - let p_ass = p_multiasset_some.get(&policy_id1).unwrap(); - let n_ass = n_multiasset_some.get(&policy_id1).unwrap(); - - assert_eq!(p_ass.len(), 1); - assert_eq!(n_ass.len(), 1); - - assert_eq!(p_ass.get(&name1).unwrap(), amount1); - assert_eq!(n_ass.get(&name1).unwrap(), amount1); - } - - fn keyhash(x: u8) -> Ed25519KeyHash { - Ed25519KeyHash::from_bytes(vec![ - x, 180, 186, 93, 223, 42, 243, 7, 81, 98, 86, 125, 97, 69, 110, 52, 130, 243, 244, 98, - 246, 13, 33, 212, 128, 168, 136, 40, - ]) - .unwrap() - } - - fn pkscript(pk: &Ed25519KeyHash) -> NativeScript { - NativeScript::new_script_pubkey(&ScriptPubkey::new(pk)) - } - - fn scripts_vec(scripts: Vec<&NativeScript>) -> NativeScripts { - NativeScripts(scripts.iter().map(|s| (*s).clone()).collect()) - } - - #[test] - fn native_scripts_get_pubkeys() { - let keyhash1 = keyhash(1); - let keyhash2 = keyhash(2); - let keyhash3 = keyhash(3); - - let pks1 = RequiredSignersSet::from(&pkscript(&keyhash1)); - assert_eq!(pks1.len(), 1); - assert!(pks1.contains(&keyhash1)); - - let pks2 = - RequiredSignersSet::from(&NativeScript::new_timelock_start(&TimelockStart::new(123))); - assert_eq!(pks2.len(), 0); - - let pks3 = RequiredSignersSet::from(&NativeScript::new_script_all(&ScriptAll::new( - &scripts_vec(vec![&pkscript(&keyhash1), &pkscript(&keyhash2)]), - ))); - assert_eq!(pks3.len(), 2); - assert!(pks3.contains(&keyhash1)); - assert!(pks3.contains(&keyhash2)); - - let pks4 = RequiredSignersSet::from(&NativeScript::new_script_any(&ScriptAny::new( - &scripts_vec(vec![ - &NativeScript::new_script_n_of_k(&ScriptNOfK::new( - 1, - &scripts_vec(vec![ - &NativeScript::new_timelock_start(&TimelockStart::new(132)), - &pkscript(&keyhash3), - ]), - )), - &NativeScript::new_script_all(&ScriptAll::new(&scripts_vec(vec![ - &NativeScript::new_timelock_expiry(&TimelockExpiry::new(132)), - &pkscript(&keyhash1), - ]))), - &NativeScript::new_script_any(&ScriptAny::new(&scripts_vec(vec![ - &pkscript(&keyhash1), - &pkscript(&keyhash2), - &pkscript(&keyhash3), - ]))), - ]), - ))); - assert_eq!(pks4.len(), 3); - assert!(pks4.contains(&keyhash1)); - assert!(pks4.contains(&keyhash2)); - assert!(pks4.contains(&keyhash3)); - } - - #[test] - fn protocol_params_update_cbor_roundtrip() { - let mut orig_ppu = ProtocolParamUpdate::new(); - orig_ppu.set_max_tx_size(1234); - orig_ppu.set_max_block_body_size(5678); - orig_ppu.set_max_block_header_size(91011); - orig_ppu.set_minfee_a(&Coin::from(1u32)); - orig_ppu.set_minfee_b(&Coin::from(2u32)); - orig_ppu.set_key_deposit(&Coin::from(3u32)); - orig_ppu.set_pool_deposit(&Coin::from(4u32)); - orig_ppu.set_max_epoch(5); - orig_ppu.set_n_opt(6); - orig_ppu.set_pool_pledge_influence(&Rational::new(&BigNum::from(7u32), &BigNum::from(77u32))); - orig_ppu.set_expansion_rate(&UnitInterval::new(&BigNum::from(8u32), &BigNum::from(9u32))); - orig_ppu.set_treasury_growth_rate(&UnitInterval::new(&BigNum::from(10u32), &BigNum::from(11u32))); - orig_ppu.set_protocol_version(&ProtocolVersion::new(12u32,13u32)); - orig_ppu.set_min_pool_cost(&Coin::from(14u32)); - orig_ppu.set_ada_per_utxo_byte(&Coin::from(15u32)); - orig_ppu.set_cost_models(&TxBuilderConstants::plutus_vasil_cost_models()); - orig_ppu.set_execution_costs(&ExUnitPrices::new( - &SubCoin::new(&BigNum::from(16u32), &BigNum::from(17u32)), - &SubCoin::new(&BigNum::from(18u32), &BigNum::from(19u32)))); - orig_ppu.set_max_tx_ex_units(&ExUnits::new(&BigNum::from(20u32), &BigNum::from(21u32))); - orig_ppu.set_max_block_ex_units(&ExUnits::new(&BigNum::from(22u32), &BigNum::from(23u32))); - orig_ppu.set_max_value_size(24); - orig_ppu.set_collateral_percentage(25); - orig_ppu.set_max_collateral_inputs(25); - - let encoded = orig_ppu.to_bytes(); - let dencoded = ProtocolParamUpdate::from_bytes(encoded).unwrap(); - - assert_eq!(dencoded, orig_ppu); - assert_eq!(dencoded.to_bytes(), orig_ppu.to_bytes()); - } -} diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs new file mode 100644 index 00000000..4f4ae296 --- /dev/null +++ b/rust/src/tests/general.rs @@ -0,0 +1,291 @@ +use crate::*; +use crate::tx_builder_constants::TxBuilderConstants; + +#[test] +fn native_script_hash() { + let keyhash = Ed25519KeyHash::from_bytes(vec![ + 143, 180, 186, 93, 223, 42, 243, 7, 81, 98, 86, 125, 97, 69, 110, 52, 130, 243, 244, 98, + 246, 13, 33, 212, 128, 168, 136, 40, + ]) + .unwrap(); + assert_eq!( + hex::encode(&keyhash.to_bytes()), + "8fb4ba5ddf2af3075162567d61456e3482f3f462f60d21d480a88828" + ); + + let script = NativeScript::new_script_pubkey(&ScriptPubkey::new(&keyhash)); + + let script_hash = script.hash(); + + assert_eq!( + hex::encode(&script_hash.to_bytes()), + "187b8d3ddcb24013097c003da0b8d8f7ddcf937119d8f59dccd05a0f" + ); +} + +#[test] +fn asset_name_ord() { + let name1 = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); + let name11 = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); + + let name2 = AssetName::new(vec![0u8, 4, 5, 6]).unwrap(); + let name22 = AssetName::new(vec![0u8, 4, 5, 6]).unwrap(); + + let name3 = AssetName::new(vec![0u8, 7, 8]).unwrap(); + let name33 = AssetName::new(vec![0u8, 7, 8]).unwrap(); + + assert_eq!(name1.cmp(&name2), Ordering::Less); + assert_eq!(name2.cmp(&name1), Ordering::Greater); + assert_eq!(name1.cmp(&name3), Ordering::Greater); + assert_eq!(name2.cmp(&name3), Ordering::Greater); + assert_eq!(name3.cmp(&name1), Ordering::Less); + assert_eq!(name3.cmp(&name2), Ordering::Less); + + assert_eq!(name1.cmp(&name11), Ordering::Equal); + assert_eq!(name2.cmp(&name22), Ordering::Equal); + assert_eq!(name3.cmp(&name33), Ordering::Equal); + + let mut map = Assets::new(); + map.insert(&name2, &to_bignum(1)); + map.insert(&name1, &to_bignum(1)); + map.insert(&name3, &to_bignum(1)); + + assert_eq!(map.keys(), AssetNames(vec![name3, name1, name2])); + + let mut map2 = MintAssets::new(); + map2.insert(&name11, Int::new_i32(1)); + map2.insert(&name33, Int::new_i32(1)); + map2.insert(&name22, Int::new_i32(1)); + + assert_eq!(map2.keys(), AssetNames(vec![name33, name11, name22])); +} + +#[test] +fn mint_to_multiasset() { + let policy_id1 = PolicyID::from([0u8; 28]); + let policy_id2 = PolicyID::from([1u8; 28]); + let name1 = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); + let name2 = AssetName::new(vec![0u8, 4, 5, 6]).unwrap(); + let amount1 = BigNum::from_str("1234").unwrap(); + let amount2 = BigNum::from_str("5678").unwrap(); + + let mut mass1 = MintAssets::new(); + mass1.insert(&name1, Int::new(&amount1)); + mass1.insert(&name2, Int::new(&amount2)); + + let mut mass2 = MintAssets::new(); + mass2.insert(&name1, Int::new(&amount2)); + mass2.insert(&name2, Int::new(&amount1)); + + let mut mint = Mint::new(); + mint.insert(&policy_id1, &mass1); + mint.insert(&policy_id2, &mass2); + + let multiasset = mint.as_positive_multiasset(); + assert_eq!(multiasset.len(), 2); + + let ass1 = multiasset.get(&policy_id1).unwrap(); + let ass2 = multiasset.get(&policy_id2).unwrap(); + + assert_eq!(ass1.len(), 2); + assert_eq!(ass2.len(), 2); + + assert_eq!(ass1.get(&name1).unwrap(), amount1); + assert_eq!(ass1.get(&name2).unwrap(), amount2); + + assert_eq!(ass2.get(&name1).unwrap(), amount2); + assert_eq!(ass2.get(&name2).unwrap(), amount1); +} + +#[test] +fn mint_to_negative_multiasset() { + let policy_id1 = PolicyID::from([0u8; 28]); + let policy_id2 = PolicyID::from([1u8; 28]); + let name1 = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); + let name2 = AssetName::new(vec![0u8, 4, 5, 6]).unwrap(); + let amount1 = BigNum::from_str("1234").unwrap(); + let amount2 = BigNum::from_str("5678").unwrap(); + + let mut mass1 = MintAssets::new(); + mass1.insert(&name1, Int::new(&amount1)); + mass1.insert(&name2, Int::new_negative(&amount2)); + + let mut mass2 = MintAssets::new(); + mass2.insert(&name1, Int::new_negative(&amount1)); + mass2.insert(&name2, Int::new(&amount2)); + + let mut mint = Mint::new(); + mint.insert(&policy_id1, &mass1); + mint.insert(&policy_id2, &mass2); + + let p_multiasset = mint.as_positive_multiasset(); + let n_multiasset = mint.as_negative_multiasset(); + + assert_eq!(p_multiasset.len(), 2); + assert_eq!(n_multiasset.len(), 2); + + let p_ass1 = p_multiasset.get(&policy_id1).unwrap(); + let p_ass2 = p_multiasset.get(&policy_id2).unwrap(); + + let n_ass1 = n_multiasset.get(&policy_id1).unwrap(); + let n_ass2 = n_multiasset.get(&policy_id2).unwrap(); + + assert_eq!(p_ass1.len(), 1); + assert_eq!(p_ass2.len(), 1); + assert_eq!(n_ass1.len(), 1); + assert_eq!(n_ass2.len(), 1); + + assert_eq!(p_ass1.get(&name1).unwrap(), amount1); + assert!(p_ass1.get(&name2).is_none()); + + assert!(p_ass2.get(&name1).is_none()); + assert_eq!(p_ass2.get(&name2).unwrap(), amount2); + + assert!(n_ass1.get(&name1).is_none()); + assert_eq!(n_ass1.get(&name2).unwrap(), amount2); + + assert_eq!(n_ass2.get(&name1).unwrap(), amount1); + assert!(n_ass2.get(&name2).is_none()); +} + +#[test] +fn mint_to_negative_multiasset_empty() { + let policy_id1 = PolicyID::from([0u8; 28]); + let name1 = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); + let amount1 = BigNum::from_str("1234").unwrap(); + + let mut mass1 = MintAssets::new(); + mass1.insert(&name1, Int::new(&amount1)); + + let mut mass2 = MintAssets::new(); + mass2.insert(&name1, Int::new_negative(&amount1)); + + let mut mint1 = Mint::new(); + mint1.insert(&policy_id1, &mass1); + + let mut mint2 = Mint::new(); + mint2.insert(&policy_id1, &mass2); + + let p_multiasset_some = mint1.as_positive_multiasset(); + let p_multiasset_none = mint2.as_positive_multiasset(); + + let n_multiasset_none = mint1.as_negative_multiasset(); + let n_multiasset_some = mint2.as_negative_multiasset(); + + assert_eq!(p_multiasset_some.len(), 1); + assert_eq!(p_multiasset_none.len(), 0); + + assert_eq!(n_multiasset_some.len(), 1); + assert_eq!(n_multiasset_none.len(), 0); + + let p_ass = p_multiasset_some.get(&policy_id1).unwrap(); + let n_ass = n_multiasset_some.get(&policy_id1).unwrap(); + + assert_eq!(p_ass.len(), 1); + assert_eq!(n_ass.len(), 1); + + assert_eq!(p_ass.get(&name1).unwrap(), amount1); + assert_eq!(n_ass.get(&name1).unwrap(), amount1); +} + +fn keyhash(x: u8) -> Ed25519KeyHash { + Ed25519KeyHash::from_bytes(vec![ + x, 180, 186, 93, 223, 42, 243, 7, 81, 98, 86, 125, 97, 69, 110, 52, 130, 243, 244, 98, 246, + 13, 33, 212, 128, 168, 136, 40, + ]) + .unwrap() +} + +fn pkscript(pk: &Ed25519KeyHash) -> NativeScript { + NativeScript::new_script_pubkey(&ScriptPubkey::new(pk)) +} + +fn scripts_vec(scripts: Vec<&NativeScript>) -> NativeScripts { + NativeScripts(scripts.iter().map(|s| (*s).clone()).collect()) +} + +#[test] +fn native_scripts_get_pubkeys() { + let keyhash1 = keyhash(1); + let keyhash2 = keyhash(2); + let keyhash3 = keyhash(3); + + let pks1 = RequiredSignersSet::from(&pkscript(&keyhash1)); + assert_eq!(pks1.len(), 1); + assert!(pks1.contains(&keyhash1)); + + let pks2 = + RequiredSignersSet::from(&NativeScript::new_timelock_start(&TimelockStart::new(123))); + assert_eq!(pks2.len(), 0); + + let pks3 = RequiredSignersSet::from(&NativeScript::new_script_all(&ScriptAll::new( + &scripts_vec(vec![&pkscript(&keyhash1), &pkscript(&keyhash2)]), + ))); + assert_eq!(pks3.len(), 2); + assert!(pks3.contains(&keyhash1)); + assert!(pks3.contains(&keyhash2)); + + let pks4 = RequiredSignersSet::from(&NativeScript::new_script_any(&ScriptAny::new( + &scripts_vec(vec![ + &NativeScript::new_script_n_of_k(&ScriptNOfK::new( + 1, + &scripts_vec(vec![ + &NativeScript::new_timelock_start(&TimelockStart::new(132)), + &pkscript(&keyhash3), + ]), + )), + &NativeScript::new_script_all(&ScriptAll::new(&scripts_vec(vec![ + &NativeScript::new_timelock_expiry(&TimelockExpiry::new(132)), + &pkscript(&keyhash1), + ]))), + &NativeScript::new_script_any(&ScriptAny::new(&scripts_vec(vec![ + &pkscript(&keyhash1), + &pkscript(&keyhash2), + &pkscript(&keyhash3), + ]))), + ]), + ))); + assert_eq!(pks4.len(), 3); + assert!(pks4.contains(&keyhash1)); + assert!(pks4.contains(&keyhash2)); + assert!(pks4.contains(&keyhash3)); +} + +#[test] +fn protocol_params_update_cbor_roundtrip() { + let mut orig_ppu = ProtocolParamUpdate::new(); + orig_ppu.set_max_tx_size(1234); + orig_ppu.set_max_block_body_size(5678); + orig_ppu.set_max_block_header_size(91011); + orig_ppu.set_minfee_a(&Coin::from(1u32)); + orig_ppu.set_minfee_b(&Coin::from(2u32)); + orig_ppu.set_key_deposit(&Coin::from(3u32)); + orig_ppu.set_pool_deposit(&Coin::from(4u32)); + orig_ppu.set_max_epoch(5); + orig_ppu.set_n_opt(6); + orig_ppu.set_pool_pledge_influence(&Rational::new(&BigNum::from(7u32), &BigNum::from(77u32))); + orig_ppu.set_expansion_rate(&UnitInterval::new(&BigNum::from(8u32), &BigNum::from(9u32))); + orig_ppu.set_treasury_growth_rate(&UnitInterval::new( + &BigNum::from(10u32), + &BigNum::from(11u32), + )); + orig_ppu.set_protocol_version(&ProtocolVersion::new(12u32, 13u32)); + orig_ppu.set_min_pool_cost(&Coin::from(14u32)); + orig_ppu.set_ada_per_utxo_byte(&Coin::from(15u32)); + orig_ppu.set_cost_models(&TxBuilderConstants::plutus_vasil_cost_models()); + orig_ppu.set_execution_costs(&ExUnitPrices::new( + &SubCoin::new(&BigNum::from(16u32), &BigNum::from(17u32)), + &SubCoin::new(&BigNum::from(18u32), &BigNum::from(19u32)), + )); + orig_ppu.set_max_tx_ex_units(&ExUnits::new(&BigNum::from(20u32), &BigNum::from(21u32))); + orig_ppu.set_max_block_ex_units(&ExUnits::new(&BigNum::from(22u32), &BigNum::from(23u32))); + orig_ppu.set_max_value_size(24); + orig_ppu.set_collateral_percentage(25); + orig_ppu.set_max_collateral_inputs(25); + + let encoded = orig_ppu.to_bytes(); + let dencoded = ProtocolParamUpdate::from_bytes(encoded).unwrap(); + + assert_eq!(dencoded, orig_ppu); + assert_eq!(dencoded.to_bytes(), orig_ppu.to_bytes()); +} From 0d26dd87041e55332764ccf471526a1fbef3cc7c Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 29 Aug 2023 18:50:32 +0500 Subject: [PATCH 097/349] add mock object --- rust/src/tests/mock_objects.rs | 66 ++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 rust/src/tests/mock_objects.rs diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/mock_objects.rs new file mode 100644 index 00000000..7cccf179 --- /dev/null +++ b/rust/src/tests/mock_objects.rs @@ -0,0 +1,66 @@ +use crate::*; + +pub(crate) fn crate_full_protocol_param_update() -> ProtocolParamUpdate { + ProtocolParamUpdate { + minfee_a: Some(Coin::from(44_444u32)), + minfee_b: Some(Coin::from(44_444u32)), + max_block_body_size: Some(44_444u32), + max_tx_size: Some(44_444u32), + max_block_header_size: Some(44_444u32), + key_deposit: Some(Coin::from(44_444u32)), + pool_deposit: Some(Coin::from(44_444u32)), + max_epoch: Some(44_444u32), + n_opt: Some(44_444u32), + pool_pledge_influence: Some(Rational::new( + &BigNum::from(44_444u32), + &BigNum::from(44_444u32), + )), + expansion_rate: Some(UnitInterval::new( + &BigNum::from(44_444u32), + &BigNum::from(44_444u32), + )), + treasury_growth_rate: Some(UnitInterval::new( + &BigNum::from(44_444u32), + &BigNum::from(44_444u32), + )), + d: Some(UnitInterval::new( + &BigNum::from(44_444u32), + &BigNum::from(44_444u32), + )), + extra_entropy: Some(Nonce::new_identity()), + protocol_version: Some(ProtocolVersion::new(1, 2)), + min_pool_cost: Some(Coin::from(44_444u32)), + ada_per_utxo_byte: Some(Coin::from(44_444u32)), + cost_models: Some(create_cost_models()), + execution_costs: Some(ExUnitPrices::new( + &SubCoin::new(&to_bignum(577), &to_bignum(10000)), + &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + )), + max_tx_ex_units: Some(ExUnits::new(&to_bignum(842996), &to_bignum(246100241))), + max_block_ex_units: Some(ExUnits::new(&to_bignum(842996), &to_bignum(246100241))), + max_value_size: Some(44_444u32), + collateral_percentage: Some(44_444u32), + max_collateral_inputs: Some(44_444u32), + } +} + +pub(crate) fn create_cost_models() -> Costmdls { + let mut res = Costmdls::new(); + res.insert( + &Language::new_plutus_v1(), + &CostModel::from(vec![ + 197209, 0, 1, 1, 396231, 621, 0, 1, 150000, 1000, 0, 1, 150000, 32, 2477736, 29175, 4, + 29773, 100, 29773, 100, 29773, 100, 29773, 100, 29773, 100, 29773, 100, 100, 100, + 29773, 100, 150000, 32, 150000, 32, 150000, 32, 150000, 1000, 0, 1, 150000, 32, 150000, + 1000, 0, 8, 148000, 425507, 118, 0, 1, 1, 150000, 1000, 0, 8, 150000, 112536, 247, 1, + 150000, 10000, 1, 136542, 1326, 1, 1000, 150000, 1000, 1, 150000, 32, 150000, 32, + 150000, 32, 1, 1, 150000, 1, 150000, 4, 103599, 248, 1, 103599, 248, 1, 145276, 1366, + 1, 179690, 497, 1, 150000, 32, 150000, 32, 150000, 32, 150000, 32, 150000, 32, 150000, + 32, 148000, 425507, 118, 0, 1, 1, 61516, 11218, 0, 1, 150000, 32, 148000, 425507, 118, + 0, 1, 1, 148000, 425507, 118, 0, 1, 1, 2477736, 29175, 4, 0, 82363, 4, 150000, 5000, 0, + 1, 150000, 32, 197209, 0, 1, 1, 150000, 32, 150000, 32, 150000, 32, 150000, 32, 150000, + 32, 150000, 32, 150000, 32, 3345831, 1, 1, + ]), + ); + res +} From 812fdc72eee727d318220ffd343a21b5e4aaeeb9 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 29 Aug 2023 18:50:52 +0500 Subject: [PATCH 098/349] add tests for voting proposal types --- .../serialization/governance/proposals.rs | 340 ++++++++++++++++++ 1 file changed, 340 insertions(+) create mode 100644 rust/src/tests/serialization/governance/proposals.rs diff --git a/rust/src/tests/serialization/governance/proposals.rs b/rust/src/tests/serialization/governance/proposals.rs new file mode 100644 index 00000000..a889a7ec --- /dev/null +++ b/rust/src/tests/serialization/governance/proposals.rs @@ -0,0 +1,340 @@ +use crate::fakes::{fake_anchor_data_hash, fake_key_hash, fake_script_hash, fake_tx_hash}; +use crate::*; +use crate::tests::mock_objects::crate_full_protocol_param_update; + +macro_rules! to_from_test { + ($proposal_type: ty, $variable_name: ident, $variable_wrapped_name: ident) => { + let json = $variable_name.to_json().unwrap(); + let cbor = $variable_name.to_bytes(); + let hex_cbor = $variable_name.to_hex(); + + assert_eq!($variable_name, <$proposal_type>::from_json(&json).unwrap()); + assert_eq!($variable_name, <$proposal_type>::from_bytes(cbor).unwrap()); + assert_eq!( + $variable_name, + <$proposal_type>::from_hex(&hex_cbor).unwrap() + ); + + let json_wrapped = $variable_wrapped_name.to_json().unwrap(); + let cbor_wrapped = $variable_wrapped_name.to_bytes(); + let hex_cbor_wrapped = $variable_wrapped_name.to_hex(); + + assert_eq!( + $variable_wrapped_name, + VotingProposal::from_json(&json_wrapped).unwrap() + ); + assert_eq!( + $variable_wrapped_name, + VotingProposal::from_bytes(cbor_wrapped).unwrap() + ); + assert_eq!( + $variable_wrapped_name, + VotingProposal::from_hex(&hex_cbor_wrapped).unwrap() + ); + }; +} + +#[test] +fn committee_ser_round_trip() { + let mut committee = + Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); + committee.add_member(&StakeCredential::from_keyhash(&fake_key_hash(1)), 1); + committee.add_member(&StakeCredential::from_scripthash(&fake_script_hash(2)), 2); + + let cbor = committee.to_bytes(); + let cbor_hex = committee.to_hex(); + let json = committee.to_json().unwrap(); + + assert_eq!(committee, Committee::from_bytes(cbor).unwrap()); + assert_eq!(committee, Committee::from_hex(&cbor_hex).unwrap()); + assert_eq!(committee, Committee::from_json(&json).unwrap()); +} + +#[test] +fn committee_empty_ser_round_trip() { + let committee = + Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); + + let cbor = committee.to_bytes(); + let cbor_hex = committee.to_hex(); + let json = committee.to_json().unwrap(); + + assert_eq!(committee, Committee::from_bytes(cbor).unwrap()); + assert_eq!(committee, Committee::from_hex(&cbor_hex).unwrap()); + assert_eq!(committee, Committee::from_json(&json).unwrap()); +} + +#[test] +fn constitution_ser_round_trip() { + let anchor = Anchor::new( + &URL::new("https://iohk.io".to_string()).unwrap(), + &fake_anchor_data_hash(1), + ); + + let constitution = Constitution::new(&anchor); + + let cbor = constitution.to_bytes(); + let cbor_hex = constitution.to_hex(); + let json = constitution.to_json().unwrap(); + + assert_eq!(constitution, Constitution::from_bytes(cbor).unwrap()); + assert_eq!(constitution, Constitution::from_hex(&cbor_hex).unwrap()); + assert_eq!(constitution, Constitution::from_json(&json).unwrap()); +} + +#[test] +fn constitution_with_script_hash_ser_round_trip() { + let anchor = Anchor::new( + &URL::new("https://iohk.io".to_string()).unwrap(), + &fake_anchor_data_hash(1), + ); + + let constitution = Constitution::new_with_script_hash(&anchor, &fake_script_hash(1)); + + let cbor = constitution.to_bytes(); + let cbor_hex = constitution.to_hex(); + let json = constitution.to_json().unwrap(); + + assert_eq!(constitution, Constitution::from_bytes(cbor).unwrap()); + assert_eq!(constitution, Constitution::from_hex(&cbor_hex).unwrap()); + assert_eq!(constitution, Constitution::from_json(&json).unwrap()); +} + +#[test] +fn hard_fork_initiation_proposal_ser_round_trip() { + let proposal = HardForkInitiationProposal::new(&ProtocolVersion::new(1, 2)); + + let proposal_wrapped = VotingProposal::new_hard_fork_initiation_proposal(&proposal); + + to_from_test!(HardForkInitiationProposal, proposal, proposal_wrapped); + assert_eq!( + proposal, + proposal_wrapped.as_hard_fork_initiation_proposal().unwrap() + ); +} + +#[test] +fn hard_fork_initiation_proposal_with_action_id_ser_round_trip() { + let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); + let proposal = + HardForkInitiationProposal::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); + + let proposal_wrapped = VotingProposal::new_hard_fork_initiation_proposal(&proposal); + + to_from_test!(HardForkInitiationProposal, proposal, proposal_wrapped); + assert_eq!( + proposal, + proposal_wrapped.as_hard_fork_initiation_proposal().unwrap() + ); +} + +#[test] +fn new_committee_proposal_ser_round_trip() { + let mut committee = + Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); + committee.add_member(&StakeCredential::from_keyhash(&fake_key_hash(1)), 1); + committee.add_member(&StakeCredential::from_scripthash(&fake_script_hash(2)), 2); + + let mut members_to_remove = StakeCredentials::new(); + members_to_remove.add(&StakeCredential::from_keyhash(&fake_key_hash(1))); + members_to_remove.add(&StakeCredential::from_scripthash(&fake_script_hash(2))); + + let proposal = NewCommitteeProposal::new(&committee, &members_to_remove); + + let proposal_wrapped = VotingProposal::new_new_committee_proposal(&proposal); + + to_from_test!(NewCommitteeProposal, proposal, proposal_wrapped); + assert_eq!( + proposal, + proposal_wrapped.as_new_committee_proposal().unwrap() + ); +} + +#[test] +fn new_committee_proposal_with_action_id_ser_round_trip() { + let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); + let mut committee = + Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); + committee.add_member(&StakeCredential::from_keyhash(&fake_key_hash(1)), 1); + committee.add_member(&StakeCredential::from_scripthash(&fake_script_hash(2)), 2); + + let mut members_to_remove = StakeCredentials::new(); + members_to_remove.add(&StakeCredential::from_keyhash(&fake_key_hash(1))); + members_to_remove.add(&StakeCredential::from_scripthash(&fake_script_hash(2))); + + let proposal = + NewCommitteeProposal::new_with_action_id(&action_id, &committee, &members_to_remove); + + let proposal_wrapped = VotingProposal::new_new_committee_proposal(&proposal); + + to_from_test!(NewCommitteeProposal, proposal, proposal_wrapped); + assert_eq!( + proposal, + proposal_wrapped.as_new_committee_proposal().unwrap() + ); +} + +#[test] +fn new_committee_proposal_with_empty_ser_round_trip() { + let committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); + let members_to_remove = StakeCredentials::new(); + let proposal = NewCommitteeProposal::new(&committee, &members_to_remove); + + let proposal_wrapped = VotingProposal::new_new_committee_proposal(&proposal); + + to_from_test!(NewCommitteeProposal, proposal, proposal_wrapped); + assert_eq!( + proposal, + proposal_wrapped.as_new_committee_proposal().unwrap() + ); +} + +#[test] +fn new_constitution_proposal_ser_round_trip() { + let anchor = Anchor::new( + &URL::new("https://iohk.io".to_string()).unwrap(), + &fake_anchor_data_hash(1), + ); + + let constitution = Constitution::new(&anchor); + let proposal = NewConstitutionProposal::new(&constitution); + + let proposal_wrapped = VotingProposal::new_new_constitution_proposal(&proposal); + + to_from_test!(NewConstitutionProposal, proposal, proposal_wrapped); + assert_eq!( + proposal, + proposal_wrapped.as_new_constitution_proposal().unwrap() + ); +} + +#[test] +fn new_constitution_proposal_with_action_id_ser_round_trip() { + let anchor = Anchor::new( + &URL::new("https://iohk.io".to_string()).unwrap(), + &fake_anchor_data_hash(1), + ); + + let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); + let constitution = Constitution::new(&anchor); + let proposal = NewConstitutionProposal::new_with_action_id(&action_id, &constitution); + + let proposal_wrapped = VotingProposal::new_new_constitution_proposal(&proposal); + + to_from_test!(NewConstitutionProposal, proposal, proposal_wrapped); + assert_eq!( + proposal, + proposal_wrapped.as_new_constitution_proposal().unwrap() + ); +} + +#[test] +fn no_confidence_proposal_ser_round_trip() { + let proposal = NoConfidenceProposal::new(); + + let proposal_wrapped = VotingProposal::new_no_confidence_proposal(&proposal); + + to_from_test!(NoConfidenceProposal, proposal, proposal_wrapped); + assert_eq!( + proposal, + proposal_wrapped.as_no_confidence_proposal().unwrap() + ); +} + +#[test] +fn no_confidence_proposal_with_action_id_ser_round_trip() { + let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); + let proposal = NoConfidenceProposal::new_with_action_id(&action_id); + + let proposal_wrapped = VotingProposal::new_no_confidence_proposal(&proposal); + + to_from_test!(NoConfidenceProposal, proposal, proposal_wrapped); + assert_eq!( + proposal, + proposal_wrapped.as_no_confidence_proposal().unwrap() + ); +} + +#[test] +fn parameter_change_proposal_ser_round_trip() { + let parameters_update = crate_full_protocol_param_update(); + let proposal = ParameterChangeProposal::new(¶meters_update); + let proposal_wrapped = VotingProposal::new_parameter_change_proposal(&proposal); + to_from_test!(ParameterChangeProposal, proposal, proposal_wrapped); + assert_eq!( + proposal, + proposal_wrapped.as_parameter_change_proposal().unwrap() + ); +} + +#[test] +fn parameter_change_proposal_with_action_id_ser_round_trip() { + let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); + let parameters_update = crate_full_protocol_param_update(); + let proposal = + ParameterChangeProposal::new_with_action_id(&action_id, ¶meters_update); + let proposal_wrapped = VotingProposal::new_parameter_change_proposal(&proposal); + to_from_test!(ParameterChangeProposal, proposal, proposal_wrapped); + assert_eq!( + proposal, + proposal_wrapped.as_parameter_change_proposal().unwrap() + ); +} + +#[test] +fn treasury_withdrawals_ser_round_trip() { + let mut withdrawals = TreasuryWithdrawals::new(); + let addr1 = RewardAddress::new(1, &StakeCredential::from_keyhash(&fake_key_hash(1))); + let addr2 = RewardAddress::new(2, &StakeCredential::from_keyhash(&fake_key_hash(2))); + withdrawals.insert(&addr1, &Coin::from(1u32)); + withdrawals.insert(&addr2, &Coin::from(2u32)); + + let json = withdrawals.to_json().unwrap(); + + assert_eq!(withdrawals, TreasuryWithdrawals::from_json(&json).unwrap()); +} + +#[test] +fn treasury_withdrawals_proposal_ser_round_trip() { + let mut withdrawals = TreasuryWithdrawals::new(); + let addr1 = RewardAddress::new(1, &StakeCredential::from_keyhash(&fake_key_hash(1))); + let addr2 = RewardAddress::new(2, &StakeCredential::from_keyhash(&fake_key_hash(2))); + withdrawals.insert(&addr1, &Coin::from(1u32)); + withdrawals.insert(&addr2, &Coin::from(2u32)); + + let proposal = TreasuryWithdrawalsProposal::new(&withdrawals); + + let proposal_wrapped = VotingProposal::new_treasury_withdrawals_proposal(&proposal); + + to_from_test!(TreasuryWithdrawalsProposal, proposal, proposal_wrapped); + assert_eq!( + proposal, + proposal_wrapped.as_treasury_withdrawals_proposal().unwrap() + ); +} + +#[test] +fn voting_proposals_ser_round_trip() { + let mut proposals = VotingProposals::new(); + let mut withdrawals = TreasuryWithdrawals::new(); + let addr1 = RewardAddress::new(1, &StakeCredential::from_keyhash(&fake_key_hash(1))); + let addr2 = RewardAddress::new(2, &StakeCredential::from_keyhash(&fake_key_hash(2))); + withdrawals.insert(&addr1, &Coin::from(1u32)); + withdrawals.insert(&addr2, &Coin::from(2u32)); + + let proposal1 = TreasuryWithdrawalsProposal::new(&withdrawals); + let proposal2 = NoConfidenceProposal::new(); + let proposal3 = InfoProposal::new(); + + proposals.add(&VotingProposal::new_treasury_withdrawals_proposal(&proposal1)); + proposals.add(&VotingProposal::new_no_confidence_proposal(&proposal2)); + proposals.add(&VotingProposal::new_info_proposal(&proposal3)); + + let cbor = proposals.to_bytes(); + let cbor_hex = proposals.to_hex(); + let json = proposals.to_json().unwrap(); + + assert_eq!(proposals, VotingProposals::from_bytes(cbor).unwrap()); + assert_eq!(proposals, VotingProposals::from_hex(&cbor_hex).unwrap()); + assert_eq!(proposals, VotingProposals::from_json(&json).unwrap()); +} \ No newline at end of file From ecb9cb1766e2c88740139cedc10ba1f89ee9eace Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 29 Aug 2023 18:51:04 +0500 Subject: [PATCH 099/349] add mod files --- rust/src/tests/mod.rs | 4 ++++ rust/src/tests/serialization/governance/mod.rs | 2 ++ rust/src/tests/serialization/mod.rs | 2 ++ 3 files changed, 8 insertions(+) create mode 100644 rust/src/tests/mod.rs create mode 100644 rust/src/tests/serialization/governance/mod.rs create mode 100644 rust/src/tests/serialization/mod.rs diff --git a/rust/src/tests/mod.rs b/rust/src/tests/mod.rs new file mode 100644 index 00000000..3142c3fc --- /dev/null +++ b/rust/src/tests/mod.rs @@ -0,0 +1,4 @@ +pub mod serialization; +pub mod general; +pub mod address; +mod mock_objects; \ No newline at end of file diff --git a/rust/src/tests/serialization/governance/mod.rs b/rust/src/tests/serialization/governance/mod.rs new file mode 100644 index 00000000..8035a1a2 --- /dev/null +++ b/rust/src/tests/serialization/governance/mod.rs @@ -0,0 +1,2 @@ +pub mod common; +pub mod proposals; \ No newline at end of file diff --git a/rust/src/tests/serialization/mod.rs b/rust/src/tests/serialization/mod.rs new file mode 100644 index 00000000..ba473309 --- /dev/null +++ b/rust/src/tests/serialization/mod.rs @@ -0,0 +1,2 @@ +pub mod certificates; +pub mod governance; \ No newline at end of file From ffec35b479282ac15c24f9a4da65524299f8a398 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 30 Aug 2023 12:43:25 +0500 Subject: [PATCH 100/349] merge fix --- rust/src/tx_builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/src/tx_builder.rs b/rust/src/tx_builder.rs index e9533057..4ed05e25 100644 --- a/rust/src/tx_builder.rs +++ b/rust/src/tx_builder.rs @@ -365,7 +365,7 @@ pub struct TransactionBuilder { collateral_return: Option, total_collateral: Option, reference_inputs: HashSet, - extra_datums: Option + extra_datums: Option, voting_procedures: Option, voting_proposals: Option, } From bd063dadbaa3c41eabb304fea6c4e6b988fb2ecd Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 30 Aug 2023 13:50:18 +0500 Subject: [PATCH 101/349] mir cert json fix --- .../move_instantaneous_rewards_cert.rs | 41 +++++++++++++++---- rust/src/tests/serialization/certificates.rs | 2 +- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs b/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs index 28a5556f..2649e445 100644 --- a/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs +++ b/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs @@ -1,4 +1,5 @@ use crate::*; +use std::vec::Vec; #[wasm_bindgen] #[derive( @@ -115,16 +116,37 @@ impl MIRToStakeCredentials { } } +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +struct StakeToCoinJson { + stake_cred: StakeCredential, + amount: DeltaCoin, +} + impl serde::Serialize for MIRToStakeCredentials { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { - let map = self + let vec = self .rewards .iter() - .collect::>(); - map.serialize(serializer) + .map(|(k, v)| StakeToCoinJson { + stake_cred: k.clone(), + amount: v.clone(), + }) + .collect::>(); + vec.serialize(serializer) } } @@ -133,11 +155,12 @@ impl<'de> serde::de::Deserialize<'de> for MIRToStakeCredentials { where D: serde::de::Deserializer<'de>, { - let map = as serde::de::Deserialize>::deserialize( - deserializer, - )?; + let map = Vec::::deserialize(deserializer)? + .into_iter() + .map(|v| (v.stake_cred, v.amount)); + Ok(Self { - rewards: map.into_iter().collect(), + rewards: map.collect(), }) } } @@ -147,10 +170,10 @@ impl JsonSchema for MIRToStakeCredentials { String::from("MIRToStakeCredentials") } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - std::collections::BTreeMap::::json_schema(gen) + Vec::::json_schema(gen) } fn is_referenceable() -> bool { - std::collections::BTreeMap::::is_referenceable() + Vec::::is_referenceable() } } diff --git a/rust/src/tests/serialization/certificates.rs b/rust/src/tests/serialization/certificates.rs index 40c4fa1a..f5ca0e5f 100644 --- a/rust/src/tests/serialization/certificates.rs +++ b/rust/src/tests/serialization/certificates.rs @@ -154,7 +154,7 @@ fn move_instantaneous_reward_to_pot_ser_round_trip() { ); } -//#[test] +#[test] fn move_instantaneous_reward_to_stake_creds_ser_round_trip() { let mut amounts = MIRToStakeCredentials::new(); amounts.insert( From 173341ef8db103d274a34454b6066e7ccb8c681e Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 30 Aug 2023 13:50:32 +0500 Subject: [PATCH 102/349] fmt --- .../protocol_types/governance/voting_procedures.rs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/rust/src/protocol_types/governance/voting_procedures.rs b/rust/src/protocol_types/governance/voting_procedures.rs index ece3e64e..44d9c00c 100644 --- a/rust/src/protocol_types/governance/voting_procedures.rs +++ b/rust/src/protocol_types/governance/voting_procedures.rs @@ -1,9 +1,9 @@ use crate::*; use schemars::gen::SchemaGenerator; use schemars::schema::Schema; +use serde::ser::SerializeSeq; use std::collections::BTreeMap; use std::vec::Vec; -use serde::ser::SerializeSeq; #[derive( Clone, @@ -39,15 +39,7 @@ struct Vote { voting_procedure: VotingProcedure, } -#[derive( - Clone, - Debug, - Eq, - Ord, - PartialEq, - PartialOrd, - Hash, -)] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] #[wasm_bindgen] pub struct VotingProcedures( pub(crate) BTreeMap>, From 31b01e7a2953a5e27450433f650a1bbf6356b468 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 30 Aug 2023 13:52:58 +0500 Subject: [PATCH 103/349] rename StakeCredential to Credential --- rust/src/address.rs | 48 +++--- rust/src/fakes.rs | 6 +- rust/src/fees.rs | 2 +- rust/src/lib.rs | 6 +- rust/src/plutus.rs | 2 +- .../committee_hot_key_deregistration.rs | 6 +- .../committee_hot_key_registration.rs | 12 +- .../certificates/drep_deregistration.rs | 6 +- .../certificates/drep_registration.rs | 8 +- .../certificates/drep_update.rs | 8 +- .../move_instantaneous_rewards_cert.rs | 10 +- .../certificates/stake_and_vote_delegation.rs | 6 +- .../certificates/stake_delegation.rs | 6 +- .../certificates/stake_deregistration.rs | 8 +- .../certificates/stake_registration.rs | 8 +- .../stake_registration_and_delegation.rs | 6 +- .../stake_vote_registration_and_delegation.rs | 6 +- .../certificates/vote_delegation.rs | 6 +- .../vote_registration_and_delegation.rs | 6 +- .../governance/proposals/committee.rs | 8 +- .../proposals/new_committee_proposal.rs | 2 +- rust/src/protocol_types/governance/voter.rs | 12 +- .../committee_hot_key_deregistration.rs | 2 +- .../committee_hot_key_registration.rs | 4 +- .../certificates/drep_deregistration.rs | 2 +- .../certificates/drep_registration.rs | 2 +- .../serialization/certificates/drep_update.rs | 2 +- .../move_instantaneous_rewards_cert.rs | 2 +- .../certificates/stake_and_vote_delegation.rs | 2 +- .../certificates/stake_delegation.rs | 2 +- .../certificates/stake_deregistration.rs | 4 +- .../certificates/stake_registration.rs | 4 +- .../stake_registration_and_delegation.rs | 2 +- .../stake_vote_registration_and_delegation.rs | 2 +- .../certificates/vote_delegation.rs | 2 +- .../vote_registration_and_delegation.rs | 2 +- rust/src/serialization/general.rs | 4 +- .../governance/proposals/committee.rs | 2 +- rust/src/serialization/governance/voter.rs | 8 +- rust/src/tests/address.rs | 44 +++--- rust/src/tests/serialization/certificates.rs | 44 +++--- .../tests/serialization/governance/common.rs | 16 +- .../serialization/governance/proposals.rs | 32 ++-- rust/src/tx_builder.rs | 148 +++++++++--------- rust/src/tx_builder/test_batch.rs | 4 +- 45 files changed, 262 insertions(+), 262 deletions(-) diff --git a/rust/src/address.rs b/rust/src/address.rs index 0c7c2b22..f2647bd6 100644 --- a/rust/src/address.rs +++ b/rust/src/address.rs @@ -120,16 +120,16 @@ pub enum StakeCredKind { serde::Deserialize, JsonSchema, )] -pub struct StakeCredential(pub(crate) StakeCredType); +pub struct Credential(pub(crate) StakeCredType); #[wasm_bindgen] -impl StakeCredential { +impl Credential { pub fn from_keyhash(hash: &Ed25519KeyHash) -> Self { - StakeCredential(StakeCredType::Key(hash.clone())) + Credential(StakeCredType::Key(hash.clone())) } pub fn from_scripthash(hash: &ScriptHash) -> Self { - StakeCredential(StakeCredType::Script(hash.clone())) + Credential(StakeCredType::Script(hash.clone())) } pub fn to_keyhash(&self) -> Option { @@ -168,9 +168,9 @@ impl StakeCredential { } } -impl_to_from!(StakeCredential); +impl_to_from!(Credential); -impl cbor_event::se::Serialize for StakeCredential { +impl cbor_event::se::Serialize for Credential { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, @@ -189,7 +189,7 @@ impl cbor_event::se::Serialize for StakeCredential { } } -impl Deserialize for StakeCredential { +impl Deserialize for Credential { fn deserialize(raw: &mut Deserializer) -> Result { (|| -> Result<_, DeserializeError> { let len = raw.array()?; @@ -220,7 +220,7 @@ impl Deserialize for StakeCredential { return Err(DeserializeFailure::EndingBreakMissing.into()); } } - Ok(StakeCredential(cred_type)) + Ok(Credential(cred_type)) })() .map_err(|e| e.annotate("StakeCredential")) } @@ -471,9 +471,9 @@ impl Address { let read_addr_cred = |bit: u8, pos: usize| { let hash_bytes: [u8; HASH_LEN] = data[pos..pos + HASH_LEN].try_into().unwrap(); let x = if header & (1 << bit) == 0 { - StakeCredential::from_keyhash(&Ed25519KeyHash::from(hash_bytes)) + Credential::from_keyhash(&Ed25519KeyHash::from(hash_bytes)) } else { - StakeCredential::from_scripthash(&ScriptHash::from(hash_bytes)) + Credential::from_scripthash(&ScriptHash::from(hash_bytes)) }; x }; @@ -643,13 +643,13 @@ impl Deserialize for Address { #[derive(Debug, Clone, Eq, Ord, PartialEq, PartialOrd)] pub struct BaseAddress { network: u8, - payment: StakeCredential, - stake: StakeCredential, + payment: Credential, + stake: Credential, } #[wasm_bindgen] impl BaseAddress { - pub fn new(network: u8, payment: &StakeCredential, stake: &StakeCredential) -> Self { + pub fn new(network: u8, payment: &Credential, stake: &Credential) -> Self { Self { network, payment: payment.clone(), @@ -657,11 +657,11 @@ impl BaseAddress { } } - pub fn payment_cred(&self) -> StakeCredential { + pub fn payment_cred(&self) -> Credential { self.payment.clone() } - pub fn stake_cred(&self) -> StakeCredential { + pub fn stake_cred(&self) -> Credential { self.stake.clone() } @@ -681,19 +681,19 @@ impl BaseAddress { #[derive(Debug, Clone, Eq, Ord, PartialEq, PartialOrd)] pub struct EnterpriseAddress { network: u8, - payment: StakeCredential, + payment: Credential, } #[wasm_bindgen] impl EnterpriseAddress { - pub fn new(network: u8, payment: &StakeCredential) -> Self { + pub fn new(network: u8, payment: &Credential) -> Self { Self { network, payment: payment.clone(), } } - pub fn payment_cred(&self) -> StakeCredential { + pub fn payment_cred(&self) -> Credential { self.payment.clone() } @@ -713,19 +713,19 @@ impl EnterpriseAddress { #[derive(Debug, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct RewardAddress { network: u8, - payment: StakeCredential, + payment: Credential, } #[wasm_bindgen] impl RewardAddress { - pub fn new(network: u8, payment: &StakeCredential) -> Self { + pub fn new(network: u8, payment: &Credential) -> Self { Self { network, payment: payment.clone(), } } - pub fn payment_cred(&self) -> StakeCredential { + pub fn payment_cred(&self) -> Credential { self.payment.clone() } @@ -870,13 +870,13 @@ impl Pointer { #[derive(Debug, Clone, Eq, Ord, PartialEq, PartialOrd)] pub struct PointerAddress { pub(crate) network: u8, - pub(crate) payment: StakeCredential, + pub(crate) payment: Credential, pub(crate) stake: Pointer, } #[wasm_bindgen] impl PointerAddress { - pub fn new(network: u8, payment: &StakeCredential, stake: &Pointer) -> Self { + pub fn new(network: u8, payment: &Credential, stake: &Pointer) -> Self { Self { network, payment: payment.clone(), @@ -884,7 +884,7 @@ impl PointerAddress { } } - pub fn payment_cred(&self) -> StakeCredential { + pub fn payment_cred(&self) -> Credential { self.payment.clone() } diff --git a/rust/src/fakes.rs b/rust/src/fakes.rs index d422f507..e9333478 100644 --- a/rust/src/fakes.rs +++ b/rust/src/fakes.rs @@ -1,5 +1,5 @@ #![allow(dead_code)] -use crate::{to_bignum, Address, BaseAddress, Bip32PrivateKey, DataHash, Ed25519KeyHash, Ed25519Signature, NetworkInfo, StakeCredential, TransactionHash, TransactionIndex, TransactionInput, TransactionOutput, Value, Vkey, PolicyID}; +use crate::{to_bignum, Address, BaseAddress, Bip32PrivateKey, DataHash, Ed25519KeyHash, Ed25519Signature, NetworkInfo, Credential, TransactionHash, TransactionIndex, TransactionInput, TransactionOutput, Value, Vkey, PolicyID}; use crate::crypto::{AnchorDataHash, GenesisDelegateHash, GenesisHash, PoolMetadataHash, ScriptHash, VRFKeyHash}; pub(crate) fn fake_bytes_32(x: u8) -> Vec { @@ -44,8 +44,8 @@ pub(crate) fn fake_script_hash(x: u8) -> ScriptHash { pub(crate) fn fake_base_address(x: u8) -> Address { BaseAddress::new( NetworkInfo::testnet().network_id(), - &StakeCredential::from_keyhash(&fake_key_hash(x)), - &StakeCredential::from_keyhash(&fake_key_hash(0)), + &Credential::from_keyhash(&fake_key_hash(x)), + &Credential::from_keyhash(&fake_key_hash(0)), ) .to_address() } diff --git a/rust/src/fees.rs b/rust/src/fees.rs index 7bbf6d8e..c53846fc 100644 --- a/rust/src/fees.rs +++ b/rust/src/fees.rs @@ -356,7 +356,7 @@ mod tests { &UnitInterval::new(&to_bignum(3), &to_bignum(100)), // margin &RewardAddress::new( network, - &StakeCredential::from_keyhash( + &Credential::from_keyhash( &PublicKey::from_bytes( &hex::decode( "54d1a9c5ad69586ceeb839c438400c376c0bd34825fb4c17cc2f58c54e1437f3", diff --git a/rust/src/lib.rs b/rust/src/lib.rs index ff12d0d7..8d6d8c1e 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1114,7 +1114,7 @@ impl PoolMetadata { #[derive( Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, )] -pub struct StakeCredentials(Vec); +pub struct StakeCredentials(Vec); impl_to_from!(StakeCredentials); @@ -1128,11 +1128,11 @@ impl StakeCredentials { self.0.len() } - pub fn get(&self, index: usize) -> StakeCredential { + pub fn get(&self, index: usize) -> Credential { self.0[index].clone() } - pub fn add(&mut self, elem: &StakeCredential) { + pub fn add(&mut self, elem: &Credential) { self.0.push(elem.clone()); } } diff --git a/rust/src/plutus.rs b/rust/src/plutus.rs index ab5c7498..ce9e136c 100644 --- a/rust/src/plutus.rs +++ b/rust/src/plutus.rs @@ -792,7 +792,7 @@ impl PlutusData { ))) } - fn from_stake_credential(stake_credential: &StakeCredential) -> Result { + fn from_stake_credential(stake_credential: &Credential) -> Result { let (bytes_plutus_data, index) = match &stake_credential.0 { StakeCredType::Key(key_hash) => (PlutusData::new_bytes(key_hash.to_bytes().to_vec()), BigNum::from(0u32)), diff --git a/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs b/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs index f1fbbe12..3d1d4f5b 100644 --- a/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs +++ b/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs @@ -14,19 +14,19 @@ use crate::*; )] #[wasm_bindgen] pub struct CommitteeHotKeyDeregistration { - pub(crate) committee_cold_key: StakeCredential, + pub(crate) committee_cold_key: Credential, } impl_to_from!(CommitteeHotKeyDeregistration); #[wasm_bindgen] impl CommitteeHotKeyDeregistration { - pub fn committee_cold_key(&self) -> StakeCredential { + pub fn committee_cold_key(&self) -> Credential { self.committee_cold_key.clone() } pub fn new( - committee_cold_key: &StakeCredential, + committee_cold_key: &Credential, ) -> Self { Self { committee_cold_key: committee_cold_key.clone(), diff --git a/rust/src/protocol_types/certificates/committee_hot_key_registration.rs b/rust/src/protocol_types/certificates/committee_hot_key_registration.rs index ec18463f..175c9b2c 100644 --- a/rust/src/protocol_types/certificates/committee_hot_key_registration.rs +++ b/rust/src/protocol_types/certificates/committee_hot_key_registration.rs @@ -14,25 +14,25 @@ use crate::*; )] #[wasm_bindgen] pub struct CommitteeHotKeyRegistration { - pub(crate) committee_cold_key: StakeCredential, - pub(crate) committee_hot_key: StakeCredential, + pub(crate) committee_cold_key: Credential, + pub(crate) committee_hot_key: Credential, } impl_to_from!(CommitteeHotKeyRegistration); #[wasm_bindgen] impl CommitteeHotKeyRegistration { - pub fn committee_cold_key(&self) -> StakeCredential { + pub fn committee_cold_key(&self) -> Credential { self.committee_cold_key.clone() } - pub fn committee_hot_key(&self) -> StakeCredential { + pub fn committee_hot_key(&self) -> Credential { self.committee_hot_key.clone() } pub fn new( - committee_cold_key: &StakeCredential, - committee_hot_key: &StakeCredential, + committee_cold_key: &Credential, + committee_hot_key: &Credential, ) -> Self { Self { committee_cold_key: committee_cold_key.clone(), diff --git a/rust/src/protocol_types/certificates/drep_deregistration.rs b/rust/src/protocol_types/certificates/drep_deregistration.rs index 1e64271d..89d4ae02 100644 --- a/rust/src/protocol_types/certificates/drep_deregistration.rs +++ b/rust/src/protocol_types/certificates/drep_deregistration.rs @@ -14,7 +14,7 @@ use crate::*; )] #[wasm_bindgen] pub struct DrepDeregistration { - pub(crate) voting_credential: StakeCredential, + pub(crate) voting_credential: Credential, pub(crate) coin: Coin, } @@ -22,7 +22,7 @@ impl_to_from!(DrepDeregistration); #[wasm_bindgen] impl DrepDeregistration { - pub fn voting_credential(&self) -> StakeCredential { + pub fn voting_credential(&self) -> Credential { self.voting_credential.clone() } @@ -30,7 +30,7 @@ impl DrepDeregistration { self.coin.clone() } - pub fn new(voting_credential: &StakeCredential, coin: &Coin) -> Self { + pub fn new(voting_credential: &Credential, coin: &Coin) -> Self { Self { voting_credential: voting_credential.clone(), coin: coin.clone(), diff --git a/rust/src/protocol_types/certificates/drep_registration.rs b/rust/src/protocol_types/certificates/drep_registration.rs index 1fa5ce28..306e93ee 100644 --- a/rust/src/protocol_types/certificates/drep_registration.rs +++ b/rust/src/protocol_types/certificates/drep_registration.rs @@ -14,7 +14,7 @@ use crate::*; )] #[wasm_bindgen] pub struct DrepRegistration { - pub(crate) voting_credential: StakeCredential, + pub(crate) voting_credential: Credential, pub(crate) coin: Coin, pub(crate) anchor: Option, } @@ -23,7 +23,7 @@ impl_to_from!(DrepRegistration); #[wasm_bindgen] impl DrepRegistration { - pub fn voting_credential(&self) -> StakeCredential { + pub fn voting_credential(&self) -> Credential { self.voting_credential.clone() } @@ -35,7 +35,7 @@ impl DrepRegistration { self.anchor.clone() } - pub fn new(voting_credential: &StakeCredential, coin: &Coin) -> Self { + pub fn new(voting_credential: &Credential, coin: &Coin) -> Self { Self { voting_credential: voting_credential.clone(), coin: coin.clone(), @@ -44,7 +44,7 @@ impl DrepRegistration { } pub fn new_with_anchor( - voting_credential: &StakeCredential, + voting_credential: &Credential, coin: &Coin, anchor: &Anchor, ) -> Self { diff --git a/rust/src/protocol_types/certificates/drep_update.rs b/rust/src/protocol_types/certificates/drep_update.rs index 7931f71b..5c8d74a6 100644 --- a/rust/src/protocol_types/certificates/drep_update.rs +++ b/rust/src/protocol_types/certificates/drep_update.rs @@ -14,7 +14,7 @@ use crate::*; )] #[wasm_bindgen] pub struct DrepUpdate { - pub(crate) voting_credential: StakeCredential, + pub(crate) voting_credential: Credential, pub(crate) anchor: Option, } @@ -22,7 +22,7 @@ impl_to_from!(DrepUpdate); #[wasm_bindgen] impl DrepUpdate { - pub fn voting_credential(&self) -> StakeCredential { + pub fn voting_credential(&self) -> Credential { self.voting_credential.clone() } @@ -30,7 +30,7 @@ impl DrepUpdate { self.anchor.clone() } - pub fn new(voting_credential: &StakeCredential) -> Self { + pub fn new(voting_credential: &Credential) -> Self { Self { voting_credential: voting_credential.clone(), anchor: None, @@ -38,7 +38,7 @@ impl DrepUpdate { } pub fn new_with_anchor( - voting_credential: &StakeCredential, + voting_credential: &Credential, anchor: &Anchor, ) -> Self { Self { diff --git a/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs b/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs index 2649e445..af7488a1 100644 --- a/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs +++ b/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs @@ -81,7 +81,7 @@ pub enum MIRKind { #[wasm_bindgen] #[derive(Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)] pub struct MIRToStakeCredentials { - pub(crate) rewards: linked_hash_map::LinkedHashMap, + pub(crate) rewards: linked_hash_map::LinkedHashMap, } impl_to_from!(MIRToStakeCredentials); @@ -98,11 +98,11 @@ impl MIRToStakeCredentials { self.rewards.len() } - pub fn insert(&mut self, cred: &StakeCredential, delta: &DeltaCoin) -> Option { + pub fn insert(&mut self, cred: &Credential, delta: &DeltaCoin) -> Option { self.rewards.insert(cred.clone(), delta.clone()) } - pub fn get(&self, cred: &StakeCredential) -> Option { + pub fn get(&self, cred: &Credential) -> Option { self.rewards.get(cred).map(|v| v.clone()) } @@ -111,7 +111,7 @@ impl MIRToStakeCredentials { self.rewards .iter() .map(|(k, _v)| k.clone()) - .collect::>(), + .collect::>(), ) } } @@ -129,7 +129,7 @@ impl MIRToStakeCredentials { JsonSchema, )] struct StakeToCoinJson { - stake_cred: StakeCredential, + stake_cred: Credential, amount: DeltaCoin, } diff --git a/rust/src/protocol_types/certificates/stake_and_vote_delegation.rs b/rust/src/protocol_types/certificates/stake_and_vote_delegation.rs index d78478f9..da5f7cc0 100644 --- a/rust/src/protocol_types/certificates/stake_and_vote_delegation.rs +++ b/rust/src/protocol_types/certificates/stake_and_vote_delegation.rs @@ -14,7 +14,7 @@ use crate::*; )] #[wasm_bindgen] pub struct StakeAndVoteDelegation { - pub(crate) stake_credential: StakeCredential, + pub(crate) stake_credential: Credential, pub(crate) pool_keyhash: Ed25519KeyHash, pub(crate) drep: DRep, } @@ -23,7 +23,7 @@ impl_to_from!(StakeAndVoteDelegation); #[wasm_bindgen] impl StakeAndVoteDelegation { - pub fn stake_credential(&self) -> StakeCredential { + pub fn stake_credential(&self) -> Credential { self.stake_credential.clone() } @@ -36,7 +36,7 @@ impl StakeAndVoteDelegation { } pub fn new( - stake_credential: &StakeCredential, + stake_credential: &Credential, pool_keyhash: &Ed25519KeyHash, drep: &DRep, ) -> Self { diff --git a/rust/src/protocol_types/certificates/stake_delegation.rs b/rust/src/protocol_types/certificates/stake_delegation.rs index 4224e26c..a7d9004e 100644 --- a/rust/src/protocol_types/certificates/stake_delegation.rs +++ b/rust/src/protocol_types/certificates/stake_delegation.rs @@ -14,7 +14,7 @@ use crate::*; JsonSchema, )] pub struct StakeDelegation { - pub(crate) stake_credential: StakeCredential, + pub(crate) stake_credential: Credential, pub(crate) pool_keyhash: Ed25519KeyHash, } @@ -22,7 +22,7 @@ impl_to_from!(StakeDelegation); #[wasm_bindgen] impl StakeDelegation { - pub fn stake_credential(&self) -> StakeCredential { + pub fn stake_credential(&self) -> Credential { self.stake_credential.clone() } @@ -30,7 +30,7 @@ impl StakeDelegation { self.pool_keyhash.clone() } - pub fn new(stake_credential: &StakeCredential, pool_keyhash: &Ed25519KeyHash) -> Self { + pub fn new(stake_credential: &Credential, pool_keyhash: &Ed25519KeyHash) -> Self { Self { stake_credential: stake_credential.clone(), pool_keyhash: pool_keyhash.clone(), diff --git a/rust/src/protocol_types/certificates/stake_deregistration.rs b/rust/src/protocol_types/certificates/stake_deregistration.rs index 80bb5c3a..953bf058 100644 --- a/rust/src/protocol_types/certificates/stake_deregistration.rs +++ b/rust/src/protocol_types/certificates/stake_deregistration.rs @@ -14,7 +14,7 @@ use crate::*; JsonSchema, )] pub struct StakeDeregistration { - pub(crate) stake_credential: StakeCredential, + pub(crate) stake_credential: Credential, pub(crate) coin: Option } @@ -22,7 +22,7 @@ impl_to_from!(StakeDeregistration); #[wasm_bindgen] impl StakeDeregistration { - pub fn stake_credential(&self) -> StakeCredential { + pub fn stake_credential(&self) -> Credential { self.stake_credential.clone() } @@ -30,14 +30,14 @@ impl StakeDeregistration { self.coin.clone() } - pub fn new(stake_credential: &StakeCredential) -> Self { + pub fn new(stake_credential: &Credential) -> Self { Self { stake_credential: stake_credential.clone(), coin: None, } } - pub fn new_with_coin(stake_credential: &StakeCredential, coin: &Coin) -> Self { + pub fn new_with_coin(stake_credential: &Credential, coin: &Coin) -> Self { Self { stake_credential: stake_credential.clone(), coin: Some(coin.clone()) diff --git a/rust/src/protocol_types/certificates/stake_registration.rs b/rust/src/protocol_types/certificates/stake_registration.rs index 6900f445..0d418d4e 100644 --- a/rust/src/protocol_types/certificates/stake_registration.rs +++ b/rust/src/protocol_types/certificates/stake_registration.rs @@ -14,7 +14,7 @@ use crate::*; JsonSchema, )] pub struct StakeRegistration { - pub(crate) stake_credential: StakeCredential, + pub(crate) stake_credential: Credential, pub(crate) coin: Option } @@ -22,7 +22,7 @@ impl_to_from!(StakeRegistration); #[wasm_bindgen] impl StakeRegistration { - pub fn stake_credential(&self) -> StakeCredential { + pub fn stake_credential(&self) -> Credential { self.stake_credential.clone() } @@ -30,14 +30,14 @@ impl StakeRegistration { self.coin.clone() } - pub fn new(stake_credential: &StakeCredential) -> Self { + pub fn new(stake_credential: &Credential) -> Self { Self { stake_credential: stake_credential.clone(), coin: None } } - pub fn new_with_coin(stake_credential: &StakeCredential, coin: &Coin) -> Self { + pub fn new_with_coin(stake_credential: &Credential, coin: &Coin) -> Self { Self { stake_credential: stake_credential.clone(), coin: Some(coin.clone()) diff --git a/rust/src/protocol_types/certificates/stake_registration_and_delegation.rs b/rust/src/protocol_types/certificates/stake_registration_and_delegation.rs index ca0fc446..3ccd8462 100644 --- a/rust/src/protocol_types/certificates/stake_registration_and_delegation.rs +++ b/rust/src/protocol_types/certificates/stake_registration_and_delegation.rs @@ -14,7 +14,7 @@ use crate::*; )] #[wasm_bindgen] pub struct StakeRegistrationAndDelegation { - pub(crate) stake_credential: StakeCredential, + pub(crate) stake_credential: Credential, pub(crate) pool_keyhash: Ed25519KeyHash, pub(crate) coin: Coin, } @@ -23,7 +23,7 @@ impl_to_from!(StakeRegistrationAndDelegation); #[wasm_bindgen] impl StakeRegistrationAndDelegation { - pub fn stake_credential(&self) -> StakeCredential { + pub fn stake_credential(&self) -> Credential { self.stake_credential.clone() } @@ -36,7 +36,7 @@ impl StakeRegistrationAndDelegation { } pub fn new( - stake_credential: &StakeCredential, + stake_credential: &Credential, pool_keyhash: &Ed25519KeyHash, coin: &Coin, ) -> Self { diff --git a/rust/src/protocol_types/certificates/stake_vote_registration_and_delegation.rs b/rust/src/protocol_types/certificates/stake_vote_registration_and_delegation.rs index fb8b8d82..65e38734 100644 --- a/rust/src/protocol_types/certificates/stake_vote_registration_and_delegation.rs +++ b/rust/src/protocol_types/certificates/stake_vote_registration_and_delegation.rs @@ -14,7 +14,7 @@ use crate::*; )] #[wasm_bindgen] pub struct StakeVoteRegistrationAndDelegation { - pub(crate) stake_credential: StakeCredential, + pub(crate) stake_credential: Credential, pub(crate) pool_keyhash: Ed25519KeyHash, pub(crate) drep: DRep, pub(crate) coin: Coin, @@ -24,7 +24,7 @@ impl_to_from!(StakeVoteRegistrationAndDelegation); #[wasm_bindgen] impl StakeVoteRegistrationAndDelegation { - pub fn stake_credential(&self) -> StakeCredential { + pub fn stake_credential(&self) -> Credential { self.stake_credential.clone() } @@ -41,7 +41,7 @@ impl StakeVoteRegistrationAndDelegation { } pub fn new( - stake_credential: &StakeCredential, + stake_credential: &Credential, pool_keyhash: &Ed25519KeyHash, drep: &DRep, coin: &Coin, diff --git a/rust/src/protocol_types/certificates/vote_delegation.rs b/rust/src/protocol_types/certificates/vote_delegation.rs index b75ff4f6..a0e21ea2 100644 --- a/rust/src/protocol_types/certificates/vote_delegation.rs +++ b/rust/src/protocol_types/certificates/vote_delegation.rs @@ -14,7 +14,7 @@ use crate::*; JsonSchema, )] pub struct VoteDelegation { - pub(crate) stake_credential: StakeCredential, + pub(crate) stake_credential: Credential, pub(crate) drep: DRep, } @@ -22,7 +22,7 @@ impl_to_from!(VoteDelegation); #[wasm_bindgen] impl VoteDelegation { - pub fn stake_credential(&self) -> StakeCredential { + pub fn stake_credential(&self) -> Credential { self.stake_credential.clone() } @@ -30,7 +30,7 @@ impl VoteDelegation { self.drep.clone() } - pub fn new(stake_credential: &StakeCredential, drep: &DRep) -> Self { + pub fn new(stake_credential: &Credential, drep: &DRep) -> Self { Self { stake_credential: stake_credential.clone(), drep: drep.clone(), diff --git a/rust/src/protocol_types/certificates/vote_registration_and_delegation.rs b/rust/src/protocol_types/certificates/vote_registration_and_delegation.rs index 6ab63cf6..0426b254 100644 --- a/rust/src/protocol_types/certificates/vote_registration_and_delegation.rs +++ b/rust/src/protocol_types/certificates/vote_registration_and_delegation.rs @@ -14,7 +14,7 @@ use crate::*; )] #[wasm_bindgen] pub struct VoteRegistrationAndDelegation { - pub(crate) stake_credential: StakeCredential, + pub(crate) stake_credential: Credential, pub(crate) drep: DRep, pub(crate) coin: Coin, } @@ -23,7 +23,7 @@ impl_to_from!(VoteRegistrationAndDelegation); #[wasm_bindgen] impl VoteRegistrationAndDelegation { - pub fn stake_credential(&self) -> StakeCredential { + pub fn stake_credential(&self) -> Credential { self.stake_credential.clone() } @@ -35,7 +35,7 @@ impl VoteRegistrationAndDelegation { self.coin.clone() } - pub fn new(stake_credential: &StakeCredential, drep: &DRep, coin: &Coin) -> Self { + pub fn new(stake_credential: &Credential, drep: &DRep, coin: &Coin) -> Self { Self { stake_credential: stake_credential.clone(), drep: drep.clone(), diff --git a/rust/src/protocol_types/governance/proposals/committee.rs b/rust/src/protocol_types/governance/proposals/committee.rs index 651a45fc..1de43d63 100644 --- a/rust/src/protocol_types/governance/proposals/committee.rs +++ b/rust/src/protocol_types/governance/proposals/committee.rs @@ -16,7 +16,7 @@ use std::collections::BTreeMap; JsonSchema, )] struct CommitteeMember { - stake_credential: StakeCredential, + stake_credential: Credential, term_limit: Epoch, } @@ -40,7 +40,7 @@ struct CommitteeJsonStruct { #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] #[wasm_bindgen] pub struct Committee { - pub(crate) members: BTreeMap, + pub(crate) members: BTreeMap, pub(crate) quorum_threshold: UnitInterval, } @@ -63,12 +63,12 @@ impl Committee { self.quorum_threshold.clone() } - pub fn add_member(&mut self, committee_cold_credential: &StakeCredential, epoch: Epoch) { + pub fn add_member(&mut self, committee_cold_credential: &Credential, epoch: Epoch) { self.members .insert(committee_cold_credential.clone(), epoch); } - pub fn get_member_epoch(&self, committee_cold_credential: &StakeCredential) -> Option { + pub fn get_member_epoch(&self, committee_cold_credential: &Credential) -> Option { self.members.get(committee_cold_credential).cloned() } } diff --git a/rust/src/protocol_types/governance/proposals/new_committee_proposal.rs b/rust/src/protocol_types/governance/proposals/new_committee_proposal.rs index c7216526..ac526914 100644 --- a/rust/src/protocol_types/governance/proposals/new_committee_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/new_committee_proposal.rs @@ -16,7 +16,7 @@ use crate::*; pub struct NewCommitteeProposal { pub(crate) gov_action_id: Option, pub(crate) committee: Committee, - pub(crate) members_to_remove: BTreeSet, + pub(crate) members_to_remove: BTreeSet, } impl_to_from!(NewCommitteeProposal); diff --git a/rust/src/protocol_types/governance/voter.rs b/rust/src/protocol_types/governance/voter.rs index 3213f184..38af069f 100644 --- a/rust/src/protocol_types/governance/voter.rs +++ b/rust/src/protocol_types/governance/voter.rs @@ -13,8 +13,8 @@ use crate::*; JsonSchema, )] pub(crate) enum VoterEnum { - ConstitutionalCommitteeHotKey(StakeCredential), - DRep(StakeCredential), + ConstitutionalCommitteeHotKey(Credential), + DRep(Credential), StakingPool(Ed25519KeyHash), } @@ -47,11 +47,11 @@ impl_to_from!(Voter); #[wasm_bindgen] impl Voter { - pub fn new_constitutional_committee_hot_key(cred: &StakeCredential) -> Self { + pub fn new_constitutional_committee_hot_key(cred: &Credential) -> Self { Self(VoterEnum::ConstitutionalCommitteeHotKey(cred.clone())) } - pub fn new_drep(cred: &StakeCredential) -> Self { + pub fn new_drep(cred: &Credential) -> Self { Self(VoterEnum::DRep(cred.clone())) } @@ -73,14 +73,14 @@ impl Voter { } } - pub fn to_constitutional_committee_hot_key(&self) -> Option { + pub fn to_constitutional_committee_hot_key(&self) -> Option { match &self.0 { VoterEnum::ConstitutionalCommitteeHotKey(cred) => Some(cred.clone()), _ => None, } } - pub fn to_drep(&self) -> Option { + pub fn to_drep(&self) -> Option { match &self.0 { VoterEnum::DRep(cred) => Some(cred.clone()), _ => None, diff --git a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs index 3f77ad56..1ed3a5ac 100644 --- a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs @@ -32,7 +32,7 @@ impl DeserializeEmbeddedGroup for CommitteeHotKeyDeregistration { deserialize_and_check_index(raw, cert_index, "cert_index")?; let committee_cold_key = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("committee_cold_key"))?; + Credential::deserialize(raw).map_err(|e| e.annotate("committee_cold_key"))?; Ok(CommitteeHotKeyDeregistration { committee_cold_key }) } diff --git a/rust/src/serialization/certificates/committee_hot_key_registration.rs b/rust/src/serialization/certificates/committee_hot_key_registration.rs index a9f921f0..acf0d72f 100644 --- a/rust/src/serialization/certificates/committee_hot_key_registration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_registration.rs @@ -38,10 +38,10 @@ impl DeserializeEmbeddedGroup for CommitteeHotKeyRegistration { deserialize_and_check_index(raw, cert_index, "cert_index")?; let committee_cold_key = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("committee_cold_key"))?; + Credential::deserialize(raw).map_err(|e| e.annotate("committee_cold_key"))?; let committee_hot_key = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("committee_hot_key"))?; + Credential::deserialize(raw).map_err(|e| e.annotate("committee_hot_key"))?; return Ok(CommitteeHotKeyRegistration { committee_cold_key, diff --git a/rust/src/serialization/certificates/drep_deregistration.rs b/rust/src/serialization/certificates/drep_deregistration.rs index d9eee988..22d6268c 100644 --- a/rust/src/serialization/certificates/drep_deregistration.rs +++ b/rust/src/serialization/certificates/drep_deregistration.rs @@ -34,7 +34,7 @@ impl DeserializeEmbeddedGroup for DrepDeregistration { deserialize_and_check_index(raw, cert_index, "cert_index")?; let voting_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("voting_credential"))?; + Credential::deserialize(raw).map_err(|e| e.annotate("voting_credential"))?; let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; diff --git a/rust/src/serialization/certificates/drep_registration.rs b/rust/src/serialization/certificates/drep_registration.rs index 563bac37..0dee8693 100644 --- a/rust/src/serialization/certificates/drep_registration.rs +++ b/rust/src/serialization/certificates/drep_registration.rs @@ -42,7 +42,7 @@ impl DeserializeEmbeddedGroup for DrepRegistration { deserialize_and_check_index(raw, cert_index, "cert_index")?; let voting_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("voting_credential"))?; + Credential::deserialize(raw).map_err(|e| e.annotate("voting_credential"))?; let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; diff --git a/rust/src/serialization/certificates/drep_update.rs b/rust/src/serialization/certificates/drep_update.rs index c9cec21e..e4afe5d0 100644 --- a/rust/src/serialization/certificates/drep_update.rs +++ b/rust/src/serialization/certificates/drep_update.rs @@ -37,7 +37,7 @@ impl DeserializeEmbeddedGroup for DrepUpdate { deserialize_and_check_index(raw, cert_index, "cert_index")?; let voting_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("voting_credential"))?; + Credential::deserialize(raw).map_err(|e| e.annotate("voting_credential"))?; let anchor = Anchor::deserialize_nullable(raw).map_err(|e| e.annotate("anchor"))?; diff --git a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs index a5c2dc17..0d685cc5 100644 --- a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs +++ b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs @@ -32,7 +32,7 @@ impl Deserialize for MIRToStakeCredentials { assert_eq!(raw.special()?, CBORSpecial::Break); break; } - let key = StakeCredential::deserialize(raw)?; + let key = Credential::deserialize(raw)?; let value = DeltaCoin::deserialize(raw)?; if table.insert(key.clone(), value).is_some() { return Err(DeserializeFailure::DuplicateKey(Key::Str(format!( diff --git a/rust/src/serialization/certificates/stake_and_vote_delegation.rs b/rust/src/serialization/certificates/stake_and_vote_delegation.rs index fa7dd3ab..48b28088 100644 --- a/rust/src/serialization/certificates/stake_and_vote_delegation.rs +++ b/rust/src/serialization/certificates/stake_and_vote_delegation.rs @@ -34,7 +34,7 @@ impl DeserializeEmbeddedGroup for StakeAndVoteDelegation { deserialize_and_check_index(raw, cert_index, "cert_index")?; let stake_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + Credential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; let pool_keyhash = Ed25519KeyHash::deserialize(raw).map_err(|e| e.annotate("pool_keyhash"))?; diff --git a/rust/src/serialization/certificates/stake_delegation.rs b/rust/src/serialization/certificates/stake_delegation.rs index bea77b56..d76fd361 100644 --- a/rust/src/serialization/certificates/stake_delegation.rs +++ b/rust/src/serialization/certificates/stake_delegation.rs @@ -41,7 +41,7 @@ impl DeserializeEmbeddedGroup for StakeDelegation { deserialize_and_check_index(raw, cert_index, "cert_index")?; let stake_credential = - (|| -> Result<_, DeserializeError> { Ok(StakeCredential::deserialize(raw)?) })() + (|| -> Result<_, DeserializeError> { Ok(Credential::deserialize(raw)?) })() .map_err(|e| e.annotate("stake_credential"))?; let pool_keyhash = (|| -> Result<_, DeserializeError> { Ok(Ed25519KeyHash::deserialize(raw)?) })() diff --git a/rust/src/serialization/certificates/stake_deregistration.rs b/rust/src/serialization/certificates/stake_deregistration.rs index 404ab8e4..3da22f65 100644 --- a/rust/src/serialization/certificates/stake_deregistration.rs +++ b/rust/src/serialization/certificates/stake_deregistration.rs @@ -85,7 +85,7 @@ fn deserialize_legacy( check_index(cert_index, desired_index, "cert_index")?; let stake_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + Credential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; return Ok(StakeDeregistration { stake_credential, @@ -106,7 +106,7 @@ fn deserialize_conway( check_index(cert_index, desired_index, "cert_index")?; let stake_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + Credential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; diff --git a/rust/src/serialization/certificates/stake_registration.rs b/rust/src/serialization/certificates/stake_registration.rs index 2e4ce59c..b52b74a9 100644 --- a/rust/src/serialization/certificates/stake_registration.rs +++ b/rust/src/serialization/certificates/stake_registration.rs @@ -85,7 +85,7 @@ fn deserialize_legacy( check_index(cert_index, desired_index, "cert_index")?; let stake_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + Credential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; return Ok(StakeRegistration { stake_credential, @@ -106,7 +106,7 @@ fn deserialize_conway( check_index(cert_index, desired_index, "cert_index")?; let stake_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + Credential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; diff --git a/rust/src/serialization/certificates/stake_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_registration_and_delegation.rs index 1424d28d..92031bc5 100644 --- a/rust/src/serialization/certificates/stake_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/stake_registration_and_delegation.rs @@ -34,7 +34,7 @@ impl DeserializeEmbeddedGroup for StakeRegistrationAndDelegation { deserialize_and_check_index(raw, cert_index, "cert_index")?; let stake_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + Credential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; let pool_keyhash = Ed25519KeyHash::deserialize(raw).map_err(|e| e.annotate("pool_keyhash"))?; diff --git a/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs index 6fd1b891..19570e47 100644 --- a/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs @@ -43,7 +43,7 @@ impl DeserializeEmbeddedGroup for StakeVoteRegistrationAndDelegation { deserialize_and_check_index(raw, cert_index, "cert_index")?; let stake_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + Credential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; let pool_keyhash = Ed25519KeyHash::deserialize(raw).map_err(|e| e.annotate("pool_keyhash"))?; diff --git a/rust/src/serialization/certificates/vote_delegation.rs b/rust/src/serialization/certificates/vote_delegation.rs index e2fbf482..f84b07ac 100644 --- a/rust/src/serialization/certificates/vote_delegation.rs +++ b/rust/src/serialization/certificates/vote_delegation.rs @@ -33,7 +33,7 @@ impl DeserializeEmbeddedGroup for VoteDelegation { deserialize_and_check_index(raw, cert_index, "cert_index")?; let stake_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + Credential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; let drep = DRep::deserialize(raw).map_err(|e| e.annotate("drep"))?; diff --git a/rust/src/serialization/certificates/vote_registration_and_delegation.rs b/rust/src/serialization/certificates/vote_registration_and_delegation.rs index d5360491..fadc717e 100644 --- a/rust/src/serialization/certificates/vote_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/vote_registration_and_delegation.rs @@ -35,7 +35,7 @@ impl DeserializeEmbeddedGroup for VoteRegistrationAndDelegation { deserialize_and_check_index(raw, desired_index, "cert_index")?; let stake_credential = - StakeCredential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; + Credential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?; let drep = DRep::deserialize(raw).map_err(|e| e.annotate("drep"))?; diff --git a/rust/src/serialization/general.rs b/rust/src/serialization/general.rs index 77d943a5..8424d4b7 100644 --- a/rust/src/serialization/general.rs +++ b/rust/src/serialization/general.rs @@ -1194,7 +1194,7 @@ impl Deserialize for StakeCredentials { assert_eq!(raw.special()?, CBORSpecial::Break); break; } - arr.push(StakeCredential::deserialize(raw)?); + arr.push(Credential::deserialize(raw)?); } Ok(()) })() @@ -4474,7 +4474,7 @@ mod tests { assert_eq!(treasury_to_pot.to_bytes(), treasury_to_pot_deser.to_bytes()); let mut stake_creds = MIRToStakeCredentials::new(); stake_creds.insert( - &StakeCredential::from_scripthash(&ScriptHash([54u8; ScriptHash::BYTE_COUNT])), + &Credential::from_scripthash(&ScriptHash([54u8; ScriptHash::BYTE_COUNT])), &Int::new_i32(-314159265), ); let to_stake_creds = diff --git a/rust/src/serialization/governance/proposals/committee.rs b/rust/src/serialization/governance/proposals/committee.rs index 365ef8aa..ac459663 100644 --- a/rust/src/serialization/governance/proposals/committee.rs +++ b/rust/src/serialization/governance/proposals/committee.rs @@ -38,7 +38,7 @@ impl DeserializeEmbeddedGroup for Committee { assert_eq!(raw.special()?, CBORSpecial::Break); break; } - let key = StakeCredential::deserialize(raw)?; + let key = Credential::deserialize(raw)?; let value = Epoch::deserialize(raw)?; if table.insert(key.clone(), value).is_some() { return Err(DeserializeFailure::DuplicateKey(Key::Str(String::from( diff --git a/rust/src/serialization/governance/voter.rs b/rust/src/serialization/governance/voter.rs index 848337b9..56418440 100644 --- a/rust/src/serialization/governance/voter.rs +++ b/rust/src/serialization/governance/voter.rs @@ -70,16 +70,16 @@ impl Deserialize for VoterEnum { } } let voter = match raw.unsigned_integer()? { - 0 => VoterEnum::ConstitutionalCommitteeHotKey(StakeCredential(StakeCredType::Key( + 0 => VoterEnum::ConstitutionalCommitteeHotKey(Credential(StakeCredType::Key( Ed25519KeyHash::deserialize(raw)?, ))), - 1 => VoterEnum::ConstitutionalCommitteeHotKey(StakeCredential( + 1 => VoterEnum::ConstitutionalCommitteeHotKey(Credential( StakeCredType::Script(ScriptHash::deserialize(raw)?), )), - 2 => VoterEnum::DRep(StakeCredential(StakeCredType::Key( + 2 => VoterEnum::DRep(Credential(StakeCredType::Key( Ed25519KeyHash::deserialize(raw)?, ))), - 3 => VoterEnum::DRep(StakeCredential(StakeCredType::Script( + 3 => VoterEnum::DRep(Credential(StakeCredType::Script( ScriptHash::deserialize(raw)?, ))), 4 => VoterEnum::StakingPool(Ed25519KeyHash::deserialize(raw)?), diff --git a/rust/src/tests/address.rs b/rust/src/tests/address.rs index 34bd63c1..46873860 100644 --- a/rust/src/tests/address.rs +++ b/rust/src/tests/address.rs @@ -21,8 +21,8 @@ fn variable_nat_decode_too_big() { fn base_serialize_consistency() { let base = BaseAddress::new( 5, - &StakeCredential::from_keyhash(&Ed25519KeyHash::from([23; Ed25519KeyHash::BYTE_COUNT])), - &StakeCredential::from_scripthash(&ScriptHash::from([42; ScriptHash::BYTE_COUNT])), + &Credential::from_keyhash(&Ed25519KeyHash::from([23; Ed25519KeyHash::BYTE_COUNT])), + &Credential::from_scripthash(&ScriptHash::from([42; ScriptHash::BYTE_COUNT])), ); let addr = base.to_address(); let addr2 = Address::from_bytes(addr.to_bytes()).unwrap(); @@ -33,7 +33,7 @@ fn base_serialize_consistency() { fn ptr_serialize_consistency() { let ptr = PointerAddress::new( 25, - &StakeCredential::from_keyhash(&Ed25519KeyHash::from([23; Ed25519KeyHash::BYTE_COUNT])), + &Credential::from_keyhash(&Ed25519KeyHash::from([23; Ed25519KeyHash::BYTE_COUNT])), &Pointer::new_pointer(&to_bignum(2354556573), &to_bignum(127), &to_bignum(0)), ); let addr = ptr.to_address(); @@ -45,7 +45,7 @@ fn ptr_serialize_consistency() { fn enterprise_serialize_consistency() { let enterprise = EnterpriseAddress::new( 64, - &StakeCredential::from_keyhash(&Ed25519KeyHash::from([23; Ed25519KeyHash::BYTE_COUNT])), + &Credential::from_keyhash(&Ed25519KeyHash::from([23; Ed25519KeyHash::BYTE_COUNT])), ); let addr = enterprise.to_address(); let addr2 = Address::from_bytes(addr.to_bytes()).unwrap(); @@ -56,7 +56,7 @@ fn enterprise_serialize_consistency() { fn reward_serialize_consistency() { let reward = RewardAddress::new( 9, - &StakeCredential::from_scripthash(&ScriptHash::from([127; Ed25519KeyHash::BYTE_COUNT])), + &Credential::from_scripthash(&ScriptHash::from([127; Ed25519KeyHash::BYTE_COUNT])), ); let addr = reward.to_address(); let addr2 = Address::from_bytes(addr.to_bytes()).unwrap(); @@ -150,8 +150,8 @@ fn bip32_12_base() { .derive(2) .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -177,7 +177,7 @@ fn bip32_12_enterprise() { .derive(0) .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(); assert_eq!( @@ -201,7 +201,7 @@ fn bip32_12_pointer() { .derive(0) .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = PointerAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -240,8 +240,8 @@ fn bip32_15_base() { .derive(2) .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -267,7 +267,7 @@ fn bip32_15_enterprise() { .derive(0) .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(); assert_eq!( @@ -291,7 +291,7 @@ fn bip32_15_pointer() { .derive(0) .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = PointerAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -374,8 +374,8 @@ fn bip32_24_base() { .derive(2) .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -401,7 +401,7 @@ fn bip32_24_enterprise() { .derive(0) .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(); assert_eq!( @@ -425,7 +425,7 @@ fn bip32_24_pointer() { .derive(0) .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = PointerAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -457,7 +457,7 @@ fn bip32_12_reward() { .derive(2) .derive(0) .to_public(); - let staking_cred = StakeCredential::from_keyhash(&staking_key.to_raw_key().hash()); + let staking_cred = Credential::from_keyhash(&staking_key.to_raw_key().hash()); let addr_net_0 = RewardAddress::new(NetworkInfo::testnet().network_id(), &staking_cred).to_address(); assert_eq!( @@ -488,8 +488,8 @@ fn bip32_24_base_multisig_hd_derivation() { .derive(2) .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -527,8 +527,8 @@ fn multisig_from_script() { let script_hash = ScriptHash::from_bytes(oneof_native_script.hash().to_bytes()).unwrap(); - let spend_cred = StakeCredential::from_scripthash(&script_hash); - let stake_cred = StakeCredential::from_scripthash(&script_hash); + let spend_cred = Credential::from_scripthash(&script_hash); + let stake_cred = Credential::from_scripthash(&script_hash); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, diff --git a/rust/src/tests/serialization/certificates.rs b/rust/src/tests/serialization/certificates.rs index f5ca0e5f..776c736e 100644 --- a/rust/src/tests/serialization/certificates.rs +++ b/rust/src/tests/serialization/certificates.rs @@ -36,7 +36,7 @@ macro_rules! to_from_test { #[test] fn committee_hot_key_deregistration_key_hash_ser_round_trip() { let cert = - CommitteeHotKeyDeregistration::new(&StakeCredential::from_keyhash(&fake_key_hash(1))); + CommitteeHotKeyDeregistration::new(&Credential::from_keyhash(&fake_key_hash(1))); let cert_wrapped = Certificate::new_committee_hot_key_deregistration(&cert); to_from_test!(CommitteeHotKeyDeregistration, cert, cert_wrapped); assert_eq!( @@ -48,7 +48,7 @@ fn committee_hot_key_deregistration_key_hash_ser_round_trip() { #[test] fn committee_hot_key_deregistration_script_hash_ser_round_trip() { let cert = - CommitteeHotKeyDeregistration::new(&StakeCredential::from_scripthash(&fake_script_hash(1))); + CommitteeHotKeyDeregistration::new(&Credential::from_scripthash(&fake_script_hash(1))); let cert_wrapped = Certificate::new_committee_hot_key_deregistration(&cert); to_from_test!(CommitteeHotKeyDeregistration, cert, cert_wrapped); assert_eq!( @@ -60,8 +60,8 @@ fn committee_hot_key_deregistration_script_hash_ser_round_trip() { #[test] fn committee_hot_key_registration_ser_round_trip() { let cert = CommitteeHotKeyRegistration::new( - &StakeCredential::from_keyhash(&fake_key_hash(1)), - &StakeCredential::from_keyhash(&fake_key_hash(2)), + &Credential::from_keyhash(&fake_key_hash(1)), + &Credential::from_keyhash(&fake_key_hash(2)), ); let cert_wrapped = Certificate::new_committee_hot_key_registration(&cert); to_from_test!(CommitteeHotKeyRegistration, cert, cert_wrapped); @@ -74,7 +74,7 @@ fn committee_hot_key_registration_ser_round_trip() { #[test] fn drep_registration_ser_round_trip() { let cert = DrepRegistration::new( - &StakeCredential::from_keyhash(&fake_key_hash(1)), + &Credential::from_keyhash(&fake_key_hash(1)), &Coin::from(100u64), ); let cert_wrapped = Certificate::new_drep_registration(&cert); @@ -88,7 +88,7 @@ fn drep_registration_with_anchor_ser_round_trip() { let anchor = Anchor::new(&url, &fake_anchor_data_hash(255)); let cert = DrepRegistration::new_with_anchor( - &StakeCredential::from_keyhash(&fake_key_hash(1)), + &Credential::from_keyhash(&fake_key_hash(1)), &Coin::from(100u64), &anchor, ); @@ -100,7 +100,7 @@ fn drep_registration_with_anchor_ser_round_trip() { #[test] fn drep_deregistration_ser_round_trip() { let cert = DrepDeregistration::new( - &StakeCredential::from_keyhash(&fake_key_hash(1)), + &Credential::from_keyhash(&fake_key_hash(1)), &Coin::from(100u64), ); let cert_wrapped = Certificate::new_drep_deregistration(&cert); @@ -110,7 +110,7 @@ fn drep_deregistration_ser_round_trip() { #[test] fn drep_update_ser_round_trip() { - let cert = DrepUpdate::new(&StakeCredential::from_keyhash(&fake_key_hash(1))); + let cert = DrepUpdate::new(&Credential::from_keyhash(&fake_key_hash(1))); let cert_wrapped = Certificate::new_drep_update(&cert); to_from_test!(DrepUpdate, cert, cert_wrapped); assert_eq!(cert, cert_wrapped.as_drep_update().unwrap()); @@ -121,7 +121,7 @@ fn drep_update_with_anchor_ser_round_trip() { let url = URL::new("https://iohk.io".to_string()).unwrap(); let anchor = Anchor::new(&url, &fake_anchor_data_hash(255)); let cert = - DrepUpdate::new_with_anchor(&StakeCredential::from_keyhash(&fake_key_hash(1)), &anchor); + DrepUpdate::new_with_anchor(&Credential::from_keyhash(&fake_key_hash(1)), &anchor); let cert_wrapped = Certificate::new_drep_update(&cert); to_from_test!(DrepUpdate, cert, cert_wrapped); assert_eq!(cert, cert_wrapped.as_drep_update().unwrap()); @@ -158,12 +158,12 @@ fn move_instantaneous_reward_to_pot_ser_round_trip() { fn move_instantaneous_reward_to_stake_creds_ser_round_trip() { let mut amounts = MIRToStakeCredentials::new(); amounts.insert( - &StakeCredential::from_keyhash(&fake_key_hash(1)), + &Credential::from_keyhash(&fake_key_hash(1)), &DeltaCoin::new(&BigNum::from(100u64)), ); let mut amounts = MIRToStakeCredentials::new(); amounts.insert( - &StakeCredential::from_keyhash(&fake_key_hash(2)), + &Credential::from_keyhash(&fake_key_hash(2)), &DeltaCoin::new(&BigNum::from(1200u64)), ); let cert = MoveInstantaneousReward::new_to_stake_creds(MIRPot::Treasury, &amounts); @@ -181,7 +181,7 @@ fn move_instantaneous_reward_to_stake_creds_ser_round_trip() { #[test] fn pool_registration_ser_round_trip() { - let staking_cred = StakeCredential::from_keyhash(&fake_key_hash(1)); + let staking_cred = Credential::from_keyhash(&fake_key_hash(1)); let reward_address = RewardAddress::new(NetworkInfo::testnet().network_id(), &staking_cred); let mut owners = Ed25519KeyHashes::new(); owners.add(&fake_key_hash(2)); @@ -235,7 +235,7 @@ fn stake_and_vote_delegation_ser_round_trip() { let drep = DRep::new_key_hash(&fake_key_hash(3)); let cert = StakeAndVoteDelegation::new( - &StakeCredential::from_keyhash(&fake_key_hash(1)), + &Credential::from_keyhash(&fake_key_hash(1)), &fake_key_hash(2), &drep, ); @@ -247,7 +247,7 @@ fn stake_and_vote_delegation_ser_round_trip() { #[test] fn stake_delegation_ser_round_trip() { let cert = StakeDelegation::new( - &StakeCredential::from_keyhash(&fake_key_hash(1)), + &Credential::from_keyhash(&fake_key_hash(1)), &fake_key_hash(2), ); let cert_wrapped = Certificate::new_stake_delegation(&cert); @@ -257,7 +257,7 @@ fn stake_delegation_ser_round_trip() { #[test] fn stake_deregistration_ser_round_trip() { - let cert = StakeDeregistration::new(&StakeCredential::from_keyhash(&fake_key_hash(1))); + let cert = StakeDeregistration::new(&Credential::from_keyhash(&fake_key_hash(1))); let cert_wrapped = Certificate::new_stake_deregistration(&cert); to_from_test!(StakeDeregistration, cert, cert_wrapped); assert_eq!(cert, cert_wrapped.as_stake_deregistration().unwrap()); @@ -266,7 +266,7 @@ fn stake_deregistration_ser_round_trip() { #[test] fn stake_deregistration_with_coin_ser_round_trip() { let cert = StakeDeregistration::new_with_coin( - &StakeCredential::from_keyhash(&fake_key_hash(1)), + &Credential::from_keyhash(&fake_key_hash(1)), &Coin::from(100u64), ); let cert_wrapped = Certificate::new_stake_deregistration(&cert); @@ -276,7 +276,7 @@ fn stake_deregistration_with_coin_ser_round_trip() { #[test] fn stake_registration_ser_round_trip() { - let cert = StakeRegistration::new(&StakeCredential::from_keyhash(&fake_key_hash(1))); + let cert = StakeRegistration::new(&Credential::from_keyhash(&fake_key_hash(1))); let cert_wrapped = Certificate::new_stake_registration(&cert); to_from_test!(StakeRegistration, cert, cert_wrapped); assert_eq!(cert, cert_wrapped.as_stake_registration().unwrap()); @@ -285,7 +285,7 @@ fn stake_registration_ser_round_trip() { #[test] fn stake_registration_with_coin_ser_round_trip() { let cert = StakeRegistration::new_with_coin( - &StakeCredential::from_keyhash(&fake_key_hash(1)), + &Credential::from_keyhash(&fake_key_hash(1)), &Coin::from(100u64), ); let cert_wrapped = Certificate::new_stake_registration(&cert); @@ -296,7 +296,7 @@ fn stake_registration_with_coin_ser_round_trip() { #[test] fn stake_registration_and_delegation_ser_round_trip() { let cert = StakeRegistrationAndDelegation::new( - &StakeCredential::from_keyhash(&fake_key_hash(1)), + &Credential::from_keyhash(&fake_key_hash(1)), &fake_key_hash(2), &Coin::from(100u64), ); @@ -312,7 +312,7 @@ fn stake_registration_and_delegation_ser_round_trip() { fn stake_vote_registration_and_delegation_ser_round_trip() { let drep = DRep::new_key_hash(&fake_key_hash(3)); let cert = StakeVoteRegistrationAndDelegation::new( - &StakeCredential::from_keyhash(&fake_key_hash(1)), + &Credential::from_keyhash(&fake_key_hash(1)), &fake_key_hash(2), &drep, &Coin::from(100u64), @@ -331,7 +331,7 @@ fn stake_vote_registration_and_delegation_ser_round_trip() { fn vote_delegation_ser_round_trip() { let drep = DRep::new_key_hash(&fake_key_hash(3)); let cert = VoteDelegation::new( - &StakeCredential::from_keyhash(&fake_key_hash(1)), + &Credential::from_keyhash(&fake_key_hash(1)), &drep ); let cert_wrapped = Certificate::new_vote_delegation(&cert); @@ -343,7 +343,7 @@ fn vote_delegation_ser_round_trip() { fn vote_registration_and_delegation_ser_round_trip() { let drep = DRep::new_key_hash(&fake_key_hash(3)); let cert = VoteRegistrationAndDelegation::new( - &StakeCredential::from_keyhash(&fake_key_hash(1)), + &Credential::from_keyhash(&fake_key_hash(1)), &drep, &Coin::from(100u64), ); diff --git a/rust/src/tests/serialization/governance/common.rs b/rust/src/tests/serialization/governance/common.rs index 3bf1dffb..8d5f5fda 100644 --- a/rust/src/tests/serialization/governance/common.rs +++ b/rust/src/tests/serialization/governance/common.rs @@ -92,7 +92,7 @@ fn governance_action_id_ser_round_trip() { #[test] fn voter_constitutional_committee_hot_key_hash_ser_round_trip() { - let voter = Voter::new_constitutional_committee_hot_key(&StakeCredential::from_keyhash( + let voter = Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash( &fake_key_hash(1), )); @@ -108,7 +108,7 @@ fn voter_constitutional_committee_hot_key_hash_ser_round_trip() { #[test] fn voter_constitutional_committee_hot_script_hash_ser_round_trip() { - let voter = Voter::new_constitutional_committee_hot_key(&StakeCredential::from_scripthash( + let voter = Voter::new_constitutional_committee_hot_key(&Credential::from_scripthash( &fake_script_hash(1), )); @@ -127,7 +127,7 @@ fn voter_constitutional_committee_hot_script_hash_ser_round_trip() { #[test] fn voter_drep_key_hash_ser_round_trip() { - let voter = Voter::new_drep(&StakeCredential::from_keyhash(&fake_key_hash(1))); + let voter = Voter::new_drep(&Credential::from_keyhash(&fake_key_hash(1))); let cbor = voter.to_bytes(); let cbor_hex = voter.to_hex(); @@ -141,7 +141,7 @@ fn voter_drep_key_hash_ser_round_trip() { #[test] fn voter_drep_script_hash_ser_round_trip() { - let voter = Voter::new_drep(&StakeCredential::from_scripthash(&fake_script_hash(1))); + let voter = Voter::new_drep(&Credential::from_scripthash(&fake_script_hash(1))); let cbor = voter.to_bytes(); let cbor_hex = voter.to_hex(); @@ -223,7 +223,7 @@ fn voting_procedures_single_item_ser_round_trip() { let mut voting_procedures = VotingProcedures::new(); voting_procedures.insert( - &Voter::new_constitutional_committee_hot_key(&StakeCredential::from_keyhash( + &Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash( &fake_key_hash(1), )), &GovernanceActionId::new(&fake_tx_hash(1), GovernanceActionIndex::from(42u32)), @@ -253,7 +253,7 @@ fn voting_procedures_muiltiple_items_ser_round_trip() { let mut voting_procedures = VotingProcedures::new(); voting_procedures.insert( - &Voter::new_constitutional_committee_hot_key(&StakeCredential::from_keyhash( + &Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash( &fake_key_hash(1), )), &GovernanceActionId::new(&fake_tx_hash(1), GovernanceActionIndex::from(42u32)), @@ -261,7 +261,7 @@ fn voting_procedures_muiltiple_items_ser_round_trip() { ); voting_procedures.insert( - &Voter::new_constitutional_committee_hot_key(&StakeCredential::from_keyhash( + &Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash( &fake_key_hash(2), )), &GovernanceActionId::new(&fake_tx_hash(2), GovernanceActionIndex::from(43u32)), @@ -269,7 +269,7 @@ fn voting_procedures_muiltiple_items_ser_round_trip() { ); voting_procedures.insert( - &Voter::new_constitutional_committee_hot_key(&StakeCredential::from_keyhash( + &Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash( &fake_key_hash(3), )), &GovernanceActionId::new(&fake_tx_hash(3), GovernanceActionIndex::from(44u32)), diff --git a/rust/src/tests/serialization/governance/proposals.rs b/rust/src/tests/serialization/governance/proposals.rs index a889a7ec..10620573 100644 --- a/rust/src/tests/serialization/governance/proposals.rs +++ b/rust/src/tests/serialization/governance/proposals.rs @@ -38,8 +38,8 @@ macro_rules! to_from_test { fn committee_ser_round_trip() { let mut committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); - committee.add_member(&StakeCredential::from_keyhash(&fake_key_hash(1)), 1); - committee.add_member(&StakeCredential::from_scripthash(&fake_script_hash(2)), 2); + committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); + committee.add_member(&Credential::from_scripthash(&fake_script_hash(2)), 2); let cbor = committee.to_bytes(); let cbor_hex = committee.to_hex(); @@ -132,12 +132,12 @@ fn hard_fork_initiation_proposal_with_action_id_ser_round_trip() { fn new_committee_proposal_ser_round_trip() { let mut committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); - committee.add_member(&StakeCredential::from_keyhash(&fake_key_hash(1)), 1); - committee.add_member(&StakeCredential::from_scripthash(&fake_script_hash(2)), 2); + committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); + committee.add_member(&Credential::from_scripthash(&fake_script_hash(2)), 2); let mut members_to_remove = StakeCredentials::new(); - members_to_remove.add(&StakeCredential::from_keyhash(&fake_key_hash(1))); - members_to_remove.add(&StakeCredential::from_scripthash(&fake_script_hash(2))); + members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); + members_to_remove.add(&Credential::from_scripthash(&fake_script_hash(2))); let proposal = NewCommitteeProposal::new(&committee, &members_to_remove); @@ -155,12 +155,12 @@ fn new_committee_proposal_with_action_id_ser_round_trip() { let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); let mut committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); - committee.add_member(&StakeCredential::from_keyhash(&fake_key_hash(1)), 1); - committee.add_member(&StakeCredential::from_scripthash(&fake_script_hash(2)), 2); + committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); + committee.add_member(&Credential::from_scripthash(&fake_script_hash(2)), 2); let mut members_to_remove = StakeCredentials::new(); - members_to_remove.add(&StakeCredential::from_keyhash(&fake_key_hash(1))); - members_to_remove.add(&StakeCredential::from_scripthash(&fake_script_hash(2))); + members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); + members_to_remove.add(&Credential::from_scripthash(&fake_script_hash(2))); let proposal = NewCommitteeProposal::new_with_action_id(&action_id, &committee, &members_to_remove); @@ -284,8 +284,8 @@ fn parameter_change_proposal_with_action_id_ser_round_trip() { #[test] fn treasury_withdrawals_ser_round_trip() { let mut withdrawals = TreasuryWithdrawals::new(); - let addr1 = RewardAddress::new(1, &StakeCredential::from_keyhash(&fake_key_hash(1))); - let addr2 = RewardAddress::new(2, &StakeCredential::from_keyhash(&fake_key_hash(2))); + let addr1 = RewardAddress::new(1, &Credential::from_keyhash(&fake_key_hash(1))); + let addr2 = RewardAddress::new(2, &Credential::from_keyhash(&fake_key_hash(2))); withdrawals.insert(&addr1, &Coin::from(1u32)); withdrawals.insert(&addr2, &Coin::from(2u32)); @@ -297,8 +297,8 @@ fn treasury_withdrawals_ser_round_trip() { #[test] fn treasury_withdrawals_proposal_ser_round_trip() { let mut withdrawals = TreasuryWithdrawals::new(); - let addr1 = RewardAddress::new(1, &StakeCredential::from_keyhash(&fake_key_hash(1))); - let addr2 = RewardAddress::new(2, &StakeCredential::from_keyhash(&fake_key_hash(2))); + let addr1 = RewardAddress::new(1, &Credential::from_keyhash(&fake_key_hash(1))); + let addr2 = RewardAddress::new(2, &Credential::from_keyhash(&fake_key_hash(2))); withdrawals.insert(&addr1, &Coin::from(1u32)); withdrawals.insert(&addr2, &Coin::from(2u32)); @@ -317,8 +317,8 @@ fn treasury_withdrawals_proposal_ser_round_trip() { fn voting_proposals_ser_round_trip() { let mut proposals = VotingProposals::new(); let mut withdrawals = TreasuryWithdrawals::new(); - let addr1 = RewardAddress::new(1, &StakeCredential::from_keyhash(&fake_key_hash(1))); - let addr2 = RewardAddress::new(2, &StakeCredential::from_keyhash(&fake_key_hash(2))); + let addr1 = RewardAddress::new(1, &Credential::from_keyhash(&fake_key_hash(1))); + let addr2 = RewardAddress::new(2, &Credential::from_keyhash(&fake_key_hash(2))); withdrawals.insert(&addr1, &Coin::from(1u32)); withdrawals.insert(&addr2, &Coin::from(2u32)); diff --git a/rust/src/tx_builder.rs b/rust/src/tx_builder.rs index 4ed05e25..4a1ad06b 100644 --- a/rust/src/tx_builder.rs +++ b/rust/src/tx_builder.rs @@ -2320,8 +2320,8 @@ mod tests { .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -2346,7 +2346,7 @@ mod tests { .unwrap(); tx_builder.set_ttl(1000); - let change_cred = StakeCredential::from_keyhash(&change_key.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &change_cred, @@ -2398,8 +2398,8 @@ mod tests { .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -2427,7 +2427,7 @@ mod tests { let datum_hash = fake_data_hash(20); let data_option = OutputDatum::new_data_hash(&datum_hash); let (_, script_hash) = plutus_script_and_hash(15); - let change_cred = StakeCredential::from_scripthash(&script_hash); + let change_cred = Credential::from_scripthash(&script_hash); let change_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &change_cred, @@ -2479,8 +2479,8 @@ mod tests { .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -2505,7 +2505,7 @@ mod tests { .unwrap(); tx_builder.set_ttl(1000); - let change_cred = StakeCredential::from_keyhash(&change_key.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &change_cred, @@ -2555,7 +2555,7 @@ mod tests { .derive(0) .to_public(); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); tx_builder.add_key_input( &spend.to_raw_key().hash(), &TransactionInput::new(&genesis_id(), 0), @@ -2573,7 +2573,7 @@ mod tests { ))); tx_builder.set_certs(&certs).unwrap(); - let change_cred = StakeCredential::from_keyhash(&change_key.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &change_cred, @@ -2632,8 +2632,8 @@ mod tests { &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(222)), ); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -2653,7 +2653,7 @@ mod tests { .unwrap(); tx_builder.set_ttl(0); - let change_cred = StakeCredential::from_keyhash(&change_key.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &change_cred, @@ -2696,8 +2696,8 @@ mod tests { &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(700)), ); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -2717,7 +2717,7 @@ mod tests { .unwrap(); tx_builder.set_ttl(0); - let change_cred = StakeCredential::from_keyhash(&change_key.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &change_cred, @@ -2762,8 +2762,8 @@ mod tests { &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(5)), ); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -2790,7 +2790,7 @@ mod tests { )); tx_builder.set_certs(&certs); - let change_cred = StakeCredential::from_keyhash(&change_key.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &change_cred, @@ -2819,8 +2819,8 @@ mod tests { .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); { assert_eq!( @@ -2909,8 +2909,8 @@ mod tests { .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 1)); tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 2)); @@ -2949,7 +2949,7 @@ mod tests { ) .unwrap(); - let change_cred = StakeCredential::from_keyhash(&change_key.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &change_cred, @@ -2990,8 +2990,8 @@ mod tests { .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 1)); tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 2)); @@ -3030,7 +3030,7 @@ mod tests { ) .unwrap(); - let change_cred = StakeCredential::from_keyhash(&change_key.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &change_cred, @@ -3071,8 +3071,8 @@ mod tests { .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 1)); tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 2)); @@ -3111,7 +3111,7 @@ mod tests { ) .unwrap(); - let change_cred = StakeCredential::from_keyhash(&change_key.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &change_cred, @@ -3154,8 +3154,8 @@ mod tests { .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); // Input with 150 coins tx_builder.add_input( @@ -3199,7 +3199,7 @@ mod tests { ) .unwrap(); - let change_cred = StakeCredential::from_keyhash(&change_key.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &change_cred, @@ -3242,8 +3242,8 @@ mod tests { .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); // Input with 600 coins tx_builder.add_input( @@ -3289,7 +3289,7 @@ mod tests { ) .unwrap(); - let change_cred = StakeCredential::from_keyhash(&change_key.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &change_cred, @@ -3339,8 +3339,8 @@ mod tests { .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let (min_script, policy_id) = mint_script_and_policy(0); let asset_name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); @@ -3397,7 +3397,7 @@ mod tests { ) .unwrap(); - let change_cred = StakeCredential::from_keyhash(&change_key.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &change_cred, @@ -3434,8 +3434,8 @@ mod tests { .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let (min_script, policy_id) = mint_script_and_policy(0); let asset_name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); @@ -3492,7 +3492,7 @@ mod tests { ) .unwrap(); - let change_cred = StakeCredential::from_keyhash(&change_key.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &change_cred, @@ -3564,8 +3564,8 @@ mod tests { ); } - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet().network_id(), @@ -3589,7 +3589,7 @@ mod tests { ) .unwrap(); - let change_cred = StakeCredential::from_keyhash(&change_key.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &change_cred, @@ -3679,8 +3679,8 @@ mod tests { ); } - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet().network_id(), @@ -3704,7 +3704,7 @@ mod tests { ) .unwrap(); - let change_cred = StakeCredential::from_keyhash(&change_key.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &change_cred, @@ -3806,8 +3806,8 @@ mod tests { ); } - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet().network_id(), @@ -3831,7 +3831,7 @@ mod tests { ) .unwrap(); - let change_cred = StakeCredential::from_keyhash(&change_key.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &change_cred, @@ -3888,8 +3888,8 @@ mod tests { .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -3927,7 +3927,7 @@ mod tests { .unwrap(); tx_builder.set_ttl(1000); - let change_cred = StakeCredential::from_keyhash(&change_key.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &change_cred, @@ -4851,8 +4851,8 @@ mod tests { .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet().network_id(), @@ -4935,9 +4935,9 @@ mod tests { .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); - let change_cred = StakeCredential::from_keyhash(&change_key.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let addr_multisig = BaseAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -5028,8 +5028,8 @@ mod tests { .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -6035,8 +6035,8 @@ mod tests { fn create_base_address_from_script_hash(sh: &ScriptHash) -> Address { BaseAddress::new( NetworkInfo::testnet().network_id(), - &StakeCredential::from_scripthash(sh), - &StakeCredential::from_keyhash(&fake_key_hash(0)), + &Credential::from_scripthash(sh), + &Credential::from_keyhash(&fake_key_hash(0)), ) .to_address() } @@ -8420,7 +8420,7 @@ mod tests { } }").unwrap(); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); tx_builder.add_key_input( &spend.to_raw_key().hash(), &TransactionInput::new(&genesis_id(), 0), @@ -8428,19 +8428,19 @@ mod tests { ); tx_builder.set_ttl(1000); let (cert_script1, cert_script_hash1) = plutus_script_and_hash(1); - let cert_script_cred1 = StakeCredential::from_scripthash(&cert_script_hash1); + let cert_script_cred1 = Credential::from_scripthash(&cert_script_hash1); let (cert_script2, cert_script_hash2) = plutus_script_and_hash(2); - let cert_script_cred2 = StakeCredential::from_scripthash(&cert_script_hash2); + let cert_script_cred2 = Credential::from_scripthash(&cert_script_hash2); let cert_script_hash3 = fake_script_hash(3); - let cert_script_cred3 = StakeCredential::from_scripthash(&cert_script_hash3); + let cert_script_cred3 = Credential::from_scripthash(&cert_script_hash3); let (withdraw_script1, withdraw_script_hash1) = plutus_script_and_hash(3); - let withdraw_script_cred1 = StakeCredential::from_scripthash(&withdraw_script_hash1); + let withdraw_script_cred1 = Credential::from_scripthash(&withdraw_script_hash1); let withdraw_script_hash2 = fake_script_hash(3); - let withdraw_script_cred2 = StakeCredential::from_scripthash(&withdraw_script_hash2); + let withdraw_script_cred2 = Credential::from_scripthash(&withdraw_script_hash2); let cert_witness_1 = PlutusWitness::new_without_datum( &cert_script1, @@ -8510,7 +8510,7 @@ mod tests { tx_builder.set_certs_builder(&certs); let mut withdrawals = WithdrawalsBuilder::new(); - let reward_cred = StakeCredential::from_keyhash(&reward.to_raw_key().hash()); + let reward_cred = Credential::from_keyhash(&reward.to_raw_key().hash()); withdrawals.add( &RewardAddress::new(NetworkInfo::testnet().network_id(), &reward_cred), &Coin::from(1u32), @@ -8527,7 +8527,7 @@ mod tests { ).unwrap(); tx_builder.set_withdrawals_builder(&withdrawals); - let change_cred = StakeCredential::from_keyhash(&change_key.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &change_cred, @@ -8538,8 +8538,8 @@ mod tests { let collateral_input = fake_tx_input(1); let collateral_addr = BaseAddress::new( NetworkInfo::testnet().network_id(), - &StakeCredential::from_keyhash(&fake_key_hash(1)), - &StakeCredential::from_keyhash(&fake_key_hash(2)), + &Credential::from_keyhash(&fake_key_hash(1)), + &Credential::from_keyhash(&fake_key_hash(2)), ).to_address(); let mut collateral_builder = TxInputsBuilder::new(); collateral_builder.add_input(&collateral_addr, &collateral_input, &Value::new(&Coin::from(123u32))); diff --git a/rust/src/tx_builder/test_batch.rs b/rust/src/tx_builder/test_batch.rs index 7e762d64..4539a4a3 100644 --- a/rust/src/tx_builder/test_batch.rs +++ b/rust/src/tx_builder/test_batch.rs @@ -34,8 +34,8 @@ mod test { .derive(2) .derive(0) .to_public(); - let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = StakeCredential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr = BaseAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, From 37ee5d997c8e950257d0d98b7be985ee81c56158 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 30 Aug 2023 13:59:41 +0500 Subject: [PATCH 104/349] move certs struct to separate file --- rust/src/lib.rs | 27 -------------- .../certificates/certificates_collection.rs | 28 +++++++++++++++ rust/src/protocol_types/certificates/mod.rs | 3 ++ .../certificates/certificates_collection.rs | 36 +++++++++++++++++++ rust/src/serialization/certificates/mod.rs | 5 +-- rust/src/serialization/general.rs | 35 ------------------ 6 files changed, 68 insertions(+), 66 deletions(-) create mode 100644 rust/src/protocol_types/certificates/certificates_collection.rs create mode 100644 rust/src/serialization/certificates/certificates_collection.rs diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 8d6d8c1e..b2d88332 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -278,33 +278,6 @@ impl DataCost { } } -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct Certificates(Vec); - -impl_to_from!(Certificates); - -#[wasm_bindgen] -impl Certificates { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> Certificate { - self.0[index].clone() - } - - pub fn add(&mut self, elem: &Certificate) { - self.0.push(elem.clone()); - } -} - pub type RequiredSigners = Ed25519KeyHashes; pub type RequiredSignersSet = BTreeSet; diff --git a/rust/src/protocol_types/certificates/certificates_collection.rs b/rust/src/protocol_types/certificates/certificates_collection.rs new file mode 100644 index 00000000..1e2611dd --- /dev/null +++ b/rust/src/protocol_types/certificates/certificates_collection.rs @@ -0,0 +1,28 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct Certificates(pub(crate) Vec); + +impl_to_from!(Certificates); + +#[wasm_bindgen] +impl Certificates { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> Certificate { + self.0[index].clone() + } + + pub fn add(&mut self, elem: &Certificate) { + self.0.push(elem.clone()); + } +} diff --git a/rust/src/protocol_types/certificates/mod.rs b/rust/src/protocol_types/certificates/mod.rs index ef3fdd67..0714273b 100644 --- a/rust/src/protocol_types/certificates/mod.rs +++ b/rust/src/protocol_types/certificates/mod.rs @@ -1,6 +1,9 @@ mod certificate; pub use certificate::*; +mod certificates_collection; +pub use certificates_collection::*; + mod genesis_key_delegation; pub use genesis_key_delegation::*; diff --git a/rust/src/serialization/certificates/certificates_collection.rs b/rust/src/serialization/certificates/certificates_collection.rs new file mode 100644 index 00000000..c10cd3f1 --- /dev/null +++ b/rust/src/serialization/certificates/certificates_collection.rs @@ -0,0 +1,36 @@ +use crate::*; + +impl Serialize for Certificates { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for Certificates { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(Certificate::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("Certificates"))?; + Ok(Self(arr)) + } +} \ No newline at end of file diff --git a/rust/src/serialization/certificates/mod.rs b/rust/src/serialization/certificates/mod.rs index c5814548..3f0e7b4b 100644 --- a/rust/src/serialization/certificates/mod.rs +++ b/rust/src/serialization/certificates/mod.rs @@ -1,10 +1,7 @@ mod certificate; -pub use certificate::*; - +mod certificates_collection; mod genesis_key_delegation; - mod move_instantaneous_rewards_cert; - mod committee_hot_key_deregistration; mod committee_hot_key_registration; mod drep_deregistration; diff --git a/rust/src/serialization/general.rs b/rust/src/serialization/general.rs index 8424d4b7..32b626c0 100644 --- a/rust/src/serialization/general.rs +++ b/rust/src/serialization/general.rs @@ -244,41 +244,6 @@ impl Deserialize for TransactionOutputs { } } -impl cbor_event::se::Serialize for Certificates { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for Certificates { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(Certificate::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("Certificates"))?; - Ok(Self(arr)) - } -} - impl cbor_event::se::Serialize for TransactionBody { fn serialize<'se, W: Write>( &self, From afc7fd99948cdf2226295bc22c505d948c18d879 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 30 Aug 2023 14:04:13 +0500 Subject: [PATCH 105/349] json gen fix --- rust/json-gen/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/json-gen/src/main.rs b/rust/json-gen/src/main.rs index 400c617e..98ddfe99 100644 --- a/rust/json-gen/src/main.rs +++ b/rust/json-gen/src/main.rs @@ -122,7 +122,7 @@ fn main() { gen_json_schema!(Nonce); gen_json_schema!(VRFCert); // address.rs - gen_json_schema!(StakeCredential); + gen_json_schema!(Credential); gen_json_schema!(StakeCredType); gen_json_schema!(Address); gen_json_schema!(RewardAddress); From 67fefa8f4734b8c80336b46786bdc9f840177a06 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 30 Aug 2023 14:08:46 +0500 Subject: [PATCH 106/349] flow update --- rust/pkg/cardano_serialization_lib.js.flow | 652 +++++++++++---------- 1 file changed, 356 insertions(+), 296 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 9c6449c8..6f0c3bfa 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -5,6 +5,30 @@ * @flow */ +/** + * @param {string} password + * @param {string} salt + * @param {string} nonce + * @param {string} data + * @returns {string} + */ +declare export function encrypt_with_password( + password: string, + salt: string, + nonce: string, + data: string +): string; + +/** + * @param {string} password + * @param {string} data + * @returns {string} + */ +declare export function decrypt_with_password( + password: string, + data: string +): string; + /** * @param {Transaction} tx * @param {LinearFee} linear_fee @@ -182,30 +206,6 @@ declare export function encode_json_str_to_native_script( schema: number ): NativeScript; -/** - * @param {string} password - * @param {string} salt - * @param {string} nonce - * @param {string} data - * @returns {string} - */ -declare export function encrypt_with_password( - password: string, - salt: string, - nonce: string, - data: string -): string; - -/** - * @param {string} password - * @param {string} data - * @returns {string} - */ -declare export function decrypt_with_password( - password: string, - data: string -): string; - /** * @param {Uint8Array} bytes * @returns {TransactionMetadatum} @@ -304,32 +304,6 @@ declare export var NetworkIdKind: {| +Mainnet: 1, // 1 |}; -/** - */ - -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 -|}; - -/** - */ - -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 -|}; - -/** - */ - -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 -|}; - /** */ @@ -344,17 +318,19 @@ declare export var VoterKind: {| /** */ -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 +declare export var StakeCredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** */ -declare export var StakeCredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 |}; /** @@ -366,16 +342,6 @@ declare export var ScriptSchema: {| +Node: 1, // 1 |}; -/** - */ - -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 -|}; - /** */ @@ -489,6 +455,40 @@ declare export var PlutusDatumSchema: {| +DetailedSchema: 1, // 1 |}; +/** + */ + +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 +|}; + +/** + */ + +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 +|}; + +/** + */ + +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 +|}; + +/** + */ + +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 +|}; + /** */ declare export class Address { @@ -554,6 +554,44 @@ declare export class Address { declare export class Anchor { free(): void; + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {Anchor} + */ + static from_bytes(bytes: Uint8Array): Anchor; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {Anchor} + */ + static from_hex(hex_str: string): Anchor; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {AnchorJSON} + */ + to_js_value(): AnchorJSON; + + /** + * @param {string} json + * @returns {Anchor} + */ + static from_json(json: string): Anchor; + /** * @returns {URL} */ @@ -966,25 +1004,25 @@ declare export class BaseAddress { /** * @param {number} network - * @param {StakeCredential} payment - * @param {StakeCredential} stake + * @param {Credential} payment + * @param {Credential} stake * @returns {BaseAddress} */ static new( network: number, - payment: StakeCredential, - stake: StakeCredential + payment: Credential, + stake: Credential ): BaseAddress; /** - * @returns {StakeCredential} + * @returns {Credential} */ - payment_cred(): StakeCredential; + payment_cred(): Credential; /** - * @returns {StakeCredential} + * @returns {Credential} */ - stake_cred(): StakeCredential; + stake_cred(): Credential; /** * @returns {Address} @@ -2163,16 +2201,16 @@ declare export class Committee { quorum_threshold(): UnitInterval; /** - * @param {StakeCredential} committee_cold_credential + * @param {Credential} committee_cold_credential * @param {number} epoch */ - add_member(committee_cold_credential: StakeCredential, epoch: number): void; + add_member(committee_cold_credential: Credential, epoch: number): void; /** - * @param {StakeCredential} committee_cold_credential + * @param {Credential} committee_cold_credential * @returns {number | void} */ - get_member_epoch(committee_cold_credential: StakeCredential): number | void; + get_member_epoch(committee_cold_credential: Credential): number | void; } /** */ @@ -2218,17 +2256,15 @@ declare export class CommitteeHotKeyDeregistration { static from_json(json: string): CommitteeHotKeyDeregistration; /** - * @returns {StakeCredential} + * @returns {Credential} */ - committee_cold_key(): StakeCredential; + committee_cold_key(): Credential; /** - * @param {StakeCredential} committee_cold_key + * @param {Credential} committee_cold_key * @returns {CommitteeHotKeyDeregistration} */ - static new( - committee_cold_key: StakeCredential - ): CommitteeHotKeyDeregistration; + static new(committee_cold_key: Credential): CommitteeHotKeyDeregistration; /** * @returns {boolean} @@ -2279,23 +2315,23 @@ declare export class CommitteeHotKeyRegistration { static from_json(json: string): CommitteeHotKeyRegistration; /** - * @returns {StakeCredential} + * @returns {Credential} */ - committee_cold_key(): StakeCredential; + committee_cold_key(): Credential; /** - * @returns {StakeCredential} + * @returns {Credential} */ - committee_hot_key(): StakeCredential; + committee_hot_key(): Credential; /** - * @param {StakeCredential} committee_cold_key - * @param {StakeCredential} committee_hot_key + * @param {Credential} committee_cold_key + * @param {Credential} committee_hot_key * @returns {CommitteeHotKeyRegistration} */ static new( - committee_cold_key: StakeCredential, - committee_hot_key: StakeCredential + committee_cold_key: Credential, + committee_hot_key: Credential ): CommitteeHotKeyRegistration; /** @@ -2563,6 +2599,81 @@ declare export class Costmdls { */ retain_language_versions(languages: Languages): Costmdls; } +/** + */ +declare export class Credential { + free(): void; + + /** + * @param {Ed25519KeyHash} hash + * @returns {Credential} + */ + static from_keyhash(hash: Ed25519KeyHash): Credential; + + /** + * @param {ScriptHash} hash + * @returns {Credential} + */ + static from_scripthash(hash: ScriptHash): Credential; + + /** + * @returns {Ed25519KeyHash | void} + */ + to_keyhash(): Ed25519KeyHash | void; + + /** + * @returns {ScriptHash | void} + */ + to_scripthash(): ScriptHash | void; + + /** + * @returns {number} + */ + kind(): number; + + /** + * @returns {boolean} + */ + has_script_hash(): boolean; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {Credential} + */ + static from_bytes(bytes: Uint8Array): Credential; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {Credential} + */ + static from_hex(hex_str: string): Credential; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {CredentialJSON} + */ + to_js_value(): CredentialJSON; + + /** + * @param {string} json + * @returns {Credential} + */ + static from_json(json: string): Credential; +} /** */ declare export class DNSRecordAorAAAA { @@ -2875,9 +2986,9 @@ declare export class DrepDeregistration { static from_json(json: string): DrepDeregistration; /** - * @returns {StakeCredential} + * @returns {Credential} */ - voting_credential(): StakeCredential; + voting_credential(): Credential; /** * @returns {BigNum} @@ -2885,14 +2996,11 @@ declare export class DrepDeregistration { coin(): BigNum; /** - * @param {StakeCredential} voting_credential + * @param {Credential} voting_credential * @param {BigNum} coin * @returns {DrepDeregistration} */ - static new( - voting_credential: StakeCredential, - coin: BigNum - ): DrepDeregistration; + static new(voting_credential: Credential, coin: BigNum): DrepDeregistration; /** * @returns {boolean} @@ -2943,9 +3051,9 @@ declare export class DrepRegistration { static from_json(json: string): DrepRegistration; /** - * @returns {StakeCredential} + * @returns {Credential} */ - voting_credential(): StakeCredential; + voting_credential(): Credential; /** * @returns {BigNum} @@ -2958,15 +3066,22 @@ declare export class DrepRegistration { anchor(): Anchor | void; /** - * @param {StakeCredential} voting_credential + * @param {Credential} voting_credential * @param {BigNum} coin - * @param {Anchor | void} anchor * @returns {DrepRegistration} */ - static new( - voting_credential: StakeCredential, + static new(voting_credential: Credential, coin: BigNum): DrepRegistration; + + /** + * @param {Credential} voting_credential + * @param {BigNum} coin + * @param {Anchor} anchor + * @returns {DrepRegistration} + */ + static new_with_anchor( + voting_credential: Credential, coin: BigNum, - anchor?: Anchor + anchor: Anchor ): DrepRegistration; } /** @@ -3013,9 +3128,9 @@ declare export class DrepUpdate { static from_json(json: string): DrepUpdate; /** - * @returns {StakeCredential} + * @returns {Credential} */ - voting_credential(): StakeCredential; + voting_credential(): Credential; /** * @returns {Anchor | void} @@ -3023,11 +3138,20 @@ declare export class DrepUpdate { anchor(): Anchor | void; /** - * @param {StakeCredential} voting_credential - * @param {Anchor | void} anchor + * @param {Credential} voting_credential * @returns {DrepUpdate} */ - static new(voting_credential: StakeCredential, anchor?: Anchor): DrepUpdate; + static new(voting_credential: Credential): DrepUpdate; + + /** + * @param {Credential} voting_credential + * @param {Anchor} anchor + * @returns {DrepUpdate} + */ + static new_with_anchor( + voting_credential: Credential, + anchor: Anchor + ): DrepUpdate; /** * @returns {boolean} @@ -3187,15 +3311,15 @@ declare export class EnterpriseAddress { /** * @param {number} network - * @param {StakeCredential} payment + * @param {Credential} payment * @returns {EnterpriseAddress} */ - static new(network: number, payment: StakeCredential): EnterpriseAddress; + static new(network: number, payment: Credential): EnterpriseAddress; /** - * @returns {StakeCredential} + * @returns {Credential} */ - payment_cred(): StakeCredential; + payment_cred(): Credential; /** * @returns {Address} @@ -4670,17 +4794,17 @@ declare export class MIRToStakeCredentials { len(): number; /** - * @param {StakeCredential} cred + * @param {Credential} cred * @param {Int} delta * @returns {Int | void} */ - insert(cred: StakeCredential, delta: Int): Int | void; + insert(cred: Credential, delta: Int): Int | void; /** - * @param {StakeCredential} cred + * @param {Credential} cred * @returns {Int | void} */ - get(cred: StakeCredential): Int | void; + get(cred: Credential): Int | void; /** * @returns {StakeCredentials} @@ -6662,20 +6786,20 @@ declare export class PointerAddress { /** * @param {number} network - * @param {StakeCredential} payment + * @param {Credential} payment * @param {Pointer} stake * @returns {PointerAddress} */ static new( network: number, - payment: StakeCredential, + payment: Credential, stake: Pointer ): PointerAddress; /** - * @returns {StakeCredential} + * @returns {Credential} */ - payment_cred(): StakeCredential; + payment_cred(): Credential; /** * @returns {Pointer} @@ -7964,15 +8088,15 @@ declare export class RewardAddress { /** * @param {number} network - * @param {StakeCredential} payment + * @param {Credential} payment * @returns {RewardAddress} */ - static new(network: number, payment: StakeCredential): RewardAddress; + static new(network: number, payment: Credential): RewardAddress; /** - * @returns {StakeCredential} + * @returns {Credential} */ - payment_cred(): StakeCredential; + payment_cred(): Credential; /** * @returns {Address} @@ -8658,9 +8782,9 @@ declare export class StakeAndVoteDelegation { static from_json(json: string): StakeAndVoteDelegation; /** - * @returns {StakeCredential} + * @returns {Credential} */ - stake_credential(): StakeCredential; + stake_credential(): Credential; /** * @returns {Ed25519KeyHash} @@ -8673,13 +8797,13 @@ declare export class StakeAndVoteDelegation { drep(): DRep; /** - * @param {StakeCredential} stake_credential + * @param {Credential} stake_credential * @param {Ed25519KeyHash} pool_keyhash * @param {DRep} drep * @returns {StakeAndVoteDelegation} */ static new( - stake_credential: StakeCredential, + stake_credential: Credential, pool_keyhash: Ed25519KeyHash, drep: DRep ): StakeAndVoteDelegation; @@ -8689,81 +8813,6 @@ declare export class StakeAndVoteDelegation { */ has_script_credentials(): boolean; } -/** - */ -declare export class StakeCredential { - free(): void; - - /** - * @param {Ed25519KeyHash} hash - * @returns {StakeCredential} - */ - static from_keyhash(hash: Ed25519KeyHash): StakeCredential; - - /** - * @param {ScriptHash} hash - * @returns {StakeCredential} - */ - static from_scripthash(hash: ScriptHash): StakeCredential; - - /** - * @returns {Ed25519KeyHash | void} - */ - to_keyhash(): Ed25519KeyHash | void; - - /** - * @returns {ScriptHash | void} - */ - to_scripthash(): ScriptHash | void; - - /** - * @returns {number} - */ - kind(): number; - - /** - * @returns {boolean} - */ - has_script_hash(): boolean; - - /** - * @returns {Uint8Array} - */ - to_bytes(): Uint8Array; - - /** - * @param {Uint8Array} bytes - * @returns {StakeCredential} - */ - static from_bytes(bytes: Uint8Array): StakeCredential; - - /** - * @returns {string} - */ - to_hex(): string; - - /** - * @param {string} hex_str - * @returns {StakeCredential} - */ - static from_hex(hex_str: string): StakeCredential; - - /** - * @returns {string} - */ - to_json(): string; - - /** - * @returns {StakeCredentialJSON} - */ - to_js_value(): StakeCredentialJSON; - - /** - * @param {string} json - * @returns {StakeCredential} - */ - static from_json(json: string): StakeCredential; -} /** */ declare export class StakeCredentials { @@ -8819,14 +8868,14 @@ declare export class StakeCredentials { /** * @param {number} index - * @returns {StakeCredential} + * @returns {Credential} */ - get(index: number): StakeCredential; + get(index: number): Credential; /** - * @param {StakeCredential} elem + * @param {Credential} elem */ - add(elem: StakeCredential): void; + add(elem: Credential): void; } /** */ @@ -8872,9 +8921,9 @@ declare export class StakeDelegation { static from_json(json: string): StakeDelegation; /** - * @returns {StakeCredential} + * @returns {Credential} */ - stake_credential(): StakeCredential; + stake_credential(): Credential; /** * @returns {Ed25519KeyHash} @@ -8882,12 +8931,12 @@ declare export class StakeDelegation { pool_keyhash(): Ed25519KeyHash; /** - * @param {StakeCredential} stake_credential + * @param {Credential} stake_credential * @param {Ed25519KeyHash} pool_keyhash * @returns {StakeDelegation} */ static new( - stake_credential: StakeCredential, + stake_credential: Credential, pool_keyhash: Ed25519KeyHash ): StakeDelegation; @@ -8940,9 +8989,9 @@ declare export class StakeDeregistration { static from_json(json: string): StakeDeregistration; /** - * @returns {StakeCredential} + * @returns {Credential} */ - stake_credential(): StakeCredential; + stake_credential(): Credential; /** * @returns {BigNum | void} @@ -8950,18 +8999,18 @@ declare export class StakeDeregistration { coin(): BigNum | void; /** - * @param {StakeCredential} stake_credential + * @param {Credential} stake_credential * @returns {StakeDeregistration} */ - static new(stake_credential: StakeCredential): StakeDeregistration; + static new(stake_credential: Credential): StakeDeregistration; /** - * @param {StakeCredential} stake_credential + * @param {Credential} stake_credential * @param {BigNum} coin * @returns {StakeDeregistration} */ static new_with_coin( - stake_credential: StakeCredential, + stake_credential: Credential, coin: BigNum ): StakeDeregistration; @@ -9014,9 +9063,9 @@ declare export class StakeRegistration { static from_json(json: string): StakeRegistration; /** - * @returns {StakeCredential} + * @returns {Credential} */ - stake_credential(): StakeCredential; + stake_credential(): Credential; /** * @returns {BigNum | void} @@ -9024,18 +9073,18 @@ declare export class StakeRegistration { coin(): BigNum | void; /** - * @param {StakeCredential} stake_credential + * @param {Credential} stake_credential * @returns {StakeRegistration} */ - static new(stake_credential: StakeCredential): StakeRegistration; + static new(stake_credential: Credential): StakeRegistration; /** - * @param {StakeCredential} stake_credential + * @param {Credential} stake_credential * @param {BigNum} coin * @returns {StakeRegistration} */ static new_with_coin( - stake_credential: StakeCredential, + stake_credential: Credential, coin: BigNum ): StakeRegistration; } @@ -9083,9 +9132,9 @@ declare export class StakeRegistrationAndDelegation { static from_json(json: string): StakeRegistrationAndDelegation; /** - * @returns {StakeCredential} + * @returns {Credential} */ - stake_credential(): StakeCredential; + stake_credential(): Credential; /** * @returns {Ed25519KeyHash} @@ -9098,13 +9147,13 @@ declare export class StakeRegistrationAndDelegation { coin(): BigNum; /** - * @param {StakeCredential} stake_credential + * @param {Credential} stake_credential * @param {Ed25519KeyHash} pool_keyhash * @param {BigNum} coin * @returns {StakeRegistrationAndDelegation} */ static new( - stake_credential: StakeCredential, + stake_credential: Credential, pool_keyhash: Ed25519KeyHash, coin: BigNum ): StakeRegistrationAndDelegation; @@ -9158,9 +9207,9 @@ declare export class StakeVoteRegistrationAndDelegation { static from_json(json: string): StakeVoteRegistrationAndDelegation; /** - * @returns {StakeCredential} + * @returns {Credential} */ - stake_credential(): StakeCredential; + stake_credential(): Credential; /** * @returns {Ed25519KeyHash} @@ -9178,14 +9227,14 @@ declare export class StakeVoteRegistrationAndDelegation { coin(): BigNum; /** - * @param {StakeCredential} stake_credential + * @param {Credential} stake_credential * @param {Ed25519KeyHash} pool_keyhash * @param {DRep} drep * @param {BigNum} coin * @returns {StakeVoteRegistrationAndDelegation} */ static new( - stake_credential: StakeCredential, + stake_credential: Credential, pool_keyhash: Ed25519KeyHash, drep: DRep, coin: BigNum @@ -10237,6 +10286,16 @@ declare export class TransactionBuilder { output_builder: TransactionOutputAmountBuilder ): void; + /** + * @param {PlutusData} datum + */ + add_extra_witness_datum(datum: PlutusData): void; + + /** + * @returns {PlutusList | void} + */ + get_extra_witness_datums(): PlutusList | void; + /** * @param {TransactionBuilderConfig} cfg * @returns {TransactionBuilder} @@ -12304,9 +12363,9 @@ declare export class VoteDelegation { static from_json(json: string): VoteDelegation; /** - * @returns {StakeCredential} + * @returns {Credential} */ - stake_credential(): StakeCredential; + stake_credential(): Credential; /** * @returns {DRep} @@ -12314,11 +12373,11 @@ declare export class VoteDelegation { drep(): DRep; /** - * @param {StakeCredential} stake_credential + * @param {Credential} stake_credential * @param {DRep} drep * @returns {VoteDelegation} */ - static new(stake_credential: StakeCredential, drep: DRep): VoteDelegation; + static new(stake_credential: Credential, drep: DRep): VoteDelegation; /** * @returns {boolean} @@ -12369,9 +12428,9 @@ declare export class VoteRegistrationAndDelegation { static from_json(json: string): VoteRegistrationAndDelegation; /** - * @returns {StakeCredential} + * @returns {Credential} */ - stake_credential(): StakeCredential; + stake_credential(): Credential; /** * @returns {DRep} @@ -12384,13 +12443,13 @@ declare export class VoteRegistrationAndDelegation { coin(): BigNum; /** - * @param {StakeCredential} stake_credential + * @param {Credential} stake_credential * @param {DRep} drep * @param {BigNum} coin * @returns {VoteRegistrationAndDelegation} */ static new( - stake_credential: StakeCredential, + stake_credential: Credential, drep: DRep, coin: BigNum ): VoteRegistrationAndDelegation; @@ -12444,16 +12503,16 @@ declare export class Voter { static from_json(json: string): Voter; /** - * @param {StakeCredential} cred + * @param {Credential} cred * @returns {Voter} */ - static new_constitutional_committee_hot_key(cred: StakeCredential): Voter; + static new_constitutional_committee_hot_key(cred: Credential): Voter; /** - * @param {StakeCredential} cred + * @param {Credential} cred * @returns {Voter} */ - static new_drep(cred: StakeCredential): Voter; + static new_drep(cred: Credential): Voter; /** * @param {Ed25519KeyHash} key_hash @@ -12467,14 +12526,14 @@ declare export class Voter { kind(): number; /** - * @returns {StakeCredential | void} + * @returns {Credential | void} */ - to_constitutional_committee_hot_key(): StakeCredential | void; + to_constitutional_committee_hot_key(): Credential | void; /** - * @returns {StakeCredential | void} + * @returns {Credential | void} */ - to_drep(): StakeCredential | void; + to_drep(): Credential | void; /** * @returns {Ed25519KeyHash | void} @@ -12659,7 +12718,7 @@ declare export class VotingProcedure { /** * @returns {number} */ - vote(): number; + vote_kind(): number; /** * @returns {Anchor | void} @@ -12714,6 +12773,17 @@ declare export class VotingProcedures { */ static new(): VotingProcedures; + /** + * @param {Voter} voter + * @param {GovernanceActionId} governance_action_id + * @param {VotingProcedure} voting_procedure + */ + insert( + voter: Voter, + governance_action_id: GovernanceActionId, + voting_procedure: VotingProcedure + ): void; + /** * @param {Voter} voter * @param {GovernanceActionId} governance_action_id @@ -13233,17 +13303,15 @@ export type CertificateEnumJSON = }; export type CertificatesJSON = CertificateJSON[]; export interface CommitteeJSON { - members: { - [k: string]: number, - }; + members: CommitteeMember[]; quorum_threshold: UnitIntervalJSON; } export interface CommitteeHotKeyDeregistrationJSON { - committee_cold_key: StakeCredTypeJSON; + committee_cold_key: CredentialJSON; } export interface CommitteeHotKeyRegistrationJSON { - committee_cold_key: StakeCredTypeJSON; - committee_hot_key: StakeCredTypeJSON; + committee_cold_key: CredentialJSON; + committee_hot_key: CredentialJSON; } export interface ConstitutionJSON { anchor: AnchorJSON; @@ -13253,6 +13321,16 @@ export type CostModelJSON = string[]; export interface CostmdlsJSON { [k: string]: CostModelJSON; } +export type CredentialJSON = StakeCredTypeJSON; +export type StakeCredTypeJSON = + | { + Key: string, + ... + } + | { + Script: string, + ... + }; export type DNSRecordAorAAAAJSON = string; export type DNSRecordSRVJSON = string; export type DRepJSON = DRepEnumJSON; @@ -13278,16 +13356,16 @@ export type DataOptionJSON = }; export interface DrepDeregistrationJSON { coin: string; - voting_credential: StakeCredTypeJSON; + voting_credential: CredentialJSON; } export interface DrepRegistrationJSON { anchor?: AnchorJSON | null; coin: string; - voting_credential: StakeCredTypeJSON; + voting_credential: CredentialJSON; } export interface DrepUpdateJSON { anchor?: AnchorJSON | null; - voting_credential: StakeCredTypeJSON; + voting_credential: CredentialJSON; } export type Ed25519KeyHashJSON = string; export type Ed25519KeyHashesJSON = string[]; @@ -13374,15 +13452,11 @@ export type MIREnumJSON = ... } | { - ToStakeCredentials: { - [k: string]: ProtocolParamUpdateJSON, - }, + ToStakeCredentials: StakeToCoinJson[], ... }; export type MIRPotJSON = "Reserves" | "Treasury"; -export interface MIRToStakeCredentialsJSON { - [k: string]: ProtocolParamUpdateJSON; -} +export type MIRToStakeCredentialsJSON = StakeToCoinJson[]; export type MintJSON = [string, MintAssetsJSON][]; export interface MintAssetsJSON { [k: string]: string; @@ -13432,7 +13506,7 @@ export type NetworkIdKindJSON = "Testnet" | "Mainnet"; export interface NewCommitteeProposalJSON { committee: CommitteeJSON; gov_action_id?: GovernanceActionIdJSON | null; - members_to_remove: StakeCredTypeJSON[]; + members_to_remove: CredentialJSON[]; } export interface NewConstitutionProposalJSON { constitution: ConstitutionJSON; @@ -13618,41 +13692,31 @@ export interface SingleHostNameJSON { export interface StakeAndVoteDelegationJSON { drep: DRepJSON; pool_keyhash: string; - stake_credential: StakeCredTypeJSON; + stake_credential: CredentialJSON; } -export type StakeCredTypeJSON = - | { - Key: string, - ... - } - | { - Script: string, - ... - }; -export type StakeCredentialJSON = StakeCredTypeJSON; -export type StakeCredentialsJSON = StakeCredTypeJSON[]; +export type StakeCredentialsJSON = CredentialJSON[]; export interface StakeDelegationJSON { pool_keyhash: string; - stake_credential: StakeCredTypeJSON; + stake_credential: CredentialJSON; } export interface StakeDeregistrationJSON { coin?: string | null; - stake_credential: StakeCredTypeJSON; + stake_credential: CredentialJSON; } export interface StakeRegistrationJSON { coin?: string | null; - stake_credential: StakeCredTypeJSON; + stake_credential: CredentialJSON; } export interface StakeRegistrationAndDelegationJSON { coin: string; pool_keyhash: string; - stake_credential: StakeCredTypeJSON; + stake_credential: CredentialJSON; } export interface StakeVoteRegistrationAndDelegationJSON { coin: string; drep: DRepJSON; pool_keyhash: string; - stake_credential: StakeCredTypeJSON; + stake_credential: CredentialJSON; } export interface TimelockExpiryJSON { slot: string; @@ -13684,10 +13748,10 @@ export interface TransactionBodyJSON { ttl?: string | null; update?: UpdateJSON | null; validity_start_interval?: string | null; - voting_procedures?: VotingProceduresJSON | null; + voting_procedures?: VoterVotes[] | null; voting_proposals?: VotingProposalsJSON | null; withdrawals?: { - [k: string]: ProtocolParamUpdateJSON, + [k: string]: string, } | null; } export type TransactionHashJSON = string; @@ -13753,21 +13817,21 @@ export interface VkeywitnessJSON { export type VkeywitnessesJSON = VkeywitnessJSON[]; export interface VoteDelegationJSON { drep: DRepJSON; - stake_credential: StakeCredTypeJSON; + stake_credential: CredentialJSON; } export interface VoteRegistrationAndDelegationJSON { coin: string; drep: DRepJSON; - stake_credential: StakeCredTypeJSON; + stake_credential: CredentialJSON; } export type VoterJSON = VoterEnumJSON; export type VoterEnumJSON = | { - ConstitutionalCommitteeHotKey: StakeCredTypeJSON, + ConstitutionalCommitteeHotKey: CredentialJSON, ... } | { - DRepJSON: StakeCredTypeJSON, + DRepJSON: CredentialJSON, ... } | { @@ -13778,11 +13842,7 @@ export interface VotingProcedureJSON { anchor?: AnchorJSON | null; vote: $Values; } -export interface VotingProceduresJSON { - [k: string]: { - [k: string]: VotingProcedureJSON, - }; -} +export type VotingProceduresJSON = VoterVotes[]; export type VotingProposalJSON = VotingProposalEnumJSON; export type VotingProposalEnumJSON = | { @@ -13815,5 +13875,5 @@ export type VotingProposalEnumJSON = }; export type VotingProposalsJSON = VotingProposalJSON[]; export interface WithdrawalsJSON { - [k: string]: ProtocolParamUpdateJSON; + [k: string]: string; } From 37c409bc0baf63e96b47fa25b1e7ffc3c738d430 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 30 Aug 2023 14:13:00 +0500 Subject: [PATCH 107/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 78e7eb29..2c32b5f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.3", + "version": "12.0.0-alpha.4", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 76874168..ccef0255 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.3", + "version": "12.0.0-alpha.4", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index e3d37785..7f8dd589 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.3" +version = "12.0.0-alpha.4" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 4d309b4d..49fcc260 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -37,7 +37,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.3" +version = "12.0.0-alpha.4" dependencies = [ "bech32", "cbor_event", From 822554cc63970bb1e423550c15282ead16673073 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 1 Sep 2023 13:51:01 +0500 Subject: [PATCH 108/349] add cert tests --- rust/src/tests/protocol_types/certificates.rs | 284 ++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 rust/src/tests/protocol_types/certificates.rs diff --git a/rust/src/tests/protocol_types/certificates.rs b/rust/src/tests/protocol_types/certificates.rs new file mode 100644 index 00000000..d249ad2d --- /dev/null +++ b/rust/src/tests/protocol_types/certificates.rs @@ -0,0 +1,284 @@ +use crate::fakes::{ + fake_genesis_delegate_hash, fake_genesis_hash, fake_key_hash, fake_script_hash, + fake_vrf_key_hash, +}; +use crate::tests::mock_objects::{crate_full_pool_params, create_anchor}; +use crate::*; + +#[test] +fn committee_hot_key_deregistration_setters_getters_test() { + let cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); + let cred_script_hash = Credential::from_scripthash(&fake_script_hash(2)); + let committee_hot_key_deregistration_1 = CommitteeHotKeyDeregistration::new(&cred_key_hash); + + let committee_hot_key_deregistration_2 = CommitteeHotKeyDeregistration::new(&cred_script_hash); + + assert_eq!( + committee_hot_key_deregistration_1.committee_cold_key(), + cred_key_hash + ); + assert!(!committee_hot_key_deregistration_1.has_script_credentials()); + assert_eq!( + committee_hot_key_deregistration_2.committee_cold_key(), + cred_script_hash + ); + assert!(committee_hot_key_deregistration_2.has_script_credentials()); +} + +#[test] +fn committee_hot_key_registration_setters_getters_test() { + let cold_cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); + let hot_cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); + let committee_hot_key_registration = + CommitteeHotKeyRegistration::new(&cold_cred_key_hash, &hot_cred_key_hash); + + assert_eq!( + committee_hot_key_registration.committee_cold_key(), + cold_cred_key_hash + ); + assert_eq!( + committee_hot_key_registration.committee_hot_key(), + hot_cred_key_hash + ); + assert!(!committee_hot_key_registration.has_script_credentials()); +} + +#[test] +fn drep_deregistration_setters_getters_test() { + let cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); + let cred_script_hash = Credential::from_scripthash(&fake_script_hash(2)); + let coin = Coin::from(100u32); + let drep_deregistration_1 = DrepDeregistration::new(&cred_key_hash, &coin); + + let drep_deregistration_2 = DrepDeregistration::new(&cred_script_hash, &coin); + + assert_eq!(drep_deregistration_1.voting_credential(), cred_key_hash); + assert_eq!(drep_deregistration_1.coin(), coin); + assert!(!drep_deregistration_1.has_script_credentials()); + assert_eq!(drep_deregistration_2.voting_credential(), cred_script_hash); + assert_eq!(drep_deregistration_2.coin(), coin); + assert!(drep_deregistration_2.has_script_credentials()); +} + +#[test] +fn drep_registration_setters_getters_test() { + let cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); + let cred_script_hash = Credential::from_scripthash(&fake_script_hash(2)); + let coin = Coin::from(100u32); + let drep_registration_1 = DrepRegistration::new(&cred_key_hash, &coin); + + let anchor = create_anchor(); + let drep_registration_2 = DrepRegistration::new_with_anchor(&cred_script_hash, &coin, &anchor); + + assert_eq!(drep_registration_1.voting_credential(), cred_key_hash); + assert_eq!(drep_registration_1.coin(), coin); + assert_eq!(drep_registration_2.voting_credential(), cred_script_hash); + assert_eq!(drep_registration_2.coin(), coin); +} + +#[test] +fn drep_update_setters_getters_test() { + let cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); + let cred_script_hash = Credential::from_scripthash(&fake_script_hash(2)); + let drep_update_1 = DrepUpdate::new(&cred_key_hash); + + let anchor = create_anchor(); + let drep_update_2 = DrepUpdate::new_with_anchor(&cred_script_hash, &anchor); + + assert_eq!(drep_update_1.voting_credential(), cred_key_hash); + assert_eq!(drep_update_1.anchor(), None); + assert_eq!(drep_update_2.voting_credential(), cred_script_hash); + assert_eq!(drep_update_2.anchor(), Some(anchor)); +} + +#[test] +fn genesis_key_delegation_setters_getters_test() { + let genesishash = fake_genesis_hash(1); + let genesis_delegate_hash = fake_genesis_delegate_hash(2); + let vrf_keyhash = fake_vrf_key_hash(3); + + let genesis_key_delegation = + GenesisKeyDelegation::new(&genesishash, &genesis_delegate_hash, &vrf_keyhash); + + assert_eq!(genesis_key_delegation.genesishash(), genesishash); + assert_eq!( + genesis_key_delegation.genesis_delegate_hash(), + genesis_delegate_hash + ); + assert_eq!(genesis_key_delegation.vrf_keyhash(), vrf_keyhash); +} + +#[test] +fn move_instantaneous_rewards_setters_getters_test() { + let mir_to_other_pot = + MoveInstantaneousReward::new_to_other_pot(MIRPot::Reserves, &Coin::from(100u32)); + + let mut rewards = MIRToStakeCredentials::new(); + rewards.insert( + &Credential::from_keyhash(&fake_key_hash(1)), + &DeltaCoin::new_i32(100), + ); + rewards.insert( + &Credential::from_keyhash(&fake_key_hash(2)), + &DeltaCoin::new_i32(200), + ); + + let mir_to_stake_credentials = + MoveInstantaneousReward::new_to_stake_creds(MIRPot::Treasury, &rewards); + + assert_eq!(mir_to_other_pot.kind(), MIRKind::ToOtherPot); + assert_eq!(mir_to_other_pot.pot(), MIRPot::Reserves); + assert_eq!(mir_to_other_pot.as_to_other_pot(), Some(Coin::from(100u32))); + assert_eq!(mir_to_other_pot.as_to_stake_creds(), None); + + assert_eq!(mir_to_stake_credentials.kind(), MIRKind::ToStakeCredentials); + assert_eq!(mir_to_stake_credentials.pot(), MIRPot::Treasury); + assert_eq!(mir_to_stake_credentials.as_to_other_pot(), None); + assert_eq!(mir_to_stake_credentials.as_to_stake_creds(), Some(rewards)); +} + +#[test] +fn pool_registration_setters_getters_test() { + let pool_params = crate_full_pool_params(); + let pool_registration = PoolRegistration::new(&pool_params); + + assert_eq!(pool_registration.pool_params(), pool_params); +} + +#[test] +fn pool_retirement_setters_getters_test() { + let pool_key_hash = fake_key_hash(1); + let epoch = Epoch::from(100u32); + let pool_retirement = PoolRetirement::new(&pool_key_hash, epoch); + + assert_eq!(pool_retirement.pool_keyhash(), pool_key_hash); + assert_eq!(pool_retirement.epoch(), epoch); +} + +#[test] +fn stake_and_vote_delegation_setters_getters_test() { + let cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); + let pool_key_hash = fake_key_hash(2); + let drep = DRep::new_always_no_confidence(); + let stake_and_vote_delegation = + StakeAndVoteDelegation::new(&cred_key_hash, &pool_key_hash, &drep); + + assert_eq!(stake_and_vote_delegation.stake_credential(), cred_key_hash); + assert_eq!(stake_and_vote_delegation.pool_keyhash(), pool_key_hash); + assert_eq!(stake_and_vote_delegation.drep(), drep); + assert_eq!(stake_and_vote_delegation.has_script_credentials(), false); +} + +#[test] +fn stake_delegation_setters_getters_test() { + let cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); + let pool_key_hash = fake_key_hash(2); + let stake_delegation = StakeDelegation::new(&cred_key_hash, &pool_key_hash); + assert_eq!(stake_delegation.stake_credential(), cred_key_hash); + assert_eq!(stake_delegation.pool_keyhash(), pool_key_hash); + assert_eq!(stake_delegation.has_script_credentials(), false); +} + +#[test] +fn stake_deregisration_setters_getters_test() { + let cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); + let stake_deregistration_1 = StakeDeregistration::new(&cred_key_hash); + + let coin = Coin::from(100u32); + let stake_deregistration_2 = StakeDeregistration::new_with_coin(&cred_key_hash, &coin); + + assert_eq!(stake_deregistration_1.stake_credential(), cred_key_hash); + assert_eq!(stake_deregistration_1.coin(), None); + assert_eq!(stake_deregistration_1.has_script_credentials(), false); + assert_eq!(stake_deregistration_2.stake_credential(), cred_key_hash); + assert_eq!(stake_deregistration_2.coin(), Some(coin)); + assert_eq!(stake_deregistration_2.has_script_credentials(), false); +} + +#[test] +fn stake_regisration_setters_getters_test() { + let cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); + let coin = Coin::from(100u32); + let stake_registration_1 = StakeRegistration::new(&cred_key_hash); + let stake_registration_2 = StakeRegistration::new_with_coin(&cred_key_hash, &coin); + + assert_eq!(stake_registration_1.stake_credential(), cred_key_hash); + assert_eq!(stake_registration_1.coin(), None); + assert_eq!(stake_registration_2.stake_credential(), cred_key_hash); + assert_eq!(stake_registration_2.coin(), Some(coin)); +} + +#[test] +fn stake_registration_and_delegation_setters_getters_test() { + let cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); + let pool_key_hash = fake_key_hash(2); + let coin = Coin::from(100u32); + let stake_registration_and_delegation = + StakeRegistrationAndDelegation::new(&cred_key_hash, &pool_key_hash, &coin); + + assert_eq!( + stake_registration_and_delegation.stake_credential(), + cred_key_hash + ); + assert_eq!( + stake_registration_and_delegation.pool_keyhash(), + pool_key_hash + ); + assert_eq!(stake_registration_and_delegation.coin(), coin); +} + +#[test] +fn stake_vote_registration_and_delegation_setters_getters_test() { + let cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); + let pool_key_hash = fake_key_hash(2); + let drep = DRep::new_always_no_confidence(); + let coin = Coin::from(100u32); + let stake_vote_registration_and_delegation = + StakeVoteRegistrationAndDelegation::new(&cred_key_hash, &pool_key_hash, &drep, &coin); + + assert_eq!( + stake_vote_registration_and_delegation.stake_credential(), + cred_key_hash + ); + assert_eq!( + stake_vote_registration_and_delegation.pool_keyhash(), + pool_key_hash + ); + assert_eq!(stake_vote_registration_and_delegation.drep(), drep); + assert_eq!(stake_vote_registration_and_delegation.coin(), coin); + assert_eq!( + stake_vote_registration_and_delegation.has_script_credentials(), + false + ); +} + +#[test] +fn vote_delegation_setters_getters_test() { + let cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); + let drep = DRep::new_always_no_confidence(); + let vote_delegation = VoteDelegation::new(&cred_key_hash, &drep); + + assert_eq!(vote_delegation.stake_credential(), cred_key_hash); + assert_eq!(vote_delegation.drep(), drep); + assert_eq!(vote_delegation.has_script_credentials(), false); +} + +#[test] +fn vote_registration_and_delegation_setters_getters_test() { + let cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); + let drep = DRep::new_always_no_confidence(); + let coin = Coin::from(100u32); + let vote_registration_and_delegation = + VoteRegistrationAndDelegation::new(&cred_key_hash, &drep, &coin); + + assert_eq!( + vote_registration_and_delegation.stake_credential(), + cred_key_hash + ); + assert_eq!(vote_registration_and_delegation.drep(), drep); + assert_eq!(vote_registration_and_delegation.coin(), coin); + assert_eq!( + vote_registration_and_delegation.has_script_credentials(), + false + ); +} From 5e37e3f631c584c1ca408afc923c1bf7c41e094e Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 1 Sep 2023 13:51:29 +0500 Subject: [PATCH 109/349] move fixed_tx test --- rust/src/tests/protocol_types/fixed_tx.rs | 66 +++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 rust/src/tests/protocol_types/fixed_tx.rs diff --git a/rust/src/tests/protocol_types/fixed_tx.rs b/rust/src/tests/protocol_types/fixed_tx.rs new file mode 100644 index 00000000..cb9b09e0 --- /dev/null +++ b/rust/src/tests/protocol_types/fixed_tx.rs @@ -0,0 +1,66 @@ +use crate::*; +use hex; + +#[test] +fn simple_round_trip() { + let original_tx = FixedTransaction::from_hex("84a700818258208b9c96823c19f2047f32210a330434b3d163e194ea17b2b702c0667f6fea7a7a000d80018182581d6138fe1dd1d91221a199ff0dacf41fdd5b87506b533d00e70fae8dae8f1abfbac06a021a0002b645031a03962de305a1581de1b3cabd3914ef99169ace1e8b545b635f809caa35f8b6c8bc69ae48061abf4009040e80a100828258207dc05ac55cdfb9cc24571d491d3a3bdbd7d48489a916d27fce3ffe5c9af1b7f55840d7eda8457f1814fe3333b7b1916e3b034e6d480f97f4f286b1443ef72383279718a3a3fddf127dae0505b01a48fd9ffe0f52d9d8c46d02bcb85d1d106c13aa048258201b3d6e1236891a921abf1a3f90a9fb1b2568b1096b6cd6d3eaaeb0ef0ee0802f58401ce4658303c3eb0f2b9705992ccd62de30423ade90219e2c4cfc9eb488c892ea28ba3110f0c062298447f4f6365499d97d31207075f9815c3fe530bd9a927402f5f6").unwrap(); + let body = hex::decode("a700818258208b9c96823c19f2047f32210a330434b3d163e194ea17b2b702c0667f6fea7a7a000d80018182581d6138fe1dd1d91221a199ff0dacf41fdd5b87506b533d00e70fae8dae8f1abfbac06a021a0002b645031a03962de305a1581de1b3cabd3914ef99169ace1e8b545b635f809caa35f8b6c8bc69ae48061abf4009040e80").unwrap(); + let wit_set = hex::decode("a100828258207dc05ac55cdfb9cc24571d491d3a3bdbd7d48489a916d27fce3ffe5c9af1b7f55840d7eda8457f1814fe3333b7b1916e3b034e6d480f97f4f286b1443ef72383279718a3a3fddf127dae0505b01a48fd9ffe0f52d9d8c46d02bcb85d1d106c13aa048258201b3d6e1236891a921abf1a3f90a9fb1b2568b1096b6cd6d3eaaeb0ef0ee0802f58401ce4658303c3eb0f2b9705992ccd62de30423ade90219e2c4cfc9eb488c892ea28ba3110f0c062298447f4f6365499d97d31207075f9815c3fe530bd9a927402").unwrap(); + let tx = FixedTransaction::new(&body, &wit_set, true).unwrap(); + let tx2 = FixedTransaction::from_bytes(tx.to_bytes()).unwrap(); + + assert_eq!(body, tx2.raw_body()); + assert_eq!(wit_set, tx2.raw_witness_set()); + assert_eq!(tx.raw_body(), tx2.raw_body()); + assert_eq!(tx.raw_witness_set(), tx2.raw_witness_set()); + assert_eq!(tx.is_valid(), tx2.is_valid()); + assert_eq!(tx.to_bytes(), tx2.to_bytes()); + assert_eq!(tx.raw_body(), original_tx.raw_body()); + assert_eq!(tx.raw_witness_set(), original_tx.raw_witness_set()); + assert_eq!(tx.is_valid(), original_tx.is_valid()); + assert_eq!(tx.to_bytes(), original_tx.to_bytes()); +} + +#[test] +fn round_trip_via_tx() { + let casual_tx = Transaction::from_hex("84a700818258208b9c96823c19f2047f32210a330434b3d163e194ea17b2b702c0667f6fea7a7a000d80018182581d6138fe1dd1d91221a199ff0dacf41fdd5b87506b533d00e70fae8dae8f1abfbac06a021a0002b645031a03962de305a1581de1b3cabd3914ef99169ace1e8b545b635f809caa35f8b6c8bc69ae48061abf4009040e80a100828258207dc05ac55cdfb9cc24571d491d3a3bdbd7d48489a916d27fce3ffe5c9af1b7f55840d7eda8457f1814fe3333b7b1916e3b034e6d480f97f4f286b1443ef72383279718a3a3fddf127dae0505b01a48fd9ffe0f52d9d8c46d02bcb85d1d106c13aa048258201b3d6e1236891a921abf1a3f90a9fb1b2568b1096b6cd6d3eaaeb0ef0ee0802f58401ce4658303c3eb0f2b9705992ccd62de30423ade90219e2c4cfc9eb488c892ea28ba3110f0c062298447f4f6365499d97d31207075f9815c3fe530bd9a927402f5f6").unwrap(); + let body = hex::decode("a700818258208b9c96823c19f2047f32210a330434b3d163e194ea17b2b702c0667f6fea7a7a000d80018182581d6138fe1dd1d91221a199ff0dacf41fdd5b87506b533d00e70fae8dae8f1abfbac06a021a0002b645031a03962de305a1581de1b3cabd3914ef99169ace1e8b545b635f809caa35f8b6c8bc69ae48061abf4009040e80").unwrap(); + let wit_set = hex::decode("a100828258207dc05ac55cdfb9cc24571d491d3a3bdbd7d48489a916d27fce3ffe5c9af1b7f55840d7eda8457f1814fe3333b7b1916e3b034e6d480f97f4f286b1443ef72383279718a3a3fddf127dae0505b01a48fd9ffe0f52d9d8c46d02bcb85d1d106c13aa048258201b3d6e1236891a921abf1a3f90a9fb1b2568b1096b6cd6d3eaaeb0ef0ee0802f58401ce4658303c3eb0f2b9705992ccd62de30423ade90219e2c4cfc9eb488c892ea28ba3110f0c062298447f4f6365499d97d31207075f9815c3fe530bd9a927402").unwrap(); + let tx = FixedTransaction::new(&body, &wit_set, true).unwrap(); + let tx2 = Transaction::from_bytes(tx.to_bytes()).unwrap(); + + assert_eq!(casual_tx.body(), tx.body()); + assert_eq!(casual_tx.witness_set(), tx.witness_set()); + assert_eq!(casual_tx.is_valid(), tx.is_valid()); + assert_eq!(casual_tx, tx2); +} + +#[test] +fn round_trip_nonstandart_body() { + let original_tx = FixedTransaction::from_hex("84a7009F8258208b9c96823c19f2047f32210a330434b3d163e194ea17b2b702c0667f6fea7a7a00FF0d80018182581d6138fe1dd1d91221a199ff0dacf41fdd5b87506b533d00e70fae8dae8f1abfbac06a021a0002b645031a03962de305a1581de1b3cabd3914ef99169ace1e8b545b635f809caa35f8b6c8bc69ae48061abf4009040e80a100828258207dc05ac55cdfb9cc24571d491d3a3bdbd7d48489a916d27fce3ffe5c9af1b7f55840d7eda8457f1814fe3333b7b1916e3b034e6d480f97f4f286b1443ef72383279718a3a3fddf127dae0505b01a48fd9ffe0f52d9d8c46d02bcb85d1d106c13aa048258201b3d6e1236891a921abf1a3f90a9fb1b2568b1096b6cd6d3eaaeb0ef0ee0802f58401ce4658303c3eb0f2b9705992ccd62de30423ade90219e2c4cfc9eb488c892ea28ba3110f0c062298447f4f6365499d97d31207075f9815c3fe530bd9a927402f5f6").unwrap(); + let casual_tx = Transaction::from_hex("84a7009F8258208b9c96823c19f2047f32210a330434b3d163e194ea17b2b702c0667f6fea7a7a00FF0d80018182581d6138fe1dd1d91221a199ff0dacf41fdd5b87506b533d00e70fae8dae8f1abfbac06a021a0002b645031a03962de305a1581de1b3cabd3914ef99169ace1e8b545b635f809caa35f8b6c8bc69ae48061abf4009040e80a100828258207dc05ac55cdfb9cc24571d491d3a3bdbd7d48489a916d27fce3ffe5c9af1b7f55840d7eda8457f1814fe3333b7b1916e3b034e6d480f97f4f286b1443ef72383279718a3a3fddf127dae0505b01a48fd9ffe0f52d9d8c46d02bcb85d1d106c13aa048258201b3d6e1236891a921abf1a3f90a9fb1b2568b1096b6cd6d3eaaeb0ef0ee0802f58401ce4658303c3eb0f2b9705992ccd62de30423ade90219e2c4cfc9eb488c892ea28ba3110f0c062298447f4f6365499d97d31207075f9815c3fe530bd9a927402f5f6").unwrap(); + let body = hex::decode("a7009F8258208b9c96823c19f2047f32210a330434b3d163e194ea17b2b702c0667f6fea7a7a00FF0d80018182581d6138fe1dd1d91221a199ff0dacf41fdd5b87506b533d00e70fae8dae8f1abfbac06a021a0002b645031a03962de305a1581de1b3cabd3914ef99169ace1e8b545b635f809caa35f8b6c8bc69ae48061abf4009040e80").unwrap(); + let wit_set = hex::decode("a100828258207dc05ac55cdfb9cc24571d491d3a3bdbd7d48489a916d27fce3ffe5c9af1b7f55840d7eda8457f1814fe3333b7b1916e3b034e6d480f97f4f286b1443ef72383279718a3a3fddf127dae0505b01a48fd9ffe0f52d9d8c46d02bcb85d1d106c13aa048258201b3d6e1236891a921abf1a3f90a9fb1b2568b1096b6cd6d3eaaeb0ef0ee0802f58401ce4658303c3eb0f2b9705992ccd62de30423ade90219e2c4cfc9eb488c892ea28ba3110f0c062298447f4f6365499d97d31207075f9815c3fe530bd9a927402").unwrap(); + let tx = FixedTransaction::new(&body, &wit_set, true).unwrap(); + let tx2 = Transaction::from_bytes(tx.to_bytes()).unwrap(); + let tx3 = FixedTransaction::from_bytes(tx.to_bytes()).unwrap(); + + assert_eq!(casual_tx.body(), tx.body()); + assert_eq!(casual_tx.witness_set(), tx.witness_set()); + assert_eq!(casual_tx.is_valid(), tx.is_valid()); + + assert_eq!(body, tx3.raw_body()); + assert_eq!(wit_set, tx3.raw_witness_set()); + assert_eq!(tx.raw_body(), tx3.raw_body()); + assert_eq!(tx.raw_witness_set(), tx3.raw_witness_set()); + assert_eq!(tx.is_valid(), tx3.is_valid()); + assert_eq!(tx.to_bytes(), tx3.to_bytes()); + assert_eq!(tx.raw_body(), original_tx.raw_body()); + assert_eq!(tx.raw_witness_set(), original_tx.raw_witness_set()); + assert_eq!(tx.is_valid(), original_tx.is_valid()); + assert_eq!(tx.to_bytes(), original_tx.to_bytes()); + + assert_eq!(casual_tx, tx2); + + assert_ne!(tx2.to_bytes(), original_tx.to_bytes()); +} From dc8898dfe2f24d00b8018ae35015788a7fb6ac83 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 1 Sep 2023 13:52:22 +0500 Subject: [PATCH 110/349] add missed functions --- .../protocol_types/governance/governance_action_ids.rs | 4 ++++ rust/src/protocol_types/governance/voter.rs | 8 ++++---- rust/src/protocol_types/governance/voters.rs | 4 ++++ rust/src/tx_builder/voting_builder.rs | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/rust/src/protocol_types/governance/governance_action_ids.rs b/rust/src/protocol_types/governance/governance_action_ids.rs index d3a1e70f..bb1f50a7 100644 --- a/rust/src/protocol_types/governance/governance_action_ids.rs +++ b/rust/src/protocol_types/governance/governance_action_ids.rs @@ -23,6 +23,10 @@ impl GovernanceActionIds { Self(Vec::new()) } + pub fn add(&mut self, governance_action_id: &GovernanceActionId) { + self.0.push(governance_action_id.clone()); + } + pub fn get(&self, index: usize) -> Option { self.0.get(index).cloned() } diff --git a/rust/src/protocol_types/governance/voter.rs b/rust/src/protocol_types/governance/voter.rs index 38af069f..55847ef4 100644 --- a/rust/src/protocol_types/governance/voter.rs +++ b/rust/src/protocol_types/governance/voter.rs @@ -73,21 +73,21 @@ impl Voter { } } - pub fn to_constitutional_committee_hot_key(&self) -> Option { + pub fn to_constitutional_committee_hot_cred(&self) -> Option { match &self.0 { VoterEnum::ConstitutionalCommitteeHotKey(cred) => Some(cred.clone()), _ => None, } } - pub fn to_drep(&self) -> Option { + pub fn to_drep_cred(&self) -> Option { match &self.0 { VoterEnum::DRep(cred) => Some(cred.clone()), _ => None, } } - pub fn to_staking_pool(&self) -> Option { + pub fn to_staking_pool_key_hash(&self) -> Option { match &self.0 { VoterEnum::StakingPool(key_hash) => Some(key_hash.clone()), _ => None, @@ -103,7 +103,7 @@ impl Voter { } } - pub fn to_keyhash(&self) -> Option { + pub fn to_key_hash(&self) -> Option { match &self.0 { VoterEnum::ConstitutionalCommitteeHotKey(cred) => cred.to_keyhash(), VoterEnum::DRep(cred) => cred.to_keyhash(), diff --git a/rust/src/protocol_types/governance/voters.rs b/rust/src/protocol_types/governance/voters.rs index 6a8f437f..89a1f718 100644 --- a/rust/src/protocol_types/governance/voters.rs +++ b/rust/src/protocol_types/governance/voters.rs @@ -23,6 +23,10 @@ impl Voters { Self(Vec::new()) } + pub fn add(&mut self, voter: &Voter) { + self.0.push(voter.clone()); + } + pub fn get(&self, index: usize) -> Option { self.0.get(index).cloned() } diff --git a/rust/src/tx_builder/voting_builder.rs b/rust/src/tx_builder/voting_builder.rs index 4207c932..c98c0a68 100644 --- a/rust/src/tx_builder/voting_builder.rs +++ b/rust/src/tx_builder/voting_builder.rs @@ -98,7 +98,7 @@ impl VotingBuilder { pub(crate) fn get_required_signers(&self) -> RequiredSignersSet { let mut set = RequiredSignersSet::new(); for (voter, voter_votes) in &self.votes { - let req_signature = voter.to_keyhash(); + let req_signature = voter.to_key_hash(); if let Some(req_signature) = req_signature { set.insert(req_signature); } From 48c93efa3408a9fa8fbb281afceecb3f8e581ed6 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 1 Sep 2023 13:52:40 +0500 Subject: [PATCH 111/349] function rename --- rust/src/protocol_types/governance/anchor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/src/protocol_types/governance/anchor.rs b/rust/src/protocol_types/governance/anchor.rs index 32ae595e..16a3c4b2 100644 --- a/rust/src/protocol_types/governance/anchor.rs +++ b/rust/src/protocol_types/governance/anchor.rs @@ -22,7 +22,7 @@ impl_to_from!(Anchor); #[wasm_bindgen] impl Anchor { - pub fn anchor_url(&self) -> URL { + pub fn url(&self) -> URL { self.anchor_url.clone() } From 9f88b77a0381232730063aacb639454fab917a08 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 1 Sep 2023 13:53:01 +0500 Subject: [PATCH 112/349] fix for tests --- rust/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index b2d88332..247363e8 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1114,7 +1114,7 @@ impl StakeCredentials { #[derive( Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, )] -pub struct RewardAddresses(Vec); +pub struct RewardAddresses(pub(crate) Vec); impl_to_from!(RewardAddresses); From ba256ff03a5df5a7b859228eff9ca11a3a4a64a1 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 1 Sep 2023 13:53:25 +0500 Subject: [PATCH 113/349] add governance tests --- .../tests/protocol_types/governance/common.rs | 220 ++++++++++++++++++ .../protocol_types/governance/proposals.rs | 168 +++++++++++++ 2 files changed, 388 insertions(+) create mode 100644 rust/src/tests/protocol_types/governance/common.rs create mode 100644 rust/src/tests/protocol_types/governance/proposals.rs diff --git a/rust/src/tests/protocol_types/governance/common.rs b/rust/src/tests/protocol_types/governance/common.rs new file mode 100644 index 00000000..7429cf24 --- /dev/null +++ b/rust/src/tests/protocol_types/governance/common.rs @@ -0,0 +1,220 @@ +use crate::*; +use crate::fakes::{fake_anchor_data_hash, fake_key_hash, fake_script_hash, fake_tx_hash}; +use crate::tests::mock_objects::create_anchor; + +#[test] +fn drep_abstain_setters_getters_test() { + let drep = DRep::new_always_abstain(); + assert_eq!(drep.kind(), DRepKind::AlwaysAbstain); + assert_eq!(drep.to_key_hash(), None); + assert_eq!(drep.to_script_hash(), None); +} + +#[test] +fn drep_no_confidence_setters_getters_test() { + let drep = DRep::new_always_no_confidence(); + assert_eq!(drep.kind(), DRepKind::AlwaysNoConfidence); + assert_eq!(drep.to_key_hash(), None); + assert_eq!(drep.to_script_hash(), None); +} + +#[test] +fn drep_key_hash_setters_getters_test() { + let key_hash = fake_key_hash(1); + let drep = DRep::new_key_hash(&key_hash); + assert_eq!(drep.kind(), DRepKind::KeyHash); + assert_eq!(drep.to_key_hash(), Some(key_hash)); + assert_eq!(drep.to_script_hash(), None); +} + +#[test] +fn drep_script_hash_setters_getters_test() { + let script_hash = fake_script_hash(1); + let drep = DRep::new_script_hash(&script_hash); + assert_eq!(drep.kind(), DRepKind::ScriptHash); + assert_eq!(drep.to_key_hash(), None); + assert_eq!(drep.to_script_hash(), Some(script_hash)); +} + +#[test] +fn anchor_setters_getters_test() { + let data_hash = fake_anchor_data_hash(1); + let url = URL::new("https://example.com".to_string()).unwrap(); + let anchor = Anchor::new( + &url, + &data_hash, + ); + assert_eq!(anchor.url(), url); + assert_eq!(anchor.anchor_data_hash(), data_hash); +} + +#[test] +fn governance_action_id_setters_getters_test() { + let index = 1; + let tx_hash = fake_tx_hash(1); + let governance_action_id = GovernanceActionId::new(&tx_hash, index); + assert_eq!(governance_action_id.transaction_id(), tx_hash); + assert_eq!(governance_action_id.index(), index); +} + +#[test] +fn governance_action_ids_setters_getters_test() { + let index_1 = 1; + let tx_hash_1 = fake_tx_hash(1); + let index_2 = 2; + let tx_hash_2 = fake_tx_hash(2); + let governance_action_id_1 = GovernanceActionId::new(&tx_hash_1, index_1); + let governance_action_id_2 = GovernanceActionId::new(&tx_hash_2, index_2); + let mut governance_action_ids = GovernanceActionIds::new(); + governance_action_ids.add(&governance_action_id_1); + governance_action_ids.add(&governance_action_id_2); + assert_eq!(governance_action_ids.len(), 2); + assert_eq!(governance_action_ids.get(0), Some(governance_action_id_1)); + assert_eq!(governance_action_ids.get(1), Some(governance_action_id_2)); + assert_eq!(governance_action_ids.get(2), None); +} + +#[test] +fn voter_drep_key_hash_setters_getters_test() { + let key_hash = fake_key_hash(1); + let voter = Voter::new_drep(&Credential::from_keyhash(&key_hash)); + assert_eq!(voter.kind(), VoterKind::DRepKeyHash); + assert_eq!(voter.to_drep_cred(), Some(Credential::from_keyhash(&key_hash))); + assert_eq!(voter.to_staking_pool_key_hash(), None); + assert_eq!(voter.to_constitutional_committee_hot_cred(), None); + assert_eq!(voter.has_script_credentials(), false); + assert_eq!(voter.to_key_hash(), Some(key_hash)); +} + +#[test] +fn voter_drep_script_hash_setters_getters_test() { + let script_hash = fake_script_hash(1); + let voter = Voter::new_drep(&Credential::from_scripthash(&script_hash)); + assert_eq!(voter.kind(), VoterKind::DRepScriptHash); + assert_eq!(voter.to_drep_cred(), Some(Credential::from_scripthash(&script_hash))); + assert_eq!(voter.to_staking_pool_key_hash(), None); + assert_eq!(voter.to_constitutional_committee_hot_cred(), None); + assert_eq!(voter.has_script_credentials(), true); + assert_eq!(voter.to_key_hash(), None); +} + +#[test] +fn voter_constitutional_committee_hot_key_hash_setters_getters_test() { + let key_hash = fake_key_hash(1); + let voter = Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash(&key_hash)); + assert_eq!(voter.kind(), VoterKind::ConstitutionalCommitteeHotKeyHash); + assert_eq!(voter.to_constitutional_committee_hot_cred(), Some(Credential::from_keyhash(&key_hash))); + assert_eq!(voter.to_staking_pool_key_hash(), None); + assert_eq!(voter.to_drep_cred(), None); + assert_eq!(voter.has_script_credentials(), false); + assert_eq!(voter.to_key_hash(), Some(key_hash)); +} + +#[test] +fn voter_constitutional_committee_hot_script_hash_setters_getters_test() { + let script_hash = fake_script_hash(1); + let voter = Voter::new_constitutional_committee_hot_key(&Credential::from_scripthash(&script_hash)); + assert_eq!(voter.kind(), VoterKind::ConstitutionalCommitteeHotScriptHash); + assert_eq!(voter.to_constitutional_committee_hot_cred(), Some(Credential::from_scripthash(&script_hash))); + assert_eq!(voter.to_staking_pool_key_hash(), None); + assert_eq!(voter.to_drep_cred(), None); + assert_eq!(voter.has_script_credentials(), true); + assert_eq!(voter.to_key_hash(), None); +} + +#[test] +fn voter_staking_pool_key_hash_setters_getters_test() { + let key_hash = fake_key_hash(1); + let voter = Voter::new_staking_pool(&key_hash); + assert_eq!(voter.kind(), VoterKind::StakingPoolKeyHash); + assert_eq!(voter.to_staking_pool_key_hash(), Some(key_hash.clone())); + assert_eq!(voter.to_constitutional_committee_hot_cred(), None); + assert_eq!(voter.to_drep_cred(), None); + assert_eq!(voter.has_script_credentials(), false); + assert_eq!(voter.to_key_hash(), Some(key_hash)); +} + +#[test] +fn voters_setters_getters_test() { + let key_hash_1 = fake_key_hash(1); + let voter_1 = Voter::new_staking_pool(&key_hash_1); + let key_hash_2 = fake_key_hash(2); + let voter_2 = Voter::new_staking_pool(&key_hash_2); + let mut voters = Voters::new(); + voters.add(&voter_1); + voters.add(&voter_2); + assert_eq!(voters.len(), 2); + assert_eq!(voters.get(0), Some(voter_1)); + assert_eq!(voters.get(1), Some(voter_2)); + assert_eq!(voters.get(2), None); +} + +#[test] +fn voting_procedure_setters_getters_test() { + let yes_procedure = VotingProcedure::new(VoteKind::Yes); + assert_eq!(yes_procedure.vote_kind(), VoteKind::Yes); + assert_eq!(yes_procedure.anchor(), None); + + let no_procedure = VotingProcedure::new(VoteKind::No); + assert_eq!(no_procedure.vote_kind(), VoteKind::No); + assert_eq!(no_procedure.anchor(), None); + + let abstain_procedure = VotingProcedure::new(VoteKind::Abstain); + assert_eq!(abstain_procedure.vote_kind(), VoteKind::Abstain); + assert_eq!(abstain_procedure.anchor(), None); +} + +#[test] +fn voting_procedure_with_anchor_setters_getters_test() { + let anchor = create_anchor(); + let yes_procedure = VotingProcedure::new_with_anchor(VoteKind::Yes, &anchor); + assert_eq!(yes_procedure.vote_kind(), VoteKind::Yes); + assert_eq!(yes_procedure.anchor(), Some(anchor.clone())); + + let no_procedure = VotingProcedure::new_with_anchor(VoteKind::No, &anchor); + assert_eq!(no_procedure.vote_kind(), VoteKind::No); + assert_eq!(no_procedure.anchor(), Some(anchor.clone())); + + let abstain_procedure = VotingProcedure::new_with_anchor(VoteKind::Abstain, &anchor); + assert_eq!(abstain_procedure.vote_kind(), VoteKind::Abstain); + assert_eq!(abstain_procedure.anchor(), Some(anchor)); +} + +#[test] +fn voting_procedures_setters_getters_test() { + let key_hash_1 = fake_key_hash(1); + let voter_1 = Voter::new_staking_pool(&key_hash_1); + let key_hash_2 = fake_key_hash(2); + let voter_2 = Voter::new_staking_pool(&key_hash_2); + let governance_action_id_1 = GovernanceActionId::new(&fake_tx_hash(1), 1); + let governance_action_id_2 = GovernanceActionId::new(&fake_tx_hash(2), 2); + let governance_action_id_3 = GovernanceActionId::new(&fake_tx_hash(3), 3); + let voting_procedure_1 = VotingProcedure::new(VoteKind::Yes); + let voting_procedure_2 = VotingProcedure::new(VoteKind::No); + let voting_procedure_3 = VotingProcedure::new(VoteKind::Abstain); + let mut voting_procedures = VotingProcedures::new(); + voting_procedures.insert(&voter_1, &governance_action_id_1, &voting_procedure_1); + voting_procedures.insert(&voter_2, &governance_action_id_2, &voting_procedure_2); + voting_procedures.insert(&voter_2, &governance_action_id_3, &voting_procedure_3); + + assert_eq!(voting_procedures.get(&voter_1, &governance_action_id_1), Some(voting_procedure_1)); + assert_eq!(voting_procedures.get(&voter_2, &governance_action_id_2), Some(voting_procedure_2)); + assert_eq!(voting_procedures.get(&voter_2, &governance_action_id_3), Some(voting_procedure_3)); + assert_eq!(voting_procedures.get(&voter_1, &governance_action_id_2), None); + assert_eq!(voting_procedures.get(&voter_1, &governance_action_id_3), None); + assert_eq!(voting_procedures.get(&voter_2, &governance_action_id_1), None); + + let voters = voting_procedures.get_voters(); + assert_eq!(voters.len(), 2); + assert!(voters.0.contains(&voter_1)); + assert!(voters.0.contains(&voter_2)); + + let governance_action_ids_1 = voting_procedures.get_governance_action_ids_by_voter(&voter_1); + assert_eq!(governance_action_ids_1.len(), 1); + assert!(governance_action_ids_1.0.contains(&governance_action_id_1)); + + let governance_action_ids_2 = voting_procedures.get_governance_action_ids_by_voter(&voter_2); + assert_eq!(governance_action_ids_2.len(), 2); + assert!(governance_action_ids_2.0.contains(&governance_action_id_2)); + assert!(governance_action_ids_2.0.contains(&governance_action_id_3)); +} diff --git a/rust/src/tests/protocol_types/governance/proposals.rs b/rust/src/tests/protocol_types/governance/proposals.rs new file mode 100644 index 00000000..d2706a28 --- /dev/null +++ b/rust/src/tests/protocol_types/governance/proposals.rs @@ -0,0 +1,168 @@ +use crate::fakes::{fake_key_hash, fake_script_hash}; +use crate::tests::mock_objects::{ + crate_full_protocol_param_update, create_action_id, create_anchor, +}; +use crate::*; +use itertools::Itertools; + +#[test] +fn committee_setters_getters_test() { + let threshold = UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32)); + let mut committee = Committee::new(&threshold); + let cred_1 = Credential::from_keyhash(&fake_key_hash(1)); + let epoch_1 = Epoch::from(100u32); + let cred_2 = Credential::from_scripthash(&fake_script_hash(2)); + let epoch_2 = Epoch::from(200u32); + let cred_3 = Credential::from_scripthash(&fake_script_hash(3)); + + committee.add_member(&cred_1, epoch_1); + committee.add_member(&cred_2, epoch_2); + + let keys = committee.members_keys(); + assert_eq!(committee.quorum_threshold(), threshold); + assert_eq!(keys.len(), 2); + assert!(keys.0.iter().contains(&cred_1)); + assert!(keys.0.iter().contains(&cred_2)); + assert_eq!(committee.get_member_epoch(&cred_1), Some(epoch_1)); + assert_eq!(committee.get_member_epoch(&cred_2), Some(epoch_2)); + assert_eq!(committee.get_member_epoch(&cred_3), None); +} + +#[test] +fn constitution_setters_getters_test() { + let anchor = create_anchor(); + let constitution = Constitution::new(&anchor); + assert_eq!(constitution.anchor(), anchor); + assert_eq!(constitution.script_hash(), None); + + let script_hash = fake_script_hash(1); + let constitution = Constitution::new_with_script_hash(&anchor, &script_hash); + assert_eq!(constitution.anchor(), anchor); + assert_eq!(constitution.script_hash(), Some(script_hash)); +} + +#[test] +fn hard_fork_initiation_proposal_setters_getters_test() { + let protocol_version = ProtocolVersion::new(1, 2); + let proposal = HardForkInitiationProposal::new(&protocol_version); + let action_id = create_action_id(); + let proposal_with_action_id = + HardForkInitiationProposal::new_with_action_id(&action_id, &protocol_version); + assert_eq!(proposal.gov_action_id(), None); + assert_eq!(proposal.protocol_version(), protocol_version); + assert_eq!(proposal_with_action_id.gov_action_id(), Some(action_id)); + assert_eq!(proposal_with_action_id.protocol_version(), protocol_version); +} + +#[test] +fn new_committee_proposal_setters_getters_test() { + let action_id = create_action_id(); + let committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); + let members_to_remove = StakeCredentials( + vec![ + Credential::from_keyhash(&fake_key_hash(1)), + Credential::from_keyhash(&fake_key_hash(2)), + ] + .into_iter() + .collect(), + ); + + let proposal = NewCommitteeProposal::new(&committee, &members_to_remove); + let proposal_with_action_id = + NewCommitteeProposal::new_with_action_id(&action_id, &committee, &members_to_remove); + assert_eq!(proposal.gov_action_id(), None); + assert_eq!(proposal.committee(), committee); + assert_eq!(proposal.members_to_remove(), members_to_remove); + assert_eq!(proposal_with_action_id.gov_action_id(), Some(action_id)); + assert_eq!(proposal_with_action_id.committee(), committee); + assert_eq!( + proposal_with_action_id.members_to_remove(), + members_to_remove + ); +} + +#[test] +fn new_constitution_proposal_setters_getters_test() { + let action_id = create_action_id(); + let constitution = Constitution::new(&create_anchor()); + let proposal = NewConstitutionProposal::new(&constitution); + let proposal_with_action_id = + NewConstitutionProposal::new_with_action_id(&action_id, &constitution); + assert_eq!(proposal.gov_action_id(), None); + assert_eq!(proposal.constitution(), constitution); + assert_eq!(proposal_with_action_id.gov_action_id(), Some(action_id)); + assert_eq!(proposal_with_action_id.constitution(), constitution); +} + +#[test] +fn no_confidence_proposal_setters_getters_test() { + let action_id = create_action_id(); + let proposal = NoConfidenceProposal::new(); + let proposal_with_action_id = NoConfidenceProposal::new_with_action_id(&action_id); + assert_eq!(proposal.gov_action_id(), None); + assert_eq!(proposal_with_action_id.gov_action_id(), Some(action_id)); +} + +#[test] +fn parameter_change_proposal_setters_getters_test() { + let protocol_params = crate_full_protocol_param_update(); + let action_id = create_action_id(); + let proposal = ParameterChangeProposal::new(&protocol_params); + let proposal_with_action_id = + ParameterChangeProposal::new_with_action_id(&action_id, &protocol_params); + assert_eq!(proposal.gov_action_id(), None); + assert_eq!(proposal.protocol_param_updates(), protocol_params); + assert_eq!(proposal_with_action_id.gov_action_id(), Some(action_id)); + assert_eq!( + proposal_with_action_id.protocol_param_updates(), + protocol_params + ); +} + +#[test] +fn treasury_withdrawals_setters_getters_test() { + let mut withdrawals = TreasuryWithdrawals::new(); + let addr1 = RewardAddress::new(1, &Credential::from_keyhash(&fake_key_hash(1))); + let addr2 = RewardAddress::new(1, &Credential::from_keyhash(&fake_key_hash(2))); + let coin1 = Coin::from(100u32); + let coin2 = Coin::from(200u32); + withdrawals.insert(&addr1, &coin1); + withdrawals.insert(&addr2, &coin2); + + let keys = withdrawals.keys(); + assert_eq!(keys.len(), 2); + assert!(keys.0.iter().contains(&addr1)); + assert!(keys.0.iter().contains(&addr2)); + assert_eq!(withdrawals.get(&addr1), Some(coin1)); + assert_eq!(withdrawals.get(&addr2), Some(coin2)); +} + +#[test] +fn treasury_withdrawals_proposal() { + let mut withdrawals = TreasuryWithdrawals::new(); + let addr = RewardAddress::new(1, &Credential::from_keyhash(&fake_key_hash(1))); + let coin = Coin::from(100u32); + withdrawals.insert(&addr, &coin); + let proposal = TreasuryWithdrawalsProposal::new(&withdrawals); + assert_eq!(proposal.withdrawals(), withdrawals); +} + +#[test] +fn voting_proposals_setters_getters_test() { + let action_id = create_action_id(); + let mut proposals = VotingProposals::new(); + let no_confidence_proposal = NoConfidenceProposal::new(); + let parameter_change_proposal = + ParameterChangeProposal::new(&crate_full_protocol_param_update()); + proposals.add(&VotingProposal::new_no_confidence_proposal(&no_confidence_proposal)); + proposals.add(&VotingProposal::new_parameter_change_proposal(¶meter_change_proposal)); + assert_eq!(proposals.len(), 2); + assert_eq!( + proposals.get(0), + VotingProposal::new_no_confidence_proposal(&no_confidence_proposal) + ); + assert_eq!( + proposals.get(1), + VotingProposal::new_parameter_change_proposal(¶meter_change_proposal) + ); +} \ No newline at end of file From 619aaaba84331bdc6de3ffacee44639c78e12b4f Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 1 Sep 2023 13:53:35 +0500 Subject: [PATCH 114/349] move fixed tx tests --- rust/src/protocol_types/tests.rs | 73 -------------------------------- 1 file changed, 73 deletions(-) delete mode 100644 rust/src/protocol_types/tests.rs diff --git a/rust/src/protocol_types/tests.rs b/rust/src/protocol_types/tests.rs deleted file mode 100644 index 2ff510e0..00000000 --- a/rust/src/protocol_types/tests.rs +++ /dev/null @@ -1,73 +0,0 @@ -#[cfg(test)] -mod test { - use crate::protocol_types::fixed_tx::FixedTransaction; - use crate::Transaction; - use hex; - - #[test] - fn simple_round_trip() { - let original_tx = FixedTransaction::from_hex("84a700818258208b9c96823c19f2047f32210a330434b3d163e194ea17b2b702c0667f6fea7a7a000d80018182581d6138fe1dd1d91221a199ff0dacf41fdd5b87506b533d00e70fae8dae8f1abfbac06a021a0002b645031a03962de305a1581de1b3cabd3914ef99169ace1e8b545b635f809caa35f8b6c8bc69ae48061abf4009040e80a100828258207dc05ac55cdfb9cc24571d491d3a3bdbd7d48489a916d27fce3ffe5c9af1b7f55840d7eda8457f1814fe3333b7b1916e3b034e6d480f97f4f286b1443ef72383279718a3a3fddf127dae0505b01a48fd9ffe0f52d9d8c46d02bcb85d1d106c13aa048258201b3d6e1236891a921abf1a3f90a9fb1b2568b1096b6cd6d3eaaeb0ef0ee0802f58401ce4658303c3eb0f2b9705992ccd62de30423ade90219e2c4cfc9eb488c892ea28ba3110f0c062298447f4f6365499d97d31207075f9815c3fe530bd9a927402f5f6").unwrap(); - let body = hex::decode("a700818258208b9c96823c19f2047f32210a330434b3d163e194ea17b2b702c0667f6fea7a7a000d80018182581d6138fe1dd1d91221a199ff0dacf41fdd5b87506b533d00e70fae8dae8f1abfbac06a021a0002b645031a03962de305a1581de1b3cabd3914ef99169ace1e8b545b635f809caa35f8b6c8bc69ae48061abf4009040e80").unwrap(); - let wit_set = hex::decode("a100828258207dc05ac55cdfb9cc24571d491d3a3bdbd7d48489a916d27fce3ffe5c9af1b7f55840d7eda8457f1814fe3333b7b1916e3b034e6d480f97f4f286b1443ef72383279718a3a3fddf127dae0505b01a48fd9ffe0f52d9d8c46d02bcb85d1d106c13aa048258201b3d6e1236891a921abf1a3f90a9fb1b2568b1096b6cd6d3eaaeb0ef0ee0802f58401ce4658303c3eb0f2b9705992ccd62de30423ade90219e2c4cfc9eb488c892ea28ba3110f0c062298447f4f6365499d97d31207075f9815c3fe530bd9a927402").unwrap(); - let tx = FixedTransaction::new(&body, &wit_set, true) - .unwrap(); - let tx2 = FixedTransaction::from_bytes(tx.to_bytes()).unwrap(); - - assert_eq!(body, tx2.raw_body()); - assert_eq!(wit_set, tx2.raw_witness_set()); - assert_eq!(tx.raw_body(), tx2.raw_body()); - assert_eq!(tx.raw_witness_set(), tx2.raw_witness_set()); - assert_eq!(tx.is_valid(), tx2.is_valid()); - assert_eq!(tx.to_bytes(), tx2.to_bytes()); - assert_eq!(tx.raw_body(), original_tx.raw_body()); - assert_eq!(tx.raw_witness_set(), original_tx.raw_witness_set()); - assert_eq!(tx.is_valid(), original_tx.is_valid()); - assert_eq!(tx.to_bytes(), original_tx.to_bytes()); - } - - #[test] - fn round_trip_via_tx() { - let casual_tx = Transaction::from_hex("84a700818258208b9c96823c19f2047f32210a330434b3d163e194ea17b2b702c0667f6fea7a7a000d80018182581d6138fe1dd1d91221a199ff0dacf41fdd5b87506b533d00e70fae8dae8f1abfbac06a021a0002b645031a03962de305a1581de1b3cabd3914ef99169ace1e8b545b635f809caa35f8b6c8bc69ae48061abf4009040e80a100828258207dc05ac55cdfb9cc24571d491d3a3bdbd7d48489a916d27fce3ffe5c9af1b7f55840d7eda8457f1814fe3333b7b1916e3b034e6d480f97f4f286b1443ef72383279718a3a3fddf127dae0505b01a48fd9ffe0f52d9d8c46d02bcb85d1d106c13aa048258201b3d6e1236891a921abf1a3f90a9fb1b2568b1096b6cd6d3eaaeb0ef0ee0802f58401ce4658303c3eb0f2b9705992ccd62de30423ade90219e2c4cfc9eb488c892ea28ba3110f0c062298447f4f6365499d97d31207075f9815c3fe530bd9a927402f5f6").unwrap(); - let body = hex::decode("a700818258208b9c96823c19f2047f32210a330434b3d163e194ea17b2b702c0667f6fea7a7a000d80018182581d6138fe1dd1d91221a199ff0dacf41fdd5b87506b533d00e70fae8dae8f1abfbac06a021a0002b645031a03962de305a1581de1b3cabd3914ef99169ace1e8b545b635f809caa35f8b6c8bc69ae48061abf4009040e80").unwrap(); - let wit_set = hex::decode("a100828258207dc05ac55cdfb9cc24571d491d3a3bdbd7d48489a916d27fce3ffe5c9af1b7f55840d7eda8457f1814fe3333b7b1916e3b034e6d480f97f4f286b1443ef72383279718a3a3fddf127dae0505b01a48fd9ffe0f52d9d8c46d02bcb85d1d106c13aa048258201b3d6e1236891a921abf1a3f90a9fb1b2568b1096b6cd6d3eaaeb0ef0ee0802f58401ce4658303c3eb0f2b9705992ccd62de30423ade90219e2c4cfc9eb488c892ea28ba3110f0c062298447f4f6365499d97d31207075f9815c3fe530bd9a927402").unwrap(); - let tx = FixedTransaction::new(&body, &wit_set, true) - .unwrap(); - let tx2 = Transaction::from_bytes(tx.to_bytes()).unwrap(); - - assert_eq!(casual_tx.body(), tx.body()); - assert_eq!(casual_tx.witness_set(), tx.witness_set()); - assert_eq!(casual_tx.is_valid(), tx.is_valid()); - assert_eq!(casual_tx, tx2); - } - - #[test] - fn round_trip_nonstandart_body() { - let original_tx = FixedTransaction::from_hex("84a7009F8258208b9c96823c19f2047f32210a330434b3d163e194ea17b2b702c0667f6fea7a7a00FF0d80018182581d6138fe1dd1d91221a199ff0dacf41fdd5b87506b533d00e70fae8dae8f1abfbac06a021a0002b645031a03962de305a1581de1b3cabd3914ef99169ace1e8b545b635f809caa35f8b6c8bc69ae48061abf4009040e80a100828258207dc05ac55cdfb9cc24571d491d3a3bdbd7d48489a916d27fce3ffe5c9af1b7f55840d7eda8457f1814fe3333b7b1916e3b034e6d480f97f4f286b1443ef72383279718a3a3fddf127dae0505b01a48fd9ffe0f52d9d8c46d02bcb85d1d106c13aa048258201b3d6e1236891a921abf1a3f90a9fb1b2568b1096b6cd6d3eaaeb0ef0ee0802f58401ce4658303c3eb0f2b9705992ccd62de30423ade90219e2c4cfc9eb488c892ea28ba3110f0c062298447f4f6365499d97d31207075f9815c3fe530bd9a927402f5f6").unwrap(); - let casual_tx = Transaction::from_hex("84a7009F8258208b9c96823c19f2047f32210a330434b3d163e194ea17b2b702c0667f6fea7a7a00FF0d80018182581d6138fe1dd1d91221a199ff0dacf41fdd5b87506b533d00e70fae8dae8f1abfbac06a021a0002b645031a03962de305a1581de1b3cabd3914ef99169ace1e8b545b635f809caa35f8b6c8bc69ae48061abf4009040e80a100828258207dc05ac55cdfb9cc24571d491d3a3bdbd7d48489a916d27fce3ffe5c9af1b7f55840d7eda8457f1814fe3333b7b1916e3b034e6d480f97f4f286b1443ef72383279718a3a3fddf127dae0505b01a48fd9ffe0f52d9d8c46d02bcb85d1d106c13aa048258201b3d6e1236891a921abf1a3f90a9fb1b2568b1096b6cd6d3eaaeb0ef0ee0802f58401ce4658303c3eb0f2b9705992ccd62de30423ade90219e2c4cfc9eb488c892ea28ba3110f0c062298447f4f6365499d97d31207075f9815c3fe530bd9a927402f5f6").unwrap(); - let body = hex::decode("a7009F8258208b9c96823c19f2047f32210a330434b3d163e194ea17b2b702c0667f6fea7a7a00FF0d80018182581d6138fe1dd1d91221a199ff0dacf41fdd5b87506b533d00e70fae8dae8f1abfbac06a021a0002b645031a03962de305a1581de1b3cabd3914ef99169ace1e8b545b635f809caa35f8b6c8bc69ae48061abf4009040e80").unwrap(); - let wit_set = hex::decode("a100828258207dc05ac55cdfb9cc24571d491d3a3bdbd7d48489a916d27fce3ffe5c9af1b7f55840d7eda8457f1814fe3333b7b1916e3b034e6d480f97f4f286b1443ef72383279718a3a3fddf127dae0505b01a48fd9ffe0f52d9d8c46d02bcb85d1d106c13aa048258201b3d6e1236891a921abf1a3f90a9fb1b2568b1096b6cd6d3eaaeb0ef0ee0802f58401ce4658303c3eb0f2b9705992ccd62de30423ade90219e2c4cfc9eb488c892ea28ba3110f0c062298447f4f6365499d97d31207075f9815c3fe530bd9a927402").unwrap(); - let tx = FixedTransaction::new(&body, &wit_set, true) - .unwrap(); - let tx2 = Transaction::from_bytes(tx.to_bytes()).unwrap(); - let tx3 = FixedTransaction::from_bytes(tx.to_bytes()).unwrap(); - - assert_eq!(casual_tx.body(), tx.body()); - assert_eq!(casual_tx.witness_set(), tx.witness_set()); - assert_eq!(casual_tx.is_valid(), tx.is_valid()); - - assert_eq!(body, tx3.raw_body()); - assert_eq!(wit_set, tx3.raw_witness_set()); - assert_eq!(tx.raw_body(), tx3.raw_body()); - assert_eq!(tx.raw_witness_set(), tx3.raw_witness_set()); - assert_eq!(tx.is_valid(), tx3.is_valid()); - assert_eq!(tx.to_bytes(), tx3.to_bytes()); - assert_eq!(tx.raw_body(), original_tx.raw_body()); - assert_eq!(tx.raw_witness_set(), original_tx.raw_witness_set()); - assert_eq!(tx.is_valid(), original_tx.is_valid()); - assert_eq!(tx.to_bytes(), original_tx.to_bytes()); - - assert_eq!(casual_tx, tx2); - - assert_ne!(tx2.to_bytes(), original_tx.to_bytes()); - } -} \ No newline at end of file From 41381ac15bc179985f2988ad3289c5d192380881 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 1 Sep 2023 13:53:52 +0500 Subject: [PATCH 115/349] add new mocks --- rust/src/tests/mock_objects.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/mock_objects.rs index 7cccf179..92aadff6 100644 --- a/rust/src/tests/mock_objects.rs +++ b/rust/src/tests/mock_objects.rs @@ -1,3 +1,4 @@ +use crate::fakes::{fake_anchor_data_hash, fake_key_hash, fake_pool_metadata_hash, fake_tx_hash, fake_vrf_key_hash}; use crate::*; pub(crate) fn crate_full_protocol_param_update() -> ProtocolParamUpdate { @@ -44,6 +45,25 @@ pub(crate) fn crate_full_protocol_param_update() -> ProtocolParamUpdate { } } +pub(crate) fn crate_full_pool_params() -> PoolParams { + PoolParams { + operator: fake_key_hash(1), + vrf_keyhash: fake_vrf_key_hash(2), + pledge: Coin::from(44_444u32), + cost: Coin::from(44_444u32), + margin: UnitInterval::new(&BigNum::from(44_444u32), &BigNum::from(44_444u32)), + reward_account: RewardAddress::new(2, &Credential::from_keyhash(&fake_key_hash(3))), + pool_owners: Ed25519KeyHashes(vec![fake_key_hash(4), fake_key_hash(5)]), + relays: Relays(vec![Relay::new_multi_host_name(&MultiHostName::new( + &DNSRecordSRV::new("iohk.io".to_string()).unwrap(), + ))]), + pool_metadata: Some(PoolMetadata::new( + &URL::new("https://iohk.io".to_string()).unwrap(), + &fake_pool_metadata_hash(6), + )), + } +} + pub(crate) fn create_cost_models() -> Costmdls { let mut res = Costmdls::new(); res.insert( @@ -64,3 +84,14 @@ pub(crate) fn create_cost_models() -> Costmdls { ); res } + +pub(crate) fn create_anchor() -> Anchor { + Anchor::new( + &URL::new("https://iohk.io".to_string()).unwrap(), + &fake_anchor_data_hash(1), + ) +} + +pub(crate) fn create_action_id() -> GovernanceActionId { + GovernanceActionId::new(&fake_tx_hash(1), 1) +} \ No newline at end of file From 73301236907ddc76fc3b9dab4ee9a4efb89f5f80 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 1 Sep 2023 13:54:03 +0500 Subject: [PATCH 116/349] update mod files --- rust/src/protocol_types/mod.rs | 5 +---- rust/src/tests/builders/mod.rs | 0 rust/src/tests/mod.rs | 10 ++++++---- rust/src/tests/protocol_types/governance/mod.rs | 2 ++ rust/src/tests/protocol_types/mod.rs | 3 +++ 5 files changed, 12 insertions(+), 8 deletions(-) create mode 100644 rust/src/tests/builders/mod.rs create mode 100644 rust/src/tests/protocol_types/governance/mod.rs create mode 100644 rust/src/tests/protocol_types/mod.rs diff --git a/rust/src/protocol_types/mod.rs b/rust/src/protocol_types/mod.rs index 70def29e..47842485 100644 --- a/rust/src/protocol_types/mod.rs +++ b/rust/src/protocol_types/mod.rs @@ -6,7 +6,4 @@ mod certificates; pub use certificates::*; mod governance; -pub use governance::*; - -#[cfg(test)] -mod tests; \ No newline at end of file +pub use governance::*; \ No newline at end of file diff --git a/rust/src/tests/builders/mod.rs b/rust/src/tests/builders/mod.rs new file mode 100644 index 00000000..e69de29b diff --git a/rust/src/tests/mod.rs b/rust/src/tests/mod.rs index 3142c3fc..2523e697 100644 --- a/rust/src/tests/mod.rs +++ b/rust/src/tests/mod.rs @@ -1,4 +1,6 @@ -pub mod serialization; -pub mod general; -pub mod address; -mod mock_objects; \ No newline at end of file +mod serialization; +mod general; +mod address; +mod mock_objects; +mod protocol_types; +mod builders; \ No newline at end of file diff --git a/rust/src/tests/protocol_types/governance/mod.rs b/rust/src/tests/protocol_types/governance/mod.rs new file mode 100644 index 00000000..4681bb17 --- /dev/null +++ b/rust/src/tests/protocol_types/governance/mod.rs @@ -0,0 +1,2 @@ +mod common; +mod proposals; \ No newline at end of file diff --git a/rust/src/tests/protocol_types/mod.rs b/rust/src/tests/protocol_types/mod.rs new file mode 100644 index 00000000..0e06482b --- /dev/null +++ b/rust/src/tests/protocol_types/mod.rs @@ -0,0 +1,3 @@ +mod fixed_tx; +mod certificates; +mod governance; \ No newline at end of file From 08e356626ca32a8ce03354d943bc8e7513e2f4e7 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 1 Sep 2023 13:56:34 +0500 Subject: [PATCH 117/349] update mod files --- rust/pkg/cardano_serialization_lib.js.flow | 36 ++++++++++++++-------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 6f0c3bfa..7c0a9344 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -315,6 +315,14 @@ declare export var VoterKind: {| +StakingPoolKeyHash: 4, // 4 |}; +/** + */ + +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 +|}; + /** */ @@ -481,14 +489,6 @@ declare export var MIRKind: {| +ToStakeCredentials: 1, // 1 |}; -/** - */ - -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 -|}; - /** */ declare export class Address { @@ -595,7 +595,7 @@ declare export class Anchor { /** * @returns {URL} */ - anchor_url(): URL; + url(): URL; /** * @returns {AnchorDataHash} @@ -3932,6 +3932,11 @@ declare export class GovernanceActionIds { */ static new(): GovernanceActionIds; + /** + * @param {GovernanceActionId} governance_action_id + */ + add(governance_action_id: GovernanceActionId): void; + /** * @param {number} index * @returns {GovernanceActionId | void} @@ -12528,17 +12533,17 @@ declare export class Voter { /** * @returns {Credential | void} */ - to_constitutional_committee_hot_key(): Credential | void; + to_constitutional_committee_hot_cred(): Credential | void; /** * @returns {Credential | void} */ - to_drep(): Credential | void; + to_drep_cred(): Credential | void; /** * @returns {Ed25519KeyHash | void} */ - to_staking_pool(): Ed25519KeyHash | void; + to_staking_pool_key_hash(): Ed25519KeyHash | void; /** * @returns {boolean} @@ -12548,7 +12553,7 @@ declare export class Voter { /** * @returns {Ed25519KeyHash | void} */ - to_keyhash(): Ed25519KeyHash | void; + to_key_hash(): Ed25519KeyHash | void; } /** */ @@ -12576,6 +12581,11 @@ declare export class Voters { */ static new(): Voters; + /** + * @param {Voter} voter + */ + add(voter: Voter): void; + /** * @param {number} index * @returns {Voter | void} From 678240a6434d001b11833387facb228186fedbc6 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 1 Sep 2023 17:43:56 +0500 Subject: [PATCH 118/349] move tests from tx_builder.rs to another file --- rust/src/tests/builders/mod.rs | 2 + rust/src/tests/builders/test_batch.rs | 785 +++ rust/src/tests/builders/tx_builder.rs | 6478 ++++++++++++++++++++++++ rust/src/tests/helpers.rs | 3 + rust/src/tests/mock_objects.rs | 105 +- rust/src/tests/mod.rs | 3 +- rust/src/tx_builder.rs | 6555 +------------------------ rust/src/tx_builder/test_batch.rs | 775 --- 8 files changed, 7407 insertions(+), 7299 deletions(-) create mode 100644 rust/src/tests/builders/test_batch.rs create mode 100644 rust/src/tests/builders/tx_builder.rs create mode 100644 rust/src/tests/helpers.rs delete mode 100644 rust/src/tx_builder/test_batch.rs diff --git a/rust/src/tests/builders/mod.rs b/rust/src/tests/builders/mod.rs index e69de29b..a32f65fc 100644 --- a/rust/src/tests/builders/mod.rs +++ b/rust/src/tests/builders/mod.rs @@ -0,0 +1,2 @@ +mod tx_builder; +mod test_batch; diff --git a/rust/src/tests/builders/test_batch.rs b/rust/src/tests/builders/test_batch.rs new file mode 100644 index 00000000..bc6edb49 --- /dev/null +++ b/rust/src/tests/builders/test_batch.rs @@ -0,0 +1,785 @@ +use crate::fakes::fake_policy_id; +use crate::fees::{min_fee, LinearFee}; +use crate::tx_builder::tx_batch_builder::{create_send_all, TransactionBatchList}; +use crate::tx_builder::{TransactionBuilderConfig, TransactionBuilderConfigBuilder}; +use crate::*; + +fn root_key() -> Bip32PrivateKey { + // art forum devote street sure rather head chuckle guard poverty release quote oak craft enemy + let entropy = [ + 0x0c, 0xcb, 0x74, 0xf3, 0x6b, 0x7d, 0xa1, 0x64, 0x9a, 0x81, 0x44, 0x67, 0x55, 0x22, 0xd4, + 0xd8, 0x09, 0x7c, 0x64, 0x12, + ]; + Bip32PrivateKey::from_bip39_entropy(&entropy, &[]) +} + +fn harden(index: u32) -> u32 { + index | 0x80_00_00_00 +} + +fn generate_address(index: u32) -> Address { + let spend = root_key() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(index) + .to_public(); + let stake = root_key() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ); + addr.to_address() +} + +fn generate_assets( + from_policy: usize, + from_asset: usize, + policies_count: usize, + assets_count: usize, + asset_name_size: usize, + amount_per_asset: Coin, +) -> Option { + let mut assets = MultiAsset::new(); + for i in from_policy..(policies_count + from_policy) { + let policy_id = fake_policy_id(i as u8); + for j in from_asset..(assets_count + from_asset) { + let asset_name = AssetName::new(vec![j as u8; asset_name_size]).unwrap(); + assets.set_asset(&policy_id, &asset_name, amount_per_asset); + } + } + + if assets.0.is_empty() { + None + } else { + Some(assets) + } +} + +fn generate_utxo( + address: &Address, + index: u32, + from_policy: usize, + from_asset: usize, + policies: usize, + assets: usize, + asset_name_size: usize, + amount_per_asset: Coin, + ada: Coin, +) -> TransactionUnspentOutput { + let input = TransactionInput::new( + &TransactionHash::from_bytes( + hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") + .unwrap(), + ) + .unwrap(), + index, + ); + let assets = generate_assets( + from_policy, + from_asset, + policies, + assets, + asset_name_size, + amount_per_asset, + ); + let value = match assets { + Some(assets) => Value::new_with_assets(&ada, &assets), + None => Value::new(&ada), + }; + let output = TransactionOutput::new(&address, &value); + TransactionUnspentOutput::new(&input, &output) +} + +fn generate_big_ada_utoxs_bacth() -> TransactionUnspentOutputs { + let mut utxos = Vec::new(); + let address = generate_address(1); + let address_2 = generate_address(2); + for i in 0..10 { + let utxo = generate_utxo( + &address, + i, + (i / 2) as usize, + (i / 2) as usize, + 5, + 5, + 20, + Coin::from(500u64), + Coin::from(5000u64), + ); + utxos.push(utxo); + } + + for i in 0..10000 { + let utxo = generate_utxo( + &address_2, + i + 1000, + 0, + 0, + 0, + 0, + 20, + Coin::zero(), + Coin::from(5000000u64), + ); + utxos.push(utxo); + } + TransactionUnspentOutputs(utxos) +} + +fn generate_big_utoxs_bacth() -> TransactionUnspentOutputs { + let mut utxos = Vec::new(); + let address = generate_address(1); + let address_2 = generate_address(2); + for i in 0..200 { + let utxo = generate_utxo( + &address, + i, + (i / 2) as usize, + (i / 2) as usize, + 5, + 5, + 20, + Coin::from(500u64), + Coin::from(5000u64), + ); + utxos.push(utxo); + } + + for i in 0..10 { + let utxo = generate_utxo( + &address_2, + i + 1000, + 0, + 0, + 0, + 0, + 20, + Coin::zero(), + Coin::from(50000000u64), + ); + utxos.push(utxo); + } + TransactionUnspentOutputs(utxos) +} + +fn get_utxos_total(utxos: &TransactionUnspentOutputs) -> Value { + let mut total_value = Value::zero(); + for utxo in utxos { + total_value = total_value.checked_add(&utxo.output.amount).unwrap(); + } + + total_value +} + +fn get_batch_total(batches: &TransactionBatchList) -> Value { + let mut total_value = Value::zero(); + for batch in batches { + for tx in batch { + for output in &tx.body.outputs { + total_value = total_value.checked_add(&output.amount).unwrap(); + } + let fee = Value::new(&tx.body.fee); + total_value = total_value.checked_add(&fee).unwrap(); + } + } + + total_value +} + +fn get_tx_fee(tx: &Transaction, cfg: &TransactionBuilderConfig) -> Coin { + min_fee(tx, &cfg.fee_algo).unwrap() +} + +fn get_ada_for_output(output: &TransactionOutput, cfg: &TransactionBuilderConfig) -> Coin { + min_ada_for_output(output, &cfg.data_cost).unwrap() +} + +fn check_balance(utxos: &TransactionUnspentOutputs, batches: &TransactionBatchList) { + let utxos_total = get_utxos_total(utxos); + let batches_total = get_batch_total(batches); + assert_eq!(utxos_total, batches_total); +} + +fn check_min_adas(batches: &TransactionBatchList, cfg: &TransactionBuilderConfig) { + for batch in batches { + for tx in batch { + for output in &tx.body.outputs { + let min_ada = get_ada_for_output(output, cfg); + assert!(output.amount.coin >= min_ada); + } + } + } +} + +fn check_fees(batches: &TransactionBatchList, cfg: &TransactionBuilderConfig) { + for batch in batches { + for tx in batch { + let fee = get_tx_fee(tx, cfg); + assert_eq!(fee, tx.body.fee); + } + } +} + +fn check_value_size_limit(batches: &TransactionBatchList, cfg: &TransactionBuilderConfig) { + for batch in batches { + for tx in batch { + for output in &tx.body.outputs { + let value_size = output.amount().to_bytes().len(); + assert!(value_size <= cfg.max_value_size as usize); + } + } + } +} + +fn check_tx_size_limit(batches: &TransactionBatchList, cfg: &TransactionBuilderConfig) { + for batch in batches { + for tx in batch { + let tx_size = tx.to_bytes().len(); + assert!(tx_size <= cfg.max_tx_size as usize); + } + } +} + +#[test] +pub fn test_big_utoxs_batch() { + let utxos = generate_big_utoxs_bacth(); + let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); + let cfg = TransactionBuilderConfigBuilder::new() + .fee_algo(&linear_fee) + .pool_deposit(&to_bignum(500000000)) + .key_deposit(&to_bignum(2000000)) + .max_value_size(4000) + .max_tx_size(8000) + .coins_per_utxo_word(&to_bignum(34_482)) + .voting_proposal_deposit(&to_bignum(500000000)) + .ex_unit_prices(&ExUnitPrices::new( + &SubCoin::new(&to_bignum(577), &to_bignum(10000)), + &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + )) + .build() + .unwrap(); + + let res = create_send_all(&generate_address(10000), &utxos, &cfg); + assert!(res.is_ok()); + + let batches = res.unwrap(); + check_balance(&utxos, &batches); + check_min_adas(&batches, &cfg); + check_fees(&batches, &cfg); + check_value_size_limit(&batches, &cfg); + check_tx_size_limit(&batches, &cfg); +} + +#[test] +pub fn test_big_utoxs_ada_batch() { + let utxos = generate_big_ada_utoxs_bacth(); + let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); + let cfg = TransactionBuilderConfigBuilder::new() + .fee_algo(&linear_fee) + .pool_deposit(&to_bignum(500000000)) + .key_deposit(&to_bignum(2000000)) + .max_value_size(4000) + .max_tx_size(8000) + .coins_per_utxo_word(&to_bignum(34_482)) + .voting_proposal_deposit(&to_bignum(500000000)) + .ex_unit_prices(&ExUnitPrices::new( + &SubCoin::new(&to_bignum(577), &to_bignum(10000)), + &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + )) + .build() + .unwrap(); + + let res = create_send_all(&generate_address(10000), &utxos, &cfg); + assert!(res.is_ok()); + + let batches = res.unwrap(); + check_balance(&utxos, &batches); + check_min_adas(&batches, &cfg); + check_fees(&batches, &cfg); + check_value_size_limit(&batches, &cfg); + check_tx_size_limit(&batches, &cfg); +} + +#[test] +pub fn test_one_utxo() { + let address = generate_address(1); + let utxo = generate_utxo( + &address, + 1, + 0, + 0, + 3, + 2, + 20, + Coin::from(500u64), + Coin::from(5000000u64), + ); + + let utxos = TransactionUnspentOutputs(vec![utxo]); + + let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); + let cfg = TransactionBuilderConfigBuilder::new() + .fee_algo(&linear_fee) + .pool_deposit(&to_bignum(500000000)) + .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) + .max_value_size(4000) + .max_tx_size(8000) + .voting_proposal_deposit(&to_bignum(500000000)) + .coins_per_utxo_word(&to_bignum(34_482)) + .ex_unit_prices(&ExUnitPrices::new( + &SubCoin::new(&to_bignum(577), &to_bignum(10000)), + &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + )) + .build() + .unwrap(); + + let res = create_send_all(&generate_address(10000), &utxos, &cfg); + assert!(res.is_ok()); + + let batches = res.unwrap(); + check_balance(&utxos, &batches); + check_min_adas(&batches, &cfg); + check_fees(&batches, &cfg); + check_value_size_limit(&batches, &cfg); + check_tx_size_limit(&batches, &cfg); +} + +#[test] +pub fn test_one_utxo_one_asset_per_output() { + let address = generate_address(1); + let utxo_1 = generate_utxo( + &address, + 1, + 0, + 0, + 3, + 1, + 20, + Coin::from(500u64), + Coin::from(5000000u64), + ); + + let utxo_2 = generate_utxo( + &address, + 2, + 1, + 0, + 3, + 1, + 20, + Coin::from(500u64), + Coin::from(5000000u64), + ); + + let utxo_3 = generate_utxo( + &address, + 3, + 2, + 0, + 3, + 1, + 20, + Coin::from(500u64), + Coin::from(5000000u64), + ); + + let utxos = TransactionUnspentOutputs(vec![utxo_1, utxo_2, utxo_3]); + + let linear_fee = LinearFee::new(&to_bignum(1), &to_bignum(0)); + let cfg = TransactionBuilderConfigBuilder::new() + .fee_algo(&linear_fee) + .pool_deposit(&to_bignum(500000000)) + .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) + .max_value_size(80) + .max_tx_size(8000) + .coins_per_utxo_word(&to_bignum(34_482)) + .ex_unit_prices(&ExUnitPrices::new( + &SubCoin::new(&to_bignum(577), &to_bignum(10000)), + &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + )) + .build() + .unwrap(); + + let res = create_send_all(&generate_address(10000), &utxos, &cfg); + assert!(res.is_ok()); + + let batches = res.unwrap(); + + for batch in &batches { + for tx in batch { + for output in &tx.body.outputs() { + assert_eq!(output.amount().multiasset.unwrap().0.len(), 1); + for asset in output.amount().multiasset.unwrap().0.values() { + assert_eq!(asset.len(), 1); + } + } + } + } + + check_balance(&utxos, &batches); + check_min_adas(&batches, &cfg); + check_fees(&batches, &cfg); + check_value_size_limit(&batches, &cfg); + check_tx_size_limit(&batches, &cfg); +} + +#[test] +pub fn test_one_utxo_one_asset_per_tx() { + let address = generate_address(1); + let utxo_1 = generate_utxo( + &address, + 1, + 0, + 0, + 1, + 1, + 20, + Coin::from(500u64), + Coin::from(5000000u64), + ); + + let utxo_2 = generate_utxo( + &address, + 2, + 1, + 0, + 1, + 1, + 20, + Coin::from(500u64), + Coin::from(5000000u64), + ); + + let utxo_3 = generate_utxo( + &address, + 3, + 2, + 0, + 1, + 1, + 20, + Coin::from(500u64), + Coin::from(5000000u64), + ); + + let utxos = TransactionUnspentOutputs(vec![utxo_1, utxo_2, utxo_3]); + + let linear_fee = LinearFee::new(&to_bignum(1), &to_bignum(0)); + let cfg = TransactionBuilderConfigBuilder::new() + .fee_algo(&linear_fee) + .pool_deposit(&to_bignum(500000000)) + .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) + .max_value_size(80) + .max_tx_size(300) + .coins_per_utxo_word(&to_bignum(34_482)) + .ex_unit_prices(&ExUnitPrices::new( + &SubCoin::new(&to_bignum(577), &to_bignum(10000)), + &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + )) + .build() + .unwrap(); + + let res = create_send_all(&generate_address(10000), &utxos, &cfg); + assert!(res.is_ok()); + + let batches = res.unwrap(); + + for batch in &batches { + for tx in batch { + assert_eq!(tx.body.outputs().len(), 1); + for output in &tx.body.outputs() { + assert_eq!(output.amount().multiasset.unwrap().0.len(), 1); + for asset in output.amount().multiasset.unwrap().0.values() { + assert_eq!(asset.len(), 1); + } + } + } + } + + check_balance(&utxos, &batches); + check_min_adas(&batches, &cfg); + check_fees(&batches, &cfg); + check_value_size_limit(&batches, &cfg); + check_tx_size_limit(&batches, &cfg); +} + +#[test] +pub fn test_only_ada_utxo() { + let address = generate_address(1); + let utxo = generate_utxo( + &address, + 1, + 0, + 0, + 0, + 0, + 20, + Coin::zero(), + Coin::from(5000000u64), + ); + + let utxos = TransactionUnspentOutputs(vec![utxo]); + + let linear_fee = LinearFee::new(&to_bignum(1), &to_bignum(0)); + let cfg = TransactionBuilderConfigBuilder::new() + .fee_algo(&linear_fee) + .pool_deposit(&to_bignum(500000000)) + .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) + .max_value_size(4000) + .max_tx_size(8000) + .coins_per_utxo_word(&to_bignum(34_482)) + .ex_unit_prices(&ExUnitPrices::new( + &SubCoin::new(&to_bignum(577), &to_bignum(10000)), + &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + )) + .build() + .unwrap(); + + let res = create_send_all(&generate_address(10000), &utxos, &cfg); + assert!(res.is_ok()); + + let batches = res.unwrap(); + check_balance(&utxos, &batches); + check_min_adas(&batches, &cfg); + check_fees(&batches, &cfg); + check_value_size_limit(&batches, &cfg); + check_tx_size_limit(&batches, &cfg); +} + +#[test] +pub fn test_not_enough_ada() { + let address = generate_address(1); + let utxo = generate_utxo(&address, 1, 0, 0, 0, 0, 20, Coin::zero(), Coin::from(1u64)); + + let utxos = TransactionUnspentOutputs(vec![utxo]); + + let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); + let cfg = TransactionBuilderConfigBuilder::new() + .fee_algo(&linear_fee) + .pool_deposit(&to_bignum(500000000)) + .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) + .max_value_size(4000) + .max_tx_size(8000) + .coins_per_utxo_word(&to_bignum(34_482)) + .ex_unit_prices(&ExUnitPrices::new( + &SubCoin::new(&to_bignum(577), &to_bignum(10000)), + &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + )) + .build() + .unwrap(); + + let res = create_send_all(&generate_address(10000), &utxos, &cfg); + assert!(res.is_err()); +} + +#[test] +pub fn test_value_limit_error() { + let address = generate_address(1); + let utxo = generate_utxo( + &address, + 1, + 0, + 0, + 1, + 1, + 20, + Coin::from(1000000u64), + Coin::from(500000u64), + ); + + let utxos = TransactionUnspentOutputs(vec![utxo]); + + let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); + let cfg = TransactionBuilderConfigBuilder::new() + .fee_algo(&linear_fee) + .pool_deposit(&to_bignum(500000000)) + .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) + .max_value_size(10) + .max_tx_size(8000000) + .coins_per_utxo_word(&to_bignum(34_482)) + .ex_unit_prices(&ExUnitPrices::new( + &SubCoin::new(&to_bignum(577), &to_bignum(10000)), + &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + )) + .build() + .unwrap(); + + let res = create_send_all(&generate_address(10000), &utxos, &cfg); + assert!(res.is_err()); +} + +#[test] +pub fn test_tx_limit_error() { + let address = generate_address(1); + let utxo = generate_utxo( + &address, + 1, + 0, + 0, + 10, + 10, + 20, + Coin::from(1000000u64), + Coin::from(50000000u64), + ); + + let utxos = TransactionUnspentOutputs(vec![utxo]); + + let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); + let cfg = TransactionBuilderConfigBuilder::new() + .fee_algo(&linear_fee) + .pool_deposit(&to_bignum(500000000)) + .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) + .max_value_size(100) + .max_tx_size(2000) + .coins_per_utxo_word(&to_bignum(34_482)) + .ex_unit_prices(&ExUnitPrices::new( + &SubCoin::new(&to_bignum(577), &to_bignum(10000)), + &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + )) + .build() + .unwrap(); + + let res = create_send_all(&generate_address(10000), &utxos, &cfg); + assert!(res.is_err()); +} + +#[test] +pub fn test_no_utxos() { + let utxos = TransactionUnspentOutputs(vec![]); + + let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); + let cfg = TransactionBuilderConfigBuilder::new() + .fee_algo(&linear_fee) + .pool_deposit(&to_bignum(500000000)) + .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) + .max_value_size(10) + .max_tx_size(8000000) + .coins_per_utxo_word(&to_bignum(34_482)) + .ex_unit_prices(&ExUnitPrices::new( + &SubCoin::new(&to_bignum(577), &to_bignum(10000)), + &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + )) + .build() + .unwrap(); + + let res = create_send_all(&generate_address(10000), &utxos, &cfg); + assert!(res.is_ok()); + + let batches = res.unwrap(); + let total_txs = batches.into_iter().fold(0, |acc, batch| acc + batch.len()); + assert_eq!(total_txs, 0); +} + +#[test] +pub fn test_script_input_error() { + let address = Address::from_hex("10798c8ce251c36c15f8bccf3306feae1218fce7503b331e6d92e666aa00efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee164").unwrap(); + let utxo = generate_utxo(&address, 1, 0, 0, 0, 0, 20, Coin::zero(), Coin::from(1u64)); + let utxos = TransactionUnspentOutputs(vec![utxo]); + + let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); + let cfg = TransactionBuilderConfigBuilder::new() + .fee_algo(&linear_fee) + .pool_deposit(&to_bignum(500000000)) + .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) + .max_value_size(10) + .max_tx_size(8000000) + .coins_per_utxo_word(&to_bignum(34_482)) + .ex_unit_prices(&ExUnitPrices::new( + &SubCoin::new(&to_bignum(577), &to_bignum(10000)), + &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + )) + .build() + .unwrap(); + + let res = create_send_all(&generate_address(10000), &utxos, &cfg); + assert!(res.is_err()); +} + +#[test] +pub fn test_two_asset_utxo_one_ada_utxo() { + let address = generate_address(1); + let asset_utxo_1 = generate_utxo( + &address, + 1, + 0, + 0, + 1, + 1, + 8, + Coin::from(1u64), + Coin::from(1344798u64), + ); + + let asset_utxo_2 = generate_utxo( + &address, + 2, + 1, + 1, + 1, + 1, + 8, + Coin::from(1u64), + Coin::from(1344798u64), + ); + + let ada_utxo = generate_utxo( + &address, + 3, + 0, + 0, + 0, + 0, + 20, + Coin::from(1u64), + Coin::from(9967920528u64), + ); + + let utxos = TransactionUnspentOutputs(vec![asset_utxo_1, asset_utxo_2, ada_utxo]); + + let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); + let cfg = TransactionBuilderConfigBuilder::new() + .fee_algo(&linear_fee) + .pool_deposit(&to_bignum(500000000)) + .key_deposit(&to_bignum(2000000)) + .voting_proposal_deposit(&to_bignum(500000000)) + .max_value_size(4000) + .max_tx_size(8000) + .coins_per_utxo_word(&to_bignum(34_482)) + .ex_unit_prices(&ExUnitPrices::new( + &SubCoin::new(&to_bignum(577), &to_bignum(10000)), + &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + )) + .build() + .unwrap(); + + let res = create_send_all(&generate_address(10000), &utxos, &cfg); + assert!(res.is_ok()); + + let batches = res.unwrap(); + check_balance(&utxos, &batches); + check_min_adas(&batches, &cfg); + check_fees(&batches, &cfg); + check_value_size_limit(&batches, &cfg); + check_tx_size_limit(&batches, &cfg); +} diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs new file mode 100644 index 00000000..a43f80cd --- /dev/null +++ b/rust/src/tests/builders/tx_builder.rs @@ -0,0 +1,6478 @@ +use super::*; +use crate::fakes::{ + fake_base_address, fake_bytes_32, fake_data_hash, fake_key_hash, fake_policy_id, + fake_script_hash, fake_tx_hash, fake_tx_input, fake_tx_input2, fake_value, fake_value2, +}; +use crate::tests::helpers::harden; +use crate::tests::mock_objects::{ + byron_address, create_default_tx_builder, create_linear_fee, create_reallistic_tx_builder, + create_tx_builder_with_fee, create_tx_builder_with_fee_and_pure_change, + create_tx_builder_with_fee_and_val_size, create_tx_builder_with_key_deposit, +}; +use crate::tx_builder::certificates_builder::CertificatesBuilder; +use crate::tx_builder::mint_builder::{MintBuilder, MintWitness}; +use crate::output_builder::TransactionOutputBuilder; +use crate::tx_builder::script_structs::{PlutusScriptSource, PlutusWitness, PlutusWitnesses}; +use crate::tx_builder::tx_inputs_builder::{ + InputWithScriptWitness, InputsWithScriptWitness, TxInputsBuilder, +}; +use crate::tx_builder::withdrawals_builder::WithdrawalsBuilder; +use crate::tx_builder::{ + fake_full_tx, fake_private_key, CoinSelectionStrategyCIP2, TransactionBuilder, + TransactionBuilderConfigBuilder, +}; +use crate::tx_builder_constants::TxBuilderConstants; +use crate::*; +use fees::*; +use itertools::Itertools; +use std::collections::{BTreeMap, HashMap, HashSet}; + +const MAX_TX_SIZE: u32 = 8000; + +fn genesis_id() -> TransactionHash { + TransactionHash::from([0u8; TransactionHash::BYTE_COUNT]) +} + +fn root_key_15() -> Bip32PrivateKey { + // art forum devote street sure rather head chuckle guard poverty release quote oak craft enemy + let entropy = [ + 0x0c, 0xcb, 0x74, 0xf3, 0x6b, 0x7d, 0xa1, 0x64, 0x9a, 0x81, 0x44, 0x67, 0x55, 0x22, 0xd4, + 0xd8, 0x09, 0x7c, 0x64, 0x12, + ]; + Bip32PrivateKey::from_bip39_entropy(&entropy, &[]) +} + +#[test] +fn check_fake_private_key() { + let fpk = fake_private_key(); + assert_eq!( + fpk.to_bech32(), + "xprv1hretan5mml3tq2p0twkhq4tz4jvka7m2l94kfr6yghkyfar6m9wppc7h9unw6p65y23kakzct3695rs32z7vaw3r2lg9scmfj8ec5du3ufydu5yuquxcz24jlkjhsc9vsa4ufzge9s00fn398svhacse5su2awrw", + ); + assert_eq!( + fpk.to_public().to_bech32(), + "xpub1eamrnx3pph58yr5l4z2wghjpu2dt2f0rp0zq9qquqa39p52ct0xercjgmegfcpcdsy4t9ld90ps2epmtcjy3jtq77n8z20qe0m3pnfqntgrgj", + ); +} + +#[test] +fn build_tx_with_change() { + let mut tx_builder = create_default_tx_builder(); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + tx_builder.add_key_input( + &spend.to_raw_key().hash(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_net_0) + .next() + .unwrap() + .with_coin(&to_bignum(222)) + .build() + .unwrap(), + ) + .unwrap(); + tx_builder.set_ttl(1000); + + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); + let change_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + let added_change = tx_builder.add_change_if_needed(&change_addr); + assert!(added_change.unwrap()); + assert_eq!(tx_builder.outputs.len(), 2); + assert_eq!( + tx_builder + .get_explicit_input() + .unwrap() + .checked_add(&tx_builder.get_implicit_input().unwrap()) + .unwrap(), + tx_builder + .get_explicit_output() + .unwrap() + .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) + .unwrap() + ); + assert_eq!(tx_builder.full_size().unwrap(), 285); + assert_eq!(tx_builder.output_sizes(), vec![62, 65]); + let _final_tx = tx_builder.build(); // just test that it doesn't throw +} + +#[test] +fn build_tx_with_change_with_datum() { + let mut tx_builder = create_default_tx_builder(); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + tx_builder.add_key_input( + &spend.to_raw_key().hash(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_net_0) + .next() + .unwrap() + .with_coin(&to_bignum(222)) + .build() + .unwrap(), + ) + .unwrap(); + tx_builder.set_ttl(1000); + + let datum_hash = fake_data_hash(20); + let data_option = OutputDatum::new_data_hash(&datum_hash); + let (_, script_hash) = plutus_script_and_hash(15); + let change_cred = Credential::from_scripthash(&script_hash); + let change_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + let added_change = tx_builder.add_change_if_needed_with_datum(&change_addr, &data_option); + assert!(added_change.unwrap()); + assert_eq!(tx_builder.outputs.len(), 2); + assert_eq!( + tx_builder + .get_explicit_input() + .unwrap() + .checked_add(&tx_builder.get_implicit_input().unwrap()) + .unwrap(), + tx_builder + .get_explicit_output() + .unwrap() + .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) + .unwrap() + ); + assert_eq!(tx_builder.full_size().unwrap(), 319); + assert_eq!(tx_builder.output_sizes(), vec![62, 99]); + let _final_tx = tx_builder.build(); // just test that it doesn't throw +} + +#[test] +fn build_tx_without_change() { + let mut tx_builder = create_default_tx_builder(); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + tx_builder.add_key_input( + &spend.to_raw_key().hash(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_net_0) + .next() + .unwrap() + .with_coin(&to_bignum(880_000)) + .build() + .unwrap(), + ) + .unwrap(); + tx_builder.set_ttl(1000); + + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); + let change_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + let added_change = tx_builder.add_change_if_needed(&change_addr); + assert!(!added_change.unwrap()); + assert_eq!(tx_builder.outputs.len(), 1); + assert_eq!( + tx_builder + .get_explicit_input() + .unwrap() + .checked_add(&tx_builder.get_implicit_input().unwrap()) + .unwrap(), + tx_builder + .get_explicit_output() + .unwrap() + .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) + .unwrap() + ); + let _final_tx = tx_builder.build(); // just test that it doesn't throw +} + +#[test] +fn build_tx_with_certs() { + let mut tx_builder = create_tx_builder_with_key_deposit(1_000_000); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + tx_builder.add_key_input( + &spend.to_raw_key().hash(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(5_000_000)), + ); + tx_builder.set_ttl(1000); + + let mut certs = Certificates::new(); + certs.add(&Certificate::new_stake_registration( + &StakeRegistration::new(&stake_cred), + )); + certs.add(&Certificate::new_stake_delegation(&StakeDelegation::new( + &stake_cred, + &stake.to_raw_key().hash(), // in reality, this should be the pool owner's key, not ours + ))); + tx_builder.set_certs(&certs).unwrap(); + + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); + let change_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + tx_builder.add_change_if_needed(&change_addr).unwrap(); + assert_eq!(tx_builder.min_fee().unwrap().to_str(), "214002"); + assert_eq!(tx_builder.get_fee_if_set().unwrap().to_str(), "214002"); + assert_eq!(tx_builder.get_deposit().unwrap().to_str(), "1000000"); + assert_eq!(tx_builder.outputs.len(), 1); + assert_eq!( + tx_builder + .get_explicit_input() + .unwrap() + .checked_add(&tx_builder.get_implicit_input().unwrap()) + .unwrap(), + tx_builder + .get_explicit_output() + .unwrap() + .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) + .unwrap() + .checked_add(&Value::new(&tx_builder.get_deposit().unwrap())) + .unwrap() + ); + let _final_tx = tx_builder.build(); // just test that it doesn't throw +} + +#[test] +fn build_tx_exact_amount() { + // transactions where sum(input) == sum(output) exact should pass + let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 0)); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + tx_builder.add_key_input( + &&spend.to_raw_key().hash(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(222)), + ); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_net_0) + .next() + .unwrap() + .with_coin(&to_bignum(222)) + .build() + .unwrap(), + ) + .unwrap(); + tx_builder.set_ttl(0); + + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); + let change_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + let added_change = tx_builder.add_change_if_needed(&change_addr).unwrap(); + assert_eq!(added_change, false); + let final_tx = tx_builder.build().unwrap(); + assert_eq!(final_tx.outputs().len(), 1); +} + +#[test] +fn build_tx_exact_change() { + // transactions where we have exactly enough ADA to add change should pass + let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 0)); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + tx_builder.add_key_input( + &&spend.to_raw_key().hash(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(700)), + ); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_net_0) + .next() + .unwrap() + .with_coin(&to_bignum(222)) + .build() + .unwrap(), + ) + .unwrap(); + tx_builder.set_ttl(0); + + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); + let change_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + let added_change = tx_builder.add_change_if_needed(&change_addr).unwrap(); + assert_eq!(added_change, true); + let final_tx = tx_builder.build().unwrap(); + assert_eq!(final_tx.outputs().len(), 2); + assert_eq!(final_tx.outputs().get(1).amount().coin().to_str(), "478"); +} + +#[test] +#[should_panic] +fn build_tx_insufficient_deposit() { + // transactions should fail with insufficient fees if a deposit is required + let mut tx_builder = create_tx_builder_with_key_deposit(5); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + tx_builder.add_key_input( + &&spend.to_raw_key().hash(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(5)), + ); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_net_0) + .next() + .unwrap() + .with_coin(&to_bignum(5)) + .build() + .unwrap(), + ) + .unwrap(); + tx_builder.set_ttl(0); + + // add a cert which requires a deposit + let mut certs = Certificates::new(); + certs.add(&Certificate::new_stake_registration( + &StakeRegistration::new(&stake_cred), + )); + tx_builder.set_certs(&certs); + + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); + let change_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + + tx_builder.add_change_if_needed(&change_addr).unwrap(); +} + +#[test] +fn build_tx_with_inputs() { + let mut tx_builder = create_default_tx_builder(); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + + { + assert_eq!( + tx_builder + .fee_for_input( + &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred) + .to_address(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)) + ) + .unwrap() + .to_str(), + "69500" + ); + tx_builder.add_input( + &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + } + tx_builder.add_input( + &BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(), + &TransactionInput::new(&genesis_id(), 1), + &Value::new(&to_bignum(1_000_000)), + ); + tx_builder.add_input( + &PointerAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &Pointer::new_pointer(&to_bignum(0), &to_bignum(0), &to_bignum(0)), + ) + .to_address(), + &TransactionInput::new(&genesis_id(), 2), + &Value::new(&to_bignum(1_000_000)), + ); + tx_builder.add_input( + &ByronAddress::icarus_from_key(&spend, NetworkInfo::testnet().protocol_magic()) + .to_address(), + &TransactionInput::new(&genesis_id(), 3), + &Value::new(&to_bignum(1_000_000)), + ); + + assert_eq!(tx_builder.inputs.len(), 4); +} + +#[test] +fn add_ref_inputs_to_builder() { + let mut tx_builder = create_default_tx_builder(); + + tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 1)); + tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 2)); + tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 3)); + tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 4)); + + assert_eq!(tx_builder.reference_inputs.len(), 4); +} + +#[test] +fn build_tx_with_script_ref() { + let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + + tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 1)); + tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 2)); + tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 3)); + tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 4)); + + tx_builder.add_input( + &PointerAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &Pointer::new_pointer(&to_bignum(0), &to_bignum(0), &to_bignum(0)), + ) + .to_address(), + &TransactionInput::new(&genesis_id(), 2), + &Value::new(&to_bignum(1_000_000)), + ); + + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + + let output_amount = Value::new(&to_bignum(500)); + + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_net_0) + .next() + .unwrap() + .with_value(&output_amount) + .build() + .unwrap(), + ) + .unwrap(); + + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); + let change_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + + let added_change = tx_builder.add_change_if_needed(&change_addr).unwrap(); + assert_eq!(added_change, true); + let final_tx = tx_builder.build().unwrap(); + assert_eq!(final_tx.outputs().len(), 2); + assert_eq!(final_tx.reference_inputs().unwrap().len(), 4); + assert_eq!(final_tx.outputs().get(1).amount().coin(), to_bignum(999499)); +} + +#[test] +fn serialization_tx_body_with_script_ref() { + let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + + tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 1)); + tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 2)); + tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 3)); + tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 4)); + + tx_builder.add_input( + &PointerAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &Pointer::new_pointer(&to_bignum(0), &to_bignum(0), &to_bignum(0)), + ) + .to_address(), + &TransactionInput::new(&genesis_id(), 2), + &Value::new(&to_bignum(1_000_000)), + ); + + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + + let output_amount = Value::new(&to_bignum(500)); + + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_net_0) + .next() + .unwrap() + .with_value(&output_amount) + .build() + .unwrap(), + ) + .unwrap(); + + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); + let change_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + + tx_builder.add_change_if_needed(&change_addr).unwrap(); + let final_tx = tx_builder.build().unwrap(); + + let deser_t = TransactionBody::from_bytes(final_tx.to_bytes()).unwrap(); + + assert_eq!(deser_t.to_bytes(), final_tx.to_bytes()); +} + +#[test] +fn json_serialization_tx_body_with_script_ref() { + let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + + tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 1)); + tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 2)); + tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 3)); + tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 4)); + + tx_builder.add_input( + &PointerAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &Pointer::new_pointer(&to_bignum(0), &to_bignum(0), &to_bignum(0)), + ) + .to_address(), + &TransactionInput::new(&genesis_id(), 2), + &Value::new(&to_bignum(1_000_000)), + ); + + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + + let output_amount = Value::new(&to_bignum(500)); + + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_net_0) + .next() + .unwrap() + .with_value(&output_amount) + .build() + .unwrap(), + ) + .unwrap(); + + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); + let change_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + + tx_builder.add_change_if_needed(&change_addr).unwrap(); + let final_tx = tx_builder.build().unwrap(); + + let json_tx_body = final_tx.to_json().unwrap(); + let deser_t = TransactionBody::from_json(json_tx_body.as_str()).unwrap(); + + assert_eq!(deser_t.to_bytes(), final_tx.to_bytes()); + assert_eq!(deser_t.to_json().unwrap(), final_tx.to_json().unwrap()); +} + +#[test] +fn build_tx_with_mint_all_sent() { + let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + + // Input with 150 coins + tx_builder.add_input( + &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(500)), + ); + + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + + let (min_script, policy_id) = mint_script_and_policy(0); + let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); + let amount = to_bignum(1234); + + // Adding mint of the asset - which should work as an input + tx_builder.add_mint_asset(&min_script, &name, Int::new(&amount)); + + let mut ass = Assets::new(); + ass.insert(&name, &amount); + let mut mass = MultiAsset::new(); + mass.insert(&policy_id, &ass); + + // One coin and the minted asset goes into the output + let mut output_amount = Value::new(&to_bignum(264)); + output_amount.set_multiasset(&mass); + + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_net_0) + .next() + .unwrap() + .with_value(&output_amount) + .build() + .unwrap(), + ) + .unwrap(); + + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); + let change_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + + let added_change = tx_builder.add_change_if_needed(&change_addr).unwrap(); + assert!(added_change); + assert_eq!(tx_builder.outputs.len(), 2); + + // Change must be one remaining coin because fee is one constant coin + let change = tx_builder.outputs.get(1).amount(); + assert_eq!(change.coin(), to_bignum(235)); + assert!(change.multiasset().is_none()); +} + +#[test] +fn build_tx_with_mint_in_change() { + let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + + // Input with 600 coins + tx_builder.add_input( + &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(600)), + ); + + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + + let (min_script, policy_id) = mint_script_and_policy(0); + let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); + + let amount_minted = to_bignum(1000); + let amount_sent = to_bignum(500); + + // Adding mint of the asset - which should work as an input + tx_builder.add_mint_asset(&min_script, &name, Int::new(&amount_minted)); + + let mut ass = Assets::new(); + ass.insert(&name, &amount_sent); + let mut mass = MultiAsset::new(); + mass.insert(&policy_id, &ass); + + // One coin and the minted asset goes into the output + let mut output_amount = Value::new(&to_bignum(300)); + output_amount.set_multiasset(&mass); + + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_net_0) + .next() + .unwrap() + .with_value(&output_amount) + .build() + .unwrap(), + ) + .unwrap(); + + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); + let change_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + + let added_change = tx_builder.add_change_if_needed(&change_addr).unwrap(); + assert!(added_change); + assert_eq!(tx_builder.outputs.len(), 2); + + // Change must be one remaining coin because fee is one constant coin + let change = tx_builder.outputs.get(1).amount(); + assert_eq!(change.coin(), to_bignum(299)); + assert!(change.multiasset().is_some()); + + let change_assets = change.multiasset().unwrap(); + let change_asset = change_assets.get(&policy_id).unwrap(); + assert_eq!( + change_asset.get(&name).unwrap(), + amount_minted.checked_sub(&amount_sent).unwrap(), + ); +} + +#[test] +fn change_with_input_and_mint_not_enough_ada() { + let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(1, 1)); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + + let (min_script, policy_id) = mint_script_and_policy(0); + let asset_name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); + + let amount_minted = to_bignum(1000); + let amount_sent = to_bignum(500); + let amount_input_amount = to_bignum(600); + + let mut asset_input = Assets::new(); + asset_input.insert(&asset_name, &amount_input_amount); + let mut mass_input = MultiAsset::new(); + mass_input.insert(&policy_id, &asset_input); + + // Input with 600 coins + tx_builder.add_input( + &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(600)), + ); + + tx_builder.add_input( + &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), + &TransactionInput::new(&genesis_id(), 1), + &Value::new_with_assets(&to_bignum(1), &mass_input), + ); + + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + + // Adding mint of the asset - which should work as an input + tx_builder.add_mint_asset(&min_script, &asset_name, Int::new(&amount_minted)); + + let mut asset = Assets::new(); + asset.insert(&asset_name, &amount_sent); + let mut mass = MultiAsset::new(); + mass.insert(&policy_id, &asset); + + // One coin and the minted asset goes into the output + let mut output_amount = Value::new(&to_bignum(400)); + output_amount.set_multiasset(&mass); + + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_net_0) + .next() + .unwrap() + .with_value(&output_amount) + .build() + .unwrap(), + ) + .unwrap(); + + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); + let change_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + + let added_change = tx_builder.add_change_if_needed(&change_addr); + assert!(added_change.is_err()); +} + +#[test] +fn change_with_input_and_mint_not_enough_assets() { + let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(1, 1)); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + + let (min_script, policy_id) = mint_script_and_policy(0); + let asset_name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); + + let amount_minted = to_bignum(1000); + let amount_sent = to_bignum(100000); + let amount_input_amount = to_bignum(600); + + let mut asset_input = Assets::new(); + asset_input.insert(&asset_name, &amount_input_amount); + let mut mass_input = MultiAsset::new(); + mass_input.insert(&policy_id, &asset_input); + + // Input with 600 coins + tx_builder.add_input( + &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(100000)), + ); + + tx_builder.add_input( + &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), + &TransactionInput::new(&genesis_id(), 1), + &Value::new_with_assets(&to_bignum(1), &mass_input), + ); + + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + + // Adding mint of the asset - which should work as an input + tx_builder.add_mint_asset(&min_script, &asset_name, Int::new(&amount_minted)); + + let mut asset = Assets::new(); + asset.insert(&asset_name, &amount_sent); + let mut mass = MultiAsset::new(); + mass.insert(&policy_id, &asset); + + // One coin and the minted asset goes into the output + let mut output_amount = Value::new(&to_bignum(400)); + output_amount.set_multiasset(&mass); + + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_net_0) + .next() + .unwrap() + .with_value(&output_amount) + .build() + .unwrap(), + ) + .unwrap(); + + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); + let change_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + + let added_change = tx_builder.add_change_if_needed(&change_addr); + assert!(added_change.is_err()); +} + +#[test] +fn build_tx_with_native_assets_change() { + let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let policy_id = &PolicyID::from([0u8; 28]); + let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); + + let ma_input1 = 100; + let ma_input2 = 200; + let ma_output1 = 60; + + let multiassets = [ma_input1, ma_input2, ma_output1] + .iter() + .map(|input| { + let mut multiasset = MultiAsset::new(); + multiasset.insert(policy_id, &{ + let mut assets = Assets::new(); + assets.insert(&name, &to_bignum(*input)); + assets + }); + multiasset + }) + .collect::>(); + + for (i, (multiasset, ada)) in multiassets + .iter() + .zip([100u64, 1000].iter().cloned().map(to_bignum)) + .enumerate() + { + let mut input_amount = Value::new(&ada); + input_amount.set_multiasset(multiasset); + + tx_builder.add_key_input( + &&spend.to_raw_key().hash(), + &TransactionInput::new(&genesis_id(), i as u32), + &input_amount, + ); + } + + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + + let mut output_amount = Value::new(&to_bignum(500)); + output_amount.set_multiasset(&multiassets[2]); + + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_net_0) + .next() + .unwrap() + .with_value(&output_amount) + .build() + .unwrap(), + ) + .unwrap(); + + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); + let change_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + + let added_change = tx_builder.add_change_if_needed(&change_addr).unwrap(); + assert_eq!(added_change, true); + let final_tx = tx_builder.build().unwrap(); + assert_eq!(final_tx.outputs().len(), 2); + assert_eq!( + final_tx + .outputs() + .get(1) + .amount() + .multiasset() + .unwrap() + .get(policy_id) + .unwrap() + .get(&name) + .unwrap(), + to_bignum(ma_input1 + ma_input2 - ma_output1) + ); + assert_eq!(final_tx.outputs().get(1).amount().coin(), to_bignum(599)); +} + +#[test] +fn build_tx_with_native_assets_change_and_purification() { + let coin_per_utxo_word = to_bignum(8); + // Prefer pure change! + let mut tx_builder = create_tx_builder_with_fee_and_pure_change(&create_linear_fee(0, 1)); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let policy_id = &PolicyID::from([0u8; 28]); + let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); + + let ma_input1 = 100; + let ma_input2 = 200; + let ma_output1 = 60; + + let multiassets = [ma_input1, ma_input2, ma_output1] + .iter() + .map(|input| { + let mut multiasset = MultiAsset::new(); + multiasset.insert(policy_id, &{ + let mut assets = Assets::new(); + assets.insert(&name, &to_bignum(*input)); + assets + }); + multiasset + }) + .collect::>(); + + for (i, (multiasset, ada)) in multiassets + .iter() + .zip([100u64, 1000].iter().cloned().map(to_bignum)) + .enumerate() + { + let mut input_amount = Value::new(&ada); + input_amount.set_multiasset(multiasset); + + tx_builder.add_key_input( + &&spend.to_raw_key().hash(), + &TransactionInput::new(&genesis_id(), i as u32), + &input_amount, + ); + } + + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + + let mut output_amount = Value::new(&to_bignum(600)); + output_amount.set_multiasset(&multiassets[2]); + + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_net_0) + .next() + .unwrap() + .with_value(&output_amount) + .build() + .unwrap(), + ) + .unwrap(); + + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); + let change_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + + let added_change = tx_builder.add_change_if_needed(&change_addr).unwrap(); + assert_eq!(added_change, true); + let final_tx = tx_builder.build().unwrap(); + assert_eq!(final_tx.outputs().len(), 3); + assert_eq!(final_tx.outputs().get(0).amount().coin(), to_bignum(600)); + assert_eq!( + final_tx + .outputs() + .get(1) + .amount() + .multiasset() + .unwrap() + .get(policy_id) + .unwrap() + .get(&name) + .unwrap(), + to_bignum(ma_input1 + ma_input2 - ma_output1) + ); + // The first change output that contains all the tokens contain minimum required Coin + let min_coin_for_dirty_change = min_ada_required( + &final_tx.outputs().get(1).amount(), + false, + &coin_per_utxo_word, + ) + .unwrap(); + assert_eq!( + final_tx.outputs().get(1).amount().coin(), + min_coin_for_dirty_change + ); + assert_eq!(final_tx.outputs().get(2).amount().coin(), to_bignum(236)); + assert_eq!(final_tx.outputs().get(2).amount().multiasset(), None); +} + +#[test] +fn build_tx_with_native_assets_change_and_no_purification_cuz_not_enough_pure_coin() { + // Prefer pure change! + let mut tx_builder = create_tx_builder_with_fee_and_pure_change(&create_linear_fee(1, 1)); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let policy_id = &PolicyID::from([0u8; 28]); + let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); + + let ma_input1 = 100; + let ma_input2 = 200; + let ma_output1 = 60; + + let multiassets = [ma_input1, ma_input2, ma_output1] + .iter() + .map(|input| { + let mut multiasset = MultiAsset::new(); + multiasset.insert(policy_id, &{ + let mut assets = Assets::new(); + assets.insert(&name, &to_bignum(*input)); + assets + }); + multiasset + }) + .collect::>(); + + for (i, (multiasset, ada)) in multiassets + .iter() + .zip([300u64, 900].iter().cloned().map(to_bignum)) + .enumerate() + { + let mut input_amount = Value::new(&ada); + input_amount.set_multiasset(multiasset); + + tx_builder.add_key_input( + &&spend.to_raw_key().hash(), + &TransactionInput::new(&genesis_id(), i as u32), + &input_amount, + ); + } + + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + + let mut output_amount = Value::new(&to_bignum(300)); + output_amount.set_multiasset(&multiassets[2]); + + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_net_0) + .next() + .unwrap() + .with_value(&output_amount) + .build() + .unwrap(), + ) + .unwrap(); + + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); + let change_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + + let added_change = tx_builder.add_change_if_needed(&change_addr).unwrap(); + assert_eq!(added_change, true); + let final_tx = tx_builder.build().unwrap(); + assert_eq!(final_tx.outputs().len(), 2); + assert_eq!(final_tx.outputs().get(0).amount().coin(), to_bignum(300)); + assert_eq!( + final_tx + .outputs() + .get(1) + .amount() + .multiasset() + .unwrap() + .get(policy_id) + .unwrap() + .get(&name) + .unwrap(), + to_bignum(ma_input1 + ma_input2 - ma_output1) + ); + // The single change output contains more Coin then minimal utxo value + // But not enough to cover the additional fee for a separate output + assert_eq!(final_tx.outputs().get(1).amount().coin(), to_bignum(499)); +} + +#[test] +#[should_panic] +fn build_tx_leftover_assets() { + let mut tx_builder = create_default_tx_builder(); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + + // add an input that contains an asset not present in the output + let policy_id = &PolicyID::from([0u8; 28]); + let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); + let mut input_amount = Value::new(&to_bignum(1_000_000)); + let mut input_multiasset = MultiAsset::new(); + input_multiasset.insert(policy_id, &{ + let mut assets = Assets::new(); + assets.insert(&name, &to_bignum(100)); + assets + }); + input_amount.set_multiasset(&input_multiasset); + tx_builder.add_key_input( + &spend.to_raw_key().hash(), + &TransactionInput::new(&genesis_id(), 0), + &input_amount, + ); + + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_net_0) + .next() + .unwrap() + .with_coin(&to_bignum(880_000)) + .build() + .unwrap(), + ) + .unwrap(); + tx_builder.set_ttl(1000); + + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); + let change_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + let added_change = tx_builder.add_change_if_needed(&change_addr); + assert!(!added_change.unwrap()); + assert_eq!(tx_builder.outputs.len(), 1); + assert_eq!( + tx_builder + .get_explicit_input() + .unwrap() + .checked_add(&tx_builder.get_implicit_input().unwrap()) + .unwrap(), + tx_builder + .get_explicit_output() + .unwrap() + .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) + .unwrap() + ); + let _final_tx = tx_builder.build(); // just test that it doesn't throw +} + +#[test] +fn build_tx_burn_less_than_min_ada() { + // with this mainnet value we should end up with a final min_ada_required of just under 1_000_000 + let mut tx_builder = create_reallistic_tx_builder(); + + let output_addr = + ByronAddress::from_base58("Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b") + .unwrap(); + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&output_addr.to_address()) + .next() + .unwrap() + .with_value(&Value::new(&to_bignum(2_000_000))) + .build() + .unwrap(), + ) + .unwrap(); + + tx_builder.add_input( + &ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") + .unwrap() + .to_address(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(2_400_000)), + ); + + tx_builder.set_ttl(1); + + let change_addr = + ByronAddress::from_base58("Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho") + .unwrap(); + let added_change = tx_builder.add_change_if_needed(&change_addr.to_address()); + assert!(!added_change.unwrap()); + assert_eq!(tx_builder.outputs.len(), 1); + assert_eq!( + tx_builder + .get_explicit_input() + .unwrap() + .checked_add(&tx_builder.get_implicit_input().unwrap()) + .unwrap(), + tx_builder + .get_explicit_output() + .unwrap() + .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) + .unwrap() + ); + let _final_tx = tx_builder.build(); // just test that it doesn't throw +} + +#[test] +fn build_tx_burn_empty_assets() { + let mut tx_builder = create_reallistic_tx_builder(); + + let output_addr = + ByronAddress::from_base58("Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b") + .unwrap(); + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&output_addr.to_address()) + .next() + .unwrap() + .with_value(&Value::new(&to_bignum(2_000_000))) + .build() + .unwrap(), + ) + .unwrap(); + + let mut input_value = Value::new(&to_bignum(2_400_000)); + input_value.set_multiasset(&MultiAsset::new()); + tx_builder.add_input( + &ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") + .unwrap() + .to_address(), + &TransactionInput::new(&genesis_id(), 0), + &input_value, + ); + + tx_builder.set_ttl(1); + + let change_addr = + ByronAddress::from_base58("Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho") + .unwrap(); + let added_change = tx_builder.add_change_if_needed(&change_addr.to_address()); + assert!(!added_change.unwrap()); + assert_eq!(tx_builder.outputs.len(), 1); + assert_eq!( + tx_builder + .get_explicit_input() + .unwrap() + .checked_add(&tx_builder.get_implicit_input().unwrap()) + .unwrap() + .coin(), + tx_builder + .get_explicit_output() + .unwrap() + .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) + .unwrap() + .coin() + ); + let _final_tx = tx_builder.build(); // just test that it doesn't throw +} + +#[test] +fn build_tx_no_useless_multiasset() { + let mut tx_builder = create_reallistic_tx_builder(); + + let policy_id = &PolicyID::from([0u8; 28]); + let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); + + // add an output that uses up all the token but leaves ADA + let mut input_amount = Value::new(&to_bignum(5_000_000)); + let mut input_multiasset = MultiAsset::new(); + input_multiasset.insert(policy_id, &{ + let mut assets = Assets::new(); + assets.insert(&name, &to_bignum(100)); + assets + }); + input_amount.set_multiasset(&input_multiasset); + + tx_builder.add_input( + &ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") + .unwrap() + .to_address(), + &TransactionInput::new(&genesis_id(), 0), + &input_amount, + ); + + // add an input that contains an asset & ADA + let mut output_amount = Value::new(&to_bignum(2_000_000)); + let mut output_multiasset = MultiAsset::new(); + output_multiasset.insert(policy_id, &{ + let mut assets = Assets::new(); + assets.insert(&name, &to_bignum(100)); + assets + }); + output_amount.set_multiasset(&output_multiasset); + + let output_addr = + ByronAddress::from_base58("Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b") + .unwrap(); + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&output_addr.to_address()) + .next() + .unwrap() + .with_value(&output_amount) + .build() + .unwrap(), + ) + .unwrap(); + + tx_builder.set_ttl(1); + + let change_addr = + ByronAddress::from_base58("Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho") + .unwrap(); + let added_change = tx_builder.add_change_if_needed(&change_addr.to_address()); + assert!(added_change.unwrap()); + assert_eq!(tx_builder.outputs.len(), 2); + let final_tx = tx_builder.build().unwrap(); + let change_output = final_tx.outputs().get(1); + let change_assets = change_output.amount().multiasset(); + + // since all tokens got sent in the output + // the change should be only ADA and not have any multiasset struct in it + assert!(change_assets.is_none()); +} + +fn create_multiasset() -> (MultiAsset, [ScriptHash; 3], [AssetName; 3]) { + let policy_ids = [fake_policy_id(0), fake_policy_id(1), fake_policy_id(2)]; + let names = [ + AssetName::new(vec![99u8; 32]).unwrap(), + AssetName::new(vec![0u8, 1, 2, 3]).unwrap(), + AssetName::new(vec![4u8, 5, 6, 7, 8, 9]).unwrap(), + ]; + let multiasset = policy_ids.iter().zip(names.iter()).fold( + MultiAsset::new(), + |mut acc, (policy_id, name)| { + acc.insert(policy_id, &{ + let mut assets = Assets::new(); + assets.insert(&name, &to_bignum(500)); + assets + }); + acc + }, + ); + return (multiasset, policy_ids, names); +} + +#[test] +fn build_tx_add_change_split_nfts() { + let max_value_size = 100; // super low max output size to test with fewer assets + let mut tx_builder = + create_tx_builder_with_fee_and_val_size(&create_linear_fee(0, 1), max_value_size); + + let (multiasset, policy_ids, names) = create_multiasset(); + + let mut input_value = Value::new(&to_bignum(1000)); + input_value.set_multiasset(&multiasset); + + tx_builder.add_input( + &ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") + .unwrap() + .to_address(), + &TransactionInput::new(&genesis_id(), 0), + &input_value, + ); + + let output_addr = + ByronAddress::from_base58("Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b") + .unwrap() + .to_address(); + let output_amount = Value::new(&to_bignum(208)); + + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&output_addr) + .next() + .unwrap() + .with_value(&output_amount) + .build() + .unwrap(), + ) + .unwrap(); + + let change_addr = + ByronAddress::from_base58("Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho") + .unwrap() + .to_address(); + + let added_change = tx_builder.add_change_if_needed(&change_addr).unwrap(); + assert_eq!(added_change, true); + let final_tx = tx_builder.build().unwrap(); + assert_eq!(final_tx.outputs().len(), 3); + for (policy_id, asset_name) in policy_ids.iter().zip(names.iter()) { + assert!(final_tx + .outputs + .0 + .iter() + .find(|output| output.amount.multiasset.as_ref().map_or_else( + || false, + |ma| ma + .0 + .iter() + .find(|(pid, a)| *pid == policy_id + && a.0.iter().find(|(name, _)| *name == asset_name).is_some()) + .is_some() + )) + .is_some()); + } + for output in final_tx.outputs.0.iter() { + assert!(output.amount.to_bytes().len() <= max_value_size as usize); + } +} + +#[test] +fn build_tx_too_big_output() { + let mut tx_builder = create_tx_builder_with_fee_and_val_size(&create_linear_fee(0, 1), 10); + + tx_builder.add_input( + &ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") + .unwrap() + .to_address(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(500)), + ); + + let output_addr = + ByronAddress::from_base58("Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b") + .unwrap() + .to_address(); + let mut output_amount = Value::new(&to_bignum(50)); + output_amount.set_multiasset(&create_multiasset().0); + + assert!(tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&output_addr) + .next() + .unwrap() + .with_value(&output_amount) + .build() + .unwrap() + ) + .is_err()); +} + +#[test] +fn build_tx_add_change_nfts_not_enough_ada() { + let mut tx_builder = create_tx_builder_with_fee_and_val_size( + &create_linear_fee(0, 1), + 150, // super low max output size to test with fewer assets + ); + + let policy_ids = [ + PolicyID::from([0u8; 28]), + PolicyID::from([1u8; 28]), + PolicyID::from([2u8; 28]), + ]; + let names = [ + AssetName::new(vec![99u8; 32]).unwrap(), + AssetName::new(vec![0u8, 1, 2, 3]).unwrap(), + AssetName::new(vec![4u8, 5, 6, 7, 8, 9]).unwrap(), + ]; + + let multiasset = policy_ids.iter().zip(names.iter()).fold( + MultiAsset::new(), + |mut acc, (policy_id, name)| { + acc.insert(policy_id, &{ + let mut assets = Assets::new(); + assets.insert(&name, &to_bignum(500)); + assets + }); + acc + }, + ); + + let mut input_value = Value::new(&to_bignum(58)); + input_value.set_multiasset(&multiasset); + + tx_builder.add_input( + &ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") + .unwrap() + .to_address(), + &TransactionInput::new(&genesis_id(), 0), + &input_value, + ); + + let output_addr = + ByronAddress::from_base58("Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b") + .unwrap() + .to_address(); + let output_amount = Value::new(&to_bignum(208)); + + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&output_addr) + .next() + .unwrap() + .with_value(&output_amount) + .build() + .unwrap(), + ) + .unwrap(); + + let change_addr = + ByronAddress::from_base58("Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho") + .unwrap() + .to_address(); + + assert!(tx_builder.add_change_if_needed(&change_addr).is_err()) +} + +fn make_input(input_hash_byte: u8, value: Value) -> TransactionUnspentOutput { + TransactionUnspentOutput::new( + &fake_tx_input(input_hash_byte), + &TransactionOutputBuilder::new() + .with_address( + &Address::from_bech32("addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z") + .unwrap(), + ) + .next() + .unwrap() + .with_value(&value) + .build() + .unwrap(), + ) +} + +#[test] +fn tx_builder_cip2_largest_first_increasing_fees() { + // we have a = 1 to test increasing fees when more inputs are added + let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(1, 0)); + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address( + &Address::from_bech32( + "addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z", + ) + .unwrap(), + ) + .next() + .unwrap() + .with_coin(&to_bignum(9000)) + .build() + .unwrap(), + ) + .unwrap(); + let mut available_inputs = TransactionUnspentOutputs::new(); + available_inputs.add(&make_input(0u8, Value::new(&to_bignum(1200)))); + available_inputs.add(&make_input(1u8, Value::new(&to_bignum(1600)))); + available_inputs.add(&make_input(2u8, Value::new(&to_bignum(6400)))); + available_inputs.add(&make_input(3u8, Value::new(&to_bignum(2400)))); + available_inputs.add(&make_input(4u8, Value::new(&to_bignum(800)))); + tx_builder + .add_inputs_from(&available_inputs, CoinSelectionStrategyCIP2::LargestFirst) + .unwrap(); + let change_addr = + ByronAddress::from_base58("Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho") + .unwrap() + .to_address(); + let change_added = tx_builder.add_change_if_needed(&change_addr).unwrap(); + assert!(change_added); + let tx = tx_builder.build().unwrap(); + // change needed + assert_eq!(2, tx.outputs().len()); + assert_eq!(3, tx.inputs().len()); + // confirm order of only what is necessary + assert_eq!(1u8, tx.inputs().get(0).transaction_id().0[0]); + assert_eq!(2u8, tx.inputs().get(1).transaction_id().0[0]); + assert_eq!(3u8, tx.inputs().get(2).transaction_id().0[0]); +} + +#[test] +fn tx_builder_cip2_largest_first_static_fees() { + // we have a = 0 so we know adding inputs/outputs doesn't change the fee so we can analyze more + let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 0)); + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address( + &Address::from_bech32( + "addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z", + ) + .unwrap(), + ) + .next() + .unwrap() + .with_coin(&to_bignum(1200)) + .build() + .unwrap(), + ) + .unwrap(); + let mut available_inputs = TransactionUnspentOutputs::new(); + available_inputs.add(&make_input(0u8, Value::new(&to_bignum(150)))); + available_inputs.add(&make_input(1u8, Value::new(&to_bignum(200)))); + available_inputs.add(&make_input(2u8, Value::new(&to_bignum(800)))); + available_inputs.add(&make_input(3u8, Value::new(&to_bignum(400)))); + available_inputs.add(&make_input(4u8, Value::new(&to_bignum(100)))); + tx_builder + .add_inputs_from(&available_inputs, CoinSelectionStrategyCIP2::LargestFirst) + .unwrap(); + let change_addr = + ByronAddress::from_base58("Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho") + .unwrap() + .to_address(); + let change_added = tx_builder.add_change_if_needed(&change_addr).unwrap(); + assert!(!change_added); + let tx = tx_builder.build().unwrap(); + // change not needed - should be exact + assert_eq!(1, tx.outputs().len()); + assert_eq!(2, tx.inputs().len()); + // confirm order of only what is necessary + assert_eq!(2u8, tx.inputs().get(0).transaction_id().0[0]); + assert_eq!(3u8, tx.inputs().get(1).transaction_id().0[0]); +} + +#[test] +fn tx_builder_cip2_largest_first_multiasset() { + // we have a = 0 so we know adding inputs/outputs doesn't change the fee so we can analyze more + let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 0)); + let pid1 = PolicyID::from([1u8; 28]); + let pid2 = PolicyID::from([2u8; 28]); + let asset_name1 = AssetName::new(vec![1u8; 8]).unwrap(); + let asset_name2 = AssetName::new(vec![2u8; 11]).unwrap(); + let asset_name3 = AssetName::new(vec![3u8; 9]).unwrap(); + + let mut output_value = Value::new(&to_bignum(415)); + let mut output_ma = MultiAsset::new(); + output_ma.set_asset(&pid1, &asset_name1, to_bignum(5)); + output_ma.set_asset(&pid1, &asset_name2, to_bignum(1)); + output_ma.set_asset(&pid2, &asset_name2, to_bignum(2)); + output_ma.set_asset(&pid2, &asset_name3, to_bignum(4)); + output_value.set_multiasset(&output_ma); + tx_builder + .add_output(&TransactionOutput::new( + &Address::from_bech32("addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z") + .unwrap(), + &output_value, + )) + .unwrap(); + + let mut available_inputs = TransactionUnspentOutputs::new(); + // should not be taken + available_inputs.add(&make_input(0u8, Value::new(&to_bignum(150)))); + + // should not be taken + let mut input1 = make_input(1u8, Value::new(&to_bignum(200))); + let mut ma1 = MultiAsset::new(); + ma1.set_asset(&pid1, &asset_name1, to_bignum(10)); + ma1.set_asset(&pid1, &asset_name2, to_bignum(1)); + ma1.set_asset(&pid2, &asset_name2, to_bignum(2)); + input1.output.amount.set_multiasset(&ma1); + available_inputs.add(&input1); + + // taken first to satisfy pid1:asset_name1 (but also satisfies pid2:asset_name3) + let mut input2 = make_input(2u8, Value::new(&to_bignum(10))); + let mut ma2 = MultiAsset::new(); + ma2.set_asset(&pid1, &asset_name1, to_bignum(20)); + ma2.set_asset(&pid2, &asset_name3, to_bignum(4)); + input2.output.amount.set_multiasset(&ma2); + available_inputs.add(&input2); + + // taken second to satisfy pid1:asset_name2 (but also satisfies pid2:asset_name1) + let mut input3 = make_input(3u8, Value::new(&to_bignum(50))); + let mut ma3 = MultiAsset::new(); + ma3.set_asset(&pid2, &asset_name1, to_bignum(5)); + ma3.set_asset(&pid1, &asset_name2, to_bignum(15)); + input3.output.amount.multiasset = Some(ma3); + available_inputs.add(&input3); + + // should not be taken either + let mut input4 = make_input(4u8, Value::new(&to_bignum(10))); + let mut ma4 = MultiAsset::new(); + ma4.set_asset(&pid1, &asset_name1, to_bignum(10)); + ma4.set_asset(&pid1, &asset_name2, to_bignum(10)); + input4.output.amount.multiasset = Some(ma4); + available_inputs.add(&input4); + + // taken third to satisfy pid2:asset_name_2 + let mut input5 = make_input(5u8, Value::new(&to_bignum(10))); + let mut ma5 = MultiAsset::new(); + ma5.set_asset(&pid1, &asset_name2, to_bignum(10)); + ma5.set_asset(&pid2, &asset_name2, to_bignum(3)); + input5.output.amount.multiasset = Some(ma5); + available_inputs.add(&input5); + + // should be taken to get enough ADA + let input6 = make_input(6u8, Value::new(&to_bignum(900))); + available_inputs.add(&input6); + + // should not be taken + available_inputs.add(&make_input(7u8, Value::new(&to_bignum(100)))); + tx_builder + .add_inputs_from( + &available_inputs, + CoinSelectionStrategyCIP2::LargestFirstMultiAsset, + ) + .unwrap(); + let change_addr = + ByronAddress::from_base58("Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho") + .unwrap() + .to_address(); + let change_added = tx_builder.add_change_if_needed(&change_addr).unwrap(); + assert!(change_added); + let tx = tx_builder.build().unwrap(); + + assert_eq!(2, tx.outputs().len()); + assert_eq!(4, tx.inputs().len()); + // check order expected per-asset + assert_eq!(2u8, tx.inputs().get(0).transaction_id().0[0]); + assert_eq!(3u8, tx.inputs().get(1).transaction_id().0[0]); + assert_eq!(5u8, tx.inputs().get(2).transaction_id().0[0]); + assert_eq!(6u8, tx.inputs().get(3).transaction_id().0[0]); + + let change = tx.outputs().get(1).amount; + assert_eq!(from_bignum(&change.coin), 555); + let change_ma = change.multiasset().unwrap(); + assert_eq!(15, from_bignum(&change_ma.get_asset(&pid1, &asset_name1))); + assert_eq!(24, from_bignum(&change_ma.get_asset(&pid1, &asset_name2))); + assert_eq!(1, from_bignum(&change_ma.get_asset(&pid2, &asset_name2))); + assert_eq!(0, from_bignum(&change_ma.get_asset(&pid2, &asset_name3))); + let expected_input = input2 + .output + .amount + .checked_add(&input3.output.amount) + .unwrap() + .checked_add(&input5.output.amount) + .unwrap() + .checked_add(&input6.output.amount) + .unwrap(); + let expected_change = expected_input.checked_sub(&output_value).unwrap(); + assert_eq!(expected_change, change); +} + +#[test] +fn tx_builder_cip2_random_improve_multiasset() { + let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 0)); + let pid1 = PolicyID::from([1u8; 28]); + let pid2 = PolicyID::from([2u8; 28]); + let asset_name1 = AssetName::new(vec![1u8; 8]).unwrap(); + let asset_name2 = AssetName::new(vec![2u8; 11]).unwrap(); + let asset_name3 = AssetName::new(vec![3u8; 9]).unwrap(); + + let mut output_value = Value::new(&to_bignum(415)); + let mut output_ma = MultiAsset::new(); + output_ma.set_asset(&pid1, &asset_name1, to_bignum(5)); + output_ma.set_asset(&pid1, &asset_name2, to_bignum(1)); + output_ma.set_asset(&pid2, &asset_name2, to_bignum(2)); + output_ma.set_asset(&pid2, &asset_name3, to_bignum(4)); + output_value.set_multiasset(&output_ma); + tx_builder + .add_output(&TransactionOutput::new( + &Address::from_bech32("addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z") + .unwrap(), + &output_value, + )) + .unwrap(); + + let mut available_inputs = TransactionUnspentOutputs::new(); + available_inputs.add(&make_input(0u8, Value::new(&to_bignum(150)))); + + let mut input1 = make_input(1u8, Value::new(&to_bignum(200))); + let mut ma1 = MultiAsset::new(); + ma1.set_asset(&pid1, &asset_name1, to_bignum(10)); + ma1.set_asset(&pid1, &asset_name2, to_bignum(1)); + ma1.set_asset(&pid2, &asset_name2, to_bignum(2)); + input1.output.amount.set_multiasset(&ma1); + available_inputs.add(&input1); + + let mut input2 = make_input(2u8, Value::new(&to_bignum(10))); + let mut ma2 = MultiAsset::new(); + ma2.set_asset(&pid1, &asset_name1, to_bignum(20)); + ma2.set_asset(&pid2, &asset_name3, to_bignum(4)); + input2.output.amount.set_multiasset(&ma2); + available_inputs.add(&input2); + + let mut input3 = make_input(3u8, Value::new(&to_bignum(50))); + let mut ma3 = MultiAsset::new(); + ma3.set_asset(&pid2, &asset_name1, to_bignum(5)); + ma3.set_asset(&pid1, &asset_name2, to_bignum(15)); + input3.output.amount.multiasset = Some(ma3); + available_inputs.add(&input3); + + let mut input4 = make_input(4u8, Value::new(&to_bignum(10))); + let mut ma4 = MultiAsset::new(); + ma4.set_asset(&pid1, &asset_name1, to_bignum(10)); + ma4.set_asset(&pid1, &asset_name2, to_bignum(10)); + input4.output.amount.multiasset = Some(ma4); + available_inputs.add(&input4); + + let mut input5 = make_input(5u8, Value::new(&to_bignum(10))); + let mut ma5 = MultiAsset::new(); + ma5.set_asset(&pid1, &asset_name2, to_bignum(10)); + ma5.set_asset(&pid2, &asset_name2, to_bignum(3)); + input5.output.amount.multiasset = Some(ma5); + available_inputs.add(&input5); + + let input6 = make_input(6u8, Value::new(&to_bignum(1000))); + available_inputs.add(&input6); + available_inputs.add(&make_input(7u8, Value::new(&to_bignum(100)))); + + let mut input8 = make_input(8u8, Value::new(&to_bignum(10))); + let mut ma8 = MultiAsset::new(); + ma8.set_asset(&pid2, &asset_name2, to_bignum(10)); + input8.output.amount.multiasset = Some(ma8); + available_inputs.add(&input8); + + let mut input9 = make_input(9u8, Value::new(&to_bignum(10))); + let mut ma9 = MultiAsset::new(); + ma9.set_asset(&pid2, &asset_name3, to_bignum(10)); + input9.output.amount.multiasset = Some(ma9); + available_inputs.add(&input9); + + tx_builder + .add_inputs_from( + &available_inputs, + CoinSelectionStrategyCIP2::RandomImproveMultiAsset, + ) + .unwrap(); + + let input_for_cover_change = make_input(10u8, Value::new(&to_bignum(1000))); + tx_builder.add_input( + &input_for_cover_change.output.address, + &input_for_cover_change.input, + &input_for_cover_change.output.amount, + ); + + let change_addr = + ByronAddress::from_base58("Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho") + .unwrap() + .to_address(); + let change_added = tx_builder.add_change_if_needed(&change_addr).unwrap(); + assert!(change_added); + let tx = tx_builder.build().unwrap(); + + assert_eq!(2, tx.outputs().len()); + + let input_total = tx_builder.get_explicit_input().unwrap(); + assert!(input_total >= output_value); +} + +#[test] +fn tx_builder_cip2_random_improve() { + // we have a = 1 to test increasing fees when more inputs are added + let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(1, 0)); + const COST: u64 = 10000; + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address( + &Address::from_bech32( + "addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z", + ) + .unwrap(), + ) + .next() + .unwrap() + .with_coin(&to_bignum(COST)) + .build() + .unwrap(), + ) + .unwrap(); + let mut available_inputs = TransactionUnspentOutputs::new(); + available_inputs.add(&make_input(0u8, Value::new(&to_bignum(1500)))); + available_inputs.add(&make_input(1u8, Value::new(&to_bignum(2000)))); + available_inputs.add(&make_input(2u8, Value::new(&to_bignum(8000)))); + available_inputs.add(&make_input(3u8, Value::new(&to_bignum(4000)))); + available_inputs.add(&make_input(4u8, Value::new(&to_bignum(1000)))); + available_inputs.add(&make_input(5u8, Value::new(&to_bignum(2000)))); + available_inputs.add(&make_input(6u8, Value::new(&to_bignum(1500)))); + let add_inputs_res = + tx_builder.add_inputs_from(&available_inputs, CoinSelectionStrategyCIP2::RandomImprove); + assert!(add_inputs_res.is_ok(), "{:?}", add_inputs_res.err()); + let change_addr = + ByronAddress::from_base58("Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho") + .unwrap() + .to_address(); + let add_change_res = tx_builder.add_change_if_needed(&change_addr); + assert!(add_change_res.is_ok(), "{:?}", add_change_res.err()); + let tx_build_res = tx_builder.build(); + assert!(tx_build_res.is_ok(), "{:?}", tx_build_res.err()); + let tx = tx_build_res.unwrap(); + // we need to look up the values to ensure there's enough + let mut input_values = BTreeMap::new(); + for utxo in available_inputs.0.iter() { + input_values.insert(utxo.input.transaction_id(), utxo.output.amount.clone()); + } + let mut encountered = std::collections::HashSet::new(); + let mut input_total = Value::new(&Coin::zero()); + for input in tx.inputs.0.iter() { + let txid = input.transaction_id(); + if !encountered.insert(txid.clone()) { + panic!("Input {:?} duplicated", txid); + } + let value = input_values.get(&txid).unwrap(); + input_total = input_total.checked_add(value).unwrap(); + } + assert!( + input_total + >= Value::new( + &tx_builder + .min_fee() + .unwrap() + .checked_add(&to_bignum(COST)) + .unwrap() + ) + ); +} + +#[test] +fn tx_builder_cip2_random_improve_when_using_all_available_inputs() { + // we have a = 1 to test increasing fees when more inputs are added + let linear_fee = LinearFee::new(&to_bignum(1), &to_bignum(0)); + let cfg = TransactionBuilderConfigBuilder::new() + .fee_algo(&linear_fee) + .pool_deposit(&to_bignum(0)) + .key_deposit(&to_bignum(0)) + .voting_proposal_deposit(&to_bignum(500000000)) + .max_value_size(9999) + .max_tx_size(9999) + .coins_per_utxo_word(&Coin::zero()) + .build() + .unwrap(); + let mut tx_builder = TransactionBuilder::new(&cfg); + const COST: u64 = 1000; + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address( + &Address::from_bech32( + "addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z", + ) + .unwrap(), + ) + .next() + .unwrap() + .with_coin(&to_bignum(COST)) + .build() + .unwrap(), + ) + .unwrap(); + let mut available_inputs = TransactionUnspentOutputs::new(); + available_inputs.add(&make_input(1u8, Value::new(&to_bignum(800)))); + available_inputs.add(&make_input(2u8, Value::new(&to_bignum(800)))); + let add_inputs_res = + tx_builder.add_inputs_from(&available_inputs, CoinSelectionStrategyCIP2::RandomImprove); + assert!(add_inputs_res.is_ok(), "{:?}", add_inputs_res.err()); +} + +#[test] +fn tx_builder_cip2_random_improve_adds_enough_for_fees() { + // we have a = 1 to test increasing fees when more inputs are added + let linear_fee = LinearFee::new(&to_bignum(1), &to_bignum(0)); + let cfg = TransactionBuilderConfigBuilder::new() + .fee_algo(&linear_fee) + .pool_deposit(&to_bignum(0)) + .key_deposit(&to_bignum(0)) + .voting_proposal_deposit(&to_bignum(500000000)) + .max_value_size(9999) + .max_tx_size(9999) + .coins_per_utxo_word(&Coin::zero()) + .build() + .unwrap(); + let mut tx_builder = TransactionBuilder::new(&cfg); + const COST: u64 = 100; + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address( + &Address::from_bech32( + "addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z", + ) + .unwrap(), + ) + .next() + .unwrap() + .with_coin(&to_bignum(COST)) + .build() + .unwrap(), + ) + .unwrap(); + assert_eq!(tx_builder.min_fee().unwrap(), to_bignum(53)); + let mut available_inputs = TransactionUnspentOutputs::new(); + available_inputs.add(&make_input(1u8, Value::new(&to_bignum(150)))); + available_inputs.add(&make_input(2u8, Value::new(&to_bignum(150)))); + available_inputs.add(&make_input(3u8, Value::new(&to_bignum(150)))); + let add_inputs_res = + tx_builder.add_inputs_from(&available_inputs, CoinSelectionStrategyCIP2::RandomImprove); + assert!(add_inputs_res.is_ok(), "{:?}", add_inputs_res.err()); + assert_eq!(tx_builder.min_fee().unwrap(), to_bignum(264)); + let change_addr = + ByronAddress::from_base58("Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho") + .unwrap() + .to_address(); + let add_change_res = tx_builder.add_change_if_needed(&change_addr); + assert!(add_change_res.is_ok(), "{:?}", add_change_res.err()); +} + +#[test] +fn build_tx_pay_to_multisig() { + let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(10, 2)); + let spend = root_key_15() + .derive(harden(1854)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + + tx_builder.add_key_input( + &spend.to_raw_key().hash(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_net_0) + .next() + .unwrap() + .with_coin(&to_bignum(999_000)) + .build() + .unwrap(), + ) + .unwrap(); + tx_builder.set_ttl(1000); + tx_builder.set_fee(&to_bignum(1_000)); + + assert_eq!(tx_builder.outputs.len(), 1); + assert_eq!( + tx_builder + .get_explicit_input() + .unwrap() + .checked_add(&tx_builder.get_implicit_input().unwrap()) + .unwrap(), + tx_builder + .get_explicit_output() + .unwrap() + .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) + .unwrap() + ); + + let _final_tx = tx_builder.build().unwrap(); + let _deser_t = TransactionBody::from_bytes(_final_tx.to_bytes()).unwrap(); + + assert_eq!(_deser_t.to_bytes(), _final_tx.to_bytes()); +} + +fn build_full_tx( + body: &TransactionBody, + witness_set: &TransactionWitnessSet, + auxiliary_data: Option, +) -> Transaction { + return Transaction::new(body, witness_set, auxiliary_data); +} + +#[test] +fn build_tx_multisig_spend_1on1_unsigned() { + let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(10, 2)); + + let spend = root_key_15() //multisig + .derive(harden(1854)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let stake = root_key_15() //multisig + .derive(harden(1854)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); + let addr_multisig = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + let addr_output = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + + tx_builder.add_input( + &addr_multisig, + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_output) + .next() + .unwrap() + .with_coin(&to_bignum(999_000)) + .build() + .unwrap(), + ) + .unwrap(); + tx_builder.set_ttl(1000); + tx_builder.set_fee(&to_bignum(1_000)); + + let mut auxiliary_data = AuxiliaryData::new(); + let mut pubkey_native_scripts = NativeScripts::new(); + let mut oneof_native_scripts = NativeScripts::new(); + + let spending_hash = spend.to_raw_key().hash(); + pubkey_native_scripts.add(&NativeScript::new_script_pubkey(&ScriptPubkey::new( + &spending_hash, + ))); + oneof_native_scripts.add(&NativeScript::new_script_n_of_k(&ScriptNOfK::new( + 1, + &pubkey_native_scripts, + ))); + auxiliary_data.set_native_scripts(&oneof_native_scripts); + tx_builder.set_auxiliary_data(&auxiliary_data); + + assert_eq!(tx_builder.outputs.len(), 1); + assert_eq!( + tx_builder + .get_explicit_input() + .unwrap() + .checked_add(&tx_builder.get_implicit_input().unwrap()) + .unwrap(), + tx_builder + .get_explicit_output() + .unwrap() + .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) + .unwrap() + ); + + let _final_tx = tx_builder.build().unwrap(); + let _deser_t = TransactionBody::from_bytes(_final_tx.to_bytes()).unwrap(); + + assert_eq!(_deser_t.to_bytes(), _final_tx.to_bytes()); + assert_eq!( + _deser_t.auxiliary_data_hash.unwrap(), + utils::hash_auxiliary_data(&auxiliary_data) + ); +} + +#[test] +fn build_tx_multisig_1on1_signed() { + let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(10, 2)); + let spend = root_key_15() + .derive(harden(1854)) //multisig + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1854)) //multisig + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let addr_net_0 = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ) + .to_address(); + tx_builder.add_key_input( + &spend.to_raw_key().hash(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&addr_net_0) + .next() + .unwrap() + .with_coin(&to_bignum(999_000)) + .build() + .unwrap(), + ) + .unwrap(); + tx_builder.set_ttl(1000); + tx_builder.set_fee(&to_bignum(1_000)); + + let mut auxiliary_data = AuxiliaryData::new(); + let mut pubkey_native_scripts = NativeScripts::new(); + let mut oneof_native_scripts = NativeScripts::new(); + + let spending_hash = spend.to_raw_key().hash(); + pubkey_native_scripts.add(&NativeScript::new_script_pubkey(&ScriptPubkey::new( + &spending_hash, + ))); + oneof_native_scripts.add(&NativeScript::new_script_n_of_k(&ScriptNOfK::new( + 1, + &pubkey_native_scripts, + ))); + auxiliary_data.set_native_scripts(&oneof_native_scripts); + tx_builder.set_auxiliary_data(&auxiliary_data); + + let body = tx_builder.build().unwrap(); + + assert_eq!(tx_builder.outputs.len(), 1); + assert_eq!( + tx_builder + .get_explicit_input() + .unwrap() + .checked_add(&tx_builder.get_implicit_input().unwrap()) + .unwrap(), + tx_builder + .get_explicit_output() + .unwrap() + .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) + .unwrap() + ); + + let mut witness_set = TransactionWitnessSet::new(); + let mut vkw = Vkeywitnesses::new(); + vkw.add(&make_vkey_witness( + &hash_transaction(&body), + &PrivateKey::from_normal_bytes( + &hex::decode("c660e50315d76a53d80732efda7630cae8885dfb85c46378684b3c6103e1284a") + .unwrap(), + ) + .unwrap(), + )); + witness_set.set_vkeys(&vkw); + + let _final_tx = build_full_tx(&body, &witness_set, None); + let _deser_t = Transaction::from_bytes(_final_tx.to_bytes()).unwrap(); + assert_eq!(_deser_t.to_bytes(), _final_tx.to_bytes()); + assert_eq!( + _deser_t.body().auxiliary_data_hash.unwrap(), + utils::hash_auxiliary_data(&auxiliary_data) + ); +} + +#[test] +fn add_change_splits_change_into_multiple_outputs_when_nfts_overflow_output_size() { + let linear_fee = LinearFee::new(&to_bignum(0), &to_bignum(1)); + let max_value_size = 100; // super low max output size to test with fewer assets + let mut tx_builder = TransactionBuilder::new( + &TransactionBuilderConfigBuilder::new() + .fee_algo(&linear_fee) + .pool_deposit(&to_bignum(0)) + .key_deposit(&to_bignum(0)) + .voting_proposal_deposit(&to_bignum(500000000)) + .max_value_size(max_value_size) + .max_tx_size(MAX_TX_SIZE) + .coins_per_utxo_word(&to_bignum(8)) + .prefer_pure_change(true) + .build() + .unwrap(), + ); + + let policy_id = PolicyID::from([0u8; 28]); + let names = [ + AssetName::new(vec![99u8; 32]).unwrap(), + AssetName::new(vec![0u8, 1, 2, 3]).unwrap(), + AssetName::new(vec![4u8, 5, 6, 7]).unwrap(), + AssetName::new(vec![5u8, 5, 6, 7]).unwrap(), + AssetName::new(vec![6u8, 5, 6, 7]).unwrap(), + ]; + let assets = names.iter().fold(Assets::new(), |mut a, name| { + a.insert(&name, &to_bignum(500)); + a + }); + let mut multiasset = MultiAsset::new(); + multiasset.insert(&policy_id, &assets); + + let mut input_value = Value::new(&to_bignum(1200)); + input_value.set_multiasset(&multiasset); + + tx_builder.add_input( + &ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") + .unwrap() + .to_address(), + &TransactionInput::new(&genesis_id(), 0), + &input_value, + ); + + let output_addr = + ByronAddress::from_base58("Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b") + .unwrap() + .to_address(); + let output_amount = Value::new(&to_bignum(208)); + + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&output_addr) + .next() + .unwrap() + .with_value(&output_amount) + .build() + .unwrap(), + ) + .unwrap(); + + let change_addr = + ByronAddress::from_base58("Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho") + .unwrap() + .to_address(); + + let add_change_result = tx_builder.add_change_if_needed(&change_addr); + assert!(add_change_result.is_ok()); + assert_eq!(tx_builder.outputs.len(), 4); + + let change1 = tx_builder.outputs.get(1); + let change2 = tx_builder.outputs.get(2); + let change3 = tx_builder.outputs.get(3); + + assert_eq!(change1.address, change_addr); + assert_eq!(change1.address, change2.address); + assert_eq!(change1.address, change3.address); + + assert_eq!(change1.amount.coin, to_bignum(288)); + assert_eq!(change2.amount.coin, to_bignum(293)); + assert_eq!(change3.amount.coin, to_bignum(410)); + + assert!(change1.amount.multiasset.is_some()); + assert!(change2.amount.multiasset.is_some()); + assert!(change3.amount.multiasset.is_none()); // purified + + let masset1 = change1.amount.multiasset.unwrap(); + let masset2 = change2.amount.multiasset.unwrap(); + + assert_eq!(masset1.keys().len(), 1); + assert_eq!(masset1.keys(), masset2.keys()); + + let asset1 = masset1.get(&policy_id).unwrap(); + let asset2 = masset2.get(&policy_id).unwrap(); + assert_eq!(asset1.len(), 4); + assert_eq!(asset2.len(), 1); + + names.iter().for_each(|name| { + let v1 = asset1.get(name); + let v2 = asset2.get(name); + assert_ne!(v1.is_some(), v2.is_some()); + assert_eq!(v1.or(v2).unwrap(), to_bignum(500)); + }); +} + +fn create_json_metadatum_string() -> String { + String::from("{ \"qwe\": 123 }") +} + +fn create_json_metadatum() -> TransactionMetadatum { + encode_json_str_to_metadatum( + create_json_metadatum_string(), + MetadataJsonSchema::NoConversions, + ) + .unwrap() +} + +fn create_aux_with_metadata(metadatum_key: &TransactionMetadatumLabel) -> AuxiliaryData { + let mut metadata = GeneralTransactionMetadata::new(); + metadata.insert(metadatum_key, &create_json_metadatum()); + + let mut aux = AuxiliaryData::new(); + aux.set_metadata(&metadata); + + let mut nats = NativeScripts::new(); + nats.add(&NativeScript::new_timelock_start(&TimelockStart::new(123))); + aux.set_native_scripts(&nats); + + return aux; +} + +fn assert_json_metadatum(dat: &TransactionMetadatum) { + let map = dat.as_map().unwrap(); + assert_eq!(map.len(), 1); + let key = TransactionMetadatum::new_text(String::from("qwe")).unwrap(); + let val = map.get(&key).unwrap(); + assert_eq!(val.as_int().unwrap(), Int::new_i32(123)); +} + +#[test] +fn set_metadata_with_empty_auxiliary() { + let mut tx_builder = create_default_tx_builder(); + + let num = to_bignum(42); + tx_builder.set_metadata(&create_aux_with_metadata(&num).metadata().unwrap()); + + assert!(tx_builder.auxiliary_data.is_some()); + + let aux = tx_builder.auxiliary_data.unwrap(); + assert!(aux.metadata().is_some()); + assert!(aux.native_scripts().is_none()); + assert!(aux.plutus_scripts().is_none()); + + let met = aux.metadata().unwrap(); + + assert_eq!(met.len(), 1); + assert_json_metadatum(&met.get(&num).unwrap()); +} + +#[test] +fn set_metadata_with_existing_auxiliary() { + let mut tx_builder = create_default_tx_builder(); + + let num1 = to_bignum(42); + tx_builder.set_auxiliary_data(&create_aux_with_metadata(&num1)); + + let num2 = to_bignum(84); + tx_builder.set_metadata(&create_aux_with_metadata(&num2).metadata().unwrap()); + + let aux = tx_builder.auxiliary_data.unwrap(); + assert!(aux.metadata().is_some()); + assert!(aux.native_scripts().is_some()); + assert!(aux.plutus_scripts().is_none()); + + let met = aux.metadata().unwrap(); + assert_eq!(met.len(), 1); + assert!(met.get(&num1).is_none()); + assert_json_metadatum(&met.get(&num2).unwrap()); +} + +#[test] +fn add_metadatum_with_empty_auxiliary() { + let mut tx_builder = create_default_tx_builder(); + + let num = to_bignum(42); + tx_builder.add_metadatum(&num, &create_json_metadatum()); + + assert!(tx_builder.auxiliary_data.is_some()); + + let aux = tx_builder.auxiliary_data.unwrap(); + assert!(aux.metadata().is_some()); + assert!(aux.native_scripts().is_none()); + assert!(aux.plutus_scripts().is_none()); + + let met = aux.metadata().unwrap(); + + assert_eq!(met.len(), 1); + assert_json_metadatum(&met.get(&num).unwrap()); +} + +#[test] +fn add_metadatum_with_existing_auxiliary() { + let mut tx_builder = create_default_tx_builder(); + + let num1 = to_bignum(42); + tx_builder.set_auxiliary_data(&create_aux_with_metadata(&num1)); + + let num2 = to_bignum(84); + tx_builder.add_metadatum(&num2, &create_json_metadatum()); + + let aux = tx_builder.auxiliary_data.unwrap(); + assert!(aux.metadata().is_some()); + assert!(aux.native_scripts().is_some()); + assert!(aux.plutus_scripts().is_none()); + + let met = aux.metadata().unwrap(); + assert_eq!(met.len(), 2); + assert_json_metadatum(&met.get(&num1).unwrap()); + assert_json_metadatum(&met.get(&num2).unwrap()); +} + +#[test] +fn add_json_metadatum_with_empty_auxiliary() { + let mut tx_builder = create_default_tx_builder(); + + let num = to_bignum(42); + tx_builder + .add_json_metadatum(&num, create_json_metadatum_string()) + .unwrap(); + + assert!(tx_builder.auxiliary_data.is_some()); + + let aux = tx_builder.auxiliary_data.unwrap(); + assert!(aux.metadata().is_some()); + assert!(aux.native_scripts().is_none()); + assert!(aux.plutus_scripts().is_none()); + + let met = aux.metadata().unwrap(); + + assert_eq!(met.len(), 1); + assert_json_metadatum(&met.get(&num).unwrap()); +} + +#[test] +fn add_json_metadatum_with_existing_auxiliary() { + let mut tx_builder = create_default_tx_builder(); + + let num1 = to_bignum(42); + tx_builder.set_auxiliary_data(&create_aux_with_metadata(&num1)); + + let num2 = to_bignum(84); + tx_builder + .add_json_metadatum(&num2, create_json_metadatum_string()) + .unwrap(); + + let aux = tx_builder.auxiliary_data.unwrap(); + assert!(aux.metadata().is_some()); + assert!(aux.native_scripts().is_some()); + assert!(aux.plutus_scripts().is_none()); + + let met = aux.metadata().unwrap(); + assert_eq!(met.len(), 2); + assert_json_metadatum(&met.get(&num1).unwrap()); + assert_json_metadatum(&met.get(&num2).unwrap()); +} + +fn create_asset_name() -> AssetName { + AssetName::new(vec![0u8, 1, 2, 3]).unwrap() +} + +fn create_mint_asset() -> MintAssets { + MintAssets::new_from_entry(&create_asset_name(), Int::new_i32(1234)) +} + +fn create_assets() -> Assets { + let mut assets = Assets::new(); + assets.insert(&create_asset_name(), &to_bignum(1234)); + return assets; +} + +fn create_mint_with_one_asset(policy_id: &PolicyID) -> Mint { + Mint::new_from_entry(policy_id, &create_mint_asset()) +} + +fn create_multiasset_one_asset(policy_id: &PolicyID) -> MultiAsset { + let mut mint = MultiAsset::new(); + mint.insert(policy_id, &create_assets()); + return mint; +} + +fn assert_mint_asset(mint: &Mint, policy_id: &PolicyID) { + assert!(mint.get(&policy_id).is_some()); + let result_asset = mint.get(&policy_id).unwrap(); + assert_eq!(result_asset.len(), 1); + assert_eq!( + result_asset.get(&create_asset_name()).unwrap(), + Int::new_i32(1234) + ); +} + +fn mint_script_and_policy_and_hash(x: u8) -> (NativeScript, PolicyID, Ed25519KeyHash) { + let hash = fake_key_hash(x); + let mint_script = NativeScript::new_script_pubkey(&ScriptPubkey::new(&hash)); + let policy_id = mint_script.hash(); + (mint_script, policy_id, hash) +} + +fn mint_script_and_policy(x: u8) -> (NativeScript, ScriptHash) { + let (m, p, _) = mint_script_and_policy_and_hash(x); + (m, p) +} + +fn plutus_script_and_hash(x: u8) -> (PlutusScript, ScriptHash) { + let s = PlutusScript::new(fake_bytes_32(x)); + (s.clone(), s.hash()) +} + +#[test] +fn set_mint_asset_with_empty_mint() { + let mut tx_builder = create_default_tx_builder(); + + let (mint_script, policy_id) = mint_script_and_policy(0); + tx_builder.set_mint_asset(&mint_script, &create_mint_asset()); + + assert!(tx_builder.mint.is_some()); + let mint_scripts = tx_builder.mint.as_ref().unwrap().get_native_scripts(); + assert!(mint_scripts.len() > 0); + + let mint = tx_builder.mint.unwrap().build(); + + assert_eq!(mint.len(), 1); + assert_mint_asset(&mint, &policy_id); + + assert_eq!(mint_scripts.len(), 1); + assert_eq!(mint_scripts.get(0), mint_script); +} + +#[test] +fn set_mint_asset_with_existing_mint() { + let mut tx_builder = create_default_tx_builder(); + + let (mint_script1, policy_id1) = mint_script_and_policy(0); + let (mint_script2, policy_id2) = mint_script_and_policy(1); + + tx_builder + .set_mint( + &create_mint_with_one_asset(&policy_id1), + &NativeScripts::from(vec![mint_script1.clone()]), + ) + .unwrap(); + + tx_builder.set_mint_asset(&mint_script2, &create_mint_asset()); + + assert!(tx_builder.mint.is_some()); + let mint_scripts = tx_builder.mint.as_ref().unwrap().get_native_scripts(); + assert!(mint_scripts.len() > 0); + + let mint = tx_builder.mint.unwrap().build(); + + assert_eq!(mint.len(), 2); + assert_mint_asset(&mint, &policy_id1); + assert_mint_asset(&mint, &policy_id2); + + // Only second script is present in the scripts + assert_eq!(mint_scripts.len(), 2); + let actual_scripts = mint_scripts + .0 + .iter() + .cloned() + .collect::>(); + let expected_scripts = vec![mint_script1, mint_script2] + .iter() + .cloned() + .collect::>(); + assert_eq!(actual_scripts, expected_scripts); +} + +#[test] +fn add_mint_asset_with_empty_mint() { + let mut tx_builder = create_default_tx_builder(); + + let (mint_script, policy_id) = mint_script_and_policy(0); + + tx_builder.add_mint_asset(&mint_script, &create_asset_name(), Int::new_i32(1234)); + + assert!(tx_builder.mint.is_some()); + let mint_scripts = tx_builder.mint.as_ref().unwrap().get_native_scripts(); + assert!(mint_scripts.len() > 0); + + let mint = tx_builder.mint.unwrap().build(); + + assert_eq!(mint.len(), 1); + assert_mint_asset(&mint, &policy_id); + + assert_eq!(mint_scripts.len(), 1); + assert_eq!(mint_scripts.get(0), mint_script); +} + +#[test] +fn add_mint_asset_with_existing_mint() { + let mut tx_builder = create_default_tx_builder(); + + let (mint_script1, policy_id1) = mint_script_and_policy(0); + let (mint_script2, policy_id2) = mint_script_and_policy(1); + + tx_builder + .set_mint( + &create_mint_with_one_asset(&policy_id1), + &NativeScripts::from(vec![mint_script1.clone()]), + ) + .unwrap(); + tx_builder.add_mint_asset(&mint_script2, &create_asset_name(), Int::new_i32(1234)); + + assert!(tx_builder.mint.is_some()); + let mint_scripts = tx_builder.mint.as_ref().unwrap().get_native_scripts(); + assert!(mint_scripts.len() > 0); + + let mint = tx_builder.mint.unwrap().build(); + + assert_eq!(mint.len(), 2); + assert_mint_asset(&mint, &policy_id1); + assert_mint_asset(&mint, &policy_id2); + + assert_eq!(mint_scripts.len(), 2); + let actual_scripts = mint_scripts + .0 + .iter() + .cloned() + .collect::>(); + let expected_scripts = vec![mint_script1, mint_script2] + .iter() + .cloned() + .collect::>(); + assert_eq!(actual_scripts, expected_scripts); +} + +#[test] +fn add_output_amount() { + let mut tx_builder = create_default_tx_builder(); + + let policy_id1 = PolicyID::from([0u8; 28]); + let multiasset = create_multiasset_one_asset(&policy_id1); + let mut value = Value::new(&to_bignum(249)); + value.set_multiasset(&multiasset); + + let address = byron_address(); + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&address) + .next() + .unwrap() + .with_value(&value) + .build() + .unwrap(), + ) + .unwrap(); + + assert_eq!(tx_builder.outputs.len(), 1); + let out = tx_builder.outputs.get(0); + + assert_eq!(out.address.to_bytes(), address.to_bytes()); + assert_eq!(out.amount, value); +} + +#[test] +fn add_output_coin() { + let mut tx_builder = create_default_tx_builder(); + + let address = byron_address(); + let coin = to_bignum(208); + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&address) + .next() + .unwrap() + .with_coin(&coin) + .build() + .unwrap(), + ) + .unwrap(); + + assert_eq!(tx_builder.outputs.len(), 1); + let out = tx_builder.outputs.get(0); + + assert_eq!(out.address.to_bytes(), address.to_bytes()); + assert_eq!(out.amount.coin, coin); + assert!(out.amount.multiasset.is_none()); +} + +#[test] +fn add_output_coin_and_multiasset() { + let mut tx_builder = create_default_tx_builder(); + + let policy_id1 = PolicyID::from([0u8; 28]); + let multiasset = create_multiasset_one_asset(&policy_id1); + + let address = byron_address(); + let coin = to_bignum(249); + + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&address) + .next() + .unwrap() + .with_coin_and_asset(&coin, &multiasset) + .build() + .unwrap(), + ) + .unwrap(); + + assert_eq!(tx_builder.outputs.len(), 1); + let out = tx_builder.outputs.get(0); + + assert_eq!(out.address.to_bytes(), address.to_bytes()); + assert_eq!(out.amount.coin, coin); + assert_eq!(out.amount.multiasset.unwrap(), multiasset); +} + +#[test] +fn add_output_asset_and_min_required_coin() { + let mut tx_builder = create_reallistic_tx_builder(); + + let policy_id1 = PolicyID::from([0u8; 28]); + let multiasset = create_multiasset_one_asset(&policy_id1); + + let address = byron_address(); + + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&address) + .next() + .unwrap() + .with_asset_and_min_required_coin_by_utxo_cost( + &multiasset, + &tx_builder.config.utxo_cost(), + ) + .unwrap() + .build() + .unwrap(), + ) + .unwrap(); + + assert_eq!(tx_builder.outputs.len(), 1); + let out = tx_builder.outputs.get(0); + + assert_eq!(out.address.to_bytes(), address.to_bytes()); + assert_eq!(out.amount.multiasset.unwrap(), multiasset); + assert_eq!(out.amount.coin, to_bignum(1146460)); +} + +#[test] +fn add_mint_asset_and_output() { + let mut tx_builder = create_default_tx_builder(); + + let (mint_script0, policy_id0) = mint_script_and_policy(0); + let (mint_script1, policy_id1) = mint_script_and_policy(1); + + let name = create_asset_name(); + let amount = Int::new_i32(1234); + + let address = byron_address(); + let coin = to_bignum(249); + + // Add unrelated mint first to check it is NOT added to output later + tx_builder.add_mint_asset(&mint_script0, &name, amount.clone()); + + tx_builder + .add_mint_asset_and_output( + &mint_script1, + &name, + amount.clone(), + &TransactionOutputBuilder::new() + .with_address(&address) + .next() + .unwrap(), + &coin, + ) + .unwrap(); + + assert!(tx_builder.mint.is_some()); + let mint_scripts = &tx_builder.mint.as_ref().unwrap().get_native_scripts(); + assert!(mint_scripts.len() > 0); + + let mint = &tx_builder.mint.unwrap().build(); + + // Mint contains two entries + assert_eq!(mint.len(), 2); + assert_mint_asset(mint, &policy_id0); + assert_mint_asset(mint, &policy_id1); + + assert_eq!(mint_scripts.len(), 2); + let actual_scripts = mint_scripts + .0 + .iter() + .cloned() + .collect::>(); + let expected_scripts = vec![mint_script0, mint_script1] + .iter() + .cloned() + .collect::>(); + assert_eq!(actual_scripts, expected_scripts); + + // One new output is created + assert_eq!(tx_builder.outputs.len(), 1); + let out = tx_builder.outputs.get(0); + + assert_eq!(out.address.to_bytes(), address.to_bytes()); + assert_eq!(out.amount.coin, coin); + + let multiasset = out.amount.multiasset.unwrap(); + + // Only second mint entry was added to the output + assert_eq!(multiasset.len(), 1); + assert!(multiasset.get(&policy_id0).is_none()); + assert!(multiasset.get(&policy_id1).is_some()); + + let asset = multiasset.get(&policy_id1).unwrap(); + assert_eq!(asset.len(), 1); + assert_eq!(asset.get(&name).unwrap(), to_bignum(1234)); +} + +#[test] +fn add_mint_asset_and_min_required_coin() { + let mut tx_builder = create_reallistic_tx_builder(); + + let (mint_script0, policy_id0) = mint_script_and_policy(0); + let (mint_script1, policy_id1) = mint_script_and_policy(1); + + let name = create_asset_name(); + let amount = Int::new_i32(1234); + + let address = byron_address(); + + // Add unrelated mint first to check it is NOT added to output later + tx_builder.add_mint_asset(&mint_script0, &name, amount.clone()); + + tx_builder + .add_mint_asset_and_output_min_required_coin( + &mint_script1, + &name, + amount.clone(), + &TransactionOutputBuilder::new() + .with_address(&address) + .next() + .unwrap(), + ) + .unwrap(); + + assert!(tx_builder.mint.is_some()); + let mint_scripts = tx_builder.mint.as_ref().unwrap().get_native_scripts(); + assert!(mint_scripts.len() > 0); + + let mint = &tx_builder.mint.unwrap().build(); + + // Mint contains two entries + assert_eq!(mint.len(), 2); + assert_mint_asset(mint, &policy_id0); + assert_mint_asset(mint, &policy_id1); + + assert_eq!(mint_scripts.len(), 2); + let actual_scripts = mint_scripts + .0 + .iter() + .cloned() + .collect::>(); + let expected_scripts = vec![mint_script0, mint_script1] + .iter() + .cloned() + .collect::>(); + assert_eq!(actual_scripts, expected_scripts); + + // One new output is created + assert_eq!(tx_builder.outputs.len(), 1); + let out = tx_builder.outputs.get(0); + + assert_eq!(out.address.to_bytes(), address.to_bytes()); + assert_eq!(out.amount.coin, to_bignum(1146460)); + + let multiasset = out.amount.multiasset.unwrap(); + + // Only second mint entry was added to the output + assert_eq!(multiasset.len(), 1); + assert!(multiasset.get(&policy_id0).is_none()); + assert!(multiasset.get(&policy_id1).is_some()); + + let asset = multiasset.get(&policy_id1).unwrap(); + assert_eq!(asset.len(), 1); + assert_eq!(asset.get(&name).unwrap(), to_bignum(1234)); +} + +#[test] +fn add_mint_includes_witnesses_into_fee_estimation() { + let mut tx_builder = create_reallistic_tx_builder(); + + let hash0 = fake_key_hash(0); + + let (mint_script1, _, hash1) = mint_script_and_policy_and_hash(1); + let (mint_script2, _, _) = mint_script_and_policy_and_hash(2); + let (mint_script3, _, _) = mint_script_and_policy_and_hash(3); + + let name1 = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); + let name2 = AssetName::new(vec![1u8, 1, 2, 3]).unwrap(); + let name3 = AssetName::new(vec![2u8, 1, 2, 3]).unwrap(); + let name4 = AssetName::new(vec![3u8, 1, 2, 3]).unwrap(); + let amount = Int::new_i32(1234); + + // One input from unrelated address + tx_builder.add_key_input( + &hash0, + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(10_000_000)), + ); + + // One input from same address as mint + tx_builder.add_key_input( + &hash1, + &TransactionInput::new(&genesis_id(), 1), + &Value::new(&to_bignum(10_000_000)), + ); + + // Original tx fee now assumes two VKey signatures for two inputs + let original_tx_fee = tx_builder.min_fee().unwrap(); + assert_eq!(original_tx_fee, to_bignum(168361)); + + // Add minting four assets from three different policies + tx_builder.add_mint_asset(&mint_script1, &name1, amount.clone()); + tx_builder.add_mint_asset(&mint_script2, &name2, amount.clone()); + tx_builder.add_mint_asset(&mint_script3, &name3, amount.clone()); + tx_builder.add_mint_asset(&mint_script3, &name4, amount.clone()); + + let mint = tx_builder.get_mint().unwrap(); + let mint_len = mint.to_bytes().len(); + + let mint_scripts = tx_builder.get_witness_set(); + let mint_scripts_len = + mint_scripts.to_bytes().len() - TransactionWitnessSet::new().to_bytes().len(); + + let fee_coefficient = tx_builder.config.fee_algo.coefficient(); + + let raw_mint_fee = fee_coefficient + .checked_mul(&to_bignum(mint_len as u64)) + .unwrap(); + + let raw_mint_script_fee = fee_coefficient + .checked_mul(&to_bignum(mint_scripts_len as u64)) + .unwrap(); + + assert_eq!(raw_mint_fee, to_bignum(5544)); + assert_eq!(raw_mint_script_fee, to_bignum(4312)); + + let new_tx_fee = tx_builder.min_fee().unwrap(); + + let fee_diff_from_adding_mint = new_tx_fee.checked_sub(&original_tx_fee).unwrap(); + + let witness_fee_increase = fee_diff_from_adding_mint + .checked_sub(&raw_mint_fee) + .unwrap() + .checked_sub(&raw_mint_script_fee) + .unwrap(); + + assert_eq!(witness_fee_increase, to_bignum(8932)); + + let fee_increase_bytes = from_bignum(&witness_fee_increase) + .checked_div(from_bignum(&fee_coefficient)) + .unwrap(); + + // Two vkey witnesses 96 bytes each (32 byte pubkey + 64 byte signature) + // Plus 11 bytes overhead for CBOR wrappers + // This is happening because we have three different minting policies + // but the same key-hash from one of them is already also used in inputs + // so no suplicate witness signature is require for that one + assert_eq!(fee_increase_bytes, 203); +} + +#[test] +fn fee_estimation_fails_on_missing_mint_scripts() { + let mut tx_builder = create_reallistic_tx_builder(); + + // No error estimating fee without mint + assert!(tx_builder.min_fee().is_ok()); + + let (mint_script1, policy_id1) = mint_script_and_policy(0); + let (mint_script2, _) = mint_script_and_policy(1); + + let name1 = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); + let amount = Int::new_i32(1234); + + let mut mint = Mint::new(); + mint.insert( + &policy_id1, + &MintAssets::new_from_entry(&name1, amount.clone()), + ); + + tx_builder + .set_mint(&mint, &NativeScripts::from(vec![mint_script1])) + .unwrap(); + + let est1 = tx_builder.min_fee(); + assert!(est1.is_ok()); + + tx_builder.add_mint_asset(&mint_script2, &name1, amount.clone()); + + let est2 = tx_builder.min_fee(); + assert!(est2.is_ok()); + + // Native script assertion has been commented out in `.min_fee` + // Until implemented in a more performant manner + // TODO: these test parts might be returned back when it's done + + // // Remove one mint script + // tx_builder.mint_scripts = + // Some(NativeScripts::from(vec![tx_builder.mint_scripts.unwrap().get(1)])); + // + // // Now two different policies are minted but only one witness script is present + // let est3 = tx_builder.min_fee(); + // assert!(est3.is_err()); + // assert!(est3.err().unwrap().to_string().contains(&format!("{:?}", hex::encode(policy_id1.to_bytes())))); + // + // // Remove all mint scripts + // tx_builder.mint_scripts = Some(NativeScripts::new()); + // + // // Mint exists but no witness scripts at all present + // let est4 = tx_builder.min_fee(); + // assert!(est4.is_err()); + // assert!(est4.err().unwrap().to_string().contains("witness scripts are not provided")); + // + // // Remove all mint scripts + // tx_builder.mint_scripts = None; + // + // // Mint exists but no witness scripts at all present + // let est5 = tx_builder.min_fee(); + // assert!(est5.is_err()); + // assert!(est5.err().unwrap().to_string().contains("witness scripts are not provided")); +} + +#[test] +fn total_input_output_with_mint_and_burn() { + let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + + let (mint_script1, policy_id1) = mint_script_and_policy(0); + let (mint_script2, policy_id2) = mint_script_and_policy(1); + + let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); + + let ma_input1 = 100; + let ma_input2 = 200; + let ma_output1 = 60; + + let multiassets = [ma_input1, ma_input2, ma_output1] + .iter() + .map(|input| { + let mut multiasset = MultiAsset::new(); + multiasset.insert(&policy_id1, &{ + let mut assets = Assets::new(); + assets.insert(&name, &to_bignum(*input)); + assets + }); + multiasset.insert(&policy_id2, &{ + let mut assets = Assets::new(); + assets.insert(&name, &to_bignum(*input)); + assets + }); + multiasset + }) + .collect::>(); + + for (i, (multiasset, ada)) in multiassets + .iter() + .zip([100u64, 100, 100].iter().cloned().map(to_bignum)) + .enumerate() + { + let mut input_amount = Value::new(&ada); + input_amount.set_multiasset(multiasset); + + tx_builder.add_key_input( + &&spend.to_raw_key().hash(), + &TransactionInput::new(&genesis_id(), i as u32), + &input_amount, + ); + } + + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address(&byron_address()) + .next() + .unwrap() + .with_coin(&to_bignum(208)) + .build() + .unwrap(), + ) + .unwrap(); + + let total_input_before_mint = tx_builder.get_total_input().unwrap(); + let total_output_before_mint = tx_builder.get_total_output().unwrap(); + + assert_eq!(total_input_before_mint.coin, to_bignum(300)); + assert_eq!(total_output_before_mint.coin, to_bignum(208)); + let ma1_input = total_input_before_mint.multiasset.unwrap(); + let ma1_output = total_output_before_mint.multiasset; + assert_eq!( + ma1_input.get(&policy_id1).unwrap().get(&name).unwrap(), + to_bignum(360) + ); + assert_eq!( + ma1_input.get(&policy_id2).unwrap().get(&name).unwrap(), + to_bignum(360) + ); + assert!(ma1_output.is_none()); + + // Adding mint + tx_builder.add_mint_asset(&mint_script1, &name, Int::new_i32(40)); + + // Adding burn + tx_builder.add_mint_asset(&mint_script2, &name, Int::new_i32(-40)); + + let total_input_after_mint = tx_builder.get_total_input().unwrap(); + let total_output_after_mint = tx_builder.get_total_output().unwrap(); + + assert_eq!(total_input_after_mint.coin, to_bignum(300)); + assert_eq!(total_output_before_mint.coin, to_bignum(208)); + let ma2_input = total_input_after_mint.multiasset.unwrap(); + let ma2_output = total_output_after_mint.multiasset.unwrap(); + assert_eq!( + ma2_input.get(&policy_id1).unwrap().get(&name).unwrap(), + to_bignum(400) + ); + assert_eq!( + ma2_input.get(&policy_id2).unwrap().get(&name).unwrap(), + to_bignum(360) + ); + assert_eq!( + ma2_output.get(&policy_id2).unwrap().get(&name).unwrap(), + to_bignum(40) + ); +} + +fn create_base_address_from_script_hash(sh: &ScriptHash) -> Address { + BaseAddress::new( + NetworkInfo::testnet().network_id(), + &Credential::from_scripthash(sh), + &Credential::from_keyhash(&fake_key_hash(0)), + ) + .to_address() +} + +#[test] +fn test_set_input_scripts() { + let mut tx_builder = create_reallistic_tx_builder(); + let (script1, hash1) = mint_script_and_policy(0); + let (script2, hash2) = mint_script_and_policy(1); + let (script3, _hash3) = mint_script_and_policy(2); + // Trying to set native scripts to the builder + let rem0 = tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![ + script1.clone(), + script2.clone(), + script3.clone(), + ])); + assert_eq!(rem0, 0); + let missing0 = tx_builder.count_missing_input_scripts(); + assert_eq!(missing0, 0); + // Adding two script inputs using script1 and script2 hashes + tx_builder.add_input( + &create_base_address_from_script_hash(&hash1), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + tx_builder.add_input( + &create_base_address_from_script_hash(&hash2), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + // Setting a non-matching script will not change anything + let rem1 = + tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![script3.clone()])); + assert_eq!(rem1, 2); + let missing1 = tx_builder.count_missing_input_scripts(); + assert_eq!(missing1, 2); + // Setting one of the required scripts leaves one to be required + let rem2 = tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![ + script1.clone(), + script3.clone(), + ])); + assert_eq!(rem2, 1); + let missing2 = tx_builder.count_missing_input_scripts(); + assert_eq!(missing2, 1); + // Setting one non-required script again does not change anything + // But shows the state has changed + let rem3 = + tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![script3.clone()])); + assert_eq!(rem3, 1); + let missing3 = tx_builder.count_missing_input_scripts(); + assert_eq!(missing3, 1); + // Setting two required scripts will show both of them added + // And the remainder required is zero + let rem4 = tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![ + script1.clone(), + script2.clone(), + ])); + assert_eq!(rem4, 0); + let missing4 = tx_builder.count_missing_input_scripts(); + assert_eq!(missing4, 0); + // Setting empty scripts does not change anything + // But shows the state has changed + let rem5 = tx_builder.add_required_native_input_scripts(&NativeScripts::new()); + assert_eq!(rem5, 0); +} + +#[test] +fn test_add_native_script_input() { + let mut tx_builder = create_reallistic_tx_builder(); + let (script1, _hash1) = mint_script_and_policy(0); + let (script2, _hash2) = mint_script_and_policy(1); + let (script3, hash3) = mint_script_and_policy(2); + // Adding two script inputs directly with their witness + tx_builder.add_native_script_input( + &script1, + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + tx_builder.add_native_script_input( + &script2, + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + // Adding one script input indirectly via hash3 address + tx_builder.add_input( + &create_base_address_from_script_hash(&hash3), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + // Checking missing input scripts shows one + // Because first two inputs already have their witness + let missing1 = tx_builder.count_missing_input_scripts(); + assert_eq!(missing1, 1); + // Setting the required script leaves none to be required` + let rem1 = + tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![script3.clone()])); + assert_eq!(rem1, 0); + let missing2 = tx_builder.count_missing_input_scripts(); + assert_eq!(missing2, 0); +} + +fn unsafe_tx_len(b: &TransactionBuilder) -> usize { + b.build_tx_unsafe().unwrap().to_bytes().len() +} + +#[test] +fn test_native_input_scripts_are_added_to_the_witnesses() { + let mut tx_builder = create_reallistic_tx_builder(); + let (script1, _hash1) = mint_script_and_policy(0); + let (script2, hash2) = mint_script_and_policy(1); + tx_builder.set_fee(&to_bignum(42)); + tx_builder.add_native_script_input( + &script1, + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + let tx_len_before_new_script_input = unsafe_tx_len(&tx_builder); + tx_builder.add_input( + &create_base_address_from_script_hash(&hash2), + &TransactionInput::new(&genesis_id(), 1), + &Value::new(&to_bignum(1_000_000)), + ); + let tx_len_after_new_script_input = unsafe_tx_len(&tx_builder); + // Tx size increased cuz input is added even without the witness + assert!(tx_len_after_new_script_input > tx_len_before_new_script_input); + tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![script2.clone()])); + let tx_len_after_adding_script_witness = unsafe_tx_len(&tx_builder); + // Tx size increased cuz the witness is added to the witnesses + assert!(tx_len_after_adding_script_witness > tx_len_after_new_script_input); + tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![ + script1.clone(), + script2.clone(), + ])); + let tx_len_after_adding_script_witness_again = unsafe_tx_len(&tx_builder); + // Tx size did not change because calling to add same witnesses again doesn't change anything + assert!(tx_len_after_adding_script_witness == tx_len_after_adding_script_witness_again); + let tx: Transaction = tx_builder.build_tx_unsafe().unwrap(); + assert!(tx.witness_set.native_scripts.is_some()); + let native_scripts = tx.witness_set.native_scripts.unwrap(); + assert_eq!(native_scripts.len(), 2); + assert_eq!(native_scripts.get(0), script1); + assert_eq!(native_scripts.get(1), script2); +} + +#[test] +fn test_building_with_missing_witness_script_fails() { + let mut tx_builder = create_reallistic_tx_builder(); + let (script1, _hash1) = mint_script_and_policy(0); + let (script2, hash2) = mint_script_and_policy(1); + tx_builder.set_fee(&to_bignum(42)); + // Ok to build before any inputs + assert!(tx_builder.build_tx().is_ok()); + // Adding native script input which adds the witness right away + tx_builder.add_native_script_input( + &script1, + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + // Ok to build when witness is added along with the input + assert!(tx_builder.build_tx().is_ok()); + // Adding script input without the witness + tx_builder.add_input( + &create_base_address_from_script_hash(&hash2), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + // Not ok to build when missing a witness + assert!(tx_builder.build_tx().is_err()); + // Can force to build using unsafe + assert!(tx_builder.build_tx_unsafe().is_ok()); + // Adding the missing witness script + tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![script2.clone()])); + // Ok to build when all witnesses are added + assert!(tx_builder.build_tx().is_ok()); +} + +#[test] +fn test_adding_plutus_script_input() { + let mut tx_builder = create_reallistic_tx_builder(); + let (script1, _) = plutus_script_and_hash(0); + let datum = PlutusData::new_bytes(fake_bytes_32(1)); + let redeemer_datum = PlutusData::new_bytes(fake_bytes_32(2)); + let redeemer = Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(0), + &redeemer_datum, + &ExUnits::new(&to_bignum(1), &to_bignum(2)), + ); + tx_builder.add_plutus_script_input( + &PlutusWitness::new(&script1, &datum, &redeemer), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + tx_builder.set_fee(&to_bignum(42)); + // There are no missing script witnesses + assert_eq!(tx_builder.count_missing_input_scripts(), 0); + let tx: Transaction = tx_builder.build_tx_unsafe().unwrap(); + assert!(tx.witness_set.plutus_scripts.is_some()); + assert_eq!(tx.witness_set.plutus_scripts.unwrap().get(0), script1); + assert!(tx.witness_set.plutus_data.is_some()); + assert_eq!(tx.witness_set.plutus_data.unwrap().get(0), datum); + assert!(tx.witness_set.redeemers.is_some()); + assert_eq!(tx.witness_set.redeemers.unwrap().get(0), redeemer); +} + +#[test] +fn test_adding_plutus_script_witnesses() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(42)); + let (script1, hash1) = plutus_script_and_hash(0); + let (script2, hash2) = plutus_script_and_hash(1); + let (script3, _hash3) = plutus_script_and_hash(3); + let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); + let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); + let redeemer1 = Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(0), + &PlutusData::new_bytes(fake_bytes_32(20)), + &ExUnits::new(&to_bignum(1), &to_bignum(2)), + ); + let redeemer2 = Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(1), + &PlutusData::new_bytes(fake_bytes_32(21)), + &ExUnits::new(&to_bignum(1), &to_bignum(2)), + ); + tx_builder.add_input( + &create_base_address_from_script_hash(&hash1), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + tx_builder.add_input( + &create_base_address_from_script_hash(&hash2), + &TransactionInput::new(&genesis_id(), 1), + &Value::new(&to_bignum(1_000_000)), + ); + // There are TWO missing script witnesses + assert_eq!(tx_builder.count_missing_input_scripts(), 2); + // Calling to add two plutus witnesses, one of which is irrelevant + tx_builder.add_required_plutus_input_scripts(&PlutusWitnesses::from(vec![ + PlutusWitness::new(&script1, &datum1, &redeemer1), + PlutusWitness::new(&script3, &datum2, &redeemer2), + ])); + // There is now ONE missing script witnesses + assert_eq!(tx_builder.count_missing_input_scripts(), 1); + // Calling to add the one remaining relevant plutus witness now + tx_builder.add_required_plutus_input_scripts(&PlutusWitnesses::from(vec![PlutusWitness::new( + &script2, &datum2, &redeemer2, + )])); + // There is now no missing script witnesses + assert_eq!(tx_builder.count_missing_input_scripts(), 0); + let tx: Transaction = tx_builder.build_tx_unsafe().unwrap(); + // Check there are two correct scripts + assert!(tx.witness_set.plutus_scripts.is_some()); + let pscripts = tx.witness_set.plutus_scripts.unwrap(); + assert_eq!(pscripts.len(), 2); + assert_eq!(pscripts.get(0), script1); + assert_eq!(pscripts.get(1), script2); + // Check there are two correct datums + assert!(tx.witness_set.plutus_data.is_some()); + let datums = tx.witness_set.plutus_data.unwrap(); + assert_eq!(datums.len(), 2); + assert_eq!(datums.get(0), datum1); + assert_eq!(datums.get(1), datum2); + // Check there are two correct redeemers + assert!(tx.witness_set.redeemers.is_some()); + let redeems = tx.witness_set.redeemers.unwrap(); + assert_eq!(redeems.len(), 2); + assert_eq!(redeems.get(0), redeemer1); + assert_eq!(redeems.get(1), redeemer2); +} + +fn create_collateral() -> TxInputsBuilder { + let mut collateral_builder = TxInputsBuilder::new(); + collateral_builder.add_input( + &byron_address(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + collateral_builder +} + +#[test] +fn test_existing_plutus_scripts_require_data_hash() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_collateral(&create_collateral()); + let (script1, _) = plutus_script_and_hash(0); + let datum = PlutusData::new_bytes(fake_bytes_32(1)); + let redeemer_datum = PlutusData::new_bytes(fake_bytes_32(2)); + let redeemer = Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(0), + &redeemer_datum, + &ExUnits::new(&to_bignum(1), &to_bignum(2)), + ); + tx_builder.add_plutus_script_input( + &PlutusWitness::new(&script1, &datum, &redeemer), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + + // Using SAFE `.build_tx` + let res = tx_builder.build_tx(); + assert!(res.is_err()); + if let Err(e) = res { + assert!(e.as_string().unwrap().contains("script data hash")); + } + + // Setting script data hash removes the error + tx_builder.set_script_data_hash(&ScriptDataHash::from_bytes(fake_bytes_32(42)).unwrap()); + // Using SAFE `.build_tx` + let res2 = tx_builder.build_tx(); + assert!(res2.is_ok()); + + // Removing script data hash will cause error again + tx_builder.remove_script_data_hash(); + // Using SAFE `.build_tx` + let res3 = tx_builder.build_tx(); + assert!(res3.is_err()); +} + +#[test] +fn test_calc_script_hash_data() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_collateral(&create_collateral()); + + let (script1, _) = plutus_script_and_hash(0); + let datum = PlutusData::new_bytes(fake_bytes_32(1)); + let redeemer_datum = PlutusData::new_bytes(fake_bytes_32(2)); + let redeemer = Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(0), + &redeemer_datum, + &ExUnits::new(&to_bignum(1), &to_bignum(2)), + ); + tx_builder.add_plutus_script_input( + &PlutusWitness::new(&script1, &datum, &redeemer), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + + // Setting script data hash removes the error + tx_builder + .calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()) + .unwrap(); + + // Using SAFE `.build_tx` + let res2 = tx_builder.build_tx(); + assert!(res2.is_ok()); + + let mut used_langs = Languages::new(); + used_langs.add(Language::new_plutus_v1()); + + let data_hash = hash_script_data( + &Redeemers::from(vec![redeemer.clone()]), + &TxBuilderConstants::plutus_default_cost_models().retain_language_versions(&used_langs), + Some(PlutusList::from(vec![datum])), + ); + assert_eq!(tx_builder.script_data_hash.unwrap(), data_hash); +} + +#[test] +fn test_plutus_witness_redeemer_index_auto_changing() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_collateral(&create_collateral()); + let (script1, _) = plutus_script_and_hash(0); + let (script2, _) = plutus_script_and_hash(1); + let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); + let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); + + // Creating redeemers with indexes ZERO + let redeemer1 = Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(0), + &PlutusData::new_bytes(fake_bytes_32(20)), + &ExUnits::new(&to_bignum(1), &to_bignum(2)), + ); + let redeemer2 = Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(0), + &PlutusData::new_bytes(fake_bytes_32(21)), + &ExUnits::new(&to_bignum(1), &to_bignum(2)), + ); + + // Add a regular NON-script input first + tx_builder.add_input( + &byron_address(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + + // Adding two plutus inputs then + // both have redeemers with index ZERO + tx_builder.add_plutus_script_input( + &PlutusWitness::new(&script1, &datum1, &redeemer1), + &TransactionInput::new(&genesis_id(), 1), + &Value::new(&to_bignum(1_000_000)), + ); + tx_builder.add_plutus_script_input( + &PlutusWitness::new(&script2, &datum2, &redeemer2), + &TransactionInput::new(&genesis_id(), 2), + &Value::new(&to_bignum(1_000_000)), + ); + + // Calc the script data hash + tx_builder + .calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()) + .unwrap(); + + let tx: Transaction = tx_builder.build_tx().unwrap(); + assert!(tx.witness_set.redeemers.is_some()); + let redeems = tx.witness_set.redeemers.unwrap(); + assert_eq!(redeems.len(), 2); + + fn compare_redeems(r1: Redeemer, r2: Redeemer) { + assert_eq!(r1.tag(), r2.tag()); + assert_eq!(r1.data(), r2.data()); + assert_eq!(r1.ex_units(), r2.ex_units()); + } + + compare_redeems(redeems.get(0), redeemer1); + compare_redeems(redeems.get(1), redeemer2); + + // Note the redeemers from the result transaction are equal with source redeemers + // In everything EXCEPT the index field, the indexes have changed to 1 and 2 + // To match the position of their corresponding input + assert_eq!(redeems.get(0).index(), to_bignum(1)); + assert_eq!(redeems.get(1).index(), to_bignum(2)); +} + +#[test] +fn test_native_and_plutus_scripts_together() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_collateral(&create_collateral()); + let (pscript1, _) = plutus_script_and_hash(0); + let (pscript2, phash2) = plutus_script_and_hash(1); + let (nscript1, _) = mint_script_and_policy(0); + let (nscript2, nhash2) = mint_script_and_policy(1); + let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); + let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); + // Creating redeemers with indexes ZERO + let redeemer1 = Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(0), + &PlutusData::new_bytes(fake_bytes_32(20)), + &ExUnits::new(&to_bignum(1), &to_bignum(2)), + ); + let redeemer2 = Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(0), + &PlutusData::new_bytes(fake_bytes_32(21)), + &ExUnits::new(&to_bignum(1), &to_bignum(2)), + ); + + // Add one plutus input directly with witness + tx_builder.add_plutus_script_input( + &PlutusWitness::new(&pscript1, &datum1, &redeemer1), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + // Add one native input directly with witness + tx_builder.add_native_script_input( + &nscript1, + &TransactionInput::new(&genesis_id(), 1), + &Value::new(&to_bignum(1_000_000)), + ); + // Add one plutus input generically without witness + tx_builder.add_input( + &create_base_address_from_script_hash(&phash2), + &TransactionInput::new(&genesis_id(), 2), + &Value::new(&to_bignum(1_000_000)), + ); + // Add one native input generically without witness + tx_builder.add_input( + &create_base_address_from_script_hash(&nhash2), + &TransactionInput::new(&genesis_id(), 3), + &Value::new(&to_bignum(1_000_000)), + ); + + // There are two missing script witnesses + assert_eq!(tx_builder.count_missing_input_scripts(), 2); + + let remaining1 = tx_builder.add_required_plutus_input_scripts(&PlutusWitnesses::from(vec![ + PlutusWitness::new(&pscript2, &datum2, &redeemer2), + ])); + + // There is one missing script witness now + assert_eq!(remaining1, 1); + assert_eq!(tx_builder.count_missing_input_scripts(), 1); + + let remaining2 = + tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![nscript2.clone()])); + + // There are no missing script witnesses now + assert_eq!(remaining2, 0); + assert_eq!(tx_builder.count_missing_input_scripts(), 0); + + tx_builder + .calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()) + .unwrap(); + + let tx: Transaction = tx_builder.build_tx().unwrap(); + + let wits = tx.witness_set; + assert!(wits.native_scripts.is_some()); + assert!(wits.plutus_scripts.is_some()); + assert!(wits.plutus_data.is_some()); + assert!(wits.redeemers.is_some()); + + let nscripts = wits.native_scripts.unwrap(); + assert_eq!(nscripts.len(), 2); + assert_eq!(nscripts.get(0), nscript1); + assert_eq!(nscripts.get(1), nscript2); + + let pscripts = wits.plutus_scripts.unwrap(); + assert_eq!(pscripts.len(), 2); + assert_eq!(pscripts.get(0), pscript1); + assert_eq!(pscripts.get(1), pscript2); + + let datums = wits.plutus_data.unwrap(); + assert_eq!(datums.len(), 2); + assert_eq!(datums.get(0), datum1); + assert_eq!(datums.get(1), datum2); + + let redeems = wits.redeemers.unwrap(); + assert_eq!(redeems.len(), 2); + assert_eq!(redeems.get(0), redeemer1); + + // The second plutus input redeemer index has automatically changed to 2 + // because it was added on the third position + assert_eq!(redeems.get(1), redeemer2.clone_with_index(&to_bignum(2))); +} + +#[test] +fn test_json_serialization_native_and_plutus_scripts_together() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_collateral(&create_collateral()); + let (pscript1, _) = plutus_script_and_hash(0); + let (pscript2, phash2) = plutus_script_and_hash(1); + let (nscript1, _) = mint_script_and_policy(0); + let (nscript2, nhash2) = mint_script_and_policy(1); + let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); + let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); + // Creating redeemers with indexes ZERO + let redeemer1 = Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(0), + &PlutusData::new_bytes(fake_bytes_32(20)), + &ExUnits::new(&to_bignum(1), &to_bignum(2)), + ); + let redeemer2 = Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(0), + &PlutusData::new_bytes(fake_bytes_32(21)), + &ExUnits::new(&to_bignum(1), &to_bignum(2)), + ); + + // Add one plutus input directly with witness + tx_builder.add_plutus_script_input( + &PlutusWitness::new(&pscript1, &datum1, &redeemer1), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + // Add one native input directly with witness + tx_builder.add_native_script_input( + &nscript1, + &TransactionInput::new(&genesis_id(), 1), + &Value::new(&to_bignum(1_000_000)), + ); + // Add one plutus input generically without witness + tx_builder.add_input( + &create_base_address_from_script_hash(&phash2), + &TransactionInput::new(&genesis_id(), 2), + &Value::new(&to_bignum(1_000_000)), + ); + // Add one native input generically without witness + tx_builder.add_input( + &create_base_address_from_script_hash(&nhash2), + &TransactionInput::new(&genesis_id(), 3), + &Value::new(&to_bignum(1_000_000)), + ); + + // There are two missing script witnesses + assert_eq!(tx_builder.count_missing_input_scripts(), 2); + + let remaining1 = tx_builder.add_required_plutus_input_scripts(&PlutusWitnesses::from(vec![ + PlutusWitness::new(&pscript2, &datum2, &redeemer2), + ])); + + // There is one missing script witness now + assert_eq!(remaining1, 1); + assert_eq!(tx_builder.count_missing_input_scripts(), 1); + + let remaining2 = + tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![nscript2.clone()])); + + // There are no missing script witnesses now + assert_eq!(remaining2, 0); + assert_eq!(tx_builder.count_missing_input_scripts(), 0); + + tx_builder.calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()); + + let tx: Transaction = tx_builder.build_tx().unwrap(); + + let json_tx = tx.to_json().unwrap(); + let deser_tx = Transaction::from_json(json_tx.as_str()).unwrap(); + + assert_eq!(deser_tx.to_bytes(), tx.to_bytes()); + assert_eq!(deser_tx.to_json().unwrap(), tx.to_json().unwrap()); +} + +#[test] +fn test_regular_and_collateral_inputs_same_keyhash() { + let mut input_builder = TxInputsBuilder::new(); + let mut collateral_builder = TxInputsBuilder::new(); + + // Add a single input of both kinds with the SAME keyhash + input_builder.add_input( + &fake_base_address(0), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + collateral_builder.add_input( + &fake_base_address(0), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + + fn get_fake_vkeys_count(i: &TxInputsBuilder, c: &TxInputsBuilder) -> usize { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_inputs(i); + tx_builder.set_collateral(c); + let tx: Transaction = fake_full_tx(&tx_builder, tx_builder.build().unwrap()).unwrap(); + tx.witness_set.vkeys.unwrap().len() + } + + // There's only one fake witness in the builder + // because a regular and a collateral inputs both use the same keyhash + assert_eq!(get_fake_vkeys_count(&input_builder, &collateral_builder), 1); + + // Add a new input of each kind with DIFFERENT keyhashes + input_builder.add_input( + &fake_base_address(1), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + collateral_builder.add_input( + &fake_base_address(2), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + + // There are now three fake witnesses in the builder + // because all three unique keyhashes got combined + assert_eq!(get_fake_vkeys_count(&input_builder, &collateral_builder), 3); +} + +#[test] +fn test_regular_and_collateral_inputs_together() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(42)); + let (pscript1, _) = plutus_script_and_hash(0); + let (pscript2, _) = plutus_script_and_hash(1); + let (nscript1, _) = mint_script_and_policy(0); + let (nscript2, _) = mint_script_and_policy(1); + let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); + let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); + // Creating redeemers with indexes ZERO + let redeemer1 = Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(0), + &PlutusData::new_bytes(fake_bytes_32(20)), + &ExUnits::new(&to_bignum(1), &to_bignum(2)), + ); + let redeemer2 = Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(0), + &PlutusData::new_bytes(fake_bytes_32(21)), + &ExUnits::new(&to_bignum(1), &to_bignum(2)), + ); + + let mut input_builder = TxInputsBuilder::new(); + let mut collateral_builder = TxInputsBuilder::new(); + + input_builder.add_native_script_input( + &nscript1, + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + collateral_builder.add_native_script_input( + &nscript2, + &TransactionInput::new(&genesis_id(), 1), + &Value::new(&to_bignum(1_000_000)), + ); + + input_builder.add_plutus_script_input( + &PlutusWitness::new(&pscript1, &datum1, &redeemer1), + &TransactionInput::new(&genesis_id(), 2), + &Value::new(&to_bignum(1_000_000)), + ); + collateral_builder.add_plutus_script_input( + &PlutusWitness::new(&pscript2, &datum2, &redeemer2), + &TransactionInput::new(&genesis_id(), 3), + &Value::new(&to_bignum(1_000_000)), + ); + + tx_builder.set_inputs(&input_builder); + tx_builder.set_collateral(&collateral_builder); + + tx_builder + .calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()) + .unwrap(); + + let w: &TransactionWitnessSet = &tx_builder.build_tx().unwrap().witness_set; + + assert!(w.native_scripts.is_some()); + let nscripts = w.native_scripts.as_ref().unwrap(); + assert_eq!(nscripts.len(), 2); + assert_eq!(nscripts.get(0), nscript1); + assert_eq!(nscripts.get(1), nscript2); + + assert!(w.plutus_scripts.is_some()); + let pscripts = w.plutus_scripts.as_ref().unwrap(); + assert_eq!(pscripts.len(), 2); + assert_eq!(pscripts.get(0), pscript1); + assert_eq!(pscripts.get(1), pscript2); + + assert!(w.plutus_data.is_some()); + let datums = w.plutus_data.as_ref().unwrap(); + assert_eq!(datums.len(), 2); + assert_eq!(datums.get(0), datum1); + assert_eq!(datums.get(1), datum2); + + assert!(w.redeemers.is_some()); + let redeemers = w.redeemers.as_ref().unwrap(); + assert_eq!(redeemers.len(), 2); + assert_eq!(redeemers.get(0), redeemer1.clone_with_index(&to_bignum(1))); + assert_eq!(redeemers.get(1), redeemer2.clone_with_index(&to_bignum(1))); +} + +#[test] +fn test_ex_unit_costs_are_added_to_the_fees() { + fn calc_fee_with_ex_units(mem: u64, step: u64) -> Coin { + let mut input_builder = TxInputsBuilder::new(); + let mut collateral_builder = TxInputsBuilder::new(); + + // Add a single input of both kinds with the SAME keyhash + input_builder.add_input( + &fake_base_address(0), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + collateral_builder.add_input( + &fake_base_address(0), + &TransactionInput::new(&genesis_id(), 1), + &Value::new(&to_bignum(1_000_000)), + ); + + let (pscript1, _) = plutus_script_and_hash(0); + let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); + let redeemer1 = Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(0), + &PlutusData::new_bytes(fake_bytes_32(20)), + &ExUnits::new(&to_bignum(mem), &to_bignum(step)), + ); + input_builder.add_plutus_script_input( + &PlutusWitness::new(&pscript1, &datum1, &redeemer1), + &TransactionInput::new(&genesis_id(), 2), + &Value::new(&to_bignum(1_000_000)), + ); + + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_inputs(&input_builder); + tx_builder.set_collateral(&collateral_builder); + + tx_builder + .add_change_if_needed(&fake_base_address(42)) + .unwrap(); + + tx_builder.get_fee_if_set().unwrap() + } + + assert_eq!(calc_fee_with_ex_units(0, 0), to_bignum(173509)); + assert_eq!(calc_fee_with_ex_units(10000, 0), to_bignum(174174)); + assert_eq!(calc_fee_with_ex_units(0, 10000000), to_bignum(174406)); + assert_eq!(calc_fee_with_ex_units(10000, 10000000), to_bignum(175071)); +} + +#[test] +fn test_script_inputs_ordering() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(42)); + let (nscript1, _) = mint_script_and_policy(0); + let (pscript1, _) = plutus_script_and_hash(0); + let (pscript2, _) = plutus_script_and_hash(1); + let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); + let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); + // Creating redeemers with indexes ZERO + let pdata1 = PlutusData::new_bytes(fake_bytes_32(20)); + let pdata2 = PlutusData::new_bytes(fake_bytes_32(21)); + let redeemer1 = Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(0), + &pdata1, + &ExUnits::new(&to_bignum(1), &to_bignum(2)), + ); + let redeemer2 = Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(0), + &pdata2, + &ExUnits::new(&to_bignum(1), &to_bignum(2)), + ); + + tx_builder.add_plutus_script_input( + &PlutusWitness::new(&pscript1, &datum1, &redeemer1), + &fake_tx_input2(2, 1), + &fake_value(), + ); + tx_builder.add_native_script_input(&nscript1, &fake_tx_input2(1, 0), &fake_value()); + tx_builder.add_plutus_script_input( + &PlutusWitness::new(&pscript2, &datum2, &redeemer2), + &fake_tx_input2(2, 0), + &fake_value(), + ); + + let tx: Transaction = tx_builder.build_tx_unsafe().unwrap(); + + let ins = tx.body.inputs; + assert_eq!(ins.len(), 3); + assert_eq!(ins.get(0).transaction_id.0[0], 1); + assert_eq!(ins.get(1).transaction_id.0[0], 2); + assert_eq!(ins.get(1).index, 0); + assert_eq!(ins.get(2).transaction_id.0[0], 2); + assert_eq!(ins.get(2).index, 1); + + let r: Redeemers = tx.witness_set.redeemers.unwrap(); + assert_eq!(r.len(), 2); + + // Redeemer1 now has the index 2 even tho the input was added first + assert_eq!(r.get(0).data(), pdata1); + assert_eq!(r.get(0).index(), to_bignum(2)); + + // Redeemer1 now has the index 1 even tho the input was added last + assert_eq!(r.get(1).data(), pdata2); + assert_eq!(r.get(1).index(), to_bignum(1)); +} + +#[test] +fn test_required_signers() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(42)); + let tx1: TransactionBody = tx_builder.build().unwrap(); + assert!(tx1.required_signers.is_none()); + + let s1 = fake_key_hash(1); + let s2 = fake_key_hash(22); + let s3 = fake_key_hash(133); + + tx_builder.add_required_signer(&s1); + tx_builder.add_required_signer(&s3); + tx_builder.add_required_signer(&s2); + + let tx1: TransactionBody = tx_builder.build().unwrap(); + assert!(tx1.required_signers.is_some()); + + let rs: RequiredSigners = tx1.required_signers.unwrap(); + assert_eq!(rs.len(), 3); + assert_eq!(rs.get(0), s1); + assert_eq!(rs.get(1), s3); + assert_eq!(rs.get(2), s2); +} + +#[test] +fn test_required_signers_are_added_to_the_witness_estimate() { + fn count_fake_witnesses_with_required_signers(keys: &Ed25519KeyHashes) -> usize { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(42)); + tx_builder.add_input( + &fake_base_address(0), + &TransactionInput::new(&fake_tx_hash(0), 0), + &Value::new(&to_bignum(10_000_000)), + ); + + keys.0.iter().for_each(|k| { + tx_builder.add_required_signer(k); + }); + + let tx: Transaction = fake_full_tx(&tx_builder, tx_builder.build().unwrap()).unwrap(); + tx.witness_set.vkeys.unwrap().len() + } + + assert_eq!( + count_fake_witnesses_with_required_signers(&Ed25519KeyHashes::new(),), + 1 + ); + + assert_eq!( + count_fake_witnesses_with_required_signers(&Ed25519KeyHashes(vec![fake_key_hash(1)]),), + 2 + ); + + assert_eq!( + count_fake_witnesses_with_required_signers(&Ed25519KeyHashes(vec![ + fake_key_hash(1), + fake_key_hash(2) + ]),), + 3 + ); + + // This case still produces only 3 fake signatures, because the same key is already used in the input address + assert_eq!( + count_fake_witnesses_with_required_signers(&Ed25519KeyHashes(vec![ + fake_key_hash(1), + fake_key_hash(2), + fake_key_hash(0) + ]),), + 3 + ); + + // When a different key is used - 4 fake witnesses are produced + assert_eq!( + count_fake_witnesses_with_required_signers(&Ed25519KeyHashes(vec![ + fake_key_hash(1), + fake_key_hash(2), + fake_key_hash(3) + ]),), + 4 + ); +} + +#[test] +fn collateral_return_and_total_collateral_setters() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(123456)); + + let mut inp = TxInputsBuilder::new(); + inp.add_input(&fake_base_address(0), &fake_tx_input(0), &fake_value()); + + tx_builder.set_inputs(&inp); + tx_builder.set_collateral(&inp); + + let col_return = TransactionOutput::new(&fake_base_address(1), &fake_value2(123123)); + let col_total = to_bignum(234234); + + tx_builder.set_collateral_return(&col_return); + tx_builder.set_total_collateral(&col_total); + + let tx: Transaction = tx_builder.build_tx_unsafe().unwrap(); + assert!(tx.body.collateral_return.is_some()); + assert_eq!(tx.body.collateral_return.unwrap(), col_return); + assert!(tx.body.total_collateral.is_some()); + assert_eq!(tx.body.total_collateral.unwrap(), col_total); +} + +fn fake_multiasset(amount: u64) -> MultiAsset { + let (_, policy_id) = mint_script_and_policy(234); + let mut assets = Assets::new(); + assets.insert( + &AssetName::new(fake_bytes_32(235)).unwrap(), + &to_bignum(amount), + ); + let mut masset = MultiAsset::new(); + masset.insert(&policy_id, &assets); + masset +} + +#[test] +fn inputs_builder_total_value() { + let mut b = TxInputsBuilder::new(); + assert_eq!(b.total_value().unwrap(), Value::zero()); + + b.add_input( + &fake_base_address(0), + &fake_tx_input(0), + &fake_value2(100_000), + ); + assert_eq!(b.total_value().unwrap(), Value::new(&to_bignum(100_000))); + + b.add_input( + &fake_base_address(1), + &fake_tx_input(1), + &fake_value2(200_000), + ); + assert_eq!(b.total_value().unwrap(), Value::new(&to_bignum(300_000))); + + let masset = fake_multiasset(123); + + b.add_input( + &fake_base_address(2), + &fake_tx_input(2), + &Value::new_with_assets(&to_bignum(300_000), &masset), + ); + assert_eq!( + b.total_value().unwrap(), + Value::new_with_assets(&to_bignum(600_000), &masset) + ); +} + +#[test] +fn test_auto_calc_total_collateral() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(123456)); + + let mut inp = TxInputsBuilder::new(); + let collateral_input_value = 2_000_000; + inp.add_input( + &fake_base_address(0), + &fake_tx_input(0), + &fake_value2(collateral_input_value.clone()), + ); + + tx_builder.set_collateral(&inp); + + let collateral_return_value = 1_234_567; + let col_return = TransactionOutput::new( + &fake_base_address(1), + &fake_value2(collateral_return_value.clone()), + ); + + tx_builder + .set_collateral_return_and_total(&col_return) + .unwrap(); + + assert!(tx_builder.collateral_return.is_some()); + assert_eq!(tx_builder.collateral_return.unwrap(), col_return,); + + assert!(tx_builder.total_collateral.is_some()); + assert_eq!( + tx_builder.total_collateral.unwrap(), + to_bignum(collateral_input_value - collateral_return_value), + ); +} + +#[test] +fn test_auto_calc_total_collateral_with_assets() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(123456)); + + let masset = fake_multiasset(123); + + let mut inp = TxInputsBuilder::new(); + let collateral_input_value = 2_000_000; + inp.add_input( + &fake_base_address(0), + &fake_tx_input(0), + &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), + ); + + tx_builder.set_collateral(&inp); + + let collateral_return_value = 1_345_678; + let col_return = TransactionOutput::new( + &fake_base_address(1), + &Value::new_with_assets(&to_bignum(collateral_return_value.clone()), &masset), + ); + + tx_builder + .set_collateral_return_and_total(&col_return) + .unwrap(); + + assert!(tx_builder.collateral_return.is_some()); + assert_eq!(tx_builder.collateral_return.unwrap(), col_return,); + + assert!(tx_builder.total_collateral.is_some()); + assert_eq!( + tx_builder.total_collateral.unwrap(), + to_bignum(collateral_input_value - collateral_return_value), + ); +} + +#[test] +fn test_auto_calc_total_collateral_fails_with_assets() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(123456)); + + let masset = fake_multiasset(123); + + let mut inp = TxInputsBuilder::new(); + let collateral_input_value = 2_000_000; + inp.add_input( + &fake_base_address(0), + &fake_tx_input(0), + &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), + ); + + tx_builder.set_collateral(&inp); + + // Collateral return does not handle ALL the assets from collateral input + let collateral_return_value = 1_345_678; + let col_return = TransactionOutput::new( + &fake_base_address(1), + &fake_value2(collateral_return_value.clone()), + ); + + let res = tx_builder.set_collateral_return_and_total(&col_return); + + // Function call returns an error + assert!(res.is_err()); + + // NEITHER total collateral nor collateral return are changed in the builder + assert!(tx_builder.total_collateral.is_none()); + assert!(tx_builder.collateral_return.is_none()); +} + +#[test] +fn test_auto_calc_total_collateral_fails_on_no_collateral() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(123456)); + + let res = tx_builder.set_collateral_return_and_total(&TransactionOutput::new( + &fake_base_address(1), + &fake_value2(1_345_678), + )); + + // Function call returns an error + assert!(res.is_err()); + + // NEITHER total collateral nor collateral return are changed in the builder + assert!(tx_builder.total_collateral.is_none()); + assert!(tx_builder.collateral_return.is_none()); +} + +#[test] +fn test_auto_calc_total_collateral_fails_on_no_ada() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(123456)); + + let mut inp = TxInputsBuilder::new(); + let collateral_input_value = 2_000_000; + inp.add_input( + &fake_base_address(0), + &fake_tx_input(0), + &Value::new(&to_bignum(collateral_input_value.clone())), + ); + + tx_builder.set_collateral(&inp); + + let res = tx_builder.set_collateral_return_and_total(&TransactionOutput::new( + &fake_base_address(1), + &fake_value2(1), + )); + + // Function call returns an error + assert!(res.is_err()); + + // NEITHER total collateral nor collateral return are changed in the builder + assert!(tx_builder.total_collateral.is_none()); + assert!(tx_builder.collateral_return.is_none()); +} + +#[test] +fn test_auto_calc_collateral_return() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(123456)); + + let mut inp = TxInputsBuilder::new(); + let collateral_input_value = 2_000_000; + inp.add_input( + &fake_base_address(0), + &fake_tx_input(0), + &fake_value2(collateral_input_value.clone()), + ); + + tx_builder.set_collateral(&inp); + + let total_collateral_value = 234_567; + let collateral_return_address = fake_base_address(1); + + tx_builder + .set_total_collateral_and_return( + &to_bignum(total_collateral_value.clone()), + &collateral_return_address, + ) + .unwrap(); + + assert!(tx_builder.total_collateral.is_some()); + assert_eq!( + tx_builder.total_collateral.unwrap(), + to_bignum(total_collateral_value.clone()), + ); + + assert!(tx_builder.collateral_return.is_some()); + let col_return: TransactionOutput = tx_builder.collateral_return.unwrap(); + assert_eq!(col_return.address, collateral_return_address); + assert_eq!( + col_return.amount, + Value::new(&to_bignum(collateral_input_value - total_collateral_value),) + ); +} + +#[test] +fn test_auto_calc_collateral_return_with_assets() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(123456)); + + let masset = fake_multiasset(123); + + let mut inp = TxInputsBuilder::new(); + let collateral_input_value = 2_000_000; + inp.add_input( + &fake_base_address(0), + &fake_tx_input(0), + &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), + ); + + tx_builder.set_collateral(&inp); + + let total_collateral_value = 345_678; + let collateral_return_address = fake_base_address(1); + + tx_builder + .set_total_collateral_and_return( + &to_bignum(total_collateral_value.clone()), + &collateral_return_address, + ) + .unwrap(); + + assert!(tx_builder.total_collateral.is_some()); + assert_eq!( + tx_builder.total_collateral.unwrap(), + to_bignum(total_collateral_value.clone()), + ); + + assert!(tx_builder.collateral_return.is_some()); + let col_return: TransactionOutput = tx_builder.collateral_return.unwrap(); + assert_eq!(col_return.address, collateral_return_address); + assert_eq!( + col_return.amount, + Value::new_with_assets( + &to_bignum(collateral_input_value - total_collateral_value), + &masset, + ) + ); +} + +#[test] +fn test_add_collateral_return_succeed_with_border_amount() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(123456)); + + let masset = fake_multiasset(123); + + let mut inp = TxInputsBuilder::new(); + let collateral_input_value = 2_000_000; + inp.add_input( + &fake_base_address(0), + &fake_tx_input(0), + &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), + ); + + tx_builder.set_collateral(&inp); + + let collateral_return_address = fake_base_address(1); + + let possible_ret = Value::new_from_assets(&masset); + let fake_out = TransactionOutput::new(&collateral_return_address, &possible_ret); + let min_ada = min_ada_for_output(&fake_out, &tx_builder.config.utxo_cost()).unwrap(); + + let total_collateral_value = to_bignum(collateral_input_value) + .checked_sub(&min_ada) + .unwrap(); + + tx_builder + .set_total_collateral_and_return(&total_collateral_value, &collateral_return_address) + .unwrap(); + + assert!(tx_builder.total_collateral.is_some()); + assert!(tx_builder.collateral_return.is_some()); + let col_return: TransactionOutput = tx_builder.collateral_return.unwrap(); + assert_eq!(col_return.address, collateral_return_address); + assert_eq!( + col_return.amount, + Value::new_with_assets(&min_ada, &masset,) + ); +} + +#[test] +fn test_add_zero_collateral_return() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(123456)); + + let mut inp = TxInputsBuilder::new(); + let collateral_input_value = 2_000_000; + inp.add_input( + &fake_base_address(0), + &fake_tx_input(0), + &Value::new(&to_bignum(collateral_input_value.clone())), + ); + + tx_builder.set_collateral(&inp); + + let collateral_return_address = fake_base_address(1); + + tx_builder + .set_total_collateral_and_return( + &to_bignum(collateral_input_value.clone()), + &collateral_return_address, + ) + .unwrap(); + + assert!(tx_builder.total_collateral.is_some()); + assert!(tx_builder.collateral_return.is_none()); +} + +#[test] +fn test_add_collateral_return_fails_no_enough_ada() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(123456)); + + let masset = fake_multiasset(123); + + let mut inp = TxInputsBuilder::new(); + let collateral_input_value = 2_000_000; + inp.add_input( + &fake_base_address(0), + &fake_tx_input(0), + &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), + ); + + tx_builder.set_collateral(&inp); + + let collateral_return_address = fake_base_address(1); + + let possible_ret = Value::new_from_assets(&masset); + let fake_out = TransactionOutput::new(&collateral_return_address, &possible_ret); + let min_ada = min_ada_for_output(&fake_out, &tx_builder.config.utxo_cost()).unwrap(); + let mut total_collateral_value = to_bignum(collateral_input_value) + .checked_sub(&min_ada) + .unwrap(); + //make total collateral value bigger for make collateral return less then min ada + total_collateral_value = total_collateral_value.checked_add(&to_bignum(1)).unwrap(); + + let coll_add_res = tx_builder + .set_total_collateral_and_return(&total_collateral_value, &collateral_return_address); + + assert!(coll_add_res.is_err()); + assert!(tx_builder.total_collateral.is_none()); + assert!(tx_builder.collateral_return.is_none()); +} + +#[test] +fn test_auto_calc_collateral_return_fails_on_no_collateral() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(123456)); + + let res = tx_builder + .set_total_collateral_and_return(&to_bignum(345_678.clone()), &fake_base_address(1)); + + assert!(res.is_err()); + assert!(tx_builder.total_collateral.is_none()); + assert!(tx_builder.collateral_return.is_none()); +} + +#[test] +fn test_costmodel_retaining_for_v1() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_collateral(&create_collateral()); + + let (script1, _) = plutus_script_and_hash(0); + let datum = PlutusData::new_integer(&BigInt::from_str("42").unwrap()); + let redeemer = Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(0), + &datum, + &ExUnits::new(&to_bignum(1700), &to_bignum(368100)), + ); + tx_builder.add_plutus_script_input( + &PlutusWitness::new(&script1, &datum, &redeemer), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + + // Setting script data hash removes the error + tx_builder + .calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()) + .unwrap(); + + // Using SAFE `.build_tx` + let res2 = tx_builder.build_tx(); + assert!(res2.is_ok()); + + let v1 = Language::new_plutus_v1(); + let v1_costmodel = TxBuilderConstants::plutus_vasil_cost_models() + .get(&v1) + .unwrap(); + let mut retained_cost_models = Costmdls::new(); + retained_cost_models.insert(&v1, &v1_costmodel); + + let data_hash = hash_script_data( + &Redeemers::from(vec![redeemer.clone()]), + &retained_cost_models, + Some(PlutusList::from(vec![datum])), + ); + assert_eq!(tx_builder.script_data_hash.unwrap(), data_hash); +} + +#[test] +fn test_costmodel_retaining_fails_on_missing_costmodel() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_collateral(&create_collateral()); + + let (script1, _) = plutus_script_and_hash(0); + let datum = PlutusData::new_integer(&BigInt::from_str("42").unwrap()); + let redeemer = Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(0), + &datum, + &ExUnits::new(&to_bignum(1700), &to_bignum(368100)), + ); + tx_builder.add_plutus_script_input( + &PlutusWitness::new(&script1, &datum, &redeemer), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ); + + let v2 = Language::new_plutus_v2(); + let v2_costmodel = TxBuilderConstants::plutus_vasil_cost_models() + .get(&v2) + .unwrap(); + let mut retained_cost_models = Costmdls::new(); + retained_cost_models.insert(&v2, &v2_costmodel); + + // Setting script data hash removes the error + let calc_result = tx_builder.calc_script_data_hash(&retained_cost_models); + assert!(calc_result.is_err()); +} + +#[test] +fn coin_selection_random_improve_multi_asset() { + let utoxs = TransactionUnspentOutputs::from_json("[ { \"input\": { + \"transaction_id\": \"96631bf40bc2ae1e10b3c9157a4c711562c664b9744ed1f580b725e0589efcd0\", + \"index\": 1 +}, +\"output\": { + \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", + \"amount\": { + \"coin\": \"661308571\", + \"multiasset\": null + }, + \"plutus_data\": null, + \"script_ref\": null +}}, +{ \"input\": { + \"transaction_id\": \"89da149fa162eca7212493f2bcc8415ed070832e053ac0ec335d3501f901ad77\", + \"index\": 1 +}, +\"output\": { + \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", + \"amount\": { + \"coin\": \"555975153\", + \"multiasset\": null + }, + \"plutus_data\": null, + \"script_ref\": null +}}, +{ \"input\": { + \"transaction_id\": \"0124993c20ea0fe626d96a644773225202fb442238c38206242d26a1131e0a6e\", + \"index\": 1 +}, +\"output\": { + \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", + \"amount\": { + \"coin\": \"1899495\", + \"multiasset\": { + \"07e8df329b724e4be48ee32738125c06000de5448aaf93ed46d59e28\": { + \"44696e6f436f696e\": \"750\" + } + } + }, + \"plutus_data\": null, + \"script_ref\": null +}}, +{ \"input\": { + \"transaction_id\": \"c15c423d624b3af3f032c079a1b390c472b8ba889b48dd581d0ea28f96a36875\", + \"index\": 0 +}, +\"output\": { + \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", + \"amount\": { + \"coin\": \"1804315\", + \"multiasset\": { + \"07e8df329b724e4be48ee32738125c06000de5448aaf93ed46d59e28\": { + \"44696e6f436f696e\": \"2000\" + } + } + }, + \"plutus_data\": null, + \"script_ref\": null +}}, +{ \"input\": { + \"transaction_id\": \"5894bf9c9125859d29770bf43e4018f4f34a69edee49a7c9488c6707ab523c9b\", + \"index\": 1 +}, +\"output\": { + \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", + \"amount\": { + \"coin\": \"440573428\", + \"multiasset\": null + }, + \"plutus_data\": null, + \"script_ref\": null +}}, +{ \"input\": { + \"transaction_id\": \"168404afd4e9927d7775c8f40c0f749fc7634832d6931c5d51a507724cf44420\", + \"index\": 0 +}, +\"output\": { + \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", + \"amount\": { + \"coin\": \"1804315\", + \"multiasset\": { + \"07e8df329b724e4be48ee32738125c06000de5448aaf93ed46d59e28\": { + \"44696e6f436f696e\": \"1000\" + } + } + }, + \"plutus_data\": null, + \"script_ref\": null +}}, +{ \"input\": { + \"transaction_id\": \"3e6138498b721ee609a4c289768b2accad39cd4f00448540a95ba3362578a2f7\", + \"index\": 4 +}, +\"output\": { + \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", + \"amount\": { + \"coin\": \"1508500\", + \"multiasset\": { + \"07e8df329b724e4be48ee32738125c06000de5448aaf93ed46d59e28\": { + \"44696e6f436f696e\": \"750\" + } + } + }, + \"plutus_data\": null, + \"script_ref\": null +}}, +{ \"input\": { + \"transaction_id\": \"3e6138498b721ee609a4c289768b2accad39cd4f00448540a95ba3362578a2f7\", + \"index\": 5 +}, +\"output\": { + \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", + \"amount\": { + \"coin\": \"664935092\", + \"multiasset\": null + }, + \"plutus_data\": null, + \"script_ref\": null +}}, +{ \"input\": { + \"transaction_id\": \"046cf1bc21c23c59975714b520dd7ed22b63dab592cb0449e0ee6cc96eefde69\", + \"index\": 2 +}, +\"output\": { + \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", + \"amount\": { + \"coin\": \"7094915\", + \"multiasset\": null + }, + \"plutus_data\": null, + \"script_ref\": null +}}, +{ \"input\": { + \"transaction_id\": \"e16f195105db5f84621af4f7ea57c7156b8699cba94d4fdb72a6fb09e31db7a8\", + \"index\": 1 +}, +\"output\": { + \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", + \"amount\": { + \"coin\": \"78400000\", + \"multiasset\": null + }, + \"plutus_data\": null, + \"script_ref\": null +}}, +{ \"input\": { + \"transaction_id\": \"e16f195105db5f84621af4f7ea57c7156b8699cba94d4fdb72a6fb09e31db7a8\", + \"index\": 2 +}, +\"output\": { + \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", + \"amount\": { + \"coin\": \"2000000\", + \"multiasset\": null + }, + \"plutus_data\": null, + \"script_ref\": null +}}, +{ \"input\": { + \"transaction_id\": \"006697ef0c9285b7001ebe5a9e356fb50441e0af803773a99b7cbb0e9b728570\", + \"index\": 1 +}, +\"output\": { + \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", + \"amount\": { + \"coin\": \"15054830\", + \"multiasset\": { + \"07e8df329b724e4be48ee32738125c06000de5448aaf93ed46d59e28\": { + \"44696e6f436f696e\": \"56250\" + }, + \"3320679b145d683b9123f0626360699fcd7408b4d3ec3bd9cc79398c\": { + \"44696e6f436f696e\": \"287000\" + }, + \"57fca08abbaddee36da742a839f7d83a7e1d2419f1507fcbf3916522\": { + \"4d494e54\": \"91051638\", + \"534245525259\": \"27198732\" + }, + \"e61bfc106338ed4aeba93036324fbea8150fd9750fcffca1cd9f1a19\": { + \"44696e6f536176696f723030303639\": \"1\", + \"44696e6f536176696f723030303936\": \"1\", + \"44696e6f536176696f723030313737\": \"1\", + \"44696e6f536176696f723030333033\": \"1\", + \"44696e6f536176696f723030333531\": \"1\", + \"44696e6f536176696f723030333931\": \"1\", + \"44696e6f536176696f723030343336\": \"1\", + \"44696e6f536176696f723030343434\": \"1\", + \"44696e6f536176696f723030353232\": \"1\", + \"44696e6f536176696f723030353337\": \"1\", + \"44696e6f536176696f723030363334\": \"1\", + \"44696e6f536176696f723030373332\": \"1\", + \"44696e6f536176696f723030373430\": \"1\", + \"44696e6f536176696f723030373435\": \"1\", + \"44696e6f536176696f723031303139\": \"1\", + \"44696e6f536176696f723031303631\": \"1\", + \"44696e6f536176696f723031333432\": \"1\", + \"44696e6f536176696f723031333832\": \"1\", + \"44696e6f536176696f723031353333\": \"1\", + \"44696e6f536176696f723031353732\": \"1\", + \"44696e6f536176696f723031363337\": \"1\", + \"44696e6f536176696f723031363430\": \"1\", + \"44696e6f536176696f723031373631\": \"1\", + \"44696e6f536176696f723031393436\": \"1\", + \"44696e6f536176696f723032313237\": \"1\", + \"44696e6f536176696f723032323232\": \"1\", + \"44696e6f536176696f723032333230\": \"1\", + \"44696e6f536176696f723032333239\": \"1\", + \"44696e6f536176696f723032333534\": \"1\", + \"44696e6f536176696f723032333631\": \"1\", + \"44696e6f536176696f723032333935\": \"1\", + \"44696e6f536176696f723032333938\": \"1\", + \"44696e6f536176696f723032343037\": \"1\", + \"44696e6f536176696f723032343434\": \"1\", + \"44696e6f536176696f723032353039\": \"1\", + \"44696e6f536176696f723032363334\": \"1\", + \"44696e6f536176696f723032363430\": \"1\", + \"44696e6f536176696f723032373537\": \"1\", + \"44696e6f536176696f723032373832\": \"1\", + \"44696e6f536176696f723032383933\": \"1\", + \"44696e6f536176696f723033323430\": \"1\", + \"44696e6f536176696f723033343937\": \"1\", + \"44696e6f536176696f723033353437\": \"1\", + \"44696e6f536176696f723033353738\": \"1\", + \"44696e6f536176696f723033363638\": \"1\", + \"44696e6f536176696f723033363836\": \"1\", + \"44696e6f536176696f723033363930\": \"1\", + \"44696e6f536176696f723033383638\": \"1\", + \"44696e6f536176696f723033383731\": \"1\", + \"44696e6f536176696f723033383931\": \"1\", + \"44696e6f536176696f723034313936\": \"1\", + \"44696e6f536176696f723034323538\": \"1\", + \"44696e6f536176696f723034323733\": \"1\", + \"44696e6f536176696f723034363235\": \"1\", + \"44696e6f536176696f723034373132\": \"1\", + \"44696e6f536176696f723034373932\": \"1\", + \"44696e6f536176696f723034383831\": \"1\", + \"44696e6f536176696f723034393936\": \"1\", + \"44696e6f536176696f723035303432\": \"1\", + \"44696e6f536176696f723035313539\": \"1\", + \"44696e6f536176696f723035333138\": \"1\", + \"44696e6f536176696f723035333532\": \"1\", + \"44696e6f536176696f723035343433\": \"1\", + \"44696e6f536176696f723035343639\": \"1\", + \"44696e6f536176696f723035373434\": \"1\", + \"44696e6f536176696f723035373638\": \"1\", + \"44696e6f536176696f723035373830\": \"1\", + \"44696e6f536176696f723035383435\": \"1\", + \"44696e6f536176696f723035383538\": \"1\", + \"44696e6f536176696f723035393632\": \"1\", + \"44696e6f536176696f723036303032\": \"1\", + \"44696e6f536176696f723036303337\": \"1\", + \"44696e6f536176696f723036303738\": \"1\", + \"44696e6f536176696f723036323033\": \"1\", + \"44696e6f536176696f723036323036\": \"1\", + \"44696e6f536176696f723036323236\": \"1\", + \"44696e6f536176696f723036333130\": \"1\", + \"44696e6f536176696f723036333935\": \"1\", + \"44696e6f536176696f723036343932\": \"1\", + \"44696e6f536176696f723036353532\": \"1\", + \"44696e6f536176696f723036363735\": \"1\", + \"44696e6f536176696f723036363839\": \"1\", + \"44696e6f536176696f723036373233\": \"1\", + \"44696e6f536176696f723036383731\": \"1\", + \"44696e6f536176696f723036383830\": \"1\", + \"44696e6f536176696f723036393137\": \"1\", + \"44696e6f536176696f723037303339\": \"1\", + \"44696e6f536176696f723037323638\": \"1\", + \"44696e6f536176696f723037333434\": \"1\", + \"44696e6f536176696f723037343232\": \"1\", + \"44696e6f536176696f723037343731\": \"1\", + \"44696e6f536176696f723037353431\": \"1\", + \"44696e6f536176696f723037363032\": \"1\", + \"44696e6f536176696f723037363136\": \"1\", + \"44696e6f536176696f723037363430\": \"1\", + \"44696e6f536176696f723037373635\": \"1\", + \"44696e6f536176696f723037373732\": \"1\", + \"44696e6f536176696f723037393039\": \"1\", + \"44696e6f536176696f723037393234\": \"1\", + \"44696e6f536176696f723037393430\": \"1\", + \"44696e6f536176696f723037393632\": \"1\", + \"44696e6f536176696f723038303130\": \"1\", + \"44696e6f536176696f723038303338\": \"1\", + \"44696e6f536176696f723038303339\": \"1\", + \"44696e6f536176696f723038303636\": \"1\", + \"44696e6f536176696f723038313735\": \"1\", + \"44696e6f536176696f723038323032\": \"1\", + \"44696e6f536176696f723038323131\": \"1\", + \"44696e6f536176696f723038323536\": \"1\", + \"44696e6f536176696f723038333532\": \"1\", + \"44696e6f536176696f723038333536\": \"1\", + \"44696e6f536176696f723038333538\": \"1\", + \"44696e6f536176696f723038333539\": \"1\", + \"44696e6f536176696f723038333830\": \"1\", + \"44696e6f536176696f723038343932\": \"1\", + \"44696e6f536176696f723038353231\": \"1\", + \"44696e6f536176696f723038353736\": \"1\", + \"44696e6f536176696f723038353836\": \"1\", + \"44696e6f536176696f723038363130\": \"1\", + \"44696e6f536176696f723039303231\": \"1\", + \"44696e6f536176696f723039303735\": \"1\", + \"44696e6f536176696f723039313039\": \"1\", + \"44696e6f536176696f723039313231\": \"1\", + \"44696e6f536176696f723039323238\": \"1\", + \"44696e6f536176696f723039333138\": \"1\", + \"44696e6f536176696f723039333731\": \"1\", + \"44696e6f536176696f723039343035\": \"1\", + \"44696e6f536176696f723039343136\": \"1\", + \"44696e6f536176696f723039353039\": \"1\", + \"44696e6f536176696f723039353635\": \"1\", + \"44696e6f536176696f723039363331\": \"1\", + \"44696e6f536176696f723039363932\": \"1\", + \"44696e6f536176696f723039383839\": \"1\", + \"44696e6f536176696f723039393038\": \"1\", + \"44696e6f536176696f723039393935\": \"1\" + }, + \"ee8e37676f6ebb8e031dff493f88ff711d24aa68666a09d61f1d3fb3\": { + \"43727970746f44696e6f3030303135\": \"1\", + \"43727970746f44696e6f3030313335\": \"1\", + \"43727970746f44696e6f3030323634\": \"1\", + \"43727970746f44696e6f3030333932\": \"1\", + \"43727970746f44696e6f3030353834\": \"1\", + \"43727970746f44696e6f3030373136\": \"1\", + \"43727970746f44696e6f3030373837\": \"1\", + \"43727970746f44696e6f3030383438\": \"1\", + \"43727970746f44696e6f3031303537\": \"1\", + \"43727970746f44696e6f3031313134\": \"1\", + \"43727970746f44696e6f3031323237\": \"1\", + \"43727970746f44696e6f3031323330\": \"1\", + \"43727970746f44696e6f3031343031\": \"1\", + \"43727970746f44696e6f3031353138\": \"1\", + \"43727970746f44696e6f3031353734\": \"1\", + \"43727970746f44696e6f3031373635\": \"1\", + \"43727970746f44696e6f3031383037\": \"1\", + \"43727970746f44696e6f3031383231\": \"1\", + \"43727970746f44696e6f3032303830\": \"1\", + \"43727970746f44696e6f3032313133\": \"1\", + \"43727970746f44696e6f3032323835\": \"1\", + \"43727970746f44696e6f3032343238\": \"1\", + \"43727970746f44696e6f3032363738\": \"1\", + \"43727970746f44696e6f3032393034\": \"1\", + \"43727970746f44696e6f3032393333\": \"1\", + \"43727970746f44696e6f3032393537\": \"1\", + \"43727970746f44696e6f3032393632\": \"1\", + \"43727970746f44696e6f3032393735\": \"1\", + \"43727970746f44696e6f3033303434\": \"1\", + \"43727970746f44696e6f3033333338\": \"1\", + \"43727970746f44696e6f3033393535\": \"1\", + \"43727970746f44696e6f3034303630\": \"1\", + \"43727970746f44696e6f3034313939\": \"1\", + \"43727970746f44696e6f3034373439\": \"1\", + \"43727970746f44696e6f3034383134\": \"1\", + \"43727970746f44696e6f3034393530\": \"1\", + \"43727970746f44696e6f3035303630\": \"1\", + \"43727970746f44696e6f3035333230\": \"1\", + \"43727970746f44696e6f2d312d3030303030\": \"1\", + \"43727970746f44696e6f2d312d3030303032\": \"1\" + } + } + }, + \"plutus_data\": null, + \"script_ref\": null +}}, +{ \"input\": { + \"transaction_id\": \"006697ef0c9285b7001ebe5a9e356fb50441e0af803773a99b7cbb0e9b728570\", + \"index\": 2 +}, +\"output\": { + \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", + \"amount\": { + \"coin\": \"2279450\", + \"multiasset\": null + }, + \"plutus_data\": null, + \"script_ref\": null +}}, +{ \"input\": { + \"transaction_id\": \"017962634cf8fa87835256a80b8374c6f75687c34d8694480cb071648551c3a7\", + \"index\": 0 +}, +\"output\": { + \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", + \"amount\": { + \"coin\": \"2000000\", + \"multiasset\": { + \"ee8e37676f6ebb8e031dff493f88ff711d24aa68666a09d61f1d3fb3\": { + \"43727970746f44696e6f3031353039\": \"1\" + } + } + }, + \"plutus_data\": null, + \"script_ref\": null +}}, +{ \"input\": { + \"transaction_id\": \"017962634cf8fa87835256a80b8374c6f75687c34d8694480cb071648551c3a7\", + \"index\": 1 +}, +\"output\": { + \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", + \"amount\": { + \"coin\": \"725669617\", + \"multiasset\": null + }, + \"plutus_data\": null, + \"script_ref\": null +}}]") + .unwrap(); + let output = TransactionOutput::from_json( + "{ + \"address\": \"addr_test1wpv93hm9sqx0ar7pgxwl9jn3xt6lwmxxy27zd932slzvghqg8fe0n\", + \"amount\": { + \"coin\": \"20000000\", + \"multiasset\": { + \"07e8df329b724e4be48ee32738125c06000de5448aaf93ed46d59e28\": { + \"44696e6f436f696e\": \"1000\" + }, + \"ee8e37676f6ebb8e031dff493f88ff711d24aa68666a09d61f1d3fb3\": { + \"43727970746f44696e6f2d312d3030303030\": \"1\", + \"43727970746f44696e6f2d312d3030303032\": \"1\" + } + } + }, + \"plutus_data\": { + \"DataHash\": \"979f68de9e070e75779f80ce5e6cc74f8d77661d65f2895c01d0a6f66eceb791\" + }, + \"script_ref\": null +}", + ) + .unwrap(); + let mut builder = create_reallistic_tx_builder(); + builder.add_output(&output).unwrap(); + let res = builder.add_inputs_from(&utoxs, CoinSelectionStrategyCIP2::RandomImproveMultiAsset); + assert!(res.is_ok()); +} + +#[test] +fn plutus_mint_test() { + let mut tx_builder = create_reallistic_tx_builder(); + let colateral_adress = Address::from_bech32("addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w").unwrap(); + let colateral_input = TransactionInput::from_json("\ + { + \"transaction_id\": \"69b0b867056a2d4fdc3827e23aa7069b125935e2def774941ca8cc7f9e0de774\", + \"index\": 1 + }").unwrap(); + + let tx_input = TransactionInput::from_json("\ + { + \"transaction_id\": \"f58a5bc761b1efdcf4b5684f6ad5495854a0d64b866e2f0f525d134750d3511b\", + \"index\": 1 + }").unwrap(); + let plutus_script = plutus::PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); + let redeemer = Redeemer::from_json( + "\ + { + \"tag\": \"Mint\", + \"index\": \"0\", + \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", + \"ex_units\": { + \"mem\": \"1042996\", + \"steps\": \"446100241\" + } + }", + ) + .unwrap(); + let asset_name = AssetName::from_hex("44544e4654").unwrap(); + let mut mint_builder = MintBuilder::new(); + let plutus_script_source = PlutusScriptSource::new(&plutus_script); + let mint_witnes = MintWitness::new_plutus_script(&plutus_script_source, &redeemer); + mint_builder.add_asset(&mint_witnes, &asset_name, &Int::new(&BigNum::from(100u64))); + + let output_adress = Address::from_bech32("addr_test1qpm5njmgzf4t7225v6j34wl30xfrufzt3jtqtdzf3en9ahpmnhtmynpasyc8fq75zv0uaj86vzsr7g3g8q5ypgu5fwtqr9zsgj").unwrap(); + let mut output_assets = MultiAsset::new(); + let mut asset = Assets::new(); + asset.insert(&asset_name, &BigNum::from(100u64)); + output_assets.insert(&plutus_script.hash(), &asset); + let output_value = Value::new_with_assets(&Coin::from(50000u64), &output_assets); + let output = TransactionOutput::new(&output_adress, &output_value); + + let mut col_builder = TxInputsBuilder::new(); + col_builder.add_input( + &colateral_adress, + &colateral_input, + &Value::new(&Coin::from(1000000000u64)), + ); + tx_builder.set_collateral(&col_builder); + tx_builder.add_output(&output); + tx_builder.add_input( + &output_adress, + &tx_input, + &Value::new(&BigNum::from(100000000000u64)), + ); + tx_builder.set_mint_builder(&mint_builder); + + tx_builder + .calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()) + .unwrap(); + + let change_res = tx_builder.add_change_if_needed(&output_adress); + assert!(change_res.is_ok()); + + let build_res = tx_builder.build_tx(); + assert!(build_res.is_ok()); + + assert!(mint_builder.get_plutus_witnesses().len() == 1); + + let tx = build_res.unwrap(); + assert!(tx.body.mint.is_some()); + assert_eq!( + tx.body.mint.unwrap().0.iter().next().unwrap().0, + plutus_script.hash() + ); +} + +#[test] +fn plutus_mint_with_script_ref_test() { + let mut tx_builder = create_reallistic_tx_builder(); + let colateral_adress = Address::from_bech32("addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w").unwrap(); + let colateral_input = TransactionInput::from_json("\ + { + \"transaction_id\": \"69b0b867056a2d4fdc3827e23aa7069b125935e2def774941ca8cc7f9e0de774\", + \"index\": 1 + }").unwrap(); + + let tx_input = TransactionInput::from_json("\ + { + \"transaction_id\": \"f58a5bc761b1efdcf4b5684f6ad5495854a0d64b866e2f0f525d134750d3511b\", + \"index\": 1 + }").unwrap(); + let tx_input_ref = TransactionInput::from_json("\ + { + \"transaction_id\": \"f58a5bc7adaadadcf4b5684f6ad5495854a0d64b866e2f0f525d134750d3511b\", + \"index\": 2 + }").unwrap(); + let plutus_script = plutus::PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); + let plutus_script2 = plutus::PlutusScript::from_hex("5907adaada00332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); + + let redeemer = Redeemer::from_json( + "\ + { + \"tag\": \"Mint\", + \"index\": \"0\", + \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", + \"ex_units\": { + \"mem\": \"1042996\", + \"steps\": \"446100241\" + } + }", + ) + .unwrap(); + + let redeemer2 = Redeemer::from_json( + "\ + { + \"tag\": \"Mint\", + \"index\": \"0\", + \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", + \"ex_units\": { + \"mem\": \"2929292\", + \"steps\": \"446188888\" + } + }", + ) + .unwrap(); + + let asset_name = AssetName::from_hex("44544e4654").unwrap(); + let asset_name2 = AssetName::from_hex("44544e4ada").unwrap(); + let mut mint_builder = MintBuilder::new(); + let plutus_script_source = PlutusScriptSource::new(&plutus_script); + let plutus_script_source_ref = PlutusScriptSource::new_ref_input_with_lang_ver( + &plutus_script2.hash(), + &tx_input_ref, + &Language::new_plutus_v2(), + ); + let mint_witnes = MintWitness::new_plutus_script(&plutus_script_source, &redeemer); + let mint_witnes_ref = MintWitness::new_plutus_script(&plutus_script_source_ref, &redeemer2); + mint_builder.add_asset(&mint_witnes, &asset_name, &Int::new(&BigNum::from(100u64))); + mint_builder.add_asset( + &mint_witnes_ref, + &asset_name, + &Int::new(&BigNum::from(100u64)), + ); + + let output_adress = Address::from_bech32("addr_test1qpm5njmgzf4t7225v6j34wl30xfrufzt3jtqtdzf3en9ahpmnhtmynpasyc8fq75zv0uaj86vzsr7g3g8q5ypgu5fwtqr9zsgj").unwrap(); + let mut output_assets = MultiAsset::new(); + let mut asset = Assets::new(); + asset.insert(&asset_name, &BigNum::from(100u64)); + output_assets.insert(&plutus_script.hash(), &asset); + let output_value = Value::new_with_assets(&Coin::from(50000u64), &output_assets); + let output = TransactionOutput::new(&output_adress, &output_value); + + let mut col_builder = TxInputsBuilder::new(); + col_builder.add_input( + &colateral_adress, + &colateral_input, + &Value::new(&Coin::from(1000000000u64)), + ); + tx_builder.set_collateral(&col_builder); + tx_builder.add_output(&output); + tx_builder.add_input( + &output_adress, + &tx_input, + &Value::new(&BigNum::from(100000000000u64)), + ); + tx_builder.set_mint_builder(&mint_builder); + + tx_builder + .calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()) + .unwrap(); + + let change_res = tx_builder.add_change_if_needed(&output_adress); + assert!(change_res.is_ok()); + + let build_res = tx_builder.build_tx(); + assert!(build_res.is_ok()); + + let tx = build_res.unwrap(); + assert_eq!(tx.witness_set.plutus_scripts.unwrap().len(), 1usize); + assert_eq!(tx.witness_set.redeemers.unwrap().len(), 2usize); + assert!(tx.witness_set.plutus_data.is_none()); + assert_eq!(tx.body.reference_inputs.unwrap().len(), 1usize); + assert!(tx.body.mint.is_some()); + assert_eq!(tx.body.mint.unwrap().len(), 2usize); +} + +#[test] +fn plutus_mint_defferent_redeemers_test() { + let mut tx_builder = create_reallistic_tx_builder(); + let colateral_adress = Address::from_bech32("addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w").unwrap(); + let colateral_input = TransactionInput::from_json("\ + { + \"transaction_id\": \"69b0b867056a2d4fdc3827e23aa7069b125935e2def774941ca8cc7f9e0de774\", + \"index\": 1 + }").unwrap(); + + let tx_input = TransactionInput::from_json("\ + { + \"transaction_id\": \"f58a5bc761b1efdcf4b5684f6ad5495854a0d64b866e2f0f525d134750d3511b\", + \"index\": 1 + }").unwrap(); + let tx_input_ref = TransactionInput::from_json("\ + { + \"transaction_id\": \"f58a5bc7adaadadcf4b5684f6ad5495854a0d64b866e2f0f525d134750d3511b\", + \"index\": 2 + }").unwrap(); + let plutus_script = plutus::PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); + + let redeemer = Redeemer::from_json( + "\ + { + \"tag\": \"Mint\", + \"index\": \"0\", + \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", + \"ex_units\": { + \"mem\": \"1042996\", + \"steps\": \"446100241\" + } + }", + ) + .unwrap(); + + let redeemer2 = Redeemer::from_json( + "\ + { + \"tag\": \"Mint\", + \"index\": \"0\", + \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", + \"ex_units\": { + \"mem\": \"2929292\", + \"steps\": \"446188888\" + } + }", + ) + .unwrap(); + + let asset_name = AssetName::from_hex("44544e4654").unwrap(); + let asset_name2 = AssetName::from_hex("44544e4ada").unwrap(); + let mut mint_builder = MintBuilder::new(); + let plutus_script_source = PlutusScriptSource::new(&plutus_script); + let mint_witnes = MintWitness::new_plutus_script(&plutus_script_source, &redeemer); + let mint_witnes2 = MintWitness::new_plutus_script(&plutus_script_source, &redeemer2); + mint_builder.add_asset(&mint_witnes, &asset_name, &Int::new(&BigNum::from(100u64))); + mint_builder.add_asset(&mint_witnes2, &asset_name, &Int::new(&BigNum::from(100u64))); + + let output_adress = Address::from_bech32("addr_test1qpm5njmgzf4t7225v6j34wl30xfrufzt3jtqtdzf3en9ahpmnhtmynpasyc8fq75zv0uaj86vzsr7g3g8q5ypgu5fwtqr9zsgj").unwrap(); + let mut output_assets = MultiAsset::new(); + let mut asset = Assets::new(); + asset.insert(&asset_name, &BigNum::from(100u64)); + output_assets.insert(&plutus_script.hash(), &asset); + let output_value = Value::new_with_assets(&Coin::from(50000u64), &output_assets); + let output = TransactionOutput::new(&output_adress, &output_value); + + let mut col_builder = TxInputsBuilder::new(); + col_builder.add_input( + &colateral_adress, + &colateral_input, + &Value::new(&Coin::from(1000000000u64)), + ); + tx_builder.set_collateral(&col_builder); + tx_builder.add_output(&output); + tx_builder.add_input( + &output_adress, + &tx_input, + &Value::new(&BigNum::from(100000000000u64)), + ); + tx_builder.set_mint_builder(&mint_builder); + + tx_builder + .calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()) + .unwrap(); + + let change_res = tx_builder.add_change_if_needed(&output_adress); + assert!(change_res.is_ok()); + + let build_res = tx_builder.build_tx(); + assert!(build_res.is_ok()); + + let tx = build_res.unwrap(); + assert_eq!(tx.witness_set.plutus_scripts.unwrap().len(), 1usize); + assert_eq!(tx.witness_set.redeemers.unwrap().len(), 2usize); + assert!(tx.witness_set.plutus_data.is_none()); + assert!(tx.body.reference_inputs.is_none()); + assert!(tx.body.mint.is_some()); + assert_eq!(tx.body.mint.unwrap().len(), 2usize); +} + +#[test] +fn multiple_plutus_inputs_test() { + let mut tx_builder = create_reallistic_tx_builder(); + let plutus_script = plutus::PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); + let redeemer1 = Redeemer::from_json( + "\ + { + \"tag\": \"Mint\", + \"index\": \"0\", + \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", + \"ex_units\": { + \"mem\": \"1042996\", + \"steps\": \"446100241\" + } + }", + ) + .unwrap(); + + let redeemer2 = Redeemer::from_json( + "\ + { + \"tag\": \"Mint\", + \"index\": \"0\", + \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", + \"ex_units\": { + \"mem\": \"1042996\", + \"steps\": \"446100241\" + } + }", + ) + .unwrap(); + + let mut in_builder = TxInputsBuilder::new(); + let input_1 = TransactionInput::new( + &TransactionHash::from_bytes( + hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") + .unwrap(), + ) + .unwrap(), + 1, + ); + let input_2 = TransactionInput::new( + &TransactionHash::from_bytes( + hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") + .unwrap(), + ) + .unwrap(), + 2, + ); + + let colateral_adress = Address::from_bech32("addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w").unwrap(); + let colateral_input = TransactionInput::new( + &TransactionHash::from_bytes( + hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") + .unwrap(), + ) + .unwrap(), + 3, + ); + + let output_adress = Address::from_bech32("addr_test1qpm5njmgzf4t7225v6j34wl30xfrufzt3jtqtdzf3en9ahpmnhtmynpasyc8fq75zv0uaj86vzsr7g3g8q5ypgu5fwtqr9zsgj").unwrap(); + let output_value = Value::new(&Coin::from(500000u64)); + let output = TransactionOutput::new(&output_adress, &output_value); + + tx_builder.add_output(&output); + let mut col_builder = TxInputsBuilder::new(); + col_builder.add_input( + &colateral_adress, + &colateral_input, + &Value::new(&Coin::from(1000000000u64)), + ); + tx_builder.set_collateral(&col_builder); + + let datum = PlutusData::new_bytes(fake_bytes_32(11)); + let plutus_wit1 = PlutusWitness::new(&plutus_script, &datum, &redeemer1); + + let plutus_wit2 = PlutusWitness::new(&plutus_script, &datum, &redeemer2); + + let value = Value::new(&Coin::from(100000000u64)); + + in_builder.add_plutus_script_input(&plutus_wit1, &input_1, &value); + in_builder.add_plutus_script_input(&plutus_wit2, &input_2, &value); + + tx_builder.set_inputs(&in_builder); + tx_builder.calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()); + tx_builder.add_change_if_needed(&output_adress); + let build_res = tx_builder.build_tx(); + assert!(&build_res.is_ok()); + let tx = build_res.unwrap(); + assert_eq!(tx.witness_set.plutus_scripts.unwrap().len(), 1usize); + assert_eq!(tx.witness_set.redeemers.unwrap().len(), 2usize); +} + +#[test] +fn multiple_plutus_inputs_with_missed_wit_test() { + let mut tx_builder = create_reallistic_tx_builder(); + let plutus_script = plutus::PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); + let redeemer1 = Redeemer::from_json( + "\ + { + \"tag\": \"Mint\", + \"index\": \"0\", + \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", + \"ex_units\": { + \"mem\": \"1042996\", + \"steps\": \"446100241\" + } + }", + ) + .unwrap(); + + let redeemer2 = Redeemer::from_json( + "\ + { + \"tag\": \"Mint\", + \"index\": \"0\", + \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", + \"ex_units\": { + \"mem\": \"1042996\", + \"steps\": \"446100241\" + } + }", + ) + .unwrap(); + + let mut in_builder = TxInputsBuilder::new(); + let input_1 = TransactionInput::new( + &TransactionHash::from_bytes( + hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") + .unwrap(), + ) + .unwrap(), + 1, + ); + let input_2 = TransactionInput::new( + &TransactionHash::from_bytes( + hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") + .unwrap(), + ) + .unwrap(), + 2, + ); + + let colateral_adress = Address::from_bech32("addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w").unwrap(); + let colateral_input = TransactionInput::new( + &TransactionHash::from_bytes( + hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") + .unwrap(), + ) + .unwrap(), + 3, + ); + + let output_adress = Address::from_bech32("addr_test1qpm5njmgzf4t7225v6j34wl30xfrufzt3jtqtdzf3en9ahpmnhtmynpasyc8fq75zv0uaj86vzsr7g3g8q5ypgu5fwtqr9zsgj").unwrap(); + let output_value = Value::new(&Coin::from(5000000u64)); + let output = TransactionOutput::new(&output_adress, &output_value); + + tx_builder.add_output(&output).unwrap(); + let mut col_builder = TxInputsBuilder::new(); + col_builder.add_input( + &colateral_adress, + &colateral_input, + &Value::new(&Coin::from(1000000000u64)), + ); + tx_builder.set_collateral(&col_builder); + + let datum = PlutusData::new_bytes(fake_bytes_32(11)); + let plutus_wit1 = PlutusWitness::new(&plutus_script, &datum, &redeemer1); + + let plutus_wit2 = PlutusWitness::new(&plutus_script, &datum, &redeemer2); + + let value = Value::new(&Coin::from(100000000u64)); + + in_builder.add_plutus_script_input(&plutus_wit1, &input_1, &value); + let script_addr = create_base_address_from_script_hash(&plutus_script.hash()); + in_builder.add_input(&script_addr, &input_2, &value); + + assert_eq!(in_builder.count_missing_input_scripts(), 1usize); + let mut inputs_with_wit = InputsWithScriptWitness::new(); + let in_with_wit = InputWithScriptWitness::new_with_plutus_witness(&input_2, &plutus_wit2); + inputs_with_wit.add(&in_with_wit); + in_builder.add_required_script_input_witnesses(&inputs_with_wit); + + tx_builder.set_inputs(&in_builder); + + tx_builder + .calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()) + .unwrap(); + tx_builder.add_change_if_needed(&output_adress).unwrap(); + let build_res = tx_builder.build_tx(); + assert!(&build_res.is_ok()); + let tx = build_res.unwrap(); + assert_eq!(tx.witness_set.plutus_scripts.unwrap().len(), 1usize); + assert_eq!(tx.witness_set.redeemers.unwrap().len(), 2usize); +} + +#[test] +fn build_tx_with_certs_withdrawals_plutus_script_address() { + let mut tx_builder = create_tx_builder_with_key_deposit(1_000_000); + let spend = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let change_key = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + let reward = root_key_15() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(3) + .derive(1) + .to_public(); + + let redeemer_cert1 = Redeemer::from_json( + "\ + { + \"tag\": \"Spend\", + \"index\": \"0\", + \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", + \"ex_units\": { + \"mem\": \"1\", + \"steps\": \"1\" + } + }", + ) + .unwrap(); + + let redeemer_cert2 = Redeemer::from_json( + "\ + { + \"tag\": \"Spend\", + \"index\": \"0\", + \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", + \"ex_units\": { + \"mem\": \"2\", + \"steps\": \"2\" + } + }", + ) + .unwrap(); + + let redeemer_cert3 = Redeemer::from_json( + "\ + { + \"tag\": \"Spend\", + \"index\": \"0\", + \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", + \"ex_units\": { + \"mem\": \"2\", + \"steps\": \"2\" + } + }", + ) + .unwrap(); + + let redeemer_withdraw1 = Redeemer::from_json( + "\ + { + \"tag\": \"Spend\", + \"index\": \"0\", + \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", + \"ex_units\": { + \"mem\": \"4\", + \"steps\": \"4\" + } + }", + ) + .unwrap(); + + let redeemer_withdraw2 = Redeemer::from_json( + "\ + { + \"tag\": \"Spend\", + \"index\": \"0\", + \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", + \"ex_units\": { + \"mem\": \"5\", + \"steps\": \"5\" + } + }", + ) + .unwrap(); + + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + tx_builder.add_key_input( + &spend.to_raw_key().hash(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(5_000_000)), + ); + tx_builder.set_ttl(1000); + let (cert_script1, cert_script_hash1) = plutus_script_and_hash(1); + let cert_script_cred1 = Credential::from_scripthash(&cert_script_hash1); + + let (cert_script2, cert_script_hash2) = plutus_script_and_hash(2); + let cert_script_cred2 = Credential::from_scripthash(&cert_script_hash2); + + let cert_script_hash3 = fake_script_hash(3); + let cert_script_cred3 = Credential::from_scripthash(&cert_script_hash3); + + let (withdraw_script1, withdraw_script_hash1) = plutus_script_and_hash(3); + let withdraw_script_cred1 = Credential::from_scripthash(&withdraw_script_hash1); + + let withdraw_script_hash2 = fake_script_hash(3); + let withdraw_script_cred2 = Credential::from_scripthash(&withdraw_script_hash2); + + let cert_witness_1 = PlutusWitness::new_without_datum(&cert_script1, &redeemer_cert1); + let cert_witness_2 = PlutusWitness::new_without_datum(&cert_script2, &redeemer_cert2); + + let ref_cert_script_input_3 = fake_tx_input(1); + let ref_cert_withdrawal_input_2 = fake_tx_input(2); + let plutus_cert_source = PlutusScriptSource::new_ref_input_with_lang_ver( + &cert_script_hash3, + &ref_cert_script_input_3, + &Language::new_plutus_v2(), + ); + let plutus_withdrawal_source = PlutusScriptSource::new_ref_input_with_lang_ver( + &withdraw_script_hash2, + &ref_cert_withdrawal_input_2, + &Language::new_plutus_v2(), + ); + + let cert_witness_3 = + PlutusWitness::new_with_ref_without_datum(&plutus_cert_source, &redeemer_cert3); + let withdraw_witness1 = + PlutusWitness::new_without_datum(&withdraw_script1, &redeemer_withdraw1); + let withdraw_witness2 = + PlutusWitness::new_with_ref_without_datum(&plutus_withdrawal_source, &redeemer_withdraw2); + + let mut certs = CertificatesBuilder::new(); + certs + .add(&Certificate::new_stake_registration( + &StakeRegistration::new(&stake_cred), + )) + .unwrap(); + certs + .add_with_plutus_witness( + &Certificate::new_stake_delegation(&StakeDelegation::new( + &cert_script_cred1, + &stake.to_raw_key().hash(), // in reality, this should be the pool owner's key, not ours + )), + &cert_witness_1, + ) + .unwrap(); + certs + .add_with_plutus_witness( + &Certificate::new_stake_delegation(&StakeDelegation::new( + &cert_script_cred2, + &stake.to_raw_key().hash(), // in reality, this should be the pool owner's key, not ours + )), + &cert_witness_2, + ) + .unwrap(); + certs + .add(&Certificate::new_stake_delegation(&StakeDelegation::new( + &stake_cred, + &stake.to_raw_key().hash(), // in reality, this should be the pool owner's key, not ours + ))) + .unwrap(); + certs + .add_with_plutus_witness( + &Certificate::new_stake_deregistration(&StakeDeregistration::new(&cert_script_cred3)), + &cert_witness_3, + ) + .unwrap(); + + tx_builder.set_certs_builder(&certs); + + let mut withdrawals = WithdrawalsBuilder::new(); + let reward_cred = Credential::from_keyhash(&reward.to_raw_key().hash()); + withdrawals + .add( + &RewardAddress::new(NetworkInfo::testnet().network_id(), &reward_cred), + &Coin::from(1u32), + ) + .unwrap(); + withdrawals + .add_with_plutus_witness( + &RewardAddress::new(NetworkInfo::testnet().network_id(), &withdraw_script_cred1), + &Coin::from(2u32), + &withdraw_witness1, + ) + .unwrap(); + withdrawals + .add_with_plutus_witness( + &RewardAddress::new(NetworkInfo::testnet().network_id(), &withdraw_script_cred2), + &Coin::from(3u32), + &withdraw_witness2, + ) + .unwrap(); + tx_builder.set_withdrawals_builder(&withdrawals); + + let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); + let change_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &change_cred, + &stake_cred, + ) + .to_address(); + let cost_models = TxBuilderConstants::plutus_default_cost_models(); + let collateral_input = fake_tx_input(1); + let collateral_addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &Credential::from_keyhash(&fake_key_hash(1)), + &Credential::from_keyhash(&fake_key_hash(2)), + ) + .to_address(); + let mut collateral_builder = TxInputsBuilder::new(); + collateral_builder.add_input( + &collateral_addr, + &collateral_input, + &Value::new(&Coin::from(123u32)), + ); + tx_builder.set_collateral(&collateral_builder); + tx_builder.calc_script_data_hash(&cost_models).unwrap(); + tx_builder.add_change_if_needed(&change_addr).unwrap(); + assert_eq!(tx_builder.outputs.len(), 1); + assert_eq!( + tx_builder + .get_explicit_input() + .unwrap() + .checked_add(&tx_builder.get_implicit_input().unwrap()) + .unwrap(), + tx_builder + .get_explicit_output() + .unwrap() + .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) + .unwrap() + .checked_add(&Value::new(&tx_builder.get_deposit().unwrap())) + .unwrap() + ); + let final_tx = tx_builder.build_tx().unwrap(); + let final_tx_body = final_tx.body(); + let final_tx_wits = final_tx.witness_set(); + + assert_eq!(final_tx_body.reference_inputs().unwrap().len(), 2); + assert_eq!(final_tx_body.withdrawals().unwrap().len(), 3); + assert_eq!(final_tx_body.certs().unwrap().len(), 5); + assert_eq!(final_tx_wits.plutus_scripts().unwrap().len(), 3); + assert_eq!(final_tx_wits.redeemers().unwrap().len(), 5); + + let certs = final_tx_body.certs().unwrap().0; + let withdraws = final_tx_body + .withdrawals() + .unwrap() + .0 + .iter() + .map(|(k, _)| k.clone()) + .collect::>(); + let redeemers = final_tx_wits.redeemers().unwrap(); + let mut indexes = HashMap::new(); + indexes.insert(RedeemerTag::new_cert(), HashSet::new()); + indexes.insert(RedeemerTag::new_reward(), HashSet::new()); + for redeemer in &redeemers.0 { + let tag_set = indexes.get_mut(&redeemer.tag()).unwrap(); + assert_ne!(tag_set.contains(&redeemer.index()), true); + tag_set.insert(redeemer.index()); + let index: usize = redeemer.index().into(); + if redeemer.tag().kind() == RedeemerTagKind::Cert { + let cert = &certs[index]; + assert!(cert.has_required_script_witness()); + } else if redeemer.tag().kind() == RedeemerTagKind::Reward { + let withdraw = &withdraws[index]; + assert!(withdraw.payment_cred().has_script_hash()); + } + } +} + +#[test] +pub fn test_extra_datum() { + let mut tx_builder = create_reallistic_tx_builder(); + tx_builder.set_fee(&to_bignum(42)); + + let datum = PlutusData::new_bytes(fake_bytes_32(1)); + tx_builder.add_extra_witness_datum(&datum); + + let mut inp = TxInputsBuilder::new(); + inp.add_input( + &fake_base_address(0), + &fake_tx_input(0), + &Value::new(&to_bignum(1000000u64)), + ); + + tx_builder.set_inputs(&inp); + tx_builder + .calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()) + .unwrap(); + + let res = tx_builder.build_tx(); + assert!(res.is_ok()); + + let tx = res.unwrap(); + + let data_hash = hash_script_data( + &Redeemers::new(), + &Costmdls::new(), + Some(PlutusList::from(vec![datum.clone()])), + ); + + let tx_builder_script_data_hash = tx_builder.script_data_hash.clone(); + assert_eq!(tx_builder_script_data_hash.unwrap(), data_hash); + + let extra_datums = tx_builder.get_extra_witness_datums().unwrap(); + assert_eq!(&extra_datums.get(0), &datum); + assert_eq!(extra_datums.len(), 1usize); + assert_eq!( + tx_builder.get_witness_set().plutus_data().unwrap().len(), + 1usize + ); + assert_eq!(tx.witness_set().plutus_data().unwrap().len(), 1usize); + assert_eq!(tx.witness_set().plutus_data().unwrap().get(0), datum); +} diff --git a/rust/src/tests/helpers.rs b/rust/src/tests/helpers.rs new file mode 100644 index 00000000..a6fbe831 --- /dev/null +++ b/rust/src/tests/helpers.rs @@ -0,0 +1,3 @@ +pub(crate) fn harden(index: u32) -> u32 { + index | 0x80_00_00_00 +} \ No newline at end of file diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/mock_objects.rs index 92aadff6..ad58cb59 100644 --- a/rust/src/tests/mock_objects.rs +++ b/rust/src/tests/mock_objects.rs @@ -1,5 +1,12 @@ use crate::fakes::{fake_anchor_data_hash, fake_key_hash, fake_pool_metadata_hash, fake_tx_hash, fake_vrf_key_hash}; use crate::*; +use crate::fees::LinearFee; +use crate::tx_builder::{TransactionBuilder, TransactionBuilderConfigBuilder}; + +const MAX_VALUE_SIZE: u32 = 4000; +const MAX_TX_SIZE: u32 = 8000; // might be out of date but suffices for our tests +// this is what is used in mainnet +static COINS_PER_UTXO_WORD: u64 = 34_482; pub(crate) fn crate_full_protocol_param_update() -> ProtocolParamUpdate { ProtocolParamUpdate { @@ -94,4 +101,100 @@ pub(crate) fn create_anchor() -> Anchor { pub(crate) fn create_action_id() -> GovernanceActionId { GovernanceActionId::new(&fake_tx_hash(1), 1) -} \ No newline at end of file +} +pub(crate) fn byron_address() -> Address { + ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") + .unwrap() + .to_address() +} + +pub(crate) fn create_linear_fee(coefficient: u64, constant: u64) -> LinearFee { + LinearFee::new(&to_bignum(coefficient), &to_bignum(constant)) +} + +pub(crate) fn create_default_linear_fee() -> LinearFee { + create_linear_fee(500, 2) +} + +pub(crate) fn create_tx_builder_full( + linear_fee: &LinearFee, + pool_deposit: u64, + key_deposit: u64, + max_val_size: u32, + coins_per_utxo_word: u64, +) -> TransactionBuilder { + let cfg = TransactionBuilderConfigBuilder::new() + .fee_algo(linear_fee) + .pool_deposit(&to_bignum(pool_deposit)) + .key_deposit(&to_bignum(key_deposit)) + .voting_proposal_deposit(&to_bignum(500000000)) + .max_value_size(max_val_size) + .max_tx_size(MAX_TX_SIZE) + .coins_per_utxo_word(&to_bignum(coins_per_utxo_word)) + .ex_unit_prices(&ExUnitPrices::new( + &SubCoin::new(&to_bignum(577), &to_bignum(10000)), + &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + )) + .build() + .unwrap(); + TransactionBuilder::new(&cfg) +} + +pub(crate) fn create_tx_builder( + linear_fee: &LinearFee, + coins_per_utxo_word: u64, + pool_deposit: u64, + key_deposit: u64, +) -> TransactionBuilder { + create_tx_builder_full( + linear_fee, + pool_deposit, + key_deposit, + MAX_VALUE_SIZE, + coins_per_utxo_word, + ) +} + +pub(crate) fn create_reallistic_tx_builder() -> TransactionBuilder { + create_tx_builder( + &create_linear_fee(44, 155381), + COINS_PER_UTXO_WORD, + 500000000, + 2000000, + ) +} + +pub(crate) fn create_tx_builder_with_fee_and_val_size( + linear_fee: &LinearFee, + max_val_size: u32, +) -> TransactionBuilder { + create_tx_builder_full(linear_fee, 1, 1, max_val_size, 8) +} + +pub(crate) fn create_tx_builder_with_fee(linear_fee: &LinearFee) -> TransactionBuilder { + create_tx_builder(linear_fee, 8, 1, 1) +} + +pub(crate) fn create_tx_builder_with_fee_and_pure_change(linear_fee: &LinearFee) -> TransactionBuilder { + TransactionBuilder::new( + &TransactionBuilderConfigBuilder::new() + .fee_algo(linear_fee) + .pool_deposit(&to_bignum(1)) + .key_deposit(&to_bignum(1)) + .voting_proposal_deposit(&to_bignum(1)) + .max_value_size(MAX_VALUE_SIZE) + .max_tx_size(MAX_TX_SIZE) + .coins_per_utxo_word(&to_bignum(8)) + .prefer_pure_change(true) + .build() + .unwrap(), + ) +} + +pub(crate) fn create_tx_builder_with_key_deposit(deposit: u64) -> TransactionBuilder { + create_tx_builder(&create_default_linear_fee(), 8, 1, deposit) +} + +pub(crate) fn create_default_tx_builder() -> TransactionBuilder { + create_tx_builder_with_fee(&create_default_linear_fee()) +} diff --git a/rust/src/tests/mod.rs b/rust/src/tests/mod.rs index 2523e697..3dc72167 100644 --- a/rust/src/tests/mod.rs +++ b/rust/src/tests/mod.rs @@ -3,4 +3,5 @@ mod general; mod address; mod mock_objects; mod protocol_types; -mod builders; \ No newline at end of file +mod builders; +mod helpers; \ No newline at end of file diff --git a/rust/src/tx_builder.rs b/rust/src/tx_builder.rs index 4a1ad06b..bd889f37 100644 --- a/rust/src/tx_builder.rs +++ b/rust/src/tx_builder.rs @@ -1,8 +1,5 @@ #![allow(deprecated)] -#[cfg(test)] -mod test_batch; - pub mod tx_inputs_builder; pub mod tx_batch_builder; pub mod mint_builder; @@ -11,7 +8,7 @@ pub mod withdrawals_builder; pub mod voting_proposal_builder; pub mod voting_builder; mod batch_tools; -mod script_structs; +pub(crate) mod script_structs; use super::fees; @@ -81,7 +78,7 @@ fn count_needed_vkeys(tx_builder: &TransactionBuilder) -> usize { // tx_body must be the result of building from tx_builder // constructs the rest of the Transaction using fake witness data of the correct length // for use in calculating the size of the final Transaction -fn fake_full_tx( +pub(crate) fn fake_full_tx( tx_builder: &TransactionBuilder, body: TransactionBody, ) -> Result { @@ -201,19 +198,19 @@ pub enum CoinSelectionStrategyCIP2 { #[wasm_bindgen] #[derive(Clone, Debug)] pub struct TransactionBuilderConfig { - fee_algo: fees::LinearFee, - pool_deposit: Coin, // protocol parameter - key_deposit: Coin, // protocol parameter - voting_proposal_deposit: Coin, // protocol parameter - max_value_size: u32, // protocol parameter - max_tx_size: u32, // protocol parameter - data_cost: DataCost, // protocol parameter - ex_unit_prices: Option, // protocol parameter - prefer_pure_change: bool, + pub(crate) fee_algo: fees::LinearFee, + pub(crate) pool_deposit: Coin, // protocol parameter + pub(crate) key_deposit: Coin, // protocol parameter + pub(crate) voting_proposal_deposit: Coin, // protocol parameter + pub(crate) max_value_size: u32, // protocol parameter + pub(crate) max_tx_size: u32, // protocol parameter + pub(crate) data_cost: DataCost, // protocol parameter + pub(crate) ex_unit_prices: Option, // protocol parameter + pub(crate) prefer_pure_change: bool, } impl TransactionBuilderConfig { - fn utxo_cost(&self) -> DataCost { + pub(crate) fn utxo_cost(&self) -> DataCost { self.data_cost.clone() } } @@ -349,25 +346,25 @@ impl TransactionBuilderConfigBuilder { #[wasm_bindgen] #[derive(Clone, Debug)] pub struct TransactionBuilder { - config: TransactionBuilderConfig, - inputs: TxInputsBuilder, - collateral: TxInputsBuilder, - outputs: TransactionOutputs, - fee: Option, - ttl: Option, // absolute slot number - certs: Option, - withdrawals: Option, - auxiliary_data: Option, - validity_start_interval: Option, - mint: Option, - script_data_hash: Option, - required_signers: Ed25519KeyHashes, - collateral_return: Option, - total_collateral: Option, - reference_inputs: HashSet, - extra_datums: Option, - voting_procedures: Option, - voting_proposals: Option, + pub(crate) config: TransactionBuilderConfig, + pub(crate) inputs: TxInputsBuilder, + pub(crate) collateral: TxInputsBuilder, + pub(crate) outputs: TransactionOutputs, + pub(crate) fee: Option, + pub(crate) ttl: Option, // absolute slot number + pub(crate) certs: Option, + pub(crate) withdrawals: Option, + pub(crate) auxiliary_data: Option, + pub(crate) validity_start_interval: Option, + pub(crate) mint: Option, + pub(crate) script_data_hash: Option, + pub(crate) required_signers: Ed25519KeyHashes, + pub(crate) collateral_return: Option, + pub(crate) total_collateral: Option, + pub(crate) reference_inputs: HashSet, + pub(crate) extra_datums: Option, + pub(crate) voting_procedures: Option, + pub(crate) voting_proposals: Option, } #[wasm_bindgen] @@ -2052,7 +2049,7 @@ impl TransactionBuilder { // that is created by the tx-builder itself, // before the transaction is getting signed by the actual wallet. // E.g. scripts or something else that has been used during the tx preparation - fn get_witness_set(&self) -> TransactionWitnessSet { + pub(crate) fn get_witness_set(&self) -> TransactionWitnessSet { let mut wit = TransactionWitnessSet::new(); if let Some(scripts) = self.get_combined_native_scripts() { wit.set_native_scripts(&scripts); @@ -2151,6490 +2148,4 @@ impl TransactionBuilder { self_copy.set_fee(&to_bignum(0x1_00_00_00_00)); min_fee(&self_copy) } -} - -#[cfg(test)] -mod tests { - use super::output_builder::TransactionOutputBuilder; - use super::*; - use crate::fakes::{fake_base_address, fake_bytes_32, fake_data_hash, fake_key_hash, fake_policy_id, fake_script_hash, fake_tx_hash, fake_tx_input, fake_tx_input2, fake_value, fake_value2}; - use crate::tx_builder_constants::TxBuilderConstants; - use fees::*; - use crate::tx_builder::script_structs::{PlutusScriptSource}; - use crate::tx_builder::tx_inputs_builder::{InputsWithScriptWitness, InputWithScriptWitness }; - - const MAX_VALUE_SIZE: u32 = 4000; - const MAX_TX_SIZE: u32 = 8000; // might be out of date but suffices for our tests - // this is what is used in mainnet - static COINS_PER_UTXO_WORD: u64 = 34_482; - - fn genesis_id() -> TransactionHash { - TransactionHash::from([0u8; TransactionHash::BYTE_COUNT]) - } - - fn root_key_15() -> Bip32PrivateKey { - // art forum devote street sure rather head chuckle guard poverty release quote oak craft enemy - let entropy = [ - 0x0c, 0xcb, 0x74, 0xf3, 0x6b, 0x7d, 0xa1, 0x64, 0x9a, 0x81, 0x44, 0x67, 0x55, 0x22, - 0xd4, 0xd8, 0x09, 0x7c, 0x64, 0x12, - ]; - Bip32PrivateKey::from_bip39_entropy(&entropy, &[]) - } - - fn harden(index: u32) -> u32 { - index | 0x80_00_00_00 - } - - #[test] - fn check_fake_private_key() { - let fpk = fake_private_key(); - assert_eq!( - fpk.to_bech32(), - "xprv1hretan5mml3tq2p0twkhq4tz4jvka7m2l94kfr6yghkyfar6m9wppc7h9unw6p65y23kakzct3695rs32z7vaw3r2lg9scmfj8ec5du3ufydu5yuquxcz24jlkjhsc9vsa4ufzge9s00fn398svhacse5su2awrw", - ); - assert_eq!( - fpk.to_public().to_bech32(), - "xpub1eamrnx3pph58yr5l4z2wghjpu2dt2f0rp0zq9qquqa39p52ct0xercjgmegfcpcdsy4t9ld90ps2epmtcjy3jtq77n8z20qe0m3pnfqntgrgj", - ); - } - - fn byron_address() -> Address { - ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") - .unwrap() - .to_address() - } - - fn create_linear_fee(coefficient: u64, constant: u64) -> LinearFee { - LinearFee::new(&to_bignum(coefficient), &to_bignum(constant)) - } - - fn create_default_linear_fee() -> LinearFee { - create_linear_fee(500, 2) - } - - fn create_tx_builder_full( - linear_fee: &LinearFee, - pool_deposit: u64, - key_deposit: u64, - max_val_size: u32, - coins_per_utxo_word: u64, - ) -> TransactionBuilder { - let cfg = TransactionBuilderConfigBuilder::new() - .fee_algo(linear_fee) - .pool_deposit(&to_bignum(pool_deposit)) - .key_deposit(&to_bignum(key_deposit)) - .voting_proposal_deposit(&to_bignum(500000000)) - .max_value_size(max_val_size) - .max_tx_size(MAX_TX_SIZE) - .coins_per_utxo_word(&to_bignum(coins_per_utxo_word)) - .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), - )) - .build() - .unwrap(); - TransactionBuilder::new(&cfg) - } - - fn create_tx_builder( - linear_fee: &LinearFee, - coins_per_utxo_word: u64, - pool_deposit: u64, - key_deposit: u64, - ) -> TransactionBuilder { - create_tx_builder_full( - linear_fee, - pool_deposit, - key_deposit, - MAX_VALUE_SIZE, - coins_per_utxo_word, - ) - } - - fn create_reallistic_tx_builder() -> TransactionBuilder { - create_tx_builder( - &create_linear_fee(44, 155381), - COINS_PER_UTXO_WORD, - 500000000, - 2000000, - ) - } - - fn create_tx_builder_with_fee_and_val_size( - linear_fee: &LinearFee, - max_val_size: u32, - ) -> TransactionBuilder { - create_tx_builder_full(linear_fee, 1, 1, max_val_size, 8) - } - - fn create_tx_builder_with_fee(linear_fee: &LinearFee) -> TransactionBuilder { - create_tx_builder(linear_fee, 8, 1, 1) - } - - fn create_tx_builder_with_fee_and_pure_change(linear_fee: &LinearFee) -> TransactionBuilder { - TransactionBuilder::new( - &TransactionBuilderConfigBuilder::new() - .fee_algo(linear_fee) - .pool_deposit(&to_bignum(1)) - .key_deposit(&to_bignum(1)) - .voting_proposal_deposit(&to_bignum(1)) - .max_value_size(MAX_VALUE_SIZE) - .max_tx_size(MAX_TX_SIZE) - .coins_per_utxo_word(&to_bignum(8)) - .prefer_pure_change(true) - .build() - .unwrap(), - ) - } - - fn create_tx_builder_with_key_deposit(deposit: u64) -> TransactionBuilder { - create_tx_builder(&create_default_linear_fee(), 8, 1, deposit) - } - - fn create_default_tx_builder() -> TransactionBuilder { - create_tx_builder_with_fee(&create_default_linear_fee()) - } - - #[test] - fn build_tx_with_change() { - let mut tx_builder = create_default_tx_builder(); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - tx_builder.add_key_input( - &spend.to_raw_key().hash(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_net_0) - .next() - .unwrap() - .with_coin(&to_bignum(222)) - .build() - .unwrap(), - ) - .unwrap(); - tx_builder.set_ttl(1000); - - let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); - let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - let added_change = tx_builder.add_change_if_needed(&change_addr); - assert!(added_change.unwrap()); - assert_eq!(tx_builder.outputs.len(), 2); - assert_eq!( - tx_builder - .get_explicit_input() - .unwrap() - .checked_add(&tx_builder.get_implicit_input().unwrap()) - .unwrap(), - tx_builder - .get_explicit_output() - .unwrap() - .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) - .unwrap() - ); - assert_eq!(tx_builder.full_size().unwrap(), 285); - assert_eq!(tx_builder.output_sizes(), vec![62, 65]); - let _final_tx = tx_builder.build(); // just test that it doesn't throw - } - - #[test] - fn build_tx_with_change_with_datum() { - let mut tx_builder = create_default_tx_builder(); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - tx_builder.add_key_input( - &spend.to_raw_key().hash(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_net_0) - .next() - .unwrap() - .with_coin(&to_bignum(222)) - .build() - .unwrap(), - ) - .unwrap(); - tx_builder.set_ttl(1000); - - let datum_hash = fake_data_hash(20); - let data_option = OutputDatum::new_data_hash(&datum_hash); - let (_, script_hash) = plutus_script_and_hash(15); - let change_cred = Credential::from_scripthash(&script_hash); - let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - let added_change = tx_builder.add_change_if_needed_with_datum(&change_addr, &data_option); - assert!(added_change.unwrap()); - assert_eq!(tx_builder.outputs.len(), 2); - assert_eq!( - tx_builder - .get_explicit_input() - .unwrap() - .checked_add(&tx_builder.get_implicit_input().unwrap()) - .unwrap(), - tx_builder - .get_explicit_output() - .unwrap() - .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) - .unwrap() - ); - assert_eq!(tx_builder.full_size().unwrap(), 319); - assert_eq!(tx_builder.output_sizes(), vec![62, 99]); - let _final_tx = tx_builder.build(); // just test that it doesn't throw - } - - #[test] - fn build_tx_without_change() { - let mut tx_builder = create_default_tx_builder(); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - tx_builder.add_key_input( - &spend.to_raw_key().hash(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_net_0) - .next() - .unwrap() - .with_coin(&to_bignum(880_000)) - .build() - .unwrap(), - ) - .unwrap(); - tx_builder.set_ttl(1000); - - let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); - let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - let added_change = tx_builder.add_change_if_needed(&change_addr); - assert!(!added_change.unwrap()); - assert_eq!(tx_builder.outputs.len(), 1); - assert_eq!( - tx_builder - .get_explicit_input() - .unwrap() - .checked_add(&tx_builder.get_implicit_input().unwrap()) - .unwrap(), - tx_builder - .get_explicit_output() - .unwrap() - .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) - .unwrap() - ); - let _final_tx = tx_builder.build(); // just test that it doesn't throw - } - - #[test] - fn build_tx_with_certs() { - let mut tx_builder = create_tx_builder_with_key_deposit(1_000_000); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - tx_builder.add_key_input( - &spend.to_raw_key().hash(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(5_000_000)), - ); - tx_builder.set_ttl(1000); - - let mut certs = Certificates::new(); - certs.add(&Certificate::new_stake_registration( - &StakeRegistration::new(&stake_cred), - )); - certs.add(&Certificate::new_stake_delegation(&StakeDelegation::new( - &stake_cred, - &stake.to_raw_key().hash(), // in reality, this should be the pool owner's key, not ours - ))); - tx_builder.set_certs(&certs).unwrap(); - - let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); - let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - tx_builder.add_change_if_needed(&change_addr).unwrap(); - assert_eq!(tx_builder.min_fee().unwrap().to_str(), "214002"); - assert_eq!(tx_builder.get_fee_if_set().unwrap().to_str(), "214002"); - assert_eq!(tx_builder.get_deposit().unwrap().to_str(), "1000000"); - assert_eq!(tx_builder.outputs.len(), 1); - assert_eq!( - tx_builder - .get_explicit_input() - .unwrap() - .checked_add(&tx_builder.get_implicit_input().unwrap()) - .unwrap(), - tx_builder - .get_explicit_output() - .unwrap() - .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) - .unwrap() - .checked_add(&Value::new(&tx_builder.get_deposit().unwrap())) - .unwrap() - ); - let _final_tx = tx_builder.build(); // just test that it doesn't throw - } - - #[test] - fn build_tx_exact_amount() { - // transactions where sum(input) == sum(output) exact should pass - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 0)); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - tx_builder.add_key_input( - &&spend.to_raw_key().hash(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(222)), - ); - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_net_0) - .next() - .unwrap() - .with_coin(&to_bignum(222)) - .build() - .unwrap(), - ) - .unwrap(); - tx_builder.set_ttl(0); - - let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); - let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - let added_change = tx_builder.add_change_if_needed(&change_addr).unwrap(); - assert_eq!(added_change, false); - let final_tx = tx_builder.build().unwrap(); - assert_eq!(final_tx.outputs().len(), 1); - } - - #[test] - fn build_tx_exact_change() { - // transactions where we have exactly enough ADA to add change should pass - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 0)); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - tx_builder.add_key_input( - &&spend.to_raw_key().hash(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(700)), - ); - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_net_0) - .next() - .unwrap() - .with_coin(&to_bignum(222)) - .build() - .unwrap(), - ) - .unwrap(); - tx_builder.set_ttl(0); - - let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); - let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - let added_change = tx_builder.add_change_if_needed(&change_addr).unwrap(); - assert_eq!(added_change, true); - let final_tx = tx_builder.build().unwrap(); - assert_eq!(final_tx.outputs().len(), 2); - assert_eq!(final_tx.outputs().get(1).amount().coin().to_str(), "478"); - } - - #[test] - #[should_panic] - fn build_tx_insufficient_deposit() { - // transactions should fail with insufficient fees if a deposit is required - let mut tx_builder = create_tx_builder_with_key_deposit(5); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - tx_builder.add_key_input( - &&spend.to_raw_key().hash(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(5)), - ); - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_net_0) - .next() - .unwrap() - .with_coin(&to_bignum(5)) - .build() - .unwrap(), - ) - .unwrap(); - tx_builder.set_ttl(0); - - // add a cert which requires a deposit - let mut certs = Certificates::new(); - certs.add(&Certificate::new_stake_registration( - &StakeRegistration::new(&stake_cred), - )); - tx_builder.set_certs(&certs); - - let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); - let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - - tx_builder.add_change_if_needed(&change_addr).unwrap(); - } - - #[test] - fn build_tx_with_inputs() { - let mut tx_builder = create_default_tx_builder(); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - - { - assert_eq!( - tx_builder - .fee_for_input( - &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred) - .to_address(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)) - ) - .unwrap() - .to_str(), - "69500" - ); - tx_builder.add_input( - &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred) - .to_address(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - } - tx_builder.add_input( - &BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(), - &TransactionInput::new(&genesis_id(), 1), - &Value::new(&to_bignum(1_000_000)), - ); - tx_builder.add_input( - &PointerAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &Pointer::new_pointer(&to_bignum(0), &to_bignum(0), &to_bignum(0)), - ) - .to_address(), - &TransactionInput::new(&genesis_id(), 2), - &Value::new(&to_bignum(1_000_000)), - ); - tx_builder.add_input( - &ByronAddress::icarus_from_key(&spend, NetworkInfo::testnet().protocol_magic()) - .to_address(), - &TransactionInput::new(&genesis_id(), 3), - &Value::new(&to_bignum(1_000_000)), - ); - - assert_eq!(tx_builder.inputs.len(), 4); - } - - #[test] - fn add_ref_inputs_to_builder() { - let mut tx_builder = create_default_tx_builder(); - - tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 1)); - tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 2)); - tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 3)); - tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 4)); - - assert_eq!(tx_builder.reference_inputs.len(), 4); - } - - #[test] - fn build_tx_with_script_ref() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - - tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 1)); - tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 2)); - tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 3)); - tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 4)); - - tx_builder.add_input( - &PointerAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &Pointer::new_pointer(&to_bignum(0), &to_bignum(0), &to_bignum(0)), - ) - .to_address(), - &TransactionInput::new(&genesis_id(), 2), - &Value::new(&to_bignum(1_000_000)), - ); - - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - - let output_amount = Value::new(&to_bignum(500)); - - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_net_0) - .next() - .unwrap() - .with_value(&output_amount) - .build() - .unwrap(), - ) - .unwrap(); - - let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); - let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - - let added_change = tx_builder.add_change_if_needed(&change_addr).unwrap(); - assert_eq!(added_change, true); - let final_tx = tx_builder.build().unwrap(); - assert_eq!(final_tx.outputs().len(), 2); - assert_eq!(final_tx.reference_inputs().unwrap().len(), 4); - assert_eq!(final_tx.outputs().get(1).amount().coin(), to_bignum(999499)); - } - - #[test] - fn serialization_tx_body_with_script_ref() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - - tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 1)); - tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 2)); - tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 3)); - tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 4)); - - tx_builder.add_input( - &PointerAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &Pointer::new_pointer(&to_bignum(0), &to_bignum(0), &to_bignum(0)), - ) - .to_address(), - &TransactionInput::new(&genesis_id(), 2), - &Value::new(&to_bignum(1_000_000)), - ); - - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - - let output_amount = Value::new(&to_bignum(500)); - - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_net_0) - .next() - .unwrap() - .with_value(&output_amount) - .build() - .unwrap(), - ) - .unwrap(); - - let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); - let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - - tx_builder.add_change_if_needed(&change_addr).unwrap(); - let final_tx = tx_builder.build().unwrap(); - - let deser_t = TransactionBody::from_bytes(final_tx.to_bytes()).unwrap(); - - assert_eq!(deser_t.to_bytes(), final_tx.to_bytes()); - } - - #[test] - fn json_serialization_tx_body_with_script_ref() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - - tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 1)); - tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 2)); - tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 3)); - tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 4)); - - tx_builder.add_input( - &PointerAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &Pointer::new_pointer(&to_bignum(0), &to_bignum(0), &to_bignum(0)), - ) - .to_address(), - &TransactionInput::new(&genesis_id(), 2), - &Value::new(&to_bignum(1_000_000)), - ); - - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - - let output_amount = Value::new(&to_bignum(500)); - - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_net_0) - .next() - .unwrap() - .with_value(&output_amount) - .build() - .unwrap(), - ) - .unwrap(); - - let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); - let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - - tx_builder.add_change_if_needed(&change_addr).unwrap(); - let final_tx = tx_builder.build().unwrap(); - - let json_tx_body = final_tx.to_json().unwrap(); - let deser_t = TransactionBody::from_json(json_tx_body.as_str()).unwrap(); - - assert_eq!(deser_t.to_bytes(), final_tx.to_bytes()); - assert_eq!(deser_t.to_json().unwrap(), final_tx.to_json().unwrap()); - } - - #[test] - fn build_tx_with_mint_all_sent() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - - // Input with 150 coins - tx_builder.add_input( - &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(500)), - ); - - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - - let (min_script, policy_id) = mint_script_and_policy(0); - let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - let amount = to_bignum(1234); - - // Adding mint of the asset - which should work as an input - tx_builder.add_mint_asset(&min_script, &name, Int::new(&amount)); - - let mut ass = Assets::new(); - ass.insert(&name, &amount); - let mut mass = MultiAsset::new(); - mass.insert(&policy_id, &ass); - - // One coin and the minted asset goes into the output - let mut output_amount = Value::new(&to_bignum(264)); - output_amount.set_multiasset(&mass); - - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_net_0) - .next() - .unwrap() - .with_value(&output_amount) - .build() - .unwrap(), - ) - .unwrap(); - - let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); - let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - - let added_change = tx_builder.add_change_if_needed(&change_addr).unwrap(); - assert!(added_change); - assert_eq!(tx_builder.outputs.len(), 2); - - // Change must be one remaining coin because fee is one constant coin - let change = tx_builder.outputs.get(1).amount(); - assert_eq!(change.coin(), to_bignum(235)); - assert!(change.multiasset().is_none()); - } - - #[test] - fn build_tx_with_mint_in_change() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - - // Input with 600 coins - tx_builder.add_input( - &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(600)), - ); - - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - - let (min_script, policy_id) = mint_script_and_policy(0); - let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - - let amount_minted = to_bignum(1000); - let amount_sent = to_bignum(500); - - // Adding mint of the asset - which should work as an input - tx_builder.add_mint_asset(&min_script, &name, Int::new(&amount_minted)); - - let mut ass = Assets::new(); - ass.insert(&name, &amount_sent); - let mut mass = MultiAsset::new(); - mass.insert(&policy_id, &ass); - - // One coin and the minted asset goes into the output - let mut output_amount = Value::new(&to_bignum(300)); - output_amount.set_multiasset(&mass); - - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_net_0) - .next() - .unwrap() - .with_value(&output_amount) - .build() - .unwrap(), - ) - .unwrap(); - - let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); - let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - - let added_change = tx_builder.add_change_if_needed(&change_addr).unwrap(); - assert!(added_change); - assert_eq!(tx_builder.outputs.len(), 2); - - // Change must be one remaining coin because fee is one constant coin - let change = tx_builder.outputs.get(1).amount(); - assert_eq!(change.coin(), to_bignum(299)); - assert!(change.multiasset().is_some()); - - let change_assets = change.multiasset().unwrap(); - let change_asset = change_assets.get(&policy_id).unwrap(); - assert_eq!( - change_asset.get(&name).unwrap(), - amount_minted.checked_sub(&amount_sent).unwrap(), - ); - } - - #[test] - fn change_with_input_and_mint_not_enough_ada() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(1, 1)); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - - let (min_script, policy_id) = mint_script_and_policy(0); - let asset_name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - - let amount_minted = to_bignum(1000); - let amount_sent = to_bignum(500); - let amount_input_amount = to_bignum(600); - - let mut asset_input = Assets::new(); - asset_input.insert(&asset_name, &amount_input_amount); - let mut mass_input = MultiAsset::new(); - mass_input.insert(&policy_id, &asset_input); - - // Input with 600 coins - tx_builder.add_input( - &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(600)), - ); - - tx_builder.add_input( - &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), - &TransactionInput::new(&genesis_id(), 1), - &Value::new_with_assets(&to_bignum(1), &mass_input), - ); - - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ).to_address(); - - // Adding mint of the asset - which should work as an input - tx_builder.add_mint_asset(&min_script, &asset_name, Int::new(&amount_minted)); - - let mut asset = Assets::new(); - asset.insert(&asset_name, &amount_sent); - let mut mass = MultiAsset::new(); - mass.insert(&policy_id, &asset); - - // One coin and the minted asset goes into the output - let mut output_amount = Value::new(&to_bignum(400)); - output_amount.set_multiasset(&mass); - - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_net_0) - .next() - .unwrap() - .with_value(&output_amount) - .build() - .unwrap(), - ) - .unwrap(); - - let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); - let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - - let added_change = tx_builder.add_change_if_needed(&change_addr); - assert!(added_change.is_err()); - } - - #[test] - fn change_with_input_and_mint_not_enough_assets() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(1, 1)); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - - let (min_script, policy_id) = mint_script_and_policy(0); - let asset_name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - - let amount_minted = to_bignum(1000); - let amount_sent = to_bignum(100000); - let amount_input_amount = to_bignum(600); - - let mut asset_input = Assets::new(); - asset_input.insert(&asset_name, &amount_input_amount); - let mut mass_input = MultiAsset::new(); - mass_input.insert(&policy_id, &asset_input); - - // Input with 600 coins - tx_builder.add_input( - &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(100000)), - ); - - tx_builder.add_input( - &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), - &TransactionInput::new(&genesis_id(), 1), - &Value::new_with_assets(&to_bignum(1), &mass_input), - ); - - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ).to_address(); - - // Adding mint of the asset - which should work as an input - tx_builder.add_mint_asset(&min_script, &asset_name, Int::new(&amount_minted)); - - let mut asset = Assets::new(); - asset.insert(&asset_name, &amount_sent); - let mut mass = MultiAsset::new(); - mass.insert(&policy_id, &asset); - - // One coin and the minted asset goes into the output - let mut output_amount = Value::new(&to_bignum(400)); - output_amount.set_multiasset(&mass); - - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_net_0) - .next() - .unwrap() - .with_value(&output_amount) - .build() - .unwrap(), - ) - .unwrap(); - - let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); - let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - - let added_change = tx_builder.add_change_if_needed(&change_addr); - assert!(added_change.is_err()); - } - - #[test] - fn build_tx_with_native_assets_change() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - - let policy_id = &PolicyID::from([0u8; 28]); - let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - - let ma_input1 = 100; - let ma_input2 = 200; - let ma_output1 = 60; - - let multiassets = [ma_input1, ma_input2, ma_output1] - .iter() - .map(|input| { - let mut multiasset = MultiAsset::new(); - multiasset.insert(policy_id, &{ - let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(*input)); - assets - }); - multiasset - }) - .collect::>(); - - for (i, (multiasset, ada)) in multiassets - .iter() - .zip([100u64, 1000].iter().cloned().map(to_bignum)) - .enumerate() - { - let mut input_amount = Value::new(&ada); - input_amount.set_multiasset(multiasset); - - tx_builder.add_key_input( - &&spend.to_raw_key().hash(), - &TransactionInput::new(&genesis_id(), i as u32), - &input_amount, - ); - } - - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - - let mut output_amount = Value::new(&to_bignum(500)); - output_amount.set_multiasset(&multiassets[2]); - - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_net_0) - .next() - .unwrap() - .with_value(&output_amount) - .build() - .unwrap(), - ) - .unwrap(); - - let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); - let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - - let added_change = tx_builder.add_change_if_needed(&change_addr).unwrap(); - assert_eq!(added_change, true); - let final_tx = tx_builder.build().unwrap(); - assert_eq!(final_tx.outputs().len(), 2); - assert_eq!( - final_tx - .outputs() - .get(1) - .amount() - .multiasset() - .unwrap() - .get(policy_id) - .unwrap() - .get(&name) - .unwrap(), - to_bignum(ma_input1 + ma_input2 - ma_output1) - ); - assert_eq!(final_tx.outputs().get(1).amount().coin(), to_bignum(599)); - } - - #[test] - fn build_tx_with_native_assets_change_and_purification() { - let coin_per_utxo_word = to_bignum(8); - // Prefer pure change! - let mut tx_builder = create_tx_builder_with_fee_and_pure_change(&create_linear_fee(0, 1)); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - - let policy_id = &PolicyID::from([0u8; 28]); - let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - - let ma_input1 = 100; - let ma_input2 = 200; - let ma_output1 = 60; - - let multiassets = [ma_input1, ma_input2, ma_output1] - .iter() - .map(|input| { - let mut multiasset = MultiAsset::new(); - multiasset.insert(policy_id, &{ - let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(*input)); - assets - }); - multiasset - }) - .collect::>(); - - for (i, (multiasset, ada)) in multiassets - .iter() - .zip([100u64, 1000].iter().cloned().map(to_bignum)) - .enumerate() - { - let mut input_amount = Value::new(&ada); - input_amount.set_multiasset(multiasset); - - tx_builder.add_key_input( - &&spend.to_raw_key().hash(), - &TransactionInput::new(&genesis_id(), i as u32), - &input_amount, - ); - } - - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - - let mut output_amount = Value::new(&to_bignum(600)); - output_amount.set_multiasset(&multiassets[2]); - - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_net_0) - .next() - .unwrap() - .with_value(&output_amount) - .build() - .unwrap(), - ) - .unwrap(); - - let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); - let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - - let added_change = tx_builder.add_change_if_needed(&change_addr).unwrap(); - assert_eq!(added_change, true); - let final_tx = tx_builder.build().unwrap(); - assert_eq!(final_tx.outputs().len(), 3); - assert_eq!(final_tx.outputs().get(0).amount().coin(), to_bignum(600)); - assert_eq!( - final_tx - .outputs() - .get(1) - .amount() - .multiasset() - .unwrap() - .get(policy_id) - .unwrap() - .get(&name) - .unwrap(), - to_bignum(ma_input1 + ma_input2 - ma_output1) - ); - // The first change output that contains all the tokens contain minimum required Coin - let min_coin_for_dirty_change = min_ada_required( - &final_tx.outputs().get(1).amount(), - false, - &coin_per_utxo_word, - ) - .unwrap(); - assert_eq!( - final_tx.outputs().get(1).amount().coin(), - min_coin_for_dirty_change - ); - assert_eq!(final_tx.outputs().get(2).amount().coin(), to_bignum(236)); - assert_eq!(final_tx.outputs().get(2).amount().multiasset(), None); - } - - #[test] - fn build_tx_with_native_assets_change_and_no_purification_cuz_not_enough_pure_coin() { - // Prefer pure change! - let mut tx_builder = create_tx_builder_with_fee_and_pure_change(&create_linear_fee(1, 1)); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - - let policy_id = &PolicyID::from([0u8; 28]); - let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - - let ma_input1 = 100; - let ma_input2 = 200; - let ma_output1 = 60; - - let multiassets = [ma_input1, ma_input2, ma_output1] - .iter() - .map(|input| { - let mut multiasset = MultiAsset::new(); - multiasset.insert(policy_id, &{ - let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(*input)); - assets - }); - multiasset - }) - .collect::>(); - - for (i, (multiasset, ada)) in multiassets - .iter() - .zip([300u64, 900].iter().cloned().map(to_bignum)) - .enumerate() - { - let mut input_amount = Value::new(&ada); - input_amount.set_multiasset(multiasset); - - tx_builder.add_key_input( - &&spend.to_raw_key().hash(), - &TransactionInput::new(&genesis_id(), i as u32), - &input_amount, - ); - } - - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - - let mut output_amount = Value::new(&to_bignum(300)); - output_amount.set_multiasset(&multiassets[2]); - - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_net_0) - .next() - .unwrap() - .with_value(&output_amount) - .build() - .unwrap(), - ) - .unwrap(); - - let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); - let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - - let added_change = tx_builder.add_change_if_needed(&change_addr).unwrap(); - assert_eq!(added_change, true); - let final_tx = tx_builder.build().unwrap(); - assert_eq!(final_tx.outputs().len(), 2); - assert_eq!(final_tx.outputs().get(0).amount().coin(), to_bignum(300)); - assert_eq!( - final_tx - .outputs() - .get(1) - .amount() - .multiasset() - .unwrap() - .get(policy_id) - .unwrap() - .get(&name) - .unwrap(), - to_bignum(ma_input1 + ma_input2 - ma_output1) - ); - // The single change output contains more Coin then minimal utxo value - // But not enough to cover the additional fee for a separate output - assert_eq!(final_tx.outputs().get(1).amount().coin(), to_bignum(499)); - } - - #[test] - #[should_panic] - fn build_tx_leftover_assets() { - let mut tx_builder = create_default_tx_builder(); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - - // add an input that contains an asset not present in the output - let policy_id = &PolicyID::from([0u8; 28]); - let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - let mut input_amount = Value::new(&to_bignum(1_000_000)); - let mut input_multiasset = MultiAsset::new(); - input_multiasset.insert(policy_id, &{ - let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(100)); - assets - }); - input_amount.set_multiasset(&input_multiasset); - tx_builder.add_key_input( - &spend.to_raw_key().hash(), - &TransactionInput::new(&genesis_id(), 0), - &input_amount, - ); - - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_net_0) - .next() - .unwrap() - .with_coin(&to_bignum(880_000)) - .build() - .unwrap(), - ) - .unwrap(); - tx_builder.set_ttl(1000); - - let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); - let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - let added_change = tx_builder.add_change_if_needed(&change_addr); - assert!(!added_change.unwrap()); - assert_eq!(tx_builder.outputs.len(), 1); - assert_eq!( - tx_builder - .get_explicit_input() - .unwrap() - .checked_add(&tx_builder.get_implicit_input().unwrap()) - .unwrap(), - tx_builder - .get_explicit_output() - .unwrap() - .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) - .unwrap() - ); - let _final_tx = tx_builder.build(); // just test that it doesn't throw - } - - #[test] - fn build_tx_burn_less_than_min_ada() { - // with this mainnet value we should end up with a final min_ada_required of just under 1_000_000 - let mut tx_builder = create_reallistic_tx_builder(); - - let output_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b", - ) - .unwrap(); - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&output_addr.to_address()) - .next() - .unwrap() - .with_value(&Value::new(&to_bignum(2_000_000))) - .build() - .unwrap(), - ) - .unwrap(); - - tx_builder.add_input( - &ByronAddress::from_base58( - "Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3", - ) - .unwrap() - .to_address(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(2_400_000)), - ); - - tx_builder.set_ttl(1); - - let change_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho", - ) - .unwrap(); - let added_change = tx_builder.add_change_if_needed(&change_addr.to_address()); - assert!(!added_change.unwrap()); - assert_eq!(tx_builder.outputs.len(), 1); - assert_eq!( - tx_builder - .get_explicit_input() - .unwrap() - .checked_add(&tx_builder.get_implicit_input().unwrap()) - .unwrap(), - tx_builder - .get_explicit_output() - .unwrap() - .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) - .unwrap() - ); - let _final_tx = tx_builder.build(); // just test that it doesn't throw - } - - #[test] - fn build_tx_burn_empty_assets() { - let mut tx_builder = create_reallistic_tx_builder(); - - let output_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b", - ) - .unwrap(); - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&output_addr.to_address()) - .next() - .unwrap() - .with_value(&Value::new(&to_bignum(2_000_000))) - .build() - .unwrap(), - ) - .unwrap(); - - let mut input_value = Value::new(&to_bignum(2_400_000)); - input_value.set_multiasset(&MultiAsset::new()); - tx_builder.add_input( - &ByronAddress::from_base58( - "Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3", - ) - .unwrap() - .to_address(), - &TransactionInput::new(&genesis_id(), 0), - &input_value, - ); - - tx_builder.set_ttl(1); - - let change_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho", - ) - .unwrap(); - let added_change = tx_builder.add_change_if_needed(&change_addr.to_address()); - assert!(!added_change.unwrap()); - assert_eq!(tx_builder.outputs.len(), 1); - assert_eq!( - tx_builder - .get_explicit_input() - .unwrap() - .checked_add(&tx_builder.get_implicit_input().unwrap()) - .unwrap() - .coin(), - tx_builder - .get_explicit_output() - .unwrap() - .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) - .unwrap() - .coin() - ); - let _final_tx = tx_builder.build(); // just test that it doesn't throw - } - - #[test] - fn build_tx_no_useless_multiasset() { - let mut tx_builder = create_reallistic_tx_builder(); - - let policy_id = &PolicyID::from([0u8; 28]); - let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - - // add an output that uses up all the token but leaves ADA - let mut input_amount = Value::new(&to_bignum(5_000_000)); - let mut input_multiasset = MultiAsset::new(); - input_multiasset.insert(policy_id, &{ - let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(100)); - assets - }); - input_amount.set_multiasset(&input_multiasset); - - tx_builder.add_input( - &ByronAddress::from_base58( - "Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3", - ) - .unwrap() - .to_address(), - &TransactionInput::new(&genesis_id(), 0), - &input_amount, - ); - - // add an input that contains an asset & ADA - let mut output_amount = Value::new(&to_bignum(2_000_000)); - let mut output_multiasset = MultiAsset::new(); - output_multiasset.insert(policy_id, &{ - let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(100)); - assets - }); - output_amount.set_multiasset(&output_multiasset); - - let output_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b", - ) - .unwrap(); - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&output_addr.to_address()) - .next() - .unwrap() - .with_value(&output_amount) - .build() - .unwrap(), - ) - .unwrap(); - - tx_builder.set_ttl(1); - - let change_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho", - ) - .unwrap(); - let added_change = tx_builder.add_change_if_needed(&change_addr.to_address()); - assert!(added_change.unwrap()); - assert_eq!(tx_builder.outputs.len(), 2); - let final_tx = tx_builder.build().unwrap(); - let change_output = final_tx.outputs().get(1); - let change_assets = change_output.amount().multiasset(); - - // since all tokens got sent in the output - // the change should be only ADA and not have any multiasset struct in it - assert!(change_assets.is_none()); - } - - fn create_multiasset() -> (MultiAsset, [ScriptHash; 3], [AssetName; 3]) { - let policy_ids = [ - fake_policy_id(0), - fake_policy_id(1), - fake_policy_id(2), - ]; - let names = [ - AssetName::new(vec![99u8; 32]).unwrap(), - AssetName::new(vec![0u8, 1, 2, 3]).unwrap(), - AssetName::new(vec![4u8, 5, 6, 7, 8, 9]).unwrap(), - ]; - let multiasset = policy_ids.iter().zip(names.iter()).fold( - MultiAsset::new(), - |mut acc, (policy_id, name)| { - acc.insert(policy_id, &{ - let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(500)); - assets - }); - acc - }, - ); - return (multiasset, policy_ids, names); - } - - #[test] - fn build_tx_add_change_split_nfts() { - let max_value_size = 100; // super low max output size to test with fewer assets - let mut tx_builder = - create_tx_builder_with_fee_and_val_size(&create_linear_fee(0, 1), max_value_size); - - let (multiasset, policy_ids, names) = create_multiasset(); - - let mut input_value = Value::new(&to_bignum(1000)); - input_value.set_multiasset(&multiasset); - - tx_builder.add_input( - &ByronAddress::from_base58( - "Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3", - ) - .unwrap() - .to_address(), - &TransactionInput::new(&genesis_id(), 0), - &input_value, - ); - - let output_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b", - ) - .unwrap() - .to_address(); - let output_amount = Value::new(&to_bignum(208)); - - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&output_addr) - .next() - .unwrap() - .with_value(&output_amount) - .build() - .unwrap(), - ) - .unwrap(); - - let change_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho", - ) - .unwrap() - .to_address(); - - let added_change = tx_builder.add_change_if_needed(&change_addr).unwrap(); - assert_eq!(added_change, true); - let final_tx = tx_builder.build().unwrap(); - assert_eq!(final_tx.outputs().len(), 3); - for (policy_id, asset_name) in policy_ids.iter().zip(names.iter()) { - assert!(final_tx - .outputs - .0 - .iter() - .find(|output| output.amount.multiasset.as_ref().map_or_else( - || false, - |ma| ma - .0 - .iter() - .find(|(pid, a)| *pid == policy_id - && a.0.iter().find(|(name, _)| *name == asset_name).is_some()) - .is_some() - )) - .is_some()); - } - for output in final_tx.outputs.0.iter() { - assert!(output.amount.to_bytes().len() <= max_value_size as usize); - } - } - - #[test] - fn build_tx_too_big_output() { - let mut tx_builder = create_tx_builder_with_fee_and_val_size(&create_linear_fee(0, 1), 10); - - tx_builder.add_input( - &ByronAddress::from_base58( - "Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3", - ) - .unwrap() - .to_address(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(500)), - ); - - let output_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b", - ) - .unwrap() - .to_address(); - let mut output_amount = Value::new(&to_bignum(50)); - output_amount.set_multiasset(&create_multiasset().0); - - assert!(tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&output_addr) - .next() - .unwrap() - .with_value(&output_amount) - .build() - .unwrap() - ) - .is_err()); - } - - #[test] - fn build_tx_add_change_nfts_not_enough_ada() { - let mut tx_builder = create_tx_builder_with_fee_and_val_size( - &create_linear_fee(0, 1), - 150, // super low max output size to test with fewer assets - ); - - let policy_ids = [ - PolicyID::from([0u8; 28]), - PolicyID::from([1u8; 28]), - PolicyID::from([2u8; 28]), - ]; - let names = [ - AssetName::new(vec![99u8; 32]).unwrap(), - AssetName::new(vec![0u8, 1, 2, 3]).unwrap(), - AssetName::new(vec![4u8, 5, 6, 7, 8, 9]).unwrap(), - ]; - - let multiasset = policy_ids.iter().zip(names.iter()).fold( - MultiAsset::new(), - |mut acc, (policy_id, name)| { - acc.insert(policy_id, &{ - let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(500)); - assets - }); - acc - }, - ); - - let mut input_value = Value::new(&to_bignum(58)); - input_value.set_multiasset(&multiasset); - - tx_builder.add_input( - &ByronAddress::from_base58( - "Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3", - ) - .unwrap() - .to_address(), - &TransactionInput::new(&genesis_id(), 0), - &input_value, - ); - - let output_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b", - ) - .unwrap() - .to_address(); - let output_amount = Value::new(&to_bignum(208)); - - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&output_addr) - .next() - .unwrap() - .with_value(&output_amount) - .build() - .unwrap(), - ) - .unwrap(); - - let change_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho", - ) - .unwrap() - .to_address(); - - assert!(tx_builder.add_change_if_needed(&change_addr).is_err()) - } - - fn make_input(input_hash_byte: u8, value: Value) -> TransactionUnspentOutput { - TransactionUnspentOutput::new( - &fake_tx_input(input_hash_byte), - &TransactionOutputBuilder::new() - .with_address( - &Address::from_bech32( - "addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z", - ) - .unwrap(), - ) - .next() - .unwrap() - .with_value(&value) - .build() - .unwrap(), - ) - } - - #[test] - fn tx_builder_cip2_largest_first_increasing_fees() { - // we have a = 1 to test increasing fees when more inputs are added - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(1, 0)); - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address( - &Address::from_bech32( - "addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z", - ) - .unwrap(), - ) - .next() - .unwrap() - .with_coin(&to_bignum(9000)) - .build() - .unwrap(), - ) - .unwrap(); - let mut available_inputs = TransactionUnspentOutputs::new(); - available_inputs.add(&make_input(0u8, Value::new(&to_bignum(1200)))); - available_inputs.add(&make_input(1u8, Value::new(&to_bignum(1600)))); - available_inputs.add(&make_input(2u8, Value::new(&to_bignum(6400)))); - available_inputs.add(&make_input(3u8, Value::new(&to_bignum(2400)))); - available_inputs.add(&make_input(4u8, Value::new(&to_bignum(800)))); - tx_builder - .add_inputs_from(&available_inputs, CoinSelectionStrategyCIP2::LargestFirst) - .unwrap(); - let change_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho", - ) - .unwrap() - .to_address(); - let change_added = tx_builder.add_change_if_needed(&change_addr).unwrap(); - assert!(change_added); - let tx = tx_builder.build().unwrap(); - // change needed - assert_eq!(2, tx.outputs().len()); - assert_eq!(3, tx.inputs().len()); - // confirm order of only what is necessary - assert_eq!(1u8, tx.inputs().get(0).transaction_id().0[0]); - assert_eq!(2u8, tx.inputs().get(1).transaction_id().0[0]); - assert_eq!(3u8, tx.inputs().get(2).transaction_id().0[0]); - } - - #[test] - fn tx_builder_cip2_largest_first_static_fees() { - // we have a = 0 so we know adding inputs/outputs doesn't change the fee so we can analyze more - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 0)); - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address( - &Address::from_bech32( - "addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z", - ) - .unwrap(), - ) - .next() - .unwrap() - .with_coin(&to_bignum(1200)) - .build() - .unwrap(), - ) - .unwrap(); - let mut available_inputs = TransactionUnspentOutputs::new(); - available_inputs.add(&make_input(0u8, Value::new(&to_bignum(150)))); - available_inputs.add(&make_input(1u8, Value::new(&to_bignum(200)))); - available_inputs.add(&make_input(2u8, Value::new(&to_bignum(800)))); - available_inputs.add(&make_input(3u8, Value::new(&to_bignum(400)))); - available_inputs.add(&make_input(4u8, Value::new(&to_bignum(100)))); - tx_builder - .add_inputs_from(&available_inputs, CoinSelectionStrategyCIP2::LargestFirst) - .unwrap(); - let change_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho", - ) - .unwrap() - .to_address(); - let change_added = tx_builder.add_change_if_needed(&change_addr).unwrap(); - assert!(!change_added); - let tx = tx_builder.build().unwrap(); - // change not needed - should be exact - assert_eq!(1, tx.outputs().len()); - assert_eq!(2, tx.inputs().len()); - // confirm order of only what is necessary - assert_eq!(2u8, tx.inputs().get(0).transaction_id().0[0]); - assert_eq!(3u8, tx.inputs().get(1).transaction_id().0[0]); - } - - #[test] - fn tx_builder_cip2_largest_first_multiasset() { - // we have a = 0 so we know adding inputs/outputs doesn't change the fee so we can analyze more - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 0)); - let pid1 = PolicyID::from([1u8; 28]); - let pid2 = PolicyID::from([2u8; 28]); - let asset_name1 = AssetName::new(vec![1u8; 8]).unwrap(); - let asset_name2 = AssetName::new(vec![2u8; 11]).unwrap(); - let asset_name3 = AssetName::new(vec![3u8; 9]).unwrap(); - - let mut output_value = Value::new(&to_bignum(415)); - let mut output_ma = MultiAsset::new(); - output_ma.set_asset(&pid1, &asset_name1, to_bignum(5)); - output_ma.set_asset(&pid1, &asset_name2, to_bignum(1)); - output_ma.set_asset(&pid2, &asset_name2, to_bignum(2)); - output_ma.set_asset(&pid2, &asset_name3, to_bignum(4)); - output_value.set_multiasset(&output_ma); - tx_builder - .add_output(&TransactionOutput::new( - &Address::from_bech32("addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z") - .unwrap(), - &output_value, - )) - .unwrap(); - - let mut available_inputs = TransactionUnspentOutputs::new(); - // should not be taken - available_inputs.add(&make_input(0u8, Value::new(&to_bignum(150)))); - - // should not be taken - let mut input1 = make_input(1u8, Value::new(&to_bignum(200))); - let mut ma1 = MultiAsset::new(); - ma1.set_asset(&pid1, &asset_name1, to_bignum(10)); - ma1.set_asset(&pid1, &asset_name2, to_bignum(1)); - ma1.set_asset(&pid2, &asset_name2, to_bignum(2)); - input1.output.amount.set_multiasset(&ma1); - available_inputs.add(&input1); - - // taken first to satisfy pid1:asset_name1 (but also satisfies pid2:asset_name3) - let mut input2 = make_input(2u8, Value::new(&to_bignum(10))); - let mut ma2 = MultiAsset::new(); - ma2.set_asset(&pid1, &asset_name1, to_bignum(20)); - ma2.set_asset(&pid2, &asset_name3, to_bignum(4)); - input2.output.amount.set_multiasset(&ma2); - available_inputs.add(&input2); - - // taken second to satisfy pid1:asset_name2 (but also satisfies pid2:asset_name1) - let mut input3 = make_input(3u8, Value::new(&to_bignum(50))); - let mut ma3 = MultiAsset::new(); - ma3.set_asset(&pid2, &asset_name1, to_bignum(5)); - ma3.set_asset(&pid1, &asset_name2, to_bignum(15)); - input3.output.amount.multiasset = Some(ma3); - available_inputs.add(&input3); - - // should not be taken either - let mut input4 = make_input(4u8, Value::new(&to_bignum(10))); - let mut ma4 = MultiAsset::new(); - ma4.set_asset(&pid1, &asset_name1, to_bignum(10)); - ma4.set_asset(&pid1, &asset_name2, to_bignum(10)); - input4.output.amount.multiasset = Some(ma4); - available_inputs.add(&input4); - - // taken third to satisfy pid2:asset_name_2 - let mut input5 = make_input(5u8, Value::new(&to_bignum(10))); - let mut ma5 = MultiAsset::new(); - ma5.set_asset(&pid1, &asset_name2, to_bignum(10)); - ma5.set_asset(&pid2, &asset_name2, to_bignum(3)); - input5.output.amount.multiasset = Some(ma5); - available_inputs.add(&input5); - - // should be taken to get enough ADA - let input6 = make_input(6u8, Value::new(&to_bignum(900))); - available_inputs.add(&input6); - - // should not be taken - available_inputs.add(&make_input(7u8, Value::new(&to_bignum(100)))); - tx_builder - .add_inputs_from( - &available_inputs, - CoinSelectionStrategyCIP2::LargestFirstMultiAsset, - ) - .unwrap(); - let change_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho", - ) - .unwrap() - .to_address(); - let change_added = tx_builder.add_change_if_needed(&change_addr).unwrap(); - assert!(change_added); - let tx = tx_builder.build().unwrap(); - - assert_eq!(2, tx.outputs().len()); - assert_eq!(4, tx.inputs().len()); - // check order expected per-asset - assert_eq!(2u8, tx.inputs().get(0).transaction_id().0[0]); - assert_eq!(3u8, tx.inputs().get(1).transaction_id().0[0]); - assert_eq!(5u8, tx.inputs().get(2).transaction_id().0[0]); - assert_eq!(6u8, tx.inputs().get(3).transaction_id().0[0]); - - let change = tx.outputs().get(1).amount; - assert_eq!(from_bignum(&change.coin), 555); - let change_ma = change.multiasset().unwrap(); - assert_eq!(15, from_bignum(&change_ma.get_asset(&pid1, &asset_name1))); - assert_eq!(24, from_bignum(&change_ma.get_asset(&pid1, &asset_name2))); - assert_eq!(1, from_bignum(&change_ma.get_asset(&pid2, &asset_name2))); - assert_eq!(0, from_bignum(&change_ma.get_asset(&pid2, &asset_name3))); - let expected_input = input2 - .output - .amount - .checked_add(&input3.output.amount) - .unwrap() - .checked_add(&input5.output.amount) - .unwrap() - .checked_add(&input6.output.amount) - .unwrap(); - let expected_change = expected_input.checked_sub(&output_value).unwrap(); - assert_eq!(expected_change, change); - } - - #[test] - fn tx_builder_cip2_random_improve_multiasset() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 0)); - let pid1 = PolicyID::from([1u8; 28]); - let pid2 = PolicyID::from([2u8; 28]); - let asset_name1 = AssetName::new(vec![1u8; 8]).unwrap(); - let asset_name2 = AssetName::new(vec![2u8; 11]).unwrap(); - let asset_name3 = AssetName::new(vec![3u8; 9]).unwrap(); - - let mut output_value = Value::new(&to_bignum(415)); - let mut output_ma = MultiAsset::new(); - output_ma.set_asset(&pid1, &asset_name1, to_bignum(5)); - output_ma.set_asset(&pid1, &asset_name2, to_bignum(1)); - output_ma.set_asset(&pid2, &asset_name2, to_bignum(2)); - output_ma.set_asset(&pid2, &asset_name3, to_bignum(4)); - output_value.set_multiasset(&output_ma); - tx_builder - .add_output(&TransactionOutput::new( - &Address::from_bech32("addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z") - .unwrap(), - &output_value, - )) - .unwrap(); - - let mut available_inputs = TransactionUnspentOutputs::new(); - available_inputs.add(&make_input(0u8, Value::new(&to_bignum(150)))); - - let mut input1 = make_input(1u8, Value::new(&to_bignum(200))); - let mut ma1 = MultiAsset::new(); - ma1.set_asset(&pid1, &asset_name1, to_bignum(10)); - ma1.set_asset(&pid1, &asset_name2, to_bignum(1)); - ma1.set_asset(&pid2, &asset_name2, to_bignum(2)); - input1.output.amount.set_multiasset(&ma1); - available_inputs.add(&input1); - - let mut input2 = make_input(2u8, Value::new(&to_bignum(10))); - let mut ma2 = MultiAsset::new(); - ma2.set_asset(&pid1, &asset_name1, to_bignum(20)); - ma2.set_asset(&pid2, &asset_name3, to_bignum(4)); - input2.output.amount.set_multiasset(&ma2); - available_inputs.add(&input2); - - let mut input3 = make_input(3u8, Value::new(&to_bignum(50))); - let mut ma3 = MultiAsset::new(); - ma3.set_asset(&pid2, &asset_name1, to_bignum(5)); - ma3.set_asset(&pid1, &asset_name2, to_bignum(15)); - input3.output.amount.multiasset = Some(ma3); - available_inputs.add(&input3); - - let mut input4 = make_input(4u8, Value::new(&to_bignum(10))); - let mut ma4 = MultiAsset::new(); - ma4.set_asset(&pid1, &asset_name1, to_bignum(10)); - ma4.set_asset(&pid1, &asset_name2, to_bignum(10)); - input4.output.amount.multiasset = Some(ma4); - available_inputs.add(&input4); - - let mut input5 = make_input(5u8, Value::new(&to_bignum(10))); - let mut ma5 = MultiAsset::new(); - ma5.set_asset(&pid1, &asset_name2, to_bignum(10)); - ma5.set_asset(&pid2, &asset_name2, to_bignum(3)); - input5.output.amount.multiasset = Some(ma5); - available_inputs.add(&input5); - - let input6 = make_input(6u8, Value::new(&to_bignum(1000))); - available_inputs.add(&input6); - available_inputs.add(&make_input(7u8, Value::new(&to_bignum(100)))); - - let mut input8 = make_input(8u8, Value::new(&to_bignum(10))); - let mut ma8 = MultiAsset::new(); - ma8.set_asset(&pid2, &asset_name2, to_bignum(10)); - input8.output.amount.multiasset = Some(ma8); - available_inputs.add(&input8); - - let mut input9 = make_input(9u8, Value::new(&to_bignum(10))); - let mut ma9 = MultiAsset::new(); - ma9.set_asset(&pid2, &asset_name3, to_bignum(10)); - input9.output.amount.multiasset = Some(ma9); - available_inputs.add(&input9); - - tx_builder - .add_inputs_from( - &available_inputs, - CoinSelectionStrategyCIP2::RandomImproveMultiAsset, - ) - .unwrap(); - - let input_for_cover_change = make_input(10u8, Value::new(&to_bignum(1000))); - tx_builder.add_input( - &input_for_cover_change.output.address, - &input_for_cover_change.input, - &input_for_cover_change.output.amount); - - let change_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho", - ) - .unwrap() - .to_address(); - let change_added = tx_builder.add_change_if_needed(&change_addr).unwrap(); - assert!(change_added); - let tx = tx_builder.build().unwrap(); - - assert_eq!(2, tx.outputs().len()); - - let input_total = tx_builder.get_explicit_input().unwrap(); - assert!(input_total >= output_value); - } - - #[test] - fn tx_builder_cip2_random_improve() { - // we have a = 1 to test increasing fees when more inputs are added - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(1, 0)); - const COST: u64 = 10000; - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address( - &Address::from_bech32( - "addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z", - ) - .unwrap(), - ) - .next() - .unwrap() - .with_coin(&to_bignum(COST)) - .build() - .unwrap(), - ) - .unwrap(); - let mut available_inputs = TransactionUnspentOutputs::new(); - available_inputs.add(&make_input(0u8, Value::new(&to_bignum(1500)))); - available_inputs.add(&make_input(1u8, Value::new(&to_bignum(2000)))); - available_inputs.add(&make_input(2u8, Value::new(&to_bignum(8000)))); - available_inputs.add(&make_input(3u8, Value::new(&to_bignum(4000)))); - available_inputs.add(&make_input(4u8, Value::new(&to_bignum(1000)))); - available_inputs.add(&make_input(5u8, Value::new(&to_bignum(2000)))); - available_inputs.add(&make_input(6u8, Value::new(&to_bignum(1500)))); - let add_inputs_res = - tx_builder.add_inputs_from(&available_inputs, CoinSelectionStrategyCIP2::RandomImprove); - assert!(add_inputs_res.is_ok(), "{:?}", add_inputs_res.err()); - let change_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho", - ) - .unwrap() - .to_address(); - let add_change_res = tx_builder.add_change_if_needed(&change_addr); - assert!(add_change_res.is_ok(), "{:?}", add_change_res.err()); - let tx_build_res = tx_builder.build(); - assert!(tx_build_res.is_ok(), "{:?}", tx_build_res.err()); - let tx = tx_build_res.unwrap(); - // we need to look up the values to ensure there's enough - let mut input_values = BTreeMap::new(); - for utxo in available_inputs.0.iter() { - input_values.insert(utxo.input.transaction_id(), utxo.output.amount.clone()); - } - let mut encountered = std::collections::HashSet::new(); - let mut input_total = Value::new(&Coin::zero()); - for input in tx.inputs.0.iter() { - let txid = input.transaction_id(); - if !encountered.insert(txid.clone()) { - panic!("Input {:?} duplicated", txid); - } - let value = input_values.get(&txid).unwrap(); - input_total = input_total.checked_add(value).unwrap(); - } - assert!( - input_total - >= Value::new( - &tx_builder - .min_fee() - .unwrap() - .checked_add(&to_bignum(COST)) - .unwrap() - ) - ); - } - - #[test] - fn tx_builder_cip2_random_improve_when_using_all_available_inputs() { - // we have a = 1 to test increasing fees when more inputs are added - let linear_fee = LinearFee::new(&to_bignum(1), &to_bignum(0)); - let cfg = TransactionBuilderConfigBuilder::new() - .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(0)) - .key_deposit(&to_bignum(0)) - .voting_proposal_deposit(&to_bignum(500000000)) - .max_value_size(9999) - .max_tx_size(9999) - .coins_per_utxo_word(&Coin::zero()) - .build() - .unwrap(); - let mut tx_builder = TransactionBuilder::new(&cfg); - const COST: u64 = 1000; - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address( - &Address::from_bech32( - "addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z", - ) - .unwrap(), - ) - .next() - .unwrap() - .with_coin(&to_bignum(COST)) - .build() - .unwrap(), - ) - .unwrap(); - let mut available_inputs = TransactionUnspentOutputs::new(); - available_inputs.add(&make_input(1u8, Value::new(&to_bignum(800)))); - available_inputs.add(&make_input(2u8, Value::new(&to_bignum(800)))); - let add_inputs_res = - tx_builder.add_inputs_from(&available_inputs, CoinSelectionStrategyCIP2::RandomImprove); - assert!(add_inputs_res.is_ok(), "{:?}", add_inputs_res.err()); - } - - #[test] - fn tx_builder_cip2_random_improve_adds_enough_for_fees() { - // we have a = 1 to test increasing fees when more inputs are added - let linear_fee = LinearFee::new(&to_bignum(1), &to_bignum(0)); - let cfg = TransactionBuilderConfigBuilder::new() - .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(0)) - .key_deposit(&to_bignum(0)) - .voting_proposal_deposit(&to_bignum(500000000)) - .max_value_size(9999) - .max_tx_size(9999) - .coins_per_utxo_word(&Coin::zero()) - .build() - .unwrap(); - let mut tx_builder = TransactionBuilder::new(&cfg); - const COST: u64 = 100; - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address( - &Address::from_bech32( - "addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z", - ) - .unwrap(), - ) - .next() - .unwrap() - .with_coin(&to_bignum(COST)) - .build() - .unwrap(), - ) - .unwrap(); - assert_eq!(tx_builder.min_fee().unwrap(), to_bignum(53)); - let mut available_inputs = TransactionUnspentOutputs::new(); - available_inputs.add(&make_input(1u8, Value::new(&to_bignum(150)))); - available_inputs.add(&make_input(2u8, Value::new(&to_bignum(150)))); - available_inputs.add(&make_input(3u8, Value::new(&to_bignum(150)))); - let add_inputs_res = - tx_builder.add_inputs_from(&available_inputs, CoinSelectionStrategyCIP2::RandomImprove); - assert!(add_inputs_res.is_ok(), "{:?}", add_inputs_res.err()); - assert_eq!(tx_builder.min_fee().unwrap(), to_bignum(264)); - let change_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho", - ) - .unwrap() - .to_address(); - let add_change_res = tx_builder.add_change_if_needed(&change_addr); - assert!(add_change_res.is_ok(), "{:?}", add_change_res.err()); - } - - #[test] - fn build_tx_pay_to_multisig() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(10, 2)); - let spend = root_key_15() - .derive(harden(1854)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - - tx_builder.add_key_input( - &spend.to_raw_key().hash(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_net_0) - .next() - .unwrap() - .with_coin(&to_bignum(999_000)) - .build() - .unwrap(), - ) - .unwrap(); - tx_builder.set_ttl(1000); - tx_builder.set_fee(&to_bignum(1_000)); - - assert_eq!(tx_builder.outputs.len(), 1); - assert_eq!( - tx_builder - .get_explicit_input() - .unwrap() - .checked_add(&tx_builder.get_implicit_input().unwrap()) - .unwrap(), - tx_builder - .get_explicit_output() - .unwrap() - .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) - .unwrap() - ); - - let _final_tx = tx_builder.build().unwrap(); - let _deser_t = TransactionBody::from_bytes(_final_tx.to_bytes()).unwrap(); - - assert_eq!(_deser_t.to_bytes(), _final_tx.to_bytes()); - } - - fn build_full_tx( - body: &TransactionBody, - witness_set: &TransactionWitnessSet, - auxiliary_data: Option, - ) -> Transaction { - return Transaction::new(body, witness_set, auxiliary_data); - } - - #[test] - fn build_tx_multisig_spend_1on1_unsigned() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(10, 2)); - - let spend = root_key_15() //multisig - .derive(harden(1854)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let stake = root_key_15() //multisig - .derive(harden(1854)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); - let addr_multisig = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - let addr_output = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - - tx_builder.add_input( - &addr_multisig, - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_output) - .next() - .unwrap() - .with_coin(&to_bignum(999_000)) - .build() - .unwrap(), - ) - .unwrap(); - tx_builder.set_ttl(1000); - tx_builder.set_fee(&to_bignum(1_000)); - - let mut auxiliary_data = AuxiliaryData::new(); - let mut pubkey_native_scripts = NativeScripts::new(); - let mut oneof_native_scripts = NativeScripts::new(); - - let spending_hash = spend.to_raw_key().hash(); - pubkey_native_scripts.add(&NativeScript::new_script_pubkey(&ScriptPubkey::new( - &spending_hash, - ))); - oneof_native_scripts.add(&NativeScript::new_script_n_of_k(&ScriptNOfK::new( - 1, - &pubkey_native_scripts, - ))); - auxiliary_data.set_native_scripts(&oneof_native_scripts); - tx_builder.set_auxiliary_data(&auxiliary_data); - - assert_eq!(tx_builder.outputs.len(), 1); - assert_eq!( - tx_builder - .get_explicit_input() - .unwrap() - .checked_add(&tx_builder.get_implicit_input().unwrap()) - .unwrap(), - tx_builder - .get_explicit_output() - .unwrap() - .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) - .unwrap() - ); - - let _final_tx = tx_builder.build().unwrap(); - let _deser_t = TransactionBody::from_bytes(_final_tx.to_bytes()).unwrap(); - - assert_eq!(_deser_t.to_bytes(), _final_tx.to_bytes()); - assert_eq!( - _deser_t.auxiliary_data_hash.unwrap(), - utils::hash_auxiliary_data(&auxiliary_data) - ); - } - - #[test] - fn build_tx_multisig_1on1_signed() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(10, 2)); - let spend = root_key_15() - .derive(harden(1854)) //multisig - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1854)) //multisig - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ) - .to_address(); - tx_builder.add_key_input( - &spend.to_raw_key().hash(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&addr_net_0) - .next() - .unwrap() - .with_coin(&to_bignum(999_000)) - .build() - .unwrap(), - ) - .unwrap(); - tx_builder.set_ttl(1000); - tx_builder.set_fee(&to_bignum(1_000)); - - let mut auxiliary_data = AuxiliaryData::new(); - let mut pubkey_native_scripts = NativeScripts::new(); - let mut oneof_native_scripts = NativeScripts::new(); - - let spending_hash = spend.to_raw_key().hash(); - pubkey_native_scripts.add(&NativeScript::new_script_pubkey(&ScriptPubkey::new( - &spending_hash, - ))); - oneof_native_scripts.add(&NativeScript::new_script_n_of_k(&ScriptNOfK::new( - 1, - &pubkey_native_scripts, - ))); - auxiliary_data.set_native_scripts(&oneof_native_scripts); - tx_builder.set_auxiliary_data(&auxiliary_data); - - let body = tx_builder.build().unwrap(); - - assert_eq!(tx_builder.outputs.len(), 1); - assert_eq!( - tx_builder - .get_explicit_input() - .unwrap() - .checked_add(&tx_builder.get_implicit_input().unwrap()) - .unwrap(), - tx_builder - .get_explicit_output() - .unwrap() - .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) - .unwrap() - ); - - let mut witness_set = TransactionWitnessSet::new(); - let mut vkw = Vkeywitnesses::new(); - vkw.add(&make_vkey_witness( - &hash_transaction(&body), - &PrivateKey::from_normal_bytes( - &hex::decode("c660e50315d76a53d80732efda7630cae8885dfb85c46378684b3c6103e1284a") - .unwrap(), - ) - .unwrap(), - )); - witness_set.set_vkeys(&vkw); - - let _final_tx = build_full_tx(&body, &witness_set, None); - let _deser_t = Transaction::from_bytes(_final_tx.to_bytes()).unwrap(); - assert_eq!(_deser_t.to_bytes(), _final_tx.to_bytes()); - assert_eq!( - _deser_t.body().auxiliary_data_hash.unwrap(), - utils::hash_auxiliary_data(&auxiliary_data) - ); - } - - #[test] - fn add_change_splits_change_into_multiple_outputs_when_nfts_overflow_output_size() { - let linear_fee = LinearFee::new(&to_bignum(0), &to_bignum(1)); - let max_value_size = 100; // super low max output size to test with fewer assets - let mut tx_builder = TransactionBuilder::new( - &TransactionBuilderConfigBuilder::new() - .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(0)) - .key_deposit(&to_bignum(0)) - .voting_proposal_deposit(&to_bignum(500000000)) - .max_value_size(max_value_size) - .max_tx_size(MAX_TX_SIZE) - .coins_per_utxo_word(&to_bignum(8)) - .prefer_pure_change(true) - .build() - .unwrap(), - ); - - let policy_id = PolicyID::from([0u8; 28]); - let names = [ - AssetName::new(vec![99u8; 32]).unwrap(), - AssetName::new(vec![0u8, 1, 2, 3]).unwrap(), - AssetName::new(vec![4u8, 5, 6, 7]).unwrap(), - AssetName::new(vec![5u8, 5, 6, 7]).unwrap(), - AssetName::new(vec![6u8, 5, 6, 7]).unwrap(), - ]; - let assets = names.iter().fold(Assets::new(), |mut a, name| { - a.insert(&name, &to_bignum(500)); - a - }); - let mut multiasset = MultiAsset::new(); - multiasset.insert(&policy_id, &assets); - - let mut input_value = Value::new(&to_bignum(1200)); - input_value.set_multiasset(&multiasset); - - tx_builder.add_input( - &ByronAddress::from_base58( - "Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3", - ) - .unwrap() - .to_address(), - &TransactionInput::new(&genesis_id(), 0), - &input_value, - ); - - let output_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b", - ) - .unwrap() - .to_address(); - let output_amount = Value::new(&to_bignum(208)); - - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&output_addr) - .next() - .unwrap() - .with_value(&output_amount) - .build() - .unwrap(), - ) - .unwrap(); - - let change_addr = ByronAddress::from_base58( - "Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho", - ) - .unwrap() - .to_address(); - - let add_change_result = tx_builder.add_change_if_needed(&change_addr); - assert!(add_change_result.is_ok()); - assert_eq!(tx_builder.outputs.len(), 4); - - let change1 = tx_builder.outputs.get(1); - let change2 = tx_builder.outputs.get(2); - let change3 = tx_builder.outputs.get(3); - - assert_eq!(change1.address, change_addr); - assert_eq!(change1.address, change2.address); - assert_eq!(change1.address, change3.address); - - assert_eq!(change1.amount.coin, to_bignum(288)); - assert_eq!(change2.amount.coin, to_bignum(293)); - assert_eq!(change3.amount.coin, to_bignum(410)); - - assert!(change1.amount.multiasset.is_some()); - assert!(change2.amount.multiasset.is_some()); - assert!(change3.amount.multiasset.is_none()); // purified - - let masset1 = change1.amount.multiasset.unwrap(); - let masset2 = change2.amount.multiasset.unwrap(); - - assert_eq!(masset1.keys().len(), 1); - assert_eq!(masset1.keys(), masset2.keys()); - - let asset1 = masset1.get(&policy_id).unwrap(); - let asset2 = masset2.get(&policy_id).unwrap(); - assert_eq!(asset1.len(), 4); - assert_eq!(asset2.len(), 1); - - names.iter().for_each(|name| { - let v1 = asset1.get(name); - let v2 = asset2.get(name); - assert_ne!(v1.is_some(), v2.is_some()); - assert_eq!(v1.or(v2).unwrap(), to_bignum(500)); - }); - } - - fn create_json_metadatum_string() -> String { - String::from("{ \"qwe\": 123 }") - } - - fn create_json_metadatum() -> TransactionMetadatum { - encode_json_str_to_metadatum( - create_json_metadatum_string(), - MetadataJsonSchema::NoConversions, - ) - .unwrap() - } - - fn create_aux_with_metadata(metadatum_key: &TransactionMetadatumLabel) -> AuxiliaryData { - let mut metadata = GeneralTransactionMetadata::new(); - metadata.insert(metadatum_key, &create_json_metadatum()); - - let mut aux = AuxiliaryData::new(); - aux.set_metadata(&metadata); - - let mut nats = NativeScripts::new(); - nats.add(&NativeScript::new_timelock_start(&TimelockStart::new(123))); - aux.set_native_scripts(&nats); - - return aux; - } - - fn assert_json_metadatum(dat: &TransactionMetadatum) { - let map = dat.as_map().unwrap(); - assert_eq!(map.len(), 1); - let key = TransactionMetadatum::new_text(String::from("qwe")).unwrap(); - let val = map.get(&key).unwrap(); - assert_eq!(val.as_int().unwrap(), Int::new_i32(123)); - } - - #[test] - fn set_metadata_with_empty_auxiliary() { - let mut tx_builder = create_default_tx_builder(); - - let num = to_bignum(42); - tx_builder.set_metadata(&create_aux_with_metadata(&num).metadata().unwrap()); - - assert!(tx_builder.auxiliary_data.is_some()); - - let aux = tx_builder.auxiliary_data.unwrap(); - assert!(aux.metadata().is_some()); - assert!(aux.native_scripts().is_none()); - assert!(aux.plutus_scripts().is_none()); - - let met = aux.metadata().unwrap(); - - assert_eq!(met.len(), 1); - assert_json_metadatum(&met.get(&num).unwrap()); - } - - #[test] - fn set_metadata_with_existing_auxiliary() { - let mut tx_builder = create_default_tx_builder(); - - let num1 = to_bignum(42); - tx_builder.set_auxiliary_data(&create_aux_with_metadata(&num1)); - - let num2 = to_bignum(84); - tx_builder.set_metadata(&create_aux_with_metadata(&num2).metadata().unwrap()); - - let aux = tx_builder.auxiliary_data.unwrap(); - assert!(aux.metadata().is_some()); - assert!(aux.native_scripts().is_some()); - assert!(aux.plutus_scripts().is_none()); - - let met = aux.metadata().unwrap(); - assert_eq!(met.len(), 1); - assert!(met.get(&num1).is_none()); - assert_json_metadatum(&met.get(&num2).unwrap()); - } - - #[test] - fn add_metadatum_with_empty_auxiliary() { - let mut tx_builder = create_default_tx_builder(); - - let num = to_bignum(42); - tx_builder.add_metadatum(&num, &create_json_metadatum()); - - assert!(tx_builder.auxiliary_data.is_some()); - - let aux = tx_builder.auxiliary_data.unwrap(); - assert!(aux.metadata().is_some()); - assert!(aux.native_scripts().is_none()); - assert!(aux.plutus_scripts().is_none()); - - let met = aux.metadata().unwrap(); - - assert_eq!(met.len(), 1); - assert_json_metadatum(&met.get(&num).unwrap()); - } - - #[test] - fn add_metadatum_with_existing_auxiliary() { - let mut tx_builder = create_default_tx_builder(); - - let num1 = to_bignum(42); - tx_builder.set_auxiliary_data(&create_aux_with_metadata(&num1)); - - let num2 = to_bignum(84); - tx_builder.add_metadatum(&num2, &create_json_metadatum()); - - let aux = tx_builder.auxiliary_data.unwrap(); - assert!(aux.metadata().is_some()); - assert!(aux.native_scripts().is_some()); - assert!(aux.plutus_scripts().is_none()); - - let met = aux.metadata().unwrap(); - assert_eq!(met.len(), 2); - assert_json_metadatum(&met.get(&num1).unwrap()); - assert_json_metadatum(&met.get(&num2).unwrap()); - } - - #[test] - fn add_json_metadatum_with_empty_auxiliary() { - let mut tx_builder = create_default_tx_builder(); - - let num = to_bignum(42); - tx_builder - .add_json_metadatum(&num, create_json_metadatum_string()) - .unwrap(); - - assert!(tx_builder.auxiliary_data.is_some()); - - let aux = tx_builder.auxiliary_data.unwrap(); - assert!(aux.metadata().is_some()); - assert!(aux.native_scripts().is_none()); - assert!(aux.plutus_scripts().is_none()); - - let met = aux.metadata().unwrap(); - - assert_eq!(met.len(), 1); - assert_json_metadatum(&met.get(&num).unwrap()); - } - - #[test] - fn add_json_metadatum_with_existing_auxiliary() { - let mut tx_builder = create_default_tx_builder(); - - let num1 = to_bignum(42); - tx_builder.set_auxiliary_data(&create_aux_with_metadata(&num1)); - - let num2 = to_bignum(84); - tx_builder - .add_json_metadatum(&num2, create_json_metadatum_string()) - .unwrap(); - - let aux = tx_builder.auxiliary_data.unwrap(); - assert!(aux.metadata().is_some()); - assert!(aux.native_scripts().is_some()); - assert!(aux.plutus_scripts().is_none()); - - let met = aux.metadata().unwrap(); - assert_eq!(met.len(), 2); - assert_json_metadatum(&met.get(&num1).unwrap()); - assert_json_metadatum(&met.get(&num2).unwrap()); - } - - fn create_asset_name() -> AssetName { - AssetName::new(vec![0u8, 1, 2, 3]).unwrap() - } - - fn create_mint_asset() -> MintAssets { - MintAssets::new_from_entry(&create_asset_name(), Int::new_i32(1234)) - } - - fn create_assets() -> Assets { - let mut assets = Assets::new(); - assets.insert(&create_asset_name(), &to_bignum(1234)); - return assets; - } - - fn create_mint_with_one_asset(policy_id: &PolicyID) -> Mint { - Mint::new_from_entry(policy_id, &create_mint_asset()) - } - - fn create_multiasset_one_asset(policy_id: &PolicyID) -> MultiAsset { - let mut mint = MultiAsset::new(); - mint.insert(policy_id, &create_assets()); - return mint; - } - - fn assert_mint_asset(mint: &Mint, policy_id: &PolicyID) { - assert!(mint.get(&policy_id).is_some()); - let result_asset = mint.get(&policy_id).unwrap(); - assert_eq!(result_asset.len(), 1); - assert_eq!( - result_asset.get(&create_asset_name()).unwrap(), - Int::new_i32(1234) - ); - } - - fn mint_script_and_policy_and_hash(x: u8) -> (NativeScript, PolicyID, Ed25519KeyHash) { - let hash = fake_key_hash(x); - let mint_script = NativeScript::new_script_pubkey(&ScriptPubkey::new(&hash)); - let policy_id = mint_script.hash(); - (mint_script, policy_id, hash) - } - - fn mint_script_and_policy(x: u8) -> (NativeScript, ScriptHash) { - let (m, p, _) = mint_script_and_policy_and_hash(x); - (m, p) - } - - fn plutus_script_and_hash(x: u8) -> (PlutusScript, ScriptHash) { - let s = PlutusScript::new(fake_bytes_32(x)); - (s.clone(), s.hash()) - } - - #[test] - fn set_mint_asset_with_empty_mint() { - let mut tx_builder = create_default_tx_builder(); - - let (mint_script, policy_id) = mint_script_and_policy(0); - tx_builder.set_mint_asset(&mint_script, &create_mint_asset()); - - assert!(tx_builder.mint.is_some()); - let mint_scripts = tx_builder.mint.as_ref().unwrap().get_native_scripts(); - assert!(mint_scripts.len() > 0); - - let mint = tx_builder.mint.unwrap().build(); - - assert_eq!(mint.len(), 1); - assert_mint_asset(&mint, &policy_id); - - assert_eq!(mint_scripts.len(), 1); - assert_eq!(mint_scripts.get(0), mint_script); - } - - #[test] - fn set_mint_asset_with_existing_mint() { - let mut tx_builder = create_default_tx_builder(); - - let (mint_script1, policy_id1) = mint_script_and_policy(0); - let (mint_script2, policy_id2) = mint_script_and_policy(1); - - tx_builder - .set_mint( - &create_mint_with_one_asset(&policy_id1), - &NativeScripts::from(vec![mint_script1.clone()]), - ) - .unwrap(); - - tx_builder.set_mint_asset(&mint_script2, &create_mint_asset()); - - assert!(tx_builder.mint.is_some()); - let mint_scripts = tx_builder.mint.as_ref().unwrap().get_native_scripts(); - assert!(mint_scripts.len() > 0); - - let mint = tx_builder.mint.unwrap().build(); - - assert_eq!(mint.len(), 2); - assert_mint_asset(&mint, &policy_id1); - assert_mint_asset(&mint, &policy_id2); - - // Only second script is present in the scripts - assert_eq!(mint_scripts.len(), 2); - let actual_scripts = mint_scripts.0.iter().cloned().collect::>(); - let expected_scripts = vec![mint_script1, mint_script2].iter().cloned().collect::>(); - assert_eq!(actual_scripts, expected_scripts); - } - - #[test] - fn add_mint_asset_with_empty_mint() { - let mut tx_builder = create_default_tx_builder(); - - let (mint_script, policy_id) = mint_script_and_policy(0); - - tx_builder.add_mint_asset(&mint_script, &create_asset_name(), Int::new_i32(1234)); - - assert!(tx_builder.mint.is_some()); - let mint_scripts = tx_builder.mint.as_ref().unwrap().get_native_scripts(); - assert!(mint_scripts.len() > 0); - - let mint = tx_builder.mint.unwrap().build(); - - assert_eq!(mint.len(), 1); - assert_mint_asset(&mint, &policy_id); - - assert_eq!(mint_scripts.len(), 1); - assert_eq!(mint_scripts.get(0), mint_script); - } - - #[test] - fn add_mint_asset_with_existing_mint() { - let mut tx_builder = create_default_tx_builder(); - - let (mint_script1, policy_id1) = mint_script_and_policy(0); - let (mint_script2, policy_id2) = mint_script_and_policy(1); - - tx_builder - .set_mint( - &create_mint_with_one_asset(&policy_id1), - &NativeScripts::from(vec![mint_script1.clone()]), - ) - .unwrap(); - tx_builder.add_mint_asset(&mint_script2, &create_asset_name(), Int::new_i32(1234)); - - assert!(tx_builder.mint.is_some()); - let mint_scripts = tx_builder.mint.as_ref().unwrap().get_native_scripts(); - assert!(mint_scripts.len() > 0); - - let mint = tx_builder.mint.unwrap().build(); - - assert_eq!(mint.len(), 2); - assert_mint_asset(&mint, &policy_id1); - assert_mint_asset(&mint, &policy_id2); - - assert_eq!(mint_scripts.len(), 2); - let actual_scripts = mint_scripts.0.iter().cloned().collect::>(); - let expected_scripts = vec![mint_script1, mint_script2].iter().cloned().collect::>(); - assert_eq!(actual_scripts, expected_scripts); - } - - #[test] - fn add_output_amount() { - let mut tx_builder = create_default_tx_builder(); - - let policy_id1 = PolicyID::from([0u8; 28]); - let multiasset = create_multiasset_one_asset(&policy_id1); - let mut value = Value::new(&to_bignum(249)); - value.set_multiasset(&multiasset); - - let address = byron_address(); - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&address) - .next() - .unwrap() - .with_value(&value) - .build() - .unwrap(), - ) - .unwrap(); - - assert_eq!(tx_builder.outputs.len(), 1); - let out = tx_builder.outputs.get(0); - - assert_eq!(out.address.to_bytes(), address.to_bytes()); - assert_eq!(out.amount, value); - } - - #[test] - fn add_output_coin() { - let mut tx_builder = create_default_tx_builder(); - - let address = byron_address(); - let coin = to_bignum(208); - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&address) - .next() - .unwrap() - .with_coin(&coin) - .build() - .unwrap(), - ) - .unwrap(); - - assert_eq!(tx_builder.outputs.len(), 1); - let out = tx_builder.outputs.get(0); - - assert_eq!(out.address.to_bytes(), address.to_bytes()); - assert_eq!(out.amount.coin, coin); - assert!(out.amount.multiasset.is_none()); - } - - #[test] - fn add_output_coin_and_multiasset() { - let mut tx_builder = create_default_tx_builder(); - - let policy_id1 = PolicyID::from([0u8; 28]); - let multiasset = create_multiasset_one_asset(&policy_id1); - - let address = byron_address(); - let coin = to_bignum(249); - - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&address) - .next() - .unwrap() - .with_coin_and_asset(&coin, &multiasset) - .build() - .unwrap(), - ) - .unwrap(); - - assert_eq!(tx_builder.outputs.len(), 1); - let out = tx_builder.outputs.get(0); - - assert_eq!(out.address.to_bytes(), address.to_bytes()); - assert_eq!(out.amount.coin, coin); - assert_eq!(out.amount.multiasset.unwrap(), multiasset); - } - - #[test] - fn add_output_asset_and_min_required_coin() { - let mut tx_builder = create_reallistic_tx_builder(); - - let policy_id1 = PolicyID::from([0u8; 28]); - let multiasset = create_multiasset_one_asset(&policy_id1); - - let address = byron_address(); - - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&address) - .next() - .unwrap() - .with_asset_and_min_required_coin_by_utxo_cost( - &multiasset, - &tx_builder.config.utxo_cost(), - ) - .unwrap() - .build() - .unwrap(), - ) - .unwrap(); - - assert_eq!(tx_builder.outputs.len(), 1); - let out = tx_builder.outputs.get(0); - - assert_eq!(out.address.to_bytes(), address.to_bytes()); - assert_eq!(out.amount.multiasset.unwrap(), multiasset); - assert_eq!(out.amount.coin, to_bignum(1146460)); - } - - #[test] - fn add_mint_asset_and_output() { - let mut tx_builder = create_default_tx_builder(); - - let (mint_script0, policy_id0) = mint_script_and_policy(0); - let (mint_script1, policy_id1) = mint_script_and_policy(1); - - let name = create_asset_name(); - let amount = Int::new_i32(1234); - - let address = byron_address(); - let coin = to_bignum(249); - - // Add unrelated mint first to check it is NOT added to output later - tx_builder.add_mint_asset(&mint_script0, &name, amount.clone()); - - tx_builder - .add_mint_asset_and_output( - &mint_script1, - &name, - amount.clone(), - &TransactionOutputBuilder::new() - .with_address(&address) - .next() - .unwrap(), - &coin, - ) - .unwrap(); - - assert!(tx_builder.mint.is_some()); - let mint_scripts = &tx_builder.mint.as_ref().unwrap().get_native_scripts(); - assert!(mint_scripts.len() > 0); - - let mint = &tx_builder.mint.unwrap().build(); - - // Mint contains two entries - assert_eq!(mint.len(), 2); - assert_mint_asset(mint, &policy_id0); - assert_mint_asset(mint, &policy_id1); - - assert_eq!(mint_scripts.len(), 2); - let actual_scripts = mint_scripts.0.iter().cloned().collect::>(); - let expected_scripts = vec![mint_script0, mint_script1].iter().cloned().collect::>(); - assert_eq!(actual_scripts, expected_scripts); - - // One new output is created - assert_eq!(tx_builder.outputs.len(), 1); - let out = tx_builder.outputs.get(0); - - assert_eq!(out.address.to_bytes(), address.to_bytes()); - assert_eq!(out.amount.coin, coin); - - let multiasset = out.amount.multiasset.unwrap(); - - // Only second mint entry was added to the output - assert_eq!(multiasset.len(), 1); - assert!(multiasset.get(&policy_id0).is_none()); - assert!(multiasset.get(&policy_id1).is_some()); - - let asset = multiasset.get(&policy_id1).unwrap(); - assert_eq!(asset.len(), 1); - assert_eq!(asset.get(&name).unwrap(), to_bignum(1234)); - } - - #[test] - fn add_mint_asset_and_min_required_coin() { - let mut tx_builder = create_reallistic_tx_builder(); - - let (mint_script0, policy_id0) = mint_script_and_policy(0); - let (mint_script1, policy_id1) = mint_script_and_policy(1); - - let name = create_asset_name(); - let amount = Int::new_i32(1234); - - let address = byron_address(); - - // Add unrelated mint first to check it is NOT added to output later - tx_builder.add_mint_asset(&mint_script0, &name, amount.clone()); - - tx_builder - .add_mint_asset_and_output_min_required_coin( - &mint_script1, - &name, - amount.clone(), - &TransactionOutputBuilder::new() - .with_address(&address) - .next() - .unwrap(), - ) - .unwrap(); - - assert!(tx_builder.mint.is_some()); - let mint_scripts = tx_builder.mint.as_ref().unwrap().get_native_scripts(); - assert!(mint_scripts.len() > 0); - - let mint = &tx_builder.mint.unwrap().build(); - - // Mint contains two entries - assert_eq!(mint.len(), 2); - assert_mint_asset(mint, &policy_id0); - assert_mint_asset(mint, &policy_id1); - - assert_eq!(mint_scripts.len(), 2); - let actual_scripts = mint_scripts.0.iter().cloned().collect::>(); - let expected_scripts = vec![mint_script0, mint_script1].iter().cloned().collect::>(); - assert_eq!(actual_scripts, expected_scripts); - - // One new output is created - assert_eq!(tx_builder.outputs.len(), 1); - let out = tx_builder.outputs.get(0); - - assert_eq!(out.address.to_bytes(), address.to_bytes()); - assert_eq!(out.amount.coin, to_bignum(1146460)); - - let multiasset = out.amount.multiasset.unwrap(); - - // Only second mint entry was added to the output - assert_eq!(multiasset.len(), 1); - assert!(multiasset.get(&policy_id0).is_none()); - assert!(multiasset.get(&policy_id1).is_some()); - - let asset = multiasset.get(&policy_id1).unwrap(); - assert_eq!(asset.len(), 1); - assert_eq!(asset.get(&name).unwrap(), to_bignum(1234)); - } - - #[test] - fn add_mint_includes_witnesses_into_fee_estimation() { - let mut tx_builder = create_reallistic_tx_builder(); - - let hash0 = fake_key_hash(0); - - let (mint_script1, _, hash1) = mint_script_and_policy_and_hash(1); - let (mint_script2, _, _) = mint_script_and_policy_and_hash(2); - let (mint_script3, _, _) = mint_script_and_policy_and_hash(3); - - let name1 = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - let name2 = AssetName::new(vec![1u8, 1, 2, 3]).unwrap(); - let name3 = AssetName::new(vec![2u8, 1, 2, 3]).unwrap(); - let name4 = AssetName::new(vec![3u8, 1, 2, 3]).unwrap(); - let amount = Int::new_i32(1234); - - // One input from unrelated address - tx_builder.add_key_input( - &hash0, - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(10_000_000)), - ); - - // One input from same address as mint - tx_builder.add_key_input( - &hash1, - &TransactionInput::new(&genesis_id(), 1), - &Value::new(&to_bignum(10_000_000)), - ); - - // Original tx fee now assumes two VKey signatures for two inputs - let original_tx_fee = tx_builder.min_fee().unwrap(); - assert_eq!(original_tx_fee, to_bignum(168361)); - - // Add minting four assets from three different policies - tx_builder.add_mint_asset(&mint_script1, &name1, amount.clone()); - tx_builder.add_mint_asset(&mint_script2, &name2, amount.clone()); - tx_builder.add_mint_asset(&mint_script3, &name3, amount.clone()); - tx_builder.add_mint_asset(&mint_script3, &name4, amount.clone()); - - let mint = tx_builder.get_mint().unwrap(); - let mint_len = mint.to_bytes().len(); - - let mint_scripts = tx_builder.get_witness_set(); - let mint_scripts_len = - mint_scripts.to_bytes().len() - TransactionWitnessSet::new().to_bytes().len(); - - let fee_coefficient = tx_builder.config.fee_algo.coefficient(); - - let raw_mint_fee = fee_coefficient - .checked_mul(&to_bignum(mint_len as u64)) - .unwrap(); - - let raw_mint_script_fee = fee_coefficient - .checked_mul(&to_bignum(mint_scripts_len as u64)) - .unwrap(); - - assert_eq!(raw_mint_fee, to_bignum(5544)); - assert_eq!(raw_mint_script_fee, to_bignum(4312)); - - let new_tx_fee = tx_builder.min_fee().unwrap(); - - let fee_diff_from_adding_mint = new_tx_fee.checked_sub(&original_tx_fee).unwrap(); - - let witness_fee_increase = fee_diff_from_adding_mint - .checked_sub(&raw_mint_fee) - .unwrap() - .checked_sub(&raw_mint_script_fee) - .unwrap(); - - assert_eq!(witness_fee_increase, to_bignum(8932)); - - let fee_increase_bytes = from_bignum(&witness_fee_increase) - .checked_div(from_bignum(&fee_coefficient)) - .unwrap(); - - // Two vkey witnesses 96 bytes each (32 byte pubkey + 64 byte signature) - // Plus 11 bytes overhead for CBOR wrappers - // This is happening because we have three different minting policies - // but the same key-hash from one of them is already also used in inputs - // so no suplicate witness signature is require for that one - assert_eq!(fee_increase_bytes, 203); - } - - #[test] - fn fee_estimation_fails_on_missing_mint_scripts() { - let mut tx_builder = create_reallistic_tx_builder(); - - // No error estimating fee without mint - assert!(tx_builder.min_fee().is_ok()); - - let (mint_script1, policy_id1) = mint_script_and_policy(0); - let (mint_script2, _) = mint_script_and_policy(1); - - let name1 = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - let amount = Int::new_i32(1234); - - let mut mint = Mint::new(); - mint.insert( - &policy_id1, - &MintAssets::new_from_entry(&name1, amount.clone()), - ); - - tx_builder - .set_mint(&mint, &NativeScripts::from(vec![mint_script1])) - .unwrap(); - - let est1 = tx_builder.min_fee(); - assert!(est1.is_ok()); - - tx_builder.add_mint_asset(&mint_script2, &name1, amount.clone()); - - let est2 = tx_builder.min_fee(); - assert!(est2.is_ok()); - - // Native script assertion has been commented out in `.min_fee` - // Until implemented in a more performant manner - // TODO: these test parts might be returned back when it's done - - // // Remove one mint script - // tx_builder.mint_scripts = - // Some(NativeScripts::from(vec![tx_builder.mint_scripts.unwrap().get(1)])); - // - // // Now two different policies are minted but only one witness script is present - // let est3 = tx_builder.min_fee(); - // assert!(est3.is_err()); - // assert!(est3.err().unwrap().to_string().contains(&format!("{:?}", hex::encode(policy_id1.to_bytes())))); - // - // // Remove all mint scripts - // tx_builder.mint_scripts = Some(NativeScripts::new()); - // - // // Mint exists but no witness scripts at all present - // let est4 = tx_builder.min_fee(); - // assert!(est4.is_err()); - // assert!(est4.err().unwrap().to_string().contains("witness scripts are not provided")); - // - // // Remove all mint scripts - // tx_builder.mint_scripts = None; - // - // // Mint exists but no witness scripts at all present - // let est5 = tx_builder.min_fee(); - // assert!(est5.is_err()); - // assert!(est5.err().unwrap().to_string().contains("witness scripts are not provided")); - } - - #[test] - fn total_input_output_with_mint_and_burn() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - - let (mint_script1, policy_id1) = mint_script_and_policy(0); - let (mint_script2, policy_id2) = mint_script_and_policy(1); - - let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - - let ma_input1 = 100; - let ma_input2 = 200; - let ma_output1 = 60; - - let multiassets = [ma_input1, ma_input2, ma_output1] - .iter() - .map(|input| { - let mut multiasset = MultiAsset::new(); - multiasset.insert(&policy_id1, &{ - let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(*input)); - assets - }); - multiasset.insert(&policy_id2, &{ - let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(*input)); - assets - }); - multiasset - }) - .collect::>(); - - for (i, (multiasset, ada)) in multiassets - .iter() - .zip([100u64, 100, 100].iter().cloned().map(to_bignum)) - .enumerate() - { - let mut input_amount = Value::new(&ada); - input_amount.set_multiasset(multiasset); - - tx_builder.add_key_input( - &&spend.to_raw_key().hash(), - &TransactionInput::new(&genesis_id(), i as u32), - &input_amount, - ); - } - - tx_builder - .add_output( - &TransactionOutputBuilder::new() - .with_address(&byron_address()) - .next() - .unwrap() - .with_coin(&to_bignum(208)) - .build() - .unwrap(), - ) - .unwrap(); - - let total_input_before_mint = tx_builder.get_total_input().unwrap(); - let total_output_before_mint = tx_builder.get_total_output().unwrap(); - - assert_eq!(total_input_before_mint.coin, to_bignum(300)); - assert_eq!(total_output_before_mint.coin, to_bignum(208)); - let ma1_input = total_input_before_mint.multiasset.unwrap(); - let ma1_output = total_output_before_mint.multiasset; - assert_eq!( - ma1_input.get(&policy_id1).unwrap().get(&name).unwrap(), - to_bignum(360) - ); - assert_eq!( - ma1_input.get(&policy_id2).unwrap().get(&name).unwrap(), - to_bignum(360) - ); - assert!(ma1_output.is_none()); - - // Adding mint - tx_builder.add_mint_asset(&mint_script1, &name, Int::new_i32(40)); - - // Adding burn - tx_builder.add_mint_asset(&mint_script2, &name, Int::new_i32(-40)); - - let total_input_after_mint = tx_builder.get_total_input().unwrap(); - let total_output_after_mint = tx_builder.get_total_output().unwrap(); - - assert_eq!(total_input_after_mint.coin, to_bignum(300)); - assert_eq!(total_output_before_mint.coin, to_bignum(208)); - let ma2_input = total_input_after_mint.multiasset.unwrap(); - let ma2_output = total_output_after_mint.multiasset.unwrap(); - assert_eq!( - ma2_input.get(&policy_id1).unwrap().get(&name).unwrap(), - to_bignum(400) - ); - assert_eq!( - ma2_input.get(&policy_id2).unwrap().get(&name).unwrap(), - to_bignum(360) - ); - assert_eq!( - ma2_output.get(&policy_id2).unwrap().get(&name).unwrap(), - to_bignum(40) - ); - } - - fn create_base_address_from_script_hash(sh: &ScriptHash) -> Address { - BaseAddress::new( - NetworkInfo::testnet().network_id(), - &Credential::from_scripthash(sh), - &Credential::from_keyhash(&fake_key_hash(0)), - ) - .to_address() - } - - #[test] - fn test_set_input_scripts() { - let mut tx_builder = create_reallistic_tx_builder(); - let (script1, hash1) = mint_script_and_policy(0); - let (script2, hash2) = mint_script_and_policy(1); - let (script3, _hash3) = mint_script_and_policy(2); - // Trying to set native scripts to the builder - let rem0 = tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![ - script1.clone(), - script2.clone(), - script3.clone(), - ])); - assert_eq!(rem0, 0); - let missing0 = tx_builder.count_missing_input_scripts(); - assert_eq!(missing0, 0); - // Adding two script inputs using script1 and script2 hashes - tx_builder.add_input( - &create_base_address_from_script_hash(&hash1), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - tx_builder.add_input( - &create_base_address_from_script_hash(&hash2), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - // Setting a non-matching script will not change anything - let rem1 = tx_builder - .add_required_native_input_scripts(&NativeScripts::from(vec![script3.clone()])); - assert_eq!(rem1, 2); - let missing1 = tx_builder.count_missing_input_scripts(); - assert_eq!(missing1, 2); - // Setting one of the required scripts leaves one to be required - let rem2 = tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![ - script1.clone(), - script3.clone(), - ])); - assert_eq!(rem2, 1); - let missing2 = tx_builder.count_missing_input_scripts(); - assert_eq!(missing2, 1); - // Setting one non-required script again does not change anything - // But shows the state has changed - let rem3 = tx_builder - .add_required_native_input_scripts(&NativeScripts::from(vec![script3.clone()])); - assert_eq!(rem3, 1); - let missing3 = tx_builder.count_missing_input_scripts(); - assert_eq!(missing3, 1); - // Setting two required scripts will show both of them added - // And the remainder required is zero - let rem4 = tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![ - script1.clone(), - script2.clone(), - ])); - assert_eq!(rem4, 0); - let missing4 = tx_builder.count_missing_input_scripts(); - assert_eq!(missing4, 0); - // Setting empty scripts does not change anything - // But shows the state has changed - let rem5 = tx_builder.add_required_native_input_scripts(&NativeScripts::new()); - assert_eq!(rem5, 0); - } - - #[test] - fn test_add_native_script_input() { - let mut tx_builder = create_reallistic_tx_builder(); - let (script1, _hash1) = mint_script_and_policy(0); - let (script2, _hash2) = mint_script_and_policy(1); - let (script3, hash3) = mint_script_and_policy(2); - // Adding two script inputs directly with their witness - tx_builder.add_native_script_input( - &script1, - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - tx_builder.add_native_script_input( - &script2, - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - // Adding one script input indirectly via hash3 address - tx_builder.add_input( - &create_base_address_from_script_hash(&hash3), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - // Checking missing input scripts shows one - // Because first two inputs already have their witness - let missing1 = tx_builder.count_missing_input_scripts(); - assert_eq!(missing1, 1); - // Setting the required script leaves none to be required` - let rem1 = tx_builder - .add_required_native_input_scripts(&NativeScripts::from(vec![script3.clone()])); - assert_eq!(rem1, 0); - let missing2 = tx_builder.count_missing_input_scripts(); - assert_eq!(missing2, 0); - } - - fn unsafe_tx_len(b: &TransactionBuilder) -> usize { - b.build_tx_unsafe().unwrap().to_bytes().len() - } - - #[test] - fn test_native_input_scripts_are_added_to_the_witnesses() { - let mut tx_builder = create_reallistic_tx_builder(); - let (script1, _hash1) = mint_script_and_policy(0); - let (script2, hash2) = mint_script_and_policy(1); - tx_builder.set_fee(&to_bignum(42)); - tx_builder.add_native_script_input( - &script1, - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - let tx_len_before_new_script_input = unsafe_tx_len(&tx_builder); - tx_builder.add_input( - &create_base_address_from_script_hash(&hash2), - &TransactionInput::new(&genesis_id(), 1), - &Value::new(&to_bignum(1_000_000)), - ); - let tx_len_after_new_script_input = unsafe_tx_len(&tx_builder); - // Tx size increased cuz input is added even without the witness - assert!(tx_len_after_new_script_input > tx_len_before_new_script_input); - tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![script2.clone()])); - let tx_len_after_adding_script_witness = unsafe_tx_len(&tx_builder); - // Tx size increased cuz the witness is added to the witnesses - assert!(tx_len_after_adding_script_witness > tx_len_after_new_script_input); - tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![ - script1.clone(), - script2.clone(), - ])); - let tx_len_after_adding_script_witness_again = unsafe_tx_len(&tx_builder); - // Tx size did not change because calling to add same witnesses again doesn't change anything - assert!(tx_len_after_adding_script_witness == tx_len_after_adding_script_witness_again); - let tx: Transaction = tx_builder.build_tx_unsafe().unwrap(); - assert!(tx.witness_set.native_scripts.is_some()); - let native_scripts = tx.witness_set.native_scripts.unwrap(); - assert_eq!(native_scripts.len(), 2); - assert_eq!(native_scripts.get(0), script1); - assert_eq!(native_scripts.get(1), script2); - } - - #[test] - fn test_building_with_missing_witness_script_fails() { - let mut tx_builder = create_reallistic_tx_builder(); - let (script1, _hash1) = mint_script_and_policy(0); - let (script2, hash2) = mint_script_and_policy(1); - tx_builder.set_fee(&to_bignum(42)); - // Ok to build before any inputs - assert!(tx_builder.build_tx().is_ok()); - // Adding native script input which adds the witness right away - tx_builder.add_native_script_input( - &script1, - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - // Ok to build when witness is added along with the input - assert!(tx_builder.build_tx().is_ok()); - // Adding script input without the witness - tx_builder.add_input( - &create_base_address_from_script_hash(&hash2), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - // Not ok to build when missing a witness - assert!(tx_builder.build_tx().is_err()); - // Can force to build using unsafe - assert!(tx_builder.build_tx_unsafe().is_ok()); - // Adding the missing witness script - tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![script2.clone()])); - // Ok to build when all witnesses are added - assert!(tx_builder.build_tx().is_ok()); - } - - #[test] - fn test_adding_plutus_script_input() { - let mut tx_builder = create_reallistic_tx_builder(); - let (script1, _) = plutus_script_and_hash(0); - let datum = PlutusData::new_bytes(fake_bytes_32(1)); - let redeemer_datum = PlutusData::new_bytes(fake_bytes_32(2)); - let redeemer = Redeemer::new( - &RedeemerTag::new_spend(), - &to_bignum(0), - &redeemer_datum, - &ExUnits::new(&to_bignum(1), &to_bignum(2)), - ); - tx_builder.add_plutus_script_input( - &PlutusWitness::new(&script1, &datum, &redeemer), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - tx_builder.set_fee(&to_bignum(42)); - // There are no missing script witnesses - assert_eq!(tx_builder.count_missing_input_scripts(), 0); - let tx: Transaction = tx_builder.build_tx_unsafe().unwrap(); - assert!(tx.witness_set.plutus_scripts.is_some()); - assert_eq!(tx.witness_set.plutus_scripts.unwrap().get(0), script1); - assert!(tx.witness_set.plutus_data.is_some()); - assert_eq!(tx.witness_set.plutus_data.unwrap().get(0), datum); - assert!(tx.witness_set.redeemers.is_some()); - assert_eq!(tx.witness_set.redeemers.unwrap().get(0), redeemer); - } - - #[test] - fn test_adding_plutus_script_witnesses() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); - let (script1, hash1) = plutus_script_and_hash(0); - let (script2, hash2) = plutus_script_and_hash(1); - let (script3, _hash3) = plutus_script_and_hash(3); - let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); - let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); - let redeemer1 = Redeemer::new( - &RedeemerTag::new_spend(), - &to_bignum(0), - &PlutusData::new_bytes(fake_bytes_32(20)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), - ); - let redeemer2 = Redeemer::new( - &RedeemerTag::new_spend(), - &to_bignum(1), - &PlutusData::new_bytes(fake_bytes_32(21)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), - ); - tx_builder.add_input( - &create_base_address_from_script_hash(&hash1), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - tx_builder.add_input( - &create_base_address_from_script_hash(&hash2), - &TransactionInput::new(&genesis_id(), 1), - &Value::new(&to_bignum(1_000_000)), - ); - // There are TWO missing script witnesses - assert_eq!(tx_builder.count_missing_input_scripts(), 2); - // Calling to add two plutus witnesses, one of which is irrelevant - tx_builder.add_required_plutus_input_scripts(&PlutusWitnesses::from(vec![ - PlutusWitness::new(&script1, &datum1, &redeemer1), - PlutusWitness::new(&script3, &datum2, &redeemer2), - ])); - // There is now ONE missing script witnesses - assert_eq!(tx_builder.count_missing_input_scripts(), 1); - // Calling to add the one remaining relevant plutus witness now - tx_builder.add_required_plutus_input_scripts(&PlutusWitnesses::from(vec![ - PlutusWitness::new(&script2, &datum2, &redeemer2), - ])); - // There is now no missing script witnesses - assert_eq!(tx_builder.count_missing_input_scripts(), 0); - let tx: Transaction = tx_builder.build_tx_unsafe().unwrap(); - // Check there are two correct scripts - assert!(tx.witness_set.plutus_scripts.is_some()); - let pscripts = tx.witness_set.plutus_scripts.unwrap(); - assert_eq!(pscripts.len(), 2); - assert_eq!(pscripts.get(0), script1); - assert_eq!(pscripts.get(1), script2); - // Check there are two correct datums - assert!(tx.witness_set.plutus_data.is_some()); - let datums = tx.witness_set.plutus_data.unwrap(); - assert_eq!(datums.len(), 2); - assert_eq!(datums.get(0), datum1); - assert_eq!(datums.get(1), datum2); - // Check there are two correct redeemers - assert!(tx.witness_set.redeemers.is_some()); - let redeems = tx.witness_set.redeemers.unwrap(); - assert_eq!(redeems.len(), 2); - assert_eq!(redeems.get(0), redeemer1); - assert_eq!(redeems.get(1), redeemer2); - } - - fn create_collateral() -> TxInputsBuilder { - let mut collateral_builder = TxInputsBuilder::new(); - collateral_builder.add_input( - &byron_address(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - collateral_builder - } - - #[test] - fn test_existing_plutus_scripts_require_data_hash() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); - tx_builder.set_collateral(&create_collateral()); - let (script1, _) = plutus_script_and_hash(0); - let datum = PlutusData::new_bytes(fake_bytes_32(1)); - let redeemer_datum = PlutusData::new_bytes(fake_bytes_32(2)); - let redeemer = Redeemer::new( - &RedeemerTag::new_spend(), - &to_bignum(0), - &redeemer_datum, - &ExUnits::new(&to_bignum(1), &to_bignum(2)), - ); - tx_builder.add_plutus_script_input( - &PlutusWitness::new(&script1, &datum, &redeemer), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - - // Using SAFE `.build_tx` - let res = tx_builder.build_tx(); - assert!(res.is_err()); - if let Err(e) = res { - assert!(e.as_string().unwrap().contains("script data hash")); - } - - // Setting script data hash removes the error - tx_builder.set_script_data_hash(&ScriptDataHash::from_bytes(fake_bytes_32(42)).unwrap()); - // Using SAFE `.build_tx` - let res2 = tx_builder.build_tx(); - assert!(res2.is_ok()); - - // Removing script data hash will cause error again - tx_builder.remove_script_data_hash(); - // Using SAFE `.build_tx` - let res3 = tx_builder.build_tx(); - assert!(res3.is_err()); - } - - #[test] - fn test_calc_script_hash_data() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); - tx_builder.set_collateral(&create_collateral()); - - let (script1, _) = plutus_script_and_hash(0); - let datum = PlutusData::new_bytes(fake_bytes_32(1)); - let redeemer_datum = PlutusData::new_bytes(fake_bytes_32(2)); - let redeemer = Redeemer::new( - &RedeemerTag::new_spend(), - &to_bignum(0), - &redeemer_datum, - &ExUnits::new(&to_bignum(1), &to_bignum(2)), - ); - tx_builder.add_plutus_script_input( - &PlutusWitness::new(&script1, &datum, &redeemer), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - - // Setting script data hash removes the error - tx_builder - .calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()) - .unwrap(); - - // Using SAFE `.build_tx` - let res2 = tx_builder.build_tx(); - assert!(res2.is_ok()); - - let mut used_langs = Languages::new(); - used_langs.add(Language::new_plutus_v1()); - - let data_hash = hash_script_data( - &Redeemers::from(vec![redeemer.clone()]), - &TxBuilderConstants::plutus_default_cost_models().retain_language_versions(&used_langs), - Some(PlutusList::from(vec![datum])), - ); - assert_eq!(tx_builder.script_data_hash.unwrap(), data_hash); - } - - #[test] - fn test_plutus_witness_redeemer_index_auto_changing() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); - tx_builder.set_collateral(&create_collateral()); - let (script1, _) = plutus_script_and_hash(0); - let (script2, _) = plutus_script_and_hash(1); - let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); - let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); - - // Creating redeemers with indexes ZERO - let redeemer1 = Redeemer::new( - &RedeemerTag::new_spend(), - &to_bignum(0), - &PlutusData::new_bytes(fake_bytes_32(20)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), - ); - let redeemer2 = Redeemer::new( - &RedeemerTag::new_spend(), - &to_bignum(0), - &PlutusData::new_bytes(fake_bytes_32(21)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), - ); - - // Add a regular NON-script input first - tx_builder.add_input( - &byron_address(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - - // Adding two plutus inputs then - // both have redeemers with index ZERO - tx_builder.add_plutus_script_input( - &PlutusWitness::new(&script1, &datum1, &redeemer1), - &TransactionInput::new(&genesis_id(), 1), - &Value::new(&to_bignum(1_000_000)), - ); - tx_builder.add_plutus_script_input( - &PlutusWitness::new(&script2, &datum2, &redeemer2), - &TransactionInput::new(&genesis_id(), 2), - &Value::new(&to_bignum(1_000_000)), - ); - - // Calc the script data hash - tx_builder - .calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()) - .unwrap(); - - let tx: Transaction = tx_builder.build_tx().unwrap(); - assert!(tx.witness_set.redeemers.is_some()); - let redeems = tx.witness_set.redeemers.unwrap(); - assert_eq!(redeems.len(), 2); - - fn compare_redeems(r1: Redeemer, r2: Redeemer) { - assert_eq!(r1.tag(), r2.tag()); - assert_eq!(r1.data(), r2.data()); - assert_eq!(r1.ex_units(), r2.ex_units()); - } - - compare_redeems(redeems.get(0), redeemer1); - compare_redeems(redeems.get(1), redeemer2); - - // Note the redeemers from the result transaction are equal with source redeemers - // In everything EXCEPT the index field, the indexes have changed to 1 and 2 - // To match the position of their corresponding input - assert_eq!(redeems.get(0).index(), to_bignum(1)); - assert_eq!(redeems.get(1).index(), to_bignum(2)); - } - - #[test] - fn test_native_and_plutus_scripts_together() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); - tx_builder.set_collateral(&create_collateral()); - let (pscript1, _) = plutus_script_and_hash(0); - let (pscript2, phash2) = plutus_script_and_hash(1); - let (nscript1, _) = mint_script_and_policy(0); - let (nscript2, nhash2) = mint_script_and_policy(1); - let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); - let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); - // Creating redeemers with indexes ZERO - let redeemer1 = Redeemer::new( - &RedeemerTag::new_spend(), - &to_bignum(0), - &PlutusData::new_bytes(fake_bytes_32(20)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), - ); - let redeemer2 = Redeemer::new( - &RedeemerTag::new_spend(), - &to_bignum(0), - &PlutusData::new_bytes(fake_bytes_32(21)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), - ); - - // Add one plutus input directly with witness - tx_builder.add_plutus_script_input( - &PlutusWitness::new(&pscript1, &datum1, &redeemer1), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - // Add one native input directly with witness - tx_builder.add_native_script_input( - &nscript1, - &TransactionInput::new(&genesis_id(), 1), - &Value::new(&to_bignum(1_000_000)), - ); - // Add one plutus input generically without witness - tx_builder.add_input( - &create_base_address_from_script_hash(&phash2), - &TransactionInput::new(&genesis_id(), 2), - &Value::new(&to_bignum(1_000_000)), - ); - // Add one native input generically without witness - tx_builder.add_input( - &create_base_address_from_script_hash(&nhash2), - &TransactionInput::new(&genesis_id(), 3), - &Value::new(&to_bignum(1_000_000)), - ); - - // There are two missing script witnesses - assert_eq!(tx_builder.count_missing_input_scripts(), 2); - - let remaining1 = - tx_builder.add_required_plutus_input_scripts(&PlutusWitnesses::from(vec![ - PlutusWitness::new(&pscript2, &datum2, &redeemer2), - ])); - - // There is one missing script witness now - assert_eq!(remaining1, 1); - assert_eq!(tx_builder.count_missing_input_scripts(), 1); - - let remaining2 = tx_builder - .add_required_native_input_scripts(&NativeScripts::from(vec![nscript2.clone()])); - - // There are no missing script witnesses now - assert_eq!(remaining2, 0); - assert_eq!(tx_builder.count_missing_input_scripts(), 0); - - tx_builder - .calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()) - .unwrap(); - - let tx: Transaction = tx_builder.build_tx().unwrap(); - - let wits = tx.witness_set; - assert!(wits.native_scripts.is_some()); - assert!(wits.plutus_scripts.is_some()); - assert!(wits.plutus_data.is_some()); - assert!(wits.redeemers.is_some()); - - let nscripts = wits.native_scripts.unwrap(); - assert_eq!(nscripts.len(), 2); - assert_eq!(nscripts.get(0), nscript1); - assert_eq!(nscripts.get(1), nscript2); - - let pscripts = wits.plutus_scripts.unwrap(); - assert_eq!(pscripts.len(), 2); - assert_eq!(pscripts.get(0), pscript1); - assert_eq!(pscripts.get(1), pscript2); - - let datums = wits.plutus_data.unwrap(); - assert_eq!(datums.len(), 2); - assert_eq!(datums.get(0), datum1); - assert_eq!(datums.get(1), datum2); - - let redeems = wits.redeemers.unwrap(); - assert_eq!(redeems.len(), 2); - assert_eq!(redeems.get(0), redeemer1); - - // The second plutus input redeemer index has automatically changed to 2 - // because it was added on the third position - assert_eq!(redeems.get(1), redeemer2.clone_with_index(&to_bignum(2))); - } - - #[test] - fn test_json_serialization_native_and_plutus_scripts_together() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); - tx_builder.set_collateral(&create_collateral()); - let (pscript1, _) = plutus_script_and_hash(0); - let (pscript2, phash2) = plutus_script_and_hash(1); - let (nscript1, _) = mint_script_and_policy(0); - let (nscript2, nhash2) = mint_script_and_policy(1); - let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); - let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); - // Creating redeemers with indexes ZERO - let redeemer1 = Redeemer::new( - &RedeemerTag::new_spend(), - &to_bignum(0), - &PlutusData::new_bytes(fake_bytes_32(20)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), - ); - let redeemer2 = Redeemer::new( - &RedeemerTag::new_spend(), - &to_bignum(0), - &PlutusData::new_bytes(fake_bytes_32(21)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), - ); - - // Add one plutus input directly with witness - tx_builder.add_plutus_script_input( - &PlutusWitness::new(&pscript1, &datum1, &redeemer1), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - // Add one native input directly with witness - tx_builder.add_native_script_input( - &nscript1, - &TransactionInput::new(&genesis_id(), 1), - &Value::new(&to_bignum(1_000_000)), - ); - // Add one plutus input generically without witness - tx_builder.add_input( - &create_base_address_from_script_hash(&phash2), - &TransactionInput::new(&genesis_id(), 2), - &Value::new(&to_bignum(1_000_000)), - ); - // Add one native input generically without witness - tx_builder.add_input( - &create_base_address_from_script_hash(&nhash2), - &TransactionInput::new(&genesis_id(), 3), - &Value::new(&to_bignum(1_000_000)), - ); - - // There are two missing script witnesses - assert_eq!(tx_builder.count_missing_input_scripts(), 2); - - let remaining1 = - tx_builder.add_required_plutus_input_scripts(&PlutusWitnesses::from(vec![ - PlutusWitness::new(&pscript2, &datum2, &redeemer2), - ])); - - // There is one missing script witness now - assert_eq!(remaining1, 1); - assert_eq!(tx_builder.count_missing_input_scripts(), 1); - - let remaining2 = tx_builder - .add_required_native_input_scripts(&NativeScripts::from(vec![nscript2.clone()])); - - // There are no missing script witnesses now - assert_eq!(remaining2, 0); - assert_eq!(tx_builder.count_missing_input_scripts(), 0); - - tx_builder.calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()); - - let tx: Transaction = tx_builder.build_tx().unwrap(); - - let json_tx = tx.to_json().unwrap(); - let deser_tx = Transaction::from_json(json_tx.as_str()).unwrap(); - - assert_eq!(deser_tx.to_bytes(), tx.to_bytes()); - assert_eq!(deser_tx.to_json().unwrap(), tx.to_json().unwrap()); - } - - #[test] - fn test_regular_and_collateral_inputs_same_keyhash() { - let mut input_builder = TxInputsBuilder::new(); - let mut collateral_builder = TxInputsBuilder::new(); - - // Add a single input of both kinds with the SAME keyhash - input_builder.add_input( - &fake_base_address(0), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - collateral_builder.add_input( - &fake_base_address(0), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - - fn get_fake_vkeys_count(i: &TxInputsBuilder, c: &TxInputsBuilder) -> usize { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); - tx_builder.set_inputs(i); - tx_builder.set_collateral(c); - let tx: Transaction = fake_full_tx(&tx_builder, tx_builder.build().unwrap()).unwrap(); - tx.witness_set.vkeys.unwrap().len() - } - - // There's only one fake witness in the builder - // because a regular and a collateral inputs both use the same keyhash - assert_eq!(get_fake_vkeys_count(&input_builder, &collateral_builder), 1); - - // Add a new input of each kind with DIFFERENT keyhashes - input_builder.add_input( - &fake_base_address(1), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - collateral_builder.add_input( - &fake_base_address(2), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - - // There are now three fake witnesses in the builder - // because all three unique keyhashes got combined - assert_eq!(get_fake_vkeys_count(&input_builder, &collateral_builder), 3); - } - - #[test] - fn test_regular_and_collateral_inputs_together() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); - let (pscript1, _) = plutus_script_and_hash(0); - let (pscript2, _) = plutus_script_and_hash(1); - let (nscript1, _) = mint_script_and_policy(0); - let (nscript2, _) = mint_script_and_policy(1); - let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); - let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); - // Creating redeemers with indexes ZERO - let redeemer1 = Redeemer::new( - &RedeemerTag::new_spend(), - &to_bignum(0), - &PlutusData::new_bytes(fake_bytes_32(20)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), - ); - let redeemer2 = Redeemer::new( - &RedeemerTag::new_spend(), - &to_bignum(0), - &PlutusData::new_bytes(fake_bytes_32(21)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), - ); - - let mut input_builder = TxInputsBuilder::new(); - let mut collateral_builder = TxInputsBuilder::new(); - - input_builder.add_native_script_input( - &nscript1, - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - collateral_builder.add_native_script_input( - &nscript2, - &TransactionInput::new(&genesis_id(), 1), - &Value::new(&to_bignum(1_000_000)), - ); - - input_builder.add_plutus_script_input( - &PlutusWitness::new(&pscript1, &datum1, &redeemer1), - &TransactionInput::new(&genesis_id(), 2), - &Value::new(&to_bignum(1_000_000)), - ); - collateral_builder.add_plutus_script_input( - &PlutusWitness::new(&pscript2, &datum2, &redeemer2), - &TransactionInput::new(&genesis_id(), 3), - &Value::new(&to_bignum(1_000_000)), - ); - - tx_builder.set_inputs(&input_builder); - tx_builder.set_collateral(&collateral_builder); - - tx_builder - .calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()) - .unwrap(); - - let w: &TransactionWitnessSet = &tx_builder.build_tx().unwrap().witness_set; - - assert!(w.native_scripts.is_some()); - let nscripts = w.native_scripts.as_ref().unwrap(); - assert_eq!(nscripts.len(), 2); - assert_eq!(nscripts.get(0), nscript1); - assert_eq!(nscripts.get(1), nscript2); - - assert!(w.plutus_scripts.is_some()); - let pscripts = w.plutus_scripts.as_ref().unwrap(); - assert_eq!(pscripts.len(), 2); - assert_eq!(pscripts.get(0), pscript1); - assert_eq!(pscripts.get(1), pscript2); - - assert!(w.plutus_data.is_some()); - let datums = w.plutus_data.as_ref().unwrap(); - assert_eq!(datums.len(), 2); - assert_eq!(datums.get(0), datum1); - assert_eq!(datums.get(1), datum2); - - assert!(w.redeemers.is_some()); - let redeemers = w.redeemers.as_ref().unwrap(); - assert_eq!(redeemers.len(), 2); - assert_eq!(redeemers.get(0), redeemer1.clone_with_index(&to_bignum(1))); - assert_eq!(redeemers.get(1), redeemer2.clone_with_index(&to_bignum(1))); - } - - #[test] - fn test_ex_unit_costs_are_added_to_the_fees() { - fn calc_fee_with_ex_units(mem: u64, step: u64) -> Coin { - let mut input_builder = TxInputsBuilder::new(); - let mut collateral_builder = TxInputsBuilder::new(); - - // Add a single input of both kinds with the SAME keyhash - input_builder.add_input( - &fake_base_address(0), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - collateral_builder.add_input( - &fake_base_address(0), - &TransactionInput::new(&genesis_id(), 1), - &Value::new(&to_bignum(1_000_000)), - ); - - let (pscript1, _) = plutus_script_and_hash(0); - let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); - let redeemer1 = Redeemer::new( - &RedeemerTag::new_spend(), - &to_bignum(0), - &PlutusData::new_bytes(fake_bytes_32(20)), - &ExUnits::new(&to_bignum(mem), &to_bignum(step)), - ); - input_builder.add_plutus_script_input( - &PlutusWitness::new(&pscript1, &datum1, &redeemer1), - &TransactionInput::new(&genesis_id(), 2), - &Value::new(&to_bignum(1_000_000)), - ); - - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_inputs(&input_builder); - tx_builder.set_collateral(&collateral_builder); - - tx_builder - .add_change_if_needed(&fake_base_address(42)) - .unwrap(); - - tx_builder.get_fee_if_set().unwrap() - } - - assert_eq!(calc_fee_with_ex_units(0, 0), to_bignum(173509)); - assert_eq!(calc_fee_with_ex_units(10000, 0), to_bignum(174174)); - assert_eq!(calc_fee_with_ex_units(0, 10000000), to_bignum(174406)); - assert_eq!(calc_fee_with_ex_units(10000, 10000000), to_bignum(175071)); - } - - #[test] - fn test_script_inputs_ordering() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); - let (nscript1, _) = mint_script_and_policy(0); - let (pscript1, _) = plutus_script_and_hash(0); - let (pscript2, _) = plutus_script_and_hash(1); - let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); - let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); - // Creating redeemers with indexes ZERO - let pdata1 = PlutusData::new_bytes(fake_bytes_32(20)); - let pdata2 = PlutusData::new_bytes(fake_bytes_32(21)); - let redeemer1 = Redeemer::new( - &RedeemerTag::new_spend(), - &to_bignum(0), - &pdata1, - &ExUnits::new(&to_bignum(1), &to_bignum(2)), - ); - let redeemer2 = Redeemer::new( - &RedeemerTag::new_spend(), - &to_bignum(0), - &pdata2, - &ExUnits::new(&to_bignum(1), &to_bignum(2)), - ); - - tx_builder.add_plutus_script_input( - &PlutusWitness::new(&pscript1, &datum1, &redeemer1), - &fake_tx_input2(2, 1), - &fake_value(), - ); - tx_builder.add_native_script_input(&nscript1, &fake_tx_input2(1, 0), &fake_value()); - tx_builder.add_plutus_script_input( - &PlutusWitness::new(&pscript2, &datum2, &redeemer2), - &fake_tx_input2(2, 0), - &fake_value(), - ); - - let tx: Transaction = tx_builder.build_tx_unsafe().unwrap(); - - let ins = tx.body.inputs; - assert_eq!(ins.len(), 3); - assert_eq!(ins.get(0).transaction_id.0[0], 1); - assert_eq!(ins.get(1).transaction_id.0[0], 2); - assert_eq!(ins.get(1).index, 0); - assert_eq!(ins.get(2).transaction_id.0[0], 2); - assert_eq!(ins.get(2).index, 1); - - let r: Redeemers = tx.witness_set.redeemers.unwrap(); - assert_eq!(r.len(), 2); - - // Redeemer1 now has the index 2 even tho the input was added first - assert_eq!(r.get(0).data(), pdata1); - assert_eq!(r.get(0).index(), to_bignum(2)); - - // Redeemer1 now has the index 1 even tho the input was added last - assert_eq!(r.get(1).data(), pdata2); - assert_eq!(r.get(1).index(), to_bignum(1)); - } - - #[test] - fn test_required_signers() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); - let tx1: TransactionBody = tx_builder.build().unwrap(); - assert!(tx1.required_signers.is_none()); - - let s1 = fake_key_hash(1); - let s2 = fake_key_hash(22); - let s3 = fake_key_hash(133); - - tx_builder.add_required_signer(&s1); - tx_builder.add_required_signer(&s3); - tx_builder.add_required_signer(&s2); - - let tx1: TransactionBody = tx_builder.build().unwrap(); - assert!(tx1.required_signers.is_some()); - - let rs: RequiredSigners = tx1.required_signers.unwrap(); - assert_eq!(rs.len(), 3); - assert_eq!(rs.get(0), s1); - assert_eq!(rs.get(1), s3); - assert_eq!(rs.get(2), s2); - } - - #[test] - fn test_required_signers_are_added_to_the_witness_estimate() { - fn count_fake_witnesses_with_required_signers(keys: &Ed25519KeyHashes) -> usize { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); - tx_builder.add_input( - &fake_base_address(0), - &TransactionInput::new(&fake_tx_hash(0), 0), - &Value::new(&to_bignum(10_000_000)), - ); - - keys.0.iter().for_each(|k| { - tx_builder.add_required_signer(k); - }); - - let tx: Transaction = fake_full_tx(&tx_builder, tx_builder.build().unwrap()).unwrap(); - tx.witness_set.vkeys.unwrap().len() - } - - assert_eq!( - count_fake_witnesses_with_required_signers(&Ed25519KeyHashes::new(),), - 1 - ); - - assert_eq!( - count_fake_witnesses_with_required_signers(&Ed25519KeyHashes(vec![fake_key_hash(1)]),), - 2 - ); - - assert_eq!( - count_fake_witnesses_with_required_signers(&Ed25519KeyHashes(vec![ - fake_key_hash(1), - fake_key_hash(2) - ]),), - 3 - ); - - // This case still produces only 3 fake signatures, because the same key is already used in the input address - assert_eq!( - count_fake_witnesses_with_required_signers(&Ed25519KeyHashes(vec![ - fake_key_hash(1), - fake_key_hash(2), - fake_key_hash(0) - ]),), - 3 - ); - - // When a different key is used - 4 fake witnesses are produced - assert_eq!( - count_fake_witnesses_with_required_signers(&Ed25519KeyHashes(vec![ - fake_key_hash(1), - fake_key_hash(2), - fake_key_hash(3) - ]),), - 4 - ); - } - - #[test] - fn collateral_return_and_total_collateral_setters() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); - - let mut inp = TxInputsBuilder::new(); - inp.add_input(&fake_base_address(0), &fake_tx_input(0), &fake_value()); - - tx_builder.set_inputs(&inp); - tx_builder.set_collateral(&inp); - - let col_return = TransactionOutput::new(&fake_base_address(1), &fake_value2(123123)); - let col_total = to_bignum(234234); - - tx_builder.set_collateral_return(&col_return); - tx_builder.set_total_collateral(&col_total); - - let tx: Transaction = tx_builder.build_tx_unsafe().unwrap(); - assert!(tx.body.collateral_return.is_some()); - assert_eq!(tx.body.collateral_return.unwrap(), col_return); - assert!(tx.body.total_collateral.is_some()); - assert_eq!(tx.body.total_collateral.unwrap(), col_total); - } - - fn fake_multiasset(amount: u64) -> MultiAsset { - let (_, policy_id) = mint_script_and_policy(234); - let mut assets = Assets::new(); - assets.insert( - &AssetName::new(fake_bytes_32(235)).unwrap(), - &to_bignum(amount), - ); - let mut masset = MultiAsset::new(); - masset.insert(&policy_id, &assets); - masset - } - - #[test] - fn inputs_builder_total_value() { - let mut b = TxInputsBuilder::new(); - assert_eq!(b.total_value().unwrap(), Value::zero()); - - b.add_input( - &fake_base_address(0), - &fake_tx_input(0), - &fake_value2(100_000), - ); - assert_eq!(b.total_value().unwrap(), Value::new(&to_bignum(100_000))); - - b.add_input( - &fake_base_address(1), - &fake_tx_input(1), - &fake_value2(200_000), - ); - assert_eq!(b.total_value().unwrap(), Value::new(&to_bignum(300_000))); - - let masset = fake_multiasset(123); - - b.add_input( - &fake_base_address(2), - &fake_tx_input(2), - &Value::new_with_assets(&to_bignum(300_000), &masset), - ); - assert_eq!( - b.total_value().unwrap(), - Value::new_with_assets(&to_bignum(600_000), &masset) - ); - } - - #[test] - fn test_auto_calc_total_collateral() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); - - let mut inp = TxInputsBuilder::new(); - let collateral_input_value = 2_000_000; - inp.add_input( - &fake_base_address(0), - &fake_tx_input(0), - &fake_value2(collateral_input_value.clone()), - ); - - tx_builder.set_collateral(&inp); - - let collateral_return_value = 1_234_567; - let col_return = TransactionOutput::new( - &fake_base_address(1), - &fake_value2(collateral_return_value.clone()), - ); - - tx_builder - .set_collateral_return_and_total(&col_return) - .unwrap(); - - assert!(tx_builder.collateral_return.is_some()); - assert_eq!(tx_builder.collateral_return.unwrap(), col_return,); - - assert!(tx_builder.total_collateral.is_some()); - assert_eq!( - tx_builder.total_collateral.unwrap(), - to_bignum(collateral_input_value - collateral_return_value), - ); - } - - #[test] - fn test_auto_calc_total_collateral_with_assets() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); - - let masset = fake_multiasset(123); - - let mut inp = TxInputsBuilder::new(); - let collateral_input_value = 2_000_000; - inp.add_input( - &fake_base_address(0), - &fake_tx_input(0), - &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), - ); - - tx_builder.set_collateral(&inp); - - let collateral_return_value = 1_345_678; - let col_return = TransactionOutput::new( - &fake_base_address(1), - &Value::new_with_assets(&to_bignum(collateral_return_value.clone()), &masset), - ); - - tx_builder - .set_collateral_return_and_total(&col_return) - .unwrap(); - - assert!(tx_builder.collateral_return.is_some()); - assert_eq!(tx_builder.collateral_return.unwrap(), col_return,); - - assert!(tx_builder.total_collateral.is_some()); - assert_eq!( - tx_builder.total_collateral.unwrap(), - to_bignum(collateral_input_value - collateral_return_value), - ); - } - - #[test] - fn test_auto_calc_total_collateral_fails_with_assets() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); - - let masset = fake_multiasset(123); - - let mut inp = TxInputsBuilder::new(); - let collateral_input_value = 2_000_000; - inp.add_input( - &fake_base_address(0), - &fake_tx_input(0), - &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), - ); - - tx_builder.set_collateral(&inp); - - // Collateral return does not handle ALL the assets from collateral input - let collateral_return_value = 1_345_678; - let col_return = TransactionOutput::new( - &fake_base_address(1), - &fake_value2(collateral_return_value.clone()), - ); - - let res = tx_builder.set_collateral_return_and_total(&col_return); - - // Function call returns an error - assert!(res.is_err()); - - // NEITHER total collateral nor collateral return are changed in the builder - assert!(tx_builder.total_collateral.is_none()); - assert!(tx_builder.collateral_return.is_none()); - } - - #[test] - fn test_auto_calc_total_collateral_fails_on_no_collateral() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); - - let res = tx_builder.set_collateral_return_and_total(&TransactionOutput::new( - &fake_base_address(1), - &fake_value2(1_345_678), - )); - - // Function call returns an error - assert!(res.is_err()); - - // NEITHER total collateral nor collateral return are changed in the builder - assert!(tx_builder.total_collateral.is_none()); - assert!(tx_builder.collateral_return.is_none()); - } - - #[test] - fn test_auto_calc_total_collateral_fails_on_no_ada() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); - - let mut inp = TxInputsBuilder::new(); - let collateral_input_value = 2_000_000; - inp.add_input( - &fake_base_address(0), - &fake_tx_input(0), - &Value::new(&to_bignum(collateral_input_value.clone())), - ); - - tx_builder.set_collateral(&inp); - - let res = tx_builder.set_collateral_return_and_total(&TransactionOutput::new( - &fake_base_address(1), - &fake_value2(1), - )); - - // Function call returns an error - assert!(res.is_err()); - - // NEITHER total collateral nor collateral return are changed in the builder - assert!(tx_builder.total_collateral.is_none()); - assert!(tx_builder.collateral_return.is_none()); - } - - #[test] - fn test_auto_calc_collateral_return() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); - - let mut inp = TxInputsBuilder::new(); - let collateral_input_value = 2_000_000; - inp.add_input( - &fake_base_address(0), - &fake_tx_input(0), - &fake_value2(collateral_input_value.clone()), - ); - - tx_builder.set_collateral(&inp); - - let total_collateral_value = 234_567; - let collateral_return_address = fake_base_address(1); - - tx_builder - .set_total_collateral_and_return( - &to_bignum(total_collateral_value.clone()), - &collateral_return_address, - ) - .unwrap(); - - assert!(tx_builder.total_collateral.is_some()); - assert_eq!( - tx_builder.total_collateral.unwrap(), - to_bignum(total_collateral_value.clone()), - ); - - assert!(tx_builder.collateral_return.is_some()); - let col_return: TransactionOutput = tx_builder.collateral_return.unwrap(); - assert_eq!(col_return.address, collateral_return_address); - assert_eq!( - col_return.amount, - Value::new(&to_bignum(collateral_input_value - total_collateral_value),) - ); - } - - #[test] - fn test_auto_calc_collateral_return_with_assets() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); - - let masset = fake_multiasset(123); - - let mut inp = TxInputsBuilder::new(); - let collateral_input_value = 2_000_000; - inp.add_input( - &fake_base_address(0), - &fake_tx_input(0), - &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), - ); - - tx_builder.set_collateral(&inp); - - let total_collateral_value = 345_678; - let collateral_return_address = fake_base_address(1); - - tx_builder - .set_total_collateral_and_return( - &to_bignum(total_collateral_value.clone()), - &collateral_return_address, - ) - .unwrap(); - - assert!(tx_builder.total_collateral.is_some()); - assert_eq!( - tx_builder.total_collateral.unwrap(), - to_bignum(total_collateral_value.clone()), - ); - - assert!(tx_builder.collateral_return.is_some()); - let col_return: TransactionOutput = tx_builder.collateral_return.unwrap(); - assert_eq!(col_return.address, collateral_return_address); - assert_eq!( - col_return.amount, - Value::new_with_assets( - &to_bignum(collateral_input_value - total_collateral_value), - &masset, - ) - ); - } - - #[test] - fn test_add_collateral_return_succeed_with_border_amount() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); - - let masset = fake_multiasset(123); - - let mut inp = TxInputsBuilder::new(); - let collateral_input_value = 2_000_000; - inp.add_input( - &fake_base_address(0), - &fake_tx_input(0), - &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), - ); - - tx_builder.set_collateral(&inp); - - let collateral_return_address = fake_base_address(1); - - let possible_ret = Value::new_from_assets(&masset); - let fake_out = TransactionOutput::new(&collateral_return_address, &possible_ret); - let min_ada = min_ada_for_output(&fake_out, &tx_builder.config.utxo_cost()).unwrap(); - - let total_collateral_value = to_bignum(collateral_input_value) - .checked_sub(&min_ada) - .unwrap(); - - tx_builder - .set_total_collateral_and_return(&total_collateral_value, &collateral_return_address) - .unwrap(); - - assert!(tx_builder.total_collateral.is_some()); - assert!(tx_builder.collateral_return.is_some()); - let col_return: TransactionOutput = tx_builder.collateral_return.unwrap(); - assert_eq!(col_return.address, collateral_return_address); - assert_eq!( - col_return.amount, - Value::new_with_assets(&min_ada, &masset,) - ); - } - - #[test] - fn test_add_zero_collateral_return() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); - - let mut inp = TxInputsBuilder::new(); - let collateral_input_value = 2_000_000; - inp.add_input( - &fake_base_address(0), - &fake_tx_input(0), - &Value::new(&to_bignum(collateral_input_value.clone())), - ); - - tx_builder.set_collateral(&inp); - - let collateral_return_address = fake_base_address(1); - - tx_builder - .set_total_collateral_and_return( - &to_bignum(collateral_input_value.clone()), - &collateral_return_address, - ) - .unwrap(); - - assert!(tx_builder.total_collateral.is_some()); - assert!(tx_builder.collateral_return.is_none()); - } - - #[test] - fn test_add_collateral_return_fails_no_enough_ada() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); - - let masset = fake_multiasset(123); - - let mut inp = TxInputsBuilder::new(); - let collateral_input_value = 2_000_000; - inp.add_input( - &fake_base_address(0), - &fake_tx_input(0), - &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), - ); - - tx_builder.set_collateral(&inp); - - let collateral_return_address = fake_base_address(1); - - let possible_ret = Value::new_from_assets(&masset); - let fake_out = TransactionOutput::new(&collateral_return_address, &possible_ret); - let min_ada = min_ada_for_output(&fake_out, &tx_builder.config.utxo_cost()).unwrap(); - let mut total_collateral_value = to_bignum(collateral_input_value) - .checked_sub(&min_ada) - .unwrap(); - //make total collateral value bigger for make collateral return less then min ada - total_collateral_value = total_collateral_value.checked_add(&to_bignum(1)).unwrap(); - - let coll_add_res = tx_builder - .set_total_collateral_and_return(&total_collateral_value, &collateral_return_address); - - assert!(coll_add_res.is_err()); - assert!(tx_builder.total_collateral.is_none()); - assert!(tx_builder.collateral_return.is_none()); - } - - #[test] - fn test_auto_calc_collateral_return_fails_on_no_collateral() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); - - let res = tx_builder - .set_total_collateral_and_return(&to_bignum(345_678.clone()), &fake_base_address(1)); - - assert!(res.is_err()); - assert!(tx_builder.total_collateral.is_none()); - assert!(tx_builder.collateral_return.is_none()); - } - - #[test] - fn test_costmodel_retaining_for_v1() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); - tx_builder.set_collateral(&create_collateral()); - - let (script1, _) = plutus_script_and_hash(0); - let datum = PlutusData::new_integer(&BigInt::from_str("42").unwrap()); - let redeemer = Redeemer::new( - &RedeemerTag::new_spend(), - &to_bignum(0), - &datum, - &ExUnits::new(&to_bignum(1700), &to_bignum(368100)), - ); - tx_builder.add_plutus_script_input( - &PlutusWitness::new(&script1, &datum, &redeemer), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - - // Setting script data hash removes the error - tx_builder - .calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()) - .unwrap(); - - // Using SAFE `.build_tx` - let res2 = tx_builder.build_tx(); - assert!(res2.is_ok()); - - let v1 = Language::new_plutus_v1(); - let v1_costmodel = TxBuilderConstants::plutus_vasil_cost_models() - .get(&v1) - .unwrap(); - let mut retained_cost_models = Costmdls::new(); - retained_cost_models.insert(&v1, &v1_costmodel); - - let data_hash = hash_script_data( - &Redeemers::from(vec![redeemer.clone()]), - &retained_cost_models, - Some(PlutusList::from(vec![datum])), - ); - assert_eq!(tx_builder.script_data_hash.unwrap(), data_hash); - } - - #[test] - fn test_costmodel_retaining_fails_on_missing_costmodel() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); - tx_builder.set_collateral(&create_collateral()); - - let (script1, _) = plutus_script_and_hash(0); - let datum = PlutusData::new_integer(&BigInt::from_str("42").unwrap()); - let redeemer = Redeemer::new( - &RedeemerTag::new_spend(), - &to_bignum(0), - &datum, - &ExUnits::new(&to_bignum(1700), &to_bignum(368100)), - ); - tx_builder.add_plutus_script_input( - &PlutusWitness::new(&script1, &datum, &redeemer), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - - let v2 = Language::new_plutus_v2(); - let v2_costmodel = TxBuilderConstants::plutus_vasil_cost_models() - .get(&v2) - .unwrap(); - let mut retained_cost_models = Costmdls::new(); - retained_cost_models.insert(&v2, &v2_costmodel); - - // Setting script data hash removes the error - let calc_result = tx_builder.calc_script_data_hash(&retained_cost_models); - assert!(calc_result.is_err()); - } - - #[test] - fn coin_selection_random_improve_multi_asset() { - let utoxs = TransactionUnspentOutputs::from_json("[ { \"input\": { - \"transaction_id\": \"96631bf40bc2ae1e10b3c9157a4c711562c664b9744ed1f580b725e0589efcd0\", - \"index\": 1 -}, -\"output\": { - \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", - \"amount\": { - \"coin\": \"661308571\", - \"multiasset\": null - }, - \"plutus_data\": null, - \"script_ref\": null -}}, -{ \"input\": { - \"transaction_id\": \"89da149fa162eca7212493f2bcc8415ed070832e053ac0ec335d3501f901ad77\", - \"index\": 1 -}, -\"output\": { - \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", - \"amount\": { - \"coin\": \"555975153\", - \"multiasset\": null - }, - \"plutus_data\": null, - \"script_ref\": null -}}, -{ \"input\": { - \"transaction_id\": \"0124993c20ea0fe626d96a644773225202fb442238c38206242d26a1131e0a6e\", - \"index\": 1 -}, -\"output\": { - \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", - \"amount\": { - \"coin\": \"1899495\", - \"multiasset\": { - \"07e8df329b724e4be48ee32738125c06000de5448aaf93ed46d59e28\": { - \"44696e6f436f696e\": \"750\" - } - } - }, - \"plutus_data\": null, - \"script_ref\": null -}}, -{ \"input\": { - \"transaction_id\": \"c15c423d624b3af3f032c079a1b390c472b8ba889b48dd581d0ea28f96a36875\", - \"index\": 0 -}, -\"output\": { - \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", - \"amount\": { - \"coin\": \"1804315\", - \"multiasset\": { - \"07e8df329b724e4be48ee32738125c06000de5448aaf93ed46d59e28\": { - \"44696e6f436f696e\": \"2000\" - } - } - }, - \"plutus_data\": null, - \"script_ref\": null -}}, -{ \"input\": { - \"transaction_id\": \"5894bf9c9125859d29770bf43e4018f4f34a69edee49a7c9488c6707ab523c9b\", - \"index\": 1 -}, -\"output\": { - \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", - \"amount\": { - \"coin\": \"440573428\", - \"multiasset\": null - }, - \"plutus_data\": null, - \"script_ref\": null -}}, -{ \"input\": { - \"transaction_id\": \"168404afd4e9927d7775c8f40c0f749fc7634832d6931c5d51a507724cf44420\", - \"index\": 0 -}, -\"output\": { - \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", - \"amount\": { - \"coin\": \"1804315\", - \"multiasset\": { - \"07e8df329b724e4be48ee32738125c06000de5448aaf93ed46d59e28\": { - \"44696e6f436f696e\": \"1000\" - } - } - }, - \"plutus_data\": null, - \"script_ref\": null -}}, -{ \"input\": { - \"transaction_id\": \"3e6138498b721ee609a4c289768b2accad39cd4f00448540a95ba3362578a2f7\", - \"index\": 4 -}, -\"output\": { - \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", - \"amount\": { - \"coin\": \"1508500\", - \"multiasset\": { - \"07e8df329b724e4be48ee32738125c06000de5448aaf93ed46d59e28\": { - \"44696e6f436f696e\": \"750\" - } - } - }, - \"plutus_data\": null, - \"script_ref\": null -}}, -{ \"input\": { - \"transaction_id\": \"3e6138498b721ee609a4c289768b2accad39cd4f00448540a95ba3362578a2f7\", - \"index\": 5 -}, -\"output\": { - \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", - \"amount\": { - \"coin\": \"664935092\", - \"multiasset\": null - }, - \"plutus_data\": null, - \"script_ref\": null -}}, -{ \"input\": { - \"transaction_id\": \"046cf1bc21c23c59975714b520dd7ed22b63dab592cb0449e0ee6cc96eefde69\", - \"index\": 2 -}, -\"output\": { - \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", - \"amount\": { - \"coin\": \"7094915\", - \"multiasset\": null - }, - \"plutus_data\": null, - \"script_ref\": null -}}, -{ \"input\": { - \"transaction_id\": \"e16f195105db5f84621af4f7ea57c7156b8699cba94d4fdb72a6fb09e31db7a8\", - \"index\": 1 -}, -\"output\": { - \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", - \"amount\": { - \"coin\": \"78400000\", - \"multiasset\": null - }, - \"plutus_data\": null, - \"script_ref\": null -}}, -{ \"input\": { - \"transaction_id\": \"e16f195105db5f84621af4f7ea57c7156b8699cba94d4fdb72a6fb09e31db7a8\", - \"index\": 2 -}, -\"output\": { - \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", - \"amount\": { - \"coin\": \"2000000\", - \"multiasset\": null - }, - \"plutus_data\": null, - \"script_ref\": null -}}, -{ \"input\": { - \"transaction_id\": \"006697ef0c9285b7001ebe5a9e356fb50441e0af803773a99b7cbb0e9b728570\", - \"index\": 1 -}, -\"output\": { - \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", - \"amount\": { - \"coin\": \"15054830\", - \"multiasset\": { - \"07e8df329b724e4be48ee32738125c06000de5448aaf93ed46d59e28\": { - \"44696e6f436f696e\": \"56250\" - }, - \"3320679b145d683b9123f0626360699fcd7408b4d3ec3bd9cc79398c\": { - \"44696e6f436f696e\": \"287000\" - }, - \"57fca08abbaddee36da742a839f7d83a7e1d2419f1507fcbf3916522\": { - \"4d494e54\": \"91051638\", - \"534245525259\": \"27198732\" - }, - \"e61bfc106338ed4aeba93036324fbea8150fd9750fcffca1cd9f1a19\": { - \"44696e6f536176696f723030303639\": \"1\", - \"44696e6f536176696f723030303936\": \"1\", - \"44696e6f536176696f723030313737\": \"1\", - \"44696e6f536176696f723030333033\": \"1\", - \"44696e6f536176696f723030333531\": \"1\", - \"44696e6f536176696f723030333931\": \"1\", - \"44696e6f536176696f723030343336\": \"1\", - \"44696e6f536176696f723030343434\": \"1\", - \"44696e6f536176696f723030353232\": \"1\", - \"44696e6f536176696f723030353337\": \"1\", - \"44696e6f536176696f723030363334\": \"1\", - \"44696e6f536176696f723030373332\": \"1\", - \"44696e6f536176696f723030373430\": \"1\", - \"44696e6f536176696f723030373435\": \"1\", - \"44696e6f536176696f723031303139\": \"1\", - \"44696e6f536176696f723031303631\": \"1\", - \"44696e6f536176696f723031333432\": \"1\", - \"44696e6f536176696f723031333832\": \"1\", - \"44696e6f536176696f723031353333\": \"1\", - \"44696e6f536176696f723031353732\": \"1\", - \"44696e6f536176696f723031363337\": \"1\", - \"44696e6f536176696f723031363430\": \"1\", - \"44696e6f536176696f723031373631\": \"1\", - \"44696e6f536176696f723031393436\": \"1\", - \"44696e6f536176696f723032313237\": \"1\", - \"44696e6f536176696f723032323232\": \"1\", - \"44696e6f536176696f723032333230\": \"1\", - \"44696e6f536176696f723032333239\": \"1\", - \"44696e6f536176696f723032333534\": \"1\", - \"44696e6f536176696f723032333631\": \"1\", - \"44696e6f536176696f723032333935\": \"1\", - \"44696e6f536176696f723032333938\": \"1\", - \"44696e6f536176696f723032343037\": \"1\", - \"44696e6f536176696f723032343434\": \"1\", - \"44696e6f536176696f723032353039\": \"1\", - \"44696e6f536176696f723032363334\": \"1\", - \"44696e6f536176696f723032363430\": \"1\", - \"44696e6f536176696f723032373537\": \"1\", - \"44696e6f536176696f723032373832\": \"1\", - \"44696e6f536176696f723032383933\": \"1\", - \"44696e6f536176696f723033323430\": \"1\", - \"44696e6f536176696f723033343937\": \"1\", - \"44696e6f536176696f723033353437\": \"1\", - \"44696e6f536176696f723033353738\": \"1\", - \"44696e6f536176696f723033363638\": \"1\", - \"44696e6f536176696f723033363836\": \"1\", - \"44696e6f536176696f723033363930\": \"1\", - \"44696e6f536176696f723033383638\": \"1\", - \"44696e6f536176696f723033383731\": \"1\", - \"44696e6f536176696f723033383931\": \"1\", - \"44696e6f536176696f723034313936\": \"1\", - \"44696e6f536176696f723034323538\": \"1\", - \"44696e6f536176696f723034323733\": \"1\", - \"44696e6f536176696f723034363235\": \"1\", - \"44696e6f536176696f723034373132\": \"1\", - \"44696e6f536176696f723034373932\": \"1\", - \"44696e6f536176696f723034383831\": \"1\", - \"44696e6f536176696f723034393936\": \"1\", - \"44696e6f536176696f723035303432\": \"1\", - \"44696e6f536176696f723035313539\": \"1\", - \"44696e6f536176696f723035333138\": \"1\", - \"44696e6f536176696f723035333532\": \"1\", - \"44696e6f536176696f723035343433\": \"1\", - \"44696e6f536176696f723035343639\": \"1\", - \"44696e6f536176696f723035373434\": \"1\", - \"44696e6f536176696f723035373638\": \"1\", - \"44696e6f536176696f723035373830\": \"1\", - \"44696e6f536176696f723035383435\": \"1\", - \"44696e6f536176696f723035383538\": \"1\", - \"44696e6f536176696f723035393632\": \"1\", - \"44696e6f536176696f723036303032\": \"1\", - \"44696e6f536176696f723036303337\": \"1\", - \"44696e6f536176696f723036303738\": \"1\", - \"44696e6f536176696f723036323033\": \"1\", - \"44696e6f536176696f723036323036\": \"1\", - \"44696e6f536176696f723036323236\": \"1\", - \"44696e6f536176696f723036333130\": \"1\", - \"44696e6f536176696f723036333935\": \"1\", - \"44696e6f536176696f723036343932\": \"1\", - \"44696e6f536176696f723036353532\": \"1\", - \"44696e6f536176696f723036363735\": \"1\", - \"44696e6f536176696f723036363839\": \"1\", - \"44696e6f536176696f723036373233\": \"1\", - \"44696e6f536176696f723036383731\": \"1\", - \"44696e6f536176696f723036383830\": \"1\", - \"44696e6f536176696f723036393137\": \"1\", - \"44696e6f536176696f723037303339\": \"1\", - \"44696e6f536176696f723037323638\": \"1\", - \"44696e6f536176696f723037333434\": \"1\", - \"44696e6f536176696f723037343232\": \"1\", - \"44696e6f536176696f723037343731\": \"1\", - \"44696e6f536176696f723037353431\": \"1\", - \"44696e6f536176696f723037363032\": \"1\", - \"44696e6f536176696f723037363136\": \"1\", - \"44696e6f536176696f723037363430\": \"1\", - \"44696e6f536176696f723037373635\": \"1\", - \"44696e6f536176696f723037373732\": \"1\", - \"44696e6f536176696f723037393039\": \"1\", - \"44696e6f536176696f723037393234\": \"1\", - \"44696e6f536176696f723037393430\": \"1\", - \"44696e6f536176696f723037393632\": \"1\", - \"44696e6f536176696f723038303130\": \"1\", - \"44696e6f536176696f723038303338\": \"1\", - \"44696e6f536176696f723038303339\": \"1\", - \"44696e6f536176696f723038303636\": \"1\", - \"44696e6f536176696f723038313735\": \"1\", - \"44696e6f536176696f723038323032\": \"1\", - \"44696e6f536176696f723038323131\": \"1\", - \"44696e6f536176696f723038323536\": \"1\", - \"44696e6f536176696f723038333532\": \"1\", - \"44696e6f536176696f723038333536\": \"1\", - \"44696e6f536176696f723038333538\": \"1\", - \"44696e6f536176696f723038333539\": \"1\", - \"44696e6f536176696f723038333830\": \"1\", - \"44696e6f536176696f723038343932\": \"1\", - \"44696e6f536176696f723038353231\": \"1\", - \"44696e6f536176696f723038353736\": \"1\", - \"44696e6f536176696f723038353836\": \"1\", - \"44696e6f536176696f723038363130\": \"1\", - \"44696e6f536176696f723039303231\": \"1\", - \"44696e6f536176696f723039303735\": \"1\", - \"44696e6f536176696f723039313039\": \"1\", - \"44696e6f536176696f723039313231\": \"1\", - \"44696e6f536176696f723039323238\": \"1\", - \"44696e6f536176696f723039333138\": \"1\", - \"44696e6f536176696f723039333731\": \"1\", - \"44696e6f536176696f723039343035\": \"1\", - \"44696e6f536176696f723039343136\": \"1\", - \"44696e6f536176696f723039353039\": \"1\", - \"44696e6f536176696f723039353635\": \"1\", - \"44696e6f536176696f723039363331\": \"1\", - \"44696e6f536176696f723039363932\": \"1\", - \"44696e6f536176696f723039383839\": \"1\", - \"44696e6f536176696f723039393038\": \"1\", - \"44696e6f536176696f723039393935\": \"1\" - }, - \"ee8e37676f6ebb8e031dff493f88ff711d24aa68666a09d61f1d3fb3\": { - \"43727970746f44696e6f3030303135\": \"1\", - \"43727970746f44696e6f3030313335\": \"1\", - \"43727970746f44696e6f3030323634\": \"1\", - \"43727970746f44696e6f3030333932\": \"1\", - \"43727970746f44696e6f3030353834\": \"1\", - \"43727970746f44696e6f3030373136\": \"1\", - \"43727970746f44696e6f3030373837\": \"1\", - \"43727970746f44696e6f3030383438\": \"1\", - \"43727970746f44696e6f3031303537\": \"1\", - \"43727970746f44696e6f3031313134\": \"1\", - \"43727970746f44696e6f3031323237\": \"1\", - \"43727970746f44696e6f3031323330\": \"1\", - \"43727970746f44696e6f3031343031\": \"1\", - \"43727970746f44696e6f3031353138\": \"1\", - \"43727970746f44696e6f3031353734\": \"1\", - \"43727970746f44696e6f3031373635\": \"1\", - \"43727970746f44696e6f3031383037\": \"1\", - \"43727970746f44696e6f3031383231\": \"1\", - \"43727970746f44696e6f3032303830\": \"1\", - \"43727970746f44696e6f3032313133\": \"1\", - \"43727970746f44696e6f3032323835\": \"1\", - \"43727970746f44696e6f3032343238\": \"1\", - \"43727970746f44696e6f3032363738\": \"1\", - \"43727970746f44696e6f3032393034\": \"1\", - \"43727970746f44696e6f3032393333\": \"1\", - \"43727970746f44696e6f3032393537\": \"1\", - \"43727970746f44696e6f3032393632\": \"1\", - \"43727970746f44696e6f3032393735\": \"1\", - \"43727970746f44696e6f3033303434\": \"1\", - \"43727970746f44696e6f3033333338\": \"1\", - \"43727970746f44696e6f3033393535\": \"1\", - \"43727970746f44696e6f3034303630\": \"1\", - \"43727970746f44696e6f3034313939\": \"1\", - \"43727970746f44696e6f3034373439\": \"1\", - \"43727970746f44696e6f3034383134\": \"1\", - \"43727970746f44696e6f3034393530\": \"1\", - \"43727970746f44696e6f3035303630\": \"1\", - \"43727970746f44696e6f3035333230\": \"1\", - \"43727970746f44696e6f2d312d3030303030\": \"1\", - \"43727970746f44696e6f2d312d3030303032\": \"1\" - } - } - }, - \"plutus_data\": null, - \"script_ref\": null -}}, -{ \"input\": { - \"transaction_id\": \"006697ef0c9285b7001ebe5a9e356fb50441e0af803773a99b7cbb0e9b728570\", - \"index\": 2 -}, -\"output\": { - \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", - \"amount\": { - \"coin\": \"2279450\", - \"multiasset\": null - }, - \"plutus_data\": null, - \"script_ref\": null -}}, -{ \"input\": { - \"transaction_id\": \"017962634cf8fa87835256a80b8374c6f75687c34d8694480cb071648551c3a7\", - \"index\": 0 -}, -\"output\": { - \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", - \"amount\": { - \"coin\": \"2000000\", - \"multiasset\": { - \"ee8e37676f6ebb8e031dff493f88ff711d24aa68666a09d61f1d3fb3\": { - \"43727970746f44696e6f3031353039\": \"1\" - } - } - }, - \"plutus_data\": null, - \"script_ref\": null -}}, -{ \"input\": { - \"transaction_id\": \"017962634cf8fa87835256a80b8374c6f75687c34d8694480cb071648551c3a7\", - \"index\": 1 -}, -\"output\": { - \"address\": \"addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5\", - \"amount\": { - \"coin\": \"725669617\", - \"multiasset\": null - }, - \"plutus_data\": null, - \"script_ref\": null -}}]") - .unwrap(); - let output = TransactionOutput::from_json("{ - \"address\": \"addr_test1wpv93hm9sqx0ar7pgxwl9jn3xt6lwmxxy27zd932slzvghqg8fe0n\", - \"amount\": { - \"coin\": \"20000000\", - \"multiasset\": { - \"07e8df329b724e4be48ee32738125c06000de5448aaf93ed46d59e28\": { - \"44696e6f436f696e\": \"1000\" - }, - \"ee8e37676f6ebb8e031dff493f88ff711d24aa68666a09d61f1d3fb3\": { - \"43727970746f44696e6f2d312d3030303030\": \"1\", - \"43727970746f44696e6f2d312d3030303032\": \"1\" - } - } - }, - \"plutus_data\": { - \"DataHash\": \"979f68de9e070e75779f80ce5e6cc74f8d77661d65f2895c01d0a6f66eceb791\" - }, - \"script_ref\": null -}").unwrap(); - let mut builder = create_reallistic_tx_builder(); - builder.add_output(&output).unwrap(); - let res = builder.add_inputs_from(&utoxs, CoinSelectionStrategyCIP2::RandomImproveMultiAsset); - assert!(res.is_ok()); - } - - #[test] - fn plutus_mint_test() { - let mut tx_builder = create_reallistic_tx_builder(); - let colateral_adress = Address::from_bech32("addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w").unwrap(); - let colateral_input = TransactionInput::from_json("\ - { - \"transaction_id\": \"69b0b867056a2d4fdc3827e23aa7069b125935e2def774941ca8cc7f9e0de774\", - \"index\": 1 - }").unwrap(); - - let tx_input = TransactionInput::from_json("\ - { - \"transaction_id\": \"f58a5bc761b1efdcf4b5684f6ad5495854a0d64b866e2f0f525d134750d3511b\", - \"index\": 1 - }").unwrap(); - let plutus_script = plutus::PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); - let redeemer = Redeemer::from_json("\ - { - \"tag\": \"Mint\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"1042996\", - \"steps\": \"446100241\" - } - }").unwrap(); - let asset_name = AssetName::from_hex("44544e4654").unwrap(); - let mut mint_builder = MintBuilder::new(); - let plutus_script_source = PlutusScriptSource::new(&plutus_script); - let mint_witnes = MintWitness::new_plutus_script(&plutus_script_source, &redeemer); - mint_builder.add_asset(&mint_witnes, &asset_name, &Int::new(&BigNum::from(100u64))); - - let output_adress = Address::from_bech32("addr_test1qpm5njmgzf4t7225v6j34wl30xfrufzt3jtqtdzf3en9ahpmnhtmynpasyc8fq75zv0uaj86vzsr7g3g8q5ypgu5fwtqr9zsgj").unwrap(); - let mut output_assets = MultiAsset::new(); - let mut asset = Assets::new(); - asset.insert(&asset_name, &BigNum::from(100u64)); - output_assets.insert(&plutus_script.hash(), &asset); - let output_value = Value::new_with_assets(&Coin::from(50000u64), &output_assets); - let output = TransactionOutput::new(&output_adress, &output_value); - - let mut col_builder = TxInputsBuilder::new(); - col_builder.add_input(&colateral_adress, &colateral_input, &Value::new(&Coin::from(1000000000u64))); - tx_builder.set_collateral(&col_builder); - tx_builder.add_output(&output); - tx_builder.add_input(&output_adress, &tx_input, &Value::new(&BigNum::from(100000000000u64))); - tx_builder.set_mint_builder(&mint_builder); - - tx_builder.calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()).unwrap(); - - let change_res = tx_builder.add_change_if_needed(&output_adress); - assert!(change_res.is_ok()); - - let build_res = tx_builder.build_tx(); - assert!(build_res.is_ok()); - - assert!(mint_builder.get_plutus_witnesses().len() == 1); - - let tx = build_res.unwrap(); - assert!(tx.body.mint.is_some()); - assert_eq!(tx.body.mint.unwrap().0.iter().next().unwrap().0, plutus_script.hash()); - } - - #[test] - fn plutus_mint_with_script_ref_test() { - let mut tx_builder = create_reallistic_tx_builder(); - let colateral_adress = Address::from_bech32("addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w").unwrap(); - let colateral_input = TransactionInput::from_json("\ - { - \"transaction_id\": \"69b0b867056a2d4fdc3827e23aa7069b125935e2def774941ca8cc7f9e0de774\", - \"index\": 1 - }").unwrap(); - - let tx_input = TransactionInput::from_json("\ - { - \"transaction_id\": \"f58a5bc761b1efdcf4b5684f6ad5495854a0d64b866e2f0f525d134750d3511b\", - \"index\": 1 - }").unwrap(); - let tx_input_ref = TransactionInput::from_json("\ - { - \"transaction_id\": \"f58a5bc7adaadadcf4b5684f6ad5495854a0d64b866e2f0f525d134750d3511b\", - \"index\": 2 - }").unwrap(); - let plutus_script = plutus::PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); - let plutus_script2 = plutus::PlutusScript::from_hex("5907adaada00332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); - - let redeemer = Redeemer::from_json("\ - { - \"tag\": \"Mint\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"1042996\", - \"steps\": \"446100241\" - } - }").unwrap(); - - let redeemer2 = Redeemer::from_json("\ - { - \"tag\": \"Mint\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"2929292\", - \"steps\": \"446188888\" - } - }").unwrap(); - - let asset_name = AssetName::from_hex("44544e4654").unwrap(); - let asset_name2 = AssetName::from_hex("44544e4ada").unwrap(); - let mut mint_builder = MintBuilder::new(); - let plutus_script_source = PlutusScriptSource::new(&plutus_script); - let plutus_script_source_ref = PlutusScriptSource::new_ref_input_with_lang_ver(&plutus_script2.hash(), &tx_input_ref, &Language::new_plutus_v2()); - let mint_witnes = MintWitness::new_plutus_script(&plutus_script_source, &redeemer); - let mint_witnes_ref = MintWitness::new_plutus_script(&plutus_script_source_ref, &redeemer2); - mint_builder.add_asset(&mint_witnes, &asset_name, &Int::new(&BigNum::from(100u64))); - mint_builder.add_asset(&mint_witnes_ref, &asset_name, &Int::new(&BigNum::from(100u64))); - - let output_adress = Address::from_bech32("addr_test1qpm5njmgzf4t7225v6j34wl30xfrufzt3jtqtdzf3en9ahpmnhtmynpasyc8fq75zv0uaj86vzsr7g3g8q5ypgu5fwtqr9zsgj").unwrap(); - let mut output_assets = MultiAsset::new(); - let mut asset = Assets::new(); - asset.insert(&asset_name, &BigNum::from(100u64)); - output_assets.insert(&plutus_script.hash(), &asset); - let output_value = Value::new_with_assets(&Coin::from(50000u64), &output_assets); - let output = TransactionOutput::new(&output_adress, &output_value); - - let mut col_builder = TxInputsBuilder::new(); - col_builder.add_input(&colateral_adress, &colateral_input, &Value::new(&Coin::from(1000000000u64))); - tx_builder.set_collateral(&col_builder); - tx_builder.add_output(&output); - tx_builder.add_input(&output_adress, &tx_input, &Value::new(&BigNum::from(100000000000u64))); - tx_builder.set_mint_builder(&mint_builder); - - tx_builder.calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()).unwrap(); - - let change_res = tx_builder.add_change_if_needed(&output_adress); - assert!(change_res.is_ok()); - - let build_res = tx_builder.build_tx(); - assert!(build_res.is_ok()); - - let tx = build_res.unwrap(); - assert_eq!(tx.witness_set.plutus_scripts.unwrap().len(), 1usize); - assert_eq!(tx.witness_set.redeemers.unwrap().len(), 2usize); - assert!(tx.witness_set.plutus_data.is_none()); - assert_eq!(tx.body.reference_inputs.unwrap().len(), 1usize); - assert!(tx.body.mint.is_some()); - assert_eq!(tx.body.mint.unwrap().len(), 2usize); - } - - #[test] - fn plutus_mint_defferent_redeemers_test() { - let mut tx_builder = create_reallistic_tx_builder(); - let colateral_adress = Address::from_bech32("addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w").unwrap(); - let colateral_input = TransactionInput::from_json("\ - { - \"transaction_id\": \"69b0b867056a2d4fdc3827e23aa7069b125935e2def774941ca8cc7f9e0de774\", - \"index\": 1 - }").unwrap(); - - let tx_input = TransactionInput::from_json("\ - { - \"transaction_id\": \"f58a5bc761b1efdcf4b5684f6ad5495854a0d64b866e2f0f525d134750d3511b\", - \"index\": 1 - }").unwrap(); - let tx_input_ref = TransactionInput::from_json("\ - { - \"transaction_id\": \"f58a5bc7adaadadcf4b5684f6ad5495854a0d64b866e2f0f525d134750d3511b\", - \"index\": 2 - }").unwrap(); - let plutus_script = plutus::PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); - - let redeemer = Redeemer::from_json("\ - { - \"tag\": \"Mint\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"1042996\", - \"steps\": \"446100241\" - } - }").unwrap(); - - let redeemer2 = Redeemer::from_json("\ - { - \"tag\": \"Mint\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"2929292\", - \"steps\": \"446188888\" - } - }").unwrap(); - - let asset_name = AssetName::from_hex("44544e4654").unwrap(); - let asset_name2 = AssetName::from_hex("44544e4ada").unwrap(); - let mut mint_builder = MintBuilder::new(); - let plutus_script_source = PlutusScriptSource::new(&plutus_script); - let mint_witnes = MintWitness::new_plutus_script(&plutus_script_source, &redeemer); - let mint_witnes2 = MintWitness::new_plutus_script(&plutus_script_source, &redeemer2); - mint_builder.add_asset(&mint_witnes, &asset_name, &Int::new(&BigNum::from(100u64))); - mint_builder.add_asset(&mint_witnes2, &asset_name, &Int::new(&BigNum::from(100u64))); - - let output_adress = Address::from_bech32("addr_test1qpm5njmgzf4t7225v6j34wl30xfrufzt3jtqtdzf3en9ahpmnhtmynpasyc8fq75zv0uaj86vzsr7g3g8q5ypgu5fwtqr9zsgj").unwrap(); - let mut output_assets = MultiAsset::new(); - let mut asset = Assets::new(); - asset.insert(&asset_name, &BigNum::from(100u64)); - output_assets.insert(&plutus_script.hash(), &asset); - let output_value = Value::new_with_assets(&Coin::from(50000u64), &output_assets); - let output = TransactionOutput::new(&output_adress, &output_value); - - let mut col_builder = TxInputsBuilder::new(); - col_builder.add_input(&colateral_adress, &colateral_input, &Value::new(&Coin::from(1000000000u64))); - tx_builder.set_collateral(&col_builder); - tx_builder.add_output(&output); - tx_builder.add_input(&output_adress, &tx_input, &Value::new(&BigNum::from(100000000000u64))); - tx_builder.set_mint_builder(&mint_builder); - - tx_builder.calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()).unwrap(); - - let change_res = tx_builder.add_change_if_needed(&output_adress); - assert!(change_res.is_ok()); - - let build_res = tx_builder.build_tx(); - assert!(build_res.is_ok()); - - let tx = build_res.unwrap(); - assert_eq!(tx.witness_set.plutus_scripts.unwrap().len(), 1usize); - assert_eq!(tx.witness_set.redeemers.unwrap().len(), 2usize); - assert!(tx.witness_set.plutus_data.is_none()); - assert!(tx.body.reference_inputs.is_none()); - assert!(tx.body.mint.is_some()); - assert_eq!(tx.body.mint.unwrap().len(), 2usize); - } - - #[test] - fn multiple_plutus_inputs_test() { - let mut tx_builder = create_reallistic_tx_builder(); - let plutus_script = plutus::PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); - let redeemer1 = Redeemer::from_json("\ - { - \"tag\": \"Mint\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"1042996\", - \"steps\": \"446100241\" - } - }").unwrap(); - - let redeemer2 = Redeemer::from_json("\ - { - \"tag\": \"Mint\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"1042996\", - \"steps\": \"446100241\" - } - }").unwrap(); - - let mut in_builder = TxInputsBuilder::new(); - let input_1 = TransactionInput::new( - &TransactionHash::from_bytes( - hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") - .unwrap(), - ) - .unwrap(), - 1, - ); - let input_2 = TransactionInput::new( - &TransactionHash::from_bytes( - hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") - .unwrap(), - ) - .unwrap(), - 2, - ); - - let colateral_adress = Address::from_bech32("addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w").unwrap(); - let colateral_input = TransactionInput::new( - &TransactionHash::from_bytes( - hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") - .unwrap(), - ) - .unwrap(), - 3 - ); - - let output_adress = Address::from_bech32("addr_test1qpm5njmgzf4t7225v6j34wl30xfrufzt3jtqtdzf3en9ahpmnhtmynpasyc8fq75zv0uaj86vzsr7g3g8q5ypgu5fwtqr9zsgj").unwrap(); - let output_value = Value::new(&Coin::from(500000u64)); - let output = TransactionOutput::new(&output_adress, &output_value); - - tx_builder.add_output(&output); - let mut col_builder = TxInputsBuilder::new(); - col_builder.add_input(&colateral_adress, &colateral_input, &Value::new(&Coin::from(1000000000u64))); - tx_builder.set_collateral(&col_builder); - - let datum = PlutusData::new_bytes(fake_bytes_32(11)); - let plutus_wit1 = PlutusWitness::new( - &plutus_script, - &datum, - &redeemer1 - ); - - let plutus_wit2 = PlutusWitness::new( - &plutus_script, - &datum, - &redeemer2 - ); - - let value = Value::new(&Coin::from(100000000u64)); - - in_builder.add_plutus_script_input(&plutus_wit1, &input_1, &value); - in_builder.add_plutus_script_input(&plutus_wit2, &input_2, &value); - - tx_builder.set_inputs(&in_builder); - tx_builder.calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()); - tx_builder.add_change_if_needed(&output_adress); - let build_res = tx_builder.build_tx(); - assert!(&build_res.is_ok()); - let tx = build_res.unwrap(); - assert_eq!(tx.witness_set.plutus_scripts.unwrap().len(), 1usize); - assert_eq!(tx.witness_set.redeemers.unwrap().len(), 2usize); - } - - #[test] - fn multiple_plutus_inputs_with_missed_wit_test() { - let mut tx_builder = create_reallistic_tx_builder(); - let plutus_script = plutus::PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); - let redeemer1 = Redeemer::from_json("\ - { - \"tag\": \"Mint\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"1042996\", - \"steps\": \"446100241\" - } - }").unwrap(); - - let redeemer2 = Redeemer::from_json("\ - { - \"tag\": \"Mint\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"1042996\", - \"steps\": \"446100241\" - } - }").unwrap(); - - let mut in_builder = TxInputsBuilder::new(); - let input_1 = TransactionInput::new( - &TransactionHash::from_bytes( - hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") - .unwrap(), - ) - .unwrap(), - 1, - ); - let input_2 = TransactionInput::new( - &TransactionHash::from_bytes( - hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") - .unwrap(), - ) - .unwrap(), - 2, - ); - - let colateral_adress = Address::from_bech32("addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w").unwrap(); - let colateral_input = TransactionInput::new( - &TransactionHash::from_bytes( - hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") - .unwrap(), - ) - .unwrap(), - 3 - ); - - let output_adress = Address::from_bech32("addr_test1qpm5njmgzf4t7225v6j34wl30xfrufzt3jtqtdzf3en9ahpmnhtmynpasyc8fq75zv0uaj86vzsr7g3g8q5ypgu5fwtqr9zsgj").unwrap(); - let output_value = Value::new(&Coin::from(5000000u64)); - let output = TransactionOutput::new(&output_adress, &output_value); - - tx_builder.add_output(&output).unwrap(); - let mut col_builder = TxInputsBuilder::new(); - col_builder.add_input(&colateral_adress, &colateral_input, &Value::new(&Coin::from(1000000000u64))); - tx_builder.set_collateral(&col_builder); - - let datum = PlutusData::new_bytes(fake_bytes_32(11)); - let plutus_wit1 = PlutusWitness::new( - &plutus_script, - &datum, - &redeemer1 - ); - - let plutus_wit2 = PlutusWitness::new( - &plutus_script, - &datum, - &redeemer2 - ); - - let value = Value::new(&Coin::from(100000000u64)); - - in_builder.add_plutus_script_input(&plutus_wit1, &input_1, &value); - let script_addr = create_base_address_from_script_hash(&plutus_script.hash()); - in_builder.add_input(&script_addr, &input_2, &value); - - assert_eq!(in_builder.count_missing_input_scripts(), 1usize); - let mut inputs_with_wit = InputsWithScriptWitness::new(); - let in_with_wit = InputWithScriptWitness::new_with_plutus_witness(&input_2, &plutus_wit2); - inputs_with_wit.add(&in_with_wit); - in_builder.add_required_script_input_witnesses(&inputs_with_wit); - - tx_builder.set_inputs(&in_builder); - - - tx_builder.calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()).unwrap(); - tx_builder.add_change_if_needed(&output_adress).unwrap(); - let build_res = tx_builder.build_tx(); - assert!(&build_res.is_ok()); - let tx = build_res.unwrap(); - assert_eq!(tx.witness_set.plutus_scripts.unwrap().len(), 1usize); - assert_eq!(tx.witness_set.redeemers.unwrap().len(), 2usize); - } - - #[test] - fn build_tx_with_certs_withdrawals_plutus_script_address() { - let mut tx_builder = create_tx_builder_with_key_deposit(1_000_000); - let spend = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(0) - .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); - let stake = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - let reward = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(3) - .derive(1) - .to_public(); - - let redeemer_cert1 = Redeemer::from_json("\ - { - \"tag\": \"Spend\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"1\", - \"steps\": \"1\" - } - }").unwrap(); - - let redeemer_cert2 = Redeemer::from_json("\ - { - \"tag\": \"Spend\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"2\", - \"steps\": \"2\" - } - }").unwrap(); - - let redeemer_cert3 = Redeemer::from_json("\ - { - \"tag\": \"Spend\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"2\", - \"steps\": \"2\" - } - }").unwrap(); - - let redeemer_withdraw1 = Redeemer::from_json("\ - { - \"tag\": \"Spend\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"4\", - \"steps\": \"4\" - } - }").unwrap(); - - let redeemer_withdraw2 = Redeemer::from_json("\ - { - \"tag\": \"Spend\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"5\", - \"steps\": \"5\" - } - }").unwrap(); - - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - tx_builder.add_key_input( - &spend.to_raw_key().hash(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(5_000_000)), - ); - tx_builder.set_ttl(1000); - let (cert_script1, cert_script_hash1) = plutus_script_and_hash(1); - let cert_script_cred1 = Credential::from_scripthash(&cert_script_hash1); - - let (cert_script2, cert_script_hash2) = plutus_script_and_hash(2); - let cert_script_cred2 = Credential::from_scripthash(&cert_script_hash2); - - let cert_script_hash3 = fake_script_hash(3); - let cert_script_cred3 = Credential::from_scripthash(&cert_script_hash3); - - let (withdraw_script1, withdraw_script_hash1) = plutus_script_and_hash(3); - let withdraw_script_cred1 = Credential::from_scripthash(&withdraw_script_hash1); - - let withdraw_script_hash2 = fake_script_hash(3); - let withdraw_script_cred2 = Credential::from_scripthash(&withdraw_script_hash2); - - let cert_witness_1 = PlutusWitness::new_without_datum( - &cert_script1, - &redeemer_cert1 - ); - let cert_witness_2= PlutusWitness::new_without_datum( - &cert_script2, - &redeemer_cert2 - ); - - let ref_cert_script_input_3 = fake_tx_input(1); - let ref_cert_withdrawal_input_2 = fake_tx_input(2); - let plutus_cert_source = PlutusScriptSource::new_ref_input_with_lang_ver( - &cert_script_hash3, - &ref_cert_script_input_3, - &Language::new_plutus_v2() - ); - let plutus_withdrawal_source = PlutusScriptSource::new_ref_input_with_lang_ver( - &withdraw_script_hash2, - &ref_cert_withdrawal_input_2, - &Language::new_plutus_v2() - ); - - let cert_witness_3 = PlutusWitness::new_with_ref_without_datum( - &plutus_cert_source, - &redeemer_cert3 - ); - let withdraw_witness1 = PlutusWitness::new_without_datum( - &withdraw_script1, - &redeemer_withdraw1 - ); - let withdraw_witness2 = PlutusWitness::new_with_ref_without_datum( - &plutus_withdrawal_source, - &redeemer_withdraw2 - ); - - - let mut certs = CertificatesBuilder::new(); - certs.add(&Certificate::new_stake_registration( - &StakeRegistration::new(&stake_cred), - )).unwrap(); - certs.add_with_plutus_witness( - &Certificate::new_stake_delegation(&StakeDelegation::new( - &cert_script_cred1, - &stake.to_raw_key().hash(), // in reality, this should be the pool owner's key, not ours - )), - &cert_witness_1 - ).unwrap(); - certs.add_with_plutus_witness( - &Certificate::new_stake_delegation(&StakeDelegation::new( - &cert_script_cred2, - &stake.to_raw_key().hash(), // in reality, this should be the pool owner's key, not ours - )), - &cert_witness_2 - ).unwrap(); - certs.add(&Certificate::new_stake_delegation(&StakeDelegation::new( - &stake_cred, - &stake.to_raw_key().hash(), // in reality, this should be the pool owner's key, not ours - ))).unwrap(); - certs.add_with_plutus_witness( - &Certificate::new_stake_deregistration(&StakeDeregistration::new( - &cert_script_cred3 - )), - &cert_witness_3 - ).unwrap(); - - tx_builder.set_certs_builder(&certs); - - let mut withdrawals = WithdrawalsBuilder::new(); - let reward_cred = Credential::from_keyhash(&reward.to_raw_key().hash()); - withdrawals.add( - &RewardAddress::new(NetworkInfo::testnet().network_id(), &reward_cred), - &Coin::from(1u32), - ).unwrap(); - withdrawals.add_with_plutus_witness( - &RewardAddress::new(NetworkInfo::testnet().network_id(), &withdraw_script_cred1), - &Coin::from(2u32), - &withdraw_witness1 - ).unwrap(); - withdrawals.add_with_plutus_witness( - &RewardAddress::new(NetworkInfo::testnet().network_id(), &withdraw_script_cred2), - &Coin::from(3u32), - &withdraw_witness2 - ).unwrap(); - tx_builder.set_withdrawals_builder(&withdrawals); - - let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); - let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &change_cred, - &stake_cred, - ) - .to_address(); - let cost_models = TxBuilderConstants::plutus_default_cost_models(); - let collateral_input = fake_tx_input(1); - let collateral_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &Credential::from_keyhash(&fake_key_hash(1)), - &Credential::from_keyhash(&fake_key_hash(2)), - ).to_address(); - let mut collateral_builder = TxInputsBuilder::new(); - collateral_builder.add_input(&collateral_addr, &collateral_input, &Value::new(&Coin::from(123u32))); - tx_builder.set_collateral(&collateral_builder); - tx_builder.calc_script_data_hash(&cost_models).unwrap(); - tx_builder.add_change_if_needed(&change_addr).unwrap(); - assert_eq!(tx_builder.outputs.len(), 1); - assert_eq!( - tx_builder - .get_explicit_input() - .unwrap() - .checked_add(&tx_builder.get_implicit_input().unwrap()) - .unwrap(), - tx_builder - .get_explicit_output() - .unwrap() - .checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())) - .unwrap() - .checked_add(&Value::new(&tx_builder.get_deposit().unwrap())) - .unwrap() - ); - let final_tx = tx_builder.build_tx().unwrap(); - let final_tx_body = final_tx.body(); - let final_tx_wits = final_tx.witness_set(); - - assert_eq!(final_tx_body.reference_inputs().unwrap().len(), 2); - assert_eq!(final_tx_body.withdrawals().unwrap().len(), 3); - assert_eq!(final_tx_body.certs().unwrap().len(), 5); - assert_eq!(final_tx_wits.plutus_scripts().unwrap().len(), 3); - assert_eq!(final_tx_wits.redeemers().unwrap().len(), 5); - - let certs = final_tx_body.certs().unwrap().0; - let withdraws = final_tx_body.withdrawals().unwrap().0 - .iter() - .map(|(k, _)| k.clone()) - .collect::>(); - let redeemers = final_tx_wits.redeemers().unwrap(); - let mut indexes = HashMap::new(); - indexes.insert(RedeemerTag::new_cert(), HashSet::new()); - indexes.insert(RedeemerTag::new_reward(), HashSet::new()); - for redeemer in &redeemers.0 { - let tag_set = indexes.get_mut(&redeemer.tag()).unwrap(); - assert_ne!(tag_set.contains(&redeemer.index()), true); - tag_set.insert(redeemer.index()); - let index: usize = redeemer.index().into(); - if redeemer.tag().kind() == RedeemerTagKind::Cert { - let cert = &certs[index]; - assert!(cert.has_required_script_witness()); - } else if redeemer.tag().kind() == RedeemerTagKind::Reward { - let withdraw = &withdraws[index]; - assert!(withdraw.payment_cred().has_script_hash()); - } - } - } - - #[test] - pub fn test_extra_datum() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); - - let datum = PlutusData::new_bytes(fake_bytes_32(1)); - tx_builder.add_extra_witness_datum(&datum); - - let mut inp = TxInputsBuilder::new(); - inp.add_input( - &fake_base_address(0), - &fake_tx_input(0), - &Value::new(&to_bignum(1000000u64)), - ); - - tx_builder.set_inputs(&inp); - tx_builder - .calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()) - .unwrap(); - - - let res = tx_builder.build_tx(); - assert!(res.is_ok()); - - let tx = res.unwrap(); - - let data_hash = hash_script_data( - &Redeemers::new(), - &Costmdls::new(), - Some(PlutusList::from(vec![datum.clone()])), - ); - - let tx_builder_script_data_hash = tx_builder.script_data_hash.clone(); - assert_eq!(tx_builder_script_data_hash.unwrap(), data_hash); - - let extra_datums = tx_builder.get_extra_witness_datums().unwrap(); - assert_eq!(&extra_datums.get(0), &datum); - assert_eq!(extra_datums.len(), 1usize); - assert_eq!(tx_builder.get_witness_set().plutus_data().unwrap().len(), 1usize); - assert_eq!(tx.witness_set().plutus_data().unwrap().len(), 1usize); - assert_eq!(tx.witness_set().plutus_data().unwrap().get(0), datum); - } -} +} \ No newline at end of file diff --git a/rust/src/tx_builder/test_batch.rs b/rust/src/tx_builder/test_batch.rs deleted file mode 100644 index 4539a4a3..00000000 --- a/rust/src/tx_builder/test_batch.rs +++ /dev/null @@ -1,775 +0,0 @@ -#[cfg(test)] -mod test { - use crate::*; - use crate::fakes::fake_policy_id; - use crate::fees::{LinearFee, min_fee}; - use crate::tx_builder::{TransactionBuilderConfig, TransactionBuilderConfigBuilder}; - use crate::tx_builder::tx_batch_builder::{create_send_all, TransactionBatchList}; - - fn root_key() -> Bip32PrivateKey { - // art forum devote street sure rather head chuckle guard poverty release quote oak craft enemy - let entropy = [ - 0x0c, 0xcb, 0x74, 0xf3, 0x6b, 0x7d, 0xa1, 0x64, 0x9a, 0x81, 0x44, 0x67, 0x55, 0x22, - 0xd4, 0xd8, 0x09, 0x7c, 0x64, 0x12, - ]; - Bip32PrivateKey::from_bip39_entropy(&entropy, &[]) - } - - fn harden(index: u32) -> u32 { - index | 0x80_00_00_00 - } - - fn generate_address(index: u32) -> Address { - let spend = root_key() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(index) - .to_public(); - let stake = root_key() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - let addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ); - addr.to_address() - } - - fn generate_assets(from_policy: usize, - from_asset: usize, - policies_count: usize, - assets_count: usize, - asset_name_size: usize, - amount_per_asset: Coin) -> Option { - let mut assets = MultiAsset::new(); - for i in from_policy..(policies_count + from_policy) { - let policy_id = fake_policy_id(i as u8); - for j in from_asset..(assets_count + from_asset) { - let asset_name = AssetName::new(vec![j as u8; asset_name_size]).unwrap(); - assets.set_asset(&policy_id, &asset_name, amount_per_asset); - } - } - - if assets.0.is_empty() { - None - } else { - Some(assets) - } - } - - fn generate_utxo(address: &Address, - index: u32, - from_policy: usize, - from_asset: usize, - policies: usize, - assets: usize, - asset_name_size: usize, - amount_per_asset: Coin, - ada: Coin) -> TransactionUnspentOutput { - let input = TransactionInput::new( - &TransactionHash::from_bytes( - hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7").unwrap()) - .unwrap(), index); - let assets = generate_assets(from_policy, from_asset, policies, assets, asset_name_size, amount_per_asset); - let value = match assets { - Some(assets) => Value::new_with_assets(&ada, &assets), - None => Value::new(&ada), - }; - let output = TransactionOutput::new(&address, &value); - TransactionUnspentOutput::new(&input, &output) - } - - fn generate_big_ada_utoxs_bacth() -> TransactionUnspentOutputs { - let mut utxos = Vec::new(); - let address = generate_address(1); - let address_2 = generate_address(2); - for i in 0..10 { - let utxo = generate_utxo( - &address, - i, - (i / 2) as usize, - (i / 2) as usize, - 5, - 5, - 20, - Coin::from(500u64), - Coin::from(5000u64)); - utxos.push(utxo); - } - - for i in 0..10000 { - let utxo = generate_utxo( - &address_2, - i + 1000, - 0, - 0, - 0, - 0, - 20, - Coin::zero(), - Coin::from(5000000u64)); - utxos.push(utxo); - } - TransactionUnspentOutputs(utxos) - } - - fn generate_big_utoxs_bacth() -> TransactionUnspentOutputs { - let mut utxos = Vec::new(); - let address = generate_address(1); - let address_2 = generate_address(2); - for i in 0..200 { - let utxo = generate_utxo( - &address, - i, - (i / 2) as usize, - (i / 2) as usize, - 5, - 5, - 20, - Coin::from(500u64), - Coin::from(5000u64)); - utxos.push(utxo); - } - - for i in 0..10 { - let utxo = generate_utxo( - &address_2, - i + 1000, - 0, - 0, - 0, - 0, - 20, - Coin::zero(), - Coin::from(50000000u64)); - utxos.push(utxo); - } - TransactionUnspentOutputs(utxos) - } - - fn get_utxos_total(utxos: &TransactionUnspentOutputs) -> Value { - let mut total_value = Value::zero(); - for utxo in utxos { - total_value = total_value.checked_add(&utxo.output.amount).unwrap(); - } - - total_value - } - - fn get_batch_total(batches: &TransactionBatchList) -> Value { - let mut total_value = Value::zero(); - for batch in batches { - for tx in batch { - for output in &tx.body.outputs { - total_value = total_value.checked_add(&output.amount).unwrap(); - } - let fee = Value::new(&tx.body.fee); - total_value = total_value.checked_add(&fee).unwrap(); - } - } - - total_value - } - - fn get_tx_fee(tx: &Transaction, cfg: &TransactionBuilderConfig) -> Coin { - min_fee(tx, &cfg.fee_algo).unwrap() - } - - fn get_ada_for_output(output: &TransactionOutput, cfg: &TransactionBuilderConfig) -> Coin { - min_ada_for_output(output, &cfg.data_cost).unwrap() - } - - fn check_balance(utxos: &TransactionUnspentOutputs, batches: &TransactionBatchList) { - let utxos_total = get_utxos_total(utxos); - let batches_total = get_batch_total(batches); - assert_eq!(utxos_total, batches_total); - } - - fn check_min_adas(batches: &TransactionBatchList, cfg: &TransactionBuilderConfig) { - for batch in batches { - for tx in batch { - for output in &tx.body.outputs { - let min_ada = get_ada_for_output(output, cfg); - assert!(output.amount.coin >= min_ada); - } - } - } - } - - fn check_fees(batches: &TransactionBatchList, cfg: &TransactionBuilderConfig) { - for batch in batches { - for tx in batch { - let fee = get_tx_fee(tx, cfg); - assert_eq!(fee, tx.body.fee); - } - } - } - - fn check_value_size_limit(batches: &TransactionBatchList, cfg: &TransactionBuilderConfig) { - for batch in batches { - for tx in batch { - for output in &tx.body.outputs { - let value_size = output.amount().to_bytes().len(); - assert!(value_size <= cfg.max_value_size as usize); - } - } - } - } - - fn check_tx_size_limit(batches: &TransactionBatchList, cfg: &TransactionBuilderConfig) { - for batch in batches { - for tx in batch { - let tx_size = tx.to_bytes().len(); - assert!(tx_size <= cfg.max_tx_size as usize); - } - } - } - - #[test] - pub fn test_big_utoxs_batch() { - let utxos = generate_big_utoxs_bacth(); - let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); - let cfg = TransactionBuilderConfigBuilder::new() - .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) - .max_value_size(4000) - .max_tx_size(8000) - .coins_per_utxo_word(&to_bignum(34_482)) - .voting_proposal_deposit(&to_bignum(500000000)) - .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), - )) - .build() - .unwrap(); - - let res = create_send_all(&generate_address(10000), &utxos, &cfg); - assert!(res.is_ok()); - - let batches = res.unwrap(); - check_balance(&utxos, &batches); - check_min_adas(&batches, &cfg); - check_fees(&batches, &cfg); - check_value_size_limit(&batches, &cfg); - check_tx_size_limit(&batches, &cfg); - } - - #[test] - pub fn test_big_utoxs_ada_batch() { - let utxos = generate_big_ada_utoxs_bacth(); - let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); - let cfg = TransactionBuilderConfigBuilder::new() - .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) - .max_value_size(4000) - .max_tx_size(8000) - .coins_per_utxo_word(&to_bignum(34_482)) - .voting_proposal_deposit(&to_bignum(500000000)) - .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), - )) - .build() - .unwrap(); - - let res = create_send_all(&generate_address(10000), &utxos, &cfg); - assert!(res.is_ok()); - - let batches = res.unwrap(); - check_balance(&utxos, &batches); - check_min_adas(&batches, &cfg); - check_fees(&batches, &cfg); - check_value_size_limit(&batches, &cfg); - check_tx_size_limit(&batches, &cfg); - } - - #[test] - pub fn test_one_utxo() { - let address = generate_address(1); - let utxo = generate_utxo( - &address, - 1, - 0, - 0, - 3, - 2, - 20, - Coin::from(500u64), - Coin::from(5000000u64)); - - let utxos = TransactionUnspentOutputs(vec![utxo]); - - let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); - let cfg = TransactionBuilderConfigBuilder::new() - .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) - .max_value_size(4000) - .max_tx_size(8000) - .voting_proposal_deposit(&to_bignum(500000000)) - .coins_per_utxo_word(&to_bignum(34_482)) - .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), - )) - .build() - .unwrap(); - - let res = create_send_all(&generate_address(10000), &utxos, &cfg); - assert!(res.is_ok()); - - let batches = res.unwrap(); - check_balance(&utxos, &batches); - check_min_adas(&batches, &cfg); - check_fees(&batches, &cfg); - check_value_size_limit(&batches, &cfg); - check_tx_size_limit(&batches, &cfg); - } - - #[test] - pub fn test_one_utxo_one_asset_per_output() { - let address = generate_address(1); - let utxo_1 = generate_utxo( - &address, - 1, - 0, - 0, - 3, - 1, - 20, - Coin::from(500u64), - Coin::from(5000000u64)); - - let utxo_2 = generate_utxo( - &address, - 2, - 1, - 0, - 3, - 1, - 20, - Coin::from(500u64), - Coin::from(5000000u64)); - - let utxo_3 = generate_utxo( - &address, - 3, - 2, - 0, - 3, - 1, - 20, - Coin::from(500u64), - Coin::from(5000000u64)); - - let utxos = TransactionUnspentOutputs(vec![utxo_1, utxo_2, utxo_3]); - - let linear_fee = LinearFee::new(&to_bignum(1), &to_bignum(0)); - let cfg = TransactionBuilderConfigBuilder::new() - .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) - .max_value_size(80) - .max_tx_size(8000) - .coins_per_utxo_word(&to_bignum(34_482)) - .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), - )) - .build() - .unwrap(); - - let res = create_send_all(&generate_address(10000), &utxos, &cfg); - assert!(res.is_ok()); - - let batches = res.unwrap(); - - for batch in &batches { - for tx in batch { - for output in &tx.body.outputs() { - assert_eq!(output.amount().multiasset.unwrap().0.len(), 1); - for asset in output.amount().multiasset.unwrap().0.values() { - assert_eq!(asset.len(), 1); - } - } - } - } - - check_balance(&utxos, &batches); - check_min_adas(&batches, &cfg); - check_fees(&batches, &cfg); - check_value_size_limit(&batches, &cfg); - check_tx_size_limit(&batches, &cfg); - } - - #[test] - pub fn test_one_utxo_one_asset_per_tx() { - let address = generate_address(1); - let utxo_1 = generate_utxo( - &address, - 1, - 0, - 0, - 1, - 1, - 20, - Coin::from(500u64), - Coin::from(5000000u64)); - - let utxo_2 = generate_utxo( - &address, - 2, - 1, - 0, - 1, - 1, - 20, - Coin::from(500u64), - Coin::from(5000000u64)); - - let utxo_3 = generate_utxo( - &address, - 3, - 2, - 0, - 1, - 1, - 20, - Coin::from(500u64), - Coin::from(5000000u64)); - - let utxos = TransactionUnspentOutputs(vec![utxo_1, utxo_2, utxo_3]); - - let linear_fee = LinearFee::new(&to_bignum(1), &to_bignum(0)); - let cfg = TransactionBuilderConfigBuilder::new() - .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) - .max_value_size(80) - .max_tx_size(300) - .coins_per_utxo_word(&to_bignum(34_482)) - .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), - )) - .build() - .unwrap(); - - let res = create_send_all(&generate_address(10000), &utxos, &cfg); - assert!(res.is_ok()); - - let batches = res.unwrap(); - - for batch in &batches { - for tx in batch { - assert_eq!(tx.body.outputs().len(), 1); - for output in &tx.body.outputs() { - assert_eq!(output.amount().multiasset.unwrap().0.len(), 1); - for asset in output.amount().multiasset.unwrap().0.values() { - assert_eq!(asset.len(), 1); - } - } - } - } - - check_balance(&utxos, &batches); - check_min_adas(&batches, &cfg); - check_fees(&batches, &cfg); - check_value_size_limit(&batches, &cfg); - check_tx_size_limit(&batches, &cfg); - } - - #[test] - pub fn test_only_ada_utxo() { - let address = generate_address(1); - let utxo = generate_utxo( - &address, - 1, - 0, - 0, - 0, - 0, - 20, - Coin::zero(), - Coin::from(5000000u64)); - - let utxos = TransactionUnspentOutputs(vec![utxo]); - - let linear_fee = LinearFee::new(&to_bignum(1), &to_bignum(0)); - let cfg = TransactionBuilderConfigBuilder::new() - .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) - .max_value_size(4000) - .max_tx_size(8000) - .coins_per_utxo_word(&to_bignum(34_482)) - .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), - )) - .build() - .unwrap(); - - let res = create_send_all(&generate_address(10000), &utxos, &cfg); - assert!(res.is_ok()); - - let batches = res.unwrap(); - check_balance(&utxos, &batches); - check_min_adas(&batches, &cfg); - check_fees(&batches, &cfg); - check_value_size_limit(&batches, &cfg); - check_tx_size_limit(&batches, &cfg); - } - - #[test] - pub fn test_not_enough_ada() { - let address = generate_address(1); - let utxo = generate_utxo( - &address, - 1, - 0, - 0, - 0, - 0, - 20, - Coin::zero(), - Coin::from(1u64)); - - let utxos = TransactionUnspentOutputs(vec![utxo]); - - let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); - let cfg = TransactionBuilderConfigBuilder::new() - .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) - .max_value_size(4000) - .max_tx_size(8000) - .coins_per_utxo_word(&to_bignum(34_482)) - .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), - )) - .build() - .unwrap(); - - let res = create_send_all(&generate_address(10000), &utxos, &cfg); - assert!(res.is_err()); - } - - #[test] - pub fn test_value_limit_error() { - let address = generate_address(1); - let utxo = generate_utxo( - &address, - 1, - 0, - 0, - 1, - 1, - 20, - Coin::from(1000000u64), - Coin::from(500000u64)); - - let utxos = TransactionUnspentOutputs(vec![utxo]); - - let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); - let cfg = TransactionBuilderConfigBuilder::new() - .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) - .max_value_size(10) - .max_tx_size(8000000) - .coins_per_utxo_word(&to_bignum(34_482)) - .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), - )) - .build() - .unwrap(); - - let res = create_send_all(&generate_address(10000), &utxos, &cfg); - assert!(res.is_err()); - } - - #[test] - pub fn test_tx_limit_error() { - let address = generate_address(1); - let utxo = generate_utxo( - &address, - 1, - 0, - 0, - 10, - 10, - 20, - Coin::from(1000000u64), - Coin::from(50000000u64)); - - let utxos = TransactionUnspentOutputs(vec![utxo]); - - let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); - let cfg = TransactionBuilderConfigBuilder::new() - .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) - .max_value_size(100) - .max_tx_size(2000) - .coins_per_utxo_word(&to_bignum(34_482)) - .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), - )) - .build() - .unwrap(); - - let res = create_send_all(&generate_address(10000), &utxos, &cfg); - assert!(res.is_err()); - } - - #[test] - pub fn test_no_utxos() { - let utxos = TransactionUnspentOutputs(vec!()); - - let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); - let cfg = TransactionBuilderConfigBuilder::new() - .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) - .max_value_size(10) - .max_tx_size(8000000) - .coins_per_utxo_word(&to_bignum(34_482)) - .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), - )) - .build() - .unwrap(); - - let res = create_send_all(&generate_address(10000), &utxos, &cfg); - assert!(res.is_ok()); - - let batches = res.unwrap(); - let total_txs = batches.into_iter().fold(0, |acc, batch| acc + batch.len()); - assert_eq!(total_txs, 0); - - } - - #[test] - pub fn test_script_input_error() { - let address = Address::from_hex("10798c8ce251c36c15f8bccf3306feae1218fce7503b331e6d92e666aa00efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee164").unwrap(); - let utxo = generate_utxo( - &address, - 1, - 0, - 0, - 0, - 0, - 20, - Coin::zero(), - Coin::from(1u64)); - let utxos = TransactionUnspentOutputs(vec![utxo]); - - let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); - let cfg = TransactionBuilderConfigBuilder::new() - .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) - .max_value_size(10) - .max_tx_size(8000000) - .coins_per_utxo_word(&to_bignum(34_482)) - .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), - )) - .build() - .unwrap(); - - let res = create_send_all(&generate_address(10000), &utxos, &cfg); - assert!(res.is_err()); - } - - #[test] - pub fn test_two_asset_utxo_one_ada_utxo() { - let address = generate_address(1); - let asset_utxo_1 = generate_utxo( - &address, - 1, - 0, - 0, - 1, - 1, - 8, - Coin::from(1u64), - Coin::from(1344798u64)); - - let asset_utxo_2 = generate_utxo( - &address, - 2, - 1, - 1, - 1, - 1, - 8, - Coin::from(1u64), - Coin::from(1344798u64)); - - let ada_utxo = generate_utxo( - &address, - 3, - 0, - 0, - 0, - 0, - 20, - Coin::from(1u64), - Coin::from(9967920528u64)); - - let utxos = TransactionUnspentOutputs(vec![asset_utxo_1, asset_utxo_2, ada_utxo]); - - let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); - let cfg = TransactionBuilderConfigBuilder::new() - .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) - .max_value_size(4000) - .max_tx_size(8000) - .coins_per_utxo_word(&to_bignum(34_482)) - .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), - )) - .build() - .unwrap(); - - let res = create_send_all(&generate_address(10000), &utxos, &cfg); - assert!(res.is_ok()); - - let batches = res.unwrap(); - check_balance(&utxos, &batches); - check_min_adas(&batches, &cfg); - check_fees(&batches, &cfg); - check_value_size_limit(&batches, &cfg); - check_tx_size_limit(&batches, &cfg); - } -} \ No newline at end of file From 1ec90ed3202ad8ac37e409bd06e0298bee2762e3 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 1 Sep 2023 17:51:40 +0500 Subject: [PATCH 119/349] rename macro --- .../certificates/committee_hot_key_deregistration.rs | 2 +- .../certificates/committee_hot_key_registration.rs | 2 +- rust/src/serialization/certificates/drep_deregistration.rs | 2 +- rust/src/serialization/certificates/drep_registration.rs | 2 +- rust/src/serialization/certificates/drep_update.rs | 2 +- rust/src/serialization/certificates/genesis_key_delegation.rs | 2 +- .../certificates/move_instantaneous_rewards_cert.rs | 2 +- rust/src/serialization/certificates/pool_registration.rs | 4 ++-- rust/src/serialization/certificates/pool_retirement.rs | 2 +- .../serialization/certificates/stake_and_vote_delegation.rs | 2 +- rust/src/serialization/certificates/stake_delegation.rs | 2 +- rust/src/serialization/certificates/stake_deregistration.rs | 2 +- rust/src/serialization/certificates/stake_registration.rs | 2 +- .../certificates/stake_registration_and_delegation.rs | 2 +- .../certificates/stake_vote_registration_and_delegation.rs | 2 +- rust/src/serialization/certificates/vote_delegation.rs | 2 +- .../certificates/vote_registration_and_delegation.rs | 2 +- rust/src/serialization/governance/proposals/committee.rs | 2 +- rust/src/serialization/governance/proposals/constitution.rs | 2 +- .../governance/proposals/hard_fork_initiation_proposal.rs | 2 +- .../governance/proposals/new_committee_proposal.rs | 2 +- .../governance/proposals/new_constitution_proposal.rs | 2 +- .../governance/proposals/no_confidence_proposal.rs | 2 +- .../governance/proposals/parameter_change_proposal.rs | 2 +- .../governance/proposals/treasury_withdrawals_proposal.rs | 2 +- rust/src/serialization/serialization_macros.rs | 2 +- 26 files changed, 27 insertions(+), 27 deletions(-) diff --git a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs index 1ed3a5ac..b73b4934 100644 --- a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs @@ -19,7 +19,7 @@ impl cbor_event::se::Serialize for CommitteeHotKeyDeregistration { } } -impl_deserialize_for_tuple!(CommitteeHotKeyDeregistration); +impl_deserialize_for_wrapped_tuple!(CommitteeHotKeyDeregistration); impl DeserializeEmbeddedGroup for CommitteeHotKeyDeregistration { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/certificates/committee_hot_key_registration.rs b/rust/src/serialization/certificates/committee_hot_key_registration.rs index acf0d72f..4928604b 100644 --- a/rust/src/serialization/certificates/committee_hot_key_registration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_registration.rs @@ -21,7 +21,7 @@ impl cbor_event::se::Serialize for CommitteeHotKeyRegistration { } } -impl_deserialize_for_tuple!(CommitteeHotKeyRegistration); +impl_deserialize_for_wrapped_tuple!(CommitteeHotKeyRegistration); impl DeserializeEmbeddedGroup for CommitteeHotKeyRegistration { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/certificates/drep_deregistration.rs b/rust/src/serialization/certificates/drep_deregistration.rs index 22d6268c..9281caac 100644 --- a/rust/src/serialization/certificates/drep_deregistration.rs +++ b/rust/src/serialization/certificates/drep_deregistration.rs @@ -21,7 +21,7 @@ impl cbor_event::se::Serialize for DrepDeregistration { } } -impl_deserialize_for_tuple!(DrepDeregistration); +impl_deserialize_for_wrapped_tuple!(DrepDeregistration); impl DeserializeEmbeddedGroup for DrepDeregistration { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/certificates/drep_registration.rs b/rust/src/serialization/certificates/drep_registration.rs index 0dee8693..a658e6cc 100644 --- a/rust/src/serialization/certificates/drep_registration.rs +++ b/rust/src/serialization/certificates/drep_registration.rs @@ -25,7 +25,7 @@ impl cbor_event::se::Serialize for DrepRegistration { } } -impl_deserialize_for_tuple!(DrepRegistration); +impl_deserialize_for_wrapped_tuple!(DrepRegistration); impl DeserializeEmbeddedGroup for DrepRegistration { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/certificates/drep_update.rs b/rust/src/serialization/certificates/drep_update.rs index e4afe5d0..b9dde9c6 100644 --- a/rust/src/serialization/certificates/drep_update.rs +++ b/rust/src/serialization/certificates/drep_update.rs @@ -24,7 +24,7 @@ impl cbor_event::se::Serialize for DrepUpdate { } } -impl_deserialize_for_tuple!(DrepUpdate); +impl_deserialize_for_wrapped_tuple!(DrepUpdate); impl DeserializeEmbeddedGroup for DrepUpdate { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/certificates/genesis_key_delegation.rs b/rust/src/serialization/certificates/genesis_key_delegation.rs index b27b8598..b1a38626 100644 --- a/rust/src/serialization/certificates/genesis_key_delegation.rs +++ b/rust/src/serialization/certificates/genesis_key_delegation.rs @@ -30,7 +30,7 @@ impl SerializeEmbeddedGroup for GenesisKeyDelegation { } } -impl_deserialize_for_tuple!(GenesisKeyDelegation); +impl_deserialize_for_wrapped_tuple!(GenesisKeyDelegation); impl DeserializeEmbeddedGroup for GenesisKeyDelegation { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs index 0d685cc5..5364143b 100644 --- a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs +++ b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs @@ -130,7 +130,7 @@ impl SerializeEmbeddedGroup for MoveInstantaneousRewardsCert { } } -impl_deserialize_for_tuple!(MoveInstantaneousRewardsCert); +impl_deserialize_for_wrapped_tuple!(MoveInstantaneousRewardsCert); impl DeserializeEmbeddedGroup for MoveInstantaneousRewardsCert { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/certificates/pool_registration.rs b/rust/src/serialization/certificates/pool_registration.rs index 75315244..428801c5 100644 --- a/rust/src/serialization/certificates/pool_registration.rs +++ b/rust/src/serialization/certificates/pool_registration.rs @@ -71,7 +71,7 @@ impl SerializeEmbeddedGroup for PoolParams { } } -impl_deserialize_for_tuple!(PoolParams); +impl_deserialize_for_wrapped_tuple!(PoolParams); impl DeserializeEmbeddedGroup for PoolParams { fn deserialize_as_embedded_group( @@ -147,7 +147,7 @@ impl SerializeEmbeddedGroup for PoolRegistration { } } -impl_deserialize_for_tuple!(PoolRegistration); +impl_deserialize_for_wrapped_tuple!(PoolRegistration); impl DeserializeEmbeddedGroup for PoolRegistration { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/certificates/pool_retirement.rs b/rust/src/serialization/certificates/pool_retirement.rs index effca1da..3087f73c 100644 --- a/rust/src/serialization/certificates/pool_retirement.rs +++ b/rust/src/serialization/certificates/pool_retirement.rs @@ -29,7 +29,7 @@ impl SerializeEmbeddedGroup for PoolRetirement { } } -impl_deserialize_for_tuple!(PoolRetirement); +impl_deserialize_for_wrapped_tuple!(PoolRetirement); impl DeserializeEmbeddedGroup for PoolRetirement { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/certificates/stake_and_vote_delegation.rs b/rust/src/serialization/certificates/stake_and_vote_delegation.rs index 48b28088..4a22b73d 100644 --- a/rust/src/serialization/certificates/stake_and_vote_delegation.rs +++ b/rust/src/serialization/certificates/stake_and_vote_delegation.rs @@ -22,7 +22,7 @@ impl cbor_event::se::Serialize for StakeAndVoteDelegation { } } -impl_deserialize_for_tuple!(StakeAndVoteDelegation); +impl_deserialize_for_wrapped_tuple!(StakeAndVoteDelegation); impl DeserializeEmbeddedGroup for StakeAndVoteDelegation { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/certificates/stake_delegation.rs b/rust/src/serialization/certificates/stake_delegation.rs index d76fd361..205518ce 100644 --- a/rust/src/serialization/certificates/stake_delegation.rs +++ b/rust/src/serialization/certificates/stake_delegation.rs @@ -29,7 +29,7 @@ impl SerializeEmbeddedGroup for StakeDelegation { } } -impl_deserialize_for_tuple!(StakeDelegation); +impl_deserialize_for_wrapped_tuple!(StakeDelegation); impl DeserializeEmbeddedGroup for StakeDelegation { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/certificates/stake_deregistration.rs b/rust/src/serialization/certificates/stake_deregistration.rs index 3da22f65..d0084dd2 100644 --- a/rust/src/serialization/certificates/stake_deregistration.rs +++ b/rust/src/serialization/certificates/stake_deregistration.rs @@ -46,7 +46,7 @@ fn serialize_as_conway<'se, W: Write>( Ok(serializer) } -impl_deserialize_for_tuple!(StakeDeregistration); +impl_deserialize_for_wrapped_tuple!(StakeDeregistration); impl DeserializeEmbeddedGroup for StakeDeregistration { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/certificates/stake_registration.rs b/rust/src/serialization/certificates/stake_registration.rs index b52b74a9..288556e0 100644 --- a/rust/src/serialization/certificates/stake_registration.rs +++ b/rust/src/serialization/certificates/stake_registration.rs @@ -46,7 +46,7 @@ fn serialize_as_conway<'se, W: Write>( Ok(serializer) } -impl_deserialize_for_tuple!(StakeRegistration); +impl_deserialize_for_wrapped_tuple!(StakeRegistration); impl DeserializeEmbeddedGroup for StakeRegistration { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/certificates/stake_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_registration_and_delegation.rs index 92031bc5..e227dff4 100644 --- a/rust/src/serialization/certificates/stake_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/stake_registration_and_delegation.rs @@ -22,7 +22,7 @@ impl cbor_event::se::Serialize for StakeRegistrationAndDelegation { } } -impl_deserialize_for_tuple!(StakeRegistrationAndDelegation); +impl_deserialize_for_wrapped_tuple!(StakeRegistrationAndDelegation); impl DeserializeEmbeddedGroup for StakeRegistrationAndDelegation { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs index 19570e47..ab31cbb6 100644 --- a/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs @@ -27,7 +27,7 @@ impl cbor_event::se::Serialize for StakeVoteRegistrationAndDelegation { } } -impl_deserialize_for_tuple!(StakeVoteRegistrationAndDelegation); +impl_deserialize_for_wrapped_tuple!(StakeVoteRegistrationAndDelegation); impl DeserializeEmbeddedGroup for StakeVoteRegistrationAndDelegation { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/certificates/vote_delegation.rs b/rust/src/serialization/certificates/vote_delegation.rs index f84b07ac..15bc7888 100644 --- a/rust/src/serialization/certificates/vote_delegation.rs +++ b/rust/src/serialization/certificates/vote_delegation.rs @@ -21,7 +21,7 @@ impl cbor_event::se::Serialize for VoteDelegation { } } -impl_deserialize_for_tuple!(VoteDelegation); +impl_deserialize_for_wrapped_tuple!(VoteDelegation); impl DeserializeEmbeddedGroup for VoteDelegation { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/certificates/vote_registration_and_delegation.rs b/rust/src/serialization/certificates/vote_registration_and_delegation.rs index fadc717e..5e540ab3 100644 --- a/rust/src/serialization/certificates/vote_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/vote_registration_and_delegation.rs @@ -22,7 +22,7 @@ impl cbor_event::se::Serialize for VoteRegistrationAndDelegation { } } -impl_deserialize_for_tuple!(VoteRegistrationAndDelegation); +impl_deserialize_for_wrapped_tuple!(VoteRegistrationAndDelegation); impl DeserializeEmbeddedGroup for VoteRegistrationAndDelegation { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/governance/proposals/committee.rs b/rust/src/serialization/governance/proposals/committee.rs index ac459663..535c7c5a 100644 --- a/rust/src/serialization/governance/proposals/committee.rs +++ b/rust/src/serialization/governance/proposals/committee.rs @@ -18,7 +18,7 @@ impl Serialize for Committee { } } -impl_deserialize_for_tuple!(Committee); +impl_deserialize_for_wrapped_tuple!(Committee); impl DeserializeEmbeddedGroup for Committee { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/governance/proposals/constitution.rs b/rust/src/serialization/governance/proposals/constitution.rs index 52ec63d3..b6b228e9 100644 --- a/rust/src/serialization/governance/proposals/constitution.rs +++ b/rust/src/serialization/governance/proposals/constitution.rs @@ -13,7 +13,7 @@ impl Serialize for Constitution { } } -impl_deserialize_for_tuple!(Constitution); +impl_deserialize_for_wrapped_tuple!(Constitution); impl DeserializeEmbeddedGroup for Constitution { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/governance/proposals/hard_fork_initiation_proposal.rs b/rust/src/serialization/governance/proposals/hard_fork_initiation_proposal.rs index 8435f782..cb66c3cb 100644 --- a/rust/src/serialization/governance/proposals/hard_fork_initiation_proposal.rs +++ b/rust/src/serialization/governance/proposals/hard_fork_initiation_proposal.rs @@ -27,7 +27,7 @@ impl cbor_event::se::Serialize for HardForkInitiationProposal { } } -impl_deserialize_for_tuple!(HardForkInitiationProposal); +impl_deserialize_for_wrapped_tuple!(HardForkInitiationProposal); impl DeserializeEmbeddedGroup for HardForkInitiationProposal { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/governance/proposals/new_committee_proposal.rs b/rust/src/serialization/governance/proposals/new_committee_proposal.rs index d0645c0c..1bf70101 100644 --- a/rust/src/serialization/governance/proposals/new_committee_proposal.rs +++ b/rust/src/serialization/governance/proposals/new_committee_proposal.rs @@ -25,7 +25,7 @@ impl Serialize for NewCommitteeProposal { } } -impl_deserialize_for_tuple!(NewCommitteeProposal); +impl_deserialize_for_wrapped_tuple!(NewCommitteeProposal); impl DeserializeEmbeddedGroup for NewCommitteeProposal { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/governance/proposals/new_constitution_proposal.rs b/rust/src/serialization/governance/proposals/new_constitution_proposal.rs index 24d3fe3f..6464964f 100644 --- a/rust/src/serialization/governance/proposals/new_constitution_proposal.rs +++ b/rust/src/serialization/governance/proposals/new_constitution_proposal.rs @@ -22,7 +22,7 @@ impl Serialize for NewConstitutionProposal { } } -impl_deserialize_for_tuple!(NewConstitutionProposal); +impl_deserialize_for_wrapped_tuple!(NewConstitutionProposal); impl DeserializeEmbeddedGroup for NewConstitutionProposal { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/governance/proposals/no_confidence_proposal.rs b/rust/src/serialization/governance/proposals/no_confidence_proposal.rs index 07f69a76..e8cb6b2b 100644 --- a/rust/src/serialization/governance/proposals/no_confidence_proposal.rs +++ b/rust/src/serialization/governance/proposals/no_confidence_proposal.rs @@ -20,7 +20,7 @@ impl cbor_event::se::Serialize for NoConfidenceProposal { } } -impl_deserialize_for_tuple!(NoConfidenceProposal); +impl_deserialize_for_wrapped_tuple!(NoConfidenceProposal); impl DeserializeEmbeddedGroup for NoConfidenceProposal { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/governance/proposals/parameter_change_proposal.rs b/rust/src/serialization/governance/proposals/parameter_change_proposal.rs index e502ddda..c533a50a 100644 --- a/rust/src/serialization/governance/proposals/parameter_change_proposal.rs +++ b/rust/src/serialization/governance/proposals/parameter_change_proposal.rs @@ -21,7 +21,7 @@ impl cbor_event::se::Serialize for ParameterChangeProposal { } } -impl_deserialize_for_tuple!(ParameterChangeProposal); +impl_deserialize_for_wrapped_tuple!(ParameterChangeProposal); impl DeserializeEmbeddedGroup for ParameterChangeProposal { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/governance/proposals/treasury_withdrawals_proposal.rs b/rust/src/serialization/governance/proposals/treasury_withdrawals_proposal.rs index b13f1471..16826447 100644 --- a/rust/src/serialization/governance/proposals/treasury_withdrawals_proposal.rs +++ b/rust/src/serialization/governance/proposals/treasury_withdrawals_proposal.rs @@ -20,7 +20,7 @@ impl Serialize for TreasuryWithdrawalsProposal { } } -impl_deserialize_for_tuple!(TreasuryWithdrawalsProposal); +impl_deserialize_for_wrapped_tuple!(TreasuryWithdrawalsProposal); impl DeserializeEmbeddedGroup for TreasuryWithdrawalsProposal { fn deserialize_as_embedded_group( diff --git a/rust/src/serialization/serialization_macros.rs b/rust/src/serialization/serialization_macros.rs index de4ca060..e8e7ddb0 100644 --- a/rust/src/serialization/serialization_macros.rs +++ b/rust/src/serialization/serialization_macros.rs @@ -137,7 +137,7 @@ macro_rules! impl_to_from { } #[macro_export] -macro_rules! impl_deserialize_for_tuple { +macro_rules! impl_deserialize_for_wrapped_tuple { ($type:ty) => { impl Deserialize for $type { fn deserialize( From f3d6d9d84d713ebfaa3d4299cffaf4a3e5979a75 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 8 Sep 2023 21:23:03 +0500 Subject: [PATCH 120/349] move tx builder + fmt --- rust/src/address.rs | 9 +- rust/src/crypto.rs | 15 ++- rust/src/fakes.rs | 10 +- rust/src/fees.rs | 2 +- rust/src/lib.rs | 243 ++++++++++++++++++++++++++++-------- rust/src/plutus.rs | 246 +++++++++++++++++++++++------------- rust/src/utils.rs | 297 ++++++++++++++++++++++++-------------------- 7 files changed, 540 insertions(+), 282 deletions(-) diff --git a/rust/src/address.rs b/rust/src/address.rs index f2647bd6..665e5961 100644 --- a/rust/src/address.rs +++ b/rust/src/address.rs @@ -67,7 +67,10 @@ impl NetworkInfo { } /// !!! DEPRECATED !!! /// This network does not exist anymore. Use `.testnet_preview()` or `.testnet_preprod()` - #[deprecated(since = "11.2.0", note = "Use `.testnet_preview` or `.testnet_preprod`")] + #[deprecated( + since = "11.2.0", + note = "Use `.testnet_preview` or `.testnet_preprod`" + )] pub fn testnet() -> NetworkInfo { NetworkInfo { network_id: 0b0000, @@ -212,7 +215,7 @@ impl Deserialize for Credential { // TODO: change codegen to make FixedValueMismatch support Vec or ranges or something expected: Key::Uint(0), } - .into()) + .into()); } }; if let cbor_event::Len::Indefinite = len { @@ -902,4 +905,4 @@ impl PointerAddress { _ => None, } } -} \ No newline at end of file +} diff --git a/rust/src/crypto.rs b/rust/src/crypto.rs index df6c4519..0085f65b 100644 --- a/rust/src/crypto.rs +++ b/rust/src/crypto.rs @@ -5,10 +5,10 @@ use cbor_event::{de::Deserializer, se::Serializer}; use chain::key; use crypto::bech32::Bech32 as _; use rand_os::OsRng; +use std::fmt; +use std::fmt::Display; use std::io::{BufRead, Seek, Write}; use std::str::FromStr; -use std::fmt::Display; -use std::fmt; use cryptoxide::blake2b::Blake2b; @@ -1217,7 +1217,16 @@ impl JsonSchema for KESSignature { // Evolving nonce type (used for Update's crypto) #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct Nonce { hash: Option<[u8; 32]>, diff --git a/rust/src/fakes.rs b/rust/src/fakes.rs index e9333478..9f72819f 100644 --- a/rust/src/fakes.rs +++ b/rust/src/fakes.rs @@ -1,6 +1,12 @@ #![allow(dead_code)] -use crate::{to_bignum, Address, BaseAddress, Bip32PrivateKey, DataHash, Ed25519KeyHash, Ed25519Signature, NetworkInfo, Credential, TransactionHash, TransactionIndex, TransactionInput, TransactionOutput, Value, Vkey, PolicyID}; -use crate::crypto::{AnchorDataHash, GenesisDelegateHash, GenesisHash, PoolMetadataHash, ScriptHash, VRFKeyHash}; +use crate::crypto::{ + AnchorDataHash, GenesisDelegateHash, GenesisHash, PoolMetadataHash, ScriptHash, VRFKeyHash, +}; +use crate::{ + to_bignum, Address, BaseAddress, Bip32PrivateKey, Credential, DataHash, Ed25519KeyHash, + Ed25519Signature, NetworkInfo, PolicyID, TransactionHash, TransactionIndex, TransactionInput, + TransactionOutput, Value, Vkey, +}; pub(crate) fn fake_bytes_32(x: u8) -> Vec { vec![ diff --git a/rust/src/fees.rs b/rust/src/fees.rs index c53846fc..03682537 100644 --- a/rust/src/fees.rs +++ b/rust/src/fees.rs @@ -89,8 +89,8 @@ pub fn min_script_fee(tx: &Transaction, ex_unit_prices: &ExUnitPrices) -> Result #[cfg(test)] mod tests { - use super::output_builder::TransactionOutputBuilder; use super::*; + use crate::TransactionOutputBuilder; use address::*; use crypto::*; diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 247363e8..c4788c0a 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -28,7 +28,7 @@ use std::io::{BufRead, Seek, Write}; use noop_proc_macro::wasm_bindgen; #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] -use wasm_bindgen::prelude::{JsValue, wasm_bindgen}; +use wasm_bindgen::prelude::{wasm_bindgen, JsValue}; // This file was code-generated using an experimental CDDL to rust tool: // https://github.com/Emurgo/cddl-codegen @@ -42,6 +42,7 @@ use cbor_event::{ }; pub mod address; +mod builders; pub mod chain_core; pub mod chain_crypto; pub mod crypto; @@ -51,17 +52,15 @@ pub mod fees; pub mod impl_mockchain; pub mod legacy_address; pub mod metadata; -pub mod output_builder; pub mod plutus; pub mod traits; -pub mod tx_builder; -pub mod tx_builder_constants; -pub mod typed_bytes; +pub use builders::*; mod protocol_types; +pub mod typed_bytes; pub use protocol_types::*; #[macro_use] pub mod utils; -mod fakes; +pub(crate) mod fakes; mod serialization; use crate::traits::NoneOrEmpty; @@ -71,18 +70,27 @@ use error::*; use metadata::*; use plutus::*; use schemars::JsonSchema; +use serialization::*; use std::cmp::Ordering; use std::collections::BTreeSet; -use std::fmt::Display; use std::fmt; +use std::fmt::Display; use utils::*; -use serialization::*; type DeltaCoin = Int; #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct UnitInterval { numerator: BigNum, @@ -560,7 +568,16 @@ impl TransactionBody { #[wasm_bindgen] #[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Eq, + Ord, + PartialEq, + PartialOrd, + Hash, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct TransactionInput { transaction_id: TransactionHash, @@ -588,9 +605,7 @@ impl TransactionInput { } #[wasm_bindgen] -#[derive( - Debug, Clone, Eq, Ord, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] +#[derive(Debug, Clone, Eq, Ord, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema)] pub struct TransactionOutput { address: Address, amount: Value, @@ -687,7 +702,16 @@ impl PartialEq for TransactionOutput { #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct Ed25519KeyHashes(pub(crate) Vec); @@ -729,12 +753,20 @@ impl IntoIterator for Ed25519KeyHashes { } } - type Port = u16; #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct Ipv4([u8; 4]); @@ -764,7 +796,16 @@ impl Ipv4 { #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct Ipv6([u8; 16]); @@ -796,7 +837,16 @@ static URL_MAX_LEN: usize = 64; #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct URL(String); @@ -832,7 +882,16 @@ static DNS_NAME_MAX_LEN: usize = 64; #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct DNSRecordAorAAAA(String); @@ -866,7 +925,16 @@ impl DNSRecordAorAAAA { #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct DNSRecordSRV(String); @@ -900,7 +968,16 @@ impl DNSRecordSRV { #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct SingleHostAddr { port: Option, @@ -935,7 +1012,16 @@ impl SingleHostAddr { #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct SingleHostName { port: Option, @@ -964,7 +1050,16 @@ impl SingleHostName { #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct MultiHostName { dns_name: DNSRecordSRV, @@ -994,7 +1089,16 @@ pub enum RelayKind { } #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub enum RelayEnum { SingleHostAddr(SingleHostAddr), @@ -1004,7 +1108,16 @@ pub enum RelayEnum { #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct Relay(RelayEnum); @@ -1056,7 +1169,16 @@ impl Relay { #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct PoolMetadata { url: URL, @@ -1547,12 +1669,11 @@ pub enum DataOption { } #[wasm_bindgen] -#[derive(Debug, Clone, Eq, Ord, PartialEq, PartialOrd )] +#[derive(Debug, Clone, Eq, Ord, PartialEq, PartialOrd)] pub struct OutputDatum(pub(crate) DataOption); #[wasm_bindgen] impl OutputDatum { - pub fn new_data_hash(data_hash: &DataHash) -> Self { Self(DataOption::DataHash(data_hash.clone())) } @@ -1897,7 +2018,16 @@ impl ProposedProtocolParameterUpdates { #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct ProtocolVersion { major: u32, @@ -1923,7 +2053,16 @@ impl ProtocolVersion { #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct ProtocolParamUpdate { minfee_a: Option, @@ -3002,8 +3141,8 @@ impl Mint { /// Mint can store multiple entries for the same policy id. /// Use `.get_all` instead. #[deprecated( - since = "11.2.0", - note = "Mint can store multiple entries for the same policy id. Use `.get_all` instead." + since = "11.2.0", + note = "Mint can store multiple entries for the same policy id. Use `.get_all` instead." )] pub fn get(&self, key: &PolicyID) -> Option { self.0 @@ -3014,7 +3153,8 @@ impl Mint { } pub fn get_all(&self, key: &PolicyID) -> Option { - let mints : Vec = self.0 + let mints: Vec = self + .0 .iter() .filter(|(k, _)| k.eq(key)) .map(|(_k, v)| v.clone()) @@ -3036,24 +3176,26 @@ impl Mint { } fn as_multiasset(&self, is_positive: bool) -> MultiAsset { - self.0.iter().fold(MultiAsset::new(), |res, e : &(PolicyID, MintAssets) | { - let assets: Assets = (e.1).0.iter().fold(Assets::new(), |res, e| { - let mut assets = res; - if e.1.is_positive() == is_positive { - let amount = match is_positive { - true => e.1.as_positive(), - false => e.1.as_negative(), - }; - assets.insert(&e.0, &amount.unwrap()); + self.0 + .iter() + .fold(MultiAsset::new(), |res, e: &(PolicyID, MintAssets)| { + let assets: Assets = (e.1).0.iter().fold(Assets::new(), |res, e| { + let mut assets = res; + if e.1.is_positive() == is_positive { + let amount = match is_positive { + true => e.1.as_positive(), + false => e.1.as_negative(), + }; + assets.insert(&e.0, &amount.unwrap()); + } + assets + }); + let mut ma = res; + if !assets.0.is_empty() { + ma.insert(&e.0, &assets); } - assets - }); - let mut ma = res; - if !assets.0.is_empty() { - ma.insert(&e.0, &assets); - } - ma - }) + ma + }) } /// Returns the multiasset where only positive (minting) entries are present @@ -3143,4 +3285,3 @@ impl From<&NativeScripts> for RequiredSignersSet { }) } } - diff --git a/rust/src/plutus.rs b/rust/src/plutus.rs index ce9e136c..ce80ba21 100644 --- a/rust/src/plutus.rs +++ b/rust/src/plutus.rs @@ -1,8 +1,8 @@ -use std::hash::Hash; use super::*; -use std::io::{BufRead, Seek, Write}; -use linked_hash_map::LinkedHashMap; use core::hash::Hasher; +use linked_hash_map::LinkedHashMap; +use std::hash::Hash; +use std::io::{BufRead, Seek, Write}; // This library was code-generated using an experimental CDDL to rust tool: // https://github.com/Emurgo/cddl-codegen @@ -271,7 +271,16 @@ impl ConstrPlutusData { #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct CostModel(Vec); @@ -324,7 +333,16 @@ impl From> for CostModel { #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct Costmdls(std::collections::BTreeMap); @@ -402,7 +420,9 @@ impl Costmdls { let mut result = Costmdls::new(); for lang in &languages.0 { match self.get(&lang) { - Some(costmodel) => { result.insert(&lang, &costmodel); }, + Some(costmodel) => { + result.insert(&lang, &costmodel); + } _ => {} } } @@ -412,7 +432,16 @@ impl Costmdls { #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct ExUnitPrices { mem_price: SubCoin, @@ -441,7 +470,16 @@ impl ExUnitPrices { #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct ExUnits { mem: BigNum, @@ -601,8 +639,7 @@ pub enum PlutusDataKind { Bytes, } -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] pub enum PlutusDataEnum { ConstrPlutusData(ConstrPlutusData), Map(PlutusMap), @@ -650,7 +687,10 @@ impl PlutusData { Self::new_constr_plutus_data(&ConstrPlutusData::new(alternative, &PlutusList::new())) } - pub fn new_single_value_constr_plutus_data(alternative: &BigNum, plutus_data: &PlutusData) -> Self { + pub fn new_single_value_constr_plutus_data( + alternative: &BigNum, + plutus_data: &PlutusData, + ) -> Self { let mut list = PlutusList::new(); list.add(plutus_data); Self::new_constr_plutus_data(&ConstrPlutusData::new(alternative, &list)) @@ -743,14 +783,14 @@ impl PlutusData { AddrType::Enterprise(addr) => Ok(addr.payment_cred()), AddrType::Ptr(addr) => Ok(addr.payment_cred()), AddrType::Reward(addr) => Ok(addr.payment_cred()), - AddrType::Byron(_) => - Err(JsError::from_str("Cannot convert Byron address to PlutusData")), + AddrType::Byron(_) => Err(JsError::from_str( + "Cannot convert Byron address to PlutusData", + )), }?; let staking_data = match &address.0 { AddrType::Base(addr) => { - let staking_bytes_data = - PlutusData::from_stake_credential(&addr.stake_cred())?; + let staking_bytes_data = PlutusData::from_stake_credential(&addr.stake_cred())?; Some(PlutusData::new_single_value_constr_plutus_data( &BigNum::from(0u32), &staking_bytes_data, @@ -760,32 +800,33 @@ impl PlutusData { }; let pointer_data = match &address.0 { - AddrType::Ptr(addr) => - Some(PlutusData::from_pointer(&addr.stake_pointer())?), + AddrType::Ptr(addr) => Some(PlutusData::from_pointer(&addr.stake_pointer())?), _ => None, }; let payment_data = PlutusData::from_stake_credential(&payment_cred)?; let staking_optional_data = match (staking_data, pointer_data) { - (Some(_), Some(_)) => - Err(JsError::from_str("Address can't have both staking and pointer data")), + (Some(_), Some(_)) => Err(JsError::from_str( + "Address can't have both staking and pointer data", + )), (Some(staking_data), None) => Ok(Some(staking_data)), (None, Some(pointer_data)) => Ok(Some(pointer_data)), - (None, None) => Ok(None) + (None, None) => Ok(None), }?; let mut data_list = PlutusList::new(); data_list.add(&payment_data); if let Some(staking_optional_data) = staking_optional_data { - data_list.add( - &PlutusData::new_single_value_constr_plutus_data( - &BigNum::from(0u32), &staking_optional_data)); + data_list.add(&PlutusData::new_single_value_constr_plutus_data( + &BigNum::from(0u32), + &staking_optional_data, + )); } else { - data_list.add(&PlutusData::new_empty_constr_plutus_data( - &BigNum::from(1u32))); + data_list.add(&PlutusData::new_empty_constr_plutus_data(&BigNum::from( + 1u32, + ))); } - Ok(PlutusData::new_constr_plutus_data(&ConstrPlutusData::new( &BigNum::from(0u32), &data_list, @@ -794,23 +835,34 @@ impl PlutusData { fn from_stake_credential(stake_credential: &Credential) -> Result { let (bytes_plutus_data, index) = match &stake_credential.0 { - StakeCredType::Key(key_hash) => - (PlutusData::new_bytes(key_hash.to_bytes().to_vec()), BigNum::from(0u32)), - StakeCredType::Script(script_hash) => - (PlutusData::new_bytes(script_hash.to_bytes().to_vec()), BigNum::from(1u32)), + StakeCredType::Key(key_hash) => ( + PlutusData::new_bytes(key_hash.to_bytes().to_vec()), + BigNum::from(0u32), + ), + StakeCredType::Script(script_hash) => ( + PlutusData::new_bytes(script_hash.to_bytes().to_vec()), + BigNum::from(1u32), + ), }; - Ok(PlutusData::new_single_value_constr_plutus_data(&index, &bytes_plutus_data)) + Ok(PlutusData::new_single_value_constr_plutus_data( + &index, + &bytes_plutus_data, + )) } fn from_pointer(pointer: &Pointer) -> Result { let mut data_list = PlutusList::new(); data_list.add(&PlutusData::new_integer(&pointer.slot_bignum().into())); data_list.add(&PlutusData::new_integer(&pointer.tx_index_bignum().into())); - data_list.add(&PlutusData::new_integer(&pointer.cert_index_bignum().into())); + data_list.add(&PlutusData::new_integer( + &pointer.cert_index_bignum().into(), + )); - Ok(PlutusData::new_constr_plutus_data( - &ConstrPlutusData::new(&BigNum::from(1u32), &data_list))) + Ok(PlutusData::new_constr_plutus_data(&ConstrPlutusData::new( + &BigNum::from(1u32), + &data_list, + ))) } } @@ -832,21 +884,26 @@ impl JsonSchema for PlutusData { //TODO: need to figure out what schema to use here impl serde::Serialize for PlutusData { fn serialize(&self, serializer: S) -> Result - where S: serde::Serializer { - let json = decode_plutus_datum_to_json_str( - self, - PlutusDatumSchema::DetailedSchema) - .map_err(|ser_err| serde::ser::Error::custom(&format!("Serialization error: {:?}", ser_err)))?; + where + S: serde::Serializer, + { + let json = decode_plutus_datum_to_json_str(self, PlutusDatumSchema::DetailedSchema) + .map_err(|ser_err| { + serde::ser::Error::custom(&format!("Serialization error: {:?}", ser_err)) + })?; serializer.serialize_str(&json) } } -impl <'de> serde::de::Deserialize<'de> for PlutusData { - fn deserialize(deserializer: D) -> Result where - D: serde::de::Deserializer<'de> { +impl<'de> serde::de::Deserialize<'de> for PlutusData { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { let datum_json = ::deserialize(deserializer)?; - encode_json_str_to_plutus_datum(&datum_json, PlutusDatumSchema::DetailedSchema) - .map_err(|ser_err| serde::de::Error::custom(&format!("Deserialization error: {:?}", ser_err))) + encode_json_str_to_plutus_datum(&datum_json, PlutusDatumSchema::DetailedSchema).map_err( + |ser_err| serde::de::Error::custom(&format!("Deserialization error: {:?}", ser_err)), + ) } } @@ -996,7 +1053,16 @@ pub enum RedeemerTagKind { #[wasm_bindgen] #[derive( - Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct RedeemerTag(RedeemerTagKind); @@ -2098,8 +2164,8 @@ impl Deserialize for Strings { #[cfg(test)] mod tests { use super::*; + use crate::TxBuilderConstants; use hex::*; - use crate::tx_builder_constants::TxBuilderConstants; #[test] pub fn plutus_constr_data() { @@ -2416,7 +2482,7 @@ mod tests { #[test] fn test_cost_model_roundtrip() { - use crate::tx_builder_constants::TxBuilderConstants; + use crate::TxBuilderConstants; let costmodels = TxBuilderConstants::plutus_vasil_cost_models(); assert_eq!( costmodels, @@ -2426,7 +2492,7 @@ mod tests { #[test] fn test_known_plutus_data_hash() { - use crate::tx_builder_constants::TxBuilderConstants; + use crate::TxBuilderConstants; let pdata = PlutusList::from(vec![PlutusData::new_constr_plutus_data( &ConstrPlutusData::new( &BigNum::zero(), @@ -2507,64 +2573,68 @@ mod tests { let mut costmodels = Costmdls::new(); costmodels.insert( &Language::new_plutus_v2(), - &TxBuilderConstants::plutus_vasil_cost_models().get(&Language::new_plutus_v2()).unwrap(), + &TxBuilderConstants::plutus_vasil_cost_models() + .get(&Language::new_plutus_v2()) + .unwrap(), ); let hash = hash_script_data( - &Redeemers(vec![ - Redeemer::new( - &RedeemerTag::new_spend(), - &BigNum::zero(), - &PlutusData::new_empty_constr_plutus_data(&BigNum::zero()), - &ExUnits::new(&to_bignum(842996), &to_bignum(246100241)), - ), - ]), + &Redeemers(vec![Redeemer::new( + &RedeemerTag::new_spend(), + &BigNum::zero(), + &PlutusData::new_empty_constr_plutus_data(&BigNum::zero()), + &ExUnits::new(&to_bignum(842996), &to_bignum(246100241)), + )]), &costmodels, None, ); - assert_eq!(hex::encode(hash.to_bytes()), "6b244f15f895fd458a02bef3a8b56f17f24150fddcb06be482f8790a600578a1"); + assert_eq!( + hex::encode(hash.to_bytes()), + "6b244f15f895fd458a02bef3a8b56f17f24150fddcb06be482f8790a600578a1" + ); } #[test] fn test_known_plutus_data_hash_2() { - let datums = PlutusList::from(vec![ - PlutusData::new_constr_plutus_data( - &ConstrPlutusData::new( - &BigNum::zero(), - &PlutusList::from(vec![ - PlutusData::new_bytes( - hex::decode("45F6A506A49A38263C4A8BBB2E1E369DD8732FB1F9A281F3E8838387").unwrap(), - ), - PlutusData::new_integer(&BigInt::from_str("60000000").unwrap()), - PlutusData::new_bytes( - hex::decode("EE8E37676F6EBB8E031DFF493F88FF711D24AA68666A09D61F1D3FB3").unwrap(), - ), - PlutusData::new_bytes( - hex::decode("43727970746F44696E6F3036333039").unwrap(), - ), - ]), - ) - ) - ]); - let redeemers = Redeemers(vec![ - Redeemer::new( - &RedeemerTag::new_spend(), - &BigNum::one(), - &PlutusData::new_empty_constr_plutus_data(&BigNum::one()), - &ExUnits::new(&to_bignum(61300), &to_bignum(18221176)), + let datums = PlutusList::from(vec![PlutusData::new_constr_plutus_data( + &ConstrPlutusData::new( + &BigNum::zero(), + &PlutusList::from(vec![ + PlutusData::new_bytes( + hex::decode("45F6A506A49A38263C4A8BBB2E1E369DD8732FB1F9A281F3E8838387") + .unwrap(), + ), + PlutusData::new_integer(&BigInt::from_str("60000000").unwrap()), + PlutusData::new_bytes( + hex::decode("EE8E37676F6EBB8E031DFF493F88FF711D24AA68666A09D61F1D3FB3") + .unwrap(), + ), + PlutusData::new_bytes(hex::decode("43727970746F44696E6F3036333039").unwrap()), + ]), ), - ]); + )]); + let redeemers = Redeemers(vec![Redeemer::new( + &RedeemerTag::new_spend(), + &BigNum::one(), + &PlutusData::new_empty_constr_plutus_data(&BigNum::one()), + &ExUnits::new(&to_bignum(61300), &to_bignum(18221176)), + )]); let hash = hash_script_data( &redeemers, &TxBuilderConstants::plutus_vasil_cost_models() .retain_language_versions(&Languages(vec![Language::new_plutus_v1()])), Some(datums), ); - assert_eq!(hex::encode(hash.to_bytes()), "0a076247a05aacbecf72ea15b94e3d0331b21295a08d9ab7b8675c13840563a6"); + assert_eq!( + hex::encode(hash.to_bytes()), + "0a076247a05aacbecf72ea15b94e3d0331b21295a08d9ab7b8675c13840563a6" + ); } #[test] fn datum_from_enterprise_key_address() { - let address = Address::from_bech32("addr1vxy2c673nsdp0mvgq5d3tpjndngucsytug00k7k6xwlx4lg6dspk5").unwrap(); + let address = + Address::from_bech32("addr1vxy2c673nsdp0mvgq5d3tpjndngucsytug00k7k6xwlx4lg6dspk5") + .unwrap(); let datum = PlutusData::from_address(&address).unwrap(); let orig_datum = PlutusData::from_json("{\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"bytes\": \"88ac6bd19c1a17ed88051b1586536cd1cc408be21efb7ada33be6afd\"}]}, {\"constructor\": 1, \"fields\": []}]}", PlutusDatumSchema::DetailedSchema).unwrap(); @@ -2573,7 +2643,9 @@ mod tests { #[test] fn datum_from_enterprise_script_address() { - let address = Address::from_bech32("addr1w8wrk560wcsldjpnqjamn8s0gn9pdrplpyetrdfpacqrpfs3xezd8").unwrap(); + let address = + Address::from_bech32("addr1w8wrk560wcsldjpnqjamn8s0gn9pdrplpyetrdfpacqrpfs3xezd8") + .unwrap(); let datum = PlutusData::from_address(&address).unwrap(); let orig_datum = PlutusData::from_json("{\"constructor\": 0, \"fields\": [{\"constructor\": 1, \"fields\": [{\"bytes\": \"dc3b534f7621f6c83304bbb99e0f44ca168c3f0932b1b521ee0030a6\"}]}, {\"constructor\": 1, \"fields\": []}]}", PlutusDatumSchema::DetailedSchema).unwrap(); diff --git a/rust/src/utils.rs b/rust/src/utils.rs index 94c67c5d..3f3183be 100644 --- a/rust/src/utils.rs +++ b/rust/src/utils.rs @@ -7,12 +7,12 @@ use hex::FromHex; use num_bigint::Sign; use serde_json; use std::convert::TryFrom; +use std::fmt::Display; use std::ops::Div; use std::{ collections::HashMap, io::{BufRead, Seek, Write}, }; -use std::fmt::Display; use super::*; use crate::error::{DeserializeError, DeserializeFailure}; @@ -30,10 +30,8 @@ pub fn from_bytes(data: &Vec) -> Result T::deserialize(&mut raw) } - - #[wasm_bindgen] -#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, JsonSchema,)] +#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, JsonSchema)] pub struct TransactionUnspentOutput { pub(crate) input: TransactionInput, pub(crate) output: TransactionOutput, @@ -79,19 +77,19 @@ impl Deserialize for TransactionUnspentOutput { let input = (|| -> Result<_, DeserializeError> { Ok(TransactionInput::deserialize(raw)?) })() - .map_err(|e| e.annotate("input"))?; + .map_err(|e| e.annotate("input"))?; let output = (|| -> Result<_, DeserializeError> { Ok(TransactionOutput::deserialize(raw)?) })() - .map_err(|e| e.annotate("output"))?; + .map_err(|e| e.annotate("output"))?; let ret = Ok(Self { input, output }); match len { cbor_event::Len::Len(n) => match n { 2 => /* it's ok */ - { - () - } + { + () + } n => { return Err( DeserializeFailure::DefiniteLenMismatch(n, Some(2)).into() @@ -101,9 +99,9 @@ impl Deserialize for TransactionUnspentOutput { cbor_event::Len::Indefinite => match raw.special()? { CBORSpecial::Break => /* it's ok */ - { - () - } + { + () + } _ => return Err(DeserializeFailure::EndingBreakMissing.into()), }, } @@ -112,12 +110,12 @@ impl Deserialize for TransactionUnspentOutput { _ => Err(DeserializeFailure::NoVariantMatched.into()), } })() - .map_err(|e| e.annotate("TransactionUnspentOutput")) + .map_err(|e| e.annotate("TransactionUnspentOutput")) } } #[wasm_bindgen] -#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, JsonSchema,)] +#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, JsonSchema)] pub struct TransactionUnspentOutputs(pub(crate) Vec); to_from_json!(TransactionUnspentOutputs); @@ -244,7 +242,11 @@ impl BigNum { } pub fn max(a: &BigNum, b: &BigNum) -> BigNum { - if a.less_than(b) { b.clone() } else { a.clone() } + if a.less_than(b) { + b.clone() + } else { + a.clone() + } } } @@ -265,14 +267,12 @@ impl TryFrom for u32 { } impl From for u64 { - fn from(value: BigNum) -> Self { value.0 } } impl From for usize { - fn from(value: BigNum) -> Self { value.0 as usize } @@ -316,8 +316,8 @@ impl Deserialize for BigNum { impl serde::Serialize for BigNum { fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, + where + S: serde::Serializer, { serializer.serialize_str(&self.to_str()) } @@ -325,8 +325,8 @@ impl serde::Serialize for BigNum { impl<'de> serde::de::Deserialize<'de> for BigNum { fn deserialize(deserializer: D) -> Result - where - D: serde::de::Deserializer<'de>, + where + D: serde::de::Deserializer<'de>, { let s = ::deserialize(deserializer)?; Self::from_str(&s).map_err(|_e| { @@ -367,14 +367,14 @@ pub type Coin = BigNum; #[wasm_bindgen] #[derive( -Clone, -Debug, -Eq, -/*Hash,*/ Ord, -PartialEq, -serde::Serialize, -serde::Deserialize, -JsonSchema, + Clone, + Debug, + Eq, + /*Hash,*/ Ord, + PartialEq, + serde::Serialize, + serde::Deserialize, + JsonSchema, )] pub struct Value { pub(crate) coin: Coin, @@ -413,10 +413,10 @@ impl Value { pub fn is_zero(&self) -> bool { self.coin.is_zero() && self - .multiasset - .as_ref() - .map(|m| m.len() == 0) - .unwrap_or(true) + .multiasset + .as_ref() + .map(|m| m.len() == 0) + .unwrap_or(true) } pub fn coin(&self) -> Coin { @@ -587,9 +587,9 @@ impl Deserialize for Value { cbor_event::Len::Len(n) => match n { 2 => /* it's ok */ - { - () - } + { + () + } n => { return Err( DeserializeFailure::DefiniteLenMismatch(n, Some(2)).into() @@ -599,9 +599,9 @@ impl Deserialize for Value { cbor_event::Len::Indefinite => match raw.special()? { CBORSpecial::Break => /* it's ok */ - { - () - } + { + () + } _ => return Err(DeserializeFailure::EndingBreakMissing.into()), }, } @@ -610,7 +610,7 @@ impl Deserialize for Value { _ => Err(DeserializeFailure::NoVariantMatched.into()), } })() - .map_err(|e| e.annotate("Value")) + .map_err(|e| e.annotate("Value")) } } @@ -671,8 +671,8 @@ impl Int { /// Returns an i32 value in case the underlying original i128 value is within the limits. /// Otherwise will just return an empty value (undefined). #[deprecated( - since = "10.0.0", - note = "Unsafe ignoring of possible boundary error and it's not clear from the function name. Use `as_i32_or_nothing`, `as_i32_or_fail`, or `to_str`" + since = "10.0.0", + note = "Unsafe ignoring of possible boundary error and it's not clear from the function name. Use `as_i32_or_nothing`, `as_i32_or_fail`, or `to_str`" )] pub fn as_i32(&self) -> Option { self.as_i32_or_nothing() @@ -736,14 +736,14 @@ impl Deserialize for Int { _ => Err(DeserializeFailure::NoVariantMatched.into()), } })() - .map_err(|e| e.annotate("Int")) + .map_err(|e| e.annotate("Int")) } } impl serde::Serialize for Int { fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, + where + S: serde::Serializer, { serializer.serialize_str(&self.to_str()) } @@ -751,8 +751,8 @@ impl serde::Serialize for Int { impl<'de> serde::de::Deserialize<'de> for Int { fn deserialize(deserializer: D) -> Result - where - D: serde::de::Deserializer<'de>, + where + D: serde::de::Deserializer<'de>, { let s = ::deserialize(deserializer)?; Self::from_str(&s).map_err(|_e| { @@ -788,7 +788,7 @@ fn read_nint(raw: &mut Deserializer) -> Result Err(cbor_event::Error::IndefiniteLenNotSupported( cbor_event::Type::NegativeInteger, ) - .into()), + .into()), cbor_event::Len::Len(v) => { raw.advance(1 + len_sz)?; Ok(-(v as i128) - 1) @@ -832,7 +832,7 @@ pub(crate) fn read_bounded_bytes( max: BOUNDED_BYTES_CHUNK_SIZE, found: bytes.len(), } - .into()); + .into()); } Ok(bytes) } @@ -859,7 +859,7 @@ pub(crate) fn read_bounded_bytes( return Err(cbor_event::Error::CustomError(String::from( "Illegal CBOR: Indefinite string found inside indefinite string", )) - .into()); + .into()); } cbor_event::Len::Len(len) => { if len as usize > BOUNDED_BYTES_CHUNK_SIZE { @@ -868,7 +868,7 @@ pub(crate) fn read_bounded_bytes( max: BOUNDED_BYTES_CHUNK_SIZE, found: len as usize, } - .into()); + .into()); } raw.advance(1 + chunk_len_sz)?; raw.as_mut_ref() @@ -895,8 +895,8 @@ impl_to_from!(BigInt); impl serde::Serialize for BigInt { fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, + where + S: serde::Serializer, { serializer.serialize_str(&self.to_str()) } @@ -904,8 +904,8 @@ impl serde::Serialize for BigInt { impl<'de> serde::de::Deserialize<'de> for BigInt { fn deserialize(deserializer: D) -> Result - where - D: serde::de::Deserializer<'de>, + where + D: serde::de::Deserializer<'de>, { let s = ::deserialize(deserializer)?; BigInt::from_str(&s).map_err(|_e| { @@ -1084,7 +1084,7 @@ impl Deserialize for BigInt { found: tag, expected: 2, } - .into()); + .into()); } } } @@ -1097,29 +1097,25 @@ impl Deserialize for BigInt { _ => return Err(DeserializeFailure::NoVariantMatched.into()), } })() - .map_err(|e| e.annotate("BigInt")) + .map_err(|e| e.annotate("BigInt")) } } impl std::convert::From for BigInt - where - T: std::convert::Into, +where + T: std::convert::Into, { fn from(x: T) -> Self { Self(x.into()) } } -impl From for BigInt - where -{ +impl From for BigInt { fn from(x: BigNum) -> Self { Self(x.0.into()) } } - - pub struct CBORReadLen { deser_len: cbor_event::Len, read: u64, @@ -1297,7 +1293,7 @@ pub fn internal_get_deposit( pool_deposit: &BigNum, // // protocol parameter key_deposit: &BigNum, // protocol parameter ) -> Result { - let certificate_refund = match &certs { + let certificate_deposit = match &certs { None => to_bignum(0), Some(certs) => certs .0 @@ -1312,13 +1308,17 @@ pub fn internal_get_deposit( } } CertificateEnum::DrepRegistration(cert) => acc.checked_add(&cert.coin), - CertificateEnum::StakeRegistrationAndDelegation(cert) => acc.checked_add(&cert.coin), + CertificateEnum::StakeRegistrationAndDelegation(cert) => { + acc.checked_add(&cert.coin) + } CertificateEnum::VoteRegistrationAndDelegation(cert) => acc.checked_add(&cert.coin), - CertificateEnum::StakeVoteRegistrationAndDelegation(cert) => acc.checked_add(&cert.coin), + CertificateEnum::StakeVoteRegistrationAndDelegation(cert) => { + acc.checked_add(&cert.coin) + } _ => Ok(acc), })?, }; - Ok(certificate_refund) + Ok(certificate_deposit) } #[wasm_bindgen] @@ -1408,14 +1408,18 @@ impl MinOutputAdaCalculator { pub fn calc_size_cost(data_cost: &DataCost, size: usize) -> Result { //according to https://hydra.iohk.io/build/15339994/download/1/babbage-changes.pdf //See on the page 9 getValue txout - to_bignum(size as u64).checked_add(&to_bignum(160))? + to_bignum(size as u64) + .checked_add(&to_bignum(160))? .checked_mul(&data_cost.coins_per_byte()) } - pub fn calc_required_coin(output: &TransactionOutput, data_cost: &DataCost) -> Result { + pub fn calc_required_coin( + output: &TransactionOutput, + data_cost: &DataCost, + ) -> Result { //according to https://hydra.iohk.io/build/15339994/download/1/babbage-changes.pdf //See on the page 9 getValue txout - Self::calc_size_cost(data_cost,output.to_bytes().len()) + Self::calc_size_cost(data_cost, output.to_bytes().len()) } } @@ -1485,32 +1489,32 @@ fn encode_wallet_value_to_native_script( ) -> Result { match value { serde_json::Value::Object(map) - if map.contains_key("cosigners") && map.contains_key("template") => - { - let mut cosigners = HashMap::new(); - - if let serde_json::Value::Object(cosigner_map) = map.get("cosigners").unwrap() { - for (key, value) in cosigner_map.iter() { - if let serde_json::Value::String(xpub) = value { - if xpub == "self" { - cosigners.insert(key.to_owned(), self_xpub.to_owned()); - } else { - cosigners.insert(key.to_owned(), xpub.to_owned()); - } + if map.contains_key("cosigners") && map.contains_key("template") => + { + let mut cosigners = HashMap::new(); + + if let serde_json::Value::Object(cosigner_map) = map.get("cosigners").unwrap() { + for (key, value) in cosigner_map.iter() { + if let serde_json::Value::String(xpub) = value { + if xpub == "self" { + cosigners.insert(key.to_owned(), self_xpub.to_owned()); } else { - return Err(JsError::from_str("cosigner value must be a string")); + cosigners.insert(key.to_owned(), xpub.to_owned()); } + } else { + return Err(JsError::from_str("cosigner value must be a string")); } - } else { - return Err(JsError::from_str("cosigners must be a map")); } + } else { + return Err(JsError::from_str("cosigners must be a map")); + } - let template = map.get("template").unwrap(); + let template = map.get("template").unwrap(); - let template_native_script = encode_template_to_native_script(template, &cosigners)?; + let template_native_script = encode_template_to_native_script(template, &cosigners)?; - Ok(template_native_script) - } + Ok(template_native_script) + } _ => Err(JsError::from_str( "top level must be an object. cosigners and template keys are required", )), @@ -1568,7 +1572,7 @@ fn encode_template_to_native_script( if let serde_json::Value::Object(some) = map.get("some").unwrap() { if some.contains_key("at_least") && some.contains_key("from") { let n = if let serde_json::Value::Number(at_least) = - some.get("at_least").unwrap() + some.get("at_least").unwrap() { if let Some(n) = at_least.as_u64() { n as u32 @@ -1651,30 +1655,48 @@ impl Display for ValueShortage { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "shortage: {{")?; if let Some((input_data, out_data, fee)) = self.ada_shortage { - writeln!(f, "ada in inputs: {}, ada in outputs: {}, fee {}", input_data, out_data, fee)?; + writeln!( + f, + "ada in inputs: {}, ada in outputs: {}, fee {}", + input_data, out_data, fee + )?; writeln!(f, "NOTE! \"ada in inputs\" must be >= (\"ada in outputs\" + fee) before adding change")?; - writeln!(f, "and \"ada in inputs\" must be == (\"ada in outputs\" + fee) after adding change")?; - } - for (policy_id, asset_name, asset_shortage, asset_available) in - &self.asset_shortage - { - write!(f, "policy id: \"{}\", asset name: \"{}\" ", policy_id, asset_name)?; - writeln!(f, "coins in inputs: {}, coins in outputs: {}", asset_shortage, asset_available)?; + writeln!( + f, + "and \"ada in inputs\" must be == (\"ada in outputs\" + fee) after adding change" + )?; + } + for (policy_id, asset_name, asset_shortage, asset_available) in &self.asset_shortage { + write!( + f, + "policy id: \"{}\", asset name: \"{}\" ", + policy_id, asset_name + )?; + writeln!( + f, + "coins in inputs: {}, coins in outputs: {}", + asset_shortage, asset_available + )?; } write!(f, " }}") } } -pub(crate) fn get_input_shortage(all_inputs_value: &Value, all_outputs_value: &Value, fee: &Coin) - -> Result, JsError> { - let mut shortage = ValueShortage{ +pub(crate) fn get_input_shortage( + all_inputs_value: &Value, + all_outputs_value: &Value, + fee: &Coin, +) -> Result, JsError> { + let mut shortage = ValueShortage { ada_shortage: None, - asset_shortage: Vec::new()}; + asset_shortage: Vec::new(), + }; if all_inputs_value.coin < all_outputs_value.coin.checked_add(fee)? { shortage.ada_shortage = Some(( all_inputs_value.coin.clone(), all_outputs_value.coin.clone(), - fee.clone())); + fee.clone(), + )); } if let Some(policies) = &all_outputs_value.multiasset { @@ -1682,11 +1704,16 @@ pub(crate) fn get_input_shortage(all_inputs_value: &Value, all_outputs_value: &V for (asset_name, coins) in &assets.0 { let inputs_coins = match &all_inputs_value.multiasset { Some(multiasset) => multiasset.get_asset(policy_id, asset_name), - None => Coin::zero() + None => Coin::zero(), }; if inputs_coins < *coins { - shortage.asset_shortage.push((policy_id.clone(), asset_name.clone(), inputs_coins, coins.clone())); + shortage.asset_shortage.push(( + policy_id.clone(), + asset_name.clone(), + inputs_coins, + coins.clone(), + )); } } } @@ -1702,7 +1729,7 @@ pub(crate) fn get_input_shortage(all_inputs_value: &Value, all_outputs_value: &V #[cfg(test)] mod tests { use super::*; - use crate::tx_builder_constants::TxBuilderConstants; + use crate::TxBuilderConstants; // this is what is used in mainnet const COINS_PER_UTXO_WORD: u64 = 34_482; @@ -1811,7 +1838,7 @@ mod tests { false, &to_bignum(COINS_PER_UTXO_WORD), ) - .unwrap() + .unwrap() ), 969750, ); @@ -1826,7 +1853,7 @@ mod tests { false, &to_bignum(COINS_PER_UTXO_WORD), ) - .unwrap() + .unwrap() ), 1_120_600, ); @@ -1841,7 +1868,7 @@ mod tests { false, &to_bignum(COINS_PER_UTXO_WORD), ) - .unwrap() + .unwrap() ), 1_124_910, ); @@ -1856,7 +1883,7 @@ mod tests { false, &to_bignum(COINS_PER_UTXO_WORD), ) - .unwrap() + .unwrap() ), 1_150_770, ); @@ -1871,7 +1898,7 @@ mod tests { false, &to_bignum(COINS_PER_UTXO_WORD), ) - .unwrap() + .unwrap() ), 1_262_830, ); @@ -1886,7 +1913,7 @@ mod tests { false, &to_bignum(COINS_PER_UTXO_WORD), ) - .unwrap() + .unwrap() ), 1_271_450, ); @@ -1901,7 +1928,7 @@ mod tests { false, &to_bignum(COINS_PER_UTXO_WORD), ) - .unwrap() + .unwrap() ), 2_633_410, ); @@ -1916,7 +1943,7 @@ mod tests { true, &to_bignum(COINS_PER_UTXO_WORD), ) - .unwrap() + .unwrap() ), 1_267_140, ); @@ -1931,7 +1958,7 @@ mod tests { true, &to_bignum(COINS_PER_UTXO_WORD), ) - .unwrap() + .unwrap() ), 1_711_070, ); @@ -1946,7 +1973,7 @@ mod tests { true, &to_bignum(COINS_PER_UTXO_WORD), ) - .unwrap() + .unwrap() ), 1_409_370, ); @@ -2405,7 +2432,7 @@ mod tests { 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 51, 13, 167, 1, 1, 255, ]) - .unwrap(); + .unwrap(); let mut cost_models = Costmdls::new(); cost_models.insert(&Language::new_plutus_v1(), &plutus_cost_model); let script_data_hash = hash_script_data(&redeemers, &cost_models, Some(datums)); @@ -2633,35 +2660,35 @@ mod tests { #[test] fn test_bigint_add() { - assert_eq!(to_bigint(10).add(&to_bigint(20)), to_bigint(30), ); - assert_eq!(to_bigint(500).add(&to_bigint(800)), to_bigint(1300), ); + assert_eq!(to_bigint(10).add(&to_bigint(20)), to_bigint(30),); + assert_eq!(to_bigint(500).add(&to_bigint(800)), to_bigint(1300),); } #[test] fn test_bigint_mul() { - assert_eq!(to_bigint(10).mul(&to_bigint(20)), to_bigint(200), ); - assert_eq!(to_bigint(500).mul(&to_bigint(800)), to_bigint(400000), ); - assert_eq!(to_bigint(12).mul(&to_bigint(22)), to_bigint(264), ); + assert_eq!(to_bigint(10).mul(&to_bigint(20)), to_bigint(200),); + assert_eq!(to_bigint(500).mul(&to_bigint(800)), to_bigint(400000),); + assert_eq!(to_bigint(12).mul(&to_bigint(22)), to_bigint(264),); } #[test] fn test_bigint_div_ceil() { - assert_eq!(to_bigint(20).div_ceil(&to_bigint(10)), to_bigint(2), ); - assert_eq!(to_bigint(20).div_ceil(&to_bigint(2)), to_bigint(10), ); - assert_eq!(to_bigint(21).div_ceil(&to_bigint(2)), to_bigint(11), ); - assert_eq!(to_bigint(6).div_ceil(&to_bigint(3)), to_bigint(2), ); - assert_eq!(to_bigint(5).div_ceil(&to_bigint(3)), to_bigint(2), ); - assert_eq!(to_bigint(7).div_ceil(&to_bigint(3)), to_bigint(3), ); + assert_eq!(to_bigint(20).div_ceil(&to_bigint(10)), to_bigint(2),); + assert_eq!(to_bigint(20).div_ceil(&to_bigint(2)), to_bigint(10),); + assert_eq!(to_bigint(21).div_ceil(&to_bigint(2)), to_bigint(11),); + assert_eq!(to_bigint(6).div_ceil(&to_bigint(3)), to_bigint(2),); + assert_eq!(to_bigint(5).div_ceil(&to_bigint(3)), to_bigint(2),); + assert_eq!(to_bigint(7).div_ceil(&to_bigint(3)), to_bigint(3),); } #[test] fn test_bignum_div() { - assert_eq!(to_bignum(10).div_floor(&to_bignum(1)), to_bignum(10), ); - assert_eq!(to_bignum(10).div_floor(&to_bignum(3)), to_bignum(3), ); - assert_eq!(to_bignum(10).div_floor(&to_bignum(4)), to_bignum(2), ); - assert_eq!(to_bignum(10).div_floor(&to_bignum(5)), to_bignum(2), ); - assert_eq!(to_bignum(10).div_floor(&to_bignum(6)), to_bignum(1), ); - assert_eq!(to_bignum(10).div_floor(&to_bignum(12)), to_bignum(0), ); + assert_eq!(to_bignum(10).div_floor(&to_bignum(1)), to_bignum(10),); + assert_eq!(to_bignum(10).div_floor(&to_bignum(3)), to_bignum(3),); + assert_eq!(to_bignum(10).div_floor(&to_bignum(4)), to_bignum(2),); + assert_eq!(to_bignum(10).div_floor(&to_bignum(5)), to_bignum(2),); + assert_eq!(to_bignum(10).div_floor(&to_bignum(6)), to_bignum(1),); + assert_eq!(to_bignum(10).div_floor(&to_bignum(12)), to_bignum(0),); } #[test] From 0f4e33328f9c48af1ef0e1458df145f9ef7ed372 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 8 Sep 2023 21:25:07 +0500 Subject: [PATCH 121/349] move builders + fmt --- .../certificates_builder.rs | 1 - .../{tx_builder => builders}/mint_builder.rs | 120 ++++---- rust/src/builders/mod.rs | 34 +++ rust/src/{ => builders}/output_builder.rs | 4 +- .../script_structs.rs | 0 .../tx_batch_builder.rs | 39 ++- rust/src/{ => builders}/tx_builder.rs | 262 ++++++++++-------- .../{ => builders}/tx_builder_constants.rs | 191 +------------ .../tx_inputs_builder.rs | 164 +++++++---- .../withdrawals_builder.rs | 1 - 10 files changed, 405 insertions(+), 411 deletions(-) rename rust/src/{tx_builder => builders}/certificates_builder.rs (99%) rename rust/src/{tx_builder => builders}/mint_builder.rs (71%) create mode 100644 rust/src/builders/mod.rs rename rust/src/{ => builders}/output_builder.rs (98%) rename rust/src/{tx_builder => builders}/script_structs.rs (100%) rename rust/src/{tx_builder => builders}/tx_batch_builder.rs (70%) rename rust/src/{ => builders}/tx_builder.rs (94%) rename rust/src/{ => builders}/tx_builder_constants.rs (65%) rename rust/src/{tx_builder => builders}/tx_inputs_builder.rs (80%) rename rust/src/{tx_builder => builders}/withdrawals_builder.rs (99%) diff --git a/rust/src/tx_builder/certificates_builder.rs b/rust/src/builders/certificates_builder.rs similarity index 99% rename from rust/src/tx_builder/certificates_builder.rs rename to rust/src/builders/certificates_builder.rs index e7728f1d..f9053ca8 100644 --- a/rust/src/tx_builder/certificates_builder.rs +++ b/rust/src/builders/certificates_builder.rs @@ -1,4 +1,3 @@ -use crate::tx_builder::script_structs::*; use crate::*; #[wasm_bindgen] diff --git a/rust/src/tx_builder/mint_builder.rs b/rust/src/builders/mint_builder.rs similarity index 71% rename from rust/src/tx_builder/mint_builder.rs rename to rust/src/builders/mint_builder.rs index 67d11d59..17658bbf 100644 --- a/rust/src/tx_builder/mint_builder.rs +++ b/rust/src/builders/mint_builder.rs @@ -1,7 +1,6 @@ -use super::*; use crate::plutus::Redeemer; -use crate::tx_builder::script_structs::PlutusScriptSourceEnum; -use crate::tx_builder::script_structs::PlutusScriptSource; +use crate::*; +use std::collections::BTreeMap; #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] enum MintWitnessEnum { @@ -19,15 +18,21 @@ impl MintWitness { MintWitness(MintWitnessEnum::NativeScript(native_script.clone())) } - pub fn new_plutus_script(plutus_script: &PlutusScriptSource, redeemer: &Redeemer) -> MintWitness { - MintWitness(MintWitnessEnum::Plutus(plutus_script.0.clone(), redeemer.clone())) + pub fn new_plutus_script( + plutus_script: &PlutusScriptSource, + redeemer: &Redeemer, + ) -> MintWitness { + MintWitness(MintWitnessEnum::Plutus( + plutus_script.0.clone(), + redeemer.clone(), + )) } } #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] struct NativeMints { script: NativeScript, - mints: BTreeMap + mints: BTreeMap, } #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] @@ -45,7 +50,7 @@ enum ScriptMint { #[derive(Clone, Debug)] #[wasm_bindgen] pub struct MintBuilder { - mints: BTreeMap + mints: BTreeMap, } #[wasm_bindgen] @@ -64,43 +69,63 @@ impl MintBuilder { self.update_mint_value(mint, asset_name, amount, true); } - fn update_mint_value(&mut self, mint: &MintWitness, asset_name: &AssetName, amount: &Int, overwrite: bool) { + fn update_mint_value( + &mut self, + mint: &MintWitness, + asset_name: &AssetName, + amount: &Int, + overwrite: bool, + ) { match &mint.0 { MintWitnessEnum::NativeScript(native_script) => { - let script_mint = self.mints.entry(native_script.hash()).or_insert(ScriptMint::Native(NativeMints { - script: native_script.clone(), - mints: BTreeMap::new(), - })); + let script_mint = + self.mints + .entry(native_script.hash()) + .or_insert(ScriptMint::Native(NativeMints { + script: native_script.clone(), + mints: BTreeMap::new(), + })); match script_mint { ScriptMint::Native(native_mints) => { - let mint = native_mints.mints.entry(asset_name.clone()).or_insert(Int::new(&BigNum::zero())); + let mint = native_mints + .mints + .entry(asset_name.clone()) + .or_insert(Int::new(&BigNum::zero())); if overwrite { mint.0 = amount.0; } else { mint.0 += amount.0; } - }, - _ => {}, + } + _ => {} } - }, + } MintWitnessEnum::Plutus(plutus_script, redeemer) => { - let script_mint = self.mints.entry(plutus_script.script_hash()).or_insert(ScriptMint::Plutus(PlutusMints { - script: plutus_script.clone(), - redeemer_mints: BTreeMap::new(), - })); + let script_mint = + self.mints + .entry(plutus_script.script_hash()) + .or_insert(ScriptMint::Plutus(PlutusMints { + script: plutus_script.clone(), + redeemer_mints: BTreeMap::new(), + })); match script_mint { ScriptMint::Plutus(plutus_mints) => { - let redeemer_mints = plutus_mints.redeemer_mints.entry(redeemer.clone()).or_insert(BTreeMap::new()); - let mint = redeemer_mints.entry(asset_name.clone()).or_insert(Int::new(&BigNum::zero())); + let redeemer_mints = plutus_mints + .redeemer_mints + .entry(redeemer.clone()) + .or_insert(BTreeMap::new()); + let mint = redeemer_mints + .entry(asset_name.clone()) + .or_insert(Int::new(&BigNum::zero())); if overwrite { mint.0 = amount.0; } else { mint.0 += amount.0; } - }, - _ => {}, + } + _ => {} } - }, + } } } @@ -114,13 +139,12 @@ impl MintBuilder { mint_asset.insert(asset_name, amount.clone()); } mint.insert(&native_mints.script.hash(), &mint_asset); - }, + } ScriptMint::Plutus(plutus_mints) => { for (_, redeemer_mints) in &plutus_mints.redeemer_mints { let mut mint_asset = MintAssets::new(); for (asset_name, amount) in redeemer_mints { mint_asset.insert(asset_name, amount.clone()); - } mint.insert(&plutus_mints.script.script_hash(), &mint_asset); } @@ -136,8 +160,8 @@ impl MintBuilder { match script_mint { ScriptMint::Native(native_mints) => { native_scripts.push(native_mints.script.clone()); - }, - _ => {}, + } + _ => {} } } NativeScripts(native_scripts) @@ -149,14 +173,13 @@ impl MintBuilder { match script_mint { ScriptMint::Plutus(plutus_mints) => { for (redeemer, _) in &plutus_mints.redeemer_mints { - plutus_witnesses.push( - PlutusWitness::new_with_ref_without_datum( - &PlutusScriptSource(plutus_mints.script.clone()), - redeemer) - ); + plutus_witnesses.push(PlutusWitness::new_with_ref_without_datum( + &PlutusScriptSource(plutus_mints.script.clone()), + redeemer, + )); } - }, - _ => {}, + } + _ => {} } } PlutusWitnesses(plutus_witnesses) @@ -167,11 +190,12 @@ impl MintBuilder { for script_mint in self.mints.values() { match script_mint { ScriptMint::Plutus(plutus_mints) => { - if let PlutusScriptSourceEnum::RefInput(ref_input, _, _) = &plutus_mints.script { + if let PlutusScriptSourceEnum::RefInput(ref_input, _, _) = &plutus_mints.script + { reference_inputs.push(ref_input.clone()); } - }, - _ => {}, + } + _ => {} } } TransactionInputs(reference_inputs) @@ -188,10 +212,10 @@ impl MintBuilder { redeeemers.push(redeemer.clone_with_index_and_tag(&index, &tag)); index = index.checked_add(&BigNum::one())?; } - }, + } _ => { index = index.checked_add(&BigNum::one())?; - }, + } } } Ok(Redeemers(redeeemers)) @@ -202,8 +226,8 @@ impl MintBuilder { match script_mint { ScriptMint::Plutus(_) => { return true; - }, - _ => {}, + } + _ => {} } } false @@ -214,8 +238,8 @@ impl MintBuilder { match script_mint { ScriptMint::Native(_) => { return true; - }, - _ => {}, + } + _ => {} } } false @@ -229,10 +253,10 @@ impl MintBuilder { if let Some(lang) = plutus_mints.script.language() { used_langs.insert(lang); } - }, - _ => {}, + } + _ => {} } } used_langs } -} \ No newline at end of file +} diff --git a/rust/src/builders/mod.rs b/rust/src/builders/mod.rs new file mode 100644 index 00000000..7b2810dc --- /dev/null +++ b/rust/src/builders/mod.rs @@ -0,0 +1,34 @@ +pub(crate) mod batch_tools; + +mod certificates_builder; +pub use certificates_builder::*; + +mod mint_builder; +pub use mint_builder::*; + +mod script_structs; +pub use script_structs::*; + +mod tx_batch_builder; +pub use tx_batch_builder::*; + +mod tx_inputs_builder; +pub use tx_inputs_builder::*; + +mod voting_builder; +pub use voting_builder::*; + +mod voting_proposal_builder; +pub use voting_proposal_builder::*; + +mod withdrawals_builder; +pub use withdrawals_builder::*; + +mod output_builder; +pub use output_builder::*; + +mod tx_builder; +pub use tx_builder::*; + +mod tx_builder_constants; +pub use tx_builder_constants::*; diff --git a/rust/src/output_builder.rs b/rust/src/builders/output_builder.rs similarity index 98% rename from rust/src/output_builder.rs rename to rust/src/builders/output_builder.rs index a8bc7696..72ccc796 100644 --- a/rust/src/output_builder.rs +++ b/rust/src/builders/output_builder.rs @@ -1,4 +1,4 @@ -use super::*; +use crate::*; /// We introduce a builder-pattern format for creating transaction outputs /// This is because: @@ -152,7 +152,7 @@ impl TransactionOutputAmountBuilder { ))?, plutus_data: self.data.clone(), script_ref: self.script_ref.clone(), - serialization_format: None + serialization_format: None, }) } } diff --git a/rust/src/tx_builder/script_structs.rs b/rust/src/builders/script_structs.rs similarity index 100% rename from rust/src/tx_builder/script_structs.rs rename to rust/src/builders/script_structs.rs diff --git a/rust/src/tx_builder/tx_batch_builder.rs b/rust/src/builders/tx_batch_builder.rs similarity index 70% rename from rust/src/tx_builder/tx_batch_builder.rs rename to rust/src/builders/tx_batch_builder.rs index a419972d..049511e2 100644 --- a/rust/src/tx_builder/tx_batch_builder.rs +++ b/rust/src/builders/tx_batch_builder.rs @@ -1,6 +1,6 @@ -use batch_tools::proposals::{TxProposal}; -use batch_tools::asset_categorizer::{AssetCategorizer}; -use super::*; +use crate::*; +use batch_tools::asset_categorizer::AssetCategorizer; +use batch_tools::proposals::TxProposal; #[wasm_bindgen] pub struct TransactionBatchList(Vec); @@ -18,7 +18,7 @@ impl TransactionBatchList { impl<'a> IntoIterator for &'a TransactionBatchList { type Item = &'a TransactionBatch; - type IntoIter = std::slice::Iter<'a, TransactionBatch>; + type IntoIter = std::slice::Iter<'a, TransactionBatch>; fn into_iter(self) -> std::slice::Iter<'a, TransactionBatch> { self.0.iter() @@ -69,7 +69,11 @@ struct TxBatchBuilder { } impl TxBatchBuilder { - pub fn new(utxos: &TransactionUnspentOutputs, address: &Address, config: &TransactionBuilderConfig) -> Result { + pub fn new( + utxos: &TransactionUnspentOutputs, + address: &Address, + config: &TransactionBuilderConfig, + ) -> Result { let asset_groups = AssetCategorizer::new(config, utxos, address)?; Ok(Self { asset_groups, @@ -77,19 +81,28 @@ impl TxBatchBuilder { }) } - pub fn build(&mut self, utxos: &TransactionUnspentOutputs) -> Result { + pub fn build( + &mut self, + utxos: &TransactionUnspentOutputs, + ) -> Result { while self.asset_groups.has_assets() || self.asset_groups.has_ada() { let mut current_tx_proposal = TxProposal::new(); - while let Some(tx_proposal) = self.asset_groups.try_append_next_utxos(¤t_tx_proposal)? { + while let Some(tx_proposal) = self + .asset_groups + .try_append_next_utxos(¤t_tx_proposal)? + { current_tx_proposal = tx_proposal; } - if current_tx_proposal.is_empty() && (self.asset_groups.has_assets() || self.asset_groups.has_ada()) { + if current_tx_proposal.is_empty() + && (self.asset_groups.has_assets() || self.asset_groups.has_ada()) + { return Err(JsError::from_str("Unable to build transaction batch")); } current_tx_proposal.add_last_ada_to_last_output()?; - self.asset_groups.set_min_ada_for_tx(&mut current_tx_proposal)?; + self.asset_groups + .set_min_ada_for_tx(&mut current_tx_proposal)?; self.tx_proposals.push(current_tx_proposal); } @@ -103,10 +116,12 @@ impl TxBatchBuilder { } #[wasm_bindgen] -pub fn create_send_all(address: &Address, utxos: &TransactionUnspentOutputs, config: &TransactionBuilderConfig) - -> Result { +pub fn create_send_all( + address: &Address, + utxos: &TransactionUnspentOutputs, + config: &TransactionBuilderConfig, +) -> Result { let mut tx_batch_builder = TxBatchBuilder::new(utxos, address, config)?; let batch = tx_batch_builder.build(utxos)?; Ok(TransactionBatchList(vec![batch])) } - diff --git a/rust/src/tx_builder.rs b/rust/src/builders/tx_builder.rs similarity index 94% rename from rust/src/tx_builder.rs rename to rust/src/builders/tx_builder.rs index bd889f37..f65548ac 100644 --- a/rust/src/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -1,29 +1,11 @@ #![allow(deprecated)] -pub mod tx_inputs_builder; -pub mod tx_batch_builder; -pub mod mint_builder; -pub mod certificates_builder; -pub mod withdrawals_builder; -pub mod voting_proposal_builder; -pub mod voting_builder; -mod batch_tools; -pub(crate) mod script_structs; - - -use super::fees; -use super::output_builder::TransactionOutputAmountBuilder; -use super::utils; +use crate::*; + use super::*; -use crate::tx_builder::tx_inputs_builder::{get_bootstraps, TxInputsBuilder}; -use linked_hash_map::LinkedHashMap; +use crate::fees; +use crate::utils; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; -use crate::tx_builder::certificates_builder::CertificatesBuilder; -use crate::tx_builder::withdrawals_builder::WithdrawalsBuilder; -use crate::tx_builder::script_structs::{PlutusWitness, PlutusWitnesses}; -use crate::tx_builder::mint_builder::{MintBuilder, MintWitness}; -use crate::tx_builder::voting_builder::VotingBuilder; -use crate::tx_builder::voting_proposal_builder::VotingProposalBuilder; pub(crate) fn fake_private_key() -> Bip32PrivateKey { Bip32PrivateKey::from_bytes(&[ @@ -199,12 +181,12 @@ pub enum CoinSelectionStrategyCIP2 { #[derive(Clone, Debug)] pub struct TransactionBuilderConfig { pub(crate) fee_algo: fees::LinearFee, - pub(crate) pool_deposit: Coin, // protocol parameter - pub(crate) key_deposit: Coin, // protocol parameter - pub(crate) voting_proposal_deposit: Coin, // protocol parameter - pub(crate) max_value_size: u32, // protocol parameter - pub(crate) max_tx_size: u32, // protocol parameter - pub(crate) data_cost: DataCost, // protocol parameter + pub(crate) pool_deposit: Coin, // protocol parameter + pub(crate) key_deposit: Coin, // protocol parameter + pub(crate) voting_proposal_deposit: Coin, // protocol parameter + pub(crate) max_value_size: u32, // protocol parameter + pub(crate) max_tx_size: u32, // protocol parameter + pub(crate) data_cost: DataCost, // protocol parameter pub(crate) ex_unit_prices: Option, // protocol parameter pub(crate) prefer_pure_change: bool, } @@ -219,13 +201,13 @@ impl TransactionBuilderConfig { #[derive(Clone, Debug)] pub struct TransactionBuilderConfigBuilder { fee_algo: Option, - pool_deposit: Option, // protocol parameter - key_deposit: Option, // protocol parameter + pool_deposit: Option, // protocol parameter + key_deposit: Option, // protocol parameter voting_proposal_deposit: Option, // protocol parameter - max_value_size: Option, // protocol parameter - max_tx_size: Option, // protocol parameter - data_cost: Option, // protocol parameter - ex_unit_prices: Option, // protocol parameter + max_value_size: Option, // protocol parameter + max_tx_size: Option, // protocol parameter + data_cost: Option, // protocol parameter + ex_unit_prices: Option, // protocol parameter prefer_pure_change: bool, } @@ -320,9 +302,7 @@ impl TransactionBuilderConfigBuilder { pool_deposit: cfg .pool_deposit .ok_or(JsError::from_str("uninitialized field: pool_deposit"))?, - voting_proposal_deposit: cfg - .voting_proposal_deposit - .ok_or(JsError::from_str( + voting_proposal_deposit: cfg.voting_proposal_deposit.ok_or(JsError::from_str( "uninitialized field: voting_proposal_deposit", ))?, key_deposit: cfg @@ -675,8 +655,11 @@ impl TransactionBuilder { if let Some(associated) = associated_indices.get(output) { for i in associated.iter() { let input = &available_inputs[*i]; - let input_fee = - self.fee_for_input(&input.output.address, &input.input, &input.output.amount)?; + let input_fee = self.fee_for_input( + &input.output.address, + &input.input, + &input.output.amount, + )?; self.add_input(&input.output.address, &input.input, &input.output.amount); *input_total = input_total.checked_add(&input.output.amount)?; *output_total = output_total.checked_add(&Value::new(&input_fee))?; @@ -849,7 +832,10 @@ impl TransactionBuilder { /// Returns the number of still missing input scripts (either native or plutus) /// Use `.add_required_native_input_scripts` or `.add_required_plutus_input_scripts` to add the missing scripts - #[deprecated(since = "10.2.0", note = "Use `.count_missing_input_scripts` from `TxInputsBuilder`")] + #[deprecated( + since = "10.2.0", + note = "Use `.count_missing_input_scripts` from `TxInputsBuilder`" + )] pub fn count_missing_input_scripts(&self) -> usize { self.inputs.count_missing_input_scripts() } @@ -1005,9 +991,9 @@ impl TransactionBuilder { since = "11.4.1", note = "Can emit an error if you add a withdrawal with script credential. Use set_withdrawals_builder instead." )] - pub fn set_withdrawals(&mut self, withdrawals: &Withdrawals) -> Result<(), JsError>{ + pub fn set_withdrawals(&mut self, withdrawals: &Withdrawals) -> Result<(), JsError> { let mut withdrawals_builder = WithdrawalsBuilder::new(); - for(withdrawal, coin) in &withdrawals.0 { + for (withdrawal, coin) in &withdrawals.0 { withdrawals_builder.add(&withdrawal, &coin)?; } @@ -1098,8 +1084,8 @@ impl TransactionBuilder { /// Mints are defining by MintBuilder now. /// Use `.set_mint_builder()` and `MintBuilder` instead. #[deprecated( - since = "11.2.0", - note = "Mints are defining by MintBuilder now. Use `.set_mint_builder()` and `MintBuilder` instead." + since = "11.2.0", + note = "Mints are defining by MintBuilder now. Use `.set_mint_builder()` and `MintBuilder` instead." )] /// Set explicit Mint object and the required witnesses to this builder /// it will replace any previously existing mint and mint scripts @@ -1119,9 +1105,10 @@ impl TransactionBuilder { let mint_witness = MintWitness::new_native_script(script); mint_builder.set_asset(&mint_witness, asset_name, amount); } else { - return Err(JsError::from_str("Mint policy does not have a matching script")); + return Err(JsError::from_str( + "Mint policy does not have a matching script", + )); } - } } self.mint = Some(mint_builder); @@ -1132,8 +1119,8 @@ impl TransactionBuilder { /// Mints are defining by MintBuilder now. /// Use `.get_mint_builder()` and `.build()` instead. #[deprecated( - since = "11.2.0", - note = "Mints are defining by MintBuilder now. Use `.get_mint_builder()` and `.build()` instead." + since = "11.2.0", + note = "Mints are defining by MintBuilder now. Use `.get_mint_builder()` and `.build()` instead." )] /// Returns a copy of the current mint state in the builder pub fn get_mint(&self) -> Option { @@ -1155,8 +1142,8 @@ impl TransactionBuilder { /// Mints are defining by MintBuilder now. /// Use `.set_mint_builder()` and `MintBuilder` instead. #[deprecated( - since = "11.2.0", - note = "Mints are defining by MintBuilder now. Use `.set_mint_builder()` and `MintBuilder` instead." + since = "11.2.0", + note = "Mints are defining by MintBuilder now. Use `.set_mint_builder()` and `MintBuilder` instead." )] /// Add a mint entry to this builder using a PolicyID and MintAssets object /// It will be securely added to existing or new Mint in this builder @@ -1180,8 +1167,8 @@ impl TransactionBuilder { /// Mints are defining by MintBuilder now. /// Use `.set_mint_builder()` and `MintBuilder` instead. #[deprecated( - since = "11.2.0", - note = "Mints are defining by MintBuilder now. Use `.set_mint_builder()` and `MintBuilder` instead." + since = "11.2.0", + note = "Mints are defining by MintBuilder now. Use `.set_mint_builder()` and `MintBuilder` instead." )] /// Add a mint entry to this builder using a PolicyID, AssetName, and Int object for amount /// It will be securely added to existing or new Mint in this builder @@ -1196,7 +1183,7 @@ impl TransactionBuilder { if let Some(mint) = &mut self.mint { mint.add_asset(&mint_witness, asset_name, &amount); } else { - let mut mint = MintBuilder::new(); + let mut mint = MintBuilder::new(); mint.add_asset(&mint_witness, asset_name, &amount); self.mint = Some(mint); } @@ -1359,10 +1346,10 @@ impl TransactionBuilder { implicit_input = implicit_input.checked_add(&withdrawals.get_total_withdrawals()?)?; } if let Some(refunds) = &self.certs { - implicit_input = implicit_input.checked_add(&refunds.get_certificates_refund( - &self.config.pool_deposit, - &self.config.key_deposit - )?)?; + implicit_input = implicit_input.checked_add( + &refunds + .get_certificates_refund(&self.config.pool_deposit, &self.config.key_deposit)?, + )?; } Ok(implicit_input) @@ -1410,19 +1397,16 @@ impl TransactionBuilder { pub fn get_deposit(&self) -> Result { let mut total_deposit = Coin::zero(); if let Some(certs) = &self.certs { - total_deposit = total_deposit.checked_add( - &certs.get_certificates_deposit( + total_deposit = + total_deposit.checked_add(&certs.get_certificates_deposit( &self.config.pool_deposit, &self.config.key_deposit, - )?, - )?; + )?)?; } if let Some(voting_proposal_builder) = &self.voting_proposals { total_deposit = total_deposit.checked_add( - &voting_proposal_builder.get_total_deposit( - &self.config.voting_proposal_deposit, - )?, + &voting_proposal_builder.get_total_deposit(&self.config.voting_proposal_deposit)?, )?; } @@ -1441,23 +1425,24 @@ impl TransactionBuilder { self.add_change_if_needed_with_optional_script_and_datum(address, None, None) } - pub fn add_change_if_needed_with_datum(&mut self, - address: &Address, - plutus_data: &OutputDatum) - -> Result - { + pub fn add_change_if_needed_with_datum( + &mut self, + address: &Address, + plutus_data: &OutputDatum, + ) -> Result { self.add_change_if_needed_with_optional_script_and_datum( address, Some(plutus_data.0.clone()), - None) + None, + ) } - - fn add_change_if_needed_with_optional_script_and_datum(&mut self, address: &Address, - plutus_data: Option, - script_ref: Option) - -> Result - { + fn add_change_if_needed_with_optional_script_and_datum( + &mut self, + address: &Address, + plutus_data: Option, + script_ref: Option, + ) -> Result { let fee = match &self.fee { None => self.min_fee(), // generating the change output involves changing the fee @@ -1473,7 +1458,10 @@ impl TransactionBuilder { let shortage = get_input_shortage(&input_total, &output_total, &fee)?; if let Some(shortage) = shortage { - return Err(JsError::from_str(&format!("Insufficient input in transaction. {}", shortage))); + return Err(JsError::from_str(&format!( + "Insufficient input in transaction. {}", + shortage + ))); } use std::cmp::Ordering; @@ -1807,7 +1795,6 @@ impl TransactionBuilder { } } - /// This method will calculate the script hash data /// using the plutus datums and redeemers already present in the builder /// along with the provided cost model, and will register the calculated value @@ -1831,24 +1818,34 @@ impl TransactionBuilder { } if let Some(mint_builder) = &self.mint { used_langs.append(&mut mint_builder.get_used_plutus_lang_versions()); - plutus_witnesses.0.append(&mut mint_builder.get_plutus_witnesses().0) + plutus_witnesses + .0 + .append(&mut mint_builder.get_plutus_witnesses().0) } if let Some(certs_builder) = &self.certs { used_langs.append(&mut certs_builder.get_used_plutus_lang_versions()); - plutus_witnesses.0.append(&mut certs_builder.get_plutus_witnesses().0) + plutus_witnesses + .0 + .append(&mut certs_builder.get_plutus_witnesses().0) } if let Some(withdrawals_builder) = &self.withdrawals { used_langs.append(&mut withdrawals_builder.get_used_plutus_lang_versions()); - plutus_witnesses.0.append(&mut withdrawals_builder.get_plutus_witnesses().0) + plutus_witnesses + .0 + .append(&mut withdrawals_builder.get_plutus_witnesses().0) } if let Some(voting_builder) = &self.voting_procedures { used_langs.append(&mut voting_builder.get_used_plutus_lang_versions()); - plutus_witnesses.0.append(&mut voting_builder.get_plutus_witnesses().0) + plutus_witnesses + .0 + .append(&mut voting_builder.get_plutus_witnesses().0) } if let Some(voting_proposal_builder) = &self.voting_proposals { used_langs.append(&mut voting_proposal_builder.get_used_plutus_lang_versions()); - plutus_witnesses.0.append(&mut voting_proposal_builder.get_plutus_witnesses().0) + plutus_witnesses + .0 + .append(&mut voting_proposal_builder.get_plutus_witnesses().0) } let (_scripts, mut datums, redeemers) = plutus_witnesses.collect(); @@ -1879,11 +1876,8 @@ impl TransactionBuilder { } if datums.is_some() || redeemers.len() > 0 || retained_cost_models.len() > 0 { - self.script_data_hash = Some(hash_script_data( - &redeemers, - &retained_cost_models, - datums, - )); + self.script_data_hash = + Some(hash_script_data(&redeemers, &retained_cost_models, datums)); } Ok(()) @@ -1919,7 +1913,10 @@ impl TransactionBuilder { certs: self.certs.as_ref().map(|x| x.build()), withdrawals: self.withdrawals.as_ref().map(|x| x.build()), update: None, - auxiliary_data_hash: self.auxiliary_data.as_ref().map(|x| utils::hash_auxiliary_data(x)), + auxiliary_data_hash: self + .auxiliary_data + .as_ref() + .map(|x| utils::hash_auxiliary_data(x)), validity_start_interval: self.validity_start_interval, mint: self.mint.as_ref().map(|x| x.build()), script_data_hash: self.script_data_hash.clone(), @@ -1979,14 +1976,22 @@ impl TransactionBuilder { }); } if let Some(certificates_builder) = &self.certs { - certificates_builder.get_native_scripts().0.iter().for_each(|s| { - ns.add(s); - }); + certificates_builder + .get_native_scripts() + .0 + .iter() + .for_each(|s| { + ns.add(s); + }); } if let Some(withdrawals_builder) = &self.withdrawals { - withdrawals_builder.get_native_scripts().0.iter().for_each(|s| { - ns.add(s); - }); + withdrawals_builder + .get_native_scripts() + .0 + .iter() + .for_each(|s| { + ns.add(s); + }); } if let Some(voting_builder) = &self.voting_procedures { voting_builder.get_native_scripts().0.iter().for_each(|s| { @@ -2019,24 +2024,40 @@ impl TransactionBuilder { }) } if let Some(certificates_builder) = &self.certs { - certificates_builder.get_plutus_witnesses().0.iter().for_each(|s| { - res.add(s); - }) + certificates_builder + .get_plutus_witnesses() + .0 + .iter() + .for_each(|s| { + res.add(s); + }) } if let Some(withdrawals_builder) = &self.withdrawals { - withdrawals_builder.get_plutus_witnesses().0.iter().for_each(|s| { - res.add(s); - }) + withdrawals_builder + .get_plutus_witnesses() + .0 + .iter() + .for_each(|s| { + res.add(s); + }) } if let Some(voting_builder) = &self.voting_procedures { - voting_builder.get_plutus_witnesses().0.iter().for_each(|s| { - res.add(s); - }) + voting_builder + .get_plutus_witnesses() + .0 + .iter() + .for_each(|s| { + res.add(s); + }) } if let Some(voting_proposal_builder) = &self.voting_proposals { - voting_proposal_builder.get_plutus_witnesses().0.iter().for_each(|s| { - res.add(s); - }) + voting_proposal_builder + .get_plutus_witnesses() + .0 + .iter() + .for_each(|s| { + res.add(s); + }) } if res.len() > 0 { Some(res) @@ -2088,21 +2109,36 @@ impl TransactionBuilder { if self.mint.as_ref().map_or(false, |m| m.has_plutus_scripts()) { return true; } - if self.certs.as_ref().map_or(false, |c| c.has_plutus_scripts()) { + if self + .certs + .as_ref() + .map_or(false, |c| c.has_plutus_scripts()) + { return true; } - if self.withdrawals.as_ref().map_or(false, |w| w.has_plutus_scripts()) { + if self + .withdrawals + .as_ref() + .map_or(false, |w| w.has_plutus_scripts()) + { return true; } - if self.voting_procedures.as_ref().map_or(false, |w| w.has_plutus_scripts()) { + if self + .voting_procedures + .as_ref() + .map_or(false, |w| w.has_plutus_scripts()) + { return true; } - if self.voting_proposals.as_ref().map_or(false, |w| w.has_plutus_scripts()) { + if self + .voting_proposals + .as_ref() + .map_or(false, |w| w.has_plutus_scripts()) + { return true; } return false; - } /// Returns full Transaction object with the body and the auxiliary data @@ -2148,4 +2184,4 @@ impl TransactionBuilder { self_copy.set_fee(&to_bignum(0x1_00_00_00_00)); min_fee(&self_copy) } -} \ No newline at end of file +} diff --git a/rust/src/tx_builder_constants.rs b/rust/src/builders/tx_builder_constants.rs similarity index 65% rename from rust/src/tx_builder_constants.rs rename to rust/src/builders/tx_builder_constants.rs index 41e9129c..ce1f7a30 100644 --- a/rust/src/tx_builder_constants.rs +++ b/rust/src/builders/tx_builder_constants.rs @@ -1,4 +1,4 @@ -use super::*; +use crate::*; // The first element is the cost model, which is an array of 166 operations costs, ordered by asc operaion names. // The second value is the pre-calculated `language_views_encoding` value required for the script hash creation. @@ -57,181 +57,18 @@ impl TxBuilderConstants { res.insert( &Language::new_plutus_v2(), &CostModel::from(vec![ - 205665, - 812, - 1, - 1, - 1000, - 571, - 0, - 1, - 1000, - 24177, - 4, - 1, - 1000, - 32, - 117366, - 10475, - 4, - 23000, - 100, - 23000, - 100, - 23000, - 100, - 23000, - 100, - 23000, - 100, - 23000, - 100, - 100, - 100, - 23000, - 100, - 19537, - 32, - 175354, - 32, - 46417, - 4, - 221973, - 511, - 0, - 1, - 89141, - 32, - 497525, - 14068, - 4, - 2, - 196500, - 453240, - 220, - 0, - 1, - 1, - 1000, - 28662, - 4, - 2, - 245000, - 216773, - 62, - 1, - 1060367, - 12586, - 1, - 208512, - 421, - 1, - 187000, - 1000, - 52998, - 1, - 80436, - 32, - 43249, - 32, - 1000, - 32, - 80556, - 1, - 57667, - 4, - 1000, - 10, - 197145, - 156, - 1, - 197145, - 156, - 1, - 204924, - 473, - 1, - 208896, - 511, - 1, - 52467, - 32, - 64832, - 32, - 65493, - 32, - 22558, - 32, - 16563, - 32, - 76511, - 32, - 196500, - 453240, - 220, - 0, - 1, - 1, - 69522, - 11687, - 0, - 1, - 60091, - 32, - 196500, - 453240, - 220, - 0, - 1, - 1, - 196500, - 453240, - 220, - 0, - 1, - 1, - 1159724, - 392670, - 0, - 2, - 806990, - 30482, - 4, - 1927926, - 82523, - 4, - 265318, - 0, - 4, - 0, - 85931, - 32, - 205665, - 812, - 1, - 1, - 41182, - 32, - 212342, - 32, - 31220, - 32, - 32696, - 32, - 43357, - 32, - 32247, - 32, - 38314, - 32, - 35892428, - 10, - 57996947, - 18975, - 10, - 38887044, - 32947, - 10 + 205665, 812, 1, 1, 1000, 571, 0, 1, 1000, 24177, 4, 1, 1000, 32, 117366, 10475, 4, + 23000, 100, 23000, 100, 23000, 100, 23000, 100, 23000, 100, 23000, 100, 100, 100, + 23000, 100, 19537, 32, 175354, 32, 46417, 4, 221973, 511, 0, 1, 89141, 32, 497525, + 14068, 4, 2, 196500, 453240, 220, 0, 1, 1, 1000, 28662, 4, 2, 245000, 216773, 62, + 1, 1060367, 12586, 1, 208512, 421, 1, 187000, 1000, 52998, 1, 80436, 32, 43249, 32, + 1000, 32, 80556, 1, 57667, 4, 1000, 10, 197145, 156, 1, 197145, 156, 1, 204924, + 473, 1, 208896, 511, 1, 52467, 32, 64832, 32, 65493, 32, 22558, 32, 16563, 32, + 76511, 32, 196500, 453240, 220, 0, 1, 1, 69522, 11687, 0, 1, 60091, 32, 196500, + 453240, 220, 0, 1, 1, 196500, 453240, 220, 0, 1, 1, 1159724, 392670, 0, 2, 806990, + 30482, 4, 1927926, 82523, 4, 265318, 0, 4, 0, 85931, 32, 205665, 812, 1, 1, 41182, + 32, 212342, 32, 31220, 32, 32696, 32, 43357, 32, 32247, 32, 38314, 32, 35892428, + 10, 57996947, 18975, 10, 38887044, 32947, 10, ]), ); res @@ -240,7 +77,7 @@ impl TxBuilderConstants { #[cfg(test)] mod tests { - use crate::tx_builder_constants::*; + use crate::*; #[test] pub fn cost_model_test() { diff --git a/rust/src/tx_builder/tx_inputs_builder.rs b/rust/src/builders/tx_inputs_builder.rs similarity index 80% rename from rust/src/tx_builder/tx_inputs_builder.rs rename to rust/src/builders/tx_inputs_builder.rs index bc3e9dd6..0d987d5e 100644 --- a/rust/src/tx_builder/tx_inputs_builder.rs +++ b/rust/src/builders/tx_inputs_builder.rs @@ -1,6 +1,6 @@ -use super::*; +use crate::*; +use linked_hash_map::LinkedHashMap; use std::collections::{BTreeMap, BTreeSet}; -use crate::tx_builder::script_structs::*; #[derive(Clone, Debug)] pub(crate) struct TxBuilderInput { @@ -12,23 +12,27 @@ pub(crate) struct TxBuilderInput { #[derive(Clone, Debug)] pub struct InputWithScriptWitness { pub(crate) input: TransactionInput, - pub(crate) witness: ScriptWitnessType + pub(crate) witness: ScriptWitnessType, } #[wasm_bindgen] impl InputWithScriptWitness { - pub fn new_with_native_script_witness(input: &TransactionInput, witness: &NativeScript) -> Self { + pub fn new_with_native_script_witness( + input: &TransactionInput, + witness: &NativeScript, + ) -> Self { Self { input: input.clone(), - witness: ScriptWitnessType::NativeScriptWitness( - NativeScriptSourceEnum::NativeScript(witness.clone())) + witness: ScriptWitnessType::NativeScriptWitness(NativeScriptSourceEnum::NativeScript( + witness.clone(), + )), } } pub fn new_with_plutus_witness(input: &TransactionInput, witness: &PlutusWitness) -> Self { Self { input: input.clone(), - witness: ScriptWitnessType::PlutusScriptWitness(witness.clone()) + witness: ScriptWitnessType::PlutusScriptWitness(witness.clone()), } } @@ -113,8 +117,8 @@ impl TxInputsBuilder { } #[deprecated( - since = "11.2.0", - note = "Use `.add_native_script_input` or `.add_plutus_script_input` instead." + since = "11.2.0", + note = "Use `.add_native_script_input` or `.add_plutus_script_input` instead." )] /// !!! DEPRECATED !!! /// This function can make a mistake in choosing right input index. Use `.add_native_script_input` or `.add_plutus_script_input` instead. @@ -148,8 +152,9 @@ impl TxInputsBuilder { ) { let hash = script.hash(); self.add_script_input(&hash, input, amount); - let witness = ScriptWitnessType::NativeScriptWitness( - NativeScriptSourceEnum::NativeScript(script.clone())); + let witness = ScriptWitnessType::NativeScriptWitness(NativeScriptSourceEnum::NativeScript( + script.clone(), + )); self.insert_input_with_witness(&hash, input, &witness); } @@ -261,7 +266,8 @@ impl TxInputsBuilder { if let Some(tx_in) = tx_in { let witness = ScriptWitnessType::NativeScriptWitness( - NativeScriptSourceEnum::NativeScript(s.clone())); + NativeScriptSourceEnum::NativeScript(s.clone()), + ); self.insert_input_with_witness(&hash, &tx_in, &witness); } } @@ -270,8 +276,8 @@ impl TxInputsBuilder { } #[deprecated( - since = "11.2.0", - note = "This function can make a mistake in choosing right input index. Use `.add_required_script_input_witnesses` instead." + since = "11.2.0", + note = "This function can make a mistake in choosing right input index. Use `.add_required_script_input_witnesses` instead." )] /// !!! DEPRECATED !!! /// This function can make a mistake in choosing right input index. Use `.add_required_script_input_witnesses` instead. @@ -304,26 +310,44 @@ impl TxInputsBuilder { /// Any scripts that don't match any of the previously added inputs will be ignored /// Returns the number of remaining required missing witness scripts /// Use `.count_missing_input_scripts` to find the number of still missing scripts - pub fn add_required_script_input_witnesses(&mut self, inputs_with_wit: &InputsWithScriptWitness) -> usize { - inputs_with_wit.0.iter().for_each(|input_with_wit: &InputWithScriptWitness| { - let hash = input_with_wit.witness.script_hash(); - if let Some(script_wits) = self.required_witnesses.scripts.get_mut(&hash) { - if script_wits.contains_key(&input_with_wit.input) { - script_wits.insert(input_with_wit.input.clone(), Some(input_with_wit.witness.clone())); + pub fn add_required_script_input_witnesses( + &mut self, + inputs_with_wit: &InputsWithScriptWitness, + ) -> usize { + inputs_with_wit + .0 + .iter() + .for_each(|input_with_wit: &InputWithScriptWitness| { + let hash = input_with_wit.witness.script_hash(); + if let Some(script_wits) = self.required_witnesses.scripts.get_mut(&hash) { + if script_wits.contains_key(&input_with_wit.input) { + script_wits.insert( + input_with_wit.input.clone(), + Some(input_with_wit.witness.clone()), + ); + } } - } }); + }); self.count_missing_input_scripts() } pub fn get_ref_inputs(&self) -> TransactionInputs { let mut inputs = Vec::new(); - for wintess in self.required_witnesses.scripts.iter() + for wintess in self + .required_witnesses + .scripts + .iter() .flat_map(|(_, tx_wits)| tx_wits.values()) - .filter_map(|wit| wit.as_ref()) { + .filter_map(|wit| wit.as_ref()) + { match wintess { - ScriptWitnessType::NativeScriptWitness(NativeScriptSourceEnum::RefInput(input, _, _)) => { + ScriptWitnessType::NativeScriptWitness(NativeScriptSourceEnum::RefInput( + input, + _, + _, + )) => { inputs.push(input.clone()); - }, + } ScriptWitnessType::PlutusScriptWitness(plutus_witness) => { if let Some(DatumSourceEnum::RefInput(input)) = &plutus_witness.datum { inputs.push(input.clone()); @@ -331,8 +355,8 @@ impl TxInputsBuilder { if let PlutusScriptSourceEnum::RefInput(input, _, _) = &plutus_witness.script { inputs.push(input.clone()); } - }, - _ => () + } + _ => (), } } TransactionInputs(inputs) @@ -341,15 +365,18 @@ impl TxInputsBuilder { /// Returns a copy of the current script input witness scripts in the builder pub fn get_native_input_scripts(&self) -> Option { let mut scripts = NativeScripts::new(); - self.required_witnesses.scripts + self.required_witnesses + .scripts .values() .flat_map(|v| v) .for_each(|tx_in_with_wit| { - if let Some(ScriptWitnessType::NativeScriptWitness( - NativeScriptSourceEnum::NativeScript(s))) = tx_in_with_wit.1 { - scripts.add(&s); - } - }); + if let Some(ScriptWitnessType::NativeScriptWitness( + NativeScriptSourceEnum::NativeScript(s), + )) = tx_in_with_wit.1 + { + scripts.add(&s); + } + }); if scripts.len() > 0 { Some(scripts) } else { @@ -359,15 +386,22 @@ impl TxInputsBuilder { pub(crate) fn get_used_plutus_lang_versions(&self) -> BTreeSet { let mut used_langs = BTreeSet::new(); - self.required_witnesses.scripts.values().for_each(|input_with_wit| { - for (_, script_wit) in input_with_wit { - if let Some(ScriptWitnessType::PlutusScriptWitness(PlutusWitness { script, .. })) = script_wit { - if let Some(lang) = script.language() { - used_langs.insert(lang); + self.required_witnesses + .scripts + .values() + .for_each(|input_with_wit| { + for (_, script_wit) in input_with_wit { + if let Some(ScriptWitnessType::PlutusScriptWitness(PlutusWitness { + script, + .. + })) = script_wit + { + if let Some(lang) = script.language() { + used_langs.insert(lang); + } } } - } - }); + }); used_langs } @@ -398,16 +432,17 @@ impl TxInputsBuilder { m }); let mut scripts = PlutusWitnesses::new(); - self.required_witnesses.scripts + self.required_witnesses + .scripts .iter() .flat_map(|x| x.1) .for_each(|(hash, option)| { - if let Some(ScriptWitnessType::PlutusScriptWitness(s)) = option { - if let Some(idx) = script_hash_index_map.get(&hash) { - scripts.add(&s.clone_with_redeemer_index_and_tag(&idx, &tag)); + if let Some(ScriptWitnessType::PlutusScriptWitness(s)) = option { + if let Some(idx) = script_hash_index_map.get(&hash) { + scripts.add(&s.clone_with_redeemer_index_and_tag(&idx, &tag)); + } } - } - }); + }); if scripts.len() > 0 { Some(scripts) } else { @@ -416,10 +451,10 @@ impl TxInputsBuilder { } pub(crate) fn has_plutus_scripts(&self) -> bool { - self.required_witnesses.scripts.values() - .any(|x| x.iter() - .any(|(_, w)| - matches!(w, Some(ScriptWitnessType::PlutusScriptWitness(_))))) + self.required_witnesses.scripts.values().any(|x| { + x.iter() + .any(|(_, w)| matches!(w, Some(ScriptWitnessType::PlutusScriptWitness(_)))) + }) } pub(crate) fn iter(&self) -> impl std::iter::Iterator + '_ { @@ -463,15 +498,30 @@ impl TxInputsBuilder { } } - fn insert_input_with_witness(&mut self, script_hash: &ScriptHash, input: &TransactionInput, witness: &ScriptWitnessType) { - let script_inputs = - self.required_witnesses.scripts.entry(script_hash.clone()).or_insert(LinkedHashMap::new()); + fn insert_input_with_witness( + &mut self, + script_hash: &ScriptHash, + input: &TransactionInput, + witness: &ScriptWitnessType, + ) { + let script_inputs = self + .required_witnesses + .scripts + .entry(script_hash.clone()) + .or_insert(LinkedHashMap::new()); script_inputs.insert(input.clone(), Some(witness.clone())); } - fn insert_input_with_empty_witness(&mut self, script_hash: &ScriptHash, input: &TransactionInput) { - let script_inputs = - self.required_witnesses.scripts.entry(script_hash.clone()).or_insert(LinkedHashMap::new()); + fn insert_input_with_empty_witness( + &mut self, + script_hash: &ScriptHash, + input: &TransactionInput, + ) { + let script_inputs = self + .required_witnesses + .scripts + .entry(script_hash.clone()) + .or_insert(LinkedHashMap::new()); script_inputs.insert(input.clone(), None); } } @@ -486,7 +536,7 @@ impl From<&TxInputsBuilder> for RequiredSignersSet { .flat_map(|tx_wits| tx_wits.values()) .for_each(|swt: &Option| { if let Some(ScriptWitnessType::NativeScriptWitness(script_source)) = swt { - set.extend(script_source.required_signers()); + set.extend(script_source.required_signers()); } }); set diff --git a/rust/src/tx_builder/withdrawals_builder.rs b/rust/src/builders/withdrawals_builder.rs similarity index 99% rename from rust/src/tx_builder/withdrawals_builder.rs rename to rust/src/builders/withdrawals_builder.rs index 731d9c26..14d5c5cd 100644 --- a/rust/src/tx_builder/withdrawals_builder.rs +++ b/rust/src/builders/withdrawals_builder.rs @@ -1,4 +1,3 @@ -use crate::tx_builder::script_structs::*; use crate::*; use linked_hash_map::LinkedHashMap; From fa3cd238aaf19b34ebe184e184e07283eae29978 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 8 Sep 2023 21:25:27 +0500 Subject: [PATCH 122/349] fix voting builder api + fmt --- .../voting_builder.rs | 37 +++++++++++-------- .../voting_proposal_builder.rs | 23 ++++-------- 2 files changed, 28 insertions(+), 32 deletions(-) rename rust/src/{tx_builder => builders}/voting_builder.rs (86%) rename rust/src/{tx_builder => builders}/voting_proposal_builder.rs (87%) diff --git a/rust/src/tx_builder/voting_builder.rs b/rust/src/builders/voting_builder.rs similarity index 86% rename from rust/src/tx_builder/voting_builder.rs rename to rust/src/builders/voting_builder.rs index c98c0a68..73f16b17 100644 --- a/rust/src/tx_builder/voting_builder.rs +++ b/rust/src/builders/voting_builder.rs @@ -1,4 +1,3 @@ -use crate::tx_builder::script_structs::*; use crate::*; use std::collections::BTreeMap; @@ -24,9 +23,9 @@ impl VotingBuilder { pub fn add( &mut self, - voter: Voter, - gov_action_id: GovernanceActionId, - voting_procedure: VotingProcedure, + voter: &Voter, + gov_action_id: &GovernanceActionId, + voting_procedure: &VotingProcedure, ) -> Result<(), JsError> { if voter.has_script_credentials() { return Err(JsError::from_str( @@ -35,21 +34,23 @@ impl VotingBuilder { )); } - let voter_votes = self.votes.entry(voter).or_insert(VoterVotes { + let voter_votes = self.votes.entry(voter.clone()).or_insert(VoterVotes { script_witness: None, votes: BTreeMap::new(), }); - voter_votes.votes.insert(gov_action_id, voting_procedure); + voter_votes + .votes + .insert(gov_action_id.clone(), voting_procedure.clone()); Ok(()) } pub fn add_with_plutus_witness( &mut self, - voter: Voter, - gov_action_id: GovernanceActionId, - voting_procedure: VotingProcedure, + voter: &Voter, + gov_action_id: &GovernanceActionId, + voting_procedure: &VotingProcedure, witness: &PlutusWitness, ) -> Result<(), JsError> { if !voter.has_script_credentials() { @@ -59,21 +60,23 @@ impl VotingBuilder { )); } - let voter_votes = self.votes.entry(voter).or_insert(VoterVotes { + let voter_votes = self.votes.entry(voter.clone()).or_insert(VoterVotes { script_witness: Some(ScriptWitnessType::PlutusScriptWitness(witness.clone())), votes: BTreeMap::new(), }); - voter_votes.votes.insert(gov_action_id, voting_procedure); + voter_votes + .votes + .insert(gov_action_id.clone(), voting_procedure.clone()); Ok(()) } pub fn add_with_native_script( &mut self, - voter: Voter, - gov_action_id: GovernanceActionId, - voting_procedure: VotingProcedure, + voter: &Voter, + gov_action_id: &GovernanceActionId, + voting_procedure: &VotingProcedure, native_script_source: &NativeScriptSource, ) -> Result<(), JsError> { if !voter.has_script_credentials() { @@ -83,14 +86,16 @@ impl VotingBuilder { )); } - let voter_votes = self.votes.entry(voter).or_insert(VoterVotes { + let voter_votes = self.votes.entry(voter.clone()).or_insert(VoterVotes { script_witness: Some(ScriptWitnessType::NativeScriptWitness( native_script_source.0.clone(), )), votes: BTreeMap::new(), }); - voter_votes.votes.insert(gov_action_id, voting_procedure); + voter_votes + .votes + .insert(gov_action_id.clone(), voting_procedure.clone()); Ok(()) } diff --git a/rust/src/tx_builder/voting_proposal_builder.rs b/rust/src/builders/voting_proposal_builder.rs similarity index 87% rename from rust/src/tx_builder/voting_proposal_builder.rs rename to rust/src/builders/voting_proposal_builder.rs index ef9b97d0..dd28f691 100644 --- a/rust/src/tx_builder/voting_proposal_builder.rs +++ b/rust/src/builders/voting_proposal_builder.rs @@ -1,4 +1,3 @@ -use crate::tx_builder::script_structs::*; use crate::*; use std::collections::BTreeMap; @@ -16,27 +15,19 @@ impl VotingProposalBuilder { } } - pub fn add( - &mut self, - proposal: VotingProposal, - ) -> Result<(), JsError> { - - self.votes.insert( - proposal, - None, - ); + pub fn add(&mut self, proposal: VotingProposal) -> Result<(), JsError> { + self.votes.insert(proposal, None); Ok(()) } pub fn add_with_plutus_witness( &mut self, - proposal: VotingProposal, + proposal: &VotingProposal, witness: &PlutusWitness, ) -> Result<(), JsError> { - self.votes.insert( - proposal, + proposal.clone(), Some(ScriptWitnessType::PlutusScriptWitness(witness.clone())), ); Ok(()) @@ -78,9 +69,9 @@ impl VotingProposalBuilder { } pub(crate) fn get_total_deposit(&self, proposal_deposit: &Coin) -> Result { - proposal_deposit.checked_mul(&Coin::from(self.votes.len())) - .or_else(|_| - Err(JsError::from_str("Overflow when calculating total deposit"))) + proposal_deposit + .checked_mul(&Coin::from(self.votes.len())) + .or_else(|_| Err(JsError::from_str("Overflow when calculating total deposit"))) } pub(crate) fn get_used_plutus_lang_versions(&self) -> BTreeSet { From 7b39c750fb66f3e774026401b27c80ee8d3af5cd Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 8 Sep 2023 21:25:54 +0500 Subject: [PATCH 123/349] move to another module + fmt --- .../batch_tools/asset_categorizer.rs | 177 ++++++++++++------ .../batch_tools/assets_calculator.rs | 95 ++++++---- .../batch_tools/cbor_calculator.rs | 64 ++++--- .../batch_tools/indexes.rs | 4 +- .../batch_tools/mod.rs | 6 +- .../batch_tools/proposals.rs | 62 +++--- .../batch_tools/utxo_stat.rs | 22 ++- .../batch_tools/witnesses_calculator.rs | 39 ++-- 8 files changed, 309 insertions(+), 160 deletions(-) rename rust/src/{tx_builder => builders}/batch_tools/asset_categorizer.rs (81%) rename rust/src/{tx_builder => builders}/batch_tools/assets_calculator.rs (65%) rename rust/src/{tx_builder => builders}/batch_tools/cbor_calculator.rs (80%) rename rust/src/{tx_builder => builders}/batch_tools/indexes.rs (92%) rename rust/src/{tx_builder => builders}/batch_tools/mod.rs (88%) rename rust/src/{tx_builder => builders}/batch_tools/proposals.rs (79%) rename rust/src/{tx_builder => builders}/batch_tools/utxo_stat.rs (69%) rename rust/src/{tx_builder => builders}/batch_tools/witnesses_calculator.rs (81%) diff --git a/rust/src/tx_builder/batch_tools/asset_categorizer.rs b/rust/src/builders/batch_tools/asset_categorizer.rs similarity index 81% rename from rust/src/tx_builder/batch_tools/asset_categorizer.rs rename to rust/src/builders/batch_tools/asset_categorizer.rs index 2d5f6720..36d33a44 100644 --- a/rust/src/tx_builder/batch_tools/asset_categorizer.rs +++ b/rust/src/builders/batch_tools/asset_categorizer.rs @@ -1,10 +1,10 @@ -use std::collections::HashMap; -use crate::tx_builder::batch_tools::proposals::{TxOutputProposal, TxProposal}; use super::assets_calculator::AssetsCalculator; use super::cbor_calculator::CborCalculator; +use super::indexes::{AssetIndex, PlaneAssetId, PolicyIndex, UtxoIndex}; use super::utxo_stat::UtxosStat; -use super::indexes::{UtxoIndex, AssetIndex, PolicyIndex, PlaneAssetId}; -use super::super::*; +use crate::builders::batch_tools::proposals::{TxOutputProposal, TxProposal}; +use crate::*; +use std::collections::{HashMap, HashSet}; #[derive(Clone)] pub(crate) struct TxProposalChanges { @@ -46,12 +46,15 @@ pub struct AssetCategorizer { free_ada_utxos: Vec<(UtxoIndex, Coin)>, //utxos_with_ada_overhead: Vec<(UtxoIndex, Coin)>, - output_size: usize, } impl AssetCategorizer { - pub(crate) fn new(config: &TransactionBuilderConfig, utxos: &TransactionUnspentOutputs, address: &Address) -> Result { + pub(crate) fn new( + config: &TransactionBuilderConfig, + utxos: &TransactionUnspentOutputs, + address: &Address, + ) -> Result { let mut assets: Vec = Vec::new(); let mut utxos_ada: Vec = Vec::new(); let mut policies: Vec = Vec::new(); @@ -84,7 +87,8 @@ impl AssetCategorizer { utxos_ada.push(utxo.output.amount.coin.clone()); addresses.push(utxo.output.address.clone()); - let ada_overhead = Self::calc_utxo_output_overhead(address, &utxo.output.amount, config)?; + let ada_overhead = + Self::calc_utxo_output_overhead(address, &utxo.output.amount, config)?; if ada_overhead > Coin::zero() { utxos_with_ada_overhead.push((current_utxo_index.clone(), ada_overhead)); } @@ -100,7 +104,7 @@ impl AssetCategorizer { policy_count += 1; } - for asset in &policy.1.0 { + for asset in &policy.1 .0 { let mut current_asset_index = AssetIndex(asset_count.clone()); let plane_id = PlaneAssetId(current_policy_index.clone(), asset.0.clone()); @@ -108,8 +112,9 @@ impl AssetCategorizer { current_asset_index = asset_index.clone(); assets_counts[current_asset_index.0].1 += 1; } else { - let mut asset_name_size = CborCalculator::get_struct_size(asset.0.0.len() as u64); - asset_name_size += asset.0.0.len(); + let mut asset_name_size = + CborCalculator::get_struct_size(asset.0 .0.len() as u64); + asset_name_size += asset.0 .0.len(); assets.push(plane_id.clone()); assets_name_sizes.push(asset_name_size); asset_ids.insert(plane_id, current_asset_index.clone()); @@ -121,7 +126,8 @@ impl AssetCategorizer { let asset_utxo_amounts = &mut assets_amounts[current_asset_index.0]; asset_utxo_amounts.insert(current_utxo_index.clone(), asset.1.clone()); - asset_to_policy.insert(current_asset_index.clone(), current_policy_index.clone()); + asset_to_policy + .insert(current_asset_index.clone(), current_policy_index.clone()); if let Some(assets_set) = policy_to_asset.get_mut(¤t_policy_index) { assets_set.insert(current_asset_index.clone()); } else { @@ -191,8 +197,11 @@ impl AssetCategorizer { !self.free_ada_utxos.is_empty() } - pub(crate) fn build_value(&self, used_utxos: &HashSet, tx_output_proposal: &TxOutputProposal) - -> Result { + pub(crate) fn build_value( + &self, + used_utxos: &HashSet, + tx_output_proposal: &TxOutputProposal, + ) -> Result { let mut value = Value::new(&tx_output_proposal.total_ada); if tx_output_proposal.used_assets.is_empty() { return Ok(value); @@ -206,7 +215,11 @@ impl AssetCategorizer { asset_coins = asset_coins.checked_add(coins)?; } } - multiasset.set_asset(&self.policies[policy_index.0], &self.assets[asset_index.0].1, asset_coins); + multiasset.set_asset( + &self.policies[policy_index.0], + &self.assets[asset_index.0].1, + asset_coins, + ); } } @@ -214,7 +227,10 @@ impl AssetCategorizer { Ok(value) } - pub(crate) fn try_append_next_utxos(&mut self, tx_proposal: &TxProposal) -> Result, JsError> { + pub(crate) fn try_append_next_utxos( + &mut self, + tx_proposal: &TxProposal, + ) -> Result, JsError> { let mut proposal_changes = None; if self.has_assets() { proposal_changes = self.try_append_next_asset_utxos(tx_proposal)?; @@ -223,7 +239,6 @@ impl AssetCategorizer { } if let Some(proposal_changes) = proposal_changes { - for utxo in proposal_changes.asset_utxo { self.remove_assets_utxo(&utxo); } @@ -238,15 +253,20 @@ impl AssetCategorizer { } } - pub(crate) fn try_append_next_asset_utxos(&self, tx_proposal: &TxProposal) -> Result, JsError> { + pub(crate) fn try_append_next_asset_utxos( + &self, + tx_proposal: &TxProposal, + ) -> Result, JsError> { let asset_intersections = self.get_asset_intersections(&tx_proposal.used_assets); - let asset_intersected_utxo = self.make_candidate(&asset_intersections, tx_proposal, false)?; + let asset_intersected_utxo = + self.make_candidate(&asset_intersections, tx_proposal, false)?; if let Some(res_utxo) = asset_intersected_utxo { return Ok(Some(res_utxo)); } let policy_intersections = self.get_policy_intersections(&tx_proposal.used_assets); - let policy_intersected_utxo = self.make_candidate(&policy_intersections, tx_proposal, false)?; + let policy_intersected_utxo = + self.make_candidate(&policy_intersections, tx_proposal, false)?; if let Some(res_utxo) = policy_intersected_utxo { return Ok(Some(res_utxo)); } @@ -254,7 +274,10 @@ impl AssetCategorizer { self.make_candidate(&self.assets_counts, tx_proposal, true) } - fn try_append_pure_ada_utxo(&self, tx_proposal: &TxProposal) -> Result, JsError> { + fn try_append_pure_ada_utxo( + &self, + tx_proposal: &TxProposal, + ) -> Result, JsError> { let mut new_proposal: TxProposal = tx_proposal.clone(); let mut used_utxos = HashSet::new(); if new_proposal.get_need_ada()? == Coin::zero() { @@ -272,9 +295,8 @@ impl AssetCategorizer { let mut new_size = self.set_min_ada_for_tx(&mut new_proposal)?; if new_proposal.get_need_ada()? > Coin::zero() { - let next_utxos = self.get_next_pure_ada_utxo_by_amount( - &new_proposal.get_need_ada()?, - &used_utxos)?; + let next_utxos = + self.get_next_pure_ada_utxo_by_amount(&new_proposal.get_need_ada()?, &used_utxos)?; for (utxo, coin) in &next_utxos { new_proposal.add_utxo(utxo, coin, &self.addresses[utxo.0])?; @@ -283,7 +305,9 @@ impl AssetCategorizer { new_size = self.set_min_ada_for_tx(&mut new_proposal)?; if new_size > (self.config.max_tx_size as usize) && tx_proposal.used_utoxs.is_empty() { - return Err(JsError::from_str("Utxo can not be places into tx, utxo value is too big.")); + return Err(JsError::from_str( + "Utxo can not be places into tx, utxo value is too big.", + )); } } @@ -306,7 +330,10 @@ impl AssetCategorizer { sizes } - fn get_asset_intersections(&self, used_assets: &HashSet) -> Vec<(AssetIndex, usize)> { + fn get_asset_intersections( + &self, + used_assets: &HashSet, + ) -> Vec<(AssetIndex, usize)> { let mut intersections = Vec::new(); for (index, asset_count) in &self.assets_counts { if used_assets.contains(index) && self.free_asset_to_utxos.contains_key(index) { @@ -316,9 +343,13 @@ impl AssetCategorizer { intersections } - fn get_policy_intersections(&self, used_assets: &HashSet) -> Vec<(AssetIndex, usize)> { + fn get_policy_intersections( + &self, + used_assets: &HashSet, + ) -> Vec<(AssetIndex, usize)> { let mut intersections = Vec::new(); - let used_policies = used_assets.iter() + let used_policies = used_assets + .iter() .filter_map(|x| self.asset_to_policy.get(x)); let available_assets: HashSet = used_policies .filter_map(|x| self.policy_to_asset.get(x)) @@ -333,9 +364,11 @@ impl AssetCategorizer { intersections } - fn prototype_append(&self, - tx_proposal: &TxProposal, - utxo: &UtxoIndex) -> Result, JsError> { + fn prototype_append( + &self, + tx_proposal: &TxProposal, + utxo: &UtxoIndex, + ) -> Result, JsError> { let utxo_assets = self.free_utxo_to_assets.get(utxo); let mut new_proposal = tx_proposal.clone(); let used_assets_in_output = match new_proposal.tx_output_proposals.last() { @@ -357,7 +390,10 @@ impl AssetCategorizer { let mut assets_for_next_output = asset_for_add; let mut create_new_output = false; while let Some(next_assets) = self.add_assets_to_proposal_output( - create_new_output, &mut new_proposal, &assets_for_next_output)? { + create_new_output, + &mut new_proposal, + &assets_for_next_output, + )? { assets_for_next_output = next_assets; create_new_output = true; } @@ -367,8 +403,10 @@ impl AssetCategorizer { if new_size > (self.config.max_tx_size as usize) { if tx_proposal.used_utoxs.is_empty() { - return Err(JsError::from_str( - &format!("Utxo can not be places into tx, utxo value is too big. Utxo index {}", utxo.0))); + return Err(JsError::from_str(&format!( + "Utxo can not be places into tx, utxo value is too big. Utxo index {}", + utxo.0 + ))); } //that means that we above limit of tx size and we cannot create that tx @@ -393,15 +431,20 @@ impl AssetCategorizer { Ok(None) } - fn add_assets_to_proposal_output(&self, create_new: bool, tx_proposal: &mut TxProposal, assets: &HashSet) - -> Result>, JsError> { + fn add_assets_to_proposal_output( + &self, + create_new: bool, + tx_proposal: &mut TxProposal, + assets: &HashSet, + ) -> Result>, JsError> { let last_output = tx_proposal.get_outputs().last(); let mut old_value_state = if create_new || last_output.is_none() { self.assets_calculator.build_empty_intermediate_value() } else { self.assets_calculator.build_intermediate_value( last_output.unwrap().get_used_assets(), - &self.asset_to_policy) + &self.asset_to_policy, + ) }; let mut new_value_state = old_value_state.clone(); @@ -413,14 +456,17 @@ impl AssetCategorizer { let new_size = self.assets_calculator.add_asset_to_intermediate_value( &mut new_value_state, asset, - &self.asset_to_policy[asset]); + &self.asset_to_policy[asset], + ); if new_size <= self.config.max_value_size as usize { asset_to_output.insert(asset.clone()); old_value_state = new_value_state.clone(); } else { if old_value_state.is_empty() { - return Err(JsError::from_str( - &format!("Asset can not be places into tx, asset size is too big. Asset index {}", asset.0))); + return Err(JsError::from_str(&format!( + "Asset can not be places into tx, asset size is too big. Asset index {}", + asset.0 + ))); } new_value_state = old_value_state.clone(); asset_to_new_output.insert(asset.clone()); @@ -442,7 +488,10 @@ impl AssetCategorizer { } } - pub(crate) fn set_min_ada_for_tx(&self, tx_proposal: &mut TxProposal) -> Result { + pub(crate) fn set_min_ada_for_tx( + &self, + tx_proposal: &mut TxProposal, + ) -> Result { self.recalculate_outputs(tx_proposal)?; let (tx_fee, tx_size) = self.estimate_fee(tx_proposal)?; tx_proposal.set_fee(&tx_fee); @@ -490,8 +539,11 @@ impl AssetCategorizer { self.free_ada_utxos.last() } - fn get_next_pure_ada_utxo_by_amount(&self, need_ada: &Coin, ignore_list: &HashSet) - -> Result, JsError> { + fn get_next_pure_ada_utxo_by_amount( + &self, + need_ada: &Coin, + ignore_list: &HashSet, + ) -> Result, JsError> { //TODO: add algo with minimal count of utxos let mut ada_left = need_ada.clone(); let mut utxos = Vec::new(); @@ -514,8 +566,12 @@ impl AssetCategorizer { } } - fn make_candidate(&self, assets: &Vec<(AssetIndex, usize)>, tx_propoasl: &TxProposal, choose_first: bool) - -> Result, JsError> { + fn make_candidate( + &self, + assets: &Vec<(AssetIndex, usize)>, + tx_propoasl: &TxProposal, + choose_first: bool, + ) -> Result, JsError> { let mut txp_with_new_output: Option = None; for (index, _) in assets.iter() { let utxos_set = self.free_asset_to_utxos.get(index); @@ -539,18 +595,24 @@ impl AssetCategorizer { Ok(txp_with_new_output) } - fn estimate_output_cost(&self, used_utoxs: &HashSet, output_proposal: &TxOutputProposal) -> Result<(Coin, usize), JsError> { + fn estimate_output_cost( + &self, + used_utoxs: &HashSet, + output_proposal: &TxOutputProposal, + ) -> Result<(Coin, usize), JsError> { let assets_size = self.assets_calculator.calc_value_size( &output_proposal.total_ada, &output_proposal.grouped_assets, used_utoxs, - &self.assets_amounts)?; + &self.assets_amounts, + )?; let mut output_size = self.output_size + assets_size; output_size += CborCalculator::get_value_struct_size(output_proposal.contains_only_ada()); CborCalculator::estimate_output_cost( &output_proposal.get_total_ada(), output_size, - &self.config.data_cost) + &self.config.data_cost, + ) } pub(crate) fn estimate_fee(&self, tx_proposal: &TxProposal) -> Result<(Coin, usize), JsError> { @@ -558,16 +620,15 @@ impl AssetCategorizer { let mut dependable_value = None; let mut min_value = None; if let Some(last_output) = tx_proposal.get_outputs().last() { - dependable_value = Some(tx_proposal.get_unused_ada()? - .checked_add(&last_output.get_total_ada())?); + dependable_value = Some( + tx_proposal + .get_unused_ada()? + .checked_add(&last_output.get_total_ada())?, + ); min_value = Some(last_output.get_min_ada()); tx_len -= CborCalculator::get_coin_size(&last_output.get_total_ada()); } - CborCalculator::estimate_fee( - tx_len, - min_value, - dependable_value, - &self.config.fee_algo) + CborCalculator::estimate_fee(tx_len, min_value, dependable_value, &self.config.fee_algo) } fn remove_assets_utxo(&mut self, utxo: &UtxoIndex) { @@ -592,12 +653,14 @@ impl AssetCategorizer { } } - fn calc_utxo_output_overhead(address: &Address, value: &Value, cfg: &TransactionBuilderConfig) - -> Result { + fn calc_utxo_output_overhead( + address: &Address, + value: &Value, + cfg: &TransactionBuilderConfig, + ) -> Result { let ada = value.coin; let output = TransactionOutput::new(address, value); let req_coin = MinOutputAdaCalculator::calc_required_coin(&output, &cfg.data_cost)?; Ok(ada.checked_sub(&req_coin).unwrap_or(Coin::zero())) } } - diff --git a/rust/src/tx_builder/batch_tools/assets_calculator.rs b/rust/src/builders/batch_tools/assets_calculator.rs similarity index 65% rename from rust/src/tx_builder/batch_tools/assets_calculator.rs rename to rust/src/builders/batch_tools/assets_calculator.rs index d3dcffd8..ec638381 100644 --- a/rust/src/tx_builder/batch_tools/assets_calculator.rs +++ b/rust/src/builders/batch_tools/assets_calculator.rs @@ -1,9 +1,9 @@ -use std::collections::HashMap; -use super::utxo_stat::UtxosStat; use super::cbor_calculator::CborCalculator; -use super::indexes::{UtxoIndex, AssetIndex, PolicyIndex}; +use super::indexes::{AssetIndex, PolicyIndex, UtxoIndex}; +use super::utxo_stat::UtxosStat; use crate::utils::*; -use super::super::*; +use crate::*; +use std::collections::{HashMap, HashSet}; #[derive(Clone)] struct IntermediatePolicyState { @@ -19,7 +19,12 @@ impl IntermediatePolicyState { } } - pub(super) fn add_asset(&mut self, asset_index: &AssetIndex, size: usize, coin_size: usize) -> usize { + pub(super) fn add_asset( + &mut self, + asset_index: &AssetIndex, + size: usize, + coin_size: usize, + ) -> usize { if !self.assets.contains(asset_index) { let mut new_size = self.total_size; if self.assets.len() > 0 { @@ -48,13 +53,19 @@ impl IntermediateOutputValue { } } - pub(super) fn set_coin(&mut self, coin: &Coin) -> usize{ + pub(super) fn set_coin(&mut self, coin: &Coin) -> usize { self.total_size += CborCalculator::get_coin_size(coin); self.total_size } - pub(super) fn add_asset(&mut self, policy_index: &PolicyIndex, asset_index: &AssetIndex, - policy_size: usize, asset_size: usize, coin_size: usize) -> usize { + pub(super) fn add_asset( + &mut self, + policy_index: &PolicyIndex, + asset_index: &AssetIndex, + policy_size: usize, + asset_size: usize, + coin_size: usize, + ) -> usize { if self.is_empty() { //value with assets and ada is array of 2 elements self.total_size += CborCalculator::get_struct_size(2); @@ -79,13 +90,14 @@ impl IntermediateOutputValue { } pub(super) fn is_empty(&self) -> bool { - self.multi_asset.iter() - .map(|(_, policy)| policy.assets.len()).sum::() <= 0 + self.multi_asset + .iter() + .map(|(_, policy)| policy.assets.len()) + .sum::() + <= 0 } } - - #[derive(Clone)] pub(super) struct AssetsCalculator { assets_name_sizes: Vec, @@ -94,10 +106,9 @@ pub(super) struct AssetsCalculator { } impl AssetsCalculator { - pub(super) fn new(utxo_stat: UtxosStat, assets_name_sizes: Vec) -> Self { //28 is the size of a policy id in bytes - let policy_size= 28 + CborCalculator::get_struct_size(28u64); + let policy_size = 28 + CborCalculator::get_struct_size(28u64); Self { assets_name_sizes, @@ -106,11 +117,13 @@ impl AssetsCalculator { } } - pub(super) fn calc_value_size(&self, - coin: &Coin, - grouped_assets: &HashMap>, - utxos: &HashSet, - assets_amounts: &Vec>) -> Result { + pub(super) fn calc_value_size( + &self, + coin: &Coin, + grouped_assets: &HashMap>, + utxos: &HashSet, + assets_amounts: &Vec>, + ) -> Result { let mut size = 0; size += CborCalculator::get_coin_size(coin); @@ -127,7 +140,7 @@ impl AssetsCalculator { let mut asset_coins = Coin::zero(); for (utxo, coins) in &assets_amounts[asset_in_policy.0] { if utxos.contains(utxo) { - asset_coins = asset_coins.checked_add(coins)?; + asset_coins = asset_coins.checked_add(coins)?; } } size += CborCalculator::get_coin_size(&asset_coins); @@ -136,24 +149,38 @@ impl AssetsCalculator { Ok(size) } - pub(super) fn add_asset_to_intermediate_value(&self, intermediate_value: &mut IntermediateOutputValue, asset_index: &AssetIndex, - policy_index: &PolicyIndex) -> usize { - intermediate_value.add_asset(policy_index, asset_index, - self.policy_size, - self.assets_name_sizes[asset_index.0], - CborCalculator::get_coin_size(&self.utxo_stat.coins_in_assets[asset_index])) + pub(super) fn add_asset_to_intermediate_value( + &self, + intermediate_value: &mut IntermediateOutputValue, + asset_index: &AssetIndex, + policy_index: &PolicyIndex, + ) -> usize { + intermediate_value.add_asset( + policy_index, + asset_index, + self.policy_size, + self.assets_name_sizes[asset_index.0], + CborCalculator::get_coin_size(&self.utxo_stat.coins_in_assets[asset_index]), + ) } - pub(super) fn build_intermediate_value(&self, assets_ids: &HashSet, - asset_to_policy: &HashMap) -> IntermediateOutputValue { + pub(super) fn build_intermediate_value( + &self, + assets_ids: &HashSet, + asset_to_policy: &HashMap, + ) -> IntermediateOutputValue { let mut intermediate_data = IntermediateOutputValue::new(); for asset_index in assets_ids { - let asset_coin_size = CborCalculator::get_coin_size(&self.utxo_stat.coins_in_assets[asset_index]); + let asset_coin_size = + CborCalculator::get_coin_size(&self.utxo_stat.coins_in_assets[asset_index]); let policy_index = &asset_to_policy[asset_index]; - intermediate_data.add_asset(policy_index, asset_index, - self.policy_size, - self.assets_name_sizes[asset_index.0], - asset_coin_size); + intermediate_data.add_asset( + policy_index, + asset_index, + self.policy_size, + self.assets_name_sizes[asset_index.0], + asset_coin_size, + ); } intermediate_data.set_coin(&self.utxo_stat.ada_coins); intermediate_data @@ -164,4 +191,4 @@ impl AssetsCalculator { value.set_coin(&self.utxo_stat.ada_coins); value } -} \ No newline at end of file +} diff --git a/rust/src/tx_builder/batch_tools/cbor_calculator.rs b/rust/src/builders/batch_tools/cbor_calculator.rs similarity index 80% rename from rust/src/tx_builder/batch_tools/cbor_calculator.rs rename to rust/src/builders/batch_tools/cbor_calculator.rs index d97b83af..baffa203 100644 --- a/rust/src/tx_builder/batch_tools/cbor_calculator.rs +++ b/rust/src/builders/batch_tools/cbor_calculator.rs @@ -1,7 +1,8 @@ -use num_traits::ToPrimitive; -use crate::fees::{LinearFee, min_fee_for_size}; +use crate::fees::{min_fee_for_size, LinearFee}; use crate::serialization::map_names::{TxBodyNames, WitnessSetNames}; -use super::super::*; +use crate::*; +use num_traits::ToPrimitive; +use std::collections::HashSet; pub(super) struct CborCalculator(); @@ -53,7 +54,7 @@ impl CborCalculator { let legacy_output_size = CborCalculator::get_struct_size(2); let address_size = CborCalculator::get_address_size(address); let address_struct_size = CborCalculator::get_struct_size(address_size as u64); - return legacy_output_size + address_size + address_struct_size + return legacy_output_size + address_size + address_struct_size; } pub(super) fn get_value_struct_size(ada_only: bool) -> usize { @@ -64,7 +65,6 @@ impl CborCalculator { //value with assets and ada is array of 2 elements CborCalculator::get_struct_size(2) } - } pub(super) fn get_bare_tx_body_size(body_fields: &HashSet) -> usize { @@ -75,7 +75,9 @@ impl CborCalculator { size } - pub(super) fn get_wintnesses_set_struct_size(witnesses_fields: &HashSet) -> usize { + pub(super) fn get_wintnesses_set_struct_size( + witnesses_fields: &HashSet, + ) -> usize { let mut size = CborCalculator::get_struct_size(witnesses_fields.len() as u64); for field in witnesses_fields { size += CborCalculator::get_struct_size(field.to_u64().unwrap()); @@ -93,11 +95,12 @@ impl CborCalculator { size } - //TODO: extract iterative logic from estimate_output_cost and estimate_fee to separate function - pub(super) fn estimate_output_cost(used_coins: &Coin, - output_size: usize, - data_cost: &DataCost) -> Result<(Coin, usize), JsError> { + pub(super) fn estimate_output_cost( + used_coins: &Coin, + output_size: usize, + data_cost: &DataCost, + ) -> Result<(Coin, usize), JsError> { let mut current_cost = MinOutputAdaCalculator::calc_size_cost(data_cost, output_size)?; if current_cost <= *used_coins { return Ok((current_cost, output_size)); @@ -120,20 +123,31 @@ impl CborCalculator { Ok((pessimistic_cost, max_size)) } - - pub(super) fn estimate_fee(tx_size_without_fee: usize, - min_dependable_amount: Option, - dependable_amount: Option, - fee_algo: &LinearFee) -> Result<(Coin, usize), JsError> { + pub(super) fn estimate_fee( + tx_size_without_fee: usize, + min_dependable_amount: Option, + dependable_amount: Option, + fee_algo: &LinearFee, + ) -> Result<(Coin, usize), JsError> { let mut current_cost = min_fee_for_size(tx_size_without_fee, fee_algo)?; let mut last_size = tx_size_without_fee + CborCalculator::get_coin_size(¤t_cost); - last_size = Self::recalc_size_with_dependable_value(last_size, ¤t_cost, min_dependable_amount, dependable_amount)?; + last_size = Self::recalc_size_with_dependable_value( + last_size, + ¤t_cost, + min_dependable_amount, + dependable_amount, + )?; for _ in 0..3 { current_cost = min_fee_for_size(last_size, fee_algo)?; let mut new_size = tx_size_without_fee + CborCalculator::get_coin_size(¤t_cost); - new_size = Self::recalc_size_with_dependable_value(new_size, ¤t_cost, min_dependable_amount, dependable_amount)?; + new_size = Self::recalc_size_with_dependable_value( + new_size, + ¤t_cost, + min_dependable_amount, + dependable_amount, + )?; if new_size == last_size { return Ok((current_cost, last_size)); @@ -149,12 +163,16 @@ impl CborCalculator { //if we get ada from somewhere for fee, that means that we reduce size of it can be reduced //by this logic we try to track this - fn recalc_size_with_dependable_value(size: usize, - current_cost: &Coin, - min_dependable_amount: Option, - dependable_amount: Option, ) -> Result { + fn recalc_size_with_dependable_value( + size: usize, + current_cost: &Coin, + min_dependable_amount: Option, + dependable_amount: Option, + ) -> Result { if let Some(dependable_amount) = dependable_amount { - let mut remain_ada = dependable_amount.checked_sub(current_cost).unwrap_or(Coin::zero()); + let mut remain_ada = dependable_amount + .checked_sub(current_cost) + .unwrap_or(Coin::zero()); if let Some(min_dependable_amount) = min_dependable_amount { if remain_ada < min_dependable_amount { remain_ada = min_dependable_amount; @@ -165,4 +183,4 @@ impl CborCalculator { Ok(size) } -} \ No newline at end of file +} diff --git a/rust/src/tx_builder/batch_tools/indexes.rs b/rust/src/builders/batch_tools/indexes.rs similarity index 92% rename from rust/src/tx_builder/batch_tools/indexes.rs rename to rust/src/builders/batch_tools/indexes.rs index ed32a921..427904a1 100644 --- a/rust/src/tx_builder/batch_tools/indexes.rs +++ b/rust/src/builders/batch_tools/indexes.rs @@ -1,4 +1,4 @@ -use super::super::*; +use crate::*; #[derive(PartialEq, Eq, Hash, Clone)] pub struct UtxoIndex(pub(super) usize); @@ -10,4 +10,4 @@ pub struct AssetIndex(pub(super) usize); pub struct PolicyIndex(pub(super) usize); #[derive(PartialEq, Eq, Clone, Hash)] -pub struct PlaneAssetId(pub(super) PolicyIndex, pub(super) AssetName); \ No newline at end of file +pub struct PlaneAssetId(pub(super) PolicyIndex, pub(super) AssetName); diff --git a/rust/src/tx_builder/batch_tools/mod.rs b/rust/src/builders/batch_tools/mod.rs similarity index 88% rename from rust/src/tx_builder/batch_tools/mod.rs rename to rust/src/builders/batch_tools/mod.rs index 6548b6ee..c3015f92 100644 --- a/rust/src/tx_builder/batch_tools/mod.rs +++ b/rust/src/builders/batch_tools/mod.rs @@ -1,7 +1,7 @@ -pub mod utxo_stat; pub mod asset_categorizer; pub mod assets_calculator; -pub mod witnesses_calculator; pub mod cbor_calculator; pub mod indexes; -pub mod proposals; \ No newline at end of file +pub mod proposals; +pub mod utxo_stat; +pub mod witnesses_calculator; diff --git a/rust/src/tx_builder/batch_tools/proposals.rs b/rust/src/builders/batch_tools/proposals.rs similarity index 79% rename from rust/src/tx_builder/batch_tools/proposals.rs rename to rust/src/builders/batch_tools/proposals.rs index 26eb3710..3b1dd4d3 100644 --- a/rust/src/tx_builder/batch_tools/proposals.rs +++ b/rust/src/builders/batch_tools/proposals.rs @@ -1,9 +1,9 @@ -use std::collections::HashMap; -use crate::serialization::map_names::TxBodyNames; -use super::super::*; -use super::indexes::{UtxoIndex, AssetIndex, PolicyIndex}; use super::asset_categorizer::AssetCategorizer; +use super::indexes::{AssetIndex, PolicyIndex, UtxoIndex}; use super::witnesses_calculator::WitnessesCalculator; +use crate::serialization::map_names::TxBodyNames; +use crate::*; +use std::collections::{HashMap, HashSet}; #[derive(Clone)] pub(crate) struct TxOutputProposal { @@ -34,7 +34,9 @@ impl TxOutputProposal { pub(super) fn add_asset(&mut self, asset: &AssetIndex, policy_index: &PolicyIndex) { self.used_assets.insert(asset.clone()); - let policy = self.grouped_assets.entry(policy_index.clone()) + let policy = self + .grouped_assets + .entry(policy_index.clone()) .or_insert(HashSet::new()); policy.insert(asset.clone()); } @@ -67,9 +69,15 @@ impl TxOutputProposal { self.size = size; } - fn create_output(&self, asset_groups: &AssetCategorizer, used_utxos: &HashSet) - -> Result { - Ok(TransactionOutput::new(&self.address, &asset_groups.build_value(used_utxos, self)?)) + fn create_output( + &self, + asset_groups: &AssetCategorizer, + used_utxos: &HashSet, + ) -> Result { + Ok(TransactionOutput::new( + &self.address, + &asset_groups.build_value(used_utxos, self)?, + )) } } @@ -103,7 +111,8 @@ impl TxProposal { } pub(super) fn add_new_output(&mut self, address: &Address) { - self.tx_output_proposals.push(TxOutputProposal::new(address)); + self.tx_output_proposals + .push(TxOutputProposal::new(address)); } pub(super) fn add_asset(&mut self, asset: &AssetIndex, policy_index: &PolicyIndex) { @@ -113,7 +122,12 @@ impl TxProposal { } } - pub(super) fn add_utxo(&mut self, utxo: &UtxoIndex, ada_coins: &Coin, address: &Address) -> Result<(), JsError> { + pub(super) fn add_utxo( + &mut self, + utxo: &UtxoIndex, + ada_coins: &Coin, + address: &Address, + ) -> Result<(), JsError> { if self.used_utoxs.contains(utxo) { return Err(JsError::from_str("UTxO already used")); } @@ -143,23 +157,26 @@ impl TxProposal { self.fee = fee.clone(); } - pub(super) fn get_total_ada_for_ouputs(&self) -> Result { - self.tx_output_proposals.iter() + self.tx_output_proposals + .iter() .map(|output| output.get_total_ada()) .try_fold(Coin::zero(), |acc, ada| acc.checked_add(&ada)) } pub(super) fn get_need_ada(&self) -> Result { - let need_ada = self.get_total_ada_for_ouputs()? - .checked_add(&self.fee)?; - Ok(need_ada.checked_sub(&self.total_ada).unwrap_or(Coin::zero())) + let need_ada = self.get_total_ada_for_ouputs()?.checked_add(&self.fee)?; + Ok(need_ada + .checked_sub(&self.total_ada) + .unwrap_or(Coin::zero())) } pub(super) fn get_unused_ada(&self) -> Result { - let need_ada = self.get_total_ada_for_ouputs()? - .checked_add(&self.fee)?; - return Ok(self.total_ada.checked_sub(&need_ada).unwrap_or(Coin::zero())); + let need_ada = self.get_total_ada_for_ouputs()?.checked_add(&self.fee)?; + return Ok(self + .total_ada + .checked_sub(&need_ada) + .unwrap_or(Coin::zero())); } pub(crate) fn add_last_ada_to_last_output(&mut self) -> Result<(), JsError> { @@ -171,8 +188,11 @@ impl TxProposal { Ok(()) } - pub(crate) fn create_tx(&self, asset_groups: &AssetCategorizer, utxos: &TransactionUnspentOutputs) - -> Result { + pub(crate) fn create_tx( + &self, + asset_groups: &AssetCategorizer, + utxos: &TransactionUnspentOutputs, + ) -> Result { let mut outputs = Vec::new(); for proposal in &self.tx_output_proposals { outputs.push(proposal.create_output(asset_groups, &self.used_utoxs)?); @@ -197,4 +217,4 @@ impl TxProposal { Ok(tx) } -} \ No newline at end of file +} diff --git a/rust/src/tx_builder/batch_tools/utxo_stat.rs b/rust/src/builders/batch_tools/utxo_stat.rs similarity index 69% rename from rust/src/tx_builder/batch_tools/utxo_stat.rs rename to rust/src/builders/batch_tools/utxo_stat.rs index 5fd9071f..5bbe3f8b 100644 --- a/rust/src/tx_builder/batch_tools/utxo_stat.rs +++ b/rust/src/builders/batch_tools/utxo_stat.rs @@ -1,6 +1,6 @@ -use std::collections::{HashMap, HashSet}; +use super::indexes::{AssetIndex, PolicyIndex, UtxoIndex}; use crate::{Coin, JsError}; -use super::indexes::{UtxoIndex, AssetIndex, PolicyIndex}; +use std::collections::{HashMap, HashSet}; #[derive(Clone)] pub(super) struct UtxosStat { @@ -11,8 +11,11 @@ pub(super) struct UtxosStat { } impl UtxosStat { - pub(super) fn new(total_ada: &Coin, policy_to_asset: &HashMap>, - amounts: &Vec>) -> Result { + pub(super) fn new( + total_ada: &Coin, + policy_to_asset: &HashMap>, + amounts: &Vec>, + ) -> Result { let mut utxos_stat = UtxosStat { total_policies: 0, assets_in_policy: HashMap::new(), @@ -20,7 +23,9 @@ impl UtxosStat { ada_coins: Coin::zero(), }; for (policy_index, assets) in policy_to_asset { - utxos_stat.assets_in_policy.insert(policy_index.clone(), assets.len()); + utxos_stat + .assets_in_policy + .insert(policy_index.clone(), assets.len()); } for i in 0..amounts.len() { @@ -30,10 +35,11 @@ impl UtxosStat { let new_total = coins.checked_add(amount)?; utxos_stat.coins_in_assets.insert(asset_index, new_total); } else { - utxos_stat.coins_in_assets.insert(asset_index, amount.clone()); + utxos_stat + .coins_in_assets + .insert(asset_index, amount.clone()); } } - } utxos_stat.total_policies = policy_to_asset.len(); @@ -41,4 +47,4 @@ impl UtxosStat { Ok(utxos_stat) } -} \ No newline at end of file +} diff --git a/rust/src/tx_builder/batch_tools/witnesses_calculator.rs b/rust/src/builders/batch_tools/witnesses_calculator.rs similarity index 81% rename from rust/src/tx_builder/batch_tools/witnesses_calculator.rs rename to rust/src/builders/batch_tools/witnesses_calculator.rs index b545bdcb..26f6ca8e 100644 --- a/rust/src/tx_builder/batch_tools/witnesses_calculator.rs +++ b/rust/src/builders/batch_tools/witnesses_calculator.rs @@ -1,6 +1,7 @@ +use crate::builders::batch_tools::cbor_calculator::CborCalculator; use crate::serialization::map_names::WitnessSetNames; -use crate::tx_builder::batch_tools::cbor_calculator::CborCalculator; -use super::super::*; +use crate::*; +use std::collections::HashSet; #[derive(Clone)] pub(super) struct WitnessesCalculator { @@ -38,11 +39,15 @@ impl WitnessesCalculator { None => (), } match &addr.payment_cred().to_scripthash() { - Some(_) => return Err(JsError::from_str("Script input is not supported for send all")), - None => () + Some(_) => { + return Err(JsError::from_str( + "Script input is not supported for send all", + )) + } + None => (), } } - None => () + None => (), } match &EnterpriseAddress::from_address(address) { Some(addr) => { @@ -51,8 +56,12 @@ impl WitnessesCalculator { None => (), } match &addr.payment_cred().to_scripthash() { - Some(_) => return Err(JsError::from_str("Script input is not supported for send all")), - None => () + Some(_) => { + return Err(JsError::from_str( + "Script input is not supported for send all", + )) + } + None => (), } } None => (), @@ -64,8 +73,12 @@ impl WitnessesCalculator { None => (), } match &addr.payment_cred().to_scripthash() { - Some(_) => return Err(JsError::from_str("Script input is not supported for send all")), - None => () + Some(_) => { + return Err(JsError::from_str( + "Script input is not supported for send all", + )) + } + None => (), } } None => (), @@ -129,7 +142,8 @@ impl WitnessesCalculator { fn add_vkey(&mut self) { if self.vkeys_count == 0 { if self.used_fields.len() > 0 { - self.total_size -= CborCalculator::get_wintnesses_set_struct_size(&self.used_fields); + self.total_size -= + CborCalculator::get_wintnesses_set_struct_size(&self.used_fields); } self.used_fields.insert(WitnessSetNames::Vkeys); @@ -148,7 +162,8 @@ impl WitnessesCalculator { self.bootsraps.push(address.clone()); if self.boostrap_count == 0 { if self.used_fields.len() > 0 { - self.total_size -= CborCalculator::get_wintnesses_set_struct_size(&self.used_fields); + self.total_size -= + CborCalculator::get_wintnesses_set_struct_size(&self.used_fields); } self.used_fields.insert(WitnessSetNames::Bootstraps); @@ -162,4 +177,4 @@ impl WitnessesCalculator { self.total_size += CborCalculator::get_struct_size(self.boostrap_count); self.total_size += CborCalculator::get_boostrap_witness_size(address); } -} \ No newline at end of file +} From b54661b388b395cc1ccc403d6a9afe9f765ab8d0 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 8 Sep 2023 21:35:16 +0500 Subject: [PATCH 124/349] move fixed tx tests + fmt --- rust/src/protocol_types/fixed_tx.rs | 148 ++-------------------------- rust/src/serialization/fixed_tx.rs | 133 +++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 140 deletions(-) create mode 100644 rust/src/serialization/fixed_tx.rs diff --git a/rust/src/protocol_types/fixed_tx.rs b/rust/src/protocol_types/fixed_tx.rs index 9e258636..8733ed91 100644 --- a/rust/src/protocol_types/fixed_tx.rs +++ b/rust/src/protocol_types/fixed_tx.rs @@ -1,24 +1,22 @@ use crate::error::JsError; use crate::*; -use std::io::{Seek, SeekFrom}; #[wasm_bindgen] pub struct FixedTransaction { - body: TransactionBody, - body_bytes: Vec, + pub(crate) body: TransactionBody, + pub(crate) body_bytes: Vec, - witness_set: TransactionWitnessSet, - witness_bytes: Vec, + pub(crate) witness_set: TransactionWitnessSet, + pub(crate) witness_bytes: Vec, - is_valid: bool, + pub(crate) is_valid: bool, - auxiliary_data: Option, - auxiliary_bytes: Option>, + pub(crate) auxiliary_data: Option, + pub(crate) auxiliary_bytes: Option>, } to_from_bytes!(FixedTransaction); - #[wasm_bindgen] impl FixedTransaction { pub fn new( @@ -57,7 +55,7 @@ impl FixedTransaction { witness_bytes: raw_witness_set.to_vec(), is_valid, auxiliary_data, - auxiliary_bytes: Some(raw_auxiliary_data.to_vec()) + auxiliary_bytes: Some(raw_auxiliary_data.to_vec()), }) } @@ -114,133 +112,3 @@ impl FixedTransaction { self.auxiliary_bytes.clone() } } - -impl cbor_event::se::Serialize for FixedTransaction { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(4))?; - serializer.write_raw_bytes(&self.body_bytes)?; - serializer.write_raw_bytes(&self.witness_bytes)?; - serializer.write_special(CBORSpecial::Bool(self.is_valid))?; - match &self.auxiliary_bytes { - Some(auxiliary_bytes) => serializer.write_raw_bytes(auxiliary_bytes)?, - None => serializer.write_special(CBORSpecial::Null)?, - }; - Ok(serializer) - } -} - -impl Deserialize for FixedTransaction { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("Transaction")) - } -} - -impl DeserializeEmbeddedGroup for FixedTransaction { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - _: cbor_event::Len, - ) -> Result { - let (body, body_bytes) = - deserilized_with_orig_bytes(raw, |raw| TransactionBody::deserialize(raw)) - .map_err(|e| e.annotate("body"))?; - let (witness_set, witness_bytes) = - deserilized_with_orig_bytes(raw, |raw| TransactionWitnessSet::deserialize(raw)) - .map_err(|e| e.annotate("witness_set"))?; - let mut checked_auxiliary_data = false; - let mut auxiliary_data = None; - let mut auxiliary_bytes = None; - let is_valid = (|| -> Result<_, DeserializeError> { - match raw.cbor_type()? == CBORType::Special { - true => { - // if it's special it can be either a bool or null. if it's null, then it's empty auxiliary data, otherwise not a valid encoding - let special = raw.special()?; - if let CBORSpecial::Bool(b) = special { - return Ok(b); - } else if special == CBORSpecial::Null { - checked_auxiliary_data = true; - return Ok(true); - } else { - return Err(DeserializeFailure::ExpectedBool.into()); - } - } - false => { - let (auxiliary_data_deser, auxiliary_bytes_deser) = - deserilized_with_orig_bytes(raw, |raw| AuxiliaryData::deserialize(raw)) - .map_err(|e| e.annotate("auxiliary_data"))?; - auxiliary_data = Some(auxiliary_data_deser); - auxiliary_bytes = Some(auxiliary_bytes_deser); - // if no special symbol was detected, it must have auxiliary data - checked_auxiliary_data = true; - return Ok(true); - } - } - })() - .map_err(|e| e.annotate("is_valid"))?; - if !checked_auxiliary_data { - // this branch is reached, if the 3rd argument was a bool. then it simply follows the rules for checking auxiliary data - (auxiliary_data, auxiliary_bytes) = (|| -> Result<_, DeserializeError> { - Ok(match raw.cbor_type()? != CBORType::Special { - true => { - let (auxiliary_data_deser, auxiliary_bytes_deser) = - deserilized_with_orig_bytes(raw, |raw| AuxiliaryData::deserialize(raw))?; - (Some(auxiliary_data_deser), Some(auxiliary_bytes_deser)) - - }, - false => { - if raw.special()? != CBORSpecial::Null { - return Err(DeserializeFailure::ExpectedNull.into()); - } - (None, None) - } - }) - })() - .map_err(|e| e.annotate("auxiliary_data"))?; - } - Ok(FixedTransaction { - body, - body_bytes, - witness_set, - witness_bytes, - is_valid, - auxiliary_data, - auxiliary_bytes - }) - } -} - -fn deserilized_with_orig_bytes( - raw: &mut Deserializer, - deserilizator: fn(&mut Deserializer) -> Result, -) -> Result<(T, Vec), DeserializeError> { - let before = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); - let value = deserilizator(raw)?; - let after = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); - let bytes_read = (after - before) as usize; - raw.as_mut_ref().seek(SeekFrom::Start(before)).unwrap(); - let original_bytes = raw.as_mut_ref().fill_buf().unwrap()[..bytes_read].to_vec(); - raw.as_mut_ref().seek(SeekFrom::Start(after)).unwrap(); - Ok((value, original_bytes)) -} diff --git a/rust/src/serialization/fixed_tx.rs b/rust/src/serialization/fixed_tx.rs new file mode 100644 index 00000000..c52fd4a1 --- /dev/null +++ b/rust/src/serialization/fixed_tx.rs @@ -0,0 +1,133 @@ +use crate::*; +use std::io::SeekFrom; + +impl cbor_event::se::Serialize for FixedTransaction { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(4))?; + serializer.write_raw_bytes(&self.body_bytes)?; + serializer.write_raw_bytes(&self.witness_bytes)?; + serializer.write_special(CBORSpecial::Bool(self.is_valid))?; + match &self.auxiliary_bytes { + Some(auxiliary_bytes) => serializer.write_raw_bytes(auxiliary_bytes)?, + None => serializer.write_special(CBORSpecial::Null)?, + }; + Ok(serializer) + } +} + +impl Deserialize for FixedTransaction { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let ret = Self::deserialize_as_embedded_group(raw, len); + match len { + cbor_event::Len::Len(_) => + /* TODO: check finite len somewhere */ + { + () + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("Transaction")) + } +} + +impl DeserializeEmbeddedGroup for FixedTransaction { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + _: cbor_event::Len, + ) -> Result { + let (body, body_bytes) = + deserilized_with_orig_bytes(raw, |raw| TransactionBody::deserialize(raw)) + .map_err(|e| e.annotate("body"))?; + let (witness_set, witness_bytes) = + deserilized_with_orig_bytes(raw, |raw| TransactionWitnessSet::deserialize(raw)) + .map_err(|e| e.annotate("witness_set"))?; + let mut checked_auxiliary_data = false; + let mut auxiliary_data = None; + let mut auxiliary_bytes = None; + let is_valid = (|| -> Result<_, DeserializeError> { + match raw.cbor_type()? == CBORType::Special { + true => { + // if it's special it can be either a bool or null. if it's null, then it's empty auxiliary data, otherwise not a valid encoding + let special = raw.special()?; + if let CBORSpecial::Bool(b) = special { + return Ok(b); + } else if special == CBORSpecial::Null { + checked_auxiliary_data = true; + return Ok(true); + } else { + return Err(DeserializeFailure::ExpectedBool.into()); + } + } + false => { + let (auxiliary_data_deser, auxiliary_bytes_deser) = + deserilized_with_orig_bytes(raw, |raw| AuxiliaryData::deserialize(raw)) + .map_err(|e| e.annotate("auxiliary_data"))?; + auxiliary_data = Some(auxiliary_data_deser); + auxiliary_bytes = Some(auxiliary_bytes_deser); + // if no special symbol was detected, it must have auxiliary data + checked_auxiliary_data = true; + return Ok(true); + } + } + })() + .map_err(|e| e.annotate("is_valid"))?; + if !checked_auxiliary_data { + // this branch is reached, if the 3rd argument was a bool. then it simply follows the rules for checking auxiliary data + (auxiliary_data, auxiliary_bytes) = (|| -> Result<_, DeserializeError> { + Ok(match raw.cbor_type()? != CBORType::Special { + true => { + let (auxiliary_data_deser, auxiliary_bytes_deser) = + deserilized_with_orig_bytes(raw, |raw| { + AuxiliaryData::deserialize(raw) + })?; + (Some(auxiliary_data_deser), Some(auxiliary_bytes_deser)) + } + false => { + if raw.special()? != CBORSpecial::Null { + return Err(DeserializeFailure::ExpectedNull.into()); + } + (None, None) + } + }) + })() + .map_err(|e| e.annotate("auxiliary_data"))?; + } + Ok(FixedTransaction { + body, + body_bytes, + witness_set, + witness_bytes, + is_valid, + auxiliary_data, + auxiliary_bytes, + }) + } +} + +fn deserilized_with_orig_bytes( + raw: &mut Deserializer, + deserilizator: fn(&mut Deserializer) -> Result, +) -> Result<(T, Vec), DeserializeError> { + let before = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); + let value = deserilizator(raw)?; + let after = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); + let bytes_read = (after - before) as usize; + raw.as_mut_ref().seek(SeekFrom::Start(before)).unwrap(); + let original_bytes = raw.as_mut_ref().fill_buf().unwrap()[..bytes_read].to_vec(); + raw.as_mut_ref().seek(SeekFrom::Start(after)).unwrap(); + Ok((value, original_bytes)) +} From 890c05eaa156946c2d6134ac0e4a3c52a822c8bc Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 8 Sep 2023 21:36:05 +0500 Subject: [PATCH 125/349] certificates fmt --- .../certificates/certificate.rs | 60 +++++++++---------- .../committee_hot_key_deregistration.rs | 4 +- .../committee_hot_key_registration.rs | 5 +- .../certificates/drep_registration.rs | 6 +- .../certificates/drep_update.rs | 5 +- .../move_instantaneous_rewards_cert.rs | 2 +- .../certificates/stake_and_vote_delegation.rs | 6 +- .../certificates/stake_deregistration.rs | 4 +- .../certificates/stake_registration.rs | 6 +- .../stake_registration_and_delegation.rs | 6 +- 10 files changed, 39 insertions(+), 65 deletions(-) diff --git a/rust/src/protocol_types/certificates/certificate.rs b/rust/src/protocol_types/certificates/certificate.rs index fe842a2a..ba7827c5 100644 --- a/rust/src/protocol_types/certificates/certificate.rs +++ b/rust/src/protocol_types/certificates/certificate.rs @@ -127,28 +127,18 @@ impl Certificate { )) } - pub fn new_drep_deregistration( - drep_deregistration: &DrepDeregistration, - ) -> Self { + pub fn new_drep_deregistration(drep_deregistration: &DrepDeregistration) -> Self { Self(CertificateEnum::DrepDeregistration( drep_deregistration.clone(), )) } - pub fn new_drep_registration( - drep_registration: &DrepRegistration, - ) -> Self { - Self(CertificateEnum::DrepRegistration( - drep_registration.clone(), - )) + pub fn new_drep_registration(drep_registration: &DrepRegistration) -> Self { + Self(CertificateEnum::DrepRegistration(drep_registration.clone())) } - pub fn new_drep_update( - drep_update: &DrepUpdate, - ) -> Self { - Self(CertificateEnum::DrepUpdate( - drep_update.clone(), - )) + pub fn new_drep_update(drep_update: &DrepUpdate) -> Self { + Self(CertificateEnum::DrepUpdate(drep_update.clone())) } pub fn new_stake_and_vote_delegation( @@ -175,12 +165,8 @@ impl Certificate { )) } - pub fn new_vote_delegation( - vote_delegation: &VoteDelegation, - ) -> Self { - Self(CertificateEnum::VoteDelegation( - vote_delegation.clone(), - )) + pub fn new_vote_delegation(vote_delegation: &VoteDelegation) -> Self { + Self(CertificateEnum::VoteDelegation(vote_delegation.clone())) } pub fn new_vote_registration_and_delegation( @@ -199,23 +185,29 @@ impl Certificate { CertificateEnum::PoolRegistration(_) => CertificateKind::PoolRegistration, CertificateEnum::PoolRetirement(_) => CertificateKind::PoolRetirement, CertificateEnum::GenesisKeyDelegation(_) => CertificateKind::GenesisKeyDelegation, - CertificateEnum::MoveInstantaneousRewardsCert(_) => - CertificateKind::MoveInstantaneousRewardsCert, - CertificateEnum::CommitteeHotKeyRegistration(_) => - CertificateKind::CommitteeHotKeyRegistration, - CertificateEnum::CommitteeHotKeyDeregistration(_) => - CertificateKind::CommitteeHotKeyDeregistration, + CertificateEnum::MoveInstantaneousRewardsCert(_) => { + CertificateKind::MoveInstantaneousRewardsCert + } + CertificateEnum::CommitteeHotKeyRegistration(_) => { + CertificateKind::CommitteeHotKeyRegistration + } + CertificateEnum::CommitteeHotKeyDeregistration(_) => { + CertificateKind::CommitteeHotKeyDeregistration + } CertificateEnum::DrepDeregistration(_) => CertificateKind::DrepDeregistration, CertificateEnum::DrepRegistration(_) => CertificateKind::DrepRegistration, CertificateEnum::DrepUpdate(_) => CertificateKind::DrepUpdate, CertificateEnum::StakeAndVoteDelegation(_) => CertificateKind::StakeAndVoteDelegation, - CertificateEnum::StakeRegistrationAndDelegation(_) => - CertificateKind::StakeRegistrationAndDelegation, - CertificateEnum::StakeVoteRegistrationAndDelegation(_) => - CertificateKind::StakeVoteRegistrationAndDelegation, + CertificateEnum::StakeRegistrationAndDelegation(_) => { + CertificateKind::StakeRegistrationAndDelegation + } + CertificateEnum::StakeVoteRegistrationAndDelegation(_) => { + CertificateKind::StakeVoteRegistrationAndDelegation + } CertificateEnum::VoteDelegation(_) => CertificateKind::VoteDelegation, - CertificateEnum::VoteRegistrationAndDelegation(_) => + CertificateEnum::VoteRegistrationAndDelegation(_) => { CertificateKind::VoteRegistrationAndDelegation + } } } @@ -317,7 +309,9 @@ impl Certificate { } } - pub fn as_stake_vote_registration_and_delegation(&self) -> Option { + pub fn as_stake_vote_registration_and_delegation( + &self, + ) -> Option { match &self.0 { CertificateEnum::StakeVoteRegistrationAndDelegation(x) => Some(x.clone()), _ => None, diff --git a/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs b/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs index 3d1d4f5b..89c9447c 100644 --- a/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs +++ b/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs @@ -25,9 +25,7 @@ impl CommitteeHotKeyDeregistration { self.committee_cold_key.clone() } - pub fn new( - committee_cold_key: &Credential, - ) -> Self { + pub fn new(committee_cold_key: &Credential) -> Self { Self { committee_cold_key: committee_cold_key.clone(), } diff --git a/rust/src/protocol_types/certificates/committee_hot_key_registration.rs b/rust/src/protocol_types/certificates/committee_hot_key_registration.rs index 175c9b2c..c8751650 100644 --- a/rust/src/protocol_types/certificates/committee_hot_key_registration.rs +++ b/rust/src/protocol_types/certificates/committee_hot_key_registration.rs @@ -30,10 +30,7 @@ impl CommitteeHotKeyRegistration { self.committee_hot_key.clone() } - pub fn new( - committee_cold_key: &Credential, - committee_hot_key: &Credential, - ) -> Self { + pub fn new(committee_cold_key: &Credential, committee_hot_key: &Credential) -> Self { Self { committee_cold_key: committee_cold_key.clone(), committee_hot_key: committee_hot_key.clone(), diff --git a/rust/src/protocol_types/certificates/drep_registration.rs b/rust/src/protocol_types/certificates/drep_registration.rs index 306e93ee..ddc1ac2d 100644 --- a/rust/src/protocol_types/certificates/drep_registration.rs +++ b/rust/src/protocol_types/certificates/drep_registration.rs @@ -43,11 +43,7 @@ impl DrepRegistration { } } - pub fn new_with_anchor( - voting_credential: &Credential, - coin: &Coin, - anchor: &Anchor, - ) -> Self { + pub fn new_with_anchor(voting_credential: &Credential, coin: &Coin, anchor: &Anchor) -> Self { Self { voting_credential: voting_credential.clone(), coin: coin.clone(), diff --git a/rust/src/protocol_types/certificates/drep_update.rs b/rust/src/protocol_types/certificates/drep_update.rs index 5c8d74a6..d4427d73 100644 --- a/rust/src/protocol_types/certificates/drep_update.rs +++ b/rust/src/protocol_types/certificates/drep_update.rs @@ -37,10 +37,7 @@ impl DrepUpdate { } } - pub fn new_with_anchor( - voting_credential: &Credential, - anchor: &Anchor, - ) -> Self { + pub fn new_with_anchor(voting_credential: &Credential, anchor: &Anchor) -> Self { Self { voting_credential: voting_credential.clone(), anchor: Some(anchor.clone()), diff --git a/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs b/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs index af7488a1..196639bb 100644 --- a/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs +++ b/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs @@ -170,7 +170,7 @@ impl JsonSchema for MIRToStakeCredentials { String::from("MIRToStakeCredentials") } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - Vec::::json_schema(gen) + Vec::::json_schema(gen) } fn is_referenceable() -> bool { Vec::::is_referenceable() diff --git a/rust/src/protocol_types/certificates/stake_and_vote_delegation.rs b/rust/src/protocol_types/certificates/stake_and_vote_delegation.rs index da5f7cc0..45b264f4 100644 --- a/rust/src/protocol_types/certificates/stake_and_vote_delegation.rs +++ b/rust/src/protocol_types/certificates/stake_and_vote_delegation.rs @@ -35,11 +35,7 @@ impl StakeAndVoteDelegation { self.drep.clone() } - pub fn new( - stake_credential: &Credential, - pool_keyhash: &Ed25519KeyHash, - drep: &DRep, - ) -> Self { + pub fn new(stake_credential: &Credential, pool_keyhash: &Ed25519KeyHash, drep: &DRep) -> Self { Self { stake_credential: stake_credential.clone(), pool_keyhash: pool_keyhash.clone(), diff --git a/rust/src/protocol_types/certificates/stake_deregistration.rs b/rust/src/protocol_types/certificates/stake_deregistration.rs index 953bf058..8caf2ee0 100644 --- a/rust/src/protocol_types/certificates/stake_deregistration.rs +++ b/rust/src/protocol_types/certificates/stake_deregistration.rs @@ -15,7 +15,7 @@ use crate::*; )] pub struct StakeDeregistration { pub(crate) stake_credential: Credential, - pub(crate) coin: Option + pub(crate) coin: Option, } impl_to_from!(StakeDeregistration); @@ -40,7 +40,7 @@ impl StakeDeregistration { pub fn new_with_coin(stake_credential: &Credential, coin: &Coin) -> Self { Self { stake_credential: stake_credential.clone(), - coin: Some(coin.clone()) + coin: Some(coin.clone()), } } diff --git a/rust/src/protocol_types/certificates/stake_registration.rs b/rust/src/protocol_types/certificates/stake_registration.rs index 0d418d4e..1ef525dd 100644 --- a/rust/src/protocol_types/certificates/stake_registration.rs +++ b/rust/src/protocol_types/certificates/stake_registration.rs @@ -15,7 +15,7 @@ use crate::*; )] pub struct StakeRegistration { pub(crate) stake_credential: Credential, - pub(crate) coin: Option + pub(crate) coin: Option, } impl_to_from!(StakeRegistration); @@ -33,14 +33,14 @@ impl StakeRegistration { pub fn new(stake_credential: &Credential) -> Self { Self { stake_credential: stake_credential.clone(), - coin: None + coin: None, } } pub fn new_with_coin(stake_credential: &Credential, coin: &Coin) -> Self { Self { stake_credential: stake_credential.clone(), - coin: Some(coin.clone()) + coin: Some(coin.clone()), } } } diff --git a/rust/src/protocol_types/certificates/stake_registration_and_delegation.rs b/rust/src/protocol_types/certificates/stake_registration_and_delegation.rs index 3ccd8462..f0105bf3 100644 --- a/rust/src/protocol_types/certificates/stake_registration_and_delegation.rs +++ b/rust/src/protocol_types/certificates/stake_registration_and_delegation.rs @@ -35,11 +35,7 @@ impl StakeRegistrationAndDelegation { self.coin.clone() } - pub fn new( - stake_credential: &Credential, - pool_keyhash: &Ed25519KeyHash, - coin: &Coin, - ) -> Self { + pub fn new(stake_credential: &Credential, pool_keyhash: &Ed25519KeyHash, coin: &Coin) -> Self { Self { stake_credential: stake_credential.clone(), pool_keyhash: pool_keyhash.clone(), From 33fbeae84dda1f404997e4357cc80bdae02905d8 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 8 Sep 2023 21:36:45 +0500 Subject: [PATCH 126/349] fmt --- rust/src/protocol_types/governance/governance_action_ids.rs | 2 +- rust/src/protocol_types/governance/proposals/mod.rs | 2 +- rust/src/protocol_types/governance/voter.rs | 3 +-- rust/src/protocol_types/governance/voters.rs | 2 +- rust/src/protocol_types/mod.rs | 2 +- .../src/serialization/certificates/certificates_collection.rs | 4 ++-- rust/src/serialization/certificates/mod.rs | 4 ++-- 7 files changed, 9 insertions(+), 10 deletions(-) diff --git a/rust/src/protocol_types/governance/governance_action_ids.rs b/rust/src/protocol_types/governance/governance_action_ids.rs index bb1f50a7..8271994b 100644 --- a/rust/src/protocol_types/governance/governance_action_ids.rs +++ b/rust/src/protocol_types/governance/governance_action_ids.rs @@ -34,4 +34,4 @@ impl GovernanceActionIds { pub fn len(&self) -> usize { self.0.len() } -} \ No newline at end of file +} diff --git a/rust/src/protocol_types/governance/proposals/mod.rs b/rust/src/protocol_types/governance/proposals/mod.rs index eac460af..9a21f560 100644 --- a/rust/src/protocol_types/governance/proposals/mod.rs +++ b/rust/src/protocol_types/governance/proposals/mod.rs @@ -32,4 +32,4 @@ mod voting_proposal; pub use voting_proposal::*; mod voting_proposals; -pub use voting_proposals::*; \ No newline at end of file +pub use voting_proposals::*; diff --git a/rust/src/protocol_types/governance/voter.rs b/rust/src/protocol_types/governance/voter.rs index 55847ef4..ceca0dae 100644 --- a/rust/src/protocol_types/governance/voter.rs +++ b/rust/src/protocol_types/governance/voter.rs @@ -96,8 +96,7 @@ impl Voter { pub fn has_script_credentials(&self) -> bool { match &self.0 { - VoterEnum::ConstitutionalCommitteeHotKey(cred) => - cred.has_script_hash(), + VoterEnum::ConstitutionalCommitteeHotKey(cred) => cred.has_script_hash(), VoterEnum::DRep(cred) => cred.has_script_hash(), VoterEnum::StakingPool(_) => false, } diff --git a/rust/src/protocol_types/governance/voters.rs b/rust/src/protocol_types/governance/voters.rs index 89a1f718..8db4c401 100644 --- a/rust/src/protocol_types/governance/voters.rs +++ b/rust/src/protocol_types/governance/voters.rs @@ -34,4 +34,4 @@ impl Voters { pub fn len(&self) -> usize { self.0.len() } -} \ No newline at end of file +} diff --git a/rust/src/protocol_types/mod.rs b/rust/src/protocol_types/mod.rs index 47842485..704055f8 100644 --- a/rust/src/protocol_types/mod.rs +++ b/rust/src/protocol_types/mod.rs @@ -6,4 +6,4 @@ mod certificates; pub use certificates::*; mod governance; -pub use governance::*; \ No newline at end of file +pub use governance::*; diff --git a/rust/src/serialization/certificates/certificates_collection.rs b/rust/src/serialization/certificates/certificates_collection.rs index c10cd3f1..ee990a5d 100644 --- a/rust/src/serialization/certificates/certificates_collection.rs +++ b/rust/src/serialization/certificates/certificates_collection.rs @@ -30,7 +30,7 @@ impl Deserialize for Certificates { } Ok(()) })() - .map_err(|e| e.annotate("Certificates"))?; + .map_err(|e| e.annotate("Certificates"))?; Ok(Self(arr)) } -} \ No newline at end of file +} diff --git a/rust/src/serialization/certificates/mod.rs b/rust/src/serialization/certificates/mod.rs index 3f0e7b4b..c27dff16 100644 --- a/rust/src/serialization/certificates/mod.rs +++ b/rust/src/serialization/certificates/mod.rs @@ -1,12 +1,12 @@ mod certificate; mod certificates_collection; -mod genesis_key_delegation; -mod move_instantaneous_rewards_cert; mod committee_hot_key_deregistration; mod committee_hot_key_registration; mod drep_deregistration; mod drep_registration; mod drep_update; +mod genesis_key_delegation; +mod move_instantaneous_rewards_cert; mod pool_registration; mod pool_retirement; mod stake_and_vote_delegation; From 91554dd391fae3c7d7a00c5cffa5cf19fd020eca Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 8 Sep 2023 21:37:21 +0500 Subject: [PATCH 127/349] fmt --- rust/src/serialization/governance/anchor.rs | 2 +- .../governance/governance_action_id.rs | 16 ++++++---------- rust/src/serialization/governance/mod.rs | 2 +- rust/src/serialization/governance/voter.rs | 14 +++++++------- .../serialization/governance/voting_procedure.rs | 7 +++---- rust/src/serialization/map_names/mod.rs | 2 +- .../src/serialization/map_names/tx_body_names.rs | 2 +- .../map_names/voting_proposal_index_names.rs | 2 +- .../serialization/map_names/witness_set_names.rs | 2 +- 9 files changed, 22 insertions(+), 27 deletions(-) diff --git a/rust/src/serialization/governance/anchor.rs b/rust/src/serialization/governance/anchor.rs index dc3d93e3..488f2bb5 100644 --- a/rust/src/serialization/governance/anchor.rs +++ b/rust/src/serialization/governance/anchor.rs @@ -1,5 +1,5 @@ -use crate::*; use crate::serialization::struct_checks::check_len; +use crate::*; impl cbor_event::se::Serialize for Anchor { fn serialize<'se, W: Write>( diff --git a/rust/src/serialization/governance/governance_action_id.rs b/rust/src/serialization/governance/governance_action_id.rs index d7859fa1..9ba76a67 100644 --- a/rust/src/serialization/governance/governance_action_id.rs +++ b/rust/src/serialization/governance/governance_action_id.rs @@ -23,17 +23,14 @@ impl Deserialize for GovernanceActionId { len, "[transaction_id, gov_action_index]", )) - .into()); + .into()); } } - let transaction_id = TransactionHash::deserialize(raw).map_err( - |e| e.annotate("transaction_id") - )?; + let transaction_id = + TransactionHash::deserialize(raw).map_err(|e| e.annotate("transaction_id"))?; - let index = GovernanceActionIndex::deserialize(raw).map_err( - |e| e.annotate("index") - )?; + let index = GovernanceActionIndex::deserialize(raw).map_err(|e| e.annotate("index"))?; if let cbor_event::Len::Indefinite = len { if raw.special()? != CBORSpecial::Break { @@ -45,8 +42,7 @@ impl Deserialize for GovernanceActionId { transaction_id, index, }) - })() - .map_err(|e| e.annotate("GovernanceActionId")) + .map_err(|e| e.annotate("GovernanceActionId")) } -} \ No newline at end of file +} diff --git a/rust/src/serialization/governance/mod.rs b/rust/src/serialization/governance/mod.rs index c1c9c6b6..cf0c3176 100644 --- a/rust/src/serialization/governance/mod.rs +++ b/rust/src/serialization/governance/mod.rs @@ -17,4 +17,4 @@ mod governance_action_id; pub use governance_action_id::*; mod proposals; -pub use proposals::*; \ No newline at end of file +pub use proposals::*; diff --git a/rust/src/serialization/governance/voter.rs b/rust/src/serialization/governance/voter.rs index 56418440..79dc9ed1 100644 --- a/rust/src/serialization/governance/voter.rs +++ b/rust/src/serialization/governance/voter.rs @@ -73,15 +73,15 @@ impl Deserialize for VoterEnum { 0 => VoterEnum::ConstitutionalCommitteeHotKey(Credential(StakeCredType::Key( Ed25519KeyHash::deserialize(raw)?, ))), - 1 => VoterEnum::ConstitutionalCommitteeHotKey(Credential( - StakeCredType::Script(ScriptHash::deserialize(raw)?), - )), - 2 => VoterEnum::DRep(Credential(StakeCredType::Key( - Ed25519KeyHash::deserialize(raw)?, - ))), - 3 => VoterEnum::DRep(Credential(StakeCredType::Script( + 1 => VoterEnum::ConstitutionalCommitteeHotKey(Credential(StakeCredType::Script( ScriptHash::deserialize(raw)?, ))), + 2 => VoterEnum::DRep(Credential(StakeCredType::Key(Ed25519KeyHash::deserialize( + raw, + )?))), + 3 => VoterEnum::DRep(Credential(StakeCredType::Script(ScriptHash::deserialize( + raw, + )?))), 4 => VoterEnum::StakingPool(Ed25519KeyHash::deserialize(raw)?), n => { return Err(DeserializeFailure::FixedValuesMismatch { diff --git a/rust/src/serialization/governance/voting_procedure.rs b/rust/src/serialization/governance/voting_procedure.rs index 5ce30c10..699a18a5 100644 --- a/rust/src/serialization/governance/voting_procedure.rs +++ b/rust/src/serialization/governance/voting_procedure.rs @@ -46,14 +46,13 @@ impl Deserialize for VotingProcedure { DeserializeError::from(DeserializeFailure::FixedValuesMismatch { found: Key::Uint(n), expected: vec![Key::Uint(0), Key::Uint(1), Key::Uint(2)], - }).annotate("vote") + }) + .annotate("vote"), ) } }; - let anchor = Anchor::deserialize_nullable(raw).map_err( - |e| e.annotate("anchor") - )?; + let anchor = Anchor::deserialize_nullable(raw).map_err(|e| e.annotate("anchor"))?; if let cbor_event::Len::Indefinite = len { if raw.special()? != CBORSpecial::Break { diff --git a/rust/src/serialization/map_names/mod.rs b/rust/src/serialization/map_names/mod.rs index 2654c3bb..9231e9c1 100644 --- a/rust/src/serialization/map_names/mod.rs +++ b/rust/src/serialization/map_names/mod.rs @@ -8,4 +8,4 @@ mod certificate_index_names; pub(crate) use certificate_index_names::*; mod voting_proposal_index_names; -pub(crate) use voting_proposal_index_names::*; \ No newline at end of file +pub(crate) use voting_proposal_index_names::*; diff --git a/rust/src/serialization/map_names/tx_body_names.rs b/rust/src/serialization/map_names/tx_body_names.rs index 3cf71392..1ff80475 100644 --- a/rust/src/serialization/map_names/tx_body_names.rs +++ b/rust/src/serialization/map_names/tx_body_names.rs @@ -17,4 +17,4 @@ pub(crate) enum TxBodyNames { CollateralReturn = 16, TotalCollateral = 17, ReferenceInputs = 18, -} \ No newline at end of file +} diff --git a/rust/src/serialization/map_names/voting_proposal_index_names.rs b/rust/src/serialization/map_names/voting_proposal_index_names.rs index f1d20f0d..b5893c00 100644 --- a/rust/src/serialization/map_names/voting_proposal_index_names.rs +++ b/rust/src/serialization/map_names/voting_proposal_index_names.rs @@ -1,4 +1,4 @@ -#[derive(Eq, Hash, PartialEq, Clone, Debug , FromPrimitive, ToPrimitive)] +#[derive(Eq, Hash, PartialEq, Clone, Debug, FromPrimitive, ToPrimitive)] pub(crate) enum VotingProposalIndexNames { ParameterChangeAction = 0, HardForkInitiationAction = 1, diff --git a/rust/src/serialization/map_names/witness_set_names.rs b/rust/src/serialization/map_names/witness_set_names.rs index 26bc6631..f7af3ef6 100644 --- a/rust/src/serialization/map_names/witness_set_names.rs +++ b/rust/src/serialization/map_names/witness_set_names.rs @@ -8,4 +8,4 @@ pub(crate) enum WitnessSetNames { Redeemers = 5, PlutusScriptsV2 = 6, PlutusScriptsV3 = 7, -} \ No newline at end of file +} From 8f4149e3ceee7fe9fd9004c35689af8f1003b545 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 8 Sep 2023 21:37:49 +0500 Subject: [PATCH 128/349] fmt --- rust/src/serialization/general.rs | 4 ++-- rust/src/serialization/mod.rs | 2 ++ rust/src/serialization/ser_info/mod.rs | 2 +- rust/src/serialization/ser_info/types.rs | 2 +- rust/src/serialization/traits.rs | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/rust/src/serialization/general.rs b/rust/src/serialization/general.rs index 32b626c0..493c05ee 100644 --- a/rust/src/serialization/general.rs +++ b/rust/src/serialization/general.rs @@ -584,7 +584,7 @@ impl Deserialize for TransactionBody { read_len.read_elems(1)?; Ok(VotingProcedures::deserialize(raw)?) })() - .map_err(|e| e.annotate("voting_procedures"))?, + .map_err(|e| e.annotate("voting_procedures"))?, ); } 20 => { @@ -596,7 +596,7 @@ impl Deserialize for TransactionBody { read_len.read_elems(1)?; Ok(VotingProposals::deserialize(raw)?) })() - .map_err(|e| e.annotate("voting_proposals"))?, + .map_err(|e| e.annotate("voting_proposals"))?, ); } unknown_key => { diff --git a/rust/src/serialization/mod.rs b/rust/src/serialization/mod.rs index e1ac9e48..3a0cbd5a 100644 --- a/rust/src/serialization/mod.rs +++ b/rust/src/serialization/mod.rs @@ -18,4 +18,6 @@ pub mod traits; pub(super) use traits::*; mod struct_checks; +mod fixed_tx; + use struct_checks::*; diff --git a/rust/src/serialization/ser_info/mod.rs b/rust/src/serialization/ser_info/mod.rs index 70a69db7..fe642b39 100644 --- a/rust/src/serialization/ser_info/mod.rs +++ b/rust/src/serialization/ser_info/mod.rs @@ -1,2 +1,2 @@ mod types; -pub use types::*; \ No newline at end of file +pub use types::*; diff --git a/rust/src/serialization/ser_info/types.rs b/rust/src/serialization/ser_info/types.rs index 8da2707d..30913ad0 100644 --- a/rust/src/serialization/ser_info/types.rs +++ b/rust/src/serialization/ser_info/types.rs @@ -5,4 +5,4 @@ use crate::*; pub enum CborContainerType { Array = 0, Map = 1, -} \ No newline at end of file +} diff --git a/rust/src/serialization/traits.rs b/rust/src/serialization/traits.rs index f0a45cc8..207ef11a 100644 --- a/rust/src/serialization/traits.rs +++ b/rust/src/serialization/traits.rs @@ -76,4 +76,4 @@ impl SerializeNullable for Option { None => serializer.write_special(CBORSpecial::Null), } } -} \ No newline at end of file +} From 8cf0d0b7d3b87e066fa42b3ee72b49b3ee5de6a9 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 8 Sep 2023 21:38:53 +0500 Subject: [PATCH 129/349] move tx builder tests --- .../{test_batch.rs => batch_tools.rs} | 41 +------------------ rust/src/tests/builders/mod.rs | 4 +- rust/src/tests/builders/tx_builder.rs | 34 ++------------- 3 files changed, 7 insertions(+), 72 deletions(-) rename rust/src/tests/builders/{test_batch.rs => batch_tools.rs} (94%) diff --git a/rust/src/tests/builders/test_batch.rs b/rust/src/tests/builders/batch_tools.rs similarity index 94% rename from rust/src/tests/builders/test_batch.rs rename to rust/src/tests/builders/batch_tools.rs index bc6edb49..208fad26 100644 --- a/rust/src/tests/builders/test_batch.rs +++ b/rust/src/tests/builders/batch_tools.rs @@ -1,47 +1,8 @@ use crate::fakes::fake_policy_id; use crate::fees::{min_fee, LinearFee}; -use crate::tx_builder::tx_batch_builder::{create_send_all, TransactionBatchList}; -use crate::tx_builder::{TransactionBuilderConfig, TransactionBuilderConfigBuilder}; +use crate::tests::mock_objects::generate_address; use crate::*; -fn root_key() -> Bip32PrivateKey { - // art forum devote street sure rather head chuckle guard poverty release quote oak craft enemy - let entropy = [ - 0x0c, 0xcb, 0x74, 0xf3, 0x6b, 0x7d, 0xa1, 0x64, 0x9a, 0x81, 0x44, 0x67, 0x55, 0x22, 0xd4, - 0xd8, 0x09, 0x7c, 0x64, 0x12, - ]; - Bip32PrivateKey::from_bip39_entropy(&entropy, &[]) -} - -fn harden(index: u32) -> u32 { - index | 0x80_00_00_00 -} - -fn generate_address(index: u32) -> Address { - let spend = root_key() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(0) - .derive(index) - .to_public(); - let stake = root_key() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - let addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), - &spend_cred, - &stake_cred, - ); - addr.to_address() -} - fn generate_assets( from_policy: usize, from_asset: usize, diff --git a/rust/src/tests/builders/mod.rs b/rust/src/tests/builders/mod.rs index a32f65fc..f5be819a 100644 --- a/rust/src/tests/builders/mod.rs +++ b/rust/src/tests/builders/mod.rs @@ -1,2 +1,4 @@ +mod batch_tools; mod tx_builder; -mod test_batch; +mod voting_builder; +mod voting_proposal_builder; diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index a43f80cd..e4fea0be 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -1,4 +1,3 @@ -use super::*; use crate::fakes::{ fake_base_address, fake_bytes_32, fake_data_hash, fake_key_hash, fake_policy_id, fake_script_hash, fake_tx_hash, fake_tx_input, fake_tx_input2, fake_value, fake_value2, @@ -9,22 +8,9 @@ use crate::tests::mock_objects::{ create_tx_builder_with_fee, create_tx_builder_with_fee_and_pure_change, create_tx_builder_with_fee_and_val_size, create_tx_builder_with_key_deposit, }; -use crate::tx_builder::certificates_builder::CertificatesBuilder; -use crate::tx_builder::mint_builder::{MintBuilder, MintWitness}; -use crate::output_builder::TransactionOutputBuilder; -use crate::tx_builder::script_structs::{PlutusScriptSource, PlutusWitness, PlutusWitnesses}; -use crate::tx_builder::tx_inputs_builder::{ - InputWithScriptWitness, InputsWithScriptWitness, TxInputsBuilder, -}; -use crate::tx_builder::withdrawals_builder::WithdrawalsBuilder; -use crate::tx_builder::{ - fake_full_tx, fake_private_key, CoinSelectionStrategyCIP2, TransactionBuilder, - TransactionBuilderConfigBuilder, -}; -use crate::tx_builder_constants::TxBuilderConstants; use crate::*; + use fees::*; -use itertools::Itertools; use std::collections::{BTreeMap, HashMap, HashSet}; const MAX_TX_SIZE: u32 = 8000; @@ -143,13 +129,6 @@ fn build_tx_with_change_with_datum() { .derive(0) .derive(0) .to_public(); - let change_key = root_key_15() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(0) - .to_public(); let stake = root_key_15() .derive(harden(1852)) .derive(harden(1815)) @@ -5790,7 +5769,6 @@ fn plutus_mint_with_script_ref_test() { .unwrap(); let asset_name = AssetName::from_hex("44544e4654").unwrap(); - let asset_name2 = AssetName::from_hex("44544e4ada").unwrap(); let mut mint_builder = MintBuilder::new(); let plutus_script_source = PlutusScriptSource::new(&plutus_script); let plutus_script_source_ref = PlutusScriptSource::new_ref_input_with_lang_ver( @@ -5864,11 +5842,6 @@ fn plutus_mint_defferent_redeemers_test() { \"transaction_id\": \"f58a5bc761b1efdcf4b5684f6ad5495854a0d64b866e2f0f525d134750d3511b\", \"index\": 1 }").unwrap(); - let tx_input_ref = TransactionInput::from_json("\ - { - \"transaction_id\": \"f58a5bc7adaadadcf4b5684f6ad5495854a0d64b866e2f0f525d134750d3511b\", - \"index\": 2 - }").unwrap(); let plutus_script = plutus::PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); let redeemer = Redeemer::from_json( @@ -5900,7 +5873,6 @@ fn plutus_mint_defferent_redeemers_test() { .unwrap(); let asset_name = AssetName::from_hex("44544e4654").unwrap(); - let asset_name2 = AssetName::from_hex("44544e4ada").unwrap(); let mut mint_builder = MintBuilder::new(); let plutus_script_source = PlutusScriptSource::new(&plutus_script); let mint_witnes = MintWitness::new_plutus_script(&plutus_script_source, &redeemer); @@ -5913,7 +5885,7 @@ fn plutus_mint_defferent_redeemers_test() { let mut asset = Assets::new(); asset.insert(&asset_name, &BigNum::from(100u64)); output_assets.insert(&plutus_script.hash(), &asset); - let output_value = Value::new_with_assets(&Coin::from(50000u64), &output_assets); + let output_value = Value::new_with_assets(&Coin::from(1142150u64), &output_assets); let output = TransactionOutput::new(&output_adress, &output_value); let mut col_builder = TxInputsBuilder::new(); @@ -5923,7 +5895,7 @@ fn plutus_mint_defferent_redeemers_test() { &Value::new(&Coin::from(1000000000u64)), ); tx_builder.set_collateral(&col_builder); - tx_builder.add_output(&output); + tx_builder.add_output(&output).unwrap(); tx_builder.add_input( &output_adress, &tx_input, From 9542270786f7dcfacf70405d396e48506acbaaa9 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 8 Sep 2023 21:39:06 +0500 Subject: [PATCH 130/349] add voting builder tests --- rust/src/tests/builders/voting_builder.rs | 435 ++++++++++++++++++++++ 1 file changed, 435 insertions(+) create mode 100644 rust/src/tests/builders/voting_builder.rs diff --git a/rust/src/tests/builders/voting_builder.rs b/rust/src/tests/builders/voting_builder.rs new file mode 100644 index 00000000..069a2ecf --- /dev/null +++ b/rust/src/tests/builders/voting_builder.rs @@ -0,0 +1,435 @@ +use crate::fakes::{fake_key_hash, fake_script_hash, fake_tx_hash, fake_vkey}; +use crate::fees::min_fee_for_size; +use crate::tests::mock_objects::{ + crate_change_address, create_linear_fee, create_plutus_script, create_rich_tx_builder, +}; +use crate::*; + +#[test] +fn voting_builder_key_signers_test() { + let mut builder = VotingBuilder::new(); + let key_hash_1 = fake_key_hash(1); + let key_hash_2 = fake_key_hash(2); + let key_hash_3 = fake_key_hash(3); + let action_id_1 = GovernanceActionId::new(&fake_tx_hash(1), 1); + let action_id_2 = GovernanceActionId::new(&fake_tx_hash(2), 2); + let action_id_3 = GovernanceActionId::new(&fake_tx_hash(3), 3); + let vote = VotingProcedure::new(VoteKind::No); + let voter_1 = + Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash(&key_hash_1)); + let voter_2 = Voter::new_drep(&Credential::from_keyhash(&key_hash_2)); + let voter_3 = Voter::new_staking_pool(&key_hash_3); + builder.add(&voter_1, &action_id_1, &vote).unwrap(); + builder.add(&voter_1, &action_id_2, &vote).unwrap(); + builder.add(&voter_2, &action_id_2, &vote).unwrap(); + builder.add(&voter_3, &action_id_3, &vote).unwrap(); + + let req_signers = builder.get_required_signers(); + assert_eq!(req_signers.len(), 3); + assert!(req_signers.contains(&key_hash_1)); + assert!(req_signers.contains(&key_hash_2)); + assert!(req_signers.contains(&key_hash_3)); + assert_eq!(builder.has_plutus_scripts(), false); + + let mut tx_builder = create_rich_tx_builder(false); + tx_builder.set_voting_builder(&builder); + tx_builder + .add_change_if_needed(&crate_change_address()) + .unwrap(); + + let tx = tx_builder.build_tx().unwrap(); + let tx_len = tx.to_bytes().len(); + let vkey_size = fake_vkey().to_bytes().len(); + let rough_tx_size = tx_len + (vkey_size * 3); + + let fee_algo = create_linear_fee(44, 155381); + let approx_fee_with_wit = min_fee_for_size(rough_tx_size, &fee_algo).unwrap(); + assert!(approx_fee_with_wit.less_than(&tx.body().fee())); + + let voting_procedures = tx.body().voting_procedures().unwrap(); + let voters = voting_procedures.get_voters(); + assert_eq!(voters.len(), 3); + assert!(voters.0.contains(&voter_1)); + assert!(voters.0.contains(&voter_2)); + assert!(voters.0.contains(&voter_3)); + + let action_ids_1 = voting_procedures.get_governance_action_ids_by_voter(&voter_1); + assert_eq!(action_ids_1.len(), 2); + assert!(action_ids_1.0.contains(&action_id_1)); + assert!(action_ids_1.0.contains(&action_id_2)); + + let action_ids_2 = voting_procedures.get_governance_action_ids_by_voter(&voter_2); + assert_eq!(action_ids_2.len(), 1); + assert!(action_ids_2.0.contains(&action_id_2)); + + let action_ids_3 = voting_procedures.get_governance_action_ids_by_voter(&voter_3); + assert_eq!(action_ids_3.len(), 1); + assert!(action_ids_3.0.contains(&action_id_3)); + + let vote_1 = voting_procedures.get(&voter_1, &action_id_1).unwrap(); + assert_eq!(vote_1, vote); + + let vote_2 = voting_procedures.get(&voter_1, &action_id_2).unwrap(); + assert_eq!(vote_2, vote); + + let vote_3 = voting_procedures.get(&voter_2, &action_id_2).unwrap(); + assert_eq!(vote_3, vote); + + let vote_4 = voting_procedures.get(&voter_3, &action_id_3).unwrap(); + assert_eq!(vote_4, vote); + + let vote_5 = voting_procedures.get(&voter_3, &action_id_1); + assert_eq!(vote_5, None); +} + +#[test] +fn voting_builder_plutus_witness() { + let mut builder = VotingBuilder::new(); + let script = create_plutus_script(1, &Language::new_plutus_v2()); + let script_hash = script.hash(); + let redeemer = Redeemer::new( + &RedeemerTag::new_cert(), + &BigNum::zero(), + &PlutusData::new_empty_constr_plutus_data(&BigNum::zero()), + &ExUnits::new(&BigNum::zero(), &BigNum::zero()), + ); + let expected_redeemer = + redeemer.clone_with_index_and_tag(&BigNum::zero(), &RedeemerTag::new_vote()); + let voter = Voter::new_drep(&Credential::from_scripthash(&script_hash)); + let action_id = GovernanceActionId::new(&fake_tx_hash(1), 1); + let vote = VotingProcedure::new(VoteKind::No); + + let witness = PlutusWitness::new_without_datum(&script, &redeemer); + builder + .add_with_plutus_witness(&voter, &action_id, &vote, &witness) + .unwrap(); + + let req_signers = builder.get_required_signers(); + assert_eq!(req_signers.len(), 0); + + let witnesses = builder.get_plutus_witnesses(); + assert_eq!(witnesses.len(), 1); + let witness_from_voting_builder = witnesses.get(0); + assert_eq!(witness_from_voting_builder.datum(), None); + assert_eq!(witness_from_voting_builder.script(), Some(script.clone())); + assert_eq!( + witness_from_voting_builder.redeemer(), + expected_redeemer.clone() + ); + + let ref_inputs = builder.get_ref_inputs(); + assert_eq!(ref_inputs.len(), 0); + + assert_eq!(builder.has_plutus_scripts(), true); + + let langs = builder.get_used_plutus_lang_versions(); + assert_eq!(langs.len(), 1); + assert!(langs.contains(&Language::new_plutus_v2())); + + let mut tx_builder = create_rich_tx_builder(true); + tx_builder.set_voting_builder(&builder); + tx_builder + .add_change_if_needed(&crate_change_address()) + .unwrap(); + + let mut cost_models = TxBuilderConstants::plutus_default_cost_models(); + cost_models = cost_models.retain_language_versions(&Languages(vec![Language::new_plutus_v2()])); + + tx_builder.calc_script_data_hash(&cost_models).unwrap(); + + let tx = tx_builder.build_tx().unwrap(); + + let tx_witnesses = tx.witness_set(); + let tx_script = tx_witnesses.plutus_scripts().unwrap(); + + assert_eq!(tx_script.len(), 1); + assert_eq!(tx_script.get(0), script); + + let tx_redeemers = tx_witnesses.redeemers().unwrap(); + assert_eq!(tx_redeemers.len(), 1); + assert_eq!(tx_redeemers.get(0), expected_redeemer); + + assert_eq!(tx_witnesses.plutus_data(), None); + + assert_eq!(tx.body().reference_inputs(), None); + + let script_data_hash = hash_script_data(&tx_redeemers, &cost_models, None); + + assert_eq!(tx.body().script_data_hash(), Some(script_data_hash)); + + let voting_procedures = tx.body().voting_procedures().unwrap(); + let voters = voting_procedures.get_voters(); + assert_eq!(voters.len(), 1); + assert!(voters.0.contains(&voter)); + + let action_ids = voting_procedures.get_governance_action_ids_by_voter(&voter); + assert_eq!(action_ids.len(), 1); + assert!(action_ids.0.contains(&action_id)); + + let vote_from_tx = voting_procedures.get(&voter, &action_id).unwrap(); + assert_eq!(vote_from_tx, vote); +} + +#[test] +fn voting_builder_plutus_ref_witness() { + let mut builder = VotingBuilder::new(); + let script_hash = fake_script_hash(1); + let redeemer = Redeemer::new( + &RedeemerTag::new_cert(), + &BigNum::zero(), + &PlutusData::new_empty_constr_plutus_data(&BigNum::zero()), + &ExUnits::new(&BigNum::zero(), &BigNum::zero()), + ); + + let ref_input = TransactionInput::new(&fake_tx_hash(5), 0); + let expected_redeemer = + redeemer.clone_with_index_and_tag(&BigNum::zero(), &RedeemerTag::new_vote()); + let voter = Voter::new_drep(&Credential::from_scripthash(&script_hash)); + let action_id = GovernanceActionId::new(&fake_tx_hash(1), 1); + let vote = VotingProcedure::new(VoteKind::No); + + let script_source = PlutusScriptSource::new_ref_input_with_lang_ver( + &script_hash, + &ref_input, + &Language::new_plutus_v2(), + ); + let witness = PlutusWitness::new_with_ref_without_datum(&script_source, &redeemer); + builder + .add_with_plutus_witness(&voter, &action_id, &vote, &witness) + .unwrap(); + + let req_signers = builder.get_required_signers(); + assert_eq!(req_signers.len(), 0); + + let witnesses = builder.get_plutus_witnesses(); + assert_eq!(witnesses.len(), 1); + let witness_from_voting_builder = witnesses.get(0); + assert_eq!(witness_from_voting_builder.datum(), None); + assert_eq!(witness_from_voting_builder.script(), None); + assert_eq!( + witness_from_voting_builder.redeemer(), + expected_redeemer.clone() + ); + + let ref_inputs = builder.get_ref_inputs(); + assert_eq!(ref_inputs.len(), 1); + assert_eq!(ref_inputs.get(0), ref_input); + + assert_eq!(builder.has_plutus_scripts(), true); + + let langs = builder.get_used_plutus_lang_versions(); + assert_eq!(langs.len(), 1); + assert!(langs.contains(&Language::new_plutus_v2())); + + let mut tx_builder = create_rich_tx_builder(true); + tx_builder.set_voting_builder(&builder); + tx_builder + .add_change_if_needed(&crate_change_address()) + .unwrap(); + + let mut cost_models = TxBuilderConstants::plutus_default_cost_models(); + cost_models = cost_models.retain_language_versions(&Languages(vec![Language::new_plutus_v2()])); + + tx_builder.calc_script_data_hash(&cost_models).unwrap(); + + let tx = tx_builder.build_tx().unwrap(); + + let tx_witnesses = tx.witness_set(); + assert_eq!(tx_witnesses.plutus_scripts().unwrap().len(), 0); + + let tx_redeemers = tx_witnesses.redeemers().unwrap(); + assert_eq!(tx_redeemers.len(), 1); + assert_eq!(tx_redeemers.get(0), expected_redeemer); + + assert_eq!(tx_witnesses.plutus_data(), None); + + let tx_ref_inputs = tx.body().reference_inputs().unwrap(); + assert_eq!(tx_ref_inputs.len(), 1); + assert_eq!(tx_ref_inputs.get(0), ref_input); + + let script_data_hash = hash_script_data(&tx_redeemers, &cost_models, None); + + assert_eq!(tx.body().script_data_hash(), Some(script_data_hash)); +} + +#[test] +fn voting_builder_native_script_witness() { + let mut builder = VotingBuilder::new(); + let key_hash = fake_key_hash(10); + let native_script = NativeScript::new_script_pubkey(&ScriptPubkey::new(&key_hash)); + let script_hash = native_script.hash(); + + let voter = Voter::new_drep(&Credential::from_scripthash(&script_hash)); + let action_id = GovernanceActionId::new(&fake_tx_hash(1), 1); + let vote = VotingProcedure::new(VoteKind::No); + + let script_source = NativeScriptSource::new(&native_script); + builder + .add_with_native_script(&voter, &action_id, &vote, &script_source) + .unwrap(); + + let req_signers = builder.get_required_signers(); + assert_eq!(req_signers.len(), 1); + assert!(req_signers.contains(&key_hash)); + + let native_scripts = builder.get_native_scripts(); + assert_eq!(native_scripts.len(), 1); + assert_eq!(native_scripts.get(0), native_script); + + let witnesses = builder.get_plutus_witnesses(); + assert_eq!(witnesses.len(), 0); + + let ref_inputs = builder.get_ref_inputs(); + assert_eq!(ref_inputs.len(), 0); + + assert_eq!(builder.has_plutus_scripts(), false); + + let langs = builder.get_used_plutus_lang_versions(); + assert_eq!(langs.len(), 0); + + let mut tx_builder = create_rich_tx_builder(false); + tx_builder.set_voting_builder(&builder); + tx_builder + .add_change_if_needed(&crate_change_address()) + .unwrap(); + + let tx = tx_builder.build_tx().unwrap(); + + let tx_witnesses = tx.witness_set(); + assert_eq!(tx_witnesses.plutus_scripts(), None); + + let tx_redeemers = tx_witnesses.redeemers(); + assert_eq!(tx_redeemers, None); + assert_eq!(tx_witnesses.plutus_data(), None); + assert_eq!(tx.body().reference_inputs(), None); + assert_eq!(tx.body().script_data_hash(), None); + + let native_scripts = tx_witnesses.native_scripts().unwrap(); + assert_eq!(native_scripts.len(), 1); + assert_eq!(native_scripts.get(0), native_script); + + let voting_procedures = tx.body().voting_procedures().unwrap(); + let voters = voting_procedures.get_voters(); + assert_eq!(voters.len(), 1); + assert!(voters.0.contains(&voter)); + + let action_ids = voting_procedures.get_governance_action_ids_by_voter(&voter); + assert_eq!(action_ids.len(), 1); + assert!(action_ids.0.contains(&action_id)); + + let vote_from_tx = voting_procedures.get(&voter, &action_id).unwrap(); + assert_eq!(vote_from_tx, vote); +} + +#[test] +fn voting_builder_native_script_ref_witness() { + let mut builder = VotingBuilder::new(); + let key_hash = fake_key_hash(10); + let script_hash = fake_script_hash(1); + + let voter = Voter::new_drep(&Credential::from_scripthash(&script_hash)); + let action_id = GovernanceActionId::new(&fake_tx_hash(1), 1); + let vote = VotingProcedure::new(VoteKind::No); + + let mut script_signers = RequiredSigners::new(); + script_signers.add(&key_hash); + + let ref_input = TransactionInput::new(&fake_tx_hash(5), 0); + let script_source = + NativeScriptSource::new_ref_input(&script_hash, &ref_input, &script_signers); + builder + .add_with_native_script(&voter, &action_id, &vote, &script_source) + .unwrap(); + + let req_signers = builder.get_required_signers(); + assert_eq!(req_signers.len(), 1); + assert!(req_signers.contains(&key_hash)); + + let native_scripts = builder.get_native_scripts(); + assert_eq!(native_scripts.len(), 0); + + let witnesses = builder.get_plutus_witnesses(); + assert_eq!(witnesses.len(), 0); + + let ref_inputs = builder.get_ref_inputs(); + assert_eq!(ref_inputs.len(), 1); + assert_eq!(ref_inputs.get(0), ref_input.clone()); + + assert_eq!(builder.has_plutus_scripts(), false); + + let langs = builder.get_used_plutus_lang_versions(); + assert_eq!(langs.len(), 0); + + let mut tx_builder = create_rich_tx_builder(false); + tx_builder.set_voting_builder(&builder); + tx_builder + .add_change_if_needed(&crate_change_address()) + .unwrap(); + + let tx = tx_builder.build_tx().unwrap(); + + let tx_witnesses = tx.witness_set(); + assert_eq!(tx_witnesses.plutus_scripts(), None); + + let tx_redeemers = tx_witnesses.redeemers(); + assert_eq!(tx_redeemers, None); + assert_eq!(tx_witnesses.plutus_data(), None); + + let ref_inputs = tx.body().reference_inputs().unwrap(); + assert_eq!(ref_inputs.len(), 1); + assert_eq!(ref_inputs.get(0), ref_input); + + assert_eq!(tx.body().script_data_hash(), None); + + assert_eq!(tx_witnesses.native_scripts(), None); + + let voting_procedures = tx.body().voting_procedures().unwrap(); + let voters = voting_procedures.get_voters(); + assert_eq!(voters.len(), 1); + assert!(voters.0.contains(&voter)); + + let action_ids = voting_procedures.get_governance_action_ids_by_voter(&voter); + assert_eq!(action_ids.len(), 1); + assert!(action_ids.0.contains(&action_id)); + + let vote_from_tx = voting_procedures.get(&voter, &action_id).unwrap(); + assert_eq!(vote_from_tx, vote); +} + +#[test] +fn voting_builder_non_script_voter_error() { + let mut builder = VotingBuilder::new(); + let key_hash = fake_key_hash(10); + let voter = Voter::new_drep(&Credential::from_keyhash(&key_hash)); + let action_id = GovernanceActionId::new(&fake_tx_hash(1), 1); + let vote = VotingProcedure::new(VoteKind::No); + + let script_source = NativeScriptSource::new(&NativeScript::new_script_pubkey( + &ScriptPubkey::new(&key_hash), + )); + let result_native = builder.add_with_native_script(&voter, &action_id, &vote, &script_source); + assert!(result_native.is_err()); + + let plutus_witness = PlutusWitness::new_without_datum( + &create_plutus_script(1, &Language::new_plutus_v2()), + &Redeemer::new( + &RedeemerTag::new_cert(), + &BigNum::zero(), + &PlutusData::new_empty_constr_plutus_data(&BigNum::zero()), + &ExUnits::new(&BigNum::zero(), &BigNum::zero()), + ), + ); + let result_plutus = builder.add_with_plutus_witness(&voter, &action_id, &vote, &plutus_witness); + assert!(result_plutus.is_err()); +} + +#[test] +fn voting_builder_key_hash_error() { + let mut builder = VotingBuilder::new(); + let voter = Voter::new_drep(&Credential::from_scripthash(&fake_script_hash(1))); + let action_id = GovernanceActionId::new(&fake_tx_hash(1), 1); + let vote = VotingProcedure::new(VoteKind::No); + + let result = builder.add(&voter, &action_id, &vote); + assert!(result.is_err()); +} From b30a94e924e22641f156707974ed06ea7cf17b94 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 8 Sep 2023 21:40:18 +0500 Subject: [PATCH 131/349] fmt --- rust/src/tests/address.rs | 1 + rust/src/tests/general.rs | 1 - rust/src/tests/helpers.rs | 2 +- rust/src/tests/mod.rs | 8 +-- .../tests/protocol_types/governance/common.rs | 65 ++++++++++++++----- .../tests/protocol_types/governance/mod.rs | 2 +- .../protocol_types/governance/proposals.rs | 11 ++-- rust/src/tests/protocol_types/mod.rs | 4 +- 8 files changed, 64 insertions(+), 30 deletions(-) diff --git a/rust/src/tests/address.rs b/rust/src/tests/address.rs index 46873860..68416752 100644 --- a/rust/src/tests/address.rs +++ b/rust/src/tests/address.rs @@ -201,6 +201,7 @@ fn bip32_12_pointer() { .derive(0) .derive(0) .to_public(); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = PointerAddress::new( NetworkInfo::testnet().network_id(), diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index 4f4ae296..1a518548 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -1,5 +1,4 @@ use crate::*; -use crate::tx_builder_constants::TxBuilderConstants; #[test] fn native_script_hash() { diff --git a/rust/src/tests/helpers.rs b/rust/src/tests/helpers.rs index a6fbe831..c61ff8a2 100644 --- a/rust/src/tests/helpers.rs +++ b/rust/src/tests/helpers.rs @@ -1,3 +1,3 @@ pub(crate) fn harden(index: u32) -> u32 { index | 0x80_00_00_00 -} \ No newline at end of file +} diff --git a/rust/src/tests/mod.rs b/rust/src/tests/mod.rs index 3dc72167..33340fca 100644 --- a/rust/src/tests/mod.rs +++ b/rust/src/tests/mod.rs @@ -1,7 +1,7 @@ -mod serialization; -mod general; mod address; +mod builders; +mod general; +mod helpers; mod mock_objects; mod protocol_types; -mod builders; -mod helpers; \ No newline at end of file +mod serialization; diff --git a/rust/src/tests/protocol_types/governance/common.rs b/rust/src/tests/protocol_types/governance/common.rs index 7429cf24..460f4d27 100644 --- a/rust/src/tests/protocol_types/governance/common.rs +++ b/rust/src/tests/protocol_types/governance/common.rs @@ -1,6 +1,6 @@ -use crate::*; use crate::fakes::{fake_anchor_data_hash, fake_key_hash, fake_script_hash, fake_tx_hash}; use crate::tests::mock_objects::create_anchor; +use crate::*; #[test] fn drep_abstain_setters_getters_test() { @@ -40,10 +40,7 @@ fn drep_script_hash_setters_getters_test() { fn anchor_setters_getters_test() { let data_hash = fake_anchor_data_hash(1); let url = URL::new("https://example.com".to_string()).unwrap(); - let anchor = Anchor::new( - &url, - &data_hash, - ); + let anchor = Anchor::new(&url, &data_hash); assert_eq!(anchor.url(), url); assert_eq!(anchor.anchor_data_hash(), data_hash); } @@ -79,7 +76,10 @@ fn voter_drep_key_hash_setters_getters_test() { let key_hash = fake_key_hash(1); let voter = Voter::new_drep(&Credential::from_keyhash(&key_hash)); assert_eq!(voter.kind(), VoterKind::DRepKeyHash); - assert_eq!(voter.to_drep_cred(), Some(Credential::from_keyhash(&key_hash))); + assert_eq!( + voter.to_drep_cred(), + Some(Credential::from_keyhash(&key_hash)) + ); assert_eq!(voter.to_staking_pool_key_hash(), None); assert_eq!(voter.to_constitutional_committee_hot_cred(), None); assert_eq!(voter.has_script_credentials(), false); @@ -91,7 +91,10 @@ fn voter_drep_script_hash_setters_getters_test() { let script_hash = fake_script_hash(1); let voter = Voter::new_drep(&Credential::from_scripthash(&script_hash)); assert_eq!(voter.kind(), VoterKind::DRepScriptHash); - assert_eq!(voter.to_drep_cred(), Some(Credential::from_scripthash(&script_hash))); + assert_eq!( + voter.to_drep_cred(), + Some(Credential::from_scripthash(&script_hash)) + ); assert_eq!(voter.to_staking_pool_key_hash(), None); assert_eq!(voter.to_constitutional_committee_hot_cred(), None); assert_eq!(voter.has_script_credentials(), true); @@ -103,7 +106,10 @@ fn voter_constitutional_committee_hot_key_hash_setters_getters_test() { let key_hash = fake_key_hash(1); let voter = Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash(&key_hash)); assert_eq!(voter.kind(), VoterKind::ConstitutionalCommitteeHotKeyHash); - assert_eq!(voter.to_constitutional_committee_hot_cred(), Some(Credential::from_keyhash(&key_hash))); + assert_eq!( + voter.to_constitutional_committee_hot_cred(), + Some(Credential::from_keyhash(&key_hash)) + ); assert_eq!(voter.to_staking_pool_key_hash(), None); assert_eq!(voter.to_drep_cred(), None); assert_eq!(voter.has_script_credentials(), false); @@ -113,9 +119,16 @@ fn voter_constitutional_committee_hot_key_hash_setters_getters_test() { #[test] fn voter_constitutional_committee_hot_script_hash_setters_getters_test() { let script_hash = fake_script_hash(1); - let voter = Voter::new_constitutional_committee_hot_key(&Credential::from_scripthash(&script_hash)); - assert_eq!(voter.kind(), VoterKind::ConstitutionalCommitteeHotScriptHash); - assert_eq!(voter.to_constitutional_committee_hot_cred(), Some(Credential::from_scripthash(&script_hash))); + let voter = + Voter::new_constitutional_committee_hot_key(&Credential::from_scripthash(&script_hash)); + assert_eq!( + voter.kind(), + VoterKind::ConstitutionalCommitteeHotScriptHash + ); + assert_eq!( + voter.to_constitutional_committee_hot_cred(), + Some(Credential::from_scripthash(&script_hash)) + ); assert_eq!(voter.to_staking_pool_key_hash(), None); assert_eq!(voter.to_drep_cred(), None); assert_eq!(voter.has_script_credentials(), true); @@ -197,12 +210,30 @@ fn voting_procedures_setters_getters_test() { voting_procedures.insert(&voter_2, &governance_action_id_2, &voting_procedure_2); voting_procedures.insert(&voter_2, &governance_action_id_3, &voting_procedure_3); - assert_eq!(voting_procedures.get(&voter_1, &governance_action_id_1), Some(voting_procedure_1)); - assert_eq!(voting_procedures.get(&voter_2, &governance_action_id_2), Some(voting_procedure_2)); - assert_eq!(voting_procedures.get(&voter_2, &governance_action_id_3), Some(voting_procedure_3)); - assert_eq!(voting_procedures.get(&voter_1, &governance_action_id_2), None); - assert_eq!(voting_procedures.get(&voter_1, &governance_action_id_3), None); - assert_eq!(voting_procedures.get(&voter_2, &governance_action_id_1), None); + assert_eq!( + voting_procedures.get(&voter_1, &governance_action_id_1), + Some(voting_procedure_1) + ); + assert_eq!( + voting_procedures.get(&voter_2, &governance_action_id_2), + Some(voting_procedure_2) + ); + assert_eq!( + voting_procedures.get(&voter_2, &governance_action_id_3), + Some(voting_procedure_3) + ); + assert_eq!( + voting_procedures.get(&voter_1, &governance_action_id_2), + None + ); + assert_eq!( + voting_procedures.get(&voter_1, &governance_action_id_3), + None + ); + assert_eq!( + voting_procedures.get(&voter_2, &governance_action_id_1), + None + ); let voters = voting_procedures.get_voters(); assert_eq!(voters.len(), 2); diff --git a/rust/src/tests/protocol_types/governance/mod.rs b/rust/src/tests/protocol_types/governance/mod.rs index 4681bb17..70de6435 100644 --- a/rust/src/tests/protocol_types/governance/mod.rs +++ b/rust/src/tests/protocol_types/governance/mod.rs @@ -1,2 +1,2 @@ mod common; -mod proposals; \ No newline at end of file +mod proposals; diff --git a/rust/src/tests/protocol_types/governance/proposals.rs b/rust/src/tests/protocol_types/governance/proposals.rs index d2706a28..801cb12a 100644 --- a/rust/src/tests/protocol_types/governance/proposals.rs +++ b/rust/src/tests/protocol_types/governance/proposals.rs @@ -149,13 +149,16 @@ fn treasury_withdrawals_proposal() { #[test] fn voting_proposals_setters_getters_test() { - let action_id = create_action_id(); let mut proposals = VotingProposals::new(); let no_confidence_proposal = NoConfidenceProposal::new(); let parameter_change_proposal = ParameterChangeProposal::new(&crate_full_protocol_param_update()); - proposals.add(&VotingProposal::new_no_confidence_proposal(&no_confidence_proposal)); - proposals.add(&VotingProposal::new_parameter_change_proposal(¶meter_change_proposal)); + proposals.add(&VotingProposal::new_no_confidence_proposal( + &no_confidence_proposal, + )); + proposals.add(&VotingProposal::new_parameter_change_proposal( + ¶meter_change_proposal, + )); assert_eq!(proposals.len(), 2); assert_eq!( proposals.get(0), @@ -165,4 +168,4 @@ fn voting_proposals_setters_getters_test() { proposals.get(1), VotingProposal::new_parameter_change_proposal(¶meter_change_proposal) ); -} \ No newline at end of file +} diff --git a/rust/src/tests/protocol_types/mod.rs b/rust/src/tests/protocol_types/mod.rs index 0e06482b..0bc1c656 100644 --- a/rust/src/tests/protocol_types/mod.rs +++ b/rust/src/tests/protocol_types/mod.rs @@ -1,3 +1,3 @@ -mod fixed_tx; mod certificates; -mod governance; \ No newline at end of file +mod fixed_tx; +mod governance; From 24f07ffbdf3f055196d188b6ea699b4ac6a754fc Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 8 Sep 2023 21:40:30 +0500 Subject: [PATCH 132/349] add new mocks --- rust/src/tests/mock_objects.rs | 94 ++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 5 deletions(-) diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/mock_objects.rs index ad58cb59..ca78a647 100644 --- a/rust/src/tests/mock_objects.rs +++ b/rust/src/tests/mock_objects.rs @@ -1,13 +1,49 @@ -use crate::fakes::{fake_anchor_data_hash, fake_key_hash, fake_pool_metadata_hash, fake_tx_hash, fake_vrf_key_hash}; -use crate::*; +use crate::fakes::{ + fake_anchor_data_hash, fake_key_hash, fake_pool_metadata_hash, fake_tx_hash, fake_vrf_key_hash, +}; use crate::fees::LinearFee; -use crate::tx_builder::{TransactionBuilder, TransactionBuilderConfigBuilder}; +use crate::tests::helpers::harden; +use crate::*; const MAX_VALUE_SIZE: u32 = 4000; const MAX_TX_SIZE: u32 = 8000; // might be out of date but suffices for our tests -// this is what is used in mainnet + // this is what is used in mainnet static COINS_PER_UTXO_WORD: u64 = 34_482; +pub(crate) fn root_key() -> Bip32PrivateKey { + // art forum devote street sure rather head chuckle guard poverty release quote oak craft enemy + let entropy = [ + 0x0c, 0xcb, 0x74, 0xf3, 0x6b, 0x7d, 0xa1, 0x64, 0x9a, 0x81, 0x44, 0x67, 0x55, 0x22, 0xd4, + 0xd8, 0x09, 0x7c, 0x64, 0x12, + ]; + Bip32PrivateKey::from_bip39_entropy(&entropy, &[]) +} + +pub(crate) fn generate_address(index: u32) -> Address { + let spend = root_key() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(index) + .to_public(); + let stake = root_key() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ); + addr.to_address() +} + pub(crate) fn crate_full_protocol_param_update() -> ProtocolParamUpdate { ProtocolParamUpdate { minfee_a: Some(Coin::from(44_444u32)), @@ -175,7 +211,9 @@ pub(crate) fn create_tx_builder_with_fee(linear_fee: &LinearFee) -> TransactionB create_tx_builder(linear_fee, 8, 1, 1) } -pub(crate) fn create_tx_builder_with_fee_and_pure_change(linear_fee: &LinearFee) -> TransactionBuilder { +pub(crate) fn create_tx_builder_with_fee_and_pure_change( + linear_fee: &LinearFee, +) -> TransactionBuilder { TransactionBuilder::new( &TransactionBuilderConfigBuilder::new() .fee_algo(linear_fee) @@ -198,3 +236,49 @@ pub(crate) fn create_tx_builder_with_key_deposit(deposit: u64) -> TransactionBui pub(crate) fn create_default_tx_builder() -> TransactionBuilder { create_tx_builder_with_fee(&create_default_linear_fee()) } + +pub(crate) fn crate_change_address() -> Address { + let spend = root_key() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(0) + .to_public(); + let stake = root_key() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let addr = BaseAddress::new( + NetworkInfo::testnet().network_id(), + &spend_cred, + &stake_cred, + ); + addr.to_address() +} + +pub(crate) fn create_rich_tx_builder(with_collateral: bool) -> TransactionBuilder { + let mut tx_builder = create_reallistic_tx_builder(); + let input = TransactionInput::new(&fake_tx_hash(1), 0); + let address = generate_address(1); + let mut input_builder = TxInputsBuilder::new(); + input_builder.add_input(&address, &input, &Value::new(&Coin::from(u64::MAX / 2))); + tx_builder.set_inputs(&input_builder); + if with_collateral { + tx_builder.set_collateral(&input_builder); + } + + tx_builder +} + +pub(crate) fn create_plutus_script(x: u8, lang: &Language) -> PlutusScript { + let mut bytes = hex::decode("4e4d01000033222220051200120011").unwrap(); + let pos = bytes.len() - 1; + bytes[pos] = x; + PlutusScript::from_bytes_with_version(bytes, lang).unwrap() +} From 7eca123bb8888cf3bc9491be9475e5a24276ecf3 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 8 Sep 2023 21:40:54 +0500 Subject: [PATCH 133/349] fmt --- rust/src/tests/serialization/certificates.rs | 17 +++++---------- .../tests/serialization/governance/common.rs | 21 ++++++------------- .../src/tests/serialization/governance/mod.rs | 2 +- .../serialization/governance/proposals.rs | 14 ++++++------- rust/src/tests/serialization/mod.rs | 2 +- 5 files changed, 20 insertions(+), 36 deletions(-) diff --git a/rust/src/tests/serialization/certificates.rs b/rust/src/tests/serialization/certificates.rs index 776c736e..ee4a1bdb 100644 --- a/rust/src/tests/serialization/certificates.rs +++ b/rust/src/tests/serialization/certificates.rs @@ -35,8 +35,7 @@ macro_rules! to_from_test { #[test] fn committee_hot_key_deregistration_key_hash_ser_round_trip() { - let cert = - CommitteeHotKeyDeregistration::new(&Credential::from_keyhash(&fake_key_hash(1))); + let cert = CommitteeHotKeyDeregistration::new(&Credential::from_keyhash(&fake_key_hash(1))); let cert_wrapped = Certificate::new_committee_hot_key_deregistration(&cert); to_from_test!(CommitteeHotKeyDeregistration, cert, cert_wrapped); assert_eq!( @@ -120,8 +119,7 @@ fn drep_update_ser_round_trip() { fn drep_update_with_anchor_ser_round_trip() { let url = URL::new("https://iohk.io".to_string()).unwrap(); let anchor = Anchor::new(&url, &fake_anchor_data_hash(255)); - let cert = - DrepUpdate::new_with_anchor(&Credential::from_keyhash(&fake_key_hash(1)), &anchor); + let cert = DrepUpdate::new_with_anchor(&Credential::from_keyhash(&fake_key_hash(1)), &anchor); let cert_wrapped = Certificate::new_drep_update(&cert); to_from_test!(DrepUpdate, cert, cert_wrapped); assert_eq!(cert, cert_wrapped.as_drep_update().unwrap()); @@ -330,10 +328,7 @@ fn stake_vote_registration_and_delegation_ser_round_trip() { #[test] fn vote_delegation_ser_round_trip() { let drep = DRep::new_key_hash(&fake_key_hash(3)); - let cert = VoteDelegation::new( - &Credential::from_keyhash(&fake_key_hash(1)), - &drep - ); + let cert = VoteDelegation::new(&Credential::from_keyhash(&fake_key_hash(1)), &drep); let cert_wrapped = Certificate::new_vote_delegation(&cert); to_from_test!(VoteDelegation, cert, cert_wrapped); assert_eq!(cert, cert_wrapped.as_vote_delegation().unwrap()); @@ -351,8 +346,6 @@ fn vote_registration_and_delegation_ser_round_trip() { to_from_test!(VoteRegistrationAndDelegation, cert, cert_wrapped); assert_eq!( cert, - cert_wrapped - .as_vote_registration_and_delegation() - .unwrap() + cert_wrapped.as_vote_registration_and_delegation().unwrap() ); -} \ No newline at end of file +} diff --git a/rust/src/tests/serialization/governance/common.rs b/rust/src/tests/serialization/governance/common.rs index 8d5f5fda..35b2745c 100644 --- a/rust/src/tests/serialization/governance/common.rs +++ b/rust/src/tests/serialization/governance/common.rs @@ -92,9 +92,8 @@ fn governance_action_id_ser_round_trip() { #[test] fn voter_constitutional_committee_hot_key_hash_ser_round_trip() { - let voter = Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash( - &fake_key_hash(1), - )); + let voter = + Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash(&fake_key_hash(1))); let cbor = voter.to_bytes(); let cbor_hex = voter.to_hex(); @@ -223,9 +222,7 @@ fn voting_procedures_single_item_ser_round_trip() { let mut voting_procedures = VotingProcedures::new(); voting_procedures.insert( - &Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash( - &fake_key_hash(1), - )), + &Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash(&fake_key_hash(1))), &GovernanceActionId::new(&fake_tx_hash(1), GovernanceActionIndex::from(42u32)), &VotingProcedure::new(VoteKind::Yes), ); @@ -253,25 +250,19 @@ fn voting_procedures_muiltiple_items_ser_round_trip() { let mut voting_procedures = VotingProcedures::new(); voting_procedures.insert( - &Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash( - &fake_key_hash(1), - )), + &Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash(&fake_key_hash(1))), &GovernanceActionId::new(&fake_tx_hash(1), GovernanceActionIndex::from(42u32)), &VotingProcedure::new(VoteKind::Yes), ); voting_procedures.insert( - &Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash( - &fake_key_hash(2), - )), + &Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash(&fake_key_hash(2))), &GovernanceActionId::new(&fake_tx_hash(2), GovernanceActionIndex::from(43u32)), &VotingProcedure::new(VoteKind::No), ); voting_procedures.insert( - &Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash( - &fake_key_hash(3), - )), + &Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash(&fake_key_hash(3))), &GovernanceActionId::new(&fake_tx_hash(3), GovernanceActionIndex::from(44u32)), &VotingProcedure::new(VoteKind::Abstain), ); diff --git a/rust/src/tests/serialization/governance/mod.rs b/rust/src/tests/serialization/governance/mod.rs index 8035a1a2..65163834 100644 --- a/rust/src/tests/serialization/governance/mod.rs +++ b/rust/src/tests/serialization/governance/mod.rs @@ -1,2 +1,2 @@ pub mod common; -pub mod proposals; \ No newline at end of file +pub mod proposals; diff --git a/rust/src/tests/serialization/governance/proposals.rs b/rust/src/tests/serialization/governance/proposals.rs index 10620573..53c973ed 100644 --- a/rust/src/tests/serialization/governance/proposals.rs +++ b/rust/src/tests/serialization/governance/proposals.rs @@ -1,6 +1,6 @@ use crate::fakes::{fake_anchor_data_hash, fake_key_hash, fake_script_hash, fake_tx_hash}; -use crate::*; use crate::tests::mock_objects::crate_full_protocol_param_update; +use crate::*; macro_rules! to_from_test { ($proposal_type: ty, $variable_name: ident, $variable_wrapped_name: ident) => { @@ -52,8 +52,7 @@ fn committee_ser_round_trip() { #[test] fn committee_empty_ser_round_trip() { - let committee = - Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); + let committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); let cbor = committee.to_bytes(); let cbor_hex = committee.to_hex(); @@ -271,8 +270,7 @@ fn parameter_change_proposal_ser_round_trip() { fn parameter_change_proposal_with_action_id_ser_round_trip() { let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); let parameters_update = crate_full_protocol_param_update(); - let proposal = - ParameterChangeProposal::new_with_action_id(&action_id, ¶meters_update); + let proposal = ParameterChangeProposal::new_with_action_id(&action_id, ¶meters_update); let proposal_wrapped = VotingProposal::new_parameter_change_proposal(&proposal); to_from_test!(ParameterChangeProposal, proposal, proposal_wrapped); assert_eq!( @@ -326,7 +324,9 @@ fn voting_proposals_ser_round_trip() { let proposal2 = NoConfidenceProposal::new(); let proposal3 = InfoProposal::new(); - proposals.add(&VotingProposal::new_treasury_withdrawals_proposal(&proposal1)); + proposals.add(&VotingProposal::new_treasury_withdrawals_proposal( + &proposal1, + )); proposals.add(&VotingProposal::new_no_confidence_proposal(&proposal2)); proposals.add(&VotingProposal::new_info_proposal(&proposal3)); @@ -337,4 +337,4 @@ fn voting_proposals_ser_round_trip() { assert_eq!(proposals, VotingProposals::from_bytes(cbor).unwrap()); assert_eq!(proposals, VotingProposals::from_hex(&cbor_hex).unwrap()); assert_eq!(proposals, VotingProposals::from_json(&json).unwrap()); -} \ No newline at end of file +} diff --git a/rust/src/tests/serialization/mod.rs b/rust/src/tests/serialization/mod.rs index ba473309..b05029ea 100644 --- a/rust/src/tests/serialization/mod.rs +++ b/rust/src/tests/serialization/mod.rs @@ -1,2 +1,2 @@ pub mod certificates; -pub mod governance; \ No newline at end of file +pub mod governance; From 15beef13eaf7ffb39f06ab35f52d5e4b993fa59d Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 9 Sep 2023 18:06:49 +0500 Subject: [PATCH 134/349] add voting proposal builder tests --- rust/src/builders/voting_proposal_builder.rs | 4 +- rust/src/lib.rs | 10 +- rust/src/tests/builders/voting_builder.rs | 12 +- .../tests/builders/voting_proposal_builder.rs | 330 ++++++++++++++++++ rust/src/tests/mock_objects.rs | 63 +++- 5 files changed, 405 insertions(+), 14 deletions(-) create mode 100644 rust/src/tests/builders/voting_proposal_builder.rs diff --git a/rust/src/builders/voting_proposal_builder.rs b/rust/src/builders/voting_proposal_builder.rs index dd28f691..8611ec52 100644 --- a/rust/src/builders/voting_proposal_builder.rs +++ b/rust/src/builders/voting_proposal_builder.rs @@ -15,8 +15,8 @@ impl VotingProposalBuilder { } } - pub fn add(&mut self, proposal: VotingProposal) -> Result<(), JsError> { - self.votes.insert(proposal, None); + pub fn add(&mut self, proposal: &VotingProposal) -> Result<(), JsError> { + self.votes.insert(proposal.clone(), None); Ok(()) } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index c4788c0a..4aef7874 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -180,7 +180,7 @@ type GovernanceActionIndex = u32; #[derive( Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, )] -pub struct TransactionInputs(Vec); +pub struct TransactionInputs(pub(crate) Vec); impl_to_from!(TransactionInputs); @@ -514,6 +514,14 @@ impl TransactionBody { self.voting_procedures.clone() } + pub fn set_voting_proposals(&mut self, voting_proposals: &VotingProposals) { + self.voting_proposals = Some(voting_proposals.clone()); + } + + pub fn voting_proposals(&self) -> Option { + self.voting_proposals.clone() + } + /// !!! DEPRECATED !!! /// This constructor uses outdated slot number format for the ttl value. /// Use `.new_tx_body` and then `.set_ttl` instead diff --git a/rust/src/tests/builders/voting_builder.rs b/rust/src/tests/builders/voting_builder.rs index 069a2ecf..eefd4932 100644 --- a/rust/src/tests/builders/voting_builder.rs +++ b/rust/src/tests/builders/voting_builder.rs @@ -1,7 +1,7 @@ use crate::fakes::{fake_key_hash, fake_script_hash, fake_tx_hash, fake_vkey}; use crate::fees::min_fee_for_size; use crate::tests::mock_objects::{ - crate_change_address, create_linear_fee, create_plutus_script, create_rich_tx_builder, + create_change_address, create_linear_fee, create_plutus_script, create_rich_tx_builder, }; use crate::*; @@ -34,7 +34,7 @@ fn voting_builder_key_signers_test() { let mut tx_builder = create_rich_tx_builder(false); tx_builder.set_voting_builder(&builder); tx_builder - .add_change_if_needed(&crate_change_address()) + .add_change_if_needed(&create_change_address()) .unwrap(); let tx = tx_builder.build_tx().unwrap(); @@ -129,7 +129,7 @@ fn voting_builder_plutus_witness() { let mut tx_builder = create_rich_tx_builder(true); tx_builder.set_voting_builder(&builder); tx_builder - .add_change_if_needed(&crate_change_address()) + .add_change_if_needed(&create_change_address()) .unwrap(); let mut cost_models = TxBuilderConstants::plutus_default_cost_models(); @@ -224,7 +224,7 @@ fn voting_builder_plutus_ref_witness() { let mut tx_builder = create_rich_tx_builder(true); tx_builder.set_voting_builder(&builder); tx_builder - .add_change_if_needed(&crate_change_address()) + .add_change_if_needed(&create_change_address()) .unwrap(); let mut cost_models = TxBuilderConstants::plutus_default_cost_models(); @@ -290,7 +290,7 @@ fn voting_builder_native_script_witness() { let mut tx_builder = create_rich_tx_builder(false); tx_builder.set_voting_builder(&builder); tx_builder - .add_change_if_needed(&crate_change_address()) + .add_change_if_needed(&create_change_address()) .unwrap(); let tx = tx_builder.build_tx().unwrap(); @@ -363,7 +363,7 @@ fn voting_builder_native_script_ref_witness() { let mut tx_builder = create_rich_tx_builder(false); tx_builder.set_voting_builder(&builder); tx_builder - .add_change_if_needed(&crate_change_address()) + .add_change_if_needed(&create_change_address()) .unwrap(); let tx = tx_builder.build_tx().unwrap(); diff --git a/rust/src/tests/builders/voting_proposal_builder.rs b/rust/src/tests/builders/voting_proposal_builder.rs new file mode 100644 index 00000000..4e591319 --- /dev/null +++ b/rust/src/tests/builders/voting_proposal_builder.rs @@ -0,0 +1,330 @@ +use crate::*; +use crate::fakes::{fake_key_hash, fake_script_hash, fake_tx_hash}; +use crate::tests::mock_objects::{crate_full_protocol_param_update, create_anchor, create_change_address, create_plutus_script, create_tx_builder_with_amount_and_deposit_params}; + +fn total_tx_output_with_fee(tx: &Transaction) -> Coin { + let mut total = Coin::zero(); + for output in &tx.body().outputs() { + total = total.checked_add(&output.amount().coin()).unwrap(); + } + + total.checked_add(&tx.body().fee()).unwrap() +} + +#[test] +fn voting_proposal_builder_one_proposal() { + let proposal_deposit = Coin::from(1000u64); + let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); + let proposal = + HardForkInitiationProposal::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); + let mut builder = VotingProposalBuilder::new(); + let wrapped_proposal = VotingProposal::new_hard_fork_initiation_proposal(&proposal); + builder.add(&wrapped_proposal).unwrap(); + + let witnesses = builder.get_plutus_witnesses(); + assert_eq!(witnesses.len(), 0); + + let inputs = builder.get_ref_inputs(); + assert_eq!(inputs.len(), 0); + + assert_eq!(builder.has_plutus_scripts(), false); + assert_eq!(builder.get_total_deposit(&proposal_deposit).unwrap(), proposal_deposit.clone()); + + let initial_amount = 1000000000u64; + let mut tx_builder = create_tx_builder_with_amount_and_deposit_params( + initial_amount, + 500, + 500, + proposal_deposit.into(), + false); + + tx_builder.set_voting_proposal_builder(&builder); + tx_builder.add_change_if_needed(&create_change_address()).unwrap(); + + let tx = tx_builder.build_tx().unwrap(); + + let voting_proposals = tx.body().voting_proposals().unwrap(); + assert_eq!(voting_proposals.len(), 1); + assert_eq!(voting_proposals.get(0), wrapped_proposal); + + let mut total_out = total_tx_output_with_fee(&tx); + total_out = total_out.checked_add(&proposal_deposit).unwrap(); + assert_eq!(total_out, Coin::from(initial_amount)); +} + +#[test] +fn voting_proposal_builder_all_proposals() { + let proposal_deposit = Coin::from(1000u64); + let total_deposit = proposal_deposit.checked_mul(&Coin::from(7u64)).unwrap(); + + let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); + let hf_proposal = + HardForkInitiationProposal::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); + let mut builder = VotingProposalBuilder::new(); + let wrapped_hf_proposal = VotingProposal::new_hard_fork_initiation_proposal(&hf_proposal); + builder.add(&wrapped_hf_proposal).unwrap(); + + let mut committee = + Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); + committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); + let mut members_to_remove = StakeCredentials::new(); + members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); + let committee_proposal = NewCommitteeProposal::new(&committee, &members_to_remove); + let wrapped_committee_proposal = VotingProposal::new_new_committee_proposal(&committee_proposal); + builder.add(&wrapped_committee_proposal).unwrap(); + + let anchor = create_anchor(); + let constitution = Constitution::new(&anchor); + let constitution_proposal = NewConstitutionProposal::new(&constitution); + let wrapped_constitution_proposal = VotingProposal::new_new_constitution_proposal(&constitution_proposal); + builder.add(&wrapped_constitution_proposal).unwrap(); + + let no_conf_proposal = NoConfidenceProposal::new(); + let wrapped_no_conf_proposal = VotingProposal::new_no_confidence_proposal(&no_conf_proposal); + builder.add(&wrapped_no_conf_proposal).unwrap(); + + let parameters_update = crate_full_protocol_param_update(); + let pp_update_proposal = ParameterChangeProposal::new(¶meters_update); + let wrapped_pp_update_proposal = VotingProposal::new_parameter_change_proposal(&pp_update_proposal); + builder.add(&wrapped_pp_update_proposal).unwrap(); + + let mut withdrawals = TreasuryWithdrawals::new(); + let addr1 = RewardAddress::new(1, &Credential::from_keyhash(&fake_key_hash(1))); + withdrawals.insert(&addr1, &Coin::from(1u32)); + let withdrawal_proposal = TreasuryWithdrawalsProposal::new(&withdrawals); + let wrapped_withdrawal_proposal = VotingProposal::new_treasury_withdrawals_proposal(&withdrawal_proposal); + builder.add(&wrapped_withdrawal_proposal).unwrap(); + + let info_proposal = InfoProposal::new(); + let wrapped_info_proposal = VotingProposal::new_info_proposal(&info_proposal); + builder.add(&wrapped_info_proposal).unwrap(); + + let witnesses = builder.get_plutus_witnesses(); + assert_eq!(witnesses.len(), 0); + + let inputs = builder.get_ref_inputs(); + assert_eq!(inputs.len(), 0); + + assert_eq!(builder.has_plutus_scripts(), false); + assert_eq!(builder.get_total_deposit(&proposal_deposit).unwrap(), total_deposit.clone()); + + let initial_amount = 1000000000u64; + let mut tx_builder = create_tx_builder_with_amount_and_deposit_params( + initial_amount, + 500, + 500, + proposal_deposit.into(), + false); + + tx_builder.set_voting_proposal_builder(&builder); + tx_builder.add_change_if_needed(&create_change_address()).unwrap(); + + let tx = tx_builder.build_tx().unwrap(); + + let voting_proposals = tx.body().voting_proposals().unwrap(); + assert_eq!(voting_proposals.len(), 7); + assert!(voting_proposals.0.contains(&wrapped_hf_proposal)); + assert!(voting_proposals.0.contains(&wrapped_committee_proposal)); + assert!(voting_proposals.0.contains(&wrapped_constitution_proposal)); + assert!(voting_proposals.0.contains(&wrapped_no_conf_proposal)); + assert!(voting_proposals.0.contains(&wrapped_pp_update_proposal)); + assert!(voting_proposals.0.contains(&wrapped_withdrawal_proposal)); + assert!(voting_proposals.0.contains(&wrapped_info_proposal)); + + let mut total_out = total_tx_output_with_fee(&tx); + total_out = total_out.checked_add(&total_deposit).unwrap(); + assert_eq!(total_out, Coin::from(initial_amount)); +} + +#[test] +fn voting_proposal_builder_with_plutus_script_witness() { + let proposal_deposit = Coin::from(1000u64); + let total_deposit = proposal_deposit.checked_mul(&Coin::from(2u64)).unwrap(); + + let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); + let hf_proposal = + HardForkInitiationProposal::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); + let mut builder = VotingProposalBuilder::new(); + let wrapped_hf_proposal = VotingProposal::new_hard_fork_initiation_proposal(&hf_proposal); + builder.add(&wrapped_hf_proposal).unwrap(); + + let script = create_plutus_script(1, &Language::new_plutus_v2()); + let redeemer = Redeemer::new( + &RedeemerTag::new_cert(), + &BigNum::from(100u32), + &PlutusData::new_empty_constr_plutus_data(&BigNum::zero()), + &ExUnits::new(&BigNum::zero(), &BigNum::zero()), + ); + let expected_redeemer = + redeemer.clone_with_index_and_tag(&BigNum::from(1u64), &RedeemerTag::new_voting_proposal()); + let plutus_witness = PlutusWitness::new_without_datum( + &script, + &redeemer, + ); + + let mut committee = + Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); + committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); + let mut members_to_remove = StakeCredentials::new(); + members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); + let committee_proposal = NewCommitteeProposal::new(&committee, &members_to_remove); + let wrapped_committee_proposal = VotingProposal::new_new_committee_proposal(&committee_proposal); + builder.add_with_plutus_witness(&wrapped_committee_proposal, &plutus_witness).unwrap(); + + let witnesses = builder.get_plutus_witnesses(); + assert_eq!(witnesses.len(), 1); + + let builder_witness = witnesses.get(0); + assert_eq!(builder_witness.redeemer(), expected_redeemer.clone()); + assert_eq!(builder_witness.script(), Some(script.clone())); + assert_eq!(builder_witness.datum(), None); + + let inputs = builder.get_ref_inputs(); + assert_eq!(inputs.len(), 0); + + assert_eq!(builder.has_plutus_scripts(), true); + assert_eq!(builder.get_total_deposit(&proposal_deposit).unwrap(), total_deposit.clone()); + + let initial_amount = 1000000000u64; + let mut tx_builder = create_tx_builder_with_amount_and_deposit_params( + initial_amount, + 500, + 500, + proposal_deposit.into(), + true); + + tx_builder.set_voting_proposal_builder(&builder); + tx_builder.add_change_if_needed(&create_change_address()).unwrap(); + + let mut cost_models = TxBuilderConstants::plutus_default_cost_models(); + cost_models = cost_models.retain_language_versions(&Languages(vec![Language::new_plutus_v2()])); + + tx_builder.calc_script_data_hash(&cost_models).unwrap(); + + let tx = tx_builder.build_tx().unwrap(); + + let voting_proposals = tx.body().voting_proposals().unwrap(); + assert_eq!(voting_proposals.len(), 2); + assert!(voting_proposals.0.contains(&wrapped_hf_proposal)); + assert!(voting_proposals.0.contains(&wrapped_committee_proposal)); + + let mut total_out = total_tx_output_with_fee(&tx); + total_out = total_out.checked_add(&total_deposit).unwrap(); + assert_eq!(total_out, Coin::from(initial_amount)); + + let tx_witnesses = tx.witness_set(); + let tx_script = tx_witnesses.plutus_scripts().unwrap(); + + assert_eq!(tx_script.len(), 1); + assert_eq!(tx_script.get(0), script); + + let tx_redeemers = tx_witnesses.redeemers().unwrap(); + assert_eq!(tx_redeemers.len(), 1); + assert_eq!(tx_redeemers.get(0), expected_redeemer); + + assert_eq!(tx_witnesses.plutus_data(), None); + + assert_eq!(tx.body().reference_inputs(), None); + + let script_data_hash = hash_script_data(&tx_redeemers, &cost_models, None); + + assert_eq!(tx.body().script_data_hash(), Some(script_data_hash)); +} + +#[test] +fn voting_proposal_builder_with_ref_plutus_script_witness() { + let proposal_deposit = Coin::from(1000u64); + let total_deposit = proposal_deposit.checked_mul(&Coin::from(2u64)).unwrap(); + + let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); + let hf_proposal = + HardForkInitiationProposal::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); + let mut builder = VotingProposalBuilder::new(); + let wrapped_hf_proposal = VotingProposal::new_hard_fork_initiation_proposal(&hf_proposal); + builder.add(&wrapped_hf_proposal).unwrap(); + + let script_hash = fake_script_hash(1); + let ref_input = TransactionInput::new(&fake_tx_hash(5), 0); + let redeemer = Redeemer::new( + &RedeemerTag::new_cert(), + &BigNum::from(100u32), + &PlutusData::new_empty_constr_plutus_data(&BigNum::zero()), + &ExUnits::new(&BigNum::zero(), &BigNum::zero()), + ); + let expected_redeemer = + redeemer.clone_with_index_and_tag(&BigNum::from(1u64), &RedeemerTag::new_voting_proposal()); + let plutus_source = PlutusScriptSource::new_ref_input_with_lang_ver(&script_hash, &ref_input, &Language::new_plutus_v2()); + let plutus_witness = PlutusWitness::new_with_ref_without_datum( + &plutus_source, + &redeemer, + ); + + let mut committee = + Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); + committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); + let mut members_to_remove = StakeCredentials::new(); + members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); + let committee_proposal = NewCommitteeProposal::new(&committee, &members_to_remove); + let wrapped_committee_proposal = VotingProposal::new_new_committee_proposal(&committee_proposal); + builder.add_with_plutus_witness(&wrapped_committee_proposal, &plutus_witness).unwrap(); + + let witnesses = builder.get_plutus_witnesses(); + assert_eq!(witnesses.len(), 1); + + let builder_witness = witnesses.get(0); + assert_eq!(builder_witness.redeemer(), expected_redeemer.clone()); + assert_eq!(builder_witness.script(), None); + assert_eq!(builder_witness.datum(), None); + + let builder_ref_inputs = builder.get_ref_inputs(); + assert_eq!(builder_ref_inputs.len(), 1); + assert_eq!(builder_ref_inputs.get(0), ref_input); + + assert_eq!(builder.has_plutus_scripts(), true); + assert_eq!(builder.get_total_deposit(&proposal_deposit).unwrap(), total_deposit.clone()); + + let initial_amount = 1000000000u64; + let mut tx_builder = create_tx_builder_with_amount_and_deposit_params( + initial_amount, + 500, + 500, + proposal_deposit.into(), + true); + + tx_builder.set_voting_proposal_builder(&builder); + tx_builder.add_change_if_needed(&create_change_address()).unwrap(); + + let mut cost_models = TxBuilderConstants::plutus_default_cost_models(); + cost_models = cost_models.retain_language_versions(&Languages(vec![Language::new_plutus_v2()])); + + tx_builder.calc_script_data_hash(&cost_models).unwrap(); + + let tx = tx_builder.build_tx().unwrap(); + + let voting_proposals = tx.body().voting_proposals().unwrap(); + assert_eq!(voting_proposals.len(), 2); + assert!(voting_proposals.0.contains(&wrapped_hf_proposal)); + assert!(voting_proposals.0.contains(&wrapped_committee_proposal)); + + let mut total_out = total_tx_output_with_fee(&tx); + total_out = total_out.checked_add(&total_deposit).unwrap(); + assert_eq!(total_out, Coin::from(initial_amount)); + + let tx_witnesses = tx.witness_set(); + let tx_script = tx_witnesses.plutus_scripts().unwrap(); + assert_eq!(tx_script.len(), 0); + + let tx_redeemers = tx_witnesses.redeemers().unwrap(); + assert_eq!(tx_redeemers.len(), 1); + assert_eq!(tx_redeemers.get(0), expected_redeemer); + + assert_eq!(tx_witnesses.plutus_data(), None); + + let tx_ref_inputs = tx.body().reference_inputs().unwrap(); + assert_eq!(tx_ref_inputs.len(), 1); + assert_eq!(tx_ref_inputs.get(0), ref_input); + + let script_data_hash = hash_script_data(&tx_redeemers, &cost_models, None); + + assert_eq!(tx.body().script_data_hash(), Some(script_data_hash)); +} \ No newline at end of file diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/mock_objects.rs index ca78a647..a9bf1771 100644 --- a/rust/src/tests/mock_objects.rs +++ b/rust/src/tests/mock_objects.rs @@ -156,6 +156,7 @@ pub(crate) fn create_tx_builder_full( linear_fee: &LinearFee, pool_deposit: u64, key_deposit: u64, + voting_proposal_deposit: u64, max_val_size: u32, coins_per_utxo_word: u64, ) -> TransactionBuilder { @@ -163,7 +164,7 @@ pub(crate) fn create_tx_builder_full( .fee_algo(linear_fee) .pool_deposit(&to_bignum(pool_deposit)) .key_deposit(&to_bignum(key_deposit)) - .voting_proposal_deposit(&to_bignum(500000000)) + .voting_proposal_deposit(&to_bignum(voting_proposal_deposit)) .max_value_size(max_val_size) .max_tx_size(MAX_TX_SIZE) .coins_per_utxo_word(&to_bignum(coins_per_utxo_word)) @@ -181,11 +182,13 @@ pub(crate) fn create_tx_builder( coins_per_utxo_word: u64, pool_deposit: u64, key_deposit: u64, + voting_proposal_deposit: u64, ) -> TransactionBuilder { create_tx_builder_full( linear_fee, pool_deposit, key_deposit, + voting_proposal_deposit, MAX_VALUE_SIZE, coins_per_utxo_word, ) @@ -197,6 +200,7 @@ pub(crate) fn create_reallistic_tx_builder() -> TransactionBuilder { COINS_PER_UTXO_WORD, 500000000, 2000000, + 500000000, ) } @@ -204,11 +208,11 @@ pub(crate) fn create_tx_builder_with_fee_and_val_size( linear_fee: &LinearFee, max_val_size: u32, ) -> TransactionBuilder { - create_tx_builder_full(linear_fee, 1, 1, max_val_size, 8) + create_tx_builder_full(linear_fee, 1, 1, 1, max_val_size, 8) } pub(crate) fn create_tx_builder_with_fee(linear_fee: &LinearFee) -> TransactionBuilder { - create_tx_builder(linear_fee, 8, 1, 1) + create_tx_builder(linear_fee, 8, 1, 1, 1) } pub(crate) fn create_tx_builder_with_fee_and_pure_change( @@ -230,14 +234,14 @@ pub(crate) fn create_tx_builder_with_fee_and_pure_change( } pub(crate) fn create_tx_builder_with_key_deposit(deposit: u64) -> TransactionBuilder { - create_tx_builder(&create_default_linear_fee(), 8, 1, deposit) + create_tx_builder(&create_default_linear_fee(), 8, 1, deposit, 1) } pub(crate) fn create_default_tx_builder() -> TransactionBuilder { create_tx_builder_with_fee(&create_default_linear_fee()) } -pub(crate) fn crate_change_address() -> Address { +pub(crate) fn create_change_address() -> Address { let spend = root_key() .derive(harden(1852)) .derive(harden(1815)) @@ -276,6 +280,55 @@ pub(crate) fn create_rich_tx_builder(with_collateral: bool) -> TransactionBuilde tx_builder } +pub(crate) fn create_tx_builder_with_amount( + amount: u64, + with_collateral: bool, +) -> TransactionBuilder { + let mut tx_builder = create_reallistic_tx_builder(); + let input = TransactionInput::new(&fake_tx_hash(1), 0); + let address = generate_address(1); + let mut input_builder = TxInputsBuilder::new(); + input_builder.add_input(&address, &input, &Value::new(&Coin::from(amount))); + tx_builder.set_inputs(&input_builder); + if with_collateral { + let col_input = TransactionInput::new(&fake_tx_hash(1), 0); + let mut col_input_builder = TxInputsBuilder::new(); + col_input_builder.add_input(&address, &col_input, &Value::new(&Coin::from(u64::MAX / 2))); + tx_builder.set_collateral(&col_input_builder); + } + + tx_builder +} + +pub(crate) fn create_tx_builder_with_amount_and_deposit_params( + amount: u64, + pool_deposit: u64, + key_deposit: u64, + voting_proposal_deposit: u64, + with_collateral: bool, +) -> TransactionBuilder { + let mut tx_builder = create_tx_builder( + &create_linear_fee(44, 155381), + COINS_PER_UTXO_WORD, + pool_deposit, + key_deposit, + voting_proposal_deposit, + ); + let input = TransactionInput::new(&fake_tx_hash(1), 0); + let address = generate_address(1); + let mut input_builder = TxInputsBuilder::new(); + input_builder.add_input(&address, &input, &Value::new(&Coin::from(amount))); + tx_builder.set_inputs(&input_builder); + if with_collateral { + let col_input = TransactionInput::new(&fake_tx_hash(1), 0); + let mut col_input_builder = TxInputsBuilder::new(); + col_input_builder.add_input(&address, &col_input, &Value::new(&Coin::from(u64::MAX / 2))); + tx_builder.set_collateral(&col_input_builder); + } + + tx_builder +} + pub(crate) fn create_plutus_script(x: u8, lang: &Language) -> PlutusScript { let mut bytes = hex::decode("4e4d01000033222220051200120011").unwrap(); let pos = bytes.len() - 1; From 025c59bebb3df4881c0d11fc9287c8232a21f8ad Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 9 Sep 2023 20:25:44 +0500 Subject: [PATCH 135/349] rename struct_checks.rs to utils.rs --- .../certificates/committee_hot_key_deregistration.rs | 2 +- .../certificates/committee_hot_key_registration.rs | 2 +- rust/src/serialization/certificates/drep_deregistration.rs | 2 +- rust/src/serialization/certificates/drep_registration.rs | 2 +- rust/src/serialization/certificates/drep_update.rs | 2 +- rust/src/serialization/certificates/genesis_key_delegation.rs | 2 +- .../certificates/move_instantaneous_rewards_cert.rs | 2 +- rust/src/serialization/certificates/pool_registration.rs | 2 +- rust/src/serialization/certificates/pool_retirement.rs | 2 +- .../serialization/certificates/stake_and_vote_delegation.rs | 2 +- rust/src/serialization/certificates/stake_delegation.rs | 2 +- rust/src/serialization/certificates/stake_deregistration.rs | 2 +- rust/src/serialization/certificates/stake_registration.rs | 2 +- .../certificates/stake_registration_and_delegation.rs | 2 +- .../certificates/stake_vote_registration_and_delegation.rs | 2 +- rust/src/serialization/certificates/vote_delegation.rs | 2 +- .../certificates/vote_registration_and_delegation.rs | 2 +- rust/src/serialization/governance/anchor.rs | 2 +- rust/src/serialization/governance/proposals/committee.rs | 2 +- rust/src/serialization/governance/proposals/constitution.rs | 2 +- .../governance/proposals/hard_fork_initiation_proposal.rs | 2 +- .../governance/proposals/new_committee_proposal.rs | 2 +- .../governance/proposals/new_constitution_proposal.rs | 2 +- .../governance/proposals/no_confidence_proposal.rs | 2 +- .../governance/proposals/parameter_change_proposal.rs | 2 +- .../governance/proposals/treasury_withdrawals_proposal.rs | 2 +- .../src/serialization/governance/proposals/voting_proposal.rs | 2 +- rust/src/serialization/mod.rs | 4 ++-- rust/src/serialization/{struct_checks.rs => utils.rs} | 0 29 files changed, 29 insertions(+), 29 deletions(-) rename rust/src/serialization/{struct_checks.rs => utils.rs} (100%) diff --git a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs index b73b4934..4a1fea43 100644 --- a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_deregistration.rs @@ -1,5 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{ +use crate::serialization::utils::{ check_len, deserialize_and_check_index, serialize_and_check_index, }; use crate::*; diff --git a/rust/src/serialization/certificates/committee_hot_key_registration.rs b/rust/src/serialization/certificates/committee_hot_key_registration.rs index 4928604b..ebfbf6bc 100644 --- a/rust/src/serialization/certificates/committee_hot_key_registration.rs +++ b/rust/src/serialization/certificates/committee_hot_key_registration.rs @@ -1,5 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{ +use crate::serialization::utils::{ check_len, deserialize_and_check_index, serialize_and_check_index, }; use crate::*; diff --git a/rust/src/serialization/certificates/drep_deregistration.rs b/rust/src/serialization/certificates/drep_deregistration.rs index 9281caac..27bcf7ca 100644 --- a/rust/src/serialization/certificates/drep_deregistration.rs +++ b/rust/src/serialization/certificates/drep_deregistration.rs @@ -1,5 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{ +use crate::serialization::utils::{ check_len, deserialize_and_check_index, serialize_and_check_index, }; use crate::*; diff --git a/rust/src/serialization/certificates/drep_registration.rs b/rust/src/serialization/certificates/drep_registration.rs index a658e6cc..1352d99c 100644 --- a/rust/src/serialization/certificates/drep_registration.rs +++ b/rust/src/serialization/certificates/drep_registration.rs @@ -1,5 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{ +use crate::serialization::utils::{ check_len, deserialize_and_check_index, serialize_and_check_index, }; use crate::*; diff --git a/rust/src/serialization/certificates/drep_update.rs b/rust/src/serialization/certificates/drep_update.rs index b9dde9c6..4d73ea73 100644 --- a/rust/src/serialization/certificates/drep_update.rs +++ b/rust/src/serialization/certificates/drep_update.rs @@ -1,5 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{ +use crate::serialization::utils::{ check_len, deserialize_and_check_index, serialize_and_check_index, }; use crate::*; diff --git a/rust/src/serialization/certificates/genesis_key_delegation.rs b/rust/src/serialization/certificates/genesis_key_delegation.rs index b1a38626..bad46599 100644 --- a/rust/src/serialization/certificates/genesis_key_delegation.rs +++ b/rust/src/serialization/certificates/genesis_key_delegation.rs @@ -1,5 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{ +use crate::serialization::utils::{ check_len, deserialize_and_check_index, serialize_and_check_index, }; use crate::*; diff --git a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs index 5364143b..a63b14c5 100644 --- a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs +++ b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs @@ -1,5 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{ +use crate::serialization::utils::{ check_len, deserialize_and_check_index, serialize_and_check_index, }; use crate::*; diff --git a/rust/src/serialization/certificates/pool_registration.rs b/rust/src/serialization/certificates/pool_registration.rs index 428801c5..88370bfa 100644 --- a/rust/src/serialization/certificates/pool_registration.rs +++ b/rust/src/serialization/certificates/pool_registration.rs @@ -1,5 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{ +use crate::serialization::utils::{ check_len, deserialize_and_check_index, serialize_and_check_index, }; use crate::*; diff --git a/rust/src/serialization/certificates/pool_retirement.rs b/rust/src/serialization/certificates/pool_retirement.rs index 3087f73c..b1629fee 100644 --- a/rust/src/serialization/certificates/pool_retirement.rs +++ b/rust/src/serialization/certificates/pool_retirement.rs @@ -1,5 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{ +use crate::serialization::utils::{ check_len, deserialize_and_check_index, serialize_and_check_index, }; use crate::*; diff --git a/rust/src/serialization/certificates/stake_and_vote_delegation.rs b/rust/src/serialization/certificates/stake_and_vote_delegation.rs index 4a22b73d..3c88447c 100644 --- a/rust/src/serialization/certificates/stake_and_vote_delegation.rs +++ b/rust/src/serialization/certificates/stake_and_vote_delegation.rs @@ -1,5 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{ +use crate::serialization::utils::{ check_len, deserialize_and_check_index, serialize_and_check_index, }; use crate::*; diff --git a/rust/src/serialization/certificates/stake_delegation.rs b/rust/src/serialization/certificates/stake_delegation.rs index 205518ce..93122cae 100644 --- a/rust/src/serialization/certificates/stake_delegation.rs +++ b/rust/src/serialization/certificates/stake_delegation.rs @@ -1,5 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{ +use crate::serialization::utils::{ check_len, deserialize_and_check_index, serialize_and_check_index, }; use crate::*; diff --git a/rust/src/serialization/certificates/stake_deregistration.rs b/rust/src/serialization/certificates/stake_deregistration.rs index d0084dd2..c597addd 100644 --- a/rust/src/serialization/certificates/stake_deregistration.rs +++ b/rust/src/serialization/certificates/stake_deregistration.rs @@ -1,5 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{check_index, check_len, serialize_and_check_index}; +use crate::serialization::utils::{check_index, check_len, serialize_and_check_index}; use crate::*; use cbor_event::Len; use num_traits::{FromPrimitive, ToPrimitive}; diff --git a/rust/src/serialization/certificates/stake_registration.rs b/rust/src/serialization/certificates/stake_registration.rs index 288556e0..bf19894b 100644 --- a/rust/src/serialization/certificates/stake_registration.rs +++ b/rust/src/serialization/certificates/stake_registration.rs @@ -1,5 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{check_index, check_len, serialize_and_check_index}; +use crate::serialization::utils::{check_index, check_len, serialize_and_check_index}; use crate::*; use cbor_event::Len; use num_traits::{FromPrimitive, ToPrimitive}; diff --git a/rust/src/serialization/certificates/stake_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_registration_and_delegation.rs index e227dff4..3c847d92 100644 --- a/rust/src/serialization/certificates/stake_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/stake_registration_and_delegation.rs @@ -1,5 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{ +use crate::serialization::utils::{ check_len, deserialize_and_check_index, serialize_and_check_index, }; use crate::*; diff --git a/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs index ab31cbb6..37167b91 100644 --- a/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/stake_vote_registration_and_delegation.rs @@ -1,5 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{ +use crate::serialization::utils::{ check_len, deserialize_and_check_index, serialize_and_check_index, }; use crate::*; diff --git a/rust/src/serialization/certificates/vote_delegation.rs b/rust/src/serialization/certificates/vote_delegation.rs index 15bc7888..a63e49b6 100644 --- a/rust/src/serialization/certificates/vote_delegation.rs +++ b/rust/src/serialization/certificates/vote_delegation.rs @@ -1,5 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{ +use crate::serialization::utils::{ check_len, deserialize_and_check_index, serialize_and_check_index, }; use crate::*; diff --git a/rust/src/serialization/certificates/vote_registration_and_delegation.rs b/rust/src/serialization/certificates/vote_registration_and_delegation.rs index 5e540ab3..52cd29e1 100644 --- a/rust/src/serialization/certificates/vote_registration_and_delegation.rs +++ b/rust/src/serialization/certificates/vote_registration_and_delegation.rs @@ -1,5 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::struct_checks::{ +use crate::serialization::utils::{ check_len, deserialize_and_check_index, serialize_and_check_index, }; use crate::*; diff --git a/rust/src/serialization/governance/anchor.rs b/rust/src/serialization/governance/anchor.rs index 488f2bb5..1949db84 100644 --- a/rust/src/serialization/governance/anchor.rs +++ b/rust/src/serialization/governance/anchor.rs @@ -1,4 +1,4 @@ -use crate::serialization::struct_checks::check_len; +use crate::serialization::utils::check_len; use crate::*; impl cbor_event::se::Serialize for Anchor { diff --git a/rust/src/serialization/governance/proposals/committee.rs b/rust/src/serialization/governance/proposals/committee.rs index 535c7c5a..6a1a88c2 100644 --- a/rust/src/serialization/governance/proposals/committee.rs +++ b/rust/src/serialization/governance/proposals/committee.rs @@ -1,4 +1,4 @@ -use crate::serialization::struct_checks::check_len; +use crate::serialization::utils::check_len; use crate::*; use std::collections::BTreeMap; diff --git a/rust/src/serialization/governance/proposals/constitution.rs b/rust/src/serialization/governance/proposals/constitution.rs index b6b228e9..c7dc7a27 100644 --- a/rust/src/serialization/governance/proposals/constitution.rs +++ b/rust/src/serialization/governance/proposals/constitution.rs @@ -1,4 +1,4 @@ -use crate::serialization::struct_checks::check_len; +use crate::serialization::utils::check_len; use crate::*; impl Serialize for Constitution { diff --git a/rust/src/serialization/governance/proposals/hard_fork_initiation_proposal.rs b/rust/src/serialization/governance/proposals/hard_fork_initiation_proposal.rs index cb66c3cb..486feb8a 100644 --- a/rust/src/serialization/governance/proposals/hard_fork_initiation_proposal.rs +++ b/rust/src/serialization/governance/proposals/hard_fork_initiation_proposal.rs @@ -1,4 +1,4 @@ -use crate::serialization::struct_checks::{check_len_indefinite, serialize_and_check_index}; +use crate::serialization::utils::{check_len_indefinite, serialize_and_check_index}; use crate::serialization::{check_len, deserialize_and_check_index}; use crate::*; use map_names::VotingProposalIndexNames; diff --git a/rust/src/serialization/governance/proposals/new_committee_proposal.rs b/rust/src/serialization/governance/proposals/new_committee_proposal.rs index 1bf70101..84f83083 100644 --- a/rust/src/serialization/governance/proposals/new_committee_proposal.rs +++ b/rust/src/serialization/governance/proposals/new_committee_proposal.rs @@ -1,4 +1,4 @@ -use crate::serialization::struct_checks::serialize_and_check_index; +use crate::serialization::utils::serialize_and_check_index; use crate::serialization::{check_len, deserialize_and_check_index}; use crate::*; use map_names::VotingProposalIndexNames; diff --git a/rust/src/serialization/governance/proposals/new_constitution_proposal.rs b/rust/src/serialization/governance/proposals/new_constitution_proposal.rs index 6464964f..b2f12d5f 100644 --- a/rust/src/serialization/governance/proposals/new_constitution_proposal.rs +++ b/rust/src/serialization/governance/proposals/new_constitution_proposal.rs @@ -1,6 +1,6 @@ use crate::*; -use crate::serialization::struct_checks::serialize_and_check_index; +use crate::serialization::utils::serialize_and_check_index; use crate::serialization::{check_len, deserialize_and_check_index}; use map_names::VotingProposalIndexNames; use num_traits::ToPrimitive; diff --git a/rust/src/serialization/governance/proposals/no_confidence_proposal.rs b/rust/src/serialization/governance/proposals/no_confidence_proposal.rs index e8cb6b2b..24db8a01 100644 --- a/rust/src/serialization/governance/proposals/no_confidence_proposal.rs +++ b/rust/src/serialization/governance/proposals/no_confidence_proposal.rs @@ -1,4 +1,4 @@ -use crate::serialization::struct_checks::serialize_and_check_index; +use crate::serialization::utils::serialize_and_check_index; use crate::serialization::{check_len, deserialize_and_check_index}; use crate::*; use map_names::VotingProposalIndexNames; diff --git a/rust/src/serialization/governance/proposals/parameter_change_proposal.rs b/rust/src/serialization/governance/proposals/parameter_change_proposal.rs index c533a50a..9a892eef 100644 --- a/rust/src/serialization/governance/proposals/parameter_change_proposal.rs +++ b/rust/src/serialization/governance/proposals/parameter_change_proposal.rs @@ -1,4 +1,4 @@ -use crate::serialization::struct_checks::serialize_and_check_index; +use crate::serialization::utils::serialize_and_check_index; use crate::serialization::{check_len, deserialize_and_check_index}; use crate::*; use map_names::VotingProposalIndexNames; diff --git a/rust/src/serialization/governance/proposals/treasury_withdrawals_proposal.rs b/rust/src/serialization/governance/proposals/treasury_withdrawals_proposal.rs index 16826447..f495eb4f 100644 --- a/rust/src/serialization/governance/proposals/treasury_withdrawals_proposal.rs +++ b/rust/src/serialization/governance/proposals/treasury_withdrawals_proposal.rs @@ -1,4 +1,4 @@ -use crate::serialization::struct_checks::serialize_and_check_index; +use crate::serialization::utils::serialize_and_check_index; use crate::serialization::{check_len, deserialize_and_check_index}; use crate::*; use map_names::VotingProposalIndexNames; diff --git a/rust/src/serialization/governance/proposals/voting_proposal.rs b/rust/src/serialization/governance/proposals/voting_proposal.rs index e491afd2..431034c4 100644 --- a/rust/src/serialization/governance/proposals/voting_proposal.rs +++ b/rust/src/serialization/governance/proposals/voting_proposal.rs @@ -1,5 +1,5 @@ use crate::serialization::map_names::VotingProposalIndexNames; -use crate::serialization::struct_checks::{check_len_indefinite, serialize_and_check_index}; +use crate::serialization::utils::{check_len_indefinite, serialize_and_check_index}; use crate::*; use num_traits::{FromPrimitive, ToPrimitive}; use std::io::{Seek, SeekFrom}; diff --git a/rust/src/serialization/mod.rs b/rust/src/serialization/mod.rs index 3a0cbd5a..ee150b34 100644 --- a/rust/src/serialization/mod.rs +++ b/rust/src/serialization/mod.rs @@ -17,7 +17,7 @@ pub mod map_names; pub mod traits; pub(super) use traits::*; -mod struct_checks; +mod utils; mod fixed_tx; -use struct_checks::*; +use utils::*; diff --git a/rust/src/serialization/struct_checks.rs b/rust/src/serialization/utils.rs similarity index 100% rename from rust/src/serialization/struct_checks.rs rename to rust/src/serialization/utils.rs From 633ac4feebdcf7541bb93e6a30a6df620ed8af04 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 9 Sep 2023 21:25:22 +0500 Subject: [PATCH 136/349] add plutus v3 support --- rust/src/builders/mint_builder.rs | 1 - rust/src/lib.rs | 5 +- rust/src/metadata.rs | 1477 --------- rust/src/plutus.rs | 2690 ----------------- rust/src/protocol_types/metadata.rs | 754 +++++ rust/src/protocol_types/mod.rs | 6 + rust/src/protocol_types/plutus.rs | 1489 +++++++++ rust/src/serialization/general.rs | 57 +- rust/src/serialization/metadata.rs | 469 +++ rust/src/serialization/mod.rs | 14 +- rust/src/serialization/plutus.rs | 692 +++++ .../src/serialization/serialization_macros.rs | 2 +- rust/src/serialization/utils.rs | 12 + rust/src/tests/builders/tx_builder.rs | 12 +- rust/src/tests/metadata.rs | 281 ++ rust/src/tests/mod.rs | 2 + rust/src/tests/plutus.rs | 525 ++++ 17 files changed, 4290 insertions(+), 4198 deletions(-) delete mode 100644 rust/src/metadata.rs delete mode 100644 rust/src/plutus.rs create mode 100644 rust/src/protocol_types/metadata.rs create mode 100644 rust/src/protocol_types/plutus.rs create mode 100644 rust/src/serialization/metadata.rs create mode 100644 rust/src/serialization/plutus.rs create mode 100644 rust/src/tests/metadata.rs create mode 100644 rust/src/tests/plutus.rs diff --git a/rust/src/builders/mint_builder.rs b/rust/src/builders/mint_builder.rs index 17658bbf..c11d494e 100644 --- a/rust/src/builders/mint_builder.rs +++ b/rust/src/builders/mint_builder.rs @@ -1,4 +1,3 @@ -use crate::plutus::Redeemer; use crate::*; use std::collections::BTreeMap; diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 4aef7874..d3582e44 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -51,8 +51,6 @@ pub mod error; pub mod fees; pub mod impl_mockchain; pub mod legacy_address; -pub mod metadata; -pub mod plutus; pub mod traits; pub use builders::*; mod protocol_types; @@ -67,8 +65,6 @@ use crate::traits::NoneOrEmpty; use address::*; use crypto::*; use error::*; -use metadata::*; -use plutus::*; use schemars::JsonSchema; use serialization::*; use std::cmp::Ordering; @@ -1723,6 +1719,7 @@ pub enum ScriptHashNamespace { NativeScript = 0, PlutusScript = 1, PlutusScriptV2 = 2, + PlutusScriptV3 = 3, } #[wasm_bindgen] diff --git a/rust/src/metadata.rs b/rust/src/metadata.rs deleted file mode 100644 index ccd81ca0..00000000 --- a/rust/src/metadata.rs +++ /dev/null @@ -1,1477 +0,0 @@ -use super::*; -use linked_hash_map::LinkedHashMap; - -const MD_MAX_LEN: usize = 64; - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub struct MetadataMap(LinkedHashMap); - -to_from_bytes!(MetadataMap); - -#[wasm_bindgen] -impl MetadataMap { - pub fn new() -> Self { - Self(LinkedHashMap::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn insert( - &mut self, - key: &TransactionMetadatum, - value: &TransactionMetadatum, - ) -> Option { - self.0.insert(key.clone(), value.clone()) - } - - // convenience function for inserting as a string key - pub fn insert_str( - &mut self, - key: &str, - value: &TransactionMetadatum, - ) -> Result, JsError> { - Ok(self.insert(&TransactionMetadatum::new_text(key.to_owned())?, value)) - } - - // convenience function for inserting 32-bit integers - for higher-precision integers use insert() with an Int struct - pub fn insert_i32( - &mut self, - key: i32, - value: &TransactionMetadatum, - ) -> Option { - self.insert(&TransactionMetadatum::new_int(&Int::new_i32(key)), value) - } - - pub fn get(&self, key: &TransactionMetadatum) -> Result { - self.0 - .get(key) - .map(|v| v.clone()) - .ok_or_else(|| JsError::from_str(&format!("key {:?} not found", key))) - } - - // convenience function for retrieving a string key - pub fn get_str(&self, key: &str) -> Result { - self.get(&TransactionMetadatum::new_text(key.to_owned())?) - } - - // convenience function for retrieving 32-bit integer keys - for higher-precision integers use get() with an Int struct - pub fn get_i32(&self, key: i32) -> Result { - self.get(&TransactionMetadatum::new_int(&Int::new_i32(key))) - } - - pub fn has(&self, key: &TransactionMetadatum) -> bool { - self.0.contains_key(key) - } - - pub fn keys(&self) -> MetadataList { - MetadataList( - self.0 - .iter() - .map(|(k, _v)| k.clone()) - .collect::>(), - ) - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub struct MetadataList(Vec); - -to_from_bytes!(MetadataList); - -#[wasm_bindgen] -impl MetadataList { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> TransactionMetadatum { - self.0[index].clone() - } - - pub fn add(&mut self, elem: &TransactionMetadatum) { - self.0.push(elem.clone()); - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub enum TransactionMetadatumKind { - MetadataMap, - MetadataList, - Int, - Bytes, - Text, -} - -#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] -enum TransactionMetadatumEnum { - MetadataMap(MetadataMap), - MetadataList(MetadataList), - Int(Int), - Bytes(Vec), - Text(String), -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub struct TransactionMetadatum(TransactionMetadatumEnum); - -to_from_bytes!(TransactionMetadatum); - -#[wasm_bindgen] -impl TransactionMetadatum { - pub fn new_map(map: &MetadataMap) -> Self { - Self(TransactionMetadatumEnum::MetadataMap(map.clone())) - } - - pub fn new_list(list: &MetadataList) -> Self { - Self(TransactionMetadatumEnum::MetadataList(list.clone())) - } - - pub fn new_int(int: &Int) -> Self { - Self(TransactionMetadatumEnum::Int(int.clone())) - } - - pub fn new_bytes(bytes: Vec) -> Result { - if bytes.len() > MD_MAX_LEN { - Err(JsError::from_str(&format!( - "Max metadata bytes too long: {}, max = {}", - bytes.len(), - MD_MAX_LEN - ))) - } else { - Ok(Self(TransactionMetadatumEnum::Bytes(bytes))) - } - } - - pub fn new_text(text: String) -> Result { - if text.len() > MD_MAX_LEN { - Err(JsError::from_str(&format!( - "Max metadata string too long: {}, max = {}", - text.len(), - MD_MAX_LEN - ))) - } else { - Ok(Self(TransactionMetadatumEnum::Text(text))) - } - } - - pub fn kind(&self) -> TransactionMetadatumKind { - match &self.0 { - TransactionMetadatumEnum::MetadataMap(_) => TransactionMetadatumKind::MetadataMap, - TransactionMetadatumEnum::MetadataList(_) => TransactionMetadatumKind::MetadataList, - TransactionMetadatumEnum::Int(_) => TransactionMetadatumKind::Int, - TransactionMetadatumEnum::Bytes(_) => TransactionMetadatumKind::Bytes, - TransactionMetadatumEnum::Text(_) => TransactionMetadatumKind::Text, - } - } - - pub fn as_map(&self) -> Result { - match &self.0 { - TransactionMetadatumEnum::MetadataMap(x) => Ok(x.clone()), - _ => Err(JsError::from_str("not a map")), - } - } - - pub fn as_list(&self) -> Result { - match &self.0 { - TransactionMetadatumEnum::MetadataList(x) => Ok(x.clone()), - _ => Err(JsError::from_str("not a list")), - } - } - - pub fn as_int(&self) -> Result { - match &self.0 { - TransactionMetadatumEnum::Int(x) => Ok(x.clone()), - _ => Err(JsError::from_str("not an int")), - } - } - - pub fn as_bytes(&self) -> Result, JsError> { - match &self.0 { - TransactionMetadatumEnum::Bytes(x) => Ok(x.clone()), - _ => Err(JsError::from_str("not bytes")), - } - } - - pub fn as_text(&self) -> Result { - match &self.0 { - TransactionMetadatumEnum::Text(x) => Ok(x.clone()), - _ => Err(JsError::from_str("not text")), - } - } -} - -impl serde::Serialize for TransactionMetadatum { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let json_str = decode_metadatum_to_json_str(self, MetadataJsonSchema::DetailedSchema) - .map_err(|e| serde::ser::Error::custom(&format!("{:?}", e)))?; - serializer.serialize_str(&json_str) - } -} - -impl<'de> serde::de::Deserialize<'de> for TransactionMetadatum { - fn deserialize(deserializer: D) -> Result - where - D: serde::de::Deserializer<'de>, - { - let s = ::deserialize(deserializer)?; - encode_json_str_to_metadatum(s.clone(), MetadataJsonSchema::DetailedSchema).map_err(|e| { - serde::de::Error::invalid_value( - serde::de::Unexpected::Str(&s), - &format!("{:?}", e).as_str(), - ) - }) - } -} - -// just for now we'll do json-in-json until I can figure this out better -// TODO: maybe not generate this? or how do we do this? -impl JsonSchema for TransactionMetadatum { - fn schema_name() -> String { - String::from("TransactionMetadatum") - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - String::json_schema(gen) - } - fn is_referenceable() -> bool { - String::is_referenceable() - } -} - -pub type TransactionMetadatumLabel = BigNum; - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub struct TransactionMetadatumLabels(Vec); - -to_from_bytes!(TransactionMetadatumLabels); - -#[wasm_bindgen] -impl TransactionMetadatumLabels { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> TransactionMetadatumLabel { - self.0[index].clone() - } - - pub fn add(&mut self, elem: &TransactionMetadatumLabel) { - self.0.push(elem.clone()); - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub struct GeneralTransactionMetadata( - LinkedHashMap, -); - -impl_to_from!(GeneralTransactionMetadata); - -#[wasm_bindgen] -impl GeneralTransactionMetadata { - pub fn new() -> Self { - Self(LinkedHashMap::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn insert( - &mut self, - key: &TransactionMetadatumLabel, - value: &TransactionMetadatum, - ) -> Option { - self.0.insert(key.clone(), value.clone()) - } - - pub fn get(&self, key: &TransactionMetadatumLabel) -> Option { - self.0.get(key).map(|v| v.clone()) - } - - pub fn keys(&self) -> TransactionMetadatumLabels { - TransactionMetadatumLabels( - self.0 - .iter() - .map(|(k, _v)| k.clone()) - .collect::>(), - ) - } -} - -impl serde::Serialize for GeneralTransactionMetadata { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let map = self.0.iter().collect::>(); - map.serialize(serializer) - } -} - -impl<'de> serde::de::Deserialize<'de> for GeneralTransactionMetadata { - fn deserialize(deserializer: D) -> Result - where - D: serde::de::Deserializer<'de>, - { - let map = as serde::de::Deserialize>::deserialize( - deserializer, - )?; - Ok(Self(map.into_iter().collect())) - } -} - -impl JsonSchema for GeneralTransactionMetadata { - fn schema_name() -> String { - String::from("GeneralTransactionMetadata") - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - std::collections::BTreeMap::::json_schema( - gen, - ) - } - fn is_referenceable() -> bool { - std::collections::BTreeMap::::is_referenceable() - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Ord, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema)] -pub struct AuxiliaryData { - metadata: Option, - native_scripts: Option, - plutus_scripts: Option, - prefer_alonzo_format: bool, -} - -impl std::cmp::PartialEq for AuxiliaryData { - fn eq(&self, other: &Self) -> bool { - self.metadata.eq(&other.metadata) - && self.native_scripts.eq(&other.native_scripts) - && self.plutus_scripts.eq(&other.plutus_scripts) - } -} - -impl std::cmp::Eq for AuxiliaryData {} - -impl_to_from!(AuxiliaryData); - -#[wasm_bindgen] -impl AuxiliaryData { - pub fn new() -> Self { - Self { - metadata: None, - native_scripts: None, - plutus_scripts: None, - prefer_alonzo_format: false, - } - } - - pub fn metadata(&self) -> Option { - self.metadata.clone() - } - - pub fn set_metadata(&mut self, metadata: &GeneralTransactionMetadata) { - self.metadata = Some(metadata.clone()); - } - - pub fn native_scripts(&self) -> Option { - self.native_scripts.clone() - } - - pub fn set_native_scripts(&mut self, native_scripts: &NativeScripts) { - self.native_scripts = Some(native_scripts.clone()) - } - - pub fn plutus_scripts(&self) -> Option { - self.plutus_scripts.clone() - } - - pub fn set_plutus_scripts(&mut self, plutus_scripts: &PlutusScripts) { - self.plutus_scripts = Some(plutus_scripts.clone()) - } - - pub fn prefer_alonzo_format(&self) -> bool { - self.prefer_alonzo_format.clone() - } - - pub fn set_prefer_alonzo_format(&mut self, prefer: bool) { - self.prefer_alonzo_format = prefer - } -} - -// encodes arbitrary bytes into chunks of 64 bytes (the limit for bytes) as a list to be valid Metadata -#[wasm_bindgen] -pub fn encode_arbitrary_bytes_as_metadatum(bytes: &[u8]) -> TransactionMetadatum { - let mut list = MetadataList::new(); - for chunk in bytes.chunks(MD_MAX_LEN) { - // this should never fail as we are already chunking it - list.add(&TransactionMetadatum::new_bytes(chunk.to_vec()).unwrap()); - } - TransactionMetadatum::new_list(&list) -} - -// decodes from chunks of bytes in a list to a byte vector if that is the metadata format, otherwise returns None -#[wasm_bindgen] -pub fn decode_arbitrary_bytes_from_metadatum( - metadata: &TransactionMetadatum, -) -> Result, JsError> { - let mut bytes = Vec::new(); - for elem in metadata.as_list()?.0 { - bytes.append(&mut elem.as_bytes()?); - } - Ok(bytes) -} - -#[wasm_bindgen] -#[derive(Copy, Clone, Eq, PartialEq)] -// Different schema methods for mapping between JSON and the metadata CBOR. -// This conversion should match TxMetadataJsonSchema in cardano-node defined (at time of writing) here: -// https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/MetaData.hs -// but has 2 additional schemas for more or less conversionse -// Note: Byte/Strings (including keys) in any schema must be at most 64 bytes in length -pub enum MetadataJsonSchema { - // Does zero implicit conversions. - // Round-trip conversions are 100% consistent - // Treats maps DIRECTLY as maps in JSON in a natural way e.g. {"key1": 47, "key2": [0, 1]]} - // From JSON: - // * null/true/false NOT supported. - // * keys treated as strings only - // To JSON - // * Bytes, non-string keys NOT supported. - // Stricter than any TxMetadataJsonSchema in cardano-node but more natural for JSON -> Metadata - NoConversions, - // Does some implicit conversions. - // Round-trip conversions MD -> JSON -> MD is NOT consistent, but JSON -> MD -> JSON is. - // Without using bytes - // Maps are treated as an array of k-v pairs as such: [{"key1": 47}, {"key2": [0, 1]}, {"key3": "0xFFFF"}] - // From JSON: - // * null/true/false NOT supported. - // * Strings parseable as bytes (0x starting hex) or integers are converted. - // To JSON: - // * Non-string keys partially supported (bytes as 0x starting hex string, integer converted to string). - // * Bytes are converted to hex strings starting with 0x for both values and keys. - // Corresponds to TxMetadataJsonSchema's TxMetadataJsonNoSchema in cardano-node - BasicConversions, - // Supports the annotated schema presented in cardano-node with tagged values e.g. {"int": 7}, {"list": [0, 1]} - // Round-trip conversions are 100% consistent - // Maps are treated as an array of k-v pairs as such: [{"key1": {"int": 47}}, {"key2": {"list": [0, 1]}}, {"key3": {"bytes": "0xFFFF"}}] - // From JSON: - // * null/true/false NOT supported. - // * Strings parseable as bytes (hex WITHOUT 0x prefix) or integers converted. - // To JSON: - // * Non-string keys are supported. Any key parseable as JSON is encoded as metadata instead of a string - // Corresponds to TxMetadataJsonSchema's TxMetadataJsonDetailedSchema in cardano-node - DetailedSchema, -} - -fn supports_tagged_values(schema: MetadataJsonSchema) -> bool { - match schema { - MetadataJsonSchema::NoConversions | MetadataJsonSchema::BasicConversions => false, - MetadataJsonSchema::DetailedSchema => true, - } -} - -fn hex_string_to_bytes(hex: &str) -> Option> { - if hex.starts_with("0x") { - hex::decode(&hex[2..]).ok() - } else { - None - } -} - -fn bytes_to_hex_string(bytes: &[u8]) -> String { - format!("0x{}", hex::encode(bytes)) -} - -// Converts JSON to Metadata according to MetadataJsonSchema -#[wasm_bindgen] -pub fn encode_json_str_to_metadatum( - json: String, - schema: MetadataJsonSchema, -) -> Result { - let value = serde_json::from_str(&json).map_err(|e| JsError::from_str(&e.to_string()))?; - encode_json_value_to_metadatum(value, schema) -} - -pub fn encode_json_value_to_metadatum( - value: serde_json::Value, - schema: MetadataJsonSchema, -) -> Result { - use serde_json::Value; - fn encode_number(x: serde_json::Number) -> Result { - if let Some(x) = x.as_u64() { - Ok(TransactionMetadatum::new_int(&Int::new(&utils::to_bignum( - x, - )))) - } else if let Some(x) = x.as_i64() { - Ok(TransactionMetadatum::new_int(&Int::new_negative( - &utils::to_bignum(-x as u64), - ))) - } else { - Err(JsError::from_str("floats not allowed in metadata")) - } - } - fn encode_string( - s: String, - schema: MetadataJsonSchema, - ) -> Result { - if schema == MetadataJsonSchema::BasicConversions { - match hex_string_to_bytes(&s) { - Some(bytes) => TransactionMetadatum::new_bytes(bytes), - None => TransactionMetadatum::new_text(s), - } - } else { - TransactionMetadatum::new_text(s) - } - } - fn encode_array( - json_arr: Vec, - schema: MetadataJsonSchema, - ) -> Result { - let mut arr = MetadataList::new(); - for value in json_arr { - arr.add(&encode_json_value_to_metadatum(value, schema)?); - } - Ok(TransactionMetadatum::new_list(&arr)) - } - match schema { - MetadataJsonSchema::NoConversions | MetadataJsonSchema::BasicConversions => match value { - Value::Null => Err(JsError::from_str("null not allowed in metadata")), - Value::Bool(_) => Err(JsError::from_str("bools not allowed in metadata")), - Value::Number(x) => encode_number(x), - Value::String(s) => encode_string(s, schema), - Value::Array(json_arr) => encode_array(json_arr, schema), - Value::Object(json_obj) => { - let mut map = MetadataMap::new(); - for (raw_key, value) in json_obj { - let key = if schema == MetadataJsonSchema::BasicConversions { - match raw_key.parse::() { - Ok(x) => TransactionMetadatum::new_int(&Int(x)), - Err(_) => encode_string(raw_key, schema)?, - } - } else { - TransactionMetadatum::new_text(raw_key)? - }; - map.insert(&key, &encode_json_value_to_metadatum(value, schema)?); - } - Ok(TransactionMetadatum::new_map(&map)) - } - }, - // we rely on tagged objects to control parsing here instead - MetadataJsonSchema::DetailedSchema => match value { - Value::Object(obj) if obj.len() == 1 => { - let (k, v) = obj.into_iter().next().unwrap(); - fn tag_mismatch() -> JsError { - JsError::from_str("key does not match type") - } - match k.as_str() { - "int" => match v { - Value::Number(x) => encode_number(x), - _ => Err(tag_mismatch()), - }, - "string" => { - encode_string(v.as_str().ok_or_else(tag_mismatch)?.to_owned(), schema) - } - "bytes" => match hex::decode(v.as_str().ok_or_else(tag_mismatch)?) { - Ok(bytes) => TransactionMetadatum::new_bytes(bytes), - Err(_) => Err(JsError::from_str( - "invalid hex string in tagged byte-object", - )), - }, - "list" => encode_array(v.as_array().ok_or_else(tag_mismatch)?.clone(), schema), - "map" => { - let mut map = MetadataMap::new(); - fn map_entry_err() -> JsError { - JsError::from_str("entry format in detailed schema map object not correct. Needs to be of form {\"k\": \"key\", \"v\": value}") - } - for entry in v.as_array().ok_or_else(tag_mismatch)? { - let entry_obj = entry.as_object().ok_or_else(map_entry_err)?; - let raw_key = entry_obj.get("k").ok_or_else(map_entry_err)?; - let value = entry_obj.get("v").ok_or_else(map_entry_err)?; - let key = encode_json_value_to_metadatum(raw_key.clone(), schema)?; - map.insert( - &key, - &encode_json_value_to_metadatum(value.clone(), schema)?, - ); - } - Ok(TransactionMetadatum::new_map(&map)) - } - invalid_key => Err(JsError::from_str(&format!( - "key '{}' in tagged object not valid", - invalid_key - ))), - } - } - _ => Err(JsError::from_str( - "DetailedSchema requires types to be tagged objects", - )), - }, - } -} - -// Converts Metadata to JSON according to MetadataJsonSchema -#[wasm_bindgen] -pub fn decode_metadatum_to_json_str( - metadatum: &TransactionMetadatum, - schema: MetadataJsonSchema, -) -> Result { - let value = decode_metadatum_to_json_value(metadatum, schema)?; - serde_json::to_string(&value).map_err(|e| JsError::from_str(&e.to_string())) -} - -pub fn decode_metadatum_to_json_value( - metadatum: &TransactionMetadatum, - schema: MetadataJsonSchema, -) -> Result { - use serde_json::Value; - use std::convert::TryFrom; - fn decode_key( - key: &TransactionMetadatum, - schema: MetadataJsonSchema, - ) -> Result { - match &key.0 { - TransactionMetadatumEnum::Text(s) => Ok(s.clone()), - TransactionMetadatumEnum::Bytes(b) if schema != MetadataJsonSchema::NoConversions => { - Ok(bytes_to_hex_string(b.as_ref())) - } - TransactionMetadatumEnum::Int(i) if schema != MetadataJsonSchema::NoConversions => { - let int_str = if i.0 >= 0 { - u64::try_from(i.0).map(|x| x.to_string()) - } else { - i64::try_from(i.0).map(|x| x.to_string()) - }; - int_str.map_err(|e| JsError::from_str(&e.to_string())) - } - TransactionMetadatumEnum::MetadataList(list) - if schema == MetadataJsonSchema::DetailedSchema => - { - decode_metadatum_to_json_str(&TransactionMetadatum::new_list(&list), schema) - } - TransactionMetadatumEnum::MetadataMap(map) - if schema == MetadataJsonSchema::DetailedSchema => - { - decode_metadatum_to_json_str(&TransactionMetadatum::new_map(&map), schema) - } - _ => Err(JsError::from_str(&format!( - "key type {:?} not allowed in JSON under specified schema", - key.0 - ))), - } - } - let (type_key, value) = match &metadatum.0 { - TransactionMetadatumEnum::MetadataMap(map) => match schema { - MetadataJsonSchema::NoConversions | MetadataJsonSchema::BasicConversions => { - // treats maps directly as JSON maps - let mut json_map = serde_json::map::Map::with_capacity(map.len()); - for (key, value) in map.0.iter() { - json_map.insert( - decode_key(key, schema)?, - decode_metadatum_to_json_value(value, schema)?, - ); - } - ("map", Value::from(json_map)) - } - - MetadataJsonSchema::DetailedSchema => ( - "map", - Value::from( - map.0 - .iter() - .map(|(key, value)| { - // must encode maps as JSON lists of objects with k/v keys - // also in these schemas we support more key types than strings - let k = decode_metadatum_to_json_value(key, schema)?; - let v = decode_metadatum_to_json_value(value, schema)?; - let mut kv_obj = serde_json::map::Map::with_capacity(2); - kv_obj.insert(String::from("k"), Value::from(k)); - kv_obj.insert(String::from("v"), v); - Ok(Value::from(kv_obj)) - }) - .collect::, JsError>>()?, - ), - ), - }, - TransactionMetadatumEnum::MetadataList(arr) => ( - "list", - Value::from( - arr.0 - .iter() - .map(|e| decode_metadatum_to_json_value(e, schema)) - .collect::, JsError>>()?, - ), - ), - TransactionMetadatumEnum::Int(x) => ( - "int", - if x.0 >= 0 { - Value::from(u64::try_from(x.0).map_err(|e| JsError::from_str(&e.to_string()))?) - } else { - Value::from(i64::try_from(x.0).map_err(|e| JsError::from_str(&e.to_string()))?) - }, - ), - TransactionMetadatumEnum::Bytes(bytes) => ( - "bytes", - match schema { - MetadataJsonSchema::NoConversions => Err(JsError::from_str( - "bytes not allowed in JSON in specified schema", - )), - // 0x prefix - MetadataJsonSchema::BasicConversions => { - Ok(Value::from(bytes_to_hex_string(bytes.as_ref()))) - } - // no prefix - MetadataJsonSchema::DetailedSchema => Ok(Value::from(hex::encode(bytes))), - }?, - ), - TransactionMetadatumEnum::Text(s) => ("string", Value::from(s.clone())), - }; - // potentially wrap value in a keyed map to represent more types - if supports_tagged_values(schema) { - let mut wrapper = serde_json::map::Map::with_capacity(1); - wrapper.insert(String::from(type_key), value); - Ok(Value::from(wrapper)) - } else { - Ok(value) - } -} - -// serialization -impl cbor_event::se::Serialize for MetadataMap { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?; - for (key, value) in &self.0 { - key.serialize(serializer)?; - value.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for MetadataMap { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut table = LinkedHashMap::new(); - let mut entries: Vec<(TransactionMetadatum, TransactionMetadatum)> = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.map()?; - while match len { - cbor_event::Len::Len(n) => entries.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - let key = TransactionMetadatum::deserialize(raw)?; - let value = TransactionMetadatum::deserialize(raw)?; - entries.push((key.clone(), value)); - } - Ok(()) - })() - .map_err(|e| e.annotate("MetadataMap"))?; - entries.iter().for_each(|(k, v)| { - if table.insert(k.clone(), v.clone()).is_some() { - // Turns out this is totally possible on the actual blockchain - // return Err(DeserializeFailure::DuplicateKey(Key::Str(String::from("some complicated/unsupported type"))).into()); - } - }); - Ok(Self(table)) - } -} - -impl cbor_event::se::Serialize for MetadataList { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for MetadataList { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(TransactionMetadatum::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("MetadataList"))?; - Ok(Self(arr)) - } -} - -impl cbor_event::se::Serialize for TransactionMetadatumEnum { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - match self { - TransactionMetadatumEnum::MetadataMap(x) => x.serialize(serializer), - TransactionMetadatumEnum::MetadataList(x) => x.serialize(serializer), - TransactionMetadatumEnum::Int(x) => x.serialize(serializer), - TransactionMetadatumEnum::Bytes(x) => serializer.write_bytes(&x), - TransactionMetadatumEnum::Text(x) => serializer.write_text(&x), - } - } -} - -impl Deserialize for TransactionMetadatumEnum { - fn deserialize(raw: &mut Deserializer) -> Result { - match raw.cbor_type()? { - CBORType::Array => { - MetadataList::deserialize(raw).map(TransactionMetadatumEnum::MetadataList) - } - CBORType::Map => { - MetadataMap::deserialize(raw).map(TransactionMetadatumEnum::MetadataMap) - } - CBORType::Bytes => TransactionMetadatum::new_bytes(raw.bytes()?) - .map(|m| m.0) - .map_err(|e| DeserializeFailure::Metadata(e).into()), - CBORType::Text => TransactionMetadatum::new_text(raw.text()?) - .map(|m| m.0) - .map_err(|e| DeserializeFailure::Metadata(e).into()), - CBORType::UnsignedInteger | CBORType::NegativeInteger => { - Int::deserialize(raw).map(TransactionMetadatumEnum::Int) - } - _ => Err(DeserializeError::new( - "TransactionMetadatumEnum", - DeserializeFailure::NoVariantMatched.into(), - )), - } - } -} - -impl cbor_event::se::Serialize for TransactionMetadatum { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - self.0.serialize(serializer) - } -} - -impl Deserialize for TransactionMetadatum { - fn deserialize(raw: &mut Deserializer) -> Result { - Ok(Self(TransactionMetadatumEnum::deserialize(raw)?)) - } -} - -impl cbor_event::se::Serialize for TransactionMetadatumLabels { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for TransactionMetadatumLabels { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(TransactionMetadatumLabel::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("TransactionMetadatumLabels"))?; - Ok(Self(arr)) - } -} - -impl cbor_event::se::Serialize for GeneralTransactionMetadata { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?; - for (key, value) in &self.0 { - key.serialize(serializer)?; - value.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for GeneralTransactionMetadata { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut table = LinkedHashMap::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.map()?; - while match len { - cbor_event::Len::Len(n) => table.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - let key = TransactionMetadatumLabel::deserialize(raw)?; - let value = TransactionMetadatum::deserialize(raw)?; - if table.insert(key.clone(), value).is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Str(String::from( - "some complicated/unsupported type", - ))) - .into()); - } - } - Ok(()) - })() - .map_err(|e| e.annotate("GeneralTransactionMetadata"))?; - Ok(Self(table)) - } -} - -impl cbor_event::se::Serialize for AuxiliaryData { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - // we still serialize using the shelley-mary era format as it is still supported - // and it takes up less space on-chain so this should be better for scaling. - // Plus the code was already written for shelley-mary anyway - if !self.prefer_alonzo_format && self.metadata.is_some() && self.plutus_scripts.is_none() { - match &self.native_scripts() { - Some(native_scripts) => { - serializer.write_array(cbor_event::Len::Len(2))?; - self.metadata.as_ref().unwrap().serialize(serializer)?; - native_scripts.serialize(serializer) - } - None => self.metadata.as_ref().unwrap().serialize(serializer), - } - } else { - let plutus_added_length = match &self.plutus_scripts { - Some(scripts) => 1 + (scripts.has_version(&Language::new_plutus_v2()) as u64), - _ => 0, - }; - // new format with plutus support - serializer.write_tag(259u64)?; - serializer.write_map(cbor_event::Len::Len( - opt64(&self.metadata) + opt64(&self.native_scripts) + plutus_added_length, - ))?; - if let Some(metadata) = &self.metadata { - serializer.write_unsigned_integer(0)?; - metadata.serialize(serializer)?; - } - if let Some(native_scripts) = &self.native_scripts { - serializer.write_unsigned_integer(1)?; - native_scripts.serialize(serializer)?; - } - if let Some(plutus_scripts) = &self.plutus_scripts { - serializer.write_unsigned_integer(2)?; - plutus_scripts - .by_version(&Language::new_plutus_v1()) - .serialize(serializer)?; - let v2 = plutus_scripts.by_version(&Language::new_plutus_v2()); - if v2.len() > 0 { - serializer.write_unsigned_integer(3)?; - v2.serialize(serializer)?; - } - } - Ok(serializer) - } - } -} - -impl Deserialize for AuxiliaryData { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - match raw.cbor_type()? { - // alonzo format - CBORType::Tag => { - let tag = raw.tag()?; - if tag != 259 { - return Err(DeserializeError::new( - "AuxiliaryData", - DeserializeFailure::TagMismatch { - found: tag, - expected: 259, - }, - )); - } - let len = raw.map()?; - let mut read_len = CBORReadLen::new(len); - let mut metadata = None; - let mut native_scripts = None; - let mut plutus_scripts_v1 = None; - let mut plutus_scripts_v2 = None; - let mut read = 0; - while match len { - cbor_event::Len::Len(n) => read < n as usize, - cbor_event::Len::Indefinite => true, - } { - match raw.cbor_type()? { - CBORType::UnsignedInteger => match raw.unsigned_integer()? { - 0 => { - if metadata.is_some() { - return Err( - DeserializeFailure::DuplicateKey(Key::Uint(0)).into() - ); - } - metadata = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(GeneralTransactionMetadata::deserialize(raw)?) - })() - .map_err(|e| e.annotate("metadata"))?, - ); - } - 1 => { - if native_scripts.is_some() { - return Err( - DeserializeFailure::DuplicateKey(Key::Uint(1)).into() - ); - } - native_scripts = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(NativeScripts::deserialize(raw)?) - })() - .map_err(|e| e.annotate("native_scripts"))?, - ); - } - 2 => { - if plutus_scripts_v1.is_some() { - return Err( - DeserializeFailure::DuplicateKey(Key::Uint(2)).into() - ); - } - plutus_scripts_v1 = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(PlutusScripts::deserialize(raw)?) - })() - .map_err(|e| e.annotate("plutus_scripts_v1"))?, - ); - } - 3 => { - if plutus_scripts_v2.is_some() { - return Err( - DeserializeFailure::DuplicateKey(Key::Uint(3)).into() - ); - } - plutus_scripts_v2 = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(PlutusScripts::deserialize(raw)? - .map_as_version(&Language::new_plutus_v2())) - })() - .map_err(|e| e.annotate("plutus_scripts_v2"))?, - ); - } - unknown_key => { - return Err(DeserializeFailure::UnknownKey(Key::Uint( - unknown_key, - )) - .into()) - } - }, - CBORType::Text => match raw.text()?.as_str() { - unknown_key => { - return Err(DeserializeFailure::UnknownKey(Key::Str( - unknown_key.to_owned(), - )) - .into()) - } - }, - CBORType::Special => match len { - cbor_event::Len::Len(_) => { - return Err(DeserializeFailure::BreakInDefiniteLen.into()) - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => break, - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - }, - other_type => { - return Err(DeserializeFailure::UnexpectedKeyType(other_type).into()) - } - } - read += 1; - } - read_len.finish()?; - let plutus_scripts = match (plutus_scripts_v1, plutus_scripts_v2) { - (Some(v1), Some(v2)) => Some(v1.merge(&v2)), - (Some(v1), _) => Some(v1), - (_, Some(v2)) => Some(v2), - _ => None, - }; - Ok(Self { - metadata, - native_scripts, - plutus_scripts, - prefer_alonzo_format: true, - }) - } - // shelley mary format (still valid for alonzo) - CBORType::Array => { - let len = raw.array()?; - let mut read_len = CBORReadLen::new(len); - read_len.read_elems(2)?; - let metadata = (|| -> Result<_, DeserializeError> { - Ok(GeneralTransactionMetadata::deserialize(raw)?) - })() - .map_err(|e| e.annotate("metadata"))?; - let native_scripts = (|| -> Result<_, DeserializeError> { - Ok(NativeScripts::deserialize(raw)?) - })() - .map_err(|e| e.annotate("native_scripts"))?; - match len { - cbor_event::Len::Len(_) => (), - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => (), - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - Ok(Self { - metadata: Some(metadata), - native_scripts: Some(native_scripts), - plutus_scripts: None, - prefer_alonzo_format: false, - }) - } - // shelley pre-mary format (still valid for alonzo + mary) - CBORType::Map => Ok(Self { - metadata: Some( - GeneralTransactionMetadata::deserialize(raw) - .map_err(|e| e.annotate("metadata"))?, - ), - native_scripts: None, - plutus_scripts: None, - prefer_alonzo_format: false, - }), - _ => return Err(DeserializeFailure::NoVariantMatched)?, - } - })() - .map_err(|e| e.annotate("AuxiliaryData")) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn binary_encoding() { - let input_bytes = (0..1000).map(|x| x as u8).collect::>(); - let metadata = encode_arbitrary_bytes_as_metadatum(input_bytes.as_ref()); - let output_bytes = decode_arbitrary_bytes_from_metadatum(&metadata).expect("decode failed"); - assert_eq!(input_bytes, output_bytes); - } - - #[test] - fn json_encoding_no_conversions() { - let input_str = String::from("{\"receiver_id\": \"SJKdj34k3jjKFDKfjFUDfdjkfd\",\"sender_id\": \"jkfdsufjdk34h3Sdfjdhfduf873\",\"comment\": \"happy birthday\",\"tags\": [0, 264, -1024, 32]}"); - let metadata = - encode_json_str_to_metadatum(input_str.clone(), MetadataJsonSchema::NoConversions) - .expect("encode failed"); - let map = metadata.as_map().unwrap(); - assert_eq!( - map.get_str("receiver_id").unwrap().as_text().unwrap(), - "SJKdj34k3jjKFDKfjFUDfdjkfd" - ); - assert_eq!( - map.get_str("sender_id").unwrap().as_text().unwrap(), - "jkfdsufjdk34h3Sdfjdhfduf873" - ); - assert_eq!( - map.get_str("comment").unwrap().as_text().unwrap(), - "happy birthday" - ); - let tags = map.get_str("tags").unwrap().as_list().unwrap(); - let tags_i32 = tags - .0 - .iter() - .map(|md| md.as_int().unwrap().as_i32_or_fail().unwrap()) - .collect::>(); - assert_eq!(tags_i32, vec![0, 264, -1024, 32]); - let output_str = decode_metadatum_to_json_str(&metadata, MetadataJsonSchema::NoConversions) - .expect("decode failed"); - let input_json: serde_json::Value = serde_json::from_str(&input_str).unwrap(); - let output_json: serde_json::Value = serde_json::from_str(&output_str).unwrap(); - assert_eq!(input_json, output_json); - } - - #[test] - fn json_encoding_basic() { - let input_str = String::from( - "{\"0x8badf00d\": \"0xdeadbeef\",\"9\": 5,\"obj\": {\"a\":[{\"5\": 2},{}]}}", - ); - let metadata = - encode_json_str_to_metadatum(input_str.clone(), MetadataJsonSchema::BasicConversions) - .expect("encode failed"); - json_encoding_check_example_metadatum(&metadata); - let output_str = - decode_metadatum_to_json_str(&metadata, MetadataJsonSchema::BasicConversions) - .expect("decode failed"); - let input_json: serde_json::Value = serde_json::from_str(&input_str).unwrap(); - let output_json: serde_json::Value = serde_json::from_str(&output_str).unwrap(); - assert_eq!(input_json, output_json); - } - - #[test] - fn json_encoding_detailed() { - let input_str = String::from( - "{\"map\":[ - { - \"k\":{\"bytes\":\"8badf00d\"}, - \"v\":{\"bytes\":\"deadbeef\"} - }, - { - \"k\":{\"int\":9}, - \"v\":{\"int\":5} - }, - { - \"k\":{\"string\":\"obj\"}, - \"v\":{\"map\":[ - { - \"k\":{\"string\":\"a\"}, - \"v\":{\"list\":[ - {\"map\":[ - { - \"k\":{\"int\":5}, - \"v\":{\"int\":2} - } - ]}, - {\"map\":[ - ]} - ]} - } - ]} - } - ]}", - ); - let metadata = - encode_json_str_to_metadatum(input_str.clone(), MetadataJsonSchema::DetailedSchema) - .expect("encode failed"); - json_encoding_check_example_metadatum(&metadata); - let output_str = - decode_metadatum_to_json_str(&metadata, MetadataJsonSchema::DetailedSchema) - .expect("decode failed"); - let input_json: serde_json::Value = serde_json::from_str(&input_str).unwrap(); - let output_json: serde_json::Value = serde_json::from_str(&output_str).unwrap(); - assert_eq!(input_json, output_json); - } - - fn json_encoding_check_example_metadatum(metadata: &TransactionMetadatum) { - let map = metadata.as_map().unwrap(); - assert_eq!( - map.get(&TransactionMetadatum::new_bytes(hex::decode("8badf00d").unwrap()).unwrap()) - .unwrap() - .as_bytes() - .unwrap(), - hex::decode("deadbeef").unwrap() - ); - assert_eq!( - map.get_i32(9) - .unwrap() - .as_int() - .unwrap() - .as_i32_or_fail() - .unwrap(), - 5 - ); - let inner_map = map.get_str("obj").unwrap().as_map().unwrap(); - let a = inner_map.get_str("a").unwrap().as_list().unwrap(); - let a1 = a.get(0).as_map().unwrap(); - assert_eq!( - a1.get_i32(5) - .unwrap() - .as_int() - .unwrap() - .as_i32_or_fail() - .unwrap(), - 2 - ); - let a2 = a.get(1).as_map().unwrap(); - assert_eq!(a2.keys().len(), 0); - } - - #[test] - fn json_encoding_detailed_complex_key() { - let input_str = String::from( - "{\"map\":[ - { - \"k\":{\"list\":[ - {\"map\": [ - { - \"k\": {\"int\": 5}, - \"v\": {\"int\": -7} - }, - { - \"k\": {\"string\": \"hello\"}, - \"v\": {\"string\": \"world\"} - } - ]}, - {\"bytes\": \"ff00ff00\"} - ]}, - \"v\":{\"int\":5} - } - ]}", - ); - let metadata = - encode_json_str_to_metadatum(input_str.clone(), MetadataJsonSchema::DetailedSchema) - .expect("encode failed"); - - let map = metadata.as_map().unwrap(); - let key = map.keys().get(0); - assert_eq!( - map.get(&key) - .unwrap() - .as_int() - .unwrap() - .as_i32_or_fail() - .unwrap(), - 5 - ); - let key_list = key.as_list().unwrap(); - assert_eq!(key_list.len(), 2); - let key_map = key_list.get(0).as_map().unwrap(); - assert_eq!( - key_map - .get_i32(5) - .unwrap() - .as_int() - .unwrap() - .as_i32_or_fail() - .unwrap(), - -7 - ); - assert_eq!( - key_map.get_str("hello").unwrap().as_text().unwrap(), - "world" - ); - let key_bytes = key_list.get(1).as_bytes().unwrap(); - assert_eq!(key_bytes, hex::decode("ff00ff00").unwrap()); - - let output_str = - decode_metadatum_to_json_str(&metadata, MetadataJsonSchema::DetailedSchema) - .expect("decode failed"); - let input_json: serde_json::Value = serde_json::from_str(&input_str).unwrap(); - let output_json: serde_json::Value = serde_json::from_str(&output_str).unwrap(); - assert_eq!(input_json, output_json); - } - - #[test] - fn metadata_serialize() { - let mut gmd = GeneralTransactionMetadata::new(); - let mdatum = TransactionMetadatum::new_text(String::from("string md")).unwrap(); - gmd.insert(&to_bignum(100), &mdatum); - let mut aux_data = AuxiliaryData::new(); - // alonzo (empty) - let ad0_deser = AuxiliaryData::from_bytes(aux_data.to_bytes()).unwrap(); - assert_eq!(aux_data.to_bytes(), ad0_deser.to_bytes()); - // pre-mary shelley - aux_data.set_metadata(&gmd); - let ad1_deser = AuxiliaryData::from_bytes(aux_data.to_bytes()).unwrap(); - assert_eq!(aux_data.to_bytes(), ad1_deser.to_bytes()); - // mary shelley - let mut native_scripts = NativeScripts::new(); - native_scripts.add(&NativeScript::new_timelock_start(&TimelockStart::new(20))); - aux_data.set_native_scripts(&native_scripts); - let ad2_deser = AuxiliaryData::from_bytes(aux_data.to_bytes()).unwrap(); - assert_eq!(aux_data.to_bytes(), ad2_deser.to_bytes()); - // alonzo - let mut plutus_scripts = PlutusScripts::new(); - plutus_scripts.add(&PlutusScript::new([61u8; 29].to_vec())); - aux_data.set_plutus_scripts(&plutus_scripts); - let ad3_deser = AuxiliaryData::from_bytes(aux_data.to_bytes()).unwrap(); - assert_eq!(aux_data.to_bytes(), ad3_deser.to_bytes()); - } - - #[test] - fn alonzo_metadata_round_trip() { - let bytes_alonzo = hex::decode("d90103a100a1186469737472696e67206d64").unwrap(); - let aux_alonzo = AuxiliaryData::from_bytes(bytes_alonzo.clone()).unwrap(); - assert!(aux_alonzo.prefer_alonzo_format); - assert_eq!(aux_alonzo.to_bytes(), bytes_alonzo); - - let bytes_pre_alonzo = hex::decode("a1186469737472696e67206d64").unwrap(); - let aux_pre_alonzo = AuxiliaryData::from_bytes(bytes_pre_alonzo.clone()).unwrap(); - assert!(!aux_pre_alonzo.prefer_alonzo_format); - assert_eq!(aux_pre_alonzo.to_bytes(), bytes_pre_alonzo); - } - - #[test] - fn metadatum_map_duplicate_keys() { - let bytes = hex::decode("a105a4781b232323232323232323232323232323232323232323232323232323827840232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323237840232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323236e232323232323232323232323232382a36f2323232323232323232323232323236a323030302d30312d303166232323232323784023232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323712323232323232323232323232323232323784023232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323a36f2323232323232323232323232323236a323030302d30312d303166232323232323784023232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323712323232323232323232323232323232323784023232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323752323232323232323232323232323232323232323236a323030302d30312d3031752323232323232323232323232323232323232323236a323030302d30312d3031").unwrap(); - TransactionMetadatum::from_bytes(bytes).unwrap(); - } - - #[test] - fn test_auxiliary_data_roundtrip() { - fn auxiliary_data_roundtrip(plutus_scripts: &PlutusScripts) { - let mut aux = AuxiliaryData::new(); - let mut metadata = GeneralTransactionMetadata::new(); - metadata.insert( - &to_bignum(42), - &encode_json_str_to_metadatum( - "{ \"test\": 148 }".to_string(), - MetadataJsonSchema::BasicConversions, - ) - .unwrap(), - ); - aux.set_metadata(&metadata); - aux.set_native_scripts(&NativeScripts::from(vec![ - NativeScript::new_timelock_start(&TimelockStart::new(1234556)), - ])); - aux.set_plutus_scripts(plutus_scripts); - assert_eq!(AuxiliaryData::from_bytes(aux.to_bytes()).unwrap(), aux); - } - - let bytes = hex::decode("4e4d01000033222220051200120011").unwrap(); - let script_v1 = PlutusScript::from_bytes(bytes.clone()).unwrap(); - let script_v2 = PlutusScript::from_bytes_v2(bytes.clone()).unwrap(); - - auxiliary_data_roundtrip(&PlutusScripts(vec![])); - auxiliary_data_roundtrip(&PlutusScripts(vec![script_v1.clone()])); - auxiliary_data_roundtrip(&PlutusScripts(vec![script_v2.clone()])); - auxiliary_data_roundtrip(&PlutusScripts(vec![script_v1.clone(), script_v2.clone()])); - } -} diff --git a/rust/src/plutus.rs b/rust/src/plutus.rs deleted file mode 100644 index ce80ba21..00000000 --- a/rust/src/plutus.rs +++ /dev/null @@ -1,2690 +0,0 @@ -use super::*; -use core::hash::Hasher; -use linked_hash_map::LinkedHashMap; -use std::hash::Hash; -use std::io::{BufRead, Seek, Write}; - -// This library was code-generated using an experimental CDDL to rust tool: -// https://github.com/Emurgo/cddl-codegen - -use cbor_event::{ - self, - de::Deserializer, - se::{Serialize, Serializer}, -}; - -use schemars::JsonSchema; - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub struct PlutusScript { - bytes: Vec, - language: LanguageKind, -} - -to_from_bytes!(PlutusScript); - -#[wasm_bindgen] -impl PlutusScript { - /** - * Creates a new Plutus script from the RAW bytes of the compiled script. - * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) - * If you creating this from those you should use PlutusScript::from_bytes() instead. - */ - pub fn new(bytes: Vec) -> PlutusScript { - Self::new_with_version(bytes, &Language::new_plutus_v1()) - } - - /** - * Creates a new Plutus script from the RAW bytes of the compiled script. - * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) - * If you creating this from those you should use PlutusScript::from_bytes() instead. - */ - pub fn new_v2(bytes: Vec) -> PlutusScript { - Self::new_with_version(bytes, &Language::new_plutus_v2()) - } - - /** - * Creates a new Plutus script from the RAW bytes of the compiled script. - * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) - * If you creating this from those you should use PlutusScript::from_bytes() instead. - */ - pub fn new_with_version(bytes: Vec, language: &Language) -> PlutusScript { - Self { - bytes, - language: language.0.clone(), - } - } - - /** - * The raw bytes of this compiled Plutus script. - * If you need "cborBytes" for cardano-cli use PlutusScript::to_bytes() instead. - */ - pub fn bytes(&self) -> Vec { - self.bytes.clone() - } - - /// Same as `.from_bytes` but will consider the script as requiring the Plutus Language V2 - pub fn from_bytes_v2(bytes: Vec) -> Result { - Self::from_bytes_with_version(bytes, &Language::new_plutus_v2()) - } - - /// Same as `.from_bytes` but will consider the script as requiring the specified language version - pub fn from_bytes_with_version( - bytes: Vec, - language: &Language, - ) -> Result { - Ok(Self::new_with_version( - Self::from_bytes(bytes)?.bytes, - language, - )) - } - - /// Same as .from_hex but will consider the script as requiring the specified language version - pub fn from_hex_with_version( - hex_str: &str, - language: &Language, - ) -> Result { - Ok(Self::new_with_version( - Self::from_hex(hex_str)?.bytes, - language, - )) - } - - pub fn hash(&self) -> ScriptHash { - let mut bytes = Vec::with_capacity(self.bytes.len() + 1); - // https://github.com/input-output-hk/cardano-ledger/blob/master/eras/babbage/test-suite/cddl-files/babbage.cddl#L413 - bytes.extend_from_slice(&vec![self.script_namespace() as u8]); - bytes.extend_from_slice(&self.bytes); - ScriptHash::from(blake2b224(bytes.as_ref())) - } - - pub fn language_version(&self) -> Language { - Language(self.language.clone()) - } - - pub(crate) fn script_namespace(&self) -> ScriptHashNamespace { - match self.language { - LanguageKind::PlutusV1 => ScriptHashNamespace::PlutusScript, - LanguageKind::PlutusV2 => ScriptHashNamespace::PlutusScriptV2, - } - } - - pub(crate) fn clone_as_version(&self, language: &Language) -> PlutusScript { - Self::new_with_version(self.bytes.clone(), language) - } -} - -impl serde::Serialize for PlutusScript { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - serializer.serialize_str(&hex::encode(&self.bytes)) - } -} - -impl<'de> serde::de::Deserialize<'de> for PlutusScript { - fn deserialize(deserializer: D) -> Result - where - D: serde::de::Deserializer<'de>, - { - let s = ::deserialize(deserializer)?; - hex::decode(&s) - .map(|bytes| PlutusScript::new(bytes)) - .map_err(|_err| { - serde::de::Error::invalid_value( - serde::de::Unexpected::Str(&s), - &"PlutusScript as hex string e.g. F8AB28C2 (without CBOR bytes tag)", - ) - }) - } -} - -impl JsonSchema for PlutusScript { - fn schema_name() -> String { - String::from("PlutusScript") - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - String::json_schema(gen) - } - fn is_referenceable() -> bool { - String::is_referenceable() - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct PlutusScripts(pub(crate) Vec); - -impl_to_from!(PlutusScripts); - -#[wasm_bindgen] -impl PlutusScripts { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> PlutusScript { - self.0[index].clone() - } - - pub fn add(&mut self, elem: &PlutusScript) { - self.0.push(elem.clone()); - } - - pub(crate) fn by_version(&self, language: &Language) -> PlutusScripts { - PlutusScripts( - self.0 - .iter() - .filter(|s| s.language_version().eq(language)) - .map(|s| s.clone()) - .collect(), - ) - } - - pub(crate) fn has_version(&self, language: &Language) -> bool { - self.0.iter().any(|s| s.language_version().eq(language)) - } - - pub(crate) fn merge(&self, other: &PlutusScripts) -> PlutusScripts { - let mut res = self.clone(); - for s in &other.0 { - res.add(s); - } - res - } - - pub(crate) fn map_as_version(&self, language: &Language) -> PlutusScripts { - let mut res = PlutusScripts::new(); - for s in &self.0 { - res.add(&s.clone_as_version(language)); - } - res - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] -pub struct ConstrPlutusData { - alternative: BigNum, - data: PlutusList, -} - -to_from_bytes!(ConstrPlutusData); - -#[wasm_bindgen] -impl ConstrPlutusData { - pub fn alternative(&self) -> BigNum { - self.alternative.clone() - } - - pub fn data(&self) -> PlutusList { - self.data.clone() - } - - pub fn new(alternative: &BigNum, data: &PlutusList) -> Self { - Self { - alternative: alternative.clone(), - data: data.clone(), - } - } -} - -impl ConstrPlutusData { - // see: https://github.com/input-output-hk/plutus/blob/1f31e640e8a258185db01fa899da63f9018c0e85/plutus-core/plutus-core/src/PlutusCore/Data.hs#L61 - // We don't directly serialize the alternative in the tag, instead the scheme is: - // - Alternatives 0-6 -> tags 121-127, followed by the arguments in a list - // - Alternatives 7-127 -> tags 1280-1400, followed by the arguments in a list - // - Any alternatives, including those that don't fit in the above -> tag 102 followed by a list containing - // an unsigned integer for the actual alternative, and then the arguments in a (nested!) list. - const GENERAL_FORM_TAG: u64 = 102; - - // None -> needs general tag serialization, not compact - fn alternative_to_compact_cbor_tag(alt: u64) -> Option { - if alt <= 6 { - Some(121 + alt) - } else if alt >= 7 && alt <= 127 { - Some(1280 - 7 + alt) - } else { - None - } - } - - // None -> General tag(=102) OR Invalid CBOR tag for this scheme - fn compact_cbor_tag_to_alternative(cbor_tag: u64) -> Option { - if cbor_tag >= 121 && cbor_tag <= 127 { - Some(cbor_tag - 121) - } else if cbor_tag >= 1280 && cbor_tag <= 1400 { - Some(cbor_tag - 1280 + 7) - } else { - None - } - } -} - -#[wasm_bindgen] -#[derive( - Clone, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub struct CostModel(Vec); - -impl_to_from!(CostModel); - -#[wasm_bindgen] -impl CostModel { - /// Creates a new CostModels instance of an unrestricted length - pub fn new() -> Self { - Self(Vec::new()) - } - - /// Sets the cost at the specified index to the specified value. - /// In case the operation index is larger than the previous largest used index, - /// it will fill any inbetween indexes with zeroes - pub fn set(&mut self, operation: usize, cost: &Int) -> Result { - let len = self.0.len(); - let idx = operation.clone(); - if idx >= len { - for _ in 0..(idx - len + 1) { - self.0.push(Int::new_i32(0)); - } - } - let old = self.0[idx].clone(); - self.0[idx] = cost.clone(); - Ok(old) - } - - pub fn get(&self, operation: usize) -> Result { - let max = self.0.len(); - if operation >= max { - return Err(JsError::from_str(&format!( - "CostModel operation {} out of bounds. Max is {}", - operation, max - ))); - } - Ok(self.0[operation].clone()) - } - - pub fn len(&self) -> usize { - self.0.len() - } -} - -impl From> for CostModel { - fn from(values: Vec) -> Self { - CostModel(values.iter().map(|x| Int(*x)).collect()) - } -} - -#[wasm_bindgen] -#[derive( - Clone, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub struct Costmdls(std::collections::BTreeMap); - -impl_to_from!(Costmdls); - -#[wasm_bindgen] -impl Costmdls { - pub fn new() -> Self { - Self(std::collections::BTreeMap::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn insert(&mut self, key: &Language, value: &CostModel) -> Option { - self.0.insert(key.clone(), value.clone()) - } - - pub fn get(&self, key: &Language) -> Option { - self.0.get(key).map(|v| v.clone()) - } - - pub fn keys(&self) -> Languages { - Languages(self.0.iter().map(|(k, _v)| k.clone()).collect::>()) - } - - pub(crate) fn language_views_encoding(&self) -> Vec { - let mut serializer = Serializer::new_vec(); - fn key_len(l: &Language) -> usize { - if l.kind() == LanguageKind::PlutusV1 { - let mut serializer = Serializer::new_vec(); - serializer.write_bytes(l.to_bytes()).unwrap(); - return serializer.finalize().len(); - } - l.to_bytes().len() - } - let mut keys: Vec = self.0.iter().map(|(k, _v)| k.clone()).collect(); - // keys must be in canonical ordering first - keys.sort_by(|lhs, rhs| match key_len(lhs).cmp(&key_len(rhs)) { - std::cmp::Ordering::Equal => lhs.cmp(&rhs), - len_order => len_order, - }); - serializer - .write_map(cbor_event::Len::Len(self.0.len() as u64)) - .unwrap(); - for key in keys.iter() { - if key.kind() == LanguageKind::PlutusV1 { - serializer.write_bytes(key.to_bytes()).unwrap(); - let cost_model = self.0.get(&key).unwrap(); - // Due to a bug in the cardano-node input-output-hk/cardano-ledger-specs/issues/2512 - // we must use indefinite length serialization in this inner bytestring to match it - let mut cost_model_serializer = Serializer::new_vec(); - cost_model_serializer - .write_array(cbor_event::Len::Indefinite) - .unwrap(); - for cost in &cost_model.0 { - cost.serialize(&mut cost_model_serializer).unwrap(); - } - cost_model_serializer - .write_special(cbor_event::Special::Break) - .unwrap(); - serializer - .write_bytes(cost_model_serializer.finalize()) - .unwrap(); - } else { - serializer.serialize(key).unwrap(); - serializer.serialize(self.0.get(&key).unwrap()).unwrap(); - } - } - serializer.finalize() - } - - pub fn retain_language_versions(&self, languages: &Languages) -> Costmdls { - let mut result = Costmdls::new(); - for lang in &languages.0 { - match self.get(&lang) { - Some(costmodel) => { - result.insert(&lang, &costmodel); - } - _ => {} - } - } - result - } -} - -#[wasm_bindgen] -#[derive( - Clone, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub struct ExUnitPrices { - mem_price: SubCoin, - step_price: SubCoin, -} - -impl_to_from!(ExUnitPrices); - -#[wasm_bindgen] -impl ExUnitPrices { - pub fn mem_price(&self) -> SubCoin { - self.mem_price.clone() - } - - pub fn step_price(&self) -> SubCoin { - self.step_price.clone() - } - - pub fn new(mem_price: &SubCoin, step_price: &SubCoin) -> Self { - Self { - mem_price: mem_price.clone(), - step_price: step_price.clone(), - } - } -} - -#[wasm_bindgen] -#[derive( - Clone, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub struct ExUnits { - mem: BigNum, - steps: BigNum, -} - -impl_to_from!(ExUnits); - -#[wasm_bindgen] -impl ExUnits { - pub fn mem(&self) -> BigNum { - self.mem.clone() - } - - pub fn steps(&self) -> BigNum { - self.steps.clone() - } - - pub fn new(mem: &BigNum, steps: &BigNum) -> Self { - Self { - mem: mem.clone(), - steps: steps.clone(), - } - } -} - -#[wasm_bindgen] -#[derive( - Clone, - Copy, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub enum LanguageKind { - PlutusV1 = 0, - PlutusV2 = 1, -} - -impl LanguageKind { - fn from_u64(x: u64) -> Option { - match x { - 0 => Some(LanguageKind::PlutusV1), - 1 => Some(LanguageKind::PlutusV2), - _ => None, - } - } -} - -#[wasm_bindgen] -#[derive( - Clone, - Copy, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub struct Language(LanguageKind); - -impl_to_from!(Language); - -#[wasm_bindgen] -impl Language { - pub fn new_plutus_v1() -> Self { - Self(LanguageKind::PlutusV1) - } - - pub fn new_plutus_v2() -> Self { - Self(LanguageKind::PlutusV2) - } - - pub fn kind(&self) -> LanguageKind { - self.0.clone() - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct Languages(pub(crate) Vec); - -#[wasm_bindgen] -impl Languages { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> Language { - self.0[index] - } - - pub fn add(&mut self, elem: Language) { - self.0.push(elem); - } - - pub fn list() -> Languages { - Languages(vec![Language::new_plutus_v1(), Language::new_plutus_v2()]) - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] -pub struct PlutusMap(LinkedHashMap); - -to_from_bytes!(PlutusMap); - -#[wasm_bindgen] -impl PlutusMap { - pub fn new() -> Self { - Self(LinkedHashMap::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn insert(&mut self, key: &PlutusData, value: &PlutusData) -> Option { - self.0.insert(key.clone(), value.clone()) - } - - pub fn get(&self, key: &PlutusData) -> Option { - self.0.get(key).map(|v| v.clone()) - } - - pub fn keys(&self) -> PlutusList { - PlutusList { - elems: self.0.iter().map(|(k, _v)| k.clone()).collect::>(), - definite_encoding: None, - } - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub enum PlutusDataKind { - ConstrPlutusData, - Map, - List, - Integer, - Bytes, -} - -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] -pub enum PlutusDataEnum { - ConstrPlutusData(ConstrPlutusData), - Map(PlutusMap), - List(PlutusList), - Integer(BigInt), - Bytes(Vec), -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Ord, PartialOrd)] -pub struct PlutusData { - datum: PlutusDataEnum, - // We should always preserve the original datums when deserialized as this is NOT canonicized - // before computing datum hashes. So this field stores the original bytes to re-use. - original_bytes: Option>, -} - -impl std::cmp::PartialEq for PlutusData { - fn eq(&self, other: &Self) -> bool { - self.datum.eq(&other.datum) - } -} - -impl Hash for PlutusData { - fn hash(&self, state: &mut H) { - self.datum.hash(state) - } -} - -impl std::cmp::Eq for PlutusData {} - -to_from_bytes!(PlutusData); - -#[wasm_bindgen] -impl PlutusData { - pub fn new_constr_plutus_data(constr_plutus_data: &ConstrPlutusData) -> Self { - Self { - datum: PlutusDataEnum::ConstrPlutusData(constr_plutus_data.clone()), - original_bytes: None, - } - } - - /// Same as `.new_constr_plutus_data` but creates constr with empty data list - pub fn new_empty_constr_plutus_data(alternative: &BigNum) -> Self { - Self::new_constr_plutus_data(&ConstrPlutusData::new(alternative, &PlutusList::new())) - } - - pub fn new_single_value_constr_plutus_data( - alternative: &BigNum, - plutus_data: &PlutusData, - ) -> Self { - let mut list = PlutusList::new(); - list.add(plutus_data); - Self::new_constr_plutus_data(&ConstrPlutusData::new(alternative, &list)) - } - - pub fn new_map(map: &PlutusMap) -> Self { - Self { - datum: PlutusDataEnum::Map(map.clone()), - original_bytes: None, - } - } - - pub fn new_list(list: &PlutusList) -> Self { - Self { - datum: PlutusDataEnum::List(list.clone()), - original_bytes: None, - } - } - - pub fn new_integer(integer: &BigInt) -> Self { - Self { - datum: PlutusDataEnum::Integer(integer.clone()), - original_bytes: None, - } - } - - pub fn new_bytes(bytes: Vec) -> Self { - Self { - datum: PlutusDataEnum::Bytes(bytes), - original_bytes: None, - } - } - - pub fn kind(&self) -> PlutusDataKind { - match &self.datum { - PlutusDataEnum::ConstrPlutusData(_) => PlutusDataKind::ConstrPlutusData, - PlutusDataEnum::Map(_) => PlutusDataKind::Map, - PlutusDataEnum::List(_) => PlutusDataKind::List, - PlutusDataEnum::Integer(_) => PlutusDataKind::Integer, - PlutusDataEnum::Bytes(_) => PlutusDataKind::Bytes, - } - } - - pub fn as_constr_plutus_data(&self) -> Option { - match &self.datum { - PlutusDataEnum::ConstrPlutusData(x) => Some(x.clone()), - _ => None, - } - } - - pub fn as_map(&self) -> Option { - match &self.datum { - PlutusDataEnum::Map(x) => Some(x.clone()), - _ => None, - } - } - - pub fn as_list(&self) -> Option { - match &self.datum { - PlutusDataEnum::List(x) => Some(x.clone()), - _ => None, - } - } - - pub fn as_integer(&self) -> Option { - match &self.datum { - PlutusDataEnum::Integer(x) => Some(x.clone()), - _ => None, - } - } - - pub fn as_bytes(&self) -> Option> { - match &self.datum { - PlutusDataEnum::Bytes(x) => Some(x.clone()), - _ => None, - } - } - - pub fn to_json(&self, schema: PlutusDatumSchema) -> Result { - decode_plutus_datum_to_json_str(self, schema) - } - - pub fn from_json(json: &str, schema: PlutusDatumSchema) -> Result { - encode_json_str_to_plutus_datum(json, schema) - } - - pub fn from_address(address: &Address) -> Result { - let payment_cred = match &address.0 { - AddrType::Base(addr) => Ok(addr.payment_cred()), - AddrType::Enterprise(addr) => Ok(addr.payment_cred()), - AddrType::Ptr(addr) => Ok(addr.payment_cred()), - AddrType::Reward(addr) => Ok(addr.payment_cred()), - AddrType::Byron(_) => Err(JsError::from_str( - "Cannot convert Byron address to PlutusData", - )), - }?; - - let staking_data = match &address.0 { - AddrType::Base(addr) => { - let staking_bytes_data = PlutusData::from_stake_credential(&addr.stake_cred())?; - Some(PlutusData::new_single_value_constr_plutus_data( - &BigNum::from(0u32), - &staking_bytes_data, - )) - } - _ => None, - }; - - let pointer_data = match &address.0 { - AddrType::Ptr(addr) => Some(PlutusData::from_pointer(&addr.stake_pointer())?), - _ => None, - }; - - let payment_data = PlutusData::from_stake_credential(&payment_cred)?; - let staking_optional_data = match (staking_data, pointer_data) { - (Some(_), Some(_)) => Err(JsError::from_str( - "Address can't have both staking and pointer data", - )), - (Some(staking_data), None) => Ok(Some(staking_data)), - (None, Some(pointer_data)) => Ok(Some(pointer_data)), - (None, None) => Ok(None), - }?; - - let mut data_list = PlutusList::new(); - data_list.add(&payment_data); - if let Some(staking_optional_data) = staking_optional_data { - data_list.add(&PlutusData::new_single_value_constr_plutus_data( - &BigNum::from(0u32), - &staking_optional_data, - )); - } else { - data_list.add(&PlutusData::new_empty_constr_plutus_data(&BigNum::from( - 1u32, - ))); - } - - Ok(PlutusData::new_constr_plutus_data(&ConstrPlutusData::new( - &BigNum::from(0u32), - &data_list, - ))) - } - - fn from_stake_credential(stake_credential: &Credential) -> Result { - let (bytes_plutus_data, index) = match &stake_credential.0 { - StakeCredType::Key(key_hash) => ( - PlutusData::new_bytes(key_hash.to_bytes().to_vec()), - BigNum::from(0u32), - ), - StakeCredType::Script(script_hash) => ( - PlutusData::new_bytes(script_hash.to_bytes().to_vec()), - BigNum::from(1u32), - ), - }; - - Ok(PlutusData::new_single_value_constr_plutus_data( - &index, - &bytes_plutus_data, - )) - } - - fn from_pointer(pointer: &Pointer) -> Result { - let mut data_list = PlutusList::new(); - data_list.add(&PlutusData::new_integer(&pointer.slot_bignum().into())); - data_list.add(&PlutusData::new_integer(&pointer.tx_index_bignum().into())); - data_list.add(&PlutusData::new_integer( - &pointer.cert_index_bignum().into(), - )); - - Ok(PlutusData::new_constr_plutus_data(&ConstrPlutusData::new( - &BigNum::from(1u32), - &data_list, - ))) - } -} - -//TODO: replace this by cardano-node schemas -impl JsonSchema for PlutusData { - fn is_referenceable() -> bool { - String::is_referenceable() - } - - fn schema_name() -> String { - String::from("PlutusData") - } - - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - String::json_schema(gen) - } -} - -//TODO: need to figure out what schema to use here -impl serde::Serialize for PlutusData { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let json = decode_plutus_datum_to_json_str(self, PlutusDatumSchema::DetailedSchema) - .map_err(|ser_err| { - serde::ser::Error::custom(&format!("Serialization error: {:?}", ser_err)) - })?; - serializer.serialize_str(&json) - } -} - -impl<'de> serde::de::Deserialize<'de> for PlutusData { - fn deserialize(deserializer: D) -> Result - where - D: serde::de::Deserializer<'de>, - { - let datum_json = ::deserialize(deserializer)?; - encode_json_str_to_plutus_datum(&datum_json, PlutusDatumSchema::DetailedSchema).map_err( - |ser_err| serde::de::Error::custom(&format!("Deserialization error: {:?}", ser_err)), - ) - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Ord, PartialOrd, Hash, serde::Serialize, serde::Deserialize, JsonSchema)] -pub struct PlutusList { - elems: Vec, - // We should always preserve the original datums when deserialized as this is NOT canonicized - // before computing datum hashes. This field will default to cardano-cli behavior if None - // and will re-use the provided one if deserialized, unless the list is modified. - pub(crate) definite_encoding: Option, -} - -impl<'a> IntoIterator for &'a PlutusList { - type Item = &'a PlutusData; - type IntoIter = std::slice::Iter<'a, PlutusData>; - - fn into_iter(self) -> std::slice::Iter<'a, PlutusData> { - self.elems.iter() - } -} - -impl std::cmp::PartialEq for PlutusList { - fn eq(&self, other: &Self) -> bool { - self.elems.eq(&other.elems) - } -} - -impl std::cmp::Eq for PlutusList {} - -to_from_bytes!(PlutusList); - -#[wasm_bindgen] -impl PlutusList { - pub fn new() -> Self { - Self { - elems: Vec::new(), - definite_encoding: None, - } - } - - pub fn len(&self) -> usize { - self.elems.len() - } - - pub fn get(&self, index: usize) -> PlutusData { - self.elems[index].clone() - } - - pub fn add(&mut self, elem: &PlutusData) { - self.elems.push(elem.clone()); - self.definite_encoding = None; - } -} - -impl From> for PlutusList { - fn from(elems: Vec) -> Self { - Self { - elems, - definite_encoding: None, - } - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct Redeemer { - tag: RedeemerTag, - index: BigNum, - data: PlutusData, - ex_units: ExUnits, -} - -impl_to_from!(Redeemer); - -#[wasm_bindgen] -impl Redeemer { - pub fn tag(&self) -> RedeemerTag { - self.tag.clone() - } - - pub fn index(&self) -> BigNum { - self.index.clone() - } - - pub fn data(&self) -> PlutusData { - self.data.clone() - } - - pub fn ex_units(&self) -> ExUnits { - self.ex_units.clone() - } - - pub fn new(tag: &RedeemerTag, index: &BigNum, data: &PlutusData, ex_units: &ExUnits) -> Self { - Self { - tag: tag.clone(), - index: index.clone(), - data: data.clone(), - ex_units: ex_units.clone(), - } - } - - #[allow(dead_code)] - pub(crate) fn clone_with_index(&self, index: &BigNum) -> Self { - Self { - tag: self.tag.clone(), - index: index.clone(), - data: self.data.clone(), - ex_units: self.ex_units.clone(), - } - } - - pub(crate) fn clone_with_index_and_tag(&self, index: &BigNum, tag: &RedeemerTag) -> Self { - Self { - tag: tag.clone(), - index: index.clone(), - data: self.data.clone(), - ex_units: self.ex_units.clone(), - } - } -} - -#[wasm_bindgen] -#[derive( - Copy, - Clone, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub enum RedeemerTagKind { - Spend, - Mint, - Cert, - Reward, - Vote, - VotingProposal, -} - -#[wasm_bindgen] -#[derive( - Clone, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub struct RedeemerTag(RedeemerTagKind); - -impl_to_from!(RedeemerTag); - -#[wasm_bindgen] -impl RedeemerTag { - pub fn new_spend() -> Self { - Self(RedeemerTagKind::Spend) - } - - pub fn new_mint() -> Self { - Self(RedeemerTagKind::Mint) - } - - pub fn new_cert() -> Self { - Self(RedeemerTagKind::Cert) - } - - pub fn new_reward() -> Self { - Self(RedeemerTagKind::Reward) - } - - pub fn new_vote() -> Self { - Self(RedeemerTagKind::Vote) - } - - pub fn new_voting_proposal() -> Self { - Self(RedeemerTagKind::VotingProposal) - } - - pub fn kind(&self) -> RedeemerTagKind { - self.0 - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct Redeemers(pub(crate) Vec); - -impl_to_from!(Redeemers); - -#[wasm_bindgen] -impl Redeemers { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> Redeemer { - self.0[index].clone() - } - - pub fn add(&mut self, elem: &Redeemer) { - self.0.push(elem.clone()); - } - - pub fn total_ex_units(&self) -> Result { - let mut tot_mem = BigNum::zero(); - let mut tot_steps = BigNum::zero(); - for i in 0..self.0.len() { - let r: &Redeemer = &self.0[i]; - tot_mem = tot_mem.checked_add(&r.ex_units().mem())?; - tot_steps = tot_steps.checked_add(&r.ex_units().steps())?; - } - Ok(ExUnits::new(&tot_mem, &tot_steps)) - } -} - -impl From> for Redeemers { - fn from(values: Vec) -> Self { - Self(values) - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub struct Strings(Vec); - -#[wasm_bindgen] -impl Strings { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> String { - self.0[index].clone() - } - - pub fn add(&mut self, elem: String) { - self.0.push(elem); - } -} - -// json - -/// JSON <-> PlutusData conversion schemas. -/// Follows ScriptDataJsonSchema in cardano-cli defined at: -/// https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 -/// -/// All methods here have the following restrictions due to limitations on dependencies: -/// * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors -/// * Hex strings for bytes don't accept odd-length (half-byte) strings. -/// cardano-cli seems to support these however but it seems to be different than just 0-padding -/// on either side when tested so proceed with caution -#[wasm_bindgen] -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum PlutusDatumSchema { - /// ScriptDataJsonNoSchema in cardano-node. - /// - /// This is the format used by --script-data-value in cardano-cli - /// This tries to accept most JSON but does not support the full spectrum of Plutus datums. - /// From JSON: - /// * null/true/false/floats NOT supported - /// * strings starting with 0x are treated as hex bytes. All other strings are encoded as their utf8 bytes. - /// To JSON: - /// * ConstrPlutusData not supported in ANY FORM (neither keys nor values) - /// * Lists not supported in keys - /// * Maps not supported in keys - //// - BasicConversions, - /// ScriptDataJsonDetailedSchema in cardano-node. - /// - /// This is the format used by --script-data-file in cardano-cli - /// This covers almost all (only minor exceptions) Plutus datums, but the JSON must conform to a strict schema. - /// The schema specifies that ALL keys and ALL values must be contained in a JSON map with 2 cases: - /// 1. For ConstrPlutusData there must be two fields "constructor" contianing a number and "fields" containing its fields - /// e.g. { "constructor": 2, "fields": [{"int": 2}, {"list": [{"bytes": "CAFEF00D"}]}]} - /// 2. For all other cases there must be only one field named "int", "bytes", "list" or "map" - /// Integer's value is a JSON number e.g. {"int": 100} - /// Bytes' value is a hex string representing the bytes WITHOUT any prefix e.g. {"bytes": "CAFEF00D"} - /// Lists' value is a JSON list of its elements encoded via the same schema e.g. {"list": [{"bytes": "CAFEF00D"}]} - /// Maps' value is a JSON list of objects, one for each key-value pair in the map, with keys "k" and "v" - /// respectively with their values being the plutus datum encoded via this same schema - /// e.g. {"map": [ - /// {"k": {"int": 2}, "v": {"int": 5}}, - /// {"k": {"map": [{"k": {"list": [{"int": 1}]}, "v": {"bytes": "FF03"}}]}, "v": {"list": []}} - /// ]} - /// From JSON: - /// * null/true/false/floats NOT supported - /// * the JSON must conform to a very specific schema - /// To JSON: - /// * all Plutus datums should be fully supported outside of the integer range limitations outlined above. - //// - DetailedSchema, -} - -#[wasm_bindgen] -pub fn encode_json_str_to_plutus_datum( - json: &str, - schema: PlutusDatumSchema, -) -> Result { - let value = serde_json::from_str(json).map_err(|e| JsError::from_str(&e.to_string()))?; - encode_json_value_to_plutus_datum(value, schema) -} - -pub fn encode_json_value_to_plutus_datum( - value: serde_json::Value, - schema: PlutusDatumSchema, -) -> Result { - use serde_json::Value; - fn encode_number(x: serde_json::Number) -> Result { - if let Some(x) = x.as_u64() { - Ok(PlutusData::new_integer(&BigInt::from(x))) - } else if let Some(x) = x.as_i64() { - Ok(PlutusData::new_integer(&BigInt::from(x))) - } else { - Err(JsError::from_str("floats not allowed in plutus datums")) - } - } - fn encode_string( - s: &str, - schema: PlutusDatumSchema, - is_key: bool, - ) -> Result { - if schema == PlutusDatumSchema::BasicConversions { - if s.starts_with("0x") { - // this must be a valid hex bytestring after - hex::decode(&s[2..]) - .map(|bytes| PlutusData::new_bytes(bytes)) - .map_err(|err| JsError::from_str(&format!("Error decoding {}: {}", s, err))) - } else if is_key { - // try as an integer - BigInt::from_str(s) - .map(|x| PlutusData::new_integer(&x)) - // if not, we use the utf8 bytes of the string instead directly - .or_else(|_err| Ok(PlutusData::new_bytes(s.as_bytes().to_vec()))) - } else { - // can only be UTF bytes if not in a key and not prefixed by 0x - Ok(PlutusData::new_bytes(s.as_bytes().to_vec())) - } - } else { - if s.starts_with("0x") { - Err(JsError::from_str("Hex byte strings in detailed schema should NOT start with 0x and should just contain the hex characters")) - } else { - hex::decode(s) - .map(|bytes| PlutusData::new_bytes(bytes)) - .map_err(|e| JsError::from_str(&e.to_string())) - } - } - } - fn encode_array( - json_arr: Vec, - schema: PlutusDatumSchema, - ) -> Result { - let mut arr = PlutusList::new(); - for value in json_arr { - arr.add(&encode_json_value_to_plutus_datum(value, schema)?); - } - Ok(PlutusData::new_list(&arr)) - } - match schema { - PlutusDatumSchema::BasicConversions => match value { - Value::Null => Err(JsError::from_str("null not allowed in plutus datums")), - Value::Bool(_) => Err(JsError::from_str("bools not allowed in plutus datums")), - Value::Number(x) => encode_number(x), - // no strings in plutus so it's all bytes (as hex or utf8 printable) - Value::String(s) => encode_string(&s, schema, false), - Value::Array(json_arr) => encode_array(json_arr, schema), - Value::Object(json_obj) => { - let mut map = PlutusMap::new(); - for (raw_key, raw_value) in json_obj { - let key = encode_string(&raw_key, schema, true)?; - let value = encode_json_value_to_plutus_datum(raw_value, schema)?; - map.insert(&key, &value); - } - Ok(PlutusData::new_map(&map)) - } - }, - PlutusDatumSchema::DetailedSchema => match value { - Value::Object(obj) => { - if obj.len() == 1 { - // all variants except tagged constructors - let (k, v) = obj.into_iter().next().unwrap(); - fn tag_mismatch() -> JsError { - JsError::from_str("key does not match type") - } - match k.as_str() { - "int" => match v { - Value::Number(x) => encode_number(x), - _ => Err(tag_mismatch()), - }, - "bytes" => { - encode_string(v.as_str().ok_or_else(tag_mismatch)?, schema, false) - } - "list" => { - encode_array(v.as_array().ok_or_else(tag_mismatch)?.clone(), schema) - } - "map" => { - let mut map = PlutusMap::new(); - fn map_entry_err() -> JsError { - JsError::from_str("entry format in detailed schema map object not correct. Needs to be of form {\"k\": {\"key_type\": key}, \"v\": {\"value_type\", value}}") - } - for entry in v.as_array().ok_or_else(tag_mismatch)? { - let entry_obj = entry.as_object().ok_or_else(map_entry_err)?; - let raw_key = entry_obj.get("k").ok_or_else(map_entry_err)?; - let value = entry_obj.get("v").ok_or_else(map_entry_err)?; - let key = - encode_json_value_to_plutus_datum(raw_key.clone(), schema)?; - map.insert( - &key, - &encode_json_value_to_plutus_datum(value.clone(), schema)?, - ); - } - Ok(PlutusData::new_map(&map)) - } - invalid_key => Err(JsError::from_str(&format!( - "key '{}' in tagged object not valid", - invalid_key - ))), - } - } else { - // constructor with tagged variant - if obj.len() != 2 { - return Err(JsError::from_str("detailed schemas must either have only one of the following keys: \"int\", \"bytes\", \"list\" or \"map\", or both of these 2 keys: \"constructor\" + \"fields\"")); - } - let variant: BigNum = obj - .get("constructor") - .and_then(|v| Some(to_bignum(v.as_u64()?))) - .ok_or_else(|| JsError::from_str("tagged constructors must contain an unsigned integer called \"constructor\""))?; - let fields_json = - obj.get("fields") - .and_then(|f| f.as_array()) - .ok_or_else(|| { - JsError::from_str( - "tagged constructors must contian a list called \"fields\"", - ) - })?; - let mut fields = PlutusList::new(); - for field_json in fields_json { - let field = encode_json_value_to_plutus_datum(field_json.clone(), schema)?; - fields.add(&field); - } - Ok(PlutusData::new_constr_plutus_data(&ConstrPlutusData::new( - &variant, &fields, - ))) - } - } - _ => Err(JsError::from_str(&format!( - "DetailedSchema requires ALL JSON to be tagged objects, found: {}", - value - ))), - }, - } -} - -//TODO: move it to serialize impl -#[wasm_bindgen] -pub fn decode_plutus_datum_to_json_str( - datum: &PlutusData, - schema: PlutusDatumSchema, -) -> Result { - let value = decode_plutus_datum_to_json_value(datum, schema)?; - serde_json::to_string(&value).map_err(|e| JsError::from_str(&e.to_string())) -} - -//TODO: move it to deserialize impl -pub fn decode_plutus_datum_to_json_value( - datum: &PlutusData, - schema: PlutusDatumSchema, -) -> Result { - use serde_json::Value; - let (type_tag, json_value) = match &datum.datum { - PlutusDataEnum::ConstrPlutusData(constr) => { - let mut obj = serde_json::map::Map::with_capacity(2); - obj.insert( - String::from("constructor"), - Value::from(from_bignum(&constr.alternative)) - ); - let mut fields = Vec::new(); - for field in constr.data.elems.iter() { - fields.push(decode_plutus_datum_to_json_value(field, schema)?); - } - obj.insert( - String::from("fields"), - Value::from(fields) - ); - (None, Value::from(obj)) - }, - PlutusDataEnum::Map(map) => match schema { - PlutusDatumSchema::BasicConversions => (None, Value::from(map.0.iter().map(|(key, value)| { - let json_key: String = match &key.datum { - PlutusDataEnum::ConstrPlutusData(_) => Err(JsError::from_str("plutus data constructors are not allowed as keys in this schema. Use DetailedSchema.")), - PlutusDataEnum::Map(_) => Err(JsError::from_str("plutus maps are not allowed as keys in this schema. Use DetailedSchema.")), - PlutusDataEnum::List(_) => Err(JsError::from_str("plutus lists are not allowed as keys in this schema. Use DetailedSchema.")), - PlutusDataEnum::Integer(x) => Ok(x.to_str()), - PlutusDataEnum::Bytes(bytes) => String::from_utf8(bytes.clone()).or_else(|_err| Ok(format!("0x{}", hex::encode(bytes)))) - }?; - let json_value = decode_plutus_datum_to_json_value(value, schema)?; - Ok((json_key, Value::from(json_value))) - }).collect::, JsError>>()?)), - PlutusDatumSchema::DetailedSchema => (Some("map"), Value::from(map.0.iter().map(|(key, value)| { - let k = decode_plutus_datum_to_json_value(key, schema)?; - let v = decode_plutus_datum_to_json_value(value, schema)?; - let mut kv_obj = serde_json::map::Map::with_capacity(2); - kv_obj.insert(String::from("k"), k); - kv_obj.insert(String::from("v"), v); - Ok(Value::from(kv_obj)) - }).collect::, JsError>>()?)), - }, - PlutusDataEnum::List(list) => { - let mut elems = Vec::new(); - for elem in list.elems.iter() { - elems.push(decode_plutus_datum_to_json_value(elem, schema)?); - } - (Some("list"), Value::from(elems)) - }, - PlutusDataEnum::Integer(bigint) => ( - Some("int"), - bigint - .as_int() - .as_ref() - .map(|int| if int.0 >= 0 { Value::from(int.0 as u64) } else { Value::from(int.0 as i64) }) - .ok_or_else(|| JsError::from_str(&format!("Integer {} too big for our JSON support", bigint.to_str())))? - ), - PlutusDataEnum::Bytes(bytes) => (Some("bytes"), Value::from(match schema { - PlutusDatumSchema::BasicConversions => { - // cardano-cli converts to a string only if bytes are utf8 and all characters are printable - String::from_utf8(bytes.clone()) - .ok() - .filter(|utf8| utf8.chars().all(|c| !c.is_control())) - // otherwise we hex-encode the bytes with a 0x prefix - .unwrap_or_else(|| format!("0x{}", hex::encode(bytes))) - }, - PlutusDatumSchema::DetailedSchema => hex::encode(bytes), - })), - }; - if type_tag.is_none() || schema != PlutusDatumSchema::DetailedSchema { - Ok(json_value) - } else { - let mut wrapper = serde_json::map::Map::with_capacity(1); - wrapper.insert(String::from(type_tag.unwrap()), json_value); - Ok(Value::from(wrapper)) - } -} - -// Serialization - -use std::io::SeekFrom; - -impl cbor_event::se::Serialize for PlutusScript { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_bytes(&self.bytes) - } -} - -impl Deserialize for PlutusScript { - fn deserialize(raw: &mut Deserializer) -> Result { - Ok(Self::new(raw.bytes()?)) - } -} - -impl cbor_event::se::Serialize for PlutusScripts { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for PlutusScripts { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(PlutusScript::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("PlutusScripts"))?; - Ok(Self(arr)) - } -} - -impl cbor_event::se::Serialize for ConstrPlutusData { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - if let Some(compact_tag) = - Self::alternative_to_compact_cbor_tag(from_bignum(&self.alternative)) - { - // compact form - serializer.write_tag(compact_tag as u64)?; - self.data.serialize(serializer) - } else { - // general form - serializer.write_tag(Self::GENERAL_FORM_TAG)?; - serializer.write_array(cbor_event::Len::Len(2))?; - self.alternative.serialize(serializer)?; - self.data.serialize(serializer) - } - } -} - -impl Deserialize for ConstrPlutusData { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let (alternative, data) = match raw.tag()? { - // general form - Self::GENERAL_FORM_TAG => { - let len = raw.array()?; - let mut read_len = CBORReadLen::new(len); - read_len.read_elems(2)?; - let alternative = BigNum::deserialize(raw)?; - let data = - (|| -> Result<_, DeserializeError> { Ok(PlutusList::deserialize(raw)?) })() - .map_err(|e| e.annotate("datas"))?; - match len { - cbor_event::Len::Len(_) => (), - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => (), - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - (alternative, data) - } - // concise form - tag => { - if let Some(alternative) = Self::compact_cbor_tag_to_alternative(tag) { - (to_bignum(alternative), PlutusList::deserialize(raw)?) - } else { - return Err(DeserializeFailure::TagMismatch { - found: tag, - expected: Self::GENERAL_FORM_TAG, - } - .into()); - } - } - }; - Ok(ConstrPlutusData { alternative, data }) - })() - .map_err(|e| e.annotate("ConstrPlutusData")) - } -} - -impl cbor_event::se::Serialize for CostModel { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for cost in &self.0 { - cost.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for CostModel { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(Int::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("CostModel"))?; - Ok(Self(arr.try_into().unwrap())) - } -} - -impl cbor_event::se::Serialize for Costmdls { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?; - for (key, value) in &self.0 { - key.serialize(serializer)?; - value.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for Costmdls { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut table = std::collections::BTreeMap::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.map()?; - while match len { - cbor_event::Len::Len(n) => table.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - let key = Language::deserialize(raw)?; - let value = CostModel::deserialize(raw)?; - if table.insert(key.clone(), value).is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Str(String::from( - "some complicated/unsupported type", - ))) - .into()); - } - } - Ok(()) - })() - .map_err(|e| e.annotate("Costmdls"))?; - Ok(Self(table)) - } -} - -impl cbor_event::se::Serialize for ExUnitPrices { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - self.mem_price.serialize(serializer)?; - self.step_price.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for ExUnitPrices { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let mut read_len = CBORReadLen::new(len); - read_len.read_elems(2)?; - let mem_price = - (|| -> Result<_, DeserializeError> { Ok(SubCoin::deserialize(raw)?) })() - .map_err(|e| e.annotate("mem_price"))?; - let step_price = - (|| -> Result<_, DeserializeError> { Ok(SubCoin::deserialize(raw)?) })() - .map_err(|e| e.annotate("step_price"))?; - match len { - cbor_event::Len::Len(_) => (), - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => (), - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - Ok(ExUnitPrices { - mem_price, - step_price, - }) - })() - .map_err(|e| e.annotate("ExUnitPrices")) - } -} - -impl cbor_event::se::Serialize for ExUnits { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - self.mem.serialize(serializer)?; - self.steps.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for ExUnits { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let mut read_len = CBORReadLen::new(len); - read_len.read_elems(2)?; - let mem = (|| -> Result<_, DeserializeError> { Ok(BigNum::deserialize(raw)?) })() - .map_err(|e| e.annotate("mem"))?; - let steps = (|| -> Result<_, DeserializeError> { Ok(BigNum::deserialize(raw)?) })() - .map_err(|e| e.annotate("steps"))?; - match len { - cbor_event::Len::Len(_) => (), - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => (), - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - Ok(ExUnits { mem, steps }) - })() - .map_err(|e| e.annotate("ExUnits")) - } -} - -impl cbor_event::se::Serialize for Language { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - // https://github.com/input-output-hk/cardano-ledger/blob/master/eras/babbage/test-suite/cddl-files/babbage.cddl#L324-L327 - serializer.write_unsigned_integer(self.kind() as u64) - } -} - -impl Deserialize for Language { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - match LanguageKind::from_u64(raw.unsigned_integer()?) { - Some(kind) => Ok(Language(kind)), - _ => Err(DeserializeError::new( - "Language", - DeserializeFailure::NoVariantMatched.into(), - )), - } - })() - .map_err(|e| e.annotate("Language")) - } -} - -impl cbor_event::se::Serialize for Languages { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for Languages { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(Language::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("Languages"))?; - Ok(Self(arr)) - } -} - -impl cbor_event::se::Serialize for PlutusMap { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?; - for (key, value) in &self.0 { - key.serialize(serializer)?; - value.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for PlutusMap { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut table = LinkedHashMap::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.map()?; - while match len { - cbor_event::Len::Len(n) => table.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - let key = PlutusData::deserialize(raw)?; - let value = PlutusData::deserialize(raw)?; - if table.insert(key.clone(), value).is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Str(String::from( - "some complicated/unsupported type", - ))) - .into()); - } - } - Ok(()) - })() - .map_err(|e| e.annotate("PlutusMap"))?; - Ok(Self(table)) - } -} - -impl cbor_event::se::Serialize for PlutusDataEnum { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - match self { - PlutusDataEnum::ConstrPlutusData(x) => x.serialize(serializer), - PlutusDataEnum::Map(x) => x.serialize(serializer), - PlutusDataEnum::List(x) => x.serialize(serializer), - PlutusDataEnum::Integer(x) => x.serialize(serializer), - PlutusDataEnum::Bytes(x) => write_bounded_bytes(serializer, &x), - } - } -} - -impl Deserialize for PlutusDataEnum { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let initial_position = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(ConstrPlutusData::deserialize(raw)?) - })(raw) - { - Ok(variant) => return Ok(PlutusDataEnum::ConstrPlutusData(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(PlutusMap::deserialize(raw)?) - })(raw) - { - Ok(variant) => return Ok(PlutusDataEnum::Map(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(PlutusList::deserialize(raw)?) - })(raw) - { - Ok(variant) => return Ok(PlutusDataEnum::List(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(BigInt::deserialize(raw)?) - })(raw) - { - Ok(variant) => return Ok(PlutusDataEnum::Integer(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(read_bounded_bytes(raw)?) - })(raw) - { - Ok(variant) => return Ok(PlutusDataEnum::Bytes(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - Err(DeserializeError::new( - "PlutusDataEnum", - DeserializeFailure::NoVariantMatched.into(), - )) - })() - .map_err(|e| e.annotate("PlutusDataEnum")) - } -} - -impl cbor_event::se::Serialize for PlutusData { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - match &self.original_bytes { - Some(bytes) => serializer.write_raw_bytes(bytes), - None => self.datum.serialize(serializer), - } - } -} - -impl Deserialize for PlutusData { - fn deserialize(raw: &mut Deserializer) -> Result { - // these unwraps are fine since we're seeking the current position - let before = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); - let datum = PlutusDataEnum::deserialize(raw)?; - let after = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); - let bytes_read = (after - before) as usize; - raw.as_mut_ref().seek(SeekFrom::Start(before)).unwrap(); - // these unwraps are fine since we read the above already - let original_bytes = raw.as_mut_ref().fill_buf().unwrap()[..bytes_read].to_vec(); - raw.as_mut_ref().consume(bytes_read); - Ok(Self { - datum, - original_bytes: Some(original_bytes), - }) - } -} - -impl cbor_event::se::Serialize for PlutusList { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - let use_definite_encoding = match self.definite_encoding { - Some(definite) => definite, - None => self.elems.is_empty(), - }; - if use_definite_encoding { - serializer.write_array(cbor_event::Len::Len(self.elems.len() as u64))?; - } else { - serializer.write_array(cbor_event::Len::Indefinite)?; - } - for element in &self.elems { - element.serialize(serializer)?; - } - if !use_definite_encoding { - serializer.write_special(cbor_event::Special::Break)?; - } - Ok(serializer) - } -} - -impl Deserialize for PlutusList { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - let len = (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(PlutusData::deserialize(raw)?); - } - Ok(len) - })() - .map_err(|e| e.annotate("PlutusList"))?; - Ok(Self { - elems: arr, - definite_encoding: Some(len != cbor_event::Len::Indefinite), - }) - } -} - -impl cbor_event::se::Serialize for Redeemer { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(4))?; - self.tag.serialize(serializer)?; - self.index.serialize(serializer)?; - self.data.serialize(serializer)?; - self.ex_units.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for Redeemer { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let mut read_len = CBORReadLen::new(len); - read_len.read_elems(4)?; - let tag = (|| -> Result<_, DeserializeError> { Ok(RedeemerTag::deserialize(raw)?) })() - .map_err(|e| e.annotate("tag"))?; - let index = (|| -> Result<_, DeserializeError> { Ok(BigNum::deserialize(raw)?) })() - .map_err(|e| e.annotate("index"))?; - let data = (|| -> Result<_, DeserializeError> { Ok(PlutusData::deserialize(raw)?) })() - .map_err(|e| e.annotate("data"))?; - let ex_units = (|| -> Result<_, DeserializeError> { Ok(ExUnits::deserialize(raw)?) })() - .map_err(|e| e.annotate("ex_units"))?; - match len { - cbor_event::Len::Len(_) => (), - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => (), - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - Ok(Redeemer { - tag, - index, - data, - ex_units, - }) - })() - .map_err(|e| e.annotate("Redeemer")) - } -} - -impl cbor_event::se::Serialize for RedeemerTagKind { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - match self { - RedeemerTagKind::Spend => serializer.write_unsigned_integer(0u64), - RedeemerTagKind::Mint => serializer.write_unsigned_integer(1u64), - RedeemerTagKind::Cert => serializer.write_unsigned_integer(2u64), - RedeemerTagKind::Reward => serializer.write_unsigned_integer(3u64), - RedeemerTagKind::Vote => serializer.write_unsigned_integer(4u64), - RedeemerTagKind::VotingProposal => serializer.write_unsigned_integer(5u64), - } - } -} - -impl Deserialize for RedeemerTagKind { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - match raw.unsigned_integer() { - Ok(0) => Ok(RedeemerTagKind::Spend), - Ok(1) => Ok(RedeemerTagKind::Mint), - Ok(2) => Ok(RedeemerTagKind::Cert), - Ok(3) => Ok(RedeemerTagKind::Reward), - Ok(4) => Ok(RedeemerTagKind::Vote), - Ok(5) => Ok(RedeemerTagKind::VotingProposal), - Ok(_) | Err(_) => Err(DeserializeFailure::NoVariantMatched.into()), - } - })() - .map_err(|e| e.annotate("RedeemerTagEnum")) - } -} - -impl cbor_event::se::Serialize for RedeemerTag { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - self.0.serialize(serializer) - } -} - -impl Deserialize for RedeemerTag { - fn deserialize(raw: &mut Deserializer) -> Result { - Ok(Self(RedeemerTagKind::deserialize(raw)?)) - } -} - -impl cbor_event::se::Serialize for Redeemers { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for Redeemers { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(Redeemer::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("Redeemers"))?; - Ok(Self(arr)) - } -} - -impl cbor_event::se::Serialize for Strings { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - serializer.write_text(&element)?; - } - Ok(serializer) - } -} - -impl Deserialize for Strings { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(String::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("Strings"))?; - Ok(Self(arr)) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::TxBuilderConstants; - use hex::*; - - #[test] - pub fn plutus_constr_data() { - let constr_0 = PlutusData::new_constr_plutus_data(&ConstrPlutusData::new( - &to_bignum(0), - &PlutusList::new(), - )); - let constr_0_hash = hex::encode(hash_plutus_data(&constr_0).to_bytes()); - assert_eq!( - constr_0_hash, - "923918e403bf43c34b4ef6b48eb2ee04babed17320d8d1b9ff9ad086e86f44ec" - ); - // let constr_0_roundtrip = PlutusData::from_bytes(constr_0.to_bytes()).unwrap(); - // TODO: do we want semantic equality or bytewise equality? - // assert_eq!(constr_0, constr_0_roundtrip); - // let constr_1854 = PlutusData::new_constr_plutus_data( - // &ConstrPlutusData::new(&to_bignum(1854), &PlutusList::new()) - // ); - // let constr_1854_roundtrip = PlutusData::from_bytes(constr_1854.to_bytes()).unwrap(); - // assert_eq!(constr_1854, constr_1854_roundtrip); - } - - #[test] - pub fn plutus_list_serialization_cli_compatibility() { - // mimic cardano-cli array encoding, see https://github.com/Emurgo/cardano-serialization-lib/issues/227 - let datum_cli = "d8799f4100d8799fd8799fd8799f581cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd8799fd8799fd8799f581cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd87a80ff1a002625a0d8799fd879801a000f4240d87a80ffff"; - let datum = PlutusData::from_bytes(Vec::from_hex(datum_cli).unwrap()).unwrap(); - assert_eq!(datum_cli, hex::encode(datum.to_bytes())); - - // encode empty arrays as fixed - assert_eq!("80", hex::encode(PlutusList::new().to_bytes())); - - // encode arrays as indefinite length array - let mut list = PlutusList::new(); - list.add(&PlutusData::new_integer(&BigInt::from_str("1").unwrap())); - assert_eq!("9f01ff", hex::encode(list.to_bytes())); - - // witness_set should have fixed length array - let mut witness_set = TransactionWitnessSet::new(); - witness_set.set_plutus_data(&list); - assert_eq!("a1049f01ff", hex::encode(witness_set.to_bytes())); - - list = PlutusList::new(); - list.add(&datum); - witness_set.set_plutus_data(&list); - assert_eq!( - format!("a1049f{}ff", datum_cli), - hex::encode(witness_set.to_bytes()) - ); - } - - #[test] - pub fn plutus_datums_respect_deserialized_encoding() { - let orig_bytes = Vec::from_hex( - "81d8799f581ce1cbb80db89e292269aeb93ec15eb963dda5176b66949fe1c2a6a38da140a1401864ff", - ) - .unwrap(); - let datums = PlutusList::from_bytes(orig_bytes.clone()).unwrap(); - let new_bytes = datums.to_bytes(); - assert_eq!(orig_bytes, new_bytes); - } - - #[test] - pub fn plutus_datum_from_json_basic() { - let json = "{ - \"5\": \"some utf8 string\", - \"0xDEADBEEF\": [ - {\"reg string\": {}}, - -9 - ] - }"; - - let datum = - encode_json_str_to_plutus_datum(json, PlutusDatumSchema::BasicConversions).unwrap(); - - let map = datum.as_map().unwrap(); - let map_5 = map - .get(&PlutusData::new_integer(&BigInt::from_str("5").unwrap())) - .unwrap(); - let utf8_bytes = "some utf8 string".as_bytes(); - assert_eq!(map_5.as_bytes().unwrap(), utf8_bytes); - let map_deadbeef: PlutusList = map - .get(&PlutusData::new_bytes(vec![222, 173, 190, 239])) - .expect("DEADBEEF key not found") - .as_list() - .expect("must be a map"); - assert_eq!(map_deadbeef.len(), 2); - let inner_map = map_deadbeef.get(0).as_map().unwrap(); - assert_eq!(inner_map.len(), 1); - let reg_string = inner_map - .get(&PlutusData::new_bytes("reg string".as_bytes().to_vec())) - .unwrap(); - assert_eq!(reg_string.as_map().expect("reg string: {}").len(), 0); - assert_eq!( - map_deadbeef.get(1).as_integer(), - BigInt::from_str("-9").ok() - ); - - // test round-trip via generated JSON - let json2 = - decode_plutus_datum_to_json_str(&datum, PlutusDatumSchema::BasicConversions).unwrap(); - let datum2 = - encode_json_str_to_plutus_datum(&json2, PlutusDatumSchema::BasicConversions).unwrap(); - assert_eq!(datum, datum2); - } - - #[test] - pub fn plutus_datum_from_json_detailed() { - let json = "{\"list\": [ - {\"map\": [ - {\"k\": {\"bytes\": \"DEADBEEF\"}, \"v\": {\"int\": 42}}, - {\"k\": {\"map\" : [ - {\"k\": {\"int\": 9}, \"v\": {\"int\": -5}} - ]}, \"v\": {\"list\": []}} - ]}, - {\"bytes\": \"CAFED00D\"}, - {\"constructor\": 0, \"fields\": [ - {\"map\": []}, - {\"int\": 23} - ]} - ]}"; - let datum = - encode_json_str_to_plutus_datum(json, PlutusDatumSchema::DetailedSchema).unwrap(); - - let list = datum.as_list().unwrap(); - assert_eq!(3, list.len()); - // map - let map = list.get(0).as_map().unwrap(); - assert_eq!(map.len(), 2); - let map_deadbeef = map - .get(&PlutusData::new_bytes(vec![222, 173, 190, 239])) - .unwrap(); - assert_eq!(map_deadbeef.as_integer(), BigInt::from_str("42").ok()); - let mut long_key = PlutusMap::new(); - long_key.insert( - &PlutusData::new_integer(&BigInt::from_str("9").unwrap()), - &PlutusData::new_integer(&BigInt::from_str("-5").unwrap()), - ); - let map_9_to_5 = map - .get(&PlutusData::new_map(&long_key)) - .unwrap() - .as_list() - .unwrap(); - assert_eq!(map_9_to_5.len(), 0); - // bytes - let bytes = list.get(1).as_bytes().unwrap(); - assert_eq!(bytes, [202, 254, 208, 13]); - // constr data - let constr = list.get(2).as_constr_plutus_data().unwrap(); - assert_eq!(to_bignum(0), constr.alternative()); - let fields = constr.data(); - assert_eq!(fields.len(), 2); - let field0 = fields.get(0).as_map().unwrap(); - assert_eq!(field0.len(), 0); - let field1 = fields.get(1); - assert_eq!(field1.as_integer(), BigInt::from_str("23").ok()); - - // test round-trip via generated JSON - let json2 = - decode_plutus_datum_to_json_str(&datum, PlutusDatumSchema::DetailedSchema).unwrap(); - let datum2 = - encode_json_str_to_plutus_datum(&json2, PlutusDatumSchema::DetailedSchema).unwrap(); - assert_eq!(datum, datum2); - } - - #[test] - pub fn test_cost_model() { - let arr = vec![ - 197209, 0, 1, 1, 396231, 621, 0, 1, 150000, 1000, 0, 1, 150000, 32, 2477736, 29175, 4, - 29773, 100, 29773, 100, 29773, 100, 29773, 100, 29773, 100, 29773, 100, 100, 100, - 29773, 100, 150000, 32, 150000, 32, 150000, 32, 150000, 1000, 0, 1, 150000, 32, 150000, - 1000, 0, 8, 148000, 425507, 118, 0, 1, 1, 150000, 1000, 0, 8, 150000, 112536, 247, 1, - 150000, 10000, 1, 136542, 1326, 1, 1000, 150000, 1000, 1, 150000, 32, 150000, 32, - 150000, 32, 1, 1, 150000, 1, 150000, 4, 103599, 248, 1, 103599, 248, 1, 145276, 1366, - 1, 179690, 497, 1, 150000, 32, 150000, 32, 150000, 32, 150000, 32, 150000, 32, 150000, - 32, 148000, 425507, 118, 0, 1, 1, 61516, 11218, 0, 1, 150000, 32, 148000, 425507, 118, - 0, 1, 1, 148000, 425507, 118, 0, 1, 1, 2477736, 29175, 4, 0, 82363, 4, 150000, 5000, 0, - 1, 150000, 32, 197209, 0, 1, 1, 150000, 32, 150000, 32, 150000, 32, 150000, 32, 150000, - 32, 150000, 32, 150000, 32, 3345831, 1, 1, - ]; - let cm = arr - .iter() - .fold((CostModel::new(), 0), |(mut cm, i), x| { - cm.set(i, &Int::new_i32(x.clone())).unwrap(); - (cm, i + 1) - }) - .0; - let mut cms = Costmdls::new(); - cms.insert(&Language::new_plutus_v1(), &cm); - assert_eq!( - hex::encode(cms.language_views_encoding()), - "a141005901d59f1a000302590001011a00060bc719026d00011a000249f01903e800011a000249f018201a0025cea81971f70419744d186419744d186419744d186419744d186419744d186419744d18641864186419744d18641a000249f018201a000249f018201a000249f018201a000249f01903e800011a000249f018201a000249f01903e800081a000242201a00067e2318760001011a000249f01903e800081a000249f01a0001b79818f7011a000249f0192710011a0002155e19052e011903e81a000249f01903e8011a000249f018201a000249f018201a000249f0182001011a000249f0011a000249f0041a000194af18f8011a000194af18f8011a0002377c190556011a0002bdea1901f1011a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a000242201a00067e23187600010119f04c192bd200011a000249f018201a000242201a00067e2318760001011a000242201a00067e2318760001011a0025cea81971f704001a000141bb041a000249f019138800011a000249f018201a000302590001011a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a00330da70101ff" - ); - } - - #[test] - fn test_plutus_script_hash() { - let hash = EnterpriseAddress::from_address( - &Address::from_bech32("addr1w896t6qnpsjs32xhw8jl3kw34pqz69kgd72l8hqw83w0k3qahx2sv") - .unwrap(), - ) - .unwrap() - .payment_cred() - .to_scripthash() - .unwrap(); - let script = PlutusScript::from_bytes( - hex::decode("590e6f590e6c0100003323332223322333222332232332233223232333222323332223233333333222222223233322232333322223232332232323332223232332233223232333332222233223322332233223322332222323232232232325335303233300a3333573466e1cd55cea8042400046664446660a40060040026eb4d5d0a8041bae35742a00e66a05046666ae68cdc39aab9d37540029000102b11931a982599ab9c04f04c04a049357426ae89401c8c98d4c124cd5ce0268250240239999ab9a3370ea0089001102b11999ab9a3370ea00a9000102c11931a982519ab9c04e04b0490480473333573466e1cd55cea8012400046601a64646464646464646464646666ae68cdc39aab9d500a480008cccccccccc06ccd40a48c8c8cccd5cd19b8735573aa0049000119810981c9aba15002302e357426ae8940088c98d4c164cd5ce02e82d02c02b89aab9e5001137540026ae854028cd40a40a8d5d0a804999aa8183ae502f35742a010666aa060eb940bcd5d0a80399a8148211aba15006335029335505304b75a6ae854014c8c8c8cccd5cd19b8735573aa0049000119a8119919191999ab9a3370e6aae7540092000233502b33504175a6ae854008c118d5d09aba25002232635305d3357380c20bc0b80b626aae7940044dd50009aba150023232323333573466e1cd55cea80124000466a05266a082eb4d5d0a80118231aba135744a004464c6a60ba66ae7018417817016c4d55cf280089baa001357426ae8940088c98d4c164cd5ce02e82d02c02b89aab9e5001137540026ae854010cd40a5d71aba15003335029335505375c40026ae854008c0e0d5d09aba2500223263530553357380b20ac0a80a626ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba150023232323333573466e1d4005200623020303a357426aae79400c8cccd5cd19b875002480108c07cc110d5d09aab9e500423333573466e1d400d20022301f302f357426aae7940148cccd5cd19b875004480008c088dd71aba135573ca00c464c6a60a066ae7015014413c13813413012c4d55cea80089baa001357426ae8940088c98d4c124cd5ce026825024023882489931a982419ab9c4910350543500049047135573ca00226ea80044d55ce9baa001135744a00226aae7940044dd50009109198008018011000911111111109199999999980080580500480400380300280200180110009109198008018011000891091980080180109000891091980080180109000891091980080180109000909111180200290911118018029091111801002909111180080290008919118011bac0013200135503c2233335573e0024a01c466a01a60086ae84008c00cd5d100101811919191999ab9a3370e6aae75400d200023330073232323333573466e1cd55cea8012400046601a605c6ae854008cd404c0a8d5d09aba25002232635303433573807006a06606426aae7940044dd50009aba150033335500b75ca0146ae854008cd403dd71aba135744a004464c6a606066ae700d00c40bc0b84d5d1280089aab9e5001137540024442466600200800600440024424660020060044002266aa002eb9d6889119118011bab00132001355036223233335573e0044a012466a01066aa05c600c6aae754008c014d55cf280118021aba200302b1357420022244004244244660020080062400224464646666ae68cdc3a800a400046a05e600a6ae84d55cf280191999ab9a3370ea00490011281791931a981399ab9c02b028026025024135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011980318039aba15002375a6ae84d5d1280111931a981219ab9c028025023022135573ca00226ea80048848cc00400c00880048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98d4c080cd5ce01201080f80f09baa00112232323333573466e1d400520042500723333573466e1d4009200223500a3006357426aae7940108cccd5cd19b87500348000940288c98d4c08ccd5ce01381201101081000f89aab9d50011375400224244460060082244400422444002240024646666ae68cdc3a800a4004400c46666ae68cdc3a80124000400c464c6a603666ae7007c0700680640604d55ce9baa0011220021220012001232323232323333573466e1d4005200c200b23333573466e1d4009200a200d23333573466e1d400d200823300b375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c46601a6eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc048c050d5d0a8049bae357426ae8940248cccd5cd19b875006480088c050c054d5d09aab9e500b23333573466e1d401d2000230133016357426aae7940308c98d4c080cd5ce01201080f80f00e80e00d80d00c80c09aab9d5004135573ca00626aae7940084d55cf280089baa00121222222230070082212222222330060090082122222223005008122222220041222222200322122222223300200900822122222223300100900820012323232323333573466e1d400520022333008375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea00490001180518059aba135573ca00c464c6a602266ae7005404804003c0384d55cea80189aba25001135573ca00226ea80048488c00800c888488ccc00401401000c80048c8c8cccd5cd19b875001480088c018dd71aba135573ca00646666ae68cdc3a80124000460106eb8d5d09aab9e5004232635300b33573801e01801401201026aae7540044dd5000909118010019091180080190008891119191999ab9a3370e6aae75400920002335500b300635742a004600a6ae84d5d1280111931a980419ab9c00c009007006135573ca00226ea800526120012001112212330010030021120014910350543100222123330010040030022001121223002003112200112001120012001122002122001200111232300100122330033002002001332323233322233322233223332223322332233322233223322332233223233322232323322323232323333222232332232323222323222325335301a5335301a333573466e1cc8cccd54c05048004c8cd406488ccd406400c004008d4058004cd4060888c00cc008004800488cdc0000a40040029000199aa98068900091299a980e299a9a81a1a98169a98131a9812001110009110019119a98188011281c11a81c8009080f880e899a8148010008800a8141a981028009111111111005240040380362038266ae712413c53686f756c642062652065786163746c79206f6e652073637269707420696e70757420746f2061766f696420646f75626c65207361742069737375650001b15335303500315335301a5335301a333573466e20ccc064ccd54c03448005402540a0cc020d4c0c00188880094004074074cdc09a9818003111001a80200d80e080e099ab9c49010f73656c6c6572206e6f7420706169640001b15335301a333573466e20ccc064cc88ccd54c03c48005402d40a8cc028004009400401c074075401006c07040704cd5ce24810d66656573206e6f7420706169640001b101b15335301a3322353022002222222222253353503e33355301f1200133502322533535040002210031001503f253353027333573466e3c0300040a40a04d41040045410000c840a4409d4004d4c0c001888800840704cd5ce2491c4f6e6c792073656c6c65722063616e2063616e63656c206f666665720001b101b135301d00122002153353016333573466e2540040d406005c40d4540044cdc199b8235302b001222003480c920d00f2235301a0012222222222333553011120012235302a002222353034003223353038002253353026333573466e3c0500040a009c4cd40cc01401c401c801d40b0024488cd54c02c480048d4d5408c00488cd54098008cd54c038480048d4d5409800488cd540a4008ccd4d540340048cc0e12000001223303900200123303800148000004cd54c02c480048d4d5408c00488cd54098008ccd4d540280048cd54c03c480048d4d5409c00488cd540a8008d5404400400488ccd5540200580080048cd54c03c480048d4d5409c00488cd540a8008d5403c004004ccd55400c044008004444888ccd54c018480054080cd54c02c480048d4d5408c00488cd54098008d54034004ccd54c0184800488d4d54090008894cd4c05cccd54c04048004c8cd405488ccd4d402c00c88008008004d4d402400488004cd4024894cd4c064008406c40040608d4d5409c00488cc028008014018400c4cd409001000d4084004cd54c02c480048d4d5408c00488c8cd5409c00cc004014c8004d540d8894cd4d40900044d5403400c884d4d540a4008894cd4c070cc0300080204cd5404801c0044c01800c00848848cc00400c00848004c8004d540b488448894cd4d40780044008884cc014008ccd54c01c480040140100044484888c00c01044884888cc0080140104484888c004010448004c8004d540a08844894cd4d406000454068884cd406cc010008cd54c01848004010004c8004d5409c88448894cd4d40600044d401800c884ccd4024014c010008ccd54c01c4800401401000448d4d400c0048800448d4d40080048800848848cc00400c0084800488ccd5cd19b8f002001006005222323230010053200135502522335350130014800088d4d54060008894cd4c02cccd5cd19b8f00200900d00c13007001130060033200135502422335350120014800088d4d5405c008894cd4c028ccd5cd19b8f00200700c00b10011300600312200212200120014881002212330010030022001222222222212333333333300100b00a009008007006005004003002200122123300100300220012221233300100400300220011122002122122330010040031200111221233001003002112001221233001003002200121223002003212230010032001222123330010040030022001121223002003112200112001122002122001200122337000040029040497a0088919180080091198019801001000a4411c28f07a93d7715db0bdc1766c8bd5b116602b105c02c54fc3bcd0d4680001").unwrap().clone(), - ).unwrap(); - assert_eq!(script.hash(), hash); - } - - #[test] - fn test_plutus_script_from_hex_with_version() { - let script_v1 = PlutusScript::from_hex_with_version( - "590e6f590e6c0100003323332223322333222332232332233223232333222323332223233333333222222223233322232333322223232332232323332223232332233223232333332222233223322332233223322332222323232232232325335303233300a3333573466e1cd55cea8042400046664446660a40060040026eb4d5d0a8041bae35742a00e66a05046666ae68cdc39aab9d37540029000102b11931a982599ab9c04f04c04a049357426ae89401c8c98d4c124cd5ce0268250240239999ab9a3370ea0089001102b11999ab9a3370ea00a9000102c11931a982519ab9c04e04b0490480473333573466e1cd55cea8012400046601a64646464646464646464646666ae68cdc39aab9d500a480008cccccccccc06ccd40a48c8c8cccd5cd19b8735573aa0049000119810981c9aba15002302e357426ae8940088c98d4c164cd5ce02e82d02c02b89aab9e5001137540026ae854028cd40a40a8d5d0a804999aa8183ae502f35742a010666aa060eb940bcd5d0a80399a8148211aba15006335029335505304b75a6ae854014c8c8c8cccd5cd19b8735573aa0049000119a8119919191999ab9a3370e6aae7540092000233502b33504175a6ae854008c118d5d09aba25002232635305d3357380c20bc0b80b626aae7940044dd50009aba150023232323333573466e1cd55cea80124000466a05266a082eb4d5d0a80118231aba135744a004464c6a60ba66ae7018417817016c4d55cf280089baa001357426ae8940088c98d4c164cd5ce02e82d02c02b89aab9e5001137540026ae854010cd40a5d71aba15003335029335505375c40026ae854008c0e0d5d09aba2500223263530553357380b20ac0a80a626ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba150023232323333573466e1d4005200623020303a357426aae79400c8cccd5cd19b875002480108c07cc110d5d09aab9e500423333573466e1d400d20022301f302f357426aae7940148cccd5cd19b875004480008c088dd71aba135573ca00c464c6a60a066ae7015014413c13813413012c4d55cea80089baa001357426ae8940088c98d4c124cd5ce026825024023882489931a982419ab9c4910350543500049047135573ca00226ea80044d55ce9baa001135744a00226aae7940044dd50009109198008018011000911111111109199999999980080580500480400380300280200180110009109198008018011000891091980080180109000891091980080180109000891091980080180109000909111180200290911118018029091111801002909111180080290008919118011bac0013200135503c2233335573e0024a01c466a01a60086ae84008c00cd5d100101811919191999ab9a3370e6aae75400d200023330073232323333573466e1cd55cea8012400046601a605c6ae854008cd404c0a8d5d09aba25002232635303433573807006a06606426aae7940044dd50009aba150033335500b75ca0146ae854008cd403dd71aba135744a004464c6a606066ae700d00c40bc0b84d5d1280089aab9e5001137540024442466600200800600440024424660020060044002266aa002eb9d6889119118011bab00132001355036223233335573e0044a012466a01066aa05c600c6aae754008c014d55cf280118021aba200302b1357420022244004244244660020080062400224464646666ae68cdc3a800a400046a05e600a6ae84d55cf280191999ab9a3370ea00490011281791931a981399ab9c02b028026025024135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011980318039aba15002375a6ae84d5d1280111931a981219ab9c028025023022135573ca00226ea80048848cc00400c00880048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98d4c080cd5ce01201080f80f09baa00112232323333573466e1d400520042500723333573466e1d4009200223500a3006357426aae7940108cccd5cd19b87500348000940288c98d4c08ccd5ce01381201101081000f89aab9d50011375400224244460060082244400422444002240024646666ae68cdc3a800a4004400c46666ae68cdc3a80124000400c464c6a603666ae7007c0700680640604d55ce9baa0011220021220012001232323232323333573466e1d4005200c200b23333573466e1d4009200a200d23333573466e1d400d200823300b375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c46601a6eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc048c050d5d0a8049bae357426ae8940248cccd5cd19b875006480088c050c054d5d09aab9e500b23333573466e1d401d2000230133016357426aae7940308c98d4c080cd5ce01201080f80f00e80e00d80d00c80c09aab9d5004135573ca00626aae7940084d55cf280089baa00121222222230070082212222222330060090082122222223005008122222220041222222200322122222223300200900822122222223300100900820012323232323333573466e1d400520022333008375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea00490001180518059aba135573ca00c464c6a602266ae7005404804003c0384d55cea80189aba25001135573ca00226ea80048488c00800c888488ccc00401401000c80048c8c8cccd5cd19b875001480088c018dd71aba135573ca00646666ae68cdc3a80124000460106eb8d5d09aab9e5004232635300b33573801e01801401201026aae7540044dd5000909118010019091180080190008891119191999ab9a3370e6aae75400920002335500b300635742a004600a6ae84d5d1280111931a980419ab9c00c009007006135573ca00226ea800526120012001112212330010030021120014910350543100222123330010040030022001121223002003112200112001120012001122002122001200111232300100122330033002002001332323233322233322233223332223322332233322233223322332233223233322232323322323232323333222232332232323222323222325335301a5335301a333573466e1cc8cccd54c05048004c8cd406488ccd406400c004008d4058004cd4060888c00cc008004800488cdc0000a40040029000199aa98068900091299a980e299a9a81a1a98169a98131a9812001110009110019119a98188011281c11a81c8009080f880e899a8148010008800a8141a981028009111111111005240040380362038266ae712413c53686f756c642062652065786163746c79206f6e652073637269707420696e70757420746f2061766f696420646f75626c65207361742069737375650001b15335303500315335301a5335301a333573466e20ccc064ccd54c03448005402540a0cc020d4c0c00188880094004074074cdc09a9818003111001a80200d80e080e099ab9c49010f73656c6c6572206e6f7420706169640001b15335301a333573466e20ccc064cc88ccd54c03c48005402d40a8cc028004009400401c074075401006c07040704cd5ce24810d66656573206e6f7420706169640001b101b15335301a3322353022002222222222253353503e33355301f1200133502322533535040002210031001503f253353027333573466e3c0300040a40a04d41040045410000c840a4409d4004d4c0c001888800840704cd5ce2491c4f6e6c792073656c6c65722063616e2063616e63656c206f666665720001b101b135301d00122002153353016333573466e2540040d406005c40d4540044cdc199b8235302b001222003480c920d00f2235301a0012222222222333553011120012235302a002222353034003223353038002253353026333573466e3c0500040a009c4cd40cc01401c401c801d40b0024488cd54c02c480048d4d5408c00488cd54098008cd54c038480048d4d5409800488cd540a4008ccd4d540340048cc0e12000001223303900200123303800148000004cd54c02c480048d4d5408c00488cd54098008ccd4d540280048cd54c03c480048d4d5409c00488cd540a8008d5404400400488ccd5540200580080048cd54c03c480048d4d5409c00488cd540a8008d5403c004004ccd55400c044008004444888ccd54c018480054080cd54c02c480048d4d5408c00488cd54098008d54034004ccd54c0184800488d4d54090008894cd4c05cccd54c04048004c8cd405488ccd4d402c00c88008008004d4d402400488004cd4024894cd4c064008406c40040608d4d5409c00488cc028008014018400c4cd409001000d4084004cd54c02c480048d4d5408c00488c8cd5409c00cc004014c8004d540d8894cd4d40900044d5403400c884d4d540a4008894cd4c070cc0300080204cd5404801c0044c01800c00848848cc00400c00848004c8004d540b488448894cd4d40780044008884cc014008ccd54c01c480040140100044484888c00c01044884888cc0080140104484888c004010448004c8004d540a08844894cd4d406000454068884cd406cc010008cd54c01848004010004c8004d5409c88448894cd4d40600044d401800c884ccd4024014c010008ccd54c01c4800401401000448d4d400c0048800448d4d40080048800848848cc00400c0084800488ccd5cd19b8f002001006005222323230010053200135502522335350130014800088d4d54060008894cd4c02cccd5cd19b8f00200900d00c13007001130060033200135502422335350120014800088d4d5405c008894cd4c028ccd5cd19b8f00200700c00b10011300600312200212200120014881002212330010030022001222222222212333333333300100b00a009008007006005004003002200122123300100300220012221233300100400300220011122002122122330010040031200111221233001003002112001221233001003002200121223002003212230010032001222123330010040030022001121223002003112200112001122002122001200122337000040029040497a0088919180080091198019801001000a4411c28f07a93d7715db0bdc1766c8bd5b116602b105c02c54fc3bcd0d4680001", - &Language::new_plutus_v1() - ).unwrap(); - assert_eq!(script_v1.language, Language::new_plutus_v1().0); - - let script_v2 = PlutusScript::from_hex_with_version( - "590e6f590e6c0100003323332223322333222332232332233223232333222323332223233333333222222223233322232333322223232332232323332223232332233223232333332222233223322332233223322332222323232232232325335303233300a3333573466e1cd55cea8042400046664446660a40060040026eb4d5d0a8041bae35742a00e66a05046666ae68cdc39aab9d37540029000102b11931a982599ab9c04f04c04a049357426ae89401c8c98d4c124cd5ce0268250240239999ab9a3370ea0089001102b11999ab9a3370ea00a9000102c11931a982519ab9c04e04b0490480473333573466e1cd55cea8012400046601a64646464646464646464646666ae68cdc39aab9d500a480008cccccccccc06ccd40a48c8c8cccd5cd19b8735573aa0049000119810981c9aba15002302e357426ae8940088c98d4c164cd5ce02e82d02c02b89aab9e5001137540026ae854028cd40a40a8d5d0a804999aa8183ae502f35742a010666aa060eb940bcd5d0a80399a8148211aba15006335029335505304b75a6ae854014c8c8c8cccd5cd19b8735573aa0049000119a8119919191999ab9a3370e6aae7540092000233502b33504175a6ae854008c118d5d09aba25002232635305d3357380c20bc0b80b626aae7940044dd50009aba150023232323333573466e1cd55cea80124000466a05266a082eb4d5d0a80118231aba135744a004464c6a60ba66ae7018417817016c4d55cf280089baa001357426ae8940088c98d4c164cd5ce02e82d02c02b89aab9e5001137540026ae854010cd40a5d71aba15003335029335505375c40026ae854008c0e0d5d09aba2500223263530553357380b20ac0a80a626ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba150023232323333573466e1d4005200623020303a357426aae79400c8cccd5cd19b875002480108c07cc110d5d09aab9e500423333573466e1d400d20022301f302f357426aae7940148cccd5cd19b875004480008c088dd71aba135573ca00c464c6a60a066ae7015014413c13813413012c4d55cea80089baa001357426ae8940088c98d4c124cd5ce026825024023882489931a982419ab9c4910350543500049047135573ca00226ea80044d55ce9baa001135744a00226aae7940044dd50009109198008018011000911111111109199999999980080580500480400380300280200180110009109198008018011000891091980080180109000891091980080180109000891091980080180109000909111180200290911118018029091111801002909111180080290008919118011bac0013200135503c2233335573e0024a01c466a01a60086ae84008c00cd5d100101811919191999ab9a3370e6aae75400d200023330073232323333573466e1cd55cea8012400046601a605c6ae854008cd404c0a8d5d09aba25002232635303433573807006a06606426aae7940044dd50009aba150033335500b75ca0146ae854008cd403dd71aba135744a004464c6a606066ae700d00c40bc0b84d5d1280089aab9e5001137540024442466600200800600440024424660020060044002266aa002eb9d6889119118011bab00132001355036223233335573e0044a012466a01066aa05c600c6aae754008c014d55cf280118021aba200302b1357420022244004244244660020080062400224464646666ae68cdc3a800a400046a05e600a6ae84d55cf280191999ab9a3370ea00490011281791931a981399ab9c02b028026025024135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011980318039aba15002375a6ae84d5d1280111931a981219ab9c028025023022135573ca00226ea80048848cc00400c00880048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98d4c080cd5ce01201080f80f09baa00112232323333573466e1d400520042500723333573466e1d4009200223500a3006357426aae7940108cccd5cd19b87500348000940288c98d4c08ccd5ce01381201101081000f89aab9d50011375400224244460060082244400422444002240024646666ae68cdc3a800a4004400c46666ae68cdc3a80124000400c464c6a603666ae7007c0700680640604d55ce9baa0011220021220012001232323232323333573466e1d4005200c200b23333573466e1d4009200a200d23333573466e1d400d200823300b375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c46601a6eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc048c050d5d0a8049bae357426ae8940248cccd5cd19b875006480088c050c054d5d09aab9e500b23333573466e1d401d2000230133016357426aae7940308c98d4c080cd5ce01201080f80f00e80e00d80d00c80c09aab9d5004135573ca00626aae7940084d55cf280089baa00121222222230070082212222222330060090082122222223005008122222220041222222200322122222223300200900822122222223300100900820012323232323333573466e1d400520022333008375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea00490001180518059aba135573ca00c464c6a602266ae7005404804003c0384d55cea80189aba25001135573ca00226ea80048488c00800c888488ccc00401401000c80048c8c8cccd5cd19b875001480088c018dd71aba135573ca00646666ae68cdc3a80124000460106eb8d5d09aab9e5004232635300b33573801e01801401201026aae7540044dd5000909118010019091180080190008891119191999ab9a3370e6aae75400920002335500b300635742a004600a6ae84d5d1280111931a980419ab9c00c009007006135573ca00226ea800526120012001112212330010030021120014910350543100222123330010040030022001121223002003112200112001120012001122002122001200111232300100122330033002002001332323233322233322233223332223322332233322233223322332233223233322232323322323232323333222232332232323222323222325335301a5335301a333573466e1cc8cccd54c05048004c8cd406488ccd406400c004008d4058004cd4060888c00cc008004800488cdc0000a40040029000199aa98068900091299a980e299a9a81a1a98169a98131a9812001110009110019119a98188011281c11a81c8009080f880e899a8148010008800a8141a981028009111111111005240040380362038266ae712413c53686f756c642062652065786163746c79206f6e652073637269707420696e70757420746f2061766f696420646f75626c65207361742069737375650001b15335303500315335301a5335301a333573466e20ccc064ccd54c03448005402540a0cc020d4c0c00188880094004074074cdc09a9818003111001a80200d80e080e099ab9c49010f73656c6c6572206e6f7420706169640001b15335301a333573466e20ccc064cc88ccd54c03c48005402d40a8cc028004009400401c074075401006c07040704cd5ce24810d66656573206e6f7420706169640001b101b15335301a3322353022002222222222253353503e33355301f1200133502322533535040002210031001503f253353027333573466e3c0300040a40a04d41040045410000c840a4409d4004d4c0c001888800840704cd5ce2491c4f6e6c792073656c6c65722063616e2063616e63656c206f666665720001b101b135301d00122002153353016333573466e2540040d406005c40d4540044cdc199b8235302b001222003480c920d00f2235301a0012222222222333553011120012235302a002222353034003223353038002253353026333573466e3c0500040a009c4cd40cc01401c401c801d40b0024488cd54c02c480048d4d5408c00488cd54098008cd54c038480048d4d5409800488cd540a4008ccd4d540340048cc0e12000001223303900200123303800148000004cd54c02c480048d4d5408c00488cd54098008ccd4d540280048cd54c03c480048d4d5409c00488cd540a8008d5404400400488ccd5540200580080048cd54c03c480048d4d5409c00488cd540a8008d5403c004004ccd55400c044008004444888ccd54c018480054080cd54c02c480048d4d5408c00488cd54098008d54034004ccd54c0184800488d4d54090008894cd4c05cccd54c04048004c8cd405488ccd4d402c00c88008008004d4d402400488004cd4024894cd4c064008406c40040608d4d5409c00488cc028008014018400c4cd409001000d4084004cd54c02c480048d4d5408c00488c8cd5409c00cc004014c8004d540d8894cd4d40900044d5403400c884d4d540a4008894cd4c070cc0300080204cd5404801c0044c01800c00848848cc00400c00848004c8004d540b488448894cd4d40780044008884cc014008ccd54c01c480040140100044484888c00c01044884888cc0080140104484888c004010448004c8004d540a08844894cd4d406000454068884cd406cc010008cd54c01848004010004c8004d5409c88448894cd4d40600044d401800c884ccd4024014c010008ccd54c01c4800401401000448d4d400c0048800448d4d40080048800848848cc00400c0084800488ccd5cd19b8f002001006005222323230010053200135502522335350130014800088d4d54060008894cd4c02cccd5cd19b8f00200900d00c13007001130060033200135502422335350120014800088d4d5405c008894cd4c028ccd5cd19b8f00200700c00b10011300600312200212200120014881002212330010030022001222222222212333333333300100b00a009008007006005004003002200122123300100300220012221233300100400300220011122002122122330010040031200111221233001003002112001221233001003002200121223002003212230010032001222123330010040030022001121223002003112200112001122002122001200122337000040029040497a0088919180080091198019801001000a4411c28f07a93d7715db0bdc1766c8bd5b116602b105c02c54fc3bcd0d4680001", - &Language::new_plutus_v2() - ).unwrap(); - assert_eq!(script_v2.language, Language::new_plutus_v2().0); - } - - fn redeemer_with_ex_units(mem: &BigNum, steps: &BigNum) -> Redeemer { - Redeemer::new( - &RedeemerTag::new_spend(), - &BigNum::zero(), - &PlutusData::new_integer(&BigInt::from_str("0").unwrap()), - &ExUnits::new(mem, steps), - ) - } - - #[test] - fn test_total_ex_units() { - let mut r = Redeemers::new(); - - fn assert_ex_units(eu: &ExUnits, exp_mem: u64, exp_steps: u64) { - assert_eq!(eu.mem, to_bignum(exp_mem)); - assert_eq!(eu.steps, to_bignum(exp_steps)); - } - - r.add(&redeemer_with_ex_units(&to_bignum(10), &to_bignum(100))); - assert_ex_units(&r.total_ex_units().unwrap(), 10, 100); - r.add(&redeemer_with_ex_units(&to_bignum(20), &to_bignum(200))); - assert_ex_units(&r.total_ex_units().unwrap(), 30, 300); - r.add(&redeemer_with_ex_units(&to_bignum(30), &to_bignum(300))); - assert_ex_units(&r.total_ex_units().unwrap(), 60, 600); - } - - #[test] - fn test_empty_constr_data() { - assert_eq!( - PlutusData::new_empty_constr_plutus_data(&BigNum::one()), - PlutusData::new_constr_plutus_data(&ConstrPlutusData::new( - &BigNum::from_str("1").unwrap(), - &PlutusList::new(), - ),), - ) - } - - #[test] - fn test_plutus_script_version() { - let bytes = hex::decode("4e4d01000033222220051200120011").unwrap(); - let s1: PlutusScript = PlutusScript::from_bytes(bytes.clone()).unwrap(); - let s2: PlutusScript = PlutusScript::from_bytes_v2(bytes.clone()).unwrap(); - - assert_eq!(s1.bytes(), bytes[1..]); - assert_eq!(s2.bytes(), bytes[1..]); - assert_eq!(s1.language_version(), Language::new_plutus_v1()); - assert_eq!(s2.language_version(), Language::new_plutus_v2()); - - assert_eq!( - s1, - PlutusScript::from_bytes_with_version(bytes.clone(), &Language::new_plutus_v1(),) - .unwrap() - ); - assert_eq!( - s2, - PlutusScript::from_bytes_with_version(bytes.clone(), &Language::new_plutus_v2(),) - .unwrap() - ); - } - - #[test] - fn test_language_roundtrip() { - fn deserialize_language_from_uint(x: u64) -> Result { - let mut buf = Serializer::new_vec(); - x.serialize(&mut buf).unwrap(); - Language::from_bytes(buf.finalize()) - } - - assert_eq!( - deserialize_language_from_uint(0).unwrap(), - Language::new_plutus_v1() - ); - assert_eq!( - deserialize_language_from_uint(1).unwrap(), - Language::new_plutus_v2() - ); - assert!(deserialize_language_from_uint(2).is_err()); - - assert_eq!( - Language::from_bytes(Language::new_plutus_v1().to_bytes()).unwrap(), - Language::new_plutus_v1(), - ); - assert_eq!( - Language::from_bytes(Language::new_plutus_v2().to_bytes()).unwrap(), - Language::new_plutus_v2(), - ); - } - - #[test] - fn test_cost_model_roundtrip() { - use crate::TxBuilderConstants; - let costmodels = TxBuilderConstants::plutus_vasil_cost_models(); - assert_eq!( - costmodels, - Costmdls::from_bytes(costmodels.to_bytes()).unwrap() - ); - } - - #[test] - fn test_known_plutus_data_hash() { - use crate::TxBuilderConstants; - let pdata = PlutusList::from(vec![PlutusData::new_constr_plutus_data( - &ConstrPlutusData::new( - &BigNum::zero(), - &PlutusList::from(vec![ - PlutusData::new_constr_plutus_data(&ConstrPlutusData::new( - &BigNum::zero(), - &PlutusList::from(vec![ - PlutusData::new_bytes( - hex::decode( - "A183BF86925F66C579A3745C9517744399679B090927B8F6E2F2E1BB", - ) - .unwrap(), - ), - PlutusData::new_bytes( - hex::decode("6164617065416D616E734576616E73").unwrap(), - ), - ]), - )), - PlutusData::new_constr_plutus_data(&ConstrPlutusData::new( - &BigNum::zero(), - &PlutusList::from(vec![ - PlutusData::new_bytes( - hex::decode( - "9A4E855293A0B9AF5E50935A331D83E7982AB5B738EA0E6FC0F9E656", - ) - .unwrap(), - ), - PlutusData::new_bytes( - hex::decode("4652414D455F38333030325F4C30").unwrap(), - ), - ]), - )), - PlutusData::new_bytes( - hex::decode("BEA1C521DF58F4EEEF60C647E5EBD88C6039915409F9FD6454A476B9") - .unwrap(), - ), - ]), - ), - )]); - let redeemers = Redeemers(vec![Redeemer::new( - &RedeemerTag::new_spend(), - &BigNum::one(), - &PlutusData::new_empty_constr_plutus_data(&BigNum::zero()), - &ExUnits::new(&to_bignum(7000000), &to_bignum(3000000000)), - )]); - let lang = Language::new_plutus_v1(); - let lang_costmodel = TxBuilderConstants::plutus_vasil_cost_models() - .get(&lang) - .unwrap(); - let mut retained_cost_models = Costmdls::new(); - retained_cost_models.insert(&lang, &lang_costmodel); - let hash = hash_script_data(&redeemers, &retained_cost_models, Some(pdata)); - assert_eq!( - hex::encode(hash.to_bytes()), - "2fd8b7e248b376314d02989c885c278796ab0e1d6e8aa0cb91f562ff5f7dbd70" - ); - } - - #[test] - fn test_same_datum_in_different_formats_with_expected_hashes() { - // This is a known datum with indefinite arrays and a known expected hash - let pdata1 = PlutusData::from_bytes(hex::decode("d8799fd8799f581ca183bf86925f66c579a3745c9517744399679b090927b8f6e2f2e1bb4f616461706541696c656e416d61746fffd8799f581c9a4e855293a0b9af5e50935a331d83e7982ab5b738ea0e6fc0f9e6564e4652414d455f36353030335f4c30ff581cbea1c521df58f4eeef60c647e5ebd88c6039915409f9fd6454a476b9ff").unwrap()).unwrap(); - assert_eq!( - hex::encode(hash_plutus_data(&pdata1).to_bytes()), - "ec3028f46325b983a470893a8bdc1b4a100695b635fb1237d301c3490b23e89b" - ); - // This is the same exact datum manually converted to definite arrays - // and it produces a different known expected hash because the format is preserved after deserialization - let pdata2 = PlutusData::from_bytes(hex::decode("d87983d87982581ca183bf86925f66c579a3745c9517744399679b090927b8f6e2f2e1bb4f616461706541696c656e416d61746fd87982581c9a4e855293a0b9af5e50935a331d83e7982ab5b738ea0e6fc0f9e6564e4652414d455f36353030335f4c30581cbea1c521df58f4eeef60c647e5ebd88c6039915409f9fd6454a476b9").unwrap()).unwrap(); - assert_eq!( - hex::encode(hash_plutus_data(&pdata2).to_bytes()), - "816cdf6d4d8cba3ad0188ca643db95ddf0e03cdfc0e75a9550a72a82cb146222" - ); - } - - #[test] - fn test_known_plutus_data_hash_with_no_datums() { - let mut costmodels = Costmdls::new(); - costmodels.insert( - &Language::new_plutus_v2(), - &TxBuilderConstants::plutus_vasil_cost_models() - .get(&Language::new_plutus_v2()) - .unwrap(), - ); - let hash = hash_script_data( - &Redeemers(vec![Redeemer::new( - &RedeemerTag::new_spend(), - &BigNum::zero(), - &PlutusData::new_empty_constr_plutus_data(&BigNum::zero()), - &ExUnits::new(&to_bignum(842996), &to_bignum(246100241)), - )]), - &costmodels, - None, - ); - assert_eq!( - hex::encode(hash.to_bytes()), - "6b244f15f895fd458a02bef3a8b56f17f24150fddcb06be482f8790a600578a1" - ); - } - - #[test] - fn test_known_plutus_data_hash_2() { - let datums = PlutusList::from(vec![PlutusData::new_constr_plutus_data( - &ConstrPlutusData::new( - &BigNum::zero(), - &PlutusList::from(vec![ - PlutusData::new_bytes( - hex::decode("45F6A506A49A38263C4A8BBB2E1E369DD8732FB1F9A281F3E8838387") - .unwrap(), - ), - PlutusData::new_integer(&BigInt::from_str("60000000").unwrap()), - PlutusData::new_bytes( - hex::decode("EE8E37676F6EBB8E031DFF493F88FF711D24AA68666A09D61F1D3FB3") - .unwrap(), - ), - PlutusData::new_bytes(hex::decode("43727970746F44696E6F3036333039").unwrap()), - ]), - ), - )]); - let redeemers = Redeemers(vec![Redeemer::new( - &RedeemerTag::new_spend(), - &BigNum::one(), - &PlutusData::new_empty_constr_plutus_data(&BigNum::one()), - &ExUnits::new(&to_bignum(61300), &to_bignum(18221176)), - )]); - let hash = hash_script_data( - &redeemers, - &TxBuilderConstants::plutus_vasil_cost_models() - .retain_language_versions(&Languages(vec![Language::new_plutus_v1()])), - Some(datums), - ); - assert_eq!( - hex::encode(hash.to_bytes()), - "0a076247a05aacbecf72ea15b94e3d0331b21295a08d9ab7b8675c13840563a6" - ); - } - - #[test] - fn datum_from_enterprise_key_address() { - let address = - Address::from_bech32("addr1vxy2c673nsdp0mvgq5d3tpjndngucsytug00k7k6xwlx4lg6dspk5") - .unwrap(); - let datum = PlutusData::from_address(&address).unwrap(); - let orig_datum = PlutusData::from_json("{\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"bytes\": \"88ac6bd19c1a17ed88051b1586536cd1cc408be21efb7ada33be6afd\"}]}, {\"constructor\": 1, \"fields\": []}]}", - PlutusDatumSchema::DetailedSchema).unwrap(); - assert_eq!(datum, orig_datum); - } - - #[test] - fn datum_from_enterprise_script_address() { - let address = - Address::from_bech32("addr1w8wrk560wcsldjpnqjamn8s0gn9pdrplpyetrdfpacqrpfs3xezd8") - .unwrap(); - let datum = PlutusData::from_address(&address).unwrap(); - let orig_datum = PlutusData::from_json("{\"constructor\": 0, \"fields\": [{\"constructor\": 1, \"fields\": [{\"bytes\": \"dc3b534f7621f6c83304bbb99e0f44ca168c3f0932b1b521ee0030a6\"}]}, {\"constructor\": 1, \"fields\": []}]}", - PlutusDatumSchema::DetailedSchema).unwrap(); - assert_eq!(datum, orig_datum); - } - - #[test] - fn datum_from_base_key_key_address() { - let address = Address::from_bech32("addr1qxy2c673nsdp0mvgq5d3tpjndngucsytug00k7k6xwlx4lvg434ar8q6zlkcspgmzkr9xmx3e3qghcs7ldad5va7dt7s5efyer").unwrap(); - let datum = PlutusData::from_address(&address).unwrap(); - let orig_datum = PlutusData::from_json("{\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"bytes\": \"88ac6bd19c1a17ed88051b1586536cd1cc408be21efb7ada33be6afd\"}]}, {\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"bytes\": \"88ac6bd19c1a17ed88051b1586536cd1cc408be21efb7ada33be6afd\"}]}]}]}]}", - PlutusDatumSchema::DetailedSchema).unwrap(); - assert_eq!(datum, orig_datum); - } - - #[test] - fn datum_from_base_script_script_address() { - let address = Address::from_bech32("addr1x8wrk560wcsldjpnqjamn8s0gn9pdrplpyetrdfpacqrpfku8df57a3p7myrxp9mhx0q73x2z6xr7zfjkx6jrmsqxznqh8u5dz").unwrap(); - let datum = PlutusData::from_address(&address).unwrap(); - let orig_datum = PlutusData::from_json("{\"constructor\": 0, \"fields\": [{\"constructor\": 1, \"fields\": [{\"bytes\": \"dc3b534f7621f6c83304bbb99e0f44ca168c3f0932b1b521ee0030a6\"}]}, {\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"constructor\": 1, \"fields\": [{\"bytes\": \"dc3b534f7621f6c83304bbb99e0f44ca168c3f0932b1b521ee0030a6\"}]}]}]}]}", - PlutusDatumSchema::DetailedSchema).unwrap(); - assert_eq!(datum, orig_datum); - } - - #[test] - fn datum_from_base_script_key_address() { - let address = Address::from_bech32("addr1z8wrk560wcsldjpnqjamn8s0gn9pdrplpyetrdfpacqrpf5g434ar8q6zlkcspgmzkr9xmx3e3qghcs7ldad5va7dt7sqx2wxh").unwrap(); - let datum = PlutusData::from_address(&address).unwrap(); - let orig_datum = PlutusData::from_json("{\"constructor\": 0, \"fields\": [{\"constructor\": 1, \"fields\": [{\"bytes\": \"dc3b534f7621f6c83304bbb99e0f44ca168c3f0932b1b521ee0030a6\"}]}, {\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"bytes\": \"88ac6bd19c1a17ed88051b1586536cd1cc408be21efb7ada33be6afd\"}]}]}]}]}", - PlutusDatumSchema::DetailedSchema).unwrap(); - assert_eq!(datum, orig_datum); - } - - #[test] - fn datum_from_base_key_script_address() { - let address = Address::from_bech32("addr1yxy2c673nsdp0mvgq5d3tpjndngucsytug00k7k6xwlx4lwu8df57a3p7myrxp9mhx0q73x2z6xr7zfjkx6jrmsqxznqrcl7jk").unwrap(); - let datum = PlutusData::from_address(&address).unwrap(); - let orig_datum = PlutusData::from_json("{\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"bytes\": \"88ac6bd19c1a17ed88051b1586536cd1cc408be21efb7ada33be6afd\"}]}, {\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"constructor\": 1, \"fields\": [{\"bytes\": \"dc3b534f7621f6c83304bbb99e0f44ca168c3f0932b1b521ee0030a6\"}]}]}]}]}", - PlutusDatumSchema::DetailedSchema).unwrap(); - assert_eq!(datum, orig_datum); - } -} diff --git a/rust/src/protocol_types/metadata.rs b/rust/src/protocol_types/metadata.rs new file mode 100644 index 00000000..94f0b11a --- /dev/null +++ b/rust/src/protocol_types/metadata.rs @@ -0,0 +1,754 @@ +use crate::*; +use linked_hash_map::LinkedHashMap; + +const MD_MAX_LEN: usize = 64; + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct MetadataMap(pub(crate) LinkedHashMap); + +to_from_bytes!(MetadataMap); + +#[wasm_bindgen] +impl MetadataMap { + pub fn new() -> Self { + Self(LinkedHashMap::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn insert( + &mut self, + key: &TransactionMetadatum, + value: &TransactionMetadatum, + ) -> Option { + self.0.insert(key.clone(), value.clone()) + } + + // convenience function for inserting as a string key + pub fn insert_str( + &mut self, + key: &str, + value: &TransactionMetadatum, + ) -> Result, JsError> { + Ok(self.insert(&TransactionMetadatum::new_text(key.to_owned())?, value)) + } + + // convenience function for inserting 32-bit integers - for higher-precision integers use insert() with an Int struct + pub fn insert_i32( + &mut self, + key: i32, + value: &TransactionMetadatum, + ) -> Option { + self.insert(&TransactionMetadatum::new_int(&Int::new_i32(key)), value) + } + + pub fn get(&self, key: &TransactionMetadatum) -> Result { + self.0 + .get(key) + .map(|v| v.clone()) + .ok_or_else(|| JsError::from_str(&format!("key {:?} not found", key))) + } + + // convenience function for retrieving a string key + pub fn get_str(&self, key: &str) -> Result { + self.get(&TransactionMetadatum::new_text(key.to_owned())?) + } + + // convenience function for retrieving 32-bit integer keys - for higher-precision integers use get() with an Int struct + pub fn get_i32(&self, key: i32) -> Result { + self.get(&TransactionMetadatum::new_int(&Int::new_i32(key))) + } + + pub fn has(&self, key: &TransactionMetadatum) -> bool { + self.0.contains_key(key) + } + + pub fn keys(&self) -> MetadataList { + MetadataList( + self.0 + .iter() + .map(|(k, _v)| k.clone()) + .collect::>(), + ) + } +} + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct MetadataList(pub(crate) Vec); + +to_from_bytes!(MetadataList); + +#[wasm_bindgen] +impl MetadataList { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> TransactionMetadatum { + self.0[index].clone() + } + + pub fn add(&mut self, elem: &TransactionMetadatum) { + self.0.push(elem.clone()); + } +} + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub enum TransactionMetadatumKind { + MetadataMap, + MetadataList, + Int, + Bytes, + Text, +} + +#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub(crate) enum TransactionMetadatumEnum { + MetadataMap(MetadataMap), + MetadataList(MetadataList), + Int(Int), + Bytes(Vec), + Text(String), +} + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct TransactionMetadatum(pub(crate) TransactionMetadatumEnum); + +to_from_bytes!(TransactionMetadatum); + +#[wasm_bindgen] +impl TransactionMetadatum { + pub fn new_map(map: &MetadataMap) -> Self { + Self(TransactionMetadatumEnum::MetadataMap(map.clone())) + } + + pub fn new_list(list: &MetadataList) -> Self { + Self(TransactionMetadatumEnum::MetadataList(list.clone())) + } + + pub fn new_int(int: &Int) -> Self { + Self(TransactionMetadatumEnum::Int(int.clone())) + } + + pub fn new_bytes(bytes: Vec) -> Result { + if bytes.len() > MD_MAX_LEN { + Err(JsError::from_str(&format!( + "Max metadata bytes too long: {}, max = {}", + bytes.len(), + MD_MAX_LEN + ))) + } else { + Ok(Self(TransactionMetadatumEnum::Bytes(bytes))) + } + } + + pub fn new_text(text: String) -> Result { + if text.len() > MD_MAX_LEN { + Err(JsError::from_str(&format!( + "Max metadata string too long: {}, max = {}", + text.len(), + MD_MAX_LEN + ))) + } else { + Ok(Self(TransactionMetadatumEnum::Text(text))) + } + } + + pub fn kind(&self) -> TransactionMetadatumKind { + match &self.0 { + TransactionMetadatumEnum::MetadataMap(_) => TransactionMetadatumKind::MetadataMap, + TransactionMetadatumEnum::MetadataList(_) => TransactionMetadatumKind::MetadataList, + TransactionMetadatumEnum::Int(_) => TransactionMetadatumKind::Int, + TransactionMetadatumEnum::Bytes(_) => TransactionMetadatumKind::Bytes, + TransactionMetadatumEnum::Text(_) => TransactionMetadatumKind::Text, + } + } + + pub fn as_map(&self) -> Result { + match &self.0 { + TransactionMetadatumEnum::MetadataMap(x) => Ok(x.clone()), + _ => Err(JsError::from_str("not a map")), + } + } + + pub fn as_list(&self) -> Result { + match &self.0 { + TransactionMetadatumEnum::MetadataList(x) => Ok(x.clone()), + _ => Err(JsError::from_str("not a list")), + } + } + + pub fn as_int(&self) -> Result { + match &self.0 { + TransactionMetadatumEnum::Int(x) => Ok(x.clone()), + _ => Err(JsError::from_str("not an int")), + } + } + + pub fn as_bytes(&self) -> Result, JsError> { + match &self.0 { + TransactionMetadatumEnum::Bytes(x) => Ok(x.clone()), + _ => Err(JsError::from_str("not bytes")), + } + } + + pub fn as_text(&self) -> Result { + match &self.0 { + TransactionMetadatumEnum::Text(x) => Ok(x.clone()), + _ => Err(JsError::from_str("not text")), + } + } +} + +impl serde::Serialize for TransactionMetadatum { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let json_str = decode_metadatum_to_json_str(self, MetadataJsonSchema::DetailedSchema) + .map_err(|e| serde::ser::Error::custom(&format!("{:?}", e)))?; + serializer.serialize_str(&json_str) + } +} + +impl<'de> serde::de::Deserialize<'de> for TransactionMetadatum { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = ::deserialize(deserializer)?; + encode_json_str_to_metadatum(s.clone(), MetadataJsonSchema::DetailedSchema).map_err(|e| { + serde::de::Error::invalid_value( + serde::de::Unexpected::Str(&s), + &format!("{:?}", e).as_str(), + ) + }) + } +} + +// just for now we'll do json-in-json until I can figure this out better +// TODO: maybe not generate this? or how do we do this? +impl JsonSchema for TransactionMetadatum { + fn schema_name() -> String { + String::from("TransactionMetadatum") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + String::json_schema(gen) + } + fn is_referenceable() -> bool { + String::is_referenceable() + } +} + +pub type TransactionMetadatumLabel = BigNum; + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub struct TransactionMetadatumLabels(pub(crate) Vec); + +to_from_bytes!(TransactionMetadatumLabels); + +#[wasm_bindgen] +impl TransactionMetadatumLabels { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> TransactionMetadatumLabel { + self.0[index].clone() + } + + pub fn add(&mut self, elem: &TransactionMetadatumLabel) { + self.0.push(elem.clone()); + } +} + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub struct GeneralTransactionMetadata( + pub(crate) LinkedHashMap, +); + +impl_to_from!(GeneralTransactionMetadata); + +#[wasm_bindgen] +impl GeneralTransactionMetadata { + pub fn new() -> Self { + Self(LinkedHashMap::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn insert( + &mut self, + key: &TransactionMetadatumLabel, + value: &TransactionMetadatum, + ) -> Option { + self.0.insert(key.clone(), value.clone()) + } + + pub fn get(&self, key: &TransactionMetadatumLabel) -> Option { + self.0.get(key).map(|v| v.clone()) + } + + pub fn keys(&self) -> TransactionMetadatumLabels { + TransactionMetadatumLabels( + self.0 + .iter() + .map(|(k, _v)| k.clone()) + .collect::>(), + ) + } +} + +impl serde::Serialize for GeneralTransactionMetadata { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let map = self.0.iter().collect::>(); + map.serialize(serializer) + } +} + +impl<'de> serde::de::Deserialize<'de> for GeneralTransactionMetadata { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let map = as serde::de::Deserialize>::deserialize( + deserializer, + )?; + Ok(Self(map.into_iter().collect())) + } +} + +impl JsonSchema for GeneralTransactionMetadata { + fn schema_name() -> String { + String::from("GeneralTransactionMetadata") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + std::collections::BTreeMap::::json_schema( + gen, + ) + } + fn is_referenceable() -> bool { + std::collections::BTreeMap::::is_referenceable() + } +} + +#[wasm_bindgen] +#[derive(Clone, Debug, Ord, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema)] +pub struct AuxiliaryData { + pub(crate) metadata: Option, + pub(crate) native_scripts: Option, + pub(crate) plutus_scripts: Option, + pub(crate) prefer_alonzo_format: bool, +} + +impl std::cmp::PartialEq for AuxiliaryData { + fn eq(&self, other: &Self) -> bool { + self.metadata.eq(&other.metadata) + && self.native_scripts.eq(&other.native_scripts) + && self.plutus_scripts.eq(&other.plutus_scripts) + } +} + +impl std::cmp::Eq for AuxiliaryData {} + +impl_to_from!(AuxiliaryData); + +#[wasm_bindgen] +impl AuxiliaryData { + pub fn new() -> Self { + Self { + metadata: None, + native_scripts: None, + plutus_scripts: None, + prefer_alonzo_format: false, + } + } + + pub fn metadata(&self) -> Option { + self.metadata.clone() + } + + pub fn set_metadata(&mut self, metadata: &GeneralTransactionMetadata) { + self.metadata = Some(metadata.clone()); + } + + pub fn native_scripts(&self) -> Option { + self.native_scripts.clone() + } + + pub fn set_native_scripts(&mut self, native_scripts: &NativeScripts) { + self.native_scripts = Some(native_scripts.clone()) + } + + pub fn plutus_scripts(&self) -> Option { + self.plutus_scripts.clone() + } + + pub fn set_plutus_scripts(&mut self, plutus_scripts: &PlutusScripts) { + self.plutus_scripts = Some(plutus_scripts.clone()) + } + + pub fn prefer_alonzo_format(&self) -> bool { + self.prefer_alonzo_format.clone() + } + + pub fn set_prefer_alonzo_format(&mut self, prefer: bool) { + self.prefer_alonzo_format = prefer + } +} + +// encodes arbitrary bytes into chunks of 64 bytes (the limit for bytes) as a list to be valid Metadata +#[wasm_bindgen] +pub fn encode_arbitrary_bytes_as_metadatum(bytes: &[u8]) -> TransactionMetadatum { + let mut list = MetadataList::new(); + for chunk in bytes.chunks(MD_MAX_LEN) { + // this should never fail as we are already chunking it + list.add(&TransactionMetadatum::new_bytes(chunk.to_vec()).unwrap()); + } + TransactionMetadatum::new_list(&list) +} + +// decodes from chunks of bytes in a list to a byte vector if that is the metadata format, otherwise returns None +#[wasm_bindgen] +pub fn decode_arbitrary_bytes_from_metadatum( + metadata: &TransactionMetadatum, +) -> Result, JsError> { + let mut bytes = Vec::new(); + for elem in metadata.as_list()?.0 { + bytes.append(&mut elem.as_bytes()?); + } + Ok(bytes) +} + +#[wasm_bindgen] +#[derive(Copy, Clone, Eq, PartialEq)] +// Different schema methods for mapping between JSON and the metadata CBOR. +// This conversion should match TxMetadataJsonSchema in cardano-node defined (at time of writing) here: +// https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/MetaData.hs +// but has 2 additional schemas for more or less conversionse +// Note: Byte/Strings (including keys) in any schema must be at most 64 bytes in length +pub enum MetadataJsonSchema { + // Does zero implicit conversions. + // Round-trip conversions are 100% consistent + // Treats maps DIRECTLY as maps in JSON in a natural way e.g. {"key1": 47, "key2": [0, 1]]} + // From JSON: + // * null/true/false NOT supported. + // * keys treated as strings only + // To JSON + // * Bytes, non-string keys NOT supported. + // Stricter than any TxMetadataJsonSchema in cardano-node but more natural for JSON -> Metadata + NoConversions, + // Does some implicit conversions. + // Round-trip conversions MD -> JSON -> MD is NOT consistent, but JSON -> MD -> JSON is. + // Without using bytes + // Maps are treated as an array of k-v pairs as such: [{"key1": 47}, {"key2": [0, 1]}, {"key3": "0xFFFF"}] + // From JSON: + // * null/true/false NOT supported. + // * Strings parseable as bytes (0x starting hex) or integers are converted. + // To JSON: + // * Non-string keys partially supported (bytes as 0x starting hex string, integer converted to string). + // * Bytes are converted to hex strings starting with 0x for both values and keys. + // Corresponds to TxMetadataJsonSchema's TxMetadataJsonNoSchema in cardano-node + BasicConversions, + // Supports the annotated schema presented in cardano-node with tagged values e.g. {"int": 7}, {"list": [0, 1]} + // Round-trip conversions are 100% consistent + // Maps are treated as an array of k-v pairs as such: [{"key1": {"int": 47}}, {"key2": {"list": [0, 1]}}, {"key3": {"bytes": "0xFFFF"}}] + // From JSON: + // * null/true/false NOT supported. + // * Strings parseable as bytes (hex WITHOUT 0x prefix) or integers converted. + // To JSON: + // * Non-string keys are supported. Any key parseable as JSON is encoded as metadata instead of a string + // Corresponds to TxMetadataJsonSchema's TxMetadataJsonDetailedSchema in cardano-node + DetailedSchema, +} + +fn supports_tagged_values(schema: MetadataJsonSchema) -> bool { + match schema { + MetadataJsonSchema::NoConversions | MetadataJsonSchema::BasicConversions => false, + MetadataJsonSchema::DetailedSchema => true, + } +} + +fn hex_string_to_bytes(hex: &str) -> Option> { + if hex.starts_with("0x") { + hex::decode(&hex[2..]).ok() + } else { + None + } +} + +fn bytes_to_hex_string(bytes: &[u8]) -> String { + format!("0x{}", hex::encode(bytes)) +} + +// Converts JSON to Metadata according to MetadataJsonSchema +#[wasm_bindgen] +pub fn encode_json_str_to_metadatum( + json: String, + schema: MetadataJsonSchema, +) -> Result { + let value = serde_json::from_str(&json).map_err(|e| JsError::from_str(&e.to_string()))?; + encode_json_value_to_metadatum(value, schema) +} + +pub fn encode_json_value_to_metadatum( + value: serde_json::Value, + schema: MetadataJsonSchema, +) -> Result { + use serde_json::Value; + fn encode_number(x: serde_json::Number) -> Result { + if let Some(x) = x.as_u64() { + Ok(TransactionMetadatum::new_int(&Int::new(&utils::to_bignum( + x, + )))) + } else if let Some(x) = x.as_i64() { + Ok(TransactionMetadatum::new_int(&Int::new_negative( + &utils::to_bignum(-x as u64), + ))) + } else { + Err(JsError::from_str("floats not allowed in metadata")) + } + } + fn encode_string( + s: String, + schema: MetadataJsonSchema, + ) -> Result { + if schema == MetadataJsonSchema::BasicConversions { + match hex_string_to_bytes(&s) { + Some(bytes) => TransactionMetadatum::new_bytes(bytes), + None => TransactionMetadatum::new_text(s), + } + } else { + TransactionMetadatum::new_text(s) + } + } + fn encode_array( + json_arr: Vec, + schema: MetadataJsonSchema, + ) -> Result { + let mut arr = MetadataList::new(); + for value in json_arr { + arr.add(&encode_json_value_to_metadatum(value, schema)?); + } + Ok(TransactionMetadatum::new_list(&arr)) + } + match schema { + MetadataJsonSchema::NoConversions | MetadataJsonSchema::BasicConversions => match value { + Value::Null => Err(JsError::from_str("null not allowed in metadata")), + Value::Bool(_) => Err(JsError::from_str("bools not allowed in metadata")), + Value::Number(x) => encode_number(x), + Value::String(s) => encode_string(s, schema), + Value::Array(json_arr) => encode_array(json_arr, schema), + Value::Object(json_obj) => { + let mut map = MetadataMap::new(); + for (raw_key, value) in json_obj { + let key = if schema == MetadataJsonSchema::BasicConversions { + match raw_key.parse::() { + Ok(x) => TransactionMetadatum::new_int(&Int(x)), + Err(_) => encode_string(raw_key, schema)?, + } + } else { + TransactionMetadatum::new_text(raw_key)? + }; + map.insert(&key, &encode_json_value_to_metadatum(value, schema)?); + } + Ok(TransactionMetadatum::new_map(&map)) + } + }, + // we rely on tagged objects to control parsing here instead + MetadataJsonSchema::DetailedSchema => match value { + Value::Object(obj) if obj.len() == 1 => { + let (k, v) = obj.into_iter().next().unwrap(); + fn tag_mismatch() -> JsError { + JsError::from_str("key does not match type") + } + match k.as_str() { + "int" => match v { + Value::Number(x) => encode_number(x), + _ => Err(tag_mismatch()), + }, + "string" => { + encode_string(v.as_str().ok_or_else(tag_mismatch)?.to_owned(), schema) + } + "bytes" => match hex::decode(v.as_str().ok_or_else(tag_mismatch)?) { + Ok(bytes) => TransactionMetadatum::new_bytes(bytes), + Err(_) => Err(JsError::from_str( + "invalid hex string in tagged byte-object", + )), + }, + "list" => encode_array(v.as_array().ok_or_else(tag_mismatch)?.clone(), schema), + "map" => { + let mut map = MetadataMap::new(); + fn map_entry_err() -> JsError { + JsError::from_str("entry format in detailed schema map object not correct. Needs to be of form {\"k\": \"key\", \"v\": value}") + } + for entry in v.as_array().ok_or_else(tag_mismatch)? { + let entry_obj = entry.as_object().ok_or_else(map_entry_err)?; + let raw_key = entry_obj.get("k").ok_or_else(map_entry_err)?; + let value = entry_obj.get("v").ok_or_else(map_entry_err)?; + let key = encode_json_value_to_metadatum(raw_key.clone(), schema)?; + map.insert( + &key, + &encode_json_value_to_metadatum(value.clone(), schema)?, + ); + } + Ok(TransactionMetadatum::new_map(&map)) + } + invalid_key => Err(JsError::from_str(&format!( + "key '{}' in tagged object not valid", + invalid_key + ))), + } + } + _ => Err(JsError::from_str( + "DetailedSchema requires types to be tagged objects", + )), + }, + } +} + +// Converts Metadata to JSON according to MetadataJsonSchema +#[wasm_bindgen] +pub fn decode_metadatum_to_json_str( + metadatum: &TransactionMetadatum, + schema: MetadataJsonSchema, +) -> Result { + let value = decode_metadatum_to_json_value(metadatum, schema)?; + serde_json::to_string(&value).map_err(|e| JsError::from_str(&e.to_string())) +} + +pub fn decode_metadatum_to_json_value( + metadatum: &TransactionMetadatum, + schema: MetadataJsonSchema, +) -> Result { + use serde_json::Value; + use std::convert::TryFrom; + fn decode_key( + key: &TransactionMetadatum, + schema: MetadataJsonSchema, + ) -> Result { + match &key.0 { + TransactionMetadatumEnum::Text(s) => Ok(s.clone()), + TransactionMetadatumEnum::Bytes(b) if schema != MetadataJsonSchema::NoConversions => { + Ok(bytes_to_hex_string(b.as_ref())) + } + TransactionMetadatumEnum::Int(i) if schema != MetadataJsonSchema::NoConversions => { + let int_str = if i.0 >= 0 { + u64::try_from(i.0).map(|x| x.to_string()) + } else { + i64::try_from(i.0).map(|x| x.to_string()) + }; + int_str.map_err(|e| JsError::from_str(&e.to_string())) + } + TransactionMetadatumEnum::MetadataList(list) + if schema == MetadataJsonSchema::DetailedSchema => + { + decode_metadatum_to_json_str(&TransactionMetadatum::new_list(&list), schema) + } + TransactionMetadatumEnum::MetadataMap(map) + if schema == MetadataJsonSchema::DetailedSchema => + { + decode_metadatum_to_json_str(&TransactionMetadatum::new_map(&map), schema) + } + _ => Err(JsError::from_str(&format!( + "key type {:?} not allowed in JSON under specified schema", + key.0 + ))), + } + } + let (type_key, value) = match &metadatum.0 { + TransactionMetadatumEnum::MetadataMap(map) => match schema { + MetadataJsonSchema::NoConversions | MetadataJsonSchema::BasicConversions => { + // treats maps directly as JSON maps + let mut json_map = serde_json::map::Map::with_capacity(map.len()); + for (key, value) in map.0.iter() { + json_map.insert( + decode_key(key, schema)?, + decode_metadatum_to_json_value(value, schema)?, + ); + } + ("map", Value::from(json_map)) + } + + MetadataJsonSchema::DetailedSchema => ( + "map", + Value::from( + map.0 + .iter() + .map(|(key, value)| { + // must encode maps as JSON lists of objects with k/v keys + // also in these schemas we support more key types than strings + let k = decode_metadatum_to_json_value(key, schema)?; + let v = decode_metadatum_to_json_value(value, schema)?; + let mut kv_obj = serde_json::map::Map::with_capacity(2); + kv_obj.insert(String::from("k"), Value::from(k)); + kv_obj.insert(String::from("v"), v); + Ok(Value::from(kv_obj)) + }) + .collect::, JsError>>()?, + ), + ), + }, + TransactionMetadatumEnum::MetadataList(arr) => ( + "list", + Value::from( + arr.0 + .iter() + .map(|e| decode_metadatum_to_json_value(e, schema)) + .collect::, JsError>>()?, + ), + ), + TransactionMetadatumEnum::Int(x) => ( + "int", + if x.0 >= 0 { + Value::from(u64::try_from(x.0).map_err(|e| JsError::from_str(&e.to_string()))?) + } else { + Value::from(i64::try_from(x.0).map_err(|e| JsError::from_str(&e.to_string()))?) + }, + ), + TransactionMetadatumEnum::Bytes(bytes) => ( + "bytes", + match schema { + MetadataJsonSchema::NoConversions => Err(JsError::from_str( + "bytes not allowed in JSON in specified schema", + )), + // 0x prefix + MetadataJsonSchema::BasicConversions => { + Ok(Value::from(bytes_to_hex_string(bytes.as_ref()))) + } + // no prefix + MetadataJsonSchema::DetailedSchema => Ok(Value::from(hex::encode(bytes))), + }?, + ), + TransactionMetadatumEnum::Text(s) => ("string", Value::from(s.clone())), + }; + // potentially wrap value in a keyed map to represent more types + if supports_tagged_values(schema) { + let mut wrapper = serde_json::map::Map::with_capacity(1); + wrapper.insert(String::from(type_key), value); + Ok(Value::from(wrapper)) + } else { + Ok(value) + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/mod.rs b/rust/src/protocol_types/mod.rs index 704055f8..c6e7e9ce 100644 --- a/rust/src/protocol_types/mod.rs +++ b/rust/src/protocol_types/mod.rs @@ -7,3 +7,9 @@ pub use certificates::*; mod governance; pub use governance::*; + +mod plutus; +pub use plutus::*; + +mod metadata; +pub use metadata::*; diff --git a/rust/src/protocol_types/plutus.rs b/rust/src/protocol_types/plutus.rs new file mode 100644 index 00000000..20b11853 --- /dev/null +++ b/rust/src/protocol_types/plutus.rs @@ -0,0 +1,1489 @@ +use crate::*; +use core::hash::Hasher; +use linked_hash_map::LinkedHashMap; +use std::hash::Hash; + +// This library was code-generated using an experimental CDDL to rust tool: +// https://github.com/Emurgo/cddl-codegen + +use cbor_event::{ + self, + de::Deserializer, + se::{Serialize, Serializer}, +}; + +use schemars::JsonSchema; + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub struct PlutusScript { + pub(crate) bytes: Vec, + pub(crate) language: LanguageKind, +} + +to_from_bytes!(PlutusScript); + +#[wasm_bindgen] +impl PlutusScript { + /** + * Creates a new Plutus script from the RAW bytes of the compiled script. + * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) + * If you creating this from those you should use PlutusScript::from_bytes() instead. + */ + pub fn new(bytes: Vec) -> PlutusScript { + Self::new_with_version(bytes, &Language::new_plutus_v1()) + } + + /** + * Creates a new Plutus script from the RAW bytes of the compiled script. + * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) + * If you creating this from those you should use PlutusScript::from_bytes() instead. + */ + pub fn new_v2(bytes: Vec) -> PlutusScript { + Self::new_with_version(bytes, &Language::new_plutus_v2()) + } + + /** + * Creates a new Plutus script from the RAW bytes of the compiled script. + * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) + * If you creating this from those you should use PlutusScript::from_bytes() instead. + */ + pub fn new_v3(bytes: Vec) -> PlutusScript { + Self::new_with_version(bytes, &Language::new_plutus_v3()) + } + + /** + * Creates a new Plutus script from the RAW bytes of the compiled script. + * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) + * If you creating this from those you should use PlutusScript::from_bytes() instead. + */ + pub fn new_with_version(bytes: Vec, language: &Language) -> PlutusScript { + Self { + bytes, + language: language.0.clone(), + } + } + + /** + * The raw bytes of this compiled Plutus script. + * If you need "cborBytes" for cardano-cli use PlutusScript::to_bytes() instead. + */ + pub fn bytes(&self) -> Vec { + self.bytes.clone() + } + + /// Same as `.from_bytes` but will consider the script as requiring the Plutus Language V2 + pub fn from_bytes_v2(bytes: Vec) -> Result { + Self::from_bytes_with_version(bytes, &Language::new_plutus_v2()) + } + + /// Same as `.from_bytes` but will consider the script as requiring the Plutus Language V3 + pub fn from_bytes_v3(bytes: Vec) -> Result { + Self::from_bytes_with_version(bytes, &Language::new_plutus_v3()) + } + + /// Same as `.from_bytes` but will consider the script as requiring the specified language version + pub fn from_bytes_with_version( + bytes: Vec, + language: &Language, + ) -> Result { + Ok(Self::new_with_version( + Self::from_bytes(bytes)?.bytes, + language, + )) + } + + /// Same as .from_hex but will consider the script as requiring the specified language version + pub fn from_hex_with_version( + hex_str: &str, + language: &Language, + ) -> Result { + Ok(Self::new_with_version( + Self::from_hex(hex_str)?.bytes, + language, + )) + } + + pub fn hash(&self) -> ScriptHash { + let mut bytes = Vec::with_capacity(self.bytes.len() + 1); + // https://github.com/input-output-hk/cardano-ledger/blob/master/eras/babbage/test-suite/cddl-files/babbage.cddl#L413 + bytes.extend_from_slice(&vec![self.script_namespace() as u8]); + bytes.extend_from_slice(&self.bytes); + ScriptHash::from(blake2b224(bytes.as_ref())) + } + + pub fn language_version(&self) -> Language { + Language(self.language.clone()) + } + + pub(crate) fn script_namespace(&self) -> ScriptHashNamespace { + match self.language { + LanguageKind::PlutusV1 => ScriptHashNamespace::PlutusScript, + LanguageKind::PlutusV2 => ScriptHashNamespace::PlutusScriptV2, + LanguageKind::PlutusV3 => ScriptHashNamespace::PlutusScriptV3, + } + } + + pub(crate) fn clone_as_version(&self, language: &Language) -> PlutusScript { + Self::new_with_version(self.bytes.clone(), language) + } +} + +impl serde::Serialize for PlutusScript { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&hex::encode(&self.bytes)) + } +} + +impl<'de> serde::de::Deserialize<'de> for PlutusScript { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = ::deserialize(deserializer)?; + hex::decode(&s) + .map(|bytes| PlutusScript::new(bytes)) + .map_err(|_err| { + serde::de::Error::invalid_value( + serde::de::Unexpected::Str(&s), + &"PlutusScript as hex string e.g. F8AB28C2 (without CBOR bytes tag)", + ) + }) + } +} + +impl JsonSchema for PlutusScript { + fn schema_name() -> String { + String::from("PlutusScript") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + String::json_schema(gen) + } + fn is_referenceable() -> bool { + String::is_referenceable() + } +} + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct PlutusScripts(pub(crate) Vec); + +impl_to_from!(PlutusScripts); + +#[wasm_bindgen] +impl PlutusScripts { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> PlutusScript { + self.0[index].clone() + } + + pub fn add(&mut self, elem: &PlutusScript) { + self.0.push(elem.clone()); + } + + pub(crate) fn by_version(&self, language: &Language) -> PlutusScripts { + PlutusScripts( + self.0 + .iter() + .filter(|s| s.language_version().eq(language)) + .map(|s| s.clone()) + .collect(), + ) + } + + pub(crate) fn has_version(&self, language: &Language) -> bool { + self.0.iter().any(|s| s.language_version().eq(language)) + } + + pub(crate) fn merge(&self, other: &PlutusScripts) -> PlutusScripts { + let mut res = self.clone(); + for s in &other.0 { + res.add(s); + } + res + } + + pub(crate) fn map_as_version(&self, language: &Language) -> PlutusScripts { + let mut res = PlutusScripts::new(); + for s in &self.0 { + res.add(&s.clone_as_version(language)); + } + res + } +} + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] +pub struct ConstrPlutusData { + pub(crate) alternative: BigNum, + pub(crate) data: PlutusList, +} + +to_from_bytes!(ConstrPlutusData); + +#[wasm_bindgen] +impl ConstrPlutusData { + pub fn alternative(&self) -> BigNum { + self.alternative.clone() + } + + pub fn data(&self) -> PlutusList { + self.data.clone() + } + + pub fn new(alternative: &BigNum, data: &PlutusList) -> Self { + Self { + alternative: alternative.clone(), + data: data.clone(), + } + } +} + +impl ConstrPlutusData { + // see: https://github.com/input-output-hk/plutus/blob/1f31e640e8a258185db01fa899da63f9018c0e85/plutus-core/plutus-core/src/PlutusCore/Data.hs#L61 + // We don't directly serialize the alternative in the tag, instead the scheme is: + // - Alternatives 0-6 -> tags 121-127, followed by the arguments in a list + // - Alternatives 7-127 -> tags 1280-1400, followed by the arguments in a list + // - Any alternatives, including those that don't fit in the above -> tag 102 followed by a list containing + // an unsigned integer for the actual alternative, and then the arguments in a (nested!) list. + pub(crate) const GENERAL_FORM_TAG: u64 = 102; + + // None -> needs general tag serialization, not compact + pub(crate) fn alternative_to_compact_cbor_tag(alt: u64) -> Option { + if alt <= 6 { + Some(121 + alt) + } else if alt >= 7 && alt <= 127 { + Some(1280 - 7 + alt) + } else { + None + } + } + + // None -> General tag(=102) OR Invalid CBOR tag for this scheme + pub(crate) fn compact_cbor_tag_to_alternative(cbor_tag: u64) -> Option { + if cbor_tag >= 121 && cbor_tag <= 127 { + Some(cbor_tag - 121) + } else if cbor_tag >= 1280 && cbor_tag <= 1400 { + Some(cbor_tag - 1280 + 7) + } else { + None + } + } +} + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct CostModel(pub(crate) Vec); + +impl_to_from!(CostModel); + +#[wasm_bindgen] +impl CostModel { + /// Creates a new CostModels instance of an unrestricted length + pub fn new() -> Self { + Self(Vec::new()) + } + + /// Sets the cost at the specified index to the specified value. + /// In case the operation index is larger than the previous largest used index, + /// it will fill any inbetween indexes with zeroes + pub fn set(&mut self, operation: usize, cost: &Int) -> Result { + let len = self.0.len(); + let idx = operation.clone(); + if idx >= len { + for _ in 0..(idx - len + 1) { + self.0.push(Int::new_i32(0)); + } + } + let old = self.0[idx].clone(); + self.0[idx] = cost.clone(); + Ok(old) + } + + pub fn get(&self, operation: usize) -> Result { + let max = self.0.len(); + if operation >= max { + return Err(JsError::from_str(&format!( + "CostModel operation {} out of bounds. Max is {}", + operation, max + ))); + } + Ok(self.0[operation].clone()) + } + + pub fn len(&self) -> usize { + self.0.len() + } +} + +impl From> for CostModel { + fn from(values: Vec) -> Self { + CostModel(values.iter().map(|x| Int(*x)).collect()) + } +} + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct Costmdls(pub(crate) std::collections::BTreeMap); + +impl_to_from!(Costmdls); + +#[wasm_bindgen] +impl Costmdls { + pub fn new() -> Self { + Self(std::collections::BTreeMap::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn insert(&mut self, key: &Language, value: &CostModel) -> Option { + self.0.insert(key.clone(), value.clone()) + } + + pub fn get(&self, key: &Language) -> Option { + self.0.get(key).map(|v| v.clone()) + } + + pub fn keys(&self) -> Languages { + Languages(self.0.iter().map(|(k, _v)| k.clone()).collect::>()) + } + + pub(crate) fn language_views_encoding(&self) -> Vec { + let mut serializer = Serializer::new_vec(); + fn key_len(l: &Language) -> usize { + if l.kind() == LanguageKind::PlutusV1 { + let mut serializer = Serializer::new_vec(); + serializer.write_bytes(l.to_bytes()).unwrap(); + return serializer.finalize().len(); + } + l.to_bytes().len() + } + let mut keys: Vec = self.0.iter().map(|(k, _v)| k.clone()).collect(); + // keys must be in canonical ordering first + keys.sort_by(|lhs, rhs| match key_len(lhs).cmp(&key_len(rhs)) { + std::cmp::Ordering::Equal => lhs.cmp(&rhs), + len_order => len_order, + }); + serializer + .write_map(cbor_event::Len::Len(self.0.len() as u64)) + .unwrap(); + for key in keys.iter() { + if key.kind() == LanguageKind::PlutusV1 { + serializer.write_bytes(key.to_bytes()).unwrap(); + let cost_model = self.0.get(&key).unwrap(); + // Due to a bug in the cardano-node input-output-hk/cardano-ledger-specs/issues/2512 + // we must use indefinite length serialization in this inner bytestring to match it + let mut cost_model_serializer = Serializer::new_vec(); + cost_model_serializer + .write_array(cbor_event::Len::Indefinite) + .unwrap(); + for cost in &cost_model.0 { + cost.serialize(&mut cost_model_serializer).unwrap(); + } + cost_model_serializer + .write_special(cbor_event::Special::Break) + .unwrap(); + serializer + .write_bytes(cost_model_serializer.finalize()) + .unwrap(); + } else { + serializer.serialize(key).unwrap(); + serializer.serialize(self.0.get(&key).unwrap()).unwrap(); + } + } + serializer.finalize() + } + + pub fn retain_language_versions(&self, languages: &Languages) -> Costmdls { + let mut result = Costmdls::new(); + for lang in &languages.0 { + match self.get(&lang) { + Some(costmodel) => { + result.insert(&lang, &costmodel); + } + _ => {} + } + } + result + } +} + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct ExUnitPrices { + pub(crate) mem_price: SubCoin, + pub(crate) step_price: SubCoin, +} + +impl_to_from!(ExUnitPrices); + +#[wasm_bindgen] +impl ExUnitPrices { + pub fn mem_price(&self) -> SubCoin { + self.mem_price.clone() + } + + pub fn step_price(&self) -> SubCoin { + self.step_price.clone() + } + + pub fn new(mem_price: &SubCoin, step_price: &SubCoin) -> Self { + Self { + mem_price: mem_price.clone(), + step_price: step_price.clone(), + } + } +} + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct ExUnits { + pub(crate) mem: BigNum, + pub(crate) steps: BigNum, +} + +impl_to_from!(ExUnits); + +#[wasm_bindgen] +impl ExUnits { + pub fn mem(&self) -> BigNum { + self.mem.clone() + } + + pub fn steps(&self) -> BigNum { + self.steps.clone() + } + + pub fn new(mem: &BigNum, steps: &BigNum) -> Self { + Self { + mem: mem.clone(), + steps: steps.clone(), + } + } +} + +#[wasm_bindgen] +#[derive( + Clone, + Copy, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub enum LanguageKind { + PlutusV1 = 0, + PlutusV2 = 1, + PlutusV3 = 2, +} + +impl LanguageKind { + pub(crate) fn from_u64(x: u64) -> Option { + match x { + 0 => Some(LanguageKind::PlutusV1), + 1 => Some(LanguageKind::PlutusV2), + 2 => Some(LanguageKind::PlutusV3), + _ => None, + } + } +} + +#[wasm_bindgen] +#[derive( + Clone, + Copy, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct Language(pub(crate) LanguageKind); + +impl_to_from!(Language); + +#[wasm_bindgen] +impl Language { + pub fn new_plutus_v1() -> Self { + Self(LanguageKind::PlutusV1) + } + + pub fn new_plutus_v2() -> Self { + Self(LanguageKind::PlutusV2) + } + + pub fn new_plutus_v3() -> Self { + Self(LanguageKind::PlutusV3) + } + + pub fn kind(&self) -> LanguageKind { + self.0.clone() + } +} + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct Languages(pub(crate) Vec); + +#[wasm_bindgen] +impl Languages { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> Language { + self.0[index] + } + + pub fn add(&mut self, elem: Language) { + self.0.push(elem); + } + + pub fn list() -> Languages { + Languages(vec![Language::new_plutus_v1(), Language::new_plutus_v2()]) + } +} + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] +pub struct PlutusMap(pub(crate) LinkedHashMap); + +to_from_bytes!(PlutusMap); + +#[wasm_bindgen] +impl PlutusMap { + pub fn new() -> Self { + Self(LinkedHashMap::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn insert(&mut self, key: &PlutusData, value: &PlutusData) -> Option { + self.0.insert(key.clone(), value.clone()) + } + + pub fn get(&self, key: &PlutusData) -> Option { + self.0.get(key).map(|v| v.clone()) + } + + pub fn keys(&self) -> PlutusList { + PlutusList { + elems: self.0.iter().map(|(k, _v)| k.clone()).collect::>(), + definite_encoding: None, + } + } +} + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub enum PlutusDataKind { + ConstrPlutusData, + Map, + List, + Integer, + Bytes, +} + +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] +pub enum PlutusDataEnum { + ConstrPlutusData(ConstrPlutusData), + Map(PlutusMap), + List(PlutusList), + Integer(BigInt), + Bytes(Vec), +} + +#[wasm_bindgen] +#[derive(Clone, Debug, Ord, PartialOrd)] +pub struct PlutusData { + pub(crate) datum: PlutusDataEnum, + // We should always preserve the original datums when deserialized as this is NOT canonicized + // before computing datum hashes. So this field stores the original bytes to re-use. + pub(crate) original_bytes: Option>, +} + +impl std::cmp::PartialEq for PlutusData { + fn eq(&self, other: &Self) -> bool { + self.datum.eq(&other.datum) + } +} + +impl Hash for PlutusData { + fn hash(&self, state: &mut H) { + self.datum.hash(state) + } +} + +impl std::cmp::Eq for PlutusData {} + +to_from_bytes!(PlutusData); + +#[wasm_bindgen] +impl PlutusData { + pub fn new_constr_plutus_data(constr_plutus_data: &ConstrPlutusData) -> Self { + Self { + datum: PlutusDataEnum::ConstrPlutusData(constr_plutus_data.clone()), + original_bytes: None, + } + } + + /// Same as `.new_constr_plutus_data` but creates constr with empty data list + pub fn new_empty_constr_plutus_data(alternative: &BigNum) -> Self { + Self::new_constr_plutus_data(&ConstrPlutusData::new(alternative, &PlutusList::new())) + } + + pub fn new_single_value_constr_plutus_data( + alternative: &BigNum, + plutus_data: &PlutusData, + ) -> Self { + let mut list = PlutusList::new(); + list.add(plutus_data); + Self::new_constr_plutus_data(&ConstrPlutusData::new(alternative, &list)) + } + + pub fn new_map(map: &PlutusMap) -> Self { + Self { + datum: PlutusDataEnum::Map(map.clone()), + original_bytes: None, + } + } + + pub fn new_list(list: &PlutusList) -> Self { + Self { + datum: PlutusDataEnum::List(list.clone()), + original_bytes: None, + } + } + + pub fn new_integer(integer: &BigInt) -> Self { + Self { + datum: PlutusDataEnum::Integer(integer.clone()), + original_bytes: None, + } + } + + pub fn new_bytes(bytes: Vec) -> Self { + Self { + datum: PlutusDataEnum::Bytes(bytes), + original_bytes: None, + } + } + + pub fn kind(&self) -> PlutusDataKind { + match &self.datum { + PlutusDataEnum::ConstrPlutusData(_) => PlutusDataKind::ConstrPlutusData, + PlutusDataEnum::Map(_) => PlutusDataKind::Map, + PlutusDataEnum::List(_) => PlutusDataKind::List, + PlutusDataEnum::Integer(_) => PlutusDataKind::Integer, + PlutusDataEnum::Bytes(_) => PlutusDataKind::Bytes, + } + } + + pub fn as_constr_plutus_data(&self) -> Option { + match &self.datum { + PlutusDataEnum::ConstrPlutusData(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_map(&self) -> Option { + match &self.datum { + PlutusDataEnum::Map(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_list(&self) -> Option { + match &self.datum { + PlutusDataEnum::List(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_integer(&self) -> Option { + match &self.datum { + PlutusDataEnum::Integer(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_bytes(&self) -> Option> { + match &self.datum { + PlutusDataEnum::Bytes(x) => Some(x.clone()), + _ => None, + } + } + + pub fn to_json(&self, schema: PlutusDatumSchema) -> Result { + decode_plutus_datum_to_json_str(self, schema) + } + + pub fn from_json(json: &str, schema: PlutusDatumSchema) -> Result { + encode_json_str_to_plutus_datum(json, schema) + } + + pub fn from_address(address: &Address) -> Result { + let payment_cred = match &address.0 { + AddrType::Base(addr) => Ok(addr.payment_cred()), + AddrType::Enterprise(addr) => Ok(addr.payment_cred()), + AddrType::Ptr(addr) => Ok(addr.payment_cred()), + AddrType::Reward(addr) => Ok(addr.payment_cred()), + AddrType::Byron(_) => Err(JsError::from_str( + "Cannot convert Byron address to PlutusData", + )), + }?; + + let staking_data = match &address.0 { + AddrType::Base(addr) => { + let staking_bytes_data = PlutusData::from_stake_credential(&addr.stake_cred())?; + Some(PlutusData::new_single_value_constr_plutus_data( + &BigNum::from(0u32), + &staking_bytes_data, + )) + } + _ => None, + }; + + let pointer_data = match &address.0 { + AddrType::Ptr(addr) => Some(PlutusData::from_pointer(&addr.stake_pointer())?), + _ => None, + }; + + let payment_data = PlutusData::from_stake_credential(&payment_cred)?; + let staking_optional_data = match (staking_data, pointer_data) { + (Some(_), Some(_)) => Err(JsError::from_str( + "Address can't have both staking and pointer data", + )), + (Some(staking_data), None) => Ok(Some(staking_data)), + (None, Some(pointer_data)) => Ok(Some(pointer_data)), + (None, None) => Ok(None), + }?; + + let mut data_list = PlutusList::new(); + data_list.add(&payment_data); + if let Some(staking_optional_data) = staking_optional_data { + data_list.add(&PlutusData::new_single_value_constr_plutus_data( + &BigNum::from(0u32), + &staking_optional_data, + )); + } else { + data_list.add(&PlutusData::new_empty_constr_plutus_data(&BigNum::from( + 1u32, + ))); + } + + Ok(PlutusData::new_constr_plutus_data(&ConstrPlutusData::new( + &BigNum::from(0u32), + &data_list, + ))) + } + + fn from_stake_credential(stake_credential: &Credential) -> Result { + let (bytes_plutus_data, index) = match &stake_credential.0 { + StakeCredType::Key(key_hash) => ( + PlutusData::new_bytes(key_hash.to_bytes().to_vec()), + BigNum::from(0u32), + ), + StakeCredType::Script(script_hash) => ( + PlutusData::new_bytes(script_hash.to_bytes().to_vec()), + BigNum::from(1u32), + ), + }; + + Ok(PlutusData::new_single_value_constr_plutus_data( + &index, + &bytes_plutus_data, + )) + } + + fn from_pointer(pointer: &Pointer) -> Result { + let mut data_list = PlutusList::new(); + data_list.add(&PlutusData::new_integer(&pointer.slot_bignum().into())); + data_list.add(&PlutusData::new_integer(&pointer.tx_index_bignum().into())); + data_list.add(&PlutusData::new_integer( + &pointer.cert_index_bignum().into(), + )); + + Ok(PlutusData::new_constr_plutus_data(&ConstrPlutusData::new( + &BigNum::from(1u32), + &data_list, + ))) + } +} + +//TODO: replace this by cardano-node schemas +impl JsonSchema for PlutusData { + fn is_referenceable() -> bool { + String::is_referenceable() + } + + fn schema_name() -> String { + String::from("PlutusData") + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + String::json_schema(gen) + } +} + +//TODO: need to figure out what schema to use here +impl serde::Serialize for PlutusData { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let json = decode_plutus_datum_to_json_str(self, PlutusDatumSchema::DetailedSchema) + .map_err(|ser_err| { + serde::ser::Error::custom(&format!("Serialization error: {:?}", ser_err)) + })?; + serializer.serialize_str(&json) + } +} + +impl<'de> serde::de::Deserialize<'de> for PlutusData { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let datum_json = ::deserialize(deserializer)?; + encode_json_str_to_plutus_datum(&datum_json, PlutusDatumSchema::DetailedSchema).map_err( + |ser_err| serde::de::Error::custom(&format!("Deserialization error: {:?}", ser_err)), + ) + } +} + +#[wasm_bindgen] +#[derive(Clone, Debug, Ord, PartialOrd, Hash, serde::Serialize, serde::Deserialize, JsonSchema)] +pub struct PlutusList { + pub(crate) elems: Vec, + // We should always preserve the original datums when deserialized as this is NOT canonicized + // before computing datum hashes. This field will default to cardano-cli behavior if None + // and will re-use the provided one if deserialized, unless the list is modified. + pub(crate) definite_encoding: Option, +} + +impl<'a> IntoIterator for &'a PlutusList { + type Item = &'a PlutusData; + type IntoIter = std::slice::Iter<'a, PlutusData>; + + fn into_iter(self) -> std::slice::Iter<'a, PlutusData> { + self.elems.iter() + } +} + +impl std::cmp::PartialEq for PlutusList { + fn eq(&self, other: &Self) -> bool { + self.elems.eq(&other.elems) + } +} + +impl std::cmp::Eq for PlutusList {} + +to_from_bytes!(PlutusList); + +#[wasm_bindgen] +impl PlutusList { + pub fn new() -> Self { + Self { + elems: Vec::new(), + definite_encoding: None, + } + } + + pub fn len(&self) -> usize { + self.elems.len() + } + + pub fn get(&self, index: usize) -> PlutusData { + self.elems[index].clone() + } + + pub fn add(&mut self, elem: &PlutusData) { + self.elems.push(elem.clone()); + self.definite_encoding = None; + } +} + +impl From> for PlutusList { + fn from(elems: Vec) -> Self { + Self { + elems, + definite_encoding: None, + } + } +} + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct Redeemer { + pub(crate) tag: RedeemerTag, + pub(crate) index: BigNum, + pub(crate) data: PlutusData, + pub(crate) ex_units: ExUnits, +} + +impl_to_from!(Redeemer); + +#[wasm_bindgen] +impl Redeemer { + pub fn tag(&self) -> RedeemerTag { + self.tag.clone() + } + + pub fn index(&self) -> BigNum { + self.index.clone() + } + + pub fn data(&self) -> PlutusData { + self.data.clone() + } + + pub fn ex_units(&self) -> ExUnits { + self.ex_units.clone() + } + + pub fn new(tag: &RedeemerTag, index: &BigNum, data: &PlutusData, ex_units: &ExUnits) -> Self { + Self { + tag: tag.clone(), + index: index.clone(), + data: data.clone(), + ex_units: ex_units.clone(), + } + } + + #[allow(dead_code)] + pub(crate) fn clone_with_index(&self, index: &BigNum) -> Self { + Self { + tag: self.tag.clone(), + index: index.clone(), + data: self.data.clone(), + ex_units: self.ex_units.clone(), + } + } + + pub(crate) fn clone_with_index_and_tag(&self, index: &BigNum, tag: &RedeemerTag) -> Self { + Self { + tag: tag.clone(), + index: index.clone(), + data: self.data.clone(), + ex_units: self.ex_units.clone(), + } + } +} + +#[wasm_bindgen] +#[derive( + Copy, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub enum RedeemerTagKind { + Spend, + Mint, + Cert, + Reward, + Vote, + VotingProposal, +} + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct RedeemerTag(pub(crate) RedeemerTagKind); + +impl_to_from!(RedeemerTag); + +#[wasm_bindgen] +impl RedeemerTag { + pub fn new_spend() -> Self { + Self(RedeemerTagKind::Spend) + } + + pub fn new_mint() -> Self { + Self(RedeemerTagKind::Mint) + } + + pub fn new_cert() -> Self { + Self(RedeemerTagKind::Cert) + } + + pub fn new_reward() -> Self { + Self(RedeemerTagKind::Reward) + } + + pub fn new_vote() -> Self { + Self(RedeemerTagKind::Vote) + } + + pub fn new_voting_proposal() -> Self { + Self(RedeemerTagKind::VotingProposal) + } + + pub fn kind(&self) -> RedeemerTagKind { + self.0 + } +} + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct Redeemers(pub(crate) Vec); + +impl_to_from!(Redeemers); + +#[wasm_bindgen] +impl Redeemers { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> Redeemer { + self.0[index].clone() + } + + pub fn add(&mut self, elem: &Redeemer) { + self.0.push(elem.clone()); + } + + pub fn total_ex_units(&self) -> Result { + let mut tot_mem = BigNum::zero(); + let mut tot_steps = BigNum::zero(); + for i in 0..self.0.len() { + let r: &Redeemer = &self.0[i]; + tot_mem = tot_mem.checked_add(&r.ex_units().mem())?; + tot_steps = tot_steps.checked_add(&r.ex_units().steps())?; + } + Ok(ExUnits::new(&tot_mem, &tot_steps)) + } +} + +impl From> for Redeemers { + fn from(values: Vec) -> Self { + Self(values) + } +} + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub struct Strings(pub(crate) Vec); + +#[wasm_bindgen] +impl Strings { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> String { + self.0[index].clone() + } + + pub fn add(&mut self, elem: String) { + self.0.push(elem); + } +} + +// json + +/// JSON <-> PlutusData conversion schemas. +/// Follows ScriptDataJsonSchema in cardano-cli defined at: +/// https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 +/// +/// All methods here have the following restrictions due to limitations on dependencies: +/// * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors +/// * Hex strings for bytes don't accept odd-length (half-byte) strings. +/// cardano-cli seems to support these however but it seems to be different than just 0-padding +/// on either side when tested so proceed with caution +#[wasm_bindgen] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum PlutusDatumSchema { + /// ScriptDataJsonNoSchema in cardano-node. + /// + /// This is the format used by --script-data-value in cardano-cli + /// This tries to accept most JSON but does not support the full spectrum of Plutus datums. + /// From JSON: + /// * null/true/false/floats NOT supported + /// * strings starting with 0x are treated as hex bytes. All other strings are encoded as their utf8 bytes. + /// To JSON: + /// * ConstrPlutusData not supported in ANY FORM (neither keys nor values) + /// * Lists not supported in keys + /// * Maps not supported in keys + //// + BasicConversions, + /// ScriptDataJsonDetailedSchema in cardano-node. + /// + /// This is the format used by --script-data-file in cardano-cli + /// This covers almost all (only minor exceptions) Plutus datums, but the JSON must conform to a strict schema. + /// The schema specifies that ALL keys and ALL values must be contained in a JSON map with 2 cases: + /// 1. For ConstrPlutusData there must be two fields "constructor" contianing a number and "fields" containing its fields + /// e.g. { "constructor": 2, "fields": [{"int": 2}, {"list": [{"bytes": "CAFEF00D"}]}]} + /// 2. For all other cases there must be only one field named "int", "bytes", "list" or "map" + /// Integer's value is a JSON number e.g. {"int": 100} + /// Bytes' value is a hex string representing the bytes WITHOUT any prefix e.g. {"bytes": "CAFEF00D"} + /// Lists' value is a JSON list of its elements encoded via the same schema e.g. {"list": [{"bytes": "CAFEF00D"}]} + /// Maps' value is a JSON list of objects, one for each key-value pair in the map, with keys "k" and "v" + /// respectively with their values being the plutus datum encoded via this same schema + /// e.g. {"map": [ + /// {"k": {"int": 2}, "v": {"int": 5}}, + /// {"k": {"map": [{"k": {"list": [{"int": 1}]}, "v": {"bytes": "FF03"}}]}, "v": {"list": []}} + /// ]} + /// From JSON: + /// * null/true/false/floats NOT supported + /// * the JSON must conform to a very specific schema + /// To JSON: + /// * all Plutus datums should be fully supported outside of the integer range limitations outlined above. + //// + DetailedSchema, +} + +#[wasm_bindgen] +pub fn encode_json_str_to_plutus_datum( + json: &str, + schema: PlutusDatumSchema, +) -> Result { + let value = serde_json::from_str(json).map_err(|e| JsError::from_str(&e.to_string()))?; + encode_json_value_to_plutus_datum(value, schema) +} + +pub fn encode_json_value_to_plutus_datum( + value: serde_json::Value, + schema: PlutusDatumSchema, +) -> Result { + use serde_json::Value; + fn encode_number(x: serde_json::Number) -> Result { + if let Some(x) = x.as_u64() { + Ok(PlutusData::new_integer(&BigInt::from(x))) + } else if let Some(x) = x.as_i64() { + Ok(PlutusData::new_integer(&BigInt::from(x))) + } else { + Err(JsError::from_str("floats not allowed in plutus datums")) + } + } + fn encode_string( + s: &str, + schema: PlutusDatumSchema, + is_key: bool, + ) -> Result { + if schema == PlutusDatumSchema::BasicConversions { + if s.starts_with("0x") { + // this must be a valid hex bytestring after + hex::decode(&s[2..]) + .map(|bytes| PlutusData::new_bytes(bytes)) + .map_err(|err| JsError::from_str(&format!("Error decoding {}: {}", s, err))) + } else if is_key { + // try as an integer + BigInt::from_str(s) + .map(|x| PlutusData::new_integer(&x)) + // if not, we use the utf8 bytes of the string instead directly + .or_else(|_err| Ok(PlutusData::new_bytes(s.as_bytes().to_vec()))) + } else { + // can only be UTF bytes if not in a key and not prefixed by 0x + Ok(PlutusData::new_bytes(s.as_bytes().to_vec())) + } + } else { + if s.starts_with("0x") { + Err(JsError::from_str("Hex byte strings in detailed schema should NOT start with 0x and should just contain the hex characters")) + } else { + hex::decode(s) + .map(|bytes| PlutusData::new_bytes(bytes)) + .map_err(|e| JsError::from_str(&e.to_string())) + } + } + } + fn encode_array( + json_arr: Vec, + schema: PlutusDatumSchema, + ) -> Result { + let mut arr = PlutusList::new(); + for value in json_arr { + arr.add(&encode_json_value_to_plutus_datum(value, schema)?); + } + Ok(PlutusData::new_list(&arr)) + } + match schema { + PlutusDatumSchema::BasicConversions => match value { + Value::Null => Err(JsError::from_str("null not allowed in plutus datums")), + Value::Bool(_) => Err(JsError::from_str("bools not allowed in plutus datums")), + Value::Number(x) => encode_number(x), + // no strings in plutus so it's all bytes (as hex or utf8 printable) + Value::String(s) => encode_string(&s, schema, false), + Value::Array(json_arr) => encode_array(json_arr, schema), + Value::Object(json_obj) => { + let mut map = PlutusMap::new(); + for (raw_key, raw_value) in json_obj { + let key = encode_string(&raw_key, schema, true)?; + let value = encode_json_value_to_plutus_datum(raw_value, schema)?; + map.insert(&key, &value); + } + Ok(PlutusData::new_map(&map)) + } + }, + PlutusDatumSchema::DetailedSchema => match value { + Value::Object(obj) => { + if obj.len() == 1 { + // all variants except tagged constructors + let (k, v) = obj.into_iter().next().unwrap(); + fn tag_mismatch() -> JsError { + JsError::from_str("key does not match type") + } + match k.as_str() { + "int" => match v { + Value::Number(x) => encode_number(x), + _ => Err(tag_mismatch()), + }, + "bytes" => { + encode_string(v.as_str().ok_or_else(tag_mismatch)?, schema, false) + } + "list" => { + encode_array(v.as_array().ok_or_else(tag_mismatch)?.clone(), schema) + } + "map" => { + let mut map = PlutusMap::new(); + fn map_entry_err() -> JsError { + JsError::from_str("entry format in detailed schema map object not correct. Needs to be of form {\"k\": {\"key_type\": key}, \"v\": {\"value_type\", value}}") + } + for entry in v.as_array().ok_or_else(tag_mismatch)? { + let entry_obj = entry.as_object().ok_or_else(map_entry_err)?; + let raw_key = entry_obj.get("k").ok_or_else(map_entry_err)?; + let value = entry_obj.get("v").ok_or_else(map_entry_err)?; + let key = + encode_json_value_to_plutus_datum(raw_key.clone(), schema)?; + map.insert( + &key, + &encode_json_value_to_plutus_datum(value.clone(), schema)?, + ); + } + Ok(PlutusData::new_map(&map)) + } + invalid_key => Err(JsError::from_str(&format!( + "key '{}' in tagged object not valid", + invalid_key + ))), + } + } else { + // constructor with tagged variant + if obj.len() != 2 { + return Err(JsError::from_str("detailed schemas must either have only one of the following keys: \"int\", \"bytes\", \"list\" or \"map\", or both of these 2 keys: \"constructor\" + \"fields\"")); + } + let variant: BigNum = obj + .get("constructor") + .and_then(|v| Some(to_bignum(v.as_u64()?))) + .ok_or_else(|| JsError::from_str("tagged constructors must contain an unsigned integer called \"constructor\""))?; + let fields_json = + obj.get("fields") + .and_then(|f| f.as_array()) + .ok_or_else(|| { + JsError::from_str( + "tagged constructors must contian a list called \"fields\"", + ) + })?; + let mut fields = PlutusList::new(); + for field_json in fields_json { + let field = encode_json_value_to_plutus_datum(field_json.clone(), schema)?; + fields.add(&field); + } + Ok(PlutusData::new_constr_plutus_data(&ConstrPlutusData::new( + &variant, &fields, + ))) + } + } + _ => Err(JsError::from_str(&format!( + "DetailedSchema requires ALL JSON to be tagged objects, found: {}", + value + ))), + }, + } +} + +//TODO: move it to serialize impl +#[wasm_bindgen] +pub fn decode_plutus_datum_to_json_str( + datum: &PlutusData, + schema: PlutusDatumSchema, +) -> Result { + let value = decode_plutus_datum_to_json_value(datum, schema)?; + serde_json::to_string(&value).map_err(|e| JsError::from_str(&e.to_string())) +} + +//TODO: move it to deserialize impl +pub fn decode_plutus_datum_to_json_value( + datum: &PlutusData, + schema: PlutusDatumSchema, +) -> Result { + use serde_json::Value; + let (type_tag, json_value) = match &datum.datum { + PlutusDataEnum::ConstrPlutusData(constr) => { + let mut obj = serde_json::map::Map::with_capacity(2); + obj.insert( + String::from("constructor"), + Value::from(from_bignum(&constr.alternative)) + ); + let mut fields = Vec::new(); + for field in constr.data.elems.iter() { + fields.push(decode_plutus_datum_to_json_value(field, schema)?); + } + obj.insert( + String::from("fields"), + Value::from(fields) + ); + (None, Value::from(obj)) + }, + PlutusDataEnum::Map(map) => match schema { + PlutusDatumSchema::BasicConversions => (None, Value::from(map.0.iter().map(|(key, value)| { + let json_key: String = match &key.datum { + PlutusDataEnum::ConstrPlutusData(_) => Err(JsError::from_str("plutus data constructors are not allowed as keys in this schema. Use DetailedSchema.")), + PlutusDataEnum::Map(_) => Err(JsError::from_str("plutus maps are not allowed as keys in this schema. Use DetailedSchema.")), + PlutusDataEnum::List(_) => Err(JsError::from_str("plutus lists are not allowed as keys in this schema. Use DetailedSchema.")), + PlutusDataEnum::Integer(x) => Ok(x.to_str()), + PlutusDataEnum::Bytes(bytes) => String::from_utf8(bytes.clone()).or_else(|_err| Ok(format!("0x{}", hex::encode(bytes)))) + }?; + let json_value = decode_plutus_datum_to_json_value(value, schema)?; + Ok((json_key, Value::from(json_value))) + }).collect::, JsError>>()?)), + PlutusDatumSchema::DetailedSchema => (Some("map"), Value::from(map.0.iter().map(|(key, value)| { + let k = decode_plutus_datum_to_json_value(key, schema)?; + let v = decode_plutus_datum_to_json_value(value, schema)?; + let mut kv_obj = serde_json::map::Map::with_capacity(2); + kv_obj.insert(String::from("k"), k); + kv_obj.insert(String::from("v"), v); + Ok(Value::from(kv_obj)) + }).collect::, JsError>>()?)), + }, + PlutusDataEnum::List(list) => { + let mut elems = Vec::new(); + for elem in list.elems.iter() { + elems.push(decode_plutus_datum_to_json_value(elem, schema)?); + } + (Some("list"), Value::from(elems)) + }, + PlutusDataEnum::Integer(bigint) => ( + Some("int"), + bigint + .as_int() + .as_ref() + .map(|int| if int.0 >= 0 { Value::from(int.0 as u64) } else { Value::from(int.0 as i64) }) + .ok_or_else(|| JsError::from_str(&format!("Integer {} too big for our JSON support", bigint.to_str())))? + ), + PlutusDataEnum::Bytes(bytes) => (Some("bytes"), Value::from(match schema { + PlutusDatumSchema::BasicConversions => { + // cardano-cli converts to a string only if bytes are utf8 and all characters are printable + String::from_utf8(bytes.clone()) + .ok() + .filter(|utf8| utf8.chars().all(|c| !c.is_control())) + // otherwise we hex-encode the bytes with a 0x prefix + .unwrap_or_else(|| format!("0x{}", hex::encode(bytes))) + }, + PlutusDatumSchema::DetailedSchema => hex::encode(bytes), + })), + }; + if type_tag.is_none() || schema != PlutusDatumSchema::DetailedSchema { + Ok(json_value) + } else { + let mut wrapper = serde_json::map::Map::with_capacity(1); + wrapper.insert(String::from(type_tag.unwrap()), json_value); + Ok(Value::from(wrapper)) + } +} \ No newline at end of file diff --git a/rust/src/serialization/general.rs b/rust/src/serialization/general.rs index 493c05ee..3bd4094c 100644 --- a/rust/src/serialization/general.rs +++ b/rust/src/serialization/general.rs @@ -1,5 +1,6 @@ use crate::*; use std::io::{Seek, SeekFrom}; +use crate::serialization::utils::merge_option_plutus_list; // This file was code-generated using an experimental CDDL to rust tool: // https://github.com/Emurgo/cddl-codegen @@ -1029,6 +1030,9 @@ impl Deserialize for ScriptRefEnum { 2 => ScriptRefEnum::PlutusScript( PlutusScript::deserialize(raw)?.clone_as_version(&Language::new_plutus_v2()), ), + 3 => ScriptRefEnum::PlutusScript( + PlutusScript::deserialize(raw)?.clone_as_version(&Language::new_plutus_v3()), + ), n => { return Err(DeserializeFailure::FixedValueMismatch { found: Key::Uint(n), @@ -1751,8 +1755,14 @@ impl cbor_event::se::Serialize for TransactionWitnessSet { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { + let mut has_plutus_v2 = false; + let mut has_plutus_v3 = false; let plutus_added_length = match &self.plutus_scripts { - Some(scripts) => 1 + (scripts.has_version(&Language::new_plutus_v2()) as u64), + Some(scripts) => { + has_plutus_v2 = scripts.has_version(&Language::new_plutus_v2()); + has_plutus_v3 = scripts.has_version(&Language::new_plutus_v3()); + 1 + (has_plutus_v2 as u64) + (has_plutus_v3 as u64) + }, _ => 0, }; serializer.write_map(cbor_event::Len::Len( @@ -1780,12 +1790,18 @@ impl cbor_event::se::Serialize for TransactionWitnessSet { plutus_scripts .by_version(&Language::new_plutus_v1()) .serialize(serializer)?; - if plutus_added_length > 1 { + if has_plutus_v2 { serializer.write_unsigned_integer(6)?; plutus_scripts .by_version(&Language::new_plutus_v2()) .serialize(serializer)?; } + if has_plutus_v3 { + serializer.write_unsigned_integer(7)?; + plutus_scripts + .by_version(&Language::new_plutus_v3()) + .serialize(serializer)?; + } } if let Some(field) = &self.plutus_data { serializer.write_unsigned_integer(4)?; @@ -1809,6 +1825,7 @@ impl Deserialize for TransactionWitnessSet { let mut bootstraps = None; let mut plutus_scripts_v1 = None; let mut plutus_scripts_v2 = None; + let mut plutus_scripts_v3 = None; let mut plutus_data = None; let mut redeemers = None; let mut read = 0; @@ -1903,6 +1920,19 @@ impl Deserialize for TransactionWitnessSet { .map_err(|e| e.annotate("plutus_scripts_v2"))?, ); } + 7 => { + if plutus_scripts_v3.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(7)).into()); + } + plutus_scripts_v3 = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(PlutusScripts::deserialize(raw)? + .map_as_version(&Language::new_plutus_v3())) + })() + .map_err(|e| e.annotate("plutus_scripts_v3"))?, + ); + } unknown_key => { return Err( DeserializeFailure::UnknownKey(Key::Uint(unknown_key)).into() @@ -1933,12 +1963,11 @@ impl Deserialize for TransactionWitnessSet { read += 1; } read_len.finish()?; - let plutus_scripts = match (plutus_scripts_v1, plutus_scripts_v2) { - (Some(v1), Some(v2)) => Some(v1.merge(&v2)), - (Some(v1), _) => Some(v1), - (_, Some(v2)) => Some(v2), - _ => None, - }; + let mut plutus_scripts = None; + plutus_scripts = merge_option_plutus_list(plutus_scripts, plutus_scripts_v1); + plutus_scripts = merge_option_plutus_list(plutus_scripts, plutus_scripts_v2); + plutus_scripts = merge_option_plutus_list(plutus_scripts, plutus_scripts_v3); + Ok(Self { vkeys, native_scripts, @@ -4539,11 +4568,14 @@ mod tests { let bytes = hex::decode("4e4d01000033222220051200120011").unwrap(); let script_v1 = PlutusScript::from_bytes(bytes.clone()).unwrap(); let script_v2 = PlutusScript::from_bytes_v2(bytes.clone()).unwrap(); + let script_v3 = PlutusScript::from_bytes_v3(bytes.clone()).unwrap(); witness_set_roundtrip(&PlutusScripts(vec![])); witness_set_roundtrip(&PlutusScripts(vec![script_v1.clone()])); witness_set_roundtrip(&PlutusScripts(vec![script_v2.clone()])); + witness_set_roundtrip(&PlutusScripts(vec![script_v3.clone()])); witness_set_roundtrip(&PlutusScripts(vec![script_v1.clone(), script_v2.clone()])); + witness_set_roundtrip(&PlutusScripts(vec![script_v1.clone(), script_v2.clone(), script_v3.clone()])); } #[test] @@ -4556,12 +4588,16 @@ mod tests { let bytes = hex::decode("4e4d01000033222220051200120011").unwrap(); let script_v1 = PlutusScript::from_bytes(bytes.clone()).unwrap(); let script_v2 = PlutusScript::from_bytes_v2(bytes.clone()).unwrap(); + let script_v3 = PlutusScript::from_bytes_v3(bytes.clone()).unwrap(); let ref1 = ScriptRef::new_plutus_script(&script_v1); assert_eq!(ScriptRef::from_bytes(ref1.to_bytes()).unwrap(), ref1); let ref2 = ScriptRef::new_plutus_script(&script_v2); assert_eq!(ScriptRef::from_bytes(ref2.to_bytes()).unwrap(), ref2); + + let ref3 = ScriptRef::new_plutus_script(&script_v3); + assert_eq!(ScriptRef::from_bytes(ref3.to_bytes()).unwrap(), ref3); } #[test] @@ -4589,6 +4625,7 @@ mod tests { let bytes = hex::decode("4e4d01000033222220051200120011").unwrap(); let script_v1 = PlutusScript::from_bytes(bytes.clone()).unwrap(); let script_v2 = PlutusScript::from_bytes_v2(bytes.clone()).unwrap(); + let script_v3 = PlutusScript::from_bytes_v3(bytes.clone()).unwrap(); let mut o3 = TransactionOutput::new(&fake_base_address(2), &fake_value2(234569)); o3.set_script_ref(&ScriptRef::new_plutus_script(&script_v1)); @@ -4607,6 +4644,10 @@ mod tests { o6.set_data_hash(&fake_data_hash(222)); o6.set_script_ref(&ScriptRef::new_plutus_script(&script_v2)); assert_eq!(TransactionOutput::from_bytes(o6.to_bytes()).unwrap(), o6); + + let mut o7 = TransactionOutput::new(&fake_base_address(6), &fake_value2(234573)); + o7.set_script_ref(&ScriptRef::new_plutus_script(&script_v3)); + assert_eq!(TransactionOutput::from_bytes(o7.to_bytes()).unwrap(), o7); } #[test] diff --git a/rust/src/serialization/metadata.rs b/rust/src/serialization/metadata.rs new file mode 100644 index 00000000..97ca0011 --- /dev/null +++ b/rust/src/serialization/metadata.rs @@ -0,0 +1,469 @@ +use linked_hash_map::LinkedHashMap; +use crate::*; +use crate::serialization::utils::merge_option_plutus_list; + +impl cbor_event::se::Serialize for MetadataMap { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?; + for (key, value) in &self.0 { + key.serialize(serializer)?; + value.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for MetadataMap { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut table = LinkedHashMap::new(); + let mut entries: Vec<(TransactionMetadatum, TransactionMetadatum)> = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.map()?; + while match len { + cbor_event::Len::Len(n) => entries.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + let key = TransactionMetadatum::deserialize(raw)?; + let value = TransactionMetadatum::deserialize(raw)?; + entries.push((key.clone(), value)); + } + Ok(()) + })() + .map_err(|e| e.annotate("MetadataMap"))?; + entries.iter().for_each(|(k, v)| { + if table.insert(k.clone(), v.clone()).is_some() { + // Turns out this is totally possible on the actual blockchain + // return Err(DeserializeFailure::DuplicateKey(Key::Str(String::from("some complicated/unsupported type"))).into()); + } + }); + Ok(Self(table)) + } +} + +impl cbor_event::se::Serialize for MetadataList { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for MetadataList { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(TransactionMetadatum::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("MetadataList"))?; + Ok(Self(arr)) + } +} + +impl cbor_event::se::Serialize for TransactionMetadatumEnum { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + match self { + TransactionMetadatumEnum::MetadataMap(x) => x.serialize(serializer), + TransactionMetadatumEnum::MetadataList(x) => x.serialize(serializer), + TransactionMetadatumEnum::Int(x) => x.serialize(serializer), + TransactionMetadatumEnum::Bytes(x) => serializer.write_bytes(&x), + TransactionMetadatumEnum::Text(x) => serializer.write_text(&x), + } + } +} + +impl Deserialize for TransactionMetadatumEnum { + fn deserialize(raw: &mut Deserializer) -> Result { + match raw.cbor_type()? { + CBORType::Array => { + MetadataList::deserialize(raw).map(TransactionMetadatumEnum::MetadataList) + } + CBORType::Map => { + MetadataMap::deserialize(raw).map(TransactionMetadatumEnum::MetadataMap) + } + CBORType::Bytes => TransactionMetadatum::new_bytes(raw.bytes()?) + .map(|m| m.0) + .map_err(|e| DeserializeFailure::Metadata(e).into()), + CBORType::Text => TransactionMetadatum::new_text(raw.text()?) + .map(|m| m.0) + .map_err(|e| DeserializeFailure::Metadata(e).into()), + CBORType::UnsignedInteger | CBORType::NegativeInteger => { + Int::deserialize(raw).map(TransactionMetadatumEnum::Int) + } + _ => Err(DeserializeError::new( + "TransactionMetadatumEnum", + DeserializeFailure::NoVariantMatched.into(), + )), + } + } +} + +impl cbor_event::se::Serialize for TransactionMetadatum { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + self.0.serialize(serializer) + } +} + +impl Deserialize for TransactionMetadatum { + fn deserialize(raw: &mut Deserializer) -> Result { + Ok(Self(TransactionMetadatumEnum::deserialize(raw)?)) + } +} + +impl cbor_event::se::Serialize for TransactionMetadatumLabels { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for TransactionMetadatumLabels { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(TransactionMetadatumLabel::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("TransactionMetadatumLabels"))?; + Ok(Self(arr)) + } +} + +impl cbor_event::se::Serialize for GeneralTransactionMetadata { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?; + for (key, value) in &self.0 { + key.serialize(serializer)?; + value.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for GeneralTransactionMetadata { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut table = LinkedHashMap::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.map()?; + while match len { + cbor_event::Len::Len(n) => table.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + let key = TransactionMetadatumLabel::deserialize(raw)?; + let value = TransactionMetadatum::deserialize(raw)?; + if table.insert(key.clone(), value).is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Str(String::from( + "some complicated/unsupported type", + ))) + .into()); + } + } + Ok(()) + })() + .map_err(|e| e.annotate("GeneralTransactionMetadata"))?; + Ok(Self(table)) + } +} + +impl cbor_event::se::Serialize for AuxiliaryData { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + // we still serialize using the shelley-mary era format as it is still supported + // and it takes up less space on-chain so this should be better for scaling. + // Plus the code was already written for shelley-mary anyway + if !self.prefer_alonzo_format && self.metadata.is_some() && self.plutus_scripts.is_none() { + match &self.native_scripts() { + Some(native_scripts) => { + serializer.write_array(cbor_event::Len::Len(2))?; + self.metadata.as_ref().unwrap().serialize(serializer)?; + native_scripts.serialize(serializer) + } + None => self.metadata.as_ref().unwrap().serialize(serializer), + } + } else { + let mut has_plutus_v2 = false; + let mut has_plutus_v3 = false; + let plutus_added_length = match &self.plutus_scripts { + Some(scripts) => { + has_plutus_v2 = scripts.has_version(&Language::new_plutus_v2()); + has_plutus_v3 = scripts.has_version(&Language::new_plutus_v3()); + 1 + (has_plutus_v2 as u64) + (has_plutus_v3 as u64) + }, + _ => 0, + }; + + // new format with plutus support + serializer.write_tag(259u64)?; + serializer.write_map(cbor_event::Len::Len( + opt64(&self.metadata) + opt64(&self.native_scripts) + plutus_added_length, + ))?; + if let Some(metadata) = &self.metadata { + serializer.write_unsigned_integer(0)?; + metadata.serialize(serializer)?; + } + if let Some(native_scripts) = &self.native_scripts { + serializer.write_unsigned_integer(1)?; + native_scripts.serialize(serializer)?; + } + if let Some(plutus_scripts) = &self.plutus_scripts { + serializer.write_unsigned_integer(2)?; + plutus_scripts + .by_version(&Language::new_plutus_v1()) + .serialize(serializer)?; + if has_plutus_v2 { + let v2 = plutus_scripts.by_version(&Language::new_plutus_v2()); + serializer.write_unsigned_integer(3)?; + v2.serialize(serializer)?; + } + if has_plutus_v3 { + let v3 = plutus_scripts.by_version(&Language::new_plutus_v3()); + serializer.write_unsigned_integer(4)?; + v3.serialize(serializer)?; + } + } + Ok(serializer) + } + } +} + +impl Deserialize for AuxiliaryData { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + match raw.cbor_type()? { + // alonzo format + CBORType::Tag => { + let tag = raw.tag()?; + if tag != 259 { + return Err(DeserializeError::new( + "AuxiliaryData", + DeserializeFailure::TagMismatch { + found: tag, + expected: 259, + }, + )); + } + let len = raw.map()?; + let mut read_len = CBORReadLen::new(len); + let mut metadata = None; + let mut native_scripts = None; + let mut plutus_scripts_v1 = None; + let mut plutus_scripts_v2 = None; + let mut plutus_scripts_v3 = None; + let mut read = 0; + while match len { + cbor_event::Len::Len(n) => read < n as usize, + cbor_event::Len::Indefinite => true, + } { + match raw.cbor_type()? { + CBORType::UnsignedInteger => match raw.unsigned_integer()? { + 0 => { + if metadata.is_some() { + return Err( + DeserializeFailure::DuplicateKey(Key::Uint(0)).into() + ); + } + metadata = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(GeneralTransactionMetadata::deserialize(raw)?) + })() + .map_err(|e| e.annotate("metadata"))?, + ); + } + 1 => { + if native_scripts.is_some() { + return Err( + DeserializeFailure::DuplicateKey(Key::Uint(1)).into() + ); + } + native_scripts = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(NativeScripts::deserialize(raw)?) + })() + .map_err(|e| e.annotate("native_scripts"))?, + ); + } + 2 => { + if plutus_scripts_v1.is_some() { + return Err( + DeserializeFailure::DuplicateKey(Key::Uint(2)).into() + ); + } + plutus_scripts_v1 = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(PlutusScripts::deserialize(raw)?) + })() + .map_err(|e| e.annotate("plutus_scripts_v1"))?, + ); + } + 3 => { + if plutus_scripts_v2.is_some() { + return Err( + DeserializeFailure::DuplicateKey(Key::Uint(3)).into() + ); + } + plutus_scripts_v2 = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(PlutusScripts::deserialize(raw)? + .map_as_version(&Language::new_plutus_v2())) + })() + .map_err(|e| e.annotate("plutus_scripts_v2"))?, + ); + } + 4 => { + if plutus_scripts_v3.is_some() { + return Err( + DeserializeFailure::DuplicateKey(Key::Uint(3)).into() + ); + } + plutus_scripts_v3 = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(PlutusScripts::deserialize(raw)? + .map_as_version(&Language::new_plutus_v3())) + })() + .map_err(|e| e.annotate("plutus_scripts_v3"))?, + ); + } + unknown_key => { + return Err(DeserializeFailure::UnknownKey(Key::Uint( + unknown_key, + )) + .into()) + } + }, + CBORType::Text => match raw.text()?.as_str() { + unknown_key => { + return Err(DeserializeFailure::UnknownKey(Key::Str( + unknown_key.to_owned(), + )) + .into()) + } + }, + CBORType::Special => match len { + cbor_event::Len::Len(_) => { + return Err(DeserializeFailure::BreakInDefiniteLen.into()) + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => break, + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + }, + other_type => { + return Err(DeserializeFailure::UnexpectedKeyType(other_type).into()) + } + } + read += 1; + } + read_len.finish()?; + let mut plutus_scripts = None; + plutus_scripts = merge_option_plutus_list(plutus_scripts, plutus_scripts_v1); + plutus_scripts = merge_option_plutus_list(plutus_scripts, plutus_scripts_v2); + plutus_scripts = merge_option_plutus_list(plutus_scripts, plutus_scripts_v3); + + Ok(Self { + metadata, + native_scripts, + plutus_scripts, + prefer_alonzo_format: true, + }) + } + // shelley mary format (still valid for alonzo) + CBORType::Array => { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(2)?; + let metadata = (|| -> Result<_, DeserializeError> { + Ok(GeneralTransactionMetadata::deserialize(raw)?) + })() + .map_err(|e| e.annotate("metadata"))?; + let native_scripts = (|| -> Result<_, DeserializeError> { + Ok(NativeScripts::deserialize(raw)?) + })() + .map_err(|e| e.annotate("native_scripts"))?; + match len { + cbor_event::Len::Len(_) => (), + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => (), + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + Ok(Self { + metadata: Some(metadata), + native_scripts: Some(native_scripts), + plutus_scripts: None, + prefer_alonzo_format: false, + }) + } + // shelley pre-mary format (still valid for alonzo + mary) + CBORType::Map => Ok(Self { + metadata: Some( + GeneralTransactionMetadata::deserialize(raw) + .map_err(|e| e.annotate("metadata"))?, + ), + native_scripts: None, + plutus_scripts: None, + prefer_alonzo_format: false, + }), + _ => return Err(DeserializeFailure::NoVariantMatched)?, + } + })() + .map_err(|e| e.annotate("AuxiliaryData")) + } +} \ No newline at end of file diff --git a/rust/src/serialization/mod.rs b/rust/src/serialization/mod.rs index ee150b34..75409f97 100644 --- a/rust/src/serialization/mod.rs +++ b/rust/src/serialization/mod.rs @@ -1,23 +1,15 @@ mod general; -pub use general::*; - mod serialization_macros; -pub use serialization_macros::*; - mod certificates; -pub use certificates::*; - mod ser_info; pub use ser_info::*; - mod governance; -pub use governance::*; - pub mod map_names; pub mod traits; pub(super) use traits::*; - mod utils; mod fixed_tx; - use utils::*; + +mod plutus; +mod metadata; \ No newline at end of file diff --git a/rust/src/serialization/plutus.rs b/rust/src/serialization/plutus.rs new file mode 100644 index 00000000..383738d9 --- /dev/null +++ b/rust/src/serialization/plutus.rs @@ -0,0 +1,692 @@ +use crate::*; +use std::io::SeekFrom; +use linked_hash_map::LinkedHashMap; + +impl cbor_event::se::Serialize for PlutusScript { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_bytes(&self.bytes) + } +} + +impl Deserialize for PlutusScript { + fn deserialize(raw: &mut Deserializer) -> Result { + Ok(Self::new(raw.bytes()?)) + } +} + +impl cbor_event::se::Serialize for PlutusScripts { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for PlutusScripts { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(PlutusScript::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("PlutusScripts"))?; + Ok(Self(arr)) + } +} + +impl cbor_event::se::Serialize for ConstrPlutusData { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + if let Some(compact_tag) = + Self::alternative_to_compact_cbor_tag(from_bignum(&self.alternative)) + { + // compact form + serializer.write_tag(compact_tag as u64)?; + self.data.serialize(serializer) + } else { + // general form + serializer.write_tag(Self::GENERAL_FORM_TAG)?; + serializer.write_array(cbor_event::Len::Len(2))?; + self.alternative.serialize(serializer)?; + self.data.serialize(serializer) + } + } +} + +impl Deserialize for ConstrPlutusData { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let (alternative, data) = match raw.tag()? { + // general form + Self::GENERAL_FORM_TAG => { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(2)?; + let alternative = BigNum::deserialize(raw)?; + let data = + (|| -> Result<_, DeserializeError> { Ok(PlutusList::deserialize(raw)?) })() + .map_err(|e| e.annotate("datas"))?; + match len { + cbor_event::Len::Len(_) => (), + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => (), + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + (alternative, data) + } + // concise form + tag => { + if let Some(alternative) = Self::compact_cbor_tag_to_alternative(tag) { + (to_bignum(alternative), PlutusList::deserialize(raw)?) + } else { + return Err(DeserializeFailure::TagMismatch { + found: tag, + expected: Self::GENERAL_FORM_TAG, + } + .into()); + } + } + }; + Ok(ConstrPlutusData { alternative, data }) + })() + .map_err(|e| e.annotate("ConstrPlutusData")) + } +} + +impl cbor_event::se::Serialize for CostModel { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for cost in &self.0 { + cost.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for CostModel { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(Int::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("CostModel"))?; + Ok(Self(arr.try_into().unwrap())) + } +} + +impl cbor_event::se::Serialize for Costmdls { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?; + for (key, value) in &self.0 { + key.serialize(serializer)?; + value.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for Costmdls { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut table = std::collections::BTreeMap::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.map()?; + while match len { + cbor_event::Len::Len(n) => table.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + let key = Language::deserialize(raw)?; + let value = CostModel::deserialize(raw)?; + if table.insert(key.clone(), value).is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Str(String::from( + "some complicated/unsupported type", + ))) + .into()); + } + } + Ok(()) + })() + .map_err(|e| e.annotate("Costmdls"))?; + Ok(Self(table)) + } +} + +impl cbor_event::se::Serialize for ExUnitPrices { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.mem_price.serialize(serializer)?; + self.step_price.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for ExUnitPrices { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(2)?; + let mem_price = + (|| -> Result<_, DeserializeError> { Ok(SubCoin::deserialize(raw)?) })() + .map_err(|e| e.annotate("mem_price"))?; + let step_price = + (|| -> Result<_, DeserializeError> { Ok(SubCoin::deserialize(raw)?) })() + .map_err(|e| e.annotate("step_price"))?; + match len { + cbor_event::Len::Len(_) => (), + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => (), + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + Ok(ExUnitPrices { + mem_price, + step_price, + }) + })() + .map_err(|e| e.annotate("ExUnitPrices")) + } +} + +impl cbor_event::se::Serialize for ExUnits { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.mem.serialize(serializer)?; + self.steps.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for ExUnits { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(2)?; + let mem = (|| -> Result<_, DeserializeError> { Ok(BigNum::deserialize(raw)?) })() + .map_err(|e| e.annotate("mem"))?; + let steps = (|| -> Result<_, DeserializeError> { Ok(BigNum::deserialize(raw)?) })() + .map_err(|e| e.annotate("steps"))?; + match len { + cbor_event::Len::Len(_) => (), + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => (), + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + Ok(ExUnits { mem, steps }) + })() + .map_err(|e| e.annotate("ExUnits")) + } +} + +impl cbor_event::se::Serialize for Language { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + // https://github.com/input-output-hk/cardano-ledger/blob/master/eras/babbage/test-suite/cddl-files/babbage.cddl#L324-L327 + serializer.write_unsigned_integer(self.kind() as u64) + } +} + +impl Deserialize for Language { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + match LanguageKind::from_u64(raw.unsigned_integer()?) { + Some(kind) => Ok(Language(kind)), + _ => Err(DeserializeError::new( + "Language", + DeserializeFailure::NoVariantMatched.into(), + )), + } + })() + .map_err(|e| e.annotate("Language")) + } +} + +impl cbor_event::se::Serialize for Languages { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for Languages { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(Language::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("Languages"))?; + Ok(Self(arr)) + } +} + +impl cbor_event::se::Serialize for PlutusMap { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?; + for (key, value) in &self.0 { + key.serialize(serializer)?; + value.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for PlutusMap { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut table = LinkedHashMap::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.map()?; + while match len { + cbor_event::Len::Len(n) => table.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + let key = PlutusData::deserialize(raw)?; + let value = PlutusData::deserialize(raw)?; + if table.insert(key.clone(), value).is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Str(String::from( + "some complicated/unsupported type", + ))) + .into()); + } + } + Ok(()) + })() + .map_err(|e| e.annotate("PlutusMap"))?; + Ok(Self(table)) + } +} + +impl cbor_event::se::Serialize for PlutusDataEnum { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + match self { + PlutusDataEnum::ConstrPlutusData(x) => x.serialize(serializer), + PlutusDataEnum::Map(x) => x.serialize(serializer), + PlutusDataEnum::List(x) => x.serialize(serializer), + PlutusDataEnum::Integer(x) => x.serialize(serializer), + PlutusDataEnum::Bytes(x) => write_bounded_bytes(serializer, &x), + } + } +} + +impl Deserialize for PlutusDataEnum { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let initial_position = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(ConstrPlutusData::deserialize(raw)?) + })(raw) + { + Ok(variant) => return Ok(PlutusDataEnum::ConstrPlutusData(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(PlutusMap::deserialize(raw)?) + })(raw) + { + Ok(variant) => return Ok(PlutusDataEnum::Map(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(PlutusList::deserialize(raw)?) + })(raw) + { + Ok(variant) => return Ok(PlutusDataEnum::List(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(BigInt::deserialize(raw)?) + })(raw) + { + Ok(variant) => return Ok(PlutusDataEnum::Integer(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(read_bounded_bytes(raw)?) + })(raw) + { + Ok(variant) => return Ok(PlutusDataEnum::Bytes(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + Err(DeserializeError::new( + "PlutusDataEnum", + DeserializeFailure::NoVariantMatched.into(), + )) + })() + .map_err(|e| e.annotate("PlutusDataEnum")) + } +} + +impl cbor_event::se::Serialize for PlutusData { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + match &self.original_bytes { + Some(bytes) => serializer.write_raw_bytes(bytes), + None => self.datum.serialize(serializer), + } + } +} + +impl Deserialize for PlutusData { + fn deserialize(raw: &mut Deserializer) -> Result { + // these unwraps are fine since we're seeking the current position + let before = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); + let datum = PlutusDataEnum::deserialize(raw)?; + let after = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); + let bytes_read = (after - before) as usize; + raw.as_mut_ref().seek(SeekFrom::Start(before)).unwrap(); + // these unwraps are fine since we read the above already + let original_bytes = raw.as_mut_ref().fill_buf().unwrap()[..bytes_read].to_vec(); + raw.as_mut_ref().consume(bytes_read); + Ok(Self { + datum, + original_bytes: Some(original_bytes), + }) + } +} + +impl cbor_event::se::Serialize for PlutusList { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + let use_definite_encoding = match self.definite_encoding { + Some(definite) => definite, + None => self.elems.is_empty(), + }; + if use_definite_encoding { + serializer.write_array(cbor_event::Len::Len(self.elems.len() as u64))?; + } else { + serializer.write_array(cbor_event::Len::Indefinite)?; + } + for element in &self.elems { + element.serialize(serializer)?; + } + if !use_definite_encoding { + serializer.write_special(cbor_event::Special::Break)?; + } + Ok(serializer) + } +} + +impl Deserialize for PlutusList { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + let len = (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(PlutusData::deserialize(raw)?); + } + Ok(len) + })() + .map_err(|e| e.annotate("PlutusList"))?; + Ok(Self { + elems: arr, + definite_encoding: Some(len != cbor_event::Len::Indefinite), + }) + } +} + +impl cbor_event::se::Serialize for Redeemer { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(4))?; + self.tag.serialize(serializer)?; + self.index.serialize(serializer)?; + self.data.serialize(serializer)?; + self.ex_units.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for Redeemer { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(4)?; + let tag = (|| -> Result<_, DeserializeError> { Ok(RedeemerTag::deserialize(raw)?) })() + .map_err(|e| e.annotate("tag"))?; + let index = (|| -> Result<_, DeserializeError> { Ok(BigNum::deserialize(raw)?) })() + .map_err(|e| e.annotate("index"))?; + let data = (|| -> Result<_, DeserializeError> { Ok(PlutusData::deserialize(raw)?) })() + .map_err(|e| e.annotate("data"))?; + let ex_units = (|| -> Result<_, DeserializeError> { Ok(ExUnits::deserialize(raw)?) })() + .map_err(|e| e.annotate("ex_units"))?; + match len { + cbor_event::Len::Len(_) => (), + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => (), + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + Ok(Redeemer { + tag, + index, + data, + ex_units, + }) + })() + .map_err(|e| e.annotate("Redeemer")) + } +} + +impl cbor_event::se::Serialize for RedeemerTagKind { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + match self { + RedeemerTagKind::Spend => serializer.write_unsigned_integer(0u64), + RedeemerTagKind::Mint => serializer.write_unsigned_integer(1u64), + RedeemerTagKind::Cert => serializer.write_unsigned_integer(2u64), + RedeemerTagKind::Reward => serializer.write_unsigned_integer(3u64), + RedeemerTagKind::Vote => serializer.write_unsigned_integer(4u64), + RedeemerTagKind::VotingProposal => serializer.write_unsigned_integer(5u64), + } + } +} + +impl Deserialize for RedeemerTagKind { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + match raw.unsigned_integer() { + Ok(0) => Ok(RedeemerTagKind::Spend), + Ok(1) => Ok(RedeemerTagKind::Mint), + Ok(2) => Ok(RedeemerTagKind::Cert), + Ok(3) => Ok(RedeemerTagKind::Reward), + Ok(4) => Ok(RedeemerTagKind::Vote), + Ok(5) => Ok(RedeemerTagKind::VotingProposal), + Ok(_) | Err(_) => Err(DeserializeFailure::NoVariantMatched.into()), + } + })() + .map_err(|e| e.annotate("RedeemerTagEnum")) + } +} + +impl cbor_event::se::Serialize for RedeemerTag { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + self.0.serialize(serializer) + } +} + +impl Deserialize for RedeemerTag { + fn deserialize(raw: &mut Deserializer) -> Result { + Ok(Self(RedeemerTagKind::deserialize(raw)?)) + } +} + +impl cbor_event::se::Serialize for Redeemers { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for Redeemers { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(Redeemer::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("Redeemers"))?; + Ok(Self(arr)) + } +} + +impl cbor_event::se::Serialize for Strings { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + serializer.write_text(&element)?; + } + Ok(serializer) + } +} + +impl Deserialize for Strings { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(String::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("Strings"))?; + Ok(Self(arr)) + } +} \ No newline at end of file diff --git a/rust/src/serialization/serialization_macros.rs b/rust/src/serialization/serialization_macros.rs index e8e7ddb0..dd460e25 100644 --- a/rust/src/serialization/serialization_macros.rs +++ b/rust/src/serialization/serialization_macros.rs @@ -144,7 +144,7 @@ macro_rules! impl_deserialize_for_wrapped_tuple { raw: &mut Deserializer, ) -> Result { (|| -> Result<_, DeserializeError> { - use crate::serialization::struct_checks::check_len_indefinite; + use crate::serialization::utils::check_len_indefinite; let len = raw.array()?; let cert = Self::deserialize_as_embedded_group(raw, len)?; diff --git a/rust/src/serialization/utils.rs b/rust/src/serialization/utils.rs index ef54dd42..2f4515a9 100644 --- a/rust/src/serialization/utils.rs +++ b/rust/src/serialization/utils.rs @@ -74,3 +74,15 @@ pub(super) fn check_len_indefinite( } Ok(()) } + +pub(crate) fn merge_option_plutus_list(left: Option, right: Option) -> Option { + if let Some(left) = left { + if let Some(right) = right { + return Some(left.merge(&right)); + } else { + return Some(left); + } + } else { + return right; + } +} diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index e4fea0be..cf1b85f8 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -5654,7 +5654,7 @@ fn plutus_mint_test() { \"transaction_id\": \"f58a5bc761b1efdcf4b5684f6ad5495854a0d64b866e2f0f525d134750d3511b\", \"index\": 1 }").unwrap(); - let plutus_script = plutus::PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); + let plutus_script = PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); let redeemer = Redeemer::from_json( "\ { @@ -5737,8 +5737,8 @@ fn plutus_mint_with_script_ref_test() { \"transaction_id\": \"f58a5bc7adaadadcf4b5684f6ad5495854a0d64b866e2f0f525d134750d3511b\", \"index\": 2 }").unwrap(); - let plutus_script = plutus::PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); - let plutus_script2 = plutus::PlutusScript::from_hex("5907adaada00332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); + let plutus_script = PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); + let plutus_script2 = PlutusScript::from_hex("5907adaada00332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); let redeemer = Redeemer::from_json( "\ @@ -5842,7 +5842,7 @@ fn plutus_mint_defferent_redeemers_test() { \"transaction_id\": \"f58a5bc761b1efdcf4b5684f6ad5495854a0d64b866e2f0f525d134750d3511b\", \"index\": 1 }").unwrap(); - let plutus_script = plutus::PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); + let plutus_script = PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); let redeemer = Redeemer::from_json( "\ @@ -5925,7 +5925,7 @@ fn plutus_mint_defferent_redeemers_test() { #[test] fn multiple_plutus_inputs_test() { let mut tx_builder = create_reallistic_tx_builder(); - let plutus_script = plutus::PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); + let plutus_script = PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); let redeemer1 = Redeemer::from_json( "\ { @@ -6018,7 +6018,7 @@ fn multiple_plutus_inputs_test() { #[test] fn multiple_plutus_inputs_with_missed_wit_test() { let mut tx_builder = create_reallistic_tx_builder(); - let plutus_script = plutus::PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); + let plutus_script = PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); let redeemer1 = Redeemer::from_json( "\ { diff --git a/rust/src/tests/metadata.rs b/rust/src/tests/metadata.rs new file mode 100644 index 00000000..b429ae8e --- /dev/null +++ b/rust/src/tests/metadata.rs @@ -0,0 +1,281 @@ +use crate::*; + +#[test] +fn binary_encoding() { + let input_bytes = (0..1000).map(|x| x as u8).collect::>(); + let metadata = encode_arbitrary_bytes_as_metadatum(input_bytes.as_ref()); + let output_bytes = decode_arbitrary_bytes_from_metadatum(&metadata).expect("decode failed"); + assert_eq!(input_bytes, output_bytes); +} + +#[test] +fn json_encoding_no_conversions() { + let input_str = String::from("{\"receiver_id\": \"SJKdj34k3jjKFDKfjFUDfdjkfd\",\"sender_id\": \"jkfdsufjdk34h3Sdfjdhfduf873\",\"comment\": \"happy birthday\",\"tags\": [0, 264, -1024, 32]}"); + let metadata = + encode_json_str_to_metadatum(input_str.clone(), MetadataJsonSchema::NoConversions) + .expect("encode failed"); + let map = metadata.as_map().unwrap(); + assert_eq!( + map.get_str("receiver_id").unwrap().as_text().unwrap(), + "SJKdj34k3jjKFDKfjFUDfdjkfd" + ); + assert_eq!( + map.get_str("sender_id").unwrap().as_text().unwrap(), + "jkfdsufjdk34h3Sdfjdhfduf873" + ); + assert_eq!( + map.get_str("comment").unwrap().as_text().unwrap(), + "happy birthday" + ); + let tags = map.get_str("tags").unwrap().as_list().unwrap(); + let tags_i32 = tags + .0 + .iter() + .map(|md| md.as_int().unwrap().as_i32_or_fail().unwrap()) + .collect::>(); + assert_eq!(tags_i32, vec![0, 264, -1024, 32]); + let output_str = decode_metadatum_to_json_str(&metadata, MetadataJsonSchema::NoConversions) + .expect("decode failed"); + let input_json: serde_json::Value = serde_json::from_str(&input_str).unwrap(); + let output_json: serde_json::Value = serde_json::from_str(&output_str).unwrap(); + assert_eq!(input_json, output_json); +} + +#[test] +fn json_encoding_basic() { + let input_str = + String::from("{\"0x8badf00d\": \"0xdeadbeef\",\"9\": 5,\"obj\": {\"a\":[{\"5\": 2},{}]}}"); + let metadata = + encode_json_str_to_metadatum(input_str.clone(), MetadataJsonSchema::BasicConversions) + .expect("encode failed"); + json_encoding_check_example_metadatum(&metadata); + let output_str = decode_metadatum_to_json_str(&metadata, MetadataJsonSchema::BasicConversions) + .expect("decode failed"); + let input_json: serde_json::Value = serde_json::from_str(&input_str).unwrap(); + let output_json: serde_json::Value = serde_json::from_str(&output_str).unwrap(); + assert_eq!(input_json, output_json); +} + +#[test] +fn json_encoding_detailed() { + let input_str = String::from( + "{\"map\":[ + { + \"k\":{\"bytes\":\"8badf00d\"}, + \"v\":{\"bytes\":\"deadbeef\"} + }, + { + \"k\":{\"int\":9}, + \"v\":{\"int\":5} + }, + { + \"k\":{\"string\":\"obj\"}, + \"v\":{\"map\":[ + { + \"k\":{\"string\":\"a\"}, + \"v\":{\"list\":[ + {\"map\":[ + { + \"k\":{\"int\":5}, + \"v\":{\"int\":2} + } + ]}, + {\"map\":[ + ]} + ]} + } + ]} + } + ]}", + ); + let metadata = + encode_json_str_to_metadatum(input_str.clone(), MetadataJsonSchema::DetailedSchema) + .expect("encode failed"); + json_encoding_check_example_metadatum(&metadata); + let output_str = decode_metadatum_to_json_str(&metadata, MetadataJsonSchema::DetailedSchema) + .expect("decode failed"); + let input_json: serde_json::Value = serde_json::from_str(&input_str).unwrap(); + let output_json: serde_json::Value = serde_json::from_str(&output_str).unwrap(); + assert_eq!(input_json, output_json); +} + +fn json_encoding_check_example_metadatum(metadata: &TransactionMetadatum) { + let map = metadata.as_map().unwrap(); + assert_eq!( + map.get(&TransactionMetadatum::new_bytes(hex::decode("8badf00d").unwrap()).unwrap()) + .unwrap() + .as_bytes() + .unwrap(), + hex::decode("deadbeef").unwrap() + ); + assert_eq!( + map.get_i32(9) + .unwrap() + .as_int() + .unwrap() + .as_i32_or_fail() + .unwrap(), + 5 + ); + let inner_map = map.get_str("obj").unwrap().as_map().unwrap(); + let a = inner_map.get_str("a").unwrap().as_list().unwrap(); + let a1 = a.get(0).as_map().unwrap(); + assert_eq!( + a1.get_i32(5) + .unwrap() + .as_int() + .unwrap() + .as_i32_or_fail() + .unwrap(), + 2 + ); + let a2 = a.get(1).as_map().unwrap(); + assert_eq!(a2.keys().len(), 0); +} + +#[test] +fn json_encoding_detailed_complex_key() { + let input_str = String::from( + "{\"map\":[ + { + \"k\":{\"list\":[ + {\"map\": [ + { + \"k\": {\"int\": 5}, + \"v\": {\"int\": -7} + }, + { + \"k\": {\"string\": \"hello\"}, + \"v\": {\"string\": \"world\"} + } + ]}, + {\"bytes\": \"ff00ff00\"} + ]}, + \"v\":{\"int\":5} + } + ]}", + ); + let metadata = + encode_json_str_to_metadatum(input_str.clone(), MetadataJsonSchema::DetailedSchema) + .expect("encode failed"); + + let map = metadata.as_map().unwrap(); + let key = map.keys().get(0); + assert_eq!( + map.get(&key) + .unwrap() + .as_int() + .unwrap() + .as_i32_or_fail() + .unwrap(), + 5 + ); + let key_list = key.as_list().unwrap(); + assert_eq!(key_list.len(), 2); + let key_map = key_list.get(0).as_map().unwrap(); + assert_eq!( + key_map + .get_i32(5) + .unwrap() + .as_int() + .unwrap() + .as_i32_or_fail() + .unwrap(), + -7 + ); + assert_eq!( + key_map.get_str("hello").unwrap().as_text().unwrap(), + "world" + ); + let key_bytes = key_list.get(1).as_bytes().unwrap(); + assert_eq!(key_bytes, hex::decode("ff00ff00").unwrap()); + + let output_str = decode_metadatum_to_json_str(&metadata, MetadataJsonSchema::DetailedSchema) + .expect("decode failed"); + let input_json: serde_json::Value = serde_json::from_str(&input_str).unwrap(); + let output_json: serde_json::Value = serde_json::from_str(&output_str).unwrap(); + assert_eq!(input_json, output_json); +} + +#[test] +fn metadata_serialize() { + let mut gmd = GeneralTransactionMetadata::new(); + let mdatum = TransactionMetadatum::new_text(String::from("string md")).unwrap(); + gmd.insert(&to_bignum(100), &mdatum); + let mut aux_data = AuxiliaryData::new(); + // alonzo (empty) + let ad0_deser = AuxiliaryData::from_bytes(aux_data.to_bytes()).unwrap(); + assert_eq!(aux_data.to_bytes(), ad0_deser.to_bytes()); + // pre-mary shelley + aux_data.set_metadata(&gmd); + let ad1_deser = AuxiliaryData::from_bytes(aux_data.to_bytes()).unwrap(); + assert_eq!(aux_data.to_bytes(), ad1_deser.to_bytes()); + // mary shelley + let mut native_scripts = NativeScripts::new(); + native_scripts.add(&NativeScript::new_timelock_start(&TimelockStart::new(20))); + aux_data.set_native_scripts(&native_scripts); + let ad2_deser = AuxiliaryData::from_bytes(aux_data.to_bytes()).unwrap(); + assert_eq!(aux_data.to_bytes(), ad2_deser.to_bytes()); + // alonzo + let mut plutus_scripts = PlutusScripts::new(); + plutus_scripts.add(&PlutusScript::new([61u8; 29].to_vec())); + aux_data.set_plutus_scripts(&plutus_scripts); + let ad3_deser = AuxiliaryData::from_bytes(aux_data.to_bytes()).unwrap(); + assert_eq!(aux_data.to_bytes(), ad3_deser.to_bytes()); +} + +#[test] +fn alonzo_metadata_round_trip() { + let bytes_alonzo = hex::decode("d90103a100a1186469737472696e67206d64").unwrap(); + let aux_alonzo = AuxiliaryData::from_bytes(bytes_alonzo.clone()).unwrap(); + assert!(aux_alonzo.prefer_alonzo_format); + assert_eq!(aux_alonzo.to_bytes(), bytes_alonzo); + + let bytes_pre_alonzo = hex::decode("a1186469737472696e67206d64").unwrap(); + let aux_pre_alonzo = AuxiliaryData::from_bytes(bytes_pre_alonzo.clone()).unwrap(); + assert!(!aux_pre_alonzo.prefer_alonzo_format); + assert_eq!(aux_pre_alonzo.to_bytes(), bytes_pre_alonzo); +} + +#[test] +fn metadatum_map_duplicate_keys() { + let bytes = hex::decode("a105a4781b232323232323232323232323232323232323232323232323232323827840232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323237840232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323236e232323232323232323232323232382a36f2323232323232323232323232323236a323030302d30312d303166232323232323784023232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323712323232323232323232323232323232323784023232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323a36f2323232323232323232323232323236a323030302d30312d303166232323232323784023232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323712323232323232323232323232323232323784023232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323752323232323232323232323232323232323232323236a323030302d30312d3031752323232323232323232323232323232323232323236a323030302d30312d3031").unwrap(); + TransactionMetadatum::from_bytes(bytes).unwrap(); +} + +#[test] +fn test_auxiliary_data_roundtrip() { + fn auxiliary_data_roundtrip(plutus_scripts: &PlutusScripts) { + let mut aux = AuxiliaryData::new(); + let mut metadata = GeneralTransactionMetadata::new(); + metadata.insert( + &to_bignum(42), + &encode_json_str_to_metadatum( + "{ \"test\": 148 }".to_string(), + MetadataJsonSchema::BasicConversions, + ) + .unwrap(), + ); + aux.set_metadata(&metadata); + aux.set_native_scripts(&NativeScripts::from(vec![ + NativeScript::new_timelock_start(&TimelockStart::new(1234556)), + ])); + aux.set_plutus_scripts(plutus_scripts); + assert_eq!(AuxiliaryData::from_bytes(aux.to_bytes()).unwrap(), aux); + } + + let bytes = hex::decode("4e4d01000033222220051200120011").unwrap(); + let script_v1 = PlutusScript::from_bytes(bytes.clone()).unwrap(); + let script_v2 = PlutusScript::from_bytes_v2(bytes.clone()).unwrap(); + let script_v3 = PlutusScript::from_bytes_v3(bytes.clone()).unwrap(); + + auxiliary_data_roundtrip(&PlutusScripts(vec![])); + auxiliary_data_roundtrip(&PlutusScripts(vec![script_v1.clone()])); + auxiliary_data_roundtrip(&PlutusScripts(vec![script_v2.clone()])); + auxiliary_data_roundtrip(&PlutusScripts(vec![script_v3.clone()])); + auxiliary_data_roundtrip(&PlutusScripts(vec![ + script_v1.clone(), + script_v2.clone(), + script_v3.clone(), + ])); +} diff --git a/rust/src/tests/mod.rs b/rust/src/tests/mod.rs index 33340fca..bd63e78d 100644 --- a/rust/src/tests/mod.rs +++ b/rust/src/tests/mod.rs @@ -5,3 +5,5 @@ mod helpers; mod mock_objects; mod protocol_types; mod serialization; +mod plutus; +mod metadata; \ No newline at end of file diff --git a/rust/src/tests/plutus.rs b/rust/src/tests/plutus.rs new file mode 100644 index 00000000..fc2bb212 --- /dev/null +++ b/rust/src/tests/plutus.rs @@ -0,0 +1,525 @@ +use crate::*; +use hex::*; + +#[test] +pub fn plutus_constr_data() { + let constr_0 = PlutusData::new_constr_plutus_data(&ConstrPlutusData::new( + &to_bignum(0), + &PlutusList::new(), + )); + let constr_0_hash = hex::encode(hash_plutus_data(&constr_0).to_bytes()); + assert_eq!( + constr_0_hash, + "923918e403bf43c34b4ef6b48eb2ee04babed17320d8d1b9ff9ad086e86f44ec" + ); + // let constr_0_roundtrip = PlutusData::from_bytes(constr_0.to_bytes()).unwrap(); + // TODO: do we want semantic equality or bytewise equality? + // assert_eq!(constr_0, constr_0_roundtrip); + // let constr_1854 = PlutusData::new_constr_plutus_data( + // &ConstrPlutusData::new(&to_bignum(1854), &PlutusList::new()) + // ); + // let constr_1854_roundtrip = PlutusData::from_bytes(constr_1854.to_bytes()).unwrap(); + // assert_eq!(constr_1854, constr_1854_roundtrip); +} + +#[test] +pub fn plutus_list_serialization_cli_compatibility() { + // mimic cardano-cli array encoding, see https://github.com/Emurgo/cardano-serialization-lib/issues/227 + let datum_cli = "d8799f4100d8799fd8799fd8799f581cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd8799fd8799fd8799f581cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd87a80ff1a002625a0d8799fd879801a000f4240d87a80ffff"; + let datum = PlutusData::from_bytes(Vec::from_hex(datum_cli).unwrap()).unwrap(); + assert_eq!(datum_cli, hex::encode(datum.to_bytes())); + + // encode empty arrays as fixed + assert_eq!("80", hex::encode(PlutusList::new().to_bytes())); + + // encode arrays as indefinite length array + let mut list = PlutusList::new(); + list.add(&PlutusData::new_integer(&BigInt::from_str("1").unwrap())); + assert_eq!("9f01ff", hex::encode(list.to_bytes())); + + // witness_set should have fixed length array + let mut witness_set = TransactionWitnessSet::new(); + witness_set.set_plutus_data(&list); + assert_eq!("a1049f01ff", hex::encode(witness_set.to_bytes())); + + list = PlutusList::new(); + list.add(&datum); + witness_set.set_plutus_data(&list); + assert_eq!( + format!("a1049f{}ff", datum_cli), + hex::encode(witness_set.to_bytes()) + ); +} + +#[test] +pub fn plutus_datums_respect_deserialized_encoding() { + let orig_bytes = Vec::from_hex( + "81d8799f581ce1cbb80db89e292269aeb93ec15eb963dda5176b66949fe1c2a6a38da140a1401864ff", + ) + .unwrap(); + let datums = PlutusList::from_bytes(orig_bytes.clone()).unwrap(); + let new_bytes = datums.to_bytes(); + assert_eq!(orig_bytes, new_bytes); +} + +#[test] +pub fn plutus_datum_from_json_basic() { + let json = "{ + \"5\": \"some utf8 string\", + \"0xDEADBEEF\": [ + {\"reg string\": {}}, + -9 + ] + }"; + + let datum = encode_json_str_to_plutus_datum(json, PlutusDatumSchema::BasicConversions).unwrap(); + + let map = datum.as_map().unwrap(); + let map_5 = map + .get(&PlutusData::new_integer(&BigInt::from_str("5").unwrap())) + .unwrap(); + let utf8_bytes = "some utf8 string".as_bytes(); + assert_eq!(map_5.as_bytes().unwrap(), utf8_bytes); + let map_deadbeef: PlutusList = map + .get(&PlutusData::new_bytes(vec![222, 173, 190, 239])) + .expect("DEADBEEF key not found") + .as_list() + .expect("must be a map"); + assert_eq!(map_deadbeef.len(), 2); + let inner_map = map_deadbeef.get(0).as_map().unwrap(); + assert_eq!(inner_map.len(), 1); + let reg_string = inner_map + .get(&PlutusData::new_bytes("reg string".as_bytes().to_vec())) + .unwrap(); + assert_eq!(reg_string.as_map().expect("reg string: {}").len(), 0); + assert_eq!( + map_deadbeef.get(1).as_integer(), + BigInt::from_str("-9").ok() + ); + + // test round-trip via generated JSON + let json2 = + decode_plutus_datum_to_json_str(&datum, PlutusDatumSchema::BasicConversions).unwrap(); + let datum2 = + encode_json_str_to_plutus_datum(&json2, PlutusDatumSchema::BasicConversions).unwrap(); + assert_eq!(datum, datum2); +} + +#[test] +pub fn plutus_datum_from_json_detailed() { + let json = "{\"list\": [ + {\"map\": [ + {\"k\": {\"bytes\": \"DEADBEEF\"}, \"v\": {\"int\": 42}}, + {\"k\": {\"map\" : [ + {\"k\": {\"int\": 9}, \"v\": {\"int\": -5}} + ]}, \"v\": {\"list\": []}} + ]}, + {\"bytes\": \"CAFED00D\"}, + {\"constructor\": 0, \"fields\": [ + {\"map\": []}, + {\"int\": 23} + ]} + ]}"; + let datum = encode_json_str_to_plutus_datum(json, PlutusDatumSchema::DetailedSchema).unwrap(); + + let list = datum.as_list().unwrap(); + assert_eq!(3, list.len()); + // map + let map = list.get(0).as_map().unwrap(); + assert_eq!(map.len(), 2); + let map_deadbeef = map + .get(&PlutusData::new_bytes(vec![222, 173, 190, 239])) + .unwrap(); + assert_eq!(map_deadbeef.as_integer(), BigInt::from_str("42").ok()); + let mut long_key = PlutusMap::new(); + long_key.insert( + &PlutusData::new_integer(&BigInt::from_str("9").unwrap()), + &PlutusData::new_integer(&BigInt::from_str("-5").unwrap()), + ); + let map_9_to_5 = map + .get(&PlutusData::new_map(&long_key)) + .unwrap() + .as_list() + .unwrap(); + assert_eq!(map_9_to_5.len(), 0); + // bytes + let bytes = list.get(1).as_bytes().unwrap(); + assert_eq!(bytes, [202, 254, 208, 13]); + // constr data + let constr = list.get(2).as_constr_plutus_data().unwrap(); + assert_eq!(to_bignum(0), constr.alternative()); + let fields = constr.data(); + assert_eq!(fields.len(), 2); + let field0 = fields.get(0).as_map().unwrap(); + assert_eq!(field0.len(), 0); + let field1 = fields.get(1); + assert_eq!(field1.as_integer(), BigInt::from_str("23").ok()); + + // test round-trip via generated JSON + let json2 = decode_plutus_datum_to_json_str(&datum, PlutusDatumSchema::DetailedSchema).unwrap(); + let datum2 = + encode_json_str_to_plutus_datum(&json2, PlutusDatumSchema::DetailedSchema).unwrap(); + assert_eq!(datum, datum2); +} + +#[test] +pub fn test_cost_model() { + let arr = vec![ + 197209, 0, 1, 1, 396231, 621, 0, 1, 150000, 1000, 0, 1, 150000, 32, 2477736, 29175, 4, + 29773, 100, 29773, 100, 29773, 100, 29773, 100, 29773, 100, 29773, 100, 100, 100, 29773, + 100, 150000, 32, 150000, 32, 150000, 32, 150000, 1000, 0, 1, 150000, 32, 150000, 1000, 0, + 8, 148000, 425507, 118, 0, 1, 1, 150000, 1000, 0, 8, 150000, 112536, 247, 1, 150000, 10000, + 1, 136542, 1326, 1, 1000, 150000, 1000, 1, 150000, 32, 150000, 32, 150000, 32, 1, 1, + 150000, 1, 150000, 4, 103599, 248, 1, 103599, 248, 1, 145276, 1366, 1, 179690, 497, 1, + 150000, 32, 150000, 32, 150000, 32, 150000, 32, 150000, 32, 150000, 32, 148000, 425507, + 118, 0, 1, 1, 61516, 11218, 0, 1, 150000, 32, 148000, 425507, 118, 0, 1, 1, 148000, 425507, + 118, 0, 1, 1, 2477736, 29175, 4, 0, 82363, 4, 150000, 5000, 0, 1, 150000, 32, 197209, 0, 1, + 1, 150000, 32, 150000, 32, 150000, 32, 150000, 32, 150000, 32, 150000, 32, 150000, 32, + 3345831, 1, 1, + ]; + let cm = arr + .iter() + .fold((CostModel::new(), 0), |(mut cm, i), x| { + cm.set(i, &Int::new_i32(x.clone())).unwrap(); + (cm, i + 1) + }) + .0; + let mut cms = Costmdls::new(); + cms.insert(&Language::new_plutus_v1(), &cm); + assert_eq!( + hex::encode(cms.language_views_encoding()), + "a141005901d59f1a000302590001011a00060bc719026d00011a000249f01903e800011a000249f018201a0025cea81971f70419744d186419744d186419744d186419744d186419744d186419744d18641864186419744d18641a000249f018201a000249f018201a000249f018201a000249f01903e800011a000249f018201a000249f01903e800081a000242201a00067e2318760001011a000249f01903e800081a000249f01a0001b79818f7011a000249f0192710011a0002155e19052e011903e81a000249f01903e8011a000249f018201a000249f018201a000249f0182001011a000249f0011a000249f0041a000194af18f8011a000194af18f8011a0002377c190556011a0002bdea1901f1011a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a000242201a00067e23187600010119f04c192bd200011a000249f018201a000242201a00067e2318760001011a000242201a00067e2318760001011a0025cea81971f704001a000141bb041a000249f019138800011a000249f018201a000302590001011a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a00330da70101ff" + ); +} + +#[test] +fn test_plutus_script_hash() { + let hash = EnterpriseAddress::from_address( + &Address::from_bech32("addr1w896t6qnpsjs32xhw8jl3kw34pqz69kgd72l8hqw83w0k3qahx2sv") + .unwrap(), + ) + .unwrap() + .payment_cred() + .to_scripthash() + .unwrap(); + let script = PlutusScript::from_bytes( + hex::decode("590e6f590e6c0100003323332223322333222332232332233223232333222323332223233333333222222223233322232333322223232332232323332223232332233223232333332222233223322332233223322332222323232232232325335303233300a3333573466e1cd55cea8042400046664446660a40060040026eb4d5d0a8041bae35742a00e66a05046666ae68cdc39aab9d37540029000102b11931a982599ab9c04f04c04a049357426ae89401c8c98d4c124cd5ce0268250240239999ab9a3370ea0089001102b11999ab9a3370ea00a9000102c11931a982519ab9c04e04b0490480473333573466e1cd55cea8012400046601a64646464646464646464646666ae68cdc39aab9d500a480008cccccccccc06ccd40a48c8c8cccd5cd19b8735573aa0049000119810981c9aba15002302e357426ae8940088c98d4c164cd5ce02e82d02c02b89aab9e5001137540026ae854028cd40a40a8d5d0a804999aa8183ae502f35742a010666aa060eb940bcd5d0a80399a8148211aba15006335029335505304b75a6ae854014c8c8c8cccd5cd19b8735573aa0049000119a8119919191999ab9a3370e6aae7540092000233502b33504175a6ae854008c118d5d09aba25002232635305d3357380c20bc0b80b626aae7940044dd50009aba150023232323333573466e1cd55cea80124000466a05266a082eb4d5d0a80118231aba135744a004464c6a60ba66ae7018417817016c4d55cf280089baa001357426ae8940088c98d4c164cd5ce02e82d02c02b89aab9e5001137540026ae854010cd40a5d71aba15003335029335505375c40026ae854008c0e0d5d09aba2500223263530553357380b20ac0a80a626ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba150023232323333573466e1d4005200623020303a357426aae79400c8cccd5cd19b875002480108c07cc110d5d09aab9e500423333573466e1d400d20022301f302f357426aae7940148cccd5cd19b875004480008c088dd71aba135573ca00c464c6a60a066ae7015014413c13813413012c4d55cea80089baa001357426ae8940088c98d4c124cd5ce026825024023882489931a982419ab9c4910350543500049047135573ca00226ea80044d55ce9baa001135744a00226aae7940044dd50009109198008018011000911111111109199999999980080580500480400380300280200180110009109198008018011000891091980080180109000891091980080180109000891091980080180109000909111180200290911118018029091111801002909111180080290008919118011bac0013200135503c2233335573e0024a01c466a01a60086ae84008c00cd5d100101811919191999ab9a3370e6aae75400d200023330073232323333573466e1cd55cea8012400046601a605c6ae854008cd404c0a8d5d09aba25002232635303433573807006a06606426aae7940044dd50009aba150033335500b75ca0146ae854008cd403dd71aba135744a004464c6a606066ae700d00c40bc0b84d5d1280089aab9e5001137540024442466600200800600440024424660020060044002266aa002eb9d6889119118011bab00132001355036223233335573e0044a012466a01066aa05c600c6aae754008c014d55cf280118021aba200302b1357420022244004244244660020080062400224464646666ae68cdc3a800a400046a05e600a6ae84d55cf280191999ab9a3370ea00490011281791931a981399ab9c02b028026025024135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011980318039aba15002375a6ae84d5d1280111931a981219ab9c028025023022135573ca00226ea80048848cc00400c00880048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98d4c080cd5ce01201080f80f09baa00112232323333573466e1d400520042500723333573466e1d4009200223500a3006357426aae7940108cccd5cd19b87500348000940288c98d4c08ccd5ce01381201101081000f89aab9d50011375400224244460060082244400422444002240024646666ae68cdc3a800a4004400c46666ae68cdc3a80124000400c464c6a603666ae7007c0700680640604d55ce9baa0011220021220012001232323232323333573466e1d4005200c200b23333573466e1d4009200a200d23333573466e1d400d200823300b375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c46601a6eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc048c050d5d0a8049bae357426ae8940248cccd5cd19b875006480088c050c054d5d09aab9e500b23333573466e1d401d2000230133016357426aae7940308c98d4c080cd5ce01201080f80f00e80e00d80d00c80c09aab9d5004135573ca00626aae7940084d55cf280089baa00121222222230070082212222222330060090082122222223005008122222220041222222200322122222223300200900822122222223300100900820012323232323333573466e1d400520022333008375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea00490001180518059aba135573ca00c464c6a602266ae7005404804003c0384d55cea80189aba25001135573ca00226ea80048488c00800c888488ccc00401401000c80048c8c8cccd5cd19b875001480088c018dd71aba135573ca00646666ae68cdc3a80124000460106eb8d5d09aab9e5004232635300b33573801e01801401201026aae7540044dd5000909118010019091180080190008891119191999ab9a3370e6aae75400920002335500b300635742a004600a6ae84d5d1280111931a980419ab9c00c009007006135573ca00226ea800526120012001112212330010030021120014910350543100222123330010040030022001121223002003112200112001120012001122002122001200111232300100122330033002002001332323233322233322233223332223322332233322233223322332233223233322232323322323232323333222232332232323222323222325335301a5335301a333573466e1cc8cccd54c05048004c8cd406488ccd406400c004008d4058004cd4060888c00cc008004800488cdc0000a40040029000199aa98068900091299a980e299a9a81a1a98169a98131a9812001110009110019119a98188011281c11a81c8009080f880e899a8148010008800a8141a981028009111111111005240040380362038266ae712413c53686f756c642062652065786163746c79206f6e652073637269707420696e70757420746f2061766f696420646f75626c65207361742069737375650001b15335303500315335301a5335301a333573466e20ccc064ccd54c03448005402540a0cc020d4c0c00188880094004074074cdc09a9818003111001a80200d80e080e099ab9c49010f73656c6c6572206e6f7420706169640001b15335301a333573466e20ccc064cc88ccd54c03c48005402d40a8cc028004009400401c074075401006c07040704cd5ce24810d66656573206e6f7420706169640001b101b15335301a3322353022002222222222253353503e33355301f1200133502322533535040002210031001503f253353027333573466e3c0300040a40a04d41040045410000c840a4409d4004d4c0c001888800840704cd5ce2491c4f6e6c792073656c6c65722063616e2063616e63656c206f666665720001b101b135301d00122002153353016333573466e2540040d406005c40d4540044cdc199b8235302b001222003480c920d00f2235301a0012222222222333553011120012235302a002222353034003223353038002253353026333573466e3c0500040a009c4cd40cc01401c401c801d40b0024488cd54c02c480048d4d5408c00488cd54098008cd54c038480048d4d5409800488cd540a4008ccd4d540340048cc0e12000001223303900200123303800148000004cd54c02c480048d4d5408c00488cd54098008ccd4d540280048cd54c03c480048d4d5409c00488cd540a8008d5404400400488ccd5540200580080048cd54c03c480048d4d5409c00488cd540a8008d5403c004004ccd55400c044008004444888ccd54c018480054080cd54c02c480048d4d5408c00488cd54098008d54034004ccd54c0184800488d4d54090008894cd4c05cccd54c04048004c8cd405488ccd4d402c00c88008008004d4d402400488004cd4024894cd4c064008406c40040608d4d5409c00488cc028008014018400c4cd409001000d4084004cd54c02c480048d4d5408c00488c8cd5409c00cc004014c8004d540d8894cd4d40900044d5403400c884d4d540a4008894cd4c070cc0300080204cd5404801c0044c01800c00848848cc00400c00848004c8004d540b488448894cd4d40780044008884cc014008ccd54c01c480040140100044484888c00c01044884888cc0080140104484888c004010448004c8004d540a08844894cd4d406000454068884cd406cc010008cd54c01848004010004c8004d5409c88448894cd4d40600044d401800c884ccd4024014c010008ccd54c01c4800401401000448d4d400c0048800448d4d40080048800848848cc00400c0084800488ccd5cd19b8f002001006005222323230010053200135502522335350130014800088d4d54060008894cd4c02cccd5cd19b8f00200900d00c13007001130060033200135502422335350120014800088d4d5405c008894cd4c028ccd5cd19b8f00200700c00b10011300600312200212200120014881002212330010030022001222222222212333333333300100b00a009008007006005004003002200122123300100300220012221233300100400300220011122002122122330010040031200111221233001003002112001221233001003002200121223002003212230010032001222123330010040030022001121223002003112200112001122002122001200122337000040029040497a0088919180080091198019801001000a4411c28f07a93d7715db0bdc1766c8bd5b116602b105c02c54fc3bcd0d4680001").unwrap().clone(), + ).unwrap(); + assert_eq!(script.hash(), hash); +} + +#[test] +fn test_plutus_script_from_hex_with_version() { + let script_v1 = PlutusScript::from_hex_with_version( + "590e6f590e6c0100003323332223322333222332232332233223232333222323332223233333333222222223233322232333322223232332232323332223232332233223232333332222233223322332233223322332222323232232232325335303233300a3333573466e1cd55cea8042400046664446660a40060040026eb4d5d0a8041bae35742a00e66a05046666ae68cdc39aab9d37540029000102b11931a982599ab9c04f04c04a049357426ae89401c8c98d4c124cd5ce0268250240239999ab9a3370ea0089001102b11999ab9a3370ea00a9000102c11931a982519ab9c04e04b0490480473333573466e1cd55cea8012400046601a64646464646464646464646666ae68cdc39aab9d500a480008cccccccccc06ccd40a48c8c8cccd5cd19b8735573aa0049000119810981c9aba15002302e357426ae8940088c98d4c164cd5ce02e82d02c02b89aab9e5001137540026ae854028cd40a40a8d5d0a804999aa8183ae502f35742a010666aa060eb940bcd5d0a80399a8148211aba15006335029335505304b75a6ae854014c8c8c8cccd5cd19b8735573aa0049000119a8119919191999ab9a3370e6aae7540092000233502b33504175a6ae854008c118d5d09aba25002232635305d3357380c20bc0b80b626aae7940044dd50009aba150023232323333573466e1cd55cea80124000466a05266a082eb4d5d0a80118231aba135744a004464c6a60ba66ae7018417817016c4d55cf280089baa001357426ae8940088c98d4c164cd5ce02e82d02c02b89aab9e5001137540026ae854010cd40a5d71aba15003335029335505375c40026ae854008c0e0d5d09aba2500223263530553357380b20ac0a80a626ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba150023232323333573466e1d4005200623020303a357426aae79400c8cccd5cd19b875002480108c07cc110d5d09aab9e500423333573466e1d400d20022301f302f357426aae7940148cccd5cd19b875004480008c088dd71aba135573ca00c464c6a60a066ae7015014413c13813413012c4d55cea80089baa001357426ae8940088c98d4c124cd5ce026825024023882489931a982419ab9c4910350543500049047135573ca00226ea80044d55ce9baa001135744a00226aae7940044dd50009109198008018011000911111111109199999999980080580500480400380300280200180110009109198008018011000891091980080180109000891091980080180109000891091980080180109000909111180200290911118018029091111801002909111180080290008919118011bac0013200135503c2233335573e0024a01c466a01a60086ae84008c00cd5d100101811919191999ab9a3370e6aae75400d200023330073232323333573466e1cd55cea8012400046601a605c6ae854008cd404c0a8d5d09aba25002232635303433573807006a06606426aae7940044dd50009aba150033335500b75ca0146ae854008cd403dd71aba135744a004464c6a606066ae700d00c40bc0b84d5d1280089aab9e5001137540024442466600200800600440024424660020060044002266aa002eb9d6889119118011bab00132001355036223233335573e0044a012466a01066aa05c600c6aae754008c014d55cf280118021aba200302b1357420022244004244244660020080062400224464646666ae68cdc3a800a400046a05e600a6ae84d55cf280191999ab9a3370ea00490011281791931a981399ab9c02b028026025024135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011980318039aba15002375a6ae84d5d1280111931a981219ab9c028025023022135573ca00226ea80048848cc00400c00880048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98d4c080cd5ce01201080f80f09baa00112232323333573466e1d400520042500723333573466e1d4009200223500a3006357426aae7940108cccd5cd19b87500348000940288c98d4c08ccd5ce01381201101081000f89aab9d50011375400224244460060082244400422444002240024646666ae68cdc3a800a4004400c46666ae68cdc3a80124000400c464c6a603666ae7007c0700680640604d55ce9baa0011220021220012001232323232323333573466e1d4005200c200b23333573466e1d4009200a200d23333573466e1d400d200823300b375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c46601a6eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc048c050d5d0a8049bae357426ae8940248cccd5cd19b875006480088c050c054d5d09aab9e500b23333573466e1d401d2000230133016357426aae7940308c98d4c080cd5ce01201080f80f00e80e00d80d00c80c09aab9d5004135573ca00626aae7940084d55cf280089baa00121222222230070082212222222330060090082122222223005008122222220041222222200322122222223300200900822122222223300100900820012323232323333573466e1d400520022333008375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea00490001180518059aba135573ca00c464c6a602266ae7005404804003c0384d55cea80189aba25001135573ca00226ea80048488c00800c888488ccc00401401000c80048c8c8cccd5cd19b875001480088c018dd71aba135573ca00646666ae68cdc3a80124000460106eb8d5d09aab9e5004232635300b33573801e01801401201026aae7540044dd5000909118010019091180080190008891119191999ab9a3370e6aae75400920002335500b300635742a004600a6ae84d5d1280111931a980419ab9c00c009007006135573ca00226ea800526120012001112212330010030021120014910350543100222123330010040030022001121223002003112200112001120012001122002122001200111232300100122330033002002001332323233322233322233223332223322332233322233223322332233223233322232323322323232323333222232332232323222323222325335301a5335301a333573466e1cc8cccd54c05048004c8cd406488ccd406400c004008d4058004cd4060888c00cc008004800488cdc0000a40040029000199aa98068900091299a980e299a9a81a1a98169a98131a9812001110009110019119a98188011281c11a81c8009080f880e899a8148010008800a8141a981028009111111111005240040380362038266ae712413c53686f756c642062652065786163746c79206f6e652073637269707420696e70757420746f2061766f696420646f75626c65207361742069737375650001b15335303500315335301a5335301a333573466e20ccc064ccd54c03448005402540a0cc020d4c0c00188880094004074074cdc09a9818003111001a80200d80e080e099ab9c49010f73656c6c6572206e6f7420706169640001b15335301a333573466e20ccc064cc88ccd54c03c48005402d40a8cc028004009400401c074075401006c07040704cd5ce24810d66656573206e6f7420706169640001b101b15335301a3322353022002222222222253353503e33355301f1200133502322533535040002210031001503f253353027333573466e3c0300040a40a04d41040045410000c840a4409d4004d4c0c001888800840704cd5ce2491c4f6e6c792073656c6c65722063616e2063616e63656c206f666665720001b101b135301d00122002153353016333573466e2540040d406005c40d4540044cdc199b8235302b001222003480c920d00f2235301a0012222222222333553011120012235302a002222353034003223353038002253353026333573466e3c0500040a009c4cd40cc01401c401c801d40b0024488cd54c02c480048d4d5408c00488cd54098008cd54c038480048d4d5409800488cd540a4008ccd4d540340048cc0e12000001223303900200123303800148000004cd54c02c480048d4d5408c00488cd54098008ccd4d540280048cd54c03c480048d4d5409c00488cd540a8008d5404400400488ccd5540200580080048cd54c03c480048d4d5409c00488cd540a8008d5403c004004ccd55400c044008004444888ccd54c018480054080cd54c02c480048d4d5408c00488cd54098008d54034004ccd54c0184800488d4d54090008894cd4c05cccd54c04048004c8cd405488ccd4d402c00c88008008004d4d402400488004cd4024894cd4c064008406c40040608d4d5409c00488cc028008014018400c4cd409001000d4084004cd54c02c480048d4d5408c00488c8cd5409c00cc004014c8004d540d8894cd4d40900044d5403400c884d4d540a4008894cd4c070cc0300080204cd5404801c0044c01800c00848848cc00400c00848004c8004d540b488448894cd4d40780044008884cc014008ccd54c01c480040140100044484888c00c01044884888cc0080140104484888c004010448004c8004d540a08844894cd4d406000454068884cd406cc010008cd54c01848004010004c8004d5409c88448894cd4d40600044d401800c884ccd4024014c010008ccd54c01c4800401401000448d4d400c0048800448d4d40080048800848848cc00400c0084800488ccd5cd19b8f002001006005222323230010053200135502522335350130014800088d4d54060008894cd4c02cccd5cd19b8f00200900d00c13007001130060033200135502422335350120014800088d4d5405c008894cd4c028ccd5cd19b8f00200700c00b10011300600312200212200120014881002212330010030022001222222222212333333333300100b00a009008007006005004003002200122123300100300220012221233300100400300220011122002122122330010040031200111221233001003002112001221233001003002200121223002003212230010032001222123330010040030022001121223002003112200112001122002122001200122337000040029040497a0088919180080091198019801001000a4411c28f07a93d7715db0bdc1766c8bd5b116602b105c02c54fc3bcd0d4680001", + &Language::new_plutus_v1() + ).unwrap(); + assert_eq!(script_v1.language, Language::new_plutus_v1().0); + + let script_v2 = PlutusScript::from_hex_with_version( + "590e6f590e6c0100003323332223322333222332232332233223232333222323332223233333333222222223233322232333322223232332232323332223232332233223232333332222233223322332233223322332222323232232232325335303233300a3333573466e1cd55cea8042400046664446660a40060040026eb4d5d0a8041bae35742a00e66a05046666ae68cdc39aab9d37540029000102b11931a982599ab9c04f04c04a049357426ae89401c8c98d4c124cd5ce0268250240239999ab9a3370ea0089001102b11999ab9a3370ea00a9000102c11931a982519ab9c04e04b0490480473333573466e1cd55cea8012400046601a64646464646464646464646666ae68cdc39aab9d500a480008cccccccccc06ccd40a48c8c8cccd5cd19b8735573aa0049000119810981c9aba15002302e357426ae8940088c98d4c164cd5ce02e82d02c02b89aab9e5001137540026ae854028cd40a40a8d5d0a804999aa8183ae502f35742a010666aa060eb940bcd5d0a80399a8148211aba15006335029335505304b75a6ae854014c8c8c8cccd5cd19b8735573aa0049000119a8119919191999ab9a3370e6aae7540092000233502b33504175a6ae854008c118d5d09aba25002232635305d3357380c20bc0b80b626aae7940044dd50009aba150023232323333573466e1cd55cea80124000466a05266a082eb4d5d0a80118231aba135744a004464c6a60ba66ae7018417817016c4d55cf280089baa001357426ae8940088c98d4c164cd5ce02e82d02c02b89aab9e5001137540026ae854010cd40a5d71aba15003335029335505375c40026ae854008c0e0d5d09aba2500223263530553357380b20ac0a80a626ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba150023232323333573466e1d4005200623020303a357426aae79400c8cccd5cd19b875002480108c07cc110d5d09aab9e500423333573466e1d400d20022301f302f357426aae7940148cccd5cd19b875004480008c088dd71aba135573ca00c464c6a60a066ae7015014413c13813413012c4d55cea80089baa001357426ae8940088c98d4c124cd5ce026825024023882489931a982419ab9c4910350543500049047135573ca00226ea80044d55ce9baa001135744a00226aae7940044dd50009109198008018011000911111111109199999999980080580500480400380300280200180110009109198008018011000891091980080180109000891091980080180109000891091980080180109000909111180200290911118018029091111801002909111180080290008919118011bac0013200135503c2233335573e0024a01c466a01a60086ae84008c00cd5d100101811919191999ab9a3370e6aae75400d200023330073232323333573466e1cd55cea8012400046601a605c6ae854008cd404c0a8d5d09aba25002232635303433573807006a06606426aae7940044dd50009aba150033335500b75ca0146ae854008cd403dd71aba135744a004464c6a606066ae700d00c40bc0b84d5d1280089aab9e5001137540024442466600200800600440024424660020060044002266aa002eb9d6889119118011bab00132001355036223233335573e0044a012466a01066aa05c600c6aae754008c014d55cf280118021aba200302b1357420022244004244244660020080062400224464646666ae68cdc3a800a400046a05e600a6ae84d55cf280191999ab9a3370ea00490011281791931a981399ab9c02b028026025024135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011980318039aba15002375a6ae84d5d1280111931a981219ab9c028025023022135573ca00226ea80048848cc00400c00880048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98d4c080cd5ce01201080f80f09baa00112232323333573466e1d400520042500723333573466e1d4009200223500a3006357426aae7940108cccd5cd19b87500348000940288c98d4c08ccd5ce01381201101081000f89aab9d50011375400224244460060082244400422444002240024646666ae68cdc3a800a4004400c46666ae68cdc3a80124000400c464c6a603666ae7007c0700680640604d55ce9baa0011220021220012001232323232323333573466e1d4005200c200b23333573466e1d4009200a200d23333573466e1d400d200823300b375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c46601a6eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc048c050d5d0a8049bae357426ae8940248cccd5cd19b875006480088c050c054d5d09aab9e500b23333573466e1d401d2000230133016357426aae7940308c98d4c080cd5ce01201080f80f00e80e00d80d00c80c09aab9d5004135573ca00626aae7940084d55cf280089baa00121222222230070082212222222330060090082122222223005008122222220041222222200322122222223300200900822122222223300100900820012323232323333573466e1d400520022333008375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea00490001180518059aba135573ca00c464c6a602266ae7005404804003c0384d55cea80189aba25001135573ca00226ea80048488c00800c888488ccc00401401000c80048c8c8cccd5cd19b875001480088c018dd71aba135573ca00646666ae68cdc3a80124000460106eb8d5d09aab9e5004232635300b33573801e01801401201026aae7540044dd5000909118010019091180080190008891119191999ab9a3370e6aae75400920002335500b300635742a004600a6ae84d5d1280111931a980419ab9c00c009007006135573ca00226ea800526120012001112212330010030021120014910350543100222123330010040030022001121223002003112200112001120012001122002122001200111232300100122330033002002001332323233322233322233223332223322332233322233223322332233223233322232323322323232323333222232332232323222323222325335301a5335301a333573466e1cc8cccd54c05048004c8cd406488ccd406400c004008d4058004cd4060888c00cc008004800488cdc0000a40040029000199aa98068900091299a980e299a9a81a1a98169a98131a9812001110009110019119a98188011281c11a81c8009080f880e899a8148010008800a8141a981028009111111111005240040380362038266ae712413c53686f756c642062652065786163746c79206f6e652073637269707420696e70757420746f2061766f696420646f75626c65207361742069737375650001b15335303500315335301a5335301a333573466e20ccc064ccd54c03448005402540a0cc020d4c0c00188880094004074074cdc09a9818003111001a80200d80e080e099ab9c49010f73656c6c6572206e6f7420706169640001b15335301a333573466e20ccc064cc88ccd54c03c48005402d40a8cc028004009400401c074075401006c07040704cd5ce24810d66656573206e6f7420706169640001b101b15335301a3322353022002222222222253353503e33355301f1200133502322533535040002210031001503f253353027333573466e3c0300040a40a04d41040045410000c840a4409d4004d4c0c001888800840704cd5ce2491c4f6e6c792073656c6c65722063616e2063616e63656c206f666665720001b101b135301d00122002153353016333573466e2540040d406005c40d4540044cdc199b8235302b001222003480c920d00f2235301a0012222222222333553011120012235302a002222353034003223353038002253353026333573466e3c0500040a009c4cd40cc01401c401c801d40b0024488cd54c02c480048d4d5408c00488cd54098008cd54c038480048d4d5409800488cd540a4008ccd4d540340048cc0e12000001223303900200123303800148000004cd54c02c480048d4d5408c00488cd54098008ccd4d540280048cd54c03c480048d4d5409c00488cd540a8008d5404400400488ccd5540200580080048cd54c03c480048d4d5409c00488cd540a8008d5403c004004ccd55400c044008004444888ccd54c018480054080cd54c02c480048d4d5408c00488cd54098008d54034004ccd54c0184800488d4d54090008894cd4c05cccd54c04048004c8cd405488ccd4d402c00c88008008004d4d402400488004cd4024894cd4c064008406c40040608d4d5409c00488cc028008014018400c4cd409001000d4084004cd54c02c480048d4d5408c00488c8cd5409c00cc004014c8004d540d8894cd4d40900044d5403400c884d4d540a4008894cd4c070cc0300080204cd5404801c0044c01800c00848848cc00400c00848004c8004d540b488448894cd4d40780044008884cc014008ccd54c01c480040140100044484888c00c01044884888cc0080140104484888c004010448004c8004d540a08844894cd4d406000454068884cd406cc010008cd54c01848004010004c8004d5409c88448894cd4d40600044d401800c884ccd4024014c010008ccd54c01c4800401401000448d4d400c0048800448d4d40080048800848848cc00400c0084800488ccd5cd19b8f002001006005222323230010053200135502522335350130014800088d4d54060008894cd4c02cccd5cd19b8f00200900d00c13007001130060033200135502422335350120014800088d4d5405c008894cd4c028ccd5cd19b8f00200700c00b10011300600312200212200120014881002212330010030022001222222222212333333333300100b00a009008007006005004003002200122123300100300220012221233300100400300220011122002122122330010040031200111221233001003002112001221233001003002200121223002003212230010032001222123330010040030022001121223002003112200112001122002122001200122337000040029040497a0088919180080091198019801001000a4411c28f07a93d7715db0bdc1766c8bd5b116602b105c02c54fc3bcd0d4680001", + &Language::new_plutus_v2() + ).unwrap(); + assert_eq!(script_v2.language, Language::new_plutus_v2().0); +} + +fn redeemer_with_ex_units(mem: &BigNum, steps: &BigNum) -> Redeemer { + Redeemer::new( + &RedeemerTag::new_spend(), + &BigNum::zero(), + &PlutusData::new_integer(&BigInt::from_str("0").unwrap()), + &ExUnits::new(mem, steps), + ) +} + +#[test] +fn test_total_ex_units() { + let mut r = Redeemers::new(); + + fn assert_ex_units(eu: &ExUnits, exp_mem: u64, exp_steps: u64) { + assert_eq!(eu.mem, to_bignum(exp_mem)); + assert_eq!(eu.steps, to_bignum(exp_steps)); + } + + r.add(&redeemer_with_ex_units(&to_bignum(10), &to_bignum(100))); + assert_ex_units(&r.total_ex_units().unwrap(), 10, 100); + r.add(&redeemer_with_ex_units(&to_bignum(20), &to_bignum(200))); + assert_ex_units(&r.total_ex_units().unwrap(), 30, 300); + r.add(&redeemer_with_ex_units(&to_bignum(30), &to_bignum(300))); + assert_ex_units(&r.total_ex_units().unwrap(), 60, 600); +} + +#[test] +fn test_empty_constr_data() { + assert_eq!( + PlutusData::new_empty_constr_plutus_data(&BigNum::one()), + PlutusData::new_constr_plutus_data(&ConstrPlutusData::new( + &BigNum::from_str("1").unwrap(), + &PlutusList::new(), + ),), + ) +} + +#[test] +fn test_plutus_script_version() { + let bytes = hex::decode("4e4d01000033222220051200120011").unwrap(); + let s1: PlutusScript = PlutusScript::from_bytes(bytes.clone()).unwrap(); + let s2: PlutusScript = PlutusScript::from_bytes_v2(bytes.clone()).unwrap(); + let s3: PlutusScript = PlutusScript::from_bytes_v3(bytes.clone()).unwrap(); + + assert_eq!(s1.bytes(), bytes[1..]); + assert_eq!(s2.bytes(), bytes[1..]); + assert_eq!(s3.bytes(), bytes[1..]); + assert_eq!(s1.language_version(), Language::new_plutus_v1()); + assert_eq!(s2.language_version(), Language::new_plutus_v2()); + assert_eq!(s3.language_version(), Language::new_plutus_v3()); + + assert_eq!( + s1, + PlutusScript::from_bytes_with_version(bytes.clone(), &Language::new_plutus_v1(),).unwrap() + ); + assert_eq!( + s2, + PlutusScript::from_bytes_with_version(bytes.clone(), &Language::new_plutus_v2(),).unwrap() + ); + assert_eq!( + s3, + PlutusScript::from_bytes_with_version(bytes.clone(), &Language::new_plutus_v3(),).unwrap() + ); +} + +#[test] +fn test_language_roundtrip() { + fn deserialize_language_from_uint(x: u64) -> Result { + let mut buf = Serializer::new_vec(); + x.serialize(&mut buf).unwrap(); + Language::from_bytes(buf.finalize()) + } + + assert_eq!( + deserialize_language_from_uint(0).unwrap(), + Language::new_plutus_v1() + ); + assert_eq!( + deserialize_language_from_uint(1).unwrap(), + Language::new_plutus_v2() + ); + assert_eq!( + deserialize_language_from_uint(2).unwrap(), + Language::new_plutus_v3() + ); + assert!(deserialize_language_from_uint(3).is_err()); + + assert_eq!( + Language::from_bytes(Language::new_plutus_v1().to_bytes()).unwrap(), + Language::new_plutus_v1(), + ); + assert_eq!( + Language::from_bytes(Language::new_plutus_v2().to_bytes()).unwrap(), + Language::new_plutus_v2(), + ); + assert_eq!( + Language::from_bytes(Language::new_plutus_v3().to_bytes()).unwrap(), + Language::new_plutus_v3(), + ); +} + +#[test] +fn test_cost_model_roundtrip() { + use crate::TxBuilderConstants; + let costmodels = TxBuilderConstants::plutus_vasil_cost_models(); + assert_eq!( + costmodels, + Costmdls::from_bytes(costmodels.to_bytes()).unwrap() + ); +} + +#[test] +fn test_known_plutus_data_hash() { + use crate::TxBuilderConstants; + let pdata = PlutusList::from(vec![PlutusData::new_constr_plutus_data( + &ConstrPlutusData::new( + &BigNum::zero(), + &PlutusList::from(vec![ + PlutusData::new_constr_plutus_data(&ConstrPlutusData::new( + &BigNum::zero(), + &PlutusList::from(vec![ + PlutusData::new_bytes( + hex::decode("A183BF86925F66C579A3745C9517744399679B090927B8F6E2F2E1BB") + .unwrap(), + ), + PlutusData::new_bytes( + hex::decode("6164617065416D616E734576616E73").unwrap(), + ), + ]), + )), + PlutusData::new_constr_plutus_data(&ConstrPlutusData::new( + &BigNum::zero(), + &PlutusList::from(vec![ + PlutusData::new_bytes( + hex::decode("9A4E855293A0B9AF5E50935A331D83E7982AB5B738EA0E6FC0F9E656") + .unwrap(), + ), + PlutusData::new_bytes(hex::decode("4652414D455F38333030325F4C30").unwrap()), + ]), + )), + PlutusData::new_bytes( + hex::decode("BEA1C521DF58F4EEEF60C647E5EBD88C6039915409F9FD6454A476B9") + .unwrap(), + ), + ]), + ), + )]); + let redeemers = Redeemers(vec![Redeemer::new( + &RedeemerTag::new_spend(), + &BigNum::one(), + &PlutusData::new_empty_constr_plutus_data(&BigNum::zero()), + &ExUnits::new(&to_bignum(7000000), &to_bignum(3000000000)), + )]); + let lang = Language::new_plutus_v1(); + let lang_costmodel = TxBuilderConstants::plutus_vasil_cost_models() + .get(&lang) + .unwrap(); + let mut retained_cost_models = Costmdls::new(); + retained_cost_models.insert(&lang, &lang_costmodel); + let hash = hash_script_data(&redeemers, &retained_cost_models, Some(pdata)); + assert_eq!( + hex::encode(hash.to_bytes()), + "2fd8b7e248b376314d02989c885c278796ab0e1d6e8aa0cb91f562ff5f7dbd70" + ); +} + +#[test] +fn test_same_datum_in_different_formats_with_expected_hashes() { + // This is a known datum with indefinite arrays and a known expected hash + let pdata1 = PlutusData::from_bytes(hex::decode("d8799fd8799f581ca183bf86925f66c579a3745c9517744399679b090927b8f6e2f2e1bb4f616461706541696c656e416d61746fffd8799f581c9a4e855293a0b9af5e50935a331d83e7982ab5b738ea0e6fc0f9e6564e4652414d455f36353030335f4c30ff581cbea1c521df58f4eeef60c647e5ebd88c6039915409f9fd6454a476b9ff").unwrap()).unwrap(); + assert_eq!( + hex::encode(hash_plutus_data(&pdata1).to_bytes()), + "ec3028f46325b983a470893a8bdc1b4a100695b635fb1237d301c3490b23e89b" + ); + // This is the same exact datum manually converted to definite arrays + // and it produces a different known expected hash because the format is preserved after deserialization + let pdata2 = PlutusData::from_bytes(hex::decode("d87983d87982581ca183bf86925f66c579a3745c9517744399679b090927b8f6e2f2e1bb4f616461706541696c656e416d61746fd87982581c9a4e855293a0b9af5e50935a331d83e7982ab5b738ea0e6fc0f9e6564e4652414d455f36353030335f4c30581cbea1c521df58f4eeef60c647e5ebd88c6039915409f9fd6454a476b9").unwrap()).unwrap(); + assert_eq!( + hex::encode(hash_plutus_data(&pdata2).to_bytes()), + "816cdf6d4d8cba3ad0188ca643db95ddf0e03cdfc0e75a9550a72a82cb146222" + ); +} + +#[test] +fn test_known_plutus_data_hash_with_no_datums() { + let mut costmodels = Costmdls::new(); + costmodels.insert( + &Language::new_plutus_v2(), + &TxBuilderConstants::plutus_vasil_cost_models() + .get(&Language::new_plutus_v2()) + .unwrap(), + ); + let hash = hash_script_data( + &Redeemers(vec![Redeemer::new( + &RedeemerTag::new_spend(), + &BigNum::zero(), + &PlutusData::new_empty_constr_plutus_data(&BigNum::zero()), + &ExUnits::new(&to_bignum(842996), &to_bignum(246100241)), + )]), + &costmodels, + None, + ); + assert_eq!( + hex::encode(hash.to_bytes()), + "6b244f15f895fd458a02bef3a8b56f17f24150fddcb06be482f8790a600578a1" + ); +} + +#[test] +fn test_known_plutus_data_hash_2() { + let datums = PlutusList::from(vec![PlutusData::new_constr_plutus_data( + &ConstrPlutusData::new( + &BigNum::zero(), + &PlutusList::from(vec![ + PlutusData::new_bytes( + hex::decode("45F6A506A49A38263C4A8BBB2E1E369DD8732FB1F9A281F3E8838387") + .unwrap(), + ), + PlutusData::new_integer(&BigInt::from_str("60000000").unwrap()), + PlutusData::new_bytes( + hex::decode("EE8E37676F6EBB8E031DFF493F88FF711D24AA68666A09D61F1D3FB3") + .unwrap(), + ), + PlutusData::new_bytes(hex::decode("43727970746F44696E6F3036333039").unwrap()), + ]), + ), + )]); + let redeemers = Redeemers(vec![Redeemer::new( + &RedeemerTag::new_spend(), + &BigNum::one(), + &PlutusData::new_empty_constr_plutus_data(&BigNum::one()), + &ExUnits::new(&to_bignum(61300), &to_bignum(18221176)), + )]); + let hash = hash_script_data( + &redeemers, + &TxBuilderConstants::plutus_vasil_cost_models() + .retain_language_versions(&Languages(vec![Language::new_plutus_v1()])), + Some(datums), + ); + assert_eq!( + hex::encode(hash.to_bytes()), + "0a076247a05aacbecf72ea15b94e3d0331b21295a08d9ab7b8675c13840563a6" + ); +} + +#[test] +fn datum_from_enterprise_key_address() { + let address = + Address::from_bech32("addr1vxy2c673nsdp0mvgq5d3tpjndngucsytug00k7k6xwlx4lg6dspk5").unwrap(); + let datum = PlutusData::from_address(&address).unwrap(); + let orig_datum = PlutusData::from_json("{\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"bytes\": \"88ac6bd19c1a17ed88051b1586536cd1cc408be21efb7ada33be6afd\"}]}, {\"constructor\": 1, \"fields\": []}]}", + PlutusDatumSchema::DetailedSchema).unwrap(); + assert_eq!(datum, orig_datum); +} + +#[test] +fn datum_from_enterprise_script_address() { + let address = + Address::from_bech32("addr1w8wrk560wcsldjpnqjamn8s0gn9pdrplpyetrdfpacqrpfs3xezd8").unwrap(); + let datum = PlutusData::from_address(&address).unwrap(); + let orig_datum = PlutusData::from_json("{\"constructor\": 0, \"fields\": [{\"constructor\": 1, \"fields\": [{\"bytes\": \"dc3b534f7621f6c83304bbb99e0f44ca168c3f0932b1b521ee0030a6\"}]}, {\"constructor\": 1, \"fields\": []}]}", + PlutusDatumSchema::DetailedSchema).unwrap(); + assert_eq!(datum, orig_datum); +} + +#[test] +fn datum_from_base_key_key_address() { + let address = Address::from_bech32("addr1qxy2c673nsdp0mvgq5d3tpjndngucsytug00k7k6xwlx4lvg434ar8q6zlkcspgmzkr9xmx3e3qghcs7ldad5va7dt7s5efyer").unwrap(); + let datum = PlutusData::from_address(&address).unwrap(); + let orig_datum = PlutusData::from_json("{\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"bytes\": \"88ac6bd19c1a17ed88051b1586536cd1cc408be21efb7ada33be6afd\"}]}, {\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"bytes\": \"88ac6bd19c1a17ed88051b1586536cd1cc408be21efb7ada33be6afd\"}]}]}]}]}", + PlutusDatumSchema::DetailedSchema).unwrap(); + assert_eq!(datum, orig_datum); +} + +#[test] +fn datum_from_base_script_script_address() { + let address = Address::from_bech32("addr1x8wrk560wcsldjpnqjamn8s0gn9pdrplpyetrdfpacqrpfku8df57a3p7myrxp9mhx0q73x2z6xr7zfjkx6jrmsqxznqh8u5dz").unwrap(); + let datum = PlutusData::from_address(&address).unwrap(); + let orig_datum = PlutusData::from_json("{\"constructor\": 0, \"fields\": [{\"constructor\": 1, \"fields\": [{\"bytes\": \"dc3b534f7621f6c83304bbb99e0f44ca168c3f0932b1b521ee0030a6\"}]}, {\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"constructor\": 1, \"fields\": [{\"bytes\": \"dc3b534f7621f6c83304bbb99e0f44ca168c3f0932b1b521ee0030a6\"}]}]}]}]}", + PlutusDatumSchema::DetailedSchema).unwrap(); + assert_eq!(datum, orig_datum); +} + +#[test] +fn datum_from_base_script_key_address() { + let address = Address::from_bech32("addr1z8wrk560wcsldjpnqjamn8s0gn9pdrplpyetrdfpacqrpf5g434ar8q6zlkcspgmzkr9xmx3e3qghcs7ldad5va7dt7sqx2wxh").unwrap(); + let datum = PlutusData::from_address(&address).unwrap(); + let orig_datum = PlutusData::from_json("{\"constructor\": 0, \"fields\": [{\"constructor\": 1, \"fields\": [{\"bytes\": \"dc3b534f7621f6c83304bbb99e0f44ca168c3f0932b1b521ee0030a6\"}]}, {\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"bytes\": \"88ac6bd19c1a17ed88051b1586536cd1cc408be21efb7ada33be6afd\"}]}]}]}]}", + PlutusDatumSchema::DetailedSchema).unwrap(); + assert_eq!(datum, orig_datum); +} + +#[test] +fn datum_from_base_key_script_address() { + let address = Address::from_bech32("addr1yxy2c673nsdp0mvgq5d3tpjndngucsytug00k7k6xwlx4lwu8df57a3p7myrxp9mhx0q73x2z6xr7zfjkx6jrmsqxznqrcl7jk").unwrap(); + let datum = PlutusData::from_address(&address).unwrap(); + let orig_datum = PlutusData::from_json("{\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"bytes\": \"88ac6bd19c1a17ed88051b1586536cd1cc408be21efb7ada33be6afd\"}]}, {\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"constructor\": 1, \"fields\": [{\"bytes\": \"dc3b534f7621f6c83304bbb99e0f44ca168c3f0932b1b521ee0030a6\"}]}]}]}]}", + PlutusDatumSchema::DetailedSchema).unwrap(); + assert_eq!(datum, orig_datum); +} From 8fff6d5101c29b77f9b49d9d89ac3fcd6aac1db1 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 10 Sep 2023 03:19:51 +0500 Subject: [PATCH 137/349] add new field to tx body and params update --- rust/src/builders/tx_builder.rs | 34 +- rust/src/fakes.rs | 12 +- rust/src/lib.rs | 549 +--------- rust/src/protocol_types/mod.rs | 6 + .../protocol_types/protocol_param_update.rs | 552 ++++++++++ rust/src/protocol_types/transaction_body.rs | 297 ++++++ rust/src/serialization/general.rs | 988 ------------------ rust/src/serialization/mod.rs | 4 +- .../serialization/protocol_param_update.rs | 864 +++++++++++++++ rust/src/serialization/transaction_body.rs | 462 ++++++++ rust/src/tests/builders/tx_builder.rs | 62 +- rust/src/tests/mock_objects.rs | 32 + rust/src/tests/serialization/mod.rs | 2 + .../serialization/protocol_param_update.rs | 117 +++ .../tests/serialization/transaction_body.rs | 44 + rust/src/utils.rs | 2 +- 16 files changed, 2479 insertions(+), 1548 deletions(-) create mode 100644 rust/src/protocol_types/protocol_param_update.rs create mode 100644 rust/src/protocol_types/transaction_body.rs create mode 100644 rust/src/serialization/protocol_param_update.rs create mode 100644 rust/src/serialization/transaction_body.rs create mode 100644 rust/src/tests/serialization/protocol_param_update.rs create mode 100644 rust/src/tests/serialization/transaction_body.rs diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index f65548ac..66428cf9 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -345,6 +345,8 @@ pub struct TransactionBuilder { pub(crate) extra_datums: Option, pub(crate) voting_procedures: Option, pub(crate) voting_proposals: Option, + pub(crate) current_treasury_value: Option, + pub(crate) donation: Option, } #[wasm_bindgen] @@ -1266,6 +1268,26 @@ impl TransactionBuilder { self.extra_datums.clone() } + pub fn set_donation(&mut self, donation: &Coin) { + self.donation = Some(donation.clone()); + } + + pub fn get_donation(&self) -> Option { + self.donation.clone() + } + + pub fn set_current_treasury_value(&mut self, current_treasury_value: &Coin) -> Result<(), JsError> { + if current_treasury_value == &Coin::zero() { + return Err(JsError::from_str("Current treasury value cannot be zero!")); + } + self.current_treasury_value = Some(current_treasury_value.clone()); + Ok(()) + } + + pub fn get_current_treasury_value(&self) -> Option { + self.current_treasury_value.clone() + } + pub fn new(cfg: &TransactionBuilderConfig) -> Self { Self { config: cfg.clone(), @@ -1287,6 +1309,8 @@ impl TransactionBuilder { extra_datums: None, voting_procedures: None, voting_proposals: None, + donation: None, + current_treasury_value: None, } } @@ -1379,9 +1403,13 @@ impl TransactionBuilder { /// Return explicit output plus deposit plus burn pub fn get_total_output(&self) -> Result { let (_, burn_value) = self.get_mint_as_values(); - self.get_explicit_output()? + let mut total = self.get_explicit_output()? .checked_add(&Value::new(&self.get_deposit()?))? - .checked_add(&burn_value) + .checked_add(&burn_value)?; + if let Some(donation) = &self.donation { + total = total.checked_add(&Value::new(donation))?; + } + Ok(total) } /// does not include fee @@ -1928,6 +1956,8 @@ impl TransactionBuilder { reference_inputs: self.get_reference_inputs().to_option(), voting_procedures: self.voting_procedures.as_ref().map(|x| x.build()), voting_proposals: self.voting_proposals.as_ref().map(|x| x.build()), + donation: self.donation.clone(), + current_treasury_value: self.current_treasury_value.clone(), }; // we must build a tx with fake data (of correct size) to check the final Transaction size let full_tx = fake_full_tx(self, built)?; diff --git a/rust/src/fakes.rs b/rust/src/fakes.rs index 9f72819f..1228b08c 100644 --- a/rust/src/fakes.rs +++ b/rust/src/fakes.rs @@ -1,7 +1,5 @@ #![allow(dead_code)] -use crate::crypto::{ - AnchorDataHash, GenesisDelegateHash, GenesisHash, PoolMetadataHash, ScriptHash, VRFKeyHash, -}; +use crate::crypto::{AnchorDataHash, AuxiliaryDataHash, GenesisDelegateHash, GenesisHash, PoolMetadataHash, ScriptDataHash, ScriptHash, VRFKeyHash}; use crate::{ to_bignum, Address, BaseAddress, Bip32PrivateKey, Credential, DataHash, Ed25519KeyHash, Ed25519Signature, NetworkInfo, PolicyID, TransactionHash, TransactionIndex, TransactionInput, @@ -23,6 +21,10 @@ pub(crate) fn fake_anchor_data_hash(x: u8) -> AnchorDataHash { AnchorDataHash::from_bytes(fake_bytes_32(x)).unwrap() } +pub(crate) fn fake_auxiliary_data_hash(x: u8) -> AuxiliaryDataHash { + AuxiliaryDataHash::from_bytes(fake_bytes_32(x)).unwrap() +} + pub(crate) fn fake_pool_metadata_hash(x: u8) -> PoolMetadataHash { PoolMetadataHash::from_bytes(fake_bytes_32(x)).unwrap() } @@ -47,6 +49,10 @@ pub(crate) fn fake_script_hash(x: u8) -> ScriptHash { ScriptHash::from_bytes((&fake_bytes_32(x)[0..28]).to_vec()).unwrap() } +pub(crate) fn fake_script_data_hash(x: u8) -> ScriptDataHash { + ScriptDataHash::from_bytes(fake_bytes_32(x)).unwrap() +} + pub(crate) fn fake_base_address(x: u8) -> Address { BaseAddress::new( NetworkInfo::testnet().network_id(), diff --git a/rust/src/lib.rs b/rust/src/lib.rs index d3582e44..ec8cfccd 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -84,6 +84,7 @@ type DeltaCoin = Int; Ord, PartialEq, PartialOrd, + Default, serde::Serialize, serde::Deserialize, JsonSchema, @@ -294,282 +295,6 @@ impl From<&Ed25519KeyHashes> for RequiredSignersSet { } } -#[wasm_bindgen] -#[derive(Clone, Eq, PartialEq, Debug, serde::Serialize, serde::Deserialize, JsonSchema)] -pub struct TransactionBody { - inputs: TransactionInputs, - outputs: TransactionOutputs, - fee: Coin, - ttl: Option, - certs: Option, - withdrawals: Option, - update: Option, - auxiliary_data_hash: Option, - validity_start_interval: Option, - mint: Option, - script_data_hash: Option, - collateral: Option, - required_signers: Option, - network_id: Option, - collateral_return: Option, - total_collateral: Option, - reference_inputs: Option, - voting_procedures: Option, - voting_proposals: Option, -} - -impl_to_from!(TransactionBody); - -#[wasm_bindgen] -impl TransactionBody { - pub fn inputs(&self) -> TransactionInputs { - self.inputs.clone() - } - - pub fn outputs(&self) -> TransactionOutputs { - self.outputs.clone() - } - - pub fn fee(&self) -> Coin { - self.fee.clone() - } - - /// !!! DEPRECATED !!! - /// Returns a Slot32 (u32) value in case the underlying original BigNum (u64) value is within the limits. - /// Otherwise will just raise an error. - #[deprecated( - since = "10.1.0", - note = "Possible boundary error. Use ttl_bignum instead" - )] - pub fn ttl(&self) -> Result, JsError> { - match self.ttl { - Some(ttl) => match ttl.try_into() { - Ok(ttl32) => Ok(Some(ttl32)), - Err(err) => Err(err), - }, - None => Ok(None), - } - } - - pub fn ttl_bignum(&self) -> Option { - self.ttl - } - - pub fn set_ttl(&mut self, ttl: &SlotBigNum) { - self.ttl = Some(ttl.clone()) - } - - pub fn remove_ttl(&mut self) { - self.ttl = None - } - - pub fn set_certs(&mut self, certs: &Certificates) { - self.certs = Some(certs.clone()) - } - - pub fn certs(&self) -> Option { - self.certs.clone() - } - - pub fn set_withdrawals(&mut self, withdrawals: &Withdrawals) { - self.withdrawals = Some(withdrawals.clone()) - } - - pub fn withdrawals(&self) -> Option { - self.withdrawals.clone() - } - - pub fn set_update(&mut self, update: &Update) { - self.update = Some(update.clone()) - } - - pub fn update(&self) -> Option { - self.update.clone() - } - - pub fn set_auxiliary_data_hash(&mut self, auxiliary_data_hash: &AuxiliaryDataHash) { - self.auxiliary_data_hash = Some(auxiliary_data_hash.clone()) - } - - pub fn auxiliary_data_hash(&self) -> Option { - self.auxiliary_data_hash.clone() - } - - /// !!! DEPRECATED !!! - /// Uses outdated slot number format. - #[deprecated( - since = "10.1.0", - note = "Underlying value capacity of slot (BigNum u64) bigger then Slot32. Use set_validity_start_interval_bignum instead." - )] - pub fn set_validity_start_interval(&mut self, validity_start_interval: Slot32) { - self.validity_start_interval = Some(validity_start_interval.into()) - } - - pub fn set_validity_start_interval_bignum(&mut self, validity_start_interval: SlotBigNum) { - self.validity_start_interval = Some(validity_start_interval.clone()) - } - - pub fn validity_start_interval_bignum(&self) -> Option { - self.validity_start_interval.clone() - } - - /// !!! DEPRECATED !!! - /// Returns a Option (u32) value in case the underlying original Option (u64) value is within the limits. - /// Otherwise will just raise an error. - /// Use `.validity_start_interval_bignum` instead. - #[deprecated( - since = "10.1.0", - note = "Possible boundary error. Use validity_start_interval_bignum instead" - )] - pub fn validity_start_interval(&self) -> Result, JsError> { - match self.validity_start_interval.clone() { - Some(interval) => match interval.try_into() { - Ok(internal32) => Ok(Some(internal32)), - Err(err) => Err(err), - }, - None => Ok(None), - } - } - - pub fn set_mint(&mut self, mint: &Mint) { - self.mint = Some(mint.clone()) - } - - pub fn mint(&self) -> Option { - self.mint.clone() - } - - /// This function returns the mint value of the transaction - /// Use `.mint()` instead. - #[deprecated(since = "10.0.0", note = "Weird naming. Use `.mint()`")] - pub fn multiassets(&self) -> Option { - self.mint() - } - - pub fn set_reference_inputs(&mut self, reference_inputs: &TransactionInputs) { - self.reference_inputs = Some(reference_inputs.clone()) - } - - pub fn reference_inputs(&self) -> Option { - self.reference_inputs.clone() - } - - pub fn set_script_data_hash(&mut self, script_data_hash: &ScriptDataHash) { - self.script_data_hash = Some(script_data_hash.clone()) - } - - pub fn script_data_hash(&self) -> Option { - self.script_data_hash.clone() - } - - pub fn set_collateral(&mut self, collateral: &TransactionInputs) { - self.collateral = Some(collateral.clone()) - } - - pub fn collateral(&self) -> Option { - self.collateral.clone() - } - - pub fn set_required_signers(&mut self, required_signers: &RequiredSigners) { - self.required_signers = Some(required_signers.clone()) - } - - pub fn required_signers(&self) -> Option { - self.required_signers.clone() - } - - pub fn set_network_id(&mut self, network_id: &NetworkId) { - self.network_id = Some(network_id.clone()) - } - - pub fn network_id(&self) -> Option { - self.network_id.clone() - } - - pub fn set_collateral_return(&mut self, collateral_return: &TransactionOutput) { - self.collateral_return = Some(collateral_return.clone()); - } - - pub fn collateral_return(&self) -> Option { - self.collateral_return.clone() - } - - pub fn set_total_collateral(&mut self, total_collateral: &Coin) { - self.total_collateral = Some(total_collateral.clone()); - } - - pub fn total_collateral(&self) -> Option { - self.total_collateral.clone() - } - - pub fn set_voting_procedures(&mut self, voting_procedures: &VotingProcedures) { - self.voting_procedures = Some(voting_procedures.clone()); - } - - pub fn voting_procedures(&self) -> Option { - self.voting_procedures.clone() - } - - pub fn set_voting_proposals(&mut self, voting_proposals: &VotingProposals) { - self.voting_proposals = Some(voting_proposals.clone()); - } - - pub fn voting_proposals(&self) -> Option { - self.voting_proposals.clone() - } - - /// !!! DEPRECATED !!! - /// This constructor uses outdated slot number format for the ttl value. - /// Use `.new_tx_body` and then `.set_ttl` instead - #[deprecated( - since = "10.1.0", - note = "Underlying value capacity of ttl (BigNum u64) bigger then Slot32. Use new_tx_body instead." - )] - pub fn new( - inputs: &TransactionInputs, - outputs: &TransactionOutputs, - fee: &Coin, - ttl: Option, - ) -> Self { - let mut tx = Self::new_tx_body(inputs, outputs, fee); - if let Some(slot32) = ttl { - tx.set_ttl(&to_bignum(slot32 as u64)); - } - tx - } - - /// Returns a new TransactionBody. - /// In the new version of "new" we removed optional ttl for support it by wasm_bingen. - /// Your can use "set_ttl" and "remove_ttl" to set a new value for ttl or set it as None. - pub fn new_tx_body( - inputs: &TransactionInputs, - outputs: &TransactionOutputs, - fee: &Coin, - ) -> Self { - Self { - inputs: inputs.clone(), - outputs: outputs.clone(), - fee: fee.clone(), - ttl: None, - certs: None, - withdrawals: None, - update: None, - auxiliary_data_hash: None, - validity_start_interval: None, - mint: None, - script_data_hash: None, - collateral: None, - required_signers: None, - network_id: None, - collateral_return: None, - total_collateral: None, - reference_inputs: None, - voting_procedures: None, - voting_proposals: None, - } - } -} - #[wasm_bindgen] #[derive( Clone, @@ -2056,278 +1781,6 @@ impl ProtocolVersion { } } -#[wasm_bindgen] -#[derive( - Clone, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub struct ProtocolParamUpdate { - minfee_a: Option, - minfee_b: Option, - max_block_body_size: Option, - max_tx_size: Option, - max_block_header_size: Option, - key_deposit: Option, - pool_deposit: Option, - max_epoch: Option, - // desired number of stake pools - n_opt: Option, - pool_pledge_influence: Option, - expansion_rate: Option, - treasury_growth_rate: Option, - // decentralization constant - d: Option, - extra_entropy: Option, - protocol_version: Option, - min_pool_cost: Option, - ada_per_utxo_byte: Option, - cost_models: Option, - execution_costs: Option, - max_tx_ex_units: Option, - max_block_ex_units: Option, - max_value_size: Option, - collateral_percentage: Option, - max_collateral_inputs: Option, -} - -impl_to_from!(ProtocolParamUpdate); - -#[wasm_bindgen] -impl ProtocolParamUpdate { - pub fn set_minfee_a(&mut self, minfee_a: &Coin) { - self.minfee_a = Some(minfee_a.clone()) - } - - pub fn minfee_a(&self) -> Option { - self.minfee_a.clone() - } - - pub fn set_minfee_b(&mut self, minfee_b: &Coin) { - self.minfee_b = Some(minfee_b.clone()) - } - - pub fn minfee_b(&self) -> Option { - self.minfee_b.clone() - } - - pub fn set_max_block_body_size(&mut self, max_block_body_size: u32) { - self.max_block_body_size = Some(max_block_body_size) - } - - pub fn max_block_body_size(&self) -> Option { - self.max_block_body_size.clone() - } - - pub fn set_max_tx_size(&mut self, max_tx_size: u32) { - self.max_tx_size = Some(max_tx_size) - } - - pub fn max_tx_size(&self) -> Option { - self.max_tx_size.clone() - } - - pub fn set_max_block_header_size(&mut self, max_block_header_size: u32) { - self.max_block_header_size = Some(max_block_header_size) - } - - pub fn max_block_header_size(&self) -> Option { - self.max_block_header_size.clone() - } - - pub fn set_key_deposit(&mut self, key_deposit: &Coin) { - self.key_deposit = Some(key_deposit.clone()) - } - - pub fn key_deposit(&self) -> Option { - self.key_deposit.clone() - } - - pub fn set_pool_deposit(&mut self, pool_deposit: &Coin) { - self.pool_deposit = Some(pool_deposit.clone()) - } - - pub fn pool_deposit(&self) -> Option { - self.pool_deposit.clone() - } - - pub fn set_max_epoch(&mut self, max_epoch: Epoch) { - self.max_epoch = Some(max_epoch.clone()) - } - - pub fn max_epoch(&self) -> Option { - self.max_epoch.clone() - } - - pub fn set_n_opt(&mut self, n_opt: u32) { - self.n_opt = Some(n_opt) - } - - pub fn n_opt(&self) -> Option { - self.n_opt.clone() - } - - pub fn set_pool_pledge_influence(&mut self, pool_pledge_influence: &Rational) { - self.pool_pledge_influence = Some(pool_pledge_influence.clone()) - } - - pub fn pool_pledge_influence(&self) -> Option { - self.pool_pledge_influence.clone() - } - - pub fn set_expansion_rate(&mut self, expansion_rate: &UnitInterval) { - self.expansion_rate = Some(expansion_rate.clone()) - } - - pub fn expansion_rate(&self) -> Option { - self.expansion_rate.clone() - } - - pub fn set_treasury_growth_rate(&mut self, treasury_growth_rate: &UnitInterval) { - self.treasury_growth_rate = Some(treasury_growth_rate.clone()) - } - - pub fn treasury_growth_rate(&self) -> Option { - self.treasury_growth_rate.clone() - } - - /// !!! DEPRECATED !!! - /// Since babbage era this param is outdated. But this param you can meet in a pre-babbage block. - #[deprecated( - since = "11.0.0", - note = "Since babbage era this param is outdated. But this param you can meet in a pre-babbage block." - )] - pub fn d(&self) -> Option { - self.d.clone() - } - - /// !!! DEPRECATED !!! - /// Since babbage era this param is outdated. But this param you can meet in a pre-babbage block. - #[deprecated( - since = "11.0.0", - note = "Since babbage era this param is outdated. But this param you can meet in a pre-babbage block." - )] - pub fn extra_entropy(&self) -> Option { - self.extra_entropy.clone() - } - - pub fn set_protocol_version(&mut self, protocol_version: &ProtocolVersion) { - self.protocol_version = Some(protocol_version.clone()) - } - - pub fn protocol_version(&self) -> Option { - self.protocol_version.clone() - } - - pub fn set_min_pool_cost(&mut self, min_pool_cost: &Coin) { - self.min_pool_cost = Some(min_pool_cost.clone()) - } - - pub fn min_pool_cost(&self) -> Option { - self.min_pool_cost.clone() - } - - pub fn set_ada_per_utxo_byte(&mut self, ada_per_utxo_byte: &Coin) { - self.ada_per_utxo_byte = Some(ada_per_utxo_byte.clone()) - } - - pub fn ada_per_utxo_byte(&self) -> Option { - self.ada_per_utxo_byte.clone() - } - - pub fn set_cost_models(&mut self, cost_models: &Costmdls) { - self.cost_models = Some(cost_models.clone()) - } - - pub fn cost_models(&self) -> Option { - self.cost_models.clone() - } - - pub fn set_execution_costs(&mut self, execution_costs: &ExUnitPrices) { - self.execution_costs = Some(execution_costs.clone()) - } - - pub fn execution_costs(&self) -> Option { - self.execution_costs.clone() - } - - pub fn set_max_tx_ex_units(&mut self, max_tx_ex_units: &ExUnits) { - self.max_tx_ex_units = Some(max_tx_ex_units.clone()) - } - - pub fn max_tx_ex_units(&self) -> Option { - self.max_tx_ex_units.clone() - } - - pub fn set_max_block_ex_units(&mut self, max_block_ex_units: &ExUnits) { - self.max_block_ex_units = Some(max_block_ex_units.clone()) - } - - pub fn max_block_ex_units(&self) -> Option { - self.max_block_ex_units.clone() - } - - pub fn set_max_value_size(&mut self, max_value_size: u32) { - self.max_value_size = Some(max_value_size.clone()) - } - - pub fn max_value_size(&self) -> Option { - self.max_value_size.clone() - } - - pub fn set_collateral_percentage(&mut self, collateral_percentage: u32) { - self.collateral_percentage = Some(collateral_percentage) - } - - pub fn collateral_percentage(&self) -> Option { - self.collateral_percentage.clone() - } - - pub fn set_max_collateral_inputs(&mut self, max_collateral_inputs: u32) { - self.max_collateral_inputs = Some(max_collateral_inputs) - } - - pub fn max_collateral_inputs(&self) -> Option { - self.max_collateral_inputs.clone() - } - - pub fn new() -> Self { - Self { - minfee_a: None, - minfee_b: None, - max_block_body_size: None, - max_tx_size: None, - max_block_header_size: None, - key_deposit: None, - pool_deposit: None, - max_epoch: None, - n_opt: None, - pool_pledge_influence: None, - expansion_rate: None, - treasury_growth_rate: None, - d: None, - extra_entropy: None, - protocol_version: None, - min_pool_cost: None, - ada_per_utxo_byte: None, - cost_models: None, - execution_costs: None, - max_tx_ex_units: None, - max_block_ex_units: None, - max_value_size: None, - collateral_percentage: None, - max_collateral_inputs: None, - } - } -} - #[wasm_bindgen] #[derive(Clone, serde::Serialize, serde::Deserialize, JsonSchema)] pub struct TransactionBodies(pub(crate) Vec); diff --git a/rust/src/protocol_types/mod.rs b/rust/src/protocol_types/mod.rs index c6e7e9ce..b0f59f35 100644 --- a/rust/src/protocol_types/mod.rs +++ b/rust/src/protocol_types/mod.rs @@ -13,3 +13,9 @@ pub use plutus::*; mod metadata; pub use metadata::*; + +mod transaction_body; +pub use transaction_body::*; + +mod protocol_param_update; +pub use protocol_param_update::*; diff --git a/rust/src/protocol_types/protocol_param_update.rs b/rust/src/protocol_types/protocol_param_update.rs new file mode 100644 index 00000000..8dafc129 --- /dev/null +++ b/rust/src/protocol_types/protocol_param_update.rs @@ -0,0 +1,552 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct PoolVotingThresholds { + pub(crate) motion_no_confidence: UnitInterval, + pub(crate) committee_normal: UnitInterval, + pub(crate) committee_no_confidence: UnitInterval, + pub(crate) hard_fork_initiation: UnitInterval, +} + +impl_to_from!(PoolVotingThresholds); + +#[wasm_bindgen] +impl PoolVotingThresholds { + pub fn new( + motion_no_confidence: &UnitInterval, + committee_normal: &UnitInterval, + committee_no_confidence: &UnitInterval, + hard_fork_initiation: &UnitInterval, + ) -> Self { + Self { + motion_no_confidence: motion_no_confidence.clone(), + committee_normal: committee_normal.clone(), + committee_no_confidence: committee_no_confidence.clone(), + hard_fork_initiation: hard_fork_initiation.clone(), + } + } + + pub fn motion_no_confidence(&self) -> UnitInterval { + self.motion_no_confidence.clone() + } + + pub fn committee_normal(&self) -> UnitInterval { + self.committee_normal.clone() + } + + pub fn committee_no_confidence(&self) -> UnitInterval { + self.committee_no_confidence.clone() + } + + pub fn hard_fork_initiation(&self) -> UnitInterval { + self.hard_fork_initiation.clone() + } +} + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + Default, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct DrepVotingThresholds { + pub(crate) motion_no_confidence: UnitInterval, + pub(crate) committee_normal: UnitInterval, + pub(crate) committee_no_confidence: UnitInterval, + pub(crate) update_constitution: UnitInterval, + pub(crate) hard_fork_initiation: UnitInterval, + pub(crate) pp_network_group: UnitInterval, + pub(crate) pp_economic_group: UnitInterval, + pub(crate) pp_technical_group: UnitInterval, + pub(crate) pp_governance_group: UnitInterval, + pub(crate) treasury_withdrawal: UnitInterval, +} + +impl_to_from!(DrepVotingThresholds); + +#[wasm_bindgen] +impl DrepVotingThresholds { + pub fn new( + motion_no_confidence: &UnitInterval, + committee_normal: &UnitInterval, + committee_no_confidence: &UnitInterval, + update_constitution: &UnitInterval, + hard_fork_initiation: &UnitInterval, + pp_network_group: &UnitInterval, + pp_economic_group: &UnitInterval, + pp_technical_group: &UnitInterval, + pp_governance_group: &UnitInterval, + treasury_withdrawal: &UnitInterval, + ) -> Self { + Self { + motion_no_confidence: motion_no_confidence.clone(), + committee_normal: committee_normal.clone(), + committee_no_confidence: committee_no_confidence.clone(), + update_constitution: update_constitution.clone(), + hard_fork_initiation: hard_fork_initiation.clone(), + pp_network_group: pp_network_group.clone(), + pp_economic_group: pp_economic_group.clone(), + pp_technical_group: pp_technical_group.clone(), + pp_governance_group: pp_governance_group.clone(), + treasury_withdrawal: treasury_withdrawal.clone(), + } + } + + pub fn new_default() -> Self { + Self { + ..Default::default() + } + } + + pub fn set_motion_no_confidence(&mut self, motion_no_confidence: &UnitInterval) { + self.motion_no_confidence = motion_no_confidence.clone() + } + + pub fn set_committee_normal(&mut self, committee_normal: &UnitInterval) { + self.committee_normal = committee_normal.clone() + } + + pub fn set_committee_no_confidence(&mut self, committee_no_confidence: &UnitInterval) { + self.committee_no_confidence = committee_no_confidence.clone() + } + + pub fn set_update_constitution(&mut self, update_constitution: &UnitInterval) { + self.update_constitution = update_constitution.clone() + } + + pub fn set_hard_fork_initiation(&mut self, hard_fork_initiation: &UnitInterval) { + self.hard_fork_initiation = hard_fork_initiation.clone() + } + + pub fn set_pp_network_group(&mut self, pp_network_group: &UnitInterval) { + self.pp_network_group = pp_network_group.clone() + } + + pub fn set_pp_economic_group(&mut self, pp_economic_group: &UnitInterval) { + self.pp_economic_group = pp_economic_group.clone() + } + + pub fn set_pp_technical_group(&mut self, pp_technical_group: &UnitInterval) { + self.pp_technical_group = pp_technical_group.clone() + } + + pub fn set_pp_governance_group(&mut self, pp_governance_group: &UnitInterval) { + self.pp_governance_group = pp_governance_group.clone() + } + + pub fn set_treasury_withdrawal(&mut self, treasury_withdrawal: &UnitInterval) { + self.treasury_withdrawal = treasury_withdrawal.clone() + } + + pub fn motion_no_confidence(&self) -> UnitInterval { + self.motion_no_confidence.clone() + } + + pub fn committee_normal(&self) -> UnitInterval { + self.committee_normal.clone() + } + + pub fn committee_no_confidence(&self) -> UnitInterval { + self.committee_no_confidence.clone() + } + + pub fn update_constitution(&self) -> UnitInterval { + self.update_constitution.clone() + } + + pub fn hard_fork_initiation(&self) -> UnitInterval { + self.hard_fork_initiation.clone() + } + + pub fn pp_network_group(&self) -> UnitInterval { + self.pp_network_group.clone() + } + + pub fn pp_economic_group(&self) -> UnitInterval { + self.pp_economic_group.clone() + } + + pub fn pp_technical_group(&self) -> UnitInterval { + self.pp_technical_group.clone() + } + + pub fn pp_governance_group(&self) -> UnitInterval { + self.pp_governance_group.clone() + } + + pub fn treasury_withdrawal(&self) -> UnitInterval { + self.treasury_withdrawal.clone() + } +} + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct ProtocolParamUpdate { + pub(crate) minfee_a: Option, + pub(crate) minfee_b: Option, + pub(crate) max_block_body_size: Option, + pub(crate) max_tx_size: Option, + pub(crate) max_block_header_size: Option, + pub(crate) key_deposit: Option, + pub(crate) pool_deposit: Option, + pub(crate) max_epoch: Option, + // desired number of stake pools + pub(crate) n_opt: Option, + pub(crate) pool_pledge_influence: Option, + pub(crate) expansion_rate: Option, + pub(crate) treasury_growth_rate: Option, + // decentralization constant + pub(crate) d: Option, + pub(crate) extra_entropy: Option, + pub(crate) protocol_version: Option, + pub(crate) min_pool_cost: Option, + pub(crate) ada_per_utxo_byte: Option, + pub(crate) cost_models: Option, + pub(crate) execution_costs: Option, + pub(crate) max_tx_ex_units: Option, + pub(crate) max_block_ex_units: Option, + pub(crate) max_value_size: Option, + pub(crate) collateral_percentage: Option, + pub(crate) max_collateral_inputs: Option, + pub(crate) pool_voting_thresholds: Option, + pub(crate) drep_voting_thresholds: Option, + pub(crate) min_committee_size: Option, + pub(crate) committee_term_limit: Option, + pub(crate) governance_action_validity_period: Option, + pub(crate) governance_action_deposit: Option, + pub(crate) drep_deposit: Option, + pub(crate) drep_inactivity_period: Option, +} + +impl_to_from!(ProtocolParamUpdate); + +#[wasm_bindgen] +impl ProtocolParamUpdate { + pub fn set_minfee_a(&mut self, minfee_a: &Coin) { + self.minfee_a = Some(minfee_a.clone()) + } + + pub fn minfee_a(&self) -> Option { + self.minfee_a.clone() + } + + pub fn set_minfee_b(&mut self, minfee_b: &Coin) { + self.minfee_b = Some(minfee_b.clone()) + } + + pub fn minfee_b(&self) -> Option { + self.minfee_b.clone() + } + + pub fn set_max_block_body_size(&mut self, max_block_body_size: u32) { + self.max_block_body_size = Some(max_block_body_size) + } + + pub fn max_block_body_size(&self) -> Option { + self.max_block_body_size.clone() + } + + pub fn set_max_tx_size(&mut self, max_tx_size: u32) { + self.max_tx_size = Some(max_tx_size) + } + + pub fn max_tx_size(&self) -> Option { + self.max_tx_size.clone() + } + + pub fn set_max_block_header_size(&mut self, max_block_header_size: u32) { + self.max_block_header_size = Some(max_block_header_size) + } + + pub fn max_block_header_size(&self) -> Option { + self.max_block_header_size.clone() + } + + pub fn set_key_deposit(&mut self, key_deposit: &Coin) { + self.key_deposit = Some(key_deposit.clone()) + } + + pub fn key_deposit(&self) -> Option { + self.key_deposit.clone() + } + + pub fn set_pool_deposit(&mut self, pool_deposit: &Coin) { + self.pool_deposit = Some(pool_deposit.clone()) + } + + pub fn pool_deposit(&self) -> Option { + self.pool_deposit.clone() + } + + pub fn set_max_epoch(&mut self, max_epoch: Epoch) { + self.max_epoch = Some(max_epoch.clone()) + } + + pub fn max_epoch(&self) -> Option { + self.max_epoch.clone() + } + + pub fn set_n_opt(&mut self, n_opt: u32) { + self.n_opt = Some(n_opt) + } + + pub fn n_opt(&self) -> Option { + self.n_opt.clone() + } + + pub fn set_pool_pledge_influence(&mut self, pool_pledge_influence: &Rational) { + self.pool_pledge_influence = Some(pool_pledge_influence.clone()) + } + + pub fn pool_pledge_influence(&self) -> Option { + self.pool_pledge_influence.clone() + } + + pub fn set_expansion_rate(&mut self, expansion_rate: &UnitInterval) { + self.expansion_rate = Some(expansion_rate.clone()) + } + + pub fn expansion_rate(&self) -> Option { + self.expansion_rate.clone() + } + + pub fn set_treasury_growth_rate(&mut self, treasury_growth_rate: &UnitInterval) { + self.treasury_growth_rate = Some(treasury_growth_rate.clone()) + } + + pub fn treasury_growth_rate(&self) -> Option { + self.treasury_growth_rate.clone() + } + + /// !!! DEPRECATED !!! + /// Since babbage era this param is outdated. But this param you can meet in a pre-babbage block. + #[deprecated( + since = "11.0.0", + note = "Since babbage era this param is outdated. But this param you can meet in a pre-babbage block." + )] + pub fn d(&self) -> Option { + self.d.clone() + } + + /// !!! DEPRECATED !!! + /// Since babbage era this param is outdated. But this param you can meet in a pre-babbage block. + #[deprecated( + since = "11.0.0", + note = "Since babbage era this param is outdated. But this param you can meet in a pre-babbage block." + )] + pub fn extra_entropy(&self) -> Option { + self.extra_entropy.clone() + } + + pub fn set_protocol_version(&mut self, protocol_version: &ProtocolVersion) { + self.protocol_version = Some(protocol_version.clone()) + } + + pub fn protocol_version(&self) -> Option { + self.protocol_version.clone() + } + + pub fn set_min_pool_cost(&mut self, min_pool_cost: &Coin) { + self.min_pool_cost = Some(min_pool_cost.clone()) + } + + pub fn min_pool_cost(&self) -> Option { + self.min_pool_cost.clone() + } + + pub fn set_ada_per_utxo_byte(&mut self, ada_per_utxo_byte: &Coin) { + self.ada_per_utxo_byte = Some(ada_per_utxo_byte.clone()) + } + + pub fn ada_per_utxo_byte(&self) -> Option { + self.ada_per_utxo_byte.clone() + } + + pub fn set_cost_models(&mut self, cost_models: &Costmdls) { + self.cost_models = Some(cost_models.clone()) + } + + pub fn cost_models(&self) -> Option { + self.cost_models.clone() + } + + pub fn set_execution_costs(&mut self, execution_costs: &ExUnitPrices) { + self.execution_costs = Some(execution_costs.clone()) + } + + pub fn execution_costs(&self) -> Option { + self.execution_costs.clone() + } + + pub fn set_max_tx_ex_units(&mut self, max_tx_ex_units: &ExUnits) { + self.max_tx_ex_units = Some(max_tx_ex_units.clone()) + } + + pub fn max_tx_ex_units(&self) -> Option { + self.max_tx_ex_units.clone() + } + + pub fn set_max_block_ex_units(&mut self, max_block_ex_units: &ExUnits) { + self.max_block_ex_units = Some(max_block_ex_units.clone()) + } + + pub fn max_block_ex_units(&self) -> Option { + self.max_block_ex_units.clone() + } + + pub fn set_max_value_size(&mut self, max_value_size: u32) { + self.max_value_size = Some(max_value_size.clone()) + } + + pub fn max_value_size(&self) -> Option { + self.max_value_size.clone() + } + + pub fn set_collateral_percentage(&mut self, collateral_percentage: u32) { + self.collateral_percentage = Some(collateral_percentage) + } + + pub fn collateral_percentage(&self) -> Option { + self.collateral_percentage.clone() + } + + pub fn set_max_collateral_inputs(&mut self, max_collateral_inputs: u32) { + self.max_collateral_inputs = Some(max_collateral_inputs) + } + + pub fn max_collateral_inputs(&self) -> Option { + self.max_collateral_inputs.clone() + } + + pub fn set_pool_voting_thresholds(&mut self, pool_voting_thresholds: &PoolVotingThresholds) { + self.pool_voting_thresholds = Some(pool_voting_thresholds.clone()) + } + + pub fn pool_voting_thresholds(&self) -> Option { + self.pool_voting_thresholds.clone() + } + + pub fn set_drep_voting_thresholds(&mut self, drep_voting_thresholds: &DrepVotingThresholds) { + self.drep_voting_thresholds = Some(drep_voting_thresholds.clone()) + } + + pub fn drep_voting_thresholds(&self) -> Option { + self.drep_voting_thresholds.clone() + } + + pub fn set_min_committee_size(&mut self, min_committee_size: u32) { + self.min_committee_size = Some(min_committee_size) + } + + pub fn min_committee_size(&self) -> Option { + self.min_committee_size.clone() + } + + pub fn set_committee_term_limit(&mut self, committee_term_limit: u32) { + self.committee_term_limit = Some(committee_term_limit) + } + + pub fn committee_term_limit(&self) -> Option { + self.committee_term_limit.clone() + } + + pub fn set_governance_action_validity_period(&mut self, governance_action_validity_period: Epoch) { + self.governance_action_validity_period = Some(governance_action_validity_period) + } + + pub fn governance_action_validity_period(&self) -> Option { + self.governance_action_validity_period.clone() + } + + pub fn set_governance_action_deposit(&mut self, governance_action_deposit: &Coin) { + self.governance_action_deposit = Some(governance_action_deposit.clone()); + } + + pub fn governance_action_deposit(&self) -> Option { + self.governance_action_deposit.clone() + } + + pub fn set_drep_deposit(&mut self, drep_deposit: &Coin) { + self.drep_deposit = Some(drep_deposit.clone()); + } + + pub fn drep_deposit(&self) -> Option { + self.drep_deposit.clone() + } + + pub fn set_drep_inactivity_period(&mut self, drep_inactivity_period: Epoch) { + self.drep_inactivity_period = Some(drep_inactivity_period) + } + + pub fn drep_inactivity_period(&self) -> Option { + self.drep_inactivity_period.clone() + } + + pub fn new() -> Self { + Self { + minfee_a: None, + minfee_b: None, + max_block_body_size: None, + max_tx_size: None, + max_block_header_size: None, + key_deposit: None, + pool_deposit: None, + max_epoch: None, + n_opt: None, + pool_pledge_influence: None, + expansion_rate: None, + treasury_growth_rate: None, + d: None, + extra_entropy: None, + protocol_version: None, + min_pool_cost: None, + ada_per_utxo_byte: None, + cost_models: None, + execution_costs: None, + max_tx_ex_units: None, + max_block_ex_units: None, + max_value_size: None, + collateral_percentage: None, + max_collateral_inputs: None, + pool_voting_thresholds: None, + drep_voting_thresholds: None, + min_committee_size: None, + committee_term_limit: None, + governance_action_validity_period: None, + governance_action_deposit: None, + drep_deposit: None, + drep_inactivity_period: None, + } + } +} diff --git a/rust/src/protocol_types/transaction_body.rs b/rust/src/protocol_types/transaction_body.rs new file mode 100644 index 00000000..cef72692 --- /dev/null +++ b/rust/src/protocol_types/transaction_body.rs @@ -0,0 +1,297 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Eq, PartialEq, Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +pub struct TransactionBody { + pub(crate) inputs: TransactionInputs, + pub(crate) outputs: TransactionOutputs, + pub(crate) fee: Coin, + pub(crate) ttl: Option, + pub(crate) certs: Option, + pub(crate) withdrawals: Option, + pub(crate) update: Option, + pub(crate) auxiliary_data_hash: Option, + pub(crate) validity_start_interval: Option, + pub(crate) mint: Option, + pub(crate) script_data_hash: Option, + pub(crate) collateral: Option, + pub(crate) required_signers: Option, + pub(crate) network_id: Option, + pub(crate) collateral_return: Option, + pub(crate) total_collateral: Option, + pub(crate) reference_inputs: Option, + pub(crate) voting_procedures: Option, + pub(crate) voting_proposals: Option, + pub(crate) donation: Option, + pub(crate) current_treasury_value: Option, +} + +impl_to_from!(TransactionBody); + +#[wasm_bindgen] +impl TransactionBody { + pub fn inputs(&self) -> TransactionInputs { + self.inputs.clone() + } + + pub fn outputs(&self) -> TransactionOutputs { + self.outputs.clone() + } + + pub fn fee(&self) -> Coin { + self.fee.clone() + } + + /// !!! DEPRECATED !!! + /// Returns a Slot32 (u32) value in case the underlying original BigNum (u64) value is within the limits. + /// Otherwise will just raise an error. + #[deprecated( + since = "10.1.0", + note = "Possible boundary error. Use ttl_bignum instead" + )] + pub fn ttl(&self) -> Result, JsError> { + match self.ttl { + Some(ttl) => match ttl.try_into() { + Ok(ttl32) => Ok(Some(ttl32)), + Err(err) => Err(err), + }, + None => Ok(None), + } + } + + pub fn ttl_bignum(&self) -> Option { + self.ttl + } + + pub fn set_ttl(&mut self, ttl: &SlotBigNum) { + self.ttl = Some(ttl.clone()) + } + + pub fn remove_ttl(&mut self) { + self.ttl = None + } + + pub fn set_certs(&mut self, certs: &Certificates) { + self.certs = Some(certs.clone()) + } + + pub fn certs(&self) -> Option { + self.certs.clone() + } + + pub fn set_withdrawals(&mut self, withdrawals: &Withdrawals) { + self.withdrawals = Some(withdrawals.clone()) + } + + pub fn withdrawals(&self) -> Option { + self.withdrawals.clone() + } + + pub fn set_update(&mut self, update: &Update) { + self.update = Some(update.clone()) + } + + pub fn update(&self) -> Option { + self.update.clone() + } + + pub fn set_auxiliary_data_hash(&mut self, auxiliary_data_hash: &AuxiliaryDataHash) { + self.auxiliary_data_hash = Some(auxiliary_data_hash.clone()) + } + + pub fn auxiliary_data_hash(&self) -> Option { + self.auxiliary_data_hash.clone() + } + + /// !!! DEPRECATED !!! + /// Uses outdated slot number format. + #[deprecated( + since = "10.1.0", + note = "Underlying value capacity of slot (BigNum u64) bigger then Slot32. Use set_validity_start_interval_bignum instead." + )] + pub fn set_validity_start_interval(&mut self, validity_start_interval: Slot32) { + self.validity_start_interval = Some(validity_start_interval.into()) + } + + pub fn set_validity_start_interval_bignum(&mut self, validity_start_interval: &SlotBigNum) { + self.validity_start_interval = Some(validity_start_interval.clone()) + } + + pub fn validity_start_interval_bignum(&self) -> Option { + self.validity_start_interval.clone() + } + + /// !!! DEPRECATED !!! + /// Returns a Option (u32) value in case the underlying original Option (u64) value is within the limits. + /// Otherwise will just raise an error. + /// Use `.validity_start_interval_bignum` instead. + #[deprecated( + since = "10.1.0", + note = "Possible boundary error. Use validity_start_interval_bignum instead" + )] + pub fn validity_start_interval(&self) -> Result, JsError> { + match self.validity_start_interval.clone() { + Some(interval) => match interval.try_into() { + Ok(internal32) => Ok(Some(internal32)), + Err(err) => Err(err), + }, + None => Ok(None), + } + } + + pub fn set_mint(&mut self, mint: &Mint) { + self.mint = Some(mint.clone()) + } + + pub fn mint(&self) -> Option { + self.mint.clone() + } + + /// This function returns the mint value of the transaction + /// Use `.mint()` instead. + #[deprecated(since = "10.0.0", note = "Weird naming. Use `.mint()`")] + pub fn multiassets(&self) -> Option { + self.mint() + } + + pub fn set_reference_inputs(&mut self, reference_inputs: &TransactionInputs) { + self.reference_inputs = Some(reference_inputs.clone()) + } + + pub fn reference_inputs(&self) -> Option { + self.reference_inputs.clone() + } + + pub fn set_script_data_hash(&mut self, script_data_hash: &ScriptDataHash) { + self.script_data_hash = Some(script_data_hash.clone()) + } + + pub fn script_data_hash(&self) -> Option { + self.script_data_hash.clone() + } + + pub fn set_collateral(&mut self, collateral: &TransactionInputs) { + self.collateral = Some(collateral.clone()) + } + + pub fn collateral(&self) -> Option { + self.collateral.clone() + } + + pub fn set_required_signers(&mut self, required_signers: &RequiredSigners) { + self.required_signers = Some(required_signers.clone()) + } + + pub fn required_signers(&self) -> Option { + self.required_signers.clone() + } + + pub fn set_network_id(&mut self, network_id: &NetworkId) { + self.network_id = Some(network_id.clone()) + } + + pub fn network_id(&self) -> Option { + self.network_id.clone() + } + + pub fn set_collateral_return(&mut self, collateral_return: &TransactionOutput) { + self.collateral_return = Some(collateral_return.clone()); + } + + pub fn collateral_return(&self) -> Option { + self.collateral_return.clone() + } + + pub fn set_total_collateral(&mut self, total_collateral: &Coin) { + self.total_collateral = Some(total_collateral.clone()); + } + + pub fn total_collateral(&self) -> Option { + self.total_collateral.clone() + } + + pub fn set_voting_procedures(&mut self, voting_procedures: &VotingProcedures) { + self.voting_procedures = Some(voting_procedures.clone()); + } + + pub fn voting_procedures(&self) -> Option { + self.voting_procedures.clone() + } + + pub fn set_voting_proposals(&mut self, voting_proposals: &VotingProposals) { + self.voting_proposals = Some(voting_proposals.clone()); + } + + pub fn voting_proposals(&self) -> Option { + self.voting_proposals.clone() + } + + pub fn set_donation(&mut self, donation: &Coin) { + self.donation = Some(donation.clone()); + } + + pub fn donation(&self) -> Option { + self.donation.clone() + } + + pub fn set_current_treasury_value(&mut self, current_treasury_value: &Coin) { + self.current_treasury_value = Some(current_treasury_value.clone()); + } + + pub fn current_treasury_value(&self) -> Option { + self.current_treasury_value.clone() + } + + /// !!! DEPRECATED !!! + /// This constructor uses outdated slot number format for the ttl value. + /// Use `.new_tx_body` and then `.set_ttl` instead + #[deprecated( + since = "10.1.0", + note = "Underlying value capacity of ttl (BigNum u64) bigger then Slot32. Use new_tx_body instead." + )] + pub fn new( + inputs: &TransactionInputs, + outputs: &TransactionOutputs, + fee: &Coin, + ttl: Option, + ) -> Self { + let mut tx = Self::new_tx_body(inputs, outputs, fee); + if let Some(slot32) = ttl { + tx.set_ttl(&to_bignum(slot32 as u64)); + } + tx + } + + /// Returns a new TransactionBody. + /// In the new version of "new" we removed optional ttl for support it by wasm_bingen. + /// Your can use "set_ttl" and "remove_ttl" to set a new value for ttl or set it as None. + pub fn new_tx_body( + inputs: &TransactionInputs, + outputs: &TransactionOutputs, + fee: &Coin, + ) -> Self { + Self { + inputs: inputs.clone(), + outputs: outputs.clone(), + fee: fee.clone(), + ttl: None, + certs: None, + withdrawals: None, + update: None, + auxiliary_data_hash: None, + validity_start_interval: None, + mint: None, + script_data_hash: None, + collateral: None, + required_signers: None, + network_id: None, + collateral_return: None, + total_collateral: None, + reference_inputs: None, + voting_procedures: None, + voting_proposals: None, + donation: None, + current_treasury_value: None, + } + } +} \ No newline at end of file diff --git a/rust/src/serialization/general.rs b/rust/src/serialization/general.rs index 3bd4094c..abc30446 100644 --- a/rust/src/serialization/general.rs +++ b/rust/src/serialization/general.rs @@ -245,429 +245,6 @@ impl Deserialize for TransactionOutputs { } } -impl cbor_event::se::Serialize for TransactionBody { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_map(cbor_event::Len::Len( - 3 + opt64(&self.ttl) - + opt64(&self.certs) - + opt64(&self.withdrawals) - + opt64(&self.update) - + opt64(&self.auxiliary_data_hash) - + opt64(&self.validity_start_interval) - + opt64(&self.mint) - + opt64(&self.script_data_hash) - + opt64(&self.collateral) - + opt64(&self.required_signers) - + opt64(&self.network_id) - + opt64(&self.collateral_return) - + opt64(&self.total_collateral) - + opt64(&self.reference_inputs) - + opt64(&self.voting_procedures) - + opt64(&self.voting_proposals), - ))?; - serializer.write_unsigned_integer(0)?; - self.inputs.serialize(serializer)?; - serializer.write_unsigned_integer(1)?; - self.outputs.serialize(serializer)?; - serializer.write_unsigned_integer(2)?; - self.fee.serialize(serializer)?; - if let Some(field) = &self.ttl { - serializer.write_unsigned_integer(3)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.certs { - serializer.write_unsigned_integer(4)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.withdrawals { - serializer.write_unsigned_integer(5)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.update { - serializer.write_unsigned_integer(6)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.auxiliary_data_hash { - serializer.write_unsigned_integer(7)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.validity_start_interval { - serializer.write_unsigned_integer(8)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.mint { - serializer.write_unsigned_integer(9)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.script_data_hash { - serializer.write_unsigned_integer(11)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.collateral { - serializer.write_unsigned_integer(13)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.required_signers { - serializer.write_unsigned_integer(14)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.network_id { - serializer.write_unsigned_integer(15)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.collateral_return { - serializer.write_unsigned_integer(16)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.total_collateral { - serializer.write_unsigned_integer(17)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.reference_inputs { - serializer.write_unsigned_integer(18)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.voting_procedures { - serializer.write_unsigned_integer(19)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.voting_proposals { - serializer.write_unsigned_integer(20)?; - field.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for TransactionBody { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.map()?; - let mut read_len = CBORReadLen::new(len); - read_len.read_elems(3)?; - let mut inputs = None; - let mut outputs = None; - let mut fee = None; - let mut ttl = None; - let mut certs = None; - let mut withdrawals = None; - let mut update = None; - let mut auxiliary_data_hash = None; - let mut validity_start_interval = None; - let mut mint = None; - let mut script_data_hash = None; - let mut collateral = None; - let mut required_signers = None; - let mut network_id = None; - let mut collateral_return = None; - let mut total_collateral = None; - let mut reference_inputs = None; - let mut voting_procedures = None; - let mut voting_proposals = None; - let mut read = 0; - while match len { - cbor_event::Len::Len(n) => read < n as usize, - cbor_event::Len::Indefinite => true, - } { - match raw.cbor_type()? { - CBORType::UnsignedInteger => match raw.unsigned_integer()? { - 0 => { - if inputs.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(0)).into()); - } - inputs = Some( - (|| -> Result<_, DeserializeError> { - Ok(TransactionInputs::deserialize(raw)?) - })() - .map_err(|e| e.annotate("inputs"))?, - ); - } - 1 => { - if outputs.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(1)).into()); - } - outputs = Some( - (|| -> Result<_, DeserializeError> { - Ok(TransactionOutputs::deserialize(raw)?) - })() - .map_err(|e| e.annotate("outputs"))?, - ); - } - 2 => { - if fee.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(2)).into()); - } - fee = - Some( - (|| -> Result<_, DeserializeError> { - Ok(Coin::deserialize(raw)?) - })() - .map_err(|e| e.annotate("fee"))?, - ); - } - 3 => { - if ttl.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(3)).into()); - } - ttl = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(SlotBigNum::deserialize(raw)?) - })() - .map_err(|e| e.annotate("ttl"))?, - ); - } - 4 => { - if certs.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(4)).into()); - } - certs = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(Certificates::deserialize(raw)?) - })() - .map_err(|e| e.annotate("certs"))?, - ); - } - 5 => { - if withdrawals.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(5)).into()); - } - withdrawals = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(Withdrawals::deserialize(raw)?) - })() - .map_err(|e| e.annotate("withdrawals"))?, - ); - } - 6 => { - if update.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(6)).into()); - } - update = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(Update::deserialize(raw)?) - })() - .map_err(|e| e.annotate("update"))?, - ); - } - 7 => { - if auxiliary_data_hash.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(7)).into()); - } - auxiliary_data_hash = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(AuxiliaryDataHash::deserialize(raw)?) - })() - .map_err(|e| e.annotate("auxiliary_data_hash"))?, - ); - } - 8 => { - if validity_start_interval.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(8)).into()); - } - validity_start_interval = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(SlotBigNum::deserialize(raw)?) - })() - .map_err(|e| e.annotate("validity_start_interval"))?, - ); - } - 9 => { - if mint.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(9)).into()); - } - mint = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(Mint::deserialize(raw)?) - })() - .map_err(|e| e.annotate("mint"))?, - ); - } - 11 => { - if script_data_hash.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(11)).into()); - } - script_data_hash = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(ScriptDataHash::deserialize(raw)?) - })() - .map_err(|e| e.annotate("script_data_hash"))?, - ); - } - 13 => { - if collateral.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(13)).into()); - } - collateral = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(TransactionInputs::deserialize(raw)?) - })() - .map_err(|e| e.annotate("collateral"))?, - ); - } - 14 => { - if required_signers.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(14)).into()); - } - required_signers = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(RequiredSigners::deserialize(raw)?) - })() - .map_err(|e| e.annotate("required_signers"))?, - ); - } - 15 => { - if network_id.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(15)).into()); - } - network_id = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(NetworkId::deserialize(raw)?) - })() - .map_err(|e| e.annotate("network_id"))?, - ); - } - 16 => { - if collateral_return.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(16)).into()); - } - collateral_return = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(TransactionOutput::deserialize(raw)?) - })() - .map_err(|e| e.annotate("collateral_return"))?, - ); - } - 17 => { - if total_collateral.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(17)).into()); - } - total_collateral = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(Coin::deserialize(raw)?) - })() - .map_err(|e| e.annotate("total_collateral"))?, - ); - } - 18 => { - if reference_inputs.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(18)).into()); - } - reference_inputs = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(TransactionInputs::deserialize(raw)?) - })() - .map_err(|e| e.annotate("reference_inputs"))?, - ); - } - 19 => { - if voting_procedures.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(19)).into()); - } - voting_procedures = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(VotingProcedures::deserialize(raw)?) - })() - .map_err(|e| e.annotate("voting_procedures"))?, - ); - } - 20 => { - if voting_proposals.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(20)).into()); - } - voting_proposals = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(VotingProposals::deserialize(raw)?) - })() - .map_err(|e| e.annotate("voting_proposals"))?, - ); - } - unknown_key => { - return Err( - DeserializeFailure::UnknownKey(Key::Uint(unknown_key)).into() - ) - } - }, - CBORType::Text => match raw.text()?.as_str() { - unknown_key => { - return Err(DeserializeFailure::UnknownKey(Key::Str( - unknown_key.to_owned(), - )) - .into()) - } - }, - CBORType::Special => match len { - cbor_event::Len::Len(_) => { - return Err(DeserializeFailure::BreakInDefiniteLen.into()) - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => break, - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - }, - other_type => { - return Err(DeserializeFailure::UnexpectedKeyType(other_type).into()) - } - } - read += 1; - } - let inputs = match inputs { - Some(x) => x, - None => return Err(DeserializeFailure::MandatoryFieldMissing(Key::Uint(0)).into()), - }; - let outputs = match outputs { - Some(x) => x, - None => return Err(DeserializeFailure::MandatoryFieldMissing(Key::Uint(1)).into()), - }; - let fee = match fee { - Some(x) => x, - None => return Err(DeserializeFailure::MandatoryFieldMissing(Key::Uint(2)).into()), - }; - read_len.finish()?; - Ok(Self { - inputs, - outputs, - fee, - ttl, - certs, - withdrawals, - update, - auxiliary_data_hash, - validity_start_interval, - mint, - script_data_hash, - collateral, - required_signers, - network_id, - collateral_return, - total_collateral, - reference_inputs, - voting_procedures, - voting_proposals, - }) - })() - .map_err(|e| e.annotate("TransactionBody")) - } -} - impl cbor_event::se::Serialize for TransactionInput { fn serialize<'se, W: Write>( &self, @@ -2762,571 +2339,6 @@ impl DeserializeEmbeddedGroup for ProtocolVersion { } } -impl cbor_event::se::Serialize for ProtocolParamUpdate { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_map(cbor_event::Len::Len( - match &self.minfee_a { - Some(_) => 1, - None => 0, - } + match &self.minfee_b { - Some(_) => 1, - None => 0, - } + match &self.max_block_body_size { - Some(_) => 1, - None => 0, - } + match &self.max_tx_size { - Some(_) => 1, - None => 0, - } + match &self.max_block_header_size { - Some(_) => 1, - None => 0, - } + match &self.key_deposit { - Some(_) => 1, - None => 0, - } + match &self.pool_deposit { - Some(_) => 1, - None => 0, - } + match &self.max_epoch { - Some(_) => 1, - None => 0, - } + match &self.n_opt { - Some(_) => 1, - None => 0, - } + match &self.pool_pledge_influence { - Some(_) => 1, - None => 0, - } + match &self.expansion_rate { - Some(_) => 1, - None => 0, - } + match &self.treasury_growth_rate { - Some(_) => 1, - None => 0, - } + match &self.d { - Some(_) => 1, - None => 0, - } + match &self.extra_entropy { - Some(_) => 1, - None => 0, - } + match &self.protocol_version { - Some(_) => 1, - None => 0, - } + match &self.min_pool_cost { - Some(_) => 1, - None => 0, - } + match &self.ada_per_utxo_byte { - Some(_) => 1, - None => 0, - } + match &self.cost_models { - Some(_) => 1, - None => 0, - } + match &self.execution_costs { - Some(_) => 1, - None => 0, - } + match &self.max_tx_ex_units { - Some(_) => 1, - None => 0, - } + match &self.max_block_ex_units { - Some(_) => 1, - None => 0, - } + match &self.max_value_size { - Some(_) => 1, - None => 0, - } + match &self.collateral_percentage { - Some(_) => 1, - None => 0, - } + match &self.max_collateral_inputs { - Some(_) => 1, - None => 0, - }, - ))?; - if let Some(field) = &self.minfee_a { - serializer.write_unsigned_integer(0)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.minfee_b { - serializer.write_unsigned_integer(1)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.max_block_body_size { - serializer.write_unsigned_integer(2)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.max_tx_size { - serializer.write_unsigned_integer(3)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.max_block_header_size { - serializer.write_unsigned_integer(4)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.key_deposit { - serializer.write_unsigned_integer(5)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.pool_deposit { - serializer.write_unsigned_integer(6)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.max_epoch { - serializer.write_unsigned_integer(7)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.n_opt { - serializer.write_unsigned_integer(8)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.pool_pledge_influence { - serializer.write_unsigned_integer(9)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.expansion_rate { - serializer.write_unsigned_integer(10)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.treasury_growth_rate { - serializer.write_unsigned_integer(11)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.d { - serializer.write_unsigned_integer(12)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.extra_entropy { - serializer.write_unsigned_integer(13)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.protocol_version { - serializer.write_unsigned_integer(14)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.min_pool_cost { - serializer.write_unsigned_integer(16)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.ada_per_utxo_byte { - serializer.write_unsigned_integer(17)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.cost_models { - serializer.write_unsigned_integer(18)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.execution_costs { - serializer.write_unsigned_integer(19)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.max_tx_ex_units { - serializer.write_unsigned_integer(20)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.max_block_ex_units { - serializer.write_unsigned_integer(21)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.max_value_size { - serializer.write_unsigned_integer(22)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.collateral_percentage { - serializer.write_unsigned_integer(23)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.max_collateral_inputs { - serializer.write_unsigned_integer(24)?; - field.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for ProtocolParamUpdate { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.map()?; - let mut read_len = CBORReadLen::new(len); - let mut minfee_a = None; - let mut minfee_b = None; - let mut max_block_body_size = None; - let mut max_tx_size = None; - let mut max_block_header_size = None; - let mut key_deposit = None; - let mut pool_deposit = None; - let mut max_epoch = None; - let mut n_opt = None; - let mut pool_pledge_influence = None; - let mut expansion_rate = None; - let mut treasury_growth_rate = None; - let mut d = None; - let mut extra_entropy = None; - let mut protocol_version = None; - let mut min_pool_cost = None; - let mut ada_per_utxo_byte = None; - let mut cost_models = None; - let mut execution_costs = None; - let mut max_tx_ex_units = None; - let mut max_block_ex_units = None; - let mut max_value_size = None; - let mut collateral_percentage = None; - let mut max_collateral_inputs = None; - let mut read = 0; - while match len { - cbor_event::Len::Len(n) => read < n as usize, - cbor_event::Len::Indefinite => true, - } { - match raw.cbor_type()? { - CBORType::UnsignedInteger => match raw.unsigned_integer()? { - 0 => { - if minfee_a.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(0)).into()); - } - minfee_a = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(Coin::deserialize(raw)?) - })() - .map_err(|e| e.annotate("minfee_a"))?, - ); - } - 1 => { - if minfee_b.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(1)).into()); - } - minfee_b = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(Coin::deserialize(raw)?) - })() - .map_err(|e| e.annotate("minfee_b"))?, - ); - } - 2 => { - if max_block_body_size.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(2)).into()); - } - max_block_body_size = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(u32::deserialize(raw)?) - })() - .map_err(|e| e.annotate("max_block_body_size"))?, - ); - } - 3 => { - if max_tx_size.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(3)).into()); - } - max_tx_size = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(u32::deserialize(raw)?) - })() - .map_err(|e| e.annotate("max_tx_size"))?, - ); - } - 4 => { - if max_block_header_size.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(4)).into()); - } - max_block_header_size = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(u32::deserialize(raw)?) - })() - .map_err(|e| e.annotate("max_block_header_size"))?, - ); - } - 5 => { - if key_deposit.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(5)).into()); - } - key_deposit = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(Coin::deserialize(raw)?) - })() - .map_err(|e| e.annotate("key_deposit"))?, - ); - } - 6 => { - if pool_deposit.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(6)).into()); - } - pool_deposit = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(Coin::deserialize(raw)?) - })() - .map_err(|e| e.annotate("pool_deposit"))?, - ); - } - 7 => { - if max_epoch.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(7)).into()); - } - max_epoch = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(Epoch::deserialize(raw)?) - })() - .map_err(|e| e.annotate("max_epoch"))?, - ); - } - 8 => { - if n_opt.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(8)).into()); - } - n_opt = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(u32::deserialize(raw)?) - })() - .map_err(|e| e.annotate("n_opt"))?, - ); - } - 9 => { - if pool_pledge_influence.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(9)).into()); - } - pool_pledge_influence = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(Rational::deserialize(raw)?) - })() - .map_err(|e| e.annotate("pool_pledge_influence"))?, - ); - } - 10 => { - if expansion_rate.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(10)).into()); - } - expansion_rate = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(UnitInterval::deserialize(raw)?) - })() - .map_err(|e| e.annotate("expansion_rate"))?, - ); - } - 11 => { - if treasury_growth_rate.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(11)).into()); - } - treasury_growth_rate = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(UnitInterval::deserialize(raw)?) - })() - .map_err(|e| e.annotate("treasury_growth_rate"))?, - ); - } - 12 => { - if d.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(12)).into()); - } - d = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(UnitInterval::deserialize(raw)?) - })() - .map_err(|e| e.annotate("d"))?, - ); - } - 13 => { - if extra_entropy.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(13)).into()); - } - extra_entropy = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(Nonce::deserialize(raw)?) - })() - .map_err(|e| e.annotate("extra_entropy"))?, - ); - } - 14 => { - if protocol_version.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(14)).into()); - } - protocol_version = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(ProtocolVersion::deserialize(raw)?) - })() - .map_err(|e| e.annotate("protocol_version"))?, - ); - } - 16 => { - if min_pool_cost.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(16)).into()); - } - min_pool_cost = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(Coin::deserialize(raw)?) - })() - .map_err(|e| e.annotate("min_pool_cost"))?, - ); - } - 17 => { - if ada_per_utxo_byte.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(17)).into()); - } - ada_per_utxo_byte = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(Coin::deserialize(raw)?) - })() - .map_err(|e| e.annotate("ada_per_utxo_byte"))?, - ); - } - 18 => { - if cost_models.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(18)).into()); - } - cost_models = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(Costmdls::deserialize(raw)?) - })() - .map_err(|e| e.annotate("cost_models"))?, - ); - } - 19 => { - if execution_costs.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(19)).into()); - } - execution_costs = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(ExUnitPrices::deserialize(raw)?) - })() - .map_err(|e| e.annotate("execution_costs"))?, - ); - } - 20 => { - if max_tx_ex_units.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(20)).into()); - } - max_tx_ex_units = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(ExUnits::deserialize(raw)?) - })() - .map_err(|e| e.annotate("max_tx_ex_units"))?, - ); - } - 21 => { - if max_block_ex_units.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(21)).into()); - } - max_block_ex_units = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(ExUnits::deserialize(raw)?) - })() - .map_err(|e| e.annotate("max_block_ex_units"))?, - ); - } - 22 => { - if max_value_size.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(22)).into()); - } - max_value_size = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(u32::deserialize(raw)?) - })() - .map_err(|e| e.annotate("max_value_size"))?, - ); - } - 23 => { - if collateral_percentage.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(23)).into()); - } - collateral_percentage = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(u32::deserialize(raw)?) - })() - .map_err(|e| e.annotate("collateral_percentage"))?, - ); - } - 24 => { - if max_collateral_inputs.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(24)).into()); - } - max_collateral_inputs = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(u32::deserialize(raw)?) - })() - .map_err(|e| e.annotate("max_collateral_inputs"))?, - ); - } - unknown_key => { - return Err( - DeserializeFailure::UnknownKey(Key::Uint(unknown_key)).into() - ) - } - }, - CBORType::Text => match raw.text()?.as_str() { - unknown_key => { - return Err(DeserializeFailure::UnknownKey(Key::Str( - unknown_key.to_owned(), - )) - .into()) - } - }, - CBORType::Special => match len { - cbor_event::Len::Len(_) => { - return Err(DeserializeFailure::BreakInDefiniteLen.into()) - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => break, - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - }, - other_type => { - return Err(DeserializeFailure::UnexpectedKeyType(other_type).into()) - } - } - read += 1; - } - read_len.finish()?; - Ok(Self { - minfee_a, - minfee_b, - max_block_body_size, - max_tx_size, - max_block_header_size, - key_deposit, - pool_deposit, - max_epoch, - n_opt, - pool_pledge_influence, - expansion_rate, - treasury_growth_rate, - d, - extra_entropy, - protocol_version, - min_pool_cost, - ada_per_utxo_byte, - cost_models, - execution_costs, - max_tx_ex_units, - max_block_ex_units, - max_value_size, - collateral_percentage, - max_collateral_inputs, - }) - })() - .map_err(|e| e.annotate("ProtocolParamUpdate")) - } -} - impl cbor_event::se::Serialize for TransactionBodies { fn serialize<'se, W: Write>( &self, diff --git a/rust/src/serialization/mod.rs b/rust/src/serialization/mod.rs index 75409f97..2dea7b4c 100644 --- a/rust/src/serialization/mod.rs +++ b/rust/src/serialization/mod.rs @@ -12,4 +12,6 @@ mod fixed_tx; use utils::*; mod plutus; -mod metadata; \ No newline at end of file +mod metadata; +mod transaction_body; +mod protocol_param_update; \ No newline at end of file diff --git a/rust/src/serialization/protocol_param_update.rs b/rust/src/serialization/protocol_param_update.rs new file mode 100644 index 00000000..c129cca7 --- /dev/null +++ b/rust/src/serialization/protocol_param_update.rs @@ -0,0 +1,864 @@ +use crate::*; +use crate::serialization::utils::check_len; + +impl Serialize for PoolVotingThresholds { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(4))?; + self.motion_no_confidence.serialize(serializer)?; + self.committee_normal.serialize(serializer)?; + self.committee_no_confidence.serialize(serializer)?; + self.hard_fork_initiation.serialize(serializer) + } +} + +impl_deserialize_for_wrapped_tuple!(PoolVotingThresholds); + +impl DeserializeEmbeddedGroup for PoolVotingThresholds { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + check_len( + len, + 4, + "[\ + motion_no_confidence, \ + committee_normal, \ + committee_no_confidence, \ + hard_fork_initiation\ + ]", + )?; + + let motion_no_confidence = UnitInterval::deserialize(raw) + .map_err(|e| e.annotate("motion_no_confidence"))?; + let committee_normal = UnitInterval::deserialize(raw) + .map_err(|e| e.annotate("committee_normal"))?; + let committee_no_confidence = UnitInterval::deserialize(raw) + .map_err(|e| e.annotate("committee_no_confidence"))?; + let hard_fork_initiation = UnitInterval::deserialize(raw) + .map_err(|e| e.annotate("hard_fork_initiation"))?; + + return Ok(PoolVotingThresholds { + motion_no_confidence, + committee_normal, + committee_no_confidence, + hard_fork_initiation, + }); + } +} + +impl Serialize for DrepVotingThresholds { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(10))?; + self.motion_no_confidence.serialize(serializer)?; + self.committee_normal.serialize(serializer)?; + self.committee_no_confidence.serialize(serializer)?; + self.update_constitution.serialize(serializer)?; + self.hard_fork_initiation.serialize(serializer)?; + self.pp_network_group.serialize(serializer)?; + self.pp_economic_group.serialize(serializer)?; + self.pp_technical_group.serialize(serializer)?; + self.pp_governance_group.serialize(serializer)?; + self.treasury_withdrawal.serialize(serializer) + } +} + +impl_deserialize_for_wrapped_tuple!(DrepVotingThresholds); + +impl DeserializeEmbeddedGroup for DrepVotingThresholds { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + check_len( + len, + 10, + "[\ + motion_no_confidence, \ + committee_normal, \ + committee_no_confidence, \ + update_constitution, \ + hard_fork_initiation, \ + pp_network_group, \ + pp_economic_group, \ + pp_technical_group, \ + pp_governance_group, \ + treasury_withdrawal\ + ]", + )?; + + let motion_no_confidence = UnitInterval::deserialize(raw) + .map_err(|e| e.annotate("motion_no_confidence"))?; + let committee_normal = UnitInterval::deserialize(raw) + .map_err(|e| e.annotate("committee_normal"))?; + let committee_no_confidence = UnitInterval::deserialize(raw) + .map_err(|e| e.annotate("committee_no_confidence"))?; + let update_constitution = UnitInterval::deserialize(raw) + .map_err(|e| e.annotate("update_constitution"))?; + let hard_fork_initiation = UnitInterval::deserialize(raw) + .map_err(|e| e.annotate("hard_fork_initiation"))?; + let pp_network_group = UnitInterval::deserialize(raw) + .map_err(|e| e.annotate("pp_network_group"))?; + let pp_economic_group = UnitInterval::deserialize(raw) + .map_err(|e| e.annotate("pp_economic_group"))?; + let pp_technical_group = UnitInterval::deserialize(raw) + .map_err(|e| e.annotate("pp_technical_group"))?; + let pp_governance_group = UnitInterval::deserialize(raw) + .map_err(|e| e.annotate("pp_governance_group"))?; + let treasury_withdrawal = UnitInterval::deserialize(raw) + .map_err(|e| e.annotate("treasury_withdrawal"))?; + + return Ok(DrepVotingThresholds { + motion_no_confidence, + committee_normal, + committee_no_confidence, + update_constitution, + hard_fork_initiation, + pp_network_group, + pp_economic_group, + pp_technical_group, + pp_governance_group, + treasury_withdrawal, + }); + } +} + +impl cbor_event::se::Serialize for ProtocolParamUpdate { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_map(cbor_event::Len::Len( + match &self.minfee_a { + Some(_) => 1, + None => 0, + } + match &self.minfee_b { + Some(_) => 1, + None => 0, + } + match &self.max_block_body_size { + Some(_) => 1, + None => 0, + } + match &self.max_tx_size { + Some(_) => 1, + None => 0, + } + match &self.max_block_header_size { + Some(_) => 1, + None => 0, + } + match &self.key_deposit { + Some(_) => 1, + None => 0, + } + match &self.pool_deposit { + Some(_) => 1, + None => 0, + } + match &self.max_epoch { + Some(_) => 1, + None => 0, + } + match &self.n_opt { + Some(_) => 1, + None => 0, + } + match &self.pool_pledge_influence { + Some(_) => 1, + None => 0, + } + match &self.expansion_rate { + Some(_) => 1, + None => 0, + } + match &self.treasury_growth_rate { + Some(_) => 1, + None => 0, + } + match &self.d { + Some(_) => 1, + None => 0, + } + match &self.extra_entropy { + Some(_) => 1, + None => 0, + } + match &self.protocol_version { + Some(_) => 1, + None => 0, + } + match &self.min_pool_cost { + Some(_) => 1, + None => 0, + } + match &self.ada_per_utxo_byte { + Some(_) => 1, + None => 0, + } + match &self.cost_models { + Some(_) => 1, + None => 0, + } + match &self.execution_costs { + Some(_) => 1, + None => 0, + } + match &self.max_tx_ex_units { + Some(_) => 1, + None => 0, + } + match &self.max_block_ex_units { + Some(_) => 1, + None => 0, + } + match &self.max_value_size { + Some(_) => 1, + None => 0, + } + match &self.collateral_percentage { + Some(_) => 1, + None => 0, + } + match &self.max_collateral_inputs { + Some(_) => 1, + None => 0, + } + match &self.pool_voting_thresholds { + Some(_) => 1, + None => 0, + } + match &self.drep_voting_thresholds { + Some(_) => 1, + None => 0, + } + match &self.min_committee_size { + Some(_) => 1, + None => 0, + } + match &self.committee_term_limit { + Some(_) => 1, + None => 0, + } + match &self.governance_action_validity_period { + Some(_) => 1, + None => 0, + } + match &self.governance_action_deposit { + Some(_) => 1, + None => 0, + } + match &self.drep_deposit { + Some(_) => 1, + None => 0, + } + match &self.drep_inactivity_period { + Some(_) => 1, + None => 0, + }, + ))?; + if let Some(field) = &self.minfee_a { + serializer.write_unsigned_integer(0)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.minfee_b { + serializer.write_unsigned_integer(1)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.max_block_body_size { + serializer.write_unsigned_integer(2)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.max_tx_size { + serializer.write_unsigned_integer(3)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.max_block_header_size { + serializer.write_unsigned_integer(4)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.key_deposit { + serializer.write_unsigned_integer(5)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.pool_deposit { + serializer.write_unsigned_integer(6)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.max_epoch { + serializer.write_unsigned_integer(7)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.n_opt { + serializer.write_unsigned_integer(8)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.pool_pledge_influence { + serializer.write_unsigned_integer(9)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.expansion_rate { + serializer.write_unsigned_integer(10)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.treasury_growth_rate { + serializer.write_unsigned_integer(11)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.d { + serializer.write_unsigned_integer(12)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.extra_entropy { + serializer.write_unsigned_integer(13)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.protocol_version { + serializer.write_unsigned_integer(14)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.min_pool_cost { + serializer.write_unsigned_integer(16)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.ada_per_utxo_byte { + serializer.write_unsigned_integer(17)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.cost_models { + serializer.write_unsigned_integer(18)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.execution_costs { + serializer.write_unsigned_integer(19)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.max_tx_ex_units { + serializer.write_unsigned_integer(20)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.max_block_ex_units { + serializer.write_unsigned_integer(21)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.max_value_size { + serializer.write_unsigned_integer(22)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.collateral_percentage { + serializer.write_unsigned_integer(23)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.max_collateral_inputs { + serializer.write_unsigned_integer(24)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.pool_voting_thresholds { + serializer.write_unsigned_integer(25)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.drep_voting_thresholds { + serializer.write_unsigned_integer(26)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.min_committee_size { + serializer.write_unsigned_integer(27)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.committee_term_limit { + serializer.write_unsigned_integer(28)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.governance_action_validity_period { + serializer.write_unsigned_integer(29)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.governance_action_deposit { + serializer.write_unsigned_integer(30)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.drep_deposit { + serializer.write_unsigned_integer(31)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.drep_inactivity_period { + serializer.write_unsigned_integer(32)?; + field.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for ProtocolParamUpdate { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.map()?; + let mut read_len = CBORReadLen::new(len); + let mut minfee_a = None; + let mut minfee_b = None; + let mut max_block_body_size = None; + let mut max_tx_size = None; + let mut max_block_header_size = None; + let mut key_deposit = None; + let mut pool_deposit = None; + let mut max_epoch = None; + let mut n_opt = None; + let mut pool_pledge_influence = None; + let mut expansion_rate = None; + let mut treasury_growth_rate = None; + let mut d = None; + let mut extra_entropy = None; + let mut protocol_version = None; + let mut min_pool_cost = None; + let mut ada_per_utxo_byte = None; + let mut cost_models = None; + let mut execution_costs = None; + let mut max_tx_ex_units = None; + let mut max_block_ex_units = None; + let mut max_value_size = None; + let mut collateral_percentage = None; + let mut max_collateral_inputs = None; + let mut pool_voting_thresholds = None; + let mut drep_voting_thresholds = None; + let mut min_committee_size = None; + let mut committee_term_limit = None; + let mut governance_action_validity_period = None; + let mut governance_action_deposit = None; + let mut drep_deposit = None; + let mut drep_inactivity_period = None; + + let mut read = 0; + while match len { + cbor_event::Len::Len(n) => read < n as usize, + cbor_event::Len::Indefinite => true, + } { + match raw.cbor_type()? { + CBORType::UnsignedInteger => match raw.unsigned_integer()? { + 0 => { + if minfee_a.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(0)).into()); + } + minfee_a = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Coin::deserialize(raw)?) + })() + .map_err(|e| e.annotate("minfee_a"))?, + ); + } + 1 => { + if minfee_b.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(1)).into()); + } + minfee_b = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Coin::deserialize(raw)?) + })() + .map_err(|e| e.annotate("minfee_b"))?, + ); + } + 2 => { + if max_block_body_size.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(2)).into()); + } + max_block_body_size = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(u32::deserialize(raw)?) + })() + .map_err(|e| e.annotate("max_block_body_size"))?, + ); + } + 3 => { + if max_tx_size.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(3)).into()); + } + max_tx_size = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(u32::deserialize(raw)?) + })() + .map_err(|e| e.annotate("max_tx_size"))?, + ); + } + 4 => { + if max_block_header_size.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(4)).into()); + } + max_block_header_size = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(u32::deserialize(raw)?) + })() + .map_err(|e| e.annotate("max_block_header_size"))?, + ); + } + 5 => { + if key_deposit.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(5)).into()); + } + key_deposit = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Coin::deserialize(raw)?) + })() + .map_err(|e| e.annotate("key_deposit"))?, + ); + } + 6 => { + if pool_deposit.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(6)).into()); + } + pool_deposit = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Coin::deserialize(raw)?) + })() + .map_err(|e| e.annotate("pool_deposit"))?, + ); + } + 7 => { + if max_epoch.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(7)).into()); + } + max_epoch = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Epoch::deserialize(raw)?) + })() + .map_err(|e| e.annotate("max_epoch"))?, + ); + } + 8 => { + if n_opt.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(8)).into()); + } + n_opt = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(u32::deserialize(raw)?) + })() + .map_err(|e| e.annotate("n_opt"))?, + ); + } + 9 => { + if pool_pledge_influence.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(9)).into()); + } + pool_pledge_influence = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Rational::deserialize(raw)?) + })() + .map_err(|e| e.annotate("pool_pledge_influence"))?, + ); + } + 10 => { + if expansion_rate.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(10)).into()); + } + expansion_rate = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(UnitInterval::deserialize(raw)?) + })() + .map_err(|e| e.annotate("expansion_rate"))?, + ); + } + 11 => { + if treasury_growth_rate.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(11)).into()); + } + treasury_growth_rate = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(UnitInterval::deserialize(raw)?) + })() + .map_err(|e| e.annotate("treasury_growth_rate"))?, + ); + } + 12 => { + if d.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(12)).into()); + } + d = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(UnitInterval::deserialize(raw)?) + })() + .map_err(|e| e.annotate("d"))?, + ); + } + 13 => { + if extra_entropy.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(13)).into()); + } + extra_entropy = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Nonce::deserialize(raw)?) + })() + .map_err(|e| e.annotate("extra_entropy"))?, + ); + } + 14 => { + if protocol_version.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(14)).into()); + } + protocol_version = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(ProtocolVersion::deserialize(raw)?) + })() + .map_err(|e| e.annotate("protocol_version"))?, + ); + } + 16 => { + if min_pool_cost.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(16)).into()); + } + min_pool_cost = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Coin::deserialize(raw)?) + })() + .map_err(|e| e.annotate("min_pool_cost"))?, + ); + } + 17 => { + if ada_per_utxo_byte.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(17)).into()); + } + ada_per_utxo_byte = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Coin::deserialize(raw)?) + })() + .map_err(|e| e.annotate("ada_per_utxo_byte"))?, + ); + } + 18 => { + if cost_models.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(18)).into()); + } + cost_models = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Costmdls::deserialize(raw)?) + })() + .map_err(|e| e.annotate("cost_models"))?, + ); + } + 19 => { + if execution_costs.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(19)).into()); + } + execution_costs = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(ExUnitPrices::deserialize(raw)?) + })() + .map_err(|e| e.annotate("execution_costs"))?, + ); + } + 20 => { + if max_tx_ex_units.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(20)).into()); + } + max_tx_ex_units = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(ExUnits::deserialize(raw)?) + })() + .map_err(|e| e.annotate("max_tx_ex_units"))?, + ); + } + 21 => { + if max_block_ex_units.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(21)).into()); + } + max_block_ex_units = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(ExUnits::deserialize(raw)?) + })() + .map_err(|e| e.annotate("max_block_ex_units"))?, + ); + } + 22 => { + if max_value_size.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(22)).into()); + } + max_value_size = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(u32::deserialize(raw)?) + })() + .map_err(|e| e.annotate("max_value_size"))?, + ); + } + 23 => { + if collateral_percentage.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(23)).into()); + } + collateral_percentage = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(u32::deserialize(raw)?) + })() + .map_err(|e| e.annotate("collateral_percentage"))?, + ); + } + 24 => { + if max_collateral_inputs.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(24)).into()); + } + max_collateral_inputs = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(u32::deserialize(raw)?) + })() + .map_err(|e| e.annotate("max_collateral_inputs"))?, + ); + } + 25 => { + if pool_voting_thresholds.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(25)).into()); + } + pool_voting_thresholds = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(PoolVotingThresholds::deserialize(raw)?) + })() + .map_err(|e| e.annotate("pool_voting_thresholds"))?, + ); + } + 26 => { + if drep_voting_thresholds.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(26)).into()); + } + drep_voting_thresholds = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(DrepVotingThresholds::deserialize(raw)?) + })() + .map_err(|e| e.annotate("drep_voting_thresholds"))?, + ); + } + 27 => { + if min_committee_size.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(27)).into()); + } + min_committee_size = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(u32::deserialize(raw)?) + })() + .map_err(|e| e.annotate("min_committee_size"))?, + ); + } + 28 => { + if committee_term_limit.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(28)).into()); + } + committee_term_limit = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Epoch::deserialize(raw)?) + })() + .map_err(|e| e.annotate("committee_term_limit"))?, + ); + } + 29 => { + if governance_action_validity_period.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(29)).into()); + } + governance_action_validity_period = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Epoch::deserialize(raw)?) + })() + .map_err(|e| e.annotate("governance_action_validity_period"))?, + ); + } + 30 => { + if governance_action_deposit.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(30)).into()); + } + governance_action_deposit = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Coin::deserialize(raw)?) + })() + .map_err(|e| e.annotate("governance_action_deposit"))?, + ); + } + 31 => { + if drep_deposit.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(31)).into()); + } + drep_deposit = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Coin::deserialize(raw)?) + })() + .map_err(|e| e.annotate("drep_deposit"))?, + ); + } + 32 => { + if drep_inactivity_period.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(32)).into()); + } + drep_inactivity_period = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Epoch::deserialize(raw)?) + })() + .map_err(|e| e.annotate("drep_inactivity_period"))?, + ); + } + unknown_key => { + return Err( + DeserializeFailure::UnknownKey(Key::Uint(unknown_key)).into() + ) + } + }, + CBORType::Text => match raw.text()?.as_str() { + unknown_key => { + return Err(DeserializeFailure::UnknownKey(Key::Str( + unknown_key.to_owned(), + )) + .into()) + } + }, + CBORType::Special => match len { + cbor_event::Len::Len(_) => { + return Err(DeserializeFailure::BreakInDefiniteLen.into()) + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => break, + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + }, + other_type => { + return Err(DeserializeFailure::UnexpectedKeyType(other_type).into()) + } + } + read += 1; + } + read_len.finish()?; + Ok(Self { + minfee_a, + minfee_b, + max_block_body_size, + max_tx_size, + max_block_header_size, + key_deposit, + pool_deposit, + max_epoch, + n_opt, + pool_pledge_influence, + expansion_rate, + treasury_growth_rate, + d, + extra_entropy, + protocol_version, + min_pool_cost, + ada_per_utxo_byte, + cost_models, + execution_costs, + max_tx_ex_units, + max_block_ex_units, + max_value_size, + collateral_percentage, + max_collateral_inputs, + pool_voting_thresholds, + drep_voting_thresholds, + min_committee_size, + committee_term_limit, + governance_action_validity_period, + governance_action_deposit, + drep_deposit, + drep_inactivity_period, + }) + })() + .map_err(|e| e.annotate("ProtocolParamUpdate")) + } +} \ No newline at end of file diff --git a/rust/src/serialization/transaction_body.rs b/rust/src/serialization/transaction_body.rs new file mode 100644 index 00000000..add56842 --- /dev/null +++ b/rust/src/serialization/transaction_body.rs @@ -0,0 +1,462 @@ +use crate::*; + +impl cbor_event::se::Serialize for TransactionBody { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_map(cbor_event::Len::Len( + 3 + opt64(&self.ttl) + + opt64(&self.certs) + + opt64(&self.withdrawals) + + opt64(&self.update) + + opt64(&self.auxiliary_data_hash) + + opt64(&self.validity_start_interval) + + opt64(&self.mint) + + opt64(&self.script_data_hash) + + opt64(&self.collateral) + + opt64(&self.required_signers) + + opt64(&self.network_id) + + opt64(&self.collateral_return) + + opt64(&self.total_collateral) + + opt64(&self.reference_inputs) + + opt64(&self.voting_procedures) + + opt64(&self.voting_proposals) + + opt64(&self.donation) + + opt64(&self.current_treasury_value), + ))?; + serializer.write_unsigned_integer(0)?; + self.inputs.serialize(serializer)?; + serializer.write_unsigned_integer(1)?; + self.outputs.serialize(serializer)?; + serializer.write_unsigned_integer(2)?; + self.fee.serialize(serializer)?; + if let Some(field) = &self.ttl { + serializer.write_unsigned_integer(3)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.certs { + serializer.write_unsigned_integer(4)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.withdrawals { + serializer.write_unsigned_integer(5)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.update { + serializer.write_unsigned_integer(6)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.auxiliary_data_hash { + serializer.write_unsigned_integer(7)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.validity_start_interval { + serializer.write_unsigned_integer(8)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.mint { + serializer.write_unsigned_integer(9)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.script_data_hash { + serializer.write_unsigned_integer(11)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.collateral { + serializer.write_unsigned_integer(13)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.required_signers { + serializer.write_unsigned_integer(14)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.network_id { + serializer.write_unsigned_integer(15)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.collateral_return { + serializer.write_unsigned_integer(16)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.total_collateral { + serializer.write_unsigned_integer(17)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.reference_inputs { + serializer.write_unsigned_integer(18)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.voting_procedures { + serializer.write_unsigned_integer(19)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.voting_proposals { + serializer.write_unsigned_integer(20)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.current_treasury_value { + serializer.write_unsigned_integer(21)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.donation { + serializer.write_unsigned_integer(22)?; + field.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for TransactionBody { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.map()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(3)?; + let mut inputs = None; + let mut outputs = None; + let mut fee = None; + let mut ttl = None; + let mut certs = None; + let mut withdrawals = None; + let mut update = None; + let mut auxiliary_data_hash = None; + let mut validity_start_interval = None; + let mut mint = None; + let mut script_data_hash = None; + let mut collateral = None; + let mut required_signers = None; + let mut network_id = None; + let mut collateral_return = None; + let mut total_collateral = None; + let mut reference_inputs = None; + let mut voting_procedures = None; + let mut voting_proposals = None; + let mut current_treasury_value = None; + let mut donation = None; + let mut read = 0; + while match len { + cbor_event::Len::Len(n) => read < n as usize, + cbor_event::Len::Indefinite => true, + } { + match raw.cbor_type()? { + CBORType::UnsignedInteger => match raw.unsigned_integer()? { + 0 => { + if inputs.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(0)).into()); + } + inputs = Some( + (|| -> Result<_, DeserializeError> { + Ok(TransactionInputs::deserialize(raw)?) + })() + .map_err(|e| e.annotate("inputs"))?, + ); + } + 1 => { + if outputs.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(1)).into()); + } + outputs = Some( + (|| -> Result<_, DeserializeError> { + Ok(TransactionOutputs::deserialize(raw)?) + })() + .map_err(|e| e.annotate("outputs"))?, + ); + } + 2 => { + if fee.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(2)).into()); + } + fee = + Some( + (|| -> Result<_, DeserializeError> { + Ok(Coin::deserialize(raw)?) + })() + .map_err(|e| e.annotate("fee"))?, + ); + } + 3 => { + if ttl.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(3)).into()); + } + ttl = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(SlotBigNum::deserialize(raw)?) + })() + .map_err(|e| e.annotate("ttl"))?, + ); + } + 4 => { + if certs.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(4)).into()); + } + certs = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Certificates::deserialize(raw)?) + })() + .map_err(|e| e.annotate("certs"))?, + ); + } + 5 => { + if withdrawals.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(5)).into()); + } + withdrawals = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Withdrawals::deserialize(raw)?) + })() + .map_err(|e| e.annotate("withdrawals"))?, + ); + } + 6 => { + if update.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(6)).into()); + } + update = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Update::deserialize(raw)?) + })() + .map_err(|e| e.annotate("update"))?, + ); + } + 7 => { + if auxiliary_data_hash.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(7)).into()); + } + auxiliary_data_hash = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(AuxiliaryDataHash::deserialize(raw)?) + })() + .map_err(|e| e.annotate("auxiliary_data_hash"))?, + ); + } + 8 => { + if validity_start_interval.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(8)).into()); + } + validity_start_interval = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(SlotBigNum::deserialize(raw)?) + })() + .map_err(|e| e.annotate("validity_start_interval"))?, + ); + } + 9 => { + if mint.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(9)).into()); + } + mint = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Mint::deserialize(raw)?) + })() + .map_err(|e| e.annotate("mint"))?, + ); + } + 11 => { + if script_data_hash.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(11)).into()); + } + script_data_hash = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(ScriptDataHash::deserialize(raw)?) + })() + .map_err(|e| e.annotate("script_data_hash"))?, + ); + } + 13 => { + if collateral.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(13)).into()); + } + collateral = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(TransactionInputs::deserialize(raw)?) + })() + .map_err(|e| e.annotate("collateral"))?, + ); + } + 14 => { + if required_signers.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(14)).into()); + } + required_signers = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(RequiredSigners::deserialize(raw)?) + })() + .map_err(|e| e.annotate("required_signers"))?, + ); + } + 15 => { + if network_id.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(15)).into()); + } + network_id = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(NetworkId::deserialize(raw)?) + })() + .map_err(|e| e.annotate("network_id"))?, + ); + } + 16 => { + if collateral_return.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(16)).into()); + } + collateral_return = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(TransactionOutput::deserialize(raw)?) + })() + .map_err(|e| e.annotate("collateral_return"))?, + ); + } + 17 => { + if total_collateral.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(17)).into()); + } + total_collateral = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Coin::deserialize(raw)?) + })() + .map_err(|e| e.annotate("total_collateral"))?, + ); + } + 18 => { + if reference_inputs.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(18)).into()); + } + reference_inputs = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(TransactionInputs::deserialize(raw)?) + })() + .map_err(|e| e.annotate("reference_inputs"))?, + ); + } + 19 => { + if voting_procedures.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(19)).into()); + } + voting_procedures = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(VotingProcedures::deserialize(raw)?) + })() + .map_err(|e| e.annotate("voting_procedures"))?, + ); + } + 20 => { + if voting_proposals.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(20)).into()); + } + voting_proposals = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(VotingProposals::deserialize(raw)?) + })() + .map_err(|e| e.annotate("voting_proposals"))?, + ); + } + 21 => { + if current_treasury_value.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(21)).into()); + } + current_treasury_value = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Coin::deserialize(raw)?) + })() + .map_err(|e| e.annotate("current_treasury_value"))?, + ); + } + 22 => { + if donation.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(22)).into()); + } + donation = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Coin::deserialize(raw)?) + })() + .map_err(|e| e.annotate("donation"))?, + ); + } + unknown_key => { + return Err( + DeserializeFailure::UnknownKey(Key::Uint(unknown_key)).into() + ) + } + }, + CBORType::Text => match raw.text()?.as_str() { + unknown_key => { + return Err(DeserializeFailure::UnknownKey(Key::Str( + unknown_key.to_owned(), + )) + .into()) + } + }, + CBORType::Special => match len { + cbor_event::Len::Len(_) => { + return Err(DeserializeFailure::BreakInDefiniteLen.into()) + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => break, + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + }, + other_type => { + return Err(DeserializeFailure::UnexpectedKeyType(other_type).into()) + } + } + read += 1; + } + let inputs = match inputs { + Some(x) => x, + None => return Err(DeserializeFailure::MandatoryFieldMissing(Key::Uint(0)).into()), + }; + let outputs = match outputs { + Some(x) => x, + None => return Err(DeserializeFailure::MandatoryFieldMissing(Key::Uint(1)).into()), + }; + let fee = match fee { + Some(x) => x, + None => return Err(DeserializeFailure::MandatoryFieldMissing(Key::Uint(2)).into()), + }; + read_len.finish()?; + Ok(Self { + inputs, + outputs, + fee, + ttl, + certs, + withdrawals, + update, + auxiliary_data_hash, + validity_start_interval, + mint, + script_data_hash, + collateral, + required_signers, + network_id, + collateral_return, + total_collateral, + reference_inputs, + voting_procedures, + voting_proposals, + donation, + current_treasury_value, + }) + })() + .map_err(|e| e.annotate("TransactionBody")) + } +} \ No newline at end of file diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index cf1b85f8..a44c23b6 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -3,11 +3,7 @@ use crate::fakes::{ fake_script_hash, fake_tx_hash, fake_tx_input, fake_tx_input2, fake_value, fake_value2, }; use crate::tests::helpers::harden; -use crate::tests::mock_objects::{ - byron_address, create_default_tx_builder, create_linear_fee, create_reallistic_tx_builder, - create_tx_builder_with_fee, create_tx_builder_with_fee_and_pure_change, - create_tx_builder_with_fee_and_val_size, create_tx_builder_with_key_deposit, -}; +use crate::tests::mock_objects::{byron_address, create_change_address, create_default_tx_builder, create_linear_fee, create_reallistic_tx_builder, create_rich_tx_builder, create_tx_builder_with_amount, create_tx_builder_with_fee, create_tx_builder_with_fee_and_pure_change, create_tx_builder_with_fee_and_val_size, create_tx_builder_with_key_deposit}; use crate::*; use fees::*; @@ -6448,3 +6444,59 @@ pub fn test_extra_datum() { assert_eq!(tx.witness_set().plutus_data().unwrap().len(), 1usize); assert_eq!(tx.witness_set().plutus_data().unwrap().get(0), datum); } + +#[test] +fn current_treasure_value_test() { + let input_amount = 10000000000; + let mut builder = create_tx_builder_with_amount(input_amount, false); + let treasure_value = Coin::from(1000000000u64); + + assert_eq!(builder.get_current_treasury_value(), None); + + builder.set_current_treasury_value(&treasure_value).unwrap(); + builder.add_change_if_needed(&create_change_address()).unwrap(); + + assert_eq!(builder.get_current_treasury_value().unwrap(), treasure_value); + + let tx = builder.build_tx().unwrap(); + assert_eq!(tx.body().outputs().len(), 1); + + let mut total_out = tx.body().outputs().get(0).amount().coin(); + total_out = total_out.checked_add(&tx.body().fee()).unwrap(); + + assert_eq!(total_out, Coin::from(input_amount)); +} + +#[test] +fn current_treasure_value_zero_error_test() { + let mut builder = create_rich_tx_builder(false); + let treasure_value = Coin::from(0u64); + + assert_eq!(builder.get_current_treasury_value(), None); + + let res = builder.set_current_treasury_value(&treasure_value); + assert!(res.is_err()); +} + +#[test] +fn donation_test() { + let input_amount = 10000000000; + let mut builder = create_tx_builder_with_amount(input_amount, false); + let donation = Coin::from(1000u64); + + assert_eq!(builder.get_donation(), None); + + builder.set_donation(&donation); + builder.add_change_if_needed(&create_change_address()).unwrap(); + + assert_eq!(builder.get_donation().unwrap(), donation); + + let tx = builder.build_tx().unwrap(); + assert_eq!(tx.body().outputs().len(), 1); + + let mut total_out = tx.body().outputs().get(0).amount().coin(); + total_out = total_out.checked_add(&tx.body().fee()).unwrap(); + total_out = total_out.checked_add(&donation).unwrap(); + + assert_eq!(total_out, Coin::from(input_amount)); +} diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/mock_objects.rs index a9bf1771..bfd8c282 100644 --- a/rust/src/tests/mock_objects.rs +++ b/rust/src/tests/mock_objects.rs @@ -85,9 +85,41 @@ pub(crate) fn crate_full_protocol_param_update() -> ProtocolParamUpdate { max_value_size: Some(44_444u32), collateral_percentage: Some(44_444u32), max_collateral_inputs: Some(44_444u32), + pool_voting_thresholds: Some(create_pool_voting_thresholds()), + drep_voting_thresholds: Some(create_drep_voting_thresholds()), + min_committee_size: Some(44_444u32), + committee_term_limit: Some(44_444u32), + governance_action_validity_period: Some(44_444u32), + governance_action_deposit: Some(Coin::from(44_444u32)), + drep_deposit: Some(Coin::from(44_444u32)), + drep_inactivity_period: Some(44_444u32), } } +pub(crate) fn create_pool_voting_thresholds() -> PoolVotingThresholds { + PoolVotingThresholds::new( + &UnitInterval::new(&BigNum::from(44_401u32), &BigNum::from(44_402u32)), + &UnitInterval::new(&BigNum::from(44_403u32), &BigNum::from(44_404u32)), + &UnitInterval::new(&BigNum::from(44_405u32), &BigNum::from(44_406u32)), + &UnitInterval::new(&BigNum::from(44_406u32), &BigNum::from(44_407u32)), + ) +} + +pub(crate) fn create_drep_voting_thresholds() -> DrepVotingThresholds { + DrepVotingThresholds::new( + &UnitInterval::new(&BigNum::from(44_401u32), &BigNum::from(44_402u32)), + &UnitInterval::new(&BigNum::from(44_403u32), &BigNum::from(44_404u32)), + &UnitInterval::new(&BigNum::from(44_405u32), &BigNum::from(44_406u32)), + &UnitInterval::new(&BigNum::from(44_406u32), &BigNum::from(44_407u32)), + &UnitInterval::new(&BigNum::from(44_408u32), &BigNum::from(44_409u32)), + &UnitInterval::new(&BigNum::from(44_410u32), &BigNum::from(44_411u32)), + &UnitInterval::new(&BigNum::from(44_412u32), &BigNum::from(44_412u32)), + &UnitInterval::new(&BigNum::from(44_414u32), &BigNum::from(44_415u32)), + &UnitInterval::new(&BigNum::from(44_416u32), &BigNum::from(44_417u32)), + &UnitInterval::new(&BigNum::from(44_418u32), &BigNum::from(44_419u32)), + ) +} + pub(crate) fn crate_full_pool_params() -> PoolParams { PoolParams { operator: fake_key_hash(1), diff --git a/rust/src/tests/serialization/mod.rs b/rust/src/tests/serialization/mod.rs index b05029ea..e4d315ea 100644 --- a/rust/src/tests/serialization/mod.rs +++ b/rust/src/tests/serialization/mod.rs @@ -1,2 +1,4 @@ pub mod certificates; pub mod governance; +pub mod transaction_body; +pub mod protocol_param_update; diff --git a/rust/src/tests/serialization/protocol_param_update.rs b/rust/src/tests/serialization/protocol_param_update.rs new file mode 100644 index 00000000..14316e66 --- /dev/null +++ b/rust/src/tests/serialization/protocol_param_update.rs @@ -0,0 +1,117 @@ +use crate::*; +use crate::tests::mock_objects::{create_cost_models, create_drep_voting_thresholds, create_pool_voting_thresholds}; + +#[test] +fn protocol_param_update_ser_round_trip() { + let pp_update= ProtocolParamUpdate { + minfee_a: Some(Coin::from(1_444u32)), + minfee_b: Some(Coin::from(2_444u32)), + max_block_body_size: Some(3_444u32), + max_tx_size: Some(4_444u32), + max_block_header_size: Some(5_444u32), + key_deposit: Some(Coin::from(6_444u32)), + pool_deposit: Some(Coin::from(7_444u32)), + max_epoch: Some(8_444u32), + n_opt: Some(9_444u32), + pool_pledge_influence: Some(Rational::new( + &BigNum::from(10_444u32), + &BigNum::from(11_444u32), + )), + expansion_rate: Some(UnitInterval::new( + &BigNum::from(12_444u32), + &BigNum::from(13_444u32), + )), + treasury_growth_rate: Some(UnitInterval::new( + &BigNum::from(14_444u32), + &BigNum::from(15_444u32), + )), + d: Some(UnitInterval::new( + &BigNum::from(16_444u32), + &BigNum::from(17_444u32), + )), + extra_entropy: Some(Nonce::new_identity()), + protocol_version: Some(ProtocolVersion::new(1, 2)), + min_pool_cost: Some(Coin::from(18_444u32)), + ada_per_utxo_byte: Some(Coin::from(19_444u32)), + cost_models: Some(create_cost_models()), + execution_costs: Some(ExUnitPrices::new( + &SubCoin::new(&to_bignum(577), &to_bignum(10000)), + &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + )), + max_tx_ex_units: Some(ExUnits::new(&to_bignum(842996), &to_bignum(246100241))), + max_block_ex_units: Some(ExUnits::new(&to_bignum(842996), &to_bignum(246100241))), + max_value_size: Some(20_444u32), + collateral_percentage: Some(21_444u32), + max_collateral_inputs: Some(22_444u32), + pool_voting_thresholds: Some(create_pool_voting_thresholds()), + drep_voting_thresholds: Some(create_drep_voting_thresholds()), + min_committee_size: Some(23_444u32), + committee_term_limit: Some(24_444u32), + governance_action_validity_period: Some(25_444u32), + governance_action_deposit: Some(Coin::from(26_444u32)), + drep_deposit: Some(Coin::from(27_444u32)), + drep_inactivity_period: Some(28_444u32), + }; + + let cbor = pp_update.to_bytes(); + let hex = pp_update.to_hex(); + let json = pp_update.to_json().unwrap(); + + let pp_update_from_cbor = ProtocolParamUpdate::from_bytes(cbor).unwrap(); + let pp_update_from_hex = ProtocolParamUpdate::from_hex(&hex).unwrap(); + let pp_update_from_json = ProtocolParamUpdate::from_json(&json).unwrap(); + + assert_eq!(pp_update, pp_update_from_cbor); + assert_eq!(pp_update, pp_update_from_hex); + assert_eq!(pp_update, pp_update_from_json); +} + +#[test] +fn pool_voting_thresholds_ser_round_trip() { + let thresholds = PoolVotingThresholds::new( + &UnitInterval::new(&BigNum::from(44_401u32), &BigNum::from(44_402u32)), + &UnitInterval::new(&BigNum::from(44_403u32), &BigNum::from(44_404u32)), + &UnitInterval::new(&BigNum::from(44_405u32), &BigNum::from(44_406u32)), + &UnitInterval::new(&BigNum::from(44_406u32), &BigNum::from(44_407u32)), + ); + + let cbor = thresholds.to_bytes(); + let hex = thresholds.to_hex(); + let json = thresholds.to_json().unwrap(); + + let thresholds_from_cbor = PoolVotingThresholds::from_bytes(cbor).unwrap(); + let thresholds_from_hex = PoolVotingThresholds::from_hex(&hex).unwrap(); + let thresholds_from_json = PoolVotingThresholds::from_json(&json).unwrap(); + + assert_eq!(thresholds, thresholds_from_cbor); + assert_eq!(thresholds, thresholds_from_hex); + assert_eq!(thresholds, thresholds_from_json); +} + +#[test] +fn drep_voting_thresholds_ser_round_trip() { + let thresholds = DrepVotingThresholds::new( + &UnitInterval::new(&BigNum::from(44_401u32), &BigNum::from(44_402u32)), + &UnitInterval::new(&BigNum::from(44_403u32), &BigNum::from(44_404u32)), + &UnitInterval::new(&BigNum::from(44_405u32), &BigNum::from(44_406u32)), + &UnitInterval::new(&BigNum::from(44_406u32), &BigNum::from(44_407u32)), + &UnitInterval::new(&BigNum::from(44_408u32), &BigNum::from(44_409u32)), + &UnitInterval::new(&BigNum::from(44_410u32), &BigNum::from(44_411u32)), + &UnitInterval::new(&BigNum::from(44_412u32), &BigNum::from(44_412u32)), + &UnitInterval::new(&BigNum::from(44_414u32), &BigNum::from(44_415u32)), + &UnitInterval::new(&BigNum::from(44_416u32), &BigNum::from(44_417u32)), + &UnitInterval::new(&BigNum::from(44_418u32), &BigNum::from(44_419u32)), + ); + + let cbor = thresholds.to_bytes(); + let hex = thresholds.to_hex(); + let json = thresholds.to_json().unwrap(); + + let thresholds_from_cbor = DrepVotingThresholds::from_bytes(cbor).unwrap(); + let thresholds_from_hex = DrepVotingThresholds::from_hex(&hex).unwrap(); + let thresholds_from_json = DrepVotingThresholds::from_json(&json).unwrap(); + + assert_eq!(thresholds, thresholds_from_cbor); + assert_eq!(thresholds, thresholds_from_hex); + assert_eq!(thresholds, thresholds_from_json); +} \ No newline at end of file diff --git a/rust/src/tests/serialization/transaction_body.rs b/rust/src/tests/serialization/transaction_body.rs new file mode 100644 index 00000000..517acb19 --- /dev/null +++ b/rust/src/tests/serialization/transaction_body.rs @@ -0,0 +1,44 @@ +use crate::fakes::{ + fake_auxiliary_data_hash, fake_base_address, fake_script_data_hash, fake_tx_input, +}; +use crate::*; + +#[test] +fn transaction_round_trip_test() { + let input = fake_tx_input(1); + let output = TransactionOutput::new(&fake_base_address(2), &Value::new(&to_bignum(1_000_001))); + let inputs = TransactionInputs(vec![input]); + let outputs = TransactionOutputs(vec![output]); + let fee = Coin::from(1_000_002u64); + let mut body = TransactionBody::new_tx_body(&inputs, &outputs, &fee); + + body.set_ttl(&to_bignum(1_000_003u64)); + body.set_certs(&Certificates::new()); + body.set_withdrawals(&Withdrawals::new()); + body.set_update(&Update::new(&ProposedProtocolParameterUpdates::new(), 1)); + body.set_auxiliary_data_hash(&fake_auxiliary_data_hash(2)); + body.set_validity_start_interval_bignum(&SlotBigNum::from(1_000_004u64)); + body.set_mint(&Mint::new()); + body.set_reference_inputs(&TransactionInputs::new()); + body.set_script_data_hash(&fake_script_data_hash(3)); + body.set_collateral(&TransactionInputs::new()); + body.set_required_signers(&RequiredSigners::new()); + body.set_network_id(&NetworkId::testnet()); + body.set_collateral_return(&TransactionOutput::new( + &fake_base_address(4), + &Value::new(&to_bignum(1_000_005u64)), + )); + body.set_total_collateral(&Coin::from(1_000_006u64)); + body.set_voting_procedures(&VotingProcedures::new()); + body.set_voting_proposals(&VotingProposals::new()); + body.set_donation(&Coin::from(1_000_007u64)); + body.set_current_treasury_value(&Coin::from(1_000_008u64)); + + let body_cbor = body.to_bytes(); + let body_hex_cbor = body.to_hex(); + let body_json = body.to_json().unwrap(); + + assert_eq!(TransactionBody::from_bytes(body_cbor).unwrap(), body); + assert_eq!(TransactionBody::from_hex(&body_hex_cbor).unwrap(), body); + assert_eq!(TransactionBody::from_json(&body_json).unwrap(), body); +} diff --git a/rust/src/utils.rs b/rust/src/utils.rs index 3f3183be..f0a18184 100644 --- a/rust/src/utils.rs +++ b/rust/src/utils.rs @@ -152,7 +152,7 @@ impl<'a> IntoIterator for &'a TransactionUnspentOutputs { // This is an unsigned type - no negative numbers. // Can be converted to/from plain rust #[wasm_bindgen] -#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Default)] pub struct BigNum(u64); impl_to_from!(BigNum); From 62af76106855b04f4d71316ce89f8b361f181382 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 10 Sep 2023 03:21:20 +0500 Subject: [PATCH 138/349] update schema gen --- rust/json-gen/src/main.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rust/json-gen/src/main.rs b/rust/json-gen/src/main.rs index 98ddfe99..809bae29 100644 --- a/rust/json-gen/src/main.rs +++ b/rust/json-gen/src/main.rs @@ -186,4 +186,6 @@ fn main() { gen_json_schema!(TreasuryWithdrawalsProposal); gen_json_schema!(Committee); gen_json_schema!(Constitution); + gen_json_schema!(DrepVotingThresholds); + gen_json_schema!(PoolVotingThresholds); } From 6b4a97e5840022f9f8b6556e8a21d25274ebf0dc Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 10 Sep 2023 03:26:12 +0500 Subject: [PATCH 139/349] add mint zero check --- rust/src/builders/mint_builder.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/rust/src/builders/mint_builder.rs b/rust/src/builders/mint_builder.rs index c11d494e..b737f54b 100644 --- a/rust/src/builders/mint_builder.rs +++ b/rust/src/builders/mint_builder.rs @@ -60,12 +60,20 @@ impl MintBuilder { } } - pub fn add_asset(&mut self, mint: &MintWitness, asset_name: &AssetName, amount: &Int) { - self.update_mint_value(mint, asset_name, amount, false); + pub fn add_asset(&mut self, mint: &MintWitness, asset_name: &AssetName, amount: &Int) -> Result<(), JsError> { + if amount.0 == 0 { + return Err(JsError::from_str("Mint cannot be zero.")); + } + self.update_mint_value(mint, asset_name, amount, false)?; + Ok(()) } - pub fn set_asset(&mut self, mint: &MintWitness, asset_name: &AssetName, amount: &Int) { - self.update_mint_value(mint, asset_name, amount, true); + pub fn set_asset(&mut self, mint: &MintWitness, asset_name: &AssetName, amount: &Int) -> Result<(), JsError> { + if amount.0 == 0 { + return Err(JsError::from_str("Mint cannot be zero.")); + } + self.update_mint_value(mint, asset_name, amount, true)?; + Ok(()) } fn update_mint_value( @@ -74,7 +82,10 @@ impl MintBuilder { asset_name: &AssetName, amount: &Int, overwrite: bool, - ) { + ) -> Result<(), JsError> { + if amount.0 == 0 { + return Err(JsError::from_str("Mint cannot be zero.")); + } match &mint.0 { MintWitnessEnum::NativeScript(native_script) => { let script_mint = @@ -126,6 +137,7 @@ impl MintBuilder { } } } + Ok(()) } pub fn build(&self) -> Mint { From 62d9c770ccf4a6d19d5fec3b513333a9990f4ba4 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 10 Sep 2023 03:31:01 +0500 Subject: [PATCH 140/349] add mint zero check --- rust/src/builders/tx_builder.rs | 4 ++-- rust/src/lib.rs | 14 ++++++++++---- rust/src/tests/builders/tx_builder.rs | 4 ++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index 66428cf9..e29e8ad5 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -1210,7 +1210,7 @@ impl TransactionBuilder { self.add_mint_asset(policy_script, asset_name, amount.clone()); let multiasset = Mint::new_from_entry( &policy_id, - &MintAssets::new_from_entry(asset_name, amount.clone()), + &MintAssets::new_from_entry(asset_name, amount.clone())?, ) .as_positive_multiasset(); @@ -1240,7 +1240,7 @@ impl TransactionBuilder { self.add_mint_asset(policy_script, asset_name, amount.clone()); let multiasset = Mint::new_from_entry( &policy_id, - &MintAssets::new_from_entry(asset_name, amount.clone()), + &MintAssets::new_from_entry(asset_name, amount.clone())?, ) .as_positive_multiasset(); diff --git a/rust/src/lib.rs b/rust/src/lib.rs index ec8cfccd..bd3b0313 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -2537,18 +2537,24 @@ impl MintAssets { Self(std::collections::BTreeMap::new()) } - pub fn new_from_entry(key: &AssetName, value: Int) -> Self { + pub fn new_from_entry(key: &AssetName, value: Int) -> Result { + if value.0 == 0 { + return Err(JsError::from_str("MintAssets cannot be created with 0 value")); + } let mut ma = MintAssets::new(); ma.insert(key, value); - ma + Ok(ma) } pub fn len(&self) -> usize { self.0.len() } - pub fn insert(&mut self, key: &AssetName, value: Int) -> Option { - self.0.insert(key.clone(), value) + pub fn insert(&mut self, key: &AssetName, value: Int) -> Result, JsError> { + if value.0 == 0 { + return Err(JsError::from_str("MintAssets cannot be created with 0 value")); + } + Ok(self.0.insert(key.clone(), value)) } pub fn get(&self, key: &AssetName) -> Option { diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index a44c23b6..b7651268 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -3081,7 +3081,7 @@ fn create_asset_name() -> AssetName { } fn create_mint_asset() -> MintAssets { - MintAssets::new_from_entry(&create_asset_name(), Int::new_i32(1234)) + MintAssets::new_from_entry(&create_asset_name(), Int::new_i32(1234)).unwrap() } fn create_assets() -> Assets { @@ -3604,7 +3604,7 @@ fn fee_estimation_fails_on_missing_mint_scripts() { let mut mint = Mint::new(); mint.insert( &policy_id1, - &MintAssets::new_from_entry(&name1, amount.clone()), + &MintAssets::new_from_entry(&name1, amount.clone()).unwrap(), ); tx_builder From 85edb9a7f5e7971b4d87c7304622cc539c298c42 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 10 Sep 2023 03:56:26 +0500 Subject: [PATCH 141/349] multiasset can't be empty --- rust/src/serialization/transaction_body.rs | 13 ++++++++++--- rust/src/utils.rs | 20 ++++++++++++++------ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/rust/src/serialization/transaction_body.rs b/rust/src/serialization/transaction_body.rs index add56842..f22b56b6 100644 --- a/rust/src/serialization/transaction_body.rs +++ b/rust/src/serialization/transaction_body.rs @@ -5,6 +5,11 @@ impl cbor_event::se::Serialize for TransactionBody { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { + let has_mint = match &self.mint { + Some(mint) => mint.len() > 0, + None => false, + }; + serializer.write_map(cbor_event::Len::Len( 3 + opt64(&self.ttl) + opt64(&self.certs) @@ -12,7 +17,7 @@ impl cbor_event::se::Serialize for TransactionBody { + opt64(&self.update) + opt64(&self.auxiliary_data_hash) + opt64(&self.validity_start_interval) - + opt64(&self.mint) + + has_mint as u64 + opt64(&self.script_data_hash) + opt64(&self.collateral) + opt64(&self.required_signers) @@ -56,8 +61,10 @@ impl cbor_event::se::Serialize for TransactionBody { field.serialize(serializer)?; } if let Some(field) = &self.mint { - serializer.write_unsigned_integer(9)?; - field.serialize(serializer)?; + if has_mint { + serializer.write_unsigned_integer(9)?; + field.serialize(serializer)?; + } } if let Some(field) = &self.script_data_hash { serializer.write_unsigned_integer(11)?; diff --git a/rust/src/utils.rs b/rust/src/utils.rs index f0a18184..c15a08a4 100644 --- a/rust/src/utils.rs +++ b/rust/src/utils.rs @@ -555,14 +555,22 @@ impl cbor_event::se::Serialize for Value { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - match &self.multiasset { - Some(multiasset) => { - serializer.write_array(cbor_event::Len::Len(2))?; - self.coin.serialize(serializer)?; - multiasset.serialize(serializer) + let multiasset_len = match &self.multiasset { + Some(multiasset) => multiasset.len(), + None => 0, + }; + + if multiasset_len == 0 { + self.coin.serialize(serializer)?; + } else { + serializer.write_array(cbor_event::Len::Len(2))?; + self.coin.serialize(serializer)?; + if let Some(multiasset) = &self.multiasset { + multiasset.serialize(serializer)?; } - None => self.coin.serialize(serializer), } + + Ok(serializer) } } From 6ea9932df39b2d65befa89d5b3343f21f6f35165 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 10 Sep 2023 03:56:39 +0500 Subject: [PATCH 142/349] fix for flowgen --- rust/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index bd3b0313..6f48f9e6 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -2537,12 +2537,12 @@ impl MintAssets { Self(std::collections::BTreeMap::new()) } - pub fn new_from_entry(key: &AssetName, value: Int) -> Result { + pub fn new_from_entry(key: &AssetName, value: &Int) -> Result { if value.0 == 0 { return Err(JsError::from_str("MintAssets cannot be created with 0 value")); } let mut ma = MintAssets::new(); - ma.insert(key, value); + ma.insert(key, value.clone())?; Ok(ma) } From 98d4c0e54fad211ee783df90d7f9af5711584c38 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 10 Sep 2023 03:57:10 +0500 Subject: [PATCH 143/349] fix test --- rust/src/tests/serialization/transaction_body.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/rust/src/tests/serialization/transaction_body.rs b/rust/src/tests/serialization/transaction_body.rs index 517acb19..18ff0735 100644 --- a/rust/src/tests/serialization/transaction_body.rs +++ b/rust/src/tests/serialization/transaction_body.rs @@ -1,6 +1,4 @@ -use crate::fakes::{ - fake_auxiliary_data_hash, fake_base_address, fake_script_data_hash, fake_tx_input, -}; +use crate::fakes::{fake_asset_name, fake_auxiliary_data_hash, fake_base_address, fake_policy_id, fake_script_data_hash, fake_tx_input}; use crate::*; #[test] @@ -11,6 +9,12 @@ fn transaction_round_trip_test() { let outputs = TransactionOutputs(vec![output]); let fee = Coin::from(1_000_002u64); let mut body = TransactionBody::new_tx_body(&inputs, &outputs, &fee); + let mut mint = Mint::new(); + let mint_asset = MintAssets::new_from_entry( + &fake_asset_name(4), + &Int::new(&to_bignum(1_000_003u64)), + ).unwrap(); + mint.insert(&fake_policy_id(3), &mint_asset); body.set_ttl(&to_bignum(1_000_003u64)); body.set_certs(&Certificates::new()); @@ -18,7 +22,7 @@ fn transaction_round_trip_test() { body.set_update(&Update::new(&ProposedProtocolParameterUpdates::new(), 1)); body.set_auxiliary_data_hash(&fake_auxiliary_data_hash(2)); body.set_validity_start_interval_bignum(&SlotBigNum::from(1_000_004u64)); - body.set_mint(&Mint::new()); + body.set_mint(&mint); body.set_reference_inputs(&TransactionInputs::new()); body.set_script_data_hash(&fake_script_data_hash(3)); body.set_collateral(&TransactionInputs::new()); From 21a9bb922ed247285db11b882cd6b37042b538dc Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 10 Sep 2023 03:58:10 +0500 Subject: [PATCH 144/349] prevent Int destroy in mint types --- rust/src/builders/tx_builder.rs | 14 +++++----- rust/src/fakes.rs | 10 +++---- rust/src/tests/builders/tx_builder.rs | 38 +++++++++++++-------------- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index e29e8ad5..e6f54b5b 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -1179,7 +1179,7 @@ impl TransactionBuilder { &mut self, policy_script: &NativeScript, asset_name: &AssetName, - amount: Int, + amount: &Int, ) { let mint_witness = MintWitness::new_native_script(policy_script); if let Some(mint) = &mut self.mint { @@ -1199,7 +1199,7 @@ impl TransactionBuilder { &mut self, policy_script: &NativeScript, asset_name: &AssetName, - amount: Int, + amount: &Int, output_builder: &TransactionOutputAmountBuilder, output_coin: &Coin, ) -> Result<(), JsError> { @@ -1207,10 +1207,10 @@ impl TransactionBuilder { return Err(JsError::from_str("Output value must be positive!")); } let policy_id: PolicyID = policy_script.hash(); - self.add_mint_asset(policy_script, asset_name, amount.clone()); + self.add_mint_asset(policy_script, asset_name, amount); let multiasset = Mint::new_from_entry( &policy_id, - &MintAssets::new_from_entry(asset_name, amount.clone())?, + &MintAssets::new_from_entry(asset_name, amount)?, ) .as_positive_multiasset(); @@ -1230,17 +1230,17 @@ impl TransactionBuilder { &mut self, policy_script: &NativeScript, asset_name: &AssetName, - amount: Int, + amount: &Int, output_builder: &TransactionOutputAmountBuilder, ) -> Result<(), JsError> { if !amount.is_positive() { return Err(JsError::from_str("Output value must be positive!")); } let policy_id: PolicyID = policy_script.hash(); - self.add_mint_asset(policy_script, asset_name, amount.clone()); + self.add_mint_asset(policy_script, asset_name, amount); let multiasset = Mint::new_from_entry( &policy_id, - &MintAssets::new_from_entry(asset_name, amount.clone())?, + &MintAssets::new_from_entry(asset_name, amount)?, ) .as_positive_multiasset(); diff --git a/rust/src/fakes.rs b/rust/src/fakes.rs index 1228b08c..81d810be 100644 --- a/rust/src/fakes.rs +++ b/rust/src/fakes.rs @@ -1,10 +1,6 @@ #![allow(dead_code)] use crate::crypto::{AnchorDataHash, AuxiliaryDataHash, GenesisDelegateHash, GenesisHash, PoolMetadataHash, ScriptDataHash, ScriptHash, VRFKeyHash}; -use crate::{ - to_bignum, Address, BaseAddress, Bip32PrivateKey, Credential, DataHash, Ed25519KeyHash, - Ed25519Signature, NetworkInfo, PolicyID, TransactionHash, TransactionIndex, TransactionInput, - TransactionOutput, Value, Vkey, -}; +use crate::{to_bignum, Address, BaseAddress, Bip32PrivateKey, Credential, DataHash, Ed25519KeyHash, Ed25519Signature, NetworkInfo, PolicyID, TransactionHash, TransactionIndex, TransactionInput, TransactionOutput, Value, Vkey, AssetName}; pub(crate) fn fake_bytes_32(x: u8) -> Vec { vec![ @@ -106,3 +102,7 @@ pub(crate) fn fake_signature(x: u8) -> Ed25519Signature { pub(crate) fn fake_policy_id(x: u8) -> PolicyID { PolicyID::from([x; 28]) } + +pub(crate) fn fake_asset_name(x: u8) -> AssetName { + AssetName([x; 32].to_vec()) +} diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index b7651268..121fca8f 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -910,7 +910,7 @@ fn build_tx_with_mint_all_sent() { let amount = to_bignum(1234); // Adding mint of the asset - which should work as an input - tx_builder.add_mint_asset(&min_script, &name, Int::new(&amount)); + tx_builder.add_mint_asset(&min_script, &name, &Int::new(&amount)); let mut ass = Assets::new(); ass.insert(&name, &amount); @@ -1000,7 +1000,7 @@ fn build_tx_with_mint_in_change() { let amount_sent = to_bignum(500); // Adding mint of the asset - which should work as an input - tx_builder.add_mint_asset(&min_script, &name, Int::new(&amount_minted)); + tx_builder.add_mint_asset(&min_script, &name, &Int::new(&amount_minted)); let mut ass = Assets::new(); ass.insert(&name, &amount_sent); @@ -1109,7 +1109,7 @@ fn change_with_input_and_mint_not_enough_ada() { .to_address(); // Adding mint of the asset - which should work as an input - tx_builder.add_mint_asset(&min_script, &asset_name, Int::new(&amount_minted)); + tx_builder.add_mint_asset(&min_script, &asset_name, &Int::new(&amount_minted)); let mut asset = Assets::new(); asset.insert(&asset_name, &amount_sent); @@ -1205,7 +1205,7 @@ fn change_with_input_and_mint_not_enough_assets() { .to_address(); // Adding mint of the asset - which should work as an input - tx_builder.add_mint_asset(&min_script, &asset_name, Int::new(&amount_minted)); + tx_builder.add_mint_asset(&min_script, &asset_name, &Int::new(&amount_minted)); let mut asset = Assets::new(); asset.insert(&asset_name, &amount_sent); @@ -3081,7 +3081,7 @@ fn create_asset_name() -> AssetName { } fn create_mint_asset() -> MintAssets { - MintAssets::new_from_entry(&create_asset_name(), Int::new_i32(1234)).unwrap() + MintAssets::new_from_entry(&create_asset_name(), &Int::new_i32(1234)).unwrap() } fn create_assets() -> Assets { @@ -3193,7 +3193,7 @@ fn add_mint_asset_with_empty_mint() { let (mint_script, policy_id) = mint_script_and_policy(0); - tx_builder.add_mint_asset(&mint_script, &create_asset_name(), Int::new_i32(1234)); + tx_builder.add_mint_asset(&mint_script, &create_asset_name(), &Int::new_i32(1234)); assert!(tx_builder.mint.is_some()); let mint_scripts = tx_builder.mint.as_ref().unwrap().get_native_scripts(); @@ -3221,7 +3221,7 @@ fn add_mint_asset_with_existing_mint() { &NativeScripts::from(vec![mint_script1.clone()]), ) .unwrap(); - tx_builder.add_mint_asset(&mint_script2, &create_asset_name(), Int::new_i32(1234)); + tx_builder.add_mint_asset(&mint_script2, &create_asset_name(), &Int::new_i32(1234)); assert!(tx_builder.mint.is_some()); let mint_scripts = tx_builder.mint.as_ref().unwrap().get_native_scripts(); @@ -3378,13 +3378,13 @@ fn add_mint_asset_and_output() { let coin = to_bignum(249); // Add unrelated mint first to check it is NOT added to output later - tx_builder.add_mint_asset(&mint_script0, &name, amount.clone()); + tx_builder.add_mint_asset(&mint_script0, &name, &amount.clone()); tx_builder .add_mint_asset_and_output( &mint_script1, &name, - amount.clone(), + &amount, &TransactionOutputBuilder::new() .with_address(&address) .next() @@ -3448,13 +3448,13 @@ fn add_mint_asset_and_min_required_coin() { let address = byron_address(); // Add unrelated mint first to check it is NOT added to output later - tx_builder.add_mint_asset(&mint_script0, &name, amount.clone()); + tx_builder.add_mint_asset(&mint_script0, &name, &amount); tx_builder .add_mint_asset_and_output_min_required_coin( &mint_script1, &name, - amount.clone(), + &amount, &TransactionOutputBuilder::new() .with_address(&address) .next() @@ -3539,10 +3539,10 @@ fn add_mint_includes_witnesses_into_fee_estimation() { assert_eq!(original_tx_fee, to_bignum(168361)); // Add minting four assets from three different policies - tx_builder.add_mint_asset(&mint_script1, &name1, amount.clone()); - tx_builder.add_mint_asset(&mint_script2, &name2, amount.clone()); - tx_builder.add_mint_asset(&mint_script3, &name3, amount.clone()); - tx_builder.add_mint_asset(&mint_script3, &name4, amount.clone()); + tx_builder.add_mint_asset(&mint_script1, &name1, &amount); + tx_builder.add_mint_asset(&mint_script2, &name2, &amount); + tx_builder.add_mint_asset(&mint_script3, &name3, &amount); + tx_builder.add_mint_asset(&mint_script3, &name4, &amount); let mint = tx_builder.get_mint().unwrap(); let mint_len = mint.to_bytes().len(); @@ -3604,7 +3604,7 @@ fn fee_estimation_fails_on_missing_mint_scripts() { let mut mint = Mint::new(); mint.insert( &policy_id1, - &MintAssets::new_from_entry(&name1, amount.clone()).unwrap(), + &MintAssets::new_from_entry(&name1, &amount.clone()).unwrap(), ); tx_builder @@ -3614,7 +3614,7 @@ fn fee_estimation_fails_on_missing_mint_scripts() { let est1 = tx_builder.min_fee(); assert!(est1.is_ok()); - tx_builder.add_mint_asset(&mint_script2, &name1, amount.clone()); + tx_builder.add_mint_asset(&mint_script2, &name1, &amount); let est2 = tx_builder.min_fee(); assert!(est2.is_ok()); @@ -3732,10 +3732,10 @@ fn total_input_output_with_mint_and_burn() { assert!(ma1_output.is_none()); // Adding mint - tx_builder.add_mint_asset(&mint_script1, &name, Int::new_i32(40)); + tx_builder.add_mint_asset(&mint_script1, &name, &Int::new_i32(40)); // Adding burn - tx_builder.add_mint_asset(&mint_script2, &name, Int::new_i32(-40)); + tx_builder.add_mint_asset(&mint_script2, &name, &Int::new_i32(-40)); let total_input_after_mint = tx_builder.get_total_input().unwrap(); let total_output_after_mint = tx_builder.get_total_output().unwrap(); From 8e4d9b739101c46805432bed10c17797adce0fbc Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 10 Sep 2023 03:59:27 +0500 Subject: [PATCH 145/349] fix modules import --- rust/json-gen/src/main.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/rust/json-gen/src/main.rs b/rust/json-gen/src/main.rs index 809bae29..ca03f40b 100644 --- a/rust/json-gen/src/main.rs +++ b/rust/json-gen/src/main.rs @@ -4,8 +4,6 @@ use std::path::Path; use cardano_serialization_lib::*; use cardano_serialization_lib::address::*; use cardano_serialization_lib::crypto::*; -use cardano_serialization_lib::metadata::*; -use cardano_serialization_lib::plutus::*; use cardano_serialization_lib::utils::*; //#[macro_export] From 0859f8775ad588e57c69d47c3935f04d0420f9fa Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 10 Sep 2023 04:01:34 +0500 Subject: [PATCH 146/349] update js flow --- rust/pkg/cardano_serialization_lib.js.flow | 669 +++++++++++++++++---- 1 file changed, 554 insertions(+), 115 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 7c0a9344..96ef1b46 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -6,28 +6,16 @@ */ /** - * @param {string} password - * @param {string} salt - * @param {string} nonce - * @param {string} data - * @returns {string} - */ -declare export function encrypt_with_password( - password: string, - salt: string, - nonce: string, - data: string -): string; - -/** - * @param {string} password - * @param {string} data - * @returns {string} + * @param {Address} address + * @param {TransactionUnspentOutputs} utxos + * @param {TransactionBuilderConfig} config + * @returns {TransactionBatchList} */ -declare export function decrypt_with_password( - password: string, - data: string -): string; +declare export function create_send_all( + address: Address, + utxos: TransactionUnspentOutputs, + config: TransactionBuilderConfig +): TransactionBatchList; /** * @param {Transaction} tx @@ -57,16 +45,28 @@ declare export function min_script_fee( ): BigNum; /** - * @param {Address} address - * @param {TransactionUnspentOutputs} utxos - * @param {TransactionBuilderConfig} config - * @returns {TransactionBatchList} + * @param {string} password + * @param {string} salt + * @param {string} nonce + * @param {string} data + * @returns {string} */ -declare export function create_send_all( - address: Address, - utxos: TransactionUnspentOutputs, - config: TransactionBuilderConfig -): TransactionBatchList; +declare export function encrypt_with_password( + password: string, + salt: string, + nonce: string, + data: string +): string; + +/** + * @param {string} password + * @param {string} data + * @returns {string} + */ +declare export function decrypt_with_password( + password: string, + data: string +): string; /** * @param {TransactionHash} tx_body_hash @@ -206,6 +206,26 @@ declare export function encode_json_str_to_native_script( schema: number ): NativeScript; +/** + * @param {string} json + * @param {number} schema + * @returns {PlutusData} + */ +declare export function encode_json_str_to_plutus_datum( + json: string, + schema: number +): PlutusData; + +/** + * @param {PlutusData} datum + * @param {number} schema + * @returns {string} + */ +declare export function decode_plutus_datum_to_json_str( + datum: PlutusData, + schema: number +): string; + /** * @param {Uint8Array} bytes * @returns {TransactionMetadatum} @@ -243,24 +263,50 @@ declare export function decode_metadatum_to_json_str( ): string; /** - * @param {string} json - * @param {number} schema - * @returns {PlutusData} */ -declare export function encode_json_str_to_plutus_datum( - json: string, - schema: number -): PlutusData; + +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 +|}; /** - * @param {PlutusData} datum - * @param {number} schema - * @returns {string} */ -declare export function decode_plutus_datum_to_json_str( - datum: PlutusData, - schema: number -): string; + +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 +|}; + +/** + */ + +declare export var StakeCredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 +|}; + +/** + */ + +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 +|}; + +/** + * Used to choosed the schema for a script JSON string + */ + +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 +|}; /** */ @@ -294,6 +340,7 @@ declare export var ScriptHashNamespace: {| +NativeScript: 0, // 0 +PlutusScript: 1, // 1 +PlutusScriptV2: 2, // 2 + +PlutusScriptV3: 3, // 3 |}; /** @@ -307,47 +354,10 @@ declare export var NetworkIdKind: {| /** */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 -|}; - -/** - */ - -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 -|}; - -/** - */ - -declare export var StakeCredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 -|}; - -/** - */ - -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 -|}; - -/** - * Used to choosed the schema for a script JSON string - */ - -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** @@ -373,15 +383,6 @@ declare export var CertificateKind: {| +VoteRegistrationAndDelegation: 16, // 16 |}; -/** - */ - -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 -|}; - /** */ @@ -395,32 +396,13 @@ declare export var VotingProposalKind: {| +InfoProposal: 6, // 6 |}; -/** - */ - -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 -|}; - -/** - */ - -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 -|}; - /** */ declare export var LanguageKind: {| +PlutusV1: 0, // 0 +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 |}; /** @@ -463,6 +445,26 @@ declare export var PlutusDatumSchema: {| +DetailedSchema: 1, // 1 |}; +/** + */ + +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 +|}; + +/** + */ + +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 +|}; + /** */ @@ -3158,6 +3160,180 @@ declare export class DrepUpdate { */ has_script_credentials(): boolean; } +/** + */ +declare export class DrepVotingThresholds { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {DrepVotingThresholds} + */ + static from_bytes(bytes: Uint8Array): DrepVotingThresholds; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {DrepVotingThresholds} + */ + static from_hex(hex_str: string): DrepVotingThresholds; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {DrepVotingThresholdsJSON} + */ + to_js_value(): DrepVotingThresholdsJSON; + + /** + * @param {string} json + * @returns {DrepVotingThresholds} + */ + static from_json(json: string): DrepVotingThresholds; + + /** + * @param {UnitInterval} motion_no_confidence + * @param {UnitInterval} committee_normal + * @param {UnitInterval} committee_no_confidence + * @param {UnitInterval} update_constitution + * @param {UnitInterval} hard_fork_initiation + * @param {UnitInterval} pp_network_group + * @param {UnitInterval} pp_economic_group + * @param {UnitInterval} pp_technical_group + * @param {UnitInterval} pp_governance_group + * @param {UnitInterval} treasury_withdrawal + * @returns {DrepVotingThresholds} + */ + static new( + motion_no_confidence: UnitInterval, + committee_normal: UnitInterval, + committee_no_confidence: UnitInterval, + update_constitution: UnitInterval, + hard_fork_initiation: UnitInterval, + pp_network_group: UnitInterval, + pp_economic_group: UnitInterval, + pp_technical_group: UnitInterval, + pp_governance_group: UnitInterval, + treasury_withdrawal: UnitInterval + ): DrepVotingThresholds; + + /** + * @returns {DrepVotingThresholds} + */ + static new_default(): DrepVotingThresholds; + + /** + * @param {UnitInterval} motion_no_confidence + */ + set_motion_no_confidence(motion_no_confidence: UnitInterval): void; + + /** + * @param {UnitInterval} committee_normal + */ + set_committee_normal(committee_normal: UnitInterval): void; + + /** + * @param {UnitInterval} committee_no_confidence + */ + set_committee_no_confidence(committee_no_confidence: UnitInterval): void; + + /** + * @param {UnitInterval} update_constitution + */ + set_update_constitution(update_constitution: UnitInterval): void; + + /** + * @param {UnitInterval} hard_fork_initiation + */ + set_hard_fork_initiation(hard_fork_initiation: UnitInterval): void; + + /** + * @param {UnitInterval} pp_network_group + */ + set_pp_network_group(pp_network_group: UnitInterval): void; + + /** + * @param {UnitInterval} pp_economic_group + */ + set_pp_economic_group(pp_economic_group: UnitInterval): void; + + /** + * @param {UnitInterval} pp_technical_group + */ + set_pp_technical_group(pp_technical_group: UnitInterval): void; + + /** + * @param {UnitInterval} pp_governance_group + */ + set_pp_governance_group(pp_governance_group: UnitInterval): void; + + /** + * @param {UnitInterval} treasury_withdrawal + */ + set_treasury_withdrawal(treasury_withdrawal: UnitInterval): void; + + /** + * @returns {UnitInterval} + */ + motion_no_confidence(): UnitInterval; + + /** + * @returns {UnitInterval} + */ + committee_normal(): UnitInterval; + + /** + * @returns {UnitInterval} + */ + committee_no_confidence(): UnitInterval; + + /** + * @returns {UnitInterval} + */ + update_constitution(): UnitInterval; + + /** + * @returns {UnitInterval} + */ + hard_fork_initiation(): UnitInterval; + + /** + * @returns {UnitInterval} + */ + pp_network_group(): UnitInterval; + + /** + * @returns {UnitInterval} + */ + pp_economic_group(): UnitInterval; + + /** + * @returns {UnitInterval} + */ + pp_technical_group(): UnitInterval; + + /** + * @returns {UnitInterval} + */ + pp_governance_group(): UnitInterval; + + /** + * @returns {UnitInterval} + */ + treasury_withdrawal(): UnitInterval; +} /** */ declare export class Ed25519KeyHash { @@ -4666,6 +4842,11 @@ declare export class Language { */ static new_plutus_v2(): Language; + /** + * @returns {Language} + */ + static new_plutus_v3(): Language; + /** * @returns {number} */ @@ -6477,6 +6658,16 @@ declare export class PlutusScript { */ static new_v2(bytes: Uint8Array): PlutusScript; + /** + * + * * Creates a new Plutus script from the RAW bytes of the compiled script. + * * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) + * * If you creating this from those you should use PlutusScript::from_bytes() instead. + * @param {Uint8Array} bytes + * @returns {PlutusScript} + */ + static new_v3(bytes: Uint8Array): PlutusScript; + /** * * * Creates a new Plutus script from the RAW bytes of the compiled script. @@ -6503,6 +6694,13 @@ declare export class PlutusScript { */ static from_bytes_v2(bytes: Uint8Array): PlutusScript; + /** + * Same as `.from_bytes` but will consider the script as requiring the Plutus Language V3 + * @param {Uint8Array} bytes + * @returns {PlutusScript} + */ + static from_bytes_v3(bytes: Uint8Array): PlutusScript; + /** * Same as `.from_bytes` but will consider the script as requiring the specified language version * @param {Uint8Array} bytes @@ -7147,6 +7345,83 @@ declare export class PoolRetirement { */ static new(pool_keyhash: Ed25519KeyHash, epoch: number): PoolRetirement; } +/** + */ +declare export class PoolVotingThresholds { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {PoolVotingThresholds} + */ + static from_bytes(bytes: Uint8Array): PoolVotingThresholds; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {PoolVotingThresholds} + */ + static from_hex(hex_str: string): PoolVotingThresholds; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {PoolVotingThresholdsJSON} + */ + to_js_value(): PoolVotingThresholdsJSON; + + /** + * @param {string} json + * @returns {PoolVotingThresholds} + */ + static from_json(json: string): PoolVotingThresholds; + + /** + * @param {UnitInterval} motion_no_confidence + * @param {UnitInterval} committee_normal + * @param {UnitInterval} committee_no_confidence + * @param {UnitInterval} hard_fork_initiation + * @returns {PoolVotingThresholds} + */ + static new( + motion_no_confidence: UnitInterval, + committee_normal: UnitInterval, + committee_no_confidence: UnitInterval, + hard_fork_initiation: UnitInterval + ): PoolVotingThresholds; + + /** + * @returns {UnitInterval} + */ + motion_no_confidence(): UnitInterval; + + /** + * @returns {UnitInterval} + */ + committee_normal(): UnitInterval; + + /** + * @returns {UnitInterval} + */ + committee_no_confidence(): UnitInterval; + + /** + * @returns {UnitInterval} + */ + hard_fork_initiation(): UnitInterval; +} /** */ declare export class PrivateKey { @@ -7571,6 +7846,92 @@ declare export class ProtocolParamUpdate { */ max_collateral_inputs(): number | void; + /** + * @param {PoolVotingThresholds} pool_voting_thresholds + */ + set_pool_voting_thresholds( + pool_voting_thresholds: PoolVotingThresholds + ): void; + + /** + * @returns {PoolVotingThresholds | void} + */ + pool_voting_thresholds(): PoolVotingThresholds | void; + + /** + * @param {DrepVotingThresholds} drep_voting_thresholds + */ + set_drep_voting_thresholds( + drep_voting_thresholds: DrepVotingThresholds + ): void; + + /** + * @returns {DrepVotingThresholds | void} + */ + drep_voting_thresholds(): DrepVotingThresholds | void; + + /** + * @param {number} min_committee_size + */ + set_min_committee_size(min_committee_size: number): void; + + /** + * @returns {number | void} + */ + min_committee_size(): number | void; + + /** + * @param {number} committee_term_limit + */ + set_committee_term_limit(committee_term_limit: number): void; + + /** + * @returns {number | void} + */ + committee_term_limit(): number | void; + + /** + * @param {number} governance_action_validity_period + */ + set_governance_action_validity_period( + governance_action_validity_period: number + ): void; + + /** + * @returns {number | void} + */ + governance_action_validity_period(): number | void; + + /** + * @param {BigNum} governance_action_deposit + */ + set_governance_action_deposit(governance_action_deposit: BigNum): void; + + /** + * @returns {BigNum | void} + */ + governance_action_deposit(): BigNum | void; + + /** + * @param {BigNum} drep_deposit + */ + set_drep_deposit(drep_deposit: BigNum): void; + + /** + * @returns {BigNum | void} + */ + drep_deposit(): BigNum | void; + + /** + * @param {number} drep_inactivity_period + */ + set_drep_inactivity_period(drep_inactivity_period: number): void; + + /** + * @returns {number | void} + */ + drep_inactivity_period(): number | void; + /** * @returns {ProtocolParamUpdate} */ @@ -9835,6 +10196,36 @@ declare export class TransactionBody { */ voting_procedures(): VotingProcedures | void; + /** + * @param {VotingProposals} voting_proposals + */ + set_voting_proposals(voting_proposals: VotingProposals): void; + + /** + * @returns {VotingProposals | void} + */ + voting_proposals(): VotingProposals | void; + + /** + * @param {BigNum} donation + */ + set_donation(donation: BigNum): void; + + /** + * @returns {BigNum | void} + */ + donation(): BigNum | void; + + /** + * @param {BigNum} current_treasury_value + */ + set_current_treasury_value(current_treasury_value: BigNum): void; + + /** + * @returns {BigNum | void} + */ + current_treasury_value(): BigNum | void; + /** * !!! DEPRECATED !!! * This constructor uses outdated slot number format for the ttl value. @@ -10301,6 +10692,26 @@ declare export class TransactionBuilder { */ get_extra_witness_datums(): PlutusList | void; + /** + * @param {BigNum} donation + */ + set_donation(donation: BigNum): void; + + /** + * @returns {BigNum | void} + */ + get_donation(): BigNum | void; + + /** + * @param {BigNum} current_treasury_value + */ + set_current_treasury_value(current_treasury_value: BigNum): void; + + /** + * @returns {BigNum | void} + */ + get_current_treasury_value(): BigNum | void; + /** * @param {TransactionBuilderConfig} cfg * @returns {TransactionBuilder} @@ -13377,6 +13788,18 @@ export interface DrepUpdateJSON { anchor?: AnchorJSON | null; voting_credential: CredentialJSON; } +export interface DrepVotingThresholdsJSON { + committee_no_confidence: UnitIntervalJSON; + committee_normal: UnitIntervalJSON; + hard_fork_initiation: UnitIntervalJSON; + motion_no_confidence: UnitIntervalJSON; + pp_economic_group: UnitIntervalJSON; + pp_governance_group: UnitIntervalJSON; + pp_network_group: UnitIntervalJSON; + pp_technical_group: UnitIntervalJSON; + treasury_withdrawal: UnitIntervalJSON; + update_constitution: UnitIntervalJSON; +} export type Ed25519KeyHashJSON = string; export type Ed25519KeyHashesJSON = string[]; export type Ed25519SignatureJSON = string; @@ -13454,7 +13877,7 @@ export type Ipv6JSON = [ ]; export type KESVKeyJSON = string; export type LanguageJSON = LanguageKindJSON; -export type LanguageKindJSON = "PlutusV1" | "PlutusV2"; +export type LanguageKindJSON = "PlutusV1" | "PlutusV2" | "PlutusV3"; export type LanguagesJSON = LanguageJSON[]; export type MIREnumJSON = | { @@ -13598,17 +14021,29 @@ export interface PoolRetirementJSON { epoch: number; pool_keyhash: string; } +export interface PoolVotingThresholdsJSON { + committee_no_confidence: UnitIntervalJSON; + committee_normal: UnitIntervalJSON; + hard_fork_initiation: UnitIntervalJSON; + motion_no_confidence: UnitIntervalJSON; +} export interface ProposedProtocolParameterUpdatesJSON { [k: string]: ProtocolParamUpdateJSON; } export interface ProtocolParamUpdateJSON { ada_per_utxo_byte?: string | null; collateral_percentage?: number | null; + committee_term_limit?: number | null; cost_models?: CostmdlsJSON | null; d?: UnitIntervalJSON | null; + drep_deposit?: string | null; + drep_inactivity_period?: number | null; + drep_voting_thresholds?: DrepVotingThresholdsJSON | null; execution_costs?: ExUnitPricesJSON | null; expansion_rate?: UnitIntervalJSON | null; extra_entropy?: NonceJSON | null; + governance_action_deposit?: string | null; + governance_action_validity_period?: number | null; key_deposit?: string | null; max_block_body_size?: number | null; max_block_ex_units?: ExUnitsJSON | null; @@ -13618,12 +14053,14 @@ export interface ProtocolParamUpdateJSON { max_tx_ex_units?: ExUnitsJSON | null; max_tx_size?: number | null; max_value_size?: number | null; + min_committee_size?: number | null; min_pool_cost?: string | null; minfee_a?: string | null; minfee_b?: string | null; n_opt?: number | null; pool_deposit?: string | null; pool_pledge_influence?: UnitIntervalJSON | null; + pool_voting_thresholds?: PoolVotingThresholdsJSON | null; protocol_version?: ProtocolVersionJSON | null; treasury_growth_rate?: UnitIntervalJSON | null; } @@ -13746,6 +14183,8 @@ export interface TransactionBodyJSON { certs?: CertificatesJSON | null; collateral?: TransactionInputsJSON | null; collateral_return?: TransactionOutputJSON | null; + current_treasury_value?: string | null; + donation?: string | null; fee: string; inputs: TransactionInputsJSON; mint?: MintJSON | null; From c1531a0792c343c5fd1350c68a324e45ce4c70aa Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 10 Sep 2023 04:08:29 +0500 Subject: [PATCH 147/349] deprecate protocol version setter in the protocol param update --- rust/src/protocol_types/protocol_param_update.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rust/src/protocol_types/protocol_param_update.rs b/rust/src/protocol_types/protocol_param_update.rs index 8dafc129..2cf93d8a 100644 --- a/rust/src/protocol_types/protocol_param_update.rs +++ b/rust/src/protocol_types/protocol_param_update.rs @@ -369,6 +369,12 @@ impl ProtocolParamUpdate { self.extra_entropy.clone() } + /// !!! DEPRECATED !!! + /// Since conway era this param is outdated. But this param you can meet in a pre-conway block. + #[deprecated( + since = "12.0.0", + note = "Since conway era this param is outdated. But this param you can meet in a pre-conway block." + )] pub fn set_protocol_version(&mut self, protocol_version: &ProtocolVersion) { self.protocol_version = Some(protocol_version.clone()) } From 8243082ad65b2686f00ea1a657a0b4b06078cd0a Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 10 Sep 2023 12:33:19 +0500 Subject: [PATCH 148/349] add tests for cert builder --- .../src/serialization/serialization_macros.rs | 2 +- .../tests/builders/certificates_builder.rs | 520 ++++++++++++++++++ rust/src/tests/builders/mod.rs | 1 + 3 files changed, 522 insertions(+), 1 deletion(-) create mode 100644 rust/src/tests/builders/certificates_builder.rs diff --git a/rust/src/serialization/serialization_macros.rs b/rust/src/serialization/serialization_macros.rs index e8e7ddb0..dd460e25 100644 --- a/rust/src/serialization/serialization_macros.rs +++ b/rust/src/serialization/serialization_macros.rs @@ -144,7 +144,7 @@ macro_rules! impl_deserialize_for_wrapped_tuple { raw: &mut Deserializer, ) -> Result { (|| -> Result<_, DeserializeError> { - use crate::serialization::struct_checks::check_len_indefinite; + use crate::serialization::utils::check_len_indefinite; let len = raw.array()?; let cert = Self::deserialize_as_embedded_group(raw, len)?; diff --git a/rust/src/tests/builders/certificates_builder.rs b/rust/src/tests/builders/certificates_builder.rs new file mode 100644 index 00000000..07345988 --- /dev/null +++ b/rust/src/tests/builders/certificates_builder.rs @@ -0,0 +1,520 @@ +use crate::fakes::{ + fake_genesis_delegate_hash, fake_genesis_hash, fake_key_hash, fake_pool_metadata_hash, + fake_vrf_key_hash, +}; +use crate::*; + +#[test] +fn certificatess_builder_deposit_test() { + let mut builder = CertificatesBuilder::new(); + let pool_deposit = 100u64; + let key_deposit = 200u64; + let key_deposit_form_args = 201u64; + let drep_reg_deposit = 400u64; + + let committee_hot_key_dereg_cert = + CommitteeHotKeyDeregistration::new(&Credential::from_keyhash(&fake_key_hash(1))); + let committee_hot_key_dereg_cert_wrapped = + Certificate::new_committee_hot_key_deregistration(&committee_hot_key_dereg_cert); + + let committee_hot_key_reg_cert = CommitteeHotKeyRegistration::new( + &Credential::from_keyhash(&fake_key_hash(2)), + &Credential::from_keyhash(&fake_key_hash(3)), + ); + let committee_hot_key_reg_cert_wrapped = + Certificate::new_committee_hot_key_registration(&committee_hot_key_reg_cert); + + let drep_reg_cert = DrepRegistration::new( + &Credential::from_keyhash(&fake_key_hash(4)), + &Coin::from(drep_reg_deposit), + ); + let drep_reg_cert_wrapped = Certificate::new_drep_registration(&drep_reg_cert); + + let drep_dereg_cert = DrepDeregistration::new( + &Credential::from_keyhash(&fake_key_hash(5)), + &Coin::from(drep_reg_deposit), + ); + let drep_dereg_cert_wrapped = Certificate::new_drep_deregistration(&drep_dereg_cert); + + let drep_update_cert = DrepUpdate::new(&Credential::from_keyhash(&fake_key_hash(6))); + let cdrep_update_cert_wrapped = Certificate::new_drep_update(&drep_update_cert); + + let genesis_key_deleg_cert = GenesisKeyDelegation::new( + &fake_genesis_hash(7), + &fake_genesis_delegate_hash(8), + &fake_vrf_key_hash(9), + ); + let genesis_key_deleg_cert_wrapped = + Certificate::new_genesis_key_delegation(&genesis_key_deleg_cert); + + let mir_cert = MoveInstantaneousReward::new_to_other_pot(MIRPot::Reserves, &Coin::from(100u64)); + let mir_cert_wrapped = Certificate::new_move_instantaneous_rewards_cert( + &MoveInstantaneousRewardsCert::new(&mir_cert), + ); + + let staking_cred = Credential::from_keyhash(&fake_key_hash(10)); + let reward_address = RewardAddress::new(NetworkInfo::testnet().network_id(), &staking_cred); + let mut owners = Ed25519KeyHashes::new(); + owners.add(&fake_key_hash(11)); + owners.add(&fake_key_hash(12)); + let relays = Relays::new(); + let matadata = PoolMetadata::new( + &URL::new("https://iohk.io".to_string()).unwrap(), + &fake_pool_metadata_hash(5), + ); + + let params = PoolParams::new( + &fake_key_hash(13), + &fake_vrf_key_hash(15), + &Coin::from(100u64), + &Coin::from(200u64), + &UnitInterval::new(&BigNum::from(110u64), &BigNum::from(220u64)), + &reward_address, + &owners, + &relays, + Some(matadata), + ); + + let pool_reg_cert = PoolRegistration::new(¶ms); + let pool_reg_cert_wrapped = Certificate::new_pool_registration(&pool_reg_cert); + + let pool_ret_cert = PoolRetirement::new(&fake_key_hash(16), Epoch::from(100u32)); + let pool_ret_cert_wrapped = Certificate::new_pool_retirement(&pool_ret_cert); + + let drep = DRep::new_key_hash(&fake_key_hash(17)); + let stake_vote_deleg_cert = StakeAndVoteDelegation::new( + &Credential::from_keyhash(&fake_key_hash(18)), + &fake_key_hash(19), + &drep, + ); + let stake_vote_deleg_cert_wrapped = + Certificate::new_stake_and_vote_delegation(&stake_vote_deleg_cert); + + let stake_deleg_cert = StakeDelegation::new( + &Credential::from_keyhash(&fake_key_hash(20)), + &fake_key_hash(21), + ); + let stake_deleg_cert_wrapped = Certificate::new_stake_delegation(&stake_deleg_cert); + + let stake_dereg_cert = StakeDeregistration::new(&Credential::from_keyhash(&fake_key_hash(22))); + let stake_dereg_cert_wrapped = Certificate::new_stake_deregistration(&stake_dereg_cert); + + let stake_dereg_with_coin_cert = + StakeDeregistration::new_with_coin( + &Credential::from_keyhash(&fake_key_hash(22)), + &Coin::from(key_deposit_form_args), + ); + let stake_dereg_with_coint_wrapped = Certificate::new_stake_deregistration(&stake_dereg_with_coin_cert); + + let stake_reg_cert = StakeRegistration::new(&Credential::from_keyhash(&fake_key_hash(23))); + let stake_reg_cert_wrapped = Certificate::new_stake_registration(&stake_reg_cert); + + let stake_reg_with_coin_cert = + StakeRegistration::new_with_coin( + &Credential::from_keyhash(&fake_key_hash(23)), + &Coin::from(key_deposit_form_args), + ); + let stake_reg_with_coint_wrapped = Certificate::new_stake_registration(&stake_reg_with_coin_cert); + + let stake_reg_deleg_cert = StakeRegistrationAndDelegation::new( + &Credential::from_keyhash(&fake_key_hash(23)), + &fake_key_hash(24), + &Coin::from(key_deposit_form_args), + ); + let stake_reg_deleg_cert_wrapped = Certificate::new_stake_registration_and_delegation(&stake_reg_deleg_cert); + + let drep = DRep::new_key_hash(&fake_key_hash(25)); + let stake_vote_reg_deleg_cert = StakeVoteRegistrationAndDelegation::new( + &Credential::from_keyhash(&fake_key_hash(26)), + &fake_key_hash(27), + &drep, + &Coin::from(key_deposit_form_args), + ); + let stake_vote_reg_deleg_cert_wrapped = Certificate::new_stake_vote_registration_and_delegation(&stake_vote_reg_deleg_cert); + + let drep = DRep::new_key_hash(&fake_key_hash(28)); + let vote_deleg_cert = VoteDelegation::new(&Credential::from_keyhash(&fake_key_hash(29)), &drep); + let vote_deleg_cert_wrapped = Certificate::new_vote_delegation(&vote_deleg_cert); + + let drep = DRep::new_key_hash(&fake_key_hash(30)); + let vote_reg_deleg_cert = VoteRegistrationAndDelegation::new( + &Credential::from_keyhash(&fake_key_hash(31)), + &drep, + &Coin::from(key_deposit_form_args), + ); + let vote_reg_deleg_cert_wrapped = Certificate::new_vote_registration_and_delegation(&vote_reg_deleg_cert); + + builder.add(&committee_hot_key_dereg_cert_wrapped).unwrap(); + builder.add(&committee_hot_key_reg_cert_wrapped).unwrap(); + builder.add(&drep_reg_cert_wrapped).unwrap(); + builder.add(&drep_dereg_cert_wrapped).unwrap(); + builder.add(&cdrep_update_cert_wrapped).unwrap(); + builder.add(&genesis_key_deleg_cert_wrapped).unwrap(); + builder.add(&mir_cert_wrapped).unwrap(); + builder.add(&pool_reg_cert_wrapped).unwrap(); + builder.add(&pool_ret_cert_wrapped).unwrap(); + builder.add(&stake_vote_deleg_cert_wrapped).unwrap(); + builder.add(&stake_deleg_cert_wrapped).unwrap(); + builder.add(&stake_dereg_cert_wrapped).unwrap(); + builder.add(&stake_dereg_with_coint_wrapped).unwrap(); + builder.add(&stake_reg_cert_wrapped).unwrap(); + builder.add(&stake_reg_with_coint_wrapped).unwrap(); + builder.add(&stake_reg_deleg_cert_wrapped).unwrap(); + builder.add(&stake_vote_reg_deleg_cert_wrapped).unwrap(); + builder.add(&vote_deleg_cert_wrapped).unwrap(); + builder.add(&vote_reg_deleg_cert_wrapped).unwrap(); + + let builder_deposit = builder.get_certificates_deposit( + &Coin::from(pool_deposit), + &Coin::from(key_deposit), + ).unwrap(); + + let expected_deposit = Coin::from( + pool_deposit + + key_deposit + + drep_reg_deposit + + (key_deposit_form_args * 4)); + + assert_eq!(builder_deposit, expected_deposit); +} + +#[test] +fn certificatess_builder_no_deposit_test() { + let mut builder = CertificatesBuilder::new(); + let pool_deposit = 100u64; + let key_deposit = 200u64; + let key_deposit_form_args = 201u64; + let drep_reg_deposit = 400u64; + + let committee_hot_key_dereg_cert = + CommitteeHotKeyDeregistration::new(&Credential::from_keyhash(&fake_key_hash(1))); + let committee_hot_key_dereg_cert_wrapped = + Certificate::new_committee_hot_key_deregistration(&committee_hot_key_dereg_cert); + + let committee_hot_key_reg_cert = CommitteeHotKeyRegistration::new( + &Credential::from_keyhash(&fake_key_hash(2)), + &Credential::from_keyhash(&fake_key_hash(3)), + ); + let committee_hot_key_reg_cert_wrapped = + Certificate::new_committee_hot_key_registration(&committee_hot_key_reg_cert); + + let drep_dereg_cert = DrepDeregistration::new( + &Credential::from_keyhash(&fake_key_hash(5)), + &Coin::from(drep_reg_deposit), + ); + let drep_dereg_cert_wrapped = Certificate::new_drep_deregistration(&drep_dereg_cert); + + let drep_update_cert = DrepUpdate::new(&Credential::from_keyhash(&fake_key_hash(6))); + let cdrep_update_cert_wrapped = Certificate::new_drep_update(&drep_update_cert); + + let genesis_key_deleg_cert = GenesisKeyDelegation::new( + &fake_genesis_hash(7), + &fake_genesis_delegate_hash(8), + &fake_vrf_key_hash(9), + ); + let genesis_key_deleg_cert_wrapped = + Certificate::new_genesis_key_delegation(&genesis_key_deleg_cert); + + let mir_cert = MoveInstantaneousReward::new_to_other_pot(MIRPot::Reserves, &Coin::from(100u64)); + let mir_cert_wrapped = Certificate::new_move_instantaneous_rewards_cert( + &MoveInstantaneousRewardsCert::new(&mir_cert), + ); + + let staking_cred = Credential::from_keyhash(&fake_key_hash(10)); + let reward_address = RewardAddress::new(NetworkInfo::testnet().network_id(), &staking_cred); + let mut owners = Ed25519KeyHashes::new(); + owners.add(&fake_key_hash(11)); + owners.add(&fake_key_hash(12)); + let relays = Relays::new(); + let matadata = PoolMetadata::new( + &URL::new("https://iohk.io".to_string()).unwrap(), + &fake_pool_metadata_hash(5), + ); + + let params = PoolParams::new( + &fake_key_hash(13), + &fake_vrf_key_hash(15), + &Coin::from(100u64), + &Coin::from(200u64), + &UnitInterval::new(&BigNum::from(110u64), &BigNum::from(220u64)), + &reward_address, + &owners, + &relays, + Some(matadata), + ); + + let pool_ret_cert = PoolRetirement::new(&fake_key_hash(16), Epoch::from(100u32)); + let pool_ret_cert_wrapped = Certificate::new_pool_retirement(&pool_ret_cert); + + let drep = DRep::new_key_hash(&fake_key_hash(17)); + let stake_vote_deleg_cert = StakeAndVoteDelegation::new( + &Credential::from_keyhash(&fake_key_hash(18)), + &fake_key_hash(19), + &drep, + ); + let stake_vote_deleg_cert_wrapped = + Certificate::new_stake_and_vote_delegation(&stake_vote_deleg_cert); + + let stake_deleg_cert = StakeDelegation::new( + &Credential::from_keyhash(&fake_key_hash(20)), + &fake_key_hash(21), + ); + let stake_deleg_cert_wrapped = Certificate::new_stake_delegation(&stake_deleg_cert); + + let stake_dereg_cert = StakeDeregistration::new(&Credential::from_keyhash(&fake_key_hash(22))); + let stake_dereg_cert_wrapped = Certificate::new_stake_deregistration(&stake_dereg_cert); + + let stake_dereg_with_coin_cert = + StakeDeregistration::new_with_coin( + &Credential::from_keyhash(&fake_key_hash(22)), + &Coin::from(key_deposit_form_args), + ); + let stake_dereg_with_coint_wrapped = Certificate::new_stake_deregistration(&stake_dereg_with_coin_cert); + + let drep = DRep::new_key_hash(&fake_key_hash(28)); + let vote_deleg_cert = VoteDelegation::new(&Credential::from_keyhash(&fake_key_hash(29)), &drep); + let vote_deleg_cert_wrapped = Certificate::new_vote_delegation(&vote_deleg_cert); + + builder.add(&committee_hot_key_dereg_cert_wrapped).unwrap(); + builder.add(&committee_hot_key_reg_cert_wrapped).unwrap(); + builder.add(&drep_dereg_cert_wrapped).unwrap(); + builder.add(&cdrep_update_cert_wrapped).unwrap(); + builder.add(&genesis_key_deleg_cert_wrapped).unwrap(); + builder.add(&mir_cert_wrapped).unwrap(); + builder.add(&pool_ret_cert_wrapped).unwrap(); + builder.add(&stake_vote_deleg_cert_wrapped).unwrap(); + builder.add(&stake_deleg_cert_wrapped).unwrap(); + builder.add(&stake_dereg_cert_wrapped).unwrap(); + builder.add(&stake_dereg_with_coint_wrapped).unwrap(); + builder.add(&vote_deleg_cert_wrapped).unwrap(); + + let builder_deposit = builder.get_certificates_deposit( + &Coin::from(pool_deposit), + &Coin::from(key_deposit), + ).unwrap(); + + let expected_deposit = Coin::zero(); + + assert_eq!(builder_deposit, expected_deposit); +} + +#[test] +fn certificatess_builder_req_signers_test() { + let mut builder = CertificatesBuilder::new(); + let pool_deposit = 100u64; + let key_deposit = 200u64; + let key_deposit_form_args = 201u64; + let drep_reg_deposit = 400u64; + + let key_hash_1 = fake_key_hash(1); + let key_hash_2 = fake_key_hash(2); + let key_hash_3 = fake_key_hash(3); + let key_hash_4 = fake_key_hash(4); + let key_hash_5 = fake_key_hash(5); + let key_hash_6 = fake_key_hash(6); + let key_hash_7 = fake_key_hash(7); + let key_hash_8 = fake_key_hash(8); + let key_hash_9 = fake_key_hash(9); + let key_hash_10 = fake_key_hash(10); + let key_hash_11 = fake_key_hash(11); + let key_hash_12 = fake_key_hash(12); + let key_hash_13 = fake_key_hash(13); + let key_hash_14 = fake_key_hash(14); + let key_hash_15 = fake_key_hash(15); + let key_hash_16 = fake_key_hash(16); + let key_hash_17 = fake_key_hash(17); + let key_hash_18 = fake_key_hash(18); + let key_hash_19 = fake_key_hash(19); + let key_hash_20 = fake_key_hash(20); + let key_hash_21 = fake_key_hash(21); + let key_hash_22 = fake_key_hash(22); + let key_hash_23 = fake_key_hash(23); + let key_hash_24 = fake_key_hash(24); + let key_hash_25 = fake_key_hash(25); + let key_hash_26 = fake_key_hash(26); + let key_hash_27 = fake_key_hash(27); + let key_hash_28 = fake_key_hash(28); + let key_hash_29 = fake_key_hash(29); + let key_hash_30 = fake_key_hash(30); + let key_hash_31 = fake_key_hash(31); + let key_hash_32 = fake_key_hash(32); + let key_hash_33 = fake_key_hash(33); + + let committee_hot_key_dereg_cert = + CommitteeHotKeyDeregistration::new(&Credential::from_keyhash(&key_hash_1)); + let committee_hot_key_dereg_cert_wrapped = + Certificate::new_committee_hot_key_deregistration(&committee_hot_key_dereg_cert); + + let committee_hot_key_reg_cert = CommitteeHotKeyRegistration::new( + &Credential::from_keyhash(&key_hash_2), + &Credential::from_keyhash(&key_hash_3), + ); + let committee_hot_key_reg_cert_wrapped = + Certificate::new_committee_hot_key_registration(&committee_hot_key_reg_cert); + + let drep_reg_cert = DrepRegistration::new( + &Credential::from_keyhash(&key_hash_4), + &Coin::from(drep_reg_deposit), + ); + let drep_reg_cert_wrapped = Certificate::new_drep_registration(&drep_reg_cert); + + let drep_dereg_cert = DrepDeregistration::new( + &Credential::from_keyhash(&key_hash_5), + &Coin::from(drep_reg_deposit), + ); + let drep_dereg_cert_wrapped = Certificate::new_drep_deregistration(&drep_dereg_cert); + + let drep_update_cert = DrepUpdate::new(&Credential::from_keyhash(&key_hash_6)); + let cdrep_update_cert_wrapped = Certificate::new_drep_update(&drep_update_cert); + + let genesis_key_deleg_cert = GenesisKeyDelegation::new( + &fake_genesis_hash(7), + &fake_genesis_delegate_hash(8), + &fake_vrf_key_hash(9), + ); + let genesis_key_deleg_cert_wrapped = + Certificate::new_genesis_key_delegation(&genesis_key_deleg_cert); + + let mir_cert = MoveInstantaneousReward::new_to_other_pot(MIRPot::Reserves, &Coin::from(100u64)); + let mir_cert_wrapped = Certificate::new_move_instantaneous_rewards_cert( + &MoveInstantaneousRewardsCert::new(&mir_cert), + ); + + let staking_cred = Credential::from_keyhash(&key_hash_10); + let reward_address = RewardAddress::new(NetworkInfo::testnet().network_id(), &staking_cred); + let mut owners = Ed25519KeyHashes::new(); + owners.add(&key_hash_11); + owners.add(&key_hash_12); + let relays = Relays::new(); + let matadata = PoolMetadata::new( + &URL::new("https://iohk.io".to_string()).unwrap(), + &fake_pool_metadata_hash(5), + ); + + let params = PoolParams::new( + &key_hash_13, + &fake_vrf_key_hash(14), + &Coin::from(100u64), + &Coin::from(200u64), + &UnitInterval::new(&BigNum::from(110u64), &BigNum::from(220u64)), + &reward_address, + &owners, + &relays, + Some(matadata), + ); + + let pool_reg_cert = PoolRegistration::new(¶ms); + let pool_reg_cert_wrapped = Certificate::new_pool_registration(&pool_reg_cert); + + let pool_ret_cert = PoolRetirement::new(&key_hash_15, Epoch::from(100u32)); + let pool_ret_cert_wrapped = Certificate::new_pool_retirement(&pool_ret_cert); + + let drep = DRep::new_key_hash(&key_hash_16); + let stake_vote_deleg_cert = StakeAndVoteDelegation::new( + &Credential::from_keyhash(&key_hash_17), + &key_hash_18, + &drep, + ); + let stake_vote_deleg_cert_wrapped = + Certificate::new_stake_and_vote_delegation(&stake_vote_deleg_cert); + + let stake_deleg_cert = StakeDelegation::new( + &Credential::from_keyhash(&key_hash_19), + &key_hash_20, + ); + let stake_deleg_cert_wrapped = Certificate::new_stake_delegation(&stake_deleg_cert); + + let stake_dereg_cert = StakeDeregistration::new(&Credential::from_keyhash(&key_hash_21)); + let stake_dereg_cert_wrapped = Certificate::new_stake_deregistration(&stake_dereg_cert); + + let stake_dereg_with_coin_cert = + StakeDeregistration::new_with_coin( + &Credential::from_keyhash(&key_hash_22), + &Coin::from(key_deposit_form_args), + ); + let stake_dereg_with_coint_wrapped = Certificate::new_stake_deregistration(&stake_dereg_with_coin_cert); + + let stake_reg_cert = StakeRegistration::new(&Credential::from_keyhash(&key_hash_23)); + let stake_reg_cert_wrapped = Certificate::new_stake_registration(&stake_reg_cert); + + let stake_reg_with_coin_cert = + StakeRegistration::new_with_coin( + &Credential::from_keyhash(&key_hash_24), + &Coin::from(key_deposit_form_args), + ); + let stake_reg_with_coint_wrapped = Certificate::new_stake_registration(&stake_reg_with_coin_cert); + + let stake_reg_deleg_cert = StakeRegistrationAndDelegation::new( + &Credential::from_keyhash(&key_hash_25), + &key_hash_26, + &Coin::from(key_deposit_form_args), + ); + let stake_reg_deleg_cert_wrapped = Certificate::new_stake_registration_and_delegation(&stake_reg_deleg_cert); + + let drep = DRep::new_key_hash(&key_hash_27); + let stake_vote_reg_deleg_cert = StakeVoteRegistrationAndDelegation::new( + &Credential::from_keyhash(&key_hash_28), + &key_hash_29, + &drep, + &Coin::from(key_deposit_form_args), + ); + let stake_vote_reg_deleg_cert_wrapped = Certificate::new_stake_vote_registration_and_delegation(&stake_vote_reg_deleg_cert); + + let drep = DRep::new_key_hash(&key_hash_30); + let vote_deleg_cert = VoteDelegation::new(&Credential::from_keyhash(&key_hash_31), &drep); + let vote_deleg_cert_wrapped = Certificate::new_vote_delegation(&vote_deleg_cert); + + let drep = DRep::new_key_hash(&key_hash_32); + let vote_reg_deleg_cert = VoteRegistrationAndDelegation::new( + &Credential::from_keyhash(&key_hash_33), + &drep, + &Coin::from(key_deposit_form_args), + ); + let vote_reg_deleg_cert_wrapped = Certificate::new_vote_registration_and_delegation(&vote_reg_deleg_cert); + + builder.add(&committee_hot_key_dereg_cert_wrapped).unwrap(); + builder.add(&committee_hot_key_reg_cert_wrapped).unwrap(); + builder.add(&drep_reg_cert_wrapped).unwrap(); + builder.add(&drep_dereg_cert_wrapped).unwrap(); + builder.add(&cdrep_update_cert_wrapped).unwrap(); + builder.add(&genesis_key_deleg_cert_wrapped).unwrap(); + builder.add(&mir_cert_wrapped).unwrap(); + builder.add(&pool_reg_cert_wrapped).unwrap(); + builder.add(&pool_ret_cert_wrapped).unwrap(); + builder.add(&stake_vote_deleg_cert_wrapped).unwrap(); + builder.add(&stake_deleg_cert_wrapped).unwrap(); + builder.add(&stake_dereg_cert_wrapped).unwrap(); + builder.add(&stake_dereg_with_coint_wrapped).unwrap(); + builder.add(&stake_reg_cert_wrapped).unwrap(); + builder.add(&stake_reg_with_coint_wrapped).unwrap(); + builder.add(&stake_reg_deleg_cert_wrapped).unwrap(); + builder.add(&stake_vote_reg_deleg_cert_wrapped).unwrap(); + builder.add(&vote_deleg_cert_wrapped).unwrap(); + builder.add(&vote_reg_deleg_cert_wrapped).unwrap(); + + let builder_deposit = builder.get_certificates_deposit( + &Coin::from(pool_deposit), + &Coin::from(key_deposit), + ).unwrap(); + + let req_signers = builder.get_required_signers(); + + assert_eq!(req_signers.len(), 17); + assert!(req_signers.contains(&key_hash_1)); + assert!(req_signers.contains(&key_hash_2)); + assert!(req_signers.contains(&key_hash_5)); + assert!(req_signers.contains(&key_hash_6)); + assert!(req_signers.contains(&key_hash_8)); + assert!(req_signers.contains(&key_hash_11)); + assert!(req_signers.contains(&key_hash_12)); + assert!(req_signers.contains(&key_hash_13)); + assert!(req_signers.contains(&key_hash_15)); + assert!(req_signers.contains(&key_hash_17)); + assert!(req_signers.contains(&key_hash_19)); + assert!(req_signers.contains(&key_hash_21)); + assert!(req_signers.contains(&key_hash_22)); + assert!(req_signers.contains(&key_hash_25)); + assert!(req_signers.contains(&key_hash_28)); + assert!(req_signers.contains(&key_hash_31)); + assert!(req_signers.contains(&key_hash_33)); +} \ No newline at end of file diff --git a/rust/src/tests/builders/mod.rs b/rust/src/tests/builders/mod.rs index f5be819a..ab508154 100644 --- a/rust/src/tests/builders/mod.rs +++ b/rust/src/tests/builders/mod.rs @@ -2,3 +2,4 @@ mod batch_tools; mod tx_builder; mod voting_builder; mod voting_proposal_builder; +mod certificates_builder; From 132e57dd4ccaca2208a4a62a887e1e88598d80a6 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 10 Sep 2023 12:38:47 +0500 Subject: [PATCH 149/349] rename stakeCred to cred --- rust/json-gen/src/main.rs | 4 +- rust/src/address.rs | 40 +++++++++---------- rust/src/builders/certificates_builder.rs | 18 ++++----- rust/src/lib.rs | 6 +-- rust/src/plutus.rs | 4 +- .../move_instantaneous_rewards_cert.rs | 4 +- .../governance/proposals/committee.rs | 4 +- .../proposals/new_committee_proposal.rs | 8 ++-- rust/src/protocol_types/governance/voter.rs | 8 ++-- rust/src/serialization/general.rs | 4 +- .../proposals/new_committee_proposal.rs | 4 +- rust/src/serialization/governance/voter.rs | 16 ++++---- .../tests/builders/voting_proposal_builder.rs | 6 +-- .../protocol_types/governance/proposals.rs | 2 +- .../serialization/governance/proposals.rs | 6 +-- 15 files changed, 67 insertions(+), 67 deletions(-) diff --git a/rust/json-gen/src/main.rs b/rust/json-gen/src/main.rs index 98ddfe99..b6f4e9f9 100644 --- a/rust/json-gen/src/main.rs +++ b/rust/json-gen/src/main.rs @@ -58,7 +58,7 @@ fn main() { gen_json_schema!(Relay); //gen_json_schema!(RelayEnum); gen_json_schema!(PoolMetadata); - gen_json_schema!(StakeCredentials); + gen_json_schema!(Credentials); gen_json_schema!(RewardAddresses); gen_json_schema!(Withdrawals); gen_json_schema!(TransactionWitnessSet); @@ -123,7 +123,7 @@ fn main() { gen_json_schema!(VRFCert); // address.rs gen_json_schema!(Credential); - gen_json_schema!(StakeCredType); + gen_json_schema!(CredType); gen_json_schema!(Address); gen_json_schema!(RewardAddress); // plutus.rs diff --git a/rust/src/address.rs b/rust/src/address.rs index 665e5961..962bbead 100644 --- a/rust/src/address.rs +++ b/rust/src/address.rs @@ -97,7 +97,7 @@ impl NetworkInfo { serde::Deserialize, JsonSchema, )] -pub enum StakeCredType { +pub enum CredType { Key(Ed25519KeyHash), Script(ScriptHash), } @@ -105,7 +105,7 @@ pub enum StakeCredType { #[wasm_bindgen] #[repr(u8)] #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub enum StakeCredKind { +pub enum CredKind { Key, Script, } @@ -123,50 +123,50 @@ pub enum StakeCredKind { serde::Deserialize, JsonSchema, )] -pub struct Credential(pub(crate) StakeCredType); +pub struct Credential(pub(crate) CredType); #[wasm_bindgen] impl Credential { pub fn from_keyhash(hash: &Ed25519KeyHash) -> Self { - Credential(StakeCredType::Key(hash.clone())) + Credential(CredType::Key(hash.clone())) } pub fn from_scripthash(hash: &ScriptHash) -> Self { - Credential(StakeCredType::Script(hash.clone())) + Credential(CredType::Script(hash.clone())) } pub fn to_keyhash(&self) -> Option { match &self.0 { - StakeCredType::Key(hash) => Some(hash.clone()), - StakeCredType::Script(_) => None, + CredType::Key(hash) => Some(hash.clone()), + CredType::Script(_) => None, } } pub fn to_scripthash(&self) -> Option { match &self.0 { - StakeCredType::Key(_) => None, - StakeCredType::Script(hash) => Some(hash.clone()), + CredType::Key(_) => None, + CredType::Script(hash) => Some(hash.clone()), } } - pub fn kind(&self) -> StakeCredKind { + pub fn kind(&self) -> CredKind { match &self.0 { - StakeCredType::Key(_) => StakeCredKind::Key, - StakeCredType::Script(_) => StakeCredKind::Script, + CredType::Key(_) => CredKind::Key, + CredType::Script(_) => CredKind::Script, } } pub fn has_script_hash(&self) -> bool { match &self.0 { - StakeCredType::Key(_) => false, - StakeCredType::Script(_) => true, + CredType::Key(_) => false, + CredType::Script(_) => true, } } fn to_raw_bytes(&self) -> Vec { match &self.0 { - StakeCredType::Key(hash) => hash.to_bytes(), - StakeCredType::Script(hash) => hash.to_bytes(), + CredType::Key(hash) => hash.to_bytes(), + CredType::Script(hash) => hash.to_bytes(), } } } @@ -180,11 +180,11 @@ impl cbor_event::se::Serialize for Credential { ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(2))?; match &self.0 { - StakeCredType::Key(keyhash) => { + CredType::Key(keyhash) => { serializer.write_unsigned_integer(0u64)?; serializer.write_bytes(keyhash.to_bytes()) } - StakeCredType::Script(scripthash) => { + CredType::Script(scripthash) => { serializer.write_unsigned_integer(1u64)?; serializer.write_bytes(scripthash.to_bytes()) } @@ -207,8 +207,8 @@ impl Deserialize for Credential { } } let cred_type = match raw.unsigned_integer()? { - 0 => StakeCredType::Key(Ed25519KeyHash::deserialize(raw)?), - 1 => StakeCredType::Script(ScriptHash::deserialize(raw)?), + 0 => CredType::Key(Ed25519KeyHash::deserialize(raw)?), + 1 => CredType::Script(ScriptHash::deserialize(raw)?), n => { return Err(DeserializeFailure::FixedValueMismatch { found: Key::Uint(n), diff --git a/rust/src/builders/certificates_builder.rs b/rust/src/builders/certificates_builder.rs index f9053ca8..570548ae 100644 --- a/rust/src/builders/certificates_builder.rs +++ b/rust/src/builders/certificates_builder.rs @@ -245,47 +245,47 @@ fn witness_keys_for_cert(cert_enum: &Certificate) -> RequiredSigners { // not witness as there is no single core node or genesis key that posts the certificate CertificateEnum::MoveInstantaneousRewardsCert(_cert) => {} CertificateEnum::CommitteeHotKeyRegistration(cert) => { - if let StakeCredType::Key(key_hash) = &cert.committee_cold_key.0 { + if let CredType::Key(key_hash) = &cert.committee_cold_key.0 { set.add(key_hash); } } CertificateEnum::CommitteeHotKeyDeregistration(cert) => { - if let StakeCredType::Key(key_hash) = &cert.committee_cold_key.0 { + if let CredType::Key(key_hash) = &cert.committee_cold_key.0 { set.add(key_hash); } } CertificateEnum::DrepUpdate(cert) => { - if let StakeCredType::Key(key_hash) = &cert.voting_credential.0 { + if let CredType::Key(key_hash) = &cert.voting_credential.0 { set.add(key_hash); } } CertificateEnum::DrepDeregistration(cert) => { - if let StakeCredType::Key(key_hash) = &cert.voting_credential.0 { + if let CredType::Key(key_hash) = &cert.voting_credential.0 { set.add(key_hash); } } CertificateEnum::StakeAndVoteDelegation(cert) => { - if let StakeCredType::Key(key_hash) = &cert.stake_credential.0 { + if let CredType::Key(key_hash) = &cert.stake_credential.0 { set.add(key_hash); } } CertificateEnum::VoteDelegation(cert) => { - if let StakeCredType::Key(key_hash) = &cert.stake_credential.0 { + if let CredType::Key(key_hash) = &cert.stake_credential.0 { set.add(key_hash); } } CertificateEnum::StakeRegistrationAndDelegation(cert) => { - if let StakeCredType::Key(key_hash) = &cert.stake_credential.0 { + if let CredType::Key(key_hash) = &cert.stake_credential.0 { set.add(key_hash); } } CertificateEnum::VoteRegistrationAndDelegation(cert) => { - if let StakeCredType::Key(key_hash) = &cert.stake_credential.0 { + if let CredType::Key(key_hash) = &cert.stake_credential.0 { set.add(key_hash); } } CertificateEnum::StakeVoteRegistrationAndDelegation(cert) => { - if let StakeCredType::Key(key_hash) = &cert.stake_credential.0 { + if let CredType::Key(key_hash) = &cert.stake_credential.0 { set.add(key_hash); } } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 4aef7874..031139f6 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1217,12 +1217,12 @@ impl PoolMetadata { #[derive( Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, )] -pub struct StakeCredentials(Vec); +pub struct Credentials(Vec); -impl_to_from!(StakeCredentials); +impl_to_from!(Credentials); #[wasm_bindgen] -impl StakeCredentials { +impl Credentials { pub fn new() -> Self { Self(Vec::new()) } diff --git a/rust/src/plutus.rs b/rust/src/plutus.rs index ce80ba21..7ef0567f 100644 --- a/rust/src/plutus.rs +++ b/rust/src/plutus.rs @@ -835,11 +835,11 @@ impl PlutusData { fn from_stake_credential(stake_credential: &Credential) -> Result { let (bytes_plutus_data, index) = match &stake_credential.0 { - StakeCredType::Key(key_hash) => ( + CredType::Key(key_hash) => ( PlutusData::new_bytes(key_hash.to_bytes().to_vec()), BigNum::from(0u32), ), - StakeCredType::Script(script_hash) => ( + CredType::Script(script_hash) => ( PlutusData::new_bytes(script_hash.to_bytes().to_vec()), BigNum::from(1u32), ), diff --git a/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs b/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs index 196639bb..f43f0236 100644 --- a/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs +++ b/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs @@ -106,8 +106,8 @@ impl MIRToStakeCredentials { self.rewards.get(cred).map(|v| v.clone()) } - pub fn keys(&self) -> StakeCredentials { - StakeCredentials( + pub fn keys(&self) -> Credentials { + Credentials( self.rewards .iter() .map(|(k, _v)| k.clone()) diff --git a/rust/src/protocol_types/governance/proposals/committee.rs b/rust/src/protocol_types/governance/proposals/committee.rs index 1de43d63..95249fea 100644 --- a/rust/src/protocol_types/governance/proposals/committee.rs +++ b/rust/src/protocol_types/governance/proposals/committee.rs @@ -55,8 +55,8 @@ impl Committee { } } - pub fn members_keys(&self) -> StakeCredentials { - StakeCredentials(self.members.keys().cloned().collect()) + pub fn members_keys(&self) -> Credentials { + Credentials(self.members.keys().cloned().collect()) } pub fn quorum_threshold(&self) -> UnitInterval { diff --git a/rust/src/protocol_types/governance/proposals/new_committee_proposal.rs b/rust/src/protocol_types/governance/proposals/new_committee_proposal.rs index ac526914..af7429af 100644 --- a/rust/src/protocol_types/governance/proposals/new_committee_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/new_committee_proposal.rs @@ -31,11 +31,11 @@ impl NewCommitteeProposal { self.committee.clone() } - pub fn members_to_remove(&self) -> StakeCredentials { - StakeCredentials(self.members_to_remove.iter().cloned().collect()) + pub fn members_to_remove(&self) -> Credentials { + Credentials(self.members_to_remove.iter().cloned().collect()) } - pub fn new(committee: &Committee, members_to_remove: &StakeCredentials) -> Self { + pub fn new(committee: &Committee, members_to_remove: &Credentials) -> Self { let members_to_remove = members_to_remove.0.iter().cloned().collect(); Self { gov_action_id: None, @@ -47,7 +47,7 @@ impl NewCommitteeProposal { pub fn new_with_action_id( gov_action_id: &GovernanceActionId, committee: &Committee, - members_to_remove: &StakeCredentials, + members_to_remove: &Credentials, ) -> Self { let members_to_remove = members_to_remove.0.iter().cloned().collect(); Self { diff --git a/rust/src/protocol_types/governance/voter.rs b/rust/src/protocol_types/governance/voter.rs index ceca0dae..987a8a51 100644 --- a/rust/src/protocol_types/governance/voter.rs +++ b/rust/src/protocol_types/governance/voter.rs @@ -62,12 +62,12 @@ impl Voter { pub fn kind(&self) -> VoterKind { match &self.0 { VoterEnum::ConstitutionalCommitteeHotKey(cred) => match cred.kind() { - StakeCredKind::Key => VoterKind::ConstitutionalCommitteeHotKeyHash, - StakeCredKind::Script => VoterKind::ConstitutionalCommitteeHotScriptHash, + CredKind::Key => VoterKind::ConstitutionalCommitteeHotKeyHash, + CredKind::Script => VoterKind::ConstitutionalCommitteeHotScriptHash, }, VoterEnum::DRep(cred) => match cred.kind() { - StakeCredKind::Key => VoterKind::DRepKeyHash, - StakeCredKind::Script => VoterKind::DRepScriptHash, + CredKind::Key => VoterKind::DRepKeyHash, + CredKind::Script => VoterKind::DRepScriptHash, }, VoterEnum::StakingPool(_) => VoterKind::StakingPoolKeyHash, } diff --git a/rust/src/serialization/general.rs b/rust/src/serialization/general.rs index 493c05ee..4c70686a 100644 --- a/rust/src/serialization/general.rs +++ b/rust/src/serialization/general.rs @@ -1133,7 +1133,7 @@ impl Deserialize for Ed25519KeyHashes { } } -impl cbor_event::se::Serialize for StakeCredentials { +impl cbor_event::se::Serialize for Credentials { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, @@ -1146,7 +1146,7 @@ impl cbor_event::se::Serialize for StakeCredentials { } } -impl Deserialize for StakeCredentials { +impl Deserialize for Credentials { fn deserialize(raw: &mut Deserializer) -> Result { let mut arr = Vec::new(); (|| -> Result<_, DeserializeError> { diff --git a/rust/src/serialization/governance/proposals/new_committee_proposal.rs b/rust/src/serialization/governance/proposals/new_committee_proposal.rs index 84f83083..857a9270 100644 --- a/rust/src/serialization/governance/proposals/new_committee_proposal.rs +++ b/rust/src/serialization/governance/proposals/new_committee_proposal.rs @@ -16,7 +16,7 @@ impl Serialize for NewCommitteeProposal { self.gov_action_id.serialize_nullable(serializer)?; - let members_to_remove = StakeCredentials(self.members_to_remove.iter().cloned().collect()); + let members_to_remove = Credentials(self.members_to_remove.iter().cloned().collect()); members_to_remove.serialize(serializer)?; self.committee.serialize(serializer)?; @@ -45,7 +45,7 @@ impl DeserializeEmbeddedGroup for NewCommitteeProposal { .map_err(|e| e.annotate("gov_action_id"))?; let members_to_remove = - StakeCredentials::deserialize(raw).map_err(|e| e.annotate("members_to_remove"))?; + Credentials::deserialize(raw).map_err(|e| e.annotate("members_to_remove"))?; let committee = Committee::deserialize(raw).map_err(|e| e.annotate("committee"))?; diff --git a/rust/src/serialization/governance/voter.rs b/rust/src/serialization/governance/voter.rs index 79dc9ed1..3badffd9 100644 --- a/rust/src/serialization/governance/voter.rs +++ b/rust/src/serialization/governance/voter.rs @@ -27,21 +27,21 @@ impl cbor_event::se::Serialize for VoterEnum { serializer.write_array(cbor_event::Len::Len(2))?; match &self { VoterEnum::ConstitutionalCommitteeHotKey(cred) => match &cred.0 { - StakeCredType::Key(key_hash) => { + CredType::Key(key_hash) => { serializer.write_unsigned_integer(0u64)?; key_hash.serialize(serializer)?; } - StakeCredType::Script(script_hash) => { + CredType::Script(script_hash) => { serializer.write_unsigned_integer(1u64)?; script_hash.serialize(serializer)?; } }, VoterEnum::DRep(cred) => match &cred.0 { - StakeCredType::Key(key_hash) => { + CredType::Key(key_hash) => { serializer.write_unsigned_integer(2u64)?; key_hash.serialize(serializer)?; } - StakeCredType::Script(script_hash) => { + CredType::Script(script_hash) => { serializer.write_unsigned_integer(3u64)?; script_hash.serialize(serializer)?; } @@ -70,16 +70,16 @@ impl Deserialize for VoterEnum { } } let voter = match raw.unsigned_integer()? { - 0 => VoterEnum::ConstitutionalCommitteeHotKey(Credential(StakeCredType::Key( + 0 => VoterEnum::ConstitutionalCommitteeHotKey(Credential(CredType::Key( Ed25519KeyHash::deserialize(raw)?, ))), - 1 => VoterEnum::ConstitutionalCommitteeHotKey(Credential(StakeCredType::Script( + 1 => VoterEnum::ConstitutionalCommitteeHotKey(Credential(CredType::Script( ScriptHash::deserialize(raw)?, ))), - 2 => VoterEnum::DRep(Credential(StakeCredType::Key(Ed25519KeyHash::deserialize( + 2 => VoterEnum::DRep(Credential(CredType::Key(Ed25519KeyHash::deserialize( raw, )?))), - 3 => VoterEnum::DRep(Credential(StakeCredType::Script(ScriptHash::deserialize( + 3 => VoterEnum::DRep(Credential(CredType::Script(ScriptHash::deserialize( raw, )?))), 4 => VoterEnum::StakingPool(Ed25519KeyHash::deserialize(raw)?), diff --git a/rust/src/tests/builders/voting_proposal_builder.rs b/rust/src/tests/builders/voting_proposal_builder.rs index 4e591319..466cdbe9 100644 --- a/rust/src/tests/builders/voting_proposal_builder.rs +++ b/rust/src/tests/builders/voting_proposal_builder.rs @@ -67,7 +67,7 @@ fn voting_proposal_builder_all_proposals() { let mut committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); - let mut members_to_remove = StakeCredentials::new(); + let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); let committee_proposal = NewCommitteeProposal::new(&committee, &members_to_remove); let wrapped_committee_proposal = VotingProposal::new_new_committee_proposal(&committee_proposal); @@ -165,7 +165,7 @@ fn voting_proposal_builder_with_plutus_script_witness() { let mut committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); - let mut members_to_remove = StakeCredentials::new(); + let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); let committee_proposal = NewCommitteeProposal::new(&committee, &members_to_remove); let wrapped_committee_proposal = VotingProposal::new_new_committee_proposal(&committee_proposal); @@ -262,7 +262,7 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { let mut committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); - let mut members_to_remove = StakeCredentials::new(); + let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); let committee_proposal = NewCommitteeProposal::new(&committee, &members_to_remove); let wrapped_committee_proposal = VotingProposal::new_new_committee_proposal(&committee_proposal); diff --git a/rust/src/tests/protocol_types/governance/proposals.rs b/rust/src/tests/protocol_types/governance/proposals.rs index 801cb12a..bef8daf7 100644 --- a/rust/src/tests/protocol_types/governance/proposals.rs +++ b/rust/src/tests/protocol_types/governance/proposals.rs @@ -58,7 +58,7 @@ fn hard_fork_initiation_proposal_setters_getters_test() { fn new_committee_proposal_setters_getters_test() { let action_id = create_action_id(); let committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); - let members_to_remove = StakeCredentials( + let members_to_remove = Credentials( vec![ Credential::from_keyhash(&fake_key_hash(1)), Credential::from_keyhash(&fake_key_hash(2)), diff --git a/rust/src/tests/serialization/governance/proposals.rs b/rust/src/tests/serialization/governance/proposals.rs index 53c973ed..ef4b0d2b 100644 --- a/rust/src/tests/serialization/governance/proposals.rs +++ b/rust/src/tests/serialization/governance/proposals.rs @@ -134,7 +134,7 @@ fn new_committee_proposal_ser_round_trip() { committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); committee.add_member(&Credential::from_scripthash(&fake_script_hash(2)), 2); - let mut members_to_remove = StakeCredentials::new(); + let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); members_to_remove.add(&Credential::from_scripthash(&fake_script_hash(2))); @@ -157,7 +157,7 @@ fn new_committee_proposal_with_action_id_ser_round_trip() { committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); committee.add_member(&Credential::from_scripthash(&fake_script_hash(2)), 2); - let mut members_to_remove = StakeCredentials::new(); + let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); members_to_remove.add(&Credential::from_scripthash(&fake_script_hash(2))); @@ -176,7 +176,7 @@ fn new_committee_proposal_with_action_id_ser_round_trip() { #[test] fn new_committee_proposal_with_empty_ser_round_trip() { let committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); - let members_to_remove = StakeCredentials::new(); + let members_to_remove = Credentials::new(); let proposal = NewCommitteeProposal::new(&committee, &members_to_remove); let proposal_wrapped = VotingProposal::new_new_committee_proposal(&proposal); From 686cd41627e1abe1cff30dccd7c7c9dab572abcd Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 10 Sep 2023 12:40:11 +0500 Subject: [PATCH 150/349] merge fix --- rust/src/protocol_types/plutus.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/src/protocol_types/plutus.rs b/rust/src/protocol_types/plutus.rs index 20b11853..8d004024 100644 --- a/rust/src/protocol_types/plutus.rs +++ b/rust/src/protocol_types/plutus.rs @@ -855,11 +855,11 @@ impl PlutusData { fn from_stake_credential(stake_credential: &Credential) -> Result { let (bytes_plutus_data, index) = match &stake_credential.0 { - StakeCredType::Key(key_hash) => ( + CredType::Key(key_hash) => ( PlutusData::new_bytes(key_hash.to_bytes().to_vec()), BigNum::from(0u32), ), - StakeCredType::Script(script_hash) => ( + CredType::Script(script_hash) => ( PlutusData::new_bytes(script_hash.to_bytes().to_vec()), BigNum::from(1u32), ), From 0f07db00f256f7eb125ae473873b6c2f1175d349 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 10 Sep 2023 12:41:06 +0500 Subject: [PATCH 151/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2c32b5f3..8e8451a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.4", + "version": "12.0.0-alpha.5", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index ccef0255..241af7b1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.4", + "version": "12.0.0-alpha.5", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 7f8dd589..073bd292 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.4" +version = "12.0.0-alpha.5" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 49fcc260..6519f254 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -37,7 +37,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.4" +version = "12.0.0-alpha.5" dependencies = [ "bech32", "cbor_event", From 52f6882673e329282cc33d2943f019d7ac79915e Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 10 Sep 2023 12:44:45 +0500 Subject: [PATCH 152/349] flow update --- rust/pkg/cardano_serialization_lib.js.flow | 200 +++++++++++---------- 1 file changed, 106 insertions(+), 94 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 96ef1b46..cd7de208 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -284,7 +284,7 @@ declare export var CborContainerType: {| /** */ -declare export var StakeCredKind: {| +declare export var CredKind: {| +Key: 0, // 0 +Script: 1, // 1 |}; @@ -2193,9 +2193,9 @@ declare export class Committee { static new(quorum_threshold: UnitInterval): Committee; /** - * @returns {StakeCredentials} + * @returns {Credentials} */ - members_keys(): StakeCredentials; + members_keys(): Credentials; /** * @returns {UnitInterval} @@ -2676,6 +2676,70 @@ declare export class Credential { */ static from_json(json: string): Credential; } +/** + */ +declare export class Credentials { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {Credentials} + */ + static from_bytes(bytes: Uint8Array): Credentials; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {Credentials} + */ + static from_hex(hex_str: string): Credentials; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {CredentialsJSON} + */ + to_js_value(): CredentialsJSON; + + /** + * @param {string} json + * @returns {Credentials} + */ + static from_json(json: string): Credentials; + + /** + * @returns {Credentials} + */ + static new(): Credentials; + + /** + * @returns {number} + */ + len(): number; + + /** + * @param {number} index + * @returns {Credential} + */ + get(index: number): Credential; + + /** + * @param {Credential} elem + */ + add(elem: Credential): void; +} /** */ declare export class DNSRecordAorAAAA { @@ -4993,9 +5057,9 @@ declare export class MIRToStakeCredentials { get(cred: Credential): Int | void; /** - * @returns {StakeCredentials} + * @returns {Credentials} */ - keys(): StakeCredentials; + keys(): Credentials; } /** */ @@ -5993,30 +6057,30 @@ declare export class NewCommitteeProposal { committee(): Committee; /** - * @returns {StakeCredentials} + * @returns {Credentials} */ - members_to_remove(): StakeCredentials; + members_to_remove(): Credentials; /** * @param {Committee} committee - * @param {StakeCredentials} members_to_remove + * @param {Credentials} members_to_remove * @returns {NewCommitteeProposal} */ static new( committee: Committee, - members_to_remove: StakeCredentials + members_to_remove: Credentials ): NewCommitteeProposal; /** * @param {GovernanceActionId} gov_action_id * @param {Committee} committee - * @param {StakeCredentials} members_to_remove + * @param {Credentials} members_to_remove * @returns {NewCommitteeProposal} */ static new_with_action_id( gov_action_id: GovernanceActionId, committee: Committee, - members_to_remove: StakeCredentials + members_to_remove: Credentials ): NewCommitteeProposal; } /** @@ -7747,6 +7811,8 @@ declare export class ProtocolParamUpdate { extra_entropy(): Nonce | void; /** + * !!! DEPRECATED !!! + * Since conway era this param is outdated. But this param you can meet in a pre-conway block. * @param {ProtocolVersion} protocol_version */ set_protocol_version(protocol_version: ProtocolVersion): void; @@ -9179,70 +9245,6 @@ declare export class StakeAndVoteDelegation { */ has_script_credentials(): boolean; } -/** - */ -declare export class StakeCredentials { - free(): void; - - /** - * @returns {Uint8Array} - */ - to_bytes(): Uint8Array; - - /** - * @param {Uint8Array} bytes - * @returns {StakeCredentials} - */ - static from_bytes(bytes: Uint8Array): StakeCredentials; - - /** - * @returns {string} - */ - to_hex(): string; - - /** - * @param {string} hex_str - * @returns {StakeCredentials} - */ - static from_hex(hex_str: string): StakeCredentials; - - /** - * @returns {string} - */ - to_json(): string; - - /** - * @returns {StakeCredentialsJSON} - */ - to_js_value(): StakeCredentialsJSON; - - /** - * @param {string} json - * @returns {StakeCredentials} - */ - static from_json(json: string): StakeCredentials; - - /** - * @returns {StakeCredentials} - */ - static new(): StakeCredentials; - - /** - * @returns {number} - */ - len(): number; - - /** - * @param {number} index - * @returns {Credential} - */ - get(index: number): Credential; - - /** - * @param {Credential} elem - */ - add(elem: Credential): void; -} /** */ declare export class StakeDelegation { @@ -13728,11 +13730,11 @@ export interface CommitteeJSON { quorum_threshold: UnitIntervalJSON; } export interface CommitteeHotKeyDeregistrationJSON { - committee_cold_key: CredentialJSON; + committee_cold_key: CredTypeJSON; } export interface CommitteeHotKeyRegistrationJSON { - committee_cold_key: CredentialJSON; - committee_hot_key: CredentialJSON; + committee_cold_key: CredTypeJSON; + committee_hot_key: CredTypeJSON; } export interface ConstitutionJSON { anchor: AnchorJSON; @@ -13742,8 +13744,7 @@ export type CostModelJSON = string[]; export interface CostmdlsJSON { [k: string]: CostModelJSON; } -export type CredentialJSON = StakeCredTypeJSON; -export type StakeCredTypeJSON = +export type CredTypeJSON = | { Key: string, ... @@ -13752,6 +13753,8 @@ export type StakeCredTypeJSON = Script: string, ... }; +export type CredentialJSON = CredTypeJSON; +export type CredentialsJSON = CredTypeJSON[]; export type DNSRecordAorAAAAJSON = string; export type DNSRecordSRVJSON = string; export type DRepJSON = DRepEnumJSON; @@ -13777,16 +13780,16 @@ export type DataOptionJSON = }; export interface DrepDeregistrationJSON { coin: string; - voting_credential: CredentialJSON; + voting_credential: CredTypeJSON; } export interface DrepRegistrationJSON { anchor?: AnchorJSON | null; coin: string; - voting_credential: CredentialJSON; + voting_credential: CredTypeJSON; } export interface DrepUpdateJSON { anchor?: AnchorJSON | null; - voting_credential: CredentialJSON; + voting_credential: CredTypeJSON; } export interface DrepVotingThresholdsJSON { committee_no_confidence: UnitIntervalJSON; @@ -13939,7 +13942,7 @@ export type NetworkIdKindJSON = "Testnet" | "Mainnet"; export interface NewCommitteeProposalJSON { committee: CommitteeJSON; gov_action_id?: GovernanceActionIdJSON | null; - members_to_remove: CredentialJSON[]; + members_to_remove: CredTypeJSON[]; } export interface NewConstitutionProposalJSON { constitution: ConstitutionJSON; @@ -14139,31 +14142,40 @@ export interface SingleHostNameJSON { export interface StakeAndVoteDelegationJSON { drep: DRepJSON; pool_keyhash: string; - stake_credential: CredentialJSON; + stake_credential: CredTypeJSON; } +export type StakeCredTypeJSON = + | { + Key: string, + ... + } + | { + Script: string, + ... + }; export type StakeCredentialsJSON = CredentialJSON[]; export interface StakeDelegationJSON { pool_keyhash: string; - stake_credential: CredentialJSON; + stake_credential: CredTypeJSON; } export interface StakeDeregistrationJSON { coin?: string | null; - stake_credential: CredentialJSON; + stake_credential: CredTypeJSON; } export interface StakeRegistrationJSON { coin?: string | null; - stake_credential: CredentialJSON; + stake_credential: CredTypeJSON; } export interface StakeRegistrationAndDelegationJSON { coin: string; pool_keyhash: string; - stake_credential: CredentialJSON; + stake_credential: CredTypeJSON; } export interface StakeVoteRegistrationAndDelegationJSON { coin: string; drep: DRepJSON; pool_keyhash: string; - stake_credential: CredentialJSON; + stake_credential: CredTypeJSON; } export interface TimelockExpiryJSON { slot: string; @@ -14266,21 +14278,21 @@ export interface VkeywitnessJSON { export type VkeywitnessesJSON = VkeywitnessJSON[]; export interface VoteDelegationJSON { drep: DRepJSON; - stake_credential: CredentialJSON; + stake_credential: CredTypeJSON; } export interface VoteRegistrationAndDelegationJSON { coin: string; drep: DRepJSON; - stake_credential: CredentialJSON; + stake_credential: CredTypeJSON; } export type VoterJSON = VoterEnumJSON; export type VoterEnumJSON = | { - ConstitutionalCommitteeHotKey: CredentialJSON, + ConstitutionalCommitteeHotKey: CredTypeJSON, ... } | { - DRepJSON: CredentialJSON, + DRepJSON: CredTypeJSON, ... } | { From 867ee69ecf5970fc226cd3edacd542e38fd9a7bd Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 18 Sep 2023 18:37:02 +0900 Subject: [PATCH 153/349] rename 'new committee' to 'update committee' --- rust/json-gen/src/main.rs | 2 +- .../src/protocol_types/governance/proposals/mod.rs | 4 ++-- ...ee_proposal.rs => update_committee_proposal.rs} | 6 +++--- .../governance/proposals/voting_proposal.rs | 14 +++++++------- rust/src/serialization/governance/proposals/mod.rs | 4 ++-- ...ee_proposal.rs => update_committee_proposal.rs} | 14 +++++++------- .../governance/proposals/voting_proposal.rs | 8 ++++---- .../map_names/voting_proposal_index_names.rs | 2 +- rust/src/tests/builders/voting_proposal_builder.rs | 6 +++--- .../tests/protocol_types/governance/proposals.rs | 4 ++-- .../tests/serialization/governance/proposals.rs | 12 ++++++------ 11 files changed, 38 insertions(+), 38 deletions(-) rename rust/src/protocol_types/governance/proposals/{new_committee_proposal.rs => update_committee_proposal.rs} (92%) rename rust/src/serialization/governance/proposals/{new_committee_proposal.rs => update_committee_proposal.rs} (77%) diff --git a/rust/json-gen/src/main.rs b/rust/json-gen/src/main.rs index b6f4e9f9..b274f2bd 100644 --- a/rust/json-gen/src/main.rs +++ b/rust/json-gen/src/main.rs @@ -178,7 +178,7 @@ fn main() { gen_json_schema!(VotingProposal); gen_json_schema!(VotingProposals); gen_json_schema!(HardForkInitiationProposal); - gen_json_schema!(NewCommitteeProposal); + gen_json_schema!(UpdateCommitteeProposal); gen_json_schema!(NewConstitutionProposal); gen_json_schema!(NoConfidenceProposal); gen_json_schema!(ParameterChangeProposal); diff --git a/rust/src/protocol_types/governance/proposals/mod.rs b/rust/src/protocol_types/governance/proposals/mod.rs index 9a21f560..2d870663 100644 --- a/rust/src/protocol_types/governance/proposals/mod.rs +++ b/rust/src/protocol_types/governance/proposals/mod.rs @@ -16,8 +16,8 @@ pub use no_confidence_proposal::*; mod committee; pub use committee::*; -mod new_committee_proposal; -pub use new_committee_proposal::*; +mod update_committee_proposal; +pub use update_committee_proposal::*; mod constitution; pub use constitution::*; diff --git a/rust/src/protocol_types/governance/proposals/new_committee_proposal.rs b/rust/src/protocol_types/governance/proposals/update_committee_proposal.rs similarity index 92% rename from rust/src/protocol_types/governance/proposals/new_committee_proposal.rs rename to rust/src/protocol_types/governance/proposals/update_committee_proposal.rs index af7429af..7cc09f1b 100644 --- a/rust/src/protocol_types/governance/proposals/new_committee_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/update_committee_proposal.rs @@ -13,16 +13,16 @@ use crate::*; JsonSchema, )] #[wasm_bindgen] -pub struct NewCommitteeProposal { +pub struct UpdateCommitteeProposal { pub(crate) gov_action_id: Option, pub(crate) committee: Committee, pub(crate) members_to_remove: BTreeSet, } -impl_to_from!(NewCommitteeProposal); +impl_to_from!(UpdateCommitteeProposal); #[wasm_bindgen] -impl NewCommitteeProposal { +impl UpdateCommitteeProposal { pub fn gov_action_id(&self) -> Option { self.gov_action_id.clone() } diff --git a/rust/src/protocol_types/governance/proposals/voting_proposal.rs b/rust/src/protocol_types/governance/proposals/voting_proposal.rs index 3160a972..90d87033 100644 --- a/rust/src/protocol_types/governance/proposals/voting_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/voting_proposal.rs @@ -17,7 +17,7 @@ pub(crate) enum VotingProposalEnum { HardForkInitiationProposal(HardForkInitiationProposal), TreasuryWithdrawalsProposal(TreasuryWithdrawalsProposal), NoConfidenceProposal(NoConfidenceProposal), - NewCommitteeProposal(NewCommitteeProposal), + UpdateCommitteeProposal(UpdateCommitteeProposal), NewConstitutionProposal(NewConstitutionProposal), InfoProposal(InfoProposal), } @@ -40,7 +40,7 @@ pub enum VotingProposalKind { HardForkInitiationProposal = 1, TreasuryWithdrawalsProposal = 2, NoConfidenceProposal = 3, - NewCommitteeProposal = 4, + UpdateCommitteeProposal = 4, NewConstitutionProposal = 5, InfoProposal = 6, } @@ -94,8 +94,8 @@ impl VotingProposal { )) } - pub fn new_new_committee_proposal(new_committee_proposal: &NewCommitteeProposal) -> Self { - Self(VotingProposalEnum::NewCommitteeProposal( + pub fn new_new_committee_proposal(new_committee_proposal: &UpdateCommitteeProposal) -> Self { + Self(VotingProposalEnum::UpdateCommitteeProposal( new_committee_proposal.clone(), )) } @@ -124,7 +124,7 @@ impl VotingProposal { VotingProposalKind::TreasuryWithdrawalsProposal } VotingProposalEnum::NoConfidenceProposal(_) => VotingProposalKind::NoConfidenceProposal, - VotingProposalEnum::NewCommitteeProposal(_) => VotingProposalKind::NewCommitteeProposal, + VotingProposalEnum::UpdateCommitteeProposal(_) => VotingProposalKind::UpdateCommitteeProposal, VotingProposalEnum::NewConstitutionProposal(_) => { VotingProposalKind::NewConstitutionProposal } @@ -160,9 +160,9 @@ impl VotingProposal { } } - pub fn as_new_committee_proposal(&self) -> Option { + pub fn as_new_committee_proposal(&self) -> Option { match &self.0 { - VotingProposalEnum::NewCommitteeProposal(p) => Some(p.clone()), + VotingProposalEnum::UpdateCommitteeProposal(p) => Some(p.clone()), _ => None, } } diff --git a/rust/src/serialization/governance/proposals/mod.rs b/rust/src/serialization/governance/proposals/mod.rs index 64a9f601..191814a7 100644 --- a/rust/src/serialization/governance/proposals/mod.rs +++ b/rust/src/serialization/governance/proposals/mod.rs @@ -16,8 +16,8 @@ pub use no_confidence_proposal::*; mod committee; pub use committee::*; -mod new_committee_proposal; -pub use new_committee_proposal::*; +mod update_committee_proposal; +pub use update_committee_proposal::*; mod constitution; pub use constitution::*; diff --git a/rust/src/serialization/governance/proposals/new_committee_proposal.rs b/rust/src/serialization/governance/proposals/update_committee_proposal.rs similarity index 77% rename from rust/src/serialization/governance/proposals/new_committee_proposal.rs rename to rust/src/serialization/governance/proposals/update_committee_proposal.rs index 857a9270..cb1ba128 100644 --- a/rust/src/serialization/governance/proposals/new_committee_proposal.rs +++ b/rust/src/serialization/governance/proposals/update_committee_proposal.rs @@ -4,15 +4,15 @@ use crate::*; use map_names::VotingProposalIndexNames; use num_traits::ToPrimitive; -impl Serialize for NewCommitteeProposal { +impl Serialize for UpdateCommitteeProposal { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(4))?; - let proposal_index = VotingProposalIndexNames::NewCommitteeAction.to_u64(); - serialize_and_check_index(serializer, proposal_index, "NewCommitteeAction")?; + let proposal_index = VotingProposalIndexNames::UpdateCommitteeAction.to_u64(); + serialize_and_check_index(serializer, proposal_index, "UpdateCommitteeAction")?; self.gov_action_id.serialize_nullable(serializer)?; @@ -25,9 +25,9 @@ impl Serialize for NewCommitteeProposal { } } -impl_deserialize_for_wrapped_tuple!(NewCommitteeProposal); +impl_deserialize_for_wrapped_tuple!(UpdateCommitteeProposal); -impl DeserializeEmbeddedGroup for NewCommitteeProposal { +impl DeserializeEmbeddedGroup for UpdateCommitteeProposal { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, @@ -38,7 +38,7 @@ impl DeserializeEmbeddedGroup for NewCommitteeProposal { "(proposal_index, gov_action_id / null, set<$committee_cold_credential>, committee)", )?; - let desired_index = VotingProposalIndexNames::NewCommitteeAction.to_u64(); + let desired_index = VotingProposalIndexNames::UpdateCommitteeAction.to_u64(); deserialize_and_check_index(raw, desired_index, "proposal_index")?; let gov_action_id = GovernanceActionId::deserialize_nullable(raw) @@ -49,7 +49,7 @@ impl DeserializeEmbeddedGroup for NewCommitteeProposal { let committee = Committee::deserialize(raw).map_err(|e| e.annotate("committee"))?; - return Ok(NewCommitteeProposal { + return Ok(UpdateCommitteeProposal { gov_action_id, members_to_remove: members_to_remove.0.iter().cloned().collect(), committee, diff --git a/rust/src/serialization/governance/proposals/voting_proposal.rs b/rust/src/serialization/governance/proposals/voting_proposal.rs index 431034c4..181253dc 100644 --- a/rust/src/serialization/governance/proposals/voting_proposal.rs +++ b/rust/src/serialization/governance/proposals/voting_proposal.rs @@ -14,7 +14,7 @@ impl Serialize for VotingProposal { VotingProposalEnum::HardForkInitiationProposal(x) => x.serialize(serializer), VotingProposalEnum::TreasuryWithdrawalsProposal(x) => x.serialize(serializer), VotingProposalEnum::NoConfidenceProposal(x) => x.serialize(serializer), - VotingProposalEnum::NewCommitteeProposal(x) => x.serialize(serializer), + VotingProposalEnum::UpdateCommitteeProposal(x) => x.serialize(serializer), VotingProposalEnum::NewConstitutionProposal(x) => x.serialize(serializer), VotingProposalEnum::InfoProposal(_) => { let index = VotingProposalIndexNames::InfoAction.to_u64(); @@ -88,9 +88,9 @@ impl DeserializeEmbeddedGroup for VotingProposal { NoConfidenceProposal::deserialize_as_embedded_group(raw, len)?, )) } - VotingProposalIndexNames::NewCommitteeAction => { - Ok(VotingProposalEnum::NewCommitteeProposal( - NewCommitteeProposal::deserialize_as_embedded_group(raw, len)?, + VotingProposalIndexNames::UpdateCommitteeAction => { + Ok(VotingProposalEnum::UpdateCommitteeProposal( + UpdateCommitteeProposal::deserialize_as_embedded_group(raw, len)?, )) } VotingProposalIndexNames::NewConstitutionAction => { diff --git a/rust/src/serialization/map_names/voting_proposal_index_names.rs b/rust/src/serialization/map_names/voting_proposal_index_names.rs index b5893c00..bf8c33f2 100644 --- a/rust/src/serialization/map_names/voting_proposal_index_names.rs +++ b/rust/src/serialization/map_names/voting_proposal_index_names.rs @@ -4,7 +4,7 @@ pub(crate) enum VotingProposalIndexNames { HardForkInitiationAction = 1, TreasuryWithdrawalsAction = 2, NoConfidenceAction = 3, - NewCommitteeAction = 4, + UpdateCommitteeAction = 4, NewConstitutionAction = 5, InfoAction = 6, } diff --git a/rust/src/tests/builders/voting_proposal_builder.rs b/rust/src/tests/builders/voting_proposal_builder.rs index 466cdbe9..7d9d58dc 100644 --- a/rust/src/tests/builders/voting_proposal_builder.rs +++ b/rust/src/tests/builders/voting_proposal_builder.rs @@ -69,7 +69,7 @@ fn voting_proposal_builder_all_proposals() { committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); - let committee_proposal = NewCommitteeProposal::new(&committee, &members_to_remove); + let committee_proposal = UpdateCommitteeProposal::new(&committee, &members_to_remove); let wrapped_committee_proposal = VotingProposal::new_new_committee_proposal(&committee_proposal); builder.add(&wrapped_committee_proposal).unwrap(); @@ -167,7 +167,7 @@ fn voting_proposal_builder_with_plutus_script_witness() { committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); - let committee_proposal = NewCommitteeProposal::new(&committee, &members_to_remove); + let committee_proposal = UpdateCommitteeProposal::new(&committee, &members_to_remove); let wrapped_committee_proposal = VotingProposal::new_new_committee_proposal(&committee_proposal); builder.add_with_plutus_witness(&wrapped_committee_proposal, &plutus_witness).unwrap(); @@ -264,7 +264,7 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); - let committee_proposal = NewCommitteeProposal::new(&committee, &members_to_remove); + let committee_proposal = UpdateCommitteeProposal::new(&committee, &members_to_remove); let wrapped_committee_proposal = VotingProposal::new_new_committee_proposal(&committee_proposal); builder.add_with_plutus_witness(&wrapped_committee_proposal, &plutus_witness).unwrap(); diff --git a/rust/src/tests/protocol_types/governance/proposals.rs b/rust/src/tests/protocol_types/governance/proposals.rs index bef8daf7..1a3abf1a 100644 --- a/rust/src/tests/protocol_types/governance/proposals.rs +++ b/rust/src/tests/protocol_types/governance/proposals.rs @@ -67,9 +67,9 @@ fn new_committee_proposal_setters_getters_test() { .collect(), ); - let proposal = NewCommitteeProposal::new(&committee, &members_to_remove); + let proposal = UpdateCommitteeProposal::new(&committee, &members_to_remove); let proposal_with_action_id = - NewCommitteeProposal::new_with_action_id(&action_id, &committee, &members_to_remove); + UpdateCommitteeProposal::new_with_action_id(&action_id, &committee, &members_to_remove); assert_eq!(proposal.gov_action_id(), None); assert_eq!(proposal.committee(), committee); assert_eq!(proposal.members_to_remove(), members_to_remove); diff --git a/rust/src/tests/serialization/governance/proposals.rs b/rust/src/tests/serialization/governance/proposals.rs index ef4b0d2b..e2f57eb4 100644 --- a/rust/src/tests/serialization/governance/proposals.rs +++ b/rust/src/tests/serialization/governance/proposals.rs @@ -138,11 +138,11 @@ fn new_committee_proposal_ser_round_trip() { members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); members_to_remove.add(&Credential::from_scripthash(&fake_script_hash(2))); - let proposal = NewCommitteeProposal::new(&committee, &members_to_remove); + let proposal = UpdateCommitteeProposal::new(&committee, &members_to_remove); let proposal_wrapped = VotingProposal::new_new_committee_proposal(&proposal); - to_from_test!(NewCommitteeProposal, proposal, proposal_wrapped); + to_from_test!(UpdateCommitteeProposal, proposal, proposal_wrapped); assert_eq!( proposal, proposal_wrapped.as_new_committee_proposal().unwrap() @@ -162,11 +162,11 @@ fn new_committee_proposal_with_action_id_ser_round_trip() { members_to_remove.add(&Credential::from_scripthash(&fake_script_hash(2))); let proposal = - NewCommitteeProposal::new_with_action_id(&action_id, &committee, &members_to_remove); + UpdateCommitteeProposal::new_with_action_id(&action_id, &committee, &members_to_remove); let proposal_wrapped = VotingProposal::new_new_committee_proposal(&proposal); - to_from_test!(NewCommitteeProposal, proposal, proposal_wrapped); + to_from_test!(UpdateCommitteeProposal, proposal, proposal_wrapped); assert_eq!( proposal, proposal_wrapped.as_new_committee_proposal().unwrap() @@ -177,11 +177,11 @@ fn new_committee_proposal_with_action_id_ser_round_trip() { fn new_committee_proposal_with_empty_ser_round_trip() { let committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); let members_to_remove = Credentials::new(); - let proposal = NewCommitteeProposal::new(&committee, &members_to_remove); + let proposal = UpdateCommitteeProposal::new(&committee, &members_to_remove); let proposal_wrapped = VotingProposal::new_new_committee_proposal(&proposal); - to_from_test!(NewCommitteeProposal, proposal, proposal_wrapped); + to_from_test!(UpdateCommitteeProposal, proposal, proposal_wrapped); assert_eq!( proposal, proposal_wrapped.as_new_committee_proposal().unwrap() From d82c1b4cf757e70f9b85da67c75f5bc441704e84 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 18 Sep 2023 19:13:16 +0900 Subject: [PATCH 154/349] updated new committee serialization --- .../serialization/governance/proposals/committee.rs | 11 +++++++++-- .../governance/proposals/update_committee_proposal.rs | 7 ++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/rust/src/serialization/governance/proposals/committee.rs b/rust/src/serialization/governance/proposals/committee.rs index 6a1a88c2..9cf74130 100644 --- a/rust/src/serialization/governance/proposals/committee.rs +++ b/rust/src/serialization/governance/proposals/committee.rs @@ -8,12 +8,19 @@ impl Serialize for Committee { serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(2))?; - self.quorum_threshold.serialize(serializer)?; + self.serialize_as_embedded_group(serializer)?; + Ok(serializer) + } +} + +impl SerializeEmbeddedGroup for Committee { + fn serialize_as_embedded_group<'a, W: Write + Sized>(&self, serializer: &'a mut Serializer) -> cbor_event::Result<&'a mut Serializer> { serializer.write_map(cbor_event::Len::Len(self.members.len() as u64))?; for (key, value) in &self.members { key.serialize(serializer)?; value.serialize(serializer)?; } + self.quorum_threshold.serialize(serializer)?; Ok(serializer) } } @@ -25,7 +32,7 @@ impl DeserializeEmbeddedGroup for Committee { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - check_len(len, 2, "(quorum_threshold, members)")?; + check_len(len, 2, "(members, quorum_threshold)")?; let quorum_threshold = UnitInterval::deserialize(raw)?; let mut table = BTreeMap::new(); diff --git a/rust/src/serialization/governance/proposals/update_committee_proposal.rs b/rust/src/serialization/governance/proposals/update_committee_proposal.rs index cb1ba128..d3c9cb7f 100644 --- a/rust/src/serialization/governance/proposals/update_committee_proposal.rs +++ b/rust/src/serialization/governance/proposals/update_committee_proposal.rs @@ -34,8 +34,8 @@ impl DeserializeEmbeddedGroup for UpdateCommitteeProposal { ) -> Result { check_len( len, - 4, - "(proposal_index, gov_action_id / null, set<$committee_cold_credential>, committee)", + 5, + "(proposal_index, gov_action_id / null, set<$committee_cold_credential>, { committee_cold_credential => epoch }, unit_interval)", )?; let desired_index = VotingProposalIndexNames::UpdateCommitteeAction.to_u64(); @@ -47,7 +47,8 @@ impl DeserializeEmbeddedGroup for UpdateCommitteeProposal { let members_to_remove = Credentials::deserialize(raw).map_err(|e| e.annotate("members_to_remove"))?; - let committee = Committee::deserialize(raw).map_err(|e| e.annotate("committee"))?; + let committee = Committee::deserialize_as_embedded_group(raw, cbor_event::Len::Len(2)) + .map_err(|e| e.annotate("committee"))?; return Ok(UpdateCommitteeProposal { gov_action_id, From c3160c3624d84a8b40fbe33ce845ce757ad89e85 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 18 Sep 2023 19:30:00 +0900 Subject: [PATCH 155/349] update new committee serialization --- rust/src/serialization/governance/proposals/committee.rs | 3 ++- .../governance/proposals/update_committee_proposal.rs | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/rust/src/serialization/governance/proposals/committee.rs b/rust/src/serialization/governance/proposals/committee.rs index 9cf74130..f470aa05 100644 --- a/rust/src/serialization/governance/proposals/committee.rs +++ b/rust/src/serialization/governance/proposals/committee.rs @@ -33,7 +33,6 @@ impl DeserializeEmbeddedGroup for Committee { len: cbor_event::Len, ) -> Result { check_len(len, 2, "(members, quorum_threshold)")?; - let quorum_threshold = UnitInterval::deserialize(raw)?; let mut table = BTreeMap::new(); let map_len = raw.map()?; @@ -54,6 +53,8 @@ impl DeserializeEmbeddedGroup for Committee { .into()); } } + let quorum_threshold = UnitInterval::deserialize(raw)?; + Ok(Committee { quorum_threshold, members: table, diff --git a/rust/src/serialization/governance/proposals/update_committee_proposal.rs b/rust/src/serialization/governance/proposals/update_committee_proposal.rs index d3c9cb7f..34c95abb 100644 --- a/rust/src/serialization/governance/proposals/update_committee_proposal.rs +++ b/rust/src/serialization/governance/proposals/update_committee_proposal.rs @@ -9,7 +9,7 @@ impl Serialize for UpdateCommitteeProposal { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(4))?; + serializer.write_array(cbor_event::Len::Len(5))?; let proposal_index = VotingProposalIndexNames::UpdateCommitteeAction.to_u64(); serialize_and_check_index(serializer, proposal_index, "UpdateCommitteeAction")?; @@ -19,7 +19,7 @@ impl Serialize for UpdateCommitteeProposal { let members_to_remove = Credentials(self.members_to_remove.iter().cloned().collect()); members_to_remove.serialize(serializer)?; - self.committee.serialize(serializer)?; + self.committee.serialize_as_embedded_group(serializer)?; Ok(serializer) } From 6f71cc2c4e71832bb7e0fbf338ca34a2560f73d8 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 18 Sep 2023 19:51:45 +0900 Subject: [PATCH 156/349] rename committee certs --- rust/json-gen/src/main.rs | 4 +-- rust/src/builders/certificates_builder.rs | 4 +-- .../certificates/certificate.rs | 36 +++++++++---------- .../committee_hot_key_deregistration.rs | 6 ++-- .../committee_hot_key_registration.rs | 6 ++-- .../serialization/certificates/certificate.rs | 16 ++++----- ...gistration.rs => committee_cold_resign.rs} | 14 ++++---- ..._registration.rs => committee_hot_auth.rs} | 14 ++++---- rust/src/serialization/certificates/mod.rs | 4 +-- .../map_names/certificate_index_names.rs | 4 +-- .../tests/builders/certificates_builder.rs | 12 +++---- rust/src/tests/protocol_types/certificates.rs | 6 ++-- rust/src/tests/serialization/certificates.rs | 12 +++---- 13 files changed, 69 insertions(+), 69 deletions(-) rename rust/src/serialization/certificates/{committee_hot_key_deregistration.rs => committee_cold_resign.rs} (67%) rename rust/src/serialization/certificates/{committee_hot_key_registration.rs => committee_hot_auth.rs} (78%) diff --git a/rust/json-gen/src/main.rs b/rust/json-gen/src/main.rs index b274f2bd..98b56858 100644 --- a/rust/json-gen/src/main.rs +++ b/rust/json-gen/src/main.rs @@ -164,8 +164,8 @@ fn main() { gen_json_schema!(GovernanceActionId); gen_json_schema!(VotingProcedure); gen_json_schema!(VotingProcedures); - gen_json_schema!(CommitteeHotKeyDeregistration); - gen_json_schema!(CommitteeHotKeyRegistration); + gen_json_schema!(CommitteeHotAuth); + gen_json_schema!(CommitteeColdResign); gen_json_schema!(DrepDeregistration); gen_json_schema!(DrepRegistration); gen_json_schema!(DrepUpdate); diff --git a/rust/src/builders/certificates_builder.rs b/rust/src/builders/certificates_builder.rs index 570548ae..d4c892d1 100644 --- a/rust/src/builders/certificates_builder.rs +++ b/rust/src/builders/certificates_builder.rs @@ -244,12 +244,12 @@ fn witness_keys_for_cert(cert_enum: &Certificate) -> RequiredSigners { } // not witness as there is no single core node or genesis key that posts the certificate CertificateEnum::MoveInstantaneousRewardsCert(_cert) => {} - CertificateEnum::CommitteeHotKeyRegistration(cert) => { + CertificateEnum::CommitteeHotAuth(cert) => { if let CredType::Key(key_hash) = &cert.committee_cold_key.0 { set.add(key_hash); } } - CertificateEnum::CommitteeHotKeyDeregistration(cert) => { + CertificateEnum::CommitteeColdResign(cert) => { if let CredType::Key(key_hash) = &cert.committee_cold_key.0 { set.add(key_hash); } diff --git a/rust/src/protocol_types/certificates/certificate.rs b/rust/src/protocol_types/certificates/certificate.rs index ba7827c5..9e2dfaff 100644 --- a/rust/src/protocol_types/certificates/certificate.rs +++ b/rust/src/protocol_types/certificates/certificate.rs @@ -10,8 +10,8 @@ pub enum CertificateKind { PoolRetirement, GenesisKeyDelegation, MoveInstantaneousRewardsCert, - CommitteeHotKeyRegistration, - CommitteeHotKeyDeregistration, + CommitteeHotAuth, + CommitteeColdResign, DrepDeregistration, DrepRegistration, DrepUpdate, @@ -42,8 +42,8 @@ pub enum CertificateEnum { PoolRetirement(PoolRetirement), GenesisKeyDelegation(GenesisKeyDelegation), MoveInstantaneousRewardsCert(MoveInstantaneousRewardsCert), - CommitteeHotKeyRegistration(CommitteeHotKeyRegistration), - CommitteeHotKeyDeregistration(CommitteeHotKeyDeregistration), + CommitteeHotAuth(CommitteeHotAuth), + CommitteeColdResign(CommitteeColdResign), DrepDeregistration(DrepDeregistration), DrepRegistration(DrepRegistration), DrepUpdate(DrepUpdate), @@ -112,17 +112,17 @@ impl Certificate { } pub fn new_committee_hot_key_registration( - committee_hot_key_registration: &CommitteeHotKeyRegistration, + committee_hot_key_registration: &CommitteeHotAuth, ) -> Self { - Self(CertificateEnum::CommitteeHotKeyRegistration( + Self(CertificateEnum::CommitteeHotAuth( committee_hot_key_registration.clone(), )) } pub fn new_committee_hot_key_deregistration( - committee_hot_key_deregistration: &CommitteeHotKeyDeregistration, + committee_hot_key_deregistration: &CommitteeColdResign, ) -> Self { - Self(CertificateEnum::CommitteeHotKeyDeregistration( + Self(CertificateEnum::CommitteeColdResign( committee_hot_key_deregistration.clone(), )) } @@ -188,11 +188,11 @@ impl Certificate { CertificateEnum::MoveInstantaneousRewardsCert(_) => { CertificateKind::MoveInstantaneousRewardsCert } - CertificateEnum::CommitteeHotKeyRegistration(_) => { - CertificateKind::CommitteeHotKeyRegistration + CertificateEnum::CommitteeHotAuth(_) => { + CertificateKind::CommitteeHotAuth } - CertificateEnum::CommitteeHotKeyDeregistration(_) => { - CertificateKind::CommitteeHotKeyDeregistration + CertificateEnum::CommitteeColdResign(_) => { + CertificateKind::CommitteeColdResign } CertificateEnum::DrepDeregistration(_) => CertificateKind::DrepDeregistration, CertificateEnum::DrepRegistration(_) => CertificateKind::DrepRegistration, @@ -260,16 +260,16 @@ impl Certificate { } } - pub fn as_committee_hot_key_registration(&self) -> Option { + pub fn as_committee_hot_key_registration(&self) -> Option { match &self.0 { - CertificateEnum::CommitteeHotKeyRegistration(x) => Some(x.clone()), + CertificateEnum::CommitteeHotAuth(x) => Some(x.clone()), _ => None, } } - pub fn as_committee_hot_key_deregistration(&self) -> Option { + pub fn as_committee_hot_key_deregistration(&self) -> Option { match &self.0 { - CertificateEnum::CommitteeHotKeyDeregistration(x) => Some(x.clone()), + CertificateEnum::CommitteeColdResign(x) => Some(x.clone()), _ => None, } } @@ -341,8 +341,8 @@ impl Certificate { CertificateEnum::StakeRegistrationAndDelegation(x) => x.has_script_credentials(), CertificateEnum::StakeVoteRegistrationAndDelegation(x) => x.has_script_credentials(), CertificateEnum::VoteRegistrationAndDelegation(x) => x.has_script_credentials(), - CertificateEnum::CommitteeHotKeyRegistration(x) => x.has_script_credentials(), - CertificateEnum::CommitteeHotKeyDeregistration(x) => x.has_script_credentials(), + CertificateEnum::CommitteeHotAuth(x) => x.has_script_credentials(), + CertificateEnum::CommitteeColdResign(x) => x.has_script_credentials(), CertificateEnum::DrepDeregistration(x) => x.has_script_credentials(), CertificateEnum::DrepUpdate(x) => x.has_script_credentials(), _ => false, diff --git a/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs b/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs index 89c9447c..dff0f32a 100644 --- a/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs +++ b/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs @@ -13,14 +13,14 @@ use crate::*; JsonSchema, )] #[wasm_bindgen] -pub struct CommitteeHotKeyDeregistration { +pub struct CommitteeColdResign { pub(crate) committee_cold_key: Credential, } -impl_to_from!(CommitteeHotKeyDeregistration); +impl_to_from!(CommitteeColdResign); #[wasm_bindgen] -impl CommitteeHotKeyDeregistration { +impl CommitteeColdResign { pub fn committee_cold_key(&self) -> Credential { self.committee_cold_key.clone() } diff --git a/rust/src/protocol_types/certificates/committee_hot_key_registration.rs b/rust/src/protocol_types/certificates/committee_hot_key_registration.rs index c8751650..cfe9120f 100644 --- a/rust/src/protocol_types/certificates/committee_hot_key_registration.rs +++ b/rust/src/protocol_types/certificates/committee_hot_key_registration.rs @@ -13,15 +13,15 @@ use crate::*; JsonSchema, )] #[wasm_bindgen] -pub struct CommitteeHotKeyRegistration { +pub struct CommitteeHotAuth { pub(crate) committee_cold_key: Credential, pub(crate) committee_hot_key: Credential, } -impl_to_from!(CommitteeHotKeyRegistration); +impl_to_from!(CommitteeHotAuth); #[wasm_bindgen] -impl CommitteeHotKeyRegistration { +impl CommitteeHotAuth { pub fn committee_cold_key(&self) -> Credential { self.committee_cold_key.clone() } diff --git a/rust/src/serialization/certificates/certificate.rs b/rust/src/serialization/certificates/certificate.rs index 94cc2d99..10fbf296 100644 --- a/rust/src/serialization/certificates/certificate.rs +++ b/rust/src/serialization/certificates/certificate.rs @@ -16,8 +16,8 @@ impl cbor_event::se::Serialize for CertificateEnum { CertificateEnum::PoolRetirement(x) => x.serialize(serializer), CertificateEnum::GenesisKeyDelegation(x) => x.serialize(serializer), CertificateEnum::MoveInstantaneousRewardsCert(x) => x.serialize(serializer), - CertificateEnum::CommitteeHotKeyRegistration(x) => x.serialize(serializer), - CertificateEnum::CommitteeHotKeyDeregistration(x) => x.serialize(serializer), + CertificateEnum::CommitteeHotAuth(x) => x.serialize(serializer), + CertificateEnum::CommitteeColdResign(x) => x.serialize(serializer), CertificateEnum::DrepRegistration(x) => x.serialize(serializer), CertificateEnum::DrepDeregistration(x) => x.serialize(serializer), CertificateEnum::DrepUpdate(x) => x.serialize(serializer), @@ -109,14 +109,14 @@ impl DeserializeEmbeddedGroup for CertificateEnum { MoveInstantaneousRewardsCert::deserialize_as_embedded_group(raw, len)?, )) } - CertificateIndexNames::CommitteeHotKeyRegistration => { - Ok(CertificateEnum::CommitteeHotKeyRegistration( - CommitteeHotKeyRegistration::deserialize_as_embedded_group(raw, len)?, + CertificateIndexNames::CommitteeHotAuth => { + Ok(CertificateEnum::CommitteeHotAuth( + CommitteeHotAuth::deserialize_as_embedded_group(raw, len)?, )) } - CertificateIndexNames::CommitteeHotKeyDeregistration => { - Ok(CertificateEnum::CommitteeHotKeyDeregistration( - CommitteeHotKeyDeregistration::deserialize_as_embedded_group(raw, len)?, + CertificateIndexNames::CommitteeColdResign => { + Ok(CertificateEnum::CommitteeColdResign( + CommitteeColdResign::deserialize_as_embedded_group(raw, len)?, )) } CertificateIndexNames::DrepRegistration => Ok(CertificateEnum::DrepRegistration( diff --git a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs b/rust/src/serialization/certificates/committee_cold_resign.rs similarity index 67% rename from rust/src/serialization/certificates/committee_hot_key_deregistration.rs rename to rust/src/serialization/certificates/committee_cold_resign.rs index 4a1fea43..071fb138 100644 --- a/rust/src/serialization/certificates/committee_hot_key_deregistration.rs +++ b/rust/src/serialization/certificates/committee_cold_resign.rs @@ -5,35 +5,35 @@ use crate::serialization::utils::{ use crate::*; use num_traits::ToPrimitive; -impl cbor_event::se::Serialize for CommitteeHotKeyDeregistration { +impl cbor_event::se::Serialize for CommitteeColdResign { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(2))?; - let proposal_index = CertificateIndexNames::CommitteeHotKeyDeregistration.to_u64(); - serialize_and_check_index(serializer, proposal_index, "CommitteeHotKeyDeregistration")?; + let proposal_index = CertificateIndexNames::CommitteeColdResign.to_u64(); + serialize_and_check_index(serializer, proposal_index, "CommitteeColdResign")?; self.committee_cold_key.serialize(serializer)?; Ok(serializer) } } -impl_deserialize_for_wrapped_tuple!(CommitteeHotKeyDeregistration); +impl_deserialize_for_wrapped_tuple!(CommitteeColdResign); -impl DeserializeEmbeddedGroup for CommitteeHotKeyDeregistration { +impl DeserializeEmbeddedGroup for CommitteeColdResign { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { check_len(len, 2, "(cert_index, committee_cold_key)")?; - let cert_index = CertificateIndexNames::CommitteeHotKeyDeregistration.to_u64(); + let cert_index = CertificateIndexNames::CommitteeColdResign.to_u64(); deserialize_and_check_index(raw, cert_index, "cert_index")?; let committee_cold_key = Credential::deserialize(raw).map_err(|e| e.annotate("committee_cold_key"))?; - Ok(CommitteeHotKeyDeregistration { committee_cold_key }) + Ok(CommitteeColdResign { committee_cold_key }) } } diff --git a/rust/src/serialization/certificates/committee_hot_key_registration.rs b/rust/src/serialization/certificates/committee_hot_auth.rs similarity index 78% rename from rust/src/serialization/certificates/committee_hot_key_registration.rs rename to rust/src/serialization/certificates/committee_hot_auth.rs index ebfbf6bc..3e6a97b9 100644 --- a/rust/src/serialization/certificates/committee_hot_key_registration.rs +++ b/rust/src/serialization/certificates/committee_hot_auth.rs @@ -5,15 +5,15 @@ use crate::serialization::utils::{ use crate::*; use num_traits::ToPrimitive; -impl cbor_event::se::Serialize for CommitteeHotKeyRegistration { +impl cbor_event::se::Serialize for CommitteeHotAuth { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(3))?; - let proposal_index = CertificateIndexNames::CommitteeHotKeyRegistration.to_u64(); - serialize_and_check_index(serializer, proposal_index, "CommitteeHotKeyRegistration")?; + let proposal_index = CertificateIndexNames::CommitteeHotAuth.to_u64(); + serialize_and_check_index(serializer, proposal_index, "CommitteeHotAuth")?; self.committee_cold_key.serialize(serializer)?; self.committee_hot_key.serialize(serializer)?; @@ -21,9 +21,9 @@ impl cbor_event::se::Serialize for CommitteeHotKeyRegistration { } } -impl_deserialize_for_wrapped_tuple!(CommitteeHotKeyRegistration); +impl_deserialize_for_wrapped_tuple!(CommitteeHotAuth); -impl DeserializeEmbeddedGroup for CommitteeHotKeyRegistration { +impl DeserializeEmbeddedGroup for CommitteeHotAuth { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, @@ -34,7 +34,7 @@ impl DeserializeEmbeddedGroup for CommitteeHotKeyRegistration { "(cert_index, committee_cold_key, committee_hot_key)", )?; - let cert_index = CertificateIndexNames::CommitteeHotKeyRegistration.to_u64(); + let cert_index = CertificateIndexNames::CommitteeHotAuth.to_u64(); deserialize_and_check_index(raw, cert_index, "cert_index")?; let committee_cold_key = @@ -43,7 +43,7 @@ impl DeserializeEmbeddedGroup for CommitteeHotKeyRegistration { let committee_hot_key = Credential::deserialize(raw).map_err(|e| e.annotate("committee_hot_key"))?; - return Ok(CommitteeHotKeyRegistration { + return Ok(CommitteeHotAuth { committee_cold_key, committee_hot_key, }); diff --git a/rust/src/serialization/certificates/mod.rs b/rust/src/serialization/certificates/mod.rs index c27dff16..8878f390 100644 --- a/rust/src/serialization/certificates/mod.rs +++ b/rust/src/serialization/certificates/mod.rs @@ -1,7 +1,7 @@ mod certificate; mod certificates_collection; -mod committee_hot_key_deregistration; -mod committee_hot_key_registration; +mod committee_cold_resign; +mod committee_hot_auth; mod drep_deregistration; mod drep_registration; mod drep_update; diff --git a/rust/src/serialization/map_names/certificate_index_names.rs b/rust/src/serialization/map_names/certificate_index_names.rs index 64cc9a95..9a7eac38 100644 --- a/rust/src/serialization/map_names/certificate_index_names.rs +++ b/rust/src/serialization/map_names/certificate_index_names.rs @@ -14,8 +14,8 @@ pub(crate) enum CertificateIndexNames { StakeRegistrationAndDelegation = 11, VoteRegistrationAndDelegation = 12, StakeVoteRegistrationAndDelegation = 13, - CommitteeHotKeyRegistration = 14, - CommitteeHotKeyDeregistration = 15, + CommitteeHotAuth = 14, + CommitteeColdResign = 15, DrepRegistration = 16, DrepDeregistration = 17, DrepUpdate = 18, diff --git a/rust/src/tests/builders/certificates_builder.rs b/rust/src/tests/builders/certificates_builder.rs index 07345988..09dd81cb 100644 --- a/rust/src/tests/builders/certificates_builder.rs +++ b/rust/src/tests/builders/certificates_builder.rs @@ -13,11 +13,11 @@ fn certificatess_builder_deposit_test() { let drep_reg_deposit = 400u64; let committee_hot_key_dereg_cert = - CommitteeHotKeyDeregistration::new(&Credential::from_keyhash(&fake_key_hash(1))); + CommitteeColdResign::new(&Credential::from_keyhash(&fake_key_hash(1))); let committee_hot_key_dereg_cert_wrapped = Certificate::new_committee_hot_key_deregistration(&committee_hot_key_dereg_cert); - let committee_hot_key_reg_cert = CommitteeHotKeyRegistration::new( + let committee_hot_key_reg_cert = CommitteeHotAuth::new( &Credential::from_keyhash(&fake_key_hash(2)), &Credential::from_keyhash(&fake_key_hash(3)), ); @@ -187,11 +187,11 @@ fn certificatess_builder_no_deposit_test() { let drep_reg_deposit = 400u64; let committee_hot_key_dereg_cert = - CommitteeHotKeyDeregistration::new(&Credential::from_keyhash(&fake_key_hash(1))); + CommitteeColdResign::new(&Credential::from_keyhash(&fake_key_hash(1))); let committee_hot_key_dereg_cert_wrapped = Certificate::new_committee_hot_key_deregistration(&committee_hot_key_dereg_cert); - let committee_hot_key_reg_cert = CommitteeHotKeyRegistration::new( + let committee_hot_key_reg_cert = CommitteeHotAuth::new( &Credential::from_keyhash(&fake_key_hash(2)), &Credential::from_keyhash(&fake_key_hash(3)), ); @@ -341,11 +341,11 @@ fn certificatess_builder_req_signers_test() { let key_hash_33 = fake_key_hash(33); let committee_hot_key_dereg_cert = - CommitteeHotKeyDeregistration::new(&Credential::from_keyhash(&key_hash_1)); + CommitteeColdResign::new(&Credential::from_keyhash(&key_hash_1)); let committee_hot_key_dereg_cert_wrapped = Certificate::new_committee_hot_key_deregistration(&committee_hot_key_dereg_cert); - let committee_hot_key_reg_cert = CommitteeHotKeyRegistration::new( + let committee_hot_key_reg_cert = CommitteeHotAuth::new( &Credential::from_keyhash(&key_hash_2), &Credential::from_keyhash(&key_hash_3), ); diff --git a/rust/src/tests/protocol_types/certificates.rs b/rust/src/tests/protocol_types/certificates.rs index d249ad2d..85dd70c6 100644 --- a/rust/src/tests/protocol_types/certificates.rs +++ b/rust/src/tests/protocol_types/certificates.rs @@ -9,9 +9,9 @@ use crate::*; fn committee_hot_key_deregistration_setters_getters_test() { let cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); let cred_script_hash = Credential::from_scripthash(&fake_script_hash(2)); - let committee_hot_key_deregistration_1 = CommitteeHotKeyDeregistration::new(&cred_key_hash); + let committee_hot_key_deregistration_1 = CommitteeColdResign::new(&cred_key_hash); - let committee_hot_key_deregistration_2 = CommitteeHotKeyDeregistration::new(&cred_script_hash); + let committee_hot_key_deregistration_2 = CommitteeColdResign::new(&cred_script_hash); assert_eq!( committee_hot_key_deregistration_1.committee_cold_key(), @@ -30,7 +30,7 @@ fn committee_hot_key_registration_setters_getters_test() { let cold_cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); let hot_cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); let committee_hot_key_registration = - CommitteeHotKeyRegistration::new(&cold_cred_key_hash, &hot_cred_key_hash); + CommitteeHotAuth::new(&cold_cred_key_hash, &hot_cred_key_hash); assert_eq!( committee_hot_key_registration.committee_cold_key(), diff --git a/rust/src/tests/serialization/certificates.rs b/rust/src/tests/serialization/certificates.rs index ee4a1bdb..3a51aea6 100644 --- a/rust/src/tests/serialization/certificates.rs +++ b/rust/src/tests/serialization/certificates.rs @@ -35,9 +35,9 @@ macro_rules! to_from_test { #[test] fn committee_hot_key_deregistration_key_hash_ser_round_trip() { - let cert = CommitteeHotKeyDeregistration::new(&Credential::from_keyhash(&fake_key_hash(1))); + let cert = CommitteeColdResign::new(&Credential::from_keyhash(&fake_key_hash(1))); let cert_wrapped = Certificate::new_committee_hot_key_deregistration(&cert); - to_from_test!(CommitteeHotKeyDeregistration, cert, cert_wrapped); + to_from_test!(CommitteeColdResign, cert, cert_wrapped); assert_eq!( cert, cert_wrapped.as_committee_hot_key_deregistration().unwrap() @@ -47,9 +47,9 @@ fn committee_hot_key_deregistration_key_hash_ser_round_trip() { #[test] fn committee_hot_key_deregistration_script_hash_ser_round_trip() { let cert = - CommitteeHotKeyDeregistration::new(&Credential::from_scripthash(&fake_script_hash(1))); + CommitteeColdResign::new(&Credential::from_scripthash(&fake_script_hash(1))); let cert_wrapped = Certificate::new_committee_hot_key_deregistration(&cert); - to_from_test!(CommitteeHotKeyDeregistration, cert, cert_wrapped); + to_from_test!(CommitteeColdResign, cert, cert_wrapped); assert_eq!( cert, cert_wrapped.as_committee_hot_key_deregistration().unwrap() @@ -58,12 +58,12 @@ fn committee_hot_key_deregistration_script_hash_ser_round_trip() { #[test] fn committee_hot_key_registration_ser_round_trip() { - let cert = CommitteeHotKeyRegistration::new( + let cert = CommitteeHotAuth::new( &Credential::from_keyhash(&fake_key_hash(1)), &Credential::from_keyhash(&fake_key_hash(2)), ); let cert_wrapped = Certificate::new_committee_hot_key_registration(&cert); - to_from_test!(CommitteeHotKeyRegistration, cert, cert_wrapped); + to_from_test!(CommitteeHotAuth, cert, cert_wrapped); assert_eq!( cert, cert_wrapped.as_committee_hot_key_registration().unwrap() From 4e4456b454bf0659b56f61802ba0d33c0fab331c Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 19 Sep 2023 14:58:15 +0900 Subject: [PATCH 157/349] do not serialize empty withdrawals, certs, req signers, voting procedures, voting proposals, collateral inputs, ref inputs, mint --- rust/src/lib.rs | 24 +++++++ .../certificates/certificates_collection.rs | 6 ++ .../governance/proposals/voting_proposals.rs | 6 ++ .../governance/voting_procedures.rs | 6 ++ rust/src/serialization/transaction_body.rs | 65 +++++++++++-------- .../tests/serialization/transaction_body.rs | 59 +++++++++++++---- rust/src/utils.rs | 4 ++ 7 files changed, 130 insertions(+), 40 deletions(-) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 4f572fcd..211ab139 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -181,6 +181,12 @@ pub struct TransactionInputs(pub(crate) Vec); impl_to_from!(TransactionInputs); +impl NoneOrEmpty for TransactionInputs { + fn is_none_or_empty(&self) -> bool { + self.0.is_empty() + } +} + #[wasm_bindgen] impl TransactionInputs { pub fn new() -> Self { @@ -286,6 +292,12 @@ impl DataCost { pub type RequiredSigners = Ed25519KeyHashes; pub type RequiredSignersSet = BTreeSet; +impl NoneOrEmpty for RequiredSigners { + fn is_none_or_empty(&self) -> bool { + self.0.is_empty() + } +} + impl From<&Ed25519KeyHashes> for RequiredSignersSet { fn from(keys: &Ed25519KeyHashes) -> Self { keys.0.iter().fold(BTreeSet::new(), |mut set, k| { @@ -994,6 +1006,12 @@ pub struct Withdrawals(linked_hash_map::LinkedHashMap); impl_to_from!(Withdrawals); +impl NoneOrEmpty for Withdrawals { + fn is_none_or_empty(&self) -> bool { + self.0.is_empty() + } +} + #[wasm_bindgen] impl Withdrawals { pub fn new() -> Self { @@ -2579,6 +2597,12 @@ pub struct Mint(Vec<(PolicyID, MintAssets)>); impl_to_from!(Mint); +impl NoneOrEmpty for Mint { + fn is_none_or_empty(&self) -> bool { + self.0.is_empty() + } +} + #[wasm_bindgen] impl Mint { pub fn new() -> Self { diff --git a/rust/src/protocol_types/certificates/certificates_collection.rs b/rust/src/protocol_types/certificates/certificates_collection.rs index 1e2611dd..d02c4b19 100644 --- a/rust/src/protocol_types/certificates/certificates_collection.rs +++ b/rust/src/protocol_types/certificates/certificates_collection.rs @@ -8,6 +8,12 @@ pub struct Certificates(pub(crate) Vec); impl_to_from!(Certificates); +impl NoneOrEmpty for Certificates { + fn is_none_or_empty(&self) -> bool { + self.0.is_empty() + } +} + #[wasm_bindgen] impl Certificates { pub fn new() -> Self { diff --git a/rust/src/protocol_types/governance/proposals/voting_proposals.rs b/rust/src/protocol_types/governance/proposals/voting_proposals.rs index f7a7aa1d..1b94ccb6 100644 --- a/rust/src/protocol_types/governance/proposals/voting_proposals.rs +++ b/rust/src/protocol_types/governance/proposals/voting_proposals.rs @@ -17,6 +17,12 @@ pub struct VotingProposals(pub(crate) Vec); impl_to_from!(VotingProposals); +impl NoneOrEmpty for VotingProposals { + fn is_none_or_empty(&self) -> bool { + self.0.is_empty() + } +} + #[wasm_bindgen] impl VotingProposals { pub fn new() -> Self { diff --git a/rust/src/protocol_types/governance/voting_procedures.rs b/rust/src/protocol_types/governance/voting_procedures.rs index 44d9c00c..fa65c33f 100644 --- a/rust/src/protocol_types/governance/voting_procedures.rs +++ b/rust/src/protocol_types/governance/voting_procedures.rs @@ -47,6 +47,12 @@ pub struct VotingProcedures( impl_to_from!(VotingProcedures); +impl NoneOrEmpty for VotingProcedures { + fn is_none_or_empty(&self) -> bool { + self.0.is_empty() + } +} + #[wasm_bindgen] impl VotingProcedures { pub fn new() -> Self { diff --git a/rust/src/serialization/transaction_body.rs b/rust/src/serialization/transaction_body.rs index f22b56b6..ef4abecb 100644 --- a/rust/src/serialization/transaction_body.rs +++ b/rust/src/serialization/transaction_body.rs @@ -5,28 +5,23 @@ impl cbor_event::se::Serialize for TransactionBody { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - let has_mint = match &self.mint { - Some(mint) => mint.len() > 0, - None => false, - }; - serializer.write_map(cbor_event::Len::Len( 3 + opt64(&self.ttl) - + opt64(&self.certs) - + opt64(&self.withdrawals) + + opt64_non_empty(&self.certs) + + opt64_non_empty(&self.withdrawals) + opt64(&self.update) + opt64(&self.auxiliary_data_hash) + opt64(&self.validity_start_interval) - + has_mint as u64 + + opt64_non_empty(&self.mint) + opt64(&self.script_data_hash) - + opt64(&self.collateral) - + opt64(&self.required_signers) + + opt64_non_empty(&self.collateral) + + opt64_non_empty(&self.required_signers) + opt64(&self.network_id) + opt64(&self.collateral_return) + opt64(&self.total_collateral) - + opt64(&self.reference_inputs) - + opt64(&self.voting_procedures) - + opt64(&self.voting_proposals) + + opt64_non_empty(&self.reference_inputs) + + opt64_non_empty(&self.voting_procedures) + + opt64_non_empty(&self.voting_proposals) + opt64(&self.donation) + opt64(&self.current_treasury_value), ))?; @@ -41,12 +36,16 @@ impl cbor_event::se::Serialize for TransactionBody { field.serialize(serializer)?; } if let Some(field) = &self.certs { - serializer.write_unsigned_integer(4)?; - field.serialize(serializer)?; + if !field.is_none_or_empty() { + serializer.write_unsigned_integer(4)?; + field.serialize(serializer)?; + } } if let Some(field) = &self.withdrawals { - serializer.write_unsigned_integer(5)?; - field.serialize(serializer)?; + if !field.is_none_or_empty() { + serializer.write_unsigned_integer(5)?; + field.serialize(serializer)?; + } } if let Some(field) = &self.update { serializer.write_unsigned_integer(6)?; @@ -61,7 +60,7 @@ impl cbor_event::se::Serialize for TransactionBody { field.serialize(serializer)?; } if let Some(field) = &self.mint { - if has_mint { + if !field.is_none_or_empty() { serializer.write_unsigned_integer(9)?; field.serialize(serializer)?; } @@ -71,12 +70,16 @@ impl cbor_event::se::Serialize for TransactionBody { field.serialize(serializer)?; } if let Some(field) = &self.collateral { - serializer.write_unsigned_integer(13)?; - field.serialize(serializer)?; + if !field.is_none_or_empty() { + serializer.write_unsigned_integer(13)?; + field.serialize(serializer)?; + } } if let Some(field) = &self.required_signers { - serializer.write_unsigned_integer(14)?; - field.serialize(serializer)?; + if !field.is_none_or_empty() { + serializer.write_unsigned_integer(14)?; + field.serialize(serializer)?; + } } if let Some(field) = &self.network_id { serializer.write_unsigned_integer(15)?; @@ -91,16 +94,22 @@ impl cbor_event::se::Serialize for TransactionBody { field.serialize(serializer)?; } if let Some(field) = &self.reference_inputs { - serializer.write_unsigned_integer(18)?; - field.serialize(serializer)?; + if !field.is_none_or_empty() { + serializer.write_unsigned_integer(18)?; + field.serialize(serializer)?; + } } if let Some(field) = &self.voting_procedures { - serializer.write_unsigned_integer(19)?; - field.serialize(serializer)?; + if !field.is_none_or_empty() { + serializer.write_unsigned_integer(19)?; + field.serialize(serializer)?; + } } if let Some(field) = &self.voting_proposals { - serializer.write_unsigned_integer(20)?; - field.serialize(serializer)?; + if !field.is_none_or_empty() { + serializer.write_unsigned_integer(20)?; + field.serialize(serializer)?; + } } if let Some(field) = &self.current_treasury_value { serializer.write_unsigned_integer(21)?; diff --git a/rust/src/tests/serialization/transaction_body.rs b/rust/src/tests/serialization/transaction_body.rs index 18ff0735..bc3d929a 100644 --- a/rust/src/tests/serialization/transaction_body.rs +++ b/rust/src/tests/serialization/transaction_body.rs @@ -1,4 +1,7 @@ -use crate::fakes::{fake_asset_name, fake_auxiliary_data_hash, fake_base_address, fake_policy_id, fake_script_data_hash, fake_tx_input}; +use crate::fakes::{ + fake_asset_name, fake_auxiliary_data_hash, fake_base_address, fake_key_hash, fake_policy_id, + fake_script_data_hash, fake_tx_hash, fake_tx_input, +}; use crate::*; #[test] @@ -10,31 +13,63 @@ fn transaction_round_trip_test() { let fee = Coin::from(1_000_002u64); let mut body = TransactionBody::new_tx_body(&inputs, &outputs, &fee); let mut mint = Mint::new(); - let mint_asset = MintAssets::new_from_entry( - &fake_asset_name(4), - &Int::new(&to_bignum(1_000_003u64)), - ).unwrap(); + let mint_asset = + MintAssets::new_from_entry(&fake_asset_name(4), &Int::new(&to_bignum(1_000_003u64))) + .unwrap(); mint.insert(&fake_policy_id(3), &mint_asset); + let mut req_signers = RequiredSigners::new(); + req_signers.add(&fake_key_hash(5)); + + let mut collateral_inputs = TransactionInputs::new(); + collateral_inputs.add(&fake_tx_input(6)); + + let mut ref_inputs = TransactionInputs::new(); + ref_inputs.add(&fake_tx_input(7)); + + let mut certs = Certificates::new(); + let stake_registration = StakeRegistration::new(&Credential::from_keyhash(&fake_key_hash(8))); + certs.add(&Certificate::new_stake_registration(&stake_registration)); + + let mut withdrawals = Withdrawals::new(); + withdrawals.insert( + &RewardAddress::new( + NetworkInfo::testnet().network_id(), + &Credential::from_keyhash(&fake_key_hash(9)), + ), + &Coin::from(1_000_010u64), + ); + + let mut voting_procedures = VotingProcedures::new(); + let voter = Voter::new_drep(&Credential::from_keyhash(&fake_key_hash(1))); + let gov_action_id = GovernanceActionId::new((&fake_tx_hash(2)), 0); + let procedure = VotingProcedure::new(VoteKind::Abstain); + voting_procedures.insert(&voter, &gov_action_id, &procedure); + + let mut voting_proposals = VotingProposals::new(); + let info_proposal = InfoProposal::new(); + let proposal = VotingProposal::new_info_proposal(&info_proposal); + voting_proposals.add(&proposal); + body.set_ttl(&to_bignum(1_000_003u64)); - body.set_certs(&Certificates::new()); - body.set_withdrawals(&Withdrawals::new()); + body.set_certs(&certs); + body.set_withdrawals(&withdrawals); body.set_update(&Update::new(&ProposedProtocolParameterUpdates::new(), 1)); body.set_auxiliary_data_hash(&fake_auxiliary_data_hash(2)); body.set_validity_start_interval_bignum(&SlotBigNum::from(1_000_004u64)); body.set_mint(&mint); - body.set_reference_inputs(&TransactionInputs::new()); + body.set_reference_inputs(&ref_inputs); body.set_script_data_hash(&fake_script_data_hash(3)); - body.set_collateral(&TransactionInputs::new()); - body.set_required_signers(&RequiredSigners::new()); + body.set_collateral(&collateral_inputs); + body.set_required_signers(&req_signers); body.set_network_id(&NetworkId::testnet()); body.set_collateral_return(&TransactionOutput::new( &fake_base_address(4), &Value::new(&to_bignum(1_000_005u64)), )); body.set_total_collateral(&Coin::from(1_000_006u64)); - body.set_voting_procedures(&VotingProcedures::new()); - body.set_voting_proposals(&VotingProposals::new()); + body.set_voting_procedures(&voting_procedures); + body.set_voting_proposals(&voting_proposals); body.set_donation(&Coin::from(1_000_007u64)); body.set_current_treasury_value(&Coin::from(1_000_008u64)); diff --git a/rust/src/utils.rs b/rust/src/utils.rs index c15a08a4..1a66c40b 100644 --- a/rust/src/utils.rs +++ b/rust/src/utils.rs @@ -1654,6 +1654,10 @@ pub(crate) fn opt64(o: &Option) -> u64 { o.is_some() as u64 } +pub(crate) fn opt64_non_empty(o: &Option) -> u64 { + (!o.is_none_or_empty()) as u64 +} + pub struct ValueShortage { pub(crate) ada_shortage: Option<(Coin, Coin, Coin)>, pub(crate) asset_shortage: Vec<(PolicyID, AssetName, Coin, Coin)>, From a7bb4ca37424845770f81c5c80b93589f1d7a3ce Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 19 Sep 2023 15:12:20 +0900 Subject: [PATCH 158/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8e8451a0..559e0b7b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.5", + "version": "12.0.0-alpha.6", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 241af7b1..b6710b78 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.5", + "version": "12.0.0-alpha.6", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 073bd292..63af5818 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.5" +version = "12.0.0-alpha.6" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 6519f254..5bc78916 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -37,7 +37,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.5" +version = "12.0.0-alpha.6" dependencies = [ "bech32", "cbor_event", From 35549bd46773dcde97c58c4019ba8a9b543666bf Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 19 Sep 2023 15:14:10 +0900 Subject: [PATCH 159/349] remove unnecessary brackets --- rust/src/tests/serialization/transaction_body.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/src/tests/serialization/transaction_body.rs b/rust/src/tests/serialization/transaction_body.rs index bc3d929a..8b08aebc 100644 --- a/rust/src/tests/serialization/transaction_body.rs +++ b/rust/src/tests/serialization/transaction_body.rs @@ -42,7 +42,7 @@ fn transaction_round_trip_test() { let mut voting_procedures = VotingProcedures::new(); let voter = Voter::new_drep(&Credential::from_keyhash(&fake_key_hash(1))); - let gov_action_id = GovernanceActionId::new((&fake_tx_hash(2)), 0); + let gov_action_id = GovernanceActionId::new(&fake_tx_hash(2), 0); let procedure = VotingProcedure::new(VoteKind::Abstain); voting_procedures.insert(&voter, &gov_action_id, &procedure); From 4d7f878437c8216d240816912394a63588995476 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 19 Sep 2023 15:33:19 +0900 Subject: [PATCH 160/349] add auto delete to schema gen --- rust/json-gen/src/main.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rust/json-gen/src/main.rs b/rust/json-gen/src/main.rs index 8b2d6e49..acc1df2a 100644 --- a/rust/json-gen/src/main.rs +++ b/rust/json-gen/src/main.rs @@ -19,7 +19,19 @@ fn main() { let schema_path = Path::new(&"schemas"); if !schema_path.exists() { fs::create_dir(schema_path).unwrap(); + } else { + let files = schema_path.read_dir().unwrap(); + for file in files { + let file = file.unwrap(); + if file.file_type().unwrap().is_file() { + let filename = file.file_name().into_string().unwrap(); + if filename.ends_with(".json") { + fs::remove_file(file.path()).unwrap(); + } + } + } } + // lib.rs gen_json_schema!(UnitInterval); gen_json_schema!(Transaction); From 320d1c665185279eff4f280ce3421b33524bdcd0 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 19 Sep 2023 15:33:37 +0900 Subject: [PATCH 161/349] flow update --- rust/pkg/cardano_serialization_lib.js.flow | 264 ++++++++++----------- 1 file changed, 127 insertions(+), 137 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index cd7de208..f650c1b8 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -371,8 +371,8 @@ declare export var CertificateKind: {| +PoolRetirement: 4, // 4 +GenesisKeyDelegation: 5, // 5 +MoveInstantaneousRewardsCert: 6, // 6 - +CommitteeHotKeyRegistration: 7, // 7 - +CommitteeHotKeyDeregistration: 8, // 8 + +CommitteeHotAuth: 7, // 7 + +CommitteeColdResign: 8, // 8 +DrepDeregistration: 9, // 9 +DrepRegistration: 10, // 10 +DrepUpdate: 11, // 11 @@ -391,7 +391,7 @@ declare export var VotingProposalKind: {| +HardForkInitiationProposal: 1, // 1 +TreasuryWithdrawalsProposal: 2, // 2 +NoConfidenceProposal: 3, // 3 - +NewCommitteeProposal: 4, // 4 + +UpdateCommitteeProposal: 4, // 4 +NewConstitutionProposal: 5, // 5 +InfoProposal: 6, // 6 |}; @@ -1840,19 +1840,19 @@ declare export class Certificate { ): Certificate; /** - * @param {CommitteeHotKeyRegistration} committee_hot_key_registration + * @param {CommitteeHotAuth} committee_hot_key_registration * @returns {Certificate} */ static new_committee_hot_key_registration( - committee_hot_key_registration: CommitteeHotKeyRegistration + committee_hot_key_registration: CommitteeHotAuth ): Certificate; /** - * @param {CommitteeHotKeyDeregistration} committee_hot_key_deregistration + * @param {CommitteeColdResign} committee_hot_key_deregistration * @returns {Certificate} */ static new_committee_hot_key_deregistration( - committee_hot_key_deregistration: CommitteeHotKeyDeregistration + committee_hot_key_deregistration: CommitteeColdResign ): Certificate; /** @@ -1956,14 +1956,14 @@ declare export class Certificate { as_move_instantaneous_rewards_cert(): MoveInstantaneousRewardsCert | void; /** - * @returns {CommitteeHotKeyRegistration | void} + * @returns {CommitteeHotAuth | void} */ - as_committee_hot_key_registration(): CommitteeHotKeyRegistration | void; + as_committee_hot_key_registration(): CommitteeHotAuth | void; /** - * @returns {CommitteeHotKeyDeregistration | void} + * @returns {CommitteeColdResign | void} */ - as_committee_hot_key_deregistration(): CommitteeHotKeyDeregistration | void; + as_committee_hot_key_deregistration(): CommitteeColdResign | void; /** * @returns {DrepDeregistration | void} @@ -2216,7 +2216,7 @@ declare export class Committee { } /** */ -declare export class CommitteeHotKeyDeregistration { +declare export class CommitteeColdResign { free(): void; /** @@ -2226,9 +2226,9 @@ declare export class CommitteeHotKeyDeregistration { /** * @param {Uint8Array} bytes - * @returns {CommitteeHotKeyDeregistration} + * @returns {CommitteeColdResign} */ - static from_bytes(bytes: Uint8Array): CommitteeHotKeyDeregistration; + static from_bytes(bytes: Uint8Array): CommitteeColdResign; /** * @returns {string} @@ -2237,9 +2237,9 @@ declare export class CommitteeHotKeyDeregistration { /** * @param {string} hex_str - * @returns {CommitteeHotKeyDeregistration} + * @returns {CommitteeColdResign} */ - static from_hex(hex_str: string): CommitteeHotKeyDeregistration; + static from_hex(hex_str: string): CommitteeColdResign; /** * @returns {string} @@ -2247,15 +2247,15 @@ declare export class CommitteeHotKeyDeregistration { to_json(): string; /** - * @returns {CommitteeHotKeyDeregistrationJSON} + * @returns {CommitteeColdResignJSON} */ - to_js_value(): CommitteeHotKeyDeregistrationJSON; + to_js_value(): CommitteeColdResignJSON; /** * @param {string} json - * @returns {CommitteeHotKeyDeregistration} + * @returns {CommitteeColdResign} */ - static from_json(json: string): CommitteeHotKeyDeregistration; + static from_json(json: string): CommitteeColdResign; /** * @returns {Credential} @@ -2264,9 +2264,9 @@ declare export class CommitteeHotKeyDeregistration { /** * @param {Credential} committee_cold_key - * @returns {CommitteeHotKeyDeregistration} + * @returns {CommitteeColdResign} */ - static new(committee_cold_key: Credential): CommitteeHotKeyDeregistration; + static new(committee_cold_key: Credential): CommitteeColdResign; /** * @returns {boolean} @@ -2275,7 +2275,7 @@ declare export class CommitteeHotKeyDeregistration { } /** */ -declare export class CommitteeHotKeyRegistration { +declare export class CommitteeHotAuth { free(): void; /** @@ -2285,9 +2285,9 @@ declare export class CommitteeHotKeyRegistration { /** * @param {Uint8Array} bytes - * @returns {CommitteeHotKeyRegistration} + * @returns {CommitteeHotAuth} */ - static from_bytes(bytes: Uint8Array): CommitteeHotKeyRegistration; + static from_bytes(bytes: Uint8Array): CommitteeHotAuth; /** * @returns {string} @@ -2296,9 +2296,9 @@ declare export class CommitteeHotKeyRegistration { /** * @param {string} hex_str - * @returns {CommitteeHotKeyRegistration} + * @returns {CommitteeHotAuth} */ - static from_hex(hex_str: string): CommitteeHotKeyRegistration; + static from_hex(hex_str: string): CommitteeHotAuth; /** * @returns {string} @@ -2306,15 +2306,15 @@ declare export class CommitteeHotKeyRegistration { to_json(): string; /** - * @returns {CommitteeHotKeyRegistrationJSON} + * @returns {CommitteeHotAuthJSON} */ - to_js_value(): CommitteeHotKeyRegistrationJSON; + to_js_value(): CommitteeHotAuthJSON; /** * @param {string} json - * @returns {CommitteeHotKeyRegistration} + * @returns {CommitteeHotAuth} */ - static from_json(json: string): CommitteeHotKeyRegistration; + static from_json(json: string): CommitteeHotAuth; /** * @returns {Credential} @@ -2329,12 +2329,12 @@ declare export class CommitteeHotKeyRegistration { /** * @param {Credential} committee_cold_key * @param {Credential} committee_hot_key - * @returns {CommitteeHotKeyRegistration} + * @returns {CommitteeHotAuth} */ static new( committee_cold_key: Credential, committee_hot_key: Credential - ): CommitteeHotKeyRegistration; + ): CommitteeHotAuth; /** * @returns {boolean} @@ -6003,86 +6003,6 @@ declare export class NetworkInfo { */ static mainnet(): NetworkInfo; } -/** - */ -declare export class NewCommitteeProposal { - free(): void; - - /** - * @returns {Uint8Array} - */ - to_bytes(): Uint8Array; - - /** - * @param {Uint8Array} bytes - * @returns {NewCommitteeProposal} - */ - static from_bytes(bytes: Uint8Array): NewCommitteeProposal; - - /** - * @returns {string} - */ - to_hex(): string; - - /** - * @param {string} hex_str - * @returns {NewCommitteeProposal} - */ - static from_hex(hex_str: string): NewCommitteeProposal; - - /** - * @returns {string} - */ - to_json(): string; - - /** - * @returns {NewCommitteeProposalJSON} - */ - to_js_value(): NewCommitteeProposalJSON; - - /** - * @param {string} json - * @returns {NewCommitteeProposal} - */ - static from_json(json: string): NewCommitteeProposal; - - /** - * @returns {GovernanceActionId | void} - */ - gov_action_id(): GovernanceActionId | void; - - /** - * @returns {Committee} - */ - committee(): Committee; - - /** - * @returns {Credentials} - */ - members_to_remove(): Credentials; - - /** - * @param {Committee} committee - * @param {Credentials} members_to_remove - * @returns {NewCommitteeProposal} - */ - static new( - committee: Committee, - members_to_remove: Credentials - ): NewCommitteeProposal; - - /** - * @param {GovernanceActionId} gov_action_id - * @param {Committee} committee - * @param {Credentials} members_to_remove - * @returns {NewCommitteeProposal} - */ - static new_with_action_id( - gov_action_id: GovernanceActionId, - committee: Committee, - members_to_remove: Credentials - ): NewCommitteeProposal; -} /** */ declare export class NewConstitutionProposal { @@ -12278,6 +12198,86 @@ declare export class Update { epoch: number ): Update; } +/** + */ +declare export class UpdateCommitteeProposal { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {UpdateCommitteeProposal} + */ + static from_bytes(bytes: Uint8Array): UpdateCommitteeProposal; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {UpdateCommitteeProposal} + */ + static from_hex(hex_str: string): UpdateCommitteeProposal; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {UpdateCommitteeProposalJSON} + */ + to_js_value(): UpdateCommitteeProposalJSON; + + /** + * @param {string} json + * @returns {UpdateCommitteeProposal} + */ + static from_json(json: string): UpdateCommitteeProposal; + + /** + * @returns {GovernanceActionId | void} + */ + gov_action_id(): GovernanceActionId | void; + + /** + * @returns {Committee} + */ + committee(): Committee; + + /** + * @returns {Credentials} + */ + members_to_remove(): Credentials; + + /** + * @param {Committee} committee + * @param {Credentials} members_to_remove + * @returns {UpdateCommitteeProposal} + */ + static new( + committee: Committee, + members_to_remove: Credentials + ): UpdateCommitteeProposal; + + /** + * @param {GovernanceActionId} gov_action_id + * @param {Committee} committee + * @param {Credentials} members_to_remove + * @returns {UpdateCommitteeProposal} + */ + static new_with_action_id( + gov_action_id: GovernanceActionId, + committee: Committee, + members_to_remove: Credentials + ): UpdateCommitteeProposal; +} /** */ declare export class VRFCert { @@ -13304,11 +13304,11 @@ declare export class VotingProposal { ): VotingProposal; /** - * @param {NewCommitteeProposal} new_committee_proposal + * @param {UpdateCommitteeProposal} new_committee_proposal * @returns {VotingProposal} */ static new_new_committee_proposal( - new_committee_proposal: NewCommitteeProposal + new_committee_proposal: UpdateCommitteeProposal ): VotingProposal; /** @@ -13351,9 +13351,9 @@ declare export class VotingProposal { as_no_confidence_proposal(): NoConfidenceProposal | void; /** - * @returns {NewCommitteeProposal | void} + * @returns {UpdateCommitteeProposal | void} */ - as_new_committee_proposal(): NewCommitteeProposal | void; + as_new_committee_proposal(): UpdateCommitteeProposal | void; /** * @returns {NewConstitutionProposal | void} @@ -13685,11 +13685,11 @@ export type CertificateEnumJSON = ... } | { - CommitteeHotKeyRegistrationJSON: CommitteeHotKeyRegistration, + CommitteeHotAuthJSON: CommitteeHotAuth, ... } | { - CommitteeHotKeyDeregistrationJSON: CommitteeHotKeyDeregistration, + CommitteeColdResignJSON: CommitteeColdResign, ... } | { @@ -13729,10 +13729,10 @@ export interface CommitteeJSON { members: CommitteeMember[]; quorum_threshold: UnitIntervalJSON; } -export interface CommitteeHotKeyDeregistrationJSON { +export interface CommitteeColdResignJSON { committee_cold_key: CredTypeJSON; } -export interface CommitteeHotKeyRegistrationJSON { +export interface CommitteeHotAuthJSON { committee_cold_key: CredTypeJSON; committee_hot_key: CredTypeJSON; } @@ -13939,11 +13939,6 @@ export type NativeScript1JSON = export type NativeScriptsJSON = NativeScriptJSON[]; export type NetworkIdJSON = NetworkIdKindJSON; export type NetworkIdKindJSON = "Testnet" | "Mainnet"; -export interface NewCommitteeProposalJSON { - committee: CommitteeJSON; - gov_action_id?: GovernanceActionIdJSON | null; - members_to_remove: CredTypeJSON[]; -} export interface NewConstitutionProposalJSON { constitution: ConstitutionJSON; gov_action_id?: GovernanceActionIdJSON | null; @@ -14144,16 +14139,6 @@ export interface StakeAndVoteDelegationJSON { pool_keyhash: string; stake_credential: CredTypeJSON; } -export type StakeCredTypeJSON = - | { - Key: string, - ... - } - | { - Script: string, - ... - }; -export type StakeCredentialsJSON = CredentialJSON[]; export interface StakeDelegationJSON { pool_keyhash: string; stake_credential: CredTypeJSON; @@ -14260,6 +14245,11 @@ export interface UpdateJSON { [k: string]: ProtocolParamUpdateJSON, }; } +export interface UpdateCommitteeProposalJSON { + committee: CommitteeJSON; + gov_action_id?: GovernanceActionIdJSON | null; + members_to_remove: CredTypeJSON[]; +} export interface VRFCertJSON { output: number[]; proof: number[]; @@ -14323,7 +14313,7 @@ export type VotingProposalEnumJSON = ... } | { - NewCommitteeProposalJSON: NewCommitteeProposal, + UpdateCommitteeProposalJSON: UpdateCommitteeProposal, ... } | { From 112d980059bf58631d22ea209fb579db078d9922 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 24 Sep 2023 00:25:28 +0900 Subject: [PATCH 162/349] update schema to ts gen --- package-lock.json | 172 ++++++++++++++++------------------------- package.json | 2 +- scripts/run-json2ts.js | 133 ++++++++++++++++++++----------- 3 files changed, 158 insertions(+), 149 deletions(-) diff --git a/package-lock.json b/package-lock.json index 559e0b7b..32a44dec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,18 +4,6 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@apidevtools/json-schema-ref-parser": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz", - "integrity": "sha512-GBD2Le9w2+lVFoc4vswGI/TjkNIZSVp7+9xPf+X3uidBfWnAeUWmquteSyt0+VCrhNMWj/FTABISQrD3Z/YA+w==", - "dev": true, - "requires": { - "@jsdevtools/ono": "^7.1.3", - "@types/json-schema": "^7.0.6", - "call-me-maybe": "^1.0.1", - "js-yaml": "^4.1.0" - } - }, "@babel/code-frame": { "version": "7.10.3", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.3.tgz", @@ -55,6 +43,18 @@ } } }, + "@bcherny/json-schema-ref-parser": { + "version": "10.0.5-fork", + "resolved": "https://registry.npmjs.org/@bcherny/json-schema-ref-parser/-/json-schema-ref-parser-10.0.5-fork.tgz", + "integrity": "sha512-E/jKbPoca1tfUPj3iSbitDZTGnq6FUFjkH6L8U2oDwSuwK1WhnnVtCG7oFOTg/DDnyoXbQYUiUiGOibHqaGVnw==", + "dev": true, + "requires": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.6", + "call-me-maybe": "^1.0.1", + "js-yaml": "^4.1.0" + } + }, "@jsdevtools/ono": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", @@ -78,27 +78,27 @@ } }, "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", + "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==", "dev": true }, "@types/lodash": { - "version": "4.14.178", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz", - "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==", + "version": "4.14.198", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.198.tgz", + "integrity": "sha512-trNJ/vtMZYMLhfN45uLq4ShQSw0/S7xCTLLVM+WM1rmFpba/VS42jVUgaO3w/NOLiWR/09lnYk0yMaA/atdIsg==", "dev": true }, "@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", "dev": true }, "@types/node": { - "version": "17.0.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.8.tgz", - "integrity": "sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg==", + "version": "20.6.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.2.tgz", + "integrity": "sha512-Y+/1vGBHV/cYk6OI1Na/LHzwnlNCAfU3ZNGrc1LdRe/LAIbdDPTTv/HU3M7yXN448aTVDq3eKRm2cg7iKLb8gw==", "dev": true }, "@types/parse-json": { @@ -108,9 +108,9 @@ "dev": true }, "@types/prettier": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.2.tgz", - "integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==", + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", "dev": true }, "ansi-styles": { @@ -151,9 +151,9 @@ } }, "call-me-maybe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha512-wCyFsDQkKPwwF8BDwOiWNx/9K45L/hvggQiDbve+viMNMQnWhrlYIuBk09offfwCRtCO9P6XwUttufzU11WCVw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", "dev": true }, "callsites": { @@ -221,13 +221,13 @@ "dev": true }, "cli-color": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.1.tgz", - "integrity": "sha512-eBbxZF6fqPUNnf7CLAFOersUnyYzv83tHFLSlts+OAHsNendaqv2tHCq+/MO+b3Y+9JeoUlIvobyxG/Z8GNeOg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.3.tgz", + "integrity": "sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==", "dev": true, "requires": { "d": "^1.0.1", - "es5-ext": "^0.10.53", + "es5-ext": "^0.10.61", "es6-iterator": "^2.0.3", "memoizee": "^0.4.15", "timers-ext": "^0.1.7" @@ -299,14 +299,14 @@ } }, "es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", "dev": true, "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" } }, "es6-iterator": { @@ -359,18 +359,18 @@ } }, "ext": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", - "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", "dev": true, "requires": { - "type": "^2.5.0" + "type": "^2.7.2" }, "dependencies": { "type": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", - "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", "dev": true } } @@ -472,12 +472,12 @@ } }, "glob-promise": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/glob-promise/-/glob-promise-3.4.0.tgz", - "integrity": "sha512-q08RJ6O+eJn+dVanerAndJwIcumgbDdYiUT7zFQl3Wm1xD6fBKtah7H8ZJChj4wP+8C+QfeVy8xautR7rdmKEw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/glob-promise/-/glob-promise-4.2.2.tgz", + "integrity": "sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw==", "dev": true, "requires": { - "@types/glob": "*" + "@types/glob": "^7.1.3" } }, "has": { @@ -602,58 +602,28 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, - "json-schema-ref-parser": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz", - "integrity": "sha512-qcP2lmGy+JUoQJ4DOQeLaZDqH9qSkeGCK3suKWxJXS82dg728Mn3j97azDMaOUmJAN4uCq91LdPx4K7E8F1a7Q==", - "dev": true, - "requires": { - "@apidevtools/json-schema-ref-parser": "9.0.9" - } - }, "json-schema-to-typescript": { - "version": "10.1.5", - "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-10.1.5.tgz", - "integrity": "sha512-X8bNNksfCQo6LhEuqNxmZr4eZpPjXZajmimciuk8eWXzZlif9Brq7WuMGD/SOhBKcRKP2SGVDNZbC28WQqx9Rg==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-13.1.1.tgz", + "integrity": "sha512-F3CYhtA7F3yPbb8vF7sFchk/2dnr1/yTKf8RcvoNpjnh67ZS/ZMH1ElLt5KHAtf2/bymiejLQQszszPWEeTdSw==", "dev": true, "requires": { - "@types/json-schema": "^7.0.6", - "@types/lodash": "^4.14.168", - "@types/prettier": "^2.1.5", - "cli-color": "^2.0.0", + "@bcherny/json-schema-ref-parser": "10.0.5-fork", + "@types/json-schema": "^7.0.11", + "@types/lodash": "^4.14.182", + "@types/prettier": "^2.6.1", + "cli-color": "^2.0.2", "get-stdin": "^8.0.0", "glob": "^7.1.6", - "glob-promise": "^3.4.0", - "is-glob": "^4.0.1", - "json-schema-ref-parser": "^9.0.6", - "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.20", - "minimist": "^1.2.5", + "glob-promise": "^4.2.2", + "is-glob": "^4.0.3", + "lodash": "^4.17.21", + "minimist": "^1.2.6", "mkdirp": "^1.0.4", "mz": "^2.7.0", - "prettier": "^2.2.0" - }, - "dependencies": { - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "prettier": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", - "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", - "dev": true - } + "prettier": "^2.6.2" } }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, "lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", @@ -689,14 +659,6 @@ "lru-queue": "^0.1.0", "next-tick": "^1.1.0", "timers-ext": "^0.1.7" - }, - "dependencies": { - "next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - } } }, "minimatch": { @@ -732,9 +694,9 @@ } }, "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", "dev": true }, "object-assign": { diff --git a/package.json b/package.json index b6710b78..816158ea 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "devDependencies": { "flowgen": "1.21.0", "husky": "4.2.5", - "json-schema-to-typescript": "^10.1.5", + "json-schema-to-typescript": "^13.1.1", "rimraf": "3.0.2" } } diff --git a/scripts/run-json2ts.js b/scripts/run-json2ts.js index f97fa288..4b94ea07 100644 --- a/scripts/run-json2ts.js +++ b/scripts/run-json2ts.js @@ -5,23 +5,92 @@ const path = require('path'); const schemasDir = path.join('rust', 'json-gen', 'schemas'); const schemaFiles = fs.readdirSync(schemasDir).filter(file => path.extname(file) === '.json'); -function replaceRef(obj) { - if (obj['$ref'] != null && typeof obj['$ref'] === 'string' && obj['$ref'].startsWith('#/definitions/')) { - obj['$ref'] = obj['$ref'].replace(/^(#\/definitions\/)/, '') + '.json';//`file:`) + '.json#'; - console.log(`replacing: ${obj['$ref']}`); +function renameSchema(obj, visited) { + if (visited != null && visited.has(obj)) { + return; } + visited = visited || new Set(); + visited.add(obj); + if (obj.hasOwnProperty("title")) { + if (!obj.title.endsWith("JSON")) { + obj.title = obj.title + "JSON"; + } + } + renameDefinitions(obj, visited); + renameRef(obj); + goOverProperties(obj, visited); + goOverMultiType(obj, visited); +} + +function renameRef(obj) { + if (obj.hasOwnProperty("$ref")) { + const ref = obj["$ref"]; + if (!ref.endsWith("JSON")) { + obj["$ref"] = ref + "JSON"; + } + } } -function replaceRefs(node) { - Object.entries(node).forEach(([k, v]) => { - if (typeof v === 'object') { - replaceRef(v); - replaceRefs(v); - /*if (v.additionalProperties != null) { - replaceRef(v.additionalProperties); - }*/ +function renameDefinitions(obj, visited) { + if (obj.hasOwnProperty("definitions")) { + for (const [key, value] of Object.entries(obj.definitions)) { + if (!key.endsWith("JSON") && !key.startsWith("__")) { + renameObjectKey(obj.definitions, key, key + "JSON"); + renameSchema(value, visited) + } + visited.add(value); } - }); + } +} + +function goOverProperties(obj, visited) { + if (obj.hasOwnProperty("properties")) { + for (const [key, value] of Object.entries(obj.properties)) { + renameSchema(value, visited); + } + } + if (obj.hasOwnProperty("items")) { + if (Array.isArray(obj.items)) { + for (const [key, value] of Object.entries(obj.items)) { + renameSchema(value, visited); + } + } else if (typeof obj.items === "object") { + renameSchema(obj.items, visited); + } + } + + if (obj.hasOwnProperty("additionalProperties")) { + if (Array.isArray(obj.additionalProperties)) { + for (const [key, value] of Object.entries(obj.additionalProperties)) { + renameSchema(value, visited); + } + } else if (typeof obj.additionalProperties === "object") { + renameSchema(obj.additionalProperties, visited); + } + + } +} + +function isMultiType(obj) { + return obj.hasOwnProperty("anyOf") || obj.hasOwnProperty("oneOf") || obj.hasOwnProperty("allOf"); +} + +function goOverMultiType(obj, visited) { + if (isMultiType(obj)) { + for (const [key, value] of Object.entries(obj)) { + if (key === "anyOf" || key === "oneOf" || key === "allOf") { + for (const [index, type] of Object.entries(value)) { + renameSchema(type, visited); + } + } + } + } +} + +function renameObjectKey(obj, oldKey, newKey) { + if (obj.hasOwnProperty(oldKey)) { + delete Object.assign(obj, {[newKey]: obj[oldKey]})[oldKey]; + } } Promise.all(schemaFiles.map(schemaFile => { @@ -38,31 +107,11 @@ Promise.all(schemaFiles.map(schemaFile => { schemaObj.additionalProperties = false; } - // NOTE: Due to infinite recursion in recursive types (e.g. NativeScript) - // possibly due to a bug in the schema->ts lib, we instead just remove the - // duplicates after the fact. Self-referencing is confirmed not supported, - // but there has been mentions in those github issues of support for other - // recursive types correctly. - // - // It's possibly related to directly using "Foo.json" in replaceRefs() - // but I was not able to get this working using the $ref external file: syntax - // that seemed to be valid online. - // We can also take advantage of the post-removal to easily remove 2 weird unused - // outputs that shouldn't have been generated to begin with (String and MapOf_*) - - /* - // we need to make all references by external so we don't duplicate declarations - if (schemaObj.definitions != null) { - // eliminate in-file definitions - schemaObj.definitions = []; - // change all refs from local to external - replaceRefs(schemaObj); - } - */ - - //console.log(`NEW: ${JSON.stringify(schemaObj)}\n\n\n\n\n`); + renameSchema(schemaObj, null); + // console.log(`NEW: ${JSON.stringify(schemaObj)}\n\n\n\n\n`); return json2ts.compile(schemaObj, schemaFile, { - declareExternallyReferenced: false, + declareExternallyReferenced: true, + additionalProperties: false, cwd: schemasDir,//path.join(process.cwd(), schemasDir), bannerComment: '' }).catch(e => { console.error(`${schemaFile}: ${e}`); }); @@ -70,6 +119,10 @@ Promise.all(schemaFiles.map(schemaFile => { })).then(tsDefs => { fs.mkdirSync(path.join('rust', 'json-gen', 'output'), { recursive: true }); const defs = tsDefs.join('').split(/\r?\n/); + //replace all auto-deduped defs with the first one + for(let i = 0; i < defs.length; ++i) { + defs[i] = defs[i].replace(/JSON\d+/, 'JSON'); + } let dedupedDefs = []; let start = null; let added = new Set(); @@ -99,12 +152,6 @@ Promise.all(schemaFiles.map(schemaFile => { } } addDef(defs.length); - // prepend 'JSON' to all identifiers here so they don't conflict with main .ts types - for (let i = 0; i < dedupedDefs.length; ++i) { - for (let id of added) { - dedupedDefs[i] = dedupedDefs[i].replace(new RegExp(`\\b${id}\\b`), id + 'JSON'); - } - } return fs.writeFileSync(path.join('rust', 'json-gen', 'output', 'json-types.d.ts'), dedupedDefs.join('\n')); }); From 46689dc36a5d873c6e6972667b42768afaf5788d Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 24 Sep 2023 00:26:00 +0900 Subject: [PATCH 163/349] fix MIR schema name --- .../certificates/move_instantaneous_rewards_cert.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs b/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs index f43f0236..78cc4df7 100644 --- a/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs +++ b/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs @@ -128,7 +128,7 @@ impl MIRToStakeCredentials { serde::Deserialize, JsonSchema, )] -struct StakeToCoinJson { +struct StakeToCoin { stake_cred: Credential, amount: DeltaCoin, } @@ -141,11 +141,11 @@ impl serde::Serialize for MIRToStakeCredentials { let vec = self .rewards .iter() - .map(|(k, v)| StakeToCoinJson { + .map(|(k, v)| StakeToCoin { stake_cred: k.clone(), amount: v.clone(), }) - .collect::>(); + .collect::>(); vec.serialize(serializer) } } @@ -155,7 +155,7 @@ impl<'de> serde::de::Deserialize<'de> for MIRToStakeCredentials { where D: serde::de::Deserializer<'de>, { - let map = Vec::::deserialize(deserializer)? + let map = Vec::::deserialize(deserializer)? .into_iter() .map(|v| (v.stake_cred, v.amount)); @@ -170,10 +170,10 @@ impl JsonSchema for MIRToStakeCredentials { String::from("MIRToStakeCredentials") } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - Vec::::json_schema(gen) + Vec::::json_schema(gen) } fn is_referenceable() -> bool { - Vec::::is_referenceable() + Vec::::is_referenceable() } } From 06a18c38ace18c4214325ca6a02262eadc1316c5 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 24 Sep 2023 00:26:48 +0900 Subject: [PATCH 164/349] flow update --- rust/pkg/cardano_serialization_lib.js.flow | 1048 ++++++++++++-------- 1 file changed, 620 insertions(+), 428 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index f650c1b8..226dbd27 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -13613,6 +13613,7 @@ declare export class WithdrawalsBuilder { build(): Withdrawals; } export type AddressJSON = string; +export type URLJSON = string; export interface AnchorJSON { anchor_data_hash: string; anchor_url: URLJSON; @@ -13623,6 +13624,33 @@ export type AssetNamesJSON = string[]; export interface AssetsJSON { [k: string]: string; } +export type NativeScriptJSON = + | { + ScriptPubkey: ScriptPubkeyJSON, + ... + } + | { + ScriptAll: ScriptAllJSON, + ... + } + | { + ScriptAny: ScriptAnyJSON, + ... + } + | { + ScriptNOfK: ScriptNOfKJSON, + ... + } + | { + TimelockStart: TimelockStartJSON, + ... + } + | { + TimelockExpiry: TimelockExpiryJSON, + ... + }; +export type NativeScriptsJSON = NativeScriptJSON[]; +export type PlutusScriptsJSON = string[]; export interface AuxiliaryDataJSON { metadata?: { [k: string]: string, @@ -13631,235 +13659,146 @@ export interface AuxiliaryDataJSON { plutus_scripts?: PlutusScriptsJSON | null; prefer_alonzo_format: boolean; } +export interface ScriptPubkeyJSON { + addr_keyhash: string; +} +export interface ScriptAllJSON { + native_scripts: NativeScriptsJSON; +} +export interface ScriptAnyJSON { + native_scripts: NativeScriptsJSON; +} +export interface ScriptNOfKJSON { + n: number; + native_scripts: NativeScriptsJSON; +} +export interface TimelockStartJSON { + slot: string; +} +export interface TimelockExpiryJSON { + slot: string; +} export type AuxiliaryDataHashJSON = string; export interface AuxiliaryDataSetJSON { [k: string]: AuxiliaryDataJSON; } export type BigIntJSON = string; export type BigNumJSON = string; -export interface BlockJSON { - auxiliary_data_set: { - [k: string]: AuxiliaryDataJSON, - }; - header: HeaderJSON; - invalid_transactions: number[]; - transaction_bodies: TransactionBodiesJSON; - transaction_witness_sets: TransactionWitnessSetsJSON; -} -export type BlockHashJSON = string; -export interface BootstrapWitnessJSON { - attributes: number[]; - chain_code: number[]; - signature: string; - vkey: VkeyJSON; -} -export type BootstrapWitnessesJSON = BootstrapWitnessJSON[]; -export type CertificateJSON = CertificateEnumJSON; -export type CertificateEnumJSON = +export type VkeyJSON = string; +export type HeaderLeaderCertEnumJSON = | { - StakeRegistrationJSON: StakeRegistration, + /** + * @minItems 2 + * @maxItems 2 + */ + NonceAndLeader: [VRFCertJSON, VRFCertJSON], ... } | { - StakeDeregistrationJSON: StakeDeregistration, + VrfResult: VRFCertJSON, ... - } + }; +export type CertificateJSON = | { - StakeDelegationJSON: StakeDelegation, + StakeRegistration: StakeRegistrationJSON, ... } | { - PoolRegistrationJSON: PoolRegistration, + StakeDeregistration: StakeDeregistrationJSON, ... } | { - PoolRetirementJSON: PoolRetirement, + StakeDelegation: StakeDelegationJSON, ... } | { - GenesisKeyDelegationJSON: GenesisKeyDelegation, + PoolRegistration: PoolRegistrationJSON, ... } | { - MoveInstantaneousRewardsCertJSON: MoveInstantaneousRewardsCert, + PoolRetirement: PoolRetirementJSON, ... } | { - CommitteeHotAuthJSON: CommitteeHotAuth, + GenesisKeyDelegation: GenesisKeyDelegationJSON, ... } | { - CommitteeColdResignJSON: CommitteeColdResign, + MoveInstantaneousRewardsCert: MoveInstantaneousRewardsCertJSON, ... } | { - DrepDeregistrationJSON: DrepDeregistration, + CommitteeHotAuth: CommitteeHotAuthJSON, ... } | { - DrepRegistrationJSON: DrepRegistration, + CommitteeColdResign: CommitteeColdResignJSON, ... } | { - DrepUpdateJSON: DrepUpdate, + DrepDeregistration: DrepDeregistrationJSON, ... } | { - StakeAndVoteDelegationJSON: StakeAndVoteDelegation, + DrepRegistration: DrepRegistrationJSON, ... } | { - StakeRegistrationAndDelegationJSON: StakeRegistrationAndDelegation, + DrepUpdate: DrepUpdateJSON, ... } | { - StakeVoteRegistrationAndDelegationJSON: StakeVoteRegistrationAndDelegation, + StakeAndVoteDelegation: StakeAndVoteDelegationJSON, ... } | { - VoteDelegationJSON: VoteDelegation, + StakeRegistrationAndDelegation: StakeRegistrationAndDelegationJSON, ... } | { - VoteRegistrationAndDelegationJSON: VoteRegistrationAndDelegation, + StakeVoteRegistrationAndDelegation: StakeVoteRegistrationAndDelegationJSON, ... - }; -export type CertificatesJSON = CertificateJSON[]; -export interface CommitteeJSON { - members: CommitteeMember[]; - quorum_threshold: UnitIntervalJSON; -} -export interface CommitteeColdResignJSON { - committee_cold_key: CredTypeJSON; -} -export interface CommitteeHotAuthJSON { - committee_cold_key: CredTypeJSON; - committee_hot_key: CredTypeJSON; -} -export interface ConstitutionJSON { - anchor: AnchorJSON; - script_hash?: string | null; -} -export type CostModelJSON = string[]; -export interface CostmdlsJSON { - [k: string]: CostModelJSON; -} -export type CredTypeJSON = + } | { - Key: string, + VoteDelegation: VoteDelegationJSON, ... } | { - Script: string, + VoteRegistrationAndDelegation: VoteRegistrationAndDelegationJSON, ... }; -export type CredentialJSON = CredTypeJSON; -export type CredentialsJSON = CredTypeJSON[]; -export type DNSRecordAorAAAAJSON = string; -export type DNSRecordSRVJSON = string; -export type DRepJSON = DRepEnumJSON; -export type DRepEnumJSON = - | ("AlwaysAbstain" | "AlwaysNoConfidence") +export type CredTypeJSON = | { - KeyHash: string, + Key: string, ... } | { - ScriptHashJSON: string, + Script: string, ... }; -export type DataHashJSON = string; -export type DataOptionJSON = +export type Ed25519KeyHashesJSON = string[]; +export type RelayJSON = | { - DataHashJSON: string, + SingleHostAddr: SingleHostAddrJSON, ... } | { - Data: string, - ... - }; -export interface DrepDeregistrationJSON { - coin: string; - voting_credential: CredTypeJSON; -} -export interface DrepRegistrationJSON { - anchor?: AnchorJSON | null; - coin: string; - voting_credential: CredTypeJSON; -} -export interface DrepUpdateJSON { - anchor?: AnchorJSON | null; - voting_credential: CredTypeJSON; -} -export interface DrepVotingThresholdsJSON { - committee_no_confidence: UnitIntervalJSON; - committee_normal: UnitIntervalJSON; - hard_fork_initiation: UnitIntervalJSON; - motion_no_confidence: UnitIntervalJSON; - pp_economic_group: UnitIntervalJSON; - pp_governance_group: UnitIntervalJSON; - pp_network_group: UnitIntervalJSON; - pp_technical_group: UnitIntervalJSON; - treasury_withdrawal: UnitIntervalJSON; - update_constitution: UnitIntervalJSON; -} -export type Ed25519KeyHashJSON = string; -export type Ed25519KeyHashesJSON = string[]; -export type Ed25519SignatureJSON = string; -export interface ExUnitPricesJSON { - mem_price: UnitIntervalJSON; - step_price: UnitIntervalJSON; -} -export interface ExUnitsJSON { - mem: string; - steps: string; -} -export interface GeneralTransactionMetadataJSON { - [k: string]: string; -} -export type GenesisDelegateHashJSON = string; -export type GenesisHashJSON = string; -export type GenesisHashesJSON = string[]; -export interface GenesisKeyDelegationJSON { - genesis_delegate_hash: string; - genesishash: string; - vrf_keyhash: string; -} -export interface GovernanceActionIdJSON { - index: number; - transaction_id: string; -} -export interface HardForkInitiationProposalJSON { - gov_action_id?: GovernanceActionIdJSON | null; - protocol_version: ProtocolVersionJSON; -} -export interface HeaderJSON { - body_signature: string; - header_body: HeaderBodyJSON; -} -export interface HeaderBodyJSON { - block_body_hash: string; - block_body_size: number; - block_number: number; - issuer_vkey: VkeyJSON; - leader_cert: HeaderLeaderCertEnumJSON; - operational_cert: OperationalCertJSON; - prev_hash?: string | null; - protocol_version: ProtocolVersionJSON; - slot: string; - vrf_vkey: string; -} -export type HeaderLeaderCertEnumJSON = - | { - NonceAndLeader: [VRFCertJSON, VRFCert], + SingleHostName: SingleHostNameJSON, ... } | { - VrfResult: VRFCertJSON, + MultiHostName: MultiHostNameJSON, ... }; -export type IntJSON = string; +/** + * @minItems 4 + * @maxItems 4 + */ export type Ipv4JSON = [number, number, number, number]; +/** + * @minItems 16 + * @maxItems 16 + */ export type Ipv6JSON = [ number, number, @@ -13878,111 +13817,142 @@ export type Ipv6JSON = [ number, number ]; -export type KESVKeyJSON = string; -export type LanguageJSON = LanguageKindJSON; -export type LanguageKindJSON = "PlutusV1" | "PlutusV2" | "PlutusV3"; -export type LanguagesJSON = LanguageJSON[]; +export type DNSRecordAorAAAAJSON = string; +export type DNSRecordSRVJSON = string; +export type RelaysJSON = RelayJSON[]; +export type MIRPotJSON = "Reserves" | "Treasury"; export type MIREnumJSON = | { ToOtherPot: string, ... } | { - ToStakeCredentials: StakeToCoinJson[], + ToStakeCredentials: StakeToCoinJSON[], + ... + }; +export type DRepJSON = + | ("AlwaysAbstain" | "AlwaysNoConfidence") + | { + KeyHash: string, + ... + } + | { + ScriptHash: string, + ... + }; +export type CertificatesJSON = CertificateJSON[]; +export type TransactionInputsJSON = TransactionInputJSON[]; +export type DataOptionJSON = + | { + DataHash: string, + ... + } + | { + Data: string, + ... + }; +export type ScriptRefJSON = + | { + NativeScript: NativeScriptJSON, + ... + } + | { + PlutusScript: string, ... }; -export type MIRPotJSON = "Reserves" | "Treasury"; -export type MIRToStakeCredentialsJSON = StakeToCoinJson[]; export type MintJSON = [string, MintAssetsJSON][]; -export interface MintAssetsJSON { - [k: string]: string; -} -export interface MoveInstantaneousRewardJSON { - pot: MIRPotJSON; - variant: MIREnumJSON; -} -export interface MoveInstantaneousRewardsCertJSON { - move_instantaneous_reward: MoveInstantaneousRewardJSON; -} -export interface MultiAssetJSON { - [k: string]: AssetsJSON; -} -export interface MultiHostNameJSON { - dns_name: DNSRecordSRVJSON; -} -export type NativeScriptJSON = NativeScript1JSON; -export type NativeScript1JSON = +export type NetworkIdJSON = "Testnet" | "Mainnet"; +export type TransactionOutputsJSON = TransactionOutputJSON[]; +export type CostModelJSON = string[]; +export type VoterJSON = + | { + ConstitutionalCommitteeHotKey: CredTypeJSON, + ... + } + | { + DRep: CredTypeJSON, + ... + } | { - ScriptPubkeyJSON: ScriptPubkey, + StakingPool: string, + ... + }; +export type VoteKindJSON = "No" | "Yes" | "Abstain"; +export type VotingProposalJSON = + | { + ParameterChangeProposal: ParameterChangeProposalJSON, ... } | { - ScriptAllJSON: ScriptAll, + HardForkInitiationProposal: HardForkInitiationProposalJSON, ... } | { - ScriptAnyJSON: ScriptAny, + TreasuryWithdrawalsProposal: TreasuryWithdrawalsProposalJSON, ... } | { - ScriptNOfKJSON: ScriptNOfK, + NoConfidenceProposal: NoConfidenceProposalJSON, ... } | { - TimelockStartJSON: TimelockStart, + UpdateCommitteeProposal: UpdateCommitteeProposalJSON, ... } | { - TimelockExpiryJSON: TimelockExpiry, + NewConstitutionProposal: NewConstitutionProposalJSON, + ... + } + | { + InfoProposal: InfoProposalJSON, ... }; -export type NativeScriptsJSON = NativeScriptJSON[]; -export type NetworkIdJSON = NetworkIdKindJSON; -export type NetworkIdKindJSON = "Testnet" | "Mainnet"; -export interface NewConstitutionProposalJSON { - constitution: ConstitutionJSON; - gov_action_id?: GovernanceActionIdJSON | null; -} -export interface NoConfidenceProposalJSON { - gov_action_id?: GovernanceActionIdJSON | null; -} -export interface NonceJSON { - hash?: - | [ - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number - ] - | null; +/** + * @minItems 0 + * @maxItems 0 + */ +export type InfoProposalJSON = []; +export type VotingProposalsJSON = VotingProposalJSON[]; +export type TransactionBodiesJSON = TransactionBodyJSON[]; +export type BootstrapWitnessesJSON = BootstrapWitnessJSON[]; +export type RedeemerTagJSON = + | "Spend" + | "Mint" + | "Cert" + | "Reward" + | "Vote" + | "VotingProposal"; +export type RedeemersJSON = RedeemerJSON[]; +export type VkeywitnessesJSON = VkeywitnessJSON[]; +export type TransactionWitnessSetsJSON = TransactionWitnessSetJSON[]; +export interface BlockJSON { + auxiliary_data_set: { + [k: string]: AuxiliaryDataJSON, + }; + header: HeaderJSON; + invalid_transactions: number[]; + transaction_bodies: TransactionBodiesJSON; + transaction_witness_sets: TransactionWitnessSetsJSON; +} +export interface HeaderJSON { + body_signature: string; + header_body: HeaderBodyJSON; +} +export interface HeaderBodyJSON { + block_body_hash: string; + block_body_size: number; + block_number: number; + issuer_vkey: VkeyJSON; + leader_cert: HeaderLeaderCertEnumJSON; + operational_cert: OperationalCertJSON; + prev_hash?: string | null; + protocol_version: ProtocolVersionJSON; + slot: string; + vrf_vkey: string; +} +export interface VRFCertJSON { + output: number[]; + proof: number[]; } export interface OperationalCertJSON { hot_vkey: string; @@ -13990,17 +13960,50 @@ export interface OperationalCertJSON { sequence_number: number; sigma: string; } -export interface ParameterChangeProposalJSON { - gov_action_id?: GovernanceActionIdJSON | null; - protocol_param_updates: ProtocolParamUpdateJSON; +export interface ProtocolVersionJSON { + major: number; + minor: number; } -export type PlutusScriptJSON = string; -export type PlutusScriptsJSON = string[]; -export interface PoolMetadataJSON { - pool_metadata_hash: string; - url: URLJSON; +export interface TransactionBodyJSON { + auxiliary_data_hash?: string | null; + certs?: CertificatesJSON | null; + collateral?: TransactionInputsJSON | null; + collateral_return?: TransactionOutputJSON | null; + current_treasury_value?: string | null; + donation?: string | null; + fee: string; + inputs: TransactionInputsJSON; + mint?: MintJSON | null; + network_id?: NetworkIdJSON | null; + outputs: TransactionOutputsJSON; + reference_inputs?: TransactionInputsJSON | null; + required_signers?: Ed25519KeyHashesJSON | null; + script_data_hash?: string | null; + total_collateral?: string | null; + ttl?: string | null; + update?: UpdateJSON | null; + validity_start_interval?: string | null; + voting_procedures?: VoterVotesJSON[] | null; + voting_proposals?: VotingProposalsJSON | null; + withdrawals?: { + [k: string]: string, + } | null; +} +export interface StakeRegistrationJSON { + coin?: string | null; + stake_credential: CredTypeJSON; +} +export interface StakeDeregistrationJSON { + coin?: string | null; + stake_credential: CredTypeJSON; +} +export interface StakeDelegationJSON { + pool_keyhash: string; + stake_credential: CredTypeJSON; +} +export interface PoolRegistrationJSON { + pool_params: PoolParamsJSON; } -export type PoolMetadataHashJSON = string; export interface PoolParamsJSON { cost: string; margin: UnitIntervalJSON; @@ -14012,21 +14015,116 @@ export interface PoolParamsJSON { reward_account: string; vrf_keyhash: string; } -export interface PoolRegistrationJSON { - pool_params: PoolParamsJSON; +export interface UnitIntervalJSON { + denominator: string; + numerator: string; +} +export interface PoolMetadataJSON { + pool_metadata_hash: string; + url: URLJSON; +} +export interface SingleHostAddrJSON { + ipv4?: Ipv4JSON | null; + ipv6?: Ipv6JSON | null; + port?: number | null; +} +export interface SingleHostNameJSON { + dns_name: DNSRecordAorAAAAJSON; + port?: number | null; +} +export interface MultiHostNameJSON { + dns_name: DNSRecordSRVJSON; } export interface PoolRetirementJSON { epoch: number; pool_keyhash: string; } -export interface PoolVotingThresholdsJSON { - committee_no_confidence: UnitIntervalJSON; - committee_normal: UnitIntervalJSON; - hard_fork_initiation: UnitIntervalJSON; - motion_no_confidence: UnitIntervalJSON; +export interface GenesisKeyDelegationJSON { + genesis_delegate_hash: string; + genesishash: string; + vrf_keyhash: string; } -export interface ProposedProtocolParameterUpdatesJSON { - [k: string]: ProtocolParamUpdateJSON; +export interface MoveInstantaneousRewardsCertJSON { + move_instantaneous_reward: MoveInstantaneousRewardJSON; +} +export interface MoveInstantaneousRewardJSON { + pot: MIRPotJSON; + variant: MIREnumJSON; +} +export interface StakeToCoinJSON { + amount: string; + stake_cred: CredTypeJSON; +} +export interface CommitteeHotAuthJSON { + committee_cold_key: CredTypeJSON; + committee_hot_key: CredTypeJSON; +} +export interface CommitteeColdResignJSON { + committee_cold_key: CredTypeJSON; +} +export interface DrepDeregistrationJSON { + coin: string; + voting_credential: CredTypeJSON; +} +export interface DrepRegistrationJSON { + anchor?: AnchorJSON | null; + coin: string; + voting_credential: CredTypeJSON; +} +export interface DrepUpdateJSON { + anchor?: AnchorJSON | null; + voting_credential: CredTypeJSON; +} +export interface StakeAndVoteDelegationJSON { + drep: DRepJSON; + pool_keyhash: string; + stake_credential: CredTypeJSON; +} +export interface StakeRegistrationAndDelegationJSON { + coin: string; + pool_keyhash: string; + stake_credential: CredTypeJSON; +} +export interface StakeVoteRegistrationAndDelegationJSON { + coin: string; + drep: DRepJSON; + pool_keyhash: string; + stake_credential: CredTypeJSON; +} +export interface VoteDelegationJSON { + drep: DRepJSON; + stake_credential: CredTypeJSON; +} +export interface VoteRegistrationAndDelegationJSON { + coin: string; + drep: DRepJSON; + stake_credential: CredTypeJSON; +} +export interface TransactionInputJSON { + index: number; + transaction_id: string; +} +export interface TransactionOutputJSON { + address: string; + amount: ValueJSON; + plutus_data?: DataOptionJSON | null; + script_ref?: ScriptRefJSON | null; +} +export interface ValueJSON { + coin: string; + multiasset?: MultiAssetJSON | null; +} +export interface MultiAssetJSON { + [k: string]: AssetsJSON; +} +export interface MintAssetsJSON { + [k: string]: string; +} +export interface UpdateJSON { + epoch: number; + proposed_protocol_parameter_updates: { + [k: string]: ProtocolParamUpdateJSON, + }; } export interface ProtocolParamUpdateJSON { ada_per_utxo_byte?: string | null; @@ -14062,269 +14160,363 @@ export interface ProtocolParamUpdateJSON { protocol_version?: ProtocolVersionJSON | null; treasury_growth_rate?: UnitIntervalJSON | null; } -export interface ProtocolVersionJSON { - major: number; - minor: number; +export interface CostmdlsJSON { + [k: string]: CostModelJSON; +} +export interface DrepVotingThresholdsJSON { + committee_no_confidence: UnitIntervalJSON; + committee_normal: UnitIntervalJSON; + hard_fork_initiation: UnitIntervalJSON; + motion_no_confidence: UnitIntervalJSON; + pp_economic_group: UnitIntervalJSON; + pp_governance_group: UnitIntervalJSON; + pp_network_group: UnitIntervalJSON; + pp_technical_group: UnitIntervalJSON; + treasury_withdrawal: UnitIntervalJSON; + update_constitution: UnitIntervalJSON; +} +export interface ExUnitPricesJSON { + mem_price: UnitIntervalJSON; + step_price: UnitIntervalJSON; +} +export interface NonceJSON { + /** + * @minItems 32 + * @maxItems 32 + */ + hash?: + | [ + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number + ] + | null; +} +export interface ExUnitsJSON { + mem: string; + steps: string; +} +export interface PoolVotingThresholdsJSON { + committee_no_confidence: UnitIntervalJSON; + committee_normal: UnitIntervalJSON; + hard_fork_initiation: UnitIntervalJSON; + motion_no_confidence: UnitIntervalJSON; +} +export interface VoterVotesJSON { + voter: VoterJSON; + votes: VoteJSON[]; +} +export interface VoteJSON { + action_id: GovernanceActionIdJSON; + voting_procedure: VotingProcedureJSON; +} +export interface GovernanceActionIdJSON { + index: number; + transaction_id: string; +} +export interface VotingProcedureJSON { + anchor?: AnchorJSON | null; + vote: VoteKindJSON; +} +export interface ParameterChangeProposalJSON { + gov_action_id?: GovernanceActionIdJSON | null; + protocol_param_updates: ProtocolParamUpdateJSON; +} +export interface HardForkInitiationProposalJSON { + gov_action_id?: GovernanceActionIdJSON | null; + protocol_version: ProtocolVersionJSON; +} +export interface TreasuryWithdrawalsProposalJSON { + withdrawals: TreasuryWithdrawalsJSON; +} +export interface TreasuryWithdrawalsJSON { + [k: string]: string; +} +export interface NoConfidenceProposalJSON { + gov_action_id?: GovernanceActionIdJSON | null; +} +export interface UpdateCommitteeProposalJSON { + committee: CommitteeJSON; + gov_action_id?: GovernanceActionIdJSON | null; + members_to_remove: CredTypeJSON[]; +} +export interface CommitteeJSON { + members: CommitteeMemberJSON[]; + quorum_threshold: UnitIntervalJSON; +} +export interface CommitteeMemberJSON { + stake_credential: CredTypeJSON; + term_limit: number; +} +export interface NewConstitutionProposalJSON { + constitution: ConstitutionJSON; + gov_action_id?: GovernanceActionIdJSON | null; +} +export interface ConstitutionJSON { + anchor: AnchorJSON; + script_hash?: string | null; +} +export interface TransactionWitnessSetJSON { + bootstraps?: BootstrapWitnessesJSON | null; + native_scripts?: NativeScriptsJSON | null; + plutus_data?: PlutusListJSON | null; + plutus_scripts?: PlutusScriptsJSON | null; + redeemers?: RedeemersJSON | null; + vkeys?: VkeywitnessesJSON | null; +} +export interface BootstrapWitnessJSON { + attributes: number[]; + chain_code: number[]; + signature: string; + vkey: VkeyJSON; +} +export interface PlutusListJSON { + definite_encoding?: boolean | null; + elems: string[]; } -export type PublicKeyJSON = string; export interface RedeemerJSON { data: string; ex_units: ExUnitsJSON; index: string; tag: RedeemerTagJSON; } -export type RedeemerTagJSON = RedeemerTagKindJSON; +export interface VkeywitnessJSON { + signature: string; + vkey: VkeyJSON; +} +export type BlockHashJSON = string; +export type CertificateEnumJSON = + | { + StakeRegistration: StakeRegistrationJSON, + ... + } + | { + StakeDeregistration: StakeDeregistrationJSON, + ... + } + | { + StakeDelegation: StakeDelegationJSON, + ... + } + | { + PoolRegistration: PoolRegistrationJSON, + ... + } + | { + PoolRetirement: PoolRetirementJSON, + ... + } + | { + GenesisKeyDelegation: GenesisKeyDelegationJSON, + ... + } + | { + MoveInstantaneousRewardsCert: MoveInstantaneousRewardsCertJSON, + ... + } + | { + CommitteeHotAuth: CommitteeHotAuthJSON, + ... + } + | { + CommitteeColdResign: CommitteeColdResignJSON, + ... + } + | { + DrepDeregistration: DrepDeregistrationJSON, + ... + } + | { + DrepRegistration: DrepRegistrationJSON, + ... + } + | { + DrepUpdate: DrepUpdateJSON, + ... + } + | { + StakeAndVoteDelegation: StakeAndVoteDelegationJSON, + ... + } + | { + StakeRegistrationAndDelegation: StakeRegistrationAndDelegationJSON, + ... + } + | { + StakeVoteRegistrationAndDelegation: StakeVoteRegistrationAndDelegationJSON, + ... + } + | { + VoteDelegation: VoteDelegationJSON, + ... + } + | { + VoteRegistrationAndDelegation: VoteRegistrationAndDelegationJSON, + ... + }; +export type CredentialJSON = CredTypeJSON; +export type CredentialsJSON = CredTypeJSON[]; +export type DRepEnumJSON = + | ("AlwaysAbstain" | "AlwaysNoConfidence") + | { + KeyHash: string, + ... + } + | { + ScriptHash: string, + ... + }; +export type DataHashJSON = string; +export type Ed25519KeyHashJSON = string; +export type Ed25519SignatureJSON = string; +export interface GeneralTransactionMetadataJSON { + [k: string]: string; +} +export type GenesisDelegateHashJSON = string; +export type GenesisHashJSON = string; +export type GenesisHashesJSON = string[]; +export type IntJSON = string; +/** + * @minItems 4 + * @maxItems 4 + */ +export type KESVKeyJSON = string; +export type LanguageJSON = LanguageKindJSON; +export type LanguageKindJSON = "PlutusV1" | "PlutusV2" | "PlutusV3"; +export type LanguagesJSON = LanguageJSON[]; +export type MIRToStakeCredentialsJSON = StakeToCoinJSON[]; +export type NetworkIdKindJSON = "Testnet" | "Mainnet"; +export type PlutusScriptJSON = string; +export type PoolMetadataHashJSON = string; +export interface ProposedProtocolParameterUpdatesJSON { + [k: string]: ProtocolParamUpdateJSON; +} +export type PublicKeyJSON = string; export type RedeemerTagKindJSON = | "Spend" - | "MintJSON" + | "Mint" | "Cert" | "Reward" | "Vote" - | "VotingProposalJSON"; -export type RedeemersJSON = RedeemerJSON[]; -export type RelayJSON = RelayEnumJSON; + | "VotingProposal"; export type RelayEnumJSON = | { - SingleHostAddrJSON: SingleHostAddr, + SingleHostAddr: SingleHostAddrJSON, ... } | { - SingleHostNameJSON: SingleHostName, + SingleHostName: SingleHostNameJSON, ... } | { - MultiHostNameJSON: MultiHostName, + MultiHostName: MultiHostNameJSON, ... }; -export type RelaysJSON = RelayJSON[]; +/** + * @minItems 4 + * @maxItems 4 + */ export type RewardAddressJSON = string; export type RewardAddressesJSON = string[]; -export interface ScriptAllJSON { - native_scripts: NativeScriptsJSON; -} -export interface ScriptAnyJSON { - native_scripts: NativeScriptsJSON; -} export type ScriptDataHashJSON = string; export type ScriptHashJSON = string; export type ScriptHashesJSON = string[]; -export interface ScriptNOfKJSON { - n: number; - native_scripts: NativeScriptsJSON; -} -export interface ScriptPubkeyJSON { - addr_keyhash: string; -} -export type ScriptRefJSON = ScriptRefEnumJSON; export type ScriptRefEnumJSON = | { - NativeScriptJSON: NativeScript, + NativeScript: NativeScriptJSON, ... } | { - PlutusScriptJSON: string, + PlutusScript: string, ... }; -export interface SingleHostAddrJSON { - ipv4?: Ipv4JSON | null; - ipv6?: Ipv6JSON | null; - port?: number | null; -} -export interface SingleHostNameJSON { - dns_name: DNSRecordAorAAAAJSON; - port?: number | null; -} -export interface StakeAndVoteDelegationJSON { - drep: DRepJSON; - pool_keyhash: string; - stake_credential: CredTypeJSON; -} -export interface StakeDelegationJSON { - pool_keyhash: string; - stake_credential: CredTypeJSON; -} -export interface StakeDeregistrationJSON { - coin?: string | null; - stake_credential: CredTypeJSON; -} -export interface StakeRegistrationJSON { - coin?: string | null; - stake_credential: CredTypeJSON; -} -export interface StakeRegistrationAndDelegationJSON { - coin: string; - pool_keyhash: string; - stake_credential: CredTypeJSON; -} -export interface StakeVoteRegistrationAndDelegationJSON { - coin: string; - drep: DRepJSON; - pool_keyhash: string; - stake_credential: CredTypeJSON; -} -export interface TimelockExpiryJSON { - slot: string; -} -export interface TimelockStartJSON { - slot: string; -} export interface TransactionJSON { auxiliary_data?: AuxiliaryDataJSON | null; body: TransactionBodyJSON; is_valid: boolean; witness_set: TransactionWitnessSetJSON; } -export type TransactionBodiesJSON = TransactionBodyJSON[]; -export interface TransactionBodyJSON { - auxiliary_data_hash?: string | null; - certs?: CertificatesJSON | null; - collateral?: TransactionInputsJSON | null; - collateral_return?: TransactionOutputJSON | null; - current_treasury_value?: string | null; - donation?: string | null; - fee: string; - inputs: TransactionInputsJSON; - mint?: MintJSON | null; - network_id?: NetworkIdJSON | null; - outputs: TransactionOutputsJSON; - reference_inputs?: TransactionInputsJSON | null; - required_signers?: Ed25519KeyHashesJSON | null; - script_data_hash?: string | null; - total_collateral?: string | null; - ttl?: string | null; - update?: UpdateJSON | null; - validity_start_interval?: string | null; - voting_procedures?: VoterVotes[] | null; - voting_proposals?: VotingProposalsJSON | null; - withdrawals?: { - [k: string]: string, - } | null; -} export type TransactionHashJSON = string; -export interface TransactionInputJSON { - index: number; - transaction_id: string; -} -export type TransactionInputsJSON = TransactionInputJSON[]; export type TransactionMetadatumJSON = string; -export interface TransactionOutputJSON { - address: string; - amount: ValueJSON; - plutus_data?: DataOptionJSON | null; - script_ref?: ScriptRefJSON | null; -} -export type TransactionOutputsJSON = TransactionOutputJSON[]; export interface TransactionUnspentOutputJSON { input: TransactionInputJSON; output: TransactionOutputJSON; } export type TransactionUnspentOutputsJSON = TransactionUnspentOutputJSON[]; -export interface TransactionWitnessSetJSON { - bootstraps?: BootstrapWitnessesJSON | null; - native_scripts?: NativeScriptsJSON | null; - plutus_data?: PlutusList | null; - plutus_scripts?: PlutusScriptsJSON | null; - redeemers?: RedeemersJSON | null; - vkeys?: VkeywitnessesJSON | null; -} -export type TransactionWitnessSetsJSON = TransactionWitnessSetJSON[]; -export interface TreasuryWithdrawalsJSON { - [k: string]: string; -} -export interface TreasuryWithdrawalsProposalJSON { - withdrawals: TreasuryWithdrawalsJSON; -} -export type URLJSON = string; -export interface UnitIntervalJSON { - denominator: string; - numerator: string; -} -export interface UpdateJSON { - epoch: number; - proposed_protocol_parameter_updates: { - [k: string]: ProtocolParamUpdateJSON, - }; -} -export interface UpdateCommitteeProposalJSON { - committee: CommitteeJSON; - gov_action_id?: GovernanceActionIdJSON | null; - members_to_remove: CredTypeJSON[]; -} -export interface VRFCertJSON { - output: number[]; - proof: number[]; -} export type VRFKeyHashJSON = string; export type VRFVKeyJSON = string; -export interface ValueJSON { - coin: string; - multiasset?: MultiAssetJSON | null; -} -export type VkeyJSON = string; -export interface VkeywitnessJSON { - signature: string; - vkey: VkeyJSON; -} -export type VkeywitnessesJSON = VkeywitnessJSON[]; -export interface VoteDelegationJSON { - drep: DRepJSON; - stake_credential: CredTypeJSON; -} -export interface VoteRegistrationAndDelegationJSON { - coin: string; - drep: DRepJSON; - stake_credential: CredTypeJSON; -} -export type VoterJSON = VoterEnumJSON; export type VoterEnumJSON = | { ConstitutionalCommitteeHotKey: CredTypeJSON, ... } | { - DRepJSON: CredTypeJSON, + DRep: CredTypeJSON, ... } | { StakingPool: string, ... }; -export interface VotingProcedureJSON { - anchor?: AnchorJSON | null; - vote: $Values; -} -export type VotingProceduresJSON = VoterVotes[]; -export type VotingProposalJSON = VotingProposalEnumJSON; +export type VotingProceduresJSON = VoterVotesJSON[]; export type VotingProposalEnumJSON = | { - ParameterChangeProposalJSON: ParameterChangeProposal, + ParameterChangeProposal: ParameterChangeProposalJSON, ... } | { - HardForkInitiationProposalJSON: HardForkInitiationProposal, + HardForkInitiationProposal: HardForkInitiationProposalJSON, ... } | { - TreasuryWithdrawalsProposalJSON: TreasuryWithdrawalsProposal, + TreasuryWithdrawalsProposal: TreasuryWithdrawalsProposalJSON, ... } | { - NoConfidenceProposalJSON: NoConfidenceProposal, + NoConfidenceProposal: NoConfidenceProposalJSON, ... } | { - UpdateCommitteeProposalJSON: UpdateCommitteeProposal, + UpdateCommitteeProposal: UpdateCommitteeProposalJSON, ... } | { - NewConstitutionProposalJSON: NewConstitutionProposal, + NewConstitutionProposal: NewConstitutionProposalJSON, ... } | { - InfoProposal: InfoProposal, + InfoProposal: InfoProposalJSON, ... }; -export type VotingProposalsJSON = VotingProposalJSON[]; export interface WithdrawalsJSON { [k: string]: string; } From 39cdd40fc155f1c2aaf87fad575cfae280348638 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 24 Sep 2023 00:42:31 +0900 Subject: [PATCH 165/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 32a44dec..5912f30f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.6", + "version": "12.0.0-alpha.7", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 816158ea..52c54d82 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.6", + "version": "12.0.0-alpha.7", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 63af5818..0249c63c 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.6" +version = "12.0.0-alpha.7" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 5bc78916..72bbefe9 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -37,7 +37,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.6" +version = "12.0.0-alpha.7" dependencies = [ "bech32", "cbor_event", From 6ce6c91533c3379bc3752d65cfffe010d0bc7cc3 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 6 Oct 2023 03:26:08 +0900 Subject: [PATCH 166/349] rename proposal to action --- rust/src/builders/voting_proposal_builder.rs | 6 +- .../governance/proposals/governance_action.rs | 183 ++++++++++++++++++ ...osal.rs => hard_fork_initiation_action.rs} | 6 +- .../{info_proposal.rs => info_action.rs} | 4 +- .../governance/proposals/mod.rs | 32 +-- ...proposal.rs => new_constitution_action.rs} | 6 +- ...ce_proposal.rs => no_confidence_action.rs} | 6 +- ...proposal.rs => parameter_change_action.rs} | 6 +- ...osal.rs => treasury_withdrawals_action.rs} | 6 +- ...proposal.rs => update_committee_action.rs} | 6 +- .../governance/proposals/voting_proposal.rs | 183 ------------------ .../governance/proposals/voting_proposals.rs | 6 +- ...oting_proposal.rs => governance_action.rs} | 54 +++--- ...osal.rs => hard_fork_initiation_action.rs} | 8 +- .../serialization/governance/proposals/mod.rs | 28 +-- ...proposal.rs => new_constitution_action.rs} | 8 +- ...ce_proposal.rs => no_confidence_action.rs} | 8 +- ...proposal.rs => parameter_change_action.rs} | 8 +- ...osal.rs => treasury_withdrawals_action.rs} | 8 +- ...proposal.rs => update_committee_action.rs} | 8 +- .../governance/proposals/voting_proposals.rs | 2 +- .../tests/builders/voting_proposal_builder.rs | 48 ++--- .../protocol_types/governance/proposals.rs | 48 ++--- .../serialization/governance/proposals.rs | 138 ++++++------- 24 files changed, 408 insertions(+), 408 deletions(-) create mode 100644 rust/src/protocol_types/governance/proposals/governance_action.rs rename rust/src/protocol_types/governance/proposals/{hard_fork_initiation_proposal.rs => hard_fork_initiation_action.rs} (89%) rename rust/src/protocol_types/governance/proposals/{info_proposal.rs => info_action.rs} (84%) rename rust/src/protocol_types/governance/proposals/{new_constitution_proposal.rs => new_constitution_action.rs} (89%) rename rust/src/protocol_types/governance/proposals/{no_confidence_proposal.rs => no_confidence_action.rs} (86%) rename rust/src/protocol_types/governance/proposals/{parameter_change_proposal.rs => parameter_change_action.rs} (90%) rename rust/src/protocol_types/governance/proposals/{treasury_withdrawals_proposal.rs => treasury_withdrawals_action.rs} (80%) rename rust/src/protocol_types/governance/proposals/{update_committee_proposal.rs => update_committee_action.rs} (92%) delete mode 100644 rust/src/protocol_types/governance/proposals/voting_proposal.rs rename rust/src/serialization/governance/proposals/{voting_proposal.rs => governance_action.rs} (66%) rename rust/src/serialization/governance/proposals/{hard_fork_initiation_proposal.rs => hard_fork_initiation_action.rs} (89%) rename rust/src/serialization/governance/proposals/{new_constitution_proposal.rs => new_constitution_action.rs} (87%) rename rust/src/serialization/governance/proposals/{no_confidence_proposal.rs => no_confidence_action.rs} (83%) rename rust/src/serialization/governance/proposals/{parameter_change_proposal.rs => parameter_change_action.rs} (87%) rename rust/src/serialization/governance/proposals/{treasury_withdrawals_proposal.rs => treasury_withdrawals_action.rs} (82%) rename rust/src/serialization/governance/proposals/{update_committee_proposal.rs => update_committee_action.rs} (90%) diff --git a/rust/src/builders/voting_proposal_builder.rs b/rust/src/builders/voting_proposal_builder.rs index 8611ec52..e411abb7 100644 --- a/rust/src/builders/voting_proposal_builder.rs +++ b/rust/src/builders/voting_proposal_builder.rs @@ -4,7 +4,7 @@ use std::collections::BTreeMap; #[wasm_bindgen] #[derive(Clone, Debug)] pub struct VotingProposalBuilder { - votes: BTreeMap>, + votes: BTreeMap>, } #[wasm_bindgen] @@ -15,7 +15,7 @@ impl VotingProposalBuilder { } } - pub fn add(&mut self, proposal: &VotingProposal) -> Result<(), JsError> { + pub fn add(&mut self, proposal: &GovernanceAction) -> Result<(), JsError> { self.votes.insert(proposal.clone(), None); Ok(()) @@ -23,7 +23,7 @@ impl VotingProposalBuilder { pub fn add_with_plutus_witness( &mut self, - proposal: &VotingProposal, + proposal: &GovernanceAction, witness: &PlutusWitness, ) -> Result<(), JsError> { self.votes.insert( diff --git a/rust/src/protocol_types/governance/proposals/governance_action.rs b/rust/src/protocol_types/governance/proposals/governance_action.rs new file mode 100644 index 00000000..fe3745eb --- /dev/null +++ b/rust/src/protocol_types/governance/proposals/governance_action.rs @@ -0,0 +1,183 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub(crate) enum GovernanceActionEnum { + ParameterChangeAction(ParameterChangeAction), + HardForkInitiationAction(HardForkInitiationAction), + TreasuryWithdrawalsAction(TreasuryWithdrawalsAction), + NoConfidenceAction(NoConfidenceAction), + UpdateCommitteeAction(UpdateCommitteeAction), + NewConstitutionAction(NewConstitutionAction), + InfoAction(InfoAction), +} + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub enum GovernanceActionKind { + ParameterChangeAction = 0, + HardForkInitiationAction = 1, + TreasuryWithdrawalsAction = 2, + NoConfidenceAction = 3, + UpdateCommitteeAction = 4, + NewConstitutionAction = 5, + InfoAction = 6, +} + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct GovernanceAction(pub(crate) GovernanceActionEnum); + +impl_to_from!(GovernanceAction); + +#[wasm_bindgen] +impl GovernanceAction { + pub fn new_parameter_change_action( + parameter_change_action: &ParameterChangeAction, + ) -> Self { + Self(GovernanceActionEnum::ParameterChangeAction( + parameter_change_action.clone(), + )) + } + + pub fn new_hard_fork_initiation_action( + hard_fork_initiation_action: &HardForkInitiationAction, + ) -> Self { + Self(GovernanceActionEnum::HardForkInitiationAction( + hard_fork_initiation_action.clone(), + )) + } + + pub fn new_treasury_withdrawals_action( + treasury_withdrawals_action: &TreasuryWithdrawalsAction, + ) -> Self { + Self(GovernanceActionEnum::TreasuryWithdrawalsAction( + treasury_withdrawals_action.clone(), + )) + } + + pub fn new_no_confidence_action(no_confidence_action: &NoConfidenceAction) -> Self { + Self(GovernanceActionEnum::NoConfidenceAction( + no_confidence_action.clone(), + )) + } + + pub fn new_new_committee_action(new_committee_action: &UpdateCommitteeAction) -> Self { + Self(GovernanceActionEnum::UpdateCommitteeAction( + new_committee_action.clone(), + )) + } + + pub fn new_new_constitution_action( + new_constitution_action: &NewConstitutionAction, + ) -> Self { + Self(GovernanceActionEnum::NewConstitutionAction( + new_constitution_action.clone(), + )) + } + + pub fn new_info_action(info_action: &InfoAction) -> Self { + Self(GovernanceActionEnum::InfoAction(info_action.clone())) + } + + pub fn kind(&self) -> GovernanceActionKind { + match &self.0 { + GovernanceActionEnum::ParameterChangeAction(_) => { + GovernanceActionKind::ParameterChangeAction + } + GovernanceActionEnum::HardForkInitiationAction(_) => { + GovernanceActionKind::HardForkInitiationAction + } + GovernanceActionEnum::TreasuryWithdrawalsAction(_) => { + GovernanceActionKind::TreasuryWithdrawalsAction + } + GovernanceActionEnum::NoConfidenceAction(_) => GovernanceActionKind::NoConfidenceAction, + GovernanceActionEnum::UpdateCommitteeAction(_) => GovernanceActionKind::UpdateCommitteeAction, + GovernanceActionEnum::NewConstitutionAction(_) => { + GovernanceActionKind::NewConstitutionAction + } + GovernanceActionEnum::InfoAction(_) => GovernanceActionKind::InfoAction, + } + } + + pub fn as_parameter_change_action(&self) -> Option { + match &self.0 { + GovernanceActionEnum::ParameterChangeAction(p) => Some(p.clone()), + _ => None, + } + } + + pub fn as_hard_fork_initiation_action(&self) -> Option { + match &self.0 { + GovernanceActionEnum::HardForkInitiationAction(p) => Some(p.clone()), + _ => None, + } + } + + pub fn as_treasury_withdrawals_action(&self) -> Option { + match &self.0 { + GovernanceActionEnum::TreasuryWithdrawalsAction(p) => Some(p.clone()), + _ => None, + } + } + + pub fn as_no_confidence_action(&self) -> Option { + match &self.0 { + GovernanceActionEnum::NoConfidenceAction(p) => Some(p.clone()), + _ => None, + } + } + + pub fn as_new_committee_action(&self) -> Option { + match &self.0 { + GovernanceActionEnum::UpdateCommitteeAction(p) => Some(p.clone()), + _ => None, + } + } + + pub fn as_new_constitution_action(&self) -> Option { + match &self.0 { + GovernanceActionEnum::NewConstitutionAction(p) => Some(p.clone()), + _ => None, + } + } + + pub fn as_info_action (&self) -> Option { + match &self.0 { + GovernanceActionEnum::InfoAction(p) => Some(p.clone()), + _ => None, + } + } +} diff --git a/rust/src/protocol_types/governance/proposals/hard_fork_initiation_proposal.rs b/rust/src/protocol_types/governance/proposals/hard_fork_initiation_action.rs similarity index 89% rename from rust/src/protocol_types/governance/proposals/hard_fork_initiation_proposal.rs rename to rust/src/protocol_types/governance/proposals/hard_fork_initiation_action.rs index 37adf457..8ebba4ee 100644 --- a/rust/src/protocol_types/governance/proposals/hard_fork_initiation_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/hard_fork_initiation_action.rs @@ -13,15 +13,15 @@ use crate::*; JsonSchema, )] #[wasm_bindgen] -pub struct HardForkInitiationProposal { +pub struct HardForkInitiationAction { pub(crate) gov_action_id: Option, pub(crate) protocol_version: ProtocolVersion, } -impl_to_from!(HardForkInitiationProposal); +impl_to_from!(HardForkInitiationAction); #[wasm_bindgen] -impl HardForkInitiationProposal { +impl HardForkInitiationAction { pub fn gov_action_id(&self) -> Option { self.gov_action_id.clone() } diff --git a/rust/src/protocol_types/governance/proposals/info_proposal.rs b/rust/src/protocol_types/governance/proposals/info_action.rs similarity index 84% rename from rust/src/protocol_types/governance/proposals/info_proposal.rs rename to rust/src/protocol_types/governance/proposals/info_action.rs index 4fd2ac93..39c43d80 100644 --- a/rust/src/protocol_types/governance/proposals/info_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/info_action.rs @@ -13,10 +13,10 @@ use crate::*; JsonSchema, )] #[wasm_bindgen] -pub struct InfoProposal(); +pub struct InfoAction(); #[wasm_bindgen] -impl InfoProposal { +impl InfoAction { pub fn new() -> Self { Self() } diff --git a/rust/src/protocol_types/governance/proposals/mod.rs b/rust/src/protocol_types/governance/proposals/mod.rs index 2d870663..8a5d05a5 100644 --- a/rust/src/protocol_types/governance/proposals/mod.rs +++ b/rust/src/protocol_types/governance/proposals/mod.rs @@ -1,35 +1,35 @@ -mod parameter_change_proposal; -pub use parameter_change_proposal::*; +mod parameter_change_action; +pub use parameter_change_action::*; -mod hard_fork_initiation_proposal; -pub use hard_fork_initiation_proposal::*; +mod hard_fork_initiation_action; +pub use hard_fork_initiation_action::*; -mod treasury_withdrawals_proposal; -pub use treasury_withdrawals_proposal::*; +mod treasury_withdrawals_action; +pub use treasury_withdrawals_action::*; mod treasury_withdrawals; pub use treasury_withdrawals::*; -mod no_confidence_proposal; -pub use no_confidence_proposal::*; +mod no_confidence_action; +pub use no_confidence_action::*; mod committee; pub use committee::*; -mod update_committee_proposal; -pub use update_committee_proposal::*; +mod update_committee_action; +pub use update_committee_action::*; mod constitution; pub use constitution::*; -mod new_constitution_proposal; -pub use new_constitution_proposal::*; +mod new_constitution_action; +pub use new_constitution_action::*; -mod info_proposal; -pub use info_proposal::*; +mod info_action; +pub use info_action::*; -mod voting_proposal; -pub use voting_proposal::*; +mod governance_action; +pub use governance_action::*; mod voting_proposals; pub use voting_proposals::*; diff --git a/rust/src/protocol_types/governance/proposals/new_constitution_proposal.rs b/rust/src/protocol_types/governance/proposals/new_constitution_action.rs similarity index 89% rename from rust/src/protocol_types/governance/proposals/new_constitution_proposal.rs rename to rust/src/protocol_types/governance/proposals/new_constitution_action.rs index 427524ae..ef020c52 100644 --- a/rust/src/protocol_types/governance/proposals/new_constitution_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/new_constitution_action.rs @@ -13,15 +13,15 @@ use crate::*; JsonSchema, )] #[wasm_bindgen] -pub struct NewConstitutionProposal { +pub struct NewConstitutionAction { pub(crate) gov_action_id: Option, pub(crate) constitution: Constitution, } -impl_to_from!(NewConstitutionProposal); +impl_to_from!(NewConstitutionAction); #[wasm_bindgen] -impl NewConstitutionProposal { +impl NewConstitutionAction { pub fn gov_action_id(&self) -> Option { self.gov_action_id.clone() } diff --git a/rust/src/protocol_types/governance/proposals/no_confidence_proposal.rs b/rust/src/protocol_types/governance/proposals/no_confidence_action.rs similarity index 86% rename from rust/src/protocol_types/governance/proposals/no_confidence_proposal.rs rename to rust/src/protocol_types/governance/proposals/no_confidence_action.rs index 0e14d1be..b7c552a0 100644 --- a/rust/src/protocol_types/governance/proposals/no_confidence_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/no_confidence_action.rs @@ -13,14 +13,14 @@ use crate::*; JsonSchema, )] #[wasm_bindgen] -pub struct NoConfidenceProposal { +pub struct NoConfidenceAction { pub(crate) gov_action_id: Option, } -impl_to_from!(NoConfidenceProposal); +impl_to_from!(NoConfidenceAction); #[wasm_bindgen] -impl NoConfidenceProposal { +impl NoConfidenceAction { pub fn gov_action_id(&self) -> Option { self.gov_action_id.clone() } diff --git a/rust/src/protocol_types/governance/proposals/parameter_change_proposal.rs b/rust/src/protocol_types/governance/proposals/parameter_change_action.rs similarity index 90% rename from rust/src/protocol_types/governance/proposals/parameter_change_proposal.rs rename to rust/src/protocol_types/governance/proposals/parameter_change_action.rs index fdebeb34..8ce69f77 100644 --- a/rust/src/protocol_types/governance/proposals/parameter_change_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/parameter_change_action.rs @@ -13,15 +13,15 @@ use crate::*; JsonSchema, )] #[wasm_bindgen] -pub struct ParameterChangeProposal { +pub struct ParameterChangeAction { pub(crate) gov_action_id: Option, pub(crate) protocol_param_updates: ProtocolParamUpdate, } -impl_to_from!(ParameterChangeProposal); +impl_to_from!(ParameterChangeAction); #[wasm_bindgen] -impl ParameterChangeProposal { +impl ParameterChangeAction { pub fn gov_action_id(&self) -> Option { self.gov_action_id.clone() } diff --git a/rust/src/protocol_types/governance/proposals/treasury_withdrawals_proposal.rs b/rust/src/protocol_types/governance/proposals/treasury_withdrawals_action.rs similarity index 80% rename from rust/src/protocol_types/governance/proposals/treasury_withdrawals_proposal.rs rename to rust/src/protocol_types/governance/proposals/treasury_withdrawals_action.rs index 120be62d..d0de9b0f 100644 --- a/rust/src/protocol_types/governance/proposals/treasury_withdrawals_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/treasury_withdrawals_action.rs @@ -13,14 +13,14 @@ use crate::*; JsonSchema, )] #[wasm_bindgen] -pub struct TreasuryWithdrawalsProposal { +pub struct TreasuryWithdrawalsAction { pub(crate) withdrawals: TreasuryWithdrawals, } -impl_to_from!(TreasuryWithdrawalsProposal); +impl_to_from!(TreasuryWithdrawalsAction); #[wasm_bindgen] -impl TreasuryWithdrawalsProposal { +impl TreasuryWithdrawalsAction { pub fn withdrawals(&self) -> TreasuryWithdrawals { self.withdrawals.clone() } diff --git a/rust/src/protocol_types/governance/proposals/update_committee_proposal.rs b/rust/src/protocol_types/governance/proposals/update_committee_action.rs similarity index 92% rename from rust/src/protocol_types/governance/proposals/update_committee_proposal.rs rename to rust/src/protocol_types/governance/proposals/update_committee_action.rs index 7cc09f1b..83e78b42 100644 --- a/rust/src/protocol_types/governance/proposals/update_committee_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/update_committee_action.rs @@ -13,16 +13,16 @@ use crate::*; JsonSchema, )] #[wasm_bindgen] -pub struct UpdateCommitteeProposal { +pub struct UpdateCommitteeAction { pub(crate) gov_action_id: Option, pub(crate) committee: Committee, pub(crate) members_to_remove: BTreeSet, } -impl_to_from!(UpdateCommitteeProposal); +impl_to_from!(UpdateCommitteeAction); #[wasm_bindgen] -impl UpdateCommitteeProposal { +impl UpdateCommitteeAction { pub fn gov_action_id(&self) -> Option { self.gov_action_id.clone() } diff --git a/rust/src/protocol_types/governance/proposals/voting_proposal.rs b/rust/src/protocol_types/governance/proposals/voting_proposal.rs deleted file mode 100644 index 90d87033..00000000 --- a/rust/src/protocol_types/governance/proposals/voting_proposal.rs +++ /dev/null @@ -1,183 +0,0 @@ -use crate::*; - -#[derive( - Clone, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub(crate) enum VotingProposalEnum { - ParameterChangeProposal(ParameterChangeProposal), - HardForkInitiationProposal(HardForkInitiationProposal), - TreasuryWithdrawalsProposal(TreasuryWithdrawalsProposal), - NoConfidenceProposal(NoConfidenceProposal), - UpdateCommitteeProposal(UpdateCommitteeProposal), - NewConstitutionProposal(NewConstitutionProposal), - InfoProposal(InfoProposal), -} - -#[derive( - Clone, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -#[wasm_bindgen] -pub enum VotingProposalKind { - ParameterChangeProposal = 0, - HardForkInitiationProposal = 1, - TreasuryWithdrawalsProposal = 2, - NoConfidenceProposal = 3, - UpdateCommitteeProposal = 4, - NewConstitutionProposal = 5, - InfoProposal = 6, -} - -#[derive( - Clone, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -#[wasm_bindgen] -pub struct VotingProposal(pub(crate) VotingProposalEnum); - -impl_to_from!(VotingProposal); - -#[wasm_bindgen] -impl VotingProposal { - pub fn new_parameter_change_proposal( - parameter_change_proposal: &ParameterChangeProposal, - ) -> Self { - Self(VotingProposalEnum::ParameterChangeProposal( - parameter_change_proposal.clone(), - )) - } - - pub fn new_hard_fork_initiation_proposal( - hard_fork_initiation_proposal: &HardForkInitiationProposal, - ) -> Self { - Self(VotingProposalEnum::HardForkInitiationProposal( - hard_fork_initiation_proposal.clone(), - )) - } - - pub fn new_treasury_withdrawals_proposal( - treasury_withdrawals_proposal: &TreasuryWithdrawalsProposal, - ) -> Self { - Self(VotingProposalEnum::TreasuryWithdrawalsProposal( - treasury_withdrawals_proposal.clone(), - )) - } - - pub fn new_no_confidence_proposal(no_confidence_proposal: &NoConfidenceProposal) -> Self { - Self(VotingProposalEnum::NoConfidenceProposal( - no_confidence_proposal.clone(), - )) - } - - pub fn new_new_committee_proposal(new_committee_proposal: &UpdateCommitteeProposal) -> Self { - Self(VotingProposalEnum::UpdateCommitteeProposal( - new_committee_proposal.clone(), - )) - } - - pub fn new_new_constitution_proposal( - new_constitution_proposal: &NewConstitutionProposal, - ) -> Self { - Self(VotingProposalEnum::NewConstitutionProposal( - new_constitution_proposal.clone(), - )) - } - - pub fn new_info_proposal(info_proposal: &InfoProposal) -> Self { - Self(VotingProposalEnum::InfoProposal(info_proposal.clone())) - } - - pub fn kind(&self) -> VotingProposalKind { - match &self.0 { - VotingProposalEnum::ParameterChangeProposal(_) => { - VotingProposalKind::ParameterChangeProposal - } - VotingProposalEnum::HardForkInitiationProposal(_) => { - VotingProposalKind::HardForkInitiationProposal - } - VotingProposalEnum::TreasuryWithdrawalsProposal(_) => { - VotingProposalKind::TreasuryWithdrawalsProposal - } - VotingProposalEnum::NoConfidenceProposal(_) => VotingProposalKind::NoConfidenceProposal, - VotingProposalEnum::UpdateCommitteeProposal(_) => VotingProposalKind::UpdateCommitteeProposal, - VotingProposalEnum::NewConstitutionProposal(_) => { - VotingProposalKind::NewConstitutionProposal - } - VotingProposalEnum::InfoProposal(_) => VotingProposalKind::InfoProposal, - } - } - - pub fn as_parameter_change_proposal(&self) -> Option { - match &self.0 { - VotingProposalEnum::ParameterChangeProposal(p) => Some(p.clone()), - _ => None, - } - } - - pub fn as_hard_fork_initiation_proposal(&self) -> Option { - match &self.0 { - VotingProposalEnum::HardForkInitiationProposal(p) => Some(p.clone()), - _ => None, - } - } - - pub fn as_treasury_withdrawals_proposal(&self) -> Option { - match &self.0 { - VotingProposalEnum::TreasuryWithdrawalsProposal(p) => Some(p.clone()), - _ => None, - } - } - - pub fn as_no_confidence_proposal(&self) -> Option { - match &self.0 { - VotingProposalEnum::NoConfidenceProposal(p) => Some(p.clone()), - _ => None, - } - } - - pub fn as_new_committee_proposal(&self) -> Option { - match &self.0 { - VotingProposalEnum::UpdateCommitteeProposal(p) => Some(p.clone()), - _ => None, - } - } - - pub fn as_new_constitution_proposal(&self) -> Option { - match &self.0 { - VotingProposalEnum::NewConstitutionProposal(p) => Some(p.clone()), - _ => None, - } - } - - pub fn as_info_proposal(&self) -> Option { - match &self.0 { - VotingProposalEnum::InfoProposal(p) => Some(p.clone()), - _ => None, - } - } -} diff --git a/rust/src/protocol_types/governance/proposals/voting_proposals.rs b/rust/src/protocol_types/governance/proposals/voting_proposals.rs index f7a7aa1d..60aef69d 100644 --- a/rust/src/protocol_types/governance/proposals/voting_proposals.rs +++ b/rust/src/protocol_types/governance/proposals/voting_proposals.rs @@ -13,7 +13,7 @@ use crate::*; JsonSchema, )] #[wasm_bindgen] -pub struct VotingProposals(pub(crate) Vec); +pub struct VotingProposals(pub(crate) Vec); impl_to_from!(VotingProposals); @@ -27,11 +27,11 @@ impl VotingProposals { self.0.len() } - pub fn get(&self, index: usize) -> VotingProposal { + pub fn get(&self, index: usize) -> GovernanceAction { self.0[index].clone() } - pub fn add(&mut self, proposal: &VotingProposal) { + pub fn add(&mut self, proposal: &GovernanceAction) { self.0.push(proposal.clone()); } } diff --git a/rust/src/serialization/governance/proposals/voting_proposal.rs b/rust/src/serialization/governance/proposals/governance_action.rs similarity index 66% rename from rust/src/serialization/governance/proposals/voting_proposal.rs rename to rust/src/serialization/governance/proposals/governance_action.rs index 181253dc..7cc2950f 100644 --- a/rust/src/serialization/governance/proposals/voting_proposal.rs +++ b/rust/src/serialization/governance/proposals/governance_action.rs @@ -4,19 +4,19 @@ use crate::*; use num_traits::{FromPrimitive, ToPrimitive}; use std::io::{Seek, SeekFrom}; -impl Serialize for VotingProposal { +impl Serialize for GovernanceAction { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { match &self.0 { - VotingProposalEnum::ParameterChangeProposal(x) => x.serialize(serializer), - VotingProposalEnum::HardForkInitiationProposal(x) => x.serialize(serializer), - VotingProposalEnum::TreasuryWithdrawalsProposal(x) => x.serialize(serializer), - VotingProposalEnum::NoConfidenceProposal(x) => x.serialize(serializer), - VotingProposalEnum::UpdateCommitteeProposal(x) => x.serialize(serializer), - VotingProposalEnum::NewConstitutionProposal(x) => x.serialize(serializer), - VotingProposalEnum::InfoProposal(_) => { + GovernanceActionEnum::ParameterChangeAction(x) => x.serialize(serializer), + GovernanceActionEnum::HardForkInitiationAction(x) => x.serialize(serializer), + GovernanceActionEnum::TreasuryWithdrawalsAction(x) => x.serialize(serializer), + GovernanceActionEnum::NoConfidenceAction(x) => x.serialize(serializer), + GovernanceActionEnum::UpdateCommitteeAction(x) => x.serialize(serializer), + GovernanceActionEnum::NewConstitutionAction(x) => x.serialize(serializer), + GovernanceActionEnum::InfoAction(_) => { let index = VotingProposalIndexNames::InfoAction.to_u64(); serialize_and_check_index(serializer, index, "VotingProposalEnum::InfoProposal") } @@ -24,7 +24,7 @@ impl Serialize for VotingProposal { } } -impl Deserialize for VotingProposal { +impl Deserialize for GovernanceAction { fn deserialize(raw: &mut Deserializer) -> Result { (|| -> Result<_, DeserializeError> { if let Ok(index) = raw.unsigned_integer() { @@ -41,19 +41,19 @@ impl Deserialize for VotingProposal { .into()); } - return Ok(Self(VotingProposalEnum::InfoProposal(InfoProposal::new()))); + return Ok(Self(GovernanceActionEnum::InfoAction(InfoAction::new()))); } let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); + let ret = Self::deserialize_as_embedded_group(raw, len)?; check_len_indefinite(raw, len)?; - ret + Ok(ret) })() .map_err(|e| e.annotate("VotingProposal")) } } -impl DeserializeEmbeddedGroup for VotingProposal { +impl DeserializeEmbeddedGroup for GovernanceAction { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, @@ -67,39 +67,39 @@ impl DeserializeEmbeddedGroup for VotingProposal { let proposal_enum = match index_enum { VotingProposalIndexNames::ParameterChangeAction => { - Ok::( - VotingProposalEnum::ParameterChangeProposal( - ParameterChangeProposal::deserialize_as_embedded_group(raw, len)?, + Ok::( + GovernanceActionEnum::ParameterChangeAction( + ParameterChangeAction::deserialize_as_embedded_group(raw, len)?, ), ) } VotingProposalIndexNames::HardForkInitiationAction => { - Ok(VotingProposalEnum::HardForkInitiationProposal( - HardForkInitiationProposal::deserialize_as_embedded_group(raw, len)?, + Ok(GovernanceActionEnum::HardForkInitiationAction( + HardForkInitiationAction::deserialize_as_embedded_group(raw, len)?, )) } VotingProposalIndexNames::TreasuryWithdrawalsAction => { - Ok(VotingProposalEnum::TreasuryWithdrawalsProposal( - TreasuryWithdrawalsProposal::deserialize_as_embedded_group(raw, len)?, + Ok(GovernanceActionEnum::TreasuryWithdrawalsAction( + TreasuryWithdrawalsAction::deserialize_as_embedded_group(raw, len)?, )) } VotingProposalIndexNames::NoConfidenceAction => { - Ok(VotingProposalEnum::NoConfidenceProposal( - NoConfidenceProposal::deserialize_as_embedded_group(raw, len)?, + Ok(GovernanceActionEnum::NoConfidenceAction( + NoConfidenceAction::deserialize_as_embedded_group(raw, len)?, )) } VotingProposalIndexNames::UpdateCommitteeAction => { - Ok(VotingProposalEnum::UpdateCommitteeProposal( - UpdateCommitteeProposal::deserialize_as_embedded_group(raw, len)?, + Ok(GovernanceActionEnum::UpdateCommitteeAction( + UpdateCommitteeAction::deserialize_as_embedded_group(raw, len)?, )) } VotingProposalIndexNames::NewConstitutionAction => { - Ok(VotingProposalEnum::NewConstitutionProposal( - NewConstitutionProposal::deserialize_as_embedded_group(raw, len)?, + Ok(GovernanceActionEnum::NewConstitutionAction( + NewConstitutionAction::deserialize_as_embedded_group(raw, len)?, )) } VotingProposalIndexNames::InfoAction => { - Ok(VotingProposalEnum::InfoProposal(InfoProposal::new())) + Ok(GovernanceActionEnum::InfoAction(InfoAction::new())) } }?; diff --git a/rust/src/serialization/governance/proposals/hard_fork_initiation_proposal.rs b/rust/src/serialization/governance/proposals/hard_fork_initiation_action.rs similarity index 89% rename from rust/src/serialization/governance/proposals/hard_fork_initiation_proposal.rs rename to rust/src/serialization/governance/proposals/hard_fork_initiation_action.rs index 486feb8a..aad34325 100644 --- a/rust/src/serialization/governance/proposals/hard_fork_initiation_proposal.rs +++ b/rust/src/serialization/governance/proposals/hard_fork_initiation_action.rs @@ -4,7 +4,7 @@ use crate::*; use map_names::VotingProposalIndexNames; use num_traits::ToPrimitive; -impl cbor_event::se::Serialize for HardForkInitiationProposal { +impl cbor_event::se::Serialize for HardForkInitiationAction { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, @@ -27,9 +27,9 @@ impl cbor_event::se::Serialize for HardForkInitiationProposal { } } -impl_deserialize_for_wrapped_tuple!(HardForkInitiationProposal); +impl_deserialize_for_wrapped_tuple!(HardForkInitiationAction); -impl DeserializeEmbeddedGroup for HardForkInitiationProposal { +impl DeserializeEmbeddedGroup for HardForkInitiationAction { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, @@ -48,7 +48,7 @@ impl DeserializeEmbeddedGroup for HardForkInitiationProposal { let protocol_version = deserialize_embedded_protocol_version(raw)?; - return Ok(HardForkInitiationProposal { + return Ok(HardForkInitiationAction { gov_action_id, protocol_version, }); diff --git a/rust/src/serialization/governance/proposals/mod.rs b/rust/src/serialization/governance/proposals/mod.rs index 191814a7..322dfbd5 100644 --- a/rust/src/serialization/governance/proposals/mod.rs +++ b/rust/src/serialization/governance/proposals/mod.rs @@ -1,32 +1,32 @@ -mod parameter_change_proposal; -pub use parameter_change_proposal::*; +mod parameter_change_action; +pub use parameter_change_action::*; -mod hard_fork_initiation_proposal; -pub use hard_fork_initiation_proposal::*; +mod hard_fork_initiation_action; +pub use hard_fork_initiation_action::*; -mod treasury_withdrawals_proposal; -pub use treasury_withdrawals_proposal::*; +mod treasury_withdrawals_action; +pub use treasury_withdrawals_action::*; mod treasury_withdrawals; pub use treasury_withdrawals::*; -mod no_confidence_proposal; -pub use no_confidence_proposal::*; +mod no_confidence_action; +pub use no_confidence_action::*; mod committee; pub use committee::*; -mod update_committee_proposal; -pub use update_committee_proposal::*; +mod update_committee_action; +pub use update_committee_action::*; mod constitution; pub use constitution::*; -mod new_constitution_proposal; -pub use new_constitution_proposal::*; +mod new_constitution_action; +pub use new_constitution_action::*; -mod voting_proposal; -pub use voting_proposal::*; +mod governance_action; +pub use governance_action::*; mod voting_proposals; pub use voting_proposals::*; diff --git a/rust/src/serialization/governance/proposals/new_constitution_proposal.rs b/rust/src/serialization/governance/proposals/new_constitution_action.rs similarity index 87% rename from rust/src/serialization/governance/proposals/new_constitution_proposal.rs rename to rust/src/serialization/governance/proposals/new_constitution_action.rs index b2f12d5f..38cf3a28 100644 --- a/rust/src/serialization/governance/proposals/new_constitution_proposal.rs +++ b/rust/src/serialization/governance/proposals/new_constitution_action.rs @@ -5,7 +5,7 @@ use crate::serialization::{check_len, deserialize_and_check_index}; use map_names::VotingProposalIndexNames; use num_traits::ToPrimitive; -impl Serialize for NewConstitutionProposal { +impl Serialize for NewConstitutionAction { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, @@ -22,9 +22,9 @@ impl Serialize for NewConstitutionProposal { } } -impl_deserialize_for_wrapped_tuple!(NewConstitutionProposal); +impl_deserialize_for_wrapped_tuple!(NewConstitutionAction); -impl DeserializeEmbeddedGroup for NewConstitutionProposal { +impl DeserializeEmbeddedGroup for NewConstitutionAction { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, @@ -44,7 +44,7 @@ impl DeserializeEmbeddedGroup for NewConstitutionProposal { let constitution = Constitution::deserialize(raw).map_err(|e| e.annotate("constitution"))?; - return Ok(NewConstitutionProposal { + return Ok(NewConstitutionAction { gov_action_id, constitution, }); diff --git a/rust/src/serialization/governance/proposals/no_confidence_proposal.rs b/rust/src/serialization/governance/proposals/no_confidence_action.rs similarity index 83% rename from rust/src/serialization/governance/proposals/no_confidence_proposal.rs rename to rust/src/serialization/governance/proposals/no_confidence_action.rs index 24db8a01..6547756d 100644 --- a/rust/src/serialization/governance/proposals/no_confidence_proposal.rs +++ b/rust/src/serialization/governance/proposals/no_confidence_action.rs @@ -4,7 +4,7 @@ use crate::*; use map_names::VotingProposalIndexNames; use num_traits::ToPrimitive; -impl cbor_event::se::Serialize for NoConfidenceProposal { +impl cbor_event::se::Serialize for NoConfidenceAction { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, @@ -20,9 +20,9 @@ impl cbor_event::se::Serialize for NoConfidenceProposal { } } -impl_deserialize_for_wrapped_tuple!(NoConfidenceProposal); +impl_deserialize_for_wrapped_tuple!(NoConfidenceAction); -impl DeserializeEmbeddedGroup for NoConfidenceProposal { +impl DeserializeEmbeddedGroup for NoConfidenceAction { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, @@ -35,6 +35,6 @@ impl DeserializeEmbeddedGroup for NoConfidenceProposal { let gov_action_id = GovernanceActionId::deserialize_nullable(raw) .map_err(|e| e.annotate("gov_action_id"))?; - return Ok(NoConfidenceProposal { gov_action_id }); + return Ok(NoConfidenceAction { gov_action_id }); } } diff --git a/rust/src/serialization/governance/proposals/parameter_change_proposal.rs b/rust/src/serialization/governance/proposals/parameter_change_action.rs similarity index 87% rename from rust/src/serialization/governance/proposals/parameter_change_proposal.rs rename to rust/src/serialization/governance/proposals/parameter_change_action.rs index 9a892eef..7917fa96 100644 --- a/rust/src/serialization/governance/proposals/parameter_change_proposal.rs +++ b/rust/src/serialization/governance/proposals/parameter_change_action.rs @@ -4,7 +4,7 @@ use crate::*; use map_names::VotingProposalIndexNames; use num_traits::ToPrimitive; -impl cbor_event::se::Serialize for ParameterChangeProposal { +impl cbor_event::se::Serialize for ParameterChangeAction { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, @@ -21,9 +21,9 @@ impl cbor_event::se::Serialize for ParameterChangeProposal { } } -impl_deserialize_for_wrapped_tuple!(ParameterChangeProposal); +impl_deserialize_for_wrapped_tuple!(ParameterChangeAction); -impl DeserializeEmbeddedGroup for ParameterChangeProposal { +impl DeserializeEmbeddedGroup for ParameterChangeAction { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, @@ -43,7 +43,7 @@ impl DeserializeEmbeddedGroup for ParameterChangeProposal { let protocol_param_updates = ProtocolParamUpdate::deserialize(raw) .map_err(|e| e.annotate("protocol_param_updates"))?; - return Ok(ParameterChangeProposal { + return Ok(ParameterChangeAction { gov_action_id, protocol_param_updates, }); diff --git a/rust/src/serialization/governance/proposals/treasury_withdrawals_proposal.rs b/rust/src/serialization/governance/proposals/treasury_withdrawals_action.rs similarity index 82% rename from rust/src/serialization/governance/proposals/treasury_withdrawals_proposal.rs rename to rust/src/serialization/governance/proposals/treasury_withdrawals_action.rs index f495eb4f..f5aae742 100644 --- a/rust/src/serialization/governance/proposals/treasury_withdrawals_proposal.rs +++ b/rust/src/serialization/governance/proposals/treasury_withdrawals_action.rs @@ -4,7 +4,7 @@ use crate::*; use map_names::VotingProposalIndexNames; use num_traits::ToPrimitive; -impl Serialize for TreasuryWithdrawalsProposal { +impl Serialize for TreasuryWithdrawalsAction { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, @@ -20,9 +20,9 @@ impl Serialize for TreasuryWithdrawalsProposal { } } -impl_deserialize_for_wrapped_tuple!(TreasuryWithdrawalsProposal); +impl_deserialize_for_wrapped_tuple!(TreasuryWithdrawalsAction); -impl DeserializeEmbeddedGroup for TreasuryWithdrawalsProposal { +impl DeserializeEmbeddedGroup for TreasuryWithdrawalsAction { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, @@ -34,6 +34,6 @@ impl DeserializeEmbeddedGroup for TreasuryWithdrawalsProposal { let withdrawals = TreasuryWithdrawals::deserialize(raw)?; - return Ok(TreasuryWithdrawalsProposal { withdrawals }); + return Ok(TreasuryWithdrawalsAction { withdrawals }); } } diff --git a/rust/src/serialization/governance/proposals/update_committee_proposal.rs b/rust/src/serialization/governance/proposals/update_committee_action.rs similarity index 90% rename from rust/src/serialization/governance/proposals/update_committee_proposal.rs rename to rust/src/serialization/governance/proposals/update_committee_action.rs index 34c95abb..4cef0b7d 100644 --- a/rust/src/serialization/governance/proposals/update_committee_proposal.rs +++ b/rust/src/serialization/governance/proposals/update_committee_action.rs @@ -4,7 +4,7 @@ use crate::*; use map_names::VotingProposalIndexNames; use num_traits::ToPrimitive; -impl Serialize for UpdateCommitteeProposal { +impl Serialize for UpdateCommitteeAction { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, @@ -25,9 +25,9 @@ impl Serialize for UpdateCommitteeProposal { } } -impl_deserialize_for_wrapped_tuple!(UpdateCommitteeProposal); +impl_deserialize_for_wrapped_tuple!(UpdateCommitteeAction); -impl DeserializeEmbeddedGroup for UpdateCommitteeProposal { +impl DeserializeEmbeddedGroup for UpdateCommitteeAction { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, @@ -50,7 +50,7 @@ impl DeserializeEmbeddedGroup for UpdateCommitteeProposal { let committee = Committee::deserialize_as_embedded_group(raw, cbor_event::Len::Len(2)) .map_err(|e| e.annotate("committee"))?; - return Ok(UpdateCommitteeProposal { + return Ok(UpdateCommitteeAction { gov_action_id, members_to_remove: members_to_remove.0.iter().cloned().collect(), committee, diff --git a/rust/src/serialization/governance/proposals/voting_proposals.rs b/rust/src/serialization/governance/proposals/voting_proposals.rs index 3fc2aa28..8a5c0c28 100644 --- a/rust/src/serialization/governance/proposals/voting_proposals.rs +++ b/rust/src/serialization/governance/proposals/voting_proposals.rs @@ -26,7 +26,7 @@ impl Deserialize for VotingProposals { assert_eq!(raw.special()?, CBORSpecial::Break); break; } - arr.push(VotingProposal::deserialize(raw)?); + arr.push(GovernanceAction::deserialize(raw)?); } Ok(()) })() diff --git a/rust/src/tests/builders/voting_proposal_builder.rs b/rust/src/tests/builders/voting_proposal_builder.rs index 7d9d58dc..0d06fc2a 100644 --- a/rust/src/tests/builders/voting_proposal_builder.rs +++ b/rust/src/tests/builders/voting_proposal_builder.rs @@ -16,9 +16,9 @@ fn voting_proposal_builder_one_proposal() { let proposal_deposit = Coin::from(1000u64); let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); let proposal = - HardForkInitiationProposal::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); + HardForkInitiationAction::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); let mut builder = VotingProposalBuilder::new(); - let wrapped_proposal = VotingProposal::new_hard_fork_initiation_proposal(&proposal); + let wrapped_proposal = GovernanceAction::new_hard_fork_initiation_action(&proposal); builder.add(&wrapped_proposal).unwrap(); let witnesses = builder.get_plutus_witnesses(); @@ -59,9 +59,9 @@ fn voting_proposal_builder_all_proposals() { let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); let hf_proposal = - HardForkInitiationProposal::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); + HardForkInitiationAction::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); let mut builder = VotingProposalBuilder::new(); - let wrapped_hf_proposal = VotingProposal::new_hard_fork_initiation_proposal(&hf_proposal); + let wrapped_hf_proposal = GovernanceAction::new_hard_fork_initiation_action(&hf_proposal); builder.add(&wrapped_hf_proposal).unwrap(); let mut committee = @@ -69,34 +69,34 @@ fn voting_proposal_builder_all_proposals() { committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); - let committee_proposal = UpdateCommitteeProposal::new(&committee, &members_to_remove); - let wrapped_committee_proposal = VotingProposal::new_new_committee_proposal(&committee_proposal); + let committee_proposal = UpdateCommitteeAction::new(&committee, &members_to_remove); + let wrapped_committee_proposal = GovernanceAction::new_new_committee_action(&committee_proposal); builder.add(&wrapped_committee_proposal).unwrap(); let anchor = create_anchor(); let constitution = Constitution::new(&anchor); - let constitution_proposal = NewConstitutionProposal::new(&constitution); - let wrapped_constitution_proposal = VotingProposal::new_new_constitution_proposal(&constitution_proposal); + let constitution_proposal = NewConstitutionAction::new(&constitution); + let wrapped_constitution_proposal = GovernanceAction::new_new_constitution_action(&constitution_proposal); builder.add(&wrapped_constitution_proposal).unwrap(); - let no_conf_proposal = NoConfidenceProposal::new(); - let wrapped_no_conf_proposal = VotingProposal::new_no_confidence_proposal(&no_conf_proposal); + let no_conf_proposal = NoConfidenceAction::new(); + let wrapped_no_conf_proposal = GovernanceAction::new_no_confidence_action(&no_conf_proposal); builder.add(&wrapped_no_conf_proposal).unwrap(); let parameters_update = crate_full_protocol_param_update(); - let pp_update_proposal = ParameterChangeProposal::new(¶meters_update); - let wrapped_pp_update_proposal = VotingProposal::new_parameter_change_proposal(&pp_update_proposal); + let pp_update_proposal = ParameterChangeAction::new(¶meters_update); + let wrapped_pp_update_proposal = GovernanceAction::new_parameter_change_action(&pp_update_proposal); builder.add(&wrapped_pp_update_proposal).unwrap(); let mut withdrawals = TreasuryWithdrawals::new(); let addr1 = RewardAddress::new(1, &Credential::from_keyhash(&fake_key_hash(1))); withdrawals.insert(&addr1, &Coin::from(1u32)); - let withdrawal_proposal = TreasuryWithdrawalsProposal::new(&withdrawals); - let wrapped_withdrawal_proposal = VotingProposal::new_treasury_withdrawals_proposal(&withdrawal_proposal); + let withdrawal_proposal = TreasuryWithdrawalsAction::new(&withdrawals); + let wrapped_withdrawal_proposal = GovernanceAction::new_treasury_withdrawals_action(&withdrawal_proposal); builder.add(&wrapped_withdrawal_proposal).unwrap(); - let info_proposal = InfoProposal::new(); - let wrapped_info_proposal = VotingProposal::new_info_proposal(&info_proposal); + let info_proposal = InfoAction::new(); + let wrapped_info_proposal = GovernanceAction::new_info_action(&info_proposal); builder.add(&wrapped_info_proposal).unwrap(); let witnesses = builder.get_plutus_witnesses(); @@ -143,9 +143,9 @@ fn voting_proposal_builder_with_plutus_script_witness() { let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); let hf_proposal = - HardForkInitiationProposal::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); + HardForkInitiationAction::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); let mut builder = VotingProposalBuilder::new(); - let wrapped_hf_proposal = VotingProposal::new_hard_fork_initiation_proposal(&hf_proposal); + let wrapped_hf_proposal = GovernanceAction::new_hard_fork_initiation_action(&hf_proposal); builder.add(&wrapped_hf_proposal).unwrap(); let script = create_plutus_script(1, &Language::new_plutus_v2()); @@ -167,8 +167,8 @@ fn voting_proposal_builder_with_plutus_script_witness() { committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); - let committee_proposal = UpdateCommitteeProposal::new(&committee, &members_to_remove); - let wrapped_committee_proposal = VotingProposal::new_new_committee_proposal(&committee_proposal); + let committee_proposal = UpdateCommitteeAction::new(&committee, &members_to_remove); + let wrapped_committee_proposal = GovernanceAction::new_new_committee_action(&committee_proposal); builder.add_with_plutus_witness(&wrapped_committee_proposal, &plutus_witness).unwrap(); let witnesses = builder.get_plutus_witnesses(); @@ -238,9 +238,9 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); let hf_proposal = - HardForkInitiationProposal::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); + HardForkInitiationAction::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); let mut builder = VotingProposalBuilder::new(); - let wrapped_hf_proposal = VotingProposal::new_hard_fork_initiation_proposal(&hf_proposal); + let wrapped_hf_proposal = GovernanceAction::new_hard_fork_initiation_action(&hf_proposal); builder.add(&wrapped_hf_proposal).unwrap(); let script_hash = fake_script_hash(1); @@ -264,8 +264,8 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); - let committee_proposal = UpdateCommitteeProposal::new(&committee, &members_to_remove); - let wrapped_committee_proposal = VotingProposal::new_new_committee_proposal(&committee_proposal); + let committee_proposal = UpdateCommitteeAction::new(&committee, &members_to_remove); + let wrapped_committee_proposal = GovernanceAction::new_new_committee_action(&committee_proposal); builder.add_with_plutus_witness(&wrapped_committee_proposal, &plutus_witness).unwrap(); let witnesses = builder.get_plutus_witnesses(); diff --git a/rust/src/tests/protocol_types/governance/proposals.rs b/rust/src/tests/protocol_types/governance/proposals.rs index 1a3abf1a..3ab8e6b9 100644 --- a/rust/src/tests/protocol_types/governance/proposals.rs +++ b/rust/src/tests/protocol_types/governance/proposals.rs @@ -42,12 +42,12 @@ fn constitution_setters_getters_test() { } #[test] -fn hard_fork_initiation_proposal_setters_getters_test() { +fn hard_fork_initiation_action_setters_getters_test() { let protocol_version = ProtocolVersion::new(1, 2); - let proposal = HardForkInitiationProposal::new(&protocol_version); + let proposal = HardForkInitiationAction::new(&protocol_version); let action_id = create_action_id(); let proposal_with_action_id = - HardForkInitiationProposal::new_with_action_id(&action_id, &protocol_version); + HardForkInitiationAction::new_with_action_id(&action_id, &protocol_version); assert_eq!(proposal.gov_action_id(), None); assert_eq!(proposal.protocol_version(), protocol_version); assert_eq!(proposal_with_action_id.gov_action_id(), Some(action_id)); @@ -55,7 +55,7 @@ fn hard_fork_initiation_proposal_setters_getters_test() { } #[test] -fn new_committee_proposal_setters_getters_test() { +fn new_committee_action_setters_getters_test() { let action_id = create_action_id(); let committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); let members_to_remove = Credentials( @@ -67,9 +67,9 @@ fn new_committee_proposal_setters_getters_test() { .collect(), ); - let proposal = UpdateCommitteeProposal::new(&committee, &members_to_remove); + let proposal = UpdateCommitteeAction::new(&committee, &members_to_remove); let proposal_with_action_id = - UpdateCommitteeProposal::new_with_action_id(&action_id, &committee, &members_to_remove); + UpdateCommitteeAction::new_with_action_id(&action_id, &committee, &members_to_remove); assert_eq!(proposal.gov_action_id(), None); assert_eq!(proposal.committee(), committee); assert_eq!(proposal.members_to_remove(), members_to_remove); @@ -82,12 +82,12 @@ fn new_committee_proposal_setters_getters_test() { } #[test] -fn new_constitution_proposal_setters_getters_test() { +fn new_constitution_action_setters_getters_test() { let action_id = create_action_id(); let constitution = Constitution::new(&create_anchor()); - let proposal = NewConstitutionProposal::new(&constitution); + let proposal = NewConstitutionAction::new(&constitution); let proposal_with_action_id = - NewConstitutionProposal::new_with_action_id(&action_id, &constitution); + NewConstitutionAction::new_with_action_id(&action_id, &constitution); assert_eq!(proposal.gov_action_id(), None); assert_eq!(proposal.constitution(), constitution); assert_eq!(proposal_with_action_id.gov_action_id(), Some(action_id)); @@ -95,21 +95,21 @@ fn new_constitution_proposal_setters_getters_test() { } #[test] -fn no_confidence_proposal_setters_getters_test() { +fn no_confidence_action_setters_getters_test() { let action_id = create_action_id(); - let proposal = NoConfidenceProposal::new(); - let proposal_with_action_id = NoConfidenceProposal::new_with_action_id(&action_id); + let proposal = NoConfidenceAction::new(); + let proposal_with_action_id = NoConfidenceAction::new_with_action_id(&action_id); assert_eq!(proposal.gov_action_id(), None); assert_eq!(proposal_with_action_id.gov_action_id(), Some(action_id)); } #[test] -fn parameter_change_proposal_setters_getters_test() { +fn parameter_change_action_setters_getters_test() { let protocol_params = crate_full_protocol_param_update(); let action_id = create_action_id(); - let proposal = ParameterChangeProposal::new(&protocol_params); + let proposal = ParameterChangeAction::new(&protocol_params); let proposal_with_action_id = - ParameterChangeProposal::new_with_action_id(&action_id, &protocol_params); + ParameterChangeAction::new_with_action_id(&action_id, &protocol_params); assert_eq!(proposal.gov_action_id(), None); assert_eq!(proposal.protocol_param_updates(), protocol_params); assert_eq!(proposal_with_action_id.gov_action_id(), Some(action_id)); @@ -138,34 +138,34 @@ fn treasury_withdrawals_setters_getters_test() { } #[test] -fn treasury_withdrawals_proposal() { +fn treasury_withdrawals_action() { let mut withdrawals = TreasuryWithdrawals::new(); let addr = RewardAddress::new(1, &Credential::from_keyhash(&fake_key_hash(1))); let coin = Coin::from(100u32); withdrawals.insert(&addr, &coin); - let proposal = TreasuryWithdrawalsProposal::new(&withdrawals); + let proposal = TreasuryWithdrawalsAction::new(&withdrawals); assert_eq!(proposal.withdrawals(), withdrawals); } #[test] fn voting_proposals_setters_getters_test() { let mut proposals = VotingProposals::new(); - let no_confidence_proposal = NoConfidenceProposal::new(); + let no_confidence_proposal = NoConfidenceAction::new(); let parameter_change_proposal = - ParameterChangeProposal::new(&crate_full_protocol_param_update()); - proposals.add(&VotingProposal::new_no_confidence_proposal( + ParameterChangeAction::new(&crate_full_protocol_param_update()); + proposals.add(&GovernanceAction::new_no_confidence_action( &no_confidence_proposal, )); - proposals.add(&VotingProposal::new_parameter_change_proposal( + proposals.add(&GovernanceAction::new_parameter_change_action( ¶meter_change_proposal, )); assert_eq!(proposals.len(), 2); assert_eq!( proposals.get(0), - VotingProposal::new_no_confidence_proposal(&no_confidence_proposal) + GovernanceAction::new_no_confidence_action(&no_confidence_proposal) ); assert_eq!( proposals.get(1), - VotingProposal::new_parameter_change_proposal(¶meter_change_proposal) + GovernanceAction::new_parameter_change_action(¶meter_change_proposal) ); -} +} \ No newline at end of file diff --git a/rust/src/tests/serialization/governance/proposals.rs b/rust/src/tests/serialization/governance/proposals.rs index e2f57eb4..e0c2c520 100644 --- a/rust/src/tests/serialization/governance/proposals.rs +++ b/rust/src/tests/serialization/governance/proposals.rs @@ -21,15 +21,15 @@ macro_rules! to_from_test { assert_eq!( $variable_wrapped_name, - VotingProposal::from_json(&json_wrapped).unwrap() + GovernanceAction::from_json(&json_wrapped).unwrap() ); assert_eq!( $variable_wrapped_name, - VotingProposal::from_bytes(cbor_wrapped).unwrap() + GovernanceAction::from_bytes(cbor_wrapped).unwrap() ); assert_eq!( $variable_wrapped_name, - VotingProposal::from_hex(&hex_cbor_wrapped).unwrap() + GovernanceAction::from_hex(&hex_cbor_wrapped).unwrap() ); }; } @@ -100,35 +100,35 @@ fn constitution_with_script_hash_ser_round_trip() { } #[test] -fn hard_fork_initiation_proposal_ser_round_trip() { - let proposal = HardForkInitiationProposal::new(&ProtocolVersion::new(1, 2)); +fn hard_fork_initiation_action_ser_round_trip() { + let proposal = HardForkInitiationAction::new(&ProtocolVersion::new(1, 2)); - let proposal_wrapped = VotingProposal::new_hard_fork_initiation_proposal(&proposal); + let proposal_wrapped = GovernanceAction::new_hard_fork_initiation_action(&proposal); - to_from_test!(HardForkInitiationProposal, proposal, proposal_wrapped); + to_from_test!(HardForkInitiationAction, proposal, proposal_wrapped); assert_eq!( proposal, - proposal_wrapped.as_hard_fork_initiation_proposal().unwrap() + proposal_wrapped.as_hard_fork_initiation_action().unwrap() ); } #[test] -fn hard_fork_initiation_proposal_with_action_id_ser_round_trip() { +fn hard_fork_initiation_action_with_action_id_ser_round_trip() { let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); let proposal = - HardForkInitiationProposal::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); + HardForkInitiationAction::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); - let proposal_wrapped = VotingProposal::new_hard_fork_initiation_proposal(&proposal); + let proposal_wrapped = GovernanceAction::new_hard_fork_initiation_action(&proposal); - to_from_test!(HardForkInitiationProposal, proposal, proposal_wrapped); + to_from_test!(HardForkInitiationAction, proposal, proposal_wrapped); assert_eq!( proposal, - proposal_wrapped.as_hard_fork_initiation_proposal().unwrap() + proposal_wrapped.as_hard_fork_initiation_action().unwrap() ); } #[test] -fn new_committee_proposal_ser_round_trip() { +fn new_committee_action_ser_round_trip() { let mut committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); @@ -138,19 +138,19 @@ fn new_committee_proposal_ser_round_trip() { members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); members_to_remove.add(&Credential::from_scripthash(&fake_script_hash(2))); - let proposal = UpdateCommitteeProposal::new(&committee, &members_to_remove); + let proposal = UpdateCommitteeAction::new(&committee, &members_to_remove); - let proposal_wrapped = VotingProposal::new_new_committee_proposal(&proposal); + let proposal_wrapped = GovernanceAction::new_new_committee_action(&proposal); - to_from_test!(UpdateCommitteeProposal, proposal, proposal_wrapped); + to_from_test!(UpdateCommitteeAction, proposal, proposal_wrapped); assert_eq!( proposal, - proposal_wrapped.as_new_committee_proposal().unwrap() + proposal_wrapped.as_new_committee_action().unwrap() ); } #[test] -fn new_committee_proposal_with_action_id_ser_round_trip() { +fn new_committee_action_with_action_id_ser_round_trip() { let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); let mut committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); @@ -162,53 +162,53 @@ fn new_committee_proposal_with_action_id_ser_round_trip() { members_to_remove.add(&Credential::from_scripthash(&fake_script_hash(2))); let proposal = - UpdateCommitteeProposal::new_with_action_id(&action_id, &committee, &members_to_remove); + UpdateCommitteeAction::new_with_action_id(&action_id, &committee, &members_to_remove); - let proposal_wrapped = VotingProposal::new_new_committee_proposal(&proposal); + let proposal_wrapped = GovernanceAction::new_new_committee_action(&proposal); - to_from_test!(UpdateCommitteeProposal, proposal, proposal_wrapped); + to_from_test!(UpdateCommitteeAction, proposal, proposal_wrapped); assert_eq!( proposal, - proposal_wrapped.as_new_committee_proposal().unwrap() + proposal_wrapped.as_new_committee_action().unwrap() ); } #[test] -fn new_committee_proposal_with_empty_ser_round_trip() { +fn new_committee_action_with_empty_ser_round_trip() { let committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); let members_to_remove = Credentials::new(); - let proposal = UpdateCommitteeProposal::new(&committee, &members_to_remove); + let proposal = UpdateCommitteeAction::new(&committee, &members_to_remove); - let proposal_wrapped = VotingProposal::new_new_committee_proposal(&proposal); + let proposal_wrapped = GovernanceAction::new_new_committee_action(&proposal); - to_from_test!(UpdateCommitteeProposal, proposal, proposal_wrapped); + to_from_test!(UpdateCommitteeAction, proposal, proposal_wrapped); assert_eq!( proposal, - proposal_wrapped.as_new_committee_proposal().unwrap() + proposal_wrapped.as_new_committee_action().unwrap() ); } #[test] -fn new_constitution_proposal_ser_round_trip() { +fn new_constitution_action_ser_round_trip() { let anchor = Anchor::new( &URL::new("https://iohk.io".to_string()).unwrap(), &fake_anchor_data_hash(1), ); let constitution = Constitution::new(&anchor); - let proposal = NewConstitutionProposal::new(&constitution); + let proposal = NewConstitutionAction::new(&constitution); - let proposal_wrapped = VotingProposal::new_new_constitution_proposal(&proposal); + let proposal_wrapped = GovernanceAction::new_new_constitution_action(&proposal); - to_from_test!(NewConstitutionProposal, proposal, proposal_wrapped); + to_from_test!(NewConstitutionAction, proposal, proposal_wrapped); assert_eq!( proposal, - proposal_wrapped.as_new_constitution_proposal().unwrap() + proposal_wrapped.as_new_constitution_action().unwrap() ); } #[test] -fn new_constitution_proposal_with_action_id_ser_round_trip() { +fn new_constitution_action_with_action_id_ser_round_trip() { let anchor = Anchor::new( &URL::new("https://iohk.io".to_string()).unwrap(), &fake_anchor_data_hash(1), @@ -216,66 +216,66 @@ fn new_constitution_proposal_with_action_id_ser_round_trip() { let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); let constitution = Constitution::new(&anchor); - let proposal = NewConstitutionProposal::new_with_action_id(&action_id, &constitution); + let proposal = NewConstitutionAction::new_with_action_id(&action_id, &constitution); - let proposal_wrapped = VotingProposal::new_new_constitution_proposal(&proposal); + let proposal_wrapped = GovernanceAction::new_new_constitution_action(&proposal); - to_from_test!(NewConstitutionProposal, proposal, proposal_wrapped); + to_from_test!(NewConstitutionAction, proposal, proposal_wrapped); assert_eq!( proposal, - proposal_wrapped.as_new_constitution_proposal().unwrap() + proposal_wrapped.as_new_constitution_action().unwrap() ); } #[test] -fn no_confidence_proposal_ser_round_trip() { - let proposal = NoConfidenceProposal::new(); +fn no_confidence_action_ser_round_trip() { + let proposal = NoConfidenceAction::new(); - let proposal_wrapped = VotingProposal::new_no_confidence_proposal(&proposal); + let proposal_wrapped = GovernanceAction::new_no_confidence_action(&proposal); - to_from_test!(NoConfidenceProposal, proposal, proposal_wrapped); + to_from_test!(NoConfidenceAction, proposal, proposal_wrapped); assert_eq!( proposal, - proposal_wrapped.as_no_confidence_proposal().unwrap() + proposal_wrapped.as_no_confidence_action().unwrap() ); } #[test] -fn no_confidence_proposal_with_action_id_ser_round_trip() { +fn no_confidence_action_with_action_id_ser_round_trip() { let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); - let proposal = NoConfidenceProposal::new_with_action_id(&action_id); + let proposal = NoConfidenceAction::new_with_action_id(&action_id); - let proposal_wrapped = VotingProposal::new_no_confidence_proposal(&proposal); + let proposal_wrapped = GovernanceAction::new_no_confidence_action(&proposal); - to_from_test!(NoConfidenceProposal, proposal, proposal_wrapped); + to_from_test!(NoConfidenceAction, proposal, proposal_wrapped); assert_eq!( proposal, - proposal_wrapped.as_no_confidence_proposal().unwrap() + proposal_wrapped.as_no_confidence_action().unwrap() ); } #[test] -fn parameter_change_proposal_ser_round_trip() { +fn parameter_change_action_ser_round_trip() { let parameters_update = crate_full_protocol_param_update(); - let proposal = ParameterChangeProposal::new(¶meters_update); - let proposal_wrapped = VotingProposal::new_parameter_change_proposal(&proposal); - to_from_test!(ParameterChangeProposal, proposal, proposal_wrapped); + let proposal = ParameterChangeAction::new(¶meters_update); + let proposal_wrapped = GovernanceAction::new_parameter_change_action(&proposal); + to_from_test!(ParameterChangeAction, proposal, proposal_wrapped); assert_eq!( proposal, - proposal_wrapped.as_parameter_change_proposal().unwrap() + proposal_wrapped.as_parameter_change_action().unwrap() ); } #[test] -fn parameter_change_proposal_with_action_id_ser_round_trip() { +fn parameter_change_action_with_action_id_ser_round_trip() { let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); let parameters_update = crate_full_protocol_param_update(); - let proposal = ParameterChangeProposal::new_with_action_id(&action_id, ¶meters_update); - let proposal_wrapped = VotingProposal::new_parameter_change_proposal(&proposal); - to_from_test!(ParameterChangeProposal, proposal, proposal_wrapped); + let proposal = ParameterChangeAction::new_with_action_id(&action_id, ¶meters_update); + let proposal_wrapped = GovernanceAction::new_parameter_change_action(&proposal); + to_from_test!(ParameterChangeAction, proposal, proposal_wrapped); assert_eq!( proposal, - proposal_wrapped.as_parameter_change_proposal().unwrap() + proposal_wrapped.as_parameter_change_action().unwrap() ); } @@ -293,21 +293,21 @@ fn treasury_withdrawals_ser_round_trip() { } #[test] -fn treasury_withdrawals_proposal_ser_round_trip() { +fn treasury_withdrawals_action_ser_round_trip() { let mut withdrawals = TreasuryWithdrawals::new(); let addr1 = RewardAddress::new(1, &Credential::from_keyhash(&fake_key_hash(1))); let addr2 = RewardAddress::new(2, &Credential::from_keyhash(&fake_key_hash(2))); withdrawals.insert(&addr1, &Coin::from(1u32)); withdrawals.insert(&addr2, &Coin::from(2u32)); - let proposal = TreasuryWithdrawalsProposal::new(&withdrawals); + let proposal = TreasuryWithdrawalsAction::new(&withdrawals); - let proposal_wrapped = VotingProposal::new_treasury_withdrawals_proposal(&proposal); + let proposal_wrapped = GovernanceAction::new_treasury_withdrawals_action(&proposal); - to_from_test!(TreasuryWithdrawalsProposal, proposal, proposal_wrapped); + to_from_test!(TreasuryWithdrawalsAction, proposal, proposal_wrapped); assert_eq!( proposal, - proposal_wrapped.as_treasury_withdrawals_proposal().unwrap() + proposal_wrapped.as_treasury_withdrawals_action().unwrap() ); } @@ -320,15 +320,15 @@ fn voting_proposals_ser_round_trip() { withdrawals.insert(&addr1, &Coin::from(1u32)); withdrawals.insert(&addr2, &Coin::from(2u32)); - let proposal1 = TreasuryWithdrawalsProposal::new(&withdrawals); - let proposal2 = NoConfidenceProposal::new(); - let proposal3 = InfoProposal::new(); + let proposal1 = TreasuryWithdrawalsAction::new(&withdrawals); + let proposal2 = NoConfidenceAction::new(); + let proposal3 = InfoAction::new(); - proposals.add(&VotingProposal::new_treasury_withdrawals_proposal( + proposals.add(&GovernanceAction::new_treasury_withdrawals_action( &proposal1, )); - proposals.add(&VotingProposal::new_no_confidence_proposal(&proposal2)); - proposals.add(&VotingProposal::new_info_proposal(&proposal3)); + proposals.add(&GovernanceAction::new_no_confidence_action(&proposal2)); + proposals.add(&GovernanceAction::new_info_action(&proposal3)); let cbor = proposals.to_bytes(); let cbor_hex = proposals.to_hex(); From 13f6c0aa6e848e8fa588b40e26a44f827d7b0770 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 6 Oct 2023 03:47:17 +0900 Subject: [PATCH 167/349] add voting proposal --- .../governance/proposals/mod.rs | 3 + .../governance/proposals/voting_proposal.rs | 56 +++++++++++++++++++ .../serialization/governance/proposals/mod.rs | 3 + .../governance/proposals/voting_proposal.rs | 47 ++++++++++++++++ 4 files changed, 109 insertions(+) create mode 100644 rust/src/protocol_types/governance/proposals/voting_proposal.rs create mode 100644 rust/src/serialization/governance/proposals/voting_proposal.rs diff --git a/rust/src/protocol_types/governance/proposals/mod.rs b/rust/src/protocol_types/governance/proposals/mod.rs index 8a5d05a5..37b3c359 100644 --- a/rust/src/protocol_types/governance/proposals/mod.rs +++ b/rust/src/protocol_types/governance/proposals/mod.rs @@ -31,5 +31,8 @@ pub use info_action::*; mod governance_action; pub use governance_action::*; +mod voting_proposal; +pub use voting_proposal::*; + mod voting_proposals; pub use voting_proposals::*; diff --git a/rust/src/protocol_types/governance/proposals/voting_proposal.rs b/rust/src/protocol_types/governance/proposals/voting_proposal.rs new file mode 100644 index 00000000..459a0941 --- /dev/null +++ b/rust/src/protocol_types/governance/proposals/voting_proposal.rs @@ -0,0 +1,56 @@ +use crate::*; + +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +#[wasm_bindgen] +pub struct VotingProposal { + pub(crate) governance_action: GovernanceAction, + pub(crate) anchor: Anchor, + pub(crate) reward_account: RewardAddress, + pub(crate) deposit: Coin, +} + +impl_to_from!(VotingProposal); + +#[wasm_bindgen] +impl VotingProposal { + pub fn governance_action(&self) -> GovernanceAction { + self.governance_action.clone() + } + + pub fn anchor(&self) -> Anchor { + self.anchor.clone() + } + + pub fn reward_account(&self) -> RewardAddress { + self.reward_account.clone() + } + + pub fn deposit(&self) -> Coin { + self.deposit.clone() + } + + pub fn new( + governance_action: &GovernanceAction, + anchor: &Anchor, + reward_account: &RewardAddress, + deposit: &Coin, + ) -> Self { + Self { + governance_action: governance_action.clone(), + anchor: anchor.clone(), + reward_account: reward_account.clone(), + deposit: deposit.clone(), + } + } +} diff --git a/rust/src/serialization/governance/proposals/mod.rs b/rust/src/serialization/governance/proposals/mod.rs index 322dfbd5..3f3c7d47 100644 --- a/rust/src/serialization/governance/proposals/mod.rs +++ b/rust/src/serialization/governance/proposals/mod.rs @@ -28,5 +28,8 @@ pub use new_constitution_action::*; mod governance_action; pub use governance_action::*; +mod voting_proposal; +pub use voting_proposal::*; + mod voting_proposals; pub use voting_proposals::*; diff --git a/rust/src/serialization/governance/proposals/voting_proposal.rs b/rust/src/serialization/governance/proposals/voting_proposal.rs new file mode 100644 index 00000000..348bb54d --- /dev/null +++ b/rust/src/serialization/governance/proposals/voting_proposal.rs @@ -0,0 +1,47 @@ +use crate::serialization::{check_len}; +use crate::*; + +impl Serialize for VotingProposal { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(4))?; + self.deposit.serialize(serializer)?; + self.reward_account.serialize(serializer)?; + self.governance_action.serialize(serializer)?; + self.anchor.serialize(serializer)?; + Ok(serializer) + } +} + +impl_deserialize_for_wrapped_tuple!(VotingProposal); + +impl DeserializeEmbeddedGroup for VotingProposal { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + check_len( + len, + 4, + "(deposit, reward_account, gov_action, anchor)", + )?; + + let deposit = Coin::deserialize(raw) + .map_err(|e| e.annotate("deposit"))?; + let reward_account = RewardAddress::deserialize(raw) + .map_err(|e| e.annotate("reward_account"))?; + let gov_action = GovernanceAction::deserialize(raw) + .map_err(|e| e.annotate("gov_action"))?; + let anchor = Anchor::deserialize(raw) + .map_err(|e| e.annotate("anchor"))?; + + return Ok(VotingProposal { + deposit, + reward_account, + governance_action: gov_action, + anchor, + }); + } +} From 766816248d17295bda62e0faa28baf2414f389b0 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 6 Oct 2023 03:47:23 +0900 Subject: [PATCH 168/349] fix naming --- rust/src/serialization/serialization_macros.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/src/serialization/serialization_macros.rs b/rust/src/serialization/serialization_macros.rs index dd460e25..6d7623bc 100644 --- a/rust/src/serialization/serialization_macros.rs +++ b/rust/src/serialization/serialization_macros.rs @@ -147,11 +147,11 @@ macro_rules! impl_deserialize_for_wrapped_tuple { use crate::serialization::utils::check_len_indefinite; let len = raw.array()?; - let cert = Self::deserialize_as_embedded_group(raw, len)?; + let inner_struct = Self::deserialize_as_embedded_group(raw, len)?; check_len_indefinite(raw, len)?; - Ok(cert) + Ok(inner_struct) })() .map_err(|e| e.annotate(stringify!($type))) } From dfcea17b9582e4b54c007ce03d4a61db5d56818c Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 6 Oct 2023 05:54:39 +0900 Subject: [PATCH 169/349] update for new structure --- rust/src/builders/tx_builder.rs | 14 +- rust/src/builders/voting_proposal_builder.rs | 36 ++-- rust/src/fakes.rs | 8 + .../governance/proposals/voting_proposals.rs | 6 +- .../governance/proposals/voting_proposals.rs | 2 +- rust/src/tests/builders/batch_tools.rs | 13 -- rust/src/tests/builders/tx_builder.rs | 3 - .../tests/builders/voting_proposal_builder.rs | 186 ++++++++++++------ rust/src/tests/mock_objects.rs | 16 +- .../protocol_types/governance/proposals.rs | 31 +-- .../serialization/governance/proposals.rs | 41 +++- 11 files changed, 216 insertions(+), 140 deletions(-) diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index f65548ac..463a0361 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -183,7 +183,6 @@ pub struct TransactionBuilderConfig { pub(crate) fee_algo: fees::LinearFee, pub(crate) pool_deposit: Coin, // protocol parameter pub(crate) key_deposit: Coin, // protocol parameter - pub(crate) voting_proposal_deposit: Coin, // protocol parameter pub(crate) max_value_size: u32, // protocol parameter pub(crate) max_tx_size: u32, // protocol parameter pub(crate) data_cost: DataCost, // protocol parameter @@ -203,7 +202,6 @@ pub struct TransactionBuilderConfigBuilder { fee_algo: Option, pool_deposit: Option, // protocol parameter key_deposit: Option, // protocol parameter - voting_proposal_deposit: Option, // protocol parameter max_value_size: Option, // protocol parameter max_tx_size: Option, // protocol parameter data_cost: Option, // protocol parameter @@ -218,7 +216,6 @@ impl TransactionBuilderConfigBuilder { fee_algo: None, pool_deposit: None, key_deposit: None, - voting_proposal_deposit: None, max_value_size: None, max_tx_size: None, data_cost: None, @@ -287,12 +284,6 @@ impl TransactionBuilderConfigBuilder { cfg } - pub fn voting_proposal_deposit(&self, voting_proposal_deposit: &Coin) -> Self { - let mut cfg = self.clone(); - cfg.voting_proposal_deposit = Some(voting_proposal_deposit.clone()); - cfg - } - pub fn build(&self) -> Result { let cfg: Self = self.clone(); Ok(TransactionBuilderConfig { @@ -302,9 +293,6 @@ impl TransactionBuilderConfigBuilder { pool_deposit: cfg .pool_deposit .ok_or(JsError::from_str("uninitialized field: pool_deposit"))?, - voting_proposal_deposit: cfg.voting_proposal_deposit.ok_or(JsError::from_str( - "uninitialized field: voting_proposal_deposit", - ))?, key_deposit: cfg .key_deposit .ok_or(JsError::from_str("uninitialized field: key_deposit"))?, @@ -1406,7 +1394,7 @@ impl TransactionBuilder { if let Some(voting_proposal_builder) = &self.voting_proposals { total_deposit = total_deposit.checked_add( - &voting_proposal_builder.get_total_deposit(&self.config.voting_proposal_deposit)?, + &voting_proposal_builder.get_total_deposit()?, )?; } diff --git a/rust/src/builders/voting_proposal_builder.rs b/rust/src/builders/voting_proposal_builder.rs index e411abb7..ef9c7f05 100644 --- a/rust/src/builders/voting_proposal_builder.rs +++ b/rust/src/builders/voting_proposal_builder.rs @@ -4,29 +4,29 @@ use std::collections::BTreeMap; #[wasm_bindgen] #[derive(Clone, Debug)] pub struct VotingProposalBuilder { - votes: BTreeMap>, + proposals: BTreeMap>, } #[wasm_bindgen] impl VotingProposalBuilder { pub fn new() -> Self { Self { - votes: BTreeMap::new(), + proposals: BTreeMap::new(), } } - pub fn add(&mut self, proposal: &GovernanceAction) -> Result<(), JsError> { - self.votes.insert(proposal.clone(), None); + pub fn add(&mut self, proposal: &VotingProposal) -> Result<(), JsError> { + self.proposals.insert(proposal.clone(), None); Ok(()) } pub fn add_with_plutus_witness( &mut self, - proposal: &GovernanceAction, + proposal: &VotingProposal, witness: &PlutusWitness, ) -> Result<(), JsError> { - self.votes.insert( + self.proposals.insert( proposal.clone(), Some(ScriptWitnessType::PlutusScriptWitness(witness.clone())), ); @@ -36,7 +36,7 @@ impl VotingProposalBuilder { pub fn get_plutus_witnesses(&self) -> PlutusWitnesses { let tag = RedeemerTag::new_voting_proposal(); let mut scripts = PlutusWitnesses::new(); - for (i, (_, script_wit)) in self.votes.iter().enumerate() { + for (i, (_, script_wit)) in self.proposals.iter().enumerate() { if let Some(ScriptWitnessType::PlutusScriptWitness(s)) = script_wit { let index = BigNum::from(i); scripts.add(&s.clone_with_redeemer_index_and_tag(&index, &tag)); @@ -47,7 +47,7 @@ impl VotingProposalBuilder { pub fn get_ref_inputs(&self) -> TransactionInputs { let mut inputs = Vec::new(); - for (_, script_wit) in &self.votes { + for (_, script_wit) in &self.proposals { match script_wit { Some(ScriptWitnessType::NativeScriptWitness(script_source)) => { if let NativeScriptSourceEnum::RefInput(input, _, _) = script_source { @@ -68,15 +68,21 @@ impl VotingProposalBuilder { TransactionInputs(inputs) } - pub(crate) fn get_total_deposit(&self, proposal_deposit: &Coin) -> Result { - proposal_deposit - .checked_mul(&Coin::from(self.votes.len())) - .or_else(|_| Err(JsError::from_str("Overflow when calculating total deposit"))) + pub(crate) fn get_total_deposit(&self) -> Result { + self.proposals.iter().fold( + Ok(Coin::zero()), + |acc: Result, (proposal, _)| { + acc.and_then(|acc| { + acc.checked_add(&proposal.deposit) + .or_else(|_| Err(JsError::from_str("Overflow when calculating total deposit"))) + }) + }, + ) } pub(crate) fn get_used_plutus_lang_versions(&self) -> BTreeSet { let mut used_langs = BTreeSet::new(); - for (_, script_wit) in &self.votes { + for (_, script_wit) in &self.proposals { if let Some(ScriptWitnessType::PlutusScriptWitness(s)) = script_wit { if let Some(lang) = s.script.language() { used_langs.insert(lang.clone()); @@ -87,7 +93,7 @@ impl VotingProposalBuilder { } pub fn has_plutus_scripts(&self) -> bool { - for (_, script_wit) in &self.votes { + for (_, script_wit) in &self.proposals { if let Some(ScriptWitnessType::PlutusScriptWitness(_)) = script_wit { return true; } @@ -97,7 +103,7 @@ impl VotingProposalBuilder { pub fn build(&self) -> VotingProposals { let mut proposals = Vec::new(); - for (voter, _) in &self.votes { + for (voter, _) in &self.proposals { proposals.push(voter.clone()); } VotingProposals(proposals) diff --git a/rust/src/fakes.rs b/rust/src/fakes.rs index 9f72819f..dbdfbca6 100644 --- a/rust/src/fakes.rs +++ b/rust/src/fakes.rs @@ -7,6 +7,7 @@ use crate::{ Ed25519Signature, NetworkInfo, PolicyID, TransactionHash, TransactionIndex, TransactionInput, TransactionOutput, Value, Vkey, }; +use crate::address::RewardAddress; pub(crate) fn fake_bytes_32(x: u8) -> Vec { vec![ @@ -56,6 +57,13 @@ pub(crate) fn fake_base_address(x: u8) -> Address { .to_address() } +pub(crate) fn fake_reward_address(x: u8) -> RewardAddress { + RewardAddress::new( + NetworkInfo::testnet().network_id(), + &Credential::from_keyhash(&fake_key_hash(x)), + ) +} + pub(crate) fn fake_tx_hash(input_hash_byte: u8) -> TransactionHash { TransactionHash::from([input_hash_byte; 32]) } diff --git a/rust/src/protocol_types/governance/proposals/voting_proposals.rs b/rust/src/protocol_types/governance/proposals/voting_proposals.rs index 60aef69d..f7a7aa1d 100644 --- a/rust/src/protocol_types/governance/proposals/voting_proposals.rs +++ b/rust/src/protocol_types/governance/proposals/voting_proposals.rs @@ -13,7 +13,7 @@ use crate::*; JsonSchema, )] #[wasm_bindgen] -pub struct VotingProposals(pub(crate) Vec); +pub struct VotingProposals(pub(crate) Vec); impl_to_from!(VotingProposals); @@ -27,11 +27,11 @@ impl VotingProposals { self.0.len() } - pub fn get(&self, index: usize) -> GovernanceAction { + pub fn get(&self, index: usize) -> VotingProposal { self.0[index].clone() } - pub fn add(&mut self, proposal: &GovernanceAction) { + pub fn add(&mut self, proposal: &VotingProposal) { self.0.push(proposal.clone()); } } diff --git a/rust/src/serialization/governance/proposals/voting_proposals.rs b/rust/src/serialization/governance/proposals/voting_proposals.rs index 8a5c0c28..3fc2aa28 100644 --- a/rust/src/serialization/governance/proposals/voting_proposals.rs +++ b/rust/src/serialization/governance/proposals/voting_proposals.rs @@ -26,7 +26,7 @@ impl Deserialize for VotingProposals { assert_eq!(raw.special()?, CBORSpecial::Break); break; } - arr.push(GovernanceAction::deserialize(raw)?); + arr.push(VotingProposal::deserialize(raw)?); } Ok(()) })() diff --git a/rust/src/tests/builders/batch_tools.rs b/rust/src/tests/builders/batch_tools.rs index 208fad26..232e4964 100644 --- a/rust/src/tests/builders/batch_tools.rs +++ b/rust/src/tests/builders/batch_tools.rs @@ -223,7 +223,6 @@ pub fn test_big_utoxs_batch() { .max_value_size(4000) .max_tx_size(8000) .coins_per_utxo_word(&to_bignum(34_482)) - .voting_proposal_deposit(&to_bignum(500000000)) .ex_unit_prices(&ExUnitPrices::new( &SubCoin::new(&to_bignum(577), &to_bignum(10000)), &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), @@ -253,7 +252,6 @@ pub fn test_big_utoxs_ada_batch() { .max_value_size(4000) .max_tx_size(8000) .coins_per_utxo_word(&to_bignum(34_482)) - .voting_proposal_deposit(&to_bignum(500000000)) .ex_unit_prices(&ExUnitPrices::new( &SubCoin::new(&to_bignum(577), &to_bignum(10000)), &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), @@ -294,10 +292,8 @@ pub fn test_one_utxo() { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(4000) .max_tx_size(8000) - .voting_proposal_deposit(&to_bignum(500000000)) .coins_per_utxo_word(&to_bignum(34_482)) .ex_unit_prices(&ExUnitPrices::new( &SubCoin::new(&to_bignum(577), &to_bignum(10000)), @@ -363,7 +359,6 @@ pub fn test_one_utxo_one_asset_per_output() { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(80) .max_tx_size(8000) .coins_per_utxo_word(&to_bignum(34_482)) @@ -443,7 +438,6 @@ pub fn test_one_utxo_one_asset_per_tx() { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(80) .max_tx_size(300) .coins_per_utxo_word(&to_bignum(34_482)) @@ -500,7 +494,6 @@ pub fn test_only_ada_utxo() { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(4000) .max_tx_size(8000) .coins_per_utxo_word(&to_bignum(34_482)) @@ -534,7 +527,6 @@ pub fn test_not_enough_ada() { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(4000) .max_tx_size(8000) .coins_per_utxo_word(&to_bignum(34_482)) @@ -571,7 +563,6 @@ pub fn test_value_limit_error() { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(10) .max_tx_size(8000000) .coins_per_utxo_word(&to_bignum(34_482)) @@ -608,7 +599,6 @@ pub fn test_tx_limit_error() { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(100) .max_tx_size(2000) .coins_per_utxo_word(&to_bignum(34_482)) @@ -632,7 +622,6 @@ pub fn test_no_utxos() { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(10) .max_tx_size(8000000) .coins_per_utxo_word(&to_bignum(34_482)) @@ -662,7 +651,6 @@ pub fn test_script_input_error() { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(10) .max_tx_size(8000000) .coins_per_utxo_word(&to_bignum(34_482)) @@ -723,7 +711,6 @@ pub fn test_two_asset_utxo_one_ada_utxo() { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(500000000)) .key_deposit(&to_bignum(2000000)) - .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(4000) .max_tx_size(8000) .coins_per_utxo_word(&to_bignum(34_482)) diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index e4fea0be..8aa878ba 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -2457,7 +2457,6 @@ fn tx_builder_cip2_random_improve_when_using_all_available_inputs() { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(0)) .key_deposit(&to_bignum(0)) - .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(9999) .max_tx_size(9999) .coins_per_utxo_word(&Coin::zero()) @@ -2497,7 +2496,6 @@ fn tx_builder_cip2_random_improve_adds_enough_for_fees() { .fee_algo(&linear_fee) .pool_deposit(&to_bignum(0)) .key_deposit(&to_bignum(0)) - .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(9999) .max_tx_size(9999) .coins_per_utxo_word(&Coin::zero()) @@ -2822,7 +2820,6 @@ fn add_change_splits_change_into_multiple_outputs_when_nfts_overflow_output_size .fee_algo(&linear_fee) .pool_deposit(&to_bignum(0)) .key_deposit(&to_bignum(0)) - .voting_proposal_deposit(&to_bignum(500000000)) .max_value_size(max_value_size) .max_tx_size(MAX_TX_SIZE) .coins_per_utxo_word(&to_bignum(8)) diff --git a/rust/src/tests/builders/voting_proposal_builder.rs b/rust/src/tests/builders/voting_proposal_builder.rs index 0d06fc2a..e570e82a 100644 --- a/rust/src/tests/builders/voting_proposal_builder.rs +++ b/rust/src/tests/builders/voting_proposal_builder.rs @@ -1,5 +1,5 @@ use crate::*; -use crate::fakes::{fake_key_hash, fake_script_hash, fake_tx_hash}; +use crate::fakes::{fake_key_hash, fake_reward_address, fake_script_hash, fake_tx_hash}; use crate::tests::mock_objects::{crate_full_protocol_param_update, create_anchor, create_change_address, create_plutus_script, create_tx_builder_with_amount_and_deposit_params}; fn total_tx_output_with_fee(tx: &Transaction) -> Coin { @@ -15,11 +15,17 @@ fn total_tx_output_with_fee(tx: &Transaction) -> Coin { fn voting_proposal_builder_one_proposal() { let proposal_deposit = Coin::from(1000u64); let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); - let proposal = + let action = HardForkInitiationAction::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); let mut builder = VotingProposalBuilder::new(); - let wrapped_proposal = GovernanceAction::new_hard_fork_initiation_action(&proposal); - builder.add(&wrapped_proposal).unwrap(); + let wrapped_action = GovernanceAction::new_hard_fork_initiation_action(&action); + let proposal = VotingProposal::new( + &wrapped_action, + &create_anchor(), + &fake_reward_address(1), + &proposal_deposit, + ); + builder.add(&proposal).unwrap(); let witnesses = builder.get_plutus_witnesses(); assert_eq!(witnesses.len(), 0); @@ -28,14 +34,13 @@ fn voting_proposal_builder_one_proposal() { assert_eq!(inputs.len(), 0); assert_eq!(builder.has_plutus_scripts(), false); - assert_eq!(builder.get_total_deposit(&proposal_deposit).unwrap(), proposal_deposit.clone()); + assert_eq!(builder.get_total_deposit().unwrap(), proposal_deposit.clone()); let initial_amount = 1000000000u64; let mut tx_builder = create_tx_builder_with_amount_and_deposit_params( initial_amount, 500, 500, - proposal_deposit.into(), false); tx_builder.set_voting_proposal_builder(&builder); @@ -45,7 +50,7 @@ fn voting_proposal_builder_one_proposal() { let voting_proposals = tx.body().voting_proposals().unwrap(); assert_eq!(voting_proposals.len(), 1); - assert_eq!(voting_proposals.get(0), wrapped_proposal); + assert_eq!(voting_proposals.get(0), proposal); let mut total_out = total_tx_output_with_fee(&tx); total_out = total_out.checked_add(&proposal_deposit).unwrap(); @@ -58,46 +63,88 @@ fn voting_proposal_builder_all_proposals() { let total_deposit = proposal_deposit.checked_mul(&Coin::from(7u64)).unwrap(); let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); - let hf_proposal = + let hf_action = HardForkInitiationAction::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); let mut builder = VotingProposalBuilder::new(); - let wrapped_hf_proposal = GovernanceAction::new_hard_fork_initiation_action(&hf_proposal); - builder.add(&wrapped_hf_proposal).unwrap(); + let wrapped_hf_action = GovernanceAction::new_hard_fork_initiation_action(&hf_action); + let hf_proposal = VotingProposal::new( + &wrapped_hf_action, + &create_anchor(), + &fake_reward_address(1), + &proposal_deposit, + ); + builder.add(&hf_proposal).unwrap(); let mut committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); - let committee_proposal = UpdateCommitteeAction::new(&committee, &members_to_remove); - let wrapped_committee_proposal = GovernanceAction::new_new_committee_action(&committee_proposal); - builder.add(&wrapped_committee_proposal).unwrap(); + let committee_action = UpdateCommitteeAction::new(&committee, &members_to_remove); + let wrapped_committee_action = GovernanceAction::new_new_committee_action(&committee_action); + let committee_proposal = VotingProposal::new( + &wrapped_committee_action, + &create_anchor(), + &fake_reward_address(2), + &proposal_deposit, + ); + builder.add(&committee_proposal).unwrap(); let anchor = create_anchor(); let constitution = Constitution::new(&anchor); - let constitution_proposal = NewConstitutionAction::new(&constitution); - let wrapped_constitution_proposal = GovernanceAction::new_new_constitution_action(&constitution_proposal); - builder.add(&wrapped_constitution_proposal).unwrap(); - - let no_conf_proposal = NoConfidenceAction::new(); - let wrapped_no_conf_proposal = GovernanceAction::new_no_confidence_action(&no_conf_proposal); - builder.add(&wrapped_no_conf_proposal).unwrap(); + let constitution_action = NewConstitutionAction::new(&constitution); + let wrapped_constitution_action = GovernanceAction::new_new_constitution_action(&constitution_action); + let constitution_proposal = VotingProposal::new( + &wrapped_constitution_action, + &create_anchor(), + &fake_reward_address(3), + &proposal_deposit, + ); + builder.add(&constitution_proposal).unwrap(); + + let no_conf_action = NoConfidenceAction::new(); + let wrapped_no_conf_action = GovernanceAction::new_no_confidence_action(&no_conf_action); + let no_conf_proposal = VotingProposal::new( + &wrapped_no_conf_action, + &create_anchor(), + &fake_reward_address(4), + &proposal_deposit, + ); + builder.add(&no_conf_proposal).unwrap(); let parameters_update = crate_full_protocol_param_update(); - let pp_update_proposal = ParameterChangeAction::new(¶meters_update); - let wrapped_pp_update_proposal = GovernanceAction::new_parameter_change_action(&pp_update_proposal); - builder.add(&wrapped_pp_update_proposal).unwrap(); + let pp_update_action = ParameterChangeAction::new(¶meters_update); + let wrapped_pp_update_action = GovernanceAction::new_parameter_change_action(&pp_update_action); + let pp_update_proposal = VotingProposal::new( + &wrapped_pp_update_action, + &create_anchor(), + &fake_reward_address(4), + &proposal_deposit, + ); + builder.add(&pp_update_proposal).unwrap(); let mut withdrawals = TreasuryWithdrawals::new(); let addr1 = RewardAddress::new(1, &Credential::from_keyhash(&fake_key_hash(1))); withdrawals.insert(&addr1, &Coin::from(1u32)); - let withdrawal_proposal = TreasuryWithdrawalsAction::new(&withdrawals); - let wrapped_withdrawal_proposal = GovernanceAction::new_treasury_withdrawals_action(&withdrawal_proposal); - builder.add(&wrapped_withdrawal_proposal).unwrap(); - - let info_proposal = InfoAction::new(); - let wrapped_info_proposal = GovernanceAction::new_info_action(&info_proposal); - builder.add(&wrapped_info_proposal).unwrap(); + let withdrawal_action = TreasuryWithdrawalsAction::new(&withdrawals); + let wrapped_withdrawal_action = GovernanceAction::new_treasury_withdrawals_action(&withdrawal_action); + let withdrawal_proposal = VotingProposal::new( + &wrapped_withdrawal_action, + &create_anchor(), + &fake_reward_address(5), + &proposal_deposit, + ); + builder.add(&withdrawal_proposal).unwrap(); + + let info_action = InfoAction::new(); + let wrapped_info_action = GovernanceAction::new_info_action(&info_action); + let info_proposal = VotingProposal::new( + &wrapped_info_action, + &create_anchor(), + &fake_reward_address(5), + &proposal_deposit, + ); + builder.add(&info_proposal).unwrap(); let witnesses = builder.get_plutus_witnesses(); assert_eq!(witnesses.len(), 0); @@ -106,14 +153,13 @@ fn voting_proposal_builder_all_proposals() { assert_eq!(inputs.len(), 0); assert_eq!(builder.has_plutus_scripts(), false); - assert_eq!(builder.get_total_deposit(&proposal_deposit).unwrap(), total_deposit.clone()); + assert_eq!(builder.get_total_deposit().unwrap(), total_deposit.clone()); let initial_amount = 1000000000u64; let mut tx_builder = create_tx_builder_with_amount_and_deposit_params( initial_amount, 500, 500, - proposal_deposit.into(), false); tx_builder.set_voting_proposal_builder(&builder); @@ -123,13 +169,13 @@ fn voting_proposal_builder_all_proposals() { let voting_proposals = tx.body().voting_proposals().unwrap(); assert_eq!(voting_proposals.len(), 7); - assert!(voting_proposals.0.contains(&wrapped_hf_proposal)); - assert!(voting_proposals.0.contains(&wrapped_committee_proposal)); - assert!(voting_proposals.0.contains(&wrapped_constitution_proposal)); - assert!(voting_proposals.0.contains(&wrapped_no_conf_proposal)); - assert!(voting_proposals.0.contains(&wrapped_pp_update_proposal)); - assert!(voting_proposals.0.contains(&wrapped_withdrawal_proposal)); - assert!(voting_proposals.0.contains(&wrapped_info_proposal)); + assert!(voting_proposals.0.contains(&hf_proposal)); + assert!(voting_proposals.0.contains(&committee_proposal)); + assert!(voting_proposals.0.contains(&constitution_proposal)); + assert!(voting_proposals.0.contains(&no_conf_proposal)); + assert!(voting_proposals.0.contains(&pp_update_proposal)); + assert!(voting_proposals.0.contains(&withdrawal_proposal)); + assert!(voting_proposals.0.contains(&info_proposal)); let mut total_out = total_tx_output_with_fee(&tx); total_out = total_out.checked_add(&total_deposit).unwrap(); @@ -142,11 +188,17 @@ fn voting_proposal_builder_with_plutus_script_witness() { let total_deposit = proposal_deposit.checked_mul(&Coin::from(2u64)).unwrap(); let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); - let hf_proposal = + let hf_action = HardForkInitiationAction::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); let mut builder = VotingProposalBuilder::new(); - let wrapped_hf_proposal = GovernanceAction::new_hard_fork_initiation_action(&hf_proposal); - builder.add(&wrapped_hf_proposal).unwrap(); + let wrapped_hf_action = GovernanceAction::new_hard_fork_initiation_action(&hf_action); + let hf_proposal = VotingProposal::new( + &wrapped_hf_action, + &create_anchor(), + &fake_reward_address(1), + &proposal_deposit, + ); + builder.add(&hf_proposal).unwrap(); let script = create_plutus_script(1, &Language::new_plutus_v2()); let redeemer = Redeemer::new( @@ -167,9 +219,15 @@ fn voting_proposal_builder_with_plutus_script_witness() { committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); - let committee_proposal = UpdateCommitteeAction::new(&committee, &members_to_remove); - let wrapped_committee_proposal = GovernanceAction::new_new_committee_action(&committee_proposal); - builder.add_with_plutus_witness(&wrapped_committee_proposal, &plutus_witness).unwrap(); + let committee_action = UpdateCommitteeAction::new(&committee, &members_to_remove); + let wrapped_committee_action = GovernanceAction::new_new_committee_action(&committee_action); + let committee_proposal = VotingProposal::new( + &wrapped_committee_action, + &create_anchor(), + &fake_reward_address(2), + &proposal_deposit, + ); + builder.add_with_plutus_witness(&committee_proposal, &plutus_witness).unwrap(); let witnesses = builder.get_plutus_witnesses(); assert_eq!(witnesses.len(), 1); @@ -183,14 +241,13 @@ fn voting_proposal_builder_with_plutus_script_witness() { assert_eq!(inputs.len(), 0); assert_eq!(builder.has_plutus_scripts(), true); - assert_eq!(builder.get_total_deposit(&proposal_deposit).unwrap(), total_deposit.clone()); + assert_eq!(builder.get_total_deposit().unwrap(), total_deposit.clone()); let initial_amount = 1000000000u64; let mut tx_builder = create_tx_builder_with_amount_and_deposit_params( initial_amount, 500, 500, - proposal_deposit.into(), true); tx_builder.set_voting_proposal_builder(&builder); @@ -205,8 +262,8 @@ fn voting_proposal_builder_with_plutus_script_witness() { let voting_proposals = tx.body().voting_proposals().unwrap(); assert_eq!(voting_proposals.len(), 2); - assert!(voting_proposals.0.contains(&wrapped_hf_proposal)); - assert!(voting_proposals.0.contains(&wrapped_committee_proposal)); + assert!(voting_proposals.0.contains(&hf_proposal)); + assert!(voting_proposals.0.contains(&committee_proposal)); let mut total_out = total_tx_output_with_fee(&tx); total_out = total_out.checked_add(&total_deposit).unwrap(); @@ -237,11 +294,17 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { let total_deposit = proposal_deposit.checked_mul(&Coin::from(2u64)).unwrap(); let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); - let hf_proposal = + let hf_action = HardForkInitiationAction::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); let mut builder = VotingProposalBuilder::new(); - let wrapped_hf_proposal = GovernanceAction::new_hard_fork_initiation_action(&hf_proposal); - builder.add(&wrapped_hf_proposal).unwrap(); + let wrapped_hf_action = GovernanceAction::new_hard_fork_initiation_action(&hf_action); + let hf_proposal = VotingProposal::new( + &wrapped_hf_action, + &create_anchor(), + &fake_reward_address(1), + &proposal_deposit, + ); + builder.add(&hf_proposal).unwrap(); let script_hash = fake_script_hash(1); let ref_input = TransactionInput::new(&fake_tx_hash(5), 0); @@ -264,9 +327,15 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); - let committee_proposal = UpdateCommitteeAction::new(&committee, &members_to_remove); - let wrapped_committee_proposal = GovernanceAction::new_new_committee_action(&committee_proposal); - builder.add_with_plutus_witness(&wrapped_committee_proposal, &plutus_witness).unwrap(); + let committee_action = UpdateCommitteeAction::new(&committee, &members_to_remove); + let wrapped_committee_action= GovernanceAction::new_new_committee_action(&committee_action); + let committee_proposal = VotingProposal::new( + &wrapped_committee_action, + &create_anchor(), + &fake_reward_address(2), + &proposal_deposit, + ); + builder.add_with_plutus_witness(&committee_proposal, &plutus_witness).unwrap(); let witnesses = builder.get_plutus_witnesses(); assert_eq!(witnesses.len(), 1); @@ -281,14 +350,13 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { assert_eq!(builder_ref_inputs.get(0), ref_input); assert_eq!(builder.has_plutus_scripts(), true); - assert_eq!(builder.get_total_deposit(&proposal_deposit).unwrap(), total_deposit.clone()); + assert_eq!(builder.get_total_deposit().unwrap(), total_deposit.clone()); let initial_amount = 1000000000u64; let mut tx_builder = create_tx_builder_with_amount_and_deposit_params( initial_amount, 500, 500, - proposal_deposit.into(), true); tx_builder.set_voting_proposal_builder(&builder); @@ -303,8 +371,8 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { let voting_proposals = tx.body().voting_proposals().unwrap(); assert_eq!(voting_proposals.len(), 2); - assert!(voting_proposals.0.contains(&wrapped_hf_proposal)); - assert!(voting_proposals.0.contains(&wrapped_committee_proposal)); + assert!(voting_proposals.0.contains(&hf_proposal)); + assert!(voting_proposals.0.contains(&committee_proposal)); let mut total_out = total_tx_output_with_fee(&tx); total_out = total_out.checked_add(&total_deposit).unwrap(); diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/mock_objects.rs index a9bf1771..842b256f 100644 --- a/rust/src/tests/mock_objects.rs +++ b/rust/src/tests/mock_objects.rs @@ -156,7 +156,6 @@ pub(crate) fn create_tx_builder_full( linear_fee: &LinearFee, pool_deposit: u64, key_deposit: u64, - voting_proposal_deposit: u64, max_val_size: u32, coins_per_utxo_word: u64, ) -> TransactionBuilder { @@ -164,7 +163,6 @@ pub(crate) fn create_tx_builder_full( .fee_algo(linear_fee) .pool_deposit(&to_bignum(pool_deposit)) .key_deposit(&to_bignum(key_deposit)) - .voting_proposal_deposit(&to_bignum(voting_proposal_deposit)) .max_value_size(max_val_size) .max_tx_size(MAX_TX_SIZE) .coins_per_utxo_word(&to_bignum(coins_per_utxo_word)) @@ -182,13 +180,11 @@ pub(crate) fn create_tx_builder( coins_per_utxo_word: u64, pool_deposit: u64, key_deposit: u64, - voting_proposal_deposit: u64, ) -> TransactionBuilder { create_tx_builder_full( linear_fee, pool_deposit, key_deposit, - voting_proposal_deposit, MAX_VALUE_SIZE, coins_per_utxo_word, ) @@ -200,7 +196,6 @@ pub(crate) fn create_reallistic_tx_builder() -> TransactionBuilder { COINS_PER_UTXO_WORD, 500000000, 2000000, - 500000000, ) } @@ -208,11 +203,11 @@ pub(crate) fn create_tx_builder_with_fee_and_val_size( linear_fee: &LinearFee, max_val_size: u32, ) -> TransactionBuilder { - create_tx_builder_full(linear_fee, 1, 1, 1, max_val_size, 8) + create_tx_builder_full(linear_fee, 1, 1, max_val_size, 8) } pub(crate) fn create_tx_builder_with_fee(linear_fee: &LinearFee) -> TransactionBuilder { - create_tx_builder(linear_fee, 8, 1, 1, 1) + create_tx_builder(linear_fee, 8, 1, 1) } pub(crate) fn create_tx_builder_with_fee_and_pure_change( @@ -223,7 +218,6 @@ pub(crate) fn create_tx_builder_with_fee_and_pure_change( .fee_algo(linear_fee) .pool_deposit(&to_bignum(1)) .key_deposit(&to_bignum(1)) - .voting_proposal_deposit(&to_bignum(1)) .max_value_size(MAX_VALUE_SIZE) .max_tx_size(MAX_TX_SIZE) .coins_per_utxo_word(&to_bignum(8)) @@ -234,7 +228,7 @@ pub(crate) fn create_tx_builder_with_fee_and_pure_change( } pub(crate) fn create_tx_builder_with_key_deposit(deposit: u64) -> TransactionBuilder { - create_tx_builder(&create_default_linear_fee(), 8, 1, deposit, 1) + create_tx_builder(&create_default_linear_fee(), 8, 1, deposit) } pub(crate) fn create_default_tx_builder() -> TransactionBuilder { @@ -304,15 +298,13 @@ pub(crate) fn create_tx_builder_with_amount_and_deposit_params( amount: u64, pool_deposit: u64, key_deposit: u64, - voting_proposal_deposit: u64, with_collateral: bool, ) -> TransactionBuilder { let mut tx_builder = create_tx_builder( &create_linear_fee(44, 155381), COINS_PER_UTXO_WORD, pool_deposit, - key_deposit, - voting_proposal_deposit, + key_deposit ); let input = TransactionInput::new(&fake_tx_hash(1), 0); let address = generate_address(1); diff --git a/rust/src/tests/protocol_types/governance/proposals.rs b/rust/src/tests/protocol_types/governance/proposals.rs index 3ab8e6b9..0cf6a8ef 100644 --- a/rust/src/tests/protocol_types/governance/proposals.rs +++ b/rust/src/tests/protocol_types/governance/proposals.rs @@ -1,4 +1,4 @@ -use crate::fakes::{fake_key_hash, fake_script_hash}; +use crate::fakes::{fake_key_hash, fake_reward_address, fake_script_hash}; use crate::tests::mock_objects::{ crate_full_protocol_param_update, create_action_id, create_anchor, }; @@ -150,22 +150,31 @@ fn treasury_withdrawals_action() { #[test] fn voting_proposals_setters_getters_test() { let mut proposals = VotingProposals::new(); - let no_confidence_proposal = NoConfidenceAction::new(); - let parameter_change_proposal = + let no_confidence_action = NoConfidenceAction::new(); + let parameter_change_action = ParameterChangeAction::new(&crate_full_protocol_param_update()); - proposals.add(&GovernanceAction::new_no_confidence_action( - &no_confidence_proposal, - )); - proposals.add(&GovernanceAction::new_parameter_change_action( - ¶meter_change_proposal, - )); + + let proposal1 = VotingProposal::new( + &GovernanceAction::new_no_confidence_action(&no_confidence_action), + &create_anchor(), + &fake_reward_address(1), + &Coin::from(100u32), + ); + let proposal2 = VotingProposal::new( + &GovernanceAction::new_parameter_change_action(¶meter_change_action), + &create_anchor(), + &fake_reward_address(2), + &Coin::from(100u32), + ); + proposals.add(&proposal1); + proposals.add(&proposal2); assert_eq!(proposals.len(), 2); assert_eq!( proposals.get(0), - GovernanceAction::new_no_confidence_action(&no_confidence_proposal) + proposal1 ); assert_eq!( proposals.get(1), - GovernanceAction::new_parameter_change_action(¶meter_change_proposal) + proposal2 ); } \ No newline at end of file diff --git a/rust/src/tests/serialization/governance/proposals.rs b/rust/src/tests/serialization/governance/proposals.rs index e0c2c520..8c818374 100644 --- a/rust/src/tests/serialization/governance/proposals.rs +++ b/rust/src/tests/serialization/governance/proposals.rs @@ -1,5 +1,7 @@ -use crate::fakes::{fake_anchor_data_hash, fake_key_hash, fake_script_hash, fake_tx_hash}; -use crate::tests::mock_objects::crate_full_protocol_param_update; +use crate::fakes::{ + fake_anchor_data_hash, fake_key_hash, fake_reward_address, fake_script_hash, fake_tx_hash, +}; +use crate::tests::mock_objects::{crate_full_protocol_param_update, create_anchor}; use crate::*; macro_rules! to_from_test { @@ -320,15 +322,34 @@ fn voting_proposals_ser_round_trip() { withdrawals.insert(&addr1, &Coin::from(1u32)); withdrawals.insert(&addr2, &Coin::from(2u32)); - let proposal1 = TreasuryWithdrawalsAction::new(&withdrawals); - let proposal2 = NoConfidenceAction::new(); - let proposal3 = InfoAction::new(); + let action1 = GovernanceAction::new_treasury_withdrawals_action( + &TreasuryWithdrawalsAction::new(&withdrawals), + ); + let action2 = GovernanceAction::new_no_confidence_action(&NoConfidenceAction::new()); + let action3 = GovernanceAction::new_info_action(&InfoAction::new()); + + let proposal1 = VotingProposal::new( + &action1, + &create_anchor(), + &fake_reward_address(1), + &Coin::from(100u32), + ); + let proposal2 = VotingProposal::new( + &action2, + &create_anchor(), + &fake_reward_address(2), + &Coin::from(200u32), + ); + let proposal3 = VotingProposal::new( + &action3, + &create_anchor(), + &fake_reward_address(3), + &Coin::from(300u32), + ); - proposals.add(&GovernanceAction::new_treasury_withdrawals_action( - &proposal1, - )); - proposals.add(&GovernanceAction::new_no_confidence_action(&proposal2)); - proposals.add(&GovernanceAction::new_info_action(&proposal3)); + proposals.add(&proposal1); + proposals.add(&proposal2); + proposals.add(&proposal3); let cbor = proposals.to_bytes(); let cbor_hex = proposals.to_hex(); From 6beb5ca913ad0974692a49f3836ce6756e612e0c Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 6 Oct 2023 06:16:16 +0900 Subject: [PATCH 170/349] add deserialization tests --- rust/src/tests/serialization/certificates.rs | 18 ++++++++ .../tests/serialization/governance/common.rs | 18 ++++++++ .../serialization/governance/proposals.rs | 42 +++++++++++++++++++ 3 files changed, 78 insertions(+) diff --git a/rust/src/tests/serialization/certificates.rs b/rust/src/tests/serialization/certificates.rs index 3a51aea6..de70eda0 100644 --- a/rust/src/tests/serialization/certificates.rs +++ b/rust/src/tests/serialization/certificates.rs @@ -349,3 +349,21 @@ fn vote_registration_and_delegation_ser_round_trip() { cert_wrapped.as_vote_registration_and_delegation().unwrap() ); } + +#[test] +fn tx_with_drep_reg_deser_test() { + let cbor = "84a4008182582038e88b8b95dc13639c2c0adc6a159316bd795da6672d4025f5f2bc50f122438f010181a20058390013ca2480e9651a5c504b36eda271ec171cdd404cfe349097524a48bd8bee57ce33c7c1f711bc5801986d89dd68078f5922b83812cc86f65f011b0000000253f7736e021a00029d59048184108200581c1033bbc7db733c057fed63fa085113dfb570566eb708d548d2f7cce800f6a1008182582072fe72c3f2506a2b88cf9c6388535d98f90d481aa734e0e3553792cb9984ffcc5840509a64b3e450f8b338ba3f759e8cf91273493d425a027a7373071c166de6ab83ed3af6b98415c6372906aeaba9269ecf1c40dccbebf8050b4e9ad5e2a5346503f5f6"; + let tx_deser = Transaction::from_hex(cbor); + assert!(tx_deser.is_ok()); + let cert = tx_deser.unwrap().body().certs().unwrap().get(0); + assert!(cert.as_drep_registration().is_some()); +} + +#[test] +fn tx_with_drep_reg_deleg_test() { + let cbor = "84a400818258201e3f301eee4c02377c137eff0260a33b67ea421e3524ce8818e4c5184fa440d2000181a2005839002d745f050a8f7e263f4d0749a82284ed9cc065018c1f4f6a7c1b764882293a49e3ef29a4f9c32e4c18f202f5324182db7790f48dccf7a6dd011b0000000253e3e5ad021a0002a281048183098200581c82293a49e3ef29a4f9c32e4c18f202f5324182db7790f48dccf7a6dd8200581c1033bbc7db733c057fed63fa085113dfb570566eb708d548d2f7cce8a0f5f6"; + let tx_deser = Transaction::from_hex(cbor); + assert!(tx_deser.is_ok()); + let cert = tx_deser.unwrap().body().certs().unwrap().get(0); + assert!(cert.as_vote_delegation().is_some()); +} diff --git a/rust/src/tests/serialization/governance/common.rs b/rust/src/tests/serialization/governance/common.rs index 35b2745c..6d4be55b 100644 --- a/rust/src/tests/serialization/governance/common.rs +++ b/rust/src/tests/serialization/governance/common.rs @@ -284,3 +284,21 @@ fn voting_procedures_muiltiple_items_ser_round_trip() { VotingProcedures::from_json(&json).unwrap() ); } + +#[test] +fn tx_with_vote_deser_test() { + let cbor = "84a400818258204547c077e8f3a9184438e36503f78b634eb416658c336c2d017d9912a7c493c7000181a20058390013ca2480e9651a5c504b36eda271ec171cdd404cfe349097524a48bd8bee57ce33c7c1f711bc5801986d89dd68078f5922b83812cc86f65f011b0000000253d3ae64021a0002a38913a18202581c1033bbc7db733c057fed63fa085113dfb570566eb708d548d2f7cce8a1825820787142668a73c7c3ca6003571f429393f2d6dad8886bbcd0a9ba7aca07cc895e008201f6a0f5f6"; + let tx_deser = Transaction::from_hex(cbor); + assert!(tx_deser.is_ok()); + let tx = tx_deser.unwrap(); + let procedures = tx.body().voting_procedures().unwrap(); + assert_eq!(procedures.0.len(), 1); + + let voter = procedures.get_voters().get(0).unwrap(); + let gov_action_ids = procedures.get_governance_action_ids_by_voter(&voter); + assert_eq!(gov_action_ids.0.len(), 1); + let gov_action_id = gov_action_ids.get(0).unwrap(); + let voting_procedure = procedures.get(&voter, &gov_action_id); + assert!(voting_procedure.is_some()); +} + diff --git a/rust/src/tests/serialization/governance/proposals.rs b/rust/src/tests/serialization/governance/proposals.rs index 8c818374..b3e7aeb9 100644 --- a/rust/src/tests/serialization/governance/proposals.rs +++ b/rust/src/tests/serialization/governance/proposals.rs @@ -359,3 +359,45 @@ fn voting_proposals_ser_round_trip() { assert_eq!(proposals, VotingProposals::from_hex(&cbor_hex).unwrap()); assert_eq!(proposals, VotingProposals::from_json(&json).unwrap()); } + +#[test] +fn voting_proposal_round_trip_test() +{ + let mut withdrawals = TreasuryWithdrawals::new(); + let addr1 = RewardAddress::new(1, &Credential::from_keyhash(&fake_key_hash(1))); + let addr2 = RewardAddress::new(2, &Credential::from_keyhash(&fake_key_hash(2))); + withdrawals.insert(&addr1, &Coin::from(1u32)); + withdrawals.insert(&addr2, &Coin::from(2u32)); + + let action1 = GovernanceAction::new_treasury_withdrawals_action( + &TreasuryWithdrawalsAction::new(&withdrawals), + ); + + let proposal = VotingProposal::new( + &action1, + &create_anchor(), + &fake_reward_address(1), + &Coin::from(100u32), + ); + + let cbor = proposal.to_bytes(); + let cbor_hex = proposal.to_hex(); + let json = proposal.to_json().unwrap(); + + assert_eq!(proposal, VotingProposal::from_bytes(cbor).unwrap()); + assert_eq!(proposal, VotingProposal::from_hex(&cbor_hex).unwrap()); + assert_eq!(proposal, VotingProposal::from_json(&json).unwrap()); +} + +#[test] +fn tx_with_voting_proposal_deser_test() { + let cbor = "84a40081825820017b91576a79a3602a02a65b600665ab71037ad14aa162538a26e64b3f5069fc000181a2005839002d745f050a8f7e263f4d0749a82284ed9cc065018c1f4f6a7c1b764882293a49e3ef29a4f9c32e4c18f202f5324182db7790f48dccf7a6dd011b0000000253d1efbc021a0002b3b11481841a000f4240581de082293a49e3ef29a4f9c32e4c18f202f5324182db7790f48dccf7a6dd8305f68282781968747470733a2f2f73686f727475726c2e61742f6173494a365820ee90ece16c47bf812b88edb89a01539e6683d6549a80b15383a4fb218ab9412df682781968747470733a2f2f73686f727475726c2e61742f784d53313558206f890de0c6e418e6526e2b1aa821850cb87aee94a6d77dc2a2e440116abc8e09a0f5f6"; + let tx_deser = Transaction::from_hex(cbor); + assert!(tx_deser.is_ok()); + + let proposals = tx_deser.unwrap().body().voting_proposals(); + assert!(proposals.is_some()); + let proposal = proposals.unwrap().get(0); + let expected_coin = Coin::from(1000000u32); + assert_eq!(proposal.deposit(), expected_coin); +} \ No newline at end of file From 09747a8530917434fb70489c4e46dff0a9bb6076 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 6 Oct 2023 06:19:33 +0900 Subject: [PATCH 171/349] update json gen --- rust/json-gen/src/main.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/rust/json-gen/src/main.rs b/rust/json-gen/src/main.rs index 98b56858..ed971ed7 100644 --- a/rust/json-gen/src/main.rs +++ b/rust/json-gen/src/main.rs @@ -177,13 +177,14 @@ fn main() { gen_json_schema!(VotingProposal); gen_json_schema!(VotingProposals); - gen_json_schema!(HardForkInitiationProposal); - gen_json_schema!(UpdateCommitteeProposal); - gen_json_schema!(NewConstitutionProposal); - gen_json_schema!(NoConfidenceProposal); - gen_json_schema!(ParameterChangeProposal); + gen_json_schema!(GovernanceAction); + gen_json_schema!(HardForkInitiationAction); + gen_json_schema!(UpdateCommitteeAction); + gen_json_schema!(NewConstitutionAction); + gen_json_schema!(NoConfidenceAction); + gen_json_schema!(ParameterChangeAction); gen_json_schema!(TreasuryWithdrawals); - gen_json_schema!(TreasuryWithdrawalsProposal); + gen_json_schema!(TreasuryWithdrawalsAction); gen_json_schema!(Committee); gen_json_schema!(Constitution); } From b7bb0a1c104a9e55bc2060d97624a4be92019b72 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 6 Oct 2023 06:26:39 +0900 Subject: [PATCH 172/349] fix test --- rust/src/tests/serialization/transaction_body.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/rust/src/tests/serialization/transaction_body.rs b/rust/src/tests/serialization/transaction_body.rs index 8b08aebc..b4c9fc0f 100644 --- a/rust/src/tests/serialization/transaction_body.rs +++ b/rust/src/tests/serialization/transaction_body.rs @@ -1,8 +1,6 @@ -use crate::fakes::{ - fake_asset_name, fake_auxiliary_data_hash, fake_base_address, fake_key_hash, fake_policy_id, - fake_script_data_hash, fake_tx_hash, fake_tx_input, -}; +use crate::fakes::{fake_asset_name, fake_auxiliary_data_hash, fake_base_address, fake_key_hash, fake_policy_id, fake_reward_address, fake_script_data_hash, fake_tx_hash, fake_tx_input}; use crate::*; +use crate::tests::mock_objects::create_anchor; #[test] fn transaction_round_trip_test() { @@ -47,8 +45,14 @@ fn transaction_round_trip_test() { voting_procedures.insert(&voter, &gov_action_id, &procedure); let mut voting_proposals = VotingProposals::new(); - let info_proposal = InfoProposal::new(); - let proposal = VotingProposal::new_info_proposal(&info_proposal); + let info_action = InfoAction::new(); + let action = GovernanceAction::new_info_action(&info_action); + let proposal = VotingProposal::new( + &action, + &create_anchor(), + &fake_reward_address(3), + &Coin::from(1_000_011u64), + ); voting_proposals.add(&proposal); body.set_ttl(&to_bignum(1_000_003u64)); From c69fd8b991b568ddaa21d217339b89965c33e192 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 6 Oct 2023 06:31:33 +0900 Subject: [PATCH 173/349] flow update --- rust/pkg/cardano_serialization_lib.js.flow | 539 ++++++++++++--------- 1 file changed, 307 insertions(+), 232 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 226dbd27..56666904 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -262,6 +262,22 @@ declare export function decode_metadatum_to_json_str( schema: number ): string; +/** + */ + +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 +|}; + +/** + */ + +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 +|}; + /** */ @@ -386,14 +402,14 @@ declare export var CertificateKind: {| /** */ -declare export var VotingProposalKind: {| - +ParameterChangeProposal: 0, // 0 - +HardForkInitiationProposal: 1, // 1 - +TreasuryWithdrawalsProposal: 2, // 2 - +NoConfidenceProposal: 3, // 3 - +UpdateCommitteeProposal: 4, // 4 - +NewConstitutionProposal: 5, // 5 - +InfoProposal: 6, // 6 +declare export var GovernanceActionKind: {| + +ParameterChangeAction: 0, // 0 + +HardForkInitiationAction: 1, // 1 + +TreasuryWithdrawalsAction: 2, // 2 + +NoConfidenceAction: 3, // 3 + +UpdateCommitteeAction: 4, // 4 + +NewConstitutionAction: 5, // 5 + +InfoAction: 6, // 6 |}; /** @@ -475,22 +491,6 @@ declare export var CoinSelectionStrategyCIP2: {| +RandomImproveMultiAsset: 3, // 3 |}; -/** - */ - -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 -|}; - -/** - */ - -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 -|}; - /** */ declare export class Address { @@ -4083,6 +4083,143 @@ declare export class GenesisKeyDelegation { vrf_keyhash: VRFKeyHash ): GenesisKeyDelegation; } +/** + */ +declare export class GovernanceAction { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {GovernanceAction} + */ + static from_bytes(bytes: Uint8Array): GovernanceAction; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {GovernanceAction} + */ + static from_hex(hex_str: string): GovernanceAction; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {GovernanceActionJSON} + */ + to_js_value(): GovernanceActionJSON; + + /** + * @param {string} json + * @returns {GovernanceAction} + */ + static from_json(json: string): GovernanceAction; + + /** + * @param {ParameterChangeAction} parameter_change_action + * @returns {GovernanceAction} + */ + static new_parameter_change_action( + parameter_change_action: ParameterChangeAction + ): GovernanceAction; + + /** + * @param {HardForkInitiationAction} hard_fork_initiation_action + * @returns {GovernanceAction} + */ + static new_hard_fork_initiation_action( + hard_fork_initiation_action: HardForkInitiationAction + ): GovernanceAction; + + /** + * @param {TreasuryWithdrawalsAction} treasury_withdrawals_action + * @returns {GovernanceAction} + */ + static new_treasury_withdrawals_action( + treasury_withdrawals_action: TreasuryWithdrawalsAction + ): GovernanceAction; + + /** + * @param {NoConfidenceAction} no_confidence_action + * @returns {GovernanceAction} + */ + static new_no_confidence_action( + no_confidence_action: NoConfidenceAction + ): GovernanceAction; + + /** + * @param {UpdateCommitteeAction} new_committee_action + * @returns {GovernanceAction} + */ + static new_new_committee_action( + new_committee_action: UpdateCommitteeAction + ): GovernanceAction; + + /** + * @param {NewConstitutionAction} new_constitution_action + * @returns {GovernanceAction} + */ + static new_new_constitution_action( + new_constitution_action: NewConstitutionAction + ): GovernanceAction; + + /** + * @param {InfoAction} info_action + * @returns {GovernanceAction} + */ + static new_info_action(info_action: InfoAction): GovernanceAction; + + /** + * @returns {number} + */ + kind(): number; + + /** + * @returns {ParameterChangeAction | void} + */ + as_parameter_change_action(): ParameterChangeAction | void; + + /** + * @returns {HardForkInitiationAction | void} + */ + as_hard_fork_initiation_action(): HardForkInitiationAction | void; + + /** + * @returns {TreasuryWithdrawalsAction | void} + */ + as_treasury_withdrawals_action(): TreasuryWithdrawalsAction | void; + + /** + * @returns {NoConfidenceAction | void} + */ + as_no_confidence_action(): NoConfidenceAction | void; + + /** + * @returns {UpdateCommitteeAction | void} + */ + as_new_committee_action(): UpdateCommitteeAction | void; + + /** + * @returns {NewConstitutionAction | void} + */ + as_new_constitution_action(): NewConstitutionAction | void; + + /** + * @returns {InfoAction | void} + */ + as_info_action(): InfoAction | void; +} /** */ declare export class GovernanceActionId { @@ -4190,7 +4327,7 @@ declare export class GovernanceActionIds { } /** */ -declare export class HardForkInitiationProposal { +declare export class HardForkInitiationAction { free(): void; /** @@ -4200,9 +4337,9 @@ declare export class HardForkInitiationProposal { /** * @param {Uint8Array} bytes - * @returns {HardForkInitiationProposal} + * @returns {HardForkInitiationAction} */ - static from_bytes(bytes: Uint8Array): HardForkInitiationProposal; + static from_bytes(bytes: Uint8Array): HardForkInitiationAction; /** * @returns {string} @@ -4211,9 +4348,9 @@ declare export class HardForkInitiationProposal { /** * @param {string} hex_str - * @returns {HardForkInitiationProposal} + * @returns {HardForkInitiationAction} */ - static from_hex(hex_str: string): HardForkInitiationProposal; + static from_hex(hex_str: string): HardForkInitiationAction; /** * @returns {string} @@ -4221,15 +4358,15 @@ declare export class HardForkInitiationProposal { to_json(): string; /** - * @returns {HardForkInitiationProposalJSON} + * @returns {HardForkInitiationActionJSON} */ - to_js_value(): HardForkInitiationProposalJSON; + to_js_value(): HardForkInitiationActionJSON; /** * @param {string} json - * @returns {HardForkInitiationProposal} + * @returns {HardForkInitiationAction} */ - static from_json(json: string): HardForkInitiationProposal; + static from_json(json: string): HardForkInitiationAction; /** * @returns {GovernanceActionId | void} @@ -4243,19 +4380,19 @@ declare export class HardForkInitiationProposal { /** * @param {ProtocolVersion} protocol_version - * @returns {HardForkInitiationProposal} + * @returns {HardForkInitiationAction} */ - static new(protocol_version: ProtocolVersion): HardForkInitiationProposal; + static new(protocol_version: ProtocolVersion): HardForkInitiationAction; /** * @param {GovernanceActionId} gov_action_id * @param {ProtocolVersion} protocol_version - * @returns {HardForkInitiationProposal} + * @returns {HardForkInitiationAction} */ static new_with_action_id( gov_action_id: GovernanceActionId, protocol_version: ProtocolVersion - ): HardForkInitiationProposal; + ): HardForkInitiationAction; } /** */ @@ -4503,13 +4640,13 @@ declare export class HeaderBody { } /** */ -declare export class InfoProposal { +declare export class InfoAction { free(): void; /** - * @returns {InfoProposal} + * @returns {InfoAction} */ - static new(): InfoProposal; + static new(): InfoAction; } /** */ @@ -6005,7 +6142,7 @@ declare export class NetworkInfo { } /** */ -declare export class NewConstitutionProposal { +declare export class NewConstitutionAction { free(): void; /** @@ -6015,9 +6152,9 @@ declare export class NewConstitutionProposal { /** * @param {Uint8Array} bytes - * @returns {NewConstitutionProposal} + * @returns {NewConstitutionAction} */ - static from_bytes(bytes: Uint8Array): NewConstitutionProposal; + static from_bytes(bytes: Uint8Array): NewConstitutionAction; /** * @returns {string} @@ -6026,9 +6163,9 @@ declare export class NewConstitutionProposal { /** * @param {string} hex_str - * @returns {NewConstitutionProposal} + * @returns {NewConstitutionAction} */ - static from_hex(hex_str: string): NewConstitutionProposal; + static from_hex(hex_str: string): NewConstitutionAction; /** * @returns {string} @@ -6036,15 +6173,15 @@ declare export class NewConstitutionProposal { to_json(): string; /** - * @returns {NewConstitutionProposalJSON} + * @returns {NewConstitutionActionJSON} */ - to_js_value(): NewConstitutionProposalJSON; + to_js_value(): NewConstitutionActionJSON; /** * @param {string} json - * @returns {NewConstitutionProposal} + * @returns {NewConstitutionAction} */ - static from_json(json: string): NewConstitutionProposal; + static from_json(json: string): NewConstitutionAction; /** * @returns {GovernanceActionId | void} @@ -6058,23 +6195,23 @@ declare export class NewConstitutionProposal { /** * @param {Constitution} constitution - * @returns {NewConstitutionProposal} + * @returns {NewConstitutionAction} */ - static new(constitution: Constitution): NewConstitutionProposal; + static new(constitution: Constitution): NewConstitutionAction; /** * @param {GovernanceActionId} gov_action_id * @param {Constitution} constitution - * @returns {NewConstitutionProposal} + * @returns {NewConstitutionAction} */ static new_with_action_id( gov_action_id: GovernanceActionId, constitution: Constitution - ): NewConstitutionProposal; + ): NewConstitutionAction; } /** */ -declare export class NoConfidenceProposal { +declare export class NoConfidenceAction { free(): void; /** @@ -6084,9 +6221,9 @@ declare export class NoConfidenceProposal { /** * @param {Uint8Array} bytes - * @returns {NoConfidenceProposal} + * @returns {NoConfidenceAction} */ - static from_bytes(bytes: Uint8Array): NoConfidenceProposal; + static from_bytes(bytes: Uint8Array): NoConfidenceAction; /** * @returns {string} @@ -6095,9 +6232,9 @@ declare export class NoConfidenceProposal { /** * @param {string} hex_str - * @returns {NoConfidenceProposal} + * @returns {NoConfidenceAction} */ - static from_hex(hex_str: string): NoConfidenceProposal; + static from_hex(hex_str: string): NoConfidenceAction; /** * @returns {string} @@ -6105,15 +6242,15 @@ declare export class NoConfidenceProposal { to_json(): string; /** - * @returns {NoConfidenceProposalJSON} + * @returns {NoConfidenceActionJSON} */ - to_js_value(): NoConfidenceProposalJSON; + to_js_value(): NoConfidenceActionJSON; /** * @param {string} json - * @returns {NoConfidenceProposal} + * @returns {NoConfidenceAction} */ - static from_json(json: string): NoConfidenceProposal; + static from_json(json: string): NoConfidenceAction; /** * @returns {GovernanceActionId | void} @@ -6121,17 +6258,17 @@ declare export class NoConfidenceProposal { gov_action_id(): GovernanceActionId | void; /** - * @returns {NoConfidenceProposal} + * @returns {NoConfidenceAction} */ - static new(): NoConfidenceProposal; + static new(): NoConfidenceAction; /** * @param {GovernanceActionId} gov_action_id - * @returns {NoConfidenceProposal} + * @returns {NoConfidenceAction} */ static new_with_action_id( gov_action_id: GovernanceActionId - ): NoConfidenceProposal; + ): NoConfidenceAction; } /** */ @@ -6298,7 +6435,7 @@ declare export class OutputDatum { } /** */ -declare export class ParameterChangeProposal { +declare export class ParameterChangeAction { free(): void; /** @@ -6308,9 +6445,9 @@ declare export class ParameterChangeProposal { /** * @param {Uint8Array} bytes - * @returns {ParameterChangeProposal} + * @returns {ParameterChangeAction} */ - static from_bytes(bytes: Uint8Array): ParameterChangeProposal; + static from_bytes(bytes: Uint8Array): ParameterChangeAction; /** * @returns {string} @@ -6319,9 +6456,9 @@ declare export class ParameterChangeProposal { /** * @param {string} hex_str - * @returns {ParameterChangeProposal} + * @returns {ParameterChangeAction} */ - static from_hex(hex_str: string): ParameterChangeProposal; + static from_hex(hex_str: string): ParameterChangeAction; /** * @returns {string} @@ -6329,15 +6466,15 @@ declare export class ParameterChangeProposal { to_json(): string; /** - * @returns {ParameterChangeProposalJSON} + * @returns {ParameterChangeActionJSON} */ - to_js_value(): ParameterChangeProposalJSON; + to_js_value(): ParameterChangeActionJSON; /** * @param {string} json - * @returns {ParameterChangeProposal} + * @returns {ParameterChangeAction} */ - static from_json(json: string): ParameterChangeProposal; + static from_json(json: string): ParameterChangeAction; /** * @returns {GovernanceActionId | void} @@ -6351,21 +6488,21 @@ declare export class ParameterChangeProposal { /** * @param {ProtocolParamUpdate} protocol_param_updates - * @returns {ParameterChangeProposal} + * @returns {ParameterChangeAction} */ static new( protocol_param_updates: ProtocolParamUpdate - ): ParameterChangeProposal; + ): ParameterChangeAction; /** * @param {GovernanceActionId} gov_action_id * @param {ProtocolParamUpdate} protocol_param_updates - * @returns {ParameterChangeProposal} + * @returns {ParameterChangeAction} */ static new_with_action_id( gov_action_id: GovernanceActionId, protocol_param_updates: ProtocolParamUpdate - ): ParameterChangeProposal; + ): ParameterChangeAction; } /** */ @@ -10856,14 +10993,6 @@ declare export class TransactionBuilderConfigBuilder { prefer_pure_change: boolean ): TransactionBuilderConfigBuilder; - /** - * @param {BigNum} voting_proposal_deposit - * @returns {TransactionBuilderConfigBuilder} - */ - voting_proposal_deposit( - voting_proposal_deposit: BigNum - ): TransactionBuilderConfigBuilder; - /** * @returns {TransactionBuilderConfig} */ @@ -11771,7 +11900,7 @@ declare export class TreasuryWithdrawals { } /** */ -declare export class TreasuryWithdrawalsProposal { +declare export class TreasuryWithdrawalsAction { free(): void; /** @@ -11781,9 +11910,9 @@ declare export class TreasuryWithdrawalsProposal { /** * @param {Uint8Array} bytes - * @returns {TreasuryWithdrawalsProposal} + * @returns {TreasuryWithdrawalsAction} */ - static from_bytes(bytes: Uint8Array): TreasuryWithdrawalsProposal; + static from_bytes(bytes: Uint8Array): TreasuryWithdrawalsAction; /** * @returns {string} @@ -11792,9 +11921,9 @@ declare export class TreasuryWithdrawalsProposal { /** * @param {string} hex_str - * @returns {TreasuryWithdrawalsProposal} + * @returns {TreasuryWithdrawalsAction} */ - static from_hex(hex_str: string): TreasuryWithdrawalsProposal; + static from_hex(hex_str: string): TreasuryWithdrawalsAction; /** * @returns {string} @@ -11802,15 +11931,15 @@ declare export class TreasuryWithdrawalsProposal { to_json(): string; /** - * @returns {TreasuryWithdrawalsProposalJSON} + * @returns {TreasuryWithdrawalsActionJSON} */ - to_js_value(): TreasuryWithdrawalsProposalJSON; + to_js_value(): TreasuryWithdrawalsActionJSON; /** * @param {string} json - * @returns {TreasuryWithdrawalsProposal} + * @returns {TreasuryWithdrawalsAction} */ - static from_json(json: string): TreasuryWithdrawalsProposal; + static from_json(json: string): TreasuryWithdrawalsAction; /** * @returns {TreasuryWithdrawals} @@ -11819,9 +11948,9 @@ declare export class TreasuryWithdrawalsProposal { /** * @param {TreasuryWithdrawals} withdrawals - * @returns {TreasuryWithdrawalsProposal} + * @returns {TreasuryWithdrawalsAction} */ - static new(withdrawals: TreasuryWithdrawals): TreasuryWithdrawalsProposal; + static new(withdrawals: TreasuryWithdrawals): TreasuryWithdrawalsAction; } /** */ @@ -12200,7 +12329,7 @@ declare export class Update { } /** */ -declare export class UpdateCommitteeProposal { +declare export class UpdateCommitteeAction { free(): void; /** @@ -12210,9 +12339,9 @@ declare export class UpdateCommitteeProposal { /** * @param {Uint8Array} bytes - * @returns {UpdateCommitteeProposal} + * @returns {UpdateCommitteeAction} */ - static from_bytes(bytes: Uint8Array): UpdateCommitteeProposal; + static from_bytes(bytes: Uint8Array): UpdateCommitteeAction; /** * @returns {string} @@ -12221,9 +12350,9 @@ declare export class UpdateCommitteeProposal { /** * @param {string} hex_str - * @returns {UpdateCommitteeProposal} + * @returns {UpdateCommitteeAction} */ - static from_hex(hex_str: string): UpdateCommitteeProposal; + static from_hex(hex_str: string): UpdateCommitteeAction; /** * @returns {string} @@ -12231,15 +12360,15 @@ declare export class UpdateCommitteeProposal { to_json(): string; /** - * @returns {UpdateCommitteeProposalJSON} + * @returns {UpdateCommitteeActionJSON} */ - to_js_value(): UpdateCommitteeProposalJSON; + to_js_value(): UpdateCommitteeActionJSON; /** * @param {string} json - * @returns {UpdateCommitteeProposal} + * @returns {UpdateCommitteeAction} */ - static from_json(json: string): UpdateCommitteeProposal; + static from_json(json: string): UpdateCommitteeAction; /** * @returns {GovernanceActionId | void} @@ -12259,24 +12388,24 @@ declare export class UpdateCommitteeProposal { /** * @param {Committee} committee * @param {Credentials} members_to_remove - * @returns {UpdateCommitteeProposal} + * @returns {UpdateCommitteeAction} */ static new( committee: Committee, members_to_remove: Credentials - ): UpdateCommitteeProposal; + ): UpdateCommitteeAction; /** * @param {GovernanceActionId} gov_action_id * @param {Committee} committee * @param {Credentials} members_to_remove - * @returns {UpdateCommitteeProposal} + * @returns {UpdateCommitteeAction} */ static new_with_action_id( gov_action_id: GovernanceActionId, committee: Committee, members_to_remove: Credentials - ): UpdateCommitteeProposal; + ): UpdateCommitteeAction; } /** */ @@ -13272,98 +13401,38 @@ declare export class VotingProposal { static from_json(json: string): VotingProposal; /** - * @param {ParameterChangeProposal} parameter_change_proposal - * @returns {VotingProposal} + * @returns {GovernanceAction} */ - static new_parameter_change_proposal( - parameter_change_proposal: ParameterChangeProposal - ): VotingProposal; + governance_action(): GovernanceAction; /** - * @param {HardForkInitiationProposal} hard_fork_initiation_proposal - * @returns {VotingProposal} - */ - static new_hard_fork_initiation_proposal( - hard_fork_initiation_proposal: HardForkInitiationProposal - ): VotingProposal; - - /** - * @param {TreasuryWithdrawalsProposal} treasury_withdrawals_proposal - * @returns {VotingProposal} + * @returns {Anchor} */ - static new_treasury_withdrawals_proposal( - treasury_withdrawals_proposal: TreasuryWithdrawalsProposal - ): VotingProposal; + anchor(): Anchor; /** - * @param {NoConfidenceProposal} no_confidence_proposal - * @returns {VotingProposal} + * @returns {RewardAddress} */ - static new_no_confidence_proposal( - no_confidence_proposal: NoConfidenceProposal - ): VotingProposal; + reward_account(): RewardAddress; /** - * @param {UpdateCommitteeProposal} new_committee_proposal - * @returns {VotingProposal} + * @returns {BigNum} */ - static new_new_committee_proposal( - new_committee_proposal: UpdateCommitteeProposal - ): VotingProposal; + deposit(): BigNum; /** - * @param {NewConstitutionProposal} new_constitution_proposal + * @param {GovernanceAction} governance_action + * @param {Anchor} anchor + * @param {RewardAddress} reward_account + * @param {BigNum} deposit * @returns {VotingProposal} */ - static new_new_constitution_proposal( - new_constitution_proposal: NewConstitutionProposal + static new( + governance_action: GovernanceAction, + anchor: Anchor, + reward_account: RewardAddress, + deposit: BigNum ): VotingProposal; - - /** - * @param {InfoProposal} info_proposal - * @returns {VotingProposal} - */ - static new_info_proposal(info_proposal: InfoProposal): VotingProposal; - - /** - * @returns {number} - */ - kind(): number; - - /** - * @returns {ParameterChangeProposal | void} - */ - as_parameter_change_proposal(): ParameterChangeProposal | void; - - /** - * @returns {HardForkInitiationProposal | void} - */ - as_hard_fork_initiation_proposal(): HardForkInitiationProposal | void; - - /** - * @returns {TreasuryWithdrawalsProposal | void} - */ - as_treasury_withdrawals_proposal(): TreasuryWithdrawalsProposal | void; - - /** - * @returns {NoConfidenceProposal | void} - */ - as_no_confidence_proposal(): NoConfidenceProposal | void; - - /** - * @returns {UpdateCommitteeProposal | void} - */ - as_new_committee_proposal(): UpdateCommitteeProposal | void; - - /** - * @returns {NewConstitutionProposal | void} - */ - as_new_constitution_proposal(): NewConstitutionProposal | void; - - /** - * @returns {InfoProposal | void} - */ - as_info_proposal(): InfoProposal | void; } /** */ @@ -13878,40 +13947,40 @@ export type VoterJSON = ... }; export type VoteKindJSON = "No" | "Yes" | "Abstain"; -export type VotingProposalJSON = +export type GovernanceActionJSON = | { - ParameterChangeProposal: ParameterChangeProposalJSON, + ParameterChangeAction: ParameterChangeActionJSON, ... } | { - HardForkInitiationProposal: HardForkInitiationProposalJSON, + HardForkInitiationAction: HardForkInitiationActionJSON, ... } | { - TreasuryWithdrawalsProposal: TreasuryWithdrawalsProposalJSON, + TreasuryWithdrawalsAction: TreasuryWithdrawalsActionJSON, ... } | { - NoConfidenceProposal: NoConfidenceProposalJSON, + NoConfidenceAction: NoConfidenceActionJSON, ... } | { - UpdateCommitteeProposal: UpdateCommitteeProposalJSON, + UpdateCommitteeAction: UpdateCommitteeActionJSON, ... } | { - NewConstitutionProposal: NewConstitutionProposalJSON, + NewConstitutionAction: NewConstitutionActionJSON, ... } | { - InfoProposal: InfoProposalJSON, + InfoAction: InfoActionJSON, ... }; /** * @minItems 0 * @maxItems 0 */ -export type InfoProposalJSON = []; +export type InfoActionJSON = []; export type VotingProposalsJSON = VotingProposalJSON[]; export type TransactionBodiesJSON = TransactionBodyJSON[]; export type BootstrapWitnessesJSON = BootstrapWitnessJSON[]; @@ -14247,24 +14316,30 @@ export interface VotingProcedureJSON { anchor?: AnchorJSON | null; vote: VoteKindJSON; } -export interface ParameterChangeProposalJSON { +export interface VotingProposalJSON { + anchor: AnchorJSON; + deposit: string; + governance_action: GovernanceActionJSON; + reward_account: string; +} +export interface ParameterChangeActionJSON { gov_action_id?: GovernanceActionIdJSON | null; protocol_param_updates: ProtocolParamUpdateJSON; } -export interface HardForkInitiationProposalJSON { +export interface HardForkInitiationActionJSON { gov_action_id?: GovernanceActionIdJSON | null; protocol_version: ProtocolVersionJSON; } -export interface TreasuryWithdrawalsProposalJSON { +export interface TreasuryWithdrawalsActionJSON { withdrawals: TreasuryWithdrawalsJSON; } export interface TreasuryWithdrawalsJSON { [k: string]: string; } -export interface NoConfidenceProposalJSON { +export interface NoConfidenceActionJSON { gov_action_id?: GovernanceActionIdJSON | null; } -export interface UpdateCommitteeProposalJSON { +export interface UpdateCommitteeActionJSON { committee: CommitteeJSON; gov_action_id?: GovernanceActionIdJSON | null; members_to_remove: CredTypeJSON[]; @@ -14277,7 +14352,7 @@ export interface CommitteeMemberJSON { stake_credential: CredTypeJSON; term_limit: number; } -export interface NewConstitutionProposalJSON { +export interface NewConstitutionActionJSON { constitution: ConstitutionJSON; gov_action_id?: GovernanceActionIdJSON | null; } @@ -14404,6 +14479,35 @@ export interface GeneralTransactionMetadataJSON { export type GenesisDelegateHashJSON = string; export type GenesisHashJSON = string; export type GenesisHashesJSON = string[]; +export type GovernanceActionEnumJSON = + | { + ParameterChangeAction: ParameterChangeActionJSON, + ... + } + | { + HardForkInitiationAction: HardForkInitiationActionJSON, + ... + } + | { + TreasuryWithdrawalsAction: TreasuryWithdrawalsActionJSON, + ... + } + | { + NoConfidenceAction: NoConfidenceActionJSON, + ... + } + | { + UpdateCommitteeAction: UpdateCommitteeActionJSON, + ... + } + | { + NewConstitutionAction: NewConstitutionActionJSON, + ... + } + | { + InfoAction: InfoActionJSON, + ... + }; export type IntJSON = string; /** * @minItems 4 @@ -14488,35 +14592,6 @@ export type VoterEnumJSON = ... }; export type VotingProceduresJSON = VoterVotesJSON[]; -export type VotingProposalEnumJSON = - | { - ParameterChangeProposal: ParameterChangeProposalJSON, - ... - } - | { - HardForkInitiationProposal: HardForkInitiationProposalJSON, - ... - } - | { - TreasuryWithdrawalsProposal: TreasuryWithdrawalsProposalJSON, - ... - } - | { - NoConfidenceProposal: NoConfidenceProposalJSON, - ... - } - | { - UpdateCommitteeProposal: UpdateCommitteeProposalJSON, - ... - } - | { - NewConstitutionProposal: NewConstitutionProposalJSON, - ... - } - | { - InfoProposal: InfoProposalJSON, - ... - }; export interface WithdrawalsJSON { [k: string]: string; } From dc9335ae04f70d04eb7c0abc8f921d1161c21cc6 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 6 Oct 2023 06:32:17 +0900 Subject: [PATCH 174/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5912f30f..de4bd344 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.7", + "version": "12.0.0-alpha.8", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 52c54d82..05569b89 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.7", + "version": "12.0.0-alpha.8", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 0249c63c..45c72712 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.7" +version = "12.0.0-alpha.8" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 72bbefe9..530e1663 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -37,7 +37,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.7" +version = "12.0.0-alpha.8" dependencies = [ "bech32", "cbor_event", From 1839cb3c526cf1f8609820f636ca1f199ad67ad7 Mon Sep 17 00:00:00 2001 From: twwu123 Date: Tue, 10 Oct 2023 13:46:42 +0800 Subject: [PATCH 175/349] add new function for utxo selection and change --- rust/src/tx_builder.rs | 105 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/rust/src/tx_builder.rs b/rust/src/tx_builder.rs index 256f2467..5a831ecb 100644 --- a/rust/src/tx_builder.rs +++ b/rust/src/tx_builder.rs @@ -343,6 +343,44 @@ impl TransactionBuilderConfigBuilder { } } +#[wasm_bindgen] +#[derive(Clone, Debug)] +pub struct ChangeConfig { + address: Address, + plutus_data: Option, + script_ref: Option +} + +#[wasm_bindgen] +impl ChangeConfig { + pub fn new(address: &Address) -> Self { + Self { + address: address.clone(), + plutus_data: None, + script_ref: None + } + } + + pub fn change_address(&self, address: &Address) -> Self { + let mut c_cfg = self.clone(); + c_cfg.address = address.clone(); + c_cfg + } + + pub fn change_plutus_data(&self, plutus_data: &OutputDatum) -> Self { + let mut c_cfg = self.clone(); + c_cfg.plutus_data = Some(plutus_data.clone()); + c_cfg + } + + pub fn change_script_ref(&self, script_ref: &ScriptRef) -> Self { + let mut c_cfg = self.clone(); + c_cfg.script_ref = Some(script_ref.clone()); + c_cfg + } +} + + #[wasm_bindgen] #[derive(Clone, Debug)] pub struct TransactionBuilder { @@ -1707,6 +1745,56 @@ impl TransactionBuilder { } } + // This method should be used after outputs of the transaction is defined. + // It will attempt utxo selection initially then add change, if adding change fails + // then it will attempt to use up the rest of the available inputs, attempting to add change + // after every extra input. + pub fn add_inputs_from_and_change( + &mut self, + inputs: &TransactionUnspentOutputs, + strategy: CoinSelectionStrategyCIP2, + change_config: &ChangeConfig + ) -> Result + { + self.add_inputs_from(inputs, strategy)?; + match &self.fee { + Some(_x) => { + return Err(JsError::from_str( + "Cannot calculate change if fee was explicitly specified", + )) + } + None => { + let mut add_change_result = self.add_change_if_needed_with_optional_script_and_datum(&change_config.address, change_config.plutus_data.clone().map_or(None, |od| Some(od.0)), change_config.script_ref.clone()); + match add_change_result { + Ok(v) => Ok(v), + Err(e) => { + let mut unused_inputs = TransactionUnspentOutputs::new(); + for input in inputs.into_iter() { + if self.inputs.inputs().0.iter().all(|used_input| input.input() != *used_input) { + unused_inputs.add(input) + } + } + unused_inputs.0.sort_by_key(|input| input.clone().output.amount.multiasset.map_or(0, |ma| ma.len())); + unused_inputs.0.reverse(); + while unused_inputs.0.len() > 0 { + let last_input = unused_inputs.0.pop(); + match last_input { + Some(input) => { + self.add_input(&input.output().address(), &input.input(), &input.output().amount()); + add_change_result = self.add_change_if_needed_with_optional_script_and_datum(&change_config.address, change_config.plutus_data.clone().map_or(None, |od| Some(od.0)), change_config.script_ref.clone()); + if let Ok(value) = add_change_result { + return Ok(value) + } + }, + None => return Err(JsError::from_str("Unable to balance tx with available inputs")) + } + } + Err(e) + } + } + } + } + } /// This method will calculate the script hash data /// using the plutus datums and redeemers already present in the builder @@ -8125,4 +8213,21 @@ mod tests { assert_eq!(tx.witness_set.plutus_scripts.unwrap().len(), 1usize); assert_eq!(tx.witness_set.redeemers.unwrap().len(), 2usize); } + + #[test] + fn utxo_selection_accounts_for_change_min_utxo_test() { + let mut tx_builder = create_reallistic_tx_builder(); + let hex_utxos = [ + "82825820731224c9d2bc3528578009fec9f9e34a67110aca2bd4dde0f050845a2daf660d0082583900436075347d6a452eba4289ae345a8eb15e73eb80979a7e817d988fc56c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e493821a001deabfa1581c9a5e0d55cdf4ce4e19c8acbff7b4dafc890af67a594a4c46d7dd1c0fa14001", + "82825820a04996d5ef87fdece0c74625f02ee5c1497a06e0e476c5095a6b0626b295074a00825839001772f234940519e71318bb9c5c8ad6eacfe8fd91a509050624e3855e6c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e4931a0016e360" + ]; + let output = TransactionOutput::new(&Address::from_bech32("addr_test1qppkqaf5044y2t46g2y6udz636c4uultszte5l5p0kvgl3tv3ck06k550q64lgwkqavljd63yda0x2va074fguprujfsjre4xh").unwrap(), &Value::new(&BigNum::from_str("969750").unwrap())); + tx_builder.add_output(&output); + let mut utxos = TransactionUnspentOutputs::new(); + for hex_utxo in hex_utxos { + utxos.add(&TransactionUnspentOutput::from_hex(hex_utxo).unwrap()); + } + let change_config = ChangeConfig::new(&Address::from_bech32("addr_test1qqzf7fhgm0gf370ngxgpskg5c3kgp2g0u4ltxlrmsvumaztv3ck06k550q64lgwkqavljd63yda0x2va074fguprujfs43mc83").unwrap()); + assert!(&tx_builder.add_inputs_from_and_change(&utxos, CoinSelectionStrategyCIP2::LargestFirstMultiAsset, &change_config).is_ok()); + } } From e4eb2745a98efc40f93fa3efa278b107d310a089 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 10 Oct 2023 16:41:26 +0900 Subject: [PATCH 176/349] fix schema gen --- rust/json-gen/src/main.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rust/json-gen/src/main.rs b/rust/json-gen/src/main.rs index e13cf58d..7718541c 100644 --- a/rust/json-gen/src/main.rs +++ b/rust/json-gen/src/main.rs @@ -171,7 +171,9 @@ fn main() { gen_json_schema!(DRep); gen_json_schema!(Anchor); gen_json_schema!(Voter); + gen_json_schema!(Voters); gen_json_schema!(GovernanceActionId); + gen_json_schema!(GovernanceActionIds); gen_json_schema!(VotingProcedure); gen_json_schema!(VotingProcedures); gen_json_schema!(CommitteeHotAuth); From d9f428d1448abf7a2e175af0a910baefb0664a48 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 10 Oct 2023 16:41:32 +0900 Subject: [PATCH 177/349] flow update --- rust/pkg/cardano_serialization_lib.js.flow | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 56666904..20f92202 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -14508,6 +14508,7 @@ export type GovernanceActionEnumJSON = InfoAction: InfoActionJSON, ... }; +export type GovernanceActionIdsJSON = GovernanceActionIdJSON[]; export type IntJSON = string; /** * @minItems 4 @@ -14591,6 +14592,7 @@ export type VoterEnumJSON = StakingPool: string, ... }; +export type VotersJSON = VoterJSON[]; export type VotingProceduresJSON = VoterVotesJSON[]; export interface WithdrawalsJSON { [k: string]: string; From 3d68d75a6f62d8eb3dcbf8dfbaee29809536177d Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 10 Oct 2023 16:42:49 +0900 Subject: [PATCH 178/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index de4bd344..72502712 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.8", + "version": "12.0.0-alpha.9", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 05569b89..1dd42dc7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.8", + "version": "12.0.0-alpha.9", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 45c72712..25ef2e53 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.8" +version = "12.0.0-alpha.9" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 530e1663..a188a8a3 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -37,7 +37,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.8" +version = "12.0.0-alpha.9" dependencies = [ "bech32", "cbor_event", From 1ea98625b3dafe5fe566027c2c34f46d08495ee3 Mon Sep 17 00:00:00 2001 From: twwu123 Date: Tue, 10 Oct 2023 17:49:12 +0800 Subject: [PATCH 179/349] add docs for new function --- .../generating-transactions.md | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/doc/getting-started/generating-transactions.md b/doc/getting-started/generating-transactions.md index 989ea30b..4767a29f 100644 --- a/doc/getting-started/generating-transactions.md +++ b/doc/getting-started/generating-transactions.md @@ -117,3 +117,53 @@ const transaction = CardanoWasm.Transaction.new( ## A note on fees Fees is Cardano Shelley are based directly on the size of the final encoded transaction. It is important to note that a transaction created by this library potentially can vary in size compared to one built with other tools. This is because transactions, as well as other Cardano Shelley structures, are encoded using [CBOR](https://cbor.io/) a binary JSON-like encoding. Due to arrays and maps allowing both definite or indefinite length encoding in the encoded transaction created by the library, the size can vary. This is because definite encoding consists of a tag containing the size of the array/map which can be 1 or more bytes long depending on the number of elements the size of the encoded structure, while indefinite length encoding consists of a 1 byte starting tag and after all elements are listed, a 1 byte ending tag. These variances should should only be a couple bytes and cardano-serialization-lib uses definite encoding which is the same length or smaller for any reasonable sized transaction. + +## UTxO Selection + +The `TransactionBuilder` struct allows you to manually enter inputs and outputs to create a valid transaction, of course, this means that you'll have to calculate things such as fees, change outputs, and perform UTxO selection on the inputs yourself. + +The `TransactionBuilder` struct has some exposed APIs that may be helpful in performing these actions. Namely the `builder.add_inputs_from_and_change` function. The function first looks at the outputs that already exists in the `builder`, then attempts to balance the transaction using `inputs` that are given in the arguments of the function. The function will set `inputs`, `outputs` and `fees` in the `builder`. + +The reason why all 3 have to be set within a single function, is because unfortunately, they all affect each other. Performing UTxO selection on some given `outputs` may result in some extra `change output`, which maybe increase the `fees` needed, which in turn, may change the `inputs` required, thereby changing what's required in the `change output`, and so on. + +Further complications arise due to the `minimum UTxO value` requirements on the Cardano network, which is tied to the size of the output. Tokens significantly increase the size of each output, and so any inputs with tokens complicates UTxO selection somewhat. + +`builder.add_inputs_from_and_change` should correctly perform UTxO selection, add these into the `builder.inputs`, add one extra output for `change`, and set the `builder.fee`. + +## Example Code +Here is a quick example of how it might be used + +```javascript +const txBuilder = wasm.TransactionBuilder.new( + wasm.TransactionBuilderConfigBuilder.new() + .fee_algo(wasm.LinearFee.new(wasm.BigNum.from_str('44'), wasm.BigNum.from_str('155381'))) + .coins_per_utxo_word(wasm.BigNum.from_str('34482')) + .pool_deposit(wasm.BigNum.from_str('500000000')) + .key_deposit(wasm.BigNum.from_str('2000000')) + .ex_unit_prices( + wasm.ExUnitPrices.new( + wasm.UnitInterval.new(wasm.BigNum.from_str('577'), wasm.BigNum.from_str('10000')), + wasm.UnitInterval.new(wasm.BigNum.from_str('721'), wasm.BigNum.from_str('10000000')), + ), + ) + .max_value_size(5000) + .max_tx_size(16384) + .build(), + ) +const utxos = [ + "82825820731224c9d2bc3528578009fec9f9e34a67110aca2bd4dde0f050845a2daf660d0082583900436075347d6a452eba4289ae345a8eb15e73eb80979a7e817d988fc56c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e493821a001deabfa1581c9a5e0d55cdf4ce4e19c8acbff7b4dafc890af67a594a4c46d7dd1c0fa14001", + "82825820a04996d5ef87fdece0c74625f02ee5c1497a06e0e476c5095a6b0626b295074a00825839001772f234940519e71318bb9c5c8ad6eacfe8fd91a509050624e3855e6c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e4931a0016e360" +] +const output = wasm.TransactionOutput.new(wasm.Address.from_bech32("addr_test1qppkqaf5044y2t46g2y6udz636c4uultszte5l5p0kvgl3tv3ck06k550q64lgwkqavljd63yda0x2va074fguprujfsjre4xh"), wasm.Value.new(wasm.BigNum.from_str("969750"))) +txBuilder.add_output(output) + +const wasmUtxos = wasm.TransactionUnspentOutputs.new(); +for (let i = 0; i < utxos.length; i++) { + wasmUtxos.add(wasm.TransactionUnspentOutput.from_hex(utxos[i])); + } +const wasmChangeConfig = wasm.ChangeConfig.new(wasm.Address.from_bech32("addr_test1qqzf7fhgm0gf370ngxgpskg5c3kgp2g0u4ltxlrmsvumaztv3ck06k550q64lgwkqavljd63yda0x2va074fguprujfs43mc83")) + +txBuilder.add_inputs_from_and_change(wasmUtxos, wasm.CoinSelectionStrategyCIP2.LargestFirstMultiAsset, wasmChangeConfig) + +const transaction = txBuilder.build_tx() +``` \ No newline at end of file From 51e0a8409f7ea539f3eb154da2a04f2c3ae4d7a2 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 11 Oct 2023 01:17:12 +0900 Subject: [PATCH 180/349] fix drep serialisation --- rust/src/serialization/governance/drep.rs | 26 ++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/rust/src/serialization/governance/drep.rs b/rust/src/serialization/governance/drep.rs index 801eccb3..abd4c9c5 100644 --- a/rust/src/serialization/governance/drep.rs +++ b/rust/src/serialization/governance/drep.rs @@ -24,18 +24,25 @@ impl cbor_event::se::Serialize for DRepEnum { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; match &self { DRepEnum::KeyHash(keyhash) => { + serializer.write_array(cbor_event::Len::Len(2))?; serializer.write_unsigned_integer(0u64)?; serializer.write_bytes(keyhash.to_bytes()) } DRepEnum::ScriptHash(scripthash) => { + serializer.write_array(cbor_event::Len::Len(2))?; serializer.write_unsigned_integer(1u64)?; serializer.write_bytes(scripthash.to_bytes()) } - DRepEnum::AlwaysAbstain => serializer.write_unsigned_integer(2u64), - DRepEnum::AlwaysNoConfidence => serializer.write_unsigned_integer(3u64), + DRepEnum::AlwaysAbstain => { + serializer.write_array(cbor_event::Len::Len(1))?; + serializer.write_unsigned_integer(2u64) + } + DRepEnum::AlwaysNoConfidence => { + serializer.write_array(cbor_event::Len::Len(1))?; + serializer.write_unsigned_integer(3u64) + } } } } @@ -54,9 +61,18 @@ impl Deserialize for DRepEnum { .into()); } } + let drep = match raw.unsigned_integer()? { - 0 => DRepEnum::KeyHash(Ed25519KeyHash::deserialize(raw)?), - 1 => DRepEnum::ScriptHash(ScriptHash::deserialize(raw)?), + 0 => { + let key_hash = + Ed25519KeyHash::deserialize(raw).map_err(|e| e.annotate("key_hash"))?; + DRepEnum::KeyHash(key_hash) + } + 1 => { + let script_hash = + ScriptHash::deserialize(raw).map_err(|e| e.annotate("script_hash"))?; + DRepEnum::ScriptHash(script_hash) + } 2 => DRepEnum::AlwaysAbstain, 3 => DRepEnum::AlwaysNoConfidence, n => { From 449ce6dd8a83dea1f6c3630d331935a8bad9d6f0 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 11 Oct 2023 01:19:24 +0900 Subject: [PATCH 181/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 72502712..ad2cb990 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.9", + "version": "12.0.0-alpha.10", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 1dd42dc7..1b39eaf1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.9", + "version": "12.0.0-alpha.10", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 25ef2e53..b9ba0622 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.9" +version = "12.0.0-alpha.10" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index a188a8a3..55531720 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -37,7 +37,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.9" +version = "12.0.0-alpha.10" dependencies = [ "bech32", "cbor_event", From a3bde58b5a0fa2b088d7355f0d562db2b571b544 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 16 Oct 2023 17:45:33 +0900 Subject: [PATCH 182/349] fix info action serialization --- .../governance/proposals/governance_action.rs | 26 ++----------- .../governance/proposals/info_action.rs | 39 +++++++++++++++++++ .../serialization/governance/proposals/mod.rs | 4 ++ .../serialization/governance/proposals.rs | 16 ++++++++ 4 files changed, 63 insertions(+), 22 deletions(-) create mode 100644 rust/src/serialization/governance/proposals/info_action.rs diff --git a/rust/src/serialization/governance/proposals/governance_action.rs b/rust/src/serialization/governance/proposals/governance_action.rs index 7cc2950f..c61ba512 100644 --- a/rust/src/serialization/governance/proposals/governance_action.rs +++ b/rust/src/serialization/governance/proposals/governance_action.rs @@ -16,10 +16,7 @@ impl Serialize for GovernanceAction { GovernanceActionEnum::NoConfidenceAction(x) => x.serialize(serializer), GovernanceActionEnum::UpdateCommitteeAction(x) => x.serialize(serializer), GovernanceActionEnum::NewConstitutionAction(x) => x.serialize(serializer), - GovernanceActionEnum::InfoAction(_) => { - let index = VotingProposalIndexNames::InfoAction.to_u64(); - serialize_and_check_index(serializer, index, "VotingProposalEnum::InfoProposal") - } + GovernanceActionEnum::InfoAction(x) => x.serialize(serializer), } } } @@ -27,23 +24,6 @@ impl Serialize for GovernanceAction { impl Deserialize for GovernanceAction { fn deserialize(raw: &mut Deserializer) -> Result { (|| -> Result<_, DeserializeError> { - if let Ok(index) = raw.unsigned_integer() { - let expected_index = VotingProposalIndexNames::InfoAction.to_u64().ok_or( - DeserializeFailure::CustomError( - "unknown index of VotingProposalEnum::InfoProposal".to_string(), - ), - )?; - if index != expected_index { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index), - expected: Key::Uint(expected_index), - } - .into()); - } - - return Ok(Self(GovernanceActionEnum::InfoAction(InfoAction::new()))); - } - let len = raw.array()?; let ret = Self::deserialize_as_embedded_group(raw, len)?; check_len_indefinite(raw, len)?; @@ -99,7 +79,9 @@ impl DeserializeEmbeddedGroup for GovernanceAction { )) } VotingProposalIndexNames::InfoAction => { - Ok(GovernanceActionEnum::InfoAction(InfoAction::new())) + Ok(GovernanceActionEnum::InfoAction( + InfoAction::deserialize_as_embedded_group(raw, len)?, + )) } }?; diff --git a/rust/src/serialization/governance/proposals/info_action.rs b/rust/src/serialization/governance/proposals/info_action.rs new file mode 100644 index 00000000..d3efa97a --- /dev/null +++ b/rust/src/serialization/governance/proposals/info_action.rs @@ -0,0 +1,39 @@ +use crate::serialization::utils::{check_len_indefinite, serialize_and_check_index}; +use crate::serialization::{check_len, deserialize_and_check_index}; +use crate::*; +use map_names::VotingProposalIndexNames; +use num_traits::ToPrimitive; + +impl cbor_event::se::Serialize for InfoAction { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(1))?; + + let proposal_index = VotingProposalIndexNames::InfoAction.to_u64(); + serialize_and_check_index(serializer, proposal_index, "InfoAction")?; + + Ok(serializer) + } +} + +impl_deserialize_for_wrapped_tuple!(InfoAction); + +impl DeserializeEmbeddedGroup for InfoAction { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + check_len( + len, + 1, + "(proposal_index)", + )?; + + let desired_index = VotingProposalIndexNames::InfoAction.to_u64(); + deserialize_and_check_index(raw, desired_index, "proposal_index")?; + + return Ok(InfoAction()); + } +} \ No newline at end of file diff --git a/rust/src/serialization/governance/proposals/mod.rs b/rust/src/serialization/governance/proposals/mod.rs index 3f3c7d47..8bb84bea 100644 --- a/rust/src/serialization/governance/proposals/mod.rs +++ b/rust/src/serialization/governance/proposals/mod.rs @@ -28,8 +28,12 @@ pub use new_constitution_action::*; mod governance_action; pub use governance_action::*; +mod info_action; +pub use info_action::*; + mod voting_proposal; pub use voting_proposal::*; mod voting_proposals; + pub use voting_proposals::*; diff --git a/rust/src/tests/serialization/governance/proposals.rs b/rust/src/tests/serialization/governance/proposals.rs index b3e7aeb9..724902e4 100644 --- a/rust/src/tests/serialization/governance/proposals.rs +++ b/rust/src/tests/serialization/governance/proposals.rs @@ -400,4 +400,20 @@ fn tx_with_voting_proposal_deser_test() { let proposal = proposals.unwrap().get(0); let expected_coin = Coin::from(1000000u32); assert_eq!(proposal.deposit(), expected_coin); +} + +#[test] +fn tx_with_info_proposal_deser_test() { + let cbor = "84a40081825820f83bdffcbc203eec54dc71208aa7974c538414898673cd7af900149e8c8e392b0001818258390030a33756d8cbf4d18ce8c9995feca1ea1fc70093943c17bd96d65fed0aed6caa1cfe93f03f6ef1d9701df8024494d0b3b8a53a1ee37c5ab21b0000000253cd778c021a0002a75114818400581de00aed6caa1cfe93f03f6ef1d9701df8024494d0b3b8a53a1ee37c5ab2810682781868747470733a2f2f73686f727475726c2e61742f7279616e582013b0234dab754774e4530a0918d8272491541a8d2f6cf8ab0a10abdaa81f2440a10081825820684cb4218cb7e943e5f728ec09ed7f9486b6c164f332312c095067e21db9592b5840a3294bdea8fd49c8e7bd965d02b37033285db1907d1fab13cce281686cae7b23ee7c8aa534f229aade6b0bacfd71a518a24aeb73d08d879aaaee14aa16abf30af5f6"; + let tx_deser = Transaction::from_hex(cbor); + assert!(tx_deser.is_ok()); + + let proposals = tx_deser.unwrap().body().voting_proposals(); + assert!(proposals.is_some()); + let proposal = proposals.unwrap().get(0); + let expected_coin = Coin::zero(); + assert_eq!(proposal.deposit(), expected_coin); + + let info = proposal.governance_action().as_info_action(); + assert!(info.is_some()); } \ No newline at end of file From feb636825aba35517e7d0c21b858261b7937ed17 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 16 Oct 2023 17:46:13 +0900 Subject: [PATCH 183/349] fmt --- .../governance/proposals/governance_action.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/rust/src/serialization/governance/proposals/governance_action.rs b/rust/src/serialization/governance/proposals/governance_action.rs index c61ba512..648bcc6f 100644 --- a/rust/src/serialization/governance/proposals/governance_action.rs +++ b/rust/src/serialization/governance/proposals/governance_action.rs @@ -1,7 +1,7 @@ use crate::serialization::map_names::VotingProposalIndexNames; -use crate::serialization::utils::{check_len_indefinite, serialize_and_check_index}; +use crate::serialization::utils::check_len_indefinite; use crate::*; -use num_traits::{FromPrimitive, ToPrimitive}; +use num_traits::FromPrimitive; use std::io::{Seek, SeekFrom}; impl Serialize for GovernanceAction { @@ -78,11 +78,9 @@ impl DeserializeEmbeddedGroup for GovernanceAction { NewConstitutionAction::deserialize_as_embedded_group(raw, len)?, )) } - VotingProposalIndexNames::InfoAction => { - Ok(GovernanceActionEnum::InfoAction( - InfoAction::deserialize_as_embedded_group(raw, len)?, - )) - } + VotingProposalIndexNames::InfoAction => Ok(GovernanceActionEnum::InfoAction( + InfoAction::deserialize_as_embedded_group(raw, len)?, + )), }?; Ok(Self(proposal_enum)) From 4463f52a74c33513ecbd93c08fb6ad4e73ace985 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 16 Oct 2023 17:48:31 +0900 Subject: [PATCH 184/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index ad2cb990..5771da23 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.10", + "version": "12.0.0-alpha.11", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 1b39eaf1..58446b6c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.10", + "version": "12.0.0-alpha.11", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index b9ba0622..95fb2e70 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.10" +version = "12.0.0-alpha.11" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 55531720..5b4cacbc 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -37,7 +37,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.10" +version = "12.0.0-alpha.11" dependencies = [ "bech32", "cbor_event", From 7d053eef5eb8bb1189011c15753ad5be43b82f1c Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 1 Nov 2023 22:12:36 +0800 Subject: [PATCH 185/349] add req witness for reg cert --- rust/src/builders/certificates_builder.rs | 8 +++++++- rust/src/protocol_types/certificates/certificate.rs | 7 +++++++ .../protocol_types/certificates/stake_registration.rs | 4 ++++ rust/src/tests/builders/certificates_builder.rs | 10 ++++------ 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/rust/src/builders/certificates_builder.rs b/rust/src/builders/certificates_builder.rs index d4c892d1..f39ad75a 100644 --- a/rust/src/builders/certificates_builder.rs +++ b/rust/src/builders/certificates_builder.rs @@ -219,7 +219,13 @@ fn witness_keys_for_cert(cert_enum: &Certificate) -> RequiredSigners { let mut set = RequiredSigners::new(); match &cert_enum.0 { // stake key registrations do not require a witness - CertificateEnum::StakeRegistration(_) => {} + CertificateEnum::StakeRegistration(cert) => { + if cert.coin.is_some() { + if let Some(key) = cert.stake_credential().to_keyhash() { + set.add(&key); + } + } + } CertificateEnum::StakeDeregistration(cert) => { if let Some(key) = cert.stake_credential().to_keyhash() { set.add(&key); diff --git a/rust/src/protocol_types/certificates/certificate.rs b/rust/src/protocol_types/certificates/certificate.rs index 9e2dfaff..ae79fe4c 100644 --- a/rust/src/protocol_types/certificates/certificate.rs +++ b/rust/src/protocol_types/certificates/certificate.rs @@ -334,6 +334,13 @@ impl Certificate { pub fn has_required_script_witness(&self) -> bool { match &self.0 { + CertificateEnum::StakeRegistration(x) => { + if x.coin.is_some() { + return x.has_script_credentials(); + } else { + return false; + } + } CertificateEnum::StakeDeregistration(x) => x.has_script_credentials(), CertificateEnum::StakeDelegation(x) => x.has_script_credentials(), CertificateEnum::VoteDelegation(x) => x.has_script_credentials(), diff --git a/rust/src/protocol_types/certificates/stake_registration.rs b/rust/src/protocol_types/certificates/stake_registration.rs index 1ef525dd..c605c1a0 100644 --- a/rust/src/protocol_types/certificates/stake_registration.rs +++ b/rust/src/protocol_types/certificates/stake_registration.rs @@ -43,4 +43,8 @@ impl StakeRegistration { coin: Some(coin.clone()), } } + + pub fn has_script_credentials(&self) -> bool { + self.stake_credential.has_script_hash() + } } diff --git a/rust/src/tests/builders/certificates_builder.rs b/rust/src/tests/builders/certificates_builder.rs index 09dd81cb..ad83ac73 100644 --- a/rust/src/tests/builders/certificates_builder.rs +++ b/rust/src/tests/builders/certificates_builder.rs @@ -312,14 +312,11 @@ fn certificatess_builder_req_signers_test() { let key_hash_4 = fake_key_hash(4); let key_hash_5 = fake_key_hash(5); let key_hash_6 = fake_key_hash(6); - let key_hash_7 = fake_key_hash(7); let key_hash_8 = fake_key_hash(8); - let key_hash_9 = fake_key_hash(9); let key_hash_10 = fake_key_hash(10); let key_hash_11 = fake_key_hash(11); let key_hash_12 = fake_key_hash(12); let key_hash_13 = fake_key_hash(13); - let key_hash_14 = fake_key_hash(14); let key_hash_15 = fake_key_hash(15); let key_hash_16 = fake_key_hash(16); let key_hash_17 = fake_key_hash(17); @@ -442,7 +439,7 @@ fn certificatess_builder_req_signers_test() { &Credential::from_keyhash(&key_hash_24), &Coin::from(key_deposit_form_args), ); - let stake_reg_with_coint_wrapped = Certificate::new_stake_registration(&stake_reg_with_coin_cert); + let stake_reg_with_coin_wrapped = Certificate::new_stake_registration(&stake_reg_with_coin_cert); let stake_reg_deleg_cert = StakeRegistrationAndDelegation::new( &Credential::from_keyhash(&key_hash_25), @@ -486,7 +483,7 @@ fn certificatess_builder_req_signers_test() { builder.add(&stake_dereg_cert_wrapped).unwrap(); builder.add(&stake_dereg_with_coint_wrapped).unwrap(); builder.add(&stake_reg_cert_wrapped).unwrap(); - builder.add(&stake_reg_with_coint_wrapped).unwrap(); + builder.add(&stake_reg_with_coin_wrapped).unwrap(); builder.add(&stake_reg_deleg_cert_wrapped).unwrap(); builder.add(&stake_vote_reg_deleg_cert_wrapped).unwrap(); builder.add(&vote_deleg_cert_wrapped).unwrap(); @@ -499,7 +496,7 @@ fn certificatess_builder_req_signers_test() { let req_signers = builder.get_required_signers(); - assert_eq!(req_signers.len(), 17); + assert_eq!(req_signers.len(), 18); assert!(req_signers.contains(&key_hash_1)); assert!(req_signers.contains(&key_hash_2)); assert!(req_signers.contains(&key_hash_5)); @@ -513,6 +510,7 @@ fn certificatess_builder_req_signers_test() { assert!(req_signers.contains(&key_hash_19)); assert!(req_signers.contains(&key_hash_21)); assert!(req_signers.contains(&key_hash_22)); + assert!(req_signers.contains(&key_hash_24)); assert!(req_signers.contains(&key_hash_25)); assert!(req_signers.contains(&key_hash_28)); assert!(req_signers.contains(&key_hash_31)); From 2089e96f6d5e876bd812fe48be8087458a477b59 Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 2 Nov 2023 00:29:43 +0800 Subject: [PATCH 186/349] add anchor for committee_cold_resign --- .../certificates/certificate.rs | 4 +-- .../committee_hot_key_deregistration.rs | 13 +++++++++ .../certificates/committee_cold_resign.rs | 8 ++++-- .../tests/builders/certificates_builder.rs | 12 ++++---- rust/src/tests/serialization/certificates.rs | 28 +++++++++++++++---- 5 files changed, 48 insertions(+), 17 deletions(-) diff --git a/rust/src/protocol_types/certificates/certificate.rs b/rust/src/protocol_types/certificates/certificate.rs index ae79fe4c..9d9ba08f 100644 --- a/rust/src/protocol_types/certificates/certificate.rs +++ b/rust/src/protocol_types/certificates/certificate.rs @@ -111,7 +111,7 @@ impl Certificate { )) } - pub fn new_committee_hot_key_registration( + pub fn new_committee_hot_auth( committee_hot_key_registration: &CommitteeHotAuth, ) -> Self { Self(CertificateEnum::CommitteeHotAuth( @@ -119,7 +119,7 @@ impl Certificate { )) } - pub fn new_committee_hot_key_deregistration( + pub fn new_committee_cold_resign( committee_hot_key_deregistration: &CommitteeColdResign, ) -> Self { Self(CertificateEnum::CommitteeColdResign( diff --git a/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs b/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs index dff0f32a..f2ddac68 100644 --- a/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs +++ b/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs @@ -15,6 +15,7 @@ use crate::*; #[wasm_bindgen] pub struct CommitteeColdResign { pub(crate) committee_cold_key: Credential, + pub(crate) anchor: Option, } impl_to_from!(CommitteeColdResign); @@ -25,9 +26,21 @@ impl CommitteeColdResign { self.committee_cold_key.clone() } + pub fn anchor(&self) -> Option { + self.anchor.clone() + } + pub fn new(committee_cold_key: &Credential) -> Self { Self { committee_cold_key: committee_cold_key.clone(), + anchor: None, + } + } + + pub fn new_with_anchor(committee_cold_key: &Credential, anchor: &Anchor) -> Self { + Self { + committee_cold_key: committee_cold_key.clone(), + anchor: Some(anchor.clone()), } } diff --git a/rust/src/serialization/certificates/committee_cold_resign.rs b/rust/src/serialization/certificates/committee_cold_resign.rs index 071fb138..1519da52 100644 --- a/rust/src/serialization/certificates/committee_cold_resign.rs +++ b/rust/src/serialization/certificates/committee_cold_resign.rs @@ -10,11 +10,12 @@ impl cbor_event::se::Serialize for CommitteeColdResign { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; + serializer.write_array(cbor_event::Len::Len(3))?; let proposal_index = CertificateIndexNames::CommitteeColdResign.to_u64(); serialize_and_check_index(serializer, proposal_index, "CommitteeColdResign")?; self.committee_cold_key.serialize(serializer)?; + self.anchor.serialize_nullable(serializer)?; Ok(serializer) } } @@ -26,14 +27,15 @@ impl DeserializeEmbeddedGroup for CommitteeColdResign { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - check_len(len, 2, "(cert_index, committee_cold_key)")?; + check_len(len, 3, "(cert_index, committee_cold_key, anchor)")?; let cert_index = CertificateIndexNames::CommitteeColdResign.to_u64(); deserialize_and_check_index(raw, cert_index, "cert_index")?; let committee_cold_key = Credential::deserialize(raw).map_err(|e| e.annotate("committee_cold_key"))?; + let anchor = Anchor::deserialize_nullable(raw).map_err(|e| e.annotate("anchor"))?; - Ok(CommitteeColdResign { committee_cold_key }) + Ok(CommitteeColdResign { committee_cold_key, anchor }) } } diff --git a/rust/src/tests/builders/certificates_builder.rs b/rust/src/tests/builders/certificates_builder.rs index ad83ac73..740f10e2 100644 --- a/rust/src/tests/builders/certificates_builder.rs +++ b/rust/src/tests/builders/certificates_builder.rs @@ -15,14 +15,14 @@ fn certificatess_builder_deposit_test() { let committee_hot_key_dereg_cert = CommitteeColdResign::new(&Credential::from_keyhash(&fake_key_hash(1))); let committee_hot_key_dereg_cert_wrapped = - Certificate::new_committee_hot_key_deregistration(&committee_hot_key_dereg_cert); + Certificate::new_committee_cold_resign(&committee_hot_key_dereg_cert); let committee_hot_key_reg_cert = CommitteeHotAuth::new( &Credential::from_keyhash(&fake_key_hash(2)), &Credential::from_keyhash(&fake_key_hash(3)), ); let committee_hot_key_reg_cert_wrapped = - Certificate::new_committee_hot_key_registration(&committee_hot_key_reg_cert); + Certificate::new_committee_hot_auth(&committee_hot_key_reg_cert); let drep_reg_cert = DrepRegistration::new( &Credential::from_keyhash(&fake_key_hash(4)), @@ -189,14 +189,14 @@ fn certificatess_builder_no_deposit_test() { let committee_hot_key_dereg_cert = CommitteeColdResign::new(&Credential::from_keyhash(&fake_key_hash(1))); let committee_hot_key_dereg_cert_wrapped = - Certificate::new_committee_hot_key_deregistration(&committee_hot_key_dereg_cert); + Certificate::new_committee_cold_resign(&committee_hot_key_dereg_cert); let committee_hot_key_reg_cert = CommitteeHotAuth::new( &Credential::from_keyhash(&fake_key_hash(2)), &Credential::from_keyhash(&fake_key_hash(3)), ); let committee_hot_key_reg_cert_wrapped = - Certificate::new_committee_hot_key_registration(&committee_hot_key_reg_cert); + Certificate::new_committee_hot_auth(&committee_hot_key_reg_cert); let drep_dereg_cert = DrepDeregistration::new( &Credential::from_keyhash(&fake_key_hash(5)), @@ -340,14 +340,14 @@ fn certificatess_builder_req_signers_test() { let committee_hot_key_dereg_cert = CommitteeColdResign::new(&Credential::from_keyhash(&key_hash_1)); let committee_hot_key_dereg_cert_wrapped = - Certificate::new_committee_hot_key_deregistration(&committee_hot_key_dereg_cert); + Certificate::new_committee_cold_resign(&committee_hot_key_dereg_cert); let committee_hot_key_reg_cert = CommitteeHotAuth::new( &Credential::from_keyhash(&key_hash_2), &Credential::from_keyhash(&key_hash_3), ); let committee_hot_key_reg_cert_wrapped = - Certificate::new_committee_hot_key_registration(&committee_hot_key_reg_cert); + Certificate::new_committee_hot_auth(&committee_hot_key_reg_cert); let drep_reg_cert = DrepRegistration::new( &Credential::from_keyhash(&key_hash_4), diff --git a/rust/src/tests/serialization/certificates.rs b/rust/src/tests/serialization/certificates.rs index de70eda0..af497354 100644 --- a/rust/src/tests/serialization/certificates.rs +++ b/rust/src/tests/serialization/certificates.rs @@ -3,6 +3,7 @@ use crate::fakes::{ fake_pool_metadata_hash, fake_script_hash, fake_vrf_key_hash, }; use crate::*; +use crate::tests::mock_objects::create_anchor; macro_rules! to_from_test { ($cert_type: ty, $variable_name: ident, $variable_wrapped_name: ident) => { @@ -34,9 +35,9 @@ macro_rules! to_from_test { } #[test] -fn committee_hot_key_deregistration_key_hash_ser_round_trip() { +fn committee_cold_resign_key_hash_ser_round_trip() { let cert = CommitteeColdResign::new(&Credential::from_keyhash(&fake_key_hash(1))); - let cert_wrapped = Certificate::new_committee_hot_key_deregistration(&cert); + let cert_wrapped = Certificate::new_committee_cold_resign(&cert); to_from_test!(CommitteeColdResign, cert, cert_wrapped); assert_eq!( cert, @@ -45,10 +46,25 @@ fn committee_hot_key_deregistration_key_hash_ser_round_trip() { } #[test] -fn committee_hot_key_deregistration_script_hash_ser_round_trip() { +fn committee_cold_resign_with_anchor_ser_round_trip() { + let anchor = create_anchor(); + let cert = CommitteeColdResign::new_with_anchor( + &Credential::from_keyhash(&fake_key_hash(1)), + &anchor, + ); + let cert_wrapped = Certificate::new_committee_cold_resign(&cert); + to_from_test!(CommitteeColdResign, cert, cert_wrapped); + assert_eq!( + cert, + cert_wrapped.as_committee_hot_key_deregistration().unwrap() + ); +} + +#[test] +fn committee_cold_resign_script_hash_ser_round_trip() { let cert = CommitteeColdResign::new(&Credential::from_scripthash(&fake_script_hash(1))); - let cert_wrapped = Certificate::new_committee_hot_key_deregistration(&cert); + let cert_wrapped = Certificate::new_committee_cold_resign(&cert); to_from_test!(CommitteeColdResign, cert, cert_wrapped); assert_eq!( cert, @@ -57,12 +73,12 @@ fn committee_hot_key_deregistration_script_hash_ser_round_trip() { } #[test] -fn committee_hot_key_registration_ser_round_trip() { +fn committee_hot_auth_ser_round_trip() { let cert = CommitteeHotAuth::new( &Credential::from_keyhash(&fake_key_hash(1)), &Credential::from_keyhash(&fake_key_hash(2)), ); - let cert_wrapped = Certificate::new_committee_hot_key_registration(&cert); + let cert_wrapped = Certificate::new_committee_hot_auth(&cert); to_from_test!(CommitteeHotAuth, cert, cert_wrapped); assert_eq!( cert, From ecb65e28c8c60653d926a7b8534a341f4a775f6b Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 2 Nov 2023 00:46:51 +0800 Subject: [PATCH 187/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5771da23..34bd94ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.11", + "version": "12.0.0-alpha.12", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 58446b6c..83d2c9f5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.11", + "version": "12.0.0-alpha.12", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 95fb2e70..9e2a305f 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.11" +version = "12.0.0-alpha.12" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 5b4cacbc..11658984 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -37,7 +37,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.11" +version = "12.0.0-alpha.12" dependencies = [ "bech32", "cbor_event", From b9d182b1b877c8baf7bac94e8357df96e6449f63 Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 2 Nov 2023 01:08:23 +0800 Subject: [PATCH 188/349] update flow --- rust/pkg/cardano_serialization_lib.js.flow | 25 ++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 20f92202..35b1d2e9 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -1843,7 +1843,7 @@ declare export class Certificate { * @param {CommitteeHotAuth} committee_hot_key_registration * @returns {Certificate} */ - static new_committee_hot_key_registration( + static new_committee_hot_auth( committee_hot_key_registration: CommitteeHotAuth ): Certificate; @@ -1851,7 +1851,7 @@ declare export class Certificate { * @param {CommitteeColdResign} committee_hot_key_deregistration * @returns {Certificate} */ - static new_committee_hot_key_deregistration( + static new_committee_cold_resign( committee_hot_key_deregistration: CommitteeColdResign ): Certificate; @@ -2262,12 +2262,27 @@ declare export class CommitteeColdResign { */ committee_cold_key(): Credential; + /** + * @returns {Anchor | void} + */ + anchor(): Anchor | void; + /** * @param {Credential} committee_cold_key * @returns {CommitteeColdResign} */ static new(committee_cold_key: Credential): CommitteeColdResign; + /** + * @param {Credential} committee_cold_key + * @param {Anchor} anchor + * @returns {CommitteeColdResign} + */ + static new_with_anchor( + committee_cold_key: Credential, + anchor: Anchor + ): CommitteeColdResign; + /** * @returns {boolean} */ @@ -9512,6 +9527,11 @@ declare export class StakeRegistration { stake_credential: Credential, coin: BigNum ): StakeRegistration; + + /** + * @returns {boolean} + */ + has_script_credentials(): boolean; } /** */ @@ -14129,6 +14149,7 @@ export interface CommitteeHotAuthJSON { committee_hot_key: CredTypeJSON; } export interface CommitteeColdResignJSON { + anchor?: AnchorJSON | null; committee_cold_key: CredTypeJSON; } export interface DrepDeregistrationJSON { From 7a618a2b01cca83c308e1561007557fec850f5b8 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 4 Nov 2023 00:19:58 +0800 Subject: [PATCH 189/349] update set deserialization (tag 258) --- .../certificates/certificates_collection.rs | 2 ++ .../governance/proposals/voting_proposals.rs | 2 ++ rust/src/serialization/utils.rs | 25 +++++++++++++++++++ rust/src/tests/serialization/certificates.rs | 21 ++++++++++------ 4 files changed, 43 insertions(+), 7 deletions(-) diff --git a/rust/src/serialization/certificates/certificates_collection.rs b/rust/src/serialization/certificates/certificates_collection.rs index ee990a5d..2828f184 100644 --- a/rust/src/serialization/certificates/certificates_collection.rs +++ b/rust/src/serialization/certificates/certificates_collection.rs @@ -1,3 +1,4 @@ +use crate::serialization::utils::skip_set_tag_wrapperr; use crate::*; impl Serialize for Certificates { @@ -15,6 +16,7 @@ impl Serialize for Certificates { impl Deserialize for Certificates { fn deserialize(raw: &mut Deserializer) -> Result { + skip_set_tag_wrapperr(raw)?; let mut arr = Vec::new(); (|| -> Result<_, DeserializeError> { let len = raw.array()?; diff --git a/rust/src/serialization/governance/proposals/voting_proposals.rs b/rust/src/serialization/governance/proposals/voting_proposals.rs index 3fc2aa28..d7e092f4 100644 --- a/rust/src/serialization/governance/proposals/voting_proposals.rs +++ b/rust/src/serialization/governance/proposals/voting_proposals.rs @@ -1,4 +1,5 @@ use crate::*; +use crate::serialization::utils::skip_set_tag_wrapperr; impl cbor_event::se::Serialize for VotingProposals { fn serialize<'se, W: Write>( @@ -17,6 +18,7 @@ impl Deserialize for VotingProposals { fn deserialize(raw: &mut Deserializer) -> Result { let mut arr = Vec::new(); (|| -> Result<_, DeserializeError> { + skip_set_tag_wrapperr(raw)?; let len = raw.array()?; while match len { cbor_event::Len::Len(n) => arr.len() < n as usize, diff --git a/rust/src/serialization/utils.rs b/rust/src/serialization/utils.rs index ef54dd42..76c4d77b 100644 --- a/rust/src/serialization/utils.rs +++ b/rust/src/serialization/utils.rs @@ -74,3 +74,28 @@ pub(super) fn check_len_indefinite( } Ok(()) } + +pub(super) fn skip_tag_wrapper( + raw: &mut Deserializer, + tag: u64, +) -> Result<(), DeserializeError> { + if let Ok(extracted_tag) = raw.tag() { + if extracted_tag != tag { + return Err(DeserializeError::new( + "skip_tag_wrapper", + DeserializeFailure::TagMismatch { + found: extracted_tag, + expected: tag, + }, + )); + } + return Ok(()); + } + Ok(()) +} + +pub(super) fn skip_set_tag_wrapperr( + raw: &mut Deserializer, +) -> Result<(), DeserializeError> { + skip_tag_wrapper(raw, 258) +} diff --git a/rust/src/tests/serialization/certificates.rs b/rust/src/tests/serialization/certificates.rs index af497354..3f8c4339 100644 --- a/rust/src/tests/serialization/certificates.rs +++ b/rust/src/tests/serialization/certificates.rs @@ -2,8 +2,8 @@ use crate::fakes::{ fake_anchor_data_hash, fake_genesis_delegate_hash, fake_genesis_hash, fake_key_hash, fake_pool_metadata_hash, fake_script_hash, fake_vrf_key_hash, }; -use crate::*; use crate::tests::mock_objects::create_anchor; +use crate::*; macro_rules! to_from_test { ($cert_type: ty, $variable_name: ident, $variable_wrapped_name: ident) => { @@ -48,10 +48,8 @@ fn committee_cold_resign_key_hash_ser_round_trip() { #[test] fn committee_cold_resign_with_anchor_ser_round_trip() { let anchor = create_anchor(); - let cert = CommitteeColdResign::new_with_anchor( - &Credential::from_keyhash(&fake_key_hash(1)), - &anchor, - ); + let cert = + CommitteeColdResign::new_with_anchor(&Credential::from_keyhash(&fake_key_hash(1)), &anchor); let cert_wrapped = Certificate::new_committee_cold_resign(&cert); to_from_test!(CommitteeColdResign, cert, cert_wrapped); assert_eq!( @@ -62,8 +60,7 @@ fn committee_cold_resign_with_anchor_ser_round_trip() { #[test] fn committee_cold_resign_script_hash_ser_round_trip() { - let cert = - CommitteeColdResign::new(&Credential::from_scripthash(&fake_script_hash(1))); + let cert = CommitteeColdResign::new(&Credential::from_scripthash(&fake_script_hash(1))); let cert_wrapped = Certificate::new_committee_cold_resign(&cert); to_from_test!(CommitteeColdResign, cert, cert_wrapped); assert_eq!( @@ -383,3 +380,13 @@ fn tx_with_drep_reg_deleg_test() { let cert = tx_deser.unwrap().body().certs().unwrap().get(0); assert!(cert.as_vote_delegation().is_some()); } + +#[test] +fn block_with_tx_with_certs_under_tag_set() { + let cbor = "85828a1a00093ff71a00b90a7e582030cf3798ec016ed63988b2e413fdadf4bda64e5b78587b74dec3e8807b3fd28058204e6f414dc8f402a977ef31062cae0e1251db537980f84c0e8623696975083fc15820f2768101e877acd0e08764765552a36c0f1a25e86d461c277bc19d0e476253fd825840622a847f3c0e77b608aa2aa1cff5c389348e80db4aa0d63b42d89753d5630cb0fcabbfd7293ee65a6b795c52cb4bd6b338f9d11fd007406fcbe89d06bb34f1145850d2c8f8179a8009b0979762ac10c6a514d8d0bc6b6d0d4413a0edbd5dbe888a8e72ba874d0f692ec940e58513c5b8ccb5072839ea1fa00776b4dcb493be8131b1a0b21bf5b5be5ff264e209fef448a30419016c5820388135462552cc6045399bd62876b28b768a760dd9a64adedbf7499bdb7cd1be8458202495446005fecca3a7ede95738dad5fd87393e81c815bde94a405be5779368c30218425840979096c8f12db5dc84a483626c966b64c10e16453b14f33b9648c250b096e391f6e9e6773017134a39c080d77f132950f43522015e9fa265695ee939625f89078209005901c0681c0f99e6f0d09b66b3e8e6eaed6a92649b635225f7d374a92af1a7ba2771880d14719c229892943bb85ba51699ae50bf7ae174e2e9869af7e289355aab000e741588d3b8c82efa6063c83fe326b72eb93f93bea07c5b5b9a720e9f9ecc20e47598b3ce56f370b268a2e2e075f24942e547d29182cecefdb9e7e45108e2261dd3d006ab778cba4cf0bced84f41fc61afcd79591d988eb401e2f870122ae590aec3467f464cebca50c5434d2491f631ebb3d835f43682244bcc839bd83e1c48950bcc73cfe5feaaa211d964bd9bdb4f9acd23fde11f469f6e0fb8bcc9aa4130a54ccab7381968e67ad1291bcdb8528228bbbb9fe15f72cf125b4de1cfdf3dd2b0d9189347a6964f17ce5063b75df8dd20f0fceeefb0d2f5781d34a03f14361ad4b9acb6c40c33ae366906f69dd422e5f2e00afd6bbecba078aebc53a69c567a864548da0205ed92937b4efbb12ab49273e598e3ec5f55abfcaae36c856024c6de779e8f2e28d997b94e116a7b6438cc04fb25b1dbb494b32e1eb97139e6d62e6a70fb2b480dc356225977a6b6b0a5bb9822d2dd5e0012c5de011219b8adc70af87304ab2c98c457078e0b859f50f69bd5eaaaf44e62d34776c8a6bcffd3c1bae81a40081825820b45589419cdc8218dabf8805fd09dded29c795939588fd2f1c397fcd29207307000181825839002844d663085837e4620b9114498f2a4577f2942d84573f95255cdea32134ccb579707f289dc83bc0fb386199a9cea4f1b0177d8384adbb1d1b0000000253eac253021a00029d2d04d901028182008200581c2134ccb579707f289dc83bc0fb386199a9cea4f1b0177d8384adbb1d81a100828258206f92479dc8d89cae74346be2e31997f8c04c977fabb3c806fd1740e7af20874b5840c3d442ba9e0c0915917eb64045603e6b90e0c2cf11c796b7c327f79a4c6e971149bcbbeae79339db8b557345c08de1f103e11c2032348825de9bc5e44150d1018258207be0e76fe15de98ecc3f02e95d4ec171ef884a6ca22b7623c75f66a07f16f3f458409644a34175257eec09a2b0ab52cc36b5bcfeea590d1ae7ead57604ce30be1ad79ecea7c07eadb7973c0c3fd99d63303b47f156fb767a4aa3180c4ed436233f05a080"; + let block = Block::from_hex(cbor); + assert!(block.is_ok()); + + let certs = block.unwrap().transaction_bodies.0[0].certs().unwrap(); + assert_eq!(certs.len(), 1); +} From bfe72bbb0474db6760e5fe34b4b1e1d35a92a0f0 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 4 Nov 2023 00:27:31 +0800 Subject: [PATCH 190/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 34bd94ba..2d08384e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.12", + "version": "12.0.0-alpha.13", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 83d2c9f5..422a51fd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.12", + "version": "12.0.0-alpha.13", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 9e2a305f..a29e779d 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.12" +version = "12.0.0-alpha.13" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 11658984..4ded9161 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -37,7 +37,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.12" +version = "12.0.0-alpha.13" dependencies = [ "bech32", "cbor_event", From e28f482c64f3061bed7b3b0a8d5e0d2f603995ac Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 7 Nov 2023 16:42:49 +0800 Subject: [PATCH 191/349] fix committee certs naming --- .../certificates/certificate.rs | 12 +++++----- ...gistration.rs => committee_cold_resign.rs} | 0 ..._registration.rs => committee_hot_auth.rs} | 0 rust/src/protocol_types/certificates/mod.rs | 8 +++---- rust/src/tests/protocol_types/certificates.rs | 24 +++++++++---------- rust/src/tests/serialization/certificates.rs | 8 +++---- 6 files changed, 26 insertions(+), 26 deletions(-) rename rust/src/protocol_types/certificates/{committee_hot_key_deregistration.rs => committee_cold_resign.rs} (100%) rename rust/src/protocol_types/certificates/{committee_hot_key_registration.rs => committee_hot_auth.rs} (100%) diff --git a/rust/src/protocol_types/certificates/certificate.rs b/rust/src/protocol_types/certificates/certificate.rs index 9d9ba08f..dfe49dd6 100644 --- a/rust/src/protocol_types/certificates/certificate.rs +++ b/rust/src/protocol_types/certificates/certificate.rs @@ -112,18 +112,18 @@ impl Certificate { } pub fn new_committee_hot_auth( - committee_hot_key_registration: &CommitteeHotAuth, + committee_hot_auth: &CommitteeHotAuth, ) -> Self { Self(CertificateEnum::CommitteeHotAuth( - committee_hot_key_registration.clone(), + committee_hot_auth.clone(), )) } pub fn new_committee_cold_resign( - committee_hot_key_deregistration: &CommitteeColdResign, + committee_cold_resign: &CommitteeColdResign, ) -> Self { Self(CertificateEnum::CommitteeColdResign( - committee_hot_key_deregistration.clone(), + committee_cold_resign.clone(), )) } @@ -260,14 +260,14 @@ impl Certificate { } } - pub fn as_committee_hot_key_registration(&self) -> Option { + pub fn as_committee_hot_auth(&self) -> Option { match &self.0 { CertificateEnum::CommitteeHotAuth(x) => Some(x.clone()), _ => None, } } - pub fn as_committee_hot_key_deregistration(&self) -> Option { + pub fn as_committee_cold_resign(&self) -> Option { match &self.0 { CertificateEnum::CommitteeColdResign(x) => Some(x.clone()), _ => None, diff --git a/rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs b/rust/src/protocol_types/certificates/committee_cold_resign.rs similarity index 100% rename from rust/src/protocol_types/certificates/committee_hot_key_deregistration.rs rename to rust/src/protocol_types/certificates/committee_cold_resign.rs diff --git a/rust/src/protocol_types/certificates/committee_hot_key_registration.rs b/rust/src/protocol_types/certificates/committee_hot_auth.rs similarity index 100% rename from rust/src/protocol_types/certificates/committee_hot_key_registration.rs rename to rust/src/protocol_types/certificates/committee_hot_auth.rs diff --git a/rust/src/protocol_types/certificates/mod.rs b/rust/src/protocol_types/certificates/mod.rs index 0714273b..57ab6175 100644 --- a/rust/src/protocol_types/certificates/mod.rs +++ b/rust/src/protocol_types/certificates/mod.rs @@ -40,11 +40,11 @@ pub use stake_vote_registration_and_delegation::*; mod vote_registration_and_delegation; pub use vote_registration_and_delegation::*; -mod committee_hot_key_registration; -pub use committee_hot_key_registration::*; +mod committee_hot_auth; +pub use committee_hot_auth::*; -mod committee_hot_key_deregistration; -pub use committee_hot_key_deregistration::*; +mod committee_cold_resign; +pub use committee_cold_resign::*; mod drep_registration; pub use drep_registration::*; diff --git a/rust/src/tests/protocol_types/certificates.rs b/rust/src/tests/protocol_types/certificates.rs index 85dd70c6..27b5a088 100644 --- a/rust/src/tests/protocol_types/certificates.rs +++ b/rust/src/tests/protocol_types/certificates.rs @@ -6,41 +6,41 @@ use crate::tests::mock_objects::{crate_full_pool_params, create_anchor}; use crate::*; #[test] -fn committee_hot_key_deregistration_setters_getters_test() { +fn committee_cold_resign_setters_getters_test() { let cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); let cred_script_hash = Credential::from_scripthash(&fake_script_hash(2)); - let committee_hot_key_deregistration_1 = CommitteeColdResign::new(&cred_key_hash); + let committee_cold_resign_1 = CommitteeColdResign::new(&cred_key_hash); - let committee_hot_key_deregistration_2 = CommitteeColdResign::new(&cred_script_hash); + let committee_cold_resign_2 = CommitteeColdResign::new(&cred_script_hash); assert_eq!( - committee_hot_key_deregistration_1.committee_cold_key(), + committee_cold_resign_1.committee_cold_key(), cred_key_hash ); - assert!(!committee_hot_key_deregistration_1.has_script_credentials()); + assert!(!committee_cold_resign_1.has_script_credentials()); assert_eq!( - committee_hot_key_deregistration_2.committee_cold_key(), + committee_cold_resign_2.committee_cold_key(), cred_script_hash ); - assert!(committee_hot_key_deregistration_2.has_script_credentials()); + assert!(committee_cold_resign_2.has_script_credentials()); } #[test] -fn committee_hot_key_registration_setters_getters_test() { +fn committee_hot_auth_setters_getters_test() { let cold_cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); let hot_cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); - let committee_hot_key_registration = + let committee_hot_auth = CommitteeHotAuth::new(&cold_cred_key_hash, &hot_cred_key_hash); assert_eq!( - committee_hot_key_registration.committee_cold_key(), + committee_hot_auth.committee_cold_key(), cold_cred_key_hash ); assert_eq!( - committee_hot_key_registration.committee_hot_key(), + committee_hot_auth.committee_hot_key(), hot_cred_key_hash ); - assert!(!committee_hot_key_registration.has_script_credentials()); + assert!(!committee_hot_auth.has_script_credentials()); } #[test] diff --git a/rust/src/tests/serialization/certificates.rs b/rust/src/tests/serialization/certificates.rs index 3f8c4339..1fd065f1 100644 --- a/rust/src/tests/serialization/certificates.rs +++ b/rust/src/tests/serialization/certificates.rs @@ -41,7 +41,7 @@ fn committee_cold_resign_key_hash_ser_round_trip() { to_from_test!(CommitteeColdResign, cert, cert_wrapped); assert_eq!( cert, - cert_wrapped.as_committee_hot_key_deregistration().unwrap() + cert_wrapped.as_committee_cold_resign().unwrap() ); } @@ -54,7 +54,7 @@ fn committee_cold_resign_with_anchor_ser_round_trip() { to_from_test!(CommitteeColdResign, cert, cert_wrapped); assert_eq!( cert, - cert_wrapped.as_committee_hot_key_deregistration().unwrap() + cert_wrapped.as_committee_cold_resign().unwrap() ); } @@ -65,7 +65,7 @@ fn committee_cold_resign_script_hash_ser_round_trip() { to_from_test!(CommitteeColdResign, cert, cert_wrapped); assert_eq!( cert, - cert_wrapped.as_committee_hot_key_deregistration().unwrap() + cert_wrapped.as_committee_cold_resign().unwrap() ); } @@ -79,7 +79,7 @@ fn committee_hot_auth_ser_round_trip() { to_from_test!(CommitteeHotAuth, cert, cert_wrapped); assert_eq!( cert, - cert_wrapped.as_committee_hot_key_registration().unwrap() + cert_wrapped.as_committee_hot_auth().unwrap() ); } From 4ba6547f4d91644a70956e752b86347184a44a5a Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 13 Nov 2023 21:44:07 +0800 Subject: [PATCH 192/349] replace new_ref_input_with_lang_ver by new_ref_input --- rust/src/builders/script_structs.rs | 19 +------------------ rust/src/tests/builders/tx_builder.rs | 6 +++--- rust/src/tests/builders/voting_builder.rs | 2 +- .../tests/builders/voting_proposal_builder.rs | 2 +- 4 files changed, 6 insertions(+), 23 deletions(-) diff --git a/rust/src/builders/script_structs.rs b/rust/src/builders/script_structs.rs index 085c70cd..8f2339e2 100644 --- a/rust/src/builders/script_structs.rs +++ b/rust/src/builders/script_structs.rs @@ -31,24 +31,7 @@ impl PlutusScriptSource { pub fn new(script: &PlutusScript) -> Self { Self(PlutusScriptSourceEnum::Script(script.clone())) } - - /// !!! DEPRECATED !!! - /// This constructor has missed information about plutus script language vesrion. That can affect - /// the script data hash calculation. - /// Use `.new_ref_input_with_lang_ver` instead - #[deprecated( - since = "11.3.0", - note = "This constructor has missed information about plutus script language vesrion. That can affect the script data hash calculation. Use `.new_ref_input_with_lang_ver` instead." - )] - pub fn new_ref_input(script_hash: &ScriptHash, input: &TransactionInput) -> Self { - Self(PlutusScriptSourceEnum::RefInput( - input.clone(), - script_hash.clone(), - None, - )) - } - - pub fn new_ref_input_with_lang_ver( + pub fn new_ref_input( script_hash: &ScriptHash, input: &TransactionInput, lang_ver: &Language, diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index c03df3b6..ab42c740 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -5764,7 +5764,7 @@ fn plutus_mint_with_script_ref_test() { let asset_name = AssetName::from_hex("44544e4654").unwrap(); let mut mint_builder = MintBuilder::new(); let plutus_script_source = PlutusScriptSource::new(&plutus_script); - let plutus_script_source_ref = PlutusScriptSource::new_ref_input_with_lang_ver( + let plutus_script_source_ref = PlutusScriptSource::new_ref_input( &plutus_script2.hash(), &tx_input_ref, &Language::new_plutus_v2(), @@ -6240,12 +6240,12 @@ fn build_tx_with_certs_withdrawals_plutus_script_address() { let ref_cert_script_input_3 = fake_tx_input(1); let ref_cert_withdrawal_input_2 = fake_tx_input(2); - let plutus_cert_source = PlutusScriptSource::new_ref_input_with_lang_ver( + let plutus_cert_source = PlutusScriptSource::new_ref_input( &cert_script_hash3, &ref_cert_script_input_3, &Language::new_plutus_v2(), ); - let plutus_withdrawal_source = PlutusScriptSource::new_ref_input_with_lang_ver( + let plutus_withdrawal_source = PlutusScriptSource::new_ref_input( &withdraw_script_hash2, &ref_cert_withdrawal_input_2, &Language::new_plutus_v2(), diff --git a/rust/src/tests/builders/voting_builder.rs b/rust/src/tests/builders/voting_builder.rs index eefd4932..49883ab7 100644 --- a/rust/src/tests/builders/voting_builder.rs +++ b/rust/src/tests/builders/voting_builder.rs @@ -188,7 +188,7 @@ fn voting_builder_plutus_ref_witness() { let action_id = GovernanceActionId::new(&fake_tx_hash(1), 1); let vote = VotingProcedure::new(VoteKind::No); - let script_source = PlutusScriptSource::new_ref_input_with_lang_ver( + let script_source = PlutusScriptSource::new_ref_input( &script_hash, &ref_input, &Language::new_plutus_v2(), diff --git a/rust/src/tests/builders/voting_proposal_builder.rs b/rust/src/tests/builders/voting_proposal_builder.rs index e570e82a..c26cd47c 100644 --- a/rust/src/tests/builders/voting_proposal_builder.rs +++ b/rust/src/tests/builders/voting_proposal_builder.rs @@ -316,7 +316,7 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { ); let expected_redeemer = redeemer.clone_with_index_and_tag(&BigNum::from(1u64), &RedeemerTag::new_voting_proposal()); - let plutus_source = PlutusScriptSource::new_ref_input_with_lang_ver(&script_hash, &ref_input, &Language::new_plutus_v2()); + let plutus_source = PlutusScriptSource::new_ref_input(&script_hash, &ref_input, &Language::new_plutus_v2()); let plutus_witness = PlutusWitness::new_with_ref_without_datum( &plutus_source, &redeemer, From 177774e67014def040f74fe5496a4e3cd2a7ca98 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 14 Nov 2023 19:09:44 +0800 Subject: [PATCH 193/349] remove ability to add a script input without witness --- rust/src/address.rs | 14 +- rust/src/builders/tx_builder.rs | 72 +--- rust/src/builders/tx_inputs_builder.rs | 248 +++----------- rust/src/error.rs | 15 + rust/src/tests/builders/tx_builder.rs | 437 +++++-------------------- rust/src/tests/mock_objects.rs | 10 +- 6 files changed, 161 insertions(+), 635 deletions(-) diff --git a/rust/src/address.rs b/rust/src/address.rs index 962bbead..469e97ed 100644 --- a/rust/src/address.rs +++ b/rust/src/address.rs @@ -645,9 +645,9 @@ impl Deserialize for Address { #[wasm_bindgen] #[derive(Debug, Clone, Eq, Ord, PartialEq, PartialOrd)] pub struct BaseAddress { - network: u8, - payment: Credential, - stake: Credential, + pub(crate) network: u8, + pub(crate) payment: Credential, + pub(crate) stake: Credential, } #[wasm_bindgen] @@ -683,8 +683,8 @@ impl BaseAddress { #[wasm_bindgen] #[derive(Debug, Clone, Eq, Ord, PartialEq, PartialOrd)] pub struct EnterpriseAddress { - network: u8, - payment: Credential, + pub(crate) network: u8, + pub(crate) payment: Credential, } #[wasm_bindgen] @@ -715,8 +715,8 @@ impl EnterpriseAddress { #[wasm_bindgen] #[derive(Debug, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct RewardAddress { - network: u8, - payment: Credential, + pub(crate) network: u8, + pub(crate) payment: Credential, } #[wasm_bindgen] diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index 2ba005ce..fd0a8874 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -414,7 +414,7 @@ impl TransactionBuilder { &input.input, &input.output.amount, )?; - self.add_input(&input.output.address, &input.input, &input.output.amount); + self.add_regular_input(&input.output.address, &input.input, &input.output.amount); input_total = input_total.checked_add(&input.output.amount)?; output_total = output_total.checked_add(&Value::new(&input_fee))?; } @@ -494,7 +494,7 @@ impl TransactionBuilder { &input.input, &input.output.amount, )?; - self.add_input(&input.output.address, &input.input, &input.output.amount); + self.add_regular_input(&input.output.address, &input.input, &input.output.amount); input_total = input_total.checked_add(&input.output.amount)?; output_total = output_total.checked_add(&Value::new(&input_fee))?; } @@ -532,7 +532,7 @@ impl TransactionBuilder { // differing from CIP2, we include the needed fees in the targets instead of just output values let input_fee = self.fee_for_input(&input.output.address, &input.input, &input.output.amount)?; - self.add_input(&input.output.address, &input.input, &input.output.amount); + self.add_regular_input(&input.output.address, &input.input, &input.output.amount); *input_total = input_total.checked_add(&input.output.amount)?; *output_total = output_total.checked_add(&Value::new(&input_fee))?; available_indices.swap_remove(available_indices.iter().position(|j| i == j).unwrap()); @@ -650,7 +650,7 @@ impl TransactionBuilder { &input.input, &input.output.amount, )?; - self.add_input(&input.output.address, &input.input, &input.output.amount); + self.add_regular_input(&input.output.address, &input.input, &input.output.amount); *input_total = input_total.checked_add(&input.output.amount)?; *output_total = output_total.checked_add(&Value::new(&input_fee))?; } @@ -763,23 +763,6 @@ impl TransactionBuilder { self.inputs.add_key_input(hash, input, amount); } - /// This method adds the input to the builder BUT leaves a missing spot for the witness native script - /// - /// After adding the input with this method, use `.add_required_native_input_scripts` - /// and `.add_required_plutus_input_scripts` to add the witness scripts - /// - /// Or instead use `.add_native_script_input` and `.add_plutus_script_input` - /// to add inputs right along with the script, instead of the script hash - #[deprecated(since = "10.2.0", note = "Use `.set_inputs`")] - pub fn add_script_input( - &mut self, - hash: &ScriptHash, - input: &TransactionInput, - amount: &Value, - ) { - self.inputs.add_script_input(hash, input, amount); - } - /// This method will add the input to the builder and also register the required native script witness #[deprecated(since = "10.2.0", note = "Use `.set_inputs`")] pub fn add_native_script_input( @@ -812,41 +795,15 @@ impl TransactionBuilder { self.inputs.add_bootstrap_input(hash, input, amount); } - /// Note that for script inputs this method will use underlying generic `.add_script_input` - /// which leaves a required empty spot for the script witness (or witnesses in case of Plutus). - /// You can use `.add_native_script_input` or `.add_plutus_script_input` directly to register the input along with the witness. - #[deprecated(since = "10.2.0", note = "Use `.set_inputs`")] - pub fn add_input(&mut self, address: &Address, input: &TransactionInput, amount: &Value) { - self.inputs.add_input(address, input, amount); - } - - /// Returns the number of still missing input scripts (either native or plutus) - /// Use `.add_required_native_input_scripts` or `.add_required_plutus_input_scripts` to add the missing scripts - #[deprecated( - since = "10.2.0", - note = "Use `.count_missing_input_scripts` from `TxInputsBuilder`" - )] - pub fn count_missing_input_scripts(&self) -> usize { - self.inputs.count_missing_input_scripts() - } - - /// Try adding the specified scripts as witnesses for ALREADY ADDED script inputs - /// Any scripts that don't match any of the previously added inputs will be ignored - /// Returns the number of remaining required missing witness scripts - /// Use `.count_missing_input_scripts` to find the number of still missing scripts - #[deprecated(since = "10.2.0", note = "Use `.set_inputs`")] - pub fn add_required_native_input_scripts(&mut self, scripts: &NativeScripts) -> usize { - self.inputs.add_required_native_input_scripts(scripts) + /// This function is replace for previous one add_input. + /// The functions adds a non script input, if it is a script input it returns an error. + /// To add script input you need to use add_native_script_input or add_plutus_script_input. + /// Also we recommend to use TxInputsBuilder and .set_inputs, because all add_*_input functions might be removed from transaction builder. + #[deprecated(since = "12.0.0", note = "Use `.set_inputs`")] + pub fn add_regular_input(&mut self, address: &Address, input: &TransactionInput, amount: &Value) -> Result<(), JsError>{ + self.inputs.add_regular_input(address, input, amount) } - /// Try adding the specified scripts as witnesses for ALREADY ADDED script inputs - /// Any scripts that don't match any of the previously added inputs will be ignored - /// Returns the number of remaining required missing witness scripts - /// Use `.count_missing_input_scripts` to find the number of still missing scripts - #[deprecated(since = "10.2.0", note = "Use `.set_inputs`")] - pub fn add_required_plutus_input_scripts(&mut self, scripts: &PlutusWitnesses) -> usize { - self.inputs.add_required_plutus_input_scripts(scripts) - } /// Returns a copy of the current script input witness scripts in the builder #[deprecated(since = "10.2.0", note = "Use `.set_inputs`")] @@ -877,7 +834,7 @@ impl TransactionBuilder { let fee_before = min_fee(&self_copy)?; - self_copy.add_input(&address, &input, &amount); + self_copy.add_regular_input(&address, &input, &amount); let fee_after = min_fee(&self_copy)?; fee_after.checked_sub(&fee_before) } @@ -2164,11 +2121,6 @@ impl TransactionBuilder { /// NOTE: is_valid set to true /// NOTE: Will fail in case there are any script inputs added with no corresponding witness pub fn build_tx(&self) -> Result { - if self.count_missing_input_scripts() > 0 { - return Err(JsError::from_str( - "There are some script inputs added that don't have the corresponding script provided as a witness!", - )); - } if self.has_plutus_inputs() { if self.script_data_hash.is_none() { return Err(JsError::from_str( diff --git a/rust/src/builders/tx_inputs_builder.rs b/rust/src/builders/tx_inputs_builder.rs index 0d987d5e..2e15cedf 100644 --- a/rust/src/builders/tx_inputs_builder.rs +++ b/rust/src/builders/tx_inputs_builder.rs @@ -8,60 +8,6 @@ pub(crate) struct TxBuilderInput { pub(crate) amount: Value, // we need to keep track of the amount in the inputs for input selection } -#[wasm_bindgen] -#[derive(Clone, Debug)] -pub struct InputWithScriptWitness { - pub(crate) input: TransactionInput, - pub(crate) witness: ScriptWitnessType, -} - -#[wasm_bindgen] -impl InputWithScriptWitness { - pub fn new_with_native_script_witness( - input: &TransactionInput, - witness: &NativeScript, - ) -> Self { - Self { - input: input.clone(), - witness: ScriptWitnessType::NativeScriptWitness(NativeScriptSourceEnum::NativeScript( - witness.clone(), - )), - } - } - - pub fn new_with_plutus_witness(input: &TransactionInput, witness: &PlutusWitness) -> Self { - Self { - input: input.clone(), - witness: ScriptWitnessType::PlutusScriptWitness(witness.clone()), - } - } - - pub fn input(&self) -> TransactionInput { - self.input.clone() - } -} - -#[wasm_bindgen] -pub struct InputsWithScriptWitness(Vec); - -#[wasm_bindgen] -impl InputsWithScriptWitness { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn add(&mut self, input: &InputWithScriptWitness) { - self.0.push(input.clone()); - } - - pub fn get(&self, index: usize) -> InputWithScriptWitness { - self.0[index].clone() - } - - pub fn len(&self) -> usize { - self.0.len() - } -} // We need to know how many of each type of witness will be in the transaction so we can calculate the tx fee #[derive(Clone, Debug)] @@ -116,20 +62,7 @@ impl TxInputsBuilder { self.required_witnesses.vkeys.insert(hash.clone()); } - #[deprecated( - since = "11.2.0", - note = "Use `.add_native_script_input` or `.add_plutus_script_input` instead." - )] - /// !!! DEPRECATED !!! - /// This function can make a mistake in choosing right input index. Use `.add_native_script_input` or `.add_plutus_script_input` instead. - /// This method adds the input to the builder BUT leaves a missing spot for the witness native script - /// - /// After adding the input with this method, use `.add_required_native_input_scripts` - /// and `.add_required_plutus_input_scripts` to add the witness scripts - /// - /// Or instead use `.add_native_script_input` and `.add_plutus_script_input` - /// to add inputs right along with the script, instead of the script hash - pub fn add_script_input( + fn add_script_input( &mut self, hash: &ScriptHash, input: &TransactionInput, @@ -186,151 +119,52 @@ impl TxInputsBuilder { self.required_witnesses.bootstraps.insert(hash.to_bytes()); } - /// Note that for script inputs this method will use underlying generic `.add_script_input` - /// which leaves a required empty spot for the script witness (or witnesses in case of Plutus). - /// You can use `.add_native_script_input` or `.add_plutus_script_input` directly to register the input along with the witness. - pub fn add_input(&mut self, address: &Address, input: &TransactionInput, amount: &Value) { - match &BaseAddress::from_address(address) { - Some(addr) => { - match &addr.payment_cred().to_keyhash() { - Some(hash) => return self.add_key_input(hash, input, amount), - None => (), - } - match &addr.payment_cred().to_scripthash() { - Some(hash) => return self.add_script_input(hash, input, amount), - None => (), - } - } - None => (), - } - match &EnterpriseAddress::from_address(address) { - Some(addr) => { - match &addr.payment_cred().to_keyhash() { - Some(hash) => return self.add_key_input(hash, input, amount), - None => (), + /// Adds non script input, in case of script or reward address input it will return an error + pub fn add_regular_input(&mut self, address: &Address, input: &TransactionInput, amount: &Value) -> Result<(), JsError>{ + match &address.0 { + AddrType::Base(base_addr) => { + match &base_addr.payment.0 { + CredType::Key(key) => { + self.add_key_input(key, input, amount); + Ok(()) + }, + CredType::Script(_) => { + Err(JsError::from_str(BuilderError::RegularInputIsScript.as_str())) + }, } - match &addr.payment_cred().to_scripthash() { - Some(hash) => return self.add_script_input(hash, input, amount), - None => (), - } - } - None => (), - } - match &PointerAddress::from_address(address) { - Some(addr) => { - match &addr.payment_cred().to_keyhash() { - Some(hash) => return self.add_key_input(hash, input, amount), - None => (), + }, + AddrType::Enterprise(ent_aaddr) => { + match &ent_aaddr.payment.0 { + CredType::Key(key) => { + self.add_key_input(key, input, amount); + Ok(()) + }, + CredType::Script(_) => { + Err(JsError::from_str(BuilderError::RegularInputIsScript.as_str())) + }, } - match &addr.payment_cred().to_scripthash() { - Some(hash) => return self.add_script_input(hash, input, amount), - None => (), + }, + AddrType::Ptr(ptr_addr) => { + match &ptr_addr.payment.0 { + CredType::Key(key) => { + self.add_key_input(key, input, amount); + Ok(()) + }, + CredType::Script(_) => { + Err(JsError::from_str(BuilderError::RegularInputIsScript.as_str())) + }, } - } - None => (), - } - match &ByronAddress::from_address(address) { - Some(addr) => { - return self.add_bootstrap_input(addr, input, amount); - } - None => (), + }, + AddrType::Byron(byron_addr) => { + self.add_bootstrap_input(byron_addr, input, amount); + Ok(()) + }, + AddrType::Reward(_) => { + Err(JsError::from_str(BuilderError::RegularInputIsFromRewardAddress.as_str())) + }, } } - /// Returns the number of still missing input scripts (either native or plutus) - /// Use `.add_required_native_input_scripts` or `.add_required_plutus_input_scripts` to add the missing scripts - pub fn count_missing_input_scripts(&self) -> usize { - self.required_witnesses - .scripts - .values() - .flat_map(|v| v.values()) - .filter(|s| s.is_none()) - .count() - } - - /// Try adding the specified scripts as witnesses for ALREADY ADDED script inputs - /// Any scripts that don't match any of the previously added inputs will be ignored - /// Returns the number of remaining required missing witness scripts - /// Use `.count_missing_input_scripts` to find the number of still missing scripts - pub fn add_required_native_input_scripts(&mut self, scripts: &NativeScripts) -> usize { - scripts.0.iter().for_each(|s: &NativeScript| { - let hash = s.hash(); - if let Some(script_wits) = self.required_witnesses.scripts.get_mut(&hash) { - let mut tx_in = None; - for script_wit in script_wits { - if script_wit.1.is_none() { - tx_in = Some(script_wit.0.clone()); - break; - } - } - - if let Some(tx_in) = tx_in { - let witness = ScriptWitnessType::NativeScriptWitness( - NativeScriptSourceEnum::NativeScript(s.clone()), - ); - self.insert_input_with_witness(&hash, &tx_in, &witness); - } - } - }); - self.count_missing_input_scripts() - } - - #[deprecated( - since = "11.2.0", - note = "This function can make a mistake in choosing right input index. Use `.add_required_script_input_witnesses` instead." - )] - /// !!! DEPRECATED !!! - /// This function can make a mistake in choosing right input index. Use `.add_required_script_input_witnesses` instead. - /// Try adding the specified scripts as witnesses for ALREADY ADDED script inputs - /// Any scripts that don't match any of the previously added inputs will be ignored - /// Returns the number of remaining required missing witness scripts - /// Use `.count_missing_input_scripts` to find the number of still missing scripts - pub fn add_required_plutus_input_scripts(&mut self, scripts: &PlutusWitnesses) -> usize { - scripts.0.iter().for_each(|s: &PlutusWitness| { - let hash = s.script.script_hash(); - if let Some(script_wits) = self.required_witnesses.scripts.get_mut(&hash) { - let mut tx_in = None; - for script_wit in script_wits { - if script_wit.1.is_none() { - tx_in = Some(script_wit.0.clone()); - break; - } - } - - if let Some(tx_in) = tx_in { - let witness = ScriptWitnessType::PlutusScriptWitness(s.clone()); - self.insert_input_with_witness(&hash, &tx_in, &witness); - } - } - }); - self.count_missing_input_scripts() - } - - /// Try adding the specified scripts as witnesses for ALREADY ADDED script inputs - /// Any scripts that don't match any of the previously added inputs will be ignored - /// Returns the number of remaining required missing witness scripts - /// Use `.count_missing_input_scripts` to find the number of still missing scripts - pub fn add_required_script_input_witnesses( - &mut self, - inputs_with_wit: &InputsWithScriptWitness, - ) -> usize { - inputs_with_wit - .0 - .iter() - .for_each(|input_with_wit: &InputWithScriptWitness| { - let hash = input_with_wit.witness.script_hash(); - if let Some(script_wits) = self.required_witnesses.scripts.get_mut(&hash) { - if script_wits.contains_key(&input_with_wit.input) { - script_wits.insert( - input_with_wit.input.clone(), - Some(input_with_wit.witness.clone()), - ); - } - } - }); - self.count_missing_input_scripts() - } - pub fn get_ref_inputs(&self) -> TransactionInputs { let mut inputs = Vec::new(); for wintess in self diff --git a/rust/src/error.rs b/rust/src/error.rs index 79dc9917..c1c32b88 100644 --- a/rust/src/error.rs +++ b/rust/src/error.rs @@ -1,3 +1,4 @@ +use std::string::ToString; use super::*; use crate::chain_crypto; use cbor_event::{self}; @@ -222,3 +223,17 @@ impl std::fmt::Display for JsError { #[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))] impl std::error::Error for JsError {} + +pub(crate) enum BuilderError { + RegularInputIsScript, + RegularInputIsFromRewardAddress, +} + +impl BuilderError { + pub(crate) fn as_str(&self) -> &'static str { + match self { + BuilderError::RegularInputIsScript => "You can't add a script input to this function. You can use `.add_native_script_input` or `.add_plutus_script_input` directly to register the input along with the witness.", + BuilderError::RegularInputIsFromRewardAddress => "You can't use an input from reward address. To spend funds from reward address you to use withdrawal mechanism.", + } + } +} diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index ab42c740..b0649b7b 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -570,13 +570,13 @@ fn build_tx_with_inputs() { .to_str(), "69500" ); - tx_builder.add_input( + tx_builder.add_regular_input( &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(1_000_000)), ); } - tx_builder.add_input( + tx_builder.add_regular_input( &BaseAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -586,7 +586,7 @@ fn build_tx_with_inputs() { &TransactionInput::new(&genesis_id(), 1), &Value::new(&to_bignum(1_000_000)), ); - tx_builder.add_input( + tx_builder.add_regular_input( &PointerAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -596,7 +596,7 @@ fn build_tx_with_inputs() { &TransactionInput::new(&genesis_id(), 2), &Value::new(&to_bignum(1_000_000)), ); - tx_builder.add_input( + tx_builder.add_regular_input( &ByronAddress::icarus_from_key(&spend, NetworkInfo::testnet().protocol_magic()) .to_address(), &TransactionInput::new(&genesis_id(), 3), @@ -651,7 +651,7 @@ fn build_tx_with_script_ref() { tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 3)); tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 4)); - tx_builder.add_input( + tx_builder.add_regular_input( &PointerAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -732,7 +732,7 @@ fn serialization_tx_body_with_script_ref() { tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 3)); tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 4)); - tx_builder.add_input( + tx_builder.add_regular_input( &PointerAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -813,7 +813,7 @@ fn json_serialization_tx_body_with_script_ref() { tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 3)); tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 4)); - tx_builder.add_input( + tx_builder.add_regular_input( &PointerAddress::new( NetworkInfo::testnet().network_id(), &spend_cred, @@ -892,7 +892,7 @@ fn build_tx_with_mint_all_sent() { let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); // Input with 150 coins - tx_builder.add_input( + tx_builder.add_regular_input( &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(500)), @@ -980,7 +980,7 @@ fn build_tx_with_mint_in_change() { let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); // Input with 600 coins - tx_builder.add_input( + tx_builder.add_regular_input( &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(600)), @@ -1089,13 +1089,13 @@ fn change_with_input_and_mint_not_enough_ada() { mass_input.insert(&policy_id, &asset_input); // Input with 600 coins - tx_builder.add_input( + tx_builder.add_regular_input( &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(600)), ); - tx_builder.add_input( + tx_builder.add_regular_input( &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), &TransactionInput::new(&genesis_id(), 1), &Value::new_with_assets(&to_bignum(1), &mass_input), @@ -1185,13 +1185,13 @@ fn change_with_input_and_mint_not_enough_assets() { mass_input.insert(&policy_id, &asset_input); // Input with 600 coins - tx_builder.add_input( + tx_builder.add_regular_input( &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(100000)), ); - tx_builder.add_input( + tx_builder.add_regular_input( &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), &TransactionInput::new(&genesis_id(), 1), &Value::new_with_assets(&to_bignum(1), &mass_input), @@ -1708,7 +1708,7 @@ fn build_tx_burn_less_than_min_ada() { ) .unwrap(); - tx_builder.add_input( + tx_builder.add_regular_input( &ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") .unwrap() .to_address(), @@ -1760,7 +1760,7 @@ fn build_tx_burn_empty_assets() { let mut input_value = Value::new(&to_bignum(2_400_000)); input_value.set_multiasset(&MultiAsset::new()); - tx_builder.add_input( + tx_builder.add_regular_input( &ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") .unwrap() .to_address(), @@ -1810,7 +1810,7 @@ fn build_tx_no_useless_multiasset() { }); input_amount.set_multiasset(&input_multiasset); - tx_builder.add_input( + tx_builder.add_regular_input( &ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") .unwrap() .to_address(), @@ -1892,7 +1892,7 @@ fn build_tx_add_change_split_nfts() { let mut input_value = Value::new(&to_bignum(1000)); input_value.set_multiasset(&multiasset); - tx_builder.add_input( + tx_builder.add_regular_input( &ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") .unwrap() .to_address(), @@ -1952,7 +1952,7 @@ fn build_tx_add_change_split_nfts() { fn build_tx_too_big_output() { let mut tx_builder = create_tx_builder_with_fee_and_val_size(&create_linear_fee(0, 1), 10); - tx_builder.add_input( + tx_builder.add_regular_input( &ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") .unwrap() .to_address(), @@ -2013,7 +2013,7 @@ fn build_tx_add_change_nfts_not_enough_ada() { let mut input_value = Value::new(&to_bignum(58)); input_value.set_multiasset(&multiasset); - tx_builder.add_input( + tx_builder.add_regular_input( &ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") .unwrap() .to_address(), @@ -2357,7 +2357,7 @@ fn tx_builder_cip2_random_improve_multiasset() { .unwrap(); let input_for_cover_change = make_input(10u8, Value::new(&to_bignum(1000))); - tx_builder.add_input( + tx_builder.add_regular_input( &input_for_cover_change.output.address, &input_for_cover_change.input, &input_for_cover_change.output.amount, @@ -2651,7 +2651,7 @@ fn build_tx_multisig_spend_1on1_unsigned() { ) .to_address(); - tx_builder.add_input( + tx_builder.add_regular_input( &addr_multisig, &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(1_000_000)), @@ -2842,7 +2842,7 @@ fn add_change_splits_change_into_multiple_outputs_when_nfts_overflow_output_size let mut input_value = Value::new(&to_bignum(1200)); input_value.set_multiasset(&multiasset); - tx_builder.add_input( + tx_builder.add_regular_input( &ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") .unwrap() .to_address(), @@ -3764,75 +3764,13 @@ fn create_base_address_from_script_hash(sh: &ScriptHash) -> Address { .to_address() } -#[test] -fn test_set_input_scripts() { - let mut tx_builder = create_reallistic_tx_builder(); - let (script1, hash1) = mint_script_and_policy(0); - let (script2, hash2) = mint_script_and_policy(1); - let (script3, _hash3) = mint_script_and_policy(2); - // Trying to set native scripts to the builder - let rem0 = tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![ - script1.clone(), - script2.clone(), - script3.clone(), - ])); - assert_eq!(rem0, 0); - let missing0 = tx_builder.count_missing_input_scripts(); - assert_eq!(missing0, 0); - // Adding two script inputs using script1 and script2 hashes - tx_builder.add_input( - &create_base_address_from_script_hash(&hash1), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - tx_builder.add_input( - &create_base_address_from_script_hash(&hash2), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - // Setting a non-matching script will not change anything - let rem1 = - tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![script3.clone()])); - assert_eq!(rem1, 2); - let missing1 = tx_builder.count_missing_input_scripts(); - assert_eq!(missing1, 2); - // Setting one of the required scripts leaves one to be required - let rem2 = tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![ - script1.clone(), - script3.clone(), - ])); - assert_eq!(rem2, 1); - let missing2 = tx_builder.count_missing_input_scripts(); - assert_eq!(missing2, 1); - // Setting one non-required script again does not change anything - // But shows the state has changed - let rem3 = - tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![script3.clone()])); - assert_eq!(rem3, 1); - let missing3 = tx_builder.count_missing_input_scripts(); - assert_eq!(missing3, 1); - // Setting two required scripts will show both of them added - // And the remainder required is zero - let rem4 = tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![ - script1.clone(), - script2.clone(), - ])); - assert_eq!(rem4, 0); - let missing4 = tx_builder.count_missing_input_scripts(); - assert_eq!(missing4, 0); - // Setting empty scripts does not change anything - // But shows the state has changed - let rem5 = tx_builder.add_required_native_input_scripts(&NativeScripts::new()); - assert_eq!(rem5, 0); -} - #[test] fn test_add_native_script_input() { let mut tx_builder = create_reallistic_tx_builder(); - let (script1, _hash1) = mint_script_and_policy(0); - let (script2, _hash2) = mint_script_and_policy(1); - let (script3, hash3) = mint_script_and_policy(2); - // Adding two script inputs directly with their witness + let (script1, _) = mint_script_and_policy(0); + let (script2, _) = mint_script_and_policy(1); + + // Adding two script inputs using script1 and script2 hashes tx_builder.add_native_script_input( &script1, &TransactionInput::new(&genesis_id(), 0), @@ -3843,22 +3781,8 @@ fn test_add_native_script_input() { &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(1_000_000)), ); - // Adding one script input indirectly via hash3 address - tx_builder.add_input( - &create_base_address_from_script_hash(&hash3), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - // Checking missing input scripts shows one - // Because first two inputs already have their witness - let missing1 = tx_builder.count_missing_input_scripts(); - assert_eq!(missing1, 1); - // Setting the required script leaves none to be required` - let rem1 = - tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![script3.clone()])); - assert_eq!(rem1, 0); - let missing2 = tx_builder.count_missing_input_scripts(); - assert_eq!(missing2, 0); + + assert_eq!(tx_builder.inputs.get_native_input_scripts().unwrap().len(), 2); } fn unsafe_tx_len(b: &TransactionBuilder) -> usize { @@ -3868,34 +3792,21 @@ fn unsafe_tx_len(b: &TransactionBuilder) -> usize { #[test] fn test_native_input_scripts_are_added_to_the_witnesses() { let mut tx_builder = create_reallistic_tx_builder(); - let (script1, _hash1) = mint_script_and_policy(0); - let (script2, hash2) = mint_script_and_policy(1); + let (script1, _) = mint_script_and_policy(0); + let (script2, _) = mint_script_and_policy(1); tx_builder.set_fee(&to_bignum(42)); + tx_builder.add_native_script_input( &script1, &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(1_000_000)), ); - let tx_len_before_new_script_input = unsafe_tx_len(&tx_builder); - tx_builder.add_input( - &create_base_address_from_script_hash(&hash2), + tx_builder.add_native_script_input( + &script2, &TransactionInput::new(&genesis_id(), 1), &Value::new(&to_bignum(1_000_000)), ); - let tx_len_after_new_script_input = unsafe_tx_len(&tx_builder); - // Tx size increased cuz input is added even without the witness - assert!(tx_len_after_new_script_input > tx_len_before_new_script_input); - tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![script2.clone()])); - let tx_len_after_adding_script_witness = unsafe_tx_len(&tx_builder); - // Tx size increased cuz the witness is added to the witnesses - assert!(tx_len_after_adding_script_witness > tx_len_after_new_script_input); - tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![ - script1.clone(), - script2.clone(), - ])); - let tx_len_after_adding_script_witness_again = unsafe_tx_len(&tx_builder); - // Tx size did not change because calling to add same witnesses again doesn't change anything - assert!(tx_len_after_adding_script_witness == tx_len_after_adding_script_witness_again); + let tx: Transaction = tx_builder.build_tx_unsafe().unwrap(); assert!(tx.witness_set.native_scripts.is_some()); let native_scripts = tx.witness_set.native_scripts.unwrap(); @@ -3904,38 +3815,6 @@ fn test_native_input_scripts_are_added_to_the_witnesses() { assert_eq!(native_scripts.get(1), script2); } -#[test] -fn test_building_with_missing_witness_script_fails() { - let mut tx_builder = create_reallistic_tx_builder(); - let (script1, _hash1) = mint_script_and_policy(0); - let (script2, hash2) = mint_script_and_policy(1); - tx_builder.set_fee(&to_bignum(42)); - // Ok to build before any inputs - assert!(tx_builder.build_tx().is_ok()); - // Adding native script input which adds the witness right away - tx_builder.add_native_script_input( - &script1, - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - // Ok to build when witness is added along with the input - assert!(tx_builder.build_tx().is_ok()); - // Adding script input without the witness - tx_builder.add_input( - &create_base_address_from_script_hash(&hash2), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ); - // Not ok to build when missing a witness - assert!(tx_builder.build_tx().is_err()); - // Can force to build using unsafe - assert!(tx_builder.build_tx_unsafe().is_ok()); - // Adding the missing witness script - tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![script2.clone()])); - // Ok to build when all witnesses are added - assert!(tx_builder.build_tx().is_ok()); -} - #[test] fn test_adding_plutus_script_input() { let mut tx_builder = create_reallistic_tx_builder(); @@ -3955,7 +3834,6 @@ fn test_adding_plutus_script_input() { ); tx_builder.set_fee(&to_bignum(42)); // There are no missing script witnesses - assert_eq!(tx_builder.count_missing_input_scripts(), 0); let tx: Transaction = tx_builder.build_tx_unsafe().unwrap(); assert!(tx.witness_set.plutus_scripts.is_some()); assert_eq!(tx.witness_set.plutus_scripts.unwrap().get(0), script1); @@ -3969,9 +3847,8 @@ fn test_adding_plutus_script_input() { fn test_adding_plutus_script_witnesses() { let mut tx_builder = create_reallistic_tx_builder(); tx_builder.set_fee(&to_bignum(42)); - let (script1, hash1) = plutus_script_and_hash(0); - let (script2, hash2) = plutus_script_and_hash(1); - let (script3, _hash3) = plutus_script_and_hash(3); + let (script1, _ ) = plutus_script_and_hash(0); + let (script2, _ ) = plutus_script_and_hash(1); let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); let redeemer1 = Redeemer::new( @@ -3986,31 +3863,17 @@ fn test_adding_plutus_script_witnesses() { &PlutusData::new_bytes(fake_bytes_32(21)), &ExUnits::new(&to_bignum(1), &to_bignum(2)), ); - tx_builder.add_input( - &create_base_address_from_script_hash(&hash1), + tx_builder.add_plutus_script_input( + &PlutusWitness::new(&script1, &datum1, &redeemer1), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(1_000_000)), ); - tx_builder.add_input( - &create_base_address_from_script_hash(&hash2), + tx_builder.add_plutus_script_input( + &PlutusWitness::new(&script2, &datum2, &redeemer2), &TransactionInput::new(&genesis_id(), 1), &Value::new(&to_bignum(1_000_000)), ); - // There are TWO missing script witnesses - assert_eq!(tx_builder.count_missing_input_scripts(), 2); - // Calling to add two plutus witnesses, one of which is irrelevant - tx_builder.add_required_plutus_input_scripts(&PlutusWitnesses::from(vec![ - PlutusWitness::new(&script1, &datum1, &redeemer1), - PlutusWitness::new(&script3, &datum2, &redeemer2), - ])); - // There is now ONE missing script witnesses - assert_eq!(tx_builder.count_missing_input_scripts(), 1); - // Calling to add the one remaining relevant plutus witness now - tx_builder.add_required_plutus_input_scripts(&PlutusWitnesses::from(vec![PlutusWitness::new( - &script2, &datum2, &redeemer2, - )])); - // There is now no missing script witnesses - assert_eq!(tx_builder.count_missing_input_scripts(), 0); + let tx: Transaction = tx_builder.build_tx_unsafe().unwrap(); // Check there are two correct scripts assert!(tx.witness_set.plutus_scripts.is_some()); @@ -4034,11 +3897,11 @@ fn test_adding_plutus_script_witnesses() { fn create_collateral() -> TxInputsBuilder { let mut collateral_builder = TxInputsBuilder::new(); - collateral_builder.add_input( + collateral_builder.add_regular_input( &byron_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(1_000_000)), - ); + ).unwrap(); collateral_builder } @@ -4148,7 +4011,7 @@ fn test_plutus_witness_redeemer_index_auto_changing() { ); // Add a regular NON-script input first - tx_builder.add_input( + tx_builder.add_regular_input( &byron_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(1_000_000)), @@ -4231,35 +4094,18 @@ fn test_native_and_plutus_scripts_together() { &Value::new(&to_bignum(1_000_000)), ); // Add one plutus input generically without witness - tx_builder.add_input( - &create_base_address_from_script_hash(&phash2), + tx_builder.add_plutus_script_input( + &PlutusWitness::new(&pscript2, &datum2, &redeemer2), &TransactionInput::new(&genesis_id(), 2), &Value::new(&to_bignum(1_000_000)), ); // Add one native input generically without witness - tx_builder.add_input( - &create_base_address_from_script_hash(&nhash2), + tx_builder.add_native_script_input( + &nscript2, &TransactionInput::new(&genesis_id(), 3), &Value::new(&to_bignum(1_000_000)), ); - // There are two missing script witnesses - assert_eq!(tx_builder.count_missing_input_scripts(), 2); - - let remaining1 = tx_builder.add_required_plutus_input_scripts(&PlutusWitnesses::from(vec![ - PlutusWitness::new(&pscript2, &datum2, &redeemer2), - ])); - - // There is one missing script witness now - assert_eq!(remaining1, 1); - assert_eq!(tx_builder.count_missing_input_scripts(), 1); - - let remaining2 = - tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![nscript2.clone()])); - - // There are no missing script witnesses now - assert_eq!(remaining2, 0); - assert_eq!(tx_builder.count_missing_input_scripts(), 0); tx_builder .calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()) @@ -4335,36 +4181,18 @@ fn test_json_serialization_native_and_plutus_scripts_together() { &Value::new(&to_bignum(1_000_000)), ); // Add one plutus input generically without witness - tx_builder.add_input( - &create_base_address_from_script_hash(&phash2), + tx_builder.add_plutus_script_input( + &PlutusWitness::new(&pscript2, &datum2, &redeemer2), &TransactionInput::new(&genesis_id(), 2), &Value::new(&to_bignum(1_000_000)), ); // Add one native input generically without witness - tx_builder.add_input( - &create_base_address_from_script_hash(&nhash2), + tx_builder.add_native_script_input( + &nscript2, &TransactionInput::new(&genesis_id(), 3), &Value::new(&to_bignum(1_000_000)), ); - // There are two missing script witnesses - assert_eq!(tx_builder.count_missing_input_scripts(), 2); - - let remaining1 = tx_builder.add_required_plutus_input_scripts(&PlutusWitnesses::from(vec![ - PlutusWitness::new(&pscript2, &datum2, &redeemer2), - ])); - - // There is one missing script witness now - assert_eq!(remaining1, 1); - assert_eq!(tx_builder.count_missing_input_scripts(), 1); - - let remaining2 = - tx_builder.add_required_native_input_scripts(&NativeScripts::from(vec![nscript2.clone()])); - - // There are no missing script witnesses now - assert_eq!(remaining2, 0); - assert_eq!(tx_builder.count_missing_input_scripts(), 0); - tx_builder.calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()); let tx: Transaction = tx_builder.build_tx().unwrap(); @@ -4382,12 +4210,12 @@ fn test_regular_and_collateral_inputs_same_keyhash() { let mut collateral_builder = TxInputsBuilder::new(); // Add a single input of both kinds with the SAME keyhash - input_builder.add_input( + input_builder.add_regular_input( &fake_base_address(0), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(1_000_000)), ); - collateral_builder.add_input( + collateral_builder.add_regular_input( &fake_base_address(0), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(1_000_000)), @@ -4407,12 +4235,12 @@ fn test_regular_and_collateral_inputs_same_keyhash() { assert_eq!(get_fake_vkeys_count(&input_builder, &collateral_builder), 1); // Add a new input of each kind with DIFFERENT keyhashes - input_builder.add_input( + input_builder.add_regular_input( &fake_base_address(1), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(1_000_000)), ); - collateral_builder.add_input( + collateral_builder.add_regular_input( &fake_base_address(2), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(1_000_000)), @@ -4513,12 +4341,12 @@ fn test_ex_unit_costs_are_added_to_the_fees() { let mut collateral_builder = TxInputsBuilder::new(); // Add a single input of both kinds with the SAME keyhash - input_builder.add_input( + input_builder.add_regular_input( &fake_base_address(0), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(1_000_000)), ); - collateral_builder.add_input( + collateral_builder.add_regular_input( &fake_base_address(0), &TransactionInput::new(&genesis_id(), 1), &Value::new(&to_bignum(1_000_000)), @@ -4644,7 +4472,7 @@ fn test_required_signers_are_added_to_the_witness_estimate() { fn count_fake_witnesses_with_required_signers(keys: &Ed25519KeyHashes) -> usize { let mut tx_builder = create_reallistic_tx_builder(); tx_builder.set_fee(&to_bignum(42)); - tx_builder.add_input( + tx_builder.add_regular_input( &fake_base_address(0), &TransactionInput::new(&fake_tx_hash(0), 0), &Value::new(&to_bignum(10_000_000)), @@ -4703,7 +4531,7 @@ fn collateral_return_and_total_collateral_setters() { tx_builder.set_fee(&to_bignum(123456)); let mut inp = TxInputsBuilder::new(); - inp.add_input(&fake_base_address(0), &fake_tx_input(0), &fake_value()); + inp.add_regular_input(&fake_base_address(0), &fake_tx_input(0), &fake_value()); tx_builder.set_inputs(&inp); tx_builder.set_collateral(&inp); @@ -4738,14 +4566,14 @@ fn inputs_builder_total_value() { let mut b = TxInputsBuilder::new(); assert_eq!(b.total_value().unwrap(), Value::zero()); - b.add_input( + b.add_regular_input( &fake_base_address(0), &fake_tx_input(0), &fake_value2(100_000), ); assert_eq!(b.total_value().unwrap(), Value::new(&to_bignum(100_000))); - b.add_input( + b.add_regular_input( &fake_base_address(1), &fake_tx_input(1), &fake_value2(200_000), @@ -4754,7 +4582,7 @@ fn inputs_builder_total_value() { let masset = fake_multiasset(123); - b.add_input( + b.add_regular_input( &fake_base_address(2), &fake_tx_input(2), &Value::new_with_assets(&to_bignum(300_000), &masset), @@ -4772,7 +4600,7 @@ fn test_auto_calc_total_collateral() { let mut inp = TxInputsBuilder::new(); let collateral_input_value = 2_000_000; - inp.add_input( + inp.add_regular_input( &fake_base_address(0), &fake_tx_input(0), &fake_value2(collateral_input_value.clone()), @@ -4809,7 +4637,7 @@ fn test_auto_calc_total_collateral_with_assets() { let mut inp = TxInputsBuilder::new(); let collateral_input_value = 2_000_000; - inp.add_input( + inp.add_regular_input( &fake_base_address(0), &fake_tx_input(0), &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), @@ -4846,7 +4674,7 @@ fn test_auto_calc_total_collateral_fails_with_assets() { let mut inp = TxInputsBuilder::new(); let collateral_input_value = 2_000_000; - inp.add_input( + inp.add_regular_input( &fake_base_address(0), &fake_tx_input(0), &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), @@ -4896,7 +4724,7 @@ fn test_auto_calc_total_collateral_fails_on_no_ada() { let mut inp = TxInputsBuilder::new(); let collateral_input_value = 2_000_000; - inp.add_input( + inp.add_regular_input( &fake_base_address(0), &fake_tx_input(0), &Value::new(&to_bignum(collateral_input_value.clone())), @@ -4924,7 +4752,7 @@ fn test_auto_calc_collateral_return() { let mut inp = TxInputsBuilder::new(); let collateral_input_value = 2_000_000; - inp.add_input( + inp.add_regular_input( &fake_base_address(0), &fake_tx_input(0), &fake_value2(collateral_input_value.clone()), @@ -4966,7 +4794,7 @@ fn test_auto_calc_collateral_return_with_assets() { let mut inp = TxInputsBuilder::new(); let collateral_input_value = 2_000_000; - inp.add_input( + inp.add_regular_input( &fake_base_address(0), &fake_tx_input(0), &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), @@ -5011,7 +4839,7 @@ fn test_add_collateral_return_succeed_with_border_amount() { let mut inp = TxInputsBuilder::new(); let collateral_input_value = 2_000_000; - inp.add_input( + inp.add_regular_input( &fake_base_address(0), &fake_tx_input(0), &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), @@ -5050,7 +4878,7 @@ fn test_add_zero_collateral_return() { let mut inp = TxInputsBuilder::new(); let collateral_input_value = 2_000_000; - inp.add_input( + inp.add_regular_input( &fake_base_address(0), &fake_tx_input(0), &Value::new(&to_bignum(collateral_input_value.clone())), @@ -5080,7 +4908,7 @@ fn test_add_collateral_return_fails_no_enough_ada() { let mut inp = TxInputsBuilder::new(); let collateral_input_value = 2_000_000; - inp.add_input( + inp.add_regular_input( &fake_base_address(0), &fake_tx_input(0), &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), @@ -5676,14 +5504,14 @@ fn plutus_mint_test() { let output = TransactionOutput::new(&output_adress, &output_value); let mut col_builder = TxInputsBuilder::new(); - col_builder.add_input( + col_builder.add_regular_input( &colateral_adress, &colateral_input, &Value::new(&Coin::from(1000000000u64)), ); tx_builder.set_collateral(&col_builder); tx_builder.add_output(&output); - tx_builder.add_input( + tx_builder.add_regular_input( &output_adress, &tx_input, &Value::new(&BigNum::from(100000000000u64)), @@ -5787,14 +5615,14 @@ fn plutus_mint_with_script_ref_test() { let output = TransactionOutput::new(&output_adress, &output_value); let mut col_builder = TxInputsBuilder::new(); - col_builder.add_input( + col_builder.add_regular_input( &colateral_adress, &colateral_input, &Value::new(&Coin::from(1000000000u64)), ); tx_builder.set_collateral(&col_builder); tx_builder.add_output(&output); - tx_builder.add_input( + tx_builder.add_regular_input( &output_adress, &tx_input, &Value::new(&BigNum::from(100000000000u64)), @@ -5882,14 +5710,14 @@ fn plutus_mint_defferent_redeemers_test() { let output = TransactionOutput::new(&output_adress, &output_value); let mut col_builder = TxInputsBuilder::new(); - col_builder.add_input( + col_builder.add_regular_input( &colateral_adress, &colateral_input, &Value::new(&Coin::from(1000000000u64)), ); tx_builder.set_collateral(&col_builder); tx_builder.add_output(&output).unwrap(); - tx_builder.add_input( + tx_builder.add_regular_input( &output_adress, &tx_input, &Value::new(&BigNum::from(100000000000u64)), @@ -5981,7 +5809,7 @@ fn multiple_plutus_inputs_test() { tx_builder.add_output(&output); let mut col_builder = TxInputsBuilder::new(); - col_builder.add_input( + col_builder.add_regular_input( &colateral_adress, &colateral_input, &Value::new(&Coin::from(1000000000u64)), @@ -6008,109 +5836,6 @@ fn multiple_plutus_inputs_test() { assert_eq!(tx.witness_set.redeemers.unwrap().len(), 2usize); } -#[test] -fn multiple_plutus_inputs_with_missed_wit_test() { - let mut tx_builder = create_reallistic_tx_builder(); - let plutus_script = PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); - let redeemer1 = Redeemer::from_json( - "\ - { - \"tag\": \"Mint\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"1042996\", - \"steps\": \"446100241\" - } - }", - ) - .unwrap(); - - let redeemer2 = Redeemer::from_json( - "\ - { - \"tag\": \"Mint\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"1042996\", - \"steps\": \"446100241\" - } - }", - ) - .unwrap(); - - let mut in_builder = TxInputsBuilder::new(); - let input_1 = TransactionInput::new( - &TransactionHash::from_bytes( - hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") - .unwrap(), - ) - .unwrap(), - 1, - ); - let input_2 = TransactionInput::new( - &TransactionHash::from_bytes( - hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") - .unwrap(), - ) - .unwrap(), - 2, - ); - - let colateral_adress = Address::from_bech32("addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w").unwrap(); - let colateral_input = TransactionInput::new( - &TransactionHash::from_bytes( - hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") - .unwrap(), - ) - .unwrap(), - 3, - ); - - let output_adress = Address::from_bech32("addr_test1qpm5njmgzf4t7225v6j34wl30xfrufzt3jtqtdzf3en9ahpmnhtmynpasyc8fq75zv0uaj86vzsr7g3g8q5ypgu5fwtqr9zsgj").unwrap(); - let output_value = Value::new(&Coin::from(5000000u64)); - let output = TransactionOutput::new(&output_adress, &output_value); - - tx_builder.add_output(&output).unwrap(); - let mut col_builder = TxInputsBuilder::new(); - col_builder.add_input( - &colateral_adress, - &colateral_input, - &Value::new(&Coin::from(1000000000u64)), - ); - tx_builder.set_collateral(&col_builder); - - let datum = PlutusData::new_bytes(fake_bytes_32(11)); - let plutus_wit1 = PlutusWitness::new(&plutus_script, &datum, &redeemer1); - - let plutus_wit2 = PlutusWitness::new(&plutus_script, &datum, &redeemer2); - - let value = Value::new(&Coin::from(100000000u64)); - - in_builder.add_plutus_script_input(&plutus_wit1, &input_1, &value); - let script_addr = create_base_address_from_script_hash(&plutus_script.hash()); - in_builder.add_input(&script_addr, &input_2, &value); - - assert_eq!(in_builder.count_missing_input_scripts(), 1usize); - let mut inputs_with_wit = InputsWithScriptWitness::new(); - let in_with_wit = InputWithScriptWitness::new_with_plutus_witness(&input_2, &plutus_wit2); - inputs_with_wit.add(&in_with_wit); - in_builder.add_required_script_input_witnesses(&inputs_with_wit); - - tx_builder.set_inputs(&in_builder); - - tx_builder - .calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()) - .unwrap(); - tx_builder.add_change_if_needed(&output_adress).unwrap(); - let build_res = tx_builder.build_tx(); - assert!(&build_res.is_ok()); - let tx = build_res.unwrap(); - assert_eq!(tx.witness_set.plutus_scripts.unwrap().len(), 1usize); - assert_eq!(tx.witness_set.redeemers.unwrap().len(), 2usize); -} - #[test] fn build_tx_with_certs_withdrawals_plutus_script_address() { let mut tx_builder = create_tx_builder_with_key_deposit(1_000_000); @@ -6337,7 +6062,7 @@ fn build_tx_with_certs_withdrawals_plutus_script_address() { ) .to_address(); let mut collateral_builder = TxInputsBuilder::new(); - collateral_builder.add_input( + collateral_builder.add_regular_input( &collateral_addr, &collateral_input, &Value::new(&Coin::from(123u32)), @@ -6406,7 +6131,7 @@ pub fn test_extra_datum() { tx_builder.add_extra_witness_datum(&datum); let mut inp = TxInputsBuilder::new(); - inp.add_input( + inp.add_regular_input( &fake_base_address(0), &fake_tx_input(0), &Value::new(&to_bignum(1000000u64)), diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/mock_objects.rs index 1dbbf373..4dc0e184 100644 --- a/rust/src/tests/mock_objects.rs +++ b/rust/src/tests/mock_objects.rs @@ -297,7 +297,7 @@ pub(crate) fn create_rich_tx_builder(with_collateral: bool) -> TransactionBuilde let input = TransactionInput::new(&fake_tx_hash(1), 0); let address = generate_address(1); let mut input_builder = TxInputsBuilder::new(); - input_builder.add_input(&address, &input, &Value::new(&Coin::from(u64::MAX / 2))); + input_builder.add_regular_input(&address, &input, &Value::new(&Coin::from(u64::MAX / 2))); tx_builder.set_inputs(&input_builder); if with_collateral { tx_builder.set_collateral(&input_builder); @@ -314,12 +314,12 @@ pub(crate) fn create_tx_builder_with_amount( let input = TransactionInput::new(&fake_tx_hash(1), 0); let address = generate_address(1); let mut input_builder = TxInputsBuilder::new(); - input_builder.add_input(&address, &input, &Value::new(&Coin::from(amount))); + input_builder.add_regular_input(&address, &input, &Value::new(&Coin::from(amount))); tx_builder.set_inputs(&input_builder); if with_collateral { let col_input = TransactionInput::new(&fake_tx_hash(1), 0); let mut col_input_builder = TxInputsBuilder::new(); - col_input_builder.add_input(&address, &col_input, &Value::new(&Coin::from(u64::MAX / 2))); + col_input_builder.add_regular_input(&address, &col_input, &Value::new(&Coin::from(u64::MAX / 2))); tx_builder.set_collateral(&col_input_builder); } @@ -341,12 +341,12 @@ pub(crate) fn create_tx_builder_with_amount_and_deposit_params( let input = TransactionInput::new(&fake_tx_hash(1), 0); let address = generate_address(1); let mut input_builder = TxInputsBuilder::new(); - input_builder.add_input(&address, &input, &Value::new(&Coin::from(amount))); + input_builder.add_regular_input(&address, &input, &Value::new(&Coin::from(amount))); tx_builder.set_inputs(&input_builder); if with_collateral { let col_input = TransactionInput::new(&fake_tx_hash(1), 0); let mut col_input_builder = TxInputsBuilder::new(); - col_input_builder.add_input(&address, &col_input, &Value::new(&Coin::from(u64::MAX / 2))); + col_input_builder.add_regular_input(&address, &col_input, &Value::new(&Coin::from(u64::MAX / 2))); tx_builder.set_collateral(&col_input_builder); } From 3ebe73bbf0fb33595a449b414e5098b96b77d159 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 14 Nov 2023 20:12:53 +0800 Subject: [PATCH 194/349] remove deprecated testnet from NetworkInfo --- rust/src/address.rs | 16 --- rust/src/fakes.rs | 4 +- rust/src/fees.rs | 2 +- rust/src/tests/address.rs | 38 ++---- .../tests/builders/certificates_builder.rs | 6 +- rust/src/tests/builders/tx_builder.rs | 118 +++++++++--------- rust/src/tests/mock_objects.rs | 4 +- rust/src/tests/serialization/certificates.rs | 2 +- .../tests/serialization/transaction_body.rs | 2 +- 9 files changed, 81 insertions(+), 111 deletions(-) diff --git a/rust/src/address.rs b/rust/src/address.rs index 469e97ed..1de8c104 100644 --- a/rust/src/address.rs +++ b/rust/src/address.rs @@ -65,18 +65,6 @@ impl NetworkInfo { protocol_magic: 1, } } - /// !!! DEPRECATED !!! - /// This network does not exist anymore. Use `.testnet_preview()` or `.testnet_preprod()` - #[deprecated( - since = "11.2.0", - note = "Use `.testnet_preview` or `.testnet_preprod`" - )] - pub fn testnet() -> NetworkInfo { - NetworkInfo { - network_id: 0b0000, - protocol_magic: 1097911063, - } - } pub fn mainnet() -> NetworkInfo { NetworkInfo { network_id: 0b0001, @@ -285,9 +273,6 @@ impl ByronAddress { magic if magic == NetworkInfo::mainnet().protocol_magic() => { Ok(NetworkInfo::mainnet().network_id()) } - magic if magic == NetworkInfo::testnet().protocol_magic() => { - Ok(NetworkInfo::testnet().network_id()) - } magic if magic == NetworkInfo::testnet_preprod().protocol_magic() => { Ok(NetworkInfo::testnet_preprod().network_id()) } @@ -597,7 +582,6 @@ impl Address { _ => "addr", }; let prefix_tail = match self.network_id()? { - id if id == NetworkInfo::testnet().network_id() => "_test", id if id == NetworkInfo::testnet_preprod().network_id() => "_test", id if id == NetworkInfo::testnet_preview().network_id() => "_test", _ => "", diff --git a/rust/src/fakes.rs b/rust/src/fakes.rs index 8e7a3947..9d679d95 100644 --- a/rust/src/fakes.rs +++ b/rust/src/fakes.rs @@ -58,7 +58,7 @@ pub(crate) fn fake_script_data_hash(x: u8) -> ScriptDataHash { pub(crate) fn fake_base_address(x: u8) -> Address { BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &Credential::from_keyhash(&fake_key_hash(x)), &Credential::from_keyhash(&fake_key_hash(0)), ) @@ -67,7 +67,7 @@ pub(crate) fn fake_base_address(x: u8) -> Address { pub(crate) fn fake_reward_address(x: u8) -> RewardAddress { RewardAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &Credential::from_keyhash(&fake_key_hash(x)), ) } diff --git a/rust/src/fees.rs b/rust/src/fees.rs index 03682537..4dcca559 100644 --- a/rust/src/fees.rs +++ b/rust/src/fees.rs @@ -470,7 +470,7 @@ mod tests { // to_bignum(1), // to_bignum(5), // &UnitInterval::new(to_bignum(1), to_bignum(10)), - // &RewardAddress::new(NetworkInfo::testnet().network_id(), &alice_stake()), + // &RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &alice_stake()), // &owners, // &relays, // Some(PoolMetadata::new(String::from("alice.pool"), &MetadataHash::from([0u8; MetadataHash::BYTE_COUNT]))) diff --git a/rust/src/tests/address.rs b/rust/src/tests/address.rs index 68416752..f205c94f 100644 --- a/rust/src/tests/address.rs +++ b/rust/src/tests/address.rs @@ -118,20 +118,6 @@ fn byron_magic_parsing() { addr.network_id().unwrap(), NetworkInfo::mainnet().network_id() ); - - // original Byron testnet address - let addr = ByronAddress::from_base58( - "2cWKMJemoBaipzQe9BArYdo2iPUfJQdZAjm4iCzDA1AfNxJSTgm9FZQTmFCYhKkeYrede", - ) - .unwrap(); - assert_eq!( - addr.byron_protocol_magic(), - NetworkInfo::testnet().protocol_magic() - ); - assert_eq!( - addr.network_id().unwrap(), - NetworkInfo::testnet().network_id() - ); } #[test] @@ -153,7 +139,7 @@ fn bip32_12_base() { let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -179,7 +165,7 @@ fn bip32_12_enterprise() { .to_public(); let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = - EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(); + EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(); assert_eq!( addr_net_0.to_bech32(None).unwrap(), "addr_test1vz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzerspjrlsz" @@ -204,7 +190,7 @@ fn bip32_12_pointer() { let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = PointerAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &Pointer::new_pointer(&to_bignum(1), &to_bignum(2), &to_bignum(3)), ) @@ -244,7 +230,7 @@ fn bip32_15_base() { let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -270,7 +256,7 @@ fn bip32_15_enterprise() { .to_public(); let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = - EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(); + EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(); assert_eq!( addr_net_0.to_bech32(None).unwrap(), "addr_test1vpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5eg57c2qv" @@ -294,7 +280,7 @@ fn bip32_15_pointer() { .to_public(); let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = PointerAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &Pointer::new_pointer(&to_bignum(1), &to_bignum(2), &to_bignum(3)), ) @@ -378,7 +364,7 @@ fn bip32_24_base() { let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -404,7 +390,7 @@ fn bip32_24_enterprise() { .to_public(); let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = - EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(); + EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(); assert_eq!( addr_net_0.to_bech32(None).unwrap(), "addr_test1vqy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqtjtf68" @@ -428,7 +414,7 @@ fn bip32_24_pointer() { .to_public(); let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = PointerAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &Pointer::new_pointer(&to_bignum(1), &to_bignum(2), &to_bignum(3)), ) @@ -460,7 +446,7 @@ fn bip32_12_reward() { .to_public(); let staking_cred = Credential::from_keyhash(&staking_key.to_raw_key().hash()); let addr_net_0 = - RewardAddress::new(NetworkInfo::testnet().network_id(), &staking_cred).to_address(); + RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &staking_cred).to_address(); assert_eq!( addr_net_0.to_bech32(None).unwrap(), "stake_test1uqevw2xnsc0pvn9t9r9c7qryfqfeerchgrlm3ea2nefr9hqp8n5xl" @@ -492,7 +478,7 @@ fn bip32_24_base_multisig_hd_derivation() { let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -531,7 +517,7 @@ fn multisig_from_script() { let spend_cred = Credential::from_scripthash(&script_hash); let stake_cred = Credential::from_scripthash(&script_hash); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) diff --git a/rust/src/tests/builders/certificates_builder.rs b/rust/src/tests/builders/certificates_builder.rs index 740f10e2..13e8eb6a 100644 --- a/rust/src/tests/builders/certificates_builder.rs +++ b/rust/src/tests/builders/certificates_builder.rs @@ -53,7 +53,7 @@ fn certificatess_builder_deposit_test() { ); let staking_cred = Credential::from_keyhash(&fake_key_hash(10)); - let reward_address = RewardAddress::new(NetworkInfo::testnet().network_id(), &staking_cred); + let reward_address = RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &staking_cred); let mut owners = Ed25519KeyHashes::new(); owners.add(&fake_key_hash(11)); owners.add(&fake_key_hash(12)); @@ -221,7 +221,7 @@ fn certificatess_builder_no_deposit_test() { ); let staking_cred = Credential::from_keyhash(&fake_key_hash(10)); - let reward_address = RewardAddress::new(NetworkInfo::testnet().network_id(), &staking_cred); + let reward_address = RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &staking_cred); let mut owners = Ed25519KeyHashes::new(); owners.add(&fake_key_hash(11)); owners.add(&fake_key_hash(12)); @@ -378,7 +378,7 @@ fn certificatess_builder_req_signers_test() { ); let staking_cred = Credential::from_keyhash(&key_hash_10); - let reward_address = RewardAddress::new(NetworkInfo::testnet().network_id(), &staking_cred); + let reward_address = RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &staking_cred); let mut owners = Ed25519KeyHashes::new(); owners.add(&key_hash_11); owners.add(&key_hash_12); diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index b0649b7b..e3d07349 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -65,7 +65,7 @@ fn build_tx_with_change() { let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -90,7 +90,7 @@ fn build_tx_with_change() { let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -136,7 +136,7 @@ fn build_tx_with_change_with_datum() { let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -164,7 +164,7 @@ fn build_tx_with_change_with_datum() { let (_, script_hash) = plutus_script_and_hash(15); let change_cred = Credential::from_scripthash(&script_hash); let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -217,7 +217,7 @@ fn build_tx_without_change() { let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -242,7 +242,7 @@ fn build_tx_without_change() { let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -310,7 +310,7 @@ fn build_tx_with_certs() { let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -370,7 +370,7 @@ fn build_tx_exact_amount() { let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -390,7 +390,7 @@ fn build_tx_exact_amount() { let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -434,7 +434,7 @@ fn build_tx_exact_change() { let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -454,7 +454,7 @@ fn build_tx_exact_change() { let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -500,7 +500,7 @@ fn build_tx_insufficient_deposit() { let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -527,7 +527,7 @@ fn build_tx_insufficient_deposit() { let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -561,7 +561,7 @@ fn build_tx_with_inputs() { assert_eq!( tx_builder .fee_for_input( - &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred) + &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) .to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(1_000_000)) @@ -571,14 +571,14 @@ fn build_tx_with_inputs() { "69500" ); tx_builder.add_regular_input( - &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), + &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(1_000_000)), ); } tx_builder.add_regular_input( &BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -588,7 +588,7 @@ fn build_tx_with_inputs() { ); tx_builder.add_regular_input( &PointerAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &Pointer::new_pointer(&to_bignum(0), &to_bignum(0), &to_bignum(0)), ) @@ -597,7 +597,7 @@ fn build_tx_with_inputs() { &Value::new(&to_bignum(1_000_000)), ); tx_builder.add_regular_input( - &ByronAddress::icarus_from_key(&spend, NetworkInfo::testnet().protocol_magic()) + &ByronAddress::icarus_from_key(&spend, NetworkInfo::testnet_preprod().protocol_magic()) .to_address(), &TransactionInput::new(&genesis_id(), 3), &Value::new(&to_bignum(1_000_000)), @@ -653,7 +653,7 @@ fn build_tx_with_script_ref() { tx_builder.add_regular_input( &PointerAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &Pointer::new_pointer(&to_bignum(0), &to_bignum(0), &to_bignum(0)), ) @@ -663,7 +663,7 @@ fn build_tx_with_script_ref() { ); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -685,7 +685,7 @@ fn build_tx_with_script_ref() { let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -734,7 +734,7 @@ fn serialization_tx_body_with_script_ref() { tx_builder.add_regular_input( &PointerAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &Pointer::new_pointer(&to_bignum(0), &to_bignum(0), &to_bignum(0)), ) @@ -744,7 +744,7 @@ fn serialization_tx_body_with_script_ref() { ); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -766,7 +766,7 @@ fn serialization_tx_body_with_script_ref() { let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -815,7 +815,7 @@ fn json_serialization_tx_body_with_script_ref() { tx_builder.add_regular_input( &PointerAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &Pointer::new_pointer(&to_bignum(0), &to_bignum(0), &to_bignum(0)), ) @@ -825,7 +825,7 @@ fn json_serialization_tx_body_with_script_ref() { ); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -847,7 +847,7 @@ fn json_serialization_tx_body_with_script_ref() { let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -893,13 +893,13 @@ fn build_tx_with_mint_all_sent() { // Input with 150 coins tx_builder.add_regular_input( - &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), + &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(500)), ); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -935,7 +935,7 @@ fn build_tx_with_mint_all_sent() { let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -981,13 +981,13 @@ fn build_tx_with_mint_in_change() { // Input with 600 coins tx_builder.add_regular_input( - &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), + &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(600)), ); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -1025,7 +1025,7 @@ fn build_tx_with_mint_in_change() { let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -1090,19 +1090,19 @@ fn change_with_input_and_mint_not_enough_ada() { // Input with 600 coins tx_builder.add_regular_input( - &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), + &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(600)), ); tx_builder.add_regular_input( - &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), + &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(), &TransactionInput::new(&genesis_id(), 1), &Value::new_with_assets(&to_bignum(1), &mass_input), ); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -1134,7 +1134,7 @@ fn change_with_input_and_mint_not_enough_ada() { let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -1186,19 +1186,19 @@ fn change_with_input_and_mint_not_enough_assets() { // Input with 600 coins tx_builder.add_regular_input( - &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), + &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(100000)), ); tx_builder.add_regular_input( - &EnterpriseAddress::new(NetworkInfo::testnet().network_id(), &spend_cred).to_address(), + &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(), &TransactionInput::new(&genesis_id(), 1), &Value::new_with_assets(&to_bignum(1), &mass_input), ); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -1230,7 +1230,7 @@ fn change_with_input_and_mint_not_enough_assets() { let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -1304,7 +1304,7 @@ fn build_tx_with_native_assets_change() { let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -1327,7 +1327,7 @@ fn build_tx_with_native_assets_change() { let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -1419,7 +1419,7 @@ fn build_tx_with_native_assets_change_and_purification() { let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -1442,7 +1442,7 @@ fn build_tx_with_native_assets_change_and_purification() { let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -1546,7 +1546,7 @@ fn build_tx_with_native_assets_change_and_no_purification_cuz_not_enough_pure_co let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -1569,7 +1569,7 @@ fn build_tx_with_native_assets_change_and_no_purification_cuz_not_enough_pure_co let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -1627,7 +1627,7 @@ fn build_tx_leftover_assets() { let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -1665,7 +1665,7 @@ fn build_tx_leftover_assets() { let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -2555,7 +2555,7 @@ fn build_tx_pay_to_multisig() { let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -2639,13 +2639,13 @@ fn build_tx_multisig_spend_1on1_unsigned() { let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let addr_multisig = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) .to_address(); let addr_output = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -2731,7 +2731,7 @@ fn build_tx_multisig_1on1_signed() { let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr_net_0 = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ) @@ -3757,7 +3757,7 @@ fn total_input_output_with_mint_and_burn() { fn create_base_address_from_script_hash(sh: &ScriptHash) -> Address { BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &Credential::from_scripthash(sh), &Credential::from_keyhash(&fake_key_hash(0)), ) @@ -6026,20 +6026,20 @@ fn build_tx_with_certs_withdrawals_plutus_script_address() { let reward_cred = Credential::from_keyhash(&reward.to_raw_key().hash()); withdrawals .add( - &RewardAddress::new(NetworkInfo::testnet().network_id(), &reward_cred), + &RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &reward_cred), &Coin::from(1u32), ) .unwrap(); withdrawals .add_with_plutus_witness( - &RewardAddress::new(NetworkInfo::testnet().network_id(), &withdraw_script_cred1), + &RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &withdraw_script_cred1), &Coin::from(2u32), &withdraw_witness1, ) .unwrap(); withdrawals .add_with_plutus_witness( - &RewardAddress::new(NetworkInfo::testnet().network_id(), &withdraw_script_cred2), + &RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &withdraw_script_cred2), &Coin::from(3u32), &withdraw_witness2, ) @@ -6048,7 +6048,7 @@ fn build_tx_with_certs_withdrawals_plutus_script_address() { let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &change_cred, &stake_cred, ) @@ -6056,7 +6056,7 @@ fn build_tx_with_certs_withdrawals_plutus_script_address() { let cost_models = TxBuilderConstants::plutus_default_cost_models(); let collateral_input = fake_tx_input(1); let collateral_addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &Credential::from_keyhash(&fake_key_hash(1)), &Credential::from_keyhash(&fake_key_hash(2)), ) diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/mock_objects.rs index 4dc0e184..19d19a24 100644 --- a/rust/src/tests/mock_objects.rs +++ b/rust/src/tests/mock_objects.rs @@ -37,7 +37,7 @@ pub(crate) fn generate_address(index: u32) -> Address { let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ); @@ -285,7 +285,7 @@ pub(crate) fn create_change_address() -> Address { let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); let addr = BaseAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &spend_cred, &stake_cred, ); diff --git a/rust/src/tests/serialization/certificates.rs b/rust/src/tests/serialization/certificates.rs index 1fd065f1..37c53ec4 100644 --- a/rust/src/tests/serialization/certificates.rs +++ b/rust/src/tests/serialization/certificates.rs @@ -193,7 +193,7 @@ fn move_instantaneous_reward_to_stake_creds_ser_round_trip() { #[test] fn pool_registration_ser_round_trip() { let staking_cred = Credential::from_keyhash(&fake_key_hash(1)); - let reward_address = RewardAddress::new(NetworkInfo::testnet().network_id(), &staking_cred); + let reward_address = RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &staking_cred); let mut owners = Ed25519KeyHashes::new(); owners.add(&fake_key_hash(2)); owners.add(&fake_key_hash(3)); diff --git a/rust/src/tests/serialization/transaction_body.rs b/rust/src/tests/serialization/transaction_body.rs index b4c9fc0f..de4f4e5a 100644 --- a/rust/src/tests/serialization/transaction_body.rs +++ b/rust/src/tests/serialization/transaction_body.rs @@ -32,7 +32,7 @@ fn transaction_round_trip_test() { let mut withdrawals = Withdrawals::new(); withdrawals.insert( &RewardAddress::new( - NetworkInfo::testnet().network_id(), + NetworkInfo::testnet_preprod().network_id(), &Credential::from_keyhash(&fake_key_hash(9)), ), &Coin::from(1_000_010u64), From 71e0ea857df91ae7536ade1ad1ec823570e3c2db Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 14 Nov 2023 20:25:26 +0800 Subject: [PATCH 195/349] remove coins_per_utxo_byte from tx builder config --- rust/src/builders/tx_builder.rs | 12 ------------ rust/src/tests/builders/batch_tools.rs | 24 ++++++++++++------------ rust/src/tests/builders/tx_builder.rs | 6 +++--- rust/src/tests/mock_objects.rs | 20 ++++++++++---------- 4 files changed, 25 insertions(+), 37 deletions(-) diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index fd0a8874..a1d998d5 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -230,18 +230,6 @@ impl TransactionBuilderConfigBuilder { cfg } - /// !!! DEPRECATED !!! - /// Since babbage era cardano nodes use coins per byte. Use '.coins_per_utxo_byte' instead. - #[deprecated( - since = "11.0.0", - note = "Since babbage era cardano nodes use coins per byte. Use '.coins_per_utxo_byte' instead." - )] - pub fn coins_per_utxo_word(&self, coins_per_utxo_word: &Coin) -> Self { - let mut cfg = self.clone(); - cfg.data_cost = Some(DataCost::new_coins_per_word(coins_per_utxo_word)); - cfg - } - pub fn coins_per_utxo_byte(&self, coins_per_utxo_byte: &Coin) -> Self { let mut cfg = self.clone(); cfg.data_cost = Some(DataCost::new_coins_per_byte(coins_per_utxo_byte)); diff --git a/rust/src/tests/builders/batch_tools.rs b/rust/src/tests/builders/batch_tools.rs index 232e4964..fefd40fa 100644 --- a/rust/src/tests/builders/batch_tools.rs +++ b/rust/src/tests/builders/batch_tools.rs @@ -222,7 +222,7 @@ pub fn test_big_utoxs_batch() { .key_deposit(&to_bignum(2000000)) .max_value_size(4000) .max_tx_size(8000) - .coins_per_utxo_word(&to_bignum(34_482)) + .coins_per_utxo_byte(&to_bignum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( &SubCoin::new(&to_bignum(577), &to_bignum(10000)), &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), @@ -251,7 +251,7 @@ pub fn test_big_utoxs_ada_batch() { .key_deposit(&to_bignum(2000000)) .max_value_size(4000) .max_tx_size(8000) - .coins_per_utxo_word(&to_bignum(34_482)) + .coins_per_utxo_byte(&to_bignum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( &SubCoin::new(&to_bignum(577), &to_bignum(10000)), &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), @@ -294,7 +294,7 @@ pub fn test_one_utxo() { .key_deposit(&to_bignum(2000000)) .max_value_size(4000) .max_tx_size(8000) - .coins_per_utxo_word(&to_bignum(34_482)) + .coins_per_utxo_byte(&to_bignum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( &SubCoin::new(&to_bignum(577), &to_bignum(10000)), &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), @@ -361,7 +361,7 @@ pub fn test_one_utxo_one_asset_per_output() { .key_deposit(&to_bignum(2000000)) .max_value_size(80) .max_tx_size(8000) - .coins_per_utxo_word(&to_bignum(34_482)) + .coins_per_utxo_byte(&to_bignum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( &SubCoin::new(&to_bignum(577), &to_bignum(10000)), &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), @@ -440,7 +440,7 @@ pub fn test_one_utxo_one_asset_per_tx() { .key_deposit(&to_bignum(2000000)) .max_value_size(80) .max_tx_size(300) - .coins_per_utxo_word(&to_bignum(34_482)) + .coins_per_utxo_byte(&to_bignum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( &SubCoin::new(&to_bignum(577), &to_bignum(10000)), &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), @@ -496,7 +496,7 @@ pub fn test_only_ada_utxo() { .key_deposit(&to_bignum(2000000)) .max_value_size(4000) .max_tx_size(8000) - .coins_per_utxo_word(&to_bignum(34_482)) + .coins_per_utxo_byte(&to_bignum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( &SubCoin::new(&to_bignum(577), &to_bignum(10000)), &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), @@ -529,7 +529,7 @@ pub fn test_not_enough_ada() { .key_deposit(&to_bignum(2000000)) .max_value_size(4000) .max_tx_size(8000) - .coins_per_utxo_word(&to_bignum(34_482)) + .coins_per_utxo_byte(&to_bignum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( &SubCoin::new(&to_bignum(577), &to_bignum(10000)), &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), @@ -565,7 +565,7 @@ pub fn test_value_limit_error() { .key_deposit(&to_bignum(2000000)) .max_value_size(10) .max_tx_size(8000000) - .coins_per_utxo_word(&to_bignum(34_482)) + .coins_per_utxo_byte(&to_bignum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( &SubCoin::new(&to_bignum(577), &to_bignum(10000)), &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), @@ -601,7 +601,7 @@ pub fn test_tx_limit_error() { .key_deposit(&to_bignum(2000000)) .max_value_size(100) .max_tx_size(2000) - .coins_per_utxo_word(&to_bignum(34_482)) + .coins_per_utxo_byte(&to_bignum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( &SubCoin::new(&to_bignum(577), &to_bignum(10000)), &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), @@ -624,7 +624,7 @@ pub fn test_no_utxos() { .key_deposit(&to_bignum(2000000)) .max_value_size(10) .max_tx_size(8000000) - .coins_per_utxo_word(&to_bignum(34_482)) + .coins_per_utxo_byte(&to_bignum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( &SubCoin::new(&to_bignum(577), &to_bignum(10000)), &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), @@ -653,7 +653,7 @@ pub fn test_script_input_error() { .key_deposit(&to_bignum(2000000)) .max_value_size(10) .max_tx_size(8000000) - .coins_per_utxo_word(&to_bignum(34_482)) + .coins_per_utxo_byte(&to_bignum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( &SubCoin::new(&to_bignum(577), &to_bignum(10000)), &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), @@ -713,7 +713,7 @@ pub fn test_two_asset_utxo_one_ada_utxo() { .key_deposit(&to_bignum(2000000)) .max_value_size(4000) .max_tx_size(8000) - .coins_per_utxo_word(&to_bignum(34_482)) + .coins_per_utxo_byte(&to_bignum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( &SubCoin::new(&to_bignum(577), &to_bignum(10000)), &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index e3d07349..970aa75a 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -2455,7 +2455,7 @@ fn tx_builder_cip2_random_improve_when_using_all_available_inputs() { .key_deposit(&to_bignum(0)) .max_value_size(9999) .max_tx_size(9999) - .coins_per_utxo_word(&Coin::zero()) + .coins_per_utxo_byte(&Coin::zero()) .build() .unwrap(); let mut tx_builder = TransactionBuilder::new(&cfg); @@ -2494,7 +2494,7 @@ fn tx_builder_cip2_random_improve_adds_enough_for_fees() { .key_deposit(&to_bignum(0)) .max_value_size(9999) .max_tx_size(9999) - .coins_per_utxo_word(&Coin::zero()) + .coins_per_utxo_byte(&Coin::zero()) .build() .unwrap(); let mut tx_builder = TransactionBuilder::new(&cfg); @@ -2818,7 +2818,7 @@ fn add_change_splits_change_into_multiple_outputs_when_nfts_overflow_output_size .key_deposit(&to_bignum(0)) .max_value_size(max_value_size) .max_tx_size(MAX_TX_SIZE) - .coins_per_utxo_word(&to_bignum(8)) + .coins_per_utxo_byte(&to_bignum(1)) .prefer_pure_change(true) .build() .unwrap(), diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/mock_objects.rs index 19d19a24..128aa986 100644 --- a/rust/src/tests/mock_objects.rs +++ b/rust/src/tests/mock_objects.rs @@ -8,7 +8,7 @@ use crate::*; const MAX_VALUE_SIZE: u32 = 4000; const MAX_TX_SIZE: u32 = 8000; // might be out of date but suffices for our tests // this is what is used in mainnet -static COINS_PER_UTXO_WORD: u64 = 34_482; +static COINS_PER_UTXO_BYTE: u64 = 34_482 / 8; pub(crate) fn root_key() -> Bip32PrivateKey { // art forum devote street sure rather head chuckle guard poverty release quote oak craft enemy @@ -189,7 +189,7 @@ pub(crate) fn create_tx_builder_full( pool_deposit: u64, key_deposit: u64, max_val_size: u32, - coins_per_utxo_word: u64, + coins_per_utxo_byte: u64, ) -> TransactionBuilder { let cfg = TransactionBuilderConfigBuilder::new() .fee_algo(linear_fee) @@ -197,7 +197,7 @@ pub(crate) fn create_tx_builder_full( .key_deposit(&to_bignum(key_deposit)) .max_value_size(max_val_size) .max_tx_size(MAX_TX_SIZE) - .coins_per_utxo_word(&to_bignum(coins_per_utxo_word)) + .coins_per_utxo_byte(&to_bignum(coins_per_utxo_byte)) .ex_unit_prices(&ExUnitPrices::new( &SubCoin::new(&to_bignum(577), &to_bignum(10000)), &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), @@ -209,7 +209,7 @@ pub(crate) fn create_tx_builder_full( pub(crate) fn create_tx_builder( linear_fee: &LinearFee, - coins_per_utxo_word: u64, + coins_per_utxo_byte: u64, pool_deposit: u64, key_deposit: u64, ) -> TransactionBuilder { @@ -218,14 +218,14 @@ pub(crate) fn create_tx_builder( pool_deposit, key_deposit, MAX_VALUE_SIZE, - coins_per_utxo_word, + coins_per_utxo_byte, ) } pub(crate) fn create_reallistic_tx_builder() -> TransactionBuilder { create_tx_builder( &create_linear_fee(44, 155381), - COINS_PER_UTXO_WORD, + COINS_PER_UTXO_BYTE, 500000000, 2000000, ) @@ -235,11 +235,11 @@ pub(crate) fn create_tx_builder_with_fee_and_val_size( linear_fee: &LinearFee, max_val_size: u32, ) -> TransactionBuilder { - create_tx_builder_full(linear_fee, 1, 1, max_val_size, 8) + create_tx_builder_full(linear_fee, 1, 1, max_val_size, 1) } pub(crate) fn create_tx_builder_with_fee(linear_fee: &LinearFee) -> TransactionBuilder { - create_tx_builder(linear_fee, 8, 1, 1) + create_tx_builder(linear_fee, 1, 1, 1) } pub(crate) fn create_tx_builder_with_fee_and_pure_change( @@ -252,7 +252,7 @@ pub(crate) fn create_tx_builder_with_fee_and_pure_change( .key_deposit(&to_bignum(1)) .max_value_size(MAX_VALUE_SIZE) .max_tx_size(MAX_TX_SIZE) - .coins_per_utxo_word(&to_bignum(8)) + .coins_per_utxo_byte(&to_bignum(1)) .prefer_pure_change(true) .build() .unwrap(), @@ -334,7 +334,7 @@ pub(crate) fn create_tx_builder_with_amount_and_deposit_params( ) -> TransactionBuilder { let mut tx_builder = create_tx_builder( &create_linear_fee(44, 155381), - COINS_PER_UTXO_WORD, + COINS_PER_UTXO_BYTE, pool_deposit, key_deposit ); From 65136fab9a0fa5f3ee7fcf706520c8db8065589e Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 15 Nov 2023 13:58:00 +0800 Subject: [PATCH 196/349] remove deprecated functions that uses coins per word --- rust/src/builders/output_builder.rs | 15 --- rust/src/lib.rs | 14 --- rust/src/tests/builders/tx_builder.rs | 9 +- rust/src/utils.rs | 169 -------------------------- 4 files changed, 4 insertions(+), 203 deletions(-) diff --git a/rust/src/builders/output_builder.rs b/rust/src/builders/output_builder.rs index 72ccc796..583e8ad4 100644 --- a/rust/src/builders/output_builder.rs +++ b/rust/src/builders/output_builder.rs @@ -93,21 +93,6 @@ impl TransactionOutputAmountBuilder { cfg } - /// !!! DEPRECATED !!! - /// Since babbage era cardano nodes use coins per byte. Use '.with_asset_and_min_required_coin_by_utxo_cost' instead. - #[deprecated( - since = "11.0.0", - note = "Since babbage era cardano nodes use coins per byte. Use '.with_asset_and_min_required_coin_by_utxo_cost' instead." - )] - pub fn with_asset_and_min_required_coin( - &self, - multiasset: &MultiAsset, - coins_per_utxo_word: &Coin, - ) -> Result { - let data_cost = DataCost::new_coins_per_word(coins_per_utxo_word); - self.with_asset_and_min_required_coin_by_utxo_cost(multiasset, &data_cost) - } - pub fn with_asset_and_min_required_coin_by_utxo_cost( &self, multiasset: &MultiAsset, diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 211ab139..1937687d 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -260,20 +260,6 @@ pub struct DataCost(DataCostEnum); #[wasm_bindgen] impl DataCost { - /// !!! DEPRECATED !!! - /// Since babbage era we should use coins per byte. Use `.new_coins_per_byte` instead. - #[deprecated( - since = "11.0.0", - note = "Since babbage era we should use coins per byte. Use `.new_coins_per_byte` instead." - )] - pub fn new_coins_per_word(coins_per_word: &Coin) -> DataCost { - if coins_per_word != &BigNum::zero() { - DataCost(DataCostEnum::CoinsPerWord(coins_per_word.clone())) - } else { - DataCost(DataCostEnum::CoinsPerByte(BigNum::zero())) - } - } - pub fn new_coins_per_byte(coins_per_byte: &Coin) -> DataCost { DataCost(DataCostEnum::CoinsPerByte(coins_per_byte.clone())) } diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index 970aa75a..63cb7666 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -1355,7 +1355,7 @@ fn build_tx_with_native_assets_change() { #[test] fn build_tx_with_native_assets_change_and_purification() { - let coin_per_utxo_word = to_bignum(8); + let coin_per_utxo_byte = to_bignum(1); // Prefer pure change! let mut tx_builder = create_tx_builder_with_fee_and_pure_change(&create_linear_fee(0, 1)); let spend = root_key_15() @@ -1467,10 +1467,9 @@ fn build_tx_with_native_assets_change_and_purification() { to_bignum(ma_input1 + ma_input2 - ma_output1) ); // The first change output that contains all the tokens contain minimum required Coin - let min_coin_for_dirty_change = min_ada_required( - &final_tx.outputs().get(1).amount(), - false, - &coin_per_utxo_word, + let min_coin_for_dirty_change = min_ada_for_output( + &final_tx.outputs().get(1), + &DataCost::new_coins_per_byte(&coin_per_utxo_byte), ) .unwrap(); assert_eq!( diff --git a/rust/src/utils.rs b/rust/src/utils.rs index 1a66c40b..7290d285 100644 --- a/rust/src/utils.rs +++ b/rust/src/utils.rs @@ -1440,25 +1440,6 @@ pub fn min_ada_for_output( MinOutputAdaCalculator::new(output, data_cost).calculate_ada() } -/// !!! DEPRECATED !!! -/// This function uses outdated set of arguments. -/// Use `min_ada_for_output` instead -#[wasm_bindgen] -#[deprecated(since = "11.0.0", note = "Use `min_ada_for_output` instead")] -pub fn min_ada_required( - assets: &Value, - has_data_hash: bool, // whether the output includes a data hash - coins_per_utxo_word: &BigNum, // protocol parameter (in lovelace) -) -> Result { - let data_cost = DataCost::new_coins_per_word(coins_per_utxo_word); - let mut calc = MinOutputAdaCalculator::new_empty(&data_cost)?; - calc.set_amount(assets); - if has_data_hash { - calc.set_data_hash(&fake_data_hash(0)); - } - calc.calculate_ada() -} - /// Used to choosed the schema for a script JSON string #[wasm_bindgen] pub enum ScriptSchema { @@ -1841,156 +1822,6 @@ mod tests { } } - #[test] - fn min_ada_value_no_multiasset() { - assert_eq!( - from_bignum( - &min_ada_required( - &Value::new(&Coin::zero()), - false, - &to_bignum(COINS_PER_UTXO_WORD), - ) - .unwrap() - ), - 969750, - ); - } - - #[test] - fn min_ada_value_one_policy_one_0_char_asset() { - assert_eq!( - from_bignum( - &min_ada_required( - &one_policy_one_0_char_asset(), - false, - &to_bignum(COINS_PER_UTXO_WORD), - ) - .unwrap() - ), - 1_120_600, - ); - } - - #[test] - fn min_ada_value_one_policy_one_1_char_asset() { - assert_eq!( - from_bignum( - &min_ada_required( - &one_policy_one_1_char_asset(), - false, - &to_bignum(COINS_PER_UTXO_WORD), - ) - .unwrap() - ), - 1_124_910, - ); - } - - #[test] - fn min_ada_value_one_policy_three_1_char_assets() { - assert_eq!( - from_bignum( - &min_ada_required( - &one_policy_three_1_char_assets(), - false, - &to_bignum(COINS_PER_UTXO_WORD), - ) - .unwrap() - ), - 1_150_770, - ); - } - - #[test] - fn min_ada_value_two_policies_one_0_char_asset() { - assert_eq!( - from_bignum( - &min_ada_required( - &two_policies_one_0_char_asset(), - false, - &to_bignum(COINS_PER_UTXO_WORD), - ) - .unwrap() - ), - 1_262_830, - ); - } - - #[test] - fn min_ada_value_two_policies_one_1_char_asset() { - assert_eq!( - from_bignum( - &min_ada_required( - &two_policies_one_1_char_asset(), - false, - &to_bignum(COINS_PER_UTXO_WORD), - ) - .unwrap() - ), - 1_271_450, - ); - } - - #[test] - fn min_ada_value_three_policies_96_1_char_assets() { - assert_eq!( - from_bignum( - &min_ada_required( - &three_policies_96_1_char_assets(), - false, - &to_bignum(COINS_PER_UTXO_WORD), - ) - .unwrap() - ), - 2_633_410, - ); - } - - #[test] - fn min_ada_value_one_policy_one_0_char_asset_datum_hash() { - assert_eq!( - from_bignum( - &min_ada_required( - &one_policy_one_0_char_asset(), - true, - &to_bignum(COINS_PER_UTXO_WORD), - ) - .unwrap() - ), - 1_267_140, - ); - } - - #[test] - fn min_ada_value_one_policy_three_32_char_assets_datum_hash() { - assert_eq!( - from_bignum( - &min_ada_required( - &one_policy_three_32_char_assets(), - true, - &to_bignum(COINS_PER_UTXO_WORD), - ) - .unwrap() - ), - 1_711_070, - ); - } - - #[test] - fn min_ada_value_two_policies_one_0_char_asset_datum_hash() { - assert_eq!( - from_bignum( - &min_ada_required( - &two_policies_one_0_char_asset(), - true, - &to_bignum(COINS_PER_UTXO_WORD), - ) - .unwrap() - ), - 1_409_370, - ); - } - #[test] fn subtract_values() { let policy1 = PolicyID::from([0; ScriptHash::BYTE_COUNT]); From ca1f54b78569db50fde2e868b6827794b5edb495 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 15 Nov 2023 16:23:59 +0800 Subject: [PATCH 197/349] remove wrong named function --- rust/src/protocol_types/transaction_body.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/rust/src/protocol_types/transaction_body.rs b/rust/src/protocol_types/transaction_body.rs index cef72692..ddca6642 100644 --- a/rust/src/protocol_types/transaction_body.rs +++ b/rust/src/protocol_types/transaction_body.rs @@ -147,13 +147,6 @@ impl TransactionBody { self.mint.clone() } - /// This function returns the mint value of the transaction - /// Use `.mint()` instead. - #[deprecated(since = "10.0.0", note = "Weird naming. Use `.mint()`")] - pub fn multiassets(&self) -> Option { - self.mint() - } - pub fn set_reference_inputs(&mut self, reference_inputs: &TransactionInputs) { self.reference_inputs = Some(reference_inputs.clone()) } From 3de15cdaaab80b19131a2163d0e03e827a674846 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 28 Nov 2023 17:40:24 +0800 Subject: [PATCH 198/349] serialization mod visibility fix --- rust/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 211ab139..4cc919e9 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -59,7 +59,7 @@ pub use protocol_types::*; #[macro_use] pub mod utils; pub(crate) mod fakes; -mod serialization; +pub mod serialization; use crate::traits::NoneOrEmpty; use address::*; From fe491d38ebf842e9f49e385ebcea17770018f0e2 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 28 Nov 2023 18:08:34 +0800 Subject: [PATCH 199/349] update js flow --- rust/pkg/cardano_serialization_lib.js.flow | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 35b1d2e9..4b5aa610 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -1840,19 +1840,19 @@ declare export class Certificate { ): Certificate; /** - * @param {CommitteeHotAuth} committee_hot_key_registration + * @param {CommitteeHotAuth} committee_hot_auth * @returns {Certificate} */ static new_committee_hot_auth( - committee_hot_key_registration: CommitteeHotAuth + committee_hot_auth: CommitteeHotAuth ): Certificate; /** - * @param {CommitteeColdResign} committee_hot_key_deregistration + * @param {CommitteeColdResign} committee_cold_resign * @returns {Certificate} */ static new_committee_cold_resign( - committee_hot_key_deregistration: CommitteeColdResign + committee_cold_resign: CommitteeColdResign ): Certificate; /** @@ -1958,12 +1958,12 @@ declare export class Certificate { /** * @returns {CommitteeHotAuth | void} */ - as_committee_hot_key_registration(): CommitteeHotAuth | void; + as_committee_hot_auth(): CommitteeHotAuth | void; /** * @returns {CommitteeColdResign | void} */ - as_committee_hot_key_deregistration(): CommitteeColdResign | void; + as_committee_cold_resign(): CommitteeColdResign | void; /** * @returns {DrepDeregistration | void} From a2c0a3c57ac4ed6950619b4c508dd5786058aec8 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 28 Nov 2023 18:09:10 +0800 Subject: [PATCH 200/349] bump version --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2d08384e..122472f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.13", + "version": "12.0.0-alpha.14", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 422a51fd..63532296 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.13", + "version": "12.0.0-alpha.14", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index a29e779d..8864ba5a 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.13" +version = "12.0.0-alpha.14" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 4ded9161..3d854d94 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -37,7 +37,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.13" +version = "12.0.0-alpha.14" dependencies = [ "bech32", "cbor_event", From a1e7accc59c9392dede138972cc955eef0185c4f Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 28 Nov 2023 19:35:39 +0800 Subject: [PATCH 201/349] update import scheme --- rust/json-gen/src/main.rs | 3 --- rust/src/lib.rs | 30 ++++++++++++++++-------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/rust/json-gen/src/main.rs b/rust/json-gen/src/main.rs index 7718541c..ad40b55c 100644 --- a/rust/json-gen/src/main.rs +++ b/rust/json-gen/src/main.rs @@ -2,9 +2,6 @@ use std::fs; use std::path::Path; use cardano_serialization_lib::*; -use cardano_serialization_lib::address::*; -use cardano_serialization_lib::crypto::*; -use cardano_serialization_lib::utils::*; //#[macro_export] macro_rules! gen_json_schema { diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 4cc919e9..e3ef0b9d 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -41,37 +41,39 @@ use cbor_event::{ se::{Serialize, Serializer}, }; -pub mod address; +mod address; +pub use address::*; mod builders; +pub use builders::*; pub mod chain_core; pub mod chain_crypto; -pub mod crypto; -pub mod emip3; -pub mod error; -pub mod fees; +mod crypto; +pub use crypto::*; +mod emip3; +pub use emip3::*; +mod error; +pub use error::*; +mod fees; +pub use fees::*; pub mod impl_mockchain; pub mod legacy_address; pub mod traits; -pub use builders::*; mod protocol_types; -pub mod typed_bytes; pub use protocol_types::*; +pub mod typed_bytes; #[macro_use] -pub mod utils; +mod utils; +pub use utils::*; pub(crate) mod fakes; -pub mod serialization; +mod serialization; +pub use serialization::*; use crate::traits::NoneOrEmpty; -use address::*; -use crypto::*; -use error::*; use schemars::JsonSchema; -use serialization::*; use std::cmp::Ordering; use std::collections::BTreeSet; use std::fmt; use std::fmt::Display; -use utils::*; type DeltaCoin = Int; From 58dcd11af4fe8141a1aa4873bcae1a861165ea8b Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 28 Nov 2023 19:36:14 +0800 Subject: [PATCH 202/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 122472f9..86e4b951 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.14", + "version": "12.0.0-alpha.15", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 63532296..40f17ae8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.14", + "version": "12.0.0-alpha.15", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 8864ba5a..f47e67f6 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.14" +version = "12.0.0-alpha.15" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 3d854d94..8d060516 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -37,7 +37,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.14" +version = "12.0.0-alpha.15" dependencies = [ "bech32", "cbor_event", From 82672d4c88836c6d87f69deb1b9404f4ef59594c Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 28 Nov 2023 20:43:12 +0800 Subject: [PATCH 203/349] replace get by get_all in MintsAssets --- rust/src/lib.rs | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 1937687d..8dc402fd 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -2527,6 +2527,10 @@ impl MintsAssets { pub fn get(&self, index: usize) -> Option { self.0.get(index).map(|v| v.clone()) } + + pub fn len(&self) -> usize { + self.0.len() + } } #[wasm_bindgen] @@ -2611,22 +2615,7 @@ impl Mint { None } - /// !!! DEPRECATED !!! - /// Mint can store multiple entries for the same policy id. - /// Use `.get_all` instead. - #[deprecated( - since = "11.2.0", - note = "Mint can store multiple entries for the same policy id. Use `.get_all` instead." - )] - pub fn get(&self, key: &PolicyID) -> Option { - self.0 - .iter() - .filter(|(k, _)| k.eq(key)) - .next() - .map(|(_k, v)| v.clone()) - } - - pub fn get_all(&self, key: &PolicyID) -> Option { + pub fn get(&self, key: &PolicyID) -> Option { let mints: Vec = self .0 .iter() From 6a588602275c47ef3eb50334ebc9e33d2b1c9975 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 28 Nov 2023 20:49:51 +0800 Subject: [PATCH 204/349] fix test --- rust/src/tests/builders/tx_builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index 63cb7666..031b294d 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -3101,7 +3101,7 @@ fn assert_mint_asset(mint: &Mint, policy_id: &PolicyID) { let result_asset = mint.get(&policy_id).unwrap(); assert_eq!(result_asset.len(), 1); assert_eq!( - result_asset.get(&create_asset_name()).unwrap(), + result_asset.get(0).unwrap().get(&create_asset_name()).unwrap(), Int::new_i32(1234) ); } From 190b825006ea6aeac221308716a8a40206f01e0c Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 28 Nov 2023 20:53:16 +0800 Subject: [PATCH 205/349] js flow update --- rust/pkg/cardano_serialization_lib.js.flow | 315 +++------------------ 1 file changed, 39 insertions(+), 276 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 35b1d2e9..3e1ef470 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -171,21 +171,6 @@ declare export function min_ada_for_output( data_cost: DataCost ): BigNum; -/** - * !!! DEPRECATED !!! - * This function uses outdated set of arguments. - * Use `min_ada_for_output` instead - * @param {Value} assets - * @param {boolean} has_data_hash - * @param {BigNum} coins_per_utxo_word - * @returns {BigNum} - */ -declare export function min_ada_required( - assets: Value, - has_data_hash: boolean, - coins_per_utxo_word: BigNum -): BigNum; - /** * Receives a script JSON string * and returns a NativeScript. @@ -265,17 +250,11 @@ declare export function decode_metadatum_to_json_str( /** */ -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 -|}; - -/** - */ - -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 |}; /** @@ -484,11 +463,17 @@ declare export var MetadataJsonSchema: {| /** */ -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 +|}; + +/** + */ + +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 |}; /** @@ -1840,19 +1825,19 @@ declare export class Certificate { ): Certificate; /** - * @param {CommitteeHotAuth} committee_hot_key_registration + * @param {CommitteeHotAuth} committee_hot_auth * @returns {Certificate} */ static new_committee_hot_auth( - committee_hot_key_registration: CommitteeHotAuth + committee_hot_auth: CommitteeHotAuth ): Certificate; /** - * @param {CommitteeColdResign} committee_hot_key_deregistration + * @param {CommitteeColdResign} committee_cold_resign * @returns {Certificate} */ static new_committee_cold_resign( - committee_hot_key_deregistration: CommitteeColdResign + committee_cold_resign: CommitteeColdResign ): Certificate; /** @@ -1958,12 +1943,12 @@ declare export class Certificate { /** * @returns {CommitteeHotAuth | void} */ - as_committee_hot_key_registration(): CommitteeHotAuth | void; + as_committee_hot_auth(): CommitteeHotAuth | void; /** * @returns {CommitteeColdResign | void} */ - as_committee_hot_key_deregistration(): CommitteeColdResign | void; + as_committee_cold_resign(): CommitteeColdResign | void; /** * @returns {DrepDeregistration | void} @@ -2948,14 +2933,6 @@ declare export class DRep { declare export class DataCost { free(): void; - /** - * !!! DEPRECATED !!! - * Since babbage era we should use coins per byte. Use `.new_coins_per_byte` instead. - * @param {BigNum} coins_per_word - * @returns {DataCost} - */ - static new_coins_per_word(coins_per_word: BigNum): DataCost; - /** * @param {BigNum} coins_per_byte * @returns {DataCost} @@ -4663,62 +4640,6 @@ declare export class InfoAction { */ static new(): InfoAction; } -/** - */ -declare export class InputWithScriptWitness { - free(): void; - - /** - * @param {TransactionInput} input - * @param {NativeScript} witness - * @returns {InputWithScriptWitness} - */ - static new_with_native_script_witness( - input: TransactionInput, - witness: NativeScript - ): InputWithScriptWitness; - - /** - * @param {TransactionInput} input - * @param {PlutusWitness} witness - * @returns {InputWithScriptWitness} - */ - static new_with_plutus_witness( - input: TransactionInput, - witness: PlutusWitness - ): InputWithScriptWitness; - - /** - * @returns {TransactionInput} - */ - input(): TransactionInput; -} -/** - */ -declare export class InputsWithScriptWitness { - free(): void; - - /** - * @returns {InputsWithScriptWitness} - */ - static new(): InputsWithScriptWitness; - - /** - * @param {InputWithScriptWitness} input - */ - add(input: InputWithScriptWitness): void; - - /** - * @param {number} index - * @returns {InputWithScriptWitness} - */ - get(index: number): InputWithScriptWitness; - - /** - * @returns {number} - */ - len(): number; -} /** */ declare export class Int { @@ -5424,20 +5345,11 @@ declare export class Mint { */ insert(key: ScriptHash, value: MintAssets): MintAssets | void; - /** - * !!! DEPRECATED !!! - * Mint can store multiple entries for the same policy id. - * Use `.get_all` instead. - * @param {ScriptHash} key - * @returns {MintAssets | void} - */ - get(key: ScriptHash): MintAssets | void; - /** * @param {ScriptHash} key * @returns {MintsAssets | void} */ - get_all(key: ScriptHash): MintsAssets | void; + get(key: ScriptHash): MintsAssets | void; /** * @returns {ScriptHashes} @@ -6143,13 +6055,6 @@ declare export class NetworkInfo { */ static testnet_preprod(): NetworkInfo; - /** - * !!! DEPRECATED !!! - * This network does not exist anymore. Use `.testnet_preview()` or `.testnet_preprod()` - * @returns {NetworkInfo} - */ - static testnet(): NetworkInfo; - /** * @returns {NetworkInfo} */ @@ -6880,27 +6785,13 @@ declare export class PlutusScriptSource { */ static new(script: PlutusScript): PlutusScriptSource; - /** - * !!! DEPRECATED !!! - * This constructor has missed information about plutus script language vesrion. That can affect - * the script data hash calculation. - * Use `.new_ref_input_with_lang_ver` instead - * @param {ScriptHash} script_hash - * @param {TransactionInput} input - * @returns {PlutusScriptSource} - */ - static new_ref_input( - script_hash: ScriptHash, - input: TransactionInput - ): PlutusScriptSource; - /** * @param {ScriptHash} script_hash * @param {TransactionInput} input * @param {Language} lang_ver * @returns {PlutusScriptSource} */ - static new_ref_input_with_lang_ver( + static new_ref_input( script_hash: ScriptHash, input: TransactionInput, lang_ver: Language @@ -10188,13 +10079,6 @@ declare export class TransactionBody { */ mint(): Mint | void; - /** - * This function returns the mint value of the transaction - * Use `.mint()` instead. - * @returns {Mint | void} - */ - multiassets(): Mint | void; - /** * @param {TransactionInputs} reference_inputs */ @@ -10414,24 +10298,6 @@ declare export class TransactionBuilder { amount: Value ): void; - /** - * This method adds the input to the builder BUT leaves a missing spot for the witness native script - * - * After adding the input with this method, use `.add_required_native_input_scripts` - * and `.add_required_plutus_input_scripts` to add the witness scripts - * - * Or instead use `.add_native_script_input` and `.add_plutus_script_input` - * to add inputs right along with the script, instead of the script hash - * @param {ScriptHash} hash - * @param {TransactionInput} input - * @param {Value} amount - */ - add_script_input( - hash: ScriptHash, - input: TransactionInput, - amount: Value - ): void; - /** * This method will add the input to the builder and also register the required native script witness * @param {NativeScript} script @@ -10468,41 +10334,19 @@ declare export class TransactionBuilder { ): void; /** - * Note that for script inputs this method will use underlying generic `.add_script_input` - * which leaves a required empty spot for the script witness (or witnesses in case of Plutus). - * You can use `.add_native_script_input` or `.add_plutus_script_input` directly to register the input along with the witness. + * This function is replace for previous one add_input. + * The functions adds a non script input, if it is a script input it returns an error. + * To add script input you need to use add_native_script_input or add_plutus_script_input. + * Also we recommend to use TxInputsBuilder and .set_inputs, because all add_*_input functions might be removed from transaction builder. * @param {Address} address * @param {TransactionInput} input * @param {Value} amount */ - add_input(address: Address, input: TransactionInput, amount: Value): void; - - /** - * Returns the number of still missing input scripts (either native or plutus) - * Use `.add_required_native_input_scripts` or `.add_required_plutus_input_scripts` to add the missing scripts - * @returns {number} - */ - count_missing_input_scripts(): number; - - /** - * Try adding the specified scripts as witnesses for ALREADY ADDED script inputs - * Any scripts that don't match any of the previously added inputs will be ignored - * Returns the number of remaining required missing witness scripts - * Use `.count_missing_input_scripts` to find the number of still missing scripts - * @param {NativeScripts} scripts - * @returns {number} - */ - add_required_native_input_scripts(scripts: NativeScripts): number; - - /** - * Try adding the specified scripts as witnesses for ALREADY ADDED script inputs - * Any scripts that don't match any of the previously added inputs will be ignored - * Returns the number of remaining required missing witness scripts - * Use `.count_missing_input_scripts` to find the number of still missing scripts - * @param {PlutusWitnesses} scripts - * @returns {number} - */ - add_required_plutus_input_scripts(scripts: PlutusWitnesses): number; + add_regular_input( + address: Address, + input: TransactionInput, + amount: Value + ): void; /** * Returns a copy of the current script input witness scripts in the builder @@ -10957,16 +10801,6 @@ declare export class TransactionBuilderConfigBuilder { */ fee_algo(fee_algo: LinearFee): TransactionBuilderConfigBuilder; - /** - * !!! DEPRECATED !!! - * Since babbage era cardano nodes use coins per byte. Use '.coins_per_utxo_byte' instead. - * @param {BigNum} coins_per_utxo_word - * @returns {TransactionBuilderConfigBuilder} - */ - coins_per_utxo_word( - coins_per_utxo_word: BigNum - ): TransactionBuilderConfigBuilder; - /** * @param {BigNum} coins_per_utxo_byte * @returns {TransactionBuilderConfigBuilder} @@ -11458,18 +11292,6 @@ declare export class TransactionOutputAmountBuilder { multiasset: MultiAsset ): TransactionOutputAmountBuilder; - /** - * !!! DEPRECATED !!! - * Since babbage era cardano nodes use coins per byte. Use '.with_asset_and_min_required_coin_by_utxo_cost' instead. - * @param {MultiAsset} multiasset - * @param {BigNum} coins_per_utxo_word - * @returns {TransactionOutputAmountBuilder} - */ - with_asset_and_min_required_coin( - multiasset: MultiAsset, - coins_per_utxo_word: BigNum - ): TransactionOutputAmountBuilder; - /** * @param {MultiAsset} multiasset * @param {DataCost} data_cost @@ -12016,26 +11838,6 @@ declare export class TxInputsBuilder { amount: Value ): void; - /** - * !!! DEPRECATED !!! - * This function can make a mistake in choosing right input index. Use `.add_native_script_input` or `.add_plutus_script_input` instead. - * This method adds the input to the builder BUT leaves a missing spot for the witness native script - * - * After adding the input with this method, use `.add_required_native_input_scripts` - * and `.add_required_plutus_input_scripts` to add the witness scripts - * - * Or instead use `.add_native_script_input` and `.add_plutus_script_input` - * to add inputs right along with the script, instead of the script hash - * @param {ScriptHash} hash - * @param {TransactionInput} input - * @param {Value} amount - */ - add_script_input( - hash: ScriptHash, - input: TransactionInput, - amount: Value - ): void; - /** * This method will add the input to the builder and also register the required native script witness * @param {NativeScript} script @@ -12072,55 +11874,16 @@ declare export class TxInputsBuilder { ): void; /** - * Note that for script inputs this method will use underlying generic `.add_script_input` - * which leaves a required empty spot for the script witness (or witnesses in case of Plutus). - * You can use `.add_native_script_input` or `.add_plutus_script_input` directly to register the input along with the witness. + * Adds non script input, in case of script or reward address input it will return an error * @param {Address} address * @param {TransactionInput} input * @param {Value} amount */ - add_input(address: Address, input: TransactionInput, amount: Value): void; - - /** - * Returns the number of still missing input scripts (either native or plutus) - * Use `.add_required_native_input_scripts` or `.add_required_plutus_input_scripts` to add the missing scripts - * @returns {number} - */ - count_missing_input_scripts(): number; - - /** - * Try adding the specified scripts as witnesses for ALREADY ADDED script inputs - * Any scripts that don't match any of the previously added inputs will be ignored - * Returns the number of remaining required missing witness scripts - * Use `.count_missing_input_scripts` to find the number of still missing scripts - * @param {NativeScripts} scripts - * @returns {number} - */ - add_required_native_input_scripts(scripts: NativeScripts): number; - - /** - * !!! DEPRECATED !!! - * This function can make a mistake in choosing right input index. Use `.add_required_script_input_witnesses` instead. - * Try adding the specified scripts as witnesses for ALREADY ADDED script inputs - * Any scripts that don't match any of the previously added inputs will be ignored - * Returns the number of remaining required missing witness scripts - * Use `.count_missing_input_scripts` to find the number of still missing scripts - * @param {PlutusWitnesses} scripts - * @returns {number} - */ - add_required_plutus_input_scripts(scripts: PlutusWitnesses): number; - - /** - * Try adding the specified scripts as witnesses for ALREADY ADDED script inputs - * Any scripts that don't match any of the previously added inputs will be ignored - * Returns the number of remaining required missing witness scripts - * Use `.count_missing_input_scripts` to find the number of still missing scripts - * @param {InputsWithScriptWitness} inputs_with_wit - * @returns {number} - */ - add_required_script_input_witnesses( - inputs_with_wit: InputsWithScriptWitness - ): number; + add_regular_input( + address: Address, + input: TransactionInput, + amount: Value + ): void; /** * @returns {TransactionInputs} From bdf07d9cfb936cf20c4d78ac442863ccbf7aab8f Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 5 Dec 2023 17:52:06 +0800 Subject: [PATCH 206/349] add set structures --- rust/src/builders/certificates_builder.rs | 6 +- rust/src/builders/script_structs.rs | 4 +- rust/src/builders/tx_builder.rs | 13 +- rust/src/builders/tx_inputs_builder.rs | 16 +- rust/src/builders/voting_builder.rs | 6 +- rust/src/builders/withdrawals_builder.rs | 6 +- rust/src/fakes.rs | 2 +- rust/src/fees.rs | 3 +- rust/src/lib.rs | 118 ++---------- rust/src/{ => protocol_types}/address.rs | 146 +-------------- .../move_instantaneous_rewards_cert.rs | 5 +- .../certificates/pool_registration.rs | 6 +- rust/src/protocol_types/credentials.rs | 172 ++++++++++++++++++ rust/src/protocol_types/ed25519_key_hashes.rs | 90 +++++++++ .../governance/proposals/committee.rs | 4 +- .../proposals/update_committee_action.rs | 16 +- rust/src/protocol_types/mod.rs | 11 ++ rust/src/protocol_types/transaction_body.rs | 6 +- rust/src/protocol_types/tx_inputs.rs | 39 ++++ .../certificates/certificates_collection.rs | 6 +- .../certificates/pool_registration.rs | 2 +- rust/src/serialization/credentials.rs | 130 +++++++++++++ rust/src/serialization/ed25519_key_hashes.rs | 40 ++++ rust/src/serialization/general.rs | 125 ------------- .../governance/proposals/info_action.rs | 2 +- .../proposals/update_committee_action.rs | 9 +- .../governance/proposals/voting_proposals.rs | 6 +- rust/src/serialization/mod.rs | 18 +- rust/src/serialization/transaction_body.rs | 2 +- rust/src/serialization/tx_inputs.rs | 95 ++++++++++ rust/src/serialization/utils.rs | 8 +- .../tests/builders/certificates_builder.rs | 6 +- rust/src/tests/builders/tx_builder.rs | 8 +- .../tests/builders/voting_proposal_builder.rs | 6 +- rust/src/tests/general.rs | 8 +- rust/src/tests/mock_objects.rs | 2 +- .../protocol_types/governance/proposals.rs | 7 +- rust/src/tests/serialization/certificates.rs | 2 +- .../serialization/governance/proposals.rs | 6 +- .../tests/serialization/transaction_body.rs | 2 +- 40 files changed, 689 insertions(+), 470 deletions(-) rename rust/src/{ => protocol_types}/address.rs (86%) create mode 100644 rust/src/protocol_types/credentials.rs create mode 100644 rust/src/protocol_types/ed25519_key_hashes.rs create mode 100644 rust/src/protocol_types/tx_inputs.rs create mode 100644 rust/src/serialization/credentials.rs create mode 100644 rust/src/serialization/ed25519_key_hashes.rs create mode 100644 rust/src/serialization/tx_inputs.rs diff --git a/rust/src/builders/certificates_builder.rs b/rust/src/builders/certificates_builder.rs index f39ad75a..7b36a494 100644 --- a/rust/src/builders/certificates_builder.rs +++ b/rust/src/builders/certificates_builder.rs @@ -64,11 +64,11 @@ impl CertificatesBuilder { Ok(()) } - pub(crate) fn get_required_signers(&self) -> RequiredSignersSet { - let mut set = RequiredSignersSet::new(); + pub(crate) fn get_required_signers(&self) -> Ed25519KeyHashesSet { + let mut set = Ed25519KeyHashesSet::new(); for (cert, script_wit) in &self.certs { let cert_req_signers = witness_keys_for_cert(&cert); - set.extend(cert_req_signers); + set.0.extend(cert_req_signers); if let Some(ScriptWitnessType::NativeScriptWitness(script_source)) = script_wit { set.extend(script_source.required_signers()); } diff --git a/rust/src/builders/script_structs.rs b/rust/src/builders/script_structs.rs index 085c70cd..edc89abc 100644 --- a/rust/src/builders/script_structs.rs +++ b/rust/src/builders/script_structs.rs @@ -96,9 +96,9 @@ impl NativeScriptSourceEnum { } } - pub fn required_signers(&self) -> RequiredSignersSet { + pub fn required_signers(&self) -> Ed25519KeyHashesSet { match self { - NativeScriptSourceEnum::NativeScript(script) => RequiredSignersSet::from(script), + NativeScriptSourceEnum::NativeScript(script) => Ed25519KeyHashesSet::from(script), NativeScriptSourceEnum::RefInput(_, _, required_signers) => required_signers.into(), } } diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index 2ba005ce..3c2ba841 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -6,6 +6,7 @@ use super::*; use crate::fees; use crate::utils; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; +use crate::map_names::TxBodyNames::RequiredSigners; pub(crate) fn fake_private_key() -> Bip32PrivateKey { Bip32PrivateKey::from_bytes(&[ @@ -39,11 +40,11 @@ pub(crate) fn fake_raw_key_public() -> PublicKey { } fn count_needed_vkeys(tx_builder: &TransactionBuilder) -> usize { - let mut input_hashes: RequiredSignersSet = RequiredSignersSet::from(&tx_builder.inputs); - input_hashes.extend(RequiredSignersSet::from(&tx_builder.collateral)); - input_hashes.extend(RequiredSignersSet::from(&tx_builder.required_signers)); + let mut input_hashes: Ed25519KeyHashesSet = Ed25519KeyHashesSet::from(&tx_builder.inputs); + input_hashes.extend(Ed25519KeyHashesSet::from(&tx_builder.collateral)); + input_hashes.extend(tx_builder.required_signers.clone()); if let Some(mint_builder) = &tx_builder.mint { - input_hashes.extend(RequiredSignersSet::from(&mint_builder.get_native_scripts())); + input_hashes.extend(Ed25519KeyHashesSet::from(&mint_builder.get_native_scripts())); } if let Some(withdrawals_builder) = &tx_builder.withdrawals { input_hashes.extend(withdrawals_builder.get_required_signers()); @@ -326,7 +327,7 @@ pub struct TransactionBuilder { pub(crate) validity_start_interval: Option, pub(crate) mint: Option, pub(crate) script_data_hash: Option, - pub(crate) required_signers: Ed25519KeyHashes, + pub(crate) required_signers: Ed25519KeyHashesSet, pub(crate) collateral_return: Option, pub(crate) total_collateral: Option, pub(crate) reference_inputs: HashSet, @@ -1290,7 +1291,7 @@ impl TransactionBuilder { validity_start_interval: None, mint: None, script_data_hash: None, - required_signers: Ed25519KeyHashes::new(), + required_signers: Ed25519KeyHashesSet::new(), collateral_return: None, total_collateral: None, reference_inputs: HashSet::new(), diff --git a/rust/src/builders/tx_inputs_builder.rs b/rust/src/builders/tx_inputs_builder.rs index 0d987d5e..f8ed11ee 100644 --- a/rust/src/builders/tx_inputs_builder.rs +++ b/rust/src/builders/tx_inputs_builder.rs @@ -65,8 +65,8 @@ impl InputsWithScriptWitness { // We need to know how many of each type of witness will be in the transaction so we can calculate the tx fee #[derive(Clone, Debug)] -pub struct RequiredWitnessSet { - vkeys: RequiredSignersSet, +pub struct InputsRequiredWitness { + vkeys: Ed25519KeyHashesSet, scripts: LinkedHashMap>>, bootstraps: BTreeSet>, } @@ -75,7 +75,7 @@ pub struct RequiredWitnessSet { #[derive(Clone, Debug)] pub struct TxInputsBuilder { inputs: BTreeMap)>, - required_witnesses: RequiredWitnessSet, + required_witnesses: InputsRequiredWitness, } pub(crate) fn get_bootstraps(inputs: &TxInputsBuilder) -> BTreeSet> { @@ -87,8 +87,8 @@ impl TxInputsBuilder { pub fn new() -> Self { Self { inputs: BTreeMap::new(), - required_witnesses: RequiredWitnessSet { - vkeys: BTreeSet::new(), + required_witnesses: InputsRequiredWitness { + vkeys: Ed25519KeyHashesSet::new(), scripts: LinkedHashMap::new(), bootstraps: BTreeSet::new(), }, @@ -113,7 +113,7 @@ impl TxInputsBuilder { amount: amount.clone(), }; self.push_input((inp, None)); - self.required_witnesses.vkeys.insert(hash.clone()); + self.required_witnesses.vkeys.add_move(hash.clone()); } #[deprecated( @@ -466,7 +466,7 @@ impl TxInputsBuilder { } pub fn add_required_signer(&mut self, key: &Ed25519KeyHash) { - self.required_witnesses.vkeys.insert(key.clone()); + self.required_witnesses.vkeys.add_move(key.clone()); } pub fn add_required_signers(&mut self, keys: &RequiredSigners) { @@ -526,7 +526,7 @@ impl TxInputsBuilder { } } -impl From<&TxInputsBuilder> for RequiredSignersSet { +impl From<&TxInputsBuilder> for Ed25519KeyHashesSet { fn from(inputs: &TxInputsBuilder) -> Self { let mut set = inputs.required_witnesses.vkeys.clone(); inputs diff --git a/rust/src/builders/voting_builder.rs b/rust/src/builders/voting_builder.rs index 73f16b17..3e977045 100644 --- a/rust/src/builders/voting_builder.rs +++ b/rust/src/builders/voting_builder.rs @@ -100,12 +100,12 @@ impl VotingBuilder { Ok(()) } - pub(crate) fn get_required_signers(&self) -> RequiredSignersSet { - let mut set = RequiredSignersSet::new(); + pub(crate) fn get_required_signers(&self) -> Ed25519KeyHashesSet { + let mut set = Ed25519KeyHashesSet::new(); for (voter, voter_votes) in &self.votes { let req_signature = voter.to_key_hash(); if let Some(req_signature) = req_signature { - set.insert(req_signature); + set.add_move(req_signature); } if let Some(ScriptWitnessType::NativeScriptWitness(script_source)) = diff --git a/rust/src/builders/withdrawals_builder.rs b/rust/src/builders/withdrawals_builder.rs index 14d5c5cd..6ab5a2a0 100644 --- a/rust/src/builders/withdrawals_builder.rs +++ b/rust/src/builders/withdrawals_builder.rs @@ -77,12 +77,12 @@ impl WithdrawalsBuilder { Ok(()) } - pub(crate) fn get_required_signers(&self) -> RequiredSignersSet { - let mut set = RequiredSignersSet::new(); + pub(crate) fn get_required_signers(&self) -> Ed25519KeyHashesSet { + let mut set = Ed25519KeyHashesSet::new(); for (address, (_, script_wit)) in &self.withdrawals { let req_signature = address.payment_cred().to_keyhash(); if let Some(req_signature) = req_signature { - set.insert(req_signature); + set.add_move(req_signature); } if let Some(ScriptWitnessType::NativeScriptWitness(script_source)) = script_wit { diff --git a/rust/src/fakes.rs b/rust/src/fakes.rs index 8e7a3947..1932474b 100644 --- a/rust/src/fakes.rs +++ b/rust/src/fakes.rs @@ -7,7 +7,7 @@ use crate::{ Ed25519Signature, NetworkInfo, PolicyID, TransactionHash, TransactionIndex, TransactionInput, TransactionOutput, Value, Vkey, AssetName, }; -use crate::address::RewardAddress; +use crate::RewardAddress; pub(crate) fn fake_bytes_32(x: u8) -> Vec { vec![ diff --git a/rust/src/fees.rs b/rust/src/fees.rs index 03682537..bb4498fa 100644 --- a/rust/src/fees.rs +++ b/rust/src/fees.rs @@ -91,7 +91,6 @@ pub fn min_script_fee(tx: &Transaction, ex_unit_prices: &ExUnitPrices) -> Result mod tests { use super::*; use crate::TransactionOutputBuilder; - use address::*; use crypto::*; // based off tx test vectors (https://gist.github.com/KtorZ/5a2089df0915f21aca368d12545ab230) @@ -331,7 +330,7 @@ mod tests { let mut certs = Certificates::new(); - let mut pool_owners = Ed25519KeyHashes::new(); + let mut pool_owners = Ed25519KeyHashesSet::new(); pool_owners.add( &PublicKey::from_bytes( &hex::decode("54d1a9c5ad69586ceeb839c438400c376c0bd34825fb4c17cc2f58c54e1437f3") diff --git a/rust/src/lib.rs b/rust/src/lib.rs index e3ef0b9d..81ac6436 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -41,8 +41,6 @@ use cbor_event::{ se::{Serialize, Serializer}, }; -mod address; -pub use address::*; mod builders; pub use builders::*; pub mod chain_core; @@ -291,62 +289,6 @@ impl DataCost { } } -pub type RequiredSigners = Ed25519KeyHashes; -pub type RequiredSignersSet = BTreeSet; - -impl NoneOrEmpty for RequiredSigners { - fn is_none_or_empty(&self) -> bool { - self.0.is_empty() - } -} - -impl From<&Ed25519KeyHashes> for RequiredSignersSet { - fn from(keys: &Ed25519KeyHashes) -> Self { - keys.0.iter().fold(BTreeSet::new(), |mut set, k| { - set.insert(k.clone()); - set - }) - } -} - -#[wasm_bindgen] -#[derive( - Clone, - Debug, - Eq, - Ord, - PartialEq, - PartialOrd, - Hash, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub struct TransactionInput { - transaction_id: TransactionHash, - index: TransactionIndex, -} - -impl_to_from!(TransactionInput); - -#[wasm_bindgen] -impl TransactionInput { - pub fn transaction_id(&self) -> TransactionHash { - self.transaction_id.clone() - } - - pub fn index(&self) -> TransactionIndex { - self.index.clone() - } - - pub fn new(transaction_id: &TransactionHash, index: TransactionIndex) -> Self { - Self { - transaction_id: transaction_id.clone(), - index: index, - } - } -} - #[wasm_bindgen] #[derive(Debug, Clone, Eq, Ord, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema)] pub struct TransactionOutput { @@ -948,33 +890,6 @@ impl PoolMetadata { } } -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct Credentials(Vec); - -impl_to_from!(Credentials); - -#[wasm_bindgen] -impl Credentials { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> Credential { - self.0[index].clone() - } - - pub fn add(&mut self, elem: &Credential) { - self.0.push(elem.clone()); - } -} - #[wasm_bindgen] #[derive( Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, @@ -1553,16 +1468,11 @@ impl NativeScript { } } - /// Returns an array of unique Ed25519KeyHashes + /// Returns a set of Ed25519KeyHashes /// contained within this script recursively on any depth level. /// The order of the keys in the result is not determined in any way. - pub fn get_required_signers(&self) -> Ed25519KeyHashes { - Ed25519KeyHashes( - RequiredSignersSet::from(self) - .iter() - .map(|k| k.clone()) - .collect(), - ) + pub fn get_required_signers(&self) -> Ed25519KeyHashesSet { + Ed25519KeyHashesSet::from(self) } } @@ -2749,27 +2659,27 @@ impl NetworkId { } } -impl From<&NativeScript> for RequiredSignersSet { +impl From<&NativeScript> for Ed25519KeyHashesSet { fn from(script: &NativeScript) -> Self { match &script.0 { NativeScriptEnum::ScriptPubkey(spk) => { - let mut set = BTreeSet::new(); - set.insert(spk.addr_keyhash()); + let mut set = Ed25519KeyHashesSet::new(); + set.add_move(spk.addr_keyhash()); set } - NativeScriptEnum::ScriptAll(all) => RequiredSignersSet::from(&all.native_scripts), - NativeScriptEnum::ScriptAny(any) => RequiredSignersSet::from(&any.native_scripts), - NativeScriptEnum::ScriptNOfK(ofk) => RequiredSignersSet::from(&ofk.native_scripts), - _ => BTreeSet::new(), + NativeScriptEnum::ScriptAll(all) => Ed25519KeyHashesSet::from(&all.native_scripts), + NativeScriptEnum::ScriptAny(any) => Ed25519KeyHashesSet::from(&any.native_scripts), + NativeScriptEnum::ScriptNOfK(ofk) => Ed25519KeyHashesSet::from(&ofk.native_scripts), + _ => Ed25519KeyHashesSet::new(), } } } -impl From<&NativeScripts> for RequiredSignersSet { +impl From<&NativeScripts> for Ed25519KeyHashesSet { fn from(scripts: &NativeScripts) -> Self { - scripts.0.iter().fold(BTreeSet::new(), |mut set, s| { - RequiredSignersSet::from(s).iter().for_each(|pk| { - set.insert(pk.clone()); + scripts.0.iter().fold(Ed25519KeyHashesSet::new(), |mut set, s| { + Ed25519KeyHashesSet::from(s).0.iter().for_each(|pk| { + set.add_move(pk.clone()); }); set }) diff --git a/rust/src/address.rs b/rust/src/protocol_types/address.rs similarity index 86% rename from rust/src/address.rs rename to rust/src/protocol_types/address.rs index 962bbead..fda6f8ac 100644 --- a/rust/src/address.rs +++ b/rust/src/protocol_types/address.rs @@ -1,4 +1,4 @@ -use super::*; +use crate::*; use crate::legacy_address::ExtendedAddr; use bech32::ToBase32; use ed25519_bip32::XPub; @@ -85,150 +85,6 @@ impl NetworkInfo { } } -#[derive( - Debug, - Clone, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub enum CredType { - Key(Ed25519KeyHash), - Script(ScriptHash), -} - -#[wasm_bindgen] -#[repr(u8)] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub enum CredKind { - Key, - Script, -} - -#[wasm_bindgen] -#[derive( - Debug, - Clone, - Eq, - Hash, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub struct Credential(pub(crate) CredType); - -#[wasm_bindgen] -impl Credential { - pub fn from_keyhash(hash: &Ed25519KeyHash) -> Self { - Credential(CredType::Key(hash.clone())) - } - - pub fn from_scripthash(hash: &ScriptHash) -> Self { - Credential(CredType::Script(hash.clone())) - } - - pub fn to_keyhash(&self) -> Option { - match &self.0 { - CredType::Key(hash) => Some(hash.clone()), - CredType::Script(_) => None, - } - } - - pub fn to_scripthash(&self) -> Option { - match &self.0 { - CredType::Key(_) => None, - CredType::Script(hash) => Some(hash.clone()), - } - } - - pub fn kind(&self) -> CredKind { - match &self.0 { - CredType::Key(_) => CredKind::Key, - CredType::Script(_) => CredKind::Script, - } - } - - pub fn has_script_hash(&self) -> bool { - match &self.0 { - CredType::Key(_) => false, - CredType::Script(_) => true, - } - } - - fn to_raw_bytes(&self) -> Vec { - match &self.0 { - CredType::Key(hash) => hash.to_bytes(), - CredType::Script(hash) => hash.to_bytes(), - } - } -} - -impl_to_from!(Credential); - -impl cbor_event::se::Serialize for Credential { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - match &self.0 { - CredType::Key(keyhash) => { - serializer.write_unsigned_integer(0u64)?; - serializer.write_bytes(keyhash.to_bytes()) - } - CredType::Script(scripthash) => { - serializer.write_unsigned_integer(1u64)?; - serializer.write_bytes(scripthash.to_bytes()) - } - } - } -} - -impl Deserialize for Credential { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - if let cbor_event::Len::Len(n) = len { - if n != 2 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 2, - len, - "[id, hash]", - )) - .into()); - } - } - let cred_type = match raw.unsigned_integer()? { - 0 => CredType::Key(Ed25519KeyHash::deserialize(raw)?), - 1 => CredType::Script(ScriptHash::deserialize(raw)?), - n => { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(n), - // TODO: change codegen to make FixedValueMismatch support Vec or ranges or something - expected: Key::Uint(0), - } - .into()); - } - }; - if let cbor_event::Len::Indefinite = len { - if raw.special()? != CBORSpecial::Break { - return Err(DeserializeFailure::EndingBreakMissing.into()); - } - } - Ok(Credential(cred_type)) - })() - .map_err(|e| e.annotate("StakeCredential")) - } -} - #[derive(Debug, Clone, Eq, Ord, PartialEq, PartialOrd)] pub(crate) enum AddrType { Base(BaseAddress), diff --git a/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs b/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs index 78cc4df7..154308aa 100644 --- a/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs +++ b/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs @@ -106,12 +106,11 @@ impl MIRToStakeCredentials { self.rewards.get(cred).map(|v| v.clone()) } - pub fn keys(&self) -> Credentials { - Credentials( + pub fn keys(&self) -> CredentialsSet { + CredentialsSet::from_iter( self.rewards .iter() .map(|(k, _v)| k.clone()) - .collect::>(), ) } } diff --git a/rust/src/protocol_types/certificates/pool_registration.rs b/rust/src/protocol_types/certificates/pool_registration.rs index 80904fd8..bf2ac322 100644 --- a/rust/src/protocol_types/certificates/pool_registration.rs +++ b/rust/src/protocol_types/certificates/pool_registration.rs @@ -88,7 +88,7 @@ pub struct PoolParams { pub(crate) cost: Coin, pub(crate) margin: UnitInterval, pub(crate) reward_account: RewardAddress, - pub(crate) pool_owners: Ed25519KeyHashes, + pub(crate) pool_owners: Ed25519KeyHashesSet, pub(crate) relays: Relays, pub(crate) pool_metadata: Option, } @@ -121,7 +121,7 @@ impl PoolParams { self.reward_account.clone() } - pub fn pool_owners(&self) -> Ed25519KeyHashes { + pub fn pool_owners(&self) -> Ed25519KeyHashesSet { self.pool_owners.clone() } @@ -140,7 +140,7 @@ impl PoolParams { cost: &Coin, margin: &UnitInterval, reward_account: &RewardAddress, - pool_owners: &Ed25519KeyHashes, + pool_owners: &Ed25519KeyHashesSet, relays: &Relays, pool_metadata: Option, ) -> Self { diff --git a/rust/src/protocol_types/credentials.rs b/rust/src/protocol_types/credentials.rs new file mode 100644 index 00000000..27ba1c0a --- /dev/null +++ b/rust/src/protocol_types/credentials.rs @@ -0,0 +1,172 @@ +use crate::*; +use linked_hash_map::LinkedHashMap; + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct CredentialsSet(pub(crate) BTreeSet); + +impl_to_from!(CredentialsSet); + +#[wasm_bindgen] +impl CredentialsSet { + pub fn new() -> Self { + Self(BTreeSet::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> Option { + self.0.iter().nth(index).cloned() + } + + pub fn add(&mut self, elem: &Credential) { + self.0.insert(elem.clone()); + } + + pub fn contains(&self, elem: &Credential) -> bool { + self.0.contains(elem) + } + + pub fn to_vec(&self) -> Credentials { + Credentials(self.0.iter().cloned().collect()) + } + + pub(crate) fn from_iter(iter: I) -> Self + where + I: IntoIterator, + { + Self(iter.into_iter().collect()) + } + + pub(crate) fn add_move(&mut self, elem: Credential) { + self.0.insert(elem); + } +} + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct Credentials(pub(crate) Vec); + +impl_to_from!(Credentials); + +#[wasm_bindgen] +impl Credentials { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> Credential { + self.0[index].clone() + } + + pub fn add(&mut self, elem: &Credential) { + self.0.push(elem.clone()); + } +} + +#[derive( + Debug, + Clone, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub enum CredType { + Key(Ed25519KeyHash), + Script(ScriptHash), +} + +#[wasm_bindgen] +#[repr(u8)] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub enum CredKind { + Key, + Script, +} + +#[wasm_bindgen] +#[derive( + Debug, + Clone, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct Credential(pub(crate) CredType); + +#[wasm_bindgen] +impl Credential { + pub fn from_keyhash(hash: &Ed25519KeyHash) -> Self { + Credential(CredType::Key(hash.clone())) + } + + pub fn from_scripthash(hash: &ScriptHash) -> Self { + Credential(CredType::Script(hash.clone())) + } + + pub fn to_keyhash(&self) -> Option { + match &self.0 { + CredType::Key(hash) => Some(hash.clone()), + CredType::Script(_) => None, + } + } + + pub fn to_scripthash(&self) -> Option { + match &self.0 { + CredType::Key(_) => None, + CredType::Script(hash) => Some(hash.clone()), + } + } + + pub fn kind(&self) -> CredKind { + match &self.0 { + CredType::Key(_) => CredKind::Key, + CredType::Script(_) => CredKind::Script, + } + } + + pub fn has_script_hash(&self) -> bool { + match &self.0 { + CredType::Key(_) => false, + CredType::Script(_) => true, + } + } + + pub(crate) fn to_raw_bytes(&self) -> Vec { + match &self.0 { + CredType::Key(hash) => hash.to_bytes(), + CredType::Script(hash) => hash.to_bytes(), + } + } +} + +impl_to_from!(Credential); diff --git a/rust/src/protocol_types/ed25519_key_hashes.rs b/rust/src/protocol_types/ed25519_key_hashes.rs new file mode 100644 index 00000000..0bb39378 --- /dev/null +++ b/rust/src/protocol_types/ed25519_key_hashes.rs @@ -0,0 +1,90 @@ +pub use crate::*; + +pub type RequiredSigners = Ed25519KeyHashes; + +#[wasm_bindgen] +#[derive( + Clone, + Hash, + Debug, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct Ed25519KeyHashesSet(pub(crate) BTreeSet); + +impl_to_from!(Ed25519KeyHashesSet); + +#[wasm_bindgen] +impl Ed25519KeyHashesSet { + pub fn new() -> Self { + Self(BTreeSet::new()) + } + + pub fn add(&mut self, key: &Ed25519KeyHash) { + self.0.insert(key.clone()); + } + + pub fn remove(&mut self, key: &Ed25519KeyHash) { + self.0.remove(key); + } + + pub fn contains(&self, key: &Ed25519KeyHash) -> bool { + self.0.contains(key) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> Option { + self.0.iter().nth(index).cloned() + } + + pub fn to_vec(&self) -> RequiredSigners { + Ed25519KeyHashes(self.0.iter().cloned().collect()) + } + + pub(crate) fn add_move(&mut self, key: Ed25519KeyHash) { + self.0.insert(key); + } + + pub(crate) fn extend(&mut self, keys: Ed25519KeyHashesSet) { + self.0.extend(keys.0); + } + + pub(crate) fn to_option(&self) -> Option { + if self.0.is_empty() { + None + } else { + Some(self.clone()) + } + } +} + +impl NoneOrEmpty for Ed25519KeyHashesSet { + fn is_none_or_empty(&self) -> bool { + self.0.is_empty() + } +} + +impl NoneOrEmpty for RequiredSigners { + fn is_none_or_empty(&self) -> bool { + self.0.is_empty() + } +} + +impl From<&Ed25519KeyHashes> for Ed25519KeyHashesSet { + fn from(keys: &Ed25519KeyHashes) -> Self { + keys.0 + .iter() + .fold(Ed25519KeyHashesSet::new(), |mut set, k| { + set.add_move(k.clone()); + set + }) + } +} diff --git a/rust/src/protocol_types/governance/proposals/committee.rs b/rust/src/protocol_types/governance/proposals/committee.rs index 95249fea..faa92ca4 100644 --- a/rust/src/protocol_types/governance/proposals/committee.rs +++ b/rust/src/protocol_types/governance/proposals/committee.rs @@ -55,8 +55,8 @@ impl Committee { } } - pub fn members_keys(&self) -> Credentials { - Credentials(self.members.keys().cloned().collect()) + pub fn members_keys(&self) -> CredentialsSet { + CredentialsSet::from_iter(self.members.keys().cloned()) } pub fn quorum_threshold(&self) -> UnitInterval { diff --git a/rust/src/protocol_types/governance/proposals/update_committee_action.rs b/rust/src/protocol_types/governance/proposals/update_committee_action.rs index 83e78b42..895e3463 100644 --- a/rust/src/protocol_types/governance/proposals/update_committee_action.rs +++ b/rust/src/protocol_types/governance/proposals/update_committee_action.rs @@ -16,7 +16,7 @@ use crate::*; pub struct UpdateCommitteeAction { pub(crate) gov_action_id: Option, pub(crate) committee: Committee, - pub(crate) members_to_remove: BTreeSet, + pub(crate) members_to_remove: CredentialsSet, } impl_to_from!(UpdateCommitteeAction); @@ -31,29 +31,27 @@ impl UpdateCommitteeAction { self.committee.clone() } - pub fn members_to_remove(&self) -> Credentials { - Credentials(self.members_to_remove.iter().cloned().collect()) + pub fn members_to_remove(&self) -> CredentialsSet { + self.members_to_remove.clone() } - pub fn new(committee: &Committee, members_to_remove: &Credentials) -> Self { - let members_to_remove = members_to_remove.0.iter().cloned().collect(); + pub fn new(committee: &Committee, members_to_remove: &CredentialsSet) -> Self { Self { gov_action_id: None, committee: committee.clone(), - members_to_remove, + members_to_remove: members_to_remove.clone(), } } pub fn new_with_action_id( gov_action_id: &GovernanceActionId, committee: &Committee, - members_to_remove: &Credentials, + members_to_remove: &CredentialsSet, ) -> Self { - let members_to_remove = members_to_remove.0.iter().cloned().collect(); Self { gov_action_id: Some(gov_action_id.clone()), committee: committee.clone(), - members_to_remove, + members_to_remove: members_to_remove.clone(), } } } diff --git a/rust/src/protocol_types/mod.rs b/rust/src/protocol_types/mod.rs index b0f59f35..62112252 100644 --- a/rust/src/protocol_types/mod.rs +++ b/rust/src/protocol_types/mod.rs @@ -19,3 +19,14 @@ pub use transaction_body::*; mod protocol_param_update; pub use protocol_param_update::*; + +mod address; +pub use address::*; +mod tx_inputs; +pub use tx_inputs::*; + +mod credentials; +pub use credentials::*; + +mod ed25519_key_hashes; +pub use ed25519_key_hashes::*; \ No newline at end of file diff --git a/rust/src/protocol_types/transaction_body.rs b/rust/src/protocol_types/transaction_body.rs index cef72692..5eb91a40 100644 --- a/rust/src/protocol_types/transaction_body.rs +++ b/rust/src/protocol_types/transaction_body.rs @@ -15,7 +15,7 @@ pub struct TransactionBody { pub(crate) mint: Option, pub(crate) script_data_hash: Option, pub(crate) collateral: Option, - pub(crate) required_signers: Option, + pub(crate) required_signers: Option, pub(crate) network_id: Option, pub(crate) collateral_return: Option, pub(crate) total_collateral: Option, @@ -178,11 +178,11 @@ impl TransactionBody { self.collateral.clone() } - pub fn set_required_signers(&mut self, required_signers: &RequiredSigners) { + pub fn set_required_signers(&mut self, required_signers: &Ed25519KeyHashesSet) { self.required_signers = Some(required_signers.clone()) } - pub fn required_signers(&self) -> Option { + pub fn required_signers(&self) -> Option { self.required_signers.clone() } diff --git a/rust/src/protocol_types/tx_inputs.rs b/rust/src/protocol_types/tx_inputs.rs new file mode 100644 index 00000000..6b480572 --- /dev/null +++ b/rust/src/protocol_types/tx_inputs.rs @@ -0,0 +1,39 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Eq, + Ord, + PartialEq, + PartialOrd, + Hash, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct TransactionInput { + pub(crate) transaction_id: TransactionHash, + pub(crate) index: TransactionIndex, +} + +impl_to_from!(TransactionInput); + +#[wasm_bindgen] +impl TransactionInput { + pub fn transaction_id(&self) -> TransactionHash { + self.transaction_id.clone() + } + + pub fn index(&self) -> TransactionIndex { + self.index.clone() + } + + pub fn new(transaction_id: &TransactionHash, index: TransactionIndex) -> Self { + Self { + transaction_id: transaction_id.clone(), + index: index, + } + } +} diff --git a/rust/src/serialization/certificates/certificates_collection.rs b/rust/src/serialization/certificates/certificates_collection.rs index 2828f184..c3391e92 100644 --- a/rust/src/serialization/certificates/certificates_collection.rs +++ b/rust/src/serialization/certificates/certificates_collection.rs @@ -1,4 +1,4 @@ -use crate::serialization::utils::skip_set_tag_wrapperr; +use crate::serialization::utils::skip_set_tag; use crate::*; impl Serialize for Certificates { @@ -6,6 +6,8 @@ impl Serialize for Certificates { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { + //TODO: uncomment this line when we conway ero will come + //serializer.write_tag(258)?; serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; for element in &self.0 { element.serialize(serializer)?; @@ -16,7 +18,7 @@ impl Serialize for Certificates { impl Deserialize for Certificates { fn deserialize(raw: &mut Deserializer) -> Result { - skip_set_tag_wrapperr(raw)?; + skip_set_tag(raw)?; let mut arr = Vec::new(); (|| -> Result<_, DeserializeError> { let len = raw.array()?; diff --git a/rust/src/serialization/certificates/pool_registration.rs b/rust/src/serialization/certificates/pool_registration.rs index 88370bfa..06f59960 100644 --- a/rust/src/serialization/certificates/pool_registration.rs +++ b/rust/src/serialization/certificates/pool_registration.rs @@ -94,7 +94,7 @@ impl DeserializeEmbeddedGroup for PoolParams { (|| -> Result<_, DeserializeError> { Ok(RewardAddress::deserialize(raw)?) })() .map_err(|e| e.annotate("reward_account"))?; let pool_owners = - (|| -> Result<_, DeserializeError> { Ok(Ed25519KeyHashes::deserialize(raw)?) })() + (|| -> Result<_, DeserializeError> { Ok(Ed25519KeyHashesSet::deserialize(raw)?) })() .map_err(|e| e.annotate("pool_owners"))?; let relays = (|| -> Result<_, DeserializeError> { Ok(Relays::deserialize(raw)?) })() .map_err(|e| e.annotate("relays"))?; diff --git a/rust/src/serialization/credentials.rs b/rust/src/serialization/credentials.rs new file mode 100644 index 00000000..c01b11da --- /dev/null +++ b/rust/src/serialization/credentials.rs @@ -0,0 +1,130 @@ +use crate::*; +use crate::serialization::utils::skip_set_tag; + +impl cbor_event::se::Serialize for CredentialsSet { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + //TODO: uncomment this line when we conway ero will come + //serializer.write_tag(258)?; + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for CredentialsSet { + fn deserialize(raw: &mut Deserializer) -> Result { + skip_set_tag(raw)?; + let mut creds = CredentialsSet::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => creds.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + creds.add_move(Credential::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("CredentialsSet"))?; + Ok(creds) + } +} + +impl cbor_event::se::Serialize for Credentials { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for Credentials { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut creds = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => creds.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + creds.push(Credential::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("Credentials"))?; + Ok(Credentials(creds)) + } +} + +impl cbor_event::se::Serialize for Credential { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + match &self.0 { + CredType::Key(keyhash) => { + serializer.write_unsigned_integer(0u64)?; + serializer.write_bytes(keyhash.to_bytes()) + } + CredType::Script(scripthash) => { + serializer.write_unsigned_integer(1u64)?; + serializer.write_bytes(scripthash.to_bytes()) + } + } + } +} + +impl Deserialize for Credential { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + if let cbor_event::Len::Len(n) = len { + if n != 2 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 2, + len, + "[id, hash]", + )) + .into()); + } + } + let cred_type = match raw.unsigned_integer()? { + 0 => CredType::Key(Ed25519KeyHash::deserialize(raw)?), + 1 => CredType::Script(ScriptHash::deserialize(raw)?), + n => { + return Err(DeserializeFailure::FixedValuesMismatch { + found: Key::Uint(n), + expected: vec![Key::Uint(0), Key::Uint(1)], + } + .into()); + } + }; + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + Ok(Credential(cred_type)) + })() + .map_err(|e| e.annotate("StakeCredential")) + } +} \ No newline at end of file diff --git a/rust/src/serialization/ed25519_key_hashes.rs b/rust/src/serialization/ed25519_key_hashes.rs new file mode 100644 index 00000000..3484ed8b --- /dev/null +++ b/rust/src/serialization/ed25519_key_hashes.rs @@ -0,0 +1,40 @@ +use crate::*; +use crate::serialization::utils::skip_set_tag; + +impl cbor_event::se::Serialize for Ed25519KeyHashesSet { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + //TODO: uncomment this line when we conway ero will come + //serializer.write_tag(258)?; + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for Ed25519KeyHashesSet { + fn deserialize(raw: &mut Deserializer) -> Result { + skip_set_tag(raw)?; + let mut creds = Ed25519KeyHashesSet::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => creds.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + creds.add_move(Ed25519KeyHash::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("RequiredSignersSet"))?; + Ok(creds) + } +} \ No newline at end of file diff --git a/rust/src/serialization/general.rs b/rust/src/serialization/general.rs index 98532884..c3d4e86a 100644 --- a/rust/src/serialization/general.rs +++ b/rust/src/serialization/general.rs @@ -175,41 +175,6 @@ impl DeserializeEmbeddedGroup for Transaction { } } -impl cbor_event::se::Serialize for TransactionInputs { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for TransactionInputs { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(TransactionInput::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("TransactionInputs"))?; - Ok(Self(arr)) - } -} - impl cbor_event::se::Serialize for TransactionOutputs { fn serialize<'se, W: Write>( &self, @@ -245,61 +210,6 @@ impl Deserialize for TransactionOutputs { } } -impl cbor_event::se::Serialize for TransactionInput { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - self.transaction_id.serialize(serializer)?; - self.index.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for TransactionInput { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("TransactionInput")) - } -} - -impl DeserializeEmbeddedGroup for TransactionInput { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - _: cbor_event::Len, - ) -> Result { - let transaction_id = - (|| -> Result<_, DeserializeError> { Ok(TransactionHash::deserialize(raw)?) })() - .map_err(|e| e.annotate("transaction_id"))?; - let index = (|| -> Result<_, DeserializeError> { Ok(u32::deserialize(raw)?) })() - .map_err(|e| e.annotate("index"))?; - Ok(TransactionInput { - transaction_id, - index, - }) - } -} - impl cbor_event::se::Serialize for TransactionOutput { fn serialize<'se, W: Write>( &self, @@ -714,41 +624,6 @@ impl Deserialize for Ed25519KeyHashes { } } -impl cbor_event::se::Serialize for Credentials { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for Credentials { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(Credential::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("StakeCredentials"))?; - Ok(Self(arr)) - } -} - impl cbor_event::se::Serialize for Ipv4 { fn serialize<'se, W: Write>( &self, diff --git a/rust/src/serialization/governance/proposals/info_action.rs b/rust/src/serialization/governance/proposals/info_action.rs index d3efa97a..aa9f3763 100644 --- a/rust/src/serialization/governance/proposals/info_action.rs +++ b/rust/src/serialization/governance/proposals/info_action.rs @@ -1,4 +1,4 @@ -use crate::serialization::utils::{check_len_indefinite, serialize_and_check_index}; +use crate::serialization::utils:: serialize_and_check_index; use crate::serialization::{check_len, deserialize_and_check_index}; use crate::*; use map_names::VotingProposalIndexNames; diff --git a/rust/src/serialization/governance/proposals/update_committee_action.rs b/rust/src/serialization/governance/proposals/update_committee_action.rs index 4cef0b7d..31d5e8e6 100644 --- a/rust/src/serialization/governance/proposals/update_committee_action.rs +++ b/rust/src/serialization/governance/proposals/update_committee_action.rs @@ -15,10 +15,7 @@ impl Serialize for UpdateCommitteeAction { serialize_and_check_index(serializer, proposal_index, "UpdateCommitteeAction")?; self.gov_action_id.serialize_nullable(serializer)?; - - let members_to_remove = Credentials(self.members_to_remove.iter().cloned().collect()); - members_to_remove.serialize(serializer)?; - + self.members_to_remove.serialize(serializer)?; self.committee.serialize_as_embedded_group(serializer)?; Ok(serializer) @@ -45,14 +42,14 @@ impl DeserializeEmbeddedGroup for UpdateCommitteeAction { .map_err(|e| e.annotate("gov_action_id"))?; let members_to_remove = - Credentials::deserialize(raw).map_err(|e| e.annotate("members_to_remove"))?; + CredentialsSet::deserialize(raw).map_err(|e| e.annotate("members_to_remove"))?; let committee = Committee::deserialize_as_embedded_group(raw, cbor_event::Len::Len(2)) .map_err(|e| e.annotate("committee"))?; return Ok(UpdateCommitteeAction { gov_action_id, - members_to_remove: members_to_remove.0.iter().cloned().collect(), + members_to_remove, committee, }); } diff --git a/rust/src/serialization/governance/proposals/voting_proposals.rs b/rust/src/serialization/governance/proposals/voting_proposals.rs index d7e092f4..01b75ded 100644 --- a/rust/src/serialization/governance/proposals/voting_proposals.rs +++ b/rust/src/serialization/governance/proposals/voting_proposals.rs @@ -1,11 +1,13 @@ use crate::*; -use crate::serialization::utils::skip_set_tag_wrapperr; +use crate::serialization::utils::skip_set_tag; impl cbor_event::se::Serialize for VotingProposals { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { + //TODO: uncomment this line when we conway ero will come + //serializer.write_tag(258)?; serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; for element in &self.0 { element.serialize(serializer)?; @@ -18,7 +20,7 @@ impl Deserialize for VotingProposals { fn deserialize(raw: &mut Deserializer) -> Result { let mut arr = Vec::new(); (|| -> Result<_, DeserializeError> { - skip_set_tag_wrapperr(raw)?; + skip_set_tag(raw)?; let len = raw.array()?; while match len { cbor_event::Len::Len(n) => arr.len() < n as usize, diff --git a/rust/src/serialization/mod.rs b/rust/src/serialization/mod.rs index 2dea7b4c..2aa6c095 100644 --- a/rust/src/serialization/mod.rs +++ b/rust/src/serialization/mod.rs @@ -1,17 +1,21 @@ +pub mod map_names; +pub mod traits; +pub(super) use traits::*; + +mod ser_info; +pub use ser_info::*; + mod general; mod serialization_macros; mod certificates; -mod ser_info; -pub use ser_info::*; mod governance; -pub mod map_names; -pub mod traits; -pub(super) use traits::*; mod utils; mod fixed_tx; use utils::*; - mod plutus; mod metadata; mod transaction_body; -mod protocol_param_update; \ No newline at end of file +mod protocol_param_update; +mod tx_inputs; +mod credentials; +mod ed25519_key_hashes; \ No newline at end of file diff --git a/rust/src/serialization/transaction_body.rs b/rust/src/serialization/transaction_body.rs index ef4abecb..56f28672 100644 --- a/rust/src/serialization/transaction_body.rs +++ b/rust/src/serialization/transaction_body.rs @@ -306,7 +306,7 @@ impl Deserialize for TransactionBody { required_signers = Some( (|| -> Result<_, DeserializeError> { read_len.read_elems(1)?; - Ok(RequiredSigners::deserialize(raw)?) + Ok(Ed25519KeyHashesSet::deserialize(raw)?) })() .map_err(|e| e.annotate("required_signers"))?, ); diff --git a/rust/src/serialization/tx_inputs.rs b/rust/src/serialization/tx_inputs.rs new file mode 100644 index 00000000..fd6db58d --- /dev/null +++ b/rust/src/serialization/tx_inputs.rs @@ -0,0 +1,95 @@ +use crate::*; +use crate::serialization::utils::skip_set_tag; + +impl cbor_event::se::Serialize for TransactionInputs { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + //TODO: uncomment this line when we conway ero will come + //serializer.write_tag(258)?; + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for TransactionInputs { + fn deserialize(raw: &mut Deserializer) -> Result { + skip_set_tag(raw)?; + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(TransactionInput::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("TransactionInputs"))?; + Ok(Self(arr)) + } +} + +impl cbor_event::se::Serialize for TransactionInput { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.transaction_id.serialize(serializer)?; + self.index.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for TransactionInput { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let ret = Self::deserialize_as_embedded_group(raw, len); + match len { + cbor_event::Len::Len(_) => + /* TODO: check finite len somewhere */ + { + () + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("TransactionInput")) + } +} + +impl DeserializeEmbeddedGroup for TransactionInput { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + _: cbor_event::Len, + ) -> Result { + let transaction_id = + (|| -> Result<_, DeserializeError> { Ok(TransactionHash::deserialize(raw)?) })() + .map_err(|e| e.annotate("transaction_id"))?; + let index = (|| -> Result<_, DeserializeError> { Ok(u32::deserialize(raw)?) })() + .map_err(|e| e.annotate("index"))?; + Ok(TransactionInput { + transaction_id, + index, + }) + } +} \ No newline at end of file diff --git a/rust/src/serialization/utils.rs b/rust/src/serialization/utils.rs index d58e07a0..3c1f442e 100644 --- a/rust/src/serialization/utils.rs +++ b/rust/src/serialization/utils.rs @@ -87,14 +87,14 @@ pub(crate) fn merge_option_plutus_list(left: Option, right: Optio } } -pub(super) fn skip_tag_wrapper( +pub(super) fn skip_tag( raw: &mut Deserializer, tag: u64, ) -> Result<(), DeserializeError> { if let Ok(extracted_tag) = raw.tag() { if extracted_tag != tag { return Err(DeserializeError::new( - "skip_tag_wrapper", + "skip_tag", DeserializeFailure::TagMismatch { found: extracted_tag, expected: tag, @@ -106,8 +106,8 @@ pub(super) fn skip_tag_wrapper( Ok(()) } -pub(super) fn skip_set_tag_wrapperr( +pub(super) fn skip_set_tag( raw: &mut Deserializer, ) -> Result<(), DeserializeError> { - skip_tag_wrapper(raw, 258) + skip_tag(raw, 258) } diff --git a/rust/src/tests/builders/certificates_builder.rs b/rust/src/tests/builders/certificates_builder.rs index 740f10e2..e196da8f 100644 --- a/rust/src/tests/builders/certificates_builder.rs +++ b/rust/src/tests/builders/certificates_builder.rs @@ -54,7 +54,7 @@ fn certificatess_builder_deposit_test() { let staking_cred = Credential::from_keyhash(&fake_key_hash(10)); let reward_address = RewardAddress::new(NetworkInfo::testnet().network_id(), &staking_cred); - let mut owners = Ed25519KeyHashes::new(); + let mut owners = Ed25519KeyHashesSet::new(); owners.add(&fake_key_hash(11)); owners.add(&fake_key_hash(12)); let relays = Relays::new(); @@ -222,7 +222,7 @@ fn certificatess_builder_no_deposit_test() { let staking_cred = Credential::from_keyhash(&fake_key_hash(10)); let reward_address = RewardAddress::new(NetworkInfo::testnet().network_id(), &staking_cred); - let mut owners = Ed25519KeyHashes::new(); + let mut owners = Ed25519KeyHashesSet::new(); owners.add(&fake_key_hash(11)); owners.add(&fake_key_hash(12)); let relays = Relays::new(); @@ -379,7 +379,7 @@ fn certificatess_builder_req_signers_test() { let staking_cred = Credential::from_keyhash(&key_hash_10); let reward_address = RewardAddress::new(NetworkInfo::testnet().network_id(), &staking_cred); - let mut owners = Ed25519KeyHashes::new(); + let mut owners = Ed25519KeyHashesSet::new(); owners.add(&key_hash_11); owners.add(&key_hash_12); let relays = Relays::new(); diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index c03df3b6..eb83c55a 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -4632,11 +4632,11 @@ fn test_required_signers() { let tx1: TransactionBody = tx_builder.build().unwrap(); assert!(tx1.required_signers.is_some()); - let rs: RequiredSigners = tx1.required_signers.unwrap(); + let rs: Ed25519KeyHashesSet = tx1.required_signers.unwrap(); assert_eq!(rs.len(), 3); - assert_eq!(rs.get(0), s1); - assert_eq!(rs.get(1), s3); - assert_eq!(rs.get(2), s2); + assert!(rs.contains(&s1)); + assert!(rs.contains(&s2)); + assert!(rs.contains(&s3)); } #[test] diff --git a/rust/src/tests/builders/voting_proposal_builder.rs b/rust/src/tests/builders/voting_proposal_builder.rs index e570e82a..4c813354 100644 --- a/rust/src/tests/builders/voting_proposal_builder.rs +++ b/rust/src/tests/builders/voting_proposal_builder.rs @@ -78,7 +78,7 @@ fn voting_proposal_builder_all_proposals() { let mut committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); - let mut members_to_remove = Credentials::new(); + let mut members_to_remove = CredentialsSet::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); let committee_action = UpdateCommitteeAction::new(&committee, &members_to_remove); let wrapped_committee_action = GovernanceAction::new_new_committee_action(&committee_action); @@ -217,7 +217,7 @@ fn voting_proposal_builder_with_plutus_script_witness() { let mut committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); - let mut members_to_remove = Credentials::new(); + let mut members_to_remove = CredentialsSet::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); let committee_action = UpdateCommitteeAction::new(&committee, &members_to_remove); let wrapped_committee_action = GovernanceAction::new_new_committee_action(&committee_action); @@ -325,7 +325,7 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { let mut committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); - let mut members_to_remove = Credentials::new(); + let mut members_to_remove = CredentialsSet::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); let committee_action = UpdateCommitteeAction::new(&committee, &members_to_remove); let wrapped_committee_action= GovernanceAction::new_new_committee_action(&committee_action); diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index 1a518548..ed9aac95 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -209,22 +209,22 @@ fn native_scripts_get_pubkeys() { let keyhash2 = keyhash(2); let keyhash3 = keyhash(3); - let pks1 = RequiredSignersSet::from(&pkscript(&keyhash1)); + let pks1 = Ed25519KeyHashesSet::from(&pkscript(&keyhash1)); assert_eq!(pks1.len(), 1); assert!(pks1.contains(&keyhash1)); let pks2 = - RequiredSignersSet::from(&NativeScript::new_timelock_start(&TimelockStart::new(123))); + Ed25519KeyHashesSet::from(&NativeScript::new_timelock_start(&TimelockStart::new(123))); assert_eq!(pks2.len(), 0); - let pks3 = RequiredSignersSet::from(&NativeScript::new_script_all(&ScriptAll::new( + let pks3 = Ed25519KeyHashesSet::from(&NativeScript::new_script_all(&ScriptAll::new( &scripts_vec(vec![&pkscript(&keyhash1), &pkscript(&keyhash2)]), ))); assert_eq!(pks3.len(), 2); assert!(pks3.contains(&keyhash1)); assert!(pks3.contains(&keyhash2)); - let pks4 = RequiredSignersSet::from(&NativeScript::new_script_any(&ScriptAny::new( + let pks4 = Ed25519KeyHashesSet::from(&NativeScript::new_script_any(&ScriptAny::new( &scripts_vec(vec![ &NativeScript::new_script_n_of_k(&ScriptNOfK::new( 1, diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/mock_objects.rs index 1dbbf373..4182e9e9 100644 --- a/rust/src/tests/mock_objects.rs +++ b/rust/src/tests/mock_objects.rs @@ -128,7 +128,7 @@ pub(crate) fn crate_full_pool_params() -> PoolParams { cost: Coin::from(44_444u32), margin: UnitInterval::new(&BigNum::from(44_444u32), &BigNum::from(44_444u32)), reward_account: RewardAddress::new(2, &Credential::from_keyhash(&fake_key_hash(3))), - pool_owners: Ed25519KeyHashes(vec![fake_key_hash(4), fake_key_hash(5)]), + pool_owners: Ed25519KeyHashesSet(vec![fake_key_hash(4), fake_key_hash(5)].into_iter().collect()), relays: Relays(vec![Relay::new_multi_host_name(&MultiHostName::new( &DNSRecordSRV::new("iohk.io".to_string()).unwrap(), ))]), diff --git a/rust/src/tests/protocol_types/governance/proposals.rs b/rust/src/tests/protocol_types/governance/proposals.rs index 0cf6a8ef..db24880a 100644 --- a/rust/src/tests/protocol_types/governance/proposals.rs +++ b/rust/src/tests/protocol_types/governance/proposals.rs @@ -21,8 +21,8 @@ fn committee_setters_getters_test() { let keys = committee.members_keys(); assert_eq!(committee.quorum_threshold(), threshold); assert_eq!(keys.len(), 2); - assert!(keys.0.iter().contains(&cred_1)); - assert!(keys.0.iter().contains(&cred_2)); + assert!(keys.contains(&cred_1)); + assert!(keys.contains(&cred_2)); assert_eq!(committee.get_member_epoch(&cred_1), Some(epoch_1)); assert_eq!(committee.get_member_epoch(&cred_2), Some(epoch_2)); assert_eq!(committee.get_member_epoch(&cred_3), None); @@ -58,13 +58,12 @@ fn hard_fork_initiation_action_setters_getters_test() { fn new_committee_action_setters_getters_test() { let action_id = create_action_id(); let committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); - let members_to_remove = Credentials( + let members_to_remove = CredentialsSet::from_iter( vec![ Credential::from_keyhash(&fake_key_hash(1)), Credential::from_keyhash(&fake_key_hash(2)), ] .into_iter() - .collect(), ); let proposal = UpdateCommitteeAction::new(&committee, &members_to_remove); diff --git a/rust/src/tests/serialization/certificates.rs b/rust/src/tests/serialization/certificates.rs index 1fd065f1..f7f3b952 100644 --- a/rust/src/tests/serialization/certificates.rs +++ b/rust/src/tests/serialization/certificates.rs @@ -194,7 +194,7 @@ fn move_instantaneous_reward_to_stake_creds_ser_round_trip() { fn pool_registration_ser_round_trip() { let staking_cred = Credential::from_keyhash(&fake_key_hash(1)); let reward_address = RewardAddress::new(NetworkInfo::testnet().network_id(), &staking_cred); - let mut owners = Ed25519KeyHashes::new(); + let mut owners = Ed25519KeyHashesSet::new(); owners.add(&fake_key_hash(2)); owners.add(&fake_key_hash(3)); let mut relays = Relays::new(); diff --git a/rust/src/tests/serialization/governance/proposals.rs b/rust/src/tests/serialization/governance/proposals.rs index 724902e4..fd6c8e4b 100644 --- a/rust/src/tests/serialization/governance/proposals.rs +++ b/rust/src/tests/serialization/governance/proposals.rs @@ -136,7 +136,7 @@ fn new_committee_action_ser_round_trip() { committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); committee.add_member(&Credential::from_scripthash(&fake_script_hash(2)), 2); - let mut members_to_remove = Credentials::new(); + let mut members_to_remove = CredentialsSet::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); members_to_remove.add(&Credential::from_scripthash(&fake_script_hash(2))); @@ -159,7 +159,7 @@ fn new_committee_action_with_action_id_ser_round_trip() { committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); committee.add_member(&Credential::from_scripthash(&fake_script_hash(2)), 2); - let mut members_to_remove = Credentials::new(); + let mut members_to_remove = CredentialsSet::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); members_to_remove.add(&Credential::from_scripthash(&fake_script_hash(2))); @@ -178,7 +178,7 @@ fn new_committee_action_with_action_id_ser_round_trip() { #[test] fn new_committee_action_with_empty_ser_round_trip() { let committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); - let members_to_remove = Credentials::new(); + let members_to_remove = CredentialsSet::new(); let proposal = UpdateCommitteeAction::new(&committee, &members_to_remove); let proposal_wrapped = GovernanceAction::new_new_committee_action(&proposal); diff --git a/rust/src/tests/serialization/transaction_body.rs b/rust/src/tests/serialization/transaction_body.rs index b4c9fc0f..2e3585c4 100644 --- a/rust/src/tests/serialization/transaction_body.rs +++ b/rust/src/tests/serialization/transaction_body.rs @@ -16,7 +16,7 @@ fn transaction_round_trip_test() { .unwrap(); mint.insert(&fake_policy_id(3), &mint_asset); - let mut req_signers = RequiredSigners::new(); + let mut req_signers = Ed25519KeyHashesSet::new(); req_signers.add(&fake_key_hash(5)); let mut collateral_inputs = TransactionInputs::new(); From 2ff944976ca29d530089868659e3eeb43321ad9b Mon Sep 17 00:00:00 2001 From: TW Date: Mon, 25 Dec 2023 21:57:49 +0800 Subject: [PATCH 207/349] add remove apis for option variables in tx builder --- rust/src/tx_builder.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/rust/src/tx_builder.rs b/rust/src/tx_builder.rs index 5a831ecb..96e43d60 100644 --- a/rust/src/tx_builder.rs +++ b/rust/src/tx_builder.rs @@ -734,6 +734,10 @@ impl TransactionBuilder { self.collateral_return = Some(collateral_return.clone()); } + pub fn remove_collateral_return(&mut self) { + self.collateral_return = None; + } + /// This function will set the collateral-return value and then auto-calculate and assign /// the total collateral coin value. Will raise an error in case no collateral inputs are set /// or in case the total collateral value will have any assets in it except coin. @@ -774,6 +778,10 @@ impl TransactionBuilder { self.total_collateral = Some(total_collateral.clone()); } + pub fn remove_total_collateral(&mut self) { + self.total_collateral = None; + } + /// This function will set the total-collateral coin and then auto-calculate and assign /// the collateral return value. Will raise an error in case no collateral inputs are set. /// The specified address will be the received of the collateral return @@ -997,6 +1005,10 @@ impl TransactionBuilder { self.ttl = Some(ttl.clone()) } + pub fn remove_ttl(&mut self) { + self.ttl = None; + } + /// !!! DEPRECATED !!! /// Uses outdated slot number format. #[deprecated( @@ -1011,6 +1023,10 @@ impl TransactionBuilder { self.validity_start_interval = Some(validity_start_interval.clone()) } + pub fn remove_validity_start_interval(&mut self) { + self.validity_start_interval = None; + } + pub fn set_certs(&mut self, certs: &Certificates) { self.certs = Some(certs.clone()); for cert in &certs.0 { @@ -1019,6 +1035,10 @@ impl TransactionBuilder { } } + pub fn remove_certs(&mut self) { + self.certs = None; + } + pub fn set_withdrawals(&mut self, withdrawals: &Withdrawals) { self.withdrawals = Some(withdrawals.clone()); for (withdrawal, _coin) in &withdrawals.0 { @@ -1027,6 +1047,10 @@ impl TransactionBuilder { } } + pub fn remove_withdrawals(&mut self) { + self.withdrawals = None; + } + pub fn get_auxiliary_data(&self) -> Option { self.auxiliary_data.clone() } @@ -1037,6 +1061,10 @@ impl TransactionBuilder { self.auxiliary_data = Some(auxiliary_data.clone()) } + pub fn remove_auxiliary_data(&mut self) { + self.auxiliary_data = None; + } + /// Set metadata using a GeneralTransactionMetadata object /// It will be set to the existing or new auxiliary data in this builder pub fn set_metadata(&mut self, metadata: &GeneralTransactionMetadata) { @@ -1089,6 +1117,10 @@ impl TransactionBuilder { self.mint = Some(mint_builder.clone()); } + pub fn remove_mint_builder(&mut self) { + self.mint = None; + } + pub fn get_mint_builder(&self) -> Option { self.mint.clone() } From 3366f0fd53ee9ed06e08419ab62b24c97c6806ca Mon Sep 17 00:00:00 2001 From: TW Date: Mon, 1 Jan 2024 23:10:59 +0800 Subject: [PATCH 208/349] implement change function with collateral return --- rust/src/tx_builder.rs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/rust/src/tx_builder.rs b/rust/src/tx_builder.rs index 96e43d60..9364c6ce 100644 --- a/rust/src/tx_builder.rs +++ b/rust/src/tx_builder.rs @@ -1828,6 +1828,42 @@ impl TransactionBuilder { } } + pub fn add_inputs_from_and_change_with_collateral_return( + &mut self, + inputs: &TransactionUnspentOutputs, + strategy: CoinSelectionStrategyCIP2, + change_config: &ChangeConfig, + collateral_percentage: u64 + ) -> Result { + let mut total_collateral = Value::zero(); + for collateral_input in self.collateral.iter() { + total_collateral = total_collateral.checked_add(&collateral_input.amount)?; + } + self.set_total_collateral_and_return(&total_collateral.coin(), &change_config.address)?; + let add_change_result = self.add_inputs_from_and_change(inputs, strategy, change_config); + match add_change_result { + Ok(_) => { + let fee = self.get_fee_if_set().unwrap(); + let collateral_required = (from_bignum(&fee) * collateral_percentage) / 100; + let set_collateral_result = self.set_total_collateral_and_return(&to_bignum(collateral_required), &change_config.address); + match set_collateral_result { + Ok(_) => { + Ok(true) + } + Err(_) => { + self.remove_collateral_return(); + self.remove_total_collateral(); + Ok(true) + } + } + } + Err(e) => { + Err(e) + } + }?; + Ok(true) + } + /// This method will calculate the script hash data /// using the plutus datums and redeemers already present in the builder /// along with the provided cost model, and will register the calculated value From 6d25074c2e72a20479473a18ea58648d1f84e369 Mon Sep 17 00:00:00 2001 From: TW Date: Mon, 8 Jan 2024 21:21:13 +0800 Subject: [PATCH 209/349] add comment for utxo select and collateral return method --- rust/src/tx_builder.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rust/src/tx_builder.rs b/rust/src/tx_builder.rs index 9364c6ce..accf10a4 100644 --- a/rust/src/tx_builder.rs +++ b/rust/src/tx_builder.rs @@ -1828,6 +1828,9 @@ impl TransactionBuilder { } } + // This method should be used after outputs of the transaction is defined. + // It will attempt to fill the required values using the inputs given. + // After which, it will attempt to set a collateral return output. pub fn add_inputs_from_and_change_with_collateral_return( &mut self, inputs: &TransactionUnspentOutputs, @@ -1844,7 +1847,7 @@ impl TransactionBuilder { match add_change_result { Ok(_) => { let fee = self.get_fee_if_set().unwrap(); - let collateral_required = (from_bignum(&fee) * collateral_percentage) / 100; + let collateral_required = ((from_bignum(&fee) * collateral_percentage) / 100) + 1; let set_collateral_result = self.set_total_collateral_and_return(&to_bignum(collateral_required), &change_config.address); match set_collateral_result { Ok(_) => { From 258e092af0e43ac2d2255ddf3810c351bcdef366 Mon Sep 17 00:00:00 2001 From: TW Date: Mon, 8 Jan 2024 21:28:09 +0800 Subject: [PATCH 210/349] improve utxo selection and change test --- rust/src/tx_builder.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rust/src/tx_builder.rs b/rust/src/tx_builder.rs index accf10a4..270e87e8 100644 --- a/rust/src/tx_builder.rs +++ b/rust/src/tx_builder.rs @@ -8300,5 +8300,7 @@ mod tests { } let change_config = ChangeConfig::new(&Address::from_bech32("addr_test1qqzf7fhgm0gf370ngxgpskg5c3kgp2g0u4ltxlrmsvumaztv3ck06k550q64lgwkqavljd63yda0x2va074fguprujfs43mc83").unwrap()); assert!(&tx_builder.add_inputs_from_and_change(&utxos, CoinSelectionStrategyCIP2::LargestFirstMultiAsset, &change_config).is_ok()); + let build_res = tx_builder.build_tx(); + assert!(&build_res.is_ok()); } } From 5c343245a3cc0e23018228a8ae00d90ecfef0194 Mon Sep 17 00:00:00 2001 From: TW Date: Tue, 9 Jan 2024 17:09:10 +0800 Subject: [PATCH 211/349] add test for utxo selection with collat return --- rust/src/tx_builder.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/rust/src/tx_builder.rs b/rust/src/tx_builder.rs index 270e87e8..05123fa0 100644 --- a/rust/src/tx_builder.rs +++ b/rust/src/tx_builder.rs @@ -8303,4 +8303,29 @@ mod tests { let build_res = tx_builder.build_tx(); assert!(&build_res.is_ok()); } + + #[test] + fn utxo_selection_with_collateral_return_test() { + let mut tx_builder = create_reallistic_tx_builder(); + let hex_utxos = [ + "82825820731224c9d2bc3528578009fec9f9e34a67110aca2bd4dde0f050845a2daf660d0082583900436075347d6a452eba4289ae345a8eb15e73eb80979a7e817d988fc56c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e493821a001deabfa1581c9a5e0d55cdf4ce4e19c8acbff7b4dafc890af67a594a4c46d7dd1c0fa14001", + "82825820a04996d5ef87fdece0c74625f02ee5c1497a06e0e476c5095a6b0626b295074a00825839001772f234940519e71318bb9c5c8ad6eacfe8fd91a509050624e3855e6c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e4931a0016e360" + ]; + let output = TransactionOutput::new(&Address::from_bech32("addr_test1qppkqaf5044y2t46g2y6udz636c4uultszte5l5p0kvgl3tv3ck06k550q64lgwkqavljd63yda0x2va074fguprujfsjre4xh").unwrap(), &Value::new(&BigNum::from_str("969750").unwrap())); + tx_builder.add_output(&output); + let mut utxos = TransactionUnspentOutputs::new(); + for hex_utxo in hex_utxos { + utxos.add(&TransactionUnspentOutput::from_hex(hex_utxo).unwrap()); + } + let mut collateral_builder = TxInputsBuilder::new(); + let collateral_input = TransactionUnspentOutput::from_hex(hex_utxos[1]).unwrap(); + collateral_builder.add_input(&collateral_input.output.address, &collateral_input.input, &collateral_input.output.amount); + tx_builder.set_collateral(&collateral_builder); + + let change_config = ChangeConfig::new(&Address::from_bech32("addr_test1qqzf7fhgm0gf370ngxgpskg5c3kgp2g0u4ltxlrmsvumaztv3ck06k550q64lgwkqavljd63yda0x2va074fguprujfs43mc83").unwrap()); + assert!(&tx_builder.add_inputs_from_and_change_with_collateral_return(&utxos, CoinSelectionStrategyCIP2::LargestFirstMultiAsset, &change_config, 150).is_ok()); + let build_res = tx_builder.build_tx(); + assert!(&build_res.is_ok()); + assert!(&build_res.clone().unwrap().body.collateral_return().is_some()); + } } From 71dba6da806ca667b8e5a66eeea3a2c8fb77cc0b Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 29 Jan 2024 16:42:07 +0800 Subject: [PATCH 212/349] flow update --- rust/pkg/cardano_serialization_lib.js.flow | 311 ++++++++++++++++----- 1 file changed, 234 insertions(+), 77 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 3e1ef470..059c89a3 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -44,30 +44,6 @@ declare export function min_script_fee( ex_unit_prices: ExUnitPrices ): BigNum; -/** - * @param {string} password - * @param {string} salt - * @param {string} nonce - * @param {string} data - * @returns {string} - */ -declare export function encrypt_with_password( - password: string, - salt: string, - nonce: string, - data: string -): string; - -/** - * @param {string} password - * @param {string} data - * @returns {string} - */ -declare export function decrypt_with_password( - password: string, - data: string -): string; - /** * @param {TransactionHash} tx_body_hash * @param {ByronAddress} addr @@ -191,6 +167,30 @@ declare export function encode_json_str_to_native_script( schema: number ): NativeScript; +/** + * @param {string} password + * @param {string} salt + * @param {string} nonce + * @param {string} data + * @returns {string} + */ +declare export function encrypt_with_password( + password: string, + salt: string, + nonce: string, + data: string +): string; + +/** + * @param {string} password + * @param {string} data + * @returns {string} + */ +declare export function decrypt_with_password( + password: string, + data: string +): string; + /** * @param {string} json * @param {number} schema @@ -271,9 +271,11 @@ declare export var VoterKind: {| /** */ -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 |}; /** @@ -285,22 +287,20 @@ declare export var CredKind: {| |}; /** + * Used to choosed the schema for a script JSON string */ -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** - * Used to choosed the schema for a script JSON string */ -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 |}; /** @@ -443,37 +443,37 @@ declare export var PlutusDatumSchema: {| /** */ -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 |}; /** */ -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 |}; /** */ -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 |}; /** */ -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 |}; /** @@ -2178,9 +2178,9 @@ declare export class Committee { static new(quorum_threshold: UnitInterval): Committee; /** - * @returns {Credentials} + * @returns {CredentialsSet} */ - members_keys(): Credentials; + members_keys(): CredentialsSet; /** * @returns {UnitInterval} @@ -2740,6 +2740,81 @@ declare export class Credentials { */ add(elem: Credential): void; } +/** + */ +declare export class CredentialsSet { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {CredentialsSet} + */ + static from_bytes(bytes: Uint8Array): CredentialsSet; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {CredentialsSet} + */ + static from_hex(hex_str: string): CredentialsSet; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {CredentialsSetJSON} + */ + to_js_value(): CredentialsSetJSON; + + /** + * @param {string} json + * @returns {CredentialsSet} + */ + static from_json(json: string): CredentialsSet; + + /** + * @returns {CredentialsSet} + */ + static new(): CredentialsSet; + + /** + * @returns {number} + */ + len(): number; + + /** + * @param {number} index + * @returns {Credential | void} + */ + get(index: number): Credential | void; + + /** + * @param {Credential} elem + */ + add(elem: Credential): void; + + /** + * @param {Credential} elem + * @returns {boolean} + */ + contains(elem: Credential): boolean; + + /** + * @returns {Credentials} + */ + to_vec(): Credentials; +} /** */ declare export class DNSRecordAorAAAA { @@ -3498,6 +3573,86 @@ declare export class Ed25519KeyHashes { */ to_option(): Ed25519KeyHashes | void; } +/** + */ +declare export class Ed25519KeyHashesSet { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {Ed25519KeyHashesSet} + */ + static from_bytes(bytes: Uint8Array): Ed25519KeyHashesSet; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {Ed25519KeyHashesSet} + */ + static from_hex(hex_str: string): Ed25519KeyHashesSet; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {Ed25519KeyHashesSetJSON} + */ + to_js_value(): Ed25519KeyHashesSetJSON; + + /** + * @param {string} json + * @returns {Ed25519KeyHashesSet} + */ + static from_json(json: string): Ed25519KeyHashesSet; + + /** + * @returns {Ed25519KeyHashesSet} + */ + static new(): Ed25519KeyHashesSet; + + /** + * @param {Ed25519KeyHash} key + */ + add(key: Ed25519KeyHash): void; + + /** + * @param {Ed25519KeyHash} key + */ + remove(key: Ed25519KeyHash): void; + + /** + * @param {Ed25519KeyHash} key + * @returns {boolean} + */ + contains(key: Ed25519KeyHash): boolean; + + /** + * @returns {number} + */ + len(): number; + + /** + * @param {number} index + * @returns {Ed25519KeyHash | void} + */ + get(index: number): Ed25519KeyHash | void; + + /** + * @returns {Ed25519KeyHashes} + */ + to_vec(): Ed25519KeyHashes; +} /** */ declare export class Ed25519Signature { @@ -5130,9 +5285,9 @@ declare export class MIRToStakeCredentials { get(cred: Credential): Int | void; /** - * @returns {Credentials} + * @returns {CredentialsSet} */ - keys(): Credentials; + keys(): CredentialsSet; } /** */ @@ -5909,12 +6064,12 @@ declare export class NativeScript { as_timelock_expiry(): TimelockExpiry | void; /** - * Returns an array of unique Ed25519KeyHashes + * Returns a set of Ed25519KeyHashes * contained within this script recursively on any depth level. * The order of the keys in the result is not determined in any way. - * @returns {Ed25519KeyHashes} + * @returns {Ed25519KeyHashesSet} */ - get_required_signers(): Ed25519KeyHashes; + get_required_signers(): Ed25519KeyHashesSet; } /** */ @@ -7220,9 +7375,9 @@ declare export class PoolParams { reward_account(): RewardAddress; /** - * @returns {Ed25519KeyHashes} + * @returns {Ed25519KeyHashesSet} */ - pool_owners(): Ed25519KeyHashes; + pool_owners(): Ed25519KeyHashesSet; /** * @returns {Relays} @@ -7241,7 +7396,7 @@ declare export class PoolParams { * @param {BigNum} cost * @param {UnitInterval} margin * @param {RewardAddress} reward_account - * @param {Ed25519KeyHashes} pool_owners + * @param {Ed25519KeyHashesSet} pool_owners * @param {Relays} relays * @param {PoolMetadata | void} pool_metadata * @returns {PoolParams} @@ -7253,7 +7408,7 @@ declare export class PoolParams { cost: BigNum, margin: UnitInterval, reward_account: RewardAddress, - pool_owners: Ed25519KeyHashes, + pool_owners: Ed25519KeyHashesSet, relays: Relays, pool_metadata?: PoolMetadata ): PoolParams; @@ -10110,14 +10265,14 @@ declare export class TransactionBody { collateral(): TransactionInputs | void; /** - * @param {Ed25519KeyHashes} required_signers + * @param {Ed25519KeyHashesSet} required_signers */ - set_required_signers(required_signers: Ed25519KeyHashes): void; + set_required_signers(required_signers: Ed25519KeyHashesSet): void; /** - * @returns {Ed25519KeyHashes | void} + * @returns {Ed25519KeyHashesSet | void} */ - required_signers(): Ed25519KeyHashes | void; + required_signers(): Ed25519KeyHashesSet | void; /** * @param {NetworkId} network_id @@ -12164,30 +12319,30 @@ declare export class UpdateCommitteeAction { committee(): Committee; /** - * @returns {Credentials} + * @returns {CredentialsSet} */ - members_to_remove(): Credentials; + members_to_remove(): CredentialsSet; /** * @param {Committee} committee - * @param {Credentials} members_to_remove + * @param {CredentialsSet} members_to_remove * @returns {UpdateCommitteeAction} */ static new( committee: Committee, - members_to_remove: Credentials + members_to_remove: CredentialsSet ): UpdateCommitteeAction; /** * @param {GovernanceActionId} gov_action_id * @param {Committee} committee - * @param {Credentials} members_to_remove + * @param {CredentialsSet} members_to_remove * @returns {UpdateCommitteeAction} */ static new_with_action_id( gov_action_id: GovernanceActionId, committee: Committee, - members_to_remove: Credentials + members_to_remove: CredentialsSet ): UpdateCommitteeAction; } /** @@ -13628,7 +13783,7 @@ export type CredTypeJSON = Script: string, ... }; -export type Ed25519KeyHashesJSON = string[]; +export type Ed25519KeyHashesSetJSON = string[]; export type RelayJSON = | { SingleHostAddr: SingleHostAddrJSON, @@ -13759,6 +13914,7 @@ export type GovernanceActionJSON = InfoAction: InfoActionJSON, ... }; +export type CredentialsSetJSON = CredTypeJSON[]; /** * @minItems 0 * @maxItems 0 @@ -13829,7 +13985,7 @@ export interface TransactionBodyJSON { network_id?: NetworkIdJSON | null; outputs: TransactionOutputsJSON; reference_inputs?: TransactionInputsJSON | null; - required_signers?: Ed25519KeyHashesJSON | null; + required_signers?: Ed25519KeyHashesSetJSON | null; script_data_hash?: string | null; total_collateral?: string | null; ttl?: string | null; @@ -13862,7 +14018,7 @@ export interface PoolParamsJSON { operator: string; pledge: string; pool_metadata?: PoolMetadataJSON | null; - pool_owners: Ed25519KeyHashesJSON; + pool_owners: Ed25519KeyHashesSetJSON; relays: RelaysJSON; reward_account: string; vrf_keyhash: string; @@ -14126,7 +14282,7 @@ export interface NoConfidenceActionJSON { export interface UpdateCommitteeActionJSON { committee: CommitteeJSON; gov_action_id?: GovernanceActionIdJSON | null; - members_to_remove: CredTypeJSON[]; + members_to_remove: CredentialsSetJSON; } export interface CommitteeJSON { members: CommitteeMemberJSON[]; @@ -14256,6 +14412,7 @@ export type DRepEnumJSON = }; export type DataHashJSON = string; export type Ed25519KeyHashJSON = string; +export type Ed25519KeyHashesJSON = string[]; export type Ed25519SignatureJSON = string; export interface GeneralTransactionMetadataJSON { [k: string]: string; From 45413f1723a0674d2d85ee6a5699074de5aab131 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 29 Jan 2024 16:42:59 +0800 Subject: [PATCH 213/349] package-lock update --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4acf6327..86e4b951 100644 --- a/package-lock.json +++ b/package-lock.json @@ -837,7 +837,7 @@ "rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", "dev": true, "requires": { "resolve": "^1.1.6" @@ -956,7 +956,7 @@ "typescript-compiler": { "version": "1.4.1-2", "resolved": "https://registry.npmjs.org/typescript-compiler/-/typescript-compiler-1.4.1-2.tgz", - "integrity": "sha1-uk99si2RU0oZKdkACdzhYety/T8=", + "integrity": "sha512-EMopKmoAEJqA4XXRFGOb7eSBhmQMbBahW6P1Koayeatp0b4AW2q/bBqYWkpG7QVQc9HGQUiS4trx2ZHcnAaZUg==", "dev": true }, "which-pm-runs": { From e835403ef1b6714cf8ddbdb407fa66478907335f Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 1 Feb 2024 16:45:25 +0800 Subject: [PATCH 214/349] bump wasm bingen version, add explicit enum args in .flow file --- rust/Cargo.toml | 2 +- rust/pkg/cardano_serialization_lib.js.flow | 648 ++++++++++++--------- 2 files changed, 360 insertions(+), 290 deletions(-) diff --git a/rust/Cargo.toml b/rust/Cargo.toml index f47e67f6..626b51e9 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -48,7 +48,7 @@ getrandom = "0.2.3" # wasm [target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies] serde-wasm-bindgen = "0.4.5" -wasm-bindgen = "=0.2.87" +wasm-bindgen = "=0.2.90" rand_os = { version = "0.1", features = ["wasm-bindgen"] } js-sys = "0.3.51" getrandom = { version = "0.2.3", features = ["js"] } diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 059c89a3..74d16a8f 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -5,6 +5,70 @@ * @flow */ +/** + * @param {string} json + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {PlutusData} + */ +declare export function encode_json_str_to_plutus_datum( + json: string, + schema: $Values +): PlutusData; + +/** + * @param {PlutusData} datum + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {string} + */ +declare export function decode_plutus_datum_to_json_str( + datum: PlutusData, + schema: $Values +): string; + +/** + * @param {Uint8Array} bytes + * @returns {TransactionMetadatum} + */ +declare export function encode_arbitrary_bytes_as_metadatum( + bytes: Uint8Array +): TransactionMetadatum; + +/** + * @param {TransactionMetadatum} metadata + * @returns {Uint8Array} + */ +declare export function decode_arbitrary_bytes_from_metadatum( + metadata: TransactionMetadatum +): Uint8Array; + +/** + * @param {string} json + * @param {$Values< + typeof + MetadataJsonSchema>} schema + * @returns {TransactionMetadatum} + */ +declare export function encode_json_str_to_metadatum( + json: string, + schema: $Values +): TransactionMetadatum; + +/** + * @param {TransactionMetadatum} metadatum + * @param {$Values< + typeof + MetadataJsonSchema>} schema + * @returns {string} + */ +declare export function decode_metadatum_to_json_str( + metadatum: TransactionMetadatum, + schema: $Values +): string; + /** * @param {Address} address * @param {TransactionUnspentOutputs} utxos @@ -17,6 +81,30 @@ declare export function create_send_all( config: TransactionBuilderConfig ): TransactionBatchList; +/** + * @param {string} password + * @param {string} salt + * @param {string} nonce + * @param {string} data + * @returns {string} + */ +declare export function encrypt_with_password( + password: string, + salt: string, + nonce: string, + data: string +): string; + +/** + * @param {string} password + * @param {string} data + * @returns {string} + */ +declare export function decrypt_with_password( + password: string, + data: string +): string; + /** * @param {Transaction} tx * @param {LinearFee} linear_fee @@ -103,7 +191,7 @@ declare export function hash_plutus_data(plutus_data: PlutusData): DataHash; /** * @param {Redeemers} redeemers * @param {Costmdls} cost_models - * @param {PlutusList | void} datums + * @param {PlutusList | void} [datums] * @returns {ScriptDataHash} */ declare export function hash_script_data( @@ -151,156 +239,140 @@ declare export function min_ada_for_output( * Receives a script JSON string * and returns a NativeScript. * Cardano Wallet and Node styles are supported. - * + * * * wallet: https://github.com/input-output-hk/cardano-wallet/blob/master/specifications/api/swagger.yaml * * node: https://github.com/input-output-hk/cardano-node/blob/master/doc/reference/simple-scripts.md - * + * * self_xpub is expected to be a Bip32PublicKey as hex-encoded bytes * @param {string} json * @param {string} self_xpub - * @param {number} schema + * @param {$Values< + typeof + ScriptSchema>} schema * @returns {NativeScript} */ declare export function encode_json_str_to_native_script( json: string, self_xpub: string, - schema: number + schema: $Values ): NativeScript; /** - * @param {string} password - * @param {string} salt - * @param {string} nonce - * @param {string} data - * @returns {string} */ -declare export function encrypt_with_password( - password: string, - salt: string, - nonce: string, - data: string -): string; -/** - * @param {string} password - * @param {string} data - * @returns {string} - */ -declare export function decrypt_with_password( - password: string, - data: string -): string; +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 +|}; /** - * @param {string} json - * @param {number} schema - * @returns {PlutusData} */ -declare export function encode_json_str_to_plutus_datum( - json: string, - schema: number -): PlutusData; -/** - * @param {PlutusData} datum - * @param {number} schema - * @returns {string} - */ -declare export function decode_plutus_datum_to_json_str( - datum: PlutusData, - schema: number -): string; +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 +|}; /** - * @param {Uint8Array} bytes - * @returns {TransactionMetadatum} */ -declare export function encode_arbitrary_bytes_as_metadatum( - bytes: Uint8Array -): TransactionMetadatum; -/** - * @param {TransactionMetadatum} metadata - * @returns {Uint8Array} - */ -declare export function decode_arbitrary_bytes_from_metadatum( - metadata: TransactionMetadatum -): Uint8Array; +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 +|}; /** - * @param {string} json - * @param {number} schema - * @returns {TransactionMetadatum} */ -declare export function encode_json_str_to_metadatum( - json: string, - schema: number -): TransactionMetadatum; + +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 +|}; /** - * @param {TransactionMetadatum} metadatum - * @param {number} schema - * @returns {string} + * JSON <-> PlutusData conversion schemas. + * Follows ScriptDataJsonSchema in cardano-cli defined at: + * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 + * + * All methods here have the following restrictions due to limitations on dependencies: + * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors + * * Hex strings for bytes don't accept odd-length (half-byte) strings. + * cardano-cli seems to support these however but it seems to be different than just 0-padding + * on either side when tested so proceed with caution */ -declare export function decode_metadatum_to_json_str( - metadatum: TransactionMetadatum, - schema: number -): string; + +declare export var PlutusDatumSchema: {| + +BasicConversions: 0, // 0 + +DetailedSchema: 1, // 1 +|}; /** */ -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 |}; /** */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 +declare export var RedeemerTagKind: {| + +Spend: 0, // 0 + +Mint: 1, // 1 + +Cert: 2, // 2 + +Reward: 3, // 3 + +Vote: 4, // 4 + +VotingProposal: 5, // 5 |}; /** + * Each new language uses a different namespace for hashing its script + * This is because you could have a language where the same bytes have different semantics + * So this avoids scripts in different languages mapping to the same hash + * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 +declare export var ScriptHashNamespace: {| + +NativeScript: 0, // 0 + +PlutusScript: 1, // 1 + +PlutusScriptV2: 2, // 2 + +PlutusScriptV3: 3, // 3 |}; /** */ -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 |}; /** - * Used to choosed the schema for a script JSON string */ -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 |}; /** */ -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 |}; /** @@ -315,44 +387,47 @@ declare export var RelayKind: {| /** */ -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 |}; /** - * Each new language uses a different namespace for hashing its script - * This is because you could have a language where the same bytes have different semantics - * So this avoids scripts in different languages mapping to the same hash - * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var ScriptHashNamespace: {| - +NativeScript: 0, // 0 - +PlutusScript: 1, // 1 - +PlutusScriptV2: 2, // 2 - +PlutusScriptV3: 3, // 3 +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 |}; /** */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** */ -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 +|}; + +/** + * Used to choosed the schema for a script JSON string + */ + +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** @@ -391,55 +466,6 @@ declare export var GovernanceActionKind: {| +InfoAction: 6, // 6 |}; -/** - */ - -declare export var LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 -|}; - -/** - */ - -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 - +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 -|}; - -/** - */ - -declare export var RedeemerTagKind: {| - +Spend: 0, // 0 - +Mint: 1, // 1 - +Cert: 2, // 2 - +Reward: 3, // 3 - +Vote: 4, // 4 - +VotingProposal: 5, // 5 -|}; - -/** - * JSON <-> PlutusData conversion schemas. - * Follows ScriptDataJsonSchema in cardano-cli defined at: - * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 - * - * All methods here have the following restrictions due to limitations on dependencies: - * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors - * * Hex strings for bytes don't accept odd-length (half-byte) strings. - * cardano-cli seems to support these however but it seems to be different than just 0-padding - * on either side when tested so proceed with caution - */ - -declare export var PlutusDatumSchema: {| - +BasicConversions: 0, // 0 - +DetailedSchema: 1, // 1 -|}; - /** */ @@ -451,29 +477,13 @@ declare export var MIRPot: {| /** */ -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 -|}; - -/** - */ - -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 -|}; - -/** - */ - -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 |}; /** @@ -520,7 +530,7 @@ declare export class Address { to_bytes(): Uint8Array; /** - * @param {string | void} prefix + * @param {string | void} [prefix] * @returns {string} */ to_bech32(prefix?: string): string; @@ -1901,9 +1911,11 @@ declare export class Certificate { ): Certificate; /** - * @returns {number} - */ - kind(): number; + * @returns {$Values< + typeof + CertificateKind>} + */ + kind(): $Values; /** * @returns {StakeRegistration | void} @@ -2629,9 +2641,11 @@ declare export class Credential { to_scripthash(): ScriptHash | void; /** - * @returns {number} - */ - kind(): number; + * @returns {$Values< + typeof + CredKind>} + */ + kind(): $Values; /** * @returns {boolean} @@ -2989,9 +3003,11 @@ declare export class DRep { static new_always_no_confidence(): DRep; /** - * @returns {number} - */ - kind(): number; + * @returns {$Values< + typeof + DRepKind>} + */ + kind(): $Values; /** * @returns {Ed25519KeyHash | void} @@ -4328,9 +4344,11 @@ declare export class GovernanceAction { static new_info_action(info_action: InfoAction): GovernanceAction; /** - * @returns {number} - */ - kind(): number; + * @returns {$Values< + typeof + GovernanceActionKind>} + */ + kind(): $Values; /** * @returns {ParameterChangeAction | void} @@ -5140,9 +5158,11 @@ declare export class Language { static new_plutus_v3(): Language; /** - * @returns {number} - */ - kind(): number; + * @returns {$Values< + typeof + LanguageKind>} + */ + kind(): $Values; } /** */ @@ -5692,31 +5712,42 @@ declare export class MoveInstantaneousReward { static from_json(json: string): MoveInstantaneousReward; /** - * @param {number} pot - * @param {BigNum} amount - * @returns {MoveInstantaneousReward} - */ - static new_to_other_pot(pot: number, amount: BigNum): MoveInstantaneousReward; + * @param {$Values< + typeof + MIRPot>} pot + * @param {BigNum} amount + * @returns {MoveInstantaneousReward} + */ + static new_to_other_pot( + pot: $Values, + amount: BigNum + ): MoveInstantaneousReward; /** - * @param {number} pot - * @param {MIRToStakeCredentials} amounts - * @returns {MoveInstantaneousReward} - */ + * @param {$Values< + typeof + MIRPot>} pot + * @param {MIRToStakeCredentials} amounts + * @returns {MoveInstantaneousReward} + */ static new_to_stake_creds( - pot: number, + pot: $Values, amounts: MIRToStakeCredentials ): MoveInstantaneousReward; /** - * @returns {number} - */ - pot(): number; + * @returns {$Values< + typeof + MIRPot>} + */ + pot(): $Values; /** - * @returns {number} - */ - kind(): number; + * @returns {$Values< + typeof + MIRKind>} + */ + kind(): $Values; /** * @returns {BigNum | void} @@ -6029,9 +6060,11 @@ declare export class NativeScript { static new_timelock_expiry(timelock_expiry: TimelockExpiry): NativeScript; /** - * @returns {number} - */ - kind(): number; + * @returns {$Values< + typeof + NativeScriptKind>} + */ + kind(): $Values; /** * @returns {ScriptPubkey | void} @@ -6174,9 +6207,11 @@ declare export class NetworkId { static mainnet(): NetworkId; /** - * @returns {number} - */ - kind(): number; + * @returns {$Values< + typeof + NetworkIdKind>} + */ + kind(): $Values; } /** */ @@ -6656,9 +6691,11 @@ declare export class PlutusData { static new_bytes(bytes: Uint8Array): PlutusData; /** - * @returns {number} - */ - kind(): number; + * @returns {$Values< + typeof + PlutusDataKind>} + */ + kind(): $Values; /** * @returns {ConstrPlutusData | void} @@ -6686,17 +6723,24 @@ declare export class PlutusData { as_bytes(): Uint8Array | void; /** - * @param {number} schema - * @returns {string} - */ - to_json(schema: number): string; + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {string} + */ + to_json(schema: $Values): string; /** - * @param {string} json - * @param {number} schema - * @returns {PlutusData} - */ - static from_json(json: string, schema: number): PlutusData; + * @param {string} json + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {PlutusData} + */ + static from_json( + json: string, + schema: $Values + ): PlutusData; /** * @param {Address} address @@ -7398,7 +7442,7 @@ declare export class PoolParams { * @param {RewardAddress} reward_account * @param {Ed25519KeyHashesSet} pool_owners * @param {Relays} relays - * @param {PoolMetadata | void} pool_metadata + * @param {PoolMetadata | void} [pool_metadata] * @returns {PoolParams} */ static new( @@ -8413,9 +8457,11 @@ declare export class RedeemerTag { static new_voting_proposal(): RedeemerTag; /** - * @returns {number} - */ - kind(): number; + * @returns {$Values< + typeof + RedeemerTagKind>} + */ + kind(): $Values; } /** */ @@ -8548,9 +8594,11 @@ declare export class Relay { static new_multi_host_name(multi_host_name: MultiHostName): Relay; /** - * @returns {number} - */ - kind(): number; + * @returns {$Values< + typeof + RelayKind>} + */ + kind(): $Values; /** * @returns {SingleHostAddr | void} @@ -9221,9 +9269,9 @@ declare export class SingleHostAddr { ipv6(): Ipv6 | void; /** - * @param {number | void} port - * @param {Ipv4 | void} ipv4 - * @param {Ipv6 | void} ipv6 + * @param {number | void} [port] + * @param {Ipv4 | void} [ipv4] + * @param {Ipv6 | void} [ipv6] * @returns {SingleHostAddr} */ static new(port?: number, ipv4?: Ipv4, ipv6?: Ipv6): SingleHostAddr; @@ -9973,7 +10021,7 @@ declare export class Transaction { /** * @param {TransactionBody} body * @param {TransactionWitnessSet} witness_set - * @param {AuxiliaryData | void} auxiliary_data + * @param {AuxiliaryData | void} [auxiliary_data] * @returns {Transaction} */ static new( @@ -10351,7 +10399,7 @@ declare export class TransactionBody { * @param {TransactionInputs} inputs * @param {TransactionOutputs} outputs * @param {BigNum} fee - * @param {number | void} ttl + * @param {number | void} [ttl] * @returns {TransactionBody} */ static new( @@ -10382,17 +10430,22 @@ declare export class TransactionBuilder { free(): void; /** - * This automatically selects and adds inputs from {inputs} consisting of just enough to cover - * the outputs that have already been added. - * This should be called after adding all certs/outputs/etc and will be an error otherwise. - * Uses CIP2: https://github.com/cardano-foundation/CIPs/blob/master/CIP-0002/CIP-0002.md - * Adding a change output must be called after via TransactionBuilder::add_change_if_needed() - * This function, diverging from CIP2, takes into account fees and will attempt to add additional - * inputs to cover the minimum fees. This does not, however, set the txbuilder's fee. - * @param {TransactionUnspentOutputs} inputs - * @param {number} strategy - */ - add_inputs_from(inputs: TransactionUnspentOutputs, strategy: number): void; + * This automatically selects and adds inputs from {inputs} consisting of just enough to cover + * the outputs that have already been added. + * This should be called after adding all certs/outputs/etc and will be an error otherwise. + * Uses CIP2: https://github.com/cardano-foundation/CIPs/blob/master/CIP-0002/CIP-0002.md + * Adding a change output must be called after via TransactionBuilder::add_change_if_needed() + * This function, diverging from CIP2, takes into account fees and will attempt to add additional + * inputs to cover the minimum fees. This does not, however, set the txbuilder's fee. + * @param {TransactionUnspentOutputs} inputs + * @param {$Values< + typeof + CoinSelectionStrategyCIP2>} strategy + */ + add_inputs_from( + inputs: TransactionUnspentOutputs, + strategy: $Values + ): void; /** * @param {TxInputsBuilder} inputs @@ -10645,16 +10698,18 @@ declare export class TransactionBuilder { add_json_metadatum(key: BigNum, val: string): void; /** - * Add a single JSON metadatum using a TransactionMetadatumLabel, a String, and a MetadataJsonSchema object - * It will be securely added to existing or new metadata in this builder - * @param {BigNum} key - * @param {string} val - * @param {number} schema - */ + * Add a single JSON metadatum using a TransactionMetadatumLabel, a String, and a MetadataJsonSchema object + * It will be securely added to existing or new metadata in this builder + * @param {BigNum} key + * @param {string} val + * @param {$Values< + typeof + MetadataJsonSchema>} schema + */ add_json_metadatum_with_schema( key: BigNum, val: string, - schema: number + schema: $Values ): void; /** @@ -11233,9 +11288,11 @@ declare export class TransactionMetadatum { static new_text(text: string): TransactionMetadatum; /** - * @returns {number} - */ - kind(): number; + * @returns {$Values< + typeof + TransactionMetadatumKind>} + */ + kind(): $Values; /** * @returns {MetadataMap} @@ -11416,9 +11473,11 @@ declare export class TransactionOutput { static new(address: Address, amount: Value): TransactionOutput; /** - * @returns {number | void} - */ - serialization_format(): number | void; + * @returns {$Values< + typeof + CborContainerType> | void} + */ + serialization_format(): $Values | void; } /** */ @@ -13006,9 +13065,11 @@ declare export class Voter { static new_staking_pool(key_hash: Ed25519KeyHash): Voter; /** - * @returns {number} - */ - kind(): number; + * @returns {$Values< + typeof + VoterKind>} + */ + kind(): $Values; /** * @returns {Credential | void} @@ -13193,22 +13254,31 @@ declare export class VotingProcedure { static from_json(json: string): VotingProcedure; /** - * @param {number} vote - * @returns {VotingProcedure} - */ - static new(vote: number): VotingProcedure; + * @param {$Values< + typeof + VoteKind>} vote + * @returns {VotingProcedure} + */ + static new(vote: $Values): VotingProcedure; /** - * @param {number} vote - * @param {Anchor} anchor - * @returns {VotingProcedure} - */ - static new_with_anchor(vote: number, anchor: Anchor): VotingProcedure; + * @param {$Values< + typeof + VoteKind>} vote + * @param {Anchor} anchor + * @returns {VotingProcedure} + */ + static new_with_anchor( + vote: $Values, + anchor: Anchor + ): VotingProcedure; /** - * @returns {number} - */ - vote_kind(): number; + * @returns {$Values< + typeof + VoteKind>} + */ + vote_kind(): $Values; /** * @returns {Anchor | void} From aeb99cf6a7eb16bac57f936e909b00d99beec934 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 9 Feb 2024 13:07:12 +0800 Subject: [PATCH 215/349] add script size protocol param --- .../protocol_types/protocol_param_update.rs | 10 ++++++++ .../serialization/protocol_param_update.rs | 23 ++++++++++++++++++- rust/src/tests/mock_objects.rs | 1 + .../serialization/protocol_param_update.rs | 1 + 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/rust/src/protocol_types/protocol_param_update.rs b/rust/src/protocol_types/protocol_param_update.rs index 2cf93d8a..3fe6319f 100644 --- a/rust/src/protocol_types/protocol_param_update.rs +++ b/rust/src/protocol_types/protocol_param_update.rs @@ -247,6 +247,7 @@ pub struct ProtocolParamUpdate { pub(crate) governance_action_deposit: Option, pub(crate) drep_deposit: Option, pub(crate) drep_inactivity_period: Option, + pub(crate) ref_script_coins_per_byte: Option, } impl_to_from!(ProtocolParamUpdate); @@ -519,6 +520,14 @@ impl ProtocolParamUpdate { self.drep_inactivity_period.clone() } + pub fn set_ref_script_coins_per_byte(&mut self, ref_script_coins_per_byte: &Coin) { + self.ref_script_coins_per_byte = Some(ref_script_coins_per_byte.clone()); + } + + pub fn ref_script_coins_per_byte(&self) -> Option { + self.ref_script_coins_per_byte.clone() + } + pub fn new() -> Self { Self { minfee_a: None, @@ -553,6 +562,7 @@ impl ProtocolParamUpdate { governance_action_deposit: None, drep_deposit: None, drep_inactivity_period: None, + ref_script_coins_per_byte: None, } } } diff --git a/rust/src/serialization/protocol_param_update.rs b/rust/src/serialization/protocol_param_update.rs index c129cca7..ca4c424b 100644 --- a/rust/src/serialization/protocol_param_update.rs +++ b/rust/src/serialization/protocol_param_update.rs @@ -231,7 +231,10 @@ impl cbor_event::se::Serialize for ProtocolParamUpdate { } + match &self.drep_inactivity_period { Some(_) => 1, None => 0, - }, + } + match &self.ref_script_coins_per_byte { + Some(_) => 1, + None => 0, + } ))?; if let Some(field) = &self.minfee_a { serializer.write_unsigned_integer(0)?; @@ -361,6 +364,10 @@ impl cbor_event::se::Serialize for ProtocolParamUpdate { serializer.write_unsigned_integer(32)?; field.serialize(serializer)?; } + if let Some(field) = &self.ref_script_coins_per_byte { + serializer.write_unsigned_integer(33)?; + field.serialize(serializer)?; + } Ok(serializer) } } @@ -402,6 +409,7 @@ impl Deserialize for ProtocolParamUpdate { let mut governance_action_deposit = None; let mut drep_deposit = None; let mut drep_inactivity_period = None; + let mut ref_script_coins_per_byte = None; let mut read = 0; while match len { @@ -794,6 +802,18 @@ impl Deserialize for ProtocolParamUpdate { .map_err(|e| e.annotate("drep_inactivity_period"))?, ); } + 33 => { + if ref_script_coins_per_byte.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(33)).into()); + } + ref_script_coins_per_byte = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Coin::deserialize(raw)?) + })() + .map_err(|e| e.annotate("ref_script_coins_per_byte"))?, + ); + } unknown_key => { return Err( DeserializeFailure::UnknownKey(Key::Uint(unknown_key)).into() @@ -857,6 +877,7 @@ impl Deserialize for ProtocolParamUpdate { governance_action_deposit, drep_deposit, drep_inactivity_period, + ref_script_coins_per_byte, }) })() .map_err(|e| e.annotate("ProtocolParamUpdate")) diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/mock_objects.rs index 128aa986..52665232 100644 --- a/rust/src/tests/mock_objects.rs +++ b/rust/src/tests/mock_objects.rs @@ -93,6 +93,7 @@ pub(crate) fn crate_full_protocol_param_update() -> ProtocolParamUpdate { governance_action_deposit: Some(Coin::from(44_444u32)), drep_deposit: Some(Coin::from(44_444u32)), drep_inactivity_period: Some(44_444u32), + ref_script_coins_per_byte: Some(Coin::from(44_444u32)), } } diff --git a/rust/src/tests/serialization/protocol_param_update.rs b/rust/src/tests/serialization/protocol_param_update.rs index 14316e66..4c7864d0 100644 --- a/rust/src/tests/serialization/protocol_param_update.rs +++ b/rust/src/tests/serialization/protocol_param_update.rs @@ -51,6 +51,7 @@ fn protocol_param_update_ser_round_trip() { governance_action_deposit: Some(Coin::from(26_444u32)), drep_deposit: Some(Coin::from(27_444u32)), drep_inactivity_period: Some(28_444u32), + ref_script_coins_per_byte: Some(Coin::from(29_444u32)), }; let cbor = pp_update.to_bytes(); From 81c6621d2b3aa63a0f2ec6b7ffa8dd60e3dea1e1 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 9 Feb 2024 13:09:27 +0800 Subject: [PATCH 216/349] change url max len --- rust/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index e4fe9676..d3abcb57 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -504,7 +504,7 @@ impl Ipv6 { } } -static URL_MAX_LEN: usize = 64; +static URL_MAX_LEN: usize = 128; #[wasm_bindgen] #[derive( From 16f905c60b1caebfc55f25bc286d0149a21df701 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 9 Feb 2024 14:15:42 +0800 Subject: [PATCH 217/349] fix certs witnesses and refund value --- rust/src/builders/certificates_builder.rs | 8 +- .../tests/builders/certificates_builder.rs | 162 +++++++++--------- 2 files changed, 83 insertions(+), 87 deletions(-) diff --git a/rust/src/builders/certificates_builder.rs b/rust/src/builders/certificates_builder.rs index 7b36a494..a27e8d02 100644 --- a/rust/src/builders/certificates_builder.rs +++ b/rust/src/builders/certificates_builder.rs @@ -151,9 +151,6 @@ impl CertificatesBuilder { refund = refund.checked_add(&key_deposit)?; } } - CertificateEnum::PoolRetirement(_) => { - refund = refund.checked_add(&pool_deposit)?; - } CertificateEnum::DrepDeregistration(cert) => { refund = refund.checked_add(&cert.coin)?; } @@ -265,6 +262,11 @@ fn witness_keys_for_cert(cert_enum: &Certificate) -> RequiredSigners { set.add(key_hash); } } + CertificateEnum::DrepRegistration(cert) => { + if let CredType::Key(key_hash) = &cert.voting_credential.0 { + set.add(key_hash); + } + } CertificateEnum::DrepDeregistration(cert) => { if let CredType::Key(key_hash) = &cert.voting_credential.0 { set.add(key_hash); diff --git a/rust/src/tests/builders/certificates_builder.rs b/rust/src/tests/builders/certificates_builder.rs index 84b65bdc..fbf3f0ad 100644 --- a/rust/src/tests/builders/certificates_builder.rs +++ b/rust/src/tests/builders/certificates_builder.rs @@ -5,7 +5,7 @@ use crate::fakes::{ use crate::*; #[test] -fn certificatess_builder_deposit_test() { +fn certificates_builder_deposit_no_refund_test() { let mut builder = CertificatesBuilder::new(); let pool_deposit = 100u64; let key_deposit = 200u64; @@ -30,12 +30,6 @@ fn certificatess_builder_deposit_test() { ); let drep_reg_cert_wrapped = Certificate::new_drep_registration(&drep_reg_cert); - let drep_dereg_cert = DrepDeregistration::new( - &Credential::from_keyhash(&fake_key_hash(5)), - &Coin::from(drep_reg_deposit), - ); - let drep_dereg_cert_wrapped = Certificate::new_drep_deregistration(&drep_dereg_cert); - let drep_update_cert = DrepUpdate::new(&Credential::from_keyhash(&fake_key_hash(6))); let cdrep_update_cert_wrapped = Certificate::new_drep_update(&drep_update_cert); @@ -53,7 +47,8 @@ fn certificatess_builder_deposit_test() { ); let staking_cred = Credential::from_keyhash(&fake_key_hash(10)); - let reward_address = RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &staking_cred); + let reward_address = + RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &staking_cred); let mut owners = Ed25519KeyHashesSet::new(); owners.add(&fake_key_hash(11)); owners.add(&fake_key_hash(12)); @@ -96,32 +91,23 @@ fn certificatess_builder_deposit_test() { ); let stake_deleg_cert_wrapped = Certificate::new_stake_delegation(&stake_deleg_cert); - let stake_dereg_cert = StakeDeregistration::new(&Credential::from_keyhash(&fake_key_hash(22))); - let stake_dereg_cert_wrapped = Certificate::new_stake_deregistration(&stake_dereg_cert); - - let stake_dereg_with_coin_cert = - StakeDeregistration::new_with_coin( - &Credential::from_keyhash(&fake_key_hash(22)), - &Coin::from(key_deposit_form_args), - ); - let stake_dereg_with_coint_wrapped = Certificate::new_stake_deregistration(&stake_dereg_with_coin_cert); - let stake_reg_cert = StakeRegistration::new(&Credential::from_keyhash(&fake_key_hash(23))); let stake_reg_cert_wrapped = Certificate::new_stake_registration(&stake_reg_cert); - let stake_reg_with_coin_cert = - StakeRegistration::new_with_coin( - &Credential::from_keyhash(&fake_key_hash(23)), - &Coin::from(key_deposit_form_args), - ); - let stake_reg_with_coint_wrapped = Certificate::new_stake_registration(&stake_reg_with_coin_cert); + let stake_reg_with_coin_cert = StakeRegistration::new_with_coin( + &Credential::from_keyhash(&fake_key_hash(23)), + &Coin::from(key_deposit_form_args), + ); + let stake_reg_with_coint_wrapped = + Certificate::new_stake_registration(&stake_reg_with_coin_cert); let stake_reg_deleg_cert = StakeRegistrationAndDelegation::new( &Credential::from_keyhash(&fake_key_hash(23)), &fake_key_hash(24), &Coin::from(key_deposit_form_args), ); - let stake_reg_deleg_cert_wrapped = Certificate::new_stake_registration_and_delegation(&stake_reg_deleg_cert); + let stake_reg_deleg_cert_wrapped = + Certificate::new_stake_registration_and_delegation(&stake_reg_deleg_cert); let drep = DRep::new_key_hash(&fake_key_hash(25)); let stake_vote_reg_deleg_cert = StakeVoteRegistrationAndDelegation::new( @@ -130,7 +116,8 @@ fn certificatess_builder_deposit_test() { &drep, &Coin::from(key_deposit_form_args), ); - let stake_vote_reg_deleg_cert_wrapped = Certificate::new_stake_vote_registration_and_delegation(&stake_vote_reg_deleg_cert); + let stake_vote_reg_deleg_cert_wrapped = + Certificate::new_stake_vote_registration_and_delegation(&stake_vote_reg_deleg_cert); let drep = DRep::new_key_hash(&fake_key_hash(28)); let vote_deleg_cert = VoteDelegation::new(&Credential::from_keyhash(&fake_key_hash(29)), &drep); @@ -142,12 +129,12 @@ fn certificatess_builder_deposit_test() { &drep, &Coin::from(key_deposit_form_args), ); - let vote_reg_deleg_cert_wrapped = Certificate::new_vote_registration_and_delegation(&vote_reg_deleg_cert); + let vote_reg_deleg_cert_wrapped = + Certificate::new_vote_registration_and_delegation(&vote_reg_deleg_cert); builder.add(&committee_hot_key_dereg_cert_wrapped).unwrap(); builder.add(&committee_hot_key_reg_cert_wrapped).unwrap(); builder.add(&drep_reg_cert_wrapped).unwrap(); - builder.add(&drep_dereg_cert_wrapped).unwrap(); builder.add(&cdrep_update_cert_wrapped).unwrap(); builder.add(&genesis_key_deleg_cert_wrapped).unwrap(); builder.add(&mir_cert_wrapped).unwrap(); @@ -155,8 +142,6 @@ fn certificatess_builder_deposit_test() { builder.add(&pool_ret_cert_wrapped).unwrap(); builder.add(&stake_vote_deleg_cert_wrapped).unwrap(); builder.add(&stake_deleg_cert_wrapped).unwrap(); - builder.add(&stake_dereg_cert_wrapped).unwrap(); - builder.add(&stake_dereg_with_coint_wrapped).unwrap(); builder.add(&stake_reg_cert_wrapped).unwrap(); builder.add(&stake_reg_with_coint_wrapped).unwrap(); builder.add(&stake_reg_deleg_cert_wrapped).unwrap(); @@ -164,22 +149,25 @@ fn certificatess_builder_deposit_test() { builder.add(&vote_deleg_cert_wrapped).unwrap(); builder.add(&vote_reg_deleg_cert_wrapped).unwrap(); - let builder_deposit = builder.get_certificates_deposit( - &Coin::from(pool_deposit), - &Coin::from(key_deposit), - ).unwrap(); + let builder_deposit = builder + .get_certificates_deposit(&Coin::from(pool_deposit), &Coin::from(key_deposit)) + .unwrap(); + + let expected_deposit = + Coin::from(pool_deposit + key_deposit + drep_reg_deposit + (key_deposit_form_args * 4)); - let expected_deposit = Coin::from( - pool_deposit - + key_deposit - + drep_reg_deposit - + (key_deposit_form_args * 4)); + let refund = builder + .get_certificates_refund(&Coin::from(pool_deposit), &Coin::from(key_deposit)) + .unwrap().coin; + + let expected_refund = Coin::zero(); assert_eq!(builder_deposit, expected_deposit); + assert_eq!(refund, expected_refund); } #[test] -fn certificatess_builder_no_deposit_test() { +fn certificates_builder_refund_no_deposit_test() { let mut builder = CertificatesBuilder::new(); let pool_deposit = 100u64; let key_deposit = 200u64; @@ -221,7 +209,8 @@ fn certificatess_builder_no_deposit_test() { ); let staking_cred = Credential::from_keyhash(&fake_key_hash(10)); - let reward_address = RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &staking_cred); + let reward_address = + RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &staking_cred); let mut owners = Ed25519KeyHashesSet::new(); owners.add(&fake_key_hash(11)); owners.add(&fake_key_hash(12)); @@ -264,12 +253,12 @@ fn certificatess_builder_no_deposit_test() { let stake_dereg_cert = StakeDeregistration::new(&Credential::from_keyhash(&fake_key_hash(22))); let stake_dereg_cert_wrapped = Certificate::new_stake_deregistration(&stake_dereg_cert); - let stake_dereg_with_coin_cert = - StakeDeregistration::new_with_coin( - &Credential::from_keyhash(&fake_key_hash(22)), - &Coin::from(key_deposit_form_args), - ); - let stake_dereg_with_coint_wrapped = Certificate::new_stake_deregistration(&stake_dereg_with_coin_cert); + let stake_dereg_with_coin_cert = StakeDeregistration::new_with_coin( + &Credential::from_keyhash(&fake_key_hash(22)), + &Coin::from(key_deposit_form_args), + ); + let stake_dereg_with_coin_wrapped = + Certificate::new_stake_deregistration(&stake_dereg_with_coin_cert); let drep = DRep::new_key_hash(&fake_key_hash(28)); let vote_deleg_cert = VoteDelegation::new(&Credential::from_keyhash(&fake_key_hash(29)), &drep); @@ -285,21 +274,26 @@ fn certificatess_builder_no_deposit_test() { builder.add(&stake_vote_deleg_cert_wrapped).unwrap(); builder.add(&stake_deleg_cert_wrapped).unwrap(); builder.add(&stake_dereg_cert_wrapped).unwrap(); - builder.add(&stake_dereg_with_coint_wrapped).unwrap(); + builder.add(&stake_dereg_with_coin_wrapped).unwrap(); builder.add(&vote_deleg_cert_wrapped).unwrap(); - let builder_deposit = builder.get_certificates_deposit( - &Coin::from(pool_deposit), - &Coin::from(key_deposit), - ).unwrap(); + let builder_deposit = builder + .get_certificates_deposit(&Coin::from(pool_deposit), &Coin::from(key_deposit)) + .unwrap(); let expected_deposit = Coin::zero(); + let refund = builder + .get_certificates_refund(&Coin::from(pool_deposit), &Coin::from(key_deposit)) + .unwrap().coin; + let expected_refund = Coin::from(key_deposit + key_deposit_form_args + drep_reg_deposit); + assert_eq!(builder_deposit, expected_deposit); + assert_eq!(refund, expected_refund); } #[test] -fn certificatess_builder_req_signers_test() { +fn certificates_builder_req_signers_test() { let mut builder = CertificatesBuilder::new(); let pool_deposit = 100u64; let key_deposit = 200u64; @@ -378,7 +372,8 @@ fn certificatess_builder_req_signers_test() { ); let staking_cred = Credential::from_keyhash(&key_hash_10); - let reward_address = RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &staking_cred); + let reward_address = + RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &staking_cred); let mut owners = Ed25519KeyHashesSet::new(); owners.add(&key_hash_11); owners.add(&key_hash_12); @@ -407,46 +402,42 @@ fn certificatess_builder_req_signers_test() { let pool_ret_cert_wrapped = Certificate::new_pool_retirement(&pool_ret_cert); let drep = DRep::new_key_hash(&key_hash_16); - let stake_vote_deleg_cert = StakeAndVoteDelegation::new( - &Credential::from_keyhash(&key_hash_17), - &key_hash_18, - &drep, - ); + let stake_vote_deleg_cert = + StakeAndVoteDelegation::new(&Credential::from_keyhash(&key_hash_17), &key_hash_18, &drep); let stake_vote_deleg_cert_wrapped = Certificate::new_stake_and_vote_delegation(&stake_vote_deleg_cert); - let stake_deleg_cert = StakeDelegation::new( - &Credential::from_keyhash(&key_hash_19), - &key_hash_20, - ); + let stake_deleg_cert = + StakeDelegation::new(&Credential::from_keyhash(&key_hash_19), &key_hash_20); let stake_deleg_cert_wrapped = Certificate::new_stake_delegation(&stake_deleg_cert); let stake_dereg_cert = StakeDeregistration::new(&Credential::from_keyhash(&key_hash_21)); let stake_dereg_cert_wrapped = Certificate::new_stake_deregistration(&stake_dereg_cert); - let stake_dereg_with_coin_cert = - StakeDeregistration::new_with_coin( - &Credential::from_keyhash(&key_hash_22), - &Coin::from(key_deposit_form_args), - ); - let stake_dereg_with_coint_wrapped = Certificate::new_stake_deregistration(&stake_dereg_with_coin_cert); + let stake_dereg_with_coin_cert = StakeDeregistration::new_with_coin( + &Credential::from_keyhash(&key_hash_22), + &Coin::from(key_deposit_form_args), + ); + let stake_dereg_with_coint_wrapped = + Certificate::new_stake_deregistration(&stake_dereg_with_coin_cert); let stake_reg_cert = StakeRegistration::new(&Credential::from_keyhash(&key_hash_23)); let stake_reg_cert_wrapped = Certificate::new_stake_registration(&stake_reg_cert); - let stake_reg_with_coin_cert = - StakeRegistration::new_with_coin( - &Credential::from_keyhash(&key_hash_24), - &Coin::from(key_deposit_form_args), - ); - let stake_reg_with_coin_wrapped = Certificate::new_stake_registration(&stake_reg_with_coin_cert); + let stake_reg_with_coin_cert = StakeRegistration::new_with_coin( + &Credential::from_keyhash(&key_hash_24), + &Coin::from(key_deposit_form_args), + ); + let stake_reg_with_coin_wrapped = + Certificate::new_stake_registration(&stake_reg_with_coin_cert); let stake_reg_deleg_cert = StakeRegistrationAndDelegation::new( &Credential::from_keyhash(&key_hash_25), &key_hash_26, &Coin::from(key_deposit_form_args), ); - let stake_reg_deleg_cert_wrapped = Certificate::new_stake_registration_and_delegation(&stake_reg_deleg_cert); + let stake_reg_deleg_cert_wrapped = + Certificate::new_stake_registration_and_delegation(&stake_reg_deleg_cert); let drep = DRep::new_key_hash(&key_hash_27); let stake_vote_reg_deleg_cert = StakeVoteRegistrationAndDelegation::new( @@ -455,7 +446,8 @@ fn certificatess_builder_req_signers_test() { &drep, &Coin::from(key_deposit_form_args), ); - let stake_vote_reg_deleg_cert_wrapped = Certificate::new_stake_vote_registration_and_delegation(&stake_vote_reg_deleg_cert); + let stake_vote_reg_deleg_cert_wrapped = + Certificate::new_stake_vote_registration_and_delegation(&stake_vote_reg_deleg_cert); let drep = DRep::new_key_hash(&key_hash_30); let vote_deleg_cert = VoteDelegation::new(&Credential::from_keyhash(&key_hash_31), &drep); @@ -467,7 +459,8 @@ fn certificatess_builder_req_signers_test() { &drep, &Coin::from(key_deposit_form_args), ); - let vote_reg_deleg_cert_wrapped = Certificate::new_vote_registration_and_delegation(&vote_reg_deleg_cert); + let vote_reg_deleg_cert_wrapped = + Certificate::new_vote_registration_and_delegation(&vote_reg_deleg_cert); builder.add(&committee_hot_key_dereg_cert_wrapped).unwrap(); builder.add(&committee_hot_key_reg_cert_wrapped).unwrap(); @@ -489,16 +482,17 @@ fn certificatess_builder_req_signers_test() { builder.add(&vote_deleg_cert_wrapped).unwrap(); builder.add(&vote_reg_deleg_cert_wrapped).unwrap(); - let builder_deposit = builder.get_certificates_deposit( - &Coin::from(pool_deposit), - &Coin::from(key_deposit), - ).unwrap(); + let builder_deposit = builder + .get_certificates_deposit(&Coin::from(pool_deposit), &Coin::from(key_deposit)) + .unwrap(); + let req_signers = builder.get_required_signers(); - assert_eq!(req_signers.len(), 18); + assert_eq!(req_signers.len(), 19); assert!(req_signers.contains(&key_hash_1)); assert!(req_signers.contains(&key_hash_2)); + assert!(req_signers.contains(&key_hash_4)); assert!(req_signers.contains(&key_hash_5)); assert!(req_signers.contains(&key_hash_6)); assert!(req_signers.contains(&key_hash_8)); @@ -515,4 +509,4 @@ fn certificatess_builder_req_signers_test() { assert!(req_signers.contains(&key_hash_28)); assert!(req_signers.contains(&key_hash_31)); assert!(req_signers.contains(&key_hash_33)); -} \ No newline at end of file +} From c8e48c06917c658ba384fc459cc8d435986ee6dc Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 10 Feb 2024 20:18:19 +0800 Subject: [PATCH 218/349] remove set types, moving out types from crypto.rs --- rust/src/builders/certificates_builder.rs | 13 +- rust/src/builders/script_structs.rs | 6 +- rust/src/builders/tx_builder.rs | 18 +- rust/src/builders/tx_inputs_builder.rs | 12 +- rust/src/builders/voting_builder.rs | 6 +- rust/src/builders/withdrawals_builder.rs | 8 +- rust/src/chain_crypto/algorithms/ed25519.rs | 4 +- rust/src/chain_crypto/sign.rs | 1 + rust/src/crypto.rs | 1480 +---------------- rust/src/fakes.rs | 2 +- rust/src/fees.rs | 2 +- rust/src/lib.rs | 190 +-- .../move_instantaneous_rewards_cert.rs | 9 +- .../certificates/pool_registration.rs | 6 +- rust/src/protocol_types/credential.rs | 89 + rust/src/protocol_types/credentials.rs | 197 +-- .../crypto/bip32_private_key.rs | 119 ++ .../protocol_types/crypto/bip32_public_key.rs | 79 + .../crypto/impl_hash_type_macro.rs | 144 ++ .../crypto/impl_signature_macro.rs | 98 ++ .../protocol_types/crypto/kes_signature.rs | 73 + .../crypto/legacy_daedalus_private_key.rs | 24 + .../crypto/macro_implemented_hash_types.rs | 22 + .../macro_implemented_signature_types.rs | 3 + rust/src/protocol_types/crypto/mod.rs | 40 + rust/src/protocol_types/crypto/nonce.rs | 47 + rust/src/protocol_types/crypto/private_key.rs | 107 ++ rust/src/protocol_types/crypto/public_key.rs | 98 ++ rust/src/protocol_types/crypto/public_keys.rs | 24 + rust/src/protocol_types/crypto/vkey.rs | 18 + rust/src/protocol_types/crypto/vkeys.rs | 24 + rust/src/protocol_types/crypto/vrf_cert.rs | 41 + rust/src/protocol_types/ed25519_key_hashes.rs | 124 +- .../governance/proposals/committee.rs | 4 +- .../proposals/update_committee_action.rs | 8 +- rust/src/protocol_types/metadata.rs | 2 +- rust/src/protocol_types/mod.rs | 11 +- rust/src/protocol_types/plutus.rs | 2 +- rust/src/protocol_types/transaction_body.rs | 6 +- .../witnesses/bootstrap_witness.rs | 45 + .../witnesses/bootstrap_witnesses.rs | 87 + rust/src/protocol_types/witnesses/mod.rs | 19 + .../witnesses/transaction_witnesses_set.rs | 76 + .../witnesses/transaction_witnesses_sets.rs | 26 + .../protocol_types/witnesses/vkeywitness.rs | 28 + .../protocol_types/witnesses/vkeywitnesses.rs | 26 + .../move_instantaneous_rewards_cert.rs | 3 +- .../certificates/pool_registration.rs | 2 +- rust/src/serialization/credential.rs | 60 + rust/src/serialization/credentials.rs | 100 +- .../src/serialization/crypto/kes_signature.rs | 33 + rust/src/serialization/crypto/mod.rs | 5 + rust/src/serialization/crypto/nonce.rs | 72 + rust/src/serialization/crypto/vkey.rs | 22 + rust/src/serialization/crypto/vkeys.rs | 40 + rust/src/serialization/crypto/vrf_cert.rs | 50 + rust/src/serialization/ed25519_key_hashes.rs | 12 +- rust/src/serialization/general.rs | 308 +--- .../proposals/update_committee_action.rs | 2 +- rust/src/serialization/metadata.rs | 2 +- rust/src/serialization/mod.rs | 5 +- rust/src/serialization/plutus.rs | 6 +- rust/src/serialization/transaction_body.rs | 2 +- .../witnesses/bootstrap_witness.rs | 68 + .../witnesses/bootstrap_witnesses.rs | 44 + rust/src/serialization/witnesses/mod.rs | 6 + .../witnesses/transaction_witnesses_set.rs | 245 +++ .../witnesses/transaction_witnesses_sets.rs | 40 + .../serialization/witnesses/vkeywitness.rs | 51 + .../serialization/witnesses/vkeywitnesses.rs | 44 + .../tests/builders/certificates_builder.rs | 6 +- rust/src/tests/builders/tx_builder.rs | 12 +- .../tests/builders/voting_proposal_builder.rs | 6 +- rust/src/tests/crypto.rs | 86 + rust/src/tests/general.rs | 8 +- rust/src/tests/mock_objects.rs | 2 +- rust/src/tests/mod.rs | 3 +- .../protocol_types/governance/proposals.rs | 2 +- rust/src/tests/serialization/certificates.rs | 2 +- .../serialization/governance/proposals.rs | 6 +- .../tests/serialization/transaction_body.rs | 2 +- 81 files changed, 2515 insertions(+), 2310 deletions(-) create mode 100644 rust/src/protocol_types/credential.rs create mode 100644 rust/src/protocol_types/crypto/bip32_private_key.rs create mode 100644 rust/src/protocol_types/crypto/bip32_public_key.rs create mode 100644 rust/src/protocol_types/crypto/impl_hash_type_macro.rs create mode 100644 rust/src/protocol_types/crypto/impl_signature_macro.rs create mode 100644 rust/src/protocol_types/crypto/kes_signature.rs create mode 100644 rust/src/protocol_types/crypto/legacy_daedalus_private_key.rs create mode 100644 rust/src/protocol_types/crypto/macro_implemented_hash_types.rs create mode 100644 rust/src/protocol_types/crypto/macro_implemented_signature_types.rs create mode 100644 rust/src/protocol_types/crypto/mod.rs create mode 100644 rust/src/protocol_types/crypto/nonce.rs create mode 100644 rust/src/protocol_types/crypto/private_key.rs create mode 100644 rust/src/protocol_types/crypto/public_key.rs create mode 100644 rust/src/protocol_types/crypto/public_keys.rs create mode 100644 rust/src/protocol_types/crypto/vkey.rs create mode 100644 rust/src/protocol_types/crypto/vkeys.rs create mode 100644 rust/src/protocol_types/crypto/vrf_cert.rs create mode 100644 rust/src/protocol_types/witnesses/bootstrap_witness.rs create mode 100644 rust/src/protocol_types/witnesses/bootstrap_witnesses.rs create mode 100644 rust/src/protocol_types/witnesses/mod.rs create mode 100644 rust/src/protocol_types/witnesses/transaction_witnesses_set.rs create mode 100644 rust/src/protocol_types/witnesses/transaction_witnesses_sets.rs create mode 100644 rust/src/protocol_types/witnesses/vkeywitness.rs create mode 100644 rust/src/protocol_types/witnesses/vkeywitnesses.rs create mode 100644 rust/src/serialization/credential.rs create mode 100644 rust/src/serialization/crypto/kes_signature.rs create mode 100644 rust/src/serialization/crypto/mod.rs create mode 100644 rust/src/serialization/crypto/nonce.rs create mode 100644 rust/src/serialization/crypto/vkey.rs create mode 100644 rust/src/serialization/crypto/vkeys.rs create mode 100644 rust/src/serialization/crypto/vrf_cert.rs create mode 100644 rust/src/serialization/witnesses/bootstrap_witness.rs create mode 100644 rust/src/serialization/witnesses/bootstrap_witnesses.rs create mode 100644 rust/src/serialization/witnesses/mod.rs create mode 100644 rust/src/serialization/witnesses/transaction_witnesses_set.rs create mode 100644 rust/src/serialization/witnesses/transaction_witnesses_sets.rs create mode 100644 rust/src/serialization/witnesses/vkeywitness.rs create mode 100644 rust/src/serialization/witnesses/vkeywitnesses.rs create mode 100644 rust/src/tests/crypto.rs diff --git a/rust/src/builders/certificates_builder.rs b/rust/src/builders/certificates_builder.rs index a27e8d02..d036dccb 100644 --- a/rust/src/builders/certificates_builder.rs +++ b/rust/src/builders/certificates_builder.rs @@ -64,13 +64,13 @@ impl CertificatesBuilder { Ok(()) } - pub(crate) fn get_required_signers(&self) -> Ed25519KeyHashesSet { - let mut set = Ed25519KeyHashesSet::new(); + pub(crate) fn get_required_signers(&self) -> Ed25519KeyHashes { + let mut set = Ed25519KeyHashes::new(); for (cert, script_wit) in &self.certs { let cert_req_signers = witness_keys_for_cert(&cert); - set.0.extend(cert_req_signers); + set.extend(&cert_req_signers); if let Some(ScriptWitnessType::NativeScriptWitness(script_source)) = script_wit { - set.extend(script_source.required_signers()); + set.extend(&script_source.required_signers()); } } set @@ -234,9 +234,7 @@ fn witness_keys_for_cert(cert_enum: &Certificate) -> RequiredSigners { } } CertificateEnum::PoolRegistration(cert) => { - for owner in &cert.pool_params().pool_owners().0 { - set.add(&owner.clone()); - } + set.extend(&cert.pool_params().pool_owners()); set.add(&cert.pool_params().operator()); } CertificateEnum::PoolRetirement(cert) => { @@ -297,7 +295,6 @@ fn witness_keys_for_cert(cert_enum: &Certificate) -> RequiredSigners { set.add(key_hash); } } - CertificateEnum::DrepRegistration(_) => {} } set } diff --git a/rust/src/builders/script_structs.rs b/rust/src/builders/script_structs.rs index e0b9520a..98b56c79 100644 --- a/rust/src/builders/script_structs.rs +++ b/rust/src/builders/script_structs.rs @@ -79,10 +79,10 @@ impl NativeScriptSourceEnum { } } - pub fn required_signers(&self) -> Ed25519KeyHashesSet { + pub fn required_signers(&self) -> Ed25519KeyHashes { match self { - NativeScriptSourceEnum::NativeScript(script) => Ed25519KeyHashesSet::from(script), - NativeScriptSourceEnum::RefInput(_, _, required_signers) => required_signers.into(), + NativeScriptSourceEnum::NativeScript(script) => Ed25519KeyHashes::from(script), + NativeScriptSourceEnum::RefInput(_, _, required_signers) => required_signers.clone(), } } } diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index 11a35658..630322f7 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -40,20 +40,20 @@ pub(crate) fn fake_raw_key_public() -> PublicKey { } fn count_needed_vkeys(tx_builder: &TransactionBuilder) -> usize { - let mut input_hashes: Ed25519KeyHashesSet = Ed25519KeyHashesSet::from(&tx_builder.inputs); - input_hashes.extend(Ed25519KeyHashesSet::from(&tx_builder.collateral)); - input_hashes.extend(tx_builder.required_signers.clone()); + let mut input_hashes: Ed25519KeyHashes = Ed25519KeyHashes::from(&tx_builder.inputs); + input_hashes.extend_move(Ed25519KeyHashes::from(&tx_builder.collateral)); + input_hashes.extend_move(tx_builder.required_signers.clone()); if let Some(mint_builder) = &tx_builder.mint { - input_hashes.extend(Ed25519KeyHashesSet::from(&mint_builder.get_native_scripts())); + input_hashes.extend_move(Ed25519KeyHashes::from(&mint_builder.get_native_scripts())); } if let Some(withdrawals_builder) = &tx_builder.withdrawals { - input_hashes.extend(withdrawals_builder.get_required_signers()); + input_hashes.extend_move(withdrawals_builder.get_required_signers()); } if let Some(certs_builder) = &tx_builder.certs { - input_hashes.extend(certs_builder.get_required_signers()); + input_hashes.extend_move(certs_builder.get_required_signers()); } if let Some(voting_builder) = &tx_builder.voting_procedures { - input_hashes.extend(voting_builder.get_required_signers()); + input_hashes.extend_move(voting_builder.get_required_signers()); } input_hashes.len() } @@ -315,7 +315,7 @@ pub struct TransactionBuilder { pub(crate) validity_start_interval: Option, pub(crate) mint: Option, pub(crate) script_data_hash: Option, - pub(crate) required_signers: Ed25519KeyHashesSet, + pub(crate) required_signers: Ed25519KeyHashes, pub(crate) collateral_return: Option, pub(crate) total_collateral: Option, pub(crate) reference_inputs: HashSet, @@ -1236,7 +1236,7 @@ impl TransactionBuilder { validity_start_interval: None, mint: None, script_data_hash: None, - required_signers: Ed25519KeyHashesSet::new(), + required_signers: Ed25519KeyHashes::new(), collateral_return: None, total_collateral: None, reference_inputs: HashSet::new(), diff --git a/rust/src/builders/tx_inputs_builder.rs b/rust/src/builders/tx_inputs_builder.rs index 409183a5..40d486fd 100644 --- a/rust/src/builders/tx_inputs_builder.rs +++ b/rust/src/builders/tx_inputs_builder.rs @@ -1,5 +1,5 @@ use crate::*; -use linked_hash_map::LinkedHashMap; +use hashlink::LinkedHashMap; use std::collections::{BTreeMap, BTreeSet}; #[derive(Clone, Debug)] @@ -12,7 +12,7 @@ pub(crate) struct TxBuilderInput { // We need to know how many of each type of witness will be in the transaction so we can calculate the tx fee #[derive(Clone, Debug)] pub struct InputsRequiredWitness { - vkeys: Ed25519KeyHashesSet, + vkeys: Ed25519KeyHashes, scripts: LinkedHashMap>>, bootstraps: BTreeSet>, } @@ -34,7 +34,7 @@ impl TxInputsBuilder { Self { inputs: BTreeMap::new(), required_witnesses: InputsRequiredWitness { - vkeys: Ed25519KeyHashesSet::new(), + vkeys: Ed25519KeyHashes::new(), scripts: LinkedHashMap::new(), bootstraps: BTreeSet::new(), }, @@ -304,7 +304,7 @@ impl TxInputsBuilder { } pub fn add_required_signers(&mut self, keys: &RequiredSigners) { - keys.0.iter().for_each(|k| self.add_required_signer(k)); + self.required_witnesses.vkeys.extend(keys); } pub fn total_value(&self) -> Result { @@ -360,7 +360,7 @@ impl TxInputsBuilder { } } -impl From<&TxInputsBuilder> for Ed25519KeyHashesSet { +impl From<&TxInputsBuilder> for Ed25519KeyHashes { fn from(inputs: &TxInputsBuilder) -> Self { let mut set = inputs.required_witnesses.vkeys.clone(); inputs @@ -370,7 +370,7 @@ impl From<&TxInputsBuilder> for Ed25519KeyHashesSet { .flat_map(|tx_wits| tx_wits.values()) .for_each(|swt: &Option| { if let Some(ScriptWitnessType::NativeScriptWitness(script_source)) = swt { - set.extend(script_source.required_signers()); + set.extend_move(script_source.required_signers()); } }); set diff --git a/rust/src/builders/voting_builder.rs b/rust/src/builders/voting_builder.rs index 3e977045..5b770efb 100644 --- a/rust/src/builders/voting_builder.rs +++ b/rust/src/builders/voting_builder.rs @@ -100,8 +100,8 @@ impl VotingBuilder { Ok(()) } - pub(crate) fn get_required_signers(&self) -> Ed25519KeyHashesSet { - let mut set = Ed25519KeyHashesSet::new(); + pub(crate) fn get_required_signers(&self) -> Ed25519KeyHashes { + let mut set = Ed25519KeyHashes::new(); for (voter, voter_votes) in &self.votes { let req_signature = voter.to_key_hash(); if let Some(req_signature) = req_signature { @@ -111,7 +111,7 @@ impl VotingBuilder { if let Some(ScriptWitnessType::NativeScriptWitness(script_source)) = &voter_votes.script_witness { - set.extend(script_source.required_signers()); + set.extend_move(script_source.required_signers()); } } set diff --git a/rust/src/builders/withdrawals_builder.rs b/rust/src/builders/withdrawals_builder.rs index 6ab5a2a0..2366dbdf 100644 --- a/rust/src/builders/withdrawals_builder.rs +++ b/rust/src/builders/withdrawals_builder.rs @@ -1,5 +1,5 @@ use crate::*; -use linked_hash_map::LinkedHashMap; +use hashlink::LinkedHashMap; #[wasm_bindgen] #[derive(Clone, Debug)] @@ -77,8 +77,8 @@ impl WithdrawalsBuilder { Ok(()) } - pub(crate) fn get_required_signers(&self) -> Ed25519KeyHashesSet { - let mut set = Ed25519KeyHashesSet::new(); + pub(crate) fn get_required_signers(&self) -> Ed25519KeyHashes { + let mut set = Ed25519KeyHashes::new(); for (address, (_, script_wit)) in &self.withdrawals { let req_signature = address.payment_cred().to_keyhash(); if let Some(req_signature) = req_signature { @@ -86,7 +86,7 @@ impl WithdrawalsBuilder { } if let Some(ScriptWitnessType::NativeScriptWitness(script_source)) = script_wit { - set.extend(script_source.required_signers()); + set.extend_move(script_source.required_signers()); } } set diff --git a/rust/src/chain_crypto/algorithms/ed25519.rs b/rust/src/chain_crypto/algorithms/ed25519.rs index 36a53143..0c2a1121 100644 --- a/rust/src/chain_crypto/algorithms/ed25519.rs +++ b/rust/src/chain_crypto/algorithms/ed25519.rs @@ -10,7 +10,7 @@ use rand_os::rand_core::{CryptoRng, RngCore}; use ed25519_bip32::XPub; /// ED25519 Signing Algorithm -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Hash)] pub struct Ed25519; #[derive(Clone)] @@ -19,7 +19,7 @@ pub struct Priv([u8; ed25519::PRIVATE_KEY_LENGTH]); #[derive(Clone, PartialEq, Eq, Hash)] pub struct Pub(pub(crate) [u8; ed25519::PUBLIC_KEY_LENGTH]); -#[derive(Clone)] +#[derive(Clone, Hash)] pub struct Sig(pub(crate) [u8; ed25519::SIGNATURE_LENGTH]); impl Pub { diff --git a/rust/src/chain_crypto/sign.rs b/rust/src/chain_crypto/sign.rs index cadbbd1c..2df4078b 100644 --- a/rust/src/chain_crypto/sign.rs +++ b/rust/src/chain_crypto/sign.rs @@ -53,6 +53,7 @@ where fn sign(key: &Self::Secret, msg: &[u8]) -> ::Signature; } +#[derive(Hash)] pub struct Signature { signdata: A::Signature, phantom: PhantomData, diff --git a/rust/src/crypto.rs b/rust/src/crypto.rs index 0085f65b..91de8e38 100644 --- a/rust/src/crypto.rs +++ b/rust/src/crypto.rs @@ -4,7 +4,6 @@ use bech32::ToBase32; use cbor_event::{de::Deserializer, se::Serializer}; use chain::key; use crypto::bech32::Bech32 as _; -use rand_os::OsRng; use std::fmt; use std::fmt::Display; use std::io::{BufRead, Seek, Write}; @@ -27,1481 +26,4 @@ pub(crate) fn blake2b256(data: &[u8]) -> [u8; 32] { } // All key structs were taken from js-chain-libs: -// https://github.com/Emurgo/js-chain-libs - -#[wasm_bindgen] -pub struct Bip32PrivateKey(crypto::SecretKey); - -#[wasm_bindgen] -impl Bip32PrivateKey { - /// derive this private key with the given index. - /// - /// # Security considerations - /// - /// * hard derivation index cannot be soft derived with the public key - /// - /// # Hard derivation vs Soft derivation - /// - /// If you pass an index below 0x80000000 then it is a soft derivation. - /// The advantage of soft derivation is that it is possible to derive the - /// public key too. I.e. derivation the private key with a soft derivation - /// index and then retrieving the associated public key is equivalent to - /// deriving the public key associated to the parent private key. - /// - /// Hard derivation index does not allow public key derivation. - /// - /// This is why deriving the private key should not fail while deriving - /// the public key may fail (if the derivation index is invalid). - /// - pub fn derive(&self, index: u32) -> Bip32PrivateKey { - Bip32PrivateKey(crypto::derive::derive_sk_ed25519(&self.0, index)) - } - - /// 128-byte xprv a key format in Cardano that some software still uses or requires - /// the traditional 96-byte xprv is simply encoded as - /// prv | chaincode - /// however, because some software may not know how to compute a public key from a private key, - /// the 128-byte inlines the public key in the following format - /// prv | pub | chaincode - /// so be careful if you see the term "xprv" as it could refer to either one - /// our library does not require the pub (instead we compute the pub key when needed) - pub fn from_128_xprv(bytes: &[u8]) -> Result { - let mut buf = [0; 96]; - buf[0..64].clone_from_slice(&bytes[0..64]); - buf[64..96].clone_from_slice(&bytes[96..128]); - - Bip32PrivateKey::from_bytes(&buf) - } - /// see from_128_xprv - pub fn to_128_xprv(&self) -> Vec { - let prv_key = self.to_raw_key().as_bytes(); - let pub_key = self.to_public().to_raw_key().as_bytes(); - let cc = self.chaincode(); - - let mut buf = [0; 128]; - buf[0..64].clone_from_slice(&prv_key); - buf[64..96].clone_from_slice(&pub_key); - buf[96..128].clone_from_slice(&cc); - buf.to_vec() - } - - pub fn generate_ed25519_bip32() -> Result { - OsRng::new() - .map(crypto::SecretKey::::generate) - .map(Bip32PrivateKey) - .map_err(|e| JsError::from_str(&format!("{}", e))) - } - - pub fn to_raw_key(&self) -> PrivateKey { - PrivateKey(key::EitherEd25519SecretKey::Extended( - crypto::derive::to_raw_sk(&self.0), - )) - } - - pub fn to_public(&self) -> Bip32PublicKey { - Bip32PublicKey(self.0.to_public().into()) - } - - pub fn from_bytes(bytes: &[u8]) -> Result { - crypto::SecretKey::::from_binary(bytes) - .map_err(|e| JsError::from_str(&format!("{}", e))) - .map(Bip32PrivateKey) - } - - pub fn as_bytes(&self) -> Vec { - self.0.as_ref().to_vec() - } - - pub fn from_bech32(bech32_str: &str) -> Result { - crypto::SecretKey::try_from_bech32_str(&bech32_str) - .map(Bip32PrivateKey) - .map_err(|_| JsError::from_str("Invalid secret key")) - } - - pub fn to_bech32(&self) -> String { - self.0.to_bech32_str() - } - - pub fn from_bip39_entropy(entropy: &[u8], password: &[u8]) -> Bip32PrivateKey { - Bip32PrivateKey(crypto::derive::from_bip39_entropy(&entropy, &password)) - } - - pub fn chaincode(&self) -> Vec { - const ED25519_PRIVATE_KEY_LENGTH: usize = 64; - const XPRV_SIZE: usize = 96; - self.0.as_ref()[ED25519_PRIVATE_KEY_LENGTH..XPRV_SIZE].to_vec() - } - - pub fn to_hex(&self) -> String { - hex::encode(self.as_bytes()) - } - - pub fn from_hex(hex_str: &str) -> Result { - match hex::decode(hex_str) { - Ok(data) => Ok(Self::from_bytes(data.as_ref())?), - Err(e) => Err(JsError::from_str(&e.to_string())), - } - } -} - -#[wasm_bindgen] -pub struct Bip32PublicKey(crypto::PublicKey); - -#[wasm_bindgen] -impl Bip32PublicKey { - /// derive this public key with the given index. - /// - /// # Errors - /// - /// If the index is not a soft derivation index (< 0x80000000) then - /// calling this method will fail. - /// - /// # Security considerations - /// - /// * hard derivation index cannot be soft derived with the public key - /// - /// # Hard derivation vs Soft derivation - /// - /// If you pass an index below 0x80000000 then it is a soft derivation. - /// The advantage of soft derivation is that it is possible to derive the - /// public key too. I.e. derivation the private key with a soft derivation - /// index and then retrieving the associated public key is equivalent to - /// deriving the public key associated to the parent private key. - /// - /// Hard derivation index does not allow public key derivation. - /// - /// This is why deriving the private key should not fail while deriving - /// the public key may fail (if the derivation index is invalid). - /// - pub fn derive(&self, index: u32) -> Result { - crypto::derive::derive_pk_ed25519(&self.0, index) - .map(Bip32PublicKey) - .map_err(|e| JsError::from_str(&format! {"{:?}", e})) - } - - pub fn to_raw_key(&self) -> PublicKey { - PublicKey(crypto::derive::to_raw_pk(&self.0)) - } - - pub fn from_bytes(bytes: &[u8]) -> Result { - crypto::PublicKey::::from_binary(bytes) - .map_err(|e| JsError::from_str(&format!("{}", e))) - .map(Bip32PublicKey) - } - - pub fn as_bytes(&self) -> Vec { - self.0.as_ref().to_vec() - } - - pub fn from_bech32(bech32_str: &str) -> Result { - crypto::PublicKey::try_from_bech32_str(&bech32_str) - .map(Bip32PublicKey) - .map_err(|e| JsError::from_str(&format!("{}", e))) - } - - pub fn to_bech32(&self) -> String { - self.0.to_bech32_str() - } - - pub fn chaincode(&self) -> Vec { - const ED25519_PUBLIC_KEY_LENGTH: usize = 32; - const XPUB_SIZE: usize = 64; - self.0.as_ref()[ED25519_PUBLIC_KEY_LENGTH..XPUB_SIZE].to_vec() - } - - pub fn to_hex(&self) -> String { - hex::encode(self.as_bytes()) - } - - pub fn from_hex(hex_str: &str) -> Result { - match hex::decode(hex_str) { - Ok(data) => Ok(Self::from_bytes(data.as_ref())?), - Err(e) => Err(JsError::from_str(&e.to_string())), - } - } -} - -#[wasm_bindgen] -pub struct PrivateKey(key::EitherEd25519SecretKey); - -impl From for PrivateKey { - fn from(secret_key: key::EitherEd25519SecretKey) -> PrivateKey { - PrivateKey(secret_key) - } -} - -#[wasm_bindgen] -impl PrivateKey { - pub fn to_public(&self) -> PublicKey { - self.0.to_public().into() - } - - pub fn generate_ed25519() -> Result { - OsRng::new() - .map(crypto::SecretKey::::generate) - .map(key::EitherEd25519SecretKey::Normal) - .map(PrivateKey) - .map_err(|e| JsError::from_str(&format!("{}", e))) - } - - pub fn generate_ed25519extended() -> Result { - OsRng::new() - .map(crypto::SecretKey::::generate) - .map(key::EitherEd25519SecretKey::Extended) - .map(PrivateKey) - .map_err(|e| JsError::from_str(&format!("{}", e))) - } - - /// Get private key from its bech32 representation - /// ```javascript - /// PrivateKey.from_bech32('ed25519_sk1ahfetf02qwwg4dkq7mgp4a25lx5vh9920cr5wnxmpzz9906qvm8qwvlts0'); - /// ``` - /// For an extended 25519 key - /// ```javascript - /// PrivateKey.from_bech32('ed25519e_sk1gqwl4szuwwh6d0yk3nsqcc6xxc3fpvjlevgwvt60df59v8zd8f8prazt8ln3lmz096ux3xvhhvm3ca9wj2yctdh3pnw0szrma07rt5gl748fp'); - /// ``` - pub fn from_bech32(bech32_str: &str) -> Result { - crypto::SecretKey::try_from_bech32_str(&bech32_str) - .map(key::EitherEd25519SecretKey::Extended) - .or_else(|_| { - crypto::SecretKey::try_from_bech32_str(&bech32_str) - .map(key::EitherEd25519SecretKey::Normal) - }) - .map(PrivateKey) - .map_err(|_| JsError::from_str("Invalid secret key")) - } - - pub fn to_bech32(&self) -> String { - match self.0 { - key::EitherEd25519SecretKey::Normal(ref secret) => secret.to_bech32_str(), - key::EitherEd25519SecretKey::Extended(ref secret) => secret.to_bech32_str(), - } - } - - pub fn as_bytes(&self) -> Vec { - match self.0 { - key::EitherEd25519SecretKey::Normal(ref secret) => secret.as_ref().to_vec(), - key::EitherEd25519SecretKey::Extended(ref secret) => secret.as_ref().to_vec(), - } - } - - pub fn from_extended_bytes(bytes: &[u8]) -> Result { - crypto::SecretKey::from_binary(bytes) - .map(key::EitherEd25519SecretKey::Extended) - .map(PrivateKey) - .map_err(|_| JsError::from_str("Invalid extended secret key")) - } - - pub fn from_normal_bytes(bytes: &[u8]) -> Result { - crypto::SecretKey::from_binary(bytes) - .map(key::EitherEd25519SecretKey::Normal) - .map(PrivateKey) - .map_err(|_| JsError::from_str("Invalid normal secret key")) - } - - pub fn sign(&self, message: &[u8]) -> Ed25519Signature { - Ed25519Signature(self.0.sign(&message.to_vec())) - } - - pub fn to_hex(&self) -> String { - hex::encode(self.as_bytes()) - } - - pub fn from_hex(hex_str: &str) -> Result { - let data: Vec = match hex::decode(hex_str) { - Ok(d) => d, - Err(e) => return Err(JsError::from_str(&e.to_string())), - }; - let data_slice: &[u8] = data.as_slice(); - crypto::SecretKey::from_binary(data_slice) - .map(key::EitherEd25519SecretKey::Normal) - .or_else(|_| { - crypto::SecretKey::from_binary(data_slice) - .map(key::EitherEd25519SecretKey::Extended) - }) - .map(PrivateKey) - .map_err(|_| JsError::from_str("Invalid secret key")) - } -} - -/// ED25519 key used as public key -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct PublicKey(crypto::PublicKey); - -impl From> for PublicKey { - fn from(key: crypto::PublicKey) -> PublicKey { - PublicKey(key) - } -} - -#[wasm_bindgen] -impl PublicKey { - /// Get public key from its bech32 representation - /// Example: - /// ```javascript - /// const pkey = PublicKey.from_bech32('ed25519_pk1dgaagyh470y66p899txcl3r0jaeaxu6yd7z2dxyk55qcycdml8gszkxze2'); - /// ``` - pub fn from_bech32(bech32_str: &str) -> Result { - crypto::PublicKey::try_from_bech32_str(&bech32_str) - .map(PublicKey) - .map_err(|_| JsError::from_str("Malformed public key")) - } - - pub fn to_bech32(&self) -> String { - self.0.to_bech32_str() - } - - pub fn as_bytes(&self) -> Vec { - self.0.as_ref().to_vec() - } - - pub fn from_bytes(bytes: &[u8]) -> Result { - crypto::PublicKey::from_binary(bytes) - .map_err(|e| JsError::from_str(&format!("{}", e))) - .map(PublicKey) - } - - pub fn verify(&self, data: &[u8], signature: &Ed25519Signature) -> bool { - signature.0.verify_slice(&self.0, data) == crypto::Verification::Success - } - - pub fn hash(&self) -> Ed25519KeyHash { - Ed25519KeyHash::from(blake2b224(self.as_bytes().as_ref())) - } - - pub fn to_hex(&self) -> String { - hex::encode(self.as_bytes()) - } - - pub fn from_hex(hex_str: &str) -> Result { - match hex::decode(hex_str) { - Ok(data) => Ok(Self::from_bytes(data.as_ref())?), - Err(e) => Err(JsError::from_str(&e.to_string())), - } - } -} - -impl serde::Serialize for PublicKey { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - serializer.serialize_str(&self.to_bech32()) - } -} - -impl<'de> serde::de::Deserialize<'de> for PublicKey { - fn deserialize(deserializer: D) -> Result - where - D: serde::de::Deserializer<'de>, - { - let s = ::deserialize(deserializer)?; - PublicKey::from_bech32(&s).map_err(|_e| { - serde::de::Error::invalid_value( - serde::de::Unexpected::Str(&s), - &"bech32 public key string", - ) - }) - } -} - -impl JsonSchema for PublicKey { - fn schema_name() -> String { - String::from("PublicKey") - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - String::json_schema(gen) - } - fn is_referenceable() -> bool { - String::is_referenceable() - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] -pub struct Vkey(PublicKey); - -impl_to_from!(Vkey); - -#[wasm_bindgen] -impl Vkey { - pub fn new(pk: &PublicKey) -> Self { - Self(pk.clone()) - } - - pub fn public_key(&self) -> PublicKey { - self.0.clone() - } -} - -impl cbor_event::se::Serialize for Vkey { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_bytes(&self.0.as_bytes()) - } -} - -impl Deserialize for Vkey { - fn deserialize(raw: &mut Deserializer) -> Result { - Ok(Self(PublicKey(crypto::PublicKey::from_binary( - raw.bytes()?.as_ref(), - )?))) - } -} - -#[wasm_bindgen] -#[derive(Clone)] -pub struct Vkeys(Vec); - -#[wasm_bindgen] -impl Vkeys { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> Vkey { - self.0[index].clone() - } - - pub fn add(&mut self, elem: &Vkey) { - self.0.push(elem.clone()); - } -} - -impl cbor_event::se::Serialize for Vkeys { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for Vkeys { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(Vkey::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("Vkeys"))?; - Ok(Self(arr)) - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] -pub struct Vkeywitness { - vkey: Vkey, - signature: Ed25519Signature, -} - -impl_to_from!(Vkeywitness); - -#[wasm_bindgen] -impl Vkeywitness { - pub fn new(vkey: &Vkey, signature: &Ed25519Signature) -> Self { - Self { - vkey: vkey.clone(), - signature: signature.clone(), - } - } - - pub fn vkey(&self) -> Vkey { - self.vkey.clone() - } - - pub fn signature(&self) -> Ed25519Signature { - self.signature.clone() - } -} - -impl cbor_event::se::Serialize for Vkeywitness { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - self.vkey.serialize(serializer)?; - self.signature.serialize(serializer) - } -} - -impl Deserialize for Vkeywitness { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let vkey = (|| -> Result<_, DeserializeError> { Ok(Vkey::deserialize(raw)?) })() - .map_err(|e| e.annotate("vkey"))?; - let signature = - (|| -> Result<_, DeserializeError> { Ok(Ed25519Signature::deserialize(raw)?) })() - .map_err(|e| e.annotate("signature"))?; - let ret = Ok(Vkeywitness::new(&vkey, &signature)); - match len { - cbor_event::Len::Len(n) => match n { - 2 => (), - _ => { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 2, len, "", - )) - .into()) - } - }, - cbor_event::Len::Indefinite => match raw.special()? { - cbor_event::Special::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("Vkeywitness")) - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] -pub struct Vkeywitnesses(pub(crate) Vec); - -impl_to_from!(Vkeywitnesses); - -#[wasm_bindgen] -impl Vkeywitnesses { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> Vkeywitness { - self.0[index].clone() - } - - pub fn add(&mut self, elem: &Vkeywitness) { - self.0.push(elem.clone()); - } -} - -impl cbor_event::se::Serialize for Vkeywitnesses { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for Vkeywitnesses { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == cbor_event::Type::Special { - assert_eq!(raw.special()?, cbor_event::Special::Break); - break; - } - arr.push(Vkeywitness::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("Vkeywitnesses"))?; - Ok(Self(arr)) - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] -pub struct BootstrapWitness { - vkey: Vkey, - signature: Ed25519Signature, - chain_code: Vec, - attributes: Vec, -} - -impl_to_from!(BootstrapWitness); - -#[wasm_bindgen] -impl BootstrapWitness { - pub fn vkey(&self) -> Vkey { - self.vkey.clone() - } - - pub fn signature(&self) -> Ed25519Signature { - self.signature.clone() - } - - pub fn chain_code(&self) -> Vec { - self.chain_code.clone() - } - - pub fn attributes(&self) -> Vec { - self.attributes.clone() - } - - pub fn new( - vkey: &Vkey, - signature: &Ed25519Signature, - chain_code: Vec, - attributes: Vec, - ) -> Self { - Self { - vkey: vkey.clone(), - signature: signature.clone(), - chain_code: chain_code, - attributes: attributes, - } - } -} - -impl cbor_event::se::Serialize for BootstrapWitness { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(4))?; - self.vkey.serialize(serializer)?; - self.signature.serialize(serializer)?; - serializer.write_bytes(&self.chain_code)?; - serializer.write_bytes(&self.attributes)?; - Ok(serializer) - } -} - -impl Deserialize for BootstrapWitness { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("BootstrapWitness")) - } -} - -impl DeserializeEmbeddedGroup for BootstrapWitness { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - _: cbor_event::Len, - ) -> Result { - let vkey = (|| -> Result<_, DeserializeError> { Ok(Vkey::deserialize(raw)?) })() - .map_err(|e| e.annotate("vkey"))?; - let signature = - (|| -> Result<_, DeserializeError> { Ok(Ed25519Signature::deserialize(raw)?) })() - .map_err(|e| e.annotate("signature"))?; - let chain_code = (|| -> Result<_, DeserializeError> { Ok(raw.bytes()?) })() - .map_err(|e| e.annotate("chain_code"))?; - let attributes = (|| -> Result<_, DeserializeError> { Ok(raw.bytes()?) })() - .map_err(|e| e.annotate("attributes"))?; - Ok(BootstrapWitness { - vkey, - signature, - chain_code, - attributes, - }) - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] -pub struct BootstrapWitnesses(Vec); - -#[wasm_bindgen] -impl BootstrapWitnesses { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> BootstrapWitness { - self.0[index].clone() - } - - pub fn add(&mut self, elem: &BootstrapWitness) { - self.0.push(elem.clone()); - } -} - -impl cbor_event::se::Serialize for BootstrapWitnesses { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for BootstrapWitnesses { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == cbor_event::Type::Special { - assert_eq!(raw.special()?, cbor_event::Special::Break); - break; - } - arr.push(BootstrapWitness::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("BootstrapWitnesses"))?; - Ok(Self(arr)) - } -} - -#[wasm_bindgen] -pub struct PublicKeys(Vec); - -#[wasm_bindgen] -impl PublicKeys { - #[wasm_bindgen(constructor)] - pub fn new() -> PublicKeys { - PublicKeys(vec![]) - } - - pub fn size(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> PublicKey { - self.0[index].clone() - } - - pub fn add(&mut self, key: &PublicKey) { - self.0.push(key.clone()); - } -} - -macro_rules! impl_signature { - ($name:ident, $signee_type:ty, $verifier_type:ty) => { - #[wasm_bindgen] - #[derive(Clone, Debug, Eq, PartialEq)] - pub struct $name(crypto::Signature<$signee_type, $verifier_type>); - - #[wasm_bindgen] - impl $name { - pub fn to_bytes(&self) -> Vec { - self.0.as_ref().to_vec() - } - - pub fn to_bech32(&self) -> String { - self.0.to_bech32_str() - } - - pub fn to_hex(&self) -> String { - hex::encode(&self.0.as_ref()) - } - - pub fn from_bech32(bech32_str: &str) -> Result<$name, JsError> { - crypto::Signature::try_from_bech32_str(&bech32_str) - .map($name) - .map_err(|e| JsError::from_str(&format!("{}", e))) - } - - pub fn from_hex(input: &str) -> Result<$name, JsError> { - crypto::Signature::from_str(input) - .map_err(|e| JsError::from_str(&format!("{:?}", e))) - .map($name) - } - } - - from_bytes!($name, bytes, { - crypto::Signature::from_binary(bytes.as_ref()) - .map_err(|e| { - DeserializeError::new(stringify!($name), DeserializeFailure::SignatureError(e)) - }) - .map($name) - }); - - impl cbor_event::se::Serialize for $name { - fn serialize<'se, W: std::io::Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_bytes(self.0.as_ref()) - } - } - - impl Deserialize for $name { - fn deserialize( - raw: &mut Deserializer, - ) -> Result { - Ok(Self(crypto::Signature::from_binary(raw.bytes()?.as_ref())?)) - } - } - - impl serde::Serialize for $name { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - serializer.serialize_str(&self.to_hex()) - } - } - - impl<'de> serde::de::Deserialize<'de> for $name { - fn deserialize(deserializer: D) -> Result - where - D: serde::de::Deserializer<'de>, - { - let s = ::deserialize(deserializer)?; - $name::from_hex(&s).map_err(|_e| { - serde::de::Error::invalid_value( - serde::de::Unexpected::Str(&s), - &"hex bytes for signature", - ) - }) - } - } - - impl JsonSchema for $name { - fn schema_name() -> String { - String::from(stringify!($name)) - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - String::json_schema(gen) - } - fn is_referenceable() -> bool { - String::is_referenceable() - } - } - }; -} - -impl_signature!(Ed25519Signature, Vec, crypto::Ed25519); -macro_rules! impl_hash_type { - ($name:ident, $byte_count:expr) => { - #[wasm_bindgen] - #[derive(Debug, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)] - pub struct $name(pub(crate) [u8; $byte_count]); - - // hash types are the only types in this library to not expect the entire CBOR structure. - // There is no CBOR binary tag here just the raw hash bytes. - from_bytes!($name, bytes, { - use std::convert::TryInto; - match bytes.len() { - $byte_count => Ok($name(bytes[..$byte_count].try_into().unwrap())), - other_len => { - let cbor_error = cbor_event::Error::WrongLen( - $byte_count, - cbor_event::Len::Len(other_len as u64), - "hash length", - ); - Err(DeserializeError::new( - stringify!($name), - DeserializeFailure::CBOR(cbor_error), - )) - } - } - }); - - #[wasm_bindgen] - impl $name { - // hash types are the only types in this library to not give the entire CBOR structure. - // There is no CBOR binary tag here just the raw hash bytes. - pub fn to_bytes(&self) -> Vec { - self.0.to_vec() - } - - pub fn to_bech32(&self, prefix: &str) -> Result { - bech32::encode(&prefix, self.to_bytes().to_base32()) - .map_err(|e| JsError::from_str(&format! {"{:?}", e})) - } - - pub fn from_bech32(bech_str: &str) -> Result<$name, JsError> { - let (_hrp, u5data) = - bech32::decode(bech_str).map_err(|e| JsError::from_str(&e.to_string()))?; - let data: Vec = bech32::FromBase32::from_base32(&u5data).unwrap(); - Ok(Self::from_bytes(data)?) - } - - pub fn to_hex(&self) -> String { - hex::encode(&self.0) - } - - pub fn from_hex(hex: &str) -> Result<$name, JsError> { - let bytes = hex::decode(hex) - .map_err(|e| JsError::from_str(&format!("hex decode failed: {}", e)))?; - Self::from_bytes(bytes).map_err(|e| JsError::from_str(&format!("{:?}", e))) - } - } - - // associated consts are not supported in wasm_bindgen - impl $name { - pub const BYTE_COUNT: usize = $byte_count; - } - - // can't expose [T; N] to wasm for new() but it's useful internally so we implement From trait - impl From<[u8; $byte_count]> for $name { - fn from(bytes: [u8; $byte_count]) -> Self { - Self(bytes) - } - } - - impl cbor_event::se::Serialize for $name { - fn serialize<'se, W: std::io::Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_bytes(self.0) - } - } - - impl Deserialize for $name { - fn deserialize( - raw: &mut Deserializer, - ) -> Result { - use std::convert::TryInto; - (|| -> Result { - let bytes = raw.bytes()?; - if bytes.len() != $byte_count { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - $byte_count, - cbor_event::Len::Len(bytes.len() as u64), - "hash length", - )) - .into()); - } - Ok($name(bytes[..$byte_count].try_into().unwrap())) - })() - .map_err(|e| e.annotate(stringify!($name))) - } - } - - impl serde::Serialize for $name { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - serializer.serialize_str(&self.to_hex()) - } - } - - impl<'de> serde::de::Deserialize<'de> for $name { - fn deserialize(deserializer: D) -> Result - where - D: serde::de::Deserializer<'de>, - { - let s = ::deserialize(deserializer)?; - $name::from_hex(&s).map_err(|_e| { - serde::de::Error::invalid_value( - serde::de::Unexpected::Str(&s), - &"hex bytes for hash", - ) - }) - } - } - - impl JsonSchema for $name { - fn schema_name() -> String { - String::from(stringify!($name)) - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - String::json_schema(gen) - } - fn is_referenceable() -> bool { - String::is_referenceable() - } - } - - impl Display for $name { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.to_hex()) - } - } - }; -} - -#[wasm_bindgen] -pub struct LegacyDaedalusPrivateKey(pub(crate) crypto::SecretKey); - -#[wasm_bindgen] -impl LegacyDaedalusPrivateKey { - pub fn from_bytes(bytes: &[u8]) -> Result { - crypto::SecretKey::::from_binary(bytes) - .map_err(|e| JsError::from_str(&format!("{}", e))) - .map(LegacyDaedalusPrivateKey) - } - - pub fn as_bytes(&self) -> Vec { - self.0.as_ref().to_vec() - } - - pub fn chaincode(&self) -> Vec { - const ED25519_PRIVATE_KEY_LENGTH: usize = 64; - const XPRV_SIZE: usize = 96; - self.0.as_ref()[ED25519_PRIVATE_KEY_LENGTH..XPRV_SIZE].to_vec() - } -} - -impl_hash_type!(Ed25519KeyHash, 28); -impl_hash_type!(ScriptHash, 28); -impl_hash_type!(AnchorDataHash, 32); -impl_hash_type!(TransactionHash, 32); -impl_hash_type!(GenesisDelegateHash, 28); -impl_hash_type!(GenesisHash, 28); -impl_hash_type!(AuxiliaryDataHash, 32); -impl_hash_type!(PoolMetadataHash, 32); -impl_hash_type!(VRFKeyHash, 32); -impl_hash_type!(BlockHash, 32); -impl_hash_type!(DataHash, 32); -impl_hash_type!(ScriptDataHash, 32); -// We might want to make these two vkeys normal classes later but for now it's just arbitrary bytes for us (used in block parsing) -impl_hash_type!(VRFVKey, 32); -impl_hash_type!(KESVKey, 32); -// same for this signature -//impl_hash_type!(KESSignature, 448); -// TODO: when >32 size trait implementations are out of nightly and into stable -// remove the following manual struct definition and use the above macro again if we -// don't have proper crypto implementations for it. -#[wasm_bindgen] -#[derive(Debug, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub struct KESSignature(pub(crate) Vec); - -#[wasm_bindgen] -impl KESSignature { - pub fn to_bytes(&self) -> Vec { - self.0.clone() - } -} - -// associated consts are not supported in wasm_bindgen -impl KESSignature { - pub const BYTE_COUNT: usize = 448; -} - -from_bytes!(KESSignature, bytes, { - match bytes.len() { - Self::BYTE_COUNT => Ok(KESSignature(bytes)), - other_len => { - let cbor_error = cbor_event::Error::WrongLen( - Self::BYTE_COUNT as u64, - cbor_event::Len::Len(other_len as u64), - "hash length", - ); - Err(DeserializeError::new( - "KESSignature", - DeserializeFailure::CBOR(cbor_error), - )) - } - } -}); - -impl cbor_event::se::Serialize for KESSignature { - fn serialize<'se, W: std::io::Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_bytes(&self.0) - } -} - -impl Deserialize for KESSignature { - fn deserialize( - raw: &mut Deserializer, - ) -> Result { - (|| -> Result { - let bytes = raw.bytes()?; - if bytes.len() != Self::BYTE_COUNT { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - Self::BYTE_COUNT as u64, - cbor_event::Len::Len(bytes.len() as u64), - "hash length", - )) - .into()); - } - Ok(KESSignature(bytes)) - })() - .map_err(|e| e.annotate("KESSignature")) - } -} - -impl serde::Serialize for KESSignature { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - serializer.serialize_str(&hex::encode(self.to_bytes())) - } -} - -impl<'de> serde::de::Deserialize<'de> for KESSignature { - fn deserialize(deserializer: D) -> Result - where - D: serde::de::Deserializer<'de>, - { - let s = ::deserialize(deserializer)?; - if let Ok(hex_bytes) = hex::decode(s.clone()) { - if let Ok(sig) = KESSignature::from_bytes(hex_bytes) { - return Ok(sig); - } - } - Err(serde::de::Error::invalid_value( - serde::de::Unexpected::Str(&s), - &"hex bytes for KESSignature", - )) - } -} - -impl JsonSchema for KESSignature { - fn schema_name() -> String { - String::from("KESSignature") - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - String::json_schema(gen) - } - fn is_referenceable() -> bool { - String::is_referenceable() - } -} - -// Evolving nonce type (used for Update's crypto) -#[wasm_bindgen] -#[derive( - Clone, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub struct Nonce { - hash: Option<[u8; 32]>, -} - -impl_to_from!(Nonce); - -// can't export consts via wasm_bindgen -impl Nonce { - pub const HASH_LEN: usize = 32; -} - -#[wasm_bindgen] -impl Nonce { - pub fn new_identity() -> Nonce { - Self { hash: None } - } - - pub fn new_from_hash(hash: Vec) -> Result { - use std::convert::TryInto; - match hash[..Self::HASH_LEN].try_into() { - Ok(bytes_correct_size) => Ok(Self { - hash: Some(bytes_correct_size), - }), - Err(e) => Err(JsError::from_str(&e.to_string())), - } - } - - pub fn get_hash(&self) -> Option> { - Some(self.hash?.to_vec()) - } -} - -impl cbor_event::se::Serialize for Nonce { - fn serialize<'se, W: std::io::Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - match &self.hash { - Some(hash) => { - serializer.write_array(cbor_event::Len::Len(2))?; - serializer.write_unsigned_integer(1)?; - serializer.write_bytes(hash) - } - None => { - serializer.write_array(cbor_event::Len::Len(1))?; - serializer.write_unsigned_integer(0) - } - } - } -} - -impl Deserialize for Nonce { - fn deserialize( - raw: &mut Deserializer, - ) -> Result { - (|| -> Result { - let len = raw.array()?; - let hash = match raw.unsigned_integer()? { - 0 => None, - 1 => { - let bytes = raw.bytes()?; - if bytes.len() != Self::HASH_LEN { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - Self::HASH_LEN as u64, - cbor_event::Len::Len(bytes.len() as u64), - "hash length", - )) - .into()); - } - Some(bytes[..Self::HASH_LEN].try_into().unwrap()) - } - _ => return Err(DeserializeFailure::NoVariantMatched.into()), - }; - match len { - cbor_event::Len::Len(n) => { - let correct_len = match n { - 1 => hash.is_none(), - 2 => hash.is_some(), - _ => false, - }; - if !correct_len { - return Err(DeserializeFailure::NoVariantMatched.into()); - } - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - }; - Ok(Self { hash }) - })() - .map_err(|e| e.annotate(stringify!($name))) - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct VRFCert { - output: Vec, - proof: Vec, -} - -impl VRFCert { - pub const PROOF_LEN: usize = 80; -} - -impl_to_from!(VRFCert); - -#[wasm_bindgen] -impl VRFCert { - pub fn output(&self) -> Vec { - self.output.clone() - } - - pub fn proof(&self) -> Vec { - self.proof.clone() - } - - pub fn new(output: Vec, proof: Vec) -> Result { - if proof.len() != Self::PROOF_LEN { - return Err(JsError::from_str(&format!( - "proof len must be {} - found {}", - Self::PROOF_LEN, - proof.len() - ))); - } - Ok(Self { - output: output, - proof: proof, - }) - } -} - -impl cbor_event::se::Serialize for VRFCert { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - serializer.write_bytes(&self.output)?; - serializer.write_bytes(&self.proof)?; - Ok(serializer) - } -} - -impl Deserialize for VRFCert { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let output = (|| -> Result<_, DeserializeError> { Ok(raw.bytes()?) })() - .map_err(|e| e.annotate("output"))?; - let proof = (|| -> Result<_, DeserializeError> { Ok(raw.bytes()?) })() - .map_err(|e| e.annotate("proof"))?; - if proof.len() != Self::PROOF_LEN { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - Self::PROOF_LEN as u64, - cbor_event::Len::Len(proof.len() as u64), - "proof length", - )) - .into()); - } - match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - Ok(VRFCert { output, proof }) - })() - .map_err(|e| e.annotate("VRFCert")) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn nonce_identity() { - let orig = Nonce::new_identity(); - let deser = Nonce::deserialize(&mut Deserializer::from(std::io::Cursor::new( - orig.to_bytes(), - ))) - .unwrap(); - assert_eq!(orig.to_bytes(), deser.to_bytes()); - } - - #[test] - fn nonce_hash() { - let orig = Nonce::new_from_hash(vec![ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - ]) - .unwrap(); - let deser = Nonce::deserialize(&mut Deserializer::from(std::io::Cursor::new( - orig.to_bytes(), - ))) - .unwrap(); - assert_eq!(orig.to_bytes(), deser.to_bytes()); - } - - #[test] - fn xprv_128_test() { - // art forum devote street sure rather head chuckle guard poverty release quote oak craft enemy - let entropy = [ - 0x0c, 0xcb, 0x74, 0xf3, 0x6b, 0x7d, 0xa1, 0x64, 0x9a, 0x81, 0x44, 0x67, 0x55, 0x22, - 0xd4, 0xd8, 0x09, 0x7c, 0x64, 0x12, - ]; - let root_key = Bip32PrivateKey::from_bip39_entropy(&entropy, &[]); - - assert_eq!(hex::encode(&root_key.as_bytes()), "b8f2bece9bdfe2b0282f5bad705562ac996efb6af96b648f4445ec44f47ad95c10e3d72f26ed075422a36ed8585c745a0e1150bcceba2357d058636991f38a3791e248de509c070d812ab2fda57860ac876bc489192c1ef4ce253c197ee219a4"); - let xprv_128 = root_key.to_128_xprv(); - // test the 128 xprv is the right format - assert_eq!(hex::encode(&xprv_128), "b8f2bece9bdfe2b0282f5bad705562ac996efb6af96b648f4445ec44f47ad95c10e3d72f26ed075422a36ed8585c745a0e1150bcceba2357d058636991f38a37cf76399a210de8720e9fa894e45e41e29ab525e30bc402801c076250d1585bcd91e248de509c070d812ab2fda57860ac876bc489192c1ef4ce253c197ee219a4"); - let root_key_copy = Bip32PrivateKey::from_128_xprv(&xprv_128).unwrap(); - - // test converting to and back is equivalent to the identity function - assert_eq!(root_key.to_bech32(), root_key_copy.to_bech32()); - } - - #[test] - fn chaincode_gen() { - // art forum devote street sure rather head chuckle guard poverty release quote oak craft enemy - let entropy = [ - 0x0c, 0xcb, 0x74, 0xf3, 0x6b, 0x7d, 0xa1, 0x64, 0x9a, 0x81, 0x44, 0x67, 0x55, 0x22, - 0xd4, 0xd8, 0x09, 0x7c, 0x64, 0x12, - ]; - let root_key = Bip32PrivateKey::from_bip39_entropy(&entropy, &[]); - - let prv_chaincode = root_key.chaincode(); - assert_eq!( - hex::encode(&prv_chaincode), - "91e248de509c070d812ab2fda57860ac876bc489192c1ef4ce253c197ee219a4" - ); - - let pub_chaincode = root_key.to_public().chaincode(); - assert_eq!( - hex::encode(&pub_chaincode), - "91e248de509c070d812ab2fda57860ac876bc489192c1ef4ce253c197ee219a4" - ); - } - - #[test] - fn private_key_from_bech32() { - let pk = PrivateKey::generate_ed25519().unwrap(); - let pk_ext = PrivateKey::generate_ed25519extended().unwrap(); - - assert_eq!( - PrivateKey::from_bech32(&pk.to_bech32()).unwrap().as_bytes(), - pk.as_bytes(), - ); - assert_eq!( - PrivateKey::from_bech32(&pk_ext.to_bech32()) - .unwrap() - .as_bytes(), - pk_ext.as_bytes(), - ); - - let er = PrivateKey::from_bech32("qwe"); - assert!(er.is_err()); - } -} +// https://github.com/Emurgo/js-chain-libs \ No newline at end of file diff --git a/rust/src/fakes.rs b/rust/src/fakes.rs index 4703a76c..46681f04 100644 --- a/rust/src/fakes.rs +++ b/rust/src/fakes.rs @@ -1,5 +1,5 @@ #![allow(dead_code)] -use crate::crypto::{ +use crate::{ AnchorDataHash, AuxiliaryDataHash, GenesisDelegateHash, GenesisHash, PoolMetadataHash, ScriptDataHash, ScriptHash, VRFKeyHash, }; use crate::{ diff --git a/rust/src/fees.rs b/rust/src/fees.rs index ef389da3..dfd0c413 100644 --- a/rust/src/fees.rs +++ b/rust/src/fees.rs @@ -330,7 +330,7 @@ mod tests { let mut certs = Certificates::new(); - let mut pool_owners = Ed25519KeyHashesSet::new(); + let mut pool_owners = Ed25519KeyHashes::new(); pool_owners.add( &PublicKey::from_bytes( &hex::decode("54d1a9c5ad69586ceeb839c438400c376c0bd34825fb4c17cc2f58c54e1437f3") diff --git a/rust/src/lib.rs b/rust/src/lib.rs index d3abcb57..f1e7e2ed 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -72,6 +72,7 @@ use std::cmp::Ordering; use std::collections::BTreeSet; use std::fmt; use std::fmt::Display; +use hashlink::LinkedHashMap; type DeltaCoin = Int; @@ -371,59 +372,6 @@ impl PartialEq for TransactionOutput { } } -#[wasm_bindgen] -#[derive( - Clone, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub struct Ed25519KeyHashes(pub(crate) Vec); - -impl_to_from!(Ed25519KeyHashes); - -#[wasm_bindgen] -impl Ed25519KeyHashes { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> Ed25519KeyHash { - self.0[index].clone() - } - - pub fn add(&mut self, elem: &Ed25519KeyHash) { - self.0.push(elem.clone()); - } - - pub fn to_option(&self) -> Option { - if self.len() > 0 { - Some(self.clone()) - } else { - None - } - } -} - -impl IntoIterator for Ed25519KeyHashes { - type Item = Ed25519KeyHash; - type IntoIter = std::vec::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.0.into_iter() - } -} - type Port = u16; #[wasm_bindgen] @@ -905,7 +853,7 @@ impl RewardAddresses { #[wasm_bindgen] #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub struct Withdrawals(linked_hash_map::LinkedHashMap); +pub struct Withdrawals(LinkedHashMap); impl_to_from!(Withdrawals); @@ -918,7 +866,7 @@ impl NoneOrEmpty for Withdrawals { #[wasm_bindgen] impl Withdrawals { pub fn new() -> Self { - Self(linked_hash_map::LinkedHashMap::new()) + Self(LinkedHashMap::new()) } pub fn len(&self) -> usize { @@ -977,81 +925,6 @@ impl JsonSchema for Withdrawals { } } -#[wasm_bindgen] -#[derive(Clone, Eq, PartialEq, Debug, serde::Serialize, serde::Deserialize, JsonSchema)] -pub struct TransactionWitnessSet { - vkeys: Option, - native_scripts: Option, - bootstraps: Option, - plutus_scripts: Option, - plutus_data: Option, - redeemers: Option, -} - -impl_to_from!(TransactionWitnessSet); - -#[wasm_bindgen] -impl TransactionWitnessSet { - pub fn set_vkeys(&mut self, vkeys: &Vkeywitnesses) { - self.vkeys = Some(vkeys.clone()) - } - - pub fn vkeys(&self) -> Option { - self.vkeys.clone() - } - - pub fn set_native_scripts(&mut self, native_scripts: &NativeScripts) { - self.native_scripts = Some(native_scripts.clone()) - } - - pub fn native_scripts(&self) -> Option { - self.native_scripts.clone() - } - - pub fn set_bootstraps(&mut self, bootstraps: &BootstrapWitnesses) { - self.bootstraps = Some(bootstraps.clone()) - } - - pub fn bootstraps(&self) -> Option { - self.bootstraps.clone() - } - - pub fn set_plutus_scripts(&mut self, plutus_scripts: &PlutusScripts) { - self.plutus_scripts = Some(plutus_scripts.clone()) - } - - pub fn plutus_scripts(&self) -> Option { - self.plutus_scripts.clone() - } - - pub fn set_plutus_data(&mut self, plutus_data: &PlutusList) { - self.plutus_data = Some(plutus_data.clone()) - } - - pub fn plutus_data(&self) -> Option { - self.plutus_data.clone() - } - - pub fn set_redeemers(&mut self, redeemers: &Redeemers) { - self.redeemers = Some(redeemers.clone()) - } - - pub fn redeemers(&self) -> Option { - self.redeemers.clone() - } - - pub fn new() -> Self { - Self { - vkeys: None, - native_scripts: None, - bootstraps: None, - plutus_scripts: None, - plutus_data: None, - redeemers: None, - } - } -} - #[wasm_bindgen] #[derive( Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, @@ -1457,8 +1330,8 @@ impl NativeScript { /// Returns a set of Ed25519KeyHashes /// contained within this script recursively on any depth level. /// The order of the keys in the result is not determined in any way. - pub fn get_required_signers(&self) -> Ed25519KeyHashesSet { - Ed25519KeyHashesSet::from(self) + pub fn get_required_signers(&self) -> Ed25519KeyHashes { + Ed25519KeyHashes::from(self) } } @@ -1591,7 +1464,7 @@ impl ScriptHashes { #[wasm_bindgen] #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] pub struct ProposedProtocolParameterUpdates( - linked_hash_map::LinkedHashMap, + LinkedHashMap, ); impl serde::Serialize for ProposedProtocolParameterUpdates { @@ -1633,7 +1506,7 @@ impl_to_from!(ProposedProtocolParameterUpdates); #[wasm_bindgen] impl ProposedProtocolParameterUpdates { pub fn new() -> Self { - Self(linked_hash_map::LinkedHashMap::new()) + Self(LinkedHashMap::new()) } pub fn len(&self) -> usize { @@ -1722,41 +1595,16 @@ impl TransactionBodies { } } -#[wasm_bindgen] -#[derive(Clone, serde::Serialize, serde::Deserialize, JsonSchema)] -pub struct TransactionWitnessSets(Vec); - -impl_to_from!(TransactionWitnessSets); - -#[wasm_bindgen] -impl TransactionWitnessSets { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> TransactionWitnessSet { - self.0[index].clone() - } - - pub fn add(&mut self, elem: &TransactionWitnessSet) { - self.0.push(elem.clone()); - } -} - pub type TransactionIndexes = Vec; #[wasm_bindgen] #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub struct AuxiliaryDataSet(linked_hash_map::LinkedHashMap); +pub struct AuxiliaryDataSet(LinkedHashMap); #[wasm_bindgen] impl AuxiliaryDataSet { pub fn new() -> Self { - Self(linked_hash_map::LinkedHashMap::new()) + Self(LinkedHashMap::new()) } pub fn len(&self) -> usize { @@ -2634,28 +2482,26 @@ impl NetworkId { } } -impl From<&NativeScript> for Ed25519KeyHashesSet { +impl From<&NativeScript> for Ed25519KeyHashes { fn from(script: &NativeScript) -> Self { match &script.0 { NativeScriptEnum::ScriptPubkey(spk) => { - let mut set = Ed25519KeyHashesSet::new(); + let mut set = Ed25519KeyHashes::new(); set.add_move(spk.addr_keyhash()); set } - NativeScriptEnum::ScriptAll(all) => Ed25519KeyHashesSet::from(&all.native_scripts), - NativeScriptEnum::ScriptAny(any) => Ed25519KeyHashesSet::from(&any.native_scripts), - NativeScriptEnum::ScriptNOfK(ofk) => Ed25519KeyHashesSet::from(&ofk.native_scripts), - _ => Ed25519KeyHashesSet::new(), + NativeScriptEnum::ScriptAll(all) => Ed25519KeyHashes::from(&all.native_scripts), + NativeScriptEnum::ScriptAny(any) => Ed25519KeyHashes::from(&any.native_scripts), + NativeScriptEnum::ScriptNOfK(ofk) => Ed25519KeyHashes::from(&ofk.native_scripts), + _ => Ed25519KeyHashes::new(), } } } -impl From<&NativeScripts> for Ed25519KeyHashesSet { +impl From<&NativeScripts> for Ed25519KeyHashes { fn from(scripts: &NativeScripts) -> Self { - scripts.0.iter().fold(Ed25519KeyHashesSet::new(), |mut set, s| { - Ed25519KeyHashesSet::from(s).0.iter().for_each(|pk| { - set.add_move(pk.clone()); - }); + scripts.0.iter().fold(Ed25519KeyHashes::new(), |mut set, s| { + set.extend_move(Ed25519KeyHashes::from(s)); set }) } diff --git a/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs b/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs index 154308aa..2acb1ed9 100644 --- a/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs +++ b/rust/src/protocol_types/certificates/move_instantaneous_rewards_cert.rs @@ -1,5 +1,6 @@ use crate::*; use std::vec::Vec; +use hashlink::LinkedHashMap; #[wasm_bindgen] #[derive( @@ -81,7 +82,7 @@ pub enum MIRKind { #[wasm_bindgen] #[derive(Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)] pub struct MIRToStakeCredentials { - pub(crate) rewards: linked_hash_map::LinkedHashMap, + pub(crate) rewards: LinkedHashMap, } impl_to_from!(MIRToStakeCredentials); @@ -90,7 +91,7 @@ impl_to_from!(MIRToStakeCredentials); impl MIRToStakeCredentials { pub fn new() -> Self { Self { - rewards: linked_hash_map::LinkedHashMap::new(), + rewards: LinkedHashMap::new(), } } @@ -106,8 +107,8 @@ impl MIRToStakeCredentials { self.rewards.get(cred).map(|v| v.clone()) } - pub fn keys(&self) -> CredentialsSet { - CredentialsSet::from_iter( + pub fn keys(&self) -> Credentials { + Credentials::from_iter( self.rewards .iter() .map(|(k, _v)| k.clone()) diff --git a/rust/src/protocol_types/certificates/pool_registration.rs b/rust/src/protocol_types/certificates/pool_registration.rs index bf2ac322..80904fd8 100644 --- a/rust/src/protocol_types/certificates/pool_registration.rs +++ b/rust/src/protocol_types/certificates/pool_registration.rs @@ -88,7 +88,7 @@ pub struct PoolParams { pub(crate) cost: Coin, pub(crate) margin: UnitInterval, pub(crate) reward_account: RewardAddress, - pub(crate) pool_owners: Ed25519KeyHashesSet, + pub(crate) pool_owners: Ed25519KeyHashes, pub(crate) relays: Relays, pub(crate) pool_metadata: Option, } @@ -121,7 +121,7 @@ impl PoolParams { self.reward_account.clone() } - pub fn pool_owners(&self) -> Ed25519KeyHashesSet { + pub fn pool_owners(&self) -> Ed25519KeyHashes { self.pool_owners.clone() } @@ -140,7 +140,7 @@ impl PoolParams { cost: &Coin, margin: &UnitInterval, reward_account: &RewardAddress, - pool_owners: &Ed25519KeyHashesSet, + pool_owners: &Ed25519KeyHashes, relays: &Relays, pool_metadata: Option, ) -> Self { diff --git a/rust/src/protocol_types/credential.rs b/rust/src/protocol_types/credential.rs new file mode 100644 index 00000000..02445df9 --- /dev/null +++ b/rust/src/protocol_types/credential.rs @@ -0,0 +1,89 @@ +use crate::*; + +#[derive( +Debug, +Clone, +Hash, +Eq, +Ord, +PartialEq, +PartialOrd, +serde::Serialize, +serde::Deserialize, +JsonSchema, +)] +pub enum CredType { + Key(Ed25519KeyHash), + Script(ScriptHash), +} + +#[wasm_bindgen] +#[repr(u8)] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub enum CredKind { + Key, + Script, +} + +#[wasm_bindgen] +#[derive( +Debug, +Clone, +Eq, +Hash, +Ord, +PartialEq, +PartialOrd, +serde::Serialize, +serde::Deserialize, +JsonSchema, +)] +pub struct Credential(pub(crate) CredType); + +#[wasm_bindgen] +impl Credential { + pub fn from_keyhash(hash: &Ed25519KeyHash) -> Self { + Credential(CredType::Key(hash.clone())) + } + + pub fn from_scripthash(hash: &ScriptHash) -> Self { + Credential(CredType::Script(hash.clone())) + } + + pub fn to_keyhash(&self) -> Option { + match &self.0 { + CredType::Key(hash) => Some(hash.clone()), + CredType::Script(_) => None, + } + } + + pub fn to_scripthash(&self) -> Option { + match &self.0 { + CredType::Key(_) => None, + CredType::Script(hash) => Some(hash.clone()), + } + } + + pub fn kind(&self) -> CredKind { + match &self.0 { + CredType::Key(_) => CredKind::Key, + CredType::Script(_) => CredKind::Script, + } + } + + pub fn has_script_hash(&self) -> bool { + match &self.0 { + CredType::Key(_) => false, + CredType::Script(_) => true, + } + } + + pub(crate) fn to_raw_bytes(&self) -> Vec { + match &self.0 { + CredType::Key(hash) => hash.to_bytes(), + CredType::Script(hash) => hash.to_bytes(), + } + } +} + +impl_to_from!(Credential); diff --git a/rust/src/protocol_types/credentials.rs b/rust/src/protocol_types/credentials.rs index 27ba1c0a..59ece34a 100644 --- a/rust/src/protocol_types/credentials.rs +++ b/rust/src/protocol_types/credentials.rs @@ -1,5 +1,5 @@ +use std::collections::HashSet; use crate::*; -use linked_hash_map::LinkedHashMap; #[wasm_bindgen] #[derive( @@ -10,163 +10,110 @@ use linked_hash_map::LinkedHashMap; Ord, PartialEq, PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, )] -pub struct CredentialsSet(pub(crate) BTreeSet); - -impl_to_from!(CredentialsSet); - -#[wasm_bindgen] -impl CredentialsSet { - pub fn new() -> Self { - Self(BTreeSet::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> Option { - self.0.iter().nth(index).cloned() - } - - pub fn add(&mut self, elem: &Credential) { - self.0.insert(elem.clone()); - } - - pub fn contains(&self, elem: &Credential) -> bool { - self.0.contains(elem) - } - - pub fn to_vec(&self) -> Credentials { - Credentials(self.0.iter().cloned().collect()) - } - - pub(crate) fn from_iter(iter: I) -> Self - where - I: IntoIterator, - { - Self(iter.into_iter().collect()) - } - - pub(crate) fn add_move(&mut self, elem: Credential) { - self.0.insert(elem); - } +pub struct Credentials { + pub(crate) credentials: Vec, + pub(crate) dedup: BTreeSet } -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct Credentials(pub(crate) Vec); - impl_to_from!(Credentials); #[wasm_bindgen] impl Credentials { pub fn new() -> Self { - Self(Vec::new()) + Self { + credentials: Vec::new(), + dedup: BTreeSet::new(), + } } pub fn len(&self) -> usize { - self.0.len() + self.credentials.len() } pub fn get(&self, index: usize) -> Credential { - self.0[index].clone() + self.credentials[index].clone() } pub fn add(&mut self, elem: &Credential) { - self.0.push(elem.clone()); + if self.dedup.insert(elem.clone()) { + self.credentials.push(elem.clone()); + } } -} -#[derive( - Debug, - Clone, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub enum CredType { - Key(Ed25519KeyHash), - Script(ScriptHash), -} - -#[wasm_bindgen] -#[repr(u8)] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub enum CredKind { - Key, - Script, -} - -#[wasm_bindgen] -#[derive( - Debug, - Clone, - Eq, - Hash, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub struct Credential(pub(crate) CredType); - -#[wasm_bindgen] -impl Credential { - pub fn from_keyhash(hash: &Ed25519KeyHash) -> Self { - Credential(CredType::Key(hash.clone())) + pub(crate) fn add_move(&mut self, elem: Credential) { + if self.dedup.insert(elem.clone()) { + self.credentials.push(elem); + } } - pub fn from_scripthash(hash: &ScriptHash) -> Self { - Credential(CredType::Script(hash.clone())) + pub(crate) fn contains(&self, elem: &Credential) -> bool { + self.dedup.contains(elem) } - pub fn to_keyhash(&self) -> Option { - match &self.0 { - CredType::Key(hash) => Some(hash.clone()), - CredType::Script(_) => None, + pub(crate) fn from_vec(vec: Vec) -> Self { + let mut dedup = BTreeSet::new(); + let mut credentials = Vec::new(); + for elem in vec { + if dedup.insert(elem.clone()) { + credentials.push(elem); + } + } + Self { + credentials, + dedup } } - pub fn to_scripthash(&self) -> Option { - match &self.0 { - CredType::Key(_) => None, - CredType::Script(hash) => Some(hash.clone()), + pub(crate) fn from_iter(iter: impl IntoIterator) -> Self { + let mut dedup = BTreeSet::new(); + let mut credentials = Vec::new(); + for elem in iter { + if dedup.insert(elem.clone()) { + credentials.push(elem); + } + } + Self { + credentials, + dedup } } - pub fn kind(&self) -> CredKind { - match &self.0 { - CredType::Key(_) => CredKind::Key, - CredType::Script(_) => CredKind::Script, - } + pub(crate) fn to_vec(&self) -> &Vec { + &self.credentials } +} - pub fn has_script_hash(&self) -> bool { - match &self.0 { - CredType::Key(_) => false, - CredType::Script(_) => true, - } + +impl serde::Serialize for Credentials { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + self.credentials.serialize(serializer) } +} - pub(crate) fn to_raw_bytes(&self) -> Vec { - match &self.0 { - CredType::Key(hash) => hash.to_bytes(), - CredType::Script(hash) => hash.to_bytes(), - } +impl<'de> serde::de::Deserialize<'de> for Credentials { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let vec = as serde::de::Deserialize>::deserialize( + deserializer, + )?; + Ok(Self::from_vec(vec)) } } -impl_to_from!(Credential); +impl JsonSchema for Credentials { + fn schema_name() -> String { + String::from("Credentials") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + Vec::::json_schema(gen) + } + fn is_referenceable() -> bool { + Vec::::is_referenceable() + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/crypto/bip32_private_key.rs b/rust/src/protocol_types/crypto/bip32_private_key.rs new file mode 100644 index 00000000..b94639ad --- /dev/null +++ b/rust/src/protocol_types/crypto/bip32_private_key.rs @@ -0,0 +1,119 @@ +use crate::*; +use crate::impl_mockchain::key; +use rand_os::OsRng; +use crate::chain_crypto::bech32::Bech32; + +#[wasm_bindgen] +pub struct Bip32PrivateKey(chain_crypto::SecretKey); + +#[wasm_bindgen] +impl Bip32PrivateKey { + /// derive this private key with the given index. + /// + /// # Security considerations + /// + /// * hard derivation index cannot be soft derived with the public key + /// + /// # Hard derivation vs Soft derivation + /// + /// If you pass an index below 0x80000000 then it is a soft derivation. + /// The advantage of soft derivation is that it is possible to derive the + /// public key too. I.e. derivation the private key with a soft derivation + /// index and then retrieving the associated public key is equivalent to + /// deriving the public key associated to the parent private key. + /// + /// Hard derivation index does not allow public key derivation. + /// + /// This is why deriving the private key should not fail while deriving + /// the public key may fail (if the derivation index is invalid). + /// + pub fn derive(&self, index: u32) -> Bip32PrivateKey { + Bip32PrivateKey(crate::chain_crypto::derive::derive_sk_ed25519(&self.0, index)) + } + + /// 128-byte xprv a key format in Cardano that some software still uses or requires + /// the traditional 96-byte xprv is simply encoded as + /// prv | chaincode + /// however, because some software may not know how to compute a public key from a private key, + /// the 128-byte inlines the public key in the following format + /// prv | pub | chaincode + /// so be careful if you see the term "xprv" as it could refer to either one + /// our library does not require the pub (instead we compute the pub key when needed) + pub fn from_128_xprv(bytes: &[u8]) -> Result { + let mut buf = [0; 96]; + buf[0..64].clone_from_slice(&bytes[0..64]); + buf[64..96].clone_from_slice(&bytes[96..128]); + + Bip32PrivateKey::from_bytes(&buf) + } + /// see from_128_xprv + pub fn to_128_xprv(&self) -> Vec { + let prv_key = self.to_raw_key().as_bytes(); + let pub_key = self.to_public().to_raw_key().as_bytes(); + let cc = self.chaincode(); + + let mut buf = [0; 128]; + buf[0..64].clone_from_slice(&prv_key); + buf[64..96].clone_from_slice(&pub_key); + buf[96..128].clone_from_slice(&cc); + buf.to_vec() + } + + pub fn generate_ed25519_bip32() -> Result { + OsRng::new() + .map(crate::chain_crypto::SecretKey::::generate) + .map(Bip32PrivateKey) + .map_err(|e| JsError::from_str(&format!("{}", e))) + } + + pub fn to_raw_key(&self) -> PrivateKey { + PrivateKey(key::EitherEd25519SecretKey::Extended( + crate::chain_crypto::derive::to_raw_sk(&self.0), + )) + } + + pub fn to_public(&self) -> Bip32PublicKey { + Bip32PublicKey(self.0.to_public().into()) + } + + pub fn from_bytes(bytes: &[u8]) -> Result { + crate::chain_crypto::SecretKey::::from_binary(bytes) + .map_err(|e| JsError::from_str(&format!("{}", e))) + .map(Bip32PrivateKey) + } + + pub fn as_bytes(&self) -> Vec { + self.0.as_ref().to_vec() + } + + pub fn from_bech32(bech32_str: &str) -> Result { + crate::chain_crypto::SecretKey::try_from_bech32_str(&bech32_str) + .map(Bip32PrivateKey) + .map_err(|_| JsError::from_str("Invalid secret key")) + } + + pub fn to_bech32(&self) -> String { + self.0.to_bech32_str() + } + + pub fn from_bip39_entropy(entropy: &[u8], password: &[u8]) -> Bip32PrivateKey { + Bip32PrivateKey(crate::chain_crypto::derive::from_bip39_entropy(&entropy, &password)) + } + + pub fn chaincode(&self) -> Vec { + const ED25519_PRIVATE_KEY_LENGTH: usize = 64; + const XPRV_SIZE: usize = 96; + self.0.as_ref()[ED25519_PRIVATE_KEY_LENGTH..XPRV_SIZE].to_vec() + } + + pub fn to_hex(&self) -> String { + hex::encode(self.as_bytes()) + } + + pub fn from_hex(hex_str: &str) -> Result { + match hex::decode(hex_str) { + Ok(data) => Ok(Self::from_bytes(data.as_ref())?), + Err(e) => Err(JsError::from_str(&e.to_string())), + } + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/crypto/bip32_public_key.rs b/rust/src/protocol_types/crypto/bip32_public_key.rs new file mode 100644 index 00000000..8741959f --- /dev/null +++ b/rust/src/protocol_types/crypto/bip32_public_key.rs @@ -0,0 +1,79 @@ +use crate::{JsError, PublicKey, wasm_bindgen}; +use crate::chain_crypto::bech32::Bech32; + +#[wasm_bindgen] +pub struct Bip32PublicKey(pub(crate) crate::chain_crypto::PublicKey); + +#[wasm_bindgen] +impl Bip32PublicKey { + /// derive this public key with the given index. + /// + /// # Errors + /// + /// If the index is not a soft derivation index (< 0x80000000) then + /// calling this method will fail. + /// + /// # Security considerations + /// + /// * hard derivation index cannot be soft derived with the public key + /// + /// # Hard derivation vs Soft derivation + /// + /// If you pass an index below 0x80000000 then it is a soft derivation. + /// The advantage of soft derivation is that it is possible to derive the + /// public key too. I.e. derivation the private key with a soft derivation + /// index and then retrieving the associated public key is equivalent to + /// deriving the public key associated to the parent private key. + /// + /// Hard derivation index does not allow public key derivation. + /// + /// This is why deriving the private key should not fail while deriving + /// the public key may fail (if the derivation index is invalid). + /// + pub fn derive(&self, index: u32) -> Result { + crate::chain_crypto::derive::derive_pk_ed25519(&self.0, index) + .map(Bip32PublicKey) + .map_err(|e| JsError::from_str(&format! {"{:?}", e})) + } + + pub fn to_raw_key(&self) -> PublicKey { + PublicKey(crate::chain_crypto::derive::to_raw_pk(&self.0)) + } + + pub fn from_bytes(bytes: &[u8]) -> Result { + crate::chain_crypto::PublicKey::::from_binary(bytes) + .map_err(|e| JsError::from_str(&format!("{}", e))) + .map(Bip32PublicKey) + } + + pub fn as_bytes(&self) -> Vec { + self.0.as_ref().to_vec() + } + + pub fn from_bech32(bech32_str: &str) -> Result { + crate::chain_crypto::PublicKey::try_from_bech32_str(&bech32_str) + .map(Bip32PublicKey) + .map_err(|e| JsError::from_str(&format!("{}", e))) + } + + pub fn to_bech32(&self) -> String { + self.0.to_bech32_str() + } + + pub fn chaincode(&self) -> Vec { + const ED25519_PUBLIC_KEY_LENGTH: usize = 32; + const XPUB_SIZE: usize = 64; + self.0.as_ref()[ED25519_PUBLIC_KEY_LENGTH..XPUB_SIZE].to_vec() + } + + pub fn to_hex(&self) -> String { + hex::encode(self.as_bytes()) + } + + pub fn from_hex(hex_str: &str) -> Result { + match hex::decode(hex_str) { + Ok(data) => Ok(Self::from_bytes(data.as_ref())?), + Err(e) => Err(JsError::from_str(&e.to_string())), + } + } +} diff --git a/rust/src/protocol_types/crypto/impl_hash_type_macro.rs b/rust/src/protocol_types/crypto/impl_hash_type_macro.rs new file mode 100644 index 00000000..085b77b8 --- /dev/null +++ b/rust/src/protocol_types/crypto/impl_hash_type_macro.rs @@ -0,0 +1,144 @@ +#[macro_export] +macro_rules! impl_hash_type { + ($name:ident, $byte_count:expr) => { + #[wasm_bindgen] + #[derive(Debug, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)] + pub struct $name(pub(crate) [u8; $byte_count]); + + // hash types are the only types in this library to not expect the entire CBOR structure. + // There is no CBOR binary tag here just the raw hash bytes. + from_bytes!($name, bytes, { + use std::convert::TryInto; + match bytes.len() { + $byte_count => Ok($name(bytes[..$byte_count].try_into().unwrap())), + other_len => { + let cbor_error = cbor_event::Error::WrongLen( + $byte_count, + cbor_event::Len::Len(other_len as u64), + "hash length", + ); + Err(DeserializeError::new( + stringify!($name), + DeserializeFailure::CBOR(cbor_error), + )) + } + } + }); + + #[wasm_bindgen] + impl $name { + // hash types are the only types in this library to not give the entire CBOR structure. + // There is no CBOR binary tag here just the raw hash bytes. + pub fn to_bytes(&self) -> Vec { + self.0.to_vec() + } + + pub fn to_bech32(&self, prefix: &str) -> Result { + use bech32::ToBase32; + bech32::encode(&prefix, self.to_bytes().to_base32()) + .map_err(|e| JsError::from_str(&format! {"{:?}", e})) + } + + pub fn from_bech32(bech_str: &str) -> Result<$name, JsError> { + let (_hrp, u5data) = + bech32::decode(bech_str).map_err(|e| JsError::from_str(&e.to_string()))?; + let data: Vec = bech32::FromBase32::from_base32(&u5data).unwrap(); + Ok(Self::from_bytes(data)?) + } + + pub fn to_hex(&self) -> String { + hex::encode(&self.0) + } + + pub fn from_hex(hex: &str) -> Result<$name, JsError> { + let bytes = hex::decode(hex) + .map_err(|e| JsError::from_str(&format!("hex decode failed: {}", e)))?; + Self::from_bytes(bytes).map_err(|e| JsError::from_str(&format!("{:?}", e))) + } + } + + // associated consts are not supported in wasm_bindgen + impl $name { + pub const BYTE_COUNT: usize = $byte_count; + } + + // can't expose [T; N] to wasm for new() but it's useful internally so we implement From trait + impl From<[u8; $byte_count]> for $name { + fn from(bytes: [u8; $byte_count]) -> Self { + Self(bytes) + } + } + + impl cbor_event::se::Serialize for $name { + fn serialize<'se, W: std::io::Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_bytes(self.0) + } + } + + impl Deserialize for $name { + fn deserialize( + raw: &mut Deserializer, + ) -> Result { + use std::convert::TryInto; + (|| -> Result { + let bytes = raw.bytes()?; + if bytes.len() != $byte_count { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + $byte_count, + cbor_event::Len::Len(bytes.len() as u64), + "hash length", + )) + .into()); + } + Ok($name(bytes[..$byte_count].try_into().unwrap())) + })() + .map_err(|e| e.annotate(stringify!($name))) + } + } + + impl serde::Serialize for $name { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&self.to_hex()) + } + } + + impl<'de> serde::de::Deserialize<'de> for $name { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = ::deserialize(deserializer)?; + $name::from_hex(&s).map_err(|_e| { + serde::de::Error::invalid_value( + serde::de::Unexpected::Str(&s), + &"hex bytes for hash", + ) + }) + } + } + + impl JsonSchema for $name { + fn schema_name() -> String { + String::from(stringify!($name)) + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + String::json_schema(gen) + } + fn is_referenceable() -> bool { + String::is_referenceable() + } + } + + impl Display for $name { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.to_hex()) + } + } + }; +} \ No newline at end of file diff --git a/rust/src/protocol_types/crypto/impl_signature_macro.rs b/rust/src/protocol_types/crypto/impl_signature_macro.rs new file mode 100644 index 00000000..747d5774 --- /dev/null +++ b/rust/src/protocol_types/crypto/impl_signature_macro.rs @@ -0,0 +1,98 @@ +#[macro_export] +macro_rules! impl_signature { + ($name:ident, $signee_type:ty, $verifier_type:ty) => { + #[wasm_bindgen] + #[derive(Clone, Debug, Hash, Eq, PartialEq)] + pub struct $name(pub (crate) chain_crypto::Signature<$signee_type, $verifier_type>); + + #[wasm_bindgen] + impl $name { + pub fn to_bytes(&self) -> Vec { + self.0.as_ref().to_vec() + } + + pub fn to_bech32(&self) -> String { + use crate::chain_crypto::bech32::Bech32; + self.0.to_bech32_str() + } + + pub fn to_hex(&self) -> String { + hex::encode(&self.0.as_ref()) + } + + pub fn from_bech32(bech32_str: &str) -> Result<$name, JsError> { + use crate::chain_crypto::bech32::Bech32; + chain_crypto::Signature::try_from_bech32_str(&bech32_str) + .map($name) + .map_err(|e| JsError::from_str(&format!("{}", e))) + } + + pub fn from_hex(input: &str) -> Result<$name, JsError> { + chain_crypto::Signature::from_str(input) + .map_err(|e| JsError::from_str(&format!("{:?}", e))) + .map($name) + } + } + + from_bytes!($name, bytes, { + chain_crypto::Signature::from_binary(bytes.as_ref()) + .map_err(|e| { + DeserializeError::new(stringify!($name), DeserializeFailure::SignatureError(e)) + }) + .map($name) + }); + + impl cbor_event::se::Serialize for $name { + fn serialize<'se, W: std::io::Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_bytes(self.0.as_ref()) + } + } + + impl Deserialize for $name { + fn deserialize( + raw: &mut Deserializer, + ) -> Result { + Ok(Self(chain_crypto::Signature::from_binary(raw.bytes()?.as_ref())?)) + } + } + + impl serde::Serialize for $name { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&self.to_hex()) + } + } + + impl<'de> serde::de::Deserialize<'de> for $name { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = ::deserialize(deserializer)?; + $name::from_hex(&s).map_err(|_e| { + serde::de::Error::invalid_value( + serde::de::Unexpected::Str(&s), + &"hex bytes for signature", + ) + }) + } + } + + impl JsonSchema for $name { + fn schema_name() -> String { + String::from(stringify!($name)) + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + String::json_schema(gen) + } + fn is_referenceable() -> bool { + String::is_referenceable() + } + } + }; +} \ No newline at end of file diff --git a/rust/src/protocol_types/crypto/kes_signature.rs b/rust/src/protocol_types/crypto/kes_signature.rs new file mode 100644 index 00000000..b04e6c1f --- /dev/null +++ b/rust/src/protocol_types/crypto/kes_signature.rs @@ -0,0 +1,73 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Debug, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct KESSignature(pub(crate) Vec); + +#[wasm_bindgen] +impl KESSignature { + pub fn to_bytes(&self) -> Vec { + self.0.clone() + } +} + +// associated consts are not supported in wasm_bindgen +impl KESSignature { + pub const BYTE_COUNT: usize = 448; +} + +from_bytes!(KESSignature, bytes, { + match bytes.len() { + Self::BYTE_COUNT => Ok(KESSignature(bytes)), + other_len => { + let cbor_error = cbor_event::Error::WrongLen( + Self::BYTE_COUNT as u64, + cbor_event::Len::Len(other_len as u64), + "hash length", + ); + Err(DeserializeError::new( + "KESSignature", + DeserializeFailure::CBOR(cbor_error), + )) + } + } +}); + +impl serde::Serialize for KESSignature { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&hex::encode(self.to_bytes())) + } +} + +impl<'de> serde::de::Deserialize<'de> for KESSignature { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = ::deserialize(deserializer)?; + if let Ok(hex_bytes) = hex::decode(s.clone()) { + if let Ok(sig) = KESSignature::from_bytes(hex_bytes) { + return Ok(sig); + } + } + Err(serde::de::Error::invalid_value( + serde::de::Unexpected::Str(&s), + &"hex bytes for KESSignature", + )) + } +} + +impl JsonSchema for KESSignature { + fn schema_name() -> String { + String::from("KESSignature") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + String::json_schema(gen) + } + fn is_referenceable() -> bool { + String::is_referenceable() + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/crypto/legacy_daedalus_private_key.rs b/rust/src/protocol_types/crypto/legacy_daedalus_private_key.rs new file mode 100644 index 00000000..e80f8a18 --- /dev/null +++ b/rust/src/protocol_types/crypto/legacy_daedalus_private_key.rs @@ -0,0 +1,24 @@ +use crate::*; +use crate::chain_crypto as crypto; + +#[wasm_bindgen] +pub struct LegacyDaedalusPrivateKey(pub(crate) crypto::SecretKey); + +#[wasm_bindgen] +impl LegacyDaedalusPrivateKey { + pub fn from_bytes(bytes: &[u8]) -> Result { + crypto::SecretKey::::from_binary(bytes) + .map_err(|e| JsError::from_str(&format!("{}", e))) + .map(LegacyDaedalusPrivateKey) + } + + pub fn as_bytes(&self) -> Vec { + self.0.as_ref().to_vec() + } + + pub fn chaincode(&self) -> Vec { + const ED25519_PRIVATE_KEY_LENGTH: usize = 64; + const XPRV_SIZE: usize = 96; + self.0.as_ref()[ED25519_PRIVATE_KEY_LENGTH..XPRV_SIZE].to_vec() + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/crypto/macro_implemented_hash_types.rs b/rust/src/protocol_types/crypto/macro_implemented_hash_types.rs new file mode 100644 index 00000000..f32c3cf8 --- /dev/null +++ b/rust/src/protocol_types/crypto/macro_implemented_hash_types.rs @@ -0,0 +1,22 @@ +use crate::*; + +impl_hash_type!(Ed25519KeyHash, 28); +impl_hash_type!(ScriptHash, 28); +impl_hash_type!(AnchorDataHash, 32); +impl_hash_type!(TransactionHash, 32); +impl_hash_type!(GenesisDelegateHash, 28); +impl_hash_type!(GenesisHash, 28); +impl_hash_type!(AuxiliaryDataHash, 32); +impl_hash_type!(PoolMetadataHash, 32); +impl_hash_type!(VRFKeyHash, 32); +impl_hash_type!(BlockHash, 32); +impl_hash_type!(DataHash, 32); +impl_hash_type!(ScriptDataHash, 32); +// We might want to make these two vkeys normal classes later but for now it's just arbitrary bytes for us (used in block parsing) +impl_hash_type!(VRFVKey, 32); +impl_hash_type!(KESVKey, 32); +// same for this signature +//impl_hash_type!(KESSignature, 448); +// TODO: when >32 size trait implementations are out of nightly and into stable +// remove the following manual struct definition and use the above macro again if we +// don't have proper crypto implementations for it. \ No newline at end of file diff --git a/rust/src/protocol_types/crypto/macro_implemented_signature_types.rs b/rust/src/protocol_types/crypto/macro_implemented_signature_types.rs new file mode 100644 index 00000000..94bb8986 --- /dev/null +++ b/rust/src/protocol_types/crypto/macro_implemented_signature_types.rs @@ -0,0 +1,3 @@ +use crate::*; + +impl_signature!(Ed25519Signature, Vec, chain_crypto::Ed25519); \ No newline at end of file diff --git a/rust/src/protocol_types/crypto/mod.rs b/rust/src/protocol_types/crypto/mod.rs new file mode 100644 index 00000000..2fda0a36 --- /dev/null +++ b/rust/src/protocol_types/crypto/mod.rs @@ -0,0 +1,40 @@ +mod impl_signature_macro; +mod impl_hash_type_macro; + +mod bip32_private_key; +pub use bip32_private_key::*; + +mod bip32_public_key; +pub use bip32_public_key::*; + +mod private_key; +pub use private_key::*; + +mod public_key; +pub use public_key::*; + +mod macro_implemented_signature_types; +pub use macro_implemented_signature_types::*; + +mod macro_implemented_hash_types; +pub use macro_implemented_hash_types::*; + +mod vkey; +pub use vkey::*; +mod vkeys; +pub use vkeys::*; + +mod public_keys; +pub use public_keys::*; + +mod legacy_daedalus_private_key; +pub use legacy_daedalus_private_key::*; + +mod kes_signature; +pub use kes_signature::*; + +mod nonce; +pub use nonce::*; + +mod vrf_cert; +pub use vrf_cert::*; \ No newline at end of file diff --git a/rust/src/protocol_types/crypto/nonce.rs b/rust/src/protocol_types/crypto/nonce.rs new file mode 100644 index 00000000..6296d69e --- /dev/null +++ b/rust/src/protocol_types/crypto/nonce.rs @@ -0,0 +1,47 @@ +use crate::*; + +// Evolving nonce type (used for Update's crypto) +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct Nonce { + pub(crate) hash: Option<[u8; 32]>, +} + +impl_to_from!(Nonce); + +// can't export consts via wasm_bindgen +impl Nonce { + pub const HASH_LEN: usize = 32; +} + +#[wasm_bindgen] +impl Nonce { + pub fn new_identity() -> Nonce { + Self { hash: None } + } + + pub fn new_from_hash(hash: Vec) -> Result { + use std::convert::TryInto; + match hash[..Self::HASH_LEN].try_into() { + Ok(bytes_correct_size) => Ok(Self { + hash: Some(bytes_correct_size), + }), + Err(e) => Err(JsError::from_str(&e.to_string())), + } + } + + pub fn get_hash(&self) -> Option> { + Some(self.hash?.to_vec()) + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/crypto/private_key.rs b/rust/src/protocol_types/crypto/private_key.rs new file mode 100644 index 00000000..9b011f56 --- /dev/null +++ b/rust/src/protocol_types/crypto/private_key.rs @@ -0,0 +1,107 @@ +use crate::{Ed25519Signature, JsError, PublicKey, wasm_bindgen}; +use crate::impl_mockchain::key; +use rand_os::OsRng; +use crate::chain_crypto::bech32::Bech32; + +#[wasm_bindgen] +pub struct PrivateKey(pub(crate) key::EitherEd25519SecretKey); + +impl From for PrivateKey { + fn from(secret_key: key::EitherEd25519SecretKey) -> PrivateKey { + PrivateKey(secret_key) + } +} + +#[wasm_bindgen] +impl PrivateKey { + pub fn to_public(&self) -> PublicKey { + self.0.to_public().into() + } + + pub fn generate_ed25519() -> Result { + OsRng::new() + .map(crate::chain_crypto::SecretKey::::generate) + .map(key::EitherEd25519SecretKey::Normal) + .map(PrivateKey) + .map_err(|e| JsError::from_str(&format!("{}", e))) + } + + pub fn generate_ed25519extended() -> Result { + OsRng::new() + .map(crate::chain_crypto::SecretKey::::generate) + .map(key::EitherEd25519SecretKey::Extended) + .map(PrivateKey) + .map_err(|e| JsError::from_str(&format!("{}", e))) + } + + /// Get private key from its bech32 representation + /// ```javascript + /// PrivateKey.from_bech32('ed25519_sk1ahfetf02qwwg4dkq7mgp4a25lx5vh9920cr5wnxmpzz9906qvm8qwvlts0'); + /// ``` + /// For an extended 25519 key + /// ```javascript + /// PrivateKey.from_bech32('ed25519e_sk1gqwl4szuwwh6d0yk3nsqcc6xxc3fpvjlevgwvt60df59v8zd8f8prazt8ln3lmz096ux3xvhhvm3ca9wj2yctdh3pnw0szrma07rt5gl748fp'); + /// ``` + pub fn from_bech32(bech32_str: &str) -> Result { + crate::chain_crypto::SecretKey::try_from_bech32_str(&bech32_str) + .map(key::EitherEd25519SecretKey::Extended) + .or_else(|_| { + crate::chain_crypto::SecretKey::try_from_bech32_str(&bech32_str) + .map(key::EitherEd25519SecretKey::Normal) + }) + .map(PrivateKey) + .map_err(|_| JsError::from_str("Invalid secret key")) + } + + pub fn to_bech32(&self) -> String { + match self.0 { + key::EitherEd25519SecretKey::Normal(ref secret) => secret.to_bech32_str(), + key::EitherEd25519SecretKey::Extended(ref secret) => secret.to_bech32_str(), + } + } + + pub fn as_bytes(&self) -> Vec { + match self.0 { + key::EitherEd25519SecretKey::Normal(ref secret) => secret.as_ref().to_vec(), + key::EitherEd25519SecretKey::Extended(ref secret) => secret.as_ref().to_vec(), + } + } + + pub fn from_extended_bytes(bytes: &[u8]) -> Result { + crate::chain_crypto::SecretKey::from_binary(bytes) + .map(key::EitherEd25519SecretKey::Extended) + .map(PrivateKey) + .map_err(|_| JsError::from_str("Invalid extended secret key")) + } + + pub fn from_normal_bytes(bytes: &[u8]) -> Result { + crate::chain_crypto::SecretKey::from_binary(bytes) + .map(key::EitherEd25519SecretKey::Normal) + .map(PrivateKey) + .map_err(|_| JsError::from_str("Invalid normal secret key")) + } + + pub fn sign(&self, message: &[u8]) -> Ed25519Signature { + Ed25519Signature(self.0.sign(&message.to_vec())) + } + + pub fn to_hex(&self) -> String { + hex::encode(self.as_bytes()) + } + + pub fn from_hex(hex_str: &str) -> Result { + let data: Vec = match hex::decode(hex_str) { + Ok(d) => d, + Err(e) => return Err(JsError::from_str(&e.to_string())), + }; + let data_slice: &[u8] = data.as_slice(); + crate::chain_crypto::SecretKey::from_binary(data_slice) + .map(key::EitherEd25519SecretKey::Normal) + .or_else(|_| { + crate::chain_crypto::SecretKey::from_binary(data_slice) + .map(key::EitherEd25519SecretKey::Extended) + }) + .map(PrivateKey) + .map_err(|_| JsError::from_str("Invalid secret key")) + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/crypto/public_key.rs b/rust/src/protocol_types/crypto/public_key.rs new file mode 100644 index 00000000..4dd7314c --- /dev/null +++ b/rust/src/protocol_types/crypto/public_key.rs @@ -0,0 +1,98 @@ +use schemars::JsonSchema; +use crate::{Ed25519KeyHash, Ed25519Signature, JsError, wasm_bindgen}; +use crate::chain_crypto::bech32::Bech32; +use crate::crypto::blake2b224; + +/// ED25519 key used as public key +#[wasm_bindgen] +#[derive(Clone, Debug, Hash, Eq, PartialEq)] +pub struct PublicKey(pub(crate) crate::chain_crypto::PublicKey); + +impl From> for PublicKey { + fn from(key: crate::chain_crypto::PublicKey) -> PublicKey { + PublicKey(key) + } +} + +#[wasm_bindgen] +impl PublicKey { + /// Get public key from its bech32 representation + /// Example: + /// ```javascript + /// const pkey = PublicKey.from_bech32('ed25519_pk1dgaagyh470y66p899txcl3r0jaeaxu6yd7z2dxyk55qcycdml8gszkxze2'); + /// ``` + pub fn from_bech32(bech32_str: &str) -> Result { + crate::chain_crypto::PublicKey::try_from_bech32_str(&bech32_str) + .map(PublicKey) + .map_err(|_| JsError::from_str("Malformed public key")) + } + + pub fn to_bech32(&self) -> String { + self.0.to_bech32_str() + } + + pub fn as_bytes(&self) -> Vec { + self.0.as_ref().to_vec() + } + + pub fn from_bytes(bytes: &[u8]) -> Result { + crate::chain_crypto::PublicKey::from_binary(bytes) + .map_err(|e| JsError::from_str(&format!("{}", e))) + .map(PublicKey) + } + + pub fn verify(&self, data: &[u8], signature: &Ed25519Signature) -> bool { + signature.0.verify_slice(&self.0, data) == crate::chain_crypto::Verification::Success + } + + pub fn hash(&self) -> Ed25519KeyHash { + Ed25519KeyHash::from(blake2b224(self.as_bytes().as_ref())) + } + + pub fn to_hex(&self) -> String { + hex::encode(self.as_bytes()) + } + + pub fn from_hex(hex_str: &str) -> Result { + match hex::decode(hex_str) { + Ok(data) => Ok(Self::from_bytes(data.as_ref())?), + Err(e) => Err(JsError::from_str(&e.to_string())), + } + } +} + +impl serde::Serialize for PublicKey { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&self.to_bech32()) + } +} + +impl<'de> serde::de::Deserialize<'de> for PublicKey { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = ::deserialize(deserializer)?; + PublicKey::from_bech32(&s).map_err(|_e| { + serde::de::Error::invalid_value( + serde::de::Unexpected::Str(&s), + &"bech32 public key string", + ) + }) + } +} + +impl JsonSchema for PublicKey { + fn schema_name() -> String { + String::from("PublicKey") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + String::json_schema(gen) + } + fn is_referenceable() -> bool { + String::is_referenceable() + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/crypto/public_keys.rs b/rust/src/protocol_types/crypto/public_keys.rs new file mode 100644 index 00000000..5271d69b --- /dev/null +++ b/rust/src/protocol_types/crypto/public_keys.rs @@ -0,0 +1,24 @@ +use crate::*; + +#[wasm_bindgen] +pub struct PublicKeys(Vec); + +#[wasm_bindgen] +impl PublicKeys { + #[wasm_bindgen(constructor)] + pub fn new() -> PublicKeys { + PublicKeys(vec![]) + } + + pub fn size(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> PublicKey { + self.0[index].clone() + } + + pub fn add(&mut self, key: &PublicKey) { + self.0.push(key.clone()); + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/crypto/vkey.rs b/rust/src/protocol_types/crypto/vkey.rs new file mode 100644 index 00000000..7d25bcfd --- /dev/null +++ b/rust/src/protocol_types/crypto/vkey.rs @@ -0,0 +1,18 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] +pub struct Vkey(pub(crate) PublicKey); + +impl_to_from!(Vkey); + +#[wasm_bindgen] +impl Vkey { + pub fn new(pk: &PublicKey) -> Self { + Self(pk.clone()) + } + + pub fn public_key(&self) -> PublicKey { + self.0.clone() + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/crypto/vkeys.rs b/rust/src/protocol_types/crypto/vkeys.rs new file mode 100644 index 00000000..7de34420 --- /dev/null +++ b/rust/src/protocol_types/crypto/vkeys.rs @@ -0,0 +1,24 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone)] +pub struct Vkeys(pub(crate) Vec); + +#[wasm_bindgen] +impl Vkeys { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> Vkey { + self.0[index].clone() + } + + pub fn add(&mut self, elem: &Vkey) { + self.0.push(elem.clone()); + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/crypto/vrf_cert.rs b/rust/src/protocol_types/crypto/vrf_cert.rs new file mode 100644 index 00000000..cb2918b1 --- /dev/null +++ b/rust/src/protocol_types/crypto/vrf_cert.rs @@ -0,0 +1,41 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct VRFCert { + pub(crate) output: Vec, + pub(crate) proof: Vec, +} + +impl VRFCert { + pub const PROOF_LEN: usize = 80; +} + +impl_to_from!(VRFCert); + +#[wasm_bindgen] +impl VRFCert { + pub fn output(&self) -> Vec { + self.output.clone() + } + + pub fn proof(&self) -> Vec { + self.proof.clone() + } + + pub fn new(output: Vec, proof: Vec) -> Result { + if proof.len() != Self::PROOF_LEN { + return Err(JsError::from_str(&format!( + "proof len must be {} - found {}", + Self::PROOF_LEN, + proof.len() + ))); + } + Ok(Self { + output: output, + proof: proof, + }) + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/ed25519_key_hashes.rs b/rust/src/protocol_types/ed25519_key_hashes.rs index 0bb39378..bd759f80 100644 --- a/rust/src/protocol_types/ed25519_key_hashes.rs +++ b/rust/src/protocol_types/ed25519_key_hashes.rs @@ -1,90 +1,130 @@ pub use crate::*; +use std::collections::HashSet; pub type RequiredSigners = Ed25519KeyHashes; #[wasm_bindgen] #[derive( Clone, - Hash, Debug, Eq, Ord, + Hash, PartialEq, PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, )] -pub struct Ed25519KeyHashesSet(pub(crate) BTreeSet); +pub struct Ed25519KeyHashes { + keyhashes: Vec, + dedup: BTreeSet, +} -impl_to_from!(Ed25519KeyHashesSet); +impl_to_from!(Ed25519KeyHashes); #[wasm_bindgen] -impl Ed25519KeyHashesSet { +impl Ed25519KeyHashes { pub fn new() -> Self { - Self(BTreeSet::new()) + Self { + keyhashes: Vec::new(), + dedup: BTreeSet::new(), + } } - pub fn add(&mut self, key: &Ed25519KeyHash) { - self.0.insert(key.clone()); + pub fn len(&self) -> usize { + self.keyhashes.len() } - pub fn remove(&mut self, key: &Ed25519KeyHash) { - self.0.remove(key); + pub fn get(&self, index: usize) -> Ed25519KeyHash { + self.keyhashes[index].clone() } - pub fn contains(&self, key: &Ed25519KeyHash) -> bool { - self.0.contains(key) + pub fn add(&mut self, elem: &Ed25519KeyHash) { + if self.dedup.insert(elem.clone()) { + self.keyhashes.push(elem.clone()); + } } - pub fn len(&self) -> usize { - self.0.len() + pub fn contains(&self, elem: &Ed25519KeyHash) -> bool { + self.dedup.contains(elem) } - pub fn get(&self, index: usize) -> Option { - self.0.iter().nth(index).cloned() + pub fn to_option(&self) -> Option { + if self.keyhashes.len() > 0 { + Some(self.clone()) + } else { + None + } } - pub fn to_vec(&self) -> RequiredSigners { - Ed25519KeyHashes(self.0.iter().cloned().collect()) + pub(crate) fn to_vec(&self) -> &Vec { + &self.keyhashes } - pub(crate) fn add_move(&mut self, key: Ed25519KeyHash) { - self.0.insert(key); + pub(crate) fn add_move(&mut self, elem: Ed25519KeyHash) { + if self.dedup.insert(elem.clone()) { + self.keyhashes.push(elem); + } } - pub(crate) fn extend(&mut self, keys: Ed25519KeyHashesSet) { - self.0.extend(keys.0); + pub(crate) fn extend(&mut self, other: &Ed25519KeyHashes) { + for keyhash in other.keyhashes.iter() { + self.add(keyhash); + } } - pub(crate) fn to_option(&self) -> Option { - if self.0.is_empty() { - None - } else { - Some(self.clone()) + pub(crate) fn extend_move(&mut self, other: Ed25519KeyHashes) { + for keyhash in other.keyhashes { + self.add_move(keyhash); + } + } + + pub(crate) fn from_vec(keyhash_vec: Vec) -> Self { + let mut dedup = BTreeSet::new(); + let mut keyhashes = Vec::new(); + for keyhash in keyhash_vec { + if dedup.insert(keyhash.clone()) { + keyhashes.push(keyhash); + } } + + Self { keyhashes, dedup } } } -impl NoneOrEmpty for Ed25519KeyHashesSet { +impl NoneOrEmpty for Ed25519KeyHashes { fn is_none_or_empty(&self) -> bool { - self.0.is_empty() + self.keyhashes.is_empty() } } -impl NoneOrEmpty for RequiredSigners { - fn is_none_or_empty(&self) -> bool { - self.0.is_empty() +impl serde::Serialize for Ed25519KeyHashes { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + self.keyhashes.serialize(serializer) } } -impl From<&Ed25519KeyHashes> for Ed25519KeyHashesSet { - fn from(keys: &Ed25519KeyHashes) -> Self { - keys.0 - .iter() - .fold(Ed25519KeyHashesSet::new(), |mut set, k| { - set.add_move(k.clone()); - set - }) +impl<'de> serde::de::Deserialize<'de> for Ed25519KeyHashes { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let vec = as serde::de::Deserialize>::deserialize( + deserializer, + )?; + Ok(Self::from_vec(vec)) } } + +impl JsonSchema for Ed25519KeyHashes { + fn schema_name() -> String { + String::from("Ed25519KeyHashes") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + Vec::::json_schema(gen) + } + fn is_referenceable() -> bool { + Vec::::is_referenceable() + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/governance/proposals/committee.rs b/rust/src/protocol_types/governance/proposals/committee.rs index faa92ca4..69bd8774 100644 --- a/rust/src/protocol_types/governance/proposals/committee.rs +++ b/rust/src/protocol_types/governance/proposals/committee.rs @@ -55,8 +55,8 @@ impl Committee { } } - pub fn members_keys(&self) -> CredentialsSet { - CredentialsSet::from_iter(self.members.keys().cloned()) + pub fn members_keys(&self) -> Credentials { + Credentials::from_iter(self.members.keys().cloned()) } pub fn quorum_threshold(&self) -> UnitInterval { diff --git a/rust/src/protocol_types/governance/proposals/update_committee_action.rs b/rust/src/protocol_types/governance/proposals/update_committee_action.rs index 895e3463..c36ed046 100644 --- a/rust/src/protocol_types/governance/proposals/update_committee_action.rs +++ b/rust/src/protocol_types/governance/proposals/update_committee_action.rs @@ -16,7 +16,7 @@ use crate::*; pub struct UpdateCommitteeAction { pub(crate) gov_action_id: Option, pub(crate) committee: Committee, - pub(crate) members_to_remove: CredentialsSet, + pub(crate) members_to_remove: Credentials, } impl_to_from!(UpdateCommitteeAction); @@ -31,11 +31,11 @@ impl UpdateCommitteeAction { self.committee.clone() } - pub fn members_to_remove(&self) -> CredentialsSet { + pub fn members_to_remove(&self) -> Credentials { self.members_to_remove.clone() } - pub fn new(committee: &Committee, members_to_remove: &CredentialsSet) -> Self { + pub fn new(committee: &Committee, members_to_remove: &Credentials) -> Self { Self { gov_action_id: None, committee: committee.clone(), @@ -46,7 +46,7 @@ impl UpdateCommitteeAction { pub fn new_with_action_id( gov_action_id: &GovernanceActionId, committee: &Committee, - members_to_remove: &CredentialsSet, + members_to_remove: &Credentials, ) -> Self { Self { gov_action_id: Some(gov_action_id.clone()), diff --git a/rust/src/protocol_types/metadata.rs b/rust/src/protocol_types/metadata.rs index 94f0b11a..b1b89342 100644 --- a/rust/src/protocol_types/metadata.rs +++ b/rust/src/protocol_types/metadata.rs @@ -1,5 +1,5 @@ use crate::*; -use linked_hash_map::LinkedHashMap; +use hashlink::LinkedHashMap; const MD_MAX_LEN: usize = 64; diff --git a/rust/src/protocol_types/mod.rs b/rust/src/protocol_types/mod.rs index 62112252..29950c69 100644 --- a/rust/src/protocol_types/mod.rs +++ b/rust/src/protocol_types/mod.rs @@ -25,8 +25,17 @@ pub use address::*; mod tx_inputs; pub use tx_inputs::*; +mod credential; +pub use credential::*; + mod credentials; pub use credentials::*; mod ed25519_key_hashes; -pub use ed25519_key_hashes::*; \ No newline at end of file +pub use ed25519_key_hashes::*; + +mod witnesses; +pub use witnesses::*; + +mod crypto; +pub use crypto::*; \ No newline at end of file diff --git a/rust/src/protocol_types/plutus.rs b/rust/src/protocol_types/plutus.rs index 8d004024..4f7af727 100644 --- a/rust/src/protocol_types/plutus.rs +++ b/rust/src/protocol_types/plutus.rs @@ -1,6 +1,6 @@ use crate::*; use core::hash::Hasher; -use linked_hash_map::LinkedHashMap; +use hashlink::LinkedHashMap; use std::hash::Hash; // This library was code-generated using an experimental CDDL to rust tool: diff --git a/rust/src/protocol_types/transaction_body.rs b/rust/src/protocol_types/transaction_body.rs index 8cd96d1e..08a8ecc4 100644 --- a/rust/src/protocol_types/transaction_body.rs +++ b/rust/src/protocol_types/transaction_body.rs @@ -15,7 +15,7 @@ pub struct TransactionBody { pub(crate) mint: Option, pub(crate) script_data_hash: Option, pub(crate) collateral: Option, - pub(crate) required_signers: Option, + pub(crate) required_signers: Option, pub(crate) network_id: Option, pub(crate) collateral_return: Option, pub(crate) total_collateral: Option, @@ -171,11 +171,11 @@ impl TransactionBody { self.collateral.clone() } - pub fn set_required_signers(&mut self, required_signers: &Ed25519KeyHashesSet) { + pub fn set_required_signers(&mut self, required_signers: &Ed25519KeyHashes) { self.required_signers = Some(required_signers.clone()) } - pub fn required_signers(&self) -> Option { + pub fn required_signers(&self) -> Option { self.required_signers.clone() } diff --git a/rust/src/protocol_types/witnesses/bootstrap_witness.rs b/rust/src/protocol_types/witnesses/bootstrap_witness.rs new file mode 100644 index 00000000..676fa876 --- /dev/null +++ b/rust/src/protocol_types/witnesses/bootstrap_witness.rs @@ -0,0 +1,45 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize, JsonSchema)] +pub struct BootstrapWitness { + pub(crate) vkey: Vkey, + pub(crate) signature: Ed25519Signature, + pub(crate) chain_code: Vec, + pub(crate) attributes: Vec, +} + +impl_to_from!(BootstrapWitness); + +#[wasm_bindgen] +impl BootstrapWitness { + pub fn vkey(&self) -> Vkey { + self.vkey.clone() + } + + pub fn signature(&self) -> Ed25519Signature { + self.signature.clone() + } + + pub fn chain_code(&self) -> Vec { + self.chain_code.clone() + } + + pub fn attributes(&self) -> Vec { + self.attributes.clone() + } + + pub fn new( + vkey: &Vkey, + signature: &Ed25519Signature, + chain_code: Vec, + attributes: Vec, + ) -> Self { + Self { + vkey: vkey.clone(), + signature: signature.clone(), + chain_code: chain_code, + attributes: attributes, + } + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/witnesses/bootstrap_witnesses.rs b/rust/src/protocol_types/witnesses/bootstrap_witnesses.rs new file mode 100644 index 00000000..87b0c832 --- /dev/null +++ b/rust/src/protocol_types/witnesses/bootstrap_witnesses.rs @@ -0,0 +1,87 @@ +use crate::*; +use std::collections::HashSet; + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct BootstrapWitnesses { + witnesses: Vec, + + //for deduplication purpose + dedup: HashSet, +} + +#[wasm_bindgen] +impl BootstrapWitnesses { + pub fn new() -> Self { + Self { + witnesses: Vec::new(), + dedup: HashSet::new(), + } + } + + pub fn len(&self) -> usize { + self.witnesses.len() + } + + pub fn get(&self, index: usize) -> BootstrapWitness { + self.witnesses[index].clone() + } + + pub fn add(&mut self, elem: &BootstrapWitness) { + if self.dedup.insert(elem.clone()) { + self.witnesses.push(elem.clone()); + } + } + + pub(crate) fn get_vec_wits(&self) -> &Vec { + &self.witnesses + } + + pub(crate) fn from_vec_wits(wits: Vec) -> Self { + let mut dedup = HashSet::new(); + let mut witnesses = Vec::new(); + for wit in wits { + if dedup.insert(wit.clone()) { + witnesses.push(wit); + } + } + + Self { + witnesses, + dedup, + } + } +} + +impl serde::Serialize for BootstrapWitnesses { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let wits = self.get_vec_wits(); + wits.serialize(serializer) + } +} + +impl<'de> serde::de::Deserialize<'de> for BootstrapWitnesses { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let wits = as serde::de::Deserialize>::deserialize(deserializer)?; + + Ok(Self::from_vec_wits(wits)) + } +} + +impl JsonSchema for BootstrapWitnesses { + fn is_referenceable() -> bool { + Vec::::is_referenceable() + } + fn schema_name() -> String { + String::from("BootstrapWitnesses") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + Vec::::json_schema(gen) + } +} diff --git a/rust/src/protocol_types/witnesses/mod.rs b/rust/src/protocol_types/witnesses/mod.rs new file mode 100644 index 00000000..5cfd8133 --- /dev/null +++ b/rust/src/protocol_types/witnesses/mod.rs @@ -0,0 +1,19 @@ +mod vkeywitness; +pub use vkeywitness::*; + +mod vkeywitnesses; +pub use vkeywitnesses::*; + +mod bootstrap_witness; +pub use bootstrap_witness::*; + +mod bootstrap_witnesses; + +pub use bootstrap_witnesses::*; + +mod transaction_witnesses_set; +pub use transaction_witnesses_set::*; + +mod transaction_witnesses_sets; +pub use transaction_witnesses_sets::*; + diff --git a/rust/src/protocol_types/witnesses/transaction_witnesses_set.rs b/rust/src/protocol_types/witnesses/transaction_witnesses_set.rs new file mode 100644 index 00000000..53983395 --- /dev/null +++ b/rust/src/protocol_types/witnesses/transaction_witnesses_set.rs @@ -0,0 +1,76 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Eq, PartialEq, Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +pub struct TransactionWitnessSet { + pub(crate) vkeys: Option, + pub(crate) native_scripts: Option, + pub(crate) bootstraps: Option, + pub(crate) plutus_scripts: Option, + pub(crate) plutus_data: Option, + pub(crate) redeemers: Option, +} + +impl_to_from!(TransactionWitnessSet); + +#[wasm_bindgen] +impl TransactionWitnessSet { + pub fn set_vkeys(&mut self, vkeys: &Vkeywitnesses) { + self.vkeys = Some(vkeys.clone()) + } + + pub fn vkeys(&self) -> Option { + self.vkeys.clone() + } + + pub fn set_native_scripts(&mut self, native_scripts: &NativeScripts) { + self.native_scripts = Some(native_scripts.clone()) + } + + pub fn native_scripts(&self) -> Option { + self.native_scripts.clone() + } + + pub fn set_bootstraps(&mut self, bootstraps: &BootstrapWitnesses) { + self.bootstraps = Some(bootstraps.clone()) + } + + pub fn bootstraps(&self) -> Option { + self.bootstraps.clone() + } + + pub fn set_plutus_scripts(&mut self, plutus_scripts: &PlutusScripts) { + self.plutus_scripts = Some(plutus_scripts.clone()) + } + + pub fn plutus_scripts(&self) -> Option { + self.plutus_scripts.clone() + } + + pub fn set_plutus_data(&mut self, plutus_data: &PlutusList) { + self.plutus_data = Some(plutus_data.clone()) + } + + pub fn plutus_data(&self) -> Option { + self.plutus_data.clone() + } + + pub fn set_redeemers(&mut self, redeemers: &Redeemers) { + self.redeemers = Some(redeemers.clone()) + } + + pub fn redeemers(&self) -> Option { + self.redeemers.clone() + } + + pub fn new() -> Self { + Self { + vkeys: None, + native_scripts: None, + bootstraps: None, + plutus_scripts: None, + plutus_data: None, + redeemers: None, + } + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/witnesses/transaction_witnesses_sets.rs b/rust/src/protocol_types/witnesses/transaction_witnesses_sets.rs new file mode 100644 index 00000000..f2d933fa --- /dev/null +++ b/rust/src/protocol_types/witnesses/transaction_witnesses_sets.rs @@ -0,0 +1,26 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, serde::Serialize, serde::Deserialize, JsonSchema)] +pub struct TransactionWitnessSets(pub(crate) Vec); + +impl_to_from!(TransactionWitnessSets); + +#[wasm_bindgen] +impl TransactionWitnessSets { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> TransactionWitnessSet { + self.0[index].clone() + } + + pub fn add(&mut self, elem: &TransactionWitnessSet) { + self.0.push(elem.clone()); + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/witnesses/vkeywitness.rs b/rust/src/protocol_types/witnesses/vkeywitness.rs new file mode 100644 index 00000000..7df27e09 --- /dev/null +++ b/rust/src/protocol_types/witnesses/vkeywitness.rs @@ -0,0 +1,28 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] +pub struct Vkeywitness { + pub(crate) vkey: Vkey, + pub(crate) signature: Ed25519Signature, +} + +impl_to_from!(Vkeywitness); + +#[wasm_bindgen] +impl Vkeywitness { + pub fn new(vkey: &Vkey, signature: &Ed25519Signature) -> Self { + Self { + vkey: vkey.clone(), + signature: signature.clone(), + } + } + + pub fn vkey(&self) -> Vkey { + self.vkey.clone() + } + + pub fn signature(&self) -> Ed25519Signature { + self.signature.clone() + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/witnesses/vkeywitnesses.rs b/rust/src/protocol_types/witnesses/vkeywitnesses.rs new file mode 100644 index 00000000..0b680d95 --- /dev/null +++ b/rust/src/protocol_types/witnesses/vkeywitnesses.rs @@ -0,0 +1,26 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] +pub struct Vkeywitnesses(pub(crate) Vec); + +impl_to_from!(Vkeywitnesses); + +#[wasm_bindgen] +impl Vkeywitnesses { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> Vkeywitness { + self.0[index].clone() + } + + pub fn add(&mut self, elem: &Vkeywitness) { + self.0.push(elem.clone()); + } +} \ No newline at end of file diff --git a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs index a63b14c5..753e1f51 100644 --- a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs +++ b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs @@ -4,6 +4,7 @@ use crate::serialization::utils::{ }; use crate::*; use num_traits::ToPrimitive; +use hashlink::LinkedHashMap; impl cbor_event::se::Serialize for MIRToStakeCredentials { fn serialize<'se, W: Write>( @@ -22,7 +23,7 @@ impl cbor_event::se::Serialize for MIRToStakeCredentials { impl Deserialize for MIRToStakeCredentials { fn deserialize(raw: &mut Deserializer) -> Result { (|| -> Result<_, DeserializeError> { - let mut table = linked_hash_map::LinkedHashMap::new(); + let mut table = LinkedHashMap::new(); let len = raw.map()?; while match len { cbor_event::Len::Len(n) => table.len() < n as usize, diff --git a/rust/src/serialization/certificates/pool_registration.rs b/rust/src/serialization/certificates/pool_registration.rs index 06f59960..88370bfa 100644 --- a/rust/src/serialization/certificates/pool_registration.rs +++ b/rust/src/serialization/certificates/pool_registration.rs @@ -94,7 +94,7 @@ impl DeserializeEmbeddedGroup for PoolParams { (|| -> Result<_, DeserializeError> { Ok(RewardAddress::deserialize(raw)?) })() .map_err(|e| e.annotate("reward_account"))?; let pool_owners = - (|| -> Result<_, DeserializeError> { Ok(Ed25519KeyHashesSet::deserialize(raw)?) })() + (|| -> Result<_, DeserializeError> { Ok(Ed25519KeyHashes::deserialize(raw)?) })() .map_err(|e| e.annotate("pool_owners"))?; let relays = (|| -> Result<_, DeserializeError> { Ok(Relays::deserialize(raw)?) })() .map_err(|e| e.annotate("relays"))?; diff --git a/rust/src/serialization/credential.rs b/rust/src/serialization/credential.rs new file mode 100644 index 00000000..ff2a886d --- /dev/null +++ b/rust/src/serialization/credential.rs @@ -0,0 +1,60 @@ +use std::io::{BufRead, Seek, Write}; +use cbor_event::de::Deserializer; +use cbor_event::se::Serializer; +use crate::{Credential, CredType, DeserializeError, DeserializeFailure, Ed25519KeyHash, Key, ScriptHash}; +use crate::protocol_types::{CBORSpecial, Deserialize}; + +impl cbor_event::se::Serialize for Credential { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + match &self.0 { + CredType::Key(keyhash) => { + serializer.write_unsigned_integer(0u64)?; + serializer.write_bytes(keyhash.to_bytes()) + } + CredType::Script(scripthash) => { + serializer.write_unsigned_integer(1u64)?; + serializer.write_bytes(scripthash.to_bytes()) + } + } + } +} + +impl Deserialize for Credential { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + if let cbor_event::Len::Len(n) = len { + if n != 2 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 2, + len, + "[id, hash]", + )) + .into()); + } + } + let cred_type = match raw.unsigned_integer()? { + 0 => CredType::Key(Ed25519KeyHash::deserialize(raw)?), + 1 => CredType::Script(ScriptHash::deserialize(raw)?), + n => { + return Err(DeserializeFailure::FixedValuesMismatch { + found: Key::Uint(n), + expected: vec![Key::Uint(0), Key::Uint(1)], + } + .into()); + } + }; + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + Ok(Credential(cred_type)) + })() + .map_err(|e| e.annotate("StakeCredential")) + } +} \ No newline at end of file diff --git a/rust/src/serialization/credentials.rs b/rust/src/serialization/credentials.rs index c01b11da..73329020 100644 --- a/rust/src/serialization/credentials.rs +++ b/rust/src/serialization/credentials.rs @@ -1,25 +1,25 @@ use crate::*; use crate::serialization::utils::skip_set_tag; -impl cbor_event::se::Serialize for CredentialsSet { +impl cbor_event::se::Serialize for Credentials { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { //TODO: uncomment this line when we conway ero will come //serializer.write_tag(258)?; - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { + serializer.write_array(cbor_event::Len::Len(self.len() as u64))?; + for element in self.to_vec() { element.serialize(serializer)?; } Ok(serializer) } } -impl Deserialize for CredentialsSet { +impl Deserialize for Credentials { fn deserialize(raw: &mut Deserializer) -> Result { skip_set_tag(raw)?; - let mut creds = CredentialsSet::new(); + let mut creds = Credentials::new(); (|| -> Result<_, DeserializeError> { let len = raw.array()?; while match len { @@ -37,94 +37,4 @@ impl Deserialize for CredentialsSet { .map_err(|e| e.annotate("CredentialsSet"))?; Ok(creds) } -} - -impl cbor_event::se::Serialize for Credentials { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for Credentials { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut creds = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => creds.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - creds.push(Credential::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("Credentials"))?; - Ok(Credentials(creds)) - } -} - -impl cbor_event::se::Serialize for Credential { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - match &self.0 { - CredType::Key(keyhash) => { - serializer.write_unsigned_integer(0u64)?; - serializer.write_bytes(keyhash.to_bytes()) - } - CredType::Script(scripthash) => { - serializer.write_unsigned_integer(1u64)?; - serializer.write_bytes(scripthash.to_bytes()) - } - } - } -} - -impl Deserialize for Credential { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - if let cbor_event::Len::Len(n) = len { - if n != 2 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 2, - len, - "[id, hash]", - )) - .into()); - } - } - let cred_type = match raw.unsigned_integer()? { - 0 => CredType::Key(Ed25519KeyHash::deserialize(raw)?), - 1 => CredType::Script(ScriptHash::deserialize(raw)?), - n => { - return Err(DeserializeFailure::FixedValuesMismatch { - found: Key::Uint(n), - expected: vec![Key::Uint(0), Key::Uint(1)], - } - .into()); - } - }; - if let cbor_event::Len::Indefinite = len { - if raw.special()? != CBORSpecial::Break { - return Err(DeserializeFailure::EndingBreakMissing.into()); - } - } - Ok(Credential(cred_type)) - })() - .map_err(|e| e.annotate("StakeCredential")) - } } \ No newline at end of file diff --git a/rust/src/serialization/crypto/kes_signature.rs b/rust/src/serialization/crypto/kes_signature.rs new file mode 100644 index 00000000..29537e58 --- /dev/null +++ b/rust/src/serialization/crypto/kes_signature.rs @@ -0,0 +1,33 @@ +use cbor_event::de::Deserializer; +use cbor_event::se::Serializer; +use crate::{DeserializeError, DeserializeFailure, KESSignature}; +use crate::protocol_types::Deserialize; + +impl cbor_event::se::Serialize for KESSignature { + fn serialize<'se, W: std::io::Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_bytes(&self.0) + } +} + +impl Deserialize for KESSignature { + fn deserialize( + raw: &mut Deserializer, + ) -> Result { + (|| -> Result { + let bytes = raw.bytes()?; + if bytes.len() != Self::BYTE_COUNT { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + Self::BYTE_COUNT as u64, + cbor_event::Len::Len(bytes.len() as u64), + "hash length", + )) + .into()); + } + Ok(KESSignature(bytes)) + })() + .map_err(|e| e.annotate("KESSignature")) + } +} \ No newline at end of file diff --git a/rust/src/serialization/crypto/mod.rs b/rust/src/serialization/crypto/mod.rs new file mode 100644 index 00000000..cb68a186 --- /dev/null +++ b/rust/src/serialization/crypto/mod.rs @@ -0,0 +1,5 @@ +mod vkey; +mod vkeys; +mod kes_signature; +mod nonce; +mod vrf_cert; \ No newline at end of file diff --git a/rust/src/serialization/crypto/nonce.rs b/rust/src/serialization/crypto/nonce.rs new file mode 100644 index 00000000..b05e5703 --- /dev/null +++ b/rust/src/serialization/crypto/nonce.rs @@ -0,0 +1,72 @@ +use crate::chain_crypto::bech32::Bech32 as _; +use crate::protocol_types::{CBORSpecial, Deserialize}; +use crate::{DeserializeError, DeserializeFailure, Nonce}; +use cbor_event::de::Deserializer; +use cbor_event::se::Serializer; + +impl cbor_event::se::Serialize for Nonce { + fn serialize<'se, W: std::io::Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + match &self.hash { + Some(hash) => { + serializer.write_array(cbor_event::Len::Len(2))?; + serializer.write_unsigned_integer(1)?; + serializer.write_bytes(hash) + } + None => { + serializer.write_array(cbor_event::Len::Len(1))?; + serializer.write_unsigned_integer(0) + } + } + } +} + +impl Deserialize for Nonce { + fn deserialize( + raw: &mut Deserializer, + ) -> Result { + (|| -> Result { + let len = raw.array()?; + let hash = match raw.unsigned_integer()? { + 0 => None, + 1 => { + let bytes = raw.bytes()?; + if bytes.len() != Self::HASH_LEN { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + Self::HASH_LEN as u64, + cbor_event::Len::Len(bytes.len() as u64), + "hash length", + )) + .into()); + } + Some(bytes[..Self::HASH_LEN].try_into().unwrap()) + } + _ => return Err(DeserializeFailure::NoVariantMatched.into()), + }; + match len { + cbor_event::Len::Len(n) => { + let correct_len = match n { + 1 => hash.is_none(), + 2 => hash.is_some(), + _ => false, + }; + if !correct_len { + return Err(DeserializeFailure::NoVariantMatched.into()); + } + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + }; + Ok(Self { hash }) + })() + .map_err(|e| e.annotate(stringify!($name))) + } +} diff --git a/rust/src/serialization/crypto/vkey.rs b/rust/src/serialization/crypto/vkey.rs new file mode 100644 index 00000000..9801c36f --- /dev/null +++ b/rust/src/serialization/crypto/vkey.rs @@ -0,0 +1,22 @@ +use std::io::{BufRead, Seek, Write}; +use cbor_event::de::Deserializer; +use cbor_event::se::Serializer; +use crate::{DeserializeError, PublicKey, Vkey}; +use crate::protocol_types::Deserialize; + +impl cbor_event::se::Serialize for Vkey { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_bytes(&self.0.as_bytes()) + } +} + +impl Deserialize for Vkey { + fn deserialize(raw: &mut Deserializer) -> Result { + Ok(Self(PublicKey(crate::chain_crypto::PublicKey::from_binary( + raw.bytes()?.as_ref(), + )?))) + } +} \ No newline at end of file diff --git a/rust/src/serialization/crypto/vkeys.rs b/rust/src/serialization/crypto/vkeys.rs new file mode 100644 index 00000000..4d9fc23c --- /dev/null +++ b/rust/src/serialization/crypto/vkeys.rs @@ -0,0 +1,40 @@ +use std::io::{BufRead, Seek, Write}; +use cbor_event::de::Deserializer; +use cbor_event::se::Serializer; +use crate::{DeserializeError, Vkey, Vkeys}; +use crate::protocol_types::{CBORSpecial, CBORType, Deserialize}; + +impl cbor_event::se::Serialize for Vkeys { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for Vkeys { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(Vkey::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("Vkeys"))?; + Ok(Self(arr)) + } +} \ No newline at end of file diff --git a/rust/src/serialization/crypto/vrf_cert.rs b/rust/src/serialization/crypto/vrf_cert.rs new file mode 100644 index 00000000..85d0c85a --- /dev/null +++ b/rust/src/serialization/crypto/vrf_cert.rs @@ -0,0 +1,50 @@ +use crate::*; + +impl cbor_event::se::Serialize for VRFCert { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + serializer.write_bytes(&self.output)?; + serializer.write_bytes(&self.proof)?; + Ok(serializer) + } +} + +impl Deserialize for VRFCert { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let output = (|| -> Result<_, DeserializeError> { Ok(raw.bytes()?) })() + .map_err(|e| e.annotate("output"))?; + let proof = (|| -> Result<_, DeserializeError> { Ok(raw.bytes()?) })() + .map_err(|e| e.annotate("proof"))?; + if proof.len() != Self::PROOF_LEN { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + Self::PROOF_LEN as u64, + cbor_event::Len::Len(proof.len() as u64), + "proof length", + )) + .into()); + } + match len { + cbor_event::Len::Len(_) => + /* TODO: check finite len somewhere */ + { + () + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + Ok(VRFCert { output, proof }) + })() + .map_err(|e| e.annotate("VRFCert")) + } +} \ No newline at end of file diff --git a/rust/src/serialization/ed25519_key_hashes.rs b/rust/src/serialization/ed25519_key_hashes.rs index 3484ed8b..21970798 100644 --- a/rust/src/serialization/ed25519_key_hashes.rs +++ b/rust/src/serialization/ed25519_key_hashes.rs @@ -1,25 +1,25 @@ use crate::*; use crate::serialization::utils::skip_set_tag; -impl cbor_event::se::Serialize for Ed25519KeyHashesSet { +impl Serialize for Ed25519KeyHashes { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { //TODO: uncomment this line when we conway ero will come //serializer.write_tag(258)?; - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { + serializer.write_array(cbor_event::Len::Len(self.len() as u64))?; + for element in self.to_vec() { element.serialize(serializer)?; } Ok(serializer) } } -impl Deserialize for Ed25519KeyHashesSet { +impl Deserialize for Ed25519KeyHashes { fn deserialize(raw: &mut Deserializer) -> Result { skip_set_tag(raw)?; - let mut creds = Ed25519KeyHashesSet::new(); + let mut creds = Ed25519KeyHashes::new(); (|| -> Result<_, DeserializeError> { let len = raw.array()?; while match len { @@ -34,7 +34,7 @@ impl Deserialize for Ed25519KeyHashesSet { } Ok(()) })() - .map_err(|e| e.annotate("RequiredSignersSet"))?; + .map_err(|e| e.annotate("Ed25519KeyHashes"))?; Ok(creds) } } \ No newline at end of file diff --git a/rust/src/serialization/general.rs b/rust/src/serialization/general.rs index c3d4e86a..6419226a 100644 --- a/rust/src/serialization/general.rs +++ b/rust/src/serialization/general.rs @@ -1,6 +1,7 @@ use crate::*; use std::io::{Seek, SeekFrom}; use crate::serialization::utils::merge_option_plutus_list; +use hashlink::LinkedHashMap; // This file was code-generated using an experimental CDDL to rust tool: // https://github.com/Emurgo/cddl-codegen @@ -589,41 +590,6 @@ impl cbor_event::se::Serialize for ScriptRef { } } -impl cbor_event::se::Serialize for Ed25519KeyHashes { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for Ed25519KeyHashes { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(Ed25519KeyHash::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("Ed25519KeyHashes"))?; - Ok(Self(arr)) - } -} - impl cbor_event::se::Serialize for Ipv4 { fn serialize<'se, W: Write>( &self, @@ -1175,7 +1141,7 @@ impl cbor_event::se::Serialize for Withdrawals { impl Deserialize for Withdrawals { fn deserialize(raw: &mut Deserializer) -> Result { - let mut table = linked_hash_map::LinkedHashMap::new(); + let mut table = LinkedHashMap::new(); (|| -> Result<_, DeserializeError> { let len = raw.map()?; while match len { @@ -1202,237 +1168,6 @@ impl Deserialize for Withdrawals { } } -impl cbor_event::se::Serialize for TransactionWitnessSet { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - let mut has_plutus_v2 = false; - let mut has_plutus_v3 = false; - let plutus_added_length = match &self.plutus_scripts { - Some(scripts) => { - has_plutus_v2 = scripts.has_version(&Language::new_plutus_v2()); - has_plutus_v3 = scripts.has_version(&Language::new_plutus_v3()); - 1 + (has_plutus_v2 as u64) + (has_plutus_v3 as u64) - }, - _ => 0, - }; - serializer.write_map(cbor_event::Len::Len( - opt64(&self.vkeys) - + opt64(&self.native_scripts) - + opt64(&self.bootstraps) - + opt64(&self.plutus_data) - + opt64(&self.redeemers) - + plutus_added_length, - ))?; - if let Some(field) = &self.vkeys { - serializer.write_unsigned_integer(0)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.native_scripts { - serializer.write_unsigned_integer(1)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.bootstraps { - serializer.write_unsigned_integer(2)?; - field.serialize(serializer)?; - } - if let Some(plutus_scripts) = &self.plutus_scripts { - serializer.write_unsigned_integer(3)?; - plutus_scripts - .by_version(&Language::new_plutus_v1()) - .serialize(serializer)?; - if has_plutus_v2 { - serializer.write_unsigned_integer(6)?; - plutus_scripts - .by_version(&Language::new_plutus_v2()) - .serialize(serializer)?; - } - if has_plutus_v3 { - serializer.write_unsigned_integer(7)?; - plutus_scripts - .by_version(&Language::new_plutus_v3()) - .serialize(serializer)?; - } - } - if let Some(field) = &self.plutus_data { - serializer.write_unsigned_integer(4)?; - field.serialize(serializer)?; - } - if let Some(field) = &self.redeemers { - serializer.write_unsigned_integer(5)?; - field.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for TransactionWitnessSet { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.map()?; - let mut read_len = CBORReadLen::new(len); - let mut vkeys = None; - let mut native_scripts = None; - let mut bootstraps = None; - let mut plutus_scripts_v1 = None; - let mut plutus_scripts_v2 = None; - let mut plutus_scripts_v3 = None; - let mut plutus_data = None; - let mut redeemers = None; - let mut read = 0; - while match len { - cbor_event::Len::Len(n) => read < n as usize, - cbor_event::Len::Indefinite => true, - } { - match raw.cbor_type()? { - CBORType::UnsignedInteger => match raw.unsigned_integer()? { - 0 => { - if vkeys.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(0)).into()); - } - vkeys = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(Vkeywitnesses::deserialize(raw)?) - })() - .map_err(|e| e.annotate("vkeys"))?, - ); - } - 1 => { - if native_scripts.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(1)).into()); - } - native_scripts = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(NativeScripts::deserialize(raw)?) - })() - .map_err(|e| e.annotate("native_scripts"))?, - ); - } - 2 => { - if bootstraps.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(2)).into()); - } - bootstraps = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(BootstrapWitnesses::deserialize(raw)?) - })() - .map_err(|e| e.annotate("bootstraps"))?, - ); - } - 3 => { - if plutus_scripts_v1.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(3)).into()); - } - plutus_scripts_v1 = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(PlutusScripts::deserialize(raw)?) - })() - .map_err(|e| e.annotate("plutus_scripts_v1"))?, - ); - } - 4 => { - if plutus_data.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(4)).into()); - } - plutus_data = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(PlutusList::deserialize(raw)?) - })() - .map_err(|e| e.annotate("plutus_data"))?, - ); - } - 5 => { - if redeemers.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(5)).into()); - } - redeemers = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(Redeemers::deserialize(raw)?) - })() - .map_err(|e| e.annotate("redeemers"))?, - ); - } - 6 => { - if plutus_scripts_v2.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(6)).into()); - } - plutus_scripts_v2 = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(PlutusScripts::deserialize(raw)? - .map_as_version(&Language::new_plutus_v2())) - })() - .map_err(|e| e.annotate("plutus_scripts_v2"))?, - ); - } - 7 => { - if plutus_scripts_v3.is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Uint(7)).into()); - } - plutus_scripts_v3 = Some( - (|| -> Result<_, DeserializeError> { - read_len.read_elems(1)?; - Ok(PlutusScripts::deserialize(raw)? - .map_as_version(&Language::new_plutus_v3())) - })() - .map_err(|e| e.annotate("plutus_scripts_v3"))?, - ); - } - unknown_key => { - return Err( - DeserializeFailure::UnknownKey(Key::Uint(unknown_key)).into() - ) - } - }, - CBORType::Text => match raw.text()?.as_str() { - unknown_key => { - return Err(DeserializeFailure::UnknownKey(Key::Str( - unknown_key.to_owned(), - )) - .into()) - } - }, - CBORType::Special => match len { - cbor_event::Len::Len(_) => { - return Err(DeserializeFailure::BreakInDefiniteLen.into()) - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => break, - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - }, - other_type => { - return Err(DeserializeFailure::UnexpectedKeyType(other_type).into()) - } - } - read += 1; - } - read_len.finish()?; - let mut plutus_scripts = None; - plutus_scripts = merge_option_plutus_list(plutus_scripts, plutus_scripts_v1); - plutus_scripts = merge_option_plutus_list(plutus_scripts, plutus_scripts_v2); - plutus_scripts = merge_option_plutus_list(plutus_scripts, plutus_scripts_v3); - - Ok(Self { - vkeys, - native_scripts, - bootstraps, - plutus_scripts, - plutus_data, - redeemers, - }) - })() - .map_err(|e| e.annotate("TransactionWitnessSet")) - } -} - impl cbor_event::se::Serialize for ScriptPubkey { fn serialize<'se, W: Write>( &self, @@ -2127,7 +1862,7 @@ impl cbor_event::se::Serialize for ProposedProtocolParameterUpdates { impl Deserialize for ProposedProtocolParameterUpdates { fn deserialize(raw: &mut Deserializer) -> Result { - let mut table = linked_hash_map::LinkedHashMap::new(); + let mut table = LinkedHashMap::new(); (|| -> Result<_, DeserializeError> { let len = raw.map()?; while match len { @@ -2249,41 +1984,6 @@ impl Deserialize for TransactionBodies { } } -impl cbor_event::se::Serialize for TransactionWitnessSets { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for TransactionWitnessSets { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(TransactionWitnessSet::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("TransactionWitnessSets"))?; - Ok(Self(arr)) - } -} - impl cbor_event::se::Serialize for AuxiliaryDataSet { fn serialize<'se, W: Write>( &self, @@ -2300,7 +2000,7 @@ impl cbor_event::se::Serialize for AuxiliaryDataSet { impl Deserialize for AuxiliaryDataSet { fn deserialize(raw: &mut Deserializer) -> Result { - let mut table = linked_hash_map::LinkedHashMap::new(); + let mut table = LinkedHashMap::new(); (|| -> Result<_, DeserializeError> { let len = raw.map()?; while match len { diff --git a/rust/src/serialization/governance/proposals/update_committee_action.rs b/rust/src/serialization/governance/proposals/update_committee_action.rs index 31d5e8e6..4ec62d55 100644 --- a/rust/src/serialization/governance/proposals/update_committee_action.rs +++ b/rust/src/serialization/governance/proposals/update_committee_action.rs @@ -42,7 +42,7 @@ impl DeserializeEmbeddedGroup for UpdateCommitteeAction { .map_err(|e| e.annotate("gov_action_id"))?; let members_to_remove = - CredentialsSet::deserialize(raw).map_err(|e| e.annotate("members_to_remove"))?; + Credentials::deserialize(raw).map_err(|e| e.annotate("members_to_remove"))?; let committee = Committee::deserialize_as_embedded_group(raw, cbor_event::Len::Len(2)) .map_err(|e| e.annotate("committee"))?; diff --git a/rust/src/serialization/metadata.rs b/rust/src/serialization/metadata.rs index 97ca0011..d6ae1d72 100644 --- a/rust/src/serialization/metadata.rs +++ b/rust/src/serialization/metadata.rs @@ -1,4 +1,4 @@ -use linked_hash_map::LinkedHashMap; +use hashlink::LinkedHashMap; use crate::*; use crate::serialization::utils::merge_option_plutus_list; diff --git a/rust/src/serialization/mod.rs b/rust/src/serialization/mod.rs index 2aa6c095..fd09f944 100644 --- a/rust/src/serialization/mod.rs +++ b/rust/src/serialization/mod.rs @@ -18,4 +18,7 @@ mod transaction_body; mod protocol_param_update; mod tx_inputs; mod credentials; -mod ed25519_key_hashes; \ No newline at end of file +mod ed25519_key_hashes; +mod witnesses; +mod credential; +mod crypto; \ No newline at end of file diff --git a/rust/src/serialization/plutus.rs b/rust/src/serialization/plutus.rs index 383738d9..5a80eed6 100644 --- a/rust/src/serialization/plutus.rs +++ b/rust/src/serialization/plutus.rs @@ -1,6 +1,7 @@ use crate::*; use std::io::SeekFrom; -use linked_hash_map::LinkedHashMap; +use hashlink::LinkedHashMap; +use crate::serialization::utils::skip_set_tag; impl cbor_event::se::Serialize for PlutusScript { fn serialize<'se, W: Write>( @@ -22,6 +23,8 @@ impl cbor_event::se::Serialize for PlutusScripts { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { + //TODO: uncomment this line when we conway ero will come + //serializer.write_tag(258)?; serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; for element in &self.0 { element.serialize(serializer)?; @@ -34,6 +37,7 @@ impl Deserialize for PlutusScripts { fn deserialize(raw: &mut Deserializer) -> Result { let mut arr = Vec::new(); (|| -> Result<_, DeserializeError> { + skip_set_tag(raw)?; let len = raw.array()?; while match len { cbor_event::Len::Len(n) => arr.len() < n as usize, diff --git a/rust/src/serialization/transaction_body.rs b/rust/src/serialization/transaction_body.rs index 56f28672..eb28a673 100644 --- a/rust/src/serialization/transaction_body.rs +++ b/rust/src/serialization/transaction_body.rs @@ -306,7 +306,7 @@ impl Deserialize for TransactionBody { required_signers = Some( (|| -> Result<_, DeserializeError> { read_len.read_elems(1)?; - Ok(Ed25519KeyHashesSet::deserialize(raw)?) + Ok(Ed25519KeyHashes::deserialize(raw)?) })() .map_err(|e| e.annotate("required_signers"))?, ); diff --git a/rust/src/serialization/witnesses/bootstrap_witness.rs b/rust/src/serialization/witnesses/bootstrap_witness.rs new file mode 100644 index 00000000..291f841a --- /dev/null +++ b/rust/src/serialization/witnesses/bootstrap_witness.rs @@ -0,0 +1,68 @@ +use std::io::{BufRead, Seek, Write}; +use cbor_event::de::Deserializer; +use cbor_event::se::Serializer; +use crate::{BootstrapWitness, DeserializeError, DeserializeFailure, Ed25519Signature, Vkey}; +use crate::protocol_types::{CBORSpecial, Deserialize, DeserializeEmbeddedGroup}; + +impl cbor_event::se::Serialize for BootstrapWitness { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(4))?; + self.vkey.serialize(serializer)?; + self.signature.serialize(serializer)?; + serializer.write_bytes(&self.chain_code)?; + serializer.write_bytes(&self.attributes)?; + Ok(serializer) + } +} + +impl Deserialize for BootstrapWitness { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let ret = Self::deserialize_as_embedded_group(raw, len); + match len { + cbor_event::Len::Len(_) => + /* TODO: check finite len somewhere */ + { + () + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("BootstrapWitness")) + } +} + +impl DeserializeEmbeddedGroup for BootstrapWitness { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + _: cbor_event::Len, + ) -> Result { + let vkey = (|| -> Result<_, DeserializeError> { Ok(Vkey::deserialize(raw)?) })() + .map_err(|e| e.annotate("vkey"))?; + let signature = + (|| -> Result<_, DeserializeError> { Ok(Ed25519Signature::deserialize(raw)?) })() + .map_err(|e| e.annotate("signature"))?; + let chain_code = (|| -> Result<_, DeserializeError> { Ok(raw.bytes()?) })() + .map_err(|e| e.annotate("chain_code"))?; + let attributes = (|| -> Result<_, DeserializeError> { Ok(raw.bytes()?) })() + .map_err(|e| e.annotate("attributes"))?; + Ok(BootstrapWitness { + vkey, + signature, + chain_code, + attributes, + }) + } +} \ No newline at end of file diff --git a/rust/src/serialization/witnesses/bootstrap_witnesses.rs b/rust/src/serialization/witnesses/bootstrap_witnesses.rs new file mode 100644 index 00000000..d4d4464c --- /dev/null +++ b/rust/src/serialization/witnesses/bootstrap_witnesses.rs @@ -0,0 +1,44 @@ +use std::io::{BufRead, Seek, Write}; +use cbor_event::de::Deserializer; +use cbor_event::se::Serializer; +use crate::{BootstrapWitness, BootstrapWitnesses, DeserializeError}; +use crate::protocol_types::Deserialize; +use crate::serialization::utils::skip_set_tag; + +impl cbor_event::se::Serialize for BootstrapWitnesses { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + //TODO: uncomment this line when we conway ero will come + //serializer.write_tag(258)?; + serializer.write_array(cbor_event::Len::Len(self.get_vec_wits().len() as u64))?; + for element in self.get_vec_wits() { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for BootstrapWitnesses { + fn deserialize(raw: &mut Deserializer) -> Result { + skip_set_tag(raw)?; + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == cbor_event::Type::Special { + assert_eq!(raw.special()?, cbor_event::Special::Break); + break; + } + arr.push(BootstrapWitness::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("BootstrapWitnesses"))?; + Ok(Self::from_vec_wits(arr)) + } +} \ No newline at end of file diff --git a/rust/src/serialization/witnesses/mod.rs b/rust/src/serialization/witnesses/mod.rs new file mode 100644 index 00000000..f23c6da7 --- /dev/null +++ b/rust/src/serialization/witnesses/mod.rs @@ -0,0 +1,6 @@ +mod vkeywitness; +mod vkeywitnesses; +mod bootstrap_witness; +mod bootstrap_witnesses; +mod transaction_witnesses_set; +mod transaction_witnesses_sets; \ No newline at end of file diff --git a/rust/src/serialization/witnesses/transaction_witnesses_set.rs b/rust/src/serialization/witnesses/transaction_witnesses_set.rs new file mode 100644 index 00000000..ebff78c2 --- /dev/null +++ b/rust/src/serialization/witnesses/transaction_witnesses_set.rs @@ -0,0 +1,245 @@ +use std::io::{BufRead, Seek, Write}; +use cbor_event::de::Deserializer; +use cbor_event::se::Serializer; +use crate::{BootstrapWitnesses, CBORReadLen, DeserializeError, DeserializeFailure, Key, Language, NativeScripts, PlutusList, PlutusScripts, Redeemers, TransactionWitnessSet, Vkeywitnesses}; +use crate::protocol_types::{CBORSpecial, CBORType, Deserialize, opt64}; +use crate::serialization::utils::merge_option_plutus_list; + +impl cbor_event::se::Serialize for TransactionWitnessSet { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + let mut has_plutus_v1 = false; + let mut has_plutus_v2 = false; + let mut has_plutus_v3 = false; + let plutus_added_length = match &self.plutus_scripts { + Some(scripts) => { + has_plutus_v1 = scripts.has_version(&Language::new_plutus_v1()); + has_plutus_v2 = scripts.has_version(&Language::new_plutus_v2()); + has_plutus_v3 = scripts.has_version(&Language::new_plutus_v3()); + (has_plutus_v1 as u64) + (has_plutus_v2 as u64) + (has_plutus_v3 as u64) + }, + _ => 0, + }; + serializer.write_map(cbor_event::Len::Len( + opt64(&self.vkeys) + + opt64(&self.native_scripts) + + opt64(&self.bootstraps) + + opt64(&self.plutus_data) + + opt64(&self.redeemers) + + plutus_added_length, + ))?; + if let Some(field) = &self.vkeys { + if field.0.len() > 0 { + serializer.write_unsigned_integer(0)?; + field.serialize(serializer)?; + } + } + if let Some(field) = &self.native_scripts { + if field.0.len() > 0 { + serializer.write_unsigned_integer(1)?; + field.serialize(serializer)?; + } + } + if let Some(field) = &self.bootstraps { + serializer.write_unsigned_integer(2)?; + field.serialize(serializer)?; + } + if let Some(plutus_scripts) = &self.plutus_scripts { + if has_plutus_v1 { + serializer.write_unsigned_integer(3)?; + plutus_scripts + .by_version(&Language::new_plutus_v1()) + .serialize(serializer)?; + } + if has_plutus_v2 { + serializer.write_unsigned_integer(6)?; + plutus_scripts + .by_version(&Language::new_plutus_v2()) + .serialize(serializer)?; + } + if has_plutus_v3 { + serializer.write_unsigned_integer(7)?; + plutus_scripts + .by_version(&Language::new_plutus_v3()) + .serialize(serializer)?; + } + } + if let Some(field) = &self.plutus_data { + serializer.write_unsigned_integer(4)?; + field.serialize(serializer)?; + } + if let Some(field) = &self.redeemers { + serializer.write_unsigned_integer(5)?; + field.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for TransactionWitnessSet { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.map()?; + let mut read_len = CBORReadLen::new(len); + let mut vkeys = None; + let mut native_scripts = None; + let mut bootstraps = None; + let mut plutus_scripts_v1 = None; + let mut plutus_scripts_v2 = None; + let mut plutus_scripts_v3 = None; + let mut plutus_data = None; + let mut redeemers = None; + let mut read = 0; + while match len { + cbor_event::Len::Len(n) => read < n as usize, + cbor_event::Len::Indefinite => true, + } { + match raw.cbor_type()? { + CBORType::UnsignedInteger => match raw.unsigned_integer()? { + 0 => { + if vkeys.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(0)).into()); + } + vkeys = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Vkeywitnesses::deserialize(raw)?) + })() + .map_err(|e| e.annotate("vkeys"))?, + ); + } + 1 => { + if native_scripts.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(1)).into()); + } + native_scripts = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(NativeScripts::deserialize(raw)?) + })() + .map_err(|e| e.annotate("native_scripts"))?, + ); + } + 2 => { + if bootstraps.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(2)).into()); + } + bootstraps = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(BootstrapWitnesses::deserialize(raw)?) + })() + .map_err(|e| e.annotate("bootstraps"))?, + ); + } + 3 => { + if plutus_scripts_v1.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(3)).into()); + } + plutus_scripts_v1 = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(PlutusScripts::deserialize(raw)?) + })() + .map_err(|e| e.annotate("plutus_scripts_v1"))?, + ); + } + 4 => { + if plutus_data.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(4)).into()); + } + plutus_data = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(PlutusList::deserialize(raw)?) + })() + .map_err(|e| e.annotate("plutus_data"))?, + ); + } + 5 => { + if redeemers.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(5)).into()); + } + redeemers = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(Redeemers::deserialize(raw)?) + })() + .map_err(|e| e.annotate("redeemers"))?, + ); + } + 6 => { + if plutus_scripts_v2.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(6)).into()); + } + plutus_scripts_v2 = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(PlutusScripts::deserialize(raw)? + .map_as_version(&Language::new_plutus_v2())) + })() + .map_err(|e| e.annotate("plutus_scripts_v2"))?, + ); + } + 7 => { + if plutus_scripts_v3.is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Uint(7)).into()); + } + plutus_scripts_v3 = Some( + (|| -> Result<_, DeserializeError> { + read_len.read_elems(1)?; + Ok(PlutusScripts::deserialize(raw)? + .map_as_version(&Language::new_plutus_v3())) + })() + .map_err(|e| e.annotate("plutus_scripts_v3"))?, + ); + } + unknown_key => { + return Err( + DeserializeFailure::UnknownKey(Key::Uint(unknown_key)).into() + ) + } + }, + CBORType::Text => match raw.text()?.as_str() { + unknown_key => { + return Err(DeserializeFailure::UnknownKey(Key::Str( + unknown_key.to_owned(), + )) + .into()) + } + }, + CBORType::Special => match len { + cbor_event::Len::Len(_) => { + return Err(DeserializeFailure::BreakInDefiniteLen.into()) + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => break, + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + }, + other_type => { + return Err(DeserializeFailure::UnexpectedKeyType(other_type).into()) + } + } + read += 1; + } + read_len.finish()?; + let mut plutus_scripts = None; + plutus_scripts = merge_option_plutus_list(plutus_scripts, plutus_scripts_v1); + plutus_scripts = merge_option_plutus_list(plutus_scripts, plutus_scripts_v2); + plutus_scripts = merge_option_plutus_list(plutus_scripts, plutus_scripts_v3); + + Ok(Self { + vkeys, + native_scripts, + bootstraps, + plutus_scripts, + plutus_data, + redeemers, + }) + })() + .map_err(|e| e.annotate("TransactionWitnessSet")) + } +} \ No newline at end of file diff --git a/rust/src/serialization/witnesses/transaction_witnesses_sets.rs b/rust/src/serialization/witnesses/transaction_witnesses_sets.rs new file mode 100644 index 00000000..a3b21bb8 --- /dev/null +++ b/rust/src/serialization/witnesses/transaction_witnesses_sets.rs @@ -0,0 +1,40 @@ +use std::io::{BufRead, Seek, Write}; +use cbor_event::de::Deserializer; +use cbor_event::se::Serializer; +use crate::{DeserializeError, TransactionWitnessSet, TransactionWitnessSets}; +use crate::protocol_types::{CBORSpecial, CBORType, Deserialize}; + +impl cbor_event::se::Serialize for TransactionWitnessSets { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for TransactionWitnessSets { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(TransactionWitnessSet::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("TransactionWitnessSets"))?; + Ok(Self(arr)) + } +} \ No newline at end of file diff --git a/rust/src/serialization/witnesses/vkeywitness.rs b/rust/src/serialization/witnesses/vkeywitness.rs new file mode 100644 index 00000000..7891109b --- /dev/null +++ b/rust/src/serialization/witnesses/vkeywitness.rs @@ -0,0 +1,51 @@ +use std::io::{BufRead, Seek, Write}; +use cbor_event::de::Deserializer; +use cbor_event::se::Serializer; +use crate::protocol_types::Deserialize; +use crate::{DeserializeError, DeserializeFailure, Ed25519Signature, Vkey, Vkeywitness}; + +impl cbor_event::se::Serialize for Vkeywitness { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.vkey.serialize(serializer)?; + self.signature.serialize(serializer) + } +} + +impl Deserialize for Vkeywitness { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let vkey = (|| -> Result<_, DeserializeError> { Ok(Vkey::deserialize(raw)?) })() + .map_err(|e| e.annotate("vkey"))?; + let signature = + (|| -> Result<_, DeserializeError> { Ok(Ed25519Signature::deserialize(raw)?) })() + .map_err(|e| e.annotate("signature"))?; + let ret = Ok(Vkeywitness::new(&vkey, &signature)); + match len { + cbor_event::Len::Len(n) => match n { + 2 => (), + _ => { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 2, len, "", + )) + .into()) + } + }, + cbor_event::Len::Indefinite => match raw.special()? { + cbor_event::Special::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("Vkeywitness")) + } +} \ No newline at end of file diff --git a/rust/src/serialization/witnesses/vkeywitnesses.rs b/rust/src/serialization/witnesses/vkeywitnesses.rs new file mode 100644 index 00000000..6b39805c --- /dev/null +++ b/rust/src/serialization/witnesses/vkeywitnesses.rs @@ -0,0 +1,44 @@ +use std::io::{BufRead, Seek, Write}; +use cbor_event::de::Deserializer; +use cbor_event::se::Serializer; +use crate::protocol_types::Deserialize; +use crate::{DeserializeError, Vkeywitness, Vkeywitnesses}; +use crate::serialization::utils::skip_set_tag; + +impl cbor_event::se::Serialize for Vkeywitnesses { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + //TODO: uncomment this line when we conway ero will come + //serializer.write_tag(258)?; + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for Vkeywitnesses { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + skip_set_tag(raw)?; + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == cbor_event::Type::Special { + assert_eq!(raw.special()?, cbor_event::Special::Break); + break; + } + arr.push(Vkeywitness::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("Vkeywitnesses"))?; + Ok(Self(arr)) + } +} \ No newline at end of file diff --git a/rust/src/tests/builders/certificates_builder.rs b/rust/src/tests/builders/certificates_builder.rs index fbf3f0ad..bdd3c3ad 100644 --- a/rust/src/tests/builders/certificates_builder.rs +++ b/rust/src/tests/builders/certificates_builder.rs @@ -49,7 +49,7 @@ fn certificates_builder_deposit_no_refund_test() { let staking_cred = Credential::from_keyhash(&fake_key_hash(10)); let reward_address = RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &staking_cred); - let mut owners = Ed25519KeyHashesSet::new(); + let mut owners = Ed25519KeyHashes::new(); owners.add(&fake_key_hash(11)); owners.add(&fake_key_hash(12)); let relays = Relays::new(); @@ -211,7 +211,7 @@ fn certificates_builder_refund_no_deposit_test() { let staking_cred = Credential::from_keyhash(&fake_key_hash(10)); let reward_address = RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &staking_cred); - let mut owners = Ed25519KeyHashesSet::new(); + let mut owners = Ed25519KeyHashes::new(); owners.add(&fake_key_hash(11)); owners.add(&fake_key_hash(12)); let relays = Relays::new(); @@ -374,7 +374,7 @@ fn certificates_builder_req_signers_test() { let staking_cred = Credential::from_keyhash(&key_hash_10); let reward_address = RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &staking_cred); - let mut owners = Ed25519KeyHashesSet::new(); + let mut owners = Ed25519KeyHashes::new(); owners.add(&key_hash_11); owners.add(&key_hash_12); let relays = Relays::new(); diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index 61bd1ef2..46a5de47 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -4459,7 +4459,7 @@ fn test_required_signers() { let tx1: TransactionBody = tx_builder.build().unwrap(); assert!(tx1.required_signers.is_some()); - let rs: Ed25519KeyHashesSet = tx1.required_signers.unwrap(); + let rs: Ed25519KeyHashes = tx1.required_signers.unwrap(); assert_eq!(rs.len(), 3); assert!(rs.contains(&s1)); assert!(rs.contains(&s2)); @@ -4477,7 +4477,7 @@ fn test_required_signers_are_added_to_the_witness_estimate() { &Value::new(&to_bignum(10_000_000)), ); - keys.0.iter().for_each(|k| { + keys.to_vec().iter().for_each(|k| { tx_builder.add_required_signer(k); }); @@ -4491,12 +4491,12 @@ fn test_required_signers_are_added_to_the_witness_estimate() { ); assert_eq!( - count_fake_witnesses_with_required_signers(&Ed25519KeyHashes(vec![fake_key_hash(1)]),), + count_fake_witnesses_with_required_signers(&Ed25519KeyHashes::from_vec(vec![fake_key_hash(1)]),), 2 ); assert_eq!( - count_fake_witnesses_with_required_signers(&Ed25519KeyHashes(vec![ + count_fake_witnesses_with_required_signers(&Ed25519KeyHashes::from_vec(vec![ fake_key_hash(1), fake_key_hash(2) ]),), @@ -4505,7 +4505,7 @@ fn test_required_signers_are_added_to_the_witness_estimate() { // This case still produces only 3 fake signatures, because the same key is already used in the input address assert_eq!( - count_fake_witnesses_with_required_signers(&Ed25519KeyHashes(vec![ + count_fake_witnesses_with_required_signers(&Ed25519KeyHashes::from_vec(vec![ fake_key_hash(1), fake_key_hash(2), fake_key_hash(0) @@ -4515,7 +4515,7 @@ fn test_required_signers_are_added_to_the_witness_estimate() { // When a different key is used - 4 fake witnesses are produced assert_eq!( - count_fake_witnesses_with_required_signers(&Ed25519KeyHashes(vec![ + count_fake_witnesses_with_required_signers(&Ed25519KeyHashes::from_vec(vec![ fake_key_hash(1), fake_key_hash(2), fake_key_hash(3) diff --git a/rust/src/tests/builders/voting_proposal_builder.rs b/rust/src/tests/builders/voting_proposal_builder.rs index b028a256..c26cd47c 100644 --- a/rust/src/tests/builders/voting_proposal_builder.rs +++ b/rust/src/tests/builders/voting_proposal_builder.rs @@ -78,7 +78,7 @@ fn voting_proposal_builder_all_proposals() { let mut committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); - let mut members_to_remove = CredentialsSet::new(); + let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); let committee_action = UpdateCommitteeAction::new(&committee, &members_to_remove); let wrapped_committee_action = GovernanceAction::new_new_committee_action(&committee_action); @@ -217,7 +217,7 @@ fn voting_proposal_builder_with_plutus_script_witness() { let mut committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); - let mut members_to_remove = CredentialsSet::new(); + let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); let committee_action = UpdateCommitteeAction::new(&committee, &members_to_remove); let wrapped_committee_action = GovernanceAction::new_new_committee_action(&committee_action); @@ -325,7 +325,7 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { let mut committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); - let mut members_to_remove = CredentialsSet::new(); + let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); let committee_action = UpdateCommitteeAction::new(&committee, &members_to_remove); let wrapped_committee_action= GovernanceAction::new_new_committee_action(&committee_action); diff --git a/rust/src/tests/crypto.rs b/rust/src/tests/crypto.rs new file mode 100644 index 00000000..8be8742a --- /dev/null +++ b/rust/src/tests/crypto.rs @@ -0,0 +1,86 @@ +use crate::*; + +#[test] +fn nonce_identity() { + let orig = Nonce::new_identity(); + let deser = Nonce::deserialize(&mut Deserializer::from(std::io::Cursor::new( + orig.to_bytes(), + ))) + .unwrap(); + assert_eq!(orig.to_bytes(), deser.to_bytes()); +} + +#[test] +fn nonce_hash() { + let orig = Nonce::new_from_hash(vec![ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, + ]) + .unwrap(); + let deser = Nonce::deserialize(&mut Deserializer::from(std::io::Cursor::new( + orig.to_bytes(), + ))) + .unwrap(); + assert_eq!(orig.to_bytes(), deser.to_bytes()); +} + +#[test] +fn xprv_128_test() { + // art forum devote street sure rather head chuckle guard poverty release quote oak craft enemy + let entropy = [ + 0x0c, 0xcb, 0x74, 0xf3, 0x6b, 0x7d, 0xa1, 0x64, 0x9a, 0x81, 0x44, 0x67, 0x55, 0x22, 0xd4, + 0xd8, 0x09, 0x7c, 0x64, 0x12, + ]; + let root_key = Bip32PrivateKey::from_bip39_entropy(&entropy, &[]); + + assert_eq!(hex::encode(&root_key.as_bytes()), "b8f2bece9bdfe2b0282f5bad705562ac996efb6af96b648f4445ec44f47ad95c10e3d72f26ed075422a36ed8585c745a0e1150bcceba2357d058636991f38a3791e248de509c070d812ab2fda57860ac876bc489192c1ef4ce253c197ee219a4"); + let xprv_128 = root_key.to_128_xprv(); + // test the 128 xprv is the right format + assert_eq!(hex::encode(&xprv_128), "b8f2bece9bdfe2b0282f5bad705562ac996efb6af96b648f4445ec44f47ad95c10e3d72f26ed075422a36ed8585c745a0e1150bcceba2357d058636991f38a37cf76399a210de8720e9fa894e45e41e29ab525e30bc402801c076250d1585bcd91e248de509c070d812ab2fda57860ac876bc489192c1ef4ce253c197ee219a4"); + let root_key_copy = Bip32PrivateKey::from_128_xprv(&xprv_128).unwrap(); + + // test converting to and back is equivalent to the identity function + assert_eq!(root_key.to_bech32(), root_key_copy.to_bech32()); +} + +#[test] +fn chaincode_gen() { + // art forum devote street sure rather head chuckle guard poverty release quote oak craft enemy + let entropy = [ + 0x0c, 0xcb, 0x74, 0xf3, 0x6b, 0x7d, 0xa1, 0x64, 0x9a, 0x81, 0x44, 0x67, 0x55, 0x22, 0xd4, + 0xd8, 0x09, 0x7c, 0x64, 0x12, + ]; + let root_key = Bip32PrivateKey::from_bip39_entropy(&entropy, &[]); + + let prv_chaincode = root_key.chaincode(); + assert_eq!( + hex::encode(&prv_chaincode), + "91e248de509c070d812ab2fda57860ac876bc489192c1ef4ce253c197ee219a4" + ); + + let pub_chaincode = root_key.to_public().chaincode(); + assert_eq!( + hex::encode(&pub_chaincode), + "91e248de509c070d812ab2fda57860ac876bc489192c1ef4ce253c197ee219a4" + ); +} + +#[test] +fn private_key_from_bech32() { + let pk = PrivateKey::generate_ed25519().unwrap(); + let pk_ext = PrivateKey::generate_ed25519extended().unwrap(); + + assert_eq!( + PrivateKey::from_bech32(&pk.to_bech32()).unwrap().as_bytes(), + pk.as_bytes(), + ); + assert_eq!( + PrivateKey::from_bech32(&pk_ext.to_bech32()) + .unwrap() + .as_bytes(), + pk_ext.as_bytes(), + ); + + let er = PrivateKey::from_bech32("qwe"); + assert!(er.is_err()); +} diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index ed9aac95..e0a5b0ce 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -209,22 +209,22 @@ fn native_scripts_get_pubkeys() { let keyhash2 = keyhash(2); let keyhash3 = keyhash(3); - let pks1 = Ed25519KeyHashesSet::from(&pkscript(&keyhash1)); + let pks1 = Ed25519KeyHashes::from(&pkscript(&keyhash1)); assert_eq!(pks1.len(), 1); assert!(pks1.contains(&keyhash1)); let pks2 = - Ed25519KeyHashesSet::from(&NativeScript::new_timelock_start(&TimelockStart::new(123))); + Ed25519KeyHashes::from(&NativeScript::new_timelock_start(&TimelockStart::new(123))); assert_eq!(pks2.len(), 0); - let pks3 = Ed25519KeyHashesSet::from(&NativeScript::new_script_all(&ScriptAll::new( + let pks3 = Ed25519KeyHashes::from(&NativeScript::new_script_all(&ScriptAll::new( &scripts_vec(vec![&pkscript(&keyhash1), &pkscript(&keyhash2)]), ))); assert_eq!(pks3.len(), 2); assert!(pks3.contains(&keyhash1)); assert!(pks3.contains(&keyhash2)); - let pks4 = Ed25519KeyHashesSet::from(&NativeScript::new_script_any(&ScriptAny::new( + let pks4 = Ed25519KeyHashes::from(&NativeScript::new_script_any(&ScriptAny::new( &scripts_vec(vec![ &NativeScript::new_script_n_of_k(&ScriptNOfK::new( 1, diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/mock_objects.rs index 0a871c91..fe85ea84 100644 --- a/rust/src/tests/mock_objects.rs +++ b/rust/src/tests/mock_objects.rs @@ -128,7 +128,7 @@ pub(crate) fn crate_full_pool_params() -> PoolParams { cost: Coin::from(44_444u32), margin: UnitInterval::new(&BigNum::from(44_444u32), &BigNum::from(44_444u32)), reward_account: RewardAddress::new(2, &Credential::from_keyhash(&fake_key_hash(3))), - pool_owners: Ed25519KeyHashesSet(vec![fake_key_hash(4), fake_key_hash(5)].into_iter().collect()), + pool_owners: Ed25519KeyHashes::from_vec(vec![fake_key_hash(4), fake_key_hash(5)].into_iter().collect()), relays: Relays(vec![Relay::new_multi_host_name(&MultiHostName::new( &DNSRecordSRV::new("iohk.io".to_string()).unwrap(), ))]), diff --git a/rust/src/tests/mod.rs b/rust/src/tests/mod.rs index bd63e78d..27eb5ac9 100644 --- a/rust/src/tests/mod.rs +++ b/rust/src/tests/mod.rs @@ -6,4 +6,5 @@ mod mock_objects; mod protocol_types; mod serialization; mod plutus; -mod metadata; \ No newline at end of file +mod metadata; +mod crypto; \ No newline at end of file diff --git a/rust/src/tests/protocol_types/governance/proposals.rs b/rust/src/tests/protocol_types/governance/proposals.rs index db24880a..9865db19 100644 --- a/rust/src/tests/protocol_types/governance/proposals.rs +++ b/rust/src/tests/protocol_types/governance/proposals.rs @@ -58,7 +58,7 @@ fn hard_fork_initiation_action_setters_getters_test() { fn new_committee_action_setters_getters_test() { let action_id = create_action_id(); let committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); - let members_to_remove = CredentialsSet::from_iter( + let members_to_remove = Credentials::from_iter( vec![ Credential::from_keyhash(&fake_key_hash(1)), Credential::from_keyhash(&fake_key_hash(2)), diff --git a/rust/src/tests/serialization/certificates.rs b/rust/src/tests/serialization/certificates.rs index 93a45717..37c53ec4 100644 --- a/rust/src/tests/serialization/certificates.rs +++ b/rust/src/tests/serialization/certificates.rs @@ -194,7 +194,7 @@ fn move_instantaneous_reward_to_stake_creds_ser_round_trip() { fn pool_registration_ser_round_trip() { let staking_cred = Credential::from_keyhash(&fake_key_hash(1)); let reward_address = RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &staking_cred); - let mut owners = Ed25519KeyHashesSet::new(); + let mut owners = Ed25519KeyHashes::new(); owners.add(&fake_key_hash(2)); owners.add(&fake_key_hash(3)); let mut relays = Relays::new(); diff --git a/rust/src/tests/serialization/governance/proposals.rs b/rust/src/tests/serialization/governance/proposals.rs index fd6c8e4b..724902e4 100644 --- a/rust/src/tests/serialization/governance/proposals.rs +++ b/rust/src/tests/serialization/governance/proposals.rs @@ -136,7 +136,7 @@ fn new_committee_action_ser_round_trip() { committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); committee.add_member(&Credential::from_scripthash(&fake_script_hash(2)), 2); - let mut members_to_remove = CredentialsSet::new(); + let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); members_to_remove.add(&Credential::from_scripthash(&fake_script_hash(2))); @@ -159,7 +159,7 @@ fn new_committee_action_with_action_id_ser_round_trip() { committee.add_member(&Credential::from_keyhash(&fake_key_hash(1)), 1); committee.add_member(&Credential::from_scripthash(&fake_script_hash(2)), 2); - let mut members_to_remove = CredentialsSet::new(); + let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); members_to_remove.add(&Credential::from_scripthash(&fake_script_hash(2))); @@ -178,7 +178,7 @@ fn new_committee_action_with_action_id_ser_round_trip() { #[test] fn new_committee_action_with_empty_ser_round_trip() { let committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); - let members_to_remove = CredentialsSet::new(); + let members_to_remove = Credentials::new(); let proposal = UpdateCommitteeAction::new(&committee, &members_to_remove); let proposal_wrapped = GovernanceAction::new_new_committee_action(&proposal); diff --git a/rust/src/tests/serialization/transaction_body.rs b/rust/src/tests/serialization/transaction_body.rs index 60e90a57..c46850e1 100644 --- a/rust/src/tests/serialization/transaction_body.rs +++ b/rust/src/tests/serialization/transaction_body.rs @@ -16,7 +16,7 @@ fn transaction_round_trip_test() { .unwrap(); mint.insert(&fake_policy_id(3), &mint_asset); - let mut req_signers = Ed25519KeyHashesSet::new(); + let mut req_signers = Ed25519KeyHashes::new(); req_signers.add(&fake_key_hash(5)); let mut collateral_inputs = TransactionInputs::new(); From 304e79d8de67afc6101d2759c01418200a8bec49 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 10 Feb 2024 22:13:41 +0800 Subject: [PATCH 219/349] split plutus.rs into separate files --- build-and-test.sh | 2 +- .../crypto/impl_signature_macro.rs | 1 + rust/src/protocol_types/plutus/cost_model.rs | 63 ++ rust/src/protocol_types/plutus/cost_models.rs | 100 +++ .../protocol_types/plutus/ex_unit_prices.rs | 39 + rust/src/protocol_types/plutus/ex_units.rs | 39 + rust/src/protocol_types/plutus/language.rs | 69 ++ rust/src/protocol_types/plutus/languages.rs | 30 + rust/src/protocol_types/plutus/mod.rs | 37 + .../{plutus.rs => plutus/plutus_data.rs} | 747 +----------------- .../protocol_types/plutus/plutus_script.rs | 154 ++++ .../protocol_types/plutus/plutus_scripts.rs | 58 ++ rust/src/protocol_types/plutus/redeemer.rs | 61 ++ .../src/protocol_types/plutus/redeemer_tag.rs | 72 ++ rust/src/protocol_types/plutus/redeemers.rs | 45 ++ rust/src/protocol_types/plutus/strings.rs | 24 + rust/src/serialization/crypto/nonce.rs | 2 +- rust/src/serialization/mod.rs | 4 +- rust/src/serialization/plutus.rs | 696 ---------------- rust/src/serialization/plutus/cost_model.rs | 36 + rust/src/serialization/plutus/cost_models.rs | 44 ++ .../serialization/plutus/ex_unit_prices.rs | 41 + rust/src/serialization/plutus/ex_units.rs | 36 + rust/src/serialization/plutus/language.rs | 26 + rust/src/serialization/plutus/languages.rs | 36 + rust/src/serialization/plutus/mod.rs | 13 + rust/src/serialization/plutus/plutus_data.rs | 266 +++++++ .../src/serialization/plutus/plutus_script.rs | 17 + .../serialization/plutus/plutus_scripts.rs | 40 + rust/src/serialization/plutus/redeemer.rs | 47 ++ rust/src/serialization/plutus/redeemer_tag.rs | 49 ++ rust/src/serialization/plutus/redeemers.rs | 36 + rust/src/serialization/plutus/strings.rs | 36 + 33 files changed, 1520 insertions(+), 1446 deletions(-) create mode 100644 rust/src/protocol_types/plutus/cost_model.rs create mode 100644 rust/src/protocol_types/plutus/cost_models.rs create mode 100644 rust/src/protocol_types/plutus/ex_unit_prices.rs create mode 100644 rust/src/protocol_types/plutus/ex_units.rs create mode 100644 rust/src/protocol_types/plutus/language.rs create mode 100644 rust/src/protocol_types/plutus/languages.rs create mode 100644 rust/src/protocol_types/plutus/mod.rs rename rust/src/protocol_types/{plutus.rs => plutus/plutus_data.rs} (59%) create mode 100644 rust/src/protocol_types/plutus/plutus_script.rs create mode 100644 rust/src/protocol_types/plutus/plutus_scripts.rs create mode 100644 rust/src/protocol_types/plutus/redeemer.rs create mode 100644 rust/src/protocol_types/plutus/redeemer_tag.rs create mode 100644 rust/src/protocol_types/plutus/redeemers.rs create mode 100644 rust/src/protocol_types/plutus/strings.rs delete mode 100644 rust/src/serialization/plutus.rs create mode 100644 rust/src/serialization/plutus/cost_model.rs create mode 100644 rust/src/serialization/plutus/cost_models.rs create mode 100644 rust/src/serialization/plutus/ex_unit_prices.rs create mode 100644 rust/src/serialization/plutus/ex_units.rs create mode 100644 rust/src/serialization/plutus/language.rs create mode 100644 rust/src/serialization/plutus/languages.rs create mode 100644 rust/src/serialization/plutus/mod.rs create mode 100644 rust/src/serialization/plutus/plutus_data.rs create mode 100644 rust/src/serialization/plutus/plutus_script.rs create mode 100644 rust/src/serialization/plutus/plutus_scripts.rs create mode 100644 rust/src/serialization/plutus/redeemer.rs create mode 100644 rust/src/serialization/plutus/redeemer_tag.rs create mode 100644 rust/src/serialization/plutus/redeemers.rs create mode 100644 rust/src/serialization/plutus/strings.rs diff --git a/build-and-test.sh b/build-and-test.sh index ecd5f31a..10ddba6b 100644 --- a/build-and-test.sh +++ b/build-and-test.sh @@ -1 +1 @@ -. test.sh && npm run rust:build-nodejs \ No newline at end of file +. ./test.sh && npm run rust:build-nodejs diff --git a/rust/src/protocol_types/crypto/impl_signature_macro.rs b/rust/src/protocol_types/crypto/impl_signature_macro.rs index 747d5774..5cfb1712 100644 --- a/rust/src/protocol_types/crypto/impl_signature_macro.rs +++ b/rust/src/protocol_types/crypto/impl_signature_macro.rs @@ -28,6 +28,7 @@ macro_rules! impl_signature { } pub fn from_hex(input: &str) -> Result<$name, JsError> { + use std::str::FromStr; chain_crypto::Signature::from_str(input) .map_err(|e| JsError::from_str(&format!("{:?}", e))) .map($name) diff --git a/rust/src/protocol_types/plutus/cost_model.rs b/rust/src/protocol_types/plutus/cost_model.rs new file mode 100644 index 00000000..8b28ea4a --- /dev/null +++ b/rust/src/protocol_types/plutus/cost_model.rs @@ -0,0 +1,63 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct CostModel(pub(crate) Vec); + +impl_to_from!(CostModel); + +#[wasm_bindgen] +impl CostModel { + /// Creates a new CostModels instance of an unrestricted length + pub fn new() -> Self { + Self(Vec::new()) + } + + /// Sets the cost at the specified index to the specified value. + /// In case the operation index is larger than the previous largest used index, + /// it will fill any inbetween indexes with zeroes + pub fn set(&mut self, operation: usize, cost: &Int) -> Result { + let len = self.0.len(); + let idx = operation.clone(); + if idx >= len { + for _ in 0..(idx - len + 1) { + self.0.push(Int::new_i32(0)); + } + } + let old = self.0[idx].clone(); + self.0[idx] = cost.clone(); + Ok(old) + } + + pub fn get(&self, operation: usize) -> Result { + let max = self.0.len(); + if operation >= max { + return Err(JsError::from_str(&format!( + "CostModel operation {} out of bounds. Max is {}", + operation, max + ))); + } + Ok(self.0[operation].clone()) + } + + pub fn len(&self) -> usize { + self.0.len() + } +} + +impl From> for CostModel { + fn from(values: Vec) -> Self { + CostModel(values.iter().map(|x| Int(*x)).collect()) + } +} diff --git a/rust/src/protocol_types/plutus/cost_models.rs b/rust/src/protocol_types/plutus/cost_models.rs new file mode 100644 index 00000000..8b63cc15 --- /dev/null +++ b/rust/src/protocol_types/plutus/cost_models.rs @@ -0,0 +1,100 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct Costmdls(pub(crate) std::collections::BTreeMap); + +impl_to_from!(Costmdls); + +#[wasm_bindgen] +impl Costmdls { + pub fn new() -> Self { + Self(std::collections::BTreeMap::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn insert(&mut self, key: &Language, value: &CostModel) -> Option { + self.0.insert(key.clone(), value.clone()) + } + + pub fn get(&self, key: &Language) -> Option { + self.0.get(key).map(|v| v.clone()) + } + + pub fn keys(&self) -> Languages { + Languages(self.0.iter().map(|(k, _v)| k.clone()).collect::>()) + } + + pub(crate) fn language_views_encoding(&self) -> Vec { + let mut serializer = Serializer::new_vec(); + fn key_len(l: &Language) -> usize { + if l.kind() == LanguageKind::PlutusV1 { + let mut serializer = Serializer::new_vec(); + serializer.write_bytes(l.to_bytes()).unwrap(); + return serializer.finalize().len(); + } + l.to_bytes().len() + } + let mut keys: Vec = self.0.iter().map(|(k, _v)| k.clone()).collect(); + // keys must be in canonical ordering first + keys.sort_by(|lhs, rhs| match key_len(lhs).cmp(&key_len(rhs)) { + std::cmp::Ordering::Equal => lhs.cmp(&rhs), + len_order => len_order, + }); + serializer + .write_map(cbor_event::Len::Len(self.0.len() as u64)) + .unwrap(); + for key in keys.iter() { + if key.kind() == LanguageKind::PlutusV1 { + serializer.write_bytes(key.to_bytes()).unwrap(); + let cost_model = self.0.get(&key).unwrap(); + // Due to a bug in the cardano-node input-output-hk/cardano-ledger-specs/issues/2512 + // we must use indefinite length serialization in this inner bytestring to match it + let mut cost_model_serializer = Serializer::new_vec(); + cost_model_serializer + .write_array(cbor_event::Len::Indefinite) + .unwrap(); + for cost in &cost_model.0 { + cost.serialize(&mut cost_model_serializer).unwrap(); + } + cost_model_serializer + .write_special(cbor_event::Special::Break) + .unwrap(); + serializer + .write_bytes(cost_model_serializer.finalize()) + .unwrap(); + } else { + serializer.serialize(key).unwrap(); + serializer.serialize(self.0.get(&key).unwrap()).unwrap(); + } + } + serializer.finalize() + } + + pub fn retain_language_versions(&self, languages: &Languages) -> Costmdls { + let mut result = Costmdls::new(); + for lang in &languages.0 { + match self.get(&lang) { + Some(costmodel) => { + result.insert(&lang, &costmodel); + } + _ => {} + } + } + result + } +} diff --git a/rust/src/protocol_types/plutus/ex_unit_prices.rs b/rust/src/protocol_types/plutus/ex_unit_prices.rs new file mode 100644 index 00000000..d0efb4fd --- /dev/null +++ b/rust/src/protocol_types/plutus/ex_unit_prices.rs @@ -0,0 +1,39 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( +Clone, +Debug, +Hash, +Eq, +Ord, +PartialEq, +PartialOrd, +serde::Serialize, +serde::Deserialize, +JsonSchema, +)] +pub struct ExUnitPrices { + pub(crate) mem_price: SubCoin, + pub(crate) step_price: SubCoin, +} + +impl_to_from!(ExUnitPrices); + +#[wasm_bindgen] +impl ExUnitPrices { + pub fn mem_price(&self) -> SubCoin { + self.mem_price.clone() + } + + pub fn step_price(&self) -> SubCoin { + self.step_price.clone() + } + + pub fn new(mem_price: &SubCoin, step_price: &SubCoin) -> Self { + Self { + mem_price: mem_price.clone(), + step_price: step_price.clone(), + } + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/plutus/ex_units.rs b/rust/src/protocol_types/plutus/ex_units.rs new file mode 100644 index 00000000..e892ef12 --- /dev/null +++ b/rust/src/protocol_types/plutus/ex_units.rs @@ -0,0 +1,39 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct ExUnits { + pub(crate) mem: BigNum, + pub(crate) steps: BigNum, +} + +impl_to_from!(ExUnits); + +#[wasm_bindgen] +impl ExUnits { + pub fn mem(&self) -> BigNum { + self.mem.clone() + } + + pub fn steps(&self) -> BigNum { + self.steps.clone() + } + + pub fn new(mem: &BigNum, steps: &BigNum) -> Self { + Self { + mem: mem.clone(), + steps: steps.clone(), + } + } +} diff --git a/rust/src/protocol_types/plutus/language.rs b/rust/src/protocol_types/plutus/language.rs new file mode 100644 index 00000000..b09fa0ed --- /dev/null +++ b/rust/src/protocol_types/plutus/language.rs @@ -0,0 +1,69 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, + Copy, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub enum LanguageKind { + PlutusV1 = 0, + PlutusV2 = 1, + PlutusV3 = 2, +} + +impl LanguageKind { + pub(crate) fn from_u64(x: u64) -> Option { + match x { + 0 => Some(LanguageKind::PlutusV1), + 1 => Some(LanguageKind::PlutusV2), + 2 => Some(LanguageKind::PlutusV3), + _ => None, + } + } +} + +#[wasm_bindgen] +#[derive( + Clone, + Copy, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct Language(pub(crate) LanguageKind); + +impl_to_from!(Language); + +#[wasm_bindgen] +impl Language { + pub fn new_plutus_v1() -> Self { + Self(LanguageKind::PlutusV1) + } + + pub fn new_plutus_v2() -> Self { + Self(LanguageKind::PlutusV2) + } + + pub fn new_plutus_v3() -> Self { + Self(LanguageKind::PlutusV3) + } + + pub fn kind(&self) -> LanguageKind { + self.0.clone() + } +} diff --git a/rust/src/protocol_types/plutus/languages.rs b/rust/src/protocol_types/plutus/languages.rs new file mode 100644 index 00000000..57f5967f --- /dev/null +++ b/rust/src/protocol_types/plutus/languages.rs @@ -0,0 +1,30 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( +Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct Languages(pub(crate) Vec); + +#[wasm_bindgen] +impl Languages { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> Language { + self.0[index] + } + + pub fn add(&mut self, elem: Language) { + self.0.push(elem); + } + + pub fn list() -> Languages { + Languages(vec![Language::new_plutus_v1(), Language::new_plutus_v2()]) + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/plutus/mod.rs b/rust/src/protocol_types/plutus/mod.rs new file mode 100644 index 00000000..8d347e02 --- /dev/null +++ b/rust/src/protocol_types/plutus/mod.rs @@ -0,0 +1,37 @@ +mod plutus_script; +pub use plutus_script::*; + +mod language; +pub use language::*; + +mod languages; +pub use languages::*; +mod plutus_scripts; +pub use plutus_scripts::*; + +mod cost_model; +pub use cost_model::*; + +mod cost_models; +pub use cost_models::*; + +mod ex_unit_prices; +pub use ex_unit_prices::*; + +mod ex_units; +pub use ex_units::*; + +mod redeemer; +pub use redeemer::*; + +mod redeemer_tag; +pub use redeemer_tag::*; + +mod redeemers; +pub use redeemers::*; + +mod strings; +pub use strings::*; + +mod plutus_data; +pub use plutus_data::*; diff --git a/rust/src/protocol_types/plutus.rs b/rust/src/protocol_types/plutus/plutus_data.rs similarity index 59% rename from rust/src/protocol_types/plutus.rs rename to rust/src/protocol_types/plutus/plutus_data.rs index 4f7af727..3346ab90 100644 --- a/rust/src/protocol_types/plutus.rs +++ b/rust/src/protocol_types/plutus/plutus_data.rs @@ -3,9 +3,6 @@ use core::hash::Hasher; use hashlink::LinkedHashMap; use std::hash::Hash; -// This library was code-generated using an experimental CDDL to rust tool: -// https://github.com/Emurgo/cddl-codegen - use cbor_event::{ self, de::Deserializer, @@ -14,216 +11,6 @@ use cbor_event::{ use schemars::JsonSchema; -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub struct PlutusScript { - pub(crate) bytes: Vec, - pub(crate) language: LanguageKind, -} - -to_from_bytes!(PlutusScript); - -#[wasm_bindgen] -impl PlutusScript { - /** - * Creates a new Plutus script from the RAW bytes of the compiled script. - * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) - * If you creating this from those you should use PlutusScript::from_bytes() instead. - */ - pub fn new(bytes: Vec) -> PlutusScript { - Self::new_with_version(bytes, &Language::new_plutus_v1()) - } - - /** - * Creates a new Plutus script from the RAW bytes of the compiled script. - * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) - * If you creating this from those you should use PlutusScript::from_bytes() instead. - */ - pub fn new_v2(bytes: Vec) -> PlutusScript { - Self::new_with_version(bytes, &Language::new_plutus_v2()) - } - - /** - * Creates a new Plutus script from the RAW bytes of the compiled script. - * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) - * If you creating this from those you should use PlutusScript::from_bytes() instead. - */ - pub fn new_v3(bytes: Vec) -> PlutusScript { - Self::new_with_version(bytes, &Language::new_plutus_v3()) - } - - /** - * Creates a new Plutus script from the RAW bytes of the compiled script. - * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) - * If you creating this from those you should use PlutusScript::from_bytes() instead. - */ - pub fn new_with_version(bytes: Vec, language: &Language) -> PlutusScript { - Self { - bytes, - language: language.0.clone(), - } - } - - /** - * The raw bytes of this compiled Plutus script. - * If you need "cborBytes" for cardano-cli use PlutusScript::to_bytes() instead. - */ - pub fn bytes(&self) -> Vec { - self.bytes.clone() - } - - /// Same as `.from_bytes` but will consider the script as requiring the Plutus Language V2 - pub fn from_bytes_v2(bytes: Vec) -> Result { - Self::from_bytes_with_version(bytes, &Language::new_plutus_v2()) - } - - /// Same as `.from_bytes` but will consider the script as requiring the Plutus Language V3 - pub fn from_bytes_v3(bytes: Vec) -> Result { - Self::from_bytes_with_version(bytes, &Language::new_plutus_v3()) - } - - /// Same as `.from_bytes` but will consider the script as requiring the specified language version - pub fn from_bytes_with_version( - bytes: Vec, - language: &Language, - ) -> Result { - Ok(Self::new_with_version( - Self::from_bytes(bytes)?.bytes, - language, - )) - } - - /// Same as .from_hex but will consider the script as requiring the specified language version - pub fn from_hex_with_version( - hex_str: &str, - language: &Language, - ) -> Result { - Ok(Self::new_with_version( - Self::from_hex(hex_str)?.bytes, - language, - )) - } - - pub fn hash(&self) -> ScriptHash { - let mut bytes = Vec::with_capacity(self.bytes.len() + 1); - // https://github.com/input-output-hk/cardano-ledger/blob/master/eras/babbage/test-suite/cddl-files/babbage.cddl#L413 - bytes.extend_from_slice(&vec![self.script_namespace() as u8]); - bytes.extend_from_slice(&self.bytes); - ScriptHash::from(blake2b224(bytes.as_ref())) - } - - pub fn language_version(&self) -> Language { - Language(self.language.clone()) - } - - pub(crate) fn script_namespace(&self) -> ScriptHashNamespace { - match self.language { - LanguageKind::PlutusV1 => ScriptHashNamespace::PlutusScript, - LanguageKind::PlutusV2 => ScriptHashNamespace::PlutusScriptV2, - LanguageKind::PlutusV3 => ScriptHashNamespace::PlutusScriptV3, - } - } - - pub(crate) fn clone_as_version(&self, language: &Language) -> PlutusScript { - Self::new_with_version(self.bytes.clone(), language) - } -} - -impl serde::Serialize for PlutusScript { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - serializer.serialize_str(&hex::encode(&self.bytes)) - } -} - -impl<'de> serde::de::Deserialize<'de> for PlutusScript { - fn deserialize(deserializer: D) -> Result - where - D: serde::de::Deserializer<'de>, - { - let s = ::deserialize(deserializer)?; - hex::decode(&s) - .map(|bytes| PlutusScript::new(bytes)) - .map_err(|_err| { - serde::de::Error::invalid_value( - serde::de::Unexpected::Str(&s), - &"PlutusScript as hex string e.g. F8AB28C2 (without CBOR bytes tag)", - ) - }) - } -} - -impl JsonSchema for PlutusScript { - fn schema_name() -> String { - String::from("PlutusScript") - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - String::json_schema(gen) - } - fn is_referenceable() -> bool { - String::is_referenceable() - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct PlutusScripts(pub(crate) Vec); - -impl_to_from!(PlutusScripts); - -#[wasm_bindgen] -impl PlutusScripts { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> PlutusScript { - self.0[index].clone() - } - - pub fn add(&mut self, elem: &PlutusScript) { - self.0.push(elem.clone()); - } - - pub(crate) fn by_version(&self, language: &Language) -> PlutusScripts { - PlutusScripts( - self.0 - .iter() - .filter(|s| s.language_version().eq(language)) - .map(|s| s.clone()) - .collect(), - ) - } - - pub(crate) fn has_version(&self, language: &Language) -> bool { - self.0.iter().any(|s| s.language_version().eq(language)) - } - - pub(crate) fn merge(&self, other: &PlutusScripts) -> PlutusScripts { - let mut res = self.clone(); - for s in &other.0 { - res.add(s); - } - res - } - - pub(crate) fn map_as_version(&self, language: &Language) -> PlutusScripts { - let mut res = PlutusScripts::new(); - for s in &self.0 { - res.add(&s.clone_as_version(language)); - } - res - } -} - #[wasm_bindgen] #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] pub struct ConstrPlutusData { @@ -283,340 +70,6 @@ impl ConstrPlutusData { } } -#[wasm_bindgen] -#[derive( - Clone, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub struct CostModel(pub(crate) Vec); - -impl_to_from!(CostModel); - -#[wasm_bindgen] -impl CostModel { - /// Creates a new CostModels instance of an unrestricted length - pub fn new() -> Self { - Self(Vec::new()) - } - - /// Sets the cost at the specified index to the specified value. - /// In case the operation index is larger than the previous largest used index, - /// it will fill any inbetween indexes with zeroes - pub fn set(&mut self, operation: usize, cost: &Int) -> Result { - let len = self.0.len(); - let idx = operation.clone(); - if idx >= len { - for _ in 0..(idx - len + 1) { - self.0.push(Int::new_i32(0)); - } - } - let old = self.0[idx].clone(); - self.0[idx] = cost.clone(); - Ok(old) - } - - pub fn get(&self, operation: usize) -> Result { - let max = self.0.len(); - if operation >= max { - return Err(JsError::from_str(&format!( - "CostModel operation {} out of bounds. Max is {}", - operation, max - ))); - } - Ok(self.0[operation].clone()) - } - - pub fn len(&self) -> usize { - self.0.len() - } -} - -impl From> for CostModel { - fn from(values: Vec) -> Self { - CostModel(values.iter().map(|x| Int(*x)).collect()) - } -} - -#[wasm_bindgen] -#[derive( - Clone, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub struct Costmdls(pub(crate) std::collections::BTreeMap); - -impl_to_from!(Costmdls); - -#[wasm_bindgen] -impl Costmdls { - pub fn new() -> Self { - Self(std::collections::BTreeMap::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn insert(&mut self, key: &Language, value: &CostModel) -> Option { - self.0.insert(key.clone(), value.clone()) - } - - pub fn get(&self, key: &Language) -> Option { - self.0.get(key).map(|v| v.clone()) - } - - pub fn keys(&self) -> Languages { - Languages(self.0.iter().map(|(k, _v)| k.clone()).collect::>()) - } - - pub(crate) fn language_views_encoding(&self) -> Vec { - let mut serializer = Serializer::new_vec(); - fn key_len(l: &Language) -> usize { - if l.kind() == LanguageKind::PlutusV1 { - let mut serializer = Serializer::new_vec(); - serializer.write_bytes(l.to_bytes()).unwrap(); - return serializer.finalize().len(); - } - l.to_bytes().len() - } - let mut keys: Vec = self.0.iter().map(|(k, _v)| k.clone()).collect(); - // keys must be in canonical ordering first - keys.sort_by(|lhs, rhs| match key_len(lhs).cmp(&key_len(rhs)) { - std::cmp::Ordering::Equal => lhs.cmp(&rhs), - len_order => len_order, - }); - serializer - .write_map(cbor_event::Len::Len(self.0.len() as u64)) - .unwrap(); - for key in keys.iter() { - if key.kind() == LanguageKind::PlutusV1 { - serializer.write_bytes(key.to_bytes()).unwrap(); - let cost_model = self.0.get(&key).unwrap(); - // Due to a bug in the cardano-node input-output-hk/cardano-ledger-specs/issues/2512 - // we must use indefinite length serialization in this inner bytestring to match it - let mut cost_model_serializer = Serializer::new_vec(); - cost_model_serializer - .write_array(cbor_event::Len::Indefinite) - .unwrap(); - for cost in &cost_model.0 { - cost.serialize(&mut cost_model_serializer).unwrap(); - } - cost_model_serializer - .write_special(cbor_event::Special::Break) - .unwrap(); - serializer - .write_bytes(cost_model_serializer.finalize()) - .unwrap(); - } else { - serializer.serialize(key).unwrap(); - serializer.serialize(self.0.get(&key).unwrap()).unwrap(); - } - } - serializer.finalize() - } - - pub fn retain_language_versions(&self, languages: &Languages) -> Costmdls { - let mut result = Costmdls::new(); - for lang in &languages.0 { - match self.get(&lang) { - Some(costmodel) => { - result.insert(&lang, &costmodel); - } - _ => {} - } - } - result - } -} - -#[wasm_bindgen] -#[derive( - Clone, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub struct ExUnitPrices { - pub(crate) mem_price: SubCoin, - pub(crate) step_price: SubCoin, -} - -impl_to_from!(ExUnitPrices); - -#[wasm_bindgen] -impl ExUnitPrices { - pub fn mem_price(&self) -> SubCoin { - self.mem_price.clone() - } - - pub fn step_price(&self) -> SubCoin { - self.step_price.clone() - } - - pub fn new(mem_price: &SubCoin, step_price: &SubCoin) -> Self { - Self { - mem_price: mem_price.clone(), - step_price: step_price.clone(), - } - } -} - -#[wasm_bindgen] -#[derive( - Clone, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub struct ExUnits { - pub(crate) mem: BigNum, - pub(crate) steps: BigNum, -} - -impl_to_from!(ExUnits); - -#[wasm_bindgen] -impl ExUnits { - pub fn mem(&self) -> BigNum { - self.mem.clone() - } - - pub fn steps(&self) -> BigNum { - self.steps.clone() - } - - pub fn new(mem: &BigNum, steps: &BigNum) -> Self { - Self { - mem: mem.clone(), - steps: steps.clone(), - } - } -} - -#[wasm_bindgen] -#[derive( - Clone, - Copy, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub enum LanguageKind { - PlutusV1 = 0, - PlutusV2 = 1, - PlutusV3 = 2, -} - -impl LanguageKind { - pub(crate) fn from_u64(x: u64) -> Option { - match x { - 0 => Some(LanguageKind::PlutusV1), - 1 => Some(LanguageKind::PlutusV2), - 2 => Some(LanguageKind::PlutusV3), - _ => None, - } - } -} - -#[wasm_bindgen] -#[derive( - Clone, - Copy, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub struct Language(pub(crate) LanguageKind); - -impl_to_from!(Language); - -#[wasm_bindgen] -impl Language { - pub fn new_plutus_v1() -> Self { - Self(LanguageKind::PlutusV1) - } - - pub fn new_plutus_v2() -> Self { - Self(LanguageKind::PlutusV2) - } - - pub fn new_plutus_v3() -> Self { - Self(LanguageKind::PlutusV3) - } - - pub fn kind(&self) -> LanguageKind { - self.0.clone() - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct Languages(pub(crate) Vec); - -#[wasm_bindgen] -impl Languages { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> Language { - self.0[index] - } - - pub fn add(&mut self, elem: Language) { - self.0.push(elem); - } - - pub fn list() -> Languages { - Languages(vec![Language::new_plutus_v1(), Language::new_plutus_v2()]) - } -} - #[wasm_bindgen] #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] pub struct PlutusMap(pub(crate) LinkedHashMap); @@ -988,204 +441,6 @@ impl From> for PlutusList { } } -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct Redeemer { - pub(crate) tag: RedeemerTag, - pub(crate) index: BigNum, - pub(crate) data: PlutusData, - pub(crate) ex_units: ExUnits, -} - -impl_to_from!(Redeemer); - -#[wasm_bindgen] -impl Redeemer { - pub fn tag(&self) -> RedeemerTag { - self.tag.clone() - } - - pub fn index(&self) -> BigNum { - self.index.clone() - } - - pub fn data(&self) -> PlutusData { - self.data.clone() - } - - pub fn ex_units(&self) -> ExUnits { - self.ex_units.clone() - } - - pub fn new(tag: &RedeemerTag, index: &BigNum, data: &PlutusData, ex_units: &ExUnits) -> Self { - Self { - tag: tag.clone(), - index: index.clone(), - data: data.clone(), - ex_units: ex_units.clone(), - } - } - - #[allow(dead_code)] - pub(crate) fn clone_with_index(&self, index: &BigNum) -> Self { - Self { - tag: self.tag.clone(), - index: index.clone(), - data: self.data.clone(), - ex_units: self.ex_units.clone(), - } - } - - pub(crate) fn clone_with_index_and_tag(&self, index: &BigNum, tag: &RedeemerTag) -> Self { - Self { - tag: tag.clone(), - index: index.clone(), - data: self.data.clone(), - ex_units: self.ex_units.clone(), - } - } -} - -#[wasm_bindgen] -#[derive( - Copy, - Clone, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub enum RedeemerTagKind { - Spend, - Mint, - Cert, - Reward, - Vote, - VotingProposal, -} - -#[wasm_bindgen] -#[derive( - Clone, - Debug, - Hash, - Eq, - Ord, - PartialEq, - PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, -)] -pub struct RedeemerTag(pub(crate) RedeemerTagKind); - -impl_to_from!(RedeemerTag); - -#[wasm_bindgen] -impl RedeemerTag { - pub fn new_spend() -> Self { - Self(RedeemerTagKind::Spend) - } - - pub fn new_mint() -> Self { - Self(RedeemerTagKind::Mint) - } - - pub fn new_cert() -> Self { - Self(RedeemerTagKind::Cert) - } - - pub fn new_reward() -> Self { - Self(RedeemerTagKind::Reward) - } - - pub fn new_vote() -> Self { - Self(RedeemerTagKind::Vote) - } - - pub fn new_voting_proposal() -> Self { - Self(RedeemerTagKind::VotingProposal) - } - - pub fn kind(&self) -> RedeemerTagKind { - self.0 - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct Redeemers(pub(crate) Vec); - -impl_to_from!(Redeemers); - -#[wasm_bindgen] -impl Redeemers { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> Redeemer { - self.0[index].clone() - } - - pub fn add(&mut self, elem: &Redeemer) { - self.0.push(elem.clone()); - } - - pub fn total_ex_units(&self) -> Result { - let mut tot_mem = BigNum::zero(); - let mut tot_steps = BigNum::zero(); - for i in 0..self.0.len() { - let r: &Redeemer = &self.0[i]; - tot_mem = tot_mem.checked_add(&r.ex_units().mem())?; - tot_steps = tot_steps.checked_add(&r.ex_units().steps())?; - } - Ok(ExUnits::new(&tot_mem, &tot_steps)) - } -} - -impl From> for Redeemers { - fn from(values: Vec) -> Self { - Self(values) - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub struct Strings(pub(crate) Vec); - -#[wasm_bindgen] -impl Strings { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> String { - self.0[index].clone() - } - - pub fn add(&mut self, elem: String) { - self.0.push(elem); - } -} - // json /// JSON <-> PlutusData conversion schemas. @@ -1486,4 +741,4 @@ pub fn decode_plutus_datum_to_json_value( wrapper.insert(String::from(type_tag.unwrap()), json_value); Ok(Value::from(wrapper)) } -} \ No newline at end of file +} diff --git a/rust/src/protocol_types/plutus/plutus_script.rs b/rust/src/protocol_types/plutus/plutus_script.rs new file mode 100644 index 00000000..b3abc1bd --- /dev/null +++ b/rust/src/protocol_types/plutus/plutus_script.rs @@ -0,0 +1,154 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub struct PlutusScript { + pub(crate) bytes: Vec, + pub(crate) language: LanguageKind, +} + +to_from_bytes!(PlutusScript); + +#[wasm_bindgen] +impl PlutusScript { + /** + * Creates a new Plutus script from the RAW bytes of the compiled script. + * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) + * If you creating this from those you should use PlutusScript::from_bytes() instead. + */ + pub fn new(bytes: Vec) -> PlutusScript { + Self::new_with_version(bytes, &Language::new_plutus_v1()) + } + + /** + * Creates a new Plutus script from the RAW bytes of the compiled script. + * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) + * If you creating this from those you should use PlutusScript::from_bytes() instead. + */ + pub fn new_v2(bytes: Vec) -> PlutusScript { + Self::new_with_version(bytes, &Language::new_plutus_v2()) + } + + /** + * Creates a new Plutus script from the RAW bytes of the compiled script. + * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) + * If you creating this from those you should use PlutusScript::from_bytes() instead. + */ + pub fn new_v3(bytes: Vec) -> PlutusScript { + Self::new_with_version(bytes, &Language::new_plutus_v3()) + } + + /** + * Creates a new Plutus script from the RAW bytes of the compiled script. + * This does NOT include any CBOR encoding around these bytes (e.g. from "cborBytes" in cardano-cli) + * If you creating this from those you should use PlutusScript::from_bytes() instead. + */ + pub fn new_with_version(bytes: Vec, language: &Language) -> PlutusScript { + Self { + bytes, + language: language.0.clone(), + } + } + + /** + * The raw bytes of this compiled Plutus script. + * If you need "cborBytes" for cardano-cli use PlutusScript::to_bytes() instead. + */ + pub fn bytes(&self) -> Vec { + self.bytes.clone() + } + + /// Same as `.from_bytes` but will consider the script as requiring the Plutus Language V2 + pub fn from_bytes_v2(bytes: Vec) -> Result { + Self::from_bytes_with_version(bytes, &Language::new_plutus_v2()) + } + + /// Same as `.from_bytes` but will consider the script as requiring the Plutus Language V3 + pub fn from_bytes_v3(bytes: Vec) -> Result { + Self::from_bytes_with_version(bytes, &Language::new_plutus_v3()) + } + + /// Same as `.from_bytes` but will consider the script as requiring the specified language version + pub fn from_bytes_with_version( + bytes: Vec, + language: &Language, + ) -> Result { + Ok(Self::new_with_version( + Self::from_bytes(bytes)?.bytes, + language, + )) + } + + /// Same as .from_hex but will consider the script as requiring the specified language version + pub fn from_hex_with_version( + hex_str: &str, + language: &Language, + ) -> Result { + Ok(Self::new_with_version( + Self::from_hex(hex_str)?.bytes, + language, + )) + } + + pub fn hash(&self) -> ScriptHash { + let mut bytes = Vec::with_capacity(self.bytes.len() + 1); + // https://github.com/input-output-hk/cardano-ledger/blob/master/eras/babbage/test-suite/cddl-files/babbage.cddl#L413 + bytes.extend_from_slice(&vec![self.script_namespace() as u8]); + bytes.extend_from_slice(&self.bytes); + ScriptHash::from(blake2b224(bytes.as_ref())) + } + + pub fn language_version(&self) -> Language { + Language(self.language.clone()) + } + + pub(crate) fn script_namespace(&self) -> ScriptHashNamespace { + match self.language { + LanguageKind::PlutusV1 => ScriptHashNamespace::PlutusScript, + LanguageKind::PlutusV2 => ScriptHashNamespace::PlutusScriptV2, + LanguageKind::PlutusV3 => ScriptHashNamespace::PlutusScriptV3, + } + } + + pub(crate) fn clone_as_version(&self, language: &Language) -> PlutusScript { + Self::new_with_version(self.bytes.clone(), language) + } +} + +impl serde::Serialize for PlutusScript { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&hex::encode(&self.bytes)) + } +} + +impl<'de> serde::de::Deserialize<'de> for PlutusScript { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = ::deserialize(deserializer)?; + hex::decode(&s) + .map(|bytes| PlutusScript::new(bytes)) + .map_err(|_err| { + serde::de::Error::invalid_value( + serde::de::Unexpected::Str(&s), + &"PlutusScript as hex string e.g. F8AB28C2 (without CBOR bytes tag)", + ) + }) + } +} + +impl JsonSchema for PlutusScript { + fn schema_name() -> String { + String::from("PlutusScript") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + String::json_schema(gen) + } + fn is_referenceable() -> bool { + String::is_referenceable() + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/plutus/plutus_scripts.rs b/rust/src/protocol_types/plutus/plutus_scripts.rs new file mode 100644 index 00000000..fa23e2f8 --- /dev/null +++ b/rust/src/protocol_types/plutus/plutus_scripts.rs @@ -0,0 +1,58 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct PlutusScripts(pub(crate) Vec); + +impl_to_from!(PlutusScripts); + +#[wasm_bindgen] +impl PlutusScripts { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> PlutusScript { + self.0[index].clone() + } + + pub fn add(&mut self, elem: &PlutusScript) { + self.0.push(elem.clone()); + } + + pub(crate) fn by_version(&self, language: &Language) -> PlutusScripts { + PlutusScripts( + self.0 + .iter() + .filter(|s| s.language_version().eq(language)) + .map(|s| s.clone()) + .collect(), + ) + } + + pub(crate) fn has_version(&self, language: &Language) -> bool { + self.0.iter().any(|s| s.language_version().eq(language)) + } + + pub(crate) fn merge(&self, other: &PlutusScripts) -> PlutusScripts { + let mut res = self.clone(); + for s in &other.0 { + res.add(s); + } + res + } + + pub(crate) fn map_as_version(&self, language: &Language) -> PlutusScripts { + let mut res = PlutusScripts::new(); + for s in &self.0 { + res.add(&s.clone_as_version(language)); + } + res + } +} diff --git a/rust/src/protocol_types/plutus/redeemer.rs b/rust/src/protocol_types/plutus/redeemer.rs new file mode 100644 index 00000000..a1abe0fb --- /dev/null +++ b/rust/src/protocol_types/plutus/redeemer.rs @@ -0,0 +1,61 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct Redeemer { + pub(crate) tag: RedeemerTag, + pub(crate) index: BigNum, + pub(crate) data: PlutusData, + pub(crate) ex_units: ExUnits, +} + +impl_to_from!(Redeemer); + +#[wasm_bindgen] +impl Redeemer { + pub fn tag(&self) -> RedeemerTag { + self.tag.clone() + } + + pub fn index(&self) -> BigNum { + self.index.clone() + } + + pub fn data(&self) -> PlutusData { + self.data.clone() + } + + pub fn ex_units(&self) -> ExUnits { + self.ex_units.clone() + } + + pub fn new(tag: &RedeemerTag, index: &BigNum, data: &PlutusData, ex_units: &ExUnits) -> Self { + Self { + tag: tag.clone(), + index: index.clone(), + data: data.clone(), + ex_units: ex_units.clone(), + } + } + + #[allow(dead_code)] + pub(crate) fn clone_with_index(&self, index: &BigNum) -> Self { + Self { + tag: self.tag.clone(), + index: index.clone(), + data: self.data.clone(), + ex_units: self.ex_units.clone(), + } + } + + pub(crate) fn clone_with_index_and_tag(&self, index: &BigNum, tag: &RedeemerTag) -> Self { + Self { + tag: tag.clone(), + index: index.clone(), + data: self.data.clone(), + ex_units: self.ex_units.clone(), + } + } +} diff --git a/rust/src/protocol_types/plutus/redeemer_tag.rs b/rust/src/protocol_types/plutus/redeemer_tag.rs new file mode 100644 index 00000000..6c544a92 --- /dev/null +++ b/rust/src/protocol_types/plutus/redeemer_tag.rs @@ -0,0 +1,72 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Copy, + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub enum RedeemerTagKind { + Spend, + Mint, + Cert, + Reward, + Vote, + VotingProposal, +} + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Hash, + Eq, + Ord, + PartialEq, + PartialOrd, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct RedeemerTag(pub(crate) RedeemerTagKind); + +impl_to_from!(RedeemerTag); + +#[wasm_bindgen] +impl RedeemerTag { + pub fn new_spend() -> Self { + Self(RedeemerTagKind::Spend) + } + + pub fn new_mint() -> Self { + Self(RedeemerTagKind::Mint) + } + + pub fn new_cert() -> Self { + Self(RedeemerTagKind::Cert) + } + + pub fn new_reward() -> Self { + Self(RedeemerTagKind::Reward) + } + + pub fn new_vote() -> Self { + Self(RedeemerTagKind::Vote) + } + + pub fn new_voting_proposal() -> Self { + Self(RedeemerTagKind::VotingProposal) + } + + pub fn kind(&self) -> RedeemerTagKind { + self.0 + } +} diff --git a/rust/src/protocol_types/plutus/redeemers.rs b/rust/src/protocol_types/plutus/redeemers.rs new file mode 100644 index 00000000..78b042ed --- /dev/null +++ b/rust/src/protocol_types/plutus/redeemers.rs @@ -0,0 +1,45 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct Redeemers(pub(crate) Vec); + +impl_to_from!(Redeemers); + +#[wasm_bindgen] +impl Redeemers { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> Redeemer { + self.0[index].clone() + } + + pub fn add(&mut self, elem: &Redeemer) { + self.0.push(elem.clone()); + } + + pub fn total_ex_units(&self) -> Result { + let mut tot_mem = BigNum::zero(); + let mut tot_steps = BigNum::zero(); + for i in 0..self.0.len() { + let r: &Redeemer = &self.0[i]; + tot_mem = tot_mem.checked_add(&r.ex_units().mem())?; + tot_steps = tot_steps.checked_add(&r.ex_units().steps())?; + } + Ok(ExUnits::new(&tot_mem, &tot_steps)) + } +} + +impl From> for Redeemers { + fn from(values: Vec) -> Self { + Self(values) + } +} diff --git a/rust/src/protocol_types/plutus/strings.rs b/rust/src/protocol_types/plutus/strings.rs new file mode 100644 index 00000000..843e545b --- /dev/null +++ b/rust/src/protocol_types/plutus/strings.rs @@ -0,0 +1,24 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub struct Strings(pub(crate) Vec); + +#[wasm_bindgen] +impl Strings { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> String { + self.0[index].clone() + } + + pub fn add(&mut self, elem: String) { + self.0.push(elem); + } +} diff --git a/rust/src/serialization/crypto/nonce.rs b/rust/src/serialization/crypto/nonce.rs index b05e5703..22086a49 100644 --- a/rust/src/serialization/crypto/nonce.rs +++ b/rust/src/serialization/crypto/nonce.rs @@ -1,4 +1,4 @@ -use crate::chain_crypto::bech32::Bech32 as _; +use std::convert::TryInto; use crate::protocol_types::{CBORSpecial, Deserialize}; use crate::{DeserializeError, DeserializeFailure, Nonce}; use cbor_event::de::Deserializer; diff --git a/rust/src/serialization/mod.rs b/rust/src/serialization/mod.rs index fd09f944..a64dfe74 100644 --- a/rust/src/serialization/mod.rs +++ b/rust/src/serialization/mod.rs @@ -12,7 +12,6 @@ mod governance; mod utils; mod fixed_tx; use utils::*; -mod plutus; mod metadata; mod transaction_body; mod protocol_param_update; @@ -21,4 +20,5 @@ mod credentials; mod ed25519_key_hashes; mod witnesses; mod credential; -mod crypto; \ No newline at end of file +mod crypto; +mod plutus; \ No newline at end of file diff --git a/rust/src/serialization/plutus.rs b/rust/src/serialization/plutus.rs deleted file mode 100644 index 5a80eed6..00000000 --- a/rust/src/serialization/plutus.rs +++ /dev/null @@ -1,696 +0,0 @@ -use crate::*; -use std::io::SeekFrom; -use hashlink::LinkedHashMap; -use crate::serialization::utils::skip_set_tag; - -impl cbor_event::se::Serialize for PlutusScript { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_bytes(&self.bytes) - } -} - -impl Deserialize for PlutusScript { - fn deserialize(raw: &mut Deserializer) -> Result { - Ok(Self::new(raw.bytes()?)) - } -} - -impl cbor_event::se::Serialize for PlutusScripts { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - //TODO: uncomment this line when we conway ero will come - //serializer.write_tag(258)?; - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for PlutusScripts { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - skip_set_tag(raw)?; - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(PlutusScript::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("PlutusScripts"))?; - Ok(Self(arr)) - } -} - -impl cbor_event::se::Serialize for ConstrPlutusData { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - if let Some(compact_tag) = - Self::alternative_to_compact_cbor_tag(from_bignum(&self.alternative)) - { - // compact form - serializer.write_tag(compact_tag as u64)?; - self.data.serialize(serializer) - } else { - // general form - serializer.write_tag(Self::GENERAL_FORM_TAG)?; - serializer.write_array(cbor_event::Len::Len(2))?; - self.alternative.serialize(serializer)?; - self.data.serialize(serializer) - } - } -} - -impl Deserialize for ConstrPlutusData { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let (alternative, data) = match raw.tag()? { - // general form - Self::GENERAL_FORM_TAG => { - let len = raw.array()?; - let mut read_len = CBORReadLen::new(len); - read_len.read_elems(2)?; - let alternative = BigNum::deserialize(raw)?; - let data = - (|| -> Result<_, DeserializeError> { Ok(PlutusList::deserialize(raw)?) })() - .map_err(|e| e.annotate("datas"))?; - match len { - cbor_event::Len::Len(_) => (), - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => (), - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - (alternative, data) - } - // concise form - tag => { - if let Some(alternative) = Self::compact_cbor_tag_to_alternative(tag) { - (to_bignum(alternative), PlutusList::deserialize(raw)?) - } else { - return Err(DeserializeFailure::TagMismatch { - found: tag, - expected: Self::GENERAL_FORM_TAG, - } - .into()); - } - } - }; - Ok(ConstrPlutusData { alternative, data }) - })() - .map_err(|e| e.annotate("ConstrPlutusData")) - } -} - -impl cbor_event::se::Serialize for CostModel { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for cost in &self.0 { - cost.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for CostModel { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(Int::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("CostModel"))?; - Ok(Self(arr.try_into().unwrap())) - } -} - -impl cbor_event::se::Serialize for Costmdls { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?; - for (key, value) in &self.0 { - key.serialize(serializer)?; - value.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for Costmdls { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut table = std::collections::BTreeMap::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.map()?; - while match len { - cbor_event::Len::Len(n) => table.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - let key = Language::deserialize(raw)?; - let value = CostModel::deserialize(raw)?; - if table.insert(key.clone(), value).is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Str(String::from( - "some complicated/unsupported type", - ))) - .into()); - } - } - Ok(()) - })() - .map_err(|e| e.annotate("Costmdls"))?; - Ok(Self(table)) - } -} - -impl cbor_event::se::Serialize for ExUnitPrices { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - self.mem_price.serialize(serializer)?; - self.step_price.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for ExUnitPrices { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let mut read_len = CBORReadLen::new(len); - read_len.read_elems(2)?; - let mem_price = - (|| -> Result<_, DeserializeError> { Ok(SubCoin::deserialize(raw)?) })() - .map_err(|e| e.annotate("mem_price"))?; - let step_price = - (|| -> Result<_, DeserializeError> { Ok(SubCoin::deserialize(raw)?) })() - .map_err(|e| e.annotate("step_price"))?; - match len { - cbor_event::Len::Len(_) => (), - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => (), - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - Ok(ExUnitPrices { - mem_price, - step_price, - }) - })() - .map_err(|e| e.annotate("ExUnitPrices")) - } -} - -impl cbor_event::se::Serialize for ExUnits { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - self.mem.serialize(serializer)?; - self.steps.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for ExUnits { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let mut read_len = CBORReadLen::new(len); - read_len.read_elems(2)?; - let mem = (|| -> Result<_, DeserializeError> { Ok(BigNum::deserialize(raw)?) })() - .map_err(|e| e.annotate("mem"))?; - let steps = (|| -> Result<_, DeserializeError> { Ok(BigNum::deserialize(raw)?) })() - .map_err(|e| e.annotate("steps"))?; - match len { - cbor_event::Len::Len(_) => (), - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => (), - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - Ok(ExUnits { mem, steps }) - })() - .map_err(|e| e.annotate("ExUnits")) - } -} - -impl cbor_event::se::Serialize for Language { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - // https://github.com/input-output-hk/cardano-ledger/blob/master/eras/babbage/test-suite/cddl-files/babbage.cddl#L324-L327 - serializer.write_unsigned_integer(self.kind() as u64) - } -} - -impl Deserialize for Language { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - match LanguageKind::from_u64(raw.unsigned_integer()?) { - Some(kind) => Ok(Language(kind)), - _ => Err(DeserializeError::new( - "Language", - DeserializeFailure::NoVariantMatched.into(), - )), - } - })() - .map_err(|e| e.annotate("Language")) - } -} - -impl cbor_event::se::Serialize for Languages { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for Languages { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(Language::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("Languages"))?; - Ok(Self(arr)) - } -} - -impl cbor_event::se::Serialize for PlutusMap { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?; - for (key, value) in &self.0 { - key.serialize(serializer)?; - value.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for PlutusMap { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut table = LinkedHashMap::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.map()?; - while match len { - cbor_event::Len::Len(n) => table.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - let key = PlutusData::deserialize(raw)?; - let value = PlutusData::deserialize(raw)?; - if table.insert(key.clone(), value).is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Str(String::from( - "some complicated/unsupported type", - ))) - .into()); - } - } - Ok(()) - })() - .map_err(|e| e.annotate("PlutusMap"))?; - Ok(Self(table)) - } -} - -impl cbor_event::se::Serialize for PlutusDataEnum { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - match self { - PlutusDataEnum::ConstrPlutusData(x) => x.serialize(serializer), - PlutusDataEnum::Map(x) => x.serialize(serializer), - PlutusDataEnum::List(x) => x.serialize(serializer), - PlutusDataEnum::Integer(x) => x.serialize(serializer), - PlutusDataEnum::Bytes(x) => write_bounded_bytes(serializer, &x), - } - } -} - -impl Deserialize for PlutusDataEnum { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let initial_position = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(ConstrPlutusData::deserialize(raw)?) - })(raw) - { - Ok(variant) => return Ok(PlutusDataEnum::ConstrPlutusData(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(PlutusMap::deserialize(raw)?) - })(raw) - { - Ok(variant) => return Ok(PlutusDataEnum::Map(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(PlutusList::deserialize(raw)?) - })(raw) - { - Ok(variant) => return Ok(PlutusDataEnum::List(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(BigInt::deserialize(raw)?) - })(raw) - { - Ok(variant) => return Ok(PlutusDataEnum::Integer(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(read_bounded_bytes(raw)?) - })(raw) - { - Ok(variant) => return Ok(PlutusDataEnum::Bytes(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - Err(DeserializeError::new( - "PlutusDataEnum", - DeserializeFailure::NoVariantMatched.into(), - )) - })() - .map_err(|e| e.annotate("PlutusDataEnum")) - } -} - -impl cbor_event::se::Serialize for PlutusData { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - match &self.original_bytes { - Some(bytes) => serializer.write_raw_bytes(bytes), - None => self.datum.serialize(serializer), - } - } -} - -impl Deserialize for PlutusData { - fn deserialize(raw: &mut Deserializer) -> Result { - // these unwraps are fine since we're seeking the current position - let before = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); - let datum = PlutusDataEnum::deserialize(raw)?; - let after = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); - let bytes_read = (after - before) as usize; - raw.as_mut_ref().seek(SeekFrom::Start(before)).unwrap(); - // these unwraps are fine since we read the above already - let original_bytes = raw.as_mut_ref().fill_buf().unwrap()[..bytes_read].to_vec(); - raw.as_mut_ref().consume(bytes_read); - Ok(Self { - datum, - original_bytes: Some(original_bytes), - }) - } -} - -impl cbor_event::se::Serialize for PlutusList { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - let use_definite_encoding = match self.definite_encoding { - Some(definite) => definite, - None => self.elems.is_empty(), - }; - if use_definite_encoding { - serializer.write_array(cbor_event::Len::Len(self.elems.len() as u64))?; - } else { - serializer.write_array(cbor_event::Len::Indefinite)?; - } - for element in &self.elems { - element.serialize(serializer)?; - } - if !use_definite_encoding { - serializer.write_special(cbor_event::Special::Break)?; - } - Ok(serializer) - } -} - -impl Deserialize for PlutusList { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - let len = (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(PlutusData::deserialize(raw)?); - } - Ok(len) - })() - .map_err(|e| e.annotate("PlutusList"))?; - Ok(Self { - elems: arr, - definite_encoding: Some(len != cbor_event::Len::Indefinite), - }) - } -} - -impl cbor_event::se::Serialize for Redeemer { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(4))?; - self.tag.serialize(serializer)?; - self.index.serialize(serializer)?; - self.data.serialize(serializer)?; - self.ex_units.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for Redeemer { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let mut read_len = CBORReadLen::new(len); - read_len.read_elems(4)?; - let tag = (|| -> Result<_, DeserializeError> { Ok(RedeemerTag::deserialize(raw)?) })() - .map_err(|e| e.annotate("tag"))?; - let index = (|| -> Result<_, DeserializeError> { Ok(BigNum::deserialize(raw)?) })() - .map_err(|e| e.annotate("index"))?; - let data = (|| -> Result<_, DeserializeError> { Ok(PlutusData::deserialize(raw)?) })() - .map_err(|e| e.annotate("data"))?; - let ex_units = (|| -> Result<_, DeserializeError> { Ok(ExUnits::deserialize(raw)?) })() - .map_err(|e| e.annotate("ex_units"))?; - match len { - cbor_event::Len::Len(_) => (), - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => (), - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - Ok(Redeemer { - tag, - index, - data, - ex_units, - }) - })() - .map_err(|e| e.annotate("Redeemer")) - } -} - -impl cbor_event::se::Serialize for RedeemerTagKind { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - match self { - RedeemerTagKind::Spend => serializer.write_unsigned_integer(0u64), - RedeemerTagKind::Mint => serializer.write_unsigned_integer(1u64), - RedeemerTagKind::Cert => serializer.write_unsigned_integer(2u64), - RedeemerTagKind::Reward => serializer.write_unsigned_integer(3u64), - RedeemerTagKind::Vote => serializer.write_unsigned_integer(4u64), - RedeemerTagKind::VotingProposal => serializer.write_unsigned_integer(5u64), - } - } -} - -impl Deserialize for RedeemerTagKind { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - match raw.unsigned_integer() { - Ok(0) => Ok(RedeemerTagKind::Spend), - Ok(1) => Ok(RedeemerTagKind::Mint), - Ok(2) => Ok(RedeemerTagKind::Cert), - Ok(3) => Ok(RedeemerTagKind::Reward), - Ok(4) => Ok(RedeemerTagKind::Vote), - Ok(5) => Ok(RedeemerTagKind::VotingProposal), - Ok(_) | Err(_) => Err(DeserializeFailure::NoVariantMatched.into()), - } - })() - .map_err(|e| e.annotate("RedeemerTagEnum")) - } -} - -impl cbor_event::se::Serialize for RedeemerTag { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - self.0.serialize(serializer) - } -} - -impl Deserialize for RedeemerTag { - fn deserialize(raw: &mut Deserializer) -> Result { - Ok(Self(RedeemerTagKind::deserialize(raw)?)) - } -} - -impl cbor_event::se::Serialize for Redeemers { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for Redeemers { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(Redeemer::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("Redeemers"))?; - Ok(Self(arr)) - } -} - -impl cbor_event::se::Serialize for Strings { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - serializer.write_text(&element)?; - } - Ok(serializer) - } -} - -impl Deserialize for Strings { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(String::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("Strings"))?; - Ok(Self(arr)) - } -} \ No newline at end of file diff --git a/rust/src/serialization/plutus/cost_model.rs b/rust/src/serialization/plutus/cost_model.rs new file mode 100644 index 00000000..a6521ed8 --- /dev/null +++ b/rust/src/serialization/plutus/cost_model.rs @@ -0,0 +1,36 @@ +use crate::*; + +impl cbor_event::se::Serialize for CostModel { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for cost in &self.0 { + cost.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for CostModel { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(Int::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("CostModel"))?; + Ok(Self(arr.try_into().unwrap())) + } +} \ No newline at end of file diff --git a/rust/src/serialization/plutus/cost_models.rs b/rust/src/serialization/plutus/cost_models.rs new file mode 100644 index 00000000..b8d6a7ec --- /dev/null +++ b/rust/src/serialization/plutus/cost_models.rs @@ -0,0 +1,44 @@ +use crate::*; + +impl cbor_event::se::Serialize for Costmdls { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?; + for (key, value) in &self.0 { + key.serialize(serializer)?; + value.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for Costmdls { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut table = std::collections::BTreeMap::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.map()?; + while match len { + cbor_event::Len::Len(n) => table.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + let key = Language::deserialize(raw)?; + let value = CostModel::deserialize(raw)?; + if table.insert(key.clone(), value).is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Str(String::from( + "some complicated/unsupported type", + ))) + .into()); + } + } + Ok(()) + })() + .map_err(|e| e.annotate("Costmdls"))?; + Ok(Self(table)) + } +} \ No newline at end of file diff --git a/rust/src/serialization/plutus/ex_unit_prices.rs b/rust/src/serialization/plutus/ex_unit_prices.rs new file mode 100644 index 00000000..31c5ae1a --- /dev/null +++ b/rust/src/serialization/plutus/ex_unit_prices.rs @@ -0,0 +1,41 @@ +use crate::*; + +impl cbor_event::se::Serialize for ExUnitPrices { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.mem_price.serialize(serializer)?; + self.step_price.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for ExUnitPrices { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(2)?; + let mem_price = + (|| -> Result<_, DeserializeError> { Ok(SubCoin::deserialize(raw)?) })() + .map_err(|e| e.annotate("mem_price"))?; + let step_price = + (|| -> Result<_, DeserializeError> { Ok(SubCoin::deserialize(raw)?) })() + .map_err(|e| e.annotate("step_price"))?; + match len { + cbor_event::Len::Len(_) => (), + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => (), + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + Ok(ExUnitPrices { + mem_price, + step_price, + }) + })() + .map_err(|e| e.annotate("ExUnitPrices")) + } +} \ No newline at end of file diff --git a/rust/src/serialization/plutus/ex_units.rs b/rust/src/serialization/plutus/ex_units.rs new file mode 100644 index 00000000..9f0599fb --- /dev/null +++ b/rust/src/serialization/plutus/ex_units.rs @@ -0,0 +1,36 @@ +use crate::*; + +impl cbor_event::se::Serialize for ExUnits { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.mem.serialize(serializer)?; + self.steps.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for ExUnits { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(2)?; + let mem = (|| -> Result<_, DeserializeError> { Ok(BigNum::deserialize(raw)?) })() + .map_err(|e| e.annotate("mem"))?; + let steps = (|| -> Result<_, DeserializeError> { Ok(BigNum::deserialize(raw)?) })() + .map_err(|e| e.annotate("steps"))?; + match len { + cbor_event::Len::Len(_) => (), + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => (), + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + Ok(ExUnits { mem, steps }) + })() + .map_err(|e| e.annotate("ExUnits")) + } +} \ No newline at end of file diff --git a/rust/src/serialization/plutus/language.rs b/rust/src/serialization/plutus/language.rs new file mode 100644 index 00000000..4686a663 --- /dev/null +++ b/rust/src/serialization/plutus/language.rs @@ -0,0 +1,26 @@ +use crate::*; + +impl cbor_event::se::Serialize for Language { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + // https://github.com/input-output-hk/cardano-ledger/blob/master/eras/babbage/test-suite/cddl-files/babbage.cddl#L324-L327 + serializer.write_unsigned_integer(self.kind() as u64) + } +} + +impl Deserialize for Language { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + match LanguageKind::from_u64(raw.unsigned_integer()?) { + Some(kind) => Ok(Language(kind)), + _ => Err(DeserializeError::new( + "Language", + DeserializeFailure::NoVariantMatched.into(), + )), + } + })() + .map_err(|e| e.annotate("Language")) + } +} \ No newline at end of file diff --git a/rust/src/serialization/plutus/languages.rs b/rust/src/serialization/plutus/languages.rs new file mode 100644 index 00000000..9d473409 --- /dev/null +++ b/rust/src/serialization/plutus/languages.rs @@ -0,0 +1,36 @@ +use crate::*; + +impl cbor_event::se::Serialize for Languages { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for Languages { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(Language::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("Languages"))?; + Ok(Self(arr)) + } +} \ No newline at end of file diff --git a/rust/src/serialization/plutus/mod.rs b/rust/src/serialization/plutus/mod.rs new file mode 100644 index 00000000..68b50d17 --- /dev/null +++ b/rust/src/serialization/plutus/mod.rs @@ -0,0 +1,13 @@ +mod cost_model; +mod cost_models; +mod ex_unit_prices; +mod ex_units; +mod language; +mod languages; +mod plutus_data; +mod plutus_script; +mod plutus_scripts; +mod redeemer; +mod redeemer_tag; +mod redeemers; +mod strings; diff --git a/rust/src/serialization/plutus/plutus_data.rs b/rust/src/serialization/plutus/plutus_data.rs new file mode 100644 index 00000000..aaad5c9a --- /dev/null +++ b/rust/src/serialization/plutus/plutus_data.rs @@ -0,0 +1,266 @@ +use crate::*; +use std::io::SeekFrom; +use hashlink::LinkedHashMap; +use crate::serialization::utils::skip_set_tag; + +impl cbor_event::se::Serialize for ConstrPlutusData { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + if let Some(compact_tag) = + Self::alternative_to_compact_cbor_tag(from_bignum(&self.alternative)) + { + // compact form + serializer.write_tag(compact_tag as u64)?; + self.data.serialize(serializer) + } else { + // general form + serializer.write_tag(Self::GENERAL_FORM_TAG)?; + serializer.write_array(cbor_event::Len::Len(2))?; + self.alternative.serialize(serializer)?; + self.data.serialize(serializer) + } + } +} + +impl Deserialize for ConstrPlutusData { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let (alternative, data) = match raw.tag()? { + // general form + Self::GENERAL_FORM_TAG => { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(2)?; + let alternative = BigNum::deserialize(raw)?; + let data = + (|| -> Result<_, DeserializeError> { Ok(PlutusList::deserialize(raw)?) })() + .map_err(|e| e.annotate("datas"))?; + match len { + cbor_event::Len::Len(_) => (), + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => (), + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + (alternative, data) + } + // concise form + tag => { + if let Some(alternative) = Self::compact_cbor_tag_to_alternative(tag) { + (to_bignum(alternative), PlutusList::deserialize(raw)?) + } else { + return Err(DeserializeFailure::TagMismatch { + found: tag, + expected: Self::GENERAL_FORM_TAG, + } + .into()); + } + } + }; + Ok(ConstrPlutusData { alternative, data }) + })() + .map_err(|e| e.annotate("ConstrPlutusData")) + } +} + +impl cbor_event::se::Serialize for PlutusMap { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?; + for (key, value) in &self.0 { + key.serialize(serializer)?; + value.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for PlutusMap { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut table = LinkedHashMap::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.map()?; + while match len { + cbor_event::Len::Len(n) => table.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + let key = PlutusData::deserialize(raw)?; + let value = PlutusData::deserialize(raw)?; + if table.insert(key.clone(), value).is_some() { + return Err(DeserializeFailure::DuplicateKey(Key::Str(String::from( + "some complicated/unsupported type", + ))) + .into()); + } + } + Ok(()) + })() + .map_err(|e| e.annotate("PlutusMap"))?; + Ok(Self(table)) + } +} + +impl cbor_event::se::Serialize for PlutusDataEnum { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + match self { + PlutusDataEnum::ConstrPlutusData(x) => x.serialize(serializer), + PlutusDataEnum::Map(x) => x.serialize(serializer), + PlutusDataEnum::List(x) => x.serialize(serializer), + PlutusDataEnum::Integer(x) => x.serialize(serializer), + PlutusDataEnum::Bytes(x) => write_bounded_bytes(serializer, &x), + } + } +} + +impl Deserialize for PlutusDataEnum { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let initial_position = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(ConstrPlutusData::deserialize(raw)?) + })(raw) + { + Ok(variant) => return Ok(PlutusDataEnum::ConstrPlutusData(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(PlutusMap::deserialize(raw)?) + })(raw) + { + Ok(variant) => return Ok(PlutusDataEnum::Map(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(PlutusList::deserialize(raw)?) + })(raw) + { + Ok(variant) => return Ok(PlutusDataEnum::List(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(BigInt::deserialize(raw)?) + })(raw) + { + Ok(variant) => return Ok(PlutusDataEnum::Integer(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(read_bounded_bytes(raw)?) + })(raw) + { + Ok(variant) => return Ok(PlutusDataEnum::Bytes(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + Err(DeserializeError::new( + "PlutusDataEnum", + DeserializeFailure::NoVariantMatched.into(), + )) + })() + .map_err(|e| e.annotate("PlutusDataEnum")) + } +} + +impl cbor_event::se::Serialize for PlutusData { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + match &self.original_bytes { + Some(bytes) => serializer.write_raw_bytes(bytes), + None => self.datum.serialize(serializer), + } + } +} + +impl Deserialize for PlutusData { + fn deserialize(raw: &mut Deserializer) -> Result { + // these unwraps are fine since we're seeking the current position + let before = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); + let datum = PlutusDataEnum::deserialize(raw)?; + let after = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); + let bytes_read = (after - before) as usize; + raw.as_mut_ref().seek(SeekFrom::Start(before)).unwrap(); + // these unwraps are fine since we read the above already + let original_bytes = raw.as_mut_ref().fill_buf().unwrap()[..bytes_read].to_vec(); + raw.as_mut_ref().consume(bytes_read); + Ok(Self { + datum, + original_bytes: Some(original_bytes), + }) + } +} + +impl cbor_event::se::Serialize for PlutusList { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + let use_definite_encoding = match self.definite_encoding { + Some(definite) => definite, + None => self.elems.is_empty(), + }; + if use_definite_encoding { + serializer.write_array(cbor_event::Len::Len(self.elems.len() as u64))?; + } else { + serializer.write_array(cbor_event::Len::Indefinite)?; + } + for element in &self.elems { + element.serialize(serializer)?; + } + if !use_definite_encoding { + serializer.write_special(cbor_event::Special::Break)?; + } + Ok(serializer) + } +} + +impl Deserialize for PlutusList { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + let len = (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(PlutusData::deserialize(raw)?); + } + Ok(len) + })() + .map_err(|e| e.annotate("PlutusList"))?; + Ok(Self { + elems: arr, + definite_encoding: Some(len != cbor_event::Len::Indefinite), + }) + } +} \ No newline at end of file diff --git a/rust/src/serialization/plutus/plutus_script.rs b/rust/src/serialization/plutus/plutus_script.rs new file mode 100644 index 00000000..e483209d --- /dev/null +++ b/rust/src/serialization/plutus/plutus_script.rs @@ -0,0 +1,17 @@ +use std::io::Read; +use crate::*; + +impl cbor_event::se::Serialize for PlutusScript { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_bytes(&self.bytes) + } +} + +impl Deserialize for PlutusScript { + fn deserialize(raw: &mut Deserializer) -> Result { + Ok(Self::new(raw.bytes()?)) + } +} \ No newline at end of file diff --git a/rust/src/serialization/plutus/plutus_scripts.rs b/rust/src/serialization/plutus/plutus_scripts.rs new file mode 100644 index 00000000..f73b1049 --- /dev/null +++ b/rust/src/serialization/plutus/plutus_scripts.rs @@ -0,0 +1,40 @@ +use crate::*; +use crate::serialization::utils::skip_set_tag; + +impl cbor_event::se::Serialize for PlutusScripts { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + //TODO: uncomment this line when we conway ero will come + //serializer.write_tag(258)?; + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for PlutusScripts { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + skip_set_tag(raw)?; + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(PlutusScript::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("PlutusScripts"))?; + Ok(Self(arr)) + } +} \ No newline at end of file diff --git a/rust/src/serialization/plutus/redeemer.rs b/rust/src/serialization/plutus/redeemer.rs new file mode 100644 index 00000000..ebcfcbb8 --- /dev/null +++ b/rust/src/serialization/plutus/redeemer.rs @@ -0,0 +1,47 @@ +use crate::*; + +impl cbor_event::se::Serialize for Redeemer { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(4))?; + self.tag.serialize(serializer)?; + self.index.serialize(serializer)?; + self.data.serialize(serializer)?; + self.ex_units.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for Redeemer { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(4)?; + let tag = (|| -> Result<_, DeserializeError> { Ok(RedeemerTag::deserialize(raw)?) })() + .map_err(|e| e.annotate("tag"))?; + let index = (|| -> Result<_, DeserializeError> { Ok(BigNum::deserialize(raw)?) })() + .map_err(|e| e.annotate("index"))?; + let data = (|| -> Result<_, DeserializeError> { Ok(PlutusData::deserialize(raw)?) })() + .map_err(|e| e.annotate("data"))?; + let ex_units = (|| -> Result<_, DeserializeError> { Ok(ExUnits::deserialize(raw)?) })() + .map_err(|e| e.annotate("ex_units"))?; + match len { + cbor_event::Len::Len(_) => (), + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => (), + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + Ok(Redeemer { + tag, + index, + data, + ex_units, + }) + })() + .map_err(|e| e.annotate("Redeemer")) + } +} \ No newline at end of file diff --git a/rust/src/serialization/plutus/redeemer_tag.rs b/rust/src/serialization/plutus/redeemer_tag.rs new file mode 100644 index 00000000..e48e84af --- /dev/null +++ b/rust/src/serialization/plutus/redeemer_tag.rs @@ -0,0 +1,49 @@ +use crate::*; + +impl cbor_event::se::Serialize for RedeemerTagKind { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + match self { + RedeemerTagKind::Spend => serializer.write_unsigned_integer(0u64), + RedeemerTagKind::Mint => serializer.write_unsigned_integer(1u64), + RedeemerTagKind::Cert => serializer.write_unsigned_integer(2u64), + RedeemerTagKind::Reward => serializer.write_unsigned_integer(3u64), + RedeemerTagKind::Vote => serializer.write_unsigned_integer(4u64), + RedeemerTagKind::VotingProposal => serializer.write_unsigned_integer(5u64), + } + } +} + +impl Deserialize for RedeemerTagKind { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + match raw.unsigned_integer() { + Ok(0) => Ok(RedeemerTagKind::Spend), + Ok(1) => Ok(RedeemerTagKind::Mint), + Ok(2) => Ok(RedeemerTagKind::Cert), + Ok(3) => Ok(RedeemerTagKind::Reward), + Ok(4) => Ok(RedeemerTagKind::Vote), + Ok(5) => Ok(RedeemerTagKind::VotingProposal), + Ok(_) | Err(_) => Err(DeserializeFailure::NoVariantMatched.into()), + } + })() + .map_err(|e| e.annotate("RedeemerTagEnum")) + } +} + +impl cbor_event::se::Serialize for RedeemerTag { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + self.0.serialize(serializer) + } +} + +impl Deserialize for RedeemerTag { + fn deserialize(raw: &mut Deserializer) -> Result { + Ok(Self(RedeemerTagKind::deserialize(raw)?)) + } +} \ No newline at end of file diff --git a/rust/src/serialization/plutus/redeemers.rs b/rust/src/serialization/plutus/redeemers.rs new file mode 100644 index 00000000..e9d14f30 --- /dev/null +++ b/rust/src/serialization/plutus/redeemers.rs @@ -0,0 +1,36 @@ +use crate::*; + +impl cbor_event::se::Serialize for Redeemers { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for Redeemers { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(Redeemer::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("Redeemers"))?; + Ok(Self(arr)) + } +} \ No newline at end of file diff --git a/rust/src/serialization/plutus/strings.rs b/rust/src/serialization/plutus/strings.rs new file mode 100644 index 00000000..50dcd443 --- /dev/null +++ b/rust/src/serialization/plutus/strings.rs @@ -0,0 +1,36 @@ +use crate::*; + +impl cbor_event::se::Serialize for Strings { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + serializer.write_text(&element)?; + } + Ok(serializer) + } +} + +impl Deserialize for Strings { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(String::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("Strings"))?; + Ok(Self(arr)) + } +} \ No newline at end of file From 4aaec2ec4912098f504eb80e7b15c1c0d8fcde0d Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 10 Feb 2024 23:36:51 +0800 Subject: [PATCH 220/349] move native scripts into separate module --- rust/src/lib.rs | 356 +------------- rust/src/plutus.rs | 0 rust/src/protocol_types/mod.rs | 8 +- rust/src/protocol_types/native_script.rs | 306 ++++++++++++ rust/src/protocol_types/native_scripts.rs | 56 +++ rust/src/serialization/general.rs | 551 ---------------------- rust/src/serialization/mod.rs | 4 +- rust/src/serialization/native_script.rs | 519 ++++++++++++++++++++ rust/src/serialization/native_scripts.rs | 36 ++ 9 files changed, 928 insertions(+), 908 deletions(-) delete mode 100644 rust/src/plutus.rs create mode 100644 rust/src/protocol_types/native_script.rs create mode 100644 rust/src/protocol_types/native_scripts.rs create mode 100644 rust/src/serialization/native_script.rs create mode 100644 rust/src/serialization/native_scripts.rs diff --git a/rust/src/lib.rs b/rust/src/lib.rs index f1e7e2ed..9688fda1 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -925,209 +925,6 @@ impl JsonSchema for Withdrawals { } } -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct ScriptPubkey { - addr_keyhash: Ed25519KeyHash, -} - -impl_to_from!(ScriptPubkey); - -#[wasm_bindgen] -impl ScriptPubkey { - pub fn addr_keyhash(&self) -> Ed25519KeyHash { - self.addr_keyhash.clone() - } - - pub fn new(addr_keyhash: &Ed25519KeyHash) -> Self { - Self { - addr_keyhash: addr_keyhash.clone(), - } - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct ScriptAll { - native_scripts: NativeScripts, -} - -impl_to_from!(ScriptAll); - -#[wasm_bindgen] -impl ScriptAll { - pub fn native_scripts(&self) -> NativeScripts { - self.native_scripts.clone() - } - - pub fn new(native_scripts: &NativeScripts) -> Self { - Self { - native_scripts: native_scripts.clone(), - } - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct ScriptAny { - native_scripts: NativeScripts, -} - -impl_to_from!(ScriptAny); - -#[wasm_bindgen] -impl ScriptAny { - pub fn native_scripts(&self) -> NativeScripts { - self.native_scripts.clone() - } - - pub fn new(native_scripts: &NativeScripts) -> Self { - Self { - native_scripts: native_scripts.clone(), - } - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct ScriptNOfK { - n: u32, - native_scripts: NativeScripts, -} - -impl_to_from!(ScriptNOfK); - -#[wasm_bindgen] -impl ScriptNOfK { - pub fn n(&self) -> u32 { - self.n - } - - pub fn native_scripts(&self) -> NativeScripts { - self.native_scripts.clone() - } - - pub fn new(n: u32, native_scripts: &NativeScripts) -> Self { - Self { - n: n, - native_scripts: native_scripts.clone(), - } - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct TimelockStart { - slot: SlotBigNum, -} - -impl_to_from!(TimelockStart); - -#[wasm_bindgen] -impl TimelockStart { - /// !!! DEPRECATED !!! - /// Returns a Slot32 (u32) value in case the underlying original BigNum (u64) value is within the limits. - /// Otherwise will just raise an error. - /// Use `.slot_bignum` instead - #[deprecated( - since = "10.1.0", - note = "Possible boundary error. Use slot_bignum instead" - )] - pub fn slot(&self) -> Result { - self.slot.try_into() - } - - pub fn slot_bignum(&self) -> SlotBigNum { - self.slot - } - - /// !!! DEPRECATED !!! - /// This constructor uses outdated slot number format. - /// Use `.new_timelockstart` instead. - #[deprecated( - since = "10.1.0", - note = "Underlying value capacity (BigNum u64) bigger then Slot32. Use new_bignum instead." - )] - pub fn new(slot: Slot32) -> Self { - Self { slot: slot.into() } - } - - pub fn new_timelockstart(slot: &SlotBigNum) -> Self { - Self { slot: slot.clone() } - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct TimelockExpiry { - slot: SlotBigNum, -} - -impl_to_from!(TimelockExpiry); - -#[wasm_bindgen] -impl TimelockExpiry { - pub fn slot(&self) -> Result { - self.slot.try_into() - } - - pub fn slot_bignum(&self) -> SlotBigNum { - self.slot - } - - /// !!! DEPRECATED !!! - /// This constructor uses outdated slot number format. - /// Use `.new_timelockexpiry` instead - #[deprecated( - since = "10.1.0", - note = "Underlying value capacity (BigNum u64) bigger then Slot32. Use new_bignum instead." - )] - pub fn new(slot: Slot32) -> Self { - Self { - slot: (slot.into()), - } - } - - pub fn new_timelockexpiry(slot: &SlotBigNum) -> Self { - Self { slot: slot.clone() } - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub enum NativeScriptKind { - ScriptPubkey, - ScriptAll, - ScriptAny, - ScriptNOfK, - TimelockStart, - TimelockExpiry, -} - -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub enum NativeScriptEnum { - ScriptPubkey(ScriptPubkey), - ScriptAll(ScriptAll), - ScriptAny(ScriptAny), - ScriptNOfK(ScriptNOfK), - TimelockStart(TimelockStart), - TimelockExpiry(TimelockExpiry), -} - #[derive( Debug, Clone, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, )] @@ -1220,14 +1017,6 @@ impl OutputDatum { } } -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct NativeScript(NativeScriptEnum); - -impl_to_from!(NativeScript); - /// Each new language uses a different namespace for hashing its script /// This is because you could have a language where the same bytes have different semantics /// So this avoids scripts in different languages mapping to the same hash @@ -1241,140 +1030,6 @@ pub enum ScriptHashNamespace { PlutusScriptV3 = 3, } -#[wasm_bindgen] -impl NativeScript { - pub fn hash(&self) -> ScriptHash { - let mut bytes = Vec::with_capacity(self.to_bytes().len() + 1); - bytes.extend_from_slice(&vec![ScriptHashNamespace::NativeScript as u8]); - bytes.extend_from_slice(&self.to_bytes()); - ScriptHash::from(blake2b224(bytes.as_ref())) - } - - pub fn new_script_pubkey(script_pubkey: &ScriptPubkey) -> Self { - Self(NativeScriptEnum::ScriptPubkey(script_pubkey.clone())) - } - - pub fn new_script_all(script_all: &ScriptAll) -> Self { - Self(NativeScriptEnum::ScriptAll(script_all.clone())) - } - - pub fn new_script_any(script_any: &ScriptAny) -> Self { - Self(NativeScriptEnum::ScriptAny(script_any.clone())) - } - - pub fn new_script_n_of_k(script_n_of_k: &ScriptNOfK) -> Self { - Self(NativeScriptEnum::ScriptNOfK(script_n_of_k.clone())) - } - - pub fn new_timelock_start(timelock_start: &TimelockStart) -> Self { - Self(NativeScriptEnum::TimelockStart(timelock_start.clone())) - } - - pub fn new_timelock_expiry(timelock_expiry: &TimelockExpiry) -> Self { - Self(NativeScriptEnum::TimelockExpiry(timelock_expiry.clone())) - } - - pub fn kind(&self) -> NativeScriptKind { - match &self.0 { - NativeScriptEnum::ScriptPubkey(_) => NativeScriptKind::ScriptPubkey, - NativeScriptEnum::ScriptAll(_) => NativeScriptKind::ScriptAll, - NativeScriptEnum::ScriptAny(_) => NativeScriptKind::ScriptAny, - NativeScriptEnum::ScriptNOfK(_) => NativeScriptKind::ScriptNOfK, - NativeScriptEnum::TimelockStart(_) => NativeScriptKind::TimelockStart, - NativeScriptEnum::TimelockExpiry(_) => NativeScriptKind::TimelockExpiry, - } - } - - pub fn as_script_pubkey(&self) -> Option { - match &self.0 { - NativeScriptEnum::ScriptPubkey(x) => Some(x.clone()), - _ => None, - } - } - - pub fn as_script_all(&self) -> Option { - match &self.0 { - NativeScriptEnum::ScriptAll(x) => Some(x.clone()), - _ => None, - } - } - - pub fn as_script_any(&self) -> Option { - match &self.0 { - NativeScriptEnum::ScriptAny(x) => Some(x.clone()), - _ => None, - } - } - - pub fn as_script_n_of_k(&self) -> Option { - match &self.0 { - NativeScriptEnum::ScriptNOfK(x) => Some(x.clone()), - _ => None, - } - } - - pub fn as_timelock_start(&self) -> Option { - match &self.0 { - NativeScriptEnum::TimelockStart(x) => Some(x.clone()), - _ => None, - } - } - - pub fn as_timelock_expiry(&self) -> Option { - match &self.0 { - NativeScriptEnum::TimelockExpiry(x) => Some(x.clone()), - _ => None, - } - } - - /// Returns a set of Ed25519KeyHashes - /// contained within this script recursively on any depth level. - /// The order of the keys in the result is not determined in any way. - pub fn get_required_signers(&self) -> Ed25519KeyHashes { - Ed25519KeyHashes::from(self) - } -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct NativeScripts(Vec); - -#[wasm_bindgen] -impl NativeScripts { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> NativeScript { - self.0[index].clone() - } - - pub fn add(&mut self, elem: &NativeScript) { - self.0.push(elem.clone()); - } -} - -impl From> for NativeScripts { - fn from(scripts: Vec) -> Self { - scripts.iter().fold(NativeScripts::new(), |mut scripts, s| { - scripts.add(s); - scripts - }) - } -} - -impl NoneOrEmpty for NativeScripts { - fn is_none_or_empty(&self) -> bool { - self.0.is_empty() - } -} - #[wasm_bindgen] #[derive( Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, @@ -2496,13 +2151,4 @@ impl From<&NativeScript> for Ed25519KeyHashes { _ => Ed25519KeyHashes::new(), } } -} - -impl From<&NativeScripts> for Ed25519KeyHashes { - fn from(scripts: &NativeScripts) -> Self { - scripts.0.iter().fold(Ed25519KeyHashes::new(), |mut set, s| { - set.extend_move(Ed25519KeyHashes::from(s)); - set - }) - } -} +} \ No newline at end of file diff --git a/rust/src/plutus.rs b/rust/src/plutus.rs deleted file mode 100644 index e69de29b..00000000 diff --git a/rust/src/protocol_types/mod.rs b/rust/src/protocol_types/mod.rs index 29950c69..02b26ef9 100644 --- a/rust/src/protocol_types/mod.rs +++ b/rust/src/protocol_types/mod.rs @@ -38,4 +38,10 @@ mod witnesses; pub use witnesses::*; mod crypto; -pub use crypto::*; \ No newline at end of file +pub use crypto::*; + +mod native_script; +pub use native_script::*; + +mod native_scripts; +pub use native_scripts::*; diff --git a/rust/src/protocol_types/native_script.rs b/rust/src/protocol_types/native_script.rs new file mode 100644 index 00000000..4f1f7d64 --- /dev/null +++ b/rust/src/protocol_types/native_script.rs @@ -0,0 +1,306 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub enum NativeScriptKind { + ScriptPubkey, + ScriptAll, + ScriptAny, + ScriptNOfK, + TimelockStart, + TimelockExpiry, +} + +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub enum NativeScriptEnum { + ScriptPubkey(ScriptPubkey), + ScriptAll(ScriptAll), + ScriptAny(ScriptAny), + ScriptNOfK(ScriptNOfK), + TimelockStart(TimelockStart), + TimelockExpiry(TimelockExpiry), +} + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct NativeScript(pub(crate) NativeScriptEnum); + +impl_to_from!(NativeScript); + +#[wasm_bindgen] +impl NativeScript { + pub fn hash(&self) -> ScriptHash { + let mut bytes = Vec::with_capacity(self.to_bytes().len() + 1); + bytes.extend_from_slice(&vec![ScriptHashNamespace::NativeScript as u8]); + bytes.extend_from_slice(&self.to_bytes()); + ScriptHash::from(blake2b224(bytes.as_ref())) + } + + pub fn new_script_pubkey(script_pubkey: &ScriptPubkey) -> Self { + Self(NativeScriptEnum::ScriptPubkey(script_pubkey.clone())) + } + + pub fn new_script_all(script_all: &ScriptAll) -> Self { + Self(NativeScriptEnum::ScriptAll(script_all.clone())) + } + + pub fn new_script_any(script_any: &ScriptAny) -> Self { + Self(NativeScriptEnum::ScriptAny(script_any.clone())) + } + + pub fn new_script_n_of_k(script_n_of_k: &ScriptNOfK) -> Self { + Self(NativeScriptEnum::ScriptNOfK(script_n_of_k.clone())) + } + + pub fn new_timelock_start(timelock_start: &TimelockStart) -> Self { + Self(NativeScriptEnum::TimelockStart(timelock_start.clone())) + } + + pub fn new_timelock_expiry(timelock_expiry: &TimelockExpiry) -> Self { + Self(NativeScriptEnum::TimelockExpiry(timelock_expiry.clone())) + } + + pub fn kind(&self) -> NativeScriptKind { + match &self.0 { + NativeScriptEnum::ScriptPubkey(_) => NativeScriptKind::ScriptPubkey, + NativeScriptEnum::ScriptAll(_) => NativeScriptKind::ScriptAll, + NativeScriptEnum::ScriptAny(_) => NativeScriptKind::ScriptAny, + NativeScriptEnum::ScriptNOfK(_) => NativeScriptKind::ScriptNOfK, + NativeScriptEnum::TimelockStart(_) => NativeScriptKind::TimelockStart, + NativeScriptEnum::TimelockExpiry(_) => NativeScriptKind::TimelockExpiry, + } + } + + pub fn as_script_pubkey(&self) -> Option { + match &self.0 { + NativeScriptEnum::ScriptPubkey(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_script_all(&self) -> Option { + match &self.0 { + NativeScriptEnum::ScriptAll(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_script_any(&self) -> Option { + match &self.0 { + NativeScriptEnum::ScriptAny(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_script_n_of_k(&self) -> Option { + match &self.0 { + NativeScriptEnum::ScriptNOfK(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_timelock_start(&self) -> Option { + match &self.0 { + NativeScriptEnum::TimelockStart(x) => Some(x.clone()), + _ => None, + } + } + + pub fn as_timelock_expiry(&self) -> Option { + match &self.0 { + NativeScriptEnum::TimelockExpiry(x) => Some(x.clone()), + _ => None, + } + } + + /// Returns a set of Ed25519KeyHashes + /// contained within this script recursively on any depth level. + /// The order of the keys in the result is not determined in any way. + pub fn get_required_signers(&self) -> Ed25519KeyHashes { + Ed25519KeyHashes::from(self) + } +} + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct ScriptPubkey { + pub(crate) addr_keyhash: Ed25519KeyHash, +} + +impl_to_from!(ScriptPubkey); + +#[wasm_bindgen] +impl ScriptPubkey { + pub fn addr_keyhash(&self) -> Ed25519KeyHash { + self.addr_keyhash.clone() + } + + pub fn new(addr_keyhash: &Ed25519KeyHash) -> Self { + Self { + addr_keyhash: addr_keyhash.clone(), + } + } +} + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct ScriptAll { + pub(crate) native_scripts: NativeScripts, +} + +impl_to_from!(ScriptAll); + +#[wasm_bindgen] +impl ScriptAll { + pub fn native_scripts(&self) -> NativeScripts { + self.native_scripts.clone() + } + + pub fn new(native_scripts: &NativeScripts) -> Self { + Self { + native_scripts: native_scripts.clone(), + } + } +} + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct ScriptAny { + pub(crate) native_scripts: NativeScripts, +} + +impl_to_from!(ScriptAny); + +#[wasm_bindgen] +impl ScriptAny { + pub fn native_scripts(&self) -> NativeScripts { + self.native_scripts.clone() + } + + pub fn new(native_scripts: &NativeScripts) -> Self { + Self { + native_scripts: native_scripts.clone(), + } + } +} + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct ScriptNOfK { + pub(crate) n: u32, + pub(crate) native_scripts: NativeScripts, +} + +impl_to_from!(ScriptNOfK); + +#[wasm_bindgen] +impl ScriptNOfK { + pub fn n(&self) -> u32 { + self.n + } + + pub fn native_scripts(&self) -> NativeScripts { + self.native_scripts.clone() + } + + pub fn new(n: u32, native_scripts: &NativeScripts) -> Self { + Self { + n: n, + native_scripts: native_scripts.clone(), + } + } +} + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct TimelockStart { + pub(crate) slot: SlotBigNum, +} + +impl_to_from!(TimelockStart); + +#[wasm_bindgen] +impl TimelockStart { + /// !!! DEPRECATED !!! + /// Returns a Slot32 (u32) value in case the underlying original BigNum (u64) value is within the limits. + /// Otherwise will just raise an error. + /// Use `.slot_bignum` instead + #[deprecated( + since = "10.1.0", + note = "Possible boundary error. Use slot_bignum instead" + )] + pub fn slot(&self) -> Result { + self.slot.try_into() + } + + pub fn slot_bignum(&self) -> SlotBigNum { + self.slot + } + + /// !!! DEPRECATED !!! + /// This constructor uses outdated slot number format. + /// Use `.new_timelockstart` instead. + #[deprecated( + since = "10.1.0", + note = "Underlying value capacity (BigNum u64) bigger then Slot32. Use new_bignum instead." + )] + pub fn new(slot: Slot32) -> Self { + Self { slot: slot.into() } + } + + pub fn new_timelockstart(slot: &SlotBigNum) -> Self { + Self { slot: slot.clone() } + } +} + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct TimelockExpiry { + pub(crate) slot: SlotBigNum, +} + +impl_to_from!(TimelockExpiry); + +#[wasm_bindgen] +impl TimelockExpiry { + pub fn slot(&self) -> Result { + self.slot.try_into() + } + + pub fn slot_bignum(&self) -> SlotBigNum { + self.slot + } + + /// !!! DEPRECATED !!! + /// This constructor uses outdated slot number format. + /// Use `.new_timelockexpiry` instead + #[deprecated( + since = "10.1.0", + note = "Underlying value capacity (BigNum u64) bigger then Slot32. Use new_bignum instead." + )] + pub fn new(slot: Slot32) -> Self { + Self { + slot: (slot.into()), + } + } + + pub fn new_timelockexpiry(slot: &SlotBigNum) -> Self { + Self { slot: slot.clone() } + } +} diff --git a/rust/src/protocol_types/native_scripts.rs b/rust/src/protocol_types/native_scripts.rs new file mode 100644 index 00000000..36075776 --- /dev/null +++ b/rust/src/protocol_types/native_scripts.rs @@ -0,0 +1,56 @@ +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct NativeScripts(pub(crate) Vec); + +#[wasm_bindgen] +impl NativeScripts { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> NativeScript { + self.0[index].clone() + } + + pub fn add(&mut self, elem: &NativeScript) { + self.0.push(elem.clone()); + } +} + +impl From> for NativeScripts { + fn from(scripts: Vec) -> Self { + scripts.iter().fold( + NativeScripts::new(), + |mut scripts, s| { + scripts.add(s); + scripts + }, + ) + } +} + +impl NoneOrEmpty for NativeScripts { + fn is_none_or_empty(&self) -> bool { + self.0.is_empty() + } +} + +impl From<&NativeScripts> for Ed25519KeyHashes { + fn from(scripts: &NativeScripts) -> Self { + scripts + .0 + .iter() + .fold(Ed25519KeyHashes::new(), |mut set, s| { + set.extend_move(Ed25519KeyHashes::from(s)); + set + }) + } +} diff --git a/rust/src/serialization/general.rs b/rust/src/serialization/general.rs index 6419226a..853dd34d 100644 --- a/rust/src/serialization/general.rs +++ b/rust/src/serialization/general.rs @@ -1168,557 +1168,6 @@ impl Deserialize for Withdrawals { } } -impl cbor_event::se::Serialize for ScriptPubkey { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - self.serialize_as_embedded_group(serializer) - } -} - -impl SerializeEmbeddedGroup for ScriptPubkey { - fn serialize_as_embedded_group<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(0u64)?; - self.addr_keyhash.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for ScriptPubkey { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let mut read_len = CBORReadLen::new(len); - read_len.read_elems(2)?; - let ret = Self::deserialize_as_embedded_group(raw, /*mut read_len, */ len); - match len { - cbor_event::Len::Len(_) => read_len.finish()?, - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => (), - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("ScriptPubkey")) - } -} - -impl DeserializeEmbeddedGroup for ScriptPubkey { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - /*read_len: &mut CBORReadLen, */ _: cbor_event::Len, - ) -> Result { - (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 0 { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(0), - } - .into()); - } - Ok(()) - })() - .map_err(|e| e.annotate("index_0"))?; - let addr_keyhash = - (|| -> Result<_, DeserializeError> { Ok(Ed25519KeyHash::deserialize(raw)?) })() - .map_err(|e| e.annotate("addr_keyhash"))?; - Ok(ScriptPubkey { addr_keyhash }) - } -} - -impl cbor_event::se::Serialize for ScriptAll { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - self.serialize_as_embedded_group(serializer) - } -} - -impl SerializeEmbeddedGroup for ScriptAll { - fn serialize_as_embedded_group<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(1u64)?; - self.native_scripts.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for ScriptAll { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let mut read_len = CBORReadLen::new(len); - read_len.read_elems(2)?; - let ret = Self::deserialize_as_embedded_group(raw, /*mut read_len, */ len); - match len { - cbor_event::Len::Len(_) => read_len.finish()?, - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => (), - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("ScriptAll")) - } -} - -impl DeserializeEmbeddedGroup for ScriptAll { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - /*read_len: &mut CBORReadLen, */ _: cbor_event::Len, - ) -> Result { - (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 1 { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(1), - } - .into()); - } - Ok(()) - })() - .map_err(|e| e.annotate("index_0"))?; - let native_scripts = - (|| -> Result<_, DeserializeError> { Ok(NativeScripts::deserialize(raw)?) })() - .map_err(|e| e.annotate("native_scripts"))?; - Ok(ScriptAll { native_scripts }) - } -} - -impl cbor_event::se::Serialize for ScriptAny { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - self.serialize_as_embedded_group(serializer) - } -} - -impl SerializeEmbeddedGroup for ScriptAny { - fn serialize_as_embedded_group<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(2u64)?; - self.native_scripts.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for ScriptAny { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let mut read_len = CBORReadLen::new(len); - read_len.read_elems(2)?; - let ret = Self::deserialize_as_embedded_group(raw, /*mut read_len, */ len); - match len { - cbor_event::Len::Len(_) => read_len.finish()?, - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => (), - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("ScriptAny")) - } -} - -impl DeserializeEmbeddedGroup for ScriptAny { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - /*/*read_len: &mut CBORReadLen, */*/ _: cbor_event::Len, - ) -> Result { - (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 2 { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(2), - } - .into()); - } - Ok(()) - })() - .map_err(|e| e.annotate("index_0"))?; - let native_scripts = - (|| -> Result<_, DeserializeError> { Ok(NativeScripts::deserialize(raw)?) })() - .map_err(|e| e.annotate("native_scripts"))?; - Ok(ScriptAny { native_scripts }) - } -} - -impl cbor_event::se::Serialize for ScriptNOfK { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(3))?; - self.serialize_as_embedded_group(serializer) - } -} - -impl SerializeEmbeddedGroup for ScriptNOfK { - fn serialize_as_embedded_group<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(3u64)?; - self.n.serialize(serializer)?; - self.native_scripts.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for ScriptNOfK { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let mut read_len = CBORReadLen::new(len); - read_len.read_elems(3)?; - let ret = Self::deserialize_as_embedded_group(raw, /*mut read_len, */ len); - match len { - cbor_event::Len::Len(_) => read_len.finish()?, - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => (), - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("ScriptNOfK")) - } -} - -impl DeserializeEmbeddedGroup for ScriptNOfK { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - /*read_len: &mut CBORReadLen, */ _: cbor_event::Len, - ) -> Result { - (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 3 { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(3), - } - .into()); - } - Ok(()) - })() - .map_err(|e| e.annotate("index_0"))?; - let n = (|| -> Result<_, DeserializeError> { Ok(u32::deserialize(raw)?) })() - .map_err(|e| e.annotate("n"))?; - let native_scripts = - (|| -> Result<_, DeserializeError> { Ok(NativeScripts::deserialize(raw)?) })() - .map_err(|e| e.annotate("native_scripts"))?; - Ok(ScriptNOfK { n, native_scripts }) - } -} - -impl cbor_event::se::Serialize for TimelockStart { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - self.serialize_as_embedded_group(serializer) - } -} - -impl SerializeEmbeddedGroup for TimelockStart { - fn serialize_as_embedded_group<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(4u64)?; - self.slot.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for TimelockStart { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let mut read_len = CBORReadLen::new(len); - read_len.read_elems(2)?; - let ret = Self::deserialize_as_embedded_group(raw, /*mut read_len, */ len); - match len { - cbor_event::Len::Len(_) => read_len.finish()?, - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => (), - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("TimelockStart")) - } -} - -impl DeserializeEmbeddedGroup for TimelockStart { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - /*read_len: &mut CBORReadLen, */ _: cbor_event::Len, - ) -> Result { - (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 4 { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(4), - } - .into()); - } - Ok(()) - })() - .map_err(|e| e.annotate("index_0"))?; - let slot = (|| -> Result<_, DeserializeError> { Ok(SlotBigNum::deserialize(raw)?) })() - .map_err(|e| e.annotate("slot"))?; - Ok(TimelockStart { slot }) - } -} - -impl cbor_event::se::Serialize for TimelockExpiry { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - self.serialize_as_embedded_group(serializer) - } -} - -impl SerializeEmbeddedGroup for TimelockExpiry { - fn serialize_as_embedded_group<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(5u64)?; - self.slot.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for TimelockExpiry { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let mut read_len = CBORReadLen::new(len); - read_len.read_elems(2)?; - let ret = Self::deserialize_as_embedded_group(raw, /*&mut read_len, */ len); - match len { - cbor_event::Len::Len(_) => read_len.finish()?, - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => (), - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("TimelockExpiry")) - } -} - -impl DeserializeEmbeddedGroup for TimelockExpiry { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - /*read_len: &mut CBORReadLen, */ _: cbor_event::Len, - ) -> Result { - (|| -> Result<_, DeserializeError> { - let index_0_value = raw.unsigned_integer()?; - if index_0_value != 5 { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(index_0_value), - expected: Key::Uint(5), - } - .into()); - } - Ok(()) - })() - .map_err(|e| e.annotate("index_0"))?; - let slot = (|| -> Result<_, DeserializeError> { Ok(SlotBigNum::deserialize(raw)?) })() - .map_err(|e| e.annotate("slot"))?; - Ok(TimelockExpiry { slot }) - } -} - -impl cbor_event::se::Serialize for NativeScriptEnum { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - match self { - NativeScriptEnum::ScriptPubkey(x) => x.serialize(serializer), - NativeScriptEnum::ScriptAll(x) => x.serialize(serializer), - NativeScriptEnum::ScriptAny(x) => x.serialize(serializer), - NativeScriptEnum::ScriptNOfK(x) => x.serialize(serializer), - NativeScriptEnum::TimelockStart(x) => x.serialize(serializer), - NativeScriptEnum::TimelockExpiry(x) => x.serialize(serializer), - } - } -} - -impl Deserialize for NativeScriptEnum { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - //let mut read_len = CBORReadLen::new(len); - let initial_position = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(ScriptPubkey::deserialize_as_embedded_group( - raw, /*&mut read_len, */ len, - )?) - })(raw) - { - Ok(variant) => return Ok(NativeScriptEnum::ScriptPubkey(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(ScriptAll::deserialize_as_embedded_group( - raw, /*mut read_len, */ len, - )?) - })(raw) - { - Ok(variant) => return Ok(NativeScriptEnum::ScriptAll(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(ScriptAny::deserialize_as_embedded_group( - raw, /*mut read_len, */ len, - )?) - })(raw) - { - Ok(variant) => return Ok(NativeScriptEnum::ScriptAny(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(ScriptNOfK::deserialize_as_embedded_group( - raw, /*mut read_len, */ len, - )?) - })(raw) - { - Ok(variant) => return Ok(NativeScriptEnum::ScriptNOfK(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(TimelockStart::deserialize_as_embedded_group( - raw, /*mut read_len, */ len, - )?) - })(raw) - { - Ok(variant) => return Ok(NativeScriptEnum::TimelockStart(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { - Ok(TimelockExpiry::deserialize_as_embedded_group( - raw, /*mut read_len, */ len, - )?) - })(raw) - { - Ok(variant) => return Ok(NativeScriptEnum::TimelockExpiry(variant)), - Err(_) => raw - .as_mut_ref() - .seek(SeekFrom::Start(initial_position)) - .unwrap(), - }; - match len { - cbor_event::Len::Len(_) => (), /*read_len.finish()?*/ - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => (), /*read_len.finish()?*/ - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - Err(DeserializeError::new( - "NativeScriptEnum", - DeserializeFailure::NoVariantMatched.into(), - )) - })() - .map_err(|e| e.annotate("NativeScriptEnum")) - } -} - -impl cbor_event::se::Serialize for NativeScript { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - self.0.serialize(serializer) - } -} - -impl Deserialize for NativeScript { - fn deserialize(raw: &mut Deserializer) -> Result { - Ok(Self(NativeScriptEnum::deserialize(raw)?)) - } -} - -impl cbor_event::se::Serialize for NativeScripts { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for NativeScripts { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); - break; - } - arr.push(NativeScript::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("NativeScripts"))?; - Ok(Self(arr)) - } -} - impl cbor_event::se::Serialize for Update { fn serialize<'se, W: Write>( &self, diff --git a/rust/src/serialization/mod.rs b/rust/src/serialization/mod.rs index a64dfe74..a2b1d642 100644 --- a/rust/src/serialization/mod.rs +++ b/rust/src/serialization/mod.rs @@ -21,4 +21,6 @@ mod ed25519_key_hashes; mod witnesses; mod credential; mod crypto; -mod plutus; \ No newline at end of file +mod plutus; +mod native_script; +mod native_scripts; \ No newline at end of file diff --git a/rust/src/serialization/native_script.rs b/rust/src/serialization/native_script.rs new file mode 100644 index 00000000..9b5722da --- /dev/null +++ b/rust/src/serialization/native_script.rs @@ -0,0 +1,519 @@ +use std::io::SeekFrom; +use crate::*; + +impl cbor_event::se::Serialize for NativeScript { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + self.0.serialize(serializer) + } +} + +impl Deserialize for NativeScript { + fn deserialize(raw: &mut Deserializer) -> Result { + Ok(Self(NativeScriptEnum::deserialize(raw)?)) + } +} + +impl cbor_event::se::Serialize for NativeScriptEnum { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + match self { + NativeScriptEnum::ScriptPubkey(x) => x.serialize(serializer), + NativeScriptEnum::ScriptAll(x) => x.serialize(serializer), + NativeScriptEnum::ScriptAny(x) => x.serialize(serializer), + NativeScriptEnum::ScriptNOfK(x) => x.serialize(serializer), + NativeScriptEnum::TimelockStart(x) => x.serialize(serializer), + NativeScriptEnum::TimelockExpiry(x) => x.serialize(serializer), + } + } +} + +impl Deserialize for NativeScriptEnum { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + //let mut read_len = CBORReadLen::new(len); + let initial_position = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(ScriptPubkey::deserialize_as_embedded_group( + raw, /*&mut read_len, */ len, + )?) + })(raw) + { + Ok(variant) => return Ok(NativeScriptEnum::ScriptPubkey(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(ScriptAll::deserialize_as_embedded_group( + raw, /*mut read_len, */ len, + )?) + })(raw) + { + Ok(variant) => return Ok(NativeScriptEnum::ScriptAll(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(ScriptAny::deserialize_as_embedded_group( + raw, /*mut read_len, */ len, + )?) + })(raw) + { + Ok(variant) => return Ok(NativeScriptEnum::ScriptAny(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(ScriptNOfK::deserialize_as_embedded_group( + raw, /*mut read_len, */ len, + )?) + })(raw) + { + Ok(variant) => return Ok(NativeScriptEnum::ScriptNOfK(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(TimelockStart::deserialize_as_embedded_group( + raw, /*mut read_len, */ len, + )?) + })(raw) + { + Ok(variant) => return Ok(NativeScriptEnum::TimelockStart(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> { + Ok(TimelockExpiry::deserialize_as_embedded_group( + raw, /*mut read_len, */ len, + )?) + })(raw) + { + Ok(variant) => return Ok(NativeScriptEnum::TimelockExpiry(variant)), + Err(_) => raw + .as_mut_ref() + .seek(SeekFrom::Start(initial_position)) + .unwrap(), + }; + match len { + cbor_event::Len::Len(_) => (), /*read_len.finish()?*/ + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => (), /*read_len.finish()?*/ + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + Err(DeserializeError::new( + "NativeScriptEnum", + DeserializeFailure::NoVariantMatched.into(), + )) + })() + .map_err(|e| e.annotate("NativeScriptEnum")) + } +} + + +impl cbor_event::se::Serialize for ScriptPubkey { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.serialize_as_embedded_group(serializer) + } +} + +impl SerializeEmbeddedGroup for ScriptPubkey { + fn serialize_as_embedded_group<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_unsigned_integer(0u64)?; + self.addr_keyhash.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for ScriptPubkey { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(2)?; + let ret = Self::deserialize_as_embedded_group(raw, /*mut read_len, */ len); + match len { + cbor_event::Len::Len(_) => read_len.finish()?, + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => (), + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("ScriptPubkey")) + } +} + +impl DeserializeEmbeddedGroup for ScriptPubkey { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + /*read_len: &mut CBORReadLen, */ _: cbor_event::Len, + ) -> Result { + (|| -> Result<_, DeserializeError> { + let index_0_value = raw.unsigned_integer()?; + if index_0_value != 0 { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(index_0_value), + expected: Key::Uint(0), + } + .into()); + } + Ok(()) + })() + .map_err(|e| e.annotate("index_0"))?; + let addr_keyhash = + (|| -> Result<_, DeserializeError> { Ok(Ed25519KeyHash::deserialize(raw)?) })() + .map_err(|e| e.annotate("addr_keyhash"))?; + Ok(ScriptPubkey { addr_keyhash }) + } +} + +impl cbor_event::se::Serialize for ScriptAll { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.serialize_as_embedded_group(serializer) + } +} + +impl SerializeEmbeddedGroup for ScriptAll { + fn serialize_as_embedded_group<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_unsigned_integer(1u64)?; + self.native_scripts.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for ScriptAll { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(2)?; + let ret = Self::deserialize_as_embedded_group(raw, /*mut read_len, */ len); + match len { + cbor_event::Len::Len(_) => read_len.finish()?, + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => (), + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("ScriptAll")) + } +} + +impl DeserializeEmbeddedGroup for ScriptAll { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + /*read_len: &mut CBORReadLen, */ _: cbor_event::Len, + ) -> Result { + (|| -> Result<_, DeserializeError> { + let index_0_value = raw.unsigned_integer()?; + if index_0_value != 1 { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(index_0_value), + expected: Key::Uint(1), + } + .into()); + } + Ok(()) + })() + .map_err(|e| e.annotate("index_0"))?; + let native_scripts = + (|| -> Result<_, DeserializeError> { Ok(NativeScripts::deserialize(raw)?) })() + .map_err(|e| e.annotate("native_scripts"))?; + Ok(ScriptAll { native_scripts }) + } +} + +impl cbor_event::se::Serialize for ScriptAny { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.serialize_as_embedded_group(serializer) + } +} + +impl SerializeEmbeddedGroup for ScriptAny { + fn serialize_as_embedded_group<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_unsigned_integer(2u64)?; + self.native_scripts.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for ScriptAny { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(2)?; + let ret = Self::deserialize_as_embedded_group(raw, /*mut read_len, */ len); + match len { + cbor_event::Len::Len(_) => read_len.finish()?, + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => (), + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("ScriptAny")) + } +} + +impl DeserializeEmbeddedGroup for ScriptAny { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + /*/*read_len: &mut CBORReadLen, */*/ _: cbor_event::Len, + ) -> Result { + (|| -> Result<_, DeserializeError> { + let index_0_value = raw.unsigned_integer()?; + if index_0_value != 2 { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(index_0_value), + expected: Key::Uint(2), + } + .into()); + } + Ok(()) + })() + .map_err(|e| e.annotate("index_0"))?; + let native_scripts = + (|| -> Result<_, DeserializeError> { Ok(NativeScripts::deserialize(raw)?) })() + .map_err(|e| e.annotate("native_scripts"))?; + Ok(ScriptAny { native_scripts }) + } +} + +impl cbor_event::se::Serialize for ScriptNOfK { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(3))?; + self.serialize_as_embedded_group(serializer) + } +} + +impl SerializeEmbeddedGroup for ScriptNOfK { + fn serialize_as_embedded_group<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_unsigned_integer(3u64)?; + self.n.serialize(serializer)?; + self.native_scripts.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for ScriptNOfK { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(3)?; + let ret = Self::deserialize_as_embedded_group(raw, /*mut read_len, */ len); + match len { + cbor_event::Len::Len(_) => read_len.finish()?, + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => (), + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("ScriptNOfK")) + } +} + +impl DeserializeEmbeddedGroup for ScriptNOfK { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + /*read_len: &mut CBORReadLen, */ _: cbor_event::Len, + ) -> Result { + (|| -> Result<_, DeserializeError> { + let index_0_value = raw.unsigned_integer()?; + if index_0_value != 3 { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(index_0_value), + expected: Key::Uint(3), + } + .into()); + } + Ok(()) + })() + .map_err(|e| e.annotate("index_0"))?; + let n = (|| -> Result<_, DeserializeError> { Ok(u32::deserialize(raw)?) })() + .map_err(|e| e.annotate("n"))?; + let native_scripts = + (|| -> Result<_, DeserializeError> { Ok(NativeScripts::deserialize(raw)?) })() + .map_err(|e| e.annotate("native_scripts"))?; + Ok(ScriptNOfK { n, native_scripts }) + } +} + +impl cbor_event::se::Serialize for TimelockStart { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.serialize_as_embedded_group(serializer) + } +} + +impl SerializeEmbeddedGroup for TimelockStart { + fn serialize_as_embedded_group<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_unsigned_integer(4u64)?; + self.slot.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for TimelockStart { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(2)?; + let ret = Self::deserialize_as_embedded_group(raw, /*mut read_len, */ len); + match len { + cbor_event::Len::Len(_) => read_len.finish()?, + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => (), + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("TimelockStart")) + } +} + +impl DeserializeEmbeddedGroup for TimelockStart { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + /*read_len: &mut CBORReadLen, */ _: cbor_event::Len, + ) -> Result { + (|| -> Result<_, DeserializeError> { + let index_0_value = raw.unsigned_integer()?; + if index_0_value != 4 { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(index_0_value), + expected: Key::Uint(4), + } + .into()); + } + Ok(()) + })() + .map_err(|e| e.annotate("index_0"))?; + let slot = (|| -> Result<_, DeserializeError> { Ok(SlotBigNum::deserialize(raw)?) })() + .map_err(|e| e.annotate("slot"))?; + Ok(TimelockStart { slot }) + } +} + +impl cbor_event::se::Serialize for TimelockExpiry { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.serialize_as_embedded_group(serializer) + } +} + +impl SerializeEmbeddedGroup for TimelockExpiry { + fn serialize_as_embedded_group<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_unsigned_integer(5u64)?; + self.slot.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for TimelockExpiry { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(2)?; + let ret = Self::deserialize_as_embedded_group(raw, /*&mut read_len, */ len); + match len { + cbor_event::Len::Len(_) => read_len.finish()?, + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => (), + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("TimelockExpiry")) + } +} + +impl DeserializeEmbeddedGroup for TimelockExpiry { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + /*read_len: &mut CBORReadLen, */ _: cbor_event::Len, + ) -> Result { + (|| -> Result<_, DeserializeError> { + let index_0_value = raw.unsigned_integer()?; + if index_0_value != 5 { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(index_0_value), + expected: Key::Uint(5), + } + .into()); + } + Ok(()) + })() + .map_err(|e| e.annotate("index_0"))?; + let slot = (|| -> Result<_, DeserializeError> { Ok(SlotBigNum::deserialize(raw)?) })() + .map_err(|e| e.annotate("slot"))?; + Ok(TimelockExpiry { slot }) + } +} \ No newline at end of file diff --git a/rust/src/serialization/native_scripts.rs b/rust/src/serialization/native_scripts.rs new file mode 100644 index 00000000..a6aa8bdb --- /dev/null +++ b/rust/src/serialization/native_scripts.rs @@ -0,0 +1,36 @@ +use crate::*; + +impl cbor_event::se::Serialize for NativeScripts { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for NativeScripts { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(NativeScript::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("NativeScripts"))?; + Ok(Self(arr)) + } +} \ No newline at end of file From 78f65a223f774213c1e9988b20b3c312450c8fc0 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 10 Feb 2024 23:38:59 +0800 Subject: [PATCH 221/349] revert build.sh --- build-and-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-and-test.sh b/build-and-test.sh index 10ddba6b..6120323a 100644 --- a/build-and-test.sh +++ b/build-and-test.sh @@ -1 +1 @@ -. ./test.sh && npm run rust:build-nodejs +. test.sh && npm run rust:build-nodejs From 66f4429c1bf712e8702f0f76fb821ccf6cff8410 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 11 Feb 2024 00:11:34 +0800 Subject: [PATCH 222/349] add dedup to native scripts --- rust/src/builders/mint_builder.rs | 6 +- rust/src/builders/tx_builder.rs | 16 ++-- rust/src/protocol_types/native_scripts.rs | 90 +++++++++++++++---- rust/src/serialization/native_scripts.rs | 12 +-- .../witnesses/transaction_witnesses_set.rs | 16 ++-- rust/src/tests/builders/tx_builder.rs | 8 +- rust/src/tests/general.rs | 30 +++---- 7 files changed, 117 insertions(+), 61 deletions(-) diff --git a/rust/src/builders/mint_builder.rs b/rust/src/builders/mint_builder.rs index b737f54b..00ea6f8c 100644 --- a/rust/src/builders/mint_builder.rs +++ b/rust/src/builders/mint_builder.rs @@ -166,16 +166,16 @@ impl MintBuilder { } pub fn get_native_scripts(&self) -> NativeScripts { - let mut native_scripts = Vec::new(); + let mut native_scripts = NativeScripts::new(); for script_mint in self.mints.values() { match script_mint { ScriptMint::Native(native_mints) => { - native_scripts.push(native_mints.script.clone()); + native_scripts.add_move(native_mints.script.clone()); } _ => {} } } - NativeScripts(native_scripts) + native_scripts } pub fn get_plutus_witnesses(&self) -> PlutusWitnesses { diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index 630322f7..b4bcd206 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -132,7 +132,7 @@ fn assert_required_mint_scripts( } let mint_scripts = maybe_mint_scripts.unwrap(); let witness_hashes: HashSet = - mint_scripts.0.iter().map(|script| script.hash()).collect(); + mint_scripts.to_vec().iter().map(|script| script.hash()).collect(); for mint_hash in mint.keys().0.iter() { if !witness_hashes.contains(mint_hash) { return Err(JsError::from_str(&format!( @@ -1029,7 +1029,7 @@ impl TransactionBuilder { pub fn set_mint(&mut self, mint: &Mint, mint_scripts: &NativeScripts) -> Result<(), JsError> { assert_required_mint_scripts(mint, Some(mint_scripts))?; let mut scripts_policies = HashMap::new(); - for scipt in &mint_scripts.0 { + for scipt in mint_scripts.to_vec() { scripts_policies.insert(scipt.hash(), scipt.clone()); } @@ -1925,24 +1925,24 @@ impl TransactionBuilder { fn get_combined_native_scripts(&self) -> Option { let mut ns = NativeScripts::new(); if let Some(input_scripts) = self.inputs.get_native_input_scripts() { - input_scripts.0.iter().for_each(|s| { + input_scripts.to_vec().iter().for_each(|s| { ns.add(s); }); } if let Some(input_scripts) = self.collateral.get_native_input_scripts() { - input_scripts.0.iter().for_each(|s| { + input_scripts.to_vec().iter().for_each(|s| { ns.add(s); }); } if let Some(mint_builder) = &self.mint { - mint_builder.get_native_scripts().0.iter().for_each(|s| { + mint_builder.get_native_scripts().to_vec().iter().for_each(|s| { ns.add(s); }); } if let Some(certificates_builder) = &self.certs { certificates_builder .get_native_scripts() - .0 + .to_vec() .iter() .for_each(|s| { ns.add(s); @@ -1951,14 +1951,14 @@ impl TransactionBuilder { if let Some(withdrawals_builder) = &self.withdrawals { withdrawals_builder .get_native_scripts() - .0 + .to_vec() .iter() .for_each(|s| { ns.add(s); }); } if let Some(voting_builder) = &self.voting_procedures { - voting_builder.get_native_scripts().0.iter().for_each(|s| { + voting_builder.get_native_scripts().to_vec().iter().for_each(|s| { ns.add(s); }); } diff --git a/rust/src/protocol_types/native_scripts.rs b/rust/src/protocol_types/native_scripts.rs index 36075776..1dd4c0b5 100644 --- a/rust/src/protocol_types/native_scripts.rs +++ b/rust/src/protocol_types/native_scripts.rs @@ -1,52 +1,77 @@ use crate::*; #[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct NativeScripts(pub(crate) Vec); +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub struct NativeScripts { + scripts: Vec, + dedup: BTreeSet, +} #[wasm_bindgen] impl NativeScripts { pub fn new() -> Self { - Self(Vec::new()) + Self { + scripts: Vec::new(), + dedup: BTreeSet::new(), + } } pub fn len(&self) -> usize { - self.0.len() + self.scripts.len() } pub fn get(&self, index: usize) -> NativeScript { - self.0[index].clone() + self.scripts[index].clone() } pub fn add(&mut self, elem: &NativeScript) { - self.0.push(elem.clone()); + if self.dedup.insert(elem.clone()) { + self.scripts.push(elem.clone()); + } + } + + pub(crate) fn add_move(&mut self, elem: NativeScript) { + if self.dedup.insert(elem.clone()) { + self.scripts.push(elem); + } + } + + pub(crate) fn to_vec(&self) -> &Vec { + &self.scripts + } + + pub(crate) fn from_vec(other: Vec) -> Self { + let mut dedup = BTreeSet::new(); + let mut scripts = Vec::new(); + for script in other { + if dedup.insert(script.clone()) { + scripts.push(script); + } + } + + Self { scripts, dedup } } } impl From> for NativeScripts { fn from(scripts: Vec) -> Self { - scripts.iter().fold( - NativeScripts::new(), - |mut scripts, s| { - scripts.add(s); - scripts - }, - ) + scripts.iter().fold(NativeScripts::new(), |mut scripts, s| { + scripts.add(s); + scripts + }) } } impl NoneOrEmpty for NativeScripts { fn is_none_or_empty(&self) -> bool { - self.0.is_empty() + self.scripts.is_empty() } } impl From<&NativeScripts> for Ed25519KeyHashes { fn from(scripts: &NativeScripts) -> Self { scripts - .0 + .scripts .iter() .fold(Ed25519KeyHashes::new(), |mut set, s| { set.extend_move(Ed25519KeyHashes::from(s)); @@ -54,3 +79,34 @@ impl From<&NativeScripts> for Ed25519KeyHashes { }) } } + +impl serde::Serialize for NativeScripts { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + self.scripts.serialize(serializer) + } +} + +impl<'de> serde::de::Deserialize<'de> for NativeScripts { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let vec = as serde::de::Deserialize>::deserialize(deserializer)?; + Ok(Self::from_vec(vec)) + } +} + +impl JsonSchema for NativeScripts { + fn schema_name() -> String { + String::from("NativeScripts") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + Vec::::json_schema(gen) + } + fn is_referenceable() -> bool { + Vec::::is_referenceable() + } +} diff --git a/rust/src/serialization/native_scripts.rs b/rust/src/serialization/native_scripts.rs index a6aa8bdb..fd4e6f67 100644 --- a/rust/src/serialization/native_scripts.rs +++ b/rust/src/serialization/native_scripts.rs @@ -5,8 +5,8 @@ impl cbor_event::se::Serialize for NativeScripts { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { + serializer.write_array(cbor_event::Len::Len(self.len() as u64))?; + for element in self.to_vec() { element.serialize(serializer)?; } Ok(serializer) @@ -15,22 +15,22 @@ impl cbor_event::se::Serialize for NativeScripts { impl Deserialize for NativeScripts { fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); + let mut scripts = NativeScripts::new(); (|| -> Result<_, DeserializeError> { let len = raw.array()?; while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Len(n) => scripts.len() < n as usize, cbor_event::Len::Indefinite => true, } { if raw.cbor_type()? == CBORType::Special { assert_eq!(raw.special()?, CBORSpecial::Break); break; } - arr.push(NativeScript::deserialize(raw)?); + scripts.add_move(NativeScript::deserialize(raw)?); } Ok(()) })() .map_err(|e| e.annotate("NativeScripts"))?; - Ok(Self(arr)) + Ok(scripts) } } \ No newline at end of file diff --git a/rust/src/serialization/witnesses/transaction_witnesses_set.rs b/rust/src/serialization/witnesses/transaction_witnesses_set.rs index ebff78c2..466b4013 100644 --- a/rust/src/serialization/witnesses/transaction_witnesses_set.rs +++ b/rust/src/serialization/witnesses/transaction_witnesses_set.rs @@ -31,20 +31,22 @@ impl cbor_event::se::Serialize for TransactionWitnessSet { + plutus_added_length, ))?; if let Some(field) = &self.vkeys { - if field.0.len() > 0 { + if field.len() > 0 { serializer.write_unsigned_integer(0)?; field.serialize(serializer)?; } } if let Some(field) = &self.native_scripts { - if field.0.len() > 0 { + if field.len() > 0 { serializer.write_unsigned_integer(1)?; field.serialize(serializer)?; } } if let Some(field) = &self.bootstraps { - serializer.write_unsigned_integer(2)?; - field.serialize(serializer)?; + if field.len() > 0 { + serializer.write_unsigned_integer(2)?; + field.serialize(serializer)?; + } } if let Some(plutus_scripts) = &self.plutus_scripts { if has_plutus_v1 { @@ -67,8 +69,10 @@ impl cbor_event::se::Serialize for TransactionWitnessSet { } } if let Some(field) = &self.plutus_data { - serializer.write_unsigned_integer(4)?; - field.serialize(serializer)?; + if field.len() > 0 { + serializer.write_unsigned_integer(4)?; + field.serialize(serializer)?; + } } if let Some(field) = &self.redeemers { serializer.write_unsigned_integer(5)?; diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index 46a5de47..f56eb439 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -3172,7 +3172,7 @@ fn set_mint_asset_with_existing_mint() { // Only second script is present in the scripts assert_eq!(mint_scripts.len(), 2); let actual_scripts = mint_scripts - .0 + .to_vec() .iter() .cloned() .collect::>(); @@ -3231,7 +3231,7 @@ fn add_mint_asset_with_existing_mint() { assert_eq!(mint_scripts.len(), 2); let actual_scripts = mint_scripts - .0 + .to_vec() .iter() .cloned() .collect::>(); @@ -3402,7 +3402,7 @@ fn add_mint_asset_and_output() { assert_eq!(mint_scripts.len(), 2); let actual_scripts = mint_scripts - .0 + .to_vec() .iter() .cloned() .collect::>(); @@ -3471,7 +3471,7 @@ fn add_mint_asset_and_min_required_coin() { assert_eq!(mint_scripts.len(), 2); let actual_scripts = mint_scripts - .0 + .to_vec() .iter() .cloned() .collect::>(); diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index e0a5b0ce..a575be75 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -199,10 +199,6 @@ fn pkscript(pk: &Ed25519KeyHash) -> NativeScript { NativeScript::new_script_pubkey(&ScriptPubkey::new(pk)) } -fn scripts_vec(scripts: Vec<&NativeScript>) -> NativeScripts { - NativeScripts(scripts.iter().map(|s| (*s).clone()).collect()) -} - #[test] fn native_scripts_get_pubkeys() { let keyhash1 = keyhash(1); @@ -218,29 +214,29 @@ fn native_scripts_get_pubkeys() { assert_eq!(pks2.len(), 0); let pks3 = Ed25519KeyHashes::from(&NativeScript::new_script_all(&ScriptAll::new( - &scripts_vec(vec![&pkscript(&keyhash1), &pkscript(&keyhash2)]), + &NativeScripts::from_vec(vec![pkscript(&keyhash1), pkscript(&keyhash2)]), ))); assert_eq!(pks3.len(), 2); assert!(pks3.contains(&keyhash1)); assert!(pks3.contains(&keyhash2)); let pks4 = Ed25519KeyHashes::from(&NativeScript::new_script_any(&ScriptAny::new( - &scripts_vec(vec![ - &NativeScript::new_script_n_of_k(&ScriptNOfK::new( + &NativeScripts::from_vec(vec![ + NativeScript::new_script_n_of_k(&ScriptNOfK::new( 1, - &scripts_vec(vec![ - &NativeScript::new_timelock_start(&TimelockStart::new(132)), - &pkscript(&keyhash3), + &NativeScripts::from_vec(vec![ + NativeScript::new_timelock_start(&TimelockStart::new(132)), + pkscript(&keyhash3), ]), )), - &NativeScript::new_script_all(&ScriptAll::new(&scripts_vec(vec![ - &NativeScript::new_timelock_expiry(&TimelockExpiry::new(132)), - &pkscript(&keyhash1), + NativeScript::new_script_all(&ScriptAll::new(&NativeScripts::from_vec(vec![ + NativeScript::new_timelock_expiry(&TimelockExpiry::new(132)), + pkscript(&keyhash1), ]))), - &NativeScript::new_script_any(&ScriptAny::new(&scripts_vec(vec![ - &pkscript(&keyhash1), - &pkscript(&keyhash2), - &pkscript(&keyhash3), + NativeScript::new_script_any(&ScriptAny::new(&NativeScripts::from_vec(vec![ + pkscript(&keyhash1), + pkscript(&keyhash2), + pkscript(&keyhash3), ]))), ]), ))); From a882a7ed00ede4ae38ddd3fb4123a32ea8282c40 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 11 Feb 2024 00:19:17 +0800 Subject: [PATCH 223/349] Revert "add dedup to native scripts" This reverts commit 66f4429c1bf712e8702f0f76fb821ccf6cff8410. --- rust/src/builders/mint_builder.rs | 6 +- rust/src/builders/tx_builder.rs | 16 ++-- rust/src/protocol_types/native_scripts.rs | 90 ++++--------------- rust/src/serialization/native_scripts.rs | 12 +-- .../witnesses/transaction_witnesses_set.rs | 16 ++-- rust/src/tests/builders/tx_builder.rs | 8 +- rust/src/tests/general.rs | 30 ++++--- 7 files changed, 61 insertions(+), 117 deletions(-) diff --git a/rust/src/builders/mint_builder.rs b/rust/src/builders/mint_builder.rs index 00ea6f8c..b737f54b 100644 --- a/rust/src/builders/mint_builder.rs +++ b/rust/src/builders/mint_builder.rs @@ -166,16 +166,16 @@ impl MintBuilder { } pub fn get_native_scripts(&self) -> NativeScripts { - let mut native_scripts = NativeScripts::new(); + let mut native_scripts = Vec::new(); for script_mint in self.mints.values() { match script_mint { ScriptMint::Native(native_mints) => { - native_scripts.add_move(native_mints.script.clone()); + native_scripts.push(native_mints.script.clone()); } _ => {} } } - native_scripts + NativeScripts(native_scripts) } pub fn get_plutus_witnesses(&self) -> PlutusWitnesses { diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index b4bcd206..630322f7 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -132,7 +132,7 @@ fn assert_required_mint_scripts( } let mint_scripts = maybe_mint_scripts.unwrap(); let witness_hashes: HashSet = - mint_scripts.to_vec().iter().map(|script| script.hash()).collect(); + mint_scripts.0.iter().map(|script| script.hash()).collect(); for mint_hash in mint.keys().0.iter() { if !witness_hashes.contains(mint_hash) { return Err(JsError::from_str(&format!( @@ -1029,7 +1029,7 @@ impl TransactionBuilder { pub fn set_mint(&mut self, mint: &Mint, mint_scripts: &NativeScripts) -> Result<(), JsError> { assert_required_mint_scripts(mint, Some(mint_scripts))?; let mut scripts_policies = HashMap::new(); - for scipt in mint_scripts.to_vec() { + for scipt in &mint_scripts.0 { scripts_policies.insert(scipt.hash(), scipt.clone()); } @@ -1925,24 +1925,24 @@ impl TransactionBuilder { fn get_combined_native_scripts(&self) -> Option { let mut ns = NativeScripts::new(); if let Some(input_scripts) = self.inputs.get_native_input_scripts() { - input_scripts.to_vec().iter().for_each(|s| { + input_scripts.0.iter().for_each(|s| { ns.add(s); }); } if let Some(input_scripts) = self.collateral.get_native_input_scripts() { - input_scripts.to_vec().iter().for_each(|s| { + input_scripts.0.iter().for_each(|s| { ns.add(s); }); } if let Some(mint_builder) = &self.mint { - mint_builder.get_native_scripts().to_vec().iter().for_each(|s| { + mint_builder.get_native_scripts().0.iter().for_each(|s| { ns.add(s); }); } if let Some(certificates_builder) = &self.certs { certificates_builder .get_native_scripts() - .to_vec() + .0 .iter() .for_each(|s| { ns.add(s); @@ -1951,14 +1951,14 @@ impl TransactionBuilder { if let Some(withdrawals_builder) = &self.withdrawals { withdrawals_builder .get_native_scripts() - .to_vec() + .0 .iter() .for_each(|s| { ns.add(s); }); } if let Some(voting_builder) = &self.voting_procedures { - voting_builder.get_native_scripts().to_vec().iter().for_each(|s| { + voting_builder.get_native_scripts().0.iter().for_each(|s| { ns.add(s); }); } diff --git a/rust/src/protocol_types/native_scripts.rs b/rust/src/protocol_types/native_scripts.rs index 1dd4c0b5..36075776 100644 --- a/rust/src/protocol_types/native_scripts.rs +++ b/rust/src/protocol_types/native_scripts.rs @@ -1,77 +1,52 @@ use crate::*; #[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub struct NativeScripts { - scripts: Vec, - dedup: BTreeSet, -} +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct NativeScripts(pub(crate) Vec); #[wasm_bindgen] impl NativeScripts { pub fn new() -> Self { - Self { - scripts: Vec::new(), - dedup: BTreeSet::new(), - } + Self(Vec::new()) } pub fn len(&self) -> usize { - self.scripts.len() + self.0.len() } pub fn get(&self, index: usize) -> NativeScript { - self.scripts[index].clone() + self.0[index].clone() } pub fn add(&mut self, elem: &NativeScript) { - if self.dedup.insert(elem.clone()) { - self.scripts.push(elem.clone()); - } - } - - pub(crate) fn add_move(&mut self, elem: NativeScript) { - if self.dedup.insert(elem.clone()) { - self.scripts.push(elem); - } - } - - pub(crate) fn to_vec(&self) -> &Vec { - &self.scripts - } - - pub(crate) fn from_vec(other: Vec) -> Self { - let mut dedup = BTreeSet::new(); - let mut scripts = Vec::new(); - for script in other { - if dedup.insert(script.clone()) { - scripts.push(script); - } - } - - Self { scripts, dedup } + self.0.push(elem.clone()); } } impl From> for NativeScripts { fn from(scripts: Vec) -> Self { - scripts.iter().fold(NativeScripts::new(), |mut scripts, s| { - scripts.add(s); - scripts - }) + scripts.iter().fold( + NativeScripts::new(), + |mut scripts, s| { + scripts.add(s); + scripts + }, + ) } } impl NoneOrEmpty for NativeScripts { fn is_none_or_empty(&self) -> bool { - self.scripts.is_empty() + self.0.is_empty() } } impl From<&NativeScripts> for Ed25519KeyHashes { fn from(scripts: &NativeScripts) -> Self { scripts - .scripts + .0 .iter() .fold(Ed25519KeyHashes::new(), |mut set, s| { set.extend_move(Ed25519KeyHashes::from(s)); @@ -79,34 +54,3 @@ impl From<&NativeScripts> for Ed25519KeyHashes { }) } } - -impl serde::Serialize for NativeScripts { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - self.scripts.serialize(serializer) - } -} - -impl<'de> serde::de::Deserialize<'de> for NativeScripts { - fn deserialize(deserializer: D) -> Result - where - D: serde::de::Deserializer<'de>, - { - let vec = as serde::de::Deserialize>::deserialize(deserializer)?; - Ok(Self::from_vec(vec)) - } -} - -impl JsonSchema for NativeScripts { - fn schema_name() -> String { - String::from("NativeScripts") - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - Vec::::json_schema(gen) - } - fn is_referenceable() -> bool { - Vec::::is_referenceable() - } -} diff --git a/rust/src/serialization/native_scripts.rs b/rust/src/serialization/native_scripts.rs index fd4e6f67..a6aa8bdb 100644 --- a/rust/src/serialization/native_scripts.rs +++ b/rust/src/serialization/native_scripts.rs @@ -5,8 +5,8 @@ impl cbor_event::se::Serialize for NativeScripts { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.len() as u64))?; - for element in self.to_vec() { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { element.serialize(serializer)?; } Ok(serializer) @@ -15,22 +15,22 @@ impl cbor_event::se::Serialize for NativeScripts { impl Deserialize for NativeScripts { fn deserialize(raw: &mut Deserializer) -> Result { - let mut scripts = NativeScripts::new(); + let mut arr = Vec::new(); (|| -> Result<_, DeserializeError> { let len = raw.array()?; while match len { - cbor_event::Len::Len(n) => scripts.len() < n as usize, + cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { if raw.cbor_type()? == CBORType::Special { assert_eq!(raw.special()?, CBORSpecial::Break); break; } - scripts.add_move(NativeScript::deserialize(raw)?); + arr.push(NativeScript::deserialize(raw)?); } Ok(()) })() .map_err(|e| e.annotate("NativeScripts"))?; - Ok(scripts) + Ok(Self(arr)) } } \ No newline at end of file diff --git a/rust/src/serialization/witnesses/transaction_witnesses_set.rs b/rust/src/serialization/witnesses/transaction_witnesses_set.rs index 466b4013..ebff78c2 100644 --- a/rust/src/serialization/witnesses/transaction_witnesses_set.rs +++ b/rust/src/serialization/witnesses/transaction_witnesses_set.rs @@ -31,22 +31,20 @@ impl cbor_event::se::Serialize for TransactionWitnessSet { + plutus_added_length, ))?; if let Some(field) = &self.vkeys { - if field.len() > 0 { + if field.0.len() > 0 { serializer.write_unsigned_integer(0)?; field.serialize(serializer)?; } } if let Some(field) = &self.native_scripts { - if field.len() > 0 { + if field.0.len() > 0 { serializer.write_unsigned_integer(1)?; field.serialize(serializer)?; } } if let Some(field) = &self.bootstraps { - if field.len() > 0 { - serializer.write_unsigned_integer(2)?; - field.serialize(serializer)?; - } + serializer.write_unsigned_integer(2)?; + field.serialize(serializer)?; } if let Some(plutus_scripts) = &self.plutus_scripts { if has_plutus_v1 { @@ -69,10 +67,8 @@ impl cbor_event::se::Serialize for TransactionWitnessSet { } } if let Some(field) = &self.plutus_data { - if field.len() > 0 { - serializer.write_unsigned_integer(4)?; - field.serialize(serializer)?; - } + serializer.write_unsigned_integer(4)?; + field.serialize(serializer)?; } if let Some(field) = &self.redeemers { serializer.write_unsigned_integer(5)?; diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index f56eb439..46a5de47 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -3172,7 +3172,7 @@ fn set_mint_asset_with_existing_mint() { // Only second script is present in the scripts assert_eq!(mint_scripts.len(), 2); let actual_scripts = mint_scripts - .to_vec() + .0 .iter() .cloned() .collect::>(); @@ -3231,7 +3231,7 @@ fn add_mint_asset_with_existing_mint() { assert_eq!(mint_scripts.len(), 2); let actual_scripts = mint_scripts - .to_vec() + .0 .iter() .cloned() .collect::>(); @@ -3402,7 +3402,7 @@ fn add_mint_asset_and_output() { assert_eq!(mint_scripts.len(), 2); let actual_scripts = mint_scripts - .to_vec() + .0 .iter() .cloned() .collect::>(); @@ -3471,7 +3471,7 @@ fn add_mint_asset_and_min_required_coin() { assert_eq!(mint_scripts.len(), 2); let actual_scripts = mint_scripts - .to_vec() + .0 .iter() .cloned() .collect::>(); diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index a575be75..e0a5b0ce 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -199,6 +199,10 @@ fn pkscript(pk: &Ed25519KeyHash) -> NativeScript { NativeScript::new_script_pubkey(&ScriptPubkey::new(pk)) } +fn scripts_vec(scripts: Vec<&NativeScript>) -> NativeScripts { + NativeScripts(scripts.iter().map(|s| (*s).clone()).collect()) +} + #[test] fn native_scripts_get_pubkeys() { let keyhash1 = keyhash(1); @@ -214,29 +218,29 @@ fn native_scripts_get_pubkeys() { assert_eq!(pks2.len(), 0); let pks3 = Ed25519KeyHashes::from(&NativeScript::new_script_all(&ScriptAll::new( - &NativeScripts::from_vec(vec![pkscript(&keyhash1), pkscript(&keyhash2)]), + &scripts_vec(vec![&pkscript(&keyhash1), &pkscript(&keyhash2)]), ))); assert_eq!(pks3.len(), 2); assert!(pks3.contains(&keyhash1)); assert!(pks3.contains(&keyhash2)); let pks4 = Ed25519KeyHashes::from(&NativeScript::new_script_any(&ScriptAny::new( - &NativeScripts::from_vec(vec![ - NativeScript::new_script_n_of_k(&ScriptNOfK::new( + &scripts_vec(vec![ + &NativeScript::new_script_n_of_k(&ScriptNOfK::new( 1, - &NativeScripts::from_vec(vec![ - NativeScript::new_timelock_start(&TimelockStart::new(132)), - pkscript(&keyhash3), + &scripts_vec(vec![ + &NativeScript::new_timelock_start(&TimelockStart::new(132)), + &pkscript(&keyhash3), ]), )), - NativeScript::new_script_all(&ScriptAll::new(&NativeScripts::from_vec(vec![ - NativeScript::new_timelock_expiry(&TimelockExpiry::new(132)), - pkscript(&keyhash1), + &NativeScript::new_script_all(&ScriptAll::new(&scripts_vec(vec![ + &NativeScript::new_timelock_expiry(&TimelockExpiry::new(132)), + &pkscript(&keyhash1), ]))), - NativeScript::new_script_any(&ScriptAny::new(&NativeScripts::from_vec(vec![ - pkscript(&keyhash1), - pkscript(&keyhash2), - pkscript(&keyhash3), + &NativeScript::new_script_any(&ScriptAny::new(&scripts_vec(vec![ + &pkscript(&keyhash1), + &pkscript(&keyhash2), + &pkscript(&keyhash3), ]))), ]), ))); From 36800a18600b655536e5b6b1a64909cca0100577 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 11 Feb 2024 03:57:57 +0800 Subject: [PATCH 224/349] deduplication for witnesses set --- .../batch_tools/witnesses_calculator.rs | 6 +- rust/src/builders/tx_builder.rs | 15 +- rust/src/chain_crypto/algorithms/ed25519.rs | 2 +- rust/src/fakes.rs | 12 +- rust/src/protocol_types/crypto/public_key.rs | 2 +- rust/src/protocol_types/crypto/vkey.rs | 2 +- rust/src/protocol_types/ed25519_key_hashes.rs | 2 +- rust/src/protocol_types/native_scripts.rs | 24 + rust/src/protocol_types/plutus/plutus_data.rs | 31 + .../protocol_types/plutus/plutus_scripts.rs | 39 +- .../witnesses/transaction_witnesses_set.rs | 16 +- .../protocol_types/witnesses/vkeywitness.rs | 2 +- .../protocol_types/witnesses/vkeywitnesses.rs | 71 +- rust/src/serialization/credentials.rs | 4 +- rust/src/serialization/ed25519_key_hashes.rs | 4 +- rust/src/serialization/general.rs | 632 +---------------- rust/src/serialization/metadata.rs | 16 +- rust/src/serialization/native_scripts.rs | 26 + rust/src/serialization/plutus/plutus_data.rs | 34 + .../src/serialization/plutus/plutus_script.rs | 6 + .../serialization/plutus/plutus_scripts.rs | 60 +- .../witnesses/transaction_witnesses_set.rs | 20 +- .../serialization/witnesses/vkeywitnesses.rs | 14 +- rust/src/tests/builders/tx_builder.rs | 99 ++- rust/src/tests/builders/voting_builder.rs | 2 +- .../tests/builders/voting_proposal_builder.rs | 3 +- rust/src/tests/general.rs | 116 ++++ rust/src/tests/mock_objects.rs | 11 +- rust/src/tests/serialization/general.rs | 636 ++++++++++++++++++ rust/src/tests/serialization/mod.rs | 1 + rust/src/utils.rs | 4 +- 31 files changed, 1174 insertions(+), 738 deletions(-) create mode 100644 rust/src/tests/serialization/general.rs diff --git a/rust/src/builders/batch_tools/witnesses_calculator.rs b/rust/src/builders/batch_tools/witnesses_calculator.rs index 26f6ca8e..8bdc51dd 100644 --- a/rust/src/builders/batch_tools/witnesses_calculator.rs +++ b/rust/src/builders/batch_tools/witnesses_calculator.rs @@ -97,16 +97,16 @@ impl WitnessesCalculator { pub(super) fn create_mock_witnesses_set(&self) -> TransactionWitnessSet { let fake_key_root = fake_private_key(); - let raw_key_public = fake_raw_key_public(); let fake_sig = fake_raw_key_sig(); // recall: this includes keys for input, certs and withdrawals let vkeys = match self.vkeys_count { 0 => None, x => { - let fake_vkey_witness = Vkeywitness::new(&Vkey::new(&raw_key_public), &fake_sig); let mut result = Vkeywitnesses::new(); - for _i in 0..x { + for i in 0..x { + let raw_key_public = fake_raw_key_public(i); + let fake_vkey_witness = Vkeywitness::new(&Vkey::new(&raw_key_public), &fake_sig); result.add(&fake_vkey_witness.clone()); } Some(result) diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index 630322f7..e1d64917 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -31,10 +31,15 @@ pub(crate) fn fake_raw_key_sig() -> Ed25519Signature { .unwrap() } -pub(crate) fn fake_raw_key_public() -> PublicKey { +pub(crate) fn fake_raw_key_public(x: u64) -> PublicKey { + let mut bytes = [0u8; 64]; + for i in 0..8 { + bytes[i] = ((x >> (i * 8)) & 0xff) as u8; + } PublicKey::from_bytes(&[ 207, 118, 57, 154, 33, 13, 232, 114, 14, 159, 168, 148, 228, 94, 65, 226, 154, 181, 37, - 227, 11, 196, 2, 128, 28, 7, 98, 80, 209, 88, 91, 205, + 227, 11, 196, 2, 128, bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], + bytes[7] ]) .unwrap() } @@ -66,16 +71,16 @@ pub(crate) fn fake_full_tx( body: TransactionBody, ) -> Result { let fake_key_root = fake_private_key(); - let raw_key_public = fake_raw_key_public(); let fake_sig = fake_raw_key_sig(); // recall: this includes keys for input, certs and withdrawals let vkeys = match count_needed_vkeys(tx_builder) { 0 => None, x => { - let fake_vkey_witness = Vkeywitness::new(&Vkey::new(&raw_key_public), &fake_sig); let mut result = Vkeywitnesses::new(); - for _i in 0..x { + for i in 0..x { + let raw_key_public = fake_raw_key_public(i as u64); + let fake_vkey_witness = Vkeywitness::new(&Vkey::new(&raw_key_public), &fake_sig); result.add(&fake_vkey_witness.clone()); } Some(result) diff --git a/rust/src/chain_crypto/algorithms/ed25519.rs b/rust/src/chain_crypto/algorithms/ed25519.rs index 0c2a1121..7d7c0334 100644 --- a/rust/src/chain_crypto/algorithms/ed25519.rs +++ b/rust/src/chain_crypto/algorithms/ed25519.rs @@ -10,7 +10,7 @@ use rand_os::rand_core::{CryptoRng, RngCore}; use ed25519_bip32::XPub; /// ED25519 Signing Algorithm -#[derive(Clone, Debug, Eq, PartialEq, Hash)] +#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct Ed25519; #[derive(Clone)] diff --git a/rust/src/fakes.rs b/rust/src/fakes.rs index 46681f04..3a2cbef7 100644 --- a/rust/src/fakes.rs +++ b/rust/src/fakes.rs @@ -1,7 +1,5 @@ #![allow(dead_code)] -use crate::{ - AnchorDataHash, AuxiliaryDataHash, GenesisDelegateHash, GenesisHash, PoolMetadataHash, ScriptDataHash, ScriptHash, VRFKeyHash, -}; +use crate::{AnchorDataHash, AuxiliaryDataHash, GenesisDelegateHash, GenesisHash, PoolMetadataHash, PublicKey, ScriptDataHash, ScriptHash, Vkeywitness, VRFKeyHash}; use crate::{ to_bignum, Address, BaseAddress, Bip32PrivateKey, Credential, DataHash, Ed25519KeyHash, Ed25519Signature, NetworkInfo, PolicyID, TransactionHash, TransactionIndex, TransactionInput, @@ -109,6 +107,10 @@ pub(crate) fn fake_vkey() -> Vkey { ) } +pub(crate) fn fake_vkey_numbered(x: u8) -> Vkey { + Vkey::new(&PublicKey::from_bytes(&[x; 32]).unwrap()) +} + pub(crate) fn fake_signature(x: u8) -> Ed25519Signature { Ed25519Signature::from_bytes([x; 64].to_vec()).unwrap() } @@ -120,3 +122,7 @@ pub(crate) fn fake_policy_id(x: u8) -> PolicyID { pub(crate) fn fake_asset_name(x: u8) -> AssetName { AssetName([x; 32].to_vec()) } + +pub(crate) fn fake_vkey_witness(x: u8) -> Vkeywitness { + Vkeywitness::new(&fake_vkey_numbered(x), &fake_signature(x)) +} \ No newline at end of file diff --git a/rust/src/protocol_types/crypto/public_key.rs b/rust/src/protocol_types/crypto/public_key.rs index 4dd7314c..a29a292c 100644 --- a/rust/src/protocol_types/crypto/public_key.rs +++ b/rust/src/protocol_types/crypto/public_key.rs @@ -5,7 +5,7 @@ use crate::crypto::blake2b224; /// ED25519 key used as public key #[wasm_bindgen] -#[derive(Clone, Debug, Hash, Eq, PartialEq)] +#[derive(Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)] pub struct PublicKey(pub(crate) crate::chain_crypto::PublicKey); impl From> for PublicKey { diff --git a/rust/src/protocol_types/crypto/vkey.rs b/rust/src/protocol_types/crypto/vkey.rs index 7d25bcfd..99f6dc01 100644 --- a/rust/src/protocol_types/crypto/vkey.rs +++ b/rust/src/protocol_types/crypto/vkey.rs @@ -1,7 +1,7 @@ use crate::*; #[wasm_bindgen] -#[derive(Clone, Debug, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] +#[derive(Clone, Debug, Ord, PartialOrd, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] pub struct Vkey(pub(crate) PublicKey); impl_to_from!(Vkey); diff --git a/rust/src/protocol_types/ed25519_key_hashes.rs b/rust/src/protocol_types/ed25519_key_hashes.rs index bd759f80..f6cc557c 100644 --- a/rust/src/protocol_types/ed25519_key_hashes.rs +++ b/rust/src/protocol_types/ed25519_key_hashes.rs @@ -66,7 +66,7 @@ impl Ed25519KeyHashes { } pub(crate) fn extend(&mut self, other: &Ed25519KeyHashes) { - for keyhash in other.keyhashes.iter() { + for keyhash in &other.keyhashes { self.add(keyhash); } } diff --git a/rust/src/protocol_types/native_scripts.rs b/rust/src/protocol_types/native_scripts.rs index 36075776..cf49aa53 100644 --- a/rust/src/protocol_types/native_scripts.rs +++ b/rust/src/protocol_types/native_scripts.rs @@ -23,8 +23,32 @@ impl NativeScripts { pub fn add(&mut self, elem: &NativeScript) { self.0.push(elem.clone()); } + + pub(crate) fn deduplicated_view(&self) -> Vec<&NativeScript> { + let mut dedup = BTreeSet::new(); + let mut scripts = Vec::new(); + for elem in &self.0 { + if dedup.insert(elem) { + scripts.push(elem); + } + } + scripts + } + + pub(crate) fn deduplicated_clone(&self) -> NativeScripts { + let mut dedup = BTreeSet::new(); + let mut scripts = Vec::new(); + for script in &self.0 { + if dedup.insert(script.clone()) { + scripts.push(script.clone()); + } + } + NativeScripts(scripts) + } } +impl_to_from!(NativeScripts); + impl From> for NativeScripts { fn from(scripts: Vec) -> Self { scripts.iter().fold( diff --git a/rust/src/protocol_types/plutus/plutus_data.rs b/rust/src/protocol_types/plutus/plutus_data.rs index 3346ab90..d4b972c0 100644 --- a/rust/src/protocol_types/plutus/plutus_data.rs +++ b/rust/src/protocol_types/plutus/plutus_data.rs @@ -430,6 +430,37 @@ impl PlutusList { self.elems.push(elem.clone()); self.definite_encoding = None; } + + pub(crate) fn deduplicated_view(&self) -> Vec<&PlutusData> { + let mut dedup = BTreeSet::new(); + let mut keyhashes = Vec::new(); + for elem in &self.elems { + if dedup.insert(elem) { + keyhashes.push(elem); + } + } + keyhashes + } + + pub(crate) fn to_set_bytes(&self) -> Vec { + let mut buf = Serializer::new_vec(); + self.serialize_as_set(true, &mut buf).unwrap(); + buf.finalize() + } + + pub(crate) fn deduplicated_clone(&self) -> Self { + let mut dedup = BTreeSet::new(); + let mut elems = Vec::new(); + for elem in &self.elems { + if dedup.insert(elem) { + elems.push(elem.clone()); + } + } + Self { + elems, + definite_encoding: self.definite_encoding, + } + } } impl From> for PlutusList { diff --git a/rust/src/protocol_types/plutus/plutus_scripts.rs b/rust/src/protocol_types/plutus/plutus_scripts.rs index fa23e2f8..8a12c097 100644 --- a/rust/src/protocol_types/plutus/plutus_scripts.rs +++ b/rust/src/protocol_types/plutus/plutus_scripts.rs @@ -1,4 +1,5 @@ use crate::*; +use std::collections::HashSet; #[wasm_bindgen] #[derive( @@ -48,11 +49,41 @@ impl PlutusScripts { res } - pub(crate) fn map_as_version(&self, language: &Language) -> PlutusScripts { - let mut res = PlutusScripts::new(); - for s in &self.0 { - res.add(&s.clone_as_version(language)); + pub(crate) fn view(&self, version: &Language) -> Vec<&PlutusScript> { + let mut res = Vec::new(); + for script in &self.0 { + if !script.language_version().eq(version) { + continue; + } + res.push(script); } res } + + pub(crate) fn deduplicated_view(&self, version: Option<&Language>) -> Vec<&PlutusScript> { + let mut dedup = BTreeSet::new(); + let mut res = Vec::new(); + for script in &self.0 { + if let Some(version) = version { + if !script.language_version().eq(version) { + continue; + } + } + if dedup.insert(script) { + res.push(script); + } + } + res + } + + pub(crate) fn deduplicated_clone(&self) -> PlutusScripts { + let mut dedup = BTreeSet::new(); + let mut scripts = Vec::new(); + for script in &self.0 { + if dedup.insert(script.clone()) { + scripts.push(script.clone()); + } + } + PlutusScripts(scripts) + } } diff --git a/rust/src/protocol_types/witnesses/transaction_witnesses_set.rs b/rust/src/protocol_types/witnesses/transaction_witnesses_set.rs index 53983395..610feb60 100644 --- a/rust/src/protocol_types/witnesses/transaction_witnesses_set.rs +++ b/rust/src/protocol_types/witnesses/transaction_witnesses_set.rs @@ -16,7 +16,9 @@ impl_to_from!(TransactionWitnessSet); #[wasm_bindgen] impl TransactionWitnessSet { pub fn set_vkeys(&mut self, vkeys: &Vkeywitnesses) { - self.vkeys = Some(vkeys.clone()) + if vkeys.len() > 0 { + self.vkeys = Some(vkeys.clone()) + } } pub fn vkeys(&self) -> Option { @@ -24,7 +26,9 @@ impl TransactionWitnessSet { } pub fn set_native_scripts(&mut self, native_scripts: &NativeScripts) { - self.native_scripts = Some(native_scripts.clone()) + if native_scripts.len() > 0 { + self.native_scripts = Some(native_scripts.deduplicated_clone()) + } } pub fn native_scripts(&self) -> Option { @@ -40,7 +44,9 @@ impl TransactionWitnessSet { } pub fn set_plutus_scripts(&mut self, plutus_scripts: &PlutusScripts) { - self.plutus_scripts = Some(plutus_scripts.clone()) + if plutus_scripts.len() > 0 { + self.plutus_scripts = Some(plutus_scripts.deduplicated_clone()) + } } pub fn plutus_scripts(&self) -> Option { @@ -48,7 +54,9 @@ impl TransactionWitnessSet { } pub fn set_plutus_data(&mut self, plutus_data: &PlutusList) { - self.plutus_data = Some(plutus_data.clone()) + if plutus_data.len() > 0 { + self.plutus_data = Some(plutus_data.deduplicated_clone()) + } } pub fn plutus_data(&self) -> Option { diff --git a/rust/src/protocol_types/witnesses/vkeywitness.rs b/rust/src/protocol_types/witnesses/vkeywitness.rs index 7df27e09..398b5cc5 100644 --- a/rust/src/protocol_types/witnesses/vkeywitness.rs +++ b/rust/src/protocol_types/witnesses/vkeywitness.rs @@ -1,7 +1,7 @@ use crate::*; #[wasm_bindgen] -#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] +#[derive(Clone, Hash, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] pub struct Vkeywitness { pub(crate) vkey: Vkey, pub(crate) signature: Ed25519Signature, diff --git a/rust/src/protocol_types/witnesses/vkeywitnesses.rs b/rust/src/protocol_types/witnesses/vkeywitnesses.rs index 0b680d95..8529e322 100644 --- a/rust/src/protocol_types/witnesses/vkeywitnesses.rs +++ b/rust/src/protocol_types/witnesses/vkeywitnesses.rs @@ -1,26 +1,83 @@ +use hashlink::LinkedHashSet; use crate::*; #[wasm_bindgen] -#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] -pub struct Vkeywitnesses(pub(crate) Vec); +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct Vkeywitnesses { + pub(crate) witnesses: Vec, + pub(crate) dedup: LinkedHashSet, +} impl_to_from!(Vkeywitnesses); #[wasm_bindgen] impl Vkeywitnesses { pub fn new() -> Self { - Self(Vec::new()) + Self { + witnesses: Vec::new(), + dedup: LinkedHashSet::new(), + } } pub fn len(&self) -> usize { - self.0.len() + self.witnesses.len() } pub fn get(&self, index: usize) -> Vkeywitness { - self.0[index].clone() + self.witnesses[index].clone() } pub fn add(&mut self, elem: &Vkeywitness) { - self.0.push(elem.clone()); + if self.dedup.insert(elem.clone()) { + self.witnesses.push(elem.clone()); + } } -} \ No newline at end of file + + pub(crate) fn add_move(&mut self, elem: Vkeywitness) { + if self.dedup.insert(elem.clone()) { + self.witnesses.push(elem); + } + } + + pub(crate) fn from_vec(vec: Vec) -> Self { + let mut dedup = LinkedHashSet::new(); + let mut witnesses = Vec::new(); + for elem in vec { + if dedup.insert(elem.clone()) { + witnesses.push(elem); + } + } + Self { witnesses, dedup } + } +} + +impl serde::Serialize for Vkeywitnesses { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + self.witnesses.serialize(serializer) + } +} + +impl<'de> serde::de::Deserialize<'de> for Vkeywitnesses { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let vec = as serde::de::Deserialize>::deserialize(deserializer)?; + Ok(Self::from_vec(vec)) + } +} + +impl JsonSchema for Vkeywitnesses { + fn schema_name() -> String { + String::from("Vkeywitnesses") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + Vec::::json_schema(gen) + } + fn is_referenceable() -> bool { + Vec::::is_referenceable() + } +} diff --git a/rust/src/serialization/credentials.rs b/rust/src/serialization/credentials.rs index 73329020..b5403f9f 100644 --- a/rust/src/serialization/credentials.rs +++ b/rust/src/serialization/credentials.rs @@ -20,10 +20,11 @@ impl Deserialize for Credentials { fn deserialize(raw: &mut Deserializer) -> Result { skip_set_tag(raw)?; let mut creds = Credentials::new(); + let mut counter = 0u64; (|| -> Result<_, DeserializeError> { let len = raw.array()?; while match len { - cbor_event::Len::Len(n) => creds.len() < n as usize, + cbor_event::Len::Len(n) => counter < n, cbor_event::Len::Indefinite => true, } { if raw.cbor_type()? == CBORType::Special { @@ -31,6 +32,7 @@ impl Deserialize for Credentials { break; } creds.add_move(Credential::deserialize(raw)?); + counter += 1; } Ok(()) })() diff --git a/rust/src/serialization/ed25519_key_hashes.rs b/rust/src/serialization/ed25519_key_hashes.rs index 21970798..5156fbfc 100644 --- a/rust/src/serialization/ed25519_key_hashes.rs +++ b/rust/src/serialization/ed25519_key_hashes.rs @@ -20,10 +20,11 @@ impl Deserialize for Ed25519KeyHashes { fn deserialize(raw: &mut Deserializer) -> Result { skip_set_tag(raw)?; let mut creds = Ed25519KeyHashes::new(); + let mut counter = 0u64; (|| -> Result<_, DeserializeError> { let len = raw.array()?; while match len { - cbor_event::Len::Len(n) => creds.len() < n as usize, + cbor_event::Len::Len(n) => counter < n, cbor_event::Len::Indefinite => true, } { if raw.cbor_type()? == CBORType::Special { @@ -31,6 +32,7 @@ impl Deserialize for Ed25519KeyHashes { break; } creds.add_move(Ed25519KeyHash::deserialize(raw)?); + counter += 1; } Ok(()) })() diff --git a/rust/src/serialization/general.rs b/rust/src/serialization/general.rs index 853dd34d..3420a02f 100644 --- a/rust/src/serialization/general.rs +++ b/rust/src/serialization/general.rs @@ -2075,634 +2075,4 @@ impl Deserialize for NetworkId { })() .map_err(|e| e.annotate("NetworkId")) } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::fakes::{ - fake_base_address, fake_bytes_32, fake_data_hash, fake_signature, fake_tx_input, - fake_tx_output, fake_value, fake_value2, fake_vkey, - }; - - #[test] - fn tx_output_deser_lagacy() { - let mut txos = TransactionOutputs::new(); - let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); - let val = &Value::new(&BigNum::from_str("435464757").unwrap()); - let txo = TransactionOutput { - address: addr.clone(), - amount: val.clone(), - plutus_data: None, - script_ref: None, - serialization_format: None, - }; - let mut txo_dh = txo.clone(); - txo_dh.set_data_hash(&DataHash::from([47u8; DataHash::BYTE_COUNT])); - txos.add(&txo); - txos.add(&txo_dh); - txos.add(&txo_dh); - txos.add(&txo); - txos.add(&txo); - txos.add(&txo_dh); - let bytes = txos.to_bytes(); - let txos_deser = TransactionOutputs::from_bytes(bytes.clone()).unwrap(); - let bytes_deser = txos_deser.to_bytes(); - assert_eq!(bytes, bytes_deser); - } - - #[test] - fn tx_output_deser_post_alonzo_with_plutus_script_and_datum() { - let mut txos = TransactionOutputs::new(); - let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); - let val = &Value::new(&BigNum::from_str("435464757").unwrap()); - let txo = TransactionOutput { - address: addr.clone(), - amount: val.clone(), - plutus_data: None, - script_ref: None, - serialization_format: None, - }; - let mut txo_dh = txo.clone(); - txo_dh.set_plutus_data(&PlutusData::new_bytes(fake_bytes_32(11))); - txo_dh.set_script_ref(&ScriptRef::new_plutus_script(&PlutusScript::new( - [61u8; 29].to_vec(), - ))); - txos.add(&txo); - txos.add(&txo_dh); - txos.add(&txo_dh); - txos.add(&txo); - txos.add(&txo); - txos.add(&txo_dh); - let bytes = txos.to_bytes(); - let txos_deser = TransactionOutputs::from_bytes(bytes.clone()).unwrap(); - let bytes_deser = txos_deser.to_bytes(); - assert_eq!(bytes, bytes_deser); - } - - #[test] - fn tx_output_deser_post_alonzo_with_plutus_script() { - let mut txos = TransactionOutputs::new(); - let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); - let val = &Value::new(&BigNum::from_str("435464757").unwrap()); - let txo = TransactionOutput { - address: addr.clone(), - amount: val.clone(), - plutus_data: None, - script_ref: None, - serialization_format: None, - }; - let mut txo_dh = txo.clone(); - txo_dh.set_script_ref(&ScriptRef::new_plutus_script(&PlutusScript::new( - [61u8; 29].to_vec(), - ))); - txos.add(&txo); - txos.add(&txo_dh); - txos.add(&txo_dh); - txos.add(&txo); - txos.add(&txo); - txos.add(&txo_dh); - let bytes = txos.to_bytes(); - let txos_deser = TransactionOutputs::from_bytes(bytes.clone()).unwrap(); - let bytes_deser = txos_deser.to_bytes(); - assert_eq!(bytes, bytes_deser); - } - - #[test] - fn tx_output_deser_post_alonzo_with_datum() { - let mut txos = TransactionOutputs::new(); - let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); - let val = &Value::new(&BigNum::from_str("435464757").unwrap()); - let txo = TransactionOutput { - address: addr.clone(), - amount: val.clone(), - plutus_data: None, - script_ref: None, - serialization_format: None, - }; - let mut txo_dh = txo.clone(); - txo_dh.set_plutus_data(&PlutusData::new_bytes(fake_bytes_32(11))); - txos.add(&txo); - txos.add(&txo_dh); - txos.add(&txo_dh); - txos.add(&txo); - txos.add(&txo); - txos.add(&txo_dh); - let bytes = txos.to_bytes(); - let txos_deser = TransactionOutputs::from_bytes(bytes.clone()).unwrap(); - let bytes_deser = txos_deser.to_bytes(); - assert_eq!(bytes, bytes_deser); - } - - #[test] - fn tx_output_deser_post_alonzo_with_native_script_and_datum() { - let mut txos = TransactionOutputs::new(); - let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); - let val = &Value::new(&BigNum::from_str("435464757").unwrap()); - let txo = TransactionOutput { - address: addr.clone(), - amount: val.clone(), - plutus_data: None, - script_ref: None, - serialization_format: None, - }; - let mut txo_dh = txo.clone(); - let native_script = NativeScript::new_timelock_start(&TimelockStart::new(20)); - txo_dh.set_script_ref(&ScriptRef::new_native_script(&native_script)); - txo_dh.set_plutus_data(&PlutusData::new_bytes(fake_bytes_32(11))); - txos.add(&txo); - txos.add(&txo_dh); - txos.add(&txo_dh); - txos.add(&txo); - txos.add(&txo); - txos.add(&txo_dh); - let bytes = txos.to_bytes(); - let txos_deser = TransactionOutputs::from_bytes(bytes.clone()).unwrap(); - let bytes_deser = txos_deser.to_bytes(); - assert_eq!(bytes, bytes_deser); - } - - #[test] - fn tx_output_deser_post_alonzo_with_native_script() { - let mut txos = TransactionOutputs::new(); - let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); - let val = &Value::new(&BigNum::from_str("435464757").unwrap()); - let txo = TransactionOutput { - address: addr.clone(), - amount: val.clone(), - plutus_data: None, - script_ref: None, - serialization_format: None, - }; - let mut txo_dh = txo.clone(); - let native_script = NativeScript::new_timelock_start(&TimelockStart::new(20)); - txo_dh.set_script_ref(&ScriptRef::new_native_script(&native_script)); - txos.add(&txo); - txos.add(&txo_dh); - txos.add(&txo_dh); - txos.add(&txo); - txos.add(&txo); - txos.add(&txo_dh); - let bytes = txos.to_bytes(); - let txos_deser = TransactionOutputs::from_bytes(bytes.clone()).unwrap(); - let bytes_deser = txos_deser.to_bytes(); - assert_eq!(bytes, bytes_deser); - } - - #[test] - fn tx_output_deser_post_alonzo_with_native_script_and_data_hash() { - let mut txos = TransactionOutputs::new(); - let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); - let val = &Value::new(&BigNum::from_str("435464757").unwrap()); - let txo = TransactionOutput { - address: addr.clone(), - amount: val.clone(), - plutus_data: None, - script_ref: None, - serialization_format: None, - }; - let mut txo_dh = txo.clone(); - let native_script = NativeScript::new_timelock_start(&TimelockStart::new(20)); - let data_hash = DataHash::from_bytes(vec![ - 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, - ]) - .unwrap(); - txo_dh.set_data_hash(&data_hash); - txo_dh.set_script_ref(&ScriptRef::new_native_script(&native_script)); - txos.add(&txo); - txos.add(&txo_dh); - txos.add(&txo_dh); - txos.add(&txo); - txos.add(&txo); - txos.add(&txo_dh); - let bytes = txos.to_bytes(); - let txos_deser = TransactionOutputs::from_bytes(bytes.clone()).unwrap(); - let bytes_deser = txos_deser.to_bytes(); - assert_eq!(bytes, bytes_deser); - } - - #[test] - fn tx_output_deser_lagacy_json() { - let mut txos = TransactionOutputs::new(); - let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); - let val = &Value::new(&BigNum::from_str("435464757").unwrap()); - let txo = TransactionOutput { - address: addr.clone(), - amount: val.clone(), - plutus_data: None, - script_ref: None, - serialization_format: None, - }; - let mut txo_dh = txo.clone(); - txo_dh.set_data_hash(&DataHash::from([47u8; DataHash::BYTE_COUNT])); - txos.add(&txo); - txos.add(&txo_dh); - txos.add(&txo_dh); - txos.add(&txo); - txos.add(&txo); - txos.add(&txo_dh); - let json_txos = txos.to_json().unwrap(); - let deser_txos = TransactionOutputs::from_json(json_txos.as_str()).unwrap(); - - assert_eq!(deser_txos.to_bytes(), txos.to_bytes()); - assert_eq!(deser_txos.to_json().unwrap(), txos.to_json().unwrap()); - } - - #[test] - fn tx_output_deser_post_alonzo_with_plutus_script_and_datum_json() { - let mut txos = TransactionOutputs::new(); - let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); - let val = &Value::new(&BigNum::from_str("435464757").unwrap()); - let txo = TransactionOutput { - address: addr.clone(), - amount: val.clone(), - plutus_data: None, - script_ref: None, - serialization_format: None, - }; - let mut txo_dh = txo.clone(); - txo_dh.set_plutus_data(&PlutusData::new_bytes(fake_bytes_32(11))); - txo_dh.set_script_ref(&ScriptRef::new_plutus_script(&PlutusScript::new( - [61u8; 29].to_vec(), - ))); - txos.add(&txo); - txos.add(&txo_dh); - txos.add(&txo_dh); - txos.add(&txo); - txos.add(&txo); - txos.add(&txo_dh); - let json_txos = txos.to_json().unwrap(); - let deser_txos = TransactionOutputs::from_json(json_txos.as_str()).unwrap(); - - assert_eq!(deser_txos.to_bytes(), txos.to_bytes()); - assert_eq!(deser_txos.to_json().unwrap(), txos.to_json().unwrap()); - } - - #[test] - fn tx_output_deser_post_alonzo_with_plutus_script_json() { - let mut txos = TransactionOutputs::new(); - let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); - let val = &Value::new(&BigNum::from_str("435464757").unwrap()); - let txo = TransactionOutput { - address: addr.clone(), - amount: val.clone(), - plutus_data: None, - script_ref: None, - serialization_format: None, - }; - let mut txo_dh = txo.clone(); - txo_dh.set_script_ref(&ScriptRef::new_plutus_script(&PlutusScript::new( - [61u8; 29].to_vec(), - ))); - txos.add(&txo); - txos.add(&txo_dh); - txos.add(&txo_dh); - txos.add(&txo); - txos.add(&txo); - txos.add(&txo_dh); - let json_txos = txos.to_json().unwrap(); - let deser_txos = TransactionOutputs::from_json(json_txos.as_str()).unwrap(); - - assert_eq!(deser_txos.to_bytes(), txos.to_bytes()); - assert_eq!(deser_txos.to_json().unwrap(), txos.to_json().unwrap()); - } - - #[test] - fn tx_output_deser_post_alonzo_with_datum_json() { - let mut txos = TransactionOutputs::new(); - let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); - let val = &Value::new(&BigNum::from_str("435464757").unwrap()); - let txo = TransactionOutput { - address: addr.clone(), - amount: val.clone(), - plutus_data: None, - script_ref: None, - serialization_format: None, - }; - let mut txo_dh = txo.clone(); - txo_dh.set_plutus_data(&PlutusData::new_bytes(fake_bytes_32(11))); - txos.add(&txo); - txos.add(&txo_dh); - txos.add(&txo_dh); - txos.add(&txo); - txos.add(&txo); - txos.add(&txo_dh); - let json_txos = txos.to_json().unwrap(); - let deser_txos = TransactionOutputs::from_json(json_txos.as_str()).unwrap(); - - assert_eq!(deser_txos.to_bytes(), txos.to_bytes()); - assert_eq!(deser_txos.to_json().unwrap(), txos.to_json().unwrap()); - } - - #[test] - fn tx_output_deser_post_alonzo_with_native_script_and_datum_json() { - let mut txos = TransactionOutputs::new(); - let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); - let val = &Value::new(&BigNum::from_str("435464757").unwrap()); - let txo = TransactionOutput { - address: addr.clone(), - amount: val.clone(), - plutus_data: None, - script_ref: None, - serialization_format: None, - }; - let mut txo_dh = txo.clone(); - let native_script = NativeScript::new_timelock_start(&TimelockStart::new(20)); - txo_dh.set_script_ref(&ScriptRef::new_native_script(&native_script)); - txo_dh.set_plutus_data(&PlutusData::new_bytes(fake_bytes_32(11))); - txos.add(&txo); - txos.add(&txo_dh); - txos.add(&txo_dh); - txos.add(&txo); - txos.add(&txo); - txos.add(&txo_dh); - let json_txos = txos.to_json().unwrap(); - let deser_txos = TransactionOutputs::from_json(json_txos.as_str()).unwrap(); - - assert_eq!(deser_txos.to_bytes(), txos.to_bytes()); - assert_eq!(deser_txos.to_json().unwrap(), txos.to_json().unwrap()); - } - - #[test] - fn tx_output_deser_post_alonzo_with_native_script_json() { - let mut txos = TransactionOutputs::new(); - let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); - let val = &Value::new(&BigNum::from_str("435464757").unwrap()); - let txo = TransactionOutput { - address: addr.clone(), - amount: val.clone(), - plutus_data: None, - script_ref: None, - serialization_format: None, - }; - let mut txo_dh = txo.clone(); - let native_script = NativeScript::new_timelock_start(&TimelockStart::new(20)); - txo_dh.set_script_ref(&ScriptRef::new_native_script(&native_script)); - txos.add(&txo); - txos.add(&txo_dh); - txos.add(&txo_dh); - txos.add(&txo); - txos.add(&txo); - txos.add(&txo_dh); - let json_txos = txos.to_json().unwrap(); - let deser_txos = TransactionOutputs::from_json(json_txos.as_str()).unwrap(); - - assert_eq!(deser_txos.to_bytes(), txos.to_bytes()); - assert_eq!(deser_txos.to_json().unwrap(), txos.to_json().unwrap()); - } - - #[test] - fn tx_output_deser_post_alonzo_with_native_script_and_data_hash_json() { - let mut txos = TransactionOutputs::new(); - let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); - let val = &Value::new(&BigNum::from_str("435464757").unwrap()); - let txo = TransactionOutput { - address: addr.clone(), - amount: val.clone(), - plutus_data: None, - script_ref: None, - serialization_format: None, - }; - let mut txo_dh = txo.clone(); - let native_script = NativeScript::new_timelock_start(&TimelockStart::new(20)); - let data_hash = DataHash::from_bytes(vec![ - 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, - ]) - .unwrap(); - txo_dh.set_data_hash(&data_hash); - txo_dh.set_script_ref(&ScriptRef::new_native_script(&native_script)); - txos.add(&txo); - txos.add(&txo_dh); - txos.add(&txo_dh); - txos.add(&txo); - txos.add(&txo); - txos.add(&txo_dh); - let json_txos = txos.to_json().unwrap(); - let deser_txos = TransactionOutputs::from_json(json_txos.as_str()).unwrap(); - - assert_eq!(deser_txos.to_bytes(), txos.to_bytes()); - assert_eq!(deser_txos.to_json().unwrap(), txos.to_json().unwrap()); - } - - #[test] - fn mir_deser() { - let reserves_to_pot = MoveInstantaneousReward::new_to_other_pot( - MIRPot::Treasury, - &Coin::from_str("143546464").unwrap(), - ); - let reserves_to_pot_deser = - MoveInstantaneousReward::from_bytes(reserves_to_pot.to_bytes()).unwrap(); - assert_eq!(reserves_to_pot.to_bytes(), reserves_to_pot_deser.to_bytes()); - let treasury_to_pot = MoveInstantaneousReward::new_to_other_pot( - MIRPot::Treasury, - &Coin::from_str("0").unwrap(), - ); - let treasury_to_pot_deser = - MoveInstantaneousReward::from_bytes(treasury_to_pot.to_bytes()).unwrap(); - assert_eq!(treasury_to_pot.to_bytes(), treasury_to_pot_deser.to_bytes()); - let mut stake_creds = MIRToStakeCredentials::new(); - stake_creds.insert( - &Credential::from_scripthash(&ScriptHash([54u8; ScriptHash::BYTE_COUNT])), - &Int::new_i32(-314159265), - ); - let to_stake_creds = - MoveInstantaneousReward::new_to_stake_creds(MIRPot::Treasury, &stake_creds); - let to_stake_creds_deser = - MoveInstantaneousReward::from_bytes(to_stake_creds.to_bytes()).unwrap(); - assert_eq!(to_stake_creds.to_bytes(), to_stake_creds_deser.to_bytes()); - } - - #[test] - #[ignore] - fn alonzo_block() { - // this test for some reason has 2-byte pool metadata hashes so don't run this without changing that - let bytes = hex::decode("85828f03095820bb30a42c1e62f0afda5f0a4e8a562f7a13a24cea00ee81917b86b89e801314aa58208a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c58208a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c8258404fefc7c718693b57c87170ceba220382afbdd148c0a53b4a009ca63ad1f101483a6170c83a77f23d362a68dcb502802df7f98fa4f7a78b4082b211530e1234305850f770f6769ae9871d42b970fc6254bb927c2181fff45897f241bd72221d86d33c8df64c0a3c8cbb9aa52fef191d7202465c52df8d33727a38c7dc5d40864d753348a340f8afcbb3bb05d4a03f16b1080d825840fe682775f0fa232e909ddc9ec3210ea7a0ee6514cd8b0815190a08f7cef3985463152e10dfad9ed6c09b641b6c1824498e77814a7c12e03096a63cd62056446358500951ed3ef2065e4196d008b50a63bb3e2bdc9a64df67eff4e230b35429291def476684114e074357a5c834bf79eacf583b6fe9fcd1d17f3719a31de97aa4da5e4630b05421359e0b6e4a9bd76c6b920b190929582010c865acec05c84c2c0d0b889f7dbe9bf3b5561f8552da1eb286eac4ccdabc5e5820d298da3803eb9958f01c02e73f2410f2f9bb2ecbc346526b1b76772e1bdd7db500005840940f8a3696847e4a238705bdd27a345086282067b9bc5cb7b69847ca8756085844d576f59ab056c169a504320cc1eab4c11fd529482b3c57da6fa96d44635b0802005901c0a1b2ee63b357fe0b19c6bb8dc3fc865c0608a89626505c5f9aff3b74a0809ca2635e0c4235c247306987c7fd76a4a06210ebf74178e72a1faa78fb8865a69005cc6a5ab5c9b40f817c715df558af7d07b6186f0ccf31715ec2fb00980730ac166af657e6670608afe1bf651d496e01b1c7ff1eb44614d8cfd1b7e32b2c2939349236cc0ada145d8d8d7ad919ef1e60c8bbad31dbedf9f395849705a00c14a8785106aae31f55abc5b1f2089cbef16d9401f158704c1e4f740f7125cfc700a99d97d0332eacb33e4bbc8dab2872ec2b3df9e113addaebd156bfc64fdfc732614d2aedd10a58a34993b7b08c822af3aa615b6bbb9b267bc902e4f1075e194aed084ca18f8bcde1a6b094bf3f5295a0d454c0a083ed5b74f7092fc0a7346c03979a30eeea76d686e512ba48d21544ba874886cdd166cbf275b11f1f3881f4c4277c09a24b88fc6168f4578267bdc9d62cb9b78b8dfc888ccce226a177725f39e7d50930552861d1e88b7898971c780dc3b773321ba1854422b5cecead7d50e77783050eeae2cd9595b9cd91681c72e5d53bb7d12f28dec9b2847ee70a3d7781fb1133aea3b169f536ff5945ec0a76950e51beded0627bb78120617a2f0842e50e3981ae0081825820ee155ace9c40292074cb6aff8c9ccdd273c81648ff1149ef36bcea6ebb8a3e25000d81825820bb30a42c1e62f0afda5f0a4e8a562f7a13a24cea00ee81917b86b89e801314aa01018183583900cb9358529df4729c3246a2a033cb9821abbfd16de4888005904abc410d6a577e9441ad8ed9663931906e4d43ece8f82c712b1d0235affb06821864a1581ca646474b8f5431261506b6c273d307c7569a4eb6c96b42dd4a29520aa14a636f75747473436f696e1903e85820ee155ace9c40292074cb6aff8c9ccdd273c81648ff1149ef36bcea6ebb8a3e25021903e70304048382008200581c0d6a577e9441ad8ed9663931906e4d43ece8f82c712b1d0235affb068a03581c0d6a577e9441ad8ed9663931906e4d43ece8f82c712b1d0235affb065820c5e21ab1c9f6022d81c3b25e3436cb7f1df77f9652ae3e1310c28e621dd87b4c0105d81e82010a581de00d6a577e9441ad8ed9663931906e4d43ece8f82c712b1d0235affb0681581c0d6a577e9441ad8ed9663931906e4d43ece8f82c712b1d0235affb0680826e636f6e73656e7375732e706f6f6c427b7d82068200a18200581c008b47844d92812fc30d1f0ac9b6fbf38778ccba9db8312ad9079079186e05a1581de00d6a577e9441ad8ed9663931906e4d43ece8f82c712b1d0235affb0618640682a1581ce0a714319812c3f773ba04ec5d6b3ffcd5aad85006805b047b082541a104190fa00008020e81581cf81ce66e0f52da5ca48193386e7511fde5b030a307b4c3681736c6f009a1581cb16b56f5ec064be6ac3cab6035efae86b366cc3dc4a0d571603d70e5a14a636f75747473436f696e1903e80b58209e1199a988ba72ffd6e9c269cadb3b53b5f360ff99f112d9b2ee30c4d74ad88b0758209e1199a988ba72ffd6e9c269cadb3b53b5f360ff99f112d9b2ee30c4d74ad88b0f0181a400818258203b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da295840815671b581b4b02a30108a799a85c7f2e5487fb667e748e8fde59e466ab987ce133ecb77ffa0dc53c5804e6706e26b94e17803235da28112bc747de48ccbd70903814c4b0100002002002002000011048118bf058184000019039782191388191388a100d90103a300a40166737472696e67024562797465730382010204a10341620181820180028148470100002002006180").unwrap(); - let block = Block::from_bytes(bytes).unwrap(); - let block2 = Block::from_bytes(block.to_bytes()).unwrap(); - assert_eq!(block.to_bytes(), block2.to_bytes()); - } - - #[test] - fn test_tx_body_roundtrip() { - let mut txb = TransactionBody::new( - &TransactionInputs(vec![fake_tx_input(0)]), - &TransactionOutputs(vec![fake_tx_output(1)]), - &to_bignum(1234567), - Some(12345678), - ); - - txb.set_collateral_return(&fake_tx_output(2)); - txb.set_total_collateral(&to_bignum(1234)); - - let txb2 = TransactionBody::from_bytes(txb.to_bytes()).unwrap(); - assert_eq!(txb, txb2); - } - - #[test] - fn test_header_body_roundtrip() { - fn fake_header_body(leader_cert: HeaderLeaderCertEnum) -> HeaderBody { - HeaderBody { - block_number: 123, - slot: to_bignum(123), - prev_hash: Some(BlockHash::from_bytes(fake_bytes_32(1)).unwrap()), - issuer_vkey: fake_vkey(), - vrf_vkey: VRFVKey::from_bytes(fake_bytes_32(2)).unwrap(), - leader_cert, - block_body_size: 123456, - block_body_hash: BlockHash::from_bytes(fake_bytes_32(4)).unwrap(), - operational_cert: OperationalCert::new( - &KESVKey::from_bytes(fake_bytes_32(5)).unwrap(), - 123, - 456, - &fake_signature(6), - ), - protocol_version: ProtocolVersion::new(12, 13), - } - } - - let hbody1 = fake_header_body(HeaderLeaderCertEnum::VrfResult( - VRFCert::new(fake_bytes_32(3), [0; 80].to_vec()).unwrap(), - )); - - assert_eq!(hbody1, HeaderBody::from_bytes(hbody1.to_bytes()).unwrap()); - - let hbody2 = fake_header_body(HeaderLeaderCertEnum::NonceAndLeader( - VRFCert::new(fake_bytes_32(4), [1; 80].to_vec()).unwrap(), - VRFCert::new(fake_bytes_32(5), [2; 80].to_vec()).unwrap(), - )); - - assert_eq!(hbody2, HeaderBody::from_bytes(hbody2.to_bytes()).unwrap()); - } - - #[test] - fn test_witness_set_roundtrip() { - fn witness_set_roundtrip(plutus_scripts: &PlutusScripts) { - let mut ws = TransactionWitnessSet::new(); - ws.set_vkeys(&Vkeywitnesses(vec![Vkeywitness::new( - &fake_vkey(), - &fake_signature(1), - )])); - ws.set_redeemers(&Redeemers(vec![Redeemer::new( - &RedeemerTag::new_spend(), - &to_bignum(12), - &PlutusData::new_integer(&BigInt::one()), - &ExUnits::new(&to_bignum(123), &to_bignum(456)), - )])); - ws.set_plutus_data(&PlutusList::from(vec![PlutusData::new_integer( - &BigInt::one(), - )])); - ws.set_plutus_scripts(plutus_scripts); - - assert_eq!( - TransactionWitnessSet::from_bytes(ws.to_bytes()).unwrap(), - ws - ); - } - - let bytes = hex::decode("4e4d01000033222220051200120011").unwrap(); - let script_v1 = PlutusScript::from_bytes(bytes.clone()).unwrap(); - let script_v2 = PlutusScript::from_bytes_v2(bytes.clone()).unwrap(); - let script_v3 = PlutusScript::from_bytes_v3(bytes.clone()).unwrap(); - - witness_set_roundtrip(&PlutusScripts(vec![])); - witness_set_roundtrip(&PlutusScripts(vec![script_v1.clone()])); - witness_set_roundtrip(&PlutusScripts(vec![script_v2.clone()])); - witness_set_roundtrip(&PlutusScripts(vec![script_v3.clone()])); - witness_set_roundtrip(&PlutusScripts(vec![script_v1.clone(), script_v2.clone()])); - witness_set_roundtrip(&PlutusScripts(vec![script_v1.clone(), script_v2.clone(), script_v3.clone()])); - } - - #[test] - fn test_script_ref_roundtrip() { - let ref0 = ScriptRef::new_native_script(&NativeScript::new_timelock_start( - &TimelockStart::new(123456), - )); - assert_eq!(ScriptRef::from_bytes(ref0.to_bytes()).unwrap(), ref0); - - let bytes = hex::decode("4e4d01000033222220051200120011").unwrap(); - let script_v1 = PlutusScript::from_bytes(bytes.clone()).unwrap(); - let script_v2 = PlutusScript::from_bytes_v2(bytes.clone()).unwrap(); - let script_v3 = PlutusScript::from_bytes_v3(bytes.clone()).unwrap(); - - let ref1 = ScriptRef::new_plutus_script(&script_v1); - assert_eq!(ScriptRef::from_bytes(ref1.to_bytes()).unwrap(), ref1); - - let ref2 = ScriptRef::new_plutus_script(&script_v2); - assert_eq!(ScriptRef::from_bytes(ref2.to_bytes()).unwrap(), ref2); - - let ref3 = ScriptRef::new_plutus_script(&script_v3); - assert_eq!(ScriptRef::from_bytes(ref3.to_bytes()).unwrap(), ref3); - } - - #[test] - fn legacy_output_roundtrip() { - let o1 = TransactionOutput::new(&fake_base_address(0), &fake_value()); - let mut o2 = TransactionOutput::new(&fake_base_address(1), &fake_value()); - o2.set_data_hash(&fake_data_hash(2)); - - assert_eq!(TransactionOutput::from_bytes(o1.to_bytes()).unwrap(), o1); - assert_eq!(TransactionOutput::from_bytes(o2.to_bytes()).unwrap(), o2); - } - - #[test] - fn babbage_output_roundtrip() { - let mut o1 = TransactionOutput::new(&fake_base_address(0), &fake_value2(234567)); - o1.set_plutus_data(&PlutusData::new_empty_constr_plutus_data(&to_bignum(42))); - assert_eq!(TransactionOutput::from_bytes(o1.to_bytes()).unwrap(), o1); - - let mut o2 = TransactionOutput::new(&fake_base_address(1), &fake_value2(234568)); - o2.set_script_ref(&ScriptRef::new_native_script( - &NativeScript::new_timelock_start(&TimelockStart::new(123456)), - )); - assert_eq!(TransactionOutput::from_bytes(o2.to_bytes()).unwrap(), o2); - - let bytes = hex::decode("4e4d01000033222220051200120011").unwrap(); - let script_v1 = PlutusScript::from_bytes(bytes.clone()).unwrap(); - let script_v2 = PlutusScript::from_bytes_v2(bytes.clone()).unwrap(); - let script_v3 = PlutusScript::from_bytes_v3(bytes.clone()).unwrap(); - - let mut o3 = TransactionOutput::new(&fake_base_address(2), &fake_value2(234569)); - o3.set_script_ref(&ScriptRef::new_plutus_script(&script_v1)); - assert_eq!(TransactionOutput::from_bytes(o3.to_bytes()).unwrap(), o3); - - let mut o4 = TransactionOutput::new(&fake_base_address(3), &fake_value2(234570)); - o4.set_script_ref(&ScriptRef::new_plutus_script(&script_v2)); - assert_eq!(TransactionOutput::from_bytes(o4.to_bytes()).unwrap(), o4); - - let mut o5 = TransactionOutput::new(&fake_base_address(4), &fake_value2(234571)); - o5.set_plutus_data(&PlutusData::new_empty_constr_plutus_data(&to_bignum(43))); - o5.set_script_ref(&ScriptRef::new_plutus_script(&script_v2)); - assert_eq!(TransactionOutput::from_bytes(o5.to_bytes()).unwrap(), o5); - - let mut o6 = TransactionOutput::new(&fake_base_address(5), &fake_value2(234572)); - o6.set_data_hash(&fake_data_hash(222)); - o6.set_script_ref(&ScriptRef::new_plutus_script(&script_v2)); - assert_eq!(TransactionOutput::from_bytes(o6.to_bytes()).unwrap(), o6); - - let mut o7 = TransactionOutput::new(&fake_base_address(6), &fake_value2(234573)); - o7.set_script_ref(&ScriptRef::new_plutus_script(&script_v3)); - assert_eq!(TransactionOutput::from_bytes(o7.to_bytes()).unwrap(), o7); - } - - #[test] - fn pre_alonzo_block() { - let bytes = hex::decode("84828f1a002072a81a00ca44f0582070d6f38b4569ba062c09632127db13474f22c534e6d8097895403c431e57f12358204f4d7523e41e058a6cbdefb5538654ffc2a53416a7f5bb99f7eac699d42d5c1f58205e3d96cb8ef0291d2f1df6aa7b5a4496ac8de1dcce100c31274325625102796d82584065417914ca323d842c5861407a638e146e6af55f59aff95f1451839de2aa709151237e24e6db7bf94db97293da9c1e61e68d60c8e2b10a116d3c71067247458b5850dc36a5a88f09f0b7a0b5d5d52d87c7c3e3c20752176a426d182255df3d026392f407990f09e5858de6432263fc167bc890a97d07d2371cd5bb26b12242c1ff6fda184ec78d15493a38a3e0df1494f800825840df4e07d3bca43341e4297e2914ea38363ecea1c17ce9145294c4631e0f09f706cb23a5f27c6b71ae9ac46a7ca25af4d7c156f15444fa41814f7d6a0b6a4e57525850d6073f277ded1ef9e8bfe9f6325858c142fbbbbff4395c45d82f0861a6ef6116204965f807e8650fa4e9ac4aa04aeb03984ea66abb129155a78931d39bbcb7ad64afef3f4f55cfa4eb6c97698e88f1051905db5820c1b1fbd809dc06e0e2dc544312aae2a46c059249f86c24ea0689a0b0944a75f558207ce5ce3992b23cb2bf566c48aba8bfc39eb24c9b43354de0129b81bf9f1414b307186058403ac64d720227c18139132b499046a168eb1c5bdd3983385e3518f33fc7f52fd0be348fe3e14d17e1ba606708c30bda061cf23ea3294b0089d3e1e1d58a7aa50702005901c074d3c2c0b5e17b12ba829017186daa1f7f365bbe5b0e0c038cb0cc05e849f702afd349234353ee3cc8878fa31299e85562f04d3cdd74e1bc73591be48d2fbc0d043f6b41fa527b2f9fb3f77605eee528926e76cc18a1638283e5591170f7073462441d40d7cc2e13a38e7d247928cb15d2e5b2e74a12d07f858f7e922bbff8a91c16e9bb8f5ea101c50d96627fb48a03d8191b5035b5de00b9824867fdffb5a2493799e94676bf685db85517dd8a87a0ba2589b3a8a69d529ae8052680c520c5577adbb91cf931e906b1629e621d5bd5c30eaee77f35c5f0a714827b48afaa4e549c1756e94291f4b083aad9c375caf9a67aeac08f32c91cd0572192267960cd74a85148b5e99d0053804dcfb44785417725c56e0fc5caf2ae50fbf25b92c7b7ebe17aa9e289470041a06fd8986f6f9ebdb12e87a970f1d388963929367013e17513e83cab8c98460cab703d5fdd26eeb079e4db701996f73c694365080236901289c5fc96471e91fb75e0e58560f5d073c3ef79a8f5dd4b45ff7abf9c7d7564232f7897ca3d85ac7bb9ecaa75b7c062f27de8b20f301e5607563b2c904e3c7f113b1eeba8a4d1c82fc1a747c920bac6af9a9f4dae1744847232ea03289e25e482a50082825820478ad95cafe9b1660809d618870c86dda1295764e113886e2b8a1de2de5af17201825820f84508cc7674b663db84ceb9f0790f5527f3c70f2a05e4d7f783cd9890463b4e01018182583900ff7f04abbd3050c0b138c8fa3005d48aaf8b9700d4565758e91a95385667fab107f848cfd4b73a7407a7661600cf68f0efc969ece37665ae1a000f4240021a000f4240031a00ca60f1075820e845fe9180ac36cc0102f892a839ad1ed2ea9a52c605fb8e4e1c2774ef0bb65ba50081825820c4b5ad6873b8581c75b8ee52f58a3eded29acbbb92d874a64228a1ca4e68956700018182581d60daad04ed2b7f69e2a9be582e37091739fa036a14c1c22f88061d43c71b004aca96b58fd90c021a000f4240031a00d986900682a7581c0d06d2547ed371fdf95fb5c4c735eecdd53e6a5bb831561bd0fcfd3da10e820300581c2f56e87d67b8e5216582cfeb95dbdc9083110a3ef68faaa51bef3a80a10e820300581c2fca486b4d8f1a0432f5bf18ef473ee4294c795a1a32e3132bc6b90fa10e820300581c4ee98623920698b77c1c7f77288cbdac5f9011ff8970b1f507567d0da10e820300581c514e81afb082fce01678809eebd90eda4f7918354ec7d0433ad16274a10e820300581c581e23030b6038bae716e5d64b9e053db10541b12e6b0b4eff485454a10e820300581ce5f27655371b54aed91cc916b2569060978be80056768fee2cc5ce1ba10e820300186582a1008182582028364596385174f5eabc763031b8d54b18ed5d06967ff44b3abbdbaca9cb58a75840de49197fed8dd13716c88e68452fb314d418a24fee9cc194308bd47b057d161ae40cd8f49bf6b378e7343ee5d3a7b9bdb1f2e9efeef896adaa9eb7373fbb8502a1008882582032a954b521c0b19514408965831ef6839637de7a1a6168bcf8455c504ba93b9c5840ab2d59239499807e25dc8025940a70cb890a52e8f47f35004cfec623036ca9f5c3e925b32bd23a7d1d044cef915913e853dbb57438f9c92a5d5f9581caa67d098258207ec249d890d0aaf9a81207960c163ae2d6ac5e715ca6b96d5860e50d9f2b2b2a5840f2d8031ac5d79777076dd1176cb7ed91690fcfb6be498320e5de9afbf6ea8e8ced23bff69230d050523a4a7e03c2b0599e18e93b31959063249fb50274a02a068258204f4d7523e41e058a6cbdefb5538654ffc2a53416a7f5bb99f7eac699d42d5c1f5840c5844b849865fed81f67842a4697c3090cf4ecb50510f1e6b379b7c63b78417ca28ea653c016d2e733877e1605e8a1712c42404ca0686f67455c620431d54b07825820e764b0340d7b353f5f745891033774e4beab6aa1458a54ff29a1324c05bb9876584026c35f8ec2102ec8fcc3bd0a1a0760486952e147f44236a35c7d818a7024590e1395f097a0d046085ded24ec8c585008d3ffc0321ad040649ce08eb33614760e82582073ae41eca2be37fc15c55a50d668c8647e10bf222172c2d58abfa6e9310e596258402c3f197360294781841f0669822b0449515a5e0b77b23185652a1b0ea8354537b3e9335577a87fa19e9fe47f1039fa286aaa11859d631f3ff74564c6da14c806825820234fb2b8530114b461c6ca8242c8b86a226c95c4c27479ca850d1aea4a52d2985840ba751817e70695a041a5f455c08947fa4e3d6ffc332adeb25691fac4927bbaafd4b3f5f9855946ad9681083aec277766c7f90da7543e912f46aeae07fdd5b90a825820dfb615a61568d6867f45a85c32227f27025180d738a8a3d7fd3c929f624d72395840cc1f728cce6ce2fec21d2648011c14d244c35ba3cbd553593655f6f07d86b8bdf103d52b61143bc1701319517d4a24b778c02e983e02a0f3fd0cd558d472f009825820e5bc21a83616bcccfe343ec36b9dc4c06c90e913df1d8a0b046008651f42caa95840f85bc5e753beed04b3f9072da7a6adadcdb87769528c59e16162e86782b6ce11feacbd5de97e352121e9509a809f613d5bcebf7413fd55f89776c5606e4a9408a100a119534da261638158220a201f79b4d15fd971297a842ac6a4e953b82886df66c0d9723f5870e5725da6380b617601").unwrap(); - let _block = Block::from_bytes(bytes).unwrap(); - } - - #[test] - fn tx_output_ser_type() { - let array_tx_output = TransactionOutput::from_hex("8258390000efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee16400efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee1641a000f4240").unwrap(); - let map_tx_output = TransactionOutput::from_hex("a30058390000efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee16400efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee164011a00039447028201d81844d9052380").unwrap(); - assert_eq!( - array_tx_output.serialization_format().unwrap(), - CborContainerType::Array - ); - assert_eq!( - map_tx_output.serialization_format().unwrap(), - CborContainerType::Map - ); - } -} +} \ No newline at end of file diff --git a/rust/src/serialization/metadata.rs b/rust/src/serialization/metadata.rs index d6ae1d72..c723d8e4 100644 --- a/rust/src/serialization/metadata.rs +++ b/rust/src/serialization/metadata.rs @@ -260,18 +260,14 @@ impl cbor_event::se::Serialize for AuxiliaryData { } if let Some(plutus_scripts) = &self.plutus_scripts { serializer.write_unsigned_integer(2)?; - plutus_scripts - .by_version(&Language::new_plutus_v1()) - .serialize(serializer)?; + plutus_scripts.serialize_by_version(&Language::new_plutus_v1(), serializer)?; if has_plutus_v2 { - let v2 = plutus_scripts.by_version(&Language::new_plutus_v2()); serializer.write_unsigned_integer(3)?; - v2.serialize(serializer)?; + plutus_scripts.serialize_by_version(&Language::new_plutus_v2(), serializer)?; } if has_plutus_v3 { - let v3 = plutus_scripts.by_version(&Language::new_plutus_v3()); serializer.write_unsigned_integer(4)?; - v3.serialize(serializer)?; + plutus_scripts.serialize_by_version(&Language::new_plutus_v3(), serializer)?; } } Ok(serializer) @@ -360,8 +356,7 @@ impl Deserialize for AuxiliaryData { plutus_scripts_v2 = Some( (|| -> Result<_, DeserializeError> { read_len.read_elems(1)?; - Ok(PlutusScripts::deserialize(raw)? - .map_as_version(&Language::new_plutus_v2())) + Ok(PlutusScripts::deserialize_with_version(raw, &Language::new_plutus_v2())?) })() .map_err(|e| e.annotate("plutus_scripts_v2"))?, ); @@ -375,8 +370,7 @@ impl Deserialize for AuxiliaryData { plutus_scripts_v3 = Some( (|| -> Result<_, DeserializeError> { read_len.read_elems(1)?; - Ok(PlutusScripts::deserialize(raw)? - .map_as_version(&Language::new_plutus_v3())) + Ok(PlutusScripts::deserialize_with_version(raw, &Language::new_plutus_v3())?) })() .map_err(|e| e.annotate("plutus_scripts_v3"))?, ); diff --git a/rust/src/serialization/native_scripts.rs b/rust/src/serialization/native_scripts.rs index a6aa8bdb..c9d7d17d 100644 --- a/rust/src/serialization/native_scripts.rs +++ b/rust/src/serialization/native_scripts.rs @@ -1,4 +1,5 @@ use crate::*; +use crate::serialization::utils::skip_set_tag; impl cbor_event::se::Serialize for NativeScripts { fn serialize<'se, W: Write>( @@ -13,8 +14,33 @@ impl cbor_event::se::Serialize for NativeScripts { } } +impl NativeScripts { + fn serialize_as_set<'se, W: Write>( + &self, + need_deduplication: bool, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + //TODO: uncomment this line when we conway ero will come + //serializer.write_tag(258)?; + if need_deduplication { + let view = self.deduplicated_view(); + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in view { + element.serialize(serializer)?; + } + } else { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + } + Ok(serializer) + } +} + impl Deserialize for NativeScripts { fn deserialize(raw: &mut Deserializer) -> Result { + skip_set_tag(raw)?; let mut arr = Vec::new(); (|| -> Result<_, DeserializeError> { let len = raw.array()?; diff --git a/rust/src/serialization/plutus/plutus_data.rs b/rust/src/serialization/plutus/plutus_data.rs index aaad5c9a..49af9391 100644 --- a/rust/src/serialization/plutus/plutus_data.rs +++ b/rust/src/serialization/plutus/plutus_data.rs @@ -240,8 +240,42 @@ impl cbor_event::se::Serialize for PlutusList { } } +impl PlutusList { + pub(crate) fn serialize_as_set<'se, W: Write>( + &self, + need_deduplication: bool, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + //TODO: uncomment this line when we conway ero will come + //serializer.write_tag(258)?; + let use_definite_encoding = match self.definite_encoding { + Some(definite) => definite, + None => self.elems.is_empty(), + }; + if use_definite_encoding { + serializer.write_array(cbor_event::Len::Len(self.elems.len() as u64))?; + } else { + serializer.write_array(cbor_event::Len::Indefinite)?; + } + if need_deduplication { + for element in self.deduplicated_view() { + element.serialize(serializer)?; + } + } else { + for element in &self.elems { + element.serialize(serializer)?; + } + } + if !use_definite_encoding { + serializer.write_special(cbor_event::Special::Break)?; + } + Ok(serializer) + } +} + impl Deserialize for PlutusList { fn deserialize(raw: &mut Deserializer) -> Result { + skip_set_tag(raw)?; let mut arr = Vec::new(); let len = (|| -> Result<_, DeserializeError> { let len = raw.array()?; diff --git a/rust/src/serialization/plutus/plutus_script.rs b/rust/src/serialization/plutus/plutus_script.rs index e483209d..b2ece92c 100644 --- a/rust/src/serialization/plutus/plutus_script.rs +++ b/rust/src/serialization/plutus/plutus_script.rs @@ -14,4 +14,10 @@ impl Deserialize for PlutusScript { fn deserialize(raw: &mut Deserializer) -> Result { Ok(Self::new(raw.bytes()?)) } +} + +impl PlutusScript { + pub(crate) fn deserialize_with_version(raw: &mut Deserializer, version: &Language) -> Result { + Ok(Self::new_with_version(raw.bytes()?, version)) + } } \ No newline at end of file diff --git a/rust/src/serialization/plutus/plutus_scripts.rs b/rust/src/serialization/plutus/plutus_scripts.rs index f73b1049..a7b77bb4 100644 --- a/rust/src/serialization/plutus/plutus_scripts.rs +++ b/rust/src/serialization/plutus/plutus_scripts.rs @@ -6,8 +6,6 @@ impl cbor_event::se::Serialize for PlutusScripts { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - //TODO: uncomment this line when we conway ero will come - //serializer.write_tag(258)?; serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; for element in &self.0 { element.serialize(serializer)?; @@ -16,6 +14,41 @@ impl cbor_event::se::Serialize for PlutusScripts { } } +impl PlutusScripts { + pub(crate) fn serialize_by_version<'se, W: Write>( + &self, + version: &Language, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + let view = self.view(version); + serializer.write_array(cbor_event::Len::Len(view.len() as u64))?; + for element in view { + element.serialize(serializer)?; + } + Ok(serializer) + } + + pub(crate) fn serialize_as_set<'se, W: Write>( + &self, + need_debuplication: bool, + version: &Language, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + //TODO: uncomment this line when we conway ero will come + //serializer.write_tag(258)?; + let view = match need_debuplication { + true => self.deduplicated_view(Some(version)), + false => self.view(version), + }; + serializer.write_array(cbor_event::Len::Len(view.len() as u64))?; + for element in view { + element.serialize(serializer)?; + } + Ok(serializer) + } + +} + impl Deserialize for PlutusScripts { fn deserialize(raw: &mut Deserializer) -> Result { let mut arr = Vec::new(); @@ -37,4 +70,27 @@ impl Deserialize for PlutusScripts { .map_err(|e| e.annotate("PlutusScripts"))?; Ok(Self(arr)) } +} + +impl PlutusScripts { + pub(crate) fn deserialize_with_version(raw: &mut Deserializer, version: &Language) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + skip_set_tag(raw)?; + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if raw.cbor_type()? == CBORType::Special { + assert_eq!(raw.special()?, CBORSpecial::Break); + break; + } + arr.push(PlutusScript::deserialize_with_version(raw, version)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("PlutusScripts"))?; + Ok(Self(arr)) + } } \ No newline at end of file diff --git a/rust/src/serialization/witnesses/transaction_witnesses_set.rs b/rust/src/serialization/witnesses/transaction_witnesses_set.rs index ebff78c2..02ba02de 100644 --- a/rust/src/serialization/witnesses/transaction_witnesses_set.rs +++ b/rust/src/serialization/witnesses/transaction_witnesses_set.rs @@ -31,7 +31,7 @@ impl cbor_event::se::Serialize for TransactionWitnessSet { + plutus_added_length, ))?; if let Some(field) = &self.vkeys { - if field.0.len() > 0 { + if field.len() > 0 { serializer.write_unsigned_integer(0)?; field.serialize(serializer)?; } @@ -49,21 +49,15 @@ impl cbor_event::se::Serialize for TransactionWitnessSet { if let Some(plutus_scripts) = &self.plutus_scripts { if has_plutus_v1 { serializer.write_unsigned_integer(3)?; - plutus_scripts - .by_version(&Language::new_plutus_v1()) - .serialize(serializer)?; + plutus_scripts.serialize_by_version(&Language::new_plutus_v1(), serializer)?; } if has_plutus_v2 { serializer.write_unsigned_integer(6)?; - plutus_scripts - .by_version(&Language::new_plutus_v2()) - .serialize(serializer)?; + plutus_scripts.serialize_by_version(&Language::new_plutus_v2(), serializer)?; } if has_plutus_v3 { serializer.write_unsigned_integer(7)?; - plutus_scripts - .by_version(&Language::new_plutus_v3()) - .serialize(serializer)?; + plutus_scripts.serialize_by_version(&Language::new_plutus_v3(), serializer)?; } } if let Some(field) = &self.plutus_data { @@ -177,8 +171,7 @@ impl Deserialize for TransactionWitnessSet { plutus_scripts_v2 = Some( (|| -> Result<_, DeserializeError> { read_len.read_elems(1)?; - Ok(PlutusScripts::deserialize(raw)? - .map_as_version(&Language::new_plutus_v2())) + Ok(PlutusScripts::deserialize_with_version(raw, &Language::new_plutus_v2())?) })() .map_err(|e| e.annotate("plutus_scripts_v2"))?, ); @@ -190,8 +183,7 @@ impl Deserialize for TransactionWitnessSet { plutus_scripts_v3 = Some( (|| -> Result<_, DeserializeError> { read_len.read_elems(1)?; - Ok(PlutusScripts::deserialize(raw)? - .map_as_version(&Language::new_plutus_v3())) + Ok(PlutusScripts::deserialize_with_version(raw, &Language::new_plutus_v3())?) })() .map_err(|e| e.annotate("plutus_scripts_v3"))?, ); diff --git a/rust/src/serialization/witnesses/vkeywitnesses.rs b/rust/src/serialization/witnesses/vkeywitnesses.rs index 6b39805c..ca76dd29 100644 --- a/rust/src/serialization/witnesses/vkeywitnesses.rs +++ b/rust/src/serialization/witnesses/vkeywitnesses.rs @@ -12,8 +12,8 @@ impl cbor_event::se::Serialize for Vkeywitnesses { ) -> cbor_event::Result<&'se mut Serializer> { //TODO: uncomment this line when we conway ero will come //serializer.write_tag(258)?; - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { + serializer.write_array(cbor_event::Len::Len(self.witnesses.len() as u64))?; + for element in &self.witnesses { element.serialize(serializer)?; } Ok(serializer) @@ -22,23 +22,25 @@ impl cbor_event::se::Serialize for Vkeywitnesses { impl Deserialize for Vkeywitnesses { fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); + let mut wits = Vkeywitnesses::new(); + let mut counter = 0u64; (|| -> Result<_, DeserializeError> { skip_set_tag(raw)?; let len = raw.array()?; while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Len(n) => counter < n, cbor_event::Len::Indefinite => true, } { if raw.cbor_type()? == cbor_event::Type::Special { assert_eq!(raw.special()?, cbor_event::Special::Break); break; } - arr.push(Vkeywitness::deserialize(raw)?); + wits.add_move(Vkeywitness::deserialize(raw)?); + counter += 1; } Ok(()) })() .map_err(|e| e.annotate("Vkeywitnesses"))?; - Ok(Self(arr)) + Ok(wits) } } \ No newline at end of file diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index 46a5de47..ea411849 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -3,7 +3,12 @@ use crate::fakes::{ fake_script_hash, fake_tx_hash, fake_tx_input, fake_tx_input2, fake_value, fake_value2, }; use crate::tests::helpers::harden; -use crate::tests::mock_objects::{byron_address, create_change_address, create_default_tx_builder, create_linear_fee, create_reallistic_tx_builder, create_rich_tx_builder, create_tx_builder_with_amount, create_tx_builder_with_fee, create_tx_builder_with_fee_and_pure_change, create_tx_builder_with_fee_and_val_size, create_tx_builder_with_key_deposit}; +use crate::tests::mock_objects::{ + byron_address, create_change_address, create_default_tx_builder, create_linear_fee, + create_reallistic_tx_builder, create_rich_tx_builder, create_tx_builder_with_amount, + create_tx_builder_with_fee, create_tx_builder_with_fee_and_pure_change, + create_tx_builder_with_fee_and_val_size, create_tx_builder_with_key_deposit, root_key_15, +}; use crate::*; use fees::*; @@ -15,15 +20,6 @@ fn genesis_id() -> TransactionHash { TransactionHash::from([0u8; TransactionHash::BYTE_COUNT]) } -fn root_key_15() -> Bip32PrivateKey { - // art forum devote street sure rather head chuckle guard poverty release quote oak craft enemy - let entropy = [ - 0x0c, 0xcb, 0x74, 0xf3, 0x6b, 0x7d, 0xa1, 0x64, 0x9a, 0x81, 0x44, 0x67, 0x55, 0x22, 0xd4, - 0xd8, 0x09, 0x7c, 0x64, 0x12, - ]; - Bip32PrivateKey::from_bip39_entropy(&entropy, &[]) -} - #[test] fn check_fake_private_key() { let fpk = fake_private_key(); @@ -561,8 +557,11 @@ fn build_tx_with_inputs() { assert_eq!( tx_builder .fee_for_input( - &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) - .to_address(), + &EnterpriseAddress::new( + NetworkInfo::testnet_preprod().network_id(), + &spend_cred + ) + .to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(1_000_000)) ) @@ -571,7 +570,8 @@ fn build_tx_with_inputs() { "69500" ); tx_builder.add_regular_input( - &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(), + &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) + .to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(1_000_000)), ); @@ -893,7 +893,8 @@ fn build_tx_with_mint_all_sent() { // Input with 150 coins tx_builder.add_regular_input( - &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(), + &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) + .to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(500)), ); @@ -981,7 +982,8 @@ fn build_tx_with_mint_in_change() { // Input with 600 coins tx_builder.add_regular_input( - &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(), + &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) + .to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(600)), ); @@ -1090,13 +1092,15 @@ fn change_with_input_and_mint_not_enough_ada() { // Input with 600 coins tx_builder.add_regular_input( - &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(), + &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) + .to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(600)), ); tx_builder.add_regular_input( - &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(), + &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) + .to_address(), &TransactionInput::new(&genesis_id(), 1), &Value::new_with_assets(&to_bignum(1), &mass_input), ); @@ -1186,13 +1190,15 @@ fn change_with_input_and_mint_not_enough_assets() { // Input with 600 coins tx_builder.add_regular_input( - &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(), + &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) + .to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&to_bignum(100000)), ); tx_builder.add_regular_input( - &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(), + &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) + .to_address(), &TransactionInput::new(&genesis_id(), 1), &Value::new_with_assets(&to_bignum(1), &mass_input), ); @@ -3101,7 +3107,11 @@ fn assert_mint_asset(mint: &Mint, policy_id: &PolicyID) { let result_asset = mint.get(&policy_id).unwrap(); assert_eq!(result_asset.len(), 1); assert_eq!( - result_asset.get(0).unwrap().get(&create_asset_name()).unwrap(), + result_asset + .get(0) + .unwrap() + .get(&create_asset_name()) + .unwrap(), Int::new_i32(1234) ); } @@ -3781,7 +3791,10 @@ fn test_add_native_script_input() { &Value::new(&to_bignum(1_000_000)), ); - assert_eq!(tx_builder.inputs.get_native_input_scripts().unwrap().len(), 2); + assert_eq!( + tx_builder.inputs.get_native_input_scripts().unwrap().len(), + 2 + ); } fn unsafe_tx_len(b: &TransactionBuilder) -> usize { @@ -3846,8 +3859,8 @@ fn test_adding_plutus_script_input() { fn test_adding_plutus_script_witnesses() { let mut tx_builder = create_reallistic_tx_builder(); tx_builder.set_fee(&to_bignum(42)); - let (script1, _ ) = plutus_script_and_hash(0); - let (script2, _ ) = plutus_script_and_hash(1); + let (script1, _) = plutus_script_and_hash(0); + let (script2, _) = plutus_script_and_hash(1); let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); let redeemer1 = Redeemer::new( @@ -3896,11 +3909,13 @@ fn test_adding_plutus_script_witnesses() { fn create_collateral() -> TxInputsBuilder { let mut collateral_builder = TxInputsBuilder::new(); - collateral_builder.add_regular_input( - &byron_address(), - &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), - ).unwrap(); + collateral_builder + .add_regular_input( + &byron_address(), + &TransactionInput::new(&genesis_id(), 0), + &Value::new(&to_bignum(1_000_000)), + ) + .unwrap(); collateral_builder } @@ -4105,7 +4120,6 @@ fn test_native_and_plutus_scripts_together() { &Value::new(&to_bignum(1_000_000)), ); - tx_builder .calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()) .unwrap(); @@ -4491,7 +4505,9 @@ fn test_required_signers_are_added_to_the_witness_estimate() { ); assert_eq!( - count_fake_witnesses_with_required_signers(&Ed25519KeyHashes::from_vec(vec![fake_key_hash(1)]),), + count_fake_witnesses_with_required_signers(&Ed25519KeyHashes::from_vec(vec![ + fake_key_hash(1) + ]),), 2 ); @@ -6031,14 +6047,20 @@ fn build_tx_with_certs_withdrawals_plutus_script_address() { .unwrap(); withdrawals .add_with_plutus_witness( - &RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &withdraw_script_cred1), + &RewardAddress::new( + NetworkInfo::testnet_preprod().network_id(), + &withdraw_script_cred1, + ), &Coin::from(2u32), &withdraw_witness1, ) .unwrap(); withdrawals .add_with_plutus_witness( - &RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &withdraw_script_cred2), + &RewardAddress::new( + NetworkInfo::testnet_preprod().network_id(), + &withdraw_script_cred2, + ), &Coin::from(3u32), &withdraw_witness2, ) @@ -6175,9 +6197,14 @@ fn current_treasure_value_test() { assert_eq!(builder.get_current_treasury_value(), None); builder.set_current_treasury_value(&treasure_value).unwrap(); - builder.add_change_if_needed(&create_change_address()).unwrap(); + builder + .add_change_if_needed(&create_change_address()) + .unwrap(); - assert_eq!(builder.get_current_treasury_value().unwrap(), treasure_value); + assert_eq!( + builder.get_current_treasury_value().unwrap(), + treasure_value + ); let tx = builder.build_tx().unwrap(); assert_eq!(tx.body().outputs().len(), 1); @@ -6208,7 +6235,9 @@ fn donation_test() { assert_eq!(builder.get_donation(), None); builder.set_donation(&donation); - builder.add_change_if_needed(&create_change_address()).unwrap(); + builder + .add_change_if_needed(&create_change_address()) + .unwrap(); assert_eq!(builder.get_donation().unwrap(), donation); diff --git a/rust/src/tests/builders/voting_builder.rs b/rust/src/tests/builders/voting_builder.rs index 49883ab7..50226a11 100644 --- a/rust/src/tests/builders/voting_builder.rs +++ b/rust/src/tests/builders/voting_builder.rs @@ -235,7 +235,7 @@ fn voting_builder_plutus_ref_witness() { let tx = tx_builder.build_tx().unwrap(); let tx_witnesses = tx.witness_set(); - assert_eq!(tx_witnesses.plutus_scripts().unwrap().len(), 0); + assert_eq!(tx_witnesses.plutus_scripts().map_or(0, |x| x.len()), 0); let tx_redeemers = tx_witnesses.redeemers().unwrap(); assert_eq!(tx_redeemers.len(), 1); diff --git a/rust/src/tests/builders/voting_proposal_builder.rs b/rust/src/tests/builders/voting_proposal_builder.rs index c26cd47c..7cad6c0c 100644 --- a/rust/src/tests/builders/voting_proposal_builder.rs +++ b/rust/src/tests/builders/voting_proposal_builder.rs @@ -379,8 +379,7 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { assert_eq!(total_out, Coin::from(initial_amount)); let tx_witnesses = tx.witness_set(); - let tx_script = tx_witnesses.plutus_scripts().unwrap(); - assert_eq!(tx_script.len(), 0); + assert_eq!(tx_witnesses.plutus_scripts().map_or(0, |x| x.len()), 0); let tx_redeemers = tx_witnesses.redeemers().unwrap(); assert_eq!(tx_redeemers.len(), 1); diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index e0a5b0ce..2430ff33 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -1,4 +1,7 @@ use crate::*; +use crate::fakes::fake_vkey_witness; +use crate::tests::helpers::harden; +use crate::tests::mock_objects::{create_plutus_script, create_reallistic_tx_builder}; #[test] fn native_script_hash() { @@ -288,3 +291,116 @@ fn protocol_params_update_cbor_roundtrip() { assert_eq!(dencoded, orig_ppu); assert_eq!(dencoded.to_bytes(), orig_ppu.to_bytes()); } + +#[test] +fn witnesses_deduplication_test(){ + let spend = tests::mock_objects::root_key_15() + .derive(harden(1854)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(0) + .derive(0) + .to_public(); + let stake = tests::mock_objects::root_key_15() + .derive(harden(1854)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + + let spending_hash = spend.to_raw_key().hash(); + + let mut native_scripts_1 = NativeScript::new_script_pubkey(&ScriptPubkey::new( + &spending_hash, + )); + + let mut internal_scripts = NativeScripts::new(); + internal_scripts.add(&native_scripts_1); + let native_scripts_2 = NativeScript::new_script_n_of_k(&ScriptNOfK::new( + 1, + &internal_scripts, + )); + + + let native_scripts_1_1 = native_scripts_1.clone(); + + let mut native_scripts = NativeScripts::new(); + native_scripts.add(&native_scripts_1); + native_scripts.add(&native_scripts_2); + native_scripts.add(&native_scripts_1_1); + + + // recall: this includes keys for input, certs and withdrawals + let vkey_witness_1 = fake_vkey_witness(1); + let vkey_witness_1_1 = fake_vkey_witness(1); + let vkey_witness_2 = fake_vkey_witness(2); + + let mut vkey_witnesses = Vkeywitnesses::new(); + vkey_witnesses.add(&vkey_witness_1); + vkey_witnesses.add(&vkey_witness_1_1); + vkey_witnesses.add(&vkey_witness_2); + + let plutus_v1_1 = create_plutus_script(1, &Language::new_plutus_v1()); + let plutus_v1_1_1 = create_plutus_script(1, &Language::new_plutus_v1()); + let plutus_v1_2 = create_plutus_script(2, &Language::new_plutus_v1()); + + let plutus_v2_1 = create_plutus_script(1, &Language::new_plutus_v2()); + let plutus_v2_1_1 = create_plutus_script(1, &Language::new_plutus_v2()); + let plutus_v2_2 = create_plutus_script(2, &Language::new_plutus_v2()); + + let plutus_v3_1 = create_plutus_script(1, &Language::new_plutus_v3()); + let plutus_v3_1_1 = create_plutus_script(1, &Language::new_plutus_v3()); + let plutus_v3_2 = create_plutus_script(2, &Language::new_plutus_v3()); + + let mut plutus_scripts = PlutusScripts::new(); + plutus_scripts.add(&plutus_v1_1); + plutus_scripts.add(&plutus_v1_1_1); + plutus_scripts.add(&plutus_v1_2); + plutus_scripts.add(&plutus_v2_1); + plutus_scripts.add(&plutus_v2_1_1); + plutus_scripts.add(&plutus_v2_2); + plutus_scripts.add(&plutus_v3_1); + plutus_scripts.add(&plutus_v3_1_1); + plutus_scripts.add(&plutus_v3_2); + + let mut datums = PlutusList::new(); + + let datum_1 = PlutusData::new_integer(&BigInt::from(1)); + let datum_1_1 = PlutusData::new_integer(&BigInt::from(1)); + let datum_2 = PlutusData::new_integer(&BigInt::from(2)); + datums.add(&datum_1); + datums.add(&datum_1_1); + datums.add(&datum_2); + + let mut tx_wits_set = TransactionWitnessSet::new(); + tx_wits_set.set_vkeys(&vkey_witnesses); + tx_wits_set.set_native_scripts(&native_scripts); + tx_wits_set.set_plutus_scripts(&plutus_scripts); + tx_wits_set.set_plutus_data(&datums); + + let roundtrip_tx_wits_set = TransactionWitnessSet::from_bytes(tx_wits_set.to_bytes()).unwrap(); + let roundtrip_vkeys = roundtrip_tx_wits_set.vkeys().unwrap(); + assert_eq!(roundtrip_vkeys.len(), 2); + assert_eq!(roundtrip_vkeys.get(0), vkey_witness_1); + assert_eq!(roundtrip_vkeys.get(1), vkey_witness_2); + + let roundtrip_native_scripts = roundtrip_tx_wits_set.native_scripts().unwrap(); + assert_eq!(roundtrip_native_scripts.len(), 2); + assert_eq!(roundtrip_native_scripts.get(0), native_scripts_1); + assert_eq!(roundtrip_native_scripts.get(1), native_scripts_2); + + let roundtrip_plutus_scripts = roundtrip_tx_wits_set.plutus_scripts().unwrap(); + assert_eq!(roundtrip_plutus_scripts.len(), 6); + assert_eq!(roundtrip_plutus_scripts.get(0), plutus_v1_1); + assert_eq!(roundtrip_plutus_scripts.get(1), plutus_v1_2); + assert_eq!(roundtrip_plutus_scripts.get(2), plutus_v2_1); + assert_eq!(roundtrip_plutus_scripts.get(3), plutus_v2_2); + assert_eq!(roundtrip_plutus_scripts.get(4), plutus_v3_1); + assert_eq!(roundtrip_plutus_scripts.get(5), plutus_v3_2); + + let roundtrip_plutus_data = roundtrip_tx_wits_set.plutus_data().unwrap(); + assert_eq!(roundtrip_plutus_data.len(), 2); + assert_eq!(roundtrip_plutus_data.get(0), datum_1); + assert_eq!(roundtrip_plutus_data.get(1), datum_2); +} diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/mock_objects.rs index fe85ea84..dd66b636 100644 --- a/rust/src/tests/mock_objects.rs +++ b/rust/src/tests/mock_objects.rs @@ -10,6 +10,15 @@ const MAX_TX_SIZE: u32 = 8000; // might be out of date but suffices for our test // this is what is used in mainnet static COINS_PER_UTXO_BYTE: u64 = 34_482 / 8; +pub(crate) fn root_key_15() -> Bip32PrivateKey { + // art forum devote street sure rather head chuckle guard poverty release quote oak craft enemy + let entropy = [ + 0x0c, 0xcb, 0x74, 0xf3, 0x6b, 0x7d, 0xa1, 0x64, 0x9a, 0x81, 0x44, 0x67, 0x55, 0x22, 0xd4, + 0xd8, 0x09, 0x7c, 0x64, 0x12, + ]; + Bip32PrivateKey::from_bip39_entropy(&entropy, &[]) +} + pub(crate) fn root_key() -> Bip32PrivateKey { // art forum devote street sure rather head chuckle guard poverty release quote oak craft enemy let entropy = [ @@ -358,4 +367,4 @@ pub(crate) fn create_plutus_script(x: u8, lang: &Language) -> PlutusScript { let pos = bytes.len() - 1; bytes[pos] = x; PlutusScript::from_bytes_with_version(bytes, lang).unwrap() -} +} \ No newline at end of file diff --git a/rust/src/tests/serialization/general.rs b/rust/src/tests/serialization/general.rs new file mode 100644 index 00000000..3b9e6c05 --- /dev/null +++ b/rust/src/tests/serialization/general.rs @@ -0,0 +1,636 @@ +use crate::{ + to_bignum, Address, BigInt, BigNum, Block, BlockHash, CborContainerType, Coin, Credential, + DataHash, ExUnits, HeaderBody, HeaderLeaderCertEnum, Int, KESVKey, MIRPot, + MIRToStakeCredentials, MoveInstantaneousReward, NativeScript, OperationalCert, PlutusData, + PlutusList, PlutusScript, PlutusScripts, ProtocolVersion, Redeemer, RedeemerTag, Redeemers, + ScriptHash, ScriptRef, TimelockStart, TransactionBody, TransactionInputs, TransactionOutput, + TransactionOutputs, TransactionWitnessSet, VRFCert, VRFVKey, Value, Vkeywitness, Vkeywitnesses, +}; + +use crate::fakes::{ + fake_base_address, fake_bytes_32, fake_data_hash, fake_signature, fake_tx_input, + fake_tx_output, fake_value, fake_value2, fake_vkey, +}; + +#[test] +fn tx_output_deser_lagacy() { + let mut txos = TransactionOutputs::new(); + let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); + let val = &Value::new(&BigNum::from_str("435464757").unwrap()); + let txo = TransactionOutput { + address: addr.clone(), + amount: val.clone(), + plutus_data: None, + script_ref: None, + serialization_format: None, + }; + let mut txo_dh = txo.clone(); + txo_dh.set_data_hash(&DataHash::from([47u8; DataHash::BYTE_COUNT])); + txos.add(&txo); + txos.add(&txo_dh); + txos.add(&txo_dh); + txos.add(&txo); + txos.add(&txo); + txos.add(&txo_dh); + let bytes = txos.to_bytes(); + let txos_deser = TransactionOutputs::from_bytes(bytes.clone()).unwrap(); + let bytes_deser = txos_deser.to_bytes(); + assert_eq!(bytes, bytes_deser); +} + +#[test] +fn tx_output_deser_post_alonzo_with_plutus_script_and_datum() { + let mut txos = TransactionOutputs::new(); + let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); + let val = &Value::new(&BigNum::from_str("435464757").unwrap()); + let txo = TransactionOutput { + address: addr.clone(), + amount: val.clone(), + plutus_data: None, + script_ref: None, + serialization_format: None, + }; + let mut txo_dh = txo.clone(); + txo_dh.set_plutus_data(&PlutusData::new_bytes(fake_bytes_32(11))); + txo_dh.set_script_ref(&ScriptRef::new_plutus_script(&PlutusScript::new( + [61u8; 29].to_vec(), + ))); + txos.add(&txo); + txos.add(&txo_dh); + txos.add(&txo_dh); + txos.add(&txo); + txos.add(&txo); + txos.add(&txo_dh); + let bytes = txos.to_bytes(); + let txos_deser = TransactionOutputs::from_bytes(bytes.clone()).unwrap(); + let bytes_deser = txos_deser.to_bytes(); + assert_eq!(bytes, bytes_deser); +} + +#[test] +fn tx_output_deser_post_alonzo_with_plutus_script() { + let mut txos = TransactionOutputs::new(); + let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); + let val = &Value::new(&BigNum::from_str("435464757").unwrap()); + let txo = TransactionOutput { + address: addr.clone(), + amount: val.clone(), + plutus_data: None, + script_ref: None, + serialization_format: None, + }; + let mut txo_dh = txo.clone(); + txo_dh.set_script_ref(&ScriptRef::new_plutus_script(&PlutusScript::new( + [61u8; 29].to_vec(), + ))); + txos.add(&txo); + txos.add(&txo_dh); + txos.add(&txo_dh); + txos.add(&txo); + txos.add(&txo); + txos.add(&txo_dh); + let bytes = txos.to_bytes(); + let txos_deser = TransactionOutputs::from_bytes(bytes.clone()).unwrap(); + let bytes_deser = txos_deser.to_bytes(); + assert_eq!(bytes, bytes_deser); +} + +#[test] +fn tx_output_deser_post_alonzo_with_datum() { + let mut txos = TransactionOutputs::new(); + let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); + let val = &Value::new(&BigNum::from_str("435464757").unwrap()); + let txo = TransactionOutput { + address: addr.clone(), + amount: val.clone(), + plutus_data: None, + script_ref: None, + serialization_format: None, + }; + let mut txo_dh = txo.clone(); + txo_dh.set_plutus_data(&PlutusData::new_bytes(fake_bytes_32(11))); + txos.add(&txo); + txos.add(&txo_dh); + txos.add(&txo_dh); + txos.add(&txo); + txos.add(&txo); + txos.add(&txo_dh); + let bytes = txos.to_bytes(); + let txos_deser = TransactionOutputs::from_bytes(bytes.clone()).unwrap(); + let bytes_deser = txos_deser.to_bytes(); + assert_eq!(bytes, bytes_deser); +} + +#[test] +fn tx_output_deser_post_alonzo_with_native_script_and_datum() { + let mut txos = TransactionOutputs::new(); + let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); + let val = &Value::new(&BigNum::from_str("435464757").unwrap()); + let txo = TransactionOutput { + address: addr.clone(), + amount: val.clone(), + plutus_data: None, + script_ref: None, + serialization_format: None, + }; + let mut txo_dh = txo.clone(); + let native_script = NativeScript::new_timelock_start(&TimelockStart::new(20)); + txo_dh.set_script_ref(&ScriptRef::new_native_script(&native_script)); + txo_dh.set_plutus_data(&PlutusData::new_bytes(fake_bytes_32(11))); + txos.add(&txo); + txos.add(&txo_dh); + txos.add(&txo_dh); + txos.add(&txo); + txos.add(&txo); + txos.add(&txo_dh); + let bytes = txos.to_bytes(); + let txos_deser = TransactionOutputs::from_bytes(bytes.clone()).unwrap(); + let bytes_deser = txos_deser.to_bytes(); + assert_eq!(bytes, bytes_deser); +} + +#[test] +fn tx_output_deser_post_alonzo_with_native_script() { + let mut txos = TransactionOutputs::new(); + let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); + let val = &Value::new(&BigNum::from_str("435464757").unwrap()); + let txo = TransactionOutput { + address: addr.clone(), + amount: val.clone(), + plutus_data: None, + script_ref: None, + serialization_format: None, + }; + let mut txo_dh = txo.clone(); + let native_script = NativeScript::new_timelock_start(&TimelockStart::new(20)); + txo_dh.set_script_ref(&ScriptRef::new_native_script(&native_script)); + txos.add(&txo); + txos.add(&txo_dh); + txos.add(&txo_dh); + txos.add(&txo); + txos.add(&txo); + txos.add(&txo_dh); + let bytes = txos.to_bytes(); + let txos_deser = TransactionOutputs::from_bytes(bytes.clone()).unwrap(); + let bytes_deser = txos_deser.to_bytes(); + assert_eq!(bytes, bytes_deser); +} + +#[test] +fn tx_output_deser_post_alonzo_with_native_script_and_data_hash() { + let mut txos = TransactionOutputs::new(); + let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); + let val = &Value::new(&BigNum::from_str("435464757").unwrap()); + let txo = TransactionOutput { + address: addr.clone(), + amount: val.clone(), + plutus_data: None, + script_ref: None, + serialization_format: None, + }; + let mut txo_dh = txo.clone(); + let native_script = NativeScript::new_timelock_start(&TimelockStart::new(20)); + let data_hash = DataHash::from_bytes(vec![ + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + ]) + .unwrap(); + txo_dh.set_data_hash(&data_hash); + txo_dh.set_script_ref(&ScriptRef::new_native_script(&native_script)); + txos.add(&txo); + txos.add(&txo_dh); + txos.add(&txo_dh); + txos.add(&txo); + txos.add(&txo); + txos.add(&txo_dh); + let bytes = txos.to_bytes(); + let txos_deser = TransactionOutputs::from_bytes(bytes.clone()).unwrap(); + let bytes_deser = txos_deser.to_bytes(); + assert_eq!(bytes, bytes_deser); +} + +#[test] +fn tx_output_deser_lagacy_json() { + let mut txos = TransactionOutputs::new(); + let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); + let val = &Value::new(&BigNum::from_str("435464757").unwrap()); + let txo = TransactionOutput { + address: addr.clone(), + amount: val.clone(), + plutus_data: None, + script_ref: None, + serialization_format: None, + }; + let mut txo_dh = txo.clone(); + txo_dh.set_data_hash(&DataHash::from([47u8; DataHash::BYTE_COUNT])); + txos.add(&txo); + txos.add(&txo_dh); + txos.add(&txo_dh); + txos.add(&txo); + txos.add(&txo); + txos.add(&txo_dh); + let json_txos = txos.to_json().unwrap(); + let deser_txos = TransactionOutputs::from_json(json_txos.as_str()).unwrap(); + + assert_eq!(deser_txos.to_bytes(), txos.to_bytes()); + assert_eq!(deser_txos.to_json().unwrap(), txos.to_json().unwrap()); +} + +#[test] +fn tx_output_deser_post_alonzo_with_plutus_script_and_datum_json() { + let mut txos = TransactionOutputs::new(); + let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); + let val = &Value::new(&BigNum::from_str("435464757").unwrap()); + let txo = TransactionOutput { + address: addr.clone(), + amount: val.clone(), + plutus_data: None, + script_ref: None, + serialization_format: None, + }; + let mut txo_dh = txo.clone(); + txo_dh.set_plutus_data(&PlutusData::new_bytes(fake_bytes_32(11))); + txo_dh.set_script_ref(&ScriptRef::new_plutus_script(&PlutusScript::new( + [61u8; 29].to_vec(), + ))); + txos.add(&txo); + txos.add(&txo_dh); + txos.add(&txo_dh); + txos.add(&txo); + txos.add(&txo); + txos.add(&txo_dh); + let json_txos = txos.to_json().unwrap(); + let deser_txos = TransactionOutputs::from_json(json_txos.as_str()).unwrap(); + + assert_eq!(deser_txos.to_bytes(), txos.to_bytes()); + assert_eq!(deser_txos.to_json().unwrap(), txos.to_json().unwrap()); +} + +#[test] +fn tx_output_deser_post_alonzo_with_plutus_script_json() { + let mut txos = TransactionOutputs::new(); + let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); + let val = &Value::new(&BigNum::from_str("435464757").unwrap()); + let txo = TransactionOutput { + address: addr.clone(), + amount: val.clone(), + plutus_data: None, + script_ref: None, + serialization_format: None, + }; + let mut txo_dh = txo.clone(); + txo_dh.set_script_ref(&ScriptRef::new_plutus_script(&PlutusScript::new( + [61u8; 29].to_vec(), + ))); + txos.add(&txo); + txos.add(&txo_dh); + txos.add(&txo_dh); + txos.add(&txo); + txos.add(&txo); + txos.add(&txo_dh); + let json_txos = txos.to_json().unwrap(); + let deser_txos = TransactionOutputs::from_json(json_txos.as_str()).unwrap(); + + assert_eq!(deser_txos.to_bytes(), txos.to_bytes()); + assert_eq!(deser_txos.to_json().unwrap(), txos.to_json().unwrap()); +} + +#[test] +fn tx_output_deser_post_alonzo_with_datum_json() { + let mut txos = TransactionOutputs::new(); + let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); + let val = &Value::new(&BigNum::from_str("435464757").unwrap()); + let txo = TransactionOutput { + address: addr.clone(), + amount: val.clone(), + plutus_data: None, + script_ref: None, + serialization_format: None, + }; + let mut txo_dh = txo.clone(); + txo_dh.set_plutus_data(&PlutusData::new_bytes(fake_bytes_32(11))); + txos.add(&txo); + txos.add(&txo_dh); + txos.add(&txo_dh); + txos.add(&txo); + txos.add(&txo); + txos.add(&txo_dh); + let json_txos = txos.to_json().unwrap(); + let deser_txos = TransactionOutputs::from_json(json_txos.as_str()).unwrap(); + + assert_eq!(deser_txos.to_bytes(), txos.to_bytes()); + assert_eq!(deser_txos.to_json().unwrap(), txos.to_json().unwrap()); +} + +#[test] +fn tx_output_deser_post_alonzo_with_native_script_and_datum_json() { + let mut txos = TransactionOutputs::new(); + let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); + let val = &Value::new(&BigNum::from_str("435464757").unwrap()); + let txo = TransactionOutput { + address: addr.clone(), + amount: val.clone(), + plutus_data: None, + script_ref: None, + serialization_format: None, + }; + let mut txo_dh = txo.clone(); + let native_script = NativeScript::new_timelock_start(&TimelockStart::new(20)); + txo_dh.set_script_ref(&ScriptRef::new_native_script(&native_script)); + txo_dh.set_plutus_data(&PlutusData::new_bytes(fake_bytes_32(11))); + txos.add(&txo); + txos.add(&txo_dh); + txos.add(&txo_dh); + txos.add(&txo); + txos.add(&txo); + txos.add(&txo_dh); + let json_txos = txos.to_json().unwrap(); + let deser_txos = TransactionOutputs::from_json(json_txos.as_str()).unwrap(); + + assert_eq!(deser_txos.to_bytes(), txos.to_bytes()); + assert_eq!(deser_txos.to_json().unwrap(), txos.to_json().unwrap()); +} + +#[test] +fn tx_output_deser_post_alonzo_with_native_script_json() { + let mut txos = TransactionOutputs::new(); + let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); + let val = &Value::new(&BigNum::from_str("435464757").unwrap()); + let txo = TransactionOutput { + address: addr.clone(), + amount: val.clone(), + plutus_data: None, + script_ref: None, + serialization_format: None, + }; + let mut txo_dh = txo.clone(); + let native_script = NativeScript::new_timelock_start(&TimelockStart::new(20)); + txo_dh.set_script_ref(&ScriptRef::new_native_script(&native_script)); + txos.add(&txo); + txos.add(&txo_dh); + txos.add(&txo_dh); + txos.add(&txo); + txos.add(&txo); + txos.add(&txo_dh); + let json_txos = txos.to_json().unwrap(); + let deser_txos = TransactionOutputs::from_json(json_txos.as_str()).unwrap(); + + assert_eq!(deser_txos.to_bytes(), txos.to_bytes()); + assert_eq!(deser_txos.to_json().unwrap(), txos.to_json().unwrap()); +} + +#[test] +fn tx_output_deser_post_alonzo_with_native_script_and_data_hash_json() { + let mut txos = TransactionOutputs::new(); + let addr = Address::from_bech32("addr1qyxwnq9kylzrtqprmyu35qt8gwylk3eemq53kqd38m9kyduv2q928esxmrz4y5e78cvp0nffhxklfxsqy3vdjn3nty9s8zygkm").unwrap(); + let val = &Value::new(&BigNum::from_str("435464757").unwrap()); + let txo = TransactionOutput { + address: addr.clone(), + amount: val.clone(), + plutus_data: None, + script_ref: None, + serialization_format: None, + }; + let mut txo_dh = txo.clone(); + let native_script = NativeScript::new_timelock_start(&TimelockStart::new(20)); + let data_hash = DataHash::from_bytes(vec![ + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + ]) + .unwrap(); + txo_dh.set_data_hash(&data_hash); + txo_dh.set_script_ref(&ScriptRef::new_native_script(&native_script)); + txos.add(&txo); + txos.add(&txo_dh); + txos.add(&txo_dh); + txos.add(&txo); + txos.add(&txo); + txos.add(&txo_dh); + let json_txos = txos.to_json().unwrap(); + let deser_txos = TransactionOutputs::from_json(json_txos.as_str()).unwrap(); + + assert_eq!(deser_txos.to_bytes(), txos.to_bytes()); + assert_eq!(deser_txos.to_json().unwrap(), txos.to_json().unwrap()); +} + +#[test] +fn mir_deser() { + let reserves_to_pot = MoveInstantaneousReward::new_to_other_pot( + MIRPot::Treasury, + &Coin::from_str("143546464").unwrap(), + ); + let reserves_to_pot_deser = + MoveInstantaneousReward::from_bytes(reserves_to_pot.to_bytes()).unwrap(); + assert_eq!(reserves_to_pot.to_bytes(), reserves_to_pot_deser.to_bytes()); + let treasury_to_pot = + MoveInstantaneousReward::new_to_other_pot(MIRPot::Treasury, &Coin::from_str("0").unwrap()); + let treasury_to_pot_deser = + MoveInstantaneousReward::from_bytes(treasury_to_pot.to_bytes()).unwrap(); + assert_eq!(treasury_to_pot.to_bytes(), treasury_to_pot_deser.to_bytes()); + let mut stake_creds = MIRToStakeCredentials::new(); + stake_creds.insert( + &Credential::from_scripthash(&ScriptHash([54u8; ScriptHash::BYTE_COUNT])), + &Int::new_i32(-314159265), + ); + let to_stake_creds = + MoveInstantaneousReward::new_to_stake_creds(MIRPot::Treasury, &stake_creds); + let to_stake_creds_deser = + MoveInstantaneousReward::from_bytes(to_stake_creds.to_bytes()).unwrap(); + assert_eq!(to_stake_creds.to_bytes(), to_stake_creds_deser.to_bytes()); +} + +#[test] +#[ignore] +fn alonzo_block() { + // this test for some reason has 2-byte pool metadata hashes so don't run this without changing that + let bytes = hex::decode("85828f03095820bb30a42c1e62f0afda5f0a4e8a562f7a13a24cea00ee81917b86b89e801314aa58208a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c58208a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c8258404fefc7c718693b57c87170ceba220382afbdd148c0a53b4a009ca63ad1f101483a6170c83a77f23d362a68dcb502802df7f98fa4f7a78b4082b211530e1234305850f770f6769ae9871d42b970fc6254bb927c2181fff45897f241bd72221d86d33c8df64c0a3c8cbb9aa52fef191d7202465c52df8d33727a38c7dc5d40864d753348a340f8afcbb3bb05d4a03f16b1080d825840fe682775f0fa232e909ddc9ec3210ea7a0ee6514cd8b0815190a08f7cef3985463152e10dfad9ed6c09b641b6c1824498e77814a7c12e03096a63cd62056446358500951ed3ef2065e4196d008b50a63bb3e2bdc9a64df67eff4e230b35429291def476684114e074357a5c834bf79eacf583b6fe9fcd1d17f3719a31de97aa4da5e4630b05421359e0b6e4a9bd76c6b920b190929582010c865acec05c84c2c0d0b889f7dbe9bf3b5561f8552da1eb286eac4ccdabc5e5820d298da3803eb9958f01c02e73f2410f2f9bb2ecbc346526b1b76772e1bdd7db500005840940f8a3696847e4a238705bdd27a345086282067b9bc5cb7b69847ca8756085844d576f59ab056c169a504320cc1eab4c11fd529482b3c57da6fa96d44635b0802005901c0a1b2ee63b357fe0b19c6bb8dc3fc865c0608a89626505c5f9aff3b74a0809ca2635e0c4235c247306987c7fd76a4a06210ebf74178e72a1faa78fb8865a69005cc6a5ab5c9b40f817c715df558af7d07b6186f0ccf31715ec2fb00980730ac166af657e6670608afe1bf651d496e01b1c7ff1eb44614d8cfd1b7e32b2c2939349236cc0ada145d8d8d7ad919ef1e60c8bbad31dbedf9f395849705a00c14a8785106aae31f55abc5b1f2089cbef16d9401f158704c1e4f740f7125cfc700a99d97d0332eacb33e4bbc8dab2872ec2b3df9e113addaebd156bfc64fdfc732614d2aedd10a58a34993b7b08c822af3aa615b6bbb9b267bc902e4f1075e194aed084ca18f8bcde1a6b094bf3f5295a0d454c0a083ed5b74f7092fc0a7346c03979a30eeea76d686e512ba48d21544ba874886cdd166cbf275b11f1f3881f4c4277c09a24b88fc6168f4578267bdc9d62cb9b78b8dfc888ccce226a177725f39e7d50930552861d1e88b7898971c780dc3b773321ba1854422b5cecead7d50e77783050eeae2cd9595b9cd91681c72e5d53bb7d12f28dec9b2847ee70a3d7781fb1133aea3b169f536ff5945ec0a76950e51beded0627bb78120617a2f0842e50e3981ae0081825820ee155ace9c40292074cb6aff8c9ccdd273c81648ff1149ef36bcea6ebb8a3e25000d81825820bb30a42c1e62f0afda5f0a4e8a562f7a13a24cea00ee81917b86b89e801314aa01018183583900cb9358529df4729c3246a2a033cb9821abbfd16de4888005904abc410d6a577e9441ad8ed9663931906e4d43ece8f82c712b1d0235affb06821864a1581ca646474b8f5431261506b6c273d307c7569a4eb6c96b42dd4a29520aa14a636f75747473436f696e1903e85820ee155ace9c40292074cb6aff8c9ccdd273c81648ff1149ef36bcea6ebb8a3e25021903e70304048382008200581c0d6a577e9441ad8ed9663931906e4d43ece8f82c712b1d0235affb068a03581c0d6a577e9441ad8ed9663931906e4d43ece8f82c712b1d0235affb065820c5e21ab1c9f6022d81c3b25e3436cb7f1df77f9652ae3e1310c28e621dd87b4c0105d81e82010a581de00d6a577e9441ad8ed9663931906e4d43ece8f82c712b1d0235affb0681581c0d6a577e9441ad8ed9663931906e4d43ece8f82c712b1d0235affb0680826e636f6e73656e7375732e706f6f6c427b7d82068200a18200581c008b47844d92812fc30d1f0ac9b6fbf38778ccba9db8312ad9079079186e05a1581de00d6a577e9441ad8ed9663931906e4d43ece8f82c712b1d0235affb0618640682a1581ce0a714319812c3f773ba04ec5d6b3ffcd5aad85006805b047b082541a104190fa00008020e81581cf81ce66e0f52da5ca48193386e7511fde5b030a307b4c3681736c6f009a1581cb16b56f5ec064be6ac3cab6035efae86b366cc3dc4a0d571603d70e5a14a636f75747473436f696e1903e80b58209e1199a988ba72ffd6e9c269cadb3b53b5f360ff99f112d9b2ee30c4d74ad88b0758209e1199a988ba72ffd6e9c269cadb3b53b5f360ff99f112d9b2ee30c4d74ad88b0f0181a400818258203b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da295840815671b581b4b02a30108a799a85c7f2e5487fb667e748e8fde59e466ab987ce133ecb77ffa0dc53c5804e6706e26b94e17803235da28112bc747de48ccbd70903814c4b0100002002002002000011048118bf058184000019039782191388191388a100d90103a300a40166737472696e67024562797465730382010204a10341620181820180028148470100002002006180").unwrap(); + let block = Block::from_bytes(bytes).unwrap(); + let block2 = Block::from_bytes(block.to_bytes()).unwrap(); + assert_eq!(block.to_bytes(), block2.to_bytes()); +} + +#[test] +fn test_tx_body_roundtrip() { + let mut txb = TransactionBody::new( + &TransactionInputs(vec![fake_tx_input(0)]), + &TransactionOutputs(vec![fake_tx_output(1)]), + &to_bignum(1234567), + Some(12345678), + ); + + txb.set_collateral_return(&fake_tx_output(2)); + txb.set_total_collateral(&to_bignum(1234)); + + let txb2 = TransactionBody::from_bytes(txb.to_bytes()).unwrap(); + assert_eq!(txb, txb2); +} + +#[test] +fn test_header_body_roundtrip() { + fn fake_header_body(leader_cert: HeaderLeaderCertEnum) -> HeaderBody { + HeaderBody { + block_number: 123, + slot: to_bignum(123), + prev_hash: Some(BlockHash::from_bytes(fake_bytes_32(1)).unwrap()), + issuer_vkey: fake_vkey(), + vrf_vkey: VRFVKey::from_bytes(fake_bytes_32(2)).unwrap(), + leader_cert, + block_body_size: 123456, + block_body_hash: BlockHash::from_bytes(fake_bytes_32(4)).unwrap(), + operational_cert: OperationalCert::new( + &KESVKey::from_bytes(fake_bytes_32(5)).unwrap(), + 123, + 456, + &fake_signature(6), + ), + protocol_version: ProtocolVersion::new(12, 13), + } + } + + let hbody1 = fake_header_body(HeaderLeaderCertEnum::VrfResult( + VRFCert::new(fake_bytes_32(3), [0; 80].to_vec()).unwrap(), + )); + + assert_eq!(hbody1, HeaderBody::from_bytes(hbody1.to_bytes()).unwrap()); + + let hbody2 = fake_header_body(HeaderLeaderCertEnum::NonceAndLeader( + VRFCert::new(fake_bytes_32(4), [1; 80].to_vec()).unwrap(), + VRFCert::new(fake_bytes_32(5), [2; 80].to_vec()).unwrap(), + )); + + assert_eq!(hbody2, HeaderBody::from_bytes(hbody2.to_bytes()).unwrap()); +} + +#[test] +fn test_witness_set_roundtrip() { + fn witness_set_roundtrip(plutus_scripts: &PlutusScripts) { + let mut ws = TransactionWitnessSet::new(); + ws.set_vkeys(&Vkeywitnesses::from_vec(vec![Vkeywitness::new( + &fake_vkey(), + &fake_signature(1), + )])); + ws.set_redeemers(&Redeemers(vec![Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(12), + &PlutusData::new_integer(&BigInt::one()), + &ExUnits::new(&to_bignum(123), &to_bignum(456)), + )])); + ws.set_plutus_data(&PlutusList::from(vec![PlutusData::new_integer( + &BigInt::one(), + )])); + ws.set_plutus_scripts(plutus_scripts); + + assert_eq!( + TransactionWitnessSet::from_bytes(ws.to_bytes()).unwrap(), + ws + ); + } + + let bytes = hex::decode("4e4d01000033222220051200120011").unwrap(); + let script_v1 = PlutusScript::from_bytes(bytes.clone()).unwrap(); + let script_v2 = PlutusScript::from_bytes_v2(bytes.clone()).unwrap(); + let script_v3 = PlutusScript::from_bytes_v3(bytes.clone()).unwrap(); + + witness_set_roundtrip(&PlutusScripts(vec![])); + witness_set_roundtrip(&PlutusScripts(vec![script_v1.clone()])); + witness_set_roundtrip(&PlutusScripts(vec![script_v2.clone()])); + witness_set_roundtrip(&PlutusScripts(vec![script_v3.clone()])); + witness_set_roundtrip(&PlutusScripts(vec![script_v1.clone(), script_v2.clone()])); + witness_set_roundtrip(&PlutusScripts(vec![ + script_v1.clone(), + script_v2.clone(), + script_v3.clone(), + ])); +} + +#[test] +fn test_script_ref_roundtrip() { + let ref0 = ScriptRef::new_native_script(&NativeScript::new_timelock_start( + &TimelockStart::new(123456), + )); + assert_eq!(ScriptRef::from_bytes(ref0.to_bytes()).unwrap(), ref0); + + let bytes = hex::decode("4e4d01000033222220051200120011").unwrap(); + let script_v1 = PlutusScript::from_bytes(bytes.clone()).unwrap(); + let script_v2 = PlutusScript::from_bytes_v2(bytes.clone()).unwrap(); + let script_v3 = PlutusScript::from_bytes_v3(bytes.clone()).unwrap(); + + let ref1 = ScriptRef::new_plutus_script(&script_v1); + assert_eq!(ScriptRef::from_bytes(ref1.to_bytes()).unwrap(), ref1); + + let ref2 = ScriptRef::new_plutus_script(&script_v2); + assert_eq!(ScriptRef::from_bytes(ref2.to_bytes()).unwrap(), ref2); + + let ref3 = ScriptRef::new_plutus_script(&script_v3); + assert_eq!(ScriptRef::from_bytes(ref3.to_bytes()).unwrap(), ref3); +} + +#[test] +fn legacy_output_roundtrip() { + let o1 = TransactionOutput::new(&fake_base_address(0), &fake_value()); + let mut o2 = TransactionOutput::new(&fake_base_address(1), &fake_value()); + o2.set_data_hash(&fake_data_hash(2)); + + assert_eq!(TransactionOutput::from_bytes(o1.to_bytes()).unwrap(), o1); + assert_eq!(TransactionOutput::from_bytes(o2.to_bytes()).unwrap(), o2); +} + +#[test] +fn babbage_output_roundtrip() { + let mut o1 = TransactionOutput::new(&fake_base_address(0), &fake_value2(234567)); + o1.set_plutus_data(&PlutusData::new_empty_constr_plutus_data(&to_bignum(42))); + assert_eq!(TransactionOutput::from_bytes(o1.to_bytes()).unwrap(), o1); + + let mut o2 = TransactionOutput::new(&fake_base_address(1), &fake_value2(234568)); + o2.set_script_ref(&ScriptRef::new_native_script( + &NativeScript::new_timelock_start(&TimelockStart::new(123456)), + )); + assert_eq!(TransactionOutput::from_bytes(o2.to_bytes()).unwrap(), o2); + + let bytes = hex::decode("4e4d01000033222220051200120011").unwrap(); + let script_v1 = PlutusScript::from_bytes(bytes.clone()).unwrap(); + let script_v2 = PlutusScript::from_bytes_v2(bytes.clone()).unwrap(); + let script_v3 = PlutusScript::from_bytes_v3(bytes.clone()).unwrap(); + + let mut o3 = TransactionOutput::new(&fake_base_address(2), &fake_value2(234569)); + o3.set_script_ref(&ScriptRef::new_plutus_script(&script_v1)); + assert_eq!(TransactionOutput::from_bytes(o3.to_bytes()).unwrap(), o3); + + let mut o4 = TransactionOutput::new(&fake_base_address(3), &fake_value2(234570)); + o4.set_script_ref(&ScriptRef::new_plutus_script(&script_v2)); + assert_eq!(TransactionOutput::from_bytes(o4.to_bytes()).unwrap(), o4); + + let mut o5 = TransactionOutput::new(&fake_base_address(4), &fake_value2(234571)); + o5.set_plutus_data(&PlutusData::new_empty_constr_plutus_data(&to_bignum(43))); + o5.set_script_ref(&ScriptRef::new_plutus_script(&script_v2)); + assert_eq!(TransactionOutput::from_bytes(o5.to_bytes()).unwrap(), o5); + + let mut o6 = TransactionOutput::new(&fake_base_address(5), &fake_value2(234572)); + o6.set_data_hash(&fake_data_hash(222)); + o6.set_script_ref(&ScriptRef::new_plutus_script(&script_v2)); + assert_eq!(TransactionOutput::from_bytes(o6.to_bytes()).unwrap(), o6); + + let mut o7 = TransactionOutput::new(&fake_base_address(6), &fake_value2(234573)); + o7.set_script_ref(&ScriptRef::new_plutus_script(&script_v3)); + assert_eq!(TransactionOutput::from_bytes(o7.to_bytes()).unwrap(), o7); +} + +#[test] +fn pre_alonzo_block() { + let bytes = hex::decode("84828f1a002072a81a00ca44f0582070d6f38b4569ba062c09632127db13474f22c534e6d8097895403c431e57f12358204f4d7523e41e058a6cbdefb5538654ffc2a53416a7f5bb99f7eac699d42d5c1f58205e3d96cb8ef0291d2f1df6aa7b5a4496ac8de1dcce100c31274325625102796d82584065417914ca323d842c5861407a638e146e6af55f59aff95f1451839de2aa709151237e24e6db7bf94db97293da9c1e61e68d60c8e2b10a116d3c71067247458b5850dc36a5a88f09f0b7a0b5d5d52d87c7c3e3c20752176a426d182255df3d026392f407990f09e5858de6432263fc167bc890a97d07d2371cd5bb26b12242c1ff6fda184ec78d15493a38a3e0df1494f800825840df4e07d3bca43341e4297e2914ea38363ecea1c17ce9145294c4631e0f09f706cb23a5f27c6b71ae9ac46a7ca25af4d7c156f15444fa41814f7d6a0b6a4e57525850d6073f277ded1ef9e8bfe9f6325858c142fbbbbff4395c45d82f0861a6ef6116204965f807e8650fa4e9ac4aa04aeb03984ea66abb129155a78931d39bbcb7ad64afef3f4f55cfa4eb6c97698e88f1051905db5820c1b1fbd809dc06e0e2dc544312aae2a46c059249f86c24ea0689a0b0944a75f558207ce5ce3992b23cb2bf566c48aba8bfc39eb24c9b43354de0129b81bf9f1414b307186058403ac64d720227c18139132b499046a168eb1c5bdd3983385e3518f33fc7f52fd0be348fe3e14d17e1ba606708c30bda061cf23ea3294b0089d3e1e1d58a7aa50702005901c074d3c2c0b5e17b12ba829017186daa1f7f365bbe5b0e0c038cb0cc05e849f702afd349234353ee3cc8878fa31299e85562f04d3cdd74e1bc73591be48d2fbc0d043f6b41fa527b2f9fb3f77605eee528926e76cc18a1638283e5591170f7073462441d40d7cc2e13a38e7d247928cb15d2e5b2e74a12d07f858f7e922bbff8a91c16e9bb8f5ea101c50d96627fb48a03d8191b5035b5de00b9824867fdffb5a2493799e94676bf685db85517dd8a87a0ba2589b3a8a69d529ae8052680c520c5577adbb91cf931e906b1629e621d5bd5c30eaee77f35c5f0a714827b48afaa4e549c1756e94291f4b083aad9c375caf9a67aeac08f32c91cd0572192267960cd74a85148b5e99d0053804dcfb44785417725c56e0fc5caf2ae50fbf25b92c7b7ebe17aa9e289470041a06fd8986f6f9ebdb12e87a970f1d388963929367013e17513e83cab8c98460cab703d5fdd26eeb079e4db701996f73c694365080236901289c5fc96471e91fb75e0e58560f5d073c3ef79a8f5dd4b45ff7abf9c7d7564232f7897ca3d85ac7bb9ecaa75b7c062f27de8b20f301e5607563b2c904e3c7f113b1eeba8a4d1c82fc1a747c920bac6af9a9f4dae1744847232ea03289e25e482a50082825820478ad95cafe9b1660809d618870c86dda1295764e113886e2b8a1de2de5af17201825820f84508cc7674b663db84ceb9f0790f5527f3c70f2a05e4d7f783cd9890463b4e01018182583900ff7f04abbd3050c0b138c8fa3005d48aaf8b9700d4565758e91a95385667fab107f848cfd4b73a7407a7661600cf68f0efc969ece37665ae1a000f4240021a000f4240031a00ca60f1075820e845fe9180ac36cc0102f892a839ad1ed2ea9a52c605fb8e4e1c2774ef0bb65ba50081825820c4b5ad6873b8581c75b8ee52f58a3eded29acbbb92d874a64228a1ca4e68956700018182581d60daad04ed2b7f69e2a9be582e37091739fa036a14c1c22f88061d43c71b004aca96b58fd90c021a000f4240031a00d986900682a7581c0d06d2547ed371fdf95fb5c4c735eecdd53e6a5bb831561bd0fcfd3da10e820300581c2f56e87d67b8e5216582cfeb95dbdc9083110a3ef68faaa51bef3a80a10e820300581c2fca486b4d8f1a0432f5bf18ef473ee4294c795a1a32e3132bc6b90fa10e820300581c4ee98623920698b77c1c7f77288cbdac5f9011ff8970b1f507567d0da10e820300581c514e81afb082fce01678809eebd90eda4f7918354ec7d0433ad16274a10e820300581c581e23030b6038bae716e5d64b9e053db10541b12e6b0b4eff485454a10e820300581ce5f27655371b54aed91cc916b2569060978be80056768fee2cc5ce1ba10e820300186582a1008182582028364596385174f5eabc763031b8d54b18ed5d06967ff44b3abbdbaca9cb58a75840de49197fed8dd13716c88e68452fb314d418a24fee9cc194308bd47b057d161ae40cd8f49bf6b378e7343ee5d3a7b9bdb1f2e9efeef896adaa9eb7373fbb8502a1008882582032a954b521c0b19514408965831ef6839637de7a1a6168bcf8455c504ba93b9c5840ab2d59239499807e25dc8025940a70cb890a52e8f47f35004cfec623036ca9f5c3e925b32bd23a7d1d044cef915913e853dbb57438f9c92a5d5f9581caa67d098258207ec249d890d0aaf9a81207960c163ae2d6ac5e715ca6b96d5860e50d9f2b2b2a5840f2d8031ac5d79777076dd1176cb7ed91690fcfb6be498320e5de9afbf6ea8e8ced23bff69230d050523a4a7e03c2b0599e18e93b31959063249fb50274a02a068258204f4d7523e41e058a6cbdefb5538654ffc2a53416a7f5bb99f7eac699d42d5c1f5840c5844b849865fed81f67842a4697c3090cf4ecb50510f1e6b379b7c63b78417ca28ea653c016d2e733877e1605e8a1712c42404ca0686f67455c620431d54b07825820e764b0340d7b353f5f745891033774e4beab6aa1458a54ff29a1324c05bb9876584026c35f8ec2102ec8fcc3bd0a1a0760486952e147f44236a35c7d818a7024590e1395f097a0d046085ded24ec8c585008d3ffc0321ad040649ce08eb33614760e82582073ae41eca2be37fc15c55a50d668c8647e10bf222172c2d58abfa6e9310e596258402c3f197360294781841f0669822b0449515a5e0b77b23185652a1b0ea8354537b3e9335577a87fa19e9fe47f1039fa286aaa11859d631f3ff74564c6da14c806825820234fb2b8530114b461c6ca8242c8b86a226c95c4c27479ca850d1aea4a52d2985840ba751817e70695a041a5f455c08947fa4e3d6ffc332adeb25691fac4927bbaafd4b3f5f9855946ad9681083aec277766c7f90da7543e912f46aeae07fdd5b90a825820dfb615a61568d6867f45a85c32227f27025180d738a8a3d7fd3c929f624d72395840cc1f728cce6ce2fec21d2648011c14d244c35ba3cbd553593655f6f07d86b8bdf103d52b61143bc1701319517d4a24b778c02e983e02a0f3fd0cd558d472f009825820e5bc21a83616bcccfe343ec36b9dc4c06c90e913df1d8a0b046008651f42caa95840f85bc5e753beed04b3f9072da7a6adadcdb87769528c59e16162e86782b6ce11feacbd5de97e352121e9509a809f613d5bcebf7413fd55f89776c5606e4a9408a100a119534da261638158220a201f79b4d15fd971297a842ac6a4e953b82886df66c0d9723f5870e5725da6380b617601").unwrap(); + let _block = Block::from_bytes(bytes).unwrap(); +} + +#[test] +fn tx_output_ser_type() { + let array_tx_output = TransactionOutput::from_hex("8258390000efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee16400efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee1641a000f4240").unwrap(); + let map_tx_output = TransactionOutput::from_hex("a30058390000efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee16400efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee164011a00039447028201d81844d9052380").unwrap(); + assert_eq!( + array_tx_output.serialization_format().unwrap(), + CborContainerType::Array + ); + assert_eq!( + map_tx_output.serialization_format().unwrap(), + CborContainerType::Map + ); +} diff --git a/rust/src/tests/serialization/mod.rs b/rust/src/tests/serialization/mod.rs index e4d315ea..b7b9a424 100644 --- a/rust/src/tests/serialization/mod.rs +++ b/rust/src/tests/serialization/mod.rs @@ -2,3 +2,4 @@ pub mod certificates; pub mod governance; pub mod transaction_body; pub mod protocol_param_update; +pub mod general; diff --git a/rust/src/utils.rs b/rust/src/utils.rs index 7290d285..ee568843 100644 --- a/rust/src/utils.rs +++ b/rust/src/utils.rs @@ -1236,7 +1236,7 @@ pub fn hash_script_data( */ buf.push(0x80); if let Some(d) = &datums { - buf.extend(d.to_bytes()); + buf.extend(d.to_set_bytes()); } buf.push(0xA0); } else { @@ -1249,7 +1249,7 @@ pub fn hash_script_data( */ buf.extend(redeemers.to_bytes()); if let Some(d) = &datums { - buf.extend(d.to_bytes()); + buf.extend(d.to_set_bytes()); } buf.extend(cost_models.language_views_encoding()); } From 47d37d98a7dd0d569296656a2af3cf0362d6072e Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 11 Feb 2024 03:58:23 +0800 Subject: [PATCH 225/349] switch from linked-hash-map to hashlink --- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 626b51e9..b3d42e2e 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -24,7 +24,7 @@ digest = "^0.9" bech32 = "0.7.2" hex = "0.4.0" cfg-if = "1" -linked-hash-map = "0.5.3" +hashlink = "0.9.0" serde_json = "1.0.57" num-bigint = "0.4.0" num-integer = "0.1.45" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 8d060516..65eeec7b 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -595,9 +595,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -605,9 +605,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ "bumpalo", "log", @@ -620,9 +620,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -630,9 +630,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", @@ -643,9 +643,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "winapi" From 9af7fab3a7ee84a2e44ff50ff164cda4cae57a77 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 11 Feb 2024 04:44:36 +0800 Subject: [PATCH 226/349] add script hash for parameter_change_action and treasury_withdrawals_action --- .../proposals/parameter_change_action.rs | 30 ++++++++++++++++ .../proposals/treasury_withdrawals_action.rs | 16 +++++++++ .../proposals/parameter_change_action.rs | 31 ++++++++++++---- .../proposals/treasury_withdrawals_action.rs | 22 ++++++++++-- .../protocol_types/governance/proposals.rs | 30 +++++++--------- .../serialization/governance/proposals.rs | 36 +++++++++++++++++++ 6 files changed, 138 insertions(+), 27 deletions(-) diff --git a/rust/src/protocol_types/governance/proposals/parameter_change_action.rs b/rust/src/protocol_types/governance/proposals/parameter_change_action.rs index 8ce69f77..3c4d5548 100644 --- a/rust/src/protocol_types/governance/proposals/parameter_change_action.rs +++ b/rust/src/protocol_types/governance/proposals/parameter_change_action.rs @@ -16,6 +16,7 @@ use crate::*; pub struct ParameterChangeAction { pub(crate) gov_action_id: Option, pub(crate) protocol_param_updates: ProtocolParamUpdate, + pub(crate) policy_hash: Option, } impl_to_from!(ParameterChangeAction); @@ -30,10 +31,15 @@ impl ParameterChangeAction { self.protocol_param_updates.clone() } + pub fn policy_hash(&self) -> Option { + self.policy_hash.clone() + } + pub fn new(protocol_param_updates: &ProtocolParamUpdate) -> Self { Self { gov_action_id: None, protocol_param_updates: protocol_param_updates.clone(), + policy_hash: None, } } @@ -44,6 +50,30 @@ impl ParameterChangeAction { Self { gov_action_id: Some(gov_action_id.clone()), protocol_param_updates: protocol_param_updates.clone(), + policy_hash: None, + } + } + + pub fn new_with_policy_hash( + protocol_param_updates: &ProtocolParamUpdate, + policy_hash: &ScriptHash, + ) -> Self { + Self { + gov_action_id: None, + protocol_param_updates: protocol_param_updates.clone(), + policy_hash: Some(policy_hash.clone()), + } + } + + pub fn new_with_policy_hash_and_action_id( + gov_action_id: &GovernanceActionId, + protocol_param_updates: &ProtocolParamUpdate, + policy_hash: &ScriptHash, + ) -> Self { + Self { + gov_action_id: Some(gov_action_id.clone()), + protocol_param_updates: protocol_param_updates.clone(), + policy_hash: Some(policy_hash.clone()), } } } diff --git a/rust/src/protocol_types/governance/proposals/treasury_withdrawals_action.rs b/rust/src/protocol_types/governance/proposals/treasury_withdrawals_action.rs index d0de9b0f..d3e5f8bb 100644 --- a/rust/src/protocol_types/governance/proposals/treasury_withdrawals_action.rs +++ b/rust/src/protocol_types/governance/proposals/treasury_withdrawals_action.rs @@ -15,6 +15,7 @@ use crate::*; #[wasm_bindgen] pub struct TreasuryWithdrawalsAction { pub(crate) withdrawals: TreasuryWithdrawals, + pub(crate) policy_hash: Option, } impl_to_from!(TreasuryWithdrawalsAction); @@ -25,9 +26,24 @@ impl TreasuryWithdrawalsAction { self.withdrawals.clone() } + pub fn policy_hash(&self) -> Option { + self.policy_hash.clone() + } + pub fn new(withdrawals: &TreasuryWithdrawals) -> Self { Self { withdrawals: withdrawals.clone(), + policy_hash: None, + } + } + + pub fn new_with_policy_hash( + withdrawals: &TreasuryWithdrawals, + policy_hash: &ScriptHash, + ) -> Self { + Self { + withdrawals: withdrawals.clone(), + policy_hash: Some(policy_hash.clone()), } } } diff --git a/rust/src/serialization/governance/proposals/parameter_change_action.rs b/rust/src/serialization/governance/proposals/parameter_change_action.rs index 7917fa96..5a1bb8a3 100644 --- a/rust/src/serialization/governance/proposals/parameter_change_action.rs +++ b/rust/src/serialization/governance/proposals/parameter_change_action.rs @@ -9,13 +9,14 @@ impl cbor_event::se::Serialize for ParameterChangeAction { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(3))?; + serializer.write_array(cbor_event::Len::Len(4))?; let proposal_index = VotingProposalIndexNames::ParameterChangeAction.to_u64(); serialize_and_check_index(serializer, proposal_index, "ParameterChangeAction")?; self.gov_action_id.serialize_nullable(serializer)?; self.protocol_param_updates.serialize(serializer)?; + self.policy_hash.serialize_nullable(serializer)?; Ok(serializer) } @@ -28,11 +29,22 @@ impl DeserializeEmbeddedGroup for ParameterChangeAction { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - check_len( - len, - 3, - "(proposal_index, gov_action_id // null, protocol_param_updates)", - )?; + let has_policy_hash = len == cbor_event::Len::Len(4) || len == cbor_event::Len::Indefinite; + + //for sancho backwards compatibility + if !has_policy_hash { + check_len( + len, + 3, + "(proposal_index, gov_action_id // null, protocol_param_updates)", + )?; + } else { + check_len( + len, + 4, + "(proposal_index, gov_action_id // null, protocol_param_updates, policy_hash // null)", + )?; + } let desired_index = VotingProposalIndexNames::ParameterChangeAction.to_u64(); deserialize_and_check_index(raw, desired_index, "proposal_index")?; @@ -43,9 +55,16 @@ impl DeserializeEmbeddedGroup for ParameterChangeAction { let protocol_param_updates = ProtocolParamUpdate::deserialize(raw) .map_err(|e| e.annotate("protocol_param_updates"))?; + let policy_hash = if has_policy_hash { + ScriptHash::deserialize_nullable(raw).map_err(|e| e.annotate("policy_hash"))? + } else { + None + }; + return Ok(ParameterChangeAction { gov_action_id, protocol_param_updates, + policy_hash, }); } } diff --git a/rust/src/serialization/governance/proposals/treasury_withdrawals_action.rs b/rust/src/serialization/governance/proposals/treasury_withdrawals_action.rs index f5aae742..492d1aaf 100644 --- a/rust/src/serialization/governance/proposals/treasury_withdrawals_action.rs +++ b/rust/src/serialization/governance/proposals/treasury_withdrawals_action.rs @@ -9,12 +9,13 @@ impl Serialize for TreasuryWithdrawalsAction { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; + serializer.write_array(cbor_event::Len::Len(3))?; let proposal_index = VotingProposalIndexNames::TreasuryWithdrawalsAction.to_u64(); serialize_and_check_index(serializer, proposal_index, "TreasuryWithdrawalsAction")?; self.withdrawals.serialize(serializer)?; + self.policy_hash.serialize_nullable(serializer)?; Ok(serializer) } @@ -27,13 +28,28 @@ impl DeserializeEmbeddedGroup for TreasuryWithdrawalsAction { raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { - check_len(len, 2, "(proposal_index, withdrawals)")?; + + let has_policy_hash = len == cbor_event::Len::Len(3) || len == cbor_event::Len::Indefinite; + + //for sancho backwards compatibility + if !has_policy_hash { + check_len(len, 2, "(proposal_index, { reward_account => coin })")?; + } else { + check_len(len, 3, "(proposal_index, { reward_account => coin }, policy_hash / null)")?; + } + let desired_index = VotingProposalIndexNames::TreasuryWithdrawalsAction.to_u64(); deserialize_and_check_index(raw, desired_index, "proposal_index")?; let withdrawals = TreasuryWithdrawals::deserialize(raw)?; - return Ok(TreasuryWithdrawalsAction { withdrawals }); + let policy_hash = if has_policy_hash { + ScriptHash::deserialize_nullable(raw)? + } else { + None + }; + + return Ok(TreasuryWithdrawalsAction { withdrawals , policy_hash}); } } diff --git a/rust/src/tests/protocol_types/governance/proposals.rs b/rust/src/tests/protocol_types/governance/proposals.rs index 9865db19..5bc2ebee 100644 --- a/rust/src/tests/protocol_types/governance/proposals.rs +++ b/rust/src/tests/protocol_types/governance/proposals.rs @@ -63,7 +63,7 @@ fn new_committee_action_setters_getters_test() { Credential::from_keyhash(&fake_key_hash(1)), Credential::from_keyhash(&fake_key_hash(2)), ] - .into_iter() + .into_iter(), ); let proposal = UpdateCommitteeAction::new(&committee, &members_to_remove); @@ -106,16 +106,17 @@ fn no_confidence_action_setters_getters_test() { fn parameter_change_action_setters_getters_test() { let protocol_params = crate_full_protocol_param_update(); let action_id = create_action_id(); + let policy_hash = fake_script_hash(1); let proposal = ParameterChangeAction::new(&protocol_params); - let proposal_with_action_id = - ParameterChangeAction::new_with_action_id(&action_id, &protocol_params); + let proposal_with_action_id = ParameterChangeAction::new_with_policy_hash_and_action_id( + &action_id, + &protocol_params, + &policy_hash, + ); assert_eq!(proposal.gov_action_id(), None); assert_eq!(proposal.protocol_param_updates(), protocol_params); assert_eq!(proposal_with_action_id.gov_action_id(), Some(action_id)); - assert_eq!( - proposal_with_action_id.protocol_param_updates(), - protocol_params - ); + assert_eq!(proposal_with_action_id.policy_hash(), Some(policy_hash)); } #[test] @@ -150,8 +151,7 @@ fn treasury_withdrawals_action() { fn voting_proposals_setters_getters_test() { let mut proposals = VotingProposals::new(); let no_confidence_action = NoConfidenceAction::new(); - let parameter_change_action = - ParameterChangeAction::new(&crate_full_protocol_param_update()); + let parameter_change_action = ParameterChangeAction::new(&crate_full_protocol_param_update()); let proposal1 = VotingProposal::new( &GovernanceAction::new_no_confidence_action(&no_confidence_action), @@ -168,12 +168,6 @@ fn voting_proposals_setters_getters_test() { proposals.add(&proposal1); proposals.add(&proposal2); assert_eq!(proposals.len(), 2); - assert_eq!( - proposals.get(0), - proposal1 - ); - assert_eq!( - proposals.get(1), - proposal2 - ); -} \ No newline at end of file + assert_eq!(proposals.get(0), proposal1); + assert_eq!(proposals.get(1), proposal2); +} diff --git a/rust/src/tests/serialization/governance/proposals.rs b/rust/src/tests/serialization/governance/proposals.rs index 724902e4..4fc85ce4 100644 --- a/rust/src/tests/serialization/governance/proposals.rs +++ b/rust/src/tests/serialization/governance/proposals.rs @@ -281,6 +281,19 @@ fn parameter_change_action_with_action_id_ser_round_trip() { ); } +#[test] +fn parameter_change_action_with_script_hash() { + let parameters_update = crate_full_protocol_param_update(); + let script_hash = ScriptHash::from(fake_script_hash(1)); + let proposal = ParameterChangeAction::new_with_policy_hash(¶meters_update, &script_hash); + let proposal_wrapped = GovernanceAction::new_parameter_change_action(&proposal); + to_from_test!(ParameterChangeAction, proposal, proposal_wrapped); + assert_eq!( + proposal, + proposal_wrapped.as_parameter_change_action().unwrap() + ); +} + #[test] fn treasury_withdrawals_ser_round_trip() { let mut withdrawals = TreasuryWithdrawals::new(); @@ -313,6 +326,29 @@ fn treasury_withdrawals_action_ser_round_trip() { ); } +#[test] +fn treasury_withdrawals_action_with_script_hash_ser_round_trip() { + let mut withdrawals = TreasuryWithdrawals::new(); + let addr1 = RewardAddress::new(1, &Credential::from_keyhash(&fake_key_hash(1))); + let addr2 = RewardAddress::new(2, &Credential::from_keyhash(&fake_key_hash(2))); + withdrawals.insert(&addr1, &Coin::from(1u32)); + withdrawals.insert(&addr2, &Coin::from(2u32)); + + let script_hash = ScriptHash::from(fake_script_hash(1)); + let proposal = TreasuryWithdrawalsAction::new_with_policy_hash(&withdrawals, &script_hash); + + let proposal_wrapped = GovernanceAction::new_treasury_withdrawals_action(&proposal); + + assert_eq!(proposal.policy_hash(), Some(script_hash)); + assert_eq!(proposal.withdrawals(), withdrawals); + + to_from_test!(TreasuryWithdrawalsAction, proposal, proposal_wrapped); + assert_eq!( + proposal, + proposal_wrapped.as_treasury_withdrawals_action().unwrap() + ); +} + #[test] fn voting_proposals_ser_round_trip() { let mut proposals = VotingProposals::new(); From 5859bd4a7bc8ae20a6db169db193a4658b0371bf Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 11 Feb 2024 04:52:25 +0800 Subject: [PATCH 227/349] add mandatory script witness for a voting proposal that have a policy hash --- rust/src/builders/voting_proposal_builder.rs | 4 +++- .../governance/proposals/new_constitution_action.rs | 4 ++++ .../governance/proposals/parameter_change_action.rs | 4 ++++ .../governance/proposals/treasury_withdrawals_action.rs | 4 ++++ .../governance/proposals/voting_proposal.rs | 8 ++++++++ 5 files changed, 23 insertions(+), 1 deletion(-) diff --git a/rust/src/builders/voting_proposal_builder.rs b/rust/src/builders/voting_proposal_builder.rs index ef9c7f05..949b8da7 100644 --- a/rust/src/builders/voting_proposal_builder.rs +++ b/rust/src/builders/voting_proposal_builder.rs @@ -16,8 +16,10 @@ impl VotingProposalBuilder { } pub fn add(&mut self, proposal: &VotingProposal) -> Result<(), JsError> { + if proposal.has_script_hash() { + return Err(JsError::from_str("Proposal has a script hash. Use add_with_plutus_witness instead.")); + } self.proposals.insert(proposal.clone(), None); - Ok(()) } diff --git a/rust/src/protocol_types/governance/proposals/new_constitution_action.rs b/rust/src/protocol_types/governance/proposals/new_constitution_action.rs index ef020c52..0776f40b 100644 --- a/rust/src/protocol_types/governance/proposals/new_constitution_action.rs +++ b/rust/src/protocol_types/governance/proposals/new_constitution_action.rs @@ -46,4 +46,8 @@ impl NewConstitutionAction { constitution: constitution.clone(), } } + + pub fn has_script_hash(&self) -> bool { + self.constitution.script_hash.is_some() + } } diff --git a/rust/src/protocol_types/governance/proposals/parameter_change_action.rs b/rust/src/protocol_types/governance/proposals/parameter_change_action.rs index 3c4d5548..08c96289 100644 --- a/rust/src/protocol_types/governance/proposals/parameter_change_action.rs +++ b/rust/src/protocol_types/governance/proposals/parameter_change_action.rs @@ -76,4 +76,8 @@ impl ParameterChangeAction { policy_hash: Some(policy_hash.clone()), } } + + pub(crate) fn has_script_hash(&self) -> bool { + self.policy_hash.is_some() + } } diff --git a/rust/src/protocol_types/governance/proposals/treasury_withdrawals_action.rs b/rust/src/protocol_types/governance/proposals/treasury_withdrawals_action.rs index d3e5f8bb..9ca76337 100644 --- a/rust/src/protocol_types/governance/proposals/treasury_withdrawals_action.rs +++ b/rust/src/protocol_types/governance/proposals/treasury_withdrawals_action.rs @@ -46,4 +46,8 @@ impl TreasuryWithdrawalsAction { policy_hash: Some(policy_hash.clone()), } } + + pub(crate) fn has_script_hash(&self) -> bool { + self.policy_hash.is_some() + } } diff --git a/rust/src/protocol_types/governance/proposals/voting_proposal.rs b/rust/src/protocol_types/governance/proposals/voting_proposal.rs index 459a0941..57b95982 100644 --- a/rust/src/protocol_types/governance/proposals/voting_proposal.rs +++ b/rust/src/protocol_types/governance/proposals/voting_proposal.rs @@ -53,4 +53,12 @@ impl VotingProposal { deposit: deposit.clone(), } } + + pub(crate) fn has_script_hash(&self) -> bool { + match self.governance_action.0 { + GovernanceActionEnum::ParameterChangeAction(ref action) => action.has_script_hash(), + GovernanceActionEnum::TreasuryWithdrawalsAction(ref action) => action.has_script_hash(), + _ => false, + } + } } From befe1cc9787ed555a6e367f5dfb647ef15032248 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 11 Feb 2024 04:55:51 +0800 Subject: [PATCH 228/349] update js.flow file --- rust/pkg/cardano_serialization_lib.js.flow | 894 ++++++++++----------- 1 file changed, 415 insertions(+), 479 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 74d16a8f..d448874e 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -5,82 +5,6 @@ * @flow */ -/** - * @param {string} json - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {PlutusData} - */ -declare export function encode_json_str_to_plutus_datum( - json: string, - schema: $Values -): PlutusData; - -/** - * @param {PlutusData} datum - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {string} - */ -declare export function decode_plutus_datum_to_json_str( - datum: PlutusData, - schema: $Values -): string; - -/** - * @param {Uint8Array} bytes - * @returns {TransactionMetadatum} - */ -declare export function encode_arbitrary_bytes_as_metadatum( - bytes: Uint8Array -): TransactionMetadatum; - -/** - * @param {TransactionMetadatum} metadata - * @returns {Uint8Array} - */ -declare export function decode_arbitrary_bytes_from_metadatum( - metadata: TransactionMetadatum -): Uint8Array; - -/** - * @param {string} json - * @param {$Values< - typeof - MetadataJsonSchema>} schema - * @returns {TransactionMetadatum} - */ -declare export function encode_json_str_to_metadatum( - json: string, - schema: $Values -): TransactionMetadatum; - -/** - * @param {TransactionMetadatum} metadatum - * @param {$Values< - typeof - MetadataJsonSchema>} schema - * @returns {string} - */ -declare export function decode_metadatum_to_json_str( - metadatum: TransactionMetadatum, - schema: $Values -): string; - -/** - * @param {Address} address - * @param {TransactionUnspentOutputs} utxos - * @param {TransactionBuilderConfig} config - * @returns {TransactionBatchList} - */ -declare export function create_send_all( - address: Address, - utxos: TransactionUnspentOutputs, - config: TransactionBuilderConfig -): TransactionBatchList; - /** * @param {string} password * @param {string} salt @@ -105,33 +29,6 @@ declare export function decrypt_with_password( data: string ): string; -/** - * @param {Transaction} tx - * @param {LinearFee} linear_fee - * @returns {BigNum} - */ -declare export function min_fee(tx: Transaction, linear_fee: LinearFee): BigNum; - -/** - * @param {ExUnits} ex_units - * @param {ExUnitPrices} ex_unit_prices - * @returns {BigNum} - */ -declare export function calculate_ex_units_ceil_cost( - ex_units: ExUnits, - ex_unit_prices: ExUnitPrices -): BigNum; - -/** - * @param {Transaction} tx - * @param {ExUnitPrices} ex_unit_prices - * @returns {BigNum} - */ -declare export function min_script_fee( - tx: Transaction, - ex_unit_prices: ExUnitPrices -): BigNum; - /** * @param {TransactionHash} tx_body_hash * @param {ByronAddress} addr @@ -258,81 +155,107 @@ declare export function encode_json_str_to_native_script( ): NativeScript; /** + * @param {Address} address + * @param {TransactionUnspentOutputs} utxos + * @param {TransactionBuilderConfig} config + * @returns {TransactionBatchList} */ - -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 -|}; +declare export function create_send_all( + address: Address, + utxos: TransactionUnspentOutputs, + config: TransactionBuilderConfig +): TransactionBatchList; /** + * @param {Uint8Array} bytes + * @returns {TransactionMetadatum} */ - -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 -|}; +declare export function encode_arbitrary_bytes_as_metadatum( + bytes: Uint8Array +): TransactionMetadatum; /** + * @param {TransactionMetadatum} metadata + * @returns {Uint8Array} */ - -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 - +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 -|}; +declare export function decode_arbitrary_bytes_from_metadatum( + metadata: TransactionMetadatum +): Uint8Array; /** + * @param {string} json + * @param {$Values< + typeof + MetadataJsonSchema>} schema + * @returns {TransactionMetadatum} */ - -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 -|}; +declare export function encode_json_str_to_metadatum( + json: string, + schema: $Values +): TransactionMetadatum; /** - * JSON <-> PlutusData conversion schemas. - * Follows ScriptDataJsonSchema in cardano-cli defined at: - * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 - * - * All methods here have the following restrictions due to limitations on dependencies: - * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors - * * Hex strings for bytes don't accept odd-length (half-byte) strings. - * cardano-cli seems to support these however but it seems to be different than just 0-padding - * on either side when tested so proceed with caution + * @param {TransactionMetadatum} metadatum + * @param {$Values< + typeof + MetadataJsonSchema>} schema + * @returns {string} */ +declare export function decode_metadatum_to_json_str( + metadatum: TransactionMetadatum, + schema: $Values +): string; -declare export var PlutusDatumSchema: {| - +BasicConversions: 0, // 0 - +DetailedSchema: 1, // 1 -|}; +/** + * @param {string} json + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {PlutusData} + */ +declare export function encode_json_str_to_plutus_datum( + json: string, + schema: $Values +): PlutusData; /** + * @param {PlutusData} datum + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {string} */ +declare export function decode_plutus_datum_to_json_str( + datum: PlutusData, + schema: $Values +): string; -declare export var LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 -|}; +/** + * @param {Transaction} tx + * @param {LinearFee} linear_fee + * @returns {BigNum} + */ +declare export function min_fee(tx: Transaction, linear_fee: LinearFee): BigNum; /** + * @param {ExUnits} ex_units + * @param {ExUnitPrices} ex_unit_prices + * @returns {BigNum} */ +declare export function calculate_ex_units_ceil_cost( + ex_units: ExUnits, + ex_unit_prices: ExUnitPrices +): BigNum; -declare export var RedeemerTagKind: {| - +Spend: 0, // 0 - +Mint: 1, // 1 - +Cert: 2, // 2 - +Reward: 3, // 3 - +Vote: 4, // 4 - +VotingProposal: 5, // 5 -|}; +/** + * @param {Transaction} tx + * @param {ExUnitPrices} ex_unit_prices + * @returns {BigNum} + */ +declare export function min_script_fee( + tx: Transaction, + ex_unit_prices: ExUnitPrices +): BigNum; /** * Each new language uses a different namespace for hashing its script @@ -351,83 +274,81 @@ declare export var ScriptHashNamespace: {| /** */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** + * Used to choosed the schema for a script JSON string */ -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** */ -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 |}; /** */ -declare export var RelayKind: {| - +SingleHostAddr: 0, // 0 - +SingleHostName: 1, // 1 - +MultiHostName: 2, // 2 +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 |}; /** */ -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 |}; /** */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 |}; /** */ -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 +declare export var RelayKind: {| + +SingleHostAddr: 0, // 0 + +SingleHostName: 1, // 1 + +MultiHostName: 2, // 2 |}; /** */ -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 |}; /** - * Used to choosed the schema for a script JSON string */ -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** @@ -453,6 +374,46 @@ declare export var CertificateKind: {| +VoteRegistrationAndDelegation: 16, // 16 |}; +/** + */ + +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 +|}; + +/** + */ + +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 +|}; + +/** + */ + +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 +|}; + +/** + */ + +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 +|}; + /** */ @@ -466,24 +427,63 @@ declare export var GovernanceActionKind: {| +InfoAction: 6, // 6 |}; +/** + * JSON <-> PlutusData conversion schemas. + * Follows ScriptDataJsonSchema in cardano-cli defined at: + * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 + * + * All methods here have the following restrictions due to limitations on dependencies: + * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors + * * Hex strings for bytes don't accept odd-length (half-byte) strings. + * cardano-cli seems to support these however but it seems to be different than just 0-padding + * on either side when tested so proceed with caution + */ + +declare export var PlutusDatumSchema: {| + +BasicConversions: 0, // 0 + +DetailedSchema: 1, // 1 +|}; + /** */ -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 +declare export var RedeemerTagKind: {| + +Spend: 0, // 0 + +Mint: 1, // 1 + +Cert: 2, // 2 + +Reward: 3, // 3 + +Vote: 4, // 4 + +VotingProposal: 5, // 5 |}; /** */ -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 +|}; + +/** + */ + +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 +|}; + +/** + */ + +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 |}; /** @@ -1371,49 +1371,25 @@ declare export class Bip32PublicKey { free(): void; /** - * derive this public key with the given index. - * - * # Errors - * - * If the index is not a soft derivation index (< 0x80000000) then - * calling this method will fail. - * - * # Security considerations - * - * * hard derivation index cannot be soft derived with the public key - * - * # Hard derivation vs Soft derivation - * - * If you pass an index below 0x80000000 then it is a soft derivation. - * The advantage of soft derivation is that it is possible to derive the - * public key too. I.e. derivation the private key with a soft derivation - * index and then retrieving the associated public key is equivalent to - * deriving the public key associated to the parent private key. - * - * Hard derivation index does not allow public key derivation. - * - * This is why deriving the private key should not fail while deriving - * the public key may fail (if the derivation index is invalid). - * @param {number} index + * @param {string} hex_str * @returns {Bip32PublicKey} */ - derive(index: number): Bip32PublicKey; + static from_hex(hex_str: string): Bip32PublicKey; /** - * @returns {PublicKey} + * @returns {string} */ - to_raw_key(): PublicKey; + to_hex(): string; /** - * @param {Uint8Array} bytes - * @returns {Bip32PublicKey} + * @returns {Uint8Array} */ - static from_bytes(bytes: Uint8Array): Bip32PublicKey; + chaincode(): Uint8Array; /** - * @returns {Uint8Array} + * @returns {string} */ - as_bytes(): Uint8Array; + to_bech32(): string; /** * @param {string} bech32_str @@ -1422,25 +1398,49 @@ declare export class Bip32PublicKey { static from_bech32(bech32_str: string): Bip32PublicKey; /** - * @returns {string} + * @returns {Uint8Array} */ - to_bech32(): string; + as_bytes(): Uint8Array; /** - * @returns {Uint8Array} + * @param {Uint8Array} bytes + * @returns {Bip32PublicKey} */ - chaincode(): Uint8Array; + static from_bytes(bytes: Uint8Array): Bip32PublicKey; /** - * @returns {string} + * @returns {PublicKey} */ - to_hex(): string; + to_raw_key(): PublicKey; /** - * @param {string} hex_str + * derive this public key with the given index. + * + * # Errors + * + * If the index is not a soft derivation index (< 0x80000000) then + * calling this method will fail. + * + * # Security considerations + * + * * hard derivation index cannot be soft derived with the public key + * + * # Hard derivation vs Soft derivation + * + * If you pass an index below 0x80000000 then it is a soft derivation. + * The advantage of soft derivation is that it is possible to derive the + * public key too. I.e. derivation the private key with a soft derivation + * index and then retrieving the associated public key is equivalent to + * deriving the public key associated to the parent private key. + * + * Hard derivation index does not allow public key derivation. + * + * This is why deriving the private key should not fail while deriving + * the public key may fail (if the derivation index is invalid). + * @param {number} index * @returns {Bip32PublicKey} */ - static from_hex(hex_str: string): Bip32PublicKey; + derive(index: number): Bip32PublicKey; } /** */ @@ -2190,9 +2190,9 @@ declare export class Committee { static new(quorum_threshold: UnitInterval): Committee; /** - * @returns {CredentialsSet} + * @returns {Credentials} */ - members_keys(): CredentialsSet; + members_keys(): Credentials; /** * @returns {UnitInterval} @@ -2745,89 +2745,14 @@ declare export class Credentials { /** * @param {number} index - * @returns {Credential} - */ - get(index: number): Credential; - - /** - * @param {Credential} elem - */ - add(elem: Credential): void; -} -/** - */ -declare export class CredentialsSet { - free(): void; - - /** - * @returns {Uint8Array} - */ - to_bytes(): Uint8Array; - - /** - * @param {Uint8Array} bytes - * @returns {CredentialsSet} - */ - static from_bytes(bytes: Uint8Array): CredentialsSet; - - /** - * @returns {string} - */ - to_hex(): string; - - /** - * @param {string} hex_str - * @returns {CredentialsSet} - */ - static from_hex(hex_str: string): CredentialsSet; - - /** - * @returns {string} - */ - to_json(): string; - - /** - * @returns {CredentialsSetJSON} - */ - to_js_value(): CredentialsSetJSON; - - /** - * @param {string} json - * @returns {CredentialsSet} - */ - static from_json(json: string): CredentialsSet; - - /** - * @returns {CredentialsSet} - */ - static new(): CredentialsSet; - - /** - * @returns {number} - */ - len(): number; - - /** - * @param {number} index - * @returns {Credential | void} + * @returns {Credential} */ - get(index: number): Credential | void; + get(index: number): Credential; /** * @param {Credential} elem */ add(elem: Credential): void; - - /** - * @param {Credential} elem - * @returns {boolean} - */ - contains(elem: Credential): boolean; - - /** - * @returns {Credentials} - */ - to_vec(): Credentials; } /** */ @@ -3585,89 +3510,15 @@ declare export class Ed25519KeyHashes { add(elem: Ed25519KeyHash): void; /** - * @returns {Ed25519KeyHashes | void} - */ - to_option(): Ed25519KeyHashes | void; -} -/** - */ -declare export class Ed25519KeyHashesSet { - free(): void; - - /** - * @returns {Uint8Array} - */ - to_bytes(): Uint8Array; - - /** - * @param {Uint8Array} bytes - * @returns {Ed25519KeyHashesSet} - */ - static from_bytes(bytes: Uint8Array): Ed25519KeyHashesSet; - - /** - * @returns {string} - */ - to_hex(): string; - - /** - * @param {string} hex_str - * @returns {Ed25519KeyHashesSet} - */ - static from_hex(hex_str: string): Ed25519KeyHashesSet; - - /** - * @returns {string} - */ - to_json(): string; - - /** - * @returns {Ed25519KeyHashesSetJSON} - */ - to_js_value(): Ed25519KeyHashesSetJSON; - - /** - * @param {string} json - * @returns {Ed25519KeyHashesSet} - */ - static from_json(json: string): Ed25519KeyHashesSet; - - /** - * @returns {Ed25519KeyHashesSet} - */ - static new(): Ed25519KeyHashesSet; - - /** - * @param {Ed25519KeyHash} key - */ - add(key: Ed25519KeyHash): void; - - /** - * @param {Ed25519KeyHash} key - */ - remove(key: Ed25519KeyHash): void; - - /** - * @param {Ed25519KeyHash} key + * @param {Ed25519KeyHash} elem * @returns {boolean} */ - contains(key: Ed25519KeyHash): boolean; + contains(elem: Ed25519KeyHash): boolean; /** - * @returns {number} - */ - len(): number; - - /** - * @param {number} index - * @returns {Ed25519KeyHash | void} - */ - get(index: number): Ed25519KeyHash | void; - - /** - * @returns {Ed25519KeyHashes} + * @returns {Ed25519KeyHashes | void} */ - to_vec(): Ed25519KeyHashes; + to_option(): Ed25519KeyHashes | void; } /** */ @@ -5305,9 +5156,9 @@ declare export class MIRToStakeCredentials { get(cred: Credential): Int | void; /** - * @returns {CredentialsSet} + * @returns {Credentials} */ - keys(): CredentialsSet; + keys(): Credentials; } /** */ @@ -6100,9 +5951,9 @@ declare export class NativeScript { * Returns a set of Ed25519KeyHashes * contained within this script recursively on any depth level. * The order of the keys in the result is not determined in any way. - * @returns {Ed25519KeyHashesSet} + * @returns {Ed25519KeyHashes} */ - get_required_signers(): Ed25519KeyHashesSet; + get_required_signers(): Ed25519KeyHashes; } /** */ @@ -6152,6 +6003,44 @@ declare export class NativeScripts { * @param {NativeScript} elem */ add(elem: NativeScript): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {NativeScripts} + */ + static from_bytes(bytes: Uint8Array): NativeScripts; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {NativeScripts} + */ + static from_hex(hex_str: string): NativeScripts; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {NativeScriptsJSON} + */ + to_js_value(): NativeScriptsJSON; + + /** + * @param {string} json + * @returns {NativeScripts} + */ + static from_json(json: string): NativeScripts; } /** */ @@ -6318,6 +6207,11 @@ declare export class NewConstitutionAction { gov_action_id: GovernanceActionId, constitution: Constitution ): NewConstitutionAction; + + /** + * @returns {boolean} + */ + has_script_hash(): boolean; } /** */ @@ -6596,6 +6490,11 @@ declare export class ParameterChangeAction { */ protocol_param_updates(): ProtocolParamUpdate; + /** + * @returns {ScriptHash | void} + */ + policy_hash(): ScriptHash | void; + /** * @param {ProtocolParamUpdate} protocol_param_updates * @returns {ParameterChangeAction} @@ -6613,6 +6512,28 @@ declare export class ParameterChangeAction { gov_action_id: GovernanceActionId, protocol_param_updates: ProtocolParamUpdate ): ParameterChangeAction; + + /** + * @param {ProtocolParamUpdate} protocol_param_updates + * @param {ScriptHash} policy_hash + * @returns {ParameterChangeAction} + */ + static new_with_policy_hash( + protocol_param_updates: ProtocolParamUpdate, + policy_hash: ScriptHash + ): ParameterChangeAction; + + /** + * @param {GovernanceActionId} gov_action_id + * @param {ProtocolParamUpdate} protocol_param_updates + * @param {ScriptHash} policy_hash + * @returns {ParameterChangeAction} + */ + static new_with_policy_hash_and_action_id( + gov_action_id: GovernanceActionId, + protocol_param_updates: ProtocolParamUpdate, + policy_hash: ScriptHash + ): ParameterChangeAction; } /** */ @@ -7419,9 +7340,9 @@ declare export class PoolParams { reward_account(): RewardAddress; /** - * @returns {Ed25519KeyHashesSet} + * @returns {Ed25519KeyHashes} */ - pool_owners(): Ed25519KeyHashesSet; + pool_owners(): Ed25519KeyHashes; /** * @returns {Relays} @@ -7440,7 +7361,7 @@ declare export class PoolParams { * @param {BigNum} cost * @param {UnitInterval} margin * @param {RewardAddress} reward_account - * @param {Ed25519KeyHashesSet} pool_owners + * @param {Ed25519KeyHashes} pool_owners * @param {Relays} relays * @param {PoolMetadata | void} [pool_metadata] * @returns {PoolParams} @@ -7452,7 +7373,7 @@ declare export class PoolParams { cost: BigNum, margin: UnitInterval, reward_account: RewardAddress, - pool_owners: Ed25519KeyHashesSet, + pool_owners: Ed25519KeyHashes, relays: Relays, pool_metadata?: PoolMetadata ): PoolParams; @@ -7654,38 +7575,33 @@ declare export class PrivateKey { free(): void; /** - * @returns {PublicKey} + * @param {string} hex_str + * @returns {PrivateKey} */ - to_public(): PublicKey; + static from_hex(hex_str: string): PrivateKey; /** - * @returns {PrivateKey} + * @returns {string} */ - static generate_ed25519(): PrivateKey; + to_hex(): string; /** - * @returns {PrivateKey} + * @param {Uint8Array} message + * @returns {Ed25519Signature} */ - static generate_ed25519extended(): PrivateKey; + sign(message: Uint8Array): Ed25519Signature; /** - * Get private key from its bech32 representation - * ```javascript - * PrivateKey.from_bech32('ed25519_sk1ahfetf02qwwg4dkq7mgp4a25lx5vh9920cr5wnxmpzz9906qvm8qwvlts0'); - * ``` - * For an extended 25519 key - * ```javascript - * PrivateKey.from_bech32('ed25519e_sk1gqwl4szuwwh6d0yk3nsqcc6xxc3fpvjlevgwvt60df59v8zd8f8prazt8ln3lmz096ux3xvhhvm3ca9wj2yctdh3pnw0szrma07rt5gl748fp'); - * ``` - * @param {string} bech32_str + * @param {Uint8Array} bytes * @returns {PrivateKey} */ - static from_bech32(bech32_str: string): PrivateKey; + static from_normal_bytes(bytes: Uint8Array): PrivateKey; /** - * @returns {string} + * @param {Uint8Array} bytes + * @returns {PrivateKey} */ - to_bech32(): string; + static from_extended_bytes(bytes: Uint8Array): PrivateKey; /** * @returns {Uint8Array} @@ -7693,33 +7609,38 @@ declare export class PrivateKey { as_bytes(): Uint8Array; /** - * @param {Uint8Array} bytes - * @returns {PrivateKey} + * @returns {string} */ - static from_extended_bytes(bytes: Uint8Array): PrivateKey; + to_bech32(): string; /** - * @param {Uint8Array} bytes + * Get private key from its bech32 representation + * ```javascript + * PrivateKey.from_bech32('ed25519_sk1ahfetf02qwwg4dkq7mgp4a25lx5vh9920cr5wnxmpzz9906qvm8qwvlts0'); + * ``` + * For an extended 25519 key + * ```javascript + * PrivateKey.from_bech32('ed25519e_sk1gqwl4szuwwh6d0yk3nsqcc6xxc3fpvjlevgwvt60df59v8zd8f8prazt8ln3lmz096ux3xvhhvm3ca9wj2yctdh3pnw0szrma07rt5gl748fp'); + * ``` + * @param {string} bech32_str * @returns {PrivateKey} */ - static from_normal_bytes(bytes: Uint8Array): PrivateKey; + static from_bech32(bech32_str: string): PrivateKey; /** - * @param {Uint8Array} message - * @returns {Ed25519Signature} + * @returns {PrivateKey} */ - sign(message: Uint8Array): Ed25519Signature; + static generate_ed25519extended(): PrivateKey; /** - * @returns {string} + * @returns {PrivateKey} */ - to_hex(): string; + static generate_ed25519(): PrivateKey; /** - * @param {string} hex_str - * @returns {PrivateKey} + * @returns {PublicKey} */ - static from_hex(hex_str: string): PrivateKey; + to_public(): PublicKey; } /** */ @@ -8232,31 +8153,20 @@ declare export class PublicKey { free(): void; /** - * Get public key from its bech32 representation - * Example: - * ```javascript - * const pkey = PublicKey.from_bech32('ed25519_pk1dgaagyh470y66p899txcl3r0jaeaxu6yd7z2dxyk55qcycdml8gszkxze2'); - * ``` - * @param {string} bech32_str + * @param {string} hex_str * @returns {PublicKey} */ - static from_bech32(bech32_str: string): PublicKey; + static from_hex(hex_str: string): PublicKey; /** * @returns {string} */ - to_bech32(): string; - - /** - * @returns {Uint8Array} - */ - as_bytes(): Uint8Array; + to_hex(): string; /** - * @param {Uint8Array} bytes - * @returns {PublicKey} + * @returns {Ed25519KeyHash} */ - static from_bytes(bytes: Uint8Array): PublicKey; + hash(): Ed25519KeyHash; /** * @param {Uint8Array} data @@ -8266,20 +8176,31 @@ declare export class PublicKey { verify(data: Uint8Array, signature: Ed25519Signature): boolean; /** - * @returns {Ed25519KeyHash} + * @param {Uint8Array} bytes + * @returns {PublicKey} */ - hash(): Ed25519KeyHash; + static from_bytes(bytes: Uint8Array): PublicKey; + + /** + * @returns {Uint8Array} + */ + as_bytes(): Uint8Array; /** * @returns {string} */ - to_hex(): string; + to_bech32(): string; /** - * @param {string} hex_str + * Get public key from its bech32 representation + * Example: + * ```javascript + * const pkey = PublicKey.from_bech32('ed25519_pk1dgaagyh470y66p899txcl3r0jaeaxu6yd7z2dxyk55qcycdml8gszkxze2'); + * ``` + * @param {string} bech32_str * @returns {PublicKey} */ - static from_hex(hex_str: string): PublicKey; + static from_bech32(bech32_str: string): PublicKey; } /** */ @@ -10313,14 +10234,14 @@ declare export class TransactionBody { collateral(): TransactionInputs | void; /** - * @param {Ed25519KeyHashesSet} required_signers + * @param {Ed25519KeyHashes} required_signers */ - set_required_signers(required_signers: Ed25519KeyHashesSet): void; + set_required_signers(required_signers: Ed25519KeyHashes): void; /** - * @returns {Ed25519KeyHashesSet | void} + * @returns {Ed25519KeyHashes | void} */ - required_signers(): Ed25519KeyHashesSet | void; + required_signers(): Ed25519KeyHashes | void; /** * @param {NetworkId} network_id @@ -12002,11 +11923,26 @@ declare export class TreasuryWithdrawalsAction { */ withdrawals(): TreasuryWithdrawals; + /** + * @returns {ScriptHash | void} + */ + policy_hash(): ScriptHash | void; + /** * @param {TreasuryWithdrawals} withdrawals * @returns {TreasuryWithdrawalsAction} */ static new(withdrawals: TreasuryWithdrawals): TreasuryWithdrawalsAction; + + /** + * @param {TreasuryWithdrawals} withdrawals + * @param {ScriptHash} policy_hash + * @returns {TreasuryWithdrawalsAction} + */ + static new_with_policy_hash( + withdrawals: TreasuryWithdrawals, + policy_hash: ScriptHash + ): TreasuryWithdrawalsAction; } /** */ @@ -12378,30 +12314,30 @@ declare export class UpdateCommitteeAction { committee(): Committee; /** - * @returns {CredentialsSet} + * @returns {Credentials} */ - members_to_remove(): CredentialsSet; + members_to_remove(): Credentials; /** * @param {Committee} committee - * @param {CredentialsSet} members_to_remove + * @param {Credentials} members_to_remove * @returns {UpdateCommitteeAction} */ static new( committee: Committee, - members_to_remove: CredentialsSet + members_to_remove: Credentials ): UpdateCommitteeAction; /** * @param {GovernanceActionId} gov_action_id * @param {Committee} committee - * @param {CredentialsSet} members_to_remove + * @param {Credentials} members_to_remove * @returns {UpdateCommitteeAction} */ static new_with_action_id( gov_action_id: GovernanceActionId, committee: Committee, - members_to_remove: CredentialsSet + members_to_remove: Credentials ): UpdateCommitteeAction; } /** @@ -13853,7 +13789,6 @@ export type CredTypeJSON = Script: string, ... }; -export type Ed25519KeyHashesSetJSON = string[]; export type RelayJSON = | { SingleHostAddr: SingleHostAddrJSON, @@ -13984,7 +13919,6 @@ export type GovernanceActionJSON = InfoAction: InfoActionJSON, ... }; -export type CredentialsSetJSON = CredTypeJSON[]; /** * @minItems 0 * @maxItems 0 @@ -13992,7 +13926,6 @@ export type CredentialsSetJSON = CredTypeJSON[]; export type InfoActionJSON = []; export type VotingProposalsJSON = VotingProposalJSON[]; export type TransactionBodiesJSON = TransactionBodyJSON[]; -export type BootstrapWitnessesJSON = BootstrapWitnessJSON[]; export type RedeemerTagJSON = | "Spend" | "Mint" @@ -14001,7 +13934,6 @@ export type RedeemerTagJSON = | "Vote" | "VotingProposal"; export type RedeemersJSON = RedeemerJSON[]; -export type VkeywitnessesJSON = VkeywitnessJSON[]; export type TransactionWitnessSetsJSON = TransactionWitnessSetJSON[]; export interface BlockJSON { auxiliary_data_set: { @@ -14055,7 +13987,7 @@ export interface TransactionBodyJSON { network_id?: NetworkIdJSON | null; outputs: TransactionOutputsJSON; reference_inputs?: TransactionInputsJSON | null; - required_signers?: Ed25519KeyHashesSetJSON | null; + required_signers?: string[] | null; script_data_hash?: string | null; total_collateral?: string | null; ttl?: string | null; @@ -14088,7 +14020,7 @@ export interface PoolParamsJSON { operator: string; pledge: string; pool_metadata?: PoolMetadataJSON | null; - pool_owners: Ed25519KeyHashesSetJSON; + pool_owners: string[]; relays: RelaysJSON; reward_account: string; vrf_keyhash: string; @@ -14334,6 +14266,7 @@ export interface VotingProposalJSON { } export interface ParameterChangeActionJSON { gov_action_id?: GovernanceActionIdJSON | null; + policy_hash?: string | null; protocol_param_updates: ProtocolParamUpdateJSON; } export interface HardForkInitiationActionJSON { @@ -14341,6 +14274,7 @@ export interface HardForkInitiationActionJSON { protocol_version: ProtocolVersionJSON; } export interface TreasuryWithdrawalsActionJSON { + policy_hash?: string | null; withdrawals: TreasuryWithdrawalsJSON; } export interface TreasuryWithdrawalsJSON { @@ -14352,7 +14286,7 @@ export interface NoConfidenceActionJSON { export interface UpdateCommitteeActionJSON { committee: CommitteeJSON; gov_action_id?: GovernanceActionIdJSON | null; - members_to_remove: CredentialsSetJSON; + members_to_remove: CredTypeJSON[]; } export interface CommitteeJSON { members: CommitteeMemberJSON[]; @@ -14371,12 +14305,12 @@ export interface ConstitutionJSON { script_hash?: string | null; } export interface TransactionWitnessSetJSON { - bootstraps?: BootstrapWitnessesJSON | null; + bootstraps?: BootstrapWitnessJSON[] | null; native_scripts?: NativeScriptsJSON | null; plutus_data?: PlutusListJSON | null; plutus_scripts?: PlutusScriptsJSON | null; redeemers?: RedeemersJSON | null; - vkeys?: VkeywitnessesJSON | null; + vkeys?: VkeywitnessJSON[] | null; } export interface BootstrapWitnessJSON { attributes: number[]; @@ -14399,6 +14333,7 @@ export interface VkeywitnessJSON { vkey: VkeyJSON; } export type BlockHashJSON = string; +export type BootstrapWitnessesJSON = BootstrapWitnessJSON[]; export type CertificateEnumJSON = | { StakeRegistration: StakeRegistrationJSON, @@ -14590,6 +14525,7 @@ export interface TransactionUnspentOutputJSON { export type TransactionUnspentOutputsJSON = TransactionUnspentOutputJSON[]; export type VRFKeyHashJSON = string; export type VRFVKeyJSON = string; +export type VkeywitnessesJSON = VkeywitnessJSON[]; export type VoterEnumJSON = | { ConstitutionalCommitteeHotKey: CredTypeJSON, From 70a1803e0c536efc24b67c5d09ecd90ad0cd8bec Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 11 Feb 2024 04:56:06 +0800 Subject: [PATCH 229/349] cargo lock update --- rust/json-gen/Cargo.lock | 87 +++++++++++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 18 deletions(-) diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 65eeec7b..224eda38 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -2,6 +2,24 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "ahash" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + [[package]] name = "autocfg" version = "1.0.1" @@ -47,10 +65,10 @@ dependencies = [ "digest", "ed25519-bip32", "getrandom", + "hashlink", "hex", "itertools", "js-sys", - "linked-hash-map", "noop_proc_macro", "num", "num-bigint", @@ -186,6 +204,25 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashlink" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692eaaf7f7607518dd3cef090f1474b61edc5301d8012f09579920df68b725ee" +dependencies = [ + "hashbrown", +] + [[package]] name = "hex" version = "0.4.3" @@ -222,12 +259,6 @@ version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" -[[package]] -name = "linked-hash-map" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" - [[package]] name = "log" version = "0.4.14" @@ -285,7 +316,7 @@ checksum = "9e6a0fd4f737c707bd9086cc16c925f294943eb62eb71499e9fd4cf71f8b9f4e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.48", ] [[package]] @@ -332,9 +363,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.15.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" @@ -350,18 +381,18 @@ checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "proc-macro2" -version = "1.0.63" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.29" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -554,9 +585,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.23" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -614,7 +645,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.48", "wasm-bindgen-shared", ] @@ -636,7 +667,7 @@ checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -668,3 +699,23 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] From 4f77f7f50a675cc17d94bc0cec2017812997c5ff Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 11 Feb 2024 04:57:13 +0800 Subject: [PATCH 230/349] bump csl version --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 86e4b951..3daf314e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.15", + "version": "12.0.0-alpha.16", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 40f17ae8..c8243707 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.15", + "version": "12.0.0-alpha.16", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index b3d42e2e..a8aea1dc 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.15" +version = "12.0.0-alpha.16" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 224eda38..01de86b2 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -55,7 +55,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.15" +version = "12.0.0-alpha.16" dependencies = [ "bech32", "cbor_event", From fc55197b8b6f3c67fb64566525f56071defd4a66 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 16 Feb 2024 23:39:59 +0800 Subject: [PATCH 231/349] fix cert script check --- rust/src/builders/certificates_builder.rs | 2 +- rust/src/protocol_types/certificates/certificate.rs | 1 + rust/src/protocol_types/certificates/drep_registration.rs | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/rust/src/builders/certificates_builder.rs b/rust/src/builders/certificates_builder.rs index d036dccb..f1f4029e 100644 --- a/rust/src/builders/certificates_builder.rs +++ b/rust/src/builders/certificates_builder.rs @@ -68,7 +68,7 @@ impl CertificatesBuilder { let mut set = Ed25519KeyHashes::new(); for (cert, script_wit) in &self.certs { let cert_req_signers = witness_keys_for_cert(&cert); - set.extend(&cert_req_signers); + set.extend_move(cert_req_signers); if let Some(ScriptWitnessType::NativeScriptWitness(script_source)) = script_wit { set.extend(&script_source.required_signers()); } diff --git a/rust/src/protocol_types/certificates/certificate.rs b/rust/src/protocol_types/certificates/certificate.rs index dfe49dd6..bda411f9 100644 --- a/rust/src/protocol_types/certificates/certificate.rs +++ b/rust/src/protocol_types/certificates/certificate.rs @@ -350,6 +350,7 @@ impl Certificate { CertificateEnum::VoteRegistrationAndDelegation(x) => x.has_script_credentials(), CertificateEnum::CommitteeHotAuth(x) => x.has_script_credentials(), CertificateEnum::CommitteeColdResign(x) => x.has_script_credentials(), + CertificateEnum::DrepRegistration(x) => x.has_script_credentials(), CertificateEnum::DrepDeregistration(x) => x.has_script_credentials(), CertificateEnum::DrepUpdate(x) => x.has_script_credentials(), _ => false, diff --git a/rust/src/protocol_types/certificates/drep_registration.rs b/rust/src/protocol_types/certificates/drep_registration.rs index ddc1ac2d..9e803c30 100644 --- a/rust/src/protocol_types/certificates/drep_registration.rs +++ b/rust/src/protocol_types/certificates/drep_registration.rs @@ -50,4 +50,8 @@ impl DrepRegistration { anchor: Some(anchor.clone()), } } + + pub fn has_script_credentials(&self) -> bool { + self.voting_credential.has_script_hash() + } } From 3756903b4ae00bf857050ca2e6a3c3dee4443b6f Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 16 Feb 2024 23:41:35 +0800 Subject: [PATCH 232/349] add block_from_wrapped_bytes function --- rust/src/lib.rs | 39 ++++++++++++++++++++++++- rust/src/tests/serialization/general.rs | 8 +++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 9688fda1..13afe025 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -33,7 +33,7 @@ use wasm_bindgen::prelude::{wasm_bindgen, JsValue}; // This file was code-generated using an experimental CDDL to rust tool: // https://github.com/Emurgo/cddl-codegen -use cbor_event::Special as CBORSpecial; +use cbor_event::{Len, Special as CBORSpecial}; use cbor_event::Type as CBORType; use cbor_event::{ self, @@ -1369,6 +1369,43 @@ impl Block { invalid_transactions: invalid_transactions, } } + + #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] + #[wasm_bindgen] + pub fn from_wrapped_bytes(data: Vec) -> Result { + Ok(block_from_wrapped_bytes()?) + } + + // non-wasm exposed DeserializeError return + #[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))] + pub fn from_wrapped_bytes(data: Vec) -> Result { + block_from_wrapped_bytes(&data) + } +} + +fn block_from_wrapped_bytes(bytes: &[u8]) -> Result { + let mut raw = Deserializer::from(std::io::Cursor::new(bytes)); + let len = raw.array()?; + if !matches!(len, Len::Len(2)) { + return Err(DeserializeError::new( + "from_wrapped_bytes", + DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 2, + len, + "from_wrapped_bytes", + )), + )); + } + + raw.unsigned_integer()?; + let block = Block::deserialize(&mut raw)?; + if let Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + + Ok(block) } #[wasm_bindgen] diff --git a/rust/src/tests/serialization/general.rs b/rust/src/tests/serialization/general.rs index 3b9e6c05..1e400a6f 100644 --- a/rust/src/tests/serialization/general.rs +++ b/rust/src/tests/serialization/general.rs @@ -634,3 +634,11 @@ fn tx_output_ser_type() { CborContainerType::Map ); } + +#[test] +fn oura_wrapped_block_test() { + let hex ="820785828a1a00101e2c1a0143a1b35820cee15d6daecaeaf320a4ddb1f7c437846f798e4a9cd08d12fb7821b175c980115820e3c87f196ce9fc40a8d929f3365e247f8f71e1981bffaa7cbdb0aa3a83dc790d582054a580ddf99f67818e0312374cef1f7dcdd59450930898d4d2d10e606b963e49825840ca5d1f988222919982b6a20f4f54ce59626fece7d7c607487762129d5196c731bcd11dfefee94ce5a60a733478970631d41bfc0620769fa7b66ebc16c8a89e5c58502855f21ba12fb101d175c376e19496e464bf37c92ec21395e5bffb35e1ae8f433f2139de166161f2b2b26afe656d3d170acfd11a535a80fca6325479d2262e208b0a4b98a01f4845c45a58fb84cb58011952de5820f2e4c6554da5b773c3f7889944fdb5b1791f8552dcafe2916041a531860e912284582039b66a10f6b78c541ea5ed6ecec4c6dd385b869026ec16c4e48414cb39cac38b0018a258409ccd6cf71a5c337f71a41904c0ea0a889a2321c94374c3a8402d8a7dd25b222abe6cb325c6b39bd63bc99fa84c094fdac2523b72f1a22081903dd047be9be9078209005901c006b35937aba451d4738486ea3ba5644d9306651f09b2012de8acc5136771fc725164ad669dd716f2726dfe138137d09feddf9450b3c51a601577bff35d0d2202c887a260855dd8310fc9365f56a4757ea7d81103d409ea0a8ad51c6ae52fc7fcf4d3d456384b7566b70a2b7bd4e21010a1ad5df12bf5d332e82c1a4a5cca39740252e0ea163f206cacf193e59ebbd0e20d621fa9913c60efe1c035d8ebaa354fbe45768339d53a4e8e04fdea79d00b869a973cfa3eeba2e2668b1dee5fcd7d13762dceb4da804fd749e5fa977ead0003a9739837aa68b80bc5a32ee015f667574a7fbe03b4bf5b027c945fa4497c01efb4ec51f3da2fb2dda33ea7dc1dedcfd2ea2c0a4da5a1c553d033033f4986e2ef5c09bbe326a25e5082c1eec406aeec8105869a9d46a83689a2e026e6e31d4037e700ffeb2920bcab88d1a400976881d17cd84582521482db0be460fb43de88e40a4ee24745ac92ab8b40329bde1d855404478c9f59b05e6322f3640ad6f40d7a771fc6d58e94f8fd0006d54272e36a30034b14327c2e6ffb92ead2f8a4165a3e4a1c44de677829e8e797547b3c0bac4b5ea89cb86c01d5b1e67aee3ba36b8cf9617484db2e4d1bfc37fed1fabb73ce3c9fa600d901028182582088c310befd2e8c9b33b340a56f4ea8141689c16eddef5d9c606055ca35897bd600018182581d6052e63f22c5107ed776b70f7b92248b02552fd08f3e747bc745099441821b00000001f09cac72a1581c34250edd1e9836f5378702fbf9416b709bc140e04f668cc355208518a1494154414441636f696e1916d6021a00030739031a0145283409a1581c34250edd1e9836f5378702fbf9416b709bc140e04f668cc355208518a1494154414441636f696e01075820e2ea39e82586fa40304df3c2cfc753c6ba8aca62e780f01a0519c34c6d7c25f5a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe185b0181a2005839007ce8986f5f3fb526a6d35d32edac0b6c8624daab6928df1964459c2723bcf2892e8182a68e3aac6f9f42ed3317d115ebad12a17232681175011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe185c0181a200583900f7fa5ddf2c3c46ed4d913812d38dd43d585adfa884938adaa7a075dd1bf1e138f2f8beabc963c94cc28ee8ed4b41744601f2edaf50b21efd011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe185d0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18600181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18620181a200583900189f009d9536b1f52f0629bea3323f48df0eacdff68726f1a32edc49db89995ed3aa88dcfb43790e2e51761fcba7e8594bcc67684f52d524011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18630181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820a944bb37a59451f9a47d5c8888a8a1145527ffb5d45a17c1df40926a42ad08330001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a400818258206a7e3a926eafa74f72c0d6a721dfdee7a7202b1fac4eee12d8c6dd030217890b07018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001eeb2890a021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18640181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820a439638a9f8e0f52e153126e8b794b7514f3a0921b08b611f3866a1fc75b7a560001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4010181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4030181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4020181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4040181a2005839002b11f0e68a65cd6a243f1a5ec9d597ba972675a00bd3172a7ddc0293b1d312a60b3824d1820dec5ec769c4af7d7598387c16ca5ba6259f46011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4080181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a400818258203298fb7878ab004c1a4b369eae7fc89abca6342f06557cebf6c89f2d8c21aa9900018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001b3152865021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a40a0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a40d0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a40f0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a40081825820dcdbb7a98286f5d48673c95b05f441bc40731b1e4c3429d192f0c6b7fc3749d100018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000002186e835b021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4130181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a300818258207e4fddb60c2034bff37bb7069f9318735fcf4de03e01e9f92251c96dc59318750001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a40081825820705ab68071f9af1d314e74a053e39a52f3fdf96f9a1280dab30d45f04c05436d07018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001eeb2890a021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a400818258206fe0c3eae23f779b0694747ed28612f47271b45e84bb3d23c11c1ef2e90fa12100018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001dcd122b6021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4150181a200583900e698ee1c7d4361c6faf62716dca0d435eafd0b25e369a5d68455beaa0f5c16e3e747e7c5a9eb3ff189c0e330683665de9326d2ffe35d0631011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4160181a2005839005bed6070c549f1560cb89361564cd2be7b36536e8da868a218d514e5fd2e3e48dbc0278cc58e47ed50a1ba90cee61ab22c8f4a639c913d4b011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418180181a200583900ab3cd541317d83d072bcc38e1294166dea5d97ce453424b84c547cfc101c5bfa799985a6e96adbb5859e90cbe4a0e4edcbef408a3622558b011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4181a0181a2005839003b3ff2a2d98519fcf53c7abb15b6c4dfe76209c52e4c2065b33b97bc465f9e3a6c6c3a8eac01d39f519b9bf3bc031480936156b7cb2e45c8011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4181d0181a20058390050fc315c9c141b4da62b10525cf5049e8ab1bb8bd96903a6d87c5272bc616bee900ed3135eb065a11faf2100670f0182ae86827df52dba96011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4181c0181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418200181a2005839005deef04c1b44c606775db03444beae0f10c75f437c131628d264b17c439dc3dbc39b8bb91832384d44263001591fd806df73b413da861fd3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418210181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418220181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418230181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418270181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418280181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418290181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4182d0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418330181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418340181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418350181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418360181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418370181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4183a0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4183c0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418460181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418470181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418490181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4184a0181a200583900189f009d9536b1f52f0629bea3323f48df0eacdff68726f1a32edc49db89995ed3aa88dcfb43790e2e51761fcba7e8594bcc67684f52d524011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418520181a2005839005c85eb9c0aa544a6bb5d1577c7a588c39caca885c8a3a9fceb0933a2cd1a02667d16df1e109350555c325023dbfa31fd9a4a8b99ff904d96011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418530181a20058390030a33756d8cbf4d18ce8c9995feca1ea1fc70093943c17bd96d65fed0aed6caa1cfe93f03f6ef1d9701df8024494d0b3b8a53a1ee37c5ab2011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418540181a2005839001da17fce0b5ae3e7feae117785eb78c77b6272be34a3d381a2722154d29c294b138005ca78de7b329ed6d2763a74a3fa1710a403e18fcb4a011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418560181a2005839001da17fce0b5ae3e7feae117785eb78c77b6272be34a3d381a2722154d29c294b138005ca78de7b329ed6d2763a74a3fa1710a403e18fcb4a011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418570181a20058390098bebc68cf6f12a7aca6531cef75d83c1b6e323485146195ffdd727dd99bbe7f44fd382de2ca6d9e5e9cc26f940decdb1b12b1a98e343274011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4185a0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4185c0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418610181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418620181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564050181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564070181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d00045640a0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d00045640b0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564181a0181a2005839005746c1b032f826b5e5256357a713a7ca63988fe2ff862e0396993b97ef0cbd5199d0e460725b3e79d371deb42110d40b778d3bf162777d4c011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564181b0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564181e0181a20058390020de866f290f45141315081d903f3eb3c06f3735e2a5b70f6a138462ada99823bc02291029853dc5338bc6e62b0540dbea54d9384f372639011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418200181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418210181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418230181a200583900057fd21bf903c585ea95dd927dee373b4cc1febc61874c48571dfb88a0a307af2a3e6a55a238fe323f9e54be10c54a8a8b25939a4f9ab35a011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418240181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582043c59e533d0934a6878a81403ec71a2225bb22d0764471cac8b5545120b475760001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418250181a2005839008f221a3021b0c09c57336733b0411d9d664e5d5e259096033a9d4bbecbce4335fa28195472386e53f0c3ab74d5cd254797d1100e4b1a33b8011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418290181a200583900d804dcdd0b0ec6ed0d8d2cd210a03b14f87c6849024930a8d6c91cf551a6a756817f0a3e1a1410730acf27202e7a9b63de26087e5cf466a5011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182b0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582072af166d0cd8883c9abb1189ae93acb1fce482ca57cad9b14711bca9627b98d80001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182d0181a2005839001c4595c4f3180180c9e822f1ac0f2955dd329eeeb94752a84281ff5295558528c6e1f7f2e16d94b74d227b9fd709edd2aeb0ab1556db75fc011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182e0181a200583900c008dd489b67e0a774fe18d79ee8d1e280264933d3b31ba44cb37755dca94fb45aa2192ab26eff8409ea010fa2d4761efa92437e0d5b6b60011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182f0181a200581d60fc38cce3448bf3d2790ca85d6b09026f7c86f21095c31f9925cf49a0011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418300181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418340181a20058390023a6fcbc8affc61518cff034c013aecf083dc64fe673ffc95cc9fd9e1fad7e0b1d0dd8820703a4f59c2488d148193a48d8fdc23a6dca8137011b00000002540be400021a00030d40ff9fa200d90102828258201287e9ce9e00a603d250b557146aa0581fc4edf277a244ce39d3b2f2ced5072f5840ae4cc1168265e2f60fec9ca9b644eaa42a77e65a39176e04aef29b01e25653a307d39ba61761f8d1ca44696e1d6bdf7a0679413ea3c448f76268e6eb02074102825820742d8af3543349b5b18f3cba28f23b2d6e465b9c136c42e1fae6b2390f5654275840112c95c93013e63fa73ee6a645fd522808d4dee019626e395a8042755c15fb1824e1503c17ea843a838809f55822366b05bce2e378d0b955e66d625c8e9acf0001d90102818200581c45d70e54f3b5e9c5a2b0cd417028197bd6f5fa5378c2f5eba896678da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584005383334e98e9263b93ffeb3e5908dbd5657caa67d32f9964d7f91dbda76fff164cbeabb981beef470d0d3e1724b85847e6fbc1c039084a817110eabf9d29e08a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258406151f0d0cae4ef0ace62dc03300dcee276765c1b493ac61f770d0633f0f71fe0d642ef29b593c511034a847dd569c56a0278e063c46d6d060abad4e6baf4b705a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840cf518f30d291871a0277e367534557205cc015d3a0d78070e1aee298aeaae3e81d70b42c464a63fa741b5300b48c1699dfc39fdf07f96b8eb240c7d6d3267805a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584056185de4c1d012d322e7e82ae98f24887ed7264f262db53f019e5900b9110a439e5a462a75be036f9f04b0ddcf09decb0894c7b6b9ff17ab4cae8184072d690fa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840ab78c606155b6aacbcf6692a18d97dd8773b4ae4c96684e4abb9cc59233023f67650ef7259069deddb65ba770ac3a1401d169ce33ec9483b8ebb9e83472e2c06a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840e21574b02002efcfe81382326aa98a0a971327ad4049690a04985400fcb14db7adc8149a0ce4dbfb5afa0d240ed9da23f15c1020d2826f50fc579a10a3662d0da10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840e64e3c19644edb6e788112ac75b4426ef94d535f1ffd9a34e86745777feaf083dc8e847a62634fef320a08b566c24ea26e8dc9e7b49fc456554215cedc0d3508a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840f49fd8eeaa366873aeb2530b2bbcbf7c5970866162ae7250c4b913e19062de1396ed70d1e32a4605071bac11c2cde3fec1dc5b37044cbea073668fe5c478400ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840f0ddd023e0dbda32d296b359db809b0088246e512fd34c7c0cc4b5ae974361873e02330e955eaaf97117525bcb3cd014bb70810f8d0d62a28c3242c86d8c3a08a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840615ee0444f039f02b26791872d6cd5562728cdc6dad02acc71475567b09f3d4b4655c601bf816ef6d11b2f3f81eeb6db09d800bf1bf4e2daf29493338c232901a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d62bfd428359f4cd04950cc73f574f0ec1c613284fdff8028ed3d876b18b69335beee9792410c6dbdc1b196b4703f250fbaeb66569869ae97d7ee843b9053405a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d813a836cc44c70647b2e7941fb72a4f720f16aca17e155a6c6a6f9bf175b1e49a3beff6edcfb0c442cc24790a12ee0b1d499a32fdbfc0a850f4846708ea340da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840aae6ac20cd419eaa7f3a95144f9ccdb46401a0db295d544e920a54b5c24fb63197fde03f12174800c3cf5318a73d92ebc53c2ba97803766892add32fd9feb400a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584071d223fd255df1e912a9c0a8230ee9f0ac95d0aa325cd31e50701ac355dfb5f3fbb27983b372c1410156eeba9163aa0f8a9787dab8c44e7afd4e2d07459a4708a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840b7f821c0ff66fcbbe7c61f43725aa2234297d6765e002d0130301cba13465fe89f59a596549725542445c76d17cedc9c9cfea8b8862d41405646d725dabc7d08a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e4584045830e5de108b9353b0c4c561af296e79eddb26b8ccfb18c5bd9fac1baf8d477691229c0bb9ea212ab56d9ae76c92de6ae50686fc0619510b8c35fb69c6b4402a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258400635ac784fe71d2f7927114edfc709dcb56013617df4edb9b6b770b067e7709e8abfd4cdcdd61512894fcf02f16e1d72bfe60fbfb86b815631d791bab132b909a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584032d67fe72feaf2175455815bbb624ee1b93f5efce905280158db94bbb2b5371d9eaff1bed6eddf9eafe8ff64b55f1d7213294bdb459e0b00c437edbcabf4cf07a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258404533de52e9e3f51e39951c9e197f6900081e98f38f3af5c4a7fe9219f8c311eaa43942b7a290ecbbbdd0bf4ef4ef1d11c39e6de4083c86892a6026c27bcf2509a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840d46541920ce2c31ffaa00cb20e8f5f00f48b6b8aa5cda67d22ea4bf12fd318461a0d8c25ee04cd7446e18f0de59b0fd4f6631e29bc8207073f2404793ae5f108a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584041bcd52ae44a3ffaa1abe1cab6c8b21f8010e2f1aee1d8651b9f6e94aabf5b2dbcedb45dd154b78dce1c5b9679956dd25153a0d945d3eb83c1de3b713e721008a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840027da3169c9c1fb9a67104061698bb0dadb2f58b660af4b461e7353fab1545a3d03157e077a388ec8556176239df3241255feb1f13b5e406bf7c3ad3af7d4202a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e458401ae63dc54e511965f7010971de7fb99585afe492cb8084b395ee01555c1e5657ab08a24be0f70d4e9cd1bde2a6ae31815c5f64025c0415afe2d503b2cb5b3e0ca10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840d2211679ca8e9cc5de71b21bac2b58fd355f5cbd2b42ff31ec37af77b776fb77c64fa76a830f240c29a4b95ae6bff9c58fc6bc2b3d18b57a2af11710ae6e3006a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584084bb7bf64ecea446d6beca88bfa2c7de71d8899e96006920c4c18e52f042aa71e1d27e60bdb6d9d6b1aa2e3330f59ee95b2c001909ff8994ea1fe4e5cd7a760aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840c6f3d6194a2fdb2a50417f80dd020adf866c91a102f22eb6bc66f5131292a1a42e9a3550e18e06cb17bd153c08f55a6cce3a1c82052ec9197495900f3ca4f407a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401a28cac7e80a657563e1433459f369bb0cb05e7e3ead78378dfc2ad15baa344e76e1ac0ca631c67848e81896fd6838b3821961928911635ca069f12c05772a08a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d201ce4ca5572db792d1563ef3614f2e2b27072e4751327f4a8f75201183a189ac57cdd9399474850e87031c7545c896ebab3983434bb6005690b9ad8fd9d50aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258403f45e44aa7457c714599f0100702ec265e91493e30c57ba4f1f74d912858bae8fb71fdf2faddf865c816cb0218eda0db17b707c8f429290f1a1c02b6a4450a0ea100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840e16b1d8f5992fda268c9d7e5c0ab6c5d38b8abaa6b92ccae5b0d2f3079d098ab67ba9a15b27807746f3c7695091ec5bb74ba8772baae14d2786eb8a512d70201a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840628a5491c5d0b4e0202b7aae87a343afd642345b823252355f6d392d8398d2174c141622e3de167b4f82c3cb8b4e8105b341851005d2ec0c1e35c354006a910ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258408ad2ee919f520a903764e0322800f7c086f870374f063d2e62ad1dfbf54e71305d90371abe3a196132e123b9248281f2d676fb29442f80249f644ce1185dfc03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d53bf84fe8712171151bb6d5f988d76428292639737d817986b46d629aea6eac2a90675cbf0347ec004ce23f9ca0b2dcff5c6d1be91ab478634de8ba8ab96102a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258404702623a2a94b9efbc03dc7d506c4bd70c1e0fea8b21f3b76c592883f0c364ffc12215e59f9ea4d2eed2e786376e6128650b4c9c3f6ad9419f070fb458efa10ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584072bb89ee81a7bcc4a866ae498d3ca076d5d5a885547c7f5899b8b59b3077310f58df420e470bf36d4ed5beaaf30eb361f04ed578cdbd0ef04f7cb573f0c0770ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840e112bb46921840820f4d5b40ec45699bc1b818ca8fe77fcc222a6fa1edb2425487f32e2039e2cf6077ce1e8e2e0b0d0581c64fb866c1c183344af131ccb9390ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840039329e261d8386f81a28f5ef5062196a46b5d4389b06bde97e662f69e37812c3ee75352f392121f58e76e5c1e1649656632b01ea46f932ccedcee102d625001a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840c1dab5e2482101ad1bd04f4018425c7133171aaf1274573ed35305f4e37bddadb3636f0aa098d2c0b5f615e8eb629bb94afac5d4c4c0743dba16a847d898b905a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840abb898b3e1ae3c4c9d068a4517b83a070d4037f979b6365ea5eb368e7d43b3fd2152fb93a462fdc553f973d90ab136332057fb66ea529d4fbc53e7f082b6fe03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258404a09ccfd9c09c6a453f46c721d280065081d89aa4b84fc809d75db1b923e78963bcbf36d64786d8c09c527e90da744e83116617b2e18d9145bac6cf66f876c08a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258408df2408adbd8b4c990a913b9ed2455c9de72d561ddb8f3ec0da5d1513f417a2fcee9ea9ace30cb840d37950c41455bd3655d12d534b70a6eac7034950f821108a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840534b54cc145722e3f7a62935d84c025e17e31c4b08d3f3fb16bb7673d37e9afb07fbdb5ffce5aeef743376bac161973e565e1c12db97bcd879cd7e9030c2a00ea100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840664fd5d8bc5d93509d02104f39e7a22c6cd894f49935cac9e662a9202b9a64baa9f55cd8aa07d3d1e095e9b974c59c0a8c50d14b0d077d70e236ad5cf52ac104a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840469cdadb48349224303d14980cab5c2ae5dacd0f6e36714d8dcb9ca85fa4eb688bd7b1334e30f8718178f7f36d8c5b204e0f9cdce5f88762fc2cbe2cb28c1d03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840f330820de229a476e1b3f84dfcf9ad98264070212e6e2d61d8b05afb1e12a1426cfd7cb0b284db237d5882cecd6e8f1fe2cf9ddc06783242812178bcb053a105a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584066b89001a28583bed59dbd07d359333207eb74d39ee092c0bf1da4351da64d38c9938a3682bb52a4253dc76074767b4cc2bc1eb2a31bbe6be3c45a5c52cbdf04a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840f365b299297ade5117d72156050cb81a76ba0b859cb46d0f2326c4071110440108b20390f878ba082d41217b2a8fd5f1435b9ba48d176ad5dcb6faff54976b0da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258407fb0b1f28d6ca64a29c6c7a51a2ab3436809b5038c06b8204104e3b98afa915246f742e2f1bd569f5132d2bbdcaeae68215a0b0f17f6367ce4eea37ed951ec01a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258406e6d2263c440486fc1b3c2aa930e519f20b70f70c28cb532d031f63cefc55c56f4647b10dd6390aa0d0f2ba75bf6cbe3ce2fc6d928dc4db74388f1e5e3057b0ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840dbb299923c24a70ae10dc637d862b750b3e6548e64c590674d2ceb87b7535199ea8dfd024694d26ae1dbbca683b1a4ba90af7d1680a9b8e4819a2ee6229e2408a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258405b2397d031c48f56b43416daea99dd3d8bd1733cb83c2a688dbe8b5dd9bfe64d596280d71973d7d540e929262dafd79b14954b855635fe845642090241003503a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840482c9089f2d60eb069432bf7f7213178a6fe3d52d37a4fa5aec677875bccdac64de7a45c6eb0bd4996414412b12d3e887a1b391e775ef56c47d53f9c944d020ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401972d18c1e9c62837121efafddc2ec778a3a8f9ec5f534c9922778905d8f809609d6c92e427852d8b5f822ad590fdeacf3877c8056f0768b44b025a2b79e7704a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258409b7141b69a493bc4d597a645ed488325492772ad4c3cd5c5c7805a5d951a4b6ed960ea27428d1add867fe7c209f4e65000bdfa878bd7a4357b223e9c55af450da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258407ac2d7823887de83bca86216e424ccb63fe9f4fa1f106bffc6afa388e91845c97177c410f1a8ca5ecd9f2701c42f5f9dd2faeb0ecf2163a37521badc8a6c1b03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840c49b6714ccbbdebebb9461a2efb39b9ac5e00a389aadfb2a1b4fe384733610c45e1f03825f65e182988da97659a71e378d49d17fb93d76b80d579b7d49399b06a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840b53ea3508cbd7da47fef05e98c0b31b13ec33de4596ba4061a8e04d91b1015c49f328da58084a6f573d93cdb7aa0972a1a1936a69ee7362adf65df3eae4e2400a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840b1c6b15b311423aa83dfaebe118d1a2a3ff006399f2a63fa82f0d0e0c12bc2b844ec78f5bc8baeef588d15b2237db48cbfa48361a6d630052c9b68e62e035601a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840bb544721cd95655497375390da19fbd87b3c63a4edf333688e2fee7935e96b6572f84b81d80fee5239062be6d3c6a75a5f0c50696d3c6663d26cecdfd8fdc808a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840a7018dfacec705459856bc706b7d05d04c56867fb64dfd0cf97fa980e881cc609e91cf6df204fb6906f860e5cf390e0290d302b6231664aad8c2b4cb30090609a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258403ddf27cce21fbf1a361233d2bcff92ecc9d3cce64c3d8186495e3509b843a0a326f528be8241b8557bf3cdac9c304fcf0fa8fd2a8e389d6acf9fc62b5626d705a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584013bd40ae7383feb674c2cd3357122aec3f6efe17b9b4f25c47cd3dfec194d0c4f20a52cc30fb92245c1a20a962772808f3dc6ee51261c86af16879a1fed2210ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840a1cf100aff45ee45c0f868214187640c8c29cb005c7aab7100ff86338d78f972733a611b4e0dae436fe9e1493d6ece69c35ada3cc6506e730ea1bae277468108a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840667d6d2987788454c41f2e86867fe98e1fd48aa789fbf9cf2208f927a8f9941d0384ebf3e3e45ee80c49934aad9b6ccaa13179b69f35b9acd21b55f56caff80da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401cd5c48fa46d8f0fb07c7737b7719d1fba5729478be3eef3e2e19942c4d6d54b01a569eb34d4f4be84a2f6961832ec17bade0511cbc01f5db5749a09bb4d8808a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258403bb5ddd91b5f5d7366b41330bf5bbbf7cf7d703bd50376ac21b07c6da696562266361678c06247a57111c63bc1fe58463a8c125e0d117bdf05cd4fe57bb8b90aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840397067045ffe0cf7126a5f73f228e1bc8721c617ebb7c41c1bc2f7b6c8cc50bf2370bc1ee679bcb0581e11da1e186504f2e3f3322fddf40a1863067ffc5e2903a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840831f5ea5dd354f5a522e044b53aa1966d036871d5a3b7d2323e404996907a33aff5aabb9db22301064033045cbf14c91d29de84b8fbbb75683ff1cb51fd0920aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401e8cc65db39cb5e9d54dac50cda84c55fd2f989f667a11dc46521768ac2f46a27a70173a92e849ee621ebe3025d87088528e7450b8312d678b6249f5a124f70fa10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840f4835bbcf5459db0826e27ea95d3ac31f7bea56c0253716212ef421995c7546a963ac89dc6cffad75692a149372cbdeaa19a9dcd171ac423711e8d71c495d703a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258408039411659145a9fb3863b2ae2f3890009bf004332f58daa6662368a7378d215cc7f40569284d5b86c5a7be210cdcb5551633762b5a7d3f8ad2095a220fec609a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584002c9ec1d95d0464eba5f4a656d72b55a92a80078e83f2f47682729af0fc782a68f3f31db7c64018ae8fbd36c5ac72d5573357a7578359056b9d3f9a29467d80ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258406f176d0fdb8768aad902c8fc115eb797719ef62a93938d7f09bbb213a88d61294143ec1d508a2a450f0e16ab3e2ffb7e0ed4cd7f75b3f2ff9f70cfaa77764506a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840f4262eeb9183eec1e896b9be61984ed9d4192b38825ba1b560ea23fe6e3224d3c94f4cc64174c1d9166e665e1a1ff8f0c84024bb8b9068b853fe4ce683d96906a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840df64e327056e335f484582fa0e4188e62620968e955431fc3576da2c1935b15ec605bb5d738f5000dcdc022646f9545d6932c2c79611dccab116295ca03c2b04a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840132cce5cea5d8bf7e9b802e4477eff041ebe1c12a8b8658a42ae91727cbf4f39b0d23831c70923a68ad7a023092bcecb61ac6253fdd17be00cecc37a71301300a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840842ecaf1b907cb34799d78d6f35eb349a986559a396840aeba5f6e8dc7e4172c16bddcb1f926a21175531478773046e9484aeb4ca83c1cbaf25f5a4813afdd0ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840a417cdf9e02755e53d6061ce0c93cacb7de24ce33e3fda9ac3a85414a7bf62676446822875972867d5647e46c22e21099e5dd8e4114949b30b86146b0dba1b05a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401f2e86831349fa458c3e2403e2caacbf046fae3c513575e8ce2d34037d34337f7e58cc98cadf034e8bce930335285220624945b316fe6af71e8ef0d12ef05001ffa100d90103a100a11902a2a1636d73678f78264175746f2d4c6f6f702d5472616e73616374696f6e202336313138303020627920415441444160783c4c6976652045706f6368203234352c207765206861766520303132682032386d20323773206c65667420756e74696c20746865206e657874206f6e6578374974277320446f6e6e657273746167202d20313520466562727561722032303234202d2031333a30313a333320696e20417573747269616060607820412072616e646f6d205a656e2d51756f746520666f7220796f753a20f09f998f783b4265206b696e642c20666f722065766572796f6e6520796f75206d656574206973206669676874696e6720612068617264657220626174746c652e68202d20506c61746f6078374e6f64652d5265766973696f6e3a203462623230343864623737643632336565366533363738363138633264386236633436373633333360782953616e63686f4e657420697320617765736f6d652c206861766520736f6d652066756e2120f09f988d7819204265737420726567617264732c204d617274696e203a2d2980"; + let bytes = hex::decode(hex).unwrap(); + let block = Block::from_wrapped_bytes(bytes); + assert!(block.is_ok()); +} \ No newline at end of file From e391f57dbbe482fc32b0b187a245b4997d2bf38f Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 16 Feb 2024 23:49:38 +0800 Subject: [PATCH 233/349] bingen fix --- rust/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 13afe025..39f66e65 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1372,8 +1372,8 @@ impl Block { #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] #[wasm_bindgen] - pub fn from_wrapped_bytes(data: Vec) -> Result { - Ok(block_from_wrapped_bytes()?) + pub fn from_wrapped_bytes(data: Vec) -> Result { + Ok(block_from_wrapped_bytes(&data)?) } // non-wasm exposed DeserializeError return From e4a472148d5c3a003af50d8b150afe494fbb0120 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 16 Feb 2024 23:49:50 +0800 Subject: [PATCH 234/349] js.flow update --- rust/pkg/cardano_serialization_lib.js.flow | 331 +++++++++++---------- 1 file changed, 171 insertions(+), 160 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index d448874e..e9692270 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -6,28 +6,16 @@ */ /** - * @param {string} password - * @param {string} salt - * @param {string} nonce - * @param {string} data - * @returns {string} - */ -declare export function encrypt_with_password( - password: string, - salt: string, - nonce: string, - data: string -): string; - -/** - * @param {string} password - * @param {string} data - * @returns {string} + * @param {Address} address + * @param {TransactionUnspentOutputs} utxos + * @param {TransactionBuilderConfig} config + * @returns {TransactionBatchList} */ -declare export function decrypt_with_password( - password: string, - data: string -): string; +declare export function create_send_all( + address: Address, + utxos: TransactionUnspentOutputs, + config: TransactionBuilderConfig +): TransactionBatchList; /** * @param {TransactionHash} tx_body_hash @@ -154,18 +142,6 @@ declare export function encode_json_str_to_native_script( schema: $Values ): NativeScript; -/** - * @param {Address} address - * @param {TransactionUnspentOutputs} utxos - * @param {TransactionBuilderConfig} config - * @returns {TransactionBatchList} - */ -declare export function create_send_all( - address: Address, - utxos: TransactionUnspentOutputs, - config: TransactionBuilderConfig -): TransactionBatchList; - /** * @param {Uint8Array} bytes * @returns {TransactionMetadatum} @@ -206,30 +182,6 @@ declare export function decode_metadatum_to_json_str( schema: $Values ): string; -/** - * @param {string} json - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {PlutusData} - */ -declare export function encode_json_str_to_plutus_datum( - json: string, - schema: $Values -): PlutusData; - -/** - * @param {PlutusData} datum - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {string} - */ -declare export function decode_plutus_datum_to_json_str( - datum: PlutusData, - schema: $Values -): string; - /** * @param {Transaction} tx * @param {LinearFee} linear_fee @@ -258,51 +210,62 @@ declare export function min_script_fee( ): BigNum; /** - * Each new language uses a different namespace for hashing its script - * This is because you could have a language where the same bytes have different semantics - * So this avoids scripts in different languages mapping to the same hash - * Note that the enum value here is different than the enum value for deciding the cost model of a script + * @param {string} json + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {PlutusData} */ - -declare export var ScriptHashNamespace: {| - +NativeScript: 0, // 0 - +PlutusScript: 1, // 1 - +PlutusScriptV2: 2, // 2 - +PlutusScriptV3: 3, // 3 -|}; +declare export function encode_json_str_to_plutus_datum( + json: string, + schema: $Values +): PlutusData; /** + * @param {PlutusData} datum + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {string} */ - -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 -|}; +declare export function decode_plutus_datum_to_json_str( + datum: PlutusData, + schema: $Values +): string; /** - * Used to choosed the schema for a script JSON string + * @param {string} password + * @param {string} salt + * @param {string} nonce + * @param {string} data + * @returns {string} */ - -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 -|}; +declare export function encrypt_with_password( + password: string, + salt: string, + nonce: string, + data: string +): string; /** + * @param {string} password + * @param {string} data + * @returns {string} */ - -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 -|}; +declare export function decrypt_with_password( + password: string, + data: string +): string; /** */ -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 |}; /** @@ -317,38 +280,12 @@ declare export var LanguageKind: {| /** */ -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 -|}; - -/** - */ - -declare export var RelayKind: {| - +SingleHostAddr: 0, // 0 - +SingleHostName: 1, // 1 - +MultiHostName: 2, // 2 -|}; - -/** - */ - -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 -|}; - -/** - */ - -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 |}; /** @@ -377,54 +314,84 @@ declare export var CertificateKind: {| /** */ -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** + * Used to choosed the schema for a script JSON string */ -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** */ -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 +declare export var RelayKind: {| + +SingleHostAddr: 0, // 0 + +SingleHostName: 1, // 1 + +MultiHostName: 2, // 2 |}; /** */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** */ -declare export var GovernanceActionKind: {| - +ParameterChangeAction: 0, // 0 - +HardForkInitiationAction: 1, // 1 - +TreasuryWithdrawalsAction: 2, // 2 - +NoConfidenceAction: 3, // 3 - +UpdateCommitteeAction: 4, // 4 - +NewConstitutionAction: 5, // 5 - +InfoAction: 6, // 6 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 +|}; + +/** + */ + +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 +|}; + +/** + */ + +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 +|}; + +/** + */ + +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 +|}; + +/** + * Each new language uses a different namespace for hashing its script + * This is because you could have a language where the same bytes have different semantics + * So this avoids scripts in different languages mapping to the same hash + * Note that the enum value here is different than the enum value for deciding the cost model of a script + */ + +declare export var ScriptHashNamespace: {| + +NativeScript: 0, // 0 + +PlutusScript: 1, // 1 + +PlutusScriptV2: 2, // 2 + +PlutusScriptV3: 3, // 3 |}; /** @@ -447,13 +414,25 @@ declare export var PlutusDatumSchema: {| /** */ -declare export var RedeemerTagKind: {| - +Spend: 0, // 0 - +Mint: 1, // 1 - +Cert: 2, // 2 - +Reward: 3, // 3 - +Vote: 4, // 4 - +VotingProposal: 5, // 5 +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 +|}; + +/** + */ + +declare export var GovernanceActionKind: {| + +ParameterChangeAction: 0, // 0 + +HardForkInitiationAction: 1, // 1 + +TreasuryWithdrawalsAction: 2, // 2 + +NoConfidenceAction: 3, // 3 + +UpdateCommitteeAction: 4, // 4 + +NewConstitutionAction: 5, // 5 + +InfoAction: 6, // 6 |}; /** @@ -478,12 +457,33 @@ declare export var MetadataJsonSchema: {| /** */ -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 +declare export var CborContainerType: {| + +Array: 0, // 0 +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 +|}; + +/** + */ + +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 +|}; + +/** + */ + +declare export var RedeemerTagKind: {| + +Spend: 0, // 0 + +Mint: 1, // 1 + +Cert: 2, // 2 + +Reward: 3, // 3 + +Vote: 4, // 4 + +VotingProposal: 5, // 5 |}; /** @@ -1525,6 +1525,12 @@ declare export class Block { auxiliary_data_set: AuxiliaryDataSet, invalid_transactions: Uint32Array ): Block; + + /** + * @param {Uint8Array} data + * @returns {Block} + */ + static from_wrapped_bytes(data: Uint8Array): Block; } /** */ @@ -3157,6 +3163,11 @@ declare export class DrepRegistration { coin: BigNum, anchor: Anchor ): DrepRegistration; + + /** + * @returns {boolean} + */ + has_script_credentials(): boolean; } /** */ From e260fcf44a7a5bba093029616fb2ad7443b216ca Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 16 Feb 2024 23:50:40 +0800 Subject: [PATCH 235/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3daf314e..88c7fa47 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.16", + "version": "12.0.0-alpha.17", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index c8243707..64520dac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.16", + "version": "12.0.0-alpha.17", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index a8aea1dc..a112ffd0 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.16" +version = "12.0.0-alpha.17" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 01de86b2..e1e5bc86 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -55,7 +55,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.16" +version = "12.0.0-alpha.17" dependencies = [ "bech32", "cbor_event", From 55c3f47e4135a24bd7e487cd6c6039df72e409f1 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 19 Feb 2024 20:27:27 +0800 Subject: [PATCH 236/349] fix collections deserialization --- .../certificates/certificates_collection.rs | 5 +-- .../move_instantaneous_rewards_cert.rs | 7 +-- .../certificates/pool_registration.rs | 7 +-- rust/src/serialization/credentials.rs | 5 +-- rust/src/serialization/crypto/vkeys.rs | 4 +- rust/src/serialization/ed25519_key_hashes.rs | 5 +-- rust/src/serialization/general.rs | 44 +++++++------------ .../governance/proposals/committee.rs | 5 +-- .../proposals/treasury_withdrawals.rs | 4 +- .../governance/proposals/voting_proposals.rs | 5 +-- .../governance/voting_procedures.rs | 15 +++---- rust/src/serialization/metadata.rs | 14 +++--- rust/src/serialization/native_scripts.rs | 5 +-- rust/src/serialization/plutus/cost_model.rs | 4 +- rust/src/serialization/plutus/cost_models.rs | 4 +- rust/src/serialization/plutus/languages.rs | 4 +- rust/src/serialization/plutus/plutus_data.rs | 8 ++-- .../serialization/plutus/plutus_scripts.rs | 8 ++-- rust/src/serialization/plutus/redeemers.rs | 4 +- rust/src/serialization/plutus/strings.rs | 4 +- rust/src/serialization/tx_inputs.rs | 5 +-- rust/src/serialization/utils.rs | 20 ++++++++- .../witnesses/transaction_witnesses_sets.rs | 4 +- 23 files changed, 84 insertions(+), 106 deletions(-) diff --git a/rust/src/serialization/certificates/certificates_collection.rs b/rust/src/serialization/certificates/certificates_collection.rs index c3391e92..1d210f94 100644 --- a/rust/src/serialization/certificates/certificates_collection.rs +++ b/rust/src/serialization/certificates/certificates_collection.rs @@ -1,4 +1,4 @@ -use crate::serialization::utils::skip_set_tag; +use crate::serialization::utils::{is_break_tag, skip_set_tag}; use crate::*; impl Serialize for Certificates { @@ -26,8 +26,7 @@ impl Deserialize for Certificates { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "Certificates")? { break; } arr.push(Certificate::deserialize(raw)?); diff --git a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs index 753e1f51..6c6079e2 100644 --- a/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs +++ b/rust/src/serialization/certificates/move_instantaneous_rewards_cert.rs @@ -1,7 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::utils::{ - check_len, deserialize_and_check_index, serialize_and_check_index, -}; +use crate::serialization::utils::{check_len, deserialize_and_check_index, is_break_tag, serialize_and_check_index}; use crate::*; use num_traits::ToPrimitive; use hashlink::LinkedHashMap; @@ -29,8 +27,7 @@ impl Deserialize for MIRToStakeCredentials { cbor_event::Len::Len(n) => table.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "MIRToStakeCredentials")? { break; } let key = Credential::deserialize(raw)?; diff --git a/rust/src/serialization/certificates/pool_registration.rs b/rust/src/serialization/certificates/pool_registration.rs index 88370bfa..d02f87e2 100644 --- a/rust/src/serialization/certificates/pool_registration.rs +++ b/rust/src/serialization/certificates/pool_registration.rs @@ -1,7 +1,5 @@ use crate::serialization::map_names::CertificateIndexNames; -use crate::serialization::utils::{ - check_len, deserialize_and_check_index, serialize_and_check_index, -}; +use crate::serialization::utils::{check_len, deserialize_and_check_index, is_break_tag, serialize_and_check_index}; use crate::*; use num_traits::ToPrimitive; @@ -27,8 +25,7 @@ impl Deserialize for Relays { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "Relays")? { break; } arr.push(Relay::deserialize(raw)?); diff --git a/rust/src/serialization/credentials.rs b/rust/src/serialization/credentials.rs index b5403f9f..a45086fb 100644 --- a/rust/src/serialization/credentials.rs +++ b/rust/src/serialization/credentials.rs @@ -1,5 +1,5 @@ use crate::*; -use crate::serialization::utils::skip_set_tag; +use crate::serialization::utils::{is_break_tag, skip_set_tag}; impl cbor_event::se::Serialize for Credentials { fn serialize<'se, W: Write>( @@ -27,8 +27,7 @@ impl Deserialize for Credentials { cbor_event::Len::Len(n) => counter < n, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "Credentials")? { break; } creds.add_move(Credential::deserialize(raw)?); diff --git a/rust/src/serialization/crypto/vkeys.rs b/rust/src/serialization/crypto/vkeys.rs index 4d9fc23c..08499ce3 100644 --- a/rust/src/serialization/crypto/vkeys.rs +++ b/rust/src/serialization/crypto/vkeys.rs @@ -3,6 +3,7 @@ use cbor_event::de::Deserializer; use cbor_event::se::Serializer; use crate::{DeserializeError, Vkey, Vkeys}; use crate::protocol_types::{CBORSpecial, CBORType, Deserialize}; +use crate::serialization::utils::is_break_tag; impl cbor_event::se::Serialize for Vkeys { fn serialize<'se, W: Write>( @@ -26,8 +27,7 @@ impl Deserialize for Vkeys { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "Vkeys")? { break; } arr.push(Vkey::deserialize(raw)?); diff --git a/rust/src/serialization/ed25519_key_hashes.rs b/rust/src/serialization/ed25519_key_hashes.rs index 5156fbfc..aeafe3ba 100644 --- a/rust/src/serialization/ed25519_key_hashes.rs +++ b/rust/src/serialization/ed25519_key_hashes.rs @@ -1,5 +1,5 @@ use crate::*; -use crate::serialization::utils::skip_set_tag; +use crate::serialization::utils::{is_break_tag, skip_set_tag}; impl Serialize for Ed25519KeyHashes { fn serialize<'se, W: Write>( @@ -27,8 +27,7 @@ impl Deserialize for Ed25519KeyHashes { cbor_event::Len::Len(n) => counter < n, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "Ed25519KeyHashes")? { break; } creds.add_move(Ed25519KeyHash::deserialize(raw)?); diff --git a/rust/src/serialization/general.rs b/rust/src/serialization/general.rs index 3420a02f..5685ad26 100644 --- a/rust/src/serialization/general.rs +++ b/rust/src/serialization/general.rs @@ -1,6 +1,6 @@ use crate::*; use std::io::{Seek, SeekFrom}; -use crate::serialization::utils::merge_option_plutus_list; +use crate::serialization::utils::{is_break_tag, merge_option_plutus_list}; use hashlink::LinkedHashMap; // This file was code-generated using an experimental CDDL to rust tool: @@ -198,8 +198,7 @@ impl Deserialize for TransactionOutputs { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "TransactionOutputs")? { break; } arr.push(TransactionOutput::deserialize(raw)?); @@ -1112,8 +1111,7 @@ impl Deserialize for RewardAddresses { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "RewardAddresses")? { break; } arr.push(RewardAddress::deserialize(raw)?); @@ -1148,8 +1146,7 @@ impl Deserialize for Withdrawals { cbor_event::Len::Len(n) => table.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "Withdrawals")? { break; } let key = RewardAddress::deserialize(raw)?; @@ -1247,8 +1244,7 @@ impl Deserialize for GenesisHashes { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "GenesisHashes")? { break; } arr.push(GenesisHash::deserialize(raw)?); @@ -1282,8 +1278,7 @@ impl Deserialize for ScriptHashes { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "ScriptHashes")? { break; } arr.push(ScriptHash::deserialize(raw)?); @@ -1318,8 +1313,7 @@ impl Deserialize for ProposedProtocolParameterUpdates { cbor_event::Len::Len(n) => table.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "ProposedProtocolParameterUpdates")? { break; } let key = GenesisHash::deserialize(raw)?; @@ -1420,8 +1414,7 @@ impl Deserialize for TransactionBodies { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "TransactionBodies")? { break; } arr.push(TransactionBody::deserialize(raw)?); @@ -1456,8 +1449,7 @@ impl Deserialize for AuxiliaryDataSet { cbor_event::Len::Len(n) => table.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "AuxiliaryDataSet")? { break; } let key = TransactionIndex::deserialize(raw)?; @@ -1526,8 +1518,7 @@ impl Deserialize for Block { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "Block.invalid_transactions")? { break; } arr.push(TransactionIndex::deserialize(raw)?); @@ -1869,8 +1860,7 @@ impl Deserialize for AssetNames { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "AssetNames")? { break; } arr.push(AssetName::deserialize(raw)?); @@ -1905,8 +1895,7 @@ impl Deserialize for Assets { cbor_event::Len::Len(n) => table.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "Assets")? { break; } let key = AssetName::deserialize(raw)?; @@ -1948,8 +1937,7 @@ impl Deserialize for MultiAsset { cbor_event::Len::Len(n) => table.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "MultiAsset")? { break; } let key = PolicyID::deserialize(raw)?; @@ -1991,8 +1979,7 @@ impl Deserialize for MintAssets { cbor_event::Len::Len(n) => table.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "MintAssets")? { break; } let key = AssetName::deserialize(raw)?; @@ -2034,8 +2021,7 @@ impl Deserialize for Mint { cbor_event::Len::Len(n) => mints.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "Mint")? { break; } let key = PolicyID::deserialize(raw)?; diff --git a/rust/src/serialization/governance/proposals/committee.rs b/rust/src/serialization/governance/proposals/committee.rs index f470aa05..7b0f73d4 100644 --- a/rust/src/serialization/governance/proposals/committee.rs +++ b/rust/src/serialization/governance/proposals/committee.rs @@ -1,4 +1,4 @@ -use crate::serialization::utils::check_len; +use crate::serialization::utils::{check_len, is_break_tag}; use crate::*; use std::collections::BTreeMap; @@ -40,8 +40,7 @@ impl DeserializeEmbeddedGroup for Committee { cbor_event::Len::Len(n) => table.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "Committee")? { break; } let key = Credential::deserialize(raw)?; diff --git a/rust/src/serialization/governance/proposals/treasury_withdrawals.rs b/rust/src/serialization/governance/proposals/treasury_withdrawals.rs index 2f622b95..b2867d6a 100644 --- a/rust/src/serialization/governance/proposals/treasury_withdrawals.rs +++ b/rust/src/serialization/governance/proposals/treasury_withdrawals.rs @@ -1,5 +1,6 @@ use crate::*; use std::collections::BTreeMap; +use crate::serialization::utils::is_break_tag; impl Serialize for TreasuryWithdrawals { fn serialize<'se, W: Write>( @@ -24,8 +25,7 @@ impl Deserialize for TreasuryWithdrawals { cbor_event::Len::Len(n) => table.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "TreasuryWithdrawals")? { break; } let key = RewardAddress::deserialize(raw)?; diff --git a/rust/src/serialization/governance/proposals/voting_proposals.rs b/rust/src/serialization/governance/proposals/voting_proposals.rs index 01b75ded..b3fd5fbf 100644 --- a/rust/src/serialization/governance/proposals/voting_proposals.rs +++ b/rust/src/serialization/governance/proposals/voting_proposals.rs @@ -1,5 +1,5 @@ use crate::*; -use crate::serialization::utils::skip_set_tag; +use crate::serialization::utils::{is_break_tag, skip_set_tag}; impl cbor_event::se::Serialize for VotingProposals { fn serialize<'se, W: Write>( @@ -26,8 +26,7 @@ impl Deserialize for VotingProposals { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "VotingProposals")? { break; } arr.push(VotingProposal::deserialize(raw)?); diff --git a/rust/src/serialization/governance/voting_procedures.rs b/rust/src/serialization/governance/voting_procedures.rs index 8780b7af..a1861ee7 100644 --- a/rust/src/serialization/governance/voting_procedures.rs +++ b/rust/src/serialization/governance/voting_procedures.rs @@ -1,5 +1,6 @@ use crate::*; use std::collections::BTreeMap; +use crate::serialization::utils::is_break_tag; impl cbor_event::se::Serialize for VotingProcedures { fn serialize<'se, W: Write>( @@ -29,11 +30,8 @@ impl Deserialize for VotingProcedures { cbor_event::Len::Len(n) => voter_to_vote.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - return Err( - DeserializeError::from(DeserializeFailure::EndingBreakMissing) - .annotate("voting_procedure map"), - ); + if is_break_tag(raw, "voting_procedure map")? { + break; } let key = Voter::deserialize(raw).map_err(|e| e.annotate("voter"))?; @@ -64,11 +62,8 @@ fn deserialize_internal_map( cbor_event::Len::Len(n) => gov_act_id_to_vote.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - return Err( - DeserializeError::from(DeserializeFailure::EndingBreakMissing) - .annotate("gov_act_id_to_vote map"), - ); + if is_break_tag(raw, "gov_act_id_to_vote map")? { + break; } let key = GovernanceActionId::deserialize(raw).map_err(|e| e.annotate("gov_act_id"))?; diff --git a/rust/src/serialization/metadata.rs b/rust/src/serialization/metadata.rs index c723d8e4..3b73d1e4 100644 --- a/rust/src/serialization/metadata.rs +++ b/rust/src/serialization/metadata.rs @@ -1,6 +1,6 @@ use hashlink::LinkedHashMap; use crate::*; -use crate::serialization::utils::merge_option_plutus_list; +use crate::serialization::utils::{is_break_tag, merge_option_plutus_list}; impl cbor_event::se::Serialize for MetadataMap { fn serialize<'se, W: Write>( @@ -26,8 +26,7 @@ impl Deserialize for MetadataMap { cbor_event::Len::Len(n) => entries.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "MetadataMap")? { break; } let key = TransactionMetadatum::deserialize(raw)?; @@ -69,8 +68,7 @@ impl Deserialize for MetadataList { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "MetadataList")? { break; } arr.push(TransactionMetadatum::deserialize(raw)?); @@ -160,8 +158,7 @@ impl Deserialize for TransactionMetadatumLabels { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "TransactionMetadatumLabels")? { break; } arr.push(TransactionMetadatumLabel::deserialize(raw)?); @@ -196,8 +193,7 @@ impl Deserialize for GeneralTransactionMetadata { cbor_event::Len::Len(n) => table.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "GeneralTransactionMetadata")? { break; } let key = TransactionMetadatumLabel::deserialize(raw)?; diff --git a/rust/src/serialization/native_scripts.rs b/rust/src/serialization/native_scripts.rs index c9d7d17d..14c2a85d 100644 --- a/rust/src/serialization/native_scripts.rs +++ b/rust/src/serialization/native_scripts.rs @@ -1,5 +1,5 @@ use crate::*; -use crate::serialization::utils::skip_set_tag; +use crate::serialization::utils::{is_break_tag, skip_set_tag}; impl cbor_event::se::Serialize for NativeScripts { fn serialize<'se, W: Write>( @@ -48,8 +48,7 @@ impl Deserialize for NativeScripts { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "NativeScripts")? { break; } arr.push(NativeScript::deserialize(raw)?); diff --git a/rust/src/serialization/plutus/cost_model.rs b/rust/src/serialization/plutus/cost_model.rs index a6521ed8..4c7d0b43 100644 --- a/rust/src/serialization/plutus/cost_model.rs +++ b/rust/src/serialization/plutus/cost_model.rs @@ -1,4 +1,5 @@ use crate::*; +use crate::serialization::utils::is_break_tag; impl cbor_event::se::Serialize for CostModel { fn serialize<'se, W: Write>( @@ -22,8 +23,7 @@ impl Deserialize for CostModel { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "CostModel")? { break; } arr.push(Int::deserialize(raw)?); diff --git a/rust/src/serialization/plutus/cost_models.rs b/rust/src/serialization/plutus/cost_models.rs index b8d6a7ec..538b8200 100644 --- a/rust/src/serialization/plutus/cost_models.rs +++ b/rust/src/serialization/plutus/cost_models.rs @@ -1,4 +1,5 @@ use crate::*; +use crate::serialization::utils::is_break_tag; impl cbor_event::se::Serialize for Costmdls { fn serialize<'se, W: Write>( @@ -23,8 +24,7 @@ impl Deserialize for Costmdls { cbor_event::Len::Len(n) => table.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "Costmdls")? { break; } let key = Language::deserialize(raw)?; diff --git a/rust/src/serialization/plutus/languages.rs b/rust/src/serialization/plutus/languages.rs index 9d473409..59709b45 100644 --- a/rust/src/serialization/plutus/languages.rs +++ b/rust/src/serialization/plutus/languages.rs @@ -1,4 +1,5 @@ use crate::*; +use crate::serialization::utils::is_break_tag; impl cbor_event::se::Serialize for Languages { fn serialize<'se, W: Write>( @@ -22,8 +23,7 @@ impl Deserialize for Languages { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "Languages")? { break; } arr.push(Language::deserialize(raw)?); diff --git a/rust/src/serialization/plutus/plutus_data.rs b/rust/src/serialization/plutus/plutus_data.rs index 49af9391..9f9c9afa 100644 --- a/rust/src/serialization/plutus/plutus_data.rs +++ b/rust/src/serialization/plutus/plutus_data.rs @@ -1,7 +1,7 @@ use crate::*; use std::io::SeekFrom; use hashlink::LinkedHashMap; -use crate::serialization::utils::skip_set_tag; +use crate::serialization::utils::{is_break_tag, skip_set_tag}; impl cbor_event::se::Serialize for ConstrPlutusData { fn serialize<'se, W: Write>( @@ -88,8 +88,7 @@ impl Deserialize for PlutusMap { cbor_event::Len::Len(n) => table.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "PlutusMap")? { break; } let key = PlutusData::deserialize(raw)?; @@ -283,8 +282,7 @@ impl Deserialize for PlutusList { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "PlutusList")? { break; } arr.push(PlutusData::deserialize(raw)?); diff --git a/rust/src/serialization/plutus/plutus_scripts.rs b/rust/src/serialization/plutus/plutus_scripts.rs index a7b77bb4..571b1a9a 100644 --- a/rust/src/serialization/plutus/plutus_scripts.rs +++ b/rust/src/serialization/plutus/plutus_scripts.rs @@ -1,5 +1,5 @@ use crate::*; -use crate::serialization::utils::skip_set_tag; +use crate::serialization::utils::{is_break_tag, skip_set_tag}; impl cbor_event::se::Serialize for PlutusScripts { fn serialize<'se, W: Write>( @@ -59,8 +59,7 @@ impl Deserialize for PlutusScripts { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "PlutusScripts")? { break; } arr.push(PlutusScript::deserialize(raw)?); @@ -82,8 +81,7 @@ impl PlutusScripts { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "PlutusScripts")? { break; } arr.push(PlutusScript::deserialize_with_version(raw, version)?); diff --git a/rust/src/serialization/plutus/redeemers.rs b/rust/src/serialization/plutus/redeemers.rs index e9d14f30..07e5ab4d 100644 --- a/rust/src/serialization/plutus/redeemers.rs +++ b/rust/src/serialization/plutus/redeemers.rs @@ -1,4 +1,5 @@ use crate::*; +use crate::serialization::utils::is_break_tag; impl cbor_event::se::Serialize for Redeemers { fn serialize<'se, W: Write>( @@ -22,8 +23,7 @@ impl Deserialize for Redeemers { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "Redeemers")? { break; } arr.push(Redeemer::deserialize(raw)?); diff --git a/rust/src/serialization/plutus/strings.rs b/rust/src/serialization/plutus/strings.rs index 50dcd443..5898ad5a 100644 --- a/rust/src/serialization/plutus/strings.rs +++ b/rust/src/serialization/plutus/strings.rs @@ -1,4 +1,5 @@ use crate::*; +use crate::serialization::utils::is_break_tag; impl cbor_event::se::Serialize for Strings { fn serialize<'se, W: Write>( @@ -22,8 +23,7 @@ impl Deserialize for Strings { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "Strings")? { break; } arr.push(String::deserialize(raw)?); diff --git a/rust/src/serialization/tx_inputs.rs b/rust/src/serialization/tx_inputs.rs index fd6db58d..84883e7a 100644 --- a/rust/src/serialization/tx_inputs.rs +++ b/rust/src/serialization/tx_inputs.rs @@ -1,5 +1,5 @@ use crate::*; -use crate::serialization::utils::skip_set_tag; +use crate::serialization::utils::{is_break_tag, skip_set_tag}; impl cbor_event::se::Serialize for TransactionInputs { fn serialize<'se, W: Write>( @@ -26,8 +26,7 @@ impl Deserialize for TransactionInputs { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "TransactionInputs")? { break; } arr.push(TransactionInput::deserialize(raw)?); diff --git a/rust/src/serialization/utils.rs b/rust/src/serialization/utils.rs index 3c1f442e..e52c0d60 100644 --- a/rust/src/serialization/utils.rs +++ b/rust/src/serialization/utils.rs @@ -75,7 +75,10 @@ pub(super) fn check_len_indefinite( Ok(()) } -pub(crate) fn merge_option_plutus_list(left: Option, right: Option) -> Option { +pub(crate) fn merge_option_plutus_list( + left: Option, + right: Option, +) -> Option { if let Some(left) = left { if let Some(right) = right { return Some(left.merge(&right)); @@ -111,3 +114,18 @@ pub(super) fn skip_set_tag( ) -> Result<(), DeserializeError> { skip_tag(raw, 258) } + +pub(crate) fn is_break_tag( + raw: &mut Deserializer, + location: &str, +) -> Result { + if raw.cbor_type()? == CBORType::Special { + if raw.special()? == CBORSpecial::Break { + return Ok(true); + } + return Err( + DeserializeError::from(DeserializeFailure::EndingBreakMissing).annotate(location), + ); + } + Ok(false) +} diff --git a/rust/src/serialization/witnesses/transaction_witnesses_sets.rs b/rust/src/serialization/witnesses/transaction_witnesses_sets.rs index a3b21bb8..be82226d 100644 --- a/rust/src/serialization/witnesses/transaction_witnesses_sets.rs +++ b/rust/src/serialization/witnesses/transaction_witnesses_sets.rs @@ -3,6 +3,7 @@ use cbor_event::de::Deserializer; use cbor_event::se::Serializer; use crate::{DeserializeError, TransactionWitnessSet, TransactionWitnessSets}; use crate::protocol_types::{CBORSpecial, CBORType, Deserialize}; +use crate::serialization::utils::is_break_tag; impl cbor_event::se::Serialize for TransactionWitnessSets { fn serialize<'se, W: Write>( @@ -26,8 +27,7 @@ impl Deserialize for TransactionWitnessSets { cbor_event::Len::Len(n) => arr.len() < n as usize, cbor_event::Len::Indefinite => true, } { - if raw.cbor_type()? == CBORType::Special { - assert_eq!(raw.special()?, CBORSpecial::Break); + if is_break_tag(raw, "TransactionWitnessSets")? { break; } arr.push(TransactionWitnessSet::deserialize(raw)?); From c624c22d3ba7ca39a4b00e304e1f5fe2e19de20d Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 19 Feb 2024 20:28:59 +0800 Subject: [PATCH 237/349] js flow update --- rust/pkg/cardano_serialization_lib.js.flow | 302 ++++++++++----------- 1 file changed, 151 insertions(+), 151 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index e9692270..010d435d 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -6,16 +6,31 @@ */ /** - * @param {Address} address - * @param {TransactionUnspentOutputs} utxos - * @param {TransactionBuilderConfig} config - * @returns {TransactionBatchList} + * @param {Transaction} tx + * @param {LinearFee} linear_fee + * @returns {BigNum} */ -declare export function create_send_all( - address: Address, - utxos: TransactionUnspentOutputs, - config: TransactionBuilderConfig -): TransactionBatchList; +declare export function min_fee(tx: Transaction, linear_fee: LinearFee): BigNum; + +/** + * @param {ExUnits} ex_units + * @param {ExUnitPrices} ex_unit_prices + * @returns {BigNum} + */ +declare export function calculate_ex_units_ceil_cost( + ex_units: ExUnits, + ex_unit_prices: ExUnitPrices +): BigNum; + +/** + * @param {Transaction} tx + * @param {ExUnitPrices} ex_unit_prices + * @returns {BigNum} + */ +declare export function min_script_fee( + tx: Transaction, + ex_unit_prices: ExUnitPrices +): BigNum; /** * @param {TransactionHash} tx_body_hash @@ -142,6 +157,42 @@ declare export function encode_json_str_to_native_script( schema: $Values ): NativeScript; +/** + * @param {string} password + * @param {string} salt + * @param {string} nonce + * @param {string} data + * @returns {string} + */ +declare export function encrypt_with_password( + password: string, + salt: string, + nonce: string, + data: string +): string; + +/** + * @param {string} password + * @param {string} data + * @returns {string} + */ +declare export function decrypt_with_password( + password: string, + data: string +): string; + +/** + * @param {Address} address + * @param {TransactionUnspentOutputs} utxos + * @param {TransactionBuilderConfig} config + * @returns {TransactionBatchList} + */ +declare export function create_send_all( + address: Address, + utxos: TransactionUnspentOutputs, + config: TransactionBuilderConfig +): TransactionBatchList; + /** * @param {Uint8Array} bytes * @returns {TransactionMetadatum} @@ -182,33 +233,6 @@ declare export function decode_metadatum_to_json_str( schema: $Values ): string; -/** - * @param {Transaction} tx - * @param {LinearFee} linear_fee - * @returns {BigNum} - */ -declare export function min_fee(tx: Transaction, linear_fee: LinearFee): BigNum; - -/** - * @param {ExUnits} ex_units - * @param {ExUnitPrices} ex_unit_prices - * @returns {BigNum} - */ -declare export function calculate_ex_units_ceil_cost( - ex_units: ExUnits, - ex_unit_prices: ExUnitPrices -): BigNum; - -/** - * @param {Transaction} tx - * @param {ExUnitPrices} ex_unit_prices - * @returns {BigNum} - */ -declare export function min_script_fee( - tx: Transaction, - ex_unit_prices: ExUnitPrices -): BigNum; - /** * @param {string} json * @param {$Values< @@ -233,30 +257,6 @@ declare export function decode_plutus_datum_to_json_str( schema: $Values ): string; -/** - * @param {string} password - * @param {string} salt - * @param {string} nonce - * @param {string} data - * @returns {string} - */ -declare export function encrypt_with_password( - password: string, - salt: string, - nonce: string, - data: string -): string; - -/** - * @param {string} password - * @param {string} data - * @returns {string} - */ -declare export function decrypt_with_password( - password: string, - data: string -): string; - /** */ @@ -271,21 +271,31 @@ declare export var TransactionMetadatumKind: {| /** */ -declare export var LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 +declare export var GovernanceActionKind: {| + +ParameterChangeAction: 0, // 0 + +HardForkInitiationAction: 1, // 1 + +TreasuryWithdrawalsAction: 2, // 2 + +NoConfidenceAction: 3, // 3 + +UpdateCommitteeAction: 4, // 4 + +NewConstitutionAction: 5, // 5 + +InfoAction: 6, // 6 |}; /** */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 +|}; + +/** + */ + +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 |}; /** @@ -314,52 +324,10 @@ declare export var CertificateKind: {| /** */ -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 -|}; - -/** - * Used to choosed the schema for a script JSON string - */ - -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 -|}; - -/** - */ - -declare export var RelayKind: {| - +SingleHostAddr: 0, // 0 - +SingleHostName: 1, // 1 - +MultiHostName: 2, // 2 -|}; - -/** - */ - -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 -|}; - -/** - */ - -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 -|}; - -/** - */ - -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 |}; /** @@ -373,11 +341,12 @@ declare export var DRepKind: {| |}; /** + * Used to choosed the schema for a script JSON string */ -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** @@ -394,6 +363,24 @@ declare export var ScriptHashNamespace: {| +PlutusScriptV3: 3, // 3 |}; +/** + */ + +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 +|}; + +/** + */ + +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 +|}; + /** * JSON <-> PlutusData conversion schemas. * Follows ScriptDataJsonSchema in cardano-cli defined at: @@ -414,52 +401,59 @@ declare export var PlutusDatumSchema: {| /** */ -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 - +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** */ -declare export var GovernanceActionKind: {| - +ParameterChangeAction: 0, // 0 - +HardForkInitiationAction: 1, // 1 - +TreasuryWithdrawalsAction: 2, // 2 - +NoConfidenceAction: 3, // 3 - +UpdateCommitteeAction: 4, // 4 - +NewConstitutionAction: 5, // 5 - +InfoAction: 6, // 6 +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 |}; /** */ -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 |}; /** */ -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 +declare export var RedeemerTagKind: {| + +Spend: 0, // 0 + +Mint: 1, // 1 + +Cert: 2, // 2 + +Reward: 3, // 3 + +Vote: 4, // 4 + +VotingProposal: 5, // 5 |}; /** */ -declare export var CborContainerType: {| - +Array: 0, // 0 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 +|}; + +/** + */ + +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 |}; /** @@ -477,13 +471,19 @@ declare export var NativeScriptKind: {| /** */ -declare export var RedeemerTagKind: {| - +Spend: 0, // 0 - +Mint: 1, // 1 - +Cert: 2, // 2 - +Reward: 3, // 3 - +Vote: 4, // 4 - +VotingProposal: 5, // 5 +declare export var RelayKind: {| + +SingleHostAddr: 0, // 0 + +SingleHostName: 1, // 1 + +MultiHostName: 2, // 2 +|}; + +/** + */ + +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** From 157d933deb91c8be873b2ba6c987f8d97ead186e Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 19 Feb 2024 20:29:48 +0800 Subject: [PATCH 238/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 88c7fa47..0d45cb35 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.17", + "version": "12.0.0-alpha.18", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 64520dac..04b4f27b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.17", + "version": "12.0.0-alpha.18", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index a112ffd0..b3d8b61a 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.17" +version = "12.0.0-alpha.18" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index e1e5bc86..dab46639 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -55,7 +55,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.17" +version = "12.0.0-alpha.18" dependencies = [ "bech32", "cbor_event", From ff5705639c06c8c77d4ddb41c34add2313fb836f Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 5 Mar 2024 22:37:45 +0700 Subject: [PATCH 239/349] fix hf initiation serialization --- .../proposals/hard_fork_initiation_action.rs | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/rust/src/serialization/governance/proposals/hard_fork_initiation_action.rs b/rust/src/serialization/governance/proposals/hard_fork_initiation_action.rs index aad34325..103a15df 100644 --- a/rust/src/serialization/governance/proposals/hard_fork_initiation_action.rs +++ b/rust/src/serialization/governance/proposals/hard_fork_initiation_action.rs @@ -20,7 +20,6 @@ impl cbor_event::se::Serialize for HardForkInitiationAction { serializer.write_special(CBORSpecial::Null)?; } - serializer.write_array(cbor_event::Len::Len(1))?; self.protocol_version.serialize(serializer)?; Ok(serializer) @@ -37,7 +36,7 @@ impl DeserializeEmbeddedGroup for HardForkInitiationAction { check_len( len, 3, - "(proposal_index, gov_action_id // null, protocol_version)", + "(proposal_index, gov_action_id // null, [protocol_version])", )?; let desired_index = VotingProposalIndexNames::HardForkInitiationAction.to_u64(); @@ -46,24 +45,11 @@ impl DeserializeEmbeddedGroup for HardForkInitiationAction { let gov_action_id = GovernanceActionId::deserialize_nullable(raw) .map_err(|e| e.annotate("gov_action_id"))?; - let protocol_version = deserialize_embedded_protocol_version(raw)?; + let protocol_version = ProtocolVersion::deserialize(raw)?; return Ok(HardForkInitiationAction { gov_action_id, protocol_version, }); } -} - -fn deserialize_embedded_protocol_version( - raw: &mut Deserializer, -) -> Result { - let len = raw.array()?; - - check_len(len, 1, "(protocol_version)")?; - - let protocol_version = - ProtocolVersion::deserialize(raw).map_err(|e| e.annotate("protocol_version"))?; - check_len_indefinite(raw, len)?; - Ok(protocol_version) -} +} \ No newline at end of file From c7159d311f64fad10394252c64d58e9bfc74d41b Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 5 Mar 2024 22:40:40 +0700 Subject: [PATCH 240/349] bump version --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- rust/pkg/cardano_serialization_lib.js.flow | 414 ++++++++++----------- 5 files changed, 211 insertions(+), 211 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0d45cb35..7b9d914d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.18", + "version": "12.0.0-alpha.19", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 04b4f27b..45e50054 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.18", + "version": "12.0.0-alpha.19", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index b3d8b61a..3fe26128 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.18" +version = "12.0.0-alpha.19" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index dab46639..95f3d3ad 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -55,7 +55,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.18" +version = "12.0.0-alpha.19" dependencies = [ "bech32", "cbor_event", diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 010d435d..13f5ee3d 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -5,6 +5,82 @@ * @flow */ +/** + * @param {string} json + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {PlutusData} + */ +declare export function encode_json_str_to_plutus_datum( + json: string, + schema: $Values +): PlutusData; + +/** + * @param {PlutusData} datum + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {string} + */ +declare export function decode_plutus_datum_to_json_str( + datum: PlutusData, + schema: $Values +): string; + +/** + * @param {Uint8Array} bytes + * @returns {TransactionMetadatum} + */ +declare export function encode_arbitrary_bytes_as_metadatum( + bytes: Uint8Array +): TransactionMetadatum; + +/** + * @param {TransactionMetadatum} metadata + * @returns {Uint8Array} + */ +declare export function decode_arbitrary_bytes_from_metadatum( + metadata: TransactionMetadatum +): Uint8Array; + +/** + * @param {string} json + * @param {$Values< + typeof + MetadataJsonSchema>} schema + * @returns {TransactionMetadatum} + */ +declare export function encode_json_str_to_metadatum( + json: string, + schema: $Values +): TransactionMetadatum; + +/** + * @param {TransactionMetadatum} metadatum + * @param {$Values< + typeof + MetadataJsonSchema>} schema + * @returns {string} + */ +declare export function decode_metadatum_to_json_str( + metadatum: TransactionMetadatum, + schema: $Values +): string; + +/** + * @param {Address} address + * @param {TransactionUnspentOutputs} utxos + * @param {TransactionBuilderConfig} config + * @returns {TransactionBatchList} + */ +declare export function create_send_all( + address: Address, + utxos: TransactionUnspentOutputs, + config: TransactionBuilderConfig +): TransactionBatchList; + /** * @param {Transaction} tx * @param {LinearFee} linear_fee @@ -32,6 +108,30 @@ declare export function min_script_fee( ex_unit_prices: ExUnitPrices ): BigNum; +/** + * @param {string} password + * @param {string} salt + * @param {string} nonce + * @param {string} data + * @returns {string} + */ +declare export function encrypt_with_password( + password: string, + salt: string, + nonce: string, + data: string +): string; + +/** + * @param {string} password + * @param {string} data + * @returns {string} + */ +declare export function decrypt_with_password( + password: string, + data: string +): string; + /** * @param {TransactionHash} tx_body_hash * @param {ByronAddress} addr @@ -158,114 +258,28 @@ declare export function encode_json_str_to_native_script( ): NativeScript; /** - * @param {string} password - * @param {string} salt - * @param {string} nonce - * @param {string} data - * @returns {string} - */ -declare export function encrypt_with_password( - password: string, - salt: string, - nonce: string, - data: string -): string; - -/** - * @param {string} password - * @param {string} data - * @returns {string} - */ -declare export function decrypt_with_password( - password: string, - data: string -): string; - -/** - * @param {Address} address - * @param {TransactionUnspentOutputs} utxos - * @param {TransactionBuilderConfig} config - * @returns {TransactionBatchList} - */ -declare export function create_send_all( - address: Address, - utxos: TransactionUnspentOutputs, - config: TransactionBuilderConfig -): TransactionBatchList; - -/** - * @param {Uint8Array} bytes - * @returns {TransactionMetadatum} - */ -declare export function encode_arbitrary_bytes_as_metadatum( - bytes: Uint8Array -): TransactionMetadatum; - -/** - * @param {TransactionMetadatum} metadata - * @returns {Uint8Array} */ -declare export function decode_arbitrary_bytes_from_metadatum( - metadata: TransactionMetadatum -): Uint8Array; -/** - * @param {string} json - * @param {$Values< - typeof - MetadataJsonSchema>} schema - * @returns {TransactionMetadatum} - */ -declare export function encode_json_str_to_metadatum( - json: string, - schema: $Values -): TransactionMetadatum; +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 +|}; /** - * @param {TransactionMetadatum} metadatum - * @param {$Values< - typeof - MetadataJsonSchema>} schema - * @returns {string} */ -declare export function decode_metadatum_to_json_str( - metadatum: TransactionMetadatum, - schema: $Values -): string; -/** - * @param {string} json - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {PlutusData} - */ -declare export function encode_json_str_to_plutus_datum( - json: string, - schema: $Values -): PlutusData; - -/** - * @param {PlutusData} datum - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {string} - */ -declare export function decode_plutus_datum_to_json_str( - datum: PlutusData, - schema: $Values -): string; +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 +|}; /** + * Used to choosed the schema for a script JSON string */ -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** @@ -282,52 +296,55 @@ declare export var GovernanceActionKind: {| |}; /** + * JSON <-> PlutusData conversion schemas. + * Follows ScriptDataJsonSchema in cardano-cli defined at: + * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 + * + * All methods here have the following restrictions due to limitations on dependencies: + * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors + * * Hex strings for bytes don't accept odd-length (half-byte) strings. + * cardano-cli seems to support these however but it seems to be different than just 0-padding + * on either side when tested so proceed with caution */ -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 +declare export var PlutusDatumSchema: {| + +BasicConversions: 0, // 0 + +DetailedSchema: 1, // 1 |}; /** + * Each new language uses a different namespace for hashing its script + * This is because you could have a language where the same bytes have different semantics + * So this avoids scripts in different languages mapping to the same hash + * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 +declare export var ScriptHashNamespace: {| + +NativeScript: 0, // 0 + +PlutusScript: 1, // 1 + +PlutusScriptV2: 2, // 2 + +PlutusScriptV3: 3, // 3 |}; /** */ -declare export var CertificateKind: {| - +StakeRegistration: 0, // 0 - +StakeDeregistration: 1, // 1 - +StakeDelegation: 2, // 2 - +PoolRegistration: 3, // 3 - +PoolRetirement: 4, // 4 - +GenesisKeyDelegation: 5, // 5 - +MoveInstantaneousRewardsCert: 6, // 6 - +CommitteeHotAuth: 7, // 7 - +CommitteeColdResign: 8, // 8 - +DrepDeregistration: 9, // 9 - +DrepRegistration: 10, // 10 - +DrepUpdate: 11, // 11 - +StakeAndVoteDelegation: 12, // 12 - +StakeRegistrationAndDelegation: 13, // 13 - +StakeVoteRegistrationAndDelegation: 14, // 14 - +VoteDelegation: 15, // 15 - +VoteRegistrationAndDelegation: 16, // 16 +declare export var RelayKind: {| + +SingleHostAddr: 0, // 0 + +SingleHostName: 1, // 1 + +MultiHostName: 2, // 2 |}; /** */ -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 |}; /** @@ -340,78 +357,70 @@ declare export var DRepKind: {| +AlwaysNoConfidence: 3, // 3 |}; -/** - * Used to choosed the schema for a script JSON string - */ - -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 -|}; - -/** - * Each new language uses a different namespace for hashing its script - * This is because you could have a language where the same bytes have different semantics - * So this avoids scripts in different languages mapping to the same hash - * Note that the enum value here is different than the enum value for deciding the cost model of a script - */ - -declare export var ScriptHashNamespace: {| - +NativeScript: 0, // 0 - +PlutusScript: 1, // 1 - +PlutusScriptV2: 2, // 2 - +PlutusScriptV3: 3, // 3 -|}; - /** */ -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 |}; /** */ -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** - * JSON <-> PlutusData conversion schemas. - * Follows ScriptDataJsonSchema in cardano-cli defined at: - * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 - * - * All methods here have the following restrictions due to limitations on dependencies: - * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors - * * Hex strings for bytes don't accept odd-length (half-byte) strings. - * cardano-cli seems to support these however but it seems to be different than just 0-padding - * on either side when tested so proceed with caution */ -declare export var PlutusDatumSchema: {| - +BasicConversions: 0, // 0 - +DetailedSchema: 1, // 1 +declare export var RedeemerTagKind: {| + +Spend: 0, // 0 + +Mint: 1, // 1 + +Cert: 2, // 2 + +Reward: 3, // 3 + +Vote: 4, // 4 + +VotingProposal: 5, // 5 |}; /** */ -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 +declare export var CertificateKind: {| + +StakeRegistration: 0, // 0 + +StakeDeregistration: 1, // 1 + +StakeDelegation: 2, // 2 + +PoolRegistration: 3, // 3 + +PoolRetirement: 4, // 4 + +GenesisKeyDelegation: 5, // 5 + +MoveInstantaneousRewardsCert: 6, // 6 + +CommitteeHotAuth: 7, // 7 + +CommitteeColdResign: 8, // 8 + +DrepDeregistration: 9, // 9 + +DrepRegistration: 10, // 10 + +DrepUpdate: 11, // 11 + +StakeAndVoteDelegation: 12, // 12 + +StakeRegistrationAndDelegation: 13, // 13 + +StakeVoteRegistrationAndDelegation: 14, // 14 + +VoteDelegation: 15, // 15 + +VoteRegistrationAndDelegation: 16, // 16 |}; /** */ -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 |}; /** @@ -428,62 +437,53 @@ declare export var VoterKind: {| /** */ -declare export var RedeemerTagKind: {| - +Spend: 0, // 0 - +Mint: 1, // 1 - +Cert: 2, // 2 - +Reward: 3, // 3 - +Vote: 4, // 4 - +VotingProposal: 5, // 5 +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 |}; /** */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 |}; /** */ -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 - +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 |}; /** */ -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 |}; /** */ -declare export var RelayKind: {| - +SingleHostAddr: 0, // 0 - +SingleHostName: 1, // 1 - +MultiHostName: 2, // 2 +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 |}; /** */ -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 |}; /** From 0ee2fabed05ab3be50a658eadb3e908e11251512 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 8 Mar 2024 11:33:15 +0700 Subject: [PATCH 241/349] security_relevant_threshold to PoolVotingThresholds --- .../protocol_types/protocol_param_update.rs | 3 + .../serialization/protocol_param_update.rs | 141 +++++++++--------- rust/src/tests/mock_objects.rs | 1 + .../serialization/protocol_param_update.rs | 1 + 4 files changed, 78 insertions(+), 68 deletions(-) diff --git a/rust/src/protocol_types/protocol_param_update.rs b/rust/src/protocol_types/protocol_param_update.rs index 2cf93d8a..12ca0e6f 100644 --- a/rust/src/protocol_types/protocol_param_update.rs +++ b/rust/src/protocol_types/protocol_param_update.rs @@ -18,6 +18,7 @@ pub struct PoolVotingThresholds { pub(crate) committee_normal: UnitInterval, pub(crate) committee_no_confidence: UnitInterval, pub(crate) hard_fork_initiation: UnitInterval, + pub(crate) security_relevant_threshold: UnitInterval, } impl_to_from!(PoolVotingThresholds); @@ -29,12 +30,14 @@ impl PoolVotingThresholds { committee_normal: &UnitInterval, committee_no_confidence: &UnitInterval, hard_fork_initiation: &UnitInterval, + security_relevant_threshold: &UnitInterval, ) -> Self { Self { motion_no_confidence: motion_no_confidence.clone(), committee_normal: committee_normal.clone(), committee_no_confidence: committee_no_confidence.clone(), hard_fork_initiation: hard_fork_initiation.clone(), + security_relevant_threshold: security_relevant_threshold.clone(), } } diff --git a/rust/src/serialization/protocol_param_update.rs b/rust/src/serialization/protocol_param_update.rs index c129cca7..042ee00b 100644 --- a/rust/src/serialization/protocol_param_update.rs +++ b/rust/src/serialization/protocol_param_update.rs @@ -1,16 +1,17 @@ -use crate::*; use crate::serialization::utils::check_len; +use crate::*; impl Serialize for PoolVotingThresholds { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(4))?; + serializer.write_array(cbor_event::Len::Len(5))?; self.motion_no_confidence.serialize(serializer)?; self.committee_normal.serialize(serializer)?; self.committee_no_confidence.serialize(serializer)?; - self.hard_fork_initiation.serialize(serializer) + self.hard_fork_initiation.serialize(serializer)?; + self.security_relevant_threshold.serialize(serializer) } } @@ -23,29 +24,33 @@ impl DeserializeEmbeddedGroup for PoolVotingThresholds { ) -> Result { check_len( len, - 4, + 5, "[\ motion_no_confidence, \ committee_normal, \ committee_no_confidence, \ - hard_fork_initiation\ + hard_fork_initiation, \ + security_relevant_threshold\ ]", )?; - let motion_no_confidence = UnitInterval::deserialize(raw) - .map_err(|e| e.annotate("motion_no_confidence"))?; - let committee_normal = UnitInterval::deserialize(raw) - .map_err(|e| e.annotate("committee_normal"))?; - let committee_no_confidence = UnitInterval::deserialize(raw) - .map_err(|e| e.annotate("committee_no_confidence"))?; - let hard_fork_initiation = UnitInterval::deserialize(raw) - .map_err(|e| e.annotate("hard_fork_initiation"))?; + let motion_no_confidence = + UnitInterval::deserialize(raw).map_err(|e| e.annotate("motion_no_confidence"))?; + let committee_normal = + UnitInterval::deserialize(raw).map_err(|e| e.annotate("committee_normal"))?; + let committee_no_confidence = + UnitInterval::deserialize(raw).map_err(|e| e.annotate("committee_no_confidence"))?; + let hard_fork_initiation = + UnitInterval::deserialize(raw).map_err(|e| e.annotate("hard_fork_initiation"))?; + let security_relevant_threshold = UnitInterval::deserialize(raw) + .map_err(|e| e.annotate("security_relevant_threshold"))?; return Ok(PoolVotingThresholds { motion_no_confidence, committee_normal, committee_no_confidence, hard_fork_initiation, + security_relevant_threshold, }); } } @@ -93,26 +98,26 @@ impl DeserializeEmbeddedGroup for DrepVotingThresholds { ]", )?; - let motion_no_confidence = UnitInterval::deserialize(raw) - .map_err(|e| e.annotate("motion_no_confidence"))?; - let committee_normal = UnitInterval::deserialize(raw) - .map_err(|e| e.annotate("committee_normal"))?; - let committee_no_confidence = UnitInterval::deserialize(raw) - .map_err(|e| e.annotate("committee_no_confidence"))?; - let update_constitution = UnitInterval::deserialize(raw) - .map_err(|e| e.annotate("update_constitution"))?; - let hard_fork_initiation = UnitInterval::deserialize(raw) - .map_err(|e| e.annotate("hard_fork_initiation"))?; - let pp_network_group = UnitInterval::deserialize(raw) - .map_err(|e| e.annotate("pp_network_group"))?; - let pp_economic_group = UnitInterval::deserialize(raw) - .map_err(|e| e.annotate("pp_economic_group"))?; - let pp_technical_group = UnitInterval::deserialize(raw) - .map_err(|e| e.annotate("pp_technical_group"))?; - let pp_governance_group = UnitInterval::deserialize(raw) - .map_err(|e| e.annotate("pp_governance_group"))?; - let treasury_withdrawal = UnitInterval::deserialize(raw) - .map_err(|e| e.annotate("treasury_withdrawal"))?; + let motion_no_confidence = + UnitInterval::deserialize(raw).map_err(|e| e.annotate("motion_no_confidence"))?; + let committee_normal = + UnitInterval::deserialize(raw).map_err(|e| e.annotate("committee_normal"))?; + let committee_no_confidence = + UnitInterval::deserialize(raw).map_err(|e| e.annotate("committee_no_confidence"))?; + let update_constitution = + UnitInterval::deserialize(raw).map_err(|e| e.annotate("update_constitution"))?; + let hard_fork_initiation = + UnitInterval::deserialize(raw).map_err(|e| e.annotate("hard_fork_initiation"))?; + let pp_network_group = + UnitInterval::deserialize(raw).map_err(|e| e.annotate("pp_network_group"))?; + let pp_economic_group = + UnitInterval::deserialize(raw).map_err(|e| e.annotate("pp_economic_group"))?; + let pp_technical_group = + UnitInterval::deserialize(raw).map_err(|e| e.annotate("pp_technical_group"))?; + let pp_governance_group = + UnitInterval::deserialize(raw).map_err(|e| e.annotate("pp_governance_group"))?; + let treasury_withdrawal = + UnitInterval::deserialize(raw).map_err(|e| e.annotate("treasury_withdrawal"))?; return Ok(DrepVotingThresholds { motion_no_confidence, @@ -419,7 +424,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(Coin::deserialize(raw)?) })() - .map_err(|e| e.annotate("minfee_a"))?, + .map_err(|e| e.annotate("minfee_a"))?, ); } 1 => { @@ -431,7 +436,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(Coin::deserialize(raw)?) })() - .map_err(|e| e.annotate("minfee_b"))?, + .map_err(|e| e.annotate("minfee_b"))?, ); } 2 => { @@ -443,7 +448,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(u32::deserialize(raw)?) })() - .map_err(|e| e.annotate("max_block_body_size"))?, + .map_err(|e| e.annotate("max_block_body_size"))?, ); } 3 => { @@ -455,7 +460,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(u32::deserialize(raw)?) })() - .map_err(|e| e.annotate("max_tx_size"))?, + .map_err(|e| e.annotate("max_tx_size"))?, ); } 4 => { @@ -467,7 +472,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(u32::deserialize(raw)?) })() - .map_err(|e| e.annotate("max_block_header_size"))?, + .map_err(|e| e.annotate("max_block_header_size"))?, ); } 5 => { @@ -479,7 +484,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(Coin::deserialize(raw)?) })() - .map_err(|e| e.annotate("key_deposit"))?, + .map_err(|e| e.annotate("key_deposit"))?, ); } 6 => { @@ -491,7 +496,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(Coin::deserialize(raw)?) })() - .map_err(|e| e.annotate("pool_deposit"))?, + .map_err(|e| e.annotate("pool_deposit"))?, ); } 7 => { @@ -503,7 +508,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(Epoch::deserialize(raw)?) })() - .map_err(|e| e.annotate("max_epoch"))?, + .map_err(|e| e.annotate("max_epoch"))?, ); } 8 => { @@ -515,7 +520,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(u32::deserialize(raw)?) })() - .map_err(|e| e.annotate("n_opt"))?, + .map_err(|e| e.annotate("n_opt"))?, ); } 9 => { @@ -527,7 +532,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(Rational::deserialize(raw)?) })() - .map_err(|e| e.annotate("pool_pledge_influence"))?, + .map_err(|e| e.annotate("pool_pledge_influence"))?, ); } 10 => { @@ -539,7 +544,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(UnitInterval::deserialize(raw)?) })() - .map_err(|e| e.annotate("expansion_rate"))?, + .map_err(|e| e.annotate("expansion_rate"))?, ); } 11 => { @@ -551,7 +556,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(UnitInterval::deserialize(raw)?) })() - .map_err(|e| e.annotate("treasury_growth_rate"))?, + .map_err(|e| e.annotate("treasury_growth_rate"))?, ); } 12 => { @@ -563,7 +568,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(UnitInterval::deserialize(raw)?) })() - .map_err(|e| e.annotate("d"))?, + .map_err(|e| e.annotate("d"))?, ); } 13 => { @@ -575,7 +580,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(Nonce::deserialize(raw)?) })() - .map_err(|e| e.annotate("extra_entropy"))?, + .map_err(|e| e.annotate("extra_entropy"))?, ); } 14 => { @@ -587,7 +592,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(ProtocolVersion::deserialize(raw)?) })() - .map_err(|e| e.annotate("protocol_version"))?, + .map_err(|e| e.annotate("protocol_version"))?, ); } 16 => { @@ -599,7 +604,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(Coin::deserialize(raw)?) })() - .map_err(|e| e.annotate("min_pool_cost"))?, + .map_err(|e| e.annotate("min_pool_cost"))?, ); } 17 => { @@ -611,7 +616,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(Coin::deserialize(raw)?) })() - .map_err(|e| e.annotate("ada_per_utxo_byte"))?, + .map_err(|e| e.annotate("ada_per_utxo_byte"))?, ); } 18 => { @@ -623,7 +628,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(Costmdls::deserialize(raw)?) })() - .map_err(|e| e.annotate("cost_models"))?, + .map_err(|e| e.annotate("cost_models"))?, ); } 19 => { @@ -635,7 +640,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(ExUnitPrices::deserialize(raw)?) })() - .map_err(|e| e.annotate("execution_costs"))?, + .map_err(|e| e.annotate("execution_costs"))?, ); } 20 => { @@ -647,7 +652,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(ExUnits::deserialize(raw)?) })() - .map_err(|e| e.annotate("max_tx_ex_units"))?, + .map_err(|e| e.annotate("max_tx_ex_units"))?, ); } 21 => { @@ -659,7 +664,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(ExUnits::deserialize(raw)?) })() - .map_err(|e| e.annotate("max_block_ex_units"))?, + .map_err(|e| e.annotate("max_block_ex_units"))?, ); } 22 => { @@ -671,7 +676,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(u32::deserialize(raw)?) })() - .map_err(|e| e.annotate("max_value_size"))?, + .map_err(|e| e.annotate("max_value_size"))?, ); } 23 => { @@ -683,7 +688,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(u32::deserialize(raw)?) })() - .map_err(|e| e.annotate("collateral_percentage"))?, + .map_err(|e| e.annotate("collateral_percentage"))?, ); } 24 => { @@ -695,7 +700,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(u32::deserialize(raw)?) })() - .map_err(|e| e.annotate("max_collateral_inputs"))?, + .map_err(|e| e.annotate("max_collateral_inputs"))?, ); } 25 => { @@ -707,7 +712,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(PoolVotingThresholds::deserialize(raw)?) })() - .map_err(|e| e.annotate("pool_voting_thresholds"))?, + .map_err(|e| e.annotate("pool_voting_thresholds"))?, ); } 26 => { @@ -719,7 +724,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(DrepVotingThresholds::deserialize(raw)?) })() - .map_err(|e| e.annotate("drep_voting_thresholds"))?, + .map_err(|e| e.annotate("drep_voting_thresholds"))?, ); } 27 => { @@ -731,7 +736,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(u32::deserialize(raw)?) })() - .map_err(|e| e.annotate("min_committee_size"))?, + .map_err(|e| e.annotate("min_committee_size"))?, ); } 28 => { @@ -743,7 +748,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(Epoch::deserialize(raw)?) })() - .map_err(|e| e.annotate("committee_term_limit"))?, + .map_err(|e| e.annotate("committee_term_limit"))?, ); } 29 => { @@ -755,7 +760,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(Epoch::deserialize(raw)?) })() - .map_err(|e| e.annotate("governance_action_validity_period"))?, + .map_err(|e| e.annotate("governance_action_validity_period"))?, ); } 30 => { @@ -767,7 +772,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(Coin::deserialize(raw)?) })() - .map_err(|e| e.annotate("governance_action_deposit"))?, + .map_err(|e| e.annotate("governance_action_deposit"))?, ); } 31 => { @@ -779,7 +784,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(Coin::deserialize(raw)?) })() - .map_err(|e| e.annotate("drep_deposit"))?, + .map_err(|e| e.annotate("drep_deposit"))?, ); } 32 => { @@ -791,7 +796,7 @@ impl Deserialize for ProtocolParamUpdate { read_len.read_elems(1)?; Ok(Epoch::deserialize(raw)?) })() - .map_err(|e| e.annotate("drep_inactivity_period"))?, + .map_err(|e| e.annotate("drep_inactivity_period"))?, ); } unknown_key => { @@ -805,7 +810,7 @@ impl Deserialize for ProtocolParamUpdate { return Err(DeserializeFailure::UnknownKey(Key::Str( unknown_key.to_owned(), )) - .into()) + .into()) } }, CBORType::Special => match len { @@ -859,6 +864,6 @@ impl Deserialize for ProtocolParamUpdate { drep_inactivity_period, }) })() - .map_err(|e| e.annotate("ProtocolParamUpdate")) + .map_err(|e| e.annotate("ProtocolParamUpdate")) } -} \ No newline at end of file +} diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/mock_objects.rs index dd66b636..c6273d76 100644 --- a/rust/src/tests/mock_objects.rs +++ b/rust/src/tests/mock_objects.rs @@ -111,6 +111,7 @@ pub(crate) fn create_pool_voting_thresholds() -> PoolVotingThresholds { &UnitInterval::new(&BigNum::from(44_403u32), &BigNum::from(44_404u32)), &UnitInterval::new(&BigNum::from(44_405u32), &BigNum::from(44_406u32)), &UnitInterval::new(&BigNum::from(44_406u32), &BigNum::from(44_407u32)), + &UnitInterval::new(&BigNum::from(44_408u32), &BigNum::from(44_409u32)), ) } diff --git a/rust/src/tests/serialization/protocol_param_update.rs b/rust/src/tests/serialization/protocol_param_update.rs index 14316e66..80d2cce8 100644 --- a/rust/src/tests/serialization/protocol_param_update.rs +++ b/rust/src/tests/serialization/protocol_param_update.rs @@ -73,6 +73,7 @@ fn pool_voting_thresholds_ser_round_trip() { &UnitInterval::new(&BigNum::from(44_403u32), &BigNum::from(44_404u32)), &UnitInterval::new(&BigNum::from(44_405u32), &BigNum::from(44_406u32)), &UnitInterval::new(&BigNum::from(44_406u32), &BigNum::from(44_407u32)), + &UnitInterval::new(&BigNum::from(44_408u32), &BigNum::from(44_409u32)), ); let cbor = thresholds.to_bytes(); From ddcb25fb2cc3d2917a4d7e59870b0dba0a799d00 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 8 Mar 2024 11:34:10 +0700 Subject: [PATCH 242/349] bump version --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7b9d914d..8ad3f4ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.19", + "version": "12.0.0-alpha.20", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 45e50054..490f2269 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.19", + "version": "12.0.0-alpha.20", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 3fe26128..aa231d4d 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.19" +version = "12.0.0-alpha.20" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 95f3d3ad..85641108 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -55,7 +55,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.19" +version = "12.0.0-alpha.20" dependencies = [ "bech32", "cbor_event", From 4ba8973355d338db92ada2d47c4323496ab35f97 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 12 Mar 2024 21:58:10 +0700 Subject: [PATCH 243/349] plutus int json serialization fix --- rust/Cargo.toml | 2 +- rust/src/protocol_types/plutus/plutus_data.rs | 15 +++++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/rust/Cargo.toml b/rust/Cargo.toml index aa231d4d..8c00d078 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -25,7 +25,7 @@ bech32 = "0.7.2" hex = "0.4.0" cfg-if = "1" hashlink = "0.9.0" -serde_json = "1.0.57" +serde_json = { version = "1.0.57", features = ["arbitrary_precision"] } num-bigint = "0.4.0" num-integer = "0.1.45" # The default can't be compiled to wasm, so it's necessary to use either the 'nightly' diff --git a/rust/src/protocol_types/plutus/plutus_data.rs b/rust/src/protocol_types/plutus/plutus_data.rs index d4b972c0..9b2f0c97 100644 --- a/rust/src/protocol_types/plutus/plutus_data.rs +++ b/rust/src/protocol_types/plutus/plutus_data.rs @@ -10,6 +10,7 @@ use cbor_event::{ }; use schemars::JsonSchema; +use serde_json::Number; #[wasm_bindgen] #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] @@ -540,12 +541,10 @@ pub fn encode_json_value_to_plutus_datum( ) -> Result { use serde_json::Value; fn encode_number(x: serde_json::Number) -> Result { - if let Some(x) = x.as_u64() { - Ok(PlutusData::new_integer(&BigInt::from(x))) - } else if let Some(x) = x.as_i64() { - Ok(PlutusData::new_integer(&BigInt::from(x))) + if let Ok(big_int) = BigInt::from_str(x.as_str()) { + Ok(PlutusData::new_integer(&big_int)) } else { - Err(JsError::from_str("floats not allowed in plutus datums")) + Err(JsError::from_str(&format!("Expected an integer value but got \"{}\"", x))) } } fn encode_string( @@ -747,11 +746,7 @@ pub fn decode_plutus_datum_to_json_value( }, PlutusDataEnum::Integer(bigint) => ( Some("int"), - bigint - .as_int() - .as_ref() - .map(|int| if int.0 >= 0 { Value::from(int.0 as u64) } else { Value::from(int.0 as i64) }) - .ok_or_else(|| JsError::from_str(&format!("Integer {} too big for our JSON support", bigint.to_str())))? + Value::Number(Number::from_string_unchecked(bigint.to_str())) ), PlutusDataEnum::Bytes(bytes) => (Some("bytes"), Value::from(match schema { PlutusDatumSchema::BasicConversions => { From 2a43f482e3ea36ede38450835d4a941eeaf65baa Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 12 Mar 2024 21:59:02 +0700 Subject: [PATCH 244/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8ad3f4ba..f750b96b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.20", + "version": "12.0.0-alpha.21", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 490f2269..1bad90eb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.20", + "version": "12.0.0-alpha.21", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 8c00d078..a269847b 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.20" +version = "12.0.0-alpha.21" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 85641108..21d17203 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -55,7 +55,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.20" +version = "12.0.0-alpha.21" dependencies = [ "bech32", "cbor_event", From 494bbcc724ef1a6eddfa8b33f7a81d1bceda79b1 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 12 Mar 2024 22:19:22 +0700 Subject: [PATCH 245/349] fix serde version --- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 14 +++++++------- rust/json-gen/Cargo.toml | 2 +- rust/src/protocol_types/plutus/plutus_data.rs | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/rust/Cargo.toml b/rust/Cargo.toml index a269847b..ec3c2869 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -25,7 +25,7 @@ bech32 = "0.7.2" hex = "0.4.0" cfg-if = "1" hashlink = "0.9.0" -serde_json = { version = "1.0.57", features = ["arbitrary_precision"] } +serde_json = { version = "1.0.114", features = ["arbitrary_precision"] } num-bigint = "0.4.0" num-integer = "0.1.45" # The default can't be compiled to wasm, so it's necessary to use either the 'nightly' diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 21d17203..e41f09eb 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -508,9 +508,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.133" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] @@ -528,13 +528,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.133" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 1.0.85", + "syn 2.0.48", ] [[package]] @@ -550,9 +550,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.75" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ "itoa", "ryu", diff --git a/rust/json-gen/Cargo.toml b/rust/json-gen/Cargo.toml index 43a104e8..df6c8a6c 100644 --- a/rust/json-gen/Cargo.toml +++ b/rust/json-gen/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT" [dependencies] -serde_json = "1.0.57" +serde_json = { version = "1.0.114", features = ["arbitrary_precision"] } schemars = "0.8.8" #serde = { version = "1.0", features = ["derive"] } cardano-serialization-lib = { path = ".." } diff --git a/rust/src/protocol_types/plutus/plutus_data.rs b/rust/src/protocol_types/plutus/plutus_data.rs index 9b2f0c97..cd19e113 100644 --- a/rust/src/protocol_types/plutus/plutus_data.rs +++ b/rust/src/protocol_types/plutus/plutus_data.rs @@ -540,7 +540,7 @@ pub fn encode_json_value_to_plutus_datum( schema: PlutusDatumSchema, ) -> Result { use serde_json::Value; - fn encode_number(x: serde_json::Number) -> Result { + fn encode_number(x: Number) -> Result { if let Ok(big_int) = BigInt::from_str(x.as_str()) { Ok(PlutusData::new_integer(&big_int)) } else { From 76adf12219b77a2a6ce5a80190a159df8937b2b3 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 12 Mar 2024 22:21:01 +0700 Subject: [PATCH 246/349] flow update --- rust/pkg/cardano_serialization_lib.js.flow | 227 +++++++++++---------- 1 file changed, 115 insertions(+), 112 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 13f5ee3d..ab8d3f3c 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -5,6 +5,18 @@ * @flow */ +/** + * @param {Address} address + * @param {TransactionUnspentOutputs} utxos + * @param {TransactionBuilderConfig} config + * @returns {TransactionBatchList} + */ +declare export function create_send_all( + address: Address, + utxos: TransactionUnspentOutputs, + config: TransactionBuilderConfig +): TransactionBatchList; + /** * @param {string} json * @param {$Values< @@ -69,18 +81,6 @@ declare export function decode_metadatum_to_json_str( schema: $Values ): string; -/** - * @param {Address} address - * @param {TransactionUnspentOutputs} utxos - * @param {TransactionBuilderConfig} config - * @returns {TransactionBatchList} - */ -declare export function create_send_all( - address: Address, - utxos: TransactionUnspentOutputs, - config: TransactionBuilderConfig -): TransactionBatchList; - /** * @param {Transaction} tx * @param {LinearFee} linear_fee @@ -258,41 +258,36 @@ declare export function encode_json_str_to_native_script( ): NativeScript; /** + * Each new language uses a different namespace for hashing its script + * This is because you could have a language where the same bytes have different semantics + * So this avoids scripts in different languages mapping to the same hash + * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 -|}; - -/** - */ - -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 +declare export var ScriptHashNamespace: {| + +NativeScript: 0, // 0 + +PlutusScript: 1, // 1 + +PlutusScriptV2: 2, // 2 + +PlutusScriptV3: 3, // 3 |}; /** - * Used to choosed the schema for a script JSON string */ -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 |}; /** */ -declare export var GovernanceActionKind: {| - +ParameterChangeAction: 0, // 0 - +HardForkInitiationAction: 1, // 1 - +TreasuryWithdrawalsAction: 2, // 2 - +NoConfidenceAction: 3, // 3 - +UpdateCommitteeAction: 4, // 4 - +NewConstitutionAction: 5, // 5 - +InfoAction: 6, // 6 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 |}; /** @@ -312,41 +307,6 @@ declare export var PlutusDatumSchema: {| +DetailedSchema: 1, // 1 |}; -/** - * Each new language uses a different namespace for hashing its script - * This is because you could have a language where the same bytes have different semantics - * So this avoids scripts in different languages mapping to the same hash - * Note that the enum value here is different than the enum value for deciding the cost model of a script - */ - -declare export var ScriptHashNamespace: {| - +NativeScript: 0, // 0 - +PlutusScript: 1, // 1 - +PlutusScriptV2: 2, // 2 - +PlutusScriptV3: 3, // 3 -|}; - -/** - */ - -declare export var RelayKind: {| - +SingleHostAddr: 0, // 0 - +SingleHostName: 1, // 1 - +MultiHostName: 2, // 2 -|}; - -/** - */ - -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 -|}; - /** */ @@ -358,35 +318,33 @@ declare export var DRepKind: {| |}; /** + * Used to choosed the schema for a script JSON string */ -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** */ -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 |}; /** */ -declare export var RedeemerTagKind: {| - +Spend: 0, // 0 - +Mint: 1, // 1 - +Cert: 2, // 2 - +Reward: 3, // 3 - +Vote: 4, // 4 - +VotingProposal: 5, // 5 +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 |}; /** @@ -415,23 +373,22 @@ declare export var CertificateKind: {| /** */ -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 - +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 +declare export var GovernanceActionKind: {| + +ParameterChangeAction: 0, // 0 + +HardForkInitiationAction: 1, // 1 + +TreasuryWithdrawalsAction: 2, // 2 + +NoConfidenceAction: 3, // 3 + +UpdateCommitteeAction: 4, // 4 + +NewConstitutionAction: 5, // 5 + +InfoAction: 6, // 6 |}; /** @@ -453,20 +410,21 @@ declare export var MIRKind: {| /** */ -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 |}; /** */ -declare export var LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 +declare export var RelayKind: {| + +SingleHostAddr: 0, // 0 + +SingleHostName: 1, // 1 + +MultiHostName: 2, // 2 |}; /** @@ -481,9 +439,51 @@ declare export var MetadataJsonSchema: {| /** */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var RedeemerTagKind: {| + +Spend: 0, // 0 + +Mint: 1, // 1 + +Cert: 2, // 2 + +Reward: 3, // 3 + +Vote: 4, // 4 + +VotingProposal: 5, // 5 +|}; + +/** + */ + +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 +|}; + +/** + */ + +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 +|}; + +/** + */ + +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 +|}; + +/** + */ + +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** @@ -7551,13 +7551,15 @@ declare export class PoolVotingThresholds { * @param {UnitInterval} committee_normal * @param {UnitInterval} committee_no_confidence * @param {UnitInterval} hard_fork_initiation + * @param {UnitInterval} security_relevant_threshold * @returns {PoolVotingThresholds} */ static new( motion_no_confidence: UnitInterval, committee_normal: UnitInterval, committee_no_confidence: UnitInterval, - hard_fork_initiation: UnitInterval + hard_fork_initiation: UnitInterval, + security_relevant_threshold: UnitInterval ): PoolVotingThresholds; /** @@ -14252,6 +14254,7 @@ export interface PoolVotingThresholdsJSON { committee_normal: UnitIntervalJSON; hard_fork_initiation: UnitIntervalJSON; motion_no_confidence: UnitIntervalJSON; + security_relevant_threshold: UnitIntervalJSON; } export interface VoterVotesJSON { voter: VoterJSON; From af70ebf142a176b16b0f6e9f1b777b0869dc5c7d Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 12 Mar 2024 22:21:25 +0700 Subject: [PATCH 247/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index f750b96b..9a6ddc69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.21", + "version": "12.0.0-alpha.22", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 1bad90eb..2676ce31 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.21", + "version": "12.0.0-alpha.22", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index ec3c2869..44339f5d 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.21" +version = "12.0.0-alpha.22" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index e41f09eb..ccc80867 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -55,7 +55,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.21" +version = "12.0.0-alpha.22" dependencies = [ "bech32", "cbor_event", From 9f81842cfc97105cde5e445e539b42ac6b252b4e Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 13 Mar 2024 15:40:41 +0700 Subject: [PATCH 248/349] fix MintsAssets js interface --- rust/json-gen/src/main.rs | 1 + rust/pkg/cardano_serialization_lib.js.flow | 376 ++++++++++++--------- rust/src/lib.rs | 4 + 3 files changed, 212 insertions(+), 169 deletions(-) diff --git a/rust/json-gen/src/main.rs b/rust/json-gen/src/main.rs index ad40b55c..a8dbe15d 100644 --- a/rust/json-gen/src/main.rs +++ b/rust/json-gen/src/main.rs @@ -96,6 +96,7 @@ fn main() { gen_json_schema!(Assets); gen_json_schema!(MultiAsset); gen_json_schema!(MintAssets); + gen_json_schema!(MintsAssets); gen_json_schema!(Mint); gen_json_schema!(NetworkId); gen_json_schema!(NetworkIdKind); diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index ab8d3f3c..80c50e6e 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -5,18 +5,6 @@ * @flow */ -/** - * @param {Address} address - * @param {TransactionUnspentOutputs} utxos - * @param {TransactionBuilderConfig} config - * @returns {TransactionBatchList} - */ -declare export function create_send_all( - address: Address, - utxos: TransactionUnspentOutputs, - config: TransactionBuilderConfig -): TransactionBatchList; - /** * @param {string} json * @param {$Values< @@ -81,57 +69,6 @@ declare export function decode_metadatum_to_json_str( schema: $Values ): string; -/** - * @param {Transaction} tx - * @param {LinearFee} linear_fee - * @returns {BigNum} - */ -declare export function min_fee(tx: Transaction, linear_fee: LinearFee): BigNum; - -/** - * @param {ExUnits} ex_units - * @param {ExUnitPrices} ex_unit_prices - * @returns {BigNum} - */ -declare export function calculate_ex_units_ceil_cost( - ex_units: ExUnits, - ex_unit_prices: ExUnitPrices -): BigNum; - -/** - * @param {Transaction} tx - * @param {ExUnitPrices} ex_unit_prices - * @returns {BigNum} - */ -declare export function min_script_fee( - tx: Transaction, - ex_unit_prices: ExUnitPrices -): BigNum; - -/** - * @param {string} password - * @param {string} salt - * @param {string} nonce - * @param {string} data - * @returns {string} - */ -declare export function encrypt_with_password( - password: string, - salt: string, - nonce: string, - data: string -): string; - -/** - * @param {string} password - * @param {string} data - * @returns {string} - */ -declare export function decrypt_with_password( - password: string, - data: string -): string; - /** * @param {TransactionHash} tx_body_hash * @param {ByronAddress} addr @@ -257,6 +194,69 @@ declare export function encode_json_str_to_native_script( schema: $Values ): NativeScript; +/** + * @param {Transaction} tx + * @param {LinearFee} linear_fee + * @returns {BigNum} + */ +declare export function min_fee(tx: Transaction, linear_fee: LinearFee): BigNum; + +/** + * @param {ExUnits} ex_units + * @param {ExUnitPrices} ex_unit_prices + * @returns {BigNum} + */ +declare export function calculate_ex_units_ceil_cost( + ex_units: ExUnits, + ex_unit_prices: ExUnitPrices +): BigNum; + +/** + * @param {Transaction} tx + * @param {ExUnitPrices} ex_unit_prices + * @returns {BigNum} + */ +declare export function min_script_fee( + tx: Transaction, + ex_unit_prices: ExUnitPrices +): BigNum; + +/** + * @param {Address} address + * @param {TransactionUnspentOutputs} utxos + * @param {TransactionBuilderConfig} config + * @returns {TransactionBatchList} + */ +declare export function create_send_all( + address: Address, + utxos: TransactionUnspentOutputs, + config: TransactionBuilderConfig +): TransactionBatchList; + +/** + * @param {string} password + * @param {string} salt + * @param {string} nonce + * @param {string} data + * @returns {string} + */ +declare export function encrypt_with_password( + password: string, + salt: string, + nonce: string, + data: string +): string; + +/** + * @param {string} password + * @param {string} data + * @returns {string} + */ +declare export function decrypt_with_password( + password: string, + data: string +): string; + /** * Each new language uses a different namespace for hashing its script * This is because you could have a language where the same bytes have different semantics @@ -274,100 +274,76 @@ declare export var ScriptHashNamespace: {| /** */ -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 |}; /** */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** - * JSON <-> PlutusData conversion schemas. - * Follows ScriptDataJsonSchema in cardano-cli defined at: - * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 - * - * All methods here have the following restrictions due to limitations on dependencies: - * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors - * * Hex strings for bytes don't accept odd-length (half-byte) strings. - * cardano-cli seems to support these however but it seems to be different than just 0-padding - * on either side when tested so proceed with caution */ -declare export var PlutusDatumSchema: {| - +BasicConversions: 0, // 0 - +DetailedSchema: 1, // 1 +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 |}; /** */ -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 |}; /** - * Used to choosed the schema for a script JSON string */ -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 +declare export var RedeemerTagKind: {| + +Spend: 0, // 0 + +Mint: 1, // 1 + +Cert: 2, // 2 + +Reward: 3, // 3 + +Vote: 4, // 4 + +VotingProposal: 5, // 5 |}; /** */ -declare export var LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 |}; /** */ -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 |}; /** */ -declare export var CertificateKind: {| - +StakeRegistration: 0, // 0 - +StakeDeregistration: 1, // 1 - +StakeDelegation: 2, // 2 - +PoolRegistration: 3, // 3 - +PoolRetirement: 4, // 4 - +GenesisKeyDelegation: 5, // 5 - +MoveInstantaneousRewardsCert: 6, // 6 - +CommitteeHotAuth: 7, // 7 - +CommitteeColdResign: 8, // 8 - +DrepDeregistration: 9, // 9 - +DrepRegistration: 10, // 10 - +DrepUpdate: 11, // 11 - +StakeAndVoteDelegation: 12, // 12 - +StakeRegistrationAndDelegation: 13, // 13 - +StakeVoteRegistrationAndDelegation: 14, // 14 - +VoteDelegation: 15, // 15 - +VoteRegistrationAndDelegation: 16, // 16 +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 |}; /** @@ -381,41 +357,35 @@ declare export var CredKind: {| /** */ -declare export var GovernanceActionKind: {| - +ParameterChangeAction: 0, // 0 - +HardForkInitiationAction: 1, // 1 - +TreasuryWithdrawalsAction: 2, // 2 - +NoConfidenceAction: 3, // 3 - +UpdateCommitteeAction: 4, // 4 - +NewConstitutionAction: 5, // 5 - +InfoAction: 6, // 6 -|}; - -/** - */ - -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 |}; /** */ -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 |}; /** */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 |}; /** @@ -439,24 +409,24 @@ declare export var MetadataJsonSchema: {| /** */ -declare export var RedeemerTagKind: {| - +Spend: 0, // 0 - +Mint: 1, // 1 - +Cert: 2, // 2 - +Reward: 3, // 3 - +Vote: 4, // 4 - +VotingProposal: 5, // 5 -|}; - -/** - */ - -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 - +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 +declare export var CertificateKind: {| + +StakeRegistration: 0, // 0 + +StakeDeregistration: 1, // 1 + +StakeDelegation: 2, // 2 + +PoolRegistration: 3, // 3 + +PoolRetirement: 4, // 4 + +GenesisKeyDelegation: 5, // 5 + +MoveInstantaneousRewardsCert: 6, // 6 + +CommitteeHotAuth: 7, // 7 + +CommitteeColdResign: 8, // 8 + +DrepDeregistration: 9, // 9 + +DrepRegistration: 10, // 10 + +DrepUpdate: 11, // 11 + +StakeAndVoteDelegation: 12, // 12 + +StakeRegistrationAndDelegation: 13, // 13 + +StakeVoteRegistrationAndDelegation: 14, // 14 + +VoteDelegation: 15, // 15 + +VoteRegistrationAndDelegation: 16, // 16 |}; /** @@ -480,10 +450,40 @@ declare export var CoinSelectionStrategyCIP2: {| /** */ -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 +declare export var GovernanceActionKind: {| + +ParameterChangeAction: 0, // 0 + +HardForkInitiationAction: 1, // 1 + +TreasuryWithdrawalsAction: 2, // 2 + +NoConfidenceAction: 3, // 3 + +UpdateCommitteeAction: 4, // 4 + +NewConstitutionAction: 5, // 5 + +InfoAction: 6, // 6 +|}; + +/** + * JSON <-> PlutusData conversion schemas. + * Follows ScriptDataJsonSchema in cardano-cli defined at: + * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 + * + * All methods here have the following restrictions due to limitations on dependencies: + * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors + * * Hex strings for bytes don't accept odd-length (half-byte) strings. + * cardano-cli seems to support these however but it seems to be different than just 0-padding + * on either side when tested so proceed with caution + */ + +declare export var PlutusDatumSchema: {| + +BasicConversions: 0, // 0 + +DetailedSchema: 1, // 1 +|}; + +/** + * Used to choosed the schema for a script JSON string + */ + +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** @@ -5529,6 +5529,43 @@ declare export class MintWitness { */ declare export class MintsAssets { free(): void; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {MintsAssetsJSON} + */ + to_js_value(): MintsAssetsJSON; + + /** + * @param {string} json + * @returns {MintsAssets} + */ + static from_json(json: string): MintsAssets; + + /** + * @returns {MintsAssets} + */ + static new(): MintsAssets; + + /** + * @param {MintAssets} mint_assets + */ + add(mint_assets: MintAssets): void; + + /** + * @param {number} index + * @returns {MintAssets | void} + */ + get(index: number): MintAssets | void; + + /** + * @returns {number} + */ + len(): number; } /** */ @@ -14479,6 +14516,7 @@ export type LanguageJSON = LanguageKindJSON; export type LanguageKindJSON = "PlutusV1" | "PlutusV2" | "PlutusV3"; export type LanguagesJSON = LanguageJSON[]; export type MIRToStakeCredentialsJSON = StakeToCoinJSON[]; +export type MintsAssetsJSON = MintAssetsJSON[]; export type NetworkIdKindJSON = "Testnet" | "Mainnet"; export type PlutusScriptJSON = string; export type PoolMetadataHashJSON = string; diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 39f66e65..af7a0575 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1965,8 +1965,12 @@ impl PartialOrd for MultiAsset { } #[wasm_bindgen] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema)] pub struct MintsAssets(Vec); +to_from_json!(MintsAssets); + +#[wasm_bindgen] impl MintsAssets { pub fn new() -> Self { Self(Vec::new()) From 3e3380ce3ea8c1f2f27bf81b48ea489756b38f37 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 13 Mar 2024 15:41:29 +0700 Subject: [PATCH 249/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9a6ddc69..643e0aa7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.22", + "version": "12.0.0-alpha.23", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 2676ce31..70a52e14 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.22", + "version": "12.0.0-alpha.23", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 44339f5d..59d6494f 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.22" +version = "12.0.0-alpha.23" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index ccc80867..dd23223b 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -55,7 +55,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.22" +version = "12.0.0-alpha.23" dependencies = [ "bech32", "cbor_event", From ece403195132a9aecff41b64046c9d33e5dcc4a6 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 26 Mar 2024 19:57:32 +0700 Subject: [PATCH 250/349] temp fix for multiple keys in plutus map --- rust/src/serialization/plutus/plutus_data.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/rust/src/serialization/plutus/plutus_data.rs b/rust/src/serialization/plutus/plutus_data.rs index 9f9c9afa..9aa3e294 100644 --- a/rust/src/serialization/plutus/plutus_data.rs +++ b/rust/src/serialization/plutus/plutus_data.rs @@ -84,8 +84,9 @@ impl Deserialize for PlutusMap { let mut table = LinkedHashMap::new(); (|| -> Result<_, DeserializeError> { let len = raw.map()?; + let mut total = 0; while match len { - cbor_event::Len::Len(n) => table.len() < n as usize, + cbor_event::Len::Len(n) => total < n as usize, cbor_event::Len::Indefinite => true, } { if is_break_tag(raw, "PlutusMap")? { @@ -93,12 +94,8 @@ impl Deserialize for PlutusMap { } let key = PlutusData::deserialize(raw)?; let value = PlutusData::deserialize(raw)?; - if table.insert(key.clone(), value).is_some() { - return Err(DeserializeFailure::DuplicateKey(Key::Str(String::from( - "some complicated/unsupported type", - ))) - .into()); - } + table.insert(key.clone(), value); + total += 1; } Ok(()) })() From d384fb7bacbff462326b9d369b0f8137af9c3121 Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 28 Mar 2024 20:52:21 +0700 Subject: [PATCH 251/349] add redeemer flag, and malformed address --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- rust/pkg/cardano_serialization_lib.js.flow | 272 ++++++++++-------- rust/src/builders/mint_builder.rs | 4 +- rust/src/builders/tx_inputs_builder.rs | 3 + rust/src/error.rs | 2 + rust/src/protocol_types/address.rs | 192 +++++++++---- rust/src/protocol_types/plutus/plutus_data.rs | 3 + rust/src/protocol_types/plutus/redeemers.rs | 73 ++++- rust/src/serialization/plutus/redeemers.rs | 9 +- rust/src/tests/address.rs | 7 + rust/src/tests/builders/tx_builder.rs | 2 +- rust/src/tests/plutus.rs | 8 +- rust/src/tests/serialization/general.rs | 2 +- rust/src/utils.rs | 2 +- 17 files changed, 386 insertions(+), 201 deletions(-) diff --git a/package-lock.json b/package-lock.json index 643e0aa7..6b8cb268 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.23", + "version": "12.0.0-alpha.25", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 70a52e14..f1a34363 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.23", + "version": "12.0.0-alpha.25", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 59d6494f..5730bdfe 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.23" +version = "12.0.0-alpha.25" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index dd23223b..4642f963 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -55,7 +55,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.23" +version = "12.0.0-alpha.25" dependencies = [ "bech32", "cbor_event", diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 80c50e6e..6884e84f 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -257,54 +257,53 @@ declare export function decrypt_with_password( data: string ): string; -/** - * Each new language uses a different namespace for hashing its script - * This is because you could have a language where the same bytes have different semantics - * So this avoids scripts in different languages mapping to the same hash - * Note that the enum value here is different than the enum value for deciding the cost model of a script - */ - -declare export var ScriptHashNamespace: {| - +NativeScript: 0, // 0 - +PlutusScript: 1, // 1 - +PlutusScriptV2: 2, // 2 - +PlutusScriptV3: 3, // 3 -|}; - /** */ -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** */ -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 |}; /** */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 |}; /** */ -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 +declare export var CertificateKind: {| + +StakeRegistration: 0, // 0 + +StakeDeregistration: 1, // 1 + +StakeDelegation: 2, // 2 + +PoolRegistration: 3, // 3 + +PoolRetirement: 4, // 4 + +GenesisKeyDelegation: 5, // 5 + +MoveInstantaneousRewardsCert: 6, // 6 + +CommitteeHotAuth: 7, // 7 + +CommitteeColdResign: 8, // 8 + +DrepDeregistration: 9, // 9 + +DrepRegistration: 10, // 10 + +DrepUpdate: 11, // 11 + +StakeAndVoteDelegation: 12, // 12 + +StakeRegistrationAndDelegation: 13, // 13 + +StakeVoteRegistrationAndDelegation: 14, // 14 + +VoteDelegation: 15, // 15 + +VoteRegistrationAndDelegation: 16, // 16 |}; /** @@ -322,36 +321,30 @@ declare export var RedeemerTagKind: {| /** */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 -|}; - -/** - */ - -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 |}; /** */ -declare export var LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 +declare export var RelayKind: {| + +SingleHostAddr: 0, // 0 + +SingleHostName: 1, // 1 + +MultiHostName: 2, // 2 |}; /** */ -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 |}; /** @@ -369,82 +362,43 @@ declare export var NativeScriptKind: {| /** */ -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 -|}; - -/** - */ - -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 +declare export var CborContainerType: {| + +Array: 0, // 0 +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 -|}; - -/** - */ - -declare export var RelayKind: {| - +SingleHostAddr: 0, // 0 - +SingleHostName: 1, // 1 - +MultiHostName: 2, // 2 -|}; - -/** - */ - -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 |}; /** */ -declare export var CertificateKind: {| - +StakeRegistration: 0, // 0 - +StakeDeregistration: 1, // 1 - +StakeDelegation: 2, // 2 - +PoolRegistration: 3, // 3 - +PoolRetirement: 4, // 4 - +GenesisKeyDelegation: 5, // 5 - +MoveInstantaneousRewardsCert: 6, // 6 - +CommitteeHotAuth: 7, // 7 - +CommitteeColdResign: 8, // 8 - +DrepDeregistration: 9, // 9 - +DrepRegistration: 10, // 10 - +DrepUpdate: 11, // 11 - +StakeAndVoteDelegation: 12, // 12 - +StakeRegistrationAndDelegation: 13, // 13 - +StakeVoteRegistrationAndDelegation: 14, // 14 - +VoteDelegation: 15, // 15 - +VoteRegistrationAndDelegation: 16, // 16 +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 |}; /** */ -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** + * Each new language uses a different namespace for hashing its script + * This is because you could have a language where the same bytes have different semantics + * So this avoids scripts in different languages mapping to the same hash + * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 +declare export var ScriptHashNamespace: {| + +NativeScript: 0, // 0 + +PlutusScript: 1, // 1 + +PlutusScriptV2: 2, // 2 + +PlutusScriptV3: 3, // 3 |}; /** @@ -460,6 +414,15 @@ declare export var GovernanceActionKind: {| +InfoAction: 6, // 6 |}; +/** + * Used to choosed the schema for a script JSON string + */ + +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 +|}; + /** * JSON <-> PlutusData conversion schemas. * Follows ScriptDataJsonSchema in cardano-cli defined at: @@ -478,12 +441,49 @@ declare export var PlutusDatumSchema: {| |}; /** - * Used to choosed the schema for a script JSON string */ -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 +|}; + +/** + */ + +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 +|}; + +/** + */ + +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 +|}; + +/** + */ + +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 +|}; + +/** + */ + +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 |}; /** @@ -513,6 +513,11 @@ declare export class Address { */ static from_json(json: string): Address; + /** + * @returns {boolean} + */ + is_malformed(): boolean; + /** * @returns {string} */ @@ -5171,6 +5176,27 @@ declare export class MIRToStakeCredentials { */ keys(): Credentials; } +/** + */ +declare export class MalformedAddress { + free(): void; + + /** + * @returns {Uint8Array} + */ + original_bytes(): Uint8Array; + + /** + * @returns {Address} + */ + to_address(): Address; + + /** + * @param {Address} addr + * @returns {MalformedAddress | void} + */ + static from_address(addr: Address): MalformedAddress | void; +} /** */ declare export class MetadataList { @@ -5492,7 +5518,7 @@ declare export class MintBuilder { /** * @returns {Redeemers} */ - get_redeeemers(): Redeemers; + get_redeemers(): Redeemers; /** * @returns {boolean} @@ -8482,6 +8508,18 @@ declare export class Redeemers { */ static new(): Redeemers; + /** + * @param {(Redeemer)[]} redeemers + * @param {$Values< + typeof + CborContainerType>} serialization_format + * @returns {Redeemers} + */ + static new_with_serialization_format( + redeemers: Redeemer[], + serialization_format: $Values + ): Redeemers; + /** * @returns {number} */ @@ -13983,7 +14021,6 @@ export type RedeemerTagJSON = | "Reward" | "Vote" | "VotingProposal"; -export type RedeemersJSON = RedeemerJSON[]; export type TransactionWitnessSetsJSON = TransactionWitnessSetJSON[]; export interface BlockJSON { auxiliary_data_set: { @@ -14360,7 +14397,7 @@ export interface TransactionWitnessSetJSON { native_scripts?: NativeScriptsJSON | null; plutus_data?: PlutusListJSON | null; plutus_scripts?: PlutusScriptsJSON | null; - redeemers?: RedeemersJSON | null; + redeemers?: RedeemerJSON[] | null; vkeys?: VkeywitnessJSON[] | null; } export interface BootstrapWitnessJSON { @@ -14531,6 +14568,7 @@ export type RedeemerTagKindJSON = | "Reward" | "Vote" | "VotingProposal"; +export type RedeemersJSON = RedeemerJSON[]; export type RelayEnumJSON = | { SingleHostAddr: SingleHostAddrJSON, diff --git a/rust/src/builders/mint_builder.rs b/rust/src/builders/mint_builder.rs index b737f54b..093ac804 100644 --- a/rust/src/builders/mint_builder.rs +++ b/rust/src/builders/mint_builder.rs @@ -212,7 +212,7 @@ impl MintBuilder { TransactionInputs(reference_inputs) } - pub fn get_redeeemers(&self) -> Result { + pub fn get_redeemers(&self) -> Result { let tag = RedeemerTag::new_mint(); let mut redeeemers = Vec::new(); let mut index = BigNum::zero(); @@ -229,7 +229,7 @@ impl MintBuilder { } } } - Ok(Redeemers(redeeemers)) + Ok(Redeemers::from(redeeemers)) } pub fn has_plutus_scripts(&self) -> bool { diff --git a/rust/src/builders/tx_inputs_builder.rs b/rust/src/builders/tx_inputs_builder.rs index 40d486fd..b087fc26 100644 --- a/rust/src/builders/tx_inputs_builder.rs +++ b/rust/src/builders/tx_inputs_builder.rs @@ -162,6 +162,9 @@ impl TxInputsBuilder { AddrType::Reward(_) => { Err(JsError::from_str(BuilderError::RegularInputIsFromRewardAddress.as_str())) }, + AddrType::Malformed(_) => { + Err(JsError::from_str(BuilderError::MalformedAddress.as_str())) + }, } } diff --git a/rust/src/error.rs b/rust/src/error.rs index c1c32b88..60f8b253 100644 --- a/rust/src/error.rs +++ b/rust/src/error.rs @@ -227,6 +227,7 @@ impl std::error::Error for JsError {} pub(crate) enum BuilderError { RegularInputIsScript, RegularInputIsFromRewardAddress, + MalformedAddress } impl BuilderError { @@ -234,6 +235,7 @@ impl BuilderError { match self { BuilderError::RegularInputIsScript => "You can't add a script input to this function. You can use `.add_native_script_input` or `.add_plutus_script_input` directly to register the input along with the witness.", BuilderError::RegularInputIsFromRewardAddress => "You can't use an input from reward address. To spend funds from reward address you to use withdrawal mechanism.", + BuilderError::MalformedAddress => "The address is malformed." } } } diff --git a/rust/src/protocol_types/address.rs b/rust/src/protocol_types/address.rs index 041832fc..7a1497aa 100644 --- a/rust/src/protocol_types/address.rs +++ b/rust/src/protocol_types/address.rs @@ -73,6 +73,70 @@ impl NetworkInfo { } } +#[wasm_bindgen] +#[derive(Debug, Clone, Eq, Ord, PartialEq, PartialOrd)] +pub struct MalformedAddress(pub(crate) Vec); + +#[wasm_bindgen] +impl MalformedAddress { + pub fn original_bytes(&self) -> Vec { + self.0.clone() + } + + pub fn to_address(&self) -> Address { + Address(AddrType::Malformed(self.clone())) + } + + pub fn from_address(addr: &Address) -> Option { + match &addr.0 { + AddrType::Malformed(malformed) => Some(malformed.clone()), + _ => None, + } + } +} + +impl serde::Serialize for MalformedAddress { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let bech32 = self + .to_address() + .to_bech32(None) + .map_err(|e| serde::ser::Error::custom(format!("to_bech32: {:?}", e)))?; + serializer.serialize_str(&bech32) + } +} + +impl<'de> serde::de::Deserialize<'de> for MalformedAddress { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let bech32 = ::deserialize(deserializer)?; + match Address::from_bech32(&bech32).map(|addr| addr.0) + { + Ok(AddrType::Malformed(malformed_address)) => Ok(malformed_address), + _ => Err(serde::de::Error::invalid_value( + serde::de::Unexpected::Str(&bech32), + &"bech32 malformed address string", + )), + } + } +} + +impl JsonSchema for MalformedAddress { + fn schema_name() -> String { + String::from("MalformedAddress") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + String::json_schema(gen) + } + fn is_referenceable() -> bool { + String::is_referenceable() + } +} + #[derive(Debug, Clone, Eq, Ord, PartialEq, PartialOrd)] pub(crate) enum AddrType { Base(BaseAddress), @@ -80,6 +144,7 @@ pub(crate) enum AddrType { Enterprise(EnterpriseAddress), Reward(RewardAddress), Byron(ByronAddress), + Malformed(MalformedAddress), } #[wasm_bindgen] @@ -237,6 +302,11 @@ impl JsonSchema for Address { // other CBOR types #[wasm_bindgen] impl Address { + + pub fn is_malformed(&self) -> bool { + matches!(&self.0, AddrType::Malformed(_)) + } + pub fn to_hex(&self) -> String { hex::encode(self.to_bytes()) } @@ -282,6 +352,7 @@ impl Address { buf.extend(reward.payment.to_raw_bytes()); } AddrType::Byron(byron) => buf.extend(byron.to_bytes()), + AddrType::Malformed(malformed) => buf.extend(malformed.0.clone()), } buf } @@ -321,21 +392,21 @@ impl Address { }; x }; - let addr = match (header & 0xF0) >> 4 { + let addr: Result = match (header & 0xF0) >> 4 { // base 0b0000 | 0b0001 | 0b0010 | 0b0011 => { const BASE_ADDR_SIZE: usize = 1 + HASH_LEN * 2; if data.len() < BASE_ADDR_SIZE { - return Err(cbor_event::Error::NotEnough(data.len(), BASE_ADDR_SIZE).into()); + Err(cbor_event::Error::NotEnough(data.len(), BASE_ADDR_SIZE).into()) + } else if data.len() > BASE_ADDR_SIZE { + Err(cbor_event::Error::TrailingData.into()) + } else { + Ok(AddrType::Base(BaseAddress::new( + network, + &read_addr_cred(4, 1), + &read_addr_cred(5, 1 + HASH_LEN), + ))) } - if data.len() > BASE_ADDR_SIZE { - return Err(cbor_event::Error::TrailingData.into()); - } - AddrType::Base(BaseAddress::new( - network, - &read_addr_cred(4, 1), - &read_addr_cred(5, 1 + HASH_LEN), - )) } // pointer 0b0100 | 0b0101 => { @@ -346,53 +417,55 @@ impl Address { return Err( cbor_event::Error::NotEnough(data.len(), PTR_ADDR_MIN_SIZE).into() ); + } else { + let mut byte_index = 1; + let payment_cred = read_addr_cred(4, 1); + byte_index += HASH_LEN; + let (slot, slot_bytes) = + variable_nat_decode(&data[byte_index..]).ok_or(DeserializeError::new( + "Address.Pointer.slot", + DeserializeFailure::VariableLenNatDecodeFailed, + ))?; + byte_index += slot_bytes; + let (tx_index, tx_bytes) = + variable_nat_decode(&data[byte_index..]).ok_or(DeserializeError::new( + "Address.Pointer.tx_index", + DeserializeFailure::VariableLenNatDecodeFailed, + ))?; + byte_index += tx_bytes; + let (cert_index, cert_bytes) = + variable_nat_decode(&data[byte_index..]).ok_or(DeserializeError::new( + "Address.Pointer.cert_index", + DeserializeFailure::VariableLenNatDecodeFailed, + ))?; + byte_index += cert_bytes; + if byte_index < data.len() { + return Err(cbor_event::Error::TrailingData.into()); + } + Ok(AddrType::Ptr(PointerAddress::new( + network, + &payment_cred, + &Pointer::new_pointer( + &to_bignum(slot), + &to_bignum(tx_index), + &to_bignum(cert_index), + ), + ))) } - let mut byte_index = 1; - let payment_cred = read_addr_cred(4, 1); - byte_index += HASH_LEN; - let (slot, slot_bytes) = - variable_nat_decode(&data[byte_index..]).ok_or(DeserializeError::new( - "Address.Pointer.slot", - DeserializeFailure::VariableLenNatDecodeFailed, - ))?; - byte_index += slot_bytes; - let (tx_index, tx_bytes) = - variable_nat_decode(&data[byte_index..]).ok_or(DeserializeError::new( - "Address.Pointer.tx_index", - DeserializeFailure::VariableLenNatDecodeFailed, - ))?; - byte_index += tx_bytes; - let (cert_index, cert_bytes) = - variable_nat_decode(&data[byte_index..]).ok_or(DeserializeError::new( - "Address.Pointer.cert_index", - DeserializeFailure::VariableLenNatDecodeFailed, - ))?; - byte_index += cert_bytes; - if byte_index < data.len() { - return Err(cbor_event::Error::TrailingData.into()); - } - AddrType::Ptr(PointerAddress::new( - network, - &payment_cred, - &Pointer::new_pointer( - &to_bignum(slot), - &to_bignum(tx_index), - &to_bignum(cert_index), - ), - )) } // enterprise 0b0110 | 0b0111 => { const ENTERPRISE_ADDR_SIZE: usize = 1 + HASH_LEN; if data.len() < ENTERPRISE_ADDR_SIZE { - return Err( + Err( cbor_event::Error::NotEnough(data.len(), ENTERPRISE_ADDR_SIZE).into(), - ); - } - if data.len() > ENTERPRISE_ADDR_SIZE { - return Err(cbor_event::Error::TrailingData.into()); + ) + } else { + if data.len() > ENTERPRISE_ADDR_SIZE { + return Err(cbor_event::Error::TrailingData.into()); + } + Ok(AddrType::Enterprise(EnterpriseAddress::new(network, &read_addr_cred(4, 1)))) } - AddrType::Enterprise(EnterpriseAddress::new(network, &read_addr_cred(4, 1))) } // reward 0b1110 | 0b1111 => { @@ -401,29 +474,33 @@ impl Address { return Err( cbor_event::Error::NotEnough(data.len(), REWARD_ADDR_SIZE).into() ); + } else { + if data.len() > REWARD_ADDR_SIZE { + return Err(cbor_event::Error::TrailingData.into()); + } + Ok(AddrType::Reward(RewardAddress::new(network, &read_addr_cred(4, 1)))) } - if data.len() > REWARD_ADDR_SIZE { - return Err(cbor_event::Error::TrailingData.into()); - } - AddrType::Reward(RewardAddress::new(network, &read_addr_cred(4, 1))) } // byron 0b1000 => { // note: 0b1000 was chosen because all existing Byron addresses actually start with 0b1000 // Therefore you can re-use Byron addresses as-is match ByronAddress::from_bytes(data.to_vec()) { - Ok(addr) => AddrType::Byron(addr), + Ok(addr) => Ok(AddrType::Byron(addr)), Err(e) => { - return Err(cbor_event::Error::CustomError( + Err(cbor_event::Error::CustomError( e.as_string().unwrap_or_default(), ) .into()) } } } - _ => return Err(DeserializeFailure::BadAddressType(header).into()), + _ => Err(DeserializeFailure::BadAddressType(header).into()), }; - Ok(Address(addr)) + match addr { + Ok(addr) => Ok(Address(addr)), + Err(_) => Ok(Address(AddrType::Malformed(MalformedAddress(data.to_vec())))), + } })() .map_err(|e| e.annotate("Address")) } @@ -463,6 +540,7 @@ impl Address { AddrType::Ptr(a) => Ok(a.network), AddrType::Reward(a) => Ok(a.network), AddrType::Byron(a) => a.network_id(), + AddrType::Malformed(_) => Err(JsError::from_str("Malformed address")), } } } diff --git a/rust/src/protocol_types/plutus/plutus_data.rs b/rust/src/protocol_types/plutus/plutus_data.rs index cd19e113..4d4eb4b0 100644 --- a/rust/src/protocol_types/plutus/plutus_data.rs +++ b/rust/src/protocol_types/plutus/plutus_data.rs @@ -260,6 +260,9 @@ impl PlutusData { AddrType::Byron(_) => Err(JsError::from_str( "Cannot convert Byron address to PlutusData", )), + AddrType::Malformed(_) => Err(JsError::from_str( + "Cannot convert Malformed address to PlutusData", + )) }?; let staking_data = match &address.0 { diff --git a/rust/src/protocol_types/plutus/redeemers.rs b/rust/src/protocol_types/plutus/redeemers.rs index 78b042ed..59aad75f 100644 --- a/rust/src/protocol_types/plutus/redeemers.rs +++ b/rust/src/protocol_types/plutus/redeemers.rs @@ -1,36 +1,50 @@ use crate::*; #[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct Redeemers(pub(crate) Vec); +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub struct Redeemers { + pub(crate) redeemers: Vec, + pub(crate) serialization_format: Option, +} impl_to_from!(Redeemers); #[wasm_bindgen] impl Redeemers { pub fn new() -> Self { - Self(Vec::new()) + Self { + redeemers: Vec::new(), + serialization_format: None, + } + } + + pub fn new_with_serialization_format( + redeemers: Vec, + serialization_format: CborContainerType, + ) -> Self { + Self { + redeemers, + serialization_format: Some(serialization_format), + } } pub fn len(&self) -> usize { - self.0.len() + self.redeemers.len() } pub fn get(&self, index: usize) -> Redeemer { - self.0[index].clone() + self.redeemers[index].clone() } pub fn add(&mut self, elem: &Redeemer) { - self.0.push(elem.clone()); + self.redeemers.push(elem.clone()); } pub fn total_ex_units(&self) -> Result { let mut tot_mem = BigNum::zero(); let mut tot_steps = BigNum::zero(); - for i in 0..self.0.len() { - let r: &Redeemer = &self.0[i]; + for i in 0..self.redeemers.len() { + let r: &Redeemer = &self.redeemers[i]; tot_mem = tot_mem.checked_add(&r.ex_units().mem())?; tot_steps = tot_steps.checked_add(&r.ex_units().steps())?; } @@ -40,6 +54,43 @@ impl Redeemers { impl From> for Redeemers { fn from(values: Vec) -> Self { - Self(values) + Self { + redeemers: values, + serialization_format: None, + } + } +} + +impl serde::Serialize for Redeemers { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + self.redeemers.serialize(serializer) + } +} + +impl<'de> serde::de::Deserialize<'de> for Redeemers { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let vec = as serde::de::Deserialize>::deserialize(deserializer)?; + Ok(Self { + redeemers: vec, + serialization_format: None, + }) + } +} + +impl JsonSchema for Redeemers { + fn is_referenceable() -> bool { + Vec::::is_referenceable() + } + fn schema_name() -> String { + String::from("Redeemers") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + Vec::::json_schema(gen) } } diff --git a/rust/src/serialization/plutus/redeemers.rs b/rust/src/serialization/plutus/redeemers.rs index 07e5ab4d..c28c1abb 100644 --- a/rust/src/serialization/plutus/redeemers.rs +++ b/rust/src/serialization/plutus/redeemers.rs @@ -6,8 +6,8 @@ impl cbor_event::se::Serialize for Redeemers { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { + serializer.write_array(Len::Len(self.redeemers.len() as u64))?; + for element in &self.redeemers { element.serialize(serializer)?; } Ok(serializer) @@ -31,6 +31,9 @@ impl Deserialize for Redeemers { Ok(()) })() .map_err(|e| e.annotate("Redeemers"))?; - Ok(Self(arr)) + Ok(Self{ + redeemers: arr, + serialization_format: None, + }) } } \ No newline at end of file diff --git a/rust/src/tests/address.rs b/rust/src/tests/address.rs index f205c94f..536f2dc9 100644 --- a/rust/src/tests/address.rs +++ b/rust/src/tests/address.rs @@ -558,3 +558,10 @@ fn prepod_network_id_test() { .unwrap(); assert_eq!(network_id, NetworkInfo::testnet_preprod().network_id()); } + +#[test] +fn malformed_address() { + let address_bech32 = "addr1q9d66zzs27kppmx8qc8h43q7m4hkxp5d39377lvxefvxd8j7eukjsdqc5c97t2zg5guqadepqqx6rc9m7wtnxy6tajjvk4a0kze4ljyuvvrpexg5up2sqxj33363v35gtew"; + let address = Address::from_bech32(address_bech32).unwrap(); + assert!(address.is_malformed()); +} \ No newline at end of file diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index ea411849..98205f8d 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -6128,7 +6128,7 @@ fn build_tx_with_certs_withdrawals_plutus_script_address() { let mut indexes = HashMap::new(); indexes.insert(RedeemerTag::new_cert(), HashSet::new()); indexes.insert(RedeemerTag::new_reward(), HashSet::new()); - for redeemer in &redeemers.0 { + for redeemer in &redeemers.redeemers { let tag_set = indexes.get_mut(&redeemer.tag()).unwrap(); assert_ne!(tag_set.contains(&redeemer.index()), true); tag_set.insert(redeemer.index()); diff --git a/rust/src/tests/plutus.rs b/rust/src/tests/plutus.rs index fc2bb212..601b0621 100644 --- a/rust/src/tests/plutus.rs +++ b/rust/src/tests/plutus.rs @@ -370,7 +370,7 @@ fn test_known_plutus_data_hash() { ]), ), )]); - let redeemers = Redeemers(vec![Redeemer::new( + let redeemers = Redeemers::from(vec![Redeemer::new( &RedeemerTag::new_spend(), &BigNum::one(), &PlutusData::new_empty_constr_plutus_data(&BigNum::zero()), @@ -416,7 +416,7 @@ fn test_known_plutus_data_hash_with_no_datums() { .unwrap(), ); let hash = hash_script_data( - &Redeemers(vec![Redeemer::new( + &Redeemers::from(vec![Redeemer::new( &RedeemerTag::new_spend(), &BigNum::zero(), &PlutusData::new_empty_constr_plutus_data(&BigNum::zero()), @@ -450,7 +450,7 @@ fn test_known_plutus_data_hash_2() { ]), ), )]); - let redeemers = Redeemers(vec![Redeemer::new( + let redeemers = Redeemers::from(vec![Redeemer::new( &RedeemerTag::new_spend(), &BigNum::one(), &PlutusData::new_empty_constr_plutus_data(&BigNum::one()), @@ -522,4 +522,4 @@ fn datum_from_base_key_script_address() { let orig_datum = PlutusData::from_json("{\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"bytes\": \"88ac6bd19c1a17ed88051b1586536cd1cc408be21efb7ada33be6afd\"}]}, {\"constructor\": 0, \"fields\": [{\"constructor\": 0, \"fields\": [{\"constructor\": 1, \"fields\": [{\"bytes\": \"dc3b534f7621f6c83304bbb99e0f44ca168c3f0932b1b521ee0030a6\"}]}]}]}]}", PlutusDatumSchema::DetailedSchema).unwrap(); assert_eq!(datum, orig_datum); -} +} \ No newline at end of file diff --git a/rust/src/tests/serialization/general.rs b/rust/src/tests/serialization/general.rs index 1e400a6f..bb1f4033 100644 --- a/rust/src/tests/serialization/general.rs +++ b/rust/src/tests/serialization/general.rs @@ -509,7 +509,7 @@ fn test_witness_set_roundtrip() { &fake_vkey(), &fake_signature(1), )])); - ws.set_redeemers(&Redeemers(vec![Redeemer::new( + ws.set_redeemers(&Redeemers::from(vec![Redeemer::new( &RedeemerTag::new_spend(), &to_bignum(12), &PlutusData::new_integer(&BigInt::one()), diff --git a/rust/src/utils.rs b/rust/src/utils.rs index ee568843..c09ae7c0 100644 --- a/rust/src/utils.rs +++ b/rust/src/utils.rs @@ -2543,7 +2543,7 @@ mod tests { let mut costmodels = Costmdls::new(); costmodels.insert(&v1, &v1_cost_model); let hash = hash_script_data( - &Redeemers(vec![Redeemer::new( + &Redeemers::from(vec![Redeemer::new( &RedeemerTag::new_spend(), &BigNum::zero(), &PlutusData::new_integer(&BigInt::from_str("42").unwrap()), From 16eed2261379705fe9a1b0a221adbee28e5895aa Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 3 Apr 2024 10:58:12 +0300 Subject: [PATCH 252/349] fix MintsAssets.add type --- rust/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index af7a0575..aa36221e 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1976,8 +1976,8 @@ impl MintsAssets { Self(Vec::new()) } - pub fn add(&mut self, mint_assets: MintAssets) { - self.0.push(mint_assets) + pub fn add(&mut self, mint_assets: &MintAssets) { + self.0.push(mint_assets.clone()) } pub fn get(&self, index: usize) -> Option { From 735c54c30ce0cae87cab54ec02416fb6ea4e0398 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 3 Apr 2024 15:35:05 +0300 Subject: [PATCH 253/349] fix fee calculation for extra datum --- rust/src/builders/tx_builder.rs | 11 ++++++- rust/src/protocol_types/plutus/plutus_data.rs | 4 +++ rust/src/tests/builders/tx_builder.rs | 33 +++++++++++-------- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index e1d64917..68c588f3 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -102,7 +102,7 @@ pub(crate) fn fake_full_tx( Some(result) } }; - let (plutus_scripts, plutus_data, redeemers) = { + let (plutus_scripts, mut plutus_data, redeemers) = { if let Some(s) = tx_builder.get_combined_plutus_scripts() { let (s, d, r) = s.collect(); (Some(s), d, Some(r)) @@ -110,6 +110,15 @@ pub(crate) fn fake_full_tx( (None, None, None) } }; + + if let Some(extra_datums) = &tx_builder.extra_datums { + if let Some(d) = &mut plutus_data { + d.extend(extra_datums); + } else { + plutus_data = Some(extra_datums.clone()); + } + } + let witness_set = TransactionWitnessSet { vkeys, native_scripts: tx_builder.get_combined_native_scripts(), diff --git a/rust/src/protocol_types/plutus/plutus_data.rs b/rust/src/protocol_types/plutus/plutus_data.rs index 4d4eb4b0..d3c8fee3 100644 --- a/rust/src/protocol_types/plutus/plutus_data.rs +++ b/rust/src/protocol_types/plutus/plutus_data.rs @@ -465,6 +465,10 @@ impl PlutusList { definite_encoding: self.definite_encoding, } } + + pub(crate) fn extend(&mut self, other: &PlutusList) { + self.elems.extend(other.elems.iter().cloned()); + } } impl From> for PlutusList { diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index 98205f8d..5b94664f 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -1,14 +1,6 @@ -use crate::fakes::{ - fake_base_address, fake_bytes_32, fake_data_hash, fake_key_hash, fake_policy_id, - fake_script_hash, fake_tx_hash, fake_tx_input, fake_tx_input2, fake_value, fake_value2, -}; +use crate::fakes::{fake_base_address, fake_bytes_32, fake_data_hash, fake_key_hash, fake_policy_id, fake_script_hash, fake_tx_hash, fake_tx_input, fake_tx_input2, fake_value, fake_value2, fake_vkey_witness}; use crate::tests::helpers::harden; -use crate::tests::mock_objects::{ - byron_address, create_change_address, create_default_tx_builder, create_linear_fee, - create_reallistic_tx_builder, create_rich_tx_builder, create_tx_builder_with_amount, - create_tx_builder_with_fee, create_tx_builder_with_fee_and_pure_change, - create_tx_builder_with_fee_and_val_size, create_tx_builder_with_key_deposit, root_key_15, -}; +use crate::tests::mock_objects::{byron_address, create_change_address, create_default_tx_builder, create_linear_fee, create_reallistic_tx_builder, create_rich_tx_builder, create_tx_builder, create_tx_builder_with_amount, create_tx_builder_with_fee, create_tx_builder_with_fee_and_pure_change, create_tx_builder_with_fee_and_val_size, create_tx_builder_with_key_deposit, root_key_15}; use crate::*; use fees::*; @@ -6145,8 +6137,12 @@ fn build_tx_with_certs_withdrawals_plutus_script_address() { #[test] pub fn test_extra_datum() { - let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); + let mut tx_builder = create_tx_builder( + &create_linear_fee(1, 100000), + 1, + 1, + 1, + ); let datum = PlutusData::new_bytes(fake_bytes_32(1)); tx_builder.add_extra_witness_datum(&datum); @@ -6155,19 +6151,28 @@ pub fn test_extra_datum() { inp.add_regular_input( &fake_base_address(0), &fake_tx_input(0), - &Value::new(&to_bignum(1000000u64)), - ); + &Value::new(&to_bignum(100000000000000u64)), + ).unwrap(); tx_builder.set_inputs(&inp); tx_builder .calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()) .unwrap(); + let change_address = create_change_address(); + + tx_builder.add_change_if_needed(&change_address).unwrap(); let res = tx_builder.build_tx(); assert!(res.is_ok()); let tx = res.unwrap(); + let tx_size = tx.to_bytes().len(); + let fake_input_wit_size = fake_vkey_witness(1).to_bytes().len(); + let real_fee = min_fee_for_size(tx_size + fake_input_wit_size, &LinearFee::new(&Coin::from(1u64), &Coin::from(100000u64))).unwrap(); + + assert!(real_fee.less_than(&tx.body.fee)); + let data_hash = hash_script_data( &Redeemers::new(), &Costmdls::new(), From 4a464a05de798bb7db586f01c1c1ae8c9a38c37a Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 3 Apr 2024 15:37:17 +0300 Subject: [PATCH 254/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- rust/pkg/cardano_serialization_lib.js.flow | 384 ++++++++++----------- 5 files changed, 196 insertions(+), 196 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6b8cb268..d9b9c135 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.25", + "version": "12.0.0-alpha.26", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index f1a34363..5dc96136 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.25", + "version": "12.0.0-alpha.26", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 5730bdfe..603df48f 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.25" +version = "12.0.0-alpha.26" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 4642f963..4fdca2e2 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -55,7 +55,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.25" +version = "12.0.0-alpha.26" dependencies = [ "bech32", "cbor_event", diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 6884e84f..b7f327c3 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -6,68 +6,43 @@ */ /** - * @param {string} json - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {PlutusData} - */ -declare export function encode_json_str_to_plutus_datum( - json: string, - schema: $Values -): PlutusData; - -/** - * @param {PlutusData} datum - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {string} - */ -declare export function decode_plutus_datum_to_json_str( - datum: PlutusData, - schema: $Values -): string; - -/** - * @param {Uint8Array} bytes - * @returns {TransactionMetadatum} + * @param {Transaction} tx + * @param {LinearFee} linear_fee + * @returns {BigNum} */ -declare export function encode_arbitrary_bytes_as_metadatum( - bytes: Uint8Array -): TransactionMetadatum; +declare export function min_fee(tx: Transaction, linear_fee: LinearFee): BigNum; /** - * @param {TransactionMetadatum} metadata - * @returns {Uint8Array} + * @param {ExUnits} ex_units + * @param {ExUnitPrices} ex_unit_prices + * @returns {BigNum} */ -declare export function decode_arbitrary_bytes_from_metadatum( - metadata: TransactionMetadatum -): Uint8Array; +declare export function calculate_ex_units_ceil_cost( + ex_units: ExUnits, + ex_unit_prices: ExUnitPrices +): BigNum; /** - * @param {string} json - * @param {$Values< - typeof - MetadataJsonSchema>} schema - * @returns {TransactionMetadatum} + * @param {Transaction} tx + * @param {ExUnitPrices} ex_unit_prices + * @returns {BigNum} */ -declare export function encode_json_str_to_metadatum( - json: string, - schema: $Values -): TransactionMetadatum; +declare export function min_script_fee( + tx: Transaction, + ex_unit_prices: ExUnitPrices +): BigNum; /** - * @param {TransactionMetadatum} metadatum - * @param {$Values< - typeof - MetadataJsonSchema>} schema - * @returns {string} + * @param {Address} address + * @param {TransactionUnspentOutputs} utxos + * @param {TransactionBuilderConfig} config + * @returns {TransactionBatchList} */ -declare export function decode_metadatum_to_json_str( - metadatum: TransactionMetadatum, - schema: $Values -): string; +declare export function create_send_all( + address: Address, + utxos: TransactionUnspentOutputs, + config: TransactionBuilderConfig +): TransactionBatchList; /** * @param {TransactionHash} tx_body_hash @@ -195,43 +170,68 @@ declare export function encode_json_str_to_native_script( ): NativeScript; /** - * @param {Transaction} tx - * @param {LinearFee} linear_fee - * @returns {BigNum} + * @param {string} json + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {PlutusData} */ -declare export function min_fee(tx: Transaction, linear_fee: LinearFee): BigNum; +declare export function encode_json_str_to_plutus_datum( + json: string, + schema: $Values +): PlutusData; /** - * @param {ExUnits} ex_units - * @param {ExUnitPrices} ex_unit_prices - * @returns {BigNum} + * @param {PlutusData} datum + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {string} */ -declare export function calculate_ex_units_ceil_cost( - ex_units: ExUnits, - ex_unit_prices: ExUnitPrices -): BigNum; +declare export function decode_plutus_datum_to_json_str( + datum: PlutusData, + schema: $Values +): string; /** - * @param {Transaction} tx - * @param {ExUnitPrices} ex_unit_prices - * @returns {BigNum} + * @param {Uint8Array} bytes + * @returns {TransactionMetadatum} */ -declare export function min_script_fee( - tx: Transaction, - ex_unit_prices: ExUnitPrices -): BigNum; +declare export function encode_arbitrary_bytes_as_metadatum( + bytes: Uint8Array +): TransactionMetadatum; /** - * @param {Address} address - * @param {TransactionUnspentOutputs} utxos - * @param {TransactionBuilderConfig} config - * @returns {TransactionBatchList} + * @param {TransactionMetadatum} metadata + * @returns {Uint8Array} */ -declare export function create_send_all( - address: Address, - utxos: TransactionUnspentOutputs, - config: TransactionBuilderConfig -): TransactionBatchList; +declare export function decode_arbitrary_bytes_from_metadatum( + metadata: TransactionMetadatum +): Uint8Array; + +/** + * @param {string} json + * @param {$Values< + typeof + MetadataJsonSchema>} schema + * @returns {TransactionMetadatum} + */ +declare export function encode_json_str_to_metadatum( + json: string, + schema: $Values +): TransactionMetadatum; + +/** + * @param {TransactionMetadatum} metadatum + * @param {$Values< + typeof + MetadataJsonSchema>} schema + * @returns {string} + */ +declare export function decode_metadatum_to_json_str( + metadatum: TransactionMetadatum, + schema: $Values +): string; /** * @param {string} password @@ -257,67 +257,6 @@ declare export function decrypt_with_password( data: string ): string; -/** - */ - -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 -|}; - -/** - */ - -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 -|}; - -/** - */ - -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 -|}; - -/** - */ - -declare export var CertificateKind: {| - +StakeRegistration: 0, // 0 - +StakeDeregistration: 1, // 1 - +StakeDelegation: 2, // 2 - +PoolRegistration: 3, // 3 - +PoolRetirement: 4, // 4 - +GenesisKeyDelegation: 5, // 5 - +MoveInstantaneousRewardsCert: 6, // 6 - +CommitteeHotAuth: 7, // 7 - +CommitteeColdResign: 8, // 8 - +DrepDeregistration: 9, // 9 - +DrepRegistration: 10, // 10 - +DrepUpdate: 11, // 11 - +StakeAndVoteDelegation: 12, // 12 - +StakeRegistrationAndDelegation: 13, // 13 - +StakeVoteRegistrationAndDelegation: 14, // 14 - +VoteDelegation: 15, // 15 - +VoteRegistrationAndDelegation: 16, // 16 -|}; - -/** - */ - -declare export var RedeemerTagKind: {| - +Spend: 0, // 0 - +Mint: 1, // 1 - +Cert: 2, // 2 - +Reward: 3, // 3 - +Vote: 4, // 4 - +VotingProposal: 5, // 5 -|}; - /** */ @@ -332,31 +271,23 @@ declare export var PlutusDataKind: {| /** */ -declare export var RelayKind: {| - +SingleHostAddr: 0, // 0 - +SingleHostName: 1, // 1 - +MultiHostName: 2, // 2 -|}; - -/** - */ - -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** */ -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 +declare export var GovernanceActionKind: {| + +ParameterChangeAction: 0, // 0 + +HardForkInitiationAction: 1, // 1 + +TreasuryWithdrawalsAction: 2, // 2 + +NoConfidenceAction: 3, // 3 + +UpdateCommitteeAction: 4, // 4 + +NewConstitutionAction: 5, // 5 + +InfoAction: 6, // 6 |}; /** @@ -370,21 +301,21 @@ declare export var CborContainerType: {| /** */ -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** */ -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 |}; /** @@ -404,23 +335,28 @@ declare export var ScriptHashNamespace: {| /** */ -declare export var GovernanceActionKind: {| - +ParameterChangeAction: 0, // 0 - +HardForkInitiationAction: 1, // 1 - +TreasuryWithdrawalsAction: 2, // 2 - +NoConfidenceAction: 3, // 3 - +UpdateCommitteeAction: 4, // 4 - +NewConstitutionAction: 5, // 5 - +InfoAction: 6, // 6 +declare export var RelayKind: {| + +SingleHostAddr: 0, // 0 + +SingleHostName: 1, // 1 + +MultiHostName: 2, // 2 |}; /** - * Used to choosed the schema for a script JSON string */ -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 +|}; + +/** + */ + +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 |}; /** @@ -443,17 +379,42 @@ declare export var PlutusDatumSchema: {| /** */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 |}; /** */ -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 +declare export var CertificateKind: {| + +StakeRegistration: 0, // 0 + +StakeDeregistration: 1, // 1 + +StakeDelegation: 2, // 2 + +PoolRegistration: 3, // 3 + +PoolRetirement: 4, // 4 + +GenesisKeyDelegation: 5, // 5 + +MoveInstantaneousRewardsCert: 6, // 6 + +CommitteeHotAuth: 7, // 7 + +CommitteeColdResign: 8, // 8 + +DrepDeregistration: 9, // 9 + +DrepRegistration: 10, // 10 + +DrepUpdate: 11, // 11 + +StakeAndVoteDelegation: 12, // 12 + +StakeRegistrationAndDelegation: 13, // 13 + +StakeVoteRegistrationAndDelegation: 14, // 14 + +VoteDelegation: 15, // 15 + +VoteRegistrationAndDelegation: 16, // 16 +|}; + +/** + */ + +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 |}; /** @@ -470,10 +431,28 @@ declare export var VoterKind: {| /** */ -declare export var LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 +|}; + +/** + */ + +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 +|}; + +/** + */ + +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 |}; /** @@ -486,6 +465,27 @@ declare export var CoinSelectionStrategyCIP2: {| +RandomImproveMultiAsset: 3, // 3 |}; +/** + */ + +declare export var RedeemerTagKind: {| + +Spend: 0, // 0 + +Mint: 1, // 1 + +Cert: 2, // 2 + +Reward: 3, // 3 + +Vote: 4, // 4 + +VotingProposal: 5, // 5 +|}; + +/** + * Used to choosed the schema for a script JSON string + */ + +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 +|}; + /** */ declare export class Address { From c7fb324d3a60ee367bf4d1d8f2f11be5f4426310 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 5 Apr 2024 00:07:43 +0300 Subject: [PATCH 255/349] add redeemers map serialization/deserialization --- release.sh | 4 +- rust/src/error.rs | 4 + rust/src/protocol_types/plutus/redeemers.rs | 13 +- rust/src/serialization/plutus/redeemer.rs | 137 ++++++++++++++++---- rust/src/serialization/plutus/redeemers.rs | 73 ++++++++--- rust/src/tests/serialization/general.rs | 118 +++++++++++++++++ 6 files changed, 299 insertions(+), 50 deletions(-) diff --git a/release.sh b/release.sh index c15ecb44..67c89902 100644 --- a/release.sh +++ b/release.sh @@ -9,8 +9,8 @@ fi echo "Preparing ${RELEASE_TYPE} release" -. build-and-test.sh \ +. ./build-and-test.sh \ && npm run js:publish-nodejs:${RELEASE_TYPE} \ && npm run js:publish-browser:${RELEASE_TYPE} \ && npm run js:publish-asm:${RELEASE_TYPE} \ -&& (cd rust; cargo publish --allow-dirty) \ No newline at end of file +&& (cd rust; cargo publish --allow-dirty) diff --git a/rust/src/error.rs b/rust/src/error.rs index 60f8b253..66744fbd 100644 --- a/rust/src/error.rs +++ b/rust/src/error.rs @@ -60,6 +60,7 @@ pub enum DeserializeFailure { UnexpectedKeyType(cbor_event::Type), VariableLenNatDecodeFailed, IoError(String), + ExpectedType(String, cbor_event::Type), CustomError(String), } @@ -141,6 +142,9 @@ impl std::fmt::Display for DeserializeError { } DeserializeFailure::IoError(e) => write!(f, "IO error: {}", e), DeserializeFailure::CustomError(e) => write!(f, "Deserialize error: {}", e), + DeserializeFailure::ExpectedType(expected, found) => { + write!(f, "Expected type {}, found {:?}", expected, found) + } } } } diff --git a/rust/src/protocol_types/plutus/redeemers.rs b/rust/src/protocol_types/plutus/redeemers.rs index 59aad75f..feb309f8 100644 --- a/rust/src/protocol_types/plutus/redeemers.rs +++ b/rust/src/protocol_types/plutus/redeemers.rs @@ -1,7 +1,7 @@ use crate::*; #[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +#[derive(Clone, Debug, Ord, PartialOrd)] pub struct Redeemers { pub(crate) redeemers: Vec, pub(crate) serialization_format: Option, @@ -18,7 +18,7 @@ impl Redeemers { } } - pub fn new_with_serialization_format( + pub(crate) fn new_with_serialization_format( redeemers: Vec, serialization_format: CborContainerType, ) -> Self { @@ -52,6 +52,15 @@ impl Redeemers { } } +impl PartialEq for Redeemers { + fn eq(&self, other: &Redeemers) -> bool { + self.redeemers == other.redeemers + } + +} + +impl Eq for Redeemers {} + impl From> for Redeemers { fn from(values: Vec) -> Self { Self { diff --git a/rust/src/serialization/plutus/redeemer.rs b/rust/src/serialization/plutus/redeemer.rs index ebcfcbb8..522194c1 100644 --- a/rust/src/serialization/plutus/redeemer.rs +++ b/rust/src/serialization/plutus/redeemer.rs @@ -1,47 +1,128 @@ use crate::*; +use crate::serialization::utils::check_len_indefinite; impl cbor_event::se::Serialize for Redeemer { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(4))?; + self.serialize_as_array_item(serializer)?; + Ok(serializer) + } +} + +impl Redeemer { + pub(crate) fn serialize_as_array_item<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(Len::Len(4))?; self.tag.serialize(serializer)?; self.index.serialize(serializer)?; self.data.serialize(serializer)?; self.ex_units.serialize(serializer)?; Ok(serializer) } + + pub(crate) fn serialize_as_map_item<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + self.serialize_as_map_key(serializer)?; + self.serialize_as_map_value(serializer) + } + fn serialize_as_map_key<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(Len::Len(2))?; + self.tag.serialize(serializer)?; + self.index.serialize(serializer)?; + Ok(serializer) + } + + fn serialize_as_map_value<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(Len::Len(2))?; + self.data.serialize(serializer)?; + self.ex_units.serialize(serializer)?; + Ok(serializer) + } } impl Deserialize for Redeemer { fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let mut read_len = CBORReadLen::new(len); - read_len.read_elems(4)?; - let tag = (|| -> Result<_, DeserializeError> { Ok(RedeemerTag::deserialize(raw)?) })() - .map_err(|e| e.annotate("tag"))?; - let index = (|| -> Result<_, DeserializeError> { Ok(BigNum::deserialize(raw)?) })() - .map_err(|e| e.annotate("index"))?; - let data = (|| -> Result<_, DeserializeError> { Ok(PlutusData::deserialize(raw)?) })() - .map_err(|e| e.annotate("data"))?; - let ex_units = (|| -> Result<_, DeserializeError> { Ok(ExUnits::deserialize(raw)?) })() - .map_err(|e| e.annotate("ex_units"))?; - match len { - cbor_event::Len::Len(_) => (), - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => (), - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - Ok(Redeemer { - tag, - index, - data, - ex_units, - }) - })() - .map_err(|e| e.annotate("Redeemer")) + Self::deserialize_as_array_item(raw).map_err(|e| e.annotate("Redeemer")) + } +} + +impl Redeemer { + pub(crate) fn deserialize_as_array_item( + raw: &mut Deserializer, + ) -> Result { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(4)?; + let tag = (|| -> Result<_, DeserializeError> { Ok(RedeemerTag::deserialize(raw)?) })() + .map_err(|e| e.annotate("tag"))?; + let index = (|| -> Result<_, DeserializeError> { Ok(BigNum::deserialize(raw)?) })() + .map_err(|e| e.annotate("index"))?; + let data = (|| -> Result<_, DeserializeError> { Ok(PlutusData::deserialize(raw)?) })() + .map_err(|e| e.annotate("data"))?; + let ex_units = (|| -> Result<_, DeserializeError> { Ok(ExUnits::deserialize(raw)?) })() + .map_err(|e| e.annotate("ex_units"))?; + check_len_indefinite(raw, len)?; + Ok(Redeemer { + tag, + index, + data, + ex_units, + }) + } + + pub(crate) fn deserialize_as_map_item( + raw: &mut Deserializer, + ) -> Result { + let (tag, index) = Self::deserialize_map_key(raw)?; + let (data, ex_units) = Self::deserialize_map_value(raw)?; + + Ok(Self { + tag, + index, + data, + ex_units, + }) + } + + fn deserialize_map_key( + raw: &mut Deserializer, + ) -> Result<(RedeemerTag, BigNum), DeserializeError> { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(2)?; + + let tag = RedeemerTag::deserialize(raw)?; + let index = BigNum::deserialize(raw)?; + + check_len_indefinite(raw, len)?; + + Ok((tag, index)) + } + + fn deserialize_map_value( + raw: &mut Deserializer, + ) -> Result<(PlutusData, ExUnits), DeserializeError> { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(2)?; + + let data = PlutusData::deserialize(raw)?; + let ex_units = ExUnits::deserialize(raw)?; + + check_len_indefinite(raw, len)?; + + Ok((data, ex_units)) } } \ No newline at end of file diff --git a/rust/src/serialization/plutus/redeemers.rs b/rust/src/serialization/plutus/redeemers.rs index c28c1abb..1dc73c12 100644 --- a/rust/src/serialization/plutus/redeemers.rs +++ b/rust/src/serialization/plutus/redeemers.rs @@ -6,9 +6,19 @@ impl cbor_event::se::Serialize for Redeemers { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(Len::Len(self.redeemers.len() as u64))?; - for element in &self.redeemers { - element.serialize(serializer)?; + match self.serialization_format { + Some(CborContainerType::Map) => { + serializer.write_map(Len::Len(self.redeemers.len() as u64))?; + for element in &self.redeemers { + element.serialize_as_map_item(serializer)?; + } + } + _ => { + serializer.write_array(Len::Len(self.redeemers.len() as u64))?; + for element in &self.redeemers { + element.serialize_as_array_item(serializer)?; + } + } } Ok(serializer) } @@ -16,24 +26,51 @@ impl cbor_event::se::Serialize for Redeemers { impl Deserialize for Redeemers { fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result { + let cbor_type = raw.cbor_type()?; + match cbor_type { + cbor_event::Type::Array => Self::deserialize_as_array(raw), + cbor_event::Type::Map => Self::deserialize_as_map(raw), + _ => return Err(DeserializeFailure::ExpectedType("Array or Map".to_string(), cbor_type).into()), + } + })().map_err(|e| e.annotate("Redeemers")) + } +} + +impl Redeemers { + fn deserialize_as_map(raw: &mut Deserializer) -> Result { let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if is_break_tag(raw, "Redeemers")? { - break; - } - arr.push(Redeemer::deserialize(raw)?); + let len = raw.map()?; + while match len { + Len::Len(n) => arr.len() < n as usize, + Len::Indefinite => true, + } { + if is_break_tag(raw, "Redeemers")? { + break; } - Ok(()) - })() - .map_err(|e| e.annotate("Redeemers"))?; - Ok(Self{ + arr.push(Redeemer::deserialize_as_map_item(raw)?); + } + Ok(Self { + redeemers: arr, + serialization_format: Some(CborContainerType::Map), + }) + } + + fn deserialize_as_array(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + let len = raw.array()?; + while match len { + Len::Len(n) => arr.len() < n as usize, + Len::Indefinite => true, + } { + if is_break_tag(raw, "Redeemers")? { + break; + } + arr.push(Redeemer::deserialize_as_array_item(raw)?); + } + Ok(Self { redeemers: arr, - serialization_format: None, + serialization_format: Some(CborContainerType::Array), }) } } \ No newline at end of file diff --git a/rust/src/tests/serialization/general.rs b/rust/src/tests/serialization/general.rs index bb1f4033..5240f281 100644 --- a/rust/src/tests/serialization/general.rs +++ b/rust/src/tests/serialization/general.rs @@ -641,4 +641,122 @@ fn oura_wrapped_block_test() { let bytes = hex::decode(hex).unwrap(); let block = Block::from_wrapped_bytes(bytes); assert!(block.is_ok()); +} + +#[test] +fn redeemers_default_array_round_trip() { + let mut redeemers = Redeemers::from(vec![ + Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(12), + &PlutusData::new_integer(&BigInt::one()), + &ExUnits::new(&to_bignum(123), &to_bignum(456)), + ), + Redeemer::new( + &RedeemerTag::new_cert(), + &to_bignum(2), + &PlutusData::new_integer(&BigInt::from(22)), + &ExUnits::new(&to_bignum(23), &to_bignum(45)), + ) + ]); + + let bytes = redeemers.to_bytes(); + let new_redeemers = Redeemers::from_bytes(bytes.clone()).unwrap(); + + assert_eq!(new_redeemers.serialization_format, Some(CborContainerType::Array)); + assert_eq!(redeemers.serialization_format, None); + assert_eq!(redeemers, new_redeemers); + assert_eq!(bytes, new_redeemers.to_bytes()) +} + +#[test] +fn redeemers_array_round_trip() { + let redeemers_vec = vec![ + Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(12), + &PlutusData::new_integer(&BigInt::one()), + &ExUnits::new(&to_bignum(123), &to_bignum(456)), + ), + Redeemer::new( + &RedeemerTag::new_cert(), + &to_bignum(2), + &PlutusData::new_integer(&BigInt::from(22)), + &ExUnits::new(&to_bignum(23), &to_bignum(45)), + ) + ]; + + let redeemers = Redeemers::new_with_serialization_format(redeemers_vec, CborContainerType::Array); + + let bytes = redeemers.to_bytes(); + let new_redeemers = Redeemers::from_bytes(bytes.clone()).unwrap(); + + assert_eq!(new_redeemers.serialization_format, Some(CborContainerType::Array)); + assert_eq!(redeemers, new_redeemers); + assert_eq!(bytes, new_redeemers.to_bytes()) +} + +#[test] +fn redeemers_map_round_trip() { + let redeemers_vec = vec![ + Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(12), + &PlutusData::new_integer(&BigInt::one()), + &ExUnits::new(&to_bignum(123), &to_bignum(456)), + ), + Redeemer::new( + &RedeemerTag::new_cert(), + &to_bignum(2), + &PlutusData::new_integer(&BigInt::from(22)), + &ExUnits::new(&to_bignum(23), &to_bignum(45)), + ) + ]; + + let redeemers = Redeemers::new_with_serialization_format(redeemers_vec, CborContainerType::Map); + + let bytes = redeemers.to_bytes(); + let new_redeemers = Redeemers::from_bytes(bytes.clone()).unwrap(); + + assert_eq!(new_redeemers.serialization_format, Some(CborContainerType::Map)); + assert_eq!(redeemers, new_redeemers); + assert_eq!(bytes, new_redeemers.to_bytes()) +} + +#[test] +fn redeemers_map_array_round_trip() { + let redeemers_vec = vec![ + Redeemer::new( + &RedeemerTag::new_spend(), + &to_bignum(12), + &PlutusData::new_integer(&BigInt::one()), + &ExUnits::new(&to_bignum(123), &to_bignum(456)), + ), + Redeemer::new( + &RedeemerTag::new_cert(), + &to_bignum(2), + &PlutusData::new_integer(&BigInt::from(22)), + &ExUnits::new(&to_bignum(23), &to_bignum(45)), + ) + ]; + + let redeemers_array = Redeemers::new_with_serialization_format(redeemers_vec.clone(), CborContainerType::Array); + let redeemers_map = Redeemers::new_with_serialization_format(redeemers_vec, CborContainerType::Map); + + let bytes_array = redeemers_array.to_bytes(); + let new_redeemers_array = Redeemers::from_bytes(bytes_array.clone()).unwrap(); + + let bytes_map = redeemers_map.to_bytes(); + let new_redeemers_map = Redeemers::from_bytes(bytes_map.clone()).unwrap(); + + assert_eq!(new_redeemers_array.serialization_format, Some(CborContainerType::Array)); + assert_eq!(redeemers_array, new_redeemers_array); + assert_eq!(bytes_array, new_redeemers_array.to_bytes()); + + assert_eq!(new_redeemers_map.serialization_format, Some(CborContainerType::Map)); + assert_eq!(redeemers_map, new_redeemers_map); + assert_eq!(bytes_map, new_redeemers_map.to_bytes()); + + assert_eq!(new_redeemers_map, new_redeemers_array); + assert_ne!(bytes_array, bytes_map) } \ No newline at end of file From 0e221bebc9d8393c8a9ddd04060ea76d90c3cf13 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 5 Apr 2024 00:08:29 +0300 Subject: [PATCH 256/349] revert release.sh --- release.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.sh b/release.sh index 67c89902..53ad10bf 100644 --- a/release.sh +++ b/release.sh @@ -9,7 +9,7 @@ fi echo "Preparing ${RELEASE_TYPE} release" -. ./build-and-test.sh \ +. build-and-test.sh \ && npm run js:publish-nodejs:${RELEASE_TYPE} \ && npm run js:publish-browser:${RELEASE_TYPE} \ && npm run js:publish-asm:${RELEASE_TYPE} \ From 196f25f14c4d277b188bf1beea772221d17b66b7 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 10 Apr 2024 15:31:20 +0300 Subject: [PATCH 257/349] fix address deserialization --- rust/src/protocol_types/address.rs | 39 ++++++++++++++++-------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/rust/src/protocol_types/address.rs b/rust/src/protocol_types/address.rs index 7a1497aa..98d82cde 100644 --- a/rust/src/protocol_types/address.rs +++ b/rust/src/protocol_types/address.rs @@ -414,9 +414,9 @@ impl Address { const PTR_ADDR_MIN_SIZE: usize = 1 + HASH_LEN + 1 + 1 + 1; if data.len() < PTR_ADDR_MIN_SIZE { // possibly more, but depends on how many bytes the natural numbers are for the pointer - return Err( + Err( cbor_event::Error::NotEnough(data.len(), PTR_ADDR_MIN_SIZE).into() - ); + ) } else { let mut byte_index = 1; let payment_cred = read_addr_cred(4, 1); @@ -440,17 +440,18 @@ impl Address { ))?; byte_index += cert_bytes; if byte_index < data.len() { - return Err(cbor_event::Error::TrailingData.into()); + Err(cbor_event::Error::TrailingData.into()) + } else { + Ok(AddrType::Ptr(PointerAddress::new( + network, + &payment_cred, + &Pointer::new_pointer( + &to_bignum(slot), + &to_bignum(tx_index), + &to_bignum(cert_index), + ), + ))) } - Ok(AddrType::Ptr(PointerAddress::new( - network, - &payment_cred, - &Pointer::new_pointer( - &to_bignum(slot), - &to_bignum(tx_index), - &to_bignum(cert_index), - ), - ))) } } // enterprise @@ -462,23 +463,25 @@ impl Address { ) } else { if data.len() > ENTERPRISE_ADDR_SIZE { - return Err(cbor_event::Error::TrailingData.into()); + Err(cbor_event::Error::TrailingData.into()) + } else { + Ok(AddrType::Enterprise(EnterpriseAddress::new(network, &read_addr_cred(4, 1)))) } - Ok(AddrType::Enterprise(EnterpriseAddress::new(network, &read_addr_cred(4, 1)))) } } // reward 0b1110 | 0b1111 => { const REWARD_ADDR_SIZE: usize = 1 + HASH_LEN; if data.len() < REWARD_ADDR_SIZE { - return Err( + Err( cbor_event::Error::NotEnough(data.len(), REWARD_ADDR_SIZE).into() - ); + ) } else { if data.len() > REWARD_ADDR_SIZE { - return Err(cbor_event::Error::TrailingData.into()); + Err(cbor_event::Error::TrailingData.into()) + } else { + Ok(AddrType::Reward(RewardAddress::new(network, &read_addr_cred(4, 1)))) } - Ok(AddrType::Reward(RewardAddress::new(network, &read_addr_cred(4, 1)))) } } // byron From 53558f3e1ddd209e5c35d073c928f3f3dce39a97 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 10 Apr 2024 15:40:25 +0300 Subject: [PATCH 258/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index d9b9c135..6791105e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.26", + "version": "12.0.0-alpha.27", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 5dc96136..485dffb0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.26", + "version": "12.0.0-alpha.27", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 603df48f..3a9fdf5c 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.26" +version = "12.0.0-alpha.27" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 4fdca2e2..15da2a6f 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -55,7 +55,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.26" +version = "12.0.0-alpha.27" dependencies = [ "bech32", "cbor_event", From 3707b43a78773a9649abc241f4fb88368d454dc4 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 10 Apr 2024 16:19:13 +0300 Subject: [PATCH 259/349] flow update --- rust/pkg/cardano_serialization_lib.js.flow | 382 ++++++++++----------- 1 file changed, 185 insertions(+), 197 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index b7f327c3..93ed1bc3 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -5,6 +5,70 @@ * @flow */ +/** + * @param {string} json + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {PlutusData} + */ +declare export function encode_json_str_to_plutus_datum( + json: string, + schema: $Values +): PlutusData; + +/** + * @param {PlutusData} datum + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {string} + */ +declare export function decode_plutus_datum_to_json_str( + datum: PlutusData, + schema: $Values +): string; + +/** + * @param {Uint8Array} bytes + * @returns {TransactionMetadatum} + */ +declare export function encode_arbitrary_bytes_as_metadatum( + bytes: Uint8Array +): TransactionMetadatum; + +/** + * @param {TransactionMetadatum} metadata + * @returns {Uint8Array} + */ +declare export function decode_arbitrary_bytes_from_metadatum( + metadata: TransactionMetadatum +): Uint8Array; + +/** + * @param {string} json + * @param {$Values< + typeof + MetadataJsonSchema>} schema + * @returns {TransactionMetadatum} + */ +declare export function encode_json_str_to_metadatum( + json: string, + schema: $Values +): TransactionMetadatum; + +/** + * @param {TransactionMetadatum} metadatum + * @param {$Values< + typeof + MetadataJsonSchema>} schema + * @returns {string} + */ +declare export function decode_metadatum_to_json_str( + metadatum: TransactionMetadatum, + schema: $Values +): string; + /** * @param {Transaction} tx * @param {LinearFee} linear_fee @@ -32,18 +96,6 @@ declare export function min_script_fee( ex_unit_prices: ExUnitPrices ): BigNum; -/** - * @param {Address} address - * @param {TransactionUnspentOutputs} utxos - * @param {TransactionBuilderConfig} config - * @returns {TransactionBatchList} - */ -declare export function create_send_all( - address: Address, - utxos: TransactionUnspentOutputs, - config: TransactionBuilderConfig -): TransactionBatchList; - /** * @param {TransactionHash} tx_body_hash * @param {ByronAddress} addr @@ -169,70 +221,6 @@ declare export function encode_json_str_to_native_script( schema: $Values ): NativeScript; -/** - * @param {string} json - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {PlutusData} - */ -declare export function encode_json_str_to_plutus_datum( - json: string, - schema: $Values -): PlutusData; - -/** - * @param {PlutusData} datum - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {string} - */ -declare export function decode_plutus_datum_to_json_str( - datum: PlutusData, - schema: $Values -): string; - -/** - * @param {Uint8Array} bytes - * @returns {TransactionMetadatum} - */ -declare export function encode_arbitrary_bytes_as_metadatum( - bytes: Uint8Array -): TransactionMetadatum; - -/** - * @param {TransactionMetadatum} metadata - * @returns {Uint8Array} - */ -declare export function decode_arbitrary_bytes_from_metadatum( - metadata: TransactionMetadatum -): Uint8Array; - -/** - * @param {string} json - * @param {$Values< - typeof - MetadataJsonSchema>} schema - * @returns {TransactionMetadatum} - */ -declare export function encode_json_str_to_metadatum( - json: string, - schema: $Values -): TransactionMetadatum; - -/** - * @param {TransactionMetadatum} metadatum - * @param {$Values< - typeof - MetadataJsonSchema>} schema - * @returns {string} - */ -declare export function decode_metadatum_to_json_str( - metadatum: TransactionMetadatum, - schema: $Values -): string; - /** * @param {string} password * @param {string} salt @@ -258,64 +246,54 @@ declare export function decrypt_with_password( ): string; /** + * @param {Address} address + * @param {TransactionUnspentOutputs} utxos + * @param {TransactionBuilderConfig} config + * @returns {TransactionBatchList} */ - -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 - +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 -|}; - -/** - */ - -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 -|}; +declare export function create_send_all( + address: Address, + utxos: TransactionUnspentOutputs, + config: TransactionBuilderConfig +): TransactionBatchList; /** */ -declare export var GovernanceActionKind: {| - +ParameterChangeAction: 0, // 0 - +HardForkInitiationAction: 1, // 1 - +TreasuryWithdrawalsAction: 2, // 2 - +NoConfidenceAction: 3, // 3 - +UpdateCommitteeAction: 4, // 4 - +NewConstitutionAction: 5, // 5 - +InfoAction: 6, // 6 +declare export var RedeemerTagKind: {| + +Spend: 0, // 0 + +Mint: 1, // 1 + +Cert: 2, // 2 + +Reward: 3, // 3 + +Vote: 4, // 4 + +VotingProposal: 5, // 5 |}; /** */ -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 |}; /** */ -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 |}; /** */ -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** @@ -332,6 +310,22 @@ declare export var ScriptHashNamespace: {| +PlutusScriptV3: 3, // 3 |}; +/** + */ + +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 +|}; + +/** + */ + +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 +|}; + /** */ @@ -354,35 +348,71 @@ declare export var DRepKind: {| /** */ -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 |}; /** - * JSON <-> PlutusData conversion schemas. - * Follows ScriptDataJsonSchema in cardano-cli defined at: - * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 - * - * All methods here have the following restrictions due to limitations on dependencies: - * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors - * * Hex strings for bytes don't accept odd-length (half-byte) strings. - * cardano-cli seems to support these however but it seems to be different than just 0-padding - * on either side when tested so proceed with caution */ -declare export var PlutusDatumSchema: {| - +BasicConversions: 0, // 0 - +DetailedSchema: 1, // 1 +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 |}; /** + * Used to choosed the schema for a script JSON string */ -declare export var LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 +|}; + +/** + */ + +declare export var GovernanceActionKind: {| + +ParameterChangeAction: 0, // 0 + +HardForkInitiationAction: 1, // 1 + +TreasuryWithdrawalsAction: 2, // 2 + +NoConfidenceAction: 3, // 3 + +UpdateCommitteeAction: 4, // 4 + +NewConstitutionAction: 5, // 5 + +InfoAction: 6, // 6 +|}; + +/** + */ + +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 +|}; + +/** + */ + +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 +|}; + +/** + */ + +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 |}; /** @@ -411,21 +441,29 @@ declare export var CertificateKind: {| /** */ -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 |}; /** + * JSON <-> PlutusData conversion schemas. + * Follows ScriptDataJsonSchema in cardano-cli defined at: + * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 + * + * All methods here have the following restrictions due to limitations on dependencies: + * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors + * * Hex strings for bytes don't accept odd-length (half-byte) strings. + * cardano-cli seems to support these however but it seems to be different than just 0-padding + * on either side when tested so proceed with caution */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 +declare export var PlutusDatumSchema: {| + +BasicConversions: 0, // 0 + +DetailedSchema: 1, // 1 |}; /** @@ -442,48 +480,10 @@ declare export var TransactionMetadatumKind: {| /** */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 -|}; - -/** - */ - -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 -|}; - -/** - */ - -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 -|}; - -/** - */ - -declare export var RedeemerTagKind: {| - +Spend: 0, // 0 - +Mint: 1, // 1 - +Cert: 2, // 2 - +Reward: 3, // 3 - +Vote: 4, // 4 - +VotingProposal: 5, // 5 -|}; - -/** - * Used to choosed the schema for a script JSON string - */ - -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 |}; /** @@ -8508,18 +8508,6 @@ declare export class Redeemers { */ static new(): Redeemers; - /** - * @param {(Redeemer)[]} redeemers - * @param {$Values< - typeof - CborContainerType>} serialization_format - * @returns {Redeemers} - */ - static new_with_serialization_format( - redeemers: Redeemer[], - serialization_format: $Values - ): Redeemers; - /** * @returns {number} */ From 11440b6cf6ec3efaa8a351218979d687ffc3a8db Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 11 Apr 2024 16:13:09 +0300 Subject: [PATCH 260/349] fix pointer address decoder --- rust/src/protocol_types/address.rs | 111 ++++++++++++++++------------- 1 file changed, 62 insertions(+), 49 deletions(-) diff --git a/rust/src/protocol_types/address.rs b/rust/src/protocol_types/address.rs index 98d82cde..3b41d8c7 100644 --- a/rust/src/protocol_types/address.rs +++ b/rust/src/protocol_types/address.rs @@ -1,5 +1,5 @@ -use crate::*; use crate::legacy_address::ExtendedAddr; +use crate::*; use bech32::ToBase32; use ed25519_bip32::XPub; @@ -414,43 +414,25 @@ impl Address { const PTR_ADDR_MIN_SIZE: usize = 1 + HASH_LEN + 1 + 1 + 1; if data.len() < PTR_ADDR_MIN_SIZE { // possibly more, but depends on how many bytes the natural numbers are for the pointer - Err( - cbor_event::Error::NotEnough(data.len(), PTR_ADDR_MIN_SIZE).into() - ) + Err(cbor_event::Error::NotEnough(data.len(), PTR_ADDR_MIN_SIZE).into()) } else { let mut byte_index = 1; let payment_cred = read_addr_cred(4, 1); byte_index += HASH_LEN; - let (slot, slot_bytes) = - variable_nat_decode(&data[byte_index..]).ok_or(DeserializeError::new( - "Address.Pointer.slot", - DeserializeFailure::VariableLenNatDecodeFailed, - ))?; - byte_index += slot_bytes; - let (tx_index, tx_bytes) = - variable_nat_decode(&data[byte_index..]).ok_or(DeserializeError::new( - "Address.Pointer.tx_index", - DeserializeFailure::VariableLenNatDecodeFailed, - ))?; - byte_index += tx_bytes; - let (cert_index, cert_bytes) = - variable_nat_decode(&data[byte_index..]).ok_or(DeserializeError::new( - "Address.Pointer.cert_index", - DeserializeFailure::VariableLenNatDecodeFailed, - ))?; - byte_index += cert_bytes; - if byte_index < data.len() { - Err(cbor_event::Error::TrailingData.into()) - } else { - Ok(AddrType::Ptr(PointerAddress::new( - network, - &payment_cred, - &Pointer::new_pointer( - &to_bignum(slot), - &to_bignum(tx_index), - &to_bignum(cert_index), - ), - ))) + match Self::decode_pointer(&data[byte_index..]) { + Ok((pointer, offset)) => { + byte_index += offset; + if byte_index < data.len() { + Err(cbor_event::Error::TrailingData.into()) + } else { + Ok(AddrType::Ptr(PointerAddress::new( + network, + &payment_cred, + &pointer, + ))) + } + } + Err(err) => Err(err) } } } @@ -458,14 +440,15 @@ impl Address { 0b0110 | 0b0111 => { const ENTERPRISE_ADDR_SIZE: usize = 1 + HASH_LEN; if data.len() < ENTERPRISE_ADDR_SIZE { - Err( - cbor_event::Error::NotEnough(data.len(), ENTERPRISE_ADDR_SIZE).into(), - ) + Err(cbor_event::Error::NotEnough(data.len(), ENTERPRISE_ADDR_SIZE).into()) } else { if data.len() > ENTERPRISE_ADDR_SIZE { Err(cbor_event::Error::TrailingData.into()) } else { - Ok(AddrType::Enterprise(EnterpriseAddress::new(network, &read_addr_cred(4, 1)))) + Ok(AddrType::Enterprise(EnterpriseAddress::new( + network, + &read_addr_cred(4, 1), + ))) } } } @@ -473,14 +456,15 @@ impl Address { 0b1110 | 0b1111 => { const REWARD_ADDR_SIZE: usize = 1 + HASH_LEN; if data.len() < REWARD_ADDR_SIZE { - Err( - cbor_event::Error::NotEnough(data.len(), REWARD_ADDR_SIZE).into() - ) + Err(cbor_event::Error::NotEnough(data.len(), REWARD_ADDR_SIZE).into()) } else { if data.len() > REWARD_ADDR_SIZE { Err(cbor_event::Error::TrailingData.into()) } else { - Ok(AddrType::Reward(RewardAddress::new(network, &read_addr_cred(4, 1)))) + Ok(AddrType::Reward(RewardAddress::new( + network, + &read_addr_cred(4, 1), + ))) } } } @@ -490,24 +474,53 @@ impl Address { // Therefore you can re-use Byron addresses as-is match ByronAddress::from_bytes(data.to_vec()) { Ok(addr) => Ok(AddrType::Byron(addr)), - Err(e) => { - Err(cbor_event::Error::CustomError( - e.as_string().unwrap_or_default(), - ) - .into()) - } + Err(e) => Err(cbor_event::Error::CustomError( + e.as_string().unwrap_or_default(), + ) + .into()), } } _ => Err(DeserializeFailure::BadAddressType(header).into()), }; match addr { Ok(addr) => Ok(Address(addr)), - Err(_) => Ok(Address(AddrType::Malformed(MalformedAddress(data.to_vec())))), + Err(_) => Ok(Address(AddrType::Malformed(MalformedAddress( + data.to_vec(), + )))), } })() .map_err(|e| e.annotate("Address")) } + fn decode_pointer(data: &[u8]) -> Result<(Pointer, usize), DeserializeError> { + let mut offset = 0; + let (slot, slot_bytes) = variable_nat_decode(&data).ok_or(DeserializeError::new( + "Address.Pointer.slot", + DeserializeFailure::VariableLenNatDecodeFailed, + ))?; + offset += slot_bytes; + let (tx_index, tx_bytes) = + variable_nat_decode(&data[offset..]).ok_or(DeserializeError::new( + "Address.Pointer.tx_index", + DeserializeFailure::VariableLenNatDecodeFailed, + ))?; + offset += tx_bytes; + let (cert_index, cert_bytes) = + variable_nat_decode(&data[offset..]).ok_or(DeserializeError::new( + "Address.Pointer.cert_index", + DeserializeFailure::VariableLenNatDecodeFailed, + ))?; + offset += cert_bytes; + Ok(( + Pointer::new_pointer( + &to_bignum(slot), + &to_bignum(tx_index), + &to_bignum(cert_index), + ), + offset, + )) + } + pub fn to_bech32(&self, prefix: Option) -> Result { let final_prefix = match prefix { Some(prefix) => prefix, From b88dce337a2e7a3e0e9564a2b7de1c17480fb375 Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 11 Apr 2024 16:14:56 +0300 Subject: [PATCH 261/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- rust/pkg/cardano_serialization_lib.js.flow | 206 ++++++++++----------- 5 files changed, 107 insertions(+), 107 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6791105e..450dc818 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.27", + "version": "12.0.0-alpha.28", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 485dffb0..f7c0ff59 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.27", + "version": "12.0.0-alpha.28", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 3a9fdf5c..72588968 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.27" +version = "12.0.0-alpha.28" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 15da2a6f..1157b6f9 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -55,7 +55,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.27" +version = "12.0.0-alpha.28" dependencies = [ "bech32", "cbor_event", diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 93ed1bc3..0e1d6efa 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -260,54 +260,51 @@ declare export function create_send_all( /** */ -declare export var RedeemerTagKind: {| - +Spend: 0, // 0 - +Mint: 1, // 1 - +Cert: 2, // 2 - +Reward: 3, // 3 - +Vote: 4, // 4 - +VotingProposal: 5, // 5 +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 |}; /** */ -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 |}; /** */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var RelayKind: {| + +SingleHostAddr: 0, // 0 + +SingleHostName: 1, // 1 + +MultiHostName: 2, // 2 |}; /** */ -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 +declare export var GovernanceActionKind: {| + +ParameterChangeAction: 0, // 0 + +HardForkInitiationAction: 1, // 1 + +TreasuryWithdrawalsAction: 2, // 2 + +NoConfidenceAction: 3, // 3 + +UpdateCommitteeAction: 4, // 4 + +NewConstitutionAction: 5, // 5 + +InfoAction: 6, // 6 |}; /** - * Each new language uses a different namespace for hashing its script - * This is because you could have a language where the same bytes have different semantics - * So this avoids scripts in different languages mapping to the same hash - * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var ScriptHashNamespace: {| - +NativeScript: 0, // 0 - +PlutusScript: 1, // 1 - +PlutusScriptV2: 2, // 2 - +PlutusScriptV3: 3, // 3 +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 |}; /** @@ -319,100 +316,112 @@ declare export var CborContainerType: {| |}; /** + * Used to choosed the schema for a script JSON string */ -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** */ -declare export var RelayKind: {| - +SingleHostAddr: 0, // 0 - +SingleHostName: 1, // 1 - +MultiHostName: 2, // 2 +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 |}; /** */ -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 |}; /** */ -declare export var LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 |}; /** - * Used to choosed the schema for a script JSON string */ -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 |}; /** */ -declare export var GovernanceActionKind: {| - +ParameterChangeAction: 0, // 0 - +HardForkInitiationAction: 1, // 1 - +TreasuryWithdrawalsAction: 2, // 2 - +NoConfidenceAction: 3, // 3 - +UpdateCommitteeAction: 4, // 4 - +NewConstitutionAction: 5, // 5 - +InfoAction: 6, // 6 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 |}; /** + * JSON <-> PlutusData conversion schemas. + * Follows ScriptDataJsonSchema in cardano-cli defined at: + * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 + * + * All methods here have the following restrictions due to limitations on dependencies: + * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors + * * Hex strings for bytes don't accept odd-length (half-byte) strings. + * cardano-cli seems to support these however but it seems to be different than just 0-padding + * on either side when tested so proceed with caution */ -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 +declare export var PlutusDatumSchema: {| + +BasicConversions: 0, // 0 + +DetailedSchema: 1, // 1 |}; /** + * Each new language uses a different namespace for hashing its script + * This is because you could have a language where the same bytes have different semantics + * So this avoids scripts in different languages mapping to the same hash + * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 +declare export var ScriptHashNamespace: {| + +NativeScript: 0, // 0 + +PlutusScript: 1, // 1 + +PlutusScriptV2: 2, // 2 + +PlutusScriptV3: 3, // 3 |}; /** */ -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 +declare export var RedeemerTagKind: {| + +Spend: 0, // 0 + +Mint: 1, // 1 + +Cert: 2, // 2 + +Reward: 3, // 3 + +Vote: 4, // 4 + +VotingProposal: 5, // 5 |}; /** @@ -441,49 +450,40 @@ declare export var CertificateKind: {| /** */ -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 - +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 |}; /** - * JSON <-> PlutusData conversion schemas. - * Follows ScriptDataJsonSchema in cardano-cli defined at: - * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 - * - * All methods here have the following restrictions due to limitations on dependencies: - * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors - * * Hex strings for bytes don't accept odd-length (half-byte) strings. - * cardano-cli seems to support these however but it seems to be different than just 0-padding - * on either side when tested so proceed with caution */ -declare export var PlutusDatumSchema: {| - +BasicConversions: 0, // 0 - +DetailedSchema: 1, // 1 +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** */ -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 |}; /** */ -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 |}; /** From a58bd59992bb65765acd5ffc185bb9cb143a1389 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 12 Apr 2024 06:09:35 +0300 Subject: [PATCH 262/349] add ref_script_coins_per_byte parameter --- .../builders/batch_tools/cbor_calculator.rs | 1 + .../batch_tools/witnesses_calculator.rs | 1 + rust/src/builders/certificates_builder.rs | 40 +- rust/src/builders/fakes.rs | 37 + rust/src/builders/mint_builder.rs | 39 +- rust/src/builders/mod.rs | 2 + rust/src/builders/script_structs.rs | 275 ----- .../builders/script_structs/datum_source.rs | 22 + rust/src/builders/script_structs/mod.rs | 20 + .../script_structs/native_script_source.rs | 65 ++ .../script_structs/plutus_script_ref.rs | 25 + .../script_structs/plutus_script_source.rs | 76 ++ .../builders/script_structs/plutus_witness.rs | 82 ++ .../script_structs/plutus_witnesses.rs | 64 ++ .../script_structs/script_witness_type.rs | 66 ++ rust/src/builders/tx_builder.rs | 155 ++- rust/src/builders/tx_inputs_builder.rs | 120 +-- rust/src/builders/voting_builder.rs | 36 +- rust/src/builders/voting_proposal_builder.rs | 30 +- rust/src/builders/withdrawals_builder.rs | 38 +- rust/src/fakes.rs | 6 +- rust/src/fees.rs | 132 ++- rust/src/lib.rs | 15 +- rust/src/protocol_types/address.rs | 12 +- rust/src/protocol_types/metadata.rs | 6 +- rust/src/protocol_types/mod.rs | 3 + rust/src/protocol_types/numeric/big_int.rs | 140 +++ rust/src/protocol_types/numeric/big_num.rs | 202 ++++ rust/src/protocol_types/numeric/int.rs | 137 +++ rust/src/protocol_types/numeric/mod.rs | 8 + rust/src/protocol_types/plutus/plutus_data.rs | 4 +- .../protocol_types/protocol_param_update.rs | 12 +- rust/src/protocol_types/transaction_body.rs | 2 +- rust/src/protocol_types/tx_inputs.rs | 7 + rust/src/rational.rs | 99 ++ rust/src/serialization/mod.rs | 3 +- rust/src/serialization/numeric/big_int.rs | 103 ++ rust/src/serialization/numeric/big_num.rs | 19 + rust/src/serialization/numeric/int.rs | 28 + rust/src/serialization/numeric/mod.rs | 3 + rust/src/serialization/plutus/plutus_data.rs | 4 +- .../serialization/protocol_param_update.rs | 4 +- rust/src/serialization/utils.rs | 20 + rust/src/tests/address.rs | 22 +- rust/src/tests/builders/batch_tools.rs | 144 +-- rust/src/tests/builders/mod.rs | 2 +- rust/src/tests/builders/tx_builder.rs | 947 ++++++++++-------- rust/src/tests/builders/voting_builder.rs | 14 +- .../tests/builders/voting_proposal_builder.rs | 89 +- rust/src/tests/general.rs | 24 +- rust/src/tests/metadata.rs | 4 +- rust/src/tests/mock_objects.rs | 54 +- rust/src/tests/plutus.rs | 22 +- rust/src/tests/serialization/general.rs | 48 +- .../serialization/protocol_param_update.rs | 15 +- .../tests/serialization/transaction_body.rs | 8 +- rust/src/utils.rs | 677 +------------ 57 files changed, 2424 insertions(+), 1809 deletions(-) create mode 100644 rust/src/builders/fakes.rs delete mode 100644 rust/src/builders/script_structs.rs create mode 100644 rust/src/builders/script_structs/datum_source.rs create mode 100644 rust/src/builders/script_structs/mod.rs create mode 100644 rust/src/builders/script_structs/native_script_source.rs create mode 100644 rust/src/builders/script_structs/plutus_script_ref.rs create mode 100644 rust/src/builders/script_structs/plutus_script_source.rs create mode 100644 rust/src/builders/script_structs/plutus_witness.rs create mode 100644 rust/src/builders/script_structs/plutus_witnesses.rs create mode 100644 rust/src/builders/script_structs/script_witness_type.rs create mode 100644 rust/src/protocol_types/numeric/big_int.rs create mode 100644 rust/src/protocol_types/numeric/big_num.rs create mode 100644 rust/src/protocol_types/numeric/int.rs create mode 100644 rust/src/protocol_types/numeric/mod.rs create mode 100644 rust/src/rational.rs create mode 100644 rust/src/serialization/numeric/big_int.rs create mode 100644 rust/src/serialization/numeric/big_num.rs create mode 100644 rust/src/serialization/numeric/int.rs create mode 100644 rust/src/serialization/numeric/mod.rs diff --git a/rust/src/builders/batch_tools/cbor_calculator.rs b/rust/src/builders/batch_tools/cbor_calculator.rs index baffa203..fec45147 100644 --- a/rust/src/builders/batch_tools/cbor_calculator.rs +++ b/rust/src/builders/batch_tools/cbor_calculator.rs @@ -3,6 +3,7 @@ use crate::serialization::map_names::{TxBodyNames, WitnessSetNames}; use crate::*; use num_traits::ToPrimitive; use std::collections::HashSet; +use crate::builders::fakes::fake_private_key; pub(super) struct CborCalculator(); diff --git a/rust/src/builders/batch_tools/witnesses_calculator.rs b/rust/src/builders/batch_tools/witnesses_calculator.rs index 8bdc51dd..23b65a43 100644 --- a/rust/src/builders/batch_tools/witnesses_calculator.rs +++ b/rust/src/builders/batch_tools/witnesses_calculator.rs @@ -2,6 +2,7 @@ use crate::builders::batch_tools::cbor_calculator::CborCalculator; use crate::serialization::map_names::WitnessSetNames; use crate::*; use std::collections::HashSet; +use crate::builders::fakes::{fake_private_key, fake_raw_key_public, fake_raw_key_sig}; #[derive(Clone)] pub(super) struct WitnessesCalculator { diff --git a/rust/src/builders/certificates_builder.rs b/rust/src/builders/certificates_builder.rs index f1f4029e..eb30c768 100644 --- a/rust/src/builders/certificates_builder.rs +++ b/rust/src/builders/certificates_builder.rs @@ -69,8 +69,10 @@ impl CertificatesBuilder { for (cert, script_wit) in &self.certs { let cert_req_signers = witness_keys_for_cert(&cert); set.extend_move(cert_req_signers); - if let Some(ScriptWitnessType::NativeScriptWitness(script_source)) = script_wit { - set.extend(&script_source.required_signers()); + if let Some(script_wit) = script_wit { + if let Some(signers) = script_wit.get_required_signers() { + set.extend(&signers); + } } } set @@ -92,17 +94,12 @@ impl CertificatesBuilder { let mut inputs = Vec::new(); for (_, script_wit) in self.certs.iter() { match script_wit { - Some(ScriptWitnessType::NativeScriptWitness(script_source)) => { - if let NativeScriptSourceEnum::RefInput(input, _, _) = script_source { - inputs.push(input.clone()); - } - } - Some(ScriptWitnessType::PlutusScriptWitness(plutus_witness)) => { - if let Some(DatumSourceEnum::RefInput(input)) = &plutus_witness.datum { - inputs.push(input.clone()); + Some(script_witness) => { + if let Some(input) = script_witness.get_script_ref_input() { + inputs.push(input); } - if let PlutusScriptSourceEnum::RefInput(input, _, _) = &plutus_witness.script { - inputs.push(input.clone()); + if let Some(input) = script_witness.get_datum_ref_input() { + inputs.push(input); } } None => {} @@ -115,7 +112,7 @@ impl CertificatesBuilder { let mut scripts = NativeScripts::new(); for (_, script_wit) in self.certs.iter() { if let Some(ScriptWitnessType::NativeScriptWitness( - NativeScriptSourceEnum::NativeScript(script), + NativeScriptSourceEnum::NativeScript(script, _), )) = script_wit { scripts.add(script); @@ -128,9 +125,7 @@ impl CertificatesBuilder { let mut used_langs = BTreeSet::new(); for (_, script_wit) in &self.certs { if let Some(ScriptWitnessType::PlutusScriptWitness(s)) = script_wit { - if let Some(lang) = s.script.language() { - used_langs.insert(lang.clone()); - } + used_langs.insert(s.script.language().clone()); } } used_langs @@ -209,6 +204,19 @@ impl CertificatesBuilder { let certs = self.certs.iter().map(|(c, _)| c.clone()).collect(); Certificates(certs) } + + //return only ref inputs that are script refs with added size + //used for calculating the fee for the transaction + //another ref input and also script ref input without size are filtered out + pub(crate) fn get_script_ref_inputs_with_size( + &self, + ) -> impl Iterator { + self.certs.iter() + .filter_map(|(_, opt_wit)| opt_wit.as_ref()) + .filter_map(|script_wit| { + script_wit.get_script_ref_input_with_size() + }) + } } // comes from witsVKeyNeeded in the Ledger spec diff --git a/rust/src/builders/fakes.rs b/rust/src/builders/fakes.rs new file mode 100644 index 00000000..a35f3ddd --- /dev/null +++ b/rust/src/builders/fakes.rs @@ -0,0 +1,37 @@ +use crate::{Bip32PrivateKey, Ed25519Signature, PublicKey}; + +pub(crate) fn fake_private_key() -> Bip32PrivateKey { + Bip32PrivateKey::from_bytes(&[ + 0xb8, 0xf2, 0xbe, 0xce, 0x9b, 0xdf, 0xe2, 0xb0, 0x28, 0x2f, 0x5b, 0xad, 0x70, 0x55, 0x62, + 0xac, 0x99, 0x6e, 0xfb, 0x6a, 0xf9, 0x6b, 0x64, 0x8f, 0x44, 0x45, 0xec, 0x44, 0xf4, 0x7a, + 0xd9, 0x5c, 0x10, 0xe3, 0xd7, 0x2f, 0x26, 0xed, 0x07, 0x54, 0x22, 0xa3, 0x6e, 0xd8, 0x58, + 0x5c, 0x74, 0x5a, 0x0e, 0x11, 0x50, 0xbc, 0xce, 0xba, 0x23, 0x57, 0xd0, 0x58, 0x63, 0x69, + 0x91, 0xf3, 0x8a, 0x37, 0x91, 0xe2, 0x48, 0xde, 0x50, 0x9c, 0x07, 0x0d, 0x81, 0x2a, 0xb2, + 0xfd, 0xa5, 0x78, 0x60, 0xac, 0x87, 0x6b, 0xc4, 0x89, 0x19, 0x2c, 0x1e, 0xf4, 0xce, 0x25, + 0x3c, 0x19, 0x7e, 0xe2, 0x19, 0xa4, + ]) + .unwrap() +} + +pub(crate) fn fake_raw_key_sig() -> Ed25519Signature { + Ed25519Signature::from_bytes(vec![ + 36, 248, 153, 211, 155, 23, 253, 93, 102, 193, 146, 196, 181, 13, 52, 62, 66, 247, 35, 91, + 48, 80, 76, 138, 231, 97, 159, 147, 200, 40, 220, 109, 206, 69, 104, 221, 105, 23, 124, 85, + 24, 40, 73, 45, 119, 122, 103, 39, 253, 102, 194, 251, 204, 189, 168, 194, 174, 237, 146, + 3, 44, 153, 121, 10, + ]) + .unwrap() +} + +pub(crate) fn fake_raw_key_public(x: u64) -> PublicKey { + let mut bytes = [0u8; 64]; + for i in 0..8 { + bytes[i] = ((x >> (i * 8)) & 0xff) as u8; + } + PublicKey::from_bytes(&[ + 207, 118, 57, 154, 33, 13, 232, 114, 14, 159, 168, 148, 228, 94, 65, 226, 154, 181, 37, + 227, 11, 196, 2, 128, bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], + bytes[7] + ]) + .unwrap() +} \ No newline at end of file diff --git a/rust/src/builders/mint_builder.rs b/rust/src/builders/mint_builder.rs index 093ac804..e4bf987e 100644 --- a/rust/src/builders/mint_builder.rs +++ b/rust/src/builders/mint_builder.rs @@ -60,7 +60,12 @@ impl MintBuilder { } } - pub fn add_asset(&mut self, mint: &MintWitness, asset_name: &AssetName, amount: &Int) -> Result<(), JsError> { + pub fn add_asset( + &mut self, + mint: &MintWitness, + asset_name: &AssetName, + amount: &Int, + ) -> Result<(), JsError> { if amount.0 == 0 { return Err(JsError::from_str("Mint cannot be zero.")); } @@ -68,7 +73,12 @@ impl MintBuilder { Ok(()) } - pub fn set_asset(&mut self, mint: &MintWitness, asset_name: &AssetName, amount: &Int) -> Result<(), JsError> { + pub fn set_asset( + &mut self, + mint: &MintWitness, + asset_name: &AssetName, + amount: &Int, + ) -> Result<(), JsError> { if amount.0 == 0 { return Err(JsError::from_str("Mint cannot be zero.")); } @@ -201,9 +211,8 @@ impl MintBuilder { for script_mint in self.mints.values() { match script_mint { ScriptMint::Plutus(plutus_mints) => { - if let PlutusScriptSourceEnum::RefInput(ref_input, _, _) = &plutus_mints.script - { - reference_inputs.push(ref_input.clone()); + if let PlutusScriptSourceEnum::RefInput(ref_script, _) = &plutus_mints.script { + reference_inputs.push(ref_script.input_ref.clone()); } } _ => {} @@ -261,13 +270,27 @@ impl MintBuilder { for (_, script_mint) in &self.mints { match script_mint { ScriptMint::Plutus(plutus_mints) => { - if let Some(lang) = plutus_mints.script.language() { - used_langs.insert(lang); - } + used_langs.insert(plutus_mints.script.language()); } _ => {} } } used_langs } + + //return only ref inputs that are script refs with added size + //used for calculating the fee for the transaction + //another ref input and also script ref input without size are filtered out + pub(crate) fn get_script_ref_inputs_with_size( + &self, + ) -> impl Iterator { + self.mints.iter().filter_map(|(_, script_mint)| { + if let ScriptMint::Plutus(plutus_mints) = script_mint { + if let PlutusScriptSourceEnum::RefInput(script_ref, _) = &plutus_mints.script { + return Some((&script_ref.input_ref, script_ref.script_size)); + } + } + None + }) + } } diff --git a/rust/src/builders/mod.rs b/rust/src/builders/mod.rs index 7b2810dc..dc1d7ffe 100644 --- a/rust/src/builders/mod.rs +++ b/rust/src/builders/mod.rs @@ -32,3 +32,5 @@ pub use tx_builder::*; mod tx_builder_constants; pub use tx_builder_constants::*; + +pub(crate) mod fakes; diff --git a/rust/src/builders/script_structs.rs b/rust/src/builders/script_structs.rs deleted file mode 100644 index 98b56c79..00000000 --- a/rust/src/builders/script_structs.rs +++ /dev/null @@ -1,275 +0,0 @@ -use crate::*; - -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub enum PlutusScriptSourceEnum { - Script(PlutusScript), - RefInput(TransactionInput, ScriptHash, Option), -} - -impl PlutusScriptSourceEnum { - pub fn script_hash(&self) -> ScriptHash { - match self { - PlutusScriptSourceEnum::Script(script) => script.hash(), - PlutusScriptSourceEnum::RefInput(_, script_hash, _) => script_hash.clone(), - } - } - - pub fn language(&self) -> Option { - match self { - PlutusScriptSourceEnum::Script(script) => Some(script.language_version()), - PlutusScriptSourceEnum::RefInput(_, _, language) => language.clone(), - } - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub struct PlutusScriptSource(pub(crate) PlutusScriptSourceEnum); - -#[wasm_bindgen] -impl PlutusScriptSource { - pub fn new(script: &PlutusScript) -> Self { - Self(PlutusScriptSourceEnum::Script(script.clone())) - } - pub fn new_ref_input( - script_hash: &ScriptHash, - input: &TransactionInput, - lang_ver: &Language, - ) -> Self { - Self(PlutusScriptSourceEnum::RefInput( - input.clone(), - script_hash.clone(), - Some(lang_ver.clone()), - )) - } -} - -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub enum DatumSourceEnum { - Datum(PlutusData), - RefInput(TransactionInput), -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub struct DatumSource(DatumSourceEnum); - -#[wasm_bindgen] -impl DatumSource { - pub fn new(datum: &PlutusData) -> Self { - Self(DatumSourceEnum::Datum(datum.clone())) - } - - pub fn new_ref_input(input: &TransactionInput) -> Self { - Self(DatumSourceEnum::RefInput(input.clone())) - } -} - -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub(crate) enum NativeScriptSourceEnum { - NativeScript(NativeScript), - RefInput(TransactionInput, ScriptHash, RequiredSigners), -} - -impl NativeScriptSourceEnum { - pub fn script_hash(&self) -> ScriptHash { - match self { - NativeScriptSourceEnum::NativeScript(script) => script.hash(), - NativeScriptSourceEnum::RefInput(_, script_hash, _) => script_hash.clone(), - } - } - - pub fn required_signers(&self) -> Ed25519KeyHashes { - match self { - NativeScriptSourceEnum::NativeScript(script) => Ed25519KeyHashes::from(script), - NativeScriptSourceEnum::RefInput(_, _, required_signers) => required_signers.clone(), - } - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub struct NativeScriptSource(pub(crate) NativeScriptSourceEnum); - -#[wasm_bindgen] -impl NativeScriptSource { - pub fn new(script: &NativeScript) -> Self { - Self(NativeScriptSourceEnum::NativeScript(script.clone())) - } - - pub fn new_ref_input( - script_hash: &ScriptHash, - input: &TransactionInput, - required_signers: &RequiredSigners, - ) -> Self { - Self(NativeScriptSourceEnum::RefInput( - input.clone(), - script_hash.clone(), - required_signers.clone(), - )) - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub struct PlutusWitness { - pub(crate) script: PlutusScriptSourceEnum, - pub(crate) datum: Option, - pub(crate) redeemer: Redeemer, -} - -#[wasm_bindgen] -impl PlutusWitness { - pub fn new(script: &PlutusScript, datum: &PlutusData, redeemer: &Redeemer) -> Self { - Self { - script: PlutusScriptSourceEnum::Script(script.clone()), - datum: Some(DatumSourceEnum::Datum(datum.clone())), - redeemer: redeemer.clone(), - } - } - - pub fn new_with_ref( - script: &PlutusScriptSource, - datum: &DatumSource, - redeemer: &Redeemer, - ) -> Self { - Self { - script: script.0.clone(), - datum: Some(datum.0.clone()), - redeemer: redeemer.clone(), - } - } - - pub fn new_without_datum(script: &PlutusScript, redeemer: &Redeemer) -> Self { - Self { - script: PlutusScriptSourceEnum::Script(script.clone()), - datum: None, - redeemer: redeemer.clone(), - } - } - - pub fn new_with_ref_without_datum(script: &PlutusScriptSource, redeemer: &Redeemer) -> Self { - Self { - script: script.0.clone(), - datum: None, - redeemer: redeemer.clone(), - } - } - - pub fn script(&self) -> Option { - match &self.script { - PlutusScriptSourceEnum::Script(script) => Some(script.clone()), - _ => None, - } - } - - pub fn datum(&self) -> Option { - match &self.datum { - Some(DatumSourceEnum::Datum(datum)) => Some(datum.clone()), - _ => None, - } - } - - pub fn redeemer(&self) -> Redeemer { - self.redeemer.clone() - } - - #[allow(dead_code)] - pub(crate) fn clone_with_redeemer_index(&self, index: &BigNum) -> Self { - Self { - script: self.script.clone(), - datum: self.datum.clone(), - redeemer: self.redeemer.clone_with_index(index), - } - } - - pub(crate) fn clone_with_redeemer_index_and_tag( - &self, - index: &BigNum, - tag: &RedeemerTag, - ) -> Self { - Self { - script: self.script.clone(), - datum: self.datum.clone(), - redeemer: self.redeemer.clone_with_index_and_tag(index, tag), - } - } -} - -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub struct PlutusWitnesses(pub(crate) Vec); - -#[wasm_bindgen] -impl PlutusWitnesses { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> PlutusWitness { - self.0[index].clone() - } - - pub fn add(&mut self, elem: &PlutusWitness) { - self.0.push(elem.clone()); - } - - pub(crate) fn collect(&self) -> (PlutusScripts, Option, Redeemers) { - let mut used_scripts = BTreeSet::new(); - let mut used_datums = BTreeSet::new(); - let mut used_redeemers = BTreeSet::new(); - let mut s = PlutusScripts::new(); - let mut d: Option = None; - let mut r = Redeemers::new(); - self.0.iter().for_each(|w| { - if let PlutusScriptSourceEnum::Script(script) = &w.script { - if used_scripts.insert(script.clone()) { - s.add(script); - } - } - if let Some(DatumSourceEnum::Datum(datum)) = &w.datum { - if used_datums.insert(datum) { - match d { - Some(ref mut d) => d.add(datum), - None => { - d = { - let mut initial_list = PlutusList::new(); - initial_list.add(datum); - Some(initial_list) - } - } - } - } - } - if used_redeemers.insert(w.redeemer.clone()) { - r.add(&w.redeemer); - } - }); - (s, d, r) - } -} - -impl From> for PlutusWitnesses { - fn from(scripts: Vec) -> Self { - Self(scripts) - } -} - -#[derive(Clone, Debug)] -pub(crate) enum ScriptWitnessType { - NativeScriptWitness(NativeScriptSourceEnum), - PlutusScriptWitness(PlutusWitness), -} - -impl ScriptWitnessType { - pub fn script_hash(&self) -> ScriptHash { - match self { - ScriptWitnessType::NativeScriptWitness(script) => script.script_hash(), - ScriptWitnessType::PlutusScriptWitness(script) => script.script.script_hash(), - } - } -} diff --git a/rust/src/builders/script_structs/datum_source.rs b/rust/src/builders/script_structs/datum_source.rs new file mode 100644 index 00000000..d0f22573 --- /dev/null +++ b/rust/src/builders/script_structs/datum_source.rs @@ -0,0 +1,22 @@ +use crate::*; + +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub enum DatumSourceEnum { + Datum(PlutusData), + RefInput(TransactionInput), +} + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub struct DatumSource(pub(crate) DatumSourceEnum); + +#[wasm_bindgen] +impl DatumSource { + pub fn new(datum: &PlutusData) -> Self { + Self(DatumSourceEnum::Datum(datum.clone())) + } + + pub fn new_ref_input(input: &TransactionInput) -> Self { + Self(DatumSourceEnum::RefInput(input.clone())) + } +} \ No newline at end of file diff --git a/rust/src/builders/script_structs/mod.rs b/rust/src/builders/script_structs/mod.rs new file mode 100644 index 00000000..c468bec0 --- /dev/null +++ b/rust/src/builders/script_structs/mod.rs @@ -0,0 +1,20 @@ +mod plutus_script_source; +pub use plutus_script_source::*; + +mod native_script_source; +pub use native_script_source::*; + +mod datum_source; +pub use datum_source::*; + +mod plutus_witness; +pub use plutus_witness::*; + +mod plutus_witnesses; +pub use plutus_witnesses::*; + +mod plutus_script_ref; +pub(crate) use plutus_script_ref::*; + +mod script_witness_type; +pub(crate) use script_witness_type::*; diff --git a/rust/src/builders/script_structs/native_script_source.rs b/rust/src/builders/script_structs/native_script_source.rs new file mode 100644 index 00000000..081bb7b3 --- /dev/null +++ b/rust/src/builders/script_structs/native_script_source.rs @@ -0,0 +1,65 @@ +use crate::*; + +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub(crate) enum NativeScriptSourceEnum { + NativeScript(NativeScript, Option), + RefInput(TransactionInput, ScriptHash, Option), +} + +impl NativeScriptSourceEnum { + pub fn script_hash(&self) -> ScriptHash { + match self { + NativeScriptSourceEnum::NativeScript(script, _) => script.hash(), + NativeScriptSourceEnum::RefInput(_, script_hash, _) => script_hash.clone(), + } + } + + pub fn required_signers(&self) -> Option { + match self { + NativeScriptSourceEnum::NativeScript(script, required_signers) => { + match required_signers { + Some(signers) => Some(signers.clone()), + None => Some(script.into()) + } + } + NativeScriptSourceEnum::RefInput(_, _, required_signers) => required_signers.clone(), + } + } + + pub fn set_required_signers(&mut self, key_hashes: &Ed25519KeyHashes) { + match self { + NativeScriptSourceEnum::NativeScript(_, required_signers) => { + *required_signers = Some(key_hashes.clone()); + } + NativeScriptSourceEnum::RefInput(_, _, required_signers) => { + *required_signers = Some(key_hashes.clone()); + } + } + } +} + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub struct NativeScriptSource(pub(crate) NativeScriptSourceEnum); + +#[wasm_bindgen] +impl NativeScriptSource { + pub fn new(script: &NativeScript) -> Self { + Self(NativeScriptSourceEnum::NativeScript(script.clone(), None)) + } + + pub fn new_ref_input( + script_hash: &ScriptHash, + input: &TransactionInput, + ) -> Self { + Self(NativeScriptSourceEnum::RefInput( + input.clone(), + script_hash.clone(), + None, + )) + } + + pub fn set_required_signers(&mut self, key_hashes: &Ed25519KeyHashes) { + self.0.set_required_signers(key_hashes) + } +} \ No newline at end of file diff --git a/rust/src/builders/script_structs/plutus_script_ref.rs b/rust/src/builders/script_structs/plutus_script_ref.rs new file mode 100644 index 00000000..65a8b373 --- /dev/null +++ b/rust/src/builders/script_structs/plutus_script_ref.rs @@ -0,0 +1,25 @@ +use crate::*; + +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub(crate) struct PlutusScriptRef { + pub(crate) input_ref: TransactionInput, + pub(crate) script_hash: ScriptHash, + pub(crate) language: Language, + pub(crate) script_size: usize, +} + +impl PlutusScriptRef { + pub(crate) fn new( + input_ref: TransactionInput, + script_hash: ScriptHash, + language: Language, + script_size: usize, + ) -> Self { + Self { + input_ref, + script_hash, + language, + script_size, + } + } +} diff --git a/rust/src/builders/script_structs/plutus_script_source.rs b/rust/src/builders/script_structs/plutus_script_source.rs new file mode 100644 index 00000000..e5cdfd49 --- /dev/null +++ b/rust/src/builders/script_structs/plutus_script_source.rs @@ -0,0 +1,76 @@ +use std::hash::Hash; +use crate::*; + +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub enum PlutusScriptSourceEnum { + Script(PlutusScript, Option), + RefInput(PlutusScriptRef, Option), +} + +impl PlutusScriptSourceEnum { + pub fn script_hash(&self) -> ScriptHash { + match self { + PlutusScriptSourceEnum::Script(script, ..) => script.hash(), + PlutusScriptSourceEnum::RefInput(script_ref, ..) => script_ref.script_hash.clone() + } + } + + pub fn language(&self) -> Language { + match self { + PlutusScriptSourceEnum::Script(script, ..) => script.language_version(), + PlutusScriptSourceEnum::RefInput(script_ref, ..) => script_ref.language.clone(), + } + } + + pub(crate) fn get_required_signers(&self) -> Option { + match self { + PlutusScriptSourceEnum::Script(_, signers) => signers.clone(), + PlutusScriptSourceEnum::RefInput(_, signers) => signers.clone(), + } + } +} + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub struct PlutusScriptSource(pub(crate) PlutusScriptSourceEnum); + +#[wasm_bindgen] +impl PlutusScriptSource { + pub fn new(script: &PlutusScript) -> Self { + Self(PlutusScriptSourceEnum::Script(script.clone(), None)) + } + pub fn new_ref_input( + script_hash: &ScriptHash, + input: &TransactionInput, + lang_ver: &Language, + script_size: usize, + ) -> Self { + Self(PlutusScriptSourceEnum::RefInput( + PlutusScriptRef::new( + input.clone(), + script_hash.clone(), + lang_ver.clone(), + script_size, + ), + None, + )) + } + + pub fn set_required_signers(&mut self, key_hashes: &Ed25519KeyHashes) { + match &mut self.0 { + PlutusScriptSourceEnum::Script(_, signers) => { + *signers = Some(key_hashes.clone()); + } + PlutusScriptSourceEnum::RefInput(_ , signers) => { + *signers = Some(key_hashes.clone()); + } + } + } + + pub fn get_ref_script_size(&self) -> Option { + match &self.0 { + PlutusScriptSourceEnum::Script(..) => None, + PlutusScriptSourceEnum::RefInput(script_ref, ..) => Some(script_ref.script_size) + } + } +} \ No newline at end of file diff --git a/rust/src/builders/script_structs/plutus_witness.rs b/rust/src/builders/script_structs/plutus_witness.rs new file mode 100644 index 00000000..28beb25a --- /dev/null +++ b/rust/src/builders/script_structs/plutus_witness.rs @@ -0,0 +1,82 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub struct PlutusWitness { + pub(crate) script: PlutusScriptSourceEnum, + pub(crate) datum: Option, + pub(crate) redeemer: Redeemer, +} + +#[wasm_bindgen] +impl PlutusWitness { + pub fn new(script: &PlutusScript, datum: &PlutusData, redeemer: &Redeemer) -> Self { + Self { + script: PlutusScriptSourceEnum::Script(script.clone(), None), + datum: Some(DatumSourceEnum::Datum(datum.clone())), + redeemer: redeemer.clone(), + } + } + + pub fn new_with_ref( + script: &PlutusScriptSource, + datum: &DatumSource, + redeemer: &Redeemer, + ) -> Self { + Self { + script: script.0.clone(), + datum: Some(datum.0.clone()), + redeemer: redeemer.clone(), + } + } + + pub fn new_without_datum(script: &PlutusScript, redeemer: &Redeemer) -> Self { + Self { + script: PlutusScriptSourceEnum::Script(script.clone(), None), + datum: None, + redeemer: redeemer.clone(), + } + } + + pub fn new_with_ref_without_datum(script: &PlutusScriptSource, redeemer: &Redeemer) -> Self { + Self { + script: script.0.clone(), + datum: None, + redeemer: redeemer.clone(), + } + } + + pub fn script(&self) -> Option { + match &self.script { + PlutusScriptSourceEnum::Script(script, _) => Some(script.clone()), + _ => None, + } + } + + pub fn datum(&self) -> Option { + match &self.datum { + Some(DatumSourceEnum::Datum(datum)) => Some(datum.clone()), + _ => None, + } + } + + pub fn redeemer(&self) -> Redeemer { + self.redeemer.clone() + } + + pub(crate) fn clone_with_redeemer_index_and_tag( + &self, + index: &BigNum, + tag: &RedeemerTag, + ) -> Self { + Self { + script: self.script.clone(), + datum: self.datum.clone(), + redeemer: self.redeemer.clone_with_index_and_tag(index, tag), + } + } + + pub(crate) fn get_required_signers(&self) -> Option { + self.script.get_required_signers() + } +} \ No newline at end of file diff --git a/rust/src/builders/script_structs/plutus_witnesses.rs b/rust/src/builders/script_structs/plutus_witnesses.rs new file mode 100644 index 00000000..74e94b62 --- /dev/null +++ b/rust/src/builders/script_structs/plutus_witnesses.rs @@ -0,0 +1,64 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub struct PlutusWitnesses(pub(crate) Vec); + +#[wasm_bindgen] +impl PlutusWitnesses { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> PlutusWitness { + self.0[index].clone() + } + + pub fn add(&mut self, elem: &PlutusWitness) { + self.0.push(elem.clone()); + } + + pub(crate) fn collect(&self) -> (PlutusScripts, Option, Redeemers) { + let mut used_scripts = BTreeSet::new(); + let mut used_datums = BTreeSet::new(); + let mut used_redeemers = BTreeSet::new(); + let mut s = PlutusScripts::new(); + let mut d: Option = None; + let mut r = Redeemers::new(); + self.0.iter().for_each(|w| { + if let PlutusScriptSourceEnum::Script(script, ..) = &w.script { + if used_scripts.insert(script.clone()) { + s.add(script); + } + } + if let Some(DatumSourceEnum::Datum(datum)) = &w.datum { + if used_datums.insert(datum) { + match d { + Some(ref mut d) => d.add(datum), + None => { + d = { + let mut initial_list = PlutusList::new(); + initial_list.add(datum); + Some(initial_list) + } + } + } + } + } + if used_redeemers.insert(w.redeemer.clone()) { + r.add(&w.redeemer); + } + }); + (s, d, r) + } +} + +impl From> for PlutusWitnesses { + fn from(scripts: Vec) -> Self { + Self(scripts) + } +} \ No newline at end of file diff --git a/rust/src/builders/script_structs/script_witness_type.rs b/rust/src/builders/script_structs/script_witness_type.rs new file mode 100644 index 00000000..0e7a8101 --- /dev/null +++ b/rust/src/builders/script_structs/script_witness_type.rs @@ -0,0 +1,66 @@ +use crate::*; + +#[derive(Clone, Debug)] +pub(crate) enum ScriptWitnessType { + NativeScriptWitness(NativeScriptSourceEnum), + PlutusScriptWitness(PlutusWitness), +} + +impl ScriptWitnessType { + pub(crate) fn script_hash(&self) -> ScriptHash { + match self { + ScriptWitnessType::NativeScriptWitness(script) => script.script_hash(), + ScriptWitnessType::PlutusScriptWitness(script) => script.script.script_hash(), + } + } + + pub(crate) fn get_required_signers(&self) -> Option { + match self { + ScriptWitnessType::NativeScriptWitness(script) => script.required_signers(), + ScriptWitnessType::PlutusScriptWitness(script) => script.get_required_signers(), + } + } + + pub(crate) fn get_script_ref_input(&self) -> Option { + match self { + ScriptWitnessType::NativeScriptWitness(NativeScriptSourceEnum::RefInput(input, ..)) => { + Some(input.clone()) + } + ScriptWitnessType::PlutusScriptWitness(plutus_witness) => { + match &plutus_witness.script { + PlutusScriptSourceEnum::RefInput(script_ref, ..) => { + Some(script_ref.input_ref.clone()) + } + _ => None, + } + } + _ => None, + } + } + + pub(crate) fn get_datum_ref_input(&self) -> Option { + match self { + ScriptWitnessType::PlutusScriptWitness(plutus_witness) => match &plutus_witness.datum { + Some(DatumSourceEnum::RefInput(input)) => Some(input.clone()), + _ => None, + }, + _ => None, + } + } + + pub(crate) fn get_script_ref_input_with_size( + &self, + ) -> Option<(&TransactionInput, usize)> { + match self { + ScriptWitnessType::PlutusScriptWitness(plutus_witness) => { + match &plutus_witness.script { + PlutusScriptSourceEnum::RefInput(script_ref, ..) => { + Some((&script_ref.input_ref, script_ref.script_size)) + } + _ => None, + } + } + _ => None, + } + } +} diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index 68c588f3..a43fcde7 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -6,44 +6,9 @@ use super::*; use crate::fees; use crate::utils; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; +use crate::builders::fakes::{fake_private_key, fake_raw_key_public, fake_raw_key_sig}; use crate::map_names::TxBodyNames::RequiredSigners; -pub(crate) fn fake_private_key() -> Bip32PrivateKey { - Bip32PrivateKey::from_bytes(&[ - 0xb8, 0xf2, 0xbe, 0xce, 0x9b, 0xdf, 0xe2, 0xb0, 0x28, 0x2f, 0x5b, 0xad, 0x70, 0x55, 0x62, - 0xac, 0x99, 0x6e, 0xfb, 0x6a, 0xf9, 0x6b, 0x64, 0x8f, 0x44, 0x45, 0xec, 0x44, 0xf4, 0x7a, - 0xd9, 0x5c, 0x10, 0xe3, 0xd7, 0x2f, 0x26, 0xed, 0x07, 0x54, 0x22, 0xa3, 0x6e, 0xd8, 0x58, - 0x5c, 0x74, 0x5a, 0x0e, 0x11, 0x50, 0xbc, 0xce, 0xba, 0x23, 0x57, 0xd0, 0x58, 0x63, 0x69, - 0x91, 0xf3, 0x8a, 0x37, 0x91, 0xe2, 0x48, 0xde, 0x50, 0x9c, 0x07, 0x0d, 0x81, 0x2a, 0xb2, - 0xfd, 0xa5, 0x78, 0x60, 0xac, 0x87, 0x6b, 0xc4, 0x89, 0x19, 0x2c, 0x1e, 0xf4, 0xce, 0x25, - 0x3c, 0x19, 0x7e, 0xe2, 0x19, 0xa4, - ]) - .unwrap() -} - -pub(crate) fn fake_raw_key_sig() -> Ed25519Signature { - Ed25519Signature::from_bytes(vec![ - 36, 248, 153, 211, 155, 23, 253, 93, 102, 193, 146, 196, 181, 13, 52, 62, 66, 247, 35, 91, - 48, 80, 76, 138, 231, 97, 159, 147, 200, 40, 220, 109, 206, 69, 104, 221, 105, 23, 124, 85, - 24, 40, 73, 45, 119, 122, 103, 39, 253, 102, 194, 251, 204, 189, 168, 194, 174, 237, 146, - 3, 44, 153, 121, 10, - ]) - .unwrap() -} - -pub(crate) fn fake_raw_key_public(x: u64) -> PublicKey { - let mut bytes = [0u8; 64]; - for i in 0..8 { - bytes[i] = ((x >> (i * 8)) & 0xff) as u8; - } - PublicKey::from_bytes(&[ - 207, 118, 57, 154, 33, 13, 232, 114, 14, 159, 168, 148, 228, 94, 65, 226, 154, 181, 37, - 227, 11, 196, 2, 128, bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], - bytes[7] - ]) - .unwrap() -} - fn count_needed_vkeys(tx_builder: &TransactionBuilder) -> usize { let mut input_hashes: Ed25519KeyHashes = Ed25519KeyHashes::from(&tx_builder.inputs); input_hashes.extend_move(Ed25519KeyHashes::from(&tx_builder.collateral)); @@ -167,16 +132,31 @@ fn min_fee(tx_builder: &TransactionBuilder) -> Result { // assert_required_mint_scripts(mint, tx_builder.mint_scripts.as_ref())?; // } let full_tx = fake_full_tx(tx_builder, tx_builder.build()?)?; - let fee: Coin = fees::min_fee(&full_tx, &tx_builder.config.fee_algo)?; + let mut fee: Coin = fees::min_fee(&full_tx, &tx_builder.config.fee_algo)?; + if let Some(ex_unit_prices) = &tx_builder.config.ex_unit_prices { let script_fee: Coin = fees::min_script_fee(&full_tx, &ex_unit_prices)?; - return fee.checked_add(&script_fee); + fee = fee.checked_add(&script_fee)?; + } else { + if tx_builder.has_plutus_inputs() { + return Err(JsError::from_str( + "Plutus inputs are present but ex_unit_prices are missing in the config!", + )); + } } - if tx_builder.has_plutus_inputs() { - return Err(JsError::from_str( - "Plutus inputs are present but ex unit prices are missing in the config!", - )); + + let total_ref_script_size = tx_builder.get_total_ref_scripts_size()?; + if let Some(ref_script_coins_per_byte) = &tx_builder.config.ref_script_coins_per_byte { + let script_ref_fee = min_ref_script_fee(total_ref_script_size, ref_script_coins_per_byte)?; + fee = fee.checked_add(&script_ref_fee)?; + } else { + if total_ref_script_size > 0 { + return Err(JsError::from_str( + "Plutus scripts are present but ref_script_coins_per_byte are missing in the config!", + )); + } } + Ok(fee) } @@ -202,6 +182,7 @@ pub struct TransactionBuilderConfig { pub(crate) max_tx_size: u32, // protocol parameter pub(crate) data_cost: DataCost, // protocol parameter pub(crate) ex_unit_prices: Option, // protocol parameter + pub(crate) ref_script_coins_per_byte: Option, // protocol parameter pub(crate) prefer_pure_change: bool, } @@ -221,6 +202,7 @@ pub struct TransactionBuilderConfigBuilder { max_tx_size: Option, // protocol parameter data_cost: Option, // protocol parameter ex_unit_prices: Option, // protocol parameter + ref_script_coins_per_byte: Option, // protocol parameter prefer_pure_change: bool, } @@ -235,6 +217,7 @@ impl TransactionBuilderConfigBuilder { max_tx_size: None, data_cost: None, ex_unit_prices: None, + ref_script_coins_per_byte: None, prefer_pure_change: false, } } @@ -281,6 +264,12 @@ impl TransactionBuilderConfigBuilder { cfg } + pub fn ref_script_coins_per_byte(&self, ref_script_coins_per_byte: &UnitInterval) -> Self { + let mut cfg = self.clone(); + cfg.ref_script_coins_per_byte = Some(ref_script_coins_per_byte.clone()); + cfg + } + pub fn prefer_pure_change(&self, prefer_pure_change: bool) -> Self { let mut cfg = self.clone(); cfg.prefer_pure_change = prefer_pure_change; @@ -309,6 +298,7 @@ impl TransactionBuilderConfigBuilder { "uninitialized field: coins_per_utxo_byte or coins_per_utxo_word", ))?, ex_unit_prices: cfg.ex_unit_prices, + ref_script_coins_per_byte: cfg.ref_script_coins_per_byte, prefer_pure_change: cfg.prefer_pure_change, }) } @@ -332,7 +322,7 @@ pub struct TransactionBuilder { pub(crate) required_signers: Ed25519KeyHashes, pub(crate) collateral_return: Option, pub(crate) total_collateral: Option, - pub(crate) reference_inputs: HashSet, + pub(crate) reference_inputs: HashMap, pub(crate) extra_datums: Option, pub(crate) voting_procedures: Option, pub(crate) voting_proposals: Option, @@ -626,9 +616,9 @@ impl TransactionBuilder { let j: &mut usize = relevant_indices.get_mut(random_index).unwrap(); let input = &available_inputs[*i]; let new_input = &available_inputs[*j]; - let cur = from_bignum(&by(&input.output.amount).unwrap_or(BigNum::zero())); - let new = from_bignum(&by(&new_input.output.amount).unwrap_or(BigNum::zero())); - let min = from_bignum(&by(&output.amount).unwrap_or(BigNum::zero())); + let cur: u64 = (&by(&input.output.amount).unwrap_or(BigNum::zero())).into(); + let new: u64 = (&by(&new_input.output.amount).unwrap_or(BigNum::zero())).into(); + let min: u64 = (&by(&output.amount).unwrap_or(BigNum::zero())).into(); let ideal = 2 * min; let max = 3 * min; let move_closer = @@ -750,7 +740,11 @@ impl TransactionBuilder { } pub fn add_reference_input(&mut self, reference_input: &TransactionInput) { - self.reference_inputs.insert(reference_input.clone()); + self.reference_inputs.insert(reference_input.clone(), 0); + } + + pub fn add_script_reference_input(&mut self, reference_input: &TransactionInput, script_size: usize) { + self.reference_inputs.insert(reference_input.clone(), script_size); } /// We have to know what kind of inputs these are to know what kind of mock witnesses to create since @@ -833,7 +827,7 @@ impl TransactionBuilder { // we need some value for these for it to be a a valid transaction // but since we're only calculating the difference between the fee of two transactions // it doesn't matter what these are set as, since it cancels out - self_copy.set_fee(&to_bignum(0)); + self_copy.set_fee(&BigNum::zero()); let fee_before = min_fee(&self_copy)?; @@ -855,8 +849,8 @@ impl TransactionBuilder { if output.amount().coin() < min_ada { Err(JsError::from_str(&format!( "Value {} less than the minimum UTXO value {}", - from_bignum(&output.amount().coin()), - from_bignum(&min_ada) + output.amount().coin(), + min_ada ))) } else { self.outputs.add(output); @@ -871,7 +865,7 @@ impl TransactionBuilder { // we need some value for these for it to be a a valid transaction // but since we're only calculating the different between the fee of two transactions // it doesn't matter what these are set as, since it cancels out - self_copy.set_fee(&to_bignum(0)); + self_copy.set_fee(&BigNum::zero()); let fee_before = min_fee(&self_copy)?; @@ -1253,7 +1247,7 @@ impl TransactionBuilder { required_signers: Ed25519KeyHashes::new(), collateral_return: None, total_collateral: None, - reference_inputs: HashSet::new(), + reference_inputs: HashMap::new(), extra_datums: None, voting_procedures: None, voting_proposals: None, @@ -1263,7 +1257,7 @@ impl TransactionBuilder { } pub fn get_reference_inputs(&self) -> TransactionInputs { - let mut inputs = self.reference_inputs.clone(); + let mut inputs: HashSet = self.reference_inputs.keys().cloned().collect(); for input in self.inputs.get_ref_inputs().0 { inputs.insert(input); } @@ -1302,6 +1296,57 @@ impl TransactionBuilder { TransactionInputs(vec_inputs) } + fn get_total_ref_scripts_size(&self) -> Result { + let mut sizes_map = HashMap::new(); + fn add_to_map<'a>(item: (&'a TransactionInput, usize), sizes_map: &mut HashMap<&'a TransactionInput, usize> ) -> Result<(), JsError>{ + if sizes_map.entry(item.0).or_insert(item.1) != &item.1 { + return Err(JsError::from_str(&format!("Different script sizes for the same ref input {}", item.0))); + } else { + Ok(()) + } + } + + for item in self.inputs.get_script_ref_inputs_with_size() { + add_to_map(item, &mut sizes_map)? + } + + for (tx_in, size) in &self.reference_inputs { + add_to_map((tx_in, *size), &mut sizes_map)? + } + + if let Some(mint) = &self.mint { + for item in mint.get_script_ref_inputs_with_size() { + add_to_map(item, &mut sizes_map)? + } + } + + if let Some(withdrawals) = &self.withdrawals { + for item in withdrawals.get_script_ref_inputs_with_size() { + add_to_map(item, &mut sizes_map)? + } + } + + if let Some(certs) = &self.certs { + for item in certs.get_script_ref_inputs_with_size() { + add_to_map(item, &mut sizes_map)? + } + } + + if let Some(voting_procedures) = &self.voting_procedures { + for item in voting_procedures.get_script_ref_inputs_with_size() { + add_to_map(item, &mut sizes_map)? + } + } + + if let Some(voting_proposals) = &self.voting_proposals { + for item in voting_proposals.get_script_ref_inputs_with_size() { + add_to_map(item, &mut sizes_map)? + } + } + + Ok(sizes_map.values().sum()) + } + /// does not include refunds or withdrawals pub fn get_explicit_input(&self) -> Result { self.inputs @@ -1365,7 +1410,7 @@ impl TransactionBuilder { self.outputs .0 .iter() - .try_fold(Value::new(&to_bignum(0)), |acc, ref output| { + .try_fold(Value::new(&BigNum::zero()), |acc, ref output| { acc.checked_add(&output.amount()) }) } @@ -2154,7 +2199,7 @@ impl TransactionBuilder { /// this is done to simplify the library code, but can be fixed later pub fn min_fee(&self) -> Result { let mut self_copy = self.clone(); - self_copy.set_fee(&to_bignum(0x1_00_00_00_00)); + self_copy.set_fee(&(0x1_00_00_00_00u64).into()); min_fee(&self_copy) } } diff --git a/rust/src/builders/tx_inputs_builder.rs b/rust/src/builders/tx_inputs_builder.rs index b087fc26..c9385d33 100644 --- a/rust/src/builders/tx_inputs_builder.rs +++ b/rust/src/builders/tx_inputs_builder.rs @@ -8,7 +8,6 @@ pub(crate) struct TxBuilderInput { pub(crate) amount: Value, // we need to keep track of the amount in the inputs for input selection } - // We need to know how many of each type of witness will be in the transaction so we can calculate the tx fee #[derive(Clone, Debug)] pub struct InputsRequiredWitness { @@ -62,12 +61,7 @@ impl TxInputsBuilder { self.required_witnesses.vkeys.add_move(hash.clone()); } - fn add_script_input( - &mut self, - hash: &ScriptHash, - input: &TransactionInput, - amount: &Value, - ) { + fn add_script_input(&mut self, hash: &ScriptHash, input: &TransactionInput, amount: &Value) { let inp = TxBuilderInput { input: input.clone(), amount: amount.clone(), @@ -87,6 +81,7 @@ impl TxInputsBuilder { self.add_script_input(&hash, input, amount); let witness = ScriptWitnessType::NativeScriptWitness(NativeScriptSourceEnum::NativeScript( script.clone(), + None, )); self.insert_input_with_witness(&hash, input, &witness); } @@ -120,51 +115,50 @@ impl TxInputsBuilder { } /// Adds non script input, in case of script or reward address input it will return an error - pub fn add_regular_input(&mut self, address: &Address, input: &TransactionInput, amount: &Value) -> Result<(), JsError>{ + pub fn add_regular_input( + &mut self, + address: &Address, + input: &TransactionInput, + amount: &Value, + ) -> Result<(), JsError> { match &address.0 { - AddrType::Base(base_addr) => { - match &base_addr.payment.0 { - CredType::Key(key) => { - self.add_key_input(key, input, amount); - Ok(()) - }, - CredType::Script(_) => { - Err(JsError::from_str(BuilderError::RegularInputIsScript.as_str())) - }, + AddrType::Base(base_addr) => match &base_addr.payment.0 { + CredType::Key(key) => { + self.add_key_input(key, input, amount); + Ok(()) } + CredType::Script(_) => Err(JsError::from_str( + BuilderError::RegularInputIsScript.as_str(), + )), }, - AddrType::Enterprise(ent_aaddr) => { - match &ent_aaddr.payment.0 { - CredType::Key(key) => { - self.add_key_input(key, input, amount); - Ok(()) - }, - CredType::Script(_) => { - Err(JsError::from_str(BuilderError::RegularInputIsScript.as_str())) - }, + AddrType::Enterprise(ent_aaddr) => match &ent_aaddr.payment.0 { + CredType::Key(key) => { + self.add_key_input(key, input, amount); + Ok(()) } + CredType::Script(_) => Err(JsError::from_str( + BuilderError::RegularInputIsScript.as_str(), + )), }, - AddrType::Ptr(ptr_addr) => { - match &ptr_addr.payment.0 { - CredType::Key(key) => { - self.add_key_input(key, input, amount); - Ok(()) - }, - CredType::Script(_) => { - Err(JsError::from_str(BuilderError::RegularInputIsScript.as_str())) - }, + AddrType::Ptr(ptr_addr) => match &ptr_addr.payment.0 { + CredType::Key(key) => { + self.add_key_input(key, input, amount); + Ok(()) } + CredType::Script(_) => Err(JsError::from_str( + BuilderError::RegularInputIsScript.as_str(), + )), }, AddrType::Byron(byron_addr) => { self.add_bootstrap_input(byron_addr, input, amount); Ok(()) - }, - AddrType::Reward(_) => { - Err(JsError::from_str(BuilderError::RegularInputIsFromRewardAddress.as_str())) - }, + } + AddrType::Reward(_) => Err(JsError::from_str( + BuilderError::RegularInputIsFromRewardAddress.as_str(), + )), AddrType::Malformed(_) => { Err(JsError::from_str(BuilderError::MalformedAddress.as_str())) - }, + } } } @@ -189,8 +183,9 @@ impl TxInputsBuilder { if let Some(DatumSourceEnum::RefInput(input)) = &plutus_witness.datum { inputs.push(input.clone()); } - if let PlutusScriptSourceEnum::RefInput(input, _, _) = &plutus_witness.script { - inputs.push(input.clone()); + if let PlutusScriptSourceEnum::RefInput(script_ref, _) = &plutus_witness.script + { + inputs.push(script_ref.input_ref.clone()); } } _ => (), @@ -199,6 +194,7 @@ impl TxInputsBuilder { TransactionInputs(inputs) } + /// Returns a copy of the current script input witness scripts in the builder pub fn get_native_input_scripts(&self) -> Option { let mut scripts = NativeScripts::new(); @@ -208,7 +204,7 @@ impl TxInputsBuilder { .flat_map(|v| v) .for_each(|tx_in_with_wit| { if let Some(ScriptWitnessType::NativeScriptWitness( - NativeScriptSourceEnum::NativeScript(s), + NativeScriptSourceEnum::NativeScript(s, _), )) = tx_in_with_wit.1 { scripts.add(&s); @@ -223,22 +219,13 @@ impl TxInputsBuilder { pub(crate) fn get_used_plutus_lang_versions(&self) -> BTreeSet { let mut used_langs = BTreeSet::new(); - self.required_witnesses - .scripts - .values() - .for_each(|input_with_wit| { - for (_, script_wit) in input_with_wit { - if let Some(ScriptWitnessType::PlutusScriptWitness(PlutusWitness { - script, - .. - })) = script_wit - { - if let Some(lang) = script.language() { - used_langs.insert(lang); - } - } + for input_with_wit in self.required_witnesses.scripts.values() { + for (_, script_wit) in input_with_wit { + if let Some(ScriptWitnessType::PlutusScriptWitness(plutus_witness)) = script_wit { + used_langs.insert(plutus_witness.script.language()); } - }); + } + } used_langs } @@ -264,7 +251,7 @@ impl TxInputsBuilder { .enumerate() .fold(BTreeMap::new(), |mut m, (i, (tx_in, hash_option))| { if hash_option.is_some() { - m.insert(&tx_in.input, to_bignum(i as u64)); + m.insert(&tx_in.input, (i as u64).into()); } m }); @@ -335,6 +322,17 @@ impl TxInputsBuilder { } } + pub(crate) fn get_script_ref_inputs_with_size( + &self, + ) -> impl Iterator { + self.required_witnesses + .scripts + .iter() + .flat_map(|(_, tx_wits)| tx_wits.iter()) + .filter_map(|(_, wit)| wit.as_ref()) + .filter_map(|wit| wit.get_script_ref_input_with_size()) + } + fn insert_input_with_witness( &mut self, script_hash: &ScriptHash, @@ -373,7 +371,9 @@ impl From<&TxInputsBuilder> for Ed25519KeyHashes { .flat_map(|tx_wits| tx_wits.values()) .for_each(|swt: &Option| { if let Some(ScriptWitnessType::NativeScriptWitness(script_source)) = swt { - set.extend_move(script_source.required_signers()); + if let Some(signers) = script_source.required_signers() { + set.extend_move(signers); + } } }); set diff --git a/rust/src/builders/voting_builder.rs b/rust/src/builders/voting_builder.rs index 5b770efb..84de3bcf 100644 --- a/rust/src/builders/voting_builder.rs +++ b/rust/src/builders/voting_builder.rs @@ -111,7 +111,9 @@ impl VotingBuilder { if let Some(ScriptWitnessType::NativeScriptWitness(script_source)) = &voter_votes.script_witness { - set.extend_move(script_source.required_signers()); + if let Some(required_signers) = script_source.required_signers() { + set.extend_move(required_signers); + } } } set @@ -133,17 +135,12 @@ impl VotingBuilder { let mut inputs = Vec::new(); for (_, voter_votes) in &self.votes { match &voter_votes.script_witness { - Some(ScriptWitnessType::NativeScriptWitness(script_source)) => { - if let NativeScriptSourceEnum::RefInput(input, _, _) = script_source { - inputs.push(input.clone()); - } - } - Some(ScriptWitnessType::PlutusScriptWitness(plutus_witness)) => { - if let Some(DatumSourceEnum::RefInput(input)) = &plutus_witness.datum { - inputs.push(input.clone()); + Some(script_witness) => { + if let Some(input) = script_witness.get_script_ref_input() { + inputs.push(input); } - if let PlutusScriptSourceEnum::RefInput(input, _, _) = &plutus_witness.script { - inputs.push(input.clone()); + if let Some(input) = script_witness.get_datum_ref_input() { + inputs.push(input); } } None => {} @@ -156,7 +153,7 @@ impl VotingBuilder { let mut scripts = NativeScripts::new(); for (_, voter_votes) in &self.votes { if let Some(ScriptWitnessType::NativeScriptWitness( - NativeScriptSourceEnum::NativeScript(script), + NativeScriptSourceEnum::NativeScript(script, _), )) = &voter_votes.script_witness { scripts.add(script); @@ -169,14 +166,23 @@ impl VotingBuilder { let mut used_langs = BTreeSet::new(); for (_, voter_votes) in &self.votes { if let Some(ScriptWitnessType::PlutusScriptWitness(s)) = &voter_votes.script_witness { - if let Some(lang) = s.script.language() { - used_langs.insert(lang.clone()); - } + used_langs.insert(s.script.language()); } } used_langs } + //return only ref inputs that are script refs with added size + //used for calculating the fee for the transaction + //another ref input and also script ref input without size are filtered out + pub(crate) fn get_script_ref_inputs_with_size( + &self, + ) -> impl Iterator { + self.votes.iter() + .filter_map(|(_, voter_votes)| voter_votes.script_witness.as_ref()) + .filter_map(|script_witness| script_witness.get_script_ref_input_with_size()) + } + pub fn has_plutus_scripts(&self) -> bool { for (_, voter_votes) in &self.votes { if let Some(ScriptWitnessType::PlutusScriptWitness(_)) = voter_votes.script_witness { diff --git a/rust/src/builders/voting_proposal_builder.rs b/rust/src/builders/voting_proposal_builder.rs index 949b8da7..70a91ed5 100644 --- a/rust/src/builders/voting_proposal_builder.rs +++ b/rust/src/builders/voting_proposal_builder.rs @@ -51,17 +51,12 @@ impl VotingProposalBuilder { let mut inputs = Vec::new(); for (_, script_wit) in &self.proposals { match script_wit { - Some(ScriptWitnessType::NativeScriptWitness(script_source)) => { - if let NativeScriptSourceEnum::RefInput(input, _, _) = script_source { - inputs.push(input.clone()); + Some(script_witness) => { + if let Some(input) = script_witness.get_script_ref_input() { + inputs.push(input); } - } - Some(ScriptWitnessType::PlutusScriptWitness(plutus_witness)) => { - if let Some(DatumSourceEnum::RefInput(input)) = &plutus_witness.datum { - inputs.push(input.clone()); - } - if let PlutusScriptSourceEnum::RefInput(input, _, _) = &plutus_witness.script { - inputs.push(input.clone()); + if let Some(input) = script_witness.get_datum_ref_input() { + inputs.push(input); } } None => {} @@ -86,14 +81,23 @@ impl VotingProposalBuilder { let mut used_langs = BTreeSet::new(); for (_, script_wit) in &self.proposals { if let Some(ScriptWitnessType::PlutusScriptWitness(s)) = script_wit { - if let Some(lang) = s.script.language() { - used_langs.insert(lang.clone()); - } + used_langs.insert(s.script.language()); } } used_langs } + //return only ref inputs that are script refs with added size + //used for calculating the fee for the transaction + //another ref input and also script ref input without size are filtered out + pub(crate) fn get_script_ref_inputs_with_size( + &self, + ) -> impl Iterator { + self.proposals.iter() + .filter_map(|(_, script_wit)| script_wit.as_ref()) + .filter_map(|script_wit| script_wit.get_script_ref_input_with_size()) + } + pub fn has_plutus_scripts(&self) -> bool { for (_, script_wit) in &self.proposals { if let Some(ScriptWitnessType::PlutusScriptWitness(_)) = script_wit { diff --git a/rust/src/builders/withdrawals_builder.rs b/rust/src/builders/withdrawals_builder.rs index 2366dbdf..d3e9ea61 100644 --- a/rust/src/builders/withdrawals_builder.rs +++ b/rust/src/builders/withdrawals_builder.rs @@ -85,8 +85,10 @@ impl WithdrawalsBuilder { set.add_move(req_signature); } - if let Some(ScriptWitnessType::NativeScriptWitness(script_source)) = script_wit { - set.extend_move(script_source.required_signers()); + if let Some(script_wit) = script_wit { + if let Some(script_wit) = script_wit.get_required_signers() { + set.extend_move(script_wit); + } } } set @@ -108,17 +110,12 @@ impl WithdrawalsBuilder { let mut inputs = Vec::new(); for (_, (_, script_wit)) in self.withdrawals.iter() { match script_wit { - Some(ScriptWitnessType::NativeScriptWitness(script_source)) => { - if let NativeScriptSourceEnum::RefInput(input, _, _) = script_source { - inputs.push(input.clone()); - } - } - Some(ScriptWitnessType::PlutusScriptWitness(plutus_witness)) => { - if let Some(DatumSourceEnum::RefInput(input)) = &plutus_witness.datum { - inputs.push(input.clone()); + Some(script_witness) => { + if let Some(input) = script_witness.get_script_ref_input() { + inputs.push(input); } - if let PlutusScriptSourceEnum::RefInput(input, _, _) = &plutus_witness.script { - inputs.push(input.clone()); + if let Some(input) = script_witness.get_datum_ref_input() { + inputs.push(input); } } None => {} @@ -131,7 +128,7 @@ impl WithdrawalsBuilder { let mut scripts = NativeScripts::new(); for (_, (_, script_wit)) in self.withdrawals.iter() { if let Some(ScriptWitnessType::NativeScriptWitness( - NativeScriptSourceEnum::NativeScript(script), + NativeScriptSourceEnum::NativeScript(script, _), )) = script_wit { scripts.add(script); @@ -144,9 +141,7 @@ impl WithdrawalsBuilder { let mut used_langs = BTreeSet::new(); for (_, (_, script_wit)) in &self.withdrawals { if let Some(ScriptWitnessType::PlutusScriptWitness(s)) = script_wit { - if let Some(lang) = s.script.language() { - used_langs.insert(lang.clone()); - } + used_langs.insert(s.script.language()); } } used_langs @@ -169,6 +164,17 @@ impl WithdrawalsBuilder { false } + //return only ref inputs that are script refs with added size + //used for calculating the fee for the transaction + //another ref input and also script ref input without size are filtered out + pub(crate) fn get_script_ref_inputs_with_size( + &self, + ) -> impl Iterator { + self.withdrawals.iter() + .filter_map(|(_, (_, script_wit))| script_wit.as_ref()) + .filter_map(|script_wit| script_wit.get_script_ref_input_with_size()) + } + pub fn build(&self) -> Withdrawals { let map = self .withdrawals diff --git a/rust/src/fakes.rs b/rust/src/fakes.rs index 3a2cbef7..a06f689c 100644 --- a/rust/src/fakes.rs +++ b/rust/src/fakes.rs @@ -1,7 +1,7 @@ #![allow(dead_code)] -use crate::{AnchorDataHash, AuxiliaryDataHash, GenesisDelegateHash, GenesisHash, PoolMetadataHash, PublicKey, ScriptDataHash, ScriptHash, Vkeywitness, VRFKeyHash}; +use crate::{AnchorDataHash, AuxiliaryDataHash, BigNum, GenesisDelegateHash, GenesisHash, PoolMetadataHash, PublicKey, ScriptDataHash, ScriptHash, Vkeywitness, VRFKeyHash}; use crate::{ - to_bignum, Address, BaseAddress, Bip32PrivateKey, Credential, DataHash, Ed25519KeyHash, + Address, BaseAddress, Bip32PrivateKey, Credential, DataHash, Ed25519KeyHash, Ed25519Signature, NetworkInfo, PolicyID, TransactionHash, TransactionIndex, TransactionInput, TransactionOutput, Value, Vkey, AssetName, }; @@ -87,7 +87,7 @@ pub(crate) fn fake_value() -> Value { } pub(crate) fn fake_value2(v: u64) -> Value { - Value::new(&to_bignum(v)) + Value::new(&BigNum(v)) } pub(crate) fn fake_tx_output(input_hash_byte: u8) -> TransactionOutput { diff --git a/rust/src/fees.rs b/rust/src/fees.rs index dfd0c413..07281b04 100644 --- a/rust/src/fees.rs +++ b/rust/src/fees.rs @@ -1,5 +1,6 @@ use super::*; use utils::*; +use crate::rational::{Rational}; #[wasm_bindgen] #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] @@ -42,40 +43,12 @@ pub fn calculate_ex_units_ceil_cost( ex_units: &ExUnits, ex_unit_prices: &ExUnitPrices, ) -> Result { - type Ratio = (BigInt, BigInt); - fn mult(sc: &SubCoin, x: &BigNum) -> Result { - let n: BigInt = BigInt::from_str(&sc.numerator.to_str())?; - let d: BigInt = BigInt::from_str(&sc.denominator.to_str())?; - let m: BigInt = BigInt::from_str(&x.to_str())?; - Ok((n.mul(&m), d)) - } - fn sum(a: &Ratio, b: &Ratio) -> Ratio { - // Ratio Addition: a/x + b/y = ((a*y) + (b*x))/(x*y) - let (a_num, a_denum) = &a; - let (b_num, b_denum) = &b; - if a_num.is_zero() { - return b.clone(); - } - if b_num.is_zero() { - return a.clone(); - } - let a_num_fixed = &a_num.mul(b_denum); - let b_num_fixed = &b_num.mul(a_denum); - let a_b_num_sum = a_num_fixed.add(b_num_fixed); - let common_denum = a_denum.mul(b_denum); - (a_b_num_sum, common_denum) - } - let mem_ratio: Ratio = mult(&ex_unit_prices.mem_price(), &ex_units.mem())?; - let steps_ratio: Ratio = mult(&ex_unit_prices.step_price(), &ex_units.steps())?; - let (total_num, total_denum) = sum(&mem_ratio, &steps_ratio); - match total_num.div_ceil(&total_denum).as_u64() { - Some(coin) => Ok(coin), - _ => Err(JsError::from_str(&format!( - "Failed to calculate ceil from ratio {}/{}", - total_num.to_str(), - total_denum.to_str(), - ))), - } + let mem_price: Rational = ex_unit_prices.mem_price().into(); + let steps_price: Rational = ex_unit_prices.step_price().into(); + let mem_ratio = mem_price.mul_bignum(&ex_units.mem())?; + let steps_ratio = steps_price.mul_bignum(&ex_units.steps())?; + let total = mem_ratio.add(&steps_ratio); + total.to_bignum_ceil() } #[wasm_bindgen] @@ -87,6 +60,13 @@ pub fn min_script_fee(tx: &Transaction, ex_unit_prices: &ExUnitPrices) -> Result Ok(Coin::zero()) } +#[wasm_bindgen] +pub fn min_ref_script_fee(total_ref_scripts_size: usize, ref_script_coins_per_byte: &UnitInterval) -> Result { + let ref_multiplier : Rational = ref_script_coins_per_byte.into(); + let total_fee = ref_multiplier.mul_usize(total_ref_scripts_size); + total_fee.to_bignum_ceil() +} + #[cfg(test)] mod tests { use super::*; @@ -124,11 +104,11 @@ mod tests { ) .next() .unwrap() - .with_coin(&to_bignum(1)) + .with_coin(&BigNum(1)) .build() .unwrap(), ); - let body = TransactionBody::new(&inputs, &outputs, &to_bignum(94002), Some(10)); + let body = TransactionBody::new(&inputs, &outputs, &BigNum(94002), Some(10)); let mut w = TransactionWitnessSet::new(); let mut vkw = Vkeywitnesses::new(); @@ -144,7 +124,7 @@ mod tests { let signed_tx = Transaction::new(&body, &w, None); - let linear_fee = LinearFee::new(&to_bignum(500), &to_bignum(2)); + let linear_fee = LinearFee::new(&BigNum(500), &BigNum(2)); assert_eq!( hex::encode(signed_tx.to_bytes()), "84a400818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a00016f32030aa10081825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee5840fae5de40c94d759ce13bf9886262159c4f26a289fd192e165995b785259e503f6887bf39dfa23a47cf163784c6eee23f61440e749bc1df3c73975f5231aeda0ff5f6" @@ -179,11 +159,11 @@ mod tests { ) .next() .unwrap() - .with_coin(&to_bignum(1)) + .with_coin(&BigNum(1)) .build() .unwrap(), ); - let body = TransactionBody::new(&inputs, &outputs, &to_bignum(112002), Some(10)); + let body = TransactionBody::new(&inputs, &outputs, &BigNum(112002), Some(10)); let mut w = TransactionWitnessSet::new(); let mut bootstrap_wits = BootstrapWitnesses::new(); @@ -198,7 +178,7 @@ mod tests { let signed_tx = Transaction::new(&body, &w, None); - let linear_fee = LinearFee::new(&to_bignum(500), &to_bignum(2)); + let linear_fee = LinearFee::new(&BigNum(500), &BigNum(2)); assert_eq!( hex::encode(signed_tx.to_bytes()), "84a400818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a0001b582030aa10281845820473811afd4d939b337c9be1a2ceeb2cb2c75108bddf224c5c21c51592a7b204a5840f0b04a852353eb23b9570df80b2aa6a61b723341ab45a2024a05b07cf58be7bdfbf722c09040db6cee61a0d236870d6ad1e1349ac999ec0db28f9471af25fb0c5820c8b95d0d35fe75a70f9f5633a3e2439b2994b9e2bc851c49e9f91d1a5dcbb1a341a0f5f6" @@ -242,7 +222,7 @@ mod tests { ) .next() .unwrap() - .with_coin(&to_bignum(289)) + .with_coin(&BigNum(289)) .build() .unwrap(), ); @@ -257,11 +237,11 @@ mod tests { ) .next() .unwrap() - .with_coin(&to_bignum(874551452)) + .with_coin(&BigNum(874551452)) .build() .unwrap(), ); - let body = TransactionBody::new(&inputs, &outputs, &to_bignum(183502), Some(999)); + let body = TransactionBody::new(&inputs, &outputs, &BigNum(183502), Some(999)); let mut w = TransactionWitnessSet::new(); let mut vkw = Vkeywitnesses::new(); @@ -285,7 +265,7 @@ mod tests { let signed_tx = Transaction::new(&body, &w, None); - let linear_fee = LinearFee::new(&to_bignum(500), &to_bignum(2)); + let linear_fee = LinearFee::new(&BigNum(500), &BigNum(2)); assert_eq!( hex::encode(signed_tx.to_bytes()), "84a400828258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7182a82582082839f8200d81858248258203b40265111d8bb3c3c608d95b3a0bf83461ace3207018282581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c19012182581d61bcd18fcffa797c16c007014e2b8553b8b9b1e94c507688726243d6111a3420989c021a0002ccce031903e7a10082825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee58401ec3e56008650282ba2e1f8a20e81707810b2d0973c4d42a1b4df65b732bda81567c7824904840b2554d2f33861da5d70588a29d33b2b61042e3c3445301d8008258206872b0a874acfe1cace12b20ea348559a7ecc912f2fc7f674f43481df973d92c5840a0718fb5b37d89ddf926c08e456d3f4c7f749e91f78bb3e370751d5b632cbd20d38d385805291b1ef2541b02543728a235e01911f4b400bfb50e5fce589de907f5f6" @@ -322,11 +302,11 @@ mod tests { ) .next() .unwrap() - .with_coin(&to_bignum(1)) + .with_coin(&BigNum(1)) .build() .unwrap(), ); - let mut body = TransactionBody::new(&inputs, &outputs, &to_bignum(266002), Some(10)); + let mut body = TransactionBody::new(&inputs, &outputs, &BigNum(266002), Some(10)); let mut certs = Certificates::new(); @@ -350,9 +330,9 @@ mod tests { &hex::decode("fbf6d41985670b9041c5bf362b5262cf34add5d265975de176d613ca05f37096") .unwrap(), )), // vrf_keyhash - &to_bignum(1000000), // pledge - &to_bignum(1000000), // cost - &UnitInterval::new(&to_bignum(3), &to_bignum(100)), // margin + &BigNum(1000000), // pledge + &BigNum(1000000), // cost + &UnitInterval::new(&BigNum(3), &BigNum(100)), // margin &RewardAddress::new( network, &Credential::from_keyhash( @@ -406,7 +386,7 @@ mod tests { let signed_tx = Transaction::new(&body, &w, None); - let linear_fee = LinearFee::new(&to_bignum(500), &to_bignum(2)); + let linear_fee = LinearFee::new(&BigNum(500), &BigNum(2)); assert_eq!( hex::encode(signed_tx.to_bytes()), "84a500818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a00040f12030a04818a03581c1c13374874c68016df54b1339b6cacdd801098431e7659b24928efc15820bd0000f498ccacdc917c28274cba51c415f3f21931ff41ca8dc1197499f8e1241a000f42401a000f4240d81e82031864581de151df9ba1b74a1c9608a487e114184556801e927d31d96425cb80af7081581c51df9ba1b74a1c9608a487e114184556801e927d31d96425cb80af7080f6a10083825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee5840a7f305d7e46abfe0f7bea6098bdf853ab9ce8e7aa381be5a991a871852f895a718e20614e22be43494c4dc3a8c78c56cd44fd38e0e5fff3e2fbd19f70402fc02825820b24c040e65994bd5b0621a060166d32d356ef4be3cc1f848426a4cf386887089584013c372f82f1523484eab273241d66d92e1402507760e279480912aa5f0d88d656d6f25d41e65257f2f38c65ac5c918a6735297741adfc718394994f20a1cfd0082582054d1a9c5ad69586ceeb839c438400c376c0bd34825fb4c17cc2f58c54e1437f35840d326b993dfec21b9b3e1bd2f80adadc2cd673a1d8d033618cc413b0b02bc3b7efbb23d1ff99138abd05c398ce98e7983a641b50dcf0f64ed33f26c6e636b0b0ff5f6" @@ -422,8 +402,8 @@ mod tests { // let mut inputs = TransactionInputs::new(); // inputs.add(&TransactionInput::new(&genesis_id(), 0)); // let mut outputs = TransactionOutputs::new(); - // outputs.add(&TransactionOutput::new(&alice_addr(), to_bignum(10))); - // let mut body = TransactionBody::new(&inputs, &outputs, to_bignum(94), 10); + // outputs.add(&TransactionOutput::new(&alice_addr(), BigNum(10))); + // let mut body = TransactionBody::new(&inputs, &outputs, BigNum(94), 10); // let mut certs = Certificates::new(); // certs.add(&Certificate::new_stake_delegation(&StakeDelegation::new(&bob_stake(), &alice_pool()))); // body.set_certs(&certs); @@ -439,8 +419,8 @@ mod tests { // let mut inputs = TransactionInputs::new(); // inputs.add(&TransactionInput::new(&genesis_id(), 0)); // let mut outputs = TransactionOutputs::new(); - // outputs.add(&TransactionOutput::new(&alice_addr(), to_bignum(10))); - // let mut body = TransactionBody::new(&inputs, &outputs, to_bignum(94), 10); + // outputs.add(&TransactionOutput::new(&alice_addr(), BigNum(10))); + // let mut body = TransactionBody::new(&inputs, &outputs, BigNum(94), 10); // let mut certs = Certificates::new(); // certs.add(&Certificate::new_stake_deregistration(&StakeDeregistration::new(&alice_pay()))); // body.set_certs(&certs); @@ -456,8 +436,8 @@ mod tests { // let mut inputs = TransactionInputs::new(); // inputs.add(&TransactionInput::new(&genesis_id(), 0)); // let mut outputs = TransactionOutputs::new(); - // outputs.add(&TransactionOutput::new(&alice_addr(), to_bignum(10))); - // let mut body = TransactionBody::new(&inputs, &outputs, to_bignum(94), 10); + // outputs.add(&TransactionOutput::new(&alice_addr(), BigNum(10))); + // let mut body = TransactionBody::new(&inputs, &outputs, BigNum(94), 10); // let mut certs = Certificates::new(); // let mut owners = Ed25519KeyHashes::new(); // owners.add(&(alice_stake().to_keyhash().unwrap())); @@ -466,9 +446,9 @@ mod tests { // let params = PoolParams::new( // &alice_pool(), // &VRFKeyHash::from([0u8; VRFKeyHash::BYTE_COUNT]), - // to_bignum(1), - // to_bignum(5), - // &UnitInterval::new(to_bignum(1), to_bignum(10)), + // BigNum(1), + // BigNum(5), + // &UnitInterval::new(BigNum(1), BigNum(10)), // &RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &alice_stake()), // &owners, // &relays, @@ -498,8 +478,8 @@ mod tests { // let mut inputs = TransactionInputs::new(); // inputs.add(&TransactionInput::new(&genesis_id(), 0)); // let mut outputs = TransactionOutputs::new(); - // outputs.add(&TransactionOutput::new(&alice_addr(), to_bignum(10))); - // let mut body = TransactionBody::new(&inputs, &outputs, to_bignum(94), 10); + // outputs.add(&TransactionOutput::new(&alice_addr(), BigNum(10))); + // let mut body = TransactionBody::new(&inputs, &outputs, BigNum(94), 10); // let mut certs = Certificates::new(); // certs.add(&Certificate::new_pool_retirement(&PoolRetirement::new(&alice_pool(), 5))); // body.set_certs(&certs); @@ -515,13 +495,13 @@ mod tests { // let mut inputs = TransactionInputs::new(); // inputs.add(&TransactionInput::new(&genesis_id(), 0)); // let mut outputs = TransactionOutputs::new(); - // outputs.add(&TransactionOutput::new(&alice_addr(), to_bignum(10))); - // let mut body = TransactionBody::new(&inputs, &outputs, to_bignum(94), 10); + // outputs.add(&TransactionOutput::new(&alice_addr(), BigNum(10))); + // let mut body = TransactionBody::new(&inputs, &outputs, BigNum(94), 10); // body.set_metadata_hash(&MetadataHash::from([37; MetadataHash::BYTE_COUNT])); // let w = make_mock_witnesses_vkey(&body, vec![&alice_key()]); // let mut metadata = TransactionMetadata::new(); // let mut md_list = TransactionMetadatums::new(); - // md_list.add(&TransactionMetadatum::new_int(&Int::new(&to_bignum(5)))); + // md_list.add(&TransactionMetadatum::new_int(&Int::new(&BigNum(5)))); // md_list.add(&TransactionMetadatum::new_text(String::from("hello"))); // metadata.insert(TransactionMetadatumLabel::new(0), &TransactionMetadatum::new_arr_transaction_metadatum(&md_list)); // let tx = Transaction::new(&body, &w, Some(metadata)); @@ -535,8 +515,8 @@ mod tests { // let mut inputs = TransactionInputs::new(); // inputs.add(&TransactionInput::new(&genesis_id(), 0)); // let mut outputs = TransactionOutputs::new(); - // outputs.add(&TransactionOutput::new(&alice_addr(), to_bignum(10))); - // let body = TransactionBody::new(&inputs, &outputs, to_bignum(94), 10); + // outputs.add(&TransactionOutput::new(&alice_addr(), BigNum(10))); + // let body = TransactionBody::new(&inputs, &outputs, BigNum(94), 10); // let mut w = make_mock_witnesses_vkey(&body, vec![&alice_key(), &bob_key()]); // let mut script_witnesses = MultisigScripts::new(); // let mut inner_scripts = MultisigScripts::new(); @@ -576,11 +556,11 @@ mod tests { ) .next() .unwrap() - .with_coin(&to_bignum(1)) + .with_coin(&BigNum(1)) .build() .unwrap(), ); - let mut body = TransactionBody::new(&inputs, &outputs, &to_bignum(162502), Some(10)); + let mut body = TransactionBody::new(&inputs, &outputs, &BigNum(162502), Some(10)); let mut withdrawals = Withdrawals::new(); withdrawals.insert( &RewardAddress::from_address( @@ -591,7 +571,7 @@ mod tests { .unwrap(), ) .unwrap(), - &to_bignum(1337), + &BigNum(1337), ); body.set_withdrawals(&withdrawals); @@ -619,7 +599,7 @@ mod tests { let signed_tx = Transaction::new(&body, &w, None); - let linear_fee = LinearFee::new(&to_bignum(500), &to_bignum(2)); + let linear_fee = LinearFee::new(&BigNum(500), &BigNum(2)); assert_eq!( hex::encode(signed_tx.to_bytes()), "84a500818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a00027ac6030a05a1581de151df9ba1b74a1c9608a487e114184556801e927d31d96425cb80af70190539a10082825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee5840fc0493f7121efe385d72830680e735ccdef99c3a31953fe877b89ad3a97fcdb871cc7f2cdd6a8104e52f6963bd9e10d814d4fabdbcdc8475bc63e872dcc94d0a82582054d1a9c5ad69586ceeb839c438400c376c0bd34825fb4c17cc2f58c54e1437f35840a051ba927582004aedab736b9f1f9330ff867c260f4751135d480074256e83cd23d2a4bb109f955c43afdcdc5d1841b28d5c1ea2148dfbb6252693590692bb00f5f6" @@ -631,11 +611,11 @@ mod tests { } fn exunits(mem: u64, steps: u64) -> ExUnits { - ExUnits::new(&to_bignum(mem), &to_bignum(steps)) + ExUnits::new(&BigNum(mem), &BigNum(steps)) } fn subcoin(num: u64, denum: u64) -> SubCoin { - SubCoin::new(&to_bignum(num), &to_bignum(denum)) + SubCoin::new(&BigNum(num), &BigNum(denum)) } fn exunit_prices(mem_prices: (u64, u64), step_prices: (u64, u64)) -> ExUnitPrices { @@ -661,22 +641,22 @@ mod tests { // 10 * (2/1) + 20 * (3/1) = 10 * 2 + 20 * 3 = 20 + 60 assert_eq!( _calculate_ex_units_ceil_cost(10, 20, (2, 1), (3, 1)), - to_bignum(80), + BigNum(80), ); // 22 * (12/6) + 33 * (33/11) = 22 * 2 + 33 * 3 = 44 + 99 = 143 assert_eq!( _calculate_ex_units_ceil_cost(22, 33, (12, 6), (33, 11)), - to_bignum(143), + BigNum(143), ); // 10 * (5/7) + 20 * (9/13) = 50/7 + 180/13 = 650/91 + 1260/91 = 1910/91 = ceil(20.98) = 21 assert_eq!( _calculate_ex_units_ceil_cost(10, 20, (5, 7), (9, 13)), - to_bignum(21), + BigNum(21), ); // 22 * (7/5) + 33 * (13/9) = 154/5 + 429/9 = 1386/45 + 2145/45 = 3531/45 = ceil(78.46) = 79 assert_eq!( _calculate_ex_units_ceil_cost(22, 33, (7, 5), (13, 9)), - to_bignum(79), + BigNum(79), ); } } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index aa36221e..10f6241f 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -64,6 +64,8 @@ mod utils; pub use utils::*; pub(crate) mod fakes; mod serialization; +mod rational; + pub use serialization::*; use crate::traits::NoneOrEmpty; @@ -116,7 +118,6 @@ impl UnitInterval { } type SubCoin = UnitInterval; -type Rational = UnitInterval; type Epoch = u32; type Slot32 = u32; type SlotBigNum = BigNum; @@ -206,6 +207,10 @@ impl TransactionInputs { self.0.push(elem.clone()); } + pub(crate) fn contains(&self, elem: &TransactionInput) -> bool { + self.0.contains(elem) + } + pub fn to_option(&self) -> Option { if self.len() > 0 { Some(self.clone()) @@ -269,7 +274,7 @@ impl DataCost { match &self.0 { DataCostEnum::CoinsPerByte(coins_per_byte) => coins_per_byte.clone(), DataCostEnum::CoinsPerWord(coins_per_word) => { - let bytes_in_word = to_bignum(8); + let bytes_in_word = BigNum(8); coins_per_word.div_floor(&bytes_in_word) } } @@ -1889,7 +1894,7 @@ impl MultiAsset { match lhs_ma.0.get_mut(policy) { Some(assets) => match assets.0.get_mut(asset_name) { Some(current) => match current.checked_sub(&amount) { - Ok(new) => match new.compare(&to_bignum(0)) { + Ok(new) => match new.compare(&BigNum(0)) { 0 => { assets.0.remove(asset_name); match assets.0.len() { @@ -1936,7 +1941,7 @@ impl PartialOrd for MultiAsset { fn amount_or_zero(ma: &MultiAsset, pid: &PolicyID, aname: &AssetName) -> Coin { ma.get(&pid) .and_then(|assets| assets.get(aname)) - .unwrap_or(to_bignum(0u64)) // assume 0 if asset not present + .unwrap_or(BigNum(0u64)) // assume 0 if asset not present } // idea: if (a-b) > 0 for some asset, then a > b for at least some asset @@ -1945,7 +1950,7 @@ impl PartialOrd for MultiAsset { for (aname, amount) in assets.0.iter() { match amount .clamped_sub(&amount_or_zero(&rhs, pid, aname)) - .cmp(&to_bignum(0)) + .cmp(&BigNum::zero()) { std::cmp::Ordering::Equal => (), _ => return false, diff --git a/rust/src/protocol_types/address.rs b/rust/src/protocol_types/address.rs index 3b41d8c7..ea05d30e 100644 --- a/rust/src/protocol_types/address.rs +++ b/rust/src/protocol_types/address.rs @@ -334,9 +334,9 @@ impl Address { 0b0100_0000 | ((ptr.payment.kind() as u8) << 4) | (ptr.network & 0xF); buf.push(header); buf.extend(ptr.payment.to_raw_bytes()); - buf.extend(variable_nat_encode(from_bignum(&ptr.stake.slot))); - buf.extend(variable_nat_encode(from_bignum(&ptr.stake.tx_index))); - buf.extend(variable_nat_encode(from_bignum(&ptr.stake.cert_index))); + buf.extend(variable_nat_encode(ptr.stake.slot.into())); + buf.extend(variable_nat_encode(ptr.stake.tx_index.into())); + buf.extend(variable_nat_encode(ptr.stake.cert_index.into())); } AddrType::Enterprise(enterprise) => { let header: u8 = 0b0110_0000 @@ -513,9 +513,9 @@ impl Address { offset += cert_bytes; Ok(( Pointer::new_pointer( - &to_bignum(slot), - &to_bignum(tx_index), - &to_bignum(cert_index), + &slot.into(), + &tx_index.into(), + &cert_index.into(), ), offset, )) diff --git a/rust/src/protocol_types/metadata.rs b/rust/src/protocol_types/metadata.rs index b1b89342..7ee1d429 100644 --- a/rust/src/protocol_types/metadata.rs +++ b/rust/src/protocol_types/metadata.rs @@ -519,12 +519,10 @@ pub fn encode_json_value_to_metadatum( use serde_json::Value; fn encode_number(x: serde_json::Number) -> Result { if let Some(x) = x.as_u64() { - Ok(TransactionMetadatum::new_int(&Int::new(&utils::to_bignum( - x, - )))) + Ok(TransactionMetadatum::new_int(&Int::new(&x.into()))) } else if let Some(x) = x.as_i64() { Ok(TransactionMetadatum::new_int(&Int::new_negative( - &utils::to_bignum(-x as u64), + &(-x as u64).into(), ))) } else { Err(JsError::from_str("floats not allowed in metadata")) diff --git a/rust/src/protocol_types/mod.rs b/rust/src/protocol_types/mod.rs index 02b26ef9..39dc77ab 100644 --- a/rust/src/protocol_types/mod.rs +++ b/rust/src/protocol_types/mod.rs @@ -45,3 +45,6 @@ pub use native_script::*; mod native_scripts; pub use native_scripts::*; + +mod numeric; +pub use numeric::*; diff --git a/rust/src/protocol_types/numeric/big_int.rs b/rust/src/protocol_types/numeric/big_int.rs new file mode 100644 index 00000000..7f4e9801 --- /dev/null +++ b/rust/src/protocol_types/numeric/big_int.rs @@ -0,0 +1,140 @@ +use num_bigint::Sign; +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] +pub struct BigInt(pub(crate) num_bigint::BigInt); + +impl_to_from!(BigInt); + +impl serde::Serialize for BigInt { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&self.to_str()) + } +} + +impl<'de> serde::de::Deserialize<'de> for BigInt { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = ::deserialize(deserializer)?; + BigInt::from_str(&s).map_err(|_e| { + serde::de::Error::invalid_value( + serde::de::Unexpected::Str(&s), + &"string rep of a big int", + ) + }) + } +} + +impl JsonSchema for BigInt { + fn schema_name() -> String { + String::from("BigInt") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + String::json_schema(gen) + } + fn is_referenceable() -> bool { + String::is_referenceable() + } +} + +#[wasm_bindgen] +impl BigInt { + pub fn is_zero(&self) -> bool { + self.0.sign() == Sign::NoSign + } + + pub fn as_u64(&self) -> Option { + let (sign, u64_digits) = self.0.to_u64_digits(); + if sign == Sign::Minus { + return None; + } + match u64_digits.len() { + 0 => Some(BigNum::zero()), + 1 => Some((*u64_digits.first().unwrap()).into()), + _ => None, + } + } + + pub fn as_int(&self) -> Option { + let (sign, u64_digits) = self.0.to_u64_digits(); + let u64_digit = match u64_digits.len() { + 0 => Some(BigNum::zero()), + 1 => Some((*u64_digits.first().unwrap()).into()), + _ => None, + }?; + match sign { + num_bigint::Sign::NoSign | num_bigint::Sign::Plus => Some(Int::new(&u64_digit)), + num_bigint::Sign::Minus => Some(Int::new_negative(&u64_digit)), + } + } + + pub fn from_str(text: &str) -> Result { + use std::str::FromStr; + num_bigint::BigInt::from_str(text) + .map_err(|e| JsError::from_str(&format! {"{:?}", e})) + .map(Self) + } + + pub fn to_str(&self) -> String { + self.0.to_string() + } + + pub fn add(&self, other: &BigInt) -> BigInt { + Self(&self.0 + &other.0) + } + + pub fn mul(&self, other: &BigInt) -> BigInt { + Self(&self.0 * &other.0) + } + + pub fn one() -> BigInt { + use std::str::FromStr; + Self(num_bigint::BigInt::from_str("1").unwrap()) + } + + pub fn increment(&self) -> BigInt { + self.add(&Self::one()) + } + + pub fn div_ceil(&self, other: &BigInt) -> BigInt { + use num_integer::Integer; + let (res, rem) = self.0.div_rem(&other.0); + let result = Self(res); + if Self(rem).is_zero() { + result + } else { + result.increment() + } + } +} + +impl std::convert::From for BigInt + where + T: std::convert::Into, +{ + fn from(x: T) -> Self { + Self(x.into()) + } +} + +impl From for BigInt { + fn from(x: BigNum) -> Self { + Self(x.0.into()) + } +} + +impl From<&BigNum> for BigInt { + fn from(x: &BigNum) -> Self { + Self(x.0.into()) + } +} + +pub fn to_bigint(val: u64) -> BigInt { + BigInt::from_str(&val.to_string()).unwrap() +} \ No newline at end of file diff --git a/rust/src/protocol_types/numeric/big_num.rs b/rust/src/protocol_types/numeric/big_num.rs new file mode 100644 index 00000000..7a39df12 --- /dev/null +++ b/rust/src/protocol_types/numeric/big_num.rs @@ -0,0 +1,202 @@ +use std::convert::TryFrom; +use std::ops::Div; +use crate::*; + +// Generic u64 wrapper for platforms that don't support u64 or BigInt/etc +// This is an unsigned type - no negative numbers. +// Can be converted to/from plain rust +#[wasm_bindgen] +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Default)] +pub struct BigNum(pub(crate) u64); + +// Specifies an amount of ADA in terms of lovelace +pub type Coin = BigNum; + +impl_to_from!(BigNum); + +impl std::fmt::Display for BigNum { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +#[wasm_bindgen] +impl BigNum { + // Create a BigNum from a standard rust string representation + pub fn from_str(string: &str) -> Result { + string + .parse::() + .map_err(|e| JsError::from_str(&format! {"{:?}", e})) + .map(BigNum) + } + + // String representation of the BigNum value for use from environments that don't support BigInt + pub fn to_str(&self) -> String { + format!("{}", self.0) + } + + pub fn zero() -> Self { + Self(0) + } + + pub fn one() -> Self { + Self(1) + } + + pub fn is_zero(&self) -> bool { + self.0 == 0 + } + + pub fn div_floor(&self, other: &BigNum) -> BigNum { + // same as (a / b) + let res = self.0.div(&other.0); + Self(res) + } + + pub fn checked_mul(&self, other: &BigNum) -> Result { + match self.0.checked_mul(other.0) { + Some(value) => Ok(BigNum(value)), + None => Err(JsError::from_str("overflow")), + } + } + + pub fn checked_add(&self, other: &BigNum) -> Result { + match self.0.checked_add(other.0) { + Some(value) => Ok(BigNum(value)), + None => Err(JsError::from_str("overflow")), + } + } + + pub fn checked_sub(&self, other: &BigNum) -> Result { + match self.0.checked_sub(other.0) { + Some(value) => Ok(BigNum(value)), + None => Err(JsError::from_str("underflow")), + } + } + + /// returns 0 if it would otherwise underflow + pub fn clamped_sub(&self, other: &BigNum) -> BigNum { + match self.0.checked_sub(other.0) { + Some(value) => BigNum(value), + None => BigNum(0), + } + } + + pub fn compare(&self, rhs_value: &BigNum) -> i8 { + match self.cmp(&rhs_value) { + std::cmp::Ordering::Equal => 0, + std::cmp::Ordering::Less => -1, + std::cmp::Ordering::Greater => 1, + } + } + + pub fn less_than(&self, rhs_value: &BigNum) -> bool { + self.compare(rhs_value) < 0 + } + + pub fn max_value() -> BigNum { + BigNum(u64::max_value()) + } + + pub fn max(a: &BigNum, b: &BigNum) -> BigNum { + if a.less_than(b) { + b.clone() + } else { + a.clone() + } + } +} + +impl TryFrom for u32 { + type Error = JsError; + + fn try_from(value: BigNum) -> Result { + if value.0 > u32::MAX.into() { + Err(JsError::from_str(&format!( + "Value {} is bigger than max u32 {}", + value.0, + u32::MAX + ))) + } else { + Ok(value.0 as u32) + } + } +} + +impl From for u64 { + fn from(value: BigNum) -> Self { + value.0 + } +} + +impl From<&BigNum> for u64 { + fn from(value: &BigNum) -> Self { + value.0 + } +} + +impl From for usize { + fn from(value: BigNum) -> Self { + value.0 as usize + } +} + +impl From for BigNum { + fn from(value: u64) -> Self { + return BigNum(value); + } +} + +impl From for BigNum { + fn from(value: usize) -> Self { + return BigNum(value as u64); + } +} + +impl From for BigNum { + fn from(value: u32) -> Self { + return BigNum(value.into()); + } +} + +impl From for BigNum { + fn from(value: u8) -> Self { + return BigNum(value.into()); + } +} + +impl serde::Serialize for BigNum { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&self.to_str()) + } +} + +impl<'de> serde::de::Deserialize<'de> for BigNum { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = ::deserialize(deserializer)?; + Self::from_str(&s).map_err(|_e| { + serde::de::Error::invalid_value( + serde::de::Unexpected::Str(&s), + &"string rep of a number", + ) + }) + } +} + +impl JsonSchema for BigNum { + fn schema_name() -> String { + String::from("BigNum") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + String::json_schema(gen) + } + fn is_referenceable() -> bool { + String::is_referenceable() + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/numeric/int.rs b/rust/src/protocol_types/numeric/int.rs new file mode 100644 index 00000000..08e1d54e --- /dev/null +++ b/rust/src/protocol_types/numeric/int.rs @@ -0,0 +1,137 @@ +use crate::*; + +// CBOR has int = uint / nint +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct Int(pub(crate) i128); + +impl_to_from!(Int); + +#[wasm_bindgen] +impl Int { + pub fn new(x: &BigNum) -> Self { + Self(x.0 as i128) + } + + pub fn new_negative(x: &BigNum) -> Self { + Self(-(x.0 as i128)) + } + + pub fn new_i32(x: i32) -> Self { + Self(x as i128) + } + + pub fn is_positive(&self) -> bool { + return self.0 >= 0; + } + + /// BigNum can only contain unsigned u64 values + /// + /// This function will return the BigNum representation + /// only in case the underlying i128 value is positive. + /// + /// Otherwise nothing will be returned (undefined). + pub fn as_positive(&self) -> Option { + if self.is_positive() { + Some((self.0 as u64).into()) + } else { + None + } + } + + /// BigNum can only contain unsigned u64 values + /// + /// This function will return the *absolute* BigNum representation + /// only in case the underlying i128 value is negative. + /// + /// Otherwise nothing will be returned (undefined). + pub fn as_negative(&self) -> Option { + if !self.is_positive() { + Some(((-self.0) as u64).into()) + } else { + None + } + } + + /// !!! DEPRECATED !!! + /// Returns an i32 value in case the underlying original i128 value is within the limits. + /// Otherwise will just return an empty value (undefined). + #[deprecated( + since = "10.0.0", + note = "Unsafe ignoring of possible boundary error and it's not clear from the function name. Use `as_i32_or_nothing`, `as_i32_or_fail`, or `to_str`" + )] + pub fn as_i32(&self) -> Option { + self.as_i32_or_nothing() + } + + /// Returns the underlying value converted to i32 if possible (within limits) + /// Otherwise will just return an empty value (undefined). + pub fn as_i32_or_nothing(&self) -> Option { + use std::convert::TryFrom; + i32::try_from(self.0).ok() + } + + /// Returns the underlying value converted to i32 if possible (within limits) + /// JsError in case of out of boundary overflow + pub fn as_i32_or_fail(&self) -> Result { + use std::convert::TryFrom; + i32::try_from(self.0).map_err(|e| JsError::from_str(&format!("{}", e))) + } + + /// Returns string representation of the underlying i128 value directly. + /// Might contain the minus sign (-) in case of negative value. + pub fn to_str(&self) -> String { + format!("{}", self.0) + } + + // Create an Int from a standard rust string representation + pub fn from_str(string: &str) -> Result { + let x = string + .parse::() + .map_err(|e| JsError::from_str(&format! {"{:?}", e}))?; + if x.abs() > u64::MAX as i128 { + return Err(JsError::from_str(&format!( + "{} out of bounds. Value (without sign) must fit within 4 bytes limit of {}", + x, + u64::MAX + ))); + } + Ok(Self(x)) + } +} + +impl serde::Serialize for Int { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&self.to_str()) + } +} + +impl<'de> serde::de::Deserialize<'de> for Int { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = ::deserialize(deserializer)?; + Self::from_str(&s).map_err(|_e| { + serde::de::Error::invalid_value( + serde::de::Unexpected::Str(&s), + &"string rep of a number", + ) + }) + } +} + +impl JsonSchema for Int { + fn schema_name() -> String { + String::from("Int") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + String::json_schema(gen) + } + fn is_referenceable() -> bool { + String::is_referenceable() + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/numeric/mod.rs b/rust/src/protocol_types/numeric/mod.rs new file mode 100644 index 00000000..f0585957 --- /dev/null +++ b/rust/src/protocol_types/numeric/mod.rs @@ -0,0 +1,8 @@ +mod big_int; +pub use big_int::*; + +mod int; +pub use int::*; + +mod big_num; +pub use big_num::*; \ No newline at end of file diff --git a/rust/src/protocol_types/plutus/plutus_data.rs b/rust/src/protocol_types/plutus/plutus_data.rs index d3c8fee3..85da2b2b 100644 --- a/rust/src/protocol_types/plutus/plutus_data.rs +++ b/rust/src/protocol_types/plutus/plutus_data.rs @@ -662,7 +662,7 @@ pub fn encode_json_value_to_plutus_datum( } let variant: BigNum = obj .get("constructor") - .and_then(|v| Some(to_bignum(v.as_u64()?))) + .and_then(|v| Some(v.as_u64()?.into())) .ok_or_else(|| JsError::from_str("tagged constructors must contain an unsigned integer called \"constructor\""))?; let fields_json = obj.get("fields") @@ -711,7 +711,7 @@ pub fn decode_plutus_datum_to_json_value( let mut obj = serde_json::map::Map::with_capacity(2); obj.insert( String::from("constructor"), - Value::from(from_bignum(&constr.alternative)) + Value::from(constr.alternative.0) ); let mut fields = Vec::new(); for field in constr.data.elems.iter() { diff --git a/rust/src/protocol_types/protocol_param_update.rs b/rust/src/protocol_types/protocol_param_update.rs index c7eb0f9f..77921281 100644 --- a/rust/src/protocol_types/protocol_param_update.rs +++ b/rust/src/protocol_types/protocol_param_update.rs @@ -226,7 +226,7 @@ pub struct ProtocolParamUpdate { pub(crate) max_epoch: Option, // desired number of stake pools pub(crate) n_opt: Option, - pub(crate) pool_pledge_influence: Option, + pub(crate) pool_pledge_influence: Option, pub(crate) expansion_rate: Option, pub(crate) treasury_growth_rate: Option, // decentralization constant @@ -250,7 +250,7 @@ pub struct ProtocolParamUpdate { pub(crate) governance_action_deposit: Option, pub(crate) drep_deposit: Option, pub(crate) drep_inactivity_period: Option, - pub(crate) ref_script_coins_per_byte: Option, + pub(crate) ref_script_coins_per_byte: Option, } impl_to_from!(ProtocolParamUpdate); @@ -329,11 +329,11 @@ impl ProtocolParamUpdate { self.n_opt.clone() } - pub fn set_pool_pledge_influence(&mut self, pool_pledge_influence: &Rational) { + pub fn set_pool_pledge_influence(&mut self, pool_pledge_influence: &UnitInterval) { self.pool_pledge_influence = Some(pool_pledge_influence.clone()) } - pub fn pool_pledge_influence(&self) -> Option { + pub fn pool_pledge_influence(&self) -> Option { self.pool_pledge_influence.clone() } @@ -523,11 +523,11 @@ impl ProtocolParamUpdate { self.drep_inactivity_period.clone() } - pub fn set_ref_script_coins_per_byte(&mut self, ref_script_coins_per_byte: &Coin) { + pub fn set_ref_script_coins_per_byte(&mut self, ref_script_coins_per_byte: &UnitInterval) { self.ref_script_coins_per_byte = Some(ref_script_coins_per_byte.clone()); } - pub fn ref_script_coins_per_byte(&self) -> Option { + pub fn ref_script_coins_per_byte(&self) -> Option { self.ref_script_coins_per_byte.clone() } diff --git a/rust/src/protocol_types/transaction_body.rs b/rust/src/protocol_types/transaction_body.rs index 08a8ecc4..b3a93d98 100644 --- a/rust/src/protocol_types/transaction_body.rs +++ b/rust/src/protocol_types/transaction_body.rs @@ -250,7 +250,7 @@ impl TransactionBody { ) -> Self { let mut tx = Self::new_tx_body(inputs, outputs, fee); if let Some(slot32) = ttl { - tx.set_ttl(&to_bignum(slot32 as u64)); + tx.set_ttl(&(slot32 as u64).into()); } tx } diff --git a/rust/src/protocol_types/tx_inputs.rs b/rust/src/protocol_types/tx_inputs.rs index 6b480572..f48824e8 100644 --- a/rust/src/protocol_types/tx_inputs.rs +++ b/rust/src/protocol_types/tx_inputs.rs @@ -1,3 +1,4 @@ +use std::fmt::Formatter; use crate::*; #[wasm_bindgen] @@ -37,3 +38,9 @@ impl TransactionInput { } } } + +impl Display for TransactionInput { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "{}#{}", self.transaction_id, self.index) + } +} diff --git a/rust/src/rational.rs b/rust/src/rational.rs new file mode 100644 index 00000000..46e3f118 --- /dev/null +++ b/rust/src/rational.rs @@ -0,0 +1,99 @@ +use std::convert::TryFrom; +use crate::{BigInt, BigNum, JsError, UnitInterval}; + +#[derive(Clone, Debug)] +pub(crate) struct Rational { + numerator: BigInt, + denominator: BigInt, +} + +impl From for Rational { + fn from(sc: UnitInterval) -> Self { + Rational::new(BigInt::from(sc.numerator), BigInt::from(sc.denominator)) + } +} + +impl From<&UnitInterval> for Rational { + fn from(sc: &UnitInterval) -> Self { + Rational::new(BigInt::from(sc.numerator), BigInt::from(sc.denominator)) + } +} + +impl Rational { + pub(crate) fn new(n: BigInt, d: BigInt) -> Self { + Rational { + numerator: n, + denominator: d, + } + } + + pub(crate) fn numerator(&self) -> &BigInt { + &self.numerator + } + + pub(crate) fn denominator(&self) -> &BigInt { + &self.denominator + } + + pub(crate) fn mul_bignum(&self, x: &BigNum) -> Result { + let m: BigInt = x.into(); + Ok(Rational::new(self.numerator.mul(&m), self.denominator.clone())) + } + + pub(crate) fn mul_usize(&self, x: usize) -> Rational { + Rational::new(self.numerator.mul(&BigInt::from(x)), self.denominator.clone()) + } + + pub(crate) fn add(&self, x: &Rational) -> Rational { + let a_num = &self.numerator; + let a_denum = &self.denominator; + let b_num = &x.numerator; + let b_denum = &x.denominator; + + if a_num.is_zero() { + return x.clone(); + } + if b_num.is_zero() { + return self.clone(); + } + let a_num_fixed = &a_num.mul(b_denum); + let b_num_fixed = &b_num.mul(a_denum); + let a_b_num_sum = a_num_fixed.add(b_num_fixed); + let common_denum = a_denum.mul(b_denum); + Rational::new(a_b_num_sum, common_denum) + } + + pub(crate) fn to_bignum_ceil(&self) -> Result { + let num = self.numerator(); + let denum = self.denominator(); + if denum.is_zero() { + return Err(JsError::from_str("Division by zero")); + } + let value = num.div_ceil(denum); + match value.as_u64() { + Some(coin) => Ok(coin), + _ => Err(JsError::from_str(&format!( + "Failed to calculate ceil from ratio {}/{}", + num.to_str(), + denum.to_str(), + ))), + } + } + + pub(crate) fn to_bignum_floor(&self) -> Result { + let num = self.numerator(); + let denum = self.denominator(); + if denum.is_zero() { + return Err(JsError::from_str("Division by zero")); + } + let value = num.div_ceil(denum); + match value.as_u64() { + Some(coin) => Ok(coin), + _ => Err(JsError::from_str(&format!( + "Failed to calculate floor from ratio {}/{}", + num.to_str(), + denum.to_str(), + ))), + } + } +} \ No newline at end of file diff --git a/rust/src/serialization/mod.rs b/rust/src/serialization/mod.rs index a2b1d642..cfcbf939 100644 --- a/rust/src/serialization/mod.rs +++ b/rust/src/serialization/mod.rs @@ -23,4 +23,5 @@ mod credential; mod crypto; mod plutus; mod native_script; -mod native_scripts; \ No newline at end of file +mod native_scripts; +mod numeric; \ No newline at end of file diff --git a/rust/src/serialization/numeric/big_int.rs b/rust/src/serialization/numeric/big_int.rs new file mode 100644 index 00000000..6c62d4e5 --- /dev/null +++ b/rust/src/serialization/numeric/big_int.rs @@ -0,0 +1,103 @@ +use crate::*; +use crate::serialization::utils::read_nint; + +impl Serialize for BigInt { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + let (sign, u64_digits) = self.0.to_u64_digits(); + match u64_digits.len() { + 0 => serializer.write_unsigned_integer(0), + // we use the uint/nint encodings to use a minimum of space + 1 => match sign { + // uint + num_bigint::Sign::Plus | num_bigint::Sign::NoSign => { + serializer.write_unsigned_integer(*u64_digits.first().unwrap()) + } + // nint + num_bigint::Sign::Minus => serializer + .write_negative_integer(-(*u64_digits.first().unwrap() as i128) as i64), + }, + _ => { + // Small edge case: nint's minimum is -18446744073709551616 but in this bigint lib + // that takes 2 u64 bytes so we put that as a special case here: + if sign == num_bigint::Sign::Minus && u64_digits == vec![0, 1] { + serializer.write_negative_integer(-18446744073709551616i128 as i64) + } else { + let (sign, bytes) = self.0.to_bytes_be(); + match sign { + // positive bigint + num_bigint::Sign::Plus | num_bigint::Sign::NoSign => { + serializer.write_tag(2u64)?; + write_bounded_bytes(serializer, &bytes) + } + // negative bigint + num_bigint::Sign::Minus => { + serializer.write_tag(3u64)?; + use std::ops::Neg; + // CBOR RFC defines this as the bytes of -n -1 + let adjusted = self + .0 + .clone() + .neg() + .checked_sub(&num_bigint::BigInt::from(1u32)) + .unwrap() + .to_biguint() + .unwrap(); + write_bounded_bytes(serializer, &adjusted.to_bytes_be()) + } + } + } + } + } + } +} + +impl Deserialize for BigInt { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + match raw.cbor_type()? { + // bigint + CBORType::Tag => { + let tag = raw.tag()?; + let bytes = read_bounded_bytes(raw)?; + match tag { + // positive bigint + 2 => Ok(Self(num_bigint::BigInt::from_bytes_be( + num_bigint::Sign::Plus, + &bytes, + ))), + // negative bigint + 3 => { + // CBOR RFC defines this as the bytes of -n -1 + let initial = + num_bigint::BigInt::from_bytes_be(num_bigint::Sign::Plus, &bytes); + use std::ops::Neg; + let adjusted = initial + .checked_add(&num_bigint::BigInt::from(1u32)) + .unwrap() + .neg(); + Ok(Self(adjusted)) + } + _ => { + return Err(DeserializeFailure::TagMismatch { + found: tag, + expected: 2, + } + .into()); + } + } + } + // uint + CBORType::UnsignedInteger => { + Ok(Self(num_bigint::BigInt::from(raw.unsigned_integer()?))) + } + // nint + CBORType::NegativeInteger => Ok(Self(num_bigint::BigInt::from(read_nint(raw)?))), + _ => return Err(DeserializeFailure::NoVariantMatched.into()), + } + })() + .map_err(|e| e.annotate("BigInt")) + } +} \ No newline at end of file diff --git a/rust/src/serialization/numeric/big_num.rs b/rust/src/serialization/numeric/big_num.rs new file mode 100644 index 00000000..dd10ffc2 --- /dev/null +++ b/rust/src/serialization/numeric/big_num.rs @@ -0,0 +1,19 @@ +use crate::*; + +impl Serialize for BigNum { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_unsigned_integer(self.0) + } +} + +impl Deserialize for BigNum { + fn deserialize(raw: &mut Deserializer) -> Result { + match raw.unsigned_integer() { + Ok(value) => Ok(Self(value)), + Err(e) => Err(DeserializeError::new("BigNum", DeserializeFailure::CBOR(e))), + } + } +} \ No newline at end of file diff --git a/rust/src/serialization/numeric/int.rs b/rust/src/serialization/numeric/int.rs new file mode 100644 index 00000000..a2d40f18 --- /dev/null +++ b/rust/src/serialization/numeric/int.rs @@ -0,0 +1,28 @@ +use crate::*; +use crate::serialization::utils::read_nint; + +impl cbor_event::se::Serialize for Int { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + if self.0 < 0 { + serializer.write_negative_integer(self.0 as i64) + } else { + serializer.write_unsigned_integer(self.0 as u64) + } + } +} + +impl Deserialize for Int { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + match raw.cbor_type()? { + cbor_event::Type::UnsignedInteger => Ok(Self(raw.unsigned_integer()? as i128)), + cbor_event::Type::NegativeInteger => Ok(Self(read_nint(raw)?)), + _ => Err(DeserializeFailure::NoVariantMatched.into()), + } + })() + .map_err(|e| e.annotate("Int")) + } +} \ No newline at end of file diff --git a/rust/src/serialization/numeric/mod.rs b/rust/src/serialization/numeric/mod.rs new file mode 100644 index 00000000..050422d6 --- /dev/null +++ b/rust/src/serialization/numeric/mod.rs @@ -0,0 +1,3 @@ +mod int; +mod big_int; +mod big_num; \ No newline at end of file diff --git a/rust/src/serialization/plutus/plutus_data.rs b/rust/src/serialization/plutus/plutus_data.rs index 9aa3e294..51e5b5fd 100644 --- a/rust/src/serialization/plutus/plutus_data.rs +++ b/rust/src/serialization/plutus/plutus_data.rs @@ -9,7 +9,7 @@ impl cbor_event::se::Serialize for ConstrPlutusData { serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { if let Some(compact_tag) = - Self::alternative_to_compact_cbor_tag(from_bignum(&self.alternative)) + Self::alternative_to_compact_cbor_tag(self.alternative.into()) { // compact form serializer.write_tag(compact_tag as u64)?; @@ -49,7 +49,7 @@ impl Deserialize for ConstrPlutusData { // concise form tag => { if let Some(alternative) = Self::compact_cbor_tag_to_alternative(tag) { - (to_bignum(alternative), PlutusList::deserialize(raw)?) + (alternative.into(), PlutusList::deserialize(raw)?) } else { return Err(DeserializeFailure::TagMismatch { found: tag, diff --git a/rust/src/serialization/protocol_param_update.rs b/rust/src/serialization/protocol_param_update.rs index 5ed9fce7..42b636e3 100644 --- a/rust/src/serialization/protocol_param_update.rs +++ b/rust/src/serialization/protocol_param_update.rs @@ -538,7 +538,7 @@ impl Deserialize for ProtocolParamUpdate { pool_pledge_influence = Some( (|| -> Result<_, DeserializeError> { read_len.read_elems(1)?; - Ok(Rational::deserialize(raw)?) + Ok(UnitInterval::deserialize(raw)?) })() .map_err(|e| e.annotate("pool_pledge_influence"))?, ); @@ -814,7 +814,7 @@ impl Deserialize for ProtocolParamUpdate { ref_script_coins_per_byte = Some( (|| -> Result<_, DeserializeError> { read_len.read_elems(1)?; - Ok(Coin::deserialize(raw)?) + Ok(UnitInterval::deserialize(raw)?) })() .map_err(|e| e.annotate("ref_script_coins_per_byte"))?, ); diff --git a/rust/src/serialization/utils.rs b/rust/src/serialization/utils.rs index e52c0d60..e67d68b1 100644 --- a/rust/src/serialization/utils.rs +++ b/rust/src/serialization/utils.rs @@ -1,5 +1,25 @@ use crate::*; +/// TODO: this function can be removed in case `cbor_event` library ever gets a fix on their side +/// See https://github.com/Emurgo/cardano-serialization-lib/pull/392 +pub(crate) fn read_nint(raw: &mut Deserializer) -> Result { + let found = raw.cbor_type()?; + if found != cbor_event::Type::NegativeInteger { + return Err(cbor_event::Error::Expected(cbor_event::Type::NegativeInteger, found).into()); + } + let (len, len_sz) = raw.cbor_len()?; + match len { + cbor_event::Len::Indefinite => Err(cbor_event::Error::IndefiniteLenNotSupported( + cbor_event::Type::NegativeInteger, + ) + .into()), + cbor_event::Len::Len(v) => { + raw.advance(1 + len_sz)?; + Ok(-(v as i128) - 1) + } + } +} + pub(super) fn deserialize_and_check_index( raw: &mut Deserializer, desired_index: Option, diff --git a/rust/src/tests/address.rs b/rust/src/tests/address.rs index 536f2dc9..7173600a 100644 --- a/rust/src/tests/address.rs +++ b/rust/src/tests/address.rs @@ -34,7 +34,7 @@ fn ptr_serialize_consistency() { let ptr = PointerAddress::new( 25, &Credential::from_keyhash(&Ed25519KeyHash::from([23; Ed25519KeyHash::BYTE_COUNT])), - &Pointer::new_pointer(&to_bignum(2354556573), &to_bignum(127), &to_bignum(0)), + &Pointer::new_pointer(&BigNum(2354556573), &BigNum(127), &BigNum(0)), ); let addr = ptr.to_address(); let addr2 = Address::from_bytes(addr.to_bytes()).unwrap(); @@ -192,7 +192,7 @@ fn bip32_12_pointer() { let addr_net_0 = PointerAddress::new( NetworkInfo::testnet_preprod().network_id(), &spend_cred, - &Pointer::new_pointer(&to_bignum(1), &to_bignum(2), &to_bignum(3)), + &Pointer::new_pointer(&BigNum(1), &BigNum(2), &BigNum(3)), ) .to_address(); assert_eq!( @@ -202,7 +202,7 @@ fn bip32_12_pointer() { let addr_net_3 = PointerAddress::new( NetworkInfo::mainnet().network_id(), &spend_cred, - &Pointer::new_pointer(&to_bignum(24157), &to_bignum(177), &to_bignum(42)), + &Pointer::new_pointer(&BigNum(24157), &BigNum(177), &BigNum(42)), ) .to_address(); assert_eq!( @@ -282,7 +282,7 @@ fn bip32_15_pointer() { let addr_net_0 = PointerAddress::new( NetworkInfo::testnet_preprod().network_id(), &spend_cred, - &Pointer::new_pointer(&to_bignum(1), &to_bignum(2), &to_bignum(3)), + &Pointer::new_pointer(&BigNum(1), &BigNum(2), &BigNum(3)), ) .to_address(); assert_eq!( @@ -292,7 +292,7 @@ fn bip32_15_pointer() { let addr_net_3 = PointerAddress::new( NetworkInfo::mainnet().network_id(), &spend_cred, - &Pointer::new_pointer(&to_bignum(24157), &to_bignum(177), &to_bignum(42)), + &Pointer::new_pointer(&BigNum(24157), &BigNum(177), &BigNum(42)), ) .to_address(); assert_eq!( @@ -416,7 +416,7 @@ fn bip32_24_pointer() { let addr_net_0 = PointerAddress::new( NetworkInfo::testnet_preprod().network_id(), &spend_cred, - &Pointer::new_pointer(&to_bignum(1), &to_bignum(2), &to_bignum(3)), + &Pointer::new_pointer(&BigNum(1), &BigNum(2), &BigNum(3)), ) .to_address(); assert_eq!( @@ -426,7 +426,7 @@ fn bip32_24_pointer() { let addr_net_3 = PointerAddress::new( NetworkInfo::mainnet().network_id(), &spend_cred, - &Pointer::new_pointer(&to_bignum(24157), &to_bignum(177), &to_bignum(42)), + &Pointer::new_pointer(&BigNum(24157), &BigNum(177), &BigNum(42)), ) .to_address(); assert_eq!( @@ -536,15 +536,15 @@ fn multisig_from_script() { fn pointer_address_big() { let addr = Address::from_bech32("addr_test1grqe6lg9ay8wkcu5k5e38lne63c80h3nq6xxhqfmhewf645pllllllllllll7lupllllllllllll7lupllllllllllll7lc9wayvj").unwrap(); let ptr = PointerAddress::from_address(&addr).unwrap().stake; - assert_eq!(u64::MAX, from_bignum(&ptr.slot)); - assert_eq!(u64::MAX, from_bignum(&ptr.tx_index)); - assert_eq!(u64::MAX, from_bignum(&ptr.cert_index)); + assert_eq!(u64::MAX, u64::from(ptr.slot)); + assert_eq!(u64::MAX, u64::from(ptr.tx_index)); + assert_eq!(u64::MAX, u64::from(ptr.cert_index)); } #[test] fn point_address_old() { let p1 = Pointer::new(10, 20, 30); - let p2 = Pointer::new_pointer(&to_bignum(10), &to_bignum(20), &to_bignum(30)); + let p2 = Pointer::new_pointer(&BigNum(10), &BigNum(20), &BigNum(30)); assert_eq!(p1, p2); } diff --git a/rust/src/tests/builders/batch_tools.rs b/rust/src/tests/builders/batch_tools.rs index fefd40fa..8f515614 100644 --- a/rust/src/tests/builders/batch_tools.rs +++ b/rust/src/tests/builders/batch_tools.rs @@ -215,17 +215,17 @@ fn check_tx_size_limit(batches: &TransactionBatchList, cfg: &TransactionBuilderC #[test] pub fn test_big_utoxs_batch() { let utxos = generate_big_utoxs_bacth(); - let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); + let linear_fee = LinearFee::new(&BigNum(44), &BigNum(155381)); let cfg = TransactionBuilderConfigBuilder::new() .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) + .pool_deposit(&BigNum(500000000)) + .key_deposit(&BigNum(2000000)) .max_value_size(4000) .max_tx_size(8000) - .coins_per_utxo_byte(&to_bignum(34_482 / 8)) + .coins_per_utxo_byte(&BigNum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + &SubCoin::new(&BigNum(577), &BigNum(10000)), + &SubCoin::new(&BigNum(721), &BigNum(10000000)), )) .build() .unwrap(); @@ -244,17 +244,17 @@ pub fn test_big_utoxs_batch() { #[test] pub fn test_big_utoxs_ada_batch() { let utxos = generate_big_ada_utoxs_bacth(); - let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); + let linear_fee = LinearFee::new(&BigNum(44), &BigNum(155381)); let cfg = TransactionBuilderConfigBuilder::new() .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) + .pool_deposit(&BigNum(500000000)) + .key_deposit(&BigNum(2000000)) .max_value_size(4000) .max_tx_size(8000) - .coins_per_utxo_byte(&to_bignum(34_482 / 8)) + .coins_per_utxo_byte(&BigNum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + &SubCoin::new(&BigNum(577), &BigNum(10000)), + &SubCoin::new(&BigNum(721), &BigNum(10000000)), )) .build() .unwrap(); @@ -287,17 +287,17 @@ pub fn test_one_utxo() { let utxos = TransactionUnspentOutputs(vec![utxo]); - let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); + let linear_fee = LinearFee::new(&BigNum(44), &BigNum(155381)); let cfg = TransactionBuilderConfigBuilder::new() .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) + .pool_deposit(&BigNum(500000000)) + .key_deposit(&BigNum(2000000)) .max_value_size(4000) .max_tx_size(8000) - .coins_per_utxo_byte(&to_bignum(34_482 / 8)) + .coins_per_utxo_byte(&BigNum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + &SubCoin::new(&BigNum(577), &BigNum(10000)), + &SubCoin::new(&BigNum(721), &BigNum(10000000)), )) .build() .unwrap(); @@ -354,17 +354,17 @@ pub fn test_one_utxo_one_asset_per_output() { let utxos = TransactionUnspentOutputs(vec![utxo_1, utxo_2, utxo_3]); - let linear_fee = LinearFee::new(&to_bignum(1), &to_bignum(0)); + let linear_fee = LinearFee::new(&BigNum(1), &BigNum(0)); let cfg = TransactionBuilderConfigBuilder::new() .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) + .pool_deposit(&BigNum(500000000)) + .key_deposit(&BigNum(2000000)) .max_value_size(80) .max_tx_size(8000) - .coins_per_utxo_byte(&to_bignum(34_482 / 8)) + .coins_per_utxo_byte(&BigNum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + &SubCoin::new(&BigNum(577), &BigNum(10000)), + &SubCoin::new(&BigNum(721), &BigNum(10000000)), )) .build() .unwrap(); @@ -433,17 +433,17 @@ pub fn test_one_utxo_one_asset_per_tx() { let utxos = TransactionUnspentOutputs(vec![utxo_1, utxo_2, utxo_3]); - let linear_fee = LinearFee::new(&to_bignum(1), &to_bignum(0)); + let linear_fee = LinearFee::new(&BigNum(1), &BigNum(0)); let cfg = TransactionBuilderConfigBuilder::new() .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) + .pool_deposit(&BigNum(500000000)) + .key_deposit(&BigNum(2000000)) .max_value_size(80) .max_tx_size(300) - .coins_per_utxo_byte(&to_bignum(34_482 / 8)) + .coins_per_utxo_byte(&BigNum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + &SubCoin::new(&BigNum(577), &BigNum(10000)), + &SubCoin::new(&BigNum(721), &BigNum(10000000)), )) .build() .unwrap(); @@ -489,17 +489,17 @@ pub fn test_only_ada_utxo() { let utxos = TransactionUnspentOutputs(vec![utxo]); - let linear_fee = LinearFee::new(&to_bignum(1), &to_bignum(0)); + let linear_fee = LinearFee::new(&BigNum(1), &BigNum(0)); let cfg = TransactionBuilderConfigBuilder::new() .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) + .pool_deposit(&BigNum(500000000)) + .key_deposit(&BigNum(2000000)) .max_value_size(4000) .max_tx_size(8000) - .coins_per_utxo_byte(&to_bignum(34_482 / 8)) + .coins_per_utxo_byte(&BigNum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + &SubCoin::new(&BigNum(577), &BigNum(10000)), + &SubCoin::new(&BigNum(721), &BigNum(10000000)), )) .build() .unwrap(); @@ -522,17 +522,17 @@ pub fn test_not_enough_ada() { let utxos = TransactionUnspentOutputs(vec![utxo]); - let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); + let linear_fee = LinearFee::new(&BigNum(44), &BigNum(155381)); let cfg = TransactionBuilderConfigBuilder::new() .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) + .pool_deposit(&BigNum(500000000)) + .key_deposit(&BigNum(2000000)) .max_value_size(4000) .max_tx_size(8000) - .coins_per_utxo_byte(&to_bignum(34_482 / 8)) + .coins_per_utxo_byte(&BigNum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + &SubCoin::new(&BigNum(577), &BigNum(10000)), + &SubCoin::new(&BigNum(721), &BigNum(10000000)), )) .build() .unwrap(); @@ -558,17 +558,17 @@ pub fn test_value_limit_error() { let utxos = TransactionUnspentOutputs(vec![utxo]); - let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); + let linear_fee = LinearFee::new(&BigNum(44), &BigNum(155381)); let cfg = TransactionBuilderConfigBuilder::new() .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) + .pool_deposit(&BigNum(500000000)) + .key_deposit(&BigNum(2000000)) .max_value_size(10) .max_tx_size(8000000) - .coins_per_utxo_byte(&to_bignum(34_482 / 8)) + .coins_per_utxo_byte(&BigNum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + &SubCoin::new(&BigNum(577), &BigNum(10000)), + &SubCoin::new(&BigNum(721), &BigNum(10000000)), )) .build() .unwrap(); @@ -594,17 +594,17 @@ pub fn test_tx_limit_error() { let utxos = TransactionUnspentOutputs(vec![utxo]); - let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); + let linear_fee = LinearFee::new(&BigNum(44), &BigNum(155381)); let cfg = TransactionBuilderConfigBuilder::new() .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) + .pool_deposit(&BigNum(500000000)) + .key_deposit(&BigNum(2000000)) .max_value_size(100) .max_tx_size(2000) - .coins_per_utxo_byte(&to_bignum(34_482 / 8)) + .coins_per_utxo_byte(&BigNum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + &SubCoin::new(&BigNum(577), &BigNum(10000)), + &SubCoin::new(&BigNum(721), &BigNum(10000000)), )) .build() .unwrap(); @@ -617,17 +617,17 @@ pub fn test_tx_limit_error() { pub fn test_no_utxos() { let utxos = TransactionUnspentOutputs(vec![]); - let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); + let linear_fee = LinearFee::new(&BigNum(44), &BigNum(155381)); let cfg = TransactionBuilderConfigBuilder::new() .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) + .pool_deposit(&BigNum(500000000)) + .key_deposit(&BigNum(2000000)) .max_value_size(10) .max_tx_size(8000000) - .coins_per_utxo_byte(&to_bignum(34_482 / 8)) + .coins_per_utxo_byte(&BigNum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + &SubCoin::new(&BigNum(577), &BigNum(10000)), + &SubCoin::new(&BigNum(721), &BigNum(10000000)), )) .build() .unwrap(); @@ -646,17 +646,17 @@ pub fn test_script_input_error() { let utxo = generate_utxo(&address, 1, 0, 0, 0, 0, 20, Coin::zero(), Coin::from(1u64)); let utxos = TransactionUnspentOutputs(vec![utxo]); - let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); + let linear_fee = LinearFee::new(&BigNum(44), &BigNum(155381)); let cfg = TransactionBuilderConfigBuilder::new() .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) + .pool_deposit(&BigNum(500000000)) + .key_deposit(&BigNum(2000000)) .max_value_size(10) .max_tx_size(8000000) - .coins_per_utxo_byte(&to_bignum(34_482 / 8)) + .coins_per_utxo_byte(&BigNum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + &SubCoin::new(&BigNum(577), &BigNum(10000)), + &SubCoin::new(&BigNum(721), &BigNum(10000000)), )) .build() .unwrap(); @@ -706,17 +706,17 @@ pub fn test_two_asset_utxo_one_ada_utxo() { let utxos = TransactionUnspentOutputs(vec![asset_utxo_1, asset_utxo_2, ada_utxo]); - let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381)); + let linear_fee = LinearFee::new(&BigNum(44), &BigNum(155381)); let cfg = TransactionBuilderConfigBuilder::new() .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(500000000)) - .key_deposit(&to_bignum(2000000)) + .pool_deposit(&BigNum(500000000)) + .key_deposit(&BigNum(2000000)) .max_value_size(4000) .max_tx_size(8000) - .coins_per_utxo_byte(&to_bignum(34_482 / 8)) + .coins_per_utxo_byte(&BigNum(34_482 / 8)) .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + &SubCoin::new(&BigNum(577), &BigNum(10000)), + &SubCoin::new(&BigNum(721), &BigNum(10000000)), )) .build() .unwrap(); diff --git a/rust/src/tests/builders/mod.rs b/rust/src/tests/builders/mod.rs index ab508154..76eaacb8 100644 --- a/rust/src/tests/builders/mod.rs +++ b/rust/src/tests/builders/mod.rs @@ -2,4 +2,4 @@ mod batch_tools; mod tx_builder; mod voting_builder; mod voting_proposal_builder; -mod certificates_builder; +mod certificates_builder; \ No newline at end of file diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index 5b94664f..26cf3195 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -1,8 +1,13 @@ -use crate::fakes::{fake_base_address, fake_bytes_32, fake_data_hash, fake_key_hash, fake_policy_id, fake_script_hash, fake_tx_hash, fake_tx_input, fake_tx_input2, fake_value, fake_value2, fake_vkey_witness}; +use crate::fakes::{ + fake_base_address, fake_bytes_32, fake_data_hash, fake_key_hash, fake_policy_id, + fake_script_hash, fake_tx_hash, fake_tx_input, fake_tx_input2, fake_value, fake_value2, + fake_vkey_witness, +}; use crate::tests::helpers::harden; -use crate::tests::mock_objects::{byron_address, create_change_address, create_default_tx_builder, create_linear_fee, create_reallistic_tx_builder, create_rich_tx_builder, create_tx_builder, create_tx_builder_with_amount, create_tx_builder_with_fee, create_tx_builder_with_fee_and_pure_change, create_tx_builder_with_fee_and_val_size, create_tx_builder_with_key_deposit, root_key_15}; +use crate::tests::mock_objects::{byron_address, create_anchor, create_change_address, create_default_tx_builder, create_linear_fee, create_reallistic_tx_builder, create_redeemer, create_redeemer_zero_cost, create_rich_tx_builder, create_tx_builder, create_tx_builder_with_amount, create_tx_builder_with_fee, create_tx_builder_with_fee_and_pure_change, create_tx_builder_with_fee_and_val_size, create_tx_builder_with_key_deposit, root_key_15}; use crate::*; +use crate::builders::fakes::fake_private_key; use fees::*; use std::collections::{BTreeMap, HashMap, HashSet}; @@ -61,7 +66,7 @@ fn build_tx_with_change() { tx_builder.add_key_input( &spend.to_raw_key().hash(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); tx_builder .add_output( @@ -69,7 +74,7 @@ fn build_tx_with_change() { .with_address(&addr_net_0) .next() .unwrap() - .with_coin(&to_bignum(222)) + .with_coin(&BigNum(222)) .build() .unwrap(), ) @@ -132,7 +137,7 @@ fn build_tx_with_change_with_datum() { tx_builder.add_key_input( &spend.to_raw_key().hash(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); tx_builder .add_output( @@ -140,7 +145,7 @@ fn build_tx_with_change_with_datum() { .with_address(&addr_net_0) .next() .unwrap() - .with_coin(&to_bignum(222)) + .with_coin(&BigNum(222)) .build() .unwrap(), ) @@ -213,7 +218,7 @@ fn build_tx_without_change() { tx_builder.add_key_input( &spend.to_raw_key().hash(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); tx_builder .add_output( @@ -221,7 +226,7 @@ fn build_tx_without_change() { .with_address(&addr_net_0) .next() .unwrap() - .with_coin(&to_bignum(880_000)) + .with_coin(&BigNum(880_000)) .build() .unwrap(), ) @@ -282,7 +287,7 @@ fn build_tx_with_certs() { tx_builder.add_key_input( &spend.to_raw_key().hash(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(5_000_000)), + &Value::new(&BigNum(5_000_000)), ); tx_builder.set_ttl(1000); @@ -353,7 +358,7 @@ fn build_tx_exact_amount() { tx_builder.add_key_input( &&spend.to_raw_key().hash(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(222)), + &Value::new(&BigNum(222)), ); let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); @@ -369,7 +374,7 @@ fn build_tx_exact_amount() { .with_address(&addr_net_0) .next() .unwrap() - .with_coin(&to_bignum(222)) + .with_coin(&BigNum(222)) .build() .unwrap(), ) @@ -417,7 +422,7 @@ fn build_tx_exact_change() { tx_builder.add_key_input( &&spend.to_raw_key().hash(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(700)), + &Value::new(&BigNum(700)), ); let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); @@ -433,7 +438,7 @@ fn build_tx_exact_change() { .with_address(&addr_net_0) .next() .unwrap() - .with_coin(&to_bignum(222)) + .with_coin(&BigNum(222)) .build() .unwrap(), ) @@ -483,7 +488,7 @@ fn build_tx_insufficient_deposit() { tx_builder.add_key_input( &&spend.to_raw_key().hash(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(5)), + &Value::new(&BigNum(5)), ); let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); @@ -499,7 +504,7 @@ fn build_tx_insufficient_deposit() { .with_address(&addr_net_0) .next() .unwrap() - .with_coin(&to_bignum(5)) + .with_coin(&BigNum(5)) .build() .unwrap(), ) @@ -555,7 +560,7 @@ fn build_tx_with_inputs() { ) .to_address(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)) + &Value::new(&BigNum(1_000_000)) ) .unwrap() .to_str(), @@ -565,7 +570,7 @@ fn build_tx_with_inputs() { &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) .to_address(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); } tx_builder.add_regular_input( @@ -576,23 +581,23 @@ fn build_tx_with_inputs() { ) .to_address(), &TransactionInput::new(&genesis_id(), 1), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); tx_builder.add_regular_input( &PointerAddress::new( NetworkInfo::testnet_preprod().network_id(), &spend_cred, - &Pointer::new_pointer(&to_bignum(0), &to_bignum(0), &to_bignum(0)), + &Pointer::new_pointer(&BigNum(0), &BigNum(0), &BigNum(0)), ) .to_address(), &TransactionInput::new(&genesis_id(), 2), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); tx_builder.add_regular_input( &ByronAddress::icarus_from_key(&spend, NetworkInfo::testnet_preprod().protocol_magic()) .to_address(), &TransactionInput::new(&genesis_id(), 3), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); assert_eq!(tx_builder.inputs.len(), 4); @@ -647,11 +652,11 @@ fn build_tx_with_script_ref() { &PointerAddress::new( NetworkInfo::testnet_preprod().network_id(), &spend_cred, - &Pointer::new_pointer(&to_bignum(0), &to_bignum(0), &to_bignum(0)), + &Pointer::new_pointer(&BigNum(0), &BigNum(0), &BigNum(0)), ) .to_address(), &TransactionInput::new(&genesis_id(), 2), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); let addr_net_0 = BaseAddress::new( @@ -661,7 +666,7 @@ fn build_tx_with_script_ref() { ) .to_address(); - let output_amount = Value::new(&to_bignum(500)); + let output_amount = Value::new(&BigNum(500)); tx_builder .add_output( @@ -688,7 +693,7 @@ fn build_tx_with_script_ref() { let final_tx = tx_builder.build().unwrap(); assert_eq!(final_tx.outputs().len(), 2); assert_eq!(final_tx.reference_inputs().unwrap().len(), 4); - assert_eq!(final_tx.outputs().get(1).amount().coin(), to_bignum(999499)); + assert_eq!(final_tx.outputs().get(1).amount().coin(), BigNum(999499)); } #[test] @@ -728,11 +733,11 @@ fn serialization_tx_body_with_script_ref() { &PointerAddress::new( NetworkInfo::testnet_preprod().network_id(), &spend_cred, - &Pointer::new_pointer(&to_bignum(0), &to_bignum(0), &to_bignum(0)), + &Pointer::new_pointer(&BigNum(0), &BigNum(0), &BigNum(0)), ) .to_address(), &TransactionInput::new(&genesis_id(), 2), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); let addr_net_0 = BaseAddress::new( @@ -742,7 +747,7 @@ fn serialization_tx_body_with_script_ref() { ) .to_address(); - let output_amount = Value::new(&to_bignum(500)); + let output_amount = Value::new(&BigNum(500)); tx_builder .add_output( @@ -809,11 +814,11 @@ fn json_serialization_tx_body_with_script_ref() { &PointerAddress::new( NetworkInfo::testnet_preprod().network_id(), &spend_cred, - &Pointer::new_pointer(&to_bignum(0), &to_bignum(0), &to_bignum(0)), + &Pointer::new_pointer(&BigNum(0), &BigNum(0), &BigNum(0)), ) .to_address(), &TransactionInput::new(&genesis_id(), 2), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); let addr_net_0 = BaseAddress::new( @@ -823,7 +828,7 @@ fn json_serialization_tx_body_with_script_ref() { ) .to_address(); - let output_amount = Value::new(&to_bignum(500)); + let output_amount = Value::new(&BigNum(500)); tx_builder .add_output( @@ -888,7 +893,7 @@ fn build_tx_with_mint_all_sent() { &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) .to_address(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(500)), + &Value::new(&BigNum(500)), ); let addr_net_0 = BaseAddress::new( @@ -900,7 +905,7 @@ fn build_tx_with_mint_all_sent() { let (min_script, policy_id) = mint_script_and_policy(0); let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - let amount = to_bignum(1234); + let amount = BigNum(1234); // Adding mint of the asset - which should work as an input tx_builder.add_mint_asset(&min_script, &name, &Int::new(&amount)); @@ -911,7 +916,7 @@ fn build_tx_with_mint_all_sent() { mass.insert(&policy_id, &ass); // One coin and the minted asset goes into the output - let mut output_amount = Value::new(&to_bignum(264)); + let mut output_amount = Value::new(&BigNum(264)); output_amount.set_multiasset(&mass); tx_builder @@ -940,7 +945,7 @@ fn build_tx_with_mint_all_sent() { // Change must be one remaining coin because fee is one constant coin let change = tx_builder.outputs.get(1).amount(); - assert_eq!(change.coin(), to_bignum(235)); + assert_eq!(change.coin(), BigNum(235)); assert!(change.multiasset().is_none()); } @@ -977,7 +982,7 @@ fn build_tx_with_mint_in_change() { &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) .to_address(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(600)), + &Value::new(&BigNum(600)), ); let addr_net_0 = BaseAddress::new( @@ -990,8 +995,8 @@ fn build_tx_with_mint_in_change() { let (min_script, policy_id) = mint_script_and_policy(0); let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - let amount_minted = to_bignum(1000); - let amount_sent = to_bignum(500); + let amount_minted = BigNum(1000); + let amount_sent = BigNum(500); // Adding mint of the asset - which should work as an input tx_builder.add_mint_asset(&min_script, &name, &Int::new(&amount_minted)); @@ -1002,7 +1007,7 @@ fn build_tx_with_mint_in_change() { mass.insert(&policy_id, &ass); // One coin and the minted asset goes into the output - let mut output_amount = Value::new(&to_bignum(300)); + let mut output_amount = Value::new(&BigNum(300)); output_amount.set_multiasset(&mass); tx_builder @@ -1031,7 +1036,7 @@ fn build_tx_with_mint_in_change() { // Change must be one remaining coin because fee is one constant coin let change = tx_builder.outputs.get(1).amount(); - assert_eq!(change.coin(), to_bignum(299)); + assert_eq!(change.coin(), BigNum(299)); assert!(change.multiasset().is_some()); let change_assets = change.multiasset().unwrap(); @@ -1073,9 +1078,9 @@ fn change_with_input_and_mint_not_enough_ada() { let (min_script, policy_id) = mint_script_and_policy(0); let asset_name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - let amount_minted = to_bignum(1000); - let amount_sent = to_bignum(500); - let amount_input_amount = to_bignum(600); + let amount_minted = BigNum(1000); + let amount_sent = BigNum(500); + let amount_input_amount = BigNum(600); let mut asset_input = Assets::new(); asset_input.insert(&asset_name, &amount_input_amount); @@ -1087,14 +1092,14 @@ fn change_with_input_and_mint_not_enough_ada() { &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) .to_address(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(600)), + &Value::new(&BigNum(600)), ); tx_builder.add_regular_input( &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) .to_address(), &TransactionInput::new(&genesis_id(), 1), - &Value::new_with_assets(&to_bignum(1), &mass_input), + &Value::new_with_assets(&BigNum(1), &mass_input), ); let addr_net_0 = BaseAddress::new( @@ -1113,7 +1118,7 @@ fn change_with_input_and_mint_not_enough_ada() { mass.insert(&policy_id, &asset); // One coin and the minted asset goes into the output - let mut output_amount = Value::new(&to_bignum(400)); + let mut output_amount = Value::new(&BigNum(400)); output_amount.set_multiasset(&mass); tx_builder @@ -1171,9 +1176,9 @@ fn change_with_input_and_mint_not_enough_assets() { let (min_script, policy_id) = mint_script_and_policy(0); let asset_name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - let amount_minted = to_bignum(1000); - let amount_sent = to_bignum(100000); - let amount_input_amount = to_bignum(600); + let amount_minted = BigNum(1000); + let amount_sent = BigNum(100000); + let amount_input_amount = BigNum(600); let mut asset_input = Assets::new(); asset_input.insert(&asset_name, &amount_input_amount); @@ -1185,14 +1190,14 @@ fn change_with_input_and_mint_not_enough_assets() { &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) .to_address(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(100000)), + &Value::new(&BigNum(100000)), ); tx_builder.add_regular_input( &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) .to_address(), &TransactionInput::new(&genesis_id(), 1), - &Value::new_with_assets(&to_bignum(1), &mass_input), + &Value::new_with_assets(&BigNum(1), &mass_input), ); let addr_net_0 = BaseAddress::new( @@ -1211,7 +1216,7 @@ fn change_with_input_and_mint_not_enough_assets() { mass.insert(&policy_id, &asset); // One coin and the minted asset goes into the output - let mut output_amount = Value::new(&to_bignum(400)); + let mut output_amount = Value::new(&BigNum(400)); output_amount.set_multiasset(&mass); tx_builder @@ -1276,7 +1281,7 @@ fn build_tx_with_native_assets_change() { let mut multiasset = MultiAsset::new(); multiasset.insert(policy_id, &{ let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(*input)); + assets.insert(&name, &BigNum(*input)); assets }); multiasset @@ -1285,7 +1290,7 @@ fn build_tx_with_native_assets_change() { for (i, (multiasset, ada)) in multiassets .iter() - .zip([100u64, 1000].iter().cloned().map(to_bignum)) + .zip([100u64, 1000].iter().cloned().map(|x| BigNum(x))) .enumerate() { let mut input_amount = Value::new(&ada); @@ -1308,7 +1313,7 @@ fn build_tx_with_native_assets_change() { ) .to_address(); - let mut output_amount = Value::new(&to_bignum(500)); + let mut output_amount = Value::new(&BigNum(500)); output_amount.set_multiasset(&multiassets[2]); tx_builder @@ -1346,14 +1351,14 @@ fn build_tx_with_native_assets_change() { .unwrap() .get(&name) .unwrap(), - to_bignum(ma_input1 + ma_input2 - ma_output1) + BigNum(ma_input1 + ma_input2 - ma_output1) ); - assert_eq!(final_tx.outputs().get(1).amount().coin(), to_bignum(599)); + assert_eq!(final_tx.outputs().get(1).amount().coin(), BigNum(599)); } #[test] fn build_tx_with_native_assets_change_and_purification() { - let coin_per_utxo_byte = to_bignum(1); + let coin_per_utxo_byte = BigNum(1); // Prefer pure change! let mut tx_builder = create_tx_builder_with_fee_and_pure_change(&create_linear_fee(0, 1)); let spend = root_key_15() @@ -1391,7 +1396,7 @@ fn build_tx_with_native_assets_change_and_purification() { let mut multiasset = MultiAsset::new(); multiasset.insert(policy_id, &{ let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(*input)); + assets.insert(&name, &BigNum(*input)); assets }); multiasset @@ -1400,7 +1405,7 @@ fn build_tx_with_native_assets_change_and_purification() { for (i, (multiasset, ada)) in multiassets .iter() - .zip([100u64, 1000].iter().cloned().map(to_bignum)) + .zip([100u64, 1000].iter().cloned().map(|x| BigNum(x))) .enumerate() { let mut input_amount = Value::new(&ada); @@ -1423,7 +1428,7 @@ fn build_tx_with_native_assets_change_and_purification() { ) .to_address(); - let mut output_amount = Value::new(&to_bignum(600)); + let mut output_amount = Value::new(&BigNum(600)); output_amount.set_multiasset(&multiassets[2]); tx_builder @@ -1450,7 +1455,7 @@ fn build_tx_with_native_assets_change_and_purification() { assert_eq!(added_change, true); let final_tx = tx_builder.build().unwrap(); assert_eq!(final_tx.outputs().len(), 3); - assert_eq!(final_tx.outputs().get(0).amount().coin(), to_bignum(600)); + assert_eq!(final_tx.outputs().get(0).amount().coin(), BigNum(600)); assert_eq!( final_tx .outputs() @@ -1462,7 +1467,7 @@ fn build_tx_with_native_assets_change_and_purification() { .unwrap() .get(&name) .unwrap(), - to_bignum(ma_input1 + ma_input2 - ma_output1) + BigNum(ma_input1 + ma_input2 - ma_output1) ); // The first change output that contains all the tokens contain minimum required Coin let min_coin_for_dirty_change = min_ada_for_output( @@ -1474,7 +1479,7 @@ fn build_tx_with_native_assets_change_and_purification() { final_tx.outputs().get(1).amount().coin(), min_coin_for_dirty_change ); - assert_eq!(final_tx.outputs().get(2).amount().coin(), to_bignum(236)); + assert_eq!(final_tx.outputs().get(2).amount().coin(), BigNum(236)); assert_eq!(final_tx.outputs().get(2).amount().multiasset(), None); } @@ -1517,7 +1522,7 @@ fn build_tx_with_native_assets_change_and_no_purification_cuz_not_enough_pure_co let mut multiasset = MultiAsset::new(); multiasset.insert(policy_id, &{ let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(*input)); + assets.insert(&name, &BigNum(*input)); assets }); multiasset @@ -1526,7 +1531,7 @@ fn build_tx_with_native_assets_change_and_no_purification_cuz_not_enough_pure_co for (i, (multiasset, ada)) in multiassets .iter() - .zip([300u64, 900].iter().cloned().map(to_bignum)) + .zip([300u64, 900].iter().cloned().map(|x| BigNum(x))) .enumerate() { let mut input_amount = Value::new(&ada); @@ -1549,7 +1554,7 @@ fn build_tx_with_native_assets_change_and_no_purification_cuz_not_enough_pure_co ) .to_address(); - let mut output_amount = Value::new(&to_bignum(300)); + let mut output_amount = Value::new(&BigNum(300)); output_amount.set_multiasset(&multiassets[2]); tx_builder @@ -1576,7 +1581,7 @@ fn build_tx_with_native_assets_change_and_no_purification_cuz_not_enough_pure_co assert_eq!(added_change, true); let final_tx = tx_builder.build().unwrap(); assert_eq!(final_tx.outputs().len(), 2); - assert_eq!(final_tx.outputs().get(0).amount().coin(), to_bignum(300)); + assert_eq!(final_tx.outputs().get(0).amount().coin(), BigNum(300)); assert_eq!( final_tx .outputs() @@ -1588,11 +1593,11 @@ fn build_tx_with_native_assets_change_and_no_purification_cuz_not_enough_pure_co .unwrap() .get(&name) .unwrap(), - to_bignum(ma_input1 + ma_input2 - ma_output1) + BigNum(ma_input1 + ma_input2 - ma_output1) ); // The single change output contains more Coin then minimal utxo value // But not enough to cover the additional fee for a separate output - assert_eq!(final_tx.outputs().get(1).amount().coin(), to_bignum(499)); + assert_eq!(final_tx.outputs().get(1).amount().coin(), BigNum(499)); } #[test] @@ -1633,11 +1638,11 @@ fn build_tx_leftover_assets() { // add an input that contains an asset not present in the output let policy_id = &PolicyID::from([0u8; 28]); let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); - let mut input_amount = Value::new(&to_bignum(1_000_000)); + let mut input_amount = Value::new(&BigNum(1_000_000)); let mut input_multiasset = MultiAsset::new(); input_multiasset.insert(policy_id, &{ let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(100)); + assets.insert(&name, &BigNum(100)); assets }); input_amount.set_multiasset(&input_multiasset); @@ -1653,7 +1658,7 @@ fn build_tx_leftover_assets() { .with_address(&addr_net_0) .next() .unwrap() - .with_coin(&to_bignum(880_000)) + .with_coin(&BigNum(880_000)) .build() .unwrap(), ) @@ -1699,7 +1704,7 @@ fn build_tx_burn_less_than_min_ada() { .with_address(&output_addr.to_address()) .next() .unwrap() - .with_value(&Value::new(&to_bignum(2_000_000))) + .with_value(&Value::new(&BigNum(2_000_000))) .build() .unwrap(), ) @@ -1710,7 +1715,7 @@ fn build_tx_burn_less_than_min_ada() { .unwrap() .to_address(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(2_400_000)), + &Value::new(&BigNum(2_400_000)), ); tx_builder.set_ttl(1); @@ -1749,13 +1754,13 @@ fn build_tx_burn_empty_assets() { .with_address(&output_addr.to_address()) .next() .unwrap() - .with_value(&Value::new(&to_bignum(2_000_000))) + .with_value(&Value::new(&BigNum(2_000_000))) .build() .unwrap(), ) .unwrap(); - let mut input_value = Value::new(&to_bignum(2_400_000)); + let mut input_value = Value::new(&BigNum(2_400_000)); input_value.set_multiasset(&MultiAsset::new()); tx_builder.add_regular_input( &ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") @@ -1798,11 +1803,11 @@ fn build_tx_no_useless_multiasset() { let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); // add an output that uses up all the token but leaves ADA - let mut input_amount = Value::new(&to_bignum(5_000_000)); + let mut input_amount = Value::new(&BigNum(5_000_000)); let mut input_multiasset = MultiAsset::new(); input_multiasset.insert(policy_id, &{ let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(100)); + assets.insert(&name, &BigNum(100)); assets }); input_amount.set_multiasset(&input_multiasset); @@ -1816,11 +1821,11 @@ fn build_tx_no_useless_multiasset() { ); // add an input that contains an asset & ADA - let mut output_amount = Value::new(&to_bignum(2_000_000)); + let mut output_amount = Value::new(&BigNum(2_000_000)); let mut output_multiasset = MultiAsset::new(); output_multiasset.insert(policy_id, &{ let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(100)); + assets.insert(&name, &BigNum(100)); assets }); output_amount.set_multiasset(&output_multiasset); @@ -1869,7 +1874,7 @@ fn create_multiasset() -> (MultiAsset, [ScriptHash; 3], [AssetName; 3]) { |mut acc, (policy_id, name)| { acc.insert(policy_id, &{ let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(500)); + assets.insert(&name, &BigNum(500)); assets }); acc @@ -1886,7 +1891,7 @@ fn build_tx_add_change_split_nfts() { let (multiasset, policy_ids, names) = create_multiasset(); - let mut input_value = Value::new(&to_bignum(1000)); + let mut input_value = Value::new(&BigNum(1000)); input_value.set_multiasset(&multiasset); tx_builder.add_regular_input( @@ -1901,7 +1906,7 @@ fn build_tx_add_change_split_nfts() { ByronAddress::from_base58("Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b") .unwrap() .to_address(); - let output_amount = Value::new(&to_bignum(208)); + let output_amount = Value::new(&BigNum(208)); tx_builder .add_output( @@ -1954,14 +1959,14 @@ fn build_tx_too_big_output() { .unwrap() .to_address(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(500)), + &Value::new(&BigNum(500)), ); let output_addr = ByronAddress::from_base58("Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b") .unwrap() .to_address(); - let mut output_amount = Value::new(&to_bignum(50)); + let mut output_amount = Value::new(&BigNum(50)); output_amount.set_multiasset(&create_multiasset().0); assert!(tx_builder @@ -2000,14 +2005,14 @@ fn build_tx_add_change_nfts_not_enough_ada() { |mut acc, (policy_id, name)| { acc.insert(policy_id, &{ let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(500)); + assets.insert(&name, &BigNum(500)); assets }); acc }, ); - let mut input_value = Value::new(&to_bignum(58)); + let mut input_value = Value::new(&BigNum(58)); input_value.set_multiasset(&multiasset); tx_builder.add_regular_input( @@ -2022,7 +2027,7 @@ fn build_tx_add_change_nfts_not_enough_ada() { ByronAddress::from_base58("Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b") .unwrap() .to_address(); - let output_amount = Value::new(&to_bignum(208)); + let output_amount = Value::new(&BigNum(208)); tx_builder .add_output( @@ -2075,17 +2080,17 @@ fn tx_builder_cip2_largest_first_increasing_fees() { ) .next() .unwrap() - .with_coin(&to_bignum(9000)) + .with_coin(&BigNum(9000)) .build() .unwrap(), ) .unwrap(); let mut available_inputs = TransactionUnspentOutputs::new(); - available_inputs.add(&make_input(0u8, Value::new(&to_bignum(1200)))); - available_inputs.add(&make_input(1u8, Value::new(&to_bignum(1600)))); - available_inputs.add(&make_input(2u8, Value::new(&to_bignum(6400)))); - available_inputs.add(&make_input(3u8, Value::new(&to_bignum(2400)))); - available_inputs.add(&make_input(4u8, Value::new(&to_bignum(800)))); + available_inputs.add(&make_input(0u8, Value::new(&BigNum(1200)))); + available_inputs.add(&make_input(1u8, Value::new(&BigNum(1600)))); + available_inputs.add(&make_input(2u8, Value::new(&BigNum(6400)))); + available_inputs.add(&make_input(3u8, Value::new(&BigNum(2400)))); + available_inputs.add(&make_input(4u8, Value::new(&BigNum(800)))); tx_builder .add_inputs_from(&available_inputs, CoinSelectionStrategyCIP2::LargestFirst) .unwrap(); @@ -2120,17 +2125,17 @@ fn tx_builder_cip2_largest_first_static_fees() { ) .next() .unwrap() - .with_coin(&to_bignum(1200)) + .with_coin(&BigNum(1200)) .build() .unwrap(), ) .unwrap(); let mut available_inputs = TransactionUnspentOutputs::new(); - available_inputs.add(&make_input(0u8, Value::new(&to_bignum(150)))); - available_inputs.add(&make_input(1u8, Value::new(&to_bignum(200)))); - available_inputs.add(&make_input(2u8, Value::new(&to_bignum(800)))); - available_inputs.add(&make_input(3u8, Value::new(&to_bignum(400)))); - available_inputs.add(&make_input(4u8, Value::new(&to_bignum(100)))); + available_inputs.add(&make_input(0u8, Value::new(&BigNum(150)))); + available_inputs.add(&make_input(1u8, Value::new(&BigNum(200)))); + available_inputs.add(&make_input(2u8, Value::new(&BigNum(800)))); + available_inputs.add(&make_input(3u8, Value::new(&BigNum(400)))); + available_inputs.add(&make_input(4u8, Value::new(&BigNum(100)))); tx_builder .add_inputs_from(&available_inputs, CoinSelectionStrategyCIP2::LargestFirst) .unwrap(); @@ -2159,12 +2164,12 @@ fn tx_builder_cip2_largest_first_multiasset() { let asset_name2 = AssetName::new(vec![2u8; 11]).unwrap(); let asset_name3 = AssetName::new(vec![3u8; 9]).unwrap(); - let mut output_value = Value::new(&to_bignum(415)); + let mut output_value = Value::new(&BigNum(415)); let mut output_ma = MultiAsset::new(); - output_ma.set_asset(&pid1, &asset_name1, to_bignum(5)); - output_ma.set_asset(&pid1, &asset_name2, to_bignum(1)); - output_ma.set_asset(&pid2, &asset_name2, to_bignum(2)); - output_ma.set_asset(&pid2, &asset_name3, to_bignum(4)); + output_ma.set_asset(&pid1, &asset_name1, BigNum(5)); + output_ma.set_asset(&pid1, &asset_name2, BigNum(1)); + output_ma.set_asset(&pid2, &asset_name2, BigNum(2)); + output_ma.set_asset(&pid2, &asset_name3, BigNum(4)); output_value.set_multiasset(&output_ma); tx_builder .add_output(&TransactionOutput::new( @@ -2176,55 +2181,55 @@ fn tx_builder_cip2_largest_first_multiasset() { let mut available_inputs = TransactionUnspentOutputs::new(); // should not be taken - available_inputs.add(&make_input(0u8, Value::new(&to_bignum(150)))); + available_inputs.add(&make_input(0u8, Value::new(&BigNum(150)))); // should not be taken - let mut input1 = make_input(1u8, Value::new(&to_bignum(200))); + let mut input1 = make_input(1u8, Value::new(&BigNum(200))); let mut ma1 = MultiAsset::new(); - ma1.set_asset(&pid1, &asset_name1, to_bignum(10)); - ma1.set_asset(&pid1, &asset_name2, to_bignum(1)); - ma1.set_asset(&pid2, &asset_name2, to_bignum(2)); + ma1.set_asset(&pid1, &asset_name1, BigNum(10)); + ma1.set_asset(&pid1, &asset_name2, BigNum(1)); + ma1.set_asset(&pid2, &asset_name2, BigNum(2)); input1.output.amount.set_multiasset(&ma1); available_inputs.add(&input1); // taken first to satisfy pid1:asset_name1 (but also satisfies pid2:asset_name3) - let mut input2 = make_input(2u8, Value::new(&to_bignum(10))); + let mut input2 = make_input(2u8, Value::new(&BigNum(10))); let mut ma2 = MultiAsset::new(); - ma2.set_asset(&pid1, &asset_name1, to_bignum(20)); - ma2.set_asset(&pid2, &asset_name3, to_bignum(4)); + ma2.set_asset(&pid1, &asset_name1, BigNum(20)); + ma2.set_asset(&pid2, &asset_name3, BigNum(4)); input2.output.amount.set_multiasset(&ma2); available_inputs.add(&input2); // taken second to satisfy pid1:asset_name2 (but also satisfies pid2:asset_name1) - let mut input3 = make_input(3u8, Value::new(&to_bignum(50))); + let mut input3 = make_input(3u8, Value::new(&BigNum(50))); let mut ma3 = MultiAsset::new(); - ma3.set_asset(&pid2, &asset_name1, to_bignum(5)); - ma3.set_asset(&pid1, &asset_name2, to_bignum(15)); + ma3.set_asset(&pid2, &asset_name1, BigNum(5)); + ma3.set_asset(&pid1, &asset_name2, BigNum(15)); input3.output.amount.multiasset = Some(ma3); available_inputs.add(&input3); // should not be taken either - let mut input4 = make_input(4u8, Value::new(&to_bignum(10))); + let mut input4 = make_input(4u8, Value::new(&BigNum(10))); let mut ma4 = MultiAsset::new(); - ma4.set_asset(&pid1, &asset_name1, to_bignum(10)); - ma4.set_asset(&pid1, &asset_name2, to_bignum(10)); + ma4.set_asset(&pid1, &asset_name1, BigNum(10)); + ma4.set_asset(&pid1, &asset_name2, BigNum(10)); input4.output.amount.multiasset = Some(ma4); available_inputs.add(&input4); // taken third to satisfy pid2:asset_name_2 - let mut input5 = make_input(5u8, Value::new(&to_bignum(10))); + let mut input5 = make_input(5u8, Value::new(&BigNum(10))); let mut ma5 = MultiAsset::new(); - ma5.set_asset(&pid1, &asset_name2, to_bignum(10)); - ma5.set_asset(&pid2, &asset_name2, to_bignum(3)); + ma5.set_asset(&pid1, &asset_name2, BigNum(10)); + ma5.set_asset(&pid2, &asset_name2, BigNum(3)); input5.output.amount.multiasset = Some(ma5); available_inputs.add(&input5); // should be taken to get enough ADA - let input6 = make_input(6u8, Value::new(&to_bignum(900))); + let input6 = make_input(6u8, Value::new(&BigNum(900))); available_inputs.add(&input6); // should not be taken - available_inputs.add(&make_input(7u8, Value::new(&to_bignum(100)))); + available_inputs.add(&make_input(7u8, Value::new(&BigNum(100)))); tx_builder .add_inputs_from( &available_inputs, @@ -2248,12 +2253,12 @@ fn tx_builder_cip2_largest_first_multiasset() { assert_eq!(6u8, tx.inputs().get(3).transaction_id().0[0]); let change = tx.outputs().get(1).amount; - assert_eq!(from_bignum(&change.coin), 555); + assert_eq!(u64::from(change.coin), 555); let change_ma = change.multiasset().unwrap(); - assert_eq!(15, from_bignum(&change_ma.get_asset(&pid1, &asset_name1))); - assert_eq!(24, from_bignum(&change_ma.get_asset(&pid1, &asset_name2))); - assert_eq!(1, from_bignum(&change_ma.get_asset(&pid2, &asset_name2))); - assert_eq!(0, from_bignum(&change_ma.get_asset(&pid2, &asset_name3))); + assert_eq!(15, u64::from(change_ma.get_asset(&pid1, &asset_name1))); + assert_eq!(24, u64::from(change_ma.get_asset(&pid1, &asset_name2))); + assert_eq!(1, u64::from(change_ma.get_asset(&pid2, &asset_name2))); + assert_eq!(0, u64::from(change_ma.get_asset(&pid2, &asset_name3))); let expected_input = input2 .output .amount @@ -2276,12 +2281,12 @@ fn tx_builder_cip2_random_improve_multiasset() { let asset_name2 = AssetName::new(vec![2u8; 11]).unwrap(); let asset_name3 = AssetName::new(vec![3u8; 9]).unwrap(); - let mut output_value = Value::new(&to_bignum(415)); + let mut output_value = Value::new(&BigNum(415)); let mut output_ma = MultiAsset::new(); - output_ma.set_asset(&pid1, &asset_name1, to_bignum(5)); - output_ma.set_asset(&pid1, &asset_name2, to_bignum(1)); - output_ma.set_asset(&pid2, &asset_name2, to_bignum(2)); - output_ma.set_asset(&pid2, &asset_name3, to_bignum(4)); + output_ma.set_asset(&pid1, &asset_name1, BigNum(5)); + output_ma.set_asset(&pid1, &asset_name2, BigNum(1)); + output_ma.set_asset(&pid2, &asset_name2, BigNum(2)); + output_ma.set_asset(&pid2, &asset_name3, BigNum(4)); output_value.set_multiasset(&output_ma); tx_builder .add_output(&TransactionOutput::new( @@ -2292,57 +2297,57 @@ fn tx_builder_cip2_random_improve_multiasset() { .unwrap(); let mut available_inputs = TransactionUnspentOutputs::new(); - available_inputs.add(&make_input(0u8, Value::new(&to_bignum(150)))); + available_inputs.add(&make_input(0u8, Value::new(&BigNum(150)))); - let mut input1 = make_input(1u8, Value::new(&to_bignum(200))); + let mut input1 = make_input(1u8, Value::new(&BigNum(200))); let mut ma1 = MultiAsset::new(); - ma1.set_asset(&pid1, &asset_name1, to_bignum(10)); - ma1.set_asset(&pid1, &asset_name2, to_bignum(1)); - ma1.set_asset(&pid2, &asset_name2, to_bignum(2)); + ma1.set_asset(&pid1, &asset_name1, BigNum(10)); + ma1.set_asset(&pid1, &asset_name2, BigNum(1)); + ma1.set_asset(&pid2, &asset_name2, BigNum(2)); input1.output.amount.set_multiasset(&ma1); available_inputs.add(&input1); - let mut input2 = make_input(2u8, Value::new(&to_bignum(10))); + let mut input2 = make_input(2u8, Value::new(&BigNum(10))); let mut ma2 = MultiAsset::new(); - ma2.set_asset(&pid1, &asset_name1, to_bignum(20)); - ma2.set_asset(&pid2, &asset_name3, to_bignum(4)); + ma2.set_asset(&pid1, &asset_name1, BigNum(20)); + ma2.set_asset(&pid2, &asset_name3, BigNum(4)); input2.output.amount.set_multiasset(&ma2); available_inputs.add(&input2); - let mut input3 = make_input(3u8, Value::new(&to_bignum(50))); + let mut input3 = make_input(3u8, Value::new(&BigNum(50))); let mut ma3 = MultiAsset::new(); - ma3.set_asset(&pid2, &asset_name1, to_bignum(5)); - ma3.set_asset(&pid1, &asset_name2, to_bignum(15)); + ma3.set_asset(&pid2, &asset_name1, BigNum(5)); + ma3.set_asset(&pid1, &asset_name2, BigNum(15)); input3.output.amount.multiasset = Some(ma3); available_inputs.add(&input3); - let mut input4 = make_input(4u8, Value::new(&to_bignum(10))); + let mut input4 = make_input(4u8, Value::new(&BigNum(10))); let mut ma4 = MultiAsset::new(); - ma4.set_asset(&pid1, &asset_name1, to_bignum(10)); - ma4.set_asset(&pid1, &asset_name2, to_bignum(10)); + ma4.set_asset(&pid1, &asset_name1, BigNum(10)); + ma4.set_asset(&pid1, &asset_name2, BigNum(10)); input4.output.amount.multiasset = Some(ma4); available_inputs.add(&input4); - let mut input5 = make_input(5u8, Value::new(&to_bignum(10))); + let mut input5 = make_input(5u8, Value::new(&BigNum(10))); let mut ma5 = MultiAsset::new(); - ma5.set_asset(&pid1, &asset_name2, to_bignum(10)); - ma5.set_asset(&pid2, &asset_name2, to_bignum(3)); + ma5.set_asset(&pid1, &asset_name2, BigNum(10)); + ma5.set_asset(&pid2, &asset_name2, BigNum(3)); input5.output.amount.multiasset = Some(ma5); available_inputs.add(&input5); - let input6 = make_input(6u8, Value::new(&to_bignum(1000))); + let input6 = make_input(6u8, Value::new(&BigNum(1000))); available_inputs.add(&input6); - available_inputs.add(&make_input(7u8, Value::new(&to_bignum(100)))); + available_inputs.add(&make_input(7u8, Value::new(&BigNum(100)))); - let mut input8 = make_input(8u8, Value::new(&to_bignum(10))); + let mut input8 = make_input(8u8, Value::new(&BigNum(10))); let mut ma8 = MultiAsset::new(); - ma8.set_asset(&pid2, &asset_name2, to_bignum(10)); + ma8.set_asset(&pid2, &asset_name2, BigNum(10)); input8.output.amount.multiasset = Some(ma8); available_inputs.add(&input8); - let mut input9 = make_input(9u8, Value::new(&to_bignum(10))); + let mut input9 = make_input(9u8, Value::new(&BigNum(10))); let mut ma9 = MultiAsset::new(); - ma9.set_asset(&pid2, &asset_name3, to_bignum(10)); + ma9.set_asset(&pid2, &asset_name3, BigNum(10)); input9.output.amount.multiasset = Some(ma9); available_inputs.add(&input9); @@ -2353,7 +2358,7 @@ fn tx_builder_cip2_random_improve_multiasset() { ) .unwrap(); - let input_for_cover_change = make_input(10u8, Value::new(&to_bignum(1000))); + let input_for_cover_change = make_input(10u8, Value::new(&BigNum(1000))); tx_builder.add_regular_input( &input_for_cover_change.output.address, &input_for_cover_change.input, @@ -2390,19 +2395,19 @@ fn tx_builder_cip2_random_improve() { ) .next() .unwrap() - .with_coin(&to_bignum(COST)) + .with_coin(&BigNum(COST)) .build() .unwrap(), ) .unwrap(); let mut available_inputs = TransactionUnspentOutputs::new(); - available_inputs.add(&make_input(0u8, Value::new(&to_bignum(1500)))); - available_inputs.add(&make_input(1u8, Value::new(&to_bignum(2000)))); - available_inputs.add(&make_input(2u8, Value::new(&to_bignum(8000)))); - available_inputs.add(&make_input(3u8, Value::new(&to_bignum(4000)))); - available_inputs.add(&make_input(4u8, Value::new(&to_bignum(1000)))); - available_inputs.add(&make_input(5u8, Value::new(&to_bignum(2000)))); - available_inputs.add(&make_input(6u8, Value::new(&to_bignum(1500)))); + available_inputs.add(&make_input(0u8, Value::new(&BigNum(1500)))); + available_inputs.add(&make_input(1u8, Value::new(&BigNum(2000)))); + available_inputs.add(&make_input(2u8, Value::new(&BigNum(8000)))); + available_inputs.add(&make_input(3u8, Value::new(&BigNum(4000)))); + available_inputs.add(&make_input(4u8, Value::new(&BigNum(1000)))); + available_inputs.add(&make_input(5u8, Value::new(&BigNum(2000)))); + available_inputs.add(&make_input(6u8, Value::new(&BigNum(1500)))); let add_inputs_res = tx_builder.add_inputs_from(&available_inputs, CoinSelectionStrategyCIP2::RandomImprove); assert!(add_inputs_res.is_ok(), "{:?}", add_inputs_res.err()); @@ -2436,7 +2441,7 @@ fn tx_builder_cip2_random_improve() { &tx_builder .min_fee() .unwrap() - .checked_add(&to_bignum(COST)) + .checked_add(&BigNum(COST)) .unwrap() ) ); @@ -2445,11 +2450,11 @@ fn tx_builder_cip2_random_improve() { #[test] fn tx_builder_cip2_random_improve_when_using_all_available_inputs() { // we have a = 1 to test increasing fees when more inputs are added - let linear_fee = LinearFee::new(&to_bignum(1), &to_bignum(0)); + let linear_fee = LinearFee::new(&BigNum(1), &BigNum(0)); let cfg = TransactionBuilderConfigBuilder::new() .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(0)) - .key_deposit(&to_bignum(0)) + .pool_deposit(&BigNum(0)) + .key_deposit(&BigNum(0)) .max_value_size(9999) .max_tx_size(9999) .coins_per_utxo_byte(&Coin::zero()) @@ -2468,14 +2473,14 @@ fn tx_builder_cip2_random_improve_when_using_all_available_inputs() { ) .next() .unwrap() - .with_coin(&to_bignum(COST)) + .with_coin(&BigNum(COST)) .build() .unwrap(), ) .unwrap(); let mut available_inputs = TransactionUnspentOutputs::new(); - available_inputs.add(&make_input(1u8, Value::new(&to_bignum(800)))); - available_inputs.add(&make_input(2u8, Value::new(&to_bignum(800)))); + available_inputs.add(&make_input(1u8, Value::new(&BigNum(800)))); + available_inputs.add(&make_input(2u8, Value::new(&BigNum(800)))); let add_inputs_res = tx_builder.add_inputs_from(&available_inputs, CoinSelectionStrategyCIP2::RandomImprove); assert!(add_inputs_res.is_ok(), "{:?}", add_inputs_res.err()); @@ -2484,11 +2489,11 @@ fn tx_builder_cip2_random_improve_when_using_all_available_inputs() { #[test] fn tx_builder_cip2_random_improve_adds_enough_for_fees() { // we have a = 1 to test increasing fees when more inputs are added - let linear_fee = LinearFee::new(&to_bignum(1), &to_bignum(0)); + let linear_fee = LinearFee::new(&BigNum(1), &BigNum(0)); let cfg = TransactionBuilderConfigBuilder::new() .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(0)) - .key_deposit(&to_bignum(0)) + .pool_deposit(&BigNum(0)) + .key_deposit(&BigNum(0)) .max_value_size(9999) .max_tx_size(9999) .coins_per_utxo_byte(&Coin::zero()) @@ -2507,20 +2512,20 @@ fn tx_builder_cip2_random_improve_adds_enough_for_fees() { ) .next() .unwrap() - .with_coin(&to_bignum(COST)) + .with_coin(&BigNum(COST)) .build() .unwrap(), ) .unwrap(); - assert_eq!(tx_builder.min_fee().unwrap(), to_bignum(53)); + assert_eq!(tx_builder.min_fee().unwrap(), BigNum(53)); let mut available_inputs = TransactionUnspentOutputs::new(); - available_inputs.add(&make_input(1u8, Value::new(&to_bignum(150)))); - available_inputs.add(&make_input(2u8, Value::new(&to_bignum(150)))); - available_inputs.add(&make_input(3u8, Value::new(&to_bignum(150)))); + available_inputs.add(&make_input(1u8, Value::new(&BigNum(150)))); + available_inputs.add(&make_input(2u8, Value::new(&BigNum(150)))); + available_inputs.add(&make_input(3u8, Value::new(&BigNum(150)))); let add_inputs_res = tx_builder.add_inputs_from(&available_inputs, CoinSelectionStrategyCIP2::RandomImprove); assert!(add_inputs_res.is_ok(), "{:?}", add_inputs_res.err()); - assert_eq!(tx_builder.min_fee().unwrap(), to_bignum(264)); + assert_eq!(tx_builder.min_fee().unwrap(), BigNum(264)); let change_addr = ByronAddress::from_base58("Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho") .unwrap() @@ -2561,7 +2566,7 @@ fn build_tx_pay_to_multisig() { tx_builder.add_key_input( &spend.to_raw_key().hash(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); tx_builder .add_output( @@ -2569,13 +2574,13 @@ fn build_tx_pay_to_multisig() { .with_address(&addr_net_0) .next() .unwrap() - .with_coin(&to_bignum(999_000)) + .with_coin(&BigNum(999_000)) .build() .unwrap(), ) .unwrap(); tx_builder.set_ttl(1000); - tx_builder.set_fee(&to_bignum(1_000)); + tx_builder.set_fee(&BigNum(1_000)); assert_eq!(tx_builder.outputs.len(), 1); assert_eq!( @@ -2651,7 +2656,7 @@ fn build_tx_multisig_spend_1on1_unsigned() { tx_builder.add_regular_input( &addr_multisig, &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); tx_builder @@ -2660,13 +2665,13 @@ fn build_tx_multisig_spend_1on1_unsigned() { .with_address(&addr_output) .next() .unwrap() - .with_coin(&to_bignum(999_000)) + .with_coin(&BigNum(999_000)) .build() .unwrap(), ) .unwrap(); tx_builder.set_ttl(1000); - tx_builder.set_fee(&to_bignum(1_000)); + tx_builder.set_fee(&BigNum(1_000)); let mut auxiliary_data = AuxiliaryData::new(); let mut pubkey_native_scripts = NativeScripts::new(); @@ -2736,7 +2741,7 @@ fn build_tx_multisig_1on1_signed() { tx_builder.add_key_input( &spend.to_raw_key().hash(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); tx_builder .add_output( @@ -2744,13 +2749,13 @@ fn build_tx_multisig_1on1_signed() { .with_address(&addr_net_0) .next() .unwrap() - .with_coin(&to_bignum(999_000)) + .with_coin(&BigNum(999_000)) .build() .unwrap(), ) .unwrap(); tx_builder.set_ttl(1000); - tx_builder.set_fee(&to_bignum(1_000)); + tx_builder.set_fee(&BigNum(1_000)); let mut auxiliary_data = AuxiliaryData::new(); let mut pubkey_native_scripts = NativeScripts::new(); @@ -2806,16 +2811,16 @@ fn build_tx_multisig_1on1_signed() { #[test] fn add_change_splits_change_into_multiple_outputs_when_nfts_overflow_output_size() { - let linear_fee = LinearFee::new(&to_bignum(0), &to_bignum(1)); + let linear_fee = LinearFee::new(&BigNum(0), &BigNum(1)); let max_value_size = 100; // super low max output size to test with fewer assets let mut tx_builder = TransactionBuilder::new( &TransactionBuilderConfigBuilder::new() .fee_algo(&linear_fee) - .pool_deposit(&to_bignum(0)) - .key_deposit(&to_bignum(0)) + .pool_deposit(&BigNum(0)) + .key_deposit(&BigNum(0)) .max_value_size(max_value_size) .max_tx_size(MAX_TX_SIZE) - .coins_per_utxo_byte(&to_bignum(1)) + .coins_per_utxo_byte(&BigNum(1)) .prefer_pure_change(true) .build() .unwrap(), @@ -2830,13 +2835,13 @@ fn add_change_splits_change_into_multiple_outputs_when_nfts_overflow_output_size AssetName::new(vec![6u8, 5, 6, 7]).unwrap(), ]; let assets = names.iter().fold(Assets::new(), |mut a, name| { - a.insert(&name, &to_bignum(500)); + a.insert(&name, &BigNum(500)); a }); let mut multiasset = MultiAsset::new(); multiasset.insert(&policy_id, &assets); - let mut input_value = Value::new(&to_bignum(1200)); + let mut input_value = Value::new(&BigNum(1200)); input_value.set_multiasset(&multiasset); tx_builder.add_regular_input( @@ -2851,7 +2856,7 @@ fn add_change_splits_change_into_multiple_outputs_when_nfts_overflow_output_size ByronAddress::from_base58("Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b") .unwrap() .to_address(); - let output_amount = Value::new(&to_bignum(208)); + let output_amount = Value::new(&BigNum(208)); tx_builder .add_output( @@ -2882,9 +2887,9 @@ fn add_change_splits_change_into_multiple_outputs_when_nfts_overflow_output_size assert_eq!(change1.address, change2.address); assert_eq!(change1.address, change3.address); - assert_eq!(change1.amount.coin, to_bignum(288)); - assert_eq!(change2.amount.coin, to_bignum(293)); - assert_eq!(change3.amount.coin, to_bignum(410)); + assert_eq!(change1.amount.coin, BigNum(288)); + assert_eq!(change2.amount.coin, BigNum(293)); + assert_eq!(change3.amount.coin, BigNum(410)); assert!(change1.amount.multiasset.is_some()); assert!(change2.amount.multiasset.is_some()); @@ -2905,7 +2910,7 @@ fn add_change_splits_change_into_multiple_outputs_when_nfts_overflow_output_size let v1 = asset1.get(name); let v2 = asset2.get(name); assert_ne!(v1.is_some(), v2.is_some()); - assert_eq!(v1.or(v2).unwrap(), to_bignum(500)); + assert_eq!(v1.or(v2).unwrap(), BigNum(500)); }); } @@ -2947,7 +2952,7 @@ fn assert_json_metadatum(dat: &TransactionMetadatum) { fn set_metadata_with_empty_auxiliary() { let mut tx_builder = create_default_tx_builder(); - let num = to_bignum(42); + let num = BigNum(42); tx_builder.set_metadata(&create_aux_with_metadata(&num).metadata().unwrap()); assert!(tx_builder.auxiliary_data.is_some()); @@ -2967,10 +2972,10 @@ fn set_metadata_with_empty_auxiliary() { fn set_metadata_with_existing_auxiliary() { let mut tx_builder = create_default_tx_builder(); - let num1 = to_bignum(42); + let num1 = BigNum(42); tx_builder.set_auxiliary_data(&create_aux_with_metadata(&num1)); - let num2 = to_bignum(84); + let num2 = BigNum(84); tx_builder.set_metadata(&create_aux_with_metadata(&num2).metadata().unwrap()); let aux = tx_builder.auxiliary_data.unwrap(); @@ -2988,7 +2993,7 @@ fn set_metadata_with_existing_auxiliary() { fn add_metadatum_with_empty_auxiliary() { let mut tx_builder = create_default_tx_builder(); - let num = to_bignum(42); + let num = BigNum(42); tx_builder.add_metadatum(&num, &create_json_metadatum()); assert!(tx_builder.auxiliary_data.is_some()); @@ -3008,10 +3013,10 @@ fn add_metadatum_with_empty_auxiliary() { fn add_metadatum_with_existing_auxiliary() { let mut tx_builder = create_default_tx_builder(); - let num1 = to_bignum(42); + let num1 = BigNum(42); tx_builder.set_auxiliary_data(&create_aux_with_metadata(&num1)); - let num2 = to_bignum(84); + let num2 = BigNum(84); tx_builder.add_metadatum(&num2, &create_json_metadatum()); let aux = tx_builder.auxiliary_data.unwrap(); @@ -3029,7 +3034,7 @@ fn add_metadatum_with_existing_auxiliary() { fn add_json_metadatum_with_empty_auxiliary() { let mut tx_builder = create_default_tx_builder(); - let num = to_bignum(42); + let num = BigNum(42); tx_builder .add_json_metadatum(&num, create_json_metadatum_string()) .unwrap(); @@ -3051,10 +3056,10 @@ fn add_json_metadatum_with_empty_auxiliary() { fn add_json_metadatum_with_existing_auxiliary() { let mut tx_builder = create_default_tx_builder(); - let num1 = to_bignum(42); + let num1 = BigNum(42); tx_builder.set_auxiliary_data(&create_aux_with_metadata(&num1)); - let num2 = to_bignum(84); + let num2 = BigNum(84); tx_builder .add_json_metadatum(&num2, create_json_metadatum_string()) .unwrap(); @@ -3080,7 +3085,7 @@ fn create_mint_asset() -> MintAssets { fn create_assets() -> Assets { let mut assets = Assets::new(); - assets.insert(&create_asset_name(), &to_bignum(1234)); + assets.insert(&create_asset_name(), &BigNum(1234)); return assets; } @@ -3250,7 +3255,7 @@ fn add_output_amount() { let policy_id1 = PolicyID::from([0u8; 28]); let multiasset = create_multiasset_one_asset(&policy_id1); - let mut value = Value::new(&to_bignum(249)); + let mut value = Value::new(&BigNum(249)); value.set_multiasset(&multiasset); let address = byron_address(); @@ -3278,7 +3283,7 @@ fn add_output_coin() { let mut tx_builder = create_default_tx_builder(); let address = byron_address(); - let coin = to_bignum(208); + let coin = BigNum(208); tx_builder .add_output( &TransactionOutputBuilder::new() @@ -3307,7 +3312,7 @@ fn add_output_coin_and_multiasset() { let multiasset = create_multiasset_one_asset(&policy_id1); let address = byron_address(); - let coin = to_bignum(249); + let coin = BigNum(249); tx_builder .add_output( @@ -3359,7 +3364,7 @@ fn add_output_asset_and_min_required_coin() { assert_eq!(out.address.to_bytes(), address.to_bytes()); assert_eq!(out.amount.multiasset.unwrap(), multiasset); - assert_eq!(out.amount.coin, to_bignum(1146460)); + assert_eq!(out.amount.coin, BigNum(1146460)); } #[test] @@ -3373,7 +3378,7 @@ fn add_mint_asset_and_output() { let amount = Int::new_i32(1234); let address = byron_address(); - let coin = to_bignum(249); + let coin = BigNum(249); // Add unrelated mint first to check it is NOT added to output later tx_builder.add_mint_asset(&mint_script0, &name, &amount.clone()); @@ -3430,7 +3435,7 @@ fn add_mint_asset_and_output() { let asset = multiasset.get(&policy_id1).unwrap(); assert_eq!(asset.len(), 1); - assert_eq!(asset.get(&name).unwrap(), to_bignum(1234)); + assert_eq!(asset.get(&name).unwrap(), BigNum(1234)); } #[test] @@ -3488,7 +3493,7 @@ fn add_mint_asset_and_min_required_coin() { let out = tx_builder.outputs.get(0); assert_eq!(out.address.to_bytes(), address.to_bytes()); - assert_eq!(out.amount.coin, to_bignum(1146460)); + assert_eq!(out.amount.coin, BigNum(1146460)); let multiasset = out.amount.multiasset.unwrap(); @@ -3499,7 +3504,7 @@ fn add_mint_asset_and_min_required_coin() { let asset = multiasset.get(&policy_id1).unwrap(); assert_eq!(asset.len(), 1); - assert_eq!(asset.get(&name).unwrap(), to_bignum(1234)); + assert_eq!(asset.get(&name).unwrap(), BigNum(1234)); } #[test] @@ -3522,19 +3527,19 @@ fn add_mint_includes_witnesses_into_fee_estimation() { tx_builder.add_key_input( &hash0, &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(10_000_000)), + &Value::new(&BigNum(10_000_000)), ); // One input from same address as mint tx_builder.add_key_input( &hash1, &TransactionInput::new(&genesis_id(), 1), - &Value::new(&to_bignum(10_000_000)), + &Value::new(&BigNum(10_000_000)), ); // Original tx fee now assumes two VKey signatures for two inputs let original_tx_fee = tx_builder.min_fee().unwrap(); - assert_eq!(original_tx_fee, to_bignum(168361)); + assert_eq!(original_tx_fee, BigNum(168361)); // Add minting four assets from three different policies tx_builder.add_mint_asset(&mint_script1, &name1, &amount); @@ -3552,15 +3557,15 @@ fn add_mint_includes_witnesses_into_fee_estimation() { let fee_coefficient = tx_builder.config.fee_algo.coefficient(); let raw_mint_fee = fee_coefficient - .checked_mul(&to_bignum(mint_len as u64)) + .checked_mul(&BigNum(mint_len as u64)) .unwrap(); let raw_mint_script_fee = fee_coefficient - .checked_mul(&to_bignum(mint_scripts_len as u64)) + .checked_mul(&BigNum(mint_scripts_len as u64)) .unwrap(); - assert_eq!(raw_mint_fee, to_bignum(5544)); - assert_eq!(raw_mint_script_fee, to_bignum(4312)); + assert_eq!(raw_mint_fee, BigNum(5544)); + assert_eq!(raw_mint_script_fee, BigNum(4312)); let new_tx_fee = tx_builder.min_fee().unwrap(); @@ -3572,10 +3577,10 @@ fn add_mint_includes_witnesses_into_fee_estimation() { .checked_sub(&raw_mint_script_fee) .unwrap(); - assert_eq!(witness_fee_increase, to_bignum(8932)); + assert_eq!(witness_fee_increase, BigNum(8932)); - let fee_increase_bytes = from_bignum(&witness_fee_increase) - .checked_div(from_bignum(&fee_coefficient)) + let fee_increase_bytes = u64::from(&witness_fee_increase) + .checked_div(u64::from(&fee_coefficient)) .unwrap(); // Two vkey witnesses 96 bytes each (32 byte pubkey + 64 byte signature) @@ -3673,12 +3678,12 @@ fn total_input_output_with_mint_and_burn() { let mut multiasset = MultiAsset::new(); multiasset.insert(&policy_id1, &{ let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(*input)); + assets.insert(&name, &BigNum(*input)); assets }); multiasset.insert(&policy_id2, &{ let mut assets = Assets::new(); - assets.insert(&name, &to_bignum(*input)); + assets.insert(&name, &BigNum(*input)); assets }); multiasset @@ -3687,7 +3692,7 @@ fn total_input_output_with_mint_and_burn() { for (i, (multiasset, ada)) in multiassets .iter() - .zip([100u64, 100, 100].iter().cloned().map(to_bignum)) + .zip([100u64, 100, 100].iter().cloned().map(BigNum::from)) .enumerate() { let mut input_amount = Value::new(&ada); @@ -3706,7 +3711,7 @@ fn total_input_output_with_mint_and_burn() { .with_address(&byron_address()) .next() .unwrap() - .with_coin(&to_bignum(208)) + .with_coin(&BigNum(208)) .build() .unwrap(), ) @@ -3715,17 +3720,17 @@ fn total_input_output_with_mint_and_burn() { let total_input_before_mint = tx_builder.get_total_input().unwrap(); let total_output_before_mint = tx_builder.get_total_output().unwrap(); - assert_eq!(total_input_before_mint.coin, to_bignum(300)); - assert_eq!(total_output_before_mint.coin, to_bignum(208)); + assert_eq!(total_input_before_mint.coin, BigNum(300)); + assert_eq!(total_output_before_mint.coin, BigNum(208)); let ma1_input = total_input_before_mint.multiasset.unwrap(); let ma1_output = total_output_before_mint.multiasset; assert_eq!( ma1_input.get(&policy_id1).unwrap().get(&name).unwrap(), - to_bignum(360) + BigNum(360) ); assert_eq!( ma1_input.get(&policy_id2).unwrap().get(&name).unwrap(), - to_bignum(360) + BigNum(360) ); assert!(ma1_output.is_none()); @@ -3738,21 +3743,21 @@ fn total_input_output_with_mint_and_burn() { let total_input_after_mint = tx_builder.get_total_input().unwrap(); let total_output_after_mint = tx_builder.get_total_output().unwrap(); - assert_eq!(total_input_after_mint.coin, to_bignum(300)); - assert_eq!(total_output_before_mint.coin, to_bignum(208)); + assert_eq!(total_input_after_mint.coin, BigNum(300)); + assert_eq!(total_output_before_mint.coin, BigNum(208)); let ma2_input = total_input_after_mint.multiasset.unwrap(); let ma2_output = total_output_after_mint.multiasset.unwrap(); assert_eq!( ma2_input.get(&policy_id1).unwrap().get(&name).unwrap(), - to_bignum(400) + BigNum(400) ); assert_eq!( ma2_input.get(&policy_id2).unwrap().get(&name).unwrap(), - to_bignum(360) + BigNum(360) ); assert_eq!( ma2_output.get(&policy_id2).unwrap().get(&name).unwrap(), - to_bignum(40) + BigNum(40) ); } @@ -3775,12 +3780,12 @@ fn test_add_native_script_input() { tx_builder.add_native_script_input( &script1, &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); tx_builder.add_native_script_input( &script2, &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); assert_eq!( @@ -3798,17 +3803,17 @@ fn test_native_input_scripts_are_added_to_the_witnesses() { let mut tx_builder = create_reallistic_tx_builder(); let (script1, _) = mint_script_and_policy(0); let (script2, _) = mint_script_and_policy(1); - tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_fee(&BigNum(42)); tx_builder.add_native_script_input( &script1, &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); tx_builder.add_native_script_input( &script2, &TransactionInput::new(&genesis_id(), 1), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); let tx: Transaction = tx_builder.build_tx_unsafe().unwrap(); @@ -3827,16 +3832,16 @@ fn test_adding_plutus_script_input() { let redeemer_datum = PlutusData::new_bytes(fake_bytes_32(2)); let redeemer = Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(0), + &BigNum(0), &redeemer_datum, - &ExUnits::new(&to_bignum(1), &to_bignum(2)), + &ExUnits::new(&BigNum(1), &BigNum(2)), ); tx_builder.add_plutus_script_input( &PlutusWitness::new(&script1, &datum, &redeemer), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); - tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_fee(&BigNum(42)); // There are no missing script witnesses let tx: Transaction = tx_builder.build_tx_unsafe().unwrap(); assert!(tx.witness_set.plutus_scripts.is_some()); @@ -3850,32 +3855,32 @@ fn test_adding_plutus_script_input() { #[test] fn test_adding_plutus_script_witnesses() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_fee(&BigNum(42)); let (script1, _) = plutus_script_and_hash(0); let (script2, _) = plutus_script_and_hash(1); let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); let redeemer1 = Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(0), + &BigNum(0), &PlutusData::new_bytes(fake_bytes_32(20)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), + &ExUnits::new(&BigNum(1), &BigNum(2)), ); let redeemer2 = Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(1), + &BigNum(1), &PlutusData::new_bytes(fake_bytes_32(21)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), + &ExUnits::new(&BigNum(1), &BigNum(2)), ); tx_builder.add_plutus_script_input( &PlutusWitness::new(&script1, &datum1, &redeemer1), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); tx_builder.add_plutus_script_input( &PlutusWitness::new(&script2, &datum2, &redeemer2), &TransactionInput::new(&genesis_id(), 1), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); let tx: Transaction = tx_builder.build_tx_unsafe().unwrap(); @@ -3905,7 +3910,7 @@ fn create_collateral() -> TxInputsBuilder { .add_regular_input( &byron_address(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ) .unwrap(); collateral_builder @@ -3914,21 +3919,21 @@ fn create_collateral() -> TxInputsBuilder { #[test] fn test_existing_plutus_scripts_require_data_hash() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); let (script1, _) = plutus_script_and_hash(0); let datum = PlutusData::new_bytes(fake_bytes_32(1)); let redeemer_datum = PlutusData::new_bytes(fake_bytes_32(2)); let redeemer = Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(0), + &BigNum(0), &redeemer_datum, - &ExUnits::new(&to_bignum(1), &to_bignum(2)), + &ExUnits::new(&BigNum(1), &BigNum(2)), ); tx_builder.add_plutus_script_input( &PlutusWitness::new(&script1, &datum, &redeemer), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); // Using SAFE `.build_tx` @@ -3954,7 +3959,7 @@ fn test_existing_plutus_scripts_require_data_hash() { #[test] fn test_calc_script_hash_data() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); let (script1, _) = plutus_script_and_hash(0); @@ -3962,14 +3967,14 @@ fn test_calc_script_hash_data() { let redeemer_datum = PlutusData::new_bytes(fake_bytes_32(2)); let redeemer = Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(0), + &BigNum(0), &redeemer_datum, - &ExUnits::new(&to_bignum(1), &to_bignum(2)), + &ExUnits::new(&BigNum(1), &BigNum(2)), ); tx_builder.add_plutus_script_input( &PlutusWitness::new(&script1, &datum, &redeemer), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); // Setting script data hash removes the error @@ -3995,7 +4000,7 @@ fn test_calc_script_hash_data() { #[test] fn test_plutus_witness_redeemer_index_auto_changing() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); let (script1, _) = plutus_script_and_hash(0); let (script2, _) = plutus_script_and_hash(1); @@ -4005,22 +4010,22 @@ fn test_plutus_witness_redeemer_index_auto_changing() { // Creating redeemers with indexes ZERO let redeemer1 = Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(0), + &BigNum(0), &PlutusData::new_bytes(fake_bytes_32(20)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), + &ExUnits::new(&BigNum(1), &BigNum(2)), ); let redeemer2 = Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(0), + &BigNum(0), &PlutusData::new_bytes(fake_bytes_32(21)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), + &ExUnits::new(&BigNum(1), &BigNum(2)), ); // Add a regular NON-script input first tx_builder.add_regular_input( &byron_address(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); // Adding two plutus inputs then @@ -4028,12 +4033,12 @@ fn test_plutus_witness_redeemer_index_auto_changing() { tx_builder.add_plutus_script_input( &PlutusWitness::new(&script1, &datum1, &redeemer1), &TransactionInput::new(&genesis_id(), 1), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); tx_builder.add_plutus_script_input( &PlutusWitness::new(&script2, &datum2, &redeemer2), &TransactionInput::new(&genesis_id(), 2), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); // Calc the script data hash @@ -4058,14 +4063,14 @@ fn test_plutus_witness_redeemer_index_auto_changing() { // Note the redeemers from the result transaction are equal with source redeemers // In everything EXCEPT the index field, the indexes have changed to 1 and 2 // To match the position of their corresponding input - assert_eq!(redeems.get(0).index(), to_bignum(1)); - assert_eq!(redeems.get(1).index(), to_bignum(2)); + assert_eq!(redeems.get(0).index(), BigNum(1)); + assert_eq!(redeems.get(1).index(), BigNum(2)); } #[test] fn test_native_and_plutus_scripts_together() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); let (pscript1, _) = plutus_script_and_hash(0); let (pscript2, phash2) = plutus_script_and_hash(1); @@ -4076,40 +4081,40 @@ fn test_native_and_plutus_scripts_together() { // Creating redeemers with indexes ZERO let redeemer1 = Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(0), + &BigNum(0), &PlutusData::new_bytes(fake_bytes_32(20)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), + &ExUnits::new(&BigNum(1), &BigNum(2)), ); let redeemer2 = Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(0), + &BigNum(0), &PlutusData::new_bytes(fake_bytes_32(21)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), + &ExUnits::new(&BigNum(1), &BigNum(2)), ); // Add one plutus input directly with witness tx_builder.add_plutus_script_input( &PlutusWitness::new(&pscript1, &datum1, &redeemer1), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); // Add one native input directly with witness tx_builder.add_native_script_input( &nscript1, &TransactionInput::new(&genesis_id(), 1), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); // Add one plutus input generically without witness tx_builder.add_plutus_script_input( &PlutusWitness::new(&pscript2, &datum2, &redeemer2), &TransactionInput::new(&genesis_id(), 2), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); // Add one native input generically without witness tx_builder.add_native_script_input( &nscript2, &TransactionInput::new(&genesis_id(), 3), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); tx_builder @@ -4145,13 +4150,13 @@ fn test_native_and_plutus_scripts_together() { // The second plutus input redeemer index has automatically changed to 2 // because it was added on the third position - assert_eq!(redeems.get(1), redeemer2.clone_with_index(&to_bignum(2))); + assert_eq!(redeems.get(1), redeemer2.clone_with_index(&BigNum(2))); } #[test] fn test_json_serialization_native_and_plutus_scripts_together() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); let (pscript1, _) = plutus_script_and_hash(0); let (pscript2, phash2) = plutus_script_and_hash(1); @@ -4162,40 +4167,40 @@ fn test_json_serialization_native_and_plutus_scripts_together() { // Creating redeemers with indexes ZERO let redeemer1 = Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(0), + &BigNum(0), &PlutusData::new_bytes(fake_bytes_32(20)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), + &ExUnits::new(&BigNum(1), &BigNum(2)), ); let redeemer2 = Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(0), + &BigNum(0), &PlutusData::new_bytes(fake_bytes_32(21)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), + &ExUnits::new(&BigNum(1), &BigNum(2)), ); // Add one plutus input directly with witness tx_builder.add_plutus_script_input( &PlutusWitness::new(&pscript1, &datum1, &redeemer1), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); // Add one native input directly with witness tx_builder.add_native_script_input( &nscript1, &TransactionInput::new(&genesis_id(), 1), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); // Add one plutus input generically without witness tx_builder.add_plutus_script_input( &PlutusWitness::new(&pscript2, &datum2, &redeemer2), &TransactionInput::new(&genesis_id(), 2), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); // Add one native input generically without witness tx_builder.add_native_script_input( &nscript2, &TransactionInput::new(&genesis_id(), 3), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); tx_builder.calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()); @@ -4218,17 +4223,17 @@ fn test_regular_and_collateral_inputs_same_keyhash() { input_builder.add_regular_input( &fake_base_address(0), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); collateral_builder.add_regular_input( &fake_base_address(0), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); fn get_fake_vkeys_count(i: &TxInputsBuilder, c: &TxInputsBuilder) -> usize { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_fee(&BigNum(42)); tx_builder.set_inputs(i); tx_builder.set_collateral(c); let tx: Transaction = fake_full_tx(&tx_builder, tx_builder.build().unwrap()).unwrap(); @@ -4243,12 +4248,12 @@ fn test_regular_and_collateral_inputs_same_keyhash() { input_builder.add_regular_input( &fake_base_address(1), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); collateral_builder.add_regular_input( &fake_base_address(2), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); // There are now three fake witnesses in the builder @@ -4259,7 +4264,7 @@ fn test_regular_and_collateral_inputs_same_keyhash() { #[test] fn test_regular_and_collateral_inputs_together() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_fee(&BigNum(42)); let (pscript1, _) = plutus_script_and_hash(0); let (pscript2, _) = plutus_script_and_hash(1); let (nscript1, _) = mint_script_and_policy(0); @@ -4269,15 +4274,15 @@ fn test_regular_and_collateral_inputs_together() { // Creating redeemers with indexes ZERO let redeemer1 = Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(0), + &BigNum(0), &PlutusData::new_bytes(fake_bytes_32(20)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), + &ExUnits::new(&BigNum(1), &BigNum(2)), ); let redeemer2 = Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(0), + &BigNum(0), &PlutusData::new_bytes(fake_bytes_32(21)), - &ExUnits::new(&to_bignum(1), &to_bignum(2)), + &ExUnits::new(&BigNum(1), &BigNum(2)), ); let mut input_builder = TxInputsBuilder::new(); @@ -4286,23 +4291,23 @@ fn test_regular_and_collateral_inputs_together() { input_builder.add_native_script_input( &nscript1, &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); collateral_builder.add_native_script_input( &nscript2, &TransactionInput::new(&genesis_id(), 1), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); input_builder.add_plutus_script_input( &PlutusWitness::new(&pscript1, &datum1, &redeemer1), &TransactionInput::new(&genesis_id(), 2), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); collateral_builder.add_plutus_script_input( &PlutusWitness::new(&pscript2, &datum2, &redeemer2), &TransactionInput::new(&genesis_id(), 3), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); tx_builder.set_inputs(&input_builder); @@ -4335,8 +4340,8 @@ fn test_regular_and_collateral_inputs_together() { assert!(w.redeemers.is_some()); let redeemers = w.redeemers.as_ref().unwrap(); assert_eq!(redeemers.len(), 2); - assert_eq!(redeemers.get(0), redeemer1.clone_with_index(&to_bignum(1))); - assert_eq!(redeemers.get(1), redeemer2.clone_with_index(&to_bignum(1))); + assert_eq!(redeemers.get(0), redeemer1.clone_with_index(&BigNum(1))); + assert_eq!(redeemers.get(1), redeemer2.clone_with_index(&BigNum(1))); } #[test] @@ -4349,26 +4354,26 @@ fn test_ex_unit_costs_are_added_to_the_fees() { input_builder.add_regular_input( &fake_base_address(0), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); collateral_builder.add_regular_input( &fake_base_address(0), &TransactionInput::new(&genesis_id(), 1), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); let (pscript1, _) = plutus_script_and_hash(0); let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); let redeemer1 = Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(0), + &BigNum(0), &PlutusData::new_bytes(fake_bytes_32(20)), - &ExUnits::new(&to_bignum(mem), &to_bignum(step)), + &ExUnits::new(&BigNum(mem), &BigNum(step)), ); input_builder.add_plutus_script_input( &PlutusWitness::new(&pscript1, &datum1, &redeemer1), &TransactionInput::new(&genesis_id(), 2), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); let mut tx_builder = create_reallistic_tx_builder(); @@ -4382,16 +4387,16 @@ fn test_ex_unit_costs_are_added_to_the_fees() { tx_builder.get_fee_if_set().unwrap() } - assert_eq!(calc_fee_with_ex_units(0, 0), to_bignum(173509)); - assert_eq!(calc_fee_with_ex_units(10000, 0), to_bignum(174174)); - assert_eq!(calc_fee_with_ex_units(0, 10000000), to_bignum(174406)); - assert_eq!(calc_fee_with_ex_units(10000, 10000000), to_bignum(175071)); + assert_eq!(calc_fee_with_ex_units(0, 0), BigNum(173509)); + assert_eq!(calc_fee_with_ex_units(10000, 0), BigNum(174174)); + assert_eq!(calc_fee_with_ex_units(0, 10000000), BigNum(174406)); + assert_eq!(calc_fee_with_ex_units(10000, 10000000), BigNum(175071)); } #[test] fn test_script_inputs_ordering() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_fee(&BigNum(42)); let (nscript1, _) = mint_script_and_policy(0); let (pscript1, _) = plutus_script_and_hash(0); let (pscript2, _) = plutus_script_and_hash(1); @@ -4402,15 +4407,15 @@ fn test_script_inputs_ordering() { let pdata2 = PlutusData::new_bytes(fake_bytes_32(21)); let redeemer1 = Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(0), + &BigNum(0), &pdata1, - &ExUnits::new(&to_bignum(1), &to_bignum(2)), + &ExUnits::new(&BigNum(1), &BigNum(2)), ); let redeemer2 = Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(0), + &BigNum(0), &pdata2, - &ExUnits::new(&to_bignum(1), &to_bignum(2)), + &ExUnits::new(&BigNum(1), &BigNum(2)), ); tx_builder.add_plutus_script_input( @@ -4440,17 +4445,17 @@ fn test_script_inputs_ordering() { // Redeemer1 now has the index 2 even tho the input was added first assert_eq!(r.get(0).data(), pdata1); - assert_eq!(r.get(0).index(), to_bignum(2)); + assert_eq!(r.get(0).index(), BigNum(2)); // Redeemer1 now has the index 1 even tho the input was added last assert_eq!(r.get(1).data(), pdata2); - assert_eq!(r.get(1).index(), to_bignum(1)); + assert_eq!(r.get(1).index(), BigNum(1)); } #[test] fn test_required_signers() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_fee(&BigNum(42)); let tx1: TransactionBody = tx_builder.build().unwrap(); assert!(tx1.required_signers.is_none()); @@ -4476,11 +4481,11 @@ fn test_required_signers() { fn test_required_signers_are_added_to_the_witness_estimate() { fn count_fake_witnesses_with_required_signers(keys: &Ed25519KeyHashes) -> usize { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_fee(&BigNum(42)); tx_builder.add_regular_input( &fake_base_address(0), &TransactionInput::new(&fake_tx_hash(0), 0), - &Value::new(&to_bignum(10_000_000)), + &Value::new(&BigNum(10_000_000)), ); keys.to_vec().iter().for_each(|k| { @@ -4535,7 +4540,7 @@ fn test_required_signers_are_added_to_the_witness_estimate() { #[test] fn collateral_return_and_total_collateral_setters() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); + tx_builder.set_fee(&BigNum(123456)); let mut inp = TxInputsBuilder::new(); inp.add_regular_input(&fake_base_address(0), &fake_tx_input(0), &fake_value()); @@ -4544,7 +4549,7 @@ fn collateral_return_and_total_collateral_setters() { tx_builder.set_collateral(&inp); let col_return = TransactionOutput::new(&fake_base_address(1), &fake_value2(123123)); - let col_total = to_bignum(234234); + let col_total = BigNum(234234); tx_builder.set_collateral_return(&col_return); tx_builder.set_total_collateral(&col_total); @@ -4561,7 +4566,7 @@ fn fake_multiasset(amount: u64) -> MultiAsset { let mut assets = Assets::new(); assets.insert( &AssetName::new(fake_bytes_32(235)).unwrap(), - &to_bignum(amount), + &BigNum(amount), ); let mut masset = MultiAsset::new(); masset.insert(&policy_id, &assets); @@ -4578,32 +4583,32 @@ fn inputs_builder_total_value() { &fake_tx_input(0), &fake_value2(100_000), ); - assert_eq!(b.total_value().unwrap(), Value::new(&to_bignum(100_000))); + assert_eq!(b.total_value().unwrap(), Value::new(&BigNum(100_000))); b.add_regular_input( &fake_base_address(1), &fake_tx_input(1), &fake_value2(200_000), ); - assert_eq!(b.total_value().unwrap(), Value::new(&to_bignum(300_000))); + assert_eq!(b.total_value().unwrap(), Value::new(&BigNum(300_000))); let masset = fake_multiasset(123); b.add_regular_input( &fake_base_address(2), &fake_tx_input(2), - &Value::new_with_assets(&to_bignum(300_000), &masset), + &Value::new_with_assets(&BigNum(300_000), &masset), ); assert_eq!( b.total_value().unwrap(), - Value::new_with_assets(&to_bignum(600_000), &masset) + Value::new_with_assets(&BigNum(600_000), &masset) ); } #[test] fn test_auto_calc_total_collateral() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); + tx_builder.set_fee(&BigNum(123456)); let mut inp = TxInputsBuilder::new(); let collateral_input_value = 2_000_000; @@ -4631,14 +4636,14 @@ fn test_auto_calc_total_collateral() { assert!(tx_builder.total_collateral.is_some()); assert_eq!( tx_builder.total_collateral.unwrap(), - to_bignum(collateral_input_value - collateral_return_value), + BigNum(collateral_input_value - collateral_return_value), ); } #[test] fn test_auto_calc_total_collateral_with_assets() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); + tx_builder.set_fee(&BigNum(123456)); let masset = fake_multiasset(123); @@ -4647,7 +4652,7 @@ fn test_auto_calc_total_collateral_with_assets() { inp.add_regular_input( &fake_base_address(0), &fake_tx_input(0), - &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), + &Value::new_with_assets(&BigNum(collateral_input_value.clone()), &masset), ); tx_builder.set_collateral(&inp); @@ -4655,7 +4660,7 @@ fn test_auto_calc_total_collateral_with_assets() { let collateral_return_value = 1_345_678; let col_return = TransactionOutput::new( &fake_base_address(1), - &Value::new_with_assets(&to_bignum(collateral_return_value.clone()), &masset), + &Value::new_with_assets(&BigNum(collateral_return_value.clone()), &masset), ); tx_builder @@ -4668,14 +4673,14 @@ fn test_auto_calc_total_collateral_with_assets() { assert!(tx_builder.total_collateral.is_some()); assert_eq!( tx_builder.total_collateral.unwrap(), - to_bignum(collateral_input_value - collateral_return_value), + BigNum(collateral_input_value - collateral_return_value), ); } #[test] fn test_auto_calc_total_collateral_fails_with_assets() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); + tx_builder.set_fee(&BigNum(123456)); let masset = fake_multiasset(123); @@ -4684,7 +4689,7 @@ fn test_auto_calc_total_collateral_fails_with_assets() { inp.add_regular_input( &fake_base_address(0), &fake_tx_input(0), - &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), + &Value::new_with_assets(&BigNum(collateral_input_value.clone()), &masset), ); tx_builder.set_collateral(&inp); @@ -4709,7 +4714,7 @@ fn test_auto_calc_total_collateral_fails_with_assets() { #[test] fn test_auto_calc_total_collateral_fails_on_no_collateral() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); + tx_builder.set_fee(&BigNum(123456)); let res = tx_builder.set_collateral_return_and_total(&TransactionOutput::new( &fake_base_address(1), @@ -4727,14 +4732,14 @@ fn test_auto_calc_total_collateral_fails_on_no_collateral() { #[test] fn test_auto_calc_total_collateral_fails_on_no_ada() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); + tx_builder.set_fee(&BigNum(123456)); let mut inp = TxInputsBuilder::new(); let collateral_input_value = 2_000_000; inp.add_regular_input( &fake_base_address(0), &fake_tx_input(0), - &Value::new(&to_bignum(collateral_input_value.clone())), + &Value::new(&BigNum(collateral_input_value.clone())), ); tx_builder.set_collateral(&inp); @@ -4755,7 +4760,7 @@ fn test_auto_calc_total_collateral_fails_on_no_ada() { #[test] fn test_auto_calc_collateral_return() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); + tx_builder.set_fee(&BigNum(123456)); let mut inp = TxInputsBuilder::new(); let collateral_input_value = 2_000_000; @@ -4772,7 +4777,7 @@ fn test_auto_calc_collateral_return() { tx_builder .set_total_collateral_and_return( - &to_bignum(total_collateral_value.clone()), + &BigNum(total_collateral_value.clone()), &collateral_return_address, ) .unwrap(); @@ -4780,7 +4785,7 @@ fn test_auto_calc_collateral_return() { assert!(tx_builder.total_collateral.is_some()); assert_eq!( tx_builder.total_collateral.unwrap(), - to_bignum(total_collateral_value.clone()), + BigNum(total_collateral_value.clone()), ); assert!(tx_builder.collateral_return.is_some()); @@ -4788,14 +4793,14 @@ fn test_auto_calc_collateral_return() { assert_eq!(col_return.address, collateral_return_address); assert_eq!( col_return.amount, - Value::new(&to_bignum(collateral_input_value - total_collateral_value),) + Value::new(&BigNum(collateral_input_value - total_collateral_value),) ); } #[test] fn test_auto_calc_collateral_return_with_assets() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); + tx_builder.set_fee(&BigNum(123456)); let masset = fake_multiasset(123); @@ -4804,7 +4809,7 @@ fn test_auto_calc_collateral_return_with_assets() { inp.add_regular_input( &fake_base_address(0), &fake_tx_input(0), - &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), + &Value::new_with_assets(&BigNum(collateral_input_value.clone()), &masset), ); tx_builder.set_collateral(&inp); @@ -4814,7 +4819,7 @@ fn test_auto_calc_collateral_return_with_assets() { tx_builder .set_total_collateral_and_return( - &to_bignum(total_collateral_value.clone()), + &BigNum(total_collateral_value.clone()), &collateral_return_address, ) .unwrap(); @@ -4822,7 +4827,7 @@ fn test_auto_calc_collateral_return_with_assets() { assert!(tx_builder.total_collateral.is_some()); assert_eq!( tx_builder.total_collateral.unwrap(), - to_bignum(total_collateral_value.clone()), + BigNum(total_collateral_value.clone()), ); assert!(tx_builder.collateral_return.is_some()); @@ -4831,7 +4836,7 @@ fn test_auto_calc_collateral_return_with_assets() { assert_eq!( col_return.amount, Value::new_with_assets( - &to_bignum(collateral_input_value - total_collateral_value), + &BigNum(collateral_input_value - total_collateral_value), &masset, ) ); @@ -4840,7 +4845,7 @@ fn test_auto_calc_collateral_return_with_assets() { #[test] fn test_add_collateral_return_succeed_with_border_amount() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); + tx_builder.set_fee(&BigNum(123456)); let masset = fake_multiasset(123); @@ -4849,7 +4854,7 @@ fn test_add_collateral_return_succeed_with_border_amount() { inp.add_regular_input( &fake_base_address(0), &fake_tx_input(0), - &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), + &Value::new_with_assets(&BigNum(collateral_input_value.clone()), &masset), ); tx_builder.set_collateral(&inp); @@ -4860,7 +4865,7 @@ fn test_add_collateral_return_succeed_with_border_amount() { let fake_out = TransactionOutput::new(&collateral_return_address, &possible_ret); let min_ada = min_ada_for_output(&fake_out, &tx_builder.config.utxo_cost()).unwrap(); - let total_collateral_value = to_bignum(collateral_input_value) + let total_collateral_value = BigNum(collateral_input_value) .checked_sub(&min_ada) .unwrap(); @@ -4881,14 +4886,14 @@ fn test_add_collateral_return_succeed_with_border_amount() { #[test] fn test_add_zero_collateral_return() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); + tx_builder.set_fee(&BigNum(123456)); let mut inp = TxInputsBuilder::new(); let collateral_input_value = 2_000_000; inp.add_regular_input( &fake_base_address(0), &fake_tx_input(0), - &Value::new(&to_bignum(collateral_input_value.clone())), + &Value::new(&BigNum(collateral_input_value.clone())), ); tx_builder.set_collateral(&inp); @@ -4897,7 +4902,7 @@ fn test_add_zero_collateral_return() { tx_builder .set_total_collateral_and_return( - &to_bignum(collateral_input_value.clone()), + &BigNum(collateral_input_value.clone()), &collateral_return_address, ) .unwrap(); @@ -4909,7 +4914,7 @@ fn test_add_zero_collateral_return() { #[test] fn test_add_collateral_return_fails_no_enough_ada() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); + tx_builder.set_fee(&BigNum(123456)); let masset = fake_multiasset(123); @@ -4918,7 +4923,7 @@ fn test_add_collateral_return_fails_no_enough_ada() { inp.add_regular_input( &fake_base_address(0), &fake_tx_input(0), - &Value::new_with_assets(&to_bignum(collateral_input_value.clone()), &masset), + &Value::new_with_assets(&BigNum(collateral_input_value.clone()), &masset), ); tx_builder.set_collateral(&inp); @@ -4928,11 +4933,11 @@ fn test_add_collateral_return_fails_no_enough_ada() { let possible_ret = Value::new_from_assets(&masset); let fake_out = TransactionOutput::new(&collateral_return_address, &possible_ret); let min_ada = min_ada_for_output(&fake_out, &tx_builder.config.utxo_cost()).unwrap(); - let mut total_collateral_value = to_bignum(collateral_input_value) + let mut total_collateral_value = BigNum(collateral_input_value) .checked_sub(&min_ada) .unwrap(); //make total collateral value bigger for make collateral return less then min ada - total_collateral_value = total_collateral_value.checked_add(&to_bignum(1)).unwrap(); + total_collateral_value = total_collateral_value.checked_add(&BigNum(1)).unwrap(); let coll_add_res = tx_builder .set_total_collateral_and_return(&total_collateral_value, &collateral_return_address); @@ -4945,10 +4950,10 @@ fn test_add_collateral_return_fails_no_enough_ada() { #[test] fn test_auto_calc_collateral_return_fails_on_no_collateral() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(123456)); + tx_builder.set_fee(&BigNum(123456)); - let res = tx_builder - .set_total_collateral_and_return(&to_bignum(345_678.clone()), &fake_base_address(1)); + let res = + tx_builder.set_total_collateral_and_return(&BigNum(345_678.clone()), &fake_base_address(1)); assert!(res.is_err()); assert!(tx_builder.total_collateral.is_none()); @@ -4958,21 +4963,21 @@ fn test_auto_calc_collateral_return_fails_on_no_collateral() { #[test] fn test_costmodel_retaining_for_v1() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); let (script1, _) = plutus_script_and_hash(0); let datum = PlutusData::new_integer(&BigInt::from_str("42").unwrap()); let redeemer = Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(0), + &BigNum(0), &datum, - &ExUnits::new(&to_bignum(1700), &to_bignum(368100)), + &ExUnits::new(&BigNum(1700), &BigNum(368100)), ); tx_builder.add_plutus_script_input( &PlutusWitness::new(&script1, &datum, &redeemer), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); // Setting script data hash removes the error @@ -5002,21 +5007,21 @@ fn test_costmodel_retaining_for_v1() { #[test] fn test_costmodel_retaining_fails_on_missing_costmodel() { let mut tx_builder = create_reallistic_tx_builder(); - tx_builder.set_fee(&to_bignum(42)); + tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); let (script1, _) = plutus_script_and_hash(0); let datum = PlutusData::new_integer(&BigInt::from_str("42").unwrap()); let redeemer = Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(0), + &BigNum(0), &datum, - &ExUnits::new(&to_bignum(1700), &to_bignum(368100)), + &ExUnits::new(&BigNum(1700), &BigNum(368100)), ); tx_builder.add_plutus_script_input( &PlutusWitness::new(&script1, &datum, &redeemer), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(1_000_000)), + &Value::new(&BigNum(1_000_000)), ); let v2 = Language::new_plutus_v2(); @@ -5603,6 +5608,7 @@ fn plutus_mint_with_script_ref_test() { &plutus_script2.hash(), &tx_input_ref, &Language::new_plutus_v2(), + 0, ); let mint_witnes = MintWitness::new_plutus_script(&plutus_script_source, &redeemer); let mint_witnes_ref = MintWitness::new_plutus_script(&plutus_script_source_ref, &redeemer2); @@ -5949,7 +5955,7 @@ fn build_tx_with_certs_withdrawals_plutus_script_address() { tx_builder.add_key_input( &spend.to_raw_key().hash(), &TransactionInput::new(&genesis_id(), 0), - &Value::new(&to_bignum(5_000_000)), + &Value::new(&BigNum(5_000_000)), ); tx_builder.set_ttl(1000); let (cert_script1, cert_script_hash1) = plutus_script_and_hash(1); @@ -5976,11 +5982,13 @@ fn build_tx_with_certs_withdrawals_plutus_script_address() { &cert_script_hash3, &ref_cert_script_input_3, &Language::new_plutus_v2(), + 0, ); let plutus_withdrawal_source = PlutusScriptSource::new_ref_input( &withdraw_script_hash2, &ref_cert_withdrawal_input_2, &Language::new_plutus_v2(), + 0, ); let cert_witness_3 = @@ -6137,12 +6145,7 @@ fn build_tx_with_certs_withdrawals_plutus_script_address() { #[test] pub fn test_extra_datum() { - let mut tx_builder = create_tx_builder( - &create_linear_fee(1, 100000), - 1, - 1, - 1, - ); + let mut tx_builder = create_tx_builder(&create_linear_fee(1, 100000), 1, 1, 1); let datum = PlutusData::new_bytes(fake_bytes_32(1)); tx_builder.add_extra_witness_datum(&datum); @@ -6151,8 +6154,9 @@ pub fn test_extra_datum() { inp.add_regular_input( &fake_base_address(0), &fake_tx_input(0), - &Value::new(&to_bignum(100000000000000u64)), - ).unwrap(); + &Value::new(&BigNum(100000000000000u64)), + ) + .unwrap(); tx_builder.set_inputs(&inp); tx_builder @@ -6169,7 +6173,11 @@ pub fn test_extra_datum() { let tx_size = tx.to_bytes().len(); let fake_input_wit_size = fake_vkey_witness(1).to_bytes().len(); - let real_fee = min_fee_for_size(tx_size + fake_input_wit_size, &LinearFee::new(&Coin::from(1u64), &Coin::from(100000u64))).unwrap(); + let real_fee = min_fee_for_size( + tx_size + fake_input_wit_size, + &LinearFee::new(&Coin::from(1u64), &Coin::from(100000u64)), + ) + .unwrap(); assert!(real_fee.less_than(&tx.body.fee)); @@ -6255,3 +6263,160 @@ fn donation_test() { assert_eq!(total_out, Coin::from(input_amount)); } + +#[test] +fn ref_script_fee_from_all_builders() { + let mut mint_builder = MintBuilder::new(); + let mut cert_builder = CertificatesBuilder::new(); + let mut withdrawal_builder = WithdrawalsBuilder::new(); + let mut voting_builder = VotingBuilder::new(); + let mut voting_proposal_builder = VotingProposalBuilder::new(); + let mut tx_input_builder = TxInputsBuilder::new(); + + let tx_in_1 = fake_tx_input(1); + let tx_in_2 = fake_tx_input(2); + let tx_in_3 = fake_tx_input(3); + let tx_in_4 = fake_tx_input(4); + let tx_in_5 = fake_tx_input(5); + let tx_in_6 = fake_tx_input(6); + let tx_in_7 = fake_tx_input(7); + let tx_in_8 = fake_tx_input(8); + let tx_in_9 = fake_tx_input(9); + + let script_hash_1 = fake_script_hash(1); + let script_hash_2 = fake_script_hash(2); + let script_hash_3 = fake_script_hash(3); + let script_hash_4 = fake_script_hash(4); + let script_hash_5 = fake_script_hash(5); + let script_hash_6 = fake_script_hash(6); + let script_hash_7 = fake_script_hash(7); + let script_hash_8 = fake_script_hash(8); + + let redeemer_1 = create_redeemer_zero_cost(1); + let redeemer_2 = create_redeemer_zero_cost(2); + let redeemer_3 = create_redeemer_zero_cost(3); + let redeemer_4 = create_redeemer_zero_cost(4); + let redeemer_5 = create_redeemer_zero_cost(5); + let redeemer_6 = create_redeemer_zero_cost(6); + let redeemer_8 = create_redeemer_zero_cost(8); + + let plutus_source_1 = PlutusScriptSource::new_ref_input(&script_hash_1, &tx_in_1, &Language::new_plutus_v2(), 10); + let plutus_source_2 = PlutusScriptSource::new_ref_input(&script_hash_2, &tx_in_2, &Language::new_plutus_v2(), 100); + let plutus_source_3 = PlutusScriptSource::new_ref_input(&script_hash_3, &tx_in_3, &Language::new_plutus_v2(), 1000); + let plutus_source_4 = PlutusScriptSource::new_ref_input(&script_hash_4, &tx_in_4, &Language::new_plutus_v2(), 10000); + let plutus_source_5 = PlutusScriptSource::new_ref_input(&script_hash_5, &tx_in_5, &Language::new_plutus_v2(), 100000); + let plutus_source_6 = PlutusScriptSource::new_ref_input(&script_hash_6, &tx_in_6, &Language::new_plutus_v2(), 1000000); + let native_script_source = NativeScriptSource::new_ref_input(&script_hash_7, &tx_in_7); + let plutus_source_8 = PlutusScriptSource::new_ref_input(&script_hash_8, &tx_in_8, &Language::new_plutus_v2(), 10000000); + + mint_builder.add_asset( + &MintWitness::new_plutus_script(&plutus_source_1, &redeemer_1), + &AssetName::from_hex("44544e4654").unwrap(), + &Int::new(&BigNum::from(100u64)) + ).unwrap(); + + mint_builder.add_asset( + &MintWitness::new_plutus_script(&plutus_source_2, &redeemer_2), + &AssetName::from_hex("44544e4654").unwrap(), + &Int::new(&BigNum::from(100u64)) + ).unwrap(); + + withdrawal_builder.add_with_plutus_witness( + &RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &Credential::from_scripthash(&script_hash_3)), + &Coin::from(1u64), + &PlutusWitness::new_with_ref_without_datum(&plutus_source_3, &redeemer_3) + ).unwrap(); + + withdrawal_builder.add_with_native_script( + &RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &Credential::from_scripthash(&script_hash_7)), + &Coin::from(1u64), + &native_script_source + ).unwrap(); + + cert_builder.add_with_plutus_witness( + &Certificate::new_stake_delegation(&StakeDelegation::new(&Credential::from_scripthash(&script_hash_4), &fake_key_hash(1))), + &PlutusWitness::new_with_ref_without_datum(&plutus_source_4, &redeemer_4) + ).unwrap(); + + voting_builder.add_with_plutus_witness( + &Voter::new_drep(&Credential::from_scripthash(&script_hash_5)), + &GovernanceActionId::new(&fake_tx_hash(1), 1), + &VotingProcedure::new(VoteKind::Abstain), + &PlutusWitness::new_with_ref_without_datum(&plutus_source_5, &redeemer_5) + ).unwrap(); + + voting_proposal_builder.add_with_plutus_witness( + &VotingProposal::new( + &GovernanceAction::new_new_constitution_action( + &NewConstitutionAction::new( + &Constitution::new_with_script_hash(&create_anchor(), &script_hash_6) + ) + ), + &create_anchor(), + &RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &Credential::from_keyhash(&fake_key_hash(1))), + &Coin::from(0u64), + ), + &PlutusWitness::new_with_ref_without_datum(&plutus_source_6, &redeemer_6) + ).unwrap(); + + tx_input_builder.add_plutus_script_input( + &PlutusWitness::new_with_ref_without_datum(&plutus_source_8, &redeemer_8), + &tx_in_8, + &Value::new(&Coin::from(1000000000u64)) + ); + + let mut tx_builder = create_reallistic_tx_builder(); + let change_address = fake_base_address(1); + + tx_builder.set_mint_builder(&mint_builder); + tx_builder.set_certs_builder(&cert_builder); + tx_builder.set_withdrawals_builder(&withdrawal_builder); + tx_builder.set_voting_builder(&voting_builder); + tx_builder.set_voting_proposal_builder(&voting_proposal_builder); + tx_builder.set_inputs(&tx_input_builder); + tx_builder.add_script_reference_input(&tx_in_9, 100000000); + + let fake_collateral = fake_tx_input(99); + let mut collateral_builder = TxInputsBuilder::new(); + collateral_builder.add_regular_input( + &fake_base_address(99), + &fake_collateral, + &Value::new(&Coin::from(1000000000u64)) + ).unwrap(); + + tx_builder.set_collateral(&collateral_builder); + tx_builder.calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()).unwrap(); + tx_builder.add_change_if_needed(&change_address).unwrap(); + + let res = tx_builder.build_tx(); + assert!(res.is_ok()); + + let mut tx = res.unwrap(); + let mut vkey_witneses = Vkeywitnesses::new(); + vkey_witneses.add(&fake_vkey_witness(1)); + let mut wit_set = tx.witness_set(); + wit_set.set_vkeys(&vkey_witneses); + tx = Transaction::new(&tx.body(), &wit_set, tx.auxiliary_data()); + + let ref_script_fee = BigNum::from(111111110u64 / 2); + let total_tx_fee = tx.body().fee(); + + //TODO: change check change calculation for pessimistic size estimation. + let tx_size = tx.to_bytes().len() + 4; + + let min_tx_fee = min_fee_for_size(tx_size, &create_linear_fee(44, 155381)).unwrap(); + let fee_leftover = total_tx_fee.checked_sub(&min_tx_fee).unwrap(); + assert_eq!(ref_script_fee, fee_leftover); + + let ref_inputs = tx.body().reference_inputs().unwrap(); + assert!(ref_inputs.contains(&tx_in_1)); + assert!(ref_inputs.contains(&tx_in_2)); + assert!(ref_inputs.contains(&tx_in_3)); + assert!(ref_inputs.contains(&tx_in_4)); + assert!(ref_inputs.contains(&tx_in_5)); + assert!(ref_inputs.contains(&tx_in_6)); + assert!(ref_inputs.contains(&tx_in_7)); + assert!(ref_inputs.contains(&tx_in_8)); + assert!(ref_inputs.contains(&tx_in_9)); + assert_eq!(ref_inputs.len(), 9); +} diff --git a/rust/src/tests/builders/voting_builder.rs b/rust/src/tests/builders/voting_builder.rs index 50226a11..8a6fe4fe 100644 --- a/rust/src/tests/builders/voting_builder.rs +++ b/rust/src/tests/builders/voting_builder.rs @@ -1,8 +1,6 @@ -use crate::fakes::{fake_key_hash, fake_script_hash, fake_tx_hash, fake_vkey}; +use crate::fakes::{fake_key_hash, fake_script_hash, fake_tx_hash, fake_tx_input, fake_vkey}; use crate::fees::min_fee_for_size; -use crate::tests::mock_objects::{ - create_change_address, create_linear_fee, create_plutus_script, create_rich_tx_builder, -}; +use crate::tests::mock_objects::{create_change_address, create_linear_fee, create_plutus_script, create_redeemer, create_rich_tx_builder}; use crate::*; #[test] @@ -192,6 +190,7 @@ fn voting_builder_plutus_ref_witness() { &script_hash, &ref_input, &Language::new_plutus_v2(), + 0 ); let witness = PlutusWitness::new_with_ref_without_datum(&script_source, &redeemer); builder @@ -335,8 +334,9 @@ fn voting_builder_native_script_ref_witness() { script_signers.add(&key_hash); let ref_input = TransactionInput::new(&fake_tx_hash(5), 0); - let script_source = - NativeScriptSource::new_ref_input(&script_hash, &ref_input, &script_signers); + let mut script_source = + NativeScriptSource::new_ref_input(&script_hash, &ref_input); + script_source.set_required_signers(&script_signers); builder .add_with_native_script(&voter, &action_id, &vote, &script_source) .unwrap(); @@ -432,4 +432,4 @@ fn voting_builder_key_hash_error() { let result = builder.add(&voter, &action_id, &vote); assert!(result.is_err()); -} +} \ No newline at end of file diff --git a/rust/src/tests/builders/voting_proposal_builder.rs b/rust/src/tests/builders/voting_proposal_builder.rs index 7cad6c0c..a6d88eb1 100644 --- a/rust/src/tests/builders/voting_proposal_builder.rs +++ b/rust/src/tests/builders/voting_proposal_builder.rs @@ -1,6 +1,9 @@ -use crate::*; use crate::fakes::{fake_key_hash, fake_reward_address, fake_script_hash, fake_tx_hash}; -use crate::tests::mock_objects::{crate_full_protocol_param_update, create_anchor, create_change_address, create_plutus_script, create_tx_builder_with_amount_and_deposit_params}; +use crate::tests::mock_objects::{ + crate_full_protocol_param_update, create_anchor, create_change_address, create_plutus_script, + create_tx_builder_with_amount_and_deposit_params, +}; +use crate::*; fn total_tx_output_with_fee(tx: &Transaction) -> Coin { let mut total = Coin::zero(); @@ -34,17 +37,19 @@ fn voting_proposal_builder_one_proposal() { assert_eq!(inputs.len(), 0); assert_eq!(builder.has_plutus_scripts(), false); - assert_eq!(builder.get_total_deposit().unwrap(), proposal_deposit.clone()); + assert_eq!( + builder.get_total_deposit().unwrap(), + proposal_deposit.clone() + ); let initial_amount = 1000000000u64; - let mut tx_builder = create_tx_builder_with_amount_and_deposit_params( - initial_amount, - 500, - 500, - false); + let mut tx_builder = + create_tx_builder_with_amount_and_deposit_params(initial_amount, 500, 500, false); tx_builder.set_voting_proposal_builder(&builder); - tx_builder.add_change_if_needed(&create_change_address()).unwrap(); + tx_builder + .add_change_if_needed(&create_change_address()) + .unwrap(); let tx = tx_builder.build_tx().unwrap(); @@ -93,7 +98,8 @@ fn voting_proposal_builder_all_proposals() { let anchor = create_anchor(); let constitution = Constitution::new(&anchor); let constitution_action = NewConstitutionAction::new(&constitution); - let wrapped_constitution_action = GovernanceAction::new_new_constitution_action(&constitution_action); + let wrapped_constitution_action = + GovernanceAction::new_new_constitution_action(&constitution_action); let constitution_proposal = VotingProposal::new( &wrapped_constitution_action, &create_anchor(), @@ -127,7 +133,8 @@ fn voting_proposal_builder_all_proposals() { let addr1 = RewardAddress::new(1, &Credential::from_keyhash(&fake_key_hash(1))); withdrawals.insert(&addr1, &Coin::from(1u32)); let withdrawal_action = TreasuryWithdrawalsAction::new(&withdrawals); - let wrapped_withdrawal_action = GovernanceAction::new_treasury_withdrawals_action(&withdrawal_action); + let wrapped_withdrawal_action = + GovernanceAction::new_treasury_withdrawals_action(&withdrawal_action); let withdrawal_proposal = VotingProposal::new( &wrapped_withdrawal_action, &create_anchor(), @@ -156,14 +163,13 @@ fn voting_proposal_builder_all_proposals() { assert_eq!(builder.get_total_deposit().unwrap(), total_deposit.clone()); let initial_amount = 1000000000u64; - let mut tx_builder = create_tx_builder_with_amount_and_deposit_params( - initial_amount, - 500, - 500, - false); + let mut tx_builder = + create_tx_builder_with_amount_and_deposit_params(initial_amount, 500, 500, false); tx_builder.set_voting_proposal_builder(&builder); - tx_builder.add_change_if_needed(&create_change_address()).unwrap(); + tx_builder + .add_change_if_needed(&create_change_address()) + .unwrap(); let tx = tx_builder.build_tx().unwrap(); @@ -209,10 +215,7 @@ fn voting_proposal_builder_with_plutus_script_witness() { ); let expected_redeemer = redeemer.clone_with_index_and_tag(&BigNum::from(1u64), &RedeemerTag::new_voting_proposal()); - let plutus_witness = PlutusWitness::new_without_datum( - &script, - &redeemer, - ); + let plutus_witness = PlutusWitness::new_without_datum(&script, &redeemer); let mut committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); @@ -227,7 +230,9 @@ fn voting_proposal_builder_with_plutus_script_witness() { &fake_reward_address(2), &proposal_deposit, ); - builder.add_with_plutus_witness(&committee_proposal, &plutus_witness).unwrap(); + builder + .add_with_plutus_witness(&committee_proposal, &plutus_witness) + .unwrap(); let witnesses = builder.get_plutus_witnesses(); assert_eq!(witnesses.len(), 1); @@ -244,14 +249,13 @@ fn voting_proposal_builder_with_plutus_script_witness() { assert_eq!(builder.get_total_deposit().unwrap(), total_deposit.clone()); let initial_amount = 1000000000u64; - let mut tx_builder = create_tx_builder_with_amount_and_deposit_params( - initial_amount, - 500, - 500, - true); + let mut tx_builder = + create_tx_builder_with_amount_and_deposit_params(initial_amount, 500, 500, true); tx_builder.set_voting_proposal_builder(&builder); - tx_builder.add_change_if_needed(&create_change_address()).unwrap(); + tx_builder + .add_change_if_needed(&create_change_address()) + .unwrap(); let mut cost_models = TxBuilderConstants::plutus_default_cost_models(); cost_models = cost_models.retain_language_versions(&Languages(vec![Language::new_plutus_v2()])); @@ -297,7 +301,7 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { let hf_action = HardForkInitiationAction::new_with_action_id(&action_id, &ProtocolVersion::new(1, 2)); let mut builder = VotingProposalBuilder::new(); - let wrapped_hf_action = GovernanceAction::new_hard_fork_initiation_action(&hf_action); + let wrapped_hf_action = GovernanceAction::new_hard_fork_initiation_action(&hf_action); let hf_proposal = VotingProposal::new( &wrapped_hf_action, &create_anchor(), @@ -316,11 +320,9 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { ); let expected_redeemer = redeemer.clone_with_index_and_tag(&BigNum::from(1u64), &RedeemerTag::new_voting_proposal()); - let plutus_source = PlutusScriptSource::new_ref_input(&script_hash, &ref_input, &Language::new_plutus_v2()); - let plutus_witness = PlutusWitness::new_with_ref_without_datum( - &plutus_source, - &redeemer, - ); + let plutus_source = + PlutusScriptSource::new_ref_input(&script_hash, &ref_input, &Language::new_plutus_v2(), 0); + let plutus_witness = PlutusWitness::new_with_ref_without_datum(&plutus_source, &redeemer); let mut committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); @@ -328,14 +330,16 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { let mut members_to_remove = Credentials::new(); members_to_remove.add(&Credential::from_keyhash(&fake_key_hash(1))); let committee_action = UpdateCommitteeAction::new(&committee, &members_to_remove); - let wrapped_committee_action= GovernanceAction::new_new_committee_action(&committee_action); + let wrapped_committee_action = GovernanceAction::new_new_committee_action(&committee_action); let committee_proposal = VotingProposal::new( &wrapped_committee_action, &create_anchor(), &fake_reward_address(2), &proposal_deposit, ); - builder.add_with_plutus_witness(&committee_proposal, &plutus_witness).unwrap(); + builder + .add_with_plutus_witness(&committee_proposal, &plutus_witness) + .unwrap(); let witnesses = builder.get_plutus_witnesses(); assert_eq!(witnesses.len(), 1); @@ -353,14 +357,13 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { assert_eq!(builder.get_total_deposit().unwrap(), total_deposit.clone()); let initial_amount = 1000000000u64; - let mut tx_builder = create_tx_builder_with_amount_and_deposit_params( - initial_amount, - 500, - 500, - true); + let mut tx_builder = + create_tx_builder_with_amount_and_deposit_params(initial_amount, 500, 500, true); tx_builder.set_voting_proposal_builder(&builder); - tx_builder.add_change_if_needed(&create_change_address()).unwrap(); + tx_builder + .add_change_if_needed(&create_change_address()) + .unwrap(); let mut cost_models = TxBuilderConstants::plutus_default_cost_models(); cost_models = cost_models.retain_language_versions(&Languages(vec![Language::new_plutus_v2()])); @@ -394,4 +397,4 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { let script_data_hash = hash_script_data(&tx_redeemers, &cost_models, None); assert_eq!(tx.body().script_data_hash(), Some(script_data_hash)); -} \ No newline at end of file +} diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index 2430ff33..a3b0cac6 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -48,9 +48,9 @@ fn asset_name_ord() { assert_eq!(name3.cmp(&name33), Ordering::Equal); let mut map = Assets::new(); - map.insert(&name2, &to_bignum(1)); - map.insert(&name1, &to_bignum(1)); - map.insert(&name3, &to_bignum(1)); + map.insert(&name2, &BigNum(1)); + map.insert(&name1, &BigNum(1)); + map.insert(&name3, &BigNum(1)); assert_eq!(map.keys(), AssetNames(vec![name3, name1, name2])); @@ -265,7 +265,7 @@ fn protocol_params_update_cbor_roundtrip() { orig_ppu.set_pool_deposit(&Coin::from(4u32)); orig_ppu.set_max_epoch(5); orig_ppu.set_n_opt(6); - orig_ppu.set_pool_pledge_influence(&Rational::new(&BigNum::from(7u32), &BigNum::from(77u32))); + orig_ppu.set_pool_pledge_influence(&UnitInterval::new(&BigNum::from(7u32), &BigNum::from(77u32))); orig_ppu.set_expansion_rate(&UnitInterval::new(&BigNum::from(8u32), &BigNum::from(9u32))); orig_ppu.set_treasury_growth_rate(&UnitInterval::new( &BigNum::from(10u32), @@ -404,3 +404,19 @@ fn witnesses_deduplication_test(){ assert_eq!(roundtrip_plutus_data.get(0), datum_1); assert_eq!(roundtrip_plutus_data.get(1), datum_2); } + +#[test] +fn min_ref_script_fee_test(){ + let cost = UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32)); + let total_size = 500; + let min_fee = min_ref_script_fee(total_size, &cost).unwrap(); + assert_eq!(min_fee, BigNum(250)); +} + +#[test] +fn min_ref_script_fee_test_fail(){ + let cost = UnitInterval::new(&BigNum::from(1u32), &BigNum::from(0u32)); + let total_size = 500; + let min_fee = min_ref_script_fee(total_size, &cost); + assert!(min_fee.is_err()); +} diff --git a/rust/src/tests/metadata.rs b/rust/src/tests/metadata.rs index b429ae8e..6bcce071 100644 --- a/rust/src/tests/metadata.rs +++ b/rust/src/tests/metadata.rs @@ -201,7 +201,7 @@ fn json_encoding_detailed_complex_key() { fn metadata_serialize() { let mut gmd = GeneralTransactionMetadata::new(); let mdatum = TransactionMetadatum::new_text(String::from("string md")).unwrap(); - gmd.insert(&to_bignum(100), &mdatum); + gmd.insert(&BigNum(100), &mdatum); let mut aux_data = AuxiliaryData::new(); // alonzo (empty) let ad0_deser = AuxiliaryData::from_bytes(aux_data.to_bytes()).unwrap(); @@ -249,7 +249,7 @@ fn test_auxiliary_data_roundtrip() { let mut aux = AuxiliaryData::new(); let mut metadata = GeneralTransactionMetadata::new(); metadata.insert( - &to_bignum(42), + &BigNum(42), &encode_json_str_to_metadatum( "{ \"test\": 148 }".to_string(), MetadataJsonSchema::BasicConversions, diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/mock_objects.rs index ffed60d6..299919ac 100644 --- a/rust/src/tests/mock_objects.rs +++ b/rust/src/tests/mock_objects.rs @@ -64,7 +64,7 @@ pub(crate) fn crate_full_protocol_param_update() -> ProtocolParamUpdate { pool_deposit: Some(Coin::from(44_444u32)), max_epoch: Some(44_444u32), n_opt: Some(44_444u32), - pool_pledge_influence: Some(Rational::new( + pool_pledge_influence: Some(UnitInterval::new( &BigNum::from(44_444u32), &BigNum::from(44_444u32), )), @@ -86,11 +86,11 @@ pub(crate) fn crate_full_protocol_param_update() -> ProtocolParamUpdate { ada_per_utxo_byte: Some(Coin::from(44_444u32)), cost_models: Some(create_cost_models()), execution_costs: Some(ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + &SubCoin::new(&BigNum(577), &BigNum(10000)), + &SubCoin::new(&BigNum(721), &BigNum(10000000)), )), - max_tx_ex_units: Some(ExUnits::new(&to_bignum(842996), &to_bignum(246100241))), - max_block_ex_units: Some(ExUnits::new(&to_bignum(842996), &to_bignum(246100241))), + max_tx_ex_units: Some(ExUnits::new(&BigNum(842996), &BigNum(246100241))), + max_block_ex_units: Some(ExUnits::new(&BigNum(842996), &BigNum(246100241))), max_value_size: Some(44_444u32), collateral_percentage: Some(44_444u32), max_collateral_inputs: Some(44_444u32), @@ -102,7 +102,10 @@ pub(crate) fn crate_full_protocol_param_update() -> ProtocolParamUpdate { governance_action_deposit: Some(Coin::from(44_444u32)), drep_deposit: Some(Coin::from(44_444u32)), drep_inactivity_period: Some(44_444u32), - ref_script_coins_per_byte: Some(Coin::from(44_444u32)), + ref_script_coins_per_byte: Some(UnitInterval::new( + &BigNum::from(44_444u32), + &BigNum::from(44_444u32), + )), } } @@ -188,7 +191,7 @@ pub(crate) fn byron_address() -> Address { } pub(crate) fn create_linear_fee(coefficient: u64, constant: u64) -> LinearFee { - LinearFee::new(&to_bignum(coefficient), &to_bignum(constant)) + LinearFee::new(&BigNum(coefficient), &BigNum(constant)) } pub(crate) fn create_default_linear_fee() -> LinearFee { @@ -204,15 +207,18 @@ pub(crate) fn create_tx_builder_full( ) -> TransactionBuilder { let cfg = TransactionBuilderConfigBuilder::new() .fee_algo(linear_fee) - .pool_deposit(&to_bignum(pool_deposit)) - .key_deposit(&to_bignum(key_deposit)) + .pool_deposit(&BigNum(pool_deposit)) + .key_deposit(&BigNum(key_deposit)) .max_value_size(max_val_size) .max_tx_size(MAX_TX_SIZE) - .coins_per_utxo_byte(&to_bignum(coins_per_utxo_byte)) + .coins_per_utxo_byte(&BigNum(coins_per_utxo_byte)) .ex_unit_prices(&ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + &SubCoin::new(&BigNum(577), &BigNum(10000)), + &SubCoin::new(&BigNum(721), &BigNum(10000000)), )) + .ref_script_coins_per_byte( + &UnitInterval::new(&BigNum(1), &BigNum(2)), + ) .build() .unwrap(); TransactionBuilder::new(&cfg) @@ -259,11 +265,11 @@ pub(crate) fn create_tx_builder_with_fee_and_pure_change( TransactionBuilder::new( &TransactionBuilderConfigBuilder::new() .fee_algo(linear_fee) - .pool_deposit(&to_bignum(1)) - .key_deposit(&to_bignum(1)) + .pool_deposit(&BigNum(1)) + .key_deposit(&BigNum(1)) .max_value_size(MAX_VALUE_SIZE) .max_tx_size(MAX_TX_SIZE) - .coins_per_utxo_byte(&to_bignum(1)) + .coins_per_utxo_byte(&BigNum(1)) .prefer_pure_change(true) .build() .unwrap(), @@ -369,4 +375,22 @@ pub(crate) fn create_plutus_script(x: u8, lang: &Language) -> PlutusScript { let pos = bytes.len() - 1; bytes[pos] = x; PlutusScript::from_bytes_with_version(bytes, lang).unwrap() +} + +pub(crate) fn create_redeemer(x: u8) -> Redeemer { + Redeemer::new( + &RedeemerTag::new_cert(), + &BigNum::from(x as u64), + &PlutusData::new_empty_constr_plutus_data(&BigNum::from(x)), + &ExUnits::new(&BigNum::from(x), &BigNum::from(x)), + ) +} + +pub(crate) fn create_redeemer_zero_cost(x: u8) -> Redeemer { + Redeemer::new( + &RedeemerTag::new_cert(), + &BigNum::from(x as u64), + &PlutusData::new_empty_constr_plutus_data(&BigNum::from(x)), + &ExUnits::new(&BigNum::zero(), &BigNum::zero()), + ) } \ No newline at end of file diff --git a/rust/src/tests/plutus.rs b/rust/src/tests/plutus.rs index 601b0621..98aa072a 100644 --- a/rust/src/tests/plutus.rs +++ b/rust/src/tests/plutus.rs @@ -4,7 +4,7 @@ use hex::*; #[test] pub fn plutus_constr_data() { let constr_0 = PlutusData::new_constr_plutus_data(&ConstrPlutusData::new( - &to_bignum(0), + &BigNum(0), &PlutusList::new(), )); let constr_0_hash = hex::encode(hash_plutus_data(&constr_0).to_bytes()); @@ -16,7 +16,7 @@ pub fn plutus_constr_data() { // TODO: do we want semantic equality or bytewise equality? // assert_eq!(constr_0, constr_0_roundtrip); // let constr_1854 = PlutusData::new_constr_plutus_data( - // &ConstrPlutusData::new(&to_bignum(1854), &PlutusList::new()) + // &ConstrPlutusData::new(&BigNum(1854), &PlutusList::new()) // ); // let constr_1854_roundtrip = PlutusData::from_bytes(constr_1854.to_bytes()).unwrap(); // assert_eq!(constr_1854, constr_1854_roundtrip); @@ -147,7 +147,7 @@ pub fn plutus_datum_from_json_detailed() { assert_eq!(bytes, [202, 254, 208, 13]); // constr data let constr = list.get(2).as_constr_plutus_data().unwrap(); - assert_eq!(to_bignum(0), constr.alternative()); + assert_eq!(BigNum(0), constr.alternative()); let fields = constr.data(); assert_eq!(fields.len(), 2); let field0 = fields.get(0).as_map().unwrap(); @@ -237,15 +237,15 @@ fn test_total_ex_units() { let mut r = Redeemers::new(); fn assert_ex_units(eu: &ExUnits, exp_mem: u64, exp_steps: u64) { - assert_eq!(eu.mem, to_bignum(exp_mem)); - assert_eq!(eu.steps, to_bignum(exp_steps)); + assert_eq!(eu.mem, BigNum(exp_mem)); + assert_eq!(eu.steps, BigNum(exp_steps)); } - r.add(&redeemer_with_ex_units(&to_bignum(10), &to_bignum(100))); + r.add(&redeemer_with_ex_units(&BigNum(10), &BigNum(100))); assert_ex_units(&r.total_ex_units().unwrap(), 10, 100); - r.add(&redeemer_with_ex_units(&to_bignum(20), &to_bignum(200))); + r.add(&redeemer_with_ex_units(&BigNum(20), &BigNum(200))); assert_ex_units(&r.total_ex_units().unwrap(), 30, 300); - r.add(&redeemer_with_ex_units(&to_bignum(30), &to_bignum(300))); + r.add(&redeemer_with_ex_units(&BigNum(30), &BigNum(300))); assert_ex_units(&r.total_ex_units().unwrap(), 60, 600); } @@ -374,7 +374,7 @@ fn test_known_plutus_data_hash() { &RedeemerTag::new_spend(), &BigNum::one(), &PlutusData::new_empty_constr_plutus_data(&BigNum::zero()), - &ExUnits::new(&to_bignum(7000000), &to_bignum(3000000000)), + &ExUnits::new(&BigNum(7000000), &BigNum(3000000000)), )]); let lang = Language::new_plutus_v1(); let lang_costmodel = TxBuilderConstants::plutus_vasil_cost_models() @@ -420,7 +420,7 @@ fn test_known_plutus_data_hash_with_no_datums() { &RedeemerTag::new_spend(), &BigNum::zero(), &PlutusData::new_empty_constr_plutus_data(&BigNum::zero()), - &ExUnits::new(&to_bignum(842996), &to_bignum(246100241)), + &ExUnits::new(&BigNum(842996), &BigNum(246100241)), )]), &costmodels, None, @@ -454,7 +454,7 @@ fn test_known_plutus_data_hash_2() { &RedeemerTag::new_spend(), &BigNum::one(), &PlutusData::new_empty_constr_plutus_data(&BigNum::one()), - &ExUnits::new(&to_bignum(61300), &to_bignum(18221176)), + &ExUnits::new(&BigNum(61300), &BigNum(18221176)), )]); let hash = hash_script_data( &redeemers, diff --git a/rust/src/tests/serialization/general.rs b/rust/src/tests/serialization/general.rs index 5240f281..2b7f678a 100644 --- a/rust/src/tests/serialization/general.rs +++ b/rust/src/tests/serialization/general.rs @@ -1,5 +1,5 @@ use crate::{ - to_bignum, Address, BigInt, BigNum, Block, BlockHash, CborContainerType, Coin, Credential, + Address, BigInt, BigNum, Block, BlockHash, CborContainerType, Coin, Credential, DataHash, ExUnits, HeaderBody, HeaderLeaderCertEnum, Int, KESVKey, MIRPot, MIRToStakeCredentials, MoveInstantaneousReward, NativeScript, OperationalCert, PlutusData, PlutusList, PlutusScript, PlutusScripts, ProtocolVersion, Redeemer, RedeemerTag, Redeemers, @@ -454,12 +454,12 @@ fn test_tx_body_roundtrip() { let mut txb = TransactionBody::new( &TransactionInputs(vec![fake_tx_input(0)]), &TransactionOutputs(vec![fake_tx_output(1)]), - &to_bignum(1234567), + &BigNum(1234567), Some(12345678), ); txb.set_collateral_return(&fake_tx_output(2)); - txb.set_total_collateral(&to_bignum(1234)); + txb.set_total_collateral(&BigNum(1234)); let txb2 = TransactionBody::from_bytes(txb.to_bytes()).unwrap(); assert_eq!(txb, txb2); @@ -470,7 +470,7 @@ fn test_header_body_roundtrip() { fn fake_header_body(leader_cert: HeaderLeaderCertEnum) -> HeaderBody { HeaderBody { block_number: 123, - slot: to_bignum(123), + slot: BigNum(123), prev_hash: Some(BlockHash::from_bytes(fake_bytes_32(1)).unwrap()), issuer_vkey: fake_vkey(), vrf_vkey: VRFVKey::from_bytes(fake_bytes_32(2)).unwrap(), @@ -511,9 +511,9 @@ fn test_witness_set_roundtrip() { )])); ws.set_redeemers(&Redeemers::from(vec![Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(12), + &BigNum(12), &PlutusData::new_integer(&BigInt::one()), - &ExUnits::new(&to_bignum(123), &to_bignum(456)), + &ExUnits::new(&BigNum(123), &BigNum(456)), )])); ws.set_plutus_data(&PlutusList::from(vec![PlutusData::new_integer( &BigInt::one(), @@ -578,7 +578,7 @@ fn legacy_output_roundtrip() { #[test] fn babbage_output_roundtrip() { let mut o1 = TransactionOutput::new(&fake_base_address(0), &fake_value2(234567)); - o1.set_plutus_data(&PlutusData::new_empty_constr_plutus_data(&to_bignum(42))); + o1.set_plutus_data(&PlutusData::new_empty_constr_plutus_data(&BigNum(42))); assert_eq!(TransactionOutput::from_bytes(o1.to_bytes()).unwrap(), o1); let mut o2 = TransactionOutput::new(&fake_base_address(1), &fake_value2(234568)); @@ -601,7 +601,7 @@ fn babbage_output_roundtrip() { assert_eq!(TransactionOutput::from_bytes(o4.to_bytes()).unwrap(), o4); let mut o5 = TransactionOutput::new(&fake_base_address(4), &fake_value2(234571)); - o5.set_plutus_data(&PlutusData::new_empty_constr_plutus_data(&to_bignum(43))); + o5.set_plutus_data(&PlutusData::new_empty_constr_plutus_data(&BigNum(43))); o5.set_script_ref(&ScriptRef::new_plutus_script(&script_v2)); assert_eq!(TransactionOutput::from_bytes(o5.to_bytes()).unwrap(), o5); @@ -648,15 +648,15 @@ fn redeemers_default_array_round_trip() { let mut redeemers = Redeemers::from(vec![ Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(12), + &BigNum(12), &PlutusData::new_integer(&BigInt::one()), - &ExUnits::new(&to_bignum(123), &to_bignum(456)), + &ExUnits::new(&BigNum(123), &BigNum(456)), ), Redeemer::new( &RedeemerTag::new_cert(), - &to_bignum(2), + &BigNum(2), &PlutusData::new_integer(&BigInt::from(22)), - &ExUnits::new(&to_bignum(23), &to_bignum(45)), + &ExUnits::new(&BigNum(23), &BigNum(45)), ) ]); @@ -674,15 +674,15 @@ fn redeemers_array_round_trip() { let redeemers_vec = vec![ Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(12), + &BigNum(12), &PlutusData::new_integer(&BigInt::one()), - &ExUnits::new(&to_bignum(123), &to_bignum(456)), + &ExUnits::new(&BigNum(123), &BigNum(456)), ), Redeemer::new( &RedeemerTag::new_cert(), - &to_bignum(2), + &BigNum(2), &PlutusData::new_integer(&BigInt::from(22)), - &ExUnits::new(&to_bignum(23), &to_bignum(45)), + &ExUnits::new(&BigNum(23), &BigNum(45)), ) ]; @@ -701,15 +701,15 @@ fn redeemers_map_round_trip() { let redeemers_vec = vec![ Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(12), + &BigNum(12), &PlutusData::new_integer(&BigInt::one()), - &ExUnits::new(&to_bignum(123), &to_bignum(456)), + &ExUnits::new(&BigNum(123), &BigNum(456)), ), Redeemer::new( &RedeemerTag::new_cert(), - &to_bignum(2), + &BigNum(2), &PlutusData::new_integer(&BigInt::from(22)), - &ExUnits::new(&to_bignum(23), &to_bignum(45)), + &ExUnits::new(&BigNum(23), &BigNum(45)), ) ]; @@ -728,15 +728,15 @@ fn redeemers_map_array_round_trip() { let redeemers_vec = vec![ Redeemer::new( &RedeemerTag::new_spend(), - &to_bignum(12), + &BigNum(12), &PlutusData::new_integer(&BigInt::one()), - &ExUnits::new(&to_bignum(123), &to_bignum(456)), + &ExUnits::new(&BigNum(123), &BigNum(456)), ), Redeemer::new( &RedeemerTag::new_cert(), - &to_bignum(2), + &BigNum(2), &PlutusData::new_integer(&BigInt::from(22)), - &ExUnits::new(&to_bignum(23), &to_bignum(45)), + &ExUnits::new(&BigNum(23), &BigNum(45)), ) ]; diff --git a/rust/src/tests/serialization/protocol_param_update.rs b/rust/src/tests/serialization/protocol_param_update.rs index 19b73436..ef8399e1 100644 --- a/rust/src/tests/serialization/protocol_param_update.rs +++ b/rust/src/tests/serialization/protocol_param_update.rs @@ -13,7 +13,7 @@ fn protocol_param_update_ser_round_trip() { pool_deposit: Some(Coin::from(7_444u32)), max_epoch: Some(8_444u32), n_opt: Some(9_444u32), - pool_pledge_influence: Some(Rational::new( + pool_pledge_influence: Some(UnitInterval::new( &BigNum::from(10_444u32), &BigNum::from(11_444u32), )), @@ -35,11 +35,11 @@ fn protocol_param_update_ser_round_trip() { ada_per_utxo_byte: Some(Coin::from(19_444u32)), cost_models: Some(create_cost_models()), execution_costs: Some(ExUnitPrices::new( - &SubCoin::new(&to_bignum(577), &to_bignum(10000)), - &SubCoin::new(&to_bignum(721), &to_bignum(10000000)), + &SubCoin::new(&BigNum(577), &BigNum(10000)), + &SubCoin::new(&BigNum(721), &BigNum(10000000)), )), - max_tx_ex_units: Some(ExUnits::new(&to_bignum(842996), &to_bignum(246100241))), - max_block_ex_units: Some(ExUnits::new(&to_bignum(842996), &to_bignum(246100241))), + max_tx_ex_units: Some(ExUnits::new(&BigNum(842996), &BigNum(246100241))), + max_block_ex_units: Some(ExUnits::new(&BigNum(842996), &BigNum(246100241))), max_value_size: Some(20_444u32), collateral_percentage: Some(21_444u32), max_collateral_inputs: Some(22_444u32), @@ -51,7 +51,10 @@ fn protocol_param_update_ser_round_trip() { governance_action_deposit: Some(Coin::from(26_444u32)), drep_deposit: Some(Coin::from(27_444u32)), drep_inactivity_period: Some(28_444u32), - ref_script_coins_per_byte: Some(Coin::from(29_444u32)), + ref_script_coins_per_byte: Some(UnitInterval::new( + &BigNum::from(29_444u32), + &BigNum::from(30_444u32), + )), }; let cbor = pp_update.to_bytes(); diff --git a/rust/src/tests/serialization/transaction_body.rs b/rust/src/tests/serialization/transaction_body.rs index c46850e1..466e7fcb 100644 --- a/rust/src/tests/serialization/transaction_body.rs +++ b/rust/src/tests/serialization/transaction_body.rs @@ -5,14 +5,14 @@ use crate::tests::mock_objects::create_anchor; #[test] fn transaction_round_trip_test() { let input = fake_tx_input(1); - let output = TransactionOutput::new(&fake_base_address(2), &Value::new(&to_bignum(1_000_001))); + let output = TransactionOutput::new(&fake_base_address(2), &Value::new(&BigNum(1_000_001))); let inputs = TransactionInputs(vec![input]); let outputs = TransactionOutputs(vec![output]); let fee = Coin::from(1_000_002u64); let mut body = TransactionBody::new_tx_body(&inputs, &outputs, &fee); let mut mint = Mint::new(); let mint_asset = - MintAssets::new_from_entry(&fake_asset_name(4), &Int::new(&to_bignum(1_000_003u64))) + MintAssets::new_from_entry(&fake_asset_name(4), &Int::new(&BigNum(1_000_003u64))) .unwrap(); mint.insert(&fake_policy_id(3), &mint_asset); @@ -55,7 +55,7 @@ fn transaction_round_trip_test() { ); voting_proposals.add(&proposal); - body.set_ttl(&to_bignum(1_000_003u64)); + body.set_ttl(&BigNum(1_000_003u64)); body.set_certs(&certs); body.set_withdrawals(&withdrawals); body.set_update(&Update::new(&ProposedProtocolParameterUpdates::new(), 1)); @@ -69,7 +69,7 @@ fn transaction_round_trip_test() { body.set_network_id(&NetworkId::testnet()); body.set_collateral_return(&TransactionOutput::new( &fake_base_address(4), - &Value::new(&to_bignum(1_000_005u64)), + &Value::new(&BigNum(1_000_005u64)), )); body.set_total_collateral(&Coin::from(1_000_006u64)); body.set_voting_procedures(&voting_procedures); diff --git a/rust/src/utils.rs b/rust/src/utils.rs index c09ae7c0..614a38ff 100644 --- a/rust/src/utils.rs +++ b/rust/src/utils.rs @@ -148,223 +148,6 @@ impl<'a> IntoIterator for &'a TransactionUnspentOutputs { } } -// Generic u64 wrapper for platforms that don't support u64 or BigInt/etc -// This is an unsigned type - no negative numbers. -// Can be converted to/from plain rust -#[wasm_bindgen] -#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Default)] -pub struct BigNum(u64); - -impl_to_from!(BigNum); - -impl std::fmt::Display for BigNum { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - -#[wasm_bindgen] -impl BigNum { - // Create a BigNum from a standard rust string representation - pub fn from_str(string: &str) -> Result { - string - .parse::() - .map_err(|e| JsError::from_str(&format! {"{:?}", e})) - .map(BigNum) - } - - // String representation of the BigNum value for use from environments that don't support BigInt - pub fn to_str(&self) -> String { - format!("{}", self.0) - } - - pub fn zero() -> Self { - Self(0) - } - - pub fn one() -> Self { - Self(1) - } - - pub fn is_zero(&self) -> bool { - self.0 == 0 - } - - pub fn div_floor(&self, other: &BigNum) -> BigNum { - // same as (a / b) - let res = self.0.div(&other.0); - Self(res) - } - - pub fn checked_mul(&self, other: &BigNum) -> Result { - match self.0.checked_mul(other.0) { - Some(value) => Ok(BigNum(value)), - None => Err(JsError::from_str("overflow")), - } - } - - pub fn checked_add(&self, other: &BigNum) -> Result { - match self.0.checked_add(other.0) { - Some(value) => Ok(BigNum(value)), - None => Err(JsError::from_str("overflow")), - } - } - - pub fn checked_sub(&self, other: &BigNum) -> Result { - match self.0.checked_sub(other.0) { - Some(value) => Ok(BigNum(value)), - None => Err(JsError::from_str("underflow")), - } - } - - /// returns 0 if it would otherwise underflow - pub fn clamped_sub(&self, other: &BigNum) -> BigNum { - match self.0.checked_sub(other.0) { - Some(value) => BigNum(value), - None => BigNum(0), - } - } - - pub fn compare(&self, rhs_value: &BigNum) -> i8 { - match self.cmp(&rhs_value) { - std::cmp::Ordering::Equal => 0, - std::cmp::Ordering::Less => -1, - std::cmp::Ordering::Greater => 1, - } - } - - pub fn less_than(&self, rhs_value: &BigNum) -> bool { - self.compare(rhs_value) < 0 - } - - pub fn max_value() -> BigNum { - BigNum(u64::max_value()) - } - - pub fn max(a: &BigNum, b: &BigNum) -> BigNum { - if a.less_than(b) { - b.clone() - } else { - a.clone() - } - } -} - -impl TryFrom for u32 { - type Error = JsError; - - fn try_from(value: BigNum) -> Result { - if value.0 > u32::MAX.into() { - Err(JsError::from_str(&format!( - "Value {} is bigger than max u32 {}", - value.0, - u32::MAX - ))) - } else { - Ok(value.0 as u32) - } - } -} - -impl From for u64 { - fn from(value: BigNum) -> Self { - value.0 - } -} - -impl From for usize { - fn from(value: BigNum) -> Self { - value.0 as usize - } -} - -impl From for BigNum { - fn from(value: u64) -> Self { - return BigNum(value); - } -} - -impl From for BigNum { - fn from(value: usize) -> Self { - return BigNum(value as u64); - } -} - -impl From for BigNum { - fn from(value: u32) -> Self { - return BigNum(value.into()); - } -} - -impl cbor_event::se::Serialize for BigNum { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_unsigned_integer(self.0) - } -} - -impl Deserialize for BigNum { - fn deserialize(raw: &mut Deserializer) -> Result { - match raw.unsigned_integer() { - Ok(value) => Ok(Self(value)), - Err(e) => Err(DeserializeError::new("BigNum", DeserializeFailure::CBOR(e))), - } - } -} - -impl serde::Serialize for BigNum { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - serializer.serialize_str(&self.to_str()) - } -} - -impl<'de> serde::de::Deserialize<'de> for BigNum { - fn deserialize(deserializer: D) -> Result - where - D: serde::de::Deserializer<'de>, - { - let s = ::deserialize(deserializer)?; - Self::from_str(&s).map_err(|_e| { - serde::de::Error::invalid_value( - serde::de::Unexpected::Str(&s), - &"string rep of a number", - ) - }) - } -} - -impl JsonSchema for BigNum { - fn schema_name() -> String { - String::from("BigNum") - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - String::json_schema(gen) - } - fn is_referenceable() -> bool { - String::is_referenceable() - } -} - -pub fn to_bignum(val: u64) -> BigNum { - BigNum(val) -} - -pub fn from_bignum(val: &BigNum) -> u64 { - val.0 -} - -pub fn to_bigint(val: u64) -> BigInt { - BigInt::from_str(&val.to_string()).unwrap() -} - -// Specifies an amount of ADA in terms of lovelace -pub type Coin = BigNum; - #[wasm_bindgen] #[derive( Clone, @@ -622,188 +405,6 @@ impl Deserialize for Value { } } -// CBOR has int = uint / nint -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub struct Int(pub(crate) i128); - -impl_to_from!(Int); - -#[wasm_bindgen] -impl Int { - pub fn new(x: &BigNum) -> Self { - Self(x.0 as i128) - } - - pub fn new_negative(x: &BigNum) -> Self { - Self(-(x.0 as i128)) - } - - pub fn new_i32(x: i32) -> Self { - Self(x as i128) - } - - pub fn is_positive(&self) -> bool { - return self.0 >= 0; - } - - /// BigNum can only contain unsigned u64 values - /// - /// This function will return the BigNum representation - /// only in case the underlying i128 value is positive. - /// - /// Otherwise nothing will be returned (undefined). - pub fn as_positive(&self) -> Option { - if self.is_positive() { - Some(to_bignum(self.0 as u64)) - } else { - None - } - } - - /// BigNum can only contain unsigned u64 values - /// - /// This function will return the *absolute* BigNum representation - /// only in case the underlying i128 value is negative. - /// - /// Otherwise nothing will be returned (undefined). - pub fn as_negative(&self) -> Option { - if !self.is_positive() { - Some(to_bignum((-self.0) as u64)) - } else { - None - } - } - - /// !!! DEPRECATED !!! - /// Returns an i32 value in case the underlying original i128 value is within the limits. - /// Otherwise will just return an empty value (undefined). - #[deprecated( - since = "10.0.0", - note = "Unsafe ignoring of possible boundary error and it's not clear from the function name. Use `as_i32_or_nothing`, `as_i32_or_fail`, or `to_str`" - )] - pub fn as_i32(&self) -> Option { - self.as_i32_or_nothing() - } - - /// Returns the underlying value converted to i32 if possible (within limits) - /// Otherwise will just return an empty value (undefined). - pub fn as_i32_or_nothing(&self) -> Option { - use std::convert::TryFrom; - i32::try_from(self.0).ok() - } - - /// Returns the underlying value converted to i32 if possible (within limits) - /// JsError in case of out of boundary overflow - pub fn as_i32_or_fail(&self) -> Result { - use std::convert::TryFrom; - i32::try_from(self.0).map_err(|e| JsError::from_str(&format!("{}", e))) - } - - /// Returns string representation of the underlying i128 value directly. - /// Might contain the minus sign (-) in case of negative value. - pub fn to_str(&self) -> String { - format!("{}", self.0) - } - - // Create an Int from a standard rust string representation - pub fn from_str(string: &str) -> Result { - let x = string - .parse::() - .map_err(|e| JsError::from_str(&format! {"{:?}", e}))?; - if x.abs() > u64::MAX as i128 { - return Err(JsError::from_str(&format!( - "{} out of bounds. Value (without sign) must fit within 4 bytes limit of {}", - x, - u64::MAX - ))); - } - Ok(Self(x)) - } -} - -impl cbor_event::se::Serialize for Int { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - if self.0 < 0 { - serializer.write_negative_integer(self.0 as i64) - } else { - serializer.write_unsigned_integer(self.0 as u64) - } - } -} - -impl Deserialize for Int { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - match raw.cbor_type()? { - cbor_event::Type::UnsignedInteger => Ok(Self(raw.unsigned_integer()? as i128)), - cbor_event::Type::NegativeInteger => Ok(Self(read_nint(raw)?)), - _ => Err(DeserializeFailure::NoVariantMatched.into()), - } - })() - .map_err(|e| e.annotate("Int")) - } -} - -impl serde::Serialize for Int { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - serializer.serialize_str(&self.to_str()) - } -} - -impl<'de> serde::de::Deserialize<'de> for Int { - fn deserialize(deserializer: D) -> Result - where - D: serde::de::Deserializer<'de>, - { - let s = ::deserialize(deserializer)?; - Self::from_str(&s).map_err(|_e| { - serde::de::Error::invalid_value( - serde::de::Unexpected::Str(&s), - &"string rep of a number", - ) - }) - } -} - -impl JsonSchema for Int { - fn schema_name() -> String { - String::from("Int") - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - String::json_schema(gen) - } - fn is_referenceable() -> bool { - String::is_referenceable() - } -} - -/// TODO: this function can be removed in case `cbor_event` library ever gets a fix on their side -/// See https://github.com/Emurgo/cardano-serialization-lib/pull/392 -fn read_nint(raw: &mut Deserializer) -> Result { - let found = raw.cbor_type()?; - if found != cbor_event::Type::NegativeInteger { - return Err(cbor_event::Error::Expected(cbor_event::Type::NegativeInteger, found).into()); - } - let (len, len_sz) = raw.cbor_len()?; - match len { - cbor_event::Len::Indefinite => Err(cbor_event::Error::IndefiniteLenNotSupported( - cbor_event::Type::NegativeInteger, - ) - .into()), - cbor_event::Len::Len(v) => { - raw.advance(1 + len_sz)?; - Ok(-(v as i128) - 1) - } - } -} - const BOUNDED_BYTES_CHUNK_SIZE: usize = 64; pub(crate) fn write_bounded_bytes<'se, W: Write>( @@ -895,234 +496,6 @@ pub(crate) fn read_bounded_bytes( } } -#[wasm_bindgen] -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] -pub struct BigInt(num_bigint::BigInt); - -impl_to_from!(BigInt); - -impl serde::Serialize for BigInt { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - serializer.serialize_str(&self.to_str()) - } -} - -impl<'de> serde::de::Deserialize<'de> for BigInt { - fn deserialize(deserializer: D) -> Result - where - D: serde::de::Deserializer<'de>, - { - let s = ::deserialize(deserializer)?; - BigInt::from_str(&s).map_err(|_e| { - serde::de::Error::invalid_value( - serde::de::Unexpected::Str(&s), - &"string rep of a big int", - ) - }) - } -} - -impl JsonSchema for BigInt { - fn schema_name() -> String { - String::from("BigInt") - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - String::json_schema(gen) - } - fn is_referenceable() -> bool { - String::is_referenceable() - } -} - -#[wasm_bindgen] -impl BigInt { - pub fn is_zero(&self) -> bool { - self.0.sign() == Sign::NoSign - } - - pub fn as_u64(&self) -> Option { - let (sign, u64_digits) = self.0.to_u64_digits(); - if sign == num_bigint::Sign::Minus { - return None; - } - match u64_digits.len() { - 0 => Some(to_bignum(0)), - 1 => Some(to_bignum(*u64_digits.first().unwrap())), - _ => None, - } - } - - pub fn as_int(&self) -> Option { - let (sign, u64_digits) = self.0.to_u64_digits(); - let u64_digit = match u64_digits.len() { - 0 => Some(to_bignum(0)), - 1 => Some(to_bignum(*u64_digits.first().unwrap())), - _ => None, - }?; - match sign { - num_bigint::Sign::NoSign | num_bigint::Sign::Plus => Some(Int::new(&u64_digit)), - num_bigint::Sign::Minus => Some(Int::new_negative(&u64_digit)), - } - } - - pub fn from_str(text: &str) -> Result { - use std::str::FromStr; - num_bigint::BigInt::from_str(text) - .map_err(|e| JsError::from_str(&format! {"{:?}", e})) - .map(Self) - } - - pub fn to_str(&self) -> String { - self.0.to_string() - } - - pub fn add(&self, other: &BigInt) -> BigInt { - Self(&self.0 + &other.0) - } - - pub fn mul(&self, other: &BigInt) -> BigInt { - Self(&self.0 * &other.0) - } - - pub fn one() -> BigInt { - use std::str::FromStr; - Self(num_bigint::BigInt::from_str("1").unwrap()) - } - - pub fn increment(&self) -> BigInt { - self.add(&Self::one()) - } - - pub fn div_ceil(&self, other: &BigInt) -> BigInt { - use num_integer::Integer; - let (res, rem) = self.0.div_rem(&other.0); - let result = Self(res); - if Self(rem).is_zero() { - result - } else { - result.increment() - } - } -} - -impl cbor_event::se::Serialize for BigInt { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - let (sign, u64_digits) = self.0.to_u64_digits(); - match u64_digits.len() { - 0 => serializer.write_unsigned_integer(0), - // we use the uint/nint encodings to use a minimum of space - 1 => match sign { - // uint - num_bigint::Sign::Plus | num_bigint::Sign::NoSign => { - serializer.write_unsigned_integer(*u64_digits.first().unwrap()) - } - // nint - num_bigint::Sign::Minus => serializer - .write_negative_integer(-(*u64_digits.first().unwrap() as i128) as i64), - }, - _ => { - // Small edge case: nint's minimum is -18446744073709551616 but in this bigint lib - // that takes 2 u64 bytes so we put that as a special case here: - if sign == num_bigint::Sign::Minus && u64_digits == vec![0, 1] { - serializer.write_negative_integer(-18446744073709551616i128 as i64) - } else { - let (sign, bytes) = self.0.to_bytes_be(); - match sign { - // positive bigint - num_bigint::Sign::Plus | num_bigint::Sign::NoSign => { - serializer.write_tag(2u64)?; - write_bounded_bytes(serializer, &bytes) - } - // negative bigint - num_bigint::Sign::Minus => { - serializer.write_tag(3u64)?; - use std::ops::Neg; - // CBOR RFC defines this as the bytes of -n -1 - let adjusted = self - .0 - .clone() - .neg() - .checked_sub(&num_bigint::BigInt::from(1u32)) - .unwrap() - .to_biguint() - .unwrap(); - write_bounded_bytes(serializer, &adjusted.to_bytes_be()) - } - } - } - } - } - } -} - -impl Deserialize for BigInt { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - match raw.cbor_type()? { - // bigint - CBORType::Tag => { - let tag = raw.tag()?; - let bytes = read_bounded_bytes(raw)?; - match tag { - // positive bigint - 2 => Ok(Self(num_bigint::BigInt::from_bytes_be( - num_bigint::Sign::Plus, - &bytes, - ))), - // negative bigint - 3 => { - // CBOR RFC defines this as the bytes of -n -1 - let initial = - num_bigint::BigInt::from_bytes_be(num_bigint::Sign::Plus, &bytes); - use std::ops::Neg; - let adjusted = initial - .checked_add(&num_bigint::BigInt::from(1u32)) - .unwrap() - .neg(); - Ok(Self(adjusted)) - } - _ => { - return Err(DeserializeFailure::TagMismatch { - found: tag, - expected: 2, - } - .into()); - } - } - } - // uint - CBORType::UnsignedInteger => { - Ok(Self(num_bigint::BigInt::from(raw.unsigned_integer()?))) - } - // nint - CBORType::NegativeInteger => Ok(Self(num_bigint::BigInt::from(read_nint(raw)?))), - _ => return Err(DeserializeFailure::NoVariantMatched.into()), - } - })() - .map_err(|e| e.annotate("BigInt")) - } -} - -impl std::convert::From for BigInt -where - T: std::convert::Into, -{ - fn from(x: T) -> Self { - Self(x.into()) - } -} - -impl From for BigInt { - fn from(x: BigNum) -> Self { - Self(x.0.into()) - } -} pub struct CBORReadLen { deser_len: cbor_event::Len, @@ -1264,20 +637,20 @@ pub fn internal_get_implicit_input( key_deposit: &BigNum, // protocol parameter ) -> Result { let withdrawal_sum = match &withdrawals { - None => to_bignum(0), + None => BigNum::zero(), Some(x) => { x.0.values() - .try_fold(to_bignum(0), |acc, ref withdrawal_amt| { + .try_fold(BigNum::zero(), |acc, ref withdrawal_amt| { acc.checked_add(&withdrawal_amt) })? } }; let certificate_refund = match &certs { - None => to_bignum(0), + None => BigNum::zero(), Some(certs) => certs .0 .iter() - .try_fold(to_bignum(0), |acc, ref cert| match &cert.0 { + .try_fold(BigNum::zero(), |acc, ref cert| match &cert.0 { CertificateEnum::StakeDeregistration(cert) => { if let Some(coin) = cert.coin { acc.checked_add(&coin) @@ -1302,11 +675,11 @@ pub fn internal_get_deposit( key_deposit: &BigNum, // protocol parameter ) -> Result { let certificate_deposit = match &certs { - None => to_bignum(0), + None => BigNum::zero(), Some(certs) => certs .0 .iter() - .try_fold(to_bignum(0), |acc, ref cert| match &cert.0 { + .try_fold(BigNum::zero(), |acc, ref cert| match &cert.0 { CertificateEnum::PoolRegistration(_) => acc.checked_add(&pool_deposit), CertificateEnum::StakeRegistration(cert) => { if let Some(coin) = cert.coin { @@ -1403,21 +776,21 @@ impl MinOutputAdaCalculator { return Ok(required_coin); } } - output.amount.coin = to_bignum(u64::MAX); + output.amount.coin = BigNum(u64::MAX); Ok(Self::calc_required_coin(&output, &self.data_cost)?) } fn create_fake_output() -> Result { let fake_base_address: Address = Address::from_bech32("addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w")?; - let fake_value: Value = Value::new(&to_bignum(1000000)); + let fake_value: Value = Value::new(&BigNum(1000000)); Ok(TransactionOutput::new(&fake_base_address, &fake_value)) } pub fn calc_size_cost(data_cost: &DataCost, size: usize) -> Result { //according to https://hydra.iohk.io/build/15339994/download/1/babbage-changes.pdf //See on the page 9 getValue txout - to_bignum(size as u64) - .checked_add(&to_bignum(160))? + BigNum(size as u64) + .checked_add(&BigNum(160))? .checked_mul(&data_cost.coins_per_byte()) } @@ -1894,18 +1267,18 @@ mod tests { // testing cases with no assets { - let a = Value::new(&to_bignum(1)); - let b = Value::new(&to_bignum(1)); + let a = Value::new(&BigNum(1)); + let b = Value::new(&BigNum(1)); assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Equal); } { - let a = Value::new(&to_bignum(2)); - let b = Value::new(&to_bignum(1)); + let a = Value::new(&BigNum(2)); + let b = Value::new(&BigNum(1)); assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Greater); } { - let a = Value::new(&to_bignum(1)); - let b = Value::new(&to_bignum(2)); + let a = Value::new(&BigNum(1)); + let b = Value::new(&BigNum(2)); assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Less); } // testing case where one side has assets @@ -1918,7 +1291,7 @@ mod tests { coin: BigNum(1), multiasset: Some(token_bundle1), }; - let b = Value::new(&to_bignum(1)); + let b = Value::new(&BigNum(1)); assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Greater); } { @@ -1926,7 +1299,7 @@ mod tests { let mut asset_list1 = Assets::new(); asset_list1.insert(&asset1, &BigNum(1)); token_bundle1.insert(&policy1, &asset_list1); - let a = Value::new(&to_bignum(1)); + let a = Value::new(&BigNum(1)); let b = Value { coin: BigNum(1), multiasset: Some(token_bundle1), @@ -2526,12 +1899,12 @@ mod tests { #[test] fn test_bignum_div() { - assert_eq!(to_bignum(10).div_floor(&to_bignum(1)), to_bignum(10),); - assert_eq!(to_bignum(10).div_floor(&to_bignum(3)), to_bignum(3),); - assert_eq!(to_bignum(10).div_floor(&to_bignum(4)), to_bignum(2),); - assert_eq!(to_bignum(10).div_floor(&to_bignum(5)), to_bignum(2),); - assert_eq!(to_bignum(10).div_floor(&to_bignum(6)), to_bignum(1),); - assert_eq!(to_bignum(10).div_floor(&to_bignum(12)), to_bignum(0),); + assert_eq!(BigNum(10).div_floor(&BigNum(1)), BigNum(10),); + assert_eq!(BigNum(10).div_floor(&BigNum(3)), BigNum(3),); + assert_eq!(BigNum(10).div_floor(&BigNum(4)), BigNum(2),); + assert_eq!(BigNum(10).div_floor(&BigNum(5)), BigNum(2),); + assert_eq!(BigNum(10).div_floor(&BigNum(6)), BigNum(1),); + assert_eq!(BigNum(10).div_floor(&BigNum(12)), BigNum::zero(),); } #[test] @@ -2547,7 +1920,7 @@ mod tests { &RedeemerTag::new_spend(), &BigNum::zero(), &PlutusData::new_integer(&BigInt::from_str("42").unwrap()), - &ExUnits::new(&to_bignum(1700), &to_bignum(368100)), + &ExUnits::new(&BigNum(1700), &BigNum(368100)), )]), &costmodels, Some(PlutusList::from(vec![PlutusData::new_integer( From 0e648d1c9ba4586badde487aa9422a83255b12f7 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 12 Apr 2024 11:20:45 +0300 Subject: [PATCH 263/349] update test --- rust/src/tests/builders/tx_builder.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index 26cf3195..cd2b3df3 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -6359,10 +6359,11 @@ fn ref_script_fee_from_all_builders() { &PlutusWitness::new_with_ref_without_datum(&plutus_source_6, &redeemer_6) ).unwrap(); + let input_coin = Coin::from(1000000000u64); tx_input_builder.add_plutus_script_input( &PlutusWitness::new_with_ref_without_datum(&plutus_source_8, &redeemer_8), &tx_in_8, - &Value::new(&Coin::from(1000000000u64)) + &Value::new(&input_coin) ); let mut tx_builder = create_reallistic_tx_builder(); @@ -6408,6 +6409,13 @@ fn ref_script_fee_from_all_builders() { let fee_leftover = total_tx_fee.checked_sub(&min_tx_fee).unwrap(); assert_eq!(ref_script_fee, fee_leftover); + let tx_out_coin = tx.body().outputs().get(0).amount().coin(); + let total_out = tx_out_coin + .checked_add(&total_tx_fee).unwrap() + .checked_sub(&Coin::from(2u64)).unwrap(); // withdrawals + + assert_eq!(total_out, input_coin); + let ref_inputs = tx.body().reference_inputs().unwrap(); assert!(ref_inputs.contains(&tx_in_1)); assert!(ref_inputs.contains(&tx_in_2)); From a070d493d06e7a582daf76f14c03111011f93f23 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 12 Apr 2024 11:30:47 +0300 Subject: [PATCH 264/349] add Address.kind() and Address.payment_cred() --- rust/src/protocol_types/address.rs | 33 ++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/rust/src/protocol_types/address.rs b/rust/src/protocol_types/address.rs index ea05d30e..32644f70 100644 --- a/rust/src/protocol_types/address.rs +++ b/rust/src/protocol_types/address.rs @@ -32,6 +32,17 @@ pub(crate) fn variable_nat_encode(mut num: u64) -> Vec { output } +#[wasm_bindgen] +#[derive(Debug, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub enum AddressKind { + Base, + Pointer, + Enterprise, + Reward, + Byron, + Malformed, +} + #[wasm_bindgen] #[derive(Debug, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct NetworkInfo { @@ -303,6 +314,28 @@ impl JsonSchema for Address { #[wasm_bindgen] impl Address { + pub fn kind(&self) -> AddressKind { + match &self.0 { + AddrType::Base(_) => AddressKind::Base, + AddrType::Ptr(_) => AddressKind::Pointer, + AddrType::Enterprise(_) => AddressKind::Enterprise, + AddrType::Reward(_) => AddressKind::Reward, + AddrType::Byron(_) => AddressKind::Byron, + AddrType::Malformed(_) => AddressKind::Malformed, + } + } + + pub fn payment_cred(&self) -> Option { + match &self.0 { + AddrType::Base(a) => Some(a.payment_cred()), + AddrType::Enterprise(a) => Some(a.payment_cred()), + AddrType::Reward(a) => Some(a.payment_cred()), + AddrType::Ptr(a) => Some(a.payment_cred()), + AddrType::Byron(_) => None, + AddrType::Malformed(_) => None, + } + } + pub fn is_malformed(&self) -> bool { matches!(&self.0, AddrType::Malformed(_)) } From 0be14e4a71841ab9779372621a91553e729242e9 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 12 Apr 2024 12:49:32 +0300 Subject: [PATCH 265/349] add prevention of empty witness serialization --- rust/src/protocol_types/plutus/plutus_data.rs | 6 ++++ rust/src/protocol_types/plutus/redeemers.rs | 6 ++++ .../witnesses/bootstrap_witnesses.rs | 6 ++++ .../protocol_types/witnesses/vkeywitnesses.rs | 6 ++++ .../witnesses/transaction_witnesses_set.rs | 32 ++++++++++++------- 5 files changed, 44 insertions(+), 12 deletions(-) diff --git a/rust/src/protocol_types/plutus/plutus_data.rs b/rust/src/protocol_types/plutus/plutus_data.rs index 85da2b2b..1209fbbd 100644 --- a/rust/src/protocol_types/plutus/plutus_data.rs +++ b/rust/src/protocol_types/plutus/plutus_data.rs @@ -394,6 +394,12 @@ pub struct PlutusList { pub(crate) definite_encoding: Option, } +impl NoneOrEmpty for PlutusList { + fn is_none_or_empty(&self) -> bool { + self.elems.is_empty() + } +} + impl<'a> IntoIterator for &'a PlutusList { type Item = &'a PlutusData; type IntoIter = std::slice::Iter<'a, PlutusData>; diff --git a/rust/src/protocol_types/plutus/redeemers.rs b/rust/src/protocol_types/plutus/redeemers.rs index feb309f8..1bab94fa 100644 --- a/rust/src/protocol_types/plutus/redeemers.rs +++ b/rust/src/protocol_types/plutus/redeemers.rs @@ -52,6 +52,12 @@ impl Redeemers { } } +impl NoneOrEmpty for Redeemers { + fn is_none_or_empty(&self) -> bool { + self.redeemers.is_empty() + } +} + impl PartialEq for Redeemers { fn eq(&self, other: &Redeemers) -> bool { self.redeemers == other.redeemers diff --git a/rust/src/protocol_types/witnesses/bootstrap_witnesses.rs b/rust/src/protocol_types/witnesses/bootstrap_witnesses.rs index 87b0c832..43563f73 100644 --- a/rust/src/protocol_types/witnesses/bootstrap_witnesses.rs +++ b/rust/src/protocol_types/witnesses/bootstrap_witnesses.rs @@ -53,6 +53,12 @@ impl BootstrapWitnesses { } } +impl NoneOrEmpty for BootstrapWitnesses { + fn is_none_or_empty(&self) -> bool { + self.witnesses.is_empty() + } +} + impl serde::Serialize for BootstrapWitnesses { fn serialize(&self, serializer: S) -> Result where diff --git a/rust/src/protocol_types/witnesses/vkeywitnesses.rs b/rust/src/protocol_types/witnesses/vkeywitnesses.rs index 8529e322..3b8b0216 100644 --- a/rust/src/protocol_types/witnesses/vkeywitnesses.rs +++ b/rust/src/protocol_types/witnesses/vkeywitnesses.rs @@ -51,6 +51,12 @@ impl Vkeywitnesses { } } +impl NoneOrEmpty for Vkeywitnesses { + fn is_none_or_empty(&self) -> bool { + self.witnesses.is_empty() + } +} + impl serde::Serialize for Vkeywitnesses { fn serialize(&self, serializer: S) -> Result where diff --git a/rust/src/serialization/witnesses/transaction_witnesses_set.rs b/rust/src/serialization/witnesses/transaction_witnesses_set.rs index 02ba02de..982e26ea 100644 --- a/rust/src/serialization/witnesses/transaction_witnesses_set.rs +++ b/rust/src/serialization/witnesses/transaction_witnesses_set.rs @@ -4,6 +4,8 @@ use cbor_event::se::Serializer; use crate::{BootstrapWitnesses, CBORReadLen, DeserializeError, DeserializeFailure, Key, Language, NativeScripts, PlutusList, PlutusScripts, Redeemers, TransactionWitnessSet, Vkeywitnesses}; use crate::protocol_types::{CBORSpecial, CBORType, Deserialize, opt64}; use crate::serialization::utils::merge_option_plutus_list; +use crate::traits::NoneOrEmpty; +use crate::utils::opt64_non_empty; impl cbor_event::se::Serialize for TransactionWitnessSet { fn serialize<'se, W: Write>( @@ -24,27 +26,29 @@ impl cbor_event::se::Serialize for TransactionWitnessSet { }; serializer.write_map(cbor_event::Len::Len( opt64(&self.vkeys) - + opt64(&self.native_scripts) - + opt64(&self.bootstraps) - + opt64(&self.plutus_data) - + opt64(&self.redeemers) + + opt64_non_empty(&self.native_scripts) + + opt64_non_empty(&self.bootstraps) + + opt64_non_empty(&self.plutus_data) + + opt64_non_empty(&self.redeemers) + plutus_added_length, ))?; if let Some(field) = &self.vkeys { - if field.len() > 0 { + if !field.is_none_or_empty() { serializer.write_unsigned_integer(0)?; field.serialize(serializer)?; } } if let Some(field) = &self.native_scripts { - if field.0.len() > 0 { + if !field.is_none_or_empty() { serializer.write_unsigned_integer(1)?; field.serialize(serializer)?; } } if let Some(field) = &self.bootstraps { - serializer.write_unsigned_integer(2)?; - field.serialize(serializer)?; + if !field.is_none_or_empty() { + serializer.write_unsigned_integer(2)?; + field.serialize(serializer)?; + } } if let Some(plutus_scripts) = &self.plutus_scripts { if has_plutus_v1 { @@ -61,12 +65,16 @@ impl cbor_event::se::Serialize for TransactionWitnessSet { } } if let Some(field) = &self.plutus_data { - serializer.write_unsigned_integer(4)?; - field.serialize(serializer)?; + if !field.is_none_or_empty() { + serializer.write_unsigned_integer(4)?; + field.serialize(serializer)?; + } } if let Some(field) = &self.redeemers { - serializer.write_unsigned_integer(5)?; - field.serialize(serializer)?; + if !field.is_none_or_empty() { + serializer.write_unsigned_integer(5)?; + field.serialize(serializer)?; + } } Ok(serializer) } From f3f909da9747c2f05beb8ceba6d8893ed01b85a5 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 12 Apr 2024 13:51:16 +0300 Subject: [PATCH 266/349] switch malformed address deserilization logic --- rust/src/protocol_types/address.rs | 42 ++++++++++++++++++------------ rust/src/tests/address.rs | 20 +++++++++++--- 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/rust/src/protocol_types/address.rs b/rust/src/protocol_types/address.rs index 32644f70..174aea09 100644 --- a/rust/src/protocol_types/address.rs +++ b/rust/src/protocol_types/address.rs @@ -265,7 +265,7 @@ impl ByronAddress { #[derive(Debug, Clone, Eq, Ord, PartialEq, PartialOrd)] pub struct Address(pub(crate) AddrType); -from_bytes!(Address, data, { Self::from_bytes_impl(data.as_ref()) }); +from_bytes!(Address, data, { Self::from_bytes_impl_safe(data.as_ref()) }); to_from_json!(Address); @@ -346,7 +346,7 @@ impl Address { pub fn from_hex(hex_str: &str) -> Result { match hex::decode(hex_str) { - Ok(data) => Ok(Self::from_bytes_impl(data.as_ref())?), + Ok(data) => Ok(Self::from_bytes_impl_safe(data.as_ref())?), Err(e) => Err(JsError::from_str(&e.to_string())), } } @@ -390,7 +390,18 @@ impl Address { buf } - fn from_bytes_impl(data: &[u8]) -> Result { + fn from_bytes_impl_safe(data: &[u8]) -> Result { + Self::from_bytes_internal_impl(data) + } + + fn from_bytes_impl_unsafe(data: &[u8]) -> Address { + match Self::from_bytes_internal_impl(data) { + Ok(addr) => addr, + Err(e) => Address(AddrType::Malformed(MalformedAddress(data.to_vec()))) + } + } + + fn from_bytes_internal_impl(data: &[u8]) -> Result { use std::convert::TryInto; // header has 4 bits addr type discrim then 4 bits network discrim. // Copied from shelley.cddl: @@ -515,12 +526,7 @@ impl Address { } _ => Err(DeserializeFailure::BadAddressType(header).into()), }; - match addr { - Ok(addr) => Ok(Address(addr)), - Err(_) => Ok(Address(AddrType::Malformed(MalformedAddress( - data.to_vec(), - )))), - } + Ok(Address(addr?)) })() .map_err(|e| e.annotate("Address")) } @@ -563,10 +569,14 @@ impl Address { AddrType::Reward(_) => "stake", _ => "addr", }; - let prefix_tail = match self.network_id()? { - id if id == NetworkInfo::testnet_preprod().network_id() => "_test", - id if id == NetworkInfo::testnet_preview().network_id() => "_test", - _ => "", + let prefix_tail = if self.is_malformed() { + "_malformed" + } else { + match self.network_id()? { + id if id == NetworkInfo::testnet_preprod().network_id() => "_test", + id if id == NetworkInfo::testnet_preview().network_id() => "_test", + _ => "", + } }; format!("{}{}", prefix_header, prefix_tail) } @@ -579,7 +589,7 @@ impl Address { let (_hrp, u5data) = bech32::decode(bech_str).map_err(|e| JsError::from_str(&e.to_string()))?; let data: Vec = bech32::FromBase32::from_base32(&u5data).unwrap(); - Ok(Self::from_bytes_impl(data.as_ref())?) + Ok(Self::from_bytes_impl_safe(data.as_ref())?) } pub fn network_id(&self) -> Result { @@ -605,7 +615,7 @@ impl cbor_event::se::Serialize for Address { impl Deserialize for Address { fn deserialize(raw: &mut Deserializer) -> Result { - Self::from_bytes_impl(raw.bytes()?.as_ref()) + Ok(Self::from_bytes_impl_unsafe(raw.bytes()?.as_ref())) } } @@ -769,7 +779,7 @@ impl Deserialize for RewardAddress { fn deserialize(raw: &mut Deserializer) -> Result { (|| -> Result { let bytes = raw.bytes()?; - match Address::from_bytes_impl(bytes.as_ref())?.0 { + match Address::from_bytes_impl_safe(bytes.as_ref())?.0 { AddrType::Reward(ra) => Ok(ra), _other_address => Err(DeserializeFailure::BadAddressType(bytes[0]).into()), } diff --git a/rust/src/tests/address.rs b/rust/src/tests/address.rs index 7173600a..b84eba4b 100644 --- a/rust/src/tests/address.rs +++ b/rust/src/tests/address.rs @@ -560,8 +560,22 @@ fn prepod_network_id_test() { } #[test] -fn malformed_address() { +fn malformed_addres_deserialisation_errors() { let address_bech32 = "addr1q9d66zzs27kppmx8qc8h43q7m4hkxp5d39377lvxefvxd8j7eukjsdqc5c97t2zg5guqadepqqx6rc9m7wtnxy6tajjvk4a0kze4ljyuvvrpexg5up2sqxj33363v35gtew"; - let address = Address::from_bech32(address_bech32).unwrap(); - assert!(address.is_malformed()); + let address = Address::from_bech32(address_bech32); + assert!(address.is_err()); +} + +#[test] +fn malformed_addres_embedded() { + let address = MalformedAddress(vec![5u8; 32]); + let output = TransactionOutput::new( + &address.to_address(), + &Value::new(&Coin::from(100u64)), + ); + let bytes = output.to_bytes(); + let output2 = TransactionOutput::from_bytes(bytes).unwrap(); + + assert!(output2.address.is_malformed()); + assert_eq!(&address.to_address(), &output2.address); } \ No newline at end of file From 3760469d7fc56a9fcd0f352e679e785615004521 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 12 Apr 2024 14:19:51 +0300 Subject: [PATCH 267/349] merge fix --- rust/src/builders/tx_builder.rs | 159 ++++++++++++++++++++++++++ rust/src/tests/builders/tx_builder.rs | 45 ++++++++ 2 files changed, 204 insertions(+) diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index a43fcde7..6320d671 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -304,6 +304,44 @@ impl TransactionBuilderConfigBuilder { } } +#[wasm_bindgen] +#[derive(Clone, Debug)] +pub struct ChangeConfig { + address: Address, + plutus_data: Option, + script_ref: Option +} + +#[wasm_bindgen] +impl ChangeConfig { + pub fn new(address: &Address) -> Self { + Self { + address: address.clone(), + plutus_data: None, + script_ref: None + } + } + + pub fn change_address(&self, address: &Address) -> Self { + let mut c_cfg = self.clone(); + c_cfg.address = address.clone(); + c_cfg + } + + pub fn change_plutus_data(&self, plutus_data: &OutputDatum) -> Self { + let mut c_cfg = self.clone(); + c_cfg.plutus_data = Some(plutus_data.clone()); + c_cfg + } + + pub fn change_script_ref(&self, script_ref: &ScriptRef) -> Self { + let mut c_cfg = self.clone(); + c_cfg.script_ref = Some(script_ref.clone()); + c_cfg + } +} + + #[wasm_bindgen] #[derive(Clone, Debug)] pub struct TransactionBuilder { @@ -665,6 +703,10 @@ impl TransactionBuilder { self.collateral_return = Some(collateral_return.clone()); } + pub fn remove_collateral_return(&mut self) { + self.collateral_return = None; + } + /// This function will set the collateral-return value and then auto-calculate and assign /// the total collateral coin value. Will raise an error in case no collateral inputs are set /// or in case the total collateral value will have any assets in it except coin. @@ -705,6 +747,10 @@ impl TransactionBuilder { self.total_collateral = Some(total_collateral.clone()); } + pub fn remove_total_collateral(&mut self) { + self.total_collateral = None; + } + /// This function will set the total-collateral coin and then auto-calculate and assign /// the collateral return value. Will raise an error in case no collateral inputs are set. /// The specified address will be the received of the collateral return @@ -801,6 +847,95 @@ impl TransactionBuilder { self.inputs.add_regular_input(address, input, amount) } + // This method should be used after outputs of the transaction is defined. + // It will attempt utxo selection initially then add change, if adding change fails + // then it will attempt to use up the rest of the available inputs, attempting to add change + // after every extra input. + pub fn add_inputs_from_and_change( + &mut self, + inputs: &TransactionUnspentOutputs, + strategy: CoinSelectionStrategyCIP2, + change_config: &ChangeConfig + ) -> Result + { + self.add_inputs_from(inputs, strategy)?; + match &self.fee { + Some(_x) => { + return Err(JsError::from_str( + "Cannot calculate change if fee was explicitly specified", + )) + } + None => { + let mut add_change_result = self.add_change_if_needed_with_optional_script_and_datum(&change_config.address, change_config.plutus_data.clone().map_or(None, |od| Some(od.0)), change_config.script_ref.clone()); + match add_change_result { + Ok(v) => Ok(v), + Err(e) => { + let mut unused_inputs = TransactionUnspentOutputs::new(); + for input in inputs.into_iter() { + if self.inputs.inputs().0.iter().all(|used_input| input.input() != *used_input) { + unused_inputs.add(input) + } + } + unused_inputs.0.sort_by_key(|input| input.clone().output.amount.multiasset.map_or(0, |ma| ma.len())); + unused_inputs.0.reverse(); + while unused_inputs.0.len() > 0 { + let last_input = unused_inputs.0.pop(); + match last_input { + Some(input) => { + self.add_regular_input(&input.output().address(), &input.input(), &input.output().amount())?; + add_change_result = self.add_change_if_needed_with_optional_script_and_datum(&change_config.address, change_config.plutus_data.clone().map_or(None, |od| Some(od.0)), change_config.script_ref.clone()); + if let Ok(value) = add_change_result { + return Ok(value) + } + }, + None => return Err(JsError::from_str("Unable to balance tx with available inputs")) + } + } + Err(e) + } + } + } + } + } + + // This method should be used after outputs of the transaction is defined. + // It will attempt to fill the required values using the inputs given. + // After which, it will attempt to set a collateral return output. + pub fn add_inputs_from_and_change_with_collateral_return( + &mut self, + inputs: &TransactionUnspentOutputs, + strategy: CoinSelectionStrategyCIP2, + change_config: &ChangeConfig, + collateral_percentage: u64 + ) -> Result { + let mut total_collateral = Value::zero(); + for collateral_input in self.collateral.iter() { + total_collateral = total_collateral.checked_add(&collateral_input.amount)?; + } + self.set_total_collateral_and_return(&total_collateral.coin(), &change_config.address)?; + let add_change_result = self.add_inputs_from_and_change(inputs, strategy, change_config); + match add_change_result { + Ok(_) => { + let fee = self.get_fee_if_set().unwrap(); + let collateral_required = ((u64::from(&fee) * collateral_percentage) / 100) + 1; + let set_collateral_result = self.set_total_collateral_and_return(&BigNum(collateral_required), &change_config.address); + match set_collateral_result { + Ok(_) => { + Ok(true) + } + Err(_) => { + self.remove_collateral_return(); + self.remove_total_collateral(); + Ok(true) + } + } + } + Err(e) => { + Err(e) + } + }?; + Ok(true) + } /// Returns a copy of the current script input witness scripts in the builder #[deprecated(since = "10.2.0", note = "Use `.set_inputs`")] @@ -892,6 +1027,10 @@ impl TransactionBuilder { self.ttl = Some(ttl.clone()) } + pub fn remove_ttl(&mut self) { + self.ttl = None; + } + /// !!! DEPRECATED !!! /// Uses outdated slot number format. #[deprecated( @@ -906,6 +1045,10 @@ impl TransactionBuilder { self.validity_start_interval = Some(validity_start_interval.clone()) } + pub fn remove_validity_start_interval(&mut self) { + self.validity_start_interval = None; + } + /// !!! DEPRECATED !!! /// Can emit error if add a cert with script credential. /// Use set_certs_builder instead. @@ -924,6 +1067,10 @@ impl TransactionBuilder { Ok(()) } + pub fn remove_certs(&mut self) { + self.certs = None; + } + pub fn set_certs_builder(&mut self, certs: &CertificatesBuilder) { self.certs = Some(certs.clone()); } @@ -958,6 +1105,10 @@ impl TransactionBuilder { self.voting_proposals = Some(voting_proposal_builder.clone()); } + pub fn remove_withdrawals(&mut self) { + self.withdrawals = None; + } + pub fn get_auxiliary_data(&self) -> Option { self.auxiliary_data.clone() } @@ -968,6 +1119,10 @@ impl TransactionBuilder { self.auxiliary_data = Some(auxiliary_data.clone()) } + pub fn remove_auxiliary_data(&mut self) { + self.auxiliary_data = None; + } + /// Set metadata using a GeneralTransactionMetadata object /// It will be set to the existing or new auxiliary data in this builder pub fn set_metadata(&mut self, metadata: &GeneralTransactionMetadata) { @@ -1020,6 +1175,10 @@ impl TransactionBuilder { self.mint = Some(mint_builder.clone()); } + pub fn remove_mint_builder(&mut self) { + self.mint = None; + } + pub fn get_mint_builder(&self) -> Option { self.mint.clone() } diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index cd2b3df3..6367559f 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -6428,3 +6428,48 @@ fn ref_script_fee_from_all_builders() { assert!(ref_inputs.contains(&tx_in_9)); assert_eq!(ref_inputs.len(), 9); } + + +#[test] +fn utxo_selection_accounts_for_change_min_utxo_test() { + let mut tx_builder = create_reallistic_tx_builder(); + let hex_utxos = [ + "82825820731224c9d2bc3528578009fec9f9e34a67110aca2bd4dde0f050845a2daf660d0082583900436075347d6a452eba4289ae345a8eb15e73eb80979a7e817d988fc56c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e493821a001deabfa1581c9a5e0d55cdf4ce4e19c8acbff7b4dafc890af67a594a4c46d7dd1c0fa14001", + "82825820a04996d5ef87fdece0c74625f02ee5c1497a06e0e476c5095a6b0626b295074a00825839001772f234940519e71318bb9c5c8ad6eacfe8fd91a509050624e3855e6c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e4931a0016e360" + ]; + let output = TransactionOutput::new(&Address::from_bech32("addr_test1qppkqaf5044y2t46g2y6udz636c4uultszte5l5p0kvgl3tv3ck06k550q64lgwkqavljd63yda0x2va074fguprujfsjre4xh").unwrap(), &Value::new(&BigNum::from_str("969750").unwrap())); + tx_builder.add_output(&output); + let mut utxos = TransactionUnspentOutputs::new(); + for hex_utxo in hex_utxos { + utxos.add(&TransactionUnspentOutput::from_hex(hex_utxo).unwrap()); + } + let change_config = ChangeConfig::new(&Address::from_bech32("addr_test1qqzf7fhgm0gf370ngxgpskg5c3kgp2g0u4ltxlrmsvumaztv3ck06k550q64lgwkqavljd63yda0x2va074fguprujfs43mc83").unwrap()); + assert!(&tx_builder.add_inputs_from_and_change(&utxos, CoinSelectionStrategyCIP2::LargestFirstMultiAsset, &change_config).is_ok()); + let build_res = tx_builder.build_tx(); + assert!(&build_res.is_ok()); +} + +#[test] +fn utxo_selection_with_collateral_return_test() { + let mut tx_builder = create_reallistic_tx_builder(); + let hex_utxos = [ + "82825820731224c9d2bc3528578009fec9f9e34a67110aca2bd4dde0f050845a2daf660d0082583900436075347d6a452eba4289ae345a8eb15e73eb80979a7e817d988fc56c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e493821a001deabfa1581c9a5e0d55cdf4ce4e19c8acbff7b4dafc890af67a594a4c46d7dd1c0fa14001", + "82825820a04996d5ef87fdece0c74625f02ee5c1497a06e0e476c5095a6b0626b295074a00825839001772f234940519e71318bb9c5c8ad6eacfe8fd91a509050624e3855e6c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e4931a0016e360" + ]; + let output = TransactionOutput::new(&Address::from_bech32("addr_test1qppkqaf5044y2t46g2y6udz636c4uultszte5l5p0kvgl3tv3ck06k550q64lgwkqavljd63yda0x2va074fguprujfsjre4xh").unwrap(), &Value::new(&BigNum::from_str("969750").unwrap())); + tx_builder.add_output(&output).unwrap(); + let mut utxos = TransactionUnspentOutputs::new(); + for hex_utxo in hex_utxos { + utxos.add(&TransactionUnspentOutput::from_hex(hex_utxo).unwrap()); + } + let mut collateral_builder = TxInputsBuilder::new(); + let collateral_input = TransactionUnspentOutput::from_hex(hex_utxos[1]).unwrap(); + collateral_builder.add_regular_input(&collateral_input.output.address, &collateral_input.input, &collateral_input.output.amount).unwrap(); + tx_builder.set_collateral(&collateral_builder); + + let change_config = ChangeConfig::new(&Address::from_bech32("addr_test1qqzf7fhgm0gf370ngxgpskg5c3kgp2g0u4ltxlrmsvumaztv3ck06k550q64lgwkqavljd63yda0x2va074fguprujfs43mc83").unwrap()); + assert!(&tx_builder.add_inputs_from_and_change_with_collateral_return(&utxos, CoinSelectionStrategyCIP2::LargestFirstMultiAsset, &change_config, 150).is_ok()); + let build_res = tx_builder.build_tx(); + assert!(&build_res.is_ok()); + assert!(&build_res.clone().unwrap().body.collateral_return().is_some()); +} From e88da280d1eb0980e71d17a6da0d9a8c6c69fed9 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 12 Apr 2024 14:23:49 +0300 Subject: [PATCH 268/349] remove unwrap --- rust/src/builders/tx_builder.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index 6320d671..3d41d831 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -916,7 +916,9 @@ impl TransactionBuilder { let add_change_result = self.add_inputs_from_and_change(inputs, strategy, change_config); match add_change_result { Ok(_) => { - let fee = self.get_fee_if_set().unwrap(); + let fee = self.get_fee_if_set().ok_or( + JsError::from_str("Cannot calculate collateral return if fee was not set"), + )?; let collateral_required = ((u64::from(&fee) * collateral_percentage) / 100) + 1; let set_collateral_result = self.set_total_collateral_and_return(&BigNum(collateral_required), &change_config.address); match set_collateral_result { From aeeb11f7d73ecb1d4d2fdf0113316be39db8e200 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 12 Apr 2024 14:32:40 +0300 Subject: [PATCH 269/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- rust/pkg/cardano_serialization_lib.js.flow | 442 ++++++++++++++------- 5 files changed, 309 insertions(+), 141 deletions(-) diff --git a/package-lock.json b/package-lock.json index 450dc818..1fafdf5a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.28", + "version": "12.0.0-alpha.29", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index f7c0ff59..1b87a658 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.28", + "version": "12.0.0-alpha.29", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 72588968..502bf7e1 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.28" +version = "12.0.0-alpha.29" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 1157b6f9..01425b4b 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -55,7 +55,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.28" +version = "12.0.0-alpha.29" dependencies = [ "bech32", "cbor_event", diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 0e1d6efa..7167c974 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -69,6 +69,42 @@ declare export function decode_metadatum_to_json_str( schema: $Values ): string; +/** + * @param {Address} address + * @param {TransactionUnspentOutputs} utxos + * @param {TransactionBuilderConfig} config + * @returns {TransactionBatchList} + */ +declare export function create_send_all( + address: Address, + utxos: TransactionUnspentOutputs, + config: TransactionBuilderConfig +): TransactionBatchList; + +/** + * @param {string} password + * @param {string} salt + * @param {string} nonce + * @param {string} data + * @returns {string} + */ +declare export function encrypt_with_password( + password: string, + salt: string, + nonce: string, + data: string +): string; + +/** + * @param {string} password + * @param {string} data + * @returns {string} + */ +declare export function decrypt_with_password( + password: string, + data: string +): string; + /** * @param {Transaction} tx * @param {LinearFee} linear_fee @@ -96,6 +132,16 @@ declare export function min_script_fee( ex_unit_prices: ExUnitPrices ): BigNum; +/** + * @param {number} total_ref_scripts_size + * @param {UnitInterval} ref_script_coins_per_byte + * @returns {BigNum} + */ +declare export function min_ref_script_fee( + total_ref_scripts_size: number, + ref_script_coins_per_byte: UnitInterval +): BigNum; + /** * @param {TransactionHash} tx_body_hash * @param {ByronAddress} addr @@ -222,40 +268,59 @@ declare export function encode_json_str_to_native_script( ): NativeScript; /** - * @param {string} password - * @param {string} salt - * @param {string} nonce - * @param {string} data - * @returns {string} */ -declare export function encrypt_with_password( - password: string, - salt: string, - nonce: string, - data: string -): string; + +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 +|}; /** - * @param {string} password - * @param {string} data - * @returns {string} + * Each new language uses a different namespace for hashing its script + * This is because you could have a language where the same bytes have different semantics + * So this avoids scripts in different languages mapping to the same hash + * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export function decrypt_with_password( - password: string, - data: string -): string; + +declare export var ScriptHashNamespace: {| + +NativeScript: 0, // 0 + +PlutusScript: 1, // 1 + +PlutusScriptV2: 2, // 2 + +PlutusScriptV3: 3, // 3 +|}; /** - * @param {Address} address - * @param {TransactionUnspentOutputs} utxos - * @param {TransactionBuilderConfig} config - * @returns {TransactionBatchList} */ -declare export function create_send_all( - address: Address, - utxos: TransactionUnspentOutputs, - config: TransactionBuilderConfig -): TransactionBatchList; + +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 +|}; + +/** + */ + +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 +|}; + +/** + */ + +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 +|}; /** */ @@ -269,19 +334,17 @@ declare export var LanguageKind: {| /** */ -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 |}; /** */ -declare export var RelayKind: {| - +SingleHostAddr: 0, // 0 - +SingleHostName: 1, // 1 - +MultiHostName: 2, // 2 +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** @@ -300,85 +363,78 @@ declare export var GovernanceActionKind: {| /** */ -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 -|}; - -/** - */ - -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** - * Used to choosed the schema for a script JSON string */ -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 |}; /** */ -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 |}; /** */ -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 +declare export var CborContainerType: {| + +Array: 0, // 0 +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 |}; /** */ -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 +declare export var RedeemerTagKind: {| + +Spend: 0, // 0 + +Mint: 1, // 1 + +Cert: 2, // 2 + +Reward: 3, // 3 + +Vote: 4, // 4 + +VotingProposal: 5, // 5 |}; /** */ -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 +declare export var AddressKind: {| + +Base: 0, // 0 + +Pointer: 1, // 1 + +Enterprise: 2, // 2 + +Reward: 3, // 3 + +Byron: 4, // 4 + +Malformed: 5, // 5 |}; /** */ -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 +declare export var RelayKind: {| + +SingleHostAddr: 0, // 0 + +SingleHostName: 1, // 1 + +MultiHostName: 2, // 2 |}; /** + * Used to choosed the schema for a script JSON string */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** @@ -399,29 +455,34 @@ declare export var PlutusDatumSchema: {| |}; /** - * Each new language uses a different namespace for hashing its script - * This is because you could have a language where the same bytes have different semantics - * So this avoids scripts in different languages mapping to the same hash - * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var ScriptHashNamespace: {| - +NativeScript: 0, // 0 - +PlutusScript: 1, // 1 - +PlutusScriptV2: 2, // 2 - +PlutusScriptV3: 3, // 3 +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 |}; /** */ -declare export var RedeemerTagKind: {| - +Spend: 0, // 0 - +Mint: 1, // 1 - +Cert: 2, // 2 - +Reward: 3, // 3 - +Vote: 4, // 4 - +VotingProposal: 5, // 5 +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 +|}; + +/** + */ + +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 |}; /** @@ -447,45 +508,6 @@ declare export var CertificateKind: {| +VoteRegistrationAndDelegation: 16, // 16 |}; -/** - */ - -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 -|}; - -/** - */ - -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 -|}; - -/** - */ - -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 -|}; - -/** - */ - -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 -|}; - /** */ declare export class Address { @@ -513,6 +535,18 @@ declare export class Address { */ static from_json(json: string): Address; + /** + * @returns {$Values< + typeof + AddressKind>} + */ + kind(): $Values; + + /** + * @returns {Credential | void} + */ + payment_cred(): Credential | void; + /** * @returns {boolean} */ @@ -2151,6 +2185,35 @@ declare export class CertificatesBuilder { */ build(): Certificates; } +/** + */ +declare export class ChangeConfig { + free(): void; + + /** + * @param {Address} address + * @returns {ChangeConfig} + */ + static new(address: Address): ChangeConfig; + + /** + * @param {Address} address + * @returns {ChangeConfig} + */ + change_address(address: Address): ChangeConfig; + + /** + * @param {OutputDatum} plutus_data + * @returns {ChangeConfig} + */ + change_plutus_data(plutus_data: OutputDatum): ChangeConfig; + + /** + * @param {ScriptRef} script_ref + * @returns {ChangeConfig} + */ + change_script_ref(script_ref: ScriptRef): ChangeConfig; +} /** */ declare export class Committee { @@ -6043,14 +6106,17 @@ declare export class NativeScriptSource { /** * @param {ScriptHash} script_hash * @param {TransactionInput} input - * @param {Ed25519KeyHashes} required_signers * @returns {NativeScriptSource} */ static new_ref_input( script_hash: ScriptHash, - input: TransactionInput, - required_signers: Ed25519KeyHashes + input: TransactionInput ): NativeScriptSource; + + /** + * @param {Ed25519KeyHashes} key_hashes + */ + set_required_signers(key_hashes: Ed25519KeyHashes): void; } /** */ @@ -6983,13 +7049,25 @@ declare export class PlutusScriptSource { * @param {ScriptHash} script_hash * @param {TransactionInput} input * @param {Language} lang_ver + * @param {number} script_size * @returns {PlutusScriptSource} */ static new_ref_input( script_hash: ScriptHash, input: TransactionInput, - lang_ver: Language + lang_ver: Language, + script_size: number ): PlutusScriptSource; + + /** + * @param {Ed25519KeyHashes} key_hashes + */ + set_required_signers(key_hashes: Ed25519KeyHashes): void; + + /** + * @returns {number | void} + */ + get_ref_script_size(): number | void; } /** */ @@ -8157,6 +8235,16 @@ declare export class ProtocolParamUpdate { */ drep_inactivity_period(): number | void; + /** + * @param {UnitInterval} ref_script_coins_per_byte + */ + set_ref_script_coins_per_byte(ref_script_coins_per_byte: UnitInterval): void; + + /** + * @returns {UnitInterval | void} + */ + ref_script_coins_per_byte(): UnitInterval | void; + /** * @returns {ProtocolParamUpdate} */ @@ -10459,6 +10547,10 @@ declare export class TransactionBuilder { */ set_collateral_return(collateral_return: TransactionOutput): void; + /** + */ + remove_collateral_return(): void; + /** * This function will set the collateral-return value and then auto-calculate and assign * the total collateral coin value. Will raise an error in case no collateral inputs are set @@ -10472,6 +10564,10 @@ declare export class TransactionBuilder { */ set_total_collateral(total_collateral: BigNum): void; + /** + */ + remove_total_collateral(): void; + /** * This function will set the total-collateral coin and then auto-calculate and assign * the collateral return value. Will raise an error in case no collateral inputs are set. @@ -10489,6 +10585,15 @@ declare export class TransactionBuilder { */ add_reference_input(reference_input: TransactionInput): void; + /** + * @param {TransactionInput} reference_input + * @param {number} script_size + */ + add_script_reference_input( + reference_input: TransactionInput, + script_size: number + ): void; + /** * We have to know what kind of inputs these are to know what kind of mock witnesses to create since * 1) mock witnesses have different lengths depending on the type which changes the expecting fee @@ -10553,6 +10658,36 @@ declare export class TransactionBuilder { amount: Value ): void; + /** + * @param {TransactionUnspentOutputs} inputs + * @param {$Values< + typeof + CoinSelectionStrategyCIP2>} strategy + * @param {ChangeConfig} change_config + * @returns {boolean} + */ + add_inputs_from_and_change( + inputs: TransactionUnspentOutputs, + strategy: $Values, + change_config: ChangeConfig + ): boolean; + + /** + * @param {TransactionUnspentOutputs} inputs + * @param {$Values< + typeof + CoinSelectionStrategyCIP2>} strategy + * @param {ChangeConfig} change_config + * @param {bigint} collateral_percentage + * @returns {boolean} + */ + add_inputs_from_and_change_with_collateral_return( + inputs: TransactionUnspentOutputs, + strategy: $Values, + change_config: ChangeConfig, + collateral_percentage: bigint + ): boolean; + /** * Returns a copy of the current script input witness scripts in the builder * @returns {NativeScripts | void} @@ -10609,6 +10744,10 @@ declare export class TransactionBuilder { */ set_ttl_bignum(ttl: BigNum): void; + /** + */ + remove_ttl(): void; + /** * !!! DEPRECATED !!! * Uses outdated slot number format. @@ -10621,6 +10760,10 @@ declare export class TransactionBuilder { */ set_validity_start_interval_bignum(validity_start_interval: BigNum): void; + /** + */ + remove_validity_start_interval(): void; + /** * !!! DEPRECATED !!! * Can emit error if add a cert with script credential. @@ -10629,6 +10772,10 @@ declare export class TransactionBuilder { */ set_certs(certs: Certificates): void; + /** + */ + remove_certs(): void; + /** * @param {CertificatesBuilder} certs */ @@ -10659,6 +10806,10 @@ declare export class TransactionBuilder { voting_proposal_builder: VotingProposalBuilder ): void; + /** + */ + remove_withdrawals(): void; + /** * @returns {AuxiliaryData | void} */ @@ -10671,6 +10822,10 @@ declare export class TransactionBuilder { */ set_auxiliary_data(auxiliary_data: AuxiliaryData): void; + /** + */ + remove_auxiliary_data(): void; + /** * Set metadata using a GeneralTransactionMetadata object * It will be set to the existing or new auxiliary data in this builder @@ -10714,6 +10869,10 @@ declare export class TransactionBuilder { */ set_mint_builder(mint_builder: MintBuilder): void; + /** + */ + remove_mint_builder(): void; + /** * @returns {MintBuilder | void} */ @@ -11046,6 +11205,14 @@ declare export class TransactionBuilderConfigBuilder { */ max_tx_size(max_tx_size: number): TransactionBuilderConfigBuilder; + /** + * @param {UnitInterval} ref_script_coins_per_byte + * @returns {TransactionBuilderConfigBuilder} + */ + ref_script_coins_per_byte( + ref_script_coins_per_byte: UnitInterval + ): TransactionBuilderConfigBuilder; + /** * @param {boolean} prefer_pure_change * @returns {TransactionBuilderConfigBuilder} @@ -14244,6 +14411,7 @@ export interface ProtocolParamUpdateJSON { pool_pledge_influence?: UnitIntervalJSON | null; pool_voting_thresholds?: PoolVotingThresholdsJSON | null; protocol_version?: ProtocolVersionJSON | null; + ref_script_coins_per_byte?: UnitIntervalJSON | null; treasury_growth_rate?: UnitIntervalJSON | null; } export interface CostmdlsJSON { From 8aa9d9f876fe1c6863b923265932fbd1ea982ba9 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 12 Apr 2024 22:42:32 +0300 Subject: [PATCH 270/349] add redeemers map deserialization test --- rust/src/tests/serialization/general.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rust/src/tests/serialization/general.rs b/rust/src/tests/serialization/general.rs index 2b7f678a..c6d7c0cf 100644 --- a/rust/src/tests/serialization/general.rs +++ b/rust/src/tests/serialization/general.rs @@ -759,4 +759,11 @@ fn redeemers_map_array_round_trip() { assert_eq!(new_redeemers_map, new_redeemers_array); assert_ne!(bytes_array, bytes_map) +} + +#[test] +fn redeemers_map_deserialization() { + let hex = "a282000082d8799f0102030405ff821821182c82040082d8799f0102030405ff8218371842"; + let redeemers = Redeemers::from_hex(hex); + assert!(redeemers.is_ok()); } \ No newline at end of file From d9aad564581d7c1831091f9519903df107e3c72d Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 7 May 2024 21:29:55 +0900 Subject: [PATCH 271/349] fix MintBuilder for multiple different redeemers, add ref input support for native scripts to MintBuilder --- rust/src/builders/mint_builder.rs | 195 +++++-- .../script_structs/native_script_source.rs | 4 + rust/src/builders/tx_builder.rs | 14 +- rust/src/builders/tx_inputs_builder.rs | 10 +- rust/src/error.rs | 18 +- rust/src/fakes.rs | 7 +- rust/src/protocol_types/plutus/redeemer.rs | 4 + rust/src/tests/builders/mint_builder.rs | 502 ++++++++++++++++++ rust/src/tests/builders/mod.rs | 3 +- rust/src/tests/builders/tx_builder.rs | 446 ++-------------- 10 files changed, 737 insertions(+), 466 deletions(-) create mode 100644 rust/src/tests/builders/mint_builder.rs diff --git a/rust/src/builders/mint_builder.rs b/rust/src/builders/mint_builder.rs index e4bf987e..41d4e493 100644 --- a/rust/src/builders/mint_builder.rs +++ b/rust/src/builders/mint_builder.rs @@ -4,7 +4,7 @@ use std::collections::BTreeMap; #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] enum MintWitnessEnum { Plutus(PlutusScriptSourceEnum, Redeemer), - NativeScript(NativeScript), + NativeScript(NativeScriptSourceEnum), } #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] @@ -13,8 +13,8 @@ pub struct MintWitness(MintWitnessEnum); #[wasm_bindgen] impl MintWitness { - pub fn new_native_script(native_script: &NativeScript) -> MintWitness { - MintWitness(MintWitnessEnum::NativeScript(native_script.clone())) + pub fn new_native_script(native_script: &NativeScriptSource) -> MintWitness { + MintWitness(MintWitnessEnum::NativeScript(native_script.0.clone())) } pub fn new_plutus_script( @@ -26,18 +26,49 @@ impl MintWitness { redeemer.clone(), )) } + + pub(crate) fn script_hash(&self) -> ScriptHash { + match &self.0 { + MintWitnessEnum::NativeScript(native_script) => native_script.script_hash(), + MintWitnessEnum::Plutus(plutus_script, _) => plutus_script.script_hash(), + } + } } #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] struct NativeMints { - script: NativeScript, + script: NativeScriptSourceEnum, mints: BTreeMap, } +impl NativeMints { + fn script_hash(&self) -> PolicyID { + match &self.script { + NativeScriptSourceEnum::NativeScript(script, _) => script.hash(), + NativeScriptSourceEnum::RefInput(_, script_hash, _) => script_hash.clone(), + } + } + + fn ref_input(&self) -> Option<&TransactionInput> { + match &self.script { + NativeScriptSourceEnum::RefInput(input, _, _) => Some(input), + _ => None, + } + } + + fn native_script(&self) -> Option<&NativeScript> { + match &self.script { + NativeScriptSourceEnum::NativeScript(script, _) => Some(script), + _ => None, + } + } +} + #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] struct PlutusMints { script: PlutusScriptSourceEnum, - redeemer_mints: BTreeMap>, + redeemer: Redeemer, + mints: BTreeMap, } #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] @@ -88,7 +119,7 @@ impl MintBuilder { fn update_mint_value( &mut self, - mint: &MintWitness, + mint_witness: &MintWitness, asset_name: &AssetName, amount: &Int, overwrite: bool, @@ -96,11 +127,14 @@ impl MintBuilder { if amount.0 == 0 { return Err(JsError::from_str("Mint cannot be zero.")); } - match &mint.0 { + let script_mint = self.mints.get(&mint_witness.script_hash()); + Self::validate_mint_witness(mint_witness, script_mint)?; + + match &mint_witness.0 { MintWitnessEnum::NativeScript(native_script) => { let script_mint = self.mints - .entry(native_script.hash()) + .entry(native_script.script_hash()) .or_insert(ScriptMint::Native(NativeMints { script: native_script.clone(), mints: BTreeMap::new(), @@ -126,15 +160,13 @@ impl MintBuilder { .entry(plutus_script.script_hash()) .or_insert(ScriptMint::Plutus(PlutusMints { script: plutus_script.clone(), - redeemer_mints: BTreeMap::new(), + redeemer: redeemer.clone(), + mints: BTreeMap::new(), })); match script_mint { ScriptMint::Plutus(plutus_mints) => { - let redeemer_mints = plutus_mints - .redeemer_mints - .entry(redeemer.clone()) - .or_insert(BTreeMap::new()); - let mint = redeemer_mints + let mint = plutus_mints + .mints .entry(asset_name.clone()) .or_insert(Int::new(&BigNum::zero())); if overwrite { @@ -150,27 +182,118 @@ impl MintBuilder { Ok(()) } + fn validate_mint_witness( + mint_witness: &MintWitness, + current_script_mint: Option<&ScriptMint>, + ) -> Result<(), JsError> { + if let Some(current_script_mint) = current_script_mint { + match &mint_witness.0 { + MintWitnessEnum::NativeScript(native_script) => { + if let ScriptMint::Native(native_mints) = current_script_mint { + Self::validate_native_source_type(&native_mints.script, &native_script)?; + } else { + return Err(JsError::from_str( + &BuilderError::MintBuilderDifferentScriptType.as_str(), + )); + } + } + MintWitnessEnum::Plutus(plutus_script, redeemer) => { + if let ScriptMint::Plutus(plutus_mints) = current_script_mint { + Self::validate_plutus_script_source_type( + &plutus_mints.script, + &plutus_script, + )?; + if !plutus_mints.redeemer.partially_eq(redeemer) { + return Err(JsError::from_str( + &BuilderError::MintBuilderDifferentRedeemerDataAndExUnits( + plutus_mints.redeemer.to_json()?, + redeemer.to_json()?, + ) + .as_str(), + )); + } + } else { + return Err(JsError::from_str( + &BuilderError::MintBuilderDifferentScriptType.as_str(), + )); + } + } + } + Ok(()) + } else { + Ok(()) + } + } + + fn validate_native_source_type( + current_script_source: &NativeScriptSourceEnum, + input_script_source: &NativeScriptSourceEnum, + ) -> Result<(), JsError> { + match current_script_source { + NativeScriptSourceEnum::NativeScript(_, _) => { + if let NativeScriptSourceEnum::NativeScript(_, _) = input_script_source { + Ok(()) + } else { + Err(JsError::from_str( + &BuilderError::MintBuilderDifferentWitnessTypeNonRef.as_str(), + )) + } + } + NativeScriptSourceEnum::RefInput(_, _, _) => { + if let NativeScriptSourceEnum::RefInput(_, _, _) = input_script_source { + Ok(()) + } else { + Err(JsError::from_str( + &BuilderError::MintBuilderDifferentWitnessTypeRef.as_str(), + )) + } + } + } + } + + fn validate_plutus_script_source_type( + current_script_source: &PlutusScriptSourceEnum, + input_script_source: &PlutusScriptSourceEnum, + ) -> Result<(), JsError> { + match current_script_source { + PlutusScriptSourceEnum::RefInput(_, _) => { + if let PlutusScriptSourceEnum::RefInput(_, _) = input_script_source { + Ok(()) + } else { + Err(JsError::from_str( + &BuilderError::MintBuilderDifferentWitnessTypeRef.as_str(), + )) + } + } + PlutusScriptSourceEnum::Script(_, _) => { + if let PlutusScriptSourceEnum::Script(_, _) = input_script_source { + Ok(()) + } else { + Err(JsError::from_str( + &BuilderError::MintBuilderDifferentWitnessTypeNonRef.as_str(), + )) + } + } + } + } + pub fn build(&self) -> Mint { let mut mint = Mint::new(); - for (_, script_mint) in self.mints.iter() { + for (policy, script_mint) in self.mints.iter() { + let mut mint_asset = MintAssets::new(); match script_mint { ScriptMint::Native(native_mints) => { - let mut mint_asset = MintAssets::new(); for (asset_name, amount) in &native_mints.mints { mint_asset.insert(asset_name, amount.clone()); } - mint.insert(&native_mints.script.hash(), &mint_asset); } ScriptMint::Plutus(plutus_mints) => { - for (_, redeemer_mints) in &plutus_mints.redeemer_mints { - let mut mint_asset = MintAssets::new(); - for (asset_name, amount) in redeemer_mints { - mint_asset.insert(asset_name, amount.clone()); - } - mint.insert(&plutus_mints.script.script_hash(), &mint_asset); + for (asset_name, amount) in &plutus_mints.mints { + mint_asset.insert(asset_name, amount.clone()); } } } + mint.insert(&policy, &mint_asset); } mint } @@ -180,7 +303,9 @@ impl MintBuilder { for script_mint in self.mints.values() { match script_mint { ScriptMint::Native(native_mints) => { - native_scripts.push(native_mints.script.clone()); + if let Some(script) = native_mints.native_script() { + native_scripts.push(script.clone()); + } } _ => {} } @@ -193,12 +318,10 @@ impl MintBuilder { for script_mint in self.mints.values() { match script_mint { ScriptMint::Plutus(plutus_mints) => { - for (redeemer, _) in &plutus_mints.redeemer_mints { - plutus_witnesses.push(PlutusWitness::new_with_ref_without_datum( - &PlutusScriptSource(plutus_mints.script.clone()), - redeemer, - )); - } + plutus_witnesses.push(PlutusWitness::new_with_ref_without_datum( + &PlutusScriptSource(plutus_mints.script.clone()), + &plutus_mints.redeemer, + )); } _ => {} } @@ -215,7 +338,11 @@ impl MintBuilder { reference_inputs.push(ref_script.input_ref.clone()); } } - _ => {} + ScriptMint::Native(native_mints) => { + if let Some(input) = native_mints.ref_input() { + reference_inputs.push(input.clone()); + } + } } } TransactionInputs(reference_inputs) @@ -228,10 +355,8 @@ impl MintBuilder { for (_, script_mint) in &self.mints { match script_mint { ScriptMint::Plutus(plutus_mints) => { - for (redeemer, _) in &plutus_mints.redeemer_mints { - redeeemers.push(redeemer.clone_with_index_and_tag(&index, &tag)); - index = index.checked_add(&BigNum::one())?; - } + redeeemers.push(plutus_mints.redeemer.clone_with_index_and_tag(&index, &tag)); + index = index.checked_add(&BigNum::one())?; } _ => { index = index.checked_add(&BigNum::one())?; diff --git a/rust/src/builders/script_structs/native_script_source.rs b/rust/src/builders/script_structs/native_script_source.rs index 081bb7b3..37bec9bb 100644 --- a/rust/src/builders/script_structs/native_script_source.rs +++ b/rust/src/builders/script_structs/native_script_source.rs @@ -62,4 +62,8 @@ impl NativeScriptSource { pub fn set_required_signers(&mut self, key_hashes: &Ed25519KeyHashes) { self.0.set_required_signers(key_hashes) } + + pub(crate) fn script_hash(&self) -> ScriptHash { + self.0.script_hash() + } } \ No newline at end of file diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index 3d41d831..19de3fa8 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -1207,7 +1207,8 @@ impl TransactionBuilder { for (policy_id, asset_map) in &mint.0 { for (asset_name, amount) in &asset_map.0 { if let Some(script) = scripts_policies.get(policy_id) { - let mint_witness = MintWitness::new_native_script(script); + let native_script_source = NativeScriptSource::new(script); + let mint_witness = MintWitness::new_native_script(&native_script_source); mint_builder.set_asset(&mint_witness, asset_name, amount); } else { return Err(JsError::from_str( @@ -1254,7 +1255,8 @@ impl TransactionBuilder { /// It will be securely added to existing or new Mint in this builder /// It will replace any existing mint assets with the same PolicyID pub fn set_mint_asset(&mut self, policy_script: &NativeScript, mint_assets: &MintAssets) { - let mint_witness = MintWitness::new_native_script(policy_script); + let native_script_source = NativeScriptSource::new(policy_script); + let mint_witness = MintWitness::new_native_script(&native_script_source); if let Some(mint) = &mut self.mint { for (asset, amount) in mint_assets.0.iter() { mint.set_asset(&mint_witness, asset, amount); @@ -1284,7 +1286,8 @@ impl TransactionBuilder { asset_name: &AssetName, amount: &Int, ) { - let mint_witness = MintWitness::new_native_script(policy_script); + let native_script_source = NativeScriptSource::new(policy_script); + let mint_witness = MintWitness::new_native_script(&native_script_source); if let Some(mint) = &mut self.mint { mint.add_asset(&mint_witness, asset_name, &amount); } else { @@ -1538,9 +1541,10 @@ impl TransactionBuilder { self.mint .as_ref() .map(|m| { + let mint = m.build(); ( - Value::new_from_assets(&m.build().as_positive_multiasset()), - Value::new_from_assets(&m.build().as_negative_multiasset()), + Value::new_from_assets(&mint.as_positive_multiasset()), + Value::new_from_assets(&mint.as_negative_multiasset()), ) }) .unwrap_or((Value::zero(), Value::zero())) diff --git a/rust/src/builders/tx_inputs_builder.rs b/rust/src/builders/tx_inputs_builder.rs index c9385d33..e0bf9b56 100644 --- a/rust/src/builders/tx_inputs_builder.rs +++ b/rust/src/builders/tx_inputs_builder.rs @@ -128,7 +128,7 @@ impl TxInputsBuilder { Ok(()) } CredType::Script(_) => Err(JsError::from_str( - BuilderError::RegularInputIsScript.as_str(), + &BuilderError::RegularInputIsScript.as_str(), )), }, AddrType::Enterprise(ent_aaddr) => match &ent_aaddr.payment.0 { @@ -137,7 +137,7 @@ impl TxInputsBuilder { Ok(()) } CredType::Script(_) => Err(JsError::from_str( - BuilderError::RegularInputIsScript.as_str(), + &BuilderError::RegularInputIsScript.as_str(), )), }, AddrType::Ptr(ptr_addr) => match &ptr_addr.payment.0 { @@ -146,7 +146,7 @@ impl TxInputsBuilder { Ok(()) } CredType::Script(_) => Err(JsError::from_str( - BuilderError::RegularInputIsScript.as_str(), + &BuilderError::RegularInputIsScript.as_str(), )), }, AddrType::Byron(byron_addr) => { @@ -154,10 +154,10 @@ impl TxInputsBuilder { Ok(()) } AddrType::Reward(_) => Err(JsError::from_str( - BuilderError::RegularInputIsFromRewardAddress.as_str(), + &BuilderError::RegularInputIsFromRewardAddress.as_str(), )), AddrType::Malformed(_) => { - Err(JsError::from_str(BuilderError::MalformedAddress.as_str())) + Err(JsError::from_str(&BuilderError::MalformedAddress.as_str())) } } } diff --git a/rust/src/error.rs b/rust/src/error.rs index 66744fbd..1360db4b 100644 --- a/rust/src/error.rs +++ b/rust/src/error.rs @@ -231,15 +231,23 @@ impl std::error::Error for JsError {} pub(crate) enum BuilderError { RegularInputIsScript, RegularInputIsFromRewardAddress, - MalformedAddress + MalformedAddress, + MintBuilderDifferentScriptType, + MintBuilderDifferentRedeemerDataAndExUnits(String, String), + MintBuilderDifferentWitnessTypeRef, + MintBuilderDifferentWitnessTypeNonRef } impl BuilderError { - pub(crate) fn as_str(&self) -> &'static str { + pub(crate) fn as_str(&self) -> String { match self { - BuilderError::RegularInputIsScript => "You can't add a script input to this function. You can use `.add_native_script_input` or `.add_plutus_script_input` directly to register the input along with the witness.", - BuilderError::RegularInputIsFromRewardAddress => "You can't use an input from reward address. To spend funds from reward address you to use withdrawal mechanism.", - BuilderError::MalformedAddress => "The address is malformed." + BuilderError::RegularInputIsScript => "You can't add a script input to this function. You can use `.add_native_script_input` or `.add_plutus_script_input` directly to register the input along with the witness.".to_string(), + BuilderError::RegularInputIsFromRewardAddress => "You can't use an input from reward address. To spend funds from reward address you to use withdrawal mechanism.".to_string(), + BuilderError::MalformedAddress => "The address is malformed.".to_string(), + BuilderError::MintBuilderDifferentScriptType => "You can't add a mint to the same policy id but with different script type.".to_string(), + BuilderError::MintBuilderDifferentRedeemerDataAndExUnits(redeemer1, redeemer2) => format!("You can't add a mint to the same policy id but with different redeemer data and ex units. Current redeemer {redeemer1}, your redeemer {redeemer2}"), + BuilderError::MintBuilderDifferentWitnessTypeRef => "You can't add a mint to the same policy id but with different witness type. Current witness is ref input".to_string(), + BuilderError::MintBuilderDifferentWitnessTypeNonRef => "You can't add a mint to the same policy id but with different witness type. Current witness is non ref".to_string(), } } } diff --git a/rust/src/fakes.rs b/rust/src/fakes.rs index a06f689c..ff6fdd0d 100644 --- a/rust/src/fakes.rs +++ b/rust/src/fakes.rs @@ -1,5 +1,5 @@ #![allow(dead_code)] -use crate::{AnchorDataHash, AuxiliaryDataHash, BigNum, GenesisDelegateHash, GenesisHash, PoolMetadataHash, PublicKey, ScriptDataHash, ScriptHash, Vkeywitness, VRFKeyHash}; +use crate::{AnchorDataHash, AuxiliaryDataHash, BigNum, GenesisDelegateHash, GenesisHash, PlutusScript, PoolMetadataHash, PublicKey, ScriptDataHash, ScriptHash, Vkeywitness, VRFKeyHash}; use crate::{ Address, BaseAddress, Bip32PrivateKey, Credential, DataHash, Ed25519KeyHash, Ed25519Signature, NetworkInfo, PolicyID, TransactionHash, TransactionIndex, TransactionInput, @@ -125,4 +125,9 @@ pub(crate) fn fake_asset_name(x: u8) -> AssetName { pub(crate) fn fake_vkey_witness(x: u8) -> Vkeywitness { Vkeywitness::new(&fake_vkey_numbered(x), &fake_signature(x)) +} + +pub(crate) fn fake_plutus_script_and_hash(x: u8) -> (PlutusScript, ScriptHash) { + let s = PlutusScript::new(fake_bytes_32(x)); + (s.clone(), s.hash()) } \ No newline at end of file diff --git a/rust/src/protocol_types/plutus/redeemer.rs b/rust/src/protocol_types/plutus/redeemer.rs index a1abe0fb..f00fdaca 100644 --- a/rust/src/protocol_types/plutus/redeemer.rs +++ b/rust/src/protocol_types/plutus/redeemer.rs @@ -58,4 +58,8 @@ impl Redeemer { ex_units: self.ex_units.clone(), } } + + pub(crate) fn partially_eq(&self, other: &Redeemer) -> bool { + self.data == other.data && self.ex_units == other.ex_units + } } diff --git a/rust/src/tests/builders/mint_builder.rs b/rust/src/tests/builders/mint_builder.rs new file mode 100644 index 00000000..2270636d --- /dev/null +++ b/rust/src/tests/builders/mint_builder.rs @@ -0,0 +1,502 @@ +use crate::*; +use crate::fakes::{fake_plutus_script_and_hash, fake_script_hash, fake_tx_input}; +use crate::tests::mock_objects::{create_reallistic_tx_builder, create_redeemer}; + +#[test] +fn plutus_mint_with_script_ref_test() { + let mut tx_builder = create_reallistic_tx_builder(); + let colateral_adress = Address::from_bech32("addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w").unwrap(); + let colateral_input = fake_tx_input(0); + let tx_input = fake_tx_input(1); + let tx_input_ref = fake_tx_input(2); + + let (plutus_script, _) = fake_plutus_script_and_hash(1); + + let (plutus_script2, _) = fake_plutus_script_and_hash(2); + + let redeemer = create_redeemer(1); + + let redeemer2 = create_redeemer(2); + + let asset_name = AssetName::from_hex("44544e4654").unwrap(); + let mut mint_builder = MintBuilder::new(); + let plutus_script_source = PlutusScriptSource::new(&plutus_script); + let plutus_script_source_ref = PlutusScriptSource::new_ref_input( + &plutus_script2.hash(), + &tx_input_ref, + &Language::new_plutus_v2(), + 0, + ); + let mint_witnes = MintWitness::new_plutus_script(&plutus_script_source, &redeemer); + let mint_witnes_ref = MintWitness::new_plutus_script(&plutus_script_source_ref, &redeemer2); + mint_builder.add_asset(&mint_witnes, &asset_name, &Int::new(&BigNum::from(100u64))).unwrap(); + mint_builder.add_asset( + &mint_witnes_ref, + &asset_name, + &Int::new(&BigNum::from(100u64)), + ).unwrap(); + + let output_adress = Address::from_bech32("addr_test1qpm5njmgzf4t7225v6j34wl30xfrufzt3jtqtdzf3en9ahpmnhtmynpasyc8fq75zv0uaj86vzsr7g3g8q5ypgu5fwtqr9zsgj").unwrap(); + let mut output_assets = MultiAsset::new(); + let mut asset = Assets::new(); + asset.insert(&asset_name, &BigNum::from(100u64)); + output_assets.insert(&plutus_script.hash(), &asset); + let output_value = Value::new_with_assets(&Coin::from(50000000u64), &output_assets); + let output = TransactionOutput::new(&output_adress, &output_value); + + let mut col_builder = TxInputsBuilder::new(); + col_builder.add_regular_input( + &colateral_adress, + &colateral_input, + &Value::new(&Coin::from(1000000000u64)), + ).unwrap(); + tx_builder.set_collateral(&col_builder); + tx_builder.add_output(&output).unwrap(); + tx_builder.add_regular_input( + &output_adress, + &tx_input, + &Value::new(&BigNum::from(100000000000u64)), + ).unwrap(); + tx_builder.set_mint_builder(&mint_builder); + + tx_builder + .calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()) + .unwrap(); + + let change_res = tx_builder.add_change_if_needed(&output_adress); + assert!(change_res.is_ok()); + + let build_res = tx_builder.build_tx(); + assert!(build_res.is_ok()); + + let tx = build_res.unwrap(); + assert_eq!(tx.witness_set.plutus_scripts.unwrap().len(), 1usize); + assert_eq!(tx.witness_set.redeemers.unwrap().len(), 2usize); + assert!(tx.witness_set.plutus_data.is_none()); + assert_eq!(tx.body.reference_inputs.unwrap().len(), 1usize); + assert!(tx.body.mint.is_some()); + assert_eq!(tx.body.mint.unwrap().len(), 2usize); +} + +#[test] +fn different_redeemers_error() { + let (plutus_script, _) = fake_plutus_script_and_hash(1); + let redeemer = create_redeemer(1); + let redeemer2 = create_redeemer(2); + + let asset_name = AssetName::from_hex("44544e4654").unwrap(); + let mut mint_builder = MintBuilder::new(); + let plutus_script_source = PlutusScriptSource::new(&plutus_script); + let mint_witnes = MintWitness::new_plutus_script(&plutus_script_source, &redeemer); + let mint_witnes2 = MintWitness::new_plutus_script(&plutus_script_source, &redeemer2); + + let res1 = mint_builder.add_asset(&mint_witnes, &asset_name, &Int::new(&BigNum::from(100u64))); + assert!(res1.is_ok()); + + let res1 = mint_builder.add_asset(&mint_witnes2, &asset_name, &Int::new(&BigNum::from(100u64))); + assert!(res1.is_err()); +} + +#[test] +fn same_redeemers() { + let (plutus_script, _) = fake_plutus_script_and_hash(1); + let redeemer = create_redeemer(1); + let mut redeemer2 = redeemer.clone(); + redeemer2.index = BigNum::from(77u64); + redeemer2.tag = RedeemerTag::new_voting_proposal(); + + let asset_name1 = AssetName::from_hex("44544e4654").unwrap(); + let asset_name2 = AssetName::from_hex("44544e4655").unwrap(); + let mut mint_builder = MintBuilder::new(); + let plutus_script_source = PlutusScriptSource::new(&plutus_script); + let mint_witnes = MintWitness::new_plutus_script(&plutus_script_source, &redeemer); + let mint_witnes2 = MintWitness::new_plutus_script(&plutus_script_source, &redeemer2); + + let res1 = mint_builder.add_asset(&mint_witnes, &asset_name1, &Int::new(&BigNum::from(100u64))); + assert!(res1.is_ok()); + + let res1 = mint_builder.add_asset(&mint_witnes2, &asset_name2, &Int::new(&BigNum::from(100u64))); + assert!(res1.is_ok()); +} + +#[test] +fn plutus_mint_test() { + let mut tx_builder = create_reallistic_tx_builder(); + let colateral_adress = Address::from_bech32("addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w").unwrap(); + let colateral_input = fake_tx_input(0); + + let tx_input = fake_tx_input(1); + let (plutus_script, _) = fake_plutus_script_and_hash(1); + + let redeemer = create_redeemer(1); + let asset_name = AssetName::from_hex("44544e4654").unwrap(); + let mut mint_builder = MintBuilder::new(); + let plutus_script_source = PlutusScriptSource::new(&plutus_script); + let mint_witnes = MintWitness::new_plutus_script(&plutus_script_source, &redeemer); + mint_builder.add_asset(&mint_witnes, &asset_name, &Int::new(&BigNum::from(100u64))).unwrap(); + + let output_adress = Address::from_bech32("addr_test1qpm5njmgzf4t7225v6j34wl30xfrufzt3jtqtdzf3en9ahpmnhtmynpasyc8fq75zv0uaj86vzsr7g3g8q5ypgu5fwtqr9zsgj").unwrap(); + let mut output_assets = MultiAsset::new(); + let mut asset = Assets::new(); + asset.insert(&asset_name, &BigNum::from(100u64)); + output_assets.insert(&plutus_script.hash(), &asset); + let output_value = Value::new_with_assets(&Coin::from(5000000u64), &output_assets); + let output = TransactionOutput::new(&output_adress, &output_value); + + let mut col_builder = TxInputsBuilder::new(); + col_builder.add_regular_input( + &colateral_adress, + &colateral_input, + &Value::new(&Coin::from(1000000000000u64)), + ).unwrap(); + tx_builder.set_collateral(&col_builder); + tx_builder.add_output(&output).unwrap(); + tx_builder.add_regular_input( + &output_adress, + &tx_input, + &Value::new(&BigNum::from(100000000000000u64)), + ).unwrap(); + tx_builder.set_mint_builder(&mint_builder); + + tx_builder + .calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()) + .unwrap(); + + let change_res = tx_builder.add_change_if_needed(&output_adress); + assert!(change_res.is_ok()); + + let build_res = tx_builder.build_tx(); + assert!(build_res.is_ok()); + + assert_eq!(mint_builder.get_plutus_witnesses().len(), 1); + + let tx = build_res.unwrap(); + assert!(tx.body.mint.is_some()); + assert_eq!( + tx.body.mint.unwrap().0.iter().next().unwrap().0, + plutus_script.hash() + ); +} + +#[test] +fn ref_inputs() { + let script_hash_1 = fake_script_hash(1); + let script_hash_2 = fake_script_hash(2); + let tx_input_ref1 = fake_tx_input(2); + let tx_input_ref2 = fake_tx_input(3); + let redeemer = create_redeemer(1); + + let asset_name1 = AssetName::from_hex("44544e4654").unwrap(); + let asset_name2 = AssetName::from_hex("44544e4655").unwrap(); + + let mut mint_builder = MintBuilder::new(); + let plutus_script_source = PlutusScriptSource::new_ref_input( + &script_hash_1, + &tx_input_ref1, + &Language::new_plutus_v2(), + 0, + ); + let native_script_source = NativeScriptSource::new_ref_input( + &script_hash_2, + &tx_input_ref2, + ); + + let mint_witnes = MintWitness::new_plutus_script(&plutus_script_source, &redeemer); + let mint_witnes2 = MintWitness::new_native_script(&native_script_source); + + mint_builder.add_asset(&mint_witnes, &asset_name1, &Int::new(&BigNum::from(100u64))).unwrap(); + mint_builder.add_asset(&mint_witnes2, &asset_name2, &Int::new(&BigNum::from(100u64))).unwrap(); + + let ref_inputs = mint_builder.get_ref_inputs(); + + assert_eq!(ref_inputs.len(), 2); + assert!(ref_inputs.contains(&tx_input_ref1)); + assert!(ref_inputs.contains(&tx_input_ref2)); +} + +#[test] +fn multiple_mints() { + let script_hash_1 = fake_script_hash(1); + let script_hash_2 = fake_script_hash(2); + let tx_input_ref1 = fake_tx_input(2); + let tx_input_ref2 = fake_tx_input(3); + let redeemer = create_redeemer(1); + + let asset_name1 = AssetName::from_hex("44544e4654").unwrap(); + let asset_name2 = AssetName::from_hex("44544e4655").unwrap(); + let asset_name3 = AssetName::from_hex("44544e4656").unwrap(); + + let mut mint_builder = MintBuilder::new(); + let plutus_script_source = PlutusScriptSource::new_ref_input( + &script_hash_1, + &tx_input_ref1, + &Language::new_plutus_v2(), + 0, + ); + + let native_script_source = NativeScriptSource::new_ref_input( + &script_hash_2, + &tx_input_ref2, + ); + + let mint_witnes = MintWitness::new_plutus_script(&plutus_script_source, &redeemer); + let mint_witnes2 = MintWitness::new_native_script(&native_script_source); + + mint_builder.add_asset(&mint_witnes, &asset_name1, &Int::new(&BigNum::from(100u64))).unwrap(); + mint_builder.add_asset(&mint_witnes2, &asset_name2, &Int::new(&BigNum::from(101u64))).unwrap(); + mint_builder.add_asset(&mint_witnes2, &asset_name3, &Int::new(&BigNum::from(102u64))).unwrap(); + + let mint = mint_builder.build(); + assert_eq!(mint.len(), 2); + + let policy_mints_list = mint.get(&script_hash_1).unwrap(); + let policy_mints_list2 = mint.get(&script_hash_2).unwrap(); + + assert_eq!(policy_mints_list.len(), 1); + assert_eq!(policy_mints_list2.len(), 1); + + let policy_mints = policy_mints_list.get(0).unwrap(); + let policy_mints2 = policy_mints_list2.get(0).unwrap(); + + assert_eq!(policy_mints.len(), 1); + assert_eq!(policy_mints2.len(), 2); + + assert_eq!(policy_mints.get(&asset_name1).unwrap().to_str(), "100"); + assert_eq!(policy_mints2.get(&asset_name2).unwrap().to_str(), "101"); + assert_eq!(policy_mints2.get(&asset_name3).unwrap().to_str(), "102"); +} + +#[test] +fn native_script_mint() { + let native_script = NativeScript::new_timelock_start( + &TimelockStart::new_timelockstart(&BigNum::from(100u64)), + ); + let script_hash = native_script.hash(); + + let asset_name1 = AssetName::from_hex("44544e4654").unwrap(); + + let mut mint_builder = MintBuilder::new(); + + let native_script_source = NativeScriptSource::new(&native_script); + let mint_witnes = MintWitness::new_native_script(&native_script_source); + mint_builder.add_asset(&mint_witnes, &asset_name1, &Int::new(&BigNum::from(100u64))).unwrap(); + + let mint = mint_builder.build(); + assert_eq!(mint.len(), 1); + + let policy_mints_list = mint.get(&script_hash).unwrap(); + assert_eq!(policy_mints_list.len(), 1); + + let policy_mints = policy_mints_list.get(0).unwrap(); + assert_eq!(policy_mints.len(), 1); + assert_eq!(policy_mints.get(&asset_name1).unwrap().to_str(), "100"); + + let native_scripts = mint_builder.get_native_scripts(); + assert_eq!(native_scripts.len(), 1); + + assert_eq!(native_scripts.get(0), native_script); +} + +#[test] +fn different_script_type_error() { + let script_hash_1 = fake_script_hash(1); + let script_hash_2 = fake_script_hash(2); + let tx_input_ref1 = fake_tx_input(2); + let tx_input_ref2 = fake_tx_input(3); + let redeemer = create_redeemer(1); + + let asset_name1 = AssetName::from_hex("44544e4654").unwrap(); + let asset_name2 = AssetName::from_hex("44544e4655").unwrap(); + + let mut mint_builder = MintBuilder::new(); + let plutus_script_source1 = PlutusScriptSource::new_ref_input( + &script_hash_1, + &tx_input_ref1, + &Language::new_plutus_v2(), + 0, + ); + let plutus_script_source2 = PlutusScriptSource::new_ref_input( + &script_hash_2, + &tx_input_ref2, + &Language::new_plutus_v2(), + 0, + ); + + let native_script_source1 = NativeScriptSource::new_ref_input( + &script_hash_2, + &tx_input_ref2, + ); + let native_script_source2 = NativeScriptSource::new_ref_input( + &script_hash_1, + &tx_input_ref1, + ); + + let mint_witnes_plutus_1 = MintWitness::new_plutus_script(&plutus_script_source1, &redeemer); + let mint_witnes_plutus_2 = MintWitness::new_plutus_script(&plutus_script_source2, &redeemer); + let mint_witnes_native_1 = MintWitness::new_native_script(&native_script_source1); + let mint_witnes_native_2 = MintWitness::new_native_script(&native_script_source2); + + mint_builder.add_asset(&mint_witnes_plutus_1, &asset_name1, &Int::new(&BigNum::from(100u64))).unwrap(); + mint_builder.add_asset(&mint_witnes_native_1, &asset_name2, &Int::new(&BigNum::from(101u64))).unwrap(); + + let res = mint_builder.add_asset(&mint_witnes_plutus_2, &asset_name1, &Int::new(&BigNum::from(100u64))); + assert!(res.is_err()); + + let res = mint_builder.add_asset(&mint_witnes_native_2, &asset_name2, &Int::new(&BigNum::from(101u64))); + assert!(res.is_err()); +} + +#[test] +fn wrong_witness_type_ref_error() { + let native_script = NativeScript::new_timelock_start( + &TimelockStart::new_timelockstart(&BigNum::from(100u64)), + ); + let (plutus_script, script_hash_1) = fake_plutus_script_and_hash(5); + let script_hash_2 = native_script.hash(); + let tx_input_ref1 = fake_tx_input(2); + let tx_input_ref2 = fake_tx_input(3); + let redeemer = create_redeemer(1); + + let asset_name1 = AssetName::from_hex("44544e4654").unwrap(); + let asset_name2 = AssetName::from_hex("44544e4655").unwrap(); + let asset_name3 = AssetName::from_hex("44544e4656").unwrap(); + let asset_name4 = AssetName::from_hex("44544e4657").unwrap(); + + let mut mint_builder = MintBuilder::new(); + + let plutus_script_source_1 = PlutusScriptSource::new_ref_input( + &script_hash_1, + &tx_input_ref1, + &Language::new_plutus_v2(), + 0, + ); + let plutus_script_source_2 = PlutusScriptSource::new(&plutus_script); + + let native_script_source_1 = NativeScriptSource::new_ref_input( + &script_hash_2, + &tx_input_ref2, + ); + let native_script_source_2 = NativeScriptSource::new(&native_script); + + let mint_witness_plutus_1 = MintWitness::new_plutus_script(&plutus_script_source_1, &redeemer); + let mint_witness_plutus_2 = MintWitness::new_plutus_script(&plutus_script_source_2, &redeemer); + + let mint_witness_native_1 = MintWitness::new_native_script(&native_script_source_1); + let mint_witness_native_2 = MintWitness::new_native_script(&native_script_source_2); + + let res1 = mint_builder.add_asset(&mint_witness_plutus_1, &asset_name1, &Int::new(&BigNum::from(100u64))); + assert!(res1.is_ok()); + + let res2 = mint_builder.add_asset(&mint_witness_plutus_2, &asset_name2, &Int::new(&BigNum::from(101u64))); + assert!(res2.is_err()); + + let res3 = mint_builder.add_asset(&mint_witness_native_1, &asset_name3, &Int::new(&BigNum::from(102u64))); + assert!(res3.is_ok()); + + let res4= mint_builder.add_asset(&mint_witness_native_2, &asset_name4, &Int::new(&BigNum::from(103u64))); + assert!(res4.is_err()); + + let mint = mint_builder.build(); + assert_eq!(mint.len(), 2); + + let policy_mints_list = mint.get(&script_hash_1).unwrap(); + let policy_mints_list2 = mint.get(&script_hash_2).unwrap(); + + assert_eq!(policy_mints_list.len(), 1); + assert_eq!(policy_mints_list2.len(), 1); + + let policy_mints = policy_mints_list.get(0).unwrap(); + let policy_mints2 = policy_mints_list2.get(0).unwrap(); + + assert_eq!(policy_mints.len(), 1); + assert_eq!(policy_mints2.len(), 1); + + assert_eq!(policy_mints.get(&asset_name1).unwrap().to_str(), "100"); + assert_eq!(policy_mints2.get(&asset_name3).unwrap().to_str(), "102"); +} + +#[test] +fn wrong_witness_type_no_ref_error() { + let native_script = NativeScript::new_timelock_start( + &TimelockStart::new_timelockstart(&BigNum::from(100u64)), + ); + let (plutus_script, script_hash_1) = fake_plutus_script_and_hash(5); + let script_hash_2 = native_script.hash(); + let tx_input_ref1 = fake_tx_input(2); + let tx_input_ref2 = fake_tx_input(3); + let redeemer = create_redeemer(1); + + let asset_name1 = AssetName::from_hex("44544e4654").unwrap(); + let asset_name2 = AssetName::from_hex("44544e4655").unwrap(); + let asset_name3 = AssetName::from_hex("44544e4656").unwrap(); + let asset_name4 = AssetName::from_hex("44544e4657").unwrap(); + + let mut mint_builder = MintBuilder::new(); + + let plutus_script_source_1 = PlutusScriptSource::new_ref_input( + &script_hash_1, + &tx_input_ref1, + &Language::new_plutus_v2(), + 0, + ); + let plutus_script_source_2 = PlutusScriptSource::new(&plutus_script); + + let native_script_source_1 = NativeScriptSource::new_ref_input( + &script_hash_2, + &tx_input_ref2, + ); + let native_script_source_2 = NativeScriptSource::new(&native_script); + + let mint_witness_plutus_1 = MintWitness::new_plutus_script(&plutus_script_source_2, &redeemer); + let mint_witness_plutus_2 = MintWitness::new_plutus_script(&plutus_script_source_1, &redeemer); + + let mint_witness_native_1 = MintWitness::new_native_script(&native_script_source_2); + let mint_witness_native_2 = MintWitness::new_native_script(&native_script_source_1); + + let res1 = mint_builder.add_asset(&mint_witness_plutus_1, &asset_name1, &Int::new(&BigNum::from(100u64))); + assert!(res1.is_ok()); + + let res2 = mint_builder.add_asset(&mint_witness_plutus_2, &asset_name2, &Int::new(&BigNum::from(101u64))); + assert!(res2.is_err()); + + let res3 = mint_builder.add_asset(&mint_witness_native_1, &asset_name3, &Int::new(&BigNum::from(102u64))); + assert!(res3.is_ok()); + + let res4= mint_builder.add_asset(&mint_witness_native_2, &asset_name4, &Int::new(&BigNum::from(103u64))); + assert!(res4.is_err()); + + let mint = mint_builder.build(); + assert_eq!(mint.len(), 2); + + let policy_mints_list = mint.get(&script_hash_1).unwrap(); + let policy_mints_list2 = mint.get(&script_hash_2).unwrap(); + + assert_eq!(policy_mints_list.len(), 1); + assert_eq!(policy_mints_list2.len(), 1); + + let policy_mints = policy_mints_list.get(0).unwrap(); + let policy_mints2 = policy_mints_list2.get(0).unwrap(); + + assert_eq!(policy_mints.len(), 1); + assert_eq!(policy_mints2.len(), 1); + + assert_eq!(policy_mints.get(&asset_name1).unwrap().to_str(), "100"); + assert_eq!(policy_mints2.get(&asset_name3).unwrap().to_str(), "102"); +} + +#[test] +fn zero_mint_error() { + let native_script = NativeScript::new_timelock_start( + &TimelockStart::new_timelockstart(&BigNum::from(100u64)), + ); + let asset_name1 = AssetName::from_hex("44544e4654").unwrap(); + let mut mint_builder = MintBuilder::new(); + + let native_script_source = NativeScriptSource::new(&native_script); + + + let mint_witness_native = MintWitness::new_native_script(&native_script_source); + + let res= mint_builder.add_asset(&mint_witness_native, &asset_name1, &Int::new(&BigNum::from(0u64))); + assert!(res.is_err()); +} \ No newline at end of file diff --git a/rust/src/tests/builders/mod.rs b/rust/src/tests/builders/mod.rs index 76eaacb8..ea43ed40 100644 --- a/rust/src/tests/builders/mod.rs +++ b/rust/src/tests/builders/mod.rs @@ -2,4 +2,5 @@ mod batch_tools; mod tx_builder; mod voting_builder; mod voting_proposal_builder; -mod certificates_builder; \ No newline at end of file +mod certificates_builder; +mod mint_builder; \ No newline at end of file diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index 6367559f..05c2c314 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -1,8 +1,4 @@ -use crate::fakes::{ - fake_base_address, fake_bytes_32, fake_data_hash, fake_key_hash, fake_policy_id, - fake_script_hash, fake_tx_hash, fake_tx_input, fake_tx_input2, fake_value, fake_value2, - fake_vkey_witness, -}; +use crate::fakes::{fake_base_address, fake_bytes_32, fake_data_hash, fake_key_hash, fake_plutus_script_and_hash, fake_policy_id, fake_script_hash, fake_tx_hash, fake_tx_input, fake_tx_input2, fake_value, fake_value2, fake_vkey_witness}; use crate::tests::helpers::harden; use crate::tests::mock_objects::{byron_address, create_anchor, create_change_address, create_default_tx_builder, create_linear_fee, create_reallistic_tx_builder, create_redeemer, create_redeemer_zero_cost, create_rich_tx_builder, create_tx_builder, create_tx_builder_with_amount, create_tx_builder_with_fee, create_tx_builder_with_fee_and_pure_change, create_tx_builder_with_fee_and_val_size, create_tx_builder_with_key_deposit, root_key_15}; use crate::*; @@ -154,7 +150,7 @@ fn build_tx_with_change_with_datum() { let datum_hash = fake_data_hash(20); let data_option = OutputDatum::new_data_hash(&datum_hash); - let (_, script_hash) = plutus_script_and_hash(15); + let (_, script_hash) = fake_plutus_script_and_hash(15); let change_cred = Credential::from_scripthash(&script_hash); let change_addr = BaseAddress::new( NetworkInfo::testnet_preprod().network_id(), @@ -3125,11 +3121,6 @@ fn mint_script_and_policy(x: u8) -> (NativeScript, ScriptHash) { (m, p) } -fn plutus_script_and_hash(x: u8) -> (PlutusScript, ScriptHash) { - let s = PlutusScript::new(fake_bytes_32(x)); - (s.clone(), s.hash()) -} - #[test] fn set_mint_asset_with_empty_mint() { let mut tx_builder = create_default_tx_builder(); @@ -3827,7 +3818,7 @@ fn test_native_input_scripts_are_added_to_the_witnesses() { #[test] fn test_adding_plutus_script_input() { let mut tx_builder = create_reallistic_tx_builder(); - let (script1, _) = plutus_script_and_hash(0); + let (script1, _) = fake_plutus_script_and_hash(0); let datum = PlutusData::new_bytes(fake_bytes_32(1)); let redeemer_datum = PlutusData::new_bytes(fake_bytes_32(2)); let redeemer = Redeemer::new( @@ -3856,8 +3847,8 @@ fn test_adding_plutus_script_input() { fn test_adding_plutus_script_witnesses() { let mut tx_builder = create_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); - let (script1, _) = plutus_script_and_hash(0); - let (script2, _) = plutus_script_and_hash(1); + let (script1, _) = fake_plutus_script_and_hash(0); + let (script2, _) = fake_plutus_script_and_hash(1); let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); let redeemer1 = Redeemer::new( @@ -3921,7 +3912,7 @@ fn test_existing_plutus_scripts_require_data_hash() { let mut tx_builder = create_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); - let (script1, _) = plutus_script_and_hash(0); + let (script1, _) = fake_plutus_script_and_hash(0); let datum = PlutusData::new_bytes(fake_bytes_32(1)); let redeemer_datum = PlutusData::new_bytes(fake_bytes_32(2)); let redeemer = Redeemer::new( @@ -3962,7 +3953,7 @@ fn test_calc_script_hash_data() { tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); - let (script1, _) = plutus_script_and_hash(0); + let (script1, _) = fake_plutus_script_and_hash(0); let datum = PlutusData::new_bytes(fake_bytes_32(1)); let redeemer_datum = PlutusData::new_bytes(fake_bytes_32(2)); let redeemer = Redeemer::new( @@ -4002,8 +3993,8 @@ fn test_plutus_witness_redeemer_index_auto_changing() { let mut tx_builder = create_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); - let (script1, _) = plutus_script_and_hash(0); - let (script2, _) = plutus_script_and_hash(1); + let (script1, _) = fake_plutus_script_and_hash(0); + let (script2, _) = fake_plutus_script_and_hash(1); let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); @@ -4072,8 +4063,8 @@ fn test_native_and_plutus_scripts_together() { let mut tx_builder = create_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); - let (pscript1, _) = plutus_script_and_hash(0); - let (pscript2, phash2) = plutus_script_and_hash(1); + let (pscript1, _) = fake_plutus_script_and_hash(0); + let (pscript2, phash2) = fake_plutus_script_and_hash(1); let (nscript1, _) = mint_script_and_policy(0); let (nscript2, nhash2) = mint_script_and_policy(1); let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); @@ -4158,8 +4149,8 @@ fn test_json_serialization_native_and_plutus_scripts_together() { let mut tx_builder = create_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); - let (pscript1, _) = plutus_script_and_hash(0); - let (pscript2, phash2) = plutus_script_and_hash(1); + let (pscript1, _) = fake_plutus_script_and_hash(0); + let (pscript2, phash2) = fake_plutus_script_and_hash(1); let (nscript1, _) = mint_script_and_policy(0); let (nscript2, nhash2) = mint_script_and_policy(1); let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); @@ -4265,8 +4256,8 @@ fn test_regular_and_collateral_inputs_same_keyhash() { fn test_regular_and_collateral_inputs_together() { let mut tx_builder = create_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); - let (pscript1, _) = plutus_script_and_hash(0); - let (pscript2, _) = plutus_script_and_hash(1); + let (pscript1, _) = fake_plutus_script_and_hash(0); + let (pscript2, _) = fake_plutus_script_and_hash(1); let (nscript1, _) = mint_script_and_policy(0); let (nscript2, _) = mint_script_and_policy(1); let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); @@ -4362,7 +4353,7 @@ fn test_ex_unit_costs_are_added_to_the_fees() { &Value::new(&BigNum(1_000_000)), ); - let (pscript1, _) = plutus_script_and_hash(0); + let (pscript1, _) = fake_plutus_script_and_hash(0); let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); let redeemer1 = Redeemer::new( &RedeemerTag::new_spend(), @@ -4398,8 +4389,8 @@ fn test_script_inputs_ordering() { let mut tx_builder = create_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); let (nscript1, _) = mint_script_and_policy(0); - let (pscript1, _) = plutus_script_and_hash(0); - let (pscript2, _) = plutus_script_and_hash(1); + let (pscript1, _) = fake_plutus_script_and_hash(0); + let (pscript2, _) = fake_plutus_script_and_hash(1); let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); // Creating redeemers with indexes ZERO @@ -4966,7 +4957,7 @@ fn test_costmodel_retaining_for_v1() { tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); - let (script1, _) = plutus_script_and_hash(0); + let (script1, _) = fake_plutus_script_and_hash(0); let datum = PlutusData::new_integer(&BigInt::from_str("42").unwrap()); let redeemer = Redeemer::new( &RedeemerTag::new_spend(), @@ -5010,7 +5001,7 @@ fn test_costmodel_retaining_fails_on_missing_costmodel() { tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); - let (script1, _) = plutus_script_and_hash(0); + let (script1, _) = fake_plutus_script_and_hash(0); let datum = PlutusData::new_integer(&BigInt::from_str("42").unwrap()); let redeemer = Redeemer::new( &RedeemerTag::new_spend(), @@ -5472,321 +5463,12 @@ fn coin_selection_random_improve_multi_asset() { assert!(res.is_ok()); } -#[test] -fn plutus_mint_test() { - let mut tx_builder = create_reallistic_tx_builder(); - let colateral_adress = Address::from_bech32("addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w").unwrap(); - let colateral_input = TransactionInput::from_json("\ - { - \"transaction_id\": \"69b0b867056a2d4fdc3827e23aa7069b125935e2def774941ca8cc7f9e0de774\", - \"index\": 1 - }").unwrap(); - - let tx_input = TransactionInput::from_json("\ - { - \"transaction_id\": \"f58a5bc761b1efdcf4b5684f6ad5495854a0d64b866e2f0f525d134750d3511b\", - \"index\": 1 - }").unwrap(); - let plutus_script = PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); - let redeemer = Redeemer::from_json( - "\ - { - \"tag\": \"Mint\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"1042996\", - \"steps\": \"446100241\" - } - }", - ) - .unwrap(); - let asset_name = AssetName::from_hex("44544e4654").unwrap(); - let mut mint_builder = MintBuilder::new(); - let plutus_script_source = PlutusScriptSource::new(&plutus_script); - let mint_witnes = MintWitness::new_plutus_script(&plutus_script_source, &redeemer); - mint_builder.add_asset(&mint_witnes, &asset_name, &Int::new(&BigNum::from(100u64))); - - let output_adress = Address::from_bech32("addr_test1qpm5njmgzf4t7225v6j34wl30xfrufzt3jtqtdzf3en9ahpmnhtmynpasyc8fq75zv0uaj86vzsr7g3g8q5ypgu5fwtqr9zsgj").unwrap(); - let mut output_assets = MultiAsset::new(); - let mut asset = Assets::new(); - asset.insert(&asset_name, &BigNum::from(100u64)); - output_assets.insert(&plutus_script.hash(), &asset); - let output_value = Value::new_with_assets(&Coin::from(50000u64), &output_assets); - let output = TransactionOutput::new(&output_adress, &output_value); - - let mut col_builder = TxInputsBuilder::new(); - col_builder.add_regular_input( - &colateral_adress, - &colateral_input, - &Value::new(&Coin::from(1000000000u64)), - ); - tx_builder.set_collateral(&col_builder); - tx_builder.add_output(&output); - tx_builder.add_regular_input( - &output_adress, - &tx_input, - &Value::new(&BigNum::from(100000000000u64)), - ); - tx_builder.set_mint_builder(&mint_builder); - - tx_builder - .calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()) - .unwrap(); - - let change_res = tx_builder.add_change_if_needed(&output_adress); - assert!(change_res.is_ok()); - - let build_res = tx_builder.build_tx(); - assert!(build_res.is_ok()); - - assert!(mint_builder.get_plutus_witnesses().len() == 1); - - let tx = build_res.unwrap(); - assert!(tx.body.mint.is_some()); - assert_eq!( - tx.body.mint.unwrap().0.iter().next().unwrap().0, - plutus_script.hash() - ); -} - -#[test] -fn plutus_mint_with_script_ref_test() { - let mut tx_builder = create_reallistic_tx_builder(); - let colateral_adress = Address::from_bech32("addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w").unwrap(); - let colateral_input = TransactionInput::from_json("\ - { - \"transaction_id\": \"69b0b867056a2d4fdc3827e23aa7069b125935e2def774941ca8cc7f9e0de774\", - \"index\": 1 - }").unwrap(); - - let tx_input = TransactionInput::from_json("\ - { - \"transaction_id\": \"f58a5bc761b1efdcf4b5684f6ad5495854a0d64b866e2f0f525d134750d3511b\", - \"index\": 1 - }").unwrap(); - let tx_input_ref = TransactionInput::from_json("\ - { - \"transaction_id\": \"f58a5bc7adaadadcf4b5684f6ad5495854a0d64b866e2f0f525d134750d3511b\", - \"index\": 2 - }").unwrap(); - let plutus_script = PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); - let plutus_script2 = PlutusScript::from_hex("5907adaada00332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); - - let redeemer = Redeemer::from_json( - "\ - { - \"tag\": \"Mint\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"1042996\", - \"steps\": \"446100241\" - } - }", - ) - .unwrap(); - - let redeemer2 = Redeemer::from_json( - "\ - { - \"tag\": \"Mint\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"2929292\", - \"steps\": \"446188888\" - } - }", - ) - .unwrap(); - - let asset_name = AssetName::from_hex("44544e4654").unwrap(); - let mut mint_builder = MintBuilder::new(); - let plutus_script_source = PlutusScriptSource::new(&plutus_script); - let plutus_script_source_ref = PlutusScriptSource::new_ref_input( - &plutus_script2.hash(), - &tx_input_ref, - &Language::new_plutus_v2(), - 0, - ); - let mint_witnes = MintWitness::new_plutus_script(&plutus_script_source, &redeemer); - let mint_witnes_ref = MintWitness::new_plutus_script(&plutus_script_source_ref, &redeemer2); - mint_builder.add_asset(&mint_witnes, &asset_name, &Int::new(&BigNum::from(100u64))); - mint_builder.add_asset( - &mint_witnes_ref, - &asset_name, - &Int::new(&BigNum::from(100u64)), - ); - - let output_adress = Address::from_bech32("addr_test1qpm5njmgzf4t7225v6j34wl30xfrufzt3jtqtdzf3en9ahpmnhtmynpasyc8fq75zv0uaj86vzsr7g3g8q5ypgu5fwtqr9zsgj").unwrap(); - let mut output_assets = MultiAsset::new(); - let mut asset = Assets::new(); - asset.insert(&asset_name, &BigNum::from(100u64)); - output_assets.insert(&plutus_script.hash(), &asset); - let output_value = Value::new_with_assets(&Coin::from(50000u64), &output_assets); - let output = TransactionOutput::new(&output_adress, &output_value); - - let mut col_builder = TxInputsBuilder::new(); - col_builder.add_regular_input( - &colateral_adress, - &colateral_input, - &Value::new(&Coin::from(1000000000u64)), - ); - tx_builder.set_collateral(&col_builder); - tx_builder.add_output(&output); - tx_builder.add_regular_input( - &output_adress, - &tx_input, - &Value::new(&BigNum::from(100000000000u64)), - ); - tx_builder.set_mint_builder(&mint_builder); - - tx_builder - .calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()) - .unwrap(); - - let change_res = tx_builder.add_change_if_needed(&output_adress); - assert!(change_res.is_ok()); - - let build_res = tx_builder.build_tx(); - assert!(build_res.is_ok()); - - let tx = build_res.unwrap(); - assert_eq!(tx.witness_set.plutus_scripts.unwrap().len(), 1usize); - assert_eq!(tx.witness_set.redeemers.unwrap().len(), 2usize); - assert!(tx.witness_set.plutus_data.is_none()); - assert_eq!(tx.body.reference_inputs.unwrap().len(), 1usize); - assert!(tx.body.mint.is_some()); - assert_eq!(tx.body.mint.unwrap().len(), 2usize); -} - -#[test] -fn plutus_mint_defferent_redeemers_test() { - let mut tx_builder = create_reallistic_tx_builder(); - let colateral_adress = Address::from_bech32("addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w").unwrap(); - let colateral_input = TransactionInput::from_json("\ - { - \"transaction_id\": \"69b0b867056a2d4fdc3827e23aa7069b125935e2def774941ca8cc7f9e0de774\", - \"index\": 1 - }").unwrap(); - - let tx_input = TransactionInput::from_json("\ - { - \"transaction_id\": \"f58a5bc761b1efdcf4b5684f6ad5495854a0d64b866e2f0f525d134750d3511b\", - \"index\": 1 - }").unwrap(); - let plutus_script = PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); - - let redeemer = Redeemer::from_json( - "\ - { - \"tag\": \"Mint\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"1042996\", - \"steps\": \"446100241\" - } - }", - ) - .unwrap(); - - let redeemer2 = Redeemer::from_json( - "\ - { - \"tag\": \"Mint\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"2929292\", - \"steps\": \"446188888\" - } - }", - ) - .unwrap(); - - let asset_name = AssetName::from_hex("44544e4654").unwrap(); - let mut mint_builder = MintBuilder::new(); - let plutus_script_source = PlutusScriptSource::new(&plutus_script); - let mint_witnes = MintWitness::new_plutus_script(&plutus_script_source, &redeemer); - let mint_witnes2 = MintWitness::new_plutus_script(&plutus_script_source, &redeemer2); - mint_builder.add_asset(&mint_witnes, &asset_name, &Int::new(&BigNum::from(100u64))); - mint_builder.add_asset(&mint_witnes2, &asset_name, &Int::new(&BigNum::from(100u64))); - - let output_adress = Address::from_bech32("addr_test1qpm5njmgzf4t7225v6j34wl30xfrufzt3jtqtdzf3en9ahpmnhtmynpasyc8fq75zv0uaj86vzsr7g3g8q5ypgu5fwtqr9zsgj").unwrap(); - let mut output_assets = MultiAsset::new(); - let mut asset = Assets::new(); - asset.insert(&asset_name, &BigNum::from(100u64)); - output_assets.insert(&plutus_script.hash(), &asset); - let output_value = Value::new_with_assets(&Coin::from(1142150u64), &output_assets); - let output = TransactionOutput::new(&output_adress, &output_value); - - let mut col_builder = TxInputsBuilder::new(); - col_builder.add_regular_input( - &colateral_adress, - &colateral_input, - &Value::new(&Coin::from(1000000000u64)), - ); - tx_builder.set_collateral(&col_builder); - tx_builder.add_output(&output).unwrap(); - tx_builder.add_regular_input( - &output_adress, - &tx_input, - &Value::new(&BigNum::from(100000000000u64)), - ); - tx_builder.set_mint_builder(&mint_builder); - - tx_builder - .calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()) - .unwrap(); - - let change_res = tx_builder.add_change_if_needed(&output_adress); - assert!(change_res.is_ok()); - - let build_res = tx_builder.build_tx(); - assert!(build_res.is_ok()); - - let tx = build_res.unwrap(); - assert_eq!(tx.witness_set.plutus_scripts.unwrap().len(), 1usize); - assert_eq!(tx.witness_set.redeemers.unwrap().len(), 2usize); - assert!(tx.witness_set.plutus_data.is_none()); - assert!(tx.body.reference_inputs.is_none()); - assert!(tx.body.mint.is_some()); - assert_eq!(tx.body.mint.unwrap().len(), 2usize); -} - #[test] fn multiple_plutus_inputs_test() { let mut tx_builder = create_reallistic_tx_builder(); - let plutus_script = PlutusScript::from_hex("5907d2010000332323232323232323232323232323322323232323222232325335332201b3333573466e1cd55ce9baa0044800080608c98c8060cd5ce00c80c00b1999ab9a3370e6aae7540092000233221233001003002323232323232323232323232323333573466e1cd55cea8062400046666666666664444444444442466666666666600201a01801601401201000e00c00a00800600466a02a02c6ae854030cd4054058d5d0a80599a80a80b9aba1500a3335501975ca0306ae854024ccd54065d7280c1aba1500833501502035742a00e666aa032042eb4d5d0a8031919191999ab9a3370e6aae75400920002332212330010030023232323333573466e1cd55cea8012400046644246600200600466a056eb4d5d0a80118161aba135744a004464c6405c66ae700bc0b80b04d55cf280089baa00135742a0046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40add69aba15002302c357426ae8940088c98c80b8cd5ce01781701609aab9e5001137540026ae84d5d1280111931901519ab9c02b02a028135573ca00226ea8004d5d0a80299a80abae35742a008666aa03203a40026ae85400cccd54065d710009aba15002301f357426ae8940088c98c8098cd5ce01381301209aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226aae7940044dd50009aba15002300f357426ae8940088c98c8060cd5ce00c80c00b080b89931900b99ab9c4910350543500017135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c24002920103505431001220021123230010012233003300200200133351222335122335004335500248811c2b194b7d10a3d2d3152c5f3a628ff50cb9fc11e59453e8ac7a1aea4500488104544e4654005005112212330010030021120011122002122122330010040031200101").unwrap(); - let redeemer1 = Redeemer::from_json( - "\ - { - \"tag\": \"Mint\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"1042996\", - \"steps\": \"446100241\" - } - }", - ) - .unwrap(); - - let redeemer2 = Redeemer::from_json( - "\ - { - \"tag\": \"Mint\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"1042996\", - \"steps\": \"446100241\" - } - }", - ) - .unwrap(); + let (plutus_script, _) = fake_plutus_script_and_hash(1); + let redeemer1 = create_redeemer(1); + let redeemer2 = create_redeemer(2); let mut in_builder = TxInputsBuilder::new(); let input_1 = TransactionInput::new( @@ -5881,75 +5563,11 @@ fn build_tx_with_certs_withdrawals_plutus_script_address() { .derive(1) .to_public(); - let redeemer_cert1 = Redeemer::from_json( - "\ - { - \"tag\": \"Spend\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"1\", - \"steps\": \"1\" - } - }", - ) - .unwrap(); - - let redeemer_cert2 = Redeemer::from_json( - "\ - { - \"tag\": \"Spend\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"2\", - \"steps\": \"2\" - } - }", - ) - .unwrap(); - - let redeemer_cert3 = Redeemer::from_json( - "\ - { - \"tag\": \"Spend\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"2\", - \"steps\": \"2\" - } - }", - ) - .unwrap(); - - let redeemer_withdraw1 = Redeemer::from_json( - "\ - { - \"tag\": \"Spend\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"4\", - \"steps\": \"4\" - } - }", - ) - .unwrap(); - - let redeemer_withdraw2 = Redeemer::from_json( - "\ - { - \"tag\": \"Spend\", - \"index\": \"0\", - \"data\": \"{\\\"constructor\\\":0,\\\"fields\\\":[]}\", - \"ex_units\": { - \"mem\": \"5\", - \"steps\": \"5\" - } - }", - ) - .unwrap(); + let redeemer_cert1 = create_redeemer(1); + let redeemer_cert2 = create_redeemer(2); + let redeemer_cert3 = create_redeemer(3); + let redeemer_withdraw1 = create_redeemer(4); + let redeemer_withdraw2 = create_redeemer(5); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); tx_builder.add_key_input( @@ -5958,16 +5576,16 @@ fn build_tx_with_certs_withdrawals_plutus_script_address() { &Value::new(&BigNum(5_000_000)), ); tx_builder.set_ttl(1000); - let (cert_script1, cert_script_hash1) = plutus_script_and_hash(1); + let (cert_script1, cert_script_hash1) = fake_plutus_script_and_hash(1); let cert_script_cred1 = Credential::from_scripthash(&cert_script_hash1); - let (cert_script2, cert_script_hash2) = plutus_script_and_hash(2); + let (cert_script2, cert_script_hash2) = fake_plutus_script_and_hash(2); let cert_script_cred2 = Credential::from_scripthash(&cert_script_hash2); let cert_script_hash3 = fake_script_hash(3); let cert_script_cred3 = Credential::from_scripthash(&cert_script_hash3); - let (withdraw_script1, withdraw_script_hash1) = plutus_script_and_hash(3); + let (withdraw_script1, withdraw_script_hash1) = fake_plutus_script_and_hash(3); let withdraw_script_cred1 = Credential::from_scripthash(&withdraw_script_hash1); let withdraw_script_hash2 = fake_script_hash(3); @@ -6402,7 +6020,7 @@ fn ref_script_fee_from_all_builders() { let ref_script_fee = BigNum::from(111111110u64 / 2); let total_tx_fee = tx.body().fee(); - //TODO: change check change calculation for pessimistic size estimation. + //TODO: check change calculation for pessimistic size estimation. let tx_size = tx.to_bytes().len() + 4; let min_tx_fee = min_fee_for_size(tx_size, &create_linear_fee(44, 155381)).unwrap(); From 102b8dc0e12feaa29f2a1c7d395fbe89490fffd1 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 7 May 2024 21:30:34 +0900 Subject: [PATCH 272/349] version bump --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- rust/pkg/cardano_serialization_lib.js.flow | 470 ++++++++++----------- 5 files changed, 239 insertions(+), 239 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1fafdf5a..5311ef2d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.29", + "version": "12.0.0-alpha.30", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 1b87a658..4bb449b9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.29", + "version": "12.0.0-alpha.30", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 502bf7e1..e05a1118 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.29" +version = "12.0.0-alpha.30" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 01425b4b..57e65ce5 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -55,7 +55,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.29" +version = "12.0.0-alpha.30" dependencies = [ "bech32", "cbor_event", diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 7167c974..9cfa3592 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -5,143 +5,6 @@ * @flow */ -/** - * @param {string} json - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {PlutusData} - */ -declare export function encode_json_str_to_plutus_datum( - json: string, - schema: $Values -): PlutusData; - -/** - * @param {PlutusData} datum - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {string} - */ -declare export function decode_plutus_datum_to_json_str( - datum: PlutusData, - schema: $Values -): string; - -/** - * @param {Uint8Array} bytes - * @returns {TransactionMetadatum} - */ -declare export function encode_arbitrary_bytes_as_metadatum( - bytes: Uint8Array -): TransactionMetadatum; - -/** - * @param {TransactionMetadatum} metadata - * @returns {Uint8Array} - */ -declare export function decode_arbitrary_bytes_from_metadatum( - metadata: TransactionMetadatum -): Uint8Array; - -/** - * @param {string} json - * @param {$Values< - typeof - MetadataJsonSchema>} schema - * @returns {TransactionMetadatum} - */ -declare export function encode_json_str_to_metadatum( - json: string, - schema: $Values -): TransactionMetadatum; - -/** - * @param {TransactionMetadatum} metadatum - * @param {$Values< - typeof - MetadataJsonSchema>} schema - * @returns {string} - */ -declare export function decode_metadatum_to_json_str( - metadatum: TransactionMetadatum, - schema: $Values -): string; - -/** - * @param {Address} address - * @param {TransactionUnspentOutputs} utxos - * @param {TransactionBuilderConfig} config - * @returns {TransactionBatchList} - */ -declare export function create_send_all( - address: Address, - utxos: TransactionUnspentOutputs, - config: TransactionBuilderConfig -): TransactionBatchList; - -/** - * @param {string} password - * @param {string} salt - * @param {string} nonce - * @param {string} data - * @returns {string} - */ -declare export function encrypt_with_password( - password: string, - salt: string, - nonce: string, - data: string -): string; - -/** - * @param {string} password - * @param {string} data - * @returns {string} - */ -declare export function decrypt_with_password( - password: string, - data: string -): string; - -/** - * @param {Transaction} tx - * @param {LinearFee} linear_fee - * @returns {BigNum} - */ -declare export function min_fee(tx: Transaction, linear_fee: LinearFee): BigNum; - -/** - * @param {ExUnits} ex_units - * @param {ExUnitPrices} ex_unit_prices - * @returns {BigNum} - */ -declare export function calculate_ex_units_ceil_cost( - ex_units: ExUnits, - ex_unit_prices: ExUnitPrices -): BigNum; - -/** - * @param {Transaction} tx - * @param {ExUnitPrices} ex_unit_prices - * @returns {BigNum} - */ -declare export function min_script_fee( - tx: Transaction, - ex_unit_prices: ExUnitPrices -): BigNum; - -/** - * @param {number} total_ref_scripts_size - * @param {UnitInterval} ref_script_coins_per_byte - * @returns {BigNum} - */ -declare export function min_ref_script_fee( - total_ref_scripts_size: number, - ref_script_coins_per_byte: UnitInterval -): BigNum; - /** * @param {TransactionHash} tx_body_hash * @param {ByronAddress} addr @@ -268,131 +131,257 @@ declare export function encode_json_str_to_native_script( ): NativeScript; /** + * @param {Address} address + * @param {TransactionUnspentOutputs} utxos + * @param {TransactionBuilderConfig} config + * @returns {TransactionBatchList} */ +declare export function create_send_all( + address: Address, + utxos: TransactionUnspentOutputs, + config: TransactionBuilderConfig +): TransactionBatchList; -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 -|}; +/** + * @param {string} password + * @param {string} salt + * @param {string} nonce + * @param {string} data + * @returns {string} + */ +declare export function encrypt_with_password( + password: string, + salt: string, + nonce: string, + data: string +): string; /** - * Each new language uses a different namespace for hashing its script - * This is because you could have a language where the same bytes have different semantics - * So this avoids scripts in different languages mapping to the same hash - * Note that the enum value here is different than the enum value for deciding the cost model of a script + * @param {string} password + * @param {string} data + * @returns {string} */ +declare export function decrypt_with_password( + password: string, + data: string +): string; -declare export var ScriptHashNamespace: {| - +NativeScript: 0, // 0 - +PlutusScript: 1, // 1 - +PlutusScriptV2: 2, // 2 - +PlutusScriptV3: 3, // 3 +/** + * @param {Transaction} tx + * @param {LinearFee} linear_fee + * @returns {BigNum} + */ +declare export function min_fee(tx: Transaction, linear_fee: LinearFee): BigNum; + +/** + * @param {ExUnits} ex_units + * @param {ExUnitPrices} ex_unit_prices + * @returns {BigNum} + */ +declare export function calculate_ex_units_ceil_cost( + ex_units: ExUnits, + ex_unit_prices: ExUnitPrices +): BigNum; + +/** + * @param {Transaction} tx + * @param {ExUnitPrices} ex_unit_prices + * @returns {BigNum} + */ +declare export function min_script_fee( + tx: Transaction, + ex_unit_prices: ExUnitPrices +): BigNum; + +/** + * @param {number} total_ref_scripts_size + * @param {UnitInterval} ref_script_coins_per_byte + * @returns {BigNum} + */ +declare export function min_ref_script_fee( + total_ref_scripts_size: number, + ref_script_coins_per_byte: UnitInterval +): BigNum; + +/** + * @param {string} json + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {PlutusData} + */ +declare export function encode_json_str_to_plutus_datum( + json: string, + schema: $Values +): PlutusData; + +/** + * @param {PlutusData} datum + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {string} + */ +declare export function decode_plutus_datum_to_json_str( + datum: PlutusData, + schema: $Values +): string; + +/** + * @param {Uint8Array} bytes + * @returns {TransactionMetadatum} + */ +declare export function encode_arbitrary_bytes_as_metadatum( + bytes: Uint8Array +): TransactionMetadatum; + +/** + * @param {TransactionMetadatum} metadata + * @returns {Uint8Array} + */ +declare export function decode_arbitrary_bytes_from_metadatum( + metadata: TransactionMetadatum +): Uint8Array; + +/** + * @param {string} json + * @param {$Values< + typeof + MetadataJsonSchema>} schema + * @returns {TransactionMetadatum} + */ +declare export function encode_json_str_to_metadatum( + json: string, + schema: $Values +): TransactionMetadatum; + +/** + * @param {TransactionMetadatum} metadatum + * @param {$Values< + typeof + MetadataJsonSchema>} schema + * @returns {string} + */ +declare export function decode_metadatum_to_json_str( + metadatum: TransactionMetadatum, + schema: $Values +): string; + +/** + */ + +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** + * Used to choosed the schema for a script JSON string */ -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 - +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** */ -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 |}; /** */ -declare export var LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 |}; /** */ -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 |}; /** */ -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 +declare export var AddressKind: {| + +Base: 0, // 0 + +Pointer: 1, // 1 + +Enterprise: 2, // 2 + +Reward: 3, // 3 + +Byron: 4, // 4 + +Malformed: 5, // 5 |}; /** + * Each new language uses a different namespace for hashing its script + * This is because you could have a language where the same bytes have different semantics + * So this avoids scripts in different languages mapping to the same hash + * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var GovernanceActionKind: {| - +ParameterChangeAction: 0, // 0 - +HardForkInitiationAction: 1, // 1 - +TreasuryWithdrawalsAction: 2, // 2 - +NoConfidenceAction: 3, // 3 - +UpdateCommitteeAction: 4, // 4 - +NewConstitutionAction: 5, // 5 - +InfoAction: 6, // 6 +declare export var ScriptHashNamespace: {| + +NativeScript: 0, // 0 + +PlutusScript: 1, // 1 + +PlutusScriptV2: 2, // 2 + +PlutusScriptV3: 3, // 3 |}; /** */ -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 |}; /** */ -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 |}; /** */ -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 |}; /** */ -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 |}; /** @@ -410,13 +399,11 @@ declare export var RedeemerTagKind: {| /** */ -declare export var AddressKind: {| - +Base: 0, // 0 - +Pointer: 1, // 1 - +Enterprise: 2, // 2 - +Reward: 3, // 3 - +Byron: 4, // 4 - +Malformed: 5, // 5 +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 |}; /** @@ -429,12 +416,11 @@ declare export var RelayKind: {| |}; /** - * Used to choosed the schema for a script JSON string */ -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 |}; /** @@ -457,32 +443,24 @@ declare export var PlutusDatumSchema: {| /** */ -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 -|}; - -/** - */ - -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 +declare export var GovernanceActionKind: {| + +ParameterChangeAction: 0, // 0 + +HardForkInitiationAction: 1, // 1 + +TreasuryWithdrawalsAction: 2, // 2 + +NoConfidenceAction: 3, // 3 + +UpdateCommitteeAction: 4, // 4 + +NewConstitutionAction: 5, // 5 + +InfoAction: 6, // 6 |}; /** */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 |}; /** @@ -508,6 +486,28 @@ declare export var CertificateKind: {| +VoteRegistrationAndDelegation: 16, // 16 |}; +/** + */ + +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 +|}; + +/** + */ + +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 +|}; + /** */ declare export class Address { @@ -5599,10 +5599,10 @@ declare export class MintWitness { free(): void; /** - * @param {NativeScript} native_script + * @param {NativeScriptSource} native_script * @returns {MintWitness} */ - static new_native_script(native_script: NativeScript): MintWitness; + static new_native_script(native_script: NativeScriptSource): MintWitness; /** * @param {PlutusScriptSource} plutus_script From 09e162161ceec0afd5a024c7e4f06baa775a58a6 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 25 May 2024 09:14:47 +0900 Subject: [PATCH 273/349] remove old tx builder file --- rust/src/tx_builder.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 rust/src/tx_builder.rs diff --git a/rust/src/tx_builder.rs b/rust/src/tx_builder.rs deleted file mode 100644 index e69de29b..00000000 From 72d4bfc577f3ab9a6902d25a2b0ae23a1db05d91 Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 30 May 2024 14:03:16 +0700 Subject: [PATCH 274/349] change percentage type for add_inputs_from_and_change_with_collateral_return --- rust/src/builders/tx_builder.rs | 9 ++++++--- rust/src/tests/builders/tx_builder.rs | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index 19de3fa8..bcb3349d 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -906,7 +906,7 @@ impl TransactionBuilder { inputs: &TransactionUnspentOutputs, strategy: CoinSelectionStrategyCIP2, change_config: &ChangeConfig, - collateral_percentage: u64 + collateral_percentage: &BigNum ) -> Result { let mut total_collateral = Value::zero(); for collateral_input in self.collateral.iter() { @@ -919,8 +919,11 @@ impl TransactionBuilder { let fee = self.get_fee_if_set().ok_or( JsError::from_str("Cannot calculate collateral return if fee was not set"), )?; - let collateral_required = ((u64::from(&fee) * collateral_percentage) / 100) + 1; - let set_collateral_result = self.set_total_collateral_and_return(&BigNum(collateral_required), &change_config.address); + let collateral_required = fee + .checked_mul(&collateral_percentage)? + .div_floor(&BigNum(100)) + .checked_add(&BigNum::one())?; + let set_collateral_result = self.set_total_collateral_and_return(&collateral_required, &change_config.address); match set_collateral_result { Ok(_) => { Ok(true) diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index 05c2c314..ffafd4a3 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -6086,7 +6086,7 @@ fn utxo_selection_with_collateral_return_test() { tx_builder.set_collateral(&collateral_builder); let change_config = ChangeConfig::new(&Address::from_bech32("addr_test1qqzf7fhgm0gf370ngxgpskg5c3kgp2g0u4ltxlrmsvumaztv3ck06k550q64lgwkqavljd63yda0x2va074fguprujfs43mc83").unwrap()); - assert!(&tx_builder.add_inputs_from_and_change_with_collateral_return(&utxos, CoinSelectionStrategyCIP2::LargestFirstMultiAsset, &change_config, 150).is_ok()); + assert!(&tx_builder.add_inputs_from_and_change_with_collateral_return(&utxos, CoinSelectionStrategyCIP2::LargestFirstMultiAsset, &change_config, &BigNum(150)).is_ok()); let build_res = tx_builder.build_tx(); assert!(&build_res.is_ok()); assert!(&build_res.clone().unwrap().body.collateral_return().is_some()); From 5a87e3c15f67f2743bfc76fb5810dabbcc008ed7 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 31 May 2024 17:05:39 +0700 Subject: [PATCH 275/349] fix add_inputs_from_and_change_with_collateral_return corner case --- rust/src/builders/tx_builder.rs | 265 ++++++++++++++++---------- rust/src/tests/builders/tx_builder.rs | 55 +++++- 2 files changed, 217 insertions(+), 103 deletions(-) diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index bcb3349d..5087f8ae 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -3,11 +3,10 @@ use crate::*; use super::*; +use crate::builders::fakes::{fake_private_key, fake_raw_key_public, fake_raw_key_sig}; use crate::fees; use crate::utils; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; -use crate::builders::fakes::{fake_private_key, fake_raw_key_public, fake_raw_key_sig}; -use crate::map_names::TxBodyNames::RequiredSigners; fn count_needed_vkeys(tx_builder: &TransactionBuilder) -> usize { let mut input_hashes: Ed25519KeyHashes = Ed25519KeyHashes::from(&tx_builder.inputs); @@ -176,11 +175,11 @@ pub enum CoinSelectionStrategyCIP2 { #[derive(Clone, Debug)] pub struct TransactionBuilderConfig { pub(crate) fee_algo: fees::LinearFee, - pub(crate) pool_deposit: Coin, // protocol parameter - pub(crate) key_deposit: Coin, // protocol parameter - pub(crate) max_value_size: u32, // protocol parameter - pub(crate) max_tx_size: u32, // protocol parameter - pub(crate) data_cost: DataCost, // protocol parameter + pub(crate) pool_deposit: Coin, // protocol parameter + pub(crate) key_deposit: Coin, // protocol parameter + pub(crate) max_value_size: u32, // protocol parameter + pub(crate) max_tx_size: u32, // protocol parameter + pub(crate) data_cost: DataCost, // protocol parameter pub(crate) ex_unit_prices: Option, // protocol parameter pub(crate) ref_script_coins_per_byte: Option, // protocol parameter pub(crate) prefer_pure_change: bool, @@ -196,12 +195,12 @@ impl TransactionBuilderConfig { #[derive(Clone, Debug)] pub struct TransactionBuilderConfigBuilder { fee_algo: Option, - pool_deposit: Option, // protocol parameter - key_deposit: Option, // protocol parameter - max_value_size: Option, // protocol parameter - max_tx_size: Option, // protocol parameter - data_cost: Option, // protocol parameter - ex_unit_prices: Option, // protocol parameter + pool_deposit: Option, // protocol parameter + key_deposit: Option, // protocol parameter + max_value_size: Option, // protocol parameter + max_tx_size: Option, // protocol parameter + data_cost: Option, // protocol parameter + ex_unit_prices: Option, // protocol parameter ref_script_coins_per_byte: Option, // protocol parameter prefer_pure_change: bool, } @@ -309,7 +308,7 @@ impl TransactionBuilderConfigBuilder { pub struct ChangeConfig { address: Address, plutus_data: Option, - script_ref: Option + script_ref: Option, } #[wasm_bindgen] @@ -318,7 +317,7 @@ impl ChangeConfig { Self { address: address.clone(), plutus_data: None, - script_ref: None + script_ref: None, } } @@ -341,7 +340,6 @@ impl ChangeConfig { } } - #[wasm_bindgen] #[derive(Clone, Debug)] pub struct TransactionBuilder { @@ -445,7 +443,11 @@ impl TransactionBuilder { &input.input, &input.output.amount, )?; - self.add_regular_input(&input.output.address, &input.input, &input.output.amount); + self.add_regular_input( + &input.output.address, + &input.input, + &input.output.amount, + ); input_total = input_total.checked_add(&input.output.amount)?; output_total = output_total.checked_add(&Value::new(&input_fee))?; } @@ -525,7 +527,11 @@ impl TransactionBuilder { &input.input, &input.output.amount, )?; - self.add_regular_input(&input.output.address, &input.input, &input.output.amount); + self.add_regular_input( + &input.output.address, + &input.input, + &input.output.amount, + ); input_total = input_total.checked_add(&input.output.amount)?; output_total = output_total.checked_add(&Value::new(&input_fee))?; } @@ -681,7 +687,11 @@ impl TransactionBuilder { &input.input, &input.output.amount, )?; - self.add_regular_input(&input.output.address, &input.input, &input.output.amount); + self.add_regular_input( + &input.output.address, + &input.input, + &input.output.amount, + ); *input_total = input_total.checked_add(&input.output.amount)?; *output_total = output_total.checked_add(&Value::new(&input_fee))?; } @@ -789,8 +799,13 @@ impl TransactionBuilder { self.reference_inputs.insert(reference_input.clone(), 0); } - pub fn add_script_reference_input(&mut self, reference_input: &TransactionInput, script_size: usize) { - self.reference_inputs.insert(reference_input.clone(), script_size); + pub fn add_script_reference_input( + &mut self, + reference_input: &TransactionInput, + script_size: usize, + ) { + self.reference_inputs + .insert(reference_input.clone(), script_size); } /// We have to know what kind of inputs these are to know what kind of mock witnesses to create since @@ -843,7 +858,12 @@ impl TransactionBuilder { /// To add script input you need to use add_native_script_input or add_plutus_script_input. /// Also we recommend to use TxInputsBuilder and .set_inputs, because all add_*_input functions might be removed from transaction builder. #[deprecated(since = "12.0.0", note = "Use `.set_inputs`")] - pub fn add_regular_input(&mut self, address: &Address, input: &TransactionInput, amount: &Value) -> Result<(), JsError>{ + pub fn add_regular_input( + &mut self, + address: &Address, + input: &TransactionInput, + amount: &Value, + ) -> Result<(), JsError> { self.inputs.add_regular_input(address, input, amount) } @@ -855,45 +875,77 @@ impl TransactionBuilder { &mut self, inputs: &TransactionUnspentOutputs, strategy: CoinSelectionStrategyCIP2, - change_config: &ChangeConfig - ) -> Result - { + change_config: &ChangeConfig, + ) -> Result { self.add_inputs_from(inputs, strategy)?; - match &self.fee { - Some(_x) => { - return Err(JsError::from_str( - "Cannot calculate change if fee was explicitly specified", - )) - } - None => { - let mut add_change_result = self.add_change_if_needed_with_optional_script_and_datum(&change_config.address, change_config.plutus_data.clone().map_or(None, |od| Some(od.0)), change_config.script_ref.clone()); - match add_change_result { - Ok(v) => Ok(v), - Err(e) => { - let mut unused_inputs = TransactionUnspentOutputs::new(); - for input in inputs.into_iter() { - if self.inputs.inputs().0.iter().all(|used_input| input.input() != *used_input) { - unused_inputs.add(input) + if self.fee.is_some() { + return Err(JsError::from_str( + "Cannot calculate change if fee was explicitly specified", + )) + } + let mut add_change_result = self + .add_change_if_needed_with_optional_script_and_datum( + &change_config.address, + change_config + .plutus_data + .clone() + .map_or(None, |od| Some(od.0)), + change_config.script_ref.clone(), + ); + match add_change_result { + Ok(v) => Ok(v), + Err(e) => { + let mut unused_inputs = TransactionUnspentOutputs::new(); + for input in inputs.into_iter() { + if self + .inputs + .inputs() + .0 + .iter() + .all(|used_input| input.input() != *used_input) + { + unused_inputs.add(input) + } + } + unused_inputs.0.sort_by_key(|input| { + input + .clone() + .output + .amount + .multiasset + .map_or(0, |ma| ma.len()) + }); + unused_inputs.0.reverse(); + while unused_inputs.0.len() > 0 { + let last_input = unused_inputs.0.pop(); + match last_input { + Some(input) => { + self.add_regular_input( + &input.output().address(), + &input.input(), + &input.output().amount(), + )?; + add_change_result = self + .add_change_if_needed_with_optional_script_and_datum( + &change_config.address, + change_config + .plutus_data + .clone() + .map_or(None, |od| Some(od.0)), + change_config.script_ref.clone(), + ); + if let Ok(value) = add_change_result { + return Ok(value); } } - unused_inputs.0.sort_by_key(|input| input.clone().output.amount.multiasset.map_or(0, |ma| ma.len())); - unused_inputs.0.reverse(); - while unused_inputs.0.len() > 0 { - let last_input = unused_inputs.0.pop(); - match last_input { - Some(input) => { - self.add_regular_input(&input.output().address(), &input.input(), &input.output().amount())?; - add_change_result = self.add_change_if_needed_with_optional_script_and_datum(&change_config.address, change_config.plutus_data.clone().map_or(None, |od| Some(od.0)), change_config.script_ref.clone()); - if let Ok(value) = add_change_result { - return Ok(value) - } - }, - None => return Err(JsError::from_str("Unable to balance tx with available inputs")) - } + None => { + return Err(JsError::from_str( + "Unable to balance tx with available inputs", + )) } - Err(e) } } + Err(e) } } } @@ -906,40 +958,46 @@ impl TransactionBuilder { inputs: &TransactionUnspentOutputs, strategy: CoinSelectionStrategyCIP2, change_config: &ChangeConfig, - collateral_percentage: &BigNum - ) -> Result { + collateral_percentage: &BigNum, + ) -> Result<(), JsError> { let mut total_collateral = Value::zero(); for collateral_input in self.collateral.iter() { total_collateral = total_collateral.checked_add(&collateral_input.amount)?; } - self.set_total_collateral_and_return(&total_collateral.coin(), &change_config.address)?; + + //set fake max total collateral and return + self.set_total_collateral(&total_collateral.coin()); + self.set_collateral_return(&TransactionOutput::new( + &change_config.address, + &total_collateral, + )); + let add_change_result = self.add_inputs_from_and_change(inputs, strategy, change_config); - match add_change_result { - Ok(_) => { - let fee = self.get_fee_if_set().ok_or( - JsError::from_str("Cannot calculate collateral return if fee was not set"), - )?; - let collateral_required = fee - .checked_mul(&collateral_percentage)? - .div_floor(&BigNum(100)) - .checked_add(&BigNum::one())?; - let set_collateral_result = self.set_total_collateral_and_return(&collateral_required, &change_config.address); - match set_collateral_result { - Ok(_) => { - Ok(true) - } - Err(_) => { - self.remove_collateral_return(); - self.remove_total_collateral(); - Ok(true) - } - } - } - Err(e) => { - Err(e) - } - }?; - Ok(true) + + self.remove_collateral_return(); + self.remove_total_collateral(); + + //check if adding inputs and change was successful + add_change_result?; + + let fee = self.get_fee_if_set().ok_or(JsError::from_str( + "Cannot calculate collateral return if fee was not set", + ))?; + + let collateral_required = fee + .checked_mul(&collateral_percentage)? + .div_floor(&BigNum(100)) + .checked_add(&BigNum::one())?; + let set_collateral_result = + self.set_total_collateral_and_return(&collateral_required, &change_config.address); + + if let Err(e) = set_collateral_result { + self.remove_collateral_return(); + self.remove_total_collateral(); + return Err(e); + } + + Ok(()) } /// Returns a copy of the current script input witness scripts in the builder @@ -1317,11 +1375,9 @@ impl TransactionBuilder { } let policy_id: PolicyID = policy_script.hash(); self.add_mint_asset(policy_script, asset_name, amount); - let multiasset = Mint::new_from_entry( - &policy_id, - &MintAssets::new_from_entry(asset_name, amount)?, - ) - .as_positive_multiasset(); + let multiasset = + Mint::new_from_entry(&policy_id, &MintAssets::new_from_entry(asset_name, amount)?) + .as_positive_multiasset(); self.add_output( &output_builder @@ -1347,11 +1403,9 @@ impl TransactionBuilder { } let policy_id: PolicyID = policy_script.hash(); self.add_mint_asset(policy_script, asset_name, amount); - let multiasset = Mint::new_from_entry( - &policy_id, - &MintAssets::new_from_entry(asset_name, amount)?, - ) - .as_positive_multiasset(); + let multiasset = + Mint::new_from_entry(&policy_id, &MintAssets::new_from_entry(asset_name, amount)?) + .as_positive_multiasset(); self.add_output( &output_builder @@ -1385,7 +1439,10 @@ impl TransactionBuilder { self.donation.clone() } - pub fn set_current_treasury_value(&mut self, current_treasury_value: &Coin) -> Result<(), JsError> { + pub fn set_current_treasury_value( + &mut self, + current_treasury_value: &Coin, + ) -> Result<(), JsError> { if current_treasury_value == &Coin::zero() { return Err(JsError::from_str("Current treasury value cannot be zero!")); } @@ -1465,9 +1522,15 @@ impl TransactionBuilder { fn get_total_ref_scripts_size(&self) -> Result { let mut sizes_map = HashMap::new(); - fn add_to_map<'a>(item: (&'a TransactionInput, usize), sizes_map: &mut HashMap<&'a TransactionInput, usize> ) -> Result<(), JsError>{ + fn add_to_map<'a>( + item: (&'a TransactionInput, usize), + sizes_map: &mut HashMap<&'a TransactionInput, usize>, + ) -> Result<(), JsError> { if sizes_map.entry(item.0).or_insert(item.1) != &item.1 { - return Err(JsError::from_str(&format!("Different script sizes for the same ref input {}", item.0))); + return Err(JsError::from_str(&format!( + "Different script sizes for the same ref input {}", + item.0 + ))); } else { Ok(()) } @@ -1564,7 +1627,8 @@ impl TransactionBuilder { /// Return explicit output plus deposit plus burn pub fn get_total_output(&self) -> Result { let (_, burn_value) = self.get_mint_as_values(); - let mut total = self.get_explicit_output()? + let mut total = self + .get_explicit_output()? .checked_add(&Value::new(&self.get_deposit()?))? .checked_add(&burn_value)?; if let Some(donation) = &self.donation { @@ -1594,9 +1658,8 @@ impl TransactionBuilder { } if let Some(voting_proposal_builder) = &self.voting_proposals { - total_deposit = total_deposit.checked_add( - &voting_proposal_builder.get_total_deposit()?, - )?; + total_deposit = + total_deposit.checked_add(&voting_proposal_builder.get_total_deposit()?)?; } Ok(total_deposit) diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index ffafd4a3..88c831e0 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -6074,6 +6074,8 @@ fn utxo_selection_with_collateral_return_test() { "82825820731224c9d2bc3528578009fec9f9e34a67110aca2bd4dde0f050845a2daf660d0082583900436075347d6a452eba4289ae345a8eb15e73eb80979a7e817d988fc56c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e493821a001deabfa1581c9a5e0d55cdf4ce4e19c8acbff7b4dafc890af67a594a4c46d7dd1c0fa14001", "82825820a04996d5ef87fdece0c74625f02ee5c1497a06e0e476c5095a6b0626b295074a00825839001772f234940519e71318bb9c5c8ad6eacfe8fd91a509050624e3855e6c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e4931a0016e360" ]; + + let collateral_percent = BigNum(150); let output = TransactionOutput::new(&Address::from_bech32("addr_test1qppkqaf5044y2t46g2y6udz636c4uultszte5l5p0kvgl3tv3ck06k550q64lgwkqavljd63yda0x2va074fguprujfsjre4xh").unwrap(), &Value::new(&BigNum::from_str("969750").unwrap())); tx_builder.add_output(&output).unwrap(); let mut utxos = TransactionUnspentOutputs::new(); @@ -6086,8 +6088,57 @@ fn utxo_selection_with_collateral_return_test() { tx_builder.set_collateral(&collateral_builder); let change_config = ChangeConfig::new(&Address::from_bech32("addr_test1qqzf7fhgm0gf370ngxgpskg5c3kgp2g0u4ltxlrmsvumaztv3ck06k550q64lgwkqavljd63yda0x2va074fguprujfs43mc83").unwrap()); - assert!(&tx_builder.add_inputs_from_and_change_with_collateral_return(&utxos, CoinSelectionStrategyCIP2::LargestFirstMultiAsset, &change_config, &BigNum(150)).is_ok()); + assert!(&tx_builder.add_inputs_from_and_change_with_collateral_return(&utxos, CoinSelectionStrategyCIP2::LargestFirstMultiAsset, &change_config, &collateral_percent).is_ok()); + let build_res = tx_builder.build_tx(); assert!(&build_res.is_ok()); - assert!(&build_res.clone().unwrap().body.collateral_return().is_some()); + + let tx = build_res.unwrap(); + assert!(&tx.body.collateral_return().is_some()); + + let mut vkey_witneses = Vkeywitnesses::new(); + vkey_witneses.add(&fake_vkey_witness(1)); + vkey_witneses.add(&fake_vkey_witness(2)); + let mut wit_set = tx.witness_set(); + wit_set.set_vkeys(&vkey_witneses); + + let tx_with_vkeys = Transaction::new(&tx.body(), &wit_set, tx.auxiliary_data()); + let tx_size = tx_with_vkeys.to_bytes().len(); + let fee = tx.body().fee(); + let min_fee = min_fee_for_size(tx_size, &create_linear_fee(44, 155381)).unwrap(); + assert!(fee >= min_fee); + + let collateral_amount = tx.body.total_collateral.unwrap(); + let calculated_collateral = fee. + checked_mul(&collateral_percent).unwrap() + .div_floor(&BigNum(100)) + .checked_add(&BigNum(1)).unwrap(); + + assert_eq!(collateral_amount, calculated_collateral); +} + +#[test] +fn utxo_selection_with_collateral_return_error() { + let mut tx_builder = create_reallistic_tx_builder(); + let hex_utxos = [ + "82825820731224c9d2bc3528578009fec9f9e34a67110aca2bd4dde0f050845a2daf660d0082583900436075347d6a452eba4289ae345a8eb15e73eb80979a7e817d988fc56c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e493821a001deabfa1581c9a5e0d55cdf4ce4e19c8acbff7b4dafc890af67a594a4c46d7dd1c0fa14001", + "82825820a04996d5ef87fdece0c74625f02ee5c1497a06e0e476c5095a6b0626b295074a00825839001772f234940519e71318bb9c5c8ad6eacfe8fd91a509050624e3855e6c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e4931a0016e360" + ]; + + //we use big percentage to lead not enough collaterals to cover the collateral fee + let collateral_percent = BigNum(15000); + let output = TransactionOutput::new(&Address::from_bech32("addr_test1qppkqaf5044y2t46g2y6udz636c4uultszte5l5p0kvgl3tv3ck06k550q64lgwkqavljd63yda0x2va074fguprujfsjre4xh").unwrap(), &Value::new(&BigNum::from_str("969750").unwrap())); + tx_builder.add_output(&output).unwrap(); + let mut utxos = TransactionUnspentOutputs::new(); + for hex_utxo in hex_utxos { + utxos.add(&TransactionUnspentOutput::from_hex(hex_utxo).unwrap()); + } + let mut collateral_builder = TxInputsBuilder::new(); + let collateral_input = TransactionUnspentOutput::from_hex(hex_utxos[1]).unwrap(); + collateral_builder.add_regular_input(&collateral_input.output.address, &collateral_input.input, &collateral_input.output.amount).unwrap(); + tx_builder.set_collateral(&collateral_builder); + + let change_config = ChangeConfig::new(&Address::from_bech32("addr_test1qqzf7fhgm0gf370ngxgpskg5c3kgp2g0u4ltxlrmsvumaztv3ck06k550q64lgwkqavljd63yda0x2va074fguprujfs43mc83").unwrap()); + let change_res = tx_builder.add_inputs_from_and_change_with_collateral_return(&utxos, CoinSelectionStrategyCIP2::LargestFirstMultiAsset, &change_config, &collateral_percent); + assert!(change_res.is_err()); } From dcc4ed19e4a06c94554eb258f0d83eaf4529eb2a Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 3 Jun 2024 19:44:30 +0700 Subject: [PATCH 276/349] add security_relevant_threshold getter, fix committee_term_limit type, add tests --- rust/pkg/cardano_serialization_lib.js.flow | 264 +++++++++--------- .../protocol_types/protocol_param_update.rs | 10 +- rust/src/tests/general.rs | 42 ++- rust/src/tests/protocol_types/mod.rs | 1 + .../protocol_types/protocol_param_update.rs | 249 +++++++++++++++++ 5 files changed, 428 insertions(+), 138 deletions(-) create mode 100644 rust/src/tests/protocol_types/protocol_param_update.rs diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 9cfa3592..fd6b3269 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -270,43 +270,51 @@ declare export function decode_metadatum_to_json_str( /** */ -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 -|}; - -/** - * Used to choosed the schema for a script JSON string - */ - -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 +declare export var RedeemerTagKind: {| + +Spend: 0, // 0 + +Mint: 1, // 1 + +Cert: 2, // 2 + +Reward: 3, // 3 + +Vote: 4, // 4 + +VotingProposal: 5, // 5 |}; /** */ -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 +declare export var RelayKind: {| + +SingleHostAddr: 0, // 0 + +SingleHostName: 1, // 1 + +MultiHostName: 2, // 2 |}; /** */ -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 +declare export var AddressKind: {| + +Base: 0, // 0 + +Pointer: 1, // 1 + +Enterprise: 2, // 2 + +Reward: 3, // 3 + +Byron: 4, // 4 + +Malformed: 5, // 5 |}; /** + * JSON <-> PlutusData conversion schemas. + * Follows ScriptDataJsonSchema in cardano-cli defined at: + * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 + * + * All methods here have the following restrictions due to limitations on dependencies: + * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors + * * Hex strings for bytes don't accept odd-length (half-byte) strings. + * cardano-cli seems to support these however but it seems to be different than just 0-padding + * on either side when tested so proceed with caution */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var PlutusDatumSchema: {| + +BasicConversions: 0, // 0 + +DetailedSchema: 1, // 1 |}; /** @@ -323,39 +331,18 @@ declare export var VoterKind: {| /** */ -declare export var AddressKind: {| - +Base: 0, // 0 - +Pointer: 1, // 1 - +Enterprise: 2, // 2 - +Reward: 3, // 3 - +Byron: 4, // 4 - +Malformed: 5, // 5 -|}; - -/** - * Each new language uses a different namespace for hashing its script - * This is because you could have a language where the same bytes have different semantics - * So this avoids scripts in different languages mapping to the same hash - * Note that the enum value here is different than the enum value for deciding the cost model of a script - */ - -declare export var ScriptHashNamespace: {| - +NativeScript: 0, // 0 - +PlutusScript: 1, // 1 - +PlutusScriptV2: 2, // 2 - +PlutusScriptV3: 3, // 3 +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 |}; /** */ -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** @@ -368,32 +355,12 @@ declare export var LanguageKind: {| |}; /** + * Used to choosed the schema for a script JSON string */ -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 -|}; - -/** - */ - -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 -|}; - -/** - */ - -declare export var RedeemerTagKind: {| - +Spend: 0, // 0 - +Mint: 1, // 1 - +Cert: 2, // 2 - +Reward: 3, // 3 - +Vote: 4, // 4 - +VotingProposal: 5, // 5 +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** @@ -406,53 +373,6 @@ declare export var CoinSelectionStrategyCIP2: {| +RandomImproveMultiAsset: 3, // 3 |}; -/** - */ - -declare export var RelayKind: {| - +SingleHostAddr: 0, // 0 - +SingleHostName: 1, // 1 - +MultiHostName: 2, // 2 -|}; - -/** - */ - -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 -|}; - -/** - * JSON <-> PlutusData conversion schemas. - * Follows ScriptDataJsonSchema in cardano-cli defined at: - * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 - * - * All methods here have the following restrictions due to limitations on dependencies: - * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors - * * Hex strings for bytes don't accept odd-length (half-byte) strings. - * cardano-cli seems to support these however but it seems to be different than just 0-padding - * on either side when tested so proceed with caution - */ - -declare export var PlutusDatumSchema: {| - +BasicConversions: 0, // 0 - +DetailedSchema: 1, // 1 -|}; - -/** - */ - -declare export var GovernanceActionKind: {| - +ParameterChangeAction: 0, // 0 - +HardForkInitiationAction: 1, // 1 - +TreasuryWithdrawalsAction: 2, // 2 - +NoConfidenceAction: 3, // 3 - +UpdateCommitteeAction: 4, // 4 - +NewConstitutionAction: 5, // 5 - +InfoAction: 6, // 6 -|}; - /** */ @@ -463,6 +383,18 @@ declare export var DRepKind: {| +AlwaysNoConfidence: 3, // 3 |}; +/** + */ + +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 +|}; + /** */ @@ -486,6 +418,33 @@ declare export var CertificateKind: {| +VoteRegistrationAndDelegation: 16, // 16 |}; +/** + */ + +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 +|}; + +/** + */ + +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 +|}; + +/** + */ + +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 +|}; + /** */ @@ -500,12 +459,53 @@ declare export var TransactionMetadatumKind: {| /** */ -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 +|}; + +/** + */ + +declare export var GovernanceActionKind: {| + +ParameterChangeAction: 0, // 0 + +HardForkInitiationAction: 1, // 1 + +TreasuryWithdrawalsAction: 2, // 2 + +NoConfidenceAction: 3, // 3 + +UpdateCommitteeAction: 4, // 4 + +NewConstitutionAction: 5, // 5 + +InfoAction: 6, // 6 +|}; + +/** + */ + +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 +|}; + +/** + */ + +declare export var CborContainerType: {| + +Array: 0, // 0 +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 +|}; + +/** + * Each new language uses a different namespace for hashing its script + * This is because you could have a language where the same bytes have different semantics + * So this avoids scripts in different languages mapping to the same hash + * Note that the enum value here is different than the enum value for deciding the cost model of a script + */ + +declare export var ScriptHashNamespace: {| + +NativeScript: 0, // 0 + +PlutusScript: 1, // 1 + +PlutusScriptV2: 2, // 2 + +PlutusScriptV3: 3, // 3 |}; /** @@ -7722,6 +7722,11 @@ declare export class PoolVotingThresholds { * @returns {UnitInterval} */ hard_fork_initiation(): UnitInterval; + + /** + * @returns {UnitInterval} + */ + security_relevant_threshold(): UnitInterval; } /** */ @@ -10678,15 +10683,14 @@ declare export class TransactionBuilder { typeof CoinSelectionStrategyCIP2>} strategy * @param {ChangeConfig} change_config - * @param {bigint} collateral_percentage - * @returns {boolean} + * @param {BigNum} collateral_percentage */ add_inputs_from_and_change_with_collateral_return( inputs: TransactionUnspentOutputs, strategy: $Values, change_config: ChangeConfig, - collateral_percentage: bigint - ): boolean; + collateral_percentage: BigNum + ): void; /** * Returns a copy of the current script input witness scripts in the builder diff --git a/rust/src/protocol_types/protocol_param_update.rs b/rust/src/protocol_types/protocol_param_update.rs index 77921281..14fe8c78 100644 --- a/rust/src/protocol_types/protocol_param_update.rs +++ b/rust/src/protocol_types/protocol_param_update.rs @@ -56,6 +56,10 @@ impl PoolVotingThresholds { pub fn hard_fork_initiation(&self) -> UnitInterval { self.hard_fork_initiation.clone() } + + pub fn security_relevant_threshold(&self) -> UnitInterval { + self.security_relevant_threshold.clone() + } } #[wasm_bindgen] @@ -245,7 +249,7 @@ pub struct ProtocolParamUpdate { pub(crate) pool_voting_thresholds: Option, pub(crate) drep_voting_thresholds: Option, pub(crate) min_committee_size: Option, - pub(crate) committee_term_limit: Option, + pub(crate) committee_term_limit: Option, pub(crate) governance_action_validity_period: Option, pub(crate) governance_action_deposit: Option, pub(crate) drep_deposit: Option, @@ -483,11 +487,11 @@ impl ProtocolParamUpdate { self.min_committee_size.clone() } - pub fn set_committee_term_limit(&mut self, committee_term_limit: u32) { + pub fn set_committee_term_limit(&mut self, committee_term_limit: Epoch) { self.committee_term_limit = Some(committee_term_limit) } - pub fn committee_term_limit(&self) -> Option { + pub fn committee_term_limit(&self) -> Option { self.committee_term_limit.clone() } diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index a3b0cac6..9fd59206 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -254,7 +254,7 @@ fn native_scripts_get_pubkeys() { } #[test] -fn protocol_params_update_cbor_roundtrip() { +fn protocol_params_update_cbor_json_roundtrip() { let mut orig_ppu = ProtocolParamUpdate::new(); orig_ppu.set_max_tx_size(1234); orig_ppu.set_max_block_body_size(5678); @@ -284,12 +284,44 @@ fn protocol_params_update_cbor_roundtrip() { orig_ppu.set_max_value_size(24); orig_ppu.set_collateral_percentage(25); orig_ppu.set_max_collateral_inputs(25); + orig_ppu.set_pool_voting_thresholds(&PoolVotingThresholds::new( + &UnitInterval::new(&BigNum::from(26u32), &BigNum::from(27u32)), + &UnitInterval::new(&BigNum::from(28u32), &BigNum::from(29u32)), + &UnitInterval::new(&BigNum::from(30u32), &BigNum::from(31u32)), + &UnitInterval::new(&BigNum::from(40u32), &BigNum::from(41u32)), + &UnitInterval::new(&BigNum::from(50u32), &BigNum::from(51u32)), + )); + orig_ppu.set_drep_voting_thresholds(&DrepVotingThresholds::new( + &UnitInterval::new(&BigNum::from(26u32), &BigNum::from(27u32)), + &UnitInterval::new(&BigNum::from(28u32), &BigNum::from(29u32)), + &UnitInterval::new(&BigNum::from(30u32), &BigNum::from(31u32)), + &UnitInterval::new(&BigNum::from(40u32), &BigNum::from(41u32)), + &UnitInterval::new(&BigNum::from(50u32), &BigNum::from(51u32)), + &UnitInterval::new(&BigNum::from(60u32), &BigNum::from(61u32)), + &UnitInterval::new(&BigNum::from(66u32), &BigNum::from(65u32)), + &UnitInterval::new(&BigNum::from(70u32), &BigNum::from(71u32)), + &UnitInterval::new(&BigNum::from(77u32), &BigNum::from(75u32)), + &UnitInterval::new(&BigNum::from(80u32), &BigNum::from(81u32)), + )); + orig_ppu.set_min_committee_size(32); + orig_ppu.set_committee_term_limit(33); + orig_ppu.set_governance_action_validity_period(34); + orig_ppu.set_governance_action_deposit(&Coin::from(35u32)); + orig_ppu.set_drep_deposit(&Coin::from(36u32)); + orig_ppu.set_drep_inactivity_period(37); + orig_ppu.set_ref_script_coins_per_byte(&UnitInterval::new(&BigNum::from(38u32), &BigNum::from(39u32))); + + let encoded_cbor = orig_ppu.to_bytes(); + let decoded_from_cbor = ProtocolParamUpdate::from_bytes(encoded_cbor).unwrap(); + + assert_eq!(decoded_from_cbor, orig_ppu); + assert_eq!(decoded_from_cbor.to_bytes(), orig_ppu.to_bytes()); - let encoded = orig_ppu.to_bytes(); - let dencoded = ProtocolParamUpdate::from_bytes(encoded).unwrap(); + let encoded_json = orig_ppu.to_json().unwrap(); + let decoded_from_json = ProtocolParamUpdate::from_json(&encoded_json).unwrap(); - assert_eq!(dencoded, orig_ppu); - assert_eq!(dencoded.to_bytes(), orig_ppu.to_bytes()); + assert_eq!(decoded_from_json, orig_ppu); + assert_eq!(decoded_from_json.to_json().unwrap(), orig_ppu.to_json().unwrap()); } #[test] diff --git a/rust/src/tests/protocol_types/mod.rs b/rust/src/tests/protocol_types/mod.rs index 0bc1c656..a1f44ad9 100644 --- a/rust/src/tests/protocol_types/mod.rs +++ b/rust/src/tests/protocol_types/mod.rs @@ -1,3 +1,4 @@ mod certificates; mod fixed_tx; mod governance; +mod protocol_param_update; diff --git a/rust/src/tests/protocol_types/protocol_param_update.rs b/rust/src/tests/protocol_types/protocol_param_update.rs new file mode 100644 index 00000000..be9ce7e9 --- /dev/null +++ b/rust/src/tests/protocol_types/protocol_param_update.rs @@ -0,0 +1,249 @@ +use crate::*; + +#[test] +fn ppu_setters_getters_test() { + let mut ppu = ProtocolParamUpdate::new(); + + assert!(ppu.max_tx_size().is_none()); + let max_tx_size = 1234; + ppu.set_max_tx_size(max_tx_size); + assert_eq!(ppu.max_tx_size().unwrap(), max_tx_size); + + assert!(ppu.max_block_body_size().is_none()); + let max_block_body_size = 5678; + ppu.set_max_block_body_size(max_block_body_size); + assert_eq!(ppu.max_block_body_size().unwrap(), max_block_body_size); + + assert!(ppu.max_block_header_size().is_none()); + let max_block_header_size = 91011; + ppu.set_max_block_header_size(max_block_header_size); + assert_eq!(ppu.max_block_header_size().unwrap(), max_block_header_size); + + assert!(ppu.minfee_a().is_none()); + let minfee_a = Coin::from(1u32); + ppu.set_minfee_a(&minfee_a); + assert_eq!(ppu.minfee_a().unwrap(), minfee_a); + + assert!(ppu.minfee_b().is_none()); + let minfee_b = Coin::from(2u32); + ppu.set_minfee_b(&minfee_b); + assert_eq!(ppu.minfee_b().unwrap(), minfee_b); + + assert!(ppu.key_deposit().is_none()); + let key_deposit = Coin::from(3u32); + ppu.set_key_deposit(&key_deposit); + assert_eq!(ppu.key_deposit().unwrap(), key_deposit); + + assert!(ppu.pool_deposit().is_none()); + let pool_deposit = Coin::from(4u32); + ppu.set_pool_deposit(&pool_deposit); + assert_eq!(ppu.pool_deposit().unwrap(), pool_deposit); + + assert!(ppu.max_epoch().is_none()); + let max_epoch = 5; + ppu.set_max_epoch(max_epoch); + assert_eq!(ppu.max_epoch().unwrap(), max_epoch); + + assert!(ppu.n_opt().is_none()); + let n_opt = 6; + ppu.set_n_opt(n_opt); + assert_eq!(ppu.n_opt().unwrap(), n_opt); + + assert!(ppu.pool_pledge_influence().is_none()); + let pool_pledge_influence = UnitInterval::new(&BigNum::from(7u32), &BigNum::from(77u32)); + ppu.set_pool_pledge_influence(&pool_pledge_influence); + assert_eq!(ppu.pool_pledge_influence().unwrap(), pool_pledge_influence); + + assert!(ppu.expansion_rate().is_none()); + let expansion_rate = UnitInterval::new(&BigNum::from(8u32), &BigNum::from(9u32)); + ppu.set_expansion_rate(&expansion_rate); + assert_eq!(ppu.expansion_rate().unwrap(), expansion_rate); + + assert!(ppu.treasury_growth_rate().is_none()); + let treasury_growth_rate = UnitInterval::new(&BigNum::from(10u32), &BigNum::from(11u32)); + ppu.set_treasury_growth_rate(&treasury_growth_rate); + assert_eq!(ppu.treasury_growth_rate().unwrap(), treasury_growth_rate); + + assert!(ppu.protocol_version().is_none()); + let protocol_version = ProtocolVersion::new(12u32, 13u32); + ppu.set_protocol_version(&protocol_version); + assert_eq!(ppu.protocol_version().unwrap(), protocol_version); + + assert!(ppu.min_pool_cost().is_none()); + let min_pool_cost = Coin::from(14u32); + ppu.set_min_pool_cost(&min_pool_cost); + assert_eq!(ppu.min_pool_cost().unwrap(), min_pool_cost); + + assert!(ppu.ada_per_utxo_byte().is_none()); + let ada_per_utxo_byte = Coin::from(15u32); + ppu.set_ada_per_utxo_byte(&ada_per_utxo_byte); + assert_eq!(ppu.ada_per_utxo_byte().unwrap(), ada_per_utxo_byte); + + assert!(ppu.cost_models().is_none()); + let cost_models = TxBuilderConstants::plutus_vasil_cost_models(); + ppu.set_cost_models(&cost_models); + assert_eq!(ppu.cost_models().unwrap(), cost_models); + + assert!(ppu.execution_costs().is_none()); + let execution_costs = ExUnitPrices::new( + &SubCoin::new(&BigNum::from(16u32), &BigNum::from(17u32)), + &SubCoin::new(&BigNum::from(18u32), &BigNum::from(19u32)), + ); + ppu.set_execution_costs(&execution_costs); + assert_eq!(ppu.execution_costs().unwrap(), execution_costs); + + assert!(ppu.max_tx_ex_units().is_none()); + let max_tx_ex_units = ExUnits::new(&BigNum::from(20u32), &BigNum::from(21u32)); + ppu.set_max_tx_ex_units(&max_tx_ex_units); + assert_eq!(ppu.max_tx_ex_units().unwrap(), max_tx_ex_units); + + assert!(ppu.max_block_ex_units().is_none()); + let max_block_ex_units = ExUnits::new(&BigNum::from(22u32), &BigNum::from(23u32)); + ppu.set_max_block_ex_units(&max_block_ex_units); + assert_eq!(ppu.max_block_ex_units().unwrap(), max_block_ex_units); + + assert!(ppu.max_value_size().is_none()); + let max_value_size = 24; + ppu.set_max_value_size(max_value_size); + assert_eq!(ppu.max_value_size().unwrap(), max_value_size); + + assert!(ppu.collateral_percentage().is_none()); + let collateral_percentage = 25; + ppu.set_collateral_percentage(collateral_percentage); + assert_eq!(ppu.collateral_percentage().unwrap(), collateral_percentage); + + assert!(ppu.max_collateral_inputs().is_none()); + let max_collateral_inputs = 25; + ppu.set_max_collateral_inputs(max_collateral_inputs); + assert_eq!(ppu.max_collateral_inputs().unwrap(), max_collateral_inputs); + + assert!(ppu.pool_voting_thresholds().is_none()); + let pool_voting_thresholds = PoolVotingThresholds::new( + &UnitInterval::new(&BigNum::from(26u32), &BigNum::from(27u32)), + &UnitInterval::new(&BigNum::from(28u32), &BigNum::from(29u32)), + &UnitInterval::new(&BigNum::from(30u32), &BigNum::from(31u32)), + &UnitInterval::new(&BigNum::from(40u32), &BigNum::from(41u32)), + &UnitInterval::new(&BigNum::from(50u32), &BigNum::from(51u32)), + ); + ppu.set_pool_voting_thresholds(&pool_voting_thresholds); + assert_eq!(ppu.pool_voting_thresholds().unwrap(), pool_voting_thresholds); + + assert!(ppu.drep_voting_thresholds().is_none()); + let drep_voting_thresholds = DrepVotingThresholds::new( + &UnitInterval::new(&BigNum::from(26u32), &BigNum::from(27u32)), + &UnitInterval::new(&BigNum::from(28u32), &BigNum::from(29u32)), + &UnitInterval::new(&BigNum::from(30u32), &BigNum::from(31u32)), + &UnitInterval::new(&BigNum::from(40u32), &BigNum::from(41u32)), + &UnitInterval::new(&BigNum::from(50u32), &BigNum::from(51u32)), + &UnitInterval::new(&BigNum::from(60u32), &BigNum::from(61u32)), + &UnitInterval::new(&BigNum::from(66u32), &BigNum::from(65u32)), + &UnitInterval::new(&BigNum::from(70u32), &BigNum::from(71u32)), + &UnitInterval::new(&BigNum::from(77u32), &BigNum::from(75u32)), + &UnitInterval::new(&BigNum::from(80u32), &BigNum::from(81u32)), + ); + ppu.set_drep_voting_thresholds(&drep_voting_thresholds); + assert_eq!(ppu.drep_voting_thresholds().unwrap(), drep_voting_thresholds); + + assert!(ppu.min_committee_size().is_none()); + let min_committee_size = 32; + ppu.set_min_committee_size(min_committee_size); + assert_eq!(ppu.min_committee_size().unwrap(), min_committee_size); + + assert!(ppu.committee_term_limit().is_none()); + let committee_term_limit = 33; + ppu.set_committee_term_limit(committee_term_limit); + assert_eq!(ppu.committee_term_limit().unwrap(), committee_term_limit); + + assert!(ppu.governance_action_validity_period().is_none()); + let governance_action_validity_period = 34; + ppu.set_governance_action_validity_period(governance_action_validity_period); + assert_eq!(ppu.governance_action_validity_period().unwrap(), governance_action_validity_period); + + assert!(ppu.governance_action_deposit().is_none()); + let governance_action_deposit = Coin::from(35u32); + ppu.set_governance_action_deposit(&governance_action_deposit); + assert_eq!(ppu.governance_action_deposit().unwrap(), governance_action_deposit); + + assert!(ppu.drep_deposit().is_none()); + let drep_deposit = Coin::from(36u32); + ppu.set_drep_deposit(&drep_deposit); + assert_eq!(ppu.drep_deposit().unwrap(), drep_deposit); + + assert!(ppu.drep_inactivity_period().is_none()); + let drep_inactivity_period = 37; + ppu.set_drep_inactivity_period(drep_inactivity_period); + assert_eq!(ppu.drep_inactivity_period().unwrap(), drep_inactivity_period); + + assert!(ppu.ref_script_coins_per_byte().is_none()); + let ref_script_coins_per_byte = UnitInterval::new(&BigNum::from(38u32), &BigNum::from(39u32)); + ppu.set_ref_script_coins_per_byte(&ref_script_coins_per_byte); + assert_eq!(ppu.ref_script_coins_per_byte().unwrap(), ref_script_coins_per_byte); + + //since it is deprecated + assert!(ppu.d().is_none()); +} + +fn pool_voting_thresholds_test() { + // Creating unit intervals for testing + let motion_no_confidence = UnitInterval::new(&BigNum::from(1u32), &BigNum::from(100u32)); + let committee_normal = UnitInterval::new(&BigNum::from(2u32), &BigNum::from(100u32)); + let committee_no_confidence = UnitInterval::new(&BigNum::from(3u32), &BigNum::from(100u32)); + let hard_fork_initiation = UnitInterval::new(&BigNum::from(4u32), &BigNum::from(100u32)); + let security_relevant_threshold = UnitInterval::new(&BigNum::from(5u32), &BigNum::from(100u32)); + + // Creating a new PoolVotingThresholds instance + let pvt = PoolVotingThresholds::new( + &motion_no_confidence, + &committee_normal, + &committee_no_confidence, + &hard_fork_initiation, + &security_relevant_threshold, + ); + + // Asserting that the getters return the expected values + assert_eq!(pvt.motion_no_confidence(), motion_no_confidence); + assert_eq!(pvt.committee_normal(), committee_normal); + assert_eq!(pvt.committee_no_confidence(), committee_no_confidence); + assert_eq!(pvt.hard_fork_initiation(), hard_fork_initiation); + assert_eq!(pvt.security_relevant_threshold(), security_relevant_threshold); +} + +fn drep_voting_thresholds_test() { + // Creating unit intervals for testing + let motion_no_confidence = UnitInterval::new(&BigNum::from(1u32), &BigNum::from(100u32)); + let committee_normal = UnitInterval::new(&BigNum::from(2u32), &BigNum::from(100u32)); + let committee_no_confidence = UnitInterval::new(&BigNum::from(3u32), &BigNum::from(100u32)); + let update_constitution = UnitInterval::new(&BigNum::from(4u32), &BigNum::from(100u32)); + let hard_fork_initiation = UnitInterval::new(&BigNum::from(5u32), &BigNum::from(100u32)); + let pp_network_group = UnitInterval::new(&BigNum::from(6u32), &BigNum::from(100u32)); + let pp_economic_group = UnitInterval::new(&BigNum::from(7u32), &BigNum::from(100u32)); + let pp_technical_group = UnitInterval::new(&BigNum::from(8u32), &BigNum::from(100u32)); + let pp_governance_group = UnitInterval::new(&BigNum::from(9u32), &BigNum::from(100u32)); + let treasury_withdrawal = UnitInterval::new(&BigNum::from(10u32), &BigNum::from(100u32)); + + // Creating a new DrepVotingThresholds instance + let dvt = DrepVotingThresholds::new( + &motion_no_confidence, + &committee_normal, + &committee_no_confidence, + &update_constitution, + &hard_fork_initiation, + &pp_network_group, + &pp_economic_group, + &pp_technical_group, + &pp_governance_group, + &treasury_withdrawal, + ); + + // Asserting that the getters return the expected values + assert_eq!(dvt.motion_no_confidence(), motion_no_confidence); + assert_eq!(dvt.committee_normal(), committee_normal); + assert_eq!(dvt.committee_no_confidence(), committee_no_confidence); + assert_eq!(dvt.update_constitution(), update_constitution); + assert_eq!(dvt.hard_fork_initiation(), hard_fork_initiation); + assert_eq!(dvt.pp_network_group(), pp_network_group); + assert_eq!(dvt.pp_economic_group(), pp_economic_group); + assert_eq!(dvt.pp_technical_group(), pp_technical_group); + assert_eq!(dvt.pp_governance_group(), pp_governance_group); + assert_eq!(dvt.treasury_withdrawal(), treasury_withdrawal); +} \ No newline at end of file From 3eb710750347b88e92a95deca55080c389eba107 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 5 Jun 2024 16:09:44 +0700 Subject: [PATCH 277/349] bump version --- package-lock.json | 2 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5311ef2d..09b18ff1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.30", + "version": "12.0.0-alpha.31", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 4bb449b9..4c7e071d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.30", + "version": "12.0.0-alpha.31", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index e05a1118..7b4804b7 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.30" +version = "12.0.0-alpha.31" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 57e65ce5..84716ddf 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -55,7 +55,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.30" +version = "12.0.0-alpha.31" dependencies = [ "bech32", "cbor_event", From e810801525b36e24a0f03ea7e14e196dd94c5502 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 16 Jun 2024 17:13:46 +0700 Subject: [PATCH 278/349] replace NativeScript by NativeScriptSource in add_native_script_input, new tests --- rust/src/builders/tx_builder.rs | 5 +- rust/src/builders/tx_inputs_builder.rs | 31 +- .../protocol_types/protocol_param_update.rs | 2 +- rust/src/tests/builders/mod.rs | 3 +- rust/src/tests/builders/tx_builder.rs | 4 +- rust/src/tests/builders/tx_inputs_builder.rs | 391 ++++++++++++++++++ rust/src/tests/mock_objects.rs | 121 +++++- 7 files changed, 538 insertions(+), 19 deletions(-) create mode 100644 rust/src/tests/builders/tx_inputs_builder.rs diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index 5087f8ae..70ac1f96 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -829,7 +829,10 @@ impl TransactionBuilder { input: &TransactionInput, amount: &Value, ) { - self.inputs.add_native_script_input(script, input, amount); + self.inputs.add_native_script_input( + &NativeScriptSource::new(script), + input, + amount); } /// This method will add the input to the builder and also register the required plutus witness diff --git a/rust/src/builders/tx_inputs_builder.rs b/rust/src/builders/tx_inputs_builder.rs index e0bf9b56..8c7d7127 100644 --- a/rust/src/builders/tx_inputs_builder.rs +++ b/rust/src/builders/tx_inputs_builder.rs @@ -73,16 +73,13 @@ impl TxInputsBuilder { /// This method will add the input to the builder and also register the required native script witness pub fn add_native_script_input( &mut self, - script: &NativeScript, + script: &NativeScriptSource, input: &TransactionInput, amount: &Value, ) { - let hash = script.hash(); + let hash = script.script_hash(); self.add_script_input(&hash, input, amount); - let witness = ScriptWitnessType::NativeScriptWitness(NativeScriptSourceEnum::NativeScript( - script.clone(), - None, - )); + let witness = ScriptWitnessType::NativeScriptWitness(script.0.clone()); self.insert_input_with_witness(&hash, input, &witness); } @@ -102,7 +99,7 @@ impl TxInputsBuilder { pub fn add_bootstrap_input( &mut self, - hash: &ByronAddress, + address: &ByronAddress, input: &TransactionInput, amount: &Value, ) { @@ -111,7 +108,7 @@ impl TxInputsBuilder { amount: amount.clone(), }; self.push_input((inp, None)); - self.required_witnesses.bootstraps.insert(hash.to_bytes()); + self.required_witnesses.bootstraps.insert(address.to_bytes()); } /// Adds non script input, in case of script or reward address input it will return an error @@ -333,6 +330,10 @@ impl TxInputsBuilder { .filter_map(|wit| wit.get_script_ref_input_with_size()) } + pub(crate) fn get_required_signers(&self) -> Ed25519KeyHashes { + self.into() + } + fn insert_input_with_witness( &mut self, script_hash: &ScriptHash, @@ -370,10 +371,18 @@ impl From<&TxInputsBuilder> for Ed25519KeyHashes { .values() .flat_map(|tx_wits| tx_wits.values()) .for_each(|swt: &Option| { - if let Some(ScriptWitnessType::NativeScriptWitness(script_source)) = swt { - if let Some(signers) = script_source.required_signers() { - set.extend_move(signers); + match swt { + Some(ScriptWitnessType::NativeScriptWitness(script_source)) => { + if let Some(signers) = script_source.required_signers() { + set.extend_move(signers); + } + } + Some(ScriptWitnessType::PlutusScriptWitness(script_source)) => { + if let Some(signers) = script_source.get_required_signers() { + set.extend_move(signers); + } } + None => (), } }); set diff --git a/rust/src/protocol_types/protocol_param_update.rs b/rust/src/protocol_types/protocol_param_update.rs index 14fe8c78..7e570f48 100644 --- a/rust/src/protocol_types/protocol_param_update.rs +++ b/rust/src/protocol_types/protocol_param_update.rs @@ -119,7 +119,7 @@ impl DrepVotingThresholds { } } - pub fn new_default() -> Self { + pub(crate) fn new_default() -> Self { Self { ..Default::default() } diff --git a/rust/src/tests/builders/mod.rs b/rust/src/tests/builders/mod.rs index ea43ed40..bdaecc2c 100644 --- a/rust/src/tests/builders/mod.rs +++ b/rust/src/tests/builders/mod.rs @@ -3,4 +3,5 @@ mod tx_builder; mod voting_builder; mod voting_proposal_builder; mod certificates_builder; -mod mint_builder; \ No newline at end of file +mod mint_builder; +mod tx_inputs_builder; \ No newline at end of file diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index 88c831e0..c40c87e4 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -4280,12 +4280,12 @@ fn test_regular_and_collateral_inputs_together() { let mut collateral_builder = TxInputsBuilder::new(); input_builder.add_native_script_input( - &nscript1, + &NativeScriptSource::new(&nscript1), &TransactionInput::new(&genesis_id(), 0), &Value::new(&BigNum(1_000_000)), ); collateral_builder.add_native_script_input( - &nscript2, + &NativeScriptSource::new(&nscript2), &TransactionInput::new(&genesis_id(), 1), &Value::new(&BigNum(1_000_000)), ); diff --git a/rust/src/tests/builders/tx_inputs_builder.rs b/rust/src/tests/builders/tx_inputs_builder.rs new file mode 100644 index 00000000..2ffe1e01 --- /dev/null +++ b/rust/src/tests/builders/tx_inputs_builder.rs @@ -0,0 +1,391 @@ +use crate::fakes::{fake_key_hash, fake_script_hash, fake_tx_input}; +use crate::tests::mock_objects::{ + create_base_address, create_base_script_address, create_enterprise_address, + create_enterprise_script_address, create_plutus_script, create_pointer_address, + create_pointer_script_address, create_redeemer, create_reward_address, +}; +use crate::*; + +#[test] +fn regular_inputs() { + let mut tx_inputs_builder = TxInputsBuilder::new(); + let base_address_1 = create_base_address(1); + let tx_input_1 = fake_tx_input(1); + let input_value_1 = Value::new(&BigNum(100)); + tx_inputs_builder + .add_regular_input(&base_address_1, &tx_input_1, &input_value_1) + .unwrap(); + + let enterprise_address_2 = create_enterprise_address(2); + let tx_input_2 = fake_tx_input(2); + let input_value_2 = Value::new(&BigNum(200)); + tx_inputs_builder + .add_regular_input(&enterprise_address_2, &tx_input_2, &input_value_2) + .unwrap(); + + let pointer_address_3 = create_pointer_address(3); + let tx_input_3 = fake_tx_input(3); + let input_value_3 = Value::new(&BigNum(300)); + tx_inputs_builder + .add_regular_input(&pointer_address_3, &tx_input_3, &input_value_3) + .unwrap(); + + let byron_address_4 = + ByronAddress::from_base58("Ae2tdPwUPEZ3MHKkpT5Bpj549vrRH7nBqYjNXnCV8G2Bc2YxNcGHEa8ykDp") + .unwrap() + .to_address(); + let tx_input_4 = fake_tx_input(4); + let input_value_4 = Value::new(&BigNum(400)); + tx_inputs_builder + .add_regular_input(&byron_address_4, &tx_input_4, &input_value_4) + .unwrap(); + + let key_hash_5 = fake_key_hash(5); + let tx_input_5 = fake_tx_input(5); + let input_value_5 = Value::new(&BigNum(500)); + tx_inputs_builder.add_key_input(&key_hash_5, &tx_input_5, &input_value_5); + + let byron_address_6 = + ByronAddress::from_base58("Ae2tdPwUPEZ6r6zbg4ibhFrNnyKHg7SYuPSfDpjKxgvwFX9LquRep7gj7FQ") + .unwrap(); + let tx_input_6 = fake_tx_input(6); + let input_value_6 = Value::new(&BigNum(600)); + tx_inputs_builder.add_bootstrap_input(&byron_address_6, &tx_input_6, &input_value_6); + + let key_hash_7 = fake_key_hash(7); + tx_inputs_builder.add_required_signer(&key_hash_7); + + let ref_inputs = tx_inputs_builder.get_ref_inputs(); + assert_eq!(ref_inputs.len(), 0); + + let native_scripts = tx_inputs_builder.get_native_input_scripts(); + assert!(native_scripts.is_none()); + + let plutus_scripts = tx_inputs_builder.get_plutus_input_scripts(); + assert!(plutus_scripts.is_none()); + + assert_eq!(tx_inputs_builder.has_plutus_scripts(), false); + + let required_signatures: Ed25519KeyHashes = tx_inputs_builder.get_required_signers(); + assert_eq!(required_signatures.len(), 5); + + required_signatures.contains(&base_address_1.payment_cred().unwrap().to_keyhash().unwrap()); + required_signatures.contains( + &enterprise_address_2 + .payment_cred() + .unwrap() + .to_keyhash() + .unwrap(), + ); + required_signatures.contains( + &pointer_address_3 + .payment_cred() + .unwrap() + .to_keyhash() + .unwrap(), + ); + required_signatures.contains(&key_hash_5); + required_signatures.contains(&key_hash_7); + + let tx_inputs = tx_inputs_builder.inputs(); + assert_eq!(tx_inputs.len(), 6); + assert!(tx_inputs.contains(&tx_input_1)); + assert!(tx_inputs.contains(&tx_input_2)); + assert!(tx_inputs.contains(&tx_input_3)); + assert!(tx_inputs.contains(&tx_input_4)); + assert!(tx_inputs.contains(&tx_input_5)); + assert!(tx_inputs.contains(&tx_input_6)); + + let bootstraps = get_bootstraps(&tx_inputs_builder); + let boostrap_1 = ByronAddress::from_address(&byron_address_4) + .unwrap() + .to_bytes(); + let boostrap_2 = byron_address_6.to_bytes(); + assert_eq!(bootstraps.len(), 2); + + assert!(bootstraps.contains(&boostrap_1)); + assert!(bootstraps.contains(&boostrap_2)); +} + +#[test] +fn script_input_as_regular_input_error() { + let mut tx_inputs_builder = TxInputsBuilder::new(); + let plutus_script = fake_tx_input(1); + let input_value = Value::new(&BigNum(100)); + + let base_address_1 = create_base_script_address(1); + let res_1 = tx_inputs_builder.add_regular_input(&base_address_1, &plutus_script, &input_value); + assert!(res_1.is_err()); + + let enterprise_address_2 = create_enterprise_script_address(2); + let res_2 = + tx_inputs_builder.add_regular_input(&enterprise_address_2, &plutus_script, &input_value); + assert!(res_2.is_err()); + + let pointer_address_3 = create_pointer_script_address(3); + let res_3 = + tx_inputs_builder.add_regular_input(&pointer_address_3, &plutus_script, &input_value); + assert!(res_3.is_err()); +} + +#[test] +fn rewards_address_input_as_regular_input_error() { + let mut tx_inputs_builder = TxInputsBuilder::new(); + let rewards_address = create_reward_address(1); + let tx_input = fake_tx_input(1); + let input_value = Value::new(&BigNum(100)); + let res = tx_inputs_builder.add_regular_input(&rewards_address, &tx_input, &input_value); + assert!(res.is_err()); +} + +#[test] +fn plutus_script_input() { + let mut tx_inputs_builder = TxInputsBuilder::new(); + let tx_input_1 = fake_tx_input(1); + let input_value_1 = Value::new(&BigNum(100)); + + let plutus_script = create_plutus_script(1, &Language::new_plutus_v2()); + let plutus_script_source = PlutusScriptSource::new(&plutus_script); + let redeemer = create_redeemer(1) + .clone_with_index_and_tag(&BigNum(0), &RedeemerTag::new_spend()); + + let datum = PlutusData::new_empty_constr_plutus_data(&BigNum::zero()); + let plutus_witness = + PlutusWitness::new_with_ref(&plutus_script_source, &DatumSource::new(&datum), &redeemer); + + tx_inputs_builder.add_plutus_script_input(&plutus_witness, &tx_input_1, &input_value_1); + + let plutus_scripts = tx_inputs_builder.get_plutus_input_scripts().unwrap(); + assert_eq!(plutus_scripts.len(), 1); + + let plutus_wit_from_builder = plutus_scripts.get(0); + assert_eq!(plutus_wit_from_builder.script().unwrap(), plutus_script); + assert_eq!(plutus_wit_from_builder.datum().unwrap(), datum); + assert_eq!(plutus_wit_from_builder.redeemer(), redeemer); + + assert!(tx_inputs_builder.has_plutus_scripts()); + + let req_signers = tx_inputs_builder.get_required_signers(); + assert_eq!(req_signers.len(), 0); + + let inputs = tx_inputs_builder.inputs(); + assert_eq!(inputs.len(), 1); + assert!(inputs.contains(&tx_input_1)); + + let ref_inputs = tx_inputs_builder.get_ref_inputs(); + assert_eq!(ref_inputs.len(), 0); +} + +#[test] +fn plutus_script_input_with_required_signers() { + let mut tx_inputs_builder = TxInputsBuilder::new(); + let tx_input_1 = fake_tx_input(1); + let input_value_1 = Value::new(&BigNum(100)); + + let key_hash = fake_key_hash(1); + let key_hashes = Ed25519KeyHashes::from_vec(vec![key_hash]); + + let plutus_script = create_plutus_script(1, &Language::new_plutus_v2()); + let mut plutus_script_source = PlutusScriptSource::new(&plutus_script); + plutus_script_source.set_required_signers(&key_hashes); + + let redeemer = create_redeemer(1) + .clone_with_index_and_tag(&BigNum(0), &RedeemerTag::new_spend()); + + let datum = PlutusData::new_empty_constr_plutus_data(&BigNum::zero()); + let plutus_witness = + PlutusWitness::new_with_ref(&plutus_script_source, &DatumSource::new(&datum), &redeemer); + + tx_inputs_builder.add_plutus_script_input(&plutus_witness, &tx_input_1, &input_value_1); + + let plutus_scripts = tx_inputs_builder.get_plutus_input_scripts().unwrap(); + assert_eq!(plutus_scripts.len(), 1); + + let plutus_wit_from_builder = plutus_scripts.get(0); + assert_eq!(plutus_wit_from_builder.script().unwrap(), plutus_script); + assert_eq!(plutus_wit_from_builder.datum().unwrap(), datum); + assert_eq!(plutus_wit_from_builder.redeemer(), redeemer); + + assert!(tx_inputs_builder.has_plutus_scripts()); + + let req_signers = tx_inputs_builder.get_required_signers(); + assert_eq!(req_signers.len(), 1); + assert_eq!(req_signers, key_hashes); + + let inputs = tx_inputs_builder.inputs(); + assert_eq!(inputs.len(), 1); + assert!(inputs.contains(&tx_input_1)); + + let ref_inputs = tx_inputs_builder.get_ref_inputs(); + assert_eq!(ref_inputs.len(), 0); +} + +#[test] +fn plutus_script_input_with_ref() { + let mut tx_inputs_builder = TxInputsBuilder::new(); + let tx_input_1 = fake_tx_input(1); + let input_value_1 = Value::new(&BigNum(100)); + + let ref_input_1 = fake_tx_input(2); + let script_hash = fake_script_hash(1); + let lang_ver = Language::new_plutus_v2(); + let script_size = 100; + + let ref_input_2 = fake_tx_input(3); + + let plutus_script_source = + PlutusScriptSource::new_ref_input(&script_hash, &ref_input_1, &lang_ver, script_size); + + let redeemer = create_redeemer(1) + .clone_with_index_and_tag(&BigNum(0), &RedeemerTag::new_spend()); + + let plutus_witness = PlutusWitness::new_with_ref( + &plutus_script_source, + &DatumSource::new_ref_input(&ref_input_2), + &redeemer, + ); + + tx_inputs_builder.add_plutus_script_input(&plutus_witness, &tx_input_1, &input_value_1); + + let plutus_scripts = tx_inputs_builder.get_plutus_input_scripts().unwrap(); + assert_eq!(plutus_scripts.len(), 1); + + let plutus_wit_from_builder = plutus_scripts.get(0); + assert_eq!(plutus_wit_from_builder.script(), None); + assert_eq!(plutus_wit_from_builder.datum(), None); + assert_eq!(plutus_wit_from_builder.redeemer(), redeemer); + + assert!(tx_inputs_builder.has_plutus_scripts()); + + let req_signers = tx_inputs_builder.get_required_signers(); + assert_eq!(req_signers.len(), 0); + + let inputs = tx_inputs_builder.inputs(); + assert_eq!(inputs.len(), 1); + assert!(inputs.contains(&tx_input_1)); + + let ref_inputs = tx_inputs_builder.get_ref_inputs(); + assert_eq!(ref_inputs.len(), 2); + assert!(ref_inputs.contains(&ref_input_1)); + assert!(ref_inputs.contains(&ref_input_2)); +} + +#[test] +fn native_script_input() { + let mut tx_inputs_builder = TxInputsBuilder::new(); + let tx_input_1 = fake_tx_input(1); + let input_value_1 = Value::new(&BigNum(100)); + + let key_hash_1 = fake_key_hash(1); + let mut native_scripts = NativeScripts::new(); + native_scripts.add( + &NativeScript::new_script_pubkey( + &ScriptPubkey::new(&key_hash_1) + ) + ); + let native_script = NativeScript::new_script_all( + &ScriptAll::new( + &native_scripts + ), + ); + + let native_script_source = NativeScriptSource::new(&native_script); + + tx_inputs_builder.add_native_script_input(&native_script_source, &tx_input_1, &input_value_1); + + let native_scripts = tx_inputs_builder.get_native_input_scripts().unwrap(); + assert_eq!(native_scripts.len(), 1); + + let native_wit_from_builder = native_scripts.get(0); + assert_eq!(native_wit_from_builder, native_script); + + let req_signers = tx_inputs_builder.get_required_signers(); + assert_eq!(req_signers.len(), 1); + assert_eq!(req_signers.get(0), key_hash_1); + + let inputs = tx_inputs_builder.inputs(); + assert_eq!(inputs.len(), 1); + assert!(inputs.contains(&tx_input_1)); + + let ref_inputs = tx_inputs_builder.get_ref_inputs(); + assert_eq!(ref_inputs.len(), 0); +} + +#[test] +fn native_script_custom_required_witness_input() { + let mut tx_inputs_builder = TxInputsBuilder::new(); + let tx_input_1 = fake_tx_input(1); + let input_value_1 = Value::new(&BigNum(100)); + + let key_hash_1 = fake_key_hash(1); + let key_hash_2 = fake_key_hash(2); + + let mut native_scripts = NativeScripts::new(); + native_scripts.add( + &NativeScript::new_script_pubkey( + &ScriptPubkey::new(&key_hash_1) + ) + ); + let native_script = NativeScript::new_script_all( + &ScriptAll::new( + &native_scripts + ), + ); + + let mut native_script_source = NativeScriptSource::new(&native_script); + let mut key_hashes = Ed25519KeyHashes::new(); + key_hashes.add(&key_hash_2); + native_script_source.set_required_signers(&key_hashes); + + tx_inputs_builder.add_native_script_input(&native_script_source, &tx_input_1, &input_value_1); + + let native_scripts = tx_inputs_builder.get_native_input_scripts().unwrap(); + assert_eq!(native_scripts.len(), 1); + + let native_wit_from_builder = native_scripts.get(0); + assert_eq!(native_wit_from_builder, native_script); + + let req_signers = tx_inputs_builder.get_required_signers(); + assert_eq!(req_signers.len(), 1); + assert_eq!(req_signers.get(0), key_hash_2); + + let inputs = tx_inputs_builder.inputs(); + assert_eq!(inputs.len(), 1); + assert!(inputs.contains(&tx_input_1)); + + let ref_inputs = tx_inputs_builder.get_ref_inputs(); + assert_eq!(ref_inputs.len(), 0); +} + +#[test] +fn native_script_input_ref_script() { + let mut tx_inputs_builder = TxInputsBuilder::new(); + let tx_input_1 = fake_tx_input(1); + let input_value_1 = Value::new(&BigNum(100)); + + let key_hash_1 = fake_key_hash(1); + let ref_input = fake_tx_input(2); + let script_hash = fake_script_hash(1); + + let mut native_script_source = NativeScriptSource::new_ref_input(&script_hash, &ref_input); + let mut key_hashes = Ed25519KeyHashes::new(); + key_hashes.add(&key_hash_1); + native_script_source.set_required_signers(&key_hashes); + + tx_inputs_builder.add_native_script_input(&native_script_source, &tx_input_1, &input_value_1); + + let native_scripts = tx_inputs_builder.get_native_input_scripts(); + assert_eq!(native_scripts, None); + + let req_signers = tx_inputs_builder.get_required_signers(); + assert_eq!(req_signers.len(), 1); + assert_eq!(req_signers.get(0), key_hash_1); + + let inputs = tx_inputs_builder.inputs(); + assert_eq!(inputs.len(), 1); + assert!(inputs.contains(&tx_input_1)); + + let ref_inputs = tx_inputs_builder.get_ref_inputs(); + assert_eq!(ref_inputs.len(), 1); + assert!(ref_inputs.contains(&ref_input)); +} \ No newline at end of file diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/mock_objects.rs index 299919ac..5fa04473 100644 --- a/rust/src/tests/mock_objects.rs +++ b/rust/src/tests/mock_objects.rs @@ -1,6 +1,4 @@ -use crate::fakes::{ - fake_anchor_data_hash, fake_key_hash, fake_pool_metadata_hash, fake_tx_hash, fake_vrf_key_hash, -}; +use crate::fakes::{fake_anchor_data_hash, fake_key_hash, fake_pool_metadata_hash, fake_script_hash, fake_tx_hash, fake_vrf_key_hash}; use crate::fees::LinearFee; use crate::tests::helpers::harden; use crate::*; @@ -309,6 +307,123 @@ pub(crate) fn create_change_address() -> Address { addr.to_address() } +pub(crate) fn create_base_address(index: u32) -> Address { + let spend = root_key() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(index) + .to_public(); + let stake = root_key() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let addr = BaseAddress::new( + NetworkInfo::testnet_preprod().network_id(), + &spend_cred, + &stake_cred, + ); + addr.to_address() +} + +pub(crate) fn create_base_script_address(index: u8) -> Address { + let stake = root_key() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + let spend_cred = Credential::from_scripthash(&fake_script_hash(index)); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let addr = BaseAddress::new( + NetworkInfo::testnet_preprod().network_id(), + &spend_cred, + &stake_cred, + ); + addr.to_address() +} + +pub(crate) fn create_enterprise_address(index: u32) -> Address { + let spend = root_key() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(index) + .to_public(); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let addr = EnterpriseAddress::new( + NetworkInfo::testnet_preprod().network_id(), + &spend_cred, + ); + addr.to_address() +} + +pub(crate) fn create_enterprise_script_address(index: u8) -> Address { + let spend_cred = Credential::from_scripthash(&fake_script_hash(index)); + let addr = EnterpriseAddress::new( + NetworkInfo::testnet_preprod().network_id(), + &spend_cred, + ); + addr.to_address() +} + +pub(crate) fn create_pointer_address(index: u32) -> Address { + let spend = root_key() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(index) + .to_public(); + let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); + let pointer = Pointer::new(1, 2, 3); + let addr = PointerAddress::new( + NetworkInfo::testnet_preprod().network_id(), + &spend_cred, + &pointer + ); + addr.to_address() +} + +pub(crate) fn create_pointer_script_address(index: u8) -> Address { + let spend_cred = Credential::from_scripthash(&fake_script_hash(index)); + let pointer = Pointer::new(1, 2, 3); + let addr = PointerAddress::new( + NetworkInfo::testnet_preprod().network_id(), + &spend_cred, + &pointer + ); + addr.to_address() +} + +pub(crate) fn create_reward_address(index: u32) -> Address { + let stake = root_key() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(1) + .derive(index) + .to_public(); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let addr = RewardAddress::new( + NetworkInfo::testnet_preprod().network_id(), + &stake_cred, + ); + addr.to_address() +} + +pub(crate) fn create_malformed_address() -> Address { + MalformedAddress(vec![255, 255, 255, 255, 255, 255]).to_address() +} + pub(crate) fn create_rich_tx_builder(with_collateral: bool) -> TransactionBuilder { let mut tx_builder = create_reallistic_tx_builder(); let input = TransactionInput::new(&fake_tx_hash(1), 0); From 3d324d104371d439ae45d343f7341de49f21ca93 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 19 Jun 2024 15:44:09 +0700 Subject: [PATCH 279/349] add duplicated keys support for plutus maps --- rust/src/protocol_types/plutus/plutus_data.rs | 95 +++++++++++++++---- rust/src/serialization/plutus/plutus_data.rs | 14 +-- rust/src/tests/plutus.rs | 57 ++++++++++- 3 files changed, 140 insertions(+), 26 deletions(-) diff --git a/rust/src/protocol_types/plutus/plutus_data.rs b/rust/src/protocol_types/plutus/plutus_data.rs index 1209fbbd..969f323b 100644 --- a/rust/src/protocol_types/plutus/plutus_data.rs +++ b/rust/src/protocol_types/plutus/plutus_data.rs @@ -71,9 +71,39 @@ impl ConstrPlutusData { } } +#[wasm_bindgen] +#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, serde::Serialize, serde::Deserialize)] +pub struct PlutusMapValues { + pub(crate) elems: Vec, +} + +#[wasm_bindgen] +impl PlutusMapValues { + pub fn new() -> Self { + Self { elems: Vec::new() } + } + + pub fn len(&self) -> usize { + self.elems.len() + } + + pub fn get(&self, index: usize) -> Option { + self.elems.get(index).cloned() + } + + pub fn add(&mut self, elem: &PlutusData) { + self.elems.push(elem.clone()); + } + + pub(crate) fn add_move(&mut self, elem: PlutusData) { + self.elems.push(elem); + } +} + + #[wasm_bindgen] #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] -pub struct PlutusMap(pub(crate) LinkedHashMap); +pub struct PlutusMap(pub(crate) LinkedHashMap); to_from_bytes!(PlutusMap); @@ -83,15 +113,19 @@ impl PlutusMap { Self(LinkedHashMap::new()) } + + /// Return count ok different keys in the map. pub fn len(&self) -> usize { self.0.len() } - pub fn insert(&mut self, key: &PlutusData, value: &PlutusData) -> Option { - self.0.insert(key.clone(), value.clone()) + /// Returns the previous value associated with the key, if any. + /// Replace the values associated with the key. + pub fn insert(&mut self, key: &PlutusData, values: &PlutusMapValues) -> Option { + self.0.insert(key.clone(), values.clone()) } - pub fn get(&self, key: &PlutusData) -> Option { + pub fn get(&self, key: &PlutusData) -> Option { self.0.get(key).map(|v| v.clone()) } @@ -101,6 +135,21 @@ impl PlutusMap { definite_encoding: None, } } + + /// Adds a value to the list of values associated with the key. + pub(crate) fn add_value(&mut self, key: &PlutusData, value: &PlutusData) { + let mut values = self.0 + .entry(key.clone()) + .or_insert_with(PlutusMapValues::new); + values.add(value); + } + + pub(crate) fn add_value_move(&mut self, key: PlutusData, value: PlutusData) { + let mut values = self.0 + .entry(key) + .or_insert_with(PlutusMapValues::new); + values.add_move(value); + } } #[wasm_bindgen] @@ -614,7 +663,7 @@ pub fn encode_json_value_to_plutus_datum( for (raw_key, raw_value) in json_obj { let key = encode_string(&raw_key, schema, true)?; let value = encode_json_value_to_plutus_datum(raw_value, schema)?; - map.insert(&key, &value); + map.add_value(&key, &value); } Ok(PlutusData::new_map(&map)) } @@ -649,7 +698,7 @@ pub fn encode_json_value_to_plutus_datum( let value = entry_obj.get("v").ok_or_else(map_entry_err)?; let key = encode_json_value_to_plutus_datum(raw_key.clone(), schema)?; - map.insert( + map.add_value( &key, &encode_json_value_to_plutus_datum(value.clone(), schema)?, ); @@ -730,7 +779,7 @@ pub fn decode_plutus_datum_to_json_value( (None, Value::from(obj)) }, PlutusDataEnum::Map(map) => match schema { - PlutusDatumSchema::BasicConversions => (None, Value::from(map.0.iter().map(|(key, value)| { + PlutusDatumSchema::BasicConversions => (None, Value::from(map.0.iter().map(|(key, values)| { let json_key: String = match &key.datum { PlutusDataEnum::ConstrPlutusData(_) => Err(JsError::from_str("plutus data constructors are not allowed as keys in this schema. Use DetailedSchema.")), PlutusDataEnum::Map(_) => Err(JsError::from_str("plutus maps are not allowed as keys in this schema. Use DetailedSchema.")), @@ -738,17 +787,29 @@ pub fn decode_plutus_datum_to_json_value( PlutusDataEnum::Integer(x) => Ok(x.to_str()), PlutusDataEnum::Bytes(bytes) => String::from_utf8(bytes.clone()).or_else(|_err| Ok(format!("0x{}", hex::encode(bytes)))) }?; - let json_value = decode_plutus_datum_to_json_value(value, schema)?; - Ok((json_key, Value::from(json_value))) + if values.len() > 1 { + Err(JsError::from_str("plutus maps are not allowed to have more than one value per key in this schema. Use DetailedSchema.")) + } else if let Some(value) = values.get(0) { + let json_value = decode_plutus_datum_to_json_value(&value, schema)?; + Ok((json_key, Value::from(json_value))) + } else { + Err(JsError::from_str("plutus maps are not allowed to have empty values in this schema. Use DetailedSchema.")) + } }).collect::, JsError>>()?)), - PlutusDatumSchema::DetailedSchema => (Some("map"), Value::from(map.0.iter().map(|(key, value)| { - let k = decode_plutus_datum_to_json_value(key, schema)?; - let v = decode_plutus_datum_to_json_value(value, schema)?; - let mut kv_obj = serde_json::map::Map::with_capacity(2); - kv_obj.insert(String::from("k"), k); - kv_obj.insert(String::from("v"), v); - Ok(Value::from(kv_obj)) - }).collect::, JsError>>()?)), + PlutusDatumSchema::DetailedSchema => { + let mut entries = Vec::new(); + for (key, values) in map.0.iter() { + for value in &values.elems { + let k = decode_plutus_datum_to_json_value(key, schema)?; + let v = decode_plutus_datum_to_json_value(value, schema)?; + let mut kv_obj = serde_json::map::Map::with_capacity(2); + kv_obj.insert(String::from("k"), k); + kv_obj.insert(String::from("v"), v); + entries.push(kv_obj); + } + } + (Some("map"), Value::from(entries)) + }, }, PlutusDataEnum::List(list) => { let mut elems = Vec::new(); diff --git a/rust/src/serialization/plutus/plutus_data.rs b/rust/src/serialization/plutus/plutus_data.rs index 51e5b5fd..beac8f6d 100644 --- a/rust/src/serialization/plutus/plutus_data.rs +++ b/rust/src/serialization/plutus/plutus_data.rs @@ -71,9 +71,11 @@ impl cbor_event::se::Serialize for PlutusMap { serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?; - for (key, value) in &self.0 { - key.serialize(serializer)?; - value.serialize(serializer)?; + for (key, values) in &self.0 { + for value in &values.elems { + key.serialize(serializer)?; + value.serialize(serializer)?; + } } Ok(serializer) } @@ -81,7 +83,7 @@ impl cbor_event::se::Serialize for PlutusMap { impl Deserialize for PlutusMap { fn deserialize(raw: &mut Deserializer) -> Result { - let mut table = LinkedHashMap::new(); + let mut plutus_map = PlutusMap::new(); (|| -> Result<_, DeserializeError> { let len = raw.map()?; let mut total = 0; @@ -94,13 +96,13 @@ impl Deserialize for PlutusMap { } let key = PlutusData::deserialize(raw)?; let value = PlutusData::deserialize(raw)?; - table.insert(key.clone(), value); + plutus_map.add_value_move(key, value); total += 1; } Ok(()) })() .map_err(|e| e.annotate("PlutusMap"))?; - Ok(Self(table)) + Ok(plutus_map) } } diff --git a/rust/src/tests/plutus.rs b/rust/src/tests/plutus.rs index 98aa072a..4e0ae3dc 100644 --- a/rust/src/tests/plutus.rs +++ b/rust/src/tests/plutus.rs @@ -79,10 +79,12 @@ pub fn plutus_datum_from_json_basic() { .get(&PlutusData::new_integer(&BigInt::from_str("5").unwrap())) .unwrap(); let utf8_bytes = "some utf8 string".as_bytes(); - assert_eq!(map_5.as_bytes().unwrap(), utf8_bytes); + assert_eq!(map_5.get(0).unwrap().as_bytes().unwrap(), utf8_bytes); let map_deadbeef: PlutusList = map .get(&PlutusData::new_bytes(vec![222, 173, 190, 239])) .expect("DEADBEEF key not found") + .get(0) + .unwrap() .as_list() .expect("must be a map"); assert_eq!(map_deadbeef.len(), 2); @@ -90,6 +92,8 @@ pub fn plutus_datum_from_json_basic() { assert_eq!(inner_map.len(), 1); let reg_string = inner_map .get(&PlutusData::new_bytes("reg string".as_bytes().to_vec())) + .unwrap() + .get(0) .unwrap(); assert_eq!(reg_string.as_map().expect("reg string: {}").len(), 0); assert_eq!( @@ -105,6 +109,51 @@ pub fn plutus_datum_from_json_basic() { assert_eq!(datum, datum2); } +#[test] +pub fn plutus_datum_from_json_detailed_duplicated_keys() { + let json = "{\"list\": [ + {\"map\": [ + {\"k\": {\"bytes\": \"DEADBEEF\"}, \"v\": {\"int\": 42}}, + {\"k\": {\"bytes\": \"DEADBEEF\"}, \"v\": {\"int\": 43}}, + {\"k\": {\"map\" : [ + {\"k\": {\"int\": 9}, \"v\": {\"int\": -5}} + ]}, \"v\": {\"list\": []}} + ]} + ]}"; + let datum = encode_json_str_to_plutus_datum(json, PlutusDatumSchema::DetailedSchema).unwrap(); + + let list = datum.as_list().unwrap(); + assert_eq!(1, list.len()); + // map + let map = list.get(0).as_map().unwrap(); + assert_eq!(map.len(), 2); + let map_deadbeef = map + .get(&PlutusData::new_bytes(vec![222, 173, 190, 239])) + .unwrap(); + assert_eq!(map_deadbeef.len(), 2); + assert_eq!(map_deadbeef.get(0).unwrap().as_integer(), BigInt::from_str("42").ok()); + assert_eq!(map_deadbeef.get(1).unwrap().as_integer(), BigInt::from_str("43").ok()); + let mut long_key = PlutusMap::new(); + long_key.add_value( + &PlutusData::new_integer(&BigInt::from_str("9").unwrap()), + &PlutusData::new_integer(&BigInt::from_str("-5").unwrap()), + ); + let map_9_to_5 = map + .get(&PlutusData::new_map(&long_key)) + .unwrap() + .get(0) + .unwrap() + .as_list() + .unwrap(); + assert_eq!(map_9_to_5.len(), 0); + + // test round-trip via generated JSON + let json2 = decode_plutus_datum_to_json_str(&datum, PlutusDatumSchema::DetailedSchema).unwrap(); + let datum2 = + encode_json_str_to_plutus_datum(&json2, PlutusDatumSchema::DetailedSchema).unwrap(); + assert_eq!(datum, datum2); +} + #[test] pub fn plutus_datum_from_json_detailed() { let json = "{\"list\": [ @@ -130,15 +179,17 @@ pub fn plutus_datum_from_json_detailed() { let map_deadbeef = map .get(&PlutusData::new_bytes(vec![222, 173, 190, 239])) .unwrap(); - assert_eq!(map_deadbeef.as_integer(), BigInt::from_str("42").ok()); + assert_eq!(map_deadbeef.get(0).unwrap().as_integer(), BigInt::from_str("42").ok()); let mut long_key = PlutusMap::new(); - long_key.insert( + long_key.add_value( &PlutusData::new_integer(&BigInt::from_str("9").unwrap()), &PlutusData::new_integer(&BigInt::from_str("-5").unwrap()), ); let map_9_to_5 = map .get(&PlutusData::new_map(&long_key)) .unwrap() + .get(0) + .unwrap() .as_list() .unwrap(); assert_eq!(map_9_to_5.len(), 0); From f1169e6018be61c608eebfb988ba81778fd91328 Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 20 Jun 2024 20:08:05 +0700 Subject: [PATCH 280/349] add VersionedBlock struct --- rust/json-gen/src/main.rs | 1 + rust/src/lib.rs | 43 ++-------------- rust/src/protocol_types/mod.rs | 3 ++ rust/src/protocol_types/versioned_block.rs | 51 +++++++++++++++++++ .../witnesses/transaction_witnesses_sets.rs | 2 +- rust/src/serialization/mod.rs | 3 +- rust/src/serialization/versioned_block.rs | 24 +++++++++ rust/src/tests/serialization/general.rs | 42 ++++++++++----- 8 files changed, 114 insertions(+), 55 deletions(-) create mode 100644 rust/src/protocol_types/versioned_block.rs create mode 100644 rust/src/serialization/versioned_block.rs diff --git a/rust/json-gen/src/main.rs b/rust/json-gen/src/main.rs index a8dbe15d..408ff981 100644 --- a/rust/json-gen/src/main.rs +++ b/rust/json-gen/src/main.rs @@ -88,6 +88,7 @@ fn main() { gen_json_schema!(TransactionWitnessSets); gen_json_schema!(AuxiliaryDataSet); gen_json_schema!(Block); + gen_json_schema!(VersionedBlock); gen_json_schema!(Header); gen_json_schema!(OperationalCert); gen_json_schema!(HeaderBody); diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 10f6241f..92d8a88d 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1231,7 +1231,7 @@ impl ProtocolVersion { } #[wasm_bindgen] -#[derive(Clone, serde::Serialize, serde::Deserialize, JsonSchema)] +#[derive(Clone, Eq, Debug, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] pub struct TransactionBodies(pub(crate) Vec); impl_to_from!(TransactionBodies); @@ -1326,7 +1326,7 @@ impl JsonSchema for AuxiliaryDataSet { } #[wasm_bindgen] -#[derive(Clone, serde::Serialize, serde::Deserialize, JsonSchema)] +#[derive(Clone, Eq, Debug, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] pub struct Block { header: Header, transaction_bodies: TransactionBodies, @@ -1374,47 +1374,10 @@ impl Block { invalid_transactions: invalid_transactions, } } - - #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] - #[wasm_bindgen] - pub fn from_wrapped_bytes(data: Vec) -> Result { - Ok(block_from_wrapped_bytes(&data)?) - } - - // non-wasm exposed DeserializeError return - #[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))] - pub fn from_wrapped_bytes(data: Vec) -> Result { - block_from_wrapped_bytes(&data) - } -} - -fn block_from_wrapped_bytes(bytes: &[u8]) -> Result { - let mut raw = Deserializer::from(std::io::Cursor::new(bytes)); - let len = raw.array()?; - if !matches!(len, Len::Len(2)) { - return Err(DeserializeError::new( - "from_wrapped_bytes", - DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 2, - len, - "from_wrapped_bytes", - )), - )); - } - - raw.unsigned_integer()?; - let block = Block::deserialize(&mut raw)?; - if let Len::Indefinite = len { - if raw.special()? != CBORSpecial::Break { - return Err(DeserializeFailure::EndingBreakMissing.into()); - } - } - - Ok(block) } #[wasm_bindgen] -#[derive(Clone, serde::Serialize, serde::Deserialize, JsonSchema)] +#[derive(Clone, Eq, Debug, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] pub struct Header { header_body: HeaderBody, body_signature: KESSignature, diff --git a/rust/src/protocol_types/mod.rs b/rust/src/protocol_types/mod.rs index 39dc77ab..f4820a96 100644 --- a/rust/src/protocol_types/mod.rs +++ b/rust/src/protocol_types/mod.rs @@ -48,3 +48,6 @@ pub use native_scripts::*; mod numeric; pub use numeric::*; + +mod versioned_block; +pub use versioned_block::*; diff --git a/rust/src/protocol_types/versioned_block.rs b/rust/src/protocol_types/versioned_block.rs new file mode 100644 index 00000000..70a64661 --- /dev/null +++ b/rust/src/protocol_types/versioned_block.rs @@ -0,0 +1,51 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Eq, PartialEq, Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +pub enum BlockEra { + Byron, + Shelley, + Allegra, + Mary, + Alonzo, + Babbage, + Conway, + Unknown +} + +#[wasm_bindgen] +#[derive(Clone, Eq, Debug, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] +pub struct VersionedBlock { + pub(crate) era_code: u32, + pub(crate) block: Block, +} + +impl_to_from!(VersionedBlock); + +#[wasm_bindgen] +impl VersionedBlock { + pub fn new(block: Block, era_code: u32) -> VersionedBlock { + VersionedBlock { + block, + era_code, + } + } + + pub fn block(&self) -> Block { + self.block.clone() + } + + pub fn era(&self) -> BlockEra { + match self.era_code { + 0 => BlockEra::Byron, + 1 => BlockEra::Byron, + 2 => BlockEra::Shelley, + 3 => BlockEra::Allegra, + 4 => BlockEra::Mary, + 5 => BlockEra::Alonzo, + 6 => BlockEra::Babbage, + 7 => BlockEra::Conway, + _ => BlockEra::Unknown, + } + } +} diff --git a/rust/src/protocol_types/witnesses/transaction_witnesses_sets.rs b/rust/src/protocol_types/witnesses/transaction_witnesses_sets.rs index f2d933fa..64ffd62b 100644 --- a/rust/src/protocol_types/witnesses/transaction_witnesses_sets.rs +++ b/rust/src/protocol_types/witnesses/transaction_witnesses_sets.rs @@ -1,7 +1,7 @@ use crate::*; #[wasm_bindgen] -#[derive(Clone, serde::Serialize, serde::Deserialize, JsonSchema)] +#[derive(Clone, Eq, Debug, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] pub struct TransactionWitnessSets(pub(crate) Vec); impl_to_from!(TransactionWitnessSets); diff --git a/rust/src/serialization/mod.rs b/rust/src/serialization/mod.rs index cfcbf939..02ad09c6 100644 --- a/rust/src/serialization/mod.rs +++ b/rust/src/serialization/mod.rs @@ -24,4 +24,5 @@ mod crypto; mod plutus; mod native_script; mod native_scripts; -mod numeric; \ No newline at end of file +mod numeric; +mod versioned_block; \ No newline at end of file diff --git a/rust/src/serialization/versioned_block.rs b/rust/src/serialization/versioned_block.rs new file mode 100644 index 00000000..f9ba8890 --- /dev/null +++ b/rust/src/serialization/versioned_block.rs @@ -0,0 +1,24 @@ +use crate::serialization::utils::{check_len, check_len_indefinite}; +use crate::*; + +impl Serialize for VersionedBlock { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(Len::Len(2))?; + self.era_code.serialize(serializer)?; + self.block.serialize(serializer) + } +} + +impl Deserialize for VersionedBlock { + fn deserialize(raw: &mut Deserializer) -> Result { + let len = raw.array()?; + check_len(len, 2, "VersionedBlock")?; + let era_code = u32::deserialize(raw)?; + let block = Block::deserialize(raw)?; + check_len_indefinite(raw, len)?; + Ok(VersionedBlock { era_code, block }) + } +} diff --git a/rust/src/tests/serialization/general.rs b/rust/src/tests/serialization/general.rs index c6d7c0cf..63303523 100644 --- a/rust/src/tests/serialization/general.rs +++ b/rust/src/tests/serialization/general.rs @@ -1,11 +1,4 @@ -use crate::{ - Address, BigInt, BigNum, Block, BlockHash, CborContainerType, Coin, Credential, - DataHash, ExUnits, HeaderBody, HeaderLeaderCertEnum, Int, KESVKey, MIRPot, - MIRToStakeCredentials, MoveInstantaneousReward, NativeScript, OperationalCert, PlutusData, - PlutusList, PlutusScript, PlutusScripts, ProtocolVersion, Redeemer, RedeemerTag, Redeemers, - ScriptHash, ScriptRef, TimelockStart, TransactionBody, TransactionInputs, TransactionOutput, - TransactionOutputs, TransactionWitnessSet, VRFCert, VRFVKey, Value, Vkeywitness, Vkeywitnesses, -}; +use crate::{Address, BigInt, BigNum, Block, BlockHash, CborContainerType, Coin, Credential, DataHash, ExUnits, HeaderBody, HeaderLeaderCertEnum, Int, KESVKey, MIRPot, MIRToStakeCredentials, MoveInstantaneousReward, NativeScript, OperationalCert, PlutusData, PlutusList, PlutusScript, PlutusScripts, ProtocolVersion, Redeemer, RedeemerTag, Redeemers, ScriptHash, ScriptRef, TimelockStart, TransactionBody, TransactionInputs, TransactionOutput, TransactionOutputs, TransactionWitnessSet, VRFCert, VRFVKey, Value, Vkeywitness, Vkeywitnesses, VersionedBlock, BlockEra}; use crate::fakes::{ fake_base_address, fake_bytes_32, fake_data_hash, fake_signature, fake_tx_input, @@ -636,11 +629,34 @@ fn tx_output_ser_type() { } #[test] -fn oura_wrapped_block_test() { - let hex ="820785828a1a00101e2c1a0143a1b35820cee15d6daecaeaf320a4ddb1f7c437846f798e4a9cd08d12fb7821b175c980115820e3c87f196ce9fc40a8d929f3365e247f8f71e1981bffaa7cbdb0aa3a83dc790d582054a580ddf99f67818e0312374cef1f7dcdd59450930898d4d2d10e606b963e49825840ca5d1f988222919982b6a20f4f54ce59626fece7d7c607487762129d5196c731bcd11dfefee94ce5a60a733478970631d41bfc0620769fa7b66ebc16c8a89e5c58502855f21ba12fb101d175c376e19496e464bf37c92ec21395e5bffb35e1ae8f433f2139de166161f2b2b26afe656d3d170acfd11a535a80fca6325479d2262e208b0a4b98a01f4845c45a58fb84cb58011952de5820f2e4c6554da5b773c3f7889944fdb5b1791f8552dcafe2916041a531860e912284582039b66a10f6b78c541ea5ed6ecec4c6dd385b869026ec16c4e48414cb39cac38b0018a258409ccd6cf71a5c337f71a41904c0ea0a889a2321c94374c3a8402d8a7dd25b222abe6cb325c6b39bd63bc99fa84c094fdac2523b72f1a22081903dd047be9be9078209005901c006b35937aba451d4738486ea3ba5644d9306651f09b2012de8acc5136771fc725164ad669dd716f2726dfe138137d09feddf9450b3c51a601577bff35d0d2202c887a260855dd8310fc9365f56a4757ea7d81103d409ea0a8ad51c6ae52fc7fcf4d3d456384b7566b70a2b7bd4e21010a1ad5df12bf5d332e82c1a4a5cca39740252e0ea163f206cacf193e59ebbd0e20d621fa9913c60efe1c035d8ebaa354fbe45768339d53a4e8e04fdea79d00b869a973cfa3eeba2e2668b1dee5fcd7d13762dceb4da804fd749e5fa977ead0003a9739837aa68b80bc5a32ee015f667574a7fbe03b4bf5b027c945fa4497c01efb4ec51f3da2fb2dda33ea7dc1dedcfd2ea2c0a4da5a1c553d033033f4986e2ef5c09bbe326a25e5082c1eec406aeec8105869a9d46a83689a2e026e6e31d4037e700ffeb2920bcab88d1a400976881d17cd84582521482db0be460fb43de88e40a4ee24745ac92ab8b40329bde1d855404478c9f59b05e6322f3640ad6f40d7a771fc6d58e94f8fd0006d54272e36a30034b14327c2e6ffb92ead2f8a4165a3e4a1c44de677829e8e797547b3c0bac4b5ea89cb86c01d5b1e67aee3ba36b8cf9617484db2e4d1bfc37fed1fabb73ce3c9fa600d901028182582088c310befd2e8c9b33b340a56f4ea8141689c16eddef5d9c606055ca35897bd600018182581d6052e63f22c5107ed776b70f7b92248b02552fd08f3e747bc745099441821b00000001f09cac72a1581c34250edd1e9836f5378702fbf9416b709bc140e04f668cc355208518a1494154414441636f696e1916d6021a00030739031a0145283409a1581c34250edd1e9836f5378702fbf9416b709bc140e04f668cc355208518a1494154414441636f696e01075820e2ea39e82586fa40304df3c2cfc753c6ba8aca62e780f01a0519c34c6d7c25f5a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe185b0181a2005839007ce8986f5f3fb526a6d35d32edac0b6c8624daab6928df1964459c2723bcf2892e8182a68e3aac6f9f42ed3317d115ebad12a17232681175011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe185c0181a200583900f7fa5ddf2c3c46ed4d913812d38dd43d585adfa884938adaa7a075dd1bf1e138f2f8beabc963c94cc28ee8ed4b41744601f2edaf50b21efd011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe185d0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18600181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18620181a200583900189f009d9536b1f52f0629bea3323f48df0eacdff68726f1a32edc49db89995ed3aa88dcfb43790e2e51761fcba7e8594bcc67684f52d524011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18630181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820a944bb37a59451f9a47d5c8888a8a1145527ffb5d45a17c1df40926a42ad08330001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a400818258206a7e3a926eafa74f72c0d6a721dfdee7a7202b1fac4eee12d8c6dd030217890b07018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001eeb2890a021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18640181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820a439638a9f8e0f52e153126e8b794b7514f3a0921b08b611f3866a1fc75b7a560001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4010181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4030181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4020181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4040181a2005839002b11f0e68a65cd6a243f1a5ec9d597ba972675a00bd3172a7ddc0293b1d312a60b3824d1820dec5ec769c4af7d7598387c16ca5ba6259f46011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4080181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a400818258203298fb7878ab004c1a4b369eae7fc89abca6342f06557cebf6c89f2d8c21aa9900018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001b3152865021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a40a0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a40d0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a40f0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a40081825820dcdbb7a98286f5d48673c95b05f441bc40731b1e4c3429d192f0c6b7fc3749d100018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000002186e835b021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4130181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a300818258207e4fddb60c2034bff37bb7069f9318735fcf4de03e01e9f92251c96dc59318750001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a40081825820705ab68071f9af1d314e74a053e39a52f3fdf96f9a1280dab30d45f04c05436d07018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001eeb2890a021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a400818258206fe0c3eae23f779b0694747ed28612f47271b45e84bb3d23c11c1ef2e90fa12100018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001dcd122b6021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4150181a200583900e698ee1c7d4361c6faf62716dca0d435eafd0b25e369a5d68455beaa0f5c16e3e747e7c5a9eb3ff189c0e330683665de9326d2ffe35d0631011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4160181a2005839005bed6070c549f1560cb89361564cd2be7b36536e8da868a218d514e5fd2e3e48dbc0278cc58e47ed50a1ba90cee61ab22c8f4a639c913d4b011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418180181a200583900ab3cd541317d83d072bcc38e1294166dea5d97ce453424b84c547cfc101c5bfa799985a6e96adbb5859e90cbe4a0e4edcbef408a3622558b011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4181a0181a2005839003b3ff2a2d98519fcf53c7abb15b6c4dfe76209c52e4c2065b33b97bc465f9e3a6c6c3a8eac01d39f519b9bf3bc031480936156b7cb2e45c8011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4181d0181a20058390050fc315c9c141b4da62b10525cf5049e8ab1bb8bd96903a6d87c5272bc616bee900ed3135eb065a11faf2100670f0182ae86827df52dba96011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4181c0181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418200181a2005839005deef04c1b44c606775db03444beae0f10c75f437c131628d264b17c439dc3dbc39b8bb91832384d44263001591fd806df73b413da861fd3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418210181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418220181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418230181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418270181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418280181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418290181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4182d0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418330181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418340181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418350181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418360181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418370181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4183a0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4183c0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418460181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418470181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418490181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4184a0181a200583900189f009d9536b1f52f0629bea3323f48df0eacdff68726f1a32edc49db89995ed3aa88dcfb43790e2e51761fcba7e8594bcc67684f52d524011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418520181a2005839005c85eb9c0aa544a6bb5d1577c7a588c39caca885c8a3a9fceb0933a2cd1a02667d16df1e109350555c325023dbfa31fd9a4a8b99ff904d96011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418530181a20058390030a33756d8cbf4d18ce8c9995feca1ea1fc70093943c17bd96d65fed0aed6caa1cfe93f03f6ef1d9701df8024494d0b3b8a53a1ee37c5ab2011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418540181a2005839001da17fce0b5ae3e7feae117785eb78c77b6272be34a3d381a2722154d29c294b138005ca78de7b329ed6d2763a74a3fa1710a403e18fcb4a011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418560181a2005839001da17fce0b5ae3e7feae117785eb78c77b6272be34a3d381a2722154d29c294b138005ca78de7b329ed6d2763a74a3fa1710a403e18fcb4a011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418570181a20058390098bebc68cf6f12a7aca6531cef75d83c1b6e323485146195ffdd727dd99bbe7f44fd382de2ca6d9e5e9cc26f940decdb1b12b1a98e343274011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4185a0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4185c0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418610181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418620181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564050181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564070181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d00045640a0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d00045640b0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564181a0181a2005839005746c1b032f826b5e5256357a713a7ca63988fe2ff862e0396993b97ef0cbd5199d0e460725b3e79d371deb42110d40b778d3bf162777d4c011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564181b0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564181e0181a20058390020de866f290f45141315081d903f3eb3c06f3735e2a5b70f6a138462ada99823bc02291029853dc5338bc6e62b0540dbea54d9384f372639011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418200181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418210181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418230181a200583900057fd21bf903c585ea95dd927dee373b4cc1febc61874c48571dfb88a0a307af2a3e6a55a238fe323f9e54be10c54a8a8b25939a4f9ab35a011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418240181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582043c59e533d0934a6878a81403ec71a2225bb22d0764471cac8b5545120b475760001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418250181a2005839008f221a3021b0c09c57336733b0411d9d664e5d5e259096033a9d4bbecbce4335fa28195472386e53f0c3ab74d5cd254797d1100e4b1a33b8011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418290181a200583900d804dcdd0b0ec6ed0d8d2cd210a03b14f87c6849024930a8d6c91cf551a6a756817f0a3e1a1410730acf27202e7a9b63de26087e5cf466a5011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182b0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582072af166d0cd8883c9abb1189ae93acb1fce482ca57cad9b14711bca9627b98d80001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182d0181a2005839001c4595c4f3180180c9e822f1ac0f2955dd329eeeb94752a84281ff5295558528c6e1f7f2e16d94b74d227b9fd709edd2aeb0ab1556db75fc011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182e0181a200583900c008dd489b67e0a774fe18d79ee8d1e280264933d3b31ba44cb37755dca94fb45aa2192ab26eff8409ea010fa2d4761efa92437e0d5b6b60011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182f0181a200581d60fc38cce3448bf3d2790ca85d6b09026f7c86f21095c31f9925cf49a0011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418300181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418340181a20058390023a6fcbc8affc61518cff034c013aecf083dc64fe673ffc95cc9fd9e1fad7e0b1d0dd8820703a4f59c2488d148193a48d8fdc23a6dca8137011b00000002540be400021a00030d40ff9fa200d90102828258201287e9ce9e00a603d250b557146aa0581fc4edf277a244ce39d3b2f2ced5072f5840ae4cc1168265e2f60fec9ca9b644eaa42a77e65a39176e04aef29b01e25653a307d39ba61761f8d1ca44696e1d6bdf7a0679413ea3c448f76268e6eb02074102825820742d8af3543349b5b18f3cba28f23b2d6e465b9c136c42e1fae6b2390f5654275840112c95c93013e63fa73ee6a645fd522808d4dee019626e395a8042755c15fb1824e1503c17ea843a838809f55822366b05bce2e378d0b955e66d625c8e9acf0001d90102818200581c45d70e54f3b5e9c5a2b0cd417028197bd6f5fa5378c2f5eba896678da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584005383334e98e9263b93ffeb3e5908dbd5657caa67d32f9964d7f91dbda76fff164cbeabb981beef470d0d3e1724b85847e6fbc1c039084a817110eabf9d29e08a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258406151f0d0cae4ef0ace62dc03300dcee276765c1b493ac61f770d0633f0f71fe0d642ef29b593c511034a847dd569c56a0278e063c46d6d060abad4e6baf4b705a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840cf518f30d291871a0277e367534557205cc015d3a0d78070e1aee298aeaae3e81d70b42c464a63fa741b5300b48c1699dfc39fdf07f96b8eb240c7d6d3267805a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584056185de4c1d012d322e7e82ae98f24887ed7264f262db53f019e5900b9110a439e5a462a75be036f9f04b0ddcf09decb0894c7b6b9ff17ab4cae8184072d690fa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840ab78c606155b6aacbcf6692a18d97dd8773b4ae4c96684e4abb9cc59233023f67650ef7259069deddb65ba770ac3a1401d169ce33ec9483b8ebb9e83472e2c06a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840e21574b02002efcfe81382326aa98a0a971327ad4049690a04985400fcb14db7adc8149a0ce4dbfb5afa0d240ed9da23f15c1020d2826f50fc579a10a3662d0da10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840e64e3c19644edb6e788112ac75b4426ef94d535f1ffd9a34e86745777feaf083dc8e847a62634fef320a08b566c24ea26e8dc9e7b49fc456554215cedc0d3508a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840f49fd8eeaa366873aeb2530b2bbcbf7c5970866162ae7250c4b913e19062de1396ed70d1e32a4605071bac11c2cde3fec1dc5b37044cbea073668fe5c478400ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840f0ddd023e0dbda32d296b359db809b0088246e512fd34c7c0cc4b5ae974361873e02330e955eaaf97117525bcb3cd014bb70810f8d0d62a28c3242c86d8c3a08a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840615ee0444f039f02b26791872d6cd5562728cdc6dad02acc71475567b09f3d4b4655c601bf816ef6d11b2f3f81eeb6db09d800bf1bf4e2daf29493338c232901a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d62bfd428359f4cd04950cc73f574f0ec1c613284fdff8028ed3d876b18b69335beee9792410c6dbdc1b196b4703f250fbaeb66569869ae97d7ee843b9053405a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d813a836cc44c70647b2e7941fb72a4f720f16aca17e155a6c6a6f9bf175b1e49a3beff6edcfb0c442cc24790a12ee0b1d499a32fdbfc0a850f4846708ea340da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840aae6ac20cd419eaa7f3a95144f9ccdb46401a0db295d544e920a54b5c24fb63197fde03f12174800c3cf5318a73d92ebc53c2ba97803766892add32fd9feb400a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584071d223fd255df1e912a9c0a8230ee9f0ac95d0aa325cd31e50701ac355dfb5f3fbb27983b372c1410156eeba9163aa0f8a9787dab8c44e7afd4e2d07459a4708a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840b7f821c0ff66fcbbe7c61f43725aa2234297d6765e002d0130301cba13465fe89f59a596549725542445c76d17cedc9c9cfea8b8862d41405646d725dabc7d08a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e4584045830e5de108b9353b0c4c561af296e79eddb26b8ccfb18c5bd9fac1baf8d477691229c0bb9ea212ab56d9ae76c92de6ae50686fc0619510b8c35fb69c6b4402a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258400635ac784fe71d2f7927114edfc709dcb56013617df4edb9b6b770b067e7709e8abfd4cdcdd61512894fcf02f16e1d72bfe60fbfb86b815631d791bab132b909a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584032d67fe72feaf2175455815bbb624ee1b93f5efce905280158db94bbb2b5371d9eaff1bed6eddf9eafe8ff64b55f1d7213294bdb459e0b00c437edbcabf4cf07a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258404533de52e9e3f51e39951c9e197f6900081e98f38f3af5c4a7fe9219f8c311eaa43942b7a290ecbbbdd0bf4ef4ef1d11c39e6de4083c86892a6026c27bcf2509a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840d46541920ce2c31ffaa00cb20e8f5f00f48b6b8aa5cda67d22ea4bf12fd318461a0d8c25ee04cd7446e18f0de59b0fd4f6631e29bc8207073f2404793ae5f108a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584041bcd52ae44a3ffaa1abe1cab6c8b21f8010e2f1aee1d8651b9f6e94aabf5b2dbcedb45dd154b78dce1c5b9679956dd25153a0d945d3eb83c1de3b713e721008a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840027da3169c9c1fb9a67104061698bb0dadb2f58b660af4b461e7353fab1545a3d03157e077a388ec8556176239df3241255feb1f13b5e406bf7c3ad3af7d4202a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e458401ae63dc54e511965f7010971de7fb99585afe492cb8084b395ee01555c1e5657ab08a24be0f70d4e9cd1bde2a6ae31815c5f64025c0415afe2d503b2cb5b3e0ca10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840d2211679ca8e9cc5de71b21bac2b58fd355f5cbd2b42ff31ec37af77b776fb77c64fa76a830f240c29a4b95ae6bff9c58fc6bc2b3d18b57a2af11710ae6e3006a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584084bb7bf64ecea446d6beca88bfa2c7de71d8899e96006920c4c18e52f042aa71e1d27e60bdb6d9d6b1aa2e3330f59ee95b2c001909ff8994ea1fe4e5cd7a760aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840c6f3d6194a2fdb2a50417f80dd020adf866c91a102f22eb6bc66f5131292a1a42e9a3550e18e06cb17bd153c08f55a6cce3a1c82052ec9197495900f3ca4f407a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401a28cac7e80a657563e1433459f369bb0cb05e7e3ead78378dfc2ad15baa344e76e1ac0ca631c67848e81896fd6838b3821961928911635ca069f12c05772a08a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d201ce4ca5572db792d1563ef3614f2e2b27072e4751327f4a8f75201183a189ac57cdd9399474850e87031c7545c896ebab3983434bb6005690b9ad8fd9d50aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258403f45e44aa7457c714599f0100702ec265e91493e30c57ba4f1f74d912858bae8fb71fdf2faddf865c816cb0218eda0db17b707c8f429290f1a1c02b6a4450a0ea100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840e16b1d8f5992fda268c9d7e5c0ab6c5d38b8abaa6b92ccae5b0d2f3079d098ab67ba9a15b27807746f3c7695091ec5bb74ba8772baae14d2786eb8a512d70201a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840628a5491c5d0b4e0202b7aae87a343afd642345b823252355f6d392d8398d2174c141622e3de167b4f82c3cb8b4e8105b341851005d2ec0c1e35c354006a910ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258408ad2ee919f520a903764e0322800f7c086f870374f063d2e62ad1dfbf54e71305d90371abe3a196132e123b9248281f2d676fb29442f80249f644ce1185dfc03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d53bf84fe8712171151bb6d5f988d76428292639737d817986b46d629aea6eac2a90675cbf0347ec004ce23f9ca0b2dcff5c6d1be91ab478634de8ba8ab96102a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258404702623a2a94b9efbc03dc7d506c4bd70c1e0fea8b21f3b76c592883f0c364ffc12215e59f9ea4d2eed2e786376e6128650b4c9c3f6ad9419f070fb458efa10ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584072bb89ee81a7bcc4a866ae498d3ca076d5d5a885547c7f5899b8b59b3077310f58df420e470bf36d4ed5beaaf30eb361f04ed578cdbd0ef04f7cb573f0c0770ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840e112bb46921840820f4d5b40ec45699bc1b818ca8fe77fcc222a6fa1edb2425487f32e2039e2cf6077ce1e8e2e0b0d0581c64fb866c1c183344af131ccb9390ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840039329e261d8386f81a28f5ef5062196a46b5d4389b06bde97e662f69e37812c3ee75352f392121f58e76e5c1e1649656632b01ea46f932ccedcee102d625001a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840c1dab5e2482101ad1bd04f4018425c7133171aaf1274573ed35305f4e37bddadb3636f0aa098d2c0b5f615e8eb629bb94afac5d4c4c0743dba16a847d898b905a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840abb898b3e1ae3c4c9d068a4517b83a070d4037f979b6365ea5eb368e7d43b3fd2152fb93a462fdc553f973d90ab136332057fb66ea529d4fbc53e7f082b6fe03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258404a09ccfd9c09c6a453f46c721d280065081d89aa4b84fc809d75db1b923e78963bcbf36d64786d8c09c527e90da744e83116617b2e18d9145bac6cf66f876c08a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258408df2408adbd8b4c990a913b9ed2455c9de72d561ddb8f3ec0da5d1513f417a2fcee9ea9ace30cb840d37950c41455bd3655d12d534b70a6eac7034950f821108a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840534b54cc145722e3f7a62935d84c025e17e31c4b08d3f3fb16bb7673d37e9afb07fbdb5ffce5aeef743376bac161973e565e1c12db97bcd879cd7e9030c2a00ea100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840664fd5d8bc5d93509d02104f39e7a22c6cd894f49935cac9e662a9202b9a64baa9f55cd8aa07d3d1e095e9b974c59c0a8c50d14b0d077d70e236ad5cf52ac104a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840469cdadb48349224303d14980cab5c2ae5dacd0f6e36714d8dcb9ca85fa4eb688bd7b1334e30f8718178f7f36d8c5b204e0f9cdce5f88762fc2cbe2cb28c1d03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840f330820de229a476e1b3f84dfcf9ad98264070212e6e2d61d8b05afb1e12a1426cfd7cb0b284db237d5882cecd6e8f1fe2cf9ddc06783242812178bcb053a105a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584066b89001a28583bed59dbd07d359333207eb74d39ee092c0bf1da4351da64d38c9938a3682bb52a4253dc76074767b4cc2bc1eb2a31bbe6be3c45a5c52cbdf04a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840f365b299297ade5117d72156050cb81a76ba0b859cb46d0f2326c4071110440108b20390f878ba082d41217b2a8fd5f1435b9ba48d176ad5dcb6faff54976b0da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258407fb0b1f28d6ca64a29c6c7a51a2ab3436809b5038c06b8204104e3b98afa915246f742e2f1bd569f5132d2bbdcaeae68215a0b0f17f6367ce4eea37ed951ec01a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258406e6d2263c440486fc1b3c2aa930e519f20b70f70c28cb532d031f63cefc55c56f4647b10dd6390aa0d0f2ba75bf6cbe3ce2fc6d928dc4db74388f1e5e3057b0ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840dbb299923c24a70ae10dc637d862b750b3e6548e64c590674d2ceb87b7535199ea8dfd024694d26ae1dbbca683b1a4ba90af7d1680a9b8e4819a2ee6229e2408a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258405b2397d031c48f56b43416daea99dd3d8bd1733cb83c2a688dbe8b5dd9bfe64d596280d71973d7d540e929262dafd79b14954b855635fe845642090241003503a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840482c9089f2d60eb069432bf7f7213178a6fe3d52d37a4fa5aec677875bccdac64de7a45c6eb0bd4996414412b12d3e887a1b391e775ef56c47d53f9c944d020ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401972d18c1e9c62837121efafddc2ec778a3a8f9ec5f534c9922778905d8f809609d6c92e427852d8b5f822ad590fdeacf3877c8056f0768b44b025a2b79e7704a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258409b7141b69a493bc4d597a645ed488325492772ad4c3cd5c5c7805a5d951a4b6ed960ea27428d1add867fe7c209f4e65000bdfa878bd7a4357b223e9c55af450da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258407ac2d7823887de83bca86216e424ccb63fe9f4fa1f106bffc6afa388e91845c97177c410f1a8ca5ecd9f2701c42f5f9dd2faeb0ecf2163a37521badc8a6c1b03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840c49b6714ccbbdebebb9461a2efb39b9ac5e00a389aadfb2a1b4fe384733610c45e1f03825f65e182988da97659a71e378d49d17fb93d76b80d579b7d49399b06a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840b53ea3508cbd7da47fef05e98c0b31b13ec33de4596ba4061a8e04d91b1015c49f328da58084a6f573d93cdb7aa0972a1a1936a69ee7362adf65df3eae4e2400a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840b1c6b15b311423aa83dfaebe118d1a2a3ff006399f2a63fa82f0d0e0c12bc2b844ec78f5bc8baeef588d15b2237db48cbfa48361a6d630052c9b68e62e035601a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840bb544721cd95655497375390da19fbd87b3c63a4edf333688e2fee7935e96b6572f84b81d80fee5239062be6d3c6a75a5f0c50696d3c6663d26cecdfd8fdc808a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840a7018dfacec705459856bc706b7d05d04c56867fb64dfd0cf97fa980e881cc609e91cf6df204fb6906f860e5cf390e0290d302b6231664aad8c2b4cb30090609a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258403ddf27cce21fbf1a361233d2bcff92ecc9d3cce64c3d8186495e3509b843a0a326f528be8241b8557bf3cdac9c304fcf0fa8fd2a8e389d6acf9fc62b5626d705a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584013bd40ae7383feb674c2cd3357122aec3f6efe17b9b4f25c47cd3dfec194d0c4f20a52cc30fb92245c1a20a962772808f3dc6ee51261c86af16879a1fed2210ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840a1cf100aff45ee45c0f868214187640c8c29cb005c7aab7100ff86338d78f972733a611b4e0dae436fe9e1493d6ece69c35ada3cc6506e730ea1bae277468108a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840667d6d2987788454c41f2e86867fe98e1fd48aa789fbf9cf2208f927a8f9941d0384ebf3e3e45ee80c49934aad9b6ccaa13179b69f35b9acd21b55f56caff80da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401cd5c48fa46d8f0fb07c7737b7719d1fba5729478be3eef3e2e19942c4d6d54b01a569eb34d4f4be84a2f6961832ec17bade0511cbc01f5db5749a09bb4d8808a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258403bb5ddd91b5f5d7366b41330bf5bbbf7cf7d703bd50376ac21b07c6da696562266361678c06247a57111c63bc1fe58463a8c125e0d117bdf05cd4fe57bb8b90aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840397067045ffe0cf7126a5f73f228e1bc8721c617ebb7c41c1bc2f7b6c8cc50bf2370bc1ee679bcb0581e11da1e186504f2e3f3322fddf40a1863067ffc5e2903a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840831f5ea5dd354f5a522e044b53aa1966d036871d5a3b7d2323e404996907a33aff5aabb9db22301064033045cbf14c91d29de84b8fbbb75683ff1cb51fd0920aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401e8cc65db39cb5e9d54dac50cda84c55fd2f989f667a11dc46521768ac2f46a27a70173a92e849ee621ebe3025d87088528e7450b8312d678b6249f5a124f70fa10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840f4835bbcf5459db0826e27ea95d3ac31f7bea56c0253716212ef421995c7546a963ac89dc6cffad75692a149372cbdeaa19a9dcd171ac423711e8d71c495d703a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258408039411659145a9fb3863b2ae2f3890009bf004332f58daa6662368a7378d215cc7f40569284d5b86c5a7be210cdcb5551633762b5a7d3f8ad2095a220fec609a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584002c9ec1d95d0464eba5f4a656d72b55a92a80078e83f2f47682729af0fc782a68f3f31db7c64018ae8fbd36c5ac72d5573357a7578359056b9d3f9a29467d80ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258406f176d0fdb8768aad902c8fc115eb797719ef62a93938d7f09bbb213a88d61294143ec1d508a2a450f0e16ab3e2ffb7e0ed4cd7f75b3f2ff9f70cfaa77764506a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840f4262eeb9183eec1e896b9be61984ed9d4192b38825ba1b560ea23fe6e3224d3c94f4cc64174c1d9166e665e1a1ff8f0c84024bb8b9068b853fe4ce683d96906a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840df64e327056e335f484582fa0e4188e62620968e955431fc3576da2c1935b15ec605bb5d738f5000dcdc022646f9545d6932c2c79611dccab116295ca03c2b04a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840132cce5cea5d8bf7e9b802e4477eff041ebe1c12a8b8658a42ae91727cbf4f39b0d23831c70923a68ad7a023092bcecb61ac6253fdd17be00cecc37a71301300a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840842ecaf1b907cb34799d78d6f35eb349a986559a396840aeba5f6e8dc7e4172c16bddcb1f926a21175531478773046e9484aeb4ca83c1cbaf25f5a4813afdd0ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840a417cdf9e02755e53d6061ce0c93cacb7de24ce33e3fda9ac3a85414a7bf62676446822875972867d5647e46c22e21099e5dd8e4114949b30b86146b0dba1b05a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401f2e86831349fa458c3e2403e2caacbf046fae3c513575e8ce2d34037d34337f7e58cc98cadf034e8bce930335285220624945b316fe6af71e8ef0d12ef05001ffa100d90103a100a11902a2a1636d73678f78264175746f2d4c6f6f702d5472616e73616374696f6e202336313138303020627920415441444160783c4c6976652045706f6368203234352c207765206861766520303132682032386d20323773206c65667420756e74696c20746865206e657874206f6e6578374974277320446f6e6e657273746167202d20313520466562727561722032303234202d2031333a30313a333320696e20417573747269616060607820412072616e646f6d205a656e2d51756f746520666f7220796f753a20f09f998f783b4265206b696e642c20666f722065766572796f6e6520796f75206d656574206973206669676874696e6720612068617264657220626174746c652e68202d20506c61746f6078374e6f64652d5265766973696f6e3a203462623230343864623737643632336565366533363738363138633264386236633436373633333360782953616e63686f4e657420697320617765736f6d652c206861766520736f6d652066756e2120f09f988d7819204265737420726567617264732c204d617274696e203a2d2980"; - let bytes = hex::decode(hex).unwrap(); - let block = Block::from_wrapped_bytes(bytes); - assert!(block.is_ok()); +fn versioned_block_deser_test() { + let versioned_block_hex ="820785828a1a00101e2c1a0143a1b35820cee15d6daecaeaf320a4ddb1f7c437846f798e4a9cd08d12fb7821b175c980115820e3c87f196ce9fc40a8d929f3365e247f8f71e1981bffaa7cbdb0aa3a83dc790d582054a580ddf99f67818e0312374cef1f7dcdd59450930898d4d2d10e606b963e49825840ca5d1f988222919982b6a20f4f54ce59626fece7d7c607487762129d5196c731bcd11dfefee94ce5a60a733478970631d41bfc0620769fa7b66ebc16c8a89e5c58502855f21ba12fb101d175c376e19496e464bf37c92ec21395e5bffb35e1ae8f433f2139de166161f2b2b26afe656d3d170acfd11a535a80fca6325479d2262e208b0a4b98a01f4845c45a58fb84cb58011952de5820f2e4c6554da5b773c3f7889944fdb5b1791f8552dcafe2916041a531860e912284582039b66a10f6b78c541ea5ed6ecec4c6dd385b869026ec16c4e48414cb39cac38b0018a258409ccd6cf71a5c337f71a41904c0ea0a889a2321c94374c3a8402d8a7dd25b222abe6cb325c6b39bd63bc99fa84c094fdac2523b72f1a22081903dd047be9be9078209005901c006b35937aba451d4738486ea3ba5644d9306651f09b2012de8acc5136771fc725164ad669dd716f2726dfe138137d09feddf9450b3c51a601577bff35d0d2202c887a260855dd8310fc9365f56a4757ea7d81103d409ea0a8ad51c6ae52fc7fcf4d3d456384b7566b70a2b7bd4e21010a1ad5df12bf5d332e82c1a4a5cca39740252e0ea163f206cacf193e59ebbd0e20d621fa9913c60efe1c035d8ebaa354fbe45768339d53a4e8e04fdea79d00b869a973cfa3eeba2e2668b1dee5fcd7d13762dceb4da804fd749e5fa977ead0003a9739837aa68b80bc5a32ee015f667574a7fbe03b4bf5b027c945fa4497c01efb4ec51f3da2fb2dda33ea7dc1dedcfd2ea2c0a4da5a1c553d033033f4986e2ef5c09bbe326a25e5082c1eec406aeec8105869a9d46a83689a2e026e6e31d4037e700ffeb2920bcab88d1a400976881d17cd84582521482db0be460fb43de88e40a4ee24745ac92ab8b40329bde1d855404478c9f59b05e6322f3640ad6f40d7a771fc6d58e94f8fd0006d54272e36a30034b14327c2e6ffb92ead2f8a4165a3e4a1c44de677829e8e797547b3c0bac4b5ea89cb86c01d5b1e67aee3ba36b8cf9617484db2e4d1bfc37fed1fabb73ce3c9fa600d901028182582088c310befd2e8c9b33b340a56f4ea8141689c16eddef5d9c606055ca35897bd600018182581d6052e63f22c5107ed776b70f7b92248b02552fd08f3e747bc745099441821b00000001f09cac72a1581c34250edd1e9836f5378702fbf9416b709bc140e04f668cc355208518a1494154414441636f696e1916d6021a00030739031a0145283409a1581c34250edd1e9836f5378702fbf9416b709bc140e04f668cc355208518a1494154414441636f696e01075820e2ea39e82586fa40304df3c2cfc753c6ba8aca62e780f01a0519c34c6d7c25f5a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe185b0181a2005839007ce8986f5f3fb526a6d35d32edac0b6c8624daab6928df1964459c2723bcf2892e8182a68e3aac6f9f42ed3317d115ebad12a17232681175011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe185c0181a200583900f7fa5ddf2c3c46ed4d913812d38dd43d585adfa884938adaa7a075dd1bf1e138f2f8beabc963c94cc28ee8ed4b41744601f2edaf50b21efd011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe185d0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18600181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18620181a200583900189f009d9536b1f52f0629bea3323f48df0eacdff68726f1a32edc49db89995ed3aa88dcfb43790e2e51761fcba7e8594bcc67684f52d524011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18630181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820a944bb37a59451f9a47d5c8888a8a1145527ffb5d45a17c1df40926a42ad08330001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a400818258206a7e3a926eafa74f72c0d6a721dfdee7a7202b1fac4eee12d8c6dd030217890b07018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001eeb2890a021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18640181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820a439638a9f8e0f52e153126e8b794b7514f3a0921b08b611f3866a1fc75b7a560001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4010181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4030181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4020181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4040181a2005839002b11f0e68a65cd6a243f1a5ec9d597ba972675a00bd3172a7ddc0293b1d312a60b3824d1820dec5ec769c4af7d7598387c16ca5ba6259f46011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4080181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a400818258203298fb7878ab004c1a4b369eae7fc89abca6342f06557cebf6c89f2d8c21aa9900018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001b3152865021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a40a0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a40d0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a40f0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a40081825820dcdbb7a98286f5d48673c95b05f441bc40731b1e4c3429d192f0c6b7fc3749d100018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000002186e835b021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4130181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a300818258207e4fddb60c2034bff37bb7069f9318735fcf4de03e01e9f92251c96dc59318750001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a40081825820705ab68071f9af1d314e74a053e39a52f3fdf96f9a1280dab30d45f04c05436d07018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001eeb2890a021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a400818258206fe0c3eae23f779b0694747ed28612f47271b45e84bb3d23c11c1ef2e90fa12100018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001dcd122b6021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4150181a200583900e698ee1c7d4361c6faf62716dca0d435eafd0b25e369a5d68455beaa0f5c16e3e747e7c5a9eb3ff189c0e330683665de9326d2ffe35d0631011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4160181a2005839005bed6070c549f1560cb89361564cd2be7b36536e8da868a218d514e5fd2e3e48dbc0278cc58e47ed50a1ba90cee61ab22c8f4a639c913d4b011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418180181a200583900ab3cd541317d83d072bcc38e1294166dea5d97ce453424b84c547cfc101c5bfa799985a6e96adbb5859e90cbe4a0e4edcbef408a3622558b011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4181a0181a2005839003b3ff2a2d98519fcf53c7abb15b6c4dfe76209c52e4c2065b33b97bc465f9e3a6c6c3a8eac01d39f519b9bf3bc031480936156b7cb2e45c8011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4181d0181a20058390050fc315c9c141b4da62b10525cf5049e8ab1bb8bd96903a6d87c5272bc616bee900ed3135eb065a11faf2100670f0182ae86827df52dba96011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4181c0181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418200181a2005839005deef04c1b44c606775db03444beae0f10c75f437c131628d264b17c439dc3dbc39b8bb91832384d44263001591fd806df73b413da861fd3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418210181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418220181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418230181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418270181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418280181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418290181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4182d0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418330181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418340181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418350181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418360181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418370181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4183a0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4183c0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418460181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418470181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418490181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4184a0181a200583900189f009d9536b1f52f0629bea3323f48df0eacdff68726f1a32edc49db89995ed3aa88dcfb43790e2e51761fcba7e8594bcc67684f52d524011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418520181a2005839005c85eb9c0aa544a6bb5d1577c7a588c39caca885c8a3a9fceb0933a2cd1a02667d16df1e109350555c325023dbfa31fd9a4a8b99ff904d96011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418530181a20058390030a33756d8cbf4d18ce8c9995feca1ea1fc70093943c17bd96d65fed0aed6caa1cfe93f03f6ef1d9701df8024494d0b3b8a53a1ee37c5ab2011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418540181a2005839001da17fce0b5ae3e7feae117785eb78c77b6272be34a3d381a2722154d29c294b138005ca78de7b329ed6d2763a74a3fa1710a403e18fcb4a011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418560181a2005839001da17fce0b5ae3e7feae117785eb78c77b6272be34a3d381a2722154d29c294b138005ca78de7b329ed6d2763a74a3fa1710a403e18fcb4a011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418570181a20058390098bebc68cf6f12a7aca6531cef75d83c1b6e323485146195ffdd727dd99bbe7f44fd382de2ca6d9e5e9cc26f940decdb1b12b1a98e343274011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4185a0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4185c0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418610181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418620181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564050181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564070181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d00045640a0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d00045640b0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564181a0181a2005839005746c1b032f826b5e5256357a713a7ca63988fe2ff862e0396993b97ef0cbd5199d0e460725b3e79d371deb42110d40b778d3bf162777d4c011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564181b0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564181e0181a20058390020de866f290f45141315081d903f3eb3c06f3735e2a5b70f6a138462ada99823bc02291029853dc5338bc6e62b0540dbea54d9384f372639011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418200181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418210181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418230181a200583900057fd21bf903c585ea95dd927dee373b4cc1febc61874c48571dfb88a0a307af2a3e6a55a238fe323f9e54be10c54a8a8b25939a4f9ab35a011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418240181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582043c59e533d0934a6878a81403ec71a2225bb22d0764471cac8b5545120b475760001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418250181a2005839008f221a3021b0c09c57336733b0411d9d664e5d5e259096033a9d4bbecbce4335fa28195472386e53f0c3ab74d5cd254797d1100e4b1a33b8011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418290181a200583900d804dcdd0b0ec6ed0d8d2cd210a03b14f87c6849024930a8d6c91cf551a6a756817f0a3e1a1410730acf27202e7a9b63de26087e5cf466a5011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182b0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582072af166d0cd8883c9abb1189ae93acb1fce482ca57cad9b14711bca9627b98d80001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182d0181a2005839001c4595c4f3180180c9e822f1ac0f2955dd329eeeb94752a84281ff5295558528c6e1f7f2e16d94b74d227b9fd709edd2aeb0ab1556db75fc011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182e0181a200583900c008dd489b67e0a774fe18d79ee8d1e280264933d3b31ba44cb37755dca94fb45aa2192ab26eff8409ea010fa2d4761efa92437e0d5b6b60011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182f0181a200581d60fc38cce3448bf3d2790ca85d6b09026f7c86f21095c31f9925cf49a0011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418300181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418340181a20058390023a6fcbc8affc61518cff034c013aecf083dc64fe673ffc95cc9fd9e1fad7e0b1d0dd8820703a4f59c2488d148193a48d8fdc23a6dca8137011b00000002540be400021a00030d40ff9fa200d90102828258201287e9ce9e00a603d250b557146aa0581fc4edf277a244ce39d3b2f2ced5072f5840ae4cc1168265e2f60fec9ca9b644eaa42a77e65a39176e04aef29b01e25653a307d39ba61761f8d1ca44696e1d6bdf7a0679413ea3c448f76268e6eb02074102825820742d8af3543349b5b18f3cba28f23b2d6e465b9c136c42e1fae6b2390f5654275840112c95c93013e63fa73ee6a645fd522808d4dee019626e395a8042755c15fb1824e1503c17ea843a838809f55822366b05bce2e378d0b955e66d625c8e9acf0001d90102818200581c45d70e54f3b5e9c5a2b0cd417028197bd6f5fa5378c2f5eba896678da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584005383334e98e9263b93ffeb3e5908dbd5657caa67d32f9964d7f91dbda76fff164cbeabb981beef470d0d3e1724b85847e6fbc1c039084a817110eabf9d29e08a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258406151f0d0cae4ef0ace62dc03300dcee276765c1b493ac61f770d0633f0f71fe0d642ef29b593c511034a847dd569c56a0278e063c46d6d060abad4e6baf4b705a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840cf518f30d291871a0277e367534557205cc015d3a0d78070e1aee298aeaae3e81d70b42c464a63fa741b5300b48c1699dfc39fdf07f96b8eb240c7d6d3267805a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584056185de4c1d012d322e7e82ae98f24887ed7264f262db53f019e5900b9110a439e5a462a75be036f9f04b0ddcf09decb0894c7b6b9ff17ab4cae8184072d690fa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840ab78c606155b6aacbcf6692a18d97dd8773b4ae4c96684e4abb9cc59233023f67650ef7259069deddb65ba770ac3a1401d169ce33ec9483b8ebb9e83472e2c06a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840e21574b02002efcfe81382326aa98a0a971327ad4049690a04985400fcb14db7adc8149a0ce4dbfb5afa0d240ed9da23f15c1020d2826f50fc579a10a3662d0da10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840e64e3c19644edb6e788112ac75b4426ef94d535f1ffd9a34e86745777feaf083dc8e847a62634fef320a08b566c24ea26e8dc9e7b49fc456554215cedc0d3508a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840f49fd8eeaa366873aeb2530b2bbcbf7c5970866162ae7250c4b913e19062de1396ed70d1e32a4605071bac11c2cde3fec1dc5b37044cbea073668fe5c478400ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840f0ddd023e0dbda32d296b359db809b0088246e512fd34c7c0cc4b5ae974361873e02330e955eaaf97117525bcb3cd014bb70810f8d0d62a28c3242c86d8c3a08a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840615ee0444f039f02b26791872d6cd5562728cdc6dad02acc71475567b09f3d4b4655c601bf816ef6d11b2f3f81eeb6db09d800bf1bf4e2daf29493338c232901a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d62bfd428359f4cd04950cc73f574f0ec1c613284fdff8028ed3d876b18b69335beee9792410c6dbdc1b196b4703f250fbaeb66569869ae97d7ee843b9053405a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d813a836cc44c70647b2e7941fb72a4f720f16aca17e155a6c6a6f9bf175b1e49a3beff6edcfb0c442cc24790a12ee0b1d499a32fdbfc0a850f4846708ea340da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840aae6ac20cd419eaa7f3a95144f9ccdb46401a0db295d544e920a54b5c24fb63197fde03f12174800c3cf5318a73d92ebc53c2ba97803766892add32fd9feb400a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584071d223fd255df1e912a9c0a8230ee9f0ac95d0aa325cd31e50701ac355dfb5f3fbb27983b372c1410156eeba9163aa0f8a9787dab8c44e7afd4e2d07459a4708a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840b7f821c0ff66fcbbe7c61f43725aa2234297d6765e002d0130301cba13465fe89f59a596549725542445c76d17cedc9c9cfea8b8862d41405646d725dabc7d08a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e4584045830e5de108b9353b0c4c561af296e79eddb26b8ccfb18c5bd9fac1baf8d477691229c0bb9ea212ab56d9ae76c92de6ae50686fc0619510b8c35fb69c6b4402a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258400635ac784fe71d2f7927114edfc709dcb56013617df4edb9b6b770b067e7709e8abfd4cdcdd61512894fcf02f16e1d72bfe60fbfb86b815631d791bab132b909a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584032d67fe72feaf2175455815bbb624ee1b93f5efce905280158db94bbb2b5371d9eaff1bed6eddf9eafe8ff64b55f1d7213294bdb459e0b00c437edbcabf4cf07a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258404533de52e9e3f51e39951c9e197f6900081e98f38f3af5c4a7fe9219f8c311eaa43942b7a290ecbbbdd0bf4ef4ef1d11c39e6de4083c86892a6026c27bcf2509a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840d46541920ce2c31ffaa00cb20e8f5f00f48b6b8aa5cda67d22ea4bf12fd318461a0d8c25ee04cd7446e18f0de59b0fd4f6631e29bc8207073f2404793ae5f108a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584041bcd52ae44a3ffaa1abe1cab6c8b21f8010e2f1aee1d8651b9f6e94aabf5b2dbcedb45dd154b78dce1c5b9679956dd25153a0d945d3eb83c1de3b713e721008a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840027da3169c9c1fb9a67104061698bb0dadb2f58b660af4b461e7353fab1545a3d03157e077a388ec8556176239df3241255feb1f13b5e406bf7c3ad3af7d4202a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e458401ae63dc54e511965f7010971de7fb99585afe492cb8084b395ee01555c1e5657ab08a24be0f70d4e9cd1bde2a6ae31815c5f64025c0415afe2d503b2cb5b3e0ca10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840d2211679ca8e9cc5de71b21bac2b58fd355f5cbd2b42ff31ec37af77b776fb77c64fa76a830f240c29a4b95ae6bff9c58fc6bc2b3d18b57a2af11710ae6e3006a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584084bb7bf64ecea446d6beca88bfa2c7de71d8899e96006920c4c18e52f042aa71e1d27e60bdb6d9d6b1aa2e3330f59ee95b2c001909ff8994ea1fe4e5cd7a760aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840c6f3d6194a2fdb2a50417f80dd020adf866c91a102f22eb6bc66f5131292a1a42e9a3550e18e06cb17bd153c08f55a6cce3a1c82052ec9197495900f3ca4f407a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401a28cac7e80a657563e1433459f369bb0cb05e7e3ead78378dfc2ad15baa344e76e1ac0ca631c67848e81896fd6838b3821961928911635ca069f12c05772a08a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d201ce4ca5572db792d1563ef3614f2e2b27072e4751327f4a8f75201183a189ac57cdd9399474850e87031c7545c896ebab3983434bb6005690b9ad8fd9d50aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258403f45e44aa7457c714599f0100702ec265e91493e30c57ba4f1f74d912858bae8fb71fdf2faddf865c816cb0218eda0db17b707c8f429290f1a1c02b6a4450a0ea100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840e16b1d8f5992fda268c9d7e5c0ab6c5d38b8abaa6b92ccae5b0d2f3079d098ab67ba9a15b27807746f3c7695091ec5bb74ba8772baae14d2786eb8a512d70201a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840628a5491c5d0b4e0202b7aae87a343afd642345b823252355f6d392d8398d2174c141622e3de167b4f82c3cb8b4e8105b341851005d2ec0c1e35c354006a910ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258408ad2ee919f520a903764e0322800f7c086f870374f063d2e62ad1dfbf54e71305d90371abe3a196132e123b9248281f2d676fb29442f80249f644ce1185dfc03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d53bf84fe8712171151bb6d5f988d76428292639737d817986b46d629aea6eac2a90675cbf0347ec004ce23f9ca0b2dcff5c6d1be91ab478634de8ba8ab96102a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258404702623a2a94b9efbc03dc7d506c4bd70c1e0fea8b21f3b76c592883f0c364ffc12215e59f9ea4d2eed2e786376e6128650b4c9c3f6ad9419f070fb458efa10ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584072bb89ee81a7bcc4a866ae498d3ca076d5d5a885547c7f5899b8b59b3077310f58df420e470bf36d4ed5beaaf30eb361f04ed578cdbd0ef04f7cb573f0c0770ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840e112bb46921840820f4d5b40ec45699bc1b818ca8fe77fcc222a6fa1edb2425487f32e2039e2cf6077ce1e8e2e0b0d0581c64fb866c1c183344af131ccb9390ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840039329e261d8386f81a28f5ef5062196a46b5d4389b06bde97e662f69e37812c3ee75352f392121f58e76e5c1e1649656632b01ea46f932ccedcee102d625001a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840c1dab5e2482101ad1bd04f4018425c7133171aaf1274573ed35305f4e37bddadb3636f0aa098d2c0b5f615e8eb629bb94afac5d4c4c0743dba16a847d898b905a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840abb898b3e1ae3c4c9d068a4517b83a070d4037f979b6365ea5eb368e7d43b3fd2152fb93a462fdc553f973d90ab136332057fb66ea529d4fbc53e7f082b6fe03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258404a09ccfd9c09c6a453f46c721d280065081d89aa4b84fc809d75db1b923e78963bcbf36d64786d8c09c527e90da744e83116617b2e18d9145bac6cf66f876c08a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258408df2408adbd8b4c990a913b9ed2455c9de72d561ddb8f3ec0da5d1513f417a2fcee9ea9ace30cb840d37950c41455bd3655d12d534b70a6eac7034950f821108a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840534b54cc145722e3f7a62935d84c025e17e31c4b08d3f3fb16bb7673d37e9afb07fbdb5ffce5aeef743376bac161973e565e1c12db97bcd879cd7e9030c2a00ea100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840664fd5d8bc5d93509d02104f39e7a22c6cd894f49935cac9e662a9202b9a64baa9f55cd8aa07d3d1e095e9b974c59c0a8c50d14b0d077d70e236ad5cf52ac104a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840469cdadb48349224303d14980cab5c2ae5dacd0f6e36714d8dcb9ca85fa4eb688bd7b1334e30f8718178f7f36d8c5b204e0f9cdce5f88762fc2cbe2cb28c1d03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840f330820de229a476e1b3f84dfcf9ad98264070212e6e2d61d8b05afb1e12a1426cfd7cb0b284db237d5882cecd6e8f1fe2cf9ddc06783242812178bcb053a105a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584066b89001a28583bed59dbd07d359333207eb74d39ee092c0bf1da4351da64d38c9938a3682bb52a4253dc76074767b4cc2bc1eb2a31bbe6be3c45a5c52cbdf04a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840f365b299297ade5117d72156050cb81a76ba0b859cb46d0f2326c4071110440108b20390f878ba082d41217b2a8fd5f1435b9ba48d176ad5dcb6faff54976b0da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258407fb0b1f28d6ca64a29c6c7a51a2ab3436809b5038c06b8204104e3b98afa915246f742e2f1bd569f5132d2bbdcaeae68215a0b0f17f6367ce4eea37ed951ec01a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258406e6d2263c440486fc1b3c2aa930e519f20b70f70c28cb532d031f63cefc55c56f4647b10dd6390aa0d0f2ba75bf6cbe3ce2fc6d928dc4db74388f1e5e3057b0ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840dbb299923c24a70ae10dc637d862b750b3e6548e64c590674d2ceb87b7535199ea8dfd024694d26ae1dbbca683b1a4ba90af7d1680a9b8e4819a2ee6229e2408a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258405b2397d031c48f56b43416daea99dd3d8bd1733cb83c2a688dbe8b5dd9bfe64d596280d71973d7d540e929262dafd79b14954b855635fe845642090241003503a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840482c9089f2d60eb069432bf7f7213178a6fe3d52d37a4fa5aec677875bccdac64de7a45c6eb0bd4996414412b12d3e887a1b391e775ef56c47d53f9c944d020ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401972d18c1e9c62837121efafddc2ec778a3a8f9ec5f534c9922778905d8f809609d6c92e427852d8b5f822ad590fdeacf3877c8056f0768b44b025a2b79e7704a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258409b7141b69a493bc4d597a645ed488325492772ad4c3cd5c5c7805a5d951a4b6ed960ea27428d1add867fe7c209f4e65000bdfa878bd7a4357b223e9c55af450da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258407ac2d7823887de83bca86216e424ccb63fe9f4fa1f106bffc6afa388e91845c97177c410f1a8ca5ecd9f2701c42f5f9dd2faeb0ecf2163a37521badc8a6c1b03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840c49b6714ccbbdebebb9461a2efb39b9ac5e00a389aadfb2a1b4fe384733610c45e1f03825f65e182988da97659a71e378d49d17fb93d76b80d579b7d49399b06a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840b53ea3508cbd7da47fef05e98c0b31b13ec33de4596ba4061a8e04d91b1015c49f328da58084a6f573d93cdb7aa0972a1a1936a69ee7362adf65df3eae4e2400a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840b1c6b15b311423aa83dfaebe118d1a2a3ff006399f2a63fa82f0d0e0c12bc2b844ec78f5bc8baeef588d15b2237db48cbfa48361a6d630052c9b68e62e035601a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840bb544721cd95655497375390da19fbd87b3c63a4edf333688e2fee7935e96b6572f84b81d80fee5239062be6d3c6a75a5f0c50696d3c6663d26cecdfd8fdc808a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840a7018dfacec705459856bc706b7d05d04c56867fb64dfd0cf97fa980e881cc609e91cf6df204fb6906f860e5cf390e0290d302b6231664aad8c2b4cb30090609a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258403ddf27cce21fbf1a361233d2bcff92ecc9d3cce64c3d8186495e3509b843a0a326f528be8241b8557bf3cdac9c304fcf0fa8fd2a8e389d6acf9fc62b5626d705a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584013bd40ae7383feb674c2cd3357122aec3f6efe17b9b4f25c47cd3dfec194d0c4f20a52cc30fb92245c1a20a962772808f3dc6ee51261c86af16879a1fed2210ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840a1cf100aff45ee45c0f868214187640c8c29cb005c7aab7100ff86338d78f972733a611b4e0dae436fe9e1493d6ece69c35ada3cc6506e730ea1bae277468108a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840667d6d2987788454c41f2e86867fe98e1fd48aa789fbf9cf2208f927a8f9941d0384ebf3e3e45ee80c49934aad9b6ccaa13179b69f35b9acd21b55f56caff80da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401cd5c48fa46d8f0fb07c7737b7719d1fba5729478be3eef3e2e19942c4d6d54b01a569eb34d4f4be84a2f6961832ec17bade0511cbc01f5db5749a09bb4d8808a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258403bb5ddd91b5f5d7366b41330bf5bbbf7cf7d703bd50376ac21b07c6da696562266361678c06247a57111c63bc1fe58463a8c125e0d117bdf05cd4fe57bb8b90aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840397067045ffe0cf7126a5f73f228e1bc8721c617ebb7c41c1bc2f7b6c8cc50bf2370bc1ee679bcb0581e11da1e186504f2e3f3322fddf40a1863067ffc5e2903a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840831f5ea5dd354f5a522e044b53aa1966d036871d5a3b7d2323e404996907a33aff5aabb9db22301064033045cbf14c91d29de84b8fbbb75683ff1cb51fd0920aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401e8cc65db39cb5e9d54dac50cda84c55fd2f989f667a11dc46521768ac2f46a27a70173a92e849ee621ebe3025d87088528e7450b8312d678b6249f5a124f70fa10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840f4835bbcf5459db0826e27ea95d3ac31f7bea56c0253716212ef421995c7546a963ac89dc6cffad75692a149372cbdeaa19a9dcd171ac423711e8d71c495d703a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258408039411659145a9fb3863b2ae2f3890009bf004332f58daa6662368a7378d215cc7f40569284d5b86c5a7be210cdcb5551633762b5a7d3f8ad2095a220fec609a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584002c9ec1d95d0464eba5f4a656d72b55a92a80078e83f2f47682729af0fc782a68f3f31db7c64018ae8fbd36c5ac72d5573357a7578359056b9d3f9a29467d80ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258406f176d0fdb8768aad902c8fc115eb797719ef62a93938d7f09bbb213a88d61294143ec1d508a2a450f0e16ab3e2ffb7e0ed4cd7f75b3f2ff9f70cfaa77764506a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840f4262eeb9183eec1e896b9be61984ed9d4192b38825ba1b560ea23fe6e3224d3c94f4cc64174c1d9166e665e1a1ff8f0c84024bb8b9068b853fe4ce683d96906a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840df64e327056e335f484582fa0e4188e62620968e955431fc3576da2c1935b15ec605bb5d738f5000dcdc022646f9545d6932c2c79611dccab116295ca03c2b04a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840132cce5cea5d8bf7e9b802e4477eff041ebe1c12a8b8658a42ae91727cbf4f39b0d23831c70923a68ad7a023092bcecb61ac6253fdd17be00cecc37a71301300a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840842ecaf1b907cb34799d78d6f35eb349a986559a396840aeba5f6e8dc7e4172c16bddcb1f926a21175531478773046e9484aeb4ca83c1cbaf25f5a4813afdd0ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840a417cdf9e02755e53d6061ce0c93cacb7de24ce33e3fda9ac3a85414a7bf62676446822875972867d5647e46c22e21099e5dd8e4114949b30b86146b0dba1b05a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401f2e86831349fa458c3e2403e2caacbf046fae3c513575e8ce2d34037d34337f7e58cc98cadf034e8bce930335285220624945b316fe6af71e8ef0d12ef05001ffa100d90103a100a11902a2a1636d73678f78264175746f2d4c6f6f702d5472616e73616374696f6e202336313138303020627920415441444160783c4c6976652045706f6368203234352c207765206861766520303132682032386d20323773206c65667420756e74696c20746865206e657874206f6e6578374974277320446f6e6e657273746167202d20313520466562727561722032303234202d2031333a30313a333320696e20417573747269616060607820412072616e646f6d205a656e2d51756f746520666f7220796f753a20f09f998f783b4265206b696e642c20666f722065766572796f6e6520796f75206d656574206973206669676874696e6720612068617264657220626174746c652e68202d20506c61746f6078374e6f64652d5265766973696f6e3a203462623230343864623737643632336565366533363738363138633264386236633436373633333360782953616e63686f4e657420697320617765736f6d652c206861766520736f6d652066756e2120f09f988d7819204265737420726567617264732c204d617274696e203a2d2980"; + let block_hex ="85828a1a00101e2c1a0143a1b35820cee15d6daecaeaf320a4ddb1f7c437846f798e4a9cd08d12fb7821b175c980115820e3c87f196ce9fc40a8d929f3365e247f8f71e1981bffaa7cbdb0aa3a83dc790d582054a580ddf99f67818e0312374cef1f7dcdd59450930898d4d2d10e606b963e49825840ca5d1f988222919982b6a20f4f54ce59626fece7d7c607487762129d5196c731bcd11dfefee94ce5a60a733478970631d41bfc0620769fa7b66ebc16c8a89e5c58502855f21ba12fb101d175c376e19496e464bf37c92ec21395e5bffb35e1ae8f433f2139de166161f2b2b26afe656d3d170acfd11a535a80fca6325479d2262e208b0a4b98a01f4845c45a58fb84cb58011952de5820f2e4c6554da5b773c3f7889944fdb5b1791f8552dcafe2916041a531860e912284582039b66a10f6b78c541ea5ed6ecec4c6dd385b869026ec16c4e48414cb39cac38b0018a258409ccd6cf71a5c337f71a41904c0ea0a889a2321c94374c3a8402d8a7dd25b222abe6cb325c6b39bd63bc99fa84c094fdac2523b72f1a22081903dd047be9be9078209005901c006b35937aba451d4738486ea3ba5644d9306651f09b2012de8acc5136771fc725164ad669dd716f2726dfe138137d09feddf9450b3c51a601577bff35d0d2202c887a260855dd8310fc9365f56a4757ea7d81103d409ea0a8ad51c6ae52fc7fcf4d3d456384b7566b70a2b7bd4e21010a1ad5df12bf5d332e82c1a4a5cca39740252e0ea163f206cacf193e59ebbd0e20d621fa9913c60efe1c035d8ebaa354fbe45768339d53a4e8e04fdea79d00b869a973cfa3eeba2e2668b1dee5fcd7d13762dceb4da804fd749e5fa977ead0003a9739837aa68b80bc5a32ee015f667574a7fbe03b4bf5b027c945fa4497c01efb4ec51f3da2fb2dda33ea7dc1dedcfd2ea2c0a4da5a1c553d033033f4986e2ef5c09bbe326a25e5082c1eec406aeec8105869a9d46a83689a2e026e6e31d4037e700ffeb2920bcab88d1a400976881d17cd84582521482db0be460fb43de88e40a4ee24745ac92ab8b40329bde1d855404478c9f59b05e6322f3640ad6f40d7a771fc6d58e94f8fd0006d54272e36a30034b14327c2e6ffb92ead2f8a4165a3e4a1c44de677829e8e797547b3c0bac4b5ea89cb86c01d5b1e67aee3ba36b8cf9617484db2e4d1bfc37fed1fabb73ce3c9fa600d901028182582088c310befd2e8c9b33b340a56f4ea8141689c16eddef5d9c606055ca35897bd600018182581d6052e63f22c5107ed776b70f7b92248b02552fd08f3e747bc745099441821b00000001f09cac72a1581c34250edd1e9836f5378702fbf9416b709bc140e04f668cc355208518a1494154414441636f696e1916d6021a00030739031a0145283409a1581c34250edd1e9836f5378702fbf9416b709bc140e04f668cc355208518a1494154414441636f696e01075820e2ea39e82586fa40304df3c2cfc753c6ba8aca62e780f01a0519c34c6d7c25f5a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe185b0181a2005839007ce8986f5f3fb526a6d35d32edac0b6c8624daab6928df1964459c2723bcf2892e8182a68e3aac6f9f42ed3317d115ebad12a17232681175011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe185c0181a200583900f7fa5ddf2c3c46ed4d913812d38dd43d585adfa884938adaa7a075dd1bf1e138f2f8beabc963c94cc28ee8ed4b41744601f2edaf50b21efd011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe185d0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18600181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18620181a200583900189f009d9536b1f52f0629bea3323f48df0eacdff68726f1a32edc49db89995ed3aa88dcfb43790e2e51761fcba7e8594bcc67684f52d524011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18630181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820a944bb37a59451f9a47d5c8888a8a1145527ffb5d45a17c1df40926a42ad08330001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a400818258206a7e3a926eafa74f72c0d6a721dfdee7a7202b1fac4eee12d8c6dd030217890b07018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001eeb2890a021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18640181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820a439638a9f8e0f52e153126e8b794b7514f3a0921b08b611f3866a1fc75b7a560001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4010181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4030181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4020181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4040181a2005839002b11f0e68a65cd6a243f1a5ec9d597ba972675a00bd3172a7ddc0293b1d312a60b3824d1820dec5ec769c4af7d7598387c16ca5ba6259f46011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4080181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a400818258203298fb7878ab004c1a4b369eae7fc89abca6342f06557cebf6c89f2d8c21aa9900018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001b3152865021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a40a0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a40d0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a40f0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a40081825820dcdbb7a98286f5d48673c95b05f441bc40731b1e4c3429d192f0c6b7fc3749d100018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000002186e835b021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4130181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a300818258207e4fddb60c2034bff37bb7069f9318735fcf4de03e01e9f92251c96dc59318750001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a40081825820705ab68071f9af1d314e74a053e39a52f3fdf96f9a1280dab30d45f04c05436d07018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001eeb2890a021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a400818258206fe0c3eae23f779b0694747ed28612f47271b45e84bb3d23c11c1ef2e90fa12100018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001dcd122b6021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4150181a200583900e698ee1c7d4361c6faf62716dca0d435eafd0b25e369a5d68455beaa0f5c16e3e747e7c5a9eb3ff189c0e330683665de9326d2ffe35d0631011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4160181a2005839005bed6070c549f1560cb89361564cd2be7b36536e8da868a218d514e5fd2e3e48dbc0278cc58e47ed50a1ba90cee61ab22c8f4a639c913d4b011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418180181a200583900ab3cd541317d83d072bcc38e1294166dea5d97ce453424b84c547cfc101c5bfa799985a6e96adbb5859e90cbe4a0e4edcbef408a3622558b011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4181a0181a2005839003b3ff2a2d98519fcf53c7abb15b6c4dfe76209c52e4c2065b33b97bc465f9e3a6c6c3a8eac01d39f519b9bf3bc031480936156b7cb2e45c8011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4181d0181a20058390050fc315c9c141b4da62b10525cf5049e8ab1bb8bd96903a6d87c5272bc616bee900ed3135eb065a11faf2100670f0182ae86827df52dba96011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4181c0181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418200181a2005839005deef04c1b44c606775db03444beae0f10c75f437c131628d264b17c439dc3dbc39b8bb91832384d44263001591fd806df73b413da861fd3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418210181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418220181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418230181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418270181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418280181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418290181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4182d0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418330181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418340181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418350181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418360181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418370181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4183a0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4183c0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418460181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418470181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418490181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4184a0181a200583900189f009d9536b1f52f0629bea3323f48df0eacdff68726f1a32edc49db89995ed3aa88dcfb43790e2e51761fcba7e8594bcc67684f52d524011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418520181a2005839005c85eb9c0aa544a6bb5d1577c7a588c39caca885c8a3a9fceb0933a2cd1a02667d16df1e109350555c325023dbfa31fd9a4a8b99ff904d96011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418530181a20058390030a33756d8cbf4d18ce8c9995feca1ea1fc70093943c17bd96d65fed0aed6caa1cfe93f03f6ef1d9701df8024494d0b3b8a53a1ee37c5ab2011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418540181a2005839001da17fce0b5ae3e7feae117785eb78c77b6272be34a3d381a2722154d29c294b138005ca78de7b329ed6d2763a74a3fa1710a403e18fcb4a011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418560181a2005839001da17fce0b5ae3e7feae117785eb78c77b6272be34a3d381a2722154d29c294b138005ca78de7b329ed6d2763a74a3fa1710a403e18fcb4a011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418570181a20058390098bebc68cf6f12a7aca6531cef75d83c1b6e323485146195ffdd727dd99bbe7f44fd382de2ca6d9e5e9cc26f940decdb1b12b1a98e343274011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4185a0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4185c0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418610181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418620181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564050181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564070181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d00045640a0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d00045640b0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564181a0181a2005839005746c1b032f826b5e5256357a713a7ca63988fe2ff862e0396993b97ef0cbd5199d0e460725b3e79d371deb42110d40b778d3bf162777d4c011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564181b0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564181e0181a20058390020de866f290f45141315081d903f3eb3c06f3735e2a5b70f6a138462ada99823bc02291029853dc5338bc6e62b0540dbea54d9384f372639011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418200181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418210181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418230181a200583900057fd21bf903c585ea95dd927dee373b4cc1febc61874c48571dfb88a0a307af2a3e6a55a238fe323f9e54be10c54a8a8b25939a4f9ab35a011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418240181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582043c59e533d0934a6878a81403ec71a2225bb22d0764471cac8b5545120b475760001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418250181a2005839008f221a3021b0c09c57336733b0411d9d664e5d5e259096033a9d4bbecbce4335fa28195472386e53f0c3ab74d5cd254797d1100e4b1a33b8011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418290181a200583900d804dcdd0b0ec6ed0d8d2cd210a03b14f87c6849024930a8d6c91cf551a6a756817f0a3e1a1410730acf27202e7a9b63de26087e5cf466a5011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182b0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582072af166d0cd8883c9abb1189ae93acb1fce482ca57cad9b14711bca9627b98d80001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182d0181a2005839001c4595c4f3180180c9e822f1ac0f2955dd329eeeb94752a84281ff5295558528c6e1f7f2e16d94b74d227b9fd709edd2aeb0ab1556db75fc011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182e0181a200583900c008dd489b67e0a774fe18d79ee8d1e280264933d3b31ba44cb37755dca94fb45aa2192ab26eff8409ea010fa2d4761efa92437e0d5b6b60011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182f0181a200581d60fc38cce3448bf3d2790ca85d6b09026f7c86f21095c31f9925cf49a0011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418300181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418340181a20058390023a6fcbc8affc61518cff034c013aecf083dc64fe673ffc95cc9fd9e1fad7e0b1d0dd8820703a4f59c2488d148193a48d8fdc23a6dca8137011b00000002540be400021a00030d40ff9fa200d90102828258201287e9ce9e00a603d250b557146aa0581fc4edf277a244ce39d3b2f2ced5072f5840ae4cc1168265e2f60fec9ca9b644eaa42a77e65a39176e04aef29b01e25653a307d39ba61761f8d1ca44696e1d6bdf7a0679413ea3c448f76268e6eb02074102825820742d8af3543349b5b18f3cba28f23b2d6e465b9c136c42e1fae6b2390f5654275840112c95c93013e63fa73ee6a645fd522808d4dee019626e395a8042755c15fb1824e1503c17ea843a838809f55822366b05bce2e378d0b955e66d625c8e9acf0001d90102818200581c45d70e54f3b5e9c5a2b0cd417028197bd6f5fa5378c2f5eba896678da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584005383334e98e9263b93ffeb3e5908dbd5657caa67d32f9964d7f91dbda76fff164cbeabb981beef470d0d3e1724b85847e6fbc1c039084a817110eabf9d29e08a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258406151f0d0cae4ef0ace62dc03300dcee276765c1b493ac61f770d0633f0f71fe0d642ef29b593c511034a847dd569c56a0278e063c46d6d060abad4e6baf4b705a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840cf518f30d291871a0277e367534557205cc015d3a0d78070e1aee298aeaae3e81d70b42c464a63fa741b5300b48c1699dfc39fdf07f96b8eb240c7d6d3267805a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584056185de4c1d012d322e7e82ae98f24887ed7264f262db53f019e5900b9110a439e5a462a75be036f9f04b0ddcf09decb0894c7b6b9ff17ab4cae8184072d690fa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840ab78c606155b6aacbcf6692a18d97dd8773b4ae4c96684e4abb9cc59233023f67650ef7259069deddb65ba770ac3a1401d169ce33ec9483b8ebb9e83472e2c06a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840e21574b02002efcfe81382326aa98a0a971327ad4049690a04985400fcb14db7adc8149a0ce4dbfb5afa0d240ed9da23f15c1020d2826f50fc579a10a3662d0da10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840e64e3c19644edb6e788112ac75b4426ef94d535f1ffd9a34e86745777feaf083dc8e847a62634fef320a08b566c24ea26e8dc9e7b49fc456554215cedc0d3508a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840f49fd8eeaa366873aeb2530b2bbcbf7c5970866162ae7250c4b913e19062de1396ed70d1e32a4605071bac11c2cde3fec1dc5b37044cbea073668fe5c478400ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840f0ddd023e0dbda32d296b359db809b0088246e512fd34c7c0cc4b5ae974361873e02330e955eaaf97117525bcb3cd014bb70810f8d0d62a28c3242c86d8c3a08a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840615ee0444f039f02b26791872d6cd5562728cdc6dad02acc71475567b09f3d4b4655c601bf816ef6d11b2f3f81eeb6db09d800bf1bf4e2daf29493338c232901a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d62bfd428359f4cd04950cc73f574f0ec1c613284fdff8028ed3d876b18b69335beee9792410c6dbdc1b196b4703f250fbaeb66569869ae97d7ee843b9053405a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d813a836cc44c70647b2e7941fb72a4f720f16aca17e155a6c6a6f9bf175b1e49a3beff6edcfb0c442cc24790a12ee0b1d499a32fdbfc0a850f4846708ea340da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840aae6ac20cd419eaa7f3a95144f9ccdb46401a0db295d544e920a54b5c24fb63197fde03f12174800c3cf5318a73d92ebc53c2ba97803766892add32fd9feb400a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584071d223fd255df1e912a9c0a8230ee9f0ac95d0aa325cd31e50701ac355dfb5f3fbb27983b372c1410156eeba9163aa0f8a9787dab8c44e7afd4e2d07459a4708a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840b7f821c0ff66fcbbe7c61f43725aa2234297d6765e002d0130301cba13465fe89f59a596549725542445c76d17cedc9c9cfea8b8862d41405646d725dabc7d08a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e4584045830e5de108b9353b0c4c561af296e79eddb26b8ccfb18c5bd9fac1baf8d477691229c0bb9ea212ab56d9ae76c92de6ae50686fc0619510b8c35fb69c6b4402a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258400635ac784fe71d2f7927114edfc709dcb56013617df4edb9b6b770b067e7709e8abfd4cdcdd61512894fcf02f16e1d72bfe60fbfb86b815631d791bab132b909a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584032d67fe72feaf2175455815bbb624ee1b93f5efce905280158db94bbb2b5371d9eaff1bed6eddf9eafe8ff64b55f1d7213294bdb459e0b00c437edbcabf4cf07a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258404533de52e9e3f51e39951c9e197f6900081e98f38f3af5c4a7fe9219f8c311eaa43942b7a290ecbbbdd0bf4ef4ef1d11c39e6de4083c86892a6026c27bcf2509a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840d46541920ce2c31ffaa00cb20e8f5f00f48b6b8aa5cda67d22ea4bf12fd318461a0d8c25ee04cd7446e18f0de59b0fd4f6631e29bc8207073f2404793ae5f108a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584041bcd52ae44a3ffaa1abe1cab6c8b21f8010e2f1aee1d8651b9f6e94aabf5b2dbcedb45dd154b78dce1c5b9679956dd25153a0d945d3eb83c1de3b713e721008a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840027da3169c9c1fb9a67104061698bb0dadb2f58b660af4b461e7353fab1545a3d03157e077a388ec8556176239df3241255feb1f13b5e406bf7c3ad3af7d4202a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e458401ae63dc54e511965f7010971de7fb99585afe492cb8084b395ee01555c1e5657ab08a24be0f70d4e9cd1bde2a6ae31815c5f64025c0415afe2d503b2cb5b3e0ca10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840d2211679ca8e9cc5de71b21bac2b58fd355f5cbd2b42ff31ec37af77b776fb77c64fa76a830f240c29a4b95ae6bff9c58fc6bc2b3d18b57a2af11710ae6e3006a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584084bb7bf64ecea446d6beca88bfa2c7de71d8899e96006920c4c18e52f042aa71e1d27e60bdb6d9d6b1aa2e3330f59ee95b2c001909ff8994ea1fe4e5cd7a760aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840c6f3d6194a2fdb2a50417f80dd020adf866c91a102f22eb6bc66f5131292a1a42e9a3550e18e06cb17bd153c08f55a6cce3a1c82052ec9197495900f3ca4f407a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401a28cac7e80a657563e1433459f369bb0cb05e7e3ead78378dfc2ad15baa344e76e1ac0ca631c67848e81896fd6838b3821961928911635ca069f12c05772a08a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d201ce4ca5572db792d1563ef3614f2e2b27072e4751327f4a8f75201183a189ac57cdd9399474850e87031c7545c896ebab3983434bb6005690b9ad8fd9d50aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258403f45e44aa7457c714599f0100702ec265e91493e30c57ba4f1f74d912858bae8fb71fdf2faddf865c816cb0218eda0db17b707c8f429290f1a1c02b6a4450a0ea100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840e16b1d8f5992fda268c9d7e5c0ab6c5d38b8abaa6b92ccae5b0d2f3079d098ab67ba9a15b27807746f3c7695091ec5bb74ba8772baae14d2786eb8a512d70201a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840628a5491c5d0b4e0202b7aae87a343afd642345b823252355f6d392d8398d2174c141622e3de167b4f82c3cb8b4e8105b341851005d2ec0c1e35c354006a910ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258408ad2ee919f520a903764e0322800f7c086f870374f063d2e62ad1dfbf54e71305d90371abe3a196132e123b9248281f2d676fb29442f80249f644ce1185dfc03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d53bf84fe8712171151bb6d5f988d76428292639737d817986b46d629aea6eac2a90675cbf0347ec004ce23f9ca0b2dcff5c6d1be91ab478634de8ba8ab96102a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258404702623a2a94b9efbc03dc7d506c4bd70c1e0fea8b21f3b76c592883f0c364ffc12215e59f9ea4d2eed2e786376e6128650b4c9c3f6ad9419f070fb458efa10ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584072bb89ee81a7bcc4a866ae498d3ca076d5d5a885547c7f5899b8b59b3077310f58df420e470bf36d4ed5beaaf30eb361f04ed578cdbd0ef04f7cb573f0c0770ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840e112bb46921840820f4d5b40ec45699bc1b818ca8fe77fcc222a6fa1edb2425487f32e2039e2cf6077ce1e8e2e0b0d0581c64fb866c1c183344af131ccb9390ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840039329e261d8386f81a28f5ef5062196a46b5d4389b06bde97e662f69e37812c3ee75352f392121f58e76e5c1e1649656632b01ea46f932ccedcee102d625001a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840c1dab5e2482101ad1bd04f4018425c7133171aaf1274573ed35305f4e37bddadb3636f0aa098d2c0b5f615e8eb629bb94afac5d4c4c0743dba16a847d898b905a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840abb898b3e1ae3c4c9d068a4517b83a070d4037f979b6365ea5eb368e7d43b3fd2152fb93a462fdc553f973d90ab136332057fb66ea529d4fbc53e7f082b6fe03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258404a09ccfd9c09c6a453f46c721d280065081d89aa4b84fc809d75db1b923e78963bcbf36d64786d8c09c527e90da744e83116617b2e18d9145bac6cf66f876c08a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258408df2408adbd8b4c990a913b9ed2455c9de72d561ddb8f3ec0da5d1513f417a2fcee9ea9ace30cb840d37950c41455bd3655d12d534b70a6eac7034950f821108a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840534b54cc145722e3f7a62935d84c025e17e31c4b08d3f3fb16bb7673d37e9afb07fbdb5ffce5aeef743376bac161973e565e1c12db97bcd879cd7e9030c2a00ea100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840664fd5d8bc5d93509d02104f39e7a22c6cd894f49935cac9e662a9202b9a64baa9f55cd8aa07d3d1e095e9b974c59c0a8c50d14b0d077d70e236ad5cf52ac104a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840469cdadb48349224303d14980cab5c2ae5dacd0f6e36714d8dcb9ca85fa4eb688bd7b1334e30f8718178f7f36d8c5b204e0f9cdce5f88762fc2cbe2cb28c1d03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840f330820de229a476e1b3f84dfcf9ad98264070212e6e2d61d8b05afb1e12a1426cfd7cb0b284db237d5882cecd6e8f1fe2cf9ddc06783242812178bcb053a105a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584066b89001a28583bed59dbd07d359333207eb74d39ee092c0bf1da4351da64d38c9938a3682bb52a4253dc76074767b4cc2bc1eb2a31bbe6be3c45a5c52cbdf04a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840f365b299297ade5117d72156050cb81a76ba0b859cb46d0f2326c4071110440108b20390f878ba082d41217b2a8fd5f1435b9ba48d176ad5dcb6faff54976b0da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258407fb0b1f28d6ca64a29c6c7a51a2ab3436809b5038c06b8204104e3b98afa915246f742e2f1bd569f5132d2bbdcaeae68215a0b0f17f6367ce4eea37ed951ec01a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258406e6d2263c440486fc1b3c2aa930e519f20b70f70c28cb532d031f63cefc55c56f4647b10dd6390aa0d0f2ba75bf6cbe3ce2fc6d928dc4db74388f1e5e3057b0ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840dbb299923c24a70ae10dc637d862b750b3e6548e64c590674d2ceb87b7535199ea8dfd024694d26ae1dbbca683b1a4ba90af7d1680a9b8e4819a2ee6229e2408a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258405b2397d031c48f56b43416daea99dd3d8bd1733cb83c2a688dbe8b5dd9bfe64d596280d71973d7d540e929262dafd79b14954b855635fe845642090241003503a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840482c9089f2d60eb069432bf7f7213178a6fe3d52d37a4fa5aec677875bccdac64de7a45c6eb0bd4996414412b12d3e887a1b391e775ef56c47d53f9c944d020ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401972d18c1e9c62837121efafddc2ec778a3a8f9ec5f534c9922778905d8f809609d6c92e427852d8b5f822ad590fdeacf3877c8056f0768b44b025a2b79e7704a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258409b7141b69a493bc4d597a645ed488325492772ad4c3cd5c5c7805a5d951a4b6ed960ea27428d1add867fe7c209f4e65000bdfa878bd7a4357b223e9c55af450da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258407ac2d7823887de83bca86216e424ccb63fe9f4fa1f106bffc6afa388e91845c97177c410f1a8ca5ecd9f2701c42f5f9dd2faeb0ecf2163a37521badc8a6c1b03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840c49b6714ccbbdebebb9461a2efb39b9ac5e00a389aadfb2a1b4fe384733610c45e1f03825f65e182988da97659a71e378d49d17fb93d76b80d579b7d49399b06a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840b53ea3508cbd7da47fef05e98c0b31b13ec33de4596ba4061a8e04d91b1015c49f328da58084a6f573d93cdb7aa0972a1a1936a69ee7362adf65df3eae4e2400a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840b1c6b15b311423aa83dfaebe118d1a2a3ff006399f2a63fa82f0d0e0c12bc2b844ec78f5bc8baeef588d15b2237db48cbfa48361a6d630052c9b68e62e035601a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840bb544721cd95655497375390da19fbd87b3c63a4edf333688e2fee7935e96b6572f84b81d80fee5239062be6d3c6a75a5f0c50696d3c6663d26cecdfd8fdc808a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840a7018dfacec705459856bc706b7d05d04c56867fb64dfd0cf97fa980e881cc609e91cf6df204fb6906f860e5cf390e0290d302b6231664aad8c2b4cb30090609a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258403ddf27cce21fbf1a361233d2bcff92ecc9d3cce64c3d8186495e3509b843a0a326f528be8241b8557bf3cdac9c304fcf0fa8fd2a8e389d6acf9fc62b5626d705a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584013bd40ae7383feb674c2cd3357122aec3f6efe17b9b4f25c47cd3dfec194d0c4f20a52cc30fb92245c1a20a962772808f3dc6ee51261c86af16879a1fed2210ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840a1cf100aff45ee45c0f868214187640c8c29cb005c7aab7100ff86338d78f972733a611b4e0dae436fe9e1493d6ece69c35ada3cc6506e730ea1bae277468108a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840667d6d2987788454c41f2e86867fe98e1fd48aa789fbf9cf2208f927a8f9941d0384ebf3e3e45ee80c49934aad9b6ccaa13179b69f35b9acd21b55f56caff80da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401cd5c48fa46d8f0fb07c7737b7719d1fba5729478be3eef3e2e19942c4d6d54b01a569eb34d4f4be84a2f6961832ec17bade0511cbc01f5db5749a09bb4d8808a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258403bb5ddd91b5f5d7366b41330bf5bbbf7cf7d703bd50376ac21b07c6da696562266361678c06247a57111c63bc1fe58463a8c125e0d117bdf05cd4fe57bb8b90aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840397067045ffe0cf7126a5f73f228e1bc8721c617ebb7c41c1bc2f7b6c8cc50bf2370bc1ee679bcb0581e11da1e186504f2e3f3322fddf40a1863067ffc5e2903a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840831f5ea5dd354f5a522e044b53aa1966d036871d5a3b7d2323e404996907a33aff5aabb9db22301064033045cbf14c91d29de84b8fbbb75683ff1cb51fd0920aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401e8cc65db39cb5e9d54dac50cda84c55fd2f989f667a11dc46521768ac2f46a27a70173a92e849ee621ebe3025d87088528e7450b8312d678b6249f5a124f70fa10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840f4835bbcf5459db0826e27ea95d3ac31f7bea56c0253716212ef421995c7546a963ac89dc6cffad75692a149372cbdeaa19a9dcd171ac423711e8d71c495d703a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258408039411659145a9fb3863b2ae2f3890009bf004332f58daa6662368a7378d215cc7f40569284d5b86c5a7be210cdcb5551633762b5a7d3f8ad2095a220fec609a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584002c9ec1d95d0464eba5f4a656d72b55a92a80078e83f2f47682729af0fc782a68f3f31db7c64018ae8fbd36c5ac72d5573357a7578359056b9d3f9a29467d80ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258406f176d0fdb8768aad902c8fc115eb797719ef62a93938d7f09bbb213a88d61294143ec1d508a2a450f0e16ab3e2ffb7e0ed4cd7f75b3f2ff9f70cfaa77764506a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840f4262eeb9183eec1e896b9be61984ed9d4192b38825ba1b560ea23fe6e3224d3c94f4cc64174c1d9166e665e1a1ff8f0c84024bb8b9068b853fe4ce683d96906a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840df64e327056e335f484582fa0e4188e62620968e955431fc3576da2c1935b15ec605bb5d738f5000dcdc022646f9545d6932c2c79611dccab116295ca03c2b04a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840132cce5cea5d8bf7e9b802e4477eff041ebe1c12a8b8658a42ae91727cbf4f39b0d23831c70923a68ad7a023092bcecb61ac6253fdd17be00cecc37a71301300a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840842ecaf1b907cb34799d78d6f35eb349a986559a396840aeba5f6e8dc7e4172c16bddcb1f926a21175531478773046e9484aeb4ca83c1cbaf25f5a4813afdd0ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840a417cdf9e02755e53d6061ce0c93cacb7de24ce33e3fda9ac3a85414a7bf62676446822875972867d5647e46c22e21099e5dd8e4114949b30b86146b0dba1b05a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401f2e86831349fa458c3e2403e2caacbf046fae3c513575e8ce2d34037d34337f7e58cc98cadf034e8bce930335285220624945b316fe6af71e8ef0d12ef05001ffa100d90103a100a11902a2a1636d73678f78264175746f2d4c6f6f702d5472616e73616374696f6e202336313138303020627920415441444160783c4c6976652045706f6368203234352c207765206861766520303132682032386d20323773206c65667420756e74696c20746865206e657874206f6e6578374974277320446f6e6e657273746167202d20313520466562727561722032303234202d2031333a30313a333320696e20417573747269616060607820412072616e646f6d205a656e2d51756f746520666f7220796f753a20f09f998f783b4265206b696e642c20666f722065766572796f6e6520796f75206d656574206973206669676874696e6720612068617264657220626174746c652e68202d20506c61746f6078374e6f64652d5265766973696f6e3a203462623230343864623737643632336565366533363738363138633264386236633436373633333360782953616e63686f4e657420697320617765736f6d652c206861766520736f6d652066756e2120f09f988d7819204265737420726567617264732c204d617274696e203a2d2980"; + let versioned_block = VersionedBlock::from_hex(versioned_block_hex); + assert!(versioned_block.is_ok()); + + let unwrapped_versioned_block = versioned_block.unwrap(); + assert_eq!(unwrapped_versioned_block.era(), BlockEra::Conway); + + let block = Block::from_hex(block_hex).unwrap(); + assert_eq!(unwrapped_versioned_block.block(), block) +} + +fn versioned_block_round_trip_test() { + let versioned_block_hex ="820785828a1a00101e2c1a0143a1b35820cee15d6daecaeaf320a4ddb1f7c437846f798e4a9cd08d12fb7821b175c980115820e3c87f196ce9fc40a8d929f3365e247f8f71e1981bffaa7cbdb0aa3a83dc790d582054a580ddf99f67818e0312374cef1f7dcdd59450930898d4d2d10e606b963e49825840ca5d1f988222919982b6a20f4f54ce59626fece7d7c607487762129d5196c731bcd11dfefee94ce5a60a733478970631d41bfc0620769fa7b66ebc16c8a89e5c58502855f21ba12fb101d175c376e19496e464bf37c92ec21395e5bffb35e1ae8f433f2139de166161f2b2b26afe656d3d170acfd11a535a80fca6325479d2262e208b0a4b98a01f4845c45a58fb84cb58011952de5820f2e4c6554da5b773c3f7889944fdb5b1791f8552dcafe2916041a531860e912284582039b66a10f6b78c541ea5ed6ecec4c6dd385b869026ec16c4e48414cb39cac38b0018a258409ccd6cf71a5c337f71a41904c0ea0a889a2321c94374c3a8402d8a7dd25b222abe6cb325c6b39bd63bc99fa84c094fdac2523b72f1a22081903dd047be9be9078209005901c006b35937aba451d4738486ea3ba5644d9306651f09b2012de8acc5136771fc725164ad669dd716f2726dfe138137d09feddf9450b3c51a601577bff35d0d2202c887a260855dd8310fc9365f56a4757ea7d81103d409ea0a8ad51c6ae52fc7fcf4d3d456384b7566b70a2b7bd4e21010a1ad5df12bf5d332e82c1a4a5cca39740252e0ea163f206cacf193e59ebbd0e20d621fa9913c60efe1c035d8ebaa354fbe45768339d53a4e8e04fdea79d00b869a973cfa3eeba2e2668b1dee5fcd7d13762dceb4da804fd749e5fa977ead0003a9739837aa68b80bc5a32ee015f667574a7fbe03b4bf5b027c945fa4497c01efb4ec51f3da2fb2dda33ea7dc1dedcfd2ea2c0a4da5a1c553d033033f4986e2ef5c09bbe326a25e5082c1eec406aeec8105869a9d46a83689a2e026e6e31d4037e700ffeb2920bcab88d1a400976881d17cd84582521482db0be460fb43de88e40a4ee24745ac92ab8b40329bde1d855404478c9f59b05e6322f3640ad6f40d7a771fc6d58e94f8fd0006d54272e36a30034b14327c2e6ffb92ead2f8a4165a3e4a1c44de677829e8e797547b3c0bac4b5ea89cb86c01d5b1e67aee3ba36b8cf9617484db2e4d1bfc37fed1fabb73ce3c9fa600d901028182582088c310befd2e8c9b33b340a56f4ea8141689c16eddef5d9c606055ca35897bd600018182581d6052e63f22c5107ed776b70f7b92248b02552fd08f3e747bc745099441821b00000001f09cac72a1581c34250edd1e9836f5378702fbf9416b709bc140e04f668cc355208518a1494154414441636f696e1916d6021a00030739031a0145283409a1581c34250edd1e9836f5378702fbf9416b709bc140e04f668cc355208518a1494154414441636f696e01075820e2ea39e82586fa40304df3c2cfc753c6ba8aca62e780f01a0519c34c6d7c25f5a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe185b0181a2005839007ce8986f5f3fb526a6d35d32edac0b6c8624daab6928df1964459c2723bcf2892e8182a68e3aac6f9f42ed3317d115ebad12a17232681175011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe185c0181a200583900f7fa5ddf2c3c46ed4d913812d38dd43d585adfa884938adaa7a075dd1bf1e138f2f8beabc963c94cc28ee8ed4b41744601f2edaf50b21efd011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe185d0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18600181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18620181a200583900189f009d9536b1f52f0629bea3323f48df0eacdff68726f1a32edc49db89995ed3aa88dcfb43790e2e51761fcba7e8594bcc67684f52d524011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18630181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820a944bb37a59451f9a47d5c8888a8a1145527ffb5d45a17c1df40926a42ad08330001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a400818258206a7e3a926eafa74f72c0d6a721dfdee7a7202b1fac4eee12d8c6dd030217890b07018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001eeb2890a021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18640181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820a439638a9f8e0f52e153126e8b794b7514f3a0921b08b611f3866a1fc75b7a560001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4010181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4030181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4020181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4040181a2005839002b11f0e68a65cd6a243f1a5ec9d597ba972675a00bd3172a7ddc0293b1d312a60b3824d1820dec5ec769c4af7d7598387c16ca5ba6259f46011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4080181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a400818258203298fb7878ab004c1a4b369eae7fc89abca6342f06557cebf6c89f2d8c21aa9900018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001b3152865021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a40a0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a40d0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a40f0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a40081825820dcdbb7a98286f5d48673c95b05f441bc40731b1e4c3429d192f0c6b7fc3749d100018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000002186e835b021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4130181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a300818258207e4fddb60c2034bff37bb7069f9318735fcf4de03e01e9f92251c96dc59318750001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a40081825820705ab68071f9af1d314e74a053e39a52f3fdf96f9a1280dab30d45f04c05436d07018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001eeb2890a021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a400818258206fe0c3eae23f779b0694747ed28612f47271b45e84bb3d23c11c1ef2e90fa12100018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001dcd122b6021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4150181a200583900e698ee1c7d4361c6faf62716dca0d435eafd0b25e369a5d68455beaa0f5c16e3e747e7c5a9eb3ff189c0e330683665de9326d2ffe35d0631011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4160181a2005839005bed6070c549f1560cb89361564cd2be7b36536e8da868a218d514e5fd2e3e48dbc0278cc58e47ed50a1ba90cee61ab22c8f4a639c913d4b011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418180181a200583900ab3cd541317d83d072bcc38e1294166dea5d97ce453424b84c547cfc101c5bfa799985a6e96adbb5859e90cbe4a0e4edcbef408a3622558b011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4181a0181a2005839003b3ff2a2d98519fcf53c7abb15b6c4dfe76209c52e4c2065b33b97bc465f9e3a6c6c3a8eac01d39f519b9bf3bc031480936156b7cb2e45c8011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4181d0181a20058390050fc315c9c141b4da62b10525cf5049e8ab1bb8bd96903a6d87c5272bc616bee900ed3135eb065a11faf2100670f0182ae86827df52dba96011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4181c0181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418200181a2005839005deef04c1b44c606775db03444beae0f10c75f437c131628d264b17c439dc3dbc39b8bb91832384d44263001591fd806df73b413da861fd3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418210181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418220181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418230181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418270181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418280181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418290181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4182d0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418330181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418340181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418350181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418360181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418370181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4183a0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4183c0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418460181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418470181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418490181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4184a0181a200583900189f009d9536b1f52f0629bea3323f48df0eacdff68726f1a32edc49db89995ed3aa88dcfb43790e2e51761fcba7e8594bcc67684f52d524011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418520181a2005839005c85eb9c0aa544a6bb5d1577c7a588c39caca885c8a3a9fceb0933a2cd1a02667d16df1e109350555c325023dbfa31fd9a4a8b99ff904d96011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418530181a20058390030a33756d8cbf4d18ce8c9995feca1ea1fc70093943c17bd96d65fed0aed6caa1cfe93f03f6ef1d9701df8024494d0b3b8a53a1ee37c5ab2011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418540181a2005839001da17fce0b5ae3e7feae117785eb78c77b6272be34a3d381a2722154d29c294b138005ca78de7b329ed6d2763a74a3fa1710a403e18fcb4a011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418560181a2005839001da17fce0b5ae3e7feae117785eb78c77b6272be34a3d381a2722154d29c294b138005ca78de7b329ed6d2763a74a3fa1710a403e18fcb4a011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418570181a20058390098bebc68cf6f12a7aca6531cef75d83c1b6e323485146195ffdd727dd99bbe7f44fd382de2ca6d9e5e9cc26f940decdb1b12b1a98e343274011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4185a0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4185c0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418610181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418620181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564050181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564070181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d00045640a0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d00045640b0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564181a0181a2005839005746c1b032f826b5e5256357a713a7ca63988fe2ff862e0396993b97ef0cbd5199d0e460725b3e79d371deb42110d40b778d3bf162777d4c011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564181b0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564181e0181a20058390020de866f290f45141315081d903f3eb3c06f3735e2a5b70f6a138462ada99823bc02291029853dc5338bc6e62b0540dbea54d9384f372639011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418200181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418210181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418230181a200583900057fd21bf903c585ea95dd927dee373b4cc1febc61874c48571dfb88a0a307af2a3e6a55a238fe323f9e54be10c54a8a8b25939a4f9ab35a011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418240181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582043c59e533d0934a6878a81403ec71a2225bb22d0764471cac8b5545120b475760001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418250181a2005839008f221a3021b0c09c57336733b0411d9d664e5d5e259096033a9d4bbecbce4335fa28195472386e53f0c3ab74d5cd254797d1100e4b1a33b8011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418290181a200583900d804dcdd0b0ec6ed0d8d2cd210a03b14f87c6849024930a8d6c91cf551a6a756817f0a3e1a1410730acf27202e7a9b63de26087e5cf466a5011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182b0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582072af166d0cd8883c9abb1189ae93acb1fce482ca57cad9b14711bca9627b98d80001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182d0181a2005839001c4595c4f3180180c9e822f1ac0f2955dd329eeeb94752a84281ff5295558528c6e1f7f2e16d94b74d227b9fd709edd2aeb0ab1556db75fc011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182e0181a200583900c008dd489b67e0a774fe18d79ee8d1e280264933d3b31ba44cb37755dca94fb45aa2192ab26eff8409ea010fa2d4761efa92437e0d5b6b60011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182f0181a200581d60fc38cce3448bf3d2790ca85d6b09026f7c86f21095c31f9925cf49a0011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418300181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418340181a20058390023a6fcbc8affc61518cff034c013aecf083dc64fe673ffc95cc9fd9e1fad7e0b1d0dd8820703a4f59c2488d148193a48d8fdc23a6dca8137011b00000002540be400021a00030d40ff9fa200d90102828258201287e9ce9e00a603d250b557146aa0581fc4edf277a244ce39d3b2f2ced5072f5840ae4cc1168265e2f60fec9ca9b644eaa42a77e65a39176e04aef29b01e25653a307d39ba61761f8d1ca44696e1d6bdf7a0679413ea3c448f76268e6eb02074102825820742d8af3543349b5b18f3cba28f23b2d6e465b9c136c42e1fae6b2390f5654275840112c95c93013e63fa73ee6a645fd522808d4dee019626e395a8042755c15fb1824e1503c17ea843a838809f55822366b05bce2e378d0b955e66d625c8e9acf0001d90102818200581c45d70e54f3b5e9c5a2b0cd417028197bd6f5fa5378c2f5eba896678da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584005383334e98e9263b93ffeb3e5908dbd5657caa67d32f9964d7f91dbda76fff164cbeabb981beef470d0d3e1724b85847e6fbc1c039084a817110eabf9d29e08a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258406151f0d0cae4ef0ace62dc03300dcee276765c1b493ac61f770d0633f0f71fe0d642ef29b593c511034a847dd569c56a0278e063c46d6d060abad4e6baf4b705a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840cf518f30d291871a0277e367534557205cc015d3a0d78070e1aee298aeaae3e81d70b42c464a63fa741b5300b48c1699dfc39fdf07f96b8eb240c7d6d3267805a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584056185de4c1d012d322e7e82ae98f24887ed7264f262db53f019e5900b9110a439e5a462a75be036f9f04b0ddcf09decb0894c7b6b9ff17ab4cae8184072d690fa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840ab78c606155b6aacbcf6692a18d97dd8773b4ae4c96684e4abb9cc59233023f67650ef7259069deddb65ba770ac3a1401d169ce33ec9483b8ebb9e83472e2c06a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840e21574b02002efcfe81382326aa98a0a971327ad4049690a04985400fcb14db7adc8149a0ce4dbfb5afa0d240ed9da23f15c1020d2826f50fc579a10a3662d0da10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840e64e3c19644edb6e788112ac75b4426ef94d535f1ffd9a34e86745777feaf083dc8e847a62634fef320a08b566c24ea26e8dc9e7b49fc456554215cedc0d3508a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840f49fd8eeaa366873aeb2530b2bbcbf7c5970866162ae7250c4b913e19062de1396ed70d1e32a4605071bac11c2cde3fec1dc5b37044cbea073668fe5c478400ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840f0ddd023e0dbda32d296b359db809b0088246e512fd34c7c0cc4b5ae974361873e02330e955eaaf97117525bcb3cd014bb70810f8d0d62a28c3242c86d8c3a08a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840615ee0444f039f02b26791872d6cd5562728cdc6dad02acc71475567b09f3d4b4655c601bf816ef6d11b2f3f81eeb6db09d800bf1bf4e2daf29493338c232901a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d62bfd428359f4cd04950cc73f574f0ec1c613284fdff8028ed3d876b18b69335beee9792410c6dbdc1b196b4703f250fbaeb66569869ae97d7ee843b9053405a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d813a836cc44c70647b2e7941fb72a4f720f16aca17e155a6c6a6f9bf175b1e49a3beff6edcfb0c442cc24790a12ee0b1d499a32fdbfc0a850f4846708ea340da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840aae6ac20cd419eaa7f3a95144f9ccdb46401a0db295d544e920a54b5c24fb63197fde03f12174800c3cf5318a73d92ebc53c2ba97803766892add32fd9feb400a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584071d223fd255df1e912a9c0a8230ee9f0ac95d0aa325cd31e50701ac355dfb5f3fbb27983b372c1410156eeba9163aa0f8a9787dab8c44e7afd4e2d07459a4708a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840b7f821c0ff66fcbbe7c61f43725aa2234297d6765e002d0130301cba13465fe89f59a596549725542445c76d17cedc9c9cfea8b8862d41405646d725dabc7d08a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e4584045830e5de108b9353b0c4c561af296e79eddb26b8ccfb18c5bd9fac1baf8d477691229c0bb9ea212ab56d9ae76c92de6ae50686fc0619510b8c35fb69c6b4402a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258400635ac784fe71d2f7927114edfc709dcb56013617df4edb9b6b770b067e7709e8abfd4cdcdd61512894fcf02f16e1d72bfe60fbfb86b815631d791bab132b909a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584032d67fe72feaf2175455815bbb624ee1b93f5efce905280158db94bbb2b5371d9eaff1bed6eddf9eafe8ff64b55f1d7213294bdb459e0b00c437edbcabf4cf07a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258404533de52e9e3f51e39951c9e197f6900081e98f38f3af5c4a7fe9219f8c311eaa43942b7a290ecbbbdd0bf4ef4ef1d11c39e6de4083c86892a6026c27bcf2509a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840d46541920ce2c31ffaa00cb20e8f5f00f48b6b8aa5cda67d22ea4bf12fd318461a0d8c25ee04cd7446e18f0de59b0fd4f6631e29bc8207073f2404793ae5f108a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584041bcd52ae44a3ffaa1abe1cab6c8b21f8010e2f1aee1d8651b9f6e94aabf5b2dbcedb45dd154b78dce1c5b9679956dd25153a0d945d3eb83c1de3b713e721008a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840027da3169c9c1fb9a67104061698bb0dadb2f58b660af4b461e7353fab1545a3d03157e077a388ec8556176239df3241255feb1f13b5e406bf7c3ad3af7d4202a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e458401ae63dc54e511965f7010971de7fb99585afe492cb8084b395ee01555c1e5657ab08a24be0f70d4e9cd1bde2a6ae31815c5f64025c0415afe2d503b2cb5b3e0ca10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840d2211679ca8e9cc5de71b21bac2b58fd355f5cbd2b42ff31ec37af77b776fb77c64fa76a830f240c29a4b95ae6bff9c58fc6bc2b3d18b57a2af11710ae6e3006a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584084bb7bf64ecea446d6beca88bfa2c7de71d8899e96006920c4c18e52f042aa71e1d27e60bdb6d9d6b1aa2e3330f59ee95b2c001909ff8994ea1fe4e5cd7a760aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840c6f3d6194a2fdb2a50417f80dd020adf866c91a102f22eb6bc66f5131292a1a42e9a3550e18e06cb17bd153c08f55a6cce3a1c82052ec9197495900f3ca4f407a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401a28cac7e80a657563e1433459f369bb0cb05e7e3ead78378dfc2ad15baa344e76e1ac0ca631c67848e81896fd6838b3821961928911635ca069f12c05772a08a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d201ce4ca5572db792d1563ef3614f2e2b27072e4751327f4a8f75201183a189ac57cdd9399474850e87031c7545c896ebab3983434bb6005690b9ad8fd9d50aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258403f45e44aa7457c714599f0100702ec265e91493e30c57ba4f1f74d912858bae8fb71fdf2faddf865c816cb0218eda0db17b707c8f429290f1a1c02b6a4450a0ea100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840e16b1d8f5992fda268c9d7e5c0ab6c5d38b8abaa6b92ccae5b0d2f3079d098ab67ba9a15b27807746f3c7695091ec5bb74ba8772baae14d2786eb8a512d70201a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840628a5491c5d0b4e0202b7aae87a343afd642345b823252355f6d392d8398d2174c141622e3de167b4f82c3cb8b4e8105b341851005d2ec0c1e35c354006a910ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258408ad2ee919f520a903764e0322800f7c086f870374f063d2e62ad1dfbf54e71305d90371abe3a196132e123b9248281f2d676fb29442f80249f644ce1185dfc03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d53bf84fe8712171151bb6d5f988d76428292639737d817986b46d629aea6eac2a90675cbf0347ec004ce23f9ca0b2dcff5c6d1be91ab478634de8ba8ab96102a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258404702623a2a94b9efbc03dc7d506c4bd70c1e0fea8b21f3b76c592883f0c364ffc12215e59f9ea4d2eed2e786376e6128650b4c9c3f6ad9419f070fb458efa10ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584072bb89ee81a7bcc4a866ae498d3ca076d5d5a885547c7f5899b8b59b3077310f58df420e470bf36d4ed5beaaf30eb361f04ed578cdbd0ef04f7cb573f0c0770ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840e112bb46921840820f4d5b40ec45699bc1b818ca8fe77fcc222a6fa1edb2425487f32e2039e2cf6077ce1e8e2e0b0d0581c64fb866c1c183344af131ccb9390ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840039329e261d8386f81a28f5ef5062196a46b5d4389b06bde97e662f69e37812c3ee75352f392121f58e76e5c1e1649656632b01ea46f932ccedcee102d625001a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840c1dab5e2482101ad1bd04f4018425c7133171aaf1274573ed35305f4e37bddadb3636f0aa098d2c0b5f615e8eb629bb94afac5d4c4c0743dba16a847d898b905a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840abb898b3e1ae3c4c9d068a4517b83a070d4037f979b6365ea5eb368e7d43b3fd2152fb93a462fdc553f973d90ab136332057fb66ea529d4fbc53e7f082b6fe03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258404a09ccfd9c09c6a453f46c721d280065081d89aa4b84fc809d75db1b923e78963bcbf36d64786d8c09c527e90da744e83116617b2e18d9145bac6cf66f876c08a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258408df2408adbd8b4c990a913b9ed2455c9de72d561ddb8f3ec0da5d1513f417a2fcee9ea9ace30cb840d37950c41455bd3655d12d534b70a6eac7034950f821108a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840534b54cc145722e3f7a62935d84c025e17e31c4b08d3f3fb16bb7673d37e9afb07fbdb5ffce5aeef743376bac161973e565e1c12db97bcd879cd7e9030c2a00ea100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840664fd5d8bc5d93509d02104f39e7a22c6cd894f49935cac9e662a9202b9a64baa9f55cd8aa07d3d1e095e9b974c59c0a8c50d14b0d077d70e236ad5cf52ac104a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840469cdadb48349224303d14980cab5c2ae5dacd0f6e36714d8dcb9ca85fa4eb688bd7b1334e30f8718178f7f36d8c5b204e0f9cdce5f88762fc2cbe2cb28c1d03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840f330820de229a476e1b3f84dfcf9ad98264070212e6e2d61d8b05afb1e12a1426cfd7cb0b284db237d5882cecd6e8f1fe2cf9ddc06783242812178bcb053a105a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584066b89001a28583bed59dbd07d359333207eb74d39ee092c0bf1da4351da64d38c9938a3682bb52a4253dc76074767b4cc2bc1eb2a31bbe6be3c45a5c52cbdf04a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840f365b299297ade5117d72156050cb81a76ba0b859cb46d0f2326c4071110440108b20390f878ba082d41217b2a8fd5f1435b9ba48d176ad5dcb6faff54976b0da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258407fb0b1f28d6ca64a29c6c7a51a2ab3436809b5038c06b8204104e3b98afa915246f742e2f1bd569f5132d2bbdcaeae68215a0b0f17f6367ce4eea37ed951ec01a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258406e6d2263c440486fc1b3c2aa930e519f20b70f70c28cb532d031f63cefc55c56f4647b10dd6390aa0d0f2ba75bf6cbe3ce2fc6d928dc4db74388f1e5e3057b0ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840dbb299923c24a70ae10dc637d862b750b3e6548e64c590674d2ceb87b7535199ea8dfd024694d26ae1dbbca683b1a4ba90af7d1680a9b8e4819a2ee6229e2408a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258405b2397d031c48f56b43416daea99dd3d8bd1733cb83c2a688dbe8b5dd9bfe64d596280d71973d7d540e929262dafd79b14954b855635fe845642090241003503a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840482c9089f2d60eb069432bf7f7213178a6fe3d52d37a4fa5aec677875bccdac64de7a45c6eb0bd4996414412b12d3e887a1b391e775ef56c47d53f9c944d020ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401972d18c1e9c62837121efafddc2ec778a3a8f9ec5f534c9922778905d8f809609d6c92e427852d8b5f822ad590fdeacf3877c8056f0768b44b025a2b79e7704a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258409b7141b69a493bc4d597a645ed488325492772ad4c3cd5c5c7805a5d951a4b6ed960ea27428d1add867fe7c209f4e65000bdfa878bd7a4357b223e9c55af450da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258407ac2d7823887de83bca86216e424ccb63fe9f4fa1f106bffc6afa388e91845c97177c410f1a8ca5ecd9f2701c42f5f9dd2faeb0ecf2163a37521badc8a6c1b03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840c49b6714ccbbdebebb9461a2efb39b9ac5e00a389aadfb2a1b4fe384733610c45e1f03825f65e182988da97659a71e378d49d17fb93d76b80d579b7d49399b06a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840b53ea3508cbd7da47fef05e98c0b31b13ec33de4596ba4061a8e04d91b1015c49f328da58084a6f573d93cdb7aa0972a1a1936a69ee7362adf65df3eae4e2400a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840b1c6b15b311423aa83dfaebe118d1a2a3ff006399f2a63fa82f0d0e0c12bc2b844ec78f5bc8baeef588d15b2237db48cbfa48361a6d630052c9b68e62e035601a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840bb544721cd95655497375390da19fbd87b3c63a4edf333688e2fee7935e96b6572f84b81d80fee5239062be6d3c6a75a5f0c50696d3c6663d26cecdfd8fdc808a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840a7018dfacec705459856bc706b7d05d04c56867fb64dfd0cf97fa980e881cc609e91cf6df204fb6906f860e5cf390e0290d302b6231664aad8c2b4cb30090609a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258403ddf27cce21fbf1a361233d2bcff92ecc9d3cce64c3d8186495e3509b843a0a326f528be8241b8557bf3cdac9c304fcf0fa8fd2a8e389d6acf9fc62b5626d705a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584013bd40ae7383feb674c2cd3357122aec3f6efe17b9b4f25c47cd3dfec194d0c4f20a52cc30fb92245c1a20a962772808f3dc6ee51261c86af16879a1fed2210ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840a1cf100aff45ee45c0f868214187640c8c29cb005c7aab7100ff86338d78f972733a611b4e0dae436fe9e1493d6ece69c35ada3cc6506e730ea1bae277468108a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840667d6d2987788454c41f2e86867fe98e1fd48aa789fbf9cf2208f927a8f9941d0384ebf3e3e45ee80c49934aad9b6ccaa13179b69f35b9acd21b55f56caff80da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401cd5c48fa46d8f0fb07c7737b7719d1fba5729478be3eef3e2e19942c4d6d54b01a569eb34d4f4be84a2f6961832ec17bade0511cbc01f5db5749a09bb4d8808a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258403bb5ddd91b5f5d7366b41330bf5bbbf7cf7d703bd50376ac21b07c6da696562266361678c06247a57111c63bc1fe58463a8c125e0d117bdf05cd4fe57bb8b90aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840397067045ffe0cf7126a5f73f228e1bc8721c617ebb7c41c1bc2f7b6c8cc50bf2370bc1ee679bcb0581e11da1e186504f2e3f3322fddf40a1863067ffc5e2903a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840831f5ea5dd354f5a522e044b53aa1966d036871d5a3b7d2323e404996907a33aff5aabb9db22301064033045cbf14c91d29de84b8fbbb75683ff1cb51fd0920aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401e8cc65db39cb5e9d54dac50cda84c55fd2f989f667a11dc46521768ac2f46a27a70173a92e849ee621ebe3025d87088528e7450b8312d678b6249f5a124f70fa10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840f4835bbcf5459db0826e27ea95d3ac31f7bea56c0253716212ef421995c7546a963ac89dc6cffad75692a149372cbdeaa19a9dcd171ac423711e8d71c495d703a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258408039411659145a9fb3863b2ae2f3890009bf004332f58daa6662368a7378d215cc7f40569284d5b86c5a7be210cdcb5551633762b5a7d3f8ad2095a220fec609a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584002c9ec1d95d0464eba5f4a656d72b55a92a80078e83f2f47682729af0fc782a68f3f31db7c64018ae8fbd36c5ac72d5573357a7578359056b9d3f9a29467d80ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258406f176d0fdb8768aad902c8fc115eb797719ef62a93938d7f09bbb213a88d61294143ec1d508a2a450f0e16ab3e2ffb7e0ed4cd7f75b3f2ff9f70cfaa77764506a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840f4262eeb9183eec1e896b9be61984ed9d4192b38825ba1b560ea23fe6e3224d3c94f4cc64174c1d9166e665e1a1ff8f0c84024bb8b9068b853fe4ce683d96906a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840df64e327056e335f484582fa0e4188e62620968e955431fc3576da2c1935b15ec605bb5d738f5000dcdc022646f9545d6932c2c79611dccab116295ca03c2b04a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840132cce5cea5d8bf7e9b802e4477eff041ebe1c12a8b8658a42ae91727cbf4f39b0d23831c70923a68ad7a023092bcecb61ac6253fdd17be00cecc37a71301300a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840842ecaf1b907cb34799d78d6f35eb349a986559a396840aeba5f6e8dc7e4172c16bddcb1f926a21175531478773046e9484aeb4ca83c1cbaf25f5a4813afdd0ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840a417cdf9e02755e53d6061ce0c93cacb7de24ce33e3fda9ac3a85414a7bf62676446822875972867d5647e46c22e21099e5dd8e4114949b30b86146b0dba1b05a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401f2e86831349fa458c3e2403e2caacbf046fae3c513575e8ce2d34037d34337f7e58cc98cadf034e8bce930335285220624945b316fe6af71e8ef0d12ef05001ffa100d90103a100a11902a2a1636d73678f78264175746f2d4c6f6f702d5472616e73616374696f6e202336313138303020627920415441444160783c4c6976652045706f6368203234352c207765206861766520303132682032386d20323773206c65667420756e74696c20746865206e657874206f6e6578374974277320446f6e6e657273746167202d20313520466562727561722032303234202d2031333a30313a333320696e20417573747269616060607820412072616e646f6d205a656e2d51756f746520666f7220796f753a20f09f998f783b4265206b696e642c20666f722065766572796f6e6520796f75206d656574206973206669676874696e6720612068617264657220626174746c652e68202d20506c61746f6078374e6f64652d5265766973696f6e3a203462623230343864623737643632336565366533363738363138633264386236633436373633333360782953616e63686f4e657420697320617765736f6d652c206861766520736f6d652066756e2120f09f988d7819204265737420726567617264732c204d617274696e203a2d2980"; + let versioned_block = VersionedBlock::from_hex(versioned_block_hex).unwrap(); + + let nex_hex = versioned_block.to_hex(); + assert_eq!(versioned_block_hex, nex_hex); + + let bytes = versioned_block.to_bytes(); + let json = versioned_block.to_json().unwrap(); + + let from_bytes = VersionedBlock::from_bytes(bytes).unwrap(); + let from_json = VersionedBlock::from_json(&json).unwrap(); + + assert_eq!(from_json, versioned_block); + assert_eq!(from_bytes, versioned_block); } #[test] From 328e21885bc9e391007ed4e6aef61bf9c191272a Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 21 Jun 2024 15:01:56 +0700 Subject: [PATCH 281/349] move ScriptRef into separate file, add to_unwrapped_bytes function --- rust/src/lib.rs | 55 ---------------- rust/src/protocol_types/mod.rs | 3 + rust/src/protocol_types/script_ref.rs | 63 ++++++++++++++++++ rust/src/serialization/general.rs | 92 -------------------------- rust/src/serialization/mod.rs | 3 +- rust/src/serialization/script_ref.rs | 93 +++++++++++++++++++++++++++ 6 files changed, 161 insertions(+), 148 deletions(-) create mode 100644 rust/src/protocol_types/script_ref.rs create mode 100644 rust/src/serialization/script_ref.rs diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 92d8a88d..923b7549 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -930,61 +930,6 @@ impl JsonSchema for Withdrawals { } } -#[derive( - Debug, Clone, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub enum ScriptRefEnum { - NativeScript(NativeScript), - PlutusScript(PlutusScript), -} - -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct ScriptRef(ScriptRefEnum); - -impl_to_from!(ScriptRef); - -#[wasm_bindgen] -impl ScriptRef { - pub fn new_native_script(native_script: &NativeScript) -> Self { - Self(ScriptRefEnum::NativeScript(native_script.clone())) - } - - pub fn new_plutus_script(plutus_script: &PlutusScript) -> Self { - Self(ScriptRefEnum::PlutusScript(plutus_script.clone())) - } - - pub fn is_native_script(&self) -> bool { - match &self.0 { - ScriptRefEnum::NativeScript(_) => true, - _ => false, - } - } - - pub fn is_plutus_script(&self) -> bool { - match &self.0 { - ScriptRefEnum::PlutusScript(_) => true, - _ => false, - } - } - - pub fn native_script(&self) -> Option { - match &self.0 { - ScriptRefEnum::NativeScript(native_script) => Some(native_script.clone()), - _ => None, - } - } - - pub fn plutus_script(&self) -> Option { - match &self.0 { - ScriptRefEnum::PlutusScript(plutus_script) => Some(plutus_script.clone()), - _ => None, - } - } -} - #[derive( Debug, Clone, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, )] diff --git a/rust/src/protocol_types/mod.rs b/rust/src/protocol_types/mod.rs index f4820a96..6e98aec1 100644 --- a/rust/src/protocol_types/mod.rs +++ b/rust/src/protocol_types/mod.rs @@ -51,3 +51,6 @@ pub use numeric::*; mod versioned_block; pub use versioned_block::*; + +mod script_ref; +pub use script_ref::*; diff --git a/rust/src/protocol_types/script_ref.rs b/rust/src/protocol_types/script_ref.rs new file mode 100644 index 00000000..f8782ce4 --- /dev/null +++ b/rust/src/protocol_types/script_ref.rs @@ -0,0 +1,63 @@ +use crate::*; + +#[derive( + Debug, Clone, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub enum ScriptRefEnum { + NativeScript(NativeScript), + PlutusScript(PlutusScript), +} + +#[wasm_bindgen] +#[derive( + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, +)] +pub struct ScriptRef(pub(crate) ScriptRefEnum); + +impl_to_from!(ScriptRef); + +#[wasm_bindgen] +impl ScriptRef { + pub fn new_native_script(native_script: &NativeScript) -> Self { + Self(ScriptRefEnum::NativeScript(native_script.clone())) + } + + pub fn new_plutus_script(plutus_script: &PlutusScript) -> Self { + Self(ScriptRefEnum::PlutusScript(plutus_script.clone())) + } + + pub fn is_native_script(&self) -> bool { + match &self.0 { + ScriptRefEnum::NativeScript(_) => true, + _ => false, + } + } + + pub fn is_plutus_script(&self) -> bool { + match &self.0 { + ScriptRefEnum::PlutusScript(_) => true, + _ => false, + } + } + + pub fn native_script(&self) -> Option { + match &self.0 { + ScriptRefEnum::NativeScript(native_script) => Some(native_script.clone()), + _ => None, + } + } + + pub fn plutus_script(&self) -> Option { + match &self.0 { + ScriptRefEnum::PlutusScript(plutus_script) => Some(plutus_script.clone()), + _ => None, + } + } + + /// Return bytes array of script ref struct but without wrapping into CBOR array under the tag + /// to_bytes returns "#6.24(bytes .cbor script)" from CDDL + /// to_unwrapped_bytes return "script" from CDDL + pub fn to_unwrapped_bytes(&self) -> Vec { + to_bytes(&self.0) + } +} \ No newline at end of file diff --git a/rust/src/serialization/general.rs b/rust/src/serialization/general.rs index 5685ad26..61e0bc1b 100644 --- a/rust/src/serialization/general.rs +++ b/rust/src/serialization/general.rs @@ -497,98 +497,6 @@ impl cbor_event::se::Serialize for DataOption { } } -impl Deserialize for ScriptRefEnum { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - if let cbor_event::Len::Len(n) = len { - if n != 2 { - return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( - 2, - len, - "[id, native_or_putus_script]", - )) - .into()); - } - } - let script_ref = match raw.unsigned_integer()? { - 0 => ScriptRefEnum::NativeScript(NativeScript::deserialize(raw)?), - 1 => ScriptRefEnum::PlutusScript(PlutusScript::deserialize(raw)?), - 2 => ScriptRefEnum::PlutusScript( - PlutusScript::deserialize(raw)?.clone_as_version(&Language::new_plutus_v2()), - ), - 3 => ScriptRefEnum::PlutusScript( - PlutusScript::deserialize(raw)?.clone_as_version(&Language::new_plutus_v3()), - ), - n => { - return Err(DeserializeFailure::FixedValueMismatch { - found: Key::Uint(n), - expected: Key::Uint(0), - } - .into()) - } - }; - if let cbor_event::Len::Indefinite = len { - if raw.special()? != CBORSpecial::Break { - return Err(DeserializeFailure::EndingBreakMissing.into()); - } - } - Ok(script_ref) - })() - .map_err(|e| e.annotate("ScriptRefEnum")) - } -} - -impl cbor_event::se::Serialize for ScriptRefEnum { - fn serialize<'a, W: Write + Sized>( - &self, - serializer: &'a mut Serializer, - ) -> cbor_event::Result<&'a mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - match &self { - ScriptRefEnum::NativeScript(native_script) => { - serializer.write_unsigned_integer(0)?; - native_script.serialize(serializer)?; - } - ScriptRefEnum::PlutusScript(plutus_script) => { - serializer.write_unsigned_integer(plutus_script.script_namespace() as u64)?; - plutus_script.serialize(serializer)?; - } - } - Ok(serializer) - } -} - -impl Deserialize for ScriptRef { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - match raw.tag()? { - //bytes string tag - 24 => Ok(ScriptRef(from_bytes(&raw.bytes()?)?)), - tag => { - return Err(DeserializeFailure::TagMismatch { - found: tag, - expected: 24, - } - .into()); - } - } - })() - .map_err(|e| e.annotate("ScriptRef")) - } -} - -impl cbor_event::se::Serialize for ScriptRef { - fn serialize<'a, W: Write + Sized>( - &self, - serializer: &'a mut Serializer, - ) -> cbor_event::Result<&'a mut Serializer> { - let bytes = to_bytes(&self.0); - serializer.write_tag(24)?.write_bytes(&bytes)?; - Ok(serializer) - } -} - impl cbor_event::se::Serialize for Ipv4 { fn serialize<'se, W: Write>( &self, diff --git a/rust/src/serialization/mod.rs b/rust/src/serialization/mod.rs index 02ad09c6..fa98180b 100644 --- a/rust/src/serialization/mod.rs +++ b/rust/src/serialization/mod.rs @@ -25,4 +25,5 @@ mod plutus; mod native_script; mod native_scripts; mod numeric; -mod versioned_block; \ No newline at end of file +mod versioned_block; +mod script_ref; \ No newline at end of file diff --git a/rust/src/serialization/script_ref.rs b/rust/src/serialization/script_ref.rs new file mode 100644 index 00000000..eba19307 --- /dev/null +++ b/rust/src/serialization/script_ref.rs @@ -0,0 +1,93 @@ +use crate::*; + +impl Deserialize for ScriptRefEnum { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + if let cbor_event::Len::Len(n) = len { + if n != 2 { + return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen( + 2, + len, + "[id, native_or_putus_script]", + )) + .into()); + } + } + let script_ref = match raw.unsigned_integer()? { + 0 => ScriptRefEnum::NativeScript(NativeScript::deserialize(raw)?), + 1 => ScriptRefEnum::PlutusScript(PlutusScript::deserialize(raw)?), + 2 => ScriptRefEnum::PlutusScript( + PlutusScript::deserialize(raw)?.clone_as_version(&Language::new_plutus_v2()), + ), + 3 => ScriptRefEnum::PlutusScript( + PlutusScript::deserialize(raw)?.clone_as_version(&Language::new_plutus_v3()), + ), + n => { + return Err(DeserializeFailure::FixedValueMismatch { + found: Key::Uint(n), + expected: Key::Uint(0), + } + .into()) + } + }; + if let cbor_event::Len::Indefinite = len { + if raw.special()? != CBORSpecial::Break { + return Err(DeserializeFailure::EndingBreakMissing.into()); + } + } + Ok(script_ref) + })() + .map_err(|e| e.annotate("ScriptRefEnum")) + } +} + +impl cbor_event::se::Serialize for ScriptRefEnum { + fn serialize<'a, W: Write + Sized>( + &self, + serializer: &'a mut Serializer, + ) -> cbor_event::Result<&'a mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + match &self { + ScriptRefEnum::NativeScript(native_script) => { + serializer.write_unsigned_integer(0)?; + native_script.serialize(serializer)?; + } + ScriptRefEnum::PlutusScript(plutus_script) => { + serializer.write_unsigned_integer(plutus_script.script_namespace() as u64)?; + plutus_script.serialize(serializer)?; + } + } + Ok(serializer) + } +} + +impl Deserialize for ScriptRef { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + match raw.tag()? { + //bytes string tag + 24 => Ok(ScriptRef(from_bytes(&raw.bytes()?)?)), + tag => { + return Err(DeserializeFailure::TagMismatch { + found: tag, + expected: 24, + } + .into()); + } + } + })() + .map_err(|e| e.annotate("ScriptRef")) + } +} + +impl cbor_event::se::Serialize for ScriptRef { + fn serialize<'a, W: Write + Sized>( + &self, + serializer: &'a mut Serializer, + ) -> cbor_event::Result<&'a mut Serializer> { + let bytes = to_bytes(&self.0); + serializer.write_tag(24)?.write_bytes(&bytes)?; + Ok(serializer) + } +} \ No newline at end of file From ed55b45fe8372215e933759587b4b76077ba97d2 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 21 Jun 2024 15:19:36 +0700 Subject: [PATCH 282/349] update js flow file --- rust/pkg/cardano_serialization_lib.js.flow | 526 +++++++++++++-------- 1 file changed, 316 insertions(+), 210 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index fd6b3269..98e875da 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -5,6 +5,55 @@ * @flow */ +/** + * @param {Transaction} tx + * @param {LinearFee} linear_fee + * @returns {BigNum} + */ +declare export function min_fee(tx: Transaction, linear_fee: LinearFee): BigNum; + +/** + * @param {ExUnits} ex_units + * @param {ExUnitPrices} ex_unit_prices + * @returns {BigNum} + */ +declare export function calculate_ex_units_ceil_cost( + ex_units: ExUnits, + ex_unit_prices: ExUnitPrices +): BigNum; + +/** + * @param {Transaction} tx + * @param {ExUnitPrices} ex_unit_prices + * @returns {BigNum} + */ +declare export function min_script_fee( + tx: Transaction, + ex_unit_prices: ExUnitPrices +): BigNum; + +/** + * @param {number} total_ref_scripts_size + * @param {UnitInterval} ref_script_coins_per_byte + * @returns {BigNum} + */ +declare export function min_ref_script_fee( + total_ref_scripts_size: number, + ref_script_coins_per_byte: UnitInterval +): BigNum; + +/** + * @param {Address} address + * @param {TransactionUnspentOutputs} utxos + * @param {TransactionBuilderConfig} config + * @returns {TransactionBatchList} + */ +declare export function create_send_all( + address: Address, + utxos: TransactionUnspentOutputs, + config: TransactionBuilderConfig +): TransactionBatchList; + /** * @param {TransactionHash} tx_body_hash * @param {ByronAddress} addr @@ -130,79 +179,6 @@ declare export function encode_json_str_to_native_script( schema: $Values ): NativeScript; -/** - * @param {Address} address - * @param {TransactionUnspentOutputs} utxos - * @param {TransactionBuilderConfig} config - * @returns {TransactionBatchList} - */ -declare export function create_send_all( - address: Address, - utxos: TransactionUnspentOutputs, - config: TransactionBuilderConfig -): TransactionBatchList; - -/** - * @param {string} password - * @param {string} salt - * @param {string} nonce - * @param {string} data - * @returns {string} - */ -declare export function encrypt_with_password( - password: string, - salt: string, - nonce: string, - data: string -): string; - -/** - * @param {string} password - * @param {string} data - * @returns {string} - */ -declare export function decrypt_with_password( - password: string, - data: string -): string; - -/** - * @param {Transaction} tx - * @param {LinearFee} linear_fee - * @returns {BigNum} - */ -declare export function min_fee(tx: Transaction, linear_fee: LinearFee): BigNum; - -/** - * @param {ExUnits} ex_units - * @param {ExUnitPrices} ex_unit_prices - * @returns {BigNum} - */ -declare export function calculate_ex_units_ceil_cost( - ex_units: ExUnits, - ex_unit_prices: ExUnitPrices -): BigNum; - -/** - * @param {Transaction} tx - * @param {ExUnitPrices} ex_unit_prices - * @returns {BigNum} - */ -declare export function min_script_fee( - tx: Transaction, - ex_unit_prices: ExUnitPrices -): BigNum; - -/** - * @param {number} total_ref_scripts_size - * @param {UnitInterval} ref_script_coins_per_byte - * @returns {BigNum} - */ -declare export function min_ref_script_fee( - total_ref_scripts_size: number, - ref_script_coins_per_byte: UnitInterval -): BigNum; - /** * @param {string} json * @param {$Values< @@ -268,15 +244,40 @@ declare export function decode_metadatum_to_json_str( ): string; /** + * @param {string} password + * @param {string} salt + * @param {string} nonce + * @param {string} data + * @returns {string} */ +declare export function encrypt_with_password( + password: string, + salt: string, + nonce: string, + data: string +): string; -declare export var RedeemerTagKind: {| - +Spend: 0, // 0 - +Mint: 1, // 1 - +Cert: 2, // 2 - +Reward: 3, // 3 - +Vote: 4, // 4 - +VotingProposal: 5, // 5 +/** + * @param {string} password + * @param {string} data + * @returns {string} + */ +declare export function decrypt_with_password( + password: string, + data: string +): string; + +/** + */ + +declare export var GovernanceActionKind: {| + +ParameterChangeAction: 0, // 0 + +HardForkInitiationAction: 1, // 1 + +TreasuryWithdrawalsAction: 2, // 2 + +NoConfidenceAction: 3, // 3 + +UpdateCommitteeAction: 4, // 4 + +NewConstitutionAction: 5, // 5 + +InfoAction: 6, // 6 |}; /** @@ -291,41 +292,56 @@ declare export var RelayKind: {| /** */ -declare export var AddressKind: {| - +Base: 0, // 0 - +Pointer: 1, // 1 - +Enterprise: 2, // 2 - +Reward: 3, // 3 - +Byron: 4, // 4 - +Malformed: 5, // 5 +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 |}; /** - * JSON <-> PlutusData conversion schemas. - * Follows ScriptDataJsonSchema in cardano-cli defined at: - * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 - * - * All methods here have the following restrictions due to limitations on dependencies: - * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors - * * Hex strings for bytes don't accept odd-length (half-byte) strings. - * cardano-cli seems to support these however but it seems to be different than just 0-padding - * on either side when tested so proceed with caution */ -declare export var PlutusDatumSchema: {| - +BasicConversions: 0, // 0 - +DetailedSchema: 1, // 1 +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 |}; /** + * Each new language uses a different namespace for hashing its script + * This is because you could have a language where the same bytes have different semantics + * So this avoids scripts in different languages mapping to the same hash + * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 +declare export var ScriptHashNamespace: {| + +NativeScript: 0, // 0 + +PlutusScript: 1, // 1 + +PlutusScriptV2: 2, // 2 + +PlutusScriptV3: 3, // 3 +|}; + +/** + */ + +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 +|}; + +/** + */ + +declare export var RedeemerTagKind: {| + +Spend: 0, // 0 + +Mint: 1, // 1 + +Cert: 2, // 2 + +Reward: 3, // 3 + +Vote: 4, // 4 + +VotingProposal: 5, // 5 |}; /** @@ -339,19 +355,28 @@ declare export var MIRPot: {| /** */ -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 |}; /** */ -declare export var LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 +|}; + +/** + */ + +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 |}; /** @@ -364,35 +389,47 @@ declare export var ScriptSchema: {| |}; /** + * JSON <-> PlutusData conversion schemas. + * Follows ScriptDataJsonSchema in cardano-cli defined at: + * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 + * + * All methods here have the following restrictions due to limitations on dependencies: + * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors + * * Hex strings for bytes don't accept odd-length (half-byte) strings. + * cardano-cli seems to support these however but it seems to be different than just 0-padding + * on either side when tested so proceed with caution */ -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 +declare export var PlutusDatumSchema: {| + +BasicConversions: 0, // 0 + +DetailedSchema: 1, // 1 |}; /** */ -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 |}; /** */ -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 +|}; + +/** + */ + +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 |}; /** @@ -421,91 +458,68 @@ declare export var CertificateKind: {| /** */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 -|}; - -/** - */ - -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 - +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 -|}; - -/** - */ - -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 -|}; - -/** - */ - -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 |}; /** */ -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** */ -declare export var GovernanceActionKind: {| - +ParameterChangeAction: 0, // 0 - +HardForkInitiationAction: 1, // 1 - +TreasuryWithdrawalsAction: 2, // 2 - +NoConfidenceAction: 3, // 3 - +UpdateCommitteeAction: 4, // 4 - +NewConstitutionAction: 5, // 5 - +InfoAction: 6, // 6 +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 |}; /** */ -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 |}; /** */ -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 +declare export var BlockEra: {| + +Byron: 0, // 0 + +Shelley: 1, // 1 + +Allegra: 2, // 2 + +Mary: 3, // 3 + +Alonzo: 4, // 4 + +Babbage: 5, // 5 + +Conway: 6, // 6 + +Unknown: 7, // 7 |}; /** - * Each new language uses a different namespace for hashing its script - * This is because you could have a language where the same bytes have different semantics - * So this avoids scripts in different languages mapping to the same hash - * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var ScriptHashNamespace: {| - +NativeScript: 0, // 0 - +PlutusScript: 1, // 1 - +PlutusScriptV2: 2, // 2 - +PlutusScriptV3: 3, // 3 +declare export var AddressKind: {| + +Base: 0, // 0 + +Pointer: 1, // 1 + +Enterprise: 2, // 2 + +Reward: 3, // 3 + +Byron: 4, // 4 + +Malformed: 5, // 5 |}; /** @@ -1564,12 +1578,6 @@ declare export class Block { auxiliary_data_set: AuxiliaryDataSet, invalid_transactions: Uint32Array ): Block; - - /** - * @param {Uint8Array} data - * @returns {Block} - */ - static from_wrapped_bytes(data: Uint8Array): Block; } /** */ @@ -3380,11 +3388,6 @@ declare export class DrepVotingThresholds { treasury_withdrawal: UnitInterval ): DrepVotingThresholds; - /** - * @returns {DrepVotingThresholds} - */ - static new_default(): DrepVotingThresholds; - /** * @param {UnitInterval} motion_no_confidence */ @@ -6890,28 +6893,57 @@ declare export class PlutusMap { static new(): PlutusMap; /** + * Return count ok different keys in the map. * @returns {number} */ len(): number; /** + * Returns the previous value associated with the key, if any. + * Replace the values associated with the key. * @param {PlutusData} key - * @param {PlutusData} value - * @returns {PlutusData | void} + * @param {PlutusMapValues} values + * @returns {PlutusMapValues | void} */ - insert(key: PlutusData, value: PlutusData): PlutusData | void; + insert(key: PlutusData, values: PlutusMapValues): PlutusMapValues | void; /** * @param {PlutusData} key - * @returns {PlutusData | void} + * @returns {PlutusMapValues | void} */ - get(key: PlutusData): PlutusData | void; + get(key: PlutusData): PlutusMapValues | void; /** * @returns {PlutusList} */ keys(): PlutusList; } +/** + */ +declare export class PlutusMapValues { + free(): void; + + /** + * @returns {PlutusMapValues} + */ + static new(): PlutusMapValues; + + /** + * @returns {number} + */ + len(): number; + + /** + * @param {number} index + * @returns {PlutusData | void} + */ + get(index: number): PlutusData | void; + + /** + * @param {PlutusData} elem + */ + add(elem: PlutusData): void; +} /** */ declare export class PlutusScript { @@ -9299,6 +9331,14 @@ declare export class ScriptRef { * @returns {PlutusScript | void} */ plutus_script(): PlutusScript | void; + + /** + * Return bytes array of script ref struct but without wrapping into CBOR array under the tag + * to_bytes returns "#6.24(bytes .cbor script)" from CDDL + * to_unwrapped_bytes return "script" from CDDL + * @returns {Uint8Array} + */ + to_unwrapped_bytes(): Uint8Array; } /** */ @@ -12237,12 +12277,12 @@ declare export class TxInputsBuilder { /** * This method will add the input to the builder and also register the required native script witness - * @param {NativeScript} script + * @param {NativeScriptSource} script * @param {TransactionInput} input * @param {Value} amount */ add_native_script_input( - script: NativeScript, + script: NativeScriptSource, input: TransactionInput, amount: Value ): void; @@ -12260,12 +12300,12 @@ declare export class TxInputsBuilder { ): void; /** - * @param {ByronAddress} hash + * @param {ByronAddress} address * @param {TransactionInput} input * @param {Value} amount */ add_bootstrap_input( - hash: ByronAddress, + address: ByronAddress, input: TransactionInput, amount: Value ): void; @@ -12842,6 +12882,68 @@ declare export class Value { */ compare(rhs_value: Value): number | void; } +/** + */ +declare export class VersionedBlock { + free(): void; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {VersionedBlock} + */ + static from_bytes(bytes: Uint8Array): VersionedBlock; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {VersionedBlock} + */ + static from_hex(hex_str: string): VersionedBlock; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {VersionedBlockJSON} + */ + to_js_value(): VersionedBlockJSON; + + /** + * @param {string} json + * @returns {VersionedBlock} + */ + static from_json(json: string): VersionedBlock; + + /** + * @param {Block} block + * @param {number} era_code + * @returns {VersionedBlock} + */ + static new(block: Block, era_code: number): VersionedBlock; + + /** + * @returns {Block} + */ + block(): Block; + + /** + * @returns {$Values< + typeof + BlockEra>} + */ + era(): $Values; +} /** */ declare export class Vkey { @@ -14775,6 +14877,10 @@ export interface TransactionUnspentOutputJSON { export type TransactionUnspentOutputsJSON = TransactionUnspentOutputJSON[]; export type VRFKeyHashJSON = string; export type VRFVKeyJSON = string; +export interface VersionedBlockJSON { + block: BlockJSON; + era_code: number; +} export type VkeywitnessesJSON = VkeywitnessJSON[]; export type VoterEnumJSON = | { From ee2cde48cb61fc6f24b6b371749252a8d90294c8 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 21 Jun 2024 17:19:33 +0700 Subject: [PATCH 283/349] add test for RefScript serialization --- rust/src/protocol_types/script_ref.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/src/protocol_types/script_ref.rs b/rust/src/protocol_types/script_ref.rs index f8782ce4..8a0aa638 100644 --- a/rust/src/protocol_types/script_ref.rs +++ b/rust/src/protocol_types/script_ref.rs @@ -3,7 +3,7 @@ use crate::*; #[derive( Debug, Clone, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, )] -pub enum ScriptRefEnum { +pub(crate) enum ScriptRefEnum { NativeScript(NativeScript), PlutusScript(PlutusScript), } From 8b29815d1ca195281438644a9ce901ff60fb5a8e Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 21 Jun 2024 17:22:31 +0700 Subject: [PATCH 284/349] add test for RefScript serialization --- rust/src/tests/serialization/general.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/rust/src/tests/serialization/general.rs b/rust/src/tests/serialization/general.rs index 63303523..7ec13e4a 100644 --- a/rust/src/tests/serialization/general.rs +++ b/rust/src/tests/serialization/general.rs @@ -1,9 +1,10 @@ -use crate::{Address, BigInt, BigNum, Block, BlockHash, CborContainerType, Coin, Credential, DataHash, ExUnits, HeaderBody, HeaderLeaderCertEnum, Int, KESVKey, MIRPot, MIRToStakeCredentials, MoveInstantaneousReward, NativeScript, OperationalCert, PlutusData, PlutusList, PlutusScript, PlutusScripts, ProtocolVersion, Redeemer, RedeemerTag, Redeemers, ScriptHash, ScriptRef, TimelockStart, TransactionBody, TransactionInputs, TransactionOutput, TransactionOutputs, TransactionWitnessSet, VRFCert, VRFVKey, Value, Vkeywitness, Vkeywitnesses, VersionedBlock, BlockEra}; +use crate::{Address, BigInt, BigNum, Block, BlockHash, CborContainerType, Coin, Credential, DataHash, ExUnits, HeaderBody, HeaderLeaderCertEnum, Int, KESVKey, MIRPot, MIRToStakeCredentials, MoveInstantaneousReward, NativeScript, OperationalCert, PlutusData, PlutusList, PlutusScript, PlutusScripts, ProtocolVersion, Redeemer, RedeemerTag, Redeemers, ScriptHash, ScriptRef, TimelockStart, TransactionBody, TransactionInputs, TransactionOutput, TransactionOutputs, TransactionWitnessSet, VRFCert, VRFVKey, Value, Vkeywitness, Vkeywitnesses, VersionedBlock, BlockEra, to_bytes}; use crate::fakes::{ fake_base_address, fake_bytes_32, fake_data_hash, fake_signature, fake_tx_input, fake_tx_output, fake_value, fake_value2, fake_vkey, }; +use crate::protocol_types::ScriptRefEnum; #[test] fn tx_output_deser_lagacy() { @@ -782,4 +783,18 @@ fn redeemers_map_deserialization() { let hex = "a282000082d8799f0102030405ff821821182c82040082d8799f0102030405ff8218371842"; let redeemers = Redeemers::from_hex(hex); assert!(redeemers.is_ok()); +} + +#[test] fn ref_script_serialization() { + let plutus_script = PlutusScript::new([61u8; 29].to_vec()); + let script_ref = ScriptRef::new_plutus_script(&plutus_script); + let script_enum = ScriptRefEnum::PlutusScript(plutus_script); + let unwrapped_bytes = to_bytes(&script_enum); + let wrapped_bytes = script_ref.to_bytes(); + + assert_eq!(unwrapped_bytes, script_ref.to_unwrapped_bytes()); + assert_ne!(unwrapped_bytes, wrapped_bytes); + + let new_script_ref = ScriptRef::from_bytes(wrapped_bytes).unwrap(); + assert_eq!(script_ref, new_script_ref); } \ No newline at end of file From 5f31653e0581481715099cc821ee9dcc614ff1ff Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 21 Jun 2024 18:20:05 +0700 Subject: [PATCH 285/349] add network_id getter for address types --- rust/src/serialization/protocol_param_update.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/rust/src/serialization/protocol_param_update.rs b/rust/src/serialization/protocol_param_update.rs index 42b636e3..7399205f 100644 --- a/rust/src/serialization/protocol_param_update.rs +++ b/rust/src/serialization/protocol_param_update.rs @@ -526,7 +526,8 @@ impl Deserialize for ProtocolParamUpdate { n_opt = Some( (|| -> Result<_, DeserializeError> { read_len.read_elems(1)?; - Ok(u32::deserialize(raw)?) + let tmp = u64::deserialize(raw)?; + Ok(tmp as u32) })() .map_err(|e| e.annotate("n_opt"))?, ); @@ -682,7 +683,8 @@ impl Deserialize for ProtocolParamUpdate { max_value_size = Some( (|| -> Result<_, DeserializeError> { read_len.read_elems(1)?; - Ok(u32::deserialize(raw)?) + let tmp = u64::deserialize(raw)?; + Ok(tmp as u32) })() .map_err(|e| e.annotate("max_value_size"))?, ); @@ -694,7 +696,8 @@ impl Deserialize for ProtocolParamUpdate { collateral_percentage = Some( (|| -> Result<_, DeserializeError> { read_len.read_elems(1)?; - Ok(u32::deserialize(raw)?) + let tmp = u64::deserialize(raw)?; + Ok(tmp as u32) })() .map_err(|e| e.annotate("collateral_percentage"))?, ); @@ -706,7 +709,8 @@ impl Deserialize for ProtocolParamUpdate { max_collateral_inputs = Some( (|| -> Result<_, DeserializeError> { read_len.read_elems(1)?; - Ok(u32::deserialize(raw)?) + let tmp = u64::deserialize(raw)?; + Ok(tmp as u32) })() .map_err(|e| e.annotate("max_collateral_inputs"))?, ); @@ -742,7 +746,8 @@ impl Deserialize for ProtocolParamUpdate { min_committee_size = Some( (|| -> Result<_, DeserializeError> { read_len.read_elems(1)?; - Ok(u32::deserialize(raw)?) + let tmp = u64::deserialize(raw)?; + Ok(tmp as u32) })() .map_err(|e| e.annotate("min_committee_size"))?, ); From 59323e642e604a2b6156c37c4da4b5cd70f14d94 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 21 Jun 2024 18:23:59 +0700 Subject: [PATCH 286/349] add network_id getter for address types --- rust/src/protocol_types/address.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/rust/src/protocol_types/address.rs b/rust/src/protocol_types/address.rs index 174aea09..ac38d5ce 100644 --- a/rust/src/protocol_types/address.rs +++ b/rust/src/protocol_types/address.rs @@ -655,6 +655,10 @@ impl BaseAddress { _ => None, } } + + pub fn network_id(&self) -> u8 { + self.network + } } #[wasm_bindgen] @@ -687,6 +691,10 @@ impl EnterpriseAddress { _ => None, } } + + pub fn network_id(&self) -> u8 { + self.network + } } #[wasm_bindgen] @@ -719,6 +727,10 @@ impl RewardAddress { _ => None, } } + + pub fn network_id(&self) -> u8 { + self.network + } } impl serde::Serialize for RewardAddress { @@ -882,4 +894,8 @@ impl PointerAddress { _ => None, } } + + pub fn network_id(&self) -> u8 { + self.network + } } From e5d1b6717e118f336482db510c507c9c7bef6ce7 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 21 Jun 2024 18:24:58 +0700 Subject: [PATCH 287/349] revert wrong changes --- rust/src/serialization/protocol_param_update.rs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/rust/src/serialization/protocol_param_update.rs b/rust/src/serialization/protocol_param_update.rs index 7399205f..42b636e3 100644 --- a/rust/src/serialization/protocol_param_update.rs +++ b/rust/src/serialization/protocol_param_update.rs @@ -526,8 +526,7 @@ impl Deserialize for ProtocolParamUpdate { n_opt = Some( (|| -> Result<_, DeserializeError> { read_len.read_elems(1)?; - let tmp = u64::deserialize(raw)?; - Ok(tmp as u32) + Ok(u32::deserialize(raw)?) })() .map_err(|e| e.annotate("n_opt"))?, ); @@ -683,8 +682,7 @@ impl Deserialize for ProtocolParamUpdate { max_value_size = Some( (|| -> Result<_, DeserializeError> { read_len.read_elems(1)?; - let tmp = u64::deserialize(raw)?; - Ok(tmp as u32) + Ok(u32::deserialize(raw)?) })() .map_err(|e| e.annotate("max_value_size"))?, ); @@ -696,8 +694,7 @@ impl Deserialize for ProtocolParamUpdate { collateral_percentage = Some( (|| -> Result<_, DeserializeError> { read_len.read_elems(1)?; - let tmp = u64::deserialize(raw)?; - Ok(tmp as u32) + Ok(u32::deserialize(raw)?) })() .map_err(|e| e.annotate("collateral_percentage"))?, ); @@ -709,8 +706,7 @@ impl Deserialize for ProtocolParamUpdate { max_collateral_inputs = Some( (|| -> Result<_, DeserializeError> { read_len.read_elems(1)?; - let tmp = u64::deserialize(raw)?; - Ok(tmp as u32) + Ok(u32::deserialize(raw)?) })() .map_err(|e| e.annotate("max_collateral_inputs"))?, ); @@ -746,8 +742,7 @@ impl Deserialize for ProtocolParamUpdate { min_committee_size = Some( (|| -> Result<_, DeserializeError> { read_len.read_elems(1)?; - let tmp = u64::deserialize(raw)?; - Ok(tmp as u32) + Ok(u32::deserialize(raw)?) })() .map_err(|e| e.annotate("min_committee_size"))?, ); From 9e9cdfeceda4050bd4bafc19f23cfa6ed1dbb13b Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 21 Jun 2024 22:04:18 +0700 Subject: [PATCH 288/349] warnings cleanup --- .../builders/batch_tools/assets_calculator.rs | 1 - rust/src/builders/certificates_builder.rs | 1 + rust/src/builders/mint_builder.rs | 27 ++- .../script_structs/plutus_script_source.rs | 3 +- rust/src/builders/tx_builder.rs | 38 ++-- rust/src/crypto.rs | 13 -- rust/src/fees.rs | 2 - rust/src/lib.rs | 6 +- rust/src/protocol_types/address.rs | 2 +- rust/src/protocol_types/credentials.rs | 1 - rust/src/protocol_types/ed25519_key_hashes.rs | 1 - rust/src/protocol_types/plutus/plutus_data.rs | 4 +- .../protocol_types/plutus/plutus_scripts.rs | 1 - rust/src/rational.rs | 1 - rust/src/serialization/crypto/vkeys.rs | 2 +- rust/src/serialization/general.rs | 2 +- .../proposals/hard_fork_initiation_action.rs | 2 +- rust/src/serialization/plutus/plutus_data.rs | 1 - .../src/serialization/plutus/plutus_script.rs | 1 - .../witnesses/transaction_witnesses_sets.rs | 2 +- rust/src/tests/address.rs | 1 - .../tests/builders/certificates_builder.rs | 27 --- rust/src/tests/builders/mint_builder.rs | 8 +- rust/src/tests/builders/tx_builder.rs | 162 +++++++++--------- rust/src/tests/builders/voting_builder.rs | 4 +- rust/src/tests/general.rs | 37 ++-- rust/src/tests/mock_objects.rs | 11 +- .../protocol_types/protocol_param_update.rs | 2 + rust/src/tests/serialization/general.rs | 6 +- rust/src/utils.rs | 102 ----------- 30 files changed, 172 insertions(+), 299 deletions(-) diff --git a/rust/src/builders/batch_tools/assets_calculator.rs b/rust/src/builders/batch_tools/assets_calculator.rs index ec638381..dcc49055 100644 --- a/rust/src/builders/batch_tools/assets_calculator.rs +++ b/rust/src/builders/batch_tools/assets_calculator.rs @@ -1,7 +1,6 @@ use super::cbor_calculator::CborCalculator; use super::indexes::{AssetIndex, PolicyIndex, UtxoIndex}; use super::utxo_stat::UtxosStat; -use crate::utils::*; use crate::*; use std::collections::{HashMap, HashSet}; diff --git a/rust/src/builders/certificates_builder.rs b/rust/src/builders/certificates_builder.rs index eb30c768..c13e464f 100644 --- a/rust/src/builders/certificates_builder.rs +++ b/rust/src/builders/certificates_builder.rs @@ -131,6 +131,7 @@ impl CertificatesBuilder { used_langs } + #[allow(unused_variables)] pub fn get_certificates_refund( &self, pool_deposit: &BigNum, diff --git a/rust/src/builders/mint_builder.rs b/rust/src/builders/mint_builder.rs index 41d4e493..cc500e33 100644 --- a/rust/src/builders/mint_builder.rs +++ b/rust/src/builders/mint_builder.rs @@ -277,19 +277,19 @@ impl MintBuilder { } } - pub fn build(&self) -> Mint { + pub(crate) fn build_unchecked(&self) -> Mint { let mut mint = Mint::new(); for (policy, script_mint) in self.mints.iter() { let mut mint_asset = MintAssets::new(); match script_mint { ScriptMint::Native(native_mints) => { for (asset_name, amount) in &native_mints.mints { - mint_asset.insert(asset_name, amount.clone()); + mint_asset.insert_unchecked(asset_name, amount.clone()); } } ScriptMint::Plutus(plutus_mints) => { for (asset_name, amount) in &plutus_mints.mints { - mint_asset.insert(asset_name, amount.clone()); + mint_asset.insert_unchecked(asset_name, amount.clone()); } } } @@ -298,6 +298,27 @@ impl MintBuilder { mint } + pub fn build(&self) -> Result { + let mut mint = Mint::new(); + for (policy, script_mint) in self.mints.iter() { + let mut mint_asset = MintAssets::new(); + match script_mint { + ScriptMint::Native(native_mints) => { + for (asset_name, amount) in &native_mints.mints { + mint_asset.insert(asset_name, amount.clone())?; + } + } + ScriptMint::Plutus(plutus_mints) => { + for (asset_name, amount) in &plutus_mints.mints { + mint_asset.insert(asset_name, amount.clone())?; + } + } + } + mint.insert(&policy, &mint_asset); + } + Ok(mint) + } + pub fn get_native_scripts(&self) -> NativeScripts { let mut native_scripts = Vec::new(); for script_mint in self.mints.values() { diff --git a/rust/src/builders/script_structs/plutus_script_source.rs b/rust/src/builders/script_structs/plutus_script_source.rs index e5cdfd49..f52f39c2 100644 --- a/rust/src/builders/script_structs/plutus_script_source.rs +++ b/rust/src/builders/script_structs/plutus_script_source.rs @@ -1,8 +1,7 @@ -use std::hash::Hash; use crate::*; #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub enum PlutusScriptSourceEnum { +pub(crate) enum PlutusScriptSourceEnum { Script(PlutusScript, Option), RefInput(PlutusScriptRef, Option), } diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index 70ac1f96..f0ed13fa 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -447,7 +447,7 @@ impl TransactionBuilder { &input.output.address, &input.input, &input.output.amount, - ); + )?; input_total = input_total.checked_add(&input.output.amount)?; output_total = output_total.checked_add(&Value::new(&input_fee))?; } @@ -531,7 +531,7 @@ impl TransactionBuilder { &input.output.address, &input.input, &input.output.amount, - ); + )?; input_total = input_total.checked_add(&input.output.amount)?; output_total = output_total.checked_add(&Value::new(&input_fee))?; } @@ -569,7 +569,7 @@ impl TransactionBuilder { // differing from CIP2, we include the needed fees in the targets instead of just output values let input_fee = self.fee_for_input(&input.output.address, &input.input, &input.output.amount)?; - self.add_regular_input(&input.output.address, &input.input, &input.output.amount); + self.add_regular_input(&input.output.address, &input.input, &input.output.amount)?; *input_total = input_total.checked_add(&input.output.amount)?; *output_total = output_total.checked_add(&Value::new(&input_fee))?; available_indices.swap_remove(available_indices.iter().position(|j| i == j).unwrap()); @@ -691,7 +691,7 @@ impl TransactionBuilder { &input.output.address, &input.input, &input.output.amount, - ); + )?; *input_total = input_total.checked_add(&input.output.amount)?; *output_total = output_total.checked_add(&Value::new(&input_fee))?; } @@ -1032,7 +1032,7 @@ impl TransactionBuilder { let fee_before = min_fee(&self_copy)?; - self_copy.add_regular_input(&address, &input, &amount); + self_copy.add_regular_input(&address, &input, &amount)?; let fee_after = min_fee(&self_copy)?; fee_after.checked_sub(&fee_before) } @@ -1273,7 +1273,7 @@ impl TransactionBuilder { if let Some(script) = scripts_policies.get(policy_id) { let native_script_source = NativeScriptSource::new(script); let mint_witness = MintWitness::new_native_script(&native_script_source); - mint_builder.set_asset(&mint_witness, asset_name, amount); + mint_builder.set_asset(&mint_witness, asset_name, amount)?; } else { return Err(JsError::from_str( "Mint policy does not have a matching script", @@ -1295,7 +1295,7 @@ impl TransactionBuilder { /// Returns a copy of the current mint state in the builder pub fn get_mint(&self) -> Option { match &self.mint { - Some(mint) => Some(mint.build()), + Some(mint) => Some(mint.build().expect("MintBuilder is invalid")), None => None, } } @@ -1318,20 +1318,21 @@ impl TransactionBuilder { /// Add a mint entry to this builder using a PolicyID and MintAssets object /// It will be securely added to existing or new Mint in this builder /// It will replace any existing mint assets with the same PolicyID - pub fn set_mint_asset(&mut self, policy_script: &NativeScript, mint_assets: &MintAssets) { + pub fn set_mint_asset(&mut self, policy_script: &NativeScript, mint_assets: &MintAssets) -> Result<(), JsError> { let native_script_source = NativeScriptSource::new(policy_script); let mint_witness = MintWitness::new_native_script(&native_script_source); if let Some(mint) = &mut self.mint { for (asset, amount) in mint_assets.0.iter() { - mint.set_asset(&mint_witness, asset, amount); + mint.set_asset(&mint_witness, asset, amount)?; } } else { let mut mint = MintBuilder::new(); for (asset, amount) in mint_assets.0.iter() { - mint.set_asset(&mint_witness, asset, amount); + mint.set_asset(&mint_witness, asset, amount)?; } self.mint = Some(mint); } + Ok(()) } /// !!! DEPRECATED !!! @@ -1349,16 +1350,17 @@ impl TransactionBuilder { policy_script: &NativeScript, asset_name: &AssetName, amount: &Int, - ) { + ) -> Result<(), JsError> { let native_script_source = NativeScriptSource::new(policy_script); let mint_witness = MintWitness::new_native_script(&native_script_source); if let Some(mint) = &mut self.mint { - mint.add_asset(&mint_witness, asset_name, &amount); + mint.add_asset(&mint_witness, asset_name, &amount)?; } else { let mut mint = MintBuilder::new(); - mint.add_asset(&mint_witness, asset_name, &amount); + mint.add_asset(&mint_witness, asset_name, &amount)?; self.mint = Some(mint); } + Ok(()) } /// Add a mint entry together with an output to this builder @@ -1377,7 +1379,7 @@ impl TransactionBuilder { return Err(JsError::from_str("Output value must be positive!")); } let policy_id: PolicyID = policy_script.hash(); - self.add_mint_asset(policy_script, asset_name, amount); + self.add_mint_asset(policy_script, asset_name, amount)?; let multiasset = Mint::new_from_entry(&policy_id, &MintAssets::new_from_entry(asset_name, amount)?) .as_positive_multiasset(); @@ -1405,7 +1407,7 @@ impl TransactionBuilder { return Err(JsError::from_str("Output value must be positive!")); } let policy_id: PolicyID = policy_script.hash(); - self.add_mint_asset(policy_script, asset_name, amount); + self.add_mint_asset(policy_script, asset_name, amount)?; let multiasset = Mint::new_from_entry(&policy_id, &MintAssets::new_from_entry(asset_name, amount)?) .as_positive_multiasset(); @@ -1610,7 +1612,7 @@ impl TransactionBuilder { self.mint .as_ref() .map(|m| { - let mint = m.build(); + let mint = m.build_unchecked(); ( Value::new_from_assets(&mint.as_positive_multiasset()), Value::new_from_assets(&mint.as_negative_multiasset()), @@ -2173,7 +2175,9 @@ impl TransactionBuilder { .as_ref() .map(|x| utils::hash_auxiliary_data(x)), validity_start_interval: self.validity_start_interval, - mint: self.mint.as_ref().map(|x| x.build()), + mint: self.mint.as_ref() + .map(|x| x.build()) + .transpose()?, script_data_hash: self.script_data_hash.clone(), collateral: self.collateral.inputs_option(), required_signers: self.required_signers.to_option(), diff --git a/rust/src/crypto.rs b/rust/src/crypto.rs index 91de8e38..2be98210 100644 --- a/rust/src/crypto.rs +++ b/rust/src/crypto.rs @@ -1,18 +1,5 @@ -use crate::chain_crypto as crypto; -use crate::impl_mockchain as chain; -use bech32::ToBase32; -use cbor_event::{de::Deserializer, se::Serializer}; -use chain::key; -use crypto::bech32::Bech32 as _; -use std::fmt; -use std::fmt::Display; -use std::io::{BufRead, Seek, Write}; -use std::str::FromStr; - use cryptoxide::blake2b::Blake2b; -use super::*; - pub(crate) fn blake2b224(data: &[u8]) -> [u8; 28] { let mut out = [0; 28]; Blake2b::blake2b(&mut out, data, &[]); diff --git a/rust/src/fees.rs b/rust/src/fees.rs index 07281b04..5fc2d82b 100644 --- a/rust/src/fees.rs +++ b/rust/src/fees.rs @@ -1,5 +1,4 @@ use super::*; -use utils::*; use crate::rational::{Rational}; #[wasm_bindgen] @@ -71,7 +70,6 @@ pub fn min_ref_script_fee(total_ref_scripts_size: usize, ref_script_coins_per_by mod tests { use super::*; use crate::TransactionOutputBuilder; - use crypto::*; // based off tx test vectors (https://gist.github.com/KtorZ/5a2089df0915f21aca368d12545ab230) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 923b7549..ca8a00b3 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -46,7 +46,7 @@ pub use builders::*; pub mod chain_core; pub mod chain_crypto; mod crypto; -pub use crypto::*; +pub(crate) use crypto::*; mod emip3; pub use emip3::*; mod error; @@ -1934,6 +1934,10 @@ impl MintAssets { Ok(self.0.insert(key.clone(), value)) } + pub(crate) fn insert_unchecked(&mut self, key: &AssetName, value: Int) -> Option { + self.0.insert(key.clone(), value) + } + pub fn get(&self, key: &AssetName) -> Option { self.0.get(key).map(|v| v.clone()) } diff --git a/rust/src/protocol_types/address.rs b/rust/src/protocol_types/address.rs index ac38d5ce..09021743 100644 --- a/rust/src/protocol_types/address.rs +++ b/rust/src/protocol_types/address.rs @@ -397,7 +397,7 @@ impl Address { fn from_bytes_impl_unsafe(data: &[u8]) -> Address { match Self::from_bytes_internal_impl(data) { Ok(addr) => addr, - Err(e) => Address(AddrType::Malformed(MalformedAddress(data.to_vec()))) + Err(_) => Address(AddrType::Malformed(MalformedAddress(data.to_vec()))) } } diff --git a/rust/src/protocol_types/credentials.rs b/rust/src/protocol_types/credentials.rs index 59ece34a..00e0640b 100644 --- a/rust/src/protocol_types/credentials.rs +++ b/rust/src/protocol_types/credentials.rs @@ -1,4 +1,3 @@ -use std::collections::HashSet; use crate::*; #[wasm_bindgen] diff --git a/rust/src/protocol_types/ed25519_key_hashes.rs b/rust/src/protocol_types/ed25519_key_hashes.rs index f6cc557c..472914fc 100644 --- a/rust/src/protocol_types/ed25519_key_hashes.rs +++ b/rust/src/protocol_types/ed25519_key_hashes.rs @@ -1,5 +1,4 @@ pub use crate::*; -use std::collections::HashSet; pub type RequiredSigners = Ed25519KeyHashes; diff --git a/rust/src/protocol_types/plutus/plutus_data.rs b/rust/src/protocol_types/plutus/plutus_data.rs index 969f323b..e0041a2a 100644 --- a/rust/src/protocol_types/plutus/plutus_data.rs +++ b/rust/src/protocol_types/plutus/plutus_data.rs @@ -138,14 +138,14 @@ impl PlutusMap { /// Adds a value to the list of values associated with the key. pub(crate) fn add_value(&mut self, key: &PlutusData, value: &PlutusData) { - let mut values = self.0 + let values = self.0 .entry(key.clone()) .or_insert_with(PlutusMapValues::new); values.add(value); } pub(crate) fn add_value_move(&mut self, key: PlutusData, value: PlutusData) { - let mut values = self.0 + let values = self.0 .entry(key) .or_insert_with(PlutusMapValues::new); values.add_move(value); diff --git a/rust/src/protocol_types/plutus/plutus_scripts.rs b/rust/src/protocol_types/plutus/plutus_scripts.rs index 8a12c097..b0ce09b5 100644 --- a/rust/src/protocol_types/plutus/plutus_scripts.rs +++ b/rust/src/protocol_types/plutus/plutus_scripts.rs @@ -1,5 +1,4 @@ use crate::*; -use std::collections::HashSet; #[wasm_bindgen] #[derive( diff --git a/rust/src/rational.rs b/rust/src/rational.rs index 46e3f118..8ba079d3 100644 --- a/rust/src/rational.rs +++ b/rust/src/rational.rs @@ -1,4 +1,3 @@ -use std::convert::TryFrom; use crate::{BigInt, BigNum, JsError, UnitInterval}; #[derive(Clone, Debug)] diff --git a/rust/src/serialization/crypto/vkeys.rs b/rust/src/serialization/crypto/vkeys.rs index 08499ce3..c88d789f 100644 --- a/rust/src/serialization/crypto/vkeys.rs +++ b/rust/src/serialization/crypto/vkeys.rs @@ -2,7 +2,7 @@ use std::io::{BufRead, Seek, Write}; use cbor_event::de::Deserializer; use cbor_event::se::Serializer; use crate::{DeserializeError, Vkey, Vkeys}; -use crate::protocol_types::{CBORSpecial, CBORType, Deserialize}; +use crate::protocol_types::Deserialize; use crate::serialization::utils::is_break_tag; impl cbor_event::se::Serialize for Vkeys { diff --git a/rust/src/serialization/general.rs b/rust/src/serialization/general.rs index 61e0bc1b..bad8a40b 100644 --- a/rust/src/serialization/general.rs +++ b/rust/src/serialization/general.rs @@ -1,6 +1,6 @@ use crate::*; use std::io::{Seek, SeekFrom}; -use crate::serialization::utils::{is_break_tag, merge_option_plutus_list}; +use crate::serialization::utils::is_break_tag; use hashlink::LinkedHashMap; // This file was code-generated using an experimental CDDL to rust tool: diff --git a/rust/src/serialization/governance/proposals/hard_fork_initiation_action.rs b/rust/src/serialization/governance/proposals/hard_fork_initiation_action.rs index 103a15df..ab6dcbdd 100644 --- a/rust/src/serialization/governance/proposals/hard_fork_initiation_action.rs +++ b/rust/src/serialization/governance/proposals/hard_fork_initiation_action.rs @@ -1,4 +1,4 @@ -use crate::serialization::utils::{check_len_indefinite, serialize_and_check_index}; +use crate::serialization::utils::serialize_and_check_index; use crate::serialization::{check_len, deserialize_and_check_index}; use crate::*; use map_names::VotingProposalIndexNames; diff --git a/rust/src/serialization/plutus/plutus_data.rs b/rust/src/serialization/plutus/plutus_data.rs index beac8f6d..f5cdb167 100644 --- a/rust/src/serialization/plutus/plutus_data.rs +++ b/rust/src/serialization/plutus/plutus_data.rs @@ -1,6 +1,5 @@ use crate::*; use std::io::SeekFrom; -use hashlink::LinkedHashMap; use crate::serialization::utils::{is_break_tag, skip_set_tag}; impl cbor_event::se::Serialize for ConstrPlutusData { diff --git a/rust/src/serialization/plutus/plutus_script.rs b/rust/src/serialization/plutus/plutus_script.rs index b2ece92c..64250739 100644 --- a/rust/src/serialization/plutus/plutus_script.rs +++ b/rust/src/serialization/plutus/plutus_script.rs @@ -1,4 +1,3 @@ -use std::io::Read; use crate::*; impl cbor_event::se::Serialize for PlutusScript { diff --git a/rust/src/serialization/witnesses/transaction_witnesses_sets.rs b/rust/src/serialization/witnesses/transaction_witnesses_sets.rs index be82226d..78d08fa4 100644 --- a/rust/src/serialization/witnesses/transaction_witnesses_sets.rs +++ b/rust/src/serialization/witnesses/transaction_witnesses_sets.rs @@ -2,7 +2,7 @@ use std::io::{BufRead, Seek, Write}; use cbor_event::de::Deserializer; use cbor_event::se::Serializer; use crate::{DeserializeError, TransactionWitnessSet, TransactionWitnessSets}; -use crate::protocol_types::{CBORSpecial, CBORType, Deserialize}; +use crate::protocol_types::Deserialize; use crate::serialization::utils::is_break_tag; impl cbor_event::se::Serialize for TransactionWitnessSets { diff --git a/rust/src/tests/address.rs b/rust/src/tests/address.rs index b84eba4b..82ff2b83 100644 --- a/rust/src/tests/address.rs +++ b/rust/src/tests/address.rs @@ -1,5 +1,4 @@ use crate::*; -use crypto::*; #[test] fn variable_nat_encoding() { diff --git a/rust/src/tests/builders/certificates_builder.rs b/rust/src/tests/builders/certificates_builder.rs index bdd3c3ad..db1d53a3 100644 --- a/rust/src/tests/builders/certificates_builder.rs +++ b/rust/src/tests/builders/certificates_builder.rs @@ -208,29 +208,9 @@ fn certificates_builder_refund_no_deposit_test() { &MoveInstantaneousRewardsCert::new(&mir_cert), ); - let staking_cred = Credential::from_keyhash(&fake_key_hash(10)); - let reward_address = - RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &staking_cred); let mut owners = Ed25519KeyHashes::new(); owners.add(&fake_key_hash(11)); owners.add(&fake_key_hash(12)); - let relays = Relays::new(); - let matadata = PoolMetadata::new( - &URL::new("https://iohk.io".to_string()).unwrap(), - &fake_pool_metadata_hash(5), - ); - - let params = PoolParams::new( - &fake_key_hash(13), - &fake_vrf_key_hash(15), - &Coin::from(100u64), - &Coin::from(200u64), - &UnitInterval::new(&BigNum::from(110u64), &BigNum::from(220u64)), - &reward_address, - &owners, - &relays, - Some(matadata), - ); let pool_ret_cert = PoolRetirement::new(&fake_key_hash(16), Epoch::from(100u32)); let pool_ret_cert_wrapped = Certificate::new_pool_retirement(&pool_ret_cert); @@ -295,8 +275,6 @@ fn certificates_builder_refund_no_deposit_test() { #[test] fn certificates_builder_req_signers_test() { let mut builder = CertificatesBuilder::new(); - let pool_deposit = 100u64; - let key_deposit = 200u64; let key_deposit_form_args = 201u64; let drep_reg_deposit = 400u64; @@ -482,11 +460,6 @@ fn certificates_builder_req_signers_test() { builder.add(&vote_deleg_cert_wrapped).unwrap(); builder.add(&vote_reg_deleg_cert_wrapped).unwrap(); - let builder_deposit = builder - .get_certificates_deposit(&Coin::from(pool_deposit), &Coin::from(key_deposit)) - .unwrap(); - - let req_signers = builder.get_required_signers(); assert_eq!(req_signers.len(), 19); diff --git a/rust/src/tests/builders/mint_builder.rs b/rust/src/tests/builders/mint_builder.rs index 2270636d..5f9173a0 100644 --- a/rust/src/tests/builders/mint_builder.rs +++ b/rust/src/tests/builders/mint_builder.rs @@ -246,7 +246,7 @@ fn multiple_mints() { mint_builder.add_asset(&mint_witnes2, &asset_name2, &Int::new(&BigNum::from(101u64))).unwrap(); mint_builder.add_asset(&mint_witnes2, &asset_name3, &Int::new(&BigNum::from(102u64))).unwrap(); - let mint = mint_builder.build(); + let mint = mint_builder.build().expect("Failed to build mint"); assert_eq!(mint.len(), 2); let policy_mints_list = mint.get(&script_hash_1).unwrap(); @@ -281,7 +281,7 @@ fn native_script_mint() { let mint_witnes = MintWitness::new_native_script(&native_script_source); mint_builder.add_asset(&mint_witnes, &asset_name1, &Int::new(&BigNum::from(100u64))).unwrap(); - let mint = mint_builder.build(); + let mint = mint_builder.build().expect("Failed to build mint"); assert_eq!(mint.len(), 1); let policy_mints_list = mint.get(&script_hash).unwrap(); @@ -396,7 +396,7 @@ fn wrong_witness_type_ref_error() { let res4= mint_builder.add_asset(&mint_witness_native_2, &asset_name4, &Int::new(&BigNum::from(103u64))); assert!(res4.is_err()); - let mint = mint_builder.build(); + let mint = mint_builder.build().expect("Failed to build mint"); assert_eq!(mint.len(), 2); let policy_mints_list = mint.get(&script_hash_1).unwrap(); @@ -465,7 +465,7 @@ fn wrong_witness_type_no_ref_error() { let res4= mint_builder.add_asset(&mint_witness_native_2, &asset_name4, &Int::new(&BigNum::from(103u64))); assert!(res4.is_err()); - let mint = mint_builder.build(); + let mint = mint_builder.build().expect("Failed to build mint"); assert_eq!(mint.len(), 2); let policy_mints_list = mint.get(&script_hash_1).unwrap(); diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index c40c87e4..c429146d 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -512,7 +512,7 @@ fn build_tx_insufficient_deposit() { certs.add(&Certificate::new_stake_registration( &StakeRegistration::new(&stake_cred), )); - tx_builder.set_certs(&certs); + tx_builder.set_certs(&certs).expect("Failed to set certs"); let change_cred = Credential::from_keyhash(&change_key.to_raw_key().hash()); let change_addr = BaseAddress::new( @@ -567,7 +567,7 @@ fn build_tx_with_inputs() { .to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&BigNum(1_000_000)), - ); + ).expect("Failed to add input"); } tx_builder.add_regular_input( &BaseAddress::new( @@ -578,7 +578,7 @@ fn build_tx_with_inputs() { .to_address(), &TransactionInput::new(&genesis_id(), 1), &Value::new(&BigNum(1_000_000)), - ); + ).expect("Failed to add input"); tx_builder.add_regular_input( &PointerAddress::new( NetworkInfo::testnet_preprod().network_id(), @@ -588,13 +588,13 @@ fn build_tx_with_inputs() { .to_address(), &TransactionInput::new(&genesis_id(), 2), &Value::new(&BigNum(1_000_000)), - ); + ).expect("Failed to add input"); tx_builder.add_regular_input( &ByronAddress::icarus_from_key(&spend, NetworkInfo::testnet_preprod().protocol_magic()) .to_address(), &TransactionInput::new(&genesis_id(), 3), &Value::new(&BigNum(1_000_000)), - ); + ).expect("Failed to add input"); assert_eq!(tx_builder.inputs.len(), 4); } @@ -650,10 +650,10 @@ fn build_tx_with_script_ref() { &spend_cred, &Pointer::new_pointer(&BigNum(0), &BigNum(0), &BigNum(0)), ) - .to_address(), + .to_address(), &TransactionInput::new(&genesis_id(), 2), &Value::new(&BigNum(1_000_000)), - ); + ).expect("Failed to add input"); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet_preprod().network_id(), @@ -734,7 +734,7 @@ fn serialization_tx_body_with_script_ref() { .to_address(), &TransactionInput::new(&genesis_id(), 2), &Value::new(&BigNum(1_000_000)), - ); + ).expect("Failed to add input"); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet_preprod().network_id(), @@ -815,7 +815,7 @@ fn json_serialization_tx_body_with_script_ref() { .to_address(), &TransactionInput::new(&genesis_id(), 2), &Value::new(&BigNum(1_000_000)), - ); + ).expect("Failed to add input"); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet_preprod().network_id(), @@ -890,7 +890,7 @@ fn build_tx_with_mint_all_sent() { .to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&BigNum(500)), - ); + ).expect("Failed to add input"); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet_preprod().network_id(), @@ -904,7 +904,7 @@ fn build_tx_with_mint_all_sent() { let amount = BigNum(1234); // Adding mint of the asset - which should work as an input - tx_builder.add_mint_asset(&min_script, &name, &Int::new(&amount)); + tx_builder.add_mint_asset(&min_script, &name, &Int::new(&amount)).expect("Failed to add mint"); let mut ass = Assets::new(); ass.insert(&name, &amount); @@ -979,7 +979,7 @@ fn build_tx_with_mint_in_change() { .to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&BigNum(600)), - ); + ).expect("Failed to add input"); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet_preprod().network_id(), @@ -995,7 +995,7 @@ fn build_tx_with_mint_in_change() { let amount_sent = BigNum(500); // Adding mint of the asset - which should work as an input - tx_builder.add_mint_asset(&min_script, &name, &Int::new(&amount_minted)); + tx_builder.add_mint_asset(&min_script, &name, &Int::new(&amount_minted)).expect("Failed to add mint"); let mut ass = Assets::new(); ass.insert(&name, &amount_sent); @@ -1089,14 +1089,14 @@ fn change_with_input_and_mint_not_enough_ada() { .to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&BigNum(600)), - ); + ).expect("Failed to add input"); tx_builder.add_regular_input( &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) .to_address(), &TransactionInput::new(&genesis_id(), 1), &Value::new_with_assets(&BigNum(1), &mass_input), - ); + ).expect("Failed to add input"); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet_preprod().network_id(), @@ -1106,7 +1106,7 @@ fn change_with_input_and_mint_not_enough_ada() { .to_address(); // Adding mint of the asset - which should work as an input - tx_builder.add_mint_asset(&min_script, &asset_name, &Int::new(&amount_minted)); + tx_builder.add_mint_asset(&min_script, &asset_name, &Int::new(&amount_minted)).expect("Failed to add mint"); let mut asset = Assets::new(); asset.insert(&asset_name, &amount_sent); @@ -1187,14 +1187,14 @@ fn change_with_input_and_mint_not_enough_assets() { .to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&BigNum(100000)), - ); + ).expect("Failed to add input"); tx_builder.add_regular_input( &EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) .to_address(), &TransactionInput::new(&genesis_id(), 1), &Value::new_with_assets(&BigNum(1), &mass_input), - ); + ).expect("Failed to add input"); let addr_net_0 = BaseAddress::new( NetworkInfo::testnet_preprod().network_id(), @@ -1204,7 +1204,7 @@ fn change_with_input_and_mint_not_enough_assets() { .to_address(); // Adding mint of the asset - which should work as an input - tx_builder.add_mint_asset(&min_script, &asset_name, &Int::new(&amount_minted)); + tx_builder.add_mint_asset(&min_script, &asset_name, &Int::new(&amount_minted)).expect("Failed to add mint"); let mut asset = Assets::new(); asset.insert(&asset_name, &amount_sent); @@ -1712,7 +1712,7 @@ fn build_tx_burn_less_than_min_ada() { .to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&BigNum(2_400_000)), - ); + ).expect("Failed to add input"); tx_builder.set_ttl(1); @@ -1764,7 +1764,7 @@ fn build_tx_burn_empty_assets() { .to_address(), &TransactionInput::new(&genesis_id(), 0), &input_value, - ); + ).expect("Failed to add input"); tx_builder.set_ttl(1); @@ -1814,7 +1814,7 @@ fn build_tx_no_useless_multiasset() { .to_address(), &TransactionInput::new(&genesis_id(), 0), &input_amount, - ); + ).expect("Failed to add input"); // add an input that contains an asset & ADA let mut output_amount = Value::new(&BigNum(2_000_000)); @@ -1896,7 +1896,7 @@ fn build_tx_add_change_split_nfts() { .to_address(), &TransactionInput::new(&genesis_id(), 0), &input_value, - ); + ).expect("Failed to add input"); let output_addr = ByronAddress::from_base58("Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b") @@ -1956,7 +1956,7 @@ fn build_tx_too_big_output() { .to_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&BigNum(500)), - ); + ).expect("Failed to add input"); let output_addr = ByronAddress::from_base58("Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b") @@ -2017,7 +2017,7 @@ fn build_tx_add_change_nfts_not_enough_ada() { .to_address(), &TransactionInput::new(&genesis_id(), 0), &input_value, - ); + ).expect("Failed to add input"); let output_addr = ByronAddress::from_base58("Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b") @@ -2359,7 +2359,7 @@ fn tx_builder_cip2_random_improve_multiasset() { &input_for_cover_change.output.address, &input_for_cover_change.input, &input_for_cover_change.output.amount, - ); + ).expect("Failed to add input"); let change_addr = ByronAddress::from_base58("Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho") @@ -2653,7 +2653,7 @@ fn build_tx_multisig_spend_1on1_unsigned() { &addr_multisig, &TransactionInput::new(&genesis_id(), 0), &Value::new(&BigNum(1_000_000)), - ); + ).expect("Failed to add input"); tx_builder .add_output( @@ -2846,7 +2846,7 @@ fn add_change_splits_change_into_multiple_outputs_when_nfts_overflow_output_size .to_address(), &TransactionInput::new(&genesis_id(), 0), &input_value, - ); + ).expect("Failed to add input"); let output_addr = ByronAddress::from_base58("Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b") @@ -3126,13 +3126,13 @@ fn set_mint_asset_with_empty_mint() { let mut tx_builder = create_default_tx_builder(); let (mint_script, policy_id) = mint_script_and_policy(0); - tx_builder.set_mint_asset(&mint_script, &create_mint_asset()); + tx_builder.set_mint_asset(&mint_script, &create_mint_asset()).expect("Failed to set mint asset"); assert!(tx_builder.mint.is_some()); let mint_scripts = tx_builder.mint.as_ref().unwrap().get_native_scripts(); assert!(mint_scripts.len() > 0); - let mint = tx_builder.mint.unwrap().build(); + let mint = tx_builder.mint.unwrap().build().expect("Failed to build mint"); assert_eq!(mint.len(), 1); assert_mint_asset(&mint, &policy_id); @@ -3155,13 +3155,13 @@ fn set_mint_asset_with_existing_mint() { ) .unwrap(); - tx_builder.set_mint_asset(&mint_script2, &create_mint_asset()); + tx_builder.set_mint_asset(&mint_script2, &create_mint_asset()).expect("Failed to set mint asset"); assert!(tx_builder.mint.is_some()); let mint_scripts = tx_builder.mint.as_ref().unwrap().get_native_scripts(); assert!(mint_scripts.len() > 0); - let mint = tx_builder.mint.unwrap().build(); + let mint = tx_builder.mint.unwrap().build().expect("Failed to build mint"); assert_eq!(mint.len(), 2); assert_mint_asset(&mint, &policy_id1); @@ -3187,13 +3187,13 @@ fn add_mint_asset_with_empty_mint() { let (mint_script, policy_id) = mint_script_and_policy(0); - tx_builder.add_mint_asset(&mint_script, &create_asset_name(), &Int::new_i32(1234)); + tx_builder.add_mint_asset(&mint_script, &create_asset_name(), &Int::new_i32(1234)).expect("Failed to add mint asset"); assert!(tx_builder.mint.is_some()); let mint_scripts = tx_builder.mint.as_ref().unwrap().get_native_scripts(); assert!(mint_scripts.len() > 0); - let mint = tx_builder.mint.unwrap().build(); + let mint = tx_builder.mint.unwrap().build().expect("Failed to build mint"); assert_eq!(mint.len(), 1); assert_mint_asset(&mint, &policy_id); @@ -3215,13 +3215,13 @@ fn add_mint_asset_with_existing_mint() { &NativeScripts::from(vec![mint_script1.clone()]), ) .unwrap(); - tx_builder.add_mint_asset(&mint_script2, &create_asset_name(), &Int::new_i32(1234)); + tx_builder.add_mint_asset(&mint_script2, &create_asset_name(), &Int::new_i32(1234)).expect("Failed to add mint asset"); assert!(tx_builder.mint.is_some()); let mint_scripts = tx_builder.mint.as_ref().unwrap().get_native_scripts(); assert!(mint_scripts.len() > 0); - let mint = tx_builder.mint.unwrap().build(); + let mint = tx_builder.mint.unwrap().build().expect("Failed to build mint"); assert_eq!(mint.len(), 2); assert_mint_asset(&mint, &policy_id1); @@ -3372,7 +3372,7 @@ fn add_mint_asset_and_output() { let coin = BigNum(249); // Add unrelated mint first to check it is NOT added to output later - tx_builder.add_mint_asset(&mint_script0, &name, &amount.clone()); + tx_builder.add_mint_asset(&mint_script0, &name, &amount.clone()).expect("Failed to add mint asset"); tx_builder .add_mint_asset_and_output( @@ -3391,7 +3391,7 @@ fn add_mint_asset_and_output() { let mint_scripts = &tx_builder.mint.as_ref().unwrap().get_native_scripts(); assert!(mint_scripts.len() > 0); - let mint = &tx_builder.mint.unwrap().build(); + let mint = &tx_builder.mint.unwrap().build().expect("Failed to build mint"); // Mint contains two entries assert_eq!(mint.len(), 2); @@ -3442,7 +3442,7 @@ fn add_mint_asset_and_min_required_coin() { let address = byron_address(); // Add unrelated mint first to check it is NOT added to output later - tx_builder.add_mint_asset(&mint_script0, &name, &amount); + tx_builder.add_mint_asset(&mint_script0, &name, &amount).expect("Failed to add mint asset"); tx_builder .add_mint_asset_and_output_min_required_coin( @@ -3460,7 +3460,7 @@ fn add_mint_asset_and_min_required_coin() { let mint_scripts = tx_builder.mint.as_ref().unwrap().get_native_scripts(); assert!(mint_scripts.len() > 0); - let mint = &tx_builder.mint.unwrap().build(); + let mint = &tx_builder.mint.unwrap().build().expect("Failed to build mint"); // Mint contains two entries assert_eq!(mint.len(), 2); @@ -3533,10 +3533,10 @@ fn add_mint_includes_witnesses_into_fee_estimation() { assert_eq!(original_tx_fee, BigNum(168361)); // Add minting four assets from three different policies - tx_builder.add_mint_asset(&mint_script1, &name1, &amount); - tx_builder.add_mint_asset(&mint_script2, &name2, &amount); - tx_builder.add_mint_asset(&mint_script3, &name3, &amount); - tx_builder.add_mint_asset(&mint_script3, &name4, &amount); + tx_builder.add_mint_asset(&mint_script1, &name1, &amount).expect("Failed to add mint asset"); + tx_builder.add_mint_asset(&mint_script2, &name2, &amount).expect("Failed to add mint asset"); + tx_builder.add_mint_asset(&mint_script3, &name3, &amount).expect("Failed to add mint asset"); + tx_builder.add_mint_asset(&mint_script3, &name4, &amount).expect("Failed to add mint asset"); let mint = tx_builder.get_mint().unwrap(); let mint_len = mint.to_bytes().len(); @@ -3608,7 +3608,7 @@ fn fee_estimation_fails_on_missing_mint_scripts() { let est1 = tx_builder.min_fee(); assert!(est1.is_ok()); - tx_builder.add_mint_asset(&mint_script2, &name1, &amount); + tx_builder.add_mint_asset(&mint_script2, &name1, &amount).expect("Failed to add mint asset"); let est2 = tx_builder.min_fee(); assert!(est2.is_ok()); @@ -3726,10 +3726,10 @@ fn total_input_output_with_mint_and_burn() { assert!(ma1_output.is_none()); // Adding mint - tx_builder.add_mint_asset(&mint_script1, &name, &Int::new_i32(40)); + tx_builder.add_mint_asset(&mint_script1, &name, &Int::new_i32(40)).expect("Failed to add mint asset"); // Adding burn - tx_builder.add_mint_asset(&mint_script2, &name, &Int::new_i32(-40)); + tx_builder.add_mint_asset(&mint_script2, &name, &Int::new_i32(-40)).expect("Failed to add mint asset"); let total_input_after_mint = tx_builder.get_total_input().unwrap(); let total_output_after_mint = tx_builder.get_total_output().unwrap(); @@ -4017,7 +4017,7 @@ fn test_plutus_witness_redeemer_index_auto_changing() { &byron_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&BigNum(1_000_000)), - ); + ).expect("Failed to add input"); // Adding two plutus inputs then // both have redeemers with index ZERO @@ -4064,9 +4064,9 @@ fn test_native_and_plutus_scripts_together() { tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); let (pscript1, _) = fake_plutus_script_and_hash(0); - let (pscript2, phash2) = fake_plutus_script_and_hash(1); + let (pscript2, _phash2) = fake_plutus_script_and_hash(1); let (nscript1, _) = mint_script_and_policy(0); - let (nscript2, nhash2) = mint_script_and_policy(1); + let (nscript2, _nhash2) = mint_script_and_policy(1); let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); // Creating redeemers with indexes ZERO @@ -4150,9 +4150,9 @@ fn test_json_serialization_native_and_plutus_scripts_together() { tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); let (pscript1, _) = fake_plutus_script_and_hash(0); - let (pscript2, phash2) = fake_plutus_script_and_hash(1); + let (pscript2, _phash2) = fake_plutus_script_and_hash(1); let (nscript1, _) = mint_script_and_policy(0); - let (nscript2, nhash2) = mint_script_and_policy(1); + let (nscript2, _nhash2) = mint_script_and_policy(1); let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); let datum2 = PlutusData::new_bytes(fake_bytes_32(11)); // Creating redeemers with indexes ZERO @@ -4194,7 +4194,7 @@ fn test_json_serialization_native_and_plutus_scripts_together() { &Value::new(&BigNum(1_000_000)), ); - tx_builder.calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()); + tx_builder.calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()).expect("Failed to calc script data hash"); let tx: Transaction = tx_builder.build_tx().unwrap(); @@ -4215,12 +4215,12 @@ fn test_regular_and_collateral_inputs_same_keyhash() { &fake_base_address(0), &TransactionInput::new(&genesis_id(), 0), &Value::new(&BigNum(1_000_000)), - ); + ).expect("Failed to add input"); collateral_builder.add_regular_input( &fake_base_address(0), &TransactionInput::new(&genesis_id(), 0), &Value::new(&BigNum(1_000_000)), - ); + ).expect("Failed to add input"); fn get_fake_vkeys_count(i: &TxInputsBuilder, c: &TxInputsBuilder) -> usize { let mut tx_builder = create_reallistic_tx_builder(); @@ -4240,12 +4240,12 @@ fn test_regular_and_collateral_inputs_same_keyhash() { &fake_base_address(1), &TransactionInput::new(&genesis_id(), 0), &Value::new(&BigNum(1_000_000)), - ); + ).expect("Failed to add input"); collateral_builder.add_regular_input( &fake_base_address(2), &TransactionInput::new(&genesis_id(), 0), &Value::new(&BigNum(1_000_000)), - ); + ).expect("Failed to add input"); // There are now three fake witnesses in the builder // because all three unique keyhashes got combined @@ -4346,12 +4346,12 @@ fn test_ex_unit_costs_are_added_to_the_fees() { &fake_base_address(0), &TransactionInput::new(&genesis_id(), 0), &Value::new(&BigNum(1_000_000)), - ); + ).expect("Failed to add input"); collateral_builder.add_regular_input( &fake_base_address(0), &TransactionInput::new(&genesis_id(), 1), &Value::new(&BigNum(1_000_000)), - ); + ).expect("Failed to add input"); let (pscript1, _) = fake_plutus_script_and_hash(0); let datum1 = PlutusData::new_bytes(fake_bytes_32(10)); @@ -4477,7 +4477,7 @@ fn test_required_signers_are_added_to_the_witness_estimate() { &fake_base_address(0), &TransactionInput::new(&fake_tx_hash(0), 0), &Value::new(&BigNum(10_000_000)), - ); + ).expect("Failed to add input"); keys.to_vec().iter().for_each(|k| { tx_builder.add_required_signer(k); @@ -4534,7 +4534,9 @@ fn collateral_return_and_total_collateral_setters() { tx_builder.set_fee(&BigNum(123456)); let mut inp = TxInputsBuilder::new(); - inp.add_regular_input(&fake_base_address(0), &fake_tx_input(0), &fake_value()); + inp. + add_regular_input(&fake_base_address(0), &fake_tx_input(0), &fake_value()) + .expect("Failed to add input"); tx_builder.set_inputs(&inp); tx_builder.set_collateral(&inp); @@ -4573,14 +4575,14 @@ fn inputs_builder_total_value() { &fake_base_address(0), &fake_tx_input(0), &fake_value2(100_000), - ); + ).expect("Failed to add input"); assert_eq!(b.total_value().unwrap(), Value::new(&BigNum(100_000))); b.add_regular_input( &fake_base_address(1), &fake_tx_input(1), &fake_value2(200_000), - ); + ).expect("Failed to add input"); assert_eq!(b.total_value().unwrap(), Value::new(&BigNum(300_000))); let masset = fake_multiasset(123); @@ -4589,7 +4591,7 @@ fn inputs_builder_total_value() { &fake_base_address(2), &fake_tx_input(2), &Value::new_with_assets(&BigNum(300_000), &masset), - ); + ).expect("Failed to add input"); assert_eq!( b.total_value().unwrap(), Value::new_with_assets(&BigNum(600_000), &masset) @@ -4607,7 +4609,7 @@ fn test_auto_calc_total_collateral() { &fake_base_address(0), &fake_tx_input(0), &fake_value2(collateral_input_value.clone()), - ); + ).expect("Failed to add input"); tx_builder.set_collateral(&inp); @@ -4644,7 +4646,7 @@ fn test_auto_calc_total_collateral_with_assets() { &fake_base_address(0), &fake_tx_input(0), &Value::new_with_assets(&BigNum(collateral_input_value.clone()), &masset), - ); + ).expect("Failed to add input"); tx_builder.set_collateral(&inp); @@ -4681,7 +4683,7 @@ fn test_auto_calc_total_collateral_fails_with_assets() { &fake_base_address(0), &fake_tx_input(0), &Value::new_with_assets(&BigNum(collateral_input_value.clone()), &masset), - ); + ).expect("Failed to add input"); tx_builder.set_collateral(&inp); @@ -4731,7 +4733,7 @@ fn test_auto_calc_total_collateral_fails_on_no_ada() { &fake_base_address(0), &fake_tx_input(0), &Value::new(&BigNum(collateral_input_value.clone())), - ); + ).expect("Failed to add input"); tx_builder.set_collateral(&inp); @@ -4759,7 +4761,7 @@ fn test_auto_calc_collateral_return() { &fake_base_address(0), &fake_tx_input(0), &fake_value2(collateral_input_value.clone()), - ); + ).expect("Failed to add input"); tx_builder.set_collateral(&inp); @@ -4801,7 +4803,7 @@ fn test_auto_calc_collateral_return_with_assets() { &fake_base_address(0), &fake_tx_input(0), &Value::new_with_assets(&BigNum(collateral_input_value.clone()), &masset), - ); + ).expect("Failed to add input"); tx_builder.set_collateral(&inp); @@ -4846,7 +4848,7 @@ fn test_add_collateral_return_succeed_with_border_amount() { &fake_base_address(0), &fake_tx_input(0), &Value::new_with_assets(&BigNum(collateral_input_value.clone()), &masset), - ); + ).expect("Failed to add input"); tx_builder.set_collateral(&inp); @@ -4885,7 +4887,7 @@ fn test_add_zero_collateral_return() { &fake_base_address(0), &fake_tx_input(0), &Value::new(&BigNum(collateral_input_value.clone())), - ); + ).expect("Failed to add input"); tx_builder.set_collateral(&inp); @@ -4915,7 +4917,7 @@ fn test_add_collateral_return_fails_no_enough_ada() { &fake_base_address(0), &fake_tx_input(0), &Value::new_with_assets(&BigNum(collateral_input_value.clone()), &masset), - ); + ).expect("Failed to add input"); tx_builder.set_collateral(&inp); @@ -5499,16 +5501,16 @@ fn multiple_plutus_inputs_test() { ); let output_adress = Address::from_bech32("addr_test1qpm5njmgzf4t7225v6j34wl30xfrufzt3jtqtdzf3en9ahpmnhtmynpasyc8fq75zv0uaj86vzsr7g3g8q5ypgu5fwtqr9zsgj").unwrap(); - let output_value = Value::new(&Coin::from(500000u64)); + let output_value = Value::new(&Coin::from(5000000u64)); let output = TransactionOutput::new(&output_adress, &output_value); - tx_builder.add_output(&output); + tx_builder.add_output(&output).expect("Failed to add output"); let mut col_builder = TxInputsBuilder::new(); col_builder.add_regular_input( &colateral_adress, &colateral_input, &Value::new(&Coin::from(1000000000u64)), - ); + ).expect("Failed to add input"); tx_builder.set_collateral(&col_builder); let datum = PlutusData::new_bytes(fake_bytes_32(11)); @@ -5522,8 +5524,8 @@ fn multiple_plutus_inputs_test() { in_builder.add_plutus_script_input(&plutus_wit2, &input_2, &value); tx_builder.set_inputs(&in_builder); - tx_builder.calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()); - tx_builder.add_change_if_needed(&output_adress); + tx_builder.calc_script_data_hash(&TxBuilderConstants::plutus_vasil_cost_models()).expect("Failed to calculate script data hash"); + tx_builder.add_change_if_needed(&output_adress).expect("Failed to add change"); let build_res = tx_builder.build_tx(); assert!(&build_res.is_ok()); let tx = build_res.unwrap(); @@ -5705,7 +5707,7 @@ fn build_tx_with_certs_withdrawals_plutus_script_address() { &collateral_addr, &collateral_input, &Value::new(&Coin::from(123u32)), - ); + ).expect("Failed to add input"); tx_builder.set_collateral(&collateral_builder); tx_builder.calc_script_data_hash(&cost_models).unwrap(); tx_builder.add_change_if_needed(&change_addr).unwrap(); @@ -6056,7 +6058,7 @@ fn utxo_selection_accounts_for_change_min_utxo_test() { "82825820a04996d5ef87fdece0c74625f02ee5c1497a06e0e476c5095a6b0626b295074a00825839001772f234940519e71318bb9c5c8ad6eacfe8fd91a509050624e3855e6c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e4931a0016e360" ]; let output = TransactionOutput::new(&Address::from_bech32("addr_test1qppkqaf5044y2t46g2y6udz636c4uultszte5l5p0kvgl3tv3ck06k550q64lgwkqavljd63yda0x2va074fguprujfsjre4xh").unwrap(), &Value::new(&BigNum::from_str("969750").unwrap())); - tx_builder.add_output(&output); + tx_builder.add_output(&output).expect("Failed to add output"); let mut utxos = TransactionUnspentOutputs::new(); for hex_utxo in hex_utxos { utxos.add(&TransactionUnspentOutput::from_hex(hex_utxo).unwrap()); diff --git a/rust/src/tests/builders/voting_builder.rs b/rust/src/tests/builders/voting_builder.rs index 8a6fe4fe..acd880e8 100644 --- a/rust/src/tests/builders/voting_builder.rs +++ b/rust/src/tests/builders/voting_builder.rs @@ -1,6 +1,6 @@ -use crate::fakes::{fake_key_hash, fake_script_hash, fake_tx_hash, fake_tx_input, fake_vkey}; +use crate::fakes::{fake_key_hash, fake_script_hash, fake_tx_hash, fake_vkey}; use crate::fees::min_fee_for_size; -use crate::tests::mock_objects::{create_change_address, create_linear_fee, create_plutus_script, create_redeemer, create_rich_tx_builder}; +use crate::tests::mock_objects::{create_change_address, create_linear_fee, create_plutus_script, create_rich_tx_builder}; use crate::*; #[test] diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index 9fd59206..568b669e 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -1,7 +1,7 @@ use crate::*; use crate::fakes::fake_vkey_witness; use crate::tests::helpers::harden; -use crate::tests::mock_objects::{create_plutus_script, create_reallistic_tx_builder}; +use crate::tests::mock_objects::create_plutus_script; #[test] fn native_script_hash() { @@ -55,9 +55,9 @@ fn asset_name_ord() { assert_eq!(map.keys(), AssetNames(vec![name3, name1, name2])); let mut map2 = MintAssets::new(); - map2.insert(&name11, Int::new_i32(1)); - map2.insert(&name33, Int::new_i32(1)); - map2.insert(&name22, Int::new_i32(1)); + map2.insert(&name11, Int::new_i32(1)).expect("insert failed"); + map2.insert(&name33, Int::new_i32(1)).expect("insert failed"); + map2.insert(&name22, Int::new_i32(1)).expect("insert failed"); assert_eq!(map2.keys(), AssetNames(vec![name33, name11, name22])); } @@ -72,12 +72,12 @@ fn mint_to_multiasset() { let amount2 = BigNum::from_str("5678").unwrap(); let mut mass1 = MintAssets::new(); - mass1.insert(&name1, Int::new(&amount1)); - mass1.insert(&name2, Int::new(&amount2)); + mass1.insert(&name1, Int::new(&amount1)).expect("insert failed"); + mass1.insert(&name2, Int::new(&amount2)).expect("insert failed"); let mut mass2 = MintAssets::new(); - mass2.insert(&name1, Int::new(&amount2)); - mass2.insert(&name2, Int::new(&amount1)); + mass2.insert(&name1, Int::new(&amount2)).expect("insert failed"); + mass2.insert(&name2, Int::new(&amount1)).expect("insert failed"); let mut mint = Mint::new(); mint.insert(&policy_id1, &mass1); @@ -109,12 +109,12 @@ fn mint_to_negative_multiasset() { let amount2 = BigNum::from_str("5678").unwrap(); let mut mass1 = MintAssets::new(); - mass1.insert(&name1, Int::new(&amount1)); - mass1.insert(&name2, Int::new_negative(&amount2)); + mass1.insert(&name1, Int::new(&amount1)).expect("insert failed"); + mass1.insert(&name2, Int::new_negative(&amount2)).expect("insert failed"); let mut mass2 = MintAssets::new(); - mass2.insert(&name1, Int::new_negative(&amount1)); - mass2.insert(&name2, Int::new(&amount2)); + mass2.insert(&name1, Int::new_negative(&amount1)).expect("insert failed"); + mass2.insert(&name2, Int::new(&amount2)).expect("insert failed"); let mut mint = Mint::new(); mint.insert(&policy_id1, &mass1); @@ -157,10 +157,10 @@ fn mint_to_negative_multiasset_empty() { let amount1 = BigNum::from_str("1234").unwrap(); let mut mass1 = MintAssets::new(); - mass1.insert(&name1, Int::new(&amount1)); + mass1.insert(&name1, Int::new(&amount1)).expect("insert failed"); let mut mass2 = MintAssets::new(); - mass2.insert(&name1, Int::new_negative(&amount1)); + mass2.insert(&name1, Int::new_negative(&amount1)).expect("insert failed"); let mut mint1 = Mint::new(); mint1.insert(&policy_id1, &mass1); @@ -333,17 +333,10 @@ fn witnesses_deduplication_test(){ .derive(0) .derive(0) .to_public(); - let stake = tests::mock_objects::root_key_15() - .derive(harden(1854)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); let spending_hash = spend.to_raw_key().hash(); - let mut native_scripts_1 = NativeScript::new_script_pubkey(&ScriptPubkey::new( + let native_scripts_1 = NativeScript::new_script_pubkey(&ScriptPubkey::new( &spending_hash, )); diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/mock_objects.rs index 5fa04473..d23da701 100644 --- a/rust/src/tests/mock_objects.rs +++ b/rust/src/tests/mock_objects.rs @@ -429,7 +429,8 @@ pub(crate) fn create_rich_tx_builder(with_collateral: bool) -> TransactionBuilde let input = TransactionInput::new(&fake_tx_hash(1), 0); let address = generate_address(1); let mut input_builder = TxInputsBuilder::new(); - input_builder.add_regular_input(&address, &input, &Value::new(&Coin::from(u64::MAX / 2))); + input_builder.add_regular_input(&address, &input, &Value::new(&Coin::from(u64::MAX / 2))) + .expect("should add input"); tx_builder.set_inputs(&input_builder); if with_collateral { tx_builder.set_collateral(&input_builder); @@ -446,12 +447,12 @@ pub(crate) fn create_tx_builder_with_amount( let input = TransactionInput::new(&fake_tx_hash(1), 0); let address = generate_address(1); let mut input_builder = TxInputsBuilder::new(); - input_builder.add_regular_input(&address, &input, &Value::new(&Coin::from(amount))); + input_builder.add_regular_input(&address, &input, &Value::new(&Coin::from(amount))).expect("should add input"); tx_builder.set_inputs(&input_builder); if with_collateral { let col_input = TransactionInput::new(&fake_tx_hash(1), 0); let mut col_input_builder = TxInputsBuilder::new(); - col_input_builder.add_regular_input(&address, &col_input, &Value::new(&Coin::from(u64::MAX / 2))); + col_input_builder.add_regular_input(&address, &col_input, &Value::new(&Coin::from(u64::MAX / 2))).expect("should add input"); tx_builder.set_collateral(&col_input_builder); } @@ -473,12 +474,12 @@ pub(crate) fn create_tx_builder_with_amount_and_deposit_params( let input = TransactionInput::new(&fake_tx_hash(1), 0); let address = generate_address(1); let mut input_builder = TxInputsBuilder::new(); - input_builder.add_regular_input(&address, &input, &Value::new(&Coin::from(amount))); + input_builder.add_regular_input(&address, &input, &Value::new(&Coin::from(amount))).expect("should add input"); tx_builder.set_inputs(&input_builder); if with_collateral { let col_input = TransactionInput::new(&fake_tx_hash(1), 0); let mut col_input_builder = TxInputsBuilder::new(); - col_input_builder.add_regular_input(&address, &col_input, &Value::new(&Coin::from(u64::MAX / 2))); + col_input_builder.add_regular_input(&address, &col_input, &Value::new(&Coin::from(u64::MAX / 2))).expect("should add input"); tx_builder.set_collateral(&col_input_builder); } diff --git a/rust/src/tests/protocol_types/protocol_param_update.rs b/rust/src/tests/protocol_types/protocol_param_update.rs index be9ce7e9..e114154c 100644 --- a/rust/src/tests/protocol_types/protocol_param_update.rs +++ b/rust/src/tests/protocol_types/protocol_param_update.rs @@ -183,6 +183,7 @@ fn ppu_setters_getters_test() { assert!(ppu.d().is_none()); } +#[test] fn pool_voting_thresholds_test() { // Creating unit intervals for testing let motion_no_confidence = UnitInterval::new(&BigNum::from(1u32), &BigNum::from(100u32)); @@ -208,6 +209,7 @@ fn pool_voting_thresholds_test() { assert_eq!(pvt.security_relevant_threshold(), security_relevant_threshold); } +#[test] fn drep_voting_thresholds_test() { // Creating unit intervals for testing let motion_no_confidence = UnitInterval::new(&BigNum::from(1u32), &BigNum::from(100u32)); diff --git a/rust/src/tests/serialization/general.rs b/rust/src/tests/serialization/general.rs index 7ec13e4a..32e6b2c6 100644 --- a/rust/src/tests/serialization/general.rs +++ b/rust/src/tests/serialization/general.rs @@ -643,13 +643,11 @@ fn versioned_block_deser_test() { assert_eq!(unwrapped_versioned_block.block(), block) } +#[test] fn versioned_block_round_trip_test() { let versioned_block_hex ="820785828a1a00101e2c1a0143a1b35820cee15d6daecaeaf320a4ddb1f7c437846f798e4a9cd08d12fb7821b175c980115820e3c87f196ce9fc40a8d929f3365e247f8f71e1981bffaa7cbdb0aa3a83dc790d582054a580ddf99f67818e0312374cef1f7dcdd59450930898d4d2d10e606b963e49825840ca5d1f988222919982b6a20f4f54ce59626fece7d7c607487762129d5196c731bcd11dfefee94ce5a60a733478970631d41bfc0620769fa7b66ebc16c8a89e5c58502855f21ba12fb101d175c376e19496e464bf37c92ec21395e5bffb35e1ae8f433f2139de166161f2b2b26afe656d3d170acfd11a535a80fca6325479d2262e208b0a4b98a01f4845c45a58fb84cb58011952de5820f2e4c6554da5b773c3f7889944fdb5b1791f8552dcafe2916041a531860e912284582039b66a10f6b78c541ea5ed6ecec4c6dd385b869026ec16c4e48414cb39cac38b0018a258409ccd6cf71a5c337f71a41904c0ea0a889a2321c94374c3a8402d8a7dd25b222abe6cb325c6b39bd63bc99fa84c094fdac2523b72f1a22081903dd047be9be9078209005901c006b35937aba451d4738486ea3ba5644d9306651f09b2012de8acc5136771fc725164ad669dd716f2726dfe138137d09feddf9450b3c51a601577bff35d0d2202c887a260855dd8310fc9365f56a4757ea7d81103d409ea0a8ad51c6ae52fc7fcf4d3d456384b7566b70a2b7bd4e21010a1ad5df12bf5d332e82c1a4a5cca39740252e0ea163f206cacf193e59ebbd0e20d621fa9913c60efe1c035d8ebaa354fbe45768339d53a4e8e04fdea79d00b869a973cfa3eeba2e2668b1dee5fcd7d13762dceb4da804fd749e5fa977ead0003a9739837aa68b80bc5a32ee015f667574a7fbe03b4bf5b027c945fa4497c01efb4ec51f3da2fb2dda33ea7dc1dedcfd2ea2c0a4da5a1c553d033033f4986e2ef5c09bbe326a25e5082c1eec406aeec8105869a9d46a83689a2e026e6e31d4037e700ffeb2920bcab88d1a400976881d17cd84582521482db0be460fb43de88e40a4ee24745ac92ab8b40329bde1d855404478c9f59b05e6322f3640ad6f40d7a771fc6d58e94f8fd0006d54272e36a30034b14327c2e6ffb92ead2f8a4165a3e4a1c44de677829e8e797547b3c0bac4b5ea89cb86c01d5b1e67aee3ba36b8cf9617484db2e4d1bfc37fed1fabb73ce3c9fa600d901028182582088c310befd2e8c9b33b340a56f4ea8141689c16eddef5d9c606055ca35897bd600018182581d6052e63f22c5107ed776b70f7b92248b02552fd08f3e747bc745099441821b00000001f09cac72a1581c34250edd1e9836f5378702fbf9416b709bc140e04f668cc355208518a1494154414441636f696e1916d6021a00030739031a0145283409a1581c34250edd1e9836f5378702fbf9416b709bc140e04f668cc355208518a1494154414441636f696e01075820e2ea39e82586fa40304df3c2cfc753c6ba8aca62e780f01a0519c34c6d7c25f5a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe185b0181a2005839007ce8986f5f3fb526a6d35d32edac0b6c8624daab6928df1964459c2723bcf2892e8182a68e3aac6f9f42ed3317d115ebad12a17232681175011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe185c0181a200583900f7fa5ddf2c3c46ed4d913812d38dd43d585adfa884938adaa7a075dd1bf1e138f2f8beabc963c94cc28ee8ed4b41744601f2edaf50b21efd011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe185d0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18600181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18620181a200583900189f009d9536b1f52f0629bea3323f48df0eacdff68726f1a32edc49db89995ed3aa88dcfb43790e2e51761fcba7e8594bcc67684f52d524011b00000002540be400021a00030d40a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18630181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820a944bb37a59451f9a47d5c8888a8a1145527ffb5d45a17c1df40926a42ad08330001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a400818258206a7e3a926eafa74f72c0d6a721dfdee7a7202b1fac4eee12d8c6dd030217890b07018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001eeb2890a021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a300818258200580612292c60a12689142d795c39d577aac4083c63a8b572fc10a69c0ae51fe18640181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820a439638a9f8e0f52e153126e8b794b7514f3a0921b08b611f3866a1fc75b7a560001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4010181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4030181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4020181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4040181a2005839002b11f0e68a65cd6a243f1a5ec9d597ba972675a00bd3172a7ddc0293b1d312a60b3824d1820dec5ec769c4af7d7598387c16ca5ba6259f46011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4080181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a400818258203298fb7878ab004c1a4b369eae7fc89abca6342f06557cebf6c89f2d8c21aa9900018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001b3152865021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a40a0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a40d0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a40f0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a40081825820dcdbb7a98286f5d48673c95b05f441bc40731b1e4c3429d192f0c6b7fc3749d100018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000002186e835b021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4130181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a300818258207e4fddb60c2034bff37bb7069f9318735fcf4de03e01e9f92251c96dc59318750001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a40081825820705ab68071f9af1d314e74a053e39a52f3fdf96f9a1280dab30d45f04c05436d07018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001eeb2890a021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a400818258206fe0c3eae23f779b0694747ed28612f47271b45e84bb3d23c11c1ef2e90fa12100018182583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b00000001dcd122b6021a000296a514d9010281841a3b9aca00581de0db1bc3c3f99ce68977ceaf27ab4dd917123ef9e73f85c304236eab238106827668747470733a2f2f6269742e6c792f337a434832484c58201111111111111111111111111111111111111111111111111111111111111111a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4150181a200583900e698ee1c7d4361c6faf62716dca0d435eafd0b25e369a5d68455beaa0f5c16e3e747e7c5a9eb3ff189c0e330683665de9326d2ffe35d0631011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4160181a2005839005bed6070c549f1560cb89361564cd2be7b36536e8da868a218d514e5fd2e3e48dbc0278cc58e47ed50a1ba90cee61ab22c8f4a639c913d4b011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418180181a200583900ab3cd541317d83d072bcc38e1294166dea5d97ce453424b84c547cfc101c5bfa799985a6e96adbb5859e90cbe4a0e4edcbef408a3622558b011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4181a0181a2005839003b3ff2a2d98519fcf53c7abb15b6c4dfe76209c52e4c2065b33b97bc465f9e3a6c6c3a8eac01d39f519b9bf3bc031480936156b7cb2e45c8011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4181d0181a20058390050fc315c9c141b4da62b10525cf5049e8ab1bb8bd96903a6d87c5272bc616bee900ed3135eb065a11faf2100670f0182ae86827df52dba96011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4181c0181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418200181a2005839005deef04c1b44c606775db03444beae0f10c75f437c131628d264b17c439dc3dbc39b8bb91832384d44263001591fd806df73b413da861fd3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418210181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418220181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418230181a2005839006087b2d29b8a424d7e3a756d08cb078ecb5215fa9344343ac2c6bfb02bdca5a48eca12260be94aecf81b9f21ca41871e06cdc4d12b5aa2e3011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418270181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418280181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418290181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4182d0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418330181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418340181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418350181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418360181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418370181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4183a0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4183c0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418460181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418470181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418490181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4184a0181a200583900189f009d9536b1f52f0629bea3323f48df0eacdff68726f1a32edc49db89995ed3aa88dcfb43790e2e51761fcba7e8594bcc67684f52d524011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418520181a2005839005c85eb9c0aa544a6bb5d1577c7a588c39caca885c8a3a9fceb0933a2cd1a02667d16df1e109350555c325023dbfa31fd9a4a8b99ff904d96011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418530181a20058390030a33756d8cbf4d18ce8c9995feca1ea1fc70093943c17bd96d65fed0aed6caa1cfe93f03f6ef1d9701df8024494d0b3b8a53a1ee37c5ab2011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418540181a2005839001da17fce0b5ae3e7feae117785eb78c77b6272be34a3d381a2722154d29c294b138005ca78de7b329ed6d2763a74a3fa1710a403e18fcb4a011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418560181a2005839001da17fce0b5ae3e7feae117785eb78c77b6272be34a3d381a2722154d29c294b138005ca78de7b329ed6d2763a74a3fa1710a403e18fcb4a011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418570181a20058390098bebc68cf6f12a7aca6531cef75d83c1b6e323485146195ffdd727dd99bbe7f44fd382de2ca6d9e5e9cc26f940decdb1b12b1a98e343274011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4185a0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a4185c0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418610181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a30081825820058e5c03e1b0e08f8710cbbd59ea8589ef0cacf031727146d53e9c1067bf54a418620181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564050181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564070181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d00045640a0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d00045640b0181a200583900003ad89c3e2ed8e98d2cdb207afda3a49cf73d7df70cff6f35d5a5afb7137b5e2a626ebed51ef0261692b21cfab50bf053e989f24d65f48f011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564181a0181a2005839005746c1b032f826b5e5256357a713a7ca63988fe2ff862e0396993b97ef0cbd5199d0e460725b3e79d371deb42110d40b778d3bf162777d4c011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564181b0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564181e0181a20058390020de866f290f45141315081d903f3eb3c06f3735e2a5b70f6a138462ada99823bc02291029853dc5338bc6e62b0540dbea54d9384f372639011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418200181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418210181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418230181a200583900057fd21bf903c585ea95dd927dee373b4cc1febc61874c48571dfb88a0a307af2a3e6a55a238fe323f9e54be10c54a8a8b25939a4f9ab35a011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418240181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582043c59e533d0934a6878a81403ec71a2225bb22d0764471cac8b5545120b475760001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418250181a2005839008f221a3021b0c09c57336733b0411d9d664e5d5e259096033a9d4bbecbce4335fa28195472386e53f0c3ab74d5cd254797d1100e4b1a33b8011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418290181a200583900d804dcdd0b0ec6ed0d8d2cd210a03b14f87c6849024930a8d6c91cf551a6a756817f0a3e1a1410730acf27202e7a9b63de26087e5cf466a5011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182b0181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582072af166d0cd8883c9abb1189ae93acb1fce482ca57cad9b14711bca9627b98d80001888258390038be1948e77426eaca9f967becc5455b11d3d40fb06b99dd3a817d5e75c7a5e1120727f24236cfb5981ec30fd50a2684a5aca866a123a1361a05f5e10082583900bb17dbac8d4a3452dbb6d0c664e804deb14a0b95ded5274007189c3641868c2b4e5289022a3a1f6f47f86823bc605c609d2c47a2db58e04a1a05f5e10082583900f8e61d5f13ab575771af475ac599ad88c7116339f82d2ea969b0e601d6d84c6a5b05cb8f89d24e9d46926975fa1dc08a58b3c26e96c06df71a05f5e10082583900693e466f25213254e061fdc95f8a5f07bf6ef0de0478adbf89a3308f7c4641296645e557c0a6426e140a09d4ba423d158aba1eae06aba7971a05f5e10082583900d93170064d82eab9dea2b3141bc88503ec80e93c8691fb6b223fe310877c17de5bd978526e288334114fada629f699c4e799394aa45c2aad1a05f5e1008258390093ab1cf6cececd048265573176355a322b7732299bbd624f655af2f674984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da11a05f5e10082583900bc032a8614a84f5d9ee772f2788954e9d664b4264226cd36d0c4ddaeaa22f3a63400c1d96ad118b5cdd300cd039e83ae1957a35b764881941a05f5e10082583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a41b000000022a4fe9af021a0002d351a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182d0181a2005839001c4595c4f3180180c9e822f1ac0f2955dd329eeeb94752a84281ff5295558528c6e1f7f2e16d94b74d227b9fd709edd2aeb0ab1556db75fc011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182e0181a200583900c008dd489b67e0a774fe18d79ee8d1e280264933d3b31ba44cb37755dca94fb45aa2192ab26eff8409ea010fa2d4761efa92437e0d5b6b60011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d0004564182f0181a200581d60fc38cce3448bf3d2790ca85d6b09026f7c86f21095c31f9925cf49a0011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418300181a200583900b5187cdefbc5b49ddc17b423c079f0717721a03882a3b265bd4c12e080f326af300273d19d5a541d45baa42ebc04265816735b026b5f34a4011b00000002540be400021a00030d40a3008182582005fb50ceafb7ec5392f24b830572c949bf5de8396ea862298285b7a4d000456418340181a20058390023a6fcbc8affc61518cff034c013aecf083dc64fe673ffc95cc9fd9e1fad7e0b1d0dd8820703a4f59c2488d148193a48d8fdc23a6dca8137011b00000002540be400021a00030d40ff9fa200d90102828258201287e9ce9e00a603d250b557146aa0581fc4edf277a244ce39d3b2f2ced5072f5840ae4cc1168265e2f60fec9ca9b644eaa42a77e65a39176e04aef29b01e25653a307d39ba61761f8d1ca44696e1d6bdf7a0679413ea3c448f76268e6eb02074102825820742d8af3543349b5b18f3cba28f23b2d6e465b9c136c42e1fae6b2390f5654275840112c95c93013e63fa73ee6a645fd522808d4dee019626e395a8042755c15fb1824e1503c17ea843a838809f55822366b05bce2e378d0b955e66d625c8e9acf0001d90102818200581c45d70e54f3b5e9c5a2b0cd417028197bd6f5fa5378c2f5eba896678da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584005383334e98e9263b93ffeb3e5908dbd5657caa67d32f9964d7f91dbda76fff164cbeabb981beef470d0d3e1724b85847e6fbc1c039084a817110eabf9d29e08a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258406151f0d0cae4ef0ace62dc03300dcee276765c1b493ac61f770d0633f0f71fe0d642ef29b593c511034a847dd569c56a0278e063c46d6d060abad4e6baf4b705a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840cf518f30d291871a0277e367534557205cc015d3a0d78070e1aee298aeaae3e81d70b42c464a63fa741b5300b48c1699dfc39fdf07f96b8eb240c7d6d3267805a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584056185de4c1d012d322e7e82ae98f24887ed7264f262db53f019e5900b9110a439e5a462a75be036f9f04b0ddcf09decb0894c7b6b9ff17ab4cae8184072d690fa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840ab78c606155b6aacbcf6692a18d97dd8773b4ae4c96684e4abb9cc59233023f67650ef7259069deddb65ba770ac3a1401d169ce33ec9483b8ebb9e83472e2c06a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840e21574b02002efcfe81382326aa98a0a971327ad4049690a04985400fcb14db7adc8149a0ce4dbfb5afa0d240ed9da23f15c1020d2826f50fc579a10a3662d0da10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840e64e3c19644edb6e788112ac75b4426ef94d535f1ffd9a34e86745777feaf083dc8e847a62634fef320a08b566c24ea26e8dc9e7b49fc456554215cedc0d3508a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840f49fd8eeaa366873aeb2530b2bbcbf7c5970866162ae7250c4b913e19062de1396ed70d1e32a4605071bac11c2cde3fec1dc5b37044cbea073668fe5c478400ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840f0ddd023e0dbda32d296b359db809b0088246e512fd34c7c0cc4b5ae974361873e02330e955eaaf97117525bcb3cd014bb70810f8d0d62a28c3242c86d8c3a08a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840615ee0444f039f02b26791872d6cd5562728cdc6dad02acc71475567b09f3d4b4655c601bf816ef6d11b2f3f81eeb6db09d800bf1bf4e2daf29493338c232901a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d62bfd428359f4cd04950cc73f574f0ec1c613284fdff8028ed3d876b18b69335beee9792410c6dbdc1b196b4703f250fbaeb66569869ae97d7ee843b9053405a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d813a836cc44c70647b2e7941fb72a4f720f16aca17e155a6c6a6f9bf175b1e49a3beff6edcfb0c442cc24790a12ee0b1d499a32fdbfc0a850f4846708ea340da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840aae6ac20cd419eaa7f3a95144f9ccdb46401a0db295d544e920a54b5c24fb63197fde03f12174800c3cf5318a73d92ebc53c2ba97803766892add32fd9feb400a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584071d223fd255df1e912a9c0a8230ee9f0ac95d0aa325cd31e50701ac355dfb5f3fbb27983b372c1410156eeba9163aa0f8a9787dab8c44e7afd4e2d07459a4708a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840b7f821c0ff66fcbbe7c61f43725aa2234297d6765e002d0130301cba13465fe89f59a596549725542445c76d17cedc9c9cfea8b8862d41405646d725dabc7d08a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e4584045830e5de108b9353b0c4c561af296e79eddb26b8ccfb18c5bd9fac1baf8d477691229c0bb9ea212ab56d9ae76c92de6ae50686fc0619510b8c35fb69c6b4402a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258400635ac784fe71d2f7927114edfc709dcb56013617df4edb9b6b770b067e7709e8abfd4cdcdd61512894fcf02f16e1d72bfe60fbfb86b815631d791bab132b909a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584032d67fe72feaf2175455815bbb624ee1b93f5efce905280158db94bbb2b5371d9eaff1bed6eddf9eafe8ff64b55f1d7213294bdb459e0b00c437edbcabf4cf07a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258404533de52e9e3f51e39951c9e197f6900081e98f38f3af5c4a7fe9219f8c311eaa43942b7a290ecbbbdd0bf4ef4ef1d11c39e6de4083c86892a6026c27bcf2509a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840d46541920ce2c31ffaa00cb20e8f5f00f48b6b8aa5cda67d22ea4bf12fd318461a0d8c25ee04cd7446e18f0de59b0fd4f6631e29bc8207073f2404793ae5f108a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584041bcd52ae44a3ffaa1abe1cab6c8b21f8010e2f1aee1d8651b9f6e94aabf5b2dbcedb45dd154b78dce1c5b9679956dd25153a0d945d3eb83c1de3b713e721008a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840027da3169c9c1fb9a67104061698bb0dadb2f58b660af4b461e7353fab1545a3d03157e077a388ec8556176239df3241255feb1f13b5e406bf7c3ad3af7d4202a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e458401ae63dc54e511965f7010971de7fb99585afe492cb8084b395ee01555c1e5657ab08a24be0f70d4e9cd1bde2a6ae31815c5f64025c0415afe2d503b2cb5b3e0ca10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840d2211679ca8e9cc5de71b21bac2b58fd355f5cbd2b42ff31ec37af77b776fb77c64fa76a830f240c29a4b95ae6bff9c58fc6bc2b3d18b57a2af11710ae6e3006a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584084bb7bf64ecea446d6beca88bfa2c7de71d8899e96006920c4c18e52f042aa71e1d27e60bdb6d9d6b1aa2e3330f59ee95b2c001909ff8994ea1fe4e5cd7a760aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840c6f3d6194a2fdb2a50417f80dd020adf866c91a102f22eb6bc66f5131292a1a42e9a3550e18e06cb17bd153c08f55a6cce3a1c82052ec9197495900f3ca4f407a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401a28cac7e80a657563e1433459f369bb0cb05e7e3ead78378dfc2ad15baa344e76e1ac0ca631c67848e81896fd6838b3821961928911635ca069f12c05772a08a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d201ce4ca5572db792d1563ef3614f2e2b27072e4751327f4a8f75201183a189ac57cdd9399474850e87031c7545c896ebab3983434bb6005690b9ad8fd9d50aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258403f45e44aa7457c714599f0100702ec265e91493e30c57ba4f1f74d912858bae8fb71fdf2faddf865c816cb0218eda0db17b707c8f429290f1a1c02b6a4450a0ea100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840e16b1d8f5992fda268c9d7e5c0ab6c5d38b8abaa6b92ccae5b0d2f3079d098ab67ba9a15b27807746f3c7695091ec5bb74ba8772baae14d2786eb8a512d70201a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840628a5491c5d0b4e0202b7aae87a343afd642345b823252355f6d392d8398d2174c141622e3de167b4f82c3cb8b4e8105b341851005d2ec0c1e35c354006a910ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258408ad2ee919f520a903764e0322800f7c086f870374f063d2e62ad1dfbf54e71305d90371abe3a196132e123b9248281f2d676fb29442f80249f644ce1185dfc03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840d53bf84fe8712171151bb6d5f988d76428292639737d817986b46d629aea6eac2a90675cbf0347ec004ce23f9ca0b2dcff5c6d1be91ab478634de8ba8ab96102a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258404702623a2a94b9efbc03dc7d506c4bd70c1e0fea8b21f3b76c592883f0c364ffc12215e59f9ea4d2eed2e786376e6128650b4c9c3f6ad9419f070fb458efa10ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584072bb89ee81a7bcc4a866ae498d3ca076d5d5a885547c7f5899b8b59b3077310f58df420e470bf36d4ed5beaaf30eb361f04ed578cdbd0ef04f7cb573f0c0770ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840e112bb46921840820f4d5b40ec45699bc1b818ca8fe77fcc222a6fa1edb2425487f32e2039e2cf6077ce1e8e2e0b0d0581c64fb866c1c183344af131ccb9390ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840039329e261d8386f81a28f5ef5062196a46b5d4389b06bde97e662f69e37812c3ee75352f392121f58e76e5c1e1649656632b01ea46f932ccedcee102d625001a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840c1dab5e2482101ad1bd04f4018425c7133171aaf1274573ed35305f4e37bddadb3636f0aa098d2c0b5f615e8eb629bb94afac5d4c4c0743dba16a847d898b905a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840abb898b3e1ae3c4c9d068a4517b83a070d4037f979b6365ea5eb368e7d43b3fd2152fb93a462fdc553f973d90ab136332057fb66ea529d4fbc53e7f082b6fe03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258404a09ccfd9c09c6a453f46c721d280065081d89aa4b84fc809d75db1b923e78963bcbf36d64786d8c09c527e90da744e83116617b2e18d9145bac6cf66f876c08a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258408df2408adbd8b4c990a913b9ed2455c9de72d561ddb8f3ec0da5d1513f417a2fcee9ea9ace30cb840d37950c41455bd3655d12d534b70a6eac7034950f821108a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840534b54cc145722e3f7a62935d84c025e17e31c4b08d3f3fb16bb7673d37e9afb07fbdb5ffce5aeef743376bac161973e565e1c12db97bcd879cd7e9030c2a00ea100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840664fd5d8bc5d93509d02104f39e7a22c6cd894f49935cac9e662a9202b9a64baa9f55cd8aa07d3d1e095e9b974c59c0a8c50d14b0d077d70e236ad5cf52ac104a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840469cdadb48349224303d14980cab5c2ae5dacd0f6e36714d8dcb9ca85fa4eb688bd7b1334e30f8718178f7f36d8c5b204e0f9cdce5f88762fc2cbe2cb28c1d03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840f330820de229a476e1b3f84dfcf9ad98264070212e6e2d61d8b05afb1e12a1426cfd7cb0b284db237d5882cecd6e8f1fe2cf9ddc06783242812178bcb053a105a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584066b89001a28583bed59dbd07d359333207eb74d39ee092c0bf1da4351da64d38c9938a3682bb52a4253dc76074767b4cc2bc1eb2a31bbe6be3c45a5c52cbdf04a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840f365b299297ade5117d72156050cb81a76ba0b859cb46d0f2326c4071110440108b20390f878ba082d41217b2a8fd5f1435b9ba48d176ad5dcb6faff54976b0da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258407fb0b1f28d6ca64a29c6c7a51a2ab3436809b5038c06b8204104e3b98afa915246f742e2f1bd569f5132d2bbdcaeae68215a0b0f17f6367ce4eea37ed951ec01a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258406e6d2263c440486fc1b3c2aa930e519f20b70f70c28cb532d031f63cefc55c56f4647b10dd6390aa0d0f2ba75bf6cbe3ce2fc6d928dc4db74388f1e5e3057b0ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840dbb299923c24a70ae10dc637d862b750b3e6548e64c590674d2ceb87b7535199ea8dfd024694d26ae1dbbca683b1a4ba90af7d1680a9b8e4819a2ee6229e2408a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258405b2397d031c48f56b43416daea99dd3d8bd1733cb83c2a688dbe8b5dd9bfe64d596280d71973d7d540e929262dafd79b14954b855635fe845642090241003503a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840482c9089f2d60eb069432bf7f7213178a6fe3d52d37a4fa5aec677875bccdac64de7a45c6eb0bd4996414412b12d3e887a1b391e775ef56c47d53f9c944d020ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401972d18c1e9c62837121efafddc2ec778a3a8f9ec5f534c9922778905d8f809609d6c92e427852d8b5f822ad590fdeacf3877c8056f0768b44b025a2b79e7704a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258409b7141b69a493bc4d597a645ed488325492772ad4c3cd5c5c7805a5d951a4b6ed960ea27428d1add867fe7c209f4e65000bdfa878bd7a4357b223e9c55af450da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258407ac2d7823887de83bca86216e424ccb63fe9f4fa1f106bffc6afa388e91845c97177c410f1a8ca5ecd9f2701c42f5f9dd2faeb0ecf2163a37521badc8a6c1b03a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840c49b6714ccbbdebebb9461a2efb39b9ac5e00a389aadfb2a1b4fe384733610c45e1f03825f65e182988da97659a71e378d49d17fb93d76b80d579b7d49399b06a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840b53ea3508cbd7da47fef05e98c0b31b13ec33de4596ba4061a8e04d91b1015c49f328da58084a6f573d93cdb7aa0972a1a1936a69ee7362adf65df3eae4e2400a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840b1c6b15b311423aa83dfaebe118d1a2a3ff006399f2a63fa82f0d0e0c12bc2b844ec78f5bc8baeef588d15b2237db48cbfa48361a6d630052c9b68e62e035601a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840bb544721cd95655497375390da19fbd87b3c63a4edf333688e2fee7935e96b6572f84b81d80fee5239062be6d3c6a75a5f0c50696d3c6663d26cecdfd8fdc808a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840a7018dfacec705459856bc706b7d05d04c56867fb64dfd0cf97fa980e881cc609e91cf6df204fb6906f860e5cf390e0290d302b6231664aad8c2b4cb30090609a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258403ddf27cce21fbf1a361233d2bcff92ecc9d3cce64c3d8186495e3509b843a0a326f528be8241b8557bf3cdac9c304fcf0fa8fd2a8e389d6acf9fc62b5626d705a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584013bd40ae7383feb674c2cd3357122aec3f6efe17b9b4f25c47cd3dfec194d0c4f20a52cc30fb92245c1a20a962772808f3dc6ee51261c86af16879a1fed2210ba100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840a1cf100aff45ee45c0f868214187640c8c29cb005c7aab7100ff86338d78f972733a611b4e0dae436fe9e1493d6ece69c35ada3cc6506e730ea1bae277468108a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840667d6d2987788454c41f2e86867fe98e1fd48aa789fbf9cf2208f927a8f9941d0384ebf3e3e45ee80c49934aad9b6ccaa13179b69f35b9acd21b55f56caff80da100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401cd5c48fa46d8f0fb07c7737b7719d1fba5729478be3eef3e2e19942c4d6d54b01a569eb34d4f4be84a2f6961832ec17bade0511cbc01f5db5749a09bb4d8808a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258403bb5ddd91b5f5d7366b41330bf5bbbf7cf7d703bd50376ac21b07c6da696562266361678c06247a57111c63bc1fe58463a8c125e0d117bdf05cd4fe57bb8b90aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840397067045ffe0cf7126a5f73f228e1bc8721c617ebb7c41c1bc2f7b6c8cc50bf2370bc1ee679bcb0581e11da1e186504f2e3f3322fddf40a1863067ffc5e2903a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840831f5ea5dd354f5a522e044b53aa1966d036871d5a3b7d2323e404996907a33aff5aabb9db22301064033045cbf14c91d29de84b8fbbb75683ff1cb51fd0920aa100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401e8cc65db39cb5e9d54dac50cda84c55fd2f989f667a11dc46521768ac2f46a27a70173a92e849ee621ebe3025d87088528e7450b8312d678b6249f5a124f70fa10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840f4835bbcf5459db0826e27ea95d3ac31f7bea56c0253716212ef421995c7546a963ac89dc6cffad75692a149372cbdeaa19a9dcd171ac423711e8d71c495d703a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258408039411659145a9fb3863b2ae2f3890009bf004332f58daa6662368a7378d215cc7f40569284d5b86c5a7be210cdcb5551633762b5a7d3f8ad2095a220fec609a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb82584002c9ec1d95d0464eba5f4a656d72b55a92a80078e83f2f47682729af0fc782a68f3f31db7c64018ae8fbd36c5ac72d5573357a7578359056b9d3f9a29467d80ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258406f176d0fdb8768aad902c8fc115eb797719ef62a93938d7f09bbb213a88d61294143ec1d508a2a450f0e16ab3e2ffb7e0ed4cd7f75b3f2ff9f70cfaa77764506a10081825820b6a42d4ccc4d26adaec67e8578bf31f13b1b7e640527356248f2ec547f9de6e45840f4262eeb9183eec1e896b9be61984ed9d4192b38825ba1b560ea23fe6e3224d3c94f4cc64174c1d9166e665e1a1ff8f0c84024bb8b9068b853fe4ce683d96906a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840df64e327056e335f484582fa0e4188e62620968e955431fc3576da2c1935b15ec605bb5d738f5000dcdc022646f9545d6932c2c79611dccab116295ca03c2b04a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840132cce5cea5d8bf7e9b802e4477eff041ebe1c12a8b8658a42ae91727cbf4f39b0d23831c70923a68ad7a023092bcecb61ac6253fdd17be00cecc37a71301300a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840842ecaf1b907cb34799d78d6f35eb349a986559a396840aeba5f6e8dc7e4172c16bddcb1f926a21175531478773046e9484aeb4ca83c1cbaf25f5a4813afdd0ca100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb825840a417cdf9e02755e53d6061ce0c93cacb7de24ce33e3fda9ac3a85414a7bf62676446822875972867d5647e46c22e21099e5dd8e4114949b30b86146b0dba1b05a100818258206ca065df8b220ae79a96e871f92e53b7e816200b789749ab5f38e105a436eb8258401f2e86831349fa458c3e2403e2caacbf046fae3c513575e8ce2d34037d34337f7e58cc98cadf034e8bce930335285220624945b316fe6af71e8ef0d12ef05001ffa100d90103a100a11902a2a1636d73678f78264175746f2d4c6f6f702d5472616e73616374696f6e202336313138303020627920415441444160783c4c6976652045706f6368203234352c207765206861766520303132682032386d20323773206c65667420756e74696c20746865206e657874206f6e6578374974277320446f6e6e657273746167202d20313520466562727561722032303234202d2031333a30313a333320696e20417573747269616060607820412072616e646f6d205a656e2d51756f746520666f7220796f753a20f09f998f783b4265206b696e642c20666f722065766572796f6e6520796f75206d656574206973206669676874696e6720612068617264657220626174746c652e68202d20506c61746f6078374e6f64652d5265766973696f6e3a203462623230343864623737643632336565366533363738363138633264386236633436373633333360782953616e63686f4e657420697320617765736f6d652c206861766520736f6d652066756e2120f09f988d7819204265737420726567617264732c204d617274696e203a2d2980"; let versioned_block = VersionedBlock::from_hex(versioned_block_hex).unwrap(); - let nex_hex = versioned_block.to_hex(); - assert_eq!(versioned_block_hex, nex_hex); - let bytes = versioned_block.to_bytes(); let json = versioned_block.to_json().unwrap(); @@ -662,7 +660,7 @@ fn versioned_block_round_trip_test() { #[test] fn redeemers_default_array_round_trip() { - let mut redeemers = Redeemers::from(vec![ + let redeemers = Redeemers::from(vec![ Redeemer::new( &RedeemerTag::new_spend(), &BigNum(12), diff --git a/rust/src/utils.rs b/rust/src/utils.rs index 614a38ff..a062301c 100644 --- a/rust/src/utils.rs +++ b/rust/src/utils.rs @@ -4,11 +4,8 @@ use cbor_event::{ se::{Serialize, Serializer}, }; use hex::FromHex; -use num_bigint::Sign; use serde_json; -use std::convert::TryFrom; use std::fmt::Display; -use std::ops::Div; use std::{ collections::HashMap, io::{BufRead, Seek, Write}, @@ -16,7 +13,6 @@ use std::{ use super::*; use crate::error::{DeserializeError, DeserializeFailure}; -use crate::fakes::fake_data_hash; use schemars::JsonSchema; pub fn to_bytes(data_item: &T) -> Vec { @@ -1097,104 +1093,6 @@ mod tests { use super::*; use crate::TxBuilderConstants; - // this is what is used in mainnet - const COINS_PER_UTXO_WORD: u64 = 34_482; - - // taken from https://github.com/input-output-hk/cardano-ledger-specs/blob/master/doc/explanations/min-utxo-alonzo.rst - fn one_policy_one_0_char_asset() -> Value { - let mut token_bundle = MultiAsset::new(); - let mut asset_list = Assets::new(); - asset_list.insert(&AssetName(vec![]), &BigNum(1)); - token_bundle.insert(&PolicyID::from([0; ScriptHash::BYTE_COUNT]), &asset_list); - Value { - coin: BigNum(0), - multiasset: Some(token_bundle), - } - } - - fn one_policy_one_1_char_asset() -> Value { - let mut token_bundle = MultiAsset::new(); - let mut asset_list = Assets::new(); - asset_list.insert(&AssetName(vec![1]), &BigNum(1)); - token_bundle.insert(&PolicyID::from([0; ScriptHash::BYTE_COUNT]), &asset_list); - Value { - coin: BigNum(1407406), - multiasset: Some(token_bundle), - } - } - - fn one_policy_three_1_char_assets() -> Value { - let mut token_bundle = MultiAsset::new(); - let mut asset_list = Assets::new(); - asset_list.insert(&AssetName(vec![1]), &BigNum(1)); - asset_list.insert(&AssetName(vec![2]), &BigNum(1)); - asset_list.insert(&AssetName(vec![3]), &BigNum(1)); - token_bundle.insert(&PolicyID::from([0; ScriptHash::BYTE_COUNT]), &asset_list); - Value { - coin: BigNum(1555554), - multiasset: Some(token_bundle), - } - } - - fn two_policies_one_0_char_asset() -> Value { - let mut token_bundle = MultiAsset::new(); - let mut asset_list = Assets::new(); - asset_list.insert(&AssetName(vec![]), &BigNum(1)); - token_bundle.insert(&PolicyID::from([0; ScriptHash::BYTE_COUNT]), &asset_list); - token_bundle.insert(&PolicyID::from([1; ScriptHash::BYTE_COUNT]), &asset_list); - Value { - coin: BigNum(1592591), - multiasset: Some(token_bundle), - } - } - - fn two_policies_one_1_char_asset() -> Value { - let mut token_bundle = MultiAsset::new(); - let mut asset_list = Assets::new(); - asset_list.insert(&AssetName(vec![1]), &BigNum(1)); - token_bundle.insert(&PolicyID::from([0; ScriptHash::BYTE_COUNT]), &asset_list); - token_bundle.insert(&PolicyID::from([1; ScriptHash::BYTE_COUNT]), &asset_list); - Value { - coin: BigNum(1592591), - multiasset: Some(token_bundle), - } - } - - fn three_policies_96_1_char_assets() -> Value { - let mut token_bundle = MultiAsset::new(); - fn add_policy(token_bundle: &mut MultiAsset, index: u8) -> () { - let mut asset_list = Assets::new(); - - for i in 0..32 { - asset_list.insert(&AssetName(vec![index * 32 + i]), &BigNum(1)); - } - token_bundle.insert( - &PolicyID::from([index; ScriptHash::BYTE_COUNT]), - &asset_list, - ); - } - add_policy(&mut token_bundle, 1); - add_policy(&mut token_bundle, 2); - add_policy(&mut token_bundle, 3); - Value { - coin: BigNum(7592585), - multiasset: Some(token_bundle), - } - } - - fn one_policy_three_32_char_assets() -> Value { - let mut token_bundle = MultiAsset::new(); - let mut asset_list = Assets::new(); - asset_list.insert(&AssetName(vec![1; 32]), &BigNum(1)); - asset_list.insert(&AssetName(vec![2; 32]), &BigNum(1)); - asset_list.insert(&AssetName(vec![3; 32]), &BigNum(1)); - token_bundle.insert(&PolicyID::from([0; ScriptHash::BYTE_COUNT]), &asset_list); - Value { - coin: BigNum(1555554), - multiasset: Some(token_bundle), - } - } - #[test] fn subtract_values() { let policy1 = PolicyID::from([0; ScriptHash::BYTE_COUNT]); From 27fe24cbf471b77f2e322a58285b11ce9aac147b Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 22 Jun 2024 02:08:07 +0700 Subject: [PATCH 289/349] warnings cleanup --- rust/src/lib.rs | 23 ++++++--------- rust/src/serialization/governance/mod.rs | 15 +--------- .../serialization/governance/proposals/mod.rs | 28 +------------------ rust/src/tests/builders/tx_builder.rs | 9 ------ 4 files changed, 10 insertions(+), 65 deletions(-) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index ca8a00b3..e5b4406e 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -207,6 +207,7 @@ impl TransactionInputs { self.0.push(elem.clone()); } + #[allow(dead_code)] pub(crate) fn contains(&self, elem: &TransactionInput) -> bool { self.0.contains(elem) } @@ -254,30 +255,22 @@ impl<'a> IntoIterator for &'a TransactionOutputs { } } -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -enum DataCostEnum { - CoinsPerWord(Coin), - CoinsPerByte(Coin), -} - #[wasm_bindgen] #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub struct DataCost(DataCostEnum); +pub struct DataCost{ + coins_per_byte: Coin +} #[wasm_bindgen] impl DataCost { pub fn new_coins_per_byte(coins_per_byte: &Coin) -> DataCost { - DataCost(DataCostEnum::CoinsPerByte(coins_per_byte.clone())) + DataCost { + coins_per_byte: coins_per_byte.clone() + } } pub fn coins_per_byte(&self) -> Coin { - match &self.0 { - DataCostEnum::CoinsPerByte(coins_per_byte) => coins_per_byte.clone(), - DataCostEnum::CoinsPerWord(coins_per_word) => { - let bytes_in_word = BigNum(8); - coins_per_word.div_floor(&bytes_in_word) - } - } + self.coins_per_byte.clone() } } diff --git a/rust/src/serialization/governance/mod.rs b/rust/src/serialization/governance/mod.rs index cf0c3176..670ab6af 100644 --- a/rust/src/serialization/governance/mod.rs +++ b/rust/src/serialization/governance/mod.rs @@ -1,20 +1,7 @@ mod drep; -pub use drep::*; - mod anchor; -pub use anchor::*; - mod voter; -pub use voter::*; - mod voting_procedure; -pub use voting_procedure::*; - mod voting_procedures; -pub use voting_procedures::*; - mod governance_action_id; -pub use governance_action_id::*; - -mod proposals; -pub use proposals::*; +mod proposals; \ No newline at end of file diff --git a/rust/src/serialization/governance/proposals/mod.rs b/rust/src/serialization/governance/proposals/mod.rs index 8bb84bea..3252dc46 100644 --- a/rust/src/serialization/governance/proposals/mod.rs +++ b/rust/src/serialization/governance/proposals/mod.rs @@ -1,39 +1,13 @@ mod parameter_change_action; -pub use parameter_change_action::*; - mod hard_fork_initiation_action; -pub use hard_fork_initiation_action::*; - mod treasury_withdrawals_action; -pub use treasury_withdrawals_action::*; - mod treasury_withdrawals; -pub use treasury_withdrawals::*; - mod no_confidence_action; -pub use no_confidence_action::*; - mod committee; -pub use committee::*; - mod update_committee_action; -pub use update_committee_action::*; - mod constitution; -pub use constitution::*; - mod new_constitution_action; -pub use new_constitution_action::*; - mod governance_action; -pub use governance_action::*; - mod info_action; -pub use info_action::*; - mod voting_proposal; -pub use voting_proposal::*; - -mod voting_proposals; - -pub use voting_proposals::*; +mod voting_proposals; \ No newline at end of file diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index c429146d..096683e5 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -3752,15 +3752,6 @@ fn total_input_output_with_mint_and_burn() { ); } -fn create_base_address_from_script_hash(sh: &ScriptHash) -> Address { - BaseAddress::new( - NetworkInfo::testnet_preprod().network_id(), - &Credential::from_scripthash(sh), - &Credential::from_keyhash(&fake_key_hash(0)), - ) - .to_address() -} - #[test] fn test_add_native_script_input() { let mut tx_builder = create_reallistic_tx_builder(); From 2034cc296d4277b98acbe11ec343e14e6ab1e7cc Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 22 Jun 2024 04:06:59 +0700 Subject: [PATCH 290/349] fixed set serialization --- .../batch_tools/witnesses_calculator.rs | 14 +++++----- rust/src/builders/certificates_builder.rs | 27 +++++++++++++----- rust/src/builders/tx_builder.rs | 8 +++--- .../governance/voting_procedures.rs | 2 +- .../protocol_types/plutus/plutus_scripts.rs | 6 ++++ .../witnesses/bootstrap_witnesses.rs | 5 +++- .../witnesses/transaction_witnesses_set.rs | 28 +++++++++++++++++++ .../protocol_types/witnesses/vkeywitnesses.rs | 5 +++- .../certificates/certificates_collection.rs | 6 +++- .../governance/proposals/voting_proposals.rs | 6 +++- .../governance/voting_procedures.rs | 7 +++++ .../serialization/plutus/plutus_scripts.rs | 6 ++-- .../witnesses/transaction_witnesses_set.rs | 8 ++++-- rust/src/traits.rs | 19 ++++++++++++- 14 files changed, 117 insertions(+), 30 deletions(-) diff --git a/rust/src/builders/batch_tools/witnesses_calculator.rs b/rust/src/builders/batch_tools/witnesses_calculator.rs index 23b65a43..b0c50614 100644 --- a/rust/src/builders/batch_tools/witnesses_calculator.rs +++ b/rust/src/builders/batch_tools/witnesses_calculator.rs @@ -130,14 +130,14 @@ impl WitnessesCalculator { } }; - TransactionWitnessSet { + TransactionWitnessSet::new_with_partial_dedup( vkeys, - native_scripts: None, - bootstraps: bootstrap_keys, - plutus_scripts: None, - plutus_data: None, - redeemers: None, - } + None, + bootstrap_keys, + None, + None, + None, + ) } fn add_vkey(&mut self) { diff --git a/rust/src/builders/certificates_builder.rs b/rust/src/builders/certificates_builder.rs index c13e464f..1e036511 100644 --- a/rust/src/builders/certificates_builder.rs +++ b/rust/src/builders/certificates_builder.rs @@ -1,15 +1,16 @@ +use std::collections::BTreeMap; use crate::*; #[wasm_bindgen] #[derive(Clone, Debug)] pub struct CertificatesBuilder { - certs: Vec<(Certificate, Option)>, + certs: BTreeMap>, } #[wasm_bindgen] impl CertificatesBuilder { pub fn new() -> Self { - Self { certs: Vec::new() } + Self { certs: BTreeMap::new() } } pub fn add(&mut self, cert: &Certificate) -> Result<(), JsError> { @@ -20,7 +21,11 @@ impl CertificatesBuilder { )); } - self.certs.push((cert.clone(), None)); + if self.certs.contains_key(cert) { + return Err(JsError::from_str("Certificate already exists")); + } + + self.certs.insert(cert.clone(), None); Ok(()) } @@ -36,10 +41,14 @@ impl CertificatesBuilder { )); } - self.certs.push(( + if self.certs.contains_key(cert) { + return Err(JsError::from_str("Certificate already exists")); + } + + self.certs.insert( cert.clone(), Some(ScriptWitnessType::PlutusScriptWitness(witness.clone())), - )); + ); Ok(()) } @@ -55,12 +64,16 @@ impl CertificatesBuilder { )); } - self.certs.push(( + if self.certs.contains_key(cert) { + return Err(JsError::from_str("Certificate already exists")); + } + + self.certs.insert( cert.clone(), Some(ScriptWitnessType::NativeScriptWitness( native_script_source.0.clone(), )), - )); + ); Ok(()) } diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index f0ed13fa..f730d1c7 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -83,14 +83,14 @@ pub(crate) fn fake_full_tx( } } - let witness_set = TransactionWitnessSet { + let witness_set = TransactionWitnessSet::new_with_partial_dedup( vkeys, - native_scripts: tx_builder.get_combined_native_scripts(), - bootstraps: bootstrap_keys, + tx_builder.get_combined_native_scripts(), + bootstrap_keys, plutus_scripts, plutus_data, redeemers, - }; + ); Ok(Transaction { body, witness_set, diff --git a/rust/src/protocol_types/governance/voting_procedures.rs b/rust/src/protocol_types/governance/voting_procedures.rs index fa65c33f..97b978c1 100644 --- a/rust/src/protocol_types/governance/voting_procedures.rs +++ b/rust/src/protocol_types/governance/voting_procedures.rs @@ -49,7 +49,7 @@ impl_to_from!(VotingProcedures); impl NoneOrEmpty for VotingProcedures { fn is_none_or_empty(&self) -> bool { - self.0.is_empty() + self.0.is_empty() || self.0.values().all(|v| v.is_empty()) } } diff --git a/rust/src/protocol_types/plutus/plutus_scripts.rs b/rust/src/protocol_types/plutus/plutus_scripts.rs index b0ce09b5..92bc768b 100644 --- a/rust/src/protocol_types/plutus/plutus_scripts.rs +++ b/rust/src/protocol_types/plutus/plutus_scripts.rs @@ -8,6 +8,12 @@ pub struct PlutusScripts(pub(crate) Vec); impl_to_from!(PlutusScripts); +impl NoneOrEmpty for PlutusScripts { + fn is_none_or_empty(&self) -> bool { + self.0.is_empty() + } +} + #[wasm_bindgen] impl PlutusScripts { pub fn new() -> Self { diff --git a/rust/src/protocol_types/witnesses/bootstrap_witnesses.rs b/rust/src/protocol_types/witnesses/bootstrap_witnesses.rs index 43563f73..13133cb9 100644 --- a/rust/src/protocol_types/witnesses/bootstrap_witnesses.rs +++ b/rust/src/protocol_types/witnesses/bootstrap_witnesses.rs @@ -27,9 +27,12 @@ impl BootstrapWitnesses { self.witnesses[index].clone() } - pub fn add(&mut self, elem: &BootstrapWitness) { + pub fn add(&mut self, elem: &BootstrapWitness) -> Result<(), JsError> { if self.dedup.insert(elem.clone()) { self.witnesses.push(elem.clone()); + Ok(()) + } else { + Err(JsError::from_str("BootstrapWitnesses::add: duplicated element")) } } diff --git a/rust/src/protocol_types/witnesses/transaction_witnesses_set.rs b/rust/src/protocol_types/witnesses/transaction_witnesses_set.rs index 610feb60..33c0bef2 100644 --- a/rust/src/protocol_types/witnesses/transaction_witnesses_set.rs +++ b/rust/src/protocol_types/witnesses/transaction_witnesses_set.rs @@ -1,4 +1,5 @@ use crate::*; +use crate::traits::EmptyToNone; #[wasm_bindgen] #[derive(Clone, Eq, PartialEq, Debug, serde::Serialize, serde::Deserialize, JsonSchema)] @@ -81,4 +82,31 @@ impl TransactionWitnessSet { redeemers: None, } } + + pub(crate) fn new_with_partial_dedup( + vkeys: Option, + native_scripts: Option, + bootstraps: Option, + plutus_scripts: Option, + plutus_data: Option, + redeemers: Option, + ) -> Self { + Self { + vkeys, + native_scripts: native_scripts + .map(|scripts| scripts.deduplicated_clone()) + .empty_to_none() + .flatten(), + bootstraps, + plutus_scripts: plutus_scripts + .map(|scripts| scripts.deduplicated_clone()) + .empty_to_none() + .flatten(), + plutus_data: plutus_data + .map(|data| data.deduplicated_clone()) + .empty_to_none() + .flatten(), + redeemers, + } + } } \ No newline at end of file diff --git a/rust/src/protocol_types/witnesses/vkeywitnesses.rs b/rust/src/protocol_types/witnesses/vkeywitnesses.rs index 3b8b0216..abe53fe5 100644 --- a/rust/src/protocol_types/witnesses/vkeywitnesses.rs +++ b/rust/src/protocol_types/witnesses/vkeywitnesses.rs @@ -27,9 +27,12 @@ impl Vkeywitnesses { self.witnesses[index].clone() } - pub fn add(&mut self, elem: &Vkeywitness) { + pub fn add(&mut self, elem: &Vkeywitness) -> Result<(), JsError>{ if self.dedup.insert(elem.clone()) { self.witnesses.push(elem.clone()); + Ok(()) + } else { + Err(JsError::from_str("Vkeywitnesses::add: duplicated element")) } } diff --git a/rust/src/serialization/certificates/certificates_collection.rs b/rust/src/serialization/certificates/certificates_collection.rs index 1d210f94..e89ce1f7 100644 --- a/rust/src/serialization/certificates/certificates_collection.rs +++ b/rust/src/serialization/certificates/certificates_collection.rs @@ -6,10 +6,14 @@ impl Serialize for Certificates { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { + if self.0.is_empty() { + return Ok(serializer); + } //TODO: uncomment this line when we conway ero will come //serializer.write_tag(258)?; + let ordered_dedup = self.0.iter().collect::>(); serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { + for element in ordered_dedup { element.serialize(serializer)?; } Ok(serializer) diff --git a/rust/src/serialization/governance/proposals/voting_proposals.rs b/rust/src/serialization/governance/proposals/voting_proposals.rs index b3fd5fbf..189ea116 100644 --- a/rust/src/serialization/governance/proposals/voting_proposals.rs +++ b/rust/src/serialization/governance/proposals/voting_proposals.rs @@ -6,10 +6,14 @@ impl cbor_event::se::Serialize for VotingProposals { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { + if self.0.is_empty() { + return Ok(serializer); + } //TODO: uncomment this line when we conway ero will come //serializer.write_tag(258)?; + let ordered_dedup = self.0.iter().collect::>(); serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { + for element in ordered_dedup { element.serialize(serializer)?; } Ok(serializer) diff --git a/rust/src/serialization/governance/voting_procedures.rs b/rust/src/serialization/governance/voting_procedures.rs index a1861ee7..df3376eb 100644 --- a/rust/src/serialization/governance/voting_procedures.rs +++ b/rust/src/serialization/governance/voting_procedures.rs @@ -7,9 +7,16 @@ impl cbor_event::se::Serialize for VotingProcedures { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { + if self.is_none_or_empty() { + return Ok(serializer) + } + serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?; for (voter, votes) in &self.0 { + if votes.is_empty() { + continue; + } voter.serialize(serializer)?; serializer.write_map(cbor_event::Len::Len(votes.len() as u64))?; for (governance_action_id, voting_procedure) in votes { diff --git a/rust/src/serialization/plutus/plutus_scripts.rs b/rust/src/serialization/plutus/plutus_scripts.rs index 571b1a9a..1f86957f 100644 --- a/rust/src/serialization/plutus/plutus_scripts.rs +++ b/rust/src/serialization/plutus/plutus_scripts.rs @@ -28,15 +28,15 @@ impl PlutusScripts { Ok(serializer) } - pub(crate) fn serialize_as_set<'se, W: Write>( + pub(crate) fn serialize_as_set_by_version<'se, W: Write>( &self, - need_debuplication: bool, + need_deduplication: bool, version: &Language, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { //TODO: uncomment this line when we conway ero will come //serializer.write_tag(258)?; - let view = match need_debuplication { + let view = match need_deduplication { true => self.deduplicated_view(Some(version)), false => self.view(version), }; diff --git a/rust/src/serialization/witnesses/transaction_witnesses_set.rs b/rust/src/serialization/witnesses/transaction_witnesses_set.rs index 982e26ea..8babdd9c 100644 --- a/rust/src/serialization/witnesses/transaction_witnesses_set.rs +++ b/rust/src/serialization/witnesses/transaction_witnesses_set.rs @@ -50,18 +50,20 @@ impl cbor_event::se::Serialize for TransactionWitnessSet { field.serialize(serializer)?; } } + + //no need deduplication here because transaction witness set already has deduplicated plutus scripts if let Some(plutus_scripts) = &self.plutus_scripts { if has_plutus_v1 { serializer.write_unsigned_integer(3)?; - plutus_scripts.serialize_by_version(&Language::new_plutus_v1(), serializer)?; + plutus_scripts.serialize_as_set_by_version(false, &Language::new_plutus_v1(), serializer)?; } if has_plutus_v2 { serializer.write_unsigned_integer(6)?; - plutus_scripts.serialize_by_version(&Language::new_plutus_v2(), serializer)?; + plutus_scripts.serialize_as_set_by_version(false, &Language::new_plutus_v2(), serializer)?; } if has_plutus_v3 { serializer.write_unsigned_integer(7)?; - plutus_scripts.serialize_by_version(&Language::new_plutus_v3(), serializer)?; + plutus_scripts.serialize_as_set_by_version(false, &Language::new_plutus_v3(), serializer)?; } } if let Some(field) = &self.plutus_data { diff --git a/rust/src/traits.rs b/rust/src/traits.rs index 8a1b2815..e2ced435 100644 --- a/rust/src/traits.rs +++ b/rust/src/traits.rs @@ -2,6 +2,10 @@ pub trait NoneOrEmpty { fn is_none_or_empty(&self) -> bool; } +pub trait EmptyToNone: Sized { + fn empty_to_none(self) -> Option; +} + impl NoneOrEmpty for &T { fn is_none_or_empty(&self) -> bool { (*self).is_none_or_empty() @@ -10,6 +14,19 @@ impl NoneOrEmpty for &T { impl NoneOrEmpty for Option { fn is_none_or_empty(&self) -> bool { - self.is_none() || self.as_ref().unwrap().is_none_or_empty() + match &self { + Some(x) => x.is_none_or_empty(), + None => true, + } } } + +impl EmptyToNone for T { + fn empty_to_none(self) -> Option { + if self.is_none_or_empty() { + None + } else { + Some(self) + } + } +} \ No newline at end of file From f19a893c68303c247b0587efc9cca845b385ea7e Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 22 Jun 2024 04:10:16 +0700 Subject: [PATCH 291/349] add error on duplicated keyhash in Ed25519KeyHash --- rust/src/protocol_types/ed25519_key_hashes.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rust/src/protocol_types/ed25519_key_hashes.rs b/rust/src/protocol_types/ed25519_key_hashes.rs index 472914fc..1c444cfb 100644 --- a/rust/src/protocol_types/ed25519_key_hashes.rs +++ b/rust/src/protocol_types/ed25519_key_hashes.rs @@ -36,9 +36,12 @@ impl Ed25519KeyHashes { self.keyhashes[index].clone() } - pub fn add(&mut self, elem: &Ed25519KeyHash) { + pub fn add(&mut self, elem: &Ed25519KeyHash) -> Result<(), JsError> { if self.dedup.insert(elem.clone()) { self.keyhashes.push(elem.clone()); + Ok(()) + } else { + Err(JsError::from_str("Ed25519KeyHashes::add: duplicated element")) } } From 7848f43256a2be8f2e5e3c2228d746dc8b3ec847 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 22 Jun 2024 04:12:17 +0700 Subject: [PATCH 292/349] add error on duplicated credential in Credentials --- rust/src/protocol_types/credentials.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rust/src/protocol_types/credentials.rs b/rust/src/protocol_types/credentials.rs index 00e0640b..220131fc 100644 --- a/rust/src/protocol_types/credentials.rs +++ b/rust/src/protocol_types/credentials.rs @@ -34,9 +34,12 @@ impl Credentials { self.credentials[index].clone() } - pub fn add(&mut self, elem: &Credential) { + pub fn add(&mut self, elem: &Credential) -> Result<(), JsError> { if self.dedup.insert(elem.clone()) { self.credentials.push(elem.clone()); + Ok(()) + } else { + Err(JsError::from_str("Credentials::add: duplicated element")) } } From 9715325d0e94d6120f10691652620d1e3d3696b2 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 22 Jun 2024 14:34:11 +0700 Subject: [PATCH 293/349] return bool on "add" for struct with deduplication --- rust/src/fakes.rs | 11 +++- rust/src/protocol_types/credentials.rs | 8 ++- rust/src/protocol_types/ed25519_key_hashes.rs | 8 ++- .../witnesses/bootstrap_witnesses.rs | 8 ++- .../protocol_types/witnesses/vkeywitnesses.rs | 8 ++- rust/src/tests/general.rs | 58 ++++++++++++++++++- 6 files changed, 87 insertions(+), 14 deletions(-) diff --git a/rust/src/fakes.rs b/rust/src/fakes.rs index ff6fdd0d..0712813e 100644 --- a/rust/src/fakes.rs +++ b/rust/src/fakes.rs @@ -1,5 +1,5 @@ #![allow(dead_code)] -use crate::{AnchorDataHash, AuxiliaryDataHash, BigNum, GenesisDelegateHash, GenesisHash, PlutusScript, PoolMetadataHash, PublicKey, ScriptDataHash, ScriptHash, Vkeywitness, VRFKeyHash}; +use crate::{AnchorDataHash, AuxiliaryDataHash, BigNum, BootstrapWitness, GenesisDelegateHash, GenesisHash, PlutusScript, PoolMetadataHash, PublicKey, ScriptDataHash, ScriptHash, Vkeywitness, VRFKeyHash}; use crate::{ Address, BaseAddress, Bip32PrivateKey, Credential, DataHash, Ed25519KeyHash, Ed25519Signature, NetworkInfo, PolicyID, TransactionHash, TransactionIndex, TransactionInput, @@ -127,6 +127,15 @@ pub(crate) fn fake_vkey_witness(x: u8) -> Vkeywitness { Vkeywitness::new(&fake_vkey_numbered(x), &fake_signature(x)) } +pub(crate) fn fake_boostrap_witness(x: u8) -> BootstrapWitness { + BootstrapWitness::new( + &fake_vkey_numbered(x), + &fake_signature(x), + vec![x; 32], + vec![x; 32], + ) +} + pub(crate) fn fake_plutus_script_and_hash(x: u8) -> (PlutusScript, ScriptHash) { let s = PlutusScript::new(fake_bytes_32(x)); (s.clone(), s.hash()) diff --git a/rust/src/protocol_types/credentials.rs b/rust/src/protocol_types/credentials.rs index 220131fc..933bc81b 100644 --- a/rust/src/protocol_types/credentials.rs +++ b/rust/src/protocol_types/credentials.rs @@ -34,12 +34,14 @@ impl Credentials { self.credentials[index].clone() } - pub fn add(&mut self, elem: &Credential) -> Result<(), JsError> { + /// Add a new `Credential` to the set. + /// Returns `true` if the element was not already present in the set. + pub fn add(&mut self, elem: &Credential) -> bool { if self.dedup.insert(elem.clone()) { self.credentials.push(elem.clone()); - Ok(()) + true } else { - Err(JsError::from_str("Credentials::add: duplicated element")) + false } } diff --git a/rust/src/protocol_types/ed25519_key_hashes.rs b/rust/src/protocol_types/ed25519_key_hashes.rs index 1c444cfb..c26083e3 100644 --- a/rust/src/protocol_types/ed25519_key_hashes.rs +++ b/rust/src/protocol_types/ed25519_key_hashes.rs @@ -36,12 +36,14 @@ impl Ed25519KeyHashes { self.keyhashes[index].clone() } - pub fn add(&mut self, elem: &Ed25519KeyHash) -> Result<(), JsError> { + /// Add a new `Ed25519KeyHash` to the set. + /// Returns `true` if the element was not already present in the set. + pub fn add(&mut self, elem: &Ed25519KeyHash) -> bool { if self.dedup.insert(elem.clone()) { self.keyhashes.push(elem.clone()); - Ok(()) + true } else { - Err(JsError::from_str("Ed25519KeyHashes::add: duplicated element")) + false } } diff --git a/rust/src/protocol_types/witnesses/bootstrap_witnesses.rs b/rust/src/protocol_types/witnesses/bootstrap_witnesses.rs index 13133cb9..768b40b7 100644 --- a/rust/src/protocol_types/witnesses/bootstrap_witnesses.rs +++ b/rust/src/protocol_types/witnesses/bootstrap_witnesses.rs @@ -27,12 +27,14 @@ impl BootstrapWitnesses { self.witnesses[index].clone() } - pub fn add(&mut self, elem: &BootstrapWitness) -> Result<(), JsError> { + /// Add a new `BootstrapWitness` to the set. + /// Returns `true` if the element was not already present in the set. + pub fn add(&mut self, elem: &BootstrapWitness) -> bool { if self.dedup.insert(elem.clone()) { self.witnesses.push(elem.clone()); - Ok(()) + true } else { - Err(JsError::from_str("BootstrapWitnesses::add: duplicated element")) + false } } diff --git a/rust/src/protocol_types/witnesses/vkeywitnesses.rs b/rust/src/protocol_types/witnesses/vkeywitnesses.rs index abe53fe5..f0396fb7 100644 --- a/rust/src/protocol_types/witnesses/vkeywitnesses.rs +++ b/rust/src/protocol_types/witnesses/vkeywitnesses.rs @@ -27,12 +27,14 @@ impl Vkeywitnesses { self.witnesses[index].clone() } - pub fn add(&mut self, elem: &Vkeywitness) -> Result<(), JsError>{ + /// Add a new `Vkeywitness` to the set. + /// Returns `true` if the element was not already present in the set. + pub fn add(&mut self, elem: &Vkeywitness) -> bool { if self.dedup.insert(elem.clone()) { self.witnesses.push(elem.clone()); - Ok(()) + true } else { - Err(JsError::from_str("Vkeywitnesses::add: duplicated element")) + false } } diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index 568b669e..2e330f0a 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -1,5 +1,5 @@ use crate::*; -use crate::fakes::fake_vkey_witness; +use crate::fakes::{fake_boostrap_witness, fake_vkey_witness}; use crate::tests::helpers::harden; use crate::tests::mock_objects::create_plutus_script; @@ -445,3 +445,59 @@ fn min_ref_script_fee_test_fail(){ let min_fee = min_ref_script_fee(total_size, &cost); assert!(min_fee.is_err()); } + +#[test] +fn ed25519_key_hashes_dedup() { + let mut key_hashes = Ed25519KeyHashes::new(); + let key_hash1 = keyhash(1); + let key_hash2 = keyhash(2); + + assert!(key_hashes.add(&key_hash1)); + assert!(key_hashes.add(&key_hash2)); + assert_eq!(key_hashes.len(), 2); + + assert!(!key_hashes.add(&key_hash1)); + assert_eq!(key_hashes.len(), 2); +} + +#[test] +fn bootstrap_witnesses_dedup() { + let mut bootstrap_witnesses = BootstrapWitnesses::new(); + let bootstrap_witness1 = fake_boostrap_witness(1); + let bootstrap_witness2 = fake_boostrap_witness(2); + + assert!(bootstrap_witnesses.add(&bootstrap_witness1)); + assert!(bootstrap_witnesses.add(&bootstrap_witness2)); + assert_eq!(bootstrap_witnesses.len(), 2); + + assert!(!bootstrap_witnesses.add(&bootstrap_witness1)); + assert_eq!(bootstrap_witnesses.len(), 2); +} + +#[test] +fn credential_dedup() { + let mut credentials = Credentials::new(); + let credential1 = Credential::from_keyhash(&keyhash(1)); + let credential2 = Credential::from_keyhash(&keyhash(2)); + + assert!(credentials.add(&credential1)); + assert!(credentials.add(&credential2)); + assert_eq!(credentials.len(), 2); + + assert!(!credentials.add(&credential1)); + assert_eq!(credentials.len(), 2); +} + +#[test] +fn vkeywitneses_dedup() { + let mut vkeywitnesses = Vkeywitnesses::new(); + let vkeywitness1 = fake_vkey_witness(1); + let vkeywitness2 = fake_vkey_witness(2); + + assert!(vkeywitnesses.add(&vkeywitness1)); + assert!(vkeywitnesses.add(&vkeywitness2)); + assert_eq!(vkeywitnesses.len(), 2); + + assert!(!vkeywitnesses.add(&vkeywitness1)); + assert_eq!(vkeywitnesses.len(), 2); +} \ No newline at end of file From ec86a0f2335d9d2d70486d5062b67df9ada9edb7 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 22 Jun 2024 14:57:08 +0700 Subject: [PATCH 294/349] move utils tests --- rust/src/tests/mod.rs | 3 +- rust/src/tests/utils.rs | 753 +++++++++++++++++++++++++++++++++++++++ rust/src/utils.rs | 763 +--------------------------------------- 3 files changed, 757 insertions(+), 762 deletions(-) create mode 100644 rust/src/tests/utils.rs diff --git a/rust/src/tests/mod.rs b/rust/src/tests/mod.rs index 27eb5ac9..2c350a8e 100644 --- a/rust/src/tests/mod.rs +++ b/rust/src/tests/mod.rs @@ -7,4 +7,5 @@ mod protocol_types; mod serialization; mod plutus; mod metadata; -mod crypto; \ No newline at end of file +mod crypto; +mod utils; \ No newline at end of file diff --git a/rust/src/tests/utils.rs b/rust/src/tests/utils.rs new file mode 100644 index 00000000..c8dabac1 --- /dev/null +++ b/rust/src/tests/utils.rs @@ -0,0 +1,753 @@ +use crate::*; + +#[test] +fn subtract_values() { + let policy1 = PolicyID::from([0; ScriptHash::BYTE_COUNT]); + let policy2 = PolicyID::from([1; ScriptHash::BYTE_COUNT]); + + let asset1 = AssetName(vec![1]); + let asset2 = AssetName(vec![2]); + let asset3 = AssetName(vec![3]); + let asset4 = AssetName(vec![4]); + + let mut token_bundle1 = MultiAsset::new(); + { + let mut asset_list1 = Assets::new(); + asset_list1.insert(&asset1, &BigNum(1)); + asset_list1.insert(&asset2, &BigNum(1)); + asset_list1.insert(&asset3, &BigNum(1)); + asset_list1.insert(&asset4, &BigNum(2)); + token_bundle1.insert(&policy1, &asset_list1); + + let mut asset_list2 = Assets::new(); + asset_list2.insert(&asset1, &BigNum(1)); + token_bundle1.insert(&policy2, &asset_list2); + } + let assets1 = Value { + coin: BigNum(1555554), + multiasset: Some(token_bundle1), + }; + + let mut token_bundle2 = MultiAsset::new(); + { + let mut asset_list2 = Assets::new(); + // more than asset1 bundle + asset_list2.insert(&asset1, &BigNum(2)); + // exactly equal to asset1 bundle + asset_list2.insert(&asset2, &BigNum(1)); + // skip asset 3 + // less than in asset1 bundle + asset_list2.insert(&asset4, &BigNum(1)); + token_bundle2.insert(&policy1, &asset_list2); + + // this policy should be removed entirely + let mut asset_list2 = Assets::new(); + asset_list2.insert(&asset1, &BigNum(1)); + token_bundle2.insert(&policy2, &asset_list2); + } + + let assets2 = Value { + coin: BigNum(2555554), + multiasset: Some(token_bundle2), + }; + + let result = assets1.clamped_sub(&assets2); + assert_eq!(result.coin().to_str(), "0"); + assert_eq!( + result.multiasset().unwrap().len(), + 1 // policy 2 was deleted successfully + ); + let policy1_content = result.multiasset().unwrap().get(&policy1).unwrap(); + assert_eq!(policy1_content.len(), 2); + assert_eq!(policy1_content.get(&asset3).unwrap().to_str(), "1"); + assert_eq!(policy1_content.get(&asset4).unwrap().to_str(), "1"); +} + +#[test] +fn compare_values() { + let policy1 = PolicyID::from([0; ScriptHash::BYTE_COUNT]); + + let asset1 = AssetName(vec![1]); + let asset2 = AssetName(vec![2]); + + // testing cases with no assets + { + let a = Value::new(&BigNum(1)); + let b = Value::new(&BigNum(1)); + assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Equal); + } + { + let a = Value::new(&BigNum(2)); + let b = Value::new(&BigNum(1)); + assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Greater); + } + { + let a = Value::new(&BigNum(1)); + let b = Value::new(&BigNum(2)); + assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Less); + } + // testing case where one side has assets + { + let mut token_bundle1 = MultiAsset::new(); + let mut asset_list1 = Assets::new(); + asset_list1.insert(&asset1, &BigNum(1)); + token_bundle1.insert(&policy1, &asset_list1); + let a = Value { + coin: BigNum(1), + multiasset: Some(token_bundle1), + }; + let b = Value::new(&BigNum(1)); + assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Greater); + } + { + let mut token_bundle1 = MultiAsset::new(); + let mut asset_list1 = Assets::new(); + asset_list1.insert(&asset1, &BigNum(1)); + token_bundle1.insert(&policy1, &asset_list1); + let a = Value::new(&BigNum(1)); + let b = Value { + coin: BigNum(1), + multiasset: Some(token_bundle1), + }; + assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Less); + } + // testing case where both sides has assets + { + let mut token_bundle1 = MultiAsset::new(); + let mut asset_list1 = Assets::new(); + asset_list1.insert(&asset1, &BigNum(1)); + token_bundle1.insert(&policy1, &asset_list1); + let a = Value { + coin: BigNum(1), + multiasset: Some(token_bundle1), + }; + + let mut token_bundle2 = MultiAsset::new(); + let mut asset_list2 = Assets::new(); + asset_list2.insert(&asset1, &BigNum(1)); + token_bundle2.insert(&policy1, &asset_list2); + let b = Value { + coin: BigNum(1), + multiasset: Some(token_bundle2), + }; + assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Equal); + } + { + let mut token_bundle1 = MultiAsset::new(); + let mut asset_list1 = Assets::new(); + asset_list1.insert(&asset1, &BigNum(1)); + token_bundle1.insert(&policy1, &asset_list1); + let a = Value { + coin: BigNum(2), + multiasset: Some(token_bundle1), + }; + + let mut token_bundle2 = MultiAsset::new(); + let mut asset_list2 = Assets::new(); + asset_list2.insert(&asset1, &BigNum(1)); + token_bundle2.insert(&policy1, &asset_list2); + let b = Value { + coin: BigNum(1), + multiasset: Some(token_bundle2), + }; + assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Greater); + } + { + let mut token_bundle1 = MultiAsset::new(); + let mut asset_list1 = Assets::new(); + asset_list1.insert(&asset1, &BigNum(1)); + token_bundle1.insert(&policy1, &asset_list1); + let a = Value { + coin: BigNum(1), + multiasset: Some(token_bundle1), + }; + + let mut token_bundle2 = MultiAsset::new(); + let mut asset_list2 = Assets::new(); + asset_list2.insert(&asset1, &BigNum(1)); + token_bundle2.insert(&policy1, &asset_list2); + let b = Value { + coin: BigNum(2), + multiasset: Some(token_bundle2), + }; + assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Less); + } + { + let mut token_bundle1 = MultiAsset::new(); + let mut asset_list1 = Assets::new(); + asset_list1.insert(&asset1, &BigNum(2)); + token_bundle1.insert(&policy1, &asset_list1); + let a = Value { + coin: BigNum(1), + multiasset: Some(token_bundle1), + }; + + let mut token_bundle2 = MultiAsset::new(); + let mut asset_list2 = Assets::new(); + asset_list2.insert(&asset1, &BigNum(1)); + token_bundle2.insert(&policy1, &asset_list2); + let b = Value { + coin: BigNum(1), + multiasset: Some(token_bundle2), + }; + assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Greater); + } + { + let mut token_bundle1 = MultiAsset::new(); + let mut asset_list1 = Assets::new(); + asset_list1.insert(&asset1, &BigNum(2)); + token_bundle1.insert(&policy1, &asset_list1); + let a = Value { + coin: BigNum(2), + multiasset: Some(token_bundle1), + }; + + let mut token_bundle2 = MultiAsset::new(); + let mut asset_list2 = Assets::new(); + asset_list2.insert(&asset1, &BigNum(1)); + token_bundle2.insert(&policy1, &asset_list2); + let b = Value { + coin: BigNum(1), + multiasset: Some(token_bundle2), + }; + assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Greater); + } + { + let mut token_bundle1 = MultiAsset::new(); + let mut asset_list1 = Assets::new(); + asset_list1.insert(&asset1, &BigNum(2)); + token_bundle1.insert(&policy1, &asset_list1); + let a = Value { + coin: BigNum(1), + multiasset: Some(token_bundle1), + }; + + let mut token_bundle2 = MultiAsset::new(); + let mut asset_list2 = Assets::new(); + asset_list2.insert(&asset1, &BigNum(1)); + token_bundle2.insert(&policy1, &asset_list2); + let b = Value { + coin: BigNum(2), + multiasset: Some(token_bundle2), + }; + assert_eq!(a.partial_cmp(&b), None); + } + { + let mut token_bundle1 = MultiAsset::new(); + let mut asset_list1 = Assets::new(); + asset_list1.insert(&asset1, &BigNum(1)); + token_bundle1.insert(&policy1, &asset_list1); + let a = Value { + coin: BigNum(1), + multiasset: Some(token_bundle1), + }; + + let mut token_bundle2 = MultiAsset::new(); + let mut asset_list2 = Assets::new(); + asset_list2.insert(&asset1, &BigNum(2)); + token_bundle2.insert(&policy1, &asset_list2); + let b = Value { + coin: BigNum(1), + multiasset: Some(token_bundle2), + }; + assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Less); + } + { + let mut token_bundle1 = MultiAsset::new(); + let mut asset_list1 = Assets::new(); + asset_list1.insert(&asset1, &BigNum(1)); + token_bundle1.insert(&policy1, &asset_list1); + let a = Value { + coin: BigNum(1), + multiasset: Some(token_bundle1), + }; + + let mut token_bundle2 = MultiAsset::new(); + let mut asset_list2 = Assets::new(); + asset_list2.insert(&asset1, &BigNum(2)); + token_bundle2.insert(&policy1, &asset_list2); + let b = Value { + coin: BigNum(2), + multiasset: Some(token_bundle2), + }; + assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Less); + } + { + let mut token_bundle1 = MultiAsset::new(); + let mut asset_list1 = Assets::new(); + asset_list1.insert(&asset1, &BigNum(1)); + token_bundle1.insert(&policy1, &asset_list1); + let a = Value { + coin: BigNum(2), + multiasset: Some(token_bundle1), + }; + + let mut token_bundle2 = MultiAsset::new(); + let mut asset_list2 = Assets::new(); + asset_list2.insert(&asset1, &BigNum(2)); + token_bundle2.insert(&policy1, &asset_list2); + let b = Value { + coin: BigNum(1), + multiasset: Some(token_bundle2), + }; + assert_eq!(a.partial_cmp(&b), None); + } + { + let mut token_bundle1 = MultiAsset::new(); + let mut asset_list1 = Assets::new(); + asset_list1.insert(&asset1, &BigNum(1)); + token_bundle1.insert(&policy1, &asset_list1); + let a = Value { + coin: BigNum(1), + multiasset: Some(token_bundle1), + }; + + let mut token_bundle2 = MultiAsset::new(); + let mut asset_list2 = Assets::new(); + asset_list2.insert(&asset2, &BigNum(1)); + token_bundle2.insert(&policy1, &asset_list2); + let b = Value { + coin: BigNum(1), + multiasset: Some(token_bundle2), + }; + assert_eq!(a.partial_cmp(&b), None); + } +} + +#[test] +fn bigint_serialization() { + let zero = BigInt::from_str("0").unwrap(); + let zero_rt = BigInt::from_bytes(zero.to_bytes()).unwrap(); + assert_eq!(zero.to_str(), zero_rt.to_str()); + assert_eq!(zero.to_bytes(), vec![0x00]); + + let pos_small = BigInt::from_str("100").unwrap(); + let pos_small_rt = BigInt::from_bytes(pos_small.to_bytes()).unwrap(); + assert_eq!(pos_small.to_str(), pos_small_rt.to_str()); + + let pos_big = BigInt::from_str("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890").unwrap(); + let pos_big_rt = BigInt::from_bytes(pos_big.to_bytes()).unwrap(); + assert_eq!(pos_big.to_str(), pos_big_rt.to_str()); + + let neg_small = BigInt::from_str("-100").unwrap(); + let neg_small_rt = BigInt::from_bytes(neg_small.to_bytes()).unwrap(); + assert_eq!(neg_small.to_str(), neg_small_rt.to_str()); + + let neg_big = BigInt::from_str("-123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890").unwrap(); + let neg_big_rt = BigInt::from_bytes(neg_big.to_bytes()).unwrap(); + assert_eq!(neg_big.to_str(), neg_big_rt.to_str()); + + // taken from CBOR RFC examples + // negative big int + assert_eq!( + hex::decode("c349010000000000000000").unwrap(), + BigInt::from_str("-18446744073709551617") + .unwrap() + .to_bytes() + ); + // positive big int + assert_eq!( + hex::decode("c249010000000000000000").unwrap(), + BigInt::from_str("18446744073709551616").unwrap().to_bytes() + ); + // uint + assert_eq!( + hex::decode("1b000000e8d4a51000").unwrap(), + BigInt::from_str("1000000000000").unwrap().to_bytes() + ); + // nint (lowest possible - used to be unsupported but works now) + assert_eq!( + hex::decode("3bffffffffffffffff").unwrap(), + BigInt::from_str("-18446744073709551616") + .unwrap() + .to_bytes() + ); + // this one fits in an i64 though + assert_eq!( + hex::decode("3903e7").unwrap(), + BigInt::from_str("-1000").unwrap().to_bytes() + ); + + let x = BigInt::from_str("-18446744073709551617").unwrap(); + let x_rt = BigInt::from_bytes(x.to_bytes()).unwrap(); + assert_eq!(x.to_str(), x_rt.to_str()); +} + +#[test] +fn bounded_bytes_read_chunked() { + use std::io::Cursor; + let chunks = vec![ + vec![ + 0x52, 0x73, 0x6F, 0x6D, 0x65, 0x20, 0x72, 0x61, 0x6E, 0x64, 0x6F, 0x6D, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6E, 0x67, + ], + vec![0x44, 0x01, 0x02, 0x03, 0x04], + ]; + let mut expected = Vec::new(); + for chunk in chunks.iter() { + expected.extend_from_slice(&chunk[1..]); + } + let mut vec = vec![0x5f]; + for mut chunk in chunks { + vec.append(&mut chunk); + } + vec.push(0xff); + let mut raw = Deserializer::from(Cursor::new(vec.clone())); + let found = read_bounded_bytes(&mut raw).unwrap(); + assert_eq!(found, expected); +} + +#[test] +fn bounded_bytes_write_chunked() { + let mut chunk_64 = vec![0x58, crate::utils::BOUNDED_BYTES_CHUNK_SIZE as u8]; + chunk_64.extend(std::iter::repeat(37).take(crate::utils::BOUNDED_BYTES_CHUNK_SIZE)); + let chunks = vec![chunk_64, vec![0x44, 0x01, 0x02, 0x03, 0x04]]; + let mut input = Vec::new(); + input.extend_from_slice(&chunks[0][2..]); + input.extend_from_slice(&chunks[1][1..]); + let mut serializer = cbor_event::se::Serializer::new_vec(); + write_bounded_bytes(&mut serializer, &input).unwrap(); + let written = serializer.finalize(); + let mut expected = vec![0x5f]; + for mut chunk in chunks { + expected.append(&mut chunk); + } + expected.push(0xff); + assert_eq!(expected, written); +} + +#[test] +fn correct_script_data_hash() { + let mut datums = PlutusList::new(); + datums.add(&PlutusData::new_integer(&BigInt::from_str("1000").unwrap())); + let mut redeemers = Redeemers::new(); + redeemers.add(&Redeemer::new( + &RedeemerTag::new_spend(), + &BigNum::from_str("1").unwrap(), + &PlutusData::new_integer(&BigInt::from_str("2000").unwrap()), + &ExUnits::new( + &BigNum::from_str("0").unwrap(), + &BigNum::from_str("0").unwrap(), + ), + )); + let plutus_cost_model = CostModel::from_bytes(vec![ + 159, 26, 0, 3, 2, 89, 0, 1, 1, 26, 0, 6, 11, 199, 25, 2, 109, 0, 1, 26, 0, 2, 73, 240, 25, + 3, 232, 0, 1, 26, 0, 2, 73, 240, 24, 32, 26, 0, 37, 206, 168, 25, 113, 247, 4, 25, 116, 77, + 24, 100, 25, 116, 77, 24, 100, 25, 116, 77, 24, 100, 25, 116, 77, 24, 100, 25, 116, 77, 24, + 100, 25, 116, 77, 24, 100, 24, 100, 24, 100, 25, 116, 77, 24, 100, 26, 0, 2, 73, 240, 24, + 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 25, 3, 232, 0, + 1, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 25, 3, 232, 0, 8, 26, 0, 2, 66, 32, 26, 0, + 6, 126, 35, 24, 118, 0, 1, 1, 26, 0, 2, 73, 240, 25, 3, 232, 0, 8, 26, 0, 2, 73, 240, 26, + 0, 1, 183, 152, 24, 247, 1, 26, 0, 2, 73, 240, 25, 39, 16, 1, 26, 0, 2, 21, 94, 25, 5, 46, + 1, 25, 3, 232, 26, 0, 2, 73, 240, 25, 3, 232, 1, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, + 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 1, 1, 26, 0, 2, 73, 240, 1, 26, 0, 2, 73, 240, 4, + 26, 0, 1, 148, 175, 24, 248, 1, 26, 0, 1, 148, 175, 24, 248, 1, 26, 0, 2, 55, 124, 25, 5, + 86, 1, 26, 0, 2, 189, 234, 25, 1, 241, 1, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, + 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, + 2, 73, 240, 24, 32, 26, 0, 2, 66, 32, 26, 0, 6, 126, 35, 24, 118, 0, 1, 1, 25, 240, 76, 25, + 43, 210, 0, 1, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 66, 32, 26, 0, 6, 126, 35, 24, 118, 0, + 1, 1, 26, 0, 2, 66, 32, 26, 0, 6, 126, 35, 24, 118, 0, 1, 1, 26, 0, 37, 206, 168, 25, 113, + 247, 4, 0, 26, 0, 1, 65, 187, 4, 26, 0, 2, 73, 240, 25, 19, 136, 0, 1, 26, 0, 2, 73, 240, + 24, 32, 26, 0, 3, 2, 89, 0, 1, 1, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, + 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, + 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 51, 13, 167, 1, 1, 255, + ]) + .unwrap(); + let mut cost_models = Costmdls::new(); + cost_models.insert(&Language::new_plutus_v1(), &plutus_cost_model); + let script_data_hash = hash_script_data(&redeemers, &cost_models, Some(datums)); + + assert_eq!( + hex::encode(script_data_hash.to_bytes()), + "4415e6667e6d6bbd992af5092d48e3c2ba9825200d0234d2470068f7f0f178b3" + ); +} + +#[test] +fn native_scripts_from_wallet_json() { + let cosigner0_hex = "1423856bc91c49e928f6f30f4e8d665d53eb4ab6028bd0ac971809d514c92db11423856bc91c49e928f6f30f4e8d665d53eb4ab6028bd0ac971809d514c92db1"; + let cosigner1_hex = "a48d97f57ce49433f347d44ee07e54a100229b4f8e125d25f7bca9ad66d9707a25cd1331f46f7d6e279451637ca20802a25c441ba9436abf644fe5410d1080e3"; + let self_key_hex = "6ce83a12e9d4c783f54c0bb511303b37160a6e4f3f96b8e878a7c1f7751e18c4ccde3fb916d330d07f7bd51fb6bd99aa831d925008d3f7795033f48abd6df7f6"; + let native_script = encode_json_str_to_native_script( + &format!( + r#" + {{ + "cosigners": {{ + "cosigner#0": "{}", + "cosigner#1": "{}", + "cosigner#2": "self" + }}, + "template": {{ + "some": {{ + "at_least": 2, + "from": [ + {{ + "all": [ + "cosigner#0", + {{ "active_from": 120 }} + ] + }}, + {{ + "any": [ + "cosigner#1", + {{ "active_until": 1000 }} + ] + }}, + "cosigner#2" + ] + }} + }} + }}"#, + cosigner0_hex, cosigner1_hex + ), + self_key_hex, + ScriptSchema::Wallet, + ); + + let n_of_k = native_script.unwrap().as_script_n_of_k().unwrap(); + let from = n_of_k.native_scripts(); + assert_eq!(n_of_k.n(), 2); + assert_eq!(from.len(), 3); + let all = from.get(0).as_script_all().unwrap().native_scripts(); + assert_eq!(all.len(), 2); + let all_0 = all.get(0).as_script_pubkey().unwrap(); + assert_eq!( + all_0.addr_keyhash(), + Bip32PublicKey::from_bytes(&hex::decode(cosigner0_hex).unwrap()) + .unwrap() + .to_raw_key() + .hash() + ); + let all_1 = all.get(1).as_timelock_start().unwrap(); + assert_eq!(all_1.slot().unwrap(), 120); + let any = from.get(1).as_script_any().unwrap().native_scripts(); + assert_eq!(all.len(), 2); + let any_0 = any.get(0).as_script_pubkey().unwrap(); + assert_eq!( + any_0.addr_keyhash(), + Bip32PublicKey::from_bytes(&hex::decode(cosigner1_hex).unwrap()) + .unwrap() + .to_raw_key() + .hash() + ); + let any_1 = any.get(1).as_timelock_expiry().unwrap(); + assert_eq!(any_1.slot().unwrap(), 1000); + let self_key = from.get(2).as_script_pubkey().unwrap(); + assert_eq!( + self_key.addr_keyhash(), + Bip32PublicKey::from_bytes(&hex::decode(self_key_hex).unwrap()) + .unwrap() + .to_raw_key() + .hash() + ); +} + +#[test] +fn int_to_str() { + assert_eq!( + Int::new(&BigNum(u64::max_value())).to_str(), + u64::max_value().to_string() + ); + assert_eq!( + Int::new(&BigNum(u64::min_value())).to_str(), + u64::min_value().to_string() + ); + assert_eq!( + Int::new_negative(&BigNum(u64::max_value())).to_str(), + (-(u64::max_value() as i128)).to_string() + ); + assert_eq!( + Int::new_negative(&BigNum(u64::min_value())).to_str(), + (-(u64::min_value() as i128)).to_string() + ); + assert_eq!(Int::new_i32(142).to_str(), "142"); + assert_eq!(Int::new_i32(-142).to_str(), "-142"); +} + +#[test] +fn int_as_i32_or_nothing() { + let over_pos_i32 = (i32::max_value() as i64) + 1; + assert!(Int::new(&BigNum(over_pos_i32 as u64)) + .as_i32_or_nothing() + .is_none()); + + let valid_pos_i32 = i32::max_value() as i64; + assert_eq!( + Int::new(&BigNum(valid_pos_i32 as u64)) + .as_i32_or_nothing() + .unwrap(), + i32::max_value() + ); + + let over_neg_i32 = (i32::min_value() as i64) - 1; + assert!(Int::new_negative(&BigNum((-over_neg_i32) as u64)) + .as_i32_or_nothing() + .is_none()); + + let valid_neg_i32 = i32::min_value() as i64; + assert_eq!( + Int::new_negative(&BigNum((-valid_neg_i32) as u64)) + .as_i32_or_nothing() + .unwrap(), + i32::min_value() + ); + + assert!(Int::new(&BigNum(u64::max_value())) + .as_i32_or_nothing() + .is_none()); + assert_eq!( + Int::new(&BigNum(i32::max_value() as u64)) + .as_i32_or_nothing() + .unwrap(), + i32::max_value() + ); + assert_eq!( + Int::new_negative(&BigNum(i32::max_value() as u64)) + .as_i32_or_nothing() + .unwrap(), + -i32::max_value() + ); + + assert_eq!(Int::new_i32(42).as_i32_or_nothing().unwrap(), 42); + assert_eq!(Int::new_i32(-42).as_i32_or_nothing().unwrap(), -42); +} + +#[test] +fn int_as_i32_or_fail() { + let over_pos_i32 = (i32::max_value() as i64) + 1; + assert!(Int::new(&BigNum(over_pos_i32 as u64)) + .as_i32_or_fail() + .is_err()); + + let valid_pos_i32 = i32::max_value() as i64; + assert_eq!( + Int::new(&BigNum(valid_pos_i32 as u64)) + .as_i32_or_fail() + .unwrap(), + i32::max_value() + ); + + let over_neg_i32 = (i32::min_value() as i64) - 1; + assert!(Int::new_negative(&BigNum((-over_neg_i32) as u64)) + .as_i32_or_fail() + .is_err()); + + let valid_neg_i32 = i32::min_value() as i64; + assert_eq!( + Int::new_negative(&BigNum((-valid_neg_i32) as u64)) + .as_i32_or_fail() + .unwrap(), + i32::min_value() + ); + + assert!(Int::new(&BigNum(u64::max_value())) + .as_i32_or_fail() + .is_err()); + assert_eq!( + Int::new(&BigNum(i32::max_value() as u64)) + .as_i32_or_fail() + .unwrap(), + i32::max_value() + ); + assert_eq!( + Int::new_negative(&BigNum(i32::max_value() as u64)) + .as_i32_or_fail() + .unwrap(), + -i32::max_value() + ); + + assert_eq!(Int::new_i32(42).as_i32_or_fail().unwrap(), 42); + assert_eq!(Int::new_i32(-42).as_i32_or_fail().unwrap(), -42); +} + +#[test] +fn int_full_range() { + // cbor_event's nint API worked via i64 but we now have a workaround for it + // so these tests are here to make sure that workaround works. + + // first nint below of i64::MIN + let bytes_x = vec![0x3b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let x = Int::from_bytes(bytes_x.clone()).unwrap(); + assert_eq!(x.to_str(), "-9223372036854775809"); + assert_eq!(bytes_x, x.to_bytes()); + + // smallest possible nint which is -u64::MAX - 1 + let bytes_y = vec![0x3b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; + let y = Int::from_bytes(bytes_y.clone()).unwrap(); + assert_eq!(y.to_str(), "-18446744073709551616"); + assert_eq!(bytes_y, y.to_bytes()); +} + +#[test] +fn test_bigint_add() { + assert_eq!(to_bigint(10).add(&to_bigint(20)), to_bigint(30),); + assert_eq!(to_bigint(500).add(&to_bigint(800)), to_bigint(1300),); +} + +#[test] +fn test_bigint_mul() { + assert_eq!(to_bigint(10).mul(&to_bigint(20)), to_bigint(200),); + assert_eq!(to_bigint(500).mul(&to_bigint(800)), to_bigint(400000),); + assert_eq!(to_bigint(12).mul(&to_bigint(22)), to_bigint(264),); +} + +#[test] +fn test_bigint_div_ceil() { + assert_eq!(to_bigint(20).div_ceil(&to_bigint(10)), to_bigint(2),); + assert_eq!(to_bigint(20).div_ceil(&to_bigint(2)), to_bigint(10),); + assert_eq!(to_bigint(21).div_ceil(&to_bigint(2)), to_bigint(11),); + assert_eq!(to_bigint(6).div_ceil(&to_bigint(3)), to_bigint(2),); + assert_eq!(to_bigint(5).div_ceil(&to_bigint(3)), to_bigint(2),); + assert_eq!(to_bigint(7).div_ceil(&to_bigint(3)), to_bigint(3),); +} + +#[test] +fn test_bignum_div() { + assert_eq!(BigNum(10).div_floor(&BigNum(1)), BigNum(10),); + assert_eq!(BigNum(10).div_floor(&BigNum(3)), BigNum(3),); + assert_eq!(BigNum(10).div_floor(&BigNum(4)), BigNum(2),); + assert_eq!(BigNum(10).div_floor(&BigNum(5)), BigNum(2),); + assert_eq!(BigNum(10).div_floor(&BigNum(6)), BigNum(1),); + assert_eq!(BigNum(10).div_floor(&BigNum(12)), BigNum::zero(),); +} + +#[test] +fn test_vasil_v1_costmodel_hashing() { + let v1 = Language::new_plutus_v1(); + let v1_cost_model = TxBuilderConstants::plutus_vasil_cost_models() + .get(&v1) + .unwrap(); + let mut costmodels = Costmdls::new(); + costmodels.insert(&v1, &v1_cost_model); + let hash = hash_script_data( + &Redeemers::from(vec![Redeemer::new( + &RedeemerTag::new_spend(), + &BigNum::zero(), + &PlutusData::new_integer(&BigInt::from_str("42").unwrap()), + &ExUnits::new(&BigNum(1700), &BigNum(368100)), + )]), + &costmodels, + Some(PlutusList::from(vec![PlutusData::new_integer( + &BigInt::from_str("42").unwrap(), + )])), + ); + assert_eq!( + hex::encode(hash.to_bytes()), + "887e1b6416d750d871c0f5b7136b54f7b8e8b0e293379d090f38f8f821d08a29" + ); +} + +#[test] +fn bigint_as_int() { + let zero = BigInt::from_str("0").unwrap(); + let zero_int = zero.as_int().unwrap(); + assert_eq!(zero_int.0, 0i128); + + let pos = BigInt::from_str("1024").unwrap(); + let pos_int = pos.as_int().unwrap(); + assert_eq!(pos_int.0, 1024i128); + + let neg = BigInt::from_str("-1024").unwrap(); + let neg_int = neg.as_int().unwrap(); + assert_eq!(neg_int.0, -1024i128); +} diff --git a/rust/src/utils.rs b/rust/src/utils.rs index a062301c..ac90c016 100644 --- a/rust/src/utils.rs +++ b/rust/src/utils.rs @@ -401,7 +401,7 @@ impl Deserialize for Value { } } -const BOUNDED_BYTES_CHUNK_SIZE: usize = 64; +pub(crate) const BOUNDED_BYTES_CHUNK_SIZE: usize = 64; pub(crate) fn write_bounded_bytes<'se, W: Write>( serializer: &'se mut Serializer, @@ -1086,763 +1086,4 @@ pub(crate) fn get_input_shortage( } else { Ok(None) } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::TxBuilderConstants; - - #[test] - fn subtract_values() { - let policy1 = PolicyID::from([0; ScriptHash::BYTE_COUNT]); - let policy2 = PolicyID::from([1; ScriptHash::BYTE_COUNT]); - - let asset1 = AssetName(vec![1]); - let asset2 = AssetName(vec![2]); - let asset3 = AssetName(vec![3]); - let asset4 = AssetName(vec![4]); - - let mut token_bundle1 = MultiAsset::new(); - { - let mut asset_list1 = Assets::new(); - asset_list1.insert(&asset1, &BigNum(1)); - asset_list1.insert(&asset2, &BigNum(1)); - asset_list1.insert(&asset3, &BigNum(1)); - asset_list1.insert(&asset4, &BigNum(2)); - token_bundle1.insert(&policy1, &asset_list1); - - let mut asset_list2 = Assets::new(); - asset_list2.insert(&asset1, &BigNum(1)); - token_bundle1.insert(&policy2, &asset_list2); - } - let assets1 = Value { - coin: BigNum(1555554), - multiasset: Some(token_bundle1), - }; - - let mut token_bundle2 = MultiAsset::new(); - { - let mut asset_list2 = Assets::new(); - // more than asset1 bundle - asset_list2.insert(&asset1, &BigNum(2)); - // exactly equal to asset1 bundle - asset_list2.insert(&asset2, &BigNum(1)); - // skip asset 3 - // less than in asset1 bundle - asset_list2.insert(&asset4, &BigNum(1)); - token_bundle2.insert(&policy1, &asset_list2); - - // this policy should be removed entirely - let mut asset_list2 = Assets::new(); - asset_list2.insert(&asset1, &BigNum(1)); - token_bundle2.insert(&policy2, &asset_list2); - } - - let assets2 = Value { - coin: BigNum(2555554), - multiasset: Some(token_bundle2), - }; - - let result = assets1.clamped_sub(&assets2); - assert_eq!(result.coin().to_str(), "0"); - assert_eq!( - result.multiasset().unwrap().len(), - 1 // policy 2 was deleted successfully - ); - let policy1_content = result.multiasset().unwrap().get(&policy1).unwrap(); - assert_eq!(policy1_content.len(), 2); - assert_eq!(policy1_content.get(&asset3).unwrap().to_str(), "1"); - assert_eq!(policy1_content.get(&asset4).unwrap().to_str(), "1"); - } - - #[test] - fn compare_values() { - let policy1 = PolicyID::from([0; ScriptHash::BYTE_COUNT]); - - let asset1 = AssetName(vec![1]); - let asset2 = AssetName(vec![2]); - - // testing cases with no assets - { - let a = Value::new(&BigNum(1)); - let b = Value::new(&BigNum(1)); - assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Equal); - } - { - let a = Value::new(&BigNum(2)); - let b = Value::new(&BigNum(1)); - assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Greater); - } - { - let a = Value::new(&BigNum(1)); - let b = Value::new(&BigNum(2)); - assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Less); - } - // testing case where one side has assets - { - let mut token_bundle1 = MultiAsset::new(); - let mut asset_list1 = Assets::new(); - asset_list1.insert(&asset1, &BigNum(1)); - token_bundle1.insert(&policy1, &asset_list1); - let a = Value { - coin: BigNum(1), - multiasset: Some(token_bundle1), - }; - let b = Value::new(&BigNum(1)); - assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Greater); - } - { - let mut token_bundle1 = MultiAsset::new(); - let mut asset_list1 = Assets::new(); - asset_list1.insert(&asset1, &BigNum(1)); - token_bundle1.insert(&policy1, &asset_list1); - let a = Value::new(&BigNum(1)); - let b = Value { - coin: BigNum(1), - multiasset: Some(token_bundle1), - }; - assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Less); - } - // testing case where both sides has assets - { - let mut token_bundle1 = MultiAsset::new(); - let mut asset_list1 = Assets::new(); - asset_list1.insert(&asset1, &BigNum(1)); - token_bundle1.insert(&policy1, &asset_list1); - let a = Value { - coin: BigNum(1), - multiasset: Some(token_bundle1), - }; - - let mut token_bundle2 = MultiAsset::new(); - let mut asset_list2 = Assets::new(); - asset_list2.insert(&asset1, &BigNum(1)); - token_bundle2.insert(&policy1, &asset_list2); - let b = Value { - coin: BigNum(1), - multiasset: Some(token_bundle2), - }; - assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Equal); - } - { - let mut token_bundle1 = MultiAsset::new(); - let mut asset_list1 = Assets::new(); - asset_list1.insert(&asset1, &BigNum(1)); - token_bundle1.insert(&policy1, &asset_list1); - let a = Value { - coin: BigNum(2), - multiasset: Some(token_bundle1), - }; - - let mut token_bundle2 = MultiAsset::new(); - let mut asset_list2 = Assets::new(); - asset_list2.insert(&asset1, &BigNum(1)); - token_bundle2.insert(&policy1, &asset_list2); - let b = Value { - coin: BigNum(1), - multiasset: Some(token_bundle2), - }; - assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Greater); - } - { - let mut token_bundle1 = MultiAsset::new(); - let mut asset_list1 = Assets::new(); - asset_list1.insert(&asset1, &BigNum(1)); - token_bundle1.insert(&policy1, &asset_list1); - let a = Value { - coin: BigNum(1), - multiasset: Some(token_bundle1), - }; - - let mut token_bundle2 = MultiAsset::new(); - let mut asset_list2 = Assets::new(); - asset_list2.insert(&asset1, &BigNum(1)); - token_bundle2.insert(&policy1, &asset_list2); - let b = Value { - coin: BigNum(2), - multiasset: Some(token_bundle2), - }; - assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Less); - } - { - let mut token_bundle1 = MultiAsset::new(); - let mut asset_list1 = Assets::new(); - asset_list1.insert(&asset1, &BigNum(2)); - token_bundle1.insert(&policy1, &asset_list1); - let a = Value { - coin: BigNum(1), - multiasset: Some(token_bundle1), - }; - - let mut token_bundle2 = MultiAsset::new(); - let mut asset_list2 = Assets::new(); - asset_list2.insert(&asset1, &BigNum(1)); - token_bundle2.insert(&policy1, &asset_list2); - let b = Value { - coin: BigNum(1), - multiasset: Some(token_bundle2), - }; - assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Greater); - } - { - let mut token_bundle1 = MultiAsset::new(); - let mut asset_list1 = Assets::new(); - asset_list1.insert(&asset1, &BigNum(2)); - token_bundle1.insert(&policy1, &asset_list1); - let a = Value { - coin: BigNum(2), - multiasset: Some(token_bundle1), - }; - - let mut token_bundle2 = MultiAsset::new(); - let mut asset_list2 = Assets::new(); - asset_list2.insert(&asset1, &BigNum(1)); - token_bundle2.insert(&policy1, &asset_list2); - let b = Value { - coin: BigNum(1), - multiasset: Some(token_bundle2), - }; - assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Greater); - } - { - let mut token_bundle1 = MultiAsset::new(); - let mut asset_list1 = Assets::new(); - asset_list1.insert(&asset1, &BigNum(2)); - token_bundle1.insert(&policy1, &asset_list1); - let a = Value { - coin: BigNum(1), - multiasset: Some(token_bundle1), - }; - - let mut token_bundle2 = MultiAsset::new(); - let mut asset_list2 = Assets::new(); - asset_list2.insert(&asset1, &BigNum(1)); - token_bundle2.insert(&policy1, &asset_list2); - let b = Value { - coin: BigNum(2), - multiasset: Some(token_bundle2), - }; - assert_eq!(a.partial_cmp(&b), None); - } - { - let mut token_bundle1 = MultiAsset::new(); - let mut asset_list1 = Assets::new(); - asset_list1.insert(&asset1, &BigNum(1)); - token_bundle1.insert(&policy1, &asset_list1); - let a = Value { - coin: BigNum(1), - multiasset: Some(token_bundle1), - }; - - let mut token_bundle2 = MultiAsset::new(); - let mut asset_list2 = Assets::new(); - asset_list2.insert(&asset1, &BigNum(2)); - token_bundle2.insert(&policy1, &asset_list2); - let b = Value { - coin: BigNum(1), - multiasset: Some(token_bundle2), - }; - assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Less); - } - { - let mut token_bundle1 = MultiAsset::new(); - let mut asset_list1 = Assets::new(); - asset_list1.insert(&asset1, &BigNum(1)); - token_bundle1.insert(&policy1, &asset_list1); - let a = Value { - coin: BigNum(1), - multiasset: Some(token_bundle1), - }; - - let mut token_bundle2 = MultiAsset::new(); - let mut asset_list2 = Assets::new(); - asset_list2.insert(&asset1, &BigNum(2)); - token_bundle2.insert(&policy1, &asset_list2); - let b = Value { - coin: BigNum(2), - multiasset: Some(token_bundle2), - }; - assert_eq!(a.partial_cmp(&b).unwrap(), std::cmp::Ordering::Less); - } - { - let mut token_bundle1 = MultiAsset::new(); - let mut asset_list1 = Assets::new(); - asset_list1.insert(&asset1, &BigNum(1)); - token_bundle1.insert(&policy1, &asset_list1); - let a = Value { - coin: BigNum(2), - multiasset: Some(token_bundle1), - }; - - let mut token_bundle2 = MultiAsset::new(); - let mut asset_list2 = Assets::new(); - asset_list2.insert(&asset1, &BigNum(2)); - token_bundle2.insert(&policy1, &asset_list2); - let b = Value { - coin: BigNum(1), - multiasset: Some(token_bundle2), - }; - assert_eq!(a.partial_cmp(&b), None); - } - { - let mut token_bundle1 = MultiAsset::new(); - let mut asset_list1 = Assets::new(); - asset_list1.insert(&asset1, &BigNum(1)); - token_bundle1.insert(&policy1, &asset_list1); - let a = Value { - coin: BigNum(1), - multiasset: Some(token_bundle1), - }; - - let mut token_bundle2 = MultiAsset::new(); - let mut asset_list2 = Assets::new(); - asset_list2.insert(&asset2, &BigNum(1)); - token_bundle2.insert(&policy1, &asset_list2); - let b = Value { - coin: BigNum(1), - multiasset: Some(token_bundle2), - }; - assert_eq!(a.partial_cmp(&b), None); - } - } - - #[test] - fn bigint_serialization() { - let zero = BigInt::from_str("0").unwrap(); - let zero_rt = BigInt::from_bytes(zero.to_bytes()).unwrap(); - assert_eq!(zero.to_str(), zero_rt.to_str()); - assert_eq!(zero.to_bytes(), vec![0x00]); - - let pos_small = BigInt::from_str("100").unwrap(); - let pos_small_rt = BigInt::from_bytes(pos_small.to_bytes()).unwrap(); - assert_eq!(pos_small.to_str(), pos_small_rt.to_str()); - - let pos_big = BigInt::from_str("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890").unwrap(); - let pos_big_rt = BigInt::from_bytes(pos_big.to_bytes()).unwrap(); - assert_eq!(pos_big.to_str(), pos_big_rt.to_str()); - - let neg_small = BigInt::from_str("-100").unwrap(); - let neg_small_rt = BigInt::from_bytes(neg_small.to_bytes()).unwrap(); - assert_eq!(neg_small.to_str(), neg_small_rt.to_str()); - - let neg_big = BigInt::from_str("-123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890").unwrap(); - let neg_big_rt = BigInt::from_bytes(neg_big.to_bytes()).unwrap(); - assert_eq!(neg_big.to_str(), neg_big_rt.to_str()); - - // taken from CBOR RFC examples - // negative big int - assert_eq!( - hex::decode("c349010000000000000000").unwrap(), - BigInt::from_str("-18446744073709551617") - .unwrap() - .to_bytes() - ); - // positive big int - assert_eq!( - hex::decode("c249010000000000000000").unwrap(), - BigInt::from_str("18446744073709551616").unwrap().to_bytes() - ); - // uint - assert_eq!( - hex::decode("1b000000e8d4a51000").unwrap(), - BigInt::from_str("1000000000000").unwrap().to_bytes() - ); - // nint (lowest possible - used to be unsupported but works now) - assert_eq!( - hex::decode("3bffffffffffffffff").unwrap(), - BigInt::from_str("-18446744073709551616") - .unwrap() - .to_bytes() - ); - // this one fits in an i64 though - assert_eq!( - hex::decode("3903e7").unwrap(), - BigInt::from_str("-1000").unwrap().to_bytes() - ); - - let x = BigInt::from_str("-18446744073709551617").unwrap(); - let x_rt = BigInt::from_bytes(x.to_bytes()).unwrap(); - assert_eq!(x.to_str(), x_rt.to_str()); - } - - #[test] - fn bounded_bytes_read_chunked() { - use std::io::Cursor; - let chunks = vec![ - vec![ - 0x52, 0x73, 0x6F, 0x6D, 0x65, 0x20, 0x72, 0x61, 0x6E, 0x64, 0x6F, 0x6D, 0x20, 0x73, - 0x74, 0x72, 0x69, 0x6E, 0x67, - ], - vec![0x44, 0x01, 0x02, 0x03, 0x04], - ]; - let mut expected = Vec::new(); - for chunk in chunks.iter() { - expected.extend_from_slice(&chunk[1..]); - } - let mut vec = vec![0x5f]; - for mut chunk in chunks { - vec.append(&mut chunk); - } - vec.push(0xff); - let mut raw = Deserializer::from(Cursor::new(vec.clone())); - let found = read_bounded_bytes(&mut raw).unwrap(); - assert_eq!(found, expected); - } - - #[test] - fn bounded_bytes_write_chunked() { - let mut chunk_64 = vec![0x58, BOUNDED_BYTES_CHUNK_SIZE as u8]; - chunk_64.extend(std::iter::repeat(37).take(BOUNDED_BYTES_CHUNK_SIZE)); - let chunks = vec![chunk_64, vec![0x44, 0x01, 0x02, 0x03, 0x04]]; - let mut input = Vec::new(); - input.extend_from_slice(&chunks[0][2..]); - input.extend_from_slice(&chunks[1][1..]); - let mut serializer = cbor_event::se::Serializer::new_vec(); - write_bounded_bytes(&mut serializer, &input).unwrap(); - let written = serializer.finalize(); - let mut expected = vec![0x5f]; - for mut chunk in chunks { - expected.append(&mut chunk); - } - expected.push(0xff); - assert_eq!(expected, written); - } - - #[test] - fn correct_script_data_hash() { - let mut datums = PlutusList::new(); - datums.add(&PlutusData::new_integer(&BigInt::from_str("1000").unwrap())); - let mut redeemers = Redeemers::new(); - redeemers.add(&Redeemer::new( - &RedeemerTag::new_spend(), - &BigNum::from_str("1").unwrap(), - &PlutusData::new_integer(&BigInt::from_str("2000").unwrap()), - &ExUnits::new( - &BigNum::from_str("0").unwrap(), - &BigNum::from_str("0").unwrap(), - ), - )); - let plutus_cost_model = CostModel::from_bytes(vec![ - 159, 26, 0, 3, 2, 89, 0, 1, 1, 26, 0, 6, 11, 199, 25, 2, 109, 0, 1, 26, 0, 2, 73, 240, - 25, 3, 232, 0, 1, 26, 0, 2, 73, 240, 24, 32, 26, 0, 37, 206, 168, 25, 113, 247, 4, 25, - 116, 77, 24, 100, 25, 116, 77, 24, 100, 25, 116, 77, 24, 100, 25, 116, 77, 24, 100, 25, - 116, 77, 24, 100, 25, 116, 77, 24, 100, 24, 100, 24, 100, 25, 116, 77, 24, 100, 26, 0, - 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, - 240, 25, 3, 232, 0, 1, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 25, 3, 232, 0, 8, - 26, 0, 2, 66, 32, 26, 0, 6, 126, 35, 24, 118, 0, 1, 1, 26, 0, 2, 73, 240, 25, 3, 232, - 0, 8, 26, 0, 2, 73, 240, 26, 0, 1, 183, 152, 24, 247, 1, 26, 0, 2, 73, 240, 25, 39, 16, - 1, 26, 0, 2, 21, 94, 25, 5, 46, 1, 25, 3, 232, 26, 0, 2, 73, 240, 25, 3, 232, 1, 26, 0, - 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 1, 1, 26, 0, - 2, 73, 240, 1, 26, 0, 2, 73, 240, 4, 26, 0, 1, 148, 175, 24, 248, 1, 26, 0, 1, 148, - 175, 24, 248, 1, 26, 0, 2, 55, 124, 25, 5, 86, 1, 26, 0, 2, 189, 234, 25, 1, 241, 1, - 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, - 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 66, - 32, 26, 0, 6, 126, 35, 24, 118, 0, 1, 1, 25, 240, 76, 25, 43, 210, 0, 1, 26, 0, 2, 73, - 240, 24, 32, 26, 0, 2, 66, 32, 26, 0, 6, 126, 35, 24, 118, 0, 1, 1, 26, 0, 2, 66, 32, - 26, 0, 6, 126, 35, 24, 118, 0, 1, 1, 26, 0, 37, 206, 168, 25, 113, 247, 4, 0, 26, 0, 1, - 65, 187, 4, 26, 0, 2, 73, 240, 25, 19, 136, 0, 1, 26, 0, 2, 73, 240, 24, 32, 26, 0, 3, - 2, 89, 0, 1, 1, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, - 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 2, 73, 240, - 24, 32, 26, 0, 2, 73, 240, 24, 32, 26, 0, 51, 13, 167, 1, 1, 255, - ]) - .unwrap(); - let mut cost_models = Costmdls::new(); - cost_models.insert(&Language::new_plutus_v1(), &plutus_cost_model); - let script_data_hash = hash_script_data(&redeemers, &cost_models, Some(datums)); - - assert_eq!( - hex::encode(script_data_hash.to_bytes()), - "4415e6667e6d6bbd992af5092d48e3c2ba9825200d0234d2470068f7f0f178b3" - ); - } - - #[test] - fn native_scripts_from_wallet_json() { - let cosigner0_hex = "1423856bc91c49e928f6f30f4e8d665d53eb4ab6028bd0ac971809d514c92db11423856bc91c49e928f6f30f4e8d665d53eb4ab6028bd0ac971809d514c92db1"; - let cosigner1_hex = "a48d97f57ce49433f347d44ee07e54a100229b4f8e125d25f7bca9ad66d9707a25cd1331f46f7d6e279451637ca20802a25c441ba9436abf644fe5410d1080e3"; - let self_key_hex = "6ce83a12e9d4c783f54c0bb511303b37160a6e4f3f96b8e878a7c1f7751e18c4ccde3fb916d330d07f7bd51fb6bd99aa831d925008d3f7795033f48abd6df7f6"; - let native_script = encode_json_str_to_native_script( - &format!( - r#" - {{ - "cosigners": {{ - "cosigner#0": "{}", - "cosigner#1": "{}", - "cosigner#2": "self" - }}, - "template": {{ - "some": {{ - "at_least": 2, - "from": [ - {{ - "all": [ - "cosigner#0", - {{ "active_from": 120 }} - ] - }}, - {{ - "any": [ - "cosigner#1", - {{ "active_until": 1000 }} - ] - }}, - "cosigner#2" - ] - }} - }} - }}"#, - cosigner0_hex, cosigner1_hex - ), - self_key_hex, - ScriptSchema::Wallet, - ); - - let n_of_k = native_script.unwrap().as_script_n_of_k().unwrap(); - let from = n_of_k.native_scripts(); - assert_eq!(n_of_k.n(), 2); - assert_eq!(from.len(), 3); - let all = from.get(0).as_script_all().unwrap().native_scripts(); - assert_eq!(all.len(), 2); - let all_0 = all.get(0).as_script_pubkey().unwrap(); - assert_eq!( - all_0.addr_keyhash(), - Bip32PublicKey::from_bytes(&hex::decode(cosigner0_hex).unwrap()) - .unwrap() - .to_raw_key() - .hash() - ); - let all_1 = all.get(1).as_timelock_start().unwrap(); - assert_eq!(all_1.slot().unwrap(), 120); - let any = from.get(1).as_script_any().unwrap().native_scripts(); - assert_eq!(all.len(), 2); - let any_0 = any.get(0).as_script_pubkey().unwrap(); - assert_eq!( - any_0.addr_keyhash(), - Bip32PublicKey::from_bytes(&hex::decode(cosigner1_hex).unwrap()) - .unwrap() - .to_raw_key() - .hash() - ); - let any_1 = any.get(1).as_timelock_expiry().unwrap(); - assert_eq!(any_1.slot().unwrap(), 1000); - let self_key = from.get(2).as_script_pubkey().unwrap(); - assert_eq!( - self_key.addr_keyhash(), - Bip32PublicKey::from_bytes(&hex::decode(self_key_hex).unwrap()) - .unwrap() - .to_raw_key() - .hash() - ); - } - - #[test] - fn int_to_str() { - assert_eq!( - Int::new(&BigNum(u64::max_value())).to_str(), - u64::max_value().to_string() - ); - assert_eq!( - Int::new(&BigNum(u64::min_value())).to_str(), - u64::min_value().to_string() - ); - assert_eq!( - Int::new_negative(&BigNum(u64::max_value())).to_str(), - (-(u64::max_value() as i128)).to_string() - ); - assert_eq!( - Int::new_negative(&BigNum(u64::min_value())).to_str(), - (-(u64::min_value() as i128)).to_string() - ); - assert_eq!(Int::new_i32(142).to_str(), "142"); - assert_eq!(Int::new_i32(-142).to_str(), "-142"); - } - - #[test] - fn int_as_i32_or_nothing() { - let over_pos_i32 = (i32::max_value() as i64) + 1; - assert!(Int::new(&BigNum(over_pos_i32 as u64)) - .as_i32_or_nothing() - .is_none()); - - let valid_pos_i32 = i32::max_value() as i64; - assert_eq!( - Int::new(&BigNum(valid_pos_i32 as u64)) - .as_i32_or_nothing() - .unwrap(), - i32::max_value() - ); - - let over_neg_i32 = (i32::min_value() as i64) - 1; - assert!(Int::new_negative(&BigNum((-over_neg_i32) as u64)) - .as_i32_or_nothing() - .is_none()); - - let valid_neg_i32 = i32::min_value() as i64; - assert_eq!( - Int::new_negative(&BigNum((-valid_neg_i32) as u64)) - .as_i32_or_nothing() - .unwrap(), - i32::min_value() - ); - - assert!(Int::new(&BigNum(u64::max_value())) - .as_i32_or_nothing() - .is_none()); - assert_eq!( - Int::new(&BigNum(i32::max_value() as u64)) - .as_i32_or_nothing() - .unwrap(), - i32::max_value() - ); - assert_eq!( - Int::new_negative(&BigNum(i32::max_value() as u64)) - .as_i32_or_nothing() - .unwrap(), - -i32::max_value() - ); - - assert_eq!(Int::new_i32(42).as_i32_or_nothing().unwrap(), 42); - assert_eq!(Int::new_i32(-42).as_i32_or_nothing().unwrap(), -42); - } - - #[test] - fn int_as_i32_or_fail() { - let over_pos_i32 = (i32::max_value() as i64) + 1; - assert!(Int::new(&BigNum(over_pos_i32 as u64)) - .as_i32_or_fail() - .is_err()); - - let valid_pos_i32 = i32::max_value() as i64; - assert_eq!( - Int::new(&BigNum(valid_pos_i32 as u64)) - .as_i32_or_fail() - .unwrap(), - i32::max_value() - ); - - let over_neg_i32 = (i32::min_value() as i64) - 1; - assert!(Int::new_negative(&BigNum((-over_neg_i32) as u64)) - .as_i32_or_fail() - .is_err()); - - let valid_neg_i32 = i32::min_value() as i64; - assert_eq!( - Int::new_negative(&BigNum((-valid_neg_i32) as u64)) - .as_i32_or_fail() - .unwrap(), - i32::min_value() - ); - - assert!(Int::new(&BigNum(u64::max_value())) - .as_i32_or_fail() - .is_err()); - assert_eq!( - Int::new(&BigNum(i32::max_value() as u64)) - .as_i32_or_fail() - .unwrap(), - i32::max_value() - ); - assert_eq!( - Int::new_negative(&BigNum(i32::max_value() as u64)) - .as_i32_or_fail() - .unwrap(), - -i32::max_value() - ); - - assert_eq!(Int::new_i32(42).as_i32_or_fail().unwrap(), 42); - assert_eq!(Int::new_i32(-42).as_i32_or_fail().unwrap(), -42); - } - - #[test] - fn int_full_range() { - // cbor_event's nint API worked via i64 but we now have a workaround for it - // so these tests are here to make sure that workaround works. - - // first nint below of i64::MIN - let bytes_x = vec![0x3b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; - let x = Int::from_bytes(bytes_x.clone()).unwrap(); - assert_eq!(x.to_str(), "-9223372036854775809"); - assert_eq!(bytes_x, x.to_bytes()); - - // smallest possible nint which is -u64::MAX - 1 - let bytes_y = vec![0x3b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; - let y = Int::from_bytes(bytes_y.clone()).unwrap(); - assert_eq!(y.to_str(), "-18446744073709551616"); - assert_eq!(bytes_y, y.to_bytes()); - } - - #[test] - fn test_bigint_add() { - assert_eq!(to_bigint(10).add(&to_bigint(20)), to_bigint(30),); - assert_eq!(to_bigint(500).add(&to_bigint(800)), to_bigint(1300),); - } - - #[test] - fn test_bigint_mul() { - assert_eq!(to_bigint(10).mul(&to_bigint(20)), to_bigint(200),); - assert_eq!(to_bigint(500).mul(&to_bigint(800)), to_bigint(400000),); - assert_eq!(to_bigint(12).mul(&to_bigint(22)), to_bigint(264),); - } - - #[test] - fn test_bigint_div_ceil() { - assert_eq!(to_bigint(20).div_ceil(&to_bigint(10)), to_bigint(2),); - assert_eq!(to_bigint(20).div_ceil(&to_bigint(2)), to_bigint(10),); - assert_eq!(to_bigint(21).div_ceil(&to_bigint(2)), to_bigint(11),); - assert_eq!(to_bigint(6).div_ceil(&to_bigint(3)), to_bigint(2),); - assert_eq!(to_bigint(5).div_ceil(&to_bigint(3)), to_bigint(2),); - assert_eq!(to_bigint(7).div_ceil(&to_bigint(3)), to_bigint(3),); - } - - #[test] - fn test_bignum_div() { - assert_eq!(BigNum(10).div_floor(&BigNum(1)), BigNum(10),); - assert_eq!(BigNum(10).div_floor(&BigNum(3)), BigNum(3),); - assert_eq!(BigNum(10).div_floor(&BigNum(4)), BigNum(2),); - assert_eq!(BigNum(10).div_floor(&BigNum(5)), BigNum(2),); - assert_eq!(BigNum(10).div_floor(&BigNum(6)), BigNum(1),); - assert_eq!(BigNum(10).div_floor(&BigNum(12)), BigNum::zero(),); - } - - #[test] - fn test_vasil_v1_costmodel_hashing() { - let v1 = Language::new_plutus_v1(); - let v1_cost_model = TxBuilderConstants::plutus_vasil_cost_models() - .get(&v1) - .unwrap(); - let mut costmodels = Costmdls::new(); - costmodels.insert(&v1, &v1_cost_model); - let hash = hash_script_data( - &Redeemers::from(vec![Redeemer::new( - &RedeemerTag::new_spend(), - &BigNum::zero(), - &PlutusData::new_integer(&BigInt::from_str("42").unwrap()), - &ExUnits::new(&BigNum(1700), &BigNum(368100)), - )]), - &costmodels, - Some(PlutusList::from(vec![PlutusData::new_integer( - &BigInt::from_str("42").unwrap(), - )])), - ); - assert_eq!( - hex::encode(hash.to_bytes()), - "887e1b6416d750d871c0f5b7136b54f7b8e8b0e293379d090f38f8f821d08a29" - ); - } - - #[test] - fn bigint_as_int() { - let zero = BigInt::from_str("0").unwrap(); - let zero_int = zero.as_int().unwrap(); - assert_eq!(zero_int.0, 0i128); - - let pos = BigInt::from_str("1024").unwrap(); - let pos_int = pos.as_int().unwrap(); - assert_eq!(pos_int.0, 1024i128); - - let neg = BigInt::from_str("-1024").unwrap(); - let neg_int = neg.as_int().unwrap(); - assert_eq!(neg_int.0, -1024i128); - } -} +} \ No newline at end of file From 9d2393a9acc7bd7c1712bce8b587cc86606984fc Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 22 Jun 2024 15:50:46 +0700 Subject: [PATCH 295/349] tx witnesses set fields deduplication, tests --- rust/src/protocol_types/native_scripts.rs | 4 + rust/src/protocol_types/plutus/plutus_data.rs | 4 + .../protocol_types/plutus/plutus_scripts.rs | 4 + rust/src/serialization/native_scripts.rs | 2 +- .../witnesses/transaction_witnesses_set.rs | 6 +- rust/src/tests/general.rs | 215 ++++++++++++++++++ 6 files changed, 232 insertions(+), 3 deletions(-) diff --git a/rust/src/protocol_types/native_scripts.rs b/rust/src/protocol_types/native_scripts.rs index cf49aa53..59023cbe 100644 --- a/rust/src/protocol_types/native_scripts.rs +++ b/rust/src/protocol_types/native_scripts.rs @@ -45,6 +45,10 @@ impl NativeScripts { } NativeScripts(scripts) } + + pub(crate) fn contains(&self, script: &NativeScript) -> bool { + self.0.contains(script) + } } impl_to_from!(NativeScripts); diff --git a/rust/src/protocol_types/plutus/plutus_data.rs b/rust/src/protocol_types/plutus/plutus_data.rs index e0041a2a..b04b22b4 100644 --- a/rust/src/protocol_types/plutus/plutus_data.rs +++ b/rust/src/protocol_types/plutus/plutus_data.rs @@ -490,6 +490,10 @@ impl PlutusList { self.definite_encoding = None; } + pub(crate) fn contains(&self, elem: &PlutusData) -> bool { + self.elems.contains(elem) + } + pub(crate) fn deduplicated_view(&self) -> Vec<&PlutusData> { let mut dedup = BTreeSet::new(); let mut keyhashes = Vec::new(); diff --git a/rust/src/protocol_types/plutus/plutus_scripts.rs b/rust/src/protocol_types/plutus/plutus_scripts.rs index 92bc768b..47f563f2 100644 --- a/rust/src/protocol_types/plutus/plutus_scripts.rs +++ b/rust/src/protocol_types/plutus/plutus_scripts.rs @@ -91,4 +91,8 @@ impl PlutusScripts { } PlutusScripts(scripts) } + + pub(crate) fn contains(&self, script: &PlutusScript) -> bool { + self.0.contains(&script) + } } diff --git a/rust/src/serialization/native_scripts.rs b/rust/src/serialization/native_scripts.rs index 14c2a85d..8b3f5e7b 100644 --- a/rust/src/serialization/native_scripts.rs +++ b/rust/src/serialization/native_scripts.rs @@ -15,7 +15,7 @@ impl cbor_event::se::Serialize for NativeScripts { } impl NativeScripts { - fn serialize_as_set<'se, W: Write>( + pub(crate) fn serialize_as_set<'se, W: Write>( &self, need_deduplication: bool, serializer: &'se mut Serializer, diff --git a/rust/src/serialization/witnesses/transaction_witnesses_set.rs b/rust/src/serialization/witnesses/transaction_witnesses_set.rs index 8babdd9c..578fa179 100644 --- a/rust/src/serialization/witnesses/transaction_witnesses_set.rs +++ b/rust/src/serialization/witnesses/transaction_witnesses_set.rs @@ -41,7 +41,8 @@ impl cbor_event::se::Serialize for TransactionWitnessSet { if let Some(field) = &self.native_scripts { if !field.is_none_or_empty() { serializer.write_unsigned_integer(1)?; - field.serialize(serializer)?; + //transaction witness set already has deduplicated native scripts + field.serialize_as_set(false, serializer)?; } } if let Some(field) = &self.bootstraps { @@ -69,7 +70,8 @@ impl cbor_event::se::Serialize for TransactionWitnessSet { if let Some(field) = &self.plutus_data { if !field.is_none_or_empty() { serializer.write_unsigned_integer(4)?; - field.serialize(serializer)?; + //transaction witness set already has deduplicated plutus data + field.serialize_as_set(false, serializer)?; } } if let Some(field) = &self.redeemers { diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index 2e330f0a..df98ab80 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -500,4 +500,219 @@ fn vkeywitneses_dedup() { assert!(!vkeywitnesses.add(&vkeywitness1)); assert_eq!(vkeywitnesses.len(), 2); +} + +#[test] +fn plutus_scripts_dedup_on_tx_witnesses_set() { + let plutus_script_v1_1 = create_plutus_script(1, &Language::new_plutus_v1()); + let plutus_script_v1_2 = create_plutus_script(2, &Language::new_plutus_v1()); + + let plutus_script_v2_1 = create_plutus_script(1, &Language::new_plutus_v2()); + let plutus_script_v2_2 = create_plutus_script(2, &Language::new_plutus_v2()); + + let plutus_script_v3_1 = create_plutus_script(1, &Language::new_plutus_v3()); + let plutus_script_v3_2 = create_plutus_script(2, &Language::new_plutus_v3()); + + let mut plutus_scrips = PlutusScripts::new(); + plutus_scrips.add(&plutus_script_v1_1); + plutus_scrips.add(&plutus_script_v1_2); + plutus_scrips.add(&plutus_script_v1_1); + + plutus_scrips.add(&plutus_script_v2_1); + plutus_scrips.add(&plutus_script_v2_2); + plutus_scrips.add(&plutus_script_v2_1); + + plutus_scrips.add(&plutus_script_v3_1); + plutus_scrips.add(&plutus_script_v3_2); + plutus_scrips.add(&plutus_script_v3_1); + assert_eq!(plutus_scrips.len(), 9); + + let mut tx_wit_set = TransactionWitnessSet::new(); + tx_wit_set.set_plutus_scripts(&plutus_scrips); + + let plutus_scripts_from = tx_wit_set.plutus_scripts().unwrap(); + assert_eq!(plutus_scripts_from.len(), 6); + assert!(plutus_scripts_from.contains(&plutus_script_v1_1)); + assert!(plutus_scripts_from.contains(&plutus_script_v1_2)); + assert!(plutus_scripts_from.contains(&plutus_script_v2_1)); + assert!(plutus_scripts_from.contains(&plutus_script_v2_2)); + assert!(plutus_scripts_from.contains(&plutus_script_v3_1)); + assert!(plutus_scripts_from.contains(&plutus_script_v3_2)); + + let tx_wit_set_bytes = tx_wit_set.to_bytes(); + let tx_wit_set_from_bytes = TransactionWitnessSet::from_bytes(tx_wit_set_bytes).unwrap(); + let plutus_scripts_from_bytes = tx_wit_set_from_bytes.plutus_scripts().unwrap(); + assert_eq!(plutus_scripts_from_bytes.len(), 6); + assert!(plutus_scripts_from_bytes.contains(&plutus_script_v1_1)); + assert!(plutus_scripts_from_bytes.contains(&plutus_script_v1_2)); + assert!(plutus_scripts_from_bytes.contains(&plutus_script_v2_1)); + assert!(plutus_scripts_from_bytes.contains(&plutus_script_v2_2)); + assert!(plutus_scripts_from_bytes.contains(&plutus_script_v3_1)); + assert!(plutus_scripts_from_bytes.contains(&plutus_script_v3_2)); +} + +#[test] +fn plutus_scripts_no_dedup_on_auxdata() { + let plutus_script_v1_1 = create_plutus_script(1, &Language::new_plutus_v1()); + let plutus_script_v1_2 = create_plutus_script(2, &Language::new_plutus_v1()); + + let plutus_script_v2_1 = create_plutus_script(1, &Language::new_plutus_v2()); + let plutus_script_v2_2 = create_plutus_script(2, &Language::new_plutus_v2()); + + let plutus_script_v3_1 = create_plutus_script(1, &Language::new_plutus_v3()); + let plutus_script_v3_2 = create_plutus_script(2, &Language::new_plutus_v3()); + + let mut plutus_scrips = PlutusScripts::new(); + plutus_scrips.add(&plutus_script_v1_1); + plutus_scrips.add(&plutus_script_v1_2); + plutus_scrips.add(&plutus_script_v1_1); + + plutus_scrips.add(&plutus_script_v2_1); + plutus_scrips.add(&plutus_script_v2_2); + plutus_scrips.add(&plutus_script_v2_1); + + plutus_scrips.add(&plutus_script_v3_1); + plutus_scrips.add(&plutus_script_v3_2); + plutus_scrips.add(&plutus_script_v3_1); + assert_eq!(plutus_scrips.len(), 9); + + let mut aux_data = AuxiliaryData::new(); + aux_data.set_plutus_scripts(&plutus_scrips); + + let plutus_scripts_from = aux_data.plutus_scripts().unwrap(); + assert_eq!(plutus_scripts_from.len(), 9); + assert!(plutus_scripts_from.contains(&plutus_script_v1_1)); + assert!(plutus_scripts_from.contains(&plutus_script_v1_2)); + assert!(plutus_scripts_from.contains(&plutus_script_v2_1)); + assert!(plutus_scripts_from.contains(&plutus_script_v2_2)); + assert!(plutus_scripts_from.contains(&plutus_script_v3_1)); + assert!(plutus_scripts_from.contains(&plutus_script_v3_2)); + + let aux_data_bytes = aux_data.to_bytes(); + let aux_data_from_bytes = AuxiliaryData::from_bytes(aux_data_bytes).unwrap(); + let plutus_scripts_from_bytes = aux_data_from_bytes.plutus_scripts().unwrap(); + assert_eq!(plutus_scripts_from_bytes.len(), 9); + assert!(plutus_scripts_from_bytes.contains(&plutus_script_v1_1)); + assert!(plutus_scripts_from_bytes.contains(&plutus_script_v1_2)); + assert!(plutus_scripts_from_bytes.contains(&plutus_script_v2_1)); + assert!(plutus_scripts_from_bytes.contains(&plutus_script_v2_2)); + assert!(plutus_scripts_from_bytes.contains(&plutus_script_v3_1)); + assert!(plutus_scripts_from_bytes.contains(&plutus_script_v3_2)); +} + +#[test] +pub fn native_scripts_dedup_on_tx_witnesses_set() { + let keyhash1 = keyhash(1); + + let native_scripts_1 = NativeScript::new_script_pubkey(&ScriptPubkey::new( + &keyhash1, + )); + + let mut internal_scripts = NativeScripts::new(); + internal_scripts.add(&native_scripts_1); + let native_scripts_2 = NativeScript::new_script_n_of_k(&ScriptNOfK::new( + 1, + &internal_scripts, + )); + + let mut native_scripts = NativeScripts::new(); + native_scripts.add(&native_scripts_1); + native_scripts.add(&native_scripts_2); + native_scripts.add(&native_scripts_1); + assert_eq!(native_scripts.len(), 3); + + let mut tx_wit_set = TransactionWitnessSet::new(); + tx_wit_set.set_native_scripts(&native_scripts); + + let native_scripts_from = tx_wit_set.native_scripts().unwrap(); + assert_eq!(native_scripts_from.len(), 2); + assert!(native_scripts_from.contains(&native_scripts_1)); + assert!(native_scripts_from.contains(&native_scripts_2)); + + let tx_wit_set_bytes = tx_wit_set.to_bytes(); + let tx_wit_set_from_bytes = TransactionWitnessSet::from_bytes(tx_wit_set_bytes).unwrap(); + let native_scripts_from_bytes = tx_wit_set_from_bytes.native_scripts().unwrap(); + assert_eq!(native_scripts_from_bytes.len(), 2); + assert!(native_scripts_from_bytes.contains(&native_scripts_1)); + assert!(native_scripts_from_bytes.contains(&native_scripts_2)); +} + +#[test] +pub fn native_scripts_no_dedup_on_auxdata() { + let keyhash1 = keyhash(1); + + let native_scripts_1 = NativeScript::new_script_pubkey(&ScriptPubkey::new( + &keyhash1, + )); + + let mut internal_scripts = NativeScripts::new(); + internal_scripts.add(&native_scripts_1); + let native_scripts_2 = NativeScript::new_script_n_of_k(&ScriptNOfK::new( + 1, + &internal_scripts, + )); + + let mut native_scripts = NativeScripts::new(); + native_scripts.add(&native_scripts_1); + native_scripts.add(&native_scripts_2); + native_scripts.add(&native_scripts_1); + assert_eq!(native_scripts.len(), 3); + + let mut aux_data = AuxiliaryData::new(); + aux_data.set_native_scripts(&native_scripts); + + let native_scripts_from = aux_data.native_scripts().unwrap(); + assert_eq!(native_scripts_from.len(), 3); + assert!(native_scripts_from.contains(&native_scripts_1)); + assert!(native_scripts_from.contains(&native_scripts_2)); + + let aux_data_bytes = aux_data.to_bytes(); + let aux_data_from_bytes = AuxiliaryData::from_bytes(aux_data_bytes).unwrap(); + let native_scripts_from_bytes = aux_data_from_bytes.native_scripts().unwrap(); + assert_eq!(native_scripts_from_bytes.len(), 3); + assert!(native_scripts_from_bytes.contains(&native_scripts_1)); + assert!(native_scripts_from_bytes.contains(&native_scripts_2)); +} + +#[test] fn plutus_data_dedup_on_tx_witnesses_set() { + let datum_1 = PlutusData::new_integer(&BigInt::from(1)); + let datum_2 = PlutusData::new_integer(&BigInt::from(2)); + + let mut datum = PlutusList::new(); + datum.add(&datum_1); + datum.add(&datum_2); + datum.add(&datum_1); + assert_eq!(datum.len(), 3); + + let mut tx_wit_set = TransactionWitnessSet::new(); + tx_wit_set.set_plutus_data(&datum); + + let datums_from = tx_wit_set.plutus_data().unwrap(); + assert_eq!(datums_from.len(), 2); + assert!(datums_from.contains(&datum_1)); + assert!(datums_from.contains(&datum_2)); + + let tx_wit_set_bytes = tx_wit_set.to_bytes(); + let tx_wit_set_from_bytes = TransactionWitnessSet::from_bytes(tx_wit_set_bytes).unwrap(); + let datums_from_bytes = tx_wit_set_from_bytes.plutus_data().unwrap(); + assert_eq!(datums_from_bytes.len(), 2); + assert!(datums_from_bytes.contains(&datum_1)); + assert!(datums_from_bytes.contains(&datum_2)); +} + +#[test] fn plutus_data_no_dedup_serialization() { + let datum_1 = PlutusData::new_integer(&BigInt::from(1)); + let datum_2 = PlutusData::new_integer(&BigInt::from(2)); + + let mut datum = PlutusList::new(); + datum.add(&datum_1); + datum.add(&datum_2); + datum.add(&datum_1); + assert_eq!(datum.len(), 3); + + let datum_bytes = datum.to_bytes(); + let datum_from_bytes = PlutusList::from_bytes(datum_bytes).unwrap(); + assert_eq!(datum_from_bytes.len(), 3); + assert!(datum_from_bytes.contains(&datum_1)); + assert!(datum_from_bytes.contains(&datum_2)); } \ No newline at end of file From 5591034b5b64b871e13d2d4878549075b6383982 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 22 Jun 2024 16:11:38 +0700 Subject: [PATCH 296/349] add tests for address payment_cred(), kind(), network_id() --- rust/src/tests/address.rs | 138 +++++++++++++++++++++++++++++++++++--- 1 file changed, 130 insertions(+), 8 deletions(-) diff --git a/rust/src/tests/address.rs b/rust/src/tests/address.rs index 82ff2b83..46e1b33e 100644 --- a/rust/src/tests/address.rs +++ b/rust/src/tests/address.rs @@ -1,4 +1,9 @@ +use crate::tests::mock_objects::{ + create_base_address, create_enterprise_address, create_malformed_address, + create_pointer_address, create_reward_address, +}; use crate::*; +use crate::fakes::fake_key_hash; #[test] fn variable_nat_encoding() { @@ -164,7 +169,8 @@ fn bip32_12_enterprise() { .to_public(); let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = - EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(); + EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) + .to_address(); assert_eq!( addr_net_0.to_bech32(None).unwrap(), "addr_test1vz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzerspjrlsz" @@ -255,7 +261,8 @@ fn bip32_15_enterprise() { .to_public(); let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = - EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(); + EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) + .to_address(); assert_eq!( addr_net_0.to_bech32(None).unwrap(), "addr_test1vpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5eg57c2qv" @@ -389,7 +396,8 @@ fn bip32_24_enterprise() { .to_public(); let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); let addr_net_0 = - EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred).to_address(); + EnterpriseAddress::new(NetworkInfo::testnet_preprod().network_id(), &spend_cred) + .to_address(); assert_eq!( addr_net_0.to_bech32(None).unwrap(), "addr_test1vqy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqtjtf68" @@ -568,13 +576,127 @@ fn malformed_addres_deserialisation_errors() { #[test] fn malformed_addres_embedded() { let address = MalformedAddress(vec![5u8; 32]); - let output = TransactionOutput::new( - &address.to_address(), - &Value::new(&Coin::from(100u64)), - ); + let output = TransactionOutput::new(&address.to_address(), &Value::new(&Coin::from(100u64))); let bytes = output.to_bytes(); let output2 = TransactionOutput::from_bytes(bytes).unwrap(); assert!(output2.address.is_malformed()); assert_eq!(&address.to_address(), &output2.address); -} \ No newline at end of file +} + +#[test] +fn address_kind() { + let base_address = create_base_address(1); + assert_eq!(base_address.kind(), AddressKind::Base); + + let pointer_address = create_pointer_address(2); + assert_eq!(pointer_address.kind(), AddressKind::Pointer); + + let enterprise_address = create_enterprise_address(3); + assert_eq!(enterprise_address.kind(), AddressKind::Enterprise); + + let reward_address = create_reward_address(4); + assert_eq!(reward_address.kind(), AddressKind::Reward); + + let byron_address = + ByronAddress::from_base58("Ae2tdPwUPEZ6r6zbg4ibhFrNnyKHg7SYuPSfDpjKxgvwFX9LquRep7gj7FQ") + .unwrap() + .to_address(); + assert_eq!(byron_address.kind(), AddressKind::Byron); + + let malformed_address = create_malformed_address(); + assert_eq!(malformed_address.kind(), AddressKind::Malformed); +} + +#[test] +fn address_payment_cred() { + let key_hash_1 = fake_key_hash(1); + let key_hash_2 = fake_key_hash(2); + let key_hash_3 = fake_key_hash(3); + let key_hash_4 = fake_key_hash(4); + let key_hash_5 = fake_key_hash(5); + let credential_1 = Credential::from_keyhash(&key_hash_1); + let credential_2 = Credential::from_keyhash(&key_hash_2); + let credential_3 = Credential::from_keyhash(&key_hash_3); + let credential_4 = Credential::from_keyhash(&key_hash_4); + let credential_5 = Credential::from_keyhash(&key_hash_5); + + let base_address = BaseAddress::new( + 1, + &credential_1, + &credential_2, + ).to_address(); + assert_eq!(base_address.payment_cred(), Some(credential_1)); + + let pointer_address = PointerAddress::new( + 2, + &credential_3, + &Pointer::new_pointer(&BigNum(1), &BigNum(2), &BigNum(3)), + ).to_address(); + assert_eq!(pointer_address.payment_cred(), Some(credential_3)); + + let enterprise_address = EnterpriseAddress::new( + 3, + &credential_4, + ).to_address(); + assert_eq!(enterprise_address.payment_cred(), Some(credential_4)); + + let reward_address = RewardAddress::new( + 4, + &credential_5, + ).to_address(); + + assert_eq!(reward_address.payment_cred(), Some(credential_5)); + + let byron_address = + ByronAddress::from_base58("Ae2tdPwUPEZ6r6zbg4ibhFrNnyKHg7SYuPSfDpjKxgvwFX9LquRep7gj7FQ") + .unwrap() + .to_address(); + assert_eq!(byron_address.payment_cred(), None); + + let malformed_address = create_malformed_address(); + assert_eq!(malformed_address.payment_cred(), None); +} + + +#[test] +fn addresses_network_id() { + let base_address = BaseAddress::new( + 1, + &Credential::from_keyhash(&fake_key_hash(1)), + &Credential::from_keyhash(&fake_key_hash(2)), + ); + assert_eq!(base_address.network_id(), 1); + assert_eq!(base_address.to_address().network_id().unwrap(), 1); + + let pointer_address = PointerAddress::new( + 2, + &Credential::from_keyhash(&fake_key_hash(3)), + &Pointer::new_pointer(&BigNum(1), &BigNum(2), &BigNum(3)), + ); + assert_eq!(pointer_address.network_id(), 2); + assert_eq!(pointer_address.to_address().network_id().unwrap(), 2); + + let enterprise_address = EnterpriseAddress::new( + 3, + &Credential::from_keyhash(&fake_key_hash(4)), + ); + assert_eq!(enterprise_address.network_id(), 3); + assert_eq!(enterprise_address.to_address().network_id().unwrap(), 3); + + let reward_address = RewardAddress::new( + 4, + &Credential::from_keyhash(&fake_key_hash(5)), + ); + assert_eq!(reward_address.network_id(), 4); + assert_eq!(reward_address.to_address().network_id().unwrap(), 4); + + let byron_address = + ByronAddress::from_base58("Ae2tdPwUPEZ6r6zbg4ibhFrNnyKHg7SYuPSfDpjKxgvwFX9LquRep7gj7FQ") + .unwrap(); + assert_eq!(byron_address.network_id().unwrap(), 1); + assert_eq!(byron_address.to_address().network_id().unwrap(), 1); + + let malformed_address = create_malformed_address(); + assert!(malformed_address.network_id().is_err()); +} From 27a790255eb7569ac92bc802bf6c395646ebfeb4 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 22 Jun 2024 23:50:23 +0700 Subject: [PATCH 297/349] fix structs that marked as "set" in cddl --- rust/src/builders/certificates_builder.rs | 2 +- rust/src/builders/tx_builder.rs | 2 +- rust/src/builders/voting_proposal_builder.rs | 2 +- .../certificates/certificates_collection.rs | 42 ++++++++++++++--- .../governance/proposals/voting_proposals.rs | 45 ++++++++++++++++--- .../certificates/certificates_collection.rs | 10 ++--- rust/src/serialization/ed25519_key_hashes.rs | 6 +-- .../governance/proposals/voting_proposals.rs | 11 ++--- .../governance/voting_procedures.rs | 13 +++--- .../serialization/plutus/plutus_scripts.rs | 1 + .../serialization/witnesses/vkeywitnesses.rs | 7 +-- rust/src/tests/builders/tx_builder.rs | 2 +- .../tests/builders/voting_proposal_builder.rs | 22 ++++----- rust/src/tests/general.rs | 10 +++-- rust/src/tests/protocol_types/certificates.rs | 28 ++++++++++++ .../protocol_types/governance/proposals.rs | 30 +++++++++++++ rust/src/utils.rs | 4 +- 17 files changed, 175 insertions(+), 62 deletions(-) diff --git a/rust/src/builders/certificates_builder.rs b/rust/src/builders/certificates_builder.rs index 1e036511..9dd3b44e 100644 --- a/rust/src/builders/certificates_builder.rs +++ b/rust/src/builders/certificates_builder.rs @@ -216,7 +216,7 @@ impl CertificatesBuilder { pub fn build(&self) -> Certificates { let certs = self.certs.iter().map(|(c, _)| c.clone()).collect(); - Certificates(certs) + Certificates::from_vec(certs) } //return only ref inputs that are script refs with added size diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index f730d1c7..bb4611fa 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -1124,7 +1124,7 @@ impl TransactionBuilder { )] pub fn set_certs(&mut self, certs: &Certificates) -> Result<(), JsError> { let mut builder = CertificatesBuilder::new(); - for cert in &certs.0 { + for cert in &certs.certs { builder.add(cert)?; } diff --git a/rust/src/builders/voting_proposal_builder.rs b/rust/src/builders/voting_proposal_builder.rs index 70a91ed5..9a56f4ae 100644 --- a/rust/src/builders/voting_proposal_builder.rs +++ b/rust/src/builders/voting_proposal_builder.rs @@ -112,6 +112,6 @@ impl VotingProposalBuilder { for (voter, _) in &self.proposals { proposals.push(voter.clone()); } - VotingProposals(proposals) + VotingProposals::from_vec(proposals) } } diff --git a/rust/src/protocol_types/certificates/certificates_collection.rs b/rust/src/protocol_types/certificates/certificates_collection.rs index d02c4b19..2e8a3397 100644 --- a/rust/src/protocol_types/certificates/certificates_collection.rs +++ b/rust/src/protocol_types/certificates/certificates_collection.rs @@ -4,31 +4,59 @@ use crate::*; #[derive( Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, )] -pub struct Certificates(pub(crate) Vec); +pub struct Certificates { + pub(crate) certs: Vec, + pub(crate) dedup: BTreeSet +} impl_to_from!(Certificates); impl NoneOrEmpty for Certificates { fn is_none_or_empty(&self) -> bool { - self.0.is_empty() + self.certs.is_empty() } } #[wasm_bindgen] impl Certificates { pub fn new() -> Self { - Self(Vec::new()) + Self { + certs: Vec::new(), + dedup: BTreeSet::new(), + } } pub fn len(&self) -> usize { - self.0.len() + self.certs.len() } pub fn get(&self, index: usize) -> Certificate { - self.0[index].clone() + self.certs[index].clone() + } + + /// Add a new `Certificate` to the set. + /// Returns `true` if the element was not already present in the set. + pub fn add(&mut self, elem: &Certificate) -> bool { + if self.dedup.insert(elem.clone()) { + self.certs.push(elem.clone()); + true + } else { + false + } } - pub fn add(&mut self, elem: &Certificate) { - self.0.push(elem.clone()); + pub(crate) fn add_move(&mut self, elem: Certificate) { + if self.dedup.insert(elem.clone()) { + self.certs.push(elem); + } + } + + + pub(crate) fn from_vec(certs_vec: Vec) -> Self { + let mut certs = Self::new(); + for cert in certs_vec { + certs.add_move(cert); + } + certs } } diff --git a/rust/src/protocol_types/governance/proposals/voting_proposals.rs b/rust/src/protocol_types/governance/proposals/voting_proposals.rs index 1b94ccb6..8e20bb8c 100644 --- a/rust/src/protocol_types/governance/proposals/voting_proposals.rs +++ b/rust/src/protocol_types/governance/proposals/voting_proposals.rs @@ -13,31 +13,62 @@ use crate::*; JsonSchema, )] #[wasm_bindgen] -pub struct VotingProposals(pub(crate) Vec); +pub struct VotingProposals { + pub(crate) proposals: Vec, + pub(crate) dedup: BTreeSet, +} impl_to_from!(VotingProposals); impl NoneOrEmpty for VotingProposals { fn is_none_or_empty(&self) -> bool { - self.0.is_empty() + self.proposals.is_empty() } } #[wasm_bindgen] impl VotingProposals { pub fn new() -> Self { - Self(Vec::new()) + Self { + proposals: Vec::new(), + dedup: BTreeSet::new(), + } } pub fn len(&self) -> usize { - self.0.len() + self.proposals.len() } pub fn get(&self, index: usize) -> VotingProposal { - self.0[index].clone() + self.proposals[index].clone() + } + + /// Add a proposal to the set of proposals + /// Returns true if the proposal was added, false if it was already present + pub fn add(&mut self, proposal: &VotingProposal) -> bool { + if self.dedup.insert(proposal.clone()) { + self.proposals.push(proposal.clone()); + true + } else { + false + } + } + + pub(crate) fn add_move(&mut self, proposal: VotingProposal) { + if self.dedup.insert(proposal.clone()) { + self.proposals.push(proposal); + } + } + + pub(crate) fn from_vec(proposals: Vec) -> Self { + let mut voting_proposals = VotingProposals::new(); + for proposal in proposals { + voting_proposals.add_move(proposal); + } + voting_proposals } - pub fn add(&mut self, proposal: &VotingProposal) { - self.0.push(proposal.clone()); + pub(crate) fn contains(&self, proposal: &VotingProposal) -> bool { + self.dedup.contains(proposal) } } diff --git a/rust/src/serialization/certificates/certificates_collection.rs b/rust/src/serialization/certificates/certificates_collection.rs index e89ce1f7..06b12c7e 100644 --- a/rust/src/serialization/certificates/certificates_collection.rs +++ b/rust/src/serialization/certificates/certificates_collection.rs @@ -6,14 +6,10 @@ impl Serialize for Certificates { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - if self.0.is_empty() { - return Ok(serializer); - } //TODO: uncomment this line when we conway ero will come //serializer.write_tag(258)?; - let ordered_dedup = self.0.iter().collect::>(); - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in ordered_dedup { + serializer.write_array(Len::Len(self.len() as u64))?; + for element in &self.certs { element.serialize(serializer)?; } Ok(serializer) @@ -38,6 +34,6 @@ impl Deserialize for Certificates { Ok(()) })() .map_err(|e| e.annotate("Certificates"))?; - Ok(Self(arr)) + Ok(Self::from_vec(arr)) } } diff --git a/rust/src/serialization/ed25519_key_hashes.rs b/rust/src/serialization/ed25519_key_hashes.rs index aeafe3ba..46d6a73e 100644 --- a/rust/src/serialization/ed25519_key_hashes.rs +++ b/rust/src/serialization/ed25519_key_hashes.rs @@ -20,18 +20,18 @@ impl Deserialize for Ed25519KeyHashes { fn deserialize(raw: &mut Deserializer) -> Result { skip_set_tag(raw)?; let mut creds = Ed25519KeyHashes::new(); - let mut counter = 0u64; + let mut total = 0u64; (|| -> Result<_, DeserializeError> { let len = raw.array()?; while match len { - cbor_event::Len::Len(n) => counter < n, + cbor_event::Len::Len(n) => total < n, cbor_event::Len::Indefinite => true, } { if is_break_tag(raw, "Ed25519KeyHashes")? { break; } creds.add_move(Ed25519KeyHash::deserialize(raw)?); - counter += 1; + total += 1; } Ok(()) })() diff --git a/rust/src/serialization/governance/proposals/voting_proposals.rs b/rust/src/serialization/governance/proposals/voting_proposals.rs index 189ea116..64ee941a 100644 --- a/rust/src/serialization/governance/proposals/voting_proposals.rs +++ b/rust/src/serialization/governance/proposals/voting_proposals.rs @@ -6,14 +6,10 @@ impl cbor_event::se::Serialize for VotingProposals { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - if self.0.is_empty() { - return Ok(serializer); - } //TODO: uncomment this line when we conway ero will come //serializer.write_tag(258)?; - let ordered_dedup = self.0.iter().collect::>(); - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in ordered_dedup { + serializer.write_array(cbor_event::Len::Len(self.len() as u64))?; + for element in &self.proposals { element.serialize(serializer)?; } Ok(serializer) @@ -22,6 +18,7 @@ impl cbor_event::se::Serialize for VotingProposals { impl Deserialize for VotingProposals { fn deserialize(raw: &mut Deserializer) -> Result { + skip_set_tag(raw)?; let mut arr = Vec::new(); (|| -> Result<_, DeserializeError> { skip_set_tag(raw)?; @@ -38,6 +35,6 @@ impl Deserialize for VotingProposals { Ok(()) })() .map_err(|e| e.annotate("VotingProposals"))?; - Ok(Self(arr)) + Ok(Self::from_vec(arr)) } } diff --git a/rust/src/serialization/governance/voting_procedures.rs b/rust/src/serialization/governance/voting_procedures.rs index df3376eb..25f10aab 100644 --- a/rust/src/serialization/governance/voting_procedures.rs +++ b/rust/src/serialization/governance/voting_procedures.rs @@ -7,12 +7,7 @@ impl cbor_event::se::Serialize for VotingProcedures { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - if self.is_none_or_empty() { - return Ok(serializer) - } - serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?; - for (voter, votes) in &self.0 { if votes.is_empty() { continue; @@ -33,8 +28,9 @@ impl Deserialize for VotingProcedures { let mut voter_to_vote = BTreeMap::new(); (|| -> Result<_, DeserializeError> { let len = raw.map()?; + let mut total = 0; while match len { - cbor_event::Len::Len(n) => voter_to_vote.len() < n as usize, + cbor_event::Len::Len(n) => total < n, cbor_event::Len::Indefinite => true, } { if is_break_tag(raw, "voting_procedure map")? { @@ -52,6 +48,7 @@ impl Deserialize for VotingProcedures { ))) .into()); } + total += 1; } Ok(Self(voter_to_vote)) })() @@ -65,8 +62,9 @@ fn deserialize_internal_map( let mut gov_act_id_to_vote = BTreeMap::new(); (|| -> Result<_, DeserializeError> { let len = raw.map()?; + let mut total = 0; while match len { - cbor_event::Len::Len(n) => gov_act_id_to_vote.len() < n as usize, + cbor_event::Len::Len(n) => total < n, cbor_event::Len::Indefinite => true, } { if is_break_tag(raw, "gov_act_id_to_vote map")? { @@ -84,6 +82,7 @@ fn deserialize_internal_map( ))) .into()); } + total += 1; } Ok(gov_act_id_to_vote) })() diff --git a/rust/src/serialization/plutus/plutus_scripts.rs b/rust/src/serialization/plutus/plutus_scripts.rs index 1f86957f..37f30906 100644 --- a/rust/src/serialization/plutus/plutus_scripts.rs +++ b/rust/src/serialization/plutus/plutus_scripts.rs @@ -51,6 +51,7 @@ impl PlutusScripts { impl Deserialize for PlutusScripts { fn deserialize(raw: &mut Deserializer) -> Result { + skip_set_tag(raw)?; let mut arr = Vec::new(); (|| -> Result<_, DeserializeError> { skip_set_tag(raw)?; diff --git a/rust/src/serialization/witnesses/vkeywitnesses.rs b/rust/src/serialization/witnesses/vkeywitnesses.rs index ca76dd29..f3190569 100644 --- a/rust/src/serialization/witnesses/vkeywitnesses.rs +++ b/rust/src/serialization/witnesses/vkeywitnesses.rs @@ -22,13 +22,14 @@ impl cbor_event::se::Serialize for Vkeywitnesses { impl Deserialize for Vkeywitnesses { fn deserialize(raw: &mut Deserializer) -> Result { + skip_set_tag(raw)?; let mut wits = Vkeywitnesses::new(); - let mut counter = 0u64; + let mut total = 0u64; (|| -> Result<_, DeserializeError> { skip_set_tag(raw)?; let len = raw.array()?; while match len { - cbor_event::Len::Len(n) => counter < n, + cbor_event::Len::Len(n) => total < n, cbor_event::Len::Indefinite => true, } { if raw.cbor_type()? == cbor_event::Type::Special { @@ -36,7 +37,7 @@ impl Deserialize for Vkeywitnesses { break; } wits.add_move(Vkeywitness::deserialize(raw)?); - counter += 1; + total += 1; } Ok(()) })() diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index 096683e5..026f1eff 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -5727,7 +5727,7 @@ fn build_tx_with_certs_withdrawals_plutus_script_address() { assert_eq!(final_tx_wits.plutus_scripts().unwrap().len(), 3); assert_eq!(final_tx_wits.redeemers().unwrap().len(), 5); - let certs = final_tx_body.certs().unwrap().0; + let certs = final_tx_body.certs().unwrap().certs; let withdraws = final_tx_body .withdrawals() .unwrap() diff --git a/rust/src/tests/builders/voting_proposal_builder.rs b/rust/src/tests/builders/voting_proposal_builder.rs index a6d88eb1..0ed09867 100644 --- a/rust/src/tests/builders/voting_proposal_builder.rs +++ b/rust/src/tests/builders/voting_proposal_builder.rs @@ -175,13 +175,13 @@ fn voting_proposal_builder_all_proposals() { let voting_proposals = tx.body().voting_proposals().unwrap(); assert_eq!(voting_proposals.len(), 7); - assert!(voting_proposals.0.contains(&hf_proposal)); - assert!(voting_proposals.0.contains(&committee_proposal)); - assert!(voting_proposals.0.contains(&constitution_proposal)); - assert!(voting_proposals.0.contains(&no_conf_proposal)); - assert!(voting_proposals.0.contains(&pp_update_proposal)); - assert!(voting_proposals.0.contains(&withdrawal_proposal)); - assert!(voting_proposals.0.contains(&info_proposal)); + assert!(voting_proposals.contains(&hf_proposal)); + assert!(voting_proposals.contains(&committee_proposal)); + assert!(voting_proposals.contains(&constitution_proposal)); + assert!(voting_proposals.contains(&no_conf_proposal)); + assert!(voting_proposals.contains(&pp_update_proposal)); + assert!(voting_proposals.contains(&withdrawal_proposal)); + assert!(voting_proposals.contains(&info_proposal)); let mut total_out = total_tx_output_with_fee(&tx); total_out = total_out.checked_add(&total_deposit).unwrap(); @@ -266,8 +266,8 @@ fn voting_proposal_builder_with_plutus_script_witness() { let voting_proposals = tx.body().voting_proposals().unwrap(); assert_eq!(voting_proposals.len(), 2); - assert!(voting_proposals.0.contains(&hf_proposal)); - assert!(voting_proposals.0.contains(&committee_proposal)); + assert!(voting_proposals.contains(&hf_proposal)); + assert!(voting_proposals.contains(&committee_proposal)); let mut total_out = total_tx_output_with_fee(&tx); total_out = total_out.checked_add(&total_deposit).unwrap(); @@ -374,8 +374,8 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { let voting_proposals = tx.body().voting_proposals().unwrap(); assert_eq!(voting_proposals.len(), 2); - assert!(voting_proposals.0.contains(&hf_proposal)); - assert!(voting_proposals.0.contains(&committee_proposal)); + assert!(voting_proposals.contains(&hf_proposal)); + assert!(voting_proposals.contains(&committee_proposal)); let mut total_out = total_tx_output_with_fee(&tx); total_out = total_out.checked_add(&total_deposit).unwrap(); diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index df98ab80..bef8b5a6 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -601,7 +601,7 @@ fn plutus_scripts_no_dedup_on_auxdata() { } #[test] -pub fn native_scripts_dedup_on_tx_witnesses_set() { +fn native_scripts_dedup_on_tx_witnesses_set() { let keyhash1 = keyhash(1); let native_scripts_1 = NativeScript::new_script_pubkey(&ScriptPubkey::new( @@ -638,7 +638,7 @@ pub fn native_scripts_dedup_on_tx_witnesses_set() { } #[test] -pub fn native_scripts_no_dedup_on_auxdata() { +fn native_scripts_no_dedup_on_auxdata() { let keyhash1 = keyhash(1); let native_scripts_1 = NativeScript::new_script_pubkey(&ScriptPubkey::new( @@ -674,7 +674,8 @@ pub fn native_scripts_no_dedup_on_auxdata() { assert!(native_scripts_from_bytes.contains(&native_scripts_2)); } -#[test] fn plutus_data_dedup_on_tx_witnesses_set() { +#[test] +fn plutus_data_dedup_on_tx_witnesses_set() { let datum_1 = PlutusData::new_integer(&BigInt::from(1)); let datum_2 = PlutusData::new_integer(&BigInt::from(2)); @@ -700,7 +701,8 @@ pub fn native_scripts_no_dedup_on_auxdata() { assert!(datums_from_bytes.contains(&datum_2)); } -#[test] fn plutus_data_no_dedup_serialization() { +#[test] +fn plutus_data_no_dedup_serialization() { let datum_1 = PlutusData::new_integer(&BigInt::from(1)); let datum_2 = PlutusData::new_integer(&BigInt::from(2)); diff --git a/rust/src/tests/protocol_types/certificates.rs b/rust/src/tests/protocol_types/certificates.rs index 27b5a088..567199c7 100644 --- a/rust/src/tests/protocol_types/certificates.rs +++ b/rust/src/tests/protocol_types/certificates.rs @@ -282,3 +282,31 @@ fn vote_registration_and_delegation_setters_getters_test() { false ); } + +#[test] +fn certificates_deduplication_test() { + let mut certs = Certificates::new(); + let cert1 = Certificate::new_stake_registration(&StakeRegistration::new( + &Credential::from_keyhash(&fake_key_hash(1)), + )); + let cert2 = Certificate::new_stake_registration(&StakeRegistration::new( + &Credential::from_keyhash(&fake_key_hash(2)), + )); + let cert3 = Certificate::new_stake_registration(&StakeRegistration::new( + &Credential::from_keyhash(&fake_key_hash(1)), + )); + + assert_eq!(certs.len(), 0); + assert!(certs.add(&cert1)); + assert_eq!(certs.len(), 1); + assert!(certs.add(&cert2)); + assert_eq!(certs.len(), 2); + assert!(!certs.add(&cert3)); + assert_eq!(certs.len(), 2); + assert_eq!(certs.get(0), cert1); + assert_eq!(certs.get(1), cert2); + + let bytes = certs.to_bytes(); + let certs2 = Certificates::from_bytes(bytes).unwrap(); + assert_eq!(certs, certs2); +} diff --git a/rust/src/tests/protocol_types/governance/proposals.rs b/rust/src/tests/protocol_types/governance/proposals.rs index 5bc2ebee..1f05bb29 100644 --- a/rust/src/tests/protocol_types/governance/proposals.rs +++ b/rust/src/tests/protocol_types/governance/proposals.rs @@ -171,3 +171,33 @@ fn voting_proposals_setters_getters_test() { assert_eq!(proposals.get(0), proposal1); assert_eq!(proposals.get(1), proposal2); } + +#[test] +fn voting_proposals_deduplication_test() { + let mut proposals = VotingProposals::new(); + let no_confidence_action = NoConfidenceAction::new(); + let parameter_change_action = ParameterChangeAction::new(&crate_full_protocol_param_update()); + + let proposal1 = VotingProposal::new( + &GovernanceAction::new_no_confidence_action(&no_confidence_action), + &create_anchor(), + &fake_reward_address(1), + &Coin::from(100u32), + ); + let proposal2 = VotingProposal::new( + &GovernanceAction::new_parameter_change_action(¶meter_change_action), + &create_anchor(), + &fake_reward_address(2), + &Coin::from(100u32), + ); + proposals.add(&proposal1); + proposals.add(&proposal2); + proposals.add(&proposal1); + assert_eq!(proposals.len(), 2); + assert_eq!(proposals.get(0), proposal1); + assert_eq!(proposals.get(1), proposal2); + + let bytes = proposals.to_bytes(); + let proposals_decoded = VotingProposals::from_bytes(bytes).unwrap(); + assert_eq!(proposals, proposals_decoded); +} \ No newline at end of file diff --git a/rust/src/utils.rs b/rust/src/utils.rs index ac90c016..f94aba77 100644 --- a/rust/src/utils.rs +++ b/rust/src/utils.rs @@ -644,7 +644,7 @@ pub fn internal_get_implicit_input( let certificate_refund = match &certs { None => BigNum::zero(), Some(certs) => certs - .0 + .certs .iter() .try_fold(BigNum::zero(), |acc, ref cert| match &cert.0 { CertificateEnum::StakeDeregistration(cert) => { @@ -673,7 +673,7 @@ pub fn internal_get_deposit( let certificate_deposit = match &certs { None => BigNum::zero(), Some(certs) => certs - .0 + .certs .iter() .try_fold(BigNum::zero(), |acc, ref cert| match &cert.0 { CertificateEnum::PoolRegistration(_) => acc.checked_add(&pool_deposit), From 988feed50d65370d6aa0e558a4b47720aed2f106 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 23 Jun 2024 00:47:24 +0700 Subject: [PATCH 298/349] tx inputs as set --- rust/src/builders/batch_tools/proposals.rs | 2 +- rust/src/builders/certificates_builder.rs | 2 +- rust/src/builders/tx_builder.rs | 16 +-- rust/src/builders/tx_inputs_builder.rs | 4 +- rust/src/builders/voting_builder.rs | 2 +- rust/src/builders/voting_proposal_builder.rs | 2 +- rust/src/builders/withdrawals_builder.rs | 2 +- rust/src/lib.rs | 46 -------- rust/src/protocol_types/mod.rs | 4 + rust/src/protocol_types/tx_input.rs | 46 ++++++++ rust/src/protocol_types/tx_inputs.rs | 103 +++++++++++++----- rust/src/serialization/mod.rs | 3 +- rust/src/serialization/tx_input.rs | 56 ++++++++++ rust/src/serialization/tx_inputs.rs | 61 +---------- rust/src/tests/builders/tx_builder.rs | 2 +- rust/src/tests/general.rs | 24 +++- rust/src/tests/serialization/general.rs | 2 +- .../tests/serialization/transaction_body.rs | 2 +- 18 files changed, 228 insertions(+), 151 deletions(-) create mode 100644 rust/src/protocol_types/tx_input.rs create mode 100644 rust/src/serialization/tx_input.rs diff --git a/rust/src/builders/batch_tools/proposals.rs b/rust/src/builders/batch_tools/proposals.rs index 3b1dd4d3..4a16ebbb 100644 --- a/rust/src/builders/batch_tools/proposals.rs +++ b/rust/src/builders/batch_tools/proposals.rs @@ -204,7 +204,7 @@ impl TxProposal { } let body = TransactionBody::new( - &TransactionInputs(inputs), + &TransactionInputs::from_vec(inputs), &TransactionOutputs(outputs), &self.fee, None, diff --git a/rust/src/builders/certificates_builder.rs b/rust/src/builders/certificates_builder.rs index 9dd3b44e..2fb02818 100644 --- a/rust/src/builders/certificates_builder.rs +++ b/rust/src/builders/certificates_builder.rs @@ -118,7 +118,7 @@ impl CertificatesBuilder { None => {} } } - TransactionInputs(inputs) + TransactionInputs::from_vec(inputs) } pub fn get_native_scripts(&self) -> NativeScripts { diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index bb4611fa..fb5978b6 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -903,7 +903,7 @@ impl TransactionBuilder { if self .inputs .inputs() - .0 + .inputs .iter() .all(|used_input| input.input() != *used_input) { @@ -1487,42 +1487,42 @@ impl TransactionBuilder { pub fn get_reference_inputs(&self) -> TransactionInputs { let mut inputs: HashSet = self.reference_inputs.keys().cloned().collect(); - for input in self.inputs.get_ref_inputs().0 { + for input in self.inputs.get_ref_inputs() { inputs.insert(input); } if let Some(mint) = &self.mint { - for input in mint.get_ref_inputs().0 { + for input in mint.get_ref_inputs() { inputs.insert(input); } } if let Some(withdrawals) = &self.withdrawals { - for input in withdrawals.get_ref_inputs().0 { + for input in withdrawals.get_ref_inputs() { inputs.insert(input); } } if let Some(certs) = &self.certs { - for input in certs.get_ref_inputs().0 { + for input in certs.get_ref_inputs() { inputs.insert(input); } } if let Some(voting_procedures) = &self.voting_procedures { - for input in voting_procedures.get_ref_inputs().0 { + for input in voting_procedures.get_ref_inputs() { inputs.insert(input); } } if let Some(voting_proposals) = &self.voting_proposals { - for input in voting_proposals.get_ref_inputs().0 { + for input in voting_proposals.get_ref_inputs() { inputs.insert(input); } } let vec_inputs = inputs.into_iter().collect(); - TransactionInputs(vec_inputs) + TransactionInputs::from_vec(vec_inputs) } fn get_total_ref_scripts_size(&self) -> Result { diff --git a/rust/src/builders/tx_inputs_builder.rs b/rust/src/builders/tx_inputs_builder.rs index 8c7d7127..3367966a 100644 --- a/rust/src/builders/tx_inputs_builder.rs +++ b/rust/src/builders/tx_inputs_builder.rs @@ -188,7 +188,7 @@ impl TxInputsBuilder { _ => (), } } - TransactionInputs(inputs) + TransactionInputs::from_vec(inputs) } @@ -303,7 +303,7 @@ impl TxInputsBuilder { } pub fn inputs(&self) -> TransactionInputs { - TransactionInputs( + TransactionInputs::from_vec( self.inputs .values() .map(|(ref tx_builder_input, _)| tx_builder_input.input.clone()) diff --git a/rust/src/builders/voting_builder.rs b/rust/src/builders/voting_builder.rs index 84de3bcf..b57aeb6d 100644 --- a/rust/src/builders/voting_builder.rs +++ b/rust/src/builders/voting_builder.rs @@ -146,7 +146,7 @@ impl VotingBuilder { None => {} } } - TransactionInputs(inputs) + TransactionInputs::from_vec(inputs) } pub fn get_native_scripts(&self) -> NativeScripts { diff --git a/rust/src/builders/voting_proposal_builder.rs b/rust/src/builders/voting_proposal_builder.rs index 9a56f4ae..d8434b99 100644 --- a/rust/src/builders/voting_proposal_builder.rs +++ b/rust/src/builders/voting_proposal_builder.rs @@ -62,7 +62,7 @@ impl VotingProposalBuilder { None => {} } } - TransactionInputs(inputs) + TransactionInputs::from_vec(inputs) } pub(crate) fn get_total_deposit(&self) -> Result { diff --git a/rust/src/builders/withdrawals_builder.rs b/rust/src/builders/withdrawals_builder.rs index d3e9ea61..809468b5 100644 --- a/rust/src/builders/withdrawals_builder.rs +++ b/rust/src/builders/withdrawals_builder.rs @@ -121,7 +121,7 @@ impl WithdrawalsBuilder { None => {} } } - TransactionInputs(inputs) + TransactionInputs::from_vec(inputs) } pub fn get_native_scripts(&self) -> NativeScripts { diff --git a/rust/src/lib.rs b/rust/src/lib.rs index e5b4406e..38862e84 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -175,52 +175,6 @@ type TransactionIndex = u32; type CertificateIndex = u32; type GovernanceActionIndex = u32; -#[wasm_bindgen] -#[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, -)] -pub struct TransactionInputs(pub(crate) Vec); - -impl_to_from!(TransactionInputs); - -impl NoneOrEmpty for TransactionInputs { - fn is_none_or_empty(&self) -> bool { - self.0.is_empty() - } -} - -#[wasm_bindgen] -impl TransactionInputs { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> TransactionInput { - self.0[index].clone() - } - - pub fn add(&mut self, elem: &TransactionInput) { - self.0.push(elem.clone()); - } - - #[allow(dead_code)] - pub(crate) fn contains(&self, elem: &TransactionInput) -> bool { - self.0.contains(elem) - } - - pub fn to_option(&self) -> Option { - if self.len() > 0 { - Some(self.clone()) - } else { - None - } - } -} - #[wasm_bindgen] #[derive(Clone, Eq, PartialEq, Debug, serde::Serialize, serde::Deserialize, JsonSchema)] pub struct TransactionOutputs(Vec); diff --git a/rust/src/protocol_types/mod.rs b/rust/src/protocol_types/mod.rs index 6e98aec1..d0cb0d34 100644 --- a/rust/src/protocol_types/mod.rs +++ b/rust/src/protocol_types/mod.rs @@ -22,6 +22,10 @@ pub use protocol_param_update::*; mod address; pub use address::*; + +mod tx_input; +pub use tx_input::*; + mod tx_inputs; pub use tx_inputs::*; diff --git a/rust/src/protocol_types/tx_input.rs b/rust/src/protocol_types/tx_input.rs new file mode 100644 index 00000000..f48824e8 --- /dev/null +++ b/rust/src/protocol_types/tx_input.rs @@ -0,0 +1,46 @@ +use std::fmt::Formatter; +use crate::*; + +#[wasm_bindgen] +#[derive( + Clone, + Debug, + Eq, + Ord, + PartialEq, + PartialOrd, + Hash, + serde::Serialize, + serde::Deserialize, + JsonSchema, +)] +pub struct TransactionInput { + pub(crate) transaction_id: TransactionHash, + pub(crate) index: TransactionIndex, +} + +impl_to_from!(TransactionInput); + +#[wasm_bindgen] +impl TransactionInput { + pub fn transaction_id(&self) -> TransactionHash { + self.transaction_id.clone() + } + + pub fn index(&self) -> TransactionIndex { + self.index.clone() + } + + pub fn new(transaction_id: &TransactionHash, index: TransactionIndex) -> Self { + Self { + transaction_id: transaction_id.clone(), + index: index, + } + } +} + +impl Display for TransactionInput { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "{}#{}", self.transaction_id, self.index) + } +} diff --git a/rust/src/protocol_types/tx_inputs.rs b/rust/src/protocol_types/tx_inputs.rs index f48824e8..7ce9de0f 100644 --- a/rust/src/protocol_types/tx_inputs.rs +++ b/rust/src/protocol_types/tx_inputs.rs @@ -1,46 +1,95 @@ -use std::fmt::Formatter; use crate::*; +use std::slice::Iter; +use std::vec::IntoIter; #[wasm_bindgen] #[derive( - Clone, - Debug, - Eq, - Ord, - PartialEq, - PartialOrd, - Hash, - serde::Serialize, - serde::Deserialize, - JsonSchema, + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, )] -pub struct TransactionInput { - pub(crate) transaction_id: TransactionHash, - pub(crate) index: TransactionIndex, +pub struct TransactionInputs { + pub(crate) inputs: Vec, + pub(crate) dedup: BTreeSet, } -impl_to_from!(TransactionInput); +impl_to_from!(TransactionInputs); + +impl NoneOrEmpty for TransactionInputs { + fn is_none_or_empty(&self) -> bool { + self.inputs.is_empty() + } +} #[wasm_bindgen] -impl TransactionInput { - pub fn transaction_id(&self) -> TransactionHash { - self.transaction_id.clone() +impl TransactionInputs { + pub fn new() -> Self { + Self { + inputs: Vec::new(), + dedup: BTreeSet::new(), + } } - pub fn index(&self) -> TransactionIndex { - self.index.clone() + pub fn len(&self) -> usize { + self.inputs.len() } - pub fn new(transaction_id: &TransactionHash, index: TransactionIndex) -> Self { - Self { - transaction_id: transaction_id.clone(), - index: index, + pub fn get(&self, index: usize) -> TransactionInput { + self.inputs[index].clone() + } + + /// Add a new `TransactionInput` to the set. + /// Returns `true` if the element was not already present in the set. + /// Note that the `TransactionInput` is added to the set only if it is not already present. + pub fn add(&mut self, elem: &TransactionInput) -> bool { + if self.dedup.insert(elem.clone()) { + self.inputs.push(elem.clone()); + true + } else { + false + } + } + + #[allow(dead_code)] + pub(crate) fn contains(&self, elem: &TransactionInput) -> bool { + self.dedup.contains(elem) + } + + pub(crate) fn add_move(&mut self, elem: TransactionInput) { + if self.dedup.insert(elem.clone()) { + self.inputs.push(elem); + } + } + + pub(crate) fn from_vec(inputs_vec: Vec) -> Self { + let mut inputs = Self::new(); + for input in inputs_vec { + inputs.add_move(input); + } + inputs + } + + pub fn to_option(&self) -> Option { + if self.len() > 0 { + Some(self.clone()) + } else { + None } } } -impl Display for TransactionInput { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "{}#{}", self.transaction_id, self.index) +impl<'a> IntoIterator for &'a TransactionInputs { + type Item = &'a TransactionInput; + type IntoIter = Iter<'a, TransactionInput>; + + fn into_iter(self) -> Self::IntoIter { + self.inputs.iter() } } + +impl IntoIterator for TransactionInputs { + type Item = TransactionInput; + type IntoIter = IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.inputs.into_iter() + } +} \ No newline at end of file diff --git a/rust/src/serialization/mod.rs b/rust/src/serialization/mod.rs index fa98180b..15a000f1 100644 --- a/rust/src/serialization/mod.rs +++ b/rust/src/serialization/mod.rs @@ -26,4 +26,5 @@ mod native_script; mod native_scripts; mod numeric; mod versioned_block; -mod script_ref; \ No newline at end of file +mod script_ref; +mod tx_input; \ No newline at end of file diff --git a/rust/src/serialization/tx_input.rs b/rust/src/serialization/tx_input.rs new file mode 100644 index 00000000..f8118acc --- /dev/null +++ b/rust/src/serialization/tx_input.rs @@ -0,0 +1,56 @@ +use crate::*; + +impl cbor_event::se::Serialize for TransactionInput { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.transaction_id.serialize(serializer)?; + self.index.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for TransactionInput { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let ret = Self::deserialize_as_embedded_group(raw, len); + match len { + cbor_event::Len::Len(_) => + /* TODO: check finite len somewhere */ + { + () + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("TransactionInput")) + } +} + +impl DeserializeEmbeddedGroup for TransactionInput { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + _: cbor_event::Len, + ) -> Result { + let transaction_id = + (|| -> Result<_, DeserializeError> { Ok(TransactionHash::deserialize(raw)?) })() + .map_err(|e| e.annotate("transaction_id"))?; + let index = (|| -> Result<_, DeserializeError> { Ok(u32::deserialize(raw)?) })() + .map_err(|e| e.annotate("index"))?; + Ok(TransactionInput { + transaction_id, + index, + }) + } +} \ No newline at end of file diff --git a/rust/src/serialization/tx_inputs.rs b/rust/src/serialization/tx_inputs.rs index 84883e7a..7fcc683d 100644 --- a/rust/src/serialization/tx_inputs.rs +++ b/rust/src/serialization/tx_inputs.rs @@ -8,8 +8,8 @@ impl cbor_event::se::Serialize for TransactionInputs { ) -> cbor_event::Result<&'se mut Serializer> { //TODO: uncomment this line when we conway ero will come //serializer.write_tag(258)?; - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { + serializer.write_array(cbor_event::Len::Len(self.len() as u64))?; + for element in &self.inputs { element.serialize(serializer)?; } Ok(serializer) @@ -34,61 +34,6 @@ impl Deserialize for TransactionInputs { Ok(()) })() .map_err(|e| e.annotate("TransactionInputs"))?; - Ok(Self(arr)) - } -} - -impl cbor_event::se::Serialize for TransactionInput { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - self.transaction_id.serialize(serializer)?; - self.index.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for TransactionInput { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("TransactionInput")) - } -} - -impl DeserializeEmbeddedGroup for TransactionInput { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - _: cbor_event::Len, - ) -> Result { - let transaction_id = - (|| -> Result<_, DeserializeError> { Ok(TransactionHash::deserialize(raw)?) })() - .map_err(|e| e.annotate("transaction_id"))?; - let index = (|| -> Result<_, DeserializeError> { Ok(u32::deserialize(raw)?) })() - .map_err(|e| e.annotate("index"))?; - Ok(TransactionInput { - transaction_id, - index, - }) + Ok(Self::from_vec(arr)) } } \ No newline at end of file diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index 026f1eff..b54d92df 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -2423,7 +2423,7 @@ fn tx_builder_cip2_random_improve() { } let mut encountered = std::collections::HashSet::new(); let mut input_total = Value::new(&Coin::zero()); - for input in tx.inputs.0.iter() { + for input in &tx.inputs { let txid = input.transaction_id(); if !encountered.insert(txid.clone()) { panic!("Input {:?} duplicated", txid); diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index bef8b5a6..cb59310d 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -1,5 +1,5 @@ use crate::*; -use crate::fakes::{fake_boostrap_witness, fake_vkey_witness}; +use crate::fakes::{fake_boostrap_witness, fake_tx_input, fake_vkey_witness}; use crate::tests::helpers::harden; use crate::tests::mock_objects::create_plutus_script; @@ -717,4 +717,26 @@ fn plutus_data_no_dedup_serialization() { assert_eq!(datum_from_bytes.len(), 3); assert!(datum_from_bytes.contains(&datum_1)); assert!(datum_from_bytes.contains(&datum_2)); +} + +#[test] +fn tx_inputs_deduplication() { + let tx_in1 = fake_tx_input(1); + let tx_in2 = fake_tx_input(2); + let tx_in3 = fake_tx_input(3); + + let mut txins = TransactionInputs::new(); + assert!(txins.add(&tx_in1)); + assert!(txins.add(&tx_in2)); + assert!(txins.add(&tx_in3)); + assert!(!txins.add(&tx_in1)); + + assert_eq!(txins.len(), 3); + + let txins_bytes = txins.to_bytes(); + let txins_from_bytes = TransactionInputs::from_bytes(txins_bytes).unwrap(); + assert_eq!(txins_from_bytes.len(), 3); + assert!(txins_from_bytes.contains(&tx_in1)); + assert!(txins_from_bytes.contains(&tx_in2)); + assert!(txins_from_bytes.contains(&tx_in3)); } \ No newline at end of file diff --git a/rust/src/tests/serialization/general.rs b/rust/src/tests/serialization/general.rs index 32e6b2c6..d7e72998 100644 --- a/rust/src/tests/serialization/general.rs +++ b/rust/src/tests/serialization/general.rs @@ -446,7 +446,7 @@ fn alonzo_block() { #[test] fn test_tx_body_roundtrip() { let mut txb = TransactionBody::new( - &TransactionInputs(vec![fake_tx_input(0)]), + &TransactionInputs::from_vec(vec![fake_tx_input(0)]), &TransactionOutputs(vec![fake_tx_output(1)]), &BigNum(1234567), Some(12345678), diff --git a/rust/src/tests/serialization/transaction_body.rs b/rust/src/tests/serialization/transaction_body.rs index 466e7fcb..eb184845 100644 --- a/rust/src/tests/serialization/transaction_body.rs +++ b/rust/src/tests/serialization/transaction_body.rs @@ -6,7 +6,7 @@ use crate::tests::mock_objects::create_anchor; fn transaction_round_trip_test() { let input = fake_tx_input(1); let output = TransactionOutput::new(&fake_base_address(2), &Value::new(&BigNum(1_000_001))); - let inputs = TransactionInputs(vec![input]); + let inputs = TransactionInputs::from_vec(vec![input]); let outputs = TransactionOutputs(vec![output]); let fee = Coin::from(1_000_002u64); let mut body = TransactionBody::new_tx_body(&inputs, &outputs, &fee); From 90cefe53c3bc0680fff94cffcd11156a0d58131e Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 23 Jun 2024 01:29:57 +0700 Subject: [PATCH 299/349] fix json serialization, add round-trip tests --- rust/src/builders/mint_builder.rs | 2 +- .../certificates/certificates_collection.rs | 35 ++++- .../governance/proposals/voting_proposals.rs | 37 ++++- rust/src/protocol_types/tx_inputs.rs | 37 ++++- .../witnesses/bootstrap_witnesses.rs | 2 + rust/src/tests/serialization/certificates.rs | 24 ++++ rust/src/tests/serialization/general.rs | 127 +++++++++++++++++- .../tests/serialization/governance/common.rs | 38 ++++++ 8 files changed, 288 insertions(+), 14 deletions(-) diff --git a/rust/src/builders/mint_builder.rs b/rust/src/builders/mint_builder.rs index cc500e33..b9954b22 100644 --- a/rust/src/builders/mint_builder.rs +++ b/rust/src/builders/mint_builder.rs @@ -366,7 +366,7 @@ impl MintBuilder { } } } - TransactionInputs(reference_inputs) + TransactionInputs::from_vec(reference_inputs) } pub fn get_redeemers(&self) -> Result { diff --git a/rust/src/protocol_types/certificates/certificates_collection.rs b/rust/src/protocol_types/certificates/certificates_collection.rs index 2e8a3397..d316f6e1 100644 --- a/rust/src/protocol_types/certificates/certificates_collection.rs +++ b/rust/src/protocol_types/certificates/certificates_collection.rs @@ -2,7 +2,7 @@ use crate::*; #[wasm_bindgen] #[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, )] pub struct Certificates { pub(crate) certs: Vec, @@ -60,3 +60,36 @@ impl Certificates { certs } } + +impl serde::Serialize for Certificates { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + self.certs.serialize(serializer) + } +} + +impl<'de> serde::de::Deserialize<'de> for Certificates { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let vec = as serde::de::Deserialize>::deserialize( + deserializer, + )?; + Ok(Self::from_vec(vec)) + } +} + +impl JsonSchema for Certificates { + fn schema_name() -> String { + String::from("Certificates") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + Vec::::json_schema(gen) + } + fn is_referenceable() -> bool { + Vec::::is_referenceable() + } +} diff --git a/rust/src/protocol_types/governance/proposals/voting_proposals.rs b/rust/src/protocol_types/governance/proposals/voting_proposals.rs index 8e20bb8c..0a33552c 100644 --- a/rust/src/protocol_types/governance/proposals/voting_proposals.rs +++ b/rust/src/protocol_types/governance/proposals/voting_proposals.rs @@ -8,9 +8,6 @@ use crate::*; Ord, PartialEq, PartialOrd, - serde::Serialize, - serde::Deserialize, - JsonSchema, )] #[wasm_bindgen] pub struct VotingProposals { @@ -72,3 +69,37 @@ impl VotingProposals { self.dedup.contains(proposal) } } + +impl serde::Serialize for VotingProposals { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + self.proposals.serialize(serializer) + } +} + +impl<'de> serde::de::Deserialize<'de> for VotingProposals { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let vec = as serde::de::Deserialize>::deserialize( + deserializer, + )?; + Ok(Self::from_vec(vec)) + } +} + +impl JsonSchema for VotingProposals { + fn schema_name() -> String { + String::from("VotingProposals") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + Vec::::json_schema(gen) + } + fn is_referenceable() -> bool { + Vec::::is_referenceable() + } +} + diff --git a/rust/src/protocol_types/tx_inputs.rs b/rust/src/protocol_types/tx_inputs.rs index 7ce9de0f..886b7952 100644 --- a/rust/src/protocol_types/tx_inputs.rs +++ b/rust/src/protocol_types/tx_inputs.rs @@ -4,7 +4,7 @@ use std::vec::IntoIter; #[wasm_bindgen] #[derive( - Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize, JsonSchema, + Clone, Debug, Eq, Ord, PartialEq, PartialOrd, )] pub struct TransactionInputs { pub(crate) inputs: Vec, @@ -92,4 +92,37 @@ impl IntoIterator for TransactionInputs { fn into_iter(self) -> Self::IntoIter { self.inputs.into_iter() } -} \ No newline at end of file +} + +impl serde::Serialize for TransactionInputs { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + self.inputs.serialize(serializer) + } +} + +impl<'de> serde::de::Deserialize<'de> for TransactionInputs { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let vec = as serde::de::Deserialize>::deserialize( + deserializer, + )?; + Ok(Self::from_vec(vec)) + } +} + +impl JsonSchema for TransactionInputs { + fn schema_name() -> String { + String::from("TransactionInputs") + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + Vec::::json_schema(gen) + } + fn is_referenceable() -> bool { + Vec::::is_referenceable() + } +} diff --git a/rust/src/protocol_types/witnesses/bootstrap_witnesses.rs b/rust/src/protocol_types/witnesses/bootstrap_witnesses.rs index 768b40b7..c1372641 100644 --- a/rust/src/protocol_types/witnesses/bootstrap_witnesses.rs +++ b/rust/src/protocol_types/witnesses/bootstrap_witnesses.rs @@ -10,6 +10,8 @@ pub struct BootstrapWitnesses { dedup: HashSet, } +impl_to_from!(BootstrapWitnesses); + #[wasm_bindgen] impl BootstrapWitnesses { pub fn new() -> Self { diff --git a/rust/src/tests/serialization/certificates.rs b/rust/src/tests/serialization/certificates.rs index 37c53ec4..a05a2680 100644 --- a/rust/src/tests/serialization/certificates.rs +++ b/rust/src/tests/serialization/certificates.rs @@ -390,3 +390,27 @@ fn block_with_tx_with_certs_under_tag_set() { let certs = block.unwrap().transaction_bodies.0[0].certs().unwrap(); assert_eq!(certs.len(), 1); } + +#[test] +fn certificates_collection_ser_round_trip() { + let mut certs = Certificates::new(); + let cert_1 = StakeRegistration::new(&Credential::from_keyhash(&fake_key_hash(1))); + certs.add(&Certificate::new_stake_registration(&cert_1)); + let cert_2 = StakeDeregistration::new(&Credential::from_keyhash(&fake_key_hash(2))); + certs.add(&Certificate::new_stake_deregistration(&cert_2)); + let cert_3 = StakeDelegation::new( + &Credential::from_keyhash(&fake_key_hash(3)), + &fake_key_hash(4), + ); + certs.add(&Certificate::new_stake_delegation(&cert_3)); + + assert_eq!(certs.len(), 3); + + let json = certs.to_json().unwrap(); + let cbor = certs.to_bytes(); + let hex_cbor = certs.to_hex(); + + assert_eq!(certs, Certificates::from_json(&json).unwrap()); + assert_eq!(certs, Certificates::from_bytes(cbor).unwrap()); + assert_eq!(certs, Certificates::from_hex(&hex_cbor).unwrap()); +} diff --git a/rust/src/tests/serialization/general.rs b/rust/src/tests/serialization/general.rs index d7e72998..7f6e93b0 100644 --- a/rust/src/tests/serialization/general.rs +++ b/rust/src/tests/serialization/general.rs @@ -1,9 +1,6 @@ -use crate::{Address, BigInt, BigNum, Block, BlockHash, CborContainerType, Coin, Credential, DataHash, ExUnits, HeaderBody, HeaderLeaderCertEnum, Int, KESVKey, MIRPot, MIRToStakeCredentials, MoveInstantaneousReward, NativeScript, OperationalCert, PlutusData, PlutusList, PlutusScript, PlutusScripts, ProtocolVersion, Redeemer, RedeemerTag, Redeemers, ScriptHash, ScriptRef, TimelockStart, TransactionBody, TransactionInputs, TransactionOutput, TransactionOutputs, TransactionWitnessSet, VRFCert, VRFVKey, Value, Vkeywitness, Vkeywitnesses, VersionedBlock, BlockEra, to_bytes}; +use crate::{Address, BigInt, BigNum, Block, BlockHash, CborContainerType, Coin, Credential, DataHash, ExUnits, HeaderBody, HeaderLeaderCertEnum, Int, KESVKey, MIRPot, MIRToStakeCredentials, MoveInstantaneousReward, NativeScript, OperationalCert, PlutusData, PlutusList, PlutusScript, PlutusScripts, ProtocolVersion, Redeemer, RedeemerTag, Redeemers, ScriptHash, ScriptRef, TimelockStart, TransactionBody, TransactionInputs, TransactionOutput, TransactionOutputs, TransactionWitnessSet, VRFCert, VRFVKey, Value, Vkeywitness, Vkeywitnesses, VersionedBlock, BlockEra, to_bytes, BootstrapWitnesses, Credentials, Ed25519KeyHashes}; -use crate::fakes::{ - fake_base_address, fake_bytes_32, fake_data_hash, fake_signature, fake_tx_input, - fake_tx_output, fake_value, fake_value2, fake_vkey, -}; +use crate::fakes::{fake_base_address, fake_boostrap_witness, fake_bytes_32, fake_data_hash, fake_key_hash, fake_signature, fake_tx_input, fake_tx_output, fake_value, fake_value2, fake_vkey, fake_vkey_witness}; use crate::protocol_types::ScriptRefEnum; #[test] @@ -783,7 +780,8 @@ fn redeemers_map_deserialization() { assert!(redeemers.is_ok()); } -#[test] fn ref_script_serialization() { +#[test] +fn ref_script_serialization() { let plutus_script = PlutusScript::new([61u8; 29].to_vec()); let script_ref = ScriptRef::new_plutus_script(&plutus_script); let script_enum = ScriptRefEnum::PlutusScript(plutus_script); @@ -795,4 +793,119 @@ fn redeemers_map_deserialization() { let new_script_ref = ScriptRef::from_bytes(wrapped_bytes).unwrap(); assert_eq!(script_ref, new_script_ref); -} \ No newline at end of file +} + +#[test] +fn boostrap_witnesses_round_trip() { + let mut witnesses = BootstrapWitnesses::new(); + let bootstrap_witness_1 = fake_boostrap_witness(1); + let bootstrap_witness_2 = fake_boostrap_witness(2); + let bootstrap_witness_3 = fake_boostrap_witness(3); + + witnesses.add(&bootstrap_witness_1); + witnesses.add(&bootstrap_witness_2); + witnesses.add(&bootstrap_witness_3); + + let bytes = witnesses.to_bytes(); + let new_witnesses = BootstrapWitnesses::from_bytes(bytes.clone()).unwrap(); + + let json = witnesses.to_json().unwrap(); + let new_witnesses_json = BootstrapWitnesses::from_json(&json).unwrap(); + + assert_eq!(witnesses, new_witnesses); + assert_eq!(witnesses, new_witnesses_json); + assert_eq!(bytes, new_witnesses.to_bytes()); + assert_eq!(json, new_witnesses_json.to_json().unwrap()); +} + +#[test] +fn credential_round_trip() { + let mut credentials = Credentials::new(); + let credential_1 = Credential::from_keyhash(&fake_key_hash(1)); + let credential_2 = Credential::from_keyhash(&fake_key_hash(2)); + let credential_3 = Credential::from_keyhash(&fake_key_hash(3)); + + credentials.add(&credential_1); + credentials.add(&credential_2); + credentials.add(&credential_3); + + let bytes = credentials.to_bytes(); + let new_credentials = Credentials::from_bytes(bytes.clone()).unwrap(); + + let json = credentials.to_json().unwrap(); + let new_credentials_json = Credentials::from_json(&json).unwrap(); + + assert_eq!(credentials, new_credentials); + assert_eq!(credentials, new_credentials_json); + assert_eq!(bytes, new_credentials.to_bytes()); + assert_eq!(json, new_credentials_json.to_json().unwrap()); +} + +#[test] +fn ed25519_key_hashes_round_trip() { + let mut keyhashes = Ed25519KeyHashes::new(); + let keyhash_1 = fake_key_hash(1); + let keyhash_2 = fake_key_hash(2); + let keyhash_3 = fake_key_hash(3); + + keyhashes.add(&keyhash_1); + keyhashes.add(&keyhash_2); + keyhashes.add(&keyhash_3); + + let bytes = keyhashes.to_bytes(); + let new_keyhashes = Ed25519KeyHashes::from_bytes(bytes.clone()).unwrap(); + + let json = keyhashes.to_json().unwrap(); + let new_keyhashes_json = Ed25519KeyHashes::from_json(&json).unwrap(); + + assert_eq!(keyhashes, new_keyhashes); + assert_eq!(keyhashes, new_keyhashes_json); + assert_eq!(bytes, new_keyhashes.to_bytes()); + assert_eq!(json, new_keyhashes_json.to_json().unwrap()); +} + +#[test] +fn vkey_witnesses_round_trip() { + let mut witnesses = Vkeywitnesses::new(); + let vkey_witness_1 = fake_vkey_witness(1); + let vkey_witness_2 = fake_vkey_witness(2); + let vkey_witness_3 = fake_vkey_witness(3); + + witnesses.add(&vkey_witness_1); + witnesses.add(&vkey_witness_2); + witnesses.add(&vkey_witness_3); + + let bytes = witnesses.to_bytes(); + let new_witnesses = Vkeywitnesses::from_bytes(bytes.clone()).unwrap(); + + let json = witnesses.to_json().unwrap(); + let new_witnesses_json = Vkeywitnesses::from_json(&json).unwrap(); + + assert_eq!(witnesses, new_witnesses); + assert_eq!(witnesses, new_witnesses_json); + assert_eq!(bytes, new_witnesses.to_bytes()); + assert_eq!(json, new_witnesses_json.to_json().unwrap()); +} + +#[test] +fn tx_inputs_round_trip() { + let mut inputs = TransactionInputs::new(); + let input_1 = fake_tx_input(1); + let input_2 = fake_tx_input(2); + let input_3 = fake_tx_input(3); + + inputs.add(&input_1); + inputs.add(&input_2); + inputs.add(&input_3); + + let bytes = inputs.to_bytes(); + let new_inputs = TransactionInputs::from_bytes(bytes.clone()).unwrap(); + + let json = inputs.to_json().unwrap(); + let new_inputs_json = TransactionInputs::from_json(&json).unwrap(); + + assert_eq!(inputs, new_inputs); + assert_eq!(inputs, new_inputs_json); + assert_eq!(bytes, new_inputs.to_bytes()); + assert_eq!(json, new_inputs_json.to_json().unwrap()); +} diff --git a/rust/src/tests/serialization/governance/common.rs b/rust/src/tests/serialization/governance/common.rs index 6d4be55b..c7a8a266 100644 --- a/rust/src/tests/serialization/governance/common.rs +++ b/rust/src/tests/serialization/governance/common.rs @@ -302,3 +302,41 @@ fn tx_with_vote_deser_test() { assert!(voting_procedure.is_some()); } +#[test] +fn voting_proposals_round_trip() { + let mut voting_proposals = VotingProposals::new(); + + let info_action = InfoAction::new(); + let action = GovernanceAction::new_info_action(&info_action); + let proposal = VotingProposal::new( + &action, + &Anchor::new( + &URL::new("https://iohk.io".to_string()).unwrap(), + &fake_anchor_data_hash(1), + ), + &RewardAddress::new( + NetworkInfo::testnet_preprod().network_id(), + &Credential::from_keyhash(&fake_key_hash(1)), + ), + &Coin::from(1_000_011u64), + ); + + voting_proposals.add(&proposal); + + let cbor = voting_proposals.to_bytes(); + let cbor_hex = voting_proposals.to_hex(); + let json = voting_proposals.to_json().unwrap(); + + assert_eq!( + voting_proposals, + VotingProposals::from_bytes(cbor).unwrap() + ); + assert_eq!( + voting_proposals, + VotingProposals::from_hex(&cbor_hex).unwrap() + ); + assert_eq!( + voting_proposals, + VotingProposals::from_json(&json).unwrap() + ); +} \ No newline at end of file From 62a6a0612b996b5ef6e0137af077785ede91521d Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 23 Jun 2024 01:33:19 +0700 Subject: [PATCH 300/349] flow update --- rust/pkg/cardano_serialization_lib.js.flow | 514 ++++++++++++--------- 1 file changed, 297 insertions(+), 217 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 98e875da..cf720ba0 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -42,6 +42,54 @@ declare export function min_ref_script_fee( ref_script_coins_per_byte: UnitInterval ): BigNum; +/** + * @param {string} json + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {PlutusData} + */ +declare export function encode_json_str_to_plutus_datum( + json: string, + schema: $Values +): PlutusData; + +/** + * @param {PlutusData} datum + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {string} + */ +declare export function decode_plutus_datum_to_json_str( + datum: PlutusData, + schema: $Values +): string; + +/** + * @param {string} password + * @param {string} salt + * @param {string} nonce + * @param {string} data + * @returns {string} + */ +declare export function encrypt_with_password( + password: string, + salt: string, + nonce: string, + data: string +): string; + +/** + * @param {string} password + * @param {string} data + * @returns {string} + */ +declare export function decrypt_with_password( + password: string, + data: string +): string; + /** * @param {Address} address * @param {TransactionUnspentOutputs} utxos @@ -54,6 +102,46 @@ declare export function create_send_all( config: TransactionBuilderConfig ): TransactionBatchList; +/** + * @param {Uint8Array} bytes + * @returns {TransactionMetadatum} + */ +declare export function encode_arbitrary_bytes_as_metadatum( + bytes: Uint8Array +): TransactionMetadatum; + +/** + * @param {TransactionMetadatum} metadata + * @returns {Uint8Array} + */ +declare export function decode_arbitrary_bytes_from_metadatum( + metadata: TransactionMetadatum +): Uint8Array; + +/** + * @param {string} json + * @param {$Values< + typeof + MetadataJsonSchema>} schema + * @returns {TransactionMetadatum} + */ +declare export function encode_json_str_to_metadatum( + json: string, + schema: $Values +): TransactionMetadatum; + +/** + * @param {TransactionMetadatum} metadatum + * @param {$Values< + typeof + MetadataJsonSchema>} schema + * @returns {string} + */ +declare export function decode_metadatum_to_json_str( + metadatum: TransactionMetadatum, + schema: $Values +): string; + /** * @param {TransactionHash} tx_body_hash * @param {ByronAddress} addr @@ -180,92 +268,42 @@ declare export function encode_json_str_to_native_script( ): NativeScript; /** - * @param {string} json - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {PlutusData} */ -declare export function encode_json_str_to_plutus_datum( - json: string, - schema: $Values -): PlutusData; -/** - * @param {PlutusData} datum - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {string} - */ -declare export function decode_plutus_datum_to_json_str( - datum: PlutusData, - schema: $Values -): string; +declare export var AddressKind: {| + +Base: 0, // 0 + +Pointer: 1, // 1 + +Enterprise: 2, // 2 + +Reward: 3, // 3 + +Byron: 4, // 4 + +Malformed: 5, // 5 +|}; /** - * @param {Uint8Array} bytes - * @returns {TransactionMetadatum} */ -declare export function encode_arbitrary_bytes_as_metadatum( - bytes: Uint8Array -): TransactionMetadatum; -/** - * @param {TransactionMetadatum} metadata - * @returns {Uint8Array} - */ -declare export function decode_arbitrary_bytes_from_metadatum( - metadata: TransactionMetadatum -): Uint8Array; +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 +|}; /** - * @param {string} json - * @param {$Values< - typeof - MetadataJsonSchema>} schema - * @returns {TransactionMetadatum} */ -declare export function encode_json_str_to_metadatum( - json: string, - schema: $Values -): TransactionMetadatum; -/** - * @param {TransactionMetadatum} metadatum - * @param {$Values< - typeof - MetadataJsonSchema>} schema - * @returns {string} - */ -declare export function decode_metadatum_to_json_str( - metadatum: TransactionMetadatum, - schema: $Values -): string; +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 +|}; /** - * @param {string} password - * @param {string} salt - * @param {string} nonce - * @param {string} data - * @returns {string} */ -declare export function encrypt_with_password( - password: string, - salt: string, - nonce: string, - data: string -): string; -/** - * @param {string} password - * @param {string} data - * @returns {string} - */ -declare export function decrypt_with_password( - password: string, - data: string -): string; +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 +|}; /** */ @@ -283,65 +321,67 @@ declare export var GovernanceActionKind: {| /** */ -declare export var RelayKind: {| - +SingleHostAddr: 0, // 0 - +SingleHostName: 1, // 1 - +MultiHostName: 2, // 2 -|}; - -/** - */ - -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 +declare export var BlockEra: {| + +Byron: 0, // 0 + +Shelley: 1, // 1 + +Allegra: 2, // 2 + +Mary: 3, // 3 + +Alonzo: 4, // 4 + +Babbage: 5, // 5 + +Conway: 6, // 6 + +Unknown: 7, // 7 |}; /** */ -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 |}; /** - * Each new language uses a different namespace for hashing its script - * This is because you could have a language where the same bytes have different semantics - * So this avoids scripts in different languages mapping to the same hash - * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var ScriptHashNamespace: {| - +NativeScript: 0, // 0 - +PlutusScript: 1, // 1 - +PlutusScriptV2: 2, // 2 - +PlutusScriptV3: 3, // 3 +declare export var RelayKind: {| + +SingleHostAddr: 0, // 0 + +SingleHostName: 1, // 1 + +MultiHostName: 2, // 2 |}; /** */ -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 +declare export var CertificateKind: {| + +StakeRegistration: 0, // 0 + +StakeDeregistration: 1, // 1 + +StakeDelegation: 2, // 2 + +PoolRegistration: 3, // 3 + +PoolRetirement: 4, // 4 + +GenesisKeyDelegation: 5, // 5 + +MoveInstantaneousRewardsCert: 6, // 6 + +CommitteeHotAuth: 7, // 7 + +CommitteeColdResign: 8, // 8 + +DrepDeregistration: 9, // 9 + +DrepRegistration: 10, // 10 + +DrepUpdate: 11, // 11 + +StakeAndVoteDelegation: 12, // 12 + +StakeRegistrationAndDelegation: 13, // 13 + +StakeVoteRegistrationAndDelegation: 14, // 14 + +VoteDelegation: 15, // 15 + +VoteRegistrationAndDelegation: 16, // 16 |}; /** */ -declare export var RedeemerTagKind: {| - +Spend: 0, // 0 - +Mint: 1, // 1 - +Cert: 2, // 2 - +Reward: 3, // 3 - +Vote: 4, // 4 - +VotingProposal: 5, // 5 +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 |}; /** @@ -355,37 +395,12 @@ declare export var MIRPot: {| /** */ -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 -|}; - -/** - */ - -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 -|}; - -/** - */ - -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 -|}; - -/** - * Used to choosed the schema for a script JSON string - */ - -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 |}; /** @@ -408,80 +423,69 @@ declare export var PlutusDatumSchema: {| /** */ -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 - +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 |}; /** */ -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 |}; /** */ -declare export var CertificateKind: {| - +StakeRegistration: 0, // 0 - +StakeDeregistration: 1, // 1 - +StakeDelegation: 2, // 2 - +PoolRegistration: 3, // 3 - +PoolRetirement: 4, // 4 - +GenesisKeyDelegation: 5, // 5 - +MoveInstantaneousRewardsCert: 6, // 6 - +CommitteeHotAuth: 7, // 7 - +CommitteeColdResign: 8, // 8 - +DrepDeregistration: 9, // 9 - +DrepRegistration: 10, // 10 - +DrepUpdate: 11, // 11 - +StakeAndVoteDelegation: 12, // 12 - +StakeRegistrationAndDelegation: 13, // 13 - +StakeVoteRegistrationAndDelegation: 14, // 14 - +VoteDelegation: 15, // 15 - +VoteRegistrationAndDelegation: 16, // 16 +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 |}; /** */ -declare export var LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 +declare export var RedeemerTagKind: {| + +Spend: 0, // 0 + +Mint: 1, // 1 + +Cert: 2, // 2 + +Reward: 3, // 3 + +Vote: 4, // 4 + +VotingProposal: 5, // 5 |}; /** */ -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 |}; /** + * Used to choosed the schema for a script JSON string */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** @@ -497,29 +501,25 @@ declare export var NativeScriptKind: {| |}; /** + * Each new language uses a different namespace for hashing its script + * This is because you could have a language where the same bytes have different semantics + * So this avoids scripts in different languages mapping to the same hash + * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var BlockEra: {| - +Byron: 0, // 0 - +Shelley: 1, // 1 - +Allegra: 2, // 2 - +Mary: 3, // 3 - +Alonzo: 4, // 4 - +Babbage: 5, // 5 - +Conway: 6, // 6 - +Unknown: 7, // 7 +declare export var ScriptHashNamespace: {| + +NativeScript: 0, // 0 + +PlutusScript: 1, // 1 + +PlutusScriptV2: 2, // 2 + +PlutusScriptV3: 3, // 3 |}; /** */ -declare export var AddressKind: {| - +Base: 0, // 0 - +Pointer: 1, // 1 - +Enterprise: 2, // 2 - +Reward: 3, // 3 - +Byron: 4, // 4 - +Malformed: 5, // 5 +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** @@ -1084,6 +1084,11 @@ declare export class BaseAddress { * @returns {BaseAddress | void} */ static from_address(addr: Address): BaseAddress | void; + + /** + * @returns {number} + */ + network_id(): number; } /** */ @@ -1700,6 +1705,44 @@ declare export class BootstrapWitness { declare export class BootstrapWitnesses { free(): void; + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {Uint8Array} bytes + * @returns {BootstrapWitnesses} + */ + static from_bytes(bytes: Uint8Array): BootstrapWitnesses; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex_str + * @returns {BootstrapWitnesses} + */ + static from_hex(hex_str: string): BootstrapWitnesses; + + /** + * @returns {string} + */ + to_json(): string; + + /** + * @returns {BootstrapWitnessesJSON} + */ + to_js_value(): BootstrapWitnessesJSON; + + /** + * @param {string} json + * @returns {BootstrapWitnesses} + */ + static from_json(json: string): BootstrapWitnesses; + /** * @returns {BootstrapWitnesses} */ @@ -1717,9 +1760,12 @@ declare export class BootstrapWitnesses { get(index: number): BootstrapWitness; /** + * Add a new `BootstrapWitness` to the set. + * Returns `true` if the element was not already present in the set. * @param {BootstrapWitness} elem + * @returns {boolean} */ - add(elem: BootstrapWitness): void; + add(elem: BootstrapWitness): boolean; } /** */ @@ -2120,9 +2166,12 @@ declare export class Certificates { get(index: number): Certificate; /** + * Add a new `Certificate` to the set. + * Returns `true` if the element was not already present in the set. * @param {Certificate} elem + * @returns {boolean} */ - add(elem: Certificate): void; + add(elem: Certificate): boolean; } /** */ @@ -2832,9 +2881,12 @@ declare export class Credentials { get(index: number): Credential; /** + * Add a new `Credential` to the set. + * Returns `true` if the element was not already present in the set. * @param {Credential} elem + * @returns {boolean} */ - add(elem: Credential): void; + add(elem: Credential): boolean; } /** */ @@ -3587,9 +3639,12 @@ declare export class Ed25519KeyHashes { get(index: number): Ed25519KeyHash; /** + * Add a new `Ed25519KeyHash` to the set. + * Returns `true` if the element was not already present in the set. * @param {Ed25519KeyHash} elem + * @returns {boolean} */ - add(elem: Ed25519KeyHash): void; + add(elem: Ed25519KeyHash): boolean; /** * @param {Ed25519KeyHash} elem @@ -3667,6 +3722,11 @@ declare export class EnterpriseAddress { * @returns {EnterpriseAddress | void} */ static from_address(addr: Address): EnterpriseAddress | void; + + /** + * @returns {number} + */ + network_id(): number; } /** */ @@ -7350,6 +7410,11 @@ declare export class PointerAddress { * @returns {PointerAddress | void} */ static from_address(addr: Address): PointerAddress | void; + + /** + * @returns {number} + */ + network_id(): number; } /** */ @@ -8828,6 +8893,11 @@ declare export class RewardAddress { * @returns {RewardAddress | void} */ static from_address(addr: Address): RewardAddress | void; + + /** + * @returns {number} + */ + network_id(): number; } /** */ @@ -11429,9 +11499,13 @@ declare export class TransactionInputs { get(index: number): TransactionInput; /** + * Add a new `TransactionInput` to the set. + * Returns `true` if the element was not already present in the set. + * Note that the `TransactionInput` is added to the set only if it is not already present. * @param {TransactionInput} elem + * @returns {boolean} */ - add(elem: TransactionInput): void; + add(elem: TransactionInput): boolean; /** * @returns {TransactionInputs | void} @@ -13144,9 +13218,12 @@ declare export class Vkeywitnesses { get(index: number): Vkeywitness; /** + * Add a new `Vkeywitness` to the set. + * Returns `true` if the element was not already present in the set. * @param {Vkeywitness} elem + * @returns {boolean} */ - add(elem: Vkeywitness): void; + add(elem: Vkeywitness): boolean; } /** */ @@ -13831,9 +13908,12 @@ declare export class VotingProposals { get(index: number): VotingProposal; /** + * Add a proposal to the set of proposals + * Returns true if the proposal was added, false if it was already present * @param {VotingProposal} proposal + * @returns {boolean} */ - add(proposal: VotingProposal): void; + add(proposal: VotingProposal): boolean; } /** */ @@ -14201,8 +14281,6 @@ export type DRepJSON = ScriptHash: string, ... }; -export type CertificatesJSON = CertificateJSON[]; -export type TransactionInputsJSON = TransactionInputJSON[]; export type DataOptionJSON = | { DataHash: string, @@ -14273,7 +14351,6 @@ export type GovernanceActionJSON = * @maxItems 0 */ export type InfoActionJSON = []; -export type VotingProposalsJSON = VotingProposalJSON[]; export type TransactionBodiesJSON = TransactionBodyJSON[]; export type RedeemerTagJSON = | "Spend" @@ -14324,17 +14401,17 @@ export interface ProtocolVersionJSON { } export interface TransactionBodyJSON { auxiliary_data_hash?: string | null; - certs?: CertificatesJSON | null; - collateral?: TransactionInputsJSON | null; + certs?: CertificateJSON[] | null; + collateral?: TransactionInputJSON[] | null; collateral_return?: TransactionOutputJSON | null; current_treasury_value?: string | null; donation?: string | null; fee: string; - inputs: TransactionInputsJSON; + inputs: TransactionInputJSON[]; mint?: MintJSON | null; network_id?: NetworkIdJSON | null; outputs: TransactionOutputsJSON; - reference_inputs?: TransactionInputsJSON | null; + reference_inputs?: TransactionInputJSON[] | null; required_signers?: string[] | null; script_data_hash?: string | null; total_collateral?: string | null; @@ -14342,7 +14419,7 @@ export interface TransactionBodyJSON { update?: UpdateJSON | null; validity_start_interval?: string | null; voting_procedures?: VoterVotesJSON[] | null; - voting_proposals?: VotingProposalsJSON | null; + voting_proposals?: VotingProposalJSON[] | null; withdrawals?: { [k: string]: string, } | null; @@ -14753,6 +14830,7 @@ export type CertificateEnumJSON = VoteRegistrationAndDelegation: VoteRegistrationAndDelegationJSON, ... }; +export type CertificatesJSON = CertificateJSON[]; export type CredentialJSON = CredTypeJSON; export type CredentialsJSON = CredTypeJSON[]; export type DRepEnumJSON = @@ -14869,6 +14947,7 @@ export interface TransactionJSON { witness_set: TransactionWitnessSetJSON; } export type TransactionHashJSON = string; +export type TransactionInputsJSON = TransactionInputJSON[]; export type TransactionMetadatumJSON = string; export interface TransactionUnspentOutputJSON { input: TransactionInputJSON; @@ -14897,6 +14976,7 @@ export type VoterEnumJSON = }; export type VotersJSON = VoterJSON[]; export type VotingProceduresJSON = VoterVotesJSON[]; +export type VotingProposalsJSON = VotingProposalJSON[]; export interface WithdrawalsJSON { [k: string]: string; } From e056c452276c0ad15bc2be6068c55feae219485f Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 23 Jun 2024 02:07:48 +0700 Subject: [PATCH 301/349] warnings cleanup --- rust/src/builders/mint_builder.rs | 2 ++ rust/src/builders/script_structs/script_witness_type.rs | 1 + rust/src/builders/tx_inputs_builder.rs | 1 + rust/src/protocol_types/credentials.rs | 1 + .../protocol_types/governance/proposals/voting_proposals.rs | 1 + rust/src/protocol_types/native_scripts.rs | 1 + rust/src/protocol_types/plutus/plutus_data.rs | 1 + rust/src/protocol_types/plutus/plutus_scripts.rs | 2 ++ rust/src/protocol_types/plutus/redeemers.rs | 1 + rust/src/protocol_types/protocol_param_update.rs | 6 ------ rust/src/rational.rs | 1 + rust/src/tests/builders/tx_builder.rs | 4 ---- 12 files changed, 12 insertions(+), 10 deletions(-) diff --git a/rust/src/builders/mint_builder.rs b/rust/src/builders/mint_builder.rs index b9954b22..0c746150 100644 --- a/rust/src/builders/mint_builder.rs +++ b/rust/src/builders/mint_builder.rs @@ -42,6 +42,8 @@ struct NativeMints { } impl NativeMints { + + #[allow(dead_code)] fn script_hash(&self) -> PolicyID { match &self.script { NativeScriptSourceEnum::NativeScript(script, _) => script.hash(), diff --git a/rust/src/builders/script_structs/script_witness_type.rs b/rust/src/builders/script_structs/script_witness_type.rs index 0e7a8101..8568b338 100644 --- a/rust/src/builders/script_structs/script_witness_type.rs +++ b/rust/src/builders/script_structs/script_witness_type.rs @@ -7,6 +7,7 @@ pub(crate) enum ScriptWitnessType { } impl ScriptWitnessType { + #[allow(dead_code)] pub(crate) fn script_hash(&self) -> ScriptHash { match self { ScriptWitnessType::NativeScriptWitness(script) => script.script_hash(), diff --git a/rust/src/builders/tx_inputs_builder.rs b/rust/src/builders/tx_inputs_builder.rs index 3367966a..8b40ab34 100644 --- a/rust/src/builders/tx_inputs_builder.rs +++ b/rust/src/builders/tx_inputs_builder.rs @@ -330,6 +330,7 @@ impl TxInputsBuilder { .filter_map(|wit| wit.get_script_ref_input_with_size()) } + #[allow(dead_code)] pub(crate) fn get_required_signers(&self) -> Ed25519KeyHashes { self.into() } diff --git a/rust/src/protocol_types/credentials.rs b/rust/src/protocol_types/credentials.rs index 933bc81b..244c76da 100644 --- a/rust/src/protocol_types/credentials.rs +++ b/rust/src/protocol_types/credentials.rs @@ -51,6 +51,7 @@ impl Credentials { } } + #[allow(dead_code)] pub(crate) fn contains(&self, elem: &Credential) -> bool { self.dedup.contains(elem) } diff --git a/rust/src/protocol_types/governance/proposals/voting_proposals.rs b/rust/src/protocol_types/governance/proposals/voting_proposals.rs index 0a33552c..15e5413a 100644 --- a/rust/src/protocol_types/governance/proposals/voting_proposals.rs +++ b/rust/src/protocol_types/governance/proposals/voting_proposals.rs @@ -65,6 +65,7 @@ impl VotingProposals { voting_proposals } + #[allow(dead_code)] pub(crate) fn contains(&self, proposal: &VotingProposal) -> bool { self.dedup.contains(proposal) } diff --git a/rust/src/protocol_types/native_scripts.rs b/rust/src/protocol_types/native_scripts.rs index 59023cbe..3e1bf99e 100644 --- a/rust/src/protocol_types/native_scripts.rs +++ b/rust/src/protocol_types/native_scripts.rs @@ -46,6 +46,7 @@ impl NativeScripts { NativeScripts(scripts) } + #[allow(dead_code)] pub(crate) fn contains(&self, script: &NativeScript) -> bool { self.0.contains(script) } diff --git a/rust/src/protocol_types/plutus/plutus_data.rs b/rust/src/protocol_types/plutus/plutus_data.rs index b04b22b4..3ca884e1 100644 --- a/rust/src/protocol_types/plutus/plutus_data.rs +++ b/rust/src/protocol_types/plutus/plutus_data.rs @@ -490,6 +490,7 @@ impl PlutusList { self.definite_encoding = None; } + #[allow(dead_code)] pub(crate) fn contains(&self, elem: &PlutusData) -> bool { self.elems.contains(elem) } diff --git a/rust/src/protocol_types/plutus/plutus_scripts.rs b/rust/src/protocol_types/plutus/plutus_scripts.rs index 47f563f2..4d6db98a 100644 --- a/rust/src/protocol_types/plutus/plutus_scripts.rs +++ b/rust/src/protocol_types/plutus/plutus_scripts.rs @@ -32,6 +32,7 @@ impl PlutusScripts { self.0.push(elem.clone()); } + #[allow(dead_code)] pub(crate) fn by_version(&self, language: &Language) -> PlutusScripts { PlutusScripts( self.0 @@ -92,6 +93,7 @@ impl PlutusScripts { PlutusScripts(scripts) } + #[allow(dead_code)] pub(crate) fn contains(&self, script: &PlutusScript) -> bool { self.0.contains(&script) } diff --git a/rust/src/protocol_types/plutus/redeemers.rs b/rust/src/protocol_types/plutus/redeemers.rs index 1bab94fa..713f2d98 100644 --- a/rust/src/protocol_types/plutus/redeemers.rs +++ b/rust/src/protocol_types/plutus/redeemers.rs @@ -18,6 +18,7 @@ impl Redeemers { } } + #[allow(dead_code)] pub(crate) fn new_with_serialization_format( redeemers: Vec, serialization_format: CborContainerType, diff --git a/rust/src/protocol_types/protocol_param_update.rs b/rust/src/protocol_types/protocol_param_update.rs index 7e570f48..887b866e 100644 --- a/rust/src/protocol_types/protocol_param_update.rs +++ b/rust/src/protocol_types/protocol_param_update.rs @@ -119,12 +119,6 @@ impl DrepVotingThresholds { } } - pub(crate) fn new_default() -> Self { - Self { - ..Default::default() - } - } - pub fn set_motion_no_confidence(&mut self, motion_no_confidence: &UnitInterval) { self.motion_no_confidence = motion_no_confidence.clone() } diff --git a/rust/src/rational.rs b/rust/src/rational.rs index 8ba079d3..3b9eb8fe 100644 --- a/rust/src/rational.rs +++ b/rust/src/rational.rs @@ -79,6 +79,7 @@ impl Rational { } } + #[allow(dead_code)] pub(crate) fn to_bignum_floor(&self) -> Result { let num = self.numerator(); let denum = self.denominator(); diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index b54d92df..6bc65e8c 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -3776,10 +3776,6 @@ fn test_add_native_script_input() { ); } -fn unsafe_tx_len(b: &TransactionBuilder) -> usize { - b.build_tx_unsafe().unwrap().to_bytes().len() -} - #[test] fn test_native_input_scripts_are_added_to_the_witnesses() { let mut tx_builder = create_reallistic_tx_builder(); From 4840c5104ae5a8fad3976e382f2d40cfc67ec40e Mon Sep 17 00:00:00 2001 From: lisicky Date: Sun, 23 Jun 2024 23:58:30 +0700 Subject: [PATCH 302/349] bump node version in nvmrc, bump dev dependencies --- .github/workflows/pr-checks.yml | 4 +- .nvmrc | 2 +- package-lock.json | 1580 +++++++++++++++++++------------ package.json | 8 +- rust/Cargo.toml | 4 +- rust/json-gen/Cargo.lock | 13 +- 6 files changed, 1009 insertions(+), 602 deletions(-) diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index 87bc26ea..b92d4559 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -14,7 +14,7 @@ jobs: submodules: 'recursive' - uses: actions/setup-node@v1 with: - node-version: '12.18.1' + node-version: '18' - name: Cache node modules uses: actions/cache@v1 with: @@ -50,7 +50,7 @@ jobs: submodules: 'recursive' - uses: actions/setup-node@v1 with: - node-version: '12.18.1' + node-version: '18' - name: Cache node modules uses: actions/cache@v1 with: diff --git a/.nvmrc b/.nvmrc index 46a81848..3f430af8 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v12.18.1 +v18 diff --git a/package-lock.json b/package-lock.json index 09b18ff1..d58b3b0e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,395 +1,337 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.31", - "lockfileVersion": 1, + "version": "12.0.0-alpha.32", + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.3.tgz", - "integrity": "sha512-fDx9eNW0qz0WkUeqL6tXEXzVlPh6Y5aCDEZesl0xBGA8ndRukX91Uk44ZqnkECp01NAZUdCAl+aiQNGi0k88Eg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.3" + "packages": { + "": { + "name": "cardano-serialization-lib", + "version": "12.0.0-alpha.32", + "hasInstallScript": true, + "license": "MIT", + "devDependencies": { + "flowgen": "1.21.0", + "husky": "^9.0.11", + "json-schema-to-typescript": "^14.0.5", + "rimraf": "^5.0.7" } }, - "@babel/helper-validator-identifier": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.3.tgz", - "integrity": "sha512-bU8JvtlYpJSBPuj1VUmKpFGaDZuLxASky3LhaKj3bmpSTY6VWooSM8msk+Z0CZoErFye2tlABF6yDkT3FOPAXw==", - "dev": true - }, - "@babel/highlight": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.3.tgz", - "integrity": "sha512-Ih9B/u7AtgEnySE2L2F0Xm0GaM729XqqLfHkalTsbjXGyqmf/6M0Cu0WpvqueUlW+xk88BHw9Nkpj49naU+vWw==", + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "11.6.4", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.6.4.tgz", + "integrity": "sha512-9K6xOqeevacvweLGik6LnZCb1fBtCOSIWQs8d096XGeqoLKC33UVMGz9+77Gw44KvbH4pKcQPWo4ZpxkXYj05w==", "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.3", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, "dependencies": { - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - } + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.15", + "js-yaml": "^4.1.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/philsturgeon" } }, - "@bcherny/json-schema-ref-parser": { - "version": "10.0.5-fork", - "resolved": "https://registry.npmjs.org/@bcherny/json-schema-ref-parser/-/json-schema-ref-parser-10.0.5-fork.tgz", - "integrity": "sha512-E/jKbPoca1tfUPj3iSbitDZTGnq6FUFjkH6L8U2oDwSuwK1WhnnVtCG7oFOTg/DDnyoXbQYUiUiGOibHqaGVnw==", + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, - "requires": { - "@jsdevtools/ono": "^7.1.3", - "@types/json-schema": "^7.0.6", - "call-me-maybe": "^1.0.1", - "js-yaml": "^4.1.0" + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "@jsdevtools/ono": { + "node_modules/@jsdevtools/ono": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", "dev": true }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true - }, - "@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" + "optional": true, + "engines": { + "node": ">=14" } }, - "@types/json-schema": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", - "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==", - "dev": true - }, - "@types/lodash": { - "version": "4.14.198", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.198.tgz", - "integrity": "sha512-trNJ/vtMZYMLhfN45uLq4ShQSw0/S7xCTLLVM+WM1rmFpba/VS42jVUgaO3w/NOLiWR/09lnYk0yMaA/atdIsg==", - "dev": true - }, - "@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, - "@types/node": { - "version": "20.6.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.2.tgz", - "integrity": "sha512-Y+/1vGBHV/cYk6OI1Na/LHzwnlNCAfU3ZNGrc1LdRe/LAIbdDPTTv/HU3M7yXN448aTVDq3eKRm2cg7iKLb8gw==", + "node_modules/@types/lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw==", "dev": true }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, - "@types/prettier": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", - "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", - "dev": true + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } }, - "ansi-styles": { + "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "requires": { + "dependencies": { "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "any-promise": { + "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", "dev": true }, - "argparse": { + "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "balanced-match": { + "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "call-me-maybe": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", - "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", - "dev": true - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "cli-color": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.3.tgz", - "integrity": "sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==", + "node_modules/cli-color": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.4.tgz", + "integrity": "sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==", "dev": true, - "requires": { + "dependencies": { "d": "^1.0.1", - "es5-ext": "^0.10.61", + "es5-ext": "^0.10.64", "es6-iterator": "^2.0.3", "memoizee": "^0.4.15", "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.10" } }, - "color-convert": { + "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "requires": { + "dependencies": { "color-name": "1.1.3" } }, - "color-name": { + "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, - "commander": { + "node_modules/commander": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", - "dev": true - }, - "compare-versions": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", - "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "dev": true, + "engines": { + "node": ">= 6" + } }, - "cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "node_modules/d": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" + "dependencies": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" } }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", "dev": true, - "requires": { - "is-arrayish": "^0.2.1" + "engines": { + "node": ">= 12" } }, - "es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", "dev": true, - "requires": { + "hasInstallScript": true, + "dependencies": { "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" } }, - "es6-iterator": { + "node_modules/es6-iterator": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", "dev": true, - "requires": { + "dependencies": { "d": "1", "es5-ext": "^0.10.35", "es6-symbol": "^3.1.1" } }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "node_modules/es6-symbol": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", "dev": true, - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" + "dependencies": { + "d": "^1.0.2", + "ext": "^1.7.0" + }, + "engines": { + "node": ">=0.12" } }, - "es6-weak-map": { + "node_modules/es6-weak-map": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", "dev": true, - "requires": { + "dependencies": { "d": "1", "es5-ext": "^0.10.46", "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.1" } }, - "escape-string-regexp": { + "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } }, - "event-emitter": { + "node_modules/event-emitter": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", "dev": true, - "requires": { + "dependencies": { "d": "1", "es5-ext": "~0.10.14" } }, - "ext": { + "node_modules/ext": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", "dev": true, - "requires": { - "type": "^2.7.2" - }, "dependencies": { - "type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true - } + "type": "^2.7.2" } }, - "find-versions": { + "node_modules/fetch-blob": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz", - "integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", "dev": true, - "requires": { - "semver-regex": "^2.0.0" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" } }, - "flowgen": { + "node_modules/flowgen": { "version": "1.21.0", "resolved": "https://registry.npmjs.org/flowgen/-/flowgen-1.21.0.tgz", "integrity": "sha512-pFNFFyMLRmW6njhOIm5TrbGUDTv64aujmys2KrkRE2NYD8sXwJUyicQRwU5SPRBRJnFSD/FNlnHo2NnHI5eJSw==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.16.7", "@babel/highlight": "^7.16.7", "commander": "^6.1.0", @@ -399,583 +341,1055 @@ "typescript": "~4.4.4", "typescript-compiler": "^1.4.1-2" }, + "bin": { + "flowgen": "lib/cli/index.js" + } + }, + "node_modules/flowgen/node_modules/@babel/code-frame": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", + "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "dev": true, "dependencies": { - "@babel/code-frame": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", - "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", - "dev": true, - "requires": { - "@babel/highlight": "^7.22.5" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", - "dev": true - }, - "@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - } + "@babel/highlight": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/flowgen/node_modules/@babel/helper-validator-identifier": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/flowgen/node_modules/@babel/highlight": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", + "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/flowgen/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/foreground-child": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" } }, - "fs.realpath": { + "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "function-bind": { + "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", - "dev": true - }, - "glob": { + "node_modules/glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "requires": { + "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" } }, - "glob-promise": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/glob-promise/-/glob-promise-4.2.2.tgz", - "integrity": "sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw==", + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, - "requires": { - "@types/glob": "^7.1.3" + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "has": { + "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, - "requires": { + "dependencies": { "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" } }, - "has-flag": { + "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "husky": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/husky/-/husky-4.2.5.tgz", - "integrity": "sha512-SYZ95AjKcX7goYVZtVZF2i6XiZcHknw50iXvY7b0MiGoj5RwdgRQNEHdb+gPDPCXKlzwrybjFjkL6FOj8uRhZQ==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "ci-info": "^2.0.0", - "compare-versions": "^3.6.0", - "cosmiconfig": "^6.0.0", - "find-versions": "^3.2.0", - "opencollective-postinstall": "^2.0.2", - "pkg-dir": "^4.2.0", - "please-upgrade-node": "^3.2.0", - "slash": "^3.0.0", - "which-pm-runs": "^1.0.0" - } - }, - "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "node_modules/husky": { + "version": "9.0.11", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", + "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "bin": { + "husky": "bin.mjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" } }, - "inflight": { + "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, - "requires": { + "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, - "inherits": { + "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "interpret": { + "node_modules/interpret": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.10" + } }, - "is-core-module": { + "node_modules/is-core-module": { "version": "2.12.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", "dev": true, - "requires": { + "dependencies": { "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-extglob": { + "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "is-glob": { + "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "requires": { + "dependencies": { "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "is-promise": { + "node_modules/is-promise": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", "dev": true }, - "js-tokens": { + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/jackspeak": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", + "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, - "js-yaml": { + "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "requires": { + "dependencies": { "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema-to-typescript": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-13.1.1.tgz", - "integrity": "sha512-F3CYhtA7F3yPbb8vF7sFchk/2dnr1/yTKf8RcvoNpjnh67ZS/ZMH1ElLt5KHAtf2/bymiejLQQszszPWEeTdSw==", - "dev": true, - "requires": { - "@bcherny/json-schema-ref-parser": "10.0.5-fork", - "@types/json-schema": "^7.0.11", - "@types/lodash": "^4.14.182", - "@types/prettier": "^2.6.1", - "cli-color": "^2.0.2", - "get-stdin": "^8.0.0", - "glob": "^7.1.6", - "glob-promise": "^4.2.2", + "node_modules/json-schema-to-typescript": { + "version": "14.0.5", + "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-14.0.5.tgz", + "integrity": "sha512-JmHsbgY0KKo8Pw0HRXpGzAlZYxlu+M5kFhSzhNkUSrVJ4sCXPdAGIdSpzva5ev2/Kybz10S6AfnNdF4o3Pzt3A==", + "dev": true, + "dependencies": { + "@apidevtools/json-schema-ref-parser": "^11.5.5", + "@types/json-schema": "^7.0.15", + "@types/lodash": "^4.17.0", + "cli-color": "^2.0.4", + "glob": "^10.3.12", "is-glob": "^4.0.3", + "js-yaml": "^4.1.0", "lodash": "^4.17.21", - "minimist": "^1.2.6", - "mkdirp": "^1.0.4", + "minimist": "^1.2.8", + "mkdirp": "^3.0.1", "mz": "^2.7.0", - "prettier": "^2.6.2" + "node-fetch": "^3.3.2", + "prettier": "^3.2.5" + }, + "bin": { + "json2ts": "dist/src/cli.js" + }, + "engines": { + "node": ">=16.0.0" } }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", - "dev": true + "node_modules/json-schema-to-typescript/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/json-schema-to-typescript/node_modules/glob": { + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", + "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "lodash": { + "node_modules/json-schema-to-typescript/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/json-schema-to-typescript/node_modules/prettier": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", + "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "lru-queue": { + "node_modules/lru-cache": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/lru-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", "dev": true, - "requires": { + "dependencies": { "es5-ext": "~0.10.2" } }, - "memoizee": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", - "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "node_modules/memoizee": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz", + "integrity": "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==", "dev": true, - "requires": { - "d": "^1.0.1", - "es5-ext": "^0.10.53", + "dependencies": { + "d": "^1.0.2", + "es5-ext": "^0.10.64", "es6-weak-map": "^2.0.3", "event-emitter": "^0.3.5", "is-promise": "^2.2.2", "lru-queue": "^0.1.0", "next-tick": "^1.1.0", "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.12" } }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { + "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } }, - "mz": { + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", "dev": true, - "requires": { + "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, - "next-tick": { + "node_modules/next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", "dev": true }, - "object-assign": { + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dev": true, + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "once": { + "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, - "requires": { + "dependencies": { "wrappy": "1" } }, - "opencollective-postinstall": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", - "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", "dev": true }, - "parent-module": { + "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true, - "requires": { - "callsites": "^3.0.0" + "engines": { + "node": ">=0.10.0" } }, - "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" + "engines": { + "node": ">=8" } }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-parse": { + "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, - "requires": { - "find-up": "^4.0.0" - }, "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - } - } - }, - "please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", - "dev": true, - "requires": { - "semver-compare": "^1.0.0" + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "prettier": { + "node_modules/prettier": { "version": "2.8.8", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } }, - "rechoir": { + "node_modules/rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", "dev": true, - "requires": { + "dependencies": { "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" } }, - "resolve": { + "node_modules/resolve": { "version": "1.22.2", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", "dev": true, - "requires": { + "dependencies": { "is-core-module": "^2.11.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true + "node_modules/rimraf": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.7.tgz", + "integrity": "sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "requires": { - "glob": "^7.1.3" + "dependencies": { + "balanced-match": "^1.0.0" } }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", - "dev": true + "node_modules/rimraf/node_modules/glob": { + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", + "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "semver-regex": { + "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz", - "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==", - "dev": true + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } }, - "shelljs": { + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shelljs": { "version": "0.8.5", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", "dev": true, - "requires": { + "dependencies": { "glob": "^7.0.0", "interpret": "^1.0.0", "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" } }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "supports-color": { + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "requires": { + "dependencies": { "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "supports-preserve-symlinks-flag": { + "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "thenify": { + "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", "dev": true, - "requires": { + "dependencies": { "any-promise": "^1.0.0" } }, - "thenify-all": { + "node_modules/thenify-all": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", "dev": true, - "requires": { + "dependencies": { "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" } }, - "timers-ext": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", - "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "node_modules/timers-ext": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.8.tgz", + "integrity": "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==", "dev": true, - "requires": { - "es5-ext": "~0.10.46", - "next-tick": "1" + "dependencies": { + "es5-ext": "^0.10.64", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.12" } }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "node_modules/type": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", + "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", "dev": true }, - "typescript": { + "node_modules/typescript": { "version": "4.4.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", - "dev": true + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } }, - "typescript-compiler": { + "node_modules/typescript-compiler": { "version": "1.4.1-2", "resolved": "https://registry.npmjs.org/typescript-compiler/-/typescript-compiler-1.4.1-2.tgz", "integrity": "sha512-EMopKmoAEJqA4XXRFGOb7eSBhmQMbBahW6P1Koayeatp0b4AW2q/bBqYWkpG7QVQc9HGQUiS4trx2ZHcnAaZUg==", "dev": true }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "wrappy": { + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true - }, - "yaml": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", - "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", - "dev": true } } } diff --git a/package.json b/package.json index 4c7e071d..d99faf6f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.31", + "version": "12.0.0-alpha.32", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", @@ -35,8 +35,8 @@ }, "devDependencies": { "flowgen": "1.21.0", - "husky": "4.2.5", - "json-schema-to-typescript": "^13.1.1", - "rimraf": "3.0.2" + "husky": "^9.0.11", + "json-schema-to-typescript": "^14.0.5", + "rimraf": "^5.0.7" } } diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 7b4804b7..d0c9992c 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.31" +version = "12.0.0-alpha.32" edition = "2018" authors = ["EMURGO"] license = "MIT" @@ -24,7 +24,7 @@ digest = "^0.9" bech32 = "0.7.2" hex = "0.4.0" cfg-if = "1" -hashlink = "0.9.0" +hashlink = "0.9.1" serde_json = { version = "1.0.114", features = ["arbitrary_precision"] } num-bigint = "0.4.0" num-integer = "0.1.45" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 84716ddf..56258fc1 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -14,12 +14,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - [[package]] name = "autocfg" version = "1.0.1" @@ -55,7 +49,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.31" +version = "12.0.0-alpha.32" dependencies = [ "bech32", "cbor_event", @@ -211,14 +205,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ "ahash", - "allocator-api2", ] [[package]] name = "hashlink" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692eaaf7f7607518dd3cef090f1474b61edc5301d8012f09579920df68b725ee" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" dependencies = [ "hashbrown", ] From b5686baebe3ef17897d5acfa18d49fac9078e53a Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 24 Jun 2024 00:10:55 +0700 Subject: [PATCH 303/349] bump csl version --- package-lock.json | 4 +- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- rust/pkg/cardano_serialization_lib.js.flow | 272 ++++++++++----------- 5 files changed, 141 insertions(+), 141 deletions(-) diff --git a/package-lock.json b/package-lock.json index d58b3b0e..05fab450 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.32", + "version": "12.0.0-beta.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.32", + "version": "12.0.0-beta.1", "hasInstallScript": true, "license": "MIT", "devDependencies": { diff --git a/package.json b/package.json index d99faf6f..174ff646 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-alpha.32", + "version": "12.0.0-beta.1", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index d0c9992c..58288aef 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-alpha.32" +version = "12.0.0-beta.1" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 56258fc1..9bb9e625 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -49,7 +49,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-alpha.32" +version = "12.0.0-beta.1" dependencies = [ "bech32", "cbor_event", diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index cf720ba0..d5986462 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -270,84 +270,31 @@ declare export function encode_json_str_to_native_script( /** */ -declare export var AddressKind: {| - +Base: 0, // 0 - +Pointer: 1, // 1 - +Enterprise: 2, // 2 - +Reward: 3, // 3 - +Byron: 4, // 4 - +Malformed: 5, // 5 -|}; - -/** - */ - -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 -|}; - -/** - */ - -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 -|}; - -/** - */ - -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 -|}; - -/** - */ - -declare export var GovernanceActionKind: {| - +ParameterChangeAction: 0, // 0 - +HardForkInitiationAction: 1, // 1 - +TreasuryWithdrawalsAction: 2, // 2 - +NoConfidenceAction: 3, // 3 - +UpdateCommitteeAction: 4, // 4 - +NewConstitutionAction: 5, // 5 - +InfoAction: 6, // 6 -|}; - -/** - */ - -declare export var BlockEra: {| - +Byron: 0, // 0 - +Shelley: 1, // 1 - +Allegra: 2, // 2 - +Mary: 3, // 3 - +Alonzo: 4, // 4 - +Babbage: 5, // 5 - +Conway: 6, // 6 - +Unknown: 7, // 7 +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** */ -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 |}; /** */ -declare export var RelayKind: {| - +SingleHostAddr: 0, // 0 - +SingleHostName: 1, // 1 - +MultiHostName: 2, // 2 +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 |}; /** @@ -374,61 +321,65 @@ declare export var CertificateKind: {| |}; /** + * JSON <-> PlutusData conversion schemas. + * Follows ScriptDataJsonSchema in cardano-cli defined at: + * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 + * + * All methods here have the following restrictions due to limitations on dependencies: + * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors + * * Hex strings for bytes don't accept odd-length (half-byte) strings. + * cardano-cli seems to support these however but it seems to be different than just 0-padding + * on either side when tested so proceed with caution */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 +declare export var PlutusDatumSchema: {| + +BasicConversions: 0, // 0 + +DetailedSchema: 1, // 1 |}; /** */ -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 |}; /** */ -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 - +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 |}; /** - * JSON <-> PlutusData conversion schemas. - * Follows ScriptDataJsonSchema in cardano-cli defined at: - * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 - * - * All methods here have the following restrictions due to limitations on dependencies: - * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors - * * Hex strings for bytes don't accept odd-length (half-byte) strings. - * cardano-cli seems to support these however but it seems to be different than just 0-padding - * on either side when tested so proceed with caution */ -declare export var PlutusDatumSchema: {| - +BasicConversions: 0, // 0 - +DetailedSchema: 1, // 1 +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 |}; /** + * Each new language uses a different namespace for hashing its script + * This is because you could have a language where the same bytes have different semantics + * So this avoids scripts in different languages mapping to the same hash + * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 +declare export var ScriptHashNamespace: {| + +NativeScript: 0, // 0 + +PlutusScript: 1, // 1 + +PlutusScriptV2: 2, // 2 + +PlutusScriptV3: 3, // 3 |}; /** @@ -443,20 +394,50 @@ declare export var VoteKind: {| /** */ -declare export var LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 |}; /** */ -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 +|}; + +/** + */ + +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 +|}; + +/** + */ + +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 +|}; + +/** + */ + +declare export var BlockEra: {| + +Byron: 0, // 0 + +Shelley: 1, // 1 + +Allegra: 2, // 2 + +Mary: 3, // 3 + +Alonzo: 4, // 4 + +Babbage: 5, // 5 + +Conway: 6, // 6 + +Unknown: 7, // 7 |}; /** @@ -472,54 +453,73 @@ declare export var RedeemerTagKind: {| |}; /** + * Used to choosed the schema for a script JSON string */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** - * Used to choosed the schema for a script JSON string */ -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 +declare export var AddressKind: {| + +Base: 0, // 0 + +Pointer: 1, // 1 + +Enterprise: 2, // 2 + +Reward: 3, // 3 + +Byron: 4, // 4 + +Malformed: 5, // 5 |}; /** */ -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 |}; /** - * Each new language uses a different namespace for hashing its script - * This is because you could have a language where the same bytes have different semantics - * So this avoids scripts in different languages mapping to the same hash - * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var ScriptHashNamespace: {| - +NativeScript: 0, // 0 - +PlutusScript: 1, // 1 - +PlutusScriptV2: 2, // 2 - +PlutusScriptV3: 3, // 3 +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 |}; /** */ -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 +declare export var RelayKind: {| + +SingleHostAddr: 0, // 0 + +SingleHostName: 1, // 1 + +MultiHostName: 2, // 2 +|}; + +/** + */ + +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 +|}; + +/** + */ + +declare export var GovernanceActionKind: {| + +ParameterChangeAction: 0, // 0 + +HardForkInitiationAction: 1, // 1 + +TreasuryWithdrawalsAction: 2, // 2 + +NoConfidenceAction: 3, // 3 + +UpdateCommitteeAction: 4, // 4 + +NewConstitutionAction: 5, // 5 + +InfoAction: 6, // 6 |}; /** From 197c4563b101eadf80fb5c55c650d4aaf8cf9358 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 24 Jun 2024 17:23:13 +0700 Subject: [PATCH 304/349] add packages with finalization registry --- README.md | 8 ++++++++ package.json | 22 ++++++++++++++++------ release.sh | 11 +++++++---- scripts/publish-helper.js | 4 ++++ 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 5c0dae0f..4711a689 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,14 @@ This is a library, written in Rust, for serialization & deserialization of data - [Browser (chrome/firefox) WASM package](https://www.npmjs.com/package/@emurgo/cardano-serialization-lib-browser) - [Browser (pure JS - no WASM) ASM.js package](https://www.npmjs.com/package/@emurgo/cardano-serialization-lib-asmjs) +##### NPM packages with GC support +Note: This package uses [weak references flag from wasm-bindgen](https://rustwasm.github.io/wasm-bindgen/reference/weak-references.html). +It uses `FinalizationRegistry` under the hood to automatically call "free" for each CSL struct when it is no longer needed. However, use this feature with caution as it may have unpredictable behaviors. +- [NodeJS WASM package with GC](https://www.npmjs.com/package/@emurgo/cardano-serialization-lib-nodejs-gc) +- [Browser (chrome/firefox) WASM package with GC](https://www.npmjs.com/package/@emurgo/cardano-serialization-lib-browser-gc) +- [Browser (pure JS - no WASM) ASM.js package with GC](https://www.npmjs.com/package/@emurgo/cardano-serialization-lib-asmjs-gc) + + ##### Rust crates - [cardano-serialization-lib](https://crates.io/crates/cardano-serialization-lib) diff --git a/package.json b/package.json index 174ff646..1c2d9995 100644 --- a/package.json +++ b/package.json @@ -7,18 +7,28 @@ "rust:build-browser": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=browser; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", "rust:build-web": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=web; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", "rust:build-asm": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=browser; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run asm:build && npm run js:flowgen", + "rust:build-nodejs:gc": "(rimraf ./rust/pkg && cd rust; WASM_BINDGEN_WEAKREF=1 wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", + "rust:build-browser:gc": "(rimraf ./rust/pkg && cd rust; WASM_BINDGEN_WEAKREF=1 wasm-pack build --target=browser; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", + "rust:build-web:gc": "(rimraf ./rust/pkg && cd rust; WASM_BINDGEN_WEAKREF=1 wasm-pack build --target=web; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", + "rust:build-asm:gc": "(rimraf ./rust/pkg && cd rust; WASM_BINDGEN_WEAKREF=1 wasm-pack build --target=browser; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run asm:build && npm run js:flowgen", "rust:publish": "cd rust && cargo publish && cd ../", "asm:build": "./binaryen/bin/wasm2js ./rust/pkg/cardano_serialization_lib_bg.wasm --output ./rust/pkg/cardano_serialization_lib.asm.js && node ./scripts/wasm-to-asm && node ./scripts/fix-buffer-ref.js", "rust:check-warnings": "(cd rust; RUSTFLAGS=\"-D warnings\" cargo +stable build)", "rust:test": "(cd rust; cargo test)", "js:flowgen": "flowgen ./rust/pkg/cardano_serialization_lib.d.ts -o ./rust/pkg/cardano_serialization_lib.js.flow --add-flow-header", "js:prepublish": "npm run rust:test && rimraf ./publish && cp -r ./rust/pkg ./publish && cp README.md publish/ && cp LICENSE publish/", - "js:publish-nodejs:prod": "npm run rust:build-nodejs && npm run js:prepublish && node ./scripts/publish-helper -nodejs && cd publish && npm publish --access public", - "js:publish-nodejs:beta": "npm run rust:build-nodejs && npm run js:prepublish && node ./scripts/publish-helper -nodejs && cd publish && npm publish --tag beta --access public", - "js:publish-browser:prod": "npm run rust:build-browser && npm run js:prepublish && node ./scripts/publish-helper -browser && cd publish && npm publish --access public", - "js:publish-browser:beta": "npm run rust:build-browser && npm run js:prepublish && node ./scripts/publish-helper -browser && cd publish && npm publish --tag beta --access public", - "js:publish-asm:prod": "npm run rust:build-asm && npm run js:prepublish && node ./scripts/publish-helper -asmjs && cd publish && npm publish --access public", - "js:publish-asm:beta": "npm run rust:build-asm && npm run js:prepublish && node ./scripts/publish-helper -asmjs && cd publish && npm publish --tag beta --access public", + "js:publish-nodejs:prod:no-gc": "npm run rust:build-nodejs && npm run js:prepublish && node ./scripts/publish-helper -nodejs && cd publish && npm publish --access public", + "js:publish-nodejs:beta:no-gc": "npm run rust:build-nodejs && npm run js:prepublish && node ./scripts/publish-helper -nodejs && cd publish && npm publish --tag beta --access public", + "js:publish-browser:prod:no-gc": "npm run rust:build-browser && npm run js:prepublish && node ./scripts/publish-helper -browser && cd publish && npm publish --access public", + "js:publish-browser:beta:no-gc": "npm run rust:build-browser && npm run js:prepublish && node ./scripts/publish-helper -browser && cd publish && npm publish --tag beta --access public", + "js:publish-asm:prod:no-gc": "npm run rust:build-asm && npm run js:prepublish && node ./scripts/publish-helper -asmjs && cd publish && npm publish --access public", + "js:publish-asm:beta:no-gc": "npm run rust:build-asm && npm run js:prepublish && node ./scripts/publish-helper -asmjs && cd publish && npm publish --tag beta --access public", + "js:publish-nodejs:prod:gc": "npm run rust:build-nodejs:gc && npm run js:prepublish && node ./scripts/publish-helper -nodejs -gc && cd publish && npm publish --access public", + "js:publish-nodejs:beta:gc": "npm run rust:build-nodejs:gc && npm run js:prepublish && node ./scripts/publish-helper -nodejs -gc && cd publish && npm publish --tag beta --access public", + "js:publish-browser:prod:gc": "npm run rust:build-browser:gc && npm run js:prepublish && node ./scripts/publish-helper -browser -gc && cd publish && npm publish --access public", + "js:publish-browser:beta:gc": "npm run rust:build-browser:gc && npm run js:prepublish && node ./scripts/publish-helper -browser -gc && cd publish && npm publish --tag beta --access public", + "js:publish-asm:prod:gc": "npm run rust:build-asm:gc && npm run js:prepublish && node ./scripts/publish-helper -asmjs -gc && cd publish && npm publish --access public", + "js:publish-asm:beta:gc": "npm run rust:build-asm:gc && npm run js:prepublish && node ./scripts/publish-helper -asmjs -gc && cd publish && npm publish --tag beta --access public", "js:ts-json-gen": "cd rust/json-gen && cargo +stable run && cd ../.. && node ./scripts/run-json2ts.js && node ./scripts/json-ts-types.js", "postinstall": "git submodule update --init --recursive && cd binaryen; cmake . && make" }, diff --git a/release.sh b/release.sh index 53ad10bf..a43d289b 100644 --- a/release.sh +++ b/release.sh @@ -9,8 +9,11 @@ fi echo "Preparing ${RELEASE_TYPE} release" -. build-and-test.sh \ -&& npm run js:publish-nodejs:${RELEASE_TYPE} \ -&& npm run js:publish-browser:${RELEASE_TYPE} \ -&& npm run js:publish-asm:${RELEASE_TYPE} \ +. ./build-and-test.sh \ +&& npm run js:publish-nodejs:${RELEASE_TYPE}:no-gc \ +&& npm run js:publish-browser:${RELEASE_TYPE}:no-gc \ +&& npm run js:publish-asm:${RELEASE_TYPE}:no-gc \ +&& npm run js:publish-nodejs:${RELEASE_TYPE}:gc \ +&& npm run js:publish-browser:${RELEASE_TYPE}:gc \ +&& npm run js:publish-asm:${RELEASE_TYPE}:gc \ && (cd rust; cargo publish --allow-dirty) diff --git a/scripts/publish-helper.js b/scripts/publish-helper.js index 3a54acf6..1a663de5 100644 --- a/scripts/publish-helper.js +++ b/scripts/publish-helper.js @@ -7,6 +7,10 @@ if (oldPkg.files.find(entry => entry === flowFile) == null) { } if (oldPkg.name === 'cardano-serialization-lib') { oldPkg.name = '@emurgo/' + oldPkg.name + process.argv.slice(2)[0]; + let optionalArg = process.argv.slice(2)[1]; + if (optionalArg) { + oldPkg.name += optionalArg; + } } if (process.argv.slice(2)[0] === '-browser' || process.argv.slice(2)[0] === '-asmjs') { // due to a bug in wasm-pack, this file is missing from browser builds From b374e35e15809963170a5fd628b264390158aa91 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 24 Jun 2024 18:20:12 +0700 Subject: [PATCH 305/349] move fakes into test submodule --- rust/src/fakes.rs | 142 ------------------ rust/src/lib.rs | 1 - rust/src/tests/address.rs | 6 +- rust/src/tests/builders/batch_tools.rs | 3 +- .../tests/builders/certificates_builder.rs | 5 +- rust/src/tests/builders/mint_builder.rs | 3 +- rust/src/tests/builders/tx_builder.rs | 3 +- rust/src/tests/builders/tx_inputs_builder.rs | 7 +- rust/src/tests/builders/voting_builder.rs | 3 +- .../tests/builders/voting_proposal_builder.rs | 6 +- rust/src/tests/general.rs | 3 +- rust/src/tests/mock_objects.rs | 141 ++++++++++++++++- rust/src/tests/protocol_types/certificates.rs | 6 +- .../tests/protocol_types/governance/common.rs | 3 +- .../protocol_types/governance/proposals.rs | 5 +- rust/src/tests/serialization/certificates.rs | 6 +- rust/src/tests/serialization/general.rs | 2 +- .../tests/serialization/governance/common.rs | 2 +- .../serialization/governance/proposals.rs | 5 +- .../tests/serialization/transaction_body.rs | 3 +- 20 files changed, 155 insertions(+), 200 deletions(-) delete mode 100644 rust/src/fakes.rs diff --git a/rust/src/fakes.rs b/rust/src/fakes.rs deleted file mode 100644 index 0712813e..00000000 --- a/rust/src/fakes.rs +++ /dev/null @@ -1,142 +0,0 @@ -#![allow(dead_code)] -use crate::{AnchorDataHash, AuxiliaryDataHash, BigNum, BootstrapWitness, GenesisDelegateHash, GenesisHash, PlutusScript, PoolMetadataHash, PublicKey, ScriptDataHash, ScriptHash, Vkeywitness, VRFKeyHash}; -use crate::{ - Address, BaseAddress, Bip32PrivateKey, Credential, DataHash, Ed25519KeyHash, - Ed25519Signature, NetworkInfo, PolicyID, TransactionHash, TransactionIndex, TransactionInput, - TransactionOutput, Value, Vkey, AssetName, -}; -use crate::RewardAddress; - -pub(crate) fn fake_bytes_32(x: u8) -> Vec { - vec![ - x, 239, 181, 120, 142, 135, 19, 200, 68, 223, 211, 43, 46, 145, 222, 30, 48, 159, 239, 255, - 213, 85, 248, 39, 204, 158, 225, 100, 1, 2, 3, 4, - ] -} - -pub(crate) fn fake_data_hash(x: u8) -> DataHash { - DataHash::from_bytes(fake_bytes_32(x)).unwrap() -} - -pub(crate) fn fake_anchor_data_hash(x: u8) -> AnchorDataHash { - AnchorDataHash::from_bytes(fake_bytes_32(x)).unwrap() -} - -pub(crate) fn fake_auxiliary_data_hash(x: u8) -> AuxiliaryDataHash { - AuxiliaryDataHash::from_bytes(fake_bytes_32(x)).unwrap() -} - -pub(crate) fn fake_pool_metadata_hash(x: u8) -> PoolMetadataHash { - PoolMetadataHash::from_bytes(fake_bytes_32(x)).unwrap() -} - -pub(crate) fn fake_genesis_hash(x: u8) -> GenesisHash { - GenesisHash::from_bytes((&fake_bytes_32(x)[0..28]).to_vec()).unwrap() -} - -pub(crate) fn fake_genesis_delegate_hash(x: u8) -> GenesisDelegateHash { - GenesisDelegateHash::from_bytes((&fake_bytes_32(x)[0..28]).to_vec()).unwrap() -} - -pub(crate) fn fake_vrf_key_hash(x: u8) -> VRFKeyHash { - VRFKeyHash::from_bytes(fake_bytes_32(x)).unwrap() -} - -pub(crate) fn fake_key_hash(x: u8) -> Ed25519KeyHash { - Ed25519KeyHash::from_bytes((&fake_bytes_32(x)[0..28]).to_vec()).unwrap() -} - -pub(crate) fn fake_script_hash(x: u8) -> ScriptHash { - ScriptHash::from_bytes((&fake_bytes_32(x)[0..28]).to_vec()).unwrap() -} - -pub(crate) fn fake_script_data_hash(x: u8) -> ScriptDataHash { - ScriptDataHash::from_bytes(fake_bytes_32(x)).unwrap() -} - -pub(crate) fn fake_base_address(x: u8) -> Address { - BaseAddress::new( - NetworkInfo::testnet_preprod().network_id(), - &Credential::from_keyhash(&fake_key_hash(x)), - &Credential::from_keyhash(&fake_key_hash(0)), - ) - .to_address() -} - -pub(crate) fn fake_reward_address(x: u8) -> RewardAddress { - RewardAddress::new( - NetworkInfo::testnet_preprod().network_id(), - &Credential::from_keyhash(&fake_key_hash(x)), - ) -} - -pub(crate) fn fake_tx_hash(input_hash_byte: u8) -> TransactionHash { - TransactionHash::from([input_hash_byte; 32]) -} - -pub(crate) fn fake_tx_input(input_hash_byte: u8) -> TransactionInput { - fake_tx_input2(input_hash_byte, 0) -} - -pub(crate) fn fake_tx_input2(input_hash_byte: u8, idx: TransactionIndex) -> TransactionInput { - TransactionInput::new(&fake_tx_hash(input_hash_byte), idx) -} - -pub(crate) fn fake_value() -> Value { - fake_value2(1_000_000) -} - -pub(crate) fn fake_value2(v: u64) -> Value { - Value::new(&BigNum(v)) -} - -pub(crate) fn fake_tx_output(input_hash_byte: u8) -> TransactionOutput { - TransactionOutput::new(&fake_base_address(input_hash_byte), &fake_value()) -} - -pub(crate) fn fake_tx_output2(input_hash_byte: u8, val: u64) -> TransactionOutput { - TransactionOutput::new(&fake_base_address(input_hash_byte), &fake_value2(val)) -} - -pub(crate) fn fake_vkey() -> Vkey { - Vkey::new( - &Bip32PrivateKey::generate_ed25519_bip32() - .unwrap() - .to_public() - .to_raw_key(), - ) -} - -pub(crate) fn fake_vkey_numbered(x: u8) -> Vkey { - Vkey::new(&PublicKey::from_bytes(&[x; 32]).unwrap()) -} - -pub(crate) fn fake_signature(x: u8) -> Ed25519Signature { - Ed25519Signature::from_bytes([x; 64].to_vec()).unwrap() -} - -pub(crate) fn fake_policy_id(x: u8) -> PolicyID { - PolicyID::from([x; 28]) -} - -pub(crate) fn fake_asset_name(x: u8) -> AssetName { - AssetName([x; 32].to_vec()) -} - -pub(crate) fn fake_vkey_witness(x: u8) -> Vkeywitness { - Vkeywitness::new(&fake_vkey_numbered(x), &fake_signature(x)) -} - -pub(crate) fn fake_boostrap_witness(x: u8) -> BootstrapWitness { - BootstrapWitness::new( - &fake_vkey_numbered(x), - &fake_signature(x), - vec![x; 32], - vec![x; 32], - ) -} - -pub(crate) fn fake_plutus_script_and_hash(x: u8) -> (PlutusScript, ScriptHash) { - let s = PlutusScript::new(fake_bytes_32(x)); - (s.clone(), s.hash()) -} \ No newline at end of file diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 38862e84..dfb464be 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -62,7 +62,6 @@ pub mod typed_bytes; #[macro_use] mod utils; pub use utils::*; -pub(crate) mod fakes; mod serialization; mod rational; diff --git a/rust/src/tests/address.rs b/rust/src/tests/address.rs index 46e1b33e..409b4e21 100644 --- a/rust/src/tests/address.rs +++ b/rust/src/tests/address.rs @@ -1,9 +1,5 @@ -use crate::tests::mock_objects::{ - create_base_address, create_enterprise_address, create_malformed_address, - create_pointer_address, create_reward_address, -}; +use crate::tests::mock_objects::{create_base_address, create_enterprise_address, create_malformed_address, create_pointer_address, create_reward_address, fake_key_hash}; use crate::*; -use crate::fakes::fake_key_hash; #[test] fn variable_nat_encoding() { diff --git a/rust/src/tests/builders/batch_tools.rs b/rust/src/tests/builders/batch_tools.rs index 8f515614..25caa7f0 100644 --- a/rust/src/tests/builders/batch_tools.rs +++ b/rust/src/tests/builders/batch_tools.rs @@ -1,6 +1,5 @@ -use crate::fakes::fake_policy_id; use crate::fees::{min_fee, LinearFee}; -use crate::tests::mock_objects::generate_address; +use crate::tests::mock_objects::{fake_policy_id, generate_address}; use crate::*; fn generate_assets( diff --git a/rust/src/tests/builders/certificates_builder.rs b/rust/src/tests/builders/certificates_builder.rs index db1d53a3..92f41157 100644 --- a/rust/src/tests/builders/certificates_builder.rs +++ b/rust/src/tests/builders/certificates_builder.rs @@ -1,8 +1,5 @@ -use crate::fakes::{ - fake_genesis_delegate_hash, fake_genesis_hash, fake_key_hash, fake_pool_metadata_hash, - fake_vrf_key_hash, -}; use crate::*; +use crate::tests::mock_objects::{fake_genesis_delegate_hash, fake_genesis_hash, fake_key_hash, fake_pool_metadata_hash, fake_vrf_key_hash}; #[test] fn certificates_builder_deposit_no_refund_test() { diff --git a/rust/src/tests/builders/mint_builder.rs b/rust/src/tests/builders/mint_builder.rs index 5f9173a0..0cbef087 100644 --- a/rust/src/tests/builders/mint_builder.rs +++ b/rust/src/tests/builders/mint_builder.rs @@ -1,6 +1,5 @@ use crate::*; -use crate::fakes::{fake_plutus_script_and_hash, fake_script_hash, fake_tx_input}; -use crate::tests::mock_objects::{create_reallistic_tx_builder, create_redeemer}; +use crate::tests::mock_objects::{create_reallistic_tx_builder, create_redeemer, fake_plutus_script_and_hash, fake_script_hash, fake_tx_input}; #[test] fn plutus_mint_with_script_ref_test() { diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index 6bc65e8c..9bc3ed79 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -1,6 +1,5 @@ -use crate::fakes::{fake_base_address, fake_bytes_32, fake_data_hash, fake_key_hash, fake_plutus_script_and_hash, fake_policy_id, fake_script_hash, fake_tx_hash, fake_tx_input, fake_tx_input2, fake_value, fake_value2, fake_vkey_witness}; use crate::tests::helpers::harden; -use crate::tests::mock_objects::{byron_address, create_anchor, create_change_address, create_default_tx_builder, create_linear_fee, create_reallistic_tx_builder, create_redeemer, create_redeemer_zero_cost, create_rich_tx_builder, create_tx_builder, create_tx_builder_with_amount, create_tx_builder_with_fee, create_tx_builder_with_fee_and_pure_change, create_tx_builder_with_fee_and_val_size, create_tx_builder_with_key_deposit, root_key_15}; +use crate::tests::mock_objects::{byron_address, create_anchor, create_change_address, create_default_tx_builder, create_linear_fee, create_reallistic_tx_builder, create_redeemer, create_redeemer_zero_cost, create_rich_tx_builder, create_tx_builder, create_tx_builder_with_amount, create_tx_builder_with_fee, create_tx_builder_with_fee_and_pure_change, create_tx_builder_with_fee_and_val_size, create_tx_builder_with_key_deposit, fake_base_address, fake_bytes_32, fake_data_hash, fake_key_hash, fake_plutus_script_and_hash, fake_policy_id, fake_script_hash, fake_tx_hash, fake_tx_input, fake_tx_input2, fake_value, fake_value2, fake_vkey_witness, root_key_15}; use crate::*; use crate::builders::fakes::fake_private_key; diff --git a/rust/src/tests/builders/tx_inputs_builder.rs b/rust/src/tests/builders/tx_inputs_builder.rs index 2ffe1e01..7b2d8d92 100644 --- a/rust/src/tests/builders/tx_inputs_builder.rs +++ b/rust/src/tests/builders/tx_inputs_builder.rs @@ -1,9 +1,4 @@ -use crate::fakes::{fake_key_hash, fake_script_hash, fake_tx_input}; -use crate::tests::mock_objects::{ - create_base_address, create_base_script_address, create_enterprise_address, - create_enterprise_script_address, create_plutus_script, create_pointer_address, - create_pointer_script_address, create_redeemer, create_reward_address, -}; +use crate::tests::mock_objects::{create_base_address, create_base_script_address, create_enterprise_address, create_enterprise_script_address, create_plutus_script, create_pointer_address, create_pointer_script_address, create_redeemer, create_reward_address, fake_key_hash, fake_script_hash, fake_tx_input}; use crate::*; #[test] diff --git a/rust/src/tests/builders/voting_builder.rs b/rust/src/tests/builders/voting_builder.rs index acd880e8..e4d91d00 100644 --- a/rust/src/tests/builders/voting_builder.rs +++ b/rust/src/tests/builders/voting_builder.rs @@ -1,6 +1,5 @@ -use crate::fakes::{fake_key_hash, fake_script_hash, fake_tx_hash, fake_vkey}; use crate::fees::min_fee_for_size; -use crate::tests::mock_objects::{create_change_address, create_linear_fee, create_plutus_script, create_rich_tx_builder}; +use crate::tests::mock_objects::{create_change_address, create_linear_fee, create_plutus_script, create_rich_tx_builder, fake_key_hash, fake_script_hash, fake_tx_hash, fake_vkey}; use crate::*; #[test] diff --git a/rust/src/tests/builders/voting_proposal_builder.rs b/rust/src/tests/builders/voting_proposal_builder.rs index 0ed09867..84df98b3 100644 --- a/rust/src/tests/builders/voting_proposal_builder.rs +++ b/rust/src/tests/builders/voting_proposal_builder.rs @@ -1,8 +1,4 @@ -use crate::fakes::{fake_key_hash, fake_reward_address, fake_script_hash, fake_tx_hash}; -use crate::tests::mock_objects::{ - crate_full_protocol_param_update, create_anchor, create_change_address, create_plutus_script, - create_tx_builder_with_amount_and_deposit_params, -}; +use crate::tests::mock_objects::{crate_full_protocol_param_update, create_anchor, create_change_address, create_plutus_script, create_tx_builder_with_amount_and_deposit_params, fake_key_hash, fake_reward_address, fake_script_hash, fake_tx_hash}; use crate::*; fn total_tx_output_with_fee(tx: &Transaction) -> Coin { diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index cb59310d..3eebb019 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -1,7 +1,6 @@ use crate::*; -use crate::fakes::{fake_boostrap_witness, fake_tx_input, fake_vkey_witness}; use crate::tests::helpers::harden; -use crate::tests::mock_objects::create_plutus_script; +use crate::tests::mock_objects::{create_plutus_script, fake_boostrap_witness, fake_tx_input, fake_vkey_witness}; #[test] fn native_script_hash() { diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/mock_objects.rs index d23da701..0cc0c4c0 100644 --- a/rust/src/tests/mock_objects.rs +++ b/rust/src/tests/mock_objects.rs @@ -1,7 +1,7 @@ -use crate::fakes::{fake_anchor_data_hash, fake_key_hash, fake_pool_metadata_hash, fake_script_hash, fake_tx_hash, fake_vrf_key_hash}; -use crate::fees::LinearFee; -use crate::tests::helpers::harden; +#![allow(dead_code)] + use crate::*; +use crate::tests::helpers::harden; const MAX_VALUE_SIZE: u32 = 4000; const MAX_TX_SIZE: u32 = 8000; // might be out of date but suffices for our tests @@ -509,4 +509,139 @@ pub(crate) fn create_redeemer_zero_cost(x: u8) -> Redeemer { &PlutusData::new_empty_constr_plutus_data(&BigNum::from(x)), &ExUnits::new(&BigNum::zero(), &BigNum::zero()), ) +} + + +pub(crate) fn fake_bytes_32(x: u8) -> Vec { + vec![ + x, 239, 181, 120, 142, 135, 19, 200, 68, 223, 211, 43, 46, 145, 222, 30, 48, 159, 239, 255, + 213, 85, 248, 39, 204, 158, 225, 100, 1, 2, 3, 4, + ] +} + +pub(crate) fn fake_data_hash(x: u8) -> DataHash { + DataHash::from_bytes(fake_bytes_32(x)).unwrap() +} + +pub(crate) fn fake_anchor_data_hash(x: u8) -> AnchorDataHash { + AnchorDataHash::from_bytes(fake_bytes_32(x)).unwrap() +} + +pub(crate) fn fake_auxiliary_data_hash(x: u8) -> AuxiliaryDataHash { + AuxiliaryDataHash::from_bytes(fake_bytes_32(x)).unwrap() +} + +pub(crate) fn fake_pool_metadata_hash(x: u8) -> PoolMetadataHash { + PoolMetadataHash::from_bytes(fake_bytes_32(x)).unwrap() +} + +pub(crate) fn fake_genesis_hash(x: u8) -> GenesisHash { + GenesisHash::from_bytes((&fake_bytes_32(x)[0..28]).to_vec()).unwrap() +} + +pub(crate) fn fake_genesis_delegate_hash(x: u8) -> GenesisDelegateHash { + GenesisDelegateHash::from_bytes((&fake_bytes_32(x)[0..28]).to_vec()).unwrap() +} + +pub(crate) fn fake_vrf_key_hash(x: u8) -> VRFKeyHash { + VRFKeyHash::from_bytes(fake_bytes_32(x)).unwrap() +} + +pub(crate) fn fake_key_hash(x: u8) -> Ed25519KeyHash { + Ed25519KeyHash::from_bytes((&fake_bytes_32(x)[0..28]).to_vec()).unwrap() +} + +pub(crate) fn fake_script_hash(x: u8) -> ScriptHash { + ScriptHash::from_bytes((&fake_bytes_32(x)[0..28]).to_vec()).unwrap() +} + +pub(crate) fn fake_script_data_hash(x: u8) -> ScriptDataHash { + ScriptDataHash::from_bytes(fake_bytes_32(x)).unwrap() +} + +pub(crate) fn fake_base_address(x: u8) -> Address { + BaseAddress::new( + NetworkInfo::testnet_preprod().network_id(), + &Credential::from_keyhash(&fake_key_hash(x)), + &Credential::from_keyhash(&fake_key_hash(0)), + ) + .to_address() +} + +pub(crate) fn fake_reward_address(x: u8) -> RewardAddress { + RewardAddress::new( + NetworkInfo::testnet_preprod().network_id(), + &Credential::from_keyhash(&fake_key_hash(x)), + ) +} + +pub(crate) fn fake_tx_hash(input_hash_byte: u8) -> TransactionHash { + TransactionHash::from([input_hash_byte; 32]) +} + +pub(crate) fn fake_tx_input(input_hash_byte: u8) -> TransactionInput { + fake_tx_input2(input_hash_byte, 0) +} + +pub(crate) fn fake_tx_input2(input_hash_byte: u8, idx: TransactionIndex) -> TransactionInput { + TransactionInput::new(&fake_tx_hash(input_hash_byte), idx) +} + +pub(crate) fn fake_value() -> Value { + fake_value2(1_000_000) +} + +pub(crate) fn fake_value2(v: u64) -> Value { + Value::new(&BigNum(v)) +} + +pub(crate) fn fake_tx_output(input_hash_byte: u8) -> TransactionOutput { + TransactionOutput::new(&fake_base_address(input_hash_byte), &fake_value()) +} + +pub(crate) fn fake_tx_output2(input_hash_byte: u8, val: u64) -> TransactionOutput { + TransactionOutput::new(&fake_base_address(input_hash_byte), &fake_value2(val)) +} + +pub(crate) fn fake_vkey() -> Vkey { + Vkey::new( + &Bip32PrivateKey::generate_ed25519_bip32() + .unwrap() + .to_public() + .to_raw_key(), + ) +} + +pub(crate) fn fake_vkey_numbered(x: u8) -> Vkey { + Vkey::new(&PublicKey::from_bytes(&[x; 32]).unwrap()) +} + +pub(crate) fn fake_signature(x: u8) -> Ed25519Signature { + Ed25519Signature::from_bytes([x; 64].to_vec()).unwrap() +} + +pub(crate) fn fake_policy_id(x: u8) -> PolicyID { + PolicyID::from([x; 28]) +} + +pub(crate) fn fake_asset_name(x: u8) -> AssetName { + AssetName([x; 32].to_vec()) +} + +pub(crate) fn fake_vkey_witness(x: u8) -> Vkeywitness { + Vkeywitness::new(&fake_vkey_numbered(x), &fake_signature(x)) +} + +pub(crate) fn fake_boostrap_witness(x: u8) -> BootstrapWitness { + BootstrapWitness::new( + &fake_vkey_numbered(x), + &fake_signature(x), + vec![x; 32], + vec![x; 32], + ) +} + +pub(crate) fn fake_plutus_script_and_hash(x: u8) -> (PlutusScript, ScriptHash) { + let s = PlutusScript::new(fake_bytes_32(x)); + (s.clone(), s.hash()) } \ No newline at end of file diff --git a/rust/src/tests/protocol_types/certificates.rs b/rust/src/tests/protocol_types/certificates.rs index 567199c7..b86fc762 100644 --- a/rust/src/tests/protocol_types/certificates.rs +++ b/rust/src/tests/protocol_types/certificates.rs @@ -1,8 +1,4 @@ -use crate::fakes::{ - fake_genesis_delegate_hash, fake_genesis_hash, fake_key_hash, fake_script_hash, - fake_vrf_key_hash, -}; -use crate::tests::mock_objects::{crate_full_pool_params, create_anchor}; +use crate::tests::mock_objects::{crate_full_pool_params, create_anchor, fake_genesis_delegate_hash, fake_genesis_hash, fake_key_hash, fake_script_hash, fake_vrf_key_hash}; use crate::*; #[test] diff --git a/rust/src/tests/protocol_types/governance/common.rs b/rust/src/tests/protocol_types/governance/common.rs index 460f4d27..03cb74d3 100644 --- a/rust/src/tests/protocol_types/governance/common.rs +++ b/rust/src/tests/protocol_types/governance/common.rs @@ -1,5 +1,4 @@ -use crate::fakes::{fake_anchor_data_hash, fake_key_hash, fake_script_hash, fake_tx_hash}; -use crate::tests::mock_objects::create_anchor; +use crate::tests::mock_objects::{create_anchor, fake_anchor_data_hash, fake_key_hash, fake_script_hash, fake_tx_hash}; use crate::*; #[test] diff --git a/rust/src/tests/protocol_types/governance/proposals.rs b/rust/src/tests/protocol_types/governance/proposals.rs index 1f05bb29..62639fdc 100644 --- a/rust/src/tests/protocol_types/governance/proposals.rs +++ b/rust/src/tests/protocol_types/governance/proposals.rs @@ -1,7 +1,4 @@ -use crate::fakes::{fake_key_hash, fake_reward_address, fake_script_hash}; -use crate::tests::mock_objects::{ - crate_full_protocol_param_update, create_action_id, create_anchor, -}; +use crate::tests::mock_objects::{crate_full_protocol_param_update, create_action_id, create_anchor, fake_key_hash, fake_reward_address, fake_script_hash}; use crate::*; use itertools::Itertools; diff --git a/rust/src/tests/serialization/certificates.rs b/rust/src/tests/serialization/certificates.rs index a05a2680..6fd95b90 100644 --- a/rust/src/tests/serialization/certificates.rs +++ b/rust/src/tests/serialization/certificates.rs @@ -1,8 +1,4 @@ -use crate::fakes::{ - fake_anchor_data_hash, fake_genesis_delegate_hash, fake_genesis_hash, fake_key_hash, - fake_pool_metadata_hash, fake_script_hash, fake_vrf_key_hash, -}; -use crate::tests::mock_objects::create_anchor; +use crate::tests::mock_objects::{create_anchor, fake_anchor_data_hash, fake_genesis_delegate_hash, fake_genesis_hash, fake_key_hash, fake_pool_metadata_hash, fake_script_hash, fake_vrf_key_hash}; use crate::*; macro_rules! to_from_test { diff --git a/rust/src/tests/serialization/general.rs b/rust/src/tests/serialization/general.rs index 7f6e93b0..d72efff7 100644 --- a/rust/src/tests/serialization/general.rs +++ b/rust/src/tests/serialization/general.rs @@ -1,7 +1,7 @@ use crate::{Address, BigInt, BigNum, Block, BlockHash, CborContainerType, Coin, Credential, DataHash, ExUnits, HeaderBody, HeaderLeaderCertEnum, Int, KESVKey, MIRPot, MIRToStakeCredentials, MoveInstantaneousReward, NativeScript, OperationalCert, PlutusData, PlutusList, PlutusScript, PlutusScripts, ProtocolVersion, Redeemer, RedeemerTag, Redeemers, ScriptHash, ScriptRef, TimelockStart, TransactionBody, TransactionInputs, TransactionOutput, TransactionOutputs, TransactionWitnessSet, VRFCert, VRFVKey, Value, Vkeywitness, Vkeywitnesses, VersionedBlock, BlockEra, to_bytes, BootstrapWitnesses, Credentials, Ed25519KeyHashes}; -use crate::fakes::{fake_base_address, fake_boostrap_witness, fake_bytes_32, fake_data_hash, fake_key_hash, fake_signature, fake_tx_input, fake_tx_output, fake_value, fake_value2, fake_vkey, fake_vkey_witness}; use crate::protocol_types::ScriptRefEnum; +use crate::tests::mock_objects::{fake_base_address, fake_boostrap_witness, fake_bytes_32, fake_data_hash, fake_key_hash, fake_signature, fake_tx_input, fake_tx_output, fake_value, fake_value2, fake_vkey, fake_vkey_witness}; #[test] fn tx_output_deser_lagacy() { diff --git a/rust/src/tests/serialization/governance/common.rs b/rust/src/tests/serialization/governance/common.rs index c7a8a266..11505e1b 100644 --- a/rust/src/tests/serialization/governance/common.rs +++ b/rust/src/tests/serialization/governance/common.rs @@ -1,5 +1,5 @@ -use crate::fakes::{fake_anchor_data_hash, fake_key_hash, fake_script_hash, fake_tx_hash}; use crate::*; +use crate::tests::mock_objects::{fake_anchor_data_hash, fake_key_hash, fake_script_hash, fake_tx_hash}; #[test] fn anchor_ser_round_trip() { diff --git a/rust/src/tests/serialization/governance/proposals.rs b/rust/src/tests/serialization/governance/proposals.rs index 4fc85ce4..feba07d7 100644 --- a/rust/src/tests/serialization/governance/proposals.rs +++ b/rust/src/tests/serialization/governance/proposals.rs @@ -1,7 +1,4 @@ -use crate::fakes::{ - fake_anchor_data_hash, fake_key_hash, fake_reward_address, fake_script_hash, fake_tx_hash, -}; -use crate::tests::mock_objects::{crate_full_protocol_param_update, create_anchor}; +use crate::tests::mock_objects::{crate_full_protocol_param_update, create_anchor, fake_anchor_data_hash, fake_key_hash, fake_reward_address, fake_script_hash, fake_tx_hash}; use crate::*; macro_rules! to_from_test { diff --git a/rust/src/tests/serialization/transaction_body.rs b/rust/src/tests/serialization/transaction_body.rs index eb184845..3118fc8a 100644 --- a/rust/src/tests/serialization/transaction_body.rs +++ b/rust/src/tests/serialization/transaction_body.rs @@ -1,6 +1,5 @@ -use crate::fakes::{fake_asset_name, fake_auxiliary_data_hash, fake_base_address, fake_key_hash, fake_policy_id, fake_reward_address, fake_script_data_hash, fake_tx_hash, fake_tx_input}; use crate::*; -use crate::tests::mock_objects::create_anchor; +use crate::tests::mock_objects::{create_anchor, fake_asset_name, fake_auxiliary_data_hash, fake_base_address, fake_key_hash, fake_policy_id, fake_reward_address, fake_script_data_hash, fake_tx_hash, fake_tx_input}; #[test] fn transaction_round_trip_test() { From 39007857a5a10f3d8b5e4413d3d61899d89f5944 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 24 Jun 2024 19:03:13 +0700 Subject: [PATCH 306/349] fakes generator functions unification --- rust/src/builders/mod.rs | 2 +- rust/src/tests/address.rs | 16 +- rust/src/tests/builders/batch_tools.rs | 50 +-- .../tests/builders/certificates_builder.rs | 2 +- rust/src/tests/builders/mint_builder.rs | 28 +- rust/src/tests/builders/tx_builder.rs | 386 +++++++++--------- rust/src/tests/builders/tx_inputs_builder.rs | 26 +- rust/src/tests/builders/voting_builder.rs | 28 +- .../tests/builders/voting_proposal_builder.rs | 48 +-- rust/src/tests/{mock_objects.rs => fakes.rs} | 189 ++++----- rust/src/tests/general.rs | 46 +-- rust/src/tests/mod.rs | 2 +- rust/src/tests/protocol_types/certificates.rs | 8 +- .../tests/protocol_types/governance/common.rs | 4 +- .../protocol_types/governance/proposals.rs | 30 +- rust/src/tests/serialization/certificates.rs | 4 +- rust/src/tests/serialization/general.rs | 2 +- .../tests/serialization/governance/common.rs | 2 +- .../serialization/governance/proposals.rs | 16 +- .../serialization/protocol_param_update.rs | 8 +- .../tests/serialization/transaction_body.rs | 4 +- 21 files changed, 438 insertions(+), 463 deletions(-) rename rust/src/tests/{mock_objects.rs => fakes.rs} (81%) diff --git a/rust/src/builders/mod.rs b/rust/src/builders/mod.rs index dc1d7ffe..d32aa4f5 100644 --- a/rust/src/builders/mod.rs +++ b/rust/src/builders/mod.rs @@ -33,4 +33,4 @@ pub use tx_builder::*; mod tx_builder_constants; pub use tx_builder_constants::*; -pub(crate) mod fakes; +pub mod fakes; diff --git a/rust/src/tests/address.rs b/rust/src/tests/address.rs index 409b4e21..b7967058 100644 --- a/rust/src/tests/address.rs +++ b/rust/src/tests/address.rs @@ -1,4 +1,4 @@ -use crate::tests::mock_objects::{create_base_address, create_enterprise_address, create_malformed_address, create_pointer_address, create_reward_address, fake_key_hash}; +use crate::tests::fakes::{fake_base_address, fake_enterprise_address, fake_malformed_address, fake_pointer_address, fake_reward_address, fake_key_hash}; use crate::*; #[test] @@ -582,16 +582,16 @@ fn malformed_addres_embedded() { #[test] fn address_kind() { - let base_address = create_base_address(1); + let base_address = fake_base_address(1); assert_eq!(base_address.kind(), AddressKind::Base); - let pointer_address = create_pointer_address(2); + let pointer_address = fake_pointer_address(2); assert_eq!(pointer_address.kind(), AddressKind::Pointer); - let enterprise_address = create_enterprise_address(3); + let enterprise_address = fake_enterprise_address(3); assert_eq!(enterprise_address.kind(), AddressKind::Enterprise); - let reward_address = create_reward_address(4); + let reward_address = fake_reward_address(4).to_address(); assert_eq!(reward_address.kind(), AddressKind::Reward); let byron_address = @@ -600,7 +600,7 @@ fn address_kind() { .to_address(); assert_eq!(byron_address.kind(), AddressKind::Byron); - let malformed_address = create_malformed_address(); + let malformed_address = fake_malformed_address(); assert_eq!(malformed_address.kind(), AddressKind::Malformed); } @@ -650,7 +650,7 @@ fn address_payment_cred() { .to_address(); assert_eq!(byron_address.payment_cred(), None); - let malformed_address = create_malformed_address(); + let malformed_address = fake_malformed_address(); assert_eq!(malformed_address.payment_cred(), None); } @@ -693,6 +693,6 @@ fn addresses_network_id() { assert_eq!(byron_address.network_id().unwrap(), 1); assert_eq!(byron_address.to_address().network_id().unwrap(), 1); - let malformed_address = create_malformed_address(); + let malformed_address = fake_malformed_address(); assert!(malformed_address.network_id().is_err()); } diff --git a/rust/src/tests/builders/batch_tools.rs b/rust/src/tests/builders/batch_tools.rs index 25caa7f0..e72be558 100644 --- a/rust/src/tests/builders/batch_tools.rs +++ b/rust/src/tests/builders/batch_tools.rs @@ -1,5 +1,5 @@ use crate::fees::{min_fee, LinearFee}; -use crate::tests::mock_objects::{fake_policy_id, generate_address}; +use crate::tests::fakes::{fake_policy_id, fake_base_address}; use crate::*; fn generate_assets( @@ -63,8 +63,8 @@ fn generate_utxo( fn generate_big_ada_utoxs_bacth() -> TransactionUnspentOutputs { let mut utxos = Vec::new(); - let address = generate_address(1); - let address_2 = generate_address(2); + let address = fake_base_address(1); + let address_2 = fake_base_address(2); for i in 0..10 { let utxo = generate_utxo( &address, @@ -99,8 +99,8 @@ fn generate_big_ada_utoxs_bacth() -> TransactionUnspentOutputs { fn generate_big_utoxs_bacth() -> TransactionUnspentOutputs { let mut utxos = Vec::new(); - let address = generate_address(1); - let address_2 = generate_address(2); + let address = fake_base_address(1); + let address_2 = fake_base_address(2); for i in 0..200 { let utxo = generate_utxo( &address, @@ -229,7 +229,7 @@ pub fn test_big_utoxs_batch() { .build() .unwrap(); - let res = create_send_all(&generate_address(10000), &utxos, &cfg); + let res = create_send_all(&fake_base_address(10000), &utxos, &cfg); assert!(res.is_ok()); let batches = res.unwrap(); @@ -258,7 +258,7 @@ pub fn test_big_utoxs_ada_batch() { .build() .unwrap(); - let res = create_send_all(&generate_address(10000), &utxos, &cfg); + let res = create_send_all(&fake_base_address(10000), &utxos, &cfg); assert!(res.is_ok()); let batches = res.unwrap(); @@ -271,7 +271,7 @@ pub fn test_big_utoxs_ada_batch() { #[test] pub fn test_one_utxo() { - let address = generate_address(1); + let address = fake_base_address(1); let utxo = generate_utxo( &address, 1, @@ -301,7 +301,7 @@ pub fn test_one_utxo() { .build() .unwrap(); - let res = create_send_all(&generate_address(10000), &utxos, &cfg); + let res = create_send_all(&fake_base_address(10000), &utxos, &cfg); assert!(res.is_ok()); let batches = res.unwrap(); @@ -314,7 +314,7 @@ pub fn test_one_utxo() { #[test] pub fn test_one_utxo_one_asset_per_output() { - let address = generate_address(1); + let address = fake_base_address(1); let utxo_1 = generate_utxo( &address, 1, @@ -368,7 +368,7 @@ pub fn test_one_utxo_one_asset_per_output() { .build() .unwrap(); - let res = create_send_all(&generate_address(10000), &utxos, &cfg); + let res = create_send_all(&fake_base_address(10000), &utxos, &cfg); assert!(res.is_ok()); let batches = res.unwrap(); @@ -393,7 +393,7 @@ pub fn test_one_utxo_one_asset_per_output() { #[test] pub fn test_one_utxo_one_asset_per_tx() { - let address = generate_address(1); + let address = fake_base_address(1); let utxo_1 = generate_utxo( &address, 1, @@ -447,7 +447,7 @@ pub fn test_one_utxo_one_asset_per_tx() { .build() .unwrap(); - let res = create_send_all(&generate_address(10000), &utxos, &cfg); + let res = create_send_all(&fake_base_address(10000), &utxos, &cfg); assert!(res.is_ok()); let batches = res.unwrap(); @@ -473,7 +473,7 @@ pub fn test_one_utxo_one_asset_per_tx() { #[test] pub fn test_only_ada_utxo() { - let address = generate_address(1); + let address = fake_base_address(1); let utxo = generate_utxo( &address, 1, @@ -503,7 +503,7 @@ pub fn test_only_ada_utxo() { .build() .unwrap(); - let res = create_send_all(&generate_address(10000), &utxos, &cfg); + let res = create_send_all(&fake_base_address(10000), &utxos, &cfg); assert!(res.is_ok()); let batches = res.unwrap(); @@ -516,7 +516,7 @@ pub fn test_only_ada_utxo() { #[test] pub fn test_not_enough_ada() { - let address = generate_address(1); + let address = fake_base_address(1); let utxo = generate_utxo(&address, 1, 0, 0, 0, 0, 20, Coin::zero(), Coin::from(1u64)); let utxos = TransactionUnspentOutputs(vec![utxo]); @@ -536,13 +536,13 @@ pub fn test_not_enough_ada() { .build() .unwrap(); - let res = create_send_all(&generate_address(10000), &utxos, &cfg); + let res = create_send_all(&fake_base_address(10000), &utxos, &cfg); assert!(res.is_err()); } #[test] pub fn test_value_limit_error() { - let address = generate_address(1); + let address = fake_base_address(1); let utxo = generate_utxo( &address, 1, @@ -572,13 +572,13 @@ pub fn test_value_limit_error() { .build() .unwrap(); - let res = create_send_all(&generate_address(10000), &utxos, &cfg); + let res = create_send_all(&fake_base_address(10000), &utxos, &cfg); assert!(res.is_err()); } #[test] pub fn test_tx_limit_error() { - let address = generate_address(1); + let address = fake_base_address(1); let utxo = generate_utxo( &address, 1, @@ -608,7 +608,7 @@ pub fn test_tx_limit_error() { .build() .unwrap(); - let res = create_send_all(&generate_address(10000), &utxos, &cfg); + let res = create_send_all(&fake_base_address(10000), &utxos, &cfg); assert!(res.is_err()); } @@ -631,7 +631,7 @@ pub fn test_no_utxos() { .build() .unwrap(); - let res = create_send_all(&generate_address(10000), &utxos, &cfg); + let res = create_send_all(&fake_base_address(10000), &utxos, &cfg); assert!(res.is_ok()); let batches = res.unwrap(); @@ -660,13 +660,13 @@ pub fn test_script_input_error() { .build() .unwrap(); - let res = create_send_all(&generate_address(10000), &utxos, &cfg); + let res = create_send_all(&fake_base_address(10000), &utxos, &cfg); assert!(res.is_err()); } #[test] pub fn test_two_asset_utxo_one_ada_utxo() { - let address = generate_address(1); + let address = fake_base_address(1); let asset_utxo_1 = generate_utxo( &address, 1, @@ -720,7 +720,7 @@ pub fn test_two_asset_utxo_one_ada_utxo() { .build() .unwrap(); - let res = create_send_all(&generate_address(10000), &utxos, &cfg); + let res = create_send_all(&fake_base_address(10000), &utxos, &cfg); assert!(res.is_ok()); let batches = res.unwrap(); diff --git a/rust/src/tests/builders/certificates_builder.rs b/rust/src/tests/builders/certificates_builder.rs index 92f41157..69827ad5 100644 --- a/rust/src/tests/builders/certificates_builder.rs +++ b/rust/src/tests/builders/certificates_builder.rs @@ -1,5 +1,5 @@ use crate::*; -use crate::tests::mock_objects::{fake_genesis_delegate_hash, fake_genesis_hash, fake_key_hash, fake_pool_metadata_hash, fake_vrf_key_hash}; +use crate::tests::fakes::{fake_genesis_delegate_hash, fake_genesis_hash, fake_key_hash, fake_pool_metadata_hash, fake_vrf_key_hash}; #[test] fn certificates_builder_deposit_no_refund_test() { diff --git a/rust/src/tests/builders/mint_builder.rs b/rust/src/tests/builders/mint_builder.rs index 0cbef087..0befb6b9 100644 --- a/rust/src/tests/builders/mint_builder.rs +++ b/rust/src/tests/builders/mint_builder.rs @@ -1,9 +1,9 @@ use crate::*; -use crate::tests::mock_objects::{create_reallistic_tx_builder, create_redeemer, fake_plutus_script_and_hash, fake_script_hash, fake_tx_input}; +use crate::tests::fakes::{fake_reallistic_tx_builder, fake_redeemer, fake_plutus_script_and_hash, fake_script_hash, fake_tx_input}; #[test] fn plutus_mint_with_script_ref_test() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); let colateral_adress = Address::from_bech32("addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w").unwrap(); let colateral_input = fake_tx_input(0); let tx_input = fake_tx_input(1); @@ -13,9 +13,9 @@ fn plutus_mint_with_script_ref_test() { let (plutus_script2, _) = fake_plutus_script_and_hash(2); - let redeemer = create_redeemer(1); + let redeemer = fake_redeemer(1); - let redeemer2 = create_redeemer(2); + let redeemer2 = fake_redeemer(2); let asset_name = AssetName::from_hex("44544e4654").unwrap(); let mut mint_builder = MintBuilder::new(); @@ -80,8 +80,8 @@ fn plutus_mint_with_script_ref_test() { #[test] fn different_redeemers_error() { let (plutus_script, _) = fake_plutus_script_and_hash(1); - let redeemer = create_redeemer(1); - let redeemer2 = create_redeemer(2); + let redeemer = fake_redeemer(1); + let redeemer2 = fake_redeemer(2); let asset_name = AssetName::from_hex("44544e4654").unwrap(); let mut mint_builder = MintBuilder::new(); @@ -99,7 +99,7 @@ fn different_redeemers_error() { #[test] fn same_redeemers() { let (plutus_script, _) = fake_plutus_script_and_hash(1); - let redeemer = create_redeemer(1); + let redeemer = fake_redeemer(1); let mut redeemer2 = redeemer.clone(); redeemer2.index = BigNum::from(77u64); redeemer2.tag = RedeemerTag::new_voting_proposal(); @@ -120,14 +120,14 @@ fn same_redeemers() { #[test] fn plutus_mint_test() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); let colateral_adress = Address::from_bech32("addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w").unwrap(); let colateral_input = fake_tx_input(0); let tx_input = fake_tx_input(1); let (plutus_script, _) = fake_plutus_script_and_hash(1); - let redeemer = create_redeemer(1); + let redeemer = fake_redeemer(1); let asset_name = AssetName::from_hex("44544e4654").unwrap(); let mut mint_builder = MintBuilder::new(); let plutus_script_source = PlutusScriptSource::new(&plutus_script); @@ -183,7 +183,7 @@ fn ref_inputs() { let script_hash_2 = fake_script_hash(2); let tx_input_ref1 = fake_tx_input(2); let tx_input_ref2 = fake_tx_input(3); - let redeemer = create_redeemer(1); + let redeemer = fake_redeemer(1); let asset_name1 = AssetName::from_hex("44544e4654").unwrap(); let asset_name2 = AssetName::from_hex("44544e4655").unwrap(); @@ -219,7 +219,7 @@ fn multiple_mints() { let script_hash_2 = fake_script_hash(2); let tx_input_ref1 = fake_tx_input(2); let tx_input_ref2 = fake_tx_input(3); - let redeemer = create_redeemer(1); + let redeemer = fake_redeemer(1); let asset_name1 = AssetName::from_hex("44544e4654").unwrap(); let asset_name2 = AssetName::from_hex("44544e4655").unwrap(); @@ -302,7 +302,7 @@ fn different_script_type_error() { let script_hash_2 = fake_script_hash(2); let tx_input_ref1 = fake_tx_input(2); let tx_input_ref2 = fake_tx_input(3); - let redeemer = create_redeemer(1); + let redeemer = fake_redeemer(1); let asset_name1 = AssetName::from_hex("44544e4654").unwrap(); let asset_name2 = AssetName::from_hex("44544e4655").unwrap(); @@ -354,7 +354,7 @@ fn wrong_witness_type_ref_error() { let script_hash_2 = native_script.hash(); let tx_input_ref1 = fake_tx_input(2); let tx_input_ref2 = fake_tx_input(3); - let redeemer = create_redeemer(1); + let redeemer = fake_redeemer(1); let asset_name1 = AssetName::from_hex("44544e4654").unwrap(); let asset_name2 = AssetName::from_hex("44544e4655").unwrap(); @@ -423,7 +423,7 @@ fn wrong_witness_type_no_ref_error() { let script_hash_2 = native_script.hash(); let tx_input_ref1 = fake_tx_input(2); let tx_input_ref2 = fake_tx_input(3); - let redeemer = create_redeemer(1); + let redeemer = fake_redeemer(1); let asset_name1 = AssetName::from_hex("44544e4654").unwrap(); let asset_name2 = AssetName::from_hex("44544e4655").unwrap(); diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index 9bc3ed79..376f688c 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -1,5 +1,5 @@ use crate::tests::helpers::harden; -use crate::tests::mock_objects::{byron_address, create_anchor, create_change_address, create_default_tx_builder, create_linear_fee, create_reallistic_tx_builder, create_redeemer, create_redeemer_zero_cost, create_rich_tx_builder, create_tx_builder, create_tx_builder_with_amount, create_tx_builder_with_fee, create_tx_builder_with_fee_and_pure_change, create_tx_builder_with_fee_and_val_size, create_tx_builder_with_key_deposit, fake_base_address, fake_bytes_32, fake_data_hash, fake_key_hash, fake_plutus_script_and_hash, fake_policy_id, fake_script_hash, fake_tx_hash, fake_tx_input, fake_tx_input2, fake_value, fake_value2, fake_vkey_witness, root_key_15}; +use crate::tests::fakes::{fake_byron_address, fake_anchor, fake_change_address, fake_default_tx_builder, fake_linear_fee, fake_reallistic_tx_builder, fake_redeemer, fake_redeemer_zero_cost, fake_rich_tx_builder, fake_tx_builder, fake_tx_builder_with_amount, fake_tx_builder_with_fee, fake_tx_builder_with_fee_and_pure_change, fake_tx_builder_with_fee_and_val_size, fake_tx_builder_with_key_deposit, fake_base_address, fake_bytes_32, fake_data_hash, fake_key_hash, fake_plutus_script_and_hash, fake_policy_id, fake_script_hash, fake_tx_hash, fake_tx_input, fake_tx_input2, fake_value, fake_value2, fake_vkey_witness, fake_root_key_15, fake_base_address_with_payment_cred}; use crate::*; use crate::builders::fakes::fake_private_key; @@ -27,22 +27,22 @@ fn check_fake_private_key() { #[test] fn build_tx_with_change() { - let mut tx_builder = create_default_tx_builder(); - let spend = root_key_15() + let mut tx_builder = fake_default_tx_builder(); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let change_key = root_key_15() + let change_key = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(1) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -105,15 +105,15 @@ fn build_tx_with_change() { #[test] fn build_tx_with_change_with_datum() { - let mut tx_builder = create_default_tx_builder(); - let spend = root_key_15() + let mut tx_builder = fake_default_tx_builder(); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -179,22 +179,22 @@ fn build_tx_with_change_with_datum() { #[test] fn build_tx_without_change() { - let mut tx_builder = create_default_tx_builder(); - let spend = root_key_15() + let mut tx_builder = fake_default_tx_builder(); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let change_key = root_key_15() + let change_key = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(1) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -255,22 +255,22 @@ fn build_tx_without_change() { #[test] fn build_tx_with_certs() { - let mut tx_builder = create_tx_builder_with_key_deposit(1_000_000); - let spend = root_key_15() + let mut tx_builder = fake_tx_builder_with_key_deposit(1_000_000); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let change_key = root_key_15() + let change_key = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(1) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -328,22 +328,22 @@ fn build_tx_with_certs() { #[test] fn build_tx_exact_amount() { // transactions where sum(input) == sum(output) exact should pass - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 0)); - let spend = root_key_15() + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(0, 0)); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let change_key = root_key_15() + let change_key = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(1) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -392,22 +392,22 @@ fn build_tx_exact_amount() { #[test] fn build_tx_exact_change() { // transactions where we have exactly enough ADA to add change should pass - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 0)); - let spend = root_key_15() + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(0, 0)); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let change_key = root_key_15() + let change_key = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(1) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -458,22 +458,22 @@ fn build_tx_exact_change() { #[should_panic] fn build_tx_insufficient_deposit() { // transactions should fail with insufficient fees if a deposit is required - let mut tx_builder = create_tx_builder_with_key_deposit(5); - let spend = root_key_15() + let mut tx_builder = fake_tx_builder_with_key_deposit(5); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let change_key = root_key_15() + let change_key = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(1) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -526,15 +526,15 @@ fn build_tx_insufficient_deposit() { #[test] fn build_tx_with_inputs() { - let mut tx_builder = create_default_tx_builder(); - let spend = root_key_15() + let mut tx_builder = fake_default_tx_builder(); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -600,7 +600,7 @@ fn build_tx_with_inputs() { #[test] fn add_ref_inputs_to_builder() { - let mut tx_builder = create_default_tx_builder(); + let mut tx_builder = fake_default_tx_builder(); tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 1)); tx_builder.add_reference_input(&TransactionInput::new(&genesis_id(), 2)); @@ -612,22 +612,22 @@ fn add_ref_inputs_to_builder() { #[test] fn build_tx_with_script_ref() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); - let spend = root_key_15() + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(0, 1)); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let change_key = root_key_15() + let change_key = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(1) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -693,22 +693,22 @@ fn build_tx_with_script_ref() { #[test] fn serialization_tx_body_with_script_ref() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); - let spend = root_key_15() + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(0, 1)); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let change_key = root_key_15() + let change_key = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(1) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -774,22 +774,22 @@ fn serialization_tx_body_with_script_ref() { #[test] fn json_serialization_tx_body_with_script_ref() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); - let spend = root_key_15() + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(0, 1)); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let change_key = root_key_15() + let change_key = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(1) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -857,22 +857,22 @@ fn json_serialization_tx_body_with_script_ref() { #[test] fn build_tx_with_mint_all_sent() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); - let spend = root_key_15() + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(0, 1)); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let change_key = root_key_15() + let change_key = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(1) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -946,22 +946,22 @@ fn build_tx_with_mint_all_sent() { #[test] fn build_tx_with_mint_in_change() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); - let spend = root_key_15() + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(0, 1)); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let change_key = root_key_15() + let change_key = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(1) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -1044,22 +1044,22 @@ fn build_tx_with_mint_in_change() { #[test] fn change_with_input_and_mint_not_enough_ada() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(1, 1)); - let spend = root_key_15() + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(1, 1)); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let change_key = root_key_15() + let change_key = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(1) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -1142,22 +1142,22 @@ fn change_with_input_and_mint_not_enough_ada() { #[test] fn change_with_input_and_mint_not_enough_assets() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(1, 1)); - let spend = root_key_15() + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(1, 1)); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let change_key = root_key_15() + let change_key = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(1) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -1240,22 +1240,22 @@ fn change_with_input_and_mint_not_enough_assets() { #[test] fn build_tx_with_native_assets_change() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); - let spend = root_key_15() + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(0, 1)); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let change_key = root_key_15() + let change_key = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(1) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -1355,22 +1355,22 @@ fn build_tx_with_native_assets_change() { fn build_tx_with_native_assets_change_and_purification() { let coin_per_utxo_byte = BigNum(1); // Prefer pure change! - let mut tx_builder = create_tx_builder_with_fee_and_pure_change(&create_linear_fee(0, 1)); - let spend = root_key_15() + let mut tx_builder = fake_tx_builder_with_fee_and_pure_change(&fake_linear_fee(0, 1)); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let change_key = root_key_15() + let change_key = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(1) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -1481,22 +1481,22 @@ fn build_tx_with_native_assets_change_and_purification() { #[test] fn build_tx_with_native_assets_change_and_no_purification_cuz_not_enough_pure_coin() { // Prefer pure change! - let mut tx_builder = create_tx_builder_with_fee_and_pure_change(&create_linear_fee(1, 1)); - let spend = root_key_15() + let mut tx_builder = fake_tx_builder_with_fee_and_pure_change(&fake_linear_fee(1, 1)); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let change_key = root_key_15() + let change_key = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(1) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -1598,22 +1598,22 @@ fn build_tx_with_native_assets_change_and_no_purification_cuz_not_enough_pure_co #[test] #[should_panic] fn build_tx_leftover_assets() { - let mut tx_builder = create_default_tx_builder(); - let spend = root_key_15() + let mut tx_builder = fake_default_tx_builder(); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let change_key = root_key_15() + let change_key = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(1) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -1688,7 +1688,7 @@ fn build_tx_leftover_assets() { #[test] fn build_tx_burn_less_than_min_ada() { // with this mainnet value we should end up with a final min_ada_required of just under 1_000_000 - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); let output_addr = ByronAddress::from_base58("Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b") @@ -1738,7 +1738,7 @@ fn build_tx_burn_less_than_min_ada() { #[test] fn build_tx_burn_empty_assets() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); let output_addr = ByronAddress::from_base58("Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b") @@ -1792,7 +1792,7 @@ fn build_tx_burn_empty_assets() { #[test] fn build_tx_no_useless_multiasset() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); let policy_id = &PolicyID::from([0u8; 28]); let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap(); @@ -1882,7 +1882,7 @@ fn create_multiasset() -> (MultiAsset, [ScriptHash; 3], [AssetName; 3]) { fn build_tx_add_change_split_nfts() { let max_value_size = 100; // super low max output size to test with fewer assets let mut tx_builder = - create_tx_builder_with_fee_and_val_size(&create_linear_fee(0, 1), max_value_size); + fake_tx_builder_with_fee_and_val_size(&fake_linear_fee(0, 1), max_value_size); let (multiasset, policy_ids, names) = create_multiasset(); @@ -1947,7 +1947,7 @@ fn build_tx_add_change_split_nfts() { #[test] fn build_tx_too_big_output() { - let mut tx_builder = create_tx_builder_with_fee_and_val_size(&create_linear_fee(0, 1), 10); + let mut tx_builder = fake_tx_builder_with_fee_and_val_size(&fake_linear_fee(0, 1), 10); tx_builder.add_regular_input( &ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") @@ -1979,8 +1979,8 @@ fn build_tx_too_big_output() { #[test] fn build_tx_add_change_nfts_not_enough_ada() { - let mut tx_builder = create_tx_builder_with_fee_and_val_size( - &create_linear_fee(0, 1), + let mut tx_builder = fake_tx_builder_with_fee_and_val_size( + &fake_linear_fee(0, 1), 150, // super low max output size to test with fewer assets ); @@ -2063,7 +2063,7 @@ fn make_input(input_hash_byte: u8, value: Value) -> TransactionUnspentOutput { #[test] fn tx_builder_cip2_largest_first_increasing_fees() { // we have a = 1 to test increasing fees when more inputs are added - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(1, 0)); + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(1, 0)); tx_builder .add_output( &TransactionOutputBuilder::new() @@ -2108,7 +2108,7 @@ fn tx_builder_cip2_largest_first_increasing_fees() { #[test] fn tx_builder_cip2_largest_first_static_fees() { // we have a = 0 so we know adding inputs/outputs doesn't change the fee so we can analyze more - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 0)); + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(0, 0)); tx_builder .add_output( &TransactionOutputBuilder::new() @@ -2152,7 +2152,7 @@ fn tx_builder_cip2_largest_first_static_fees() { #[test] fn tx_builder_cip2_largest_first_multiasset() { // we have a = 0 so we know adding inputs/outputs doesn't change the fee so we can analyze more - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 0)); + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(0, 0)); let pid1 = PolicyID::from([1u8; 28]); let pid2 = PolicyID::from([2u8; 28]); let asset_name1 = AssetName::new(vec![1u8; 8]).unwrap(); @@ -2269,7 +2269,7 @@ fn tx_builder_cip2_largest_first_multiasset() { #[test] fn tx_builder_cip2_random_improve_multiasset() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 0)); + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(0, 0)); let pid1 = PolicyID::from([1u8; 28]); let pid2 = PolicyID::from([2u8; 28]); let asset_name1 = AssetName::new(vec![1u8; 8]).unwrap(); @@ -2377,7 +2377,7 @@ fn tx_builder_cip2_random_improve_multiasset() { #[test] fn tx_builder_cip2_random_improve() { // we have a = 1 to test increasing fees when more inputs are added - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(1, 0)); + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(1, 0)); const COST: u64 = 10000; tx_builder .add_output( @@ -2531,8 +2531,8 @@ fn tx_builder_cip2_random_improve_adds_enough_for_fees() { #[test] fn build_tx_pay_to_multisig() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(10, 2)); - let spend = root_key_15() + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(10, 2)); + let spend = fake_root_key_15() .derive(harden(1854)) .derive(harden(1815)) .derive(harden(0)) @@ -2540,7 +2540,7 @@ fn build_tx_pay_to_multisig() { .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -2607,16 +2607,16 @@ fn build_full_tx( #[test] fn build_tx_multisig_spend_1on1_unsigned() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(10, 2)); + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(10, 2)); - let spend = root_key_15() //multisig + let spend = fake_root_key_15() //multisig .derive(harden(1854)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let stake = root_key_15() //multisig + let stake = fake_root_key_15() //multisig .derive(harden(1854)) .derive(harden(1815)) .derive(harden(0)) @@ -2624,7 +2624,7 @@ fn build_tx_multisig_spend_1on1_unsigned() { .derive(0) .to_public(); - let change_key = root_key_15() + let change_key = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -2709,15 +2709,15 @@ fn build_tx_multisig_spend_1on1_unsigned() { #[test] fn build_tx_multisig_1on1_signed() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(10, 2)); - let spend = root_key_15() + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(10, 2)); + let spend = fake_root_key_15() .derive(harden(1854)) //multisig .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1854)) //multisig .derive(harden(1815)) .derive(harden(0)) @@ -2945,7 +2945,7 @@ fn assert_json_metadatum(dat: &TransactionMetadatum) { #[test] fn set_metadata_with_empty_auxiliary() { - let mut tx_builder = create_default_tx_builder(); + let mut tx_builder = fake_default_tx_builder(); let num = BigNum(42); tx_builder.set_metadata(&create_aux_with_metadata(&num).metadata().unwrap()); @@ -2965,7 +2965,7 @@ fn set_metadata_with_empty_auxiliary() { #[test] fn set_metadata_with_existing_auxiliary() { - let mut tx_builder = create_default_tx_builder(); + let mut tx_builder = fake_default_tx_builder(); let num1 = BigNum(42); tx_builder.set_auxiliary_data(&create_aux_with_metadata(&num1)); @@ -2986,7 +2986,7 @@ fn set_metadata_with_existing_auxiliary() { #[test] fn add_metadatum_with_empty_auxiliary() { - let mut tx_builder = create_default_tx_builder(); + let mut tx_builder = fake_default_tx_builder(); let num = BigNum(42); tx_builder.add_metadatum(&num, &create_json_metadatum()); @@ -3006,7 +3006,7 @@ fn add_metadatum_with_empty_auxiliary() { #[test] fn add_metadatum_with_existing_auxiliary() { - let mut tx_builder = create_default_tx_builder(); + let mut tx_builder = fake_default_tx_builder(); let num1 = BigNum(42); tx_builder.set_auxiliary_data(&create_aux_with_metadata(&num1)); @@ -3027,7 +3027,7 @@ fn add_metadatum_with_existing_auxiliary() { #[test] fn add_json_metadatum_with_empty_auxiliary() { - let mut tx_builder = create_default_tx_builder(); + let mut tx_builder = fake_default_tx_builder(); let num = BigNum(42); tx_builder @@ -3049,7 +3049,7 @@ fn add_json_metadatum_with_empty_auxiliary() { #[test] fn add_json_metadatum_with_existing_auxiliary() { - let mut tx_builder = create_default_tx_builder(); + let mut tx_builder = fake_default_tx_builder(); let num1 = BigNum(42); tx_builder.set_auxiliary_data(&create_aux_with_metadata(&num1)); @@ -3122,7 +3122,7 @@ fn mint_script_and_policy(x: u8) -> (NativeScript, ScriptHash) { #[test] fn set_mint_asset_with_empty_mint() { - let mut tx_builder = create_default_tx_builder(); + let mut tx_builder = fake_default_tx_builder(); let (mint_script, policy_id) = mint_script_and_policy(0); tx_builder.set_mint_asset(&mint_script, &create_mint_asset()).expect("Failed to set mint asset"); @@ -3142,7 +3142,7 @@ fn set_mint_asset_with_empty_mint() { #[test] fn set_mint_asset_with_existing_mint() { - let mut tx_builder = create_default_tx_builder(); + let mut tx_builder = fake_default_tx_builder(); let (mint_script1, policy_id1) = mint_script_and_policy(0); let (mint_script2, policy_id2) = mint_script_and_policy(1); @@ -3182,7 +3182,7 @@ fn set_mint_asset_with_existing_mint() { #[test] fn add_mint_asset_with_empty_mint() { - let mut tx_builder = create_default_tx_builder(); + let mut tx_builder = fake_default_tx_builder(); let (mint_script, policy_id) = mint_script_and_policy(0); @@ -3203,7 +3203,7 @@ fn add_mint_asset_with_empty_mint() { #[test] fn add_mint_asset_with_existing_mint() { - let mut tx_builder = create_default_tx_builder(); + let mut tx_builder = fake_default_tx_builder(); let (mint_script1, policy_id1) = mint_script_and_policy(0); let (mint_script2, policy_id2) = mint_script_and_policy(1); @@ -3241,14 +3241,14 @@ fn add_mint_asset_with_existing_mint() { #[test] fn add_output_amount() { - let mut tx_builder = create_default_tx_builder(); + let mut tx_builder = fake_default_tx_builder(); let policy_id1 = PolicyID::from([0u8; 28]); let multiasset = create_multiasset_one_asset(&policy_id1); let mut value = Value::new(&BigNum(249)); value.set_multiasset(&multiasset); - let address = byron_address(); + let address = fake_byron_address(); tx_builder .add_output( &TransactionOutputBuilder::new() @@ -3270,9 +3270,9 @@ fn add_output_amount() { #[test] fn add_output_coin() { - let mut tx_builder = create_default_tx_builder(); + let mut tx_builder = fake_default_tx_builder(); - let address = byron_address(); + let address = fake_byron_address(); let coin = BigNum(208); tx_builder .add_output( @@ -3296,12 +3296,12 @@ fn add_output_coin() { #[test] fn add_output_coin_and_multiasset() { - let mut tx_builder = create_default_tx_builder(); + let mut tx_builder = fake_default_tx_builder(); let policy_id1 = PolicyID::from([0u8; 28]); let multiasset = create_multiasset_one_asset(&policy_id1); - let address = byron_address(); + let address = fake_byron_address(); let coin = BigNum(249); tx_builder @@ -3326,12 +3326,12 @@ fn add_output_coin_and_multiasset() { #[test] fn add_output_asset_and_min_required_coin() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); let policy_id1 = PolicyID::from([0u8; 28]); let multiasset = create_multiasset_one_asset(&policy_id1); - let address = byron_address(); + let address = fake_byron_address(); tx_builder .add_output( @@ -3359,7 +3359,7 @@ fn add_output_asset_and_min_required_coin() { #[test] fn add_mint_asset_and_output() { - let mut tx_builder = create_default_tx_builder(); + let mut tx_builder = fake_default_tx_builder(); let (mint_script0, policy_id0) = mint_script_and_policy(0); let (mint_script1, policy_id1) = mint_script_and_policy(1); @@ -3367,7 +3367,7 @@ fn add_mint_asset_and_output() { let name = create_asset_name(); let amount = Int::new_i32(1234); - let address = byron_address(); + let address = fake_byron_address(); let coin = BigNum(249); // Add unrelated mint first to check it is NOT added to output later @@ -3430,7 +3430,7 @@ fn add_mint_asset_and_output() { #[test] fn add_mint_asset_and_min_required_coin() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); let (mint_script0, policy_id0) = mint_script_and_policy(0); let (mint_script1, policy_id1) = mint_script_and_policy(1); @@ -3438,7 +3438,7 @@ fn add_mint_asset_and_min_required_coin() { let name = create_asset_name(); let amount = Int::new_i32(1234); - let address = byron_address(); + let address = fake_byron_address(); // Add unrelated mint first to check it is NOT added to output later tx_builder.add_mint_asset(&mint_script0, &name, &amount).expect("Failed to add mint asset"); @@ -3499,7 +3499,7 @@ fn add_mint_asset_and_min_required_coin() { #[test] fn add_mint_includes_witnesses_into_fee_estimation() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); let hash0 = fake_key_hash(0); @@ -3583,7 +3583,7 @@ fn add_mint_includes_witnesses_into_fee_estimation() { #[test] fn fee_estimation_fails_on_missing_mint_scripts() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); // No error estimating fee without mint assert!(tx_builder.min_fee().is_ok()); @@ -3644,8 +3644,8 @@ fn fee_estimation_fails_on_missing_mint_scripts() { #[test] fn total_input_output_with_mint_and_burn() { - let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1)); - let spend = root_key_15() + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(0, 1)); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -3698,7 +3698,7 @@ fn total_input_output_with_mint_and_burn() { tx_builder .add_output( &TransactionOutputBuilder::new() - .with_address(&byron_address()) + .with_address(&fake_byron_address()) .next() .unwrap() .with_coin(&BigNum(208)) @@ -3753,7 +3753,7 @@ fn total_input_output_with_mint_and_burn() { #[test] fn test_add_native_script_input() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); let (script1, _) = mint_script_and_policy(0); let (script2, _) = mint_script_and_policy(1); @@ -3777,7 +3777,7 @@ fn test_add_native_script_input() { #[test] fn test_native_input_scripts_are_added_to_the_witnesses() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); let (script1, _) = mint_script_and_policy(0); let (script2, _) = mint_script_and_policy(1); tx_builder.set_fee(&BigNum(42)); @@ -3803,7 +3803,7 @@ fn test_native_input_scripts_are_added_to_the_witnesses() { #[test] fn test_adding_plutus_script_input() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); let (script1, _) = fake_plutus_script_and_hash(0); let datum = PlutusData::new_bytes(fake_bytes_32(1)); let redeemer_datum = PlutusData::new_bytes(fake_bytes_32(2)); @@ -3831,7 +3831,7 @@ fn test_adding_plutus_script_input() { #[test] fn test_adding_plutus_script_witnesses() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); let (script1, _) = fake_plutus_script_and_hash(0); let (script2, _) = fake_plutus_script_and_hash(1); @@ -3885,7 +3885,7 @@ fn create_collateral() -> TxInputsBuilder { let mut collateral_builder = TxInputsBuilder::new(); collateral_builder .add_regular_input( - &byron_address(), + &fake_byron_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&BigNum(1_000_000)), ) @@ -3895,7 +3895,7 @@ fn create_collateral() -> TxInputsBuilder { #[test] fn test_existing_plutus_scripts_require_data_hash() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); let (script1, _) = fake_plutus_script_and_hash(0); @@ -3935,7 +3935,7 @@ fn test_existing_plutus_scripts_require_data_hash() { #[test] fn test_calc_script_hash_data() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); @@ -3976,7 +3976,7 @@ fn test_calc_script_hash_data() { #[test] fn test_plutus_witness_redeemer_index_auto_changing() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); let (script1, _) = fake_plutus_script_and_hash(0); @@ -4000,7 +4000,7 @@ fn test_plutus_witness_redeemer_index_auto_changing() { // Add a regular NON-script input first tx_builder.add_regular_input( - &byron_address(), + &fake_byron_address(), &TransactionInput::new(&genesis_id(), 0), &Value::new(&BigNum(1_000_000)), ).expect("Failed to add input"); @@ -4046,7 +4046,7 @@ fn test_plutus_witness_redeemer_index_auto_changing() { #[test] fn test_native_and_plutus_scripts_together() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); let (pscript1, _) = fake_plutus_script_and_hash(0); @@ -4132,7 +4132,7 @@ fn test_native_and_plutus_scripts_together() { #[test] fn test_json_serialization_native_and_plutus_scripts_together() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); let (pscript1, _) = fake_plutus_script_and_hash(0); @@ -4209,7 +4209,7 @@ fn test_regular_and_collateral_inputs_same_keyhash() { ).expect("Failed to add input"); fn get_fake_vkeys_count(i: &TxInputsBuilder, c: &TxInputsBuilder) -> usize { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); tx_builder.set_inputs(i); tx_builder.set_collateral(c); @@ -4240,7 +4240,7 @@ fn test_regular_and_collateral_inputs_same_keyhash() { #[test] fn test_regular_and_collateral_inputs_together() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); let (pscript1, _) = fake_plutus_script_and_hash(0); let (pscript2, _) = fake_plutus_script_and_hash(1); @@ -4353,7 +4353,7 @@ fn test_ex_unit_costs_are_added_to_the_fees() { &Value::new(&BigNum(1_000_000)), ); - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_inputs(&input_builder); tx_builder.set_collateral(&collateral_builder); @@ -4372,7 +4372,7 @@ fn test_ex_unit_costs_are_added_to_the_fees() { #[test] fn test_script_inputs_ordering() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); let (nscript1, _) = mint_script_and_policy(0); let (pscript1, _) = fake_plutus_script_and_hash(0); @@ -4431,7 +4431,7 @@ fn test_script_inputs_ordering() { #[test] fn test_required_signers() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); let tx1: TransactionBody = tx_builder.build().unwrap(); assert!(tx1.required_signers.is_none()); @@ -4457,10 +4457,10 @@ fn test_required_signers() { #[test] fn test_required_signers_are_added_to_the_witness_estimate() { fn count_fake_witnesses_with_required_signers(keys: &Ed25519KeyHashes) -> usize { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); tx_builder.add_regular_input( - &fake_base_address(0), + &fake_base_address_with_payment_cred(Credential::from_keyhash(&fake_key_hash(0))), &TransactionInput::new(&fake_tx_hash(0), 0), &Value::new(&BigNum(10_000_000)), ).expect("Failed to add input"); @@ -4516,7 +4516,7 @@ fn test_required_signers_are_added_to_the_witness_estimate() { #[test] fn collateral_return_and_total_collateral_setters() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(123456)); let mut inp = TxInputsBuilder::new(); @@ -4586,7 +4586,7 @@ fn inputs_builder_total_value() { #[test] fn test_auto_calc_total_collateral() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(123456)); let mut inp = TxInputsBuilder::new(); @@ -4621,7 +4621,7 @@ fn test_auto_calc_total_collateral() { #[test] fn test_auto_calc_total_collateral_with_assets() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(123456)); let masset = fake_multiasset(123); @@ -4658,7 +4658,7 @@ fn test_auto_calc_total_collateral_with_assets() { #[test] fn test_auto_calc_total_collateral_fails_with_assets() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(123456)); let masset = fake_multiasset(123); @@ -4692,7 +4692,7 @@ fn test_auto_calc_total_collateral_fails_with_assets() { #[test] fn test_auto_calc_total_collateral_fails_on_no_collateral() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(123456)); let res = tx_builder.set_collateral_return_and_total(&TransactionOutput::new( @@ -4710,7 +4710,7 @@ fn test_auto_calc_total_collateral_fails_on_no_collateral() { #[test] fn test_auto_calc_total_collateral_fails_on_no_ada() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(123456)); let mut inp = TxInputsBuilder::new(); @@ -4738,7 +4738,7 @@ fn test_auto_calc_total_collateral_fails_on_no_ada() { #[test] fn test_auto_calc_collateral_return() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(123456)); let mut inp = TxInputsBuilder::new(); @@ -4778,7 +4778,7 @@ fn test_auto_calc_collateral_return() { #[test] fn test_auto_calc_collateral_return_with_assets() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(123456)); let masset = fake_multiasset(123); @@ -4823,7 +4823,7 @@ fn test_auto_calc_collateral_return_with_assets() { #[test] fn test_add_collateral_return_succeed_with_border_amount() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(123456)); let masset = fake_multiasset(123); @@ -4864,7 +4864,7 @@ fn test_add_collateral_return_succeed_with_border_amount() { #[test] fn test_add_zero_collateral_return() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(123456)); let mut inp = TxInputsBuilder::new(); @@ -4892,7 +4892,7 @@ fn test_add_zero_collateral_return() { #[test] fn test_add_collateral_return_fails_no_enough_ada() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(123456)); let masset = fake_multiasset(123); @@ -4928,7 +4928,7 @@ fn test_add_collateral_return_fails_no_enough_ada() { #[test] fn test_auto_calc_collateral_return_fails_on_no_collateral() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(123456)); let res = @@ -4941,7 +4941,7 @@ fn test_auto_calc_collateral_return_fails_on_no_collateral() { #[test] fn test_costmodel_retaining_for_v1() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); @@ -4985,7 +4985,7 @@ fn test_costmodel_retaining_for_v1() { #[test] fn test_costmodel_retaining_fails_on_missing_costmodel() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); tx_builder.set_fee(&BigNum(42)); tx_builder.set_collateral(&create_collateral()); @@ -5445,7 +5445,7 @@ fn coin_selection_random_improve_multi_asset() { }", ) .unwrap(); - let mut builder = create_reallistic_tx_builder(); + let mut builder = fake_reallistic_tx_builder(); builder.add_output(&output).unwrap(); let res = builder.add_inputs_from(&utoxs, CoinSelectionStrategyCIP2::RandomImproveMultiAsset); assert!(res.is_ok()); @@ -5453,10 +5453,10 @@ fn coin_selection_random_improve_multi_asset() { #[test] fn multiple_plutus_inputs_test() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); let (plutus_script, _) = fake_plutus_script_and_hash(1); - let redeemer1 = create_redeemer(1); - let redeemer2 = create_redeemer(2); + let redeemer1 = fake_redeemer(1); + let redeemer2 = fake_redeemer(2); let mut in_builder = TxInputsBuilder::new(); let input_1 = TransactionInput::new( @@ -5521,29 +5521,29 @@ fn multiple_plutus_inputs_test() { #[test] fn build_tx_with_certs_withdrawals_plutus_script_address() { - let mut tx_builder = create_tx_builder_with_key_deposit(1_000_000); - let spend = root_key_15() + let mut tx_builder = fake_tx_builder_with_key_deposit(1_000_000); + let spend = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(0) .to_public(); - let change_key = root_key_15() + let change_key = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(1) .derive(0) .to_public(); - let stake = root_key_15() + let stake = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(2) .derive(0) .to_public(); - let reward = root_key_15() + let reward = fake_root_key_15() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -5551,11 +5551,11 @@ fn build_tx_with_certs_withdrawals_plutus_script_address() { .derive(1) .to_public(); - let redeemer_cert1 = create_redeemer(1); - let redeemer_cert2 = create_redeemer(2); - let redeemer_cert3 = create_redeemer(3); - let redeemer_withdraw1 = create_redeemer(4); - let redeemer_withdraw2 = create_redeemer(5); + let redeemer_cert1 = fake_redeemer(1); + let redeemer_cert2 = fake_redeemer(2); + let redeemer_cert3 = fake_redeemer(3); + let redeemer_withdraw1 = fake_redeemer(4); + let redeemer_withdraw2 = fake_redeemer(5); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); tx_builder.add_key_input( @@ -5751,7 +5751,7 @@ fn build_tx_with_certs_withdrawals_plutus_script_address() { #[test] pub fn test_extra_datum() { - let mut tx_builder = create_tx_builder(&create_linear_fee(1, 100000), 1, 1, 1); + let mut tx_builder = fake_tx_builder(&fake_linear_fee(1, 100000), 1, 1, 1); let datum = PlutusData::new_bytes(fake_bytes_32(1)); tx_builder.add_extra_witness_datum(&datum); @@ -5769,7 +5769,7 @@ pub fn test_extra_datum() { .calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()) .unwrap(); - let change_address = create_change_address(); + let change_address = fake_change_address(); tx_builder.add_change_if_needed(&change_address).unwrap(); let res = tx_builder.build_tx(); @@ -5810,14 +5810,14 @@ pub fn test_extra_datum() { #[test] fn current_treasure_value_test() { let input_amount = 10000000000; - let mut builder = create_tx_builder_with_amount(input_amount, false); + let mut builder = fake_tx_builder_with_amount(input_amount, false); let treasure_value = Coin::from(1000000000u64); assert_eq!(builder.get_current_treasury_value(), None); builder.set_current_treasury_value(&treasure_value).unwrap(); builder - .add_change_if_needed(&create_change_address()) + .add_change_if_needed(&fake_change_address()) .unwrap(); assert_eq!( @@ -5836,7 +5836,7 @@ fn current_treasure_value_test() { #[test] fn current_treasure_value_zero_error_test() { - let mut builder = create_rich_tx_builder(false); + let mut builder = fake_rich_tx_builder(false); let treasure_value = Coin::from(0u64); assert_eq!(builder.get_current_treasury_value(), None); @@ -5848,14 +5848,14 @@ fn current_treasure_value_zero_error_test() { #[test] fn donation_test() { let input_amount = 10000000000; - let mut builder = create_tx_builder_with_amount(input_amount, false); + let mut builder = fake_tx_builder_with_amount(input_amount, false); let donation = Coin::from(1000u64); assert_eq!(builder.get_donation(), None); builder.set_donation(&donation); builder - .add_change_if_needed(&create_change_address()) + .add_change_if_needed(&fake_change_address()) .unwrap(); assert_eq!(builder.get_donation().unwrap(), donation); @@ -5898,13 +5898,13 @@ fn ref_script_fee_from_all_builders() { let script_hash_7 = fake_script_hash(7); let script_hash_8 = fake_script_hash(8); - let redeemer_1 = create_redeemer_zero_cost(1); - let redeemer_2 = create_redeemer_zero_cost(2); - let redeemer_3 = create_redeemer_zero_cost(3); - let redeemer_4 = create_redeemer_zero_cost(4); - let redeemer_5 = create_redeemer_zero_cost(5); - let redeemer_6 = create_redeemer_zero_cost(6); - let redeemer_8 = create_redeemer_zero_cost(8); + let redeemer_1 = fake_redeemer_zero_cost(1); + let redeemer_2 = fake_redeemer_zero_cost(2); + let redeemer_3 = fake_redeemer_zero_cost(3); + let redeemer_4 = fake_redeemer_zero_cost(4); + let redeemer_5 = fake_redeemer_zero_cost(5); + let redeemer_6 = fake_redeemer_zero_cost(6); + let redeemer_8 = fake_redeemer_zero_cost(8); let plutus_source_1 = PlutusScriptSource::new_ref_input(&script_hash_1, &tx_in_1, &Language::new_plutus_v2(), 10); let plutus_source_2 = PlutusScriptSource::new_ref_input(&script_hash_2, &tx_in_2, &Language::new_plutus_v2(), 100); @@ -5955,10 +5955,10 @@ fn ref_script_fee_from_all_builders() { &VotingProposal::new( &GovernanceAction::new_new_constitution_action( &NewConstitutionAction::new( - &Constitution::new_with_script_hash(&create_anchor(), &script_hash_6) + &Constitution::new_with_script_hash(&fake_anchor(), &script_hash_6) ) ), - &create_anchor(), + &fake_anchor(), &RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &Credential::from_keyhash(&fake_key_hash(1))), &Coin::from(0u64), ), @@ -5972,7 +5972,7 @@ fn ref_script_fee_from_all_builders() { &Value::new(&input_coin) ); - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); let change_address = fake_base_address(1); tx_builder.set_mint_builder(&mint_builder); @@ -6011,7 +6011,7 @@ fn ref_script_fee_from_all_builders() { //TODO: check change calculation for pessimistic size estimation. let tx_size = tx.to_bytes().len() + 4; - let min_tx_fee = min_fee_for_size(tx_size, &create_linear_fee(44, 155381)).unwrap(); + let min_tx_fee = min_fee_for_size(tx_size, &fake_linear_fee(44, 155381)).unwrap(); let fee_leftover = total_tx_fee.checked_sub(&min_tx_fee).unwrap(); assert_eq!(ref_script_fee, fee_leftover); @@ -6038,7 +6038,7 @@ fn ref_script_fee_from_all_builders() { #[test] fn utxo_selection_accounts_for_change_min_utxo_test() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); let hex_utxos = [ "82825820731224c9d2bc3528578009fec9f9e34a67110aca2bd4dde0f050845a2daf660d0082583900436075347d6a452eba4289ae345a8eb15e73eb80979a7e817d988fc56c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e493821a001deabfa1581c9a5e0d55cdf4ce4e19c8acbff7b4dafc890af67a594a4c46d7dd1c0fa14001", "82825820a04996d5ef87fdece0c74625f02ee5c1497a06e0e476c5095a6b0626b295074a00825839001772f234940519e71318bb9c5c8ad6eacfe8fd91a509050624e3855e6c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e4931a0016e360" @@ -6057,7 +6057,7 @@ fn utxo_selection_accounts_for_change_min_utxo_test() { #[test] fn utxo_selection_with_collateral_return_test() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); let hex_utxos = [ "82825820731224c9d2bc3528578009fec9f9e34a67110aca2bd4dde0f050845a2daf660d0082583900436075347d6a452eba4289ae345a8eb15e73eb80979a7e817d988fc56c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e493821a001deabfa1581c9a5e0d55cdf4ce4e19c8acbff7b4dafc890af67a594a4c46d7dd1c0fa14001", "82825820a04996d5ef87fdece0c74625f02ee5c1497a06e0e476c5095a6b0626b295074a00825839001772f234940519e71318bb9c5c8ad6eacfe8fd91a509050624e3855e6c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e4931a0016e360" @@ -6093,7 +6093,7 @@ fn utxo_selection_with_collateral_return_test() { let tx_with_vkeys = Transaction::new(&tx.body(), &wit_set, tx.auxiliary_data()); let tx_size = tx_with_vkeys.to_bytes().len(); let fee = tx.body().fee(); - let min_fee = min_fee_for_size(tx_size, &create_linear_fee(44, 155381)).unwrap(); + let min_fee = min_fee_for_size(tx_size, &fake_linear_fee(44, 155381)).unwrap(); assert!(fee >= min_fee); let collateral_amount = tx.body.total_collateral.unwrap(); @@ -6107,7 +6107,7 @@ fn utxo_selection_with_collateral_return_test() { #[test] fn utxo_selection_with_collateral_return_error() { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); let hex_utxos = [ "82825820731224c9d2bc3528578009fec9f9e34a67110aca2bd4dde0f050845a2daf660d0082583900436075347d6a452eba4289ae345a8eb15e73eb80979a7e817d988fc56c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e493821a001deabfa1581c9a5e0d55cdf4ce4e19c8acbff7b4dafc890af67a594a4c46d7dd1c0fa14001", "82825820a04996d5ef87fdece0c74625f02ee5c1497a06e0e476c5095a6b0626b295074a00825839001772f234940519e71318bb9c5c8ad6eacfe8fd91a509050624e3855e6c8e2cfd5a9478355fa1d60759f93751237af3299d7faa947023e4931a0016e360" diff --git a/rust/src/tests/builders/tx_inputs_builder.rs b/rust/src/tests/builders/tx_inputs_builder.rs index 7b2d8d92..7a59933a 100644 --- a/rust/src/tests/builders/tx_inputs_builder.rs +++ b/rust/src/tests/builders/tx_inputs_builder.rs @@ -1,24 +1,24 @@ -use crate::tests::mock_objects::{create_base_address, create_base_script_address, create_enterprise_address, create_enterprise_script_address, create_plutus_script, create_pointer_address, create_pointer_script_address, create_redeemer, create_reward_address, fake_key_hash, fake_script_hash, fake_tx_input}; +use crate::tests::fakes::{fake_base_address, fake_base_script_address, fake_enterprise_address, fake_enterprise_script_address, fake_plutus_script, fake_pointer_address, fake_pointer_script_address, fake_redeemer, fake_reward_address, fake_key_hash, fake_script_hash, fake_tx_input}; use crate::*; #[test] fn regular_inputs() { let mut tx_inputs_builder = TxInputsBuilder::new(); - let base_address_1 = create_base_address(1); + let base_address_1 = fake_base_address(1); let tx_input_1 = fake_tx_input(1); let input_value_1 = Value::new(&BigNum(100)); tx_inputs_builder .add_regular_input(&base_address_1, &tx_input_1, &input_value_1) .unwrap(); - let enterprise_address_2 = create_enterprise_address(2); + let enterprise_address_2 = fake_enterprise_address(2); let tx_input_2 = fake_tx_input(2); let input_value_2 = Value::new(&BigNum(200)); tx_inputs_builder .add_regular_input(&enterprise_address_2, &tx_input_2, &input_value_2) .unwrap(); - let pointer_address_3 = create_pointer_address(3); + let pointer_address_3 = fake_pointer_address(3); let tx_input_3 = fake_tx_input(3); let input_value_3 = Value::new(&BigNum(300)); tx_inputs_builder @@ -108,16 +108,16 @@ fn script_input_as_regular_input_error() { let plutus_script = fake_tx_input(1); let input_value = Value::new(&BigNum(100)); - let base_address_1 = create_base_script_address(1); + let base_address_1 = fake_base_script_address(1); let res_1 = tx_inputs_builder.add_regular_input(&base_address_1, &plutus_script, &input_value); assert!(res_1.is_err()); - let enterprise_address_2 = create_enterprise_script_address(2); + let enterprise_address_2 = fake_enterprise_script_address(2); let res_2 = tx_inputs_builder.add_regular_input(&enterprise_address_2, &plutus_script, &input_value); assert!(res_2.is_err()); - let pointer_address_3 = create_pointer_script_address(3); + let pointer_address_3 = fake_pointer_script_address(3); let res_3 = tx_inputs_builder.add_regular_input(&pointer_address_3, &plutus_script, &input_value); assert!(res_3.is_err()); @@ -126,7 +126,7 @@ fn script_input_as_regular_input_error() { #[test] fn rewards_address_input_as_regular_input_error() { let mut tx_inputs_builder = TxInputsBuilder::new(); - let rewards_address = create_reward_address(1); + let rewards_address = fake_reward_address(1).to_address(); let tx_input = fake_tx_input(1); let input_value = Value::new(&BigNum(100)); let res = tx_inputs_builder.add_regular_input(&rewards_address, &tx_input, &input_value); @@ -139,9 +139,9 @@ fn plutus_script_input() { let tx_input_1 = fake_tx_input(1); let input_value_1 = Value::new(&BigNum(100)); - let plutus_script = create_plutus_script(1, &Language::new_plutus_v2()); + let plutus_script = fake_plutus_script(1, &Language::new_plutus_v2()); let plutus_script_source = PlutusScriptSource::new(&plutus_script); - let redeemer = create_redeemer(1) + let redeemer = fake_redeemer(1) .clone_with_index_and_tag(&BigNum(0), &RedeemerTag::new_spend()); let datum = PlutusData::new_empty_constr_plutus_data(&BigNum::zero()); @@ -180,11 +180,11 @@ fn plutus_script_input_with_required_signers() { let key_hash = fake_key_hash(1); let key_hashes = Ed25519KeyHashes::from_vec(vec![key_hash]); - let plutus_script = create_plutus_script(1, &Language::new_plutus_v2()); + let plutus_script = fake_plutus_script(1, &Language::new_plutus_v2()); let mut plutus_script_source = PlutusScriptSource::new(&plutus_script); plutus_script_source.set_required_signers(&key_hashes); - let redeemer = create_redeemer(1) + let redeemer = fake_redeemer(1) .clone_with_index_and_tag(&BigNum(0), &RedeemerTag::new_spend()); let datum = PlutusData::new_empty_constr_plutus_data(&BigNum::zero()); @@ -231,7 +231,7 @@ fn plutus_script_input_with_ref() { let plutus_script_source = PlutusScriptSource::new_ref_input(&script_hash, &ref_input_1, &lang_ver, script_size); - let redeemer = create_redeemer(1) + let redeemer = fake_redeemer(1) .clone_with_index_and_tag(&BigNum(0), &RedeemerTag::new_spend()); let plutus_witness = PlutusWitness::new_with_ref( diff --git a/rust/src/tests/builders/voting_builder.rs b/rust/src/tests/builders/voting_builder.rs index e4d91d00..546b9177 100644 --- a/rust/src/tests/builders/voting_builder.rs +++ b/rust/src/tests/builders/voting_builder.rs @@ -1,5 +1,5 @@ use crate::fees::min_fee_for_size; -use crate::tests::mock_objects::{create_change_address, create_linear_fee, create_plutus_script, create_rich_tx_builder, fake_key_hash, fake_script_hash, fake_tx_hash, fake_vkey}; +use crate::tests::fakes::{fake_change_address, fake_linear_fee, fake_plutus_script, fake_rich_tx_builder, fake_key_hash, fake_script_hash, fake_tx_hash, fake_vkey}; use crate::*; #[test] @@ -28,10 +28,10 @@ fn voting_builder_key_signers_test() { assert!(req_signers.contains(&key_hash_3)); assert_eq!(builder.has_plutus_scripts(), false); - let mut tx_builder = create_rich_tx_builder(false); + let mut tx_builder = fake_rich_tx_builder(false); tx_builder.set_voting_builder(&builder); tx_builder - .add_change_if_needed(&create_change_address()) + .add_change_if_needed(&fake_change_address()) .unwrap(); let tx = tx_builder.build_tx().unwrap(); @@ -39,7 +39,7 @@ fn voting_builder_key_signers_test() { let vkey_size = fake_vkey().to_bytes().len(); let rough_tx_size = tx_len + (vkey_size * 3); - let fee_algo = create_linear_fee(44, 155381); + let fee_algo = fake_linear_fee(44, 155381); let approx_fee_with_wit = min_fee_for_size(rough_tx_size, &fee_algo).unwrap(); assert!(approx_fee_with_wit.less_than(&tx.body().fee())); @@ -82,7 +82,7 @@ fn voting_builder_key_signers_test() { #[test] fn voting_builder_plutus_witness() { let mut builder = VotingBuilder::new(); - let script = create_plutus_script(1, &Language::new_plutus_v2()); + let script = fake_plutus_script(1, &Language::new_plutus_v2()); let script_hash = script.hash(); let redeemer = Redeemer::new( &RedeemerTag::new_cert(), @@ -123,10 +123,10 @@ fn voting_builder_plutus_witness() { assert_eq!(langs.len(), 1); assert!(langs.contains(&Language::new_plutus_v2())); - let mut tx_builder = create_rich_tx_builder(true); + let mut tx_builder = fake_rich_tx_builder(true); tx_builder.set_voting_builder(&builder); tx_builder - .add_change_if_needed(&create_change_address()) + .add_change_if_needed(&fake_change_address()) .unwrap(); let mut cost_models = TxBuilderConstants::plutus_default_cost_models(); @@ -219,10 +219,10 @@ fn voting_builder_plutus_ref_witness() { assert_eq!(langs.len(), 1); assert!(langs.contains(&Language::new_plutus_v2())); - let mut tx_builder = create_rich_tx_builder(true); + let mut tx_builder = fake_rich_tx_builder(true); tx_builder.set_voting_builder(&builder); tx_builder - .add_change_if_needed(&create_change_address()) + .add_change_if_needed(&fake_change_address()) .unwrap(); let mut cost_models = TxBuilderConstants::plutus_default_cost_models(); @@ -285,10 +285,10 @@ fn voting_builder_native_script_witness() { let langs = builder.get_used_plutus_lang_versions(); assert_eq!(langs.len(), 0); - let mut tx_builder = create_rich_tx_builder(false); + let mut tx_builder = fake_rich_tx_builder(false); tx_builder.set_voting_builder(&builder); tx_builder - .add_change_if_needed(&create_change_address()) + .add_change_if_needed(&fake_change_address()) .unwrap(); let tx = tx_builder.build_tx().unwrap(); @@ -359,10 +359,10 @@ fn voting_builder_native_script_ref_witness() { let langs = builder.get_used_plutus_lang_versions(); assert_eq!(langs.len(), 0); - let mut tx_builder = create_rich_tx_builder(false); + let mut tx_builder = fake_rich_tx_builder(false); tx_builder.set_voting_builder(&builder); tx_builder - .add_change_if_needed(&create_change_address()) + .add_change_if_needed(&fake_change_address()) .unwrap(); let tx = tx_builder.build_tx().unwrap(); @@ -410,7 +410,7 @@ fn voting_builder_non_script_voter_error() { assert!(result_native.is_err()); let plutus_witness = PlutusWitness::new_without_datum( - &create_plutus_script(1, &Language::new_plutus_v2()), + &fake_plutus_script(1, &Language::new_plutus_v2()), &Redeemer::new( &RedeemerTag::new_cert(), &BigNum::zero(), diff --git a/rust/src/tests/builders/voting_proposal_builder.rs b/rust/src/tests/builders/voting_proposal_builder.rs index 84df98b3..6a48f17b 100644 --- a/rust/src/tests/builders/voting_proposal_builder.rs +++ b/rust/src/tests/builders/voting_proposal_builder.rs @@ -1,4 +1,4 @@ -use crate::tests::mock_objects::{crate_full_protocol_param_update, create_anchor, create_change_address, create_plutus_script, create_tx_builder_with_amount_and_deposit_params, fake_key_hash, fake_reward_address, fake_script_hash, fake_tx_hash}; +use crate::tests::fakes::{fake_full_protocol_param_update, fake_anchor, fake_change_address, fake_plutus_script, fake_tx_builder_with_amount_and_deposit_params, fake_key_hash, fake_reward_address, fake_script_hash, fake_tx_hash}; use crate::*; fn total_tx_output_with_fee(tx: &Transaction) -> Coin { @@ -20,7 +20,7 @@ fn voting_proposal_builder_one_proposal() { let wrapped_action = GovernanceAction::new_hard_fork_initiation_action(&action); let proposal = VotingProposal::new( &wrapped_action, - &create_anchor(), + &fake_anchor(), &fake_reward_address(1), &proposal_deposit, ); @@ -40,11 +40,11 @@ fn voting_proposal_builder_one_proposal() { let initial_amount = 1000000000u64; let mut tx_builder = - create_tx_builder_with_amount_and_deposit_params(initial_amount, 500, 500, false); + fake_tx_builder_with_amount_and_deposit_params(initial_amount, 500, 500, false); tx_builder.set_voting_proposal_builder(&builder); tx_builder - .add_change_if_needed(&create_change_address()) + .add_change_if_needed(&fake_change_address()) .unwrap(); let tx = tx_builder.build_tx().unwrap(); @@ -70,7 +70,7 @@ fn voting_proposal_builder_all_proposals() { let wrapped_hf_action = GovernanceAction::new_hard_fork_initiation_action(&hf_action); let hf_proposal = VotingProposal::new( &wrapped_hf_action, - &create_anchor(), + &fake_anchor(), &fake_reward_address(1), &proposal_deposit, ); @@ -85,20 +85,20 @@ fn voting_proposal_builder_all_proposals() { let wrapped_committee_action = GovernanceAction::new_new_committee_action(&committee_action); let committee_proposal = VotingProposal::new( &wrapped_committee_action, - &create_anchor(), + &fake_anchor(), &fake_reward_address(2), &proposal_deposit, ); builder.add(&committee_proposal).unwrap(); - let anchor = create_anchor(); + let anchor = fake_anchor(); let constitution = Constitution::new(&anchor); let constitution_action = NewConstitutionAction::new(&constitution); let wrapped_constitution_action = GovernanceAction::new_new_constitution_action(&constitution_action); let constitution_proposal = VotingProposal::new( &wrapped_constitution_action, - &create_anchor(), + &fake_anchor(), &fake_reward_address(3), &proposal_deposit, ); @@ -108,18 +108,18 @@ fn voting_proposal_builder_all_proposals() { let wrapped_no_conf_action = GovernanceAction::new_no_confidence_action(&no_conf_action); let no_conf_proposal = VotingProposal::new( &wrapped_no_conf_action, - &create_anchor(), + &fake_anchor(), &fake_reward_address(4), &proposal_deposit, ); builder.add(&no_conf_proposal).unwrap(); - let parameters_update = crate_full_protocol_param_update(); + let parameters_update = fake_full_protocol_param_update(); let pp_update_action = ParameterChangeAction::new(¶meters_update); let wrapped_pp_update_action = GovernanceAction::new_parameter_change_action(&pp_update_action); let pp_update_proposal = VotingProposal::new( &wrapped_pp_update_action, - &create_anchor(), + &fake_anchor(), &fake_reward_address(4), &proposal_deposit, ); @@ -133,7 +133,7 @@ fn voting_proposal_builder_all_proposals() { GovernanceAction::new_treasury_withdrawals_action(&withdrawal_action); let withdrawal_proposal = VotingProposal::new( &wrapped_withdrawal_action, - &create_anchor(), + &fake_anchor(), &fake_reward_address(5), &proposal_deposit, ); @@ -143,7 +143,7 @@ fn voting_proposal_builder_all_proposals() { let wrapped_info_action = GovernanceAction::new_info_action(&info_action); let info_proposal = VotingProposal::new( &wrapped_info_action, - &create_anchor(), + &fake_anchor(), &fake_reward_address(5), &proposal_deposit, ); @@ -160,11 +160,11 @@ fn voting_proposal_builder_all_proposals() { let initial_amount = 1000000000u64; let mut tx_builder = - create_tx_builder_with_amount_and_deposit_params(initial_amount, 500, 500, false); + fake_tx_builder_with_amount_and_deposit_params(initial_amount, 500, 500, false); tx_builder.set_voting_proposal_builder(&builder); tx_builder - .add_change_if_needed(&create_change_address()) + .add_change_if_needed(&fake_change_address()) .unwrap(); let tx = tx_builder.build_tx().unwrap(); @@ -196,13 +196,13 @@ fn voting_proposal_builder_with_plutus_script_witness() { let wrapped_hf_action = GovernanceAction::new_hard_fork_initiation_action(&hf_action); let hf_proposal = VotingProposal::new( &wrapped_hf_action, - &create_anchor(), + &fake_anchor(), &fake_reward_address(1), &proposal_deposit, ); builder.add(&hf_proposal).unwrap(); - let script = create_plutus_script(1, &Language::new_plutus_v2()); + let script = fake_plutus_script(1, &Language::new_plutus_v2()); let redeemer = Redeemer::new( &RedeemerTag::new_cert(), &BigNum::from(100u32), @@ -222,7 +222,7 @@ fn voting_proposal_builder_with_plutus_script_witness() { let wrapped_committee_action = GovernanceAction::new_new_committee_action(&committee_action); let committee_proposal = VotingProposal::new( &wrapped_committee_action, - &create_anchor(), + &fake_anchor(), &fake_reward_address(2), &proposal_deposit, ); @@ -246,11 +246,11 @@ fn voting_proposal_builder_with_plutus_script_witness() { let initial_amount = 1000000000u64; let mut tx_builder = - create_tx_builder_with_amount_and_deposit_params(initial_amount, 500, 500, true); + fake_tx_builder_with_amount_and_deposit_params(initial_amount, 500, 500, true); tx_builder.set_voting_proposal_builder(&builder); tx_builder - .add_change_if_needed(&create_change_address()) + .add_change_if_needed(&fake_change_address()) .unwrap(); let mut cost_models = TxBuilderConstants::plutus_default_cost_models(); @@ -300,7 +300,7 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { let wrapped_hf_action = GovernanceAction::new_hard_fork_initiation_action(&hf_action); let hf_proposal = VotingProposal::new( &wrapped_hf_action, - &create_anchor(), + &fake_anchor(), &fake_reward_address(1), &proposal_deposit, ); @@ -329,7 +329,7 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { let wrapped_committee_action = GovernanceAction::new_new_committee_action(&committee_action); let committee_proposal = VotingProposal::new( &wrapped_committee_action, - &create_anchor(), + &fake_anchor(), &fake_reward_address(2), &proposal_deposit, ); @@ -354,11 +354,11 @@ fn voting_proposal_builder_with_ref_plutus_script_witness() { let initial_amount = 1000000000u64; let mut tx_builder = - create_tx_builder_with_amount_and_deposit_params(initial_amount, 500, 500, true); + fake_tx_builder_with_amount_and_deposit_params(initial_amount, 500, 500, true); tx_builder.set_voting_proposal_builder(&builder); tx_builder - .add_change_if_needed(&create_change_address()) + .add_change_if_needed(&fake_change_address()) .unwrap(); let mut cost_models = TxBuilderConstants::plutus_default_cost_models(); diff --git a/rust/src/tests/mock_objects.rs b/rust/src/tests/fakes.rs similarity index 81% rename from rust/src/tests/mock_objects.rs rename to rust/src/tests/fakes.rs index 0cc0c4c0..3e6cfd5d 100644 --- a/rust/src/tests/mock_objects.rs +++ b/rust/src/tests/fakes.rs @@ -8,7 +8,7 @@ const MAX_TX_SIZE: u32 = 8000; // might be out of date but suffices for our test // this is what is used in mainnet static COINS_PER_UTXO_BYTE: u64 = 34_482 / 8; -pub(crate) fn root_key_15() -> Bip32PrivateKey { +pub(crate) fn fake_root_key_15() -> Bip32PrivateKey { // art forum devote street sure rather head chuckle guard poverty release quote oak craft enemy let entropy = [ 0x0c, 0xcb, 0x74, 0xf3, 0x6b, 0x7d, 0xa1, 0x64, 0x9a, 0x81, 0x44, 0x67, 0x55, 0x22, 0xd4, @@ -17,7 +17,7 @@ pub(crate) fn root_key_15() -> Bip32PrivateKey { Bip32PrivateKey::from_bip39_entropy(&entropy, &[]) } -pub(crate) fn root_key() -> Bip32PrivateKey { +pub(crate) fn fake_root_key() -> Bip32PrivateKey { // art forum devote street sure rather head chuckle guard poverty release quote oak craft enemy let entropy = [ 0x0c, 0xcb, 0x74, 0xf3, 0x6b, 0x7d, 0xa1, 0x64, 0x9a, 0x81, 0x44, 0x67, 0x55, 0x22, 0xd4, @@ -26,15 +26,32 @@ pub(crate) fn root_key() -> Bip32PrivateKey { Bip32PrivateKey::from_bip39_entropy(&entropy, &[]) } -pub(crate) fn generate_address(index: u32) -> Address { - let spend = root_key() +pub(crate) fn fake_base_address_with_payment_cred(payment_cred: Credential) -> Address { + let stake = fake_root_key() + .derive(harden(1852)) + .derive(harden(1815)) + .derive(harden(0)) + .derive(2) + .derive(0) + .to_public(); + let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); + let addr = BaseAddress::new( + NetworkInfo::testnet_preprod().network_id(), + &payment_cred, + &stake_cred, + ); + addr.to_address() +} + +pub(crate) fn fake_base_address(index: u32) -> Address { + let spend = fake_root_key() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(0) .derive(index) .to_public(); - let stake = root_key() + let stake = fake_root_key() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -51,7 +68,7 @@ pub(crate) fn generate_address(index: u32) -> Address { addr.to_address() } -pub(crate) fn crate_full_protocol_param_update() -> ProtocolParamUpdate { +pub(crate) fn fake_full_protocol_param_update() -> ProtocolParamUpdate { ProtocolParamUpdate { minfee_a: Some(Coin::from(44_444u32)), minfee_b: Some(Coin::from(44_444u32)), @@ -82,7 +99,7 @@ pub(crate) fn crate_full_protocol_param_update() -> ProtocolParamUpdate { protocol_version: Some(ProtocolVersion::new(1, 2)), min_pool_cost: Some(Coin::from(44_444u32)), ada_per_utxo_byte: Some(Coin::from(44_444u32)), - cost_models: Some(create_cost_models()), + cost_models: Some(fake_cost_models()), execution_costs: Some(ExUnitPrices::new( &SubCoin::new(&BigNum(577), &BigNum(10000)), &SubCoin::new(&BigNum(721), &BigNum(10000000)), @@ -92,8 +109,8 @@ pub(crate) fn crate_full_protocol_param_update() -> ProtocolParamUpdate { max_value_size: Some(44_444u32), collateral_percentage: Some(44_444u32), max_collateral_inputs: Some(44_444u32), - pool_voting_thresholds: Some(create_pool_voting_thresholds()), - drep_voting_thresholds: Some(create_drep_voting_thresholds()), + pool_voting_thresholds: Some(fake_pool_voting_thresholds()), + drep_voting_thresholds: Some(fake_drep_voting_thresholds()), min_committee_size: Some(44_444u32), committee_term_limit: Some(44_444u32), governance_action_validity_period: Some(44_444u32), @@ -107,7 +124,7 @@ pub(crate) fn crate_full_protocol_param_update() -> ProtocolParamUpdate { } } -pub(crate) fn create_pool_voting_thresholds() -> PoolVotingThresholds { +pub(crate) fn fake_pool_voting_thresholds() -> PoolVotingThresholds { PoolVotingThresholds::new( &UnitInterval::new(&BigNum::from(44_401u32), &BigNum::from(44_402u32)), &UnitInterval::new(&BigNum::from(44_403u32), &BigNum::from(44_404u32)), @@ -117,7 +134,7 @@ pub(crate) fn create_pool_voting_thresholds() -> PoolVotingThresholds { ) } -pub(crate) fn create_drep_voting_thresholds() -> DrepVotingThresholds { +pub(crate) fn fake_drep_voting_thresholds() -> DrepVotingThresholds { DrepVotingThresholds::new( &UnitInterval::new(&BigNum::from(44_401u32), &BigNum::from(44_402u32)), &UnitInterval::new(&BigNum::from(44_403u32), &BigNum::from(44_404u32)), @@ -132,7 +149,7 @@ pub(crate) fn create_drep_voting_thresholds() -> DrepVotingThresholds { ) } -pub(crate) fn crate_full_pool_params() -> PoolParams { +pub(crate) fn fake_full_pool_params() -> PoolParams { PoolParams { operator: fake_key_hash(1), vrf_keyhash: fake_vrf_key_hash(2), @@ -151,7 +168,7 @@ pub(crate) fn crate_full_pool_params() -> PoolParams { } } -pub(crate) fn create_cost_models() -> Costmdls { +pub(crate) fn fake_cost_models() -> Costmdls { let mut res = Costmdls::new(); res.insert( &Language::new_plutus_v1(), @@ -172,31 +189,31 @@ pub(crate) fn create_cost_models() -> Costmdls { res } -pub(crate) fn create_anchor() -> Anchor { +pub(crate) fn fake_anchor() -> Anchor { Anchor::new( &URL::new("https://iohk.io".to_string()).unwrap(), &fake_anchor_data_hash(1), ) } -pub(crate) fn create_action_id() -> GovernanceActionId { +pub(crate) fn fake_action_id() -> GovernanceActionId { GovernanceActionId::new(&fake_tx_hash(1), 1) } -pub(crate) fn byron_address() -> Address { +pub(crate) fn fake_byron_address() -> Address { ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") .unwrap() .to_address() } -pub(crate) fn create_linear_fee(coefficient: u64, constant: u64) -> LinearFee { +pub(crate) fn fake_linear_fee(coefficient: u64, constant: u64) -> LinearFee { LinearFee::new(&BigNum(coefficient), &BigNum(constant)) } -pub(crate) fn create_default_linear_fee() -> LinearFee { - create_linear_fee(500, 2) +pub(crate) fn fake_default_linear_fee() -> LinearFee { + fake_linear_fee(500, 2) } -pub(crate) fn create_tx_builder_full( +pub(crate) fn fake_tx_builder_full( linear_fee: &LinearFee, pool_deposit: u64, key_deposit: u64, @@ -222,13 +239,13 @@ pub(crate) fn create_tx_builder_full( TransactionBuilder::new(&cfg) } -pub(crate) fn create_tx_builder( +pub(crate) fn fake_tx_builder( linear_fee: &LinearFee, coins_per_utxo_byte: u64, pool_deposit: u64, key_deposit: u64, ) -> TransactionBuilder { - create_tx_builder_full( + fake_tx_builder_full( linear_fee, pool_deposit, key_deposit, @@ -237,27 +254,27 @@ pub(crate) fn create_tx_builder( ) } -pub(crate) fn create_reallistic_tx_builder() -> TransactionBuilder { - create_tx_builder( - &create_linear_fee(44, 155381), +pub(crate) fn fake_reallistic_tx_builder() -> TransactionBuilder { + fake_tx_builder( + &fake_linear_fee(44, 155381), COINS_PER_UTXO_BYTE, 500000000, 2000000, ) } -pub(crate) fn create_tx_builder_with_fee_and_val_size( +pub(crate) fn fake_tx_builder_with_fee_and_val_size( linear_fee: &LinearFee, max_val_size: u32, ) -> TransactionBuilder { - create_tx_builder_full(linear_fee, 1, 1, max_val_size, 1) + fake_tx_builder_full(linear_fee, 1, 1, max_val_size, 1) } -pub(crate) fn create_tx_builder_with_fee(linear_fee: &LinearFee) -> TransactionBuilder { - create_tx_builder(linear_fee, 1, 1, 1) +pub(crate) fn fake_tx_builder_with_fee(linear_fee: &LinearFee) -> TransactionBuilder { + fake_tx_builder(linear_fee, 1, 1, 1) } -pub(crate) fn create_tx_builder_with_fee_and_pure_change( +pub(crate) fn fake_tx_builder_with_fee_and_pure_change( linear_fee: &LinearFee, ) -> TransactionBuilder { TransactionBuilder::new( @@ -274,48 +291,23 @@ pub(crate) fn create_tx_builder_with_fee_and_pure_change( ) } -pub(crate) fn create_tx_builder_with_key_deposit(deposit: u64) -> TransactionBuilder { - create_tx_builder(&create_default_linear_fee(), 8, 1, deposit) +pub(crate) fn fake_tx_builder_with_key_deposit(deposit: u64) -> TransactionBuilder { + fake_tx_builder(&fake_default_linear_fee(), 8, 1, deposit) } -pub(crate) fn create_default_tx_builder() -> TransactionBuilder { - create_tx_builder_with_fee(&create_default_linear_fee()) +pub(crate) fn fake_default_tx_builder() -> TransactionBuilder { + fake_tx_builder_with_fee(&fake_default_linear_fee()) } -pub(crate) fn create_change_address() -> Address { - let spend = root_key() +pub(crate) fn fake_change_address() -> Address { + let spend = fake_root_key() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) .derive(1) .derive(0) .to_public(); - let stake = root_key() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(2) - .derive(0) - .to_public(); - let spend_cred = Credential::from_keyhash(&spend.to_raw_key().hash()); - let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - let addr = BaseAddress::new( - NetworkInfo::testnet_preprod().network_id(), - &spend_cred, - &stake_cred, - ); - addr.to_address() -} - -pub(crate) fn create_base_address(index: u32) -> Address { - let spend = root_key() - .derive(harden(1852)) - .derive(harden(1815)) - .derive(harden(0)) - .derive(1) - .derive(index) - .to_public(); - let stake = root_key() + let stake = fake_root_key() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -332,8 +324,8 @@ pub(crate) fn create_base_address(index: u32) -> Address { addr.to_address() } -pub(crate) fn create_base_script_address(index: u8) -> Address { - let stake = root_key() +pub(crate) fn fake_base_script_address(index: u8) -> Address { + let stake = fake_root_key() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -350,8 +342,8 @@ pub(crate) fn create_base_script_address(index: u8) -> Address { addr.to_address() } -pub(crate) fn create_enterprise_address(index: u32) -> Address { - let spend = root_key() +pub(crate) fn fake_enterprise_address(index: u32) -> Address { + let spend = fake_root_key() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -366,7 +358,7 @@ pub(crate) fn create_enterprise_address(index: u32) -> Address { addr.to_address() } -pub(crate) fn create_enterprise_script_address(index: u8) -> Address { +pub(crate) fn fake_enterprise_script_address(index: u8) -> Address { let spend_cred = Credential::from_scripthash(&fake_script_hash(index)); let addr = EnterpriseAddress::new( NetworkInfo::testnet_preprod().network_id(), @@ -375,8 +367,8 @@ pub(crate) fn create_enterprise_script_address(index: u8) -> Address { addr.to_address() } -pub(crate) fn create_pointer_address(index: u32) -> Address { - let spend = root_key() +pub(crate) fn fake_pointer_address(index: u32) -> Address { + let spend = fake_root_key() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -393,7 +385,7 @@ pub(crate) fn create_pointer_address(index: u32) -> Address { addr.to_address() } -pub(crate) fn create_pointer_script_address(index: u8) -> Address { +pub(crate) fn fake_pointer_script_address(index: u8) -> Address { let spend_cred = Credential::from_scripthash(&fake_script_hash(index)); let pointer = Pointer::new(1, 2, 3); let addr = PointerAddress::new( @@ -404,8 +396,8 @@ pub(crate) fn create_pointer_script_address(index: u8) -> Address { addr.to_address() } -pub(crate) fn create_reward_address(index: u32) -> Address { - let stake = root_key() +pub(crate) fn fake_reward_address(index: u32) -> RewardAddress { + let stake = fake_root_key() .derive(harden(1852)) .derive(harden(1815)) .derive(harden(0)) @@ -413,21 +405,20 @@ pub(crate) fn create_reward_address(index: u32) -> Address { .derive(index) .to_public(); let stake_cred = Credential::from_keyhash(&stake.to_raw_key().hash()); - let addr = RewardAddress::new( + RewardAddress::new( NetworkInfo::testnet_preprod().network_id(), &stake_cred, - ); - addr.to_address() + ) } -pub(crate) fn create_malformed_address() -> Address { +pub(crate) fn fake_malformed_address() -> Address { MalformedAddress(vec![255, 255, 255, 255, 255, 255]).to_address() } -pub(crate) fn create_rich_tx_builder(with_collateral: bool) -> TransactionBuilder { - let mut tx_builder = create_reallistic_tx_builder(); +pub(crate) fn fake_rich_tx_builder(with_collateral: bool) -> TransactionBuilder { + let mut tx_builder = fake_reallistic_tx_builder(); let input = TransactionInput::new(&fake_tx_hash(1), 0); - let address = generate_address(1); + let address = fake_base_address(1); let mut input_builder = TxInputsBuilder::new(); input_builder.add_regular_input(&address, &input, &Value::new(&Coin::from(u64::MAX / 2))) .expect("should add input"); @@ -439,13 +430,13 @@ pub(crate) fn create_rich_tx_builder(with_collateral: bool) -> TransactionBuilde tx_builder } -pub(crate) fn create_tx_builder_with_amount( +pub(crate) fn fake_tx_builder_with_amount( amount: u64, with_collateral: bool, ) -> TransactionBuilder { - let mut tx_builder = create_reallistic_tx_builder(); + let mut tx_builder = fake_reallistic_tx_builder(); let input = TransactionInput::new(&fake_tx_hash(1), 0); - let address = generate_address(1); + let address = fake_base_address(1); let mut input_builder = TxInputsBuilder::new(); input_builder.add_regular_input(&address, &input, &Value::new(&Coin::from(amount))).expect("should add input"); tx_builder.set_inputs(&input_builder); @@ -459,20 +450,20 @@ pub(crate) fn create_tx_builder_with_amount( tx_builder } -pub(crate) fn create_tx_builder_with_amount_and_deposit_params( +pub(crate) fn fake_tx_builder_with_amount_and_deposit_params( amount: u64, pool_deposit: u64, key_deposit: u64, with_collateral: bool, ) -> TransactionBuilder { - let mut tx_builder = create_tx_builder( - &create_linear_fee(44, 155381), + let mut tx_builder = fake_tx_builder( + &fake_linear_fee(44, 155381), COINS_PER_UTXO_BYTE, pool_deposit, key_deposit ); let input = TransactionInput::new(&fake_tx_hash(1), 0); - let address = generate_address(1); + let address = fake_base_address(1); let mut input_builder = TxInputsBuilder::new(); input_builder.add_regular_input(&address, &input, &Value::new(&Coin::from(amount))).expect("should add input"); tx_builder.set_inputs(&input_builder); @@ -486,14 +477,14 @@ pub(crate) fn create_tx_builder_with_amount_and_deposit_params( tx_builder } -pub(crate) fn create_plutus_script(x: u8, lang: &Language) -> PlutusScript { +pub(crate) fn fake_plutus_script(x: u8, lang: &Language) -> PlutusScript { let mut bytes = hex::decode("4e4d01000033222220051200120011").unwrap(); let pos = bytes.len() - 1; bytes[pos] = x; PlutusScript::from_bytes_with_version(bytes, lang).unwrap() } -pub(crate) fn create_redeemer(x: u8) -> Redeemer { +pub(crate) fn fake_redeemer(x: u8) -> Redeemer { Redeemer::new( &RedeemerTag::new_cert(), &BigNum::from(x as u64), @@ -502,7 +493,7 @@ pub(crate) fn create_redeemer(x: u8) -> Redeemer { ) } -pub(crate) fn create_redeemer_zero_cost(x: u8) -> Redeemer { +pub(crate) fn fake_redeemer_zero_cost(x: u8) -> Redeemer { Redeemer::new( &RedeemerTag::new_cert(), &BigNum::from(x as u64), @@ -559,22 +550,6 @@ pub(crate) fn fake_script_data_hash(x: u8) -> ScriptDataHash { ScriptDataHash::from_bytes(fake_bytes_32(x)).unwrap() } -pub(crate) fn fake_base_address(x: u8) -> Address { - BaseAddress::new( - NetworkInfo::testnet_preprod().network_id(), - &Credential::from_keyhash(&fake_key_hash(x)), - &Credential::from_keyhash(&fake_key_hash(0)), - ) - .to_address() -} - -pub(crate) fn fake_reward_address(x: u8) -> RewardAddress { - RewardAddress::new( - NetworkInfo::testnet_preprod().network_id(), - &Credential::from_keyhash(&fake_key_hash(x)), - ) -} - pub(crate) fn fake_tx_hash(input_hash_byte: u8) -> TransactionHash { TransactionHash::from([input_hash_byte; 32]) } @@ -596,11 +571,11 @@ pub(crate) fn fake_value2(v: u64) -> Value { } pub(crate) fn fake_tx_output(input_hash_byte: u8) -> TransactionOutput { - TransactionOutput::new(&fake_base_address(input_hash_byte), &fake_value()) + TransactionOutput::new(&fake_base_address(input_hash_byte as u32), &fake_value()) } pub(crate) fn fake_tx_output2(input_hash_byte: u8, val: u64) -> TransactionOutput { - TransactionOutput::new(&fake_base_address(input_hash_byte), &fake_value2(val)) + TransactionOutput::new(&fake_base_address(input_hash_byte as u32), &fake_value2(val)) } pub(crate) fn fake_vkey() -> Vkey { diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index 3eebb019..fd57bdb1 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -1,6 +1,6 @@ use crate::*; use crate::tests::helpers::harden; -use crate::tests::mock_objects::{create_plutus_script, fake_boostrap_witness, fake_tx_input, fake_vkey_witness}; +use crate::tests::fakes::{fake_plutus_script, fake_boostrap_witness, fake_tx_input, fake_vkey_witness}; #[test] fn native_script_hash() { @@ -325,7 +325,7 @@ fn protocol_params_update_cbor_json_roundtrip() { #[test] fn witnesses_deduplication_test(){ - let spend = tests::mock_objects::root_key_15() + let spend = tests::fakes::fake_root_key_15() .derive(harden(1854)) .derive(harden(1815)) .derive(harden(0)) @@ -365,17 +365,17 @@ fn witnesses_deduplication_test(){ vkey_witnesses.add(&vkey_witness_1_1); vkey_witnesses.add(&vkey_witness_2); - let plutus_v1_1 = create_plutus_script(1, &Language::new_plutus_v1()); - let plutus_v1_1_1 = create_plutus_script(1, &Language::new_plutus_v1()); - let plutus_v1_2 = create_plutus_script(2, &Language::new_plutus_v1()); + let plutus_v1_1 = fake_plutus_script(1, &Language::new_plutus_v1()); + let plutus_v1_1_1 = fake_plutus_script(1, &Language::new_plutus_v1()); + let plutus_v1_2 = fake_plutus_script(2, &Language::new_plutus_v1()); - let plutus_v2_1 = create_plutus_script(1, &Language::new_plutus_v2()); - let plutus_v2_1_1 = create_plutus_script(1, &Language::new_plutus_v2()); - let plutus_v2_2 = create_plutus_script(2, &Language::new_plutus_v2()); + let plutus_v2_1 = fake_plutus_script(1, &Language::new_plutus_v2()); + let plutus_v2_1_1 = fake_plutus_script(1, &Language::new_plutus_v2()); + let plutus_v2_2 = fake_plutus_script(2, &Language::new_plutus_v2()); - let plutus_v3_1 = create_plutus_script(1, &Language::new_plutus_v3()); - let plutus_v3_1_1 = create_plutus_script(1, &Language::new_plutus_v3()); - let plutus_v3_2 = create_plutus_script(2, &Language::new_plutus_v3()); + let plutus_v3_1 = fake_plutus_script(1, &Language::new_plutus_v3()); + let plutus_v3_1_1 = fake_plutus_script(1, &Language::new_plutus_v3()); + let plutus_v3_2 = fake_plutus_script(2, &Language::new_plutus_v3()); let mut plutus_scripts = PlutusScripts::new(); plutus_scripts.add(&plutus_v1_1); @@ -503,14 +503,14 @@ fn vkeywitneses_dedup() { #[test] fn plutus_scripts_dedup_on_tx_witnesses_set() { - let plutus_script_v1_1 = create_plutus_script(1, &Language::new_plutus_v1()); - let plutus_script_v1_2 = create_plutus_script(2, &Language::new_plutus_v1()); + let plutus_script_v1_1 = fake_plutus_script(1, &Language::new_plutus_v1()); + let plutus_script_v1_2 = fake_plutus_script(2, &Language::new_plutus_v1()); - let plutus_script_v2_1 = create_plutus_script(1, &Language::new_plutus_v2()); - let plutus_script_v2_2 = create_plutus_script(2, &Language::new_plutus_v2()); + let plutus_script_v2_1 = fake_plutus_script(1, &Language::new_plutus_v2()); + let plutus_script_v2_2 = fake_plutus_script(2, &Language::new_plutus_v2()); - let plutus_script_v3_1 = create_plutus_script(1, &Language::new_plutus_v3()); - let plutus_script_v3_2 = create_plutus_script(2, &Language::new_plutus_v3()); + let plutus_script_v3_1 = fake_plutus_script(1, &Language::new_plutus_v3()); + let plutus_script_v3_2 = fake_plutus_script(2, &Language::new_plutus_v3()); let mut plutus_scrips = PlutusScripts::new(); plutus_scrips.add(&plutus_script_v1_1); @@ -552,14 +552,14 @@ fn plutus_scripts_dedup_on_tx_witnesses_set() { #[test] fn plutus_scripts_no_dedup_on_auxdata() { - let plutus_script_v1_1 = create_plutus_script(1, &Language::new_plutus_v1()); - let plutus_script_v1_2 = create_plutus_script(2, &Language::new_plutus_v1()); + let plutus_script_v1_1 = fake_plutus_script(1, &Language::new_plutus_v1()); + let plutus_script_v1_2 = fake_plutus_script(2, &Language::new_plutus_v1()); - let plutus_script_v2_1 = create_plutus_script(1, &Language::new_plutus_v2()); - let plutus_script_v2_2 = create_plutus_script(2, &Language::new_plutus_v2()); + let plutus_script_v2_1 = fake_plutus_script(1, &Language::new_plutus_v2()); + let plutus_script_v2_2 = fake_plutus_script(2, &Language::new_plutus_v2()); - let plutus_script_v3_1 = create_plutus_script(1, &Language::new_plutus_v3()); - let plutus_script_v3_2 = create_plutus_script(2, &Language::new_plutus_v3()); + let plutus_script_v3_1 = fake_plutus_script(1, &Language::new_plutus_v3()); + let plutus_script_v3_2 = fake_plutus_script(2, &Language::new_plutus_v3()); let mut plutus_scrips = PlutusScripts::new(); plutus_scrips.add(&plutus_script_v1_1); diff --git a/rust/src/tests/mod.rs b/rust/src/tests/mod.rs index 2c350a8e..197793b2 100644 --- a/rust/src/tests/mod.rs +++ b/rust/src/tests/mod.rs @@ -2,7 +2,7 @@ mod address; mod builders; mod general; mod helpers; -mod mock_objects; +mod fakes; mod protocol_types; mod serialization; mod plutus; diff --git a/rust/src/tests/protocol_types/certificates.rs b/rust/src/tests/protocol_types/certificates.rs index b86fc762..1a53bb17 100644 --- a/rust/src/tests/protocol_types/certificates.rs +++ b/rust/src/tests/protocol_types/certificates.rs @@ -1,4 +1,4 @@ -use crate::tests::mock_objects::{crate_full_pool_params, create_anchor, fake_genesis_delegate_hash, fake_genesis_hash, fake_key_hash, fake_script_hash, fake_vrf_key_hash}; +use crate::tests::fakes::{fake_full_pool_params, fake_anchor, fake_genesis_delegate_hash, fake_genesis_hash, fake_key_hash, fake_script_hash, fake_vrf_key_hash}; use crate::*; #[test] @@ -63,7 +63,7 @@ fn drep_registration_setters_getters_test() { let coin = Coin::from(100u32); let drep_registration_1 = DrepRegistration::new(&cred_key_hash, &coin); - let anchor = create_anchor(); + let anchor = fake_anchor(); let drep_registration_2 = DrepRegistration::new_with_anchor(&cred_script_hash, &coin, &anchor); assert_eq!(drep_registration_1.voting_credential(), cred_key_hash); @@ -78,7 +78,7 @@ fn drep_update_setters_getters_test() { let cred_script_hash = Credential::from_scripthash(&fake_script_hash(2)); let drep_update_1 = DrepUpdate::new(&cred_key_hash); - let anchor = create_anchor(); + let anchor = fake_anchor(); let drep_update_2 = DrepUpdate::new_with_anchor(&cred_script_hash, &anchor); assert_eq!(drep_update_1.voting_credential(), cred_key_hash); @@ -135,7 +135,7 @@ fn move_instantaneous_rewards_setters_getters_test() { #[test] fn pool_registration_setters_getters_test() { - let pool_params = crate_full_pool_params(); + let pool_params = fake_full_pool_params(); let pool_registration = PoolRegistration::new(&pool_params); assert_eq!(pool_registration.pool_params(), pool_params); diff --git a/rust/src/tests/protocol_types/governance/common.rs b/rust/src/tests/protocol_types/governance/common.rs index 03cb74d3..e9a21995 100644 --- a/rust/src/tests/protocol_types/governance/common.rs +++ b/rust/src/tests/protocol_types/governance/common.rs @@ -1,4 +1,4 @@ -use crate::tests::mock_objects::{create_anchor, fake_anchor_data_hash, fake_key_hash, fake_script_hash, fake_tx_hash}; +use crate::tests::fakes::{fake_anchor, fake_anchor_data_hash, fake_key_hash, fake_script_hash, fake_tx_hash}; use crate::*; #[test] @@ -178,7 +178,7 @@ fn voting_procedure_setters_getters_test() { #[test] fn voting_procedure_with_anchor_setters_getters_test() { - let anchor = create_anchor(); + let anchor = fake_anchor(); let yes_procedure = VotingProcedure::new_with_anchor(VoteKind::Yes, &anchor); assert_eq!(yes_procedure.vote_kind(), VoteKind::Yes); assert_eq!(yes_procedure.anchor(), Some(anchor.clone())); diff --git a/rust/src/tests/protocol_types/governance/proposals.rs b/rust/src/tests/protocol_types/governance/proposals.rs index 62639fdc..7d7b3056 100644 --- a/rust/src/tests/protocol_types/governance/proposals.rs +++ b/rust/src/tests/protocol_types/governance/proposals.rs @@ -1,4 +1,4 @@ -use crate::tests::mock_objects::{crate_full_protocol_param_update, create_action_id, create_anchor, fake_key_hash, fake_reward_address, fake_script_hash}; +use crate::tests::fakes::{fake_full_protocol_param_update, fake_action_id, fake_anchor, fake_key_hash, fake_reward_address, fake_script_hash}; use crate::*; use itertools::Itertools; @@ -27,7 +27,7 @@ fn committee_setters_getters_test() { #[test] fn constitution_setters_getters_test() { - let anchor = create_anchor(); + let anchor = fake_anchor(); let constitution = Constitution::new(&anchor); assert_eq!(constitution.anchor(), anchor); assert_eq!(constitution.script_hash(), None); @@ -42,7 +42,7 @@ fn constitution_setters_getters_test() { fn hard_fork_initiation_action_setters_getters_test() { let protocol_version = ProtocolVersion::new(1, 2); let proposal = HardForkInitiationAction::new(&protocol_version); - let action_id = create_action_id(); + let action_id = fake_action_id(); let proposal_with_action_id = HardForkInitiationAction::new_with_action_id(&action_id, &protocol_version); assert_eq!(proposal.gov_action_id(), None); @@ -53,7 +53,7 @@ fn hard_fork_initiation_action_setters_getters_test() { #[test] fn new_committee_action_setters_getters_test() { - let action_id = create_action_id(); + let action_id = fake_action_id(); let committee = Committee::new(&UnitInterval::new(&BigNum::from(1u32), &BigNum::from(2u32))); let members_to_remove = Credentials::from_iter( vec![ @@ -79,8 +79,8 @@ fn new_committee_action_setters_getters_test() { #[test] fn new_constitution_action_setters_getters_test() { - let action_id = create_action_id(); - let constitution = Constitution::new(&create_anchor()); + let action_id = fake_action_id(); + let constitution = Constitution::new(&fake_anchor()); let proposal = NewConstitutionAction::new(&constitution); let proposal_with_action_id = NewConstitutionAction::new_with_action_id(&action_id, &constitution); @@ -92,7 +92,7 @@ fn new_constitution_action_setters_getters_test() { #[test] fn no_confidence_action_setters_getters_test() { - let action_id = create_action_id(); + let action_id = fake_action_id(); let proposal = NoConfidenceAction::new(); let proposal_with_action_id = NoConfidenceAction::new_with_action_id(&action_id); assert_eq!(proposal.gov_action_id(), None); @@ -101,8 +101,8 @@ fn no_confidence_action_setters_getters_test() { #[test] fn parameter_change_action_setters_getters_test() { - let protocol_params = crate_full_protocol_param_update(); - let action_id = create_action_id(); + let protocol_params = fake_full_protocol_param_update(); + let action_id = fake_action_id(); let policy_hash = fake_script_hash(1); let proposal = ParameterChangeAction::new(&protocol_params); let proposal_with_action_id = ParameterChangeAction::new_with_policy_hash_and_action_id( @@ -148,17 +148,17 @@ fn treasury_withdrawals_action() { fn voting_proposals_setters_getters_test() { let mut proposals = VotingProposals::new(); let no_confidence_action = NoConfidenceAction::new(); - let parameter_change_action = ParameterChangeAction::new(&crate_full_protocol_param_update()); + let parameter_change_action = ParameterChangeAction::new(&fake_full_protocol_param_update()); let proposal1 = VotingProposal::new( &GovernanceAction::new_no_confidence_action(&no_confidence_action), - &create_anchor(), + &fake_anchor(), &fake_reward_address(1), &Coin::from(100u32), ); let proposal2 = VotingProposal::new( &GovernanceAction::new_parameter_change_action(¶meter_change_action), - &create_anchor(), + &fake_anchor(), &fake_reward_address(2), &Coin::from(100u32), ); @@ -173,17 +173,17 @@ fn voting_proposals_setters_getters_test() { fn voting_proposals_deduplication_test() { let mut proposals = VotingProposals::new(); let no_confidence_action = NoConfidenceAction::new(); - let parameter_change_action = ParameterChangeAction::new(&crate_full_protocol_param_update()); + let parameter_change_action = ParameterChangeAction::new(&fake_full_protocol_param_update()); let proposal1 = VotingProposal::new( &GovernanceAction::new_no_confidence_action(&no_confidence_action), - &create_anchor(), + &fake_anchor(), &fake_reward_address(1), &Coin::from(100u32), ); let proposal2 = VotingProposal::new( &GovernanceAction::new_parameter_change_action(¶meter_change_action), - &create_anchor(), + &fake_anchor(), &fake_reward_address(2), &Coin::from(100u32), ); diff --git a/rust/src/tests/serialization/certificates.rs b/rust/src/tests/serialization/certificates.rs index 6fd95b90..72a9545f 100644 --- a/rust/src/tests/serialization/certificates.rs +++ b/rust/src/tests/serialization/certificates.rs @@ -1,4 +1,4 @@ -use crate::tests::mock_objects::{create_anchor, fake_anchor_data_hash, fake_genesis_delegate_hash, fake_genesis_hash, fake_key_hash, fake_pool_metadata_hash, fake_script_hash, fake_vrf_key_hash}; +use crate::tests::fakes::{fake_anchor, fake_anchor_data_hash, fake_genesis_delegate_hash, fake_genesis_hash, fake_key_hash, fake_pool_metadata_hash, fake_script_hash, fake_vrf_key_hash}; use crate::*; macro_rules! to_from_test { @@ -43,7 +43,7 @@ fn committee_cold_resign_key_hash_ser_round_trip() { #[test] fn committee_cold_resign_with_anchor_ser_round_trip() { - let anchor = create_anchor(); + let anchor = fake_anchor(); let cert = CommitteeColdResign::new_with_anchor(&Credential::from_keyhash(&fake_key_hash(1)), &anchor); let cert_wrapped = Certificate::new_committee_cold_resign(&cert); diff --git a/rust/src/tests/serialization/general.rs b/rust/src/tests/serialization/general.rs index d72efff7..eeb067bd 100644 --- a/rust/src/tests/serialization/general.rs +++ b/rust/src/tests/serialization/general.rs @@ -1,7 +1,7 @@ use crate::{Address, BigInt, BigNum, Block, BlockHash, CborContainerType, Coin, Credential, DataHash, ExUnits, HeaderBody, HeaderLeaderCertEnum, Int, KESVKey, MIRPot, MIRToStakeCredentials, MoveInstantaneousReward, NativeScript, OperationalCert, PlutusData, PlutusList, PlutusScript, PlutusScripts, ProtocolVersion, Redeemer, RedeemerTag, Redeemers, ScriptHash, ScriptRef, TimelockStart, TransactionBody, TransactionInputs, TransactionOutput, TransactionOutputs, TransactionWitnessSet, VRFCert, VRFVKey, Value, Vkeywitness, Vkeywitnesses, VersionedBlock, BlockEra, to_bytes, BootstrapWitnesses, Credentials, Ed25519KeyHashes}; use crate::protocol_types::ScriptRefEnum; -use crate::tests::mock_objects::{fake_base_address, fake_boostrap_witness, fake_bytes_32, fake_data_hash, fake_key_hash, fake_signature, fake_tx_input, fake_tx_output, fake_value, fake_value2, fake_vkey, fake_vkey_witness}; +use crate::tests::fakes::{fake_base_address, fake_boostrap_witness, fake_bytes_32, fake_data_hash, fake_key_hash, fake_signature, fake_tx_input, fake_tx_output, fake_value, fake_value2, fake_vkey, fake_vkey_witness}; #[test] fn tx_output_deser_lagacy() { diff --git a/rust/src/tests/serialization/governance/common.rs b/rust/src/tests/serialization/governance/common.rs index 11505e1b..fcf4db47 100644 --- a/rust/src/tests/serialization/governance/common.rs +++ b/rust/src/tests/serialization/governance/common.rs @@ -1,5 +1,5 @@ use crate::*; -use crate::tests::mock_objects::{fake_anchor_data_hash, fake_key_hash, fake_script_hash, fake_tx_hash}; +use crate::tests::fakes::{fake_anchor_data_hash, fake_key_hash, fake_script_hash, fake_tx_hash}; #[test] fn anchor_ser_round_trip() { diff --git a/rust/src/tests/serialization/governance/proposals.rs b/rust/src/tests/serialization/governance/proposals.rs index feba07d7..f8623e5b 100644 --- a/rust/src/tests/serialization/governance/proposals.rs +++ b/rust/src/tests/serialization/governance/proposals.rs @@ -1,4 +1,4 @@ -use crate::tests::mock_objects::{crate_full_protocol_param_update, create_anchor, fake_anchor_data_hash, fake_key_hash, fake_reward_address, fake_script_hash, fake_tx_hash}; +use crate::tests::fakes::{fake_full_protocol_param_update, fake_anchor, fake_anchor_data_hash, fake_key_hash, fake_reward_address, fake_script_hash, fake_tx_hash}; use crate::*; macro_rules! to_from_test { @@ -255,7 +255,7 @@ fn no_confidence_action_with_action_id_ser_round_trip() { #[test] fn parameter_change_action_ser_round_trip() { - let parameters_update = crate_full_protocol_param_update(); + let parameters_update = fake_full_protocol_param_update(); let proposal = ParameterChangeAction::new(¶meters_update); let proposal_wrapped = GovernanceAction::new_parameter_change_action(&proposal); to_from_test!(ParameterChangeAction, proposal, proposal_wrapped); @@ -268,7 +268,7 @@ fn parameter_change_action_ser_round_trip() { #[test] fn parameter_change_action_with_action_id_ser_round_trip() { let action_id = GovernanceActionId::new(&fake_tx_hash(1), 0); - let parameters_update = crate_full_protocol_param_update(); + let parameters_update = fake_full_protocol_param_update(); let proposal = ParameterChangeAction::new_with_action_id(&action_id, ¶meters_update); let proposal_wrapped = GovernanceAction::new_parameter_change_action(&proposal); to_from_test!(ParameterChangeAction, proposal, proposal_wrapped); @@ -280,7 +280,7 @@ fn parameter_change_action_with_action_id_ser_round_trip() { #[test] fn parameter_change_action_with_script_hash() { - let parameters_update = crate_full_protocol_param_update(); + let parameters_update = fake_full_protocol_param_update(); let script_hash = ScriptHash::from(fake_script_hash(1)); let proposal = ParameterChangeAction::new_with_policy_hash(¶meters_update, &script_hash); let proposal_wrapped = GovernanceAction::new_parameter_change_action(&proposal); @@ -363,19 +363,19 @@ fn voting_proposals_ser_round_trip() { let proposal1 = VotingProposal::new( &action1, - &create_anchor(), + &fake_anchor(), &fake_reward_address(1), &Coin::from(100u32), ); let proposal2 = VotingProposal::new( &action2, - &create_anchor(), + &fake_anchor(), &fake_reward_address(2), &Coin::from(200u32), ); let proposal3 = VotingProposal::new( &action3, - &create_anchor(), + &fake_anchor(), &fake_reward_address(3), &Coin::from(300u32), ); @@ -408,7 +408,7 @@ fn voting_proposal_round_trip_test() let proposal = VotingProposal::new( &action1, - &create_anchor(), + &fake_anchor(), &fake_reward_address(1), &Coin::from(100u32), ); diff --git a/rust/src/tests/serialization/protocol_param_update.rs b/rust/src/tests/serialization/protocol_param_update.rs index ef8399e1..a3ba4454 100644 --- a/rust/src/tests/serialization/protocol_param_update.rs +++ b/rust/src/tests/serialization/protocol_param_update.rs @@ -1,5 +1,5 @@ use crate::*; -use crate::tests::mock_objects::{create_cost_models, create_drep_voting_thresholds, create_pool_voting_thresholds}; +use crate::tests::fakes::{fake_cost_models, fake_drep_voting_thresholds, fake_pool_voting_thresholds}; #[test] fn protocol_param_update_ser_round_trip() { @@ -33,7 +33,7 @@ fn protocol_param_update_ser_round_trip() { protocol_version: Some(ProtocolVersion::new(1, 2)), min_pool_cost: Some(Coin::from(18_444u32)), ada_per_utxo_byte: Some(Coin::from(19_444u32)), - cost_models: Some(create_cost_models()), + cost_models: Some(fake_cost_models()), execution_costs: Some(ExUnitPrices::new( &SubCoin::new(&BigNum(577), &BigNum(10000)), &SubCoin::new(&BigNum(721), &BigNum(10000000)), @@ -43,8 +43,8 @@ fn protocol_param_update_ser_round_trip() { max_value_size: Some(20_444u32), collateral_percentage: Some(21_444u32), max_collateral_inputs: Some(22_444u32), - pool_voting_thresholds: Some(create_pool_voting_thresholds()), - drep_voting_thresholds: Some(create_drep_voting_thresholds()), + pool_voting_thresholds: Some(fake_pool_voting_thresholds()), + drep_voting_thresholds: Some(fake_drep_voting_thresholds()), min_committee_size: Some(23_444u32), committee_term_limit: Some(24_444u32), governance_action_validity_period: Some(25_444u32), diff --git a/rust/src/tests/serialization/transaction_body.rs b/rust/src/tests/serialization/transaction_body.rs index 3118fc8a..6b741e5a 100644 --- a/rust/src/tests/serialization/transaction_body.rs +++ b/rust/src/tests/serialization/transaction_body.rs @@ -1,5 +1,5 @@ use crate::*; -use crate::tests::mock_objects::{create_anchor, fake_asset_name, fake_auxiliary_data_hash, fake_base_address, fake_key_hash, fake_policy_id, fake_reward_address, fake_script_data_hash, fake_tx_hash, fake_tx_input}; +use crate::tests::fakes::{fake_anchor, fake_asset_name, fake_auxiliary_data_hash, fake_base_address, fake_key_hash, fake_policy_id, fake_reward_address, fake_script_data_hash, fake_tx_hash, fake_tx_input}; #[test] fn transaction_round_trip_test() { @@ -48,7 +48,7 @@ fn transaction_round_trip_test() { let action = GovernanceAction::new_info_action(&info_action); let proposal = VotingProposal::new( &action, - &create_anchor(), + &fake_anchor(), &fake_reward_address(3), &Coin::from(1_000_011u64), ); From 29e316bd413743c83296a45c8c66b68c3ac04b50 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 24 Jun 2024 19:07:48 +0700 Subject: [PATCH 307/349] move fees tests to test module --- rust/src/fees.rs | 595 +---------------------------------------- rust/src/tests/fees.rs | 588 ++++++++++++++++++++++++++++++++++++++++ rust/src/tests/mod.rs | 3 +- 3 files changed, 591 insertions(+), 595 deletions(-) create mode 100644 rust/src/tests/fees.rs diff --git a/rust/src/fees.rs b/rust/src/fees.rs index 5fc2d82b..bd9d8074 100644 --- a/rust/src/fees.rs +++ b/rust/src/fees.rs @@ -64,597 +64,4 @@ pub fn min_ref_script_fee(total_ref_scripts_size: usize, ref_script_coins_per_by let ref_multiplier : Rational = ref_script_coins_per_byte.into(); let total_fee = ref_multiplier.mul_usize(total_ref_scripts_size); total_fee.to_bignum_ceil() -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::TransactionOutputBuilder; - - // based off tx test vectors (https://gist.github.com/KtorZ/5a2089df0915f21aca368d12545ab230) - - // However, they don't match due to serialization differences in definite vs indefinite - // CBOR lengths for maps/arrays, thus for now we've got all the tests as >= instead. - // It's possible they're still off by a byte or two somewhere. - - #[test] - fn tx_simple_utxo() { - // # Vector #1: simple transaction - let mut inputs = TransactionInputs::new(); - inputs.add(&TransactionInput::new( - &TransactionHash::from_bytes( - hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") - .unwrap(), - ) - .unwrap(), - 0, - )); - let mut outputs = TransactionOutputs::new(); - - outputs.add( - &TransactionOutputBuilder::new() - .with_address( - &Address::from_bytes( - hex::decode("611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c") - .unwrap(), - ) - .unwrap(), - ) - .next() - .unwrap() - .with_coin(&BigNum(1)) - .build() - .unwrap(), - ); - let body = TransactionBody::new(&inputs, &outputs, &BigNum(94002), Some(10)); - - let mut w = TransactionWitnessSet::new(); - let mut vkw = Vkeywitnesses::new(); - vkw.add(&make_vkey_witness( - &hash_transaction(&body), - &PrivateKey::from_normal_bytes( - &hex::decode("c660e50315d76a53d80732efda7630cae8885dfb85c46378684b3c6103e1284a") - .unwrap(), - ) - .unwrap(), - )); - w.set_vkeys(&vkw); - - let signed_tx = Transaction::new(&body, &w, None); - - let linear_fee = LinearFee::new(&BigNum(500), &BigNum(2)); - assert_eq!( - hex::encode(signed_tx.to_bytes()), - "84a400818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a00016f32030aa10081825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee5840fae5de40c94d759ce13bf9886262159c4f26a289fd192e165995b785259e503f6887bf39dfa23a47cf163784c6eee23f61440e749bc1df3c73975f5231aeda0ff5f6" - ); - assert_eq!( - min_fee(&signed_tx, &linear_fee).unwrap().to_str(), - "94502" // todo: compare to Haskell fee to make sure the diff is not too big - ); - } - - #[test] - fn tx_simple_byron_utxo() { - let mut inputs = TransactionInputs::new(); - inputs.add(&TransactionInput::new( - &TransactionHash::from_bytes( - hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") - .unwrap(), - ) - .unwrap(), - 0, - )); - let mut outputs = TransactionOutputs::new(); - - outputs.add( - &TransactionOutputBuilder::new() - .with_address( - &Address::from_bytes( - hex::decode("611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c") - .unwrap(), - ) - .unwrap(), - ) - .next() - .unwrap() - .with_coin(&BigNum(1)) - .build() - .unwrap(), - ); - let body = TransactionBody::new(&inputs, &outputs, &BigNum(112002), Some(10)); - - let mut w = TransactionWitnessSet::new(); - let mut bootstrap_wits = BootstrapWitnesses::new(); - bootstrap_wits.add(&make_icarus_bootstrap_witness( - &hash_transaction(&body), - &ByronAddress::from_base58("Ae2tdPwUPEZ6r6zbg4ibhFrNnyKHg7SYuPSfDpjKxgvwFX9LquRep7gj7FQ").unwrap(), - &Bip32PrivateKey::from_bytes( - &hex::decode("d84c65426109a36edda5375ea67f1b738e1dacf8629f2bb5a2b0b20f3cd5075873bf5cdfa7e533482677219ac7d639e30a38e2e645ea9140855f44ff09e60c52c8b95d0d35fe75a70f9f5633a3e2439b2994b9e2bc851c49e9f91d1a5dcbb1a3").unwrap() - ).unwrap() - )); - w.set_bootstraps(&bootstrap_wits); - - let signed_tx = Transaction::new(&body, &w, None); - - let linear_fee = LinearFee::new(&BigNum(500), &BigNum(2)); - assert_eq!( - hex::encode(signed_tx.to_bytes()), - "84a400818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a0001b582030aa10281845820473811afd4d939b337c9be1a2ceeb2cb2c75108bddf224c5c21c51592a7b204a5840f0b04a852353eb23b9570df80b2aa6a61b723341ab45a2024a05b07cf58be7bdfbf722c09040db6cee61a0d236870d6ad1e1349ac999ec0db28f9471af25fb0c5820c8b95d0d35fe75a70f9f5633a3e2439b2994b9e2bc851c49e9f91d1a5dcbb1a341a0f5f6" - ); - assert_eq!( - min_fee(&signed_tx, &linear_fee).unwrap().to_str(), - "112502" // todo: compare to Haskell fee to make sure the diff is not too big - ); - } - - #[test] - fn tx_multi_utxo() { - // # Vector #2: multiple outputs and inputs - let mut inputs = TransactionInputs::new(); - inputs.add(&TransactionInput::new( - &TransactionHash::from_bytes( - hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") - .unwrap(), - ) - .unwrap(), - 42, - )); - inputs.add(&TransactionInput::new( - &TransactionHash::from_bytes( - hex::decode("82839f8200d81858248258203b40265111d8bb3c3c608d95b3a0bf83461ace32") - .unwrap(), - ) - .unwrap(), - 7, - )); - let mut outputs = TransactionOutputs::new(); - - outputs.add( - &TransactionOutputBuilder::new() - .with_address( - &Address::from_bytes( - hex::decode("611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c") - .unwrap(), - ) - .unwrap(), - ) - .next() - .unwrap() - .with_coin(&BigNum(289)) - .build() - .unwrap(), - ); - outputs.add( - &TransactionOutputBuilder::new() - .with_address( - &Address::from_bytes( - hex::decode("61bcd18fcffa797c16c007014e2b8553b8b9b1e94c507688726243d611") - .unwrap(), - ) - .unwrap(), - ) - .next() - .unwrap() - .with_coin(&BigNum(874551452)) - .build() - .unwrap(), - ); - let body = TransactionBody::new(&inputs, &outputs, &BigNum(183502), Some(999)); - - let mut w = TransactionWitnessSet::new(); - let mut vkw = Vkeywitnesses::new(); - vkw.add(&make_vkey_witness( - &hash_transaction(&body), - &PrivateKey::from_normal_bytes( - &hex::decode("c660e50315d76a53d80732efda7630cae8885dfb85c46378684b3c6103e1284a") - .unwrap(), - ) - .unwrap(), - )); - vkw.add(&make_vkey_witness( - &hash_transaction(&body), - &PrivateKey::from_normal_bytes( - &hex::decode("13fe79205e16c09536acb6f0524d04069f380329d13949698c5f22c65c989eb4") - .unwrap(), - ) - .unwrap(), - )); - w.set_vkeys(&vkw); - - let signed_tx = Transaction::new(&body, &w, None); - - let linear_fee = LinearFee::new(&BigNum(500), &BigNum(2)); - assert_eq!( - hex::encode(signed_tx.to_bytes()), - "84a400828258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7182a82582082839f8200d81858248258203b40265111d8bb3c3c608d95b3a0bf83461ace3207018282581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c19012182581d61bcd18fcffa797c16c007014e2b8553b8b9b1e94c507688726243d6111a3420989c021a0002ccce031903e7a10082825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee58401ec3e56008650282ba2e1f8a20e81707810b2d0973c4d42a1b4df65b732bda81567c7824904840b2554d2f33861da5d70588a29d33b2b61042e3c3445301d8008258206872b0a874acfe1cace12b20ea348559a7ecc912f2fc7f674f43481df973d92c5840a0718fb5b37d89ddf926c08e456d3f4c7f749e91f78bb3e370751d5b632cbd20d38d385805291b1ef2541b02543728a235e01911f4b400bfb50e5fce589de907f5f6" - ); - assert_eq!( - min_fee(&signed_tx, &linear_fee).unwrap().to_str(), - "184002" // todo: compare to Haskell fee to make sure the diff is not too big - ); - } - - #[test] - fn tx_register_stake() { - // # Vector #3: with stake pool registration certificate - let network = 1; - let mut inputs = TransactionInputs::new(); - inputs.add(&TransactionInput::new( - &TransactionHash::from_bytes( - hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") - .unwrap(), - ) - .unwrap(), - 0, - )); - let mut outputs = TransactionOutputs::new(); - - outputs.add( - &TransactionOutputBuilder::new() - .with_address( - &Address::from_bytes( - hex::decode("611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c") - .unwrap(), - ) - .unwrap(), - ) - .next() - .unwrap() - .with_coin(&BigNum(1)) - .build() - .unwrap(), - ); - let mut body = TransactionBody::new(&inputs, &outputs, &BigNum(266002), Some(10)); - - let mut certs = Certificates::new(); - - let mut pool_owners = Ed25519KeyHashes::new(); - pool_owners.add( - &PublicKey::from_bytes( - &hex::decode("54d1a9c5ad69586ceeb839c438400c376c0bd34825fb4c17cc2f58c54e1437f3") - .unwrap(), - ) - .unwrap() - .hash(), - ); - let registration_cert = PoolRegistration::new(&PoolParams::new( - &PublicKey::from_bytes( - &hex::decode("b24c040e65994bd5b0621a060166d32d356ef4be3cc1f848426a4cf386887089") - .unwrap(), - ) - .unwrap() - .hash(), // operator - &VRFKeyHash::from(blake2b256( - &hex::decode("fbf6d41985670b9041c5bf362b5262cf34add5d265975de176d613ca05f37096") - .unwrap(), - )), // vrf_keyhash - &BigNum(1000000), // pledge - &BigNum(1000000), // cost - &UnitInterval::new(&BigNum(3), &BigNum(100)), // margin - &RewardAddress::new( - network, - &Credential::from_keyhash( - &PublicKey::from_bytes( - &hex::decode( - "54d1a9c5ad69586ceeb839c438400c376c0bd34825fb4c17cc2f58c54e1437f3", - ) - .unwrap(), - ) - .unwrap() - .hash(), - ), - ), // reward_address - &pool_owners, // pool_owners - &Relays::new(), // relays - None, // metadata - )); - certs.add(&Certificate::new_pool_registration(®istration_cert)); - body.set_certs(&certs); - - let mut w = TransactionWitnessSet::new(); - let mut vkw = Vkeywitnesses::new(); - // input key witness - vkw.add(&make_vkey_witness( - &hash_transaction(&body), - &PrivateKey::from_normal_bytes( - &hex::decode("c660e50315d76a53d80732efda7630cae8885dfb85c46378684b3c6103e1284a") - .unwrap(), - ) - .unwrap(), - )); - // operator key witness - vkw.add(&make_vkey_witness( - &hash_transaction(&body), - &PrivateKey::from_normal_bytes( - &hex::decode("2363f3660b9f3b41685665bf10632272e2d03c258e8a5323436f0f3406293505") - .unwrap(), - ) - .unwrap(), - )); - // owner key witness - vkw.add(&make_vkey_witness( - &hash_transaction(&body), - &PrivateKey::from_normal_bytes( - &hex::decode("5ada7f4d92bce1ee1707c0a0e211eb7941287356e6ed0e76843806e307b07c8d") - .unwrap(), - ) - .unwrap(), - )); - w.set_vkeys(&vkw); - - let signed_tx = Transaction::new(&body, &w, None); - - let linear_fee = LinearFee::new(&BigNum(500), &BigNum(2)); - assert_eq!( - hex::encode(signed_tx.to_bytes()), - "84a500818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a00040f12030a04818a03581c1c13374874c68016df54b1339b6cacdd801098431e7659b24928efc15820bd0000f498ccacdc917c28274cba51c415f3f21931ff41ca8dc1197499f8e1241a000f42401a000f4240d81e82031864581de151df9ba1b74a1c9608a487e114184556801e927d31d96425cb80af7081581c51df9ba1b74a1c9608a487e114184556801e927d31d96425cb80af7080f6a10083825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee5840a7f305d7e46abfe0f7bea6098bdf853ab9ce8e7aa381be5a991a871852f895a718e20614e22be43494c4dc3a8c78c56cd44fd38e0e5fff3e2fbd19f70402fc02825820b24c040e65994bd5b0621a060166d32d356ef4be3cc1f848426a4cf386887089584013c372f82f1523484eab273241d66d92e1402507760e279480912aa5f0d88d656d6f25d41e65257f2f38c65ac5c918a6735297741adfc718394994f20a1cfd0082582054d1a9c5ad69586ceeb839c438400c376c0bd34825fb4c17cc2f58c54e1437f35840d326b993dfec21b9b3e1bd2f80adadc2cd673a1d8d033618cc413b0b02bc3b7efbb23d1ff99138abd05c398ce98e7983a641b50dcf0f64ed33f26c6e636b0b0ff5f6" - ); - assert_eq!( - min_fee(&signed_tx, &linear_fee).unwrap().to_str(), - "269502" // todo: compare to Haskell fee to make sure the diff is not too big - ); - } - - // #[test] - // fn tx_delegate_stake() { - // let mut inputs = TransactionInputs::new(); - // inputs.add(&TransactionInput::new(&genesis_id(), 0)); - // let mut outputs = TransactionOutputs::new(); - // outputs.add(&TransactionOutput::new(&alice_addr(), BigNum(10))); - // let mut body = TransactionBody::new(&inputs, &outputs, BigNum(94), 10); - // let mut certs = Certificates::new(); - // certs.add(&Certificate::new_stake_delegation(&StakeDelegation::new(&bob_stake(), &alice_pool()))); - // body.set_certs(&certs); - // let w = make_mock_witnesses_vkey(&body, vec![&alice_key(), &bob_key()]); - // let tx = Transaction::new(&body, &w, None); - // let haskell_crypto_bytes = witness_vkey_bytes_haskell(&w) + HASKELL_HLEN * 2; - // let our_crypto_bytes = witness_vkey_bytes_rust(&w) + Ed25519KeyHash::BYTE_COUNT + Ed25519KeyHash::BYTE_COUNT; - // assert!(txsize(&tx) - our_crypto_bytes + haskell_crypto_bytes >= 178); - // } - - // #[test] - // fn tx_deregister_stake() { - // let mut inputs = TransactionInputs::new(); - // inputs.add(&TransactionInput::new(&genesis_id(), 0)); - // let mut outputs = TransactionOutputs::new(); - // outputs.add(&TransactionOutput::new(&alice_addr(), BigNum(10))); - // let mut body = TransactionBody::new(&inputs, &outputs, BigNum(94), 10); - // let mut certs = Certificates::new(); - // certs.add(&Certificate::new_stake_deregistration(&StakeDeregistration::new(&alice_pay()))); - // body.set_certs(&certs); - // let w = make_mock_witnesses_vkey(&body, vec![&alice_key()]); - // let tx = Transaction::new(&body, &w, None); - // let haskell_crypto_bytes = witness_vkey_bytes_haskell(&w) + HASKELL_HLEN; - // let our_crypto_bytes = witness_vkey_bytes_rust(&w) + Ed25519KeyHash::BYTE_COUNT; - // assert!(txsize(&tx) - our_crypto_bytes + haskell_crypto_bytes >= 150); - // } - - // #[test] - // fn tx_register_pool() { - // let mut inputs = TransactionInputs::new(); - // inputs.add(&TransactionInput::new(&genesis_id(), 0)); - // let mut outputs = TransactionOutputs::new(); - // outputs.add(&TransactionOutput::new(&alice_addr(), BigNum(10))); - // let mut body = TransactionBody::new(&inputs, &outputs, BigNum(94), 10); - // let mut certs = Certificates::new(); - // let mut owners = Ed25519KeyHashes::new(); - // owners.add(&(alice_stake().to_keyhash().unwrap())); - // let mut relays = Relays::new(); - // relays.add(&Relay::new_single_host_name(&SingleHostName::new(None, String::from("relay.io")))); - // let params = PoolParams::new( - // &alice_pool(), - // &VRFKeyHash::from([0u8; VRFKeyHash::BYTE_COUNT]), - // BigNum(1), - // BigNum(5), - // &UnitInterval::new(BigNum(1), BigNum(10)), - // &RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &alice_stake()), - // &owners, - // &relays, - // Some(PoolMetadata::new(String::from("alice.pool"), &MetadataHash::from([0u8; MetadataHash::BYTE_COUNT]))) - // ); - // certs.add(&Certificate::new_pool_registration(&PoolRegistration::new(¶ms))); - // body.set_certs(&certs); - // let w = make_mock_witnesses_vkey(&body, vec![&alice_key()]); - // let tx = Transaction::new(&body, &w, None); - // let haskell_crypto_bytes = witness_vkey_bytes_haskell(&w) - // + HASKELL_HLEN // operator pool keyhash - // + HASKELL_HLEN // vrf keyhash - // + HASKELL_HLEN // reward account - // + owners.len() * HASKELL_HLEN // owners' keyhashes - // + HASKELL_HLEN; // metadata hash - // let our_crypto_bytes = witness_vkey_bytes_rust(&w) - // + Ed25519KeyHash::BYTE_COUNT - // + VRFKeyHash::BYTE_COUNT - // + Ed25519KeyHash::BYTE_COUNT - // + owners.len() * Ed25519KeyHash::BYTE_COUNT - // + MetadataHash::BYTE_COUNT; - // assert!(txsize(&tx) - our_crypto_bytes + haskell_crypto_bytes >= 200); - // } - - // #[test] - // fn tx_retire_pool() { - // let mut inputs = TransactionInputs::new(); - // inputs.add(&TransactionInput::new(&genesis_id(), 0)); - // let mut outputs = TransactionOutputs::new(); - // outputs.add(&TransactionOutput::new(&alice_addr(), BigNum(10))); - // let mut body = TransactionBody::new(&inputs, &outputs, BigNum(94), 10); - // let mut certs = Certificates::new(); - // certs.add(&Certificate::new_pool_retirement(&PoolRetirement::new(&alice_pool(), 5))); - // body.set_certs(&certs); - // let w = make_mock_witnesses_vkey(&body, vec![&alice_key()]); - // let tx = Transaction::new(&body, &w, None); - // let haskell_crypto_bytes = witness_vkey_bytes_haskell(&w) + HASKELL_HLEN; - // let our_crypto_bytes = witness_vkey_bytes_rust(&w) + Ed25519KeyHash::BYTE_COUNT; - // assert!(txsize(&tx) - our_crypto_bytes + haskell_crypto_bytes >= 149); - // } - - // #[test] - // fn tx_metadata() { - // let mut inputs = TransactionInputs::new(); - // inputs.add(&TransactionInput::new(&genesis_id(), 0)); - // let mut outputs = TransactionOutputs::new(); - // outputs.add(&TransactionOutput::new(&alice_addr(), BigNum(10))); - // let mut body = TransactionBody::new(&inputs, &outputs, BigNum(94), 10); - // body.set_metadata_hash(&MetadataHash::from([37; MetadataHash::BYTE_COUNT])); - // let w = make_mock_witnesses_vkey(&body, vec![&alice_key()]); - // let mut metadata = TransactionMetadata::new(); - // let mut md_list = TransactionMetadatums::new(); - // md_list.add(&TransactionMetadatum::new_int(&Int::new(&BigNum(5)))); - // md_list.add(&TransactionMetadatum::new_text(String::from("hello"))); - // metadata.insert(TransactionMetadatumLabel::new(0), &TransactionMetadatum::new_arr_transaction_metadatum(&md_list)); - // let tx = Transaction::new(&body, &w, Some(metadata)); - // let haskell_crypto_bytes = witness_vkey_bytes_haskell(&w) + HASKELL_HLEN; - // let our_crypto_bytes = witness_vkey_bytes_rust(&w) + MetadataHash::BYTE_COUNT; - // assert!(txsize(&tx) - our_crypto_bytes + haskell_crypto_bytes >= 154); - // } - - // #[test] - // fn tx_multisig() { - // let mut inputs = TransactionInputs::new(); - // inputs.add(&TransactionInput::new(&genesis_id(), 0)); - // let mut outputs = TransactionOutputs::new(); - // outputs.add(&TransactionOutput::new(&alice_addr(), BigNum(10))); - // let body = TransactionBody::new(&inputs, &outputs, BigNum(94), 10); - // let mut w = make_mock_witnesses_vkey(&body, vec![&alice_key(), &bob_key()]); - // let mut script_witnesses = MultisigScripts::new(); - // let mut inner_scripts = MultisigScripts::new(); - // inner_scripts.add(&MultisigScript::new_msig_pubkey(&alice_pay().to_keyhash().unwrap())); - // inner_scripts.add(&MultisigScript::new_msig_pubkey(&bob_pay().to_keyhash().unwrap())); - // inner_scripts.add(&MultisigScript::new_msig_pubkey(&carl_pay().to_keyhash().unwrap())); - // script_witnesses.add(&MultisigScript::new_msig_n_of_k(2, &inner_scripts)); - // w.set_scripts(&script_witnesses); - // let tx = Transaction::new(&body, &w, None); - // let haskell_crypto_bytes = witness_vkey_bytes_haskell(&w); - // let our_crypto_bytes = witness_vkey_bytes_rust(&w); - // assert!(txsize(&tx) - our_crypto_bytes + haskell_crypto_bytes - haskell_multisig_byte_diff(&script_witnesses) >= 189); - // } - - #[test] - fn tx_withdrawal() { - // # Vector #8: with reward withdrawal - let mut inputs = TransactionInputs::new(); - inputs.add(&TransactionInput::new( - &TransactionHash::from_bytes( - hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") - .unwrap(), - ) - .unwrap(), - 0, - )); - let mut outputs = TransactionOutputs::new(); - - outputs.add( - &TransactionOutputBuilder::new() - .with_address( - &Address::from_bytes( - hex::decode("611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c") - .unwrap(), - ) - .unwrap(), - ) - .next() - .unwrap() - .with_coin(&BigNum(1)) - .build() - .unwrap(), - ); - let mut body = TransactionBody::new(&inputs, &outputs, &BigNum(162502), Some(10)); - let mut withdrawals = Withdrawals::new(); - withdrawals.insert( - &RewardAddress::from_address( - &Address::from_bytes( - hex::decode("e151df9ba1b74a1c9608a487e114184556801e927d31d96425cb80af70") - .unwrap(), - ) - .unwrap(), - ) - .unwrap(), - &BigNum(1337), - ); - body.set_withdrawals(&withdrawals); - - let mut w = TransactionWitnessSet::new(); - let mut vkw = Vkeywitnesses::new(); - // input key witness - vkw.add(&make_vkey_witness( - &hash_transaction(&body), - &PrivateKey::from_normal_bytes( - &hex::decode("c660e50315d76a53d80732efda7630cae8885dfb85c46378684b3c6103e1284a") - .unwrap(), - ) - .unwrap(), - )); - // withdrawal key witness - vkw.add(&make_vkey_witness( - &hash_transaction(&body), - &PrivateKey::from_normal_bytes( - &hex::decode("5ada7f4d92bce1ee1707c0a0e211eb7941287356e6ed0e76843806e307b07c8d") - .unwrap(), - ) - .unwrap(), - )); - w.set_vkeys(&vkw); - - let signed_tx = Transaction::new(&body, &w, None); - - let linear_fee = LinearFee::new(&BigNum(500), &BigNum(2)); - assert_eq!( - hex::encode(signed_tx.to_bytes()), - "84a500818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a00027ac6030a05a1581de151df9ba1b74a1c9608a487e114184556801e927d31d96425cb80af70190539a10082825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee5840fc0493f7121efe385d72830680e735ccdef99c3a31953fe877b89ad3a97fcdb871cc7f2cdd6a8104e52f6963bd9e10d814d4fabdbcdc8475bc63e872dcc94d0a82582054d1a9c5ad69586ceeb839c438400c376c0bd34825fb4c17cc2f58c54e1437f35840a051ba927582004aedab736b9f1f9330ff867c260f4751135d480074256e83cd23d2a4bb109f955c43afdcdc5d1841b28d5c1ea2148dfbb6252693590692bb00f5f6" - ); - assert_eq!( - min_fee(&signed_tx, &linear_fee).unwrap().to_str(), - "163002" // todo: compare to Haskell fee to make sure the diff is not too big - ); - } - - fn exunits(mem: u64, steps: u64) -> ExUnits { - ExUnits::new(&BigNum(mem), &BigNum(steps)) - } - - fn subcoin(num: u64, denum: u64) -> SubCoin { - SubCoin::new(&BigNum(num), &BigNum(denum)) - } - - fn exunit_prices(mem_prices: (u64, u64), step_prices: (u64, u64)) -> ExUnitPrices { - ExUnitPrices::new( - &subcoin(mem_prices.0, mem_prices.1), - &subcoin(step_prices.0, step_prices.1), - ) - } - - fn _calculate_ex_units_ceil_cost( - mem: u64, - steps: u64, - mem_prices: (u64, u64), - step_prices: (u64, u64), - ) -> Coin { - let ex_units = exunits(mem, steps); - let ex_unit_prices = exunit_prices(mem_prices, step_prices); - calculate_ex_units_ceil_cost(&ex_units, &ex_unit_prices).unwrap() - } - - #[test] - fn test_calc_ex_units_cost() { - // 10 * (2/1) + 20 * (3/1) = 10 * 2 + 20 * 3 = 20 + 60 - assert_eq!( - _calculate_ex_units_ceil_cost(10, 20, (2, 1), (3, 1)), - BigNum(80), - ); - // 22 * (12/6) + 33 * (33/11) = 22 * 2 + 33 * 3 = 44 + 99 = 143 - assert_eq!( - _calculate_ex_units_ceil_cost(22, 33, (12, 6), (33, 11)), - BigNum(143), - ); - // 10 * (5/7) + 20 * (9/13) = 50/7 + 180/13 = 650/91 + 1260/91 = 1910/91 = ceil(20.98) = 21 - assert_eq!( - _calculate_ex_units_ceil_cost(10, 20, (5, 7), (9, 13)), - BigNum(21), - ); - // 22 * (7/5) + 33 * (13/9) = 154/5 + 429/9 = 1386/45 + 2145/45 = 3531/45 = ceil(78.46) = 79 - assert_eq!( - _calculate_ex_units_ceil_cost(22, 33, (7, 5), (13, 9)), - BigNum(79), - ); - } -} +} \ No newline at end of file diff --git a/rust/src/tests/fees.rs b/rust/src/tests/fees.rs new file mode 100644 index 00000000..04de0d19 --- /dev/null +++ b/rust/src/tests/fees.rs @@ -0,0 +1,588 @@ +use crate::TransactionOutputBuilder; +use crate::*; + +// based off tx test vectors (https://gist.github.com/KtorZ/5a2089df0915f21aca368d12545ab230) + +// However, they don't match due to serialization differences in definite vs indefinite +// CBOR lengths for maps/arrays, thus for now we've got all the tests as >= instead. +// It's possible they're still off by a byte or two somewhere. + +#[test] +fn tx_simple_utxo() { + // # Vector #1: simple transaction + let mut inputs = TransactionInputs::new(); + inputs.add(&TransactionInput::new( + &TransactionHash::from_bytes( + hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") + .unwrap(), + ) + .unwrap(), + 0, + )); + let mut outputs = TransactionOutputs::new(); + + outputs.add( + &TransactionOutputBuilder::new() + .with_address( + &Address::from_bytes( + hex::decode("611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c") + .unwrap(), + ) + .unwrap(), + ) + .next() + .unwrap() + .with_coin(&BigNum(1)) + .build() + .unwrap(), + ); + let body = TransactionBody::new(&inputs, &outputs, &BigNum(94002), Some(10)); + + let mut w = TransactionWitnessSet::new(); + let mut vkw = Vkeywitnesses::new(); + vkw.add(&make_vkey_witness( + &hash_transaction(&body), + &PrivateKey::from_normal_bytes( + &hex::decode("c660e50315d76a53d80732efda7630cae8885dfb85c46378684b3c6103e1284a") + .unwrap(), + ) + .unwrap(), + )); + w.set_vkeys(&vkw); + + let signed_tx = Transaction::new(&body, &w, None); + + let linear_fee = LinearFee::new(&BigNum(500), &BigNum(2)); + assert_eq!( + hex::encode(signed_tx.to_bytes()), + "84a400818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a00016f32030aa10081825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee5840fae5de40c94d759ce13bf9886262159c4f26a289fd192e165995b785259e503f6887bf39dfa23a47cf163784c6eee23f61440e749bc1df3c73975f5231aeda0ff5f6" + ); + assert_eq!( + min_fee(&signed_tx, &linear_fee).unwrap().to_str(), + "94502" // todo: compare to Haskell fee to make sure the diff is not too big + ); +} + +#[test] +fn tx_simple_byron_utxo() { + let mut inputs = TransactionInputs::new(); + inputs.add(&TransactionInput::new( + &TransactionHash::from_bytes( + hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") + .unwrap(), + ) + .unwrap(), + 0, + )); + let mut outputs = TransactionOutputs::new(); + + outputs.add( + &TransactionOutputBuilder::new() + .with_address( + &Address::from_bytes( + hex::decode("611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c") + .unwrap(), + ) + .unwrap(), + ) + .next() + .unwrap() + .with_coin(&BigNum(1)) + .build() + .unwrap(), + ); + let body = TransactionBody::new(&inputs, &outputs, &BigNum(112002), Some(10)); + + let mut w = TransactionWitnessSet::new(); + let mut bootstrap_wits = BootstrapWitnesses::new(); + bootstrap_wits.add(&make_icarus_bootstrap_witness( + &hash_transaction(&body), + &ByronAddress::from_base58("Ae2tdPwUPEZ6r6zbg4ibhFrNnyKHg7SYuPSfDpjKxgvwFX9LquRep7gj7FQ").unwrap(), + &Bip32PrivateKey::from_bytes( + &hex::decode("d84c65426109a36edda5375ea67f1b738e1dacf8629f2bb5a2b0b20f3cd5075873bf5cdfa7e533482677219ac7d639e30a38e2e645ea9140855f44ff09e60c52c8b95d0d35fe75a70f9f5633a3e2439b2994b9e2bc851c49e9f91d1a5dcbb1a3").unwrap() + ).unwrap() + )); + w.set_bootstraps(&bootstrap_wits); + + let signed_tx = Transaction::new(&body, &w, None); + + let linear_fee = LinearFee::new(&BigNum(500), &BigNum(2)); + assert_eq!( + hex::encode(signed_tx.to_bytes()), + "84a400818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a0001b582030aa10281845820473811afd4d939b337c9be1a2ceeb2cb2c75108bddf224c5c21c51592a7b204a5840f0b04a852353eb23b9570df80b2aa6a61b723341ab45a2024a05b07cf58be7bdfbf722c09040db6cee61a0d236870d6ad1e1349ac999ec0db28f9471af25fb0c5820c8b95d0d35fe75a70f9f5633a3e2439b2994b9e2bc851c49e9f91d1a5dcbb1a341a0f5f6" + ); + assert_eq!( + min_fee(&signed_tx, &linear_fee).unwrap().to_str(), + "112502" // todo: compare to Haskell fee to make sure the diff is not too big + ); +} + +#[test] +fn tx_multi_utxo() { + // # Vector #2: multiple outputs and inputs + let mut inputs = TransactionInputs::new(); + inputs.add(&TransactionInput::new( + &TransactionHash::from_bytes( + hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") + .unwrap(), + ) + .unwrap(), + 42, + )); + inputs.add(&TransactionInput::new( + &TransactionHash::from_bytes( + hex::decode("82839f8200d81858248258203b40265111d8bb3c3c608d95b3a0bf83461ace32") + .unwrap(), + ) + .unwrap(), + 7, + )); + let mut outputs = TransactionOutputs::new(); + + outputs.add( + &TransactionOutputBuilder::new() + .with_address( + &Address::from_bytes( + hex::decode("611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c") + .unwrap(), + ) + .unwrap(), + ) + .next() + .unwrap() + .with_coin(&BigNum(289)) + .build() + .unwrap(), + ); + outputs.add( + &TransactionOutputBuilder::new() + .with_address( + &Address::from_bytes( + hex::decode("61bcd18fcffa797c16c007014e2b8553b8b9b1e94c507688726243d611") + .unwrap(), + ) + .unwrap(), + ) + .next() + .unwrap() + .with_coin(&BigNum(874551452)) + .build() + .unwrap(), + ); + let body = TransactionBody::new(&inputs, &outputs, &BigNum(183502), Some(999)); + + let mut w = TransactionWitnessSet::new(); + let mut vkw = Vkeywitnesses::new(); + vkw.add(&make_vkey_witness( + &hash_transaction(&body), + &PrivateKey::from_normal_bytes( + &hex::decode("c660e50315d76a53d80732efda7630cae8885dfb85c46378684b3c6103e1284a") + .unwrap(), + ) + .unwrap(), + )); + vkw.add(&make_vkey_witness( + &hash_transaction(&body), + &PrivateKey::from_normal_bytes( + &hex::decode("13fe79205e16c09536acb6f0524d04069f380329d13949698c5f22c65c989eb4") + .unwrap(), + ) + .unwrap(), + )); + w.set_vkeys(&vkw); + + let signed_tx = Transaction::new(&body, &w, None); + + let linear_fee = LinearFee::new(&BigNum(500), &BigNum(2)); + assert_eq!( + hex::encode(signed_tx.to_bytes()), + "84a400828258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7182a82582082839f8200d81858248258203b40265111d8bb3c3c608d95b3a0bf83461ace3207018282581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c19012182581d61bcd18fcffa797c16c007014e2b8553b8b9b1e94c507688726243d6111a3420989c021a0002ccce031903e7a10082825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee58401ec3e56008650282ba2e1f8a20e81707810b2d0973c4d42a1b4df65b732bda81567c7824904840b2554d2f33861da5d70588a29d33b2b61042e3c3445301d8008258206872b0a874acfe1cace12b20ea348559a7ecc912f2fc7f674f43481df973d92c5840a0718fb5b37d89ddf926c08e456d3f4c7f749e91f78bb3e370751d5b632cbd20d38d385805291b1ef2541b02543728a235e01911f4b400bfb50e5fce589de907f5f6" + ); + assert_eq!( + min_fee(&signed_tx, &linear_fee).unwrap().to_str(), + "184002" // todo: compare to Haskell fee to make sure the diff is not too big + ); +} + +#[test] +fn tx_register_stake() { + // # Vector #3: with stake pool registration certificate + let network = 1; + let mut inputs = TransactionInputs::new(); + inputs.add(&TransactionInput::new( + &TransactionHash::from_bytes( + hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") + .unwrap(), + ) + .unwrap(), + 0, + )); + let mut outputs = TransactionOutputs::new(); + + outputs.add( + &TransactionOutputBuilder::new() + .with_address( + &Address::from_bytes( + hex::decode("611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c") + .unwrap(), + ) + .unwrap(), + ) + .next() + .unwrap() + .with_coin(&BigNum(1)) + .build() + .unwrap(), + ); + let mut body = TransactionBody::new(&inputs, &outputs, &BigNum(266002), Some(10)); + + let mut certs = Certificates::new(); + + let mut pool_owners = Ed25519KeyHashes::new(); + pool_owners.add( + &PublicKey::from_bytes( + &hex::decode("54d1a9c5ad69586ceeb839c438400c376c0bd34825fb4c17cc2f58c54e1437f3") + .unwrap(), + ) + .unwrap() + .hash(), + ); + let registration_cert = PoolRegistration::new(&PoolParams::new( + &PublicKey::from_bytes( + &hex::decode("b24c040e65994bd5b0621a060166d32d356ef4be3cc1f848426a4cf386887089") + .unwrap(), + ) + .unwrap() + .hash(), // operator + &VRFKeyHash::from(blake2b256( + &hex::decode("fbf6d41985670b9041c5bf362b5262cf34add5d265975de176d613ca05f37096") + .unwrap(), + )), // vrf_keyhash + &BigNum(1000000), // pledge + &BigNum(1000000), // cost + &UnitInterval::new(&BigNum(3), &BigNum(100)), // margin + &RewardAddress::new( + network, + &Credential::from_keyhash( + &PublicKey::from_bytes( + &hex::decode( + "54d1a9c5ad69586ceeb839c438400c376c0bd34825fb4c17cc2f58c54e1437f3", + ) + .unwrap(), + ) + .unwrap() + .hash(), + ), + ), // reward_address + &pool_owners, // pool_owners + &Relays::new(), // relays + None, // metadata + )); + certs.add(&Certificate::new_pool_registration(®istration_cert)); + body.set_certs(&certs); + + let mut w = TransactionWitnessSet::new(); + let mut vkw = Vkeywitnesses::new(); + // input key witness + vkw.add(&make_vkey_witness( + &hash_transaction(&body), + &PrivateKey::from_normal_bytes( + &hex::decode("c660e50315d76a53d80732efda7630cae8885dfb85c46378684b3c6103e1284a") + .unwrap(), + ) + .unwrap(), + )); + // operator key witness + vkw.add(&make_vkey_witness( + &hash_transaction(&body), + &PrivateKey::from_normal_bytes( + &hex::decode("2363f3660b9f3b41685665bf10632272e2d03c258e8a5323436f0f3406293505") + .unwrap(), + ) + .unwrap(), + )); + // owner key witness + vkw.add(&make_vkey_witness( + &hash_transaction(&body), + &PrivateKey::from_normal_bytes( + &hex::decode("5ada7f4d92bce1ee1707c0a0e211eb7941287356e6ed0e76843806e307b07c8d") + .unwrap(), + ) + .unwrap(), + )); + w.set_vkeys(&vkw); + + let signed_tx = Transaction::new(&body, &w, None); + + let linear_fee = LinearFee::new(&BigNum(500), &BigNum(2)); + assert_eq!( + hex::encode(signed_tx.to_bytes()), + "84a500818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a00040f12030a04818a03581c1c13374874c68016df54b1339b6cacdd801098431e7659b24928efc15820bd0000f498ccacdc917c28274cba51c415f3f21931ff41ca8dc1197499f8e1241a000f42401a000f4240d81e82031864581de151df9ba1b74a1c9608a487e114184556801e927d31d96425cb80af7081581c51df9ba1b74a1c9608a487e114184556801e927d31d96425cb80af7080f6a10083825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee5840a7f305d7e46abfe0f7bea6098bdf853ab9ce8e7aa381be5a991a871852f895a718e20614e22be43494c4dc3a8c78c56cd44fd38e0e5fff3e2fbd19f70402fc02825820b24c040e65994bd5b0621a060166d32d356ef4be3cc1f848426a4cf386887089584013c372f82f1523484eab273241d66d92e1402507760e279480912aa5f0d88d656d6f25d41e65257f2f38c65ac5c918a6735297741adfc718394994f20a1cfd0082582054d1a9c5ad69586ceeb839c438400c376c0bd34825fb4c17cc2f58c54e1437f35840d326b993dfec21b9b3e1bd2f80adadc2cd673a1d8d033618cc413b0b02bc3b7efbb23d1ff99138abd05c398ce98e7983a641b50dcf0f64ed33f26c6e636b0b0ff5f6" + ); + assert_eq!( + min_fee(&signed_tx, &linear_fee).unwrap().to_str(), + "269502" // todo: compare to Haskell fee to make sure the diff is not too big + ); +} + +// #[test] +// fn tx_delegate_stake() { +// let mut inputs = TransactionInputs::new(); +// inputs.add(&TransactionInput::new(&genesis_id(), 0)); +// let mut outputs = TransactionOutputs::new(); +// outputs.add(&TransactionOutput::new(&alice_addr(), BigNum(10))); +// let mut body = TransactionBody::new(&inputs, &outputs, BigNum(94), 10); +// let mut certs = Certificates::new(); +// certs.add(&Certificate::new_stake_delegation(&StakeDelegation::new(&bob_stake(), &alice_pool()))); +// body.set_certs(&certs); +// let w = make_mock_witnesses_vkey(&body, vec![&alice_key(), &bob_key()]); +// let tx = Transaction::new(&body, &w, None); +// let haskell_crypto_bytes = witness_vkey_bytes_haskell(&w) + HASKELL_HLEN * 2; +// let our_crypto_bytes = witness_vkey_bytes_rust(&w) + Ed25519KeyHash::BYTE_COUNT + Ed25519KeyHash::BYTE_COUNT; +// assert!(txsize(&tx) - our_crypto_bytes + haskell_crypto_bytes >= 178); +// } + +// #[test] +// fn tx_deregister_stake() { +// let mut inputs = TransactionInputs::new(); +// inputs.add(&TransactionInput::new(&genesis_id(), 0)); +// let mut outputs = TransactionOutputs::new(); +// outputs.add(&TransactionOutput::new(&alice_addr(), BigNum(10))); +// let mut body = TransactionBody::new(&inputs, &outputs, BigNum(94), 10); +// let mut certs = Certificates::new(); +// certs.add(&Certificate::new_stake_deregistration(&StakeDeregistration::new(&alice_pay()))); +// body.set_certs(&certs); +// let w = make_mock_witnesses_vkey(&body, vec![&alice_key()]); +// let tx = Transaction::new(&body, &w, None); +// let haskell_crypto_bytes = witness_vkey_bytes_haskell(&w) + HASKELL_HLEN; +// let our_crypto_bytes = witness_vkey_bytes_rust(&w) + Ed25519KeyHash::BYTE_COUNT; +// assert!(txsize(&tx) - our_crypto_bytes + haskell_crypto_bytes >= 150); +// } + +// #[test] +// fn tx_register_pool() { +// let mut inputs = TransactionInputs::new(); +// inputs.add(&TransactionInput::new(&genesis_id(), 0)); +// let mut outputs = TransactionOutputs::new(); +// outputs.add(&TransactionOutput::new(&alice_addr(), BigNum(10))); +// let mut body = TransactionBody::new(&inputs, &outputs, BigNum(94), 10); +// let mut certs = Certificates::new(); +// let mut owners = Ed25519KeyHashes::new(); +// owners.add(&(alice_stake().to_keyhash().unwrap())); +// let mut relays = Relays::new(); +// relays.add(&Relay::new_single_host_name(&SingleHostName::new(None, String::from("relay.io")))); +// let params = PoolParams::new( +// &alice_pool(), +// &VRFKeyHash::from([0u8; VRFKeyHash::BYTE_COUNT]), +// BigNum(1), +// BigNum(5), +// &UnitInterval::new(BigNum(1), BigNum(10)), +// &RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &alice_stake()), +// &owners, +// &relays, +// Some(PoolMetadata::new(String::from("alice.pool"), &MetadataHash::from([0u8; MetadataHash::BYTE_COUNT]))) +// ); +// certs.add(&Certificate::new_pool_registration(&PoolRegistration::new(¶ms))); +// body.set_certs(&certs); +// let w = make_mock_witnesses_vkey(&body, vec![&alice_key()]); +// let tx = Transaction::new(&body, &w, None); +// let haskell_crypto_bytes = witness_vkey_bytes_haskell(&w) +// + HASKELL_HLEN // operator pool keyhash +// + HASKELL_HLEN // vrf keyhash +// + HASKELL_HLEN // reward account +// + owners.len() * HASKELL_HLEN // owners' keyhashes +// + HASKELL_HLEN; // metadata hash +// let our_crypto_bytes = witness_vkey_bytes_rust(&w) +// + Ed25519KeyHash::BYTE_COUNT +// + VRFKeyHash::BYTE_COUNT +// + Ed25519KeyHash::BYTE_COUNT +// + owners.len() * Ed25519KeyHash::BYTE_COUNT +// + MetadataHash::BYTE_COUNT; +// assert!(txsize(&tx) - our_crypto_bytes + haskell_crypto_bytes >= 200); +// } + +// #[test] +// fn tx_retire_pool() { +// let mut inputs = TransactionInputs::new(); +// inputs.add(&TransactionInput::new(&genesis_id(), 0)); +// let mut outputs = TransactionOutputs::new(); +// outputs.add(&TransactionOutput::new(&alice_addr(), BigNum(10))); +// let mut body = TransactionBody::new(&inputs, &outputs, BigNum(94), 10); +// let mut certs = Certificates::new(); +// certs.add(&Certificate::new_pool_retirement(&PoolRetirement::new(&alice_pool(), 5))); +// body.set_certs(&certs); +// let w = make_mock_witnesses_vkey(&body, vec![&alice_key()]); +// let tx = Transaction::new(&body, &w, None); +// let haskell_crypto_bytes = witness_vkey_bytes_haskell(&w) + HASKELL_HLEN; +// let our_crypto_bytes = witness_vkey_bytes_rust(&w) + Ed25519KeyHash::BYTE_COUNT; +// assert!(txsize(&tx) - our_crypto_bytes + haskell_crypto_bytes >= 149); +// } + +// #[test] +// fn tx_metadata() { +// let mut inputs = TransactionInputs::new(); +// inputs.add(&TransactionInput::new(&genesis_id(), 0)); +// let mut outputs = TransactionOutputs::new(); +// outputs.add(&TransactionOutput::new(&alice_addr(), BigNum(10))); +// let mut body = TransactionBody::new(&inputs, &outputs, BigNum(94), 10); +// body.set_metadata_hash(&MetadataHash::from([37; MetadataHash::BYTE_COUNT])); +// let w = make_mock_witnesses_vkey(&body, vec![&alice_key()]); +// let mut metadata = TransactionMetadata::new(); +// let mut md_list = TransactionMetadatums::new(); +// md_list.add(&TransactionMetadatum::new_int(&Int::new(&BigNum(5)))); +// md_list.add(&TransactionMetadatum::new_text(String::from("hello"))); +// metadata.insert(TransactionMetadatumLabel::new(0), &TransactionMetadatum::new_arr_transaction_metadatum(&md_list)); +// let tx = Transaction::new(&body, &w, Some(metadata)); +// let haskell_crypto_bytes = witness_vkey_bytes_haskell(&w) + HASKELL_HLEN; +// let our_crypto_bytes = witness_vkey_bytes_rust(&w) + MetadataHash::BYTE_COUNT; +// assert!(txsize(&tx) - our_crypto_bytes + haskell_crypto_bytes >= 154); +// } + +// #[test] +// fn tx_multisig() { +// let mut inputs = TransactionInputs::new(); +// inputs.add(&TransactionInput::new(&genesis_id(), 0)); +// let mut outputs = TransactionOutputs::new(); +// outputs.add(&TransactionOutput::new(&alice_addr(), BigNum(10))); +// let body = TransactionBody::new(&inputs, &outputs, BigNum(94), 10); +// let mut w = make_mock_witnesses_vkey(&body, vec![&alice_key(), &bob_key()]); +// let mut script_witnesses = MultisigScripts::new(); +// let mut inner_scripts = MultisigScripts::new(); +// inner_scripts.add(&MultisigScript::new_msig_pubkey(&alice_pay().to_keyhash().unwrap())); +// inner_scripts.add(&MultisigScript::new_msig_pubkey(&bob_pay().to_keyhash().unwrap())); +// inner_scripts.add(&MultisigScript::new_msig_pubkey(&carl_pay().to_keyhash().unwrap())); +// script_witnesses.add(&MultisigScript::new_msig_n_of_k(2, &inner_scripts)); +// w.set_scripts(&script_witnesses); +// let tx = Transaction::new(&body, &w, None); +// let haskell_crypto_bytes = witness_vkey_bytes_haskell(&w); +// let our_crypto_bytes = witness_vkey_bytes_rust(&w); +// assert!(txsize(&tx) - our_crypto_bytes + haskell_crypto_bytes - haskell_multisig_byte_diff(&script_witnesses) >= 189); +// } + +#[test] +fn tx_withdrawal() { + // # Vector #8: with reward withdrawal + let mut inputs = TransactionInputs::new(); + inputs.add(&TransactionInput::new( + &TransactionHash::from_bytes( + hex::decode("3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7") + .unwrap(), + ) + .unwrap(), + 0, + )); + let mut outputs = TransactionOutputs::new(); + + outputs.add( + &TransactionOutputBuilder::new() + .with_address( + &Address::from_bytes( + hex::decode("611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c") + .unwrap(), + ) + .unwrap(), + ) + .next() + .unwrap() + .with_coin(&BigNum(1)) + .build() + .unwrap(), + ); + let mut body = TransactionBody::new(&inputs, &outputs, &BigNum(162502), Some(10)); + let mut withdrawals = Withdrawals::new(); + withdrawals.insert( + &RewardAddress::from_address( + &Address::from_bytes( + hex::decode("e151df9ba1b74a1c9608a487e114184556801e927d31d96425cb80af70").unwrap(), + ) + .unwrap(), + ) + .unwrap(), + &BigNum(1337), + ); + body.set_withdrawals(&withdrawals); + + let mut w = TransactionWitnessSet::new(); + let mut vkw = Vkeywitnesses::new(); + // input key witness + vkw.add(&make_vkey_witness( + &hash_transaction(&body), + &PrivateKey::from_normal_bytes( + &hex::decode("c660e50315d76a53d80732efda7630cae8885dfb85c46378684b3c6103e1284a") + .unwrap(), + ) + .unwrap(), + )); + // withdrawal key witness + vkw.add(&make_vkey_witness( + &hash_transaction(&body), + &PrivateKey::from_normal_bytes( + &hex::decode("5ada7f4d92bce1ee1707c0a0e211eb7941287356e6ed0e76843806e307b07c8d") + .unwrap(), + ) + .unwrap(), + )); + w.set_vkeys(&vkw); + + let signed_tx = Transaction::new(&body, &w, None); + + let linear_fee = LinearFee::new(&BigNum(500), &BigNum(2)); + assert_eq!( + hex::encode(signed_tx.to_bytes()), + "84a500818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a00027ac6030a05a1581de151df9ba1b74a1c9608a487e114184556801e927d31d96425cb80af70190539a10082825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee5840fc0493f7121efe385d72830680e735ccdef99c3a31953fe877b89ad3a97fcdb871cc7f2cdd6a8104e52f6963bd9e10d814d4fabdbcdc8475bc63e872dcc94d0a82582054d1a9c5ad69586ceeb839c438400c376c0bd34825fb4c17cc2f58c54e1437f35840a051ba927582004aedab736b9f1f9330ff867c260f4751135d480074256e83cd23d2a4bb109f955c43afdcdc5d1841b28d5c1ea2148dfbb6252693590692bb00f5f6" + ); + assert_eq!( + min_fee(&signed_tx, &linear_fee).unwrap().to_str(), + "163002" // todo: compare to Haskell fee to make sure the diff is not too big + ); +} + +fn exunits(mem: u64, steps: u64) -> ExUnits { + ExUnits::new(&BigNum(mem), &BigNum(steps)) +} + +fn subcoin(num: u64, denum: u64) -> SubCoin { + SubCoin::new(&BigNum(num), &BigNum(denum)) +} + +fn exunit_prices(mem_prices: (u64, u64), step_prices: (u64, u64)) -> ExUnitPrices { + ExUnitPrices::new( + &subcoin(mem_prices.0, mem_prices.1), + &subcoin(step_prices.0, step_prices.1), + ) +} + +fn _calculate_ex_units_ceil_cost( + mem: u64, + steps: u64, + mem_prices: (u64, u64), + step_prices: (u64, u64), +) -> Coin { + let ex_units = exunits(mem, steps); + let ex_unit_prices = exunit_prices(mem_prices, step_prices); + calculate_ex_units_ceil_cost(&ex_units, &ex_unit_prices).unwrap() +} + +#[test] +fn test_calc_ex_units_cost() { + // 10 * (2/1) + 20 * (3/1) = 10 * 2 + 20 * 3 = 20 + 60 + assert_eq!( + _calculate_ex_units_ceil_cost(10, 20, (2, 1), (3, 1)), + BigNum(80), + ); + // 22 * (12/6) + 33 * (33/11) = 22 * 2 + 33 * 3 = 44 + 99 = 143 + assert_eq!( + _calculate_ex_units_ceil_cost(22, 33, (12, 6), (33, 11)), + BigNum(143), + ); + // 10 * (5/7) + 20 * (9/13) = 50/7 + 180/13 = 650/91 + 1260/91 = 1910/91 = ceil(20.98) = 21 + assert_eq!( + _calculate_ex_units_ceil_cost(10, 20, (5, 7), (9, 13)), + BigNum(21), + ); + // 22 * (7/5) + 33 * (13/9) = 154/5 + 429/9 = 1386/45 + 2145/45 = 3531/45 = ceil(78.46) = 79 + assert_eq!( + _calculate_ex_units_ceil_cost(22, 33, (7, 5), (13, 9)), + BigNum(79), + ); +} diff --git a/rust/src/tests/mod.rs b/rust/src/tests/mod.rs index 197793b2..b3a4d145 100644 --- a/rust/src/tests/mod.rs +++ b/rust/src/tests/mod.rs @@ -8,4 +8,5 @@ mod serialization; mod plutus; mod metadata; mod crypto; -mod utils; \ No newline at end of file +mod utils; +mod fees; \ No newline at end of file From 216c907d3a1d78f757d542fd67dfcaa8d2bb826b Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 24 Jun 2024 19:18:48 +0700 Subject: [PATCH 308/349] move emip3 and tx_builder_constants tests to test module --- rust/src/builders/tx_builder_constants.rs | 49 +------------------ rust/src/emip3.rs | 18 +------ rust/src/tests/builders/mod.rs | 3 +- .../src/tests/builders/tx_builder_constans.rs | 48 ++++++++++++++++++ rust/src/tests/emip3.rs | 12 +++++ rust/src/tests/mod.rs | 3 +- 6 files changed, 66 insertions(+), 67 deletions(-) create mode 100644 rust/src/tests/builders/tx_builder_constans.rs create mode 100644 rust/src/tests/emip3.rs diff --git a/rust/src/builders/tx_builder_constants.rs b/rust/src/builders/tx_builder_constants.rs index e2853dfa..34c3acf3 100644 --- a/rust/src/builders/tx_builder_constants.rs +++ b/rust/src/builders/tx_builder_constants.rs @@ -73,51 +73,4 @@ impl TxBuilderConstants { ); res } -} - -#[cfg(test)] -mod tests { - use crate::*; - - #[test] - pub fn cost_model_test() { - assert_eq!( - TxBuilderConstants::plutus_alonzo_cost_models() - .get(&Language::new_plutus_v1()) - .unwrap() - .len(), - 166, - ); - assert_eq!( - TxBuilderConstants::plutus_vasil_cost_models() - .get(&Language::new_plutus_v1()) - .unwrap() - .len(), - 166, - ); - assert_eq!( - TxBuilderConstants::plutus_vasil_cost_models() - .get(&Language::new_plutus_v2()) - .unwrap() - .len(), - 175, - ); - assert_eq!( - hex::encode(TxBuilderConstants::plutus_alonzo_cost_models().language_views_encoding()), - "a141005901d59f1a000302590001011a00060bc719026d00011a000249f01903e800011a000249f018201a0025cea81971f70419744d186419744d186419744d186419744d186419744d186419744d18641864186419744d18641a000249f018201a000249f018201a000249f018201a000249f01903e800011a000249f018201a000249f01903e800081a000242201a00067e2318760001011a000249f01903e800081a000249f01a0001b79818f7011a000249f0192710011a0002155e19052e011903e81a000249f01903e8011a000249f018201a000249f018201a000249f0182001011a000249f0011a000249f0041a000194af18f8011a000194af18f8011a0002377c190556011a0002bdea1901f1011a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a000242201a00067e23187600010119f04c192bd200011a000249f018201a000242201a00067e2318760001011a000242201a00067e2318760001011a0025cea81971f704001a000141bb041a000249f019138800011a000249f018201a000302590001011a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a00330da70101ff", - ); - assert_eq!( - hex::encode(TxBuilderConstants::plutus_vasil_cost_models().language_views_encoding()), - "a20198af1a0003236119032c01011903e819023b00011903e8195e7104011903e818201a0001ca761928eb041959d818641959d818641959d818641959d818641959d818641959d81864186418641959d81864194c5118201a0002acfa182019b551041a000363151901ff00011a00015c3518201a000797751936f404021a0002ff941a0006ea7818dc0001011903e8196ff604021a0003bd081a00034ec5183e011a00102e0f19312a011a00032e801901a5011a0002da781903e819cf06011a00013a34182019a8f118201903e818201a00013aac0119e143041903e80a1a00030219189c011a00030219189c011a0003207c1901d9011a000330001901ff0119ccf3182019fd40182019ffd5182019581e18201940b318201a00012adf18201a0002ff941a0006ea7818dc0001011a00010f92192da7000119eabb18201a0002ff941a0006ea7818dc0001011a0002ff941a0006ea7818dc0001011a0011b22c1a0005fdde00021a000c504e197712041a001d6af61a0001425b041a00040c660004001a00014fab18201a0003236119032c010119a0de18201a00033d7618201979f41820197fb8182019a95d1820197df718201995aa18201a0223accc0a1a0374f693194a1f0a1a02515e841980b30a41005901b69f1a0003236119032c01011903e819023b00011903e8195e7104011903e818201a0001ca761928eb041959d818641959d818641959d818641959d818641959d818641959d81864186418641959d81864194c5118201a0002acfa182019b551041a000363151901ff00011a00015c3518201a000797751936f404021a0002ff941a0006ea7818dc0001011903e8196ff604021a0003bd081a00034ec5183e011a00102e0f19312a011a00032e801901a5011a0002da781903e819cf06011a00013a34182019a8f118201903e818201a00013aac0119e143041903e80a1a00030219189c011a00030219189c011a0003207c1901d9011a000330001901ff0119ccf3182019fd40182019ffd5182019581e18201940b318201a00012adf18201a0002ff941a0006ea7818dc0001011a00010f92192da7000119eabb18201a0002ff941a0006ea7818dc0001011a0002ff941a0006ea7818dc0001011a000c504e197712041a001d6af61a0001425b041a00040c660004001a00014fab18201a0003236119032c010119a0de18201a00033d7618201979f41820197fb8182019a95d1820197df718201995aa18201a0374f693194a1f0aff", - ); - } - - #[test] - pub fn from_json() { - println!("{}", TxBuilderConstants::plutus_vasil_cost_models().to_json().unwrap()); - assert_eq!( - TxBuilderConstants::plutus_vasil_cost_models().to_hex(), - Costmdls::from_json("{ \"PlutusV1\": [\"205665\",\"812\",\"1\",\"1\",\"1000\",\"571\",\"0\",\"1\",\"1000\",\"24177\",\"4\",\"1\",\"1000\",\"32\",\"117366\",\"10475\",\"4\",\"23000\",\"100\",\"23000\",\"100\",\"23000\",\"100\",\"23000\",\"100\",\"23000\",\"100\",\"23000\",\"100\",\"100\",\"100\",\"23000\",\"100\",\"19537\",\"32\",\"175354\",\"32\",\"46417\",\"4\",\"221973\",\"511\",\"0\",\"1\",\"89141\",\"32\",\"497525\",\"14068\",\"4\",\"2\",\"196500\",\"453240\",\"220\",\"0\",\"1\",\"1\",\"1000\",\"28662\",\"4\",\"2\",\"245000\",\"216773\",\"62\",\"1\",\"1060367\",\"12586\",\"1\",\"208512\",\"421\",\"1\",\"187000\",\"1000\",\"52998\",\"1\",\"80436\",\"32\",\"43249\",\"32\",\"1000\",\"32\",\"80556\",\"1\",\"57667\",\"4\",\"1000\",\"10\",\"197145\",\"156\",\"1\",\"197145\",\"156\",\"1\",\"204924\",\"473\",\"1\",\"208896\",\"511\",\"1\",\"52467\",\"32\",\"64832\",\"32\",\"65493\",\"32\",\"22558\",\"32\",\"16563\",\"32\",\"76511\",\"32\",\"196500\",\"453240\",\"220\",\"0\",\"1\",\"1\",\"69522\",\"11687\",\"0\",\"1\",\"60091\",\"32\",\"196500\",\"453240\",\"220\",\"0\",\"1\",\"1\",\"196500\",\"453240\",\"220\",\"0\",\"1\",\"1\",\"806990\",\"30482\",\"4\",\"1927926\",\"82523\",\"4\",\"265318\",\"0\",\"4\",\"0\",\"85931\",\"32\",\"205665\",\"812\",\"1\",\"1\",\"41182\",\"32\",\"212342\",\"32\",\"31220\",\"32\",\"32696\",\"32\",\"43357\",\"32\",\"32247\",\"32\",\"38314\",\"32\",\"57996947\",\"18975\",\"10\"], \"PlutusV2\": [\"205665\",\"812\",\"1\",\"1\",\"1000\",\"571\",\"0\",\"1\",\"1000\",\"24177\",\"4\",\"1\",\"1000\",\"32\",\"117366\",\"10475\",\"4\",\"23000\",\"100\",\"23000\",\"100\",\"23000\",\"100\",\"23000\",\"100\",\"23000\",\"100\",\"23000\",\"100\",\"100\",\"100\",\"23000\",\"100\",\"19537\",\"32\",\"175354\",\"32\",\"46417\",\"4\",\"221973\",\"511\",\"0\",\"1\",\"89141\",\"32\",\"497525\",\"14068\",\"4\",\"2\",\"196500\",\"453240\",\"220\",\"0\",\"1\",\"1\",\"1000\",\"28662\",\"4\",\"2\",\"245000\",\"216773\",\"62\",\"1\",\"1060367\",\"12586\",\"1\",\"208512\",\"421\",\"1\",\"187000\",\"1000\",\"52998\",\"1\",\"80436\",\"32\",\"43249\",\"32\",\"1000\",\"32\",\"80556\",\"1\",\"57667\",\"4\",\"1000\",\"10\",\"197145\",\"156\",\"1\",\"197145\",\"156\",\"1\",\"204924\",\"473\",\"1\",\"208896\",\"511\",\"1\",\"52467\",\"32\",\"64832\",\"32\",\"65493\",\"32\",\"22558\",\"32\",\"16563\",\"32\",\"76511\",\"32\",\"196500\",\"453240\",\"220\",\"0\",\"1\",\"1\",\"69522\",\"11687\",\"0\",\"1\",\"60091\",\"32\",\"196500\",\"453240\",\"220\",\"0\",\"1\",\"1\",\"196500\",\"453240\",\"220\",\"0\",\"1\",\"1\",\"1159724\",\"392670\",\"0\",\"2\",\"806990\",\"30482\",\"4\",\"1927926\",\"82523\",\"4\",\"265318\",\"0\",\"4\",\"0\",\"85931\",\"32\",\"205665\",\"812\",\"1\",\"1\",\"41182\",\"32\",\"212342\",\"32\",\"31220\",\"32\",\"32696\",\"32\",\"43357\",\"32\",\"32247\",\"32\",\"38314\",\"32\",\"35892428\",\"10\",\"57996947\",\"18975\",\"10\",\"38887044\",\"32947\",\"10\"] }").unwrap().to_hex(), - ); - } -} +} \ No newline at end of file diff --git a/rust/src/emip3.rs b/rust/src/emip3.rs index 7bb3b04c..b69f545e 100644 --- a/rust/src/emip3.rs +++ b/rust/src/emip3.rs @@ -115,20 +115,4 @@ pub fn decrypt_with_password(password: &str, data: &str) -> Result Date: Tue, 2 Jul 2024 21:55:13 +0700 Subject: [PATCH 309/349] fix redeemer indexing for mint builder --- rust/src/builders/mint_builder.rs | 10 +++- rust/src/tests/builders/mint_builder.rs | 80 ++++++++++++++++++++++++- rust/src/tests/fakes.rs | 9 +++ 3 files changed, 95 insertions(+), 4 deletions(-) diff --git a/rust/src/builders/mint_builder.rs b/rust/src/builders/mint_builder.rs index 0c746150..3b6bdb4d 100644 --- a/rust/src/builders/mint_builder.rs +++ b/rust/src/builders/mint_builder.rs @@ -302,7 +302,7 @@ impl MintBuilder { pub fn build(&self) -> Result { let mut mint = Mint::new(); - for (policy, script_mint) in self.mints.iter() { + for (policy, script_mint) in &self.mints { let mut mint_asset = MintAssets::new(); match script_mint { ScriptMint::Native(native_mints) => { @@ -338,12 +338,16 @@ impl MintBuilder { pub fn get_plutus_witnesses(&self) -> PlutusWitnesses { let mut plutus_witnesses = Vec::new(); - for script_mint in self.mints.values() { + let tag = RedeemerTag::new_mint(); + for (index, (_, script_mint)) in self.mints.iter().enumerate() { match script_mint { ScriptMint::Plutus(plutus_mints) => { plutus_witnesses.push(PlutusWitness::new_with_ref_without_datum( &PlutusScriptSource(plutus_mints.script.clone()), - &plutus_mints.redeemer, + &plutus_mints.redeemer.clone_with_index_and_tag( + &BigNum::from(index), + &tag, + ), )); } _ => {} diff --git a/rust/src/tests/builders/mint_builder.rs b/rust/src/tests/builders/mint_builder.rs index 0befb6b9..70d14a0b 100644 --- a/rust/src/tests/builders/mint_builder.rs +++ b/rust/src/tests/builders/mint_builder.rs @@ -1,5 +1,5 @@ use crate::*; -use crate::tests::fakes::{fake_reallistic_tx_builder, fake_redeemer, fake_plutus_script_and_hash, fake_script_hash, fake_tx_input}; +use crate::tests::fakes::{fake_reallistic_tx_builder, fake_redeemer, fake_plutus_script_and_hash, fake_script_hash, fake_tx_input, fake_redeemer_with_tag}; #[test] fn plutus_mint_with_script_ref_test() { @@ -498,4 +498,82 @@ fn zero_mint_error() { let res= mint_builder.add_asset(&mint_witness_native, &asset_name1, &Int::new(&BigNum::from(0u64))); assert!(res.is_err()); +} + +#[test] +fn redeemer_tag_index_test() { + let bytes1 = vec![3u8; 28]; + let bytes2 = vec![1u8; 28]; + let bytes3 = vec![2u8; 28]; + let script_hash_1 = ScriptHash::from_bytes(bytes1).expect("Failed to create script hash"); + let script_hash_2 = ScriptHash::from_bytes(bytes2).expect("Failed to create script hash"); + let script_hash_3 = ScriptHash::from_bytes(bytes3).expect("Failed to create script hash"); + let tx_input_ref1 = fake_tx_input(2); + let tx_input_ref2 = fake_tx_input(3); + let tx_input_ref3 = fake_tx_input(4); + let data_1 = PlutusData::new_empty_constr_plutus_data(&BigNum::from(1u64)); + let data_2 = PlutusData::new_empty_constr_plutus_data(&BigNum::from(2u64)); + let data_3 = PlutusData::new_empty_constr_plutus_data(&BigNum::from(3u64)); + let redeemer1 = fake_redeemer_with_tag(99, &RedeemerTag::new_vote(), &data_1); + let redeemer2 = fake_redeemer_with_tag(98, &RedeemerTag::new_cert(), &data_2); + let redeemer3 = fake_redeemer_with_tag(97, &RedeemerTag::new_spend(), &data_3); + + let asset_name1 = AssetName::from_hex("44544e4654").unwrap(); + let asset_name2 = AssetName::from_hex("44544e4655").unwrap(); + let asset_name3 = AssetName::from_hex("44544e4656").unwrap(); + + let mut mint_builder = MintBuilder::new(); + + let plutus_script_source1 = PlutusScriptSource::new_ref_input( + &script_hash_1, + &tx_input_ref1, + &Language::new_plutus_v2(), + 0 + ); + let plutus_script_source2 = PlutusScriptSource::new_ref_input( + &script_hash_2, + &tx_input_ref2, + &Language::new_plutus_v2(), + 0 + ); + + let plutus_script_source3 = PlutusScriptSource::new_ref_input( + &script_hash_3, + &tx_input_ref3, + &Language::new_plutus_v2(), + 0 + ); + + let mint_witnes1 = MintWitness::new_plutus_script(&plutus_script_source1, &redeemer1); + let mint_witnes2 = MintWitness::new_plutus_script(&plutus_script_source2, &redeemer2); + let mint_witnes3 = MintWitness::new_plutus_script(&plutus_script_source3, &redeemer3); + + mint_builder.add_asset(&mint_witnes1, &asset_name1, &Int::new(&BigNum::from(100u64))).unwrap(); + mint_builder.add_asset(&mint_witnes2, &asset_name2, &Int::new(&BigNum::from(101u64))).unwrap(); + mint_builder.add_asset(&mint_witnes3, &asset_name3, &Int::new(&BigNum::from(102u64))).unwrap(); + + let mint = mint_builder.build().expect("Failed to build mint"); + assert_eq!(mint.len(), 3); + + let policy_ids = mint.keys(); + + let first_index = policy_ids.0.iter().position(|x| *x == script_hash_1).unwrap(); + let second_index = policy_ids.0.iter().position(|x| *x == script_hash_2).unwrap(); + let third_index = policy_ids.0.iter().position(|x| *x == script_hash_3).unwrap(); + + let plutus_witnesses = mint_builder.get_plutus_witnesses(); + let redeemers = mint_builder.get_redeemers().expect("Failed to get redeemers"); + assert_eq!(plutus_witnesses.len(), 3); + + let first_redeemer = redeemers.redeemers.iter().find(|x| x.data == data_1).unwrap(); + let second_redeemer = redeemers.redeemers.iter().find(|x| x.data == data_2).unwrap(); + let third_redeemer = redeemers.redeemers.iter().find(|x| x.data == data_3).unwrap(); + + assert_eq!(first_redeemer.tag(), RedeemerTag::new_mint()); + assert_eq!(second_redeemer.tag(), RedeemerTag::new_mint()); + assert_eq!(third_redeemer.tag(), RedeemerTag::new_mint()); + + assert_eq!(first_redeemer.index(), BigNum::from(first_index as u64)); + assert_eq!(second_redeemer.index(), BigNum::from(second_index as u64)); + assert_eq!(third_redeemer.index(), BigNum::from(third_index as u64)); } \ No newline at end of file diff --git a/rust/src/tests/fakes.rs b/rust/src/tests/fakes.rs index 3e6cfd5d..ef834440 100644 --- a/rust/src/tests/fakes.rs +++ b/rust/src/tests/fakes.rs @@ -493,6 +493,15 @@ pub(crate) fn fake_redeemer(x: u8) -> Redeemer { ) } +pub(crate) fn fake_redeemer_with_tag(index: u64, tag: &RedeemerTag, data: &PlutusData) -> Redeemer { + Redeemer::new( + tag, + &BigNum::from(index), + data, + &ExUnits::new(&BigNum::from(index), &BigNum::from(index)), + ) +} + pub(crate) fn fake_redeemer_zero_cost(x: u8) -> Redeemer { Redeemer::new( &RedeemerTag::new_cert(), From f2403651fbe76c95db5e324eb4d62d7765d82501 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 2 Jul 2024 21:56:42 +0700 Subject: [PATCH 310/349] version bump --- package-lock.json | 4 ++-- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 05fab450..831e8f35 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.1", + "version": "12.0.0-beta.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.1", + "version": "12.0.0-beta.2", "hasInstallScript": true, "license": "MIT", "devDependencies": { diff --git a/package.json b/package.json index 1c2d9995..6ea1f487 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.1", + "version": "12.0.0-beta.2", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 58288aef..0bd65fb0 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-beta.1" +version = "12.0.0-beta.2" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 9bb9e625..7dbd0d93 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -49,7 +49,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-beta.1" +version = "12.0.0-beta.2" dependencies = [ "bech32", "cbor_event", From fa6db4c35f372c0a202b868e3fcc542c98ff0a12 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 29 Jul 2024 16:46:05 +0900 Subject: [PATCH 311/349] fix naming consistency --- rust/src/protocol_types/governance/voter.rs | 2 +- rust/src/tests/protocol_types/governance/common.rs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rust/src/protocol_types/governance/voter.rs b/rust/src/protocol_types/governance/voter.rs index 987a8a51..d6f7bd05 100644 --- a/rust/src/protocol_types/governance/voter.rs +++ b/rust/src/protocol_types/governance/voter.rs @@ -73,7 +73,7 @@ impl Voter { } } - pub fn to_constitutional_committee_hot_cred(&self) -> Option { + pub fn to_constitutional_committee_hot_key(&self) -> Option { match &self.0 { VoterEnum::ConstitutionalCommitteeHotKey(cred) => Some(cred.clone()), _ => None, diff --git a/rust/src/tests/protocol_types/governance/common.rs b/rust/src/tests/protocol_types/governance/common.rs index e9a21995..515d1e6e 100644 --- a/rust/src/tests/protocol_types/governance/common.rs +++ b/rust/src/tests/protocol_types/governance/common.rs @@ -80,7 +80,7 @@ fn voter_drep_key_hash_setters_getters_test() { Some(Credential::from_keyhash(&key_hash)) ); assert_eq!(voter.to_staking_pool_key_hash(), None); - assert_eq!(voter.to_constitutional_committee_hot_cred(), None); + assert_eq!(voter.to_constitutional_committee_hot_key(), None); assert_eq!(voter.has_script_credentials(), false); assert_eq!(voter.to_key_hash(), Some(key_hash)); } @@ -95,7 +95,7 @@ fn voter_drep_script_hash_setters_getters_test() { Some(Credential::from_scripthash(&script_hash)) ); assert_eq!(voter.to_staking_pool_key_hash(), None); - assert_eq!(voter.to_constitutional_committee_hot_cred(), None); + assert_eq!(voter.to_constitutional_committee_hot_key(), None); assert_eq!(voter.has_script_credentials(), true); assert_eq!(voter.to_key_hash(), None); } @@ -106,7 +106,7 @@ fn voter_constitutional_committee_hot_key_hash_setters_getters_test() { let voter = Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash(&key_hash)); assert_eq!(voter.kind(), VoterKind::ConstitutionalCommitteeHotKeyHash); assert_eq!( - voter.to_constitutional_committee_hot_cred(), + voter.to_constitutional_committee_hot_key(), Some(Credential::from_keyhash(&key_hash)) ); assert_eq!(voter.to_staking_pool_key_hash(), None); @@ -125,7 +125,7 @@ fn voter_constitutional_committee_hot_script_hash_setters_getters_test() { VoterKind::ConstitutionalCommitteeHotScriptHash ); assert_eq!( - voter.to_constitutional_committee_hot_cred(), + voter.to_constitutional_committee_hot_key(), Some(Credential::from_scripthash(&script_hash)) ); assert_eq!(voter.to_staking_pool_key_hash(), None); @@ -140,7 +140,7 @@ fn voter_staking_pool_key_hash_setters_getters_test() { let voter = Voter::new_staking_pool(&key_hash); assert_eq!(voter.kind(), VoterKind::StakingPoolKeyHash); assert_eq!(voter.to_staking_pool_key_hash(), Some(key_hash.clone())); - assert_eq!(voter.to_constitutional_committee_hot_cred(), None); + assert_eq!(voter.to_constitutional_committee_hot_key(), None); assert_eq!(voter.to_drep_cred(), None); assert_eq!(voter.has_script_credentials(), false); assert_eq!(voter.to_key_hash(), Some(key_hash)); From 995017ab4a132743af19e407e8ee44fee77d4191 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 29 Jul 2024 17:25:36 +0900 Subject: [PATCH 312/349] add new_from_credential and to/from bech32 for DRep --- rust/src/protocol_types/governance/drep.rs | 47 +++++++++++++++++++ .../tests/protocol_types/governance/common.rs | 17 +++++++ .../tests/serialization/governance/common.rs | 30 ++++++++++++ 3 files changed, 94 insertions(+) diff --git a/rust/src/protocol_types/governance/drep.rs b/rust/src/protocol_types/governance/drep.rs index 8ed8825c..7d96e9eb 100644 --- a/rust/src/protocol_types/governance/drep.rs +++ b/rust/src/protocol_types/governance/drep.rs @@ -1,4 +1,5 @@ use crate::*; +use bech32::ToBase32; #[derive( Clone, @@ -63,6 +64,14 @@ impl DRep { Self(DRepEnum::AlwaysNoConfidence) } + pub fn new_from_credential(cred: &Credential) -> Self { + let drep = match &cred.0 { + CredType::Key(key_hash) => DRepEnum::KeyHash(key_hash.clone()), + CredType::Script(script_hash) => DRepEnum::ScriptHash(script_hash.clone()), + }; + Self(drep) + } + pub fn kind(&self) -> DRepKind { match &self.0 { DRepEnum::KeyHash(_) => DRepKind::KeyHash, @@ -85,4 +94,42 @@ impl DRep { _ => None, } } + + pub fn to_bech32(&self) -> Result { + let (hrp, data) = match &self.0 { + DRepEnum::KeyHash(keyhash) => Ok(("drep", keyhash.to_bytes())), + DRepEnum::ScriptHash(scripthash) => Ok(("drep_script", scripthash.to_bytes())), + DRepEnum::AlwaysAbstain => { + Err(JsError::from_str("Cannot convert AlwaysAbstain to bech32")) + } + DRepEnum::AlwaysNoConfidence => Err(JsError::from_str( + "Cannot convert AlwaysNoConfidence to bech32", + )), + }?; + bech32::encode(&hrp, data.to_base32()).map_err(|e| JsError::from_str(&format! {"{:?}", e})) + } + + pub fn from_bech32(bech32_str: &str) -> Result { + let (hrp, u5data) = + bech32::decode(bech32_str).map_err(|e| JsError::from_str(&e.to_string()))?; + let data: Vec = bech32::FromBase32::from_base32(&u5data) + .map_err(|_| JsError::from_str("Malformed DRep"))?; + let kind = match hrp.as_str() { + "drep" => DRepKind::KeyHash, + "drep_script" => DRepKind::ScriptHash, + _ => return Err(JsError::from_str("Malformed DRep")), + }; + let drep = match kind { + DRepKind::KeyHash => DRepEnum::KeyHash( + Ed25519KeyHash::from_bytes(data) + .map_err(|_| JsError::from_str("Malformed DRep"))?, + ), + DRepKind::ScriptHash => DRepEnum::ScriptHash( + ScriptHash::from_bytes(data).map_err(|_| JsError::from_str("Malformed DRep"))?, + ), + DRepKind::AlwaysAbstain => DRepEnum::AlwaysAbstain, + DRepKind::AlwaysNoConfidence => DRepEnum::AlwaysNoConfidence, + }; + Ok(DRep(drep)) + } } diff --git a/rust/src/tests/protocol_types/governance/common.rs b/rust/src/tests/protocol_types/governance/common.rs index 515d1e6e..7aebf60e 100644 --- a/rust/src/tests/protocol_types/governance/common.rs +++ b/rust/src/tests/protocol_types/governance/common.rs @@ -35,6 +35,23 @@ fn drep_script_hash_setters_getters_test() { assert_eq!(drep.to_script_hash(), Some(script_hash)); } +#[test] +fn drep_from_cred_test() { + let key_hash = fake_key_hash(1); + let cred = Credential::from_keyhash(&key_hash); + let drep = DRep::new_from_credential(&cred); + assert_eq!(drep.kind(), DRepKind::KeyHash); + assert_eq!(drep.to_key_hash(), Some(key_hash)); + assert_eq!(drep.to_script_hash(), None); + + let script_hash = fake_script_hash(1); + let cred = Credential::from_scripthash(&script_hash); + let drep = DRep::new_from_credential(&cred); + assert_eq!(drep.kind(), DRepKind::ScriptHash); + assert_eq!(drep.to_key_hash(), None); + assert_eq!(drep.to_script_hash(), Some(script_hash)); +} + #[test] fn anchor_setters_getters_test() { let data_hash = fake_anchor_data_hash(1); diff --git a/rust/src/tests/serialization/governance/common.rs b/rust/src/tests/serialization/governance/common.rs index fcf4db47..3c577f82 100644 --- a/rust/src/tests/serialization/governance/common.rs +++ b/rust/src/tests/serialization/governance/common.rs @@ -73,6 +73,36 @@ fn drep_always_no_confidence_ser_round_trip() { assert_eq!(drep.kind(), DRepKind::AlwaysNoConfidence); } +#[test] +fn drep_to_from_bech32_keshhash() { + let drep = DRep::new_key_hash(&fake_key_hash(1)); + let bech32 = drep.to_bech32().unwrap(); + let drep_deser = DRep::from_bech32(&bech32).unwrap(); + assert_eq!(drep, drep_deser); +} + +#[test] +fn drep_to_from_bech32_script_hash() { + let drep = DRep::new_script_hash(&fake_script_hash(1)); + let bech32 = drep.to_bech32().unwrap(); + let drep_deser = DRep::from_bech32(&bech32).unwrap(); + assert_eq!(drep, drep_deser); +} + +#[test] +fn drep_to_from_bech32_always_abstain() { + let drep = DRep::new_always_abstain(); + let bech32 = drep.to_bech32(); + assert!(bech32.is_err()); +} + +#[test] +fn drep_to_from_bech32_always_no_confidence() { + let drep = DRep::new_always_no_confidence(); + let bech32 = drep.to_bech32(); + assert!(bech32.is_err()); +} + #[test] fn governance_action_id_ser_round_trip() { let gov_action_id = From 1da6da908cd0faf044617179867694afeadd8d7f Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 30 Jul 2024 01:38:38 +0900 Subject: [PATCH 313/349] add tiers calculator for ref script fee --- rust/src/fees.rs | 58 +++++++++++++-- rust/src/protocol_types/numeric/big_int.rs | 38 +++++++--- rust/src/rational.rs | 87 +++++++++++++++++++++- rust/src/tests/builders/tx_builder.rs | 16 ++-- rust/src/tests/general.rs | 84 +++++++++++++++++++++ 5 files changed, 258 insertions(+), 25 deletions(-) diff --git a/rust/src/fees.rs b/rust/src/fees.rs index bd9d8074..f17eedf3 100644 --- a/rust/src/fees.rs +++ b/rust/src/fees.rs @@ -1,5 +1,5 @@ use super::*; -use crate::rational::{Rational}; +use crate::rational::Rational; #[wasm_bindgen] #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] @@ -60,8 +60,54 @@ pub fn min_script_fee(tx: &Transaction, ex_unit_prices: &ExUnitPrices) -> Result } #[wasm_bindgen] -pub fn min_ref_script_fee(total_ref_scripts_size: usize, ref_script_coins_per_byte: &UnitInterval) -> Result { - let ref_multiplier : Rational = ref_script_coins_per_byte.into(); - let total_fee = ref_multiplier.mul_usize(total_ref_scripts_size); - total_fee.to_bignum_ceil() -} \ No newline at end of file +pub fn min_ref_script_fee( + total_ref_scripts_size: usize, + ref_script_coins_per_byte: &UnitInterval, +) -> Result { + let multiplier = Rational::new(BigInt::from(12), BigInt::from(10)); // 1.2 + let size_increment: usize = 25_600; // 25KiB + let ref_multiplier: Rational = ref_script_coins_per_byte.into(); + let total_fee = tier_ref_script_fee( + multiplier, + size_increment, + ref_multiplier, + total_ref_scripts_size, + )?; + + Ok(total_fee) +} + +fn tier_ref_script_fee( + multiplier: Rational, + size_increment: usize, + base_fee: Rational, + total_size: usize, +) -> Result { + if multiplier.is_negative_or_zero() || size_increment == 0 { + return Err(JsError::from_str( + "Size increment and multiplier must be positive", + )); + } + + let full_tiers = (total_size / size_increment) as u32; + let partial_tier_size = total_size % size_increment; + let tier_price = base_fee.mul_usize(size_increment); + + let mut acc = Rational::zero(); + + if full_tiers > 0 { + let progression_enumerator = Rational::one().sub(&multiplier.pow(full_tiers)); + let progression_denominator = Rational::one().sub(&multiplier); + let tier_progression_sum = progression_enumerator.div_ratio(&progression_denominator); + acc = acc.add(&tier_price.mul_ratio(&tier_progression_sum)); + } + + // Add the partial tier + if partial_tier_size > 0 { + let last_tier_price = base_fee.mul_ratio(&multiplier.pow(full_tiers)); + let partial_tier_fee = last_tier_price.mul_usize(partial_tier_size); + acc = acc.add(&partial_tier_fee); + } + + acc.to_bignum_floor() +} diff --git a/rust/src/protocol_types/numeric/big_int.rs b/rust/src/protocol_types/numeric/big_int.rs index 7f4e9801..4c9655f8 100644 --- a/rust/src/protocol_types/numeric/big_int.rs +++ b/rust/src/protocol_types/numeric/big_int.rs @@ -1,4 +1,6 @@ use num_bigint::Sign; +use num_integer::Integer; +use num_traits::Signed; use crate::*; #[wasm_bindgen] @@ -89,13 +91,28 @@ impl BigInt { Self(&self.0 + &other.0) } + pub fn sub(&self, other: &BigInt) -> BigInt { + Self(&self.0 - &other.0) + } + pub fn mul(&self, other: &BigInt) -> BigInt { Self(&self.0 * &other.0) } + pub fn pow(&self, exp: u32) -> BigInt { + Self(self.0.pow(exp)) + } + pub fn one() -> BigInt { - use std::str::FromStr; - Self(num_bigint::BigInt::from_str("1").unwrap()) + Self(num_bigint::BigInt::from(1)) + } + + pub fn zero() -> BigInt { + Self(num_bigint::BigInt::from(0)) + } + + pub fn abs(&self) -> BigInt { + Self(self.0.abs()) } pub fn increment(&self) -> BigInt { @@ -103,14 +120,15 @@ impl BigInt { } pub fn div_ceil(&self, other: &BigInt) -> BigInt { - use num_integer::Integer; - let (res, rem) = self.0.div_rem(&other.0); - let result = Self(res); - if Self(rem).is_zero() { - result - } else { - result.increment() - } + Self(self.0.div_ceil(&other.0)) + } + + pub fn div_floor(&self, other: &BigInt) -> BigInt { + Self(self.0.div_floor(&other.0)) + } + + pub(crate) fn is_negative(&self) -> bool { + self.0.is_negative() } } diff --git a/rust/src/rational.rs b/rust/src/rational.rs index 3b9eb8fe..180599bb 100644 --- a/rust/src/rational.rs +++ b/rust/src/rational.rs @@ -23,6 +23,21 @@ impl Rational { Rational { numerator: n, denominator: d, + }.reduce_minuses() + } + + + pub (crate) fn one() -> Self { + Rational { + numerator: BigInt::one(), + denominator: BigInt::one(), + } + } + + pub(crate) fn zero() -> Self { + Rational { + numerator: BigInt::zero(), + denominator: BigInt::one(), } } @@ -43,6 +58,29 @@ impl Rational { Rational::new(self.numerator.mul(&BigInt::from(x)), self.denominator.clone()) } + pub(crate) fn mul_ratio(&self, x: &Rational) -> Rational { + let a_num = &self.numerator; + let a_denum = &self.denominator; + let b_num = &x.numerator; + let b_denum = &x.denominator; + + let a_num_fixed = a_num.mul(b_num); + let a_denum_fixed = a_denum.mul(b_denum); + Rational::new(a_num_fixed, a_denum_fixed) + } + + pub(crate) fn div_ratio(&self, x: &Rational) -> Rational { + let a_num = &self.numerator; + let a_denum = &self.denominator; + let b_num = &x.numerator; + let b_denum = &x.denominator; + + let a_num_fixed = a_num.mul(b_denum); + let a_denum_fixed = a_denum.mul(b_num); + + Rational::new(a_num_fixed, a_denum_fixed) + } + pub(crate) fn add(&self, x: &Rational) -> Rational { let a_num = &self.numerator; let a_denum = &self.denominator; @@ -62,6 +100,25 @@ impl Rational { Rational::new(a_b_num_sum, common_denum) } + pub(crate) fn sub(&self, x: &Rational) -> Rational { + let a_num = &self.numerator; + let a_denum = &self.denominator; + let b_num = &x.numerator; + let b_denum = &x.denominator; + + if a_num.is_zero() { + return x.clone(); + } + if b_num.is_zero() { + return self.clone(); + } + let a_num_fixed = &a_num.mul(b_denum); + let b_num_fixed = &b_num.mul(a_denum); + let a_b_num_diff = a_num_fixed.sub(b_num_fixed); + let common_denum = a_denum.mul(b_denum); + Rational::new(a_b_num_diff, common_denum) + } + pub(crate) fn to_bignum_ceil(&self) -> Result { let num = self.numerator(); let denum = self.denominator(); @@ -79,6 +136,26 @@ impl Rational { } } + pub(crate) fn pow(&self, exp: u32) -> Rational { + let num = self.numerator.pow(exp); + let denum = self.denominator.pow(exp); + Rational::new(num, denum).reduce_minuses() + } + + pub(crate) fn is_zero(&self) -> bool { + self.numerator.is_zero() + } + + pub(crate) fn is_negative(&self) -> bool { + let is_num_negative = self.numerator.is_negative(); + let is_denum_negative = self.denominator.is_negative(); + is_num_negative ^ is_denum_negative + } + + pub(crate) fn is_negative_or_zero(&self) -> bool { + self.is_zero() || self.is_negative() + } + #[allow(dead_code)] pub(crate) fn to_bignum_floor(&self) -> Result { let num = self.numerator(); @@ -86,7 +163,7 @@ impl Rational { if denum.is_zero() { return Err(JsError::from_str("Division by zero")); } - let value = num.div_ceil(denum); + let value = num.div_floor(denum); match value.as_u64() { Some(coin) => Ok(coin), _ => Err(JsError::from_str(&format!( @@ -96,4 +173,12 @@ impl Rational { ))), } } + + fn reduce_minuses(mut self) -> Self{ + if self.numerator.is_negative() && self.denominator.is_negative() { + self.numerator = self.numerator.abs(); + self.denominator = self.denominator.abs(); + } + self + } } \ No newline at end of file diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index 376f688c..a7c4475e 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -5907,13 +5907,13 @@ fn ref_script_fee_from_all_builders() { let redeemer_8 = fake_redeemer_zero_cost(8); let plutus_source_1 = PlutusScriptSource::new_ref_input(&script_hash_1, &tx_in_1, &Language::new_plutus_v2(), 10); - let plutus_source_2 = PlutusScriptSource::new_ref_input(&script_hash_2, &tx_in_2, &Language::new_plutus_v2(), 100); - let plutus_source_3 = PlutusScriptSource::new_ref_input(&script_hash_3, &tx_in_3, &Language::new_plutus_v2(), 1000); - let plutus_source_4 = PlutusScriptSource::new_ref_input(&script_hash_4, &tx_in_4, &Language::new_plutus_v2(), 10000); - let plutus_source_5 = PlutusScriptSource::new_ref_input(&script_hash_5, &tx_in_5, &Language::new_plutus_v2(), 100000); - let plutus_source_6 = PlutusScriptSource::new_ref_input(&script_hash_6, &tx_in_6, &Language::new_plutus_v2(), 1000000); + let plutus_source_2 = PlutusScriptSource::new_ref_input(&script_hash_2, &tx_in_2, &Language::new_plutus_v2(), 11); + let plutus_source_3 = PlutusScriptSource::new_ref_input(&script_hash_3, &tx_in_3, &Language::new_plutus_v2(), 111); + let plutus_source_4 = PlutusScriptSource::new_ref_input(&script_hash_4, &tx_in_4, &Language::new_plutus_v2(), 200); + let plutus_source_5 = PlutusScriptSource::new_ref_input(&script_hash_5, &tx_in_5, &Language::new_plutus_v2(), 3000); + let plutus_source_6 = PlutusScriptSource::new_ref_input(&script_hash_6, &tx_in_6, &Language::new_plutus_v2(), 5000); let native_script_source = NativeScriptSource::new_ref_input(&script_hash_7, &tx_in_7); - let plutus_source_8 = PlutusScriptSource::new_ref_input(&script_hash_8, &tx_in_8, &Language::new_plutus_v2(), 10000000); + let plutus_source_8 = PlutusScriptSource::new_ref_input(&script_hash_8, &tx_in_8, &Language::new_plutus_v2(), 50000); mint_builder.add_asset( &MintWitness::new_plutus_script(&plutus_source_1, &redeemer_1), @@ -5981,7 +5981,7 @@ fn ref_script_fee_from_all_builders() { tx_builder.set_voting_builder(&voting_builder); tx_builder.set_voting_proposal_builder(&voting_proposal_builder); tx_builder.set_inputs(&tx_input_builder); - tx_builder.add_script_reference_input(&tx_in_9, 100000000); + tx_builder.add_script_reference_input(&tx_in_9, 16000); let fake_collateral = fake_tx_input(99); let mut collateral_builder = TxInputsBuilder::new(); @@ -6005,7 +6005,7 @@ fn ref_script_fee_from_all_builders() { wit_set.set_vkeys(&vkey_witneses); tx = Transaction::new(&tx.body(), &wit_set, tx.auxiliary_data()); - let ref_script_fee = BigNum::from(111111110u64 / 2); + let ref_script_fee = BigNum::from(44815u64); let total_tx_fee = tx.body().fee(); //TODO: check change calculation for pessimistic size estimation. diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index fd57bdb1..0a2b0b0d 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -738,4 +738,88 @@ fn tx_inputs_deduplication() { assert!(txins_from_bytes.contains(&tx_in1)); assert!(txins_from_bytes.contains(&tx_in2)); assert!(txins_from_bytes.contains(&tx_in3)); +} + +// Helper function to create a UnitInterval from a fraction +fn new_uinternal(numerator: u64, denominator: u64) -> UnitInterval { + UnitInterval::new(&BigNum::from(numerator), &BigNum::from(denominator)) +} + +#[test] +fn min_ref_script_fee_zero_size_test() { + let result = min_ref_script_fee(0, &new_uinternal(1, 1000)).unwrap(); + assert_eq!(result.to_str(), "0"); +} + +#[test] +fn min_ref_script_fee_small_size_test() { + let result = min_ref_script_fee(1000, &new_uinternal(1, 1000)).unwrap(); + assert_eq!(result.to_str(), "1"); +} + +#[test] +fn min_ref_script_fee_exactly_one_tier_test() { + let result = min_ref_script_fee(25600, &new_uinternal(1, 1000)).unwrap(); + assert_eq!(result.to_str(), "25"); +} + +#[test] +fn min_ref_script_fee_multiple_full_tiers_test() { + let result = min_ref_script_fee(25600 * 2, &new_uinternal(1, 1000)).unwrap(); + // You may need to adjust this expected value based on your exact implementation + let expected = ((25600f64 / 1000f64) + (25600f64 * 0.0012f64)) as u64; ; + assert_eq!(result, BigNum(expected)); +} + +#[test] +fn min_ref_script_fee_partial_tier_test() { + let result = min_ref_script_fee(30000, &new_uinternal(1, 1000)).unwrap(); + // You may need to adjust this expected value based on your exact implementation + assert_eq!(result.to_str(), "30"); +} + +#[test] +fn min_ref_script_fee_large_size_test() { + let result = min_ref_script_fee(1000000, &new_uinternal(1, 1000)).unwrap(); + // You may need to adjust this expected value based on your exact implementation + assert_eq!(result.to_str(), "158607"); +} + +#[test] +fn min_ref_script_fee_different_cost_per_byte_test() { + let result = min_ref_script_fee(50000, &new_uinternal(5, 1000)).unwrap(); + // You may need to adjust this expected value based on your exact implementation + assert_eq!(result.to_str(), "274"); +} + +#[test] +fn min_ref_script_fee_one_cost_per_byte_test() { + let result = min_ref_script_fee(10000, &new_uinternal(1, 1)).unwrap(); + assert_eq!(result.to_str(), "10000"); +} + +#[test] +fn min_ref_script_fee_zero_cost_per_byte_test() { + let fee = min_ref_script_fee(10000, &new_uinternal(0, 1)).unwrap(); + assert_eq!(fee.to_str(), "0"); +} + +#[test] +fn test_multiple_tiers() { + // Test cases with different numbers of tiers + let test_cases = [ + (25600, "25"), // Exactly 1 tier + (25601, "25"), // 1 full tier + 1 byte (at 1.2x price) + (51200, "56"), // Exactly 2 tiers + (76800, "93"), // Exactly 3 tiers + (80000, "98"), // 3 full tiers + partial tier + (100000, "133"), // 3 full tiers + larger partial tier + (128000, "190"), // Exactly 5 tiers + (179200, "330"), // 7 full tiers + ]; + + for (size, expected) in test_cases.iter() { + let result = min_ref_script_fee(*size, &new_uinternal(1, 1000)).unwrap(); + assert_eq!(result.to_str(), *expected, "Failed for size {}", size); + } } \ No newline at end of file From 044021efe294b83607e3c97965715b5b3009df81 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 30 Jul 2024 01:44:54 +0900 Subject: [PATCH 314/349] fix warning --- rust/src/tests/general.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index 0a2b0b0d..2bc6c131 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -767,7 +767,7 @@ fn min_ref_script_fee_exactly_one_tier_test() { fn min_ref_script_fee_multiple_full_tiers_test() { let result = min_ref_script_fee(25600 * 2, &new_uinternal(1, 1000)).unwrap(); // You may need to adjust this expected value based on your exact implementation - let expected = ((25600f64 / 1000f64) + (25600f64 * 0.0012f64)) as u64; ; + let expected = ((25600f64 / 1000f64) + (25600f64 * 0.0012f64)) as u64; assert_eq!(result, BigNum(expected)); } From 4666a9a100c7f163765c202fae3ed5d9a3750f67 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 30 Jul 2024 01:45:33 +0900 Subject: [PATCH 315/349] make certificates builder to respect insertion order --- rust/src/builders/certificates_builder.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rust/src/builders/certificates_builder.rs b/rust/src/builders/certificates_builder.rs index 2fb02818..b9aa0cba 100644 --- a/rust/src/builders/certificates_builder.rs +++ b/rust/src/builders/certificates_builder.rs @@ -1,16 +1,16 @@ -use std::collections::BTreeMap; +use hashlink::LinkedHashMap; use crate::*; #[wasm_bindgen] #[derive(Clone, Debug)] pub struct CertificatesBuilder { - certs: BTreeMap>, + certs: LinkedHashMap>, } #[wasm_bindgen] impl CertificatesBuilder { pub fn new() -> Self { - Self { certs: BTreeMap::new() } + Self { certs: LinkedHashMap::new() } } pub fn add(&mut self, cert: &Certificate) -> Result<(), JsError> { From ad2671acf81ff489d1fed7e7299b1560e206806e Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 30 Jul 2024 01:50:26 +0900 Subject: [PATCH 316/349] update js flow file --- rust/pkg/cardano_serialization_lib.js.flow | 353 ++++++++++++--------- 1 file changed, 199 insertions(+), 154 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index d5986462..e7575efa 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -42,30 +42,6 @@ declare export function min_ref_script_fee( ref_script_coins_per_byte: UnitInterval ): BigNum; -/** - * @param {string} json - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {PlutusData} - */ -declare export function encode_json_str_to_plutus_datum( - json: string, - schema: $Values -): PlutusData; - -/** - * @param {PlutusData} datum - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {string} - */ -declare export function decode_plutus_datum_to_json_str( - datum: PlutusData, - schema: $Values -): string; - /** * @param {string} password * @param {string} salt @@ -90,18 +66,6 @@ declare export function decrypt_with_password( data: string ): string; -/** - * @param {Address} address - * @param {TransactionUnspentOutputs} utxos - * @param {TransactionBuilderConfig} config - * @returns {TransactionBatchList} - */ -declare export function create_send_all( - address: Address, - utxos: TransactionUnspentOutputs, - config: TransactionBuilderConfig -): TransactionBatchList; - /** * @param {Uint8Array} bytes * @returns {TransactionMetadatum} @@ -268,11 +232,107 @@ declare export function encode_json_str_to_native_script( ): NativeScript; /** + * @param {string} json + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {PlutusData} + */ +declare export function encode_json_str_to_plutus_datum( + json: string, + schema: $Values +): PlutusData; + +/** + * @param {PlutusData} datum + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {string} */ +declare export function decode_plutus_datum_to_json_str( + datum: PlutusData, + schema: $Values +): string; -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 +/** + * @param {Address} address + * @param {TransactionUnspentOutputs} utxos + * @param {TransactionBuilderConfig} config + * @returns {TransactionBatchList} + */ +declare export function create_send_all( + address: Address, + utxos: TransactionUnspentOutputs, + config: TransactionBuilderConfig +): TransactionBatchList; + +/** + * JSON <-> PlutusData conversion schemas. + * Follows ScriptDataJsonSchema in cardano-cli defined at: + * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 + * + * All methods here have the following restrictions due to limitations on dependencies: + * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors + * * Hex strings for bytes don't accept odd-length (half-byte) strings. + * cardano-cli seems to support these however but it seems to be different than just 0-padding + * on either side when tested so proceed with caution + */ + +declare export var PlutusDatumSchema: {| + +BasicConversions: 0, // 0 + +DetailedSchema: 1, // 1 +|}; + +/** + */ + +declare export var GovernanceActionKind: {| + +ParameterChangeAction: 0, // 0 + +HardForkInitiationAction: 1, // 1 + +TreasuryWithdrawalsAction: 2, // 2 + +NoConfidenceAction: 3, // 3 + +UpdateCommitteeAction: 4, // 4 + +NewConstitutionAction: 5, // 5 + +InfoAction: 6, // 6 +|}; + +/** + */ + +declare export var AddressKind: {| + +Base: 0, // 0 + +Pointer: 1, // 1 + +Enterprise: 2, // 2 + +Reward: 3, // 3 + +Byron: 4, // 4 + +Malformed: 5, // 5 +|}; + +/** + */ + +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 +|}; + +/** + */ + +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 +|}; + +/** + */ + +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 |}; /** @@ -286,6 +346,20 @@ declare export var TransactionMetadatumKind: {| +Text: 4, // 4 |}; +/** + */ + +declare export var BlockEra: {| + +Byron: 0, // 0 + +Shelley: 1, // 1 + +Allegra: 2, // 2 + +Mary: 3, // 3 + +Alonzo: 4, // 4 + +Babbage: 5, // 5 + +Conway: 6, // 6 + +Unknown: 7, // 7 +|}; + /** */ @@ -321,20 +395,11 @@ declare export var CertificateKind: {| |}; /** - * JSON <-> PlutusData conversion schemas. - * Follows ScriptDataJsonSchema in cardano-cli defined at: - * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 - * - * All methods here have the following restrictions due to limitations on dependencies: - * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors - * * Hex strings for bytes don't accept odd-length (half-byte) strings. - * cardano-cli seems to support these however but it seems to be different than just 0-padding - * on either side when tested so proceed with caution */ -declare export var PlutusDatumSchema: {| - +BasicConversions: 0, // 0 - +DetailedSchema: 1, // 1 +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 |}; /** @@ -346,51 +411,6 @@ declare export var LanguageKind: {| +PlutusV3: 2, // 2 |}; -/** - */ - -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 -|}; - -/** - */ - -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 -|}; - -/** - * Each new language uses a different namespace for hashing its script - * This is because you could have a language where the same bytes have different semantics - * So this avoids scripts in different languages mapping to the same hash - * Note that the enum value here is different than the enum value for deciding the cost model of a script - */ - -declare export var ScriptHashNamespace: {| - +NativeScript: 0, // 0 - +PlutusScript: 1, // 1 - +PlutusScriptV2: 2, // 2 - +PlutusScriptV3: 3, // 3 -|}; - -/** - */ - -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 -|}; - /** */ @@ -404,9 +424,10 @@ declare export var CoinSelectionStrategyCIP2: {| /** */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var RelayKind: {| + +SingleHostAddr: 0, // 0 + +SingleHostName: 1, // 1 + +MultiHostName: 2, // 2 |}; /** @@ -417,29 +438,6 @@ declare export var MIRPot: {| +Treasury: 1, // 1 |}; -/** - */ - -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 -|}; - -/** - */ - -declare export var BlockEra: {| - +Byron: 0, // 0 - +Shelley: 1, // 1 - +Allegra: 2, // 2 - +Mary: 3, // 3 - +Alonzo: 4, // 4 - +Babbage: 5, // 5 - +Conway: 6, // 6 - +Unknown: 7, // 7 -|}; - /** */ @@ -462,64 +460,66 @@ declare export var ScriptSchema: {| |}; /** + * Each new language uses a different namespace for hashing its script + * This is because you could have a language where the same bytes have different semantics + * So this avoids scripts in different languages mapping to the same hash + * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var AddressKind: {| - +Base: 0, // 0 - +Pointer: 1, // 1 - +Enterprise: 2, // 2 - +Reward: 3, // 3 - +Byron: 4, // 4 - +Malformed: 5, // 5 +declare export var ScriptHashNamespace: {| + +NativeScript: 0, // 0 + +PlutusScript: 1, // 1 + +PlutusScriptV2: 2, // 2 + +PlutusScriptV3: 3, // 3 |}; /** */ -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 |}; /** */ -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** */ -declare export var RelayKind: {| - +SingleHostAddr: 0, // 0 - +SingleHostName: 1, // 1 - +MultiHostName: 2, // 2 +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 |}; /** */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 |}; /** */ -declare export var GovernanceActionKind: {| - +ParameterChangeAction: 0, // 0 - +HardForkInitiationAction: 1, // 1 - +TreasuryWithdrawalsAction: 2, // 2 - +NoConfidenceAction: 3, // 3 - +UpdateCommitteeAction: 4, // 4 - +NewConstitutionAction: 5, // 5 - +InfoAction: 6, // 6 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 |}; /** @@ -1165,17 +1165,39 @@ declare export class BigInt { */ add(other: BigInt): BigInt; + /** + * @param {BigInt} other + * @returns {BigInt} + */ + sub(other: BigInt): BigInt; + /** * @param {BigInt} other * @returns {BigInt} */ mul(other: BigInt): BigInt; + /** + * @param {number} exp + * @returns {BigInt} + */ + pow(exp: number): BigInt; + /** * @returns {BigInt} */ static one(): BigInt; + /** + * @returns {BigInt} + */ + static zero(): BigInt; + + /** + * @returns {BigInt} + */ + abs(): BigInt; + /** * @returns {BigInt} */ @@ -1186,6 +1208,12 @@ declare export class BigInt { * @returns {BigInt} */ div_ceil(other: BigInt): BigInt; + + /** + * @param {BigInt} other + * @returns {BigInt} + */ + div_floor(other: BigInt): BigInt; } /** */ @@ -3061,6 +3089,12 @@ declare export class DRep { */ static new_always_no_confidence(): DRep; + /** + * @param {Credential} cred + * @returns {DRep} + */ + static new_from_credential(cred: Credential): DRep; + /** * @returns {$Values< typeof @@ -3077,6 +3111,17 @@ declare export class DRep { * @returns {ScriptHash | void} */ to_script_hash(): ScriptHash | void; + + /** + * @returns {string} + */ + to_bech32(): string; + + /** + * @param {string} bech32_str + * @returns {DRep} + */ + static from_bech32(bech32_str: string): DRep; } /** */ @@ -13436,7 +13481,7 @@ declare export class Voter { /** * @returns {Credential | void} */ - to_constitutional_committee_hot_cred(): Credential | void; + to_constitutional_committee_hot_key(): Credential | void; /** * @returns {Credential | void} From eb1b085c40bfb3f53fd71b488b69ad3d3c48fd86 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 30 Jul 2024 01:54:23 +0900 Subject: [PATCH 317/349] bump version --- package-lock.json | 4 ++-- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 831e8f35..37c86caf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.2", + "version": "12.0.0-beta.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.2", + "version": "12.0.0-beta.3", "hasInstallScript": true, "license": "MIT", "devDependencies": { diff --git a/package.json b/package.json index 6ea1f487..4d21876c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.2", + "version": "12.0.0-beta.3", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 0bd65fb0..00ee8cfd 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-beta.2" +version = "12.0.0-beta.3" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 7dbd0d93..1a19ce6a 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -49,7 +49,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-beta.2" +version = "12.0.0-beta.3" dependencies = [ "bech32", "cbor_event", From 6d79164d2e573c96ddc8eeeacfef35d9c484434a Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 30 Jul 2024 18:48:47 +0900 Subject: [PATCH 318/349] remove comments --- rust/src/tests/general.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index 2bc6c131..309fbed2 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -766,7 +766,6 @@ fn min_ref_script_fee_exactly_one_tier_test() { #[test] fn min_ref_script_fee_multiple_full_tiers_test() { let result = min_ref_script_fee(25600 * 2, &new_uinternal(1, 1000)).unwrap(); - // You may need to adjust this expected value based on your exact implementation let expected = ((25600f64 / 1000f64) + (25600f64 * 0.0012f64)) as u64; assert_eq!(result, BigNum(expected)); } @@ -774,21 +773,18 @@ fn min_ref_script_fee_multiple_full_tiers_test() { #[test] fn min_ref_script_fee_partial_tier_test() { let result = min_ref_script_fee(30000, &new_uinternal(1, 1000)).unwrap(); - // You may need to adjust this expected value based on your exact implementation assert_eq!(result.to_str(), "30"); } #[test] fn min_ref_script_fee_large_size_test() { let result = min_ref_script_fee(1000000, &new_uinternal(1, 1000)).unwrap(); - // You may need to adjust this expected value based on your exact implementation assert_eq!(result.to_str(), "158607"); } #[test] fn min_ref_script_fee_different_cost_per_byte_test() { let result = min_ref_script_fee(50000, &new_uinternal(5, 1000)).unwrap(); - // You may need to adjust this expected value based on your exact implementation assert_eq!(result.to_str(), "274"); } From cb1d0f1d5c1fe0b97e4aa3f453f26b4784280971 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 2 Aug 2024 23:15:08 +0900 Subject: [PATCH 319/349] rename new_with_coin to new_with_explicit_deposit and new_with_explicit_refund --- .../protocol_types/certificates/stake_deregistration.rs | 2 +- .../src/protocol_types/certificates/stake_registration.rs | 2 +- rust/src/tests/builders/certificates_builder.rs | 8 ++++---- rust/src/tests/protocol_types/certificates.rs | 4 ++-- rust/src/tests/serialization/certificates.rs | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/rust/src/protocol_types/certificates/stake_deregistration.rs b/rust/src/protocol_types/certificates/stake_deregistration.rs index 8caf2ee0..4670148d 100644 --- a/rust/src/protocol_types/certificates/stake_deregistration.rs +++ b/rust/src/protocol_types/certificates/stake_deregistration.rs @@ -37,7 +37,7 @@ impl StakeDeregistration { } } - pub fn new_with_coin(stake_credential: &Credential, coin: &Coin) -> Self { + pub fn new_with_explicit_refund(stake_credential: &Credential, coin: &Coin) -> Self { Self { stake_credential: stake_credential.clone(), coin: Some(coin.clone()), diff --git a/rust/src/protocol_types/certificates/stake_registration.rs b/rust/src/protocol_types/certificates/stake_registration.rs index c605c1a0..c0cd6f77 100644 --- a/rust/src/protocol_types/certificates/stake_registration.rs +++ b/rust/src/protocol_types/certificates/stake_registration.rs @@ -37,7 +37,7 @@ impl StakeRegistration { } } - pub fn new_with_coin(stake_credential: &Credential, coin: &Coin) -> Self { + pub fn new_with_explicit_deposit(stake_credential: &Credential, coin: &Coin) -> Self { Self { stake_credential: stake_credential.clone(), coin: Some(coin.clone()), diff --git a/rust/src/tests/builders/certificates_builder.rs b/rust/src/tests/builders/certificates_builder.rs index 69827ad5..452d48cb 100644 --- a/rust/src/tests/builders/certificates_builder.rs +++ b/rust/src/tests/builders/certificates_builder.rs @@ -91,7 +91,7 @@ fn certificates_builder_deposit_no_refund_test() { let stake_reg_cert = StakeRegistration::new(&Credential::from_keyhash(&fake_key_hash(23))); let stake_reg_cert_wrapped = Certificate::new_stake_registration(&stake_reg_cert); - let stake_reg_with_coin_cert = StakeRegistration::new_with_coin( + let stake_reg_with_coin_cert = StakeRegistration::new_with_explicit_deposit( &Credential::from_keyhash(&fake_key_hash(23)), &Coin::from(key_deposit_form_args), ); @@ -230,7 +230,7 @@ fn certificates_builder_refund_no_deposit_test() { let stake_dereg_cert = StakeDeregistration::new(&Credential::from_keyhash(&fake_key_hash(22))); let stake_dereg_cert_wrapped = Certificate::new_stake_deregistration(&stake_dereg_cert); - let stake_dereg_with_coin_cert = StakeDeregistration::new_with_coin( + let stake_dereg_with_coin_cert = StakeDeregistration::new_with_explicit_refund( &Credential::from_keyhash(&fake_key_hash(22)), &Coin::from(key_deposit_form_args), ); @@ -389,7 +389,7 @@ fn certificates_builder_req_signers_test() { let stake_dereg_cert = StakeDeregistration::new(&Credential::from_keyhash(&key_hash_21)); let stake_dereg_cert_wrapped = Certificate::new_stake_deregistration(&stake_dereg_cert); - let stake_dereg_with_coin_cert = StakeDeregistration::new_with_coin( + let stake_dereg_with_coin_cert = StakeDeregistration::new_with_explicit_refund( &Credential::from_keyhash(&key_hash_22), &Coin::from(key_deposit_form_args), ); @@ -399,7 +399,7 @@ fn certificates_builder_req_signers_test() { let stake_reg_cert = StakeRegistration::new(&Credential::from_keyhash(&key_hash_23)); let stake_reg_cert_wrapped = Certificate::new_stake_registration(&stake_reg_cert); - let stake_reg_with_coin_cert = StakeRegistration::new_with_coin( + let stake_reg_with_coin_cert = StakeRegistration::new_with_explicit_deposit( &Credential::from_keyhash(&key_hash_24), &Coin::from(key_deposit_form_args), ); diff --git a/rust/src/tests/protocol_types/certificates.rs b/rust/src/tests/protocol_types/certificates.rs index 1a53bb17..05235577 100644 --- a/rust/src/tests/protocol_types/certificates.rs +++ b/rust/src/tests/protocol_types/certificates.rs @@ -181,7 +181,7 @@ fn stake_deregisration_setters_getters_test() { let stake_deregistration_1 = StakeDeregistration::new(&cred_key_hash); let coin = Coin::from(100u32); - let stake_deregistration_2 = StakeDeregistration::new_with_coin(&cred_key_hash, &coin); + let stake_deregistration_2 = StakeDeregistration::new_with_explicit_refund(&cred_key_hash, &coin); assert_eq!(stake_deregistration_1.stake_credential(), cred_key_hash); assert_eq!(stake_deregistration_1.coin(), None); @@ -196,7 +196,7 @@ fn stake_regisration_setters_getters_test() { let cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); let coin = Coin::from(100u32); let stake_registration_1 = StakeRegistration::new(&cred_key_hash); - let stake_registration_2 = StakeRegistration::new_with_coin(&cred_key_hash, &coin); + let stake_registration_2 = StakeRegistration::new_with_explicit_deposit(&cred_key_hash, &coin); assert_eq!(stake_registration_1.stake_credential(), cred_key_hash); assert_eq!(stake_registration_1.coin(), None); diff --git a/rust/src/tests/serialization/certificates.rs b/rust/src/tests/serialization/certificates.rs index 72a9545f..62bffc8b 100644 --- a/rust/src/tests/serialization/certificates.rs +++ b/rust/src/tests/serialization/certificates.rs @@ -272,7 +272,7 @@ fn stake_deregistration_ser_round_trip() { #[test] fn stake_deregistration_with_coin_ser_round_trip() { - let cert = StakeDeregistration::new_with_coin( + let cert = StakeDeregistration::new_with_explicit_refund( &Credential::from_keyhash(&fake_key_hash(1)), &Coin::from(100u64), ); @@ -291,7 +291,7 @@ fn stake_registration_ser_round_trip() { #[test] fn stake_registration_with_coin_ser_round_trip() { - let cert = StakeRegistration::new_with_coin( + let cert = StakeRegistration::new_with_explicit_deposit( &Credential::from_keyhash(&fake_key_hash(1)), &Coin::from(100u64), ); From 500f14422452e17c123e9f5b4d1e700633bab864 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 3 Aug 2024 02:57:34 +0900 Subject: [PATCH 320/349] add specific constructors for reg_cert and unreg_cert into certificate type --- .../certificates/certificate.rs | 59 +++++++++++++++++++ rust/src/tests/serialization/certificates.rs | 52 ++++++++++++++++ 2 files changed, 111 insertions(+) diff --git a/rust/src/protocol_types/certificates/certificate.rs b/rust/src/protocol_types/certificates/certificate.rs index bda411f9..3045550b 100644 --- a/rust/src/protocol_types/certificates/certificate.rs +++ b/rust/src/protocol_types/certificates/certificate.rs @@ -73,18 +73,45 @@ impl_to_from!(Certificate); #[wasm_bindgen] impl Certificate { + pub fn new_stake_registration(stake_registration: &StakeRegistration) -> Self { Self(CertificateEnum::StakeRegistration( stake_registration.clone(), )) } + /// Since StakeRegistration can represent stake_registration certificate or reg_cert certificate, because both certificates have the same semantics. + /// And in some cases you want to create a reg_cert, this function is used to create a reg_cert. + /// The function will return an error if StakeRegistration represents a stake_registration certificate. + pub fn new_reg_cert(stake_registration: &StakeRegistration) -> Result { + if stake_registration.coin.is_none() { + return Err(JsError::from_str("coin is required")); + } else { + Ok(Self(CertificateEnum::StakeRegistration( + stake_registration.clone(), + ))) + } + } + pub fn new_stake_deregistration(stake_deregistration: &StakeDeregistration) -> Self { Self(CertificateEnum::StakeDeregistration( stake_deregistration.clone(), )) } + /// Since StakeDeregistration can represent stake_deregistration certificate or unreg_cert certificate, because both certificates have the same semantics. + /// And in some cases you want to create an unreg_cert, this function is used to create an unreg_cert. + /// The function will return an error if StakeDeregistration represents a stake_deregistration certificate. + pub fn new_unreg_cert(stake_deregistration: &StakeDeregistration) -> Result { + if stake_deregistration.coin.is_none() { + return Err(JsError::from_str("coin is required")); + } else { + Ok(Self(CertificateEnum::StakeDeregistration( + stake_deregistration.clone(), + ))) + } + } + pub fn new_stake_delegation(stake_delegation: &StakeDelegation) -> Self { Self(CertificateEnum::StakeDelegation(stake_delegation.clone())) } @@ -218,6 +245,22 @@ impl Certificate { } } + /// Since StakeRegistration can represent stake_registration certificate or reg_cert certificate, because both certificates have the same semantics. + /// And in some cases you want to get a reg_cert, this function is used to get a reg_cert. + /// The function will return None if StakeRegistration represents a stake_registration certificate or Certificate is not a StakeRegistration. + pub fn as_reg_cert(&self) -> Option { + match &self.0 { + CertificateEnum::StakeRegistration(x) => { + return if x.coin.is_some() { + Some(x.clone()) + } else { + None + } + } + _ => None, + } + } + pub fn as_stake_deregistration(&self) -> Option { match &self.0 { CertificateEnum::StakeDeregistration(x) => Some(x.clone()), @@ -225,6 +268,22 @@ impl Certificate { } } + /// Since StakeDeregistration can represent stake_deregistration certificate or unreg_cert certificate, because both certificates have the same semantics. + /// And in some cases you want to get an unreg_cert, this function is used to get an unreg_cert. + /// The function will return None if StakeDeregistration represents a stake_deregistration certificate or Certificate is not a StakeDeregistration. + pub fn as_unreg_cert(&self) -> Option { + match &self.0 { + CertificateEnum::StakeDeregistration(x) => { + return if x.coin.is_some() { + Some(x.clone()) + } else { + None + } + } + _ => None, + } + } + pub fn as_stake_delegation(&self) -> Option { match &self.0 { CertificateEnum::StakeDelegation(x) => Some(x.clone()), diff --git a/rust/src/tests/serialization/certificates.rs b/rust/src/tests/serialization/certificates.rs index 62bffc8b..b74f02f6 100644 --- a/rust/src/tests/serialization/certificates.rs +++ b/rust/src/tests/serialization/certificates.rs @@ -281,12 +281,45 @@ fn stake_deregistration_with_coin_ser_round_trip() { assert_eq!(cert, cert_wrapped.as_stake_deregistration().unwrap()); } +#[test] +fn stake_deregistration_getter_test() { + let cert = StakeDeregistration::new( + &Credential::from_keyhash(&fake_key_hash(1)) + ); + let cert_wrapped = Certificate::new_unreg_cert(&cert).unwrap(); + to_from_test!(StakeDeregistration, cert, cert_wrapped); + assert_eq!(cert, cert_wrapped.as_stake_deregistration().unwrap()); + assert_eq!(None, cert_wrapped.as_unreg_cert()); +} + +#[test] +fn unreg_cert_getter_test() { + let cert = StakeDeregistration::new_with_explicit_refund( + &Credential::from_keyhash(&fake_key_hash(1)), + &Coin::from(100u64), + ); + let cert_wrapped = Certificate::new_unreg_cert(&cert).unwrap(); + to_from_test!(StakeDeregistration, cert, cert_wrapped); + assert_eq!(cert, cert_wrapped.as_stake_deregistration().unwrap()); + assert_eq!(cert, cert_wrapped.as_unreg_cert().unwrap()); +} + +#[test] +fn unreg_cert_error_test() { + let cert = StakeDeregistration::new( + &Credential::from_keyhash(&fake_key_hash(1)) + ); + let res = Certificate::new_unreg_cert(&cert); + assert!(res.is_err()); +} + #[test] fn stake_registration_ser_round_trip() { let cert = StakeRegistration::new(&Credential::from_keyhash(&fake_key_hash(1))); let cert_wrapped = Certificate::new_stake_registration(&cert); to_from_test!(StakeRegistration, cert, cert_wrapped); assert_eq!(cert, cert_wrapped.as_stake_registration().unwrap()); + assert_eq!(None, cert_wrapped.as_reg_cert()) } #[test] @@ -300,6 +333,25 @@ fn stake_registration_with_coin_ser_round_trip() { assert_eq!(cert, cert_wrapped.as_stake_registration().unwrap()); } +#[test] +fn reg_cert_getter_test() { + let cert = StakeRegistration::new_with_explicit_deposit( + &Credential::from_keyhash(&fake_key_hash(1)), + &Coin::from(100u64), + ); + let cert_wrapped = Certificate::new_reg_cert(&cert).unwrap(); + to_from_test!(StakeRegistration, cert, cert_wrapped); + assert_eq!(cert, cert_wrapped.as_stake_registration().unwrap()); + assert_eq!(cert, cert_wrapped.as_reg_cert().unwrap()); +} + +#[test] +fn reg_cert_error_test() { + let cert = StakeRegistration::new(&Credential::from_keyhash(&fake_key_hash(1))); + let res = Certificate::new_reg_cert(&cert); + assert!(res.is_err()); +} + #[test] fn stake_registration_and_delegation_ser_round_trip() { let cert = StakeRegistrationAndDelegation::new( From 9bbb7dc465f2b732b6706ff0b59319eae0bcd5bf Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 3 Aug 2024 03:03:46 +0900 Subject: [PATCH 321/349] fix max dns name len --- rust/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index dfb464be..72f599c8 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -448,7 +448,7 @@ impl URL { } } -static DNS_NAME_MAX_LEN: usize = 64; +static DNS_NAME_MAX_LEN: usize = 128; #[wasm_bindgen] #[derive( From b765c78dc5d1c48bff828bae3e8556d29543d322 Mon Sep 17 00:00:00 2001 From: lisicky Date: Sat, 3 Aug 2024 03:05:00 +0900 Subject: [PATCH 322/349] fix tests --- rust/src/tests/serialization/certificates.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/src/tests/serialization/certificates.rs b/rust/src/tests/serialization/certificates.rs index b74f02f6..e70edccc 100644 --- a/rust/src/tests/serialization/certificates.rs +++ b/rust/src/tests/serialization/certificates.rs @@ -286,7 +286,7 @@ fn stake_deregistration_getter_test() { let cert = StakeDeregistration::new( &Credential::from_keyhash(&fake_key_hash(1)) ); - let cert_wrapped = Certificate::new_unreg_cert(&cert).unwrap(); + let cert_wrapped = Certificate::new_stake_deregistration(&cert); to_from_test!(StakeDeregistration, cert, cert_wrapped); assert_eq!(cert, cert_wrapped.as_stake_deregistration().unwrap()); assert_eq!(None, cert_wrapped.as_unreg_cert()); From 0287a6ab9c2933b89dd3e843404fc5cc07cf8b42 Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 8 Aug 2024 01:43:23 +0900 Subject: [PATCH 323/349] fix memory management for set_asset --- rust/src/lib.rs | 4 +- rust/src/tests/builders/tx_builder.rs | 64 +++++++++++++-------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 72f599c8..6e836ba1 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1715,12 +1715,12 @@ impl MultiAsset { &mut self, policy_id: &PolicyID, asset_name: &AssetName, - value: BigNum, + value: &BigNum, ) -> Option { self.0 .entry(policy_id.clone()) .or_default() - .insert(asset_name, &value) + .insert(asset_name, value) } /// returns the amount of asset {asset_name} under policy {policy_id} diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index a7c4475e..e46adc20 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -2161,10 +2161,10 @@ fn tx_builder_cip2_largest_first_multiasset() { let mut output_value = Value::new(&BigNum(415)); let mut output_ma = MultiAsset::new(); - output_ma.set_asset(&pid1, &asset_name1, BigNum(5)); - output_ma.set_asset(&pid1, &asset_name2, BigNum(1)); - output_ma.set_asset(&pid2, &asset_name2, BigNum(2)); - output_ma.set_asset(&pid2, &asset_name3, BigNum(4)); + output_ma.set_asset(&pid1, &asset_name1, &BigNum(5)); + output_ma.set_asset(&pid1, &asset_name2, &BigNum(1)); + output_ma.set_asset(&pid2, &asset_name2, &BigNum(2)); + output_ma.set_asset(&pid2, &asset_name3, &BigNum(4)); output_value.set_multiasset(&output_ma); tx_builder .add_output(&TransactionOutput::new( @@ -2181,41 +2181,41 @@ fn tx_builder_cip2_largest_first_multiasset() { // should not be taken let mut input1 = make_input(1u8, Value::new(&BigNum(200))); let mut ma1 = MultiAsset::new(); - ma1.set_asset(&pid1, &asset_name1, BigNum(10)); - ma1.set_asset(&pid1, &asset_name2, BigNum(1)); - ma1.set_asset(&pid2, &asset_name2, BigNum(2)); + ma1.set_asset(&pid1, &asset_name1, &BigNum(10)); + ma1.set_asset(&pid1, &asset_name2, &BigNum(1)); + ma1.set_asset(&pid2, &asset_name2, &BigNum(2)); input1.output.amount.set_multiasset(&ma1); available_inputs.add(&input1); // taken first to satisfy pid1:asset_name1 (but also satisfies pid2:asset_name3) let mut input2 = make_input(2u8, Value::new(&BigNum(10))); let mut ma2 = MultiAsset::new(); - ma2.set_asset(&pid1, &asset_name1, BigNum(20)); - ma2.set_asset(&pid2, &asset_name3, BigNum(4)); + ma2.set_asset(&pid1, &asset_name1, &BigNum(20)); + ma2.set_asset(&pid2, &asset_name3, &BigNum(4)); input2.output.amount.set_multiasset(&ma2); available_inputs.add(&input2); // taken second to satisfy pid1:asset_name2 (but also satisfies pid2:asset_name1) let mut input3 = make_input(3u8, Value::new(&BigNum(50))); let mut ma3 = MultiAsset::new(); - ma3.set_asset(&pid2, &asset_name1, BigNum(5)); - ma3.set_asset(&pid1, &asset_name2, BigNum(15)); + ma3.set_asset(&pid2, &asset_name1, &BigNum(5)); + ma3.set_asset(&pid1, &asset_name2, &BigNum(15)); input3.output.amount.multiasset = Some(ma3); available_inputs.add(&input3); // should not be taken either let mut input4 = make_input(4u8, Value::new(&BigNum(10))); let mut ma4 = MultiAsset::new(); - ma4.set_asset(&pid1, &asset_name1, BigNum(10)); - ma4.set_asset(&pid1, &asset_name2, BigNum(10)); + ma4.set_asset(&pid1, &asset_name1, &BigNum(10)); + ma4.set_asset(&pid1, &asset_name2, &BigNum(10)); input4.output.amount.multiasset = Some(ma4); available_inputs.add(&input4); // taken third to satisfy pid2:asset_name_2 let mut input5 = make_input(5u8, Value::new(&BigNum(10))); let mut ma5 = MultiAsset::new(); - ma5.set_asset(&pid1, &asset_name2, BigNum(10)); - ma5.set_asset(&pid2, &asset_name2, BigNum(3)); + ma5.set_asset(&pid1, &asset_name2, &BigNum(10)); + ma5.set_asset(&pid2, &asset_name2, &BigNum(3)); input5.output.amount.multiasset = Some(ma5); available_inputs.add(&input5); @@ -2278,10 +2278,10 @@ fn tx_builder_cip2_random_improve_multiasset() { let mut output_value = Value::new(&BigNum(415)); let mut output_ma = MultiAsset::new(); - output_ma.set_asset(&pid1, &asset_name1, BigNum(5)); - output_ma.set_asset(&pid1, &asset_name2, BigNum(1)); - output_ma.set_asset(&pid2, &asset_name2, BigNum(2)); - output_ma.set_asset(&pid2, &asset_name3, BigNum(4)); + output_ma.set_asset(&pid1, &asset_name1, &BigNum(5)); + output_ma.set_asset(&pid1, &asset_name2, &BigNum(1)); + output_ma.set_asset(&pid2, &asset_name2, &BigNum(2)); + output_ma.set_asset(&pid2, &asset_name3, &BigNum(4)); output_value.set_multiasset(&output_ma); tx_builder .add_output(&TransactionOutput::new( @@ -2296,37 +2296,37 @@ fn tx_builder_cip2_random_improve_multiasset() { let mut input1 = make_input(1u8, Value::new(&BigNum(200))); let mut ma1 = MultiAsset::new(); - ma1.set_asset(&pid1, &asset_name1, BigNum(10)); - ma1.set_asset(&pid1, &asset_name2, BigNum(1)); - ma1.set_asset(&pid2, &asset_name2, BigNum(2)); + ma1.set_asset(&pid1, &asset_name1, &BigNum(10)); + ma1.set_asset(&pid1, &asset_name2, &BigNum(1)); + ma1.set_asset(&pid2, &asset_name2, &BigNum(2)); input1.output.amount.set_multiasset(&ma1); available_inputs.add(&input1); let mut input2 = make_input(2u8, Value::new(&BigNum(10))); let mut ma2 = MultiAsset::new(); - ma2.set_asset(&pid1, &asset_name1, BigNum(20)); - ma2.set_asset(&pid2, &asset_name3, BigNum(4)); + ma2.set_asset(&pid1, &asset_name1, &BigNum(20)); + ma2.set_asset(&pid2, &asset_name3, &BigNum(4)); input2.output.amount.set_multiasset(&ma2); available_inputs.add(&input2); let mut input3 = make_input(3u8, Value::new(&BigNum(50))); let mut ma3 = MultiAsset::new(); - ma3.set_asset(&pid2, &asset_name1, BigNum(5)); - ma3.set_asset(&pid1, &asset_name2, BigNum(15)); + ma3.set_asset(&pid2, &asset_name1, &BigNum(5)); + ma3.set_asset(&pid1, &asset_name2, &BigNum(15)); input3.output.amount.multiasset = Some(ma3); available_inputs.add(&input3); let mut input4 = make_input(4u8, Value::new(&BigNum(10))); let mut ma4 = MultiAsset::new(); - ma4.set_asset(&pid1, &asset_name1, BigNum(10)); - ma4.set_asset(&pid1, &asset_name2, BigNum(10)); + ma4.set_asset(&pid1, &asset_name1, &BigNum(10)); + ma4.set_asset(&pid1, &asset_name2, &BigNum(10)); input4.output.amount.multiasset = Some(ma4); available_inputs.add(&input4); let mut input5 = make_input(5u8, Value::new(&BigNum(10))); let mut ma5 = MultiAsset::new(); - ma5.set_asset(&pid1, &asset_name2, BigNum(10)); - ma5.set_asset(&pid2, &asset_name2, BigNum(3)); + ma5.set_asset(&pid1, &asset_name2, &BigNum(10)); + ma5.set_asset(&pid2, &asset_name2, &BigNum(3)); input5.output.amount.multiasset = Some(ma5); available_inputs.add(&input5); @@ -2336,13 +2336,13 @@ fn tx_builder_cip2_random_improve_multiasset() { let mut input8 = make_input(8u8, Value::new(&BigNum(10))); let mut ma8 = MultiAsset::new(); - ma8.set_asset(&pid2, &asset_name2, BigNum(10)); + ma8.set_asset(&pid2, &asset_name2, &BigNum(10)); input8.output.amount.multiasset = Some(ma8); available_inputs.add(&input8); let mut input9 = make_input(9u8, Value::new(&BigNum(10))); let mut ma9 = MultiAsset::new(); - ma9.set_asset(&pid2, &asset_name3, BigNum(10)); + ma9.set_asset(&pid2, &asset_name3, &BigNum(10)); input9.output.amount.multiasset = Some(ma9); available_inputs.add(&input9); From 1d6974140c9e1c1c2e388302b9fa32830308d8e8 Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 8 Aug 2024 01:43:39 +0900 Subject: [PATCH 324/349] fix memory management for set_asset --- rust/src/builders/batch_tools/asset_categorizer.rs | 2 +- rust/src/tests/builders/batch_tools.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/src/builders/batch_tools/asset_categorizer.rs b/rust/src/builders/batch_tools/asset_categorizer.rs index 36d33a44..2ce705b4 100644 --- a/rust/src/builders/batch_tools/asset_categorizer.rs +++ b/rust/src/builders/batch_tools/asset_categorizer.rs @@ -218,7 +218,7 @@ impl AssetCategorizer { multiasset.set_asset( &self.policies[policy_index.0], &self.assets[asset_index.0].1, - asset_coins, + &asset_coins, ); } } diff --git a/rust/src/tests/builders/batch_tools.rs b/rust/src/tests/builders/batch_tools.rs index e72be558..917d8363 100644 --- a/rust/src/tests/builders/batch_tools.rs +++ b/rust/src/tests/builders/batch_tools.rs @@ -15,7 +15,7 @@ fn generate_assets( let policy_id = fake_policy_id(i as u8); for j in from_asset..(assets_count + from_asset) { let asset_name = AssetName::new(vec![j as u8; asset_name_size]).unwrap(); - assets.set_asset(&policy_id, &asset_name, amount_per_asset); + assets.set_asset(&policy_id, &asset_name, &amount_per_asset); } } From 97d8be22b61bf78213128d7cd2221ffc931c9339 Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 8 Aug 2024 01:44:35 +0900 Subject: [PATCH 325/349] add fixed block --- rust/src/lib.rs | 324 --------------- rust/src/protocol_types/block/block.rs | 54 +++ rust/src/protocol_types/block/fixed_block.rs | 43 ++ .../block/fixed_transaction_bodies.rs | 27 ++ .../src/protocol_types/block/fixed_tx_body.rs | 29 ++ .../block/fixed_versioned_block.rs | 32 ++ rust/src/protocol_types/block/header.rs | 28 ++ rust/src/protocol_types/block/header_body.rs | 176 ++++++++ rust/src/protocol_types/block/mod.rs | 29 ++ .../protocol_types/block/operational_cert.rs | 45 ++ .../block/transaction_bodies.rs | 26 ++ .../{ => block}/versioned_block.rs | 0 rust/src/protocol_types/mod.rs | 6 +- rust/src/serialization/block/block.rs | 80 ++++ rust/src/serialization/block/fixed_block.rs | 83 ++++ .../block/fixed_transaction_bodies.rs | 23 ++ .../block/fixed_transaction_body.rs | 17 + .../block/fixed_versioned_block.rs | 16 + rust/src/serialization/block/header.rs | 57 +++ rust/src/serialization/block/header_body.rs | 150 +++++++ rust/src/serialization/block/mod.rs | 10 + .../serialization/block/operational_cert.rs | 73 ++++ .../serialization/block/transaction_bodies.rs | 36 ++ .../{ => block}/versioned_block.rs | 0 rust/src/serialization/fixed_tx.rs | 16 +- rust/src/serialization/general.rs | 389 ------------------ rust/src/serialization/mod.rs | 4 +- rust/src/serialization/utils.rs | 15 + 28 files changed, 1055 insertions(+), 733 deletions(-) create mode 100644 rust/src/protocol_types/block/block.rs create mode 100644 rust/src/protocol_types/block/fixed_block.rs create mode 100644 rust/src/protocol_types/block/fixed_transaction_bodies.rs create mode 100644 rust/src/protocol_types/block/fixed_tx_body.rs create mode 100644 rust/src/protocol_types/block/fixed_versioned_block.rs create mode 100644 rust/src/protocol_types/block/header.rs create mode 100644 rust/src/protocol_types/block/header_body.rs create mode 100644 rust/src/protocol_types/block/mod.rs create mode 100644 rust/src/protocol_types/block/operational_cert.rs create mode 100644 rust/src/protocol_types/block/transaction_bodies.rs rename rust/src/protocol_types/{ => block}/versioned_block.rs (100%) create mode 100644 rust/src/serialization/block/block.rs create mode 100644 rust/src/serialization/block/fixed_block.rs create mode 100644 rust/src/serialization/block/fixed_transaction_bodies.rs create mode 100644 rust/src/serialization/block/fixed_transaction_body.rs create mode 100644 rust/src/serialization/block/fixed_versioned_block.rs create mode 100644 rust/src/serialization/block/header.rs create mode 100644 rust/src/serialization/block/header_body.rs create mode 100644 rust/src/serialization/block/mod.rs create mode 100644 rust/src/serialization/block/operational_cert.rs create mode 100644 rust/src/serialization/block/transaction_bodies.rs rename rust/src/serialization/{ => block}/versioned_block.rs (100%) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 6e836ba1..a81cf5a3 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1121,33 +1121,6 @@ impl ProtocolVersion { } } -#[wasm_bindgen] -#[derive(Clone, Eq, Debug, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] -pub struct TransactionBodies(pub(crate) Vec); - -impl_to_from!(TransactionBodies); - -#[wasm_bindgen] -impl TransactionBodies { - pub fn new() -> Self { - Self(Vec::new()) - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get(&self, index: usize) -> TransactionBody { - self.0[index].clone() - } - - pub fn add(&mut self, elem: &TransactionBody) { - self.0.push(elem.clone()); - } -} - -pub type TransactionIndexes = Vec; - #[wasm_bindgen] #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] pub struct AuxiliaryDataSet(LinkedHashMap); @@ -1216,303 +1189,6 @@ impl JsonSchema for AuxiliaryDataSet { } } -#[wasm_bindgen] -#[derive(Clone, Eq, Debug, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] -pub struct Block { - header: Header, - transaction_bodies: TransactionBodies, - transaction_witness_sets: TransactionWitnessSets, - auxiliary_data_set: AuxiliaryDataSet, - invalid_transactions: TransactionIndexes, -} - -impl_to_from!(Block); - -#[wasm_bindgen] -impl Block { - pub fn header(&self) -> Header { - self.header.clone() - } - - pub fn transaction_bodies(&self) -> TransactionBodies { - self.transaction_bodies.clone() - } - - pub fn transaction_witness_sets(&self) -> TransactionWitnessSets { - self.transaction_witness_sets.clone() - } - - pub fn auxiliary_data_set(&self) -> AuxiliaryDataSet { - self.auxiliary_data_set.clone() - } - - pub fn invalid_transactions(&self) -> TransactionIndexes { - self.invalid_transactions.clone() - } - - pub fn new( - header: &Header, - transaction_bodies: &TransactionBodies, - transaction_witness_sets: &TransactionWitnessSets, - auxiliary_data_set: &AuxiliaryDataSet, - invalid_transactions: TransactionIndexes, - ) -> Self { - Self { - header: header.clone(), - transaction_bodies: transaction_bodies.clone(), - transaction_witness_sets: transaction_witness_sets.clone(), - auxiliary_data_set: auxiliary_data_set.clone(), - invalid_transactions: invalid_transactions, - } - } -} - -#[wasm_bindgen] -#[derive(Clone, Eq, Debug, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] -pub struct Header { - header_body: HeaderBody, - body_signature: KESSignature, -} - -impl_to_from!(Header); - -#[wasm_bindgen] -impl Header { - pub fn header_body(&self) -> HeaderBody { - self.header_body.clone() - } - - pub fn body_signature(&self) -> KESSignature { - self.body_signature.clone() - } - - pub fn new(header_body: &HeaderBody, body_signature: &KESSignature) -> Self { - Self { - header_body: header_body.clone(), - body_signature: body_signature.clone(), - } - } -} - -#[wasm_bindgen] -#[derive(Clone, Eq, PartialEq, Debug, serde::Serialize, serde::Deserialize, JsonSchema)] -pub struct OperationalCert { - hot_vkey: KESVKey, - sequence_number: u32, - kes_period: u32, - sigma: Ed25519Signature, -} - -impl_to_from!(OperationalCert); - -#[wasm_bindgen] -impl OperationalCert { - pub fn hot_vkey(&self) -> KESVKey { - self.hot_vkey.clone() - } - - pub fn sequence_number(&self) -> u32 { - self.sequence_number.clone() - } - - pub fn kes_period(&self) -> u32 { - self.kes_period.clone() - } - - pub fn sigma(&self) -> Ed25519Signature { - self.sigma.clone() - } - - pub fn new( - hot_vkey: &KESVKey, - sequence_number: u32, - kes_period: u32, - sigma: &Ed25519Signature, - ) -> Self { - Self { - hot_vkey: hot_vkey.clone(), - sequence_number: sequence_number, - kes_period: kes_period, - sigma: sigma.clone(), - } - } -} - -#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] -pub enum HeaderLeaderCertEnum { - NonceAndLeader(VRFCert, VRFCert), - VrfResult(VRFCert), -} - -#[wasm_bindgen] -#[derive(Clone, Eq, PartialEq, Debug, serde::Serialize, serde::Deserialize, JsonSchema)] -pub struct HeaderBody { - block_number: u32, - slot: SlotBigNum, - prev_hash: Option, - issuer_vkey: Vkey, - vrf_vkey: VRFVKey, - leader_cert: HeaderLeaderCertEnum, - block_body_size: u32, - block_body_hash: BlockHash, - operational_cert: OperationalCert, - protocol_version: ProtocolVersion, -} - -impl_to_from!(HeaderBody); - -#[wasm_bindgen] -impl HeaderBody { - pub fn block_number(&self) -> u32 { - self.block_number.clone() - } - - /// !!! DEPRECATED !!! - /// Returns a Slot32 (u32) value in case the underlying original BigNum (u64) value is within the limits. - /// Otherwise will just raise an error. - #[deprecated( - since = "10.1.0", - note = "Possible boundary error. Use slot_bignum instead" - )] - pub fn slot(&self) -> Result { - self.slot.clone().try_into() - } - - pub fn slot_bignum(&self) -> SlotBigNum { - self.slot.clone() - } - - pub fn prev_hash(&self) -> Option { - self.prev_hash.clone() - } - - pub fn issuer_vkey(&self) -> Vkey { - self.issuer_vkey.clone() - } - - pub fn vrf_vkey(&self) -> VRFVKey { - self.vrf_vkey.clone() - } - - /// If this function returns true, the `.nonce_vrf_or_nothing` - /// and the `.leader_vrf_or_nothing` functions will return - /// non-empty results - pub fn has_nonce_and_leader_vrf(&self) -> bool { - match &self.leader_cert { - HeaderLeaderCertEnum::NonceAndLeader(_, _) => true, - _ => false, - } - } - - /// Might return nothing in case `.has_nonce_and_leader_vrf` returns false - pub fn nonce_vrf_or_nothing(&self) -> Option { - match &self.leader_cert { - HeaderLeaderCertEnum::NonceAndLeader(nonce, _) => Some(nonce.clone()), - _ => None, - } - } - - /// Might return nothing in case `.has_nonce_and_leader_vrf` returns false - pub fn leader_vrf_or_nothing(&self) -> Option { - match &self.leader_cert { - HeaderLeaderCertEnum::NonceAndLeader(_, leader) => Some(leader.clone()), - _ => None, - } - } - - /// If this function returns true, the `.vrf_result_or_nothing` - /// function will return a non-empty result - pub fn has_vrf_result(&self) -> bool { - match &self.leader_cert { - HeaderLeaderCertEnum::VrfResult(_) => true, - _ => false, - } - } - - /// Might return nothing in case `.has_vrf_result` returns false - pub fn vrf_result_or_nothing(&self) -> Option { - match &self.leader_cert { - HeaderLeaderCertEnum::VrfResult(cert) => Some(cert.clone()), - _ => None, - } - } - - pub fn block_body_size(&self) -> u32 { - self.block_body_size.clone() - } - - pub fn block_body_hash(&self) -> BlockHash { - self.block_body_hash.clone() - } - - pub fn operational_cert(&self) -> OperationalCert { - self.operational_cert.clone() - } - - pub fn protocol_version(&self) -> ProtocolVersion { - self.protocol_version.clone() - } - - /// !!! DEPRECATED !!! - /// This constructor uses outdated slot number format. - /// Use `.new_headerbody` instead - #[deprecated( - since = "10.1.0", - note = "Underlying value capacity of slot (BigNum u64) bigger then Slot32. Use new_bignum instead." - )] - pub fn new( - block_number: u32, - slot: Slot32, - prev_hash: Option, - issuer_vkey: &Vkey, - vrf_vkey: &VRFVKey, - vrf_result: &VRFCert, - block_body_size: u32, - block_body_hash: &BlockHash, - operational_cert: &OperationalCert, - protocol_version: &ProtocolVersion, - ) -> Self { - Self { - block_number: block_number, - slot: slot.clone().into(), - prev_hash: prev_hash.clone(), - issuer_vkey: issuer_vkey.clone(), - vrf_vkey: vrf_vkey.clone(), - leader_cert: HeaderLeaderCertEnum::VrfResult(vrf_result.clone()), - block_body_size: block_body_size, - block_body_hash: block_body_hash.clone(), - operational_cert: operational_cert.clone(), - protocol_version: protocol_version.clone(), - } - } - - pub fn new_headerbody( - block_number: u32, - slot: &SlotBigNum, - prev_hash: Option, - issuer_vkey: &Vkey, - vrf_vkey: &VRFVKey, - vrf_result: &VRFCert, - block_body_size: u32, - block_body_hash: &BlockHash, - operational_cert: &OperationalCert, - protocol_version: &ProtocolVersion, - ) -> Self { - Self { - block_number: block_number, - slot: slot.clone(), - prev_hash: prev_hash.clone(), - issuer_vkey: issuer_vkey.clone(), - vrf_vkey: vrf_vkey.clone(), - leader_cert: HeaderLeaderCertEnum::VrfResult(vrf_result.clone()), - block_body_size: block_body_size, - block_body_hash: block_body_hash.clone(), - operational_cert: operational_cert.clone(), - protocol_version: protocol_version.clone(), - } - } -} - #[wasm_bindgen] #[derive(Clone, Debug, Eq, PartialEq, Hash)] pub struct AssetName(Vec); diff --git a/rust/src/protocol_types/block/block.rs b/rust/src/protocol_types/block/block.rs new file mode 100644 index 00000000..ff1d10fe --- /dev/null +++ b/rust/src/protocol_types/block/block.rs @@ -0,0 +1,54 @@ +use crate::*; + +pub type TransactionIndexes = Vec; + +#[wasm_bindgen] +#[derive(Clone, Eq, Debug, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] +pub struct Block { + pub(crate) header: Header, + pub(crate) transaction_bodies: TransactionBodies, + pub(crate) transaction_witness_sets: TransactionWitnessSets, + pub(crate) auxiliary_data_set: AuxiliaryDataSet, + pub(crate) invalid_transactions: TransactionIndexes, +} + +impl_to_from!(Block); + +#[wasm_bindgen] +impl Block { + pub fn header(&self) -> Header { + self.header.clone() + } + + pub fn transaction_bodies(&self) -> TransactionBodies { + self.transaction_bodies.clone() + } + + pub fn transaction_witness_sets(&self) -> TransactionWitnessSets { + self.transaction_witness_sets.clone() + } + + pub fn auxiliary_data_set(&self) -> AuxiliaryDataSet { + self.auxiliary_data_set.clone() + } + + pub fn invalid_transactions(&self) -> TransactionIndexes { + self.invalid_transactions.clone() + } + + pub fn new( + header: &Header, + transaction_bodies: &TransactionBodies, + transaction_witness_sets: &TransactionWitnessSets, + auxiliary_data_set: &AuxiliaryDataSet, + invalid_transactions: TransactionIndexes, + ) -> Self { + Self { + header: header.clone(), + transaction_bodies: transaction_bodies.clone(), + transaction_witness_sets: transaction_witness_sets.clone(), + auxiliary_data_set: auxiliary_data_set.clone(), + invalid_transactions: invalid_transactions, + } + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/block/fixed_block.rs b/rust/src/protocol_types/block/fixed_block.rs new file mode 100644 index 00000000..7b905ab0 --- /dev/null +++ b/rust/src/protocol_types/block/fixed_block.rs @@ -0,0 +1,43 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Eq, Debug, PartialEq)] +/// Read only view of a block with more strict structs for hash sensitive structs. +/// Warning: This is experimental and may be removed or changed in the future. +pub struct FixedBlock { + pub(crate) header: Header, + pub(crate) transaction_bodies: FixedTransactionBodies, + pub(crate) transaction_witness_sets: TransactionWitnessSets, + pub(crate) auxiliary_data_set: AuxiliaryDataSet, + pub(crate) invalid_transactions: TransactionIndexes, + pub(crate) block_hash: BlockHash, +} + +from_bytes!(FixedBlock); + +#[wasm_bindgen] +impl FixedBlock { + pub fn header(&self) -> Header { + self.header.clone() + } + + pub fn transaction_bodies(&self) -> FixedTransactionBodies { + self.transaction_bodies.clone() + } + + pub fn transaction_witness_sets(&self) -> TransactionWitnessSets { + self.transaction_witness_sets.clone() + } + + pub fn auxiliary_data_set(&self) -> AuxiliaryDataSet { + self.auxiliary_data_set.clone() + } + + pub fn invalid_transactions(&self) -> TransactionIndexes { + self.invalid_transactions.clone() + } + + pub fn block_hash(&self) -> BlockHash { + self.block_hash.clone() + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/block/fixed_transaction_bodies.rs b/rust/src/protocol_types/block/fixed_transaction_bodies.rs new file mode 100644 index 00000000..5a089280 --- /dev/null +++ b/rust/src/protocol_types/block/fixed_transaction_bodies.rs @@ -0,0 +1,27 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Eq, Debug, PartialEq)] +/// Warning: This is experimental and may be removed or changed in the future. +pub struct FixedTransactionBodies(pub(crate) Vec); + +from_bytes!(FixedTransactionBodies); + +#[wasm_bindgen] +impl FixedTransactionBodies { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> FixedTransactionBody { + self.0[index].clone() + } + + pub fn add(&mut self, elem: &FixedTransactionBody) { + self.0.push(elem.clone()); + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/block/fixed_tx_body.rs b/rust/src/protocol_types/block/fixed_tx_body.rs new file mode 100644 index 00000000..4496c0da --- /dev/null +++ b/rust/src/protocol_types/block/fixed_tx_body.rs @@ -0,0 +1,29 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Eq, Debug, PartialEq)] +/// Read-only view of a transaction body. With correct hash and original bytes. +/// Warning: This is experimental and may be removed in the future. +pub struct FixedTransactionBody { + pub(crate) body: TransactionBody, + pub(crate) tx_hash: TransactionHash, + pub(crate) original_bytes: Vec, +} + +from_bytes!(FixedTransactionBody); + +#[wasm_bindgen] +impl FixedTransactionBody { + + pub fn transaction_body(&self) -> TransactionBody { + self.body.clone() + } + + pub fn tx_hash(&self) -> TransactionHash { + self.tx_hash.clone() + } + + pub fn original_bytes(&self) -> Vec { + self.original_bytes.clone() + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/block/fixed_versioned_block.rs b/rust/src/protocol_types/block/fixed_versioned_block.rs new file mode 100644 index 00000000..540e3d1c --- /dev/null +++ b/rust/src/protocol_types/block/fixed_versioned_block.rs @@ -0,0 +1,32 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Eq, Debug, PartialEq)] +/// Warning: This is experimental and may be removed in the future. +pub struct FixedVersionedBlock { + pub(crate) block: FixedBlock, + pub(crate) era_code: u32, +} + +from_bytes!(FixedVersionedBlock); + +#[wasm_bindgen] +impl FixedVersionedBlock { + pub fn block(&self) -> FixedBlock { + self.block.clone() + } + + pub fn era(&self) -> BlockEra { + match self.era_code { + 0 => BlockEra::Byron, + 1 => BlockEra::Byron, + 2 => BlockEra::Shelley, + 3 => BlockEra::Allegra, + 4 => BlockEra::Mary, + 5 => BlockEra::Alonzo, + 6 => BlockEra::Babbage, + 7 => BlockEra::Conway, + _ => BlockEra::Unknown, + } + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/block/header.rs b/rust/src/protocol_types/block/header.rs new file mode 100644 index 00000000..3a382363 --- /dev/null +++ b/rust/src/protocol_types/block/header.rs @@ -0,0 +1,28 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Eq, Debug, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] +pub struct Header { + pub(crate) header_body: HeaderBody, + pub(crate) body_signature: KESSignature, +} + +impl_to_from!(Header); + +#[wasm_bindgen] +impl Header { + pub fn header_body(&self) -> HeaderBody { + self.header_body.clone() + } + + pub fn body_signature(&self) -> KESSignature { + self.body_signature.clone() + } + + pub fn new(header_body: &HeaderBody, body_signature: &KESSignature) -> Self { + Self { + header_body: header_body.clone(), + body_signature: body_signature.clone(), + } + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/block/header_body.rs b/rust/src/protocol_types/block/header_body.rs new file mode 100644 index 00000000..ae37f54e --- /dev/null +++ b/rust/src/protocol_types/block/header_body.rs @@ -0,0 +1,176 @@ +use crate::*; + +#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] +pub enum HeaderLeaderCertEnum { + NonceAndLeader(VRFCert, VRFCert), + VrfResult(VRFCert), +} + +#[wasm_bindgen] +#[derive(Clone, Eq, PartialEq, Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +pub struct HeaderBody { + pub(crate) block_number: u32, + pub(crate) slot: SlotBigNum, + pub(crate) prev_hash: Option, + pub(crate) issuer_vkey: Vkey, + pub(crate) vrf_vkey: VRFVKey, + pub(crate) leader_cert: HeaderLeaderCertEnum, + pub(crate) block_body_size: u32, + pub(crate) block_body_hash: BlockHash, + pub(crate) operational_cert: OperationalCert, + pub(crate) protocol_version: ProtocolVersion, +} + +impl_to_from!(HeaderBody); + +#[wasm_bindgen] +impl HeaderBody { + pub fn block_number(&self) -> u32 { + self.block_number.clone() + } + + /// !!! DEPRECATED !!! + /// Returns a Slot32 (u32) value in case the underlying original BigNum (u64) value is within the limits. + /// Otherwise will just raise an error. + #[deprecated( + since = "10.1.0", + note = "Possible boundary error. Use slot_bignum instead" + )] + pub fn slot(&self) -> Result { + self.slot.clone().try_into() + } + + pub fn slot_bignum(&self) -> SlotBigNum { + self.slot.clone() + } + + pub fn prev_hash(&self) -> Option { + self.prev_hash.clone() + } + + pub fn issuer_vkey(&self) -> Vkey { + self.issuer_vkey.clone() + } + + pub fn vrf_vkey(&self) -> VRFVKey { + self.vrf_vkey.clone() + } + + /// If this function returns true, the `.nonce_vrf_or_nothing` + /// and the `.leader_vrf_or_nothing` functions will return + /// non-empty results + pub fn has_nonce_and_leader_vrf(&self) -> bool { + match &self.leader_cert { + HeaderLeaderCertEnum::NonceAndLeader(_, _) => true, + _ => false, + } + } + + /// Might return nothing in case `.has_nonce_and_leader_vrf` returns false + pub fn nonce_vrf_or_nothing(&self) -> Option { + match &self.leader_cert { + HeaderLeaderCertEnum::NonceAndLeader(nonce, _) => Some(nonce.clone()), + _ => None, + } + } + + /// Might return nothing in case `.has_nonce_and_leader_vrf` returns false + pub fn leader_vrf_or_nothing(&self) -> Option { + match &self.leader_cert { + HeaderLeaderCertEnum::NonceAndLeader(_, leader) => Some(leader.clone()), + _ => None, + } + } + + /// If this function returns true, the `.vrf_result_or_nothing` + /// function will return a non-empty result + pub fn has_vrf_result(&self) -> bool { + match &self.leader_cert { + HeaderLeaderCertEnum::VrfResult(_) => true, + _ => false, + } + } + + /// Might return nothing in case `.has_vrf_result` returns false + pub fn vrf_result_or_nothing(&self) -> Option { + match &self.leader_cert { + HeaderLeaderCertEnum::VrfResult(cert) => Some(cert.clone()), + _ => None, + } + } + + pub fn block_body_size(&self) -> u32 { + self.block_body_size.clone() + } + + pub fn block_body_hash(&self) -> BlockHash { + self.block_body_hash.clone() + } + + pub fn operational_cert(&self) -> OperationalCert { + self.operational_cert.clone() + } + + pub fn protocol_version(&self) -> ProtocolVersion { + self.protocol_version.clone() + } + + /// !!! DEPRECATED !!! + /// This constructor uses outdated slot number format. + /// Use `.new_headerbody` instead + #[deprecated( + since = "10.1.0", + note = "Underlying value capacity of slot (BigNum u64) bigger then Slot32. Use new_bignum instead." + )] + pub fn new( + block_number: u32, + slot: Slot32, + prev_hash: Option, + issuer_vkey: &Vkey, + vrf_vkey: &VRFVKey, + vrf_result: &VRFCert, + block_body_size: u32, + block_body_hash: &BlockHash, + operational_cert: &OperationalCert, + protocol_version: &ProtocolVersion, + ) -> Self { + Self { + block_number: block_number, + slot: slot.clone().into(), + prev_hash: prev_hash.clone(), + issuer_vkey: issuer_vkey.clone(), + vrf_vkey: vrf_vkey.clone(), + leader_cert: HeaderLeaderCertEnum::VrfResult(vrf_result.clone()), + block_body_size: block_body_size, + block_body_hash: block_body_hash.clone(), + operational_cert: operational_cert.clone(), + protocol_version: protocol_version.clone(), + } + } + + pub fn new_headerbody( + block_number: u32, + slot: &SlotBigNum, + prev_hash: Option, + issuer_vkey: &Vkey, + vrf_vkey: &VRFVKey, + vrf_result: &VRFCert, + block_body_size: u32, + block_body_hash: &BlockHash, + operational_cert: &OperationalCert, + protocol_version: &ProtocolVersion, + ) -> Self { + Self { + block_number: block_number, + slot: slot.clone(), + prev_hash: prev_hash.clone(), + issuer_vkey: issuer_vkey.clone(), + vrf_vkey: vrf_vkey.clone(), + leader_cert: HeaderLeaderCertEnum::VrfResult(vrf_result.clone()), + block_body_size: block_body_size, + block_body_hash: block_body_hash.clone(), + operational_cert: operational_cert.clone(), + protocol_version: protocol_version.clone(), + } + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/block/mod.rs b/rust/src/protocol_types/block/mod.rs new file mode 100644 index 00000000..1e50c4c3 --- /dev/null +++ b/rust/src/protocol_types/block/mod.rs @@ -0,0 +1,29 @@ +mod block; +pub use block::*; + +mod fixed_block; +pub use fixed_block::*; + +mod fixed_tx_body; +pub use fixed_tx_body::*; + +mod header; +pub use header::*; + +mod transaction_bodies; +pub use transaction_bodies::*; + +mod header_body; +pub use header_body::*; + +mod operational_cert; +pub use operational_cert::*; + +mod fixed_versioned_block; +pub use fixed_versioned_block::*; + +mod fixed_transaction_bodies; +pub use fixed_transaction_bodies::*; + +mod versioned_block; +pub use versioned_block::*; \ No newline at end of file diff --git a/rust/src/protocol_types/block/operational_cert.rs b/rust/src/protocol_types/block/operational_cert.rs new file mode 100644 index 00000000..28e5e7a7 --- /dev/null +++ b/rust/src/protocol_types/block/operational_cert.rs @@ -0,0 +1,45 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Eq, PartialEq, Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +pub struct OperationalCert { + pub(crate) hot_vkey: KESVKey, + pub(crate) sequence_number: u32, + pub(crate) kes_period: u32, + pub(crate) sigma: Ed25519Signature, +} + +impl_to_from!(OperationalCert); + +#[wasm_bindgen] +impl OperationalCert { + pub fn hot_vkey(&self) -> KESVKey { + self.hot_vkey.clone() + } + + pub fn sequence_number(&self) -> u32 { + self.sequence_number.clone() + } + + pub fn kes_period(&self) -> u32 { + self.kes_period.clone() + } + + pub fn sigma(&self) -> Ed25519Signature { + self.sigma.clone() + } + + pub fn new( + hot_vkey: &KESVKey, + sequence_number: u32, + kes_period: u32, + sigma: &Ed25519Signature, + ) -> Self { + Self { + hot_vkey: hot_vkey.clone(), + sequence_number: sequence_number, + kes_period: kes_period, + sigma: sigma.clone(), + } + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/block/transaction_bodies.rs b/rust/src/protocol_types/block/transaction_bodies.rs new file mode 100644 index 00000000..8e9493ce --- /dev/null +++ b/rust/src/protocol_types/block/transaction_bodies.rs @@ -0,0 +1,26 @@ +use crate::*; + +#[wasm_bindgen] +#[derive(Clone, Eq, Debug, PartialEq, serde::Serialize, serde::Deserialize, JsonSchema)] +pub struct TransactionBodies(pub(crate) Vec); + +impl_to_from!(TransactionBodies); + +#[wasm_bindgen] +impl TransactionBodies { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, index: usize) -> TransactionBody { + self.0[index].clone() + } + + pub fn add(&mut self, elem: &TransactionBody) { + self.0.push(elem.clone()); + } +} \ No newline at end of file diff --git a/rust/src/protocol_types/versioned_block.rs b/rust/src/protocol_types/block/versioned_block.rs similarity index 100% rename from rust/src/protocol_types/versioned_block.rs rename to rust/src/protocol_types/block/versioned_block.rs diff --git a/rust/src/protocol_types/mod.rs b/rust/src/protocol_types/mod.rs index d0cb0d34..3a0642ce 100644 --- a/rust/src/protocol_types/mod.rs +++ b/rust/src/protocol_types/mod.rs @@ -53,8 +53,8 @@ pub use native_scripts::*; mod numeric; pub use numeric::*; -mod versioned_block; -pub use versioned_block::*; - mod script_ref; pub use script_ref::*; + +mod block; +pub use block::*; diff --git a/rust/src/serialization/block/block.rs b/rust/src/serialization/block/block.rs new file mode 100644 index 00000000..43d656ff --- /dev/null +++ b/rust/src/serialization/block/block.rs @@ -0,0 +1,80 @@ +use crate::*; +use crate::serialization::utils::is_break_tag; + +impl cbor_event::se::Serialize for Block { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(5))?; + self.header.serialize(serializer)?; + self.transaction_bodies.serialize(serializer)?; + self.transaction_witness_sets.serialize(serializer)?; + self.auxiliary_data_set.serialize(serializer)?; + serializer.write_array(cbor_event::Len::Len(self.invalid_transactions.len() as u64))?; + for element in self.invalid_transactions.iter() { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for Block { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(4)?; + let header = (|| -> Result<_, DeserializeError> { Ok(Header::deserialize(raw)?) })() + .map_err(|e| e.annotate("header"))?; + let transaction_bodies = + (|| -> Result<_, DeserializeError> { Ok(TransactionBodies::deserialize(raw)?) })() + .map_err(|e| e.annotate("transaction_bodies"))?; + let transaction_witness_sets = (|| -> Result<_, DeserializeError> { + Ok(TransactionWitnessSets::deserialize(raw)?) + })() + .map_err(|e| e.annotate("transaction_witness_sets"))?; + let auxiliary_data_set = + (|| -> Result<_, DeserializeError> { Ok(AuxiliaryDataSet::deserialize(raw)?) })() + .map_err(|e| e.annotate("auxiliary_data_set"))?; + let invalid_present = match len { + cbor_event::Len::Indefinite => raw.cbor_type()? == CBORType::Array, + cbor_event::Len::Len(4) => false, + _ => true, + }; + let invalid_transactions = (|| -> Result<_, DeserializeError> { + let mut arr = Vec::new(); + if invalid_present { + read_len.read_elems(1)?; + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if is_break_tag(raw, "Block.invalid_transactions")? { + break; + } + arr.push(TransactionIndex::deserialize(raw)?); + } + } + Ok(arr) + })() + .map_err(|e| e.annotate("invalid_transactions"))?; + match len { + cbor_event::Len::Len(_) => (), + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => (), + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + Ok(Block { + header, + transaction_bodies, + transaction_witness_sets, + auxiliary_data_set, + invalid_transactions, + }) + })() + .map_err(|e| e.annotate("Block")) + } +} diff --git a/rust/src/serialization/block/fixed_block.rs b/rust/src/serialization/block/fixed_block.rs new file mode 100644 index 00000000..b8fd7f3f --- /dev/null +++ b/rust/src/serialization/block/fixed_block.rs @@ -0,0 +1,83 @@ +use crate::serialization::utils::{deserilized_with_orig_bytes, is_break_tag}; +use crate::*; + +impl Deserialize for FixedBlock { + fn deserialize(raw: &mut Deserializer) -> Result { + let (( + header, + transaction_bodies, + transaction_witness_sets, + auxiliary_data_set, + invalid_transactions, + ), orig_bytes) = deserilized_with_orig_bytes(raw, |raw| -> Result<_, DeserializeError> { + deserialize_block(raw) + }).map_err(|e| e.annotate("Block"))?; + let block_hash = BlockHash(blake2b256(orig_bytes.as_ref())); + Ok(FixedBlock { + header, + transaction_bodies, + transaction_witness_sets, + auxiliary_data_set, + invalid_transactions, + block_hash, + }) + } +} + +fn deserialize_block( + raw: &mut Deserializer, +) -> Result<(Header, FixedTransactionBodies, TransactionWitnessSets, AuxiliaryDataSet, TransactionIndexes), DeserializeError> { + let len = raw.array()?; + let mut read_len = CBORReadLen::new(len); + read_len.read_elems(4)?; + let header = (|| -> Result<_, DeserializeError> { Ok(Header::deserialize(raw)?) })() + .map_err(|e| e.annotate("header"))?; + let transaction_bodies = (|| -> Result<_, DeserializeError> { + Ok(FixedTransactionBodies::deserialize(raw)?) + })() + .map_err(|e| e.annotate("fixed_transaction_bodies"))?; + let transaction_witness_sets = (|| -> Result<_, DeserializeError> { + Ok(TransactionWitnessSets::deserialize(raw)?) + })() + .map_err(|e| e.annotate("transaction_witness_sets"))?; + let auxiliary_data_set = + (|| -> Result<_, DeserializeError> { Ok(AuxiliaryDataSet::deserialize(raw)?) })() + .map_err(|e| e.annotate("auxiliary_data_set"))?; + let invalid_present = match len { + Len::Indefinite => raw.cbor_type()? == CBORType::Array, + Len::Len(4) => false, + _ => true, + }; + let invalid_transactions = (|| -> Result<_, DeserializeError> { + let mut arr = Vec::new(); + if invalid_present { + read_len.read_elems(1)?; + let len = raw.array()?; + while match len { + Len::Len(n) => arr.len() < n as usize, + Len::Indefinite => true, + } { + if is_break_tag(raw, "Block.invalid_transactions")? { + break; + } + arr.push(TransactionIndex::deserialize(raw)?); + } + } + Ok(arr) + })() + .map_err(|e| e.annotate("invalid_transactions"))?; + match len { + Len::Len(_) => (), + Len::Indefinite => match raw.special()? { + CBORSpecial::Break => (), + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + Ok(( + header, + transaction_bodies, + transaction_witness_sets, + auxiliary_data_set, + invalid_transactions, + )) +} diff --git a/rust/src/serialization/block/fixed_transaction_bodies.rs b/rust/src/serialization/block/fixed_transaction_bodies.rs new file mode 100644 index 00000000..ed8c1281 --- /dev/null +++ b/rust/src/serialization/block/fixed_transaction_bodies.rs @@ -0,0 +1,23 @@ +use crate::*; +use crate::serialization::utils::is_break_tag; + +impl Deserialize for FixedTransactionBodies { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if is_break_tag(raw, "FixedTransactionBodies")? { + break; + } + arr.push(FixedTransactionBody::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("FixedTransactionBodies"))?; + Ok(Self(arr)) + } +} diff --git a/rust/src/serialization/block/fixed_transaction_body.rs b/rust/src/serialization/block/fixed_transaction_body.rs new file mode 100644 index 00000000..9c999215 --- /dev/null +++ b/rust/src/serialization/block/fixed_transaction_body.rs @@ -0,0 +1,17 @@ +use crate::*; +use crate::serialization::utils::{deserilized_with_orig_bytes}; + +impl Deserialize for FixedTransactionBody { + fn deserialize(raw: &mut Deserializer) -> Result { + let (body, orig_bytes) = deserilized_with_orig_bytes(raw, |raw| -> Result<_, DeserializeError> { + let body = TransactionBody::deserialize(raw)?; + Ok(body) + }).map_err(|e| e.annotate("TransactionBody"))?; + let hash = TransactionHash(blake2b256(orig_bytes.as_ref())); + Ok(FixedTransactionBody { + body, + tx_hash: hash, + original_bytes: orig_bytes, + }) + } +} diff --git a/rust/src/serialization/block/fixed_versioned_block.rs b/rust/src/serialization/block/fixed_versioned_block.rs new file mode 100644 index 00000000..eb2a085c --- /dev/null +++ b/rust/src/serialization/block/fixed_versioned_block.rs @@ -0,0 +1,16 @@ +use crate::serialization::utils::{check_len, check_len_indefinite}; +use crate::*; + +impl Deserialize for FixedVersionedBlock { + fn deserialize(raw: &mut Deserializer) -> Result { + let len = raw.array()?; + check_len(len, 2, "VersionedBlock")?; + let era_code = u32::deserialize(raw)?; + let block = FixedBlock::deserialize(raw)?; + check_len_indefinite(raw, len)?; + Ok(FixedVersionedBlock { + block, + era_code, + }) + } +} diff --git a/rust/src/serialization/block/header.rs b/rust/src/serialization/block/header.rs new file mode 100644 index 00000000..c1a5da13 --- /dev/null +++ b/rust/src/serialization/block/header.rs @@ -0,0 +1,57 @@ +use crate::*; + +impl cbor_event::se::Serialize for Header { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(2))?; + self.header_body.serialize(serializer)?; + self.body_signature.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for Header { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let ret = Self::deserialize_as_embedded_group(raw, len); + match len { + cbor_event::Len::Len(_) => + /* TODO: check finite len somewhere */ + { + () + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("Header")) + } +} + +impl DeserializeEmbeddedGroup for Header { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + _: cbor_event::Len, + ) -> Result { + let header_body = + (|| -> Result<_, DeserializeError> { Ok(HeaderBody::deserialize(raw)?) })() + .map_err(|e| e.annotate("header_body"))?; + let body_signature = + (|| -> Result<_, DeserializeError> { Ok(KESSignature::deserialize(raw)?) })() + .map_err(|e| e.annotate("body_signature"))?; + Ok(Header { + header_body, + body_signature, + }) + } +} \ No newline at end of file diff --git a/rust/src/serialization/block/header_body.rs b/rust/src/serialization/block/header_body.rs new file mode 100644 index 00000000..6627e23c --- /dev/null +++ b/rust/src/serialization/block/header_body.rs @@ -0,0 +1,150 @@ +use crate::*; + +impl cbor_event::se::Serialize for HeaderBody { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(15))?; + self.block_number.serialize(serializer)?; + self.slot.serialize(serializer)?; + match &self.prev_hash { + Some(x) => x.serialize(serializer), + None => serializer.write_special(CBORSpecial::Null), + }?; + self.issuer_vkey.serialize(serializer)?; + self.vrf_vkey.serialize(serializer)?; + match &self.leader_cert { + HeaderLeaderCertEnum::NonceAndLeader(nonce_vrf, leader_vrf) => { + nonce_vrf.serialize(serializer)?; + leader_vrf.serialize(serializer)?; + } + HeaderLeaderCertEnum::VrfResult(vrf_cert) => { + vrf_cert.serialize(serializer)?; + } + } + self.block_body_size.serialize(serializer)?; + self.block_body_hash.serialize(serializer)?; + self.operational_cert + .serialize_as_embedded_group(serializer)?; + self.protocol_version + .serialize_as_embedded_group(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for HeaderBody { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let ret = Self::deserialize_as_embedded_group(raw, len); + match len { + cbor_event::Len::Len(_) => + /* TODO: check finite len somewhere */ + { + () + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("HeaderBody")) + } +} + +impl DeserializeEmbeddedGroup for HeaderBody { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + len: cbor_event::Len, + ) -> Result { + let block_number = (|| -> Result<_, DeserializeError> { Ok(u32::deserialize(raw)?) })() + .map_err(|e| e.annotate("block_number"))?; + let slot = (|| -> Result<_, DeserializeError> { Ok(SlotBigNum::deserialize(raw)?) })() + .map_err(|e| e.annotate("slot"))?; + let prev_hash = (|| -> Result<_, DeserializeError> { + Ok(match raw.cbor_type()? != CBORType::Special { + true => Some(BlockHash::deserialize(raw)?), + false => { + if raw.special()? != CBORSpecial::Null { + return Err(DeserializeFailure::ExpectedNull.into()); + } + None + } + }) + })() + .map_err(|e| e.annotate("prev_hash"))?; + let issuer_vkey = (|| -> Result<_, DeserializeError> { Ok(Vkey::deserialize(raw)?) })() + .map_err(|e| e.annotate("issuer_vkey"))?; + let vrf_vkey = (|| -> Result<_, DeserializeError> { Ok(VRFVKey::deserialize(raw)?) })() + .map_err(|e| e.annotate("vrf_vkey"))?; + let leader_cert = { + // NONCE VFR CERT, first of two certs + // or a single VRF RESULT CERT + // depending on the protocol version + let first_vrf_cert = + (|| -> Result<_, DeserializeError> { Ok(VRFCert::deserialize(raw)?) })() + .map_err(|e| e.annotate("nonce_vrf"))?; + let cbor_type: cbor_event::Type = raw.cbor_type()?; + match cbor_type { + cbor_event::Type::Array => { + // Legacy format, reading the second VRF cert + let leader_vrf = + (|| -> Result<_, DeserializeError> { Ok(VRFCert::deserialize(raw)?) })() + .map_err(|e| e.annotate("leader_vrf"))?; + HeaderLeaderCertEnum::NonceAndLeader(first_vrf_cert, leader_vrf) + } + cbor_event::Type::UnsignedInteger => { + // New format, no second VRF cert is present + HeaderLeaderCertEnum::VrfResult(first_vrf_cert) + } + t => { + return Err(DeserializeError::new( + "HeaderBody.leader_cert", + DeserializeFailure::UnexpectedKeyType(t), + )) + } + } + }; + let block_body_size = (|| -> Result<_, DeserializeError> { Ok(u32::deserialize(raw)?) })() + .map_err(|e| e.annotate("block_body_size"))?; + let block_body_hash = + (|| -> Result<_, DeserializeError> { Ok(BlockHash::deserialize(raw)?) })() + .map_err(|e| e.annotate("block_body_hash"))?; + + let operational_cert = (|| -> Result<_, DeserializeError> { + if raw.cbor_type()? == CBORType::Array { + Ok(OperationalCert::deserialize(raw)?) + } else { + Ok(OperationalCert::deserialize_as_embedded_group(raw, len)?) + } + })() + .map_err(|e| e.annotate("operational_cert"))?; + let protocol_version = (|| -> Result<_, DeserializeError> { + if raw.cbor_type()? == CBORType::Array { + Ok(ProtocolVersion::deserialize(raw)?) + } else { + Ok(ProtocolVersion::deserialize_as_embedded_group(raw, len)?) + } + })() + .map_err(|e| e.annotate("protocol_version"))?; + Ok(HeaderBody { + block_number, + slot, + prev_hash, + issuer_vkey, + vrf_vkey, + leader_cert, + block_body_size, + block_body_hash, + operational_cert, + protocol_version, + }) + } +} \ No newline at end of file diff --git a/rust/src/serialization/block/mod.rs b/rust/src/serialization/block/mod.rs new file mode 100644 index 00000000..54be5d37 --- /dev/null +++ b/rust/src/serialization/block/mod.rs @@ -0,0 +1,10 @@ +mod block; +mod header; +mod operational_cert; +mod header_body; +mod transaction_bodies; +mod fixed_block; +mod fixed_transaction_body; +mod fixed_transaction_bodies; +mod versioned_block; +mod fixed_versioned_block; diff --git a/rust/src/serialization/block/operational_cert.rs b/rust/src/serialization/block/operational_cert.rs new file mode 100644 index 00000000..1b6490ed --- /dev/null +++ b/rust/src/serialization/block/operational_cert.rs @@ -0,0 +1,73 @@ +use crate::*; + +impl cbor_event::se::Serialize for OperationalCert { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(4))?; + self.serialize_as_embedded_group(serializer) + } +} + +impl SerializeEmbeddedGroup for OperationalCert { + fn serialize_as_embedded_group<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + self.hot_vkey.serialize(serializer)?; + self.sequence_number.serialize(serializer)?; + self.kes_period.serialize(serializer)?; + self.sigma.serialize(serializer)?; + Ok(serializer) + } +} + +impl Deserialize for OperationalCert { + fn deserialize(raw: &mut Deserializer) -> Result { + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + let ret = Self::deserialize_as_embedded_group(raw, len); + match len { + cbor_event::Len::Len(_) => + /* TODO: check finite len somewhere */ + { + () + } + cbor_event::Len::Indefinite => match raw.special()? { + CBORSpecial::Break => + /* it's ok */ + { + () + } + _ => return Err(DeserializeFailure::EndingBreakMissing.into()), + }, + } + ret + })() + .map_err(|e| e.annotate("OperationalCert")) + } +} + +impl DeserializeEmbeddedGroup for OperationalCert { + fn deserialize_as_embedded_group( + raw: &mut Deserializer, + _: cbor_event::Len, + ) -> Result { + let hot_vkey = (|| -> Result<_, DeserializeError> { Ok(KESVKey::deserialize(raw)?) })() + .map_err(|e| e.annotate("hot_vkey"))?; + let sequence_number = (|| -> Result<_, DeserializeError> { Ok(u32::deserialize(raw)?) })() + .map_err(|e| e.annotate("sequence_number"))?; + let kes_period = (|| -> Result<_, DeserializeError> { Ok(u32::deserialize(raw)?) })() + .map_err(|e| e.annotate("kes_period"))?; + let sigma = + (|| -> Result<_, DeserializeError> { Ok(Ed25519Signature::deserialize(raw)?) })() + .map_err(|e| e.annotate("sigma"))?; + Ok(OperationalCert { + hot_vkey, + sequence_number, + kes_period, + sigma, + }) + } +} \ No newline at end of file diff --git a/rust/src/serialization/block/transaction_bodies.rs b/rust/src/serialization/block/transaction_bodies.rs new file mode 100644 index 00000000..eafe1400 --- /dev/null +++ b/rust/src/serialization/block/transaction_bodies.rs @@ -0,0 +1,36 @@ +use crate::*; +use crate::serialization::utils::is_break_tag; + +impl cbor_event::se::Serialize for TransactionBodies { + fn serialize<'se, W: Write>( + &self, + serializer: &'se mut Serializer, + ) -> cbor_event::Result<&'se mut Serializer> { + serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; + for element in &self.0 { + element.serialize(serializer)?; + } + Ok(serializer) + } +} + +impl Deserialize for TransactionBodies { + fn deserialize(raw: &mut Deserializer) -> Result { + let mut arr = Vec::new(); + (|| -> Result<_, DeserializeError> { + let len = raw.array()?; + while match len { + cbor_event::Len::Len(n) => arr.len() < n as usize, + cbor_event::Len::Indefinite => true, + } { + if is_break_tag(raw, "TransactionBodies")? { + break; + } + arr.push(TransactionBody::deserialize(raw)?); + } + Ok(()) + })() + .map_err(|e| e.annotate("TransactionBodies"))?; + Ok(Self(arr)) + } +} diff --git a/rust/src/serialization/versioned_block.rs b/rust/src/serialization/block/versioned_block.rs similarity index 100% rename from rust/src/serialization/versioned_block.rs rename to rust/src/serialization/block/versioned_block.rs diff --git a/rust/src/serialization/fixed_tx.rs b/rust/src/serialization/fixed_tx.rs index c52fd4a1..c4b5f58c 100644 --- a/rust/src/serialization/fixed_tx.rs +++ b/rust/src/serialization/fixed_tx.rs @@ -1,5 +1,5 @@ use crate::*; -use std::io::SeekFrom; +use crate::serialization::utils::deserilized_with_orig_bytes; impl cbor_event::se::Serialize for FixedTransaction { fn serialize<'se, W: Write>( @@ -117,17 +117,3 @@ impl DeserializeEmbeddedGroup for FixedTransaction { }) } } - -fn deserilized_with_orig_bytes( - raw: &mut Deserializer, - deserilizator: fn(&mut Deserializer) -> Result, -) -> Result<(T, Vec), DeserializeError> { - let before = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); - let value = deserilizator(raw)?; - let after = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); - let bytes_read = (after - before) as usize; - raw.as_mut_ref().seek(SeekFrom::Start(before)).unwrap(); - let original_bytes = raw.as_mut_ref().fill_buf().unwrap()[..bytes_read].to_vec(); - raw.as_mut_ref().seek(SeekFrom::Start(after)).unwrap(); - Ok((value, original_bytes)) -} diff --git a/rust/src/serialization/general.rs b/rust/src/serialization/general.rs index bad8a40b..03d4c70a 100644 --- a/rust/src/serialization/general.rs +++ b/rust/src/serialization/general.rs @@ -1300,40 +1300,6 @@ impl DeserializeEmbeddedGroup for ProtocolVersion { } } -impl cbor_event::se::Serialize for TransactionBodies { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?; - for element in &self.0 { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for TransactionBodies { - fn deserialize(raw: &mut Deserializer) -> Result { - let mut arr = Vec::new(); - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if is_break_tag(raw, "TransactionBodies")? { - break; - } - arr.push(TransactionBody::deserialize(raw)?); - } - Ok(()) - })() - .map_err(|e| e.annotate("TransactionBodies"))?; - Ok(Self(arr)) - } -} - impl cbor_event::se::Serialize for AuxiliaryDataSet { fn serialize<'se, W: Write>( &self, @@ -1376,361 +1342,6 @@ impl Deserialize for AuxiliaryDataSet { } } -impl cbor_event::se::Serialize for Block { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(5))?; - self.header.serialize(serializer)?; - self.transaction_bodies.serialize(serializer)?; - self.transaction_witness_sets.serialize(serializer)?; - self.auxiliary_data_set.serialize(serializer)?; - serializer.write_array(cbor_event::Len::Len(self.invalid_transactions.len() as u64))?; - for element in self.invalid_transactions.iter() { - element.serialize(serializer)?; - } - Ok(serializer) - } -} - -impl Deserialize for Block { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let mut read_len = CBORReadLen::new(len); - read_len.read_elems(4)?; - let header = (|| -> Result<_, DeserializeError> { Ok(Header::deserialize(raw)?) })() - .map_err(|e| e.annotate("header"))?; - let transaction_bodies = - (|| -> Result<_, DeserializeError> { Ok(TransactionBodies::deserialize(raw)?) })() - .map_err(|e| e.annotate("transaction_bodies"))?; - let transaction_witness_sets = (|| -> Result<_, DeserializeError> { - Ok(TransactionWitnessSets::deserialize(raw)?) - })() - .map_err(|e| e.annotate("transaction_witness_sets"))?; - let auxiliary_data_set = - (|| -> Result<_, DeserializeError> { Ok(AuxiliaryDataSet::deserialize(raw)?) })() - .map_err(|e| e.annotate("auxiliary_data_set"))?; - let invalid_present = match len { - cbor_event::Len::Indefinite => raw.cbor_type()? == CBORType::Array, - cbor_event::Len::Len(4) => false, - _ => true, - }; - let invalid_transactions = (|| -> Result<_, DeserializeError> { - let mut arr = Vec::new(); - if invalid_present { - read_len.read_elems(1)?; - let len = raw.array()?; - while match len { - cbor_event::Len::Len(n) => arr.len() < n as usize, - cbor_event::Len::Indefinite => true, - } { - if is_break_tag(raw, "Block.invalid_transactions")? { - break; - } - arr.push(TransactionIndex::deserialize(raw)?); - } - } - Ok(arr) - })() - .map_err(|e| e.annotate("invalid_transactions"))?; - match len { - cbor_event::Len::Len(_) => (), - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => (), - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - Ok(Block { - header, - transaction_bodies, - transaction_witness_sets, - auxiliary_data_set, - invalid_transactions, - }) - })() - .map_err(|e| e.annotate("Block")) - } -} - -impl cbor_event::se::Serialize for Header { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(2))?; - self.header_body.serialize(serializer)?; - self.body_signature.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for Header { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("Header")) - } -} - -impl DeserializeEmbeddedGroup for Header { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - _: cbor_event::Len, - ) -> Result { - let header_body = - (|| -> Result<_, DeserializeError> { Ok(HeaderBody::deserialize(raw)?) })() - .map_err(|e| e.annotate("header_body"))?; - let body_signature = - (|| -> Result<_, DeserializeError> { Ok(KESSignature::deserialize(raw)?) })() - .map_err(|e| e.annotate("body_signature"))?; - Ok(Header { - header_body, - body_signature, - }) - } -} - -impl cbor_event::se::Serialize for OperationalCert { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(4))?; - self.serialize_as_embedded_group(serializer) - } -} - -impl SerializeEmbeddedGroup for OperationalCert { - fn serialize_as_embedded_group<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - self.hot_vkey.serialize(serializer)?; - self.sequence_number.serialize(serializer)?; - self.kes_period.serialize(serializer)?; - self.sigma.serialize(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for OperationalCert { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("OperationalCert")) - } -} - -impl DeserializeEmbeddedGroup for OperationalCert { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - _: cbor_event::Len, - ) -> Result { - let hot_vkey = (|| -> Result<_, DeserializeError> { Ok(KESVKey::deserialize(raw)?) })() - .map_err(|e| e.annotate("hot_vkey"))?; - let sequence_number = (|| -> Result<_, DeserializeError> { Ok(u32::deserialize(raw)?) })() - .map_err(|e| e.annotate("sequence_number"))?; - let kes_period = (|| -> Result<_, DeserializeError> { Ok(u32::deserialize(raw)?) })() - .map_err(|e| e.annotate("kes_period"))?; - let sigma = - (|| -> Result<_, DeserializeError> { Ok(Ed25519Signature::deserialize(raw)?) })() - .map_err(|e| e.annotate("sigma"))?; - Ok(OperationalCert { - hot_vkey, - sequence_number, - kes_period, - sigma, - }) - } -} - -impl cbor_event::se::Serialize for HeaderBody { - fn serialize<'se, W: Write>( - &self, - serializer: &'se mut Serializer, - ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_array(cbor_event::Len::Len(15))?; - self.block_number.serialize(serializer)?; - self.slot.serialize(serializer)?; - match &self.prev_hash { - Some(x) => x.serialize(serializer), - None => serializer.write_special(CBORSpecial::Null), - }?; - self.issuer_vkey.serialize(serializer)?; - self.vrf_vkey.serialize(serializer)?; - match &self.leader_cert { - HeaderLeaderCertEnum::NonceAndLeader(nonce_vrf, leader_vrf) => { - nonce_vrf.serialize(serializer)?; - leader_vrf.serialize(serializer)?; - } - HeaderLeaderCertEnum::VrfResult(vrf_cert) => { - vrf_cert.serialize(serializer)?; - } - } - self.block_body_size.serialize(serializer)?; - self.block_body_hash.serialize(serializer)?; - self.operational_cert - .serialize_as_embedded_group(serializer)?; - self.protocol_version - .serialize_as_embedded_group(serializer)?; - Ok(serializer) - } -} - -impl Deserialize for HeaderBody { - fn deserialize(raw: &mut Deserializer) -> Result { - (|| -> Result<_, DeserializeError> { - let len = raw.array()?; - let ret = Self::deserialize_as_embedded_group(raw, len); - match len { - cbor_event::Len::Len(_) => - /* TODO: check finite len somewhere */ - { - () - } - cbor_event::Len::Indefinite => match raw.special()? { - CBORSpecial::Break => - /* it's ok */ - { - () - } - _ => return Err(DeserializeFailure::EndingBreakMissing.into()), - }, - } - ret - })() - .map_err(|e| e.annotate("HeaderBody")) - } -} - -impl DeserializeEmbeddedGroup for HeaderBody { - fn deserialize_as_embedded_group( - raw: &mut Deserializer, - len: cbor_event::Len, - ) -> Result { - let block_number = (|| -> Result<_, DeserializeError> { Ok(u32::deserialize(raw)?) })() - .map_err(|e| e.annotate("block_number"))?; - let slot = (|| -> Result<_, DeserializeError> { Ok(SlotBigNum::deserialize(raw)?) })() - .map_err(|e| e.annotate("slot"))?; - let prev_hash = (|| -> Result<_, DeserializeError> { - Ok(match raw.cbor_type()? != CBORType::Special { - true => Some(BlockHash::deserialize(raw)?), - false => { - if raw.special()? != CBORSpecial::Null { - return Err(DeserializeFailure::ExpectedNull.into()); - } - None - } - }) - })() - .map_err(|e| e.annotate("prev_hash"))?; - let issuer_vkey = (|| -> Result<_, DeserializeError> { Ok(Vkey::deserialize(raw)?) })() - .map_err(|e| e.annotate("issuer_vkey"))?; - let vrf_vkey = (|| -> Result<_, DeserializeError> { Ok(VRFVKey::deserialize(raw)?) })() - .map_err(|e| e.annotate("vrf_vkey"))?; - let leader_cert = { - // NONCE VFR CERT, first of two certs - // or a single VRF RESULT CERT - // depending on the protocol version - let first_vrf_cert = - (|| -> Result<_, DeserializeError> { Ok(VRFCert::deserialize(raw)?) })() - .map_err(|e| e.annotate("nonce_vrf"))?; - let cbor_type: cbor_event::Type = raw.cbor_type()?; - match cbor_type { - cbor_event::Type::Array => { - // Legacy format, reading the second VRF cert - let leader_vrf = - (|| -> Result<_, DeserializeError> { Ok(VRFCert::deserialize(raw)?) })() - .map_err(|e| e.annotate("leader_vrf"))?; - HeaderLeaderCertEnum::NonceAndLeader(first_vrf_cert, leader_vrf) - } - cbor_event::Type::UnsignedInteger => { - // New format, no second VRF cert is present - HeaderLeaderCertEnum::VrfResult(first_vrf_cert) - } - t => { - return Err(DeserializeError::new( - "HeaderBody.leader_cert", - DeserializeFailure::UnexpectedKeyType(t), - )) - } - } - }; - let block_body_size = (|| -> Result<_, DeserializeError> { Ok(u32::deserialize(raw)?) })() - .map_err(|e| e.annotate("block_body_size"))?; - let block_body_hash = - (|| -> Result<_, DeserializeError> { Ok(BlockHash::deserialize(raw)?) })() - .map_err(|e| e.annotate("block_body_hash"))?; - - let operational_cert = (|| -> Result<_, DeserializeError> { - if raw.cbor_type()? == CBORType::Array { - Ok(OperationalCert::deserialize(raw)?) - } else { - Ok(OperationalCert::deserialize_as_embedded_group(raw, len)?) - } - })() - .map_err(|e| e.annotate("operational_cert"))?; - let protocol_version = (|| -> Result<_, DeserializeError> { - if raw.cbor_type()? == CBORType::Array { - Ok(ProtocolVersion::deserialize(raw)?) - } else { - Ok(ProtocolVersion::deserialize_as_embedded_group(raw, len)?) - } - })() - .map_err(|e| e.annotate("protocol_version"))?; - Ok(HeaderBody { - block_number, - slot, - prev_hash, - issuer_vkey, - vrf_vkey, - leader_cert, - block_body_size, - block_body_hash, - operational_cert, - protocol_version, - }) - } -} - impl cbor_event::se::Serialize for AssetName { fn serialize<'se, W: Write>( &self, diff --git a/rust/src/serialization/mod.rs b/rust/src/serialization/mod.rs index 15a000f1..4624829a 100644 --- a/rust/src/serialization/mod.rs +++ b/rust/src/serialization/mod.rs @@ -25,6 +25,6 @@ mod plutus; mod native_script; mod native_scripts; mod numeric; -mod versioned_block; mod script_ref; -mod tx_input; \ No newline at end of file +mod tx_input; +mod block; \ No newline at end of file diff --git a/rust/src/serialization/utils.rs b/rust/src/serialization/utils.rs index e67d68b1..8b9b7015 100644 --- a/rust/src/serialization/utils.rs +++ b/rust/src/serialization/utils.rs @@ -1,3 +1,4 @@ +use std::io::SeekFrom; use crate::*; /// TODO: this function can be removed in case `cbor_event` library ever gets a fix on their side @@ -149,3 +150,17 @@ pub(crate) fn is_break_tag( } Ok(false) } + +pub(crate) fn deserilized_with_orig_bytes( + raw: &mut Deserializer, + deserializer: fn(&mut Deserializer) -> Result, +) -> Result<(T, Vec), DeserializeError> { + let before = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); + let value = deserializer(raw)?; + let after = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap(); + let bytes_read = (after - before) as usize; + raw.as_mut_ref().seek(SeekFrom::Start(before)).unwrap(); + let original_bytes = raw.as_mut_ref().fill_buf().unwrap()[..bytes_read].to_vec(); + raw.as_mut_ref().seek(SeekFrom::Start(after)).unwrap(); + Ok((value, original_bytes)) +} \ No newline at end of file From 89cbeea2cab5610147a1588401e62e685e780464 Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 8 Aug 2024 01:44:56 +0900 Subject: [PATCH 326/349] add preview cost models for conway --- rust/src/builders/tx_builder_constants.rs | 64 ++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/rust/src/builders/tx_builder_constants.rs b/rust/src/builders/tx_builder_constants.rs index 34c3acf3..05696b14 100644 --- a/rust/src/builders/tx_builder_constants.rs +++ b/rust/src/builders/tx_builder_constants.rs @@ -73,4 +73,66 @@ impl TxBuilderConstants { ); res } -} \ No newline at end of file + + pub fn plutus_conway_cost_models() -> Costmdls { + let mut res = Costmdls::new(); + res.insert( + &Language::new_plutus_v1(), + &CostModel::from(vec![ + 100788, 420, 1, 1, 1000, 173, 0, 1, 1000, 59957, 4, 1, 11183, 32, 201305, 8356, 4, + 16000, 100, 16000, 100, 16000, 100, 16000, 100, 16000, 100, 16000, 100, 100, 100, + 16000, 100, 94375, 32, 132994, 32, 61462, 4, 72010, 178, 0, 1, 22151, 32, 91189, + 769, 4, 2, 85848, 228465, 122, 0, 1, 1, 1000, 42921, 4, 2, 24548, 29498, 38, 1, + 898148, 27279, 1, 51775, 558, 1, 39184, 1000, 60594, 1, 141895, 32, 83150, 32, + 15299, 32, 76049, 1, 13169, 4, 22100, 10, 28999, 74, 1, 28999, 74, 1, 43285, 552, + 1, 44749, 541, 1, 33852, 32, 68246, 32, 72362, 32, 7243, 32, 7391, 32, 11546, 32, + 85848, 228465, 122, 0, 1, 1, 90434, 519, 0, 1, 74433, 32, 85848, 228465, 122, 0, 1, + 1, 85848, 228465, 122, 0, 1, 1, 270652, 22588, 4, 1457325, 64566, 4, 20467, 1, 4, + 0, 141992, 32, 100788, 420, 1, 1, 81663, 32, 59498, 32, 20142, 32, 24588, 32, + 20744, 32, 25933, 32, 24623, 32, 53384111, 14333, 10, + ]), + ); + res.insert( + &Language::new_plutus_v2(), + &CostModel::from(vec![ + 100788, 420, 1, 1, 1000, 173, 0, 1, 1000, 59957, 4, 1, 11183, 32, 201305, 8356, 4, + 16000, 100, 16000, 100, 16000, 100, 16000, 100, 16000, 100, 16000, 100, 100, 100, + 16000, 100, 94375, 32, 132994, 32, 61462, 4, 72010, 178, 0, 1, 22151, 32, 91189, + 769, 4, 2, 85848, 228465, 122, 0, 1, 1, 1000, 42921, 4, 2, 24548, 29498, 38, 1, + 898148, 27279, 1, 51775, 558, 1, 39184, 1000, 60594, 1, 141895, 32, 83150, 32, + 15299, 32, 76049, 1, 13169, 4, 22100, 10, 28999, 74, 1, 28999, 74, 1, 43285, 552, + 1, 44749, 541, 1, 33852, 32, 68246, 32, 72362, 32, 7243, 32, 7391, 32, 11546, 32, + 85848, 228465, 122, 0, 1, 1, 90434, 519, 0, 1, 74433, 32, 85848, 228465, 122, 0, 1, + 1, 85848, 228465, 122, 0, 1, 1, 955506, 213312, 0, 2, 270652, 22588, 4, 1457325, + 64566, 4, 20467, 1, 4, 0, 141992, 32, 100788, 420, 1, 1, 81663, 32, 59498, 32, + 20142, 32, 24588, 32, 20744, 32, 25933, 32, 24623, 32, 43053543, 10, 53384111, + 14333, 10, 43574283, 26308, 10, + ]), + ); + res.insert( + &Language::new_plutus_v3(), + &CostModel::from(vec![ + 100788, 420, 1, 1, 1000, 173, 0, 1, 1000, 59957, 4, 1, 11183, 32, 201305, 8356, 4, + 16000, 100, 16000, 100, 16000, 100, 16000, 100, 16000, 100, 16000, 100, 100, 100, + 16000, 100, 94375, 32, 132994, 32, 61462, 4, 72010, 178, 0, 1, 22151, 32, 91189, + 769, 4, 2, 85848, 123203, 7305, -900, 1716, 549, 57, 85848, 0, 1, 1, 1000, 42921, + 4, 2, 24548, 29498, 38, 1, 898148, 27279, 1, 51775, 558, 1, 39184, 1000, 60594, 1, + 141895, 32, 83150, 32, 15299, 32, 76049, 1, 13169, 4, 22100, 10, 28999, 74, 1, + 28999, 74, 1, 43285, 552, 1, 44749, 541, 1, 33852, 32, 68246, 32, 72362, 32, 7243, + 32, 7391, 32, 11546, 32, 85848, 123203, 7305, -900, 1716, 549, 57, 85848, 0, 1, + 90434, 519, 0, 1, 74433, 32, 85848, 123203, 7305, -900, 1716, 549, 57, 85848, 0, 1, + 1, 85848, 123203, 7305, -900, 1716, 549, 57, 85848, 0, 1, 955506, 213312, 0, 2, + 270652, 22588, 4, 1457325, 64566, 4, 20467, 1, 4, 0, 141992, 32, 100788, 420, 1, 1, + 81663, 32, 59498, 32, 20142, 32, 24588, 32, 20744, 32, 25933, 32, 24623, 32, + 43053543, 10, 53384111, 14333, 10, 43574283, 26308, 10, 16000, 100, 16000, 100, + 962335, 18, 2780678, 6, 442008, 1, 52538055, 3756, 18, 267929, 18, 76433006, 8868, + 18, 52948122, 18, 1995836, 36, 3227919, 12, 901022, 1, 166917843, 4307, 36, 284546, + 36, 158221314, 26549, 36, 74698472, 36, 333849714, 1, 254006273, 72, 2174038, 72, + 2261318, 64571, 4, 207616, 8310, 4, 1293828, 28716, 63, 0, 1, 1006041, 43623, 251, + 0, 1, + ]), + ); + + return res; + } +} From 242abc19f6d415b42beedb891b35517bf01737b9 Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 8 Aug 2024 01:46:13 +0900 Subject: [PATCH 327/349] fix types for wasm --- rust/src/protocol_types/certificates/certificate.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/src/protocol_types/certificates/certificate.rs b/rust/src/protocol_types/certificates/certificate.rs index 3045550b..f071c5e3 100644 --- a/rust/src/protocol_types/certificates/certificate.rs +++ b/rust/src/protocol_types/certificates/certificate.rs @@ -83,7 +83,7 @@ impl Certificate { /// Since StakeRegistration can represent stake_registration certificate or reg_cert certificate, because both certificates have the same semantics. /// And in some cases you want to create a reg_cert, this function is used to create a reg_cert. /// The function will return an error if StakeRegistration represents a stake_registration certificate. - pub fn new_reg_cert(stake_registration: &StakeRegistration) -> Result { + pub fn new_reg_cert(stake_registration: &StakeRegistration) -> Result { if stake_registration.coin.is_none() { return Err(JsError::from_str("coin is required")); } else { @@ -102,7 +102,7 @@ impl Certificate { /// Since StakeDeregistration can represent stake_deregistration certificate or unreg_cert certificate, because both certificates have the same semantics. /// And in some cases you want to create an unreg_cert, this function is used to create an unreg_cert. /// The function will return an error if StakeDeregistration represents a stake_deregistration certificate. - pub fn new_unreg_cert(stake_deregistration: &StakeDeregistration) -> Result { + pub fn new_unreg_cert(stake_deregistration: &StakeDeregistration) -> Result { if stake_deregistration.coin.is_none() { return Err(JsError::from_str("coin is required")); } else { From 2d91fdeb63c0e717c809d3351f8a29be444a966e Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 8 Aug 2024 02:10:41 +0900 Subject: [PATCH 328/349] bump version --- package-lock.json | 4 ++-- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 37c86caf..ca919883 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.3", + "version": "12.0.0-beta.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.3", + "version": "12.0.0-beta.4", "hasInstallScript": true, "license": "MIT", "devDependencies": { diff --git a/package.json b/package.json index 4d21876c..c9ca71e2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.3", + "version": "12.0.0-beta.4", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 00ee8cfd..4d796121 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-beta.3" +version = "12.0.0-beta.4" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 1a19ce6a..e811cdf8 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -49,7 +49,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-beta.3" +version = "12.0.0-beta.4" dependencies = [ "bech32", "cbor_event", From b9f2b00d3499fffaef5c6c9c825e21c47182bbf0 Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 8 Aug 2024 02:12:00 +0900 Subject: [PATCH 329/349] bump bindgen version --- rust/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 4d796121..0cd5f51e 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -48,7 +48,7 @@ getrandom = "0.2.3" # wasm [target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies] serde-wasm-bindgen = "0.4.5" -wasm-bindgen = "=0.2.90" +wasm-bindgen = "=0.2.92" rand_os = { version = "0.1", features = ["wasm-bindgen"] } js-sys = "0.3.51" getrandom = { version = "0.2.3", features = ["js"] } From 0bdbdc34ea1191ad563eb16961ea262aa8f76a04 Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 8 Aug 2024 02:21:19 +0900 Subject: [PATCH 330/349] add from_hex for "fixed" structs --- rust/src/protocol_types/block/fixed_block.rs | 1 + rust/src/protocol_types/block/fixed_transaction_bodies.rs | 1 + rust/src/protocol_types/block/fixed_tx_body.rs | 1 + rust/src/protocol_types/block/fixed_versioned_block.rs | 1 + 4 files changed, 4 insertions(+) diff --git a/rust/src/protocol_types/block/fixed_block.rs b/rust/src/protocol_types/block/fixed_block.rs index 7b905ab0..fb22a3eb 100644 --- a/rust/src/protocol_types/block/fixed_block.rs +++ b/rust/src/protocol_types/block/fixed_block.rs @@ -14,6 +14,7 @@ pub struct FixedBlock { } from_bytes!(FixedBlock); +from_hex!(FixedBlock); #[wasm_bindgen] impl FixedBlock { diff --git a/rust/src/protocol_types/block/fixed_transaction_bodies.rs b/rust/src/protocol_types/block/fixed_transaction_bodies.rs index 5a089280..b480f4cd 100644 --- a/rust/src/protocol_types/block/fixed_transaction_bodies.rs +++ b/rust/src/protocol_types/block/fixed_transaction_bodies.rs @@ -6,6 +6,7 @@ use crate::*; pub struct FixedTransactionBodies(pub(crate) Vec); from_bytes!(FixedTransactionBodies); +from_hex!(FixedTransactionBodies); #[wasm_bindgen] impl FixedTransactionBodies { diff --git a/rust/src/protocol_types/block/fixed_tx_body.rs b/rust/src/protocol_types/block/fixed_tx_body.rs index 4496c0da..d1a4b4eb 100644 --- a/rust/src/protocol_types/block/fixed_tx_body.rs +++ b/rust/src/protocol_types/block/fixed_tx_body.rs @@ -11,6 +11,7 @@ pub struct FixedTransactionBody { } from_bytes!(FixedTransactionBody); +from_hex!(FixedTransactionBody); #[wasm_bindgen] impl FixedTransactionBody { diff --git a/rust/src/protocol_types/block/fixed_versioned_block.rs b/rust/src/protocol_types/block/fixed_versioned_block.rs index 540e3d1c..82f3921d 100644 --- a/rust/src/protocol_types/block/fixed_versioned_block.rs +++ b/rust/src/protocol_types/block/fixed_versioned_block.rs @@ -9,6 +9,7 @@ pub struct FixedVersionedBlock { } from_bytes!(FixedVersionedBlock); +from_hex!(FixedVersionedBlock); #[wasm_bindgen] impl FixedVersionedBlock { From 889764f0d4072c97739c24c3049b8d79ece48569 Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 8 Aug 2024 02:22:00 +0900 Subject: [PATCH 331/349] bump version --- package-lock.json | 4 ++-- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 22 +++++++++++----------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index ca919883..7e88e493 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.4", + "version": "12.0.0-beta.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.4", + "version": "12.0.0-beta.5", "hasInstallScript": true, "license": "MIT", "devDependencies": { diff --git a/package.json b/package.json index c9ca71e2..b33d7e4e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.4", + "version": "12.0.0-beta.5", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 0cd5f51e..e18bb2c1 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-beta.4" +version = "12.0.0-beta.5" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index e811cdf8..bd23e381 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -49,7 +49,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-beta.4" +version = "12.0.0-beta.5" dependencies = [ "bech32", "cbor_event", @@ -619,9 +619,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -629,9 +629,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", @@ -644,9 +644,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -654,9 +654,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", @@ -667,9 +667,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "winapi" From 5f3b18c124fb2ea6e7d80fdb08a206c161835752 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 12 Aug 2024 22:09:37 +0900 Subject: [PATCH 332/349] drep naming unification --- rust/json-gen/src/main.rs | 8 ++-- rust/src/builders/certificates_builder.rs | 10 ++-- .../certificates/certificate.rs | 48 +++++++++---------- .../certificates/drep_deregistration.rs | 6 +-- .../certificates/drep_registration.rs | 6 +-- .../certificates/drep_update.rs | 6 +-- .../protocol_types/protocol_param_update.rs | 12 ++--- .../serialization/certificates/certificate.rs | 18 +++---- .../certificates/drep_deregistration.rs | 14 +++--- .../certificates/drep_registration.rs | 14 +++--- .../serialization/certificates/drep_update.rs | 14 +++--- .../map_names/certificate_index_names.rs | 6 +-- .../serialization/protocol_param_update.rs | 10 ++-- .../tests/builders/certificates_builder.rs | 14 +++--- rust/src/tests/fakes.rs | 4 +- rust/src/tests/general.rs | 2 +- rust/src/tests/protocol_types/certificates.rs | 12 ++--- .../protocol_types/protocol_param_update.rs | 6 +-- rust/src/tests/serialization/certificates.rs | 20 ++++---- .../serialization/protocol_param_update.rs | 8 ++-- rust/src/utils.rs | 4 +- 21 files changed, 121 insertions(+), 121 deletions(-) diff --git a/rust/json-gen/src/main.rs b/rust/json-gen/src/main.rs index 408ff981..d22dc080 100644 --- a/rust/json-gen/src/main.rs +++ b/rust/json-gen/src/main.rs @@ -177,9 +177,9 @@ fn main() { gen_json_schema!(VotingProcedures); gen_json_schema!(CommitteeHotAuth); gen_json_schema!(CommitteeColdResign); - gen_json_schema!(DrepDeregistration); - gen_json_schema!(DrepRegistration); - gen_json_schema!(DrepUpdate); + gen_json_schema!(DRepDeregistration); + gen_json_schema!(DRepRegistration); + gen_json_schema!(DRepUpdate); gen_json_schema!(StakeAndVoteDelegation); gen_json_schema!(StakeRegistrationAndDelegation); gen_json_schema!(StakeVoteRegistrationAndDelegation); @@ -198,6 +198,6 @@ fn main() { gen_json_schema!(TreasuryWithdrawalsAction); gen_json_schema!(Committee); gen_json_schema!(Constitution); - gen_json_schema!(DrepVotingThresholds); + gen_json_schema!(DRepVotingThresholds); gen_json_schema!(PoolVotingThresholds); } diff --git a/rust/src/builders/certificates_builder.rs b/rust/src/builders/certificates_builder.rs index b9aa0cba..2e94dc22 100644 --- a/rust/src/builders/certificates_builder.rs +++ b/rust/src/builders/certificates_builder.rs @@ -160,7 +160,7 @@ impl CertificatesBuilder { refund = refund.checked_add(&key_deposit)?; } } - CertificateEnum::DrepDeregistration(cert) => { + CertificateEnum::DRepDeregistration(cert) => { refund = refund.checked_add(&cert.coin)?; } _ => {} @@ -187,7 +187,7 @@ impl CertificatesBuilder { deposit = deposit.checked_add(&key_deposit)?; } } - CertificateEnum::DrepRegistration(cert) => { + CertificateEnum::DRepRegistration(cert) => { deposit = deposit.checked_add(&cert.coin)?; } CertificateEnum::StakeRegistrationAndDelegation(cert) => { @@ -277,17 +277,17 @@ fn witness_keys_for_cert(cert_enum: &Certificate) -> RequiredSigners { set.add(key_hash); } } - CertificateEnum::DrepUpdate(cert) => { + CertificateEnum::DRepUpdate(cert) => { if let CredType::Key(key_hash) = &cert.voting_credential.0 { set.add(key_hash); } } - CertificateEnum::DrepRegistration(cert) => { + CertificateEnum::DRepRegistration(cert) => { if let CredType::Key(key_hash) = &cert.voting_credential.0 { set.add(key_hash); } } - CertificateEnum::DrepDeregistration(cert) => { + CertificateEnum::DRepDeregistration(cert) => { if let CredType::Key(key_hash) = &cert.voting_credential.0 { set.add(key_hash); } diff --git a/rust/src/protocol_types/certificates/certificate.rs b/rust/src/protocol_types/certificates/certificate.rs index f071c5e3..53660dd8 100644 --- a/rust/src/protocol_types/certificates/certificate.rs +++ b/rust/src/protocol_types/certificates/certificate.rs @@ -12,9 +12,9 @@ pub enum CertificateKind { MoveInstantaneousRewardsCert, CommitteeHotAuth, CommitteeColdResign, - DrepDeregistration, - DrepRegistration, - DrepUpdate, + DRepDeregistration, + DRepRegistration, + DRepUpdate, StakeAndVoteDelegation, StakeRegistrationAndDelegation, StakeVoteRegistrationAndDelegation, @@ -44,9 +44,9 @@ pub enum CertificateEnum { MoveInstantaneousRewardsCert(MoveInstantaneousRewardsCert), CommitteeHotAuth(CommitteeHotAuth), CommitteeColdResign(CommitteeColdResign), - DrepDeregistration(DrepDeregistration), - DrepRegistration(DrepRegistration), - DrepUpdate(DrepUpdate), + DRepDeregistration(DRepDeregistration), + DRepRegistration(DRepRegistration), + DRepUpdate(DRepUpdate), StakeAndVoteDelegation(StakeAndVoteDelegation), StakeRegistrationAndDelegation(StakeRegistrationAndDelegation), StakeVoteRegistrationAndDelegation(StakeVoteRegistrationAndDelegation), @@ -154,18 +154,18 @@ impl Certificate { )) } - pub fn new_drep_deregistration(drep_deregistration: &DrepDeregistration) -> Self { - Self(CertificateEnum::DrepDeregistration( + pub fn new_drep_deregistration(drep_deregistration: &DRepDeregistration) -> Self { + Self(CertificateEnum::DRepDeregistration( drep_deregistration.clone(), )) } - pub fn new_drep_registration(drep_registration: &DrepRegistration) -> Self { - Self(CertificateEnum::DrepRegistration(drep_registration.clone())) + pub fn new_drep_registration(drep_registration: &DRepRegistration) -> Self { + Self(CertificateEnum::DRepRegistration(drep_registration.clone())) } - pub fn new_drep_update(drep_update: &DrepUpdate) -> Self { - Self(CertificateEnum::DrepUpdate(drep_update.clone())) + pub fn new_drep_update(drep_update: &DRepUpdate) -> Self { + Self(CertificateEnum::DRepUpdate(drep_update.clone())) } pub fn new_stake_and_vote_delegation( @@ -221,9 +221,9 @@ impl Certificate { CertificateEnum::CommitteeColdResign(_) => { CertificateKind::CommitteeColdResign } - CertificateEnum::DrepDeregistration(_) => CertificateKind::DrepDeregistration, - CertificateEnum::DrepRegistration(_) => CertificateKind::DrepRegistration, - CertificateEnum::DrepUpdate(_) => CertificateKind::DrepUpdate, + CertificateEnum::DRepDeregistration(_) => CertificateKind::DRepDeregistration, + CertificateEnum::DRepRegistration(_) => CertificateKind::DRepRegistration, + CertificateEnum::DRepUpdate(_) => CertificateKind::DRepUpdate, CertificateEnum::StakeAndVoteDelegation(_) => CertificateKind::StakeAndVoteDelegation, CertificateEnum::StakeRegistrationAndDelegation(_) => { CertificateKind::StakeRegistrationAndDelegation @@ -333,23 +333,23 @@ impl Certificate { } } - pub fn as_drep_deregistration(&self) -> Option { + pub fn as_drep_deregistration(&self) -> Option { match &self.0 { - CertificateEnum::DrepDeregistration(x) => Some(x.clone()), + CertificateEnum::DRepDeregistration(x) => Some(x.clone()), _ => None, } } - pub fn as_drep_registration(&self) -> Option { + pub fn as_drep_registration(&self) -> Option { match &self.0 { - CertificateEnum::DrepRegistration(x) => Some(x.clone()), + CertificateEnum::DRepRegistration(x) => Some(x.clone()), _ => None, } } - pub fn as_drep_update(&self) -> Option { + pub fn as_drep_update(&self) -> Option { match &self.0 { - CertificateEnum::DrepUpdate(x) => Some(x.clone()), + CertificateEnum::DRepUpdate(x) => Some(x.clone()), _ => None, } } @@ -409,9 +409,9 @@ impl Certificate { CertificateEnum::VoteRegistrationAndDelegation(x) => x.has_script_credentials(), CertificateEnum::CommitteeHotAuth(x) => x.has_script_credentials(), CertificateEnum::CommitteeColdResign(x) => x.has_script_credentials(), - CertificateEnum::DrepRegistration(x) => x.has_script_credentials(), - CertificateEnum::DrepDeregistration(x) => x.has_script_credentials(), - CertificateEnum::DrepUpdate(x) => x.has_script_credentials(), + CertificateEnum::DRepRegistration(x) => x.has_script_credentials(), + CertificateEnum::DRepDeregistration(x) => x.has_script_credentials(), + CertificateEnum::DRepUpdate(x) => x.has_script_credentials(), _ => false, } } diff --git a/rust/src/protocol_types/certificates/drep_deregistration.rs b/rust/src/protocol_types/certificates/drep_deregistration.rs index 89d4ae02..f67eb955 100644 --- a/rust/src/protocol_types/certificates/drep_deregistration.rs +++ b/rust/src/protocol_types/certificates/drep_deregistration.rs @@ -13,15 +13,15 @@ use crate::*; JsonSchema, )] #[wasm_bindgen] -pub struct DrepDeregistration { +pub struct DRepDeregistration { pub(crate) voting_credential: Credential, pub(crate) coin: Coin, } -impl_to_from!(DrepDeregistration); +impl_to_from!(DRepDeregistration); #[wasm_bindgen] -impl DrepDeregistration { +impl DRepDeregistration { pub fn voting_credential(&self) -> Credential { self.voting_credential.clone() } diff --git a/rust/src/protocol_types/certificates/drep_registration.rs b/rust/src/protocol_types/certificates/drep_registration.rs index 9e803c30..c0ad2d84 100644 --- a/rust/src/protocol_types/certificates/drep_registration.rs +++ b/rust/src/protocol_types/certificates/drep_registration.rs @@ -13,16 +13,16 @@ use crate::*; JsonSchema, )] #[wasm_bindgen] -pub struct DrepRegistration { +pub struct DRepRegistration { pub(crate) voting_credential: Credential, pub(crate) coin: Coin, pub(crate) anchor: Option, } -impl_to_from!(DrepRegistration); +impl_to_from!(DRepRegistration); #[wasm_bindgen] -impl DrepRegistration { +impl DRepRegistration { pub fn voting_credential(&self) -> Credential { self.voting_credential.clone() } diff --git a/rust/src/protocol_types/certificates/drep_update.rs b/rust/src/protocol_types/certificates/drep_update.rs index d4427d73..d845aaa6 100644 --- a/rust/src/protocol_types/certificates/drep_update.rs +++ b/rust/src/protocol_types/certificates/drep_update.rs @@ -13,15 +13,15 @@ use crate::*; JsonSchema, )] #[wasm_bindgen] -pub struct DrepUpdate { +pub struct DRepUpdate { pub(crate) voting_credential: Credential, pub(crate) anchor: Option, } -impl_to_from!(DrepUpdate); +impl_to_from!(DRepUpdate); #[wasm_bindgen] -impl DrepUpdate { +impl DRepUpdate { pub fn voting_credential(&self) -> Credential { self.voting_credential.clone() } diff --git a/rust/src/protocol_types/protocol_param_update.rs b/rust/src/protocol_types/protocol_param_update.rs index 887b866e..cc38e608 100644 --- a/rust/src/protocol_types/protocol_param_update.rs +++ b/rust/src/protocol_types/protocol_param_update.rs @@ -76,7 +76,7 @@ impl PoolVotingThresholds { serde::Deserialize, JsonSchema, )] -pub struct DrepVotingThresholds { +pub struct DRepVotingThresholds { pub(crate) motion_no_confidence: UnitInterval, pub(crate) committee_normal: UnitInterval, pub(crate) committee_no_confidence: UnitInterval, @@ -89,10 +89,10 @@ pub struct DrepVotingThresholds { pub(crate) treasury_withdrawal: UnitInterval, } -impl_to_from!(DrepVotingThresholds); +impl_to_from!(DRepVotingThresholds); #[wasm_bindgen] -impl DrepVotingThresholds { +impl DRepVotingThresholds { pub fn new( motion_no_confidence: &UnitInterval, committee_normal: &UnitInterval, @@ -241,7 +241,7 @@ pub struct ProtocolParamUpdate { pub(crate) collateral_percentage: Option, pub(crate) max_collateral_inputs: Option, pub(crate) pool_voting_thresholds: Option, - pub(crate) drep_voting_thresholds: Option, + pub(crate) drep_voting_thresholds: Option, pub(crate) min_committee_size: Option, pub(crate) committee_term_limit: Option, pub(crate) governance_action_validity_period: Option, @@ -465,11 +465,11 @@ impl ProtocolParamUpdate { self.pool_voting_thresholds.clone() } - pub fn set_drep_voting_thresholds(&mut self, drep_voting_thresholds: &DrepVotingThresholds) { + pub fn set_drep_voting_thresholds(&mut self, drep_voting_thresholds: &DRepVotingThresholds) { self.drep_voting_thresholds = Some(drep_voting_thresholds.clone()) } - pub fn drep_voting_thresholds(&self) -> Option { + pub fn drep_voting_thresholds(&self) -> Option { self.drep_voting_thresholds.clone() } diff --git a/rust/src/serialization/certificates/certificate.rs b/rust/src/serialization/certificates/certificate.rs index 10fbf296..08429c3c 100644 --- a/rust/src/serialization/certificates/certificate.rs +++ b/rust/src/serialization/certificates/certificate.rs @@ -18,9 +18,9 @@ impl cbor_event::se::Serialize for CertificateEnum { CertificateEnum::MoveInstantaneousRewardsCert(x) => x.serialize(serializer), CertificateEnum::CommitteeHotAuth(x) => x.serialize(serializer), CertificateEnum::CommitteeColdResign(x) => x.serialize(serializer), - CertificateEnum::DrepRegistration(x) => x.serialize(serializer), - CertificateEnum::DrepDeregistration(x) => x.serialize(serializer), - CertificateEnum::DrepUpdate(x) => x.serialize(serializer), + CertificateEnum::DRepRegistration(x) => x.serialize(serializer), + CertificateEnum::DRepDeregistration(x) => x.serialize(serializer), + CertificateEnum::DRepUpdate(x) => x.serialize(serializer), CertificateEnum::StakeAndVoteDelegation(x) => x.serialize(serializer), CertificateEnum::StakeRegistrationAndDelegation(x) => x.serialize(serializer), CertificateEnum::StakeVoteRegistrationAndDelegation(x) => x.serialize(serializer), @@ -119,14 +119,14 @@ impl DeserializeEmbeddedGroup for CertificateEnum { CommitteeColdResign::deserialize_as_embedded_group(raw, len)?, )) } - CertificateIndexNames::DrepRegistration => Ok(CertificateEnum::DrepRegistration( - DrepRegistration::deserialize_as_embedded_group(raw, len)?, + CertificateIndexNames::DRepRegistration => Ok(CertificateEnum::DRepRegistration( + DRepRegistration::deserialize_as_embedded_group(raw, len)?, )), - CertificateIndexNames::DrepDeregistration => Ok(CertificateEnum::DrepDeregistration( - DrepDeregistration::deserialize_as_embedded_group(raw, len)?, + CertificateIndexNames::DRepDeregistration => Ok(CertificateEnum::DRepDeregistration( + DRepDeregistration::deserialize_as_embedded_group(raw, len)?, )), - CertificateIndexNames::DrepUpdate => Ok(CertificateEnum::DrepUpdate( - DrepUpdate::deserialize_as_embedded_group(raw, len)?, + CertificateIndexNames::DRepUpdate => Ok(CertificateEnum::DRepUpdate( + DRepUpdate::deserialize_as_embedded_group(raw, len)?, )), CertificateIndexNames::StakeAndVoteDelegation => { Ok(CertificateEnum::StakeAndVoteDelegation( diff --git a/rust/src/serialization/certificates/drep_deregistration.rs b/rust/src/serialization/certificates/drep_deregistration.rs index 27bcf7ca..14381382 100644 --- a/rust/src/serialization/certificates/drep_deregistration.rs +++ b/rust/src/serialization/certificates/drep_deregistration.rs @@ -5,15 +5,15 @@ use crate::serialization::utils::{ use crate::*; use num_traits::ToPrimitive; -impl cbor_event::se::Serialize for DrepDeregistration { +impl cbor_event::se::Serialize for DRepDeregistration { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(3))?; - let proposal_index = CertificateIndexNames::DrepDeregistration.to_u64(); - serialize_and_check_index(serializer, proposal_index, "DrepDeregistration")?; + let proposal_index = CertificateIndexNames::DRepDeregistration.to_u64(); + serialize_and_check_index(serializer, proposal_index, "DRepDeregistration")?; self.voting_credential.serialize(serializer)?; self.coin.serialize(serializer)?; @@ -21,16 +21,16 @@ impl cbor_event::se::Serialize for DrepDeregistration { } } -impl_deserialize_for_wrapped_tuple!(DrepDeregistration); +impl_deserialize_for_wrapped_tuple!(DRepDeregistration); -impl DeserializeEmbeddedGroup for DrepDeregistration { +impl DeserializeEmbeddedGroup for DRepDeregistration { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { check_len(len, 3, "(cert_index, voting_credential, coin)")?; - let cert_index = CertificateIndexNames::DrepDeregistration.to_u64(); + let cert_index = CertificateIndexNames::DRepDeregistration.to_u64(); deserialize_and_check_index(raw, cert_index, "cert_index")?; let voting_credential = @@ -38,7 +38,7 @@ impl DeserializeEmbeddedGroup for DrepDeregistration { let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?; - Ok(DrepDeregistration { + Ok(DRepDeregistration { voting_credential, coin, }) diff --git a/rust/src/serialization/certificates/drep_registration.rs b/rust/src/serialization/certificates/drep_registration.rs index 1352d99c..4e4da473 100644 --- a/rust/src/serialization/certificates/drep_registration.rs +++ b/rust/src/serialization/certificates/drep_registration.rs @@ -5,15 +5,15 @@ use crate::serialization::utils::{ use crate::*; use num_traits::ToPrimitive; -impl cbor_event::se::Serialize for DrepRegistration { +impl cbor_event::se::Serialize for DRepRegistration { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(4))?; - let proposal_index = CertificateIndexNames::DrepRegistration.to_u64(); - serialize_and_check_index(serializer, proposal_index, "DrepRegistration")?; + let proposal_index = CertificateIndexNames::DRepRegistration.to_u64(); + serialize_and_check_index(serializer, proposal_index, "DRepRegistration")?; self.voting_credential.serialize(serializer)?; self.coin.serialize(serializer)?; @@ -25,9 +25,9 @@ impl cbor_event::se::Serialize for DrepRegistration { } } -impl_deserialize_for_wrapped_tuple!(DrepRegistration); +impl_deserialize_for_wrapped_tuple!(DRepRegistration); -impl DeserializeEmbeddedGroup for DrepRegistration { +impl DeserializeEmbeddedGroup for DRepRegistration { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, @@ -38,7 +38,7 @@ impl DeserializeEmbeddedGroup for DrepRegistration { "(cert_index, voting_credential, coin, anchor / null)", )?; - let cert_index = CertificateIndexNames::DrepRegistration.to_u64(); + let cert_index = CertificateIndexNames::DRepRegistration.to_u64(); deserialize_and_check_index(raw, cert_index, "cert_index")?; let voting_credential = @@ -48,7 +48,7 @@ impl DeserializeEmbeddedGroup for DrepRegistration { let anchor = Anchor::deserialize_nullable(raw).map_err(|e| e.annotate("anchor"))?; - Ok(DrepRegistration { + Ok(DRepRegistration { voting_credential, coin, anchor, diff --git a/rust/src/serialization/certificates/drep_update.rs b/rust/src/serialization/certificates/drep_update.rs index 4d73ea73..b5a09fac 100644 --- a/rust/src/serialization/certificates/drep_update.rs +++ b/rust/src/serialization/certificates/drep_update.rs @@ -5,15 +5,15 @@ use crate::serialization::utils::{ use crate::*; use num_traits::ToPrimitive; -impl cbor_event::se::Serialize for DrepUpdate { +impl cbor_event::se::Serialize for DRepUpdate { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(3))?; - let proposal_index = CertificateIndexNames::DrepUpdate.to_u64(); - serialize_and_check_index(serializer, proposal_index, "DrepUpdate")?; + let proposal_index = CertificateIndexNames::DRepUpdate.to_u64(); + serialize_and_check_index(serializer, proposal_index, "DRepUpdate")?; self.voting_credential.serialize(serializer)?; match &self.anchor { @@ -24,16 +24,16 @@ impl cbor_event::se::Serialize for DrepUpdate { } } -impl_deserialize_for_wrapped_tuple!(DrepUpdate); +impl_deserialize_for_wrapped_tuple!(DRepUpdate); -impl DeserializeEmbeddedGroup for DrepUpdate { +impl DeserializeEmbeddedGroup for DRepUpdate { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, ) -> Result { check_len(len, 3, "(cert_index, voting_credential, anchor / null)")?; - let cert_index = CertificateIndexNames::DrepUpdate.to_u64(); + let cert_index = CertificateIndexNames::DRepUpdate.to_u64(); deserialize_and_check_index(raw, cert_index, "cert_index")?; let voting_credential = @@ -41,7 +41,7 @@ impl DeserializeEmbeddedGroup for DrepUpdate { let anchor = Anchor::deserialize_nullable(raw).map_err(|e| e.annotate("anchor"))?; - Ok(DrepUpdate { + Ok(DRepUpdate { voting_credential, anchor, }) diff --git a/rust/src/serialization/map_names/certificate_index_names.rs b/rust/src/serialization/map_names/certificate_index_names.rs index 9a7eac38..b7ad732c 100644 --- a/rust/src/serialization/map_names/certificate_index_names.rs +++ b/rust/src/serialization/map_names/certificate_index_names.rs @@ -16,7 +16,7 @@ pub(crate) enum CertificateIndexNames { StakeVoteRegistrationAndDelegation = 13, CommitteeHotAuth = 14, CommitteeColdResign = 15, - DrepRegistration = 16, - DrepDeregistration = 17, - DrepUpdate = 18, + DRepRegistration = 16, + DRepDeregistration = 17, + DRepUpdate = 18, } diff --git a/rust/src/serialization/protocol_param_update.rs b/rust/src/serialization/protocol_param_update.rs index 42b636e3..03f2facc 100644 --- a/rust/src/serialization/protocol_param_update.rs +++ b/rust/src/serialization/protocol_param_update.rs @@ -55,7 +55,7 @@ impl DeserializeEmbeddedGroup for PoolVotingThresholds { } } -impl Serialize for DrepVotingThresholds { +impl Serialize for DRepVotingThresholds { fn serialize<'se, W: Write>( &self, serializer: &'se mut Serializer, @@ -74,9 +74,9 @@ impl Serialize for DrepVotingThresholds { } } -impl_deserialize_for_wrapped_tuple!(DrepVotingThresholds); +impl_deserialize_for_wrapped_tuple!(DRepVotingThresholds); -impl DeserializeEmbeddedGroup for DrepVotingThresholds { +impl DeserializeEmbeddedGroup for DRepVotingThresholds { fn deserialize_as_embedded_group( raw: &mut Deserializer, len: cbor_event::Len, @@ -119,7 +119,7 @@ impl DeserializeEmbeddedGroup for DrepVotingThresholds { let treasury_withdrawal = UnitInterval::deserialize(raw).map_err(|e| e.annotate("treasury_withdrawal"))?; - return Ok(DrepVotingThresholds { + return Ok(DRepVotingThresholds { motion_no_confidence, committee_normal, committee_no_confidence, @@ -730,7 +730,7 @@ impl Deserialize for ProtocolParamUpdate { drep_voting_thresholds = Some( (|| -> Result<_, DeserializeError> { read_len.read_elems(1)?; - Ok(DrepVotingThresholds::deserialize(raw)?) + Ok(DRepVotingThresholds::deserialize(raw)?) })() .map_err(|e| e.annotate("drep_voting_thresholds"))?, ); diff --git a/rust/src/tests/builders/certificates_builder.rs b/rust/src/tests/builders/certificates_builder.rs index 452d48cb..159d4002 100644 --- a/rust/src/tests/builders/certificates_builder.rs +++ b/rust/src/tests/builders/certificates_builder.rs @@ -21,13 +21,13 @@ fn certificates_builder_deposit_no_refund_test() { let committee_hot_key_reg_cert_wrapped = Certificate::new_committee_hot_auth(&committee_hot_key_reg_cert); - let drep_reg_cert = DrepRegistration::new( + let drep_reg_cert = DRepRegistration::new( &Credential::from_keyhash(&fake_key_hash(4)), &Coin::from(drep_reg_deposit), ); let drep_reg_cert_wrapped = Certificate::new_drep_registration(&drep_reg_cert); - let drep_update_cert = DrepUpdate::new(&Credential::from_keyhash(&fake_key_hash(6))); + let drep_update_cert = DRepUpdate::new(&Credential::from_keyhash(&fake_key_hash(6))); let cdrep_update_cert_wrapped = Certificate::new_drep_update(&drep_update_cert); let genesis_key_deleg_cert = GenesisKeyDelegation::new( @@ -183,13 +183,13 @@ fn certificates_builder_refund_no_deposit_test() { let committee_hot_key_reg_cert_wrapped = Certificate::new_committee_hot_auth(&committee_hot_key_reg_cert); - let drep_dereg_cert = DrepDeregistration::new( + let drep_dereg_cert = DRepDeregistration::new( &Credential::from_keyhash(&fake_key_hash(5)), &Coin::from(drep_reg_deposit), ); let drep_dereg_cert_wrapped = Certificate::new_drep_deregistration(&drep_dereg_cert); - let drep_update_cert = DrepUpdate::new(&Credential::from_keyhash(&fake_key_hash(6))); + let drep_update_cert = DRepUpdate::new(&Credential::from_keyhash(&fake_key_hash(6))); let cdrep_update_cert_wrapped = Certificate::new_drep_update(&drep_update_cert); let genesis_key_deleg_cert = GenesisKeyDelegation::new( @@ -318,19 +318,19 @@ fn certificates_builder_req_signers_test() { let committee_hot_key_reg_cert_wrapped = Certificate::new_committee_hot_auth(&committee_hot_key_reg_cert); - let drep_reg_cert = DrepRegistration::new( + let drep_reg_cert = DRepRegistration::new( &Credential::from_keyhash(&key_hash_4), &Coin::from(drep_reg_deposit), ); let drep_reg_cert_wrapped = Certificate::new_drep_registration(&drep_reg_cert); - let drep_dereg_cert = DrepDeregistration::new( + let drep_dereg_cert = DRepDeregistration::new( &Credential::from_keyhash(&key_hash_5), &Coin::from(drep_reg_deposit), ); let drep_dereg_cert_wrapped = Certificate::new_drep_deregistration(&drep_dereg_cert); - let drep_update_cert = DrepUpdate::new(&Credential::from_keyhash(&key_hash_6)); + let drep_update_cert = DRepUpdate::new(&Credential::from_keyhash(&key_hash_6)); let cdrep_update_cert_wrapped = Certificate::new_drep_update(&drep_update_cert); let genesis_key_deleg_cert = GenesisKeyDelegation::new( diff --git a/rust/src/tests/fakes.rs b/rust/src/tests/fakes.rs index ef834440..ee4f132a 100644 --- a/rust/src/tests/fakes.rs +++ b/rust/src/tests/fakes.rs @@ -134,8 +134,8 @@ pub(crate) fn fake_pool_voting_thresholds() -> PoolVotingThresholds { ) } -pub(crate) fn fake_drep_voting_thresholds() -> DrepVotingThresholds { - DrepVotingThresholds::new( +pub(crate) fn fake_drep_voting_thresholds() -> DRepVotingThresholds { + DRepVotingThresholds::new( &UnitInterval::new(&BigNum::from(44_401u32), &BigNum::from(44_402u32)), &UnitInterval::new(&BigNum::from(44_403u32), &BigNum::from(44_404u32)), &UnitInterval::new(&BigNum::from(44_405u32), &BigNum::from(44_406u32)), diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index 309fbed2..d721c72d 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -290,7 +290,7 @@ fn protocol_params_update_cbor_json_roundtrip() { &UnitInterval::new(&BigNum::from(40u32), &BigNum::from(41u32)), &UnitInterval::new(&BigNum::from(50u32), &BigNum::from(51u32)), )); - orig_ppu.set_drep_voting_thresholds(&DrepVotingThresholds::new( + orig_ppu.set_drep_voting_thresholds(&DRepVotingThresholds::new( &UnitInterval::new(&BigNum::from(26u32), &BigNum::from(27u32)), &UnitInterval::new(&BigNum::from(28u32), &BigNum::from(29u32)), &UnitInterval::new(&BigNum::from(30u32), &BigNum::from(31u32)), diff --git a/rust/src/tests/protocol_types/certificates.rs b/rust/src/tests/protocol_types/certificates.rs index 05235577..b367f0fb 100644 --- a/rust/src/tests/protocol_types/certificates.rs +++ b/rust/src/tests/protocol_types/certificates.rs @@ -44,9 +44,9 @@ fn drep_deregistration_setters_getters_test() { let cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); let cred_script_hash = Credential::from_scripthash(&fake_script_hash(2)); let coin = Coin::from(100u32); - let drep_deregistration_1 = DrepDeregistration::new(&cred_key_hash, &coin); + let drep_deregistration_1 = DRepDeregistration::new(&cred_key_hash, &coin); - let drep_deregistration_2 = DrepDeregistration::new(&cred_script_hash, &coin); + let drep_deregistration_2 = DRepDeregistration::new(&cred_script_hash, &coin); assert_eq!(drep_deregistration_1.voting_credential(), cred_key_hash); assert_eq!(drep_deregistration_1.coin(), coin); @@ -61,10 +61,10 @@ fn drep_registration_setters_getters_test() { let cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); let cred_script_hash = Credential::from_scripthash(&fake_script_hash(2)); let coin = Coin::from(100u32); - let drep_registration_1 = DrepRegistration::new(&cred_key_hash, &coin); + let drep_registration_1 = DRepRegistration::new(&cred_key_hash, &coin); let anchor = fake_anchor(); - let drep_registration_2 = DrepRegistration::new_with_anchor(&cred_script_hash, &coin, &anchor); + let drep_registration_2 = DRepRegistration::new_with_anchor(&cred_script_hash, &coin, &anchor); assert_eq!(drep_registration_1.voting_credential(), cred_key_hash); assert_eq!(drep_registration_1.coin(), coin); @@ -76,10 +76,10 @@ fn drep_registration_setters_getters_test() { fn drep_update_setters_getters_test() { let cred_key_hash = Credential::from_keyhash(&fake_key_hash(1)); let cred_script_hash = Credential::from_scripthash(&fake_script_hash(2)); - let drep_update_1 = DrepUpdate::new(&cred_key_hash); + let drep_update_1 = DRepUpdate::new(&cred_key_hash); let anchor = fake_anchor(); - let drep_update_2 = DrepUpdate::new_with_anchor(&cred_script_hash, &anchor); + let drep_update_2 = DRepUpdate::new_with_anchor(&cred_script_hash, &anchor); assert_eq!(drep_update_1.voting_credential(), cred_key_hash); assert_eq!(drep_update_1.anchor(), None); diff --git a/rust/src/tests/protocol_types/protocol_param_update.rs b/rust/src/tests/protocol_types/protocol_param_update.rs index e114154c..903bf8bd 100644 --- a/rust/src/tests/protocol_types/protocol_param_update.rs +++ b/rust/src/tests/protocol_types/protocol_param_update.rs @@ -129,7 +129,7 @@ fn ppu_setters_getters_test() { assert_eq!(ppu.pool_voting_thresholds().unwrap(), pool_voting_thresholds); assert!(ppu.drep_voting_thresholds().is_none()); - let drep_voting_thresholds = DrepVotingThresholds::new( + let drep_voting_thresholds = DRepVotingThresholds::new( &UnitInterval::new(&BigNum::from(26u32), &BigNum::from(27u32)), &UnitInterval::new(&BigNum::from(28u32), &BigNum::from(29u32)), &UnitInterval::new(&BigNum::from(30u32), &BigNum::from(31u32)), @@ -223,8 +223,8 @@ fn drep_voting_thresholds_test() { let pp_governance_group = UnitInterval::new(&BigNum::from(9u32), &BigNum::from(100u32)); let treasury_withdrawal = UnitInterval::new(&BigNum::from(10u32), &BigNum::from(100u32)); - // Creating a new DrepVotingThresholds instance - let dvt = DrepVotingThresholds::new( + // Creating a new DRepVotingThresholds instance + let dvt = DRepVotingThresholds::new( &motion_no_confidence, &committee_normal, &committee_no_confidence, diff --git a/rust/src/tests/serialization/certificates.rs b/rust/src/tests/serialization/certificates.rs index e70edccc..404afaf9 100644 --- a/rust/src/tests/serialization/certificates.rs +++ b/rust/src/tests/serialization/certificates.rs @@ -81,12 +81,12 @@ fn committee_hot_auth_ser_round_trip() { #[test] fn drep_registration_ser_round_trip() { - let cert = DrepRegistration::new( + let cert = DRepRegistration::new( &Credential::from_keyhash(&fake_key_hash(1)), &Coin::from(100u64), ); let cert_wrapped = Certificate::new_drep_registration(&cert); - to_from_test!(DrepRegistration, cert, cert_wrapped); + to_from_test!(DRepRegistration, cert, cert_wrapped); assert_eq!(cert, cert_wrapped.as_drep_registration().unwrap()); } @@ -95,32 +95,32 @@ fn drep_registration_with_anchor_ser_round_trip() { let url = URL::new("https://iohk.io".to_string()).unwrap(); let anchor = Anchor::new(&url, &fake_anchor_data_hash(255)); - let cert = DrepRegistration::new_with_anchor( + let cert = DRepRegistration::new_with_anchor( &Credential::from_keyhash(&fake_key_hash(1)), &Coin::from(100u64), &anchor, ); let cert_wrapped = Certificate::new_drep_registration(&cert); - to_from_test!(DrepRegistration, cert, cert_wrapped); + to_from_test!(DRepRegistration, cert, cert_wrapped); assert_eq!(cert, cert_wrapped.as_drep_registration().unwrap()); } #[test] fn drep_deregistration_ser_round_trip() { - let cert = DrepDeregistration::new( + let cert = DRepDeregistration::new( &Credential::from_keyhash(&fake_key_hash(1)), &Coin::from(100u64), ); let cert_wrapped = Certificate::new_drep_deregistration(&cert); - to_from_test!(DrepDeregistration, cert, cert_wrapped); + to_from_test!(DRepDeregistration, cert, cert_wrapped); assert_eq!(cert, cert_wrapped.as_drep_deregistration().unwrap()); } #[test] fn drep_update_ser_round_trip() { - let cert = DrepUpdate::new(&Credential::from_keyhash(&fake_key_hash(1))); + let cert = DRepUpdate::new(&Credential::from_keyhash(&fake_key_hash(1))); let cert_wrapped = Certificate::new_drep_update(&cert); - to_from_test!(DrepUpdate, cert, cert_wrapped); + to_from_test!(DRepUpdate, cert, cert_wrapped); assert_eq!(cert, cert_wrapped.as_drep_update().unwrap()); } @@ -128,9 +128,9 @@ fn drep_update_ser_round_trip() { fn drep_update_with_anchor_ser_round_trip() { let url = URL::new("https://iohk.io".to_string()).unwrap(); let anchor = Anchor::new(&url, &fake_anchor_data_hash(255)); - let cert = DrepUpdate::new_with_anchor(&Credential::from_keyhash(&fake_key_hash(1)), &anchor); + let cert = DRepUpdate::new_with_anchor(&Credential::from_keyhash(&fake_key_hash(1)), &anchor); let cert_wrapped = Certificate::new_drep_update(&cert); - to_from_test!(DrepUpdate, cert, cert_wrapped); + to_from_test!(DRepUpdate, cert, cert_wrapped); assert_eq!(cert, cert_wrapped.as_drep_update().unwrap()); } diff --git a/rust/src/tests/serialization/protocol_param_update.rs b/rust/src/tests/serialization/protocol_param_update.rs index a3ba4454..cfc4daec 100644 --- a/rust/src/tests/serialization/protocol_param_update.rs +++ b/rust/src/tests/serialization/protocol_param_update.rs @@ -95,7 +95,7 @@ fn pool_voting_thresholds_ser_round_trip() { #[test] fn drep_voting_thresholds_ser_round_trip() { - let thresholds = DrepVotingThresholds::new( + let thresholds = DRepVotingThresholds::new( &UnitInterval::new(&BigNum::from(44_401u32), &BigNum::from(44_402u32)), &UnitInterval::new(&BigNum::from(44_403u32), &BigNum::from(44_404u32)), &UnitInterval::new(&BigNum::from(44_405u32), &BigNum::from(44_406u32)), @@ -112,9 +112,9 @@ fn drep_voting_thresholds_ser_round_trip() { let hex = thresholds.to_hex(); let json = thresholds.to_json().unwrap(); - let thresholds_from_cbor = DrepVotingThresholds::from_bytes(cbor).unwrap(); - let thresholds_from_hex = DrepVotingThresholds::from_hex(&hex).unwrap(); - let thresholds_from_json = DrepVotingThresholds::from_json(&json).unwrap(); + let thresholds_from_cbor = DRepVotingThresholds::from_bytes(cbor).unwrap(); + let thresholds_from_hex = DRepVotingThresholds::from_hex(&hex).unwrap(); + let thresholds_from_json = DRepVotingThresholds::from_json(&json).unwrap(); assert_eq!(thresholds, thresholds_from_cbor); assert_eq!(thresholds, thresholds_from_hex); diff --git a/rust/src/utils.rs b/rust/src/utils.rs index f94aba77..1b0804cf 100644 --- a/rust/src/utils.rs +++ b/rust/src/utils.rs @@ -655,7 +655,7 @@ pub fn internal_get_implicit_input( } } CertificateEnum::PoolRetirement(_) => acc.checked_add(&pool_deposit), - CertificateEnum::DrepDeregistration(cert) => acc.checked_add(&cert.coin), + CertificateEnum::DRepDeregistration(cert) => acc.checked_add(&cert.coin), _ => Ok(acc), })?, }; @@ -684,7 +684,7 @@ pub fn internal_get_deposit( acc.checked_add(&key_deposit) } } - CertificateEnum::DrepRegistration(cert) => acc.checked_add(&cert.coin), + CertificateEnum::DRepRegistration(cert) => acc.checked_add(&cert.coin), CertificateEnum::StakeRegistrationAndDelegation(cert) => { acc.checked_add(&cert.coin) } From 9c1de59d90c2986d2a10b8844fe7b1a61d6b1106 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 12 Aug 2024 22:09:47 +0900 Subject: [PATCH 333/349] update flow file --- rust/pkg/cardano_serialization_lib.js.flow | 883 +++++++++++++-------- 1 file changed, 537 insertions(+), 346 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index e7575efa..1f8fe79f 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -5,6 +5,30 @@ * @flow */ +/** + * @param {string} password + * @param {string} salt + * @param {string} nonce + * @param {string} data + * @returns {string} + */ +declare export function encrypt_with_password( + password: string, + salt: string, + nonce: string, + data: string +): string; + +/** + * @param {string} password + * @param {string} data + * @returns {string} + */ +declare export function decrypt_with_password( + password: string, + data: string +): string; + /** * @param {Transaction} tx * @param {LinearFee} linear_fee @@ -43,27 +67,27 @@ declare export function min_ref_script_fee( ): BigNum; /** - * @param {string} password - * @param {string} salt - * @param {string} nonce - * @param {string} data - * @returns {string} + * @param {string} json + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {PlutusData} */ -declare export function encrypt_with_password( - password: string, - salt: string, - nonce: string, - data: string -): string; +declare export function encode_json_str_to_plutus_datum( + json: string, + schema: $Values +): PlutusData; /** - * @param {string} password - * @param {string} data + * @param {PlutusData} datum + * @param {$Values< + typeof + PlutusDatumSchema>} schema * @returns {string} */ -declare export function decrypt_with_password( - password: string, - data: string +declare export function decode_plutus_datum_to_json_str( + datum: PlutusData, + schema: $Values ): string; /** @@ -231,30 +255,6 @@ declare export function encode_json_str_to_native_script( schema: $Values ): NativeScript; -/** - * @param {string} json - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {PlutusData} - */ -declare export function encode_json_str_to_plutus_datum( - json: string, - schema: $Values -): PlutusData; - -/** - * @param {PlutusData} datum - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {string} - */ -declare export function decode_plutus_datum_to_json_str( - datum: PlutusData, - schema: $Values -): string; - /** * @param {Address} address * @param {TransactionUnspentOutputs} utxos @@ -268,107 +268,94 @@ declare export function create_send_all( ): TransactionBatchList; /** - * JSON <-> PlutusData conversion schemas. - * Follows ScriptDataJsonSchema in cardano-cli defined at: - * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 - * - * All methods here have the following restrictions due to limitations on dependencies: - * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors - * * Hex strings for bytes don't accept odd-length (half-byte) strings. - * cardano-cli seems to support these however but it seems to be different than just 0-padding - * on either side when tested so proceed with caution + * Used to choosed the schema for a script JSON string */ -declare export var PlutusDatumSchema: {| - +BasicConversions: 0, // 0 - +DetailedSchema: 1, // 1 +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** + * Each new language uses a different namespace for hashing its script + * This is because you could have a language where the same bytes have different semantics + * So this avoids scripts in different languages mapping to the same hash + * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var GovernanceActionKind: {| - +ParameterChangeAction: 0, // 0 - +HardForkInitiationAction: 1, // 1 - +TreasuryWithdrawalsAction: 2, // 2 - +NoConfidenceAction: 3, // 3 - +UpdateCommitteeAction: 4, // 4 - +NewConstitutionAction: 5, // 5 - +InfoAction: 6, // 6 +declare export var ScriptHashNamespace: {| + +NativeScript: 0, // 0 + +PlutusScript: 1, // 1 + +PlutusScriptV2: 2, // 2 + +PlutusScriptV3: 3, // 3 |}; /** */ -declare export var AddressKind: {| - +Base: 0, // 0 - +Pointer: 1, // 1 - +Enterprise: 2, // 2 +declare export var RedeemerTagKind: {| + +Spend: 0, // 0 + +Mint: 1, // 1 + +Cert: 2, // 2 +Reward: 3, // 3 - +Byron: 4, // 4 - +Malformed: 5, // 5 -|}; - -/** - */ - -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 + +Vote: 4, // 4 + +VotingProposal: 5, // 5 |}; /** */ -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 |}; /** + * JSON <-> PlutusData conversion schemas. + * Follows ScriptDataJsonSchema in cardano-cli defined at: + * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 + * + * All methods here have the following restrictions due to limitations on dependencies: + * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors + * * Hex strings for bytes don't accept odd-length (half-byte) strings. + * cardano-cli seems to support these however but it seems to be different than just 0-padding + * on either side when tested so proceed with caution */ -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 +declare export var PlutusDatumSchema: {| + +BasicConversions: 0, // 0 + +DetailedSchema: 1, // 1 |}; /** */ -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 |}; /** */ -declare export var BlockEra: {| - +Byron: 0, // 0 - +Shelley: 1, // 1 - +Allegra: 2, // 2 - +Mary: 3, // 3 - +Alonzo: 4, // 4 - +Babbage: 5, // 5 - +Conway: 6, // 6 - +Unknown: 7, // 7 +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 |}; /** */ -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 +declare export var CborContainerType: {| + +Array: 0, // 0 +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 |}; /** @@ -384,9 +371,9 @@ declare export var CertificateKind: {| +MoveInstantaneousRewardsCert: 6, // 6 +CommitteeHotAuth: 7, // 7 +CommitteeColdResign: 8, // 8 - +DrepDeregistration: 9, // 9 - +DrepRegistration: 10, // 10 - +DrepUpdate: 11, // 11 + +DRepDeregistration: 9, // 9 + +DRepRegistration: 10, // 10 + +DRepUpdate: 11, // 11 +StakeAndVoteDelegation: 12, // 12 +StakeRegistrationAndDelegation: 13, // 13 +StakeVoteRegistrationAndDelegation: 14, // 14 @@ -397,129 +384,142 @@ declare export var CertificateKind: {| /** */ -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 |}; /** */ -declare export var LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** */ -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 |}; /** */ -declare export var RelayKind: {| - +SingleHostAddr: 0, // 0 - +SingleHostName: 1, // 1 - +MultiHostName: 2, // 2 +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** */ -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 |}; /** */ -declare export var RedeemerTagKind: {| - +Spend: 0, // 0 - +Mint: 1, // 1 - +Cert: 2, // 2 - +Reward: 3, // 3 - +Vote: 4, // 4 - +VotingProposal: 5, // 5 +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 |}; /** - * Used to choosed the schema for a script JSON string */ -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 +declare export var RelayKind: {| + +SingleHostAddr: 0, // 0 + +SingleHostName: 1, // 1 + +MultiHostName: 2, // 2 |}; /** - * Each new language uses a different namespace for hashing its script - * This is because you could have a language where the same bytes have different semantics - * So this avoids scripts in different languages mapping to the same hash - * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var ScriptHashNamespace: {| - +NativeScript: 0, // 0 - +PlutusScript: 1, // 1 - +PlutusScriptV2: 2, // 2 - +PlutusScriptV3: 3, // 3 +declare export var BlockEra: {| + +Byron: 0, // 0 + +Shelley: 1, // 1 + +Allegra: 2, // 2 + +Mary: 3, // 3 + +Alonzo: 4, // 4 + +Babbage: 5, // 5 + +Conway: 6, // 6 + +Unknown: 7, // 7 |}; /** */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 +declare export var GovernanceActionKind: {| + +ParameterChangeAction: 0, // 0 + +HardForkInitiationAction: 1, // 1 + +TreasuryWithdrawalsAction: 2, // 2 + +NoConfidenceAction: 3, // 3 + +UpdateCommitteeAction: 4, // 4 + +NewConstitutionAction: 5, // 5 + +InfoAction: 6, // 6 |}; /** */ -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 |}; /** */ -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 +declare export var AddressKind: {| + +Base: 0, // 0 + +Pointer: 1, // 1 + +Enterprise: 2, // 2 + +Reward: 3, // 3 + +Byron: 4, // 4 + +Malformed: 5, // 5 |}; /** */ -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 |}; /** */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 +|}; + +/** + */ + +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 |}; /** @@ -1917,6 +1917,15 @@ declare export class Certificate { stake_registration: StakeRegistration ): Certificate; + /** + * Since StakeRegistration can represent stake_registration certificate or reg_cert certificate, because both certificates have the same semantics. + * And in some cases you want to create a reg_cert, this function is used to create a reg_cert. + * The function will return an error if StakeRegistration represents a stake_registration certificate. + * @param {StakeRegistration} stake_registration + * @returns {Certificate} + */ + static new_reg_cert(stake_registration: StakeRegistration): Certificate; + /** * @param {StakeDeregistration} stake_deregistration * @returns {Certificate} @@ -1925,6 +1934,15 @@ declare export class Certificate { stake_deregistration: StakeDeregistration ): Certificate; + /** + * Since StakeDeregistration can represent stake_deregistration certificate or unreg_cert certificate, because both certificates have the same semantics. + * And in some cases you want to create an unreg_cert, this function is used to create an unreg_cert. + * The function will return an error if StakeDeregistration represents a stake_deregistration certificate. + * @param {StakeDeregistration} stake_deregistration + * @returns {Certificate} + */ + static new_unreg_cert(stake_deregistration: StakeDeregistration): Certificate; + /** * @param {StakeDelegation} stake_delegation * @returns {Certificate} @@ -1978,26 +1996,26 @@ declare export class Certificate { ): Certificate; /** - * @param {DrepDeregistration} drep_deregistration + * @param {DRepDeregistration} drep_deregistration * @returns {Certificate} */ static new_drep_deregistration( - drep_deregistration: DrepDeregistration + drep_deregistration: DRepDeregistration ): Certificate; /** - * @param {DrepRegistration} drep_registration + * @param {DRepRegistration} drep_registration * @returns {Certificate} */ static new_drep_registration( - drep_registration: DrepRegistration + drep_registration: DRepRegistration ): Certificate; /** - * @param {DrepUpdate} drep_update + * @param {DRepUpdate} drep_update * @returns {Certificate} */ - static new_drep_update(drep_update: DrepUpdate): Certificate; + static new_drep_update(drep_update: DRepUpdate): Certificate; /** * @param {StakeAndVoteDelegation} stake_and_vote_delegation @@ -2049,11 +2067,27 @@ declare export class Certificate { */ as_stake_registration(): StakeRegistration | void; + /** + * Since StakeRegistration can represent stake_registration certificate or reg_cert certificate, because both certificates have the same semantics. + * And in some cases you want to get a reg_cert, this function is used to get a reg_cert. + * The function will return None if StakeRegistration represents a stake_registration certificate or Certificate is not a StakeRegistration. + * @returns {StakeRegistration | void} + */ + as_reg_cert(): StakeRegistration | void; + /** * @returns {StakeDeregistration | void} */ as_stake_deregistration(): StakeDeregistration | void; + /** + * Since StakeDeregistration can represent stake_deregistration certificate or unreg_cert certificate, because both certificates have the same semantics. + * And in some cases you want to get an unreg_cert, this function is used to get an unreg_cert. + * The function will return None if StakeDeregistration represents a stake_deregistration certificate or Certificate is not a StakeDeregistration. + * @returns {StakeDeregistration | void} + */ + as_unreg_cert(): StakeDeregistration | void; + /** * @returns {StakeDelegation | void} */ @@ -2090,19 +2124,19 @@ declare export class Certificate { as_committee_cold_resign(): CommitteeColdResign | void; /** - * @returns {DrepDeregistration | void} + * @returns {DRepDeregistration | void} */ - as_drep_deregistration(): DrepDeregistration | void; + as_drep_deregistration(): DRepDeregistration | void; /** - * @returns {DrepRegistration | void} + * @returns {DRepRegistration | void} */ - as_drep_registration(): DrepRegistration | void; + as_drep_registration(): DRepRegistration | void; /** - * @returns {DrepUpdate | void} + * @returns {DRepUpdate | void} */ - as_drep_update(): DrepUpdate | void; + as_drep_update(): DRepUpdate | void; /** * @returns {StakeAndVoteDelegation | void} @@ -3064,140 +3098,68 @@ declare export class DRep { /** * @param {string} json * @returns {DRep} - */ - static from_json(json: string): DRep; - - /** - * @param {Ed25519KeyHash} key_hash - * @returns {DRep} - */ - static new_key_hash(key_hash: Ed25519KeyHash): DRep; - - /** - * @param {ScriptHash} script_hash - * @returns {DRep} - */ - static new_script_hash(script_hash: ScriptHash): DRep; - - /** - * @returns {DRep} - */ - static new_always_abstain(): DRep; - - /** - * @returns {DRep} - */ - static new_always_no_confidence(): DRep; - - /** - * @param {Credential} cred - * @returns {DRep} - */ - static new_from_credential(cred: Credential): DRep; - - /** - * @returns {$Values< - typeof - DRepKind>} - */ - kind(): $Values; - - /** - * @returns {Ed25519KeyHash | void} - */ - to_key_hash(): Ed25519KeyHash | void; - - /** - * @returns {ScriptHash | void} - */ - to_script_hash(): ScriptHash | void; - - /** - * @returns {string} - */ - to_bech32(): string; - - /** - * @param {string} bech32_str - * @returns {DRep} - */ - static from_bech32(bech32_str: string): DRep; -} -/** - */ -declare export class DataCost { - free(): void; + */ + static from_json(json: string): DRep; /** - * @param {BigNum} coins_per_byte - * @returns {DataCost} + * @param {Ed25519KeyHash} key_hash + * @returns {DRep} */ - static new_coins_per_byte(coins_per_byte: BigNum): DataCost; + static new_key_hash(key_hash: Ed25519KeyHash): DRep; /** - * @returns {BigNum} + * @param {ScriptHash} script_hash + * @returns {DRep} */ - coins_per_byte(): BigNum; -} -/** - */ -declare export class DataHash { - free(): void; + static new_script_hash(script_hash: ScriptHash): DRep; /** - * @param {Uint8Array} bytes - * @returns {DataHash} + * @returns {DRep} */ - static from_bytes(bytes: Uint8Array): DataHash; + static new_always_abstain(): DRep; /** - * @returns {Uint8Array} + * @returns {DRep} */ - to_bytes(): Uint8Array; + static new_always_no_confidence(): DRep; /** - * @param {string} prefix - * @returns {string} + * @param {Credential} cred + * @returns {DRep} */ - to_bech32(prefix: string): string; + static new_from_credential(cred: Credential): DRep; /** - * @param {string} bech_str - * @returns {DataHash} - */ - static from_bech32(bech_str: string): DataHash; + * @returns {$Values< + typeof + DRepKind>} + */ + kind(): $Values; /** - * @returns {string} + * @returns {Ed25519KeyHash | void} */ - to_hex(): string; + to_key_hash(): Ed25519KeyHash | void; /** - * @param {string} hex - * @returns {DataHash} + * @returns {ScriptHash | void} */ - static from_hex(hex: string): DataHash; -} -/** - */ -declare export class DatumSource { - free(): void; + to_script_hash(): ScriptHash | void; /** - * @param {PlutusData} datum - * @returns {DatumSource} + * @returns {string} */ - static new(datum: PlutusData): DatumSource; + to_bech32(): string; /** - * @param {TransactionInput} input - * @returns {DatumSource} + * @param {string} bech32_str + * @returns {DRep} */ - static new_ref_input(input: TransactionInput): DatumSource; + static from_bech32(bech32_str: string): DRep; } /** */ -declare export class DrepDeregistration { +declare export class DRepDeregistration { free(): void; /** @@ -3207,9 +3169,9 @@ declare export class DrepDeregistration { /** * @param {Uint8Array} bytes - * @returns {DrepDeregistration} + * @returns {DRepDeregistration} */ - static from_bytes(bytes: Uint8Array): DrepDeregistration; + static from_bytes(bytes: Uint8Array): DRepDeregistration; /** * @returns {string} @@ -3218,9 +3180,9 @@ declare export class DrepDeregistration { /** * @param {string} hex_str - * @returns {DrepDeregistration} + * @returns {DRepDeregistration} */ - static from_hex(hex_str: string): DrepDeregistration; + static from_hex(hex_str: string): DRepDeregistration; /** * @returns {string} @@ -3228,15 +3190,15 @@ declare export class DrepDeregistration { to_json(): string; /** - * @returns {DrepDeregistrationJSON} + * @returns {DRepDeregistrationJSON} */ - to_js_value(): DrepDeregistrationJSON; + to_js_value(): DRepDeregistrationJSON; /** * @param {string} json - * @returns {DrepDeregistration} + * @returns {DRepDeregistration} */ - static from_json(json: string): DrepDeregistration; + static from_json(json: string): DRepDeregistration; /** * @returns {Credential} @@ -3251,9 +3213,9 @@ declare export class DrepDeregistration { /** * @param {Credential} voting_credential * @param {BigNum} coin - * @returns {DrepDeregistration} + * @returns {DRepDeregistration} */ - static new(voting_credential: Credential, coin: BigNum): DrepDeregistration; + static new(voting_credential: Credential, coin: BigNum): DRepDeregistration; /** * @returns {boolean} @@ -3262,7 +3224,7 @@ declare export class DrepDeregistration { } /** */ -declare export class DrepRegistration { +declare export class DRepRegistration { free(): void; /** @@ -3272,9 +3234,9 @@ declare export class DrepRegistration { /** * @param {Uint8Array} bytes - * @returns {DrepRegistration} + * @returns {DRepRegistration} */ - static from_bytes(bytes: Uint8Array): DrepRegistration; + static from_bytes(bytes: Uint8Array): DRepRegistration; /** * @returns {string} @@ -3283,9 +3245,9 @@ declare export class DrepRegistration { /** * @param {string} hex_str - * @returns {DrepRegistration} + * @returns {DRepRegistration} */ - static from_hex(hex_str: string): DrepRegistration; + static from_hex(hex_str: string): DRepRegistration; /** * @returns {string} @@ -3293,15 +3255,15 @@ declare export class DrepRegistration { to_json(): string; /** - * @returns {DrepRegistrationJSON} + * @returns {DRepRegistrationJSON} */ - to_js_value(): DrepRegistrationJSON; + to_js_value(): DRepRegistrationJSON; /** * @param {string} json - * @returns {DrepRegistration} + * @returns {DRepRegistration} */ - static from_json(json: string): DrepRegistration; + static from_json(json: string): DRepRegistration; /** * @returns {Credential} @@ -3321,21 +3283,21 @@ declare export class DrepRegistration { /** * @param {Credential} voting_credential * @param {BigNum} coin - * @returns {DrepRegistration} + * @returns {DRepRegistration} */ - static new(voting_credential: Credential, coin: BigNum): DrepRegistration; + static new(voting_credential: Credential, coin: BigNum): DRepRegistration; /** * @param {Credential} voting_credential * @param {BigNum} coin * @param {Anchor} anchor - * @returns {DrepRegistration} + * @returns {DRepRegistration} */ static new_with_anchor( voting_credential: Credential, coin: BigNum, anchor: Anchor - ): DrepRegistration; + ): DRepRegistration; /** * @returns {boolean} @@ -3344,7 +3306,7 @@ declare export class DrepRegistration { } /** */ -declare export class DrepUpdate { +declare export class DRepUpdate { free(): void; /** @@ -3354,9 +3316,9 @@ declare export class DrepUpdate { /** * @param {Uint8Array} bytes - * @returns {DrepUpdate} + * @returns {DRepUpdate} */ - static from_bytes(bytes: Uint8Array): DrepUpdate; + static from_bytes(bytes: Uint8Array): DRepUpdate; /** * @returns {string} @@ -3365,9 +3327,9 @@ declare export class DrepUpdate { /** * @param {string} hex_str - * @returns {DrepUpdate} + * @returns {DRepUpdate} */ - static from_hex(hex_str: string): DrepUpdate; + static from_hex(hex_str: string): DRepUpdate; /** * @returns {string} @@ -3375,15 +3337,15 @@ declare export class DrepUpdate { to_json(): string; /** - * @returns {DrepUpdateJSON} + * @returns {DRepUpdateJSON} */ - to_js_value(): DrepUpdateJSON; + to_js_value(): DRepUpdateJSON; /** * @param {string} json - * @returns {DrepUpdate} + * @returns {DRepUpdate} */ - static from_json(json: string): DrepUpdate; + static from_json(json: string): DRepUpdate; /** * @returns {Credential} @@ -3397,19 +3359,19 @@ declare export class DrepUpdate { /** * @param {Credential} voting_credential - * @returns {DrepUpdate} + * @returns {DRepUpdate} */ - static new(voting_credential: Credential): DrepUpdate; + static new(voting_credential: Credential): DRepUpdate; /** * @param {Credential} voting_credential * @param {Anchor} anchor - * @returns {DrepUpdate} + * @returns {DRepUpdate} */ static new_with_anchor( voting_credential: Credential, anchor: Anchor - ): DrepUpdate; + ): DRepUpdate; /** * @returns {boolean} @@ -3418,7 +3380,7 @@ declare export class DrepUpdate { } /** */ -declare export class DrepVotingThresholds { +declare export class DRepVotingThresholds { free(): void; /** @@ -3428,9 +3390,9 @@ declare export class DrepVotingThresholds { /** * @param {Uint8Array} bytes - * @returns {DrepVotingThresholds} + * @returns {DRepVotingThresholds} */ - static from_bytes(bytes: Uint8Array): DrepVotingThresholds; + static from_bytes(bytes: Uint8Array): DRepVotingThresholds; /** * @returns {string} @@ -3439,9 +3401,9 @@ declare export class DrepVotingThresholds { /** * @param {string} hex_str - * @returns {DrepVotingThresholds} + * @returns {DRepVotingThresholds} */ - static from_hex(hex_str: string): DrepVotingThresholds; + static from_hex(hex_str: string): DRepVotingThresholds; /** * @returns {string} @@ -3449,15 +3411,15 @@ declare export class DrepVotingThresholds { to_json(): string; /** - * @returns {DrepVotingThresholdsJSON} + * @returns {DRepVotingThresholdsJSON} */ - to_js_value(): DrepVotingThresholdsJSON; + to_js_value(): DRepVotingThresholdsJSON; /** * @param {string} json - * @returns {DrepVotingThresholds} + * @returns {DRepVotingThresholds} */ - static from_json(json: string): DrepVotingThresholds; + static from_json(json: string): DRepVotingThresholds; /** * @param {UnitInterval} motion_no_confidence @@ -3470,7 +3432,7 @@ declare export class DrepVotingThresholds { * @param {UnitInterval} pp_technical_group * @param {UnitInterval} pp_governance_group * @param {UnitInterval} treasury_withdrawal - * @returns {DrepVotingThresholds} + * @returns {DRepVotingThresholds} */ static new( motion_no_confidence: UnitInterval, @@ -3483,7 +3445,7 @@ declare export class DrepVotingThresholds { pp_technical_group: UnitInterval, pp_governance_group: UnitInterval, treasury_withdrawal: UnitInterval - ): DrepVotingThresholds; + ): DRepVotingThresholds; /** * @param {UnitInterval} motion_no_confidence @@ -3585,6 +3547,78 @@ declare export class DrepVotingThresholds { */ treasury_withdrawal(): UnitInterval; } +/** + */ +declare export class DataCost { + free(): void; + + /** + * @param {BigNum} coins_per_byte + * @returns {DataCost} + */ + static new_coins_per_byte(coins_per_byte: BigNum): DataCost; + + /** + * @returns {BigNum} + */ + coins_per_byte(): BigNum; +} +/** + */ +declare export class DataHash { + free(): void; + + /** + * @param {Uint8Array} bytes + * @returns {DataHash} + */ + static from_bytes(bytes: Uint8Array): DataHash; + + /** + * @returns {Uint8Array} + */ + to_bytes(): Uint8Array; + + /** + * @param {string} prefix + * @returns {string} + */ + to_bech32(prefix: string): string; + + /** + * @param {string} bech_str + * @returns {DataHash} + */ + static from_bech32(bech_str: string): DataHash; + + /** + * @returns {string} + */ + to_hex(): string; + + /** + * @param {string} hex + * @returns {DataHash} + */ + static from_hex(hex: string): DataHash; +} +/** + */ +declare export class DatumSource { + free(): void; + + /** + * @param {PlutusData} datum + * @returns {DatumSource} + */ + static new(datum: PlutusData): DatumSource; + + /** + * @param {TransactionInput} input + * @returns {DatumSource} + */ + static new_ref_input(input: TransactionInput): DatumSource; +} /** */ declare export class Ed25519KeyHash { @@ -3893,6 +3927,55 @@ declare export class ExUnits { */ static new(mem: BigNum, steps: BigNum): ExUnits; } +/** + * Read only view of a block with more strict structs for hash sensitive structs. + * Warning: This is experimental and may be removed or changed in the future. + */ +declare export class FixedBlock { + free(): void; + + /** + * @param {Uint8Array} bytes + * @returns {FixedBlock} + */ + static from_bytes(bytes: Uint8Array): FixedBlock; + + /** + * @param {string} hex_str + * @returns {FixedBlock} + */ + static from_hex(hex_str: string): FixedBlock; + + /** + * @returns {Header} + */ + header(): Header; + + /** + * @returns {FixedTransactionBodies} + */ + transaction_bodies(): FixedTransactionBodies; + + /** + * @returns {TransactionWitnessSets} + */ + transaction_witness_sets(): TransactionWitnessSets; + + /** + * @returns {AuxiliaryDataSet} + */ + auxiliary_data_set(): AuxiliaryDataSet; + + /** + * @returns {Uint32Array} + */ + invalid_transactions(): Uint32Array; + + /** + * @returns {BlockHash} + */ + block_hash(): BlockHash; +} /** */ declare export class FixedTransaction { @@ -4001,6 +4084,109 @@ declare export class FixedTransaction { */ raw_auxiliary_data(): Uint8Array | void; } +/** + * Warning: This is experimental and may be removed or changed in the future. + */ +declare export class FixedTransactionBodies { + free(): void; + + /** + * @param {Uint8Array} bytes + * @returns {FixedTransactionBodies} + */ + static from_bytes(bytes: Uint8Array): FixedTransactionBodies; + + /** + * @param {string} hex_str + * @returns {FixedTransactionBodies} + */ + static from_hex(hex_str: string): FixedTransactionBodies; + + /** + * @returns {FixedTransactionBodies} + */ + static new(): FixedTransactionBodies; + + /** + * @returns {number} + */ + len(): number; + + /** + * @param {number} index + * @returns {FixedTransactionBody} + */ + get(index: number): FixedTransactionBody; + + /** + * @param {FixedTransactionBody} elem + */ + add(elem: FixedTransactionBody): void; +} +/** + * Read-only view of a transaction body. With correct hash and original bytes. + * Warning: This is experimental and may be removed in the future. + */ +declare export class FixedTransactionBody { + free(): void; + + /** + * @param {Uint8Array} bytes + * @returns {FixedTransactionBody} + */ + static from_bytes(bytes: Uint8Array): FixedTransactionBody; + + /** + * @param {string} hex_str + * @returns {FixedTransactionBody} + */ + static from_hex(hex_str: string): FixedTransactionBody; + + /** + * @returns {TransactionBody} + */ + transaction_body(): TransactionBody; + + /** + * @returns {TransactionHash} + */ + tx_hash(): TransactionHash; + + /** + * @returns {Uint8Array} + */ + original_bytes(): Uint8Array; +} +/** + * Warning: This is experimental and may be removed in the future. + */ +declare export class FixedVersionedBlock { + free(): void; + + /** + * @param {Uint8Array} bytes + * @returns {FixedVersionedBlock} + */ + static from_bytes(bytes: Uint8Array): FixedVersionedBlock; + + /** + * @param {string} hex_str + * @returns {FixedVersionedBlock} + */ + static from_hex(hex_str: string): FixedVersionedBlock; + + /** + * @returns {FixedBlock} + */ + block(): FixedBlock; + + /** + * @returns {$Values< + typeof + BlockEra>} + */ + era(): $Values; +} /** */ declare export class GeneralTransactionMetadata { @@ -8309,16 +8495,16 @@ declare export class ProtocolParamUpdate { pool_voting_thresholds(): PoolVotingThresholds | void; /** - * @param {DrepVotingThresholds} drep_voting_thresholds + * @param {DRepVotingThresholds} drep_voting_thresholds */ set_drep_voting_thresholds( - drep_voting_thresholds: DrepVotingThresholds + drep_voting_thresholds: DRepVotingThresholds ): void; /** - * @returns {DrepVotingThresholds | void} + * @returns {DRepVotingThresholds | void} */ - drep_voting_thresholds(): DrepVotingThresholds | void; + drep_voting_thresholds(): DRepVotingThresholds | void; /** * @param {number} min_committee_size @@ -9788,7 +9974,7 @@ declare export class StakeDeregistration { * @param {BigNum} coin * @returns {StakeDeregistration} */ - static new_with_coin( + static new_with_explicit_refund( stake_credential: Credential, coin: BigNum ): StakeDeregistration; @@ -9862,7 +10048,7 @@ declare export class StakeRegistration { * @param {BigNum} coin * @returns {StakeRegistration} */ - static new_with_coin( + static new_with_explicit_deposit( stake_credential: Credential, coin: BigNum ): StakeRegistration; @@ -12369,6 +12555,11 @@ declare export class TxBuilderConstants { * @returns {Costmdls} */ static plutus_vasil_cost_models(): Costmdls; + + /** + * @returns {Costmdls} + */ + static plutus_conway_cost_models(): Costmdls; } /** */ @@ -14223,15 +14414,15 @@ export type CertificateJSON = ... } | { - DrepDeregistration: DrepDeregistrationJSON, + DRepDeregistration: DRepDeregistrationJSON, ... } | { - DrepRegistration: DrepRegistrationJSON, + DRepRegistration: DRepRegistrationJSON, ... } | { - DrepUpdate: DrepUpdateJSON, + DRepUpdate: DRepUpdateJSON, ... } | { @@ -14543,16 +14734,16 @@ export interface CommitteeColdResignJSON { anchor?: AnchorJSON | null; committee_cold_key: CredTypeJSON; } -export interface DrepDeregistrationJSON { +export interface DRepDeregistrationJSON { coin: string; voting_credential: CredTypeJSON; } -export interface DrepRegistrationJSON { +export interface DRepRegistrationJSON { anchor?: AnchorJSON | null; coin: string; voting_credential: CredTypeJSON; } -export interface DrepUpdateJSON { +export interface DRepUpdateJSON { anchor?: AnchorJSON | null; voting_credential: CredTypeJSON; } @@ -14615,7 +14806,7 @@ export interface ProtocolParamUpdateJSON { d?: UnitIntervalJSON | null; drep_deposit?: string | null; drep_inactivity_period?: number | null; - drep_voting_thresholds?: DrepVotingThresholdsJSON | null; + drep_voting_thresholds?: DRepVotingThresholdsJSON | null; execution_costs?: ExUnitPricesJSON | null; expansion_rate?: UnitIntervalJSON | null; extra_entropy?: NonceJSON | null; @@ -14645,7 +14836,7 @@ export interface ProtocolParamUpdateJSON { export interface CostmdlsJSON { [k: string]: CostModelJSON; } -export interface DrepVotingThresholdsJSON { +export interface DRepVotingThresholdsJSON { committee_no_confidence: UnitIntervalJSON; committee_normal: UnitIntervalJSON; hard_fork_initiation: UnitIntervalJSON; @@ -14844,15 +15035,15 @@ export type CertificateEnumJSON = ... } | { - DrepDeregistration: DrepDeregistrationJSON, + DRepDeregistration: DRepDeregistrationJSON, ... } | { - DrepRegistration: DrepRegistrationJSON, + DRepRegistration: DRepRegistrationJSON, ... } | { - DrepUpdate: DrepUpdateJSON, + DRepUpdate: DRepUpdateJSON, ... } | { From 1155ade510bc0285a88c9ede879ebfa1bdadfe40 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 13 Aug 2024 23:46:31 +0900 Subject: [PATCH 334/349] fix coin selection to have at least one input --- rust/src/builders/tx_builder.rs | 73 +++++++++++++-------- rust/src/builders/tx_inputs_builder.rs | 4 ++ rust/src/tests/builders/tx_builder.rs | 89 ++++++++++++++++++++++++++ 3 files changed, 139 insertions(+), 27 deletions(-) diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index fb5978b6..2e1157fb 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -380,11 +380,28 @@ impl TransactionBuilder { inputs: &TransactionUnspentOutputs, strategy: CoinSelectionStrategyCIP2, ) -> Result<(), JsError> { - let available_inputs = &inputs.0.clone(); + let mut available_inputs: Vec<&TransactionUnspentOutput> = inputs.0.iter().collect(); + let have_no_inputs_in_tx = !self.inputs.has_inputs(); let mut input_total = self.get_total_input()?; let mut output_total = self .get_total_output()? .checked_add(&Value::new(&self.min_fee()?))?; + + if (input_total.coin >= output_total.coin) && have_no_inputs_in_tx { + if available_inputs.is_empty() { + return Err(JsError::from_str("No inputs to add. Transaction should have at least one input")); + } + + //just add first input, to cover needs of one input + let input = available_inputs.pop().unwrap(); + self.add_regular_input( + &input.output.address, + &input.input, + &input.output.amount, + )?; + input_total = input_total.checked_add(&input.output.amount)?; + } + match strategy { CoinSelectionStrategyCIP2::LargestFirst => { if self @@ -396,7 +413,7 @@ impl TransactionBuilder { return Err(JsError::from_str("Multiasset values not supported by LargestFirst. Please use LargestFirstMultiAsset")); } self.cip2_largest_first_by( - available_inputs, + &available_inputs, &mut (0..available_inputs.len()).collect(), &mut input_total, &mut output_total, @@ -417,7 +434,7 @@ impl TransactionBuilder { let mut available_indices = (0..available_inputs.len()).collect::>(); self.cip2_random_improve_by( - available_inputs, + &available_inputs, &mut available_indices, &mut input_total, &mut output_total, @@ -460,7 +477,7 @@ impl TransactionBuilder { for (policy_id, assets) in ma.0.iter() { for (asset_name, _) in assets.0.iter() { self.cip2_largest_first_by( - available_inputs, + &available_inputs, &mut available_indices, &mut input_total, &mut output_total, @@ -471,7 +488,7 @@ impl TransactionBuilder { } // add in remaining ADA self.cip2_largest_first_by( - available_inputs, + &available_inputs, &mut available_indices, &mut input_total, &mut output_total, @@ -488,7 +505,7 @@ impl TransactionBuilder { for (policy_id, assets) in ma.0.iter() { for (asset_name, _) in assets.0.iter() { self.cip2_random_improve_by( - available_inputs, + &available_inputs, &mut available_indices, &mut input_total, &mut output_total, @@ -501,7 +518,7 @@ impl TransactionBuilder { } // add in remaining ADA self.cip2_random_improve_by( - available_inputs, + &available_inputs, &mut available_indices, &mut input_total, &mut output_total, @@ -543,7 +560,7 @@ impl TransactionBuilder { fn cip2_largest_first_by( &mut self, - available_inputs: &Vec, + available_inputs: &Vec<&TransactionUnspentOutput>, available_indices: &mut Vec, input_total: &mut Value, output_total: &mut Value, @@ -586,7 +603,7 @@ impl TransactionBuilder { fn cip2_random_improve_by( &mut self, - available_inputs: &Vec, + available_inputs: &Vec<&TransactionUnspentOutput>, available_indices: &mut BTreeSet, input_total: &mut Value, output_total: &mut Value, @@ -654,24 +671,26 @@ impl TransactionBuilder { if !relevant_indices.is_empty() && pure_ada { // Phase 2: Improvement for output in outputs.iter_mut() { - let associated = associated_indices.get_mut(output).unwrap(); - for i in associated.iter_mut() { - let random_index = rng.gen_range(0..relevant_indices.len()); - let j: &mut usize = relevant_indices.get_mut(random_index).unwrap(); - let input = &available_inputs[*i]; - let new_input = &available_inputs[*j]; - let cur: u64 = (&by(&input.output.amount).unwrap_or(BigNum::zero())).into(); - let new: u64 = (&by(&new_input.output.amount).unwrap_or(BigNum::zero())).into(); - let min: u64 = (&by(&output.amount).unwrap_or(BigNum::zero())).into(); - let ideal = 2 * min; - let max = 3 * min; - let move_closer = - (ideal as i128 - new as i128).abs() < (ideal as i128 - cur as i128).abs(); - let not_exceed_max = new < max; - if move_closer && not_exceed_max { - std::mem::swap(i, j); - available_indices.insert(*i); - available_indices.remove(j); + let associated = associated_indices.get_mut(output); + if let Some(associated) = associated { + for i in associated.iter_mut() { + let random_index = rng.gen_range(0..relevant_indices.len()); + let j: &mut usize = relevant_indices.get_mut(random_index).unwrap(); + let input = &available_inputs[*i]; + let new_input = &available_inputs[*j]; + let cur: u64 = (&by(&input.output.amount).unwrap_or(BigNum::zero())).into(); + let new: u64 = (&by(&new_input.output.amount).unwrap_or(BigNum::zero())).into(); + let min: u64 = (&by(&output.amount).unwrap_or(BigNum::zero())).into(); + let ideal = 2 * min; + let max = 3 * min; + let move_closer = + (ideal as i128 - new as i128).abs() < (ideal as i128 - cur as i128).abs(); + let not_exceed_max = new < max; + if move_closer && not_exceed_max { + std::mem::swap(i, j); + available_indices.insert(*i); + available_indices.remove(j); + } } } } diff --git a/rust/src/builders/tx_inputs_builder.rs b/rust/src/builders/tx_inputs_builder.rs index 8b40ab34..703d5529 100644 --- a/rust/src/builders/tx_inputs_builder.rs +++ b/rust/src/builders/tx_inputs_builder.rs @@ -335,6 +335,10 @@ impl TxInputsBuilder { self.into() } + pub(crate) fn has_inputs(&self) -> bool { + !self.inputs.is_empty() + } + fn insert_input_with_witness( &mut self, script_hash: &ScriptHash, diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index e46adc20..e22e8978 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -6130,3 +6130,92 @@ fn utxo_selection_with_collateral_return_error() { let change_res = tx_builder.add_inputs_from_and_change_with_collateral_return(&utxos, CoinSelectionStrategyCIP2::LargestFirstMultiAsset, &change_config, &collateral_percent); assert!(change_res.is_err()); } + + +#[test] +fn tx_builder_huge_implicit_input_coin_selection() { + // we have a = 1 to test increasing fees when more inputs are added + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(1, 0)); + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address( + &Address::from_bech32( + "addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z", + ) + .unwrap(), + ) + .next() + .unwrap() + .with_coin(&BigNum(10000)) + .build() + .unwrap(), + ) + .unwrap(); + let mut cert_builder = CertificatesBuilder::new(); + cert_builder + .add( + &Certificate::new_stake_deregistration(&StakeDeregistration::new_with_explicit_refund( + &Credential::from_keyhash(&fake_key_hash(1)), + &BigNum(9999999999), + )), + ) + .unwrap(); + + tx_builder.set_certs_builder(&cert_builder); + let mut available_inputs = TransactionUnspentOutputs::new(); + available_inputs.add(&make_input(0u8, Value::new(&BigNum(1500)))); + available_inputs.add(&make_input(1u8, Value::new(&BigNum(2000)))); + + let add_inputs_res = + tx_builder.add_inputs_from(&available_inputs, CoinSelectionStrategyCIP2::RandomImprove); + assert!(add_inputs_res.is_ok(), "{:?}", add_inputs_res.err()); + assert_eq!(tx_builder.inputs.len(), 1); + + let change_addr = + ByronAddress::from_base58("Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho") + .unwrap() + .to_address(); + let add_change_res = tx_builder.add_change_if_needed(&change_addr); + assert!(add_change_res.is_ok(), "{:?}", add_change_res.err()); + let tx_build_res = tx_builder.build(); + assert!(tx_build_res.is_ok(), "{:?}", tx_build_res.err()); +} + +#[test] +fn tx_builder_no_any_input_coin_selection() { + // we have a = 1 to test increasing fees when more inputs are added + let mut tx_builder = fake_tx_builder_with_fee(&fake_linear_fee(1, 0)); + tx_builder + .add_output( + &TransactionOutputBuilder::new() + .with_address( + &Address::from_bech32( + "addr1vyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqs6l44z", + ) + .unwrap(), + ) + .next() + .unwrap() + .with_coin(&BigNum(10000)) + .build() + .unwrap(), + ) + .unwrap(); + let mut cert_builder = CertificatesBuilder::new(); + cert_builder + .add( + &Certificate::new_stake_deregistration(&StakeDeregistration::new_with_explicit_refund( + &Credential::from_keyhash(&fake_key_hash(1)), + &BigNum(9999999999), + )), + ) + .unwrap(); + + tx_builder.set_certs_builder(&cert_builder); + let available_inputs = TransactionUnspentOutputs::new(); + + let add_inputs_res = + tx_builder.add_inputs_from(&available_inputs, CoinSelectionStrategyCIP2::RandomImprove); + assert!(add_inputs_res.is_err()); +} \ No newline at end of file From 539f23cde534ba45dd8ff8b4f5bd7a8cee3d4af9 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 13 Aug 2024 23:48:01 +0900 Subject: [PATCH 335/349] update flow file --- rust/pkg/cardano_serialization_lib.js.flow | 362 ++++++++++----------- 1 file changed, 181 insertions(+), 181 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 1f8fe79f..3db82730 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -5,67 +5,6 @@ * @flow */ -/** - * @param {string} password - * @param {string} salt - * @param {string} nonce - * @param {string} data - * @returns {string} - */ -declare export function encrypt_with_password( - password: string, - salt: string, - nonce: string, - data: string -): string; - -/** - * @param {string} password - * @param {string} data - * @returns {string} - */ -declare export function decrypt_with_password( - password: string, - data: string -): string; - -/** - * @param {Transaction} tx - * @param {LinearFee} linear_fee - * @returns {BigNum} - */ -declare export function min_fee(tx: Transaction, linear_fee: LinearFee): BigNum; - -/** - * @param {ExUnits} ex_units - * @param {ExUnitPrices} ex_unit_prices - * @returns {BigNum} - */ -declare export function calculate_ex_units_ceil_cost( - ex_units: ExUnits, - ex_unit_prices: ExUnitPrices -): BigNum; - -/** - * @param {Transaction} tx - * @param {ExUnitPrices} ex_unit_prices - * @returns {BigNum} - */ -declare export function min_script_fee( - tx: Transaction, - ex_unit_prices: ExUnitPrices -): BigNum; - -/** - * @param {number} total_ref_scripts_size - * @param {UnitInterval} ref_script_coins_per_byte - * @returns {BigNum} - */ -declare export function min_ref_script_fee( - total_ref_scripts_size: number, - ref_script_coins_per_byte: UnitInterval -): BigNum; - /** * @param {string} json * @param {$Values< @@ -255,6 +194,30 @@ declare export function encode_json_str_to_native_script( schema: $Values ): NativeScript; +/** + * @param {string} password + * @param {string} salt + * @param {string} nonce + * @param {string} data + * @returns {string} + */ +declare export function encrypt_with_password( + password: string, + salt: string, + nonce: string, + data: string +): string; + +/** + * @param {string} password + * @param {string} data + * @returns {string} + */ +declare export function decrypt_with_password( + password: string, + data: string +): string; + /** * @param {Address} address * @param {TransactionUnspentOutputs} utxos @@ -268,13 +231,41 @@ declare export function create_send_all( ): TransactionBatchList; /** - * Used to choosed the schema for a script JSON string + * @param {Transaction} tx + * @param {LinearFee} linear_fee + * @returns {BigNum} */ +declare export function min_fee(tx: Transaction, linear_fee: LinearFee): BigNum; -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 -|}; +/** + * @param {ExUnits} ex_units + * @param {ExUnitPrices} ex_unit_prices + * @returns {BigNum} + */ +declare export function calculate_ex_units_ceil_cost( + ex_units: ExUnits, + ex_unit_prices: ExUnitPrices +): BigNum; + +/** + * @param {Transaction} tx + * @param {ExUnitPrices} ex_unit_prices + * @returns {BigNum} + */ +declare export function min_script_fee( + tx: Transaction, + ex_unit_prices: ExUnitPrices +): BigNum; + +/** + * @param {number} total_ref_scripts_size + * @param {UnitInterval} ref_script_coins_per_byte + * @returns {BigNum} + */ +declare export function min_ref_script_fee( + total_ref_scripts_size: number, + ref_script_coins_per_byte: UnitInterval +): BigNum; /** * Each new language uses a different namespace for hashing its script @@ -293,119 +284,66 @@ declare export var ScriptHashNamespace: {| /** */ -declare export var RedeemerTagKind: {| - +Spend: 0, // 0 - +Mint: 1, // 1 - +Cert: 2, // 2 - +Reward: 3, // 3 - +Vote: 4, // 4 - +VotingProposal: 5, // 5 -|}; - -/** - */ - -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 -|}; - -/** - * JSON <-> PlutusData conversion schemas. - * Follows ScriptDataJsonSchema in cardano-cli defined at: - * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 - * - * All methods here have the following restrictions due to limitations on dependencies: - * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors - * * Hex strings for bytes don't accept odd-length (half-byte) strings. - * cardano-cli seems to support these however but it seems to be different than just 0-padding - * on either side when tested so proceed with caution - */ - -declare export var PlutusDatumSchema: {| - +BasicConversions: 0, // 0 - +DetailedSchema: 1, // 1 -|}; - -/** - */ - -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 |}; /** */ -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 +declare export var RelayKind: {| + +SingleHostAddr: 0, // 0 + +SingleHostName: 1, // 1 + +MultiHostName: 2, // 2 |}; /** */ -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** */ -declare export var CertificateKind: {| - +StakeRegistration: 0, // 0 - +StakeDeregistration: 1, // 1 - +StakeDelegation: 2, // 2 - +PoolRegistration: 3, // 3 - +PoolRetirement: 4, // 4 - +GenesisKeyDelegation: 5, // 5 - +MoveInstantaneousRewardsCert: 6, // 6 - +CommitteeHotAuth: 7, // 7 - +CommitteeColdResign: 8, // 8 - +DRepDeregistration: 9, // 9 - +DRepRegistration: 10, // 10 - +DRepUpdate: 11, // 11 - +StakeAndVoteDelegation: 12, // 12 - +StakeRegistrationAndDelegation: 13, // 13 - +StakeVoteRegistrationAndDelegation: 14, // 14 - +VoteDelegation: 15, // 15 - +VoteRegistrationAndDelegation: 16, // 16 +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 |}; /** */ -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 |}; /** + * Used to choosed the schema for a script JSON string */ -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** */ -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 |}; /** @@ -419,29 +357,28 @@ declare export var CredKind: {| /** */ -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 |}; /** */ -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 |}; /** */ -declare export var RelayKind: {| - +SingleHostAddr: 0, // 0 - +SingleHostName: 1, // 1 - +MultiHostName: 2, // 2 +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 |}; /** @@ -474,10 +411,45 @@ declare export var GovernanceActionKind: {| /** */ -declare export var LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 +declare export var CertificateKind: {| + +StakeRegistration: 0, // 0 + +StakeDeregistration: 1, // 1 + +StakeDelegation: 2, // 2 + +PoolRegistration: 3, // 3 + +PoolRetirement: 4, // 4 + +GenesisKeyDelegation: 5, // 5 + +MoveInstantaneousRewardsCert: 6, // 6 + +CommitteeHotAuth: 7, // 7 + +CommitteeColdResign: 8, // 8 + +DRepDeregistration: 9, // 9 + +DRepRegistration: 10, // 10 + +DRepUpdate: 11, // 11 + +StakeAndVoteDelegation: 12, // 12 + +StakeRegistrationAndDelegation: 13, // 13 + +StakeVoteRegistrationAndDelegation: 14, // 14 + +VoteDelegation: 15, // 15 + +VoteRegistrationAndDelegation: 16, // 16 +|}; + +/** + */ + +declare export var RedeemerTagKind: {| + +Spend: 0, // 0 + +Mint: 1, // 1 + +Cert: 2, // 2 + +Reward: 3, // 3 + +Vote: 4, // 4 + +VotingProposal: 5, // 5 +|}; + +/** + */ + +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 |}; /** @@ -495,31 +467,59 @@ declare export var AddressKind: {| /** */ -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 - +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 |}; /** */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 |}; /** */ -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 +|}; + +/** + */ + +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 +|}; + +/** + * JSON <-> PlutusData conversion schemas. + * Follows ScriptDataJsonSchema in cardano-cli defined at: + * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 + * + * All methods here have the following restrictions due to limitations on dependencies: + * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors + * * Hex strings for bytes don't accept odd-length (half-byte) strings. + * cardano-cli seems to support these however but it seems to be different than just 0-padding + * on either side when tested so proceed with caution + */ + +declare export var PlutusDatumSchema: {| + +BasicConversions: 0, // 0 + +DetailedSchema: 1, // 1 |}; /** From 479879bd6e02a8b448e173f202a8a1ea9bdd9d94 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 13 Aug 2024 23:49:25 +0900 Subject: [PATCH 336/349] version bump --- package-lock.json | 4 ++-- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7e88e493..8dad1cb1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.5", + "version": "12.0.0-beta.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.5", + "version": "12.0.0-beta.6", "hasInstallScript": true, "license": "MIT", "devDependencies": { diff --git a/package.json b/package.json index b33d7e4e..54af488c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.5", + "version": "12.0.0-beta.6", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index e18bb2c1..f1b3f22d 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-beta.5" +version = "12.0.0-beta.6" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index bd23e381..887ed588 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -49,7 +49,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-beta.5" +version = "12.0.0-beta.6" dependencies = [ "bech32", "cbor_event", From e47682cd09d18fe7b54e85e1f46c76f2195e0af1 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 14 Aug 2024 00:15:14 +0900 Subject: [PATCH 337/349] fix warnings --- rust/Cargo.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rust/Cargo.toml b/rust/Cargo.toml index f1b3f22d..2aec1bef 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -12,6 +12,13 @@ exclude = [ "pkg/*", ] +[features] +default = [] +#TODO: need to review the features and delete legacy ones. List is defined to avoid warnings. +property-test-api = [] +generic-serialization = [] +with-bench = [] + [lib] crate-type = ["cdylib", "rlib"] From 96f24672343b970f01c6d4d507020bd927042f62 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 16 Aug 2024 17:40:02 +0900 Subject: [PATCH 338/349] add ref inputs and tx inputs debuplication --- rust/src/builders/tx_builder.rs | 72 +++++--- rust/src/builders/tx_inputs_builder.rs | 4 + rust/src/tests/builders/tx_builder.rs | 219 ++++++++++++++++++++++++- 3 files changed, 275 insertions(+), 20 deletions(-) diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index 2e1157fb..d89e7384 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -183,6 +183,7 @@ pub struct TransactionBuilderConfig { pub(crate) ex_unit_prices: Option, // protocol parameter pub(crate) ref_script_coins_per_byte: Option, // protocol parameter pub(crate) prefer_pure_change: bool, + pub(crate) deduplicate_explicit_ref_inputs_with_regular_inputs: bool, } impl TransactionBuilderConfig { @@ -203,6 +204,7 @@ pub struct TransactionBuilderConfigBuilder { ex_unit_prices: Option, // protocol parameter ref_script_coins_per_byte: Option, // protocol parameter prefer_pure_change: bool, + deduplicate_explicit_ref_inputs_with_regular_inputs: bool, } #[wasm_bindgen] @@ -218,6 +220,7 @@ impl TransactionBuilderConfigBuilder { ex_unit_prices: None, ref_script_coins_per_byte: None, prefer_pure_change: false, + deduplicate_explicit_ref_inputs_with_regular_inputs: false, } } @@ -275,6 +278,13 @@ impl TransactionBuilderConfigBuilder { cfg } + ///Removes a ref input (that was set via set_reference_inputs) if the ref inputs was presented in regular tx inputs + pub fn deduplicate_explicit_ref_inputs_with_regular_inputs(&self, deduplicate_explicit_ref_inputs_with_regular_inputs: bool) -> Self { + let mut cfg = self.clone(); + cfg.deduplicate_explicit_ref_inputs_with_regular_inputs = deduplicate_explicit_ref_inputs_with_regular_inputs; + cfg + } + pub fn build(&self) -> Result { let cfg: Self = self.clone(); Ok(TransactionBuilderConfig { @@ -299,6 +309,7 @@ impl TransactionBuilderConfigBuilder { ex_unit_prices: cfg.ex_unit_prices, ref_script_coins_per_byte: cfg.ref_script_coins_per_byte, prefer_pure_change: cfg.prefer_pure_change, + deduplicate_explicit_ref_inputs_with_regular_inputs: cfg.deduplicate_explicit_ref_inputs_with_regular_inputs, }) } } @@ -1505,37 +1516,44 @@ impl TransactionBuilder { } pub fn get_reference_inputs(&self) -> TransactionInputs { - let mut inputs: HashSet = self.reference_inputs.keys().cloned().collect(); - for input in self.inputs.get_ref_inputs() { - inputs.insert(input); - } + let mut inputs: HashSet = HashSet::new(); - if let Some(mint) = &self.mint { - for input in mint.get_ref_inputs() { - inputs.insert(input); + let mut add_ref_inputs_set = |ref_inputs: TransactionInputs| { + for input in ref_inputs { + if !self.inputs.has_input(&input) { + inputs.insert(input); + } } + }; + + add_ref_inputs_set(self.inputs.get_ref_inputs()); + + if let Some(mint) = &self.mint { + add_ref_inputs_set(mint.get_ref_inputs()); } if let Some(withdrawals) = &self.withdrawals { - for input in withdrawals.get_ref_inputs() { - inputs.insert(input); - } + add_ref_inputs_set(withdrawals.get_ref_inputs()); } if let Some(certs) = &self.certs { - for input in certs.get_ref_inputs() { - inputs.insert(input); - } + add_ref_inputs_set(certs.get_ref_inputs()); } if let Some(voting_procedures) = &self.voting_procedures { - for input in voting_procedures.get_ref_inputs() { - inputs.insert(input); - } + add_ref_inputs_set(voting_procedures.get_ref_inputs()); } if let Some(voting_proposals) = &self.voting_proposals { - for input in voting_proposals.get_ref_inputs() { + add_ref_inputs_set(voting_proposals.get_ref_inputs()); + } + + if self.config.deduplicate_explicit_ref_inputs_with_regular_inputs { + add_ref_inputs_set(TransactionInputs::from_vec( + self.reference_inputs.keys().cloned().collect()) + ) + } else { + for input in self.reference_inputs.keys().cloned() { inputs.insert(input); } } @@ -1544,6 +1562,21 @@ impl TransactionBuilder { TransactionInputs::from_vec(vec_inputs) } + fn validate_inputs_intersection(&self) -> Result<(), JsError> { + let ref_inputs = self.get_reference_inputs(); + for input in &ref_inputs { + if self.inputs.has_input(input) { + return Err(JsError::from_str(&format!( + "The reference input {:?} is also present in the regular transaction inputs set. \ + It's not allowed to have the same inputs in both the transaction's inputs set and the reference inputs set. \ + You can use the `deduplicate_explicit_ref_inputs_with_regular_inputs` parameter in the `TransactionConfigBuilder` \ + to enforce the removal of duplicate reference inputs." + , input))); + } + } + Ok(()) + } + fn get_total_ref_scripts_size(&self) -> Result { let mut sizes_map = HashMap::new(); fn add_to_map<'a>( @@ -1551,10 +1584,10 @@ impl TransactionBuilder { sizes_map: &mut HashMap<&'a TransactionInput, usize>, ) -> Result<(), JsError> { if sizes_map.entry(item.0).or_insert(item.1) != &item.1 { - return Err(JsError::from_str(&format!( + Err(JsError::from_str(&format!( "Different script sizes for the same ref input {}", item.0 - ))); + ))) } else { Ok(()) } @@ -2438,6 +2471,7 @@ impl TransactionBuilder { )); } } + self.validate_inputs_intersection()?; self.build_tx_unsafe() } diff --git a/rust/src/builders/tx_inputs_builder.rs b/rust/src/builders/tx_inputs_builder.rs index 703d5529..1e50c17f 100644 --- a/rust/src/builders/tx_inputs_builder.rs +++ b/rust/src/builders/tx_inputs_builder.rs @@ -339,6 +339,10 @@ impl TxInputsBuilder { !self.inputs.is_empty() } + pub(crate) fn has_input(&self, input: &TransactionInput) -> bool { + self.inputs.contains_key(input) + } + fn insert_input_with_witness( &mut self, script_hash: &ScriptHash, diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index e22e8978..b367c4f6 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -5888,6 +5888,7 @@ fn ref_script_fee_from_all_builders() { let tx_in_7 = fake_tx_input(7); let tx_in_8 = fake_tx_input(8); let tx_in_9 = fake_tx_input(9); + let tx_in_10 = fake_tx_input(10); let script_hash_1 = fake_script_hash(1); let script_hash_2 = fake_script_hash(2); @@ -5968,7 +5969,7 @@ fn ref_script_fee_from_all_builders() { let input_coin = Coin::from(1000000000u64); tx_input_builder.add_plutus_script_input( &PlutusWitness::new_with_ref_without_datum(&plutus_source_8, &redeemer_8), - &tx_in_8, + &tx_in_10, &Value::new(&input_coin) ); @@ -6218,4 +6219,220 @@ fn tx_builder_no_any_input_coin_selection() { let add_inputs_res = tx_builder.add_inputs_from(&available_inputs, CoinSelectionStrategyCIP2::RandomImprove); assert!(add_inputs_res.is_err()); +} + + +#[test] +fn ref_inputs_debuplication_test() { + let mut mint_builder = MintBuilder::new(); + let mut cert_builder = CertificatesBuilder::new(); + let mut withdrawal_builder = WithdrawalsBuilder::new(); + let mut voting_builder = VotingBuilder::new(); + let mut voting_proposal_builder = VotingProposalBuilder::new(); + let mut tx_input_builder = TxInputsBuilder::new(); + + let tx_in_1 = fake_tx_input(1); + let tx_in_2 = fake_tx_input(2); + let tx_in_3 = fake_tx_input(3); + let tx_in_4 = fake_tx_input(4); + let tx_in_5 = fake_tx_input(5); + let tx_in_6 = fake_tx_input(6); + let tx_in_7 = fake_tx_input(7); + let tx_in_8 = fake_tx_input(8); + let tx_in_9 = fake_tx_input(9); + let tx_in_10 = fake_tx_input(10); + + let script_hash_1 = fake_script_hash(1); + let script_hash_2 = fake_script_hash(2); + let script_hash_3 = fake_script_hash(3); + let script_hash_4 = fake_script_hash(4); + let script_hash_5 = fake_script_hash(5); + let script_hash_6 = fake_script_hash(6); + let script_hash_7 = fake_script_hash(7); + let script_hash_8 = fake_script_hash(8); + + let redeemer_1 = fake_redeemer_zero_cost(1); + let redeemer_2 = fake_redeemer_zero_cost(2); + let redeemer_3 = fake_redeemer_zero_cost(3); + let redeemer_4 = fake_redeemer_zero_cost(4); + let redeemer_5 = fake_redeemer_zero_cost(5); + let redeemer_6 = fake_redeemer_zero_cost(6); + let redeemer_8 = fake_redeemer_zero_cost(8); + + let plutus_source_1 = PlutusScriptSource::new_ref_input(&script_hash_1, &tx_in_1, &Language::new_plutus_v2(), 10); + let plutus_source_2 = PlutusScriptSource::new_ref_input(&script_hash_2, &tx_in_2, &Language::new_plutus_v2(), 11); + let plutus_source_3 = PlutusScriptSource::new_ref_input(&script_hash_3, &tx_in_3, &Language::new_plutus_v2(), 111); + let plutus_source_4 = PlutusScriptSource::new_ref_input(&script_hash_4, &tx_in_4, &Language::new_plutus_v2(), 200); + let plutus_source_5 = PlutusScriptSource::new_ref_input(&script_hash_5, &tx_in_5, &Language::new_plutus_v2(), 3000); + let plutus_source_6 = PlutusScriptSource::new_ref_input(&script_hash_6, &tx_in_6, &Language::new_plutus_v2(), 5000); + let native_script_source = NativeScriptSource::new_ref_input(&script_hash_7, &tx_in_7); + let plutus_source_8 = PlutusScriptSource::new_ref_input(&script_hash_8, &tx_in_8, &Language::new_plutus_v2(), 50000); + + mint_builder.add_asset( + &MintWitness::new_plutus_script(&plutus_source_1, &redeemer_1), + &AssetName::from_hex("44544e4654").unwrap(), + &Int::new(&BigNum::from(100u64)) + ).unwrap(); + + mint_builder.add_asset( + &MintWitness::new_plutus_script(&plutus_source_2, &redeemer_2), + &AssetName::from_hex("44544e4654").unwrap(), + &Int::new(&BigNum::from(100u64)) + ).unwrap(); + + withdrawal_builder.add_with_plutus_witness( + &RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &Credential::from_scripthash(&script_hash_3)), + &Coin::from(1u64), + &PlutusWitness::new_with_ref_without_datum(&plutus_source_3, &redeemer_3) + ).unwrap(); + + withdrawal_builder.add_with_native_script( + &RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &Credential::from_scripthash(&script_hash_7)), + &Coin::from(1u64), + &native_script_source + ).unwrap(); + + cert_builder.add_with_plutus_witness( + &Certificate::new_stake_delegation(&StakeDelegation::new(&Credential::from_scripthash(&script_hash_4), &fake_key_hash(1))), + &PlutusWitness::new_with_ref_without_datum(&plutus_source_4, &redeemer_4) + ).unwrap(); + + voting_builder.add_with_plutus_witness( + &Voter::new_drep(&Credential::from_scripthash(&script_hash_5)), + &GovernanceActionId::new(&fake_tx_hash(1), 1), + &VotingProcedure::new(VoteKind::Abstain), + &PlutusWitness::new_with_ref_without_datum(&plutus_source_5, &redeemer_5) + ).unwrap(); + + voting_proposal_builder.add_with_plutus_witness( + &VotingProposal::new( + &GovernanceAction::new_new_constitution_action( + &NewConstitutionAction::new( + &Constitution::new_with_script_hash(&fake_anchor(), &script_hash_6) + ) + ), + &fake_anchor(), + &RewardAddress::new(NetworkInfo::testnet_preprod().network_id(), &Credential::from_keyhash(&fake_key_hash(1))), + &Coin::from(0u64), + ), + &PlutusWitness::new_with_ref_without_datum(&plutus_source_6, &redeemer_6) + ).unwrap(); + + let input_coin = Coin::from(1000000000u64); + tx_input_builder.add_plutus_script_input( + &PlutusWitness::new_with_ref_without_datum(&plutus_source_8, &redeemer_8), + &tx_in_10, + &Value::new(&input_coin) + ); + + let mut tx_builder = fake_reallistic_tx_builder(); + let change_address = fake_base_address(1); + + tx_builder.set_mint_builder(&mint_builder); + tx_builder.set_certs_builder(&cert_builder); + tx_builder.set_withdrawals_builder(&withdrawal_builder); + tx_builder.set_voting_builder(&voting_builder); + tx_builder.set_voting_proposal_builder(&voting_proposal_builder); + tx_builder.set_inputs(&tx_input_builder); + tx_builder.add_script_reference_input(&tx_in_9, 16000); + + tx_builder.add_regular_input(&fake_base_address(1), &tx_in_1, &Value::new(&Coin::from(1000000000u64))).unwrap(); + tx_builder.add_regular_input(&fake_base_address(1), &tx_in_2, &Value::new(&Coin::from(1000000000u64))).unwrap(); + tx_builder.add_regular_input(&fake_base_address(1), &tx_in_3, &Value::new(&Coin::from(1000000000u64))).unwrap(); + tx_builder.add_regular_input(&fake_base_address(1), &tx_in_4, &Value::new(&Coin::from(1000000000u64))).unwrap(); + tx_builder.add_regular_input(&fake_base_address(1), &tx_in_5, &Value::new(&Coin::from(1000000000u64))).unwrap(); + tx_builder.add_regular_input(&fake_base_address(1), &tx_in_6, &Value::new(&Coin::from(1000000000u64))).unwrap(); + tx_builder.add_regular_input(&fake_base_address(1), &tx_in_7, &Value::new(&Coin::from(1000000000u64))).unwrap(); + tx_builder.add_regular_input(&fake_base_address(1), &tx_in_8, &Value::new(&Coin::from(1000000000u64))).unwrap(); + + + let fake_collateral = fake_tx_input(99); + let mut collateral_builder = TxInputsBuilder::new(); + collateral_builder.add_regular_input( + &fake_base_address(99), + &fake_collateral, + &Value::new(&Coin::from(1000000000u64)) + ).unwrap(); + + tx_builder.set_collateral(&collateral_builder); + tx_builder.calc_script_data_hash(&TxBuilderConstants::plutus_default_cost_models()).unwrap(); + tx_builder.add_change_if_needed(&change_address).unwrap(); + + let res = tx_builder.build_tx(); + assert!(res.is_ok()); + + let mut tx = res.unwrap(); + let mut vkey_witneses = Vkeywitnesses::new(); + vkey_witneses.add(&fake_vkey_witness(1)); + let mut wit_set = tx.witness_set(); + wit_set.set_vkeys(&vkey_witneses); + tx = Transaction::new(&tx.body(), &wit_set, tx.auxiliary_data()); + + let total_tx_fee = tx.body().fee(); + + let tx_out_coin = tx.body().outputs().get(0).amount().coin(); + let total_out = tx_out_coin + .checked_add(&total_tx_fee).unwrap() + .checked_sub(&Coin::from(2u64)).unwrap(); // withdrawals + + assert_eq!(total_out, input_coin.checked_mul(&BigNum(9)).unwrap()); + + let ref_inputs = tx.body().reference_inputs().unwrap(); + assert!(ref_inputs.contains(&tx_in_9)); + assert_eq!(ref_inputs.len(), 1); +} + +#[test] +fn ref_inputs_and_reg_inputs_intersection_error() { + let tx_in_1 = fake_tx_input(1); + let tx_in_2 = fake_tx_input(2); + + let mut tx_builder = fake_reallistic_tx_builder(); + let change_address = fake_base_address(1); + + tx_builder.add_regular_input(&fake_base_address(1), &tx_in_1, &Value::new(&Coin::from(1000000000u64))).unwrap(); + tx_builder.add_regular_input(&fake_base_address(1), &tx_in_2, &Value::new(&Coin::from(1000000000u64))).unwrap(); + + tx_builder.add_reference_input(&tx_in_1); + tx_builder.add_change_if_needed(&change_address).unwrap(); + + let res = tx_builder.build_tx(); + assert!(res.is_err()); +} + +#[test] +fn ref_inputs_and_reg_inputs_no_intersection_error() { + let tx_in_1 = fake_tx_input(1); + let tx_in_2 = fake_tx_input(2); + let tx_in_3 = fake_tx_input(3); + + let linear_fee = LinearFee::new(&BigNum(1), &BigNum(0)); + let cfg = TransactionBuilderConfigBuilder::new() + .fee_algo(&linear_fee) + .pool_deposit(&BigNum(0)) + .key_deposit(&BigNum(0)) + .max_value_size(9999) + .max_tx_size(9999) + .coins_per_utxo_byte(&Coin::zero()) + .deduplicate_explicit_ref_inputs_with_regular_inputs(true) + .build() + .unwrap(); + let mut tx_builder = TransactionBuilder::new(&cfg); + let change_address = fake_base_address(1); + + tx_builder.add_regular_input(&fake_base_address(1), &tx_in_1, &Value::new(&Coin::from(1000000000u64))).unwrap(); + tx_builder.add_regular_input(&fake_base_address(1), &tx_in_2, &Value::new(&Coin::from(1000000000u64))).unwrap(); + + tx_builder.add_reference_input(&tx_in_1); + tx_builder.add_reference_input(&tx_in_3); + tx_builder.add_change_if_needed(&change_address).unwrap(); + + let res = tx_builder.build_tx(); + assert!(res.is_ok()); + + let tx = res.unwrap(); + + let ref_inputs = tx.body().reference_inputs().unwrap(); + assert!(ref_inputs.contains(&tx_in_3)); + assert_eq!(ref_inputs.len(), 1); } \ No newline at end of file From dd18a8eaf346f0cb55859e63aa2ed7aa8a2523cf Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 16 Aug 2024 17:40:08 +0900 Subject: [PATCH 339/349] flow update --- rust/pkg/cardano_serialization_lib.js.flow | 401 +++++++++++---------- 1 file changed, 205 insertions(+), 196 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 3db82730..93f2712b 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -6,68 +6,41 @@ */ /** - * @param {string} json - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {PlutusData} - */ -declare export function encode_json_str_to_plutus_datum( - json: string, - schema: $Values -): PlutusData; - -/** - * @param {PlutusData} datum - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {string} - */ -declare export function decode_plutus_datum_to_json_str( - datum: PlutusData, - schema: $Values -): string; - -/** - * @param {Uint8Array} bytes - * @returns {TransactionMetadatum} + * @param {Transaction} tx + * @param {LinearFee} linear_fee + * @returns {BigNum} */ -declare export function encode_arbitrary_bytes_as_metadatum( - bytes: Uint8Array -): TransactionMetadatum; +declare export function min_fee(tx: Transaction, linear_fee: LinearFee): BigNum; /** - * @param {TransactionMetadatum} metadata - * @returns {Uint8Array} + * @param {ExUnits} ex_units + * @param {ExUnitPrices} ex_unit_prices + * @returns {BigNum} */ -declare export function decode_arbitrary_bytes_from_metadatum( - metadata: TransactionMetadatum -): Uint8Array; +declare export function calculate_ex_units_ceil_cost( + ex_units: ExUnits, + ex_unit_prices: ExUnitPrices +): BigNum; /** - * @param {string} json - * @param {$Values< - typeof - MetadataJsonSchema>} schema - * @returns {TransactionMetadatum} + * @param {Transaction} tx + * @param {ExUnitPrices} ex_unit_prices + * @returns {BigNum} */ -declare export function encode_json_str_to_metadatum( - json: string, - schema: $Values -): TransactionMetadatum; +declare export function min_script_fee( + tx: Transaction, + ex_unit_prices: ExUnitPrices +): BigNum; /** - * @param {TransactionMetadatum} metadatum - * @param {$Values< - typeof - MetadataJsonSchema>} schema - * @returns {string} + * @param {number} total_ref_scripts_size + * @param {UnitInterval} ref_script_coins_per_byte + * @returns {BigNum} */ -declare export function decode_metadatum_to_json_str( - metadatum: TransactionMetadatum, - schema: $Values -): string; +declare export function min_ref_script_fee( + total_ref_scripts_size: number, + ref_script_coins_per_byte: UnitInterval +): BigNum; /** * @param {TransactionHash} tx_body_hash @@ -219,53 +192,80 @@ declare export function decrypt_with_password( ): string; /** - * @param {Address} address - * @param {TransactionUnspentOutputs} utxos - * @param {TransactionBuilderConfig} config - * @returns {TransactionBatchList} + * @param {string} json + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {PlutusData} */ -declare export function create_send_all( - address: Address, - utxos: TransactionUnspentOutputs, - config: TransactionBuilderConfig -): TransactionBatchList; +declare export function encode_json_str_to_plutus_datum( + json: string, + schema: $Values +): PlutusData; /** - * @param {Transaction} tx - * @param {LinearFee} linear_fee - * @returns {BigNum} + * @param {PlutusData} datum + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {string} */ -declare export function min_fee(tx: Transaction, linear_fee: LinearFee): BigNum; +declare export function decode_plutus_datum_to_json_str( + datum: PlutusData, + schema: $Values +): string; /** - * @param {ExUnits} ex_units - * @param {ExUnitPrices} ex_unit_prices - * @returns {BigNum} + * @param {Uint8Array} bytes + * @returns {TransactionMetadatum} */ -declare export function calculate_ex_units_ceil_cost( - ex_units: ExUnits, - ex_unit_prices: ExUnitPrices -): BigNum; +declare export function encode_arbitrary_bytes_as_metadatum( + bytes: Uint8Array +): TransactionMetadatum; /** - * @param {Transaction} tx - * @param {ExUnitPrices} ex_unit_prices - * @returns {BigNum} + * @param {TransactionMetadatum} metadata + * @returns {Uint8Array} */ -declare export function min_script_fee( - tx: Transaction, - ex_unit_prices: ExUnitPrices -): BigNum; +declare export function decode_arbitrary_bytes_from_metadatum( + metadata: TransactionMetadatum +): Uint8Array; /** - * @param {number} total_ref_scripts_size - * @param {UnitInterval} ref_script_coins_per_byte - * @returns {BigNum} + * @param {string} json + * @param {$Values< + typeof + MetadataJsonSchema>} schema + * @returns {TransactionMetadatum} */ -declare export function min_ref_script_fee( - total_ref_scripts_size: number, - ref_script_coins_per_byte: UnitInterval -): BigNum; +declare export function encode_json_str_to_metadatum( + json: string, + schema: $Values +): TransactionMetadatum; + +/** + * @param {TransactionMetadatum} metadatum + * @param {$Values< + typeof + MetadataJsonSchema>} schema + * @returns {string} + */ +declare export function decode_metadatum_to_json_str( + metadatum: TransactionMetadatum, + schema: $Values +): string; + +/** + * @param {Address} address + * @param {TransactionUnspentOutputs} utxos + * @param {TransactionBuilderConfig} config + * @returns {TransactionBatchList} + */ +declare export function create_send_all( + address: Address, + utxos: TransactionUnspentOutputs, + config: TransactionBuilderConfig +): TransactionBatchList; /** * Each new language uses a different namespace for hashing its script @@ -284,49 +284,58 @@ declare export var ScriptHashNamespace: {| /** */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 +declare export var GovernanceActionKind: {| + +ParameterChangeAction: 0, // 0 + +HardForkInitiationAction: 1, // 1 + +TreasuryWithdrawalsAction: 2, // 2 + +NoConfidenceAction: 3, // 3 + +UpdateCommitteeAction: 4, // 4 + +NewConstitutionAction: 5, // 5 + +InfoAction: 6, // 6 |}; /** + * JSON <-> PlutusData conversion schemas. + * Follows ScriptDataJsonSchema in cardano-cli defined at: + * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 + * + * All methods here have the following restrictions due to limitations on dependencies: + * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors + * * Hex strings for bytes don't accept odd-length (half-byte) strings. + * cardano-cli seems to support these however but it seems to be different than just 0-padding + * on either side when tested so proceed with caution */ -declare export var RelayKind: {| - +SingleHostAddr: 0, // 0 - +SingleHostName: 1, // 1 - +MultiHostName: 2, // 2 +declare export var PlutusDatumSchema: {| + +BasicConversions: 0, // 0 + +DetailedSchema: 1, // 1 |}; /** */ -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 |}; /** */ -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 |}; /** */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 |}; /** @@ -338,38 +347,6 @@ declare export var ScriptSchema: {| +Node: 1, // 1 |}; -/** - */ - -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 -|}; - -/** - */ - -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 -|}; - -/** - */ - -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 -|}; - -/** - */ - -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 -|}; - /** */ @@ -384,28 +361,17 @@ declare export var PlutusDataKind: {| /** */ -declare export var BlockEra: {| - +Byron: 0, // 0 - +Shelley: 1, // 1 - +Allegra: 2, // 2 - +Mary: 3, // 3 - +Alonzo: 4, // 4 - +Babbage: 5, // 5 - +Conway: 6, // 6 - +Unknown: 7, // 7 +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 |}; /** */ -declare export var GovernanceActionKind: {| - +ParameterChangeAction: 0, // 0 - +HardForkInitiationAction: 1, // 1 - +TreasuryWithdrawalsAction: 2, // 2 - +NoConfidenceAction: 3, // 3 - +UpdateCommitteeAction: 4, // 4 - +NewConstitutionAction: 5, // 5 - +InfoAction: 6, // 6 +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** @@ -434,22 +400,19 @@ declare export var CertificateKind: {| /** */ -declare export var RedeemerTagKind: {| - +Spend: 0, // 0 - +Mint: 1, // 1 - +Cert: 2, // 2 - +Reward: 3, // 3 - +Vote: 4, // 4 - +VotingProposal: 5, // 5 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 |}; /** */ -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 |}; /** @@ -464,16 +427,6 @@ declare export var AddressKind: {| +Malformed: 5, // 5 |}; -/** - */ - -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 -|}; - /** */ @@ -489,11 +442,55 @@ declare export var NativeScriptKind: {| /** */ -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 +declare export var RedeemerTagKind: {| + +Spend: 0, // 0 + +Mint: 1, // 1 + +Cert: 2, // 2 + +Reward: 3, // 3 + +Vote: 4, // 4 + +VotingProposal: 5, // 5 +|}; + +/** + */ + +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 +|}; + +/** + */ + +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 +|}; + +/** + */ + +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 +|}; + +/** + */ + +declare export var BlockEra: {| + +Byron: 0, // 0 + +Shelley: 1, // 1 + +Allegra: 2, // 2 + +Mary: 3, // 3 + +Alonzo: 4, // 4 + +Babbage: 5, // 5 + +Conway: 6, // 6 + +Unknown: 7, // 7 |}; /** @@ -506,20 +503,23 @@ declare export var LanguageKind: {| |}; /** - * JSON <-> PlutusData conversion schemas. - * Follows ScriptDataJsonSchema in cardano-cli defined at: - * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 - * - * All methods here have the following restrictions due to limitations on dependencies: - * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors - * * Hex strings for bytes don't accept odd-length (half-byte) strings. - * cardano-cli seems to support these however but it seems to be different than just 0-padding - * on either side when tested so proceed with caution */ -declare export var PlutusDatumSchema: {| - +BasicConversions: 0, // 0 - +DetailedSchema: 1, // 1 +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 +|}; + +/** + */ + +declare export var RelayKind: {| + +SingleHostAddr: 0, // 0 + +SingleHostName: 1, // 1 + +MultiHostName: 2, // 2 |}; /** @@ -11566,6 +11566,15 @@ declare export class TransactionBuilderConfigBuilder { prefer_pure_change: boolean ): TransactionBuilderConfigBuilder; + /** + * Removes a ref input (that was set via set_reference_inputs) if the ref inputs was presented in regular tx inputs + * @param {boolean} deduplicate_explicit_ref_inputs_with_regular_inputs + * @returns {TransactionBuilderConfigBuilder} + */ + deduplicate_explicit_ref_inputs_with_regular_inputs( + deduplicate_explicit_ref_inputs_with_regular_inputs: boolean + ): TransactionBuilderConfigBuilder; + /** * @returns {TransactionBuilderConfig} */ From 57c9dc1cb459233887afa91448554d58eed9f870 Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 16 Aug 2024 17:40:35 +0900 Subject: [PATCH 340/349] version bump --- package-lock.json | 4 ++-- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8dad1cb1..0f5d3033 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.6", + "version": "12.0.0-beta.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.6", + "version": "12.0.0-beta.7", "hasInstallScript": true, "license": "MIT", "devDependencies": { diff --git a/package.json b/package.json index 54af488c..5f6fbe8d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.6", + "version": "12.0.0-beta.7", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 2aec1bef..4b084001 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-beta.6" +version = "12.0.0-beta.7" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 887ed588..eaf78667 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -49,7 +49,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-beta.6" +version = "12.0.0-beta.7" dependencies = [ "bech32", "cbor_event", From b5013dda473e838c9f2b2250966a2dc4b516d858 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 19 Aug 2024 20:12:18 +0900 Subject: [PATCH 341/349] add script size parameter for native script source with reference input --- rust/src/builders/mint_builder.rs | 8 ++++---- .../script_structs/native_script_source.rs | 17 +++++++++++++---- .../script_structs/script_witness_type.rs | 10 +++++++--- rust/src/builders/tx_inputs_builder.rs | 4 +--- rust/src/tests/builders/mint_builder.rs | 6 ++++++ rust/src/tests/builders/tx_builder.rs | 6 +++--- rust/src/tests/builders/tx_inputs_builder.rs | 2 +- rust/src/tests/builders/voting_builder.rs | 2 +- 8 files changed, 36 insertions(+), 19 deletions(-) diff --git a/rust/src/builders/mint_builder.rs b/rust/src/builders/mint_builder.rs index 3b6bdb4d..d7bc9b35 100644 --- a/rust/src/builders/mint_builder.rs +++ b/rust/src/builders/mint_builder.rs @@ -47,13 +47,13 @@ impl NativeMints { fn script_hash(&self) -> PolicyID { match &self.script { NativeScriptSourceEnum::NativeScript(script, _) => script.hash(), - NativeScriptSourceEnum::RefInput(_, script_hash, _) => script_hash.clone(), + NativeScriptSourceEnum::RefInput(_, script_hash, _, _) => script_hash.clone(), } } fn ref_input(&self) -> Option<&TransactionInput> { match &self.script { - NativeScriptSourceEnum::RefInput(input, _, _) => Some(input), + NativeScriptSourceEnum::RefInput(input, _, _, _) => Some(input), _ => None, } } @@ -241,8 +241,8 @@ impl MintBuilder { )) } } - NativeScriptSourceEnum::RefInput(_, _, _) => { - if let NativeScriptSourceEnum::RefInput(_, _, _) = input_script_source { + NativeScriptSourceEnum::RefInput(_, _, _, _) => { + if let NativeScriptSourceEnum::RefInput(_, _, _, _) = input_script_source { Ok(()) } else { Err(JsError::from_str( diff --git a/rust/src/builders/script_structs/native_script_source.rs b/rust/src/builders/script_structs/native_script_source.rs index 37bec9bb..39eedb62 100644 --- a/rust/src/builders/script_structs/native_script_source.rs +++ b/rust/src/builders/script_structs/native_script_source.rs @@ -3,14 +3,14 @@ use crate::*; #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] pub(crate) enum NativeScriptSourceEnum { NativeScript(NativeScript, Option), - RefInput(TransactionInput, ScriptHash, Option), + RefInput(TransactionInput, ScriptHash, Option, usize), } impl NativeScriptSourceEnum { pub fn script_hash(&self) -> ScriptHash { match self { NativeScriptSourceEnum::NativeScript(script, _) => script.hash(), - NativeScriptSourceEnum::RefInput(_, script_hash, _) => script_hash.clone(), + NativeScriptSourceEnum::RefInput(_, script_hash, _, _) => script_hash.clone(), } } @@ -22,7 +22,7 @@ impl NativeScriptSourceEnum { None => Some(script.into()) } } - NativeScriptSourceEnum::RefInput(_, _, required_signers) => required_signers.clone(), + NativeScriptSourceEnum::RefInput(_, _, required_signers, _) => required_signers.clone(), } } @@ -31,7 +31,7 @@ impl NativeScriptSourceEnum { NativeScriptSourceEnum::NativeScript(_, required_signers) => { *required_signers = Some(key_hashes.clone()); } - NativeScriptSourceEnum::RefInput(_, _, required_signers) => { + NativeScriptSourceEnum::RefInput(_, _, required_signers, _) => { *required_signers = Some(key_hashes.clone()); } } @@ -51,11 +51,13 @@ impl NativeScriptSource { pub fn new_ref_input( script_hash: &ScriptHash, input: &TransactionInput, + script_size: usize, ) -> Self { Self(NativeScriptSourceEnum::RefInput( input.clone(), script_hash.clone(), None, + script_size )) } @@ -66,4 +68,11 @@ impl NativeScriptSource { pub(crate) fn script_hash(&self) -> ScriptHash { self.0.script_hash() } + + pub fn get_ref_script_size(&self) -> Option { + match &self.0 { + NativeScriptSourceEnum::NativeScript(..) => None, + NativeScriptSourceEnum::RefInput(.., size) => Some(*size) + } + } } \ No newline at end of file diff --git a/rust/src/builders/script_structs/script_witness_type.rs b/rust/src/builders/script_structs/script_witness_type.rs index 8568b338..33304c74 100644 --- a/rust/src/builders/script_structs/script_witness_type.rs +++ b/rust/src/builders/script_structs/script_witness_type.rs @@ -49,9 +49,7 @@ impl ScriptWitnessType { } } - pub(crate) fn get_script_ref_input_with_size( - &self, - ) -> Option<(&TransactionInput, usize)> { + pub(crate) fn get_script_ref_input_with_size(&self) -> Option<(&TransactionInput, usize)> { match self { ScriptWitnessType::PlutusScriptWitness(plutus_witness) => { match &plutus_witness.script { @@ -61,6 +59,12 @@ impl ScriptWitnessType { _ => None, } } + ScriptWitnessType::NativeScriptWitness(NativeScriptSourceEnum::RefInput( + input, + _, + _, + size, + )) => Some((input, *size)), _ => None, } } diff --git a/rust/src/builders/tx_inputs_builder.rs b/rust/src/builders/tx_inputs_builder.rs index 1e50c17f..f37c03d8 100644 --- a/rust/src/builders/tx_inputs_builder.rs +++ b/rust/src/builders/tx_inputs_builder.rs @@ -170,9 +170,7 @@ impl TxInputsBuilder { { match wintess { ScriptWitnessType::NativeScriptWitness(NativeScriptSourceEnum::RefInput( - input, - _, - _, + input, _, _, _, )) => { inputs.push(input.clone()); } diff --git a/rust/src/tests/builders/mint_builder.rs b/rust/src/tests/builders/mint_builder.rs index 70d14a0b..831dac70 100644 --- a/rust/src/tests/builders/mint_builder.rs +++ b/rust/src/tests/builders/mint_builder.rs @@ -198,6 +198,7 @@ fn ref_inputs() { let native_script_source = NativeScriptSource::new_ref_input( &script_hash_2, &tx_input_ref2, + 0, ); let mint_witnes = MintWitness::new_plutus_script(&plutus_script_source, &redeemer); @@ -236,6 +237,7 @@ fn multiple_mints() { let native_script_source = NativeScriptSource::new_ref_input( &script_hash_2, &tx_input_ref2, + 0, ); let mint_witnes = MintWitness::new_plutus_script(&plutus_script_source, &redeemer); @@ -324,10 +326,12 @@ fn different_script_type_error() { let native_script_source1 = NativeScriptSource::new_ref_input( &script_hash_2, &tx_input_ref2, + 0, ); let native_script_source2 = NativeScriptSource::new_ref_input( &script_hash_1, &tx_input_ref1, + 0, ); let mint_witnes_plutus_1 = MintWitness::new_plutus_script(&plutus_script_source1, &redeemer); @@ -374,6 +378,7 @@ fn wrong_witness_type_ref_error() { let native_script_source_1 = NativeScriptSource::new_ref_input( &script_hash_2, &tx_input_ref2, + 0, ); let native_script_source_2 = NativeScriptSource::new(&native_script); @@ -443,6 +448,7 @@ fn wrong_witness_type_no_ref_error() { let native_script_source_1 = NativeScriptSource::new_ref_input( &script_hash_2, &tx_input_ref2, + 0, ); let native_script_source_2 = NativeScriptSource::new(&native_script); diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index b367c4f6..72902986 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -5913,7 +5913,7 @@ fn ref_script_fee_from_all_builders() { let plutus_source_4 = PlutusScriptSource::new_ref_input(&script_hash_4, &tx_in_4, &Language::new_plutus_v2(), 200); let plutus_source_5 = PlutusScriptSource::new_ref_input(&script_hash_5, &tx_in_5, &Language::new_plutus_v2(), 3000); let plutus_source_6 = PlutusScriptSource::new_ref_input(&script_hash_6, &tx_in_6, &Language::new_plutus_v2(), 5000); - let native_script_source = NativeScriptSource::new_ref_input(&script_hash_7, &tx_in_7); + let native_script_source = NativeScriptSource::new_ref_input(&script_hash_7, &tx_in_7, 10000); let plutus_source_8 = PlutusScriptSource::new_ref_input(&script_hash_8, &tx_in_8, &Language::new_plutus_v2(), 50000); mint_builder.add_asset( @@ -6006,7 +6006,7 @@ fn ref_script_fee_from_all_builders() { wit_set.set_vkeys(&vkey_witneses); tx = Transaction::new(&tx.body(), &wit_set, tx.auxiliary_data()); - let ref_script_fee = BigNum::from(44815u64); + let ref_script_fee = BigNum::from(53099u64); let total_tx_fee = tx.body().fee(); //TODO: check change calculation for pessimistic size estimation. @@ -6265,7 +6265,7 @@ fn ref_inputs_debuplication_test() { let plutus_source_4 = PlutusScriptSource::new_ref_input(&script_hash_4, &tx_in_4, &Language::new_plutus_v2(), 200); let plutus_source_5 = PlutusScriptSource::new_ref_input(&script_hash_5, &tx_in_5, &Language::new_plutus_v2(), 3000); let plutus_source_6 = PlutusScriptSource::new_ref_input(&script_hash_6, &tx_in_6, &Language::new_plutus_v2(), 5000); - let native_script_source = NativeScriptSource::new_ref_input(&script_hash_7, &tx_in_7); + let native_script_source = NativeScriptSource::new_ref_input(&script_hash_7, &tx_in_7, 10000); let plutus_source_8 = PlutusScriptSource::new_ref_input(&script_hash_8, &tx_in_8, &Language::new_plutus_v2(), 50000); mint_builder.add_asset( diff --git a/rust/src/tests/builders/tx_inputs_builder.rs b/rust/src/tests/builders/tx_inputs_builder.rs index 7a59933a..52391d27 100644 --- a/rust/src/tests/builders/tx_inputs_builder.rs +++ b/rust/src/tests/builders/tx_inputs_builder.rs @@ -362,7 +362,7 @@ fn native_script_input_ref_script() { let ref_input = fake_tx_input(2); let script_hash = fake_script_hash(1); - let mut native_script_source = NativeScriptSource::new_ref_input(&script_hash, &ref_input); + let mut native_script_source = NativeScriptSource::new_ref_input(&script_hash, &ref_input, 0); let mut key_hashes = Ed25519KeyHashes::new(); key_hashes.add(&key_hash_1); native_script_source.set_required_signers(&key_hashes); diff --git a/rust/src/tests/builders/voting_builder.rs b/rust/src/tests/builders/voting_builder.rs index 546b9177..f4afb9c6 100644 --- a/rust/src/tests/builders/voting_builder.rs +++ b/rust/src/tests/builders/voting_builder.rs @@ -334,7 +334,7 @@ fn voting_builder_native_script_ref_witness() { let ref_input = TransactionInput::new(&fake_tx_hash(5), 0); let mut script_source = - NativeScriptSource::new_ref_input(&script_hash, &ref_input); + NativeScriptSource::new_ref_input(&script_hash, &ref_input, 0); script_source.set_required_signers(&script_signers); builder .add_with_native_script(&voter, &action_id, &vote, &script_source) From 01ca02de7090ac8b0793059c1bccf8c5c53be422 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 19 Aug 2024 20:31:59 +0900 Subject: [PATCH 342/349] version bump --- package-lock.json | 4 ++-- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0f5d3033..42c856e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.7", + "version": "12.0.0-beta.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.7", + "version": "12.0.0-beta.8", "hasInstallScript": true, "license": "MIT", "devDependencies": { diff --git a/package.json b/package.json index 5f6fbe8d..181e0dfd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.7", + "version": "12.0.0-beta.8", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 4b084001..141ff9d5 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-beta.7" +version = "12.0.0-beta.8" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index eaf78667..50d2a92d 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -49,7 +49,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-beta.7" +version = "12.0.0-beta.8" dependencies = [ "bech32", "cbor_event", From 1675fe010d439e52b4767ba2bd324e496c49fc56 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 19 Aug 2024 20:32:20 +0900 Subject: [PATCH 343/349] flow update --- rust/pkg/cardano_serialization_lib.js.flow | 241 +++++++++++---------- 1 file changed, 124 insertions(+), 117 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 93f2712b..c4f986dc 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -5,6 +5,18 @@ * @flow */ +/** + * @param {Address} address + * @param {TransactionUnspentOutputs} utxos + * @param {TransactionBuilderConfig} config + * @returns {TransactionBatchList} + */ +declare export function create_send_all( + address: Address, + utxos: TransactionUnspentOutputs, + config: TransactionBuilderConfig +): TransactionBatchList; + /** * @param {Transaction} tx * @param {LinearFee} linear_fee @@ -256,42 +268,34 @@ declare export function decode_metadatum_to_json_str( ): string; /** - * @param {Address} address - * @param {TransactionUnspentOutputs} utxos - * @param {TransactionBuilderConfig} config - * @returns {TransactionBatchList} */ -declare export function create_send_all( - address: Address, - utxos: TransactionUnspentOutputs, - config: TransactionBuilderConfig -): TransactionBatchList; + +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 +|}; /** - * Each new language uses a different namespace for hashing its script - * This is because you could have a language where the same bytes have different semantics - * So this avoids scripts in different languages mapping to the same hash - * Note that the enum value here is different than the enum value for deciding the cost model of a script + * Used to choosed the schema for a script JSON string */ -declare export var ScriptHashNamespace: {| - +NativeScript: 0, // 0 - +PlutusScript: 1, // 1 - +PlutusScriptV2: 2, // 2 - +PlutusScriptV3: 3, // 3 +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** */ -declare export var GovernanceActionKind: {| - +ParameterChangeAction: 0, // 0 - +HardForkInitiationAction: 1, // 1 - +TreasuryWithdrawalsAction: 2, // 2 - +NoConfidenceAction: 3, // 3 - +UpdateCommitteeAction: 4, // 4 - +NewConstitutionAction: 5, // 5 - +InfoAction: 6, // 6 +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 |}; /** @@ -314,64 +318,76 @@ declare export var PlutusDatumSchema: {| /** */ -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 |}; /** */ -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 +declare export var RedeemerTagKind: {| + +Spend: 0, // 0 + +Mint: 1, // 1 + +Cert: 2, // 2 + +Reward: 3, // 3 + +Vote: 4, // 4 + +VotingProposal: 5, // 5 |}; /** */ -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 |}; /** - * Used to choosed the schema for a script JSON string */ -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 +declare export var RelayKind: {| + +SingleHostAddr: 0, // 0 + +SingleHostName: 1, // 1 + +MultiHostName: 2, // 2 |}; /** */ -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 - +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 +declare export var AddressKind: {| + +Base: 0, // 0 + +Pointer: 1, // 1 + +Enterprise: 2, // 2 + +Reward: 3, // 3 + +Byron: 4, // 4 + +Malformed: 5, // 5 |}; /** */ -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 |}; /** */ -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 +declare export var GovernanceActionKind: {| + +ParameterChangeAction: 0, // 0 + +HardForkInitiationAction: 1, // 1 + +TreasuryWithdrawalsAction: 2, // 2 + +NoConfidenceAction: 3, // 3 + +UpdateCommitteeAction: 4, // 4 + +NewConstitutionAction: 5, // 5 + +InfoAction: 6, // 6 |}; /** @@ -400,66 +416,63 @@ declare export var CertificateKind: {| /** */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 |}; /** */ -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 |}; /** */ -declare export var AddressKind: {| - +Base: 0, // 0 - +Pointer: 1, // 1 - +Enterprise: 2, // 2 - +Reward: 3, // 3 - +Byron: 4, // 4 - +Malformed: 5, // 5 +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 |}; /** */ -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** */ -declare export var RedeemerTagKind: {| - +Spend: 0, // 0 - +Mint: 1, // 1 - +Cert: 2, // 2 - +Reward: 3, // 3 - +Vote: 4, // 4 - +VotingProposal: 5, // 5 +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 |}; /** */ -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 +|}; + +/** + */ + +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 |}; /** @@ -472,11 +485,17 @@ declare export var VoteKind: {| |}; /** + * Each new language uses a different namespace for hashing its script + * This is because you could have a language where the same bytes have different semantics + * So this avoids scripts in different languages mapping to the same hash + * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 +declare export var ScriptHashNamespace: {| + +NativeScript: 0, // 0 + +PlutusScript: 1, // 1 + +PlutusScriptV2: 2, // 2 + +PlutusScriptV3: 3, // 3 |}; /** @@ -496,30 +515,11 @@ declare export var BlockEra: {| /** */ -declare export var LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 -|}; - -/** - */ - -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 -|}; - -/** - */ - -declare export var RelayKind: {| - +SingleHostAddr: 0, // 0 - +SingleHostName: 1, // 1 - +MultiHostName: 2, // 2 +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 |}; /** @@ -6400,17 +6400,24 @@ declare export class NativeScriptSource { /** * @param {ScriptHash} script_hash * @param {TransactionInput} input + * @param {number} script_size * @returns {NativeScriptSource} */ static new_ref_input( script_hash: ScriptHash, - input: TransactionInput + input: TransactionInput, + script_size: number ): NativeScriptSource; /** * @param {Ed25519KeyHashes} key_hashes */ set_required_signers(key_hashes: Ed25519KeyHashes): void; + + /** + * @returns {number | void} + */ + get_ref_script_size(): number | void; } /** */ From ca0db79372040e44c2951211e94af1eed3c8772d Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 20 Aug 2024 21:02:00 +0900 Subject: [PATCH 344/349] version bump --- package-lock.json | 4 ++-- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 42c856e0..6819d35c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.8", + "version": "12.0.0-beta.9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.8", + "version": "12.0.0-beta.9", "hasInstallScript": true, "license": "MIT", "devDependencies": { diff --git a/package.json b/package.json index 181e0dfd..ad62d52a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.8", + "version": "12.0.0-beta.9", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 141ff9d5..ed6763d0 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-beta.8" +version = "12.0.0-beta.9" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 50d2a92d..4fb0c904 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -49,7 +49,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-beta.8" +version = "12.0.0-beta.9" dependencies = [ "bech32", "cbor_event", From 7e54491c50fc1ac19517b86f8b2cc1d4bf7c86cd Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 27 Aug 2024 00:38:28 +0900 Subject: [PATCH 345/349] naming unification --- rust/pkg/cardano_serialization_lib.js.flow | 264 +++++++++--------- rust/src/builders/certificates_builder.rs | 4 +- .../certificates/committee_cold_resign.rs | 16 +- .../certificates/committee_hot_auth.rs | 20 +- rust/src/protocol_types/governance/voter.rs | 24 +- .../certificates/committee_cold_resign.rs | 4 +- .../certificates/committee_hot_auth.rs | 12 +- rust/src/serialization/governance/voter.rs | 6 +- rust/src/tests/builders/tx_builder.rs | 4 +- rust/src/tests/builders/voting_builder.rs | 18 +- rust/src/tests/protocol_types/certificates.rs | 8 +- .../tests/protocol_types/governance/common.rs | 48 ++-- .../tests/serialization/governance/common.rs | 18 +- .../tests/serialization/transaction_body.rs | 2 +- 14 files changed, 224 insertions(+), 224 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index c4f986dc..85e423d5 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -267,6 +267,20 @@ declare export function decode_metadatum_to_json_str( schema: $Values ): string; +/** + * Each new language uses a different namespace for hashing its script + * This is because you could have a language where the same bytes have different semantics + * So this avoids scripts in different languages mapping to the same hash + * Note that the enum value here is different than the enum value for deciding the cost model of a script + */ + +declare export var ScriptHashNamespace: {| + +NativeScript: 0, // 0 + +PlutusScript: 1, // 1 + +PlutusScriptV2: 2, // 2 + +PlutusScriptV3: 3, // 3 +|}; + /** */ @@ -278,26 +292,6 @@ declare export var PlutusDataKind: {| +Bytes: 4, // 4 |}; -/** - * Used to choosed the schema for a script JSON string - */ - -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 -|}; - -/** - */ - -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 -|}; - /** * JSON <-> PlutusData conversion schemas. * Follows ScriptDataJsonSchema in cardano-cli defined at: @@ -318,22 +312,30 @@ declare export var PlutusDatumSchema: {| /** */ -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 |}; /** */ -declare export var RedeemerTagKind: {| - +Spend: 0, // 0 - +Mint: 1, // 1 - +Cert: 2, // 2 - +Reward: 3, // 3 - +Vote: 4, // 4 - +VotingProposal: 5, // 5 +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 +|}; + +/** + */ + +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 |}; /** @@ -348,6 +350,39 @@ declare export var NativeScriptKind: {| +TimelockExpiry: 5, // 5 |}; +/** + */ + +declare export var GovernanceActionKind: {| + +ParameterChangeAction: 0, // 0 + +HardForkInitiationAction: 1, // 1 + +TreasuryWithdrawalsAction: 2, // 2 + +NoConfidenceAction: 3, // 3 + +UpdateCommitteeAction: 4, // 4 + +NewConstitutionAction: 5, // 5 + +InfoAction: 6, // 6 +|}; + +/** + */ + +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 +|}; + +/** + */ + +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 +|}; + /** */ @@ -360,34 +395,34 @@ declare export var RelayKind: {| /** */ -declare export var AddressKind: {| - +Base: 0, // 0 - +Pointer: 1, // 1 - +Enterprise: 2, // 2 - +Reward: 3, // 3 - +Byron: 4, // 4 - +Malformed: 5, // 5 +declare export var CborContainerType: {| + +Array: 0, // 0 + +Map: 1, // 1 |}; /** */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** */ -declare export var GovernanceActionKind: {| - +ParameterChangeAction: 0, // 0 - +HardForkInitiationAction: 1, // 1 - +TreasuryWithdrawalsAction: 2, // 2 - +NoConfidenceAction: 3, // 3 - +UpdateCommitteeAction: 4, // 4 - +NewConstitutionAction: 5, // 5 - +InfoAction: 6, // 6 +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 +|}; + +/** + */ + +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** @@ -416,53 +451,65 @@ declare export var CertificateKind: {| /** */ -declare export var LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 +declare export var BlockEra: {| + +Byron: 0, // 0 + +Shelley: 1, // 1 + +Allegra: 2, // 2 + +Mary: 3, // 3 + +Alonzo: 4, // 4 + +Babbage: 5, // 5 + +Conway: 6, // 6 + +Unknown: 7, // 7 |}; /** */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 |}; /** */ -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 |}; /** */ -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 +declare export var AddressKind: {| + +Base: 0, // 0 + +Pointer: 1, // 1 + +Enterprise: 2, // 2 + +Reward: 3, // 3 + +Byron: 4, // 4 + +Malformed: 5, // 5 |}; /** + * Used to choosed the schema for a script JSON string */ -declare export var CborContainerType: {| - +Array: 0, // 0 - +Map: 1, // 1 +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** */ -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 +declare export var RedeemerTagKind: {| + +Spend: 0, // 0 + +Mint: 1, // 1 + +Cert: 2, // 2 + +Reward: 3, // 3 + +Vote: 4, // 4 + +VotingProposal: 5, // 5 |}; /** @@ -475,53 +522,6 @@ declare export var CoinSelectionStrategyCIP2: {| +RandomImproveMultiAsset: 3, // 3 |}; -/** - */ - -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 -|}; - -/** - * Each new language uses a different namespace for hashing its script - * This is because you could have a language where the same bytes have different semantics - * So this avoids scripts in different languages mapping to the same hash - * Note that the enum value here is different than the enum value for deciding the cost model of a script - */ - -declare export var ScriptHashNamespace: {| - +NativeScript: 0, // 0 - +PlutusScript: 1, // 1 - +PlutusScriptV2: 2, // 2 - +PlutusScriptV3: 3, // 3 -|}; - -/** - */ - -declare export var BlockEra: {| - +Byron: 0, // 0 - +Shelley: 1, // 1 - +Allegra: 2, // 2 - +Mary: 3, // 3 - +Alonzo: 4, // 4 - +Babbage: 5, // 5 - +Conway: 6, // 6 - +Unknown: 7, // 7 -|}; - -/** - */ - -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 -|}; - /** */ declare export class Address { @@ -2450,7 +2450,7 @@ declare export class CommitteeColdResign { /** * @returns {Credential} */ - committee_cold_key(): Credential; + committee_cold_credential(): Credential; /** * @returns {Anchor | void} @@ -2458,18 +2458,18 @@ declare export class CommitteeColdResign { anchor(): Anchor | void; /** - * @param {Credential} committee_cold_key + * @param {Credential} committee_cold_credential * @returns {CommitteeColdResign} */ - static new(committee_cold_key: Credential): CommitteeColdResign; + static new(committee_cold_credential: Credential): CommitteeColdResign; /** - * @param {Credential} committee_cold_key + * @param {Credential} committee_cold_credential * @param {Anchor} anchor * @returns {CommitteeColdResign} */ static new_with_anchor( - committee_cold_key: Credential, + committee_cold_credential: Credential, anchor: Anchor ): CommitteeColdResign; @@ -2524,21 +2524,21 @@ declare export class CommitteeHotAuth { /** * @returns {Credential} */ - committee_cold_key(): Credential; + committee_cold_credential(): Credential; /** * @returns {Credential} */ - committee_hot_key(): Credential; + committee_hot_credential(): Credential; /** - * @param {Credential} committee_cold_key - * @param {Credential} committee_hot_key + * @param {Credential} committee_cold_credential + * @param {Credential} committee_hot_credential * @returns {CommitteeHotAuth} */ static new( - committee_cold_key: Credential, - committee_hot_key: Credential + committee_cold_credential: Credential, + committee_hot_credential: Credential ): CommitteeHotAuth; /** @@ -14743,12 +14743,12 @@ export interface StakeToCoinJSON { stake_cred: CredTypeJSON; } export interface CommitteeHotAuthJSON { - committee_cold_key: CredTypeJSON; - committee_hot_key: CredTypeJSON; + committee_cold_credential: CredTypeJSON; + committee_hot_credential: CredTypeJSON; } export interface CommitteeColdResignJSON { anchor?: AnchorJSON | null; - committee_cold_key: CredTypeJSON; + committee_cold_credential: CredTypeJSON; } export interface DRepDeregistrationJSON { coin: string; diff --git a/rust/src/builders/certificates_builder.rs b/rust/src/builders/certificates_builder.rs index 2e94dc22..50eaed1b 100644 --- a/rust/src/builders/certificates_builder.rs +++ b/rust/src/builders/certificates_builder.rs @@ -268,12 +268,12 @@ fn witness_keys_for_cert(cert_enum: &Certificate) -> RequiredSigners { // not witness as there is no single core node or genesis key that posts the certificate CertificateEnum::MoveInstantaneousRewardsCert(_cert) => {} CertificateEnum::CommitteeHotAuth(cert) => { - if let CredType::Key(key_hash) = &cert.committee_cold_key.0 { + if let CredType::Key(key_hash) = &cert.committee_cold_credential.0 { set.add(key_hash); } } CertificateEnum::CommitteeColdResign(cert) => { - if let CredType::Key(key_hash) = &cert.committee_cold_key.0 { + if let CredType::Key(key_hash) = &cert.committee_cold_credential.0 { set.add(key_hash); } } diff --git a/rust/src/protocol_types/certificates/committee_cold_resign.rs b/rust/src/protocol_types/certificates/committee_cold_resign.rs index f2ddac68..6e28d85e 100644 --- a/rust/src/protocol_types/certificates/committee_cold_resign.rs +++ b/rust/src/protocol_types/certificates/committee_cold_resign.rs @@ -14,7 +14,7 @@ use crate::*; )] #[wasm_bindgen] pub struct CommitteeColdResign { - pub(crate) committee_cold_key: Credential, + pub(crate) committee_cold_credential: Credential, pub(crate) anchor: Option, } @@ -22,29 +22,29 @@ impl_to_from!(CommitteeColdResign); #[wasm_bindgen] impl CommitteeColdResign { - pub fn committee_cold_key(&self) -> Credential { - self.committee_cold_key.clone() + pub fn committee_cold_credential(&self) -> Credential { + self.committee_cold_credential.clone() } pub fn anchor(&self) -> Option { self.anchor.clone() } - pub fn new(committee_cold_key: &Credential) -> Self { + pub fn new(committee_cold_credential: &Credential) -> Self { Self { - committee_cold_key: committee_cold_key.clone(), + committee_cold_credential: committee_cold_credential.clone(), anchor: None, } } - pub fn new_with_anchor(committee_cold_key: &Credential, anchor: &Anchor) -> Self { + pub fn new_with_anchor(committee_cold_credential: &Credential, anchor: &Anchor) -> Self { Self { - committee_cold_key: committee_cold_key.clone(), + committee_cold_credential: committee_cold_credential.clone(), anchor: Some(anchor.clone()), } } pub fn has_script_credentials(&self) -> bool { - self.committee_cold_key.has_script_hash() + self.committee_cold_credential.has_script_hash() } } diff --git a/rust/src/protocol_types/certificates/committee_hot_auth.rs b/rust/src/protocol_types/certificates/committee_hot_auth.rs index cfe9120f..d0adaa39 100644 --- a/rust/src/protocol_types/certificates/committee_hot_auth.rs +++ b/rust/src/protocol_types/certificates/committee_hot_auth.rs @@ -14,30 +14,30 @@ use crate::*; )] #[wasm_bindgen] pub struct CommitteeHotAuth { - pub(crate) committee_cold_key: Credential, - pub(crate) committee_hot_key: Credential, + pub(crate) committee_cold_credential: Credential, + pub(crate) committee_hot_credential: Credential, } impl_to_from!(CommitteeHotAuth); #[wasm_bindgen] impl CommitteeHotAuth { - pub fn committee_cold_key(&self) -> Credential { - self.committee_cold_key.clone() + pub fn committee_cold_credential(&self) -> Credential { + self.committee_cold_credential.clone() } - pub fn committee_hot_key(&self) -> Credential { - self.committee_hot_key.clone() + pub fn committee_hot_credential(&self) -> Credential { + self.committee_hot_credential.clone() } - pub fn new(committee_cold_key: &Credential, committee_hot_key: &Credential) -> Self { + pub fn new(committee_cold_credential: &Credential, committee_hot_credential: &Credential) -> Self { Self { - committee_cold_key: committee_cold_key.clone(), - committee_hot_key: committee_hot_key.clone(), + committee_cold_credential: committee_cold_credential.clone(), + committee_hot_credential: committee_hot_credential.clone(), } } pub fn has_script_credentials(&self) -> bool { - self.committee_cold_key.has_script_hash() + self.committee_cold_credential.has_script_hash() } } diff --git a/rust/src/protocol_types/governance/voter.rs b/rust/src/protocol_types/governance/voter.rs index d6f7bd05..dbd7932f 100644 --- a/rust/src/protocol_types/governance/voter.rs +++ b/rust/src/protocol_types/governance/voter.rs @@ -13,7 +13,7 @@ use crate::*; JsonSchema, )] pub(crate) enum VoterEnum { - ConstitutionalCommitteeHotKey(Credential), + ConstitutionalCommitteeHotCred(Credential), DRep(Credential), StakingPool(Ed25519KeyHash), } @@ -47,21 +47,21 @@ impl_to_from!(Voter); #[wasm_bindgen] impl Voter { - pub fn new_constitutional_committee_hot_key(cred: &Credential) -> Self { - Self(VoterEnum::ConstitutionalCommitteeHotKey(cred.clone())) + pub fn new_constitutional_committee_hot_credential(cred: &Credential) -> Self { + Self(VoterEnum::ConstitutionalCommitteeHotCred(cred.clone())) } - pub fn new_drep(cred: &Credential) -> Self { + pub fn new_drep_credential(cred: &Credential) -> Self { Self(VoterEnum::DRep(cred.clone())) } - pub fn new_staking_pool(key_hash: &Ed25519KeyHash) -> Self { + pub fn new_stake_pool_key_hash(key_hash: &Ed25519KeyHash) -> Self { Self(VoterEnum::StakingPool(key_hash.clone())) } pub fn kind(&self) -> VoterKind { match &self.0 { - VoterEnum::ConstitutionalCommitteeHotKey(cred) => match cred.kind() { + VoterEnum::ConstitutionalCommitteeHotCred(cred) => match cred.kind() { CredKind::Key => VoterKind::ConstitutionalCommitteeHotKeyHash, CredKind::Script => VoterKind::ConstitutionalCommitteeHotScriptHash, }, @@ -73,21 +73,21 @@ impl Voter { } } - pub fn to_constitutional_committee_hot_key(&self) -> Option { + pub fn to_constitutional_committee_hot_credential(&self) -> Option { match &self.0 { - VoterEnum::ConstitutionalCommitteeHotKey(cred) => Some(cred.clone()), + VoterEnum::ConstitutionalCommitteeHotCred(cred) => Some(cred.clone()), _ => None, } } - pub fn to_drep_cred(&self) -> Option { + pub fn to_drep_credential(&self) -> Option { match &self.0 { VoterEnum::DRep(cred) => Some(cred.clone()), _ => None, } } - pub fn to_staking_pool_key_hash(&self) -> Option { + pub fn to_stake_pool_key_hash(&self) -> Option { match &self.0 { VoterEnum::StakingPool(key_hash) => Some(key_hash.clone()), _ => None, @@ -96,7 +96,7 @@ impl Voter { pub fn has_script_credentials(&self) -> bool { match &self.0 { - VoterEnum::ConstitutionalCommitteeHotKey(cred) => cred.has_script_hash(), + VoterEnum::ConstitutionalCommitteeHotCred(cred) => cred.has_script_hash(), VoterEnum::DRep(cred) => cred.has_script_hash(), VoterEnum::StakingPool(_) => false, } @@ -104,7 +104,7 @@ impl Voter { pub fn to_key_hash(&self) -> Option { match &self.0 { - VoterEnum::ConstitutionalCommitteeHotKey(cred) => cred.to_keyhash(), + VoterEnum::ConstitutionalCommitteeHotCred(cred) => cred.to_keyhash(), VoterEnum::DRep(cred) => cred.to_keyhash(), VoterEnum::StakingPool(key_hash) => Some(key_hash.clone()), } diff --git a/rust/src/serialization/certificates/committee_cold_resign.rs b/rust/src/serialization/certificates/committee_cold_resign.rs index 1519da52..f00adcbe 100644 --- a/rust/src/serialization/certificates/committee_cold_resign.rs +++ b/rust/src/serialization/certificates/committee_cold_resign.rs @@ -14,7 +14,7 @@ impl cbor_event::se::Serialize for CommitteeColdResign { let proposal_index = CertificateIndexNames::CommitteeColdResign.to_u64(); serialize_and_check_index(serializer, proposal_index, "CommitteeColdResign")?; - self.committee_cold_key.serialize(serializer)?; + self.committee_cold_credential.serialize(serializer)?; self.anchor.serialize_nullable(serializer)?; Ok(serializer) } @@ -36,6 +36,6 @@ impl DeserializeEmbeddedGroup for CommitteeColdResign { Credential::deserialize(raw).map_err(|e| e.annotate("committee_cold_key"))?; let anchor = Anchor::deserialize_nullable(raw).map_err(|e| e.annotate("anchor"))?; - Ok(CommitteeColdResign { committee_cold_key, anchor }) + Ok(CommitteeColdResign { committee_cold_credential: committee_cold_key, anchor }) } } diff --git a/rust/src/serialization/certificates/committee_hot_auth.rs b/rust/src/serialization/certificates/committee_hot_auth.rs index 3e6a97b9..9f378ceb 100644 --- a/rust/src/serialization/certificates/committee_hot_auth.rs +++ b/rust/src/serialization/certificates/committee_hot_auth.rs @@ -15,8 +15,8 @@ impl cbor_event::se::Serialize for CommitteeHotAuth { let proposal_index = CertificateIndexNames::CommitteeHotAuth.to_u64(); serialize_and_check_index(serializer, proposal_index, "CommitteeHotAuth")?; - self.committee_cold_key.serialize(serializer)?; - self.committee_hot_key.serialize(serializer)?; + self.committee_cold_credential.serialize(serializer)?; + self.committee_hot_credential.serialize(serializer)?; Ok(serializer) } } @@ -43,9 +43,9 @@ impl DeserializeEmbeddedGroup for CommitteeHotAuth { let committee_hot_key = Credential::deserialize(raw).map_err(|e| e.annotate("committee_hot_key"))?; - return Ok(CommitteeHotAuth { - committee_cold_key, - committee_hot_key, - }); + Ok(CommitteeHotAuth { + committee_cold_credential: committee_cold_key, + committee_hot_credential: committee_hot_key, + }) } } diff --git a/rust/src/serialization/governance/voter.rs b/rust/src/serialization/governance/voter.rs index 3badffd9..f4529709 100644 --- a/rust/src/serialization/governance/voter.rs +++ b/rust/src/serialization/governance/voter.rs @@ -26,7 +26,7 @@ impl cbor_event::se::Serialize for VoterEnum { ) -> cbor_event::Result<&'se mut Serializer> { serializer.write_array(cbor_event::Len::Len(2))?; match &self { - VoterEnum::ConstitutionalCommitteeHotKey(cred) => match &cred.0 { + VoterEnum::ConstitutionalCommitteeHotCred(cred) => match &cred.0 { CredType::Key(key_hash) => { serializer.write_unsigned_integer(0u64)?; key_hash.serialize(serializer)?; @@ -70,10 +70,10 @@ impl Deserialize for VoterEnum { } } let voter = match raw.unsigned_integer()? { - 0 => VoterEnum::ConstitutionalCommitteeHotKey(Credential(CredType::Key( + 0 => VoterEnum::ConstitutionalCommitteeHotCred(Credential(CredType::Key( Ed25519KeyHash::deserialize(raw)?, ))), - 1 => VoterEnum::ConstitutionalCommitteeHotKey(Credential(CredType::Script( + 1 => VoterEnum::ConstitutionalCommitteeHotCred(Credential(CredType::Script( ScriptHash::deserialize(raw)?, ))), 2 => VoterEnum::DRep(Credential(CredType::Key(Ed25519KeyHash::deserialize( diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index 72902986..22c2b8f4 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -5946,7 +5946,7 @@ fn ref_script_fee_from_all_builders() { ).unwrap(); voting_builder.add_with_plutus_witness( - &Voter::new_drep(&Credential::from_scripthash(&script_hash_5)), + &Voter::new_drep_credential(&Credential::from_scripthash(&script_hash_5)), &GovernanceActionId::new(&fake_tx_hash(1), 1), &VotingProcedure::new(VoteKind::Abstain), &PlutusWitness::new_with_ref_without_datum(&plutus_source_5, &redeemer_5) @@ -6298,7 +6298,7 @@ fn ref_inputs_debuplication_test() { ).unwrap(); voting_builder.add_with_plutus_witness( - &Voter::new_drep(&Credential::from_scripthash(&script_hash_5)), + &Voter::new_drep_credential(&Credential::from_scripthash(&script_hash_5)), &GovernanceActionId::new(&fake_tx_hash(1), 1), &VotingProcedure::new(VoteKind::Abstain), &PlutusWitness::new_with_ref_without_datum(&plutus_source_5, &redeemer_5) diff --git a/rust/src/tests/builders/voting_builder.rs b/rust/src/tests/builders/voting_builder.rs index f4afb9c6..df627bf7 100644 --- a/rust/src/tests/builders/voting_builder.rs +++ b/rust/src/tests/builders/voting_builder.rs @@ -13,9 +13,9 @@ fn voting_builder_key_signers_test() { let action_id_3 = GovernanceActionId::new(&fake_tx_hash(3), 3); let vote = VotingProcedure::new(VoteKind::No); let voter_1 = - Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash(&key_hash_1)); - let voter_2 = Voter::new_drep(&Credential::from_keyhash(&key_hash_2)); - let voter_3 = Voter::new_staking_pool(&key_hash_3); + Voter::new_constitutional_committee_hot_credential(&Credential::from_keyhash(&key_hash_1)); + let voter_2 = Voter::new_drep_credential(&Credential::from_keyhash(&key_hash_2)); + let voter_3 = Voter::new_stake_pool_key_hash(&key_hash_3); builder.add(&voter_1, &action_id_1, &vote).unwrap(); builder.add(&voter_1, &action_id_2, &vote).unwrap(); builder.add(&voter_2, &action_id_2, &vote).unwrap(); @@ -92,7 +92,7 @@ fn voting_builder_plutus_witness() { ); let expected_redeemer = redeemer.clone_with_index_and_tag(&BigNum::zero(), &RedeemerTag::new_vote()); - let voter = Voter::new_drep(&Credential::from_scripthash(&script_hash)); + let voter = Voter::new_drep_credential(&Credential::from_scripthash(&script_hash)); let action_id = GovernanceActionId::new(&fake_tx_hash(1), 1); let vote = VotingProcedure::new(VoteKind::No); @@ -181,7 +181,7 @@ fn voting_builder_plutus_ref_witness() { let ref_input = TransactionInput::new(&fake_tx_hash(5), 0); let expected_redeemer = redeemer.clone_with_index_and_tag(&BigNum::zero(), &RedeemerTag::new_vote()); - let voter = Voter::new_drep(&Credential::from_scripthash(&script_hash)); + let voter = Voter::new_drep_credential(&Credential::from_scripthash(&script_hash)); let action_id = GovernanceActionId::new(&fake_tx_hash(1), 1); let vote = VotingProcedure::new(VoteKind::No); @@ -257,7 +257,7 @@ fn voting_builder_native_script_witness() { let native_script = NativeScript::new_script_pubkey(&ScriptPubkey::new(&key_hash)); let script_hash = native_script.hash(); - let voter = Voter::new_drep(&Credential::from_scripthash(&script_hash)); + let voter = Voter::new_drep_credential(&Credential::from_scripthash(&script_hash)); let action_id = GovernanceActionId::new(&fake_tx_hash(1), 1); let vote = VotingProcedure::new(VoteKind::No); @@ -325,7 +325,7 @@ fn voting_builder_native_script_ref_witness() { let key_hash = fake_key_hash(10); let script_hash = fake_script_hash(1); - let voter = Voter::new_drep(&Credential::from_scripthash(&script_hash)); + let voter = Voter::new_drep_credential(&Credential::from_scripthash(&script_hash)); let action_id = GovernanceActionId::new(&fake_tx_hash(1), 1); let vote = VotingProcedure::new(VoteKind::No); @@ -399,7 +399,7 @@ fn voting_builder_native_script_ref_witness() { fn voting_builder_non_script_voter_error() { let mut builder = VotingBuilder::new(); let key_hash = fake_key_hash(10); - let voter = Voter::new_drep(&Credential::from_keyhash(&key_hash)); + let voter = Voter::new_drep_credential(&Credential::from_keyhash(&key_hash)); let action_id = GovernanceActionId::new(&fake_tx_hash(1), 1); let vote = VotingProcedure::new(VoteKind::No); @@ -425,7 +425,7 @@ fn voting_builder_non_script_voter_error() { #[test] fn voting_builder_key_hash_error() { let mut builder = VotingBuilder::new(); - let voter = Voter::new_drep(&Credential::from_scripthash(&fake_script_hash(1))); + let voter = Voter::new_drep_credential(&Credential::from_scripthash(&fake_script_hash(1))); let action_id = GovernanceActionId::new(&fake_tx_hash(1), 1); let vote = VotingProcedure::new(VoteKind::No); diff --git a/rust/src/tests/protocol_types/certificates.rs b/rust/src/tests/protocol_types/certificates.rs index b367f0fb..3476d3cc 100644 --- a/rust/src/tests/protocol_types/certificates.rs +++ b/rust/src/tests/protocol_types/certificates.rs @@ -10,12 +10,12 @@ fn committee_cold_resign_setters_getters_test() { let committee_cold_resign_2 = CommitteeColdResign::new(&cred_script_hash); assert_eq!( - committee_cold_resign_1.committee_cold_key(), + committee_cold_resign_1.committee_cold_credential(), cred_key_hash ); assert!(!committee_cold_resign_1.has_script_credentials()); assert_eq!( - committee_cold_resign_2.committee_cold_key(), + committee_cold_resign_2.committee_cold_credential(), cred_script_hash ); assert!(committee_cold_resign_2.has_script_credentials()); @@ -29,11 +29,11 @@ fn committee_hot_auth_setters_getters_test() { CommitteeHotAuth::new(&cold_cred_key_hash, &hot_cred_key_hash); assert_eq!( - committee_hot_auth.committee_cold_key(), + committee_hot_auth.committee_cold_credential(), cold_cred_key_hash ); assert_eq!( - committee_hot_auth.committee_hot_key(), + committee_hot_auth.committee_hot_credential(), hot_cred_key_hash ); assert!(!committee_hot_auth.has_script_credentials()); diff --git a/rust/src/tests/protocol_types/governance/common.rs b/rust/src/tests/protocol_types/governance/common.rs index 7aebf60e..c88964b1 100644 --- a/rust/src/tests/protocol_types/governance/common.rs +++ b/rust/src/tests/protocol_types/governance/common.rs @@ -90,14 +90,14 @@ fn governance_action_ids_setters_getters_test() { #[test] fn voter_drep_key_hash_setters_getters_test() { let key_hash = fake_key_hash(1); - let voter = Voter::new_drep(&Credential::from_keyhash(&key_hash)); + let voter = Voter::new_drep_credential(&Credential::from_keyhash(&key_hash)); assert_eq!(voter.kind(), VoterKind::DRepKeyHash); assert_eq!( - voter.to_drep_cred(), + voter.to_drep_credential(), Some(Credential::from_keyhash(&key_hash)) ); - assert_eq!(voter.to_staking_pool_key_hash(), None); - assert_eq!(voter.to_constitutional_committee_hot_key(), None); + assert_eq!(voter.to_stake_pool_key_hash(), None); + assert_eq!(voter.to_constitutional_committee_hot_credential(), None); assert_eq!(voter.has_script_credentials(), false); assert_eq!(voter.to_key_hash(), Some(key_hash)); } @@ -105,14 +105,14 @@ fn voter_drep_key_hash_setters_getters_test() { #[test] fn voter_drep_script_hash_setters_getters_test() { let script_hash = fake_script_hash(1); - let voter = Voter::new_drep(&Credential::from_scripthash(&script_hash)); + let voter = Voter::new_drep_credential(&Credential::from_scripthash(&script_hash)); assert_eq!(voter.kind(), VoterKind::DRepScriptHash); assert_eq!( - voter.to_drep_cred(), + voter.to_drep_credential(), Some(Credential::from_scripthash(&script_hash)) ); - assert_eq!(voter.to_staking_pool_key_hash(), None); - assert_eq!(voter.to_constitutional_committee_hot_key(), None); + assert_eq!(voter.to_stake_pool_key_hash(), None); + assert_eq!(voter.to_constitutional_committee_hot_credential(), None); assert_eq!(voter.has_script_credentials(), true); assert_eq!(voter.to_key_hash(), None); } @@ -120,14 +120,14 @@ fn voter_drep_script_hash_setters_getters_test() { #[test] fn voter_constitutional_committee_hot_key_hash_setters_getters_test() { let key_hash = fake_key_hash(1); - let voter = Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash(&key_hash)); + let voter = Voter::new_constitutional_committee_hot_credential(&Credential::from_keyhash(&key_hash)); assert_eq!(voter.kind(), VoterKind::ConstitutionalCommitteeHotKeyHash); assert_eq!( - voter.to_constitutional_committee_hot_key(), + voter.to_constitutional_committee_hot_credential(), Some(Credential::from_keyhash(&key_hash)) ); - assert_eq!(voter.to_staking_pool_key_hash(), None); - assert_eq!(voter.to_drep_cred(), None); + assert_eq!(voter.to_stake_pool_key_hash(), None); + assert_eq!(voter.to_drep_credential(), None); assert_eq!(voter.has_script_credentials(), false); assert_eq!(voter.to_key_hash(), Some(key_hash)); } @@ -136,17 +136,17 @@ fn voter_constitutional_committee_hot_key_hash_setters_getters_test() { fn voter_constitutional_committee_hot_script_hash_setters_getters_test() { let script_hash = fake_script_hash(1); let voter = - Voter::new_constitutional_committee_hot_key(&Credential::from_scripthash(&script_hash)); + Voter::new_constitutional_committee_hot_credential(&Credential::from_scripthash(&script_hash)); assert_eq!( voter.kind(), VoterKind::ConstitutionalCommitteeHotScriptHash ); assert_eq!( - voter.to_constitutional_committee_hot_key(), + voter.to_constitutional_committee_hot_credential(), Some(Credential::from_scripthash(&script_hash)) ); - assert_eq!(voter.to_staking_pool_key_hash(), None); - assert_eq!(voter.to_drep_cred(), None); + assert_eq!(voter.to_stake_pool_key_hash(), None); + assert_eq!(voter.to_drep_credential(), None); assert_eq!(voter.has_script_credentials(), true); assert_eq!(voter.to_key_hash(), None); } @@ -154,11 +154,11 @@ fn voter_constitutional_committee_hot_script_hash_setters_getters_test() { #[test] fn voter_staking_pool_key_hash_setters_getters_test() { let key_hash = fake_key_hash(1); - let voter = Voter::new_staking_pool(&key_hash); + let voter = Voter::new_stake_pool_key_hash(&key_hash); assert_eq!(voter.kind(), VoterKind::StakingPoolKeyHash); - assert_eq!(voter.to_staking_pool_key_hash(), Some(key_hash.clone())); - assert_eq!(voter.to_constitutional_committee_hot_key(), None); - assert_eq!(voter.to_drep_cred(), None); + assert_eq!(voter.to_stake_pool_key_hash(), Some(key_hash.clone())); + assert_eq!(voter.to_constitutional_committee_hot_credential(), None); + assert_eq!(voter.to_drep_credential(), None); assert_eq!(voter.has_script_credentials(), false); assert_eq!(voter.to_key_hash(), Some(key_hash)); } @@ -166,9 +166,9 @@ fn voter_staking_pool_key_hash_setters_getters_test() { #[test] fn voters_setters_getters_test() { let key_hash_1 = fake_key_hash(1); - let voter_1 = Voter::new_staking_pool(&key_hash_1); + let voter_1 = Voter::new_stake_pool_key_hash(&key_hash_1); let key_hash_2 = fake_key_hash(2); - let voter_2 = Voter::new_staking_pool(&key_hash_2); + let voter_2 = Voter::new_stake_pool_key_hash(&key_hash_2); let mut voters = Voters::new(); voters.add(&voter_1); voters.add(&voter_2); @@ -212,9 +212,9 @@ fn voting_procedure_with_anchor_setters_getters_test() { #[test] fn voting_procedures_setters_getters_test() { let key_hash_1 = fake_key_hash(1); - let voter_1 = Voter::new_staking_pool(&key_hash_1); + let voter_1 = Voter::new_stake_pool_key_hash(&key_hash_1); let key_hash_2 = fake_key_hash(2); - let voter_2 = Voter::new_staking_pool(&key_hash_2); + let voter_2 = Voter::new_stake_pool_key_hash(&key_hash_2); let governance_action_id_1 = GovernanceActionId::new(&fake_tx_hash(1), 1); let governance_action_id_2 = GovernanceActionId::new(&fake_tx_hash(2), 2); let governance_action_id_3 = GovernanceActionId::new(&fake_tx_hash(3), 3); diff --git a/rust/src/tests/serialization/governance/common.rs b/rust/src/tests/serialization/governance/common.rs index 3c577f82..930f1476 100644 --- a/rust/src/tests/serialization/governance/common.rs +++ b/rust/src/tests/serialization/governance/common.rs @@ -123,7 +123,7 @@ fn governance_action_id_ser_round_trip() { #[test] fn voter_constitutional_committee_hot_key_hash_ser_round_trip() { let voter = - Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash(&fake_key_hash(1))); + Voter::new_constitutional_committee_hot_credential(&Credential::from_keyhash(&fake_key_hash(1))); let cbor = voter.to_bytes(); let cbor_hex = voter.to_hex(); @@ -137,7 +137,7 @@ fn voter_constitutional_committee_hot_key_hash_ser_round_trip() { #[test] fn voter_constitutional_committee_hot_script_hash_ser_round_trip() { - let voter = Voter::new_constitutional_committee_hot_key(&Credential::from_scripthash( + let voter = Voter::new_constitutional_committee_hot_credential(&Credential::from_scripthash( &fake_script_hash(1), )); @@ -156,7 +156,7 @@ fn voter_constitutional_committee_hot_script_hash_ser_round_trip() { #[test] fn voter_drep_key_hash_ser_round_trip() { - let voter = Voter::new_drep(&Credential::from_keyhash(&fake_key_hash(1))); + let voter = Voter::new_drep_credential(&Credential::from_keyhash(&fake_key_hash(1))); let cbor = voter.to_bytes(); let cbor_hex = voter.to_hex(); @@ -170,7 +170,7 @@ fn voter_drep_key_hash_ser_round_trip() { #[test] fn voter_drep_script_hash_ser_round_trip() { - let voter = Voter::new_drep(&Credential::from_scripthash(&fake_script_hash(1))); + let voter = Voter::new_drep_credential(&Credential::from_scripthash(&fake_script_hash(1))); let cbor = voter.to_bytes(); let cbor_hex = voter.to_hex(); @@ -184,7 +184,7 @@ fn voter_drep_script_hash_ser_round_trip() { #[test] fn voter_staking_pool_ser_round_trip() { - let voter = Voter::new_staking_pool(&fake_key_hash(1)); + let voter = Voter::new_stake_pool_key_hash(&fake_key_hash(1)); let cbor = voter.to_bytes(); let cbor_hex = voter.to_hex(); @@ -252,7 +252,7 @@ fn voting_procedures_single_item_ser_round_trip() { let mut voting_procedures = VotingProcedures::new(); voting_procedures.insert( - &Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash(&fake_key_hash(1))), + &Voter::new_constitutional_committee_hot_credential(&Credential::from_keyhash(&fake_key_hash(1))), &GovernanceActionId::new(&fake_tx_hash(1), GovernanceActionIndex::from(42u32)), &VotingProcedure::new(VoteKind::Yes), ); @@ -280,19 +280,19 @@ fn voting_procedures_muiltiple_items_ser_round_trip() { let mut voting_procedures = VotingProcedures::new(); voting_procedures.insert( - &Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash(&fake_key_hash(1))), + &Voter::new_constitutional_committee_hot_credential(&Credential::from_keyhash(&fake_key_hash(1))), &GovernanceActionId::new(&fake_tx_hash(1), GovernanceActionIndex::from(42u32)), &VotingProcedure::new(VoteKind::Yes), ); voting_procedures.insert( - &Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash(&fake_key_hash(2))), + &Voter::new_constitutional_committee_hot_credential(&Credential::from_keyhash(&fake_key_hash(2))), &GovernanceActionId::new(&fake_tx_hash(2), GovernanceActionIndex::from(43u32)), &VotingProcedure::new(VoteKind::No), ); voting_procedures.insert( - &Voter::new_constitutional_committee_hot_key(&Credential::from_keyhash(&fake_key_hash(3))), + &Voter::new_constitutional_committee_hot_credential(&Credential::from_keyhash(&fake_key_hash(3))), &GovernanceActionId::new(&fake_tx_hash(3), GovernanceActionIndex::from(44u32)), &VotingProcedure::new(VoteKind::Abstain), ); diff --git a/rust/src/tests/serialization/transaction_body.rs b/rust/src/tests/serialization/transaction_body.rs index 6b741e5a..827a7b96 100644 --- a/rust/src/tests/serialization/transaction_body.rs +++ b/rust/src/tests/serialization/transaction_body.rs @@ -38,7 +38,7 @@ fn transaction_round_trip_test() { ); let mut voting_procedures = VotingProcedures::new(); - let voter = Voter::new_drep(&Credential::from_keyhash(&fake_key_hash(1))); + let voter = Voter::new_drep_credential(&Credential::from_keyhash(&fake_key_hash(1))); let gov_action_id = GovernanceActionId::new(&fake_tx_hash(2), 0); let procedure = VotingProcedure::new(VoteKind::Abstain); voting_procedures.insert(&voter, &gov_action_id, &procedure); From ad4b118fc2f07dedd62d0ae0072d96ee77beda63 Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 27 Aug 2024 00:41:30 +0900 Subject: [PATCH 346/349] version bump --- package-lock.json | 4 ++-- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6819d35c..eae0fc00 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.9", + "version": "12.0.0-beta.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.9", + "version": "12.0.0-beta.10", "hasInstallScript": true, "license": "MIT", "devDependencies": { diff --git a/package.json b/package.json index ad62d52a..752a0119 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.9", + "version": "12.0.0-beta.10", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index ed6763d0..e2704607 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-beta.9" +version = "12.0.0-beta.10" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 4fb0c904..442f5beb 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -49,7 +49,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-beta.9" +version = "12.0.0-beta.10" dependencies = [ "bech32", "cbor_event", From ed8c44899d41eaafdb8b745bf435141d1951ae4e Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 28 Aug 2024 11:36:33 +0900 Subject: [PATCH 347/349] fix plutus map serialization for multiple keys --- rust/src/protocol_types/plutus/plutus_data.rs | 4 +++ rust/src/serialization/plutus/plutus_data.rs | 2 +- rust/src/tests/general.rs | 33 +++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/rust/src/protocol_types/plutus/plutus_data.rs b/rust/src/protocol_types/plutus/plutus_data.rs index 3ca884e1..fcc4f97a 100644 --- a/rust/src/protocol_types/plutus/plutus_data.rs +++ b/rust/src/protocol_types/plutus/plutus_data.rs @@ -150,6 +150,10 @@ impl PlutusMap { .or_insert_with(PlutusMapValues::new); values.add_move(value); } + + pub(crate) fn total_len(&self) -> usize { + self.0.iter().map(|(_k, v)| v.len()).sum() + } } #[wasm_bindgen] diff --git a/rust/src/serialization/plutus/plutus_data.rs b/rust/src/serialization/plutus/plutus_data.rs index f5cdb167..f3ce5f64 100644 --- a/rust/src/serialization/plutus/plutus_data.rs +++ b/rust/src/serialization/plutus/plutus_data.rs @@ -69,7 +69,7 @@ impl cbor_event::se::Serialize for PlutusMap { &self, serializer: &'se mut Serializer, ) -> cbor_event::Result<&'se mut Serializer> { - serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?; + serializer.write_map(cbor_event::Len::Len(self.total_len() as u64))?; for (key, values) in &self.0 { for value in &values.elems { key.serialize(serializer)?; diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index d721c72d..d6b3273f 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -818,4 +818,37 @@ fn test_multiple_tiers() { let result = min_ref_script_fee(*size, &new_uinternal(1, 1000)).unwrap(); assert_eq!(result.to_str(), *expected, "Failed for size {}", size); } +} + +#[test] +fn plutus_map_keys_duplication_test() { + let mut map = PlutusMap::new(); + let key1 = PlutusData::new_integer(&BigInt::from(1)); + let key2 = PlutusData::new_integer(&BigInt::from(2)); + let value1 = PlutusData::new_integer(&BigInt::from(3)); + let value2 = PlutusData::new_integer(&BigInt::from(4)); + let value3 = PlutusData::new_integer(&BigInt::from(5)); + + assert_eq!(map.len(), 0); + assert_eq!(map.total_len(), 0); + + let mut plutus_map_value1 = PlutusMapValues::new(); + plutus_map_value1.add(&value1); + plutus_map_value1.add(&value2); + + let mut plutus_map_value2 = PlutusMapValues::new(); + plutus_map_value2.add(&value3); + + map.insert(&key1, &plutus_map_value1); + map.insert(&key2, &plutus_map_value2); + + assert_eq!(map.len(), 2); + assert_eq!(map.total_len(), 3); + + let map_bytes = map.to_bytes(); + let map_from_bytes = PlutusMap::from_bytes(map_bytes).unwrap(); + assert_eq!(map_from_bytes.len(), 2); + assert_eq!(map_from_bytes.total_len(), 3); + + assert_eq!(map, map_from_bytes) } \ No newline at end of file From f111d76703d70d961743a9ecb4816bbfee168847 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 28 Aug 2024 11:40:30 +0900 Subject: [PATCH 348/349] version bump --- package-lock.json | 4 ++-- package.json | 2 +- rust/Cargo.toml | 2 +- rust/json-gen/Cargo.lock | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index eae0fc00..006f489f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.10", + "version": "12.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.10", + "version": "12.0.0", "hasInstallScript": true, "license": "MIT", "devDependencies": { diff --git a/package.json b/package.json index 752a0119..8cebde4f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.0.0-beta.10", + "version": "12.0.0", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index e2704607..a9f78622 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.0.0-beta.10" +version = "12.0.0" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 442f5beb..dd98dbae 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -49,7 +49,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.0.0-beta.10" +version = "12.0.0" dependencies = [ "bech32", "cbor_event", From a2774f6905f4577675451d03013c62051bc8e491 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 28 Aug 2024 11:42:13 +0900 Subject: [PATCH 349/349] flow update --- rust/pkg/cardano_serialization_lib.js.flow | 432 ++++++++++----------- 1 file changed, 216 insertions(+), 216 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 85e423d5..ba623ef2 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -17,6 +17,30 @@ declare export function create_send_all( config: TransactionBuilderConfig ): TransactionBatchList; +/** + * @param {string} password + * @param {string} salt + * @param {string} nonce + * @param {string} data + * @returns {string} + */ +declare export function encrypt_with_password( + password: string, + salt: string, + nonce: string, + data: string +): string; + +/** + * @param {string} password + * @param {string} data + * @returns {string} + */ +declare export function decrypt_with_password( + password: string, + data: string +): string; + /** * @param {Transaction} tx * @param {LinearFee} linear_fee @@ -54,6 +78,70 @@ declare export function min_ref_script_fee( ref_script_coins_per_byte: UnitInterval ): BigNum; +/** + * @param {string} json + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {PlutusData} + */ +declare export function encode_json_str_to_plutus_datum( + json: string, + schema: $Values +): PlutusData; + +/** + * @param {PlutusData} datum + * @param {$Values< + typeof + PlutusDatumSchema>} schema + * @returns {string} + */ +declare export function decode_plutus_datum_to_json_str( + datum: PlutusData, + schema: $Values +): string; + +/** + * @param {Uint8Array} bytes + * @returns {TransactionMetadatum} + */ +declare export function encode_arbitrary_bytes_as_metadatum( + bytes: Uint8Array +): TransactionMetadatum; + +/** + * @param {TransactionMetadatum} metadata + * @returns {Uint8Array} + */ +declare export function decode_arbitrary_bytes_from_metadatum( + metadata: TransactionMetadatum +): Uint8Array; + +/** + * @param {string} json + * @param {$Values< + typeof + MetadataJsonSchema>} schema + * @returns {TransactionMetadatum} + */ +declare export function encode_json_str_to_metadatum( + json: string, + schema: $Values +): TransactionMetadatum; + +/** + * @param {TransactionMetadatum} metadatum + * @param {$Values< + typeof + MetadataJsonSchema>} schema + * @returns {string} + */ +declare export function decode_metadatum_to_json_str( + metadatum: TransactionMetadatum, + schema: $Values +): string; + /** * @param {TransactionHash} tx_body_hash * @param {ByronAddress} addr @@ -180,216 +268,148 @@ declare export function encode_json_str_to_native_script( ): NativeScript; /** - * @param {string} password - * @param {string} salt - * @param {string} nonce - * @param {string} data - * @returns {string} - */ -declare export function encrypt_with_password( - password: string, - salt: string, - nonce: string, - data: string -): string; - -/** - * @param {string} password - * @param {string} data - * @returns {string} - */ -declare export function decrypt_with_password( - password: string, - data: string -): string; - -/** - * @param {string} json - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {PlutusData} - */ -declare export function encode_json_str_to_plutus_datum( - json: string, - schema: $Values -): PlutusData; - -/** - * @param {PlutusData} datum - * @param {$Values< - typeof - PlutusDatumSchema>} schema - * @returns {string} - */ -declare export function decode_plutus_datum_to_json_str( - datum: PlutusData, - schema: $Values -): string; - -/** - * @param {Uint8Array} bytes - * @returns {TransactionMetadatum} */ -declare export function encode_arbitrary_bytes_as_metadatum( - bytes: Uint8Array -): TransactionMetadatum; -/** - * @param {TransactionMetadatum} metadata - * @returns {Uint8Array} - */ -declare export function decode_arbitrary_bytes_from_metadatum( - metadata: TransactionMetadatum -): Uint8Array; +declare export var MetadataJsonSchema: {| + +NoConversions: 0, // 0 + +BasicConversions: 1, // 1 + +DetailedSchema: 2, // 2 +|}; /** - * @param {string} json - * @param {$Values< - typeof - MetadataJsonSchema>} schema - * @returns {TransactionMetadatum} */ -declare export function encode_json_str_to_metadatum( - json: string, - schema: $Values -): TransactionMetadatum; -/** - * @param {TransactionMetadatum} metadatum - * @param {$Values< - typeof - MetadataJsonSchema>} schema - * @returns {string} - */ -declare export function decode_metadatum_to_json_str( - metadatum: TransactionMetadatum, - schema: $Values -): string; +declare export var VoterKind: {| + +ConstitutionalCommitteeHotKeyHash: 0, // 0 + +ConstitutionalCommitteeHotScriptHash: 1, // 1 + +DRepKeyHash: 2, // 2 + +DRepScriptHash: 3, // 3 + +StakingPoolKeyHash: 4, // 4 +|}; /** - * Each new language uses a different namespace for hashing its script - * This is because you could have a language where the same bytes have different semantics - * So this avoids scripts in different languages mapping to the same hash - * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var ScriptHashNamespace: {| - +NativeScript: 0, // 0 - +PlutusScript: 1, // 1 - +PlutusScriptV2: 2, // 2 - +PlutusScriptV3: 3, // 3 +declare export var CoinSelectionStrategyCIP2: {| + +LargestFirst: 0, // 0 + +RandomImprove: 1, // 1 + +LargestFirstMultiAsset: 2, // 2 + +RandomImproveMultiAsset: 3, // 3 |}; /** */ -declare export var PlutusDataKind: {| - +ConstrPlutusData: 0, // 0 - +Map: 1, // 1 - +List: 2, // 2 - +Integer: 3, // 3 - +Bytes: 4, // 4 +declare export var NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 |}; /** - * JSON <-> PlutusData conversion schemas. - * Follows ScriptDataJsonSchema in cardano-cli defined at: - * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 - * - * All methods here have the following restrictions due to limitations on dependencies: - * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors - * * Hex strings for bytes don't accept odd-length (half-byte) strings. - * cardano-cli seems to support these however but it seems to be different than just 0-padding - * on either side when tested so proceed with caution */ -declare export var PlutusDatumSchema: {| - +BasicConversions: 0, // 0 - +DetailedSchema: 1, // 1 +declare export var NativeScriptKind: {| + +ScriptPubkey: 0, // 0 + +ScriptAll: 1, // 1 + +ScriptAny: 2, // 2 + +ScriptNOfK: 3, // 3 + +TimelockStart: 4, // 4 + +TimelockExpiry: 5, // 5 |}; /** */ -declare export var TransactionMetadatumKind: {| - +MetadataMap: 0, // 0 - +MetadataList: 1, // 1 - +Int: 2, // 2 - +Bytes: 3, // 3 - +Text: 4, // 4 +declare export var VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 |}; /** */ -declare export var DRepKind: {| - +KeyHash: 0, // 0 - +ScriptHash: 1, // 1 - +AlwaysAbstain: 2, // 2 - +AlwaysNoConfidence: 3, // 3 +declare export var CertificateKind: {| + +StakeRegistration: 0, // 0 + +StakeDeregistration: 1, // 1 + +StakeDelegation: 2, // 2 + +PoolRegistration: 3, // 3 + +PoolRetirement: 4, // 4 + +GenesisKeyDelegation: 5, // 5 + +MoveInstantaneousRewardsCert: 6, // 6 + +CommitteeHotAuth: 7, // 7 + +CommitteeColdResign: 8, // 8 + +DRepDeregistration: 9, // 9 + +DRepRegistration: 10, // 10 + +DRepUpdate: 11, // 11 + +StakeAndVoteDelegation: 12, // 12 + +StakeRegistrationAndDelegation: 13, // 13 + +StakeVoteRegistrationAndDelegation: 14, // 14 + +VoteDelegation: 15, // 15 + +VoteRegistrationAndDelegation: 16, // 16 |}; /** */ -declare export var NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var AddressKind: {| + +Base: 0, // 0 + +Pointer: 1, // 1 + +Enterprise: 2, // 2 + +Reward: 3, // 3 + +Byron: 4, // 4 + +Malformed: 5, // 5 |}; /** + * Each new language uses a different namespace for hashing its script + * This is because you could have a language where the same bytes have different semantics + * So this avoids scripts in different languages mapping to the same hash + * Note that the enum value here is different than the enum value for deciding the cost model of a script */ -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 +declare export var ScriptHashNamespace: {| + +NativeScript: 0, // 0 + +PlutusScript: 1, // 1 + +PlutusScriptV2: 2, // 2 + +PlutusScriptV3: 3, // 3 |}; /** */ -declare export var GovernanceActionKind: {| - +ParameterChangeAction: 0, // 0 - +HardForkInitiationAction: 1, // 1 - +TreasuryWithdrawalsAction: 2, // 2 - +NoConfidenceAction: 3, // 3 - +UpdateCommitteeAction: 4, // 4 - +NewConstitutionAction: 5, // 5 - +InfoAction: 6, // 6 +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 |}; /** */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 4, // 4 +declare export var MIRPot: {| + +Reserves: 0, // 0 + +Treasury: 1, // 1 |}; /** + * Used to choosed the schema for a script JSON string */ -declare export var LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 +declare export var ScriptSchema: {| + +Wallet: 0, // 0 + +Node: 1, // 1 |}; /** */ -declare export var RelayKind: {| - +SingleHostAddr: 0, // 0 - +SingleHostName: 1, // 1 - +MultiHostName: 2, // 2 +declare export var TransactionMetadatumKind: {| + +MetadataMap: 0, // 0 + +MetadataList: 1, // 1 + +Int: 2, // 2 + +Bytes: 3, // 3 + +Text: 4, // 4 |}; /** @@ -403,18 +423,22 @@ declare export var CborContainerType: {| /** */ -declare export var VoteKind: {| - +No: 0, // 0 - +Yes: 1, // 1 - +Abstain: 2, // 2 +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 |}; /** */ -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 +declare export var DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 |}; /** @@ -425,29 +449,6 @@ declare export var CredKind: {| +Script: 1, // 1 |}; -/** - */ - -declare export var CertificateKind: {| - +StakeRegistration: 0, // 0 - +StakeDeregistration: 1, // 1 - +StakeDelegation: 2, // 2 - +PoolRegistration: 3, // 3 - +PoolRetirement: 4, // 4 - +GenesisKeyDelegation: 5, // 5 - +MoveInstantaneousRewardsCert: 6, // 6 - +CommitteeHotAuth: 7, // 7 - +CommitteeColdResign: 8, // 8 - +DRepDeregistration: 9, // 9 - +DRepRegistration: 10, // 10 - +DRepUpdate: 11, // 11 - +StakeAndVoteDelegation: 12, // 12 - +StakeRegistrationAndDelegation: 13, // 13 - +StakeVoteRegistrationAndDelegation: 14, // 14 - +VoteDelegation: 15, // 15 - +VoteRegistrationAndDelegation: 16, // 16 -|}; - /** */ @@ -465,39 +466,40 @@ declare export var BlockEra: {| /** */ -declare export var MIRPot: {| - +Reserves: 0, // 0 - +Treasury: 1, // 1 -|}; - -/** - */ - -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 +declare export var GovernanceActionKind: {| + +ParameterChangeAction: 0, // 0 + +HardForkInitiationAction: 1, // 1 + +TreasuryWithdrawalsAction: 2, // 2 + +NoConfidenceAction: 3, // 3 + +UpdateCommitteeAction: 4, // 4 + +NewConstitutionAction: 5, // 5 + +InfoAction: 6, // 6 |}; /** */ -declare export var AddressKind: {| - +Base: 0, // 0 - +Pointer: 1, // 1 - +Enterprise: 2, // 2 - +Reward: 3, // 3 - +Byron: 4, // 4 - +Malformed: 5, // 5 +declare export var RelayKind: {| + +SingleHostAddr: 0, // 0 + +SingleHostName: 1, // 1 + +MultiHostName: 2, // 2 |}; /** - * Used to choosed the schema for a script JSON string + * JSON <-> PlutusData conversion schemas. + * Follows ScriptDataJsonSchema in cardano-cli defined at: + * https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/ScriptData.hs#L254 + * + * All methods here have the following restrictions due to limitations on dependencies: + * * JSON numbers above u64::MAX (positive) or below i64::MIN (negative) will throw errors + * * Hex strings for bytes don't accept odd-length (half-byte) strings. + * cardano-cli seems to support these however but it seems to be different than just 0-padding + * on either side when tested so proceed with caution */ -declare export var ScriptSchema: {| - +Wallet: 0, // 0 - +Node: 1, // 1 +declare export var PlutusDatumSchema: {| + +BasicConversions: 0, // 0 + +DetailedSchema: 1, // 1 |}; /** @@ -515,11 +517,9 @@ declare export var RedeemerTagKind: {| /** */ -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 3, // 3 +declare export var MIRKind: {| + +ToOtherPot: 0, // 0 + +ToStakeCredentials: 1, // 1 |}; /** @@ -13664,19 +13664,19 @@ declare export class Voter { * @param {Credential} cred * @returns {Voter} */ - static new_constitutional_committee_hot_key(cred: Credential): Voter; + static new_constitutional_committee_hot_credential(cred: Credential): Voter; /** * @param {Credential} cred * @returns {Voter} */ - static new_drep(cred: Credential): Voter; + static new_drep_credential(cred: Credential): Voter; /** * @param {Ed25519KeyHash} key_hash * @returns {Voter} */ - static new_staking_pool(key_hash: Ed25519KeyHash): Voter; + static new_stake_pool_key_hash(key_hash: Ed25519KeyHash): Voter; /** * @returns {$Values< @@ -13688,17 +13688,17 @@ declare export class Voter { /** * @returns {Credential | void} */ - to_constitutional_committee_hot_key(): Credential | void; + to_constitutional_committee_hot_credential(): Credential | void; /** * @returns {Credential | void} */ - to_drep_cred(): Credential | void; + to_drep_credential(): Credential | void; /** * @returns {Ed25519KeyHash | void} */ - to_staking_pool_key_hash(): Ed25519KeyHash | void; + to_stake_pool_key_hash(): Ed25519KeyHash | void; /** * @returns {boolean} @@ -14557,7 +14557,7 @@ export type TransactionOutputsJSON = TransactionOutputJSON[]; export type CostModelJSON = string[]; export type VoterJSON = | { - ConstitutionalCommitteeHotKey: CredTypeJSON, + ConstitutionalCommitteeHotCred: CredTypeJSON, ... } | { @@ -15215,7 +15215,7 @@ export interface VersionedBlockJSON { export type VkeywitnessesJSON = VkeywitnessJSON[]; export type VoterEnumJSON = | { - ConstitutionalCommitteeHotKey: CredTypeJSON, + ConstitutionalCommitteeHotCred: CredTypeJSON, ... } | {