commit
a7cadf0371
|
@ -151,6 +151,7 @@ Address.prototype._addTxItem = function(txItem, notxlist) {
|
||||||
this.unconfirmedBalanceSat += v;
|
this.unconfirmedBalanceSat += v;
|
||||||
this.unconfirmedTxApperances += add;
|
this.unconfirmedTxApperances += add;
|
||||||
}
|
}
|
||||||
|
|
||||||
return txs;
|
return txs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,9 @@ var path = require('path'),
|
||||||
b_port,
|
b_port,
|
||||||
p2p_port;
|
p2p_port;
|
||||||
|
|
||||||
|
var packageStr = fs.readFileSync('package.json');
|
||||||
|
var version = JSON.parse(packageStr).version;
|
||||||
|
|
||||||
|
|
||||||
function getUserHome() {
|
function getUserHome() {
|
||||||
return process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];
|
return process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];
|
||||||
|
@ -57,6 +60,59 @@ if (!dataDir) {
|
||||||
}
|
}
|
||||||
dataDir += network === 'testnet' ? 'testnet3' : '';
|
dataDir += network === 'testnet' ? 'testnet3' : '';
|
||||||
|
|
||||||
|
var safeConfirmations = process.env.SAFE_CONFIRMATIONS || 6;
|
||||||
|
|
||||||
|
|
||||||
|
var bitcoindConf = {
|
||||||
|
protocol: process.env.BITCOIND_PROTO || 'http',
|
||||||
|
user: process.env.BITCOIND_USER || 'user',
|
||||||
|
pass: process.env.BITCOIND_PASS || 'pass',
|
||||||
|
host: process.env.BITCOIND_HOST || '127.0.0.1',
|
||||||
|
port: process.env.BITCOIND_PORT || b_port,
|
||||||
|
p2pPort: process.env.BITCOIND_P2P_PORT || p2p_port,
|
||||||
|
dataDir: dataDir,
|
||||||
|
// DO NOT CHANGE THIS!
|
||||||
|
disableAgent: true
|
||||||
|
};
|
||||||
|
|
||||||
|
/*jshint multistr: true */
|
||||||
|
console.log(
|
||||||
|
'\n\
|
||||||
|
____ _ __ __ ___ _ \n\
|
||||||
|
/ _/___ _____(_)___ _/ /_ / /_ / | ____ (_)\n\
|
||||||
|
/ // __ \\/ ___/ / __ `/ __ \\/ __/ / /\| \| / __ \\/ / \n\
|
||||||
|
_/ // / / (__ ) / /_/ / / / / /_ / ___ |/ /_/ / / \n\
|
||||||
|
/___/_/ /_/____/_/\\__, /_/ /_/\\__/ /_/ |_/ .___/_/ \n\
|
||||||
|
/____/ /_/ \n\
|
||||||
|
\n\t\t\t\t\t\tv%s\n\
|
||||||
|
# Configuration:\n\
|
||||||
|
\t\tNetwork: %s\tINSIGHT_NETWORK\n\
|
||||||
|
\t\tDatabase Path: %s\tINSIGHT_DB\n\
|
||||||
|
\t\tSafe Confirmations: %s\tSAFE_CONFIRMATIONS\n\
|
||||||
|
# Bicoind Connection configuration:\n\
|
||||||
|
\t\tRPC Username: %s\tBITCOIND_USER\n\
|
||||||
|
\t\tRPC Password: %s\tBITCOIND_PASS\n\
|
||||||
|
\t\tRPC Protocol: %s\tBITCOIND_PROTO\n\
|
||||||
|
\t\tRPC Host: %s\tBITCOIND_HOST\n\
|
||||||
|
\t\tRPC Port: %s\tBITCOIND_PORT\n\
|
||||||
|
\t\tP2P Port: %s\tBITCOIND_P2P_PORT\n\
|
||||||
|
\t\tData Dir: %s\tBITCOIND_DATADIR\n\
|
||||||
|
\t\t%s\n\
|
||||||
|
\nChange setting by assigning the enviroment variables in the last column. Example:\n\
|
||||||
|
$ INSIGHT_NETWORK="testnet" BITCOIND_HOST="123.123.123.123" ./insight.js\
|
||||||
|
\n\n',
|
||||||
|
version,
|
||||||
|
network, home, safeConfirmations,
|
||||||
|
bitcoindConf.user,
|
||||||
|
bitcoindConf.pass?'Yes(hidden)':'No',
|
||||||
|
bitcoindConf.protocol,
|
||||||
|
bitcoindConf.host,
|
||||||
|
bitcoindConf.port,
|
||||||
|
bitcoindConf.p2p_port,
|
||||||
|
dataDir+(network==='testnet'?'*':''),
|
||||||
|
(network==='testnet'?'* (/testnet3 is added automatically)':'')
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
if (! fs.existsSync(db)){
|
if (! fs.existsSync(db)){
|
||||||
|
|
||||||
|
@ -71,17 +127,7 @@ module.exports = {
|
||||||
apiPrefix: '/api',
|
apiPrefix: '/api',
|
||||||
port: port,
|
port: port,
|
||||||
leveldb: db,
|
leveldb: db,
|
||||||
bitcoind: {
|
bitcoind: bitcoindConf,
|
||||||
protocol: process.env.BITCOIND_PROTO || 'http',
|
|
||||||
user: process.env.BITCOIND_USER || 'user',
|
|
||||||
pass: process.env.BITCOIND_PASS || 'pass',
|
|
||||||
host: process.env.BITCOIND_HOST || '127.0.0.1',
|
|
||||||
port: process.env.BITCOIND_PORT || b_port,
|
|
||||||
p2pPort: process.env.BITCOIND_P2P_PORT || p2p_port,
|
|
||||||
dataDir: dataDir,
|
|
||||||
// DO NOT CHANGE THIS!
|
|
||||||
disableAgent: true
|
|
||||||
},
|
|
||||||
network: network,
|
network: network,
|
||||||
disableP2pSync: false,
|
disableP2pSync: false,
|
||||||
disableHistoricSync: false,
|
disableHistoricSync: false,
|
||||||
|
@ -92,5 +138,5 @@ module.exports = {
|
||||||
keys: {
|
keys: {
|
||||||
segmentio: process.env.INSIGHT_SEGMENTIO_KEY
|
segmentio: process.env.INSIGHT_SEGMENTIO_KEY
|
||||||
},
|
},
|
||||||
safeConfirmations: 6, // PLEASE NOTE THAT *FULL RESYNC* IS NEEDED TO CHANGE safeConfirmations
|
safeConfirmations: safeConfirmations, // PLEASE NOTE THAT *FULL RESYNC* IS NEEDED TO CHANGE safeConfirmations
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
//Set the node enviornment variable if not set before
|
//Set the node enviornment variable if not set before
|
||||||
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
|
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ function BlockExtractor(dataDir, network) {
|
||||||
self.dataDir = dataDir;
|
self.dataDir = dataDir;
|
||||||
self.files = glob.sync(path);
|
self.files = glob.sync(path);
|
||||||
self.nfiles = self.files.length;
|
self.nfiles = self.files.length;
|
||||||
self.errorCount =0;
|
|
||||||
|
|
||||||
if (self.nfiles === 0)
|
if (self.nfiles === 0)
|
||||||
throw new Error('Could not find block files at: ' + path);
|
throw new Error('Could not find block files at: ' + path);
|
||||||
|
@ -98,41 +97,30 @@ BlockExtractor.prototype.getNextBlock = function(cb) {
|
||||||
|
|
||||||
async.whilst(
|
async.whilst(
|
||||||
function() {
|
function() {
|
||||||
return (!magic || magic === '00000000');
|
return (!magic);
|
||||||
},
|
},
|
||||||
function(w_cb) {
|
function(w_cb) {
|
||||||
magic = null;
|
|
||||||
|
|
||||||
self.readCurrentFileSync();
|
self.readCurrentFileSync();
|
||||||
|
|
||||||
if (self.currentFileIndex < 0) return cb();
|
if (self.currentFileIndex < 0) return cb();
|
||||||
|
|
||||||
var byte0 = self.currentParser ? self.currentParser.buffer(1).toString('hex') : null;
|
|
||||||
|
|
||||||
if (byte0) {
|
magic = self.currentParser ? self.currentParser.buffer(4).toString('hex')
|
||||||
// Grab 3 bytes from block without removing them
|
: null ;
|
||||||
var p = self.currentParser.pos;
|
|
||||||
var bytes123 = self.currentParser.subject.toString('hex',p,p+3);
|
|
||||||
magic = byte0 + bytes123;
|
|
||||||
|
|
||||||
if (magic !=='00000000' && magic !== self.magic) {
|
|
||||||
|
|
||||||
if (self.errorCount++ > 4)
|
|
||||||
return cb(new Error('CRITICAL ERROR: Magic number mismatch: ' +
|
|
||||||
magic + '!=' + self.magic));
|
|
||||||
|
|
||||||
|
if (!self.currentParser || self.currentParser.eof() || magic === '00000000') {
|
||||||
magic = null;
|
magic = null;
|
||||||
}
|
if (self.nextFile()) {
|
||||||
}
|
|
||||||
|
|
||||||
if (!self.currentParser || self.currentParser.eof() ) {
|
|
||||||
if (self.nextFile())
|
|
||||||
console.log('Moving forward to file:' + self.currentFile() );
|
console.log('Moving forward to file:' + self.currentFile() );
|
||||||
else
|
return w_cb();
|
||||||
|
}
|
||||||
|
else {
|
||||||
console.log('Finished all files');
|
console.log('Finished all files');
|
||||||
|
|
||||||
magic = null;
|
magic = null;
|
||||||
return w_cb();
|
return w_cb();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
return w_cb();
|
return w_cb();
|
||||||
}
|
}
|
||||||
|
@ -140,8 +128,14 @@ BlockExtractor.prototype.getNextBlock = function(cb) {
|
||||||
},
|
},
|
||||||
function (a_cb) {
|
function (a_cb) {
|
||||||
if (!magic) return a_cb();
|
if (!magic) return a_cb();
|
||||||
// Remove 3 bytes from magic and spacer
|
if (magic !== self.magic) {
|
||||||
self.currentParser.buffer(3+4);
|
var e = new Error('CRITICAL ERROR: Magic number mismatch: ' +
|
||||||
|
magic + '!=' + self.magic);
|
||||||
|
return a_cb(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// spacer?
|
||||||
|
self.currentParser.word32le();
|
||||||
return a_cb();
|
return a_cb();
|
||||||
},
|
},
|
||||||
function (a_cb) {
|
function (a_cb) {
|
||||||
|
@ -150,7 +144,6 @@ BlockExtractor.prototype.getNextBlock = function(cb) {
|
||||||
b = new Block();
|
b = new Block();
|
||||||
b.parse(self.currentParser);
|
b.parse(self.currentParser);
|
||||||
b.getHash();
|
b.getHash();
|
||||||
self.errorCount=0;
|
|
||||||
return a_cb();
|
return a_cb();
|
||||||
},
|
},
|
||||||
], function(err) {
|
], function(err) {
|
||||||
|
|
|
@ -36,13 +36,14 @@ function HistoricSync(opts) {
|
||||||
|
|
||||||
this.rpc = new RpcClient(config.bitcoind);
|
this.rpc = new RpcClient(config.bitcoind);
|
||||||
this.sync = new Sync(opts);
|
this.sync = new Sync(opts);
|
||||||
|
this.height =0;
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoricSync.prototype.showProgress = function() {
|
HistoricSync.prototype.showProgress = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if ( self.status ==='syncing' &&
|
if ( self.status ==='syncing' &&
|
||||||
( self.syncedBlocks ) % self.step !== 1) return;
|
( self.height ) % self.step !== 1) return;
|
||||||
|
|
||||||
if (self.error)
|
if (self.error)
|
||||||
error(self.error);
|
error(self.error);
|
||||||
|
@ -82,7 +83,7 @@ HistoricSync.prototype.info = function() {
|
||||||
status: this.status,
|
status: this.status,
|
||||||
blockChainHeight: this.blockChainHeight,
|
blockChainHeight: this.blockChainHeight,
|
||||||
syncPercentage: this.syncPercentage,
|
syncPercentage: this.syncPercentage,
|
||||||
syncedBlocks: this.syncedBlocks,
|
height: this.height,
|
||||||
syncTipHash: this.sync.tip,
|
syncTipHash: this.sync.tip,
|
||||||
error: this.error,
|
error: this.error,
|
||||||
type: this.type,
|
type: this.type,
|
||||||
|
@ -92,7 +93,7 @@ HistoricSync.prototype.info = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
HistoricSync.prototype.updatePercentage = function() {
|
HistoricSync.prototype.updatePercentage = function() {
|
||||||
var r = this.syncedBlocks / this.blockChainHeight;
|
var r = this.height / 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;
|
||||||
};
|
};
|
||||||
|
@ -153,16 +154,6 @@ HistoricSync.prototype.getBlockFromFile = function(cb) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
HistoricSync.prototype.updateConnectedCountDB = function(cb) {
|
|
||||||
var self = this;
|
|
||||||
self.sync.bDb.countConnected(function(err, count) {
|
|
||||||
self.connectedCountDB = count || 0;
|
|
||||||
self.syncedBlocks = count || 0;
|
|
||||||
return cb(err);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
HistoricSync.prototype.updateBlockChainHeight = function(cb) {
|
HistoricSync.prototype.updateBlockChainHeight = function(cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
@ -199,7 +190,7 @@ HistoricSync.prototype.updateStartBlock = function(next) {
|
||||||
|
|
||||||
self.startBlock = self.genesis;
|
self.startBlock = self.genesis;
|
||||||
|
|
||||||
self.sync.bDb.getTip(function(err,tip) {
|
self.sync.bDb.getTip(function(err,tip, height) {
|
||||||
if (!tip) return next();
|
if (!tip) return next();
|
||||||
|
|
||||||
var blockInfo;
|
var blockInfo;
|
||||||
|
@ -219,6 +210,12 @@ HistoricSync.prototype.updateStartBlock = function(next) {
|
||||||
function(err) {
|
function(err) {
|
||||||
if (err) return next(err);
|
if (err) return next(err);
|
||||||
var ret = false;
|
var ret = false;
|
||||||
|
|
||||||
|
var d = Math.abs(height-blockInfo.height);
|
||||||
|
if (d>6) {
|
||||||
|
error('Previous Tip block tip height differs by %d. Please delete and resync (-D)',d);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
if ( self.blockChainHeight === blockInfo.height ||
|
if ( self.blockChainHeight === blockInfo.height ||
|
||||||
blockInfo.confirmations > 0) {
|
blockInfo.confirmations > 0) {
|
||||||
ret = false;
|
ret = false;
|
||||||
|
@ -227,7 +224,6 @@ HistoricSync.prototype.updateStartBlock = function(next) {
|
||||||
oldtip = tip;
|
oldtip = tip;
|
||||||
if (!tip)
|
if (!tip)
|
||||||
throw new Error('Previous blockchain tip was not found on bitcoind. Please reset Insight DB. Tip was:'+tip)
|
throw new Error('Previous blockchain tip was not found on bitcoind. Please reset Insight DB. Tip was:'+tip)
|
||||||
|
|
||||||
tip = blockInfo.previousblockhash;
|
tip = blockInfo.previousblockhash;
|
||||||
info('Previous TIP is now orphan. Back to:' + tip);
|
info('Previous TIP is now orphan. Back to:' + tip);
|
||||||
ret = true;
|
ret = true;
|
||||||
|
@ -236,7 +232,8 @@ HistoricSync.prototype.updateStartBlock = function(next) {
|
||||||
},
|
},
|
||||||
function(err) {
|
function(err) {
|
||||||
self.startBlock = tip;
|
self.startBlock = tip;
|
||||||
info('Resuming sync from block:'+tip);
|
self.height = height;
|
||||||
|
info('Resuming sync from block: %s #%d',tip,height);
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -247,7 +244,7 @@ HistoricSync.prototype.prepareFileSync = function(opts, next) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if ( opts.forceRPC || !config.bitcoind.dataDir ||
|
if ( opts.forceRPC || !config.bitcoind.dataDir ||
|
||||||
self.connectedCountDB > self.blockChainHeight * 0.9) return next();
|
self.height > self.blockChainHeight * 0.9) return next();
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -260,6 +257,7 @@ HistoricSync.prototype.prepareFileSync = function(opts, next) {
|
||||||
self.getFn = self.getBlockFromFile;
|
self.getFn = self.getBlockFromFile;
|
||||||
self.allowReorgs = true;
|
self.allowReorgs = true;
|
||||||
self.sync.bDb.getLastFileIndex(function(err, idx) {
|
self.sync.bDb.getLastFileIndex(function(err, idx) {
|
||||||
|
|
||||||
if (opts.forceStartFile)
|
if (opts.forceStartFile)
|
||||||
self.blockExtractor.currentFileIndex = opts.forceStartFile;
|
self.blockExtractor.currentFileIndex = opts.forceStartFile;
|
||||||
else if (idx) self.blockExtractor.currentFileIndex = idx;
|
else if (idx) self.blockExtractor.currentFileIndex = idx;
|
||||||
|
@ -280,7 +278,9 @@ HistoricSync.prototype.prepareFileSync = function(opts, next) {
|
||||||
return w_cb(err);
|
return w_cb(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}, next);
|
}, function(err){
|
||||||
|
return next(err);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -298,7 +298,7 @@ HistoricSync.prototype.prepareRpcSync = function(opts, next) {
|
||||||
HistoricSync.prototype.showSyncStartMessage = function() {
|
HistoricSync.prototype.showSyncStartMessage = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
info('Got ' + self.connectedCountDB +
|
info('Got ' + self.height +
|
||||||
' blocks in current DB, out of ' + self.blockChainHeight + ' block at bitcoind');
|
' blocks in current DB, out of ' + self.blockChainHeight + ' block at bitcoind');
|
||||||
|
|
||||||
if (self.blockExtractor) {
|
if (self.blockExtractor) {
|
||||||
|
@ -317,7 +317,7 @@ HistoricSync.prototype.showSyncStartMessage = function() {
|
||||||
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.height) / 1000);
|
||||||
if (step < 10) step = 10;
|
if (step < 10) step = 10;
|
||||||
|
|
||||||
self.step = step;
|
self.step = step;
|
||||||
|
@ -335,10 +335,10 @@ HistoricSync.prototype.prepareToSync = function(opts, next) {
|
||||||
self.status = 'starting';
|
self.status = 'starting';
|
||||||
async.series([
|
async.series([
|
||||||
function(s_c) {
|
function(s_c) {
|
||||||
self.checkNetworkSettings(s_c);
|
self.sync.txDb.checkVersion02(s_c);
|
||||||
},
|
},
|
||||||
function(s_c) {
|
function(s_c) {
|
||||||
self.updateConnectedCountDB(s_c);
|
self.checkNetworkSettings(s_c);
|
||||||
},
|
},
|
||||||
function(s_c) {
|
function(s_c) {
|
||||||
self.updateBlockChainHeight(s_c);
|
self.updateBlockChainHeight(s_c);
|
||||||
|
@ -382,12 +382,10 @@ HistoricSync.prototype.start = function(opts, next) {
|
||||||
function (w_cb) {
|
function (w_cb) {
|
||||||
self.getFn(function(err,blockInfo) {
|
self.getFn(function(err,blockInfo) {
|
||||||
if (err) return w_cb(self.setError(err));
|
if (err) return w_cb(self.setError(err));
|
||||||
if (blockInfo && blockInfo.hash
|
if (blockInfo && blockInfo.hash && (!opts.stopAt || opts.stopAt !== blockInfo.hash)) {
|
||||||
&& (!opts.stopAt || opts.stopAt !== blockInfo.hash)
|
self.sync.storeTipBlock(blockInfo, self.allowReorgs, function(err, height) {
|
||||||
) {
|
|
||||||
self.syncedBlocks++;
|
|
||||||
self.sync.storeTipBlock(blockInfo, self.allowReorgs, function(err) {
|
|
||||||
if (err) return w_cb(self.setError(err));
|
if (err) return w_cb(self.setError(err));
|
||||||
|
self.height=height;
|
||||||
setImmediate(function(){
|
setImmediate(function(){
|
||||||
return w_cb(err);
|
return w_cb(err);
|
||||||
});
|
});
|
||||||
|
|
|
@ -164,7 +164,7 @@ Sync.prototype.storeTipBlock = function(b, allowReorgs, cb) {
|
||||||
if (err && err.toString().match(/WARN/)) {
|
if (err && err.toString().match(/WARN/)) {
|
||||||
err = null;
|
err = null;
|
||||||
}
|
}
|
||||||
return cb(err);
|
return cb(err, height);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,8 @@ var OUTS_PREFIX = 'txo-'; //txo-<txid>-<n> => [addr, btc_sat]
|
||||||
var SPENT_PREFIX = 'txs-'; //txs-<txid(out)>-<n(out)>-<txid(in)>-<n(in)> = ts
|
var SPENT_PREFIX = 'txs-'; //txs-<txid(out)>-<n(out)>-<txid(in)>-<n(in)> = ts
|
||||||
|
|
||||||
// to sum up addr balance (only outs, spents are gotten later)
|
// to sum up addr balance (only outs, spents are gotten later)
|
||||||
var ADDR_PREFIX = 'txa-'; //txa-<addr>-<txid>-<n> => + btc_sat:ts [:<txid>-<n>](spent)
|
var ADDR_PREFIX = 'txa-'; //txa-<addr>-<txid>-<n>
|
||||||
|
// => + btc_sat:ts [:isConfirmed:[scriptPubKey|isSpendConfirmed:SpentTxid:SpentVout:SpentTs]
|
||||||
|
|
||||||
// TODO: use bitcore networks module
|
// TODO: use bitcore networks module
|
||||||
var genesisTXID = '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b';
|
var genesisTXID = '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b';
|
||||||
|
@ -178,7 +179,7 @@ TransactionDb.prototype._fillOutpoints = function(txInfo, cb) {
|
||||||
var incompleteInputs = 0;
|
var incompleteInputs = 0;
|
||||||
|
|
||||||
async.eachLimit(txInfo.vin, CONCURRENCY, function(i, c_in) {
|
async.eachLimit(txInfo.vin, CONCURRENCY, function(i, c_in) {
|
||||||
self.fromTxIdN(i.txid, i.vout, txInfo.confirmations, function(err, ret) {
|
self.fromTxIdN(i.txid, i.vout, function(err, ret) {
|
||||||
if (!ret || !ret.addr || !ret.valueSat) {
|
if (!ret || !ret.addr || !ret.valueSat) {
|
||||||
info('Could not get TXouts in %s,%d from %s ', i.txid, i.vout, txInfo.txid);
|
info('Could not get TXouts in %s,%d from %s ', i.txid, i.vout, txInfo.txid);
|
||||||
if (ret) i.unconfirmedInput = ret.unconfirmedInput;
|
if (ret) i.unconfirmedInput = ret.unconfirmedInput;
|
||||||
|
@ -272,7 +273,7 @@ TransactionDb.prototype.fromIdWithInfo = function(txid, cb) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionDb.prototype.fromTxIdN = function(txid, n, confirmations, cb) {
|
TransactionDb.prototype.fromTxIdN = function(txid, n, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var k = OUTS_PREFIX + txid + '-' + n;
|
var k = OUTS_PREFIX + txid + '-' + n;
|
||||||
|
|
||||||
|
@ -289,18 +290,6 @@ TransactionDb.prototype.fromTxIdN = function(txid, n, confirmations, cb) {
|
||||||
valueSat: parseInt(a[1]),
|
valueSat: parseInt(a[1]),
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* If this TxID comes from an RPC request
|
|
||||||
* the .confirmations value from bitcoind is available
|
|
||||||
* so we could avoid checking if the input was double spent
|
|
||||||
*
|
|
||||||
* This speed up address calculations by ~30%
|
|
||||||
*
|
|
||||||
if (confirmations >= CONFIRMATION_NR_TO_NOT_CHECK) {
|
|
||||||
return cb(null, ret);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// spent?
|
// spent?
|
||||||
var k = SPENT_PREFIX + txid + '-' + n + '-';
|
var k = SPENT_PREFIX + txid + '-' + n + '-';
|
||||||
db.createReadStream({
|
db.createReadStream({
|
||||||
|
@ -671,4 +660,17 @@ TransactionDb.prototype.getPoolInfo = function(txid, cb) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
TransactionDb.prototype.checkVersion02 = function(cb) {
|
||||||
|
var k = 'txb-f0315ffc38709d70ad5647e22048358dd3745f3ce3874223c80a7c92fab0c8ba-00000000b873e79784647a6c82962c70d228557d24a747ea4d1b8bbe878e1206';
|
||||||
|
db.get(k, function(err, val) {
|
||||||
|
if (val) {
|
||||||
|
console.log('\n#############################\n\n ## Insight API DB is older that v0.2. Please resync using:\n $ util/sync.js -D\n More information at Insight API\'s Readme.md');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
return cb();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
module.exports = require('soop')(TransactionDb);
|
module.exports = require('soop')(TransactionDb);
|
||||||
|
|
|
@ -31,7 +31,10 @@ describe('Address balances', function() {
|
||||||
a.update(function(err) {
|
a.update(function(err) {
|
||||||
if (err) done(err);
|
if (err) done(err);
|
||||||
v.addr.should.equal(a.addrStr);
|
v.addr.should.equal(a.addrStr);
|
||||||
|
|
||||||
|
if (v.unconfirmedTxApperances)
|
||||||
a.unconfirmedTxApperances.should.equal(v.unconfirmedTxApperances || 0, 'unconfirmedTxApperances');
|
a.unconfirmedTxApperances.should.equal(v.unconfirmedTxApperances || 0, 'unconfirmedTxApperances');
|
||||||
|
if (v.unconfirmedBalanceSat)
|
||||||
a.unconfirmedBalanceSat.should.equal(v.unconfirmedBalanceSat || 0, 'unconfirmedBalanceSat');
|
a.unconfirmedBalanceSat.should.equal(v.unconfirmedBalanceSat || 0, 'unconfirmedBalanceSat');
|
||||||
if (v.txApperances)
|
if (v.txApperances)
|
||||||
a.txApperances.should.equal(v.txApperances, 'txApperances');
|
a.txApperances.should.equal(v.txApperances, 'txApperances');
|
||||||
|
|
Loading…
Reference in New Issue