Skip to content

Commit

Permalink
Merge PR #875 from 'nodech/txdb-reorg-open'
Browse files Browse the repository at this point in the history
  • Loading branch information
nodech committed Dec 11, 2023
2 parents c9e3985 + a1c72c2 commit 349d203
Show file tree
Hide file tree
Showing 5 changed files with 290 additions and 41 deletions.
4 changes: 4 additions & 0 deletions lib/wallet/records.js
Expand Up @@ -422,6 +422,10 @@ class MapRecord extends bio.Struct {
return this.wids.delete(wid);
}

has(wid) {
return this.wids.has(wid);
}

write(bw) {
bw.writeU32(this.wids.size);

Expand Down
49 changes: 44 additions & 5 deletions lib/wallet/txdb.js
Expand Up @@ -784,7 +784,6 @@ class TXDB {

/**
* Add transaction without a batch.
* @private
* @param {TX} tx
* @param {BlockMeta} [block]
* @returns {Promise<Details?>}
Expand Down Expand Up @@ -880,6 +879,11 @@ class TXDB {
if (!hash)
continue;

const wtx = await this.getTX(hash);

if (wtx.height !== -1)
return;

await this.remove(hash);
}
}
Expand Down Expand Up @@ -1041,6 +1045,7 @@ class TXDB {
}

await this.saveCredit(b, credit, path);
await this.watchOpensEarly(b, output);
}

// Handle names.
Expand Down Expand Up @@ -1278,6 +1283,8 @@ class TXDB {
// Commit the new state. The balance has updated.
const balance = await this.updateBalance(b, state);

this.unindexOpens(b, tx);

await b.write();

this.unlockTX(tx);
Expand Down Expand Up @@ -1533,6 +1540,14 @@ class TXDB {
if (tx.isCoinbase())
return this.removeRecursive(wtx);

// On unconfirm, if we already have OPEN txs in the pending list we
// remove transaction and it's descendants instead of storing them in
// the pending list. This follows the mempool behaviour where the first
// entries in the mempool will be the ones left, instead of txs coming
// from the block. This ensures consistency with the double open rules.
if (await this.isDoubleOpen(tx))
return this.removeRecursive(wtx);

return this.disconnect(wtx, wtx.getBlock());
}

Expand Down Expand Up @@ -1650,6 +1665,10 @@ class TXDB {
await this.saveCredit(b, credit, path);
}

// Unconfirm will also index OPENs as the transaction is now part of the
// wallet pending transactions.
this.indexOpens(b, tx);

// Undo name state.
await this.undoNameState(b, tx);

Expand Down Expand Up @@ -1834,12 +1853,33 @@ class TXDB {
}
}

/**
* Start tracking OPENs right away.
* This does not check if the name is owned by the wallet.
* @private
* @param {Batch} b
* @param {Output} tx
* @param {Path} path
* @returns {Promise}
*/

async watchOpensEarly(b, output) {
const {covenant} = output;

if (!covenant.isOpen())
return;

const nameHash = covenant.getHash(0);

if (!await this.wdb.hasNameMap(nameHash, this.wid))
await this.addNameMap(b, nameHash);
}

/**
* Handle incoming covenant.
* @param {Object} b
* @param {TX} tx
* @param {Number} i
* @param {Path} path
* @param {CoinView} view
* @param {Number} height
* @returns {Promise<Boolean>} updated
*/
Expand Down Expand Up @@ -1898,8 +1938,7 @@ class TXDB {
case types.OPEN: {
if (!path) {
// Are we "watching" this name?
const map = await this.wdb.getNameMap(nameHash);
if (!map || !map.wids.has(this.wid))
if (!await this.wdb.hasNameMap(nameHash, this.wid))
break;

const name = covenant.get(2);
Expand Down
30 changes: 29 additions & 1 deletion lib/wallet/walletdb.js
Expand Up @@ -1934,6 +1934,22 @@ class WalletDB extends EventEmitter {
return MapRecord.decode(data);
}

/**
* Does wdb have wallet map.
* @param {Buffer} key
* @param {Number} wid
* @returns {Promise<Boolean>}
*/

async hasMap(key, wid) {
const map = await this.getMap(key);

if (!map)
return false;

return map.has(wid);
}

/**
* Add wid to a wallet map.
* @param {Wallet} wallet
Expand Down Expand Up @@ -2125,6 +2141,17 @@ class WalletDB extends EventEmitter {
return this.getMap(layout.N.encode(nameHash));
}

/**
* Has wid in the wallet map.
* @param {Buffer} nameHash
* @param {Number} wid
* @returns {Promise<Boolean>}
*/

async hasNameMap(nameHash, wid) {
return this.hasMap(layout.N.encode(nameHash), wid);
}

/**
* Add wid to a wallet map.
* @param {Wallet} wallet
Expand Down Expand Up @@ -2224,7 +2251,7 @@ class WalletDB extends EventEmitter {
/**
* Revert TXDB to an older state.
* @param {Number} target
* @returns {Promise}
* @returns {Promise<Number>}
*/

async revert(target) {
Expand All @@ -2250,6 +2277,7 @@ class WalletDB extends EventEmitter {
});

this.logger.info('Rolled back %d WalletDB transactions.', total);
return total;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions test/mempool-invalidation-test.js
Expand Up @@ -148,8 +148,8 @@ describe('Mempool Invalidation', function() {
assert.strictEqual(await getNameState(name), states.OPENING);

assert.strictEqual(node.mempool.map.size, 0);
// we don't want coins to get stuck in the wallet.
wallet2.abandon(memopen.hash());
const pending = await wallet2.getPending();
assert.strictEqual(pending.length, 0);
});

it('should invalidate bids', async () => {
Expand Down

0 comments on commit 349d203

Please sign in to comment.