diff --git a/lib/wallet/wallet.js b/lib/wallet/wallet.js index b2ed019cb..d60a76bb4 100644 --- a/lib/wallet/wallet.js +++ b/lib/wallet/wallet.js @@ -3039,15 +3039,21 @@ class Wallet extends EventEmitter { /** * Make a revoke MTX. * @param {String} name + * @param {String|Number} acct * @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); @@ -3063,6 +3069,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}".`); @@ -3106,7 +3115,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); } @@ -3137,7 +3147,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 125616f3a..34515512b 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); + }); + }); });