Skip to content

Commit

Permalink
Merge branch 'pruning' of https://github.com/kajoseph/bitcore
Browse files Browse the repository at this point in the history
  • Loading branch information
kajoseph committed Jan 12, 2024
2 parents 8b1e2bf + f90fa20 commit daaea28
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 16 deletions.
20 changes: 13 additions & 7 deletions packages/bitcore-node/src/services/pruning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,15 @@ export class PruningService {
const count = await this.transactionModel.collection.countDocuments({
chain,
network,
blockHeight: -1,
blockHeight: SpentHeightIndicators.pending,
blockTimeNormalized: { $lt: oldTime }
});
logger.info(`Found ${count} outdated ${chain} ${network} mempool txs`);
let rmCount = 0;
await new Promise((resolve, reject) => {
this.transactionModel.collection
.find({ chain, network, blockHeight: -1, blockTimeNormalized: { $lt: oldTime } })
.sort({ chain: 1, network: 1, blockTimeNormalized: 1 })
.find({ chain, network, blockHeight: SpentHeightIndicators.pending, blockTimeNormalized: { $lt: oldTime } })
.sort(count > 5000 ? { chain: 1, network: 1, blockTimeNormalized: 1 } : {})
.pipe(
new Transform({
objectMode: true,
Expand Down Expand Up @@ -184,12 +184,12 @@ export class PruningService {
const count = await this.transactionModel.collection.countDocuments({
chain,
network,
blockHeight: -3
blockHeight: SpentHeightIndicators.conflicting
});
logger.info(`Found ${count} invalid ${chain} ${network} txs`);
await new Promise((resolve, reject) => {
this.transactionModel.collection
.find({ chain, network, blockHeight: -3 })
.find({ chain, network, blockHeight: SpentHeightIndicators.conflicting })
.pipe(
new Transform({
objectMode: true,
Expand Down Expand Up @@ -256,8 +256,14 @@ export class PruningService {
return;
}
return Promise.all([
this.transactionModel.collection.deleteMany({ chain, network, txid: { $in: txids }, blockHeight: SpentHeightIndicators.pending }),
this.coinModel.collection.deleteMany({ chain, network, mintTxid: { $in: txids }, mintHeight: SpentHeightIndicators.pending }),
this.transactionModel.collection.updateMany(
{ chain, network, txid: { $in: txids }, blockHeight: SpentHeightIndicators.pending },
{ $set: { blockHeight: SpentHeightIndicators.expired } }
),
this.coinModel.collection.updateMany(
{ chain, network, mintTxid: { $in: txids }, mintHeight: SpentHeightIndicators.pending },
{ $set: { mintHeight: SpentHeightIndicators.expired } }
),
this.coinModel.collection.updateMany(
{ chain, network, spentTxid: { $in: txids }, spentHeight: SpentHeightIndicators.pending },
{ $set: { spentTxid: null, spentHeight: SpentHeightIndicators.unspent } }
Expand Down
7 changes: 6 additions & 1 deletion packages/bitcore-node/src/types/Coin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,10 @@ export const enum SpentHeightIndicators {
/**
* An internal error occurred. (The database appears to be inconsistent.)
*/
error = -4
error = -4,

/**
* The coin was minted by a transaction that has expired from the mempool.
*/
expired = -5
}
Original file line number Diff line number Diff line change
Expand Up @@ -160,18 +160,20 @@ describe('Pruning Service', function() {
expect(count).eq(1);
await Pruning.processOldMempoolTxs(chain, network, 29);

const shouldBeGoneTx = await TransactionStorage.collection
const shouldBeExpiredTx = await TransactionStorage.collection
.find({ chain, network, txid: { $in: [oldMempoolTx.txid] } })
.toArray();
const shouldBeGoneCoins = await CoinStorage.collection
const shouldBeExpiredCoins = await CoinStorage.collection
.find({ chain, network, mintTxid: { $in: [oldMempoolTxOutput.mintTxid, oldMempoolTx2Output.mintTxid] } })
.toArray();
const parentTxOutputs = await CoinStorage.collection
.find({ chain, network, mintTxid: parentTxOutput1.mintTxid })
.toArray();

expect(shouldBeGoneTx.length).eq(0);
expect(shouldBeGoneCoins.length).eq(0);
expect(shouldBeExpiredTx.length).eq(1);
expect(shouldBeExpiredTx.every(tx => tx.blockHeight === -5)).to.equal(true);
expect(shouldBeExpiredCoins.length).eq(2);
expect(shouldBeExpiredCoins.every(coin => coin.mintHeight === -5)).to.equal(true);
expect(parentTxOutputs.length).eq(2);
expect(parentTxOutputs.filter(coin => coin.spentHeight === -2).length).to.equal(1);
});
Expand All @@ -195,15 +197,19 @@ describe('Pruning Service', function() {
expect(count).eq(3);
await Pruning.processOldMempoolTxs(chain, network, 29);

const shouldBeGoneTx = await TransactionStorage.collection
const processedTxs = await TransactionStorage.collection
.find({ chain, network, txid: { $in: [modTxid(oldMempoolTx.txid, 0), modTxid(oldMempoolTx.txid, 1), modTxid(oldMempoolTx.txid, 2)] } })
.toArray();
const shouldBeGoneCoins = await CoinStorage.collection
const processedCoins = await CoinStorage.collection
.find({ chain, network, mintTxid: { $in: [modTxid(oldMempoolTxOutput.mintTxid, 0), modTxid(oldMempoolTx2Output.mintTxid, 0), modTxid(oldMempoolTxOutput.mintTxid, 1), modTxid(oldMempoolTx2Output.mintTxid, 1), modTxid(oldMempoolTxOutput.mintTxid, 2), modTxid(oldMempoolTx2Output.mintTxid, 2)] } })
.toArray();

expect(shouldBeGoneTx.length).eq(1);
expect(shouldBeGoneCoins.length).eq(2);
expect(processedTxs.length).eq(3);
expect(processedTxs.filter(tx => tx.blockHeight === -5).length).eq(2);
expect(processedTxs.filter(tx => tx.blockHeight === -1).length).eq(1); // still in mempool
expect(processedCoins.length).eq(6);
expect(processedCoins.filter(coin => coin.mintHeight === -5).length).eq(4);
expect(processedCoins.filter(coin => coin.mintHeight === -1).length).eq(2); // still in mempool
});

it('should skip removing transactions on rpc error', async () => {
Expand Down

0 comments on commit daaea28

Please sign in to comment.