peer: improvements

This commit is contained in:
Fedor Indutny 2014-05-06 00:55:24 +04:00
parent fb651d703e
commit 7f0ea92a43
5 changed files with 115 additions and 20 deletions

View File

@ -30,7 +30,8 @@ function Peer(pool, socket, options) {
this.options = options || {};
this._broadcast = {
timout: this.options.broadcastTimeout || 30000,
timeout: this.options.broadcastTimeout || 30000,
interval: this.options.broadcastInterval || 3000,
map: {}
};
@ -96,8 +97,15 @@ Peer.prototype.broadcast = function broadcast(items) {
var result = items.map(function(item) {
var key = item.hash('hex');
var old = this._broadcast.map[key];
if (old)
if (old) {
clearTimeout(old.timer);
clearInterval(old.interval);
}
var inv = this.framer.inv([{
type: item.type,
hash: item.hash()
}])
// Auto-cleanup broadcast map after timeout
var entry = {
@ -105,7 +113,13 @@ Peer.prototype.broadcast = function broadcast(items) {
timeout: setTimeout(function() {
entry.e.emit('timeout');
delete self._broadcast.map[key];
}, this._broadcast.timout),
}, this._broadcast.timeout),
// Retransmit
interval: setInterval(function() {
self._write(inv);
}, this._broadcast.interval),
type: item.type,
value: item.render()
};
@ -141,6 +155,7 @@ Peer.prototype.destroy = function destroy() {
// Clean-up timeouts
Object.keys(this._broadcast.map).forEach(function(key) {
clearTimeout(this._broadcast.map[key].timer);
clearInterval(this._broadcast.map[key].interval);
}, this);
clearInterval(this._ping.timer);
@ -236,6 +251,8 @@ Peer.prototype._onPacket = function onPacket(packet) {
if (this._res(cmd, payload)) {
return;
} else {
if (cmd === 'reject')
console.log(cmd, payload);
this.emit(cmd, payload);
}
};

View File

@ -13,7 +13,7 @@ function Pool(options) {
EventEmitter.call(this);
this.options = options || {};
this.size = options.size || 16;
this.size = options.size || 32;
this.parallel = options.parallel || 2000;
this.redundancy = 2;
this.load = {

View File

@ -1,6 +1,6 @@
var bcoin = require('../bcoin');
var constants = bcoin.protocol.constants;
var utils = bcoin.protocol.utils;
var utils = bcoin.utils;
var script = exports;
script.decode = function decode(s) {
@ -11,12 +11,24 @@ script.decode = function decode(s) {
var b = s[i++];
// Next `b` bytes should be pushed to stack
if (b >= 0x01 && b <= 0x75) {
if (b >= 0x01 && b <= 0x4b) {
opcodes.push(s.slice(i, i + b));
i += b;
continue;
}
// Zero
if (b === 0) {
opcodes.push([]);
continue;
}
// Raw number
if (b >= 0x51 && b <= 0x60) {
opcodes.push([ b - 0x50 ]);
continue;
}
var opcode = constants.opcodesByVal[b];
if (opcode === 'pushdata1') {
var len = s[i++];
@ -49,7 +61,11 @@ script.encode = function encode(s) {
// Push value to stack
if (Array.isArray(instr)) {
if (1 <= instr.length && instr.length <= 0x75) {
if (instr.length === 0) {
res.push(0);
} else if (instr.length === 1 && 0 < instr[0] && instr[0] <= 16) {
res.push(0x50 + instr[0]);
} else if (1 <= instr.length && instr.length <= 0x4b) {
res = res.concat(instr.length, instr);
} else if (instr.length <= 0xff) {
res = res.concat(opcodes['pushdata1'], instr.length, instr);
@ -109,12 +125,12 @@ script.execute = function execute(s, stack, tx) {
if (stack.length === 0)
return false;
stack.push(bcoin.utils.ripesha(stack.pop()));
stack.push(utils.ripesha(stack.pop()));
} else if (o === 'eqverify' || o === 'eq') {
if (stack.length < 2)
return false;
var res = bcoin.utils.isEqual(stack.pop(), stack.pop());
var res = utils.isEqual(stack.pop(), stack.pop());
if (o === 'eqverify') {
if (!res)
return false;
@ -147,3 +163,52 @@ script.execute = function execute(s, stack, tx) {
return true;
};
script.isPubkeyhash = function isPubkeyhash(s, hash) {
if (s.length !== 5)
return false;
var match = s[0] === 'dup' &&
s[1] === 'hash160' &&
Array.isArray(s[2]) &&
s[3] === 'eqverify' &&
s[4] === 'checksig';
if (!match)
return false;
if (hash)
return utils.isEqual(s[2], hash);
else
return s[2];
}
script.isMultisig = function isMultisig(s, key) {
if (s.length < 4)
return false;
var m = s[0];
if (!Array.isArray(m) || m.length !== 1)
return false;
m = m[0];
if (m + 3 !== s.length || s[s.length - 1] !== 'checkmultisig')
return false;
var n = s[s.length - 2];
if (!Array.isArray(n) || n.length !== 1)
return false;
var keys = s.slice(1, m);
var isArray = keys.every(function(k) {
return Array.isArray(k);
});
if (!isArray)
return false;
if (!key)
return keys;
return keys.some(function(k) {
return utils.isEqual(k, key);
});
}

View File

@ -17,6 +17,7 @@ function Wallet(options, passphrase) {
if (!options)
options = {};
this.compressed = true;
this.key = null;
if (options.passphrase) {
@ -38,8 +39,10 @@ Wallet.prototype.getPrivateKey = function getPrivateKey(enc) {
return priv;
if (enc === 'base58') {
// We'll be using compressed public key as an address
var arr = [ 128 ].concat(priv, 1);
// We'll be using ncompressed public key as an address
var arr = [ 128 ].concat(priv);
if (this.compressed)
arr.push(1);
var chk = utils.checksum(arr);
return utils.toBase58(arr.concat(chk));
} else {
@ -48,7 +51,7 @@ Wallet.prototype.getPrivateKey = function getPrivateKey(enc) {
};
Wallet.prototype.getPublicKey = function getPublicKey() {
return this.key.getPublic(true, 'array');
return this.key.getPublic(this.compressed, 'array');
};
Wallet.prototype.getHash = function getHash() {
@ -92,16 +95,18 @@ Wallet.prototype.validateAddress = function validateAddress(addr) {
Wallet.validateAddress = Wallet.prototype.validateAddress;
Wallet.prototype.own = function own(tx) {
var hash = this.getHash();
var key = this.getPublicKey();
var outputs = tx.outputs.filter(function(output) {
if (output.script.length < 5)
return false;
var s = output.script;
var s = output.script.slice(-5);
return s[0] === 'dup' &&
s[1] === 'hash160' &&
utils.isEqual(s[2], this.getHash()) &&
s[3] === 'eqverify' &&
s[4] === 'checksig';
if (bcoin.script.isPubkeyhash(s, hash))
return true;
if (bcoin.script.isMultisig(s, key))
return true;
return false;
}, this);
if (outputs.length === 0)
return false;

View File

@ -22,4 +22,12 @@ describe('Script', function() {
var dst = bcoin.script.encode(decoded);
assert.equal(bcoin.utils.toHex(dst), src);
});
it('should encode/decode numbers', function() {
var script = [ [], [1], [2], [16] ];
var encoded = bcoin.script.encode(script);
assert.deepEqual(encoded, [ 0, 0x51, 0x52, 0x60 ]);
var decoded = bcoin.script.decode(encoded);
assert.deepEqual(decoded, script);
});
});