From 0253438503c156ecfa8f4074a67c8c0c2ade6a62 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Thu, 19 Sep 2024 00:55:14 +0700 Subject: [PATCH 1/6] feat: new fork WITHDRAWALS introduced --- src/chainparams.cpp | 36 +++++++++++++++++++++++++++++++ src/consensus/params.h | 1 + src/deploymentinfo.cpp | 4 ++++ src/rpc/blockchain.cpp | 1 + test/functional/rpc_blockchain.py | 11 ++++++++++ 5 files changed, 53 insertions(+) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index e041149cd1..d551dfeea0 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -209,6 +209,15 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].bit = 11; + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nStartTime = 1728864000; // October 14, 2024 + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nTimeout = 1760400000; // October 14, 2025 + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nWindowSize = 4032; + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nThresholdStart = 3226; // 80% of 4032 + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nThresholdMin = 2420; // 60% of 4032 + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nFalloffCoeff = 5; // this corresponds to 10 periods + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].useEHF = true; + // The best chain should have at least this much work. consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000988117deadb0db9cd5b8"); // 2109672 @@ -395,6 +404,15 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].bit = 11; + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nStartTime = 1728864000; // October 14, 2024 + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nWindowSize = 100; + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nThresholdStart = 80; // 80% of 100 + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nThresholdMin = 60; // 60% of 100 + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nFalloffCoeff = 5; // this corresponds to 10 periods + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].useEHF = true; + // The best chain should have at least this much work. consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000000031779704a0f54b4"); // 1069875 @@ -556,6 +574,15 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].bit = 11; + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nStartTime = 1704067200; // January 1, 2024 + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nWindowSize = 120; + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nThresholdStart = 80; // 80% of 100 + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nThresholdMin = 60; // 60% of 100 + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nFalloffCoeff = 5; // this corresponds to 10 periods + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].useEHF = true; + // The best chain should have at least this much work. consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000000000000000000000"); @@ -782,6 +809,15 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].bit = 11; + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nStartTime = 0; + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nWindowSize = 300; + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nThresholdStart = 300 / 5 * 4; // 80% of 12 + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nThresholdMin = 300 / 5 * 3; // 60% of 7 + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nFalloffCoeff = 5; // this corresponds to 10 periods + consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].useEHF = true; + // The best chain should have at least this much work. consensus.nMinimumChainWork = uint256S("0x00"); diff --git a/src/consensus/params.h b/src/consensus/params.h index 95918aa6db..508d477c54 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -39,6 +39,7 @@ constexpr bool ValidDeployment(BuriedDeployment dep) { return dep <= DEPLOYMENT_ enum DeploymentPos : uint16_t { DEPLOYMENT_TESTDUMMY, + DEPLOYMENT_WITHDRAWALS, // Deployment of Fix for quorum selection for withdrawals // NOTE: Also add new deployments to VersionBitsDeploymentInfo in deploymentinfo.cpp MAX_VERSION_BITS_DEPLOYMENTS }; diff --git a/src/deploymentinfo.cpp b/src/deploymentinfo.cpp index 98ba9b3652..6ea50a3d47 100644 --- a/src/deploymentinfo.cpp +++ b/src/deploymentinfo.cpp @@ -11,6 +11,10 @@ const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_B /*.name =*/ "testdummy", /*.gbt_force =*/ true, }, + { + /*.name =*/"withdrawals", + /*.gbt_force =*/true, + }, }; std::string DeploymentName(Consensus::BuriedDeployment dep) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 6bf41d7ba8..defe3fb34e 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1841,6 +1841,7 @@ RPCHelpMan getblockchaininfo() SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_V19); SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_V20); SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_MN_RR); + SoftForkDescPushBack(tip, ehfSignals, softforks, consensusParams, Consensus::DEPLOYMENT_WITHDRAWALS); SoftForkDescPushBack(tip, ehfSignals, softforks, consensusParams, Consensus::DEPLOYMENT_TESTDUMMY); obj.pushKV("softforks", softforks); diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py index a36e881c68..a327a630aa 100755 --- a/test/functional/rpc_blockchain.py +++ b/test/functional/rpc_blockchain.py @@ -157,6 +157,17 @@ class BlockchainTest(BitcoinTestFramework): 'v19': { 'type': 'buried', 'active': False, 'height': 900}, 'v20': { 'type': 'buried', 'active': False, 'height': 900}, 'mn_rr': { 'type': 'buried', 'active': False, 'height': 900}, + 'withdrawals': { + 'type': 'bip9', + 'bip9': { + 'status': 'defined', + 'start_time': 0, + 'timeout': 9223372036854775807, # testdummy does not have a timeout so is set to the max int64 value + 'since': 0, + 'min_activation_height': 0, + 'ehf': True + }, + 'active': False}, 'testdummy': { 'type': 'bip9', 'bip9': { From 27040030e9b7c78ca2197bc8b653d483d7589ced Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 18 Sep 2024 19:46:45 +0700 Subject: [PATCH 2/6] fix: using proper quorums for asset unlock validation --- src/evo/assetlocktx.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/evo/assetlocktx.cpp b/src/evo/assetlocktx.cpp index ccbb0042e0..64ee2b32c4 100644 --- a/src/evo/assetlocktx.cpp +++ b/src/evo/assetlocktx.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -113,13 +114,18 @@ bool CAssetUnlockPayload::VerifySig(const llmq::CQuorumManager& qman, const uint // and at the quorumHash must be active in either the current or previous quorum cycle // and the sig must validate against that specific quorumHash. + Consensus::LLMQType llmqType = Params().GetConsensus().llmqTypePlatform; - // We check at most 2 quorums - const auto quorums = qman.ScanQuorums(llmqType, pindexTip, 2); + const auto& llmq_params_opt = Params().GetLLMQ(llmqType); + assert(llmq_params_opt.has_value()); + + // after deployment WITHDRAWALS activated we check not to quorum, but all active quorums + 1 the latest inactive + const int quorums_to_scan = DeploymentActiveAt(*pindexTip, Params().GetConsensus(), Consensus::DEPLOYMENT_WITHDRAWALS) ? (llmq_params_opt->signingActiveQuorumCount + 1) : 2; + const auto quorums = qman.ScanQuorums(llmqType, pindexTip, quorums_to_scan); if (bool isActive = std::any_of(quorums.begin(), quorums.end(), [&](const auto &q) { return q->qc->quorumHash == quorumHash; }); !isActive) { - return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-assetunlock-not-active-quorum"); + return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-assetunlock-too-old-quorum"); } if (static_cast(pindexTip->nHeight) < requestedHeight || pindexTip->nHeight >= getHeightToExpiry()) { From 5fd7b07ddc24fe5fbb2bebbf8e38d6b92f1ddff8 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Thu, 19 Sep 2024 03:50:44 +0700 Subject: [PATCH 3/6] chore: test new validation of asset unlocks tests after fork 'withdrawals' --- test/functional/feature_asset_locks.py | 35 ++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/test/functional/feature_asset_locks.py b/test/functional/feature_asset_locks.py index 91480c0007..c49903f996 100755 --- a/test/functional/feature_asset_locks.py +++ b/test/functional/feature_asset_locks.py @@ -38,6 +38,7 @@ from test_framework.util import ( assert_equal, assert_greater_than, assert_greater_than_or_equal, + softfork_active, ) from test_framework.wallet_util import bytes_to_wif @@ -271,6 +272,7 @@ class AssetLocksTest(DashTestFramework): self.test_asset_unlocks(node_wallet, node, pubkey) self.test_withdrawal_limits(node_wallet, node, pubkey) self.test_mn_rr(node_wallet, node, pubkey) + self.test_withdrawal_fork(node_wallet, node, pubkey) def test_asset_locks(self, node_wallet, node, pubkey): @@ -430,8 +432,9 @@ class AssetLocksTest(DashTestFramework): self.log.info("Checking that two quorums later it is too late because quorum is not active...") self.mine_quorum_2_nodes(llmq_type_name='llmq_test_platform', llmq_type=106) self.log.info("Expecting new reject-reason...") + assert not softfork_active(self.nodes[0], 'withdrawals') self.check_mempool_result(tx=asset_unlock_tx_too_late, - result_expected={'allowed': False, 'reject-reason' : 'bad-assetunlock-not-active-quorum'}) + result_expected={'allowed': False, 'reject-reason' : 'bad-assetunlock-too-old-quorum'}) block_to_reconsider = node.getbestblockhash() self.log.info("Test block invalidation with asset unlock tx...") @@ -445,7 +448,8 @@ class AssetLocksTest(DashTestFramework): self.validate_credit_pool_balance(locked - 2 * COIN) 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") + assert not softfork_active(self.nodes[0], 'withdrawals') + self.create_and_check_block([asset_unlock_tx_too_late], expected_error = "bad-assetunlock-too-old-quorum") self.generate(node, 1) @@ -636,6 +640,33 @@ class AssetLocksTest(DashTestFramework): self.generate(node, 1) assert_equal(locked, self.get_credit_pool_balance()) + def test_withdrawal_fork(self, node_wallet, node, pubkey): + self.log.info("Testing asset unlock after 'withdrawal' activation...") + + assert softfork_active(self.nodes[0], 'withdrawals') + self.log.info("Generating several txes by same quorum....") + + asset_unlock_tx = self.create_assetunlock(501, COIN, pubkey) + asset_unlock_tx_payload = CAssetUnlockTx() + asset_unlock_tx_payload.deserialize(BytesIO(asset_unlock_tx.vExtraPayload)) + + self.log.info("Check that new Asset Unlock is valid for current quorum") + self.check_mempool_result(tx=asset_unlock_tx, result_expected={'allowed': True, 'fees': {'base': Decimal(str(tiny_amount / COIN))}}) + + while asset_unlock_tx_payload.quorumHash in node.quorum('list')['llmq_test_platform']: + self.log.info(f"Generate one more quorum until signing quorum becomes not available") + self.mine_quorum_2_nodes(llmq_type_name="llmq_test_platform", llmq_type=106) + + self.check_mempool_result(tx=asset_unlock_tx, result_expected={'allowed': True, 'fees': {'base': Decimal(str(tiny_amount / COIN))}}) + + self.log.info(f"Generate one more quorum after which asset unlock meant to be still valid") + self.mine_quorum_2_nodes(llmq_type_name="llmq_test_platform", llmq_type=106) + self.check_mempool_result(tx=asset_unlock_tx, result_expected={'allowed': True, 'fees': {'base': Decimal(str(tiny_amount / COIN))}}) + self.log.info(f"Generate one more quorum after which asset unlock meant to be expired") + self.mine_quorum_2_nodes(llmq_type_name="llmq_test_platform", llmq_type=106) + self.check_mempool_result(tx=asset_unlock_tx, result_expected={'allowed': False, 'reject-reason': 'bad-assetunlock-too-old-quorum'}) + + if __name__ == '__main__': AssetLocksTest().main() From 6fbd128947e012733c5a02bcda46a93bd20b1aee Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Fri, 11 Oct 2024 15:33:52 +0300 Subject: [PATCH 4/6] chore: clang format/reword/typos --- src/evo/assetlocktx.cpp | 7 +++++-- test/functional/rpc_blockchain.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/evo/assetlocktx.cpp b/src/evo/assetlocktx.cpp index 64ee2b32c4..27e53e0b24 100644 --- a/src/evo/assetlocktx.cpp +++ b/src/evo/assetlocktx.cpp @@ -120,8 +120,11 @@ bool CAssetUnlockPayload::VerifySig(const llmq::CQuorumManager& qman, const uint const auto& llmq_params_opt = Params().GetLLMQ(llmqType); assert(llmq_params_opt.has_value()); - // after deployment WITHDRAWALS activated we check not to quorum, but all active quorums + 1 the latest inactive - const int quorums_to_scan = DeploymentActiveAt(*pindexTip, Params().GetConsensus(), Consensus::DEPLOYMENT_WITHDRAWALS) ? (llmq_params_opt->signingActiveQuorumCount + 1) : 2; + // We check two quorums before DEPLOYMENT_WITHDRAWALS activation + // and "all active quorums + 1 the latest inactive" after activation. + const int quorums_to_scan = DeploymentActiveAt(*pindexTip, Params().GetConsensus(), Consensus::DEPLOYMENT_WITHDRAWALS) + ? (llmq_params_opt->signingActiveQuorumCount + 1) + : 2; const auto quorums = qman.ScanQuorums(llmqType, pindexTip, quorums_to_scan); if (bool isActive = std::any_of(quorums.begin(), quorums.end(), [&](const auto &q) { return q->qc->quorumHash == quorumHash; }); !isActive) { diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py index a327a630aa..14c4f55f4a 100755 --- a/test/functional/rpc_blockchain.py +++ b/test/functional/rpc_blockchain.py @@ -162,7 +162,7 @@ class BlockchainTest(BitcoinTestFramework): 'bip9': { 'status': 'defined', 'start_time': 0, - 'timeout': 9223372036854775807, # testdummy does not have a timeout so is set to the max int64 value + 'timeout': 9223372036854775807, # "withdrawals" does not have a timeout so is set to the max int64 value 'since': 0, 'min_activation_height': 0, 'ehf': True From ecd0a96f63bf20659add1c0901d594bfa12af641 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 16 Oct 2024 00:01:39 +0300 Subject: [PATCH 5/6] test: fix test_withdrawal_fork --- test/functional/feature_asset_locks.py | 55 ++++++++++++++++---------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/test/functional/feature_asset_locks.py b/test/functional/feature_asset_locks.py index c49903f996..89bbd6caa8 100755 --- a/test/functional/feature_asset_locks.py +++ b/test/functional/feature_asset_locks.py @@ -45,6 +45,7 @@ from test_framework.wallet_util import bytes_to_wif llmq_type_test = 106 # LLMQType::LLMQ_TEST_PLATFORM tiny_amount = int(Decimal("0.0007") * COIN) blocks_in_one_day = 576 +HEIGHT_DIFF_EXPIRING = 48 class AssetLocksTest(DashTestFramework): def set_test_params(self): @@ -272,7 +273,7 @@ class AssetLocksTest(DashTestFramework): self.test_asset_unlocks(node_wallet, node, pubkey) self.test_withdrawal_limits(node_wallet, node, pubkey) self.test_mn_rr(node_wallet, node, pubkey) - self.test_withdrawal_fork(node_wallet, node, pubkey) + self.test_withdrawal_fork(node_wallet, pubkey) def test_asset_locks(self, node_wallet, node, pubkey): @@ -347,7 +348,7 @@ class AssetLocksTest(DashTestFramework): asset_unlock_tx_duplicate_index = copy.deepcopy(asset_unlock_tx) # modify this tx with duplicated index to make a hash of tx different, otherwise tx would be refused too early asset_unlock_tx_duplicate_index.vout[0].nValue += COIN - too_late_height = node.getblockcount() + 48 + too_late_height = node.getblockcount() + HEIGHT_DIFF_EXPIRING self.check_mempool_result(tx=asset_unlock_tx, result_expected={'allowed': True, 'fees': {'base': Decimal(str(tiny_amount / COIN))}}) self.check_mempool_result(tx=asset_unlock_tx_too_big_fee, @@ -640,33 +641,45 @@ class AssetLocksTest(DashTestFramework): self.generate(node, 1) assert_equal(locked, self.get_credit_pool_balance()) - def test_withdrawal_fork(self, node_wallet, node, pubkey): + def test_withdrawal_fork(self, node_wallet, pubkey): self.log.info("Testing asset unlock after 'withdrawal' activation...") + assert softfork_active(node_wallet, 'withdrawals') - assert softfork_active(self.nodes[0], 'withdrawals') - self.log.info("Generating several txes by same quorum....") - - asset_unlock_tx = self.create_assetunlock(501, COIN, pubkey) - asset_unlock_tx_payload = CAssetUnlockTx() - asset_unlock_tx_payload.deserialize(BytesIO(asset_unlock_tx.vExtraPayload)) - - self.log.info("Check that new Asset Unlock is valid for current quorum") - self.check_mempool_result(tx=asset_unlock_tx, result_expected={'allowed': True, 'fees': {'base': Decimal(str(tiny_amount / COIN))}}) - - while asset_unlock_tx_payload.quorumHash in node.quorum('list')['llmq_test_platform']: - self.log.info(f"Generate one more quorum until signing quorum becomes not available") - self.mine_quorum_2_nodes(llmq_type_name="llmq_test_platform", llmq_type=106) + index = 501 + while True: + self.log.info(f"Generating new Asset Unlock tx, index={index}...") + asset_unlock_tx = self.create_assetunlock(index, COIN, pubkey) + asset_unlock_tx_payload = CAssetUnlockTx() + asset_unlock_tx_payload.deserialize(BytesIO(asset_unlock_tx.vExtraPayload)) + self.log.info("Check that Asset Unlock tx is valid for current quorum") self.check_mempool_result(tx=asset_unlock_tx, result_expected={'allowed': True, 'fees': {'base': Decimal(str(tiny_amount / COIN))}}) - self.log.info(f"Generate one more quorum after which asset unlock meant to be still valid") - self.mine_quorum_2_nodes(llmq_type_name="llmq_test_platform", llmq_type=106) - self.check_mempool_result(tx=asset_unlock_tx, result_expected={'allowed': True, 'fees': {'base': Decimal(str(tiny_amount / COIN))}}) - self.log.info(f"Generate one more quorum after which asset unlock meant to be expired") + quorumHash_str = format(asset_unlock_tx_payload.quorumHash, '064x') + assert quorumHash_str in node_wallet.quorum('list')['llmq_test_platform'] + + while quorumHash_str != node_wallet.quorum('list')['llmq_test_platform'][-1]: + self.log.info("Generate one more quorum until signing quorum becomes the last one in the list") + self.mine_quorum_2_nodes(llmq_type_name="llmq_test_platform", llmq_type=106) + self.check_mempool_result(tx=asset_unlock_tx, result_expected={'allowed': True, 'fees': {'base': Decimal(str(tiny_amount / COIN))}}) + + self.log.info("Generate one more quorum after which signing quorum is gone but Asset Unlock tx is still valid") + assert quorumHash_str in node_wallet.quorum('list')['llmq_test_platform'] + self.mine_quorum_2_nodes(llmq_type_name="llmq_test_platform", llmq_type=106) + assert quorumHash_str not in node_wallet.quorum('list')['llmq_test_platform'] + + if asset_unlock_tx_payload.requestedHeight + HEIGHT_DIFF_EXPIRING > node_wallet.getblockcount(): + self.check_mempool_result(tx=asset_unlock_tx, result_expected={'allowed': True, 'fees': {'base': Decimal(str(tiny_amount / COIN))}}) + break + else: + self.check_mempool_result(tx=asset_unlock_tx, result_expected={'allowed': False, 'reject-reason' : 'bad-assetunlock-too-late'}) + self.log.info("Asset Unlock tx expired, let's try again...") + index += 1 + + self.log.info("Generate one more quorum after which signing quorum becomes too old") self.mine_quorum_2_nodes(llmq_type_name="llmq_test_platform", llmq_type=106) self.check_mempool_result(tx=asset_unlock_tx, result_expected={'allowed': False, 'reject-reason': 'bad-assetunlock-too-old-quorum'}) - if __name__ == '__main__': AssetLocksTest().main() From d69030951389d5d2c160e13024c86ca815a5a5e4 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Thu, 17 Oct 2024 03:03:09 +0700 Subject: [PATCH 6/6] fix: limit amount of attempts for test `test_withdrawal_fork` --- test/functional/feature_asset_locks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/feature_asset_locks.py b/test/functional/feature_asset_locks.py index 89bbd6caa8..f802edd056 100755 --- a/test/functional/feature_asset_locks.py +++ b/test/functional/feature_asset_locks.py @@ -646,7 +646,7 @@ class AssetLocksTest(DashTestFramework): assert softfork_active(node_wallet, 'withdrawals') index = 501 - while True: + while index < 511: self.log.info(f"Generating new Asset Unlock tx, index={index}...") asset_unlock_tx = self.create_assetunlock(index, COIN, pubkey) asset_unlock_tx_payload = CAssetUnlockTx()