Skip to content

Commit

Permalink
Merge pull request #8 from QuickBrownFoxLabs/networkhps
Browse files Browse the repository at this point in the history
Networkhps
  • Loading branch information
bogrod authored Mar 23, 2018
2 parents 176d802 + 00536d6 commit 2eaf561
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 19 deletions.
1 change: 0 additions & 1 deletion app/controllers/pqstats.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ module.exports.getPqStats = function (req, res, next) {
return;
};
StatsDb.getPqStats(function (error, stats) {
console.log("STATS", stats);
if (error) {
console.log("err", error);
return common.handleErrors(error, res);
Expand Down
3 changes: 3 additions & 0 deletions app/controllers/status.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ exports.show = function(req, res) {
case 'getTicketInfo':
statusObject.getTicketInfo(returnJsonp);
break;
case 'gethps':
statusObject.getHashPerSeconds(returnJsonp);
break;
case 'getInfo':
default:
statusObject.getInfo(returnJsonp);
Expand Down
9 changes: 9 additions & 0 deletions app/models/Status.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ var RpcClient = bitcore.RpcClient;
var config = require('../../config/config');
var rpc = new RpcClient(config.bitcoind);
var bDb = require('../../lib/BlockDb').default();
var StatsDb = require('../../lib/StatsDb');

function Status() {}

Expand Down Expand Up @@ -172,4 +173,12 @@ Status.prototype.getLastBlockHash = function (next) {
});
};

Status.prototype.getHashPerSeconds = function (next) {
var self = this;
StatsDb.getHashPerSecondsOverTime(function (err, results) {
self.networkHashps = results;
next(err);
});
}

module.exports = require('soop')(Status);
2 changes: 2 additions & 0 deletions config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ var enableEmailstore = process.env.ENABLE_EMAILSTORE === 'true';
var loggerLevel = process.env.LOGGER_LEVEL || 'info';
var enableHTTPS = process.env.ENABLE_HTTPS === 'true';
var enableCurrencyRates = process.env.ENABLE_CURRENCYRATES === 'true';
var hpsInterval = process.env.STATS_HPS_INTERVAL || 10;

if (!fs.existsSync(db)) {
mkdirp.sync(db);
Expand Down Expand Up @@ -173,4 +174,5 @@ module.exports = {
safeConfirmations: safeConfirmations, // PLEASE NOTE THAT *FULL RESYNC* IS NEEDED TO CHANGE safeConfirmations
ignoreCache: ignoreCache,
forceRPCsync: forceRPCsync,
hpsInterval: hpsInterval
};
24 changes: 20 additions & 4 deletions lib/BlockDb.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,28 @@ BlockDb.prototype._changeBlockHeight = function (hash, height, cb) {
});
};

BlockDb.prototype.setBlockMain = function (hash, height, cb) {
this._changeBlockHeight(hash, height, cb);
BlockDb.prototype.setBlockMain = function (hash, height, done) {
var self = this;
async.parallel([
function (cb) {
self._changeBlockHeight(hash, height, cb);
},
function (cb) {
StatsDb.changeBlockHeight(hash, height, cb);
}
], done);
};

BlockDb.prototype.setBlockNotMain = function (hash, cb) {
this._changeBlockHeight(hash, -1, cb);
BlockDb.prototype.setBlockNotMain = function (hash, done) {
var self = this;
async.parallel([
function (cb) {
self._changeBlockHeight(hash, -1, cb);
},
function (cb) {
StatsDb.changeBlockHeight(hash, -1, cb);
}
], done);
};

// adds a block (and its txs). Does not update Next pointer in
Expand Down
13 changes: 13 additions & 0 deletions lib/PeerSync.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ var PeerManager = bitcore.PeerManager;
var config = require('../config/config');
var networks = bitcore.networks;
var sockets = require('../app/controllers/socket.js');
var StatsDb = require('./StatsDb');

var peerdb_fn = 'peerdb.json';

var getNetworkHashpsIn = config.hpsInterval;

function PeerSync(opts) {
opts = opts|| {};
this.shouldBroadcast = opts.shouldBroadcast;
Expand Down Expand Up @@ -85,6 +88,16 @@ PeerSync.prototype.handleBlock = function(info) {
var blockHash = bitcoreUtil.formatHashFull(block.calcHash());
self.log('[p2p_sync] Handle block: %s (allowReorgs: %s)', blockHash, self.allowReorgs);

if(getNetworkHashpsIn === 0) {
StatsDb.saveNetworkHashPerSeconds(function (err) {
if(err) {
console.error(err);
}
})
} else {
getNetworkHashpsIn--;
}

var tx_hashes = block.txs.map(function(tx) {
return bitcoreUtil.formatHashFull(tx.hash);
});
Expand Down
10 changes: 10 additions & 0 deletions lib/Rpc.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,16 @@ Rpc.verifyMessage = function(address, signature, message, cb) {
});
};

Rpc.getNetworkHashps = function(blocks, height, cb) {
var self = this;
bitcoreRpc.getNetworkHashps(blocks, height, function (err, message) {
if(err) {
return cb(err);
}
cb(null, message.result);
});
}

module.exports = require('soop')(Rpc);


90 changes: 76 additions & 14 deletions lib/StatsDb.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,19 @@ function init(initDone) {
}
async.parallel([
function (pCb) {
db.run('create table if not exists blocks (height integer primary key, hash text, minedAt integer)', pCb);
db.run('create table if not exists blocks (height integer, hash text primary key, minedAt integer)', pCb);
},
function (pCb) {
db.run('create table if not exists transactions (id text primary key, block text, time integer, blocktime integer)', pCb);
db.run('create table if not exists transactions (id text primary key, block text)', pCb);
},
function (pCb) {
db.run('create table if not exists vin (id text primary key, tx text, from_tx text, vout_index integer)', pCb);
},
function (pCb) {
db.run('create table if not exists vout (id text primary key, tx text, address text, amount real, nindex integer)', pCb);
},
function (pCb) {
db.run('create table if not exists hashperseconds (timestamp int, hashperseconds int)', pCb);
}
], initDone);
});
Expand All @@ -40,7 +43,7 @@ function saveBlock(block, cb) {
db.run('insert or replace into blocks (height, hash, minedAt) values ($height, $hash, $minedAt)', {
$height: block.height,
$hash: block.hash,
$minedAt: block.time
$minedAt: block.time || Math.floor(new Date().getTime() / 1000)
}, cb);
}

Expand Down Expand Up @@ -94,7 +97,7 @@ function saveVout(tx, vout, cb) {
)
}

function saveTx(tx, cb) {
function saveTx(blockhash, tx, cb) {
async.waterfall([
function (wCb) {
Rpc.getTxInfo(tx, wCb);
Expand All @@ -106,11 +109,9 @@ function saveTx(tx, cb) {
[
function (pCb) {
db.run(
'insert or replace into transactions (id, block, time, blocktime) values ($id, $block, $time, $blocktime)', {
'insert or replace into transactions (id, block) values ($id, $block)', {
$id: txInfo.txid,
$block: txInfo.blockhash,
$time: txInfo.time,
$blocktime: txInfo.blocktime
$block: blockhash
},
pCb
)
Expand All @@ -128,12 +129,47 @@ function saveTx(tx, cb) {
], cb);
}

function processTxs(txs, cb) {
async.mapLimit(txs, CONCURRENT_LIMIT, saveTx, cb);
function processTxs(block, txs, cb) {
async.mapLimit(txs, CONCURRENT_LIMIT, function (tx, mcb) {
saveTx(block, tx, mcb)
}, cb);
}

module.exports.init = init;

module.exports.changeBlockHeight = function (block, height, done) {
if (height > 0) {
//update the block
db.run("update blocks set height = $height where hash = $hash", {
$hash: block,
$height: height
}, done);
} else {
async.series([
function (cb) {
db.run("delete from vin where tx in (select id from transactions where block = $hash)", {
$hash: block
}, cb);
},
function (cb) {
db.run("delete from vout where tx in (select id from transactions where block = $hash)", {
$hash: block
}, cb);
},
function (cb) {
db.run("delete from transactions where block = $hash", {
$hash: block
}, cb);
},
function (cb) {
db.run("delete from blocks where hash = $hash", {
$hash: block
}, cb)
}
], done);
}
}

module.exports.processBlock = function (block, cb) {
if (block.height === 0) { //the transaction here doesn't really exist?
process.nextTick(cb);
Expand All @@ -144,7 +180,7 @@ module.exports.processBlock = function (block, cb) {
saveBlock(block, sCb);
},
function (sCb) {
processTxs(block.tx, sCb)
processTxs(block.hash, block.tx, sCb)
}
], function (error) {
if (error) {
Expand All @@ -160,10 +196,10 @@ module.exports.getPqStats = function (cb) {
var tsYesterday = ts - (24 * 3600);
async.parallel([
function (pCb) {
db.all("select count(distinct t.id) as totalPqTx from transactions t inner join vout o on t.id = o.tx where (o.address like 'Tb%' or o.address like 'Ta%' or o.address like 'Hb%') and t.blocktime >= " + tsYesterday, pCb)
db.all("select count(distinct t.id) as totalPqTx from transactions t inner join blocks b on b.hash = t.block inner join vout o on t.id = o.tx where (o.address like 'Tb%' or o.address like 'Ta%' or o.address like 'Hb%') and b.minedAt >= " + tsYesterday, pCb)
},
function (pCb) {
db.all("select count(distinct id) as totalTx from transactions where blocktime >= " + tsYesterday, pCb);
db.all("select count(distinct id) as totalTx from transactions t inner join blocks b on b.hash = t.block where b.minedAt >= " + tsYesterday, pCb);
},
function (pCb) {
db.all("select sum(o.amount) as totalPqHx from vout o outer left join vin i on o.tx = i.from_tx and o.nindex = i.vout_index where i.id is null and (o.address like 'Tb%' or o.address like 'Ta%' or o.address like 'Hb%')", pCb);
Expand All @@ -179,9 +215,35 @@ module.exports.getPqStats = function (cb) {
var stats = {
pqTxCount24h: rows[0][0].totalPqTx,
totalTxCount24h: rows[1][0].totalTx,
pqHx: rows[2][0].totalPqHx,
pqHx: rows[2][0].totalPqHx || 0,
totalHx: rows[3][0].totalHx
}
cb(null, stats);
});
}

module.exports.saveNetworkHashPerSeconds = function (done) {
console.log('saving network hash per seconds to stats db');
async.waterfall([
function (cb) {
Rpc.getNetworkHashps(config.hpsInterval, -1, cb);
},
function (hps, cb) {
console.log("HPS", hps);
db.run('insert into hashperseconds (timestamp, hashperseconds) values ($time, $hps)', {
$time: Math.round(new Date().getTime() / 1000),
$hps: hps
}, cb)
}
], function (err) {
if (err) {
console.log('Error saving network has per seconds:', err);
return done(err);
}
done();
});
}

module.exports.getHashPerSecondsOverTime = function (cb) {
db.all('select * from hashperseconds', cb);
}

0 comments on commit 2eaf561

Please sign in to comment.