diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e585cf3e..3543fcd8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -**When upgrading to this version of hsd, you must pass `--wallet-migrate=3` when +**When upgrading to this version of hsd, you must pass `--wallet-migrate=4` when you run it for the first time.** ### Primitives @@ -72,7 +72,18 @@ process and allows parallel rescans. conflicting transactions) - Add options to `getNames` for passing `own`. - Rename `createAuctionTxs` to `createAuctionTXs`. - + - All `bid` serializations will include `height` of the bid. (`-1` if + it was migrated not-owned bid) + - `GET /wallet/:id/auction` (`getAuctions`) + - `GET /wallet/:id/auction/:name` (`getAuctionByName`) + - `GET /wallet/:id/bid` (`getBids`) + - `GET /wallet/:id/bid/:name` (`getBidsByName`) + - All `reveal` serializations will include `bidPrevout` of the bid. (`null` if + it was migrated not-owned reveal) + - `GET /wallet/:id/auction` (`getAuctions`) + - `GET /wallet/:id/auction/:name` (`getAuctionByName`) + - `GET /wallet/:id/reveal` (`getReveals`) + - `GET /wallet/:id/reveal/:name` (`getRevealsByName`) ## v6.0.0 diff --git a/lib/wallet/layout.js b/lib/wallet/layout.js index 43deba732..11059d3b8 100644 --- a/lib/wallet/layout.js +++ b/lib/wallet/layout.js @@ -126,6 +126,7 @@ exports.wdb = { * U[tx-hash] -> name undo record (name undo record by tx hash) * i[name-hash][tx-hash][index] -> bid (BlindBid by name + tx + index) * B[name-hash][tx-hash][index] -> reveal (BidReveal by name + tx + index) + * E[name-hash][tx-hash][index] - bid to reveal out (by bid txhash + index) * v[blind-hash] -> blind (Blind Value by blind hash) * o[name-hash] -> tx hash OPEN only (tx hash by name hash) */ @@ -163,6 +164,7 @@ exports.txdb = { U: bdb.key('U', ['hash256']), i: bdb.key('i', ['hash256', 'hash256', 'uint32']), B: bdb.key('B', ['hash256', 'hash256', 'uint32']), + E: bdb.key('E', ['hash256', 'hash256', 'uint32']), v: bdb.key('v', ['hash256']), o: bdb.key('o', ['hash256']) }; diff --git a/lib/wallet/migrations.js b/lib/wallet/migrations.js index 9eeb07f54..9b49bd4c9 100644 --- a/lib/wallet/migrations.js +++ b/lib/wallet/migrations.js @@ -19,6 +19,8 @@ const WalletKey = require('./walletkey'); const Path = require('./path'); const Script = require('../script/script'); const MapRecord = require('./records').MapRecord; +const Outpoint = require('../primitives/outpoint'); +const TX = require('../primitives/tx'); const AbstractMigration = require('../migrations/migration'); const { MigrationResult, @@ -27,6 +29,10 @@ const { oldLayout } = require('../migrations/migrator'); const layouts = require('./layout'); +const wlayout = layouts.wdb; + +/** @typedef {import('bdb').DB} DB */ +/** @typedef {import('./walletdb')} WalletDB */ /** * Switch to new migrations layout. @@ -54,7 +60,7 @@ class MigrateMigrations extends AbstractMigration { /** * Actual migration - * @param {Batch} b + * @param {DB.Batch} b * @returns {Promise} */ @@ -468,6 +474,249 @@ class MigrateTXDBBalances extends AbstractMigration { } } +/** + * Applies to WalletDB v2 + * Migrate bid reveal entries. + * - Adds height to the blind bid entries. + * - NOTE: This can not be recovered if the bid is not owned by the wallet. + * Wallet does not store transactions for not-owned bids. + * - Add Bid Outpoint information to the reveal (BidReveal) entries. + * - NOTE: This information can not be recovered for not-owned reveals. + * Wallet does not store transactions for not-owned reveals. + * - Add new BID -> REVEAL index. (layout.E) + * - NOTE: This information can not be recovered for not-owned reveals. + * Wallet does not store transactions for not-owned reveals. + * + */ + +class MigrateBidRevealEntries extends AbstractMigration { + /** + * Create Bid Reveal Entries migration object. + * @param {WalletMigratorOptions} options + * @constructor + */ + + constructor(options) { + super(options); + + this.options = options; + this.logger = options.logger.context('bid-reveal-entries-migration'); + this.db = options.db; + this.ldb = options.ldb; + this.layout = MigrateBidRevealEntries.layout(); + } + + /** + * We always migrate. + * @returns {Promise} + */ + + async check() { + return types.MIGRATE; + } + + /** + * Actual migration + * @param {DB.Batch} b + * @param {WalletMigrationResult} pending + * @returns {Promise} + */ + + async migrate(b, pending) { + /** @type {Number[]} */ + const wids = await this.ldb.keys({ + gte: wlayout.W.min(), + lte: wlayout.W.max(), + parse: key => wlayout.W.decode(key)[0] + }); + + for (const wid of wids) { + await this.migrateReveals(wid); + await this.migrateBids(wid); + } + + this.db.writeVersion(b, 3); + } + + /** + * Migrate reveals and index Bid2Reveal + * @param {Number} wid + * @returns {Promise} + */ + + async migrateReveals(wid) { + const txlayout = this.layout.txdb; + const prefix = txlayout.prefix.encode(wid); + const bucket = this.ldb.bucket(prefix); + const emptyOutpoint = new Outpoint(); + + const reveals = bucket.iterator({ + gte: txlayout.B.min(), + lte: txlayout.B.max(), + values: true + }); + + for await (const {key, value} of reveals) { + const b = bucket.batch(); + const [nameHash, txHash, txIndex] = txlayout.B.decode(key); + const nameLen = value[0]; + const totalOld = nameLen + 1 + 13; + const totalNew = nameLen + 1 + 13 + 36; + + // allow migration to be interrupted in the middle. + assert(value.length === totalOld || value.length === totalNew); + + // skip if already migrated. + if (value.length === totalNew) + continue; + + const owned = value[nameLen + 1 + 12]; + const rawTXRecord = await bucket.get(txlayout.t.encode(txHash)); + assert(owned && rawTXRecord || !owned); + + // We can not index the bid link and bid2reveal index if + // the transaction is not owned by the wallet. + // But we need to put null outpoint to the reveal for serialization. + if (!owned) { + const newReveal = Buffer.concat([value, emptyOutpoint.encode()]); + assert(newReveal.length === totalNew); + b.put(key, newReveal); + await b.write(); + continue; + } + + const reader = bio.read(rawTXRecord); + const tx = TX.fromReader(reader); + assert(tx.inputs[txIndex]); + + const bidPrevout = tx.inputs[txIndex].prevout; + const bidKey = txlayout.i.encode( + nameHash, bidPrevout.hash, bidPrevout.index); + const bidRecord = await bucket.get(bidKey); + // ensure bid exists. + assert(bidRecord); + + const newReveal = Buffer.concat([value, bidPrevout.encode()]); + assert(newReveal.length === totalNew); + // update reveal with bid outpoint. + b.put(key, newReveal); + // index bid to reveal. + b.put(txlayout.E.encode(nameHash, bidPrevout.hash, bidPrevout.index), + (new Outpoint(txHash, txIndex)).encode()); + await b.write(); + } + } + + /** + * Migrate bids, add height to the entries. + * @param {Number} wid + * @returns {Promise} + */ + + async migrateBids(wid) { + const txlayout = this.layout.txdb; + const prefix = txlayout.prefix.encode(wid); + const bucket = this.ldb.bucket(prefix); + + const bids = bucket.iterator({ + gte: txlayout.i.min(), + lte: txlayout.i.max(), + values: true + }); + + /** + * @param {Buffer} blindBid + * @param {Number} height + * @returns {Buffer} + */ + + const reencodeBlindBid = (blindBid, height) => { + const nameLen = blindBid[0]; + const totalOld = nameLen + 1 + 41; + const totalNew = nameLen + 1 + 41 + 4; + assert(blindBid.length === totalOld); + + const newBlindBid = Buffer.alloc(totalNew); + // copy everything before expected height place. + blindBid.copy(newBlindBid, 0, 0, totalOld - 1); + // copy height. + bio.encoding.writeU32(newBlindBid, height, totalOld - 1); + // copy last byte (owned flag). + blindBid.copy(newBlindBid, totalNew - 1, totalOld - 1); + + return newBlindBid; + }; + + for await (const {key, value} of bids) { + const b = bucket.batch(); + const [,txHash] = txlayout.i.decode(key); + const nameLen = value[0]; + const totalNew = nameLen + 1 + 41 + 4; + + // allow migration to be interrupted in the middle. + if (totalNew === value.length) + continue; + + const owned = value[nameLen + 1 + 40]; + if (!owned) { + const height = 0xffffffff; // -1 + const newValue = reencodeBlindBid(value, height); + b.put(key, newValue); + await b.write(); + continue; + } + + const rawTXRecord = await bucket.get(txlayout.t.encode(txHash)); + assert(rawTXRecord); + + const br = bio.read(rawTXRecord); + TX.fromReader(br); + // skip mtime. + br.seek(4); + + const hasBlock = br.readU8() === 1; + // We only index the bid in blocks, not in mempool. + assert(hasBlock); + + // skip hash. + br.seek(32); + const height = br.readU32(); + const newValue = reencodeBlindBid(value, height); + b.put(key, newValue); + + await b.write(); + } + } + + static info() { + return { + name: 'Bid reveal entries migration', + description: 'Migrate bids and reveals to link each other.' + }; + } + + static layout() { + return { + wdb: { + V: bdb.key('V'), + // W[wid] -> wallet id + W: bdb.key('W', ['uint32']) + }, + txdb: { + prefix: bdb.key('t', ['uint32']), + // t[tx-hash] -> extended tx (Read only) + t: bdb.key('t', ['hash256']), + // i[name-hash][tx-hash][index] -> txdb.BlindBid + i: bdb.key('i', ['hash256', 'hash256', 'uint32']), + // B[name-hash][tx-hash][index] -> txdb.BidReveal + B: bdb.key('B', ['hash256', 'hash256', 'uint32']), + // E[name-hash][tx-hash][index] -> bid to reveal out. + E: bdb.key('E', ['hash256', 'hash256', 'uint32']) + } + }; + } +} + /** * Wallet migration results. * @alias module:blockchain.WalletMigrationResult @@ -548,12 +797,14 @@ class WalletMigratorOptions { this.migrateFlag = -1; this.dbVersion = 0; + /** @type {WalletDB} */ this.db = null; + /** @type {DB} */ this.ldb = null; this.layout = layouts.wdb; - if (options) - this.fromOptions(options); + assert(options); + this.fromOptions(options); } /** @@ -603,7 +854,8 @@ exports.migrations = { 0: MigrateMigrations, 1: MigrateChangeAddress, 2: MigrateAccountLookahead, - 3: MigrateTXDBBalances + 3: MigrateTXDBBalances, + 4: MigrateBidRevealEntries }; // Expose migrations @@ -611,5 +863,6 @@ exports.MigrateChangeAddress = MigrateChangeAddress; exports.MigrateMigrations = MigrateMigrations; exports.MigrateAccountLookahead = MigrateAccountLookahead; exports.MigrateTXDBBalances = MigrateTXDBBalances; +exports.MigrateBidRevealEntries = MigrateBidRevealEntries; module.exports = exports; diff --git a/lib/wallet/txdb.js b/lib/wallet/txdb.js index 2d92e6bd1..9ad1a4cf3 100644 --- a/lib/wallet/txdb.js +++ b/lib/wallet/txdb.js @@ -550,6 +550,7 @@ class TXDB { bb.lockup = options.lockup; bb.blind = options.blind; bb.own = options.own; + bb.height = options.height; b.put(layout.i.encode(nameHash, hash, index), bb.encode()); } @@ -646,23 +647,67 @@ class TXDB { return brv; } + /** + * Get reveal by bid outpoint. + * @param {Buffer} nameHash + * @param {Outpoint} bidOut + * @returns {Promise} + */ + + async getRevealByBid(nameHash, bidOut) { + const rawOutpoint = await this.bucket.get( + layout.E.encode(nameHash, bidOut.hash, bidOut.index)); + + if (!rawOutpoint) + return null; + + const outpoint = Outpoint.decode(rawOutpoint); + return this.getReveal(nameHash, outpoint); + } + + /** + * Get bid by reveal outpoint. + * @param {Buffer} nameHash + * @param {Outpoint} revealOut + * @returns {Promise} + */ + + async getBidByReveal(nameHash, revealOut) { + const reveal = await this.getReveal(nameHash, revealOut); + + if (!reveal) + return null; + + return this.getBid(nameHash, reveal.bidPrevout); + } + /** * Write a reveal. * @param {Object} b * @param {Buffer} nameHash * @param {Outpoint} outpoint * @param {Object} options + * @param {String} options.name + * @param {Amount} options.value + * @param {Number} options.height + * @param {Boolean} options.own + * @param {Outpoint} options.bidPrevout + * @returns {void} */ putReveal(b, nameHash, outpoint, options) { const {hash, index} = outpoint; + const {bidPrevout} = options; const brv = new BidReveal(); brv.nameHash = nameHash; brv.name = options.name; brv.value = options.value; brv.height = options.height; brv.own = options.own; + brv.bidPrevout = bidPrevout; b.put(layout.B.encode(nameHash, hash, index), brv.encode()); + b.put(layout.E.encode(nameHash, bidPrevout.hash, bidPrevout.index), + outpoint.encode()); } /** @@ -670,11 +715,13 @@ class TXDB { * @param {Object} b * @param {Buffer} nameHash * @param {Outpoint} outpoint + * @param {Outpoint} bidPrevout */ - removeReveal(b, nameHash, outpoint) { + removeReveal(b, nameHash, outpoint, bidPrevout) { const {hash, index} = outpoint; b.del(layout.B.encode(nameHash, hash, index)); + b.del(layout.E.encode(nameHash, bidPrevout.hash, bidPrevout.index)); } /** @@ -1975,6 +2022,7 @@ class TXDB { name, lockup, blind, + height, own: false }); @@ -1992,6 +2040,7 @@ class TXDB { name, lockup, blind, + height, own: true }); @@ -2012,18 +2061,20 @@ class TXDB { ns.setValue(output.value); } + const {prevout} = tx.inputs[i]; + if (!path) { this.putReveal(b, nameHash, outpoint, { name: ns.name, value: output.value, height: height, - own: false + own: false, + bidPrevout: prevout }); updated = true; break; } - const {prevout} = tx.inputs[i]; const coin = view.getOutput(prevout); if (coin) { @@ -2041,7 +2092,8 @@ class TXDB { name: ns.name, value: output.value, height: height, - own: true + own: true, + bidPrevout: prevout }); updated = true; @@ -2225,8 +2277,9 @@ class TXDB { break; } case types.REVEAL: { + const input = tx.inputs[i]; const nameHash = covenant.getHash(0); - this.removeReveal(b, nameHash, tx.outpoint(i)); + this.removeReveal(b, nameHash, tx.outpoint(i), input.prevout); break; } } @@ -3960,18 +4013,25 @@ class BlindBid extends bio.Struct { this.value = -1; this.lockup = 0; this.blind = consensus.ZERO_HASH; + this.height = -1; this.own = false; } getSize() { - return 1 + this.name.length + 41; + return 1 + this.name.length + 45; } write(bw) { + let height = this.height; + + if (height === -1) + height = 0xffffffff; + bw.writeU8(this.name.length); bw.writeBytes(this.name); bw.writeU64(this.lockup); bw.writeBytes(this.blind); + bw.writeU32(height); bw.writeU8(this.own ? 1 : 0); return bw; } @@ -3980,7 +4040,12 @@ class BlindBid extends bio.Struct { this.name = br.readBytes(br.readU8()); this.lockup = br.readU64(); this.blind = br.readBytes(32); + this.height = br.readU32(); this.own = br.readU8() === 1; + + if (this.height === 0xffffffff) + this.height = -1; + return this; } @@ -3992,6 +4057,7 @@ class BlindBid extends bio.Struct { value: this.value === -1 ? undefined : this.value, lockup: this.lockup, blind: this.blind.toString('hex'), + height: this.height, own: this.own }; } @@ -4042,13 +4108,14 @@ class BidReveal extends bio.Struct { this.name = EMPTY; this.nameHash = consensus.ZERO_HASH; this.prevout = new Outpoint(); + this.bidPrevout = new Outpoint(); this.value = 0; this.height = -1; this.own = false; } getSize() { - return 1 + this.name.length + 13; + return 1 + this.name.length + 13 + 36; } write(bw) { @@ -4062,6 +4129,7 @@ class BidReveal extends bio.Struct { bw.writeU64(this.value); bw.writeU32(height); bw.writeU8(this.own ? 1 : 0); + this.bidPrevout.write(bw); return bw; } @@ -4071,6 +4139,7 @@ class BidReveal extends bio.Struct { this.value = br.readU64(); this.height = br.readU32(); this.own = br.readU8() === 1; + this.bidPrevout.read(br); if (this.height === 0xffffffff) this.height = -1; @@ -4083,6 +4152,7 @@ class BidReveal extends bio.Struct { name: this.name.toString('ascii'), nameHash: this.nameHash.toString('hex'), prevout: this.prevout.toJSON(), + bidPrevout: this.bidPrevout.isNull() ? null : this.bidPrevout.toJSON(), value: this.value, height: this.height, own: this.own diff --git a/lib/wallet/wallet.js b/lib/wallet/wallet.js index 0ae33504c..6a6af89e1 100644 --- a/lib/wallet/wallet.js +++ b/lib/wallet/wallet.js @@ -4700,6 +4700,17 @@ class Wallet extends EventEmitter { return this.txdb.getBlind(blind); } + /** + * Get bid + * @param {Buffer} nameHash + * @param {Outpoint} outpoint + * @returns {Promise} + */ + + async getBid(nameHash, outpoint) { + return this.txdb.getBid(nameHash, outpoint); + } + /** * Get all bids for name. * @param {Buffer} nameHash @@ -4720,6 +4731,28 @@ class Wallet extends EventEmitter { return this.txdb.getBids(name ? rules.hashName(name) : null); } + /** + * Get bid by reveal. + * @param {Buffer} nameHash + * @param {Outpoint} outpoint - reveal outpoint + * @returns {Promise} + */ + + async getBidByReveal(nameHash, outpoint) { + return this.txdb.getBidByReveal(nameHash, outpoint); + } + + /** + * Get reveal. + * @param {Buffer} nameHash + * @param {Outpoint} outpoint + * @returns {BidReveal?} + */ + + async getReveal(nameHash, outpoint) { + return this.txdb.getReveal(nameHash, outpoint); + } + /** * Get all reveals by name. * @param {Buffer} nameHash @@ -4740,6 +4773,17 @@ class Wallet extends EventEmitter { return this.txdb.getReveals(name ? rules.hashName(name) : null); } + /** + * Get reveal for bid. + * @param {Buffer} nameHash + * @param {Outpoint} outpoint - bid outpoint + * @returns {Promise} + */ + + async getRevealByBid(nameHash, outpoint) { + return this.txdb.getRevealByBid(nameHash, outpoint); + } + /** * Add a transaction to the wallets TX history. * @param {TX} tx diff --git a/lib/wallet/walletdb.js b/lib/wallet/walletdb.js index 65df6f5a9..5fb9d8b16 100644 --- a/lib/wallet/walletdb.js +++ b/lib/wallet/walletdb.js @@ -78,7 +78,7 @@ class WalletDB extends EventEmitter { this.feeRate = this.options.feeRate; this.db = bdb.create(this.options); this.name = 'wallet'; - this.version = 2; + this.version = 3; // chain state. this.hasStateCache = false; diff --git a/test/data/migrations/README.md b/test/data/migrations/README.md new file mode 100644 index 000000000..4bee7730f --- /dev/null +++ b/test/data/migrations/README.md @@ -0,0 +1,11 @@ +Migration data with before/after entries. + +It contains generator scripts and manually assembled jsons for the migrations. + +## Notes + - wallet-4-bid-reveal.json (wallet-4-bid-reveal-gen.js) + - `fullAfter` is db dump with new version, `after` is filtered out things + that can not be recovered. + - Removed not-owned BID <-> Reveal bidings, they are not possible to + recover. We don't have transactions for those. We can't recover height of + the bids either. diff --git a/test/data/migrations/wallet-4-bid-reveal-gen.js b/test/data/migrations/wallet-4-bid-reveal-gen.js new file mode 100644 index 000000000..b42934dfe --- /dev/null +++ b/test/data/migrations/wallet-4-bid-reveal-gen.js @@ -0,0 +1,186 @@ +'use strict'; + +// Works for walletdb version 2 to 3 migration. +// HSD v6 -> v7 migration. + +const assert = require('bsert'); +const bdb = require('bdb'); +const Network = require('../../../lib/protocol/network'); +const WalletDB = require('../../../lib/wallet/walletdb'); +const MTX = require('../../../lib/primitives/mtx'); +const wutils = require('../../../test/util/wallet'); +const rules = require('../../../lib/covenants/rules'); + +const layout = { + wdb: { + V: bdb.key('V'), + // W[wid] -> wallet id + W: bdb.key('W', ['uint32']) + }, + txdb: { + prefix: bdb.key('t', ['uint32']), + // t[tx-hash] -> extended tx (Read only) + t: bdb.key('t', ['hash256']), + // i[name-hash][tx-hash][index] -> txdb.BlindBid + i: bdb.key('i', ['hash256', 'hash256', 'uint32']), + // B[name-hash][tx-hash][index] -> txdb.BidReveal + B: bdb.key('B', ['hash256', 'hash256', 'uint32']), + // E[name-hash][tx-hash][index] -> bid to reveal out. + E: bdb.key('E', ['hash256', 'hash256', 'uint32']) + } +}; + +const NETWORK = Network.get('regtest'); + +const wallet1priv = 'rprvKE8qsHtkmUxUSPQdn2sFKFUcKyUQz9pKQhxjEWecnXg9hgJMsmJXcw' + + 'J77SqmHT1R6mcuNqVPzgT2EoGStsXaUN92VJKhQWUB6uZdL8gAZvez'; +const wallet2priv = 'rprvKE8qsHtkmUxUSR4jE7Lti9XV77hv7xxacAShw5MvxY6RfsAYVeB1WL' + + 'WtjiebDmqTruVJxmMeQUMkk61e83WDZbZidDnNPhHyQpeEwxjuSZuG'; + +let txID = 0; +let timeCounter = 0; + +(async () => { + const wdb = new WalletDB({ + network: NETWORK, + memory: true, + nowFn: () => timeCounter++ + }); + + await wdb.open(); + + const wallet1 = await wdb.create({ + id: 'wallet1', + master: wallet1priv + }); + + await wallet1.createAccount('alt'); + + const wallet2 = await wdb.create({ + id: 'wallet2', + master: wallet2priv + }); + + // add 10 blocks to the wallet. + await mineBlocks(wdb, 100); + + // fund wallets + const mtx1 = new MTX(); + mtx1.addInput(wutils.deterministicInput(txID++)); + mtx1.addOutput(await wallet1.receiveAddress(0), 10e6); + + const mtx2 = new MTX(); + mtx2.addInput(wutils.deterministicInput(txID++)); + mtx2.addOutput(await wallet1.receiveAddress(1), 10e6); + + // fund second wallet. + const mtx3 = new MTX(); + mtx3.addInput(wutils.deterministicInput(txID++)); + mtx3.addOutput(await wallet2.receiveAddress(), 10e6); + + await wdb.addBlock(wutils.nextEntry(wdb), [ + mtx1.toTX(), + mtx2.toTX(), + mtx3.toTX() + ]); + + const name1 = 'testname1'; + const name2 = 'testname2'; + + const open1 = await wallet1.createOpen(name1, { + account: 0 + }); + await wdb.addTX(open1.toTX()); + const open2 = await wallet1.createOpen(name2, { + account: 0 + }); + + await wdb.addBlock(wutils.nextEntry(wdb), [ + open1.toTX(), + open2.toTX() + ]); + + await mineBlocks(wdb, NETWORK.names.treeInterval + 1); + + const ns = await wallet1.getNameState(rules.hashName(name1)); + const bid1 = await wallet1.createBid(name1, 2e6, 2e6, { + account: 0 + }); + + const bid2 = await wallet1.createBid(name2, 2e6, 2e6, { + account: 1 + }); + + // wallet2 does not know the state of the name. + const _getNameStatusBak = wdb.getNameStatus; + wdb.getNameStatus = (nameHash) => { + assert(Buffer.isBuffer(nameHash)); + assert(nameHash.equals(rules.hashName(name1))); + + return ns; + }; + + const bid3 = await wallet2.createBid(name1, 3e6, 3e6); + await wdb.addBlock(wutils.nextEntry(wdb), [ + bid1.toTX(), + bid2.toTX(), + bid3.toTX() + ]); + + wdb.getNameStatus = _getNameStatusBak; + await mineBlocks(wdb, NETWORK.names.biddingPeriod); + + const reveal1 = await wallet1.createReveal(name1, { + account: 0 + }); + + const reveal2 = await wallet1.createReveal(name2, { + account: 1 + }); + + const reveal3 = await wallet2.createReveal(name1); + + await wdb.addBlock(wutils.nextEntry(wdb), [ + reveal1.toTX(), + reveal2.toTX(), + reveal3.toTX() + ]); + + const dump = await getMigrationDump(wdb); + console.log(JSON.stringify({ + data: dump + }, null, 2)); + + await wdb.close(); +})().catch((e) => { + console.error(e.stack); + process.exit(1); +}); + +async function mineBlocks(wdb, n) { + for (let i = 0; i < n; i++) { + const entry = wutils.nextEntry(wdb); + await wdb.addBlock(entry, []); + } +}; + +async function getMigrationDump(wdb) { + const prefixes = []; + + for (let i = 1; i < 3; i++) { + const tprefix = layout.txdb.prefix.encode(i).toString('hex'); + const ti = tprefix + 'i'.charCodeAt(0).toString(16); + const tB = tprefix + 'B'.charCodeAt(0).toString(16); + const tE = tprefix + 'E'.charCodeAt(0).toString(16); + const tt = tprefix + 't'.charCodeAt(0).toString(16); + prefixes.push(ti, tB, tE, tt); + } + + for (let i = 0; i < 3; i++) { + prefixes.push(layout.wdb.W.encode(i).toString('hex')); + } + + const dump = await wutils.dumpWDB(wdb, prefixes); + + return dump; +}; diff --git a/test/data/migrations/wallet-4-bid-reveal.json b/test/data/migrations/wallet-4-bid-reveal.json new file mode 100644 index 000000000..181e6aad0 --- /dev/null +++ b/test/data/migrations/wallet-4-bid-reveal.json @@ -0,0 +1,86 @@ +{ + "description": "Migration for linking bid to reveal and vice versa. Affects txdb layout i, B and E (new). Uses txdb layout t to collect data.", + "before": { + "5700000000": "077072696d617279", + "5700000001": "0777616c6c657431", + "5700000002": "0777616c6c657432", + "740000000142074675b3cd135b485a497164408e26b2f077c32aec913c42fde3f80b08b4382ccc9c76cf691cb577640a511a7e1539e72f5672ea75bf364dd3d2e6add1e10efd00000000": "09746573746e616d653280841e00000000007300000001", + "740000000142aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a01f3b3fc483462c0de2f7962542da4e9a62393476d55a47cc29952d69957bbaf00000000": "09746573746e616d6531c0c62d00000000007300000000", + "740000000142aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a1706eab2dce949dd69cd82079f7b4dde902ec7702f0ea1f583c64574fe2341f400000000": "09746573746e616d653180841e00000000007300000001", + "740000000169074675b3cd135b485a497164408e26b2f077c32aec913c42fde3f80b08b4382c1ed9775dad6a119d8f4b54b803790de583a1877f0c1126f8cce41e77c438a74600000000": "09746573746e616d653280841e0000000000d9d0782ee039b29bccf72e07f6a8d0cf4aea50ff9ee1764d762f913f5e14980b01", + "740000000169aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a3bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d900000000": "09746573746e616d6531c0c62d0000000000ca5a40c98ed472f5726ef80a1e6299b0a713769cb1122aeb80f962cc02a4d8d400", + "740000000169aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a9a3ff4271510594109bd09d92271f7ef2fbd70f9e5bcae8a7347f29b7d3d849100000000": "09746573746e616d653180841e0000000000fb278d451ca7cf961fece75487723f06d66fbc7326e282b1889a1757066b890501", + "7400000001741706eab2dce949dd69cd82079f7b4dde902ec7702f0ea1f583c64574fe2341f4": "00000000029a3ff4271510594109bd09d92271f7ef2fbd70f9e5bcae8a7347f29b7d3d849100000000ffffffff9a3ff4271510594109bd09d92271f7ef2fbd70f9e5bcae8a7347f29b7d3d849101000000ffffffff0280841e000000000000142f6d31b494bdfa42034719ca28894496cdb89359040320aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a046600000020450566fda05dda024354f47c1f6d07769342a57c5dffe1d3a908a9043a83156bb8cd79000000000000149ae567da742bcd8894e5f0c789aa1a5a017396cc000000000000020021037f44c97b1d5c69af830f7c14647c710e95300bd94dd92ad75fdd30ca7489287f020021024e3c15df14b521891f269af40258119698ebaed5f7299abf9583546e2438e73209000000017eb84dc58b93e03a71f5d663a2296b8d9dc52950c625b5ae31efd8cea4a0e67b730000008872ce1dffffff7f", + "7400000001741b474b762714c2f0adb18d2127d4f32fd8202d64f4f2a031195cb72a98a8f25a": "0000000001a1f71206f2277bacd0b1fa32a633d20b69deb3e6dc1bc95db78a572d9f30915501000000ffffffff02000000000000000000146a94c2244bd9a4b5257a8c946b68af72f4118b35020320074675b3cd135b485a497164408e26b2f077c32aec913c42fde3f80b08b4382c040000000009746573746e616d6532207998000000000000141fcdaa5bd5efa8811106f6390e5ecc327083426b0000000000000200210256bc84ba99364f4a0146c1203b52104447d1085aee74df1242be003664e36cdf0400000001827ba7677abf30338299f8d2ab3c1a0a1144544dac46f5ec486bac54d3a9fe1c660000001054ce1dffffff7f", + "7400000001741ed9775dad6a119d8f4b54b803790de583a1877f0c1126f8cce41e77c438a746": "0000000001a76270b8188bbdd60aba522a75eb9643fb12183f9e7a929abc5fb7c0bdfc270200000000ffffffff0280841e000000000000146337e3ecd9354ba7a5fbe0ce2feb6d3bc5558a54030420074675b3cd135b485a497164408e26b2f077c32aec913c42fde3f80b08b4382c046600000009746573746e616d653220d9d0782ee039b29bccf72e07f6a8d0cf4aea50ff9ee1764d762f913f5e14980bbc007a00000000000014f0f269d0cb5eb1e065b1084d1d787a7ec5b6ed8c00000000000002002102df1a2c03a8d1b89b0b2f570ad99764f7dc4bcc710afa9745af65f2bc7789cfc806000000015c899b34c8d3bfa15916696ab22daba092a57b6729f7b0d2d80dbd366600783b6d0000007864ce1dffffff7f", + "7400000001742bca389fe3871c49fe6ea6706980a247fa4c4e97e60e1ac79598bd151b8055f3": "000000000111da6d1f761ddf9bdb4c9d6e5303ebd41f61858d0a5647a1a7bfe089bf921be900000000ffffffff0180969800000000000014cffd1219803f5f43f72a2a8e841a2fefb0347657000000000000000000000001ed1abdda4d85676c7978e2d3e85c8e2a36316e79b34955cf475a0bd1336bf21765000000b851ce1dffffff7f", + "7400000001749a3ff4271510594109bd09d92271f7ef2fbd70f9e5bcae8a7347f29b7d3d8491": "00000000011b474b762714c2f0adb18d2127d4f32fd8202d64f4f2a031195cb72a98a8f25a01000000ffffffff0280841e000000000000142f6d31b494bdfa42034719ca28894496cdb89359030420aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a046600000009746573746e616d653120fb278d451ca7cf961fece75487723f06d66fbc7326e282b1889a1757066b89055ce37900000000000014222740511246fe2b10957049ae10e0bbe7fa996c000000000000020021023960f57b3d5844794ac0dd5576fb59b3a64d82d4d76285a36173d169412539e205000000015c899b34c8d3bfa15916696ab22daba092a57b6729f7b0d2d80dbd366600783b6d0000007864ce1dffffff7f", + "740000000174a1f71206f2277bacd0b1fa32a633d20b69deb3e6dc1bc95db78a572d9f309155": "00000000012bca389fe3871c49fe6ea6706980a247fa4c4e97e60e1ac79598bd151b8055f300000000ffffffff0200000000000000000014b9e7138dd8a5fdd11fee499ccb7a6cd131edbaa3020320aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a040000000009746573746e616d6531d0879800000000000014a62c71694f8bf7583bfe73bd1b2235b81ee12558000000000000020021020c30819abd60558d2f9d1fdfabb5d46df7254b5a9346c9d78dc9b5ace6b1089e0300000001827ba7677abf30338299f8d2ab3c1a0a1144544dac46f5ec486bac54d3a9fe1c660000001054ce1dffffff7f", + "740000000174a76270b8188bbdd60aba522a75eb9643fb12183f9e7a929abc5fb7c0bdfc2702": "0000000001e12c22d4f162d9a012c9319233da5d3e923cc5e1029b8f90e47249c9ab256b3500000000ffffffff0180969800000000000014657eb0831fd4fafd3e595163416d76861ea9acd9000000000000000100000001ed1abdda4d85676c7978e2d3e85c8e2a36316e79b34955cf475a0bd1336bf21765000000b851ce1dffffff7f", + "740000000174cc9c76cf691cb577640a511a7e1539e72f5672ea75bf364dd3d2e6add1e10efd": "00000000021ed9775dad6a119d8f4b54b803790de583a1877f0c1126f8cce41e77c438a74600000000ffffffff1ed9775dad6a119d8f4b54b803790de583a1877f0c1126f8cce41e77c438a74601000000ffffffff0280841e000000000000146337e3ecd9354ba7a5fbe0ce2feb6d3bc5558a54040320074675b3cd135b485a497164408e26b2f077c32aec913c42fde3f80b08b4382c046600000020f70095f015fc11f5bae44f6136cbe1bb846103e79e065ea54f9e56f58e5322ab18eb79000000000000145258eb6f21709d00f66fa39deab6e8d5391eae5f00000000000002002103d1ab347d75498ccde90f26907c8aad98fcb5ecc922ff7de8f4be83c9b7a099b6020021021e772405b9b642a904d6e1f5739b56d1714327853f6cbb97777c70ef0c54c5450b000000017eb84dc58b93e03a71f5d663a2296b8d9dc52950c625b5ae31efd8cea4a0e67b730000008872ce1dffffff7f", + "740000000242aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a01f3b3fc483462c0de2f7962542da4e9a62393476d55a47cc29952d69957bbaf00000000": "09746573746e616d6531c0c62d00000000007300000001", + "740000000242aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a1706eab2dce949dd69cd82079f7b4dde902ec7702f0ea1f583c64574fe2341f400000000": "09746573746e616d653180841e00000000007300000000", + "740000000269aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a3bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d900000000": "09746573746e616d6531c0c62d0000000000ca5a40c98ed472f5726ef80a1e6299b0a713769cb1122aeb80f962cc02a4d8d401", + "74000000027401f3b3fc483462c0de2f7962542da4e9a62393476d55a47cc29952d69957bbaf": "00000000023bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d900000000ffffffff3bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d901000000ffffffff02c0c62d000000000000148e659d46d7ceb9464cc04f3aeb73bc2702c1e7a3040320aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a0466000000204c679195282ea315863be7119a2f1f6a4b9486fe7f86e6e778435f4fe9ed4083d8a86a00000000000014bfe57d3d51c357a99aa9c84195fe8e000273399a00000000000002002103aa28c5dc394dd41bda11c296f1e0ef98edfa09e5730b6abdab5f1e1e700e2a61020021036b182787487be70c07012724b985e8fe7f49067f2a3e4c5535da0118a21d13fa0c000000017eb84dc58b93e03a71f5d663a2296b8d9dc52950c625b5ae31efd8cea4a0e67b730000008872ce1dffffff7f", + "7400000002743bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d9": "0000000001abe815e307b0d125b21242058b6e0a8a43190c86456af1de27c17f0c8ddc29a600000000ffffffff02c0c62d000000000000148e659d46d7ceb9464cc04f3aeb73bc2702c1e7a3030420aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a046600000009746573746e616d653120ca5a40c98ed472f5726ef80a1e6299b0a713769cb1122aeb80f962cc02a4d8d47cbe6a00000000000014b44aae19323f53e63e5cd184dba19a71616808150000000000000200210237b59c5644219778989265c96ecdb213578feca83fc908a975d8465359779e8807000000015c899b34c8d3bfa15916696ab22daba092a57b6729f7b0d2d80dbd366600783b6d0000007864ce1dffffff7f", + "740000000274abe815e307b0d125b21242058b6e0a8a43190c86456af1de27c17f0c8ddc29a6": "00000000017b0aa1735e5ba58d3236316c671fe4f00ed366ee72417c9ed02a53a8019e85b800000000ffffffff01809698000000000000148ec33e2b7a9dc5fde7e6a166005d3b29265b313d000000000000000200000001ed1abdda4d85676c7978e2d3e85c8e2a36316e79b34955cf475a0bd1336bf21765000000b851ce1dffffff7f" + }, + "fullAfter": { + "5700000000": "077072696d617279", + "5700000001": "0777616c6c657431", + "5700000002": "0777616c6c657432", + "740000000142074675b3cd135b485a497164408e26b2f077c32aec913c42fde3f80b08b4382ccc9c76cf691cb577640a511a7e1539e72f5672ea75bf364dd3d2e6add1e10efd00000000": "09746573746e616d653280841e000000000073000000011ed9775dad6a119d8f4b54b803790de583a1877f0c1126f8cce41e77c438a74600000000", + "740000000142aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a01f3b3fc483462c0de2f7962542da4e9a62393476d55a47cc29952d69957bbaf00000000": "09746573746e616d6531c0c62d000000000073000000003bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d900000000", + "740000000142aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a1706eab2dce949dd69cd82079f7b4dde902ec7702f0ea1f583c64574fe2341f400000000": "09746573746e616d653180841e000000000073000000019a3ff4271510594109bd09d92271f7ef2fbd70f9e5bcae8a7347f29b7d3d849100000000", + "740000000145074675b3cd135b485a497164408e26b2f077c32aec913c42fde3f80b08b4382c1ed9775dad6a119d8f4b54b803790de583a1877f0c1126f8cce41e77c438a74600000000": "cc9c76cf691cb577640a511a7e1539e72f5672ea75bf364dd3d2e6add1e10efd00000000", + "740000000145aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a3bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d900000000": "01f3b3fc483462c0de2f7962542da4e9a62393476d55a47cc29952d69957bbaf00000000", + "740000000145aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a9a3ff4271510594109bd09d92271f7ef2fbd70f9e5bcae8a7347f29b7d3d849100000000": "1706eab2dce949dd69cd82079f7b4dde902ec7702f0ea1f583c64574fe2341f400000000", + "740000000169074675b3cd135b485a497164408e26b2f077c32aec913c42fde3f80b08b4382c1ed9775dad6a119d8f4b54b803790de583a1877f0c1126f8cce41e77c438a74600000000": "09746573746e616d653280841e0000000000d9d0782ee039b29bccf72e07f6a8d0cf4aea50ff9ee1764d762f913f5e14980b6d00000001", + "740000000169aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a3bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d900000000": "09746573746e616d6531c0c62d0000000000ca5a40c98ed472f5726ef80a1e6299b0a713769cb1122aeb80f962cc02a4d8d46d00000000", + "740000000169aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a9a3ff4271510594109bd09d92271f7ef2fbd70f9e5bcae8a7347f29b7d3d849100000000": "09746573746e616d653180841e0000000000fb278d451ca7cf961fece75487723f06d66fbc7326e282b1889a1757066b89056d00000001", + "7400000001741706eab2dce949dd69cd82079f7b4dde902ec7702f0ea1f583c64574fe2341f4": "00000000029a3ff4271510594109bd09d92271f7ef2fbd70f9e5bcae8a7347f29b7d3d849100000000ffffffff9a3ff4271510594109bd09d92271f7ef2fbd70f9e5bcae8a7347f29b7d3d849101000000ffffffff0280841e000000000000142f6d31b494bdfa42034719ca28894496cdb89359040320aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a046600000020450566fda05dda024354f47c1f6d07769342a57c5dffe1d3a908a9043a83156bb8cd79000000000000149ae567da742bcd8894e5f0c789aa1a5a017396cc000000000000020021037f44c97b1d5c69af830f7c14647c710e95300bd94dd92ad75fdd30ca7489287f020021024e3c15df14b521891f269af40258119698ebaed5f7299abf9583546e2438e73209000000017eb84dc58b93e03a71f5d663a2296b8d9dc52950c625b5ae31efd8cea4a0e67b730000008872ce1dffffff7f", + "7400000001741b474b762714c2f0adb18d2127d4f32fd8202d64f4f2a031195cb72a98a8f25a": "0000000001a1f71206f2277bacd0b1fa32a633d20b69deb3e6dc1bc95db78a572d9f30915501000000ffffffff02000000000000000000146a94c2244bd9a4b5257a8c946b68af72f4118b35020320074675b3cd135b485a497164408e26b2f077c32aec913c42fde3f80b08b4382c040000000009746573746e616d6532207998000000000000141fcdaa5bd5efa8811106f6390e5ecc327083426b0000000000000200210256bc84ba99364f4a0146c1203b52104447d1085aee74df1242be003664e36cdf0400000001827ba7677abf30338299f8d2ab3c1a0a1144544dac46f5ec486bac54d3a9fe1c660000001054ce1dffffff7f", + "7400000001741ed9775dad6a119d8f4b54b803790de583a1877f0c1126f8cce41e77c438a746": "0000000001a76270b8188bbdd60aba522a75eb9643fb12183f9e7a929abc5fb7c0bdfc270200000000ffffffff0280841e000000000000146337e3ecd9354ba7a5fbe0ce2feb6d3bc5558a54030420074675b3cd135b485a497164408e26b2f077c32aec913c42fde3f80b08b4382c046600000009746573746e616d653220d9d0782ee039b29bccf72e07f6a8d0cf4aea50ff9ee1764d762f913f5e14980bbc007a00000000000014f0f269d0cb5eb1e065b1084d1d787a7ec5b6ed8c00000000000002002102df1a2c03a8d1b89b0b2f570ad99764f7dc4bcc710afa9745af65f2bc7789cfc806000000015c899b34c8d3bfa15916696ab22daba092a57b6729f7b0d2d80dbd366600783b6d0000007864ce1dffffff7f", + "7400000001742bca389fe3871c49fe6ea6706980a247fa4c4e97e60e1ac79598bd151b8055f3": "000000000111da6d1f761ddf9bdb4c9d6e5303ebd41f61858d0a5647a1a7bfe089bf921be900000000ffffffff0180969800000000000014cffd1219803f5f43f72a2a8e841a2fefb0347657000000000000000000000001ed1abdda4d85676c7978e2d3e85c8e2a36316e79b34955cf475a0bd1336bf21765000000b851ce1dffffff7f", + "7400000001749a3ff4271510594109bd09d92271f7ef2fbd70f9e5bcae8a7347f29b7d3d8491": "00000000011b474b762714c2f0adb18d2127d4f32fd8202d64f4f2a031195cb72a98a8f25a01000000ffffffff0280841e000000000000142f6d31b494bdfa42034719ca28894496cdb89359030420aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a046600000009746573746e616d653120fb278d451ca7cf961fece75487723f06d66fbc7326e282b1889a1757066b89055ce37900000000000014222740511246fe2b10957049ae10e0bbe7fa996c000000000000020021023960f57b3d5844794ac0dd5576fb59b3a64d82d4d76285a36173d169412539e205000000015c899b34c8d3bfa15916696ab22daba092a57b6729f7b0d2d80dbd366600783b6d0000007864ce1dffffff7f", + "740000000174a1f71206f2277bacd0b1fa32a633d20b69deb3e6dc1bc95db78a572d9f309155": "00000000012bca389fe3871c49fe6ea6706980a247fa4c4e97e60e1ac79598bd151b8055f300000000ffffffff0200000000000000000014b9e7138dd8a5fdd11fee499ccb7a6cd131edbaa3020320aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a040000000009746573746e616d6531d0879800000000000014a62c71694f8bf7583bfe73bd1b2235b81ee12558000000000000020021020c30819abd60558d2f9d1fdfabb5d46df7254b5a9346c9d78dc9b5ace6b1089e0300000001827ba7677abf30338299f8d2ab3c1a0a1144544dac46f5ec486bac54d3a9fe1c660000001054ce1dffffff7f", + "740000000174a76270b8188bbdd60aba522a75eb9643fb12183f9e7a929abc5fb7c0bdfc2702": "0000000001e12c22d4f162d9a012c9319233da5d3e923cc5e1029b8f90e47249c9ab256b3500000000ffffffff0180969800000000000014657eb0831fd4fafd3e595163416d76861ea9acd9000000000000000100000001ed1abdda4d85676c7978e2d3e85c8e2a36316e79b34955cf475a0bd1336bf21765000000b851ce1dffffff7f", + "740000000174cc9c76cf691cb577640a511a7e1539e72f5672ea75bf364dd3d2e6add1e10efd": "00000000021ed9775dad6a119d8f4b54b803790de583a1877f0c1126f8cce41e77c438a74600000000ffffffff1ed9775dad6a119d8f4b54b803790de583a1877f0c1126f8cce41e77c438a74601000000ffffffff0280841e000000000000146337e3ecd9354ba7a5fbe0ce2feb6d3bc5558a54040320074675b3cd135b485a497164408e26b2f077c32aec913c42fde3f80b08b4382c046600000020f70095f015fc11f5bae44f6136cbe1bb846103e79e065ea54f9e56f58e5322ab18eb79000000000000145258eb6f21709d00f66fa39deab6e8d5391eae5f00000000000002002103d1ab347d75498ccde90f26907c8aad98fcb5ecc922ff7de8f4be83c9b7a099b6020021021e772405b9b642a904d6e1f5739b56d1714327853f6cbb97777c70ef0c54c5450b000000017eb84dc58b93e03a71f5d663a2296b8d9dc52950c625b5ae31efd8cea4a0e67b730000008872ce1dffffff7f", + "740000000242aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a01f3b3fc483462c0de2f7962542da4e9a62393476d55a47cc29952d69957bbaf00000000": "09746573746e616d6531c0c62d000000000073000000013bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d900000000", + "740000000242aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a1706eab2dce949dd69cd82079f7b4dde902ec7702f0ea1f583c64574fe2341f400000000": "09746573746e616d653180841e000000000073000000009a3ff4271510594109bd09d92271f7ef2fbd70f9e5bcae8a7347f29b7d3d849100000000", + "740000000245aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a3bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d900000000": "01f3b3fc483462c0de2f7962542da4e9a62393476d55a47cc29952d69957bbaf00000000", + "740000000245aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a9a3ff4271510594109bd09d92271f7ef2fbd70f9e5bcae8a7347f29b7d3d849100000000": "1706eab2dce949dd69cd82079f7b4dde902ec7702f0ea1f583c64574fe2341f400000000", + "740000000269aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a3bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d900000000": "09746573746e616d6531c0c62d0000000000ca5a40c98ed472f5726ef80a1e6299b0a713769cb1122aeb80f962cc02a4d8d46d00000001", + "74000000027401f3b3fc483462c0de2f7962542da4e9a62393476d55a47cc29952d69957bbaf": "00000000023bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d900000000ffffffff3bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d901000000ffffffff02c0c62d000000000000148e659d46d7ceb9464cc04f3aeb73bc2702c1e7a3040320aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a0466000000204c679195282ea315863be7119a2f1f6a4b9486fe7f86e6e778435f4fe9ed4083d8a86a00000000000014bfe57d3d51c357a99aa9c84195fe8e000273399a00000000000002002103aa28c5dc394dd41bda11c296f1e0ef98edfa09e5730b6abdab5f1e1e700e2a61020021036b182787487be70c07012724b985e8fe7f49067f2a3e4c5535da0118a21d13fa0c000000017eb84dc58b93e03a71f5d663a2296b8d9dc52950c625b5ae31efd8cea4a0e67b730000008872ce1dffffff7f", + "7400000002743bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d9": "0000000001abe815e307b0d125b21242058b6e0a8a43190c86456af1de27c17f0c8ddc29a600000000ffffffff02c0c62d000000000000148e659d46d7ceb9464cc04f3aeb73bc2702c1e7a3030420aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a046600000009746573746e616d653120ca5a40c98ed472f5726ef80a1e6299b0a713769cb1122aeb80f962cc02a4d8d47cbe6a00000000000014b44aae19323f53e63e5cd184dba19a71616808150000000000000200210237b59c5644219778989265c96ecdb213578feca83fc908a975d8465359779e8807000000015c899b34c8d3bfa15916696ab22daba092a57b6729f7b0d2d80dbd366600783b6d0000007864ce1dffffff7f", + "740000000274abe815e307b0d125b21242058b6e0a8a43190c86456af1de27c17f0c8ddc29a6": "00000000017b0aa1735e5ba58d3236316c671fe4f00ed366ee72417c9ed02a53a8019e85b800000000ffffffff01809698000000000000148ec33e2b7a9dc5fde7e6a166005d3b29265b313d000000000000000200000001ed1abdda4d85676c7978e2d3e85c8e2a36316e79b34955cf475a0bd1336bf21765000000b851ce1dffffff7f" + }, + "after": { + "5700000000": "077072696d617279", + "5700000001": "0777616c6c657431", + "5700000002": "0777616c6c657432", + "740000000142074675b3cd135b485a497164408e26b2f077c32aec913c42fde3f80b08b4382ccc9c76cf691cb577640a511a7e1539e72f5672ea75bf364dd3d2e6add1e10efd00000000": "09746573746e616d653280841e000000000073000000011ed9775dad6a119d8f4b54b803790de583a1877f0c1126f8cce41e77c438a74600000000", + "740000000142aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a01f3b3fc483462c0de2f7962542da4e9a62393476d55a47cc29952d69957bbaf00000000": "09746573746e616d6531c0c62d000000000073000000000000000000000000000000000000000000000000000000000000000000000000ffffffff", + "740000000142aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a1706eab2dce949dd69cd82079f7b4dde902ec7702f0ea1f583c64574fe2341f400000000": "09746573746e616d653180841e000000000073000000019a3ff4271510594109bd09d92271f7ef2fbd70f9e5bcae8a7347f29b7d3d849100000000", + "740000000145074675b3cd135b485a497164408e26b2f077c32aec913c42fde3f80b08b4382c1ed9775dad6a119d8f4b54b803790de583a1877f0c1126f8cce41e77c438a74600000000": "cc9c76cf691cb577640a511a7e1539e72f5672ea75bf364dd3d2e6add1e10efd00000000", + "740000000145aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a9a3ff4271510594109bd09d92271f7ef2fbd70f9e5bcae8a7347f29b7d3d849100000000": "1706eab2dce949dd69cd82079f7b4dde902ec7702f0ea1f583c64574fe2341f400000000", + "740000000169074675b3cd135b485a497164408e26b2f077c32aec913c42fde3f80b08b4382c1ed9775dad6a119d8f4b54b803790de583a1877f0c1126f8cce41e77c438a74600000000": "09746573746e616d653280841e0000000000d9d0782ee039b29bccf72e07f6a8d0cf4aea50ff9ee1764d762f913f5e14980b6d00000001", + "740000000169aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a3bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d900000000": "09746573746e616d6531c0c62d0000000000ca5a40c98ed472f5726ef80a1e6299b0a713769cb1122aeb80f962cc02a4d8d4ffffffff00", + "740000000169aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a9a3ff4271510594109bd09d92271f7ef2fbd70f9e5bcae8a7347f29b7d3d849100000000": "09746573746e616d653180841e0000000000fb278d451ca7cf961fece75487723f06d66fbc7326e282b1889a1757066b89056d00000001", + "7400000001741706eab2dce949dd69cd82079f7b4dde902ec7702f0ea1f583c64574fe2341f4": "00000000029a3ff4271510594109bd09d92271f7ef2fbd70f9e5bcae8a7347f29b7d3d849100000000ffffffff9a3ff4271510594109bd09d92271f7ef2fbd70f9e5bcae8a7347f29b7d3d849101000000ffffffff0280841e000000000000142f6d31b494bdfa42034719ca28894496cdb89359040320aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a046600000020450566fda05dda024354f47c1f6d07769342a57c5dffe1d3a908a9043a83156bb8cd79000000000000149ae567da742bcd8894e5f0c789aa1a5a017396cc000000000000020021037f44c97b1d5c69af830f7c14647c710e95300bd94dd92ad75fdd30ca7489287f020021024e3c15df14b521891f269af40258119698ebaed5f7299abf9583546e2438e73209000000017eb84dc58b93e03a71f5d663a2296b8d9dc52950c625b5ae31efd8cea4a0e67b730000008872ce1dffffff7f", + "7400000001741b474b762714c2f0adb18d2127d4f32fd8202d64f4f2a031195cb72a98a8f25a": "0000000001a1f71206f2277bacd0b1fa32a633d20b69deb3e6dc1bc95db78a572d9f30915501000000ffffffff02000000000000000000146a94c2244bd9a4b5257a8c946b68af72f4118b35020320074675b3cd135b485a497164408e26b2f077c32aec913c42fde3f80b08b4382c040000000009746573746e616d6532207998000000000000141fcdaa5bd5efa8811106f6390e5ecc327083426b0000000000000200210256bc84ba99364f4a0146c1203b52104447d1085aee74df1242be003664e36cdf0400000001827ba7677abf30338299f8d2ab3c1a0a1144544dac46f5ec486bac54d3a9fe1c660000001054ce1dffffff7f", + "7400000001741ed9775dad6a119d8f4b54b803790de583a1877f0c1126f8cce41e77c438a746": "0000000001a76270b8188bbdd60aba522a75eb9643fb12183f9e7a929abc5fb7c0bdfc270200000000ffffffff0280841e000000000000146337e3ecd9354ba7a5fbe0ce2feb6d3bc5558a54030420074675b3cd135b485a497164408e26b2f077c32aec913c42fde3f80b08b4382c046600000009746573746e616d653220d9d0782ee039b29bccf72e07f6a8d0cf4aea50ff9ee1764d762f913f5e14980bbc007a00000000000014f0f269d0cb5eb1e065b1084d1d787a7ec5b6ed8c00000000000002002102df1a2c03a8d1b89b0b2f570ad99764f7dc4bcc710afa9745af65f2bc7789cfc806000000015c899b34c8d3bfa15916696ab22daba092a57b6729f7b0d2d80dbd366600783b6d0000007864ce1dffffff7f", + "7400000001742bca389fe3871c49fe6ea6706980a247fa4c4e97e60e1ac79598bd151b8055f3": "000000000111da6d1f761ddf9bdb4c9d6e5303ebd41f61858d0a5647a1a7bfe089bf921be900000000ffffffff0180969800000000000014cffd1219803f5f43f72a2a8e841a2fefb0347657000000000000000000000001ed1abdda4d85676c7978e2d3e85c8e2a36316e79b34955cf475a0bd1336bf21765000000b851ce1dffffff7f", + "7400000001749a3ff4271510594109bd09d92271f7ef2fbd70f9e5bcae8a7347f29b7d3d8491": "00000000011b474b762714c2f0adb18d2127d4f32fd8202d64f4f2a031195cb72a98a8f25a01000000ffffffff0280841e000000000000142f6d31b494bdfa42034719ca28894496cdb89359030420aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a046600000009746573746e616d653120fb278d451ca7cf961fece75487723f06d66fbc7326e282b1889a1757066b89055ce37900000000000014222740511246fe2b10957049ae10e0bbe7fa996c000000000000020021023960f57b3d5844794ac0dd5576fb59b3a64d82d4d76285a36173d169412539e205000000015c899b34c8d3bfa15916696ab22daba092a57b6729f7b0d2d80dbd366600783b6d0000007864ce1dffffff7f", + "740000000174a1f71206f2277bacd0b1fa32a633d20b69deb3e6dc1bc95db78a572d9f309155": "00000000012bca389fe3871c49fe6ea6706980a247fa4c4e97e60e1ac79598bd151b8055f300000000ffffffff0200000000000000000014b9e7138dd8a5fdd11fee499ccb7a6cd131edbaa3020320aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a040000000009746573746e616d6531d0879800000000000014a62c71694f8bf7583bfe73bd1b2235b81ee12558000000000000020021020c30819abd60558d2f9d1fdfabb5d46df7254b5a9346c9d78dc9b5ace6b1089e0300000001827ba7677abf30338299f8d2ab3c1a0a1144544dac46f5ec486bac54d3a9fe1c660000001054ce1dffffff7f", + "740000000174a76270b8188bbdd60aba522a75eb9643fb12183f9e7a929abc5fb7c0bdfc2702": "0000000001e12c22d4f162d9a012c9319233da5d3e923cc5e1029b8f90e47249c9ab256b3500000000ffffffff0180969800000000000014657eb0831fd4fafd3e595163416d76861ea9acd9000000000000000100000001ed1abdda4d85676c7978e2d3e85c8e2a36316e79b34955cf475a0bd1336bf21765000000b851ce1dffffff7f", + "740000000174cc9c76cf691cb577640a511a7e1539e72f5672ea75bf364dd3d2e6add1e10efd": "00000000021ed9775dad6a119d8f4b54b803790de583a1877f0c1126f8cce41e77c438a74600000000ffffffff1ed9775dad6a119d8f4b54b803790de583a1877f0c1126f8cce41e77c438a74601000000ffffffff0280841e000000000000146337e3ecd9354ba7a5fbe0ce2feb6d3bc5558a54040320074675b3cd135b485a497164408e26b2f077c32aec913c42fde3f80b08b4382c046600000020f70095f015fc11f5bae44f6136cbe1bb846103e79e065ea54f9e56f58e5322ab18eb79000000000000145258eb6f21709d00f66fa39deab6e8d5391eae5f00000000000002002103d1ab347d75498ccde90f26907c8aad98fcb5ecc922ff7de8f4be83c9b7a099b6020021021e772405b9b642a904d6e1f5739b56d1714327853f6cbb97777c70ef0c54c5450b000000017eb84dc58b93e03a71f5d663a2296b8d9dc52950c625b5ae31efd8cea4a0e67b730000008872ce1dffffff7f", + "740000000242aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a01f3b3fc483462c0de2f7962542da4e9a62393476d55a47cc29952d69957bbaf00000000": "09746573746e616d6531c0c62d000000000073000000013bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d900000000", + "740000000242aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a1706eab2dce949dd69cd82079f7b4dde902ec7702f0ea1f583c64574fe2341f400000000": "09746573746e616d653180841e000000000073000000000000000000000000000000000000000000000000000000000000000000000000ffffffff", + "740000000245aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a3bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d900000000": "01f3b3fc483462c0de2f7962542da4e9a62393476d55a47cc29952d69957bbaf00000000", + "740000000269aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a3bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d900000000": "09746573746e616d6531c0c62d0000000000ca5a40c98ed472f5726ef80a1e6299b0a713769cb1122aeb80f962cc02a4d8d46d00000001", + "74000000027401f3b3fc483462c0de2f7962542da4e9a62393476d55a47cc29952d69957bbaf": "00000000023bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d900000000ffffffff3bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d901000000ffffffff02c0c62d000000000000148e659d46d7ceb9464cc04f3aeb73bc2702c1e7a3040320aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a0466000000204c679195282ea315863be7119a2f1f6a4b9486fe7f86e6e778435f4fe9ed4083d8a86a00000000000014bfe57d3d51c357a99aa9c84195fe8e000273399a00000000000002002103aa28c5dc394dd41bda11c296f1e0ef98edfa09e5730b6abdab5f1e1e700e2a61020021036b182787487be70c07012724b985e8fe7f49067f2a3e4c5535da0118a21d13fa0c000000017eb84dc58b93e03a71f5d663a2296b8d9dc52950c625b5ae31efd8cea4a0e67b730000008872ce1dffffff7f", + "7400000002743bd9079ea3d113b8eb0288c4b2a7c91d08a0cfe45ecad626d56c9251961f28d9": "0000000001abe815e307b0d125b21242058b6e0a8a43190c86456af1de27c17f0c8ddc29a600000000ffffffff02c0c62d000000000000148e659d46d7ceb9464cc04f3aeb73bc2702c1e7a3030420aca5b24203acfd52b9abe29d4adcccad9b8f93a57b495481b4af8a5b0c9f719a046600000009746573746e616d653120ca5a40c98ed472f5726ef80a1e6299b0a713769cb1122aeb80f962cc02a4d8d47cbe6a00000000000014b44aae19323f53e63e5cd184dba19a71616808150000000000000200210237b59c5644219778989265c96ecdb213578feca83fc908a975d8465359779e8807000000015c899b34c8d3bfa15916696ab22daba092a57b6729f7b0d2d80dbd366600783b6d0000007864ce1dffffff7f", + "740000000274abe815e307b0d125b21242058b6e0a8a43190c86456af1de27c17f0c8ddc29a6": "00000000017b0aa1735e5ba58d3236316c671fe4f00ed366ee72417c9ed02a53a8019e85b800000000ffffffff01809698000000000000148ec33e2b7a9dc5fde7e6a166005d3b29265b313d000000000000000200000001ed1abdda4d85676c7978e2d3e85c8e2a36316e79b34955cf475a0bd1336bf21765000000b851ce1dffffff7f" + } +} diff --git a/test/util/wallet.js b/test/util/wallet.js index b2b6b7a7d..7d2b9029e 100644 --- a/test/util/wallet.js +++ b/test/util/wallet.js @@ -70,3 +70,19 @@ function fromU32(num) { data.writeUInt32LE(num, 0, true); return data; } + +walletUtils.dumpWDB = async (wdb, prefixes) => { + const data = await wdb.dump(); + const filtered = {}; + + for (const [key, value] of Object.entries(data)) { + for (const prefix of prefixes) { + if (key.startsWith(prefix)) { + filtered[key] = value; + break; + } + } + } + + return filtered; +}; diff --git a/test/wallet-http-test.js b/test/wallet-http-test.js index 873a354e1..c231c6d49 100644 --- a/test/wallet-http-test.js +++ b/test/wallet-http-test.js @@ -877,6 +877,7 @@ describe('Wallet HTTP', function() { // the first bids of this test suite assert.equal(bids.length, 3); assert.ok(bids.every(bid => bid.name === name)); + assert.ok(bids.every(bid => bid.height === nodeCtx.height)); // tx1 assert.ok(bids.find(bid => @@ -930,6 +931,8 @@ describe('Wallet HTTP', function() { const bids = await wallet.getBidsByName(name); assert.equal(bids.length, 2); + assert.ok(bids.every(bid => bid.height === nodeCtx.height)); + // there is no value property on bids // from other wallets assert.ok(bids.find(bid => @@ -949,6 +952,7 @@ describe('Wallet HTTP', function() { assert.equal(bids.length, 1); const [bid] = bids; assert.equal(bid.prevout.hash, tx1.hash); + assert.strictEqual(bid.height, nodeCtx.height); } }); @@ -1010,6 +1014,20 @@ describe('Wallet HTTP', function() { const reveals = json.outputs.filter(output => output.covenant.type === types.REVEAL); assert.equal(reveals.length, 3); + + ownedNames.push(name); + + await nodeCtx.mineBlocks(1, cbAddress); + + const allReveals = await wallet.getReveals(); + assert.strictEqual(allReveals.length, 3); + assert.ok(allReveals.every(reveal => reveal.name === name)); + assert.ok(allReveals.every(reveal => reveal.height === nodeCtx.height)); + + const revealsByName = await wallet.getRevealsByName(name); + assert.strictEqual(revealsByName.length, 3); + assert.ok(revealsByName.every(reveal => reveal.name === name)); + assert.ok(revealsByName.every(reveal => reveal.height === nodeCtx.height)); }); it('should get all reveals (single player)', async () => { @@ -1059,12 +1077,14 @@ describe('Wallet HTTP', function() { { const reveals = await wallet.getReveals(); - assert.equal(reveals.length, 2); + assert.equal(reveals.length, 5); } { // a single reveal per name const reveals = await wallet.getRevealsByName(name); + const [reveal] = reveals; + assert.strictEqual(reveal.height + revealPeriod, nodeCtx.height); assert.equal(reveals.length, 1); } }); @@ -1123,24 +1143,52 @@ describe('Wallet HTTP', function() { { const reveals = await wallet.getRevealsByName(name, {own: true}); - assert.equal(reveals.length, 1); + assert.strictEqual(reveals.length, 1); const [reveal] = reveals; - assert.equal(reveal.own, true); - assert.equal(reveal.prevout.hash, r1.hash); + assert.strictEqual(reveal.bidPrevout.hash, state.bids[0].hash); + assert.strictEqual(reveal.bidPrevout.index, 0); + assert.strictEqual(reveal.own, true); + assert.strictEqual(reveal.prevout.hash, r1.hash); } { const reveals = await wallet.getRevealsByName(name); - assert.equal(reveals.length, 2); + assert.strictEqual(reveals.length, 2); - assert.ok(reveals.find(reveal => - reveal.prevout.hash === r1.hash - )); + const r1 = reveals.find(reveal => + reveal.prevout.hash === state.reveals[0].hash); + const r2 = reveals.find(reveal => + reveal.prevout.hash === state.reveals[1].hash); - assert.ok(reveals.find(reveal => - reveal.prevout.hash === r2.hash - )); + assert.ok(r1); + assert.ok(r2); + + assert.strictEqual(r1.bidPrevout.hash, state.bids[0].hash); + assert.strictEqual(r1.bidPrevout.index, 0); + + assert.strictEqual(r2.bidPrevout.hash, state.bids[1].hash); + assert.strictEqual(r2.bidPrevout.index, 0); } + + const dump = await nodeCtx.wdb.dump(); + const dumpSlice = {}; + + Object.keys(dump).filter((key) => { + const wid1 = '7400000001'; + // txdblayout.t + if (key.startsWith(wid1 + '74')) + dumpSlice[key] = dump[key]; + + // txdblayout.i + if (key.startsWith(wid1 + '69')) + dumpSlice[key] = dump[key]; + + // txdblayout.B + if (key.startsWith(wid1 + '42')) + dumpSlice[key] = dump[key]; + }); + + console.log(dumpSlice); }); it('should get auction info', async () => { diff --git a/test/wallet-migration-test.js b/test/wallet-migration-test.js index 57faf81a5..89b347f70 100644 --- a/test/wallet-migration-test.js +++ b/test/wallet-migration-test.js @@ -572,6 +572,7 @@ describe('Wallet Migrations', function() { }; walletDB.options.walletMigrate = 0; + walletDB.version = 2; await walletDB.open(); const wallet = walletDB.primary; @@ -828,4 +829,91 @@ describe('Wallet Migrations', function() { await walletDB.close(); }); }); + + describe('Bid Reveal Migration (integration)', function() { + const location = testdir('wallet-bid-reveal'); + const migrationsBAK = WalletMigrator.migrations; + const data = require('./data/migrations/wallet-4-bid-reveal.json'); + const Migration = WalletMigrator.MigrateBidRevealEntries; + const layout = Migration.layout(); + + const walletOptions = { + prefix: location, + memory: false, + network + }; + + let walletDB, ldb; + before(async () => { + WalletMigrator.migrations = {}; + await fs.mkdirp(location); + + walletDB = new WalletDB(walletOptions); + ldb = walletDB.db; + + await ldb.open(); + + const b = ldb.batch(); + for (const [key, value] of Object.entries(data.before)) { + const bkey = Buffer.from(key, 'hex'); + const bvalue = Buffer.from(value, 'hex'); + + b.put(bkey, bvalue); + } + await b.write(); + + await ldb.close(); + }); + + after(async () => { + WalletMigrator.migrations = migrationsBAK; + await rimraf(location); + }); + + beforeEach(async () => { + walletDB = new WalletDB(walletOptions); + ldb = walletDB.db; + }); + + afterEach(async () => { + if (ldb.opened) + await ldb.close(); + }); + + it('should have before entries', async () => { + walletDB.version = 2; + await walletDB.open(); + await checkVersion(ldb, layout.wdb.V.encode(), 2); + await checkEntries(ldb, data.before); + await walletDB.close(); + }); + + it('should enable wallet migration', () => { + WalletMigrator.migrations = { + 0: Migration + }; + }); + + it('should fail without migrate flag', async () => { + const expectedError = migrationError(WalletMigrator.migrations, [0], + wdbFlagError(0)); + + await assert.rejects(async () => { + await walletDB.open(); + }, { + message: expectedError + }); + + await ldb.close(); + }); + + it('should migrate', async () => { + walletDB.options.walletMigrate = 0; + + await walletDB.open(); + // check we have migrated entries. + await checkEntries(ldb, data.after); + await walletDB.close(); + }); + }); }); diff --git a/test/wallet-test.js b/test/wallet-test.js index d89b03438..f9ebd56b2 100644 --- a/test/wallet-test.js +++ b/test/wallet-test.js @@ -2177,6 +2177,7 @@ describe('Wallet', function() { // Hack required to focus test on txdb mechanics. // We don't otherwise need WalletDB or Blockchain + // TODO: Remove this after #888 is merged. wdb.getRenewalBlock = () => { return network.genesis.hash; }; @@ -2341,6 +2342,7 @@ describe('Wallet', function() { ); const mtx = new MTX(); + mtx.addInput(dummyInput()); mtx.outputs.push(output); // Confirm external REVEAL @@ -2546,6 +2548,7 @@ describe('Wallet', function() { // Hack required to focus test on txdb mechanics. // We don't otherwise need WalletDB or Blockchain + // TODO: Remove this after #888 is merged. wdb.getRenewalBlock = () => { return network.genesis.hash; }; @@ -2707,6 +2710,7 @@ describe('Wallet', function() { ); const mtx = new MTX(); + mtx.addInput(dummyInput()); mtx.outputs.push(output); // Confirm external REVEAL @@ -3180,6 +3184,7 @@ describe('Wallet', function() { // Hack required to focus test on txdb mechanics. // We don't otherwise need WalletDB or Blockchain + // TODO: Remove this after #888 is merged. wdb.getRenewalBlock = () => { return network.genesis.hash; }; @@ -3626,4 +3631,135 @@ describe('Wallet', function() { assert.strictEqual(await bob.txdb.hasBlind(expectedBlinds.bob), true); }); }); + + describe('Bid and Reveal by Reveal and Bid', function () { + const network = Network.get('regtest'); + const wdb = new WalletDB({ network }); + + // Hack required to focus test on txdb mechanics. + // We don't otherwise need WalletDB or Blockchain + // TODO: Remove this after #888 is merged. + wdb.getRenewalBlock = () => { + return network.genesis.hash; + }; + + const mineBlocks = async (count) => { + for (let i = 0; i < count; i++) { + await wdb.addBlock(nextEntry(wdb), []); + } + }; + + const NAME = rules.grindName(10, 1, network); + const NAMEHASH = rules.hashString(NAME); + let wallet; + + const BASE_BID = 1e6; + const BASE_LOCKUP = 2e6; + const BID_COUNT = 5; + const bids = []; + let revealMTX; + + before(async () => { + await wdb.open(); + await wdb.connect(); + + wallet = await wdb.create(); + }); + + after(async () => { + await wdb.disconnect(); + await wdb.close(); + }); + + it('should fund wallet', async () => { + const addr = await wallet.receiveAddress(); + + const txs = []; + for (let i = 0; i < BID_COUNT; i++) { + const mtx = new MTX(); + mtx.addOutpoint(new Outpoint(Buffer.alloc(32), 0)); + mtx.addOutput(addr, 20e6); + txs.push(mtx.toTX()); + } + + await wdb.addBlock(nextEntry(wdb), txs); + }); + + it('should open names', async () => { + const open = await wallet.createOpen(NAME); + await wdb.addBlock(nextEntry(wdb), [open.toTX()]); + await mineBlocks(network.names.treeInterval + 1); + }); + + it('should create and get bid', async () => { + for (let i = 0; i < BID_COUNT; i++) { + const bid = await wallet.createBid(NAME, BASE_BID + i, BASE_LOCKUP + i); + await wdb.addTX(bid.toTX()); + bids.push(bid); + } + + const txs = bids.map(b => b.toTX()); + await wdb.addBlock(nextEntry(wdb), txs); + + for (const [index, bid] of bids.entries()) { + const bidOut = bid.outpoint(0); + const blindBid = await wallet.getBid(NAMEHASH, bidOut); + assert.ok(blindBid); + assert.bufferEqual(blindBid.nameHash, NAMEHASH); + assert.bufferEqual(blindBid.prevout.hash, bid.hash()); + assert.strictEqual(blindBid.prevout.index, 0); + assert.strictEqual(blindBid.lockup, BASE_LOCKUP + index); + assert.strictEqual(blindBid.height, wdb.state.height); + assert.strictEqual(blindBid.own, true); + } + + await mineBlocks(network.names.biddingPeriod); + }); + + it('should create and get reveal', async () => { + revealMTX = await wallet.createReveal(NAME); + await wdb.addBlock(nextEntry(wdb), [revealMTX.toTX()]); + + for (const [index, out] of revealMTX.outputs.entries()) { + if (!out.covenant.isReveal()) + continue; + + const revealOut = revealMTX.outpoint(index); + const bidReveal = await wallet.getReveal(NAMEHASH, revealOut); + + assert.ok(bidReveal); + assert.bufferEqual(bidReveal.prevout.hash, revealMTX.hash()); + assert.strictEqual(bidReveal.prevout.index, index); + assert.bufferEqual(bidReveal.nameHash, NAMEHASH); + assert.strictEqual(bidReveal.height, wdb.state.height); + assert.strictEqual(bidReveal.own, true); + } + }); + + it('should get reveal by bid', async () => { + for (const [index, bidTX] of bids.entries()) { + const bidOut = bidTX.outpoint(0); + const bidReveal = await wallet.getRevealByBid(NAMEHASH, bidOut); + assert.ok(bidReveal); + + assert.bufferEqual(bidReveal.bidPrevout.hash, bidOut.hash); + assert.strictEqual(bidReveal.bidPrevout.index, bidOut.index); + assert.strictEqual(bidReveal.value, BASE_BID + index); + } + }); + + it('should get bid by reveal', async () => { + for (const bidTX of bids) { + const bidOut = bidTX.outpoint(0); + const bidReveal = await wallet.getRevealByBid(NAMEHASH, bidOut); + assert.ok(bidReveal); + + const origBlindBid = await wallet.getBid(NAMEHASH, bidOut); + const blindBid = await wallet.getBidByReveal(NAMEHASH, + new Outpoint(bidReveal.prevout.hash, bidReveal.prevout.index)); + + assert.deepStrictEqual(blindBid, origBlindBid); + } + }); + }); });