diff --git a/lib/wallet/wallet.js b/lib/wallet/wallet.js index b89e94aa2f..289b709f2b 100644 --- a/lib/wallet/wallet.js +++ b/lib/wallet/wallet.js @@ -3036,12 +3036,17 @@ class Wallet extends EventEmitter { * @returns {MTX} */ - async makeRevoke(name) { + async makeRevoke(name, acct) { assert(typeof name === 'string'); if (!rules.verifyName(name)) throw new Error('Invalid name.'); + if (acct != null) { + assert((acct >>> 0) === acct || typeof acct === 'string'); + acct = await this.getAccountIndex(acct); + } + const rawName = Buffer.from(name, 'ascii'); const nameHash = rules.hashName(rawName); const ns = await this.getNameState(nameHash); @@ -3057,6 +3062,9 @@ class Wallet extends EventEmitter { if (!coin) throw new Error(`Wallet does not own: "${name}".`); + if (acct != null && !await this.txdb.hasCoinByAccount(acct, hash, index)) + throw new Error(`Account does not own: "${name}".`); + // Is local? if (coin.height < ns.height) throw new Error(`Wallet does not own: "${name}".`); @@ -3100,7 +3108,8 @@ class Wallet extends EventEmitter { */ async _createRevoke(name, options) { - const mtx = await this.makeRevoke(name); + const acct = options ? options.account : null; + const mtx = await this.makeRevoke(name, acct); await this.fill(mtx, options); return this.finalize(mtx, options); } @@ -3131,7 +3140,7 @@ class Wallet extends EventEmitter { async _sendRevoke(name, options) { const passphrase = options ? options.passphrase : null; - const mtx = await this._createRevoke(name); + const mtx = await this._createRevoke(name, options); return this.sendMTX(mtx, passphrase); } diff --git a/test/wallet-accounts-auction-test.js b/test/wallet-accounts-auction-test.js index 125616f3a9..34515512bd 100644 --- a/test/wallet-accounts-auction-test.js +++ b/test/wallet-accounts-auction-test.js @@ -366,4 +366,37 @@ describe('Multiple accounts participating in same auction', function() { assert.strictEqual(node.mempool.map.size, 0); }); }); + + describe('REVOKE', function() { + it('should reject REVOKE from wrong account', async () => { + await assert.rejects(async () => { + await wallet.sendRevoke(name, {account: 'bob'}); + }, { + name: 'Error', + message: `Account does not own: "${name}".` + }); + }); + + it('should send REVOKE from correct account', async () => { + const tx = await wallet.sendRevoke(name, {account: 0}); + assert(tx); + + await wallet.abandon(tx.hash()); + + assert.strictEqual(node.mempool.map.size, 1); + await node.mempool.reset(); + assert.strictEqual(node.mempool.map.size, 0); + }); + + it('should send REVOKE from correct account automatically', async () => { + const tx = await wallet.sendRevoke(name); + assert(tx); + + await wallet.abandon(tx.hash()); + + assert.strictEqual(node.mempool.map.size, 1); + await node.mempool.reset(); + assert.strictEqual(node.mempool.map.size, 0); + }); + }); });