From bdf07d9cfb936cf20c4d78ac442863ccbf7aab8f Mon Sep 17 00:00:00 2001 From: lisicky Date: Tue, 5 Dec 2023 17:52:06 +0800 Subject: [PATCH] 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();