fix working for spent, also in var names

This commit is contained in:
Matias Alejo Garcia 2014-02-16 13:38:34 -03:00
parent a4626f97eb
commit f69f210abf
5 changed files with 72 additions and 70 deletions

View File

@ -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;

View File

@ -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);
},

View File

@ -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;

View File

@ -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>&nbsp;&nbsp;
<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>&nbsp;&nbsp;
</small>

View File

@ -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();