add MessageDb
This commit is contained in:
parent
1c6010ba99
commit
c39749c58e
@ -76,45 +76,6 @@ var bitcoindConf = {
|
|||||||
disableAgent: true
|
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\tINSIGHT_SAFE_CONFIRMATIONS\n\
|
|
||||||
\t\tIgnore Cache: %s\tINSIGHT_IGNORE_CACHE\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 Host: %s\tBITCOIND_P2P_HOST\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, ignoreCache ? 'yes' : 'no',
|
|
||||||
bitcoindConf.user,
|
|
||||||
bitcoindConf.pass ? 'Yes(hidden)' : 'No',
|
|
||||||
bitcoindConf.protocol,
|
|
||||||
bitcoindConf.host,
|
|
||||||
bitcoindConf.port,
|
|
||||||
bitcoindConf.p2pHost,
|
|
||||||
bitcoindConf.p2pPort,
|
|
||||||
dataDir + (network === 'testnet' ? '*' : ''), (network === 'testnet' ? '* (/testnet3 is added automatically)' : '')
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
if (!fs.existsSync(db)) {
|
if (!fs.existsSync(db)) {
|
||||||
|
|||||||
57
insight.js
57
insight.js
@ -15,6 +15,45 @@ var express = require('express'),
|
|||||||
//Initializing system variables
|
//Initializing system variables
|
||||||
var config = require('./config/config');
|
var config = require('./config/config');
|
||||||
|
|
||||||
|
// text title
|
||||||
|
/*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\tINSIGHT_SAFE_CONFIRMATIONS\n\
|
||||||
|
\t\tIgnore Cache: %s\tINSIGHT_IGNORE_CACHE\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, ignoreCache ? 'yes' : 'no',
|
||||||
|
bitcoindConf.user,
|
||||||
|
bitcoindConf.pass ? 'Yes(hidden)' : 'No',
|
||||||
|
bitcoindConf.protocol,
|
||||||
|
bitcoindConf.host,
|
||||||
|
bitcoindConf.port,
|
||||||
|
bitcoindConf.p2pPort,
|
||||||
|
dataDir + (network === 'testnet' ? '*' : ''), (network === 'testnet' ? '* (/testnet3 is added automatically)' : '')
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* express app
|
* express app
|
||||||
*/
|
*/
|
||||||
@ -32,8 +71,7 @@ var walk = function(path) {
|
|||||||
if (/(.*)\.(js$)/.test(file)) {
|
if (/(.*)\.(js$)/.test(file)) {
|
||||||
require(newPath);
|
require(newPath);
|
||||||
}
|
}
|
||||||
}
|
} else if (stat.isDirectory()) {
|
||||||
else if (stat.isDirectory()) {
|
|
||||||
walk(newPath);
|
walk(newPath);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -45,7 +83,9 @@ walk(models_path);
|
|||||||
* p2pSync process
|
* p2pSync process
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var peerSync = new PeerSync({shouldBroadcast: true});
|
var peerSync = new PeerSync({
|
||||||
|
shouldBroadcast: true
|
||||||
|
});
|
||||||
|
|
||||||
if (!config.disableP2pSync) {
|
if (!config.disableP2pSync) {
|
||||||
peerSync.run();
|
peerSync.run();
|
||||||
@ -60,16 +100,15 @@ var historicSync = new HistoricSync({
|
|||||||
peerSync.historicSync = historicSync;
|
peerSync.historicSync = historicSync;
|
||||||
|
|
||||||
if (!config.disableHistoricSync) {
|
if (!config.disableHistoricSync) {
|
||||||
historicSync.start({}, function(err){
|
historicSync.start({}, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
var txt = 'ABORTED with error: ' + err.message;
|
var txt = 'ABORTED with error: ' + err.message;
|
||||||
console.log('[historic_sync] ' + txt);
|
console.log('[historic_sync] ' + txt);
|
||||||
}
|
}
|
||||||
if (peerSync) peerSync.allowReorgs = true;
|
if (peerSync) peerSync.allowReorgs = true;
|
||||||
});
|
});
|
||||||
}
|
} else
|
||||||
else
|
if (peerSync) peerSync.allowReorgs = true;
|
||||||
if (peerSync) peerSync.allowReorgs = true;
|
|
||||||
|
|
||||||
|
|
||||||
//express settings
|
//express settings
|
||||||
@ -84,8 +123,8 @@ var ios = require('socket.io')(server);
|
|||||||
require('./app/controllers/socket.js').init(expressApp, ios);
|
require('./app/controllers/socket.js').init(expressApp, ios);
|
||||||
|
|
||||||
//Start the app by listening on <port>
|
//Start the app by listening on <port>
|
||||||
server.listen(config.port, function(){
|
server.listen(config.port, function() {
|
||||||
console.log('insight server listening on port %d in %s mode', server.address().port, process.env.NODE_ENV);
|
console.log('insight server listening on port %d in %s mode', server.address().port, process.env.NODE_ENV);
|
||||||
});
|
});
|
||||||
|
|
||||||
//expose app
|
//expose app
|
||||||
|
|||||||
57
lib/MessageDb.js
Normal file
57
lib/MessageDb.js
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
'use strict';
|
||||||
|
var imports = require('soop').imports();
|
||||||
|
var levelup = require('levelup');
|
||||||
|
var config = require('../config/config');
|
||||||
|
var Rpc = imports.rpc || require('./Rpc');
|
||||||
|
var async = require('async');
|
||||||
|
var logger = require('./logger').logger;
|
||||||
|
|
||||||
|
var MESSAGE_PREFIX = 'msg-'; // msg-<sin1>-<sin2> => <message>
|
||||||
|
|
||||||
|
var MAX_OPEN_FILES = 500;
|
||||||
|
var CONCURRENCY = 5;
|
||||||
|
|
||||||
|
var db = imports.db || levelup(config.leveldb + '/messages', {
|
||||||
|
maxOpenFiles: MAX_OPEN_FILES
|
||||||
|
});
|
||||||
|
|
||||||
|
var d = logger.log;
|
||||||
|
var info = logger.info;
|
||||||
|
|
||||||
|
|
||||||
|
var MessageDb = function() {
|
||||||
|
db.on('put', function(key, value) {
|
||||||
|
console.log(key + '=>' + value);
|
||||||
|
});
|
||||||
|
db.on('ready', function() {
|
||||||
|
console.log('Database ready!');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
MessageDb.prototype.close = function(cb) {
|
||||||
|
db.close(cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var messageKey = function(from, to, ts) {
|
||||||
|
if (!ts) ts = Math.round(new Date().getTime() / 1000);
|
||||||
|
return MESSAGE_PREFIX + from.toString() + '-' + to.toString() + '-' + ts;
|
||||||
|
};
|
||||||
|
|
||||||
|
MessageDb.prototype.addMessage = function(m, from, to, cb) {
|
||||||
|
var key = messageKey(from, to);
|
||||||
|
var value = m;
|
||||||
|
db.put(key, value, cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
MessageDb.prototype.getMessages = function(from, to, from_ts, to_ts, cb) {
|
||||||
|
// TODO
|
||||||
|
db.get(messageKey(from, to), function(err, val) {
|
||||||
|
if (err && err.notFound) return cb();
|
||||||
|
if (err) return cb(err);
|
||||||
|
|
||||||
|
return cb(null, val);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = require('soop')(MessageDb);
|
||||||
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var imports = require('soop').imports();
|
var imports = require('soop').imports();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -20,40 +20,42 @@ var genesisTXID = '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda
|
|||||||
var CONCURRENCY = 10;
|
var CONCURRENCY = 10;
|
||||||
var DEFAULT_SAFE_CONFIRMATIONS = 6;
|
var DEFAULT_SAFE_CONFIRMATIONS = 6;
|
||||||
|
|
||||||
var MAX_OPEN_FILES = 500;
|
var MAX_OPEN_FILES = 500;
|
||||||
var END_OF_WORLD_TS = 1e13;
|
var END_OF_WORLD_TS = 1e13;
|
||||||
// var CONFIRMATION_NR_TO_NOT_CHECK = 10; //Spend
|
// var CONFIRMATION_NR_TO_NOT_CHECK = 10; //Spend
|
||||||
/**
|
/**
|
||||||
* Module dependencies.
|
* Module dependencies.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var bitcore = require('bitcore'),
|
var bitcore = require('bitcore'),
|
||||||
Rpc = imports.rpc || require('./Rpc'),
|
Rpc = imports.rpc || require('./Rpc'),
|
||||||
util = bitcore.util,
|
util = bitcore.util,
|
||||||
networks = bitcore.networks,
|
networks = bitcore.networks,
|
||||||
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'),
|
||||||
Script = bitcore.Script,
|
Script = bitcore.Script,
|
||||||
bitcoreUtil = bitcore.util,
|
bitcoreUtil = bitcore.util,
|
||||||
buffertools = require('buffertools');
|
buffertools = require('buffertools');
|
||||||
|
|
||||||
var logger = require('./logger').logger;
|
var logger = require('./logger').logger;
|
||||||
var inf = logger.info;
|
var inf = logger.info;
|
||||||
|
|
||||||
var db = imports.db || levelup(config.leveldb + '/txs',{maxOpenFiles: MAX_OPEN_FILES} );
|
var db = imports.db || levelup(config.leveldb + '/txs', {
|
||||||
var PoolMatch = imports.poolMatch || require('soop').load('./PoolMatch',config);
|
maxOpenFiles: MAX_OPEN_FILES
|
||||||
|
});
|
||||||
|
var PoolMatch = imports.poolMatch || require('soop').load('./PoolMatch', config);
|
||||||
// This is 0.1.2 = > c++ version of base58-native
|
// This is 0.1.2 = > c++ version of base58-native
|
||||||
var base58 = require('base58-native').base58Check;
|
var base58 = require('base58-native').base58Check;
|
||||||
var encodedData = require('soop').load('bitcore/util/EncodedData',{
|
var encodedData = require('soop').load('bitcore/util/EncodedData', {
|
||||||
base58: base58
|
base58: base58
|
||||||
});
|
});
|
||||||
var versionedData= require('soop').load('bitcore/util/VersionedData',{
|
var versionedData = require('soop').load('bitcore/util/VersionedData', {
|
||||||
parent: encodedData
|
parent: encodedData
|
||||||
});
|
});
|
||||||
|
|
||||||
var Address = require('soop').load('bitcore/lib/Address',{
|
var Address = require('soop').load('bitcore/lib/Address', {
|
||||||
parent: versionedData
|
parent: versionedData
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -76,7 +78,9 @@ 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() {
|
||||||
db = levelup(path, {maxOpenFiles: 500});
|
db = levelup(path, {
|
||||||
|
maxOpenFiles: 500
|
||||||
|
});
|
||||||
return cb();
|
return cb();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -278,13 +282,14 @@ TransactionDb.prototype.fromTxIdN = function(txid, n, cb) {
|
|||||||
var k = OUTS_PREFIX + txid + '-' + n;
|
var k = OUTS_PREFIX + txid + '-' + n;
|
||||||
|
|
||||||
db.get(k, function(err, val) {
|
db.get(k, function(err, val) {
|
||||||
var ret;
|
var ret;
|
||||||
|
|
||||||
if (!val || (err && err.notFound)) {
|
if (!val || (err && err.notFound)) {
|
||||||
err=null;
|
err = null;
|
||||||
ret= { unconfirmedInput: 1 };
|
ret = {
|
||||||
}
|
unconfirmedInput: 1
|
||||||
else {
|
};
|
||||||
|
} else {
|
||||||
var a = val.split(':');
|
var a = val.split(':');
|
||||||
ret = {
|
ret = {
|
||||||
addr: a[0],
|
addr: a[0],
|
||||||
@ -312,7 +317,7 @@ TransactionDb.prototype.fromTxIdN = function(txid, n, cb) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
TransactionDb.prototype.deleteCacheForAddress = function(addr,cb) {
|
TransactionDb.prototype.deleteCacheForAddress = function(addr, cb) {
|
||||||
var k = ADDR_PREFIX + addr + '-';
|
var k = ADDR_PREFIX + addr + '-';
|
||||||
var dbScript = [];
|
var dbScript = [];
|
||||||
db.createReadStream({
|
db.createReadStream({
|
||||||
@ -330,17 +335,17 @@ TransactionDb.prototype.deleteCacheForAddress = function(addr,cb) {
|
|||||||
.on('error', function(err) {
|
.on('error', function(err) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
})
|
})
|
||||||
.on('end', function (){
|
.on('end', function() {
|
||||||
db.batch(dbScript,cb);
|
db.batch(dbScript, cb);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionDb.prototype.cacheConfirmations = function(txouts,cb) {
|
TransactionDb.prototype.cacheConfirmations = function(txouts, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var dbScript=[];
|
var dbScript = [];
|
||||||
for(var ii in txouts){
|
for (var ii in txouts) {
|
||||||
var txout=txouts[ii];
|
var txout = txouts[ii];
|
||||||
|
|
||||||
//everything already cached?
|
//everything already cached?
|
||||||
if (txout.spentIsConfirmedCached) {
|
if (txout.spentIsConfirmedCached) {
|
||||||
@ -354,15 +359,14 @@ TransactionDb.prototype.cacheConfirmations = function(txouts,cb) {
|
|||||||
// if spent, we overwrite scriptPubKey cache (not needed anymore)
|
// if spent, we overwrite scriptPubKey cache (not needed anymore)
|
||||||
// First 1 = txout.isConfirmedCached (must be equal to 1 at this point)
|
// First 1 = txout.isConfirmedCached (must be equal to 1 at this point)
|
||||||
infoToCache = [1, 1, txout.spentTxId, txout.spentIndex, txout.spentTs];
|
infoToCache = [1, 1, txout.spentTxId, txout.spentIndex, txout.spentTs];
|
||||||
}
|
} else {
|
||||||
else {
|
if (!txout.isConfirmedCached) {
|
||||||
if (!txout.isConfirmedCached) {
|
|
||||||
infoToCache.push(1);
|
infoToCache.push(1);
|
||||||
txout.confirmedWillBeCached=1;
|
txout.confirmedWillBeCached = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//console.log('[TransactionDb.js.352:infoToCache:]',infoToCache); //TODO
|
//console.log('[TransactionDb.js.352:infoToCache:]',infoToCache); //TODO
|
||||||
if (infoToCache.length){
|
if (infoToCache.length) {
|
||||||
|
|
||||||
infoToCache.unshift(txout.value_sat);
|
infoToCache.unshift(txout.value_sat);
|
||||||
dbScript.push({
|
dbScript.push({
|
||||||
@ -374,25 +378,24 @@ TransactionDb.prototype.cacheConfirmations = function(txouts,cb) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//console.log('[TransactionDb.js.339:dbScript:]',dbScript); //TODO
|
//console.log('[TransactionDb.js.339:dbScript:]',dbScript); //TODO
|
||||||
db.batch(dbScript,cb);
|
db.batch(dbScript, cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
TransactionDb.prototype.cacheScriptPubKey = function(txouts,cb) {
|
TransactionDb.prototype.cacheScriptPubKey = function(txouts, cb) {
|
||||||
// console.log('[TransactionDb.js.381:cacheScriptPubKey:]'); //TODO
|
// console.log('[TransactionDb.js.381:cacheScriptPubKey:]'); //TODO
|
||||||
var self = this;
|
var self = this;
|
||||||
var dbScript=[];
|
var dbScript = [];
|
||||||
for(var ii in txouts){
|
for (var ii in txouts) {
|
||||||
var txout=txouts[ii];
|
var txout = txouts[ii];
|
||||||
//everything already cached?
|
//everything already cached?
|
||||||
if (txout.scriptPubKeyCached || txout.spentTxId) {
|
if (txout.scriptPubKeyCached || txout.spentTxId) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (txout.scriptPubKey) {
|
if (txout.scriptPubKey) {
|
||||||
var infoToCache = [txout.value_sat,
|
var infoToCache = [txout.value_sat, (txout.isConfirmedCached || txout.confirmedWillBeCached) ? 1 : 0, txout.scriptPubKey];
|
||||||
(txout.isConfirmedCached || txout.confirmedWillBeCached)?1:0, txout.scriptPubKey];
|
|
||||||
dbScript.push({
|
dbScript.push({
|
||||||
type: 'put',
|
type: 'put',
|
||||||
key: txout.key,
|
key: txout.key,
|
||||||
@ -400,7 +403,7 @@ TransactionDb.prototype.cacheScriptPubKey = function(txouts,cb) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
db.batch(dbScript,cb);
|
db.batch(dbScript, cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -424,12 +427,12 @@ TransactionDb.prototype._parseAddrData = function(k, data, ignoreCache) {
|
|||||||
// v[1]== isConfirmedCached
|
// v[1]== isConfirmedCached
|
||||||
// v[2]=== '1' -> is SpendCached -> [4]=spendTxId [5]=spentIndex [6]=spendTs
|
// v[2]=== '1' -> is SpendCached -> [4]=spendTxId [5]=spentIndex [6]=spendTs
|
||||||
// v[2]!== '1' -> is ScriptPubkey -> [[2] = scriptPubkey
|
// v[2]!== '1' -> is ScriptPubkey -> [[2] = scriptPubkey
|
||||||
if (v[1]==='1'){
|
if (v[1] === '1') {
|
||||||
item.isConfirmed = 1;
|
item.isConfirmed = 1;
|
||||||
item.isConfirmedCached = 1;
|
item.isConfirmedCached = 1;
|
||||||
// console.log('[TransactionDb.js.356] CACHE HIT CONF:', item.key);
|
// console.log('[TransactionDb.js.356] CACHE HIT CONF:', item.key);
|
||||||
// Sent, confirmed
|
// Sent, confirmed
|
||||||
if (v[2] === '1'){
|
if (v[2] === '1') {
|
||||||
// console.log('[TransactionDb.js.356] CACHE HIT SPENT:', item.key);
|
// console.log('[TransactionDb.js.356] CACHE HIT SPENT:', item.key);
|
||||||
item.spentIsConfirmed = 1;
|
item.spentIsConfirmed = 1;
|
||||||
item.spentIsConfirmedCached = 1;
|
item.spentIsConfirmedCached = 1;
|
||||||
@ -441,7 +444,7 @@ TransactionDb.prototype._parseAddrData = function(k, data, ignoreCache) {
|
|||||||
else if (v[2]) {
|
else if (v[2]) {
|
||||||
item.scriptPubKey = v[2];
|
item.scriptPubKey = v[2];
|
||||||
item.scriptPubKeyCached = 1;
|
item.scriptPubKeyCached = 1;
|
||||||
// console.log('[TransactionDb.js.356] CACHE HIT SCRIPTPUBKEY:', item.key, v, item.scriptPubKey);
|
// console.log('[TransactionDb.js.356] CACHE HIT SCRIPTPUBKEY:', item.key, v, item.scriptPubKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
@ -452,24 +455,26 @@ TransactionDb.prototype.fromAddr = function(addr, opts, cb) {
|
|||||||
var self = this;
|
var self = this;
|
||||||
var k = ADDR_PREFIX + addr + '-';
|
var k = ADDR_PREFIX + addr + '-';
|
||||||
var ret = [];
|
var ret = [];
|
||||||
var unique={};
|
var unique = {};
|
||||||
|
|
||||||
db.createReadStream({
|
db.createReadStream({
|
||||||
start: k,
|
start: k,
|
||||||
end: k + '~',
|
end: k + '~',
|
||||||
limit: opts.txLimit>0 ? opts.txLimit: -1, // -1 means not limit
|
limit: opts.txLimit > 0 ? opts.txLimit : -1, // -1 means not limit
|
||||||
})
|
})
|
||||||
.on('data', function(data) {
|
.on('data', function(data) {
|
||||||
var k = data.key.split('-');
|
var k = data.key.split('-');
|
||||||
var index = k[3]+k[4];
|
var index = k[3] + k[4];
|
||||||
if (!unique[index]) {
|
if (!unique[index]) {
|
||||||
unique[index]=1;
|
unique[index] = 1;
|
||||||
ret.push(self._parseAddrData(k, data, opts.ignoreCache));
|
ret.push(self._parseAddrData(k, data, opts.ignoreCache));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.on('error', cb)
|
.on('error', cb)
|
||||||
.on('end', function() {
|
.on('end', function() {
|
||||||
async.eachLimit(ret.filter(function(x){return !x.spentIsConfirmed;}), CONCURRENCY, function(o, e_c) {
|
async.eachLimit(ret.filter(function(x) {
|
||||||
|
return !x.spentIsConfirmed;
|
||||||
|
}), CONCURRENCY, function(o, e_c) {
|
||||||
var k = SPENT_PREFIX + o.txid + '-' + o.index + '-';
|
var k = SPENT_PREFIX + o.txid + '-' + o.index + '-';
|
||||||
db.createReadStream({
|
db.createReadStream({
|
||||||
start: k,
|
start: k,
|
||||||
@ -488,18 +493,20 @@ TransactionDb.prototype.fromAddr = function(addr, opts, cb) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionDb.prototype._fromBuffer = function (buf) {
|
TransactionDb.prototype._fromBuffer = function(buf) {
|
||||||
var buf2 = buffertools.reverse(buf);
|
var buf2 = buffertools.reverse(buf);
|
||||||
return parseInt(buf2.toString('hex'), 16);
|
return parseInt(buf2.toString('hex'), 16);
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionDb.prototype.getStandardizedTx = function (tx, time, isCoinBase) {
|
TransactionDb.prototype.getStandardizedTx = function(tx, time, isCoinBase) {
|
||||||
var self = this;
|
var self = this;
|
||||||
tx.txid = bitcoreUtil.formatHashFull(tx.getHash());
|
tx.txid = bitcoreUtil.formatHashFull(tx.getHash());
|
||||||
var ti=0;
|
var ti = 0;
|
||||||
|
|
||||||
tx.vin = tx.ins.map(function(txin) {
|
tx.vin = tx.ins.map(function(txin) {
|
||||||
var ret = {n: ti++};
|
var ret = {
|
||||||
|
n: ti++
|
||||||
|
};
|
||||||
if (isCoinBase) {
|
if (isCoinBase) {
|
||||||
ret.isCoinBase = true;
|
ret.isCoinBase = true;
|
||||||
} else {
|
} else {
|
||||||
@ -517,7 +524,9 @@ TransactionDb.prototype.getStandardizedTx = function (tx, time, isCoinBase) {
|
|||||||
var addrs = new Address.fromScriptPubKey(s, config.network);
|
var addrs = new Address.fromScriptPubKey(s, config.network);
|
||||||
// support only for p2pubkey p2pubkeyhash and p2sh
|
// support only for p2pubkey p2pubkeyhash and p2sh
|
||||||
if (addrs && addrs.length === 1) {
|
if (addrs && addrs.length === 1) {
|
||||||
val = {addresses: [addrs[0].toString() ] };
|
val = {
|
||||||
|
addresses: [addrs[0].toString()]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@ -532,22 +541,23 @@ TransactionDb.prototype.getStandardizedTx = function (tx, time, isCoinBase) {
|
|||||||
|
|
||||||
|
|
||||||
TransactionDb.prototype.fillScriptPubKey = function(txouts, cb) {
|
TransactionDb.prototype.fillScriptPubKey = function(txouts, cb) {
|
||||||
var self=this;
|
var self = this;
|
||||||
// Complete utxo info
|
// Complete utxo info
|
||||||
async.eachLimit(txouts, CONCURRENCY, function (txout, a_c) {
|
async.eachLimit(txouts, CONCURRENCY, function(txout, a_c) {
|
||||||
self.fromIdInfoSimple(txout.txid, function(err, info) {
|
self.fromIdInfoSimple(txout.txid, function(err, info) {
|
||||||
if (!info || !info.vout) return a_c(err);
|
if (!info || !info.vout) return a_c(err);
|
||||||
|
|
||||||
txout.scriptPubKey = info.vout[txout.index].scriptPubKey.hex;
|
txout.scriptPubKey = info.vout[txout.index].scriptPubKey.hex;
|
||||||
return a_c();
|
return a_c();
|
||||||
});
|
});
|
||||||
}, function(){
|
}, function() {
|
||||||
self.cacheScriptPubKey(txouts, cb);
|
self.cacheScriptPubKey(txouts, cb);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionDb.prototype.removeFromTxId = function(txid, cb) {
|
TransactionDb.prototype.removeFromTxId = function(txid, cb) {
|
||||||
async.series([
|
async.series([
|
||||||
|
|
||||||
function(c) {
|
function(c) {
|
||||||
db.createReadStream({
|
db.createReadStream({
|
||||||
start: OUTS_PREFIX + txid + '-',
|
start: OUTS_PREFIX + txid + '-',
|
||||||
@ -579,15 +589,15 @@ TransactionDb.prototype.removeFromTxId = function(txid, cb) {
|
|||||||
|
|
||||||
// relatedAddrs is an optional hash, to collect related addresses in the transaction
|
// relatedAddrs is an optional hash, to collect related addresses in the transaction
|
||||||
TransactionDb.prototype._addScript = function(tx, relatedAddrs) {
|
TransactionDb.prototype._addScript = function(tx, relatedAddrs) {
|
||||||
var dbScript = [];
|
var dbScript = [];
|
||||||
var ts = tx.time;
|
var ts = tx.time;
|
||||||
var txid = tx.txid || tx.hash;
|
var txid = tx.txid || tx.hash;
|
||||||
// var u=require('util');
|
// var u=require('util');
|
||||||
// console.log('[TransactionDb.js.518]', u.inspect(tx,{depth:10})); //TODO
|
// console.log('[TransactionDb.js.518]', u.inspect(tx,{depth:10})); //TODO
|
||||||
// Input Outpoints (mark them as spent)
|
// Input Outpoints (mark them as spent)
|
||||||
for(var ii in tx.vin) {
|
for (var ii in tx.vin) {
|
||||||
var i = tx.vin[ii];
|
var i = tx.vin[ii];
|
||||||
if (i.txid){
|
if (i.txid) {
|
||||||
var k = SPENT_PREFIX + i.txid + '-' + i.vout + '-' + txid + '-' + i.n;
|
var k = SPENT_PREFIX + i.txid + '-' + i.vout + '-' + txid + '-' + i.n;
|
||||||
dbScript.push({
|
dbScript.push({
|
||||||
type: 'put',
|
type: 'put',
|
||||||
@ -597,27 +607,27 @@ TransactionDb.prototype._addScript = function(tx, relatedAddrs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(var ii in tx.vout) {
|
for (var ii in tx.vout) {
|
||||||
var o = tx.vout[ii];
|
var o = tx.vout[ii];
|
||||||
if ( o.scriptPubKey && o.scriptPubKey.addresses &&
|
if (o.scriptPubKey && o.scriptPubKey.addresses &&
|
||||||
o.scriptPubKey.addresses[0] && !o.scriptPubKey.addresses[1] // TODO : not supported=> standard multisig
|
o.scriptPubKey.addresses[0] && !o.scriptPubKey.addresses[1] // TODO : not supported=> standard multisig
|
||||||
) {
|
) {
|
||||||
var addr = o.scriptPubKey.addresses[0];
|
var addr = o.scriptPubKey.addresses[0];
|
||||||
var sat = o.valueSat || ((o.value||0) * util.COIN).toFixed(0);
|
var sat = o.valueSat || ((o.value || 0) * util.COIN).toFixed(0);
|
||||||
|
|
||||||
if (relatedAddrs) relatedAddrs[addr]=1;
|
if (relatedAddrs) relatedAddrs[addr] = 1;
|
||||||
var k = OUTS_PREFIX + txid + '-' + o.n;
|
var k = OUTS_PREFIX + txid + '-' + o.n;
|
||||||
var tsr = END_OF_WORLD_TS - ts;
|
var tsr = END_OF_WORLD_TS - ts;
|
||||||
dbScript.push({
|
dbScript.push({
|
||||||
type: 'put',
|
type: 'put',
|
||||||
key: k,
|
key: k,
|
||||||
value: addr + ':' + sat,
|
value: addr + ':' + sat,
|
||||||
},{
|
}, {
|
||||||
type: 'put',
|
type: 'put',
|
||||||
key: ADDR_PREFIX + addr + '-' + tsr + '-'+ txid + '-' + o.n,
|
key: ADDR_PREFIX + addr + '-' + tsr + '-' + txid + '-' + o.n,
|
||||||
value: sat,
|
value: sat,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dbScript;
|
return dbScript;
|
||||||
};
|
};
|
||||||
@ -626,12 +636,14 @@ TransactionDb.prototype._addScript = function(tx, relatedAddrs) {
|
|||||||
TransactionDb.prototype.add = function(tx, cb) {
|
TransactionDb.prototype.add = function(tx, cb) {
|
||||||
var relatedAddrs = {};
|
var relatedAddrs = {};
|
||||||
var dbScript = this._addScript(tx, relatedAddrs);
|
var dbScript = this._addScript(tx, relatedAddrs);
|
||||||
db.batch(dbScript, function(err) { return cb(err,relatedAddrs);});
|
db.batch(dbScript, function(err) {
|
||||||
|
return cb(err, relatedAddrs);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionDb.prototype._addManyFromObjs = function(txs, next) {
|
TransactionDb.prototype._addManyFromObjs = function(txs, next) {
|
||||||
var dbScript = [];
|
var dbScript = [];
|
||||||
for(var ii in txs){
|
for (var ii in txs) {
|
||||||
var s = this._addScript(txs[ii]);
|
var s = this._addScript(txs[ii]);
|
||||||
dbScript = dbScript.concat(s);
|
dbScript = dbScript.concat(s);
|
||||||
}
|
}
|
||||||
@ -639,17 +651,17 @@ TransactionDb.prototype._addManyFromObjs = function(txs, next) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TransactionDb.prototype._addManyFromHashes = function(txs, next) {
|
TransactionDb.prototype._addManyFromHashes = function(txs, next) {
|
||||||
var self=this;
|
var self = this;
|
||||||
var dbScript = [];
|
var dbScript = [];
|
||||||
async.eachLimit(txs, CONCURRENCY, function(tx, each_cb) {
|
async.eachLimit(txs, CONCURRENCY, function(tx, each_cb) {
|
||||||
if (tx === genesisTXID)
|
if (tx === genesisTXID)
|
||||||
return each_cb();
|
return each_cb();
|
||||||
|
|
||||||
Rpc.getTxInfo(tx, function(err, inInfo) {
|
Rpc.getTxInfo(tx, function(err, inInfo) {
|
||||||
if (!inInfo) return each_cb(err);
|
if (!inInfo) return each_cb(err);
|
||||||
dbScript = dbScript.concat(self._addScript(inInfo));
|
dbScript = dbScript.concat(self._addScript(inInfo));
|
||||||
return each_cb();
|
return each_cb();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(err) {
|
function(err) {
|
||||||
if (err) return next(err);
|
if (err) return next(err);
|
||||||
@ -661,10 +673,10 @@ TransactionDb.prototype._addManyFromHashes = function(txs, next) {
|
|||||||
TransactionDb.prototype.addMany = function(txs, next) {
|
TransactionDb.prototype.addMany = function(txs, next) {
|
||||||
if (!txs) return next();
|
if (!txs) return next();
|
||||||
|
|
||||||
var fn = (typeof txs[0] ==='string') ?
|
var fn = (typeof txs[0] === 'string') ?
|
||||||
this._addManyFromHashes : this._addManyFromObjs;
|
this._addManyFromHashes : this._addManyFromObjs;
|
||||||
|
|
||||||
return fn.apply(this,[txs, next]);
|
return fn.apply(this, [txs, next]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -677,7 +689,7 @@ TransactionDb.prototype.getPoolInfo = function(txid, cb) {
|
|||||||
|
|
||||||
if (txInfo && txInfo.isCoinBase)
|
if (txInfo && txInfo.isCoinBase)
|
||||||
ret = self.poolMatch.match(new Buffer(txInfo.vin[0].coinbase, 'hex'));
|
ret = self.poolMatch.match(new Buffer(txInfo.vin[0].coinbase, 'hex'));
|
||||||
|
|
||||||
return cb(ret);
|
return cb(ret);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -685,16 +697,16 @@ TransactionDb.prototype.getPoolInfo = function(txid, cb) {
|
|||||||
|
|
||||||
TransactionDb.prototype.checkVersion02 = function(cb) {
|
TransactionDb.prototype.checkVersion02 = function(cb) {
|
||||||
var k = 'txa-';
|
var k = 'txa-';
|
||||||
var isV2=1;
|
var isV2 = 1;
|
||||||
db.createReadStream({
|
db.createReadStream({
|
||||||
start: k,
|
start: k,
|
||||||
end: k + '~',
|
end: k + '~',
|
||||||
limit: 1,
|
limit: 1,
|
||||||
})
|
})
|
||||||
.on('data', function(data) {
|
.on('data', function(data) {
|
||||||
isV2=0;
|
isV2 = 0;
|
||||||
})
|
})
|
||||||
.on('end', function (){
|
.on('end', function() {
|
||||||
return cb(isV2);
|
return cb(isV2);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -702,9 +714,9 @@ TransactionDb.prototype.checkVersion02 = function(cb) {
|
|||||||
TransactionDb.prototype.migrateV02 = function(cb) {
|
TransactionDb.prototype.migrateV02 = function(cb) {
|
||||||
var k = 'txa-';
|
var k = 'txa-';
|
||||||
var dbScript = [];
|
var dbScript = [];
|
||||||
var c=0;
|
var c = 0;
|
||||||
var c2=0;
|
var c2 = 0;
|
||||||
var N=50000;
|
var N = 50000;
|
||||||
db.createReadStream({
|
db.createReadStream({
|
||||||
start: k,
|
start: k,
|
||||||
end: k + '~'
|
end: k + '~'
|
||||||
@ -714,22 +726,21 @@ TransactionDb.prototype.migrateV02 = function(cb) {
|
|||||||
var v = data.value.split(':');
|
var v = data.value.split(':');
|
||||||
dbScript.push({
|
dbScript.push({
|
||||||
type: 'put',
|
type: 'put',
|
||||||
key: ADDR_PREFIX + k[1] + '-' + (END_OF_WORLD_TS - parseInt(v[1]))
|
key: ADDR_PREFIX + k[1] + '-' + (END_OF_WORLD_TS - parseInt(v[1])) + '-' + k[2] + '-' + k[3],
|
||||||
+ '-' + k[2] + '-' + k[3],
|
|
||||||
value: v[0],
|
value: v[0],
|
||||||
});
|
});
|
||||||
if (c++>N) {
|
if (c++ > N) {
|
||||||
console.log('\t%dM txs outs processed', ((c2+=N)/1e6).toFixed(3)); //TODO
|
console.log('\t%dM txs outs processed', ((c2 += N) / 1e6).toFixed(3)); //TODO
|
||||||
db.batch(dbScript,function () {
|
db.batch(dbScript, function() {
|
||||||
c=0;
|
c = 0;
|
||||||
dbScript=[];
|
dbScript = [];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.on('error', function(err) {
|
.on('error', function(err) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
})
|
})
|
||||||
.on('end', function (){
|
.on('end', function() {
|
||||||
return cb();
|
return cb();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@ -80,7 +80,7 @@
|
|||||||
"grunt-nodemon": "~0.2.0",
|
"grunt-nodemon": "~0.2.0",
|
||||||
"grunt-mocha-test": "~0.8.1",
|
"grunt-mocha-test": "~0.8.1",
|
||||||
"should": "2.1.1",
|
"should": "2.1.1",
|
||||||
"chai": "=1.9.1",
|
"chai": "*",
|
||||||
"grunt-markdown": "~0.5.0"
|
"grunt-markdown": "~0.5.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,8 +28,7 @@ describe('PeerSync', function() {
|
|||||||
it('should return with no errors', function() {
|
it('should return with no errors', function() {
|
||||||
expect(function() {
|
expect(function() {
|
||||||
ps.handleInv(inv_info);
|
ps.handleInv(inv_info);
|
||||||
}).not.to.
|
}).not.to.throw(Error);
|
||||||
throw (Error);
|
|
||||||
});
|
});
|
||||||
it('should call sendGetData', function() {
|
it('should call sendGetData', function() {
|
||||||
ps.handleInv(inv_info);
|
ps.handleInv(inv_info);
|
||||||
|
|||||||
19
test/test.MessageDb.js
Normal file
19
test/test.MessageDb.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var chai = require('chai');
|
||||||
|
var should = chai.should;
|
||||||
|
|
||||||
|
var MessageDb = require('../lib/MessageDb');
|
||||||
|
|
||||||
|
describe('MessageDb', function() {
|
||||||
|
it('should be able to create instance', function() {
|
||||||
|
var mdb = new MessageDb();
|
||||||
|
});
|
||||||
|
it('should receive events', function(done) {
|
||||||
|
var mdb = new MessageDb();
|
||||||
|
var message = {};
|
||||||
|
mdb.addMessage(message, 'from', 'to', function(err) {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user