optimize redeemscript map generation

This commit is contained in:
Manuel Araoz 2014-06-24 13:17:22 -03:00
parent 53e0371b7f
commit 326384cd4b
8 changed files with 48 additions and 35 deletions

View File

@ -232,8 +232,6 @@ Insight.prototype._requestNode = function(options, callback) {
return callback(e, ret);
});
response.on('error', function(e) {
console.log('[Insight.js.201]'); //TODO
return callback(e, ret);
});
});
@ -284,7 +282,6 @@ Insight.prototype._requestBrowser = function(options, callback) {
} else {
errTxt = 'Error code: ' + request.status + ' - Status: ' + request.statusText + ' - Description: ' + request.responseText;
setTimeout(function() {
console.log('### Retrying Insight Request....');
return self._request(options, callback);
}, self.retryDelay);
}

View File

@ -233,19 +233,17 @@ PublicKeyRing.prototype.getAddressesInfo = function(opts) {
};
// TODO this could be cached
PublicKeyRing.prototype._addScriptMap = function(map, index, isChange) {
var script = this.getRedeemScript(index, isChange);
PublicKeyRing.prototype._addScriptMap = function(map, path) {
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');
};
PublicKeyRing.prototype.getRedeemScriptMap = function() {
PublicKeyRing.prototype.getRedeemScriptMap = function(paths) {
var ret = {};
for (var i = 0; i < this.indexes.getChangeIndex(); i++) {
this._addScriptMap(ret, i, true);
}
for (var i = 0; i < this.indexes.getReceiveIndex(); i++) {
this._addScriptMap(ret, i, false);
for (var i = 0; i < paths.length; i++) {
var path = paths[i];
this._addScriptMap(ret, path);
}
return ret;
};

View File

@ -4,7 +4,6 @@ var imports = require('soop').imports();
function Structure() {}
/*
* Based on https://github.com/maraoz/bips/blob/master/bip-NNNN.mediawiki
* m / purpose' / cosigner_index / change / address_index
@ -31,6 +30,15 @@ Structure.FullBranch = function(address_index, isChange, cosigner_index) {
sub = sub.substring(2);
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.IdBranch = Structure.Branch(0, 0, ID_INDEX);
Structure.PURPOSE = PURPOSE;

View File

@ -709,7 +709,6 @@ Wallet.prototype.createTxSync = function(toAddress, amountSatStr, comment, utxos
var b = new Builder(opts)
.setUnspent(utxos)
.setHashToScriptMap(pkr.getRedeemScriptMap())
.setOutputs([{
address: toAddress,
amountSat: amountSat
@ -720,6 +719,8 @@ Wallet.prototype.createTxSync = function(toAddress, amountSatStr, comment, utxos
return pkr.pathForAddress(utxo.address);
});
b = b.setHashToScriptMap(pkr.getRedeemScriptMap(inputChainPaths));
if (priv) {
var keys = priv.getForPaths(inputChainPaths);
var signed = b.sign(keys);

View File

@ -17,7 +17,6 @@ FakeBlockchain.prototype.fixUnspent = function(u) {
};
FakeBlockchain.prototype.getUnspent = function(addresses, cb) {
if (!addresses || !addresses.length) return cb(null, []);
return cb(null, this.u || [{
'address': 'mji7zocy8QzYywQakwWf99w9bCT6orY1C1',
'txid': '0be0fb4579911be829e3077202e1ab47fcc12cf3ab8f8487ccceae768e1f95fa',
@ -31,7 +30,6 @@ FakeBlockchain.prototype.getUnspent = function(addresses, cb) {
};
FakeBlockchain.prototype.getUnspent2 = function(addresses, cb) {
if (!addresses || !addresses.length) return cb(null, []);
return cb(null, this.u || [{
'address': 'mji7zocy8QzYywQakwWf99w9bCT6orY1C1',
'txid': '0be0fb4579911be829e3077202e1ab47fcc12cf3ab8f8487ccceae768e1f95fa',

View File

@ -381,13 +381,19 @@ describe('PublicKeyRing model', function() {
it('#getRedeemScriptMap check tests', function() {
var k = createW();
var w = k.w;
var amount = 2;
for (var i = 0; i < 2; i++)
for (var i = 0; i < amount; i++)
w.generateAddress(true);
for (var i = 0; i < 2; i++)
for (var i = 0; i < amount; i++)
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).forEach(function(k) {
should.exist(m[k]);

View File

@ -144,7 +144,6 @@ describe('TxProposals model', function() {
var b = new Builder(opts)
.setUnspent(utxos)
.setHashToScriptMap(pkr.getRedeemScriptMap())
.setOutputs([{
address: toAddress,
amountSat: amountSat
@ -154,6 +153,12 @@ describe('TxProposals model', function() {
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;
if (priv) {
var pkeys = priv.getForPaths(inputChainPaths);

View File

@ -42,30 +42,36 @@ describe('Wallet model', function() {
w.getNetworkName().should.equal('testnet');
});
var createW = function(netKey, N, conf) {
var c = JSON.parse(JSON.stringify(conf || config));
if (!N) N = c.totalCopayers;
if (netKey) c.netKey = netKey;
c.privateKey = new copay.PrivateKey({
networkName: c.networkName
var mainPrivateKey = new copay.PrivateKey({
networkName: config.networkName
});
var mainCopayerEPK = mainPrivateKey.deriveBIP45Branch().extendedPublicKeyString();
c.privateKey = mainPrivateKey;
c.publicKeyRing = new copay.PublicKeyRing({
networkName: c.networkName,
requiredCopayers: Math.min(N, c.requiredCopayers),
totalCopayers: N,
});
var copayerEPK = c.privateKey.deriveBIP45Branch().extendedPublicKeyString()
c.publicKeyRing.addCopayer(copayerEPK);
c.publicKeyRing.addCopayer(mainCopayerEPK);
c.txProposals = new copay.TxProposals({
networkName: c.networkName,
});
c.storage = new Storage(config.storage);
c.network = new Network(config.network);
c.blockchain = new Blockchain(config.blockchain);
var storage = new Storage(config.storage);
var network = new Network(config.network);
var blockchain = new Blockchain(config.blockchain);
c.storage = storage;
c.network = network;
c.blockchain = blockchain;
c.addressBook = {
'2NFR2kzH9NUdp8vsXTB4wWQtTtzhpKxsyoJ': {
@ -138,13 +144,6 @@ describe('Wallet model', function() {
pkr.addCopayer();
}
}
pkr.generateAddress(true);
pkr.generateAddress(true);
pkr.generateAddress(true);
pkr.generateAddress(false);
pkr.generateAddress(false);
pkr.generateAddress(false);
//3x3 indexes
return w;
};
@ -234,7 +233,7 @@ describe('Wallet model', function() {
var w = createW2();
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++) {
unspentTest[0].address = w.publicKeyRing.getAddress(index, isChange).toString();
unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(index, isChange);
@ -531,6 +530,7 @@ describe('Wallet model', function() {
it('should get balance', function(done) {
var w = createW();
var spy = sinon.spy(w.blockchain, 'getUnspent');
w.blockchain.fixUnspent([]);
w.getBalance(function(err, balance, balanceByAddr, safeBalance) {
sinon.assert.callCount(spy, 1);
balance.should.equal(0);