insight-ui-zcash/lib/BlockDb.js

200 lines
5.1 KiB
JavaScript
Raw Normal View History

2014-02-03 18:30:46 -08:00
'use strict';
require('classtool');
2014-02-05 08:02:51 -08:00
function spec(b) {
2014-02-03 18:30:46 -08:00
2014-02-08 05:57:37 -08:00
var TIMESTAMP_PREFIX = 'b-ts-'; // b-ts-<ts> => <hash>
var PREV_PREFIX = 'b-prev-'; // b-prev-<hash> => <prev_hash>
var NEXT_PREFIX = 'b-next-'; // b-next-<hash> => <next_hash>
var MAIN_PREFIX = 'b-main-'; // b-main-<hash> => 1/0
var TIP = 'b-tip-'; // last block on the chain
2014-02-03 18:30:46 -08:00
/**
* Module dependencies.
*/
var RpcClient = require('bitcore/RpcClient').class(),
util = require('bitcore/util/util'),
levelup = require('levelup'),
BitcoreBlock= require('bitcore/Block').class(),
2014-02-04 08:06:05 -08:00
config = require('../config/config');
2014-02-05 10:08:39 -08:00
var db = b.db || levelup(config.leveldb + '/blocks');
var rpc = b.rpc || new RpcClient(config.bitcoind);
2014-02-03 18:30:46 -08:00
2014-02-05 08:02:51 -08:00
var BlockDb = function() {
2014-02-05 06:23:41 -08:00
};
BlockDb.prototype.close = function(cb) {
2014-02-05 08:02:51 -08:00
db.close(cb);
2014-02-03 18:30:46 -08:00
};
BlockDb.prototype.drop = function(cb) {
var path = config.leveldb + '/blocks';
2014-02-05 08:02:51 -08:00
db.close(function() {
2014-02-04 08:06:05 -08:00
require('leveldown').destroy(path, function () {
2014-02-05 08:02:51 -08:00
db = levelup(path);
2014-02-04 08:06:05 -08:00
return cb();
});
2014-02-03 18:30:46 -08:00
});
};
2014-02-09 14:33:39 -08:00
// adds a block. Does not update Next pointer in
// the block prev to the new block, nor TIP pointer
2014-02-08 05:57:37 -08:00
//
2014-02-03 18:30:46 -08:00
BlockDb.prototype.add = function(b, cb) {
2014-02-08 05:57:37 -08:00
var time_key = TIMESTAMP_PREFIX +
2014-02-05 07:31:38 -08:00
( b.time || Math.round(new Date().getTime() / 1000) );
2014-02-03 18:30:46 -08:00
2014-02-08 05:57:37 -08:00
return db.batch()
2014-02-03 18:30:46 -08:00
.put(time_key, b.hash)
2014-02-08 05:57:37 -08:00
.put(MAIN_PREFIX + b.hash, 1)
.put(PREV_PREFIX + b.hash, b.previousblockhash)
2014-02-03 18:30:46 -08:00
.write(cb);
};
2014-02-08 05:57:37 -08:00
BlockDb.prototype.getTip = function(cb) {
db.get(TIP, function(err, val) {
return cb(err,val);
2014-02-03 22:22:58 -08:00
});
};
2014-02-09 14:33:39 -08:00
BlockDb.prototype.setTip = function(hash, cb) {
db.put(TIP, hash, function(err) {
return cb(err);
});
};
2014-02-04 08:06:05 -08:00
//mainly for testing
BlockDb.prototype.setPrev = function(hash, prevHash, cb) {
2014-02-08 05:57:37 -08:00
db.put(PREV_PREFIX + hash, prevHash, function(err) {
2014-02-04 08:06:05 -08:00
return cb(err);
});
};
BlockDb.prototype.getPrev = function(hash, cb) {
2014-02-08 05:57:37 -08:00
db.get(PREV_PREFIX + hash, function(err,val) {
if (err && err.notFound) { err = null; val = null;}
2014-02-04 08:06:05 -08:00
return cb(err,val);
});
};
2014-02-08 05:57:37 -08:00
BlockDb.prototype.getNext = function(hash, cb) {
db.get(NEXT_PREFIX + hash, function(err,val) {
if (err && err.notFound) { err = null; val = null;}
return cb(err,val);
});
};
2014-02-04 08:06:05 -08:00
2014-02-08 05:57:37 -08:00
BlockDb.prototype.isMain = function(hash, cb) {
db.get(MAIN_PREFIX + hash, function(err, val) {
if (err && err.notFound) { err = null; val = 0;}
return cb(err,parseInt(val));
});
};
BlockDb.prototype.setMain = function(hash, isMain, cb) {
if (!isMain) console.log('\tNew orphan: %s',hash);
2014-02-08 05:57:37 -08:00
db.put(MAIN_PREFIX + hash, isMain?1:0, function(err) {
return cb(err);
});
};
BlockDb.prototype.setNext = function(hash, nextHash, cb) {
db.put(NEXT_PREFIX + hash, nextHash, function(err) {
return cb(err);
});
};
2014-02-04 08:06:05 -08:00
BlockDb.prototype.countNotOrphan = function(cb) {
2014-02-03 18:30:46 -08:00
var c = 0;
2014-02-05 08:02:51 -08:00
console.log('Counting connected blocks. This could take some minutes');
2014-02-08 05:57:37 -08:00
db.createReadStream({start: MAIN_PREFIX, end: MAIN_PREFIX + '~' })
2014-02-03 18:30:46 -08:00
.on('data', function (data) {
2014-02-03 22:22:58 -08:00
if (data.value !== 0) c++;
2014-02-03 18:30:46 -08:00
})
.on('error', function (err) {
return cb(err);
})
.on('end', function () {
2014-02-04 18:50:18 -08:00
return cb(null, c);
2014-02-03 18:30:46 -08:00
});
};
2014-02-08 05:57:37 -08:00
// .has() return true orphans also
2014-02-03 18:30:46 -08:00
BlockDb.prototype.has = function(hash, cb) {
2014-02-08 05:57:37 -08:00
var k = PREV_PREFIX + hash;
2014-02-05 08:02:51 -08:00
db.get(k, function (err,val) {
2014-02-03 18:30:46 -08:00
var ret;
if (err && err.notFound) {
err = null;
ret = false;
}
if (typeof val !== 'undefined') {
ret = true;
}
return cb(err, ret);
});
};
BlockDb.prototype.fromHashWithInfo = function(hash, cb) {
2014-02-10 06:00:31 -08:00
var self = this;
2014-02-03 18:30:46 -08:00
rpc.getBlock(hash, function(err, info) {
// Not found?
if (err && err.code === -5) return cb();
if (err) return cb(err);
if (info.result.height)
info.result.reward = BitcoreBlock.getBlockValue(info.result.height) / util.COIN ;
2014-02-10 06:00:31 -08:00
self.isMain(hash, function(err, val) {
if (err) return cb(err);
info.result.isMainChain = val ? true : false;
return cb(null, {
hash: hash,
info: info.result,
});
2014-02-03 18:30:46 -08:00
});
});
};
BlockDb.prototype.getBlocksByDate = function(start_ts, end_ts, cb) {
2014-02-04 12:22:51 -08:00
var list = [];
2014-02-05 08:02:51 -08:00
db.createReadStream({
2014-02-08 05:57:37 -08:00
start: TIMESTAMP_PREFIX + start_ts,
end: TIMESTAMP_PREFIX + end_ts,
fillCache: true
2014-02-05 08:02:51 -08:00
})
2014-02-04 12:22:51 -08:00
.on('data', function (data) {
list.push({
2014-02-08 05:57:37 -08:00
ts: data.key.replace(TIMESTAMP_PREFIX, ''),
2014-02-04 12:22:51 -08:00
hash: data.value,
});
})
.on('error', function (err) {
return cb(err);
})
.on('end', function () {
return cb(null, list.reverse());
2014-02-04 12:22:51 -08:00
});
};
2014-02-05 10:27:50 -08:00
BlockDb.prototype.blockIndex = function(height, cb) {
2014-02-03 18:30:46 -08:00
var rpc = new RpcClient(config.bitcoind);
rpc.getBlockHash(height, function(err, bh){
if (err) return cb(err);
cb(null, { blockHash: bh.result });
});
};
return BlockDb;
2014-02-03 18:30:46 -08:00
}
module.defineClass(spec);