refactor.
This commit is contained in:
parent
79aa613662
commit
9e61d0ee86
@ -419,7 +419,7 @@ Block.prototype.toCompact = function toCompact() {
|
||||
p.writeVarint(this.txs.length);
|
||||
|
||||
this.txs.forEach(function(tx) {
|
||||
p.writeBytes(tx.hash());
|
||||
p.writeHash(tx.hash());
|
||||
});
|
||||
|
||||
return p.render();
|
||||
|
||||
@ -43,6 +43,7 @@ function Chain(node, options) {
|
||||
this.tip = null;
|
||||
this.height = -1;
|
||||
this.segwitActive = null;
|
||||
this.spv = !!options.spv;
|
||||
|
||||
this.orphan = {
|
||||
map: {},
|
||||
@ -241,7 +242,7 @@ Chain.prototype._preload = function _preload(callback) {
|
||||
if (!this.options.preload)
|
||||
return callback();
|
||||
|
||||
if (!this.options.spv)
|
||||
if (!this.spv)
|
||||
return callback();
|
||||
|
||||
if (network.type !== 'main')
|
||||
@ -478,7 +479,7 @@ Chain.prototype._verify = function _verify(block, prev, callback) {
|
||||
|
||||
// Only allow version 5 blocks (segwit)
|
||||
// once the majority of blocks are using it.
|
||||
if (network.segwitHeight !== -1 && height >= network.segwitHeight) {
|
||||
if (network.type === 'segnet3' && height >= network.segwitHeight) {
|
||||
if (block.version < 5 && prev.isOutdated(5))
|
||||
return done(new VerifyError(block, 'obsolete', 'bad-version', 0));
|
||||
}
|
||||
@ -591,7 +592,7 @@ Chain.prototype._checkDuplicates = function _checkDuplicates(block, prev, callba
|
||||
var self = this;
|
||||
var height = prev.height + 1;
|
||||
|
||||
if (this.options.spv || block.type !== 'block')
|
||||
if (this.spv || block.type !== 'block')
|
||||
return callback();
|
||||
|
||||
if (block.isGenesis())
|
||||
@ -628,7 +629,7 @@ Chain.prototype._checkInputs = function _checkInputs(block, prev, flags, callbac
|
||||
var scriptCheck = true;
|
||||
var historical = false;
|
||||
|
||||
if (this.options.spv || block.type !== 'block')
|
||||
if (this.spv || block.type !== 'block')
|
||||
return callback();
|
||||
|
||||
if (block.isGenesis())
|
||||
@ -1551,31 +1552,7 @@ Chain.prototype.getLocator = function getLocator(start, callback, force) {
|
||||
start = start.hash('hex');
|
||||
}
|
||||
|
||||
function getTop(callback) {
|
||||
if (typeof start === 'string') {
|
||||
return self.db.getHeight(start, function(err, top) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (top === -1) {
|
||||
// We could simply `return [start]` here,
|
||||
// but there is no standardized "spacing"
|
||||
// for locator hashes. Pretend this hash
|
||||
// is our tip. This is useful for getheaders
|
||||
// when not using headers-first.
|
||||
hashes.push(start);
|
||||
top = self.height;
|
||||
}
|
||||
|
||||
return callback(null, top);
|
||||
});
|
||||
} else if (typeof start === 'number') {
|
||||
top = start;
|
||||
}
|
||||
return callback(null, top);
|
||||
}
|
||||
|
||||
return getTop(function(err, top) {
|
||||
function build(err, top) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
@ -1611,7 +1588,31 @@ Chain.prototype.getLocator = function getLocator(start, callback, force) {
|
||||
return callback(err);
|
||||
return callback(null, hashes);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof start === 'string') {
|
||||
return self.db.getHeight(start, function(err, top) {
|
||||
if (err)
|
||||
return build(err);
|
||||
|
||||
if (top === -1) {
|
||||
// We could simply `return [start]` here,
|
||||
// but there is no standardized "spacing"
|
||||
// for locator hashes. Pretend this hash
|
||||
// is our tip. This is useful for getheaders
|
||||
// when not using headers-first.
|
||||
hashes.push(start);
|
||||
top = self.height;
|
||||
}
|
||||
|
||||
return build(null, top);
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof start === 'number')
|
||||
top = start;
|
||||
|
||||
return build(null, top);
|
||||
};
|
||||
|
||||
Chain.prototype.getOrphanRoot = function getOrphanRoot(hash) {
|
||||
@ -1662,7 +1663,7 @@ Chain.prototype.getTargetAsync = function getTargetAsync(last, block, callback)
|
||||
|
||||
Chain.prototype.getTarget = function getTarget(last, block, ancestors) {
|
||||
var powLimit = utils.toCompact(network.powLimit);
|
||||
var ts, first, i, prev;
|
||||
var ts, first, i;
|
||||
|
||||
// Genesis
|
||||
if (!last)
|
||||
@ -1680,14 +1681,11 @@ Chain.prototype.getTarget = function getTarget(last, block, ancestors) {
|
||||
return powLimit;
|
||||
|
||||
i = 1;
|
||||
prev = ancestors;
|
||||
while (prev[i]
|
||||
while (ancestors[i]
|
||||
&& last.height % network.powDiffInterval !== 0
|
||||
&& last.bits === powLimit) {
|
||||
last = prev[i++];
|
||||
last = ancestors[i++];
|
||||
}
|
||||
|
||||
return last.bits;
|
||||
}
|
||||
return last.bits;
|
||||
}
|
||||
@ -1744,7 +1742,6 @@ Chain.prototype.findLocator = function findLocator(locator, callback) {
|
||||
}, callback);
|
||||
};
|
||||
|
||||
// https://github.com/bitcoin/bitcoin/pull/7648/files
|
||||
Chain.prototype.getState = function getState(prev, id, callback) {
|
||||
var self = this;
|
||||
var period = network.minerConfirmationWindow;
|
||||
@ -1957,15 +1954,15 @@ Chain.prototype.isSegwitActive = function isSegwitActive(callback, force) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!prev.isUpgraded(5)) {
|
||||
if (self.tip.version >= 5 && prev.isUpgraded(5)) {
|
||||
prev.free();
|
||||
self.segwitActive = false;
|
||||
return callback(null, false);
|
||||
self.segwitActive = true;
|
||||
return callback(null, true);
|
||||
}
|
||||
|
||||
prev.free();
|
||||
self.segwitActive = true;
|
||||
return callback(null, true);
|
||||
self.segwitActive = false;
|
||||
return callback(null, false);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@ -39,6 +39,7 @@ function ChainDB(chain, options) {
|
||||
|
||||
this.keepBlocks = options.keepBlocks || 288;
|
||||
this.prune = !!options.prune;
|
||||
this.spv = !!options.spv;
|
||||
|
||||
// Need to cache up to the retarget interval
|
||||
// if we're going to be checking the damn
|
||||
@ -65,8 +66,8 @@ ChainDB.prototype._init = function _init() {
|
||||
if (this.loaded)
|
||||
return;
|
||||
|
||||
this.db = bcoin.ldb((this.options.spv ? 'spv' : '') + 'chain', {
|
||||
compression: false,
|
||||
this.db = bcoin.ldb(this.spv ? 'spvchain' : 'chain', {
|
||||
compression: true,
|
||||
cacheSize: 16 << 20,
|
||||
writeBufferSize: 8 << 20
|
||||
});
|
||||
@ -577,7 +578,7 @@ ChainDB.prototype.has = function has(height, callback) {
|
||||
};
|
||||
|
||||
ChainDB.prototype.saveBlock = function saveBlock(block, batch, connect, callback) {
|
||||
if (this.options.spv)
|
||||
if (this.spv)
|
||||
return utils.nextTick(callback);
|
||||
|
||||
batch.put('b/b/' + block.hash('hex'), block.toCompact());
|
||||
@ -595,7 +596,7 @@ ChainDB.prototype.saveBlock = function saveBlock(block, batch, connect, callback
|
||||
ChainDB.prototype.removeBlock = function removeBlock(hash, batch, callback) {
|
||||
var self = this;
|
||||
|
||||
if (this.options.spv)
|
||||
if (this.spv)
|
||||
return utils.nextTick(callback);
|
||||
|
||||
this._ensureHistory(hash, function(err, block) {
|
||||
@ -618,7 +619,7 @@ ChainDB.prototype.removeBlock = function removeBlock(hash, batch, callback) {
|
||||
ChainDB.prototype.connectBlock = function connectBlock(block, batch, callback) {
|
||||
var self = this;
|
||||
|
||||
if (this.options.spv) {
|
||||
if (this.spv) {
|
||||
self.emit('add block', block);
|
||||
return utils.nextTick(callback);
|
||||
}
|
||||
@ -689,7 +690,7 @@ ChainDB.prototype.connectBlock = function connectBlock(block, batch, callback) {
|
||||
ChainDB.prototype.disconnectBlock = function disconnectBlock(hash, batch, callback) {
|
||||
var self = this;
|
||||
|
||||
if (this.options.spv)
|
||||
if (this.spv)
|
||||
return utils.nextTick(callback);
|
||||
|
||||
this._ensureHistory(hash, function(err, block) {
|
||||
@ -699,8 +700,10 @@ ChainDB.prototype.disconnectBlock = function disconnectBlock(hash, batch, callba
|
||||
if (!block)
|
||||
return callback();
|
||||
|
||||
if (typeof hash === 'string')
|
||||
assert(block.hash('hex') === hash);
|
||||
if (self.options.paranoid) {
|
||||
if (typeof hash === 'string')
|
||||
assert(block.hash('hex') === hash, 'Database is corrupt.');
|
||||
}
|
||||
|
||||
block.txs.forEach(function(tx) {
|
||||
var hash = tx.hash('hex');
|
||||
@ -1040,8 +1043,8 @@ ChainDB.prototype.getTX = function getTX(hash, callback) {
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
if (self.options.paranoid && tx.hash('hex') !== hash)
|
||||
return callback(new Error('ChainDB is corrupt. All is lost.'));
|
||||
if (self.options.paranoid)
|
||||
assert(tx.hash('hex') === hash, 'Database is corrupt.');
|
||||
|
||||
return callback(null, tx);
|
||||
});
|
||||
@ -1234,6 +1237,10 @@ ChainDB.prototype.getBlock = function getBlock(hash, callback) {
|
||||
|
||||
delete block.hashes;
|
||||
block = new bcoin.block(block);
|
||||
|
||||
if (self.options.paranoid)
|
||||
assert(block.hash('hex') === hash, 'Database is corrupt.');
|
||||
|
||||
return callback(null, block);
|
||||
});
|
||||
});
|
||||
@ -1251,8 +1258,9 @@ ChainDB.prototype._getTX = function _getTX(hash, callback) {
|
||||
ChainDB.prototype.isUnspentTX = function isUnspentTX(hash, callback) {
|
||||
return callback(null, false);
|
||||
|
||||
if (this.options.spv)
|
||||
if (this.spv)
|
||||
return callback(null, false);
|
||||
|
||||
return this.isSpentTX(hash, function(err, spent) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
@ -1292,7 +1300,7 @@ ChainDB.prototype.isSpentTX = function isSpentTX(hash, callback) {
|
||||
ChainDB.prototype._pruneBlock = function _pruneBlock(block, batch, callback) {
|
||||
var futureHeight;
|
||||
|
||||
if (this.options.spv)
|
||||
if (this.spv)
|
||||
return callback();
|
||||
|
||||
if (!this.prune)
|
||||
|
||||
@ -268,7 +268,7 @@ Miner.prototype.createBlock = function createBlock(callback) {
|
||||
// Set up the witness nonce and
|
||||
// commitment output for segwit.
|
||||
block.witness = true;
|
||||
block.witnessNonce = utils.nonce().toBuffer();
|
||||
block.witnessNonce = utils.nonce().toBuffer('le', 8);
|
||||
coinbase.inputs[0].witness.items[0] = block.witnessNonce;
|
||||
coinbase.addOutput({
|
||||
script: new bcoin.script([]),
|
||||
|
||||
@ -47,6 +47,7 @@ function Peer(pool, options) {
|
||||
this.haveWitness = false;
|
||||
this.hashContinue = null;
|
||||
this.filter = null;
|
||||
this.relay = true;
|
||||
|
||||
this.challenge = null;
|
||||
this.lastPong = 0;
|
||||
@ -229,7 +230,7 @@ Peer.prototype.broadcast = function broadcast(items) {
|
||||
var result = [];
|
||||
var payload = [];
|
||||
|
||||
if (this.version && this.version.relay === false)
|
||||
if (!this.relay)
|
||||
return;
|
||||
|
||||
if (this.destroyed)
|
||||
@ -522,24 +523,19 @@ Peer.prototype._handleFilterLoad = function _handleFilterLoad(payload) {
|
||||
this.filter = new bcoin.bloom(size, payload.n, payload.tweak);
|
||||
this.filter.filter = payload.filter;
|
||||
this.filter.update = payload.update;
|
||||
if (this.version)
|
||||
this.version.relay = true;
|
||||
this.relay = true;
|
||||
};
|
||||
|
||||
Peer.prototype._handleFilterAdd = function _handleFilterAdd(payload) {
|
||||
if (this.filter)
|
||||
this.filter.add(payload.data);
|
||||
|
||||
if (this.version)
|
||||
this.version.relay = true;
|
||||
this.relay = true;
|
||||
};
|
||||
|
||||
Peer.prototype._handleFilterClear = function _handleFilterClear(payload) {
|
||||
if (this.filter)
|
||||
this.filter.reset();
|
||||
|
||||
if (this.version)
|
||||
this.version.relay = true;
|
||||
this.relay = true;
|
||||
};
|
||||
|
||||
Peer.prototype._handleUTXOs = function _handleUTXOs(payload) {
|
||||
@ -795,6 +791,9 @@ Peer.prototype._handleVersion = function handleVersion(payload) {
|
||||
if (payload.witness)
|
||||
this.haveWitness = true;
|
||||
|
||||
if (payload.relay === false)
|
||||
this.relay = false;
|
||||
|
||||
// ACK
|
||||
this._write(this.framer.verack());
|
||||
this.version = payload;
|
||||
|
||||
@ -642,7 +642,7 @@ Framer.merkleBlock = function _merkleBlock(block, writer) {
|
||||
var p = new BufferWriter(writer);
|
||||
var i;
|
||||
|
||||
p.write32(block.version);
|
||||
p.writeU32(block.version);
|
||||
p.writeHash(block.prevBlock);
|
||||
p.writeHash(block.merkleRoot);
|
||||
p.writeU32(block.ts);
|
||||
|
||||
@ -375,8 +375,6 @@ Parser.parseVersion = function parseVersion(p) {
|
||||
assert(ts >= 0, 'Timestamp is negative.');
|
||||
assert(height >= 0, 'Height is negative.');
|
||||
|
||||
this.version = version;
|
||||
|
||||
return {
|
||||
version: version,
|
||||
services: services,
|
||||
@ -476,7 +474,7 @@ Parser.parseMerkleBlock = function parseMerkleBlock(p) {
|
||||
p = new BufferReader(p);
|
||||
p.start();
|
||||
|
||||
version = p.readU32(); // Technically signed
|
||||
version = p.readU32();
|
||||
prevBlock = p.readHash();
|
||||
merkleRoot = p.readHash();
|
||||
ts = p.readU32();
|
||||
@ -735,8 +733,8 @@ Parser.parseCoin = function parseCoin(p, extended) {
|
||||
};
|
||||
|
||||
Parser.parseTX = function parseTX(p) {
|
||||
var inCount, txIn, tx;
|
||||
var outCount, txOut;
|
||||
var inCount, inputs;
|
||||
var outCount, outputs;
|
||||
var version, locktime, i;
|
||||
var raw;
|
||||
|
||||
@ -749,20 +747,16 @@ Parser.parseTX = function parseTX(p) {
|
||||
version = p.readU32(); // Technically signed
|
||||
inCount = p.readVarint();
|
||||
|
||||
txIn = new Array(inCount);
|
||||
inputs = new Array(inCount);
|
||||
for (i = 0; i < inCount; i++) {
|
||||
tx = Parser.parseInput(p);
|
||||
|
||||
txIn[i] = tx;
|
||||
txIn[i].witness = { items: [] };
|
||||
inputs[i] = Parser.parseInput(p);
|
||||
inputs[i].witness = { items: [] };
|
||||
}
|
||||
|
||||
outCount = p.readVarint();
|
||||
txOut = new Array(outCount);
|
||||
for (i = 0; i < outCount; i++) {
|
||||
tx = Parser.parseOutput(p);
|
||||
txOut[i] = tx;
|
||||
}
|
||||
outputs = new Array(outCount);
|
||||
for (i = 0; i < outCount; i++)
|
||||
outputs[i] = Parser.parseOutput(p);
|
||||
|
||||
locktime = p.readU32();
|
||||
|
||||
@ -771,8 +765,8 @@ Parser.parseTX = function parseTX(p) {
|
||||
return {
|
||||
version: version,
|
||||
flag: 1,
|
||||
inputs: txIn,
|
||||
outputs: txOut,
|
||||
inputs: inputs,
|
||||
outputs: outputs,
|
||||
locktime: locktime,
|
||||
_witnessSize: 0,
|
||||
_raw: raw,
|
||||
@ -796,8 +790,8 @@ Parser.isWitnessTX = function isWitnessTX(p) {
|
||||
};
|
||||
|
||||
Parser.parseWitnessTX = function parseWitnessTX(p) {
|
||||
var inCount, txIn, tx;
|
||||
var outCount, txOut;
|
||||
var inCount, inputs, witness;
|
||||
var outCount, outputs;
|
||||
var marker, flag;
|
||||
var version, locktime, i;
|
||||
var witnessSize = 0;
|
||||
@ -819,24 +813,20 @@ Parser.parseWitnessTX = function parseWitnessTX(p) {
|
||||
|
||||
inCount = p.readVarint();
|
||||
|
||||
txIn = new Array(inCount);
|
||||
for (i = 0; i < inCount; i++) {
|
||||
tx = Parser.parseInput(p);
|
||||
txIn[i] = tx;
|
||||
}
|
||||
inputs = new Array(inCount);
|
||||
for (i = 0; i < inCount; i++)
|
||||
inputs[i] = Parser.parseInput(p);
|
||||
|
||||
outCount = p.readVarint();
|
||||
|
||||
txOut = new Array(outCount);
|
||||
for (i = 0; i < outCount; i++) {
|
||||
tx = Parser.parseOutput(p);
|
||||
txOut[i] = tx;
|
||||
}
|
||||
outputs = new Array(outCount);
|
||||
for (i = 0; i < outCount; i++)
|
||||
outputs[i] = Parser.parseOutput(p);
|
||||
|
||||
for (i = 0; i < inCount; i++) {
|
||||
tx = Parser.parseWitness(p);
|
||||
txIn[i].witness = tx;
|
||||
witnessSize += tx._size;
|
||||
witness = Parser.parseWitness(p);
|
||||
inputs[i].witness = witness;
|
||||
witnessSize += witness._size;
|
||||
}
|
||||
|
||||
locktime = p.readU32();
|
||||
@ -846,8 +836,8 @@ Parser.parseWitnessTX = function parseWitnessTX(p) {
|
||||
return {
|
||||
version: version,
|
||||
flag: flag,
|
||||
inputs: txIn,
|
||||
outputs: txOut,
|
||||
inputs: inputs,
|
||||
outputs: outputs,
|
||||
locktime: locktime,
|
||||
_raw: raw,
|
||||
_size: raw.length,
|
||||
@ -898,11 +888,10 @@ Parser.parseReject = function parseReject(p) {
|
||||
ccode = p.readU8();
|
||||
reason = p.readVarString('ascii');
|
||||
|
||||
try {
|
||||
if (p.left() >= 32)
|
||||
data = p.readHash();
|
||||
} catch (e) {
|
||||
else
|
||||
data = null;
|
||||
}
|
||||
|
||||
return {
|
||||
message: message,
|
||||
@ -919,7 +908,7 @@ Parser.parseAddress = function parseAddress(p, full) {
|
||||
p = new BufferReader(p);
|
||||
p.start();
|
||||
|
||||
if (full && this.version >= 31402)
|
||||
if (full) // only version >= 31402
|
||||
ts = p.readU32();
|
||||
else
|
||||
ts = 0;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user