deferred.
This commit is contained in:
parent
95b62b4b65
commit
0abf791bb7
@ -115,48 +115,6 @@ Coins.prototype.spend = function spend(index) {
|
|||||||
return coin;
|
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.
|
* Serialize the coins object.
|
||||||
* @param {TX|Coins} tx
|
* @param {TX|Coins} tx
|
||||||
@ -187,7 +145,7 @@ Coins.prototype.toRaw = function toRaw(writer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (output instanceof DeferredCoin) {
|
if (output instanceof DeferredCoin) {
|
||||||
p.writeBytes(output.raw);
|
p.writeBytes(output.toRaw());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +186,7 @@ Coins.prototype.toRaw = function toRaw(writer) {
|
|||||||
Coins.parseRaw = function parseRaw(data, hash, index) {
|
Coins.parseRaw = function parseRaw(data, hash, index) {
|
||||||
var p = new BufferReader(data);
|
var p = new BufferReader(data);
|
||||||
var i = 0;
|
var i = 0;
|
||||||
var version, height, coins, mask, prefix, raw;
|
var version, height, coins, mask, prefix, offset, size;
|
||||||
|
|
||||||
version = p.readVarint();
|
version = p.readVarint();
|
||||||
height = p.readU32();
|
height = p.readU32();
|
||||||
@ -245,8 +203,7 @@ Coins.parseRaw = function parseRaw(data, hash, index) {
|
|||||||
coins.height = -1;
|
coins.height = -1;
|
||||||
|
|
||||||
while (p.left()) {
|
while (p.left()) {
|
||||||
p.start();
|
offset = p.start();
|
||||||
|
|
||||||
mask = p.readU8();
|
mask = p.readU8();
|
||||||
|
|
||||||
if (mask === 0xff) {
|
if (mask === 0xff) {
|
||||||
@ -272,15 +229,14 @@ Coins.parseRaw = function parseRaw(data, hash, index) {
|
|||||||
|
|
||||||
p.readVarint();
|
p.readVarint();
|
||||||
|
|
||||||
|
size = p.end();
|
||||||
|
|
||||||
if (index != null && i !== index) {
|
if (index != null && i !== index) {
|
||||||
p.end();
|
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
raw = p.endData(true);
|
coins.outputs.push(new DeferredCoin(offset, size, data));
|
||||||
|
|
||||||
coins.outputs.push(new DeferredCoin(raw));
|
|
||||||
|
|
||||||
if (index != null)
|
if (index != null)
|
||||||
return coins.outputs[0].toCoin(coins, i);
|
return coins.outputs[0].toCoin(coins, i);
|
||||||
@ -288,44 +244,11 @@ Coins.parseRaw = function parseRaw(data, hash, index) {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(index == null, 'Bad index.');
|
||||||
|
|
||||||
return coins;
|
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.
|
* Parse a single serialized coin.
|
||||||
* @param {Buffer} data
|
* @param {Buffer} data
|
||||||
@ -335,6 +258,7 @@ DeferredCoin.prototype.toRaw = function toRaw() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Coins.parseCoin = function parseCoin(data, hash, index) {
|
Coins.parseCoin = function parseCoin(data, hash, index) {
|
||||||
|
assert(index != null, 'Bad index.');
|
||||||
return Coins.parseCoins(data, hash, 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
|
* Helpers
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user