refactor. close methods.

This commit is contained in:
Christopher Jeffrey 2016-03-29 13:15:43 -07:00
parent 3d6892cbe9
commit caf52c0579
12 changed files with 145 additions and 84 deletions

View File

@ -189,6 +189,11 @@ Chain.prototype.open = function open(callback) {
this.once('open', callback); this.once('open', callback);
}; };
Chain.prototype.close =
Chain.prototype.destroy = function destroy(callback) {
this.db.close(utils.ensure(callback));
};
Chain.prototype._lock = function _lock(func, args, force) { Chain.prototype._lock = function _lock(func, args, force) {
return this.locker.lock(func, args, force); return this.locker.lock(func, args, force);
}; };

View File

@ -174,7 +174,8 @@ ChainDB.prototype.open = function open(callback) {
this.once('open', callback); this.once('open', callback);
}; };
ChainDB.prototype.close = function close(callback) { ChainDB.prototype.close =
ChainDB.prototype.destroy = function destroy(callback) {
callback = utils.ensure(callback); callback = utils.ensure(callback);
this.db.close(callback); this.db.close(callback);
}; };

View File

@ -193,6 +193,17 @@ Fullnode.prototype.open = function open(callback) {
this.once('open', callback); this.once('open', callback);
}; };
Fullnode.prototype.close =
Fullnode.prototype.destroy = function destroy(callback) {
utils.parallel([
this.pool.close.bind(this.pool),
this.http.close.bind(this.http),
this.mempool.close.bind(this.mempool),
this.walletdb.close.bind(this.walletdb),
this.chain.close.bind(this.chain)
], callback);
};
Fullnode.prototype.createWallet = function createWallet(options, callback) { Fullnode.prototype.createWallet = function createWallet(options, callback) {
var self = this; var self = this;
callback = utils.ensure(callback); callback = utils.ensure(callback);

View File

@ -245,6 +245,10 @@ HTTPServer.prototype.listen = function listen(port, host, callback) {
}); });
}; };
HTTPServer.prototype.close = function close(callback) {
this.server.close(callback);
};
/** /**
* Helpers * Helpers
*/ */

View File

@ -421,6 +421,11 @@ NodeServer.prototype.open = function open(callback) {
this.once('open', callback); this.once('open', callback);
}; };
NodeServer.prototype.close =
NodeServer.prototype.destroy = function destroy(callback) {
this.server.close(callback);
};
NodeServer.prototype._initIO = function _initIO() { NodeServer.prototype._initIO = function _initIO() {
var self = this; var self = this;

View File

@ -127,6 +127,11 @@ Mempool.prototype.open = function open(callback) {
return this.once('open', callback); return this.once('open', callback);
}; };
Mempool.prototype.close =
Mempool.prototype.destroy = function destroy(callback) {
this.db.close(utils.ensure(callback));
};
Mempool.prototype.addBlock = function addBlock(block, callback, force) { Mempool.prototype.addBlock = function addBlock(block, callback, force) {
var self = this; var self = this;
var unlock = this._lock(addBlock, [block, callback], force); var unlock = this._lock(addBlock, [block, callback], force);

View File

@ -649,9 +649,6 @@ MTX.prototype.addOutput = function addOutput(obj, value) {
this.outputs.push(output); this.outputs.push(output);
if (options.script)
output.script = options.script.clone();
this.scriptOutput(this.outputs.length - 1, options); this.scriptOutput(this.outputs.length - 1, options);
return this; return this;
@ -670,7 +667,7 @@ MTX.prototype.scriptOutput = function scriptOutput(index, options) {
assert(output); assert(output);
if (options.script) if (options.script)
output.script = options.script; output.script = options.script.clone();
else else
output.script = Script.createOutputScript(options); output.script = Script.createOutputScript(options);
}; };
@ -955,7 +952,7 @@ MTX.prototype.fill = function fill(coins, options) {
} }
assert(coins); assert(coins);
assert(options.changeAddress); assert(options.changeAddress, '`changeAddress` is required.');
result = this.selectCoins(coins, options); result = this.selectCoins(coins, options);

View File

@ -295,17 +295,19 @@ Pool.prototype.getHeaders = function getHeaders(peer, top, stop, callback) {
}); });
}; };
Pool.prototype.startServer = function startServer() { Pool.prototype.startServer = function startServer(callback) {
var self = this; var self = this;
var net; var net;
callback = utils.ensure(callback);
if (bcoin.isBrowser) if (bcoin.isBrowser)
return; return utils.nextTick(callback);
net = require('n' + 'et'); net = require('n' + 'et');
if (!this.options.listen) if (!this.options.listen)
return; return utils.nextTick(callback);
assert(!this.server); assert(!this.server);
@ -322,17 +324,19 @@ Pool.prototype.startServer = function startServer() {
data.address, data.port); data.address, data.port);
}); });
this.server.listen(network.port, '0.0.0.0'); this.server.listen(network.port, '0.0.0.0', callback);
}; };
Pool.prototype.stopServer = function stopServer() { Pool.prototype.stopServer = function stopServer(callback) {
callback = utils.ensure(callback);
if (bcoin.isBrowser) if (bcoin.isBrowser)
return; return utils.nextTick(callback);
if (!this.server) if (!this.server)
return; return utils.nextTick(callback);
this.server.close(); this.server.close(callback);
delete this.server; delete this.server;
}; };
@ -1706,29 +1710,42 @@ Pool.prototype.broadcast = function broadcast(msg, callback) {
return e; return e;
}; };
Pool.prototype.destroy = function destroy() { Pool.prototype.close =
Pool.prototype.destroy = function destroy(callback) {
callback = utils.ensure(callback);
if (this.destroyed) if (this.destroyed)
return; return utils.nextTick(callback);
this.destroyed = true; this.destroyed = true;
if (this.peers.load) this.stopSync();
this.peers.load.destroy();
this.inv.list.forEach(function(entry) { this.inv.list.forEach(function(entry) {
clearTimeout(entry.timer); clearTimeout(entry.timer);
entry.timer = null; entry.timer = null;
}); });
this.peers.pending.slice().forEach(function(peer) { Object.keys(this.request.map).forEach(function(hash) {
peer.destroy(); this.request.map[hash].finish();
}); }, this);
if (this.peers.load)
this.peers.load.destroy();
this.peers.regular.slice().forEach(function(peer) { this.peers.regular.slice().forEach(function(peer) {
peer.destroy(); peer.destroy();
}); });
this.stopServer(); this.peers.pending.slice().forEach(function(peer) {
peer.destroy();
});
this.peers.leeches.slice().forEach(function(peer) {
peer.destroy();
});
this.stopServer(callback);
}; };
Pool.prototype.getPeer = function getPeer(addr) { Pool.prototype.getPeer = function getPeer(addr) {

View File

@ -182,6 +182,8 @@ exports.opcodes = {
OP_INVALIDOPCODE: 0xff OP_INVALIDOPCODE: 0xff
}; };
Object.freeze(exports.opcodes);
exports.opcodesByVal = new Array(256); exports.opcodesByVal = new Array(256);
Object.keys(exports.opcodes).forEach(function(name) { Object.keys(exports.opcodes).forEach(function(name) {
var val = exports.opcodes[name]; var val = exports.opcodes[name];

View File

@ -11,6 +11,9 @@ var utils = require('./utils');
var assert = utils.assert; var assert = utils.assert;
var BufferWriter = require('./writer'); var BufferWriter = require('./writer');
var opcodes = constants.opcodes; var opcodes = constants.opcodes;
var STACK_TRUE = new Buffer([1]);
var STACK_FALSE = new Buffer([]);
var STACK_NEGATE = new Buffer([0xff]);
function Witness(items) { function Witness(items) {
if (!(this instanceof Witness)) if (!(this instanceof Witness))
@ -103,11 +106,11 @@ Witness.fromString = function fromString(items) {
op = items[i]; op = items[i];
if (op === '-1' || op === '1negate') { if (op === '-1' || op === '1negate') {
op = new Buffer([0xff]); op = STACK_NEGATE;
} else if (op === '0' || op === 'false') { } else if (op === '0' || op === 'false') {
op = new Buffer([]); op = STACK_FALSE;
} else if (op === 'true') { } else if (op === 'true') {
op = new Buffer([1]); op = STACK_TRUE;
} else if (+op >= 1 && +op <= 16) { } else if (+op >= 1 && +op <= 16) {
op = new Buffer([+op]); op = new Buffer([+op]);
} else { } else {
@ -148,11 +151,11 @@ Witness.fromSymbolic = function fromSymbolic(items) {
op = op.slice(3); op = op.slice(3);
if (+op === -1) if (+op === -1)
op = new Buffer([0xff]); op = STACK_NEGATE;
else if (+op === 0 || op === 'false') else if (+op === 0 || op === 'false')
op = new Buffer([]); op = STACK_FALSE;
else if (+op === 1 || op === 'true') else if (+op === 1 || op === 'true')
op = new Buffer([1]); op = STACK_TRUE;
else if (+op >= 1 && +op <= 16) else if (+op >= 1 && +op <= 16)
op = new Buffer([+op]); op = new Buffer([+op]);
else else
@ -573,7 +576,7 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version
} }
if (op === opcodes.OP_0) { if (op === opcodes.OP_0) {
stack.push(new Buffer([])); stack.push(STACK_FALSE);
continue; continue;
} }
@ -597,7 +600,7 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version
break; break;
} }
case opcodes.OP_1NEGATE: { case opcodes.OP_1NEGATE: {
stack.push(new Buffer([0xff])); stack.push(STACK_NEGATE);
break; break;
} }
case opcodes.OP_IF: case opcodes.OP_IF:
@ -752,7 +755,7 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version
break; break;
case opcodes.OP_ABS: case opcodes.OP_ABS:
if (n.cmpn(0) < 0) if (n.cmpn(0) < 0)
n = n.neg(); n.ineg();
break; break;
case opcodes.OP_NOT: case opcodes.OP_NOT:
n = n.cmpn(0) === 0; n = n.cmpn(0) === 0;
@ -860,7 +863,7 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version
n2 = Script.num(stack.pop(), flags); n2 = Script.num(stack.pop(), flags);
n1 = Script.num(stack.pop(), flags); n1 = Script.num(stack.pop(), flags);
val = n2.cmp(n1) <= 0 && n1.cmp(n3) < 0; val = n2.cmp(n1) <= 0 && n1.cmp(n3) < 0;
stack.push(val.cmpn(0) !== 0 ? new Buffer([1]) : new Buffer([])); stack.push(val.cmpn(0) !== 0 ? STACK_TRUE : STACK_FALSE);
break; break;
} }
@ -909,7 +912,7 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version
if (!res) if (!res)
throw new ScriptError('Equal verification failed.', op, ip); throw new ScriptError('Equal verification failed.', op, ip);
} else { } else {
stack.push(res ? new Buffer([1]) : new Buffer([])); stack.push(res ? STACK_TRUE : STACK_FALSE);
} }
break; break;
} }
@ -942,7 +945,7 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version
if (!res) if (!res)
throw new ScriptError('Signature verification failed.', op, ip); throw new ScriptError('Signature verification failed.', op, ip);
} else { } else {
stack.push(res ? new Buffer([1]) : new Buffer([])); stack.push(res ? STACK_TRUE : STACK_FALSE);
} }
break; break;
@ -1023,7 +1026,7 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version
if (!res) if (!res)
throw new ScriptError('Signature verification failed.', op, ip); throw new ScriptError('Signature verification failed.', op, ip);
} else { } else {
stack.push(res ? new Buffer([1]) : new Buffer([])); stack.push(res ? STACK_TRUE : STACK_FALSE);
} }
break; break;
@ -1236,7 +1239,7 @@ Script.array = function(value) {
} }
if (value.cmpn(0) === 0) if (value.cmpn(0) === 0)
return new Buffer([]); return STACK_FALSE;
return value.toBuffer('le'); return value.toBuffer('le');
}; };
@ -1270,7 +1273,7 @@ Script.checkPush = function checkPush(value, flags) {
return false; return false;
if (value.length <= 75) if (value.length <= 75)
return pushdata.opcode == null && pushdata.len === value.length; return pushdata.opcode == null && pushdata.size === value.length;
if (value.length <= 255) if (value.length <= 255)
return pushdata.opcode === opcodes.OP_PUSHDATA1; return pushdata.opcode === opcodes.OP_PUSHDATA1;
@ -1859,7 +1862,7 @@ Script.isMultisigInput = function isMultisigInput(code, keys, isWitness) {
if (!Script.isDummy(code[0])) if (!Script.isDummy(code[0]))
return false; return false;
} else { } else {
if (code[0] !== 0) if (code[0] !== opcodes.OP_0)
return false; return false;
} }
@ -1991,11 +1994,11 @@ Script.isDummy = function isDummy(data) {
return data.length === 0; return data.length === 0;
}; };
Script.isZero = function isZero(data) { Script.isZero = function isZero(op) {
if (data === 0) if (op === opcodes.OP_0)
return true; return true;
return Script.isDummy(data); return Script.isDummy(op);
}; };
Script.isData = function isData(data) { Script.isData = function isData(data) {
@ -2234,13 +2237,16 @@ Script.format = function format(code) {
if (Buffer.isBuffer(chunk)) if (Buffer.isBuffer(chunk))
return '[' + utils.toHex(chunk) + ']'; return '[' + utils.toHex(chunk) + ']';
if (typeof chunk === 'number') { assert(typeof chunk === 'number');
if (constants.opcodeByVal[chunk])
return constants.opcodesByVal[chunk].slice(3).toLowerCase();
return chunk;
}
return chunk; if (constants.opcodeByVal[chunk])
return constants.opcodesByVal[chunk];
chunk = chunk.toString(16);
if (chunk.length < 2)
chunk = '0' + chunk;
return 'UNKNOWN(' + chunk + ')';
}).join(' '); }).join(' ');
}; };
@ -2298,9 +2304,9 @@ Script.prototype.getArgs = function getArgs() {
return 2; return 2;
if (this.isMultisig()) { if (this.isMultisig()) {
keys = this.code.slice(1, -2); keys = this.code.length - 3;
m = Script.getSmall(this.code[0]); m = Script.getSmall(this.code[0]);
if (keys.length < 1 || m < 1) if (keys < 1 || m < 1)
return -1; return -1;
return m + 1; return m + 1;
} }
@ -2367,6 +2373,13 @@ Script.fromString = function fromString(code) {
return new Script(code); return new Script(code);
}; };
Script.prototype.getSmall = function getSmall(i) {
if (i < 0)
i = this.code.length + i;
return Script.getSmall(this.code[i]);
};
Script.getSmall = function getSmall(op) { Script.getSmall = function getSmall(op) {
if (typeof op !== 'number') if (typeof op !== 'number')
return null; return null;
@ -2595,17 +2608,17 @@ Script.verifyProgram = function verifyProgram(witness, output, flags, tx, i) {
}; };
Script.concat = function concat(scripts) { Script.concat = function concat(scripts) {
var s = []; var code = [];
var i; var i;
s = s.concat(scripts[0].code); code = code.concat(scripts[0].code);
for (i = 1; i < scripts.length; i++) { for (i = 1; i < scripts.length; i++) {
s.push(opcodes.OP_CODESEPARATOR); code.push(opcodes.OP_CODESEPARATOR);
s = s.concat(scripts[i].code); code = code.concat(scripts[i].code);
} }
return s; return code;
}; };
Script.checksig = function checksig(msg, sig, key, flags) { Script.checksig = function checksig(msg, sig, key, flags) {
@ -2646,7 +2659,7 @@ Script.sign = function sign(msg, key, type) {
Script.decode = function decode(buf) { Script.decode = function decode(buf) {
var code = []; var code = [];
var off = 0; var off = 0;
var op, len; var op, size;
assert(Buffer.isBuffer(buf)); assert(Buffer.isBuffer(buf));
@ -2667,7 +2680,7 @@ Script.decode = function decode(buf) {
if (off > buf.length) { if (off > buf.length) {
utils.hidden(code[code.length - 1], 'pushdata', { utils.hidden(code[code.length - 1], 'pushdata', {
opcode: null, opcode: null,
len: op size: op
}); });
} }
continue; continue;
@ -2679,36 +2692,36 @@ Script.decode = function decode(buf) {
} }
if (op === opcodes.OP_PUSHDATA1) { if (op === opcodes.OP_PUSHDATA1) {
len = buf[off]; size = buf[off];
off += 1; off += 1;
code.push(buf.slice(off, off + len)); code.push(buf.slice(off, off + size));
off += len; off += size;
if (len <= 0x4b || off > buf.length) { if (size <= 0x4b || off > buf.length) {
utils.hidden(code[code.length - 1], 'pushdata', { utils.hidden(code[code.length - 1], 'pushdata', {
opcode: op, opcode: op,
len: len size: size
}); });
} }
} else if (op === opcodes.OP_PUSHDATA2) { } else if (op === opcodes.OP_PUSHDATA2) {
len = utils.readU16(buf, off); size = utils.readU16(buf, off);
off += 2; off += 2;
code.push(buf.slice(off, off + len)); code.push(buf.slice(off, off + size));
off += len; off += size;
if (len <= 0xff || off > buf.length) { if (size <= 0xff || off > buf.length) {
utils.hidden(code[code.length - 1], 'pushdata', { utils.hidden(code[code.length - 1], 'pushdata', {
opcode: op, opcode: op,
len: len size: size
}); });
} }
} else if (op === opcodes.OP_PUSHDATA4) { } else if (op === opcodes.OP_PUSHDATA4) {
len = utils.readU32(buf, off); size = utils.readU32(buf, off);
off += 4; off += 4;
code.push(buf.slice(off, off + len)); code.push(buf.slice(off, off + size));
off += len; off += size;
if (len <= 0xffff || off > buf.length) { if (size <= 0xffff || off > buf.length) {
utils.hidden(code[code.length - 1], 'pushdata', { utils.hidden(code[code.length - 1], 'pushdata', {
opcode: op, opcode: op,
len: len size: size
}); });
} }
} else { } else {
@ -2735,19 +2748,19 @@ Script.encode = function encode(code) {
// may have been decoded from before. // may have been decoded from before.
if (op.pushdata) { if (op.pushdata) {
if (op.pushdata.opcode === null) { if (op.pushdata.opcode === null) {
p.writeU8(op.pushdata.len); p.writeU8(op.pushdata.size);
p.writeBytes(op); p.writeBytes(op);
} else if (op.pushdata.opcode === opcodes.OP_PUSHDATA1) { } else if (op.pushdata.opcode === opcodes.OP_PUSHDATA1) {
p.writeU8(opcodes.OP_PUSHDATA1); p.writeU8(opcodes.OP_PUSHDATA1);
p.writeU8(op.pushdata.len); p.writeU8(op.pushdata.size);
p.writeBytes(op); p.writeBytes(op);
} else if (op.pushdata.opcode === opcodes.OP_PUSHDATA2) { } else if (op.pushdata.opcode === opcodes.OP_PUSHDATA2) {
p.writeU8(opcodes.OP_PUSHDATA2); p.writeU8(opcodes.OP_PUSHDATA2);
p.writeU16(op.pushdata.len); p.writeU16(op.pushdata.size);
p.writeBytes(op); p.writeBytes(op);
} else if (op.pushdata.opcode === opcodes.OP_PUSHDATA4) { } else if (op.pushdata.opcode === opcodes.OP_PUSHDATA4) {
p.writeU8(opcodes.OP_PUSHDATA4); p.writeU8(opcodes.OP_PUSHDATA4);
p.writeU32(op.pushdata.len); p.writeU32(op.pushdata.size);
p.writeBytes(op); p.writeBytes(op);
} }
continue; continue;
@ -2756,15 +2769,6 @@ Script.encode = function encode(code) {
if (op.length === 0) { if (op.length === 0) {
p.writeU8(opcodes.OP_0); p.writeU8(opcodes.OP_0);
} else if (op.length <= 0x4b) { } else if (op.length <= 0x4b) {
if (op.length === 1) {
if (op[0] === 0xff) {
p.writeU8(opcodes.OP_1NEGATE);
continue;
} else if (op[0] >= 0 && op[0] <= 16) {
p.writeU8(op[0] === 0 ? 0 : op[0] + 0x50);
continue;
}
}
p.writeU8(op.length); p.writeU8(op.length);
p.writeBytes(op); p.writeBytes(op);
} else if (op.length <= 0xff) { } else if (op.length <= 0xff) {

View File

@ -176,6 +176,12 @@ WalletDB.prototype.open = function open(callback) {
this.once('open', callback); this.once('open', callback);
}; };
WalletDB.prototype.close =
WalletDB.prototype.destroy = function destroy(callback) {
callback = utils.ensure(callback);
this.db.close(callback);
};
WalletDB.prototype.syncOutputDepth = function syncOutputDepth(id, tx, callback) { WalletDB.prototype.syncOutputDepth = function syncOutputDepth(id, tx, callback) {
var self = this; var self = this;

View File

@ -143,4 +143,8 @@ describe('Wallet', function() {
}); });
}); });
}); });
it('should destroy pool', function(cb) {
node.close(cb);
});
}); });