deferred coin.

This commit is contained in:
Christopher Jeffrey 2016-06-12 03:23:21 -07:00
parent e9c0dc7037
commit 95b62b4b65
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 78 additions and 79 deletions

View File

@ -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);
};
/**

View File

@ -68,6 +68,7 @@ BufferReader.prototype.seek = function seek(off) {
BufferReader.prototype.start = function start() {
this.stack.push(this.offset);
return this.offset;
};
/**