commit
47c5b9b336
12
.gitignore
vendored
12
.gitignore
vendored
@ -29,16 +29,10 @@ npm-debug.log
|
|||||||
.nodemonignore
|
.nodemonignore
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
db/txs/*
|
db/
|
||||||
db/txs
|
|
||||||
db/testnet/txs/*
|
|
||||||
db/testnet/txs
|
|
||||||
db/blocks/*
|
|
||||||
db/blocks
|
|
||||||
db/testnet/blocks/*
|
|
||||||
db/testnet/blocks
|
|
||||||
db/*
|
|
||||||
db-test/
|
db-test/
|
||||||
|
testnet-db/
|
||||||
|
db.bkp/
|
||||||
|
|
||||||
README.html
|
README.html
|
||||||
public
|
public
|
||||||
|
|||||||
@ -2,7 +2,15 @@ BitcoreHTTP:
|
|||||||
port: 8080
|
port: 8080
|
||||||
logging: true
|
logging: true
|
||||||
BitcoreNode:
|
BitcoreNode:
|
||||||
|
LevelUp: ./testnet-db
|
||||||
|
network: testnet
|
||||||
NetworkMonitor:
|
NetworkMonitor:
|
||||||
network: livenet
|
|
||||||
host: localhost
|
host: localhost
|
||||||
port: 8333
|
port: 18333
|
||||||
|
Reporter: none # none, simple, matrix
|
||||||
|
RPC:
|
||||||
|
user: user
|
||||||
|
pass: password
|
||||||
|
protocol: http
|
||||||
|
host: 127.0.0.1
|
||||||
|
port: 18332
|
||||||
|
|||||||
8
api/config/livenet.yml
Normal file
8
api/config/livenet.yml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
BitcoreHTTP:
|
||||||
|
port: 8080
|
||||||
|
logging: true
|
||||||
|
BitcoreNode:
|
||||||
|
NetworkMonitor:
|
||||||
|
network: livenet
|
||||||
|
host: localhost
|
||||||
|
port: 8333
|
||||||
8
api/config/testnet.yml
Normal file
8
api/config/testnet.yml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
BitcoreHTTP:
|
||||||
|
port: 8080
|
||||||
|
logging: true
|
||||||
|
BitcoreNode:
|
||||||
|
NetworkMonitor:
|
||||||
|
network: livenet
|
||||||
|
host: localhost
|
||||||
|
port: 8333
|
||||||
@ -98,6 +98,7 @@ BitcoreHTTP.prototype.onListening = function() {
|
|||||||
|
|
||||||
|
|
||||||
BitcoreHTTP.prototype.start = function() {
|
BitcoreHTTP.prototype.start = function() {
|
||||||
|
this.node.start();
|
||||||
this.server.listen(this.port);
|
this.server.listen(this.port);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
var chai = require('chai');
|
var chai = require('chai');
|
||||||
var should = chai.should();
|
var should = chai.should();
|
||||||
|
var sinon = require('sinon');
|
||||||
|
|
||||||
var EventEmitter = require('eventemitter2').EventEmitter2;
|
var EventEmitter = require('eventemitter2').EventEmitter2;
|
||||||
|
|
||||||
@ -19,6 +20,7 @@ describe('BitcoreHTTP', function() {
|
|||||||
var nodeMock;
|
var nodeMock;
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
nodeMock = new EventEmitter();
|
nodeMock = new EventEmitter();
|
||||||
|
nodeMock.start = sinon.spy();
|
||||||
});
|
});
|
||||||
describe('instantiates', function() {
|
describe('instantiates', function() {
|
||||||
it('from constructor', function() {
|
it('from constructor', function() {
|
||||||
|
|||||||
@ -18,7 +18,7 @@ describe('BitcoreHTTP v1 node routes', function() {
|
|||||||
nodeMock = new EventEmitter();
|
nodeMock = new EventEmitter();
|
||||||
nodeMock.status = {
|
nodeMock.status = {
|
||||||
sync: 0.75,
|
sync: 0.75,
|
||||||
peer_count: 8,
|
peerCount: 8,
|
||||||
version: 'test'
|
version: 'test'
|
||||||
};
|
};
|
||||||
nodeMock.getStatus = function() {
|
nodeMock.getStatus = function() {
|
||||||
|
|||||||
@ -5,9 +5,6 @@ BitcoreNode:
|
|||||||
host: localhost
|
host: localhost
|
||||||
port: 8333
|
port: 8333
|
||||||
Reporter: none # none, simple, matrix
|
Reporter: none # none, simple, matrix
|
||||||
BitcoreHTTP:
|
|
||||||
host: localhost
|
|
||||||
port: 8080
|
|
||||||
RPC:
|
RPC:
|
||||||
user: user
|
user: user
|
||||||
pass: password
|
pass: password
|
||||||
|
|||||||
@ -5,9 +5,6 @@ BitcoreNode:
|
|||||||
host: localhost
|
host: localhost
|
||||||
port: 8333
|
port: 8333
|
||||||
Reporter: none # none, simple, matrix
|
Reporter: none # none, simple, matrix
|
||||||
BitcoreHTTP:
|
|
||||||
host: localhost
|
|
||||||
port: 8080
|
|
||||||
RPC:
|
RPC:
|
||||||
user: user
|
user: user
|
||||||
pass: password
|
pass: password
|
||||||
|
|||||||
@ -5,9 +5,6 @@ BitcoreNode:
|
|||||||
host: localhost
|
host: localhost
|
||||||
port: 18333
|
port: 18333
|
||||||
Reporter: none # none, simple, matrix
|
Reporter: none # none, simple, matrix
|
||||||
BitcoreHTTP:
|
|
||||||
host: localhost
|
|
||||||
port: 8080
|
|
||||||
RPC:
|
RPC:
|
||||||
user: user
|
user: user
|
||||||
pass: password
|
pass: password
|
||||||
|
|||||||
@ -159,7 +159,7 @@ BlockChain.prototype.getBlockLocator = function() {
|
|||||||
$.checkState(!_.isUndefined(this.height[this.tip]));
|
$.checkState(!_.isUndefined(this.height[this.tip]));
|
||||||
|
|
||||||
var result = [];
|
var result = [];
|
||||||
var currentHeight = this.height[this.tip];
|
var currentHeight = this.getCurrentHeight();
|
||||||
var exponentialBackOff = 1;
|
var exponentialBackOff = 1;
|
||||||
for (var i = 0; i < 10; i++) {
|
for (var i = 0; i < 10; i++) {
|
||||||
if (currentHeight >= 0) {
|
if (currentHeight >= 0) {
|
||||||
@ -174,4 +174,8 @@ BlockChain.prototype.getBlockLocator = function() {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BlockChain.prototype.getCurrentHeight = function() {
|
||||||
|
return this.height[this.tip];
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = BlockChain;
|
module.exports = BlockChain;
|
||||||
|
|||||||
@ -38,7 +38,10 @@ NetworkMonitor.prototype.setupPeer = function(peer) {
|
|||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
peer.on('ready', function() {
|
peer.on('ready', function() {
|
||||||
self.emit('ready');
|
self.emit('ready', self.maxHeight);
|
||||||
|
});
|
||||||
|
peer.on('version', function(m) {
|
||||||
|
self.maxHeight = m.startHeight;
|
||||||
});
|
});
|
||||||
peer.on('inv', function(m) {
|
peer.on('inv', function(m) {
|
||||||
self.emit('inv', m.inventory);
|
self.emit('inv', m.inventory);
|
||||||
@ -73,7 +76,6 @@ NetworkMonitor.prototype.requestBlocks = function(locator) {
|
|||||||
_.isString(locator[0]), 'start must be a block hash string array');
|
_.isString(locator[0]), 'start must be a block hash string array');
|
||||||
this.peer.sendMessage(this.messages.GetBlocks({
|
this.peer.sendMessage(this.messages.GetBlocks({
|
||||||
starts: locator,
|
starts: locator,
|
||||||
//stop: '000000002c05cc2e78923c34df87fd108b22221ac6076c18f3ade378a4d915e9' // TODO: remove this!!!
|
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -87,6 +89,11 @@ NetworkMonitor.prototype.stop = function(reason) {
|
|||||||
console.log('Stopping network, reason:', reason);
|
console.log('Stopping network, reason:', reason);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NetworkMonitor.prototype.getConnectedPeers = function() {
|
||||||
|
// TODO: update when using Pool instead of Peer
|
||||||
|
return this.peer.status === Peer.STATUS.READY ? 1 : 0;
|
||||||
|
};
|
||||||
|
|
||||||
NetworkMonitor.prototype.abort = function(reason) {
|
NetworkMonitor.prototype.abort = function(reason) {
|
||||||
this.peer.disconnect();
|
this.peer.disconnect();
|
||||||
if (reason) {
|
if (reason) {
|
||||||
|
|||||||
39
lib/node.js
39
lib/node.js
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
var EventEmitter = require('eventemitter2').EventEmitter2;
|
var EventEmitter = require('eventemitter2').EventEmitter2;
|
||||||
|
var pjson = require('../package.json');
|
||||||
|
|
||||||
var bitcore = require('bitcore');
|
var bitcore = require('bitcore');
|
||||||
var _ = bitcore.deps._;
|
var _ = bitcore.deps._;
|
||||||
@ -36,7 +37,6 @@ var BitcoreNode = function(bus, networkMonitor, blockService, transactionService
|
|||||||
this.blockService = blockService;
|
this.blockService = blockService;
|
||||||
|
|
||||||
this.blockCache = {};
|
this.blockCache = {};
|
||||||
this.inventory = {}; // blockHash -> bool (has data)
|
|
||||||
this.initialize();
|
this.initialize();
|
||||||
};
|
};
|
||||||
util.inherits(BitcoreNode, EventEmitter);
|
util.inherits(BitcoreNode, EventEmitter);
|
||||||
@ -79,7 +79,8 @@ BitcoreNode.prototype.initialize = function() {
|
|||||||
var prevHeight = 0;
|
var prevHeight = 0;
|
||||||
var statTimer = 5 * 1000;
|
var statTimer = 5 * 1000;
|
||||||
setInterval(function() {
|
setInterval(function() {
|
||||||
console.log(process.memoryUsage().heapTotal / 1024 / 1024, 'mb used');
|
console.log('MB used:', process.memoryUsage().heapTotal / 1024 / 1024,
|
||||||
|
100 * self.getSyncProgress() + '% synced');
|
||||||
if (!self.blockchain) {
|
if (!self.blockchain) {
|
||||||
// not ready yet
|
// not ready yet
|
||||||
console.log('No blockchain yet');
|
console.log('No blockchain yet');
|
||||||
@ -100,9 +101,8 @@ BitcoreNode.prototype.initialize = function() {
|
|||||||
|
|
||||||
var prevHash = bitcore.util.buffer.reverse(block.header.prevHash).toString('hex');
|
var prevHash = bitcore.util.buffer.reverse(block.header.prevHash).toString('hex');
|
||||||
self.blockCache[block.hash] = block;
|
self.blockCache[block.hash] = block;
|
||||||
self.inventory[block.hash] = true;
|
|
||||||
if (!self.blockchain.hasData(prevHash)) {
|
if (!self.blockchain.hasData(prevHash)) {
|
||||||
self.requestFromTip();
|
self._requestFromTip();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var blockchainChanges = self.blockchain.proposeNewBlock(block);
|
var blockchainChanges = self.blockchain.proposeNewBlock(block);
|
||||||
@ -111,8 +111,6 @@ BitcoreNode.prototype.initialize = function() {
|
|||||||
block.height = self.blockchain.height[block.id];
|
block.height = self.blockchain.height[block.id];
|
||||||
block.work = self.blockchain.work[block.id];
|
block.work = self.blockchain.work[block.id];
|
||||||
|
|
||||||
//console.log('block', block.id, block.height);
|
|
||||||
|
|
||||||
return Promise.each(blockchainChanges.unconfirmed, function(hash) {
|
return Promise.each(blockchainChanges.unconfirmed, function(hash) {
|
||||||
return self.blockService.unconfirm(self.blockCache[hash]);
|
return self.blockService.unconfirm(self.blockCache[hash]);
|
||||||
})
|
})
|
||||||
@ -128,13 +126,6 @@ BitcoreNode.prototype.initialize = function() {
|
|||||||
delete self.blockCache[deleteHash];
|
delete self.blockCache[deleteHash];
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(function() {
|
|
||||||
// TODO: include this
|
|
||||||
if (false && _.size(self.inventory) && _.all(_.values(self.inventory))) {
|
|
||||||
self.inventory = {};
|
|
||||||
self.requestFromTip();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function(error) {
|
.catch(function(error) {
|
||||||
self.stop(error);
|
self.stop(error);
|
||||||
});
|
});
|
||||||
@ -155,9 +146,7 @@ BitcoreNode.prototype.start = function() {
|
|||||||
var self = this;
|
var self = this;
|
||||||
var genesis = bitcore.Block.fromBuffer(genesisBlocks[bitcore.Networks.defaultNetwork.name]);
|
var genesis = bitcore.Block.fromBuffer(genesisBlocks[bitcore.Networks.defaultNetwork.name]);
|
||||||
|
|
||||||
console.log('getting blockchain');
|
|
||||||
this.blockService.getBlockchain().then(function(blockchain) {
|
this.blockService.getBlockchain().then(function(blockchain) {
|
||||||
console.log('got blockchain', !!blockchain);
|
|
||||||
if (!blockchain) {
|
if (!blockchain) {
|
||||||
self.blockchain = new BlockChain();
|
self.blockchain = new BlockChain();
|
||||||
self.bus.process(genesis);
|
self.bus.process(genesis);
|
||||||
@ -173,7 +162,20 @@ BitcoreNode.prototype.stop = function(reason) {
|
|||||||
this.networkMonitor.abort(reason);
|
this.networkMonitor.abort(reason);
|
||||||
};
|
};
|
||||||
|
|
||||||
BitcoreNode.prototype.requestFromTip = function() {
|
BitcoreNode.prototype.getStatus = function() {
|
||||||
|
return Promise.resolve({
|
||||||
|
sync: this.getSyncProgress(),
|
||||||
|
peerCount: this.networkMonitor.getConnectedPeers(),
|
||||||
|
version: pjson.version,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
BitcoreNode.prototype.getSyncProgress = function() {
|
||||||
|
return !_.isUndefined(this.reportedMaxHeight) ?
|
||||||
|
(this.blockchain.getCurrentHeight() / this.reportedMaxHeight) : 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
BitcoreNode.prototype._requestFromTip = function() {
|
||||||
var locator = this.blockchain.getBlockLocator();
|
var locator = this.blockchain.getBlockLocator();
|
||||||
//console.log('requesting blocks, locator size:', locator.length);
|
//console.log('requesting blocks, locator size:', locator.length);
|
||||||
this.networkMonitor.requestBlocks(locator);
|
this.networkMonitor.requestBlocks(locator);
|
||||||
@ -181,8 +183,9 @@ BitcoreNode.prototype.requestFromTip = function() {
|
|||||||
|
|
||||||
BitcoreNode.prototype.sync = function() {
|
BitcoreNode.prototype.sync = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.networkMonitor.on('ready', function() {
|
this.networkMonitor.on('ready', function(reportedMaxHeight) {
|
||||||
self.requestFromTip();
|
self.reportedMaxHeight = reportedMaxHeight;
|
||||||
|
self._requestFromTip();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -475,7 +475,7 @@ BlockService.prototype.getBlockchain = function() {
|
|||||||
return self._getLatestHash()
|
return self._getLatestHash()
|
||||||
.then(function(tip) {
|
.then(function(tip) {
|
||||||
if (!tip) {
|
if (!tip) {
|
||||||
console.log('No tip found');
|
console.log('No tip found, syncing blockchain from genesis block');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
console.log('Tip is', tip);
|
console.log('Tip is', tip);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user