all test passing!

This commit is contained in:
Matias Alejo Garcia 2014-08-03 23:57:23 -03:00
commit f5f9848ff1
5 changed files with 107 additions and 78 deletions

View file

@ -17,8 +17,6 @@ var CORE_FIELDS = ['builderObj', 'inputChainPaths', 'version'];
function TxProposal(opts) {
preconditions.checkArgument(opts);
preconditions.checkArgument(opts.inputChainPaths, 'no inputChainPaths');
preconditions.checkArgument(opts.creator, 'no creator');
preconditions.checkArgument(opts.createdTs, 'no createdTs');
preconditions.checkArgument(opts.builder, 'no builder');
preconditions.checkArgument(opts.inputChainPaths, 'no inputChainPaths');
@ -106,8 +104,7 @@ TxProposal.prototype.toObj = function() {
};
TxProposal.trim = function() {
var o = this.toObj();
TxProposal._trim = function(o) {
var ret = {};
CORE_FIELDS.forEach(function(k) {
ret[k] = o[k];
@ -115,7 +112,6 @@ TxProposal.trim = function() {
return ret;
};
// fromObj => from a trusted source
TxProposal.fromObj = function(o, forceOpts) {
preconditions.checkArgument(o.builderObj);
delete o['builder'];
@ -137,6 +133,9 @@ TxProposal.fromObj = function(o, forceOpts) {
return new TxProposal(o);
};
TxProposal.fromUntrustedObj = function(o, forceOpts) {
return TxProposal.fromObj(TxProposal._trim(o),forceOpts);
};
TxProposal._formatKeys = function(keys) {
@ -208,7 +207,11 @@ TxProposal.prototype.setSeen = function(copayerId) {
};
TxProposal.prototype.setRejected = function(copayerId) {
if (!this.rejectedBy[copayerId] && !this.signedBy)
if (this.signedBy[copayerId])
throw new Error('Can not reject a signed TX');
if (!this.rejectedBy[copayerId])
this.rejectedBy[copayerId] = Date.now();
};
@ -230,7 +233,7 @@ TxProposal.prototype._allSignatures = function() {
TxProposal.prototype.setCopayers = function(senderId, keyMap, readOnlyPeers) {
var newCopayers = {},
var newCopayer = {},
oldCopayers = {}, newSignedBy = {}, readOnlyPeers = {}, isNew = 1;
for(var k in this.signedBy) {
@ -253,35 +256,36 @@ TxProposal.prototype.setCopayers = function(senderId, keyMap, readOnlyPeers) {
if (oldCopayers[copayerId]) {
//Already have it. Do nothing
} else {
newCopayers[copayerId] = Date.now();
newCopayer[copayerId] = Date.now();
delete oldCopayers[i];
}
}
if (!newCopayers[senderId] && !readOnlyPeers[senderId])
if (!newCopayer[senderId] && !readOnlyPeers[senderId])
throw new Error('TX must have a (new) senders signature')
if (isNew && Object.keys(newCopayers).length>1)
throw new Error('New TX must have only 1 signature');
if (Object.keys(newCopayer).length>1)
throw new Error('New TX must have only 1 new signature');
// Handler creator / createdTs.
// from senderId, and must be signed by senderId
if (isNew) {
this.creator = Object.keys(newCopayers)[0];
this.creator = Object.keys(newCopayer)[0];
this.createdTs = Date.now();
}
//Ended. Update this.
for(var i in newCopayers) {
this.signedBy[i] = newCopayers[i];
for(var i in newCopayer) {
this.signedBy[i] = newCopayer[i];
}
// signedBy has preference over rejectedBy
for(var i in this.signedBy) {
delete this.rejectedBy[i];
}
console.log('[TxProposal.js.287:newCopayer:]',newCopayer); //TODO
return Object.keys(newCopayers);
return Object.keys(newCopayer);
};
// merge will not merge any metadata.

View file

@ -56,13 +56,12 @@ TxProposals.prototype.toObj = function() {
};
TxProposals.prototype.merge = function(inObj, senderId, copayersForPubkeys, builderOpts) {
var safeObj = inObj.trimUntrustedObj();
var incomingTx = TxProposal.fromObj(safeObj, builderOpts);
TxProposals.prototype.merge = function(inObj, builderOpts) {
var incomingTx = TxProposal.fromUntrustedObj(inObj, builderOpts);
incomingTx._sync();
var myTxps = this.txps;
var ntxid = inTxp.getId();
var ntxid = incomingTx.getId();
var ret = {
ntxid: ntxid
};
@ -70,37 +69,39 @@ TxProposals.prototype.merge = function(inObj, senderId, copayersForPubkeys, buil
if (myTxps[ntxid]) {
// Merge an existing txProposal
ret.hasChanged = myTxps[ntxid].merge(inTxp, allowedPubKeys);
ret.hasChanged = myTxps[ntxid].merge(incomingTx, allowedPubKeys);
} else {
// Create a new one
ret.new = 1;
this.txps[ntxid] = inTxp;
this.txps[ntxid] = incomingTx;
}
ret.txp = this.txps[ntxid];
return ret;
};
TxProposals.prototype.mergeFromObj = function(txProposalObj, allowedPubKeys, opts) {
var inTxp = TxProposal.fromObj(txProposalObj, opts);
var mergeInfo = this.merge(inTxp, allowedPubKeys);
mergeInfo.inTxp = inTxp;
return mergeInfo;
};
// Add a LOCALLY CREATED (trusted) tx proposal
TxProposals.prototype.add = function(txp) {
txp.sync();
txp._sync();
var ntxid = txp.getId();
this.txps[ntxid] = txp;
return ntxid;
};
TxProposals.prototype._getTxp = function(ntxid) {
var ret = this.txps[ntxid];
if (!ret)
throw new Error('Could not find txp: '+ntxid);
return ret;
};
TxProposals.prototype.getTxProposal = function(ntxid, copayers) {
var txp = this.txps[ntxid];
var txp = this._getTxp(ntxid);
var i = JSON.parse(JSON.stringify(txp));
i.builder = txp.builder;
i.ntxid = ntxid;
@ -136,6 +137,17 @@ TxProposals.prototype.getTxProposal = function(ntxid, copayers) {
return i;
};
TxProposals.prototype.reject = function(ntxid, copayerId) {
var txp = this._getTxp(ntxid);
txp.setRejected(copayerId);
};
TxProposals.prototype.seen = function(ntxid, copayerId) {
var txp = this._getTxp(ntxid);
txp.setSeen(copayerId);
};
//returns the unspent txid-vout used in PENDING Txs
TxProposals.prototype.getUsedUnspent = function(maxRejectCount) {
var ret = {};

View file

@ -130,30 +130,27 @@ Wallet.prototype._handlePublicKeyRing = function(senderId, data, isInbound) {
};
Wallet.prototype._processProposalEvents = function(mergeInfo) {
var ev = [];
if (mergeInfo) {
if (mergeInfo.new) {
Wallet.prototype._processProposalEvents = function(senderId, m) {
var ev;
if (m) {
if (m.new) {
ev = {
type: 'new',
cid: senderId
}
} else {
for (var i in mergeInfo.newCopayers) {
var copayerId = mergeInfo.newCopayers[i];
ev.push({
type: 'signed',
cid: copayerId
});
}
} else if(m.newCopayer){
ev={
type: 'signed',
cid: m.newCopayer
};
}
} else {
ev = {
type: 'corrupt',
cId: senderId,
error: e,
};
}
if (ev)
this.emit('txProposalEvent', ev);
};
@ -189,13 +186,12 @@ Wallet.prototype._handleTxProposal = function(senderId, data) {
var m;
try {
m = this.txProposals.mergeObj(senderId, data.txProposal, Wallet.builderOpts);
m = this.txProposals.merge(data.txProposal, Wallet.builderOpts);
var keyMap = this._getKeyMap(m.tpx,senderId);
ret.newCopayers = m.txp.setCopayers(senderId, keyMap);
ret.newCopayer = m.txp.setCopayers(senderId, keyMap);
} catch (e) {
this.log('Corrupt TX proposal received', senderId, e); //TODO
this.log('Corrupt TX proposal received', senderId, e);
}
if (m) {
@ -632,20 +628,12 @@ Wallet.prototype.getTxProposals = function() {
Wallet.prototype.reject = function(ntxid) {
var myId = this.getMyCopayerId();
var txp = this.txProposals.txps[ntxid];
if (!txp || txp.rejectedBy[myId] || txp.signedBy[myId]) {
throw new Error('Invalid transaction to reject: ' + ntxid);
}
txp.rejectedBy[myId] = Date.now();
var txp = this.txProposals.reject(ntxid, this.getMyCopayerId()) ;
this.sendReject(ntxid);
this.store();
this.emit('txProposalsUpdated');
};
Wallet.prototype.sign = function(ntxid, cb) {
preconditions.checkState(typeof this.getMyCopayerId() !== 'undefined');
var self = this;
@ -834,9 +822,9 @@ Wallet.prototype.createTxSync = function(toAddress, amountSatStr, comment, utxos
var priv = this.privateKey;
opts = opts || {};
preconditions.checkArgument(new Address(toAddress).network().name === this.getNetworkName());
preconditions.checkState(pkr.isComplete());
preconditions.checkState(priv);
preconditions.checkArgument(new Address(toAddress).network().name === this.getNetworkName(), 'networkname mismatch');
preconditions.checkState(pkr.isComplete(), 'pubkey ring incomplete');
preconditions.checkState(priv,'no private key');
if (comment) preconditions.checkArgument(comment.length <= 100);
if (!opts.remainderOut) {