Skip to content

Commit bd3165f

Browse files
authored
Merge pull request #1313 from mintlayer/fix/issuance_and_supply_change_fee
Temp fix for issuance and supply change fee in the same tx
2 parents 81b4285 + b29a9eb commit bd3165f

File tree

12 files changed

+671
-507
lines changed

12 files changed

+671
-507
lines changed

chainstate/src/detail/ban_score.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ impl BanScore for ConnectTransactionError {
150150
ConnectTransactionError::TokensAccountingError(err) => err.ban_score(),
151151
ConnectTransactionError::TokensAccountingBlockUndoError(_) => 100,
152152
ConnectTransactionError::TotalFeeRequiredOverflow => 100,
153+
ConnectTransactionError::InsufficientCoinsFee(_, _) => 100,
153154
}
154155
}
155156
}
@@ -249,7 +250,7 @@ impl BanScore for TokensError {
249250
TokensError::IssueError(_, _, _) => 100,
250251
TokensError::MultipleTokenIssuanceInTransaction(_, _) => 100,
251252
TokensError::CoinOrTokenOverflow => 100,
252-
TokensError::InsufficientTokenFees(_, _) => 100,
253+
TokensError::InsufficientTokenFees(_) => 100,
253254
TokensError::TransferZeroTokens(_, _) => 100,
254255
TokensError::TokenIdCantBeCalculated => 100,
255256
TokensError::TokensInBlockReward => 100,

chainstate/test-framework/src/random_tx_maker.rs

+8-18
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,6 @@ impl<'a> RandomTxMaker<'a> {
169169
let mut result_inputs = Vec::new();
170170
let mut result_outputs = Vec::new();
171171

172-
let min_tx_fee = self.chainstate.get_chain_config().token_min_supply_change_fee();
173-
174172
for (i, token_id) in inputs.iter().copied().enumerate() {
175173
if rng.gen_bool(0.9) {
176174
let circulating_supply =
@@ -199,13 +197,10 @@ impl<'a> RandomTxMaker<'a> {
199197
));
200198
result_inputs.extend(vec![account_input, fee_inputs[i].clone()]);
201199

202-
let outputs = vec![
203-
TxOutput::Transfer(
204-
OutputValue::TokenV1(token_id, to_mint),
205-
Destination::AnyoneCanSpend,
206-
),
207-
TxOutput::Burn(OutputValue::Coin(min_tx_fee)),
208-
];
200+
let outputs = vec![TxOutput::Transfer(
201+
OutputValue::TokenV1(token_id, to_mint),
202+
Destination::AnyoneCanSpend,
203+
)];
209204
result_outputs.extend(outputs);
210205

211206
let _ = tokens_cache.mint_tokens(token_id, to_mint).unwrap();
@@ -224,7 +219,8 @@ impl<'a> RandomTxMaker<'a> {
224219
));
225220
result_inputs.extend(vec![account_input, fee_inputs[i].clone()]);
226221

227-
let outputs = vec![TxOutput::Burn(OutputValue::Coin(min_tx_fee))];
222+
// fake output to avoid empty outputs error
223+
let outputs = vec![TxOutput::Burn(OutputValue::Coin(Amount::ZERO))];
228224
result_outputs.extend(outputs);
229225

230226
let _ = tokens_cache.lock_circulating_supply(token_id).unwrap();
@@ -314,7 +310,6 @@ impl<'a> RandomTxMaker<'a> {
314310
random_token_issuance_v1(self.chainstate.get_chain_config(), rng),
315311
))),
316312
TxOutput::Transfer(OutputValue::Coin(change), Destination::AnyoneCanSpend),
317-
TxOutput::Burn(OutputValue::Coin(min_tx_fee)),
318313
]
319314
} else {
320315
Vec::new()
@@ -337,7 +332,6 @@ impl<'a> RandomTxMaker<'a> {
337332
Destination::AnyoneCanSpend,
338333
),
339334
TxOutput::Transfer(OutputValue::Coin(change), Destination::AnyoneCanSpend),
340-
TxOutput::Burn(OutputValue::Coin(min_tx_fee)),
341335
]
342336
} else {
343337
Vec::new()
@@ -403,12 +397,8 @@ impl<'a> RandomTxMaker<'a> {
403397
));
404398
result_inputs.extend(vec![account_input, fee_tx_input.clone()]);
405399

406-
let min_tx_fee =
407-
self.chainstate.get_chain_config().token_min_supply_change_fee();
408-
let outputs = vec![
409-
TxOutput::Burn(OutputValue::TokenV1(token_id, to_unmint)),
410-
TxOutput::Burn(OutputValue::Coin(min_tx_fee)),
411-
];
400+
let outputs =
401+
vec![TxOutput::Burn(OutputValue::TokenV1(token_id, to_unmint))];
412402
result_outputs.extend(outputs);
413403
}
414404
*fee_input = None;

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

+4-6
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@
1414
// limitations under the License.
1515

1616
use chainstate::ConnectTransactionError;
17-
use chainstate::{
18-
BlockError, ChainstateError, CheckBlockError, CheckBlockTransactionsError, IOPolicyError,
19-
};
17+
use chainstate::{BlockError, ChainstateError, CheckBlockError, CheckBlockTransactionsError};
2018
use chainstate_test_framework::{TestFramework, TransactionBuilder};
2119
use common::chain::{
2220
signature::inputsig::InputWitness, tokens::TokenIssuanceVersion, ChainstateUpgrade,
@@ -240,9 +238,9 @@ fn data_deposit_insufficient_fee(#[case] seed: Seed, #[case] expect_success: boo
240238
let result = tf.process_block(block.clone(), chainstate::BlockSource::Local);
241239

242240
let expected_err = Err(ChainstateError::ProcessBlockError(
243-
BlockError::StateUpdateFailed(ConnectTransactionError::IOPolicyError(
244-
IOPolicyError::AttemptToPrintMoneyOrViolateTimelockConstraints,
245-
OutPointSourceId::Transaction(tx.transaction().get_id()),
241+
BlockError::StateUpdateFailed(ConnectTransactionError::InsufficientCoinsFee(
242+
data_fee,
243+
tf.chain_config().data_deposit_min_fee(),
246244
)),
247245
));
248246

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

+24-26
Original file line numberDiff line numberDiff line change
@@ -693,41 +693,39 @@ fn token_issuance_with_insufficient_fee(#[case] seed: Seed) {
693693
number_of_decimals: rng.gen_range(1..18),
694694
metadata_uri: random_ascii_alphanumeric_string(&mut rng, 1..1024).as_bytes().to_vec(),
695695
};
696+
let tx = TransactionBuilder::new()
697+
.add_input(
698+
TxInput::from_utxo(genesis_outpoint_id, 0),
699+
InputWitness::NoSignature(None),
700+
)
701+
.add_output(TxOutput::Transfer(
702+
issuance_data.clone().into(),
703+
Destination::AnyoneCanSpend,
704+
))
705+
.add_output(TxOutput::Transfer(
706+
OutputValue::Coin(coins_value),
707+
Destination::AnyoneCanSpend,
708+
))
709+
.add_output(TxOutput::Burn(OutputValue::Coin(
710+
(token_min_issuance_fee - Amount::from_atoms(1)).unwrap(),
711+
)))
712+
.build();
713+
let tx_id = tx.transaction().get_id();
696714
let block = tf
697715
.make_block_builder()
698716
// All coins in inputs added to outputs, fee = 0 coins
699-
.add_transaction(
700-
TransactionBuilder::new()
701-
.add_input(
702-
TxInput::from_utxo(genesis_outpoint_id, 0),
703-
InputWitness::NoSignature(None),
704-
)
705-
.add_output(TxOutput::Transfer(
706-
issuance_data.clone().into(),
707-
Destination::AnyoneCanSpend,
708-
))
709-
.add_output(TxOutput::Transfer(
710-
OutputValue::Coin(coins_value),
711-
Destination::AnyoneCanSpend,
712-
))
713-
.add_output(TxOutput::Burn(OutputValue::Coin(
714-
(token_min_issuance_fee - Amount::from_atoms(1)).unwrap(),
715-
)))
716-
.build(),
717-
)
717+
.add_transaction(tx)
718718
.build();
719719

720720
let result = tf.process_block(block, BlockSource::Local);
721721

722722
// Try to process tx with insufficient token fees
723-
assert!(matches!(
724-
result,
725-
Err(ChainstateError::ProcessBlockError(
726-
BlockError::StateUpdateFailed(ConnectTransactionError::TokensError(
727-
TokensError::InsufficientTokenFees(_, _)
728-
))
723+
assert_eq!(
724+
result.unwrap_err(),
725+
ChainstateError::ProcessBlockError(BlockError::StateUpdateFailed(
726+
ConnectTransactionError::TokensError(TokensError::InsufficientTokenFees(tx_id))
729727
))
730-
));
728+
);
731729

732730
// Valid issuance
733731
let genesis_outpoint_id = tf.genesis().get_id().into();

0 commit comments

Comments
 (0)