Skip to content

Commit 18afc1e

Browse files
authored
Merge pull request #208 from alessandrokonrad/isValid
is_valid addition to transaction
2 parents 6bf7148 + 2495240 commit 18afc1e

File tree

5 files changed

+67
-23
lines changed

5 files changed

+67
-23
lines changed

rust/src/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub enum DeserializeFailure {
3030
DuplicateKey(Key),
3131
EndingBreakMissing,
3232
ExpectedNull,
33+
ExpectedBool,
3334
FixedValueMismatch{
3435
found: Key,
3536
expected: Key,
@@ -95,6 +96,7 @@ impl std::fmt::Display for DeserializeError {
9596
DeserializeFailure::DuplicateKey(key) => write!(f, "Duplicate key: {}", key),
9697
DeserializeFailure::EndingBreakMissing => write!(f, "Missing ending CBOR Break"),
9798
DeserializeFailure::ExpectedNull => write!(f, "Expected null, found other type"),
99+
DeserializeFailure::ExpectedBool => write!(f, "Expected bool, found other type"),
98100
DeserializeFailure::FixedValueMismatch{ found, expected } => write!(f, "Expected fixed value {} found {}", expected, found),
99101
DeserializeFailure::MandatoryFieldMissing(key) => write!(f, "Mandatory field {} not found", key),
100102
DeserializeFailure::Metadata(e) => write!(f, "Metadata error: {:?}", e),

rust/src/fees.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@ mod tests {
8282
let linear_fee = LinearFee::new(&to_bignum(500), &to_bignum(2));
8383
assert_eq!(
8484
hex::encode(signed_tx.to_bytes()),
85-
"83a400818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a00016f32030aa10081825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee5840fae5de40c94d759ce13bf9886262159c4f26a289fd192e165995b785259e503f6887bf39dfa23a47cf163784c6eee23f61440e749bc1df3c73975f5231aeda0ff6"
85+
"84a400818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a00016f32030aa10081825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee5840fae5de40c94d759ce13bf9886262159c4f26a289fd192e165995b785259e503f6887bf39dfa23a47cf163784c6eee23f61440e749bc1df3c73975f5231aeda0ff5f6"
8686
);
8787
assert_eq!(
8888
min_fee(&signed_tx, &linear_fee).unwrap().to_str(),
89-
"94002" // todo: compare to Haskell fee to make sure the diff is not too big
89+
"94502" // todo: compare to Haskell fee to make sure the diff is not too big
9090
);
9191
}
9292

@@ -128,11 +128,11 @@ mod tests {
128128
let linear_fee = LinearFee::new(&to_bignum(500), &to_bignum(2));
129129
assert_eq!(
130130
hex::encode(signed_tx.to_bytes()),
131-
"83a400818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a0001b582030aa10281845820473811afd4d939b337c9be1a2ceeb2cb2c75108bddf224c5c21c51592a7b204a5840f0b04a852353eb23b9570df80b2aa6a61b723341ab45a2024a05b07cf58be7bdfbf722c09040db6cee61a0d236870d6ad1e1349ac999ec0db28f9471af25fb0c5820c8b95d0d35fe75a70f9f5633a3e2439b2994b9e2bc851c49e9f91d1a5dcbb1a341a0f6"
131+
"84a400818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a0001b582030aa10281845820473811afd4d939b337c9be1a2ceeb2cb2c75108bddf224c5c21c51592a7b204a5840f0b04a852353eb23b9570df80b2aa6a61b723341ab45a2024a05b07cf58be7bdfbf722c09040db6cee61a0d236870d6ad1e1349ac999ec0db28f9471af25fb0c5820c8b95d0d35fe75a70f9f5633a3e2439b2994b9e2bc851c49e9f91d1a5dcbb1a341a0f5f6"
132132
);
133133
assert_eq!(
134134
min_fee(&signed_tx, &linear_fee).unwrap().to_str(),
135-
"112002" // todo: compare to Haskell fee to make sure the diff is not too big
135+
"112502" // todo: compare to Haskell fee to make sure the diff is not too big
136136
);
137137
}
138138

@@ -198,11 +198,11 @@ mod tests {
198198
let linear_fee = LinearFee::new(&to_bignum(500), &to_bignum(2));
199199
assert_eq!(
200200
hex::encode(signed_tx.to_bytes()),
201-
"83a400828258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7182a82582082839f8200d81858248258203b40265111d8bb3c3c608d95b3a0bf83461ace3207018282581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c19012182581d61bcd18fcffa797c16c007014e2b8553b8b9b1e94c507688726243d6111a3420989c021a0002ccce031903e7a10082825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee58401ec3e56008650282ba2e1f8a20e81707810b2d0973c4d42a1b4df65b732bda81567c7824904840b2554d2f33861da5d70588a29d33b2b61042e3c3445301d8008258206872b0a874acfe1cace12b20ea348559a7ecc912f2fc7f674f43481df973d92c5840a0718fb5b37d89ddf926c08e456d3f4c7f749e91f78bb3e370751d5b632cbd20d38d385805291b1ef2541b02543728a235e01911f4b400bfb50e5fce589de907f6"
201+
"84a400828258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7182a82582082839f8200d81858248258203b40265111d8bb3c3c608d95b3a0bf83461ace3207018282581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c19012182581d61bcd18fcffa797c16c007014e2b8553b8b9b1e94c507688726243d6111a3420989c021a0002ccce031903e7a10082825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee58401ec3e56008650282ba2e1f8a20e81707810b2d0973c4d42a1b4df65b732bda81567c7824904840b2554d2f33861da5d70588a29d33b2b61042e3c3445301d8008258206872b0a874acfe1cace12b20ea348559a7ecc912f2fc7f674f43481df973d92c5840a0718fb5b37d89ddf926c08e456d3f4c7f749e91f78bb3e370751d5b632cbd20d38d385805291b1ef2541b02543728a235e01911f4b400bfb50e5fce589de907f5f6"
202202
);
203203
assert_eq!(
204204
min_fee(&signed_tx, &linear_fee).unwrap().to_str(),
205-
"183502" // todo: compare to Haskell fee to make sure the diff is not too big
205+
"184002" // todo: compare to Haskell fee to make sure the diff is not too big
206206
);
207207
}
208208

@@ -294,11 +294,11 @@ mod tests {
294294
let linear_fee = LinearFee::new(&to_bignum(500), &to_bignum(2));
295295
assert_eq!(
296296
hex::encode(signed_tx.to_bytes()),
297-
"83a500818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a00040f12030a04818a03581c1c13374874c68016df54b1339b6cacdd801098431e7659b24928efc15820bd0000f498ccacdc917c28274cba51c415f3f21931ff41ca8dc1197499f8e1241a000f42401a000f4240d81e82031864581de151df9ba1b74a1c9608a487e114184556801e927d31d96425cb80af7081581c51df9ba1b74a1c9608a487e114184556801e927d31d96425cb80af7080f6a10083825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee5840a7f305d7e46abfe0f7bea6098bdf853ab9ce8e7aa381be5a991a871852f895a718e20614e22be43494c4dc3a8c78c56cd44fd38e0e5fff3e2fbd19f70402fc02825820b24c040e65994bd5b0621a060166d32d356ef4be3cc1f848426a4cf386887089584013c372f82f1523484eab273241d66d92e1402507760e279480912aa5f0d88d656d6f25d41e65257f2f38c65ac5c918a6735297741adfc718394994f20a1cfd0082582054d1a9c5ad69586ceeb839c438400c376c0bd34825fb4c17cc2f58c54e1437f35840d326b993dfec21b9b3e1bd2f80adadc2cd673a1d8d033618cc413b0b02bc3b7efbb23d1ff99138abd05c398ce98e7983a641b50dcf0f64ed33f26c6e636b0b0ff6"
297+
"84a500818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a00040f12030a04818a03581c1c13374874c68016df54b1339b6cacdd801098431e7659b24928efc15820bd0000f498ccacdc917c28274cba51c415f3f21931ff41ca8dc1197499f8e1241a000f42401a000f4240d81e82031864581de151df9ba1b74a1c9608a487e114184556801e927d31d96425cb80af7081581c51df9ba1b74a1c9608a487e114184556801e927d31d96425cb80af7080f6a10083825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee5840a7f305d7e46abfe0f7bea6098bdf853ab9ce8e7aa381be5a991a871852f895a718e20614e22be43494c4dc3a8c78c56cd44fd38e0e5fff3e2fbd19f70402fc02825820b24c040e65994bd5b0621a060166d32d356ef4be3cc1f848426a4cf386887089584013c372f82f1523484eab273241d66d92e1402507760e279480912aa5f0d88d656d6f25d41e65257f2f38c65ac5c918a6735297741adfc718394994f20a1cfd0082582054d1a9c5ad69586ceeb839c438400c376c0bd34825fb4c17cc2f58c54e1437f35840d326b993dfec21b9b3e1bd2f80adadc2cd673a1d8d033618cc413b0b02bc3b7efbb23d1ff99138abd05c398ce98e7983a641b50dcf0f64ed33f26c6e636b0b0ff5f6"
298298
);
299299
assert_eq!(
300300
min_fee(&signed_tx, &linear_fee).unwrap().to_str(),
301-
"269002" // todo: compare to Haskell fee to make sure the diff is not too big
301+
"269502" // todo: compare to Haskell fee to make sure the diff is not too big
302302
);
303303
}
304304

@@ -488,11 +488,11 @@ mod tests {
488488
let linear_fee = LinearFee::new(&to_bignum(500), &to_bignum(2));
489489
assert_eq!(
490490
hex::encode(signed_tx.to_bytes()),
491-
"83a500818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a00027ac6030a05a1581de151df9ba1b74a1c9608a487e114184556801e927d31d96425cb80af70190539a10082825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee5840fc0493f7121efe385d72830680e735ccdef99c3a31953fe877b89ad3a97fcdb871cc7f2cdd6a8104e52f6963bd9e10d814d4fabdbcdc8475bc63e872dcc94d0a82582054d1a9c5ad69586ceeb839c438400c376c0bd34825fb4c17cc2f58c54e1437f35840a051ba927582004aedab736b9f1f9330ff867c260f4751135d480074256e83cd23d2a4bb109f955c43afdcdc5d1841b28d5c1ea2148dfbb6252693590692bb00f6"
491+
"84a500818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d611c616f1acb460668a9b2f123c80372c2adad3583b9c6cd2b1deeed1c01021a00027ac6030a05a1581de151df9ba1b74a1c9608a487e114184556801e927d31d96425cb80af70190539a10082825820f9aa3fccb7fe539e471188ccc9ee65514c5961c070b06ca185962484a4813bee5840fc0493f7121efe385d72830680e735ccdef99c3a31953fe877b89ad3a97fcdb871cc7f2cdd6a8104e52f6963bd9e10d814d4fabdbcdc8475bc63e872dcc94d0a82582054d1a9c5ad69586ceeb839c438400c376c0bd34825fb4c17cc2f58c54e1437f35840a051ba927582004aedab736b9f1f9330ff867c260f4751135d480074256e83cd23d2a4bb109f955c43afdcdc5d1841b28d5c1ea2148dfbb6252693590692bb00f5f6"
492492
);
493493
assert_eq!(
494494
min_fee(&signed_tx, &linear_fee).unwrap().to_str(),
495-
"162502" // todo: compare to Haskell fee to make sure the diff is not too big
495+
"163002" // todo: compare to Haskell fee to make sure the diff is not too big
496496
);
497497
}
498498
}

rust/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ type Slot = u32;
9898
pub struct Transaction {
9999
body: TransactionBody,
100100
witness_set: TransactionWitnessSet,
101+
is_valid: bool,
101102
auxiliary_data: Option<AuxiliaryData>,
102103
}
103104

@@ -113,10 +114,18 @@ impl Transaction {
113114
self.witness_set.clone()
114115
}
115116

117+
pub fn is_valid(&self) -> bool {
118+
self.is_valid.clone()
119+
}
120+
116121
pub fn auxiliary_data(&self) -> Option<AuxiliaryData> {
117122
self.auxiliary_data.clone()
118123
}
119124

125+
pub fn set_is_valid(&mut self, valid: bool) {
126+
self.is_valid = valid
127+
}
128+
120129
pub fn new(
121130
body: &TransactionBody,
122131
witness_set: &TransactionWitnessSet,
@@ -125,6 +134,7 @@ impl Transaction {
125134
Self {
126135
body: body.clone(),
127136
witness_set: witness_set.clone(),
137+
is_valid: true,
128138
auxiliary_data: auxiliary_data.clone(),
129139
}
130140
}

rust/src/serialization.rs

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,10 @@ impl DeserializeEmbeddedGroup for UnitInterval {
5656

5757
impl cbor_event::se::Serialize for Transaction {
5858
fn serialize<'se, W: Write>(&self, serializer: &'se mut Serializer<W>) -> cbor_event::Result<&'se mut Serializer<W>> {
59-
serializer.write_array(cbor_event::Len::Len(3))?;
59+
serializer.write_array(cbor_event::Len::Len(4))?;
6060
self.body.serialize(serializer)?;
6161
self.witness_set.serialize(serializer)?;
62+
serializer.write_special(CBORSpecial::Bool(self.is_valid))?;
6263
match &self.auxiliary_data {
6364
Some(x) => {
6465
x.serialize(serializer)
@@ -94,22 +95,52 @@ impl DeserializeEmbeddedGroup for Transaction {
9495
let witness_set = (|| -> Result<_, DeserializeError> {
9596
Ok(TransactionWitnessSet::deserialize(raw)?)
9697
})().map_err(|e| e.annotate("witness_set"))?;
97-
let auxiliary_data = (|| -> Result<_, DeserializeError> {
98-
Ok(match raw.cbor_type()? != CBORType::Special {
98+
let mut checked_auxiliary_data = false;
99+
let mut auxiliary_data = None;
100+
let is_valid = (|| -> Result<_, DeserializeError> {
101+
match raw.cbor_type()? == CBORType::Special {
99102
true => {
100-
Some(AuxiliaryData::deserialize(raw)?)
103+
// if it's special it can be either a bool or null. if it's null, then it's empty auxiliary data, otherwise not a valid encoding
104+
let special = raw.special()?;
105+
if let CBORSpecial::Bool(b) = special {
106+
return Ok(b);
107+
} else if special == CBORSpecial::Null {
108+
checked_auxiliary_data = true;
109+
return Ok(true);
110+
} else {
111+
return Err(DeserializeFailure::ExpectedBool.into());
112+
}
101113
},
102114
false => {
103-
if raw.special()? != CBORSpecial::Null {
104-
return Err(DeserializeFailure::ExpectedNull.into());
105-
}
106-
None
115+
// if no special symbol was detected, it must have auxiliary data
116+
auxiliary_data = (|| -> Result<_, DeserializeError> {
117+
Ok(Some(AuxiliaryData::deserialize(raw)?))
118+
})().map_err(|e| e.annotate("auxiliary_data"))?;
119+
checked_auxiliary_data = true;
120+
return Ok(true);
107121
}
108-
})
109-
})().map_err(|e| e.annotate("auxiliary_data"))?;
122+
}
123+
})().map_err(|e| e.annotate("is_valid"))?;
124+
if (!checked_auxiliary_data) {
125+
// this branch is reached, if the 3rd argument was a bool. then it simply follows the rules for checking auxiliary data
126+
auxiliary_data = (|| -> Result<_, DeserializeError> {
127+
Ok(match raw.cbor_type()? != CBORType::Special {
128+
true => {
129+
Some(AuxiliaryData::deserialize(raw)?)
130+
},
131+
false => {
132+
if raw.special()? != CBORSpecial::Null {
133+
return Err(DeserializeFailure::ExpectedNull.into());
134+
}
135+
None
136+
}
137+
})
138+
})().map_err(|e| e.annotate("auxiliary_data"))?;
139+
}
110140
Ok(Transaction {
111141
body,
112142
witness_set,
143+
is_valid,
113144
auxiliary_data,
114145
})
115146
}

rust/src/tx_builder.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ fn fake_full_tx(tx_builder: &TransactionBuilder, body: TransactionBody) -> Resul
9696
Ok(Transaction {
9797
body,
9898
witness_set,
99+
is_valid: true,
99100
auxiliary_data: tx_builder.auxiliary_data.clone(),
100101
})
101102
}
@@ -662,7 +663,7 @@ mod tests {
662663
tx_builder.get_explicit_input().unwrap().checked_add(&tx_builder.get_implicit_input().unwrap()).unwrap(),
663664
tx_builder.get_explicit_output().unwrap().checked_add(&Value::new(&tx_builder.get_fee_if_set().unwrap())).unwrap()
664665
);
665-
assert_eq!(tx_builder.full_size().unwrap(), 283);
666+
assert_eq!(tx_builder.full_size().unwrap(), 284);
666667
assert_eq!(tx_builder.output_sizes(), vec![61, 65]);
667668
let _final_tx = tx_builder.build(); // just test that it doesn't throw
668669
}
@@ -782,8 +783,8 @@ mod tests {
782783
tx_builder.add_change_if_needed(
783784
&change_addr
784785
).unwrap();
785-
assert_eq!(tx_builder.min_fee().unwrap().to_str(), "213502");
786-
assert_eq!(tx_builder.get_fee_if_set().unwrap().to_str(), "213502");
786+
assert_eq!(tx_builder.min_fee().unwrap().to_str(), "214002");
787+
assert_eq!(tx_builder.get_fee_if_set().unwrap().to_str(), "214002");
787788
assert_eq!(tx_builder.get_deposit().unwrap().to_str(), "1000000");
788789
assert_eq!(tx_builder.outputs.len(), 1);
789790
assert_eq!(

0 commit comments

Comments
 (0)