Skip to content

Commit fdb4a0e

Browse files
authored
Merge pull request #190 from Emurgo/fix-checked-sub
Exclude empty multiasset struct when subtracting values
2 parents 0c40765 + ad7e81f commit fdb4a0e

File tree

2 files changed

+69
-2
lines changed

2 files changed

+69
-2
lines changed

rust/src/tx_builder.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,4 +1188,65 @@ mod tests {
11881188
);
11891189
let _final_tx = tx_builder.build(); // just test that it doesn't throw
11901190
}
1191+
1192+
#[test]
1193+
fn build_tx_no_useless_multiasset() {
1194+
let linear_fee = LinearFee::new(&to_bignum(44), &to_bignum(155381));
1195+
let mut tx_builder =
1196+
TransactionBuilder::new(&linear_fee, &to_bignum(1000000), &to_bignum(500000000), &to_bignum(2000000));
1197+
1198+
let policy_id = &PolicyID::from([0u8; 28]);
1199+
let name = AssetName::new(vec![0u8, 1, 2, 3]).unwrap();
1200+
1201+
// add an output that uses up all the token but leaves ADA
1202+
let mut input_amount = Value::new(&to_bignum(5_000_000));
1203+
let mut input_multiasset = MultiAsset::new();
1204+
input_multiasset.insert(policy_id, &{
1205+
let mut assets = Assets::new();
1206+
assets.insert(&name, &to_bignum(100));
1207+
assets
1208+
});
1209+
input_amount.set_multiasset(&input_multiasset);
1210+
1211+
tx_builder.add_input(
1212+
&ByronAddress::from_base58("Ae2tdPwUPEZ5uzkzh1o2DHECiUi3iugvnnKHRisPgRRP3CTF4KCMvy54Xd3").unwrap().to_address(),
1213+
&TransactionInput::new(
1214+
&genesis_id(),
1215+
0
1216+
),
1217+
&input_amount
1218+
);
1219+
1220+
// add an input that contains an asset & ADA
1221+
let mut output_amount = Value::new(&to_bignum(2_000_000));
1222+
let mut output_multiasset = MultiAsset::new();
1223+
output_multiasset.insert(policy_id, &{
1224+
let mut assets = Assets::new();
1225+
assets.insert(&name, &to_bignum(100));
1226+
assets
1227+
});
1228+
output_amount.set_multiasset(&output_multiasset);
1229+
1230+
let output_addr = ByronAddress::from_base58("Ae2tdPwUPEZD9QQf2ZrcYV34pYJwxK4vqXaF8EXkup1eYH73zUScHReM42b").unwrap();
1231+
tx_builder.add_output(&TransactionOutput::new(
1232+
&output_addr.to_address(),
1233+
&output_amount
1234+
)).unwrap();
1235+
1236+
tx_builder.set_ttl(1);
1237+
1238+
let change_addr = ByronAddress::from_base58("Ae2tdPwUPEZGUEsuMAhvDcy94LKsZxDjCbgaiBBMgYpR8sKf96xJmit7Eho").unwrap();
1239+
let added_change = tx_builder.add_change_if_needed(
1240+
&change_addr.to_address()
1241+
);
1242+
assert!(added_change.unwrap());
1243+
assert_eq!(tx_builder.outputs.len(), 2);
1244+
let final_tx = tx_builder.build().unwrap();
1245+
let change_output = final_tx.outputs().get(1);
1246+
let change_assets = change_output.amount().multiasset();
1247+
1248+
// since all tokens got sent in the output
1249+
// the change should be only ADA and not have any multiasset struct in it
1250+
assert!(change_assets.is_none());
1251+
}
11911252
}

rust/src/utils.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,10 @@ impl Value {
303303
let coin = self.coin.checked_sub(&rhs_value.coin)?;
304304
let multiasset = match(&self.multiasset, &rhs_value.multiasset) {
305305
(Some(lhs_ma), Some(rhs_ma)) => {
306-
Some(lhs_ma.sub(rhs_ma))
306+
match (lhs_ma.sub(rhs_ma).len()) {
307+
0 => None,
308+
_ => Some(lhs_ma.sub(rhs_ma))
309+
}
307310
},
308311
(Some(lhs_ma), None) => Some(lhs_ma.clone()),
309312
(None, Some(_rhs_ma)) => None,
@@ -317,7 +320,10 @@ impl Value {
317320
let coin = self.coin.clamped_sub(&rhs_value.coin);
318321
let multiasset = match(&self.multiasset, &rhs_value.multiasset) {
319322
(Some(lhs_ma), Some(rhs_ma)) => {
320-
Some(lhs_ma.sub(rhs_ma))
323+
match (lhs_ma.sub(rhs_ma).len()) {
324+
0 => None,
325+
_ => Some(lhs_ma.sub(rhs_ma))
326+
}
321327
},
322328
(Some(lhs_ma), None) => Some(lhs_ma.clone()),
323329
(None, Some(_rhs_ma)) => None,

0 commit comments

Comments
 (0)