mirror of https://github.com/BTCPrivate/copay.git
optimize redeemscript map generation
This commit is contained in:
parent
53e0371b7f
commit
326384cd4b
|
@ -232,8 +232,6 @@ Insight.prototype._requestNode = function(options, callback) {
|
||||||
return callback(e, ret);
|
return callback(e, ret);
|
||||||
});
|
});
|
||||||
response.on('error', function(e) {
|
response.on('error', function(e) {
|
||||||
|
|
||||||
console.log('[Insight.js.201]'); //TODO
|
|
||||||
return callback(e, ret);
|
return callback(e, ret);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -284,7 +282,6 @@ Insight.prototype._requestBrowser = function(options, callback) {
|
||||||
} else {
|
} else {
|
||||||
errTxt = 'Error code: ' + request.status + ' - Status: ' + request.statusText + ' - Description: ' + request.responseText;
|
errTxt = 'Error code: ' + request.status + ' - Status: ' + request.statusText + ' - Description: ' + request.responseText;
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
console.log('### Retrying Insight Request....');
|
|
||||||
return self._request(options, callback);
|
return self._request(options, callback);
|
||||||
}, self.retryDelay);
|
}, self.retryDelay);
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,19 +233,17 @@ PublicKeyRing.prototype.getAddressesInfo = function(opts) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO this could be cached
|
// TODO this could be cached
|
||||||
PublicKeyRing.prototype._addScriptMap = function(map, index, isChange) {
|
PublicKeyRing.prototype._addScriptMap = function(map, path) {
|
||||||
var script = this.getRedeemScript(index, isChange);
|
var p = Structure.indicesForPath(path);
|
||||||
|
var script = this.getRedeemScript(p.index, p.isChange);
|
||||||
map[Address.fromScript(script, this.network.name).toString()] = script.getBuffer().toString('hex');
|
map[Address.fromScript(script, this.network.name).toString()] = script.getBuffer().toString('hex');
|
||||||
};
|
};
|
||||||
|
|
||||||
PublicKeyRing.prototype.getRedeemScriptMap = function() {
|
PublicKeyRing.prototype.getRedeemScriptMap = function(paths) {
|
||||||
var ret = {};
|
var ret = {};
|
||||||
|
for (var i = 0; i < paths.length; i++) {
|
||||||
for (var i = 0; i < this.indexes.getChangeIndex(); i++) {
|
var path = paths[i];
|
||||||
this._addScriptMap(ret, i, true);
|
this._addScriptMap(ret, path);
|
||||||
}
|
|
||||||
for (var i = 0; i < this.indexes.getReceiveIndex(); i++) {
|
|
||||||
this._addScriptMap(ret, i, false);
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,6 @@ var imports = require('soop').imports();
|
||||||
|
|
||||||
function Structure() {}
|
function Structure() {}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Based on https://github.com/maraoz/bips/blob/master/bip-NNNN.mediawiki
|
* Based on https://github.com/maraoz/bips/blob/master/bip-NNNN.mediawiki
|
||||||
* m / purpose' / cosigner_index / change / address_index
|
* m / purpose' / cosigner_index / change / address_index
|
||||||
|
@ -31,6 +30,15 @@ Structure.FullBranch = function(address_index, isChange, cosigner_index) {
|
||||||
sub = sub.substring(2);
|
sub = sub.substring(2);
|
||||||
return BIP45_PUBLIC_PREFIX + '/' + sub;
|
return BIP45_PUBLIC_PREFIX + '/' + sub;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Structure.indicesForPath = function(path) {
|
||||||
|
var s = path.split('/');
|
||||||
|
return {
|
||||||
|
isChange: s[3] === '1',
|
||||||
|
index: parseInt(s[4]),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
Structure.IdFullBranch = Structure.FullBranch(0, 0, ID_INDEX);
|
Structure.IdFullBranch = Structure.FullBranch(0, 0, ID_INDEX);
|
||||||
Structure.IdBranch = Structure.Branch(0, 0, ID_INDEX);
|
Structure.IdBranch = Structure.Branch(0, 0, ID_INDEX);
|
||||||
Structure.PURPOSE = PURPOSE;
|
Structure.PURPOSE = PURPOSE;
|
||||||
|
|
|
@ -709,7 +709,6 @@ Wallet.prototype.createTxSync = function(toAddress, amountSatStr, comment, utxos
|
||||||
|
|
||||||
var b = new Builder(opts)
|
var b = new Builder(opts)
|
||||||
.setUnspent(utxos)
|
.setUnspent(utxos)
|
||||||
.setHashToScriptMap(pkr.getRedeemScriptMap())
|
|
||||||
.setOutputs([{
|
.setOutputs([{
|
||||||
address: toAddress,
|
address: toAddress,
|
||||||
amountSat: amountSat
|
amountSat: amountSat
|
||||||
|
@ -720,6 +719,8 @@ Wallet.prototype.createTxSync = function(toAddress, amountSatStr, comment, utxos
|
||||||
return pkr.pathForAddress(utxo.address);
|
return pkr.pathForAddress(utxo.address);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
b = b.setHashToScriptMap(pkr.getRedeemScriptMap(inputChainPaths));
|
||||||
|
|
||||||
if (priv) {
|
if (priv) {
|
||||||
var keys = priv.getForPaths(inputChainPaths);
|
var keys = priv.getForPaths(inputChainPaths);
|
||||||
var signed = b.sign(keys);
|
var signed = b.sign(keys);
|
||||||
|
|
|
@ -17,7 +17,6 @@ FakeBlockchain.prototype.fixUnspent = function(u) {
|
||||||
};
|
};
|
||||||
|
|
||||||
FakeBlockchain.prototype.getUnspent = function(addresses, cb) {
|
FakeBlockchain.prototype.getUnspent = function(addresses, cb) {
|
||||||
if (!addresses || !addresses.length) return cb(null, []);
|
|
||||||
return cb(null, this.u || [{
|
return cb(null, this.u || [{
|
||||||
'address': 'mji7zocy8QzYywQakwWf99w9bCT6orY1C1',
|
'address': 'mji7zocy8QzYywQakwWf99w9bCT6orY1C1',
|
||||||
'txid': '0be0fb4579911be829e3077202e1ab47fcc12cf3ab8f8487ccceae768e1f95fa',
|
'txid': '0be0fb4579911be829e3077202e1ab47fcc12cf3ab8f8487ccceae768e1f95fa',
|
||||||
|
@ -31,7 +30,6 @@ FakeBlockchain.prototype.getUnspent = function(addresses, cb) {
|
||||||
};
|
};
|
||||||
|
|
||||||
FakeBlockchain.prototype.getUnspent2 = function(addresses, cb) {
|
FakeBlockchain.prototype.getUnspent2 = function(addresses, cb) {
|
||||||
if (!addresses || !addresses.length) return cb(null, []);
|
|
||||||
return cb(null, this.u || [{
|
return cb(null, this.u || [{
|
||||||
'address': 'mji7zocy8QzYywQakwWf99w9bCT6orY1C1',
|
'address': 'mji7zocy8QzYywQakwWf99w9bCT6orY1C1',
|
||||||
'txid': '0be0fb4579911be829e3077202e1ab47fcc12cf3ab8f8487ccceae768e1f95fa',
|
'txid': '0be0fb4579911be829e3077202e1ab47fcc12cf3ab8f8487ccceae768e1f95fa',
|
||||||
|
|
|
@ -381,13 +381,19 @@ describe('PublicKeyRing model', function() {
|
||||||
it('#getRedeemScriptMap check tests', function() {
|
it('#getRedeemScriptMap check tests', function() {
|
||||||
var k = createW();
|
var k = createW();
|
||||||
var w = k.w;
|
var w = k.w;
|
||||||
|
var amount = 2;
|
||||||
|
|
||||||
for (var i = 0; i < 2; i++)
|
for (var i = 0; i < amount; i++)
|
||||||
w.generateAddress(true);
|
w.generateAddress(true);
|
||||||
for (var i = 0; i < 2; i++)
|
for (var i = 0; i < amount; i++)
|
||||||
w.generateAddress(false);
|
w.generateAddress(false);
|
||||||
|
|
||||||
var m = w.getRedeemScriptMap();
|
var m = w.getRedeemScriptMap([
|
||||||
|
'm/45\'/2147483647/1/0',
|
||||||
|
'm/45\'/2147483647/1/1',
|
||||||
|
'm/45\'/2147483647/0/0',
|
||||||
|
'm/45\'/2147483647/0/1'
|
||||||
|
]);
|
||||||
Object.keys(m).length.should.equal(4);
|
Object.keys(m).length.should.equal(4);
|
||||||
Object.keys(m).forEach(function(k) {
|
Object.keys(m).forEach(function(k) {
|
||||||
should.exist(m[k]);
|
should.exist(m[k]);
|
||||||
|
|
|
@ -144,7 +144,6 @@ describe('TxProposals model', function() {
|
||||||
|
|
||||||
var b = new Builder(opts)
|
var b = new Builder(opts)
|
||||||
.setUnspent(utxos)
|
.setUnspent(utxos)
|
||||||
.setHashToScriptMap(pkr.getRedeemScriptMap())
|
|
||||||
.setOutputs([{
|
.setOutputs([{
|
||||||
address: toAddress,
|
address: toAddress,
|
||||||
amountSat: amountSat
|
amountSat: amountSat
|
||||||
|
@ -154,6 +153,12 @@ describe('TxProposals model', function() {
|
||||||
return pkr.pathForAddress(utxo.address);
|
return pkr.pathForAddress(utxo.address);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var selectedUtxos = b.getSelectedUnspent();
|
||||||
|
var inputChainPaths = selectedUtxos.map(function(utxo) {
|
||||||
|
return pkr.pathForAddress(utxo.address);
|
||||||
|
});
|
||||||
|
b.setHashToScriptMap(pkr.getRedeemScriptMap(inputChainPaths));
|
||||||
|
|
||||||
var signRet;
|
var signRet;
|
||||||
if (priv) {
|
if (priv) {
|
||||||
var pkeys = priv.getForPaths(inputChainPaths);
|
var pkeys = priv.getForPaths(inputChainPaths);
|
||||||
|
|
|
@ -42,30 +42,36 @@ describe('Wallet model', function() {
|
||||||
w.getNetworkName().should.equal('testnet');
|
w.getNetworkName().should.equal('testnet');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
var createW = function(netKey, N, conf) {
|
var createW = function(netKey, N, conf) {
|
||||||
|
|
||||||
var c = JSON.parse(JSON.stringify(conf || config));
|
var c = JSON.parse(JSON.stringify(conf || config));
|
||||||
if (!N) N = c.totalCopayers;
|
if (!N) N = c.totalCopayers;
|
||||||
|
|
||||||
if (netKey) c.netKey = netKey;
|
if (netKey) c.netKey = netKey;
|
||||||
c.privateKey = new copay.PrivateKey({
|
var mainPrivateKey = new copay.PrivateKey({
|
||||||
networkName: c.networkName
|
networkName: config.networkName
|
||||||
});
|
});
|
||||||
|
var mainCopayerEPK = mainPrivateKey.deriveBIP45Branch().extendedPublicKeyString();
|
||||||
|
c.privateKey = mainPrivateKey;
|
||||||
|
|
||||||
c.publicKeyRing = new copay.PublicKeyRing({
|
c.publicKeyRing = new copay.PublicKeyRing({
|
||||||
networkName: c.networkName,
|
networkName: c.networkName,
|
||||||
requiredCopayers: Math.min(N, c.requiredCopayers),
|
requiredCopayers: Math.min(N, c.requiredCopayers),
|
||||||
totalCopayers: N,
|
totalCopayers: N,
|
||||||
});
|
});
|
||||||
var copayerEPK = c.privateKey.deriveBIP45Branch().extendedPublicKeyString()
|
c.publicKeyRing.addCopayer(mainCopayerEPK);
|
||||||
c.publicKeyRing.addCopayer(copayerEPK);
|
|
||||||
|
|
||||||
c.txProposals = new copay.TxProposals({
|
c.txProposals = new copay.TxProposals({
|
||||||
networkName: c.networkName,
|
networkName: c.networkName,
|
||||||
});
|
});
|
||||||
c.storage = new Storage(config.storage);
|
|
||||||
c.network = new Network(config.network);
|
var storage = new Storage(config.storage);
|
||||||
c.blockchain = new Blockchain(config.blockchain);
|
var network = new Network(config.network);
|
||||||
|
var blockchain = new Blockchain(config.blockchain);
|
||||||
|
c.storage = storage;
|
||||||
|
c.network = network;
|
||||||
|
c.blockchain = blockchain;
|
||||||
|
|
||||||
c.addressBook = {
|
c.addressBook = {
|
||||||
'2NFR2kzH9NUdp8vsXTB4wWQtTtzhpKxsyoJ': {
|
'2NFR2kzH9NUdp8vsXTB4wWQtTtzhpKxsyoJ': {
|
||||||
|
@ -138,13 +144,6 @@ describe('Wallet model', function() {
|
||||||
pkr.addCopayer();
|
pkr.addCopayer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pkr.generateAddress(true);
|
|
||||||
pkr.generateAddress(true);
|
|
||||||
pkr.generateAddress(true);
|
|
||||||
pkr.generateAddress(false);
|
|
||||||
pkr.generateAddress(false);
|
|
||||||
pkr.generateAddress(false);
|
|
||||||
//3x3 indexes
|
|
||||||
|
|
||||||
return w;
|
return w;
|
||||||
};
|
};
|
||||||
|
@ -234,7 +233,7 @@ describe('Wallet model', function() {
|
||||||
var w = createW2();
|
var w = createW2();
|
||||||
|
|
||||||
var ts = Date.now();
|
var ts = Date.now();
|
||||||
for (var isChange = 0; isChange < 2; isChange++) {
|
for (var isChange = false; !isChange; isChange = true) {
|
||||||
for (var index = 0; index < 3; index++) {
|
for (var index = 0; index < 3; index++) {
|
||||||
unspentTest[0].address = w.publicKeyRing.getAddress(index, isChange).toString();
|
unspentTest[0].address = w.publicKeyRing.getAddress(index, isChange).toString();
|
||||||
unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(index, isChange);
|
unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(index, isChange);
|
||||||
|
@ -531,6 +530,7 @@ describe('Wallet model', function() {
|
||||||
it('should get balance', function(done) {
|
it('should get balance', function(done) {
|
||||||
var w = createW();
|
var w = createW();
|
||||||
var spy = sinon.spy(w.blockchain, 'getUnspent');
|
var spy = sinon.spy(w.blockchain, 'getUnspent');
|
||||||
|
w.blockchain.fixUnspent([]);
|
||||||
w.getBalance(function(err, balance, balanceByAddr, safeBalance) {
|
w.getBalance(function(err, balance, balanceByAddr, safeBalance) {
|
||||||
sinon.assert.callCount(spy, 1);
|
sinon.assert.callCount(spy, 1);
|
||||||
balance.should.equal(0);
|
balance.should.equal(0);
|
||||||
|
|
Loading…
Reference in New Issue