Skip to content

Commit ce3b047

Browse files
authored
Merge pull request #2083 from mintlayer/fix_spurious_test_failures_due_to_zero_token_transfers
Fix spurious test failures due to accidental zero token transfers
2 parents 6a68141 + 7227704 commit ce3b047

4 files changed

Lines changed: 147 additions & 82 deletions

File tree

chainstate/test-framework/src/helpers.rs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -297,17 +297,16 @@ pub fn calculate_fill_order(
297297
.unwrap()
298298
}
299299

300-
pub fn order_min_non_zero_fill_amount(
300+
/// For orders v1, return the minimal fill amount that would result in a non-zero filled amount.
301+
/// For orders v0 return 1.
302+
pub fn order_min_accepted_non_zero_fill_amount(
301303
tf: &TestFramework,
302304
order_id: &OrderId,
303305
orders_version: OrdersVersion,
304306
) -> Amount {
305307
match orders_version {
306-
// Note: in orders v0 even direct zero fills are allowed.
307-
// However, this function is supposed to only return non-zero amounts.
308308
OrdersVersion::V0 => Amount::from_atoms(1),
309309

310-
// In orders v1, the fill amount must be big enough so that the filled amount is non-zero.
311310
OrdersVersion::V1 => {
312311
let db_tx = tf.storage.transaction_ro().unwrap();
313312
let orders_db = OrdersAccountingDB::new(&db_tx);
@@ -321,6 +320,35 @@ pub fn order_min_non_zero_fill_amount(
321320
}
322321
}
323322

323+
/// Return the minimal fill amount that would result in a non-zero filled amount.
324+
/// Note: since orders v0 use the current balance for the filled amount calculation, this function
325+
/// should only be used to generate the first fill of the v0 order in the block under construction.
326+
pub fn order_min_amount_for_non_zero_fill(
327+
tf: &TestFramework,
328+
order_id: &OrderId,
329+
orders_version: OrdersVersion,
330+
) -> Amount {
331+
let db_tx = tf.storage.transaction_ro().unwrap();
332+
let orders_db = OrdersAccountingDB::new(&db_tx);
333+
334+
match orders_version {
335+
OrdersVersion::V0 => {
336+
let ask_balance = orders_db.get_ask_balance(order_id).unwrap().into_atoms();
337+
let give_balance = orders_db.get_give_balance(order_id).unwrap().into_atoms();
338+
339+
Amount::from_atoms(ask_balance.div_ceil(give_balance))
340+
}
341+
342+
OrdersVersion::V1 => {
343+
let order_data = orders_db.get_order_data(order_id).unwrap().unwrap();
344+
let original_ask = order_data.ask().amount().into_atoms();
345+
let original_give = order_data.give().amount().into_atoms();
346+
347+
Amount::from_atoms(original_ask.div_ceil(original_give))
348+
}
349+
}
350+
}
351+
324352
/// Split an u128 value into the specified number of "randomish" parts (the min part size is half
325353
/// the average part size).
326354
pub fn split_u128(rng: &mut impl CryptoRng, amount: u128, parts_count: usize) -> Vec<u128> {

chainstate/test-suite/src/tests/input_commitments.rs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -389,17 +389,14 @@ fn order_fill(#[case] seed: Seed, #[case] orders_version: OrdersVersion) {
389389
let order_fill_tx = TransactionBuilder::new()
390390
.add_input(coins_outpoint.into(), InputWitness::NoSignature(None))
391391
.add_input(fill_order_input, InputWitness::NoSignature(None))
392-
.add_output(TxOutput::Transfer(
393-
OutputValue::TokenV1(token_id, filled_amount),
394-
Destination::AnyoneCanSpend,
395-
))
396392
.add_output(TxOutput::Transfer(
397393
OutputValue::Coin(coins_left),
398394
coins_owner_dest.clone(),
399395
))
396+
.add_token_transfer_output_if_non_zero(token_id, filled_amount, Destination::AnyoneCanSpend)
400397
.build();
401398
let order_fill_tx_id = order_fill_tx.transaction().get_id();
402-
let coins_outpoint = UtxoOutPoint::new(order_fill_tx_id.into(), 1);
399+
let coins_outpoint = UtxoOutPoint::new(order_fill_tx_id.into(), 0);
403400

404401
tf.make_block_builder()
405402
.add_transaction(order_fill_tx)
@@ -418,15 +415,19 @@ fn order_fill(#[case] seed: Seed, #[case] orders_version: OrdersVersion) {
418415
let fill_order_input =
419416
make_fill_order_input(orders_version, AccountNonce::new(1), &order_id, fill_amount);
420417

421-
let tx = Transaction::new(
422-
0,
423-
vec![coins_outpoint.clone().into(), fill_order_input],
424-
vec![TxOutput::Transfer(
425-
OutputValue::TokenV1(token_id, filled_amount),
418+
let tx = TransactionBuilder::new()
419+
.add_input(
420+
coins_outpoint.clone().into(),
421+
InputWitness::NoSignature(None),
422+
)
423+
.add_input(fill_order_input, InputWitness::NoSignature(None))
424+
.add_token_transfer_output_if_non_zero(
425+
token_id,
426+
filled_amount,
426427
Destination::AnyoneCanSpend,
427-
)],
428-
)
429-
.unwrap();
428+
)
429+
.build()
430+
.take_transaction();
430431

431432
let coins_utxo = tf.utxo(&coins_outpoint).take_output();
432433
let bad_coins_utxo = {
@@ -676,14 +677,11 @@ fn order_conclude(#[case] seed: Seed, #[case] orders_version: OrdersVersion) {
676677
let order_fill_tx = TransactionBuilder::new()
677678
.add_input(coins_outpoint.into(), InputWitness::NoSignature(None))
678679
.add_input(fill_order_input, InputWitness::NoSignature(None))
679-
.add_output(TxOutput::Transfer(
680-
OutputValue::TokenV1(token_id, filled_amount),
681-
Destination::AnyoneCanSpend,
682-
))
683680
.add_output(TxOutput::Transfer(
684681
OutputValue::Coin(coins_left),
685682
Destination::AnyoneCanSpend,
686683
))
684+
.add_token_transfer_output_if_non_zero(token_id, filled_amount, Destination::AnyoneCanSpend)
687685
.build();
688686

689687
tf.make_block_builder()

0 commit comments

Comments
 (0)