diff --git a/lib/wallet/http.js b/lib/wallet/http.js index 747f2f88a..c2b5d01aa 100644 --- a/lib/wallet/http.js +++ b/lib/wallet/http.js @@ -1326,15 +1326,17 @@ class HTTP extends Server { const options = TransactionOptions.fromValidator(valid, this.network); + const rawResource = resource.encode(); + if (broadcast) { // TODO: Add abort signal to close when request closes. - const tx = await req.wallet.sendUpdate(name, resource, options); + const tx = await req.wallet.sendUpdate(name, rawResource, options); return res.json(200, tx.getJSON(this.network)); } // TODO: Add create TX with locks for used Coins and/or // adds to the pending list. - const mtx = await req.wallet.createUpdate(name, resource, options); + const mtx = await req.wallet.createUpdate(name, rawResource, options); if (sign) await req.wallet.sign(mtx, options.passphrase); diff --git a/lib/wallet/rpc.js b/lib/wallet/rpc.js index 61ae0004d..10d159bda 100644 --- a/lib/wallet/rpc.js +++ b/lib/wallet/rpc.js @@ -2487,7 +2487,8 @@ class RPC extends RPCBase { async sendUpdate(args, help) { const opts = this._validateUpdate(args, help, 'sendupdate'); const wallet = this.wallet; - const tx = await wallet.sendUpdate(opts.name, opts.resource, { + const rawResource = opts.resource.encode(); + const tx = await wallet.sendUpdate(opts.name, rawResource, { account: opts.account }); @@ -2497,7 +2498,8 @@ class RPC extends RPCBase { async createUpdate(args, help) { const opts = this._validateUpdate(args, help, 'createupdate'); const wallet = this.wallet; - const mtx = await wallet.createUpdate(opts.name, opts.resource, { + const rawResource = opts.resource.encode(); + const mtx = await wallet.createUpdate(opts.name, rawResource, { paths: true, account: opts.account }); @@ -2813,7 +2815,8 @@ class RPC extends RPCBase { 'UPDATE action requires 2 arguments: name, data' ); const {name, resource} = this._validateUpdate(action); - actions.push({ type: type, args: [name, resource] }); + const rawResource = resource.encode(); + actions.push({ type: type, args: [name, rawResource] }); break; } case 'RENEW': { diff --git a/lib/wallet/wallet.js b/lib/wallet/wallet.js index f5920c22f..f2a3d938f 100644 --- a/lib/wallet/wallet.js +++ b/lib/wallet/wallet.js @@ -34,7 +34,6 @@ const MasterKey = require('./masterkey'); const policy = require('../protocol/policy'); const consensus = require('../protocol/consensus'); const rules = require('../covenants/rules'); -const {Resource} = require('../dns/resource'); const Claim = require('../primitives/claim'); const reserved = require('../covenants/reserved'); const {ownership} = require('../covenants/ownership'); @@ -2607,14 +2606,14 @@ class Wallet extends EventEmitter { * Make a register MTX. * @private * @param {String} name - * @param {Resource?} resource + * @param {Buffer?} rawResource * @param {MTX?} [mtx] * @returns {Promise} */ - async _makeRegister(name, resource, mtx) { + async _makeRegister(name, rawResource, mtx) { assert(typeof name === 'string'); - assert(!resource || (resource instanceof Resource)); + assert(!rawResource || Buffer.isBuffer(rawResource)); if (!rules.verifyName(name)) throw new Error(`Invalid name: ${name}.`); @@ -2661,18 +2660,14 @@ class Wallet extends EventEmitter { output.address = coin.address; output.value = ns.value; - let rawResource = EMPTY; + if (!rawResource) + rawResource = EMPTY; - if (resource) { - const raw = resource.encode(); - - if (raw.length > rules.MAX_RESOURCE_SIZE) + if (rawResource.length > rules.MAX_RESOURCE_SIZE) { throw new Error( - `Resource size (${raw.length}) exceeds maximum `+ + `Resource size (${rawResource.length}) exceeds maximum `+ `(${rules.MAX_RESOURCE_SIZE}) for name: ${name}.` ); - - rawResource = raw; } const blockHash = await this.wdb.getRenewalBlock(); @@ -2690,15 +2685,15 @@ class Wallet extends EventEmitter { /** * Make an update MTX. * @param {String} name - * @param {Resource} resource + * @param {Buffer} rawResource * @param {(Number|String)?} acct * @param {MTX?} [mtx] * @returns {Promise} */ - async makeUpdate(name, resource, acct, mtx) { + async makeUpdate(name, rawResource, acct, mtx) { assert(typeof name === 'string'); - assert(resource instanceof Resource); + assert(Buffer.isBuffer(rawResource)); if (!rules.verifyName(name)) throw new Error('Invalid name.'); @@ -2736,7 +2731,7 @@ class Wallet extends EventEmitter { const coin = credit.coin; if (coin.covenant.isReveal() || coin.covenant.isClaim()) - return this._makeRegister(name, resource, mtx); + return this._makeRegister(name, rawResource, mtx); if (ns.isExpired(height, network)) throw new Error(`Name has expired: ${name}.`); @@ -2755,15 +2750,13 @@ class Wallet extends EventEmitter { throw new Error(`Name is not registered: ${name}.`); } - const raw = resource.encode(); - - if (raw.length > rules.MAX_RESOURCE_SIZE) + if (rawResource.length > rules.MAX_RESOURCE_SIZE) throw new Error(`Resource exceeds maximum size: ${name}.`); const output = new Output(); output.address = coin.address; output.value = coin.value; - output.covenant.setUpdate(nameHash, ns.height, raw); + output.covenant.setUpdate(nameHash, ns.height, rawResource); if (!mtx) mtx = new MTX(); @@ -2777,14 +2770,14 @@ class Wallet extends EventEmitter { * Create and finalize an update * MTX without a lock. * @param {String} name - * @param {Resource} resource + * @param {Buffer} rawResource * @param {Object} options * @returns {Promise} */ - async _createUpdate(name, resource, options) { + async _createUpdate(name, rawResource, options) { const acct = options ? options.account : null; - const mtx = await this.makeUpdate(name, resource, acct); + const mtx = await this.makeUpdate(name, rawResource, acct); await this.fill(mtx, options); return this.finalize(mtx, options); } @@ -2811,14 +2804,14 @@ class Wallet extends EventEmitter { * Create and send an update * MTX without a lock. * @param {String} name - * @param {Resource} resource + * @param {Buffer} rawResource * @param {Object} options * @returns {Promise} */ - async _sendUpdate(name, resource, options) { + async _sendUpdate(name, rawResource, options) { const passphrase = options ? options.passphrase : null; - const mtx = await this._createUpdate(name, resource, options); + const mtx = await this._createUpdate(name, rawResource, options); return this.sendMTX(mtx, passphrase); } @@ -2826,15 +2819,15 @@ class Wallet extends EventEmitter { * Create and send an update * MTX with a lock. * @param {String} name - * @param {Resource} resource + * @param {Buffer} rawResource * @param {Object} options * @returns {Promise} */ - async sendUpdate(name, resource, options) { + async sendUpdate(name, rawResource, options) { const unlock = await this.fundLock.lock(); try { - return await this._sendUpdate(name, resource, options); + return await this._sendUpdate(name, rawResource, options); } finally { unlock(); } @@ -4003,8 +3996,8 @@ class Wallet extends EventEmitter { case 'UPDATE': { assert(args.length === 2, 'Bad arguments for UPDATE.'); const name = args[0]; - const resource = args[1]; - await this.makeUpdate(name, resource, acct, mtx); + const rawResource = args[1]; + await this.makeUpdate(name, rawResource, acct, mtx); break; } case 'RENEW': { diff --git a/test/anyone-can-renew-test.js b/test/anyone-can-renew-test.js index ee039bc4a..a2d49b317 100644 --- a/test/anyone-can-renew-test.js +++ b/test/anyone-can-renew-test.js @@ -127,7 +127,7 @@ describe('Anyone-can-renew address', function() { const resource = Resource.fromJSON({ records: [{type: 'TXT', txt: ['This name is ANYONE-CAN-RENEW']}] }); - await alice.sendUpdate(name, resource); + await alice.sendUpdate(name, resource.encode()); await mineBlocks(network.names.treeInterval); ns = await node.getNameStatus(nameHash); diff --git a/test/claim-test.js b/test/claim-test.js index 26cbc1392..91d2b436d 100644 --- a/test/claim-test.js +++ b/test/claim-test.js @@ -167,7 +167,7 @@ describe('Reserved Name Claims', function() { const resource = Resource.fromJSON({ records: [{type: 'TXT', txt: ['#CooperationGood']}] }); - const register = await wallet.sendUpdate('cloudflare', resource); + const register = await wallet.sendUpdate('cloudflare', resource.encode()); check(); await mineBlocks(1); check(); diff --git a/test/interactive-swap-test.js b/test/interactive-swap-test.js index 705418186..31f8c6db9 100644 --- a/test/interactive-swap-test.js +++ b/test/interactive-swap-test.js @@ -113,7 +113,7 @@ describe('Interactive name swap', function() { const resource = Resource.fromJSON({ records: [{type: 'TXT', txt: ['Contact Alice to buy this name!']}] }); - await alice.sendUpdate(name, resource); + await alice.sendUpdate(name, resource.encode()); await mineBlocks(network.names.treeInterval); }); @@ -292,7 +292,7 @@ describe('Interactive name swap', function() { const resource = Resource.fromJSON({ records: [{type: 'TXT', txt: ['Thanks Alice! --Bob']}] }); - await bob.sendUpdate(name, resource); + await bob.sendUpdate(name, resource.encode()); await mineBlocks(network.names.treeInterval); const actual = await node.chain.db.getNameState(nameHash); assert.bufferEqual(resource.encode(), actual.data); diff --git a/test/mempool-invalidation-test.js b/test/mempool-invalidation-test.js index 120d781e1..1a969dded 100644 --- a/test/mempool-invalidation-test.js +++ b/test/mempool-invalidation-test.js @@ -321,7 +321,8 @@ describe('Mempool Invalidation', function() { assert.strictEqual(await getNameState(name), states.CLOSED); - await wallet.sendUpdate(name, Resource.fromJSON({ records: [] })); + const res = Resource.fromJSON({ records: [] }); + await wallet.sendUpdate(name, res.encode()); for (let i = 0; i < network.names.renewalWindow - 2; i++) await mineBlock(node); diff --git a/test/mempool-reorg-test.js b/test/mempool-reorg-test.js index 16a870a83..2d2de61d7 100644 --- a/test/mempool-reorg-test.js +++ b/test/mempool-reorg-test.js @@ -41,9 +41,11 @@ describe('Mempool Covenant Reorg', function () { let counter = 0; function makeResource() { - return Resource.fromJSON({ + const res = Resource.fromJSON({ records: [{type: 'TXT', txt: [`${counter++}`]}] }); + + return res.encode(); } it('should fund wallet and win name', async () => { diff --git a/test/net-spv-test.js b/test/net-spv-test.js index 4a0d6cd84..974bf7577 100644 --- a/test/net-spv-test.js +++ b/test/net-spv-test.js @@ -122,16 +122,13 @@ describe('SPV', function() { await mineBlocks(biddingPeriod); await wallet.sendReveal(name); await mineBlocks(revealPeriod); - await wallet.sendUpdate( - name, - Resource.fromJSON( - { - records: [ - {type: 'NS', ns: 'one.'} - ] - } - ) - ); + const res = Resource.fromJSON({ + records: [ + {type: 'NS', ns: 'one.'} + ] + }); + + await wallet.sendUpdate(name, res.encode()); await mineBlocks(treeInterval + SAFE_ROOT); }); @@ -166,16 +163,13 @@ describe('SPV', function() { }); it('should update name data', async () => { - await wallet.sendUpdate( - name, - Resource.fromJSON( - { - records: [ - {type: 'NS', ns: 'two.'} - ] - } - ) - ); + const res = Resource.fromJSON({ + records: [ + {type: 'NS', ns: 'two.'} + ] + }); + + await wallet.sendUpdate(name, res.encode()); await mineBlocks(treeInterval + SAFE_ROOT); }); diff --git a/test/wallet-accounts-auction-test.js b/test/wallet-accounts-auction-test.js index 2244df580..7f036e3d9 100644 --- a/test/wallet-accounts-auction-test.js +++ b/test/wallet-accounts-auction-test.js @@ -5,7 +5,7 @@ const Network = require('../lib/protocol/network'); const FullNode = require('../lib/node/fullnode'); const Address = require('../lib/primitives/address'); const rules = require('../lib/covenants/rules'); -const Resource = require('../lib/dns/resource'); +const {Resource} = require('../lib/dns/resource'); const WalletClient = require('../lib/client/wallet'); const network = Network.get('regtest'); @@ -129,20 +129,20 @@ describe('Multiple accounts participating in same auction', function() { }); describe('UPDATE', function() { - const aliceResource = Resource.Resource.fromJSON({ + const aliceResource = Resource.fromJSON({ records: [ { type: 'TXT', txt: ['ALICE'] } - ]}); - const bobResource = Resource.Resource.fromJSON({ + ]}).encode(); + const bobResource = Resource.fromJSON({ records: [ { type: 'TXT', txt: ['BOB'] } - ]}); + ]}).encode(); it('should advance auction to REGISTER phase', async () => { await mineBlocks(network.names.revealPeriod); diff --git a/test/wallet-auction-test.js b/test/wallet-auction-test.js index 33ae3de32..772046051 100644 --- a/test/wallet-auction-test.js +++ b/test/wallet-auction-test.js @@ -58,6 +58,8 @@ const wdb = new WalletDB({ workers: workers }); +const EMPTY_RESOURCE = (new Resource()).encode(); + describe('Wallet Auction', function() { let wallet, wallet2; @@ -499,14 +501,17 @@ describe('Wallet Auction', function() { }); it('should REGISTER and fail duplicate register', async () => { - const register1 = await wallet.sendUpdate(name1, Resource.fromString('name1.1')); + const res1 = Resource.fromString('name1.1').encode(); + const register1 = await wallet.sendUpdate(name1, res1); assert(register1); - const register2 = await wallet.sendUpdate(name2, Resource.fromString('name2.1')); + const res2 = Resource.fromString('name2.1').encode(); + const register2 = await wallet.sendUpdate(name2, res2); assert(register2); let err; try { - await wallet.sendUpdate(name1, Resource.fromString('hello')); + const res = Resource.fromString('hello').encode(); + await wallet.sendUpdate(name1, res); } catch (e) { err = e; } @@ -517,19 +522,22 @@ describe('Wallet Auction', function() { await mineBlock([register1, register2]); // This becomes update. - const update = await wallet.sendUpdate(name2, Resource.fromString('name2.2')); + const res22 = Resource.fromString('name2.2').encode(); + const update = await wallet.sendUpdate(name2, res22); assert(update); await mineBlock([update]); }); it('should UPDATE and fail duplicate UPDATE', async () => { - const update = await wallet.sendUpdate(name1, Resource.fromString('name1.2')); + const res = Resource.fromString('name1.2').encode(); + const update = await wallet.sendUpdate(name1, res); assert(update); let err = null; try { - await wallet.sendUpdate(name1, Resource.fromString('name1.3')); + const res = Resource.fromString('name1.3').encode(); + await wallet.sendUpdate(name1, res); } catch (e) { err = e; } @@ -650,10 +658,10 @@ describe('Wallet Auction', function() { const name4 = rules.grindName(6, 0, network); const name5 = rules.grindName(7, 0, network); - const res1 = Resource.fromJSON({records: [{type: 'TXT', txt: ['one']}]}); - const res2 = Resource.fromJSON({records: [{type: 'TXT', txt: ['two']}]}); - const res3 = Resource.fromJSON({records: [{type: 'TXT', txt: ['three']}]}); - const res4 = Resource.fromJSON({records: [{type: 'TXT', txt: ['four']}]}); + const res1 = Resource.fromJSON({records: [{type: 'TXT', txt: ['one']}]}).encode(); + const res2 = Resource.fromJSON({records: [{type: 'TXT', txt: ['two']}]}).encode(); + const res3 = Resource.fromJSON({records: [{type: 'TXT', txt: ['three']}]}).encode(); + const res4 = Resource.fromJSON({records: [{type: 'TXT', txt: ['four']}]}).encode(); const mempool = []; wdb.send = (tx) => { @@ -1207,10 +1215,10 @@ describe('Wallet Auction', function() { const ns3 = await chain.db.getNameStateByName(name3); const ns4 = await chain.db.getNameStateByName(name4); - assert.bufferEqual(ns1.data, res1.encode()); - assert.bufferEqual(ns2.data, res2.encode()); + assert.bufferEqual(ns1.data, res1); + assert.bufferEqual(ns2.data, res2); assert.bufferEqual(ns3.data, Buffer.from([])); // revoked name data is cleared - assert.bufferEqual(ns4.data, res4.encode()); + assert.bufferEqual(ns4.data, res4); const coin1 = await wallet.getCoin(ns1.owner.hash, ns1.owner.index); assert(!coin1); // name was transferred out of wallet @@ -1556,10 +1564,11 @@ describe('Wallet Auction', function() { it('should send batches of REGISTERs', async () => { let count = 0; + for (let i = 1; i <= 8; i++) { const batch = []; for (let j = 1; j <= 100; j++) { - batch.push({ type: 'UPDATE', args: [names[count++], new Resource()]}); + batch.push({ type: 'UPDATE', args: [names[count++], EMPTY_RESOURCE]}); } await wallet.sendBatch(batch); await mineBlocks(1); @@ -1582,7 +1591,7 @@ describe('Wallet Auction', function() { it('should not batch too many UPDATEs', async () => { const batch = []; for (let i = 0; i < consensus.MAX_BLOCK_UPDATES + 1; i++) - batch.push({ type: 'UPDATE', args: [names[i], new Resource()]}); + batch.push({ type: 'UPDATE', args: [names[i], EMPTY_RESOURCE]}); await assert.rejects( wallet.createBatch(batch), diff --git a/test/wallet-balance-test.js b/test/wallet-balance-test.js index 664a2c603..91b2e8da4 100644 --- a/test/wallet-balance-test.js +++ b/test/wallet-balance-test.js @@ -112,7 +112,7 @@ const FINAL_PRICE_2 = 2e5; // less then 1e6/4 (2.5e5) // const BLIND_ONLY_3 = BLIND_AMOUNT_3 - BID_AMOUNT_3; // Empty resource -const EMPTY_RS = Resource.fromJSON({ records: [] }); +const EMPTY_RS = Resource.fromJSON({ records: [] }).encode(); /* * Wallet helpers diff --git a/test/wallet-deepclean-test.js b/test/wallet-deepclean-test.js index a9b6c0961..ced4f15c1 100644 --- a/test/wallet-deepclean-test.js +++ b/test/wallet-deepclean-test.js @@ -4,7 +4,7 @@ const assert = require('bsert'); const Network = require('../lib/protocol/network'); const FullNode = require('../lib/node/fullnode'); const Address = require('../lib/primitives/address'); -const Resource = require('../lib/dns/resource'); +const {Resource} = require('../lib/dns/resource'); const network = Network.get('regtest'); @@ -93,7 +93,7 @@ describe('Wallet Deep Clean', function() { await w.sendReveal(name, {account: 0}); await mineBlocks(network.names.revealPeriod); - const res = Resource.Resource.fromJSON({ + const res = Resource.fromJSON({ records: [ { type: 'TXT', @@ -102,7 +102,7 @@ describe('Wallet Deep Clean', function() { ] }); - await w.sendUpdate(name, res, {account: 0}); + await w.sendUpdate(name, res.encode(), {account: 0}); await w.sendRedeem(name, {account: 0}); await mineBlocks(network.names.treeInterval); } diff --git a/test/wallet-test.js b/test/wallet-test.js index 82ecb51a3..f256abc2d 100644 --- a/test/wallet-test.js +++ b/test/wallet-test.js @@ -2400,7 +2400,7 @@ describe('Wallet', function() { // Advance to close wdb.height += network.names.revealPeriod; - const resource = Resource.fromJSON({records: []}); + const resource = Resource.fromJSON({records: []}).encode(); const register = await wallet.sendUpdate(name, resource, {hardFee: fee}); uTXCount++; @@ -2779,7 +2779,7 @@ describe('Wallet', function() { // Advance to close wdb.height += network.names.revealPeriod; - const resource = Resource.fromJSON({records: []}); + const resource = Resource.fromJSON({records: []}).encode(); const register = await wallet.createUpdate(name, resource, {hardFee: fee}); // Check @@ -3174,7 +3174,7 @@ describe('Wallet', function() { records: [{type: 'NS', ns: 'ns1.easyhandshake.com.'}] }); - update = await wallet.sendUpdate('cloudflare', records); + update = await wallet.sendUpdate('cloudflare', records.encode()); const entry = nextEntry(wdb); await wdb.addBlock(entry, [update]); @@ -3558,7 +3558,7 @@ describe('Wallet', function() { it('should send and confirm REGISTER', async () => { const resource = Resource.fromJSON({ records: [] }); - const register = await wallet.sendUpdate(name, resource, { + const register = await wallet.sendUpdate(name, resource.encode(), { hardFee: fee }); uTXCount++;