add nonce support to WebRTC and Wallet
Each person keeps track of their own nonce, and the nonces of the other copayers. The nonce is iterated for each message. If a person ever doesn't iterate their nonce, that message is discarded by the copayers. The nonces are saved as networkNonce (your nonce) and networkNonces (the nonces of your copayers) in the wallet file. In order to support restoring old wallets, the first four bytes of the 8 byte nonce are actually the current time in seconds. Thus you can restore an old wallet, because certainly at least one second has passed since your last message. Only if you try to restore an old wallet within 1 second from the time of your last message will you have a problem (or if your system clock is grossly inaccurate).
This commit is contained in:
parent
a1155c2798
commit
88ab38eb00
6 changed files with 370 additions and 23 deletions
|
|
@ -50,6 +50,11 @@ function Wallet(opts) {
|
|||
this.registeredPeerIds = [];
|
||||
this.addressBook = opts.addressBook || {};
|
||||
this.publicKey = this.privateKey.publicHex;
|
||||
|
||||
//network nonces are 8 byte buffers, representing a big endian number
|
||||
//one nonce for oneself, and then one nonce for each copayer
|
||||
this.network.setHexNonce(opts.networkNonce);
|
||||
this.network.setHexNonces(opts.networkNonces);
|
||||
}
|
||||
|
||||
Wallet.parent = EventEmitter;
|
||||
|
|
@ -343,8 +348,14 @@ Wallet.prototype.store = function() {
|
|||
|
||||
Wallet.prototype.toObj = function() {
|
||||
var optsObj = this._optsToObj();
|
||||
|
||||
var networkNonce = this.network.getHexNonce();
|
||||
var networkNonces = this.network.getHexNonces();
|
||||
|
||||
var walletObj = {
|
||||
opts: optsObj,
|
||||
networkNonce: networkNonce, //yours
|
||||
networkNonces: networkNonces, //copayers
|
||||
publicKeyRing: this.publicKeyRing.toObj(),
|
||||
txProposals: this.txProposals.toObj(),
|
||||
privateKey: this.privateKey ? this.privateKey.toObj() : undefined,
|
||||
|
|
@ -374,6 +385,10 @@ Wallet.prototype.toEncryptedObj = function() {
|
|||
return this.storage.export(walletObj);
|
||||
};
|
||||
|
||||
Wallet.prototype.send = function(recipients, obj) {
|
||||
this.network.send(recipients, obj);
|
||||
};
|
||||
|
||||
Wallet.prototype.sendAllTxProposals = function(recipients) {
|
||||
var ntxids = this.txProposals.getNtxids();
|
||||
for (var i in ntxids) {
|
||||
|
|
@ -386,7 +401,7 @@ Wallet.prototype.sendTxProposal = function(ntxid, recipients) {
|
|||
preconditions.checkArgument(ntxid);
|
||||
preconditions.checkState(this.txProposals.txps[ntxid]);
|
||||
this.log('### SENDING txProposal ' + ntxid + ' TO:', recipients || 'All', this.txProposals);
|
||||
this.network.send(recipients, {
|
||||
this.send(recipients, {
|
||||
type: 'txProposal',
|
||||
txProposal: this.txProposals.txps[ntxid].toObj(),
|
||||
walletId: this.id,
|
||||
|
|
@ -396,7 +411,7 @@ Wallet.prototype.sendTxProposal = function(ntxid, recipients) {
|
|||
Wallet.prototype.sendWalletReady = function(recipients) {
|
||||
this.log('### SENDING WalletReady TO:', recipients);
|
||||
|
||||
this.network.send(recipients, {
|
||||
this.send(recipients, {
|
||||
type: 'walletReady',
|
||||
walletId: this.id,
|
||||
});
|
||||
|
|
@ -405,7 +420,7 @@ Wallet.prototype.sendWalletReady = function(recipients) {
|
|||
Wallet.prototype.sendWalletId = function(recipients) {
|
||||
this.log('### SENDING walletId TO:', recipients || 'All', this.id);
|
||||
|
||||
this.network.send(recipients, {
|
||||
this.send(recipients, {
|
||||
type: 'walletId',
|
||||
walletId: this.id,
|
||||
opts: this._optsToObj(),
|
||||
|
|
@ -419,7 +434,7 @@ Wallet.prototype.sendPublicKeyRing = function(recipients) {
|
|||
var publicKeyRing = this.publicKeyRing.toObj();
|
||||
delete publicKeyRing.publicKeysCache; // exclude publicKeysCache from network obj
|
||||
|
||||
this.network.send(recipients, {
|
||||
this.send(recipients, {
|
||||
type: 'publicKeyRing',
|
||||
publicKeyRing: publicKeyRing,
|
||||
walletId: this.id,
|
||||
|
|
@ -429,7 +444,7 @@ Wallet.prototype.sendIndexes = function(recipients) {
|
|||
var indexes = AddressIndex.serialize(this.publicKeyRing.indexes);
|
||||
this.log('### INDEXES TO:', recipients || 'All', indexes);
|
||||
|
||||
this.network.send(recipients, {
|
||||
this.send(recipients, {
|
||||
type: 'indexes',
|
||||
indexes: indexes,
|
||||
walletId: this.id,
|
||||
|
|
@ -438,7 +453,7 @@ Wallet.prototype.sendIndexes = function(recipients) {
|
|||
|
||||
Wallet.prototype.sendAddressBook = function(recipients) {
|
||||
this.log('### SENDING addressBook TO:', recipients || 'All', this.addressBook);
|
||||
this.network.send(recipients, {
|
||||
this.send(recipients, {
|
||||
type: 'addressbook',
|
||||
addressBook: this.addressBook,
|
||||
walletId: this.id,
|
||||
|
|
|
|||
|
|
@ -163,6 +163,57 @@ Network.prototype.getKey = function() {
|
|||
return this.key;
|
||||
};
|
||||
|
||||
//hex version of one's own nonce
|
||||
Network.prototype.setHexNonce = function(networkNonce) {
|
||||
if (networkNonce) {
|
||||
if (networkNonce.length !== 16)
|
||||
throw new Error('incorrect length of hex nonce');
|
||||
this.networkNonce = new Buffer(networkNonce, 'hex');
|
||||
}
|
||||
else
|
||||
this.iterateNonce();
|
||||
};
|
||||
|
||||
//hex version of copayers' nonces
|
||||
Network.prototype.setHexNonces = function(networkNonces) {
|
||||
for (var i in networkNonces) {
|
||||
if (!this.networkNonces)
|
||||
this.networkNonces = {};
|
||||
if (networkNonces[i].length === 16)
|
||||
this.networkNonces[i] = new Buffer(networkNonces[i], 'hex');
|
||||
}
|
||||
};
|
||||
|
||||
//for oneself
|
||||
Network.prototype.getHexNonce = function() {
|
||||
return this.networkNonce.toString('hex');
|
||||
};
|
||||
|
||||
//for copayers
|
||||
Network.prototype.getHexNonces = function() {
|
||||
var networkNoncesHex = [];
|
||||
for (var i in this.networkNonces) {
|
||||
networkNoncesHex[i] = this.networkNonces[i].toString('hex');
|
||||
}
|
||||
return networkNoncesHex;
|
||||
};
|
||||
|
||||
Network.prototype.iterateNonce = function() {
|
||||
if (!this.networkNonce || this.networkNonce.length !== 8) {
|
||||
this.networkNonce = new Buffer(8);
|
||||
this.networkNonce.fill(0);
|
||||
}
|
||||
//the first 4 bytes of a nonce is a unix timestamp in seconds
|
||||
//the second 4 bytes is just an iterated "sub" nonce
|
||||
//the whole thing is interpreted as one big endian number
|
||||
var noncep1 = this.networkNonce.slice(0, 4);
|
||||
noncep1.writeUInt32BE(Math.floor(Date.now()/1000), 0);
|
||||
var noncep2uint = this.networkNonce.slice(4, 8).readUInt32BE(0);
|
||||
var noncep2 = this.networkNonce.slice(4, 8);
|
||||
noncep2.writeUInt32BE(noncep2uint + 1, 0);
|
||||
return this.networkNonce;
|
||||
};
|
||||
|
||||
Network.prototype._onData = function(enc, isInbound, peerId) {
|
||||
var encUint8Array = new Uint8Array(enc);
|
||||
var encbuf = new Buffer(encUint8Array);
|
||||
|
|
@ -173,7 +224,16 @@ Network.prototype._onData = function(enc, isInbound, peerId) {
|
|||
|
||||
try {
|
||||
var encoded = JSON.parse(encstr);
|
||||
var databuf = this._decode(key, encoded);
|
||||
var prevnonce = this.networkNonces ? this.networkNonces[peerId] : undefined;
|
||||
var opts = {prevnonce: prevnonce};
|
||||
var decoded = this._decode(key, encoded, opts);
|
||||
|
||||
//if no error thrown in the last step, we can set the copayer's nonce
|
||||
if (!this.networkNonces)
|
||||
this.networkNonces = {};
|
||||
this.networkNonces[peerId] = decoded.nonce;
|
||||
|
||||
var databuf = decoded.payload;
|
||||
var datastr = databuf.toString();
|
||||
var payload = JSON.parse(datastr);
|
||||
} catch (e) {
|
||||
|
|
@ -384,13 +444,13 @@ Network.prototype._encode = function(topubkey, fromkey, payload, opts) {
|
|||
|
||||
Network.prototype._decode = function(key, encoded, opts) {
|
||||
var decoded = Message.decode(key, encoded, opts);
|
||||
var payload = decoded.payload;
|
||||
return payload;
|
||||
return decoded;
|
||||
};
|
||||
|
||||
Network.prototype._sendToOne = function(copayerId, payload, opts, cb) {
|
||||
Network.prototype._sendToOne = function(copayerId, payload, cb) {
|
||||
if (!Buffer.isBuffer(payload))
|
||||
throw new Error('payload must be a buffer');
|
||||
|
||||
var peerId = this.peerFromCopayer(copayerId);
|
||||
if (peerId !== this.peerId) {
|
||||
var dataConn = this.connections[peerId];
|
||||
|
|
@ -401,7 +461,7 @@ Network.prototype._sendToOne = function(copayerId, payload, opts, cb) {
|
|||
if (typeof cb === 'function') cb();
|
||||
};
|
||||
|
||||
Network.prototype.send = function(copayerIds, payload, opts, cb) {
|
||||
Network.prototype.send = function(copayerIds, payload, cb) {
|
||||
if (!payload) return cb();
|
||||
|
||||
var self = this;
|
||||
|
|
@ -419,10 +479,12 @@ Network.prototype.send = function(copayerIds, payload, opts, cb) {
|
|||
var l = copayerIds.length;
|
||||
var i = 0;
|
||||
copayerIds.forEach(function(copayerId) {
|
||||
self.iterateNonce();
|
||||
var opts = {nonce: self.networkNonce};
|
||||
var copayerIdBuf = new Buffer(copayerId, 'hex');
|
||||
var encPayload = self._encode(copayerIdBuf, self.getKey(), payloadBuf);
|
||||
var encPayload = self._encode(copayerIdBuf, self.getKey(), payloadBuf, opts);
|
||||
var enc = new Buffer(JSON.stringify(encPayload));
|
||||
self._sendToOne(copayerId, enc, opts, function() {
|
||||
self._sendToOne(copayerId, enc, function() {
|
||||
if (++i === l && typeof cb === 'function') cb();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -41,4 +41,55 @@ Network.prototype.peerFromCopayer = function(copayerId) {
|
|||
return copayerId;
|
||||
};
|
||||
|
||||
//hex version of one's own nonce
|
||||
Network.prototype.setHexNonce = function(networkNonce) {
|
||||
if (networkNonce && networkNonce.length === 16)
|
||||
this.networkNonce = new Buffer(networkNonce, 'hex');
|
||||
else
|
||||
this.iterateNonce();
|
||||
};
|
||||
|
||||
//hex version of copayers' nonces
|
||||
Network.prototype.setHexNonces = function(networkNonces) {
|
||||
for (var i in networkNonces) {
|
||||
if (!this.networkNonces)
|
||||
this.networkNonces = {};
|
||||
if (networkNonces[i].length === 16)
|
||||
this.networkNonces[i] = new Buffer(networkNonces[i], 'hex');
|
||||
}
|
||||
};
|
||||
|
||||
//for oneself
|
||||
Network.prototype.getHexNonce = function() {
|
||||
return this.networkNonce.toString('hex');
|
||||
};
|
||||
|
||||
//for copayers
|
||||
Network.prototype.getHexNonces = function() {
|
||||
var networkNoncesHex = [];
|
||||
for (var i in this.networkNonces) {
|
||||
networkNoncesHex = this.networkNonces[i].toString('hex');
|
||||
}
|
||||
return networkNoncesHex;
|
||||
};
|
||||
|
||||
Network.prototype.iterateNonce = function() {
|
||||
if (!this.networkNonce || this.networkNonce.length !== 8) {
|
||||
this.networkNonce = new Buffer(8);
|
||||
this.networkNonce.fill(0);
|
||||
this.networkNonce[7] = 1;
|
||||
return this.networkNonce;
|
||||
}
|
||||
//the first 4 bytes of a nonce is a unix timestamp in seconds
|
||||
//the second 4 bytes is just an iterated "sub" nonce
|
||||
//the whole thing is interpreted as one big endian number
|
||||
var noncep1 = this.networkNonce.slice(0, 4);
|
||||
noncep1.writeUInt32BE(Math.floor(Date.now()/1000), 0);
|
||||
var noncep2uint = this.networkNonce.slice(4, 8).readUInt32BE(0);
|
||||
var noncep2 = this.networkNonce.slice(4, 8);
|
||||
noncep2.writeUInt32BE(noncep2uint + 1, 0);
|
||||
return this.networkNonce;
|
||||
};
|
||||
|
||||
|
||||
module.exports = require('soop')(Network);
|
||||
|
|
|
|||
|
|
@ -687,6 +687,7 @@ describe('Wallet model', function() {
|
|||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should send all TxProposal', function(done) {
|
||||
var w = cachedCreateW2();
|
||||
var utxo = createUTXO(w);
|
||||
|
|
@ -700,6 +701,16 @@ describe('Wallet model', function() {
|
|||
});
|
||||
});
|
||||
|
||||
describe('#send', function() {
|
||||
it('should call this.network.send', function () {
|
||||
var w = cachedCreateW2();
|
||||
var save = w.network.send;
|
||||
w.network.send = sinon.spy();
|
||||
w.send();
|
||||
w.network.send.calledOnce.should.equal(true);
|
||||
w.network.send = save;
|
||||
});
|
||||
});
|
||||
|
||||
describe('#indexDiscovery', function() {
|
||||
var ADDRESSES_CHANGE, ADDRESSES_RECEIVE, w;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ var FakeBlockchain = require('./mocks/FakeBlockchain');
|
|||
var FakeStorage = require('./mocks/FakeStorage');
|
||||
var WalletFactory = require('../js/models/core/WalletFactory');
|
||||
|
||||
var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"cosigner":2,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{},"publicKeysCache":{"m/0/1/0":["0314368b8efa07e8c7dad30498d0a7e3aa575db1fef833347c6d381c1a33a17b17","02cfd95f89ab46bd3bd86954dd9f83dbab0cd2e4466dee587e8e4d8d733fc0d748","02568969eb6212fe946450be6c5b3353fc754a40b2cdc4aed501a8976fec371da8","0360f870a088ae0ef1c37035a9b6a462ca8dcdd5da275f4e2dcd19f44b81d3e7e4","0300ad8f1bded838b02e127bb25961fbcee718db2df81f680f889692acdcbdd73d"],"m/0/1/1":["024f97a9adb2fa9306c4e3d9244f5e5355c7e2c6b3dd4122ba804e17dc9729df5d","0214834a5adcbc4ad0f3bbbc1c280b8ac480387fcc9a1fd988c1526ed496d923c4","024e72338bd5e976375d076bd71a9649e9141b4cbfc9e16cb7109b354b3e913a05","0322045ea35c3118aa7ab9f2c9f182b0120956b0aa65cc72b9d093f145327a4b17","030dc2450c72df366c1960739c577a2efd4451070bd78effcb6f71d1bcd7dfc7a8"],"m/0/1/2":["0247de59deb66783b8f9b0c326234a9569d00866c2a73f599e77a4d0cab5cbce8f","0376e49f0ac3647404034aae0dc8dd927c34a634ef24ea36f56a272f75fce9539b","032fbaa2593bd1eea4a46e7ac15f15802cdd1eb65a7d5bc4364ddd9d52f0838234","03a81f2a7e1f7191aa0b0c6e0a4ccefc71edd3564e86014972fe338045f68d5a5a","02eb8a012ea9a709392502cacda6ef5115d6d2319ab470d546d9068ab941621a99"],"m/0/0/0":["036dcbd378b4352120d6b720b6294dd2d0dd02801fcf010bb69dadbec1f3999279","022089eedb85dc45d1efa418e1ea226588deedebc1d85acca15ff72783e33636c0","0388aa5fd432b74c56427396f350d236c3ca8f7b2f62da513ce4c2e6ff04a67e9c","02fc4caa7449db7483d2e1fccdacac6fa2f736278c758af9966402589b5632f13e","02e4a15b885d8b2d586f82fa85d16179644e60a154674bde0ec3004810b1bdab99"],"m/0/0/1":["039afa26b2f341c76c7b3c3d0672438f35ac6ebb67b1ddfefac9cd79b7b24418c1","021acaaf500d431ebc396f50630767b01c91ce98ae48e968775ceaad932b7e3b8e","022a947259c4a9f76d5e95c0849df31d01233df41d0d75d631b89317a48d8cddce","03d38d9f94217da780303d9a8987c86d737ef39683febc0cd6632cddbfa62186fd","0394d2581b307fe2af19721888d922aab58ab198ef88cedf9506177e30d807811e"],"m/0/0/2":["037825ffce15d34f9bd6c02bcda7701826706471a4d6ab5004eb965f98811c2098","023768dd6d3c71b7df5733ccda5b2d8b454d5b4c4179d91a6fda74db8b869a2406","021a79e91f003f308764d43039e9b5d56bc8f33ca2f4d30ec6cc5a37c0d09dc273","02437f1e388b273936319f79a5d22958ef5ebff9c8cd7b6f6f72518445b1e30867","0373b0881cb4fd02baa62589023fdfe9739c6148cf104d907549f2528eb80146f5"]}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet","privateKeyCache":{}},"addressBook":{}}';
|
||||
var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"cosigner":2,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{},"publicKeysCache":{"m/0/1/0":["0314368b8efa07e8c7dad30498d0a7e3aa575db1fef833347c6d381c1a33a17b17","02cfd95f89ab46bd3bd86954dd9f83dbab0cd2e4466dee587e8e4d8d733fc0d748","02568969eb6212fe946450be6c5b3353fc754a40b2cdc4aed501a8976fec371da8","0360f870a088ae0ef1c37035a9b6a462ca8dcdd5da275f4e2dcd19f44b81d3e7e4","0300ad8f1bded838b02e127bb25961fbcee718db2df81f680f889692acdcbdd73d"],"m/0/1/1":["024f97a9adb2fa9306c4e3d9244f5e5355c7e2c6b3dd4122ba804e17dc9729df5d","0214834a5adcbc4ad0f3bbbc1c280b8ac480387fcc9a1fd988c1526ed496d923c4","024e72338bd5e976375d076bd71a9649e9141b4cbfc9e16cb7109b354b3e913a05","0322045ea35c3118aa7ab9f2c9f182b0120956b0aa65cc72b9d093f145327a4b17","030dc2450c72df366c1960739c577a2efd4451070bd78effcb6f71d1bcd7dfc7a8"],"m/0/1/2":["0247de59deb66783b8f9b0c326234a9569d00866c2a73f599e77a4d0cab5cbce8f","0376e49f0ac3647404034aae0dc8dd927c34a634ef24ea36f56a272f75fce9539b","032fbaa2593bd1eea4a46e7ac15f15802cdd1eb65a7d5bc4364ddd9d52f0838234","03a81f2a7e1f7191aa0b0c6e0a4ccefc71edd3564e86014972fe338045f68d5a5a","02eb8a012ea9a709392502cacda6ef5115d6d2319ab470d546d9068ab941621a99"],"m/0/0/0":["036dcbd378b4352120d6b720b6294dd2d0dd02801fcf010bb69dadbec1f3999279","022089eedb85dc45d1efa418e1ea226588deedebc1d85acca15ff72783e33636c0","0388aa5fd432b74c56427396f350d236c3ca8f7b2f62da513ce4c2e6ff04a67e9c","02fc4caa7449db7483d2e1fccdacac6fa2f736278c758af9966402589b5632f13e","02e4a15b885d8b2d586f82fa85d16179644e60a154674bde0ec3004810b1bdab99"],"m/0/0/1":["039afa26b2f341c76c7b3c3d0672438f35ac6ebb67b1ddfefac9cd79b7b24418c1","021acaaf500d431ebc396f50630767b01c91ce98ae48e968775ceaad932b7e3b8e","022a947259c4a9f76d5e95c0849df31d01233df41d0d75d631b89317a48d8cddce","03d38d9f94217da780303d9a8987c86d737ef39683febc0cd6632cddbfa62186fd","0394d2581b307fe2af19721888d922aab58ab198ef88cedf9506177e30d807811e"],"m/0/0/2":["037825ffce15d34f9bd6c02bcda7701826706471a4d6ab5004eb965f98811c2098","023768dd6d3c71b7df5733ccda5b2d8b454d5b4c4179d91a6fda74db8b869a2406","021a79e91f003f308764d43039e9b5d56bc8f33ca2f4d30ec6cc5a37c0d09dc273","02437f1e388b273936319f79a5d22958ef5ebff9c8cd7b6f6f72518445b1e30867","0373b0881cb4fd02baa62589023fdfe9739c6148cf104d907549f2528eb80146f5"]}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet","privateKeyCache":{}},"addressBook":{}}';
|
||||
|
||||
describe('WalletFactory model', function() {
|
||||
var config = {
|
||||
|
|
@ -97,8 +97,8 @@ describe('WalletFactory model', function() {
|
|||
});
|
||||
|
||||
it('support old index schema: #fromObj #toObj round trip', function() {
|
||||
var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":{"changeIndex":0,"receiveIndex":0},"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{},"publicKeysCache":{"m/0/1/0":["0314368b8efa07e8c7dad30498d0a7e3aa575db1fef833347c6d381c1a33a17b17","02cfd95f89ab46bd3bd86954dd9f83dbab0cd2e4466dee587e8e4d8d733fc0d748","02568969eb6212fe946450be6c5b3353fc754a40b2cdc4aed501a8976fec371da8","0360f870a088ae0ef1c37035a9b6a462ca8dcdd5da275f4e2dcd19f44b81d3e7e4","0300ad8f1bded838b02e127bb25961fbcee718db2df81f680f889692acdcbdd73d"],"m/0/1/1":["024f97a9adb2fa9306c4e3d9244f5e5355c7e2c6b3dd4122ba804e17dc9729df5d","0214834a5adcbc4ad0f3bbbc1c280b8ac480387fcc9a1fd988c1526ed496d923c4","024e72338bd5e976375d076bd71a9649e9141b4cbfc9e16cb7109b354b3e913a05","0322045ea35c3118aa7ab9f2c9f182b0120956b0aa65cc72b9d093f145327a4b17","030dc2450c72df366c1960739c577a2efd4451070bd78effcb6f71d1bcd7dfc7a8"],"m/0/1/2":["0247de59deb66783b8f9b0c326234a9569d00866c2a73f599e77a4d0cab5cbce8f","0376e49f0ac3647404034aae0dc8dd927c34a634ef24ea36f56a272f75fce9539b","032fbaa2593bd1eea4a46e7ac15f15802cdd1eb65a7d5bc4364ddd9d52f0838234","03a81f2a7e1f7191aa0b0c6e0a4ccefc71edd3564e86014972fe338045f68d5a5a","02eb8a012ea9a709392502cacda6ef5115d6d2319ab470d546d9068ab941621a99"],"m/0/0/0":["036dcbd378b4352120d6b720b6294dd2d0dd02801fcf010bb69dadbec1f3999279","022089eedb85dc45d1efa418e1ea226588deedebc1d85acca15ff72783e33636c0","0388aa5fd432b74c56427396f350d236c3ca8f7b2f62da513ce4c2e6ff04a67e9c","02fc4caa7449db7483d2e1fccdacac6fa2f736278c758af9966402589b5632f13e","02e4a15b885d8b2d586f82fa85d16179644e60a154674bde0ec3004810b1bdab99"],"m/0/0/1":["039afa26b2f341c76c7b3c3d0672438f35ac6ebb67b1ddfefac9cd79b7b24418c1","021acaaf500d431ebc396f50630767b01c91ce98ae48e968775ceaad932b7e3b8e","022a947259c4a9f76d5e95c0849df31d01233df41d0d75d631b89317a48d8cddce","03d38d9f94217da780303d9a8987c86d737ef39683febc0cd6632cddbfa62186fd","0394d2581b307fe2af19721888d922aab58ab198ef88cedf9506177e30d807811e"],"m/0/0/2":["037825ffce15d34f9bd6c02bcda7701826706471a4d6ab5004eb965f98811c2098","023768dd6d3c71b7df5733ccda5b2d8b454d5b4c4179d91a6fda74db8b869a2406","021a79e91f003f308764d43039e9b5d56bc8f33ca2f4d30ec6cc5a37c0d09dc273","02437f1e388b273936319f79a5d22958ef5ebff9c8cd7b6f6f72518445b1e30867","0373b0881cb4fd02baa62589023fdfe9739c6148cf104d907549f2528eb80146f5"]}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet","privateKeyCache":{}},"addressBook":{}}';
|
||||
var o2 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"cosigner":2147483647,"changeIndex":0,"receiveIndex":0},{"cosigner":0,"changeIndex":0,"receiveIndex":0},{"cosigner":1,"changeIndex":0,"receiveIndex":0},{"cosigner":2,"changeIndex":0,"receiveIndex":0},{"cosigner":3,"changeIndex":0,"receiveIndex":0},{"cosigner":4,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{},"publicKeysCache":{"m/0/1/0":["0314368b8efa07e8c7dad30498d0a7e3aa575db1fef833347c6d381c1a33a17b17","02cfd95f89ab46bd3bd86954dd9f83dbab0cd2e4466dee587e8e4d8d733fc0d748","02568969eb6212fe946450be6c5b3353fc754a40b2cdc4aed501a8976fec371da8","0360f870a088ae0ef1c37035a9b6a462ca8dcdd5da275f4e2dcd19f44b81d3e7e4","0300ad8f1bded838b02e127bb25961fbcee718db2df81f680f889692acdcbdd73d"],"m/0/1/1":["024f97a9adb2fa9306c4e3d9244f5e5355c7e2c6b3dd4122ba804e17dc9729df5d","0214834a5adcbc4ad0f3bbbc1c280b8ac480387fcc9a1fd988c1526ed496d923c4","024e72338bd5e976375d076bd71a9649e9141b4cbfc9e16cb7109b354b3e913a05","0322045ea35c3118aa7ab9f2c9f182b0120956b0aa65cc72b9d093f145327a4b17","030dc2450c72df366c1960739c577a2efd4451070bd78effcb6f71d1bcd7dfc7a8"],"m/0/1/2":["0247de59deb66783b8f9b0c326234a9569d00866c2a73f599e77a4d0cab5cbce8f","0376e49f0ac3647404034aae0dc8dd927c34a634ef24ea36f56a272f75fce9539b","032fbaa2593bd1eea4a46e7ac15f15802cdd1eb65a7d5bc4364ddd9d52f0838234","03a81f2a7e1f7191aa0b0c6e0a4ccefc71edd3564e86014972fe338045f68d5a5a","02eb8a012ea9a709392502cacda6ef5115d6d2319ab470d546d9068ab941621a99"],"m/0/0/0":["036dcbd378b4352120d6b720b6294dd2d0dd02801fcf010bb69dadbec1f3999279","022089eedb85dc45d1efa418e1ea226588deedebc1d85acca15ff72783e33636c0","0388aa5fd432b74c56427396f350d236c3ca8f7b2f62da513ce4c2e6ff04a67e9c","02fc4caa7449db7483d2e1fccdacac6fa2f736278c758af9966402589b5632f13e","02e4a15b885d8b2d586f82fa85d16179644e60a154674bde0ec3004810b1bdab99"],"m/0/0/1":["039afa26b2f341c76c7b3c3d0672438f35ac6ebb67b1ddfefac9cd79b7b24418c1","021acaaf500d431ebc396f50630767b01c91ce98ae48e968775ceaad932b7e3b8e","022a947259c4a9f76d5e95c0849df31d01233df41d0d75d631b89317a48d8cddce","03d38d9f94217da780303d9a8987c86d737ef39683febc0cd6632cddbfa62186fd","0394d2581b307fe2af19721888d922aab58ab198ef88cedf9506177e30d807811e"],"m/0/0/2":["037825ffce15d34f9bd6c02bcda7701826706471a4d6ab5004eb965f98811c2098","023768dd6d3c71b7df5733ccda5b2d8b454d5b4c4179d91a6fda74db8b869a2406","021a79e91f003f308764d43039e9b5d56bc8f33ca2f4d30ec6cc5a37c0d09dc273","02437f1e388b273936319f79a5d22958ef5ebff9c8cd7b6f6f72518445b1e30867","0373b0881cb4fd02baa62589023fdfe9739c6148cf104d907549f2528eb80146f5"]}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet","privateKeyCache":{}},"addressBook":{}}';
|
||||
var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":{"changeIndex":0,"receiveIndex":0},"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{},"publicKeysCache":{"m/0/1/0":["0314368b8efa07e8c7dad30498d0a7e3aa575db1fef833347c6d381c1a33a17b17","02cfd95f89ab46bd3bd86954dd9f83dbab0cd2e4466dee587e8e4d8d733fc0d748","02568969eb6212fe946450be6c5b3353fc754a40b2cdc4aed501a8976fec371da8","0360f870a088ae0ef1c37035a9b6a462ca8dcdd5da275f4e2dcd19f44b81d3e7e4","0300ad8f1bded838b02e127bb25961fbcee718db2df81f680f889692acdcbdd73d"],"m/0/1/1":["024f97a9adb2fa9306c4e3d9244f5e5355c7e2c6b3dd4122ba804e17dc9729df5d","0214834a5adcbc4ad0f3bbbc1c280b8ac480387fcc9a1fd988c1526ed496d923c4","024e72338bd5e976375d076bd71a9649e9141b4cbfc9e16cb7109b354b3e913a05","0322045ea35c3118aa7ab9f2c9f182b0120956b0aa65cc72b9d093f145327a4b17","030dc2450c72df366c1960739c577a2efd4451070bd78effcb6f71d1bcd7dfc7a8"],"m/0/1/2":["0247de59deb66783b8f9b0c326234a9569d00866c2a73f599e77a4d0cab5cbce8f","0376e49f0ac3647404034aae0dc8dd927c34a634ef24ea36f56a272f75fce9539b","032fbaa2593bd1eea4a46e7ac15f15802cdd1eb65a7d5bc4364ddd9d52f0838234","03a81f2a7e1f7191aa0b0c6e0a4ccefc71edd3564e86014972fe338045f68d5a5a","02eb8a012ea9a709392502cacda6ef5115d6d2319ab470d546d9068ab941621a99"],"m/0/0/0":["036dcbd378b4352120d6b720b6294dd2d0dd02801fcf010bb69dadbec1f3999279","022089eedb85dc45d1efa418e1ea226588deedebc1d85acca15ff72783e33636c0","0388aa5fd432b74c56427396f350d236c3ca8f7b2f62da513ce4c2e6ff04a67e9c","02fc4caa7449db7483d2e1fccdacac6fa2f736278c758af9966402589b5632f13e","02e4a15b885d8b2d586f82fa85d16179644e60a154674bde0ec3004810b1bdab99"],"m/0/0/1":["039afa26b2f341c76c7b3c3d0672438f35ac6ebb67b1ddfefac9cd79b7b24418c1","021acaaf500d431ebc396f50630767b01c91ce98ae48e968775ceaad932b7e3b8e","022a947259c4a9f76d5e95c0849df31d01233df41d0d75d631b89317a48d8cddce","03d38d9f94217da780303d9a8987c86d737ef39683febc0cd6632cddbfa62186fd","0394d2581b307fe2af19721888d922aab58ab198ef88cedf9506177e30d807811e"],"m/0/0/2":["037825ffce15d34f9bd6c02bcda7701826706471a4d6ab5004eb965f98811c2098","023768dd6d3c71b7df5733ccda5b2d8b454d5b4c4179d91a6fda74db8b869a2406","021a79e91f003f308764d43039e9b5d56bc8f33ca2f4d30ec6cc5a37c0d09dc273","02437f1e388b273936319f79a5d22958ef5ebff9c8cd7b6f6f72518445b1e30867","0373b0881cb4fd02baa62589023fdfe9739c6148cf104d907549f2528eb80146f5"]}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet","privateKeyCache":{}},"addressBook":{}}';
|
||||
var o2 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"cosigner":2147483647,"changeIndex":0,"receiveIndex":0},{"cosigner":0,"changeIndex":0,"receiveIndex":0},{"cosigner":1,"changeIndex":0,"receiveIndex":0},{"cosigner":2,"changeIndex":0,"receiveIndex":0},{"cosigner":3,"changeIndex":0,"receiveIndex":0},{"cosigner":4,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{},"publicKeysCache":{"m/0/1/0":["0314368b8efa07e8c7dad30498d0a7e3aa575db1fef833347c6d381c1a33a17b17","02cfd95f89ab46bd3bd86954dd9f83dbab0cd2e4466dee587e8e4d8d733fc0d748","02568969eb6212fe946450be6c5b3353fc754a40b2cdc4aed501a8976fec371da8","0360f870a088ae0ef1c37035a9b6a462ca8dcdd5da275f4e2dcd19f44b81d3e7e4","0300ad8f1bded838b02e127bb25961fbcee718db2df81f680f889692acdcbdd73d"],"m/0/1/1":["024f97a9adb2fa9306c4e3d9244f5e5355c7e2c6b3dd4122ba804e17dc9729df5d","0214834a5adcbc4ad0f3bbbc1c280b8ac480387fcc9a1fd988c1526ed496d923c4","024e72338bd5e976375d076bd71a9649e9141b4cbfc9e16cb7109b354b3e913a05","0322045ea35c3118aa7ab9f2c9f182b0120956b0aa65cc72b9d093f145327a4b17","030dc2450c72df366c1960739c577a2efd4451070bd78effcb6f71d1bcd7dfc7a8"],"m/0/1/2":["0247de59deb66783b8f9b0c326234a9569d00866c2a73f599e77a4d0cab5cbce8f","0376e49f0ac3647404034aae0dc8dd927c34a634ef24ea36f56a272f75fce9539b","032fbaa2593bd1eea4a46e7ac15f15802cdd1eb65a7d5bc4364ddd9d52f0838234","03a81f2a7e1f7191aa0b0c6e0a4ccefc71edd3564e86014972fe338045f68d5a5a","02eb8a012ea9a709392502cacda6ef5115d6d2319ab470d546d9068ab941621a99"],"m/0/0/0":["036dcbd378b4352120d6b720b6294dd2d0dd02801fcf010bb69dadbec1f3999279","022089eedb85dc45d1efa418e1ea226588deedebc1d85acca15ff72783e33636c0","0388aa5fd432b74c56427396f350d236c3ca8f7b2f62da513ce4c2e6ff04a67e9c","02fc4caa7449db7483d2e1fccdacac6fa2f736278c758af9966402589b5632f13e","02e4a15b885d8b2d586f82fa85d16179644e60a154674bde0ec3004810b1bdab99"],"m/0/0/1":["039afa26b2f341c76c7b3c3d0672438f35ac6ebb67b1ddfefac9cd79b7b24418c1","021acaaf500d431ebc396f50630767b01c91ce98ae48e968775ceaad932b7e3b8e","022a947259c4a9f76d5e95c0849df31d01233df41d0d75d631b89317a48d8cddce","03d38d9f94217da780303d9a8987c86d737ef39683febc0cd6632cddbfa62186fd","0394d2581b307fe2af19721888d922aab58ab198ef88cedf9506177e30d807811e"],"m/0/0/2":["037825ffce15d34f9bd6c02bcda7701826706471a4d6ab5004eb965f98811c2098","023768dd6d3c71b7df5733ccda5b2d8b454d5b4c4179d91a6fda74db8b869a2406","021a79e91f003f308764d43039e9b5d56bc8f33ca2f4d30ec6cc5a37c0d09dc273","02437f1e388b273936319f79a5d22958ef5ebff9c8cd7b6f6f72518445b1e30867","0373b0881cb4fd02baa62589023fdfe9739c6148cf104d907549f2528eb80146f5"]}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet","privateKeyCache":{}},"addressBook":{}}';
|
||||
|
||||
var wf = new WalletFactory(config, '0.0.5');
|
||||
var w = wf.fromObj(JSON.parse(o));
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ describe('Network / WebRTC', function() {
|
|||
var encoded = n._encode(key.public, key, data);
|
||||
var decoded = n._decode(key, encoded);
|
||||
encoded.sig.should.not.equal(0);
|
||||
decoded.toString().should.equal('my data to encrypt');
|
||||
decoded.payload.toString().should.equal('my data to encrypt');
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -168,11 +168,11 @@ describe('Network / WebRTC', function() {
|
|||
key.regenerateSync();
|
||||
|
||||
var copayerId = key.public.toString('hex');
|
||||
n._sendToOne = function(a1, a2, a3, cb) {
|
||||
n._sendToOne = function(a1, a2, cb) {
|
||||
cb();
|
||||
};
|
||||
var opts = {};
|
||||
n.send(copayerId, data, opts, function() {
|
||||
n.send(copayerId, data, function() {
|
||||
done();
|
||||
});
|
||||
|
||||
|
|
@ -191,13 +191,13 @@ describe('Network / WebRTC', function() {
|
|||
key.regenerateSync();
|
||||
|
||||
var copayerId = key.public.toString('hex');
|
||||
n._sendToOne = function(a1, enc, opts, cb) {
|
||||
n._sendToOne = function(a1, enc, cb) {
|
||||
var encPayload = JSON.parse(enc.toString());
|
||||
encPayload.sig.length.should.be.greaterThan(0);
|
||||
cb();
|
||||
};
|
||||
var opts = {};
|
||||
n.send(copayerId, data, opts, function() {
|
||||
n.send(copayerId, data, function() {
|
||||
done();
|
||||
});
|
||||
|
||||
|
|
@ -216,11 +216,11 @@ describe('Network / WebRTC', function() {
|
|||
key.regenerateSync();
|
||||
|
||||
var copayerIds = [key.public.toString('hex')];
|
||||
n._sendToOne = function(a1, a2, a3, cb) {
|
||||
n._sendToOne = function(a1, a2, cb) {
|
||||
cb();
|
||||
};
|
||||
var opts = {};
|
||||
n.send(copayerIds, data, opts, function() {
|
||||
n.send(copayerIds, data, function() {
|
||||
done();
|
||||
});
|
||||
|
||||
|
|
@ -294,6 +294,214 @@ describe('Network / WebRTC', function() {
|
|||
n._deletePeer.getCall(0).args[1].should.equal('incorrect pubkey for peerId');
|
||||
});
|
||||
|
||||
it('should not reject data sent from a peer with no previously set nonce but who is setting one now', function() {
|
||||
var n = new WebRTC();
|
||||
n.privkey = key2.private.toString('hex');
|
||||
//n.networkNonces = {};
|
||||
//n.networkNonces[(new bitcore.SIN(key1.public)).toString()] = new Buffer('0000000000000001', 'hex'); //previously used nonce
|
||||
|
||||
var message = {
|
||||
type: 'hello',
|
||||
copayerId: key1.public.toString('hex')
|
||||
};
|
||||
var messagestr = JSON.stringify(message);
|
||||
var messagebuf = new Buffer(messagestr);
|
||||
|
||||
var opts = {nonce: new Buffer('0000000000000001', 'hex')}; //message send with new nonce
|
||||
var encoded = n._encode(key2.public, key1, messagebuf, opts);
|
||||
var encodedstr = JSON.stringify(encoded);
|
||||
var encodeduint = new Buffer(encodedstr);
|
||||
|
||||
var isInbound = true;
|
||||
var peerId = new bitcore.SIN(key1.public);
|
||||
|
||||
n._deletePeer = sinon.spy();
|
||||
|
||||
n._onData(encodeduint, isInbound, peerId);
|
||||
n._deletePeer.calledOnce.should.equal(false);
|
||||
n.getHexNonces()[(new bitcore.SIN(key1.public)).toString()].toString('hex').should.equal('0000000000000001');
|
||||
});
|
||||
|
||||
it('should not reject data sent from a peer with a really big new nonce', function() {
|
||||
var n = new WebRTC();
|
||||
n.privkey = key2.private.toString('hex');
|
||||
n.networkNonces = {};
|
||||
n.networkNonces[(new bitcore.SIN(key1.public)).toString()] = new Buffer('5000000000000001', 'hex'); //previously used nonce
|
||||
|
||||
var message = {
|
||||
type: 'hello',
|
||||
copayerId: key1.public.toString('hex')
|
||||
};
|
||||
var messagestr = JSON.stringify(message);
|
||||
var messagebuf = new Buffer(messagestr);
|
||||
|
||||
var opts = {nonce: new Buffer('5000000000000002', 'hex')}; //message send with new nonce
|
||||
var encoded = n._encode(key2.public, key1, messagebuf, opts);
|
||||
var encodedstr = JSON.stringify(encoded);
|
||||
var encodeduint = new Buffer(encodedstr);
|
||||
|
||||
var isInbound = true;
|
||||
var peerId = new bitcore.SIN(key1.public);
|
||||
|
||||
n._deletePeer = sinon.spy();
|
||||
|
||||
n._onData(encodeduint, isInbound, peerId);
|
||||
n._deletePeer.calledOnce.should.equal(false);
|
||||
});
|
||||
|
||||
it('should not reject data sent from a peer with a really big new nonce', function() {
|
||||
var n = new WebRTC();
|
||||
n.privkey = key2.private.toString('hex');
|
||||
n.networkNonces = {};
|
||||
n.networkNonces[(new bitcore.SIN(key1.public)).toString()] = new Buffer('5000000000000001', 'hex'); //previously used nonce
|
||||
|
||||
var message = {
|
||||
type: 'hello',
|
||||
copayerId: key1.public.toString('hex')
|
||||
};
|
||||
var messagestr = JSON.stringify(message);
|
||||
var messagebuf = new Buffer(messagestr);
|
||||
|
||||
var opts = {nonce: new Buffer('5000000000000002', 'hex')}; //message send with new nonce
|
||||
var encoded = n._encode(key2.public, key1, messagebuf, opts);
|
||||
var encodedstr = JSON.stringify(encoded);
|
||||
var encodeduint = new Buffer(encodedstr);
|
||||
|
||||
var isInbound = true;
|
||||
var peerId = new bitcore.SIN(key1.public);
|
||||
|
||||
n._deletePeer = sinon.spy();
|
||||
|
||||
n._onData(encodeduint, isInbound, peerId);
|
||||
n._deletePeer.calledOnce.should.equal(false);
|
||||
});
|
||||
|
||||
it('should reject data sent from a peer with an outdated nonce', function() {
|
||||
var n = new WebRTC();
|
||||
n.privkey = key2.private.toString('hex');
|
||||
n.networkNonces = {};
|
||||
n.networkNonces[(new bitcore.SIN(key1.public)).toString()] = new Buffer('0000000000000002', 'hex'); //previously used nonce
|
||||
|
||||
var message = {
|
||||
type: 'hello',
|
||||
copayerId: key1.public.toString('hex')
|
||||
};
|
||||
var messagestr = JSON.stringify(message);
|
||||
var messagebuf = new Buffer(messagestr);
|
||||
|
||||
var opts = {nonce: new Buffer('0000000000000001', 'hex')}; //message send with old nonce
|
||||
var encoded = n._encode(key2.public, key1, messagebuf, opts);
|
||||
var encodedstr = JSON.stringify(encoded);
|
||||
var encodeduint = new Buffer(encodedstr);
|
||||
|
||||
var isInbound = true;
|
||||
var peerId = new bitcore.SIN(key1.public);
|
||||
|
||||
n._deletePeer = sinon.spy();
|
||||
|
||||
n._onData(encodeduint, isInbound, peerId);
|
||||
n._deletePeer.calledOnce.should.equal(true);
|
||||
});
|
||||
|
||||
it('should reject data sent from a peer with a really big outdated nonce', function() {
|
||||
var n = new WebRTC();
|
||||
n.privkey = key2.private.toString('hex');
|
||||
n.networkNonces = {};
|
||||
n.networkNonces[(new bitcore.SIN(key1.public)).toString()] = new Buffer('5000000000000002', 'hex'); //previously used nonce
|
||||
|
||||
var message = {
|
||||
type: 'hello',
|
||||
copayerId: key1.public.toString('hex')
|
||||
};
|
||||
var messagestr = JSON.stringify(message);
|
||||
var messagebuf = new Buffer(messagestr);
|
||||
|
||||
var opts = {nonce: new Buffer('5000000000000001', 'hex')}; //message send with old nonce
|
||||
var encoded = n._encode(key2.public, key1, messagebuf, opts);
|
||||
var encodedstr = JSON.stringify(encoded);
|
||||
var encodeduint = new Buffer(encodedstr);
|
||||
|
||||
var isInbound = true;
|
||||
var peerId = new bitcore.SIN(key1.public);
|
||||
|
||||
n._deletePeer = sinon.spy();
|
||||
|
||||
n._onData(encodeduint, isInbound, peerId);
|
||||
n._deletePeer.calledOnce.should.equal(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#setHexNonce', function() {
|
||||
|
||||
it('should set a nonce from a hex value', function() {
|
||||
var hex = '0000000000000000';
|
||||
var n = new WebRTC();
|
||||
n.setHexNonce(hex);
|
||||
n.getHexNonce().should.equal(hex);
|
||||
n.networkNonce.toString('hex').should.equal(hex);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#setHexNonces', function() {
|
||||
|
||||
it('should set a nonce from a hex value', function() {
|
||||
var hex = '0000000000000000';
|
||||
var n = new WebRTC();
|
||||
n.setHexNonces({fakeid: hex});
|
||||
n.getHexNonces().fakeid.should.equal(hex);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getHexNonce', function() {
|
||||
|
||||
it('should get a nonce hex value', function() {
|
||||
var hex = '0000000000000000';
|
||||
var n = new WebRTC();
|
||||
n.setHexNonce(hex);
|
||||
n.getHexNonce().should.equal(hex);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getHexNonces', function() {
|
||||
|
||||
it('should get a nonce from a hex value', function() {
|
||||
var hex = '0000000000000000';
|
||||
var n = new WebRTC();
|
||||
n.setHexNonces({fakeid: hex});
|
||||
n.getHexNonces().fakeid.should.equal(hex);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#iterateNonce', function() {
|
||||
|
||||
it('should set a nonce not already set', function() {
|
||||
var n = new WebRTC();
|
||||
n.iterateNonce();
|
||||
n.networkNonce.slice(4, 8).toString('hex').should.equal('00000001');
|
||||
n.networkNonce.slice(0, 4).toString('hex').should.not.equal('00000000');
|
||||
});
|
||||
|
||||
it('called twice should increment', function() {
|
||||
var n = new WebRTC();
|
||||
n.iterateNonce();
|
||||
n.networkNonce.slice(4, 8).toString('hex').should.equal('00000001');
|
||||
n.iterateNonce();
|
||||
n.networkNonce.slice(4, 8).toString('hex').should.equal('00000002');
|
||||
});
|
||||
|
||||
it('should set the first byte to the most significant "now" digit', function() {
|
||||
var n = new WebRTC();
|
||||
n.iterateNonce();
|
||||
var buf = new Buffer(4);
|
||||
buf.writeUInt32BE(Math.floor(Date.now()/1000), 0);
|
||||
n.networkNonce[0].should.equal(buf[0]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue