deferred.

This commit is contained in:
Christopher Jeffrey 2016-06-12 05:23:28 -07:00
parent 95b62b4b65
commit 0abf791bb7
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -115,48 +115,6 @@ Coins.prototype.spend = function spend(index) {
return coin;
};
/**
* Fill transaction(s) with coins.
* @param {TX} tx
* @param {Boolean?} spend - Whether the coins should
* be spent when filling.
* @returns {Boolean} True if all inputs were filled.
*/
Coins.prototype.fill = function fill(tx) {
var res = true;
var i, input, prevout;
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
prevout = input.prevout;
if (prevout.hash !== this.hash)
continue;
input.coin = this.spend(prevout.index);
if (!input.coin)
res = false;
}
return res;
};
/**
* Convert collection to an array.
* @returns {Coin[]}
*/
Coins.prototype.toArray = function toArray() {
var out = [];
var i;
for (i = 0; i < this.outputs.length; i++) {
if (this.outputs[i])
out.push(this.outputs[i]);
}
return out;
};
/**
* Serialize the coins object.
* @param {TX|Coins} tx
@ -187,7 +145,7 @@ Coins.prototype.toRaw = function toRaw(writer) {
}
if (output instanceof DeferredCoin) {
p.writeBytes(output.raw);
p.writeBytes(output.toRaw());
continue;
}
@ -228,7 +186,7 @@ Coins.prototype.toRaw = function toRaw(writer) {
Coins.parseRaw = function parseRaw(data, hash, index) {
var p = new BufferReader(data);
var i = 0;
var version, height, coins, mask, prefix, raw;
var version, height, coins, mask, prefix, offset, size;
version = p.readVarint();
height = p.readU32();
@ -245,8 +203,7 @@ Coins.parseRaw = function parseRaw(data, hash, index) {
coins.height = -1;
while (p.left()) {
p.start();
offset = p.start();
mask = p.readU8();
if (mask === 0xff) {
@ -272,15 +229,14 @@ Coins.parseRaw = function parseRaw(data, hash, index) {
p.readVarint();
size = p.end();
if (index != null && i !== index) {
p.end();
i++;
continue;
}
raw = p.endData(true);
coins.outputs.push(new DeferredCoin(raw));
coins.outputs.push(new DeferredCoin(offset, size, data));
if (index != null)
return coins.outputs[0].toCoin(coins, i);
@ -288,44 +244,11 @@ Coins.parseRaw = function parseRaw(data, hash, index) {
i++;
}
assert(index == null, 'Bad index.');
return coins;
};
function DeferredCoin(raw) {
this.raw = raw;
}
DeferredCoin.prototype.toCoin = function toCoin(coins, index) {
var p = new BufferReader(this.raw);
var prefix = p.readU8() & 3;
var script, value;
if (prefix === 0)
script = new bcoin.script(bcoin.protocol.parser.parseScript(p));
else if (prefix === 1)
script = bcoin.script.createPubkeyhash(p.readBytes(20));
else if (prefix === 2)
script = bcoin.script.createScripthash(p.readBytes(20));
else
assert(false, 'Bad prefix.');
value = p.readVarint();
return new bcoin.coin({
version: coins.version,
coinbase: coins.coinbase,
height: coins.height,
hash: coins.hash,
index: index,
script: script,
value: value
});
};
DeferredCoin.prototype.toRaw = function toRaw() {
return this.raw;
};
/**
* Parse a single serialized coin.
* @param {Buffer} data
@ -335,6 +258,7 @@ DeferredCoin.prototype.toRaw = function toRaw() {
*/
Coins.parseCoin = function parseCoin(data, hash, index) {
assert(index != null, 'Bad index.');
return Coins.parseCoins(data, hash, index);
};
@ -376,6 +300,66 @@ Coins.fromTX = function fromTX(tx) {
});
};
/**
* A "deferred" coin is an object which defers
* parsing of a compressed coin. Say there is
* a transaction with 100 outputs. When block
* comes in, there may only be _one_ input in
* that entire block which redeems an output
* from that transaction. When parsing the
* Coins, there is no sense to get _all_ of
* them into their abstract form. A "deferred"
* coin is just a pointer to that coin in the
* Coins buffer, as well as a size. Parsing
* is done only if that coin is being redeemed.
* @exposes DeferredCoin
* @constructor
* @private
* @param {Number} offset
* @param {Number} size
* @param {Buffer} raw
*/
function DeferredCoin(offset, size, raw) {
this.offset = offset;
this.size = size;
this.raw = raw;
}
DeferredCoin.prototype.toCoin = function toCoin(coins, index) {
var p = new BufferReader(this.raw);
var prefix, script, value;
p.seek(this.offset);
prefix = p.readU8() & 3;
if (prefix === 0)
script = new bcoin.script(bcoin.protocol.parser.parseScript(p));
else if (prefix === 1)
script = bcoin.script.createPubkeyhash(p.readBytes(20));
else if (prefix === 2)
script = bcoin.script.createScripthash(p.readBytes(20));
else
assert(false, 'Bad prefix.');
value = p.readVarint();
return new bcoin.coin({
version: coins.version,
coinbase: coins.coinbase,
height: coins.height,
hash: coins.hash,
index: index,
script: script,
value: value
});
};
DeferredCoin.prototype.toRaw = function toRaw() {
return this.raw.slice(this.offset, this.offset + this.size);
};
/*
* Helpers
*/