From e3d6eff237d83c2317077d6d9fdf7d3d515ecded Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 27 Dec 2024 01:38:09 +0400 Subject: [PATCH 1/4] follow tx tag state for new vkeys and boostrap witnesses --- rust/src/protocol_types/fixed_tx.rs | 93 +++++++++--- .../witnesses/fixed_tx_witnesses_set.rs | 25 +++- rust/src/serialization/fixed_tx.rs | 25 ++-- rust/src/tests/protocol_types/fixed_tx.rs | 52 +++++++ rust/src/utils.rs | 135 +++++++++++------- 5 files changed, 249 insertions(+), 81 deletions(-) diff --git a/rust/src/protocol_types/fixed_tx.rs b/rust/src/protocol_types/fixed_tx.rs index 79989a42..c9aafcec 100644 --- a/rust/src/protocol_types/fixed_tx.rs +++ b/rust/src/protocol_types/fixed_tx.rs @@ -4,16 +4,16 @@ use crate::*; #[wasm_bindgen] #[derive(Clone, Debug, Eq, PartialEq)] pub struct FixedTransaction { - pub(crate) body: TransactionBody, - pub(crate) body_bytes: Vec, - pub(crate) tx_hash: TransactionHash, + body: TransactionBody, + body_bytes: Vec, + tx_hash: TransactionHash, - pub(crate) witness_set: FixedTxWitnessesSet, + witness_set: FixedTxWitnessesSet, - pub(crate) is_valid: bool, + is_valid: bool, - pub(crate) auxiliary_data: Option, - pub(crate) auxiliary_bytes: Option>, + auxiliary_data: Option, + auxiliary_bytes: Option>, } to_from_bytes!(FixedTransaction); @@ -26,9 +26,17 @@ impl FixedTransaction { is_valid: bool, ) -> Result { let body = TransactionBody::from_bytes(raw_body.to_vec())?; - let witness_set = FixedTxWitnessesSet::from_bytes(raw_witness_set.to_vec())?; + let mut witness_set = FixedTxWitnessesSet::from_bytes(raw_witness_set.to_vec())?; let tx_hash = TransactionHash::from(blake2b256(raw_body)); + let tag_state = + has_transaction_set_tag_internal(&body, Some(witness_set.tx_witnesses_set_ref()))?; + let force_set_tag = match tag_state { + TransactionSetsState::AllSetsHaveNoTag => false, + _ => true, + }; + witness_set.force_set_tags_for_new_witnesses(force_set_tag); + Ok(FixedTransaction { body, body_bytes: raw_body.to_vec(), @@ -47,10 +55,18 @@ impl FixedTransaction { is_valid: bool, ) -> Result { let body = TransactionBody::from_bytes(raw_body.to_vec())?; - let witness_set = FixedTxWitnessesSet::from_bytes(raw_witness_set.to_vec())?; + let mut witness_set = FixedTxWitnessesSet::from_bytes(raw_witness_set.to_vec())?; let tx_hash = TransactionHash::from(blake2b256(raw_body)); let auxiliary_data = Some(AuxiliaryData::from_bytes(raw_auxiliary_data.to_vec())?); + let tag_state = + has_transaction_set_tag_internal(&body, Some(witness_set.tx_witnesses_set_ref()))?; + let force_set_tag = match tag_state { + TransactionSetsState::AllSetsHaveNoTag => false, + _ => true, + }; + witness_set.force_set_tags_for_new_witnesses(force_set_tag); + Ok(FixedTransaction { body, body_bytes: raw_body.to_vec(), @@ -66,11 +82,20 @@ impl FixedTransaction { let body = TransactionBody::from_bytes(raw_body.to_vec())?; let tx_hash = TransactionHash::from(blake2b256(raw_body)); + let tag_state = has_transaction_set_tag_internal(&body, None)?; + let force_set_tag = match tag_state { + TransactionSetsState::AllSetsHaveNoTag => false, + _ => true, + }; + + let mut witness_set = FixedTxWitnessesSet::new_empty(); + witness_set.force_set_tags_for_new_witnesses(force_set_tag); + Ok(FixedTransaction { body, body_bytes: raw_body.to_vec(), tx_hash, - witness_set: FixedTxWitnessesSet::new_empty(), + witness_set, is_valid: true, auxiliary_data: None, auxiliary_bytes: None, @@ -80,14 +105,25 @@ impl FixedTransaction { pub(crate) fn new_with_original_bytes( tx_body: TransactionBody, raw_body: Vec, - tx_witnesses_set: FixedTxWitnessesSet, + mut tx_witnesses_set: FixedTxWitnessesSet, is_valid: bool, auxiliary_data: Option, raw_auxiliary_data: Option>, - ) -> FixedTransaction { + ) -> Result { let tx_hash = TransactionHash::from(blake2b256(&raw_body)); - FixedTransaction { + let tag_state = has_transaction_set_tag_internal( + &tx_body, + Some(tx_witnesses_set.tx_witnesses_set_ref()), + )?; + let force_set_tag = match tag_state { + TransactionSetsState::AllSetsHaveNoTag => false, + _ => true, + }; + + tx_witnesses_set.force_set_tags_for_new_witnesses(force_set_tag); + + Ok(FixedTransaction { body: tx_body, body_bytes: raw_body, tx_hash, @@ -95,7 +131,7 @@ impl FixedTransaction { is_valid, auxiliary_data, auxiliary_bytes: raw_auxiliary_data, - } + }) } pub fn body(&self) -> TransactionBody { @@ -116,7 +152,10 @@ impl FixedTransaction { /// We do not recommend using this function, since it might lead to script integrity hash. /// The only purpose of this struct is to sign the transaction from third-party sources. /// Use `.sign_and_add_vkey_signature` or `.sign_and_add_icarus_bootstrap_signature` or `.sign_and_add_daedalus_bootstrap_signature` instead. - #[deprecated(since = "12.1.0", note = "Use `.sign_and_add_vkey_signature` or `.sign_and_add_icarus_bootstrap_signature` or `.sign_and_add_daedalus_bootstrap_signature` instead.")] + #[deprecated( + since = "12.1.0", + note = "Use `.sign_and_add_vkey_signature` or `.sign_and_add_icarus_bootstrap_signature` or `.sign_and_add_daedalus_bootstrap_signature` instead." + )] pub fn set_witness_set(&mut self, raw_witness_set: &[u8]) -> Result<(), JsError> { let witness_set = FixedTxWitnessesSet::from_bytes(raw_witness_set.to_vec())?; self.witness_set = witness_set; @@ -172,15 +211,35 @@ impl FixedTransaction { Ok(()) } - pub fn sign_and_add_icarus_bootstrap_signature(&mut self, addr: &ByronAddress, private_key: &Bip32PrivateKey) -> Result<(), JsError> { + pub fn sign_and_add_icarus_bootstrap_signature( + &mut self, + addr: &ByronAddress, + private_key: &Bip32PrivateKey, + ) -> Result<(), JsError> { let bootstrap_witness = make_icarus_bootstrap_witness(&self.tx_hash, addr, private_key); self.witness_set.add_bootstrap_witness(&bootstrap_witness); Ok(()) } - pub fn sign_and_add_daedalus_bootstrap_signature(&mut self, addr: &ByronAddress, private_key: &LegacyDaedalusPrivateKey) -> Result<(), JsError> { + pub fn sign_and_add_daedalus_bootstrap_signature( + &mut self, + addr: &ByronAddress, + private_key: &LegacyDaedalusPrivateKey, + ) -> Result<(), JsError> { let bootstrap_witness = make_daedalus_bootstrap_witness(&self.tx_hash, addr, private_key); self.witness_set.add_bootstrap_witness(&bootstrap_witness); Ok(()) } + + pub(crate) fn body_bytes_ref(&self) -> &Vec { + &self.body_bytes + } + + pub(crate) fn witnesses_set_ref(&self) -> &FixedTxWitnessesSet { + &self.witness_set + } + + pub(crate) fn auxiliary_bytes_ref(&self) -> Option<&Vec> { + self.auxiliary_bytes.as_ref() + } } diff --git a/rust/src/protocol_types/witnesses/fixed_tx_witnesses_set.rs b/rust/src/protocol_types/witnesses/fixed_tx_witnesses_set.rs index 1a3efce3..bfb2a568 100644 --- a/rust/src/protocol_types/witnesses/fixed_tx_witnesses_set.rs +++ b/rust/src/protocol_types/witnesses/fixed_tx_witnesses_set.rs @@ -12,6 +12,7 @@ use crate::*; pub struct FixedTxWitnessesSet { raw_parts: TransactionWitnessSetRaw, tx_witnesses_set: TransactionWitnessSet, + transaction_has_set_tags: bool, } #[wasm_bindgen] @@ -27,6 +28,7 @@ impl FixedTxWitnessesSet { Self { tx_witnesses_set: witnesses_set, raw_parts, + transaction_has_set_tags: true, } } @@ -34,6 +36,7 @@ impl FixedTxWitnessesSet { Self { tx_witnesses_set: TransactionWitnessSet::new(), raw_parts: TransactionWitnessSetRaw::new(), + transaction_has_set_tags: true } } @@ -43,7 +46,14 @@ impl FixedTxWitnessesSet { pub fn add_vkey_witness(&mut self, vkey_witness: &Vkeywitness) { if self.tx_witnesses_set.vkeys.is_none() { - self.tx_witnesses_set.vkeys = Some(Vkeywitnesses::new()); + let mut vkeys = Vkeywitnesses::new(); + vkeys.set_force_original_cbor_set_type(true); + if self.transaction_has_set_tags { + vkeys.set_set_type(CborSetType::Tagged) + } else { + vkeys.set_set_type(CborSetType::Untagged) + } + self.tx_witnesses_set.vkeys = Some(vkeys); } if let Some(vkeys) = &mut self.tx_witnesses_set.vkeys { vkeys.add(vkey_witness); @@ -53,7 +63,14 @@ impl FixedTxWitnessesSet { pub fn add_bootstrap_witness(&mut self, bootstrap_witness: &BootstrapWitness) { if self.tx_witnesses_set.bootstraps.is_none() { - self.tx_witnesses_set.bootstraps = Some(BootstrapWitnesses::new()); + let mut bootstraps = BootstrapWitnesses::new(); + bootstraps.set_force_original_cbor_set_type(true); + if self.transaction_has_set_tags { + bootstraps.set_set_type(CborSetType::Tagged) + } else { + bootstraps.set_set_type(CborSetType::Untagged) + } + self.tx_witnesses_set.bootstraps = Some(bootstraps); } if let Some(bootstraps) = &mut self.tx_witnesses_set.bootstraps { bootstraps.add(bootstrap_witness); @@ -86,4 +103,8 @@ impl FixedTxWitnessesSet { pub(crate) fn raw_parts_ref(&self) -> &TransactionWitnessSetRaw { &self.raw_parts } + + pub(crate) fn force_set_tags_for_new_witnesses(&mut self, set_tags: bool) { + self.transaction_has_set_tags = set_tags; + } } \ No newline at end of file diff --git a/rust/src/serialization/fixed_tx.rs b/rust/src/serialization/fixed_tx.rs index ca5153c0..5412b1ba 100644 --- a/rust/src/serialization/fixed_tx.rs +++ b/rust/src/serialization/fixed_tx.rs @@ -1,5 +1,5 @@ -use crate::*; use crate::serialization::utils::deserilized_with_orig_bytes; +use crate::*; impl cbor_event::se::Serialize for FixedTransaction { fn serialize<'se, W: Write>( @@ -7,10 +7,10 @@ impl cbor_event::se::Serialize for FixedTransaction { 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)?; - self.witness_set.serialize(serializer)?; - serializer.write_special(CBORSpecial::Bool(self.is_valid))?; - match &self.auxiliary_bytes { + serializer.write_raw_bytes(&self.body_bytes_ref())?; + self.witnesses_set_ref().serialize(serializer)?; + serializer.write_special(CBORSpecial::Bool(self.is_valid()))?; + match &self.auxiliary_bytes_ref() { Some(auxiliary_bytes) => serializer.write_raw_bytes(auxiliary_bytes)?, None => serializer.write_special(CBORSpecial::Null)?, }; @@ -52,8 +52,8 @@ impl DeserializeEmbeddedGroup for FixedTransaction { let (body, body_bytes) = deserilized_with_orig_bytes(raw, |raw| TransactionBody::deserialize(raw)) .map_err(|e| e.annotate("body"))?; - let witness_set = FixedTxWitnessesSet::deserialize(raw) - .map_err(|e| e.annotate("witness_set"))?; + let witness_set = + FixedTxWitnessesSet::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; @@ -105,13 +105,20 @@ impl DeserializeEmbeddedGroup for FixedTransaction { })() .map_err(|e| e.annotate("auxiliary_data"))?; } - Ok(FixedTransaction::new_with_original_bytes( + FixedTransaction::new_with_original_bytes( body, body_bytes, witness_set, is_valid, auxiliary_data, auxiliary_bytes, - )) + ) + .map_err(|_| { + DeserializeError::new( + "FixedTransaction", + DeserializeFailure::CustomError("Failed to create FixedTransaction. \ + Smth wrong with FixedTransaction::new_with_original_bytes()".to_string()), + ) + }) } } diff --git a/rust/src/tests/protocol_types/fixed_tx.rs b/rust/src/tests/protocol_types/fixed_tx.rs index 7cb14593..001466a1 100644 --- a/rust/src/tests/protocol_types/fixed_tx.rs +++ b/rust/src/tests/protocol_types/fixed_tx.rs @@ -1,5 +1,7 @@ use crate::*; use hex; +use crate::fakes::fake_bootstrap_witness; +use crate::tests::fakes::{fake_byron_address, fake_vkey_witness}; #[test] fn simple_round_trip() { @@ -170,4 +172,54 @@ fn fixed_transaction_with_plutus_witnesses() { assert!(fixed_tx_roundtrip.witness_set().vkeys().unwrap().contains(&vkey_witness_1)); assert_eq!(fixed_tx.transaction_hash(), fixed_tx_roundtrip.transaction_hash()); +} + +#[test] +fn add_witnesses_to_tagged_tx() { + let hex = "84a400d90102818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a00016f32030aa0f5f6"; + let vkey_witness = fake_vkey_witness(1); + let byron_address = ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") + .unwrap(); + let bootstrap_witness = fake_bootstrap_witness(1, &byron_address); + let mut fixed_tx = FixedTransaction::from_hex(hex).unwrap(); + fixed_tx.add_bootstrap_witness(&bootstrap_witness); + fixed_tx.add_vkey_witness(&vkey_witness); + + let new_bytes = fixed_tx.to_bytes(); + + let tx_sets = has_transaction_set_tag(hex::decode(hex).unwrap()).unwrap(); + assert_eq!(tx_sets, TransactionSetsState::AllSetsHaveTag); + + let new_tx_sets = has_transaction_set_tag(new_bytes.clone()).unwrap(); + assert_eq!(new_tx_sets, TransactionSetsState::AllSetsHaveTag); + + let new_tx = FixedTransaction::from_bytes(new_bytes).unwrap(); + + let wit_set_tag = has_transaction_witnesses_set_tag(&new_tx.witness_set()); + assert_eq!(wit_set_tag, Some(TransactionSetsState::AllSetsHaveTag)); +} + +#[test] +fn add_witnesses_to_untagged_tx() { + let hex = "84a400818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a00016f32030aa0f5f6"; + let vkey_witness = fake_vkey_witness(1); + let byron_address = ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3") + .unwrap(); + let bootstrap_witness = fake_bootstrap_witness(1, &byron_address); + let mut fixed_tx = FixedTransaction::from_hex(hex).unwrap(); + fixed_tx.add_bootstrap_witness(&bootstrap_witness); + fixed_tx.add_vkey_witness(&vkey_witness); + + let new_bytes = fixed_tx.to_bytes(); + + let tx_sets = has_transaction_set_tag(hex::decode(hex).unwrap()).unwrap(); + assert_eq!(tx_sets, TransactionSetsState::AllSetsHaveNoTag); + + let new_tx_sets = has_transaction_set_tag(new_bytes.clone()).unwrap(); + assert_eq!(new_tx_sets, TransactionSetsState::AllSetsHaveNoTag); + + let new_tx = FixedTransaction::from_bytes(new_bytes).unwrap(); + + let wit_set_tag = has_transaction_witnesses_set_tag(&new_tx.witness_set()); + assert_eq!(wit_set_tag, Some(TransactionSetsState::AllSetsHaveNoTag)); } \ No newline at end of file diff --git a/rust/src/utils.rs b/rust/src/utils.rs index 5c761ad2..786bf643 100644 --- a/rust/src/utils.rs +++ b/rust/src/utils.rs @@ -1101,90 +1101,63 @@ pub enum TransactionSetsState { /// WARNING this function will be deleted after all tags for set types will be mandatory. Approx after next hf #[wasm_bindgen] pub fn has_transaction_set_tag(tx_bytes: Vec) -> Result { + let tx = Transaction::from_bytes(tx_bytes)?; + has_transaction_set_tag_internal(&tx.body, Some(&tx.witness_set)) +} + +pub(crate) fn has_transaction_set_tag_internal(body: &TransactionBody, witnesses_set: Option<&TransactionWitnessSet>) -> Result { + let body_tag = has_transaction_body_set_tag(&body)?; + let witness_tag = witnesses_set.map(has_transaction_witnesses_set_tag).flatten(); + + match (body_tag, witness_tag) { + (TransactionSetsState::AllSetsHaveTag, Some(TransactionSetsState::AllSetsHaveTag)) => Ok(TransactionSetsState::AllSetsHaveTag), + (TransactionSetsState::AllSetsHaveNoTag, Some(TransactionSetsState::AllSetsHaveNoTag)) => Ok(TransactionSetsState::AllSetsHaveNoTag), + (TransactionSetsState::AllSetsHaveTag, None) => Ok(TransactionSetsState::AllSetsHaveTag), + (TransactionSetsState::AllSetsHaveNoTag, None) => Ok(TransactionSetsState::AllSetsHaveNoTag), + _ => Ok(TransactionSetsState::MixedSets), + } +} + +pub(crate) fn has_transaction_body_set_tag(body: &TransactionBody) -> Result { let mut has_tag = false; let mut has_no_tag = false; - let tx = Transaction::from_bytes(tx_bytes)?; - tx.witness_set.bootstraps.as_ref().map(|bs| { - match bs.get_set_type() { - CborSetType::Tagged => has_tag = true, - CborSetType::Untagged => has_no_tag = true, - } - }); - tx.witness_set.vkeys.as_ref().map(|vkeys| { - match vkeys.get_set_type() { - CborSetType::Tagged => has_tag = true, - CborSetType::Untagged => has_no_tag = true, - } - }); - tx.witness_set.plutus_data.as_ref().map(|plutus_data| { - match plutus_data.get_set_type() { - Some(CborSetType::Tagged) => has_tag = true, - Some(CborSetType::Untagged) => has_no_tag = true, - None => has_tag = true, - } - }); - tx.witness_set.native_scripts.as_ref().map(|native_scripts| { - match native_scripts.get_set_type() { - Some(CborSetType::Tagged) => has_tag = true, - Some(CborSetType::Untagged) => has_no_tag = true, - None => has_tag = true, - } - }); - tx.witness_set.plutus_scripts.as_ref().map(|plutus_scripts| { - match plutus_scripts.get_set_type(&Language::new_plutus_v1()) { - Some(CborSetType::Tagged) => has_tag = true, - Some(CborSetType::Untagged) => has_no_tag = true, - None => has_tag = true, - } - match plutus_scripts.get_set_type(&Language::new_plutus_v2()) { - Some(CborSetType::Tagged) => has_tag = true, - Some(CborSetType::Untagged) => has_no_tag = true, - None => has_tag = true, - } - match plutus_scripts.get_set_type(&Language::new_plutus_v3()) { - Some(CborSetType::Tagged) => has_tag = true, - Some(CborSetType::Untagged) => has_no_tag = true, - None => has_tag = true, - } - }); - - match tx.body.inputs.get_set_type() { + match body.inputs.get_set_type() { CborSetType::Tagged => has_tag = true, CborSetType::Untagged => has_no_tag = true, } - tx.body.reference_inputs.as_ref().map(|ref_inputs| { + body.reference_inputs.as_ref().map(|ref_inputs| { match ref_inputs.get_set_type() { CborSetType::Tagged => has_tag = true, CborSetType::Untagged => has_no_tag = true, } }); - tx.body.required_signers.as_ref().map(|required_signers| { + body.required_signers.as_ref().map(|required_signers| { match required_signers.get_set_type() { CborSetType::Tagged => has_tag = true, CborSetType::Untagged => has_no_tag = true, } }); - tx.body.voting_proposals.as_ref().map(|voting_proposals| { + body.voting_proposals.as_ref().map(|voting_proposals| { match voting_proposals.get_set_type() { CborSetType::Tagged => has_tag = true, CborSetType::Untagged => has_no_tag = true, } }); - tx.body.collateral.as_ref().map(|collateral_inputs| { + body.collateral.as_ref().map(|collateral_inputs| { match collateral_inputs.get_set_type() { CborSetType::Tagged => has_tag = true, CborSetType::Untagged => has_no_tag = true, } }); - tx.body.certs.as_ref().map(|certs| { + body.certs.as_ref().map(|certs| { match certs.get_set_type() { CborSetType::Tagged => has_tag = true, CborSetType::Untagged => has_no_tag = true, } }); - tx.body.certs.as_ref().map(|certs| { + body.certs.as_ref().map(|certs| { for cert in certs { match &cert.0 { CertificateEnum::PoolRegistration(pool_reg) => { @@ -1198,7 +1171,7 @@ pub fn has_transaction_set_tag(tx_bytes: Vec) -> Result { @@ -1218,4 +1191,60 @@ pub fn has_transaction_set_tag(tx_bytes: Vec) -> Result Ok(TransactionSetsState::AllSetsHaveNoTag), (false, false) => Err(JsError::from_str("Transaction has invalid state")), } +} + +pub(crate) fn has_transaction_witnesses_set_tag(witness_set: &TransactionWitnessSet) -> Option { + let mut has_tag = false; + let mut has_no_tag = false; + + witness_set.bootstraps.as_ref().map(|bs| { + match bs.get_set_type() { + CborSetType::Tagged => has_tag = true, + CborSetType::Untagged => has_no_tag = true, + } + }); + witness_set.vkeys.as_ref().map(|vkeys| { + match vkeys.get_set_type() { + CborSetType::Tagged => has_tag = true, + CborSetType::Untagged => has_no_tag = true, + } + }); + witness_set.plutus_data.as_ref().map(|plutus_data| { + match plutus_data.get_set_type() { + Some(CborSetType::Tagged) => has_tag = true, + Some(CborSetType::Untagged) => has_no_tag = true, + None => has_tag = true, + } + }); + witness_set.native_scripts.as_ref().map(|native_scripts| { + match native_scripts.get_set_type() { + Some(CborSetType::Tagged) => has_tag = true, + Some(CborSetType::Untagged) => has_no_tag = true, + None => has_tag = true, + } + }); + witness_set.plutus_scripts.as_ref().map(|plutus_scripts| { + match plutus_scripts.get_set_type(&Language::new_plutus_v1()) { + Some(CborSetType::Tagged) => has_tag = true, + Some(CborSetType::Untagged) => has_no_tag = true, + None => has_tag = true, + } + match plutus_scripts.get_set_type(&Language::new_plutus_v2()) { + Some(CborSetType::Tagged) => has_tag = true, + Some(CborSetType::Untagged) => has_no_tag = true, + None => has_tag = true, + } + match plutus_scripts.get_set_type(&Language::new_plutus_v3()) { + Some(CborSetType::Tagged) => has_tag = true, + Some(CborSetType::Untagged) => has_no_tag = true, + None => has_tag = true, + } + }); + + match (has_tag, has_no_tag) { + (true, true) => Some(TransactionSetsState::MixedSets), + (true, false) => Some(TransactionSetsState::AllSetsHaveTag), + (false, true) => Some(TransactionSetsState::AllSetsHaveNoTag), + (false, false) => None, + } } \ No newline at end of file From 91a4b5aa758abf5b4f4cd9c9e82589ba739671ad Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 9 Jan 2025 11:32:13 +0400 Subject: [PATCH 2/4] fix warnings --- rust/src/legacy_address/crc32.rs | 2 +- rust/src/tests/protocol_types/fixed_tx.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/src/legacy_address/crc32.rs b/rust/src/legacy_address/crc32.rs index bce1e914..1fbc78d3 100644 --- a/rust/src/legacy_address/crc32.rs +++ b/rust/src/legacy_address/crc32.rs @@ -275,7 +275,7 @@ impl Crc32 { /// beware that the order in which you update the Crc32 /// matter. #[inline] - pub fn update<'a, I>(&'a mut self, bytes: I) -> &mut Self + pub fn update<'a, I>(&'a mut self, bytes: I) -> &'a mut Self where I: IntoIterator, { diff --git a/rust/src/tests/protocol_types/fixed_tx.rs b/rust/src/tests/protocol_types/fixed_tx.rs index 001466a1..84018641 100644 --- a/rust/src/tests/protocol_types/fixed_tx.rs +++ b/rust/src/tests/protocol_types/fixed_tx.rs @@ -1,7 +1,7 @@ use crate::*; use hex; use crate::fakes::fake_bootstrap_witness; -use crate::tests::fakes::{fake_byron_address, fake_vkey_witness}; +use crate::tests::fakes::fake_vkey_witness; #[test] fn simple_round_trip() { From b533b00c5f878f3d79917e65844f6b5e27d0ecbc Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 9 Jan 2025 11:40:29 +0400 Subject: [PATCH 3/4] flow file update --- rust/pkg/cardano_serialization_lib.js.flow | 456 +++++++++++---------- 1 file changed, 229 insertions(+), 227 deletions(-) diff --git a/rust/pkg/cardano_serialization_lib.js.flow b/rust/pkg/cardano_serialization_lib.js.flow index 8ddd03b0..2cf783df 100644 --- a/rust/pkg/cardano_serialization_lib.js.flow +++ b/rust/pkg/cardano_serialization_lib.js.flow @@ -5,82 +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 {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 - * @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 @@ -118,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 {TransactionHash} tx_body_hash * @param {ByronAddress} addr @@ -277,86 +177,119 @@ declare export function has_transaction_set_tag( ): $Values; /** + * @param {Address} address + * @param {TransactionUnspentOutputs} utxos + * @param {TransactionBuilderConfig} config + * @returns {TransactionBatchList} */ - -declare export var MIRKind: {| - +ToOtherPot: 0, // 0 - +ToStakeCredentials: 1, // 1 -|}; +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; -declare export var MetadataJsonSchema: {| - +NoConversions: 0, // 0 - +BasicConversions: 1, // 1 - +DetailedSchema: 2, // 2 -|}; +/** + * @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; -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 -|}; +/** + * @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; -declare export var NativeScriptKind: {| - +ScriptPubkey: 0, // 0 - +ScriptAll: 1, // 1 - +ScriptAny: 2, // 2 - +ScriptNOfK: 3, // 3 - +TimelockStart: 4, // 4 - +TimelockExpiry: 5, // 5 -|}; +/** + * @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 LanguageKind: {| - +PlutusV1: 0, // 0 - +PlutusV2: 1, // 1 - +PlutusV3: 2, // 2 -|}; +/** + * @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 CborSetType: {| - +Tagged: 0, // 0 - +Untagged: 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 +declare export var CredKind: {| + +Key: 0, // 0 + +Script: 1, // 1 |}; /** @@ -372,6 +305,33 @@ 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 DRepKind: {| + +KeyHash: 0, // 0 + +ScriptHash: 1, // 1 + +AlwaysAbstain: 2, // 2 + +AlwaysNoConfidence: 3, // 3 +|}; + /** */ @@ -383,21 +343,23 @@ declare export var CborContainerType: {| /** */ -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 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 |}; /** @@ -409,6 +371,25 @@ declare export var RelayKind: {| +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 NetworkIdKind: {| + +Testnet: 0, // 0 + +Mainnet: 1, // 1 +|}; + /** * Used to choosed the schema for a script JSON string */ @@ -421,53 +402,82 @@ declare export var ScriptSchema: {| /** */ -declare export var VoterKind: {| - +ConstitutionalCommitteeHotKeyHash: 0, // 0 - +ConstitutionalCommitteeHotScriptHash: 1, // 1 - +DRepKeyHash: 2, // 2 - +DRepScriptHash: 3, // 3 - +StakingPoolKeyHash: 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 |}; /** */ -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 |}; /** */ -declare export var CredKind: {| - +Key: 0, // 0 - +Script: 1, // 1 +declare export var CborSetType: {| + +Tagged: 0, // 0 + +Untagged: 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 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 VoteKind: {| + +No: 0, // 0 + +Yes: 1, // 1 + +Abstain: 2, // 2 +|}; + +/** + */ + +declare export var TransactionSetsState: {| + +AllSetsHaveTag: 0, // 0 + +AllSetsHaveNoTag: 1, // 1 + +MixedSets: 2, // 2 +|}; + +/** + */ + +declare export var PlutusDataKind: {| + +ConstrPlutusData: 0, // 0 + +Map: 1, // 1 + +List: 2, // 2 + +Integer: 3, // 3 + +Bytes: 4, // 4 |}; /** @@ -484,42 +494,27 @@ declare export var ScriptHashNamespace: {| +PlutusScriptV3: 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 TransactionSetsState: {| - +AllSetsHaveTag: 0, // 0 - +AllSetsHaveNoTag: 1, // 1 - +MixedSets: 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 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 |}; /** @@ -533,19 +528,24 @@ declare export var MIRPot: {| /** */ -declare export var CoinSelectionStrategyCIP2: {| - +LargestFirst: 0, // 0 - +RandomImprove: 1, // 1 - +LargestFirstMultiAsset: 2, // 2 - +RandomImproveMultiAsset: 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 NetworkIdKind: {| - +Testnet: 0, // 0 - +Mainnet: 1, // 1 +declare export var LanguageKind: {| + +PlutusV1: 0, // 0 + +PlutusV2: 1, // 1 + +PlutusV3: 2, // 2 |}; /** @@ -11203,11 +11203,13 @@ declare export class TransactionBuilder { fee_for_output(output: TransactionOutput): BigNum; /** + * Set exact fee for the transaction. If the real fee will be bigger then the set value, the transaction will not be created on .build_tx() * @param {BigNum} fee */ set_fee(fee: BigNum): void; /** + * Set minimal fee for the transaction. If the real fee will be bigger then the set value, the transaction will be created with the real fee. * @param {BigNum} fee */ set_min_fee(fee: BigNum): void; From 846d0f274a436403659fa7b197a09c029d7f2126 Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 9 Jan 2025 11:47:35 +0400 Subject: [PATCH 4/4] 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 a294fb26..d6c12dfd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "13.2.0", + "version": "13.2.1", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/package.json b/package.json index 807fcca4..534ea0b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "13.2.0", + "version": "13.2.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 d6b5c7df..1edbafd5 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "13.2.0" +version = "13.2.1" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index 2d536e24..fa7fd79f 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 = "13.2.0" +version = "13.2.1" dependencies = [ "bech32", "cbor_event",