diff --git a/packages/rs-dpp/src/state_transition/state_transitions/shielded/identity_create_from_shielded_pool_transition/accessors/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/shielded/identity_create_from_shielded_pool_transition/accessors/mod.rs index 68715016c64..c6a05f5c962 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/shielded/identity_create_from_shielded_pool_transition/accessors/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/shielded/identity_create_from_shielded_pool_transition/accessors/mod.rs @@ -17,18 +17,74 @@ impl IdentityCreateFromShieldedPoolTransitionAccessorsV0 } } + fn set_actions(&mut self, actions: Vec) { + match self { + IdentityCreateFromShieldedPoolTransition::V0(v0) => v0.actions = actions, + } + } + fn public_keys(&self) -> &[IdentityPublicKeyInCreation] { match self { IdentityCreateFromShieldedPoolTransition::V0(v0) => &v0.public_keys, } } + fn set_public_keys(&mut self, public_keys: Vec) { + match self { + IdentityCreateFromShieldedPoolTransition::V0(v0) => v0.public_keys = public_keys, + } + } + fn denomination(&self) -> u64 { match self { IdentityCreateFromShieldedPoolTransition::V0(v0) => v0.denomination, } } + fn set_denomination(&mut self, denomination: u64) { + match self { + IdentityCreateFromShieldedPoolTransition::V0(v0) => v0.denomination = denomination, + } + } + + fn anchor(&self) -> [u8; 32] { + match self { + IdentityCreateFromShieldedPoolTransition::V0(v0) => v0.anchor, + } + } + + fn set_anchor(&mut self, anchor: [u8; 32]) { + match self { + IdentityCreateFromShieldedPoolTransition::V0(v0) => v0.anchor = anchor, + } + } + + fn proof(&self) -> &[u8] { + match self { + IdentityCreateFromShieldedPoolTransition::V0(v0) => &v0.proof, + } + } + + fn set_proof(&mut self, proof: Vec) { + match self { + IdentityCreateFromShieldedPoolTransition::V0(v0) => v0.proof = proof, + } + } + + fn binding_signature(&self) -> [u8; 64] { + match self { + IdentityCreateFromShieldedPoolTransition::V0(v0) => v0.binding_signature, + } + } + + fn set_binding_signature(&mut self, binding_signature: [u8; 64]) { + match self { + IdentityCreateFromShieldedPoolTransition::V0(v0) => { + v0.binding_signature = binding_signature + } + } + } + fn send_to_address_on_creation_failure(&self) -> &PlatformAddress { match self { IdentityCreateFromShieldedPoolTransition::V0(v0) => { @@ -37,9 +93,117 @@ impl IdentityCreateFromShieldedPoolTransitionAccessorsV0 } } + fn set_send_to_address_on_creation_failure( + &mut self, + send_to_address_on_creation_failure: PlatformAddress, + ) { + match self { + IdentityCreateFromShieldedPoolTransition::V0(v0) => { + v0.send_to_address_on_creation_failure = send_to_address_on_creation_failure + } + } + } + fn identity_id(&self) -> Identifier { match self { IdentityCreateFromShieldedPoolTransition::V0(v0) => v0.identity_id, } } + + fn set_identity_id(&mut self, identity_id: Identifier) { + match self { + IdentityCreateFromShieldedPoolTransition::V0(v0) => v0.identity_id = identity_id, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::identity::{KeyType, Purpose, SecurityLevel}; + use crate::state_transition::identity_create_from_shielded_pool_transition::v0::IdentityCreateFromShieldedPoolTransitionV0; + use crate::state_transition::public_key_in_creation::v0::IdentityPublicKeyInCreationV0; + use platform_value::BinaryData; + + fn mk_action(nullifier_byte: u8) -> SerializedAction { + SerializedAction { + nullifier: [nullifier_byte; 32], + rk: [2u8; 32], + cmx: [3u8; 32], + encrypted_note: vec![4u8; 216], + cv_net: [5u8; 32], + spend_auth_sig: [6u8; 64], + } + } + + fn mk_key(id: u32, data_byte: u8) -> IdentityPublicKeyInCreation { + IdentityPublicKeyInCreation::V0(IdentityPublicKeyInCreationV0 { + id, + key_type: KeyType::ECDSA_SECP256K1, + purpose: Purpose::AUTHENTICATION, + security_level: SecurityLevel::MASTER, + contract_bounds: None, + read_only: false, + data: BinaryData::new(vec![data_byte; 33]), + signature: BinaryData::new(vec![]), + }) + } + + fn make_transition() -> IdentityCreateFromShieldedPoolTransition { + IdentityCreateFromShieldedPoolTransitionV0 { + public_keys: vec![mk_key(0, 0xAA)], + denomination: 10_000_000_000, + actions: vec![mk_action(0x11)], + anchor: [7u8; 32], + proof: vec![8u8; 10], + binding_signature: [9u8; 64], + send_to_address_on_creation_failure: PlatformAddress::P2pkh([0u8; 20]), + identity_id: Identifier::new([1u8; 32]), + } + .into() + } + + #[test] + fn test_getters_and_setters() { + let mut t = make_transition(); + + assert_eq!(t.actions(), &[mk_action(0x11)]); + assert_eq!(t.public_keys(), &[mk_key(0, 0xAA)]); + assert_eq!(t.denomination(), 10_000_000_000); + assert_eq!(t.anchor(), [7u8; 32]); + assert_eq!(t.proof(), &[8u8; 10]); + assert_eq!(t.binding_signature(), [9u8; 64]); + assert_eq!( + t.send_to_address_on_creation_failure(), + &PlatformAddress::P2pkh([0u8; 20]) + ); + assert_eq!(t.identity_id(), Identifier::new([1u8; 32])); + + t.set_actions(vec![mk_action(0x22)]); + assert_eq!(t.actions(), &[mk_action(0x22)]); + + t.set_public_keys(vec![mk_key(1, 0xBB)]); + assert_eq!(t.public_keys(), &[mk_key(1, 0xBB)]); + + t.set_denomination(20_000_000_000); + assert_eq!(t.denomination(), 20_000_000_000); + + t.set_anchor([1u8; 32]); + assert_eq!(t.anchor(), [1u8; 32]); + + t.set_proof(vec![0xAu8; 5]); + assert_eq!(t.proof(), &[0xAu8; 5]); + + t.set_binding_signature([0xBu8; 64]); + assert_eq!(t.binding_signature(), [0xBu8; 64]); + + t.set_send_to_address_on_creation_failure(PlatformAddress::P2pkh([2u8; 20])); + assert_eq!( + t.send_to_address_on_creation_failure(), + &PlatformAddress::P2pkh([2u8; 20]) + ); + + t.set_identity_id(Identifier::new([3u8; 32])); + assert_eq!(t.identity_id(), Identifier::new([3u8; 32])); + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/shielded/identity_create_from_shielded_pool_transition/accessors/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/shielded/identity_create_from_shielded_pool_transition/accessors/v0/mod.rs index bf0c2c0b62f..a7ada8efe3c 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/shielded/identity_create_from_shielded_pool_transition/accessors/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/shielded/identity_create_from_shielded_pool_transition/accessors/v0/mod.rs @@ -6,18 +6,46 @@ use platform_value::Identifier; pub trait IdentityCreateFromShieldedPoolTransitionAccessorsV0 { /// Get the serialized Orchard actions (spend/output pairs). fn actions(&self) -> &[SerializedAction]; + /// Replace the serialized Orchard actions. + fn set_actions(&mut self, actions: Vec); /// Get the public keys of the new identity. fn public_keys(&self) -> &[IdentityPublicKeyInCreation]; + /// Replace the public keys of the new identity. + fn set_public_keys(&mut self, public_keys: Vec); /// Get the fixed exit denomination (in credits). fn denomination(&self) -> u64; + /// Set the fixed exit denomination (in credits). + fn set_denomination(&mut self, denomination: u64); + + /// Get the Orchard anchor (Sinsemilla root of the note commitment tree). + fn anchor(&self) -> [u8; 32]; + /// Set the Orchard anchor. + fn set_anchor(&mut self, anchor: [u8; 32]); + + /// Get the Halo2 proof bytes. + fn proof(&self) -> &[u8]; + /// Set the Halo2 proof bytes. + fn set_proof(&mut self, proof: Vec); + + /// Get the RedPallas binding signature. + fn binding_signature(&self) -> [u8; 64]; + /// Set the RedPallas binding signature. + fn set_binding_signature(&mut self, binding_signature: [u8; 64]); /// Get the fallback address credited (minus penalty) if identity creation fails a stateful check. fn send_to_address_on_creation_failure(&self) -> &PlatformAddress; + /// Set the fallback address credited (minus penalty) if identity creation fails a stateful check. + fn set_send_to_address_on_creation_failure( + &mut self, + send_to_address_on_creation_failure: PlatformAddress, + ); /// Get the id of the new identity (derived from the spend nullifiers). fn identity_id(&self) -> Identifier; + /// Set the id of the new identity. + fn set_identity_id(&mut self, identity_id: Identifier); /// Extract nullifier bytes from each action. /// Generic over the element type: use `Vec` or `[u8; 32]` as needed. diff --git a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/accessors/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/accessors/mod.rs new file mode 100644 index 00000000000..d6fee584ad1 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/accessors/mod.rs @@ -0,0 +1,150 @@ +mod v0; + +pub use v0::*; + +use crate::address_funds::PlatformAddress; +use crate::shielded::SerializedAction; +use crate::state_transition::shield_from_asset_lock_transition::ShieldFromAssetLockTransition; + +impl ShieldFromAssetLockTransitionAccessorsV0 for ShieldFromAssetLockTransition { + fn actions(&self) -> &[SerializedAction] { + match self { + ShieldFromAssetLockTransition::V0(v0) => &v0.actions, + } + } + + fn set_actions(&mut self, actions: Vec) { + match self { + ShieldFromAssetLockTransition::V0(v0) => v0.actions = actions, + } + } + + fn value_balance(&self) -> u64 { + match self { + ShieldFromAssetLockTransition::V0(v0) => v0.value_balance, + } + } + + fn set_value_balance(&mut self, value_balance: u64) { + match self { + ShieldFromAssetLockTransition::V0(v0) => v0.value_balance = value_balance, + } + } + + fn anchor(&self) -> [u8; 32] { + match self { + ShieldFromAssetLockTransition::V0(v0) => v0.anchor, + } + } + + fn set_anchor(&mut self, anchor: [u8; 32]) { + match self { + ShieldFromAssetLockTransition::V0(v0) => v0.anchor = anchor, + } + } + + fn proof(&self) -> &[u8] { + match self { + ShieldFromAssetLockTransition::V0(v0) => &v0.proof, + } + } + + fn set_proof(&mut self, proof: Vec) { + match self { + ShieldFromAssetLockTransition::V0(v0) => v0.proof = proof, + } + } + + fn binding_signature(&self) -> [u8; 64] { + match self { + ShieldFromAssetLockTransition::V0(v0) => v0.binding_signature, + } + } + + fn set_binding_signature(&mut self, binding_signature: [u8; 64]) { + match self { + ShieldFromAssetLockTransition::V0(v0) => v0.binding_signature = binding_signature, + } + } + + fn surplus_output(&self) -> Option<&PlatformAddress> { + match self { + ShieldFromAssetLockTransition::V0(v0) => v0.surplus_output.as_ref(), + } + } + + fn set_surplus_output(&mut self, surplus_output: Option) { + match self { + ShieldFromAssetLockTransition::V0(v0) => v0.surplus_output = surplus_output, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::identity::state_transition::asset_lock_proof::chain::ChainAssetLockProof; + use crate::identity::state_transition::asset_lock_proof::AssetLockProof; + use crate::state_transition::shield_from_asset_lock_transition::v0::ShieldFromAssetLockTransitionV0; + use dashcore::OutPoint; + use platform_value::BinaryData; + + fn mk_action(nullifier_byte: u8) -> SerializedAction { + SerializedAction { + nullifier: [nullifier_byte; 32], + rk: [2u8; 32], + cmx: [3u8; 32], + encrypted_note: vec![4u8; 216], + cv_net: [5u8; 32], + spend_auth_sig: [6u8; 64], + } + } + + fn make_transition() -> ShieldFromAssetLockTransition { + ShieldFromAssetLockTransitionV0 { + asset_lock_proof: AssetLockProof::Chain(ChainAssetLockProof { + core_chain_locked_height: 100, + out_point: OutPoint::from([11u8; 36]), + }), + actions: vec![mk_action(0x11)], + value_balance: 1_000, + anchor: [7u8; 32], + proof: vec![8u8; 10], + binding_signature: [9u8; 64], + surplus_output: None, + signature: BinaryData::new(vec![10u8; 65]), + } + .into() + } + + #[test] + fn test_getters_and_setters() { + let mut t = make_transition(); + + assert_eq!(t.actions(), &[mk_action(0x11)]); + assert_eq!(t.value_balance(), 1_000); + assert_eq!(t.anchor(), [7u8; 32]); + assert_eq!(t.proof(), &[8u8; 10]); + assert_eq!(t.binding_signature(), [9u8; 64]); + assert_eq!(t.surplus_output(), None); + + t.set_actions(vec![mk_action(0x22)]); + assert_eq!(t.actions(), &[mk_action(0x22)]); + + t.set_value_balance(42); + assert_eq!(t.value_balance(), 42); + + t.set_anchor([1u8; 32]); + assert_eq!(t.anchor(), [1u8; 32]); + + t.set_proof(vec![0xAu8; 5]); + assert_eq!(t.proof(), &[0xAu8; 5]); + + t.set_binding_signature([0xBu8; 64]); + assert_eq!(t.binding_signature(), [0xBu8; 64]); + + let surplus = PlatformAddress::P2pkh([3u8; 20]); + t.set_surplus_output(Some(surplus)); + assert_eq!(t.surplus_output(), Some(&surplus)); + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/accessors/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/accessors/v0/mod.rs new file mode 100644 index 00000000000..51531e87033 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/accessors/v0/mod.rs @@ -0,0 +1,50 @@ +use crate::address_funds::PlatformAddress; +use crate::shielded::SerializedAction; + +/// Accessors for the fields of a `ShieldFromAssetLockTransition`. +/// +/// `asset_lock_proof` is exposed through +/// [`AssetLockProved`](crate::identity::state_transition::AssetLockProved) and the ECDSA +/// `signature` through +/// [`StateTransitionSingleSigned`](crate::state_transition::StateTransitionSingleSigned), so they +/// are intentionally not duplicated here. +pub trait ShieldFromAssetLockTransitionAccessorsV0 { + /// Get the serialized Orchard actions (spend/output pairs). + fn actions(&self) -> &[SerializedAction]; + /// Replace the serialized Orchard actions. + fn set_actions(&mut self, actions: Vec); + + /// Get the amount of credits flowing into the shielded pool from the asset lock. + fn value_balance(&self) -> u64; + /// Set the amount of credits flowing into the shielded pool from the asset lock. + fn set_value_balance(&mut self, value_balance: u64); + + /// Get the Orchard anchor (Sinsemilla root of the note commitment tree). + fn anchor(&self) -> [u8; 32]; + /// Set the Orchard anchor. + fn set_anchor(&mut self, anchor: [u8; 32]); + + /// Get the Halo2 proof bytes. + fn proof(&self) -> &[u8]; + /// Set the Halo2 proof bytes. + fn set_proof(&mut self, proof: Vec); + + /// Get the RedPallas binding signature. + fn binding_signature(&self) -> [u8; 64]; + /// Set the RedPallas binding signature. + fn set_binding_signature(&mut self, binding_signature: [u8; 64]); + + /// Get the optional platform-address output that receives the asset-lock surplus. + fn surplus_output(&self) -> Option<&PlatformAddress>; + /// Set the optional platform-address output that receives the asset-lock surplus. + fn set_surplus_output(&mut self, surplus_output: Option); + + /// Extract nullifier bytes from each action. + /// Generic over the element type: use `Vec` or `[u8; 32]` as needed. + fn nullifiers>(&self) -> Vec { + self.actions() + .iter() + .map(|a| T::from(a.nullifier)) + .collect() + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/mod.rs index 1d6476dd336..f8ab580d66d 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/mod.rs @@ -1,3 +1,4 @@ +pub mod accessors; pub mod fields; pub mod methods; mod proved; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/accessors/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/accessors/mod.rs new file mode 100644 index 00000000000..6cb10c58038 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/accessors/mod.rs @@ -0,0 +1,148 @@ +mod v0; + +pub use v0::*; + +use crate::address_funds::AddressFundsFeeStrategy; +use crate::shielded::SerializedAction; +use crate::state_transition::shield_transition::ShieldTransition; + +impl ShieldTransitionAccessorsV0 for ShieldTransition { + fn actions(&self) -> &[SerializedAction] { + match self { + ShieldTransition::V0(v0) => &v0.actions, + } + } + + fn set_actions(&mut self, actions: Vec) { + match self { + ShieldTransition::V0(v0) => v0.actions = actions, + } + } + + fn amount(&self) -> u64 { + match self { + ShieldTransition::V0(v0) => v0.amount, + } + } + + fn set_amount(&mut self, amount: u64) { + match self { + ShieldTransition::V0(v0) => v0.amount = amount, + } + } + + fn anchor(&self) -> [u8; 32] { + match self { + ShieldTransition::V0(v0) => v0.anchor, + } + } + + fn set_anchor(&mut self, anchor: [u8; 32]) { + match self { + ShieldTransition::V0(v0) => v0.anchor = anchor, + } + } + + fn proof(&self) -> &[u8] { + match self { + ShieldTransition::V0(v0) => &v0.proof, + } + } + + fn set_proof(&mut self, proof: Vec) { + match self { + ShieldTransition::V0(v0) => v0.proof = proof, + } + } + + fn binding_signature(&self) -> [u8; 64] { + match self { + ShieldTransition::V0(v0) => v0.binding_signature, + } + } + + fn set_binding_signature(&mut self, binding_signature: [u8; 64]) { + match self { + ShieldTransition::V0(v0) => v0.binding_signature = binding_signature, + } + } + + fn fee_strategy(&self) -> &AddressFundsFeeStrategy { + match self { + ShieldTransition::V0(v0) => &v0.fee_strategy, + } + } + + fn set_fee_strategy(&mut self, fee_strategy: AddressFundsFeeStrategy) { + match self { + ShieldTransition::V0(v0) => v0.fee_strategy = fee_strategy, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::address_funds::AddressFundsFeeStrategyStep; + use crate::state_transition::shield_transition::v0::ShieldTransitionV0; + use std::collections::BTreeMap; + + fn mk_action(nullifier_byte: u8) -> SerializedAction { + SerializedAction { + nullifier: [nullifier_byte; 32], + rk: [2u8; 32], + cmx: [3u8; 32], + encrypted_note: vec![4u8; 216], + cv_net: [5u8; 32], + spend_auth_sig: [6u8; 64], + } + } + + fn make_transition() -> ShieldTransition { + ShieldTransitionV0 { + inputs: BTreeMap::new(), + actions: vec![mk_action(0x11)], + amount: 1_000, + anchor: [7u8; 32], + proof: vec![8u8; 10], + binding_signature: [9u8; 64], + fee_strategy: vec![], + user_fee_increase: 0, + input_witnesses: vec![], + } + .into() + } + + #[test] + fn test_getters_and_setters() { + let mut t = make_transition(); + + assert_eq!(t.actions(), &[mk_action(0x11)]); + assert_eq!(t.amount(), 1_000); + assert_eq!(t.anchor(), [7u8; 32]); + assert_eq!(t.proof(), &[8u8; 10]); + assert_eq!(t.binding_signature(), [9u8; 64]); + assert!(t.fee_strategy().is_empty()); + + t.set_actions(vec![mk_action(0x22), mk_action(0x33)]); + assert_eq!(t.actions(), &[mk_action(0x22), mk_action(0x33)]); + + t.set_amount(42); + assert_eq!(t.amount(), 42); + + t.set_anchor([1u8; 32]); + assert_eq!(t.anchor(), [1u8; 32]); + + t.set_proof(vec![0xAu8; 5]); + assert_eq!(t.proof(), &[0xAu8; 5]); + + t.set_binding_signature([0xBu8; 64]); + assert_eq!(t.binding_signature(), [0xBu8; 64]); + + t.set_fee_strategy(vec![AddressFundsFeeStrategyStep::DeductFromInput(1)]); + assert_eq!( + t.fee_strategy(), + &[AddressFundsFeeStrategyStep::DeductFromInput(1)] + ); + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/accessors/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/accessors/v0/mod.rs new file mode 100644 index 00000000000..df6cba35ed1 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/accessors/v0/mod.rs @@ -0,0 +1,50 @@ +use crate::address_funds::AddressFundsFeeStrategy; +use crate::shielded::SerializedAction; + +/// Accessors for the fields of a `ShieldTransition`. +/// +/// `inputs` / `input_witnesses` are exposed through +/// [`StateTransitionWitnessSigned`](crate::state_transition::StateTransitionWitnessSigned) and +/// `user_fee_increase` through +/// [`StateTransitionHasUserFeeIncrease`](crate::state_transition::StateTransitionHasUserFeeIncrease), +/// so they are intentionally not duplicated here. +pub trait ShieldTransitionAccessorsV0 { + /// Get the serialized Orchard actions (spend/output pairs). + fn actions(&self) -> &[SerializedAction]; + /// Replace the serialized Orchard actions. + fn set_actions(&mut self, actions: Vec); + + /// Get the amount of credits being shielded (entering the shielded pool). + fn amount(&self) -> u64; + /// Set the amount of credits being shielded. + fn set_amount(&mut self, amount: u64); + + /// Get the Orchard anchor (Sinsemilla root of the note commitment tree). + fn anchor(&self) -> [u8; 32]; + /// Set the Orchard anchor. + fn set_anchor(&mut self, anchor: [u8; 32]); + + /// Get the Halo2 proof bytes. + fn proof(&self) -> &[u8]; + /// Set the Halo2 proof bytes. + fn set_proof(&mut self, proof: Vec); + + /// Get the RedPallas binding signature. + fn binding_signature(&self) -> [u8; 64]; + /// Set the RedPallas binding signature. + fn set_binding_signature(&mut self, binding_signature: [u8; 64]); + + /// Get the fee payment strategy. + fn fee_strategy(&self) -> &AddressFundsFeeStrategy; + /// Set the fee payment strategy. + fn set_fee_strategy(&mut self, fee_strategy: AddressFundsFeeStrategy); + + /// Extract nullifier bytes from each action. + /// Generic over the element type: use `Vec` or `[u8; 32]` as needed. + fn nullifiers>(&self) -> Vec { + self.actions() + .iter() + .map(|a| T::from(a.nullifier)) + .collect() + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/mod.rs index d04d041261c..5107a765363 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/mod.rs @@ -1,3 +1,4 @@ +pub mod accessors; pub mod methods; mod state_transition_estimated_fee_validation; mod state_transition_like; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_transfer_transition/accessors/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_transfer_transition/accessors/mod.rs index e12d9f4e66f..c971c6d7aa5 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_transfer_transition/accessors/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_transfer_transition/accessors/mod.rs @@ -11,4 +11,112 @@ impl ShieldedTransferTransitionAccessorsV0 for ShieldedTransferTransition { ShieldedTransferTransition::V0(v0) => &v0.actions, } } + + fn set_actions(&mut self, actions: Vec) { + match self { + ShieldedTransferTransition::V0(v0) => v0.actions = actions, + } + } + + fn value_balance(&self) -> u64 { + match self { + ShieldedTransferTransition::V0(v0) => v0.value_balance, + } + } + + fn set_value_balance(&mut self, value_balance: u64) { + match self { + ShieldedTransferTransition::V0(v0) => v0.value_balance = value_balance, + } + } + + fn anchor(&self) -> [u8; 32] { + match self { + ShieldedTransferTransition::V0(v0) => v0.anchor, + } + } + + fn set_anchor(&mut self, anchor: [u8; 32]) { + match self { + ShieldedTransferTransition::V0(v0) => v0.anchor = anchor, + } + } + + fn proof(&self) -> &[u8] { + match self { + ShieldedTransferTransition::V0(v0) => &v0.proof, + } + } + + fn set_proof(&mut self, proof: Vec) { + match self { + ShieldedTransferTransition::V0(v0) => v0.proof = proof, + } + } + + fn binding_signature(&self) -> [u8; 64] { + match self { + ShieldedTransferTransition::V0(v0) => v0.binding_signature, + } + } + + fn set_binding_signature(&mut self, binding_signature: [u8; 64]) { + match self { + ShieldedTransferTransition::V0(v0) => v0.binding_signature = binding_signature, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::state_transition::shielded_transfer_transition::v0::ShieldedTransferTransitionV0; + + fn mk_action(nullifier_byte: u8) -> SerializedAction { + SerializedAction { + nullifier: [nullifier_byte; 32], + rk: [2u8; 32], + cmx: [3u8; 32], + encrypted_note: vec![4u8; 216], + cv_net: [5u8; 32], + spend_auth_sig: [6u8; 64], + } + } + + fn make_transition() -> ShieldedTransferTransition { + ShieldedTransferTransitionV0 { + actions: vec![mk_action(0x11)], + value_balance: 1_000, + anchor: [7u8; 32], + proof: vec![8u8; 10], + binding_signature: [9u8; 64], + } + .into() + } + + #[test] + fn test_getters_and_setters() { + let mut t = make_transition(); + + assert_eq!(t.actions(), &[mk_action(0x11)]); + assert_eq!(t.value_balance(), 1_000); + assert_eq!(t.anchor(), [7u8; 32]); + assert_eq!(t.proof(), &[8u8; 10]); + assert_eq!(t.binding_signature(), [9u8; 64]); + + t.set_actions(vec![mk_action(0x22)]); + assert_eq!(t.actions(), &[mk_action(0x22)]); + + t.set_value_balance(42); + assert_eq!(t.value_balance(), 42); + + t.set_anchor([1u8; 32]); + assert_eq!(t.anchor(), [1u8; 32]); + + t.set_proof(vec![0xAu8; 5]); + assert_eq!(t.proof(), &[0xAu8; 5]); + + t.set_binding_signature([0xBu8; 64]); + assert_eq!(t.binding_signature(), [0xBu8; 64]); + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_transfer_transition/accessors/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_transfer_transition/accessors/v0/mod.rs index 869c6167d28..0300b5592a8 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_transfer_transition/accessors/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_transfer_transition/accessors/v0/mod.rs @@ -1,8 +1,30 @@ use crate::shielded::SerializedAction; pub trait ShieldedTransferTransitionAccessorsV0 { - /// Get the serialized Orchard actions + /// Get the serialized Orchard actions. fn actions(&self) -> &[SerializedAction]; + /// Replace the serialized Orchard actions. + fn set_actions(&mut self, actions: Vec); + + /// Get the net value balance (fee amount extracted from the shielded pool). + fn value_balance(&self) -> u64; + /// Set the net value balance (fee amount extracted from the shielded pool). + fn set_value_balance(&mut self, value_balance: u64); + + /// Get the Orchard anchor (Sinsemilla root of the note commitment tree). + fn anchor(&self) -> [u8; 32]; + /// Set the Orchard anchor. + fn set_anchor(&mut self, anchor: [u8; 32]); + + /// Get the Halo2 proof bytes. + fn proof(&self) -> &[u8]; + /// Set the Halo2 proof bytes. + fn set_proof(&mut self, proof: Vec); + + /// Get the RedPallas binding signature. + fn binding_signature(&self) -> [u8; 64]; + /// Set the RedPallas binding signature. + fn set_binding_signature(&mut self, binding_signature: [u8; 64]); /// Extract nullifier bytes from each action. /// Generic over the element type: use `Vec` or `[u8; 32]` as needed. diff --git a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_withdrawal_transition/accessors/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_withdrawal_transition/accessors/mod.rs index d2bdd82cf71..890ba767d16 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_withdrawal_transition/accessors/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_withdrawal_transition/accessors/mod.rs @@ -5,6 +5,7 @@ pub use v0::*; use crate::identity::core_script::CoreScript; use crate::shielded::SerializedAction; use crate::state_transition::shielded_withdrawal_transition::ShieldedWithdrawalTransition; +use crate::withdrawal::Pooling; impl ShieldedWithdrawalTransitionAccessorsV0 for ShieldedWithdrawalTransition { fn actions(&self) -> &[SerializedAction] { @@ -13,9 +14,162 @@ impl ShieldedWithdrawalTransitionAccessorsV0 for ShieldedWithdrawalTransition { } } + fn set_actions(&mut self, actions: Vec) { + match self { + ShieldedWithdrawalTransition::V0(v0) => v0.actions = actions, + } + } + + fn unshielding_amount(&self) -> u64 { + match self { + ShieldedWithdrawalTransition::V0(v0) => v0.unshielding_amount, + } + } + + fn set_unshielding_amount(&mut self, unshielding_amount: u64) { + match self { + ShieldedWithdrawalTransition::V0(v0) => v0.unshielding_amount = unshielding_amount, + } + } + + fn anchor(&self) -> [u8; 32] { + match self { + ShieldedWithdrawalTransition::V0(v0) => v0.anchor, + } + } + + fn set_anchor(&mut self, anchor: [u8; 32]) { + match self { + ShieldedWithdrawalTransition::V0(v0) => v0.anchor = anchor, + } + } + + fn proof(&self) -> &[u8] { + match self { + ShieldedWithdrawalTransition::V0(v0) => &v0.proof, + } + } + + fn set_proof(&mut self, proof: Vec) { + match self { + ShieldedWithdrawalTransition::V0(v0) => v0.proof = proof, + } + } + + fn binding_signature(&self) -> [u8; 64] { + match self { + ShieldedWithdrawalTransition::V0(v0) => v0.binding_signature, + } + } + + fn set_binding_signature(&mut self, binding_signature: [u8; 64]) { + match self { + ShieldedWithdrawalTransition::V0(v0) => v0.binding_signature = binding_signature, + } + } + + fn core_fee_per_byte(&self) -> u32 { + match self { + ShieldedWithdrawalTransition::V0(v0) => v0.core_fee_per_byte, + } + } + + fn set_core_fee_per_byte(&mut self, core_fee_per_byte: u32) { + match self { + ShieldedWithdrawalTransition::V0(v0) => v0.core_fee_per_byte = core_fee_per_byte, + } + } + + fn pooling(&self) -> Pooling { + match self { + ShieldedWithdrawalTransition::V0(v0) => v0.pooling, + } + } + + fn set_pooling(&mut self, pooling: Pooling) { + match self { + ShieldedWithdrawalTransition::V0(v0) => v0.pooling = pooling, + } + } + fn output_script(&self) -> &CoreScript { match self { ShieldedWithdrawalTransition::V0(v0) => &v0.output_script, } } + + fn set_output_script(&mut self, output_script: CoreScript) { + match self { + ShieldedWithdrawalTransition::V0(v0) => v0.output_script = output_script, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::state_transition::shielded_withdrawal_transition::v0::ShieldedWithdrawalTransitionV0; + + fn mk_action(nullifier_byte: u8) -> SerializedAction { + SerializedAction { + nullifier: [nullifier_byte; 32], + rk: [2u8; 32], + cmx: [3u8; 32], + encrypted_note: vec![4u8; 216], + cv_net: [5u8; 32], + spend_auth_sig: [6u8; 64], + } + } + + fn make_transition() -> ShieldedWithdrawalTransition { + ShieldedWithdrawalTransitionV0 { + actions: vec![mk_action(0x11)], + unshielding_amount: 1_000, + anchor: [7u8; 32], + proof: vec![8u8; 10], + binding_signature: [9u8; 64], + core_fee_per_byte: 1, + pooling: Pooling::Never, + output_script: CoreScript::new_p2pkh([11u8; 20]), + } + .into() + } + + #[test] + fn test_getters_and_setters() { + let mut t = make_transition(); + + assert_eq!(t.actions(), &[mk_action(0x11)]); + assert_eq!(t.unshielding_amount(), 1_000); + assert_eq!(t.anchor(), [7u8; 32]); + assert_eq!(t.proof(), &[8u8; 10]); + assert_eq!(t.binding_signature(), [9u8; 64]); + assert_eq!(t.core_fee_per_byte(), 1); + assert_eq!(t.pooling(), Pooling::Never); + assert_eq!(t.output_script(), &CoreScript::new_p2pkh([11u8; 20])); + + t.set_actions(vec![mk_action(0x22)]); + assert_eq!(t.actions(), &[mk_action(0x22)]); + + t.set_unshielding_amount(42); + assert_eq!(t.unshielding_amount(), 42); + + t.set_anchor([1u8; 32]); + assert_eq!(t.anchor(), [1u8; 32]); + + t.set_proof(vec![0xAu8; 5]); + assert_eq!(t.proof(), &[0xAu8; 5]); + + t.set_binding_signature([0xBu8; 64]); + assert_eq!(t.binding_signature(), [0xBu8; 64]); + + t.set_core_fee_per_byte(7); + assert_eq!(t.core_fee_per_byte(), 7); + + t.set_pooling(Pooling::Standard); + assert_eq!(t.pooling(), Pooling::Standard); + + t.set_output_script(CoreScript::new_p2pkh([22u8; 20])); + assert_eq!(t.output_script(), &CoreScript::new_p2pkh([22u8; 20])); + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_withdrawal_transition/accessors/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_withdrawal_transition/accessors/v0/mod.rs index c6fd48b4a1f..08b8b4678c8 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_withdrawal_transition/accessors/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_withdrawal_transition/accessors/v0/mod.rs @@ -1,12 +1,47 @@ use crate::identity::core_script::CoreScript; use crate::shielded::SerializedAction; +use crate::withdrawal::Pooling; pub trait ShieldedWithdrawalTransitionAccessorsV0 { - /// Get the serialized Orchard actions + /// Get the serialized Orchard actions. fn actions(&self) -> &[SerializedAction]; + /// Replace the serialized Orchard actions. + fn set_actions(&mut self, actions: Vec); - /// Get the output script receiving withdrawn funds + /// Get the total credits leaving the shielded pool (recipient amount + fee). + fn unshielding_amount(&self) -> u64; + /// Set the total credits leaving the shielded pool. + fn set_unshielding_amount(&mut self, unshielding_amount: u64); + + /// Get the Orchard anchor (Sinsemilla root of the note commitment tree). + fn anchor(&self) -> [u8; 32]; + /// Set the Orchard anchor. + fn set_anchor(&mut self, anchor: [u8; 32]); + + /// Get the Halo2 proof bytes. + fn proof(&self) -> &[u8]; + /// Set the Halo2 proof bytes. + fn set_proof(&mut self, proof: Vec); + + /// Get the RedPallas binding signature. + fn binding_signature(&self) -> [u8; 64]; + /// Set the RedPallas binding signature. + fn set_binding_signature(&mut self, binding_signature: [u8; 64]); + + /// Get the core transaction fee rate. + fn core_fee_per_byte(&self) -> u32; + /// Set the core transaction fee rate. + fn set_core_fee_per_byte(&mut self, core_fee_per_byte: u32); + + /// Get the withdrawal pooling strategy. + fn pooling(&self) -> Pooling; + /// Set the withdrawal pooling strategy. + fn set_pooling(&mut self, pooling: Pooling); + + /// Get the output script receiving withdrawn funds. fn output_script(&self) -> &CoreScript; + /// Set the output script receiving withdrawn funds. + fn set_output_script(&mut self, output_script: CoreScript); /// Extract nullifier bytes from each action. /// Generic over the element type: use `Vec` or `[u8; 32]` as needed. diff --git a/packages/rs-dpp/src/state_transition/state_transitions/shielded/unshield_transition/accessors/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/shielded/unshield_transition/accessors/mod.rs index 2c0619d2159..8b77ffe21d5 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/shielded/unshield_transition/accessors/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/shielded/unshield_transition/accessors/mod.rs @@ -13,9 +13,128 @@ impl UnshieldTransitionAccessorsV0 for UnshieldTransition { } } + fn set_actions(&mut self, actions: Vec) { + match self { + UnshieldTransition::V0(v0) => v0.actions = actions, + } + } + fn output_address(&self) -> &PlatformAddress { match self { UnshieldTransition::V0(v0) => &v0.output_address, } } + + fn set_output_address(&mut self, output_address: PlatformAddress) { + match self { + UnshieldTransition::V0(v0) => v0.output_address = output_address, + } + } + + fn unshielding_amount(&self) -> u64 { + match self { + UnshieldTransition::V0(v0) => v0.unshielding_amount, + } + } + + fn set_unshielding_amount(&mut self, unshielding_amount: u64) { + match self { + UnshieldTransition::V0(v0) => v0.unshielding_amount = unshielding_amount, + } + } + + fn anchor(&self) -> [u8; 32] { + match self { + UnshieldTransition::V0(v0) => v0.anchor, + } + } + + fn set_anchor(&mut self, anchor: [u8; 32]) { + match self { + UnshieldTransition::V0(v0) => v0.anchor = anchor, + } + } + + fn proof(&self) -> &[u8] { + match self { + UnshieldTransition::V0(v0) => &v0.proof, + } + } + + fn set_proof(&mut self, proof: Vec) { + match self { + UnshieldTransition::V0(v0) => v0.proof = proof, + } + } + + fn binding_signature(&self) -> [u8; 64] { + match self { + UnshieldTransition::V0(v0) => v0.binding_signature, + } + } + + fn set_binding_signature(&mut self, binding_signature: [u8; 64]) { + match self { + UnshieldTransition::V0(v0) => v0.binding_signature = binding_signature, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::state_transition::unshield_transition::v0::UnshieldTransitionV0; + + fn mk_action(nullifier_byte: u8) -> SerializedAction { + SerializedAction { + nullifier: [nullifier_byte; 32], + rk: [2u8; 32], + cmx: [3u8; 32], + encrypted_note: vec![4u8; 216], + cv_net: [5u8; 32], + spend_auth_sig: [6u8; 64], + } + } + + fn make_transition() -> UnshieldTransition { + UnshieldTransitionV0 { + output_address: PlatformAddress::P2pkh([1u8; 20]), + actions: vec![mk_action(0x11)], + unshielding_amount: 1_000, + anchor: [7u8; 32], + proof: vec![8u8; 10], + binding_signature: [9u8; 64], + } + .into() + } + + #[test] + fn test_getters_and_setters() { + let mut t = make_transition(); + + assert_eq!(t.actions(), &[mk_action(0x11)]); + assert_eq!(t.output_address(), &PlatformAddress::P2pkh([1u8; 20])); + assert_eq!(t.unshielding_amount(), 1_000); + assert_eq!(t.anchor(), [7u8; 32]); + assert_eq!(t.proof(), &[8u8; 10]); + assert_eq!(t.binding_signature(), [9u8; 64]); + + t.set_actions(vec![mk_action(0x22)]); + assert_eq!(t.actions(), &[mk_action(0x22)]); + + t.set_output_address(PlatformAddress::P2pkh([2u8; 20])); + assert_eq!(t.output_address(), &PlatformAddress::P2pkh([2u8; 20])); + + t.set_unshielding_amount(42); + assert_eq!(t.unshielding_amount(), 42); + + t.set_anchor([1u8; 32]); + assert_eq!(t.anchor(), [1u8; 32]); + + t.set_proof(vec![0xAu8; 5]); + assert_eq!(t.proof(), &[0xAu8; 5]); + + t.set_binding_signature([0xBu8; 64]); + assert_eq!(t.binding_signature(), [0xBu8; 64]); + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/shielded/unshield_transition/accessors/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/shielded/unshield_transition/accessors/v0/mod.rs index 583448b4568..5fb7a9e3f89 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/shielded/unshield_transition/accessors/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/shielded/unshield_transition/accessors/v0/mod.rs @@ -2,11 +2,35 @@ use crate::address_funds::PlatformAddress; use crate::shielded::SerializedAction; pub trait UnshieldTransitionAccessorsV0 { - /// Get the serialized Orchard actions + /// Get the serialized Orchard actions. fn actions(&self) -> &[SerializedAction]; + /// Replace the serialized Orchard actions. + fn set_actions(&mut self, actions: Vec); - /// Get the output address receiving unshielded funds + /// Get the output address receiving unshielded funds. fn output_address(&self) -> &PlatformAddress; + /// Set the output address receiving unshielded funds. + fn set_output_address(&mut self, output_address: PlatformAddress); + + /// Get the total credits leaving the shielded pool (recipient amount + fee). + fn unshielding_amount(&self) -> u64; + /// Set the total credits leaving the shielded pool. + fn set_unshielding_amount(&mut self, unshielding_amount: u64); + + /// Get the Orchard anchor (Sinsemilla root of the note commitment tree). + fn anchor(&self) -> [u8; 32]; + /// Set the Orchard anchor. + fn set_anchor(&mut self, anchor: [u8; 32]); + + /// Get the Halo2 proof bytes. + fn proof(&self) -> &[u8]; + /// Set the Halo2 proof bytes. + fn set_proof(&mut self, proof: Vec); + + /// Get the RedPallas binding signature. + fn binding_signature(&self) -> [u8; 64]; + /// Set the RedPallas binding signature. + fn set_binding_signature(&mut self, binding_signature: [u8; 64]); /// Extract nullifier bytes from each action. /// Generic over the element type: use `Vec` or `[u8; 32]` as needed.