deferred coin.
This commit is contained in:
parent
e9c0dc7037
commit
95b62b4b65
@ -76,7 +76,14 @@ Coins.prototype.has = function has(index) {
|
||||
*/
|
||||
|
||||
Coins.prototype.get = function get(index) {
|
||||
return this.outputs[index];
|
||||
var coin = this.outputs[index];
|
||||
if (!coin)
|
||||
return;
|
||||
|
||||
if (coin instanceof DeferredCoin)
|
||||
coin = coin.toCoin(this, index);
|
||||
|
||||
return coin;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -179,6 +186,11 @@ Coins.prototype.toRaw = function toRaw(writer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (output instanceof DeferredCoin) {
|
||||
p.writeBytes(output.raw);
|
||||
continue;
|
||||
}
|
||||
|
||||
prefix = 0;
|
||||
|
||||
// Saves up to 7 bytes.
|
||||
@ -213,10 +225,10 @@ Coins.prototype.toRaw = function toRaw(writer) {
|
||||
* @returns {Object} A "naked" coins object.
|
||||
*/
|
||||
|
||||
Coins.parseRaw = function parseRaw(data, hash) {
|
||||
Coins.parseRaw = function parseRaw(data, hash, index) {
|
||||
var p = new BufferReader(data);
|
||||
var i = 0;
|
||||
var version, height, coins, coin, mask, prefix;
|
||||
var version, height, coins, mask, prefix, raw;
|
||||
|
||||
version = p.readVarint();
|
||||
height = p.readU32();
|
||||
@ -233,43 +245,87 @@ Coins.parseRaw = function parseRaw(data, hash) {
|
||||
coins.height = -1;
|
||||
|
||||
while (p.left()) {
|
||||
p.start();
|
||||
|
||||
mask = p.readU8();
|
||||
|
||||
if (mask === 0xff) {
|
||||
if (index != null) {
|
||||
if (i === index)
|
||||
return;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
coins.outputs.push(null);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
coin = {
|
||||
version: coins.version,
|
||||
coinbase: coins.coinbase,
|
||||
height: coins.height,
|
||||
hash: coins.hash,
|
||||
index: i++,
|
||||
script: null,
|
||||
value: null
|
||||
};
|
||||
|
||||
prefix = mask & 3;
|
||||
|
||||
if (prefix === 0)
|
||||
coin.script = new bcoin.script(bcoin.protocol.parser.parseScript(p));
|
||||
else if (prefix === 1)
|
||||
coin.script = bcoin.script.createPubkeyhash(p.readBytes(20));
|
||||
else if (prefix === 2)
|
||||
coin.script = bcoin.script.createScripthash(p.readBytes(20));
|
||||
p.seek(p.readVarint());
|
||||
else if (prefix <= 2)
|
||||
p.seek(20);
|
||||
else
|
||||
assert(false, 'Bad prefix.');
|
||||
|
||||
coin.value = p.readVarint();
|
||||
p.readVarint();
|
||||
|
||||
coins.outputs.push(new bcoin.coin(coin));
|
||||
if (index != null && i !== index) {
|
||||
p.end();
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
raw = p.endData(true);
|
||||
|
||||
coins.outputs.push(new DeferredCoin(raw));
|
||||
|
||||
if (index != null)
|
||||
return coins.outputs[0].toCoin(coins, i);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
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
|
||||
@ -279,65 +335,7 @@ Coins.parseRaw = function parseRaw(data, hash) {
|
||||
*/
|
||||
|
||||
Coins.parseCoin = function parseCoin(data, hash, index) {
|
||||
var p = new BufferReader(data);
|
||||
var i = 0;
|
||||
var mask, prefix, version, height, coinbase, script, value;
|
||||
|
||||
version = p.readVarint();
|
||||
height = p.readU32();
|
||||
coinbase = (height & 1) !== 0;
|
||||
height >>>= 1;
|
||||
|
||||
if (height === 0x7fffffff)
|
||||
height = -1;
|
||||
|
||||
while (p.left()) {
|
||||
mask = p.readU8();
|
||||
|
||||
if (mask === 0xff) {
|
||||
if (i === index)
|
||||
break;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
prefix = mask & 3;
|
||||
|
||||
if (i !== index) {
|
||||
if (prefix === 0)
|
||||
p.seek(p.readVarint());
|
||||
else if (prefix <= 2)
|
||||
p.seek(20);
|
||||
else
|
||||
assert(false, 'Bad prefix.');
|
||||
p.readVarint();
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
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: version,
|
||||
coinbase: coinbase,
|
||||
height: height,
|
||||
hash: hash,
|
||||
index: i,
|
||||
script: script,
|
||||
value: value
|
||||
});
|
||||
}
|
||||
|
||||
assert(false, 'No coin.');
|
||||
return Coins.parseCoins(data, hash, index);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -68,6 +68,7 @@ BufferReader.prototype.seek = function seek(off) {
|
||||
|
||||
BufferReader.prototype.start = function start() {
|
||||
this.stack.push(this.offset);
|
||||
return this.offset;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user