This commit is contained in:
Christopher Jeffrey 2016-03-29 17:45:10 -07:00
parent 5dc7030ac4
commit 86efd59261
9 changed files with 87 additions and 42 deletions

View File

@ -154,21 +154,24 @@ Chain.prototype._init = function _init() {
if (err)
return self.emit('error', err);
self.isSegwitActive(function(err) {
self.db.getTip(function(err, tip) {
if (err)
return self.emit('error', err);
self.db.getTip(function(err, tip) {
assert(tip);
self.tip = tip;
self.height = tip.height;
if (self.bestHeight === -1)
network.height = tip.height;
self.isSegwitActive(function(err, result) {
if (err)
return self.emit('error', err);
assert(tip);
self.tip = tip;
self.height = tip.height;
if (self.bestHeight === -1)
network.height = tip.height;
if (result)
utils.debug('Segwit is active.');
self.loaded = true;
self.emit('open');
@ -1906,6 +1909,7 @@ Chain.prototype.computeBlockVersion = function computeBlockVersion(prev, callbac
};
Chain.prototype.isSegwitActive = function isSegwitActive(callback) {
var self = this;
var tip = this.tip;
var unlock;
@ -1915,7 +1919,7 @@ Chain.prototype.isSegwitActive = function isSegwitActive(callback) {
if (!tip)
return utils.asyncify(callback)(null, false);
if (!(network.segwitHeight !== -1 && height >= network.segwitHeight))
if (!(network.segwitHeight !== -1 && tip.height >= network.segwitHeight))
return utils.asyncify(callback)(null, false);
unlock = this._lock(isSegwitActive, [callback]);

View File

@ -22,12 +22,12 @@ var network = bcoin.protocol.network;
function Coin(tx, index) {
var options;
if (!(this instanceof Coin))
return new Coin(tx, index);
if (tx instanceof Coin)
return tx;
if (!(this instanceof Coin))
return new Coin(tx, index);
if (tx instanceof bcoin.tx) {
this.version = tx.version;
this.height = tx.height;
@ -117,7 +117,7 @@ Coin.prototype.toJSON = function toJSON() {
version: this.version,
height: this.height,
value: utils.btc(this.value),
script: utils.toHex(bcoin.protocol.framer(this.script)),
script: utils.toHex(bcoin.protocol.framer.script(this.script)),
coinbase: this.coinbase,
hash: this.hash ? utils.revHex(this.hash) : null,
index: this.index

View File

@ -360,6 +360,7 @@ Mempool.prototype.addTX = function addTX(tx, peer, callback, force) {
'mempool full',
0));
}
utils.debug('Added orphan %s to mempool.', tx.rhash);
return self.storeOrphan(tx, callback);
}
@ -412,6 +413,7 @@ Mempool.prototype.addUnchecked = function addUnchecked(tx, peer, callback) {
self.addUnchecked(tx, peer, function(err) {
if (err)
self.emit('error', err);
utils.debug('Resolved orphan %s in mempool.', tx.rhash);
next();
}, true);
}, callback);
@ -872,9 +874,9 @@ Mempool.prototype.getLocks = function getLocks(tx, flags, entry, callback) {
if (input.sequence & disableFlag)
return next();
coinHeight = coin.height === -1
coinHeight = input.coin.height === -1
? self.chain.tip + 1
: coin.height;
: input.coin.height;
if ((input.sequence & typeFlag) === 0) {
coinHeight += (input.sequence & mask) - 1;
@ -921,7 +923,7 @@ Mempool.prototype.evalLocks = function evalLocks(entry, minHeight, minTime, call
return callback(null, true);
});
}
};
Mempool.prototype.checkLocks = function checkLocks(tx, flags, entry, callback) {
var self = this;
@ -931,7 +933,7 @@ Mempool.prototype.checkLocks = function checkLocks(tx, flags, entry, callback) {
self.evalLocks(entry, minHeight, minTime, callback);
});
}
};
Mempool.prototype.checkMempoolLocks = function checkMempoolLocks(tx, flags, callback) {
var self = this;
@ -950,7 +952,7 @@ Mempool.prototype.checkMempoolLocks = function checkMempoolLocks(tx, flags, call
});
this.checkLocks(tx, flags, index, callback);
}
};
/**
* VerifyError

View File

@ -42,6 +42,8 @@ function Peer(pool, options) {
this.ack = false;
this.connected = false;
this.ts = this.options.ts || 0;
this.sendHeaders = false;
this.haveWitness = false;
this.challenge = null;
this.lastPong = 0;
@ -147,6 +149,11 @@ Peer.prototype._init = function init() {
this.challenge = utils.nonce();
this._ping.timer = setInterval(function() {
if (self.options.witness && !self.haveWitness) {
self._error('Peer does not support segregated witness.');
self.setMisbehavior(100);
return;
}
self._write(self.framer.ping({
nonce: self.challenge
}));
@ -163,12 +170,20 @@ Peer.prototype._init = function init() {
self.emit('ack');
self.ts = utils.now();
self._write(self.framer.packet('getaddr', new Buffer([])));
self._write(self.framer.packet('getaddr'));
if (self.pool.options.headers) {
if (self.options.headers) {
if (self.version && self.version.version > 70012)
self._write(self.framer.packet('sendheaders', new Buffer([])));
self._write(self.framer.packet('sendheaders'));
}
if (self.options.witness) {
if (self.version && self.version.version >= 70012)
self._write(self.framer.packet('havewitness'));
}
if (self.pool.chain.isFull())
self.getMempool();
});
// Send hello
@ -454,6 +469,16 @@ Peer.prototype._onPacket = function onPacket(packet) {
}
}
if (cmd === 'sendheaders') {
this.sendHeaders = true;
return;
}
if (cmd === 'havewitness') {
this.haveWitness = true;
return;
}
if (this._res(cmd, payload))
return;
@ -469,14 +494,14 @@ Peer.prototype._emitMerkle = function _emitMerkle(payload) {
Peer.prototype._handleVersion = function handleVersion(payload) {
if (payload.version < constants.minVersion) {
this._error('Peer doesn\'t support required protocol version.');
this.pool.setMisbehavior(this, 100);
this.setMisbehavior(100);
return;
}
if (this.options.headers) {
if (payload.version < 31800) {
this._error('Peer doesn\'t support getheaders.');
this.pool.setMisbehavior(this, 100);
this.setMisbehavior(100);
return;
}
}
@ -484,7 +509,7 @@ Peer.prototype._handleVersion = function handleVersion(payload) {
if (this.options.network) {
if (!payload.network) {
this._error('Peer does not support network services.');
this.pool.setMisbehavior(this, 100);
this.setMisbehavior(100);
return;
}
}
@ -492,19 +517,22 @@ Peer.prototype._handleVersion = function handleVersion(payload) {
if (this.options.spv) {
if (!payload.bloom && payload.version < 70011) {
this._error('Peer does not support bip37.');
this.pool.setMisbehavior(this, 100);
this.setMisbehavior(100);
return;
}
}
if (this.options.witness) {
if (!payload.witness) {
this._error('Peer does not support segregated witness.');
this.pool.setMisbehavior(this, 100);
return;
// this._error('Peer does not support segregated witness service.');
// this.setMisbehavior(100);
// return;
}
}
if (payload.witness)
this.haveWitness = true;
// ACK
this._write(this.framer.verack());
this.version = payload;
@ -734,8 +762,8 @@ Peer.prototype.isMisbehaving = function isMisbehaving() {
return this.pool.isMisbehaving(this.host);
};
Peer.prototype.setMisbehavior = function setMisbehavior(dos) {
return this.pool.setMisbehavior(this, dos);
Peer.prototype.setMisbehavior = function setMisbehavior(score) {
return this.pool.setMisbehavior(this, score);
};
Peer.prototype.sendReject = function sendReject(obj, code, reason, score) {

View File

@ -7,10 +7,9 @@
var bn = require('bn.js');
exports.minVersion = 70001;
exports.version = 70002;
exports.version = 70012;
// exports.maxMessage = 2 * 1024 * 1024; // main
exports.maxMessage = 4 * 1000 * 1000; // segwit
exports.bcoinServices = 0;
exports.services = {
network: (1 << 0),
@ -19,6 +18,9 @@ exports.services = {
witness: (1 << 3)
};
exports.localServices = exports.services.network
| exports.services.witness;
exports.inv = {
error: 0,
tx: 1,

View File

@ -10,6 +10,7 @@ var constants = require('./constants');
var utils = require('../utils');
var assert = utils.assert;
var BufferWriter = require('../writer');
var DUMMY = new Buffer([]);
/**
* Framer
@ -53,8 +54,14 @@ Framer.prototype.header = function header(cmd, payload) {
};
Framer.prototype.packet = function packet(cmd, payload) {
var h = this.header(cmd, payload);
return Buffer.concat([h, payload]);
var header;
if (!payload)
payload = DUMMY;
header = this.header(cmd, payload);
return Buffer.concat([header, payload]);
};
Framer.prototype.version = function version(options) {
@ -205,10 +212,10 @@ Framer.version = function version(options, writer) {
options.local = {};
if (options.local.services == null)
options.local.services = constants.bcoinServices;
options.local.services = constants.localServices;
p.write32(constants.version);
p.writeU64(constants.bcoinServices);
p.writeU64(constants.localServices);
p.write64(utils.now());
Framer.address(options.remote, false, p);
Framer.address(options.local, false, p);

View File

@ -153,6 +153,9 @@ Parser.prototype.parsePayload = function parsePayload(cmd, p) {
if (cmd === 'alert')
return Parser.parseAlert(p);
if (cmd === 'utxo')
return Parser.parseUTXO(p);
return p;
};
@ -436,7 +439,7 @@ Parser.parseOutput = function parseOutput(p) {
};
Parser.parseUTXO = function parseUTXO(p) {
var version, height, value, script, hash, index, coinbase;
var version, height, value, script;
p = new BufferReader(p);
p.start();

View File

@ -2234,7 +2234,7 @@ Script.format = function format(code) {
assert(typeof chunk === 'number');
if (constants.opcodeByVal[chunk])
if (constants.opcodesByVal[chunk])
return constants.opcodesByVal[chunk];
chunk = chunk.toString(16);

View File

@ -852,7 +852,7 @@ TX.prototype.isStandardInputs = function isStandardInputs(flags) {
return false;
if ((flags & constants.flags.VERIFY_WITNESS)
&& input.coin.isWitnessProgram()) {
&& input.coin.script.isWitnessProgram()) {
hadWitness = true;
// Input script must be empty.
@ -1266,8 +1266,7 @@ TX._fromExtended = function _fromExtended(buf, saveCoins) {
coin = bcoin.protocol.parser.parseCoin(coin, false);
coin.hash = tx.inputs[i].prevout.hash;
coin.index = tx.inputs[i].prevout.index;
coin.coinbase = false;
tx.inputs[i].coin = new bcoin.coin(coin);
tx.inputs[i].coin = coin;
}
}