diff --git a/bench/tx.js b/bench/tx.js index cd2f3720..f8ee7c19 100644 --- a/bench/tx.js +++ b/bench/tx.js @@ -15,7 +15,7 @@ var block = bcoin.block.fromJSON(require('../test/data/block300025.json')); var btx = block.txs[397]; var tx1 = parseTX('../test/data/tx3.hex'); -var tx4 = parseExtended('../test/data/tx4.hex'); +var tx4 = parseTX('../test/data/tx4.hex'); var wtx = fs.readFileSync(__dirname + '/../test/data/wtx.hex', 'utf8'); wtx = new Buffer(wtx.trim(), 'hex'); var tx; @@ -30,11 +30,6 @@ function parseTX(file) { return tx; } -function parseExtended(file) { - file = fs.readFileSync(__dirname + '/' + file, 'utf8').trim(); - return bcoin.tx.fromExtended(file, true, 'hex'); -} - var end = bench('parse'); for (var i = 0; i < 1000; i++) tx = bcoin.tx.fromRaw(wtx); diff --git a/lib/primitives/tx.js b/lib/primitives/tx.js index db11abaf..e9f75f99 100644 --- a/lib/primitives/tx.js +++ b/lib/primitives/tx.js @@ -2392,129 +2392,10 @@ TX.isWitness = function isWitness(data) { * timestamp, pending-since time, and optionally a vector * for the serialized coins. * @param {Boolean?} saveCoins - Whether to serialize the coins. - * @param {String?} enc - One of `"hex"` or `null`. * @returns {Buffer} */ TX.prototype.toExtended = function toExtended(saveCoins, writer) { - var height = this.height; - var index = this.index; - var p = BufferWriter(writer); - var i, input; - - if (height === -1) - height = 0x7fffffff; - - if (index === -1) - index = 0x7fffffff; - - this.toRaw(p); - - p.writeU32(height); - p.writeHash(this.block || constants.ZERO_HASH); - p.writeU32(index); - p.writeU32(this.ts); - p.writeU32(this.ps); - - if (saveCoins) { - p.writeVarint(this.inputs.length); - for (i = 0; i < this.inputs.length; i++) { - input = this.inputs[i]; - - if (!input.coin) { - p.writeVarint(0); - continue; - } - - p.writeVarBytes(input.coin.toRaw()); - } - } - - if (!writer) - p = p.render(); - - return p; -}; - -/** - * Inject properties from "extended" serialization format. - * @param {Buffer} data - * @param {Boolean?} saveCoins - If true, the function will - * attempt to parse the coins. - * @param {String?} enc - One of `"hex"` or `null`. - */ - -TX.prototype.fromExtended = function fromExtended(data, saveCoins) { - var p = BufferReader(data); - var i, coinCount, coin; - - this.fromRaw(p); - - this.height = p.readU32(); - this.block = p.readHash('hex'); - this.index = p.readU32(); - this.ts = p.readU32(); - this.ps = p.readU32(); - - if (this.block === constants.NULL_HASH) - this.block = null; - - if (this.height === 0x7fffffff) - this.height = -1; - - if (this.index === 0x7fffffff) - this.index = -1; - - if (saveCoins) { - coinCount = p.readVarint(); - for (i = 0; i < coinCount; i++) { - coin = p.readVarBytes(); - if (coin.length === 0) - continue; - coin = Coin.fromRaw(coin); - coin.hash = this.inputs[i].prevout.hash; - coin.index = this.inputs[i].prevout.index; - this.inputs[i].coin = coin; - } - } - - return this; -}; - -/** - * Instantiate a transaction from a Buffer - * in "extended" serialization format. - * @param {Buffer} data - * @param {Boolean?} saveCoins - If true, the function will - * attempt to parse the coins. - * @param {String?} enc - One of `"hex"` or `null`. - * @returns {TX} - */ - -TX.fromExtended = function fromExtended(data, saveCoins, enc) { - if (typeof saveCoins === 'string') { - enc = saveCoins; - saveCoins = false; - } - - if (typeof data === 'string') - data = new Buffer(data, enc); - - return new TX().fromExtended(data, saveCoins); -}; - -/** - * Serialize a transaction to BCoin "extended format". - * This is the serialization format BCoin uses internally - * to store transactions in the database. The extended - * serialization includes the height, block hash, index, - * timestamp, pending-since time, and optionally a vector - * for the serialized coins. - * @param {Boolean?} saveCoins - Whether to serialize the coins. - * @returns {Buffer} - */ - -TX.prototype.toExtended2 = function toExtended2(saveCoins, writer) { var p = BufferWriter(writer); var i, input, field, bit, oct; @@ -2569,7 +2450,7 @@ TX.prototype.toExtended2 = function toExtended2(saveCoins, writer) { * attempt to parse the coins. */ -TX.prototype.fromExtended2 = function fromExtended2(data, saveCoins) { +TX.prototype.fromExtended = function fromExtended(data, saveCoins) { var p = BufferReader(data); var i, input, coin, field, bit, oct, spent; @@ -2618,7 +2499,7 @@ TX.prototype.fromExtended2 = function fromExtended2(data, saveCoins) { * @returns {TX} */ -TX.fromExtended2 = function fromExtended2(data, saveCoins, enc) { +TX.fromExtended = function fromExtended(data, saveCoins, enc) { if (typeof saveCoins === 'string') { enc = saveCoins; saveCoins = false; @@ -2627,7 +2508,7 @@ TX.fromExtended2 = function fromExtended2(data, saveCoins, enc) { if (typeof data === 'string') data = new Buffer(data, enc); - return new TX().fromExtended2(data, saveCoins); + return new TX().fromExtended(data, saveCoins); }; /** diff --git a/migrate/walletdb3to4.js b/migrate/walletdb3to4.js index 0a2921c4..c6a5b58e 100644 --- a/migrate/walletdb3to4.js +++ b/migrate/walletdb3to4.js @@ -4,6 +4,9 @@ var constants = require('../lib/protocol/constants'); var WalletDB = require('../lib/wallet/walletdb'); var TXDB = require('../lib/wallet/txdb'); var BufferWriter = require('../lib/utils/writer'); +var BufferReader = require('../lib/utils/reader'); +var TX = require('../lib/primitives/tx'); +var Coin = require('../lib/primitives/coin'); var utils = require('../lib/utils/utils'); var co = bcoin.co; var layout = WalletDB.layout; @@ -61,7 +64,7 @@ var updateTXDB = co(function* updateTXDB() { key = keys[i]; if (key[0] === 0x74 && key[5] === 0x74) { tx = yield db.get(key); - tx = bcoin.tx.fromExtended(tx); + tx = fromExtended(tx); hash = tx.hash('hex'); txs[hash] = tx; } @@ -91,6 +94,44 @@ var updateTXDB = co(function* updateTXDB() { yield walletdb.close(); }); +function fromExtended(data, saveCoins) { + var tx = new TX(); + var p = BufferReader(data); + var i, coinCount, coin; + + tx.fromRaw(p); + + tx.height = p.readU32(); + tx.block = p.readHash('hex'); + tx.index = p.readU32(); + tx.ts = p.readU32(); + tx.ps = p.readU32(); + + if (tx.block === constants.NULL_HASH) + tx.block = null; + + if (tx.height === 0x7fffffff) + tx.height = -1; + + if (tx.index === 0x7fffffff) + tx.index = -1; + + if (saveCoins) { + coinCount = p.readVarint(); + for (i = 0; i < coinCount; i++) { + coin = p.readVarBytes(); + if (coin.length === 0) + continue; + coin = Coin.fromRaw(coin); + coin.hash = tx.inputs[i].prevout.hash; + coin.index = tx.inputs[i].prevout.index; + tx.inputs[i].coin = coin; + } + } + + return tx; +} + co.spawn(function* () { yield db.open(); batch = db.batch(); diff --git a/test/data/tx4.hex b/test/data/tx4.hex index aa03f564..7e03fd09 100644 --- a/test/data/tx4.hex +++ b/test/data/tx4.hex @@ -1 +1,2 @@ -01000000018759d7397a86d6c42dfe2c55612e523d171e51708fec9e289118deb5ba99400101000000dc00493046022100da3264579decba370d0b5d896c5f4664dfdf06119cc3ca5cef937389e61b5bf1022100a5584aa704578d35080129edb22d2bea7a24f16f0603cc22a9390cdc0a8f6e6301483045022018478cf5c7ef4cf0b0b6583937bba83b76bf87461825f44130dbb854111a62d8022100e431be966081676b2d785a3260e2a50e250d8a2f5d8364309fe1195dfa87a31d01475221030c341a91e5de82732d6bfb1c3676585b817096cd8bf076cf0ea88c339b9815072102f3f450d36aced52de6023ca5e9d7e256d5c5183f3316211d53bb151c3585222e52ae000000000104c70300000000001976a914a532649591196c7ff3ebd5783c29c9a08d54a3a288ac370c05004a0c0500749180fd60334bdcbb7cfadad26ca3746367047cdd218635b315380200000000010000000db72b550000000001290100000098d9040014ee03000000000017a914195bde4cd150acf910b5c83a024fd2d9f33306af8700 +01000000018759d7397a86d6c42dfe2c55612e523d171e51708fec9e289118deb5ba99400101000000dc00493046022100da3264579decba370d0b5d896c5f4664dfdf06119cc3ca5cef937389e61b5bf1022100a5584aa704578d35080129edb22d2bea7a24f16f0603cc22a9390cdc0a8f6e6301483045022018478cf5c7ef4cf0b0b6583937bba83b76bf87461825f44130dbb854111a62d8022100e431be966081676b2d785a3260e2a50e250d8a2f5d8364309fe1195dfa87a31d01475221030c341a91e5de82732d6bfb1c3676585b817096cd8bf076cf0ea88c339b9815072102f3f450d36aced52de6023ca5e9d7e256d5c5183f3316211d53bb151c3585222e52ae000000000104c70300000000001976a914a532649591196c7ff3ebd5783c29c9a08d54a3a288ac370c0500 +0100000001c6ada6066f14a0cd4dc39f086f1f7637b76bfc08da5dc25f8179b0ccfc5d09f7000000006a473044022067934a2152ab5fe96119d702fc48322b967aee669a14e9da8913481d4b7f133402207e444ee1987fcb25ebcb9d98add22e3948ac847a67b306dba106d8e6ba48781001210297812667d2a62d7bbcf17e2d2ade2ade548a9464e9e8e29b42a777f85c93a48effffffff02f4ad2600000000001976a91454987f4e1ea17ec34a489d82ae9d39f6928e61cd88ac14ee03000000000017a914195bde4cd150acf910b5c83a024fd2d9f33306af8700000000 diff --git a/test/tx-test.js b/test/tx-test.js index eb0c4648..6f2911a1 100644 --- a/test/tx-test.js +++ b/test/tx-test.js @@ -14,7 +14,7 @@ var fs = require('fs'); var tx1 = parseTX('data/tx1.hex'); var tx2 = parseTX('data/tx2.hex'); var tx3 = parseTX('data/tx3.hex'); -var tx4 = parseExtended('data/tx4.hex'); +var tx4 = parseTX('data/tx4.hex'); var wtx = parseTX('data/wtx.hex'); var coolest = parseTX('data/coolest-tx-ever-sent.hex'); @@ -28,11 +28,6 @@ function parseTX(file) { return tx; } -function parseExtended(file) { - file = fs.readFileSync(__dirname + '/' + file, 'utf8').trim(); - return bcoin.tx.fromExtended(file, true, 'hex'); -} - function clearCache(tx, nocache) { var i, input, output; diff --git a/test/wallet-test.js b/test/wallet-test.js index 820d2a5b..979c484e 100644 --- a/test/wallet-test.js +++ b/test/wallet-test.js @@ -193,6 +193,8 @@ describe('Wallet', function() { t1.addInput(dummy()); t1.ts = utils.now(); t1.height = 1; + t1.block = constants.NULL_HASH; + t1.index = 0; // balance: 51000 yield w.sign(t1); @@ -291,6 +293,8 @@ describe('Wallet', function() { t2.ts = utils.now(); t2.height = 1; + t2.block = constants.NULL_HASH; + t2.index = 0; yield walletdb.addTX(t2); })); @@ -302,6 +306,8 @@ describe('Wallet', function() { tx.addInput(doubleSpend.coin); tx.ts = utils.now(); tx.height = 1; + tx.block = constants.NULL_HASH; + tx.index = 0; txs = yield w.getHistory(); assert.equal(txs.length, 5); @@ -353,6 +359,8 @@ describe('Wallet', function() { t1.addInput(dummy()); t1.ts = utils.now(); t1.height = 1; + t1.block = constants.NULL_HASH; + t1.index = 0; // balance: 51000 yield w.sign(t1); @@ -449,18 +457,26 @@ describe('Wallet', function() { t2.ts = utils.now(); t2.height = 1; + t2.block = constants.NULL_HASH; + t2.index = 0; yield walletdb.addTX(t2); t3.ts = utils.now(); t3.height = 1; + t3.block = constants.NULL_HASH; + t3.index = 0; yield walletdb.addTX(t3); t4.ts = utils.now(); t4.height = 1; + t4.block = constants.NULL_HASH; + t4.index = 0; yield walletdb.addTX(t4); f1.ts = utils.now(); f1.height = 1; + f1.block = constants.NULL_HASH; + f1.index = 0; yield walletdb.addTX(f1); balance = yield w.getBalance(); @@ -717,9 +733,10 @@ describe('Wallet', function() { utx = utx.toTX(); // Simulate a confirmation - utx.ps = 0; utx.ts = 1; utx.height = 1; + utx.block = constants.NULL_HASH; + utx.index = 0; assert.equal(w1[depth], 1); @@ -760,9 +777,10 @@ describe('Wallet', function() { assert.equal(w3.change.getAddress('base58'), change); // Simulate a confirmation - send.ps = 0; send.ts = 1; send.height = 1; + send.block = constants.NULL_HASH; + send.index = 0; yield walletdb.addTX(send); yield walletdb.addTX(send); @@ -1201,7 +1219,10 @@ describe('Wallet', function() { t1 = bcoin.mtx() .addOutput(addr, 50000); t1.addInput(dummy()); + t1.ts = utils.now(); + t1.block = constants.NULL_HASH; t1.height = 1; + t1.index = 0; yield alice.sign(t1); t1 = t1.toTX(); @@ -1244,11 +1265,15 @@ describe('Wallet', function() { // Bob sees t2 on the chain. t2.height = 3; t2.ts = utils.now(); + t2.block = constants.NULL_HASH; + t2.index = 0; yield bob.add(t2); // Bob sees t3 on the chain. t3.height = 3; t3.ts = utils.now(); + t3.block = constants.NULL_HASH; + t3.index = 0; yield bob.add(t3); assert.equal((yield bob.getBalance()).unconfirmed, 30000); @@ -1274,7 +1299,10 @@ describe('Wallet', function() { t1 = bcoin.mtx() .addOutput(addr, 50000); t1.addInput(dummy()); + t1.ts = utils.now(); + t1.block = constants.NULL_HASH; t1.height = 1; + t1.index = 0; yield alice.sign(t1); t1 = t1.toTX(); @@ -1328,11 +1356,15 @@ describe('Wallet', function() { // Bob sees t2 on the chain. t2.height = 3; t2.ts = utils.now(); + t2.block = constants.NULL_HASH; + t2.index = 0; yield bob.add(t2); // Bob sees t3 on the chain. t3.height = 3; t3.ts = utils.now(); + t3.block = constants.NULL_HASH; + t3.index = 0; yield bob.add(t3); assert.equal((yield bob.getBalance()).unconfirmed, 30000);