fix working for spent, also in var names
This commit is contained in:
parent
a4626f97eb
commit
f69f210abf
|
@ -85,18 +85,18 @@ function spec() {
|
|||
|
||||
txs.push({txid: txItem.txid, ts: txItem.ts});
|
||||
|
||||
if (txItem.spendTxId) {
|
||||
txs.push({txid: txItem.spendTxId, ts: txItem.spendTs});
|
||||
if (txItem.spentTxId) {
|
||||
txs.push({txid: txItem.spentTxId, ts: txItem.spentTs});
|
||||
}
|
||||
|
||||
if (txItem.isConfirmed) {
|
||||
self.txApperances += 1;
|
||||
self.totalReceivedSat += v;
|
||||
if (! txItem.spendTxId ) {
|
||||
//unspend
|
||||
if (! txItem.spentTxId ) {
|
||||
//unspent
|
||||
self.balanceSat += v;
|
||||
}
|
||||
else if(!txItem.spendIsConfirmed) {
|
||||
else if(!txItem.spentIsConfirmed) {
|
||||
// unspent
|
||||
self.balanceSat += v;
|
||||
self.unconfirmedBalanceSat -= v;
|
||||
|
|
|
@ -14,9 +14,9 @@ function spec(b) {
|
|||
|
||||
// to show tx outs
|
||||
var OUTS_PREFIX = 'txo-'; //txo-<txid>-<n> => [addr, btc_sat]
|
||||
var SPEND_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, spends 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
|
||||
|
||||
// TODO: use bitcore networks module
|
||||
|
@ -24,7 +24,7 @@ function spec(b) {
|
|||
var CONCURRENCY = 10;
|
||||
|
||||
var MAX_OPEN_FILES = 500;
|
||||
var CONFIRMATION_NR_TO_NOT_CHECK = 10;
|
||||
// var CONFIRMATION_NR_TO_NOT_CHECK = 10; //Spend
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
@ -89,22 +89,22 @@ function spec(b) {
|
|||
});
|
||||
};
|
||||
|
||||
TransactionDb.prototype._addSpendInfo = function(r, txid, index, ts) {
|
||||
if (r.spendTxId) {
|
||||
if (!r.multipleSpendAttempts) {
|
||||
r.multipleSpendAttempts = [{
|
||||
txid: r.spendTxId,
|
||||
TransactionDb.prototype._addSpentInfo = function(r, txid, index, ts) {
|
||||
if (r.spentTxId) {
|
||||
if (!r.multipleSpentAttempts) {
|
||||
r.multipleSpentAttempts = [{
|
||||
txid: r.spentTxId,
|
||||
index: r.index,
|
||||
}];
|
||||
}
|
||||
r.multipleSpendAttempts.push({
|
||||
r.multipleSpentAttempts.push({
|
||||
txid: txid,
|
||||
index: parseInt(index),
|
||||
});
|
||||
} else {
|
||||
r.spendTxId = txid;
|
||||
r.spendIndex = parseInt(index);
|
||||
r.spendTs = parseInt(ts);
|
||||
r.spentTxId = txid;
|
||||
r.spentIndex = parseInt(index);
|
||||
r.spentTs = parseInt(ts);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -137,7 +137,7 @@ function spec(b) {
|
|||
})
|
||||
.on('end', function() {
|
||||
|
||||
var k = SPEND_PREFIX + txid;
|
||||
var k = SPENT_PREFIX + txid;
|
||||
db.createReadStream({
|
||||
start: k,
|
||||
end: k + '~'
|
||||
|
@ -147,9 +147,9 @@ function spec(b) {
|
|||
var j = idx[parseInt(k[2])];
|
||||
|
||||
assert(typeof j !== 'undefined', 'Spent could not be stored: tx ' + txid +
|
||||
'spend in TX:' + k[1] + ',' + k[2] + ' j:' + j);
|
||||
'spent in TX:' + k[1] + ',' + k[2] + ' j:' + j);
|
||||
|
||||
self._addSpendInfo(ret[j], k[3], k[4], data.value);
|
||||
self._addSpentInfo(ret[j], k[3], k[4], data.value);
|
||||
})
|
||||
.on('error', function(err) {
|
||||
return cb(err);
|
||||
|
@ -161,19 +161,19 @@ function spec(b) {
|
|||
};
|
||||
|
||||
|
||||
TransactionDb.prototype._fillSpend = function(info, cb) {
|
||||
TransactionDb.prototype._fillSpent = function(info, cb) {
|
||||
var self = this;
|
||||
|
||||
if (!info) return cb();
|
||||
|
||||
var k = SPEND_PREFIX + info.txid;
|
||||
var k = SPENT_PREFIX + info.txid;
|
||||
db.createReadStream({
|
||||
start: k,
|
||||
end: k + '~'
|
||||
})
|
||||
.on('data', function(data) {
|
||||
var k = data.key.split('-');
|
||||
self._addSpendInfo(info.vout[k[2]], k[3], k[4], data.value);
|
||||
self._addSpentInfo(info.vout[k[2]], k[3], k[4], data.value);
|
||||
})
|
||||
.on('error', function(err) {
|
||||
return cb(err);
|
||||
|
@ -202,7 +202,7 @@ function spec(b) {
|
|||
return c_in(); // error not scalated
|
||||
}
|
||||
|
||||
info.firstSeenTs = ret.spendTs;
|
||||
info.firstSeenTs = ret.spentTs;
|
||||
i.unconfirmedInput = i.unconfirmedInput;
|
||||
i.addr = ret.addr;
|
||||
i.valueSat = ret.valueSat;
|
||||
|
@ -210,32 +210,33 @@ function spec(b) {
|
|||
valueIn += i.valueSat;
|
||||
|
||||
/*
|
||||
* If confirmed by bitcoind, we could not check for double spends
|
||||
* but we prefer to keep the flag of double spend attempt
|
||||
* If confirmed by bitcoind, we could not check for double spents
|
||||
* but we prefer to keep the flag of double spent attempt
|
||||
*
|
||||
if (info.confirmations
|
||||
&& info.confirmations >= CONFIRMATION_NR_TO_NOT_CHECK)
|
||||
return c_in();
|
||||
isspent
|
||||
*/
|
||||
// Double spend?
|
||||
if (ret.multipleSpendAttempt || !ret.spendTxId ||
|
||||
(ret.spendTxId && ret.spendTxId !== info.txid)
|
||||
// Double spent?
|
||||
if (ret.multipleSpentAttempt || !ret.spentTxId ||
|
||||
(ret.spentTxId && ret.spentTxId !== info.txid)
|
||||
) {
|
||||
if (ret.multipleSpendAttempts) {
|
||||
ret.multipleSpendAttempts.each(function(mul) {
|
||||
if (mul.spendTxId !== info.txid) {
|
||||
i.doubleSpendTxID = ret.spendTxId;
|
||||
i.doubleSpendIndex = ret.spendIndex;
|
||||
if (ret.multipleSpentAttempts) {
|
||||
ret.multipleSpentAttempts.each(function(mul) {
|
||||
if (mul.spentTxId !== info.txid) {
|
||||
i.doubleSpentTxID = ret.spentTxId;
|
||||
i.doubleSpentIndex = ret.spentIndex;
|
||||
}
|
||||
});
|
||||
} else if (!ret.spendTxId) {
|
||||
i.dbError = 'Input spend not registered';
|
||||
} else if (!ret.spentTxId) {
|
||||
i.dbError = 'Input spent not registered';
|
||||
} else {
|
||||
i.doubleSpendTxID = ret.spendTxId;
|
||||
i.doubleSpendIndex = ret.spendIndex;
|
||||
i.doubleSpentTxID = ret.spentTxId;
|
||||
i.doubleSpentIndex = ret.spentIndex;
|
||||
}
|
||||
} else {
|
||||
i.doubleSpendTxID = null;
|
||||
i.doubleSpentTxID = null;
|
||||
}
|
||||
return c_in();
|
||||
});
|
||||
|
@ -258,7 +259,7 @@ function spec(b) {
|
|||
if (err) return next(err);
|
||||
|
||||
self._fillOutpoints(info, function() {
|
||||
self._fillSpend(info, function() {
|
||||
self._fillSpent(info, function() {
|
||||
return next(null, info);
|
||||
});
|
||||
});
|
||||
|
@ -272,6 +273,7 @@ function spec(b) {
|
|||
self._getInfo(txid, function(err, info) {
|
||||
if (err) return cb(err);
|
||||
if (!info) return cb();
|
||||
//console.log('[TransactionDb.js.278:info:]',info); //TODO
|
||||
return cb(err, {
|
||||
txid: txid,
|
||||
info: info
|
||||
|
@ -299,7 +301,7 @@ function spec(b) {
|
|||
/*
|
||||
* If this TxID comes from an RPC request
|
||||
* the .confirmations value from bitcoind is available
|
||||
* so we could avoid checking if the input were double spended
|
||||
* so we could avoid checking if the input were double spented
|
||||
*
|
||||
* This speed up address calculations by ~30%
|
||||
*
|
||||
|
@ -308,15 +310,15 @@ function spec(b) {
|
|||
}
|
||||
*/
|
||||
|
||||
// Spend?
|
||||
var k = SPEND_PREFIX + txid + '-' + n;
|
||||
// spent?
|
||||
var k = SPENT_PREFIX + txid + '-' + n;
|
||||
db.createReadStream({
|
||||
start: k,
|
||||
end: k + '~'
|
||||
})
|
||||
.on('data', function(data) {
|
||||
var k = data.key.split('-');
|
||||
self._addSpendInfo(ret, k[3], k[4], data.value);
|
||||
self._addSpentInfo(ret, k[3], k[4], data.value);
|
||||
})
|
||||
.on('error', function(error) {
|
||||
return cb(error);
|
||||
|
@ -334,26 +336,26 @@ function spec(b) {
|
|||
if (err) return cb(err);
|
||||
|
||||
o.isConfirmed = is;
|
||||
if (!o.spendTxId) return cb();
|
||||
if (!o.spentTxId) return cb();
|
||||
|
||||
if (o.multipleSpendAttempts) {
|
||||
if (o.multipleSpentAttempts) {
|
||||
|
||||
async.eachLimit(o.multipleSpendAttempts, CONCURRENCY,
|
||||
async.eachLimit(o.multipleSpentAttempts, CONCURRENCY,
|
||||
function(oi, e_c) {
|
||||
self.isConfirmed(oi.spendTxId, function(err, is) {
|
||||
self.isConfirmed(oi.spentTxId, function(err, is) {
|
||||
if (err) return;
|
||||
if (is) {
|
||||
o.spendTxId = oi.spendTxId;
|
||||
o.spentTxId = oi.spentTxId;
|
||||
o.index = oi.index;
|
||||
o.spendIsConfirmed = 1;
|
||||
o.spentIsConfirmed = 1;
|
||||
}
|
||||
return e_c();
|
||||
});
|
||||
}, cb);
|
||||
} else {
|
||||
self.isConfirmed(o.spendTxId, function(err, is) {
|
||||
self.isConfirmed(o.spentTxId, function(err, is) {
|
||||
if (err) return cb(err);
|
||||
o.spendIsConfirmed = is;
|
||||
o.spentIsConfirmed = is;
|
||||
return cb();
|
||||
});
|
||||
}
|
||||
|
@ -386,14 +388,14 @@ function spec(b) {
|
|||
.on('end', function() {
|
||||
|
||||
async.eachLimit(ret, CONCURRENCY, function(o, e_c) {
|
||||
var k = SPEND_PREFIX + o.txid + '-' + o.index;
|
||||
var k = SPENT_PREFIX + o.txid + '-' + o.index;
|
||||
db.createReadStream({
|
||||
start: k,
|
||||
end: k + '~'
|
||||
})
|
||||
.on('data', function(data) {
|
||||
var k = data.key.split('-');
|
||||
self._addSpendInfo(o, k[3], k[4], data.value);
|
||||
self._addSpentInfo(o, k[3], k[4], data.value);
|
||||
})
|
||||
.on('error', function(err) {
|
||||
return e_c(err);
|
||||
|
@ -430,8 +432,8 @@ function spec(b) {
|
|||
},
|
||||
function(c) {
|
||||
db.createReadStream({
|
||||
start: SPEND_PREFIX + txid,
|
||||
end: SPEND_PREFIX + txid + '~'
|
||||
start: SPENT_PREFIX + txid,
|
||||
end: SPENT_PREFIX + txid + '~'
|
||||
})
|
||||
.pipe(
|
||||
db.createWriteStream({
|
||||
|
@ -553,7 +555,7 @@ function spec(b) {
|
|||
async.forEachLimit(tx.vin, CONCURRENCY,
|
||||
function(i, next_out) {
|
||||
db.batch()
|
||||
.put(SPEND_PREFIX + i.txid + '-' + i.vout + '-' + tx.txid + '-' + i.n,
|
||||
.put(SPENT_PREFIX + i.txid + '-' + i.vout + '-' + tx.txid + '-' + i.n,
|
||||
ts || 0)
|
||||
.write(next_out);
|
||||
},
|
||||
|
|
|
@ -52,10 +52,10 @@ function($scope, $rootScope, $routeParams, $location, Global, Transaction, Trans
|
|||
tmp[addr].addr = addr;
|
||||
tmp[addr].items = [];
|
||||
}
|
||||
tmp[addr].isSpend = items[i].spendTxId;
|
||||
tmp[addr].isSpent = items[i].spentTxId;
|
||||
|
||||
tmp[addr].doubleSpendTxID = tmp[addr].doubleSpendTxID || items[i].doubleSpendTxID;
|
||||
tmp[addr].doubleSpendIndex = tmp[addr].doubleSpendIndex || items[i].doubleSpendIndex;
|
||||
tmp[addr].doubleSpentTxID = tmp[addr].doubleSpentTxID || items[i].doubleSpentTxID;
|
||||
tmp[addr].doubleSpentIndex = tmp[addr].doubleSpentIndex || items[i].doubleSpentIndex;
|
||||
tmp[addr].unconfirmedInput += items[i].unconfirmedInput;
|
||||
tmp[addr].dbError = tmp[addr].dbError || items[i].dbError;
|
||||
tmp[addr].valueSat += items[i].value * COIN;
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
</div>
|
||||
<div data-ng-show="vin.unconfirmedInput" class="text-danger"> <span class="glyphicon glyphicon-warning-sign"></span> (Input unconfirmed)</div>
|
||||
<div data-ng-show="vin.dbError" class="text-danger"> <span class="glyphicon glyphicon-warning-sign"></span> Incoherence in levelDB detected, please resync</div>
|
||||
<div data-ng-show="vin.doubleSpendTxID" class="text-danger"> <span class="glyphicon glyphicon-warning-sign"></span> Double spend attempt detected. From tx:
|
||||
<a href="/tx/{{vin.doubleSpendTxID}}">{{vin.doubleSpendTxID}},{{vin.doubleSpendIndex}}</a>
|
||||
<div data-ng-show="vin.doubleSpentTxID" class="text-danger"> <span class="glyphicon glyphicon-warning-sign"></span> Double spent attempt detected. From tx:
|
||||
<a href="/tx/{{vin.doubleSpentTxID}}">{{vin.doubleSpentTxID}},{{vin.doubleSpentIndex}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -51,8 +51,8 @@
|
|||
</div>
|
||||
<div data-ng-show="vin.unconfirmedInput" class="text-danger"> <span class="glyphicon glyphicon-warning-sign"></span> (Input unconfirmed)</div>
|
||||
<div data-ng-show="vin.dbError" class="text-danger"> <span class="glyphicon glyphicon-warning-sign"></span> Incoherence in levelDB detected, please resync</div>
|
||||
<div data-ng-show="vin.doubleSpendTxID" class="text-danger"> <span class="glyphicon glyphicon-warning-sign"></span> Double spend attempt detected. From tx:
|
||||
<a href="/tx/{{vin.doubleSpendTxID}}">{{vin.doubleSpendTxID}},{{vin.doubleSpendIndex}}</a>
|
||||
<div data-ng-show="vin.doubleSpentTxID" class="text-danger"> <span class="glyphicon glyphicon-warning-sign"></span> Double spent attempt detected. From tx:
|
||||
<a href="/tx/{{vin.doubleSpentTxID}}">{{vin.doubleSpentTxID}},{{vin.doubleSpentIndex}}</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -83,8 +83,8 @@
|
|||
|
||||
<small>
|
||||
{{$root.currency.getConvertion(vout.value)}}
|
||||
<span class="text-danger" data-ng-show="vout.isSpend" tooltip="Output is spend" tooltip-placement="left">(S)</span>
|
||||
<span class="text-success" data-ng-show="!vout.isSpend" tooltip="Output is unspend" tooltip-placement="left">(U)</span>
|
||||
<span class="text-danger" data-ng-show="vout.isSpent" tooltip="Output is spent" tooltip-placement="left">(S)</span>
|
||||
<span class="text-success" data-ng-show="!vout.isSpent" tooltip="Output is unspent" tooltip-placement="left">(U)</span>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
|
@ -100,8 +100,8 @@
|
|||
<div data-ng-repeat="vout in tx.vout" data-ng-show="itemsExpanded">
|
||||
<div class="col-md-12 transaction-vin-vout">
|
||||
<div class="text-muted pull-right btc-value"><small>{{$root.currency.getConvertion(vout.value)}}
|
||||
<span class="text-success" data-ng-show="!vout.spendTxId" tooltip="Output is unspend" tooltip-placement="left">(U)</span>
|
||||
<a class="glyphicon glyphicon-chevron-right" data-ng-show="vout.spendTxId" href="/#!/tx/{{vout.spendTxId}}" title="Spent at: {{vout.spendTxId}},{{vout.spendIndex}}"></a>
|
||||
<span class="text-success" data-ng-show="!vout.spentTxId" tooltip="Output is unspent" tooltip-placement="left">(U)</span>
|
||||
<a class="glyphicon glyphicon-chevron-right" data-ng-show="vout.spentTxId" href="/#!/tx/{{vout.spentTxId}}" title="Spent at: {{vout.spentTxId}},{{vout.spentIndex}}"></a>
|
||||
|
||||
|
||||
</small>
|
||||
|
|
|
@ -48,8 +48,8 @@ describe('TransactionDb Expenses', function(){
|
|||
var c=0;
|
||||
txDb.fromTxId( txid, function(err, readItems) {
|
||||
s.forEach( function(v) {
|
||||
assert.equal(readItems[c].spendTxId,v.txid);
|
||||
assert.equal(readItems[c].spendIndex,v.n);
|
||||
assert.equal(readItems[c].spentTxId,v.txid);
|
||||
assert.equal(readItems[c].spentIndex,v.n);
|
||||
c++;
|
||||
});
|
||||
done();
|
||||
|
|
Loading…
Reference in New Issue