Skip to content

Commit f99ef5f

Browse files
authored
Merge pull request #2035 from mintlayer/minor_p2p_improvement_and_extra_tests
Minor p2p improvement and extra tests
2 parents 22561ab + 790abdc commit f99ef5f

File tree

4 files changed

+602
-53
lines changed

4 files changed

+602
-53
lines changed

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

Lines changed: 253 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,9 +1350,9 @@ fn mint_unlimited_supply(#[case] seed: Seed) {
13501350
});
13511351
}
13521352

1353-
// Issue and mint maximum possible tokens for Unlimited supply.
1354-
// Try to mint 1 more and check an error.
1355-
// Try to mint random number and check an error.
1353+
// Issue and mint maximum possible tokens (i128::MAX) for Unlimited supply.
1354+
// Try to mint 1 more and expect an error.
1355+
// Try to mint random number and expect an error.
13561356
#[rstest]
13571357
#[trace]
13581358
#[case(Seed::from_entropy())]
@@ -1373,8 +1373,8 @@ fn mint_unlimited_supply_max(#[case] seed: Seed) {
13731373
IsTokenFreezable::No,
13741374
);
13751375

1376-
// Mint tokens i128::MAX
1377-
let mint_tx = TransactionBuilder::new()
1376+
// Mint i128::MAX atoms
1377+
let initial_mint_tx = TransactionBuilder::new()
13781378
.add_input(
13791379
TxInput::from_command(
13801380
AccountNonce::new(0),
@@ -1395,9 +1395,9 @@ fn mint_unlimited_supply_max(#[case] seed: Seed) {
13951395
Destination::AnyoneCanSpend,
13961396
))
13971397
.build();
1398-
let mint_tx_id = mint_tx.transaction().get_id();
1398+
let initial_mint_tx_id = initial_mint_tx.transaction().get_id();
13991399
tf.make_block_builder()
1400-
.add_transaction(mint_tx)
1400+
.add_transaction(initial_mint_tx)
14011401
.build_and_process(&mut rng)
14021402
.unwrap();
14031403

@@ -1416,25 +1416,29 @@ fn mint_unlimited_supply_max(#[case] seed: Seed) {
14161416
true,
14171417
);
14181418

1419-
{
1420-
// Try mint one more over i128::MAX
1421-
let mint_tx = TransactionBuilder::new()
1419+
let make_mint_tx = |amount| {
1420+
TransactionBuilder::new()
14221421
.add_input(
14231422
TxInput::from_command(
14241423
AccountNonce::new(1),
1425-
AccountCommand::MintTokens(token_id, Amount::from_atoms(1)),
1424+
AccountCommand::MintTokens(token_id, amount),
14261425
),
14271426
InputWitness::NoSignature(None),
14281427
)
14291428
.add_input(
1430-
TxInput::from_utxo(mint_tx_id.into(), 0),
1429+
TxInput::from_utxo(initial_mint_tx_id.into(), 0),
14311430
InputWitness::NoSignature(None),
14321431
)
14331432
.add_output(TxOutput::Transfer(
1434-
OutputValue::TokenV1(token_id, Amount::from_atoms(1)),
1433+
OutputValue::TokenV1(token_id, amount),
14351434
Destination::AnyoneCanSpend,
14361435
))
1437-
.build();
1436+
.build()
1437+
};
1438+
1439+
{
1440+
// Try minting one more atom.
1441+
let mint_tx = make_mint_tx(Amount::from_atoms(1));
14381442
let mint_tx_id = mint_tx.transaction().get_id();
14391443
let result =
14401444
tf.make_block_builder().add_transaction(mint_tx).build_and_process(&mut rng);
@@ -1454,41 +1458,256 @@ fn mint_unlimited_supply_max(#[case] seed: Seed) {
14541458
);
14551459
}
14561460

1457-
// Try mint random number over i128::MAX
1458-
let random_amount = Amount::from_atoms(rng.gen_range(0..i128::MAX as u128));
1459-
let mint_tx = TransactionBuilder::new()
1461+
{
1462+
// Try minting a random number of atoms
1463+
let amount = Amount::from_atoms(rng.gen_range(1..=i128::MAX as u128));
1464+
let mint_tx = make_mint_tx(amount);
1465+
let mint_tx_id = mint_tx.transaction().get_id();
1466+
let result =
1467+
tf.make_block_builder().add_transaction(mint_tx).build_and_process(&mut rng);
1468+
1469+
assert_eq!(
1470+
result.unwrap_err(),
1471+
ChainstateError::ProcessBlockError(BlockError::StateUpdateFailed(
1472+
ConnectTransactionError::ConstrainedValueAccumulatorError(
1473+
constraints_value_accumulator::Error::TokensAccountingError(
1474+
tokens_accounting::Error::AccountingError(
1475+
accounting::Error::ArithmeticErrorDeltaAdditionFailed
1476+
)
1477+
),
1478+
mint_tx_id.into()
1479+
)
1480+
))
1481+
);
1482+
}
1483+
1484+
{
1485+
// For completeness, try minting a random number of atoms bigger than i128::MAX.
1486+
// A different error will be generated.
1487+
let amount = Amount::from_atoms(rng.gen_range((i128::MAX as u128) + 1..=u128::MAX));
1488+
let mint_tx = make_mint_tx(amount);
1489+
let mint_tx_id = mint_tx.transaction().get_id();
1490+
let result =
1491+
tf.make_block_builder().add_transaction(mint_tx).build_and_process(&mut rng);
1492+
1493+
assert_eq!(
1494+
result.unwrap_err(),
1495+
ChainstateError::ProcessBlockError(BlockError::StateUpdateFailed(
1496+
ConnectTransactionError::ConstrainedValueAccumulatorError(
1497+
constraints_value_accumulator::Error::TokensAccountingError(
1498+
tokens_accounting::Error::AccountingError(
1499+
accounting::Error::ArithmeticErrorToSignedFailed
1500+
)
1501+
),
1502+
mint_tx_id.into()
1503+
)
1504+
))
1505+
);
1506+
}
1507+
});
1508+
}
1509+
1510+
// Same as mint_unlimited_supply_max, but use TokenTotalSupply::Fixed with an amount bigger than i128::MAX.
1511+
// 1) mint maximum possible tokens (i128::MAX);
1512+
// 2) try minting 1 more and expect an error;
1513+
// 3) try minting a random amount and expect an error.
1514+
#[rstest]
1515+
#[trace]
1516+
#[case(Seed::from_entropy())]
1517+
fn mint_pseudo_unlimited_supply_max(#[case] seed: Seed) {
1518+
utils::concurrency::model(move || {
1519+
let mut rng = make_seedable_rng(seed);
1520+
let mut tf = TestFramework::builder(&mut rng).build();
1521+
1522+
let token_supply_change_fee =
1523+
tf.chainstate.get_chain_config().token_supply_change_fee(BlockHeight::zero());
1524+
1525+
let max_amount_to_mint = Amount::from_atoms(i128::MAX as u128);
1526+
let total_supply_atoms = if rng.gen_bool(0.5) {
1527+
u128::MAX
1528+
} else {
1529+
rng.gen_range((i128::MAX as u128) + 1..u128::MAX)
1530+
};
1531+
let total_supply_atoms_above_i128_max = total_supply_atoms - i128::MAX as u128;
1532+
assert!(total_supply_atoms_above_i128_max > 0);
1533+
1534+
let (token_id, issuance_block_id, issuance_tx, issuance, utxo_with_change) =
1535+
issue_token_from_genesis(
1536+
&mut rng,
1537+
&mut tf,
1538+
TokenTotalSupply::Fixed(Amount::from_atoms(total_supply_atoms)),
1539+
IsTokenFreezable::No,
1540+
);
1541+
1542+
// Mint i128::MAX atoms
1543+
let initial_mint_tx = TransactionBuilder::new()
14601544
.add_input(
14611545
TxInput::from_command(
1462-
AccountNonce::new(1),
1463-
AccountCommand::MintTokens(token_id, random_amount),
1546+
AccountNonce::new(0),
1547+
AccountCommand::MintTokens(token_id, max_amount_to_mint),
14641548
),
14651549
InputWitness::NoSignature(None),
14661550
)
14671551
.add_input(
1468-
TxInput::from_utxo(mint_tx_id.into(), 0),
1552+
utxo_with_change.clone().into(),
14691553
InputWitness::NoSignature(None),
14701554
)
14711555
.add_output(TxOutput::Transfer(
1472-
OutputValue::TokenV1(token_id, random_amount),
1556+
OutputValue::Coin(token_supply_change_fee),
1557+
Destination::AnyoneCanSpend,
1558+
))
1559+
.add_output(TxOutput::Transfer(
1560+
OutputValue::TokenV1(token_id, max_amount_to_mint),
14731561
Destination::AnyoneCanSpend,
14741562
))
14751563
.build();
1476-
let mint_tx_id = mint_tx.transaction().get_id();
1477-
let result = tf.make_block_builder().add_transaction(mint_tx).build_and_process(&mut rng);
1564+
let initial_mint_tx_id = initial_mint_tx.transaction().get_id();
1565+
tf.make_block_builder()
1566+
.add_transaction(initial_mint_tx)
1567+
.build_and_process(&mut rng)
1568+
.unwrap();
14781569

1479-
assert_eq!(
1480-
result.unwrap_err(),
1481-
ChainstateError::ProcessBlockError(BlockError::StateUpdateFailed(
1482-
ConnectTransactionError::ConstrainedValueAccumulatorError(
1483-
constraints_value_accumulator::Error::TokensAccountingError(
1484-
tokens_accounting::Error::AccountingError(
1485-
accounting::Error::ArithmeticErrorDeltaAdditionFailed
1486-
)
1570+
check_fungible_token(
1571+
&tf,
1572+
&mut rng,
1573+
&token_id,
1574+
&ExpectedFungibleTokenData {
1575+
issuance,
1576+
issuance_tx,
1577+
issuance_block_id,
1578+
circulating_supply: Some(max_amount_to_mint),
1579+
is_locked: false,
1580+
is_frozen: IsTokenFrozen::No(IsTokenFreezable::No),
1581+
},
1582+
true,
1583+
);
1584+
1585+
let make_mint_tx = |amount| {
1586+
TransactionBuilder::new()
1587+
.add_input(
1588+
TxInput::from_command(
1589+
AccountNonce::new(1),
1590+
AccountCommand::MintTokens(token_id, amount),
14871591
),
1488-
mint_tx_id.into()
1592+
InputWitness::NoSignature(None),
14891593
)
1490-
))
1491-
);
1594+
.add_input(
1595+
TxInput::from_utxo(initial_mint_tx_id.into(), 0),
1596+
InputWitness::NoSignature(None),
1597+
)
1598+
.add_output(TxOutput::Transfer(
1599+
OutputValue::TokenV1(token_id, amount),
1600+
Destination::AnyoneCanSpend,
1601+
))
1602+
.build()
1603+
};
1604+
1605+
{
1606+
// Try mint one more atom
1607+
let mint_tx = make_mint_tx(Amount::from_atoms(1));
1608+
let mint_tx_id = mint_tx.transaction().get_id();
1609+
let result =
1610+
tf.make_block_builder().add_transaction(mint_tx).build_and_process(&mut rng);
1611+
1612+
assert_eq!(
1613+
result.unwrap_err(),
1614+
ChainstateError::ProcessBlockError(BlockError::StateUpdateFailed(
1615+
ConnectTransactionError::ConstrainedValueAccumulatorError(
1616+
constraints_value_accumulator::Error::TokensAccountingError(
1617+
tokens_accounting::Error::AccountingError(
1618+
accounting::Error::ArithmeticErrorDeltaAdditionFailed
1619+
)
1620+
),
1621+
mint_tx_id.into()
1622+
)
1623+
))
1624+
);
1625+
}
1626+
1627+
{
1628+
// Try minting a random number of atoms, so that the total is below the specified max supply.
1629+
let amount = Amount::from_atoms(rng.gen_range(1..=total_supply_atoms_above_i128_max));
1630+
let mint_tx = make_mint_tx(amount);
1631+
let mint_tx_id = mint_tx.transaction().get_id();
1632+
let result =
1633+
tf.make_block_builder().add_transaction(mint_tx).build_and_process(&mut rng);
1634+
1635+
assert_eq!(
1636+
result.unwrap_err(),
1637+
ChainstateError::ProcessBlockError(BlockError::StateUpdateFailed(
1638+
ConnectTransactionError::ConstrainedValueAccumulatorError(
1639+
constraints_value_accumulator::Error::TokensAccountingError(
1640+
tokens_accounting::Error::AccountingError(
1641+
accounting::Error::ArithmeticErrorDeltaAdditionFailed
1642+
)
1643+
),
1644+
mint_tx_id.into()
1645+
)
1646+
))
1647+
);
1648+
}
1649+
1650+
{
1651+
// For completeness, try minting a random number of atoms, so that the total is above
1652+
// the specified max supply. Different errors are expected in this case, depending
1653+
// on whether the total amount fits into u128.
1654+
1655+
let max_extra_amount_to_fit_into_u128 = u128::MAX - total_supply_atoms;
1656+
1657+
if max_extra_amount_to_fit_into_u128 != 0 {
1658+
// The total amount fits into u128.
1659+
1660+
let amount = Amount::from_atoms(
1661+
total_supply_atoms_above_i128_max
1662+
+ rng.gen_range(1..=max_extra_amount_to_fit_into_u128),
1663+
);
1664+
let mint_tx = make_mint_tx(amount);
1665+
let mint_tx_id = mint_tx.transaction().get_id();
1666+
let result =
1667+
tf.make_block_builder().add_transaction(mint_tx).build_and_process(&mut rng);
1668+
1669+
assert_eq!(
1670+
result.unwrap_err(),
1671+
ChainstateError::ProcessBlockError(BlockError::StateUpdateFailed(
1672+
ConnectTransactionError::ConstrainedValueAccumulatorError(
1673+
constraints_value_accumulator::Error::TokensAccountingError(
1674+
tokens_accounting::Error::MintExceedsSupplyLimit(
1675+
amount,
1676+
Amount::from_atoms(total_supply_atoms),
1677+
token_id
1678+
)
1679+
),
1680+
mint_tx_id.into()
1681+
)
1682+
))
1683+
);
1684+
}
1685+
1686+
{
1687+
// The total amount doesn't fit into u128.
1688+
1689+
let amount = Amount::from_atoms(rng.gen_range(
1690+
total_supply_atoms_above_i128_max + max_extra_amount_to_fit_into_u128 + 1
1691+
..=u128::MAX,
1692+
));
1693+
let mint_tx = make_mint_tx(amount);
1694+
let mint_tx_id = mint_tx.transaction().get_id();
1695+
let result =
1696+
tf.make_block_builder().add_transaction(mint_tx).build_and_process(&mut rng);
1697+
1698+
assert_eq!(
1699+
result.unwrap_err(),
1700+
ChainstateError::ProcessBlockError(BlockError::StateUpdateFailed(
1701+
ConnectTransactionError::ConstrainedValueAccumulatorError(
1702+
constraints_value_accumulator::Error::TokensAccountingError(
1703+
tokens_accounting::Error::AmountOverflow
1704+
),
1705+
mint_tx_id.into()
1706+
)
1707+
))
1708+
);
1709+
}
1710+
}
14921711
});
14931712
}
14941713

p2p/src/sync/peer/block_manager.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,15 @@ where
716716
self.incoming.peers_best_block_that_we_have.as_displayable()
717717
);
718718

719+
// Now use preliminary_headers_check; this can be done because the first header
720+
// is known to be connected to the chainstate.
721+
{
722+
let new_block_headers = new_block_headers.clone();
723+
self.chainstate_handle
724+
.call(move |c| Ok(c.preliminary_headers_check(&new_block_headers)?))
725+
.await?;
726+
}
727+
719728
if !self.incoming.requested_blocks.is_empty() {
720729
// We are already downloading blocks, so bail out.
721730
// Note that we unconditionally replace pending_headers with new_block_headers
@@ -732,15 +741,6 @@ where
732741
return Ok(());
733742
}
734743

735-
// Now use preliminary_headers_check; this can be done because the first header
736-
// is known to be connected to the chainstate.
737-
{
738-
let new_block_headers = new_block_headers.clone();
739-
self.chainstate_handle
740-
.call(move |c| Ok(c.preliminary_headers_check(&new_block_headers)?))
741-
.await?;
742-
}
743-
744744
self.request_blocks(new_block_headers)
745745
}
746746

0 commit comments

Comments
 (0)