dpp/asset_lock/reduced_asset_lock_value/
mod.rs1use crate::asset_lock::reduced_asset_lock_value::v0::AssetLockValueV0;
2use crate::fee::Credits;
3use crate::ProtocolError;
4use bincode::{Decode, Encode};
5use derive_more::From;
6use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize};
7use platform_value::Bytes32;
8use platform_version::version::PlatformVersion;
9
10mod v0;
11
12pub use v0::{AssetLockValueGettersV0, AssetLockValueSettersV0};
13
14#[derive(
15 Debug,
16 Clone,
17 Encode,
18 Decode,
19 PlatformSerialize,
20 PlatformDeserialize,
21 From,
22 PartialEq,
23 serde::Serialize,
24 serde::Deserialize,
25)]
26#[platform_serialize(unversioned)]
27#[serde(tag = "$formatVersion")]
28pub enum AssetLockValue {
29 #[serde(rename = "0")]
30 V0(AssetLockValueV0),
31}
32
33#[cfg(all(feature = "json-conversion", feature = "serde-conversion"))]
34impl crate::serialization::JsonConvertible for AssetLockValue {}
35
36#[cfg(all(feature = "value-conversion", feature = "serde-conversion"))]
37impl crate::serialization::ValueConvertible for AssetLockValue {}
38
39impl AssetLockValue {
40 pub fn new(
41 initial_credit_value: Credits,
42 tx_out_script: Vec<u8>,
43 remaining_credit_value: Credits,
44 used_tags: Vec<Bytes32>,
45 platform_version: &PlatformVersion,
46 ) -> Result<Self, ProtocolError> {
47 match platform_version
48 .dpp
49 .asset_lock_versions
50 .reduced_asset_lock_value
51 .default_current_version
52 {
53 0 => Ok(AssetLockValue::V0(AssetLockValueV0 {
54 initial_credit_value,
55 tx_out_script,
56 remaining_credit_value,
57 used_tags,
58 })),
59 version => Err(ProtocolError::UnknownVersionMismatch {
60 method: "ReducedAssetLockValue::new".to_string(),
61 known_versions: vec![0],
62 received: version,
63 }),
64 }
65 }
66}
67
68impl AssetLockValueGettersV0 for AssetLockValue {
69 fn initial_credit_value(&self) -> Credits {
70 match self {
71 AssetLockValue::V0(v0) => v0.initial_credit_value,
72 }
73 }
74
75 fn tx_out_script(&self) -> &Vec<u8> {
76 match self {
77 AssetLockValue::V0(v0) => &v0.tx_out_script,
78 }
79 }
80
81 fn tx_out_script_owned(self) -> Vec<u8> {
82 match self {
83 AssetLockValue::V0(v0) => v0.tx_out_script,
84 }
85 }
86
87 fn remaining_credit_value(&self) -> Credits {
88 match self {
89 AssetLockValue::V0(v0) => v0.remaining_credit_value,
90 }
91 }
92
93 fn used_tags_ref(&self) -> &Vec<Bytes32> {
94 match self {
95 AssetLockValue::V0(v0) => &v0.used_tags,
96 }
97 }
98}
99
100impl AssetLockValueSettersV0 for AssetLockValue {
101 fn set_initial_credit_value(&mut self, value: Credits) {
102 match self {
103 AssetLockValue::V0(v0) => v0.initial_credit_value = value,
104 }
105 }
106
107 fn set_tx_out_script(&mut self, value: Vec<u8>) {
108 match self {
109 AssetLockValue::V0(v0) => v0.tx_out_script = value,
110 }
111 }
112
113 fn set_remaining_credit_value(&mut self, value: Credits) {
114 match self {
115 AssetLockValue::V0(v0) => v0.remaining_credit_value = value,
116 }
117 }
118
119 fn set_used_tags(&mut self, tags: Vec<Bytes32>) {
120 match self {
121 AssetLockValue::V0(v0) => v0.used_tags = tags,
122 }
123 }
124
125 fn add_used_tag(&mut self, tag: Bytes32) {
126 match self {
127 AssetLockValue::V0(v0) => v0.used_tags.push(tag),
128 }
129 }
130}
131
132#[cfg(all(
133 test,
134 feature = "json-conversion",
135 feature = "value-conversion",
136 feature = "serde-conversion"
137))]
138mod json_convertible_tests {
139 use super::*;
140 use platform_value::platform_value;
141 use platform_version::version::PlatformVersion;
142 use serde_json::json;
143
144 fn fixture() -> AssetLockValue {
145 AssetLockValue::new(
146 1_000_000,
147 vec![0xaa, 0xbb, 0xcc, 0xdd],
148 500_000,
149 vec![Bytes32::new([0x42; 32])],
150 PlatformVersion::latest(),
151 )
152 .expect("fixture")
153 }
154
155 #[test]
156 fn json_round_trip_with_full_wire_shape() {
157 use crate::serialization::JsonConvertible;
158 let original = fixture();
159 let json = original.to_json().expect("to_json");
160 assert_eq!(
165 json,
166 json!({
167 "$formatVersion": "0",
168 "initial_credit_value": 1_000_000,
169 "tx_out_script": "qrvM3Q==",
170 "remaining_credit_value": 500_000,
171 "used_tags": ["QkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkI="],
172 })
173 );
174 let recovered = AssetLockValue::from_json(json).expect("from_json");
175 assert_eq!(original, recovered);
176 }
177
178 #[test]
179 fn value_round_trip_with_full_wire_shape() {
180 use crate::serialization::ValueConvertible;
181 use platform_value::Value;
182 let original = fixture();
183 let value = original.to_object().expect("to_object");
184 assert_eq!(
190 value,
191 platform_value!({
192 "$formatVersion": "0",
193 "initial_credit_value": 1_000_000u64,
194 "tx_out_script": Value::Bytes(vec![0xaa, 0xbb, 0xcc, 0xdd]),
195 "remaining_credit_value": 500_000u64,
196 "used_tags": [Value::Bytes32([0x42; 32])],
197 })
198 );
199 let recovered = AssetLockValue::from_object(value).expect("from_object");
200 assert_eq!(original, recovered);
201 }
202
203 #[test]
204 fn json_large_credits_serialize_as_strings_for_js_safety() {
205 use crate::serialization::JsonConvertible;
206 let original = AssetLockValue::new(
212 9_007_199_254_740_993, vec![0xaa, 0xbb, 0xcc, 0xdd],
214 500_000,
215 vec![Bytes32::new([0x42; 32])],
216 PlatformVersion::latest(),
217 )
218 .expect("fixture");
219 let json = original.to_json().expect("to_json");
220 assert_eq!(json["initial_credit_value"], json!("9007199254740993"));
221 assert_eq!(json["remaining_credit_value"], json!(500_000));
223 let recovered = AssetLockValue::from_json(json).expect("from_json");
225 assert_eq!(original, recovered);
226 }
227}