From a2fe2b27d9ae1c5f1da59ffaa8abc9eaa3507683 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Mon, 22 Jul 2024 13:49:35 +0700 Subject: [PATCH 1/3] test: minor improvements for credit pool functional test --- test/functional/feature_asset_locks.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/test/functional/feature_asset_locks.py b/test/functional/feature_asset_locks.py index c4a1b030be..e75b927aca 100755 --- a/test/functional/feature_asset_locks.py +++ b/test/functional/feature_asset_locks.py @@ -223,14 +223,14 @@ class AssetLocksTest(DashTestFramework): except JSONRPCException as e: assert expected_error in e.error['message'] - def slowly_generate_batch(self, amount): - self.log.info(f"Slowly generate {amount} blocks") - while amount > 0: - self.log.info(f"Generating batch of blocks {amount} left") - next = min(10, amount) - amount -= next - self.bump_mocktime(next) - self.nodes[1].generate(next) + def slowly_generate_batch(self, count): + self.log.info(f"Slowly generate {count} blocks") + while count > 0: + self.log.info(f"Generating batch of blocks {count} left") + batch = min(10, count) + count -= batch + self.bump_mocktime(batch) + self.nodes[1].generate(batch) self.sync_all() def run_test(self): @@ -381,7 +381,7 @@ class AssetLocksTest(DashTestFramework): assert_equal(rawtx_is["chainlock"], False) assert not "confirmations" in rawtx assert not "confirmations" in rawtx_is - # disable back IS + self.log.info("Disable back IS") self.set_sporks() assert "assetUnlockTx" in node.getrawtransaction(txid, 1) @@ -441,7 +441,7 @@ class AssetLocksTest(DashTestFramework): inode.reconsiderblock(block_to_reconsider) self.validate_credit_pool_balance(locked - 2 * COIN) - self.log.info("Forcibly mining asset_unlock_tx_too_late and ensure block is invalid...") + self.log.info("Forcibly mining asset_unlock_tx_too_late and ensure block is invalid") self.create_and_check_block([asset_unlock_tx_too_late], expected_error = "bad-assetunlock-not-active-quorum") node.generate(1) @@ -450,7 +450,7 @@ class AssetLocksTest(DashTestFramework): self.validate_credit_pool_balance(locked - 2 * COIN) self.validate_credit_pool_balance(block_hash=self.block_hash_1, expected=locked) - self.log.info("Forcibly mine asset_unlock_tx_full and ensure block is invalid...") + self.log.info("Forcibly mine asset_unlock_tx_duplicate_index and ensure block is invalid") self.create_and_check_block([asset_unlock_tx_duplicate_index], expected_error = "bad-assetunlock-duplicated-index") From 4ad18f64f5c0ad29d6fead19bcbbc2c84aa48865 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Mon, 22 Jul 2024 13:52:10 +0700 Subject: [PATCH 2/3] fix: properly test hard limit of 1000 dash Now function test doesn't distint difference between 10% or 1000. Adjust amounts to make it less than 10% but more than 1000 --- test/functional/feature_asset_locks.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/functional/feature_asset_locks.py b/test/functional/feature_asset_locks.py index e75b927aca..9cb473760b 100755 --- a/test/functional/feature_asset_locks.py +++ b/test/functional/feature_asset_locks.py @@ -41,7 +41,6 @@ from test_framework.util import ( assert_equal, assert_greater_than, assert_greater_than_or_equal, - get_bip9_details, hex_str_to_bytes, ) @@ -490,8 +489,8 @@ class AssetLocksTest(DashTestFramework): total = self.get_credit_pool_balance() coins = node_wallet.listunspent() - while total <= 10_900 * COIN: - self.log.info(f"Collecting coins in pool... Collected {total}/{10_900 * COIN}") + while total <= 10_100 * COIN: + self.log.info(f"Collecting coins in pool... Collected {total}/{10_100 * COIN}") coin = coins.pop() to_lock = int(coin['amount'] * COIN) - tiny_amount if to_lock > 99 * COIN: @@ -503,11 +502,13 @@ class AssetLocksTest(DashTestFramework): node.generate(1) self.sync_all() credit_pool_balance_1 = self.get_credit_pool_balance() - assert_greater_than(credit_pool_balance_1, 10_900 * COIN) + assert_greater_than(credit_pool_balance_1, 10_100 * COIN) limit_amount_1 = 1000 * COIN + self.log.info("Create 4 transaction to be sure that only 3 of them can be mined") + self.log.info("Sum of 600, 101 * 3 are less than 10% of credit pool but bigger than hard-limit 1000") # take most of limit by one big tx for faster testing and # create several tiny withdrawal with exactly 1 *invalid* / causes spend above limit tx - withdrawals = [600 * COIN, 131 * COIN, 131 * COIN, 131 * COIN, 131 * COIN] + withdrawals = [600 * COIN, 101 * COIN, 101 * COIN, 101 * COIN, 101 * COIN] amount_to_withdraw_1 = sum(withdrawals) index = 400 for next_amount in withdrawals: @@ -521,24 +522,23 @@ class AssetLocksTest(DashTestFramework): self.sync_mempools() node.generate(1) self.sync_all() - self.log.info(f"MN_RR status: {get_bip9_details(node, 'mn_rr')}") new_total = self.get_credit_pool_balance() amount_actually_withdrawn = total - new_total block = node.getblock(node.getbestblockhash()) - self.log.info("Testing that we tried to withdraw more than we could...") + self.log.info("Testing that we tried to withdraw more than we could") assert_greater_than(amount_to_withdraw_1, amount_actually_withdrawn) - self.log.info("Checking that we tried to withdraw more than the limit...") + self.log.info("Checking that we tried to withdraw more than the limit 1000") assert_greater_than(amount_to_withdraw_1, limit_amount_1) - self.log.info("Checking we didn't actually withdraw more than allowed by the limit...") + self.log.info("Checking we didn't actually withdraw more than allowed by the limit") assert_greater_than_or_equal(limit_amount_1, amount_actually_withdrawn) - assert_equal(amount_actually_withdrawn, 993 * COIN) + assert_equal(amount_actually_withdrawn, 903 * COIN) + node.generate(1) self.sync_all() self.log.info("Checking that exactly 1 tx stayed in mempool...") self.mempool_size = 1 self.check_mempool_size() - assert_equal(new_total, self.get_credit_pool_balance()) self.log.info("Fast forward to next day again...") self.slowly_generate_batch(blocks_in_one_day - 2) @@ -561,7 +561,7 @@ class AssetLocksTest(DashTestFramework): assert_equal(new_total, self.get_credit_pool_balance()) self.log.info("Trying to withdraw more... expecting to fail") index += 1 - asset_unlock_tx = self.create_assetunlock(index, COIN * 100, pubkey) + asset_unlock_tx = self.create_assetunlock(index, COIN, pubkey) self.send_tx(asset_unlock_tx) node.generate(1) self.sync_all() From f22ade31b99fb770df49aa62f194b25dd70e42c2 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Tue, 23 Jul 2024 12:02:05 +0300 Subject: [PATCH 3/3] tests: more strict test for withrawal 1000 and minor improvements --- test/functional/feature_asset_locks.py | 47 ++++++++++++++++++-------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/test/functional/feature_asset_locks.py b/test/functional/feature_asset_locks.py index 9cb473760b..314d807456 100755 --- a/test/functional/feature_asset_locks.py +++ b/test/functional/feature_asset_locks.py @@ -489,8 +489,7 @@ class AssetLocksTest(DashTestFramework): total = self.get_credit_pool_balance() coins = node_wallet.listunspent() - while total <= 10_100 * COIN: - self.log.info(f"Collecting coins in pool... Collected {total}/{10_100 * COIN}") + while total <= 10_901 * COIN: coin = coins.pop() to_lock = int(coin['amount'] * COIN) - tiny_amount if to_lock > 99 * COIN: @@ -498,26 +497,26 @@ class AssetLocksTest(DashTestFramework): total += to_lock tx = self.create_assetlock(coin, to_lock, pubkey) self.send_tx_simple(tx) + self.log.info(f"Collecting coins in pool... Collected {total}/{10_901 * COIN}") self.sync_mempools() node.generate(1) self.sync_all() credit_pool_balance_1 = self.get_credit_pool_balance() - assert_greater_than(credit_pool_balance_1, 10_100 * COIN) + assert_greater_than(credit_pool_balance_1, 10_901 * COIN) limit_amount_1 = 1000 * COIN - self.log.info("Create 4 transaction to be sure that only 3 of them can be mined") - self.log.info("Sum of 600, 101 * 3 are less than 10% of credit pool but bigger than hard-limit 1000") + self.log.info("Create 5 transactions and make sure that only 4 of them can be mined") + self.log.info("because their sum is bigger than the hard-limit (1000)") # take most of limit by one big tx for faster testing and # create several tiny withdrawal with exactly 1 *invalid* / causes spend above limit tx - withdrawals = [600 * COIN, 101 * COIN, 101 * COIN, 101 * COIN, 101 * COIN] + withdrawals = [600 * COIN, 100 * COIN, 100 * COIN, 100 * COIN - 10000, 100 * COIN + 10001] amount_to_withdraw_1 = sum(withdrawals) index = 400 for next_amount in withdrawals: index += 1 asset_unlock_tx = self.create_assetunlock(index, next_amount, pubkey) - self.send_tx_simple(asset_unlock_tx) - if index == 401: - self.sync_mempools() - node.generate(1) + last_txid = self.send_tx_simple(asset_unlock_tx) + # make sure larger amounts are mined first simply to make this test deterministic + node.prioritisetransaction(last_txid, next_amount // 10000) self.sync_mempools() node.generate(1) @@ -525,14 +524,13 @@ class AssetLocksTest(DashTestFramework): new_total = self.get_credit_pool_balance() amount_actually_withdrawn = total - new_total - block = node.getblock(node.getbestblockhash()) self.log.info("Testing that we tried to withdraw more than we could") assert_greater_than(amount_to_withdraw_1, amount_actually_withdrawn) - self.log.info("Checking that we tried to withdraw more than the limit 1000") + self.log.info("Checking that we tried to withdraw more than the hard-limit (1000)") assert_greater_than(amount_to_withdraw_1, limit_amount_1) self.log.info("Checking we didn't actually withdraw more than allowed by the limit") assert_greater_than_or_equal(limit_amount_1, amount_actually_withdrawn) - assert_equal(amount_actually_withdrawn, 903 * COIN) + assert_equal(amount_actually_withdrawn, 900 * COIN + 10001) node.generate(1) self.sync_all() @@ -540,8 +538,28 @@ class AssetLocksTest(DashTestFramework): self.mempool_size = 1 self.check_mempool_size() assert_equal(new_total, self.get_credit_pool_balance()) + pending_txid = node.getrawmempool()[0] + + amount_to_withdraw_2 = limit_amount_1 - amount_actually_withdrawn + self.log.info(f"We can still consume {Decimal(str(amount_to_withdraw_2 / COIN))} before we hit the hard-limit (1000)") + index += 1 + asset_unlock_tx = self.create_assetunlock(index, amount_to_withdraw_2, pubkey) + self.send_tx_simple(asset_unlock_tx) + self.sync_mempools() + node.generate(1) + self.sync_all() + new_total = self.get_credit_pool_balance() + amount_actually_withdrawn = total - new_total + assert_equal(limit_amount_1, amount_actually_withdrawn) + + self.log.info("Checking that exactly the same tx as before stayed in mempool and it's the only one...") + self.mempool_size = 1 + self.check_mempool_size() + assert_equal(new_total, self.get_credit_pool_balance()) + assert pending_txid in node.getrawmempool() + self.log.info("Fast forward to next day again...") - self.slowly_generate_batch(blocks_in_one_day - 2) + self.slowly_generate_batch(blocks_in_one_day - 1) self.log.info("Checking mempool is empty now...") self.mempool_size = 0 self.check_mempool_size() @@ -583,6 +601,7 @@ class AssetLocksTest(DashTestFramework): def test_mn_rr(self, node_wallet, node, pubkey): self.log.info("Activate mn_rr...") locked = self.get_credit_pool_balance() + node.generate(12 - node.getblockcount() % 12) self.activate_mn_rr(expected_activation_height=node.getblockcount() + 12 * 3) self.log.info(f'height: {node.getblockcount()} credit: {self.get_credit_pool_balance()}') assert_equal(locked, self.get_credit_pool_balance())