optimize performance and fix testnet
This commit is contained in:
parent
f2f5d7e807
commit
029e2ef999
16
config/testnet.yml
Normal file
16
config/testnet.yml
Normal file
@ -0,0 +1,16 @@
|
||||
BitcoreNode:
|
||||
LevelUp: ./testnet-db
|
||||
network: testnet
|
||||
NetworkMonitor:
|
||||
host: localhost
|
||||
port: 18333
|
||||
Reporter: none # none, simple, matrix
|
||||
BitcoreHTTP:
|
||||
host: localhost
|
||||
port: 8080
|
||||
RPC:
|
||||
user: user
|
||||
pass: password
|
||||
protocol: http
|
||||
host: 127.0.0.1
|
||||
port: 18332
|
||||
@ -9,13 +9,16 @@ var $ = bitcore.util.preconditions;
|
||||
var _ = bitcore.deps._;
|
||||
var p2p = require('bitcore-p2p');
|
||||
var Peer = p2p.Peer;
|
||||
var messages = new p2p.Messages();
|
||||
|
||||
function NetworkMonitor(eventBus, peer) {
|
||||
$.checkArgument(eventBus);
|
||||
$.checkArgument(peer);
|
||||
this.bus = eventBus;
|
||||
this.peer = peer;
|
||||
this.messages = new p2p.Messages({
|
||||
network: this.peer.network,
|
||||
magicNumber: this.peer.network.networkMagic.readUInt32LE(0)
|
||||
});
|
||||
this.setupPeer(peer);
|
||||
}
|
||||
util.inherits(NetworkMonitor, EventEmitter);
|
||||
@ -41,7 +44,7 @@ NetworkMonitor.prototype.setupPeer = function(peer) {
|
||||
peer.on('inv', function(m) {
|
||||
self.emit('inv', m.inventory);
|
||||
// TODO only ask for data if tx or block is unknown
|
||||
peer.sendMessage(messages.GetData(m.inventory));
|
||||
peer.sendMessage(self.messages.GetData(m.inventory));
|
||||
});
|
||||
peer.on('tx', function(m) {
|
||||
self.bus.process(m.transaction)
|
||||
@ -69,8 +72,7 @@ NetworkMonitor.prototype.requestBlocks = function(locator) {
|
||||
$.checkArgument(_.isArray(locator) &&
|
||||
_.isUndefined(locator[0]) ||
|
||||
_.isString(locator[0]), 'start must be a block hash string array');
|
||||
console.log('request blocks', locator);
|
||||
this.peer.sendMessage(messages.GetBlocks({
|
||||
this.peer.sendMessage(this.messages.GetBlocks({
|
||||
starts: locator,
|
||||
//stop: '000000002c05cc2e78923c34df87fd108b22221ac6076c18f3ade378a4d915e9' // TODO: remove this!!!
|
||||
}));
|
||||
|
||||
11
lib/node.js
11
lib/node.js
@ -76,6 +76,8 @@ BitcoreNode.prototype.initialize = function() {
|
||||
var self = this;
|
||||
|
||||
|
||||
var prevHeight = 0;
|
||||
var statTimer = 5 * 1000;
|
||||
setInterval(function() {
|
||||
if (!self.blockchain) {
|
||||
// not ready yet
|
||||
@ -83,8 +85,10 @@ BitcoreNode.prototype.initialize = function() {
|
||||
}
|
||||
var tipHash = self.blockchain.tip;
|
||||
var block = self.blockCache[tipHash];
|
||||
console.log('block', block.id, 'height', block.height);
|
||||
}, 5 * 1000);
|
||||
var delta = block.height - prevHeight;
|
||||
prevHeight = block.height;
|
||||
console.log(block.id, block.height, 'vel', delta * 1000 / statTimer, 'b/s');
|
||||
}, statTimer);
|
||||
|
||||
this.bus.register(bitcore.Block, function(block) {
|
||||
|
||||
@ -100,7 +104,8 @@ BitcoreNode.prototype.initialize = function() {
|
||||
// Annotate block with extra data from the chain
|
||||
block.height = self.blockchain.height[block.id];
|
||||
block.work = self.blockchain.work[block.id];
|
||||
console.log('>block', block.id, 'height', block.height);
|
||||
|
||||
//console.log('block', block.id, block.height);
|
||||
|
||||
return Promise.each(blockchainChanges.unconfirmed, function(hash) {
|
||||
return self.blockService.unconfirm(self.blockCache[hash]);
|
||||
|
||||
@ -200,7 +200,9 @@ BlockService.prototype.getLatest = function() {
|
||||
return self.getBlock(blockHash);
|
||||
|
||||
}).catch(LevelUp.errors.NotFoundError, function() {
|
||||
|
||||
return null;
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
@ -251,6 +253,7 @@ BlockService.prototype.confirm = function(block, ops) {
|
||||
//console.log(4);
|
||||
self._setBlockByTs(ops, block);
|
||||
|
||||
//console.log(4.1);
|
||||
self._setTip(ops, block);
|
||||
|
||||
//console.log(5);
|
||||
@ -471,23 +474,23 @@ BlockService.prototype.getBlockchain = function() {
|
||||
};
|
||||
|
||||
return self.database.getAsync(Index.tip)
|
||||
.catch(function(err) {
|
||||
if (err.notFound) {
|
||||
return undefined;
|
||||
}
|
||||
throw err;
|
||||
})
|
||||
.then(function(tip) {
|
||||
if (!tip) {
|
||||
console.log('No tip found');
|
||||
return;
|
||||
}
|
||||
console.log('Tip is', tip);
|
||||
blockchain.tip = tip;
|
||||
return fetchUnlessGenesis(tip).then(function() {
|
||||
return blockchain;
|
||||
.catch(function(err) {
|
||||
if (err.notFound) {
|
||||
return undefined;
|
||||
}
|
||||
throw err;
|
||||
})
|
||||
.then(function(tip) {
|
||||
if (!tip) {
|
||||
console.log('No tip found');
|
||||
return;
|
||||
}
|
||||
console.log('Tip is', tip);
|
||||
blockchain.tip = tip;
|
||||
return fetchUnlessGenesis(tip).then(function() {
|
||||
return blockchain;
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = BlockService;
|
||||
|
||||
@ -25,7 +25,7 @@ var _ = bitcore.deps._;
|
||||
var $ = bitcore.util.preconditions;
|
||||
|
||||
var NULLTXHASH = bitcore.util.buffer.emptyBuffer(32).toString('hex');
|
||||
var GENESISTX = '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b'
|
||||
var GENESISTX = '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b';
|
||||
|
||||
var helper = function(name) {
|
||||
return function(txId, output) {
|
||||
@ -50,15 +50,15 @@ var helperAddress = function(index) {
|
||||
};
|
||||
|
||||
var Index = {
|
||||
output: 'txo-', // txo-<txid>-<n> -> serialized Output
|
||||
spent: 'txs-', // txo-<txid>-<n>-<spend txid>-<m> -> block height of confirmation for spend
|
||||
address: 'txa-', // txa-<address>-<txid>-<n> -> Output
|
||||
output: 'txo-', // txo-<txid>-<n> -> serialized Output
|
||||
spent: 'txs-', // txo-<txid>-<n>-<spend txid>-<m> -> block height of confirmation for spend
|
||||
address: 'txa-', // txa-<address>-<txid>-<n> -> Output
|
||||
addressSpent: 'txas-', // txa-<address>-<txid>-<n> -> {
|
||||
// heightSpent: number, (may be -1 for unconfirmed tx)
|
||||
// spentTx: string, spentTxInputIndex: number, spendInput: Input
|
||||
// }
|
||||
transaction: 'btx-' // btx-<txid> -> block in main chain that confirmed the tx
|
||||
}
|
||||
// heightSpent: number, (may be -1 for unconfirmed tx)
|
||||
// spentTx: string, spentTxInputIndex: number, spendInput: Input
|
||||
// }
|
||||
transaction: 'btx-' // btx-<txid> -> block in main chain that confirmed the tx
|
||||
};
|
||||
|
||||
_.extend(Index, {
|
||||
getOutput: helper(Index.output),
|
||||
@ -76,7 +76,7 @@ _.extend(Index, {
|
||||
}
|
||||
});
|
||||
|
||||
function TransactionService (opts) {
|
||||
function TransactionService(opts) {
|
||||
opts = _.extend({}, opts);
|
||||
this.database = opts.database || Promise.promisifyAll(new LevelUp(config.get('LevelUp')));
|
||||
this.rpc = opts.rpc || Promise.promisifyAll(new RPC(config.get('RPC')));
|
||||
@ -91,7 +91,6 @@ TransactionService.transactionRPCtoBitcore = function(rpcResponse) {
|
||||
};
|
||||
|
||||
TransactionService.prototype.getTransaction = function(transactionId) {
|
||||
|
||||
var self = this;
|
||||
|
||||
if (transactionId === GENESISTX) {
|
||||
@ -106,27 +105,24 @@ TransactionService.prototype.getTransaction = function(transactionId) {
|
||||
};
|
||||
|
||||
TransactionService.prototype._confirmOutput = function(ops, block, transaction) {
|
||||
var txid = transaction.id;
|
||||
return function(output, index) {
|
||||
ops.push({
|
||||
type: 'put',
|
||||
key: Index.getOutput(transaction.id, index),
|
||||
key: Index.getOutput(txid, index),
|
||||
value: output.toJSON()
|
||||
});
|
||||
var address;
|
||||
// TODO: Move this logic to bitcore
|
||||
if (output.script.isPublicKeyOut()) {
|
||||
var hash = bitcore.crypto.Hash.sha256ripemd160(output.script.chunks[0].buf);
|
||||
address = new bitcore.Address(hash, bitcore.Networks.defaultNetwork, bitcore.Address.PayToPublicKeyHash);
|
||||
} else if (output.script.isPublicKeyHashOut() || output.script.isScriptHashOut()) {
|
||||
if (output.script.isPublicKeyHashOut() || output.script.isScriptHashOut()) {
|
||||
address = output.script.toAddress();
|
||||
}
|
||||
if (address) {
|
||||
var out4addr = output.toObject();
|
||||
out4addr.heightConfirmed = block.height;
|
||||
ops.push({
|
||||
type: 'put',
|
||||
key: Index.getOutputsForAddress(address, transaction.id, index),
|
||||
value: JSON.stringify(_.extend(output.toObject(), {
|
||||
heightConfirmed: block.height
|
||||
}))
|
||||
key: Index.getOutputsForAddress(address, txid, index),
|
||||
value: JSON.stringify(out4addr)
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -134,13 +130,14 @@ TransactionService.prototype._confirmOutput = function(ops, block, transaction)
|
||||
|
||||
TransactionService.prototype._confirmInput = function(ops, block, transaction) {
|
||||
var self = this;
|
||||
var txid = transaction.id;
|
||||
return function(input, index) {
|
||||
if (input.prevTxId.toString('hex') === NULLTXHASH) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
ops.push({
|
||||
type: 'put',
|
||||
key: Index.getOutput(transaction.id, index),
|
||||
key: Index.getOutput(txid, index),
|
||||
value: JSON.stringify(_.extend(input.toObject(), {
|
||||
heightConfirmed: block.height
|
||||
}))
|
||||
@ -151,15 +148,14 @@ TransactionService.prototype._confirmInput = function(ops, block, transaction) {
|
||||
}
|
||||
|
||||
return Promise.try(function() {
|
||||
return self._getAddressForInput(input)
|
||||
}).then(function(address) {
|
||||
var address = self._getAddressForInput(input);
|
||||
if (address) {
|
||||
ops.push({
|
||||
type: 'put',
|
||||
key: Index.getSpentOutputsForAddress(address, transaction.id, index),
|
||||
key: Index.getSpentOutputsForAddress(address, txid, index),
|
||||
value: JSON.stringify({
|
||||
heightSpent: block.height,
|
||||
spentTx: transaction.id,
|
||||
spentTx: txid,
|
||||
spentTxInputIndex: index,
|
||||
spendInput: input.toObject()
|
||||
})
|
||||
@ -171,29 +167,8 @@ TransactionService.prototype._confirmInput = function(ops, block, transaction) {
|
||||
|
||||
TransactionService.prototype._getAddressForInput = function(input) {
|
||||
var script = input.script;
|
||||
var self = this;
|
||||
|
||||
if (script.isPublicKeyHashIn()) {
|
||||
var hash = bitcore.crypto.Hash.sha256ripemd160(script.chunks[0].buf);
|
||||
return new bitcore.Address(
|
||||
hash, bitcore.Networks.defaultNetwork, bitcore.Address.PayToPublicKeyHash
|
||||
);
|
||||
} else if (script.isPublicKeyIn()) {
|
||||
/*
|
||||
return self.getTransaction(input.prevTxId.toString('hex')).then(function(transaction) {
|
||||
var outputScript = transaction.outputs[input.outputIndex].script;
|
||||
if (outputScript.isPublicKeyOut()) {
|
||||
return new bitcore.Address(
|
||||
bitcore.crypto.Hash.sha256ripemd160(outputScript.chunks[0].buf),
|
||||
bitcore.Networks.defaultNetwork, bitcore.Address.PayToPublicKeyHash
|
||||
);
|
||||
}
|
||||
return;
|
||||
});
|
||||
*/
|
||||
} else {
|
||||
return new bitcore.Script(script.chunks[script.chunks.length - 1]).toAddress();
|
||||
}
|
||||
// TODO: move this to bitcore
|
||||
return new bitcore.Script(script.chunks[script.chunks.length - 1]).toAddress();
|
||||
};
|
||||
|
||||
TransactionService.prototype._confirmTransaction = function(ops, block, transaction) {
|
||||
@ -203,11 +178,12 @@ TransactionService.prototype._confirmTransaction = function(ops, block, transact
|
||||
key: Index.getBlockForTransaction(transaction),
|
||||
value: block.id
|
||||
});
|
||||
return Promise.all(
|
||||
var confirmFunctions =
|
||||
_.map(transaction.outputs, self._confirmOutput(ops, block, transaction))
|
||||
.concat(
|
||||
_.map(transaction.inputs, self._confirmInput(ops, block, transaction))
|
||||
));
|
||||
.concat(
|
||||
_.map(transaction.inputs, self._confirmInput(ops, block, transaction))
|
||||
);
|
||||
return Promise.all(confirmFunctions);
|
||||
};
|
||||
|
||||
TransactionService.prototype._unconfirmTransaction = function(ops, block, transaction) {
|
||||
@ -219,9 +195,9 @@ TransactionService.prototype._unconfirmTransaction = function(ops, block, transa
|
||||
});
|
||||
return Promise.all(
|
||||
_.map(transaction.outputs, self._unconfirmOutput(ops, block, transaction))
|
||||
.concat(
|
||||
_.map(transaction.inputs, self._unconfirmInput(ops, block, transaction))
|
||||
));
|
||||
.concat(
|
||||
_.map(transaction.inputs, self._unconfirmInput(ops, block, transaction))
|
||||
));
|
||||
};
|
||||
|
||||
module.exports = TransactionService;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user