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