copay/js/models/core/TxProposals.js

202 lines
4.3 KiB
JavaScript
Raw Normal View History

2014-07-30 17:20:08 -07:00
'use strict';
var bitcore = require('bitcore');
var util = bitcore.util;
var Transaction = bitcore.Transaction;
2014-09-02 14:29:02 -07:00
var TxProposal = require('./TxProposal');
2014-07-30 17:20:08 -07:00
var Script = bitcore.Script;
var Key = bitcore.Key;
var buffertools = bitcore.buffertools;
var preconditions = require('preconditions').instance();
2014-07-31 21:09:46 -07:00
function TxProposals(opts) {
2014-07-30 17:20:08 -07:00
opts = opts || {};
this.walletId = opts.walletId;
this.network = opts.networkName === 'livenet' ?
bitcore.networks.livenet : bitcore.networks.testnet;
this.txps = {};
}
// fromObj => from a trusted source
2014-07-31 21:09:46 -07:00
TxProposals.fromObj = function(o, forceOpts) {
var ret = new TxProposals({
2014-07-30 17:20:08 -07:00
networkName: o.networkName,
walletId: o.walletId,
});
o.txps.forEach(function(o2) {
var t = TxProposal.fromObj(o2, forceOpts);
if (t.builder) {
var id = t.getId();
2014-07-30 17:20:08 -07:00
ret.txps[id] = t;
}
});
return ret;
};
2014-08-21 10:12:55 -07:00
TxProposals.prototype.length = function() {
return Object.keys(this.txps).length;
};
2014-09-09 19:00:24 -07:00
TxProposals.prototype.getNtxidsSince = function(sinceTs) {
preconditions.checkArgument(sinceTs);
var ret = [];
for(var ii in this.txps){
var txp = this.txps[ii];
if (txp.createdTs >= sinceTs)
ret.push(ii);
}
console.log('[TxProposals.js.52:ret:]',ret); //TODO
return ret;
};
2014-07-31 21:09:46 -07:00
TxProposals.prototype.getNtxids = function() {
2014-07-30 17:20:08 -07:00
return Object.keys(this.txps);
};
TxProposals.prototype.deleteOne = function(ntxid) {
preconditions.checkState(this.txps[ntxid], 'Unknown TXP: ' + ntxid);
delete this.txps[ntxid];
};
2014-08-21 10:12:55 -07:00
TxProposals.prototype.deleteAll = function() {
this.txps = {};
};
TxProposals.prototype.deletePending = function(maxRejectCount) {
for (var ntxid in this.txps) {
if (this.txps[ntxid].isPending(maxRejectCount))
delete this.txps[ntxid];
};
};
2014-07-31 21:09:46 -07:00
TxProposals.prototype.toObj = function() {
2014-07-30 17:20:08 -07:00
var ret = [];
for (var id in this.txps) {
var t = this.txps[id];
if (!t.sent)
ret.push(t.toObj());
}
return {
txps: ret,
walletId: this.walletId,
networkName: this.network.name,
};
};
2014-08-03 19:57:23 -07:00
TxProposals.prototype.merge = function(inObj, builderOpts) {
var incomingTx = TxProposal.fromUntrustedObj(inObj, builderOpts);
2014-08-03 18:34:47 -07:00
incomingTx._sync();
2014-07-30 17:20:08 -07:00
2014-08-03 18:34:47 -07:00
var myTxps = this.txps;
2014-08-03 19:57:23 -07:00
var ntxid = incomingTx.getId();
2014-08-03 18:34:47 -07:00
var ret = {
ntxid: ntxid
};
2014-07-30 17:20:08 -07:00
if (myTxps[ntxid]) {
2014-08-03 18:34:47 -07:00
// Merge an existing txProposal
2014-08-04 03:16:22 -07:00
ret.hasChanged = myTxps[ntxid].merge(incomingTx);
2014-08-03 18:34:47 -07:00
} else {
// Create a new one
2014-08-05 12:25:02 -07:00
ret.new = ret.hasChanged = 1;
2014-08-03 19:57:23 -07:00
this.txps[ntxid] = incomingTx;
2014-07-30 17:20:08 -07:00
}
2014-08-03 18:34:47 -07:00
ret.txp = this.txps[ntxid];
2014-07-30 17:20:08 -07:00
return ret;
};
// Add a LOCALLY CREATED (trusted) tx proposal
TxProposals.prototype.add = function(txp) {
2014-08-03 19:57:23 -07:00
txp._sync();
var ntxid = txp.getId();
2014-07-30 17:20:08 -07:00
this.txps[ntxid] = txp;
return ntxid;
};
2014-08-03 19:57:23 -07:00
2014-08-05 12:25:02 -07:00
TxProposals.prototype.get = function(ntxid) {
2014-08-03 19:57:23 -07:00
var ret = this.txps[ntxid];
if (!ret)
2014-08-05 12:25:02 -07:00
throw new Error('Unknown TXP: '+ntxid);
2014-08-03 19:57:23 -07:00
return ret;
};
2014-07-31 21:09:46 -07:00
TxProposals.prototype.getTxProposal = function(ntxid, copayers) {
2014-08-05 12:25:02 -07:00
var txp = this.get(ntxid);
2014-08-03 19:57:23 -07:00
2014-07-30 17:20:08 -07:00
var i = JSON.parse(JSON.stringify(txp));
i.builder = txp.builder;
i.ntxid = ntxid;
i.peerActions = {};
if (copayers) {
for (var j = 0; j < copayers.length; j++) {
var p = copayers[j];
i.peerActions[p] = {};
}
}
for (var p in txp.seenBy) {
i.peerActions[p] = {
seen: txp.seenBy[p]
};
}
for (var p in txp.signedBy) {
i.peerActions[p] = i.peerActions[p] || {};
i.peerActions[p].sign = txp.signedBy[p];
}
var r = 0;
for (var p in txp.rejectedBy) {
i.peerActions[p] = i.peerActions[p] || {};
i.peerActions[p].rejected = txp.rejectedBy[p];
r++;
}
i.rejectCount = r;
var c = txp.creator;
i.peerActions[c] = i.peerActions[c] || {};
i.peerActions[c].create = txp.createdTs;
return i;
};
2014-08-03 19:57:23 -07:00
TxProposals.prototype.reject = function(ntxid, copayerId) {
2014-08-05 12:25:02 -07:00
var txp = this.get(ntxid);
2014-08-03 19:57:23 -07:00
txp.setRejected(copayerId);
};
TxProposals.prototype.seen = function(ntxid, copayerId) {
2014-08-05 12:25:02 -07:00
var txp = this.get(ntxid);
2014-08-03 19:57:23 -07:00
txp.setSeen(copayerId);
};
2014-07-30 17:20:08 -07:00
//returns the unspent txid-vout used in PENDING Txs
2014-07-31 21:09:46 -07:00
TxProposals.prototype.getUsedUnspent = function(maxRejectCount) {
2014-07-30 17:20:08 -07:00
var ret = {};
for (var i in this.txps) {
2014-08-21 11:19:08 -07:00
if (!this.txps[i].isPending(maxRejectCount))
continue;
2014-07-30 17:20:08 -07:00
var u = this.txps[i].builder.getSelectedUnspent();
var p = this.getTxProposal(i);
2014-08-21 10:12:55 -07:00
2014-07-30 17:20:08 -07:00
for (var j in u) {
ret[u[j].txid + ',' + u[j].vout] = 1;
}
}
return ret;
};
2014-07-31 21:09:46 -07:00
module.exports = TxProposals;