Skip to content

Commit 8a03767

Browse files
committed
feat!: replaced CSkipList to CRangesSet in credit pool
By design we can have more and more and more gaps in indexes list so far as we can not re-sign expired transaction of asset-unlock. CRangesList is protected from this situation
1 parent 2b948c9 commit 8a03767

File tree

3 files changed

+12
-34
lines changed

3 files changed

+12
-34
lines changed

src/evo/creditpool.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ static UnlockDataPerBlock GetDataFromUnlockTxes(const std::vector<CTransactionRe
7070

7171
std::string CCreditPool::ToString() const
7272
{
73-
return strprintf("CCreditPool(locked=%lld, currentLimit=%lld, nIndexes=%lld)",
74-
locked, currentLimit, indexes.Size());
73+
return strprintf("CCreditPool(locked=%lld, currentLimit=%lld)",
74+
locked, currentLimit);
7575
}
7676

7777
std::optional<CCreditPool> CCreditPoolManager::GetFromCache(const CBlockIndex* const block_index)
@@ -130,7 +130,7 @@ CCreditPool CCreditPoolManager::ConstructCreditPool(const CBlockIndex* const blo
130130
// If reading of previous block is not successfully, but
131131
// prev contains credit pool related data, something strange happened
132132
assert(prev.locked == 0);
133-
assert(prev.indexes.Size() == 0);
133+
assert(prev.indexes.IsEmpty());
134134

135135
CCreditPool emptyPool;
136136
AddToCache(block_index->GetBlockHash(), block_index->nHeight, emptyPool);
@@ -150,9 +150,9 @@ CCreditPool CCreditPoolManager::ConstructCreditPool(const CBlockIndex* const blo
150150
// Indexes should not be duplicated since genesis block, but the Unlock Amount
151151
// of withdrawal transaction is limited only by this window
152152
UnlockDataPerBlock blockData = GetDataFromUnlockTxes(block->vtx);
153-
CSkipSet indexes{std::move(prev.indexes)};
153+
CRangesSet indexes{std::move(prev.indexes)};
154154
if (std::any_of(blockData.indexes.begin(), blockData.indexes.end(), [&](const uint64_t index) { return !indexes.Add(index); })) {
155-
throw std::runtime_error(strprintf("%s: failed-getcreditpool-index-exceed", __func__));
155+
throw std::runtime_error(strprintf("%s: failed-getcreditpool-index-duplicated", __func__));
156156
}
157157

158158
const CBlockIndex* distant_block_index = block_index;
@@ -266,10 +266,6 @@ bool CCreditPoolDiff::Unlock(const CTransaction& tx, TxValidationState& state)
266266
return state.Invalid(TxValidationResult::TX_CONSENSUS, "failed-creditpool-unlock-duplicated-index");
267267
}
268268

269-
if (!pool.indexes.CanBeAdded(index)) {
270-
return state.Invalid(TxValidationResult::TX_CONSENSUS, "failed-creditpool-unlock-cant-add");
271-
}
272-
273269
newIndexes.insert(index);
274270
sessionUnlocked += toUnlock;
275271
return true;

src/evo/creditpool.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#include <sync.h>
1616
#include <threadsafety.h>
1717
#include <unordered_lru_cache.h>
18-
#include <util/skip_set.h>
18+
#include <util/ranges_set.h>
1919

2020
#include <optional>
2121
#include <unordered_set>
@@ -34,7 +34,7 @@ struct CCreditPool {
3434
// needs for logic of limits of unlocks
3535
CAmount currentLimit{0};
3636
CAmount latelyUnlocked{0};
37-
CSkipSet indexes{};
37+
CRangesSet indexes{};
3838

3939
std::string ToString() const;
4040

test/functional/feature_asset_locks.py

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -284,14 +284,6 @@ def run_test(self):
284284
self.validate_credit_pool_amount(locked_1)
285285

286286
self.log.info("Testing asset unlock...")
287-
asset_unlock_tx_index_too_far = self.create_assetunlock(10001, COIN, pubkey)
288-
tx_too_far_index = self.send_tx(asset_unlock_tx_index_too_far)
289-
node.generate(1)
290-
self.sync_all()
291-
self.mempool_size += 1
292-
self.check_mempool_size()
293-
self.log.info("Checking that `asset_unlock_tx_index_too_far` not mined yet...")
294-
self.ensure_tx_is_not_mined(tx_too_far_index)
295287

296288
self.log.info("Generating several txes by same quorum....")
297289
self.validate_credit_pool_amount(locked_1)
@@ -323,17 +315,11 @@ def run_test(self):
323315
self.mempool_size += 1
324316
self.check_mempool_size()
325317
self.validate_credit_pool_amount(locked_1)
326-
self.log.info("Mining one block - index '10001' can't be included in this block")
327318
node.generate(1)
328319
self.sync_all()
329320
self.validate_credit_pool_amount(locked_1 - COIN)
330321
self.mempool_size -= 1
331322
self.check_mempool_size()
332-
self.log.info("Tx should not be mined yet... mine one more block")
333-
node.generate(1)
334-
self.sync_all()
335-
self.mempool_size -= 1
336-
self.check_mempool_size()
337323
block_asset_unlock = node.getrawtransaction(asset_unlock_tx.rehash(), 1)['blockhash']
338324

339325
self.send_tx(asset_unlock_tx,
@@ -346,21 +332,17 @@ def run_test(self):
346332
expected_error = "bad-assetunlock-duplicated-index",
347333
reason = "double index")
348334

349-
self.log.info("Checking tx with too far index is mined too - it is not too far anymore...")
350-
self.validate_credit_pool_amount(locked_1 - 2 * COIN)
351-
self.nodes[0].getrawtransaction(tx_too_far_index, 1)['blockhash']
352-
353335
self.log.info("Mining next quorum to check tx 'asset_unlock_tx_late' is still valid...")
354336
self.mine_quorum()
355337
self.log.info("Checking credit pool amount is same...")
356-
self.validate_credit_pool_amount(locked_1 - 2 * COIN)
338+
self.validate_credit_pool_amount(locked_1 - 1 * COIN)
357339
self.check_mempool_result(tx=asset_unlock_tx_late, result_expected={'allowed': True})
358340
self.log.info("Checking credit pool amount still is same...")
359-
self.validate_credit_pool_amount(locked_1 - 2 * COIN)
341+
self.validate_credit_pool_amount(locked_1 - 1 * COIN)
360342
self.send_tx(asset_unlock_tx_late)
361343
node.generate(1)
362344
self.sync_all()
363-
self.validate_credit_pool_amount(locked_1 - 3 * COIN)
345+
self.validate_credit_pool_amount(locked_1 - 2 * COIN)
364346

365347
self.log.info("Generating many blocks to make quorum far behind (even still active)...")
366348
self.slowly_generate_batch(too_late_height - node.getblock(node.getbestblockhash())["height"] - 1)
@@ -385,15 +367,15 @@ def run_test(self):
385367
self.validate_credit_pool_amount(locked_1)
386368
for inode in self.nodes:
387369
inode.reconsiderblock(block_to_reconsider)
388-
self.validate_credit_pool_amount(locked_1 - 3 * COIN)
370+
self.validate_credit_pool_amount(locked_1 - 2 * COIN)
389371

390372
self.log.info("Forcibly mining asset_unlock_tx_too_late and ensure block is invalid...")
391373
self.create_and_check_block([asset_unlock_tx_too_late], expected_error = "bad-assetunlock-not-active-quorum")
392374

393375
node.generate(1)
394376
self.sync_all()
395377

396-
self.validate_credit_pool_amount(locked_1 - 3 * COIN)
378+
self.validate_credit_pool_amount(locked_1 - 2 * COIN)
397379
self.validate_credit_pool_amount(block_hash=block_hash_1, expected=locked_1)
398380

399381
self.log.info("Checking too big withdrawal... expected to not be mined")

0 commit comments

Comments
 (0)