dpp/state_transition/state_transitions/shielded/shield_transition/
mod.rs1pub mod accessors;
2pub mod methods;
3mod state_transition_estimated_fee_validation;
4mod state_transition_like;
5mod state_transition_validation;
6pub mod v0;
7mod version;
8
9use crate::state_transition::shield_transition::v0::ShieldTransitionV0;
10use crate::state_transition::shield_transition::v0::ShieldTransitionV0Signable;
11use crate::state_transition::StateTransitionFieldTypes;
12
13pub type ShieldTransitionLatest = ShieldTransitionV0;
14
15use crate::identity::state_transition::OptionallyAssetLockProved;
16#[cfg(feature = "json-conversion")]
17use crate::serialization::JsonConvertible;
18#[cfg(feature = "value-conversion")]
19use crate::serialization::ValueConvertible;
20use crate::ProtocolError;
21use bincode::{Decode, Encode};
22use derive_more::From;
23use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize, PlatformSignable};
24use platform_versioning::PlatformVersioned;
25#[cfg(feature = "serde-conversion")]
26use serde::{Deserialize, Serialize};
27
28#[derive(
29 Debug,
30 Clone,
31 Encode,
32 Decode,
33 PlatformDeserialize,
34 PlatformSerialize,
35 PlatformSignable,
36 PlatformVersioned,
37 From,
38 PartialEq,
39)]
40#[cfg_attr(
41 feature = "serde-conversion",
42 derive(Serialize, Deserialize),
43 serde(tag = "$formatVersion")
44)]
45#[cfg_attr(
46 all(feature = "json-conversion", feature = "serde-conversion"),
47 derive(JsonConvertible)
48)]
49#[cfg_attr(feature = "value-conversion", derive(ValueConvertible))]
50#[platform_serialize(unversioned)] #[platform_version_path_bounds(
52 "dpp.state_transition_serialization_versions.shield_state_transition"
53)]
54pub enum ShieldTransition {
55 #[cfg_attr(feature = "serde-conversion", serde(rename = "0"))]
56 V0(ShieldTransitionV0),
57}
58
59impl OptionallyAssetLockProved for ShieldTransition {}
60
61impl StateTransitionFieldTypes for ShieldTransition {
62 fn signature_property_paths() -> Vec<&'static str> {
63 vec![]
64 }
65
66 fn identifiers_property_paths() -> Vec<&'static str> {
67 vec![]
68 }
69
70 fn binary_property_paths() -> Vec<&'static str> {
71 vec![]
72 }
73}
74
75#[cfg(all(
76 test,
77 feature = "json-conversion",
78 feature = "value-conversion",
79 feature = "serde-conversion"
80))]
81pub(crate) mod json_convertible_tests {
82 use super::*;
83 use crate::address_funds::{AddressFundsFeeStrategyStep, AddressWitness, PlatformAddress};
84 use crate::shielded::SerializedAction;
85 use crate::state_transition::shield_transition::v0::ShieldTransitionV0;
86 use platform_value::{platform_value, BinaryData, Bytes32};
87 use serde_json::json;
88 use std::collections::BTreeMap;
89
90 fn fixture_action() -> SerializedAction {
91 SerializedAction {
92 nullifier: [0x11; 32],
93 rk: [0x22; 32],
94 cmx: [0x33; 32],
95 encrypted_note: vec![0x44; 216],
96 cv_net: [0x55; 32],
97 spend_auth_sig: [0x66; 64],
98 }
99 }
100
101 pub(crate) fn fixture() -> ShieldTransition {
102 let mut inputs = BTreeMap::new();
103 inputs.insert(PlatformAddress::P2pkh([0xa1; 20]), (3u32, 500_000u64));
104 ShieldTransition::V0(ShieldTransitionV0 {
105 inputs,
106 actions: vec![fixture_action()],
107 amount: 250_000,
108 anchor: [0x77; 32],
109 proof: vec![0x88; 192],
110 binding_signature: [0x99; 64],
111 fee_strategy: vec![AddressFundsFeeStrategyStep::DeductFromInput(0)],
112 user_fee_increase: 5,
113 input_witnesses: vec![AddressWitness::P2pkh {
114 signature: BinaryData::new(vec![0xaa; 65]),
115 }],
116 })
117 }
118
119 #[test]
120 fn json_round_trip_with_full_wire_shape() {
121 use crate::serialization::JsonConvertible;
122 let original = fixture();
123 let json = original.to_json().expect("to_json");
124 assert_eq!(
133 json,
134 json!({
135 "$formatVersion": "0",
136 "inputs": [{
137 "address": "00a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1",
138 "nonce": 3,
139 "amount": 500_000,
140 }],
141 "actions": [{
142 "nullifier": "ERERERERERERERERERERERERERERERERERERERERERE=",
143 "rk": "IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI=",
144 "cmx": "MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM=",
145 "encryptedNote": "RERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERE",
146 "cvNet": "VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVU=",
147 "spendAuthSig": "ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZg==",
148 }],
149 "amount": 250_000,
150 "anchor": "d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3c=",
151 "proof": "iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI",
152 "bindingSignature": "mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmQ==",
153 "feeStrategy": [{"$type": "deductFromInput", "index": 0}],
154 "userFeeIncrease": 5,
155 "inputWitnesses": [{
156 "$type": "p2pkh",
157 "signature": "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo=",
158 }],
159 })
160 );
161 let recovered = ShieldTransition::from_json(json).expect("from_json");
162 assert_eq!(original, recovered);
163 }
164
165 #[test]
166 fn value_round_trip_with_full_wire_shape() {
167 use crate::serialization::ValueConvertible;
168 let original = fixture();
169 let value = original.to_object().expect("to_object");
170 let mut address_bytes = vec![0x00];
175 address_bytes.extend(vec![0xa1; 20]);
176 assert_eq!(
177 value,
178 platform_value!({
179 "$formatVersion": "0",
180 "inputs": [{
181 "address": platform_value::Value::Bytes(address_bytes),
182 "nonce": 3u32,
183 "amount": 500_000u64,
184 }],
185 "actions": [{
186 "nullifier": Bytes32::new([0x11; 32]),
187 "rk": Bytes32::new([0x22; 32]),
188 "cmx": Bytes32::new([0x33; 32]),
189 "encryptedNote": platform_value::Value::Bytes(vec![0x44; 216]),
190 "cvNet": Bytes32::new([0x55; 32]),
191 "spendAuthSig": platform_value::Value::Bytes(vec![0x66; 64]),
192 }],
193 "amount": 250_000u64,
194 "anchor": Bytes32::new([0x77; 32]),
195 "proof": platform_value::Value::Bytes(vec![0x88; 192]),
196 "bindingSignature": platform_value::Value::Bytes(vec![0x99; 64]),
197 "feeStrategy": [{"$type": "deductFromInput", "index": 0u16}],
198 "userFeeIncrease": 5u16,
199 "inputWitnesses": [{
200 "$type": "p2pkh",
201 "signature": BinaryData::new(vec![0xaa; 65]),
202 }],
203 })
204 );
205 let recovered = ShieldTransition::from_object(value).expect("from_object");
206 assert_eq!(original, recovered);
207 }
208}