fix: withdrawal (asset unlock) txes to use Platform Quorum on RegTest (#5800)

## Issue being fixed or feature implemented
Asset Unlock tx uses platform's quorum on devnets, testnet, mainnet, but
still quorum type "Test (100)" on Reg Tests
That's part II PR, prior work is here:
https://github.com/dashpay/dash/pull/5618

## What was done?
- Removed `consensus.llmqTypeAssetLocks` which has been kept only for
RegTest - use `consensus.llmqTypePlatform` instead.
- Functional test `feature_asset_locks.py` uses `llmq_type_test = 106`
instead `llmq_type_test = 100` for asset unlock tx
- there's 4 MNs + 3 evo nodes instead 3 MNs as before: evo nodes
requires to have IS to be active


## How Has This Been Tested?
Run unit/functional tests


## Breaking Changes
Asset Unlock tx uses correct quorum "106 llmq_test_platform" on reg test
instead "100 llmq_test"

## Checklist:
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have added or updated relevant unit/integration/functional/e2e
tests
- [ ] I have made corresponding changes to the documentation
- [x] I have assigned this pull request to a milestone
This commit is contained in:
Konstantin Akimov 2024-01-07 08:28:47 +07:00 committed by GitHub
parent 25111262cd
commit cf12572c67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 15 deletions

View File

@ -283,7 +283,6 @@ public:
consensus.llmqTypeDIP0024InstantSend = Consensus::LLMQType::LLMQ_60_75; consensus.llmqTypeDIP0024InstantSend = Consensus::LLMQType::LLMQ_60_75;
consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_100_67; consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_100_67;
consensus.llmqTypeMnhf = Consensus::LLMQType::LLMQ_400_85; consensus.llmqTypeMnhf = Consensus::LLMQType::LLMQ_400_85;
consensus.llmqTypeAssetLocks = consensus.llmqTypePlatform;
fDefaultConsistencyChecks = false; fDefaultConsistencyChecks = false;
fRequireStandard = true; fRequireStandard = true;
@ -475,7 +474,6 @@ public:
consensus.llmqTypeDIP0024InstantSend = Consensus::LLMQType::LLMQ_60_75; consensus.llmqTypeDIP0024InstantSend = Consensus::LLMQType::LLMQ_60_75;
consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_25_67; consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_25_67;
consensus.llmqTypeMnhf = Consensus::LLMQType::LLMQ_50_60; consensus.llmqTypeMnhf = Consensus::LLMQType::LLMQ_50_60;
consensus.llmqTypeAssetLocks = consensus.llmqTypePlatform;
fDefaultConsistencyChecks = false; fDefaultConsistencyChecks = false;
fRequireStandard = false; fRequireStandard = false;
@ -650,7 +648,6 @@ public:
consensus.llmqTypeDIP0024InstantSend = Consensus::LLMQType::LLMQ_DEVNET_DIP0024; consensus.llmqTypeDIP0024InstantSend = Consensus::LLMQType::LLMQ_DEVNET_DIP0024;
consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_DEVNET_PLATFORM; consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_DEVNET_PLATFORM;
consensus.llmqTypeMnhf = Consensus::LLMQType::LLMQ_DEVNET; consensus.llmqTypeMnhf = Consensus::LLMQType::LLMQ_DEVNET;
consensus.llmqTypeAssetLocks = consensus.llmqTypePlatform;
UpdateDevnetLLMQChainLocksFromArgs(args); UpdateDevnetLLMQChainLocksFromArgs(args);
UpdateDevnetLLMQInstantSendDIP0024FromArgs(args); UpdateDevnetLLMQInstantSendDIP0024FromArgs(args);
@ -723,7 +720,6 @@ public:
void UpdateDevnetLLMQPlatform(Consensus::LLMQType llmqType) void UpdateDevnetLLMQPlatform(Consensus::LLMQType llmqType)
{ {
consensus.llmqTypePlatform = llmqType; consensus.llmqTypePlatform = llmqType;
consensus.llmqTypeAssetLocks = llmqType;
} }
/** /**
@ -927,7 +923,6 @@ public:
consensus.llmqTypeDIP0024InstantSend = Consensus::LLMQType::LLMQ_TEST_DIP0024; consensus.llmqTypeDIP0024InstantSend = Consensus::LLMQType::LLMQ_TEST_DIP0024;
consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_TEST_PLATFORM; consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_TEST_PLATFORM;
consensus.llmqTypeMnhf = Consensus::LLMQType::LLMQ_TEST; consensus.llmqTypeMnhf = Consensus::LLMQType::LLMQ_TEST;
consensus.llmqTypeAssetLocks = Consensus::LLMQType::LLMQ_TEST;
UpdateLLMQTestParametersFromArgs(args, Consensus::LLMQType::LLMQ_TEST); UpdateLLMQTestParametersFromArgs(args, Consensus::LLMQType::LLMQ_TEST);
UpdateLLMQTestParametersFromArgs(args, Consensus::LLMQType::LLMQ_TEST_INSTANTSEND); UpdateLLMQTestParametersFromArgs(args, Consensus::LLMQType::LLMQ_TEST_INSTANTSEND);

View File

@ -162,7 +162,6 @@ struct Params {
LLMQType llmqTypeDIP0024InstantSend{LLMQType::LLMQ_NONE}; LLMQType llmqTypeDIP0024InstantSend{LLMQType::LLMQ_NONE};
LLMQType llmqTypePlatform{LLMQType::LLMQ_NONE}; LLMQType llmqTypePlatform{LLMQType::LLMQ_NONE};
LLMQType llmqTypeMnhf{LLMQType::LLMQ_NONE}; LLMQType llmqTypeMnhf{LLMQType::LLMQ_NONE};
LLMQType llmqTypeAssetLocks{LLMQType::LLMQ_NONE};
int DeploymentHeight(BuriedDeployment dep) const int DeploymentHeight(BuriedDeployment dep) const
{ {

View File

@ -114,7 +114,7 @@ bool CAssetUnlockPayload::VerifySig(const uint256& msgHash, gsl::not_null<const
// and at the quorumHash must be active in either the current or previous quorum cycle // and at the quorumHash must be active in either the current or previous quorum cycle
// and the sig must validate against that specific quorumHash. // and the sig must validate against that specific quorumHash.
Consensus::LLMQType llmqType = Params().GetConsensus().llmqTypeAssetLocks; Consensus::LLMQType llmqType = Params().GetConsensus().llmqTypePlatform;
// We check at most 2 quorums // We check at most 2 quorums
const auto quorums = llmq::quorumManager->ScanQuorums(llmqType, pindexTip, 2); const auto quorums = llmq::quorumManager->ScanQuorums(llmqType, pindexTip, 2);

View File

@ -45,13 +45,13 @@ from test_framework.util import (
hex_str_to_bytes, hex_str_to_bytes,
) )
llmq_type_test = 100 llmq_type_test = 106 # LLMQType::LLMQ_TEST_PLATFORM
tiny_amount = int(Decimal("0.0007") * COIN) tiny_amount = int(Decimal("0.0007") * COIN)
blocks_in_one_day = 576 blocks_in_one_day = 576
class AssetLocksTest(DashTestFramework): class AssetLocksTest(DashTestFramework):
def set_test_params(self): def set_test_params(self):
self.set_dash_test_params(5, 3) self.set_dash_test_params(6, 4, evo_count=3)
def skip_test_if_missing_module(self): def skip_test_if_missing_module(self):
self.skip_if_no_wallet() self.skip_if_no_wallet()
@ -98,7 +98,9 @@ class AssetLocksTest(DashTestFramework):
request_id = hash256(request_id_buf)[::-1].hex() request_id = hash256(request_id_buf)[::-1].hex()
height = node_wallet.getblockcount() height = node_wallet.getblockcount()
self.log.info(f"Creating asset unlock: {llmq_type_test} {request_id}")
quorumHash = mninfo[0].node.quorum("selectquorum", llmq_type_test, request_id)["quorumHash"] quorumHash = mninfo[0].node.quorum("selectquorum", llmq_type_test, request_id)["quorumHash"]
self.log.info(f"Used quorum hash: {quorumHash}")
unlockTx_payload = CAssetUnlockTx( unlockTx_payload = CAssetUnlockTx(
version = 1, version = 1,
index = index, index = index,
@ -235,8 +237,35 @@ class AssetLocksTest(DashTestFramework):
node = self.nodes[1] node = self.nodes[1]
self.set_sporks() self.set_sporks()
self.activate_v20()
self.activate_v19(expected_activation_height=900)
self.log.info("Activated v19 at height:" + str(node.getblockcount()))
# TODO: need to refactor this part to common code
# enabling instantsend -> 3 rotating quorums -> new 103 quorum
# with following dynamically adding evo nodes one-by-one seems
# as little too much complex for functional test (each which use Evo nodes)
self.nodes[0].sporkupdate("SPORK_2_INSTANTSEND_ENABLED", 0)
self.wait_for_sporks_same()
self.move_to_next_cycle()
self.log.info("Cycle H height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+C height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+2C height:" + str(self.nodes[0].getblockcount()))
self.mine_cycle_quorum(llmq_type_name='llmq_test_dip0024', llmq_type=103)
for i in range(3):
self.dynamically_add_masternode(evo=True)
node.generate(8)
self.sync_blocks()
self.set_sporks()
self.activate_v20()
node.generate(1)
self.sync_all()
self.mempool_size = 0 self.mempool_size = 0
key = ECKey() key = ECKey()
@ -253,13 +282,13 @@ class AssetLocksTest(DashTestFramework):
coin = coins.pop() coin = coins.pop()
asset_lock_tx = self.create_assetlock(coin, locked_1, pubkey) asset_lock_tx = self.create_assetlock(coin, locked_1, pubkey)
self.check_mempool_result(tx=asset_lock_tx, result_expected={'allowed': True}) self.check_mempool_result(tx=asset_lock_tx, result_expected={'allowed': True})
self.validate_credit_pool_balance(0) self.validate_credit_pool_balance(0)
txid_in_block = self.send_tx(asset_lock_tx) txid_in_block = self.send_tx(asset_lock_tx)
assert "assetLockTx" in node.getrawtransaction(txid_in_block, 1) assert "assetLockTx" in node.getrawtransaction(txid_in_block, 1)
self.validate_credit_pool_balance(0) self.validate_credit_pool_balance(0)
node.generate(1) node.generate(1)
assert_equal(self.get_credit_pool_balance(node=node_wallet), 0)
assert_equal(self.get_credit_pool_balance(node=node), locked_1) assert_equal(self.get_credit_pool_balance(node=node), locked_1)
self.log.info("Generate a number of blocks to ensure this is the longest chain for later in the test when we reconsiderblock") self.log.info("Generate a number of blocks to ensure this is the longest chain for later in the test when we reconsiderblock")
node.generate(12) node.generate(12)
@ -295,7 +324,7 @@ class AssetLocksTest(DashTestFramework):
self.create_and_check_block([extra_lock_tx], expected_error = 'bad-cbtx-assetlocked-amount') self.create_and_check_block([extra_lock_tx], expected_error = 'bad-cbtx-assetlocked-amount')
self.log.info("Mine a quorum...") self.log.info("Mine a quorum...")
self.mine_quorum() self.mine_quorum(llmq_type_name='llmq_test_platform', llmq_type=106, expected_connections=2, expected_members=3, expected_contributions=3, expected_complaints=0, expected_justifications=0, expected_commitments=3 )
self.validate_credit_pool_balance(locked_1) self.validate_credit_pool_balance(locked_1)
@ -349,7 +378,7 @@ class AssetLocksTest(DashTestFramework):
reason = "double copy") reason = "double copy")
self.log.info("Mining next quorum to check tx 'asset_unlock_tx_late' is still valid...") self.log.info("Mining next quorum to check tx 'asset_unlock_tx_late' is still valid...")
self.mine_quorum() self.mine_quorum(llmq_type_name="llmq_test_platform", llmq_type=106)
self.log.info("Checking credit pool amount is same...") self.log.info("Checking credit pool amount is same...")
self.validate_credit_pool_balance(locked_1 - 1 * COIN) self.validate_credit_pool_balance(locked_1 - 1 * COIN)
self.check_mempool_result(tx=asset_unlock_tx_late, result_expected={'allowed': True}) self.check_mempool_result(tx=asset_unlock_tx_late, result_expected={'allowed': True})
@ -369,7 +398,7 @@ class AssetLocksTest(DashTestFramework):
result_expected={'allowed': False, 'reject-reason' : 'bad-assetunlock-too-late'}) result_expected={'allowed': False, 'reject-reason' : 'bad-assetunlock-too-late'})
self.log.info("Checking that two quorums later it is too late because quorum is not active...") self.log.info("Checking that two quorums later it is too late because quorum is not active...")
self.mine_quorum() self.mine_quorum(llmq_type_name="llmq_test_platform", llmq_type=106)
self.log.info("Expecting new reject-reason...") self.log.info("Expecting new reject-reason...")
self.check_mempool_result(tx=asset_unlock_tx_too_late, 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-not-active-quorum'})
@ -427,7 +456,7 @@ class AssetLocksTest(DashTestFramework):
self.log.info("Fast forward to the next day to reset all current unlock limits...") self.log.info("Fast forward to the next day to reset all current unlock limits...")
self.slowly_generate_batch(blocks_in_one_day + 1) self.slowly_generate_batch(blocks_in_one_day + 1)
self.mine_quorum() self.mine_quorum(llmq_type_name="llmq_test_platform", llmq_type=106)
total = self.get_credit_pool_balance() total = self.get_credit_pool_balance()
while total <= 10_900 * COIN: while total <= 10_900 * COIN:

View File

@ -1155,6 +1155,7 @@ class DashTestFramework(BitcoinTestFramework):
for i in range(0, idx): for i in range(0, idx):
self.connect_nodes(i, idx) self.connect_nodes(i, idx)
# TODO: to let creating Evo Nodes without instant-send available
def dynamically_add_masternode(self, evo=False, rnd=None, should_be_rejected=False): def dynamically_add_masternode(self, evo=False, rnd=None, should_be_rejected=False):
mn_idx = len(self.nodes) mn_idx = len(self.nodes)