feat: update limit of withdrawals to flat 2000 starting from v22

This commit is contained in:
Konstantin Akimov 2024-10-28 12:15:15 +07:00
parent 25c3355053
commit 31ca8a497a
No known key found for this signature in database
GPG Key ID: 2176C4A5D01EA524
4 changed files with 35 additions and 11 deletions

View File

@ -812,9 +812,9 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].bit = 11; consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].bit = 11;
consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nStartTime = 0; consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nWindowSize = 300; consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nWindowSize = 900;
consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nThresholdStart = 300 / 5 * 4; // 80% of 12 consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nThresholdStart = 900 / 5 * 4; // 80% of window size
consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nThresholdMin = 300 / 5 * 3; // 60% of 7 consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nThresholdMin = 900 / 5 * 3; // 60% of window size
consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nFalloffCoeff = 5; // this corresponds to 10 periods consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].nFalloffCoeff = 5; // this corresponds to 10 periods
consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].useEHF = true; consensus.vDeployments[Consensus::DEPLOYMENT_WITHDRAWALS].useEHF = true;

View File

@ -171,14 +171,18 @@ CCreditPool CCreditPoolManager::ConstructCreditPool(const CBlockIndex* const blo
} }
} }
// Unlock limits are # max(100, min(.10 * assetlockpool, 1000)) inside window
CAmount currentLimit = locked; CAmount currentLimit = locked;
const CAmount latelyUnlocked = prev.latelyUnlocked + blockData.unlocked - distantUnlocked; const CAmount latelyUnlocked = prev.latelyUnlocked + blockData.unlocked - distantUnlocked;
if (DeploymentActiveAt(*block_index, Params().GetConsensus(), Consensus::DEPLOYMENT_WITHDRAWALS)) {
currentLimit = std::min(currentLimit, LimitAmountV22);
} else {
// Unlock limits in pre-v22 are max(100, min(.10 * assetlockpool, 1000)) inside window
if (currentLimit + latelyUnlocked > LimitAmountLow) { if (currentLimit + latelyUnlocked > LimitAmountLow) {
currentLimit = std::max(LimitAmountLow, locked / 10) - latelyUnlocked; currentLimit = std::max(LimitAmountLow, locked / 10) - latelyUnlocked;
if (currentLimit < 0) currentLimit = 0; if (currentLimit < 0) currentLimit = 0;
} }
currentLimit = std::min(currentLimit, LimitAmountHigh - latelyUnlocked); currentLimit = std::min(currentLimit, LimitAmountHigh - latelyUnlocked);
}
assert(currentLimit >= 0); assert(currentLimit >= 0);

View File

@ -117,6 +117,7 @@ public:
static constexpr int LimitBlocksToTrace = 576; static constexpr int LimitBlocksToTrace = 576;
static constexpr CAmount LimitAmountLow = 100 * COIN; static constexpr CAmount LimitAmountLow = 100 * COIN;
static constexpr CAmount LimitAmountHigh = 1000 * COIN; static constexpr CAmount LimitAmountHigh = 1000 * COIN;
static constexpr CAmount LimitAmountV22 = 2000 * COIN;
explicit CCreditPoolManager(CEvoDB& _evoDb); explicit CCreditPoolManager(CEvoDB& _evoDb);

View File

@ -273,7 +273,7 @@ class AssetLocksTest(DashTestFramework):
self.test_asset_unlocks(node_wallet, node, pubkey) self.test_asset_unlocks(node_wallet, node, pubkey)
self.test_withdrawal_limits(node_wallet, node, pubkey) self.test_withdrawal_limits(node_wallet, node, pubkey)
self.test_mn_rr(node_wallet, node, pubkey) self.test_mn_rr(node_wallet, node, pubkey)
self.test_withdrawal_fork(node_wallet, pubkey) self.test_withdrawal_fork(node_wallet, node, pubkey)
def test_asset_locks(self, node_wallet, node, pubkey): def test_asset_locks(self, node_wallet, node, pubkey):
@ -466,7 +466,9 @@ class AssetLocksTest(DashTestFramework):
def test_withdrawal_limits(self, node_wallet, node, pubkey): def test_withdrawal_limits(self, node_wallet, node, pubkey):
self.log.info("Testing withdrawal limits...") self.log.info("Testing withdrawal limits before v22 'withdrawal fork'...")
assert not softfork_active(node_wallet, 'withdrawals')
self.log.info("Too big withdrawal is expected to not be mined") self.log.info("Too big withdrawal is expected to not be mined")
asset_unlock_tx_full = self.create_assetunlock(201, 1 + self.get_credit_pool_balance(), pubkey) asset_unlock_tx_full = self.create_assetunlock(201, 1 + self.get_credit_pool_balance(), pubkey)
@ -615,6 +617,7 @@ class AssetLocksTest(DashTestFramework):
self.log.info("Checking that credit pool is not changed...") self.log.info("Checking that credit pool is not changed...")
assert_equal(new_total, self.get_credit_pool_balance()) assert_equal(new_total, self.get_credit_pool_balance())
self.check_mempool_size() self.check_mempool_size()
assert not softfork_active(node_wallet, 'withdrawals')
def test_mn_rr(self, node_wallet, node, pubkey): def test_mn_rr(self, node_wallet, node, pubkey):
@ -645,8 +648,9 @@ class AssetLocksTest(DashTestFramework):
self.generate(node, 1) self.generate(node, 1)
assert_equal(locked, self.get_credit_pool_balance()) assert_equal(locked, self.get_credit_pool_balance())
def test_withdrawal_fork(self, node_wallet, pubkey): def test_withdrawal_fork(self, node_wallet, node, pubkey):
self.log.info("Testing asset unlock after 'withdrawal' activation...") self.log.info("Testing asset unlock after 'withdrawal' activation...")
self.activate_by_name('withdrawals')
assert softfork_active(node_wallet, 'withdrawals') assert softfork_active(node_wallet, 'withdrawals')
index = 501 index = 501
@ -684,6 +688,21 @@ class AssetLocksTest(DashTestFramework):
self.mine_quorum_2_nodes(llmq_type_name="llmq_test_platform", llmq_type=106) 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'}) self.check_mempool_result(tx=asset_unlock_tx, result_expected={'allowed': False, 'reject-reason': 'bad-assetunlock-too-old-quorum'})
asset_unlock_tx = self.create_assetunlock(520, 2000 * COIN + 1, pubkey)
txid_in_block = self.send_tx(asset_unlock_tx)
self.generate(node, 1)
self.ensure_tx_is_not_mined(txid_in_block)
asset_unlock_tx = self.create_assetunlock(521, 2000 * COIN, pubkey)
txid_in_block = self.send_tx(asset_unlock_tx)
self.generate(node, 1)
block = node.getblock(node.getbestblockhash())
assert txid_in_block in block['tx']
asset_unlock_tx = self.create_assetunlock(522, COIN, pubkey)
txid_in_block = self.send_tx(asset_unlock_tx)
self.generate(node, 1)
self.ensure_tx_is_not_mined(txid_in_block)
if __name__ == '__main__': if __name__ == '__main__':
AssetLocksTest().main() AssetLocksTest().main()