From a35fcc776dff1a8bd601e6ec53653aefe6c8fe70 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Wed, 12 Feb 2014 19:27:29 -0300 Subject: [PATCH] addr tx orderer by TS. keep unconfirmed balance. fix times in txs --- app/controllers/socket.js | 5 ++- app/models/Address.js | 51 +++++++++++++++++++++++++++---- lib/HistoricSync.js | 9 +++--- lib/TransactionDb.js | 32 +++++++++++++------ public/src/js/services/socket.js | 5 ++- public/views/address.html | 5 +++ public/views/includes/header.html | 7 +++-- public/views/transaction.html | 9 +++++- public/views/transaction/tx.html | 8 ++++- test/integration/addr.json | 2 +- 10 files changed, 105 insertions(+), 28 deletions(-) diff --git a/app/controllers/socket.js b/app/controllers/socket.js index 603c7ee..ebdce59 100644 --- a/app/controllers/socket.js +++ b/app/controllers/socket.js @@ -43,5 +43,8 @@ module.exports.broadcastAddressTx = function(address, tx) { }; module.exports.broadcastSyncInfo = function(historicSync) { - if (ios) ios.sockets.in('sync').emit('status', historicSync); + + if (ios) { + ios.sockets.in('sync').emit('status', historicSync); + } }; diff --git a/app/models/Address.js b/app/models/Address.js index cdb820b..28ec018 100644 --- a/app/models/Address.js +++ b/app/models/Address.js @@ -13,6 +13,9 @@ function spec() { this.balanceSat = 0; this.totalReceivedSat = 0; this.totalSentSat = 0; + + this.unconfirmedBalanceSat = 0; + this.txApperances = 0; // TODO store only txids? +index? +all? @@ -51,12 +54,25 @@ function spec() { }, enumerable: 1, }); + + + Object.defineProperty(this, 'unconfirmedBalance', { + get: function() { + return parseFloat(this.unconfirmedBalanceSat) / parseFloat(BitcoreUtil.COIN); + }, + set: function(i) { + this.unconfirmedBalanceSat = i * BitcoreUtil.COIN; + }, + enumerable: 1, + }); + } Address.prototype.update = function(next) { var self = this; if (!self.addrStr) return next(); + var txs = []; var db = new TransactionDb(); async.series([ function (cb) { @@ -64,27 +80,50 @@ function spec() { if (err) return cb(err); txOut.forEach(function(txItem){ + var v = txItem.value_sat; + + txs.push({txid: txItem.txid, ts: txItem.ts}); + self.txApperances += 1; + + if (txItem.spendTxId) { + txs.push({txid: txItem.spendTxId, ts: txItem.spendTs}); + self.txApperances += 1; + } + if (txItem.isConfirmed) { - var v = txItem.value_sat; self.totalReceivedSat += v; - self.transactions.push(txItem.txid); - if (! txItem.spendTxId || !txItem.spendIsConfirmed) { + if (! txItem.spendTxId ) { + //unspend + self.balanceSat += v; + } + else if(!txItem.spendIsConfirmed) { // unspent self.balanceSat += v; - self.txApperances +=1; + self.unconfirmedBalanceSat -= v; } else { // spent self.totalSentSat += v; - self.transactions.push(txItem.spendTxId); - self.txApperances +=2; } } + else { + self.unconfirmedBalanceSat += v; + } }); return cb(); }); }, ], function (err) { + + // sort input and outputs togheter + txs.sort( + function compare(a,b) { + if (a.ts < b.ts) return 1; + if (a.ts > b.ts) return -1; + return 0; + }); + + self.transactions = txs.map(function(i) { return i.txid; } ); return next(err); }); }; diff --git a/lib/HistoricSync.js b/lib/HistoricSync.js index 87c671f..826fc05 100644 --- a/lib/HistoricSync.js +++ b/lib/HistoricSync.js @@ -104,13 +104,14 @@ function spec() { HistoricSync.prototype.showProgress = function() { var self = this; - if ( ( self.syncedBlocks + self.skippedBlocks) % self.step !== 1) return; + if ( self.status ==='syncing' && + ( self.syncedBlocks + self.skippedBlocks) % self.step !== 1) return; if (self.error) { p('ERROR: ' + self.error); } else { - self.syncPercentage = parseFloat(100 * (self.syncedBlocks + self.skippedBlocks) / self.blockChainHeight).toFixed(3); + self.syncPercentage = parseFloat(100 * self.syncedBlocks / self.blockChainHeight).toFixed(3); if (self.syncPercentage > 100) self.syncPercentage = 100; p(util.format('status: [%d%%] skipped: %d ', self.syncPercentage, self.skippedBlocks)); @@ -193,7 +194,6 @@ function spec() { (blockEnd && blockEnd === blockHash)) { self.status = 'finished'; p('DONE. Found block: ', blockHash); - self.showProgress(); return cb(err); } @@ -266,7 +266,6 @@ function spec() { var self = this; self.showProgress(); - self.getBlockFromFile(function(err, blockInfo) { if (err) { self.setError(util.format('ERROR: @%s: %s [count: syncedBlocks: %d]', @@ -406,12 +405,14 @@ function spec() { }); }); }, function(err) { + self.showProgress(); return next(err); }); } else { self.type = 'from RPC calls'; self.getPrevNextBlock(start, end, scanOpts, function(err) { + self.showProgress(); return next(err); }); } diff --git a/lib/TransactionDb.js b/lib/TransactionDb.js index a06ae45..50f55a4 100644 --- a/lib/TransactionDb.js +++ b/lib/TransactionDb.js @@ -69,7 +69,7 @@ function spec(b) { }); }; - TransactionDb.prototype._addSpendInfo = function(r, txid, index) { + TransactionDb.prototype._addSpendInfo = function(r, txid, index, ts) { if (r.spendTxId) { if (!r.multipleSpendAttempts) { r.multipleSpendAttempts = [{ @@ -85,6 +85,7 @@ function spec(b) { else { r.spendTxId = txid; r.spendIndex = parseInt(index); + r.spendTs = parseInt(ts); } }; @@ -123,7 +124,7 @@ function spec(b) { assert(typeof j !== 'undefined','Spent could not be stored: tx ' + txid + 'spend in TX:' + k[2] + ',' + k[3]+ ' j:' + j); - self._addSpendInfo(ret[j], k[4], k[5]); + self._addSpendInfo(ret[j], k[4], k[5], data.value); }) .on('error', function (err) { return cb(err); @@ -144,7 +145,7 @@ function spec(b) { db.createReadStream({start: k, end: k + '~'}) .on('data', function (data) { var k = data.key.split('-'); - self._addSpendInfo(info.vout[k[3]], k[4], k[5]); + self._addSpendInfo(info.vout[k[3]], k[4], k[5], data.value); }) .on('error', function (err) { return cb(err); @@ -162,6 +163,7 @@ function spec(b) { var valueIn = 0; var incompleteInputs = 0; + var ts; async.eachLimit(info.vin, CONCURRENCY, function(i, c_in) { self.fromTxIdN(i.txid, i.vout, function(err, ret) { @@ -203,6 +205,8 @@ function spec(b) { i.doubleSpendTxID = null; } + info.firstSeenTs = i.spendTs; + valueIn += i.valueSat; return c_in(); }); @@ -264,7 +268,7 @@ function spec(b) { db.createReadStream({start: k, end: k + '~'}) .on('data', function (data) { var k = data.key.split('-'); - self._addSpendInfo(ret, k[4], k[5]); + self._addSpendInfo(ret, k[4], k[5], data.value); }) .on('error', function (error) { return cb(error); @@ -336,7 +340,7 @@ function spec(b) { db.createReadStream({start: k, end: k + '~'}) .on('data', function (data) { var k = data.key.split('-'); - self._addSpendInfo(o, k[4], k[5]); + self._addSpendInfo(o, k[4], k[5], data.value); }) .on('error', function (err) { return e_c(err); @@ -461,12 +465,20 @@ function spec(b) { var addr = o.scriptPubKey.addresses[0]; var sat = Math.round(o.value * util.COIN); - db.batch() - .put( OUTS_PREFIX + tx.txid + '-' + o.n, addr + ':' + sat) - .put( ADDR_PREFIX + addr + '-' + ts + '-' + tx.txid + - '-' + o.n, sat) - .write(next_out); + // existed? + db.get(OUTS_PREFIX + tx.txid + '-' + o.n, function (err,val) { + if (!val) { + db.batch() + .put( OUTS_PREFIX + tx.txid + '-' + o.n, addr + ':' + sat) + .put( ADDR_PREFIX + addr + '-' + ts + '-' + tx.txid + + '-' + o.n, sat) + .write(next_out); + } + else { + return next_out(); + } + }); } else { //console.log ('WARN in TX: %s could not parse OUTPUT %d', tx.txid, o.n); diff --git a/public/src/js/services/socket.js b/public/src/js/services/socket.js index 9a2d459..a2bf1e4 100644 --- a/public/src/js/services/socket.js +++ b/public/src/js/services/socket.js @@ -48,7 +48,10 @@ ScopedSocket.prototype.emit = function(event, data, callback) { angular.module('insight.socket').factory('getSocket', function($rootScope) { - var socket = io.connect(); + var socket = io.connect(null, { + 'reconnect': true, + 'reconnection delay': 500, +}); return function(scope) { var scopedSocket = new ScopedSocket(socket, $rootScope); scope.$on('$routeChangeStart', function() { diff --git a/public/views/address.html b/public/views/address.html index 4c5e9df..0771f47 100644 --- a/public/views/address.html +++ b/public/views/address.html @@ -26,6 +26,11 @@ Final Balance {{$root.currency.getConvertion(address.balance)}} + + Unconfirmed Tx Balance + {{$root.currency.getConvertion(address.unconfirmedBalance)}} + + No. Transactions {{address.txApperances}} diff --git a/public/views/includes/header.html b/public/views/includes/header.html index 0a8252f..f92bdea 100644 --- a/public/views/includes/header.html +++ b/public/views/includes/header.html @@ -24,7 +24,7 @@