leveldb connection using classtool
This commit is contained in:
parent
a031941c62
commit
061e4e4b34
|
@ -3,7 +3,7 @@
|
||||||
require('classtool');
|
require('classtool');
|
||||||
|
|
||||||
|
|
||||||
function spec() {
|
function spec(b) {
|
||||||
|
|
||||||
var TIMESTAMP_ROOT = 'b-ts-'; // b-ts-<ts> => <hash>
|
var TIMESTAMP_ROOT = 'b-ts-'; // b-ts-<ts> => <hash>
|
||||||
var PREV_ROOT = 'b-prev-'; // b-prev-<hash> => <prev_hash> (0 if orphan)
|
var PREV_ROOT = 'b-prev-'; // b-prev-<hash> => <prev_hash> (0 if orphan)
|
||||||
|
@ -17,36 +17,34 @@ function spec() {
|
||||||
levelup = require('levelup'),
|
levelup = require('levelup'),
|
||||||
BitcoreBlock= require('bitcore/Block').class(),
|
BitcoreBlock= require('bitcore/Block').class(),
|
||||||
config = require('../config/config');
|
config = require('../config/config');
|
||||||
|
var db = b.db || levelup(config.leveldb + '/blocks');
|
||||||
|
|
||||||
var BlockDb = function(db) {
|
|
||||||
this.db = db || levelup(config.leveldb + '/blocks');
|
var BlockDb = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDb.prototype.close = function(cb) {
|
BlockDb.prototype.close = function(cb) {
|
||||||
this.db.close(cb);
|
db.close(cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDb.prototype.drop = function(cb) {
|
BlockDb.prototype.drop = function(cb) {
|
||||||
var self = this;
|
|
||||||
var path = config.leveldb + '/blocks';
|
var path = config.leveldb + '/blocks';
|
||||||
self.db.close(function() {
|
db.close(function() {
|
||||||
require('leveldown').destroy(path, function () {
|
require('leveldown').destroy(path, function () {
|
||||||
self.db = levelup(path);
|
db = levelup(path);
|
||||||
return cb();
|
return cb();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDb.prototype.add = function(b, cb) {
|
BlockDb.prototype.add = function(b, cb) {
|
||||||
var self = this;
|
|
||||||
|
|
||||||
if (!b.hash) return cb(new Error('no Hash at Block.save'));
|
if (!b.hash) return cb(new Error('no Hash at Block.save'));
|
||||||
|
|
||||||
|
|
||||||
var time_key = TIMESTAMP_ROOT +
|
var time_key = TIMESTAMP_ROOT +
|
||||||
( b.time || Math.round(new Date().getTime() / 1000) );
|
( b.time || Math.round(new Date().getTime() / 1000) );
|
||||||
|
|
||||||
self.db.batch()
|
db.batch()
|
||||||
.put(time_key, b.hash)
|
.put(time_key, b.hash)
|
||||||
.put(PREV_ROOT + b.hash, b.previousblockhash)
|
.put(PREV_ROOT + b.hash, b.previousblockhash)
|
||||||
.write(cb);
|
.write(cb);
|
||||||
|
@ -55,13 +53,11 @@ function spec() {
|
||||||
|
|
||||||
|
|
||||||
BlockDb.prototype.setOrphan = function(hash, cb) {
|
BlockDb.prototype.setOrphan = function(hash, cb) {
|
||||||
var self = this;
|
|
||||||
|
|
||||||
var k = PREV_ROOT + hash;
|
var k = PREV_ROOT + hash;
|
||||||
|
|
||||||
self.db.get(k, function (err,oldPrevHash) {
|
db.get(k, function (err,oldPrevHash) {
|
||||||
if (err || !oldPrevHash) return cb(err);
|
if (err || !oldPrevHash) return cb(err);
|
||||||
self.db.put(PREV_ROOT + hash, 0, function() {
|
db.put(PREV_ROOT + hash, 0, function() {
|
||||||
return cb(err, oldPrevHash);
|
return cb(err, oldPrevHash);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -70,14 +66,14 @@ function spec() {
|
||||||
|
|
||||||
//mainly for testing
|
//mainly for testing
|
||||||
BlockDb.prototype.setPrev = function(hash, prevHash, cb) {
|
BlockDb.prototype.setPrev = function(hash, prevHash, cb) {
|
||||||
this.db.put(PREV_ROOT + hash, prevHash, function(err) {
|
db.put(PREV_ROOT + hash, prevHash, function(err) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
//mainly for testing
|
//mainly for testing
|
||||||
BlockDb.prototype.getPrev = function(hash, cb) {
|
BlockDb.prototype.getPrev = function(hash, cb) {
|
||||||
this.db.get(PREV_ROOT + hash, function(err,val) {
|
db.get(PREV_ROOT + hash, function(err,val) {
|
||||||
return cb(err,val);
|
return cb(err,val);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -87,7 +83,7 @@ function spec() {
|
||||||
BlockDb.prototype.countNotOrphan = function(cb) {
|
BlockDb.prototype.countNotOrphan = function(cb) {
|
||||||
var c = 0;
|
var c = 0;
|
||||||
console.log('Counting connected blocks. This could take some minutes');
|
console.log('Counting connected blocks. This could take some minutes');
|
||||||
this.db.createReadStream({start: PREV_ROOT, end: PREV_ROOT + '~' })
|
db.createReadStream({start: PREV_ROOT, end: PREV_ROOT + '~' })
|
||||||
.on('data', function (data) {
|
.on('data', function (data) {
|
||||||
if (data.value !== 0) c++;
|
if (data.value !== 0) c++;
|
||||||
})
|
})
|
||||||
|
@ -100,10 +96,8 @@ function spec() {
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDb.prototype.has = function(hash, cb) {
|
BlockDb.prototype.has = function(hash, cb) {
|
||||||
var self = this;
|
|
||||||
|
|
||||||
var k = PREV_ROOT + hash;
|
var k = PREV_ROOT + hash;
|
||||||
self.db.get(k, function (err,val) {
|
db.get(k, function (err,val) {
|
||||||
var ret;
|
var ret;
|
||||||
if (err && err.notFound) {
|
if (err && err.notFound) {
|
||||||
err = null;
|
err = null;
|
||||||
|
@ -135,9 +129,8 @@ function spec() {
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDb.prototype.getBlocksByDate = function(start_ts, end_ts, cb) {
|
BlockDb.prototype.getBlocksByDate = function(start_ts, end_ts, cb) {
|
||||||
var self = this;
|
|
||||||
var list = [];
|
var list = [];
|
||||||
self.db.createReadStream({
|
db.createReadStream({
|
||||||
start: TIMESTAMP_ROOT + start_ts,
|
start: TIMESTAMP_ROOT + start_ts,
|
||||||
end: TIMESTAMP_ROOT + end_ts
|
end: TIMESTAMP_ROOT + end_ts
|
||||||
})
|
})
|
||||||
|
@ -145,7 +138,6 @@ function spec() {
|
||||||
list.push({
|
list.push({
|
||||||
ts: data.key.replace(TIMESTAMP_ROOT, ''),
|
ts: data.key.replace(TIMESTAMP_ROOT, ''),
|
||||||
hash: data.value,
|
hash: data.value,
|
||||||
info: {}
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.on('error', function (err) {
|
.on('error', function (err) {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
require('classtool');
|
require('classtool');
|
||||||
|
|
||||||
|
|
||||||
function spec() {
|
function spec(b) {
|
||||||
|
|
||||||
// blockHash -> txid mapping (to reorgs)
|
// blockHash -> txid mapping (to reorgs)
|
||||||
var ROOT = 'tx-b-'; //tx-b-<txid>-<block> => 1/0 (connected or not)
|
var ROOT = 'tx-b-'; //tx-b-<txid>-<block> => 1/0 (connected or not)
|
||||||
|
@ -28,21 +28,21 @@ function spec() {
|
||||||
async = require('async'),
|
async = require('async'),
|
||||||
config = require('../config/config'),
|
config = require('../config/config'),
|
||||||
assert = require('assert');
|
assert = require('assert');
|
||||||
|
var db = b.db || levelup(config.leveldb + '/txs');
|
||||||
|
|
||||||
var TransactionDb = function(db) {
|
var TransactionDb = function() {
|
||||||
this.db = db || levelup(config.leveldb + '/txs');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionDb.prototype.close = function(cb) {
|
TransactionDb.prototype.close = function(cb) {
|
||||||
this.db.close(cb);
|
db.close(cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionDb.prototype.drop = function(cb) {
|
TransactionDb.prototype.drop = function(cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var path = config.leveldb + '/txs';
|
var path = config.leveldb + '/txs';
|
||||||
self.db.close(function() {
|
db.close(function() {
|
||||||
require('leveldown').destroy(path, function () {
|
require('leveldown').destroy(path, function () {
|
||||||
self.db = levelup(path);
|
db = levelup(path);
|
||||||
return cb();
|
return cb();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -54,7 +54,7 @@ function spec() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var k = OUTS_ROOT + txid;
|
var k = OUTS_ROOT + txid;
|
||||||
self.db.get(k, function (err,val) {
|
db.get(k, function (err,val) {
|
||||||
|
|
||||||
var ret;
|
var ret;
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ function spec() {
|
||||||
var ret=[];
|
var ret=[];
|
||||||
|
|
||||||
// outs.
|
// outs.
|
||||||
self.db.createReadStream({start: k, end: k + '~'})
|
db.createReadStream({start: k, end: k + '~'})
|
||||||
.on('data', function (data) {
|
.on('data', function (data) {
|
||||||
var k = data.key.split('-');
|
var k = data.key.split('-');
|
||||||
var v = data.value.split(':');
|
var v = data.value.split(':');
|
||||||
|
@ -92,7 +92,7 @@ function spec() {
|
||||||
.on('end', function () {
|
.on('end', function () {
|
||||||
var k = SPEND_ROOT + txid;
|
var k = SPEND_ROOT + txid;
|
||||||
var l = ret.length;
|
var l = ret.length;
|
||||||
self.db.createReadStream({start: k, end: k + '~'})
|
db.createReadStream({start: k, end: k + '~'})
|
||||||
.on('data', function (data) {
|
.on('data', function (data) {
|
||||||
var k = data.key.split('-');
|
var k = data.key.split('-');
|
||||||
var v = data.value.split(':');
|
var v = data.value.split(':');
|
||||||
|
@ -181,7 +181,7 @@ function spec() {
|
||||||
|
|
||||||
var k = OUTS_ROOT + txid + '-' + n;
|
var k = OUTS_ROOT + txid + '-' + n;
|
||||||
|
|
||||||
self.db.get(k, function (err,val) {
|
db.get(k, function (err,val) {
|
||||||
if (err && err.notFound) {
|
if (err && err.notFound) {
|
||||||
err = null;
|
err = null;
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ function spec() {
|
||||||
var ret=[];
|
var ret=[];
|
||||||
|
|
||||||
//
|
//
|
||||||
self.db.createReadStream({start: k, end: k + '~'})
|
db.createReadStream({start: k, end: k + '~'})
|
||||||
.on('data', function (data) {
|
.on('data', function (data) {
|
||||||
var k = data.key.split('-');
|
var k = data.key.split('-');
|
||||||
var v = data.value.split(':');
|
var v = data.value.split(':');
|
||||||
|
@ -214,7 +214,7 @@ function spec() {
|
||||||
.on('end', function () {
|
.on('end', function () {
|
||||||
async.each(ret, function(o, e_c) {
|
async.each(ret, function(o, e_c) {
|
||||||
var k = SPEND_ROOT + o.txid + '-' + o.index;
|
var k = SPEND_ROOT + o.txid + '-' + o.index;
|
||||||
self.db.get(k, function(err, val) {
|
db.get(k, function(err, val) {
|
||||||
if (err && err.notFound) err=null;
|
if (err && err.notFound) err=null;
|
||||||
if (err || !val) return e_c(err);
|
if (err || !val) return e_c(err);
|
||||||
|
|
||||||
|
@ -237,20 +237,20 @@ function spec() {
|
||||||
|
|
||||||
async.series([
|
async.series([
|
||||||
function(c) {
|
function(c) {
|
||||||
self.db.createReadStream({
|
db.createReadStream({
|
||||||
start: OUTS_ROOT + txid,
|
start: OUTS_ROOT + txid,
|
||||||
end: OUTS_ROOT + txid + '~',
|
end: OUTS_ROOT + txid + '~',
|
||||||
}).pipe(
|
}).pipe(
|
||||||
self.db.createWriteStream({type:'del'})
|
db.createWriteStream({type:'del'})
|
||||||
).on('close', c);
|
).on('close', c);
|
||||||
},
|
},
|
||||||
function(c) {
|
function(c) {
|
||||||
self.db.createReadStream({
|
db.createReadStream({
|
||||||
start: SPEND_ROOT + txid,
|
start: SPEND_ROOT + txid,
|
||||||
end: SPEND_ROOT + txid + '~'
|
end: SPEND_ROOT + txid + '~'
|
||||||
})
|
})
|
||||||
.pipe(
|
.pipe(
|
||||||
self.db.createWriteStream({type:'del'})
|
db.createWriteStream({type:'del'})
|
||||||
).on('close', c);
|
).on('close', c);
|
||||||
}],
|
}],
|
||||||
function(err) {
|
function(err) {
|
||||||
|
@ -313,7 +313,7 @@ function spec() {
|
||||||
if (tx.isCoinBase) return p_c();
|
if (tx.isCoinBase) return p_c();
|
||||||
async.forEachLimit(tx.vin, CONCURRENCY,
|
async.forEachLimit(tx.vin, CONCURRENCY,
|
||||||
function(i, next_out) {
|
function(i, next_out) {
|
||||||
self.db.batch()
|
db.batch()
|
||||||
.put( SPEND_ROOT + i.txid + '-' + i.vout ,
|
.put( SPEND_ROOT + i.txid + '-' + i.vout ,
|
||||||
tx.txid + ':' + i.n + ':' + ts)
|
tx.txid + ':' + i.n + ':' + ts)
|
||||||
.write(next_out);
|
.write(next_out);
|
||||||
|
@ -344,7 +344,7 @@ function spec() {
|
||||||
|
|
||||||
var addr = o.scriptPubKey.addresses[0];
|
var addr = o.scriptPubKey.addresses[0];
|
||||||
var sat = Math.round(o.value * util.COIN);
|
var sat = Math.round(o.value * util.COIN);
|
||||||
self.db.batch()
|
db.batch()
|
||||||
.put( OUTS_ROOT + tx.txid + '-' + o.n, addr + ':' + sat)
|
.put( OUTS_ROOT + tx.txid + '-' + o.n, addr + ':' + sat)
|
||||||
.put( ADDR_ROOT + addr + '-' + ts + '-' + tx.txid +
|
.put( ADDR_ROOT + addr + '-' + ts + '-' + tx.txid +
|
||||||
'-' + o.n, sat)
|
'-' + o.n, sat)
|
||||||
|
@ -395,7 +395,7 @@ function spec() {
|
||||||
self.add(inInfo, function(err) {
|
self.add(inInfo, function(err) {
|
||||||
if (err || !blockHash) return each_cb(err);
|
if (err || !blockHash) return each_cb(err);
|
||||||
|
|
||||||
self.db.put(ROOT + t + '-' + blockHash, 1, function(err) {
|
db.put(ROOT + t + '-' + blockHash, 1, function(err) {
|
||||||
return each_cb(err);
|
return each_cb(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -405,7 +405,7 @@ function spec() {
|
||||||
self.add(t, function(err) {
|
self.add(t, function(err) {
|
||||||
if (err) return each_cb(err);
|
if (err) return each_cb(err);
|
||||||
|
|
||||||
self.db.put(ROOT + t.txid + '-' + blockHash, 1, function(err) {
|
db.put(ROOT + t.txid + '-' + blockHash, 1, function(err) {
|
||||||
return each_cb(err);
|
return each_cb(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,10 +21,6 @@ describe('TransactionDb fromIdWithInfo', function(){
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
after(function(c) {
|
|
||||||
txDb.close(c);
|
|
||||||
});
|
|
||||||
|
|
||||||
var txid = '7e621eeb02874ab039a8566fd36f4591e65eca65313875221842c53de6907d6c';
|
var txid = '7e621eeb02874ab039a8566fd36f4591e65eca65313875221842c53de6907d6c';
|
||||||
it('tx info ' + txid, function(done) {
|
it('tx info ' + txid, function(done) {
|
||||||
txDb.fromIdWithInfo(txid, function(err, tx) {
|
txDb.fromIdWithInfo(txid, function(err, tx) {
|
||||||
|
@ -126,11 +122,6 @@ describe('TransactionDb Outs', function(){
|
||||||
return c();
|
return c();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
after(function(c) {
|
|
||||||
txDb.close(c);
|
|
||||||
});
|
|
||||||
|
|
||||||
txItemsValid.forEach( function(v) {
|
txItemsValid.forEach( function(v) {
|
||||||
if (v.disabled) return;
|
if (v.disabled) return;
|
||||||
it('test a processing tx ' + v.txid, function(done) {
|
it('test a processing tx ' + v.txid, function(done) {
|
||||||
|
|
|
@ -42,11 +42,6 @@ describe('TransactionDb Expenses', function(){
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
after(function(c) {
|
|
||||||
txDb.close(c);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
Object.keys(spentValid).forEach( function(txid) {
|
Object.keys(spentValid).forEach( function(txid) {
|
||||||
it('test result of spending tx ' + txid, function(done) {
|
it('test result of spending tx ' + txid, function(done) {
|
||||||
var s = spentValid[txid];
|
var s = spentValid[txid];
|
||||||
|
|
|
@ -17,12 +17,6 @@ describe('Address balances', function(){
|
||||||
return c();
|
return c();
|
||||||
});
|
});
|
||||||
|
|
||||||
after(function(c) {
|
|
||||||
txDb.close(c);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
addrValid.forEach( function(v) {
|
addrValid.forEach( function(v) {
|
||||||
if (v.disabled) {
|
if (v.disabled) {
|
||||||
console.log(v.addr + " => disabled in JSON");
|
console.log(v.addr + " => disabled in JSON");
|
||||||
|
|
|
@ -21,11 +21,6 @@ describe('BlockDb fromHashWithInfo', function(){
|
||||||
return c();
|
return c();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
after(function(c) {
|
|
||||||
bDb.close(c);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should poll block\'s info from bitcoind', function(done) {
|
it('should poll block\'s info from bitcoind', function(done) {
|
||||||
bDb.fromHashWithInfo(TESTING_BLOCK, function(err, b2) {
|
bDb.fromHashWithInfo(TESTING_BLOCK, function(err, b2) {
|
||||||
if (err) done(err);
|
if (err) done(err);
|
||||||
|
|
|
@ -5,8 +5,8 @@ process.env.NODE_ENV = process.env.NODE_ENV || 'development';
|
||||||
|
|
||||||
var TESTING_BLOCK0 = '000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943';
|
var TESTING_BLOCK0 = '000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943';
|
||||||
var TESTING_BLOCK1 = '00000000b873e79784647a6c82962c70d228557d24a747ea4d1b8bbe878e1206';
|
var TESTING_BLOCK1 = '00000000b873e79784647a6c82962c70d228557d24a747ea4d1b8bbe878e1206';
|
||||||
var START_TS = 1293895128; // 1/1/2011
|
var START_TS = 1;
|
||||||
var END_TS = 1296688428; // 2/2/2011 23:23PM
|
var END_TS = '1296688928~'; // 2/2/2011 23:23PM
|
||||||
|
|
||||||
var assert = require('assert'),
|
var assert = require('assert'),
|
||||||
BlockDb = require('../../lib/BlockDb').class();
|
BlockDb = require('../../lib/BlockDb').class();
|
||||||
|
@ -21,11 +21,6 @@ describe('BlockDb getBlocksByDate', function(){
|
||||||
return c();
|
return c();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
after(function(c) {
|
|
||||||
bDb.close(c);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Get Hash by Date', function(done) {
|
it('Get Hash by Date', function(done) {
|
||||||
|
|
||||||
bDb.getBlocksByDate(START_TS, END_TS, function(err, list) {
|
bDb.getBlocksByDate(START_TS, END_TS, function(err, list) {
|
||||||
|
|
Loading…
Reference in New Issue