serialization: less polymorphism.
This commit is contained in:
parent
ba88ffab01
commit
a95aba92fb
@ -95,8 +95,8 @@ Payment.fromRaw = function fromRaw(data, enc) {
|
||||
return new Payment().fromRaw(data);
|
||||
};
|
||||
|
||||
Payment.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = new ProtoWriter(writer);
|
||||
Payment.prototype.toRaw = function toRaw() {
|
||||
var bw = new ProtoWriter();
|
||||
var i, tx, op, output;
|
||||
|
||||
if (this.merchantData)
|
||||
@ -118,10 +118,7 @@ Payment.prototype.toRaw = function toRaw(writer) {
|
||||
if (this.memo != null)
|
||||
bw.writeFieldString(4, this.memo);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
module.exports = Payment;
|
||||
|
||||
@ -54,18 +54,15 @@ PaymentACK.fromRaw = function fromRaw(data, enc) {
|
||||
return new PaymentACK().fromRaw(data);
|
||||
};
|
||||
|
||||
PaymentACK.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = new ProtoWriter(writer);
|
||||
PaymentACK.prototype.toRaw = function toRaw() {
|
||||
var bw = new ProtoWriter();
|
||||
|
||||
bw.writeFieldBytes(1, this.payment.toRaw());
|
||||
|
||||
if (this.memo != null)
|
||||
bw.writeFieldString(2, this.memo);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
module.exports = PaymentACK;
|
||||
|
||||
@ -147,8 +147,8 @@ PaymentDetails.fromRaw = function fromRaw(data, enc) {
|
||||
return new PaymentDetails().fromRaw(data);
|
||||
};
|
||||
|
||||
PaymentDetails.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = new ProtoWriter(writer);
|
||||
PaymentDetails.prototype.toRaw = function toRaw() {
|
||||
var bw = new ProtoWriter();
|
||||
var i, op, output;
|
||||
|
||||
if (this.network != null)
|
||||
@ -176,10 +176,7 @@ PaymentDetails.prototype.toRaw = function toRaw(writer) {
|
||||
if (this.merchantData)
|
||||
bw.writeFieldString(7, this.merchantData);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
module.exports = PaymentDetails;
|
||||
|
||||
@ -83,8 +83,8 @@ PaymentRequest.fromRaw = function fromRaw(data, enc) {
|
||||
return new PaymentRequest().fromRaw(data);
|
||||
};
|
||||
|
||||
PaymentRequest.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = new ProtoWriter(writer);
|
||||
PaymentRequest.prototype.toRaw = function toRaw() {
|
||||
var bw = new ProtoWriter();
|
||||
|
||||
if (this.version !== -1)
|
||||
bw.writeFieldU32(1, this.version);
|
||||
@ -100,10 +100,7 @@ PaymentRequest.prototype.toRaw = function toRaw(writer) {
|
||||
if (this.signature)
|
||||
bw.writeFieldBytes(5, this.signature);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
PaymentRequest.prototype.getAlgorithm = function getAlgorithm() {
|
||||
|
||||
@ -432,8 +432,8 @@ ChainEntry.fromBlock = function fromBlock(chain, block, prev) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
ChainEntry.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
ChainEntry.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
|
||||
bw.writeU32(this.version);
|
||||
bw.writeHash(this.prevBlock);
|
||||
@ -444,10 +444,7 @@ ChainEntry.prototype.toRaw = function toRaw(writer) {
|
||||
bw.writeU32(this.height);
|
||||
bw.writeBytes(this.chainwork.toArrayLike(Buffer, 'le', 32));
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -56,7 +56,7 @@ UndoCoins.prototype.toRaw = function toRaw() {
|
||||
|
||||
for (i = 0; i < this.items.length; i++) {
|
||||
coin = this.items[i];
|
||||
coin.toRaw(bw);
|
||||
coin.toWriter(bw);
|
||||
}
|
||||
|
||||
return bw.render();
|
||||
@ -75,7 +75,7 @@ UndoCoins.prototype.fromRaw = function fromRaw(data) {
|
||||
var i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
this.items.push(UndoCoin.fromRaw(br));
|
||||
this.items.push(UndoCoin.fromReader(br));
|
||||
|
||||
return this;
|
||||
};
|
||||
@ -187,12 +187,11 @@ UndoCoin.prototype.toOutput = function toOutput() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the undo coin.
|
||||
* @returns {Buffer}
|
||||
* Write the undo coin to a buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
*/
|
||||
|
||||
UndoCoin.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
UndoCoin.prototype.toWriter = function toWriter(bw) {
|
||||
var height = this.height;
|
||||
|
||||
assert(height !== 0);
|
||||
@ -214,21 +213,26 @@ UndoCoin.prototype.toRaw = function toRaw(writer) {
|
||||
compress.output(this.output, bw);
|
||||
}
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* Serialize the undo coin.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
UndoCoin.prototype.toRaw = function toRaw() {
|
||||
return this.toWriter(new BufferWriter()).render();
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from buffer reader.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
* @param {BufferReader} br
|
||||
* @returns {UndoCoin}
|
||||
*/
|
||||
|
||||
UndoCoin.prototype.fromRaw = function fromRaw(data) {
|
||||
var br = new BufferReader(data);
|
||||
UndoCoin.prototype.fromReader = function fromReader(br) {
|
||||
var code = br.readVarint();
|
||||
|
||||
this.output = new Output();
|
||||
@ -248,6 +252,27 @@ UndoCoin.prototype.fromRaw = function fromRaw(data) {
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
* @returns {UndoCoin}
|
||||
*/
|
||||
|
||||
UndoCoin.prototype.fromRaw = function fromRaw(data) {
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate undo coin from serialized data.
|
||||
* @param {Buffer} data
|
||||
* @returns {UndoCoin}
|
||||
*/
|
||||
|
||||
UndoCoin.fromReader = function fromReader(br) {
|
||||
return new UndoCoin().fromReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate undo coin from serialized data.
|
||||
* @param {Buffer} data
|
||||
|
||||
@ -414,12 +414,11 @@ Mnemonic.fromJSON = function fromJSON(json) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize mnemonic.
|
||||
* @returns {Buffer}
|
||||
* Write the mnemonic to a buffer writer.
|
||||
* @params {BufferWriter} bw
|
||||
*/
|
||||
|
||||
Mnemonic.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
Mnemonic.prototype.toWriter = function toWriter(bw) {
|
||||
var lang = Mnemonic.languages.indexOf(this.language);
|
||||
|
||||
assert(lang !== -1);
|
||||
@ -430,21 +429,25 @@ Mnemonic.prototype.toRaw = function toRaw(writer) {
|
||||
bw.writeVarString(this.getPhrase(), 'utf8');
|
||||
bw.writeVarString(this.passphrase, 'utf8');
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
* Serialize mnemonic.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
Mnemonic.prototype.fromRaw = function fromRaw(data) {
|
||||
var br = new BufferReader(data);
|
||||
Mnemonic.prototype.toRaw = function toRaw(writer) {
|
||||
return this.toWriter(new BufferWriter()).render();
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from buffer reader.
|
||||
* @private
|
||||
* @param {BufferReader} br
|
||||
*/
|
||||
|
||||
Mnemonic.prototype.fromReader = function fromReader(br) {
|
||||
this.bits = br.readU16();
|
||||
this.language = Mnemonic.languages[br.readU8()];
|
||||
this.entropy = br.readBytes(this.bits / 8);
|
||||
@ -459,6 +462,26 @@ Mnemonic.prototype.fromRaw = function fromRaw(data) {
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
Mnemonic.prototype.fromRaw = function fromRaw(data) {
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate mnemonic from buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @returns {Mnemonic}
|
||||
*/
|
||||
|
||||
Mnemonic.fromReader = function fromReader(br) {
|
||||
return new Mnemonic().fromReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate mnemonic from serialized data.
|
||||
* @param {Buffer} data
|
||||
|
||||
@ -623,8 +623,7 @@ HDPrivateKey.prototype.fromBase58 = function fromBase58(xkey) {
|
||||
* @param {Buffer} raw
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.fromRaw = function fromRaw(raw) {
|
||||
var br = new BufferReader(raw);
|
||||
HDPrivateKey.prototype.fromReader = function fromReader(br) {
|
||||
var i, version, type, prefix;
|
||||
|
||||
version = br.readU32BE();
|
||||
@ -651,6 +650,16 @@ HDPrivateKey.prototype.fromRaw = function fromRaw(raw) {
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} raw
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.fromRaw = function fromRaw(raw) {
|
||||
return this.fromReader(new BufferReader(raw));
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize key to a base58 string.
|
||||
* @param {(Network|NetworkType)?} network
|
||||
@ -662,14 +671,12 @@ HDPrivateKey.prototype.toBase58 = function toBase58(network) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the key.
|
||||
* Write the key to a buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.toRaw = function toRaw(network, writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
|
||||
HDPrivateKey.prototype.toWriter = function toWriter(bw, network) {
|
||||
if (!network)
|
||||
network = this.network;
|
||||
|
||||
@ -684,8 +691,35 @@ HDPrivateKey.prototype.toRaw = function toRaw(network, writer) {
|
||||
bw.writeBytes(this.privateKey);
|
||||
bw.writeChecksum();
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the key.
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.toRaw = function toRaw(network) {
|
||||
return this.toWriter(new BufferWriter(), network).render();
|
||||
};
|
||||
|
||||
/**
|
||||
* Write the key in "extended"
|
||||
* format to a buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
* @param {(Network|NetworkType)?} network
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.toExtendedWriter = function toExtendedWriter(bw, network) {
|
||||
this.toWriter(bw, network);
|
||||
|
||||
if (this.mnemonic) {
|
||||
bw.writeU8(1);
|
||||
this.mnemonic.toWriter(bw);
|
||||
} else {
|
||||
bw.writeU8(0);
|
||||
}
|
||||
|
||||
return bw;
|
||||
};
|
||||
@ -697,22 +731,21 @@ HDPrivateKey.prototype.toRaw = function toRaw(network, writer) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.toExtended = function toExtended(network, writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
HDPrivateKey.prototype.toExtended = function toExtended(network) {
|
||||
return this.toExtendedWriter(new BufferWriter(), network).render();
|
||||
};
|
||||
|
||||
this.toRaw(network, bw);
|
||||
/**
|
||||
* Inject properties from buffer reader.
|
||||
* @private
|
||||
* @param {BufferReader} br
|
||||
*/
|
||||
|
||||
if (this.mnemonic) {
|
||||
bw.writeU8(1);
|
||||
this.mnemonic.toRaw(bw);
|
||||
} else {
|
||||
bw.writeU8(0);
|
||||
}
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
HDPrivateKey.prototype.fromExtendedReader = function fromExtendedReader(br) {
|
||||
this.fromReader(br);
|
||||
if (br.readU8() === 1)
|
||||
this.mnemonic = Mnemonic.fromReader(br);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -722,11 +755,17 @@ HDPrivateKey.prototype.toExtended = function toExtended(network, writer) {
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.fromExtended = function fromExtended(data) {
|
||||
var br = new BufferReader(data);
|
||||
this.fromRaw(br);
|
||||
if (br.readU8() === 1)
|
||||
this.mnemonic = Mnemonic.fromRaw(br);
|
||||
return this;
|
||||
return this.fromExtendedReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate key from "extended" buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @returns {HDPrivateKey}
|
||||
*/
|
||||
|
||||
HDPrivateKey.fromExtendedReader = function fromExtendedReader(br) {
|
||||
return new HDPrivateKey().fromExtendedReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -749,6 +788,16 @@ HDPrivateKey.fromBase58 = function fromBase58(xkey) {
|
||||
return new HDPrivateKey().fromBase58(xkey);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate key from buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @returns {HDPrivateKey}
|
||||
*/
|
||||
|
||||
HDPrivateKey.fromReader = function fromReader(br) {
|
||||
return new HDPrivateKey().fromReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate key from serialized data.
|
||||
* @param {Buffer} raw
|
||||
|
||||
@ -485,8 +485,7 @@ HDPublicKey.prototype.fromBase58 = function fromBase58(xkey) {
|
||||
* @param {Buffer} raw
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.fromRaw = function fromRaw(raw) {
|
||||
var br = new BufferReader(raw);
|
||||
HDPublicKey.prototype.fromReader = function fromReader(br) {
|
||||
var i, version, type, prefix;
|
||||
|
||||
version = br.readU32BE();
|
||||
@ -511,6 +510,16 @@ HDPublicKey.prototype.fromRaw = function fromRaw(raw) {
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} raw
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.fromRaw = function fromRaw(raw) {
|
||||
return this.fromReader(new BufferReader(raw));
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize key data to base58 extended key.
|
||||
* @param {Network|String} network
|
||||
@ -522,14 +531,12 @@ HDPublicKey.prototype.toBase58 = function toBase58(network) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the key.
|
||||
* Write the key to a buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
* @param {Network|NetworkType} network
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.toRaw = function toRaw(network, writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
|
||||
HDPublicKey.prototype.toWriter = function toWriter(bw, network) {
|
||||
if (!network)
|
||||
network = this.network;
|
||||
|
||||
@ -543,12 +550,19 @@ HDPublicKey.prototype.toRaw = function toRaw(network, writer) {
|
||||
bw.writeBytes(this.publicKey);
|
||||
bw.writeChecksum();
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the key.
|
||||
* @param {Network|NetworkType} network
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.toRaw = function toRaw(network) {
|
||||
return this.toWriter(new BufferWriter(), network).render();
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate an HD public key from a base58 string.
|
||||
* @param {Base58String} xkey
|
||||
@ -559,6 +573,16 @@ HDPublicKey.fromBase58 = function fromBase58(xkey) {
|
||||
return new HDPublicKey().fromBase58(xkey);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate key from serialized data.
|
||||
* @param {BufferReader} br
|
||||
* @returns {HDPublicKey}
|
||||
*/
|
||||
|
||||
HDPublicKey.fromReader = function fromReader(br) {
|
||||
return new HDPublicKey().fromReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate key from serialized data.
|
||||
* @param {Buffer} raw
|
||||
|
||||
@ -2163,7 +2163,7 @@ RPC.prototype.signrawtransaction = co(function* signrawtransaction(args) {
|
||||
txs = [];
|
||||
|
||||
while (br.left())
|
||||
txs.push(MTX.fromRaw(br));
|
||||
txs.push(MTX.fromReader(br));
|
||||
|
||||
merged = txs[0];
|
||||
|
||||
|
||||
@ -320,8 +320,8 @@ ConfirmStats.prototype.removeTX = function removeTX(entryHeight, bestHeight, buc
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
ConfirmStats.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
ConfirmStats.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
var i;
|
||||
|
||||
function writeArray(buckets) {
|
||||
@ -342,10 +342,7 @@ ConfirmStats.prototype.toRaw = function toRaw(writer) {
|
||||
for (i = 0; i < this.maxConfirms; i++)
|
||||
writeArray(this.confAvg[i]);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -805,18 +802,15 @@ PolicyEstimator.prototype.estimatePriority = function estimatePriority(target, s
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
PolicyEstimator.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
PolicyEstimator.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
|
||||
bw.writeU32(this.network.magic);
|
||||
bw.writeU32(this.bestHeight);
|
||||
bw.writeVarBytes(this.feeStats.toRaw());
|
||||
bw.writeVarBytes(this.priStats.toRaw());
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -116,8 +116,8 @@ CompactBlock.prototype.fromRaw = function fromRaw(data) {
|
||||
index = br.readVarint();
|
||||
assert(index <= 0xffff);
|
||||
assert(index < this.totalTX);
|
||||
tx = TX.fromRaw(br);
|
||||
this.ptx.push([index, tx]);
|
||||
tx = TX.fromReader(br);
|
||||
this.ptx.push(new PrefilledTX(index, tx));
|
||||
}
|
||||
|
||||
this.init();
|
||||
@ -131,16 +131,27 @@ CompactBlock.fromRaw = function fromRaw(data, enc) {
|
||||
return new CompactBlock().fromRaw(data);
|
||||
};
|
||||
|
||||
CompactBlock.prototype.toRaw = function toRaw(writer) {
|
||||
return this.frame(true, writer);
|
||||
CompactBlock.prototype.toRaw = function toRaw() {
|
||||
return this.frame(true);
|
||||
};
|
||||
|
||||
CompactBlock.prototype.toNormal = function toNormal(writer) {
|
||||
return this.frame(false, writer);
|
||||
CompactBlock.prototype.toNormal = function toNormal() {
|
||||
return this.frame(false);
|
||||
};
|
||||
|
||||
CompactBlock.prototype.frame = function frame(witness, writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
CompactBlock.prototype.toWriter = function toWriter(bw) {
|
||||
return this.frameWriter(bw, true);
|
||||
};
|
||||
|
||||
CompactBlock.prototype.toNormalWriter = function toNormalWriter(bw) {
|
||||
return this.frameWriter(bw, false);
|
||||
};
|
||||
|
||||
CompactBlock.prototype.frame = function frame(witness) {
|
||||
return this.frameWriter(new BufferWriter(), witness).render();
|
||||
};
|
||||
|
||||
CompactBlock.prototype.frameWriter = function frameWriter(bw, witness) {
|
||||
var i, id, lo, hi, ptx;
|
||||
|
||||
bw.writeU32(this.version);
|
||||
@ -167,16 +178,13 @@ CompactBlock.prototype.frame = function frame(witness, writer) {
|
||||
|
||||
for (i = 0; i < this.ptx.length; i++) {
|
||||
ptx = this.ptx[i];
|
||||
bw.writeVarint(ptx[0]);
|
||||
bw.writeVarint(ptx.index);
|
||||
if (witness)
|
||||
ptx[1].toRaw(bw);
|
||||
ptx.tx.toWriter(bw);
|
||||
else
|
||||
ptx[1].toNormal(bw);
|
||||
ptx.tx.toNormalWriter(bw);
|
||||
}
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
};
|
||||
|
||||
@ -286,10 +294,10 @@ CompactBlock.prototype.init = function init() {
|
||||
for (i = 0; i < this.ptx.length; i++) {
|
||||
ptx = this.ptx[i];
|
||||
assert(ptx);
|
||||
last += ptx[0] + 1;
|
||||
last += ptx.index + 1;
|
||||
assert(last <= 0xffff);
|
||||
assert(last <= this.ids.length + i);
|
||||
this.available[last] = ptx[1];
|
||||
this.available[last] = ptx.tx;
|
||||
this.count++;
|
||||
}
|
||||
|
||||
@ -364,7 +372,7 @@ CompactBlock.prototype.fromBlock = function fromBlock(block, witness, nonce) {
|
||||
this.ids.push(id);
|
||||
}
|
||||
|
||||
this.ptx.push([0, block.txs[0]]);
|
||||
this.ptx.push(new PrefilledTX(0, block.txs[0]));
|
||||
|
||||
return this;
|
||||
};
|
||||
@ -455,8 +463,7 @@ TXRequest.fromCompact = function fromCompact(block) {
|
||||
return new TXRequest().fromCompact(block);
|
||||
};
|
||||
|
||||
TXRequest.prototype.fromRaw = function fromRaw(data) {
|
||||
var br = BufferReader(data);
|
||||
TXRequest.prototype.fromReader = function fromReader(br) {
|
||||
var i, count, index, offset;
|
||||
|
||||
this.hash = br.readHash('hex');
|
||||
@ -482,12 +489,19 @@ TXRequest.prototype.fromRaw = function fromRaw(data) {
|
||||
return this;
|
||||
};
|
||||
|
||||
TXRequest.prototype.fromRaw = function fromRaw(data) {
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
TXRequest.fromReader = function fromReader(br) {
|
||||
return new TXRequest().fromReader(br);
|
||||
};
|
||||
|
||||
TXRequest.fromRaw = function fromRaw(data) {
|
||||
return new TXRequest().fromRaw(data);
|
||||
};
|
||||
|
||||
TXRequest.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
TXRequest.prototype.toWriter = function toWriter(bw) {
|
||||
var i, index;
|
||||
|
||||
bw.writeHash(this.hash);
|
||||
@ -499,12 +513,13 @@ TXRequest.prototype.toRaw = function toRaw(writer) {
|
||||
bw.writeVarint(index);
|
||||
}
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
};
|
||||
|
||||
TXRequest.prototype.toRaw = function toRaw() {
|
||||
return this.toWriter(new BufferWriter()).render();
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents BlockTransactions (bip152): `blocktxn` packet.
|
||||
* @see https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki
|
||||
@ -535,8 +550,7 @@ TXResponse.fromOptions = function fromOptions(options) {
|
||||
return new TXResponse().fromOptions(options);
|
||||
};
|
||||
|
||||
TXResponse.prototype.fromRaw = function fromRaw(data) {
|
||||
var br = BufferReader(data);
|
||||
TXResponse.prototype.fromReader = function fromReader(br) {
|
||||
var i, count;
|
||||
|
||||
this.hash = br.readHash('hex');
|
||||
@ -544,11 +558,19 @@ TXResponse.prototype.fromRaw = function fromRaw(data) {
|
||||
count = br.readVarint();
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
this.txs.push(TX.fromRaw(br));
|
||||
this.txs.push(TX.fromReader(br));
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
TXResponse.prototype.fromRaw = function fromRaw(data) {
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
TXResponse.fromReader = function fromReader(br) {
|
||||
return new TXResponse().fromReader(br);
|
||||
};
|
||||
|
||||
TXResponse.fromRaw = function fromRaw(data) {
|
||||
return new TXResponse().fromRaw(data);
|
||||
};
|
||||
@ -572,16 +594,23 @@ TXResponse.fromBlock = function fromBlock(block, req) {
|
||||
return new TXResponse().fromBlock(block, req);
|
||||
};
|
||||
|
||||
TXResponse.prototype.toRaw = function toRaw(writer) {
|
||||
return this.frame(true, writer);
|
||||
TXResponse.prototype.toRaw = function toRaw() {
|
||||
return this.frame(true);
|
||||
};
|
||||
|
||||
TXResponse.prototype.toNormal = function toNormal(writer) {
|
||||
return this.frame(false, writer);
|
||||
TXResponse.prototype.toNormal = function toNormal() {
|
||||
return this.frame(false);
|
||||
};
|
||||
|
||||
TXResponse.prototype.frame = function frame(witness, writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
TXResponse.prototype.toWriter = function toWriter(bw) {
|
||||
return this.frameWriter(bw, true);
|
||||
};
|
||||
|
||||
TXResponse.prototype.toNormalWriter = function toNormalWriter(bw) {
|
||||
return this.frameWriter(bw, false);
|
||||
};
|
||||
|
||||
TXResponse.prototype.frameWriter = function frameWriter(bw, witness) {
|
||||
var i, tx;
|
||||
|
||||
bw.writeHash(this.hash);
|
||||
@ -591,17 +620,27 @@ TXResponse.prototype.frame = function frame(witness, writer) {
|
||||
for (i = 0; i < this.txs.length; i++) {
|
||||
tx = this.txs[i];
|
||||
if (witness)
|
||||
tx.toRaw(bw);
|
||||
tx.toWriter(bw);
|
||||
else
|
||||
tx.toNormal(bw);
|
||||
tx.toNormalWriter(bw);
|
||||
}
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
};
|
||||
|
||||
TXResponse.prototype.frame = function frame(witness) {
|
||||
return this.frameWriter(new BufferWriter(), witness).render();
|
||||
};
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function PrefilledTX(index, tx) {
|
||||
this.index = index;
|
||||
this.tx = tx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
@ -186,23 +186,20 @@ VersionPacket.fromOptions = function fromOptions(options) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
VersionPacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
VersionPacket.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
|
||||
bw.write32(this.version);
|
||||
bw.writeU64(this.services);
|
||||
bw.write64(this.ts);
|
||||
this.recv.toRaw(false, bw);
|
||||
this.from.toRaw(false, bw);
|
||||
this.recv.toWriter(bw, false);
|
||||
this.from.toWriter(bw, false);
|
||||
bw.writeBytes(this.nonce);
|
||||
bw.writeVarString(this.agent, 'ascii');
|
||||
bw.write32(this.height);
|
||||
bw.writeU8(this.relay ? 1 : 0);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -272,10 +269,10 @@ VersionPacket.prototype.fromRaw = function fromRaw(data) {
|
||||
this.version = br.read32();
|
||||
this.services = br.readU53();
|
||||
this.ts = br.read53();
|
||||
this.recv.fromRaw(br, false);
|
||||
this.recv.fromReader(br, false);
|
||||
|
||||
if (br.left() > 0) {
|
||||
this.from.fromRaw(br, false);
|
||||
this.from.fromReader(br, false);
|
||||
this.nonce = br.readBytes(8);
|
||||
}
|
||||
|
||||
@ -332,8 +329,8 @@ VerackPacket.prototype.type = exports.types.VERACK;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
VerackPacket.prototype.toRaw = function toRaw(writer) {
|
||||
return writer || DUMMY;
|
||||
VerackPacket.prototype.toRaw = function toRaw() {
|
||||
return DUMMY;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -386,16 +383,13 @@ PingPacket.prototype.type = exports.types.PING;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
PingPacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
PingPacket.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
|
||||
if (this.nonce)
|
||||
bw.writeBytes(this.nonce);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -451,15 +445,10 @@ PongPacket.prototype.type = exports.types.PONG;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
PongPacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
|
||||
PongPacket.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
bw.writeBytes(this.nonce);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -650,20 +639,24 @@ AlertPacket.prototype.verify = function verify(key) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the alert packet (includes payload _and_ signature).
|
||||
* Write the alert packet to a buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
*/
|
||||
|
||||
AlertPacket.prototype.toWriter = function toWriter(bw) {
|
||||
bw.writeVarBytes(this.toPayload());
|
||||
bw.writeVarBytes(this.signature);
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the alert packet (includes
|
||||
* payload _and_ signature).
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
AlertPacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
|
||||
bw.writeVarBytes(this.toPayload());
|
||||
bw.writeVarBytes(this.signature);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
AlertPacket.prototype.toRaw = function toRaw() {
|
||||
return this.toWriter(new BufferWriter()).render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -672,8 +665,8 @@ AlertPacket.prototype.toRaw = function toRaw(writer) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
AlertPacket.prototype.framePayload = function framePayload(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
AlertPacket.prototype.framePayload = function framePayload() {
|
||||
var bw = new BufferWriter();
|
||||
var i;
|
||||
|
||||
bw.write32(this.version);
|
||||
@ -698,26 +691,22 @@ AlertPacket.prototype.framePayload = function framePayload(writer) {
|
||||
bw.writeVarString(this.statusBar, 'ascii');
|
||||
bw.writeVarString(this.reserved, 'ascii');
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* Inject properties from buffer reader.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
* @param {BufferReader} br
|
||||
*/
|
||||
|
||||
AlertPacket.prototype.fromRaw = function fromRaw(data) {
|
||||
var br = BufferReader(data);
|
||||
AlertPacket.prototype.fromReader = function fromReader(br) {
|
||||
var i, count;
|
||||
|
||||
this._payload = br.readVarBytes();
|
||||
this.signature = br.readVarBytes();
|
||||
|
||||
br = BufferReader(this._payload);
|
||||
br = new BufferReader(this._payload);
|
||||
|
||||
this.version = br.read32();
|
||||
this.relayUntil = br.read53();
|
||||
@ -744,6 +733,26 @@ AlertPacket.prototype.fromRaw = function fromRaw(data) {
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
AlertPacket.prototype.fromRaw = function fromRaw(data) {
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate alert packet from buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @returns {AlertPacket}
|
||||
*/
|
||||
|
||||
AlertPacket.fromReader = function fromReader(br) {
|
||||
return new AlertPacket().fromReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate alert packet from serialized data.
|
||||
* @param {Buffer} data
|
||||
@ -780,8 +789,8 @@ GetAddrPacket.prototype.type = exports.types.GETADDR;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
GetAddrPacket.prototype.toRaw = function toRaw(writer) {
|
||||
return writer || DUMMY;
|
||||
GetAddrPacket.prototype.toRaw = function toRaw() {
|
||||
return DUMMY;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -834,19 +843,16 @@ AddrPacket.prototype.type = exports.types.ADDR;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
AddrPacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
AddrPacket.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
var i;
|
||||
|
||||
bw.writeVarint(this.items.length);
|
||||
|
||||
for (i = 0; i < this.items.length; i++)
|
||||
this.items[i].toRaw(true, bw);
|
||||
this.items[i].toWriter(bw, true);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -862,7 +868,7 @@ AddrPacket.prototype.fromRaw = function fromRaw(data) {
|
||||
count = br.readVarint();
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
this.items.push(NetworkAddress.fromRaw(br, true));
|
||||
this.items.push(NetworkAddress.fromReader(br, true));
|
||||
|
||||
return this;
|
||||
};
|
||||
@ -907,19 +913,16 @@ InvPacket.prototype.type = exports.types.INV;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
InvPacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
InvPacket.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
var i;
|
||||
|
||||
bw.writeVarint(this.items.length);
|
||||
|
||||
for (i = 0; i < this.items.length; i++)
|
||||
this.items[i].toRaw(bw);
|
||||
this.items[i].toWriter(bw);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -929,13 +932,13 @@ InvPacket.prototype.toRaw = function toRaw(writer) {
|
||||
*/
|
||||
|
||||
InvPacket.prototype.fromRaw = function fromRaw(data) {
|
||||
var br = BufferReader(data);
|
||||
var br = new BufferReader(data);
|
||||
var i, count;
|
||||
|
||||
count = br.readVarint();
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
this.items.push(InvItem.fromRaw(br));
|
||||
this.items.push(InvItem.fromReader(br));
|
||||
|
||||
return this;
|
||||
};
|
||||
@ -1050,8 +1053,8 @@ GetBlocksPacket.prototype.type = exports.types.GETBLOCKS;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
GetBlocksPacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
GetBlocksPacket.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
var i;
|
||||
|
||||
bw.writeU32(this.version);
|
||||
@ -1062,10 +1065,7 @@ GetBlocksPacket.prototype.toRaw = function toRaw(writer) {
|
||||
|
||||
bw.writeHash(this.stop || constants.ZERO_HASH);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1167,19 +1167,16 @@ HeadersPacket.prototype.type = exports.types.HEADERS;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
HeadersPacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
HeadersPacket.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
var i;
|
||||
|
||||
bw.writeVarint(this.items.length);
|
||||
|
||||
for (i = 0; i < this.items.length; i++)
|
||||
this.items[i].toRaw(bw);
|
||||
this.items[i].toWriter(bw);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1195,7 +1192,7 @@ HeadersPacket.prototype.fromRaw = function fromRaw(data) {
|
||||
count = br.readVarint();
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
this.items.push(Headers.fromRaw(br));
|
||||
this.items.push(Headers.fromReader(br));
|
||||
|
||||
return this;
|
||||
};
|
||||
@ -1236,8 +1233,8 @@ SendHeadersPacket.prototype.type = exports.types.SENDHEADERS;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
SendHeadersPacket.prototype.toRaw = function toRaw(writer) {
|
||||
return writer || DUMMY;
|
||||
SendHeadersPacket.prototype.toRaw = function toRaw() {
|
||||
return DUMMY;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1293,10 +1290,10 @@ BlockPacket.prototype.type = exports.types.BLOCK;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
BlockPacket.prototype.toRaw = function toRaw(writer) {
|
||||
BlockPacket.prototype.toRaw = function toRaw() {
|
||||
if (this.witness)
|
||||
return this.block.toRaw(writer);
|
||||
return this.block.toNormal(writer);
|
||||
return this.block.toRaw();
|
||||
return this.block.toNormal();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1353,10 +1350,10 @@ TXPacket.prototype.type = exports.types.TX;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
TXPacket.prototype.toRaw = function toRaw(writer) {
|
||||
TXPacket.prototype.toRaw = function toRaw() {
|
||||
if (this.witness)
|
||||
return this.tx.toRaw(writer);
|
||||
return this.tx.toNormal(writer);
|
||||
return this.tx.toRaw();
|
||||
return this.tx.toNormal();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1460,8 +1457,8 @@ RejectPacket.fromOptions = function fromOptions(options) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
RejectPacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
RejectPacket.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
|
||||
assert(this.message.length <= 12);
|
||||
assert(this.reason.length <= 111);
|
||||
@ -1473,10 +1470,7 @@ RejectPacket.prototype.toRaw = function toRaw(writer) {
|
||||
if (this.data)
|
||||
bw.writeHash(this.data);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1603,8 +1597,8 @@ MempoolPacket.prototype.type = exports.types.MEMPOOL;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
MempoolPacket.prototype.toRaw = function toRaw(writer) {
|
||||
return writer || DUMMY;
|
||||
MempoolPacket.prototype.toRaw = function toRaw() {
|
||||
return DUMMY;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1656,8 +1650,8 @@ FilterLoadPacket.prototype.type = exports.types.FILTERLOAD;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
FilterLoadPacket.prototype.toRaw = function toRaw(writer) {
|
||||
return this.filter.toRaw(writer);
|
||||
FilterLoadPacket.prototype.toRaw = function toRaw() {
|
||||
return this.filter.toRaw();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1726,15 +1720,10 @@ FilterAddPacket.prototype.type = exports.types.FILTERADD;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
FilterAddPacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
|
||||
FilterAddPacket.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
bw.writeVarBytes(this.data);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1785,8 +1774,8 @@ FilterClearPacket.prototype.type = exports.types.FILTERCLEAR;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
FilterClearPacket.prototype.toRaw = function toRaw(writer) {
|
||||
return writer || DUMMY;
|
||||
FilterClearPacket.prototype.toRaw = function toRaw() {
|
||||
return DUMMY;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1839,8 +1828,8 @@ MerkleBlockPacket.prototype.type = exports.types.MERKLEBLOCK;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
MerkleBlockPacket.prototype.toRaw = function toRaw(writer) {
|
||||
return this.block.toRaw(writer);
|
||||
MerkleBlockPacket.prototype.toRaw = function toRaw() {
|
||||
return this.block.toRaw();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1897,20 +1886,17 @@ GetUTXOsPacket.prototype.type = exports.types.GETUTXOS;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
GetUTXOsPacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
GetUTXOsPacket.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
var i;
|
||||
|
||||
bw.writeU8(this.mempool ? 1 : 0);
|
||||
bw.writeVarint(this.prevout.length);
|
||||
|
||||
for (i = 0; i < this.prevout.length; i++)
|
||||
this.prevout[i].toRaw(bw);
|
||||
this.prevout[i].toWriter(bw);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1928,7 +1914,7 @@ GetUTXOsPacket.prototype.fromRaw = function fromRaw(data) {
|
||||
count = br.readVarint();
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
this.prevout.push(Outpoint.fromRaw(br));
|
||||
this.prevout.push(Outpoint.fromReader(br));
|
||||
|
||||
return this;
|
||||
};
|
||||
@ -2023,8 +2009,8 @@ UTXOsPacket.fromOptions = function fromOptions(options) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
UTXOsPacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
UTXOsPacket.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
var map = new Buffer((this.hits.length + 7) / 8 | 0);
|
||||
var i, bit, oct, coin, height;
|
||||
|
||||
@ -2052,10 +2038,7 @@ UTXOsPacket.prototype.toRaw = function toRaw(writer) {
|
||||
bw.writeVarBytes(coin.script.toRaw());
|
||||
}
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2089,7 +2072,7 @@ UTXOsPacket.prototype.fromRaw = function fromRaw(data) {
|
||||
if (height === 0x7fffffff)
|
||||
height = -1;
|
||||
|
||||
output = Output.fromRaw(br);
|
||||
output = Output.fromReader(br);
|
||||
|
||||
coin.version = version;
|
||||
coin.height = height;
|
||||
@ -2138,8 +2121,8 @@ HaveWitnessPacket.prototype.type = exports.types.HAVEWITNESS;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
HaveWitnessPacket.prototype.toRaw = function toRaw(writer) {
|
||||
return writer || DUMMY;
|
||||
HaveWitnessPacket.prototype.toRaw = function toRaw() {
|
||||
return DUMMY;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2192,15 +2175,10 @@ FeeFilterPacket.prototype.type = exports.types.FEEFILTER;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
FeeFilterPacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
|
||||
FeeFilterPacket.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
bw.write64(this.rate);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2258,16 +2236,11 @@ SendCmpctPacket.prototype.type = exports.types.SENDCMPCT;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
SendCmpctPacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
|
||||
SendCmpctPacket.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
bw.writeU8(this.mode);
|
||||
bw.writeU64(this.version);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2326,10 +2299,10 @@ CmpctBlockPacket.prototype.type = exports.types.CMPCTBLOCK;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
CmpctBlockPacket.prototype.toRaw = function toRaw(writer) {
|
||||
CmpctBlockPacket.prototype.toRaw = function toRaw() {
|
||||
if (this.witness)
|
||||
return this.block.toRaw(writer);
|
||||
return this.block.toNormal(writer);
|
||||
return this.block.toRaw();
|
||||
return this.block.toNormal();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2383,8 +2356,8 @@ GetBlockTxnPacket.prototype.type = exports.types.GETBLOCKTXN;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
GetBlockTxnPacket.prototype.toRaw = function toRaw(writer) {
|
||||
return this.request.toRaw(writer);
|
||||
GetBlockTxnPacket.prototype.toRaw = function toRaw() {
|
||||
return this.request.toRaw();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2441,10 +2414,10 @@ BlockTxnPacket.prototype.type = exports.types.BLOCKTXN;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
BlockTxnPacket.prototype.toRaw = function toRaw(writer) {
|
||||
BlockTxnPacket.prototype.toRaw = function toRaw() {
|
||||
if (this.witness)
|
||||
return this.response.toRaw(writer);
|
||||
return this.response.toNormal(writer);
|
||||
return this.response.toRaw();
|
||||
return this.response.toNormal();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2501,16 +2474,11 @@ EncinitPacket.prototype.type = exports.types.ENCINIT;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
EncinitPacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
|
||||
EncinitPacket.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
bw.writeBytes(this.publicKey);
|
||||
bw.writeU8(this.cipher);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2566,15 +2534,10 @@ EncackPacket.prototype.type = exports.types.ENCACK;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
EncackPacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
|
||||
EncackPacket.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
bw.writeBytes(this.publicKey);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2629,15 +2592,10 @@ AuthChallengePacket.prototype.type = exports.types.AUTHCHALLENGE;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
AuthChallengePacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
|
||||
AuthChallengePacket.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
bw.writeBytes(this.hash);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2692,15 +2650,10 @@ AuthReplyPacket.prototype.type = exports.types.AUTHREPLY;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
AuthReplyPacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
|
||||
AuthReplyPacket.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
bw.writeBytes(this.signature);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2755,15 +2708,10 @@ AuthProposePacket.prototype.type = exports.types.AUTHPROPOSE;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
AuthProposePacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
|
||||
AuthProposePacket.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
bw.writeBytes(this.hash);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2820,15 +2768,10 @@ UnknownPacket.prototype.type = exports.types.UNKNOWN;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
UnknownPacket.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
|
||||
UnknownPacket.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
bw.writeBytes(this.data);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -52,6 +52,7 @@ function AbstractBlock(options) {
|
||||
|
||||
this.txs = null;
|
||||
this.mutable = false;
|
||||
this.memory = false;
|
||||
|
||||
this._valid = null;
|
||||
this._validHeaders = null;
|
||||
@ -165,20 +166,15 @@ AbstractBlock.prototype.hash = function hash(enc) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
AbstractBlock.prototype.abbr = function abbr(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
|
||||
AbstractBlock.prototype.abbr = function abbr() {
|
||||
var bw = new BufferWriter();
|
||||
bw.writeU32(this.version);
|
||||
bw.writeHash(this.prevBlock);
|
||||
bw.writeHash(this.merkleRoot);
|
||||
bw.writeU32(this.ts);
|
||||
bw.writeU32(this.bits);
|
||||
bw.writeU32(this.nonce);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -176,11 +176,9 @@ Address.prototype.inspect = function inspect() {
|
||||
*/
|
||||
|
||||
Address.prototype.fromRaw = function fromRaw(data) {
|
||||
var i, br, prefix, network, type, version, hash;
|
||||
var br = new BufferReader(data, true);
|
||||
var i, prefix, network, type, version, hash;
|
||||
|
||||
assert(Buffer.isBuffer(data));
|
||||
|
||||
br = new BufferReader(data, true);
|
||||
prefix = br.readU8();
|
||||
|
||||
for (i = 0; i < networks.types.length; i++) {
|
||||
|
||||
@ -43,7 +43,6 @@ function Block(options) {
|
||||
this._raw = null;
|
||||
this._size = -1;
|
||||
this._witnessSize = -1;
|
||||
this._lastWitnessSize = 0;
|
||||
|
||||
if (options)
|
||||
this.fromOptions(options);
|
||||
@ -81,13 +80,8 @@ Block.fromOptions = function fromOptions(options) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
Block.prototype.toRaw = function toRaw(writer) {
|
||||
var raw = this.getRaw();
|
||||
if (writer) {
|
||||
writer.writeBytes(raw);
|
||||
return writer;
|
||||
}
|
||||
return raw;
|
||||
Block.prototype.toRaw = function toRaw() {
|
||||
return this.getRaw().data;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -95,51 +89,82 @@ Block.prototype.toRaw = function toRaw(writer) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
Block.prototype.toNormal = function toNormal(writer) {
|
||||
var raw;
|
||||
if (!this.hasWitness()) {
|
||||
raw = this.getRaw();
|
||||
if (writer) {
|
||||
writer.writeBytes(raw);
|
||||
return writer;
|
||||
}
|
||||
return raw;
|
||||
}
|
||||
return this.frameNormal(writer);
|
||||
Block.prototype.toNormal = function toNormal() {
|
||||
if (this.hasWitness())
|
||||
return this.frameNormal().data;
|
||||
return this.toRaw();
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the block. Include witnesses if present.
|
||||
* @returns {Buffer}
|
||||
* @param {BufferWriter} bw
|
||||
*/
|
||||
|
||||
Block.prototype.toWitness = function toWitness(writer) {
|
||||
return this.toRaw(writer);
|
||||
Block.prototype.toWriter = function toWriter(bw) {
|
||||
this.writeRaw(bw);
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the block, do not include witnesses.
|
||||
* @param {BufferWriter} bw
|
||||
*/
|
||||
|
||||
Block.prototype.toNormalWriter = function toNormalWriter(bw) {
|
||||
if (this.hasWitness()) {
|
||||
this.frameNormalWriter(bw);
|
||||
return bw;
|
||||
}
|
||||
return this.toWriter(bw);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the raw block serialization.
|
||||
* Include witnesses if present.
|
||||
* @returns {Buffer}
|
||||
* @private
|
||||
* @returns {RawBlock}
|
||||
*/
|
||||
|
||||
Block.prototype.getRaw = function getRaw() {
|
||||
var raw;
|
||||
|
||||
if (this.mutable) {
|
||||
assert(!this._raw);
|
||||
return this.frameNormal();
|
||||
}
|
||||
|
||||
if (this._raw) {
|
||||
assert(this._size > 0);
|
||||
assert(this._witnessSize >= 0);
|
||||
this._lastWitnessSize = this._witnessSize;
|
||||
return this._raw;
|
||||
raw = new RawBlock(this._size, this._witnessSize);
|
||||
raw.data = this._raw;
|
||||
return raw;
|
||||
}
|
||||
|
||||
raw = this.frameWitness();
|
||||
|
||||
if (!this.mutable) {
|
||||
this._size = raw.length;
|
||||
this._witnessSize = this._lastWitnessSize;
|
||||
this._raw = raw;
|
||||
}
|
||||
this._raw = raw.data;
|
||||
this._size = raw.total;
|
||||
this._witnessSize = raw.witness;
|
||||
|
||||
return raw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Write the raw block serialization
|
||||
* to a buffer writer. Include the
|
||||
* witnesses if present.
|
||||
* @returns {RawBlock}
|
||||
*/
|
||||
|
||||
Block.prototype.writeRaw = function writeRaw(bw) {
|
||||
var raw;
|
||||
|
||||
if (this.mutable)
|
||||
return this.frameWitnessWriter(bw);
|
||||
|
||||
raw = this.getRaw();
|
||||
bw.writeBytes(raw.data);
|
||||
|
||||
return raw;
|
||||
};
|
||||
@ -150,31 +175,9 @@ Block.prototype.getRaw = function getRaw() {
|
||||
*/
|
||||
|
||||
Block.prototype.getSizes = function getSizes() {
|
||||
var sizes = new BlockSizes();
|
||||
var writer;
|
||||
|
||||
if (this._size !== -1) {
|
||||
sizes.total = this._size;
|
||||
sizes.witness = this._witnessSize;
|
||||
return sizes;
|
||||
}
|
||||
|
||||
if (!this.mutable) {
|
||||
assert(!this._raw);
|
||||
this.getRaw();
|
||||
sizes.total = this._size;
|
||||
sizes.witness = this._witnessSize;
|
||||
return sizes;
|
||||
}
|
||||
|
||||
writer = new BufferWriter();
|
||||
|
||||
this.toRaw(writer);
|
||||
|
||||
sizes.total = writer.written;
|
||||
sizes.witness = this._lastWitnessSize;
|
||||
|
||||
return sizes;
|
||||
if (this.mutable)
|
||||
return this.writeRaw(new BufferWriter());
|
||||
return this.getRaw();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -224,13 +227,14 @@ Block.prototype.getBaseSize = function getBaseSize() {
|
||||
*/
|
||||
|
||||
Block.prototype.hasWitness = function hasWitness() {
|
||||
var i;
|
||||
var i, tx;
|
||||
|
||||
if (this._witnessSize !== -1)
|
||||
return this._witnessSize !== 0;
|
||||
|
||||
for (i = 0; i < this.txs.length; i++) {
|
||||
if (this.txs[i].hasWitness())
|
||||
tx = this.txs[i];
|
||||
if (tx.hasWitness())
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -239,7 +243,7 @@ Block.prototype.hasWitness = function hasWitness() {
|
||||
|
||||
/**
|
||||
* Add a transaction to the block's tx vector.
|
||||
* @param {TX|NakedTX} tx
|
||||
* @param {TX} tx
|
||||
* @returns {TX}
|
||||
*/
|
||||
|
||||
@ -443,7 +447,7 @@ Block.prototype._verify = function _verify(ret) {
|
||||
if (!this.verifyHeaders(ret))
|
||||
return false;
|
||||
|
||||
// Check merkle root
|
||||
// Check merkle root.
|
||||
merkle = this.createMerkleRoot('hex');
|
||||
|
||||
// If the merkle is mutated,
|
||||
@ -460,6 +464,7 @@ Block.prototype._verify = function _verify(ret) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check base size.
|
||||
if (this.txs.length === 0
|
||||
|| this.txs.length > constants.block.MAX_SIZE
|
||||
|| this.getBaseSize() > constants.block.MAX_SIZE) {
|
||||
@ -468,29 +473,29 @@ Block.prototype._verify = function _verify(ret) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// First TX must be a coinbase
|
||||
// First TX must be a coinbase.
|
||||
if (this.txs.length === 0 || !this.txs[0].isCoinbase()) {
|
||||
ret.reason = 'bad-cb-missing';
|
||||
ret.score = 100;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test all txs
|
||||
// Test all transactions.
|
||||
for (i = 0; i < this.txs.length; i++) {
|
||||
tx = this.txs[i];
|
||||
|
||||
// The rest of the txs must not be coinbases
|
||||
// The rest of the txs must not be coinbases.
|
||||
if (i > 0 && tx.isCoinbase()) {
|
||||
ret.reason = 'bad-cb-multiple';
|
||||
ret.score = 100;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Sanity checks
|
||||
// Sanity checks.
|
||||
if (!tx.isSane(ret))
|
||||
return false;
|
||||
|
||||
// Count legacy sigops (do not count scripthash or witness)
|
||||
// Count legacy sigops (do not count scripthash or witness).
|
||||
sigops += tx.getLegacySigops();
|
||||
if (sigops * scale > constants.block.MAX_SIGOPS_WEIGHT) {
|
||||
ret.reason = 'bad-blk-sigops';
|
||||
@ -685,9 +690,9 @@ Block.fromJSON = function fromJSON(json) {
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
Block.prototype.fromRaw = function fromRaw(data) {
|
||||
var br = BufferReader(data);
|
||||
var i, tx, witnessSize;
|
||||
Block.prototype.fromReader = function fromReader(br) {
|
||||
var witnessSize = 0;
|
||||
var i, tx;
|
||||
|
||||
br.start();
|
||||
|
||||
@ -699,10 +704,8 @@ Block.prototype.fromRaw = function fromRaw(data) {
|
||||
this.nonce = br.readU32();
|
||||
this.totalTX = br.readVarint();
|
||||
|
||||
witnessSize = 0;
|
||||
|
||||
for (i = 0; i < this.totalTX; i++) {
|
||||
tx = TX.fromRaw(br);
|
||||
tx = TX.fromReader(br);
|
||||
witnessSize += tx._witnessSize;
|
||||
this.addTX(tx);
|
||||
}
|
||||
@ -716,6 +719,27 @@ Block.prototype.fromRaw = function fromRaw(data) {
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
Block.prototype.fromRaw = function fromRaw(data) {
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate a block from a serialized Buffer.
|
||||
* @param {Buffer} data
|
||||
* @param {String?} enc - Encoding, can be `'hex'` or null.
|
||||
* @returns {Block}
|
||||
*/
|
||||
|
||||
Block.fromReader = function fromReader(data) {
|
||||
return new Block().fromReader(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate a block from a serialized Buffer.
|
||||
* @param {Buffer} data
|
||||
@ -749,9 +773,7 @@ Block.prototype.toMerkle = function toMerkle(filter) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
Block.prototype.frame = function frame(witness, writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
var witnessSize = 0;
|
||||
Block.prototype.frameNormalWriter = function frameNormalWriter(bw) {
|
||||
var i, tx;
|
||||
|
||||
bw.writeU32(this.version);
|
||||
@ -764,20 +786,54 @@ Block.prototype.frame = function frame(witness, writer) {
|
||||
|
||||
for (i = 0; i < this.txs.length; i++) {
|
||||
tx = this.txs[i];
|
||||
if (witness) {
|
||||
tx.toRaw(bw);
|
||||
witnessSize += tx._lastWitnessSize;
|
||||
} else {
|
||||
tx.toNormal(bw);
|
||||
}
|
||||
tx.toNormalWriter(bw);
|
||||
}
|
||||
|
||||
this._lastWitnessSize = witnessSize;
|
||||
return new RawBlock(bw.written, 0);
|
||||
};
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
/**
|
||||
* Serialze block with or without witness data.
|
||||
* @private
|
||||
* @param {Boolean} witness
|
||||
* @param {BufferWriter?} writer
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
return bw;
|
||||
Block.prototype.frameWitnessWriter = function frameWitnessWriter(bw) {
|
||||
var witnessSize = 0;
|
||||
var i, tx, raw;
|
||||
|
||||
bw.writeU32(this.version);
|
||||
bw.writeHash(this.prevBlock);
|
||||
bw.writeHash(this.merkleRoot);
|
||||
bw.writeU32(this.ts);
|
||||
bw.writeU32(this.bits);
|
||||
bw.writeU32(this.nonce);
|
||||
bw.writeVarint(this.txs.length);
|
||||
|
||||
for (i = 0; i < this.txs.length; i++) {
|
||||
tx = this.txs[i];
|
||||
raw = tx.writeRaw(bw);
|
||||
witnessSize += raw.witness;
|
||||
}
|
||||
|
||||
return new RawBlock(bw.written, witnessSize);
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialze block with or without witness data.
|
||||
* @private
|
||||
* @param {Boolean} witness
|
||||
* @param {BufferWriter?} writer
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
Block.prototype.frameNormal = function frameNormal() {
|
||||
var bw = new BufferWriter();
|
||||
var raw = this.frameNormalWriter(bw);
|
||||
raw.data = bw.render();
|
||||
return raw;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -787,19 +843,11 @@ Block.prototype.frame = function frame(witness, writer) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
Block.prototype.frameNormal = function frameNormal(writer) {
|
||||
return this.frame(false, writer);
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialze block with witness data.
|
||||
* @private
|
||||
* @param {BufferWriter?} writer
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
Block.prototype.frameWitness = function frameWitness(writer) {
|
||||
return this.frame(true, writer);
|
||||
Block.prototype.frameWitness = function frameWitness() {
|
||||
var bw = new BufferWriter();
|
||||
var raw = this.frameWitnessWriter(bw);
|
||||
raw.data = bw.render();
|
||||
return raw;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -827,9 +875,10 @@ Block.isBlock = function isBlock(obj) {
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function BlockSizes() {
|
||||
this.total = 0;
|
||||
this.witness = 0;
|
||||
function RawBlock(total, witness) {
|
||||
this.data = null;
|
||||
this.total = total;
|
||||
this.witness = witness;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -194,13 +194,11 @@ Coin.prototype.fromJSON = function fromJSON(json) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the coin.
|
||||
* @param {String?} enc - Encoding, can be `'hex'` or null.
|
||||
* @returns {Buffer|String}
|
||||
* Write the coin to a buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
*/
|
||||
|
||||
Coin.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
Coin.prototype.toWriter = function toWriter(bw) {
|
||||
var height = this.height;
|
||||
|
||||
if (height === -1)
|
||||
@ -212,21 +210,25 @@ Coin.prototype.toRaw = function toRaw(writer) {
|
||||
bw.writeVarBytes(this.script.toRaw());
|
||||
bw.writeU8(this.coinbase ? 1 : 0);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
* Serialize the coin.
|
||||
* @returns {Buffer|String}
|
||||
*/
|
||||
|
||||
Coin.prototype.fromRaw = function fromRaw(data) {
|
||||
var br = BufferReader(data);
|
||||
Coin.prototype.toRaw = function toRaw() {
|
||||
return this.toWriter(new BufferWriter()).render();
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized buffer writer.
|
||||
* @private
|
||||
* @param {BufferReader} br
|
||||
*/
|
||||
|
||||
Coin.prototype.fromReader = function fromReader(br) {
|
||||
this.version = br.readU32();
|
||||
this.height = br.readU32();
|
||||
this.value = br.read64();
|
||||
@ -240,7 +242,27 @@ Coin.prototype.fromRaw = function fromRaw(data) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate an coin from a serialized Buffer.
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
Coin.prototype.fromRaw = function fromRaw(data) {
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate a coin from a buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @returns {Coin}
|
||||
*/
|
||||
|
||||
Coin.fromReader = function fromReader(br) {
|
||||
return new Coin().fromReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate a coin from a serialized Buffer.
|
||||
* @param {Buffer} data
|
||||
* @param {String?} enc - Encoding, can be `'hex'` or null.
|
||||
* @returns {Coin}
|
||||
@ -260,6 +282,7 @@ Coin.fromRaw = function fromRaw(data, enc) {
|
||||
|
||||
Coin.prototype.fromTX = function fromTX(tx, index) {
|
||||
assert(util.isNumber(index));
|
||||
assert(index < tx.outputs.length);
|
||||
this.version = tx.version;
|
||||
this.height = tx.height;
|
||||
this.value = tx.outputs[index].value;
|
||||
|
||||
@ -47,42 +47,15 @@ Headers.prototype._verify = function _verify(ret) {
|
||||
*/
|
||||
|
||||
Headers.prototype.getSize = function getSize() {
|
||||
var writer = new BufferWriter();
|
||||
this.toRaw(writer);
|
||||
return writer.written;
|
||||
return this.toWriter(new BufferWriter()).written;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inspect the headers and return a more
|
||||
* user-friendly representation of the data.
|
||||
* @returns {Object}
|
||||
* Serialize the headers to a buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
*/
|
||||
|
||||
Headers.prototype.inspect = function inspect() {
|
||||
return {
|
||||
type: 'headers',
|
||||
hash: this.rhash(),
|
||||
height: this.height,
|
||||
date: util.date(this.ts),
|
||||
version: util.hex32(this.version),
|
||||
prevBlock: util.revHex(this.prevBlock),
|
||||
merkleRoot: util.revHex(this.merkleRoot),
|
||||
ts: this.ts,
|
||||
bits: this.bits,
|
||||
nonce: this.nonce,
|
||||
totalTX: this.totalTX
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the headers.
|
||||
* @param {String?} enc - Encoding, can be `'hex'` or null.
|
||||
* @returns {Buffer|String}
|
||||
*/
|
||||
|
||||
Headers.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
|
||||
Headers.prototype.toWriter = function toWriter(bw) {
|
||||
bw.writeU32(this.version);
|
||||
bw.writeHash(this.prevBlock);
|
||||
bw.writeHash(this.merkleRoot);
|
||||
@ -90,13 +63,35 @@ Headers.prototype.toRaw = function toRaw(writer) {
|
||||
bw.writeU32(this.bits);
|
||||
bw.writeU32(this.nonce);
|
||||
bw.writeVarint(this.totalTX);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the headers.
|
||||
* @returns {Buffer|String}
|
||||
*/
|
||||
|
||||
Headers.prototype.toRaw = function toRaw() {
|
||||
return this.toWriter(new BufferWriter()).render();
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from buffer reader.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
Headers.prototype.fromReader = function fromReader(br) {
|
||||
this.version = br.readU32(); // Technically signed
|
||||
this.prevBlock = br.readHash('hex');
|
||||
this.merkleRoot = br.readHash('hex');
|
||||
this.ts = br.readU32();
|
||||
this.bits = br.readU32();
|
||||
this.nonce = br.readU32();
|
||||
this.totalTX = br.readVarint();
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
@ -104,17 +99,17 @@ Headers.prototype.toRaw = function toRaw(writer) {
|
||||
*/
|
||||
|
||||
Headers.prototype.fromRaw = function fromRaw(data) {
|
||||
var br = BufferReader(data);
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
this.version = br.readU32(); // Technically signed
|
||||
this.prevBlock = br.readHash('hex');
|
||||
this.merkleRoot = br.readHash('hex');
|
||||
this.ts = br.readU32();
|
||||
this.bits = br.readU32();
|
||||
this.nonce = br.readU32();
|
||||
this.totalTX = br.readVarint();
|
||||
/**
|
||||
* Instantiate headers from buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @returns {Headers}
|
||||
*/
|
||||
|
||||
return this;
|
||||
Headers.fromReader = function fromReader(br) {
|
||||
return new Headers().fromReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -131,24 +126,41 @@ Headers.fromRaw = function fromRaw(data, enc) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* Inject properties from buffer reader.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
* @param {BufferReader} br
|
||||
*/
|
||||
|
||||
Headers.prototype.fromAbbr = function fromAbbr(data) {
|
||||
var br = BufferReader(data);
|
||||
|
||||
Headers.prototype.fromAbbrReader = function fromAbbrReader(br) {
|
||||
this.version = br.readU32(); // Technically signed
|
||||
this.prevBlock = br.readHash('hex');
|
||||
this.merkleRoot = br.readHash('hex');
|
||||
this.ts = br.readU32();
|
||||
this.bits = br.readU32();
|
||||
this.nonce = br.readU32();
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
Headers.prototype.fromAbbr = function fromAbbr(data) {
|
||||
return this.fromAbbrReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate headers from buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @returns {Headers}
|
||||
*/
|
||||
|
||||
Headers.fromAbbrReader = function fromAbbrReader(br) {
|
||||
return new Headers().fromAbbrReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate headers from serialized data.
|
||||
* @param {Buffer} data
|
||||
@ -197,6 +209,27 @@ Headers.fromBlock = function fromBlock(block) {
|
||||
return headers;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inspect the headers and return a more
|
||||
* user-friendly representation of the data.
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
Headers.prototype.inspect = function inspect() {
|
||||
return {
|
||||
hash: this.rhash(),
|
||||
height: this.height,
|
||||
date: util.date(this.ts),
|
||||
version: util.hex32(this.version),
|
||||
prevBlock: util.revHex(this.prevBlock),
|
||||
merkleRoot: util.revHex(this.merkleRoot),
|
||||
ts: this.ts,
|
||||
bits: this.bits,
|
||||
nonce: this.nonce,
|
||||
totalTX: this.totalTX
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Test an object to see if it is a Headers object.
|
||||
* @param {Object} obj
|
||||
|
||||
@ -316,32 +316,52 @@ Input.fromJSON = function fromJSON(json) {
|
||||
* @returns {Buffer|String}
|
||||
*/
|
||||
|
||||
Input.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
Input.prototype.toRaw = function toRaw() {
|
||||
return this.toWriter(new BufferWriter()).render();
|
||||
};
|
||||
|
||||
this.prevout.toRaw(bw);
|
||||
/**
|
||||
* Write the input to a buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
*/
|
||||
|
||||
Input.prototype.toWriter = function toWriter(bw) {
|
||||
this.prevout.toWriter(bw);
|
||||
bw.writeVarBytes(this.script.toRaw());
|
||||
bw.writeU32(this.sequence);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from buffer reader.
|
||||
* @private
|
||||
* @param {BufferReader} br
|
||||
*/
|
||||
|
||||
Input.prototype.fromReader = function fromReader(br) {
|
||||
this.prevout.fromReader(br);
|
||||
this.script.fromRaw(br.readVarBytes());
|
||||
this.sequence = br.readU32();
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
Input.prototype.fromRaw = function fromRaw(data) {
|
||||
var br = BufferReader(data);
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
this.prevout.fromRaw(br);
|
||||
this.script.fromRaw(br.readVarBytes());
|
||||
this.sequence = br.readU32();
|
||||
/**
|
||||
* Instantiate an input from a buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @returns {Input}
|
||||
*/
|
||||
|
||||
return this;
|
||||
Input.fromReader = function fromReader(br) {
|
||||
return new Input().fromReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -357,52 +377,6 @@ Input.fromRaw = function fromRaw(data, enc) {
|
||||
return new Input().fromRaw(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the input to an "extended" format,
|
||||
* including both the input and the witness.
|
||||
* @param {String?} enc - Encoding, can be `'hex'` or null.
|
||||
* @returns {Buffer|String}
|
||||
*/
|
||||
|
||||
Input.prototype.toExtended = function toExtended(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
|
||||
this.toRaw(bw);
|
||||
this.witness.toRaw(bw);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from extended serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
Input.prototype.fromExtended = function fromExtended(data) {
|
||||
var br = BufferReader(data);
|
||||
this.fromRaw(br);
|
||||
this.witness.fromRaw(br);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate an input from a Buffer
|
||||
* in "extended" serialization format.
|
||||
* @param {Buffer} data
|
||||
* @param {String?} enc - Encoding, can be `'hex'` or null.
|
||||
* @returns {TX}
|
||||
*/
|
||||
|
||||
Input.fromExtended = function fromExtended(data, enc) {
|
||||
if (typeof data === 'string')
|
||||
data = new Buffer(data, enc);
|
||||
return new Input().fromExtended(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from coin.
|
||||
* @private
|
||||
|
||||
@ -27,21 +27,36 @@ function InvItem(type, hash) {
|
||||
this.hash = hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write inv item to buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
*/
|
||||
|
||||
InvItem.prototype.toWriter = function toWriter(bw) {
|
||||
bw.writeU32(this.type);
|
||||
bw.writeHash(this.hash);
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize inv item.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
InvItem.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
InvItem.prototype.toRaw = function toRaw() {
|
||||
return this.toWriter(new BufferWriter()).render();
|
||||
};
|
||||
|
||||
bw.writeU32(this.type);
|
||||
bw.writeHash(this.hash);
|
||||
/**
|
||||
* Inject properties from buffer reader.
|
||||
* @private
|
||||
* @param {BufferReader} br
|
||||
*/
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
InvItem.prototype.fromReader = function fromReader(br) {
|
||||
this.type = br.readU32();
|
||||
this.hash = br.readHash('hex');
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -50,10 +65,17 @@ InvItem.prototype.toRaw = function toRaw(writer) {
|
||||
*/
|
||||
|
||||
InvItem.prototype.fromRaw = function fromRaw(data) {
|
||||
var br = BufferReader(data);
|
||||
this.type = br.readU32();
|
||||
this.hash = br.readHash('hex');
|
||||
return this;
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate inv item from buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @returns {InvItem}
|
||||
*/
|
||||
|
||||
InvItem.fromReader = function fromReader(br) {
|
||||
return new InvItem().fromReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -811,12 +811,11 @@ KeyRing.fromJSON = function fromJSON(json) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the keyring.
|
||||
* @returns {Buffer}
|
||||
* Write the keyring to a buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
*/
|
||||
|
||||
KeyRing.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
KeyRing.prototype.toWriter = function toWriter(bw) {
|
||||
var field = 0;
|
||||
|
||||
if (this.witness)
|
||||
@ -839,20 +838,26 @@ KeyRing.prototype.toRaw = function toRaw(writer) {
|
||||
else
|
||||
bw.writeVarint(0);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
* Serialize the keyring.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
KeyRing.prototype.fromRaw = function fromRaw(data, network) {
|
||||
var br = new BufferReader(data);
|
||||
KeyRing.prototype.toRaw = function toRaw() {
|
||||
return this.toWriter(new BufferWriter()).render();
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from buffer reader.
|
||||
* @private
|
||||
* @param {BufferReader} br
|
||||
* @param {Network?} network
|
||||
*/
|
||||
|
||||
KeyRing.prototype.fromReader = function fromReader(br, network) {
|
||||
var field, compressed, key, script;
|
||||
|
||||
this.network = Network.get(network);
|
||||
@ -881,6 +886,27 @@ KeyRing.prototype.fromRaw = function fromRaw(data, network) {
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
* @param {Network?} network
|
||||
*/
|
||||
|
||||
KeyRing.prototype.fromRaw = function fromRaw(data, network) {
|
||||
return this.fromReader(new BufferReader(data), network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate a keyring from buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @returns {KeyRing}
|
||||
*/
|
||||
|
||||
KeyRing.fromReader = function fromReader(br) {
|
||||
return new KeyRing().fromReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate a keyring from serialized data.
|
||||
* @param {Buffer} data
|
||||
|
||||
@ -83,15 +83,8 @@ MemBlock.fromOptions = function fromOptions(options) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
MemBlock.prototype.abbr = function abbr(writer) {
|
||||
var data = this.raw.slice(0, 80);
|
||||
|
||||
if (writer) {
|
||||
writer.writeBytes(data);
|
||||
return writer;
|
||||
}
|
||||
|
||||
return data;
|
||||
MemBlock.prototype.abbr = function abbr() {
|
||||
return this.raw.slice(0, 80);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -132,7 +125,7 @@ MemBlock.prototype.getCoinbaseHeight = function getCoinbaseHeight() {
|
||||
*/
|
||||
|
||||
MemBlock.prototype.fromRaw = function fromRaw(data) {
|
||||
var br = BufferReader(data, true);
|
||||
var br = new BufferReader(data, true);
|
||||
var height = -1;
|
||||
var inCount, input;
|
||||
|
||||
|
||||
@ -94,14 +94,12 @@ MerkleBlock.fromOptions = function fromOptions(data) {
|
||||
*/
|
||||
|
||||
MerkleBlock.prototype.getSize = function getSize() {
|
||||
var writer = new BufferWriter();
|
||||
this.toRaw(writer);
|
||||
return writer.written;
|
||||
return this.toWriter(new BufferWriter()).written;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a transaction to the block's tx vector.
|
||||
* @param {TX|NakedTX} tx
|
||||
* @param {TX} tx
|
||||
* @returns {TX}
|
||||
*/
|
||||
|
||||
@ -338,13 +336,11 @@ MerkleBlock.prototype.inspect = function inspect() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the merkleblock.
|
||||
* @param {String?} enc - Encoding, can be `'hex'` or null.
|
||||
* @returns {Buffer|String}
|
||||
* Write the merkleblock to a buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
*/
|
||||
|
||||
MerkleBlock.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
MerkleBlock.prototype.toWriter = function toWriter(bw) {
|
||||
var i;
|
||||
|
||||
bw.writeU32(this.version);
|
||||
@ -362,20 +358,26 @@ MerkleBlock.prototype.toRaw = function toRaw(writer) {
|
||||
|
||||
bw.writeVarBytes(this.flags);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
* Serialize the merkleblock.
|
||||
* @param {String?} enc - Encoding, can be `'hex'` or null.
|
||||
* @returns {Buffer|String}
|
||||
*/
|
||||
|
||||
MerkleBlock.prototype.fromRaw = function fromRaw(data) {
|
||||
var br = BufferReader(data);
|
||||
MerkleBlock.prototype.toRaw = function toRaw() {
|
||||
return this.toWriter(new BufferWriter()).render();
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from buffer reader.
|
||||
* @private
|
||||
* @param {BufferReader} br
|
||||
*/
|
||||
|
||||
MerkleBlock.prototype.fromReader = function fromReader(br) {
|
||||
var i, count;
|
||||
|
||||
this.version = br.readU32();
|
||||
@ -396,6 +398,26 @@ MerkleBlock.prototype.fromRaw = function fromRaw(data) {
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
MerkleBlock.prototype.fromRaw = function fromRaw(data) {
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate a merkleblock from a buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @returns {MerkleBlock}
|
||||
*/
|
||||
|
||||
MerkleBlock.fromReader = function fromReader(br) {
|
||||
return new MerkleBlock().fromReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate a merkleblock from a serialized data.
|
||||
* @param {Buffer} data
|
||||
|
||||
@ -1386,6 +1386,14 @@ MTX.fromJSON = function fromJSON(json) {
|
||||
return new MTX().fromJSON(JSON)._mutable();
|
||||
};
|
||||
|
||||
/**
|
||||
* @see TX.fromReader
|
||||
*/
|
||||
|
||||
MTX.fromReader = function fromReader(br) {
|
||||
return new MTX().fromReader(br)._mutable();
|
||||
};
|
||||
|
||||
/**
|
||||
* @see TX.fromRaw
|
||||
*/
|
||||
|
||||
@ -247,15 +247,13 @@ NetworkAddress.fromSocket = function fromSocket(hostname, network) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* Inject properties from buffer reader.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
* @param {BufferReader} br
|
||||
* @param {Boolean?} full - Include timestamp.
|
||||
*/
|
||||
|
||||
NetworkAddress.prototype.fromRaw = function fromRaw(data, full) {
|
||||
var br = BufferReader(data);
|
||||
|
||||
NetworkAddress.prototype.fromReader = function fromReader(br, full) {
|
||||
// only version >= 31402
|
||||
this.ts = full ? br.readU32() : 0;
|
||||
this.services = br.readU53();
|
||||
@ -267,6 +265,28 @@ NetworkAddress.prototype.fromRaw = function fromRaw(data, full) {
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
* @param {Boolean?} full - Include timestamp.
|
||||
*/
|
||||
|
||||
NetworkAddress.prototype.fromRaw = function fromRaw(data, full) {
|
||||
return this.fromReader(new BufferReader(data), full);
|
||||
};
|
||||
|
||||
/**
|
||||
* Insantiate a network address from buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @param {Boolean?} full - Include timestamp.
|
||||
* @returns {NetworkAddress}
|
||||
*/
|
||||
|
||||
NetworkAddress.fromReader = function fromReader(br, full) {
|
||||
return new NetworkAddress().fromReader(br, full);
|
||||
};
|
||||
|
||||
/**
|
||||
* Insantiate a network address from serialized data.
|
||||
* @param {Buffer} data
|
||||
@ -279,14 +299,13 @@ NetworkAddress.fromRaw = function fromRaw(data, full) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize network address.
|
||||
* @param {Boolean} full - Include timestamp.
|
||||
* Write network address to a buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
* @param {Boolean?} full - Include timestamp.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
NetworkAddress.prototype.toRaw = function toRaw(full, writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
|
||||
NetworkAddress.prototype.toWriter = function toWriter(bw, full) {
|
||||
if (full)
|
||||
bw.writeU32(this.ts);
|
||||
|
||||
@ -294,12 +313,19 @@ NetworkAddress.prototype.toRaw = function toRaw(full, writer) {
|
||||
bw.writeBytes(IP.toBuffer(this.host));
|
||||
bw.writeU16BE(this.port);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize network address.
|
||||
* @param {Boolean?} full - Include timestamp.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
NetworkAddress.prototype.toRaw = function toRaw(full) {
|
||||
return this.toWriter(new BufferWriter(), full).render();
|
||||
};
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
@ -64,21 +64,36 @@ Outpoint.prototype.isNull = function isNull() {
|
||||
return this.index === 0xffffffff && this.hash === constants.NULL_HASH;
|
||||
};
|
||||
|
||||
/**
|
||||
* Write outpoint to a buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
*/
|
||||
|
||||
Outpoint.prototype.toWriter = function toWriter(bw) {
|
||||
bw.writeHash(this.hash);
|
||||
bw.writeU32(this.index);
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize outpoint.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
Outpoint.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
Outpoint.prototype.toRaw = function toRaw() {
|
||||
return this.toWriter(new BufferWriter()).render();
|
||||
};
|
||||
|
||||
bw.writeHash(this.hash);
|
||||
bw.writeU32(this.index);
|
||||
/**
|
||||
* Inject properties from buffer reader.
|
||||
* @private
|
||||
* @param {BufferReader} br
|
||||
*/
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
Outpoint.prototype.fromReader = function fromReader(br) {
|
||||
this.hash = br.readHash('hex');
|
||||
this.index = br.readU32();
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -88,10 +103,17 @@ Outpoint.prototype.toRaw = function toRaw(writer) {
|
||||
*/
|
||||
|
||||
Outpoint.prototype.fromRaw = function fromRaw(data) {
|
||||
var br = BufferReader(data);
|
||||
this.hash = br.readHash('hex');
|
||||
this.index = br.readU32();
|
||||
return this;
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate outpoint from a buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @returns {Outpoint}
|
||||
*/
|
||||
|
||||
Outpoint.fromReader = function fromReader(br) {
|
||||
return new Outpoint().fromReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -181,7 +181,7 @@ Output.prototype.getDustThreshold = function getDustThreshold(rate) {
|
||||
*/
|
||||
|
||||
Output.prototype.getSize = function getSize() {
|
||||
return this.toRaw(BufferWriter()).written;
|
||||
return this.toWriter(new BufferWriter()).written;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -217,22 +217,37 @@ Output.fromJSON = function fromJSON(json) {
|
||||
return new Output().fromJSON(json);
|
||||
};
|
||||
|
||||
/**
|
||||
* Write the output to a buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
*/
|
||||
|
||||
Output.prototype.toWriter = function toWriter(bw) {
|
||||
bw.write64(this.value);
|
||||
bw.writeVarBytes(this.script.toRaw());
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the output.
|
||||
* @param {String?} enc - Encoding, can be `'hex'` or null.
|
||||
* @returns {Buffer|String}
|
||||
*/
|
||||
|
||||
Output.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
Output.prototype.toRaw = function toRaw() {
|
||||
return this.toWriter(new BufferWriter()).render();
|
||||
};
|
||||
|
||||
bw.write64(this.value);
|
||||
bw.writeVarBytes(this.script.toRaw());
|
||||
/**
|
||||
* Inject properties from buffer reader.
|
||||
* @private
|
||||
* @param {BufferReader} br
|
||||
*/
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
Output.prototype.fromReader = function fromReader(br) {
|
||||
this.value = br.read64();
|
||||
this.script.fromRaw(br.readVarBytes());
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -242,12 +257,17 @@ Output.prototype.toRaw = function toRaw(writer) {
|
||||
*/
|
||||
|
||||
Output.prototype.fromRaw = function fromRaw(data) {
|
||||
var br = BufferReader(data);
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
this.value = br.read64();
|
||||
this.script.fromRaw(br.readVarBytes());
|
||||
/**
|
||||
* Instantiate an output from a buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @returns {Output}
|
||||
*/
|
||||
|
||||
return this;
|
||||
Output.fromReader = function fromReader(br) {
|
||||
return new Output().fromReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -260,7 +280,6 @@ Output.prototype.fromRaw = function fromRaw(data) {
|
||||
Output.fromRaw = function fromRaw(data, enc) {
|
||||
if (typeof data === 'string')
|
||||
data = new Buffer(data, enc);
|
||||
|
||||
return new Output().fromRaw(data);
|
||||
};
|
||||
|
||||
|
||||
@ -9,13 +9,13 @@
|
||||
|
||||
var assert = require('assert');
|
||||
var util = require('../utils/util');
|
||||
var co = require('../utils/co');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var btcutils = require('../btc/utils');
|
||||
var Amount = require('../btc/amount');
|
||||
var constants = require('../protocol/constants');
|
||||
var Network = require('../protocol/network');
|
||||
var Script = require('../script/script');
|
||||
var Stack = require('../script/stack');
|
||||
var BufferWriter = require('../utils/writer');
|
||||
var VerifyResult = require('../btc/errors').VerifyResult;
|
||||
var Input = require('./input');
|
||||
@ -92,7 +92,6 @@ function TX(options) {
|
||||
this._raw = null;
|
||||
this._size = -1;
|
||||
this._witnessSize = -1;
|
||||
this._lastWitnessSize = 0;
|
||||
|
||||
this._outputValue = -1;
|
||||
this._inputValue = -1;
|
||||
@ -253,17 +252,11 @@ TX.prototype.hash = function _hash(enc) {
|
||||
TX.prototype.witnessHash = function witnessHash(enc) {
|
||||
var hash = this._whash;
|
||||
|
||||
if (this.isCoinbase()) {
|
||||
return enc === 'hex'
|
||||
? constants.NULL_HASH
|
||||
: util.copy(constants.ZERO_HASH);
|
||||
}
|
||||
|
||||
if (!this.hasWitness())
|
||||
return this.hash(enc);
|
||||
|
||||
if (!hash) {
|
||||
hash = crypto.hash256(this.toWitness());
|
||||
hash = crypto.hash256(this.toRaw());
|
||||
if (!this.mutable)
|
||||
this._whash = hash;
|
||||
}
|
||||
@ -279,13 +272,8 @@ TX.prototype.witnessHash = function witnessHash(enc) {
|
||||
* @returns {Buffer} Serialized transaction.
|
||||
*/
|
||||
|
||||
TX.prototype.toRaw = function toRaw(writer) {
|
||||
var raw = this.getRaw();
|
||||
if (writer) {
|
||||
writer.writeBytes(raw);
|
||||
return writer;
|
||||
}
|
||||
return raw;
|
||||
TX.prototype.toRaw = function toRaw() {
|
||||
return this.getRaw().data;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -295,27 +283,34 @@ TX.prototype.toRaw = function toRaw(writer) {
|
||||
* @returns {Buffer} Serialized transaction.
|
||||
*/
|
||||
|
||||
TX.prototype.toNormal = function toNormal(writer) {
|
||||
var raw = this.getRaw();
|
||||
if (!TX.isWitness(raw)) {
|
||||
if (writer) {
|
||||
writer.writeBytes(raw);
|
||||
return writer;
|
||||
}
|
||||
return raw;
|
||||
}
|
||||
return this.frameNormal(writer);
|
||||
TX.prototype.toNormal = function toNormal() {
|
||||
if (this.hasWitness())
|
||||
return this.frameNormal().data;
|
||||
return this.toRaw();
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the transaction with the
|
||||
* witness vector. Will use normal
|
||||
* serialization if witness vector is empty.
|
||||
* @returns {Buffer} Serialized transaction.
|
||||
* Write the transaction to a buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
*/
|
||||
|
||||
TX.prototype.toWitness = function toWitness(writer) {
|
||||
return this.toRaw(writer);
|
||||
TX.prototype.toWriter = function toWriter(bw) {
|
||||
this.writeRaw(bw);
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Write the transaction to a buffer writer.
|
||||
* Uses non-witness serialization.
|
||||
* @param {BufferWriter} bw
|
||||
*/
|
||||
|
||||
TX.prototype.toNormalWriter = function toNormalWriter(bw) {
|
||||
if (this.hasWitness()) {
|
||||
this.frameNormalWriter(bw);
|
||||
return bw;
|
||||
}
|
||||
return this.toWriter(bw);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -323,17 +318,26 @@ TX.prototype.toWitness = function toWitness(writer) {
|
||||
* that this is cached. This will use
|
||||
* the witness serialization if a
|
||||
* witness is present.
|
||||
* @returns {Buffer} Serialized transaction.
|
||||
* @private
|
||||
* @returns {RawTX}
|
||||
*/
|
||||
|
||||
TX.prototype.getRaw = function getRaw() {
|
||||
var raw;
|
||||
|
||||
if (this.mutable) {
|
||||
assert(!this._raw);
|
||||
if (this.hasWitness())
|
||||
return this.frameWitness();
|
||||
return this.frameNormal();
|
||||
}
|
||||
|
||||
if (this._raw) {
|
||||
assert(this._size > 0);
|
||||
assert(this._witnessSize >= 0);
|
||||
this._lastWitnessSize = this._witnessSize;
|
||||
return this._raw;
|
||||
raw = new RawTX(this._size, this._witnessSize);
|
||||
raw.data = this._raw;
|
||||
return raw;
|
||||
}
|
||||
|
||||
if (this.hasWitness())
|
||||
@ -341,39 +345,43 @@ TX.prototype.getRaw = function getRaw() {
|
||||
else
|
||||
raw = this.frameNormal();
|
||||
|
||||
if (!this.mutable) {
|
||||
this._raw = raw;
|
||||
this._size = raw.length;
|
||||
this._witnessSize = this._lastWitnessSize;
|
||||
}
|
||||
this._raw = raw.data;
|
||||
this._size = raw.total;
|
||||
this._witnessSize = raw.witness;
|
||||
|
||||
return raw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate real size and size of the witness bytes.
|
||||
* @returns {Object} Contains `size` and `witnessSize`.
|
||||
* Write raw transaction to buffer writer.
|
||||
* Cache if possible.
|
||||
* @returns {RawTX}
|
||||
*/
|
||||
|
||||
TX.prototype.writeRaw = function writeRaw(bw) {
|
||||
var raw;
|
||||
|
||||
if (this.mutable) {
|
||||
if (this.hasWitness())
|
||||
return this.frameWitnessWriter(bw);
|
||||
return this.frameNormalWriter(bw);
|
||||
}
|
||||
|
||||
raw = this.getRaw();
|
||||
bw.writeBytes(raw.data);
|
||||
|
||||
return raw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate total size and size of the witness bytes.
|
||||
* @returns {Object} Contains `total` and `witness`.
|
||||
*/
|
||||
|
||||
TX.prototype.getSizes = function getSizes() {
|
||||
var sizes = new TXSizes();
|
||||
var writer;
|
||||
|
||||
if (this.mutable) {
|
||||
assert(!this._raw);
|
||||
writer = new BufferWriter();
|
||||
this.toRaw(writer);
|
||||
sizes.total = writer.written;
|
||||
sizes.witness = this._lastWitnessSize;
|
||||
return sizes;
|
||||
}
|
||||
|
||||
this.getRaw();
|
||||
|
||||
sizes.total = this._size;
|
||||
sizes.witness = this._witnessSize;
|
||||
|
||||
return sizes;
|
||||
if (this.mutable)
|
||||
return this.writeRaw(new BufferWriter());
|
||||
return this.getRaw();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -394,9 +402,9 @@ TX.prototype.getVirtualSize = function getVirtualSize() {
|
||||
*/
|
||||
|
||||
TX.prototype.getWeight = function getWeight() {
|
||||
var sizes = this.getSizes();
|
||||
var base = sizes.total - sizes.witness;
|
||||
return base * (constants.WITNESS_SCALE_FACTOR - 1) + sizes.total;
|
||||
var raw = this.getSizes();
|
||||
var base = raw.total - raw.witness;
|
||||
return base * (constants.WITNESS_SCALE_FACTOR - 1) + raw.total;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -417,8 +425,8 @@ TX.prototype.getSize = function getSize() {
|
||||
*/
|
||||
|
||||
TX.prototype.getBaseSize = function getBaseSize() {
|
||||
var sizes = this.getSizes();
|
||||
return sizes.total - sizes.witness;
|
||||
var raw = this.getSizes();
|
||||
return raw.total - raw.witness;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -427,13 +435,14 @@ TX.prototype.getBaseSize = function getBaseSize() {
|
||||
*/
|
||||
|
||||
TX.prototype.hasWitness = function hasWitness() {
|
||||
var i;
|
||||
var i, input;
|
||||
|
||||
if (this._witnessSize !== -1)
|
||||
return this._witnessSize !== 0;
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
if (this.inputs[i].witness.items.length > 0)
|
||||
input = this.inputs[i];
|
||||
if (input.witness.items.length > 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -452,9 +461,6 @@ TX.prototype.hasWitness = function hasWitness() {
|
||||
*/
|
||||
|
||||
TX.prototype.signatureHash = function signatureHash(index, prev, type, version) {
|
||||
if (typeof index !== 'number')
|
||||
index = this.inputs.indexOf(index);
|
||||
|
||||
if (typeof type === 'string')
|
||||
type = constants.hashType[type.toUpperCase()];
|
||||
|
||||
@ -506,8 +512,7 @@ TX.prototype.signatureHashV0 = function signatureHashV0(index, prev, type) {
|
||||
input = this.inputs[index];
|
||||
|
||||
// Outpoint.
|
||||
bw.writeHash(input.prevout.hash);
|
||||
bw.writeU32(input.prevout.index);
|
||||
input.prevout.toWriter(bw);
|
||||
|
||||
// Replace script with previous
|
||||
// output script if current index.
|
||||
@ -519,8 +524,7 @@ TX.prototype.signatureHashV0 = function signatureHashV0(index, prev, type) {
|
||||
input = this.inputs[i];
|
||||
|
||||
// Outpoint.
|
||||
bw.writeHash(input.prevout.hash);
|
||||
bw.writeU32(input.prevout.index);
|
||||
input.prevout.toWriter(bw);
|
||||
|
||||
// Replace script with previous
|
||||
// output script if current index.
|
||||
@ -606,7 +610,7 @@ TX.prototype.signatureHashV1 = function signatureHashV1(index, prev, type) {
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
input = this.inputs[i];
|
||||
input.prevout.toRaw(bw);
|
||||
input.prevout.toWriter(bw);
|
||||
}
|
||||
|
||||
prevouts = crypto.hash256(bw.render());
|
||||
@ -649,7 +653,7 @@ TX.prototype.signatureHashV1 = function signatureHashV1(index, prev, type) {
|
||||
|
||||
for (i = 0; i < this.outputs.length; i++) {
|
||||
output = this.outputs[i];
|
||||
output.toRaw(bw);
|
||||
output.toWriter(bw);
|
||||
}
|
||||
|
||||
outputs = crypto.hash256(bw.render());
|
||||
@ -715,12 +719,7 @@ TX.prototype.verify = function verify(flags) {
|
||||
*/
|
||||
|
||||
TX.prototype.verifyInput = function verifyInput(index, flags) {
|
||||
var input;
|
||||
|
||||
if (typeof index === 'object')
|
||||
index = this.inputs.indexOf(index);
|
||||
|
||||
input = this.inputs[index];
|
||||
var input = this.inputs[index];
|
||||
|
||||
assert(input, 'Input does not exist.');
|
||||
|
||||
@ -753,15 +752,15 @@ TX.prototype.verifyInput = function verifyInput(index, flags) {
|
||||
* @returns {Boolean} Whether the inputs are valid.
|
||||
*/
|
||||
|
||||
TX.prototype.verifyAsync = function verifyAsync(flags) {
|
||||
TX.prototype.verifyAsync = co(function* verifyAsync(flags) {
|
||||
if (this.inputs.length === 0)
|
||||
return Promise.resolve(false);
|
||||
return false;
|
||||
|
||||
if (this.isCoinbase())
|
||||
return Promise.resolve(true);
|
||||
return true;
|
||||
|
||||
return workerPool.verify(this, flags);
|
||||
};
|
||||
return yield workerPool.verify(this, flags);
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify a transaction input asynchronously.
|
||||
@ -771,18 +770,11 @@ TX.prototype.verifyAsync = function verifyAsync(flags) {
|
||||
* @returns {Boolean} Whether the input is valid.
|
||||
*/
|
||||
|
||||
TX.prototype.verifyInputAsync = function verifyInputAsync(index, flags) {
|
||||
var input;
|
||||
|
||||
if (typeof index === 'object')
|
||||
index = this.inputs.indexOf(index);
|
||||
|
||||
input = this.inputs[index];
|
||||
|
||||
TX.prototype.verifyInputAsync = co(function* verifyInputAsync(index, flags) {
|
||||
var input = this.inputs[index];
|
||||
assert(input, 'Input does not exist.');
|
||||
|
||||
return workerPool.verifyInput(this, index, flags);
|
||||
};
|
||||
return yield workerPool.verifyInput(this, index, flags);
|
||||
});
|
||||
|
||||
/**
|
||||
* Test whether the transaction is a coinbase
|
||||
@ -1169,13 +1161,17 @@ TX.prototype.isFinal = function isFinal(height, ts) {
|
||||
|
||||
TX.prototype.getLegacySigops = function getLegacySigops() {
|
||||
var total = 0;
|
||||
var i;
|
||||
var i, input, output;
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++)
|
||||
total += this.inputs[i].script.getSigops(false);
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
input = this.inputs[i];
|
||||
total += input.script.getSigops(false);
|
||||
}
|
||||
|
||||
for (i = 0; i < this.outputs.length; i++)
|
||||
total += this.outputs[i].script.getSigops(false);
|
||||
for (i = 0; i < this.outputs.length; i++) {
|
||||
output = this.outputs[i];
|
||||
total += output.script.getSigops(false);
|
||||
}
|
||||
|
||||
return total;
|
||||
};
|
||||
@ -1187,19 +1183,20 @@ TX.prototype.getLegacySigops = function getLegacySigops() {
|
||||
|
||||
TX.prototype.getScripthashSigops = function getScripthashSigops() {
|
||||
var total = 0;
|
||||
var i, input;
|
||||
var i, input, coin;
|
||||
|
||||
if (this.isCoinbase())
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
input = this.inputs[i];
|
||||
coin = input.coin;
|
||||
|
||||
if (!input.coin)
|
||||
if (!coin)
|
||||
continue;
|
||||
|
||||
if (input.coin.script.isScripthash())
|
||||
total += input.coin.script.getScripthashSigops(input.script);
|
||||
if (coin.script.isScripthash())
|
||||
total += coin.script.getScripthashSigops(input.script);
|
||||
}
|
||||
|
||||
return total;
|
||||
@ -1439,34 +1436,26 @@ TX.prototype.isStandard = function isStandard(ret) {
|
||||
|
||||
TX.prototype.hasStandardInputs = function hasStandardInputs() {
|
||||
var maxSigops = constants.script.MAX_SCRIPTHASH_SIGOPS;
|
||||
var VERIFY_NONE = constants.flags.VERIFY_NONE;
|
||||
var i, input, stack, redeem;
|
||||
var i, input, coin, redeem;
|
||||
|
||||
if (this.isCoinbase())
|
||||
return true;
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
input = this.inputs[i];
|
||||
coin = input.coin;
|
||||
|
||||
if (!input.coin)
|
||||
if (!coin)
|
||||
return false;
|
||||
|
||||
if (input.coin.script.isUnknown())
|
||||
if (coin.script.isUnknown())
|
||||
return false;
|
||||
|
||||
if (input.coin.script.isScripthash()) {
|
||||
stack = new Stack();
|
||||
if (coin.script.isScripthash()) {
|
||||
redeem = input.script.getRedeem();
|
||||
|
||||
try {
|
||||
input.script.execute(stack, VERIFY_NONE, this, i, 0);
|
||||
} catch (e) {
|
||||
if (!redeem)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stack.length === 0)
|
||||
return false;
|
||||
|
||||
redeem = Script.fromRaw(stack.top(-1));
|
||||
|
||||
if (redeem.getSigops(true) > maxSigops)
|
||||
return false;
|
||||
@ -1737,13 +1726,14 @@ TX.prototype.maxSize = function maxSize() {
|
||||
*/
|
||||
|
||||
TX.prototype.getModifiedSize = function getModifiedSize(size) {
|
||||
var i, offset;
|
||||
var i, input, offset;
|
||||
|
||||
if (size == null)
|
||||
size = this.maxSize();
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
offset = 41 + Math.min(110, this.inputs[i].script.getSize());
|
||||
input = this.inputs[i];
|
||||
offset = 41 + Math.min(110, input.script.getSize());
|
||||
if (size > offset)
|
||||
size -= offset;
|
||||
}
|
||||
@ -1940,9 +1930,6 @@ TX.prototype.isWatched = function isWatched(filter) {
|
||||
var found = false;
|
||||
var i, input, output, prevout;
|
||||
|
||||
if (!filter)
|
||||
return false;
|
||||
|
||||
// 1. Test the tx hash
|
||||
if (filter.test(this.hash()))
|
||||
found = true;
|
||||
@ -2195,32 +2182,51 @@ TX.fromRaw = function fromRaw(data, enc) {
|
||||
return new TX().fromRaw(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate a transaction from a buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @returns {TX}
|
||||
*/
|
||||
|
||||
TX.fromReader = function fromReader(br) {
|
||||
return new TX().fromReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer|BufferReader} data
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
TX.prototype.fromRaw = function fromRaw(data) {
|
||||
var br, i, count;
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
if (TX.isWitness(data))
|
||||
return this.fromWitness(data);
|
||||
/**
|
||||
* Inject properties from buffer reader.
|
||||
* @private
|
||||
* @param {BufferReader} br
|
||||
*/
|
||||
|
||||
TX.prototype.fromReader = function fromReader(br) {
|
||||
var i, count;
|
||||
|
||||
if (TX.isWitness(br))
|
||||
return this.fromWitnessReader(br);
|
||||
|
||||
br = BufferReader(data);
|
||||
br.start();
|
||||
|
||||
this.version = br.readU32(); // Technically signed
|
||||
this.version = br.readU32();
|
||||
|
||||
count = br.readVarint();
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
this.inputs.push(Input.fromRaw(br));
|
||||
this.inputs.push(Input.fromReader(br));
|
||||
|
||||
count = br.readVarint();
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
this.outputs.push(Output.fromRaw(br));
|
||||
this.outputs.push(Output.fromReader(br));
|
||||
|
||||
this.locktime = br.readU32();
|
||||
|
||||
@ -2237,13 +2243,12 @@ TX.prototype.fromRaw = function fromRaw(data) {
|
||||
|
||||
/**
|
||||
* Inject properties from serialized
|
||||
* data (witness serialization).
|
||||
* buffer reader (witness serialization).
|
||||
* @private
|
||||
* @param {Buffer|BufferReader} data
|
||||
* @param {BufferReader} br
|
||||
*/
|
||||
|
||||
TX.prototype.fromWitness = function fromWitness(data) {
|
||||
var br = BufferReader(data);
|
||||
TX.prototype.fromWitnessReader = function fromWitnessReader(br) {
|
||||
var flag = 0;
|
||||
var witnessSize = 0;
|
||||
var hasWitness = false;
|
||||
@ -2251,7 +2256,7 @@ TX.prototype.fromWitness = function fromWitness(data) {
|
||||
|
||||
br.start();
|
||||
|
||||
this.version = br.readU32(); // Technically signed
|
||||
this.version = br.readU32();
|
||||
|
||||
assert(br.readU8() === 0, 'Non-zero marker.');
|
||||
|
||||
@ -2264,12 +2269,12 @@ TX.prototype.fromWitness = function fromWitness(data) {
|
||||
count = br.readVarint();
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
this.inputs.push(Input.fromRaw(br));
|
||||
this.inputs.push(Input.fromReader(br));
|
||||
|
||||
count = br.readVarint();
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
this.outputs.push(Output.fromRaw(br));
|
||||
this.outputs.push(Output.fromReader(br));
|
||||
|
||||
if (flag & 1) {
|
||||
flag ^= 1;
|
||||
@ -2278,7 +2283,7 @@ TX.prototype.fromWitness = function fromWitness(data) {
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
input = this.inputs[i];
|
||||
input.witness.fromRaw(br);
|
||||
input.witness.fromReader(br);
|
||||
if (input.witness.items.length > 0)
|
||||
hasWitness = true;
|
||||
}
|
||||
@ -2311,12 +2316,39 @@ TX.prototype.fromWitness = function fromWitness(data) {
|
||||
/**
|
||||
* Serialize transaction without witness.
|
||||
* @private
|
||||
* @param {BufferWriter?} writer - A buffer writer to continue writing from.
|
||||
* @returns {Buffer} Returns a BufferWriter if `writer` was passed in.
|
||||
* @returns {RawTX}
|
||||
*/
|
||||
|
||||
TX.prototype.frameNormal = function frameNormal(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
TX.prototype.frameNormal = function frameNormal() {
|
||||
var bw = new BufferWriter();
|
||||
var raw = this.frameNormalWriter(bw);
|
||||
raw.data = bw.render();
|
||||
return raw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize transaction with witness. Calculates the witness
|
||||
* size as it is framing (exposed on return value as `witness`).
|
||||
* @private
|
||||
* @returns {RawTX}
|
||||
*/
|
||||
|
||||
TX.prototype.frameWitness = function frameWitness() {
|
||||
var bw = new BufferWriter();
|
||||
var raw = this.frameWitnessWriter(bw);
|
||||
raw.data = bw.render();
|
||||
return raw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize transaction without witness.
|
||||
* @private
|
||||
* @param {BufferWriter} writer
|
||||
* @returns {RawTX}
|
||||
*/
|
||||
|
||||
TX.prototype.frameNormalWriter = function frameNormalWriter(bw) {
|
||||
var offset = bw.written;
|
||||
var i;
|
||||
|
||||
if (this.inputs.length === 0 && this.outputs.length !== 0)
|
||||
@ -2327,33 +2359,28 @@ TX.prototype.frameNormal = function frameNormal(writer) {
|
||||
bw.writeVarint(this.inputs.length);
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++)
|
||||
this.inputs[i].toRaw(bw);
|
||||
this.inputs[i].toWriter(bw);
|
||||
|
||||
bw.writeVarint(this.outputs.length);
|
||||
|
||||
for (i = 0; i < this.outputs.length; i++)
|
||||
this.outputs[i].toRaw(bw);
|
||||
this.outputs[i].toWriter(bw);
|
||||
|
||||
bw.writeU32(this.locktime);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
this._lastWitnessSize = 0;
|
||||
|
||||
return bw;
|
||||
return new RawTX(bw.written - offset, 0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize transaction with witness. Calculates the witness
|
||||
* size as it is framing (exposed on return value as `_witnessSize`).
|
||||
* size as it is framing (exposed on return value as `witness`).
|
||||
* @private
|
||||
* @param {BufferWriter?} writer - A buffer writer to continue writing from.
|
||||
* @returns {Buffer} Returns a BufferWriter if `writer` was passed in.
|
||||
* @param {BufferWriter} bw
|
||||
* @returns {RawTX}
|
||||
*/
|
||||
|
||||
TX.prototype.frameWitness = function frameWitness(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
TX.prototype.frameWitnessWriter = function frameWitnessWriter(bw) {
|
||||
var offset = bw.written;
|
||||
var witnessSize = 0;
|
||||
var i, start;
|
||||
|
||||
@ -2367,17 +2394,17 @@ TX.prototype.frameWitness = function frameWitness(writer) {
|
||||
bw.writeVarint(this.inputs.length);
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++)
|
||||
this.inputs[i].toRaw(bw);
|
||||
this.inputs[i].toWriter(bw);
|
||||
|
||||
bw.writeVarint(this.outputs.length);
|
||||
|
||||
for (i = 0; i < this.outputs.length; i++)
|
||||
this.outputs[i].toRaw(bw);
|
||||
this.outputs[i].toWriter(bw);
|
||||
|
||||
start = bw.written;
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++)
|
||||
this.inputs[i].witness.toRaw(bw);
|
||||
this.inputs[i].witness.toWriter(bw);
|
||||
|
||||
witnessSize += bw.written - start;
|
||||
|
||||
@ -2386,12 +2413,7 @@ TX.prototype.frameWitness = function frameWitness(writer) {
|
||||
if (witnessSize === this.inputs.length)
|
||||
throw new Error('Cannot serialize empty-witness tx.');
|
||||
|
||||
this._lastWitnessSize = witnessSize + 2;
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return new RawTX(bw.written - offset, witnessSize + 2);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2400,19 +2422,12 @@ TX.prototype.frameWitness = function frameWitness(writer) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
TX.isWitness = function isWitness(data) {
|
||||
if (Buffer.isBuffer(data)) {
|
||||
if (data.length < 6)
|
||||
return false;
|
||||
|
||||
return data[4] === 0 && data[5] !== 0;
|
||||
}
|
||||
|
||||
if (data.left() < 6)
|
||||
TX.isWitness = function isWitness(br) {
|
||||
if (br.left() < 6)
|
||||
return false;
|
||||
|
||||
return data.data[data.offset + 4] === 0
|
||||
&& data.data[data.offset + 5] !== 0;
|
||||
return br.data[br.offset + 4] === 0
|
||||
&& br.data[br.offset + 5] !== 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2426,13 +2441,13 @@ TX.isWitness = function isWitness(data) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
TX.prototype.toExtended = function toExtended(saveCoins, writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
TX.prototype.toExtended = function toExtended(saveCoins) {
|
||||
var bw = new BufferWriter();
|
||||
var height = this.height;
|
||||
var index = this.index;
|
||||
var i, input, field, bit, oct;
|
||||
|
||||
this.toRaw(bw);
|
||||
this.toWriter(bw);
|
||||
|
||||
bw.writeU32(this.ps);
|
||||
|
||||
@ -2469,14 +2484,11 @@ TX.prototype.toExtended = function toExtended(saveCoins, writer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
input.coin.toRaw(bw);
|
||||
input.coin.toWriter(bw);
|
||||
}
|
||||
}
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2487,10 +2499,10 @@ TX.prototype.toExtended = function toExtended(saveCoins, writer) {
|
||||
*/
|
||||
|
||||
TX.prototype.fromExtended = function fromExtended(data, saveCoins) {
|
||||
var br = BufferReader(data);
|
||||
var br = new BufferReader(data);
|
||||
var i, input, coin, field, bit, oct, spent;
|
||||
|
||||
this.fromRaw(br);
|
||||
this.fromReader(br);
|
||||
|
||||
this.ps = br.readU32();
|
||||
|
||||
@ -2520,7 +2532,7 @@ TX.prototype.fromExtended = function fromExtended(data, saveCoins) {
|
||||
if (spent)
|
||||
continue;
|
||||
|
||||
coin = Coin.fromRaw(br);
|
||||
coin = Coin.fromReader(br);
|
||||
coin.hash = input.prevout.hash;
|
||||
coin.index = input.prevout.index;
|
||||
|
||||
@ -2570,9 +2582,10 @@ TX.isTX = function isTX(obj) {
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function TXSizes() {
|
||||
this.total = 0;
|
||||
this.witness = 0;
|
||||
function RawTX(total, witness) {
|
||||
this.data = null;
|
||||
this.total = total;
|
||||
this.witness = witness;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -7,12 +7,13 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var BN = require('bn.js');
|
||||
var constants = require('../protocol/constants');
|
||||
var util = require('../utils/util');
|
||||
var encoding = require('./encoding');
|
||||
var BufferReader = require('../utils/reader');
|
||||
var BufferWriter = require('../utils/writer');
|
||||
var assert = require('assert');
|
||||
var opcodes = constants.opcodes;
|
||||
|
||||
/**
|
||||
@ -30,45 +31,160 @@ function Opcode(value, data) {
|
||||
if (!(this instanceof Opcode))
|
||||
return new Opcode(value, data);
|
||||
|
||||
this.value = value;
|
||||
this.value = value || 0;
|
||||
this.data = data || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the opcode to a buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
*/
|
||||
|
||||
Opcode.prototype.toWriter = function toWriter(bw) {
|
||||
if (this.value === -1)
|
||||
throw new Error('Cannot reserialize a parse error.');
|
||||
|
||||
if (!this.data) {
|
||||
bw.writeU8(this.value);
|
||||
return bw;
|
||||
}
|
||||
|
||||
if (this.value <= 0x4b) {
|
||||
assert(this.value === this.data.length);
|
||||
bw.writeU8(this.value);
|
||||
bw.writeBytes(this.data);
|
||||
return bw;
|
||||
}
|
||||
|
||||
switch (this.value) {
|
||||
case opcodes.OP_PUSHDATA1:
|
||||
bw.writeU8(this.value);
|
||||
bw.writeU8(this.data.length);
|
||||
bw.writeBytes(this.data);
|
||||
break;
|
||||
case opcodes.OP_PUSHDATA2:
|
||||
bw.writeU8(this.value);
|
||||
bw.writeU16(this.data.length);
|
||||
bw.writeBytes(this.data);
|
||||
break;
|
||||
case opcodes.OP_PUSHDATA4:
|
||||
bw.writeU8(this.value);
|
||||
bw.writeU32(this.data.length);
|
||||
bw.writeBytes(this.data);
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unknown pushdata opcode.');
|
||||
}
|
||||
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encode the opcode.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
Opcode.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
return this.toWriter(new BufferWriter()).render();
|
||||
};
|
||||
|
||||
if (this.value === -1)
|
||||
throw new Error('Cannot reserialize a parse error.');
|
||||
/**
|
||||
* Inject properties from buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @private
|
||||
*/
|
||||
|
||||
if (this.data) {
|
||||
if (this.value <= 0x4b) {
|
||||
bw.writeU8(this.data.length);
|
||||
bw.writeBytes(this.data);
|
||||
} else if (this.value === opcodes.OP_PUSHDATA1) {
|
||||
bw.writeU8(opcodes.OP_PUSHDATA1);
|
||||
bw.writeU8(this.data.length);
|
||||
bw.writeBytes(this.data);
|
||||
} else if (this.value === opcodes.OP_PUSHDATA2) {
|
||||
bw.writeU8(opcodes.OP_PUSHDATA2);
|
||||
bw.writeU16(this.data.length);
|
||||
bw.writeBytes(this.data);
|
||||
} else if (this.value === opcodes.OP_PUSHDATA4) {
|
||||
bw.writeU8(opcodes.OP_PUSHDATA4);
|
||||
bw.writeU32(this.data.length);
|
||||
bw.writeBytes(this.data);
|
||||
} else {
|
||||
throw new Error('Unknown pushdata opcode.');
|
||||
Opcode.prototype.fromReader = function fromReader(br) {
|
||||
var op = br.readU8();
|
||||
var size;
|
||||
|
||||
if (op >= 0x01 && op <= 0x4b) {
|
||||
if (br.left() < op) {
|
||||
this.value = -1;
|
||||
return this;
|
||||
}
|
||||
} else {
|
||||
bw.writeU8(this.value);
|
||||
this.value = op;
|
||||
this.data = br.readBytes(op);
|
||||
return this;
|
||||
}
|
||||
|
||||
return bw.render();
|
||||
switch (op) {
|
||||
case opcodes.OP_PUSHDATA1:
|
||||
if (br.left() < 1) {
|
||||
this.value = -1;
|
||||
break;
|
||||
}
|
||||
size = br.readU8();
|
||||
if (br.left() < size) {
|
||||
this.value = -1;
|
||||
break;
|
||||
}
|
||||
this.value = op;
|
||||
this.data = br.readBytes(size);
|
||||
break;
|
||||
case opcodes.OP_PUSHDATA2:
|
||||
if (br.left() < 2) {
|
||||
this.value = -1;
|
||||
break;
|
||||
}
|
||||
size = br.readU16();
|
||||
if (br.left() < size) {
|
||||
this.value = -1;
|
||||
break;
|
||||
}
|
||||
this.value = op;
|
||||
this.data = br.readBytes(size);
|
||||
break;
|
||||
case opcodes.OP_PUSHDATA4:
|
||||
if (br.left() < 4) {
|
||||
this.value = -1;
|
||||
break;
|
||||
}
|
||||
size = br.readU32();
|
||||
if (br.left() < size) {
|
||||
this.value = -1;
|
||||
break;
|
||||
}
|
||||
this.value = op;
|
||||
this.data = br.readBytes(size);
|
||||
break;
|
||||
default:
|
||||
this.value = op;
|
||||
break;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
* @returns {Opcode}
|
||||
*/
|
||||
|
||||
Opcode.prototype.fromRaw = function fromRaw(data) {
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate opcode from buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @returns {Opcode}
|
||||
*/
|
||||
|
||||
Opcode.fromReader = function fromReader(br) {
|
||||
return new Opcode().fromReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate opcode from serialized data.
|
||||
* @param {Buffer} data
|
||||
* @returns {Opcode}
|
||||
*/
|
||||
|
||||
Opcode.fromRaw = function fromRaw(data) {
|
||||
return new Opcode().fromRaw(data);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -129,7 +129,7 @@ Script.prototype.toArray = function toArray() {
|
||||
Script.prototype.fromArray = function fromArray(code) {
|
||||
assert(Array.isArray(code));
|
||||
this.code = Script.parseArray(code);
|
||||
this.raw = Script.encode(this.code);
|
||||
this.compile();
|
||||
return this;
|
||||
};
|
||||
|
||||
@ -186,7 +186,27 @@ Script.prototype.toASM = function toASM(decode) {
|
||||
*/
|
||||
|
||||
Script.prototype.compile = function compile() {
|
||||
this.raw = Script.encode(this.code);
|
||||
var bw = new BufferWriter();
|
||||
var i, op;
|
||||
|
||||
for (i = 0; i < this.code.length; i++) {
|
||||
op = this.code[i];
|
||||
op.toWriter(bw);
|
||||
}
|
||||
|
||||
this.raw = bw.render();
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Write the script to a buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
*/
|
||||
|
||||
Script.prototype.toWriter = function toWriter(bw) {
|
||||
bw.writeVarBytes(this.raw);
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -195,11 +215,7 @@ Script.prototype.compile = function compile() {
|
||||
* @returns {Buffer|String} Serialized script.
|
||||
*/
|
||||
|
||||
Script.prototype.toRaw = function toRaw(writer) {
|
||||
if (writer) {
|
||||
writer.writeVarBytes(this.raw);
|
||||
return writer;
|
||||
}
|
||||
Script.prototype.toRaw = function toRaw() {
|
||||
return this.raw;
|
||||
};
|
||||
|
||||
@ -1401,7 +1417,7 @@ Script.prototype.removeData = function removeData(data) {
|
||||
for (i = index.length - 1; i >= 0; i--)
|
||||
this.code.splice(index[i], 1);
|
||||
|
||||
this.raw = Script.encode(this.code);
|
||||
this.compile();
|
||||
|
||||
return index.length;
|
||||
};
|
||||
@ -1478,14 +1494,11 @@ Script.isMinimal = function isMinimal(data, opcode, flags) {
|
||||
*/
|
||||
|
||||
Script.isCode = function isCode(raw) {
|
||||
var i, op, code;
|
||||
var script = Script.fromRaw(raw);
|
||||
var i, op;
|
||||
|
||||
assert(Buffer.isBuffer(raw));
|
||||
|
||||
code = Script.decode(raw);
|
||||
|
||||
for (i = 0; i < code.length; i++) {
|
||||
op = code[i];
|
||||
for (i = 0; i < script.code.length; i++) {
|
||||
op = script.code[i];
|
||||
|
||||
if (op.data)
|
||||
continue;
|
||||
@ -2430,7 +2443,8 @@ Script.prototype.getCoinbaseFlags = function getCoinbaseFlags() {
|
||||
else
|
||||
nonce = -1;
|
||||
|
||||
flags = Script.encode(this.code.slice(index));
|
||||
flags = Script.fromArray(this.code.slice(index));
|
||||
flags = flags.toRaw();
|
||||
|
||||
text = flags.toString('utf8');
|
||||
text = text.replace(/[\u0000-\u0019\u007f-\u00ff]/g, '');
|
||||
@ -3439,6 +3453,16 @@ Script.sign = function sign(msg, key, type) {
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from buffer reader.
|
||||
* @private
|
||||
* @param {BufferReader} br
|
||||
*/
|
||||
|
||||
Script.prototype.fromReader = function fromReader(br) {
|
||||
return this.fromRaw(br.readVarBytes());
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
@ -3446,15 +3470,27 @@ Script.sign = function sign(msg, key, type) {
|
||||
*/
|
||||
|
||||
Script.prototype.fromRaw = function fromRaw(data) {
|
||||
if (data instanceof BufferReader)
|
||||
data = data.readVarBytes();
|
||||
var br = new BufferReader(data, true);
|
||||
|
||||
this.raw = data;
|
||||
this.code = Script.decode(data);
|
||||
|
||||
while (br.left())
|
||||
this.code.push(Opcode.fromReader(br));
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a script from buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @param {String?} enc - Either `"hex"` or `null`.
|
||||
* @returns {Script}
|
||||
*/
|
||||
|
||||
Script.fromReader = function fromReader(br) {
|
||||
return new Script().fromReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a script from a serialized buffer.
|
||||
* @param {Buffer|String} data - Serialized script.
|
||||
@ -3468,127 +3504,6 @@ Script.fromRaw = function fromRaw(data, enc) {
|
||||
return new Script().fromRaw(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Decode a serialized script into script code.
|
||||
* Note that the serialized script must _not_
|
||||
* include the varint size before it. Parse
|
||||
* errors will output an opcode with a value
|
||||
* of -1.
|
||||
*
|
||||
* @param {Buffer} raw - Serialized script.
|
||||
* @returns {Opcode[]} Script code.
|
||||
*/
|
||||
|
||||
Script.decode = function decode(raw) {
|
||||
var br = new BufferReader(raw, true);
|
||||
var code = [];
|
||||
var op, size, data;
|
||||
|
||||
assert(Buffer.isBuffer(raw));
|
||||
|
||||
while (br.left()) {
|
||||
op = br.readU8();
|
||||
if (op >= 0x01 && op <= 0x4b) {
|
||||
if (br.left() < op) {
|
||||
code.push(new Opcode(-1));
|
||||
break;
|
||||
}
|
||||
data = br.readBytes(op);
|
||||
code.push(new Opcode(op, data));
|
||||
} else if (op === opcodes.OP_PUSHDATA1) {
|
||||
if (br.left() < 1) {
|
||||
code.push(new Opcode(-1));
|
||||
break;
|
||||
}
|
||||
size = br.readU8();
|
||||
if (br.left() < size) {
|
||||
code.push(new Opcode(-1));
|
||||
break;
|
||||
}
|
||||
data = br.readBytes(size);
|
||||
code.push(new Opcode(op, data));
|
||||
} else if (op === opcodes.OP_PUSHDATA2) {
|
||||
if (br.left() < 2) {
|
||||
code.push(new Opcode(-1));
|
||||
break;
|
||||
}
|
||||
size = br.readU16();
|
||||
if (br.left() < size) {
|
||||
code.push(new Opcode(-1));
|
||||
break;
|
||||
}
|
||||
data = br.readBytes(size);
|
||||
code.push(new Opcode(op, data));
|
||||
} else if (op === opcodes.OP_PUSHDATA4) {
|
||||
if (br.left() < 4) {
|
||||
code.push(new Opcode(-1));
|
||||
break;
|
||||
}
|
||||
size = br.readU32();
|
||||
if (br.left() < size) {
|
||||
code.push(new Opcode(-1));
|
||||
break;
|
||||
}
|
||||
data = br.readBytes(size);
|
||||
code.push(new Opcode(op, data));
|
||||
} else {
|
||||
code.push(new Opcode(op));
|
||||
}
|
||||
}
|
||||
|
||||
return code;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encode and serialize script code. This will _not_
|
||||
* include the varint size at the start.
|
||||
* @param {Array} code - Script code.
|
||||
* @returns {Buffer} Serialized script.
|
||||
*/
|
||||
|
||||
Script.encode = function encode(code, writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
var i, op;
|
||||
|
||||
assert(Array.isArray(code));
|
||||
|
||||
for (i = 0; i < code.length; i++) {
|
||||
op = code[i];
|
||||
|
||||
if (op.value === -1)
|
||||
throw new Error('Cannot reserialize a parse error.');
|
||||
|
||||
if (op.data) {
|
||||
if (op.value <= 0x4b) {
|
||||
bw.writeU8(op.data.length);
|
||||
bw.writeBytes(op.data);
|
||||
} else if (op.value === opcodes.OP_PUSHDATA1) {
|
||||
bw.writeU8(opcodes.OP_PUSHDATA1);
|
||||
bw.writeU8(op.data.length);
|
||||
bw.writeBytes(op.data);
|
||||
} else if (op.value === opcodes.OP_PUSHDATA2) {
|
||||
bw.writeU8(opcodes.OP_PUSHDATA2);
|
||||
bw.writeU16(op.data.length);
|
||||
bw.writeBytes(op.data);
|
||||
} else if (op.value === opcodes.OP_PUSHDATA4) {
|
||||
bw.writeU8(opcodes.OP_PUSHDATA4);
|
||||
bw.writeU32(op.data.length);
|
||||
bw.writeBytes(op.data);
|
||||
} else {
|
||||
throw new Error('Unknown pushdata opcode.');
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
bw.writeU8(op.value);
|
||||
}
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert an array of Buffers and
|
||||
* Numbers into an array of Opcodes.
|
||||
|
||||
@ -299,13 +299,11 @@ Witness.prototype.indexOf = function indexOf(data) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Encode the witness to a Buffer.
|
||||
* @param {String} enc - Encoding, either `'hex'` or `null`.
|
||||
* @returns {Buffer|String} Serialized script.
|
||||
* Write witness to a buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
*/
|
||||
|
||||
Witness.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
Witness.prototype.toWriter = function toWriter(bw) {
|
||||
var i;
|
||||
|
||||
bw.writeVarint(this.items.length);
|
||||
@ -313,12 +311,19 @@ Witness.prototype.toRaw = function toRaw(writer) {
|
||||
for (i = 0; i < this.items.length; i++)
|
||||
bw.writeVarBytes(this.items[i]);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encode the witness to a Buffer.
|
||||
* @param {String} enc - Encoding, either `'hex'` or `null`.
|
||||
* @returns {Buffer|String} Serialized script.
|
||||
*/
|
||||
|
||||
Witness.prototype.toRaw = function toRaw() {
|
||||
return this.toWriter(new BufferWriter()).render();
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert witness to a hex string.
|
||||
* @returns {String}
|
||||
@ -513,13 +518,12 @@ Witness.encodeItem = function encodeItem(data) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* Inject properties from buffer reader.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
* @param {BufferReader} br
|
||||
*/
|
||||
|
||||
Witness.prototype.fromRaw = function fromRaw(data) {
|
||||
var br = BufferReader(data);
|
||||
Witness.prototype.fromReader = function fromReader(br) {
|
||||
var chunkCount = br.readVarint();
|
||||
var i;
|
||||
|
||||
@ -530,7 +534,26 @@ Witness.prototype.fromRaw = function fromRaw(data) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a Witness from a serialized buffer.
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
Witness.prototype.fromRaw = function fromRaw(data) {
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a witness from a buffer reader.
|
||||
* @param {BufferReader} br
|
||||
*/
|
||||
|
||||
Witness.fromReader = function fromReader(br) {
|
||||
return new Witness().fromReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a witness from a serialized buffer.
|
||||
* @param {Buffer|String} data - Serialized witness.
|
||||
* @param {String?} enc - Either `"hex"` or `null`.
|
||||
* @returns {Witness}
|
||||
|
||||
@ -29,113 +29,96 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var BufferReader = require('./reader');
|
||||
var ASN1 = exports;
|
||||
|
||||
ASN1.parseTag = function parseTag(br) {
|
||||
var tag = br.readU8();
|
||||
var primitive = (tag & 0x20) === 0;
|
||||
/*
|
||||
* Primitives
|
||||
*/
|
||||
|
||||
ASN1.readTag = function readTag(br) {
|
||||
var type = br.readU8();
|
||||
var primitive = (type & 0x20) === 0;
|
||||
var oct;
|
||||
|
||||
if ((tag & 0x1f) === 0x1f) {
|
||||
oct = tag;
|
||||
tag = 0;
|
||||
if ((type & 0x1f) === 0x1f) {
|
||||
oct = type;
|
||||
type = 0;
|
||||
while ((oct & 0x80) === 0x80) {
|
||||
oct = br.readU8();
|
||||
tag <<= 7;
|
||||
tag |= oct & 0x7f;
|
||||
type <<= 7;
|
||||
type |= oct & 0x7f;
|
||||
}
|
||||
} else {
|
||||
tag &= 0x1f;
|
||||
type &= 0x1f;
|
||||
}
|
||||
|
||||
return {
|
||||
type: type,
|
||||
primitive: primitive,
|
||||
tag: tag,
|
||||
len: ASN1.parseLen(br, primitive)
|
||||
size: ASN1.readSize(br, primitive)
|
||||
};
|
||||
};
|
||||
|
||||
ASN1.parseLen = function parseLen(br, primitive) {
|
||||
var len = br.readU8();
|
||||
var num, i, j;
|
||||
ASN1.readSize = function readSize(br, primitive) {
|
||||
var size = br.readU8();
|
||||
var bytes, i, j;
|
||||
|
||||
// Indefinite form
|
||||
if (!primitive && len === 0x80)
|
||||
return null;
|
||||
if (!primitive && size === 0x80)
|
||||
throw new Error('Indefinite size.');
|
||||
|
||||
// Definite form
|
||||
if ((len & 0x80) === 0) {
|
||||
if ((size & 0x80) === 0) {
|
||||
// Short form
|
||||
return len;
|
||||
return size;
|
||||
}
|
||||
|
||||
// Long form
|
||||
num = len & 0x7f;
|
||||
assert(num < 4, 'length octect is too long');
|
||||
bytes = size & 0x7f;
|
||||
|
||||
len = 0;
|
||||
for (i = 0; i < num; i++) {
|
||||
len <<= 8;
|
||||
if (bytes > 3)
|
||||
throw new Error('Length octet is too long.');
|
||||
|
||||
size = 0;
|
||||
for (i = 0; i < bytes; i++) {
|
||||
size <<= 8;
|
||||
j = br.readU8();
|
||||
len |= j;
|
||||
size |= j;
|
||||
}
|
||||
|
||||
return len;
|
||||
return size;
|
||||
};
|
||||
|
||||
ASN1.parseCert = function parseCert(data) {
|
||||
var d = BufferReader(data);
|
||||
var br;
|
||||
|
||||
d.start();
|
||||
|
||||
br = BufferReader(ASN1.parseSeq(d));
|
||||
|
||||
return {
|
||||
tbs: ASN1.parseTBS(br),
|
||||
sigAlg: ASN1.parseAlgIdent(br),
|
||||
sig: ASN1.parseBitstr(br),
|
||||
raw: d.endData(true)
|
||||
};
|
||||
ASN1.readSeq = function readSeq(br) {
|
||||
var tag = ASN1.implicit(br, 0x10);
|
||||
return br.readBytes(tag.size);
|
||||
};
|
||||
|
||||
ASN1.parseTBS = function parseTBS(data) {
|
||||
var d = BufferReader(data);
|
||||
var br;
|
||||
|
||||
d.start();
|
||||
|
||||
br = BufferReader(ASN1.parseSeq(d));
|
||||
|
||||
return {
|
||||
version: ASN1.parseExplicitInt(br, 0, true),
|
||||
serial: ASN1.parseInt(br),
|
||||
sig: ASN1.parseAlgIdent(br),
|
||||
issuer: ASN1.parseName(br),
|
||||
validity: ASN1.parseValidity(br),
|
||||
subject: ASN1.parseName(br),
|
||||
pubkey: ASN1.parsePubkey(br),
|
||||
raw: d.endData(true)
|
||||
};
|
||||
ASN1.implicit = function implicit(br, type) {
|
||||
var tag = ASN1.readTag(br);
|
||||
if (tag.type !== type)
|
||||
throw new Error('Unexpected tag: ' + tag.type + '.');
|
||||
return tag;
|
||||
};
|
||||
|
||||
ASN1.parseSeq = function parseSeq(data) {
|
||||
var br = BufferReader(data);
|
||||
var tag = ASN1.parseTag(br);
|
||||
assert.equal(tag.tag, 0x10); // seq
|
||||
return br.readBytes(tag.len, true);
|
||||
ASN1.explicit = function explicit(br, type) {
|
||||
var offset = br.offset;
|
||||
var tag = ASN1.readTag(br);
|
||||
if (tag.type !== type) {
|
||||
br.offset = offset;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
ASN1.parseInt = function parseInt(data, readNum) {
|
||||
var br = BufferReader(data);
|
||||
var tag = ASN1.parseTag(br);
|
||||
var num;
|
||||
ASN1.seq = function seq(br) {
|
||||
return new BufferReader(ASN1.readSeq(br), true);
|
||||
};
|
||||
|
||||
assert.equal(tag.tag, 0x02); // int
|
||||
|
||||
num = br.readBytes(tag.len, true);
|
||||
ASN1.readInt = function readInt(br, readNum) {
|
||||
var tag = ASN1.implicit(br, 0x02);
|
||||
var num = br.readBytes(tag.size);
|
||||
|
||||
if (readNum)
|
||||
return num.readUIntBE(0, num.length);
|
||||
@ -143,30 +126,28 @@ ASN1.parseInt = function parseInt(data, readNum) {
|
||||
return num;
|
||||
};
|
||||
|
||||
ASN1.parseExplicitInt = function parseExplicitInt(data, i, readNum) {
|
||||
var br = BufferReader(data);
|
||||
var off = br.offset;
|
||||
var tag = ASN1.parseTag(br);
|
||||
if (tag.tag !== i) {
|
||||
br.seek(-(br.offset - off));
|
||||
ASN1.readExplicitInt = function readExplicitInt(br, type, readNum) {
|
||||
if (!ASN1.explicit(br, type))
|
||||
return -1;
|
||||
}
|
||||
return ASN1.parseInt(br, readNum);
|
||||
return ASN1.readInt(br, readNum);
|
||||
};
|
||||
|
||||
ASN1.parseBitstr = function parseBitstr(data) {
|
||||
var br = BufferReader(data);
|
||||
var tag = ASN1.parseTag(br);
|
||||
assert.equal(tag.tag, 0x03); // bitstr
|
||||
return ASN1.alignBitstr(br.readBytes(tag.len, true));
|
||||
ASN1.readBitstr = function readBitstr(br) {
|
||||
var tag = ASN1.implicit(br, 0x03);
|
||||
var str = br.readBytes(tag.size);
|
||||
return ASN1.alignBitstr(str);
|
||||
};
|
||||
|
||||
ASN1.parseString = function parseString(data) {
|
||||
var br = BufferReader(data);
|
||||
var tag = ASN1.parseTag(br);
|
||||
switch (tag.tag) {
|
||||
ASN1.readString = function readString(br) {
|
||||
var tag = ASN1.readTag(br);
|
||||
var str;
|
||||
|
||||
switch (tag.type) {
|
||||
case 0x03: // bitstr
|
||||
return ASN1.alignBitstr(br.readBytes(tag.len, true));
|
||||
str = br.readBytes(tag.size);
|
||||
return ASN1.alignBitstr(str);
|
||||
// Note:
|
||||
// Fuck all these.
|
||||
case 0x04: // octstr
|
||||
case 0x12: // numstr
|
||||
case 0x13: // prinstr
|
||||
@ -180,9 +161,9 @@ ASN1.parseString = function parseString(data) {
|
||||
case 0x1c: // unistr
|
||||
case 0x1d: // charstr
|
||||
case 0x1e: // bmpstr
|
||||
return br.readString('utf8', tag.len);
|
||||
return br.readString('utf8', tag.size);
|
||||
default:
|
||||
assert(false, 'Bad string.');
|
||||
throw new Error('Unexpected tag: ' + tag.type + '.');
|
||||
}
|
||||
};
|
||||
|
||||
@ -207,52 +188,83 @@ ASN1.alignBitstr = function(data) {
|
||||
return out;
|
||||
};
|
||||
|
||||
ASN1.parsePubkey = function parsePubkey(data) {
|
||||
var br = BufferReader(data);
|
||||
br = BufferReader(ASN1.parseSeq(br));
|
||||
/*
|
||||
* Certificates
|
||||
*/
|
||||
|
||||
ASN1.readCert = function readCert(br) {
|
||||
var buf = br;
|
||||
|
||||
buf.start();
|
||||
|
||||
br = ASN1.seq(buf);
|
||||
|
||||
return {
|
||||
alg: ASN1.parseAlgIdent(br),
|
||||
pubkey: ASN1.parseBitstr(br)
|
||||
tbs: ASN1.readTBS(br),
|
||||
sigAlg: ASN1.readAlgIdent(br),
|
||||
sig: ASN1.readBitstr(br),
|
||||
raw: buf.endData(true)
|
||||
};
|
||||
};
|
||||
|
||||
ASN1.parseName = function parseName(data) {
|
||||
var br = BufferReader(data);
|
||||
var values = [];
|
||||
var tag;
|
||||
ASN1.readTBS = function readTBS(br) {
|
||||
var buf = br;
|
||||
|
||||
br = BufferReader(ASN1.parseSeq(br));
|
||||
buf.start();
|
||||
|
||||
br = ASN1.seq(buf);
|
||||
|
||||
return {
|
||||
version: ASN1.readExplicitInt(br, 0x00, true),
|
||||
serial: ASN1.readInt(br),
|
||||
sig: ASN1.readAlgIdent(br),
|
||||
issuer: ASN1.readName(br),
|
||||
validity: ASN1.readValidity(br),
|
||||
subject: ASN1.readName(br),
|
||||
pubkey: ASN1.readPubkey(br),
|
||||
raw: buf.endData(true)
|
||||
};
|
||||
};
|
||||
|
||||
ASN1.readPubkey = function readPubkey(br) {
|
||||
br = ASN1.seq(br);
|
||||
return {
|
||||
alg: ASN1.readAlgIdent(br),
|
||||
pubkey: ASN1.readBitstr(br)
|
||||
};
|
||||
};
|
||||
|
||||
ASN1.readName = function readName(br) {
|
||||
var values = [];
|
||||
|
||||
br = ASN1.seq(br);
|
||||
|
||||
while (br.left()) {
|
||||
tag = ASN1.parseTag(br);
|
||||
assert.equal(tag.tag, 0x11); // set
|
||||
tag = ASN1.parseTag(br);
|
||||
assert.equal(tag.tag, 0x10); // seq
|
||||
ASN1.implicit(br, 0x11); // set
|
||||
ASN1.implicit(br, 0x10); // seq
|
||||
values.push({
|
||||
type: ASN1.parseOID(br),
|
||||
value: ASN1.parseString(br)
|
||||
type: ASN1.readOID(br),
|
||||
value: ASN1.readString(br)
|
||||
});
|
||||
}
|
||||
|
||||
return values;
|
||||
};
|
||||
|
||||
ASN1.parseValidity = function parseValidity(data) {
|
||||
var br = BufferReader(data);
|
||||
br = BufferReader(ASN1.parseSeq(br));
|
||||
ASN1.readValidity = function readValidity(br) {
|
||||
br = ASN1.seq(br);
|
||||
return {
|
||||
notBefore: ASN1.parseTime(br),
|
||||
notAfter: ASN1.parseTime(br)
|
||||
notBefore: ASN1.readTime(br),
|
||||
notAfter: ASN1.readTime(br)
|
||||
};
|
||||
};
|
||||
|
||||
ASN1.parseTime = function parseTime(data) {
|
||||
var br = BufferReader(data);
|
||||
var tag = ASN1.parseTag(br);
|
||||
var str = br.readString('ascii', tag.len);
|
||||
ASN1.readTime = function readTime(br) {
|
||||
var tag = ASN1.readTag(br);
|
||||
var str = br.readString('ascii', tag.size);
|
||||
var year, mon, day, hour, min, sec;
|
||||
|
||||
switch (tag.tag) {
|
||||
switch (tag.type) {
|
||||
case 0x17: // utctime
|
||||
year = str.slice(0, 2) | 0;
|
||||
mon = str.slice(2, 4) | 0;
|
||||
@ -274,25 +286,24 @@ ASN1.parseTime = function parseTime(data) {
|
||||
sec = str.slice(12, 14) | 0;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
throw new Error('Unexpected tag: ' + tag.type + '.');
|
||||
}
|
||||
|
||||
return Date.UTC(year, mon - 1, day, hour, min, sec, 0) / 1000;
|
||||
};
|
||||
|
||||
ASN1.parseOID = function parseOID(data) {
|
||||
var br = BufferReader(data);
|
||||
var tag = ASN1.parseTag(br);
|
||||
ASN1.readOID = function readOID(br) {
|
||||
var tag = ASN1.implicit(br, 0x06);
|
||||
var data = br.readBytes(tag.size);
|
||||
return ASN1.formatOID(data);
|
||||
};
|
||||
|
||||
ASN1.formatOID = function formatOID(data) {
|
||||
var br = new BufferReader(data);
|
||||
var ids = [];
|
||||
var ident = 0;
|
||||
var subident = 0;
|
||||
var objid, result, first, second;
|
||||
|
||||
assert.equal(tag.tag, 0x06); // objid
|
||||
|
||||
objid = br.readBytes(tag.len, true);
|
||||
br = BufferReader(objid);
|
||||
var result, first, second;
|
||||
|
||||
while (br.left()) {
|
||||
subident = br.readU8();
|
||||
@ -314,17 +325,17 @@ ASN1.parseOID = function parseOID(data) {
|
||||
return result.join('.');
|
||||
};
|
||||
|
||||
ASN1.parseAlgIdent = function parseAlgIdent(data) {
|
||||
var br = BufferReader(data);
|
||||
ASN1.readAlgIdent = function readAlgIdent(br) {
|
||||
var params = null;
|
||||
var alg;
|
||||
var alg, tag;
|
||||
|
||||
br = BufferReader(ASN1.parseSeq(br));
|
||||
br = ASN1.seq(br);
|
||||
|
||||
alg = ASN1.parseOID(br);
|
||||
alg = ASN1.readOID(br);
|
||||
|
||||
if (br.left() > 0) {
|
||||
params = br.readBytes(ASN1.parseTag(br).len, true);
|
||||
tag = ASN1.readTag(br);
|
||||
params = br.readBytes(tag.size);
|
||||
if (params.length === 0)
|
||||
params = null;
|
||||
}
|
||||
@ -335,27 +346,49 @@ ASN1.parseAlgIdent = function parseAlgIdent(data) {
|
||||
};
|
||||
};
|
||||
|
||||
ASN1.parseRSAPublic = function parseRSAPublic(data) {
|
||||
var br = BufferReader(data);
|
||||
br = BufferReader(ASN1.parseSeq(br));
|
||||
/*
|
||||
* RSA
|
||||
*/
|
||||
|
||||
ASN1.readRSAPublic = function readRSAPublic(br) {
|
||||
br = ASN1.seq(br);
|
||||
return {
|
||||
modulus: ASN1.parseInt(br),
|
||||
publicExponent: ASN1.parseInt(br)
|
||||
modulus: ASN1.readInt(br),
|
||||
publicExponent: ASN1.readInt(br)
|
||||
};
|
||||
};
|
||||
|
||||
ASN1.parseRSAPrivate = function parseRSAPrivate(data) {
|
||||
var br = BufferReader(data);
|
||||
br = BufferReader(ASN1.parseSeq(br));
|
||||
ASN1.readRSAPrivate = function readRSAPrivate(br) {
|
||||
br = ASN1.seq(br);
|
||||
return {
|
||||
version: ASN1.parseInt(br, true),
|
||||
modulus: ASN1.parseInt(br),
|
||||
publicExponent: ASN1.parseInt(br),
|
||||
privateExponent: ASN1.parseInt(br),
|
||||
prime1: ASN1.parseInt(br),
|
||||
prime2: ASN1.parseInt(br),
|
||||
exponent1: ASN1.parseInt(br),
|
||||
exponent2: ASN1.parseInt(br),
|
||||
coefficient: ASN1.parseInt(br)
|
||||
version: ASN1.readInt(br, true),
|
||||
modulus: ASN1.readInt(br),
|
||||
publicExponent: ASN1.readInt(br),
|
||||
privateExponent: ASN1.readInt(br),
|
||||
prime1: ASN1.readInt(br),
|
||||
prime2: ASN1.readInt(br),
|
||||
exponent1: ASN1.readInt(br),
|
||||
exponent2: ASN1.readInt(br),
|
||||
coefficient: ASN1.readInt(br)
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* Public
|
||||
*/
|
||||
|
||||
ASN1.parseRSAPublic = function parseRSAPublic(data) {
|
||||
return ASN1.readRSAPublic(new BufferReader(data, true));
|
||||
};
|
||||
|
||||
ASN1.parseRSAPrivate = function parseRSAPrivate(data) {
|
||||
return ASN1.readRSAPrivate(new BufferReader(data, true));
|
||||
};
|
||||
|
||||
ASN1.parseCert = function parseCert(data) {
|
||||
return ASN1.readCert(new BufferReader(data, true));
|
||||
};
|
||||
|
||||
ASN1.parseTBS = function parseTBS(data) {
|
||||
return ASN1.readTBS(new BufferReader(data, true));
|
||||
};
|
||||
|
||||
@ -178,18 +178,15 @@ Bloom.fromRate = function fromRate(items, rate, update) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
Bloom.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
Bloom.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
|
||||
bw.writeVarBytes(this.filter);
|
||||
bw.writeU32(this.n);
|
||||
bw.writeU32(this.tweak);
|
||||
bw.writeU8(this.update);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -199,7 +196,7 @@ Bloom.prototype.toRaw = function toRaw(writer) {
|
||||
*/
|
||||
|
||||
Bloom.prototype.fromRaw = function fromRaw(data) {
|
||||
var br = BufferReader(data);
|
||||
var br = new BufferReader(data);
|
||||
|
||||
this.filter = br.readVarBytes();
|
||||
this.n = br.readU32();
|
||||
|
||||
@ -11,6 +11,10 @@ var assert = require('assert');
|
||||
var BufferReader = require('../utils/reader');
|
||||
var BufferWriter = require('../utils/writer');
|
||||
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
|
||||
var wireType = {
|
||||
VARINT: 0,
|
||||
FIXED64: 1,
|
||||
@ -20,11 +24,15 @@ var wireType = {
|
||||
FIXED32: 5
|
||||
};
|
||||
|
||||
/**
|
||||
* ProtoReader
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
function ProtoReader(data, zeroCopy) {
|
||||
if (data instanceof ProtoReader)
|
||||
return data;
|
||||
if (!(this instanceof ProtoReader))
|
||||
return new ProtoReader(data, zeroCopy);
|
||||
|
||||
BufferReader.call(this, data, zeroCopy);
|
||||
}
|
||||
|
||||
@ -92,72 +100,105 @@ ProtoReader.prototype.nextTag = function nextTag() {
|
||||
ProtoReader.prototype.readField = function readField(tag, opt) {
|
||||
var offset = this.offset;
|
||||
var header = this.readVarint();
|
||||
var value, data, group, field;
|
||||
var field = new Field(header);
|
||||
var inner;
|
||||
|
||||
if (tag != null && (header >>> 3) !== tag) {
|
||||
if (tag != null && field.tag !== tag) {
|
||||
assert(opt, 'Non-optional field not present.');
|
||||
this.offset = offset;
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (header & 7) {
|
||||
switch (field.type) {
|
||||
case wireType.VARINT:
|
||||
value = this.readVarint();
|
||||
field.value = this.readVarint();
|
||||
break;
|
||||
case wireType.FIXED64:
|
||||
value = this.readU64();
|
||||
field.value = this.readU64();
|
||||
break;
|
||||
case wireType.DELIMITED:
|
||||
data = this.readVarBytes();
|
||||
field.data = this.readVarBytes();
|
||||
break;
|
||||
case wireType.START_GROUP:
|
||||
group = [];
|
||||
field.group = [];
|
||||
for (;;) {
|
||||
field = this.readField();
|
||||
if (field.type === wireType.END_GROUP)
|
||||
inner = this.readField();
|
||||
if (inner.type === wireType.END_GROUP)
|
||||
break;
|
||||
group.push(field);
|
||||
field.group.push(inner);
|
||||
}
|
||||
break;
|
||||
case wireType.END_GROUP:
|
||||
assert(false, 'Unexpected end group.');
|
||||
break;
|
||||
case wireType.FIXED32:
|
||||
value = this.readU32();
|
||||
field.value = this.readU32();
|
||||
break;
|
||||
default:
|
||||
assert(false, 'Bad wire type.');
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
size: this.offset - offset,
|
||||
header: header,
|
||||
tag: header >>> 3,
|
||||
type: header & 7,
|
||||
value: value,
|
||||
data: data,
|
||||
group: group
|
||||
};
|
||||
field.size = this.offset - offset;
|
||||
|
||||
return field;
|
||||
};
|
||||
|
||||
function ProtoWriter(options) {
|
||||
if (options instanceof ProtoWriter)
|
||||
return options;
|
||||
/**
|
||||
* ProtoWriter
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
function ProtoWriter() {
|
||||
if (!(this instanceof ProtoWriter))
|
||||
return new ProtoWriter(options);
|
||||
return new ProtoWriter();
|
||||
|
||||
BufferWriter.call(this, options);
|
||||
BufferWriter.call(this);
|
||||
}
|
||||
|
||||
util.inherits(ProtoWriter, BufferWriter);
|
||||
|
||||
ProtoWriter.prototype.writeVarint = function writeVarint(num) {
|
||||
var size = exports.sizeVarint(num);
|
||||
var buf = new Buffer(size);
|
||||
exports.writeVarint(buf, num, 0);
|
||||
this.writeBytes(buf);
|
||||
var value;
|
||||
|
||||
// Avoid an extra allocation until
|
||||
// we make bufferwriter more hackable.
|
||||
// More insanity here...
|
||||
switch (size) {
|
||||
case 6:
|
||||
value = exports.slipVarint(num);
|
||||
this.writeU32BE(value / 0x10000 | 0);
|
||||
this.writeU16BE(value & 0xffff);
|
||||
break;
|
||||
case 5:
|
||||
value = exports.slipVarint(num);
|
||||
this.writeU32BE(value / 0x100 | 0);
|
||||
this.writeU8(value & 0xff);
|
||||
break;
|
||||
case 4:
|
||||
value = exports.slipVarint(num);
|
||||
this.writeU32BE(value);
|
||||
break;
|
||||
case 3:
|
||||
value = exports.slipVarint(num);
|
||||
this.writeU16BE(value >> 8);
|
||||
this.writeU8(value & 0xff);
|
||||
break;
|
||||
case 2:
|
||||
value = exports.slipVarint(num);
|
||||
this.writeU16BE(value);
|
||||
break;
|
||||
case 1:
|
||||
value = exports.slipVarint(num);
|
||||
this.writeU8(value);
|
||||
break;
|
||||
default:
|
||||
value = new Buffer(size);
|
||||
exports.writeVarint(value, num, 0);
|
||||
this.writeBytes(value);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
ProtoWriter.prototype.writeFieldVarint = function writeFieldVarint(tag, value) {
|
||||
@ -189,6 +230,10 @@ ProtoWriter.prototype.writeFieldString = function writeFieldString(tag, data, en
|
||||
this.writeFieldBytes(tag, data);
|
||||
};
|
||||
|
||||
/*
|
||||
* Encoding
|
||||
*/
|
||||
|
||||
exports.readVarint = function readVarint(data, off) {
|
||||
var num = 0;
|
||||
var ch = 0x80;
|
||||
@ -199,7 +244,9 @@ exports.readVarint = function readVarint(data, off) {
|
||||
num = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
ch = data[off++];
|
||||
|
||||
// Optimization for javascript insanity.
|
||||
switch (size) {
|
||||
case 0:
|
||||
@ -215,12 +262,13 @@ exports.readVarint = function readVarint(data, off) {
|
||||
num += (ch & 0x7f) * Math.pow(2, 7 * size);
|
||||
break;
|
||||
}
|
||||
|
||||
size++;
|
||||
|
||||
assert(size < 7, 'Number exceeds 2^53-1.');
|
||||
}
|
||||
|
||||
assert(util.isSafeInteger(num), 'Number exceeds 2^53-1.');
|
||||
|
||||
return { size: size, value: num };
|
||||
return new Varint(size, num);
|
||||
};
|
||||
|
||||
exports.writeVarint = function writeVarint(data, num, off) {
|
||||
@ -242,6 +290,28 @@ exports.writeVarint = function writeVarint(data, num, off) {
|
||||
return off;
|
||||
};
|
||||
|
||||
exports.slipVarint = function slipVarint(num) {
|
||||
var data = 0;
|
||||
var size = 0;
|
||||
var ch;
|
||||
|
||||
assert(util.isSafeInteger(num), 'Number exceeds 2^53-1.');
|
||||
|
||||
do {
|
||||
assert(size < 7);
|
||||
ch = num & 0x7f;
|
||||
num -= num % 0x80;
|
||||
num /= 0x80;
|
||||
if (num !== 0)
|
||||
ch |= 0x80;
|
||||
data *= 256;
|
||||
data += ch;
|
||||
size++;
|
||||
} while (num > 0);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
exports.sizeVarint = function sizeVarint(num) {
|
||||
var size = 0;
|
||||
|
||||
@ -256,5 +326,27 @@ exports.sizeVarint = function sizeVarint(num) {
|
||||
return size;
|
||||
};
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function Field(header) {
|
||||
this.tag = header >>> 3;
|
||||
this.type = header & 7;
|
||||
this.size = 0;
|
||||
this.value = 0;
|
||||
this.data = null;
|
||||
this.group = null;
|
||||
}
|
||||
|
||||
function Varint(size, value) {
|
||||
this.size = size;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
exports.ProtoReader = ProtoReader;
|
||||
exports.ProtoWriter = ProtoWriter;
|
||||
|
||||
@ -7,9 +7,9 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var encoding = require('./encoding');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var assert = require('assert');
|
||||
|
||||
/**
|
||||
* An object that allows reading of buffers in a sane manner.
|
||||
@ -22,15 +22,14 @@ var assert = require('assert');
|
||||
*/
|
||||
|
||||
function BufferReader(data, zeroCopy) {
|
||||
if (data instanceof BufferReader)
|
||||
return data;
|
||||
|
||||
if (!(this instanceof BufferReader))
|
||||
return new BufferReader(data, zeroCopy);
|
||||
|
||||
assert(Buffer.isBuffer(data), 'Must pass a Buffer.');
|
||||
|
||||
this.data = data;
|
||||
this.offset = 0;
|
||||
this.zeroCopy = zeroCopy;
|
||||
this.zeroCopy = zeroCopy || false;
|
||||
this.stack = [];
|
||||
}
|
||||
|
||||
|
||||
@ -56,12 +56,9 @@ var FILL = 24;
|
||||
* @param {(BufferWriter|Object)?} options
|
||||
*/
|
||||
|
||||
function BufferWriter(options) {
|
||||
if (options instanceof BufferWriter)
|
||||
return options;
|
||||
|
||||
function BufferWriter() {
|
||||
if (!(this instanceof BufferWriter))
|
||||
return new BufferWriter(options);
|
||||
return new BufferWriter();
|
||||
|
||||
this.ops = [];
|
||||
this.written = 0;
|
||||
|
||||
@ -910,8 +910,8 @@ Account.prototype.toJSON = function toJSON(minimal) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
Account.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
Account.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
var i, key;
|
||||
|
||||
bw.writeVarString(this.name, 'ascii');
|
||||
@ -933,10 +933,7 @@ Account.prototype.toRaw = function toRaw(writer) {
|
||||
bw.writeBytes(key.toRaw());
|
||||
}
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -445,8 +445,8 @@ MasterKey.prototype._encrypt = co(function* encrypt(passphrase, aes) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
MasterKey.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
MasterKey.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
|
||||
if (this.encrypted) {
|
||||
bw.writeU8(1);
|
||||
@ -458,19 +458,13 @@ MasterKey.prototype.toRaw = function toRaw(writer) {
|
||||
bw.writeU32(this.r);
|
||||
bw.writeU32(this.p);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
}
|
||||
|
||||
bw.writeU8(0);
|
||||
bw.writeVarBytes(this.key.toExtended());
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -175,8 +175,8 @@ Path.fromRaw = function fromRaw(data) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
Path.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
Path.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
|
||||
bw.writeU32(this.account);
|
||||
bw.writeU8(this.keyType);
|
||||
@ -206,10 +206,7 @@ Path.prototype.toRaw = function toRaw(writer) {
|
||||
bw.write8(this.version);
|
||||
bw.writeU8(this.type);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -77,18 +77,15 @@ ChainState.fromRaw = function fromRaw(data) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
ChainState.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
ChainState.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
|
||||
bw.writeU32(this.startHeight);
|
||||
bw.writeHash(this.startHash);
|
||||
bw.writeU32(this.height);
|
||||
bw.writeU8(this.marked ? 1 : 0);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -202,17 +199,12 @@ BlockMeta.fromRaw = function fromRaw(data) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
BlockMeta.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
|
||||
BlockMeta.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
bw.writeHash(this.hash);
|
||||
bw.writeU32(this.height);
|
||||
bw.writeU32(this.ts);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -258,7 +250,7 @@ BlockMapRecord.prototype.fromRaw = function fromRaw(data) {
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
hash = br.readHash('hex');
|
||||
tx = TXMapRecord.fromRaw(hash, br);
|
||||
tx = TXMapRecord.fromReader(hash, br);
|
||||
this.txs.push(tx);
|
||||
this.index[tx.hash] = tx;
|
||||
}
|
||||
@ -283,8 +275,8 @@ BlockMapRecord.fromRaw = function fromRaw(height, data) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
BlockMapRecord.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
BlockMapRecord.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
var i, tx;
|
||||
|
||||
bw.writeU32(this.txs.length);
|
||||
@ -292,13 +284,10 @@ BlockMapRecord.prototype.toRaw = function toRaw(writer) {
|
||||
for (i = 0; i < this.txs.length; i++) {
|
||||
tx = this.txs[i];
|
||||
bw.writeHash(tx.hash);
|
||||
tx.toRaw(bw);
|
||||
tx.toWriter(bw);
|
||||
}
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -369,13 +358,25 @@ TXMapRecord.prototype.remove = function remove(wid) {
|
||||
return util.binaryRemove(this.wids, wid, cmp);
|
||||
};
|
||||
|
||||
TXMapRecord.prototype.toRaw = function toRaw(writer) {
|
||||
return serializeWallets(this.wids, writer);
|
||||
TXMapRecord.prototype.toWriter = function toWriter(bw) {
|
||||
return serializeWallets(bw, this.wids);
|
||||
};
|
||||
|
||||
TXMapRecord.prototype.toRaw = function toRaw() {
|
||||
return this.toWriter(new BufferWriter()).render();
|
||||
};
|
||||
|
||||
TXMapRecord.prototype.fromReader = function fromReader(br) {
|
||||
this.wids = parseWallets(br);
|
||||
return this;
|
||||
};
|
||||
|
||||
TXMapRecord.prototype.fromRaw = function fromRaw(data) {
|
||||
this.wids = parseWallets(data);
|
||||
return this;
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
TXMapRecord.fromReader = function fromReader(hash, br) {
|
||||
return new TXMapRecord(hash).fromReader(br);
|
||||
};
|
||||
|
||||
TXMapRecord.fromRaw = function fromRaw(hash, data) {
|
||||
@ -401,13 +402,25 @@ OutpointMapRecord.prototype.remove = function remove(wid) {
|
||||
return util.binaryRemove(this.wids, wid, cmp);
|
||||
};
|
||||
|
||||
OutpointMapRecord.prototype.toRaw = function toRaw(writer) {
|
||||
return serializeWallets(this.wids, writer);
|
||||
OutpointMapRecord.prototype.toWriter = function toWriter(bw) {
|
||||
return serializeWallets(bw, this.wids);
|
||||
};
|
||||
|
||||
OutpointMapRecord.prototype.toRaw = function toRaw() {
|
||||
return this.toWriter(new BufferWriter()).render();
|
||||
};
|
||||
|
||||
OutpointMapRecord.prototype.fromReader = function fromReader(br) {
|
||||
this.wids = parseWallets(br);
|
||||
return this;
|
||||
};
|
||||
|
||||
OutpointMapRecord.prototype.fromRaw = function fromRaw(data) {
|
||||
this.wids = parseWallets(data);
|
||||
return this;
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
OutpointMapRecord.fromReader = function fromReader(hash, index, br) {
|
||||
return new OutpointMapRecord(hash, index).fromReader(br);
|
||||
};
|
||||
|
||||
OutpointMapRecord.fromRaw = function fromRaw(hash, index, data) {
|
||||
@ -432,13 +445,25 @@ PathMapRecord.prototype.remove = function remove(wid) {
|
||||
return util.binaryRemove(this.wids, wid, cmp);
|
||||
};
|
||||
|
||||
PathMapRecord.prototype.toRaw = function toRaw(writer) {
|
||||
return serializeWallets(this.wids, writer);
|
||||
PathMapRecord.prototype.toWriter = function toWriter(bw) {
|
||||
return serializeWallets(bw, this.wids);
|
||||
};
|
||||
|
||||
PathMapRecord.prototype.toRaw = function toRaw() {
|
||||
return this.toWriter(new BufferWriter()).render();
|
||||
};
|
||||
|
||||
PathMapRecord.prototype.fromReader = function fromReader(br) {
|
||||
this.wids = parseWallets(br);
|
||||
return this;
|
||||
};
|
||||
|
||||
PathMapRecord.prototype.fromRaw = function fromRaw(data) {
|
||||
this.wids = parseWallets(data);
|
||||
return this;
|
||||
return this.fromReader(new BufferReader(data));
|
||||
};
|
||||
|
||||
PathMapRecord.fromReader = function fromReader(hash, br) {
|
||||
return new PathMapRecord(hash).fromReader(br);
|
||||
};
|
||||
|
||||
PathMapRecord.fromRaw = function fromRaw(hash, data) {
|
||||
@ -457,8 +482,7 @@ function cmpid(a, b) {
|
||||
return a.id - b.id;
|
||||
}
|
||||
|
||||
function parseWallets(data) {
|
||||
var br = new BufferReader(data);
|
||||
function parseWallets(br) {
|
||||
var count = br.readU32();
|
||||
var wids = [];
|
||||
var i;
|
||||
@ -469,8 +493,7 @@ function parseWallets(data) {
|
||||
return wids;
|
||||
}
|
||||
|
||||
function serializeWallets(wids, writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
function serializeWallets(bw, wids) {
|
||||
var i, wid;
|
||||
|
||||
bw.writeU32(wids.length);
|
||||
@ -480,9 +503,6 @@ function serializeWallets(wids, writer) {
|
||||
bw.writeU32(wid);
|
||||
}
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
}
|
||||
|
||||
|
||||
@ -2895,18 +2895,15 @@ TXDBState.prototype.toBalance = function toBalance() {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
TXDBState.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
TXDBState.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
|
||||
bw.writeU64(this.tx);
|
||||
bw.writeU64(this.coin);
|
||||
bw.writeU64(this.unconfirmed);
|
||||
bw.writeU64(this.confirmed);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2985,8 +2982,8 @@ function Credit(coin, spent) {
|
||||
*/
|
||||
|
||||
Credit.prototype.fromRaw = function fromRaw(data) {
|
||||
var br = BufferReader(data);
|
||||
this.coin.fromRaw(br);
|
||||
var br = new BufferReader(data);
|
||||
this.coin.fromReader(br);
|
||||
this.spent = br.readU8() === 1;
|
||||
return this;
|
||||
};
|
||||
@ -3006,16 +3003,11 @@ Credit.fromRaw = function fromRaw(data) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
Credit.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = BufferWriter(writer);
|
||||
|
||||
this.coin.toRaw(bw);
|
||||
Credit.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
this.coin.toWriter(bw);
|
||||
bw.writeU8(this.spent ? 1 : 0);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -3377,8 +3369,8 @@ BlockRecord.fromRaw = function fromRaw(data) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
BlockRecord.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
BlockRecord.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
var i;
|
||||
|
||||
bw.writeHash(this.hash);
|
||||
@ -3390,10 +3382,7 @@ BlockRecord.prototype.toRaw = function toRaw(writer) {
|
||||
for (i = 0; i < this.hashes.length; i++)
|
||||
bw.writeHash(this.hashes[i]);
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -2440,8 +2440,8 @@ Wallet.prototype.toJSON = function toJSON(unsafe) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
Wallet.prototype.toRaw = function toRaw(writer) {
|
||||
var bw = new BufferWriter(writer);
|
||||
Wallet.prototype.toRaw = function toRaw() {
|
||||
var bw = new BufferWriter();
|
||||
|
||||
bw.writeU32(this.network.magic);
|
||||
bw.writeU32(this.wid);
|
||||
@ -2453,10 +2453,7 @@ Wallet.prototype.toRaw = function toRaw(writer) {
|
||||
bw.writeU32(this.tokenDepth);
|
||||
bw.writeVarBytes(this.master.toRaw());
|
||||
|
||||
if (!writer)
|
||||
bw = bw.render();
|
||||
|
||||
return bw;
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -33,7 +33,7 @@ Framer.prototype.packet = function _packet(packet) {
|
||||
bw.writeU8(packet.cmd);
|
||||
bw.seek(4);
|
||||
|
||||
packet.toRaw(bw);
|
||||
packet.toWriter(bw);
|
||||
|
||||
bw.writeU8(0x0a);
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@ Packet.id = 0;
|
||||
|
||||
Packet.prototype.cmd = -1;
|
||||
|
||||
Packet.prototype.toRaw = function toRaw() {
|
||||
Packet.prototype.toWriter = function toWriter() {
|
||||
throw new Error('Abstract method.');
|
||||
};
|
||||
|
||||
@ -71,7 +71,7 @@ util.inherits(EventPacket, Packet);
|
||||
|
||||
EventPacket.prototype.cmd = packetTypes.EVENT;
|
||||
|
||||
EventPacket.prototype.toRaw = function toRaw(bw) {
|
||||
EventPacket.prototype.toWriter = function toWriter(bw) {
|
||||
bw.writeVarString(JSON.stringify(this.items), 'utf8');
|
||||
};
|
||||
|
||||
@ -96,7 +96,7 @@ util.inherits(LogPacket, Packet);
|
||||
|
||||
LogPacket.prototype.cmd = packetTypes.LOG;
|
||||
|
||||
LogPacket.prototype.toRaw = function toRaw(bw) {
|
||||
LogPacket.prototype.toWriter = function toWriter(bw) {
|
||||
bw.writeVarString(this.text, 'utf8');
|
||||
};
|
||||
|
||||
@ -121,7 +121,7 @@ util.inherits(ErrorPacket, Packet);
|
||||
|
||||
ErrorPacket.prototype.cmd = packetTypes.ERROR;
|
||||
|
||||
ErrorPacket.prototype.toRaw = function toRaw(bw) {
|
||||
ErrorPacket.prototype.toWriter = function toWriter(bw) {
|
||||
bw.writeVarString(this.error.message + '', 'utf8');
|
||||
bw.writeVarString(this.error.stack + '', 'utf8');
|
||||
bw.writeVarString((this.error.type || ''), 'utf8');
|
||||
@ -150,7 +150,7 @@ util.inherits(ErrorResultPacket, Packet);
|
||||
|
||||
ErrorResultPacket.prototype.cmd = packetTypes.ERRORRESULT;
|
||||
|
||||
ErrorResultPacket.prototype.toRaw = function toRaw(bw) {
|
||||
ErrorResultPacket.prototype.toWriter = function toWriter(bw) {
|
||||
bw.writeVarString(this.error.message + '', 'utf8');
|
||||
bw.writeVarString(this.error.stack + '', 'utf8');
|
||||
bw.writeVarString((this.error.type || ''), 'utf8');
|
||||
@ -180,16 +180,22 @@ util.inherits(VerifyPacket, Packet);
|
||||
|
||||
VerifyPacket.prototype.cmd = packetTypes.VERIFY;
|
||||
|
||||
VerifyPacket.prototype.toRaw = function(bw) {
|
||||
VerifyPacket.prototype.toWriter = function(bw) {
|
||||
frameTX(this.tx, bw);
|
||||
bw.writeU32(this.flags);
|
||||
bw.write32(this.flags != null ? this.flags : -1);
|
||||
};
|
||||
|
||||
VerifyPacket.fromRaw = function fromRaw(TX, data) {
|
||||
var br = new BufferReader(data, true);
|
||||
var packet = new VerifyPacket();
|
||||
|
||||
packet.tx = parseTX(TX, br);
|
||||
packet.flags = br.readU32();
|
||||
|
||||
packet.flags = br.read32();
|
||||
|
||||
if (packet.flags === -1)
|
||||
packet.flags = null;
|
||||
|
||||
return packet;
|
||||
};
|
||||
|
||||
@ -207,7 +213,7 @@ util.inherits(VerifyResultPacket, Packet);
|
||||
|
||||
VerifyResultPacket.prototype.cmd = packetTypes.VERIFYRESULT;
|
||||
|
||||
VerifyResultPacket.prototype.toRaw = function toRaw(bw) {
|
||||
VerifyResultPacket.prototype.toWriter = function toWriter(bw) {
|
||||
bw.writeU8(this.value ? 1 : 0);
|
||||
};
|
||||
|
||||
@ -234,16 +240,16 @@ util.inherits(SignPacket, Packet);
|
||||
|
||||
SignPacket.prototype.cmd = packetTypes.SIGN;
|
||||
|
||||
SignPacket.prototype.toRaw = function toRaw(bw) {
|
||||
SignPacket.prototype.toWriter = function toWriter(bw) {
|
||||
var i, ring;
|
||||
|
||||
frameTX(this.tx, bw);
|
||||
|
||||
bw.writeU32(this.rings.length);
|
||||
bw.writeVarint(this.rings.length);
|
||||
|
||||
for (i = 0; i < this.rings.length; i++) {
|
||||
ring = this.rings[i];
|
||||
bw.writeBytes(ring.toRaw());
|
||||
ring.toWriter(bw);
|
||||
}
|
||||
|
||||
bw.write8(this.type != null ? this.type : -1);
|
||||
@ -256,10 +262,10 @@ SignPacket.fromRaw = function fromRaw(MTX, KeyRing, data) {
|
||||
|
||||
packet.tx = parseTX(MTX, br);
|
||||
|
||||
count = br.readU32();
|
||||
count = br.readVarint();
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
ring = KeyRing.fromRaw(br);
|
||||
ring = KeyRing.fromReader(br);
|
||||
packet.rings.push(ring);
|
||||
}
|
||||
|
||||
@ -300,7 +306,7 @@ SignResultPacket.fromTX = function fromTX(tx, total) {
|
||||
return packet;
|
||||
};
|
||||
|
||||
SignResultPacket.prototype.toRaw = function toRaw(bw) {
|
||||
SignResultPacket.prototype.toWriter = function toWriter(bw) {
|
||||
var i;
|
||||
|
||||
assert(this.script.length === this.witness.length);
|
||||
@ -309,8 +315,8 @@ SignResultPacket.prototype.toRaw = function toRaw(bw) {
|
||||
bw.writeVarint(this.script.length);
|
||||
|
||||
for (i = 0; i < this.script.length; i++) {
|
||||
this.script[i].toRaw(bw);
|
||||
this.witness[i].toRaw(bw);
|
||||
this.script[i].toWriter(bw);
|
||||
this.witness[i].toWriter(bw);
|
||||
}
|
||||
};
|
||||
|
||||
@ -337,8 +343,8 @@ SignResultPacket.fromRaw = function fromRaw(data) {
|
||||
count = br.readVarint();
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
packet.script.push(Script.fromRaw(br));
|
||||
packet.witness.push(Witness.fromRaw(br));
|
||||
packet.script.push(Script.fromReader(br));
|
||||
packet.witness.push(Witness.fromReader(br));
|
||||
}
|
||||
|
||||
return packet;
|
||||
@ -360,9 +366,9 @@ util.inherits(VerifyInputPacket, Packet);
|
||||
|
||||
VerifyInputPacket.prototype.cmd = packetTypes.VERIFYINPUT;
|
||||
|
||||
VerifyInputPacket.prototype.toRaw = function toRaw(bw) {
|
||||
VerifyInputPacket.prototype.toWriter = function toWriter(bw) {
|
||||
frameTX(this.tx, bw);
|
||||
bw.writeU32(this.index);
|
||||
bw.writeVarint(this.index);
|
||||
bw.write32(this.flags != null ? this.flags : -1);
|
||||
};
|
||||
|
||||
@ -371,7 +377,7 @@ VerifyInputPacket.fromRaw = function fromRaw(TX, data) {
|
||||
var packet = new VerifyInputPacket();
|
||||
|
||||
packet.tx = parseTX(TX, br);
|
||||
packet.index = br.readU32();
|
||||
packet.index = br.readVarint();
|
||||
packet.flags = br.read32();
|
||||
|
||||
if (packet.flags === -1)
|
||||
@ -394,7 +400,7 @@ util.inherits(VerifyInputResultPacket, Packet);
|
||||
|
||||
VerifyInputResultPacket.prototype.cmd = packetTypes.VERIFYINPUTRESULT;
|
||||
|
||||
VerifyInputResultPacket.prototype.toRaw = function toRaw(bw) {
|
||||
VerifyInputResultPacket.prototype.toWriter = function toWriter(bw) {
|
||||
bw.writeU8(this.value ? 1 : 0);
|
||||
};
|
||||
|
||||
@ -410,11 +416,11 @@ VerifyInputResultPacket.fromRaw = function fromRaw(data) {
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
function SignInputPacket(tx, index, rings, type) {
|
||||
function SignInputPacket(tx, index, ring, type) {
|
||||
Packet.call(this);
|
||||
this.tx = tx || null;
|
||||
this.index = index;
|
||||
this.rings = rings || [];
|
||||
this.ring = ring || null;
|
||||
this.type = type != null ? type : null;
|
||||
}
|
||||
|
||||
@ -422,18 +428,19 @@ util.inherits(SignInputPacket, Packet);
|
||||
|
||||
SignInputPacket.prototype.cmd = packetTypes.SIGNINPUT;
|
||||
|
||||
SignInputPacket.prototype.toRaw = function toRaw(bw) {
|
||||
var i, ring;
|
||||
SignInputPacket.prototype.toWriter = function toWriter(bw) {
|
||||
var input = this.tx.inputs[this.index];
|
||||
|
||||
frameTX(this.tx, bw);
|
||||
bw.writeU32(this.index);
|
||||
assert(input);
|
||||
assert(input.coin);
|
||||
|
||||
bw.writeU32(this.rings.length);
|
||||
this.tx.toWriter(bw);
|
||||
bw.writeVarint(this.index);
|
||||
|
||||
for (i = 0; i < this.rings.length; i++) {
|
||||
ring = this.rings[i];
|
||||
bw.writeBytes(ring.toRaw());
|
||||
}
|
||||
bw.writeVarint(input.coin.value);
|
||||
input.coin.script.toWriter(bw);
|
||||
|
||||
this.ring.toWriter(bw);
|
||||
|
||||
bw.write8(this.type != null ? this.type : -1);
|
||||
};
|
||||
@ -441,27 +448,33 @@ SignInputPacket.prototype.toRaw = function toRaw(bw) {
|
||||
SignInputPacket.fromRaw = function fromRaw(MTX, KeyRing, data) {
|
||||
var br = new BufferReader(data, true);
|
||||
var packet = new SignInputPacket();
|
||||
var i, count, ring;
|
||||
var coin = new Coin();
|
||||
var input;
|
||||
|
||||
packet.tx = parseTX(MTX, br);
|
||||
packet.index = br.readU32();
|
||||
packet.index = br.readVarint();
|
||||
|
||||
count = br.readU32();
|
||||
coin.value = br.readVarint();
|
||||
coin.script.fromReader(br);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
ring = KeyRing.fromRaw(br);
|
||||
packet.rings.push(ring);
|
||||
}
|
||||
packet.ring = KeyRing.fromReader(br);
|
||||
|
||||
packet.type = br.read8();
|
||||
|
||||
if (packet.type === -1)
|
||||
packet.type = null;
|
||||
|
||||
input = packet.tx.inputs[packet.index];
|
||||
assert(input);
|
||||
|
||||
coin.hash = input.prevout.hash;
|
||||
coin.index = input.prevout.index;
|
||||
|
||||
input.coin = coin;
|
||||
|
||||
return packet;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* SignInputResultPacket
|
||||
* @constructor
|
||||
@ -490,10 +503,10 @@ SignInputResultPacket.fromTX = function fromTX(tx, i, value) {
|
||||
return packet;
|
||||
};
|
||||
|
||||
SignInputResultPacket.prototype.toRaw = function toRaw(bw) {
|
||||
SignInputResultPacket.prototype.toWriter = function toWriter(bw) {
|
||||
bw.writeU8(this.value ? 1 : 0);
|
||||
this.script.toRaw(bw);
|
||||
this.witness.toRaw(bw);
|
||||
this.script.toWriter(bw);
|
||||
this.witness.toWriter(bw);
|
||||
};
|
||||
|
||||
SignInputResultPacket.prototype.inject = function inject(tx, i) {
|
||||
@ -507,8 +520,8 @@ SignInputResultPacket.fromRaw = function fromRaw(data) {
|
||||
var br = new BufferReader(data, true);
|
||||
var packet = new SignInputResultPacket();
|
||||
packet.value = br.readU8() === 1;
|
||||
packet.script = Script.fromRaw(br);
|
||||
packet.witness = Witness.fromRaw(br);
|
||||
packet.script = Script.fromReader(br);
|
||||
packet.witness = Witness.fromReader(br);
|
||||
return packet;
|
||||
};
|
||||
|
||||
@ -529,7 +542,7 @@ util.inherits(ECVerifyPacket, Packet);
|
||||
|
||||
ECVerifyPacket.prototype.cmd = packetTypes.ECVERIFY;
|
||||
|
||||
ECVerifyPacket.prototype.toRaw = function(bw) {
|
||||
ECVerifyPacket.prototype.toWriter = function(bw) {
|
||||
bw.writeVarBytes(this.msg);
|
||||
bw.writeVarBytes(this.sig);
|
||||
bw.writeVarBytes(this.key);
|
||||
@ -558,7 +571,7 @@ util.inherits(ECVerifyResultPacket, Packet);
|
||||
|
||||
ECVerifyResultPacket.prototype.cmd = packetTypes.ECVERIFYRESULT;
|
||||
|
||||
ECVerifyResultPacket.prototype.toRaw = function toRaw(bw) {
|
||||
ECVerifyResultPacket.prototype.toWriter = function toWriter(bw) {
|
||||
bw.writeU8(this.value ? 1 : 0);
|
||||
};
|
||||
|
||||
@ -584,7 +597,7 @@ util.inherits(ECSignPacket, Packet);
|
||||
|
||||
ECSignPacket.prototype.cmd = packetTypes.ECSIGN;
|
||||
|
||||
ECSignPacket.prototype.toRaw = function(bw) {
|
||||
ECSignPacket.prototype.toWriter = function(bw) {
|
||||
bw.writeVarBytes(this.msg);
|
||||
bw.writeVarBytes(this.key);
|
||||
};
|
||||
@ -611,7 +624,7 @@ util.inherits(ECSignResultPacket, Packet);
|
||||
|
||||
ECSignResultPacket.prototype.cmd = packetTypes.ECSIGNRESULT;
|
||||
|
||||
ECSignResultPacket.prototype.toRaw = function toRaw(bw) {
|
||||
ECSignResultPacket.prototype.toWriter = function toWriter(bw) {
|
||||
bw.writeVarBytes(this.sig);
|
||||
};
|
||||
|
||||
@ -639,7 +652,7 @@ util.inherits(MinePacket, Packet);
|
||||
|
||||
MinePacket.prototype.cmd = packetTypes.MINE;
|
||||
|
||||
MinePacket.prototype.toRaw = function(bw) {
|
||||
MinePacket.prototype.toWriter = function(bw) {
|
||||
bw.writeBytes(this.data);
|
||||
bw.writeBytes(this.target);
|
||||
bw.writeU32(this.min);
|
||||
@ -670,7 +683,7 @@ util.inherits(MineResultPacket, Packet);
|
||||
|
||||
MineResultPacket.prototype.cmd = packetTypes.MINERESULT;
|
||||
|
||||
MineResultPacket.prototype.toRaw = function toRaw(bw) {
|
||||
MineResultPacket.prototype.toWriter = function toWriter(bw) {
|
||||
bw.writeU32(this.nonce);
|
||||
};
|
||||
|
||||
@ -702,7 +715,7 @@ util.inherits(ScryptPacket, Packet);
|
||||
|
||||
ScryptPacket.prototype.cmd = packetTypes.SCRYPT;
|
||||
|
||||
ScryptPacket.prototype.toRaw = function(bw) {
|
||||
ScryptPacket.prototype.toWriter = function(bw) {
|
||||
bw.writeVarBytes(this.passwd);
|
||||
bw.writeVarBytes(this.salt);
|
||||
bw.writeU32(this.N);
|
||||
@ -737,7 +750,7 @@ util.inherits(ScryptResultPacket, Packet);
|
||||
|
||||
ScryptResultPacket.prototype.cmd = packetTypes.SCRYPTRESULT;
|
||||
|
||||
ScryptResultPacket.prototype.toRaw = function toRaw(bw) {
|
||||
ScryptResultPacket.prototype.toWriter = function toWriter(bw) {
|
||||
bw.writeVarBytes(this.key);
|
||||
};
|
||||
|
||||
@ -755,7 +768,7 @@ ScryptResultPacket.fromRaw = function fromRaw(data) {
|
||||
function frameTX(tx, bw) {
|
||||
var i, input;
|
||||
|
||||
tx.toRaw(bw);
|
||||
tx.toWriter(bw);
|
||||
|
||||
for (i = 0; i < tx.inputs.length; i++) {
|
||||
input = tx.inputs[i];
|
||||
@ -767,12 +780,12 @@ function frameTX(tx, bw) {
|
||||
|
||||
bw.writeU8(1);
|
||||
bw.writeVarint(input.coin.value);
|
||||
input.coin.script.toRaw(bw);
|
||||
input.coin.script.toWriter(bw);
|
||||
}
|
||||
}
|
||||
|
||||
function parseTX(TX, br) {
|
||||
var tx = TX.fromRaw(br);
|
||||
var tx = TX.fromReader(br);
|
||||
var i, input, prevout, coin;
|
||||
|
||||
for (i = 0; i < tx.inputs.length; i++) {
|
||||
@ -784,7 +797,7 @@ function parseTX(TX, br) {
|
||||
|
||||
coin = new Coin();
|
||||
coin.value = br.readVarint();
|
||||
coin.script.fromRaw(br);
|
||||
coin.script.fromReader(br);
|
||||
|
||||
coin.hash = prevout.hash;
|
||||
coin.index = prevout.index;
|
||||
|
||||
@ -317,17 +317,9 @@ WorkerPool.prototype.verifyInput = co(function* verifyInput(tx, index, flags) {
|
||||
*/
|
||||
|
||||
WorkerPool.prototype.signInput = co(function* signInput(tx, index, ring, type) {
|
||||
var rings = ring;
|
||||
var packet, result;
|
||||
|
||||
if (!Array.isArray(rings))
|
||||
rings = [rings];
|
||||
|
||||
packet = new packets.SignInputPacket(tx, index, rings, type);
|
||||
result = yield this.execute(packet, -1);
|
||||
|
||||
var packet = new packets.SignInputPacket(tx, index, ring, type);
|
||||
var result = yield this.execute(packet, -1);
|
||||
result.inject(tx);
|
||||
|
||||
return result.value;
|
||||
});
|
||||
|
||||
|
||||
@ -188,7 +188,7 @@ var reserializeUndo = co(function* reserializeUndo() {
|
||||
|
||||
while (br.left()) {
|
||||
undo.push(null);
|
||||
injectCoin(undo.top(), Coin.fromRaw(br));
|
||||
injectCoin(undo.top(), Coin.fromReader(br));
|
||||
}
|
||||
|
||||
batch.write(item.key, undo.toRaw());
|
||||
|
||||
@ -139,8 +139,8 @@ function parseWallets(data) {
|
||||
return wids;
|
||||
}
|
||||
|
||||
function serializeWallets(wids, writer) {
|
||||
var p = new BufferWriter(writer);
|
||||
function serializeWallets(wids) {
|
||||
var p = new BufferWriter();
|
||||
var i, wid;
|
||||
|
||||
p.writeU32(wids.length);
|
||||
@ -150,10 +150,7 @@ function serializeWallets(wids, writer) {
|
||||
p.writeU32(wid);
|
||||
}
|
||||
|
||||
if (!writer)
|
||||
p = p.render();
|
||||
|
||||
return p;
|
||||
return p.render();
|
||||
}
|
||||
|
||||
function accountToRaw(account) {
|
||||
|
||||
@ -207,10 +207,9 @@ describe('Protocol', function() {
|
||||
});
|
||||
|
||||
it('should parse, reserialize, and verify alert packets', function() {
|
||||
var p = new bcoin.reader(alertData);
|
||||
p.start();
|
||||
while (p.left()) {
|
||||
var alert = packets.AlertPacket.fromRaw(p);
|
||||
var br = new bcoin.reader(alertData);
|
||||
while (br.left()) {
|
||||
var alert = packets.AlertPacket.fromReader(br);
|
||||
assert(alert.verify(network.alertKey));
|
||||
alert._payload = null;
|
||||
alert._hash = null;
|
||||
@ -218,6 +217,5 @@ describe('Protocol', function() {
|
||||
alert = packets.AlertPacket.fromRaw(data);
|
||||
assert(alert.verify(network.alertKey));
|
||||
}
|
||||
p.end();
|
||||
});
|
||||
});
|
||||
|
||||
@ -19,22 +19,22 @@ describe('Script', function() {
|
||||
+ '101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f'
|
||||
+ 'ac';
|
||||
|
||||
var decoded = bcoin.script.decode(new Buffer(src, 'hex'));
|
||||
assert.equal(decoded.length, 3);
|
||||
assert.equal(decoded[0].data.toString('hex'),
|
||||
var decoded = bcoin.script(new Buffer(src, 'hex'));
|
||||
assert.equal(decoded.code.length, 3);
|
||||
assert.equal(decoded.code[0].data.toString('hex'),
|
||||
'000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f');
|
||||
assert.equal(decoded[1].data.toString('hex'),
|
||||
assert.equal(decoded.code[1].data.toString('hex'),
|
||||
'101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f');
|
||||
assert.equal(decoded[2].value, opcodes.OP_CHECKSIG);
|
||||
assert.equal(decoded.code[2].value, opcodes.OP_CHECKSIG);
|
||||
|
||||
var dst = bcoin.script.encode(decoded);
|
||||
var dst = decoded.toRaw();
|
||||
assert.equal(dst.toString('hex'), src);
|
||||
});
|
||||
|
||||
it('should encode/decode numbers', function() {
|
||||
var script = [0, 0x51, 0x52, 0x60];
|
||||
var encoded = bcoin.script.fromArray(script).raw;
|
||||
var decoded = bcoin.script.decode(encoded).map(function(op) { return op.value; });
|
||||
var decoded = bcoin.script(encoded).toArray();
|
||||
assert.deepEqual(decoded, script);
|
||||
});
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user