chain: refactor coins.
This commit is contained in:
parent
2d94935ddd
commit
9bc92abb41
@ -317,8 +317,9 @@ Coins.prototype.toRaw = function toRaw(writer) {
|
|||||||
|
|
||||||
Coins.prototype.fromRaw = function fromRaw(data, hash, index) {
|
Coins.prototype.fromRaw = function fromRaw(data, hash, index) {
|
||||||
var p = new BufferReader(data);
|
var p = new BufferReader(data);
|
||||||
var i = 0;
|
var pos = 0;
|
||||||
var bits, coin, offset, size, fstart, flen, bit, oct, spent;
|
var fstart, flen, bit, oct;
|
||||||
|
var bits, coin, spent;
|
||||||
|
|
||||||
this.version = p.readVarint();
|
this.version = p.readVarint();
|
||||||
|
|
||||||
@ -339,72 +340,25 @@ Coins.prototype.fromRaw = function fromRaw(data, hash, index) {
|
|||||||
|
|
||||||
while (p.left()) {
|
while (p.left()) {
|
||||||
// Read a single bit out of the spent field.
|
// Read a single bit out of the spent field.
|
||||||
bit = i % 8;
|
bit = pos % 8;
|
||||||
oct = (i - bit) / 8;
|
oct = (pos - bit) / 8;
|
||||||
spent = (p.data[fstart + oct] >>> (7 - bit)) & 1;
|
spent = (p.data[fstart + oct] >>> (7 - bit)) & 1;
|
||||||
|
|
||||||
// Already spent.
|
// Already spent.
|
||||||
if (spent) {
|
if (spent) {
|
||||||
// Don't bother pushing outputs on if
|
|
||||||
// we're seeking to a specific index.
|
|
||||||
if (index != null) {
|
|
||||||
if (i === index)
|
|
||||||
return;
|
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.outputs.push(null);
|
this.outputs.push(null);
|
||||||
i++;
|
pos++;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = p.offset;
|
|
||||||
|
|
||||||
// Skip past the compressed scripts.
|
|
||||||
switch (p.readU8()) {
|
|
||||||
case 0:
|
|
||||||
p.seek(p.readVarint());
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
case 2:
|
|
||||||
p.seek(20);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
p.seek(33);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error('Bad prefix.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip past the value.
|
|
||||||
p.readVarint();
|
|
||||||
|
|
||||||
size = p.offset - offset;
|
|
||||||
|
|
||||||
// Keep going if we're seeking
|
|
||||||
// to a specific index.
|
|
||||||
if (index != null && i !== index) {
|
|
||||||
i++;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the offset and size
|
// Store the offset and size
|
||||||
// in the compressed coin object.
|
// in the compressed coin object.
|
||||||
coin = new CompressedCoin(offset, size, data);
|
coin = CompressedCoin.fromRaw(p);
|
||||||
|
|
||||||
// We found our coin.
|
|
||||||
if (index != null)
|
|
||||||
return coin.toCoin(this, i);
|
|
||||||
|
|
||||||
this.outputs.push(coin);
|
this.outputs.push(coin);
|
||||||
i++;
|
pos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We couldn't find our coin.
|
|
||||||
if (index != null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -417,8 +371,56 @@ Coins.prototype.fromRaw = function fromRaw(data, hash, index) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Coins.parseCoin = function parseCoin(data, hash, index) {
|
Coins.parseCoin = function parseCoin(data, hash, index) {
|
||||||
assert(index != null, 'Bad coin index.');
|
var p = new BufferReader(data);
|
||||||
return new Coins().fromRaw(data, hash, index);
|
var coin = new Coin();
|
||||||
|
var pos = 0;
|
||||||
|
var fstart, flen, bit, oct;
|
||||||
|
var spent, bits;
|
||||||
|
|
||||||
|
coin.version = p.readVarint();
|
||||||
|
|
||||||
|
bits = p.readU32();
|
||||||
|
|
||||||
|
coin.hash = hash;
|
||||||
|
coin.index = index;
|
||||||
|
coin.height = bits >>> 1;
|
||||||
|
coin.hash = hash;
|
||||||
|
coin.coinbase = (bits & 1) !== 0;
|
||||||
|
|
||||||
|
if (coin.height === 0x7fffffff)
|
||||||
|
coin.height = -1;
|
||||||
|
|
||||||
|
// Mark the start of the spent field and
|
||||||
|
// seek past it to avoid reading a buffer.
|
||||||
|
flen = p.readVarint();
|
||||||
|
fstart = p.offset;
|
||||||
|
p.seek(flen);
|
||||||
|
|
||||||
|
while (p.left()) {
|
||||||
|
// Read a single bit out of the spent field.
|
||||||
|
bit = pos % 8;
|
||||||
|
oct = (pos - bit) / 8;
|
||||||
|
spent = (p.data[fstart + oct] >>> (7 - bit)) & 1;
|
||||||
|
|
||||||
|
// We found our coin.
|
||||||
|
if (pos === index) {
|
||||||
|
if (spent)
|
||||||
|
return;
|
||||||
|
decompress.script(p, coin.script);
|
||||||
|
coin.value = p.readVarint();
|
||||||
|
return coin;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Already spent.
|
||||||
|
if (spent) {
|
||||||
|
pos++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip passed the compressed coin.
|
||||||
|
skipCoin(p);
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -439,7 +441,7 @@ Coins.fromRaw = function fromRaw(data, hash) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Coins.prototype.fromTX = function fromTX(tx) {
|
Coins.prototype.fromTX = function fromTX(tx) {
|
||||||
var i;
|
var i, output;
|
||||||
|
|
||||||
this.version = tx.version;
|
this.version = tx.version;
|
||||||
this.hash = tx.hash('hex');
|
this.hash = tx.hash('hex');
|
||||||
@ -447,10 +449,13 @@ Coins.prototype.fromTX = function fromTX(tx) {
|
|||||||
this.coinbase = tx.isCoinbase();
|
this.coinbase = tx.isCoinbase();
|
||||||
|
|
||||||
for (i = 0; i < tx.outputs.length; i++) {
|
for (i = 0; i < tx.outputs.length; i++) {
|
||||||
if (tx.outputs[i].script.isUnspendable()) {
|
output = tx.outputs[i];
|
||||||
|
|
||||||
|
if (output.script.isUnspendable()) {
|
||||||
this.outputs.push(null);
|
this.outputs.push(null);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.outputs.push(Coin.fromTX(tx, i));
|
this.outputs.push(Coin.fromTX(tx, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -487,9 +492,6 @@ Coins.fromTX = function fromTX(tx) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function CompressedCoin(offset, size, raw) {
|
function CompressedCoin(offset, size, raw) {
|
||||||
if (!(this instanceof CompressedCoin))
|
|
||||||
return new CompressedCoin(offset, size, raw);
|
|
||||||
|
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.raw = raw;
|
this.raw = raw;
|
||||||
@ -534,6 +536,47 @@ CompressedCoin.prototype.toRaw = function toRaw() {
|
|||||||
return this.raw.slice(this.offset, this.offset + this.size);
|
return this.raw.slice(this.offset, this.offset + this.size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate compressed coin from reader.
|
||||||
|
* @param {BufferReader} p
|
||||||
|
* @returns {CompressedCoin}
|
||||||
|
*/
|
||||||
|
|
||||||
|
CompressedCoin.fromRaw = function fromRaw(p) {
|
||||||
|
var offset = p.offset;
|
||||||
|
var size = skipCoin(p);
|
||||||
|
return new CompressedCoin(offset, size, p.data);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helpers
|
||||||
|
*/
|
||||||
|
|
||||||
|
function skipCoin(p) {
|
||||||
|
var start = p.offset;
|
||||||
|
|
||||||
|
// Skip past the compressed scripts.
|
||||||
|
switch (p.readU8()) {
|
||||||
|
case 0:
|
||||||
|
p.seek(p.readVarint());
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
p.seek(20);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
p.seek(33);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('Bad prefix.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip past the value.
|
||||||
|
p.readVarint();
|
||||||
|
|
||||||
|
return p.offset - start;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expose
|
* Expose
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user