refactor.

This commit is contained in:
Christopher Jeffrey 2016-04-04 14:07:16 -07:00
parent 79aa613662
commit 9e61d0ee86
7 changed files with 97 additions and 104 deletions

View File

@ -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();

View File

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

View File

@ -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)

View File

@ -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([]),

View File

@ -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;

View File

@ -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);

View File

@ -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;