Skip to main content

drive/state_transition_action/shielded/
mod.rs

1/// IdentityCreateFromShieldedPool transition action
2pub mod identity_create_from_shielded_pool;
3/// IdentityTopUpFromShieldedPool transition action
4pub mod identity_top_up_from_shielded_pool;
5/// Shield transition action
6pub mod shield;
7/// Shield from asset lock transition action
8pub mod shield_from_asset_lock;
9/// Shield from identity transition action
10pub mod shield_from_identity;
11/// Shielded transfer transition action
12pub mod shielded_transfer;
13/// Shielded withdrawal transition action
14pub mod shielded_withdrawal;
15/// TokenPurchaseFromShieldedPool transition action
16pub mod token_purchase_from_shielded_pool;
17/// TokenShieldedTransferWithShieldedFee transition action
18pub mod token_shielded_transfer_with_shielded_fee;
19/// TokenUnshieldWithShieldedFee transition action
20pub mod token_unshield_with_shielded_fee;
21/// Unshield transition action
22pub mod unshield;
23
24use dpp::shielded::SerializedAction;
25
26/// One note from an Orchard action: the per-action fields that travel together.
27#[derive(Debug, Clone)]
28pub struct ShieldedActionNote {
29    /// Nullifier (needed for Rho derivation in trial decryption)
30    pub nullifier: [u8; 32],
31    /// Note commitment (cmx value)
32    pub cmx: [u8; 32],
33    /// Value commitment (cv_net). Stored unencrypted alongside the note so a
34    /// wallet can recover the value of an outgoing note via OVK decryption.
35    pub cv_net: [u8; 32],
36    /// Encrypted note ciphertext
37    pub encrypted_note: Vec<u8>,
38}
39
40impl From<&SerializedAction> for ShieldedActionNote {
41    fn from(action: &SerializedAction) -> Self {
42        ShieldedActionNote {
43            nullifier: action.nullifier,
44            cmx: action.cmx,
45            cv_net: action.cv_net,
46            encrypted_note: action.encrypted_note.clone(),
47        }
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54
55    #[test]
56    fn test_shielded_action_note_fields() {
57        let note = ShieldedActionNote {
58            nullifier: [0xAA; 32],
59            cmx: [0xBB; 32],
60            cv_net: [0x22; 32],
61            encrypted_note: vec![1, 2, 3, 4],
62        };
63        assert_eq!(note.nullifier, [0xAA; 32]);
64        assert_eq!(note.cmx, [0xBB; 32]);
65        assert_eq!(note.cv_net, [0x22; 32]);
66        assert_eq!(note.encrypted_note, vec![1, 2, 3, 4]);
67    }
68
69    #[test]
70    fn test_from_serialized_action() {
71        let action = SerializedAction {
72            nullifier: [0x11; 32],
73            rk: [0x00; 32],
74            cmx: [0x22; 32],
75            encrypted_note: vec![0xAB, 0xCD],
76            cv_net: [0x33; 32],
77            spend_auth_sig: [0x00; 64],
78        };
79        let note = ShieldedActionNote::from(&action);
80        assert_eq!(note.nullifier, [0x11; 32]);
81        assert_eq!(note.cmx, [0x22; 32]);
82        assert_eq!(note.cv_net, [0x33; 32]);
83        assert_eq!(note.encrypted_note, vec![0xAB, 0xCD]);
84    }
85
86    #[test]
87    fn test_from_serialized_action_empty_encrypted_note() {
88        let action = SerializedAction {
89            nullifier: [0xFF; 32],
90            rk: [0x00; 32],
91            cmx: [0x00; 32],
92            encrypted_note: vec![],
93            cv_net: [0x44; 32],
94            spend_auth_sig: [0x00; 64],
95        };
96        let note = ShieldedActionNote::from(&action);
97        assert_eq!(note.nullifier, [0xFF; 32]);
98        assert_eq!(note.cv_net, [0x44; 32]);
99        assert!(note.encrypted_note.is_empty());
100    }
101
102    #[test]
103    fn test_clone() {
104        let note = ShieldedActionNote {
105            nullifier: [0xAA; 32],
106            cmx: [0xBB; 32],
107            cv_net: [0x22; 32],
108            encrypted_note: vec![5, 6, 7],
109        };
110        let cloned = note.clone();
111        assert_eq!(cloned.nullifier, note.nullifier);
112        assert_eq!(cloned.cmx, note.cmx);
113        assert_eq!(cloned.cv_net, note.cv_net);
114        assert_eq!(cloned.encrypted_note, note.encrypted_note);
115    }
116
117    #[test]
118    fn test_debug() {
119        let note = ShieldedActionNote {
120            nullifier: [0x00; 32],
121            cmx: [0x00; 32],
122            cv_net: [0x22; 32],
123            encrypted_note: vec![],
124        };
125        let debug_str = format!("{:?}", note);
126        assert!(debug_str.contains("ShieldedActionNote"));
127    }
128}