addr tx orderer by TS. keep unconfirmed balance. fix times in txs
This commit is contained in:
parent
d561c191e7
commit
a35fcc776d
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -26,6 +26,11 @@
|
|||
<td class="small">Final Balance</td>
|
||||
<td class="address ellipsis text-right">{{$root.currency.getConvertion(address.balance)}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="small">Unconfirmed Tx Balance</td>
|
||||
<td class="address ellipsis text-right">{{$root.currency.getConvertion(address.unconfirmedBalance)}}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="small">No. Transactions</td>
|
||||
<td class="address ellipsis text-right">{{address.txApperances}}</td>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<ul class="nav navbar-nav navbar-right">
|
||||
<li>
|
||||
<div class="status" data-ng-controller="StatusController">
|
||||
<a href="#" data-ng-init="getSync()">
|
||||
<div data-ng-init="getSync()" class="pull-left">
|
||||
<span class="t text-danger" data-ng-show="sync.error" tooltip="{{sync.error}}" tooltip-placement="bottom">
|
||||
<span class="glyphicon glyphicon-warning-sign"></span>
|
||||
ERROR
|
||||
|
@ -33,8 +33,9 @@
|
|||
<span class="glyphicon glyphicon-refresh icon-rotate"></span>
|
||||
{{sync.status}} {{sync.syncPercentage}}%
|
||||
</span>
|
||||
<span class="t text-default" tooltip="Historic sync finished" tooltip-placement="bottom" data-ng-show="sync.status==='finished'"> On sync</span>
|
||||
</a> ·
|
||||
<span class="t text-default" tooltip="Historic sync finished" tooltip-placement="bottom" data-ng-show="sync.status==='finished'"> On sync </span>
|
||||
</div>
|
||||
·
|
||||
<span data-ng-init="getStatus('Info')">
|
||||
<strong>Conn</strong> {{info.connections}}
|
||||
</span> ·
|
||||
|
|
|
@ -21,8 +21,15 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td><strong>Received Time </strong></td>
|
||||
<td class="text-muted text-right">{{tx.time * 1000|date:'medium'}}</td>
|
||||
<td data-ng-show="tx.firstSeenTs" class="text-muted text-right">{{tx.firstSeenTs * 1000|date:'medium'}}</td>
|
||||
<td data-ng-show="!tx.firstSeenTs" class="text-muted text-right">N/A</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Mined Time </strong></td>
|
||||
<td data-ng-show="tx.time" class="text-muted text-right">{{tx.time * 1000|date:'medium'}}</td>
|
||||
<td data-ng-show="!tx.time" class="text-muted text-right">N/A</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<div data-ng-include src="'/views/includes/currency.html'"></div>
|
||||
|
|
|
@ -6,7 +6,13 @@
|
|||
<a class="txid" href="/tx/{{tx.txid}}">{{tx.txid}}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6 text-right" data-ng-show="tx.time">
|
||||
|
||||
<div class="col-xs-12 col-md-6 text-right" data-ng-show="tx.firstSeenTs">
|
||||
first seen at
|
||||
<time>{{tx.firstSeenTs * 1000 | date:'medium'}}</time>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6 text-right" data-ng-show="tx.time && !tx.firstSeenTs">
|
||||
mined at
|
||||
<time>{{tx.time * 1000 | date:'medium'}}</time>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
},
|
||||
{
|
||||
"addr": "mzW2hdZN2um7WBvTDerdahKqRgj3md9C29",
|
||||
"txApperances": 2041,
|
||||
"txApperances": 6049,
|
||||
"balance": 1199.74393853,
|
||||
"totalReceived": 1199.74393853,
|
||||
"totalSent": 0
|
||||
|
|
Loading…
Reference in New Issue