insight with soop. WIP
This commit is contained in:
parent
1af6bb7a02
commit
e19cd9f2ba
@ -7,9 +7,9 @@ var Address = require('../models/Address');
|
|||||||
var async = require('async');
|
var async = require('async');
|
||||||
var common = require('./common');
|
var common = require('./common');
|
||||||
|
|
||||||
var TransactionDb = require('../../lib/TransactionDb').class();
|
var Rpc = require('../../lib/Rpc');
|
||||||
var BlockDb = require('../../lib/BlockDb').class();
|
var TransactionDb = require('../../lib/TransactionDb').default();
|
||||||
var Rpc = require('../../lib/Rpc').class();
|
var BlockDb = require('../../lib/BlockDb').default();
|
||||||
|
|
||||||
var tDb = new TransactionDb();
|
var tDb = new TransactionDb();
|
||||||
var bdb = new BlockDb();
|
var bdb = new BlockDb();
|
||||||
|
|||||||
@ -1,19 +1,16 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
require('classtool');
|
//var imports = require('soop').imports();
|
||||||
|
var async = require('async');
|
||||||
|
var BitcoreAddress = require('bitcore/Address');
|
||||||
|
var BitcoreTransaction = require('bitcore/Transaction');
|
||||||
|
var BitcoreUtil = require('bitcore/util/util');
|
||||||
|
var Parser = require('bitcore/util/BinaryParser');
|
||||||
|
var Buffer = require('buffer').Buffer;
|
||||||
|
var TransactionDb = require('../../lib/TransactionDb').default();
|
||||||
|
var CONCURRENCY = 5;
|
||||||
|
|
||||||
|
function Address(addrStr) {
|
||||||
function spec() {
|
|
||||||
var async = require('async');
|
|
||||||
var BitcoreAddress = require('bitcore/Address').class();
|
|
||||||
var BitcoreUtil = require('bitcore/util/util');
|
|
||||||
var TransactionDb = require('../../lib/TransactionDb').class();
|
|
||||||
var BitcoreTransaction = require('bitcore/Transaction').class();
|
|
||||||
var Parser = require('bitcore/util/BinaryParser').class();
|
|
||||||
var Buffer = require('buffer').Buffer;
|
|
||||||
var CONCURRENCY = 5;
|
|
||||||
|
|
||||||
function Address(addrStr) {
|
|
||||||
this.balanceSat = 0;
|
this.balanceSat = 0;
|
||||||
this.totalReceivedSat = 0;
|
this.totalReceivedSat = 0;
|
||||||
this.totalSentSat = 0;
|
this.totalSentSat = 0;
|
||||||
@ -71,18 +68,18 @@ function spec() {
|
|||||||
enumerable: 1,
|
enumerable: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Address.prototype._getScriptPubKey = function(hex,n) {
|
Address.prototype._getScriptPubKey = function(hex,n) {
|
||||||
// ScriptPubKey is not provided by bitcoind RPC, so we parse it from tx hex.
|
// ScriptPubKey is not provided by bitcoind RPC, so we parse it from tx hex.
|
||||||
|
|
||||||
var parser = new Parser(new Buffer(hex,'hex'));
|
var parser = new Parser(new Buffer(hex,'hex'));
|
||||||
var tx = new BitcoreTransaction();
|
var tx = new BitcoreTransaction();
|
||||||
tx.parse(parser);
|
tx.parse(parser);
|
||||||
return (tx.outs[n].s.toString('hex'));
|
return (tx.outs[n].s.toString('hex'));
|
||||||
};
|
};
|
||||||
|
|
||||||
Address.prototype.getUtxo = function(next) {
|
Address.prototype.getUtxo = function(next) {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (!self.addrStr) return next();
|
if (!self.addrStr) return next();
|
||||||
|
|
||||||
@ -117,9 +114,9 @@ function spec() {
|
|||||||
return next(err,ret);
|
return next(err,ret);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Address.prototype.update = function(next) {
|
Address.prototype.update = function(next) {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (!self.addrStr) return next();
|
if (!self.addrStr) return next();
|
||||||
|
|
||||||
@ -186,9 +183,7 @@ function spec() {
|
|||||||
self.transactions = txs.map(function(i) { return i.txid; } );
|
self.transactions = txs.map(function(i) { return i.txid; } );
|
||||||
return next(err);
|
return next(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return Address;
|
module.exports = require('soop')(Address);
|
||||||
}
|
|
||||||
module.defineClass(spec);
|
|
||||||
|
|
||||||
|
|||||||
@ -1,19 +1,17 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
//var imports = require('soop').imports();
|
||||||
|
|
||||||
require('classtool');
|
var async = require('async');
|
||||||
|
var RpcClient = require('bitcore/RpcClient');
|
||||||
|
var BlockDb = require('../../lib/BlockDb');
|
||||||
|
var config = require('../../config/config');
|
||||||
|
var rpc = new RpcClient(config.bitcoind);
|
||||||
|
|
||||||
function spec() {
|
function Status() {
|
||||||
var async = require('async');
|
|
||||||
var RpcClient = require('bitcore/RpcClient').class();
|
|
||||||
var BlockDb = require('../../lib/BlockDb').class();
|
|
||||||
var config = require('../../config/config');
|
|
||||||
var rpc = new RpcClient(config.bitcoind);
|
|
||||||
|
|
||||||
function Status() {
|
|
||||||
this.bDb = new BlockDb();
|
this.bDb = new BlockDb();
|
||||||
}
|
}
|
||||||
|
|
||||||
Status.prototype.getInfo = function(next) {
|
Status.prototype.getInfo = function(next) {
|
||||||
var that = this;
|
var that = this;
|
||||||
async.series([
|
async.series([
|
||||||
function (cb) {
|
function (cb) {
|
||||||
@ -27,9 +25,9 @@ function spec() {
|
|||||||
], function (err) {
|
], function (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Status.prototype.getDifficulty = function(next) {
|
Status.prototype.getDifficulty = function(next) {
|
||||||
var that = this;
|
var that = this;
|
||||||
async.series([
|
async.series([
|
||||||
function (cb) {
|
function (cb) {
|
||||||
@ -43,9 +41,9 @@ function spec() {
|
|||||||
], function (err) {
|
], function (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Status.prototype.getTxOutSetInfo = function(next) {
|
Status.prototype.getTxOutSetInfo = function(next) {
|
||||||
var that = this;
|
var that = this;
|
||||||
async.series([
|
async.series([
|
||||||
function (cb) {
|
function (cb) {
|
||||||
@ -59,9 +57,9 @@ function spec() {
|
|||||||
], function (err) {
|
], function (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Status.prototype.getBestBlockHash = function(next) {
|
Status.prototype.getBestBlockHash = function(next) {
|
||||||
var that = this;
|
var that = this;
|
||||||
async.series([
|
async.series([
|
||||||
function (cb) {
|
function (cb) {
|
||||||
@ -76,9 +74,9 @@ function spec() {
|
|||||||
], function (err) {
|
], function (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Status.prototype.getLastBlockHash = function(next) {
|
Status.prototype.getLastBlockHash = function(next) {
|
||||||
var that = this;
|
var that = this;
|
||||||
that.bDb.getTip(function(err,tip) {
|
that.bDb.getTip(function(err,tip) {
|
||||||
that.syncTipHash = tip;
|
that.syncTipHash = tip;
|
||||||
@ -103,10 +101,6 @@ function spec() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return Status;
|
|
||||||
|
|
||||||
}
|
|
||||||
module.defineClass(spec);
|
|
||||||
|
|
||||||
|
module.exports = require('soop')(Status);
|
||||||
|
|||||||
@ -5,7 +5,7 @@ var util = require('util');
|
|||||||
|
|
||||||
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
|
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
|
||||||
|
|
||||||
var RpcClient = require('../node_modules/bitcore/RpcClient').class();
|
var RpcClient = require('../node_modules/bitcore/RpcClient');
|
||||||
|
|
||||||
var config = require('../config/config');
|
var config = require('../config/config');
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
var T = require('../lib/TransactionDb').class();
|
var T = require('../lib/TransactionDb');
|
||||||
|
|
||||||
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
|
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
|
||||||
|
|
||||||
|
|||||||
137
lib/BlockDb.js
137
lib/BlockDb.js
@ -1,44 +1,39 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
var imports = require('soop').imports();
|
||||||
|
var parent = imports.parent || require('events').EventEmitter;
|
||||||
|
var TIMESTAMP_PREFIX = 'bts-'; // b-ts-<ts> => <hash>
|
||||||
|
var PREV_PREFIX = 'bpr-'; // b-prev-<hash> => <prev_hash>
|
||||||
|
var NEXT_PREFIX = 'bne-'; // b-next-<hash> => <next_hash>
|
||||||
|
var MAIN_PREFIX = 'bma-'; // b-main-<hash> => 1/0
|
||||||
|
var TIP = 'bti-'; // last block on the chain
|
||||||
|
var LAST_FILE_INDEX = 'file-'; // last processed file index
|
||||||
|
|
||||||
require('classtool');
|
var MAX_OPEN_FILES = 500;
|
||||||
|
|
||||||
|
|
||||||
function spec(b) {
|
/**
|
||||||
|
* Module dependencies.
|
||||||
var superclass = b.superclass || require('events').EventEmitter;
|
*/
|
||||||
var TIMESTAMP_PREFIX = 'bts-'; // b-ts-<ts> => <hash>
|
var levelup = require('levelup'),
|
||||||
var PREV_PREFIX = 'bpr-'; // b-prev-<hash> => <prev_hash>
|
|
||||||
var NEXT_PREFIX = 'bne-'; // b-next-<hash> => <next_hash>
|
|
||||||
var MAIN_PREFIX = 'bma-'; // b-main-<hash> => 1/0
|
|
||||||
var TIP = 'bti-'; // last block on the chain
|
|
||||||
var LAST_FILE_INDEX = 'file-'; // last processed file index
|
|
||||||
|
|
||||||
var MAX_OPEN_FILES = 500;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Module dependencies.
|
|
||||||
*/
|
|
||||||
var levelup = require('levelup'),
|
|
||||||
config = require('../config/config');
|
config = require('../config/config');
|
||||||
var db = b.db || levelup(config.leveldb + '/blocks',{maxOpenFiles: MAX_OPEN_FILES} );
|
var db = imports.db || levelup(config.leveldb + '/blocks',{maxOpenFiles: MAX_OPEN_FILES} );
|
||||||
var Rpc = b.rpc || require('./Rpc').class();
|
var Rpc = imports.rpc || require('./Rpc');
|
||||||
var PoolMatch = b.poolMatch || require('./PoolMatch').class(config);
|
var PoolMatch = imports.poolMatch || require('soop').load('./PoolMatch',config);
|
||||||
|
|
||||||
var TransactionDb = require('./TransactionDb.js').class();
|
var TransactionDb = require('./TransactionDb.js').default();
|
||||||
|
|
||||||
var BlockDb = function() {
|
var BlockDb = function() {
|
||||||
BlockDb.super(this, arguments);
|
BlockDb.super(this, arguments);
|
||||||
this.poolMatch = new PoolMatch();
|
this.poolMatch = new PoolMatch();
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDb.superclass = superclass;
|
BlockDb.parent = parent;
|
||||||
|
|
||||||
BlockDb.prototype.close = function(cb) {
|
BlockDb.prototype.close = function(cb) {
|
||||||
db.close(cb);
|
db.close(cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDb.prototype.drop = function(cb) {
|
BlockDb.prototype.drop = function(cb) {
|
||||||
var path = config.leveldb + '/blocks';
|
var path = config.leveldb + '/blocks';
|
||||||
db.close(function() {
|
db.close(function() {
|
||||||
require('leveldown').destroy(path, function () {
|
require('leveldown').destroy(path, function () {
|
||||||
@ -46,12 +41,12 @@ function spec(b) {
|
|||||||
return cb();
|
return cb();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// adds a block. Does not update Next pointer in
|
// adds a block. Does not update Next pointer in
|
||||||
// the block prev to the new block, nor TIP pointer
|
// the block prev to the new block, nor TIP pointer
|
||||||
//
|
//
|
||||||
BlockDb.prototype.add = function(b, cb) {
|
BlockDb.prototype.add = function(b, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var time_key = TIMESTAMP_PREFIX +
|
var time_key = TIMESTAMP_PREFIX +
|
||||||
( b.time || Math.round(new Date().getTime() / 1000) );
|
( b.time || Math.round(new Date().getTime() / 1000) );
|
||||||
@ -66,36 +61,36 @@ function spec(b) {
|
|||||||
}
|
}
|
||||||
cb(err);
|
cb(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDb.prototype.getTip = function(cb) {
|
BlockDb.prototype.getTip = function(cb) {
|
||||||
db.get(TIP, function(err, val) {
|
db.get(TIP, function(err, val) {
|
||||||
return cb(err,val);
|
return cb(err,val);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDb.prototype.setTip = function(hash, cb) {
|
BlockDb.prototype.setTip = function(hash, cb) {
|
||||||
db.put(TIP, hash, function(err) {
|
db.put(TIP, hash, function(err) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
//mainly for testing
|
//mainly for testing
|
||||||
BlockDb.prototype.setPrev = function(hash, prevHash, cb) {
|
BlockDb.prototype.setPrev = function(hash, prevHash, cb) {
|
||||||
db.put(PREV_PREFIX + hash, prevHash, function(err) {
|
db.put(PREV_PREFIX + hash, prevHash, function(err) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDb.prototype.getPrev = function(hash, cb) {
|
BlockDb.prototype.getPrev = function(hash, cb) {
|
||||||
db.get(PREV_PREFIX + hash, function(err,val) {
|
db.get(PREV_PREFIX + hash, function(err,val) {
|
||||||
if (err && err.notFound) { err = null; val = null;}
|
if (err && err.notFound) { err = null; val = null;}
|
||||||
return cb(err,val);
|
return cb(err,val);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
BlockDb.prototype.setLastFileIndex = function(idx, cb) {
|
BlockDb.prototype.setLastFileIndex = function(idx, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (this.lastFileIndexSaved === idx) return cb();
|
if (this.lastFileIndexSaved === idx) return cb();
|
||||||
|
|
||||||
@ -103,42 +98,42 @@ function spec(b) {
|
|||||||
self.lastFileIndexSaved = idx;
|
self.lastFileIndexSaved = idx;
|
||||||
return cb(err);
|
return cb(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDb.prototype.getLastFileIndex = function(cb) {
|
BlockDb.prototype.getLastFileIndex = function(cb) {
|
||||||
db.get(LAST_FILE_INDEX, function(err,val) {
|
db.get(LAST_FILE_INDEX, function(err,val) {
|
||||||
if (err && err.notFound) { err = null; val = null;}
|
if (err && err.notFound) { err = null; val = null;}
|
||||||
return cb(err,val);
|
return cb(err,val);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDb.prototype.getNext = function(hash, cb) {
|
BlockDb.prototype.getNext = function(hash, cb) {
|
||||||
db.get(NEXT_PREFIX + hash, function(err,val) {
|
db.get(NEXT_PREFIX + hash, function(err,val) {
|
||||||
if (err && err.notFound) { err = null; val = null;}
|
if (err && err.notFound) { err = null; val = null;}
|
||||||
return cb(err,val);
|
return cb(err,val);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDb.prototype.isMain = function(hash, cb) {
|
BlockDb.prototype.isMain = function(hash, cb) {
|
||||||
db.get(MAIN_PREFIX + hash, function(err, val) {
|
db.get(MAIN_PREFIX + hash, function(err, val) {
|
||||||
if (err && err.notFound) { err = null; val = 0;}
|
if (err && err.notFound) { err = null; val = 0;}
|
||||||
return cb(err,parseInt(val));
|
return cb(err,parseInt(val));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDb.prototype.setMain = function(hash, isMain, cb) {
|
BlockDb.prototype.setMain = function(hash, isMain, cb) {
|
||||||
if (!isMain) console.log('\tNew orphan: %s',hash);
|
if (!isMain) console.log('\tNew orphan: %s',hash);
|
||||||
db.put(MAIN_PREFIX + hash, isMain?1:0, function(err) {
|
db.put(MAIN_PREFIX + hash, isMain?1:0, function(err) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
BlockDb.prototype.setNext = function(hash, nextHash, cb) {
|
BlockDb.prototype.setNext = function(hash, nextHash, cb) {
|
||||||
db.put(NEXT_PREFIX + hash, nextHash, function(err) {
|
db.put(NEXT_PREFIX + hash, nextHash, function(err) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDb.prototype.countConnected = function(cb) {
|
BlockDb.prototype.countConnected = 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');
|
||||||
db.createReadStream({start: MAIN_PREFIX, end: MAIN_PREFIX + '~' })
|
db.createReadStream({start: MAIN_PREFIX, end: MAIN_PREFIX + '~' })
|
||||||
@ -151,10 +146,10 @@ function spec(b) {
|
|||||||
.on('end', function () {
|
.on('end', function () {
|
||||||
return cb(null, c);
|
return cb(null, c);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// .has() return true orphans also
|
// .has() return true orphans also
|
||||||
BlockDb.prototype.has = function(hash, cb) {
|
BlockDb.prototype.has = function(hash, cb) {
|
||||||
var k = PREV_PREFIX + hash;
|
var k = PREV_PREFIX + hash;
|
||||||
db.get(k, function (err) {
|
db.get(k, function (err) {
|
||||||
var ret = true;
|
var ret = true;
|
||||||
@ -164,9 +159,9 @@ function spec(b) {
|
|||||||
}
|
}
|
||||||
return cb(err, ret);
|
return cb(err, ret);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDb.prototype.getPoolInfo = function(tx, cb) {
|
BlockDb.prototype.getPoolInfo = function(tx, cb) {
|
||||||
var tr = new TransactionDb();
|
var tr = new TransactionDb();
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
@ -180,9 +175,9 @@ function spec(b) {
|
|||||||
return cb(aa);
|
return cb(aa);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDb.prototype.fromHashWithInfo = function(hash, cb) {
|
BlockDb.prototype.fromHashWithInfo = function(hash, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
Rpc.getBlock(hash, function(err, info) {
|
Rpc.getBlock(hash, function(err, info) {
|
||||||
@ -199,9 +194,9 @@ function spec(b) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDb.prototype.getBlocksByDate = function(start_ts, end_ts, cb) {
|
BlockDb.prototype.getBlocksByDate = function(start_ts, end_ts, cb) {
|
||||||
var list = [];
|
var list = [];
|
||||||
db.createReadStream({
|
db.createReadStream({
|
||||||
start: TIMESTAMP_PREFIX + start_ts,
|
start: TIMESTAMP_PREFIX + start_ts,
|
||||||
@ -221,14 +216,10 @@ function spec(b) {
|
|||||||
.on('end', function () {
|
.on('end', function () {
|
||||||
return cb(null, list.reverse());
|
return cb(null, list.reverse());
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDb.prototype.blockIndex = function(height, cb) {
|
BlockDb.prototype.blockIndex = function(height, cb) {
|
||||||
return Rpc.blockIndex(height,cb);
|
return Rpc.blockIndex(height,cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
return BlockDb;
|
|
||||||
}
|
|
||||||
module.defineClass(spec);
|
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = require('soop')(BlockDb);
|
||||||
|
|||||||
@ -1,18 +1,13 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
var Block = require('bitcore/Block'),
|
||||||
require('classtool');
|
|
||||||
|
|
||||||
function spec() {
|
|
||||||
|
|
||||||
var Block = require('bitcore/Block').class(),
|
|
||||||
networks = require('bitcore/networks'),
|
networks = require('bitcore/networks'),
|
||||||
Parser = require('bitcore/util/BinaryParser').class(),
|
Parser = require('bitcore/util/BinaryParser'),
|
||||||
fs = require('fs'),
|
fs = require('fs'),
|
||||||
Buffer = require('buffer').Buffer,
|
Buffer = require('buffer').Buffer,
|
||||||
glob = require('glob'),
|
glob = require('glob'),
|
||||||
async = require('async');
|
async = require('async');
|
||||||
|
|
||||||
function BlockExtractor(dataDir, network) {
|
function BlockExtractor(dataDir, network) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var path = dataDir + '/blocks/blk*.dat';
|
var path = dataDir + '/blocks/blk*.dat';
|
||||||
@ -30,16 +25,16 @@ function spec() {
|
|||||||
self.currentParser = null;
|
self.currentParser = null;
|
||||||
self.network = network === 'testnet' ? networks.testnet: networks.livenet;
|
self.network = network === 'testnet' ? networks.testnet: networks.livenet;
|
||||||
self.magic = self.network.magic.toString('hex');
|
self.magic = self.network.magic.toString('hex');
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockExtractor.prototype.currentFile = function() {
|
BlockExtractor.prototype.currentFile = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
return self.files[self.currentFileIndex];
|
return self.files[self.currentFileIndex];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
BlockExtractor.prototype.nextFile = function() {
|
BlockExtractor.prototype.nextFile = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (self.currentFileIndex < 0) return false;
|
if (self.currentFileIndex < 0) return false;
|
||||||
@ -58,9 +53,9 @@ function spec() {
|
|||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockExtractor.prototype.readCurrentFileSync = function() {
|
BlockExtractor.prototype.readCurrentFileSync = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (self.currentFileIndex < 0 || self.isCurrentRead) return;
|
if (self.currentFileIndex < 0 || self.isCurrentRead) return;
|
||||||
@ -87,11 +82,11 @@ function spec() {
|
|||||||
|
|
||||||
self.currentBuffer = buffer;
|
self.currentBuffer = buffer;
|
||||||
self.currentParser = new Parser(buffer);
|
self.currentParser = new Parser(buffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BlockExtractor.prototype.getNextBlock = function(cb) {
|
BlockExtractor.prototype.getNextBlock = function(cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var b;
|
var b;
|
||||||
@ -154,9 +149,7 @@ function spec() {
|
|||||||
], function(err) {
|
], function(err) {
|
||||||
return cb(err,b);
|
return cb(err,b);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return BlockExtractor;
|
module.exports = require('soop')(BlockExtractor);
|
||||||
}
|
|
||||||
module.defineClass(spec);
|
|
||||||
|
|
||||||
|
|||||||
@ -1,30 +1,27 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
require('classtool');
|
var imports = require('soop').imports();
|
||||||
|
|
||||||
|
var util = require('util');
|
||||||
|
var assert = require('assert');
|
||||||
|
var RpcClient = require('bitcore/RpcClient');
|
||||||
|
var Script = require('bitcore/Script');
|
||||||
|
var networks = require('bitcore/networks');
|
||||||
|
var async = require('async');
|
||||||
|
var config = require('../config/config');
|
||||||
|
var Sync = require('./Sync');
|
||||||
|
var sockets = require('../app/controllers/socket.js');
|
||||||
|
var BlockExtractor = require('./BlockExtractor.js');
|
||||||
|
var buffertools = require('buffertools');
|
||||||
|
|
||||||
|
// var bitcoreUtil = require('bitcore/util/util');
|
||||||
|
// var Deserialize = require('bitcore/Deserialize');
|
||||||
|
|
||||||
|
|
||||||
|
var BAD_GEN_ERROR = 'Bad genesis block. Network mismatch between Insight and bitcoind? Insight is configured for:';
|
||||||
|
|
||||||
function spec() {
|
var BAD_GEN_ERROR_DB = 'Bad genesis block. Network mismatch between Insight and levelDB? Insight is configured for:';
|
||||||
var util = require('util');
|
function HistoricSync(opts) {
|
||||||
var assert = require('assert');
|
|
||||||
var RpcClient = require('bitcore/RpcClient').class();
|
|
||||||
var Script = require('bitcore/Script').class();
|
|
||||||
var networks = require('bitcore/networks');
|
|
||||||
var async = require('async');
|
|
||||||
var config = require('../config/config');
|
|
||||||
var Sync = require('./Sync').class();
|
|
||||||
var sockets = require('../app/controllers/socket.js');
|
|
||||||
var BlockExtractor = require('./BlockExtractor.js').class();
|
|
||||||
var buffertools = require('buffertools');
|
|
||||||
|
|
||||||
// var bitcoreUtil = require('bitcore/util/util');
|
|
||||||
// var Deserialize = require('bitcore/Deserialize');
|
|
||||||
|
|
||||||
|
|
||||||
var BAD_GEN_ERROR = 'Bad genesis block. Network mismatch between Insight and bitcoind? Insight is configured for:';
|
|
||||||
|
|
||||||
var BAD_GEN_ERROR_DB = 'Bad genesis block. Network mismatch between Insight and levelDB? Insight is configured for:';
|
|
||||||
function HistoricSync(opts) {
|
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
|
|
||||||
this.network = config.network === 'testnet' ? networks.testnet: networks.livenet;
|
this.network = config.network === 'testnet' ? networks.testnet: networks.livenet;
|
||||||
@ -37,18 +34,18 @@ function spec() {
|
|||||||
this.rpc = new RpcClient(config.bitcoind);
|
this.rpc = new RpcClient(config.bitcoind);
|
||||||
this.shouldBroadcast = opts.shouldBroadcastSync;
|
this.shouldBroadcast = opts.shouldBroadcastSync;
|
||||||
this.sync = new Sync(opts);
|
this.sync = new Sync(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
function p() {
|
function p() {
|
||||||
var args = [];
|
var args = [];
|
||||||
Array.prototype.push.apply(args, arguments);
|
Array.prototype.push.apply(args, arguments);
|
||||||
|
|
||||||
args.unshift('[historic_sync]');
|
args.unshift('[historic_sync]');
|
||||||
/*jshint validthis:true */
|
/*jshint validthis:true */
|
||||||
console.log.apply(this, args);
|
console.log.apply(this, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoricSync.prototype.showProgress = function() {
|
HistoricSync.prototype.showProgress = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if ( self.status ==='syncing' &&
|
if ( self.status ==='syncing' &&
|
||||||
@ -65,28 +62,28 @@ function spec() {
|
|||||||
sockets.broadcastSyncInfo(self.info());
|
sockets.broadcastSyncInfo(self.info());
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (self.syncPercentage > 10) {
|
// if (self.syncPercentage > 10) {
|
||||||
// process.exit(-1);
|
// process.exit(-1);
|
||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
HistoricSync.prototype.setError = function(err) {
|
HistoricSync.prototype.setError = function(err) {
|
||||||
var self = this;
|
var self = this;
|
||||||
self.error = err.message?err.message:err.toString();
|
self.error = err.message?err.message:err.toString();
|
||||||
self.status='error';
|
self.status='error';
|
||||||
self.showProgress();
|
self.showProgress();
|
||||||
return err;
|
return err;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
HistoricSync.prototype.close = function() {
|
HistoricSync.prototype.close = function() {
|
||||||
this.sync.close();
|
this.sync.close();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
HistoricSync.prototype.info = function() {
|
HistoricSync.prototype.info = function() {
|
||||||
this.updatePercentage();
|
this.updatePercentage();
|
||||||
return {
|
return {
|
||||||
status: this.status,
|
status: this.status,
|
||||||
@ -99,15 +96,15 @@ function spec() {
|
|||||||
startTs: this.startTs,
|
startTs: this.startTs,
|
||||||
endTs: this.endTs,
|
endTs: this.endTs,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
HistoricSync.prototype.updatePercentage = function() {
|
HistoricSync.prototype.updatePercentage = function() {
|
||||||
var r = this.syncedBlocks / this.blockChainHeight;
|
var r = this.syncedBlocks / this.blockChainHeight;
|
||||||
this.syncPercentage = parseFloat(100 * r).toFixed(3);
|
this.syncPercentage = parseFloat(100 * r).toFixed(3);
|
||||||
if (this.syncPercentage > 100) this.syncPercentage = 100;
|
if (this.syncPercentage > 100) this.syncPercentage = 100;
|
||||||
};
|
};
|
||||||
|
|
||||||
HistoricSync.prototype.getBlockFromRPC = function(cb) {
|
HistoricSync.prototype.getBlockFromRPC = function(cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (!self.currentRpcHash) return cb();
|
if (!self.currentRpcHash) return cb();
|
||||||
@ -129,9 +126,9 @@ function spec() {
|
|||||||
}
|
}
|
||||||
return cb(null, blockInfo);
|
return cb(null, blockInfo);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
HistoricSync.prototype.getBlockFromFile = function(cb) {
|
HistoricSync.prototype.getBlockFromFile = function(cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var blockInfo;
|
var blockInfo;
|
||||||
@ -170,29 +167,29 @@ function spec() {
|
|||||||
return cb(err,blockInfo);
|
return cb(err,blockInfo);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
HistoricSync.prototype.updateConnectedCountDB = function(cb) {
|
HistoricSync.prototype.updateConnectedCountDB = function(cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
self.sync.bDb.countConnected(function(err, count) {
|
self.sync.bDb.countConnected(function(err, count) {
|
||||||
self.connectedCountDB = count || 0;
|
self.connectedCountDB = count || 0;
|
||||||
self.syncedBlocks = count || 0;
|
self.syncedBlocks = count || 0;
|
||||||
return cb(err);
|
return cb(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
HistoricSync.prototype.updateBlockChainHeight = function(cb) {
|
HistoricSync.prototype.updateBlockChainHeight = function(cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.rpc.getBlockCount(function(err, res) {
|
self.rpc.getBlockCount(function(err, res) {
|
||||||
self.blockChainHeight = res.result;
|
self.blockChainHeight = res.result;
|
||||||
return cb(err);
|
return cb(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
HistoricSync.prototype.checkNetworkSettings = function(next) {
|
HistoricSync.prototype.checkNetworkSettings = function(next) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.hasGenesis = false;
|
self.hasGenesis = false;
|
||||||
@ -211,9 +208,9 @@ function spec() {
|
|||||||
return next(err);
|
return next(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
HistoricSync.prototype.updateStartBlock = function(next) {
|
HistoricSync.prototype.updateStartBlock = function(next) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.startBlock = self.genesis;
|
self.startBlock = self.genesis;
|
||||||
@ -258,9 +255,9 @@ function spec() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
HistoricSync.prototype.prepareFileSync = function(opts, next) {
|
HistoricSync.prototype.prepareFileSync = function(opts, next) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if ( opts.forceRPC || !config.bitcoind.dataDir ||
|
if ( opts.forceRPC || !config.bitcoind.dataDir ||
|
||||||
@ -299,10 +296,10 @@ function spec() {
|
|||||||
});
|
});
|
||||||
}, next);
|
}, next);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
//NOP
|
//NOP
|
||||||
HistoricSync.prototype.prepareRpcSync = function(opts, next) {
|
HistoricSync.prototype.prepareRpcSync = function(opts, next) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (self.blockExtractor) return next();
|
if (self.blockExtractor) return next();
|
||||||
@ -310,9 +307,9 @@ function spec() {
|
|||||||
self.currentRpcHash = self.startBlock;
|
self.currentRpcHash = self.startBlock;
|
||||||
self.allowReorgs = false;
|
self.allowReorgs = false;
|
||||||
return next();
|
return next();
|
||||||
};
|
};
|
||||||
|
|
||||||
HistoricSync.prototype.showSyncStartMessage = function() {
|
HistoricSync.prototype.showSyncStartMessage = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
p('Got ' + self.connectedCountDB +
|
p('Got ' + self.connectedCountDB +
|
||||||
@ -328,10 +325,10 @@ function spec() {
|
|||||||
|
|
||||||
p('Starting from: ', self.startBlock);
|
p('Starting from: ', self.startBlock);
|
||||||
self.showProgress();
|
self.showProgress();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
HistoricSync.prototype.setupSyncStatus = function() {
|
HistoricSync.prototype.setupSyncStatus = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var step = parseInt( (self.blockChainHeight - self.syncedBlocks) / 1000);
|
var step = parseInt( (self.blockChainHeight - self.syncedBlocks) / 1000);
|
||||||
@ -344,9 +341,9 @@ function spec() {
|
|||||||
self.endTs = null;
|
self.endTs = null;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
this.syncPercentage = 0;
|
this.syncPercentage = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
HistoricSync.prototype.prepareToSync = function(opts, next) {
|
HistoricSync.prototype.prepareToSync = function(opts, next) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.status = 'starting';
|
self.status = 'starting';
|
||||||
@ -377,10 +374,10 @@ function spec() {
|
|||||||
self.setupSyncStatus();
|
self.setupSyncStatus();
|
||||||
return next();
|
return next();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
HistoricSync.prototype.start = function(opts, next) {
|
HistoricSync.prototype.start = function(opts, next) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (self.status==='starting' || self.status==='syncing') {
|
if (self.status==='starting' || self.status==='syncing') {
|
||||||
@ -422,8 +419,6 @@ function spec() {
|
|||||||
});
|
});
|
||||||
}, next);
|
}, next);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return HistoricSync;
|
|
||||||
}
|
|
||||||
module.defineClass(spec);
|
|
||||||
|
|
||||||
|
module.exports = require('soop')(HistoricSync);
|
||||||
|
|||||||
@ -1,17 +1,14 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
require('classtool');
|
var fs = require('fs');
|
||||||
|
var bitcoreUtil = require('bitcore/util/util');
|
||||||
|
var Sync = require('./Sync');
|
||||||
|
var Peer = require('bitcore/Peer');
|
||||||
|
var config = require('../config/config');
|
||||||
|
var networks = require('bitcore/networks');
|
||||||
|
|
||||||
function spec() {
|
var peerdb_fn = 'peerdb.json';
|
||||||
var fs = require('fs');
|
|
||||||
var bitcoreUtil = require('bitcore/util/util');
|
|
||||||
var Sync = require('./Sync').class();
|
|
||||||
var Peer = require('bitcore/Peer').class();
|
|
||||||
var config = require('../config/config');
|
|
||||||
var networks = require('bitcore/networks');
|
|
||||||
|
|
||||||
var peerdb_fn = 'peerdb.json';
|
function PeerSync(opts) {
|
||||||
|
|
||||||
function PeerSync(opts) {
|
|
||||||
this.connected = false;
|
this.connected = false;
|
||||||
this.peerdb = undefined;
|
this.peerdb = undefined;
|
||||||
this.allowReorgs = false;
|
this.allowReorgs = false;
|
||||||
@ -21,31 +18,31 @@ function spec() {
|
|||||||
this.peerman = new this.PeerManager();
|
this.peerman = new this.PeerManager();
|
||||||
this.load_peers();
|
this.load_peers();
|
||||||
this.sync = new Sync(opts);
|
this.sync = new Sync(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
PeerSync.prototype.load_peers = function() {
|
PeerSync.prototype.load_peers = function() {
|
||||||
this.peerdb = [{
|
this.peerdb = [{
|
||||||
ipv4: config.bitcoind.host,
|
ipv4: config.bitcoind.host,
|
||||||
port: config.bitcoind.p2pPort
|
port: config.bitcoind.p2pPort
|
||||||
}];
|
}];
|
||||||
|
|
||||||
fs.writeFileSync(peerdb_fn, JSON.stringify(this.peerdb));
|
fs.writeFileSync(peerdb_fn, JSON.stringify(this.peerdb));
|
||||||
};
|
};
|
||||||
|
|
||||||
PeerSync.prototype.info = function() {
|
PeerSync.prototype.info = function() {
|
||||||
return {
|
return {
|
||||||
connected: this.connected,
|
connected: this.connected,
|
||||||
host: this.peerdb[0].ipv4,
|
host: this.peerdb[0].ipv4,
|
||||||
port: this.peerdb[0].port
|
port: this.peerdb[0].port
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
PeerSync.prototype.handleInv = function(info) {
|
PeerSync.prototype.handleInv = function(info) {
|
||||||
var invs = info.message.invs;
|
var invs = info.message.invs;
|
||||||
info.conn.sendGetData(invs);
|
info.conn.sendGetData(invs);
|
||||||
};
|
};
|
||||||
|
|
||||||
PeerSync.prototype.handleTx = function(info) {
|
PeerSync.prototype.handleTx = function(info) {
|
||||||
var tx = info.message.tx.getStandardizedObject();
|
var tx = info.message.tx.getStandardizedObject();
|
||||||
tx.outs = info.message.tx.outs;
|
tx.outs = info.message.tx.outs;
|
||||||
tx.ins = info.message.tx.ins;
|
tx.ins = info.message.tx.ins;
|
||||||
@ -57,9 +54,9 @@ function spec() {
|
|||||||
console.log('[p2p_sync] Error in handle TX: ' + JSON.stringify(err));
|
console.log('[p2p_sync] Error in handle TX: ' + JSON.stringify(err));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
PeerSync.prototype.handleBlock = function(info) {
|
PeerSync.prototype.handleBlock = function(info) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var block = info.message.block;
|
var block = info.message.block;
|
||||||
var blockHash = bitcoreUtil.formatHashFull(block.calcHash());
|
var blockHash = bitcoreUtil.formatHashFull(block.calcHash());
|
||||||
@ -85,15 +82,15 @@ function spec() {
|
|||||||
console.log('[p2p_sync] Error in handle Block: ' + err);
|
console.log('[p2p_sync] Error in handle Block: ' + err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
PeerSync.prototype.handle_connected = function(data) {
|
PeerSync.prototype.handle_connected = function(data) {
|
||||||
var peerman = data.pm;
|
var peerman = data.pm;
|
||||||
var peers_n = peerman.peers.length;
|
var peers_n = peerman.peers.length;
|
||||||
console.log('[p2p_sync] Connected to ' + peers_n + ' peer' + (peers_n !== 1 ? 's' : ''));
|
console.log('[p2p_sync] Connected to ' + peers_n + ' peer' + (peers_n !== 1 ? 's' : ''));
|
||||||
};
|
};
|
||||||
|
|
||||||
PeerSync.prototype.run = function() {
|
PeerSync.prototype.run = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
this.peerdb.forEach(function(datum) {
|
this.peerdb.forEach(function(datum) {
|
||||||
@ -114,14 +111,11 @@ function spec() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.peerman.start();
|
this.peerman.start();
|
||||||
};
|
};
|
||||||
|
|
||||||
PeerSync.prototype.close = function() {
|
PeerSync.prototype.close = function() {
|
||||||
this.sync.close();
|
this.sync.close();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return PeerSync;
|
module.exports = require('soop')(PeerSync);
|
||||||
|
|
||||||
}
|
|
||||||
module.defineClass(spec);
|
|
||||||
|
|||||||
@ -1,14 +1,11 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
require('classtool');
|
var imports = require('soop').imports();
|
||||||
|
var fs = require('fs');
|
||||||
|
var buffertools = require('buffertools');
|
||||||
|
var db = imports.db || JSON.parse( fs.readFileSync(imports.poolMatchFile || './poolMatchFile.json'));
|
||||||
|
|
||||||
function spec(b) {
|
var PoolMatch = function() {
|
||||||
|
|
||||||
var fs = require('fs');
|
|
||||||
var buffertools = require('buffertools');
|
|
||||||
var db = b.db || JSON.parse( fs.readFileSync(b.poolMatchFile || './poolMatchFile.json'));
|
|
||||||
|
|
||||||
var PoolMatch = function() {
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.strings = {};
|
self.strings = {};
|
||||||
@ -20,19 +17,16 @@ function spec(b) {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
PoolMatch.prototype.match = function(buffer) {
|
PoolMatch.prototype.match = function(buffer) {
|
||||||
var self = this;
|
var self = this;
|
||||||
for(var k in self.strings) {
|
for(var k in self.strings) {
|
||||||
if (buffertools.indexOf(buffer, k) >= 0) {
|
if (buffertools.indexOf(buffer, k) >= 0) {
|
||||||
return self.strings[k];
|
return self.strings[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return PoolMatch;
|
|
||||||
}
|
|
||||||
module.defineClass(spec);
|
|
||||||
|
|
||||||
|
module.exports = require('soop')(PoolMatch);
|
||||||
|
|||||||
42
lib/Rpc.js
42
lib/Rpc.js
@ -1,21 +1,19 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
require('classtool');
|
var imports = require('soop').imports();
|
||||||
|
|
||||||
|
var RpcClient = require('bitcore/RpcClient'),
|
||||||
function spec(b) {
|
BitcoreBlock = require('bitcore/Block'),
|
||||||
var RpcClient = require('bitcore/RpcClient').class(),
|
|
||||||
BitcoreBlock = require('bitcore/Block').class(),
|
|
||||||
bitcoreUtil = require('bitcore/util/util'),
|
bitcoreUtil = require('bitcore/util/util'),
|
||||||
util = require('util'),
|
util = require('util'),
|
||||||
config = require('../config/config');
|
config = require('../config/config');
|
||||||
|
|
||||||
var bitcoreRpc = b.bitcoreRpc || new RpcClient(config.bitcoind);
|
var bitcoreRpc = imports.bitcoreRpc || new RpcClient(config.bitcoind);
|
||||||
|
|
||||||
function Rpc() {
|
function Rpc() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Rpc._parseTxResult = function(info) {
|
Rpc._parseTxResult = function(info) {
|
||||||
var b = new Buffer(info.hex,'hex');
|
var b = new Buffer(info.hex,'hex');
|
||||||
|
|
||||||
// remove fields we dont need, to speed and adapt the information
|
// remove fields we dont need, to speed and adapt the information
|
||||||
@ -39,10 +37,10 @@ function spec(b) {
|
|||||||
info.size = b.length;
|
info.size = b.length;
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Rpc.errMsg = function(err) {
|
Rpc.errMsg = function(err) {
|
||||||
var e = err;
|
var e = err;
|
||||||
e.message += util.format(' [Host: %s:%d User:%s Using password:%s]',
|
e.message += util.format(' [Host: %s:%d User:%s Using password:%s]',
|
||||||
bitcoreRpc.host,
|
bitcoreRpc.host,
|
||||||
@ -51,9 +49,9 @@ function spec(b) {
|
|||||||
bitcoreRpc.pass?'yes':'no'
|
bitcoreRpc.pass?'yes':'no'
|
||||||
);
|
);
|
||||||
return e;
|
return e;
|
||||||
};
|
};
|
||||||
|
|
||||||
Rpc.getTxInfo = function(txid, doNotParse, cb) {
|
Rpc.getTxInfo = function(txid, doNotParse, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (typeof doNotParse === 'function') {
|
if (typeof doNotParse === 'function') {
|
||||||
@ -69,19 +67,19 @@ function spec(b) {
|
|||||||
var info = doNotParse ? txInfo.result : self._parseTxResult(txInfo.result);
|
var info = doNotParse ? txInfo.result : self._parseTxResult(txInfo.result);
|
||||||
return cb(null,info);
|
return cb(null,info);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Rpc.blockIndex = function(height, cb) {
|
Rpc.blockIndex = function(height, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
bitcoreRpc.getBlockHash(height, function(err, bh){
|
bitcoreRpc.getBlockHash(height, function(err, bh){
|
||||||
if (err) return cb(self.errMsg(err));
|
if (err) return cb(self.errMsg(err));
|
||||||
cb(null, { blockHash: bh.result });
|
cb(null, { blockHash: bh.result });
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Rpc.getBlock = function(hash, cb) {
|
Rpc.getBlock = function(hash, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
bitcoreRpc.getBlock(hash, function(err,info) {
|
bitcoreRpc.getBlock(hash, function(err,info) {
|
||||||
@ -95,9 +93,9 @@ function spec(b) {
|
|||||||
|
|
||||||
return cb(err,info.result);
|
return cb(err,info.result);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Rpc.sendRawTransaction = function(rawtx, cb) {
|
Rpc.sendRawTransaction = function(rawtx, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
bitcoreRpc.sendRawTransaction(rawtx, function(err, txid) {
|
bitcoreRpc.sendRawTransaction(rawtx, function(err, txid) {
|
||||||
if (err && err.code === -5) return cb(err); // transaction already in block chain
|
if (err && err.code === -5) return cb(err); // transaction already in block chain
|
||||||
@ -105,10 +103,8 @@ function spec(b) {
|
|||||||
|
|
||||||
return cb(err, txid.result);
|
return cb(err, txid.result);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return Rpc;
|
module.exports = require('soop')(Rpc);
|
||||||
}
|
|
||||||
module.defineClass(spec);
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
73
lib/Sync.js
73
lib/Sync.js
@ -1,19 +1,16 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
require('classtool');
|
var imports = require('soop').imports();
|
||||||
|
var sockets = require('../app/controllers/socket.js');
|
||||||
|
|
||||||
|
var BlockDb = require('./BlockDb').default();
|
||||||
|
var TransactionDb = require('./TransactionDb').default();
|
||||||
|
var config = require('../config/config');
|
||||||
|
var networks = require('bitcore/networks');
|
||||||
|
var async = require('async');
|
||||||
|
|
||||||
|
|
||||||
function spec() {
|
function Sync(opts) {
|
||||||
var sockets = require('../app/controllers/socket.js');
|
|
||||||
var BlockDb = require('./BlockDb').class();
|
|
||||||
|
|
||||||
var TransactionDb = require('./TransactionDb').class();
|
|
||||||
var config = require('../config/config');
|
|
||||||
var networks = require('bitcore/networks');
|
|
||||||
var async = require('async');
|
|
||||||
|
|
||||||
|
|
||||||
function Sync(opts) {
|
|
||||||
this.opts = opts || {};
|
this.opts = opts || {};
|
||||||
this.bDb = new BlockDb(opts);
|
this.bDb = new BlockDb(opts);
|
||||||
this.txDb = new TransactionDb(opts);
|
this.txDb = new TransactionDb(opts);
|
||||||
@ -21,17 +18,17 @@ function spec() {
|
|||||||
this.txDb.on('new_tx', this.handleNewTx.bind(this));
|
this.txDb.on('new_tx', this.handleNewTx.bind(this));
|
||||||
this.bDb.on('new_block', this.handleNewBlock.bind(this));
|
this.bDb.on('new_block', this.handleNewBlock.bind(this));
|
||||||
this.network = config.network === 'testnet' ? networks.testnet : networks.livenet;
|
this.network = config.network === 'testnet' ? networks.testnet : networks.livenet;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sync.prototype.close = function(cb) {
|
Sync.prototype.close = function(cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
self.txDb.close(function() {
|
self.txDb.close(function() {
|
||||||
self.bDb.close(cb);
|
self.bDb.close(cb);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Sync.prototype.destroy = function(next) {
|
Sync.prototype.destroy = function(next) {
|
||||||
var self = this;
|
var self = this;
|
||||||
async.series([
|
async.series([
|
||||||
|
|
||||||
@ -42,9 +39,9 @@ function spec() {
|
|||||||
self.txDb.drop(b);
|
self.txDb.drop(b);
|
||||||
},
|
},
|
||||||
], next);
|
], next);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Arrives a NEW block, which is the new TIP
|
* Arrives a NEW block, which is the new TIP
|
||||||
*
|
*
|
||||||
* Case 0) Simple case
|
* Case 0) Simple case
|
||||||
@ -74,7 +71,7 @@ function spec() {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Sync.prototype.storeTipBlock = function(b, allowReorgs, cb) {
|
Sync.prototype.storeTipBlock = function(b, allowReorgs, cb) {
|
||||||
|
|
||||||
if (typeof allowReorgs === 'function') {
|
if (typeof allowReorgs === 'function') {
|
||||||
cb = allowReorgs;
|
cb = allowReorgs;
|
||||||
@ -151,11 +148,11 @@ function spec() {
|
|||||||
}
|
}
|
||||||
return cb(err);
|
return cb(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Sync.prototype.processReorg = function(oldTip, oldNext, newPrev, cb) {
|
Sync.prototype.processReorg = function(oldTip, oldNext, newPrev, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var orphanizeFrom;
|
var orphanizeFrom;
|
||||||
@ -196,17 +193,17 @@ function spec() {
|
|||||||
function(err) {
|
function(err) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Sync.prototype.setBlockMain = function(hash, isMain, cb) {
|
Sync.prototype.setBlockMain = function(hash, isMain, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
self.bDb.setMain(hash, isMain, function(err) {
|
self.bDb.setMain(hash, isMain, function(err) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
return self.txDb.handleBlockChange(hash, isMain, cb);
|
return self.txDb.handleBlockChange(hash, isMain, cb);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Sync.prototype.setBranchOrphan = function(fromHash, cb) {
|
Sync.prototype.setBranchOrphan = function(fromHash, cb) {
|
||||||
var self = this,
|
var self = this,
|
||||||
hashInterator = fromHash;
|
hashInterator = fromHash;
|
||||||
|
|
||||||
@ -223,9 +220,9 @@ function spec() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}, cb);
|
}, cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
Sync.prototype.setBranchConnectedBackwards = function(fromHash, cb) {
|
Sync.prototype.setBranchConnectedBackwards = function(fromHash, cb) {
|
||||||
var self = this,
|
var self = this,
|
||||||
hashInterator = fromHash,
|
hashInterator = fromHash,
|
||||||
lastHash = fromHash,
|
lastHash = fromHash,
|
||||||
@ -254,36 +251,34 @@ function spec() {
|
|||||||
return cb(err, hashInterator, lastHash);
|
return cb(err, hashInterator, lastHash);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Sync.prototype.handleTxForAddress = function(data) {
|
Sync.prototype.handleTxForAddress = function(data) {
|
||||||
if (this.opts.shouldBroadcast) {
|
if (this.opts.shouldBroadcast) {
|
||||||
sockets.broadcastAddressTx(data.address, data.txid);
|
sockets.broadcastAddressTx(data.address, data.txid);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Sync.prototype.handleNewTx = function(data) {
|
Sync.prototype.handleNewTx = function(data) {
|
||||||
if (this.opts.shouldBroadcast) {
|
if (this.opts.shouldBroadcast) {
|
||||||
sockets.broadcastTx(data.tx);
|
sockets.broadcastTx(data.tx);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Sync.prototype.handleNewBlock = function(data) {
|
Sync.prototype.handleNewBlock = function(data) {
|
||||||
if (this.opts.shouldBroadcast) {
|
if (this.opts.shouldBroadcast) {
|
||||||
sockets.broadcastBlock(data.blockid);
|
sockets.broadcastBlock(data.blockid);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Sync.prototype.storeTxs = function(txs, cb) {
|
Sync.prototype.storeTxs = function(txs, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
self.txDb.createFromArray(txs, null, function(err) {
|
self.txDb.createFromArray(txs, null, function(err) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
return cb(err);
|
return cb(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return Sync;
|
module.exports = require('soop')(Sync);
|
||||||
}
|
|
||||||
module.defineClass(spec);
|
|
||||||
|
|||||||
@ -1,66 +1,63 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
require('classtool');
|
var imports = require('soop').imports();
|
||||||
|
|
||||||
|
var parent = imports.parent || require('events').EventEmitter;
|
||||||
|
// blockHash -> txid mapping
|
||||||
|
var IN_BLK_PREFIX = 'txb-'; //txb-<txid>-<block> => 1/0 (connected or not)
|
||||||
|
|
||||||
function spec(b) {
|
// Only for orphan blocks
|
||||||
|
var FROM_BLK_PREFIX = 'tx-'; //tx-<block>-<txid> => 1
|
||||||
|
|
||||||
var superclass = b.superclass || require('events').EventEmitter;
|
// to show tx outs
|
||||||
// blockHash -> txid mapping
|
var OUTS_PREFIX = 'txo-'; //txo-<txid>-<n> => [addr, btc_sat]
|
||||||
var IN_BLK_PREFIX = 'txb-'; //txb-<txid>-<block> => 1/0 (connected or not)
|
var SPENT_PREFIX = 'txs-'; //txs-<txid(out)>-<n(out)>-<txid(in)>-<n(in)> = ts
|
||||||
|
|
||||||
// Only for orphan blocks
|
// to sum up addr balance (only outs, spents are gotten later)
|
||||||
var FROM_BLK_PREFIX = 'tx-'; //tx-<block>-<txid> => 1
|
var ADDR_PREFIX = 'txa-'; //txa-<addr>-<txid>-<n> => + btc_sat:ts
|
||||||
|
|
||||||
// to show tx outs
|
// TODO: use bitcore networks module
|
||||||
var OUTS_PREFIX = 'txo-'; //txo-<txid>-<n> => [addr, btc_sat]
|
var genesisTXID = '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b';
|
||||||
var SPENT_PREFIX = 'txs-'; //txs-<txid(out)>-<n(out)>-<txid(in)>-<n(in)> = ts
|
var CONCURRENCY = 10;
|
||||||
|
|
||||||
// to sum up addr balance (only outs, spents are gotten later)
|
var MAX_OPEN_FILES = 500;
|
||||||
var ADDR_PREFIX = 'txa-'; //txa-<addr>-<txid>-<n> => + btc_sat:ts
|
|
||||||
|
|
||||||
// TODO: use bitcore networks module
|
|
||||||
var genesisTXID = '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b';
|
|
||||||
var CONCURRENCY = 10;
|
|
||||||
|
|
||||||
var MAX_OPEN_FILES = 500;
|
|
||||||
// var CONFIRMATION_NR_TO_NOT_CHECK = 10; //Spend
|
// var CONFIRMATION_NR_TO_NOT_CHECK = 10; //Spend
|
||||||
/**
|
/**
|
||||||
* Module dependencies.
|
* Module dependencies.
|
||||||
*/
|
*/
|
||||||
var Rpc = b.rpc || require('./Rpc').class(),
|
var Rpc = imports.rpc || require('./Rpc'),
|
||||||
util = require('bitcore/util/util'),
|
util = require('bitcore/util/util'),
|
||||||
levelup = require('levelup'),
|
levelup = require('levelup'),
|
||||||
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',{maxOpenFiles: MAX_OPEN_FILES} );
|
var db = imports.db || levelup(config.leveldb + '/txs',{maxOpenFiles: MAX_OPEN_FILES} );
|
||||||
var Script = require('bitcore/Script').class();
|
var Script = require('bitcore/Script');
|
||||||
// This is 0.1.2 => c++ version of base57-native
|
// This is 0.1.2 = > c++ version of base57-native
|
||||||
var base58 = require('base58-native').base58Check;
|
var base58 = require('base58-native').base58Check;
|
||||||
var encodedData = require('bitcore/util/EncodedData').class({
|
var encodedData = require('soop').load('bitcore/util/EncodedData',{
|
||||||
base58: base58
|
base58: base58
|
||||||
});
|
});
|
||||||
var versionedData = require('bitcore/util/VersionedData').class({
|
var versionedData= require('soop').load('bitcore/util/VersionedData',{
|
||||||
superclass: encodedData
|
patent: encodedData
|
||||||
});
|
});
|
||||||
var Address = require('bitcore/Address').class({
|
var Address = require('soop').load('bitcore/Address',{
|
||||||
superclass: versionedData
|
parent: versionedData
|
||||||
});
|
});
|
||||||
var bitutil = require('bitcore/util/util');
|
var bitutil = require('bitcore/util/util');
|
||||||
var networks = require('bitcore/networks');
|
var networks = require('bitcore/networks');
|
||||||
|
|
||||||
var TransactionDb = function() {
|
var TransactionDb = function() {
|
||||||
TransactionDb.super(this, arguments);
|
TransactionDb.super(this, arguments);
|
||||||
this.network = config.network === 'testnet' ? networks.testnet : networks.livenet;
|
this.network = config.network === 'testnet' ? networks.testnet : networks.livenet;
|
||||||
};
|
};
|
||||||
TransactionDb.superclass = superclass;
|
TransactionDb.parent = parent;
|
||||||
|
|
||||||
TransactionDb.prototype.close = function(cb) {
|
TransactionDb.prototype.close = function(cb) {
|
||||||
db.close(cb);
|
db.close(cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionDb.prototype.drop = function(cb) {
|
TransactionDb.prototype.drop = function(cb) {
|
||||||
var path = config.leveldb + '/txs';
|
var path = config.leveldb + '/txs';
|
||||||
db.close(function() {
|
db.close(function() {
|
||||||
require('leveldown').destroy(path, function() {
|
require('leveldown').destroy(path, function() {
|
||||||
@ -68,10 +65,10 @@ function spec(b) {
|
|||||||
return cb();
|
return cb();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
TransactionDb.prototype.has = function(txid, cb) {
|
TransactionDb.prototype.has = function(txid, cb) {
|
||||||
|
|
||||||
var k = OUTS_PREFIX + txid;
|
var k = OUTS_PREFIX + txid;
|
||||||
db.get(k, function(err, val) {
|
db.get(k, function(err, val) {
|
||||||
@ -87,9 +84,9 @@ function spec(b) {
|
|||||||
}
|
}
|
||||||
return cb(err, ret);
|
return cb(err, ret);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionDb.prototype._addSpentInfo = function(r, txid, index, ts) {
|
TransactionDb.prototype._addSpentInfo = function(r, txid, index, ts) {
|
||||||
if (r.spentTxId) {
|
if (r.spentTxId) {
|
||||||
if (!r.multipleSpentAttempts) {
|
if (!r.multipleSpentAttempts) {
|
||||||
r.multipleSpentAttempts = [{
|
r.multipleSpentAttempts = [{
|
||||||
@ -106,11 +103,11 @@ function spec(b) {
|
|||||||
r.spentIndex = parseInt(index);
|
r.spentIndex = parseInt(index);
|
||||||
r.spentTs = parseInt(ts);
|
r.spentTs = parseInt(ts);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// This is not used now
|
// This is not used now
|
||||||
TransactionDb.prototype.fromTxId = function(txid, cb) {
|
TransactionDb.prototype.fromTxId = function(txid, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var k = OUTS_PREFIX + txid;
|
var k = OUTS_PREFIX + txid;
|
||||||
var ret = [];
|
var ret = [];
|
||||||
@ -158,10 +155,10 @@ function spec(b) {
|
|||||||
return cb(err, ret);
|
return cb(err, ret);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
TransactionDb.prototype._fillSpent = function(info, cb) {
|
TransactionDb.prototype._fillSpent = function(info, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (!info) return cb();
|
if (!info) return cb();
|
||||||
@ -181,10 +178,10 @@ function spec(b) {
|
|||||||
.on('end', function(err) {
|
.on('end', function(err) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
TransactionDb.prototype._fillOutpoints = function(info, cb) {
|
TransactionDb.prototype._fillOutpoints = function(info, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (!info || info.isCoinBase) return cb();
|
if (!info || info.isCoinBase) return cb();
|
||||||
@ -210,9 +207,9 @@ function spec(b) {
|
|||||||
valueIn += i.valueSat;
|
valueIn += i.valueSat;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If confirmed by bitcoind, we could not check for double spents
|
* If confirmed by bitcoind, we could not check for double spents
|
||||||
* but we prefer to keep the flag of double spent attempt
|
* but we prefer to keep the flag of double spent attempt
|
||||||
*
|
*
|
||||||
if (info.confirmations
|
if (info.confirmations
|
||||||
&& info.confirmations >= CONFIRMATION_NR_TO_NOT_CHECK)
|
&& info.confirmations >= CONFIRMATION_NR_TO_NOT_CHECK)
|
||||||
return c_in();
|
return c_in();
|
||||||
@ -250,9 +247,9 @@ isspent
|
|||||||
}
|
}
|
||||||
return cb();
|
return cb();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionDb.prototype._getInfo = function(txid, next) {
|
TransactionDb.prototype._getInfo = function(txid, next) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
Rpc.getTxInfo(txid, function(err, info) {
|
Rpc.getTxInfo(txid, function(err, info) {
|
||||||
@ -264,19 +261,19 @@ isspent
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Simplified / faster Info version: No spent / outpoints info.
|
// Simplified / faster Info version: No spent / outpoints info.
|
||||||
TransactionDb.prototype.fromIdInfoSimple = function(txid, cb) {
|
TransactionDb.prototype.fromIdInfoSimple = function(txid, cb) {
|
||||||
Rpc.getTxInfo(txid, true, function(err, info) {
|
Rpc.getTxInfo(txid, true, function(err, info) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
if (!info) return cb();
|
if (!info) return cb();
|
||||||
return cb(err, info);
|
return cb(err, info);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionDb.prototype.fromIdWithInfo = function(txid, cb) {
|
TransactionDb.prototype.fromIdWithInfo = function(txid, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self._getInfo(txid, function(err, info) {
|
self._getInfo(txid, function(err, info) {
|
||||||
@ -287,9 +284,9 @@ isspent
|
|||||||
info: info
|
info: info
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionDb.prototype.fromTxIdN = function(txid, n, confirmations, cb) {
|
TransactionDb.prototype.fromTxIdN = function(txid, n, confirmations, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var k = OUTS_PREFIX + txid + '-' + n;
|
var k = OUTS_PREFIX + txid + '-' + n;
|
||||||
|
|
||||||
@ -335,9 +332,9 @@ isspent
|
|||||||
return cb(null, ret);
|
return cb(null, ret);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionDb.prototype.fillConfirmations = function(o, cb) {
|
TransactionDb.prototype.fillConfirmations = function(o, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.isConfirmed(o.txid, function(err, is) {
|
self.isConfirmed(o.txid, function(err, is) {
|
||||||
@ -368,9 +365,9 @@ isspent
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionDb.prototype.fromAddr = function(addr, cb) {
|
TransactionDb.prototype.fromAddr = function(addr, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var k = ADDR_PREFIX + addr + '-';
|
var k = ADDR_PREFIX + addr + '-';
|
||||||
@ -420,10 +417,10 @@ isspent
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
TransactionDb.prototype.removeFromTxId = function(txid, cb) {
|
TransactionDb.prototype.removeFromTxId = function(txid, cb) {
|
||||||
|
|
||||||
async.series([
|
async.series([
|
||||||
|
|
||||||
@ -453,12 +450,12 @@ isspent
|
|||||||
cb(err);
|
cb(err);
|
||||||
});
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// TODO. replace with
|
// TODO. replace with
|
||||||
// Script.prototype.getAddrStrs if that one get merged in bitcore
|
// Script.prototype.getAddrStrs if that one get merged in bitcore
|
||||||
TransactionDb.prototype.getAddrStr = function(s) {
|
TransactionDb.prototype.getAddrStr = function(s) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var addrStrs = [];
|
var addrStrs = [];
|
||||||
@ -491,9 +488,9 @@ isspent
|
|||||||
}
|
}
|
||||||
|
|
||||||
return addrStrs;
|
return addrStrs;
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionDb.prototype.adaptTxObject = function(txInfo) {
|
TransactionDb.prototype.adaptTxObject = function(txInfo) {
|
||||||
var self = this;
|
var self = this;
|
||||||
// adapt bitcore TX object to bitcoind JSON response
|
// adapt bitcore TX object to bitcoind JSON response
|
||||||
txInfo.txid = txInfo.hash;
|
txInfo.txid = txInfo.hash;
|
||||||
@ -543,11 +540,11 @@ isspent
|
|||||||
}
|
}
|
||||||
return o;
|
return o;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TransactionDb.prototype.add = function(tx, blockhash, cb) {
|
TransactionDb.prototype.add = function(tx, blockhash, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var addrs = [];
|
var addrs = [];
|
||||||
|
|
||||||
@ -631,11 +628,11 @@ isspent
|
|||||||
|
|
||||||
return cb(err);
|
return cb(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TransactionDb.prototype.setConfirmation = function(txId, blockHash, confirmed, c) {
|
TransactionDb.prototype.setConfirmation = function(txId, blockHash, confirmed, c) {
|
||||||
if (!blockHash) return c();
|
if (!blockHash) return c();
|
||||||
|
|
||||||
confirmed = confirmed ? 1 : 0;
|
confirmed = confirmed ? 1 : 0;
|
||||||
@ -644,11 +641,11 @@ isspent
|
|||||||
.put(IN_BLK_PREFIX + txId + '-' + blockHash, confirmed)
|
.put(IN_BLK_PREFIX + txId + '-' + blockHash, confirmed)
|
||||||
.put(FROM_BLK_PREFIX + blockHash + '-' + txId, 1)
|
.put(FROM_BLK_PREFIX + blockHash + '-' + txId, 1)
|
||||||
.write(c);
|
.write(c);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// This slowdown addr balance calculation by 100%
|
// This slowdown addr balance calculation by 100%
|
||||||
TransactionDb.prototype.isConfirmed = function(txId, c) {
|
TransactionDb.prototype.isConfirmed = function(txId, c) {
|
||||||
var k = IN_BLK_PREFIX + txId;
|
var k = IN_BLK_PREFIX + txId;
|
||||||
var ret = false;
|
var ret = false;
|
||||||
|
|
||||||
@ -665,9 +662,9 @@ isspent
|
|||||||
.on('end', function(err) {
|
.on('end', function(err) {
|
||||||
return c(err, ret);
|
return c(err, ret);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionDb.prototype.handleBlockChange = function(hash, isMain, cb) {
|
TransactionDb.prototype.handleBlockChange = function(hash, isMain, cb) {
|
||||||
var toChange = [];
|
var toChange = [];
|
||||||
console.log('\tSearching Txs from block:' + hash);
|
console.log('\tSearching Txs from block:' + hash);
|
||||||
|
|
||||||
@ -694,10 +691,10 @@ isspent
|
|||||||
console.log('\t%s %d Txs', isMain ? 'Confirming' : 'Invalidating', toChange.length);
|
console.log('\t%s %d Txs', isMain ? 'Confirming' : 'Invalidating', toChange.length);
|
||||||
db.batch(toChange, cb);
|
db.batch(toChange, cb);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// txs can be a [hashes] or [txObjects]
|
// txs can be a [hashes] or [txObjects]
|
||||||
TransactionDb.prototype.createFromArray = function(txs, blockHash, next) {
|
TransactionDb.prototype.createFromArray = function(txs, blockHash, next) {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (!txs) return next();
|
if (!txs) return next();
|
||||||
|
|
||||||
@ -718,16 +715,14 @@ isspent
|
|||||||
function(err) {
|
function(err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
TransactionDb.prototype.createFromBlock = function(b, next) {
|
TransactionDb.prototype.createFromBlock = function(b, next) {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (!b || !b.tx) return next();
|
if (!b || !b.tx) return next();
|
||||||
|
|
||||||
return self.createFromArray(b.tx, b.hash, next);
|
return self.createFromArray(b.tx, b.hash, next);
|
||||||
};
|
};
|
||||||
|
|
||||||
return TransactionDb;
|
module.exports = require('soop')(TransactionDb);
|
||||||
}
|
|
||||||
module.defineClass(spec);
|
|
||||||
|
|||||||
@ -57,7 +57,7 @@
|
|||||||
"leveldown": "*",
|
"leveldown": "*",
|
||||||
"levelup": "*",
|
"levelup": "*",
|
||||||
"glob": "*",
|
"glob": "*",
|
||||||
"classtool": "*",
|
"soop": "git://github.com/gasteve/node-soop.git",
|
||||||
"commander": "*",
|
"commander": "*",
|
||||||
"bignum": "*",
|
"bignum": "*",
|
||||||
"express": "~3.4.7",
|
"express": "~3.4.7",
|
||||||
|
|||||||
@ -11,7 +11,7 @@ var
|
|||||||
util = require('util'),
|
util = require('util'),
|
||||||
async = require('async'),
|
async = require('async'),
|
||||||
config = require('../../config/config'),
|
config = require('../../config/config'),
|
||||||
TransactionDb = require('../../lib/TransactionDb').class();
|
TransactionDb = require('../../lib/TransactionDb').default();
|
||||||
|
|
||||||
var spentValid = JSON.parse(fs.readFileSync('test/integration/spent.json'));
|
var spentValid = JSON.parse(fs.readFileSync('test/integration/spent.json'));
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user