simplify scanning.
This commit is contained in:
parent
2a5c35cf05
commit
06ba355363
@ -259,9 +259,9 @@ HDPrivateKey.prototype.scan44 = function scan44(options, txByAddress, callback)
|
|||||||
assert(accounts[accountIndex] == null || chainConstant === 1);
|
assert(accounts[accountIndex] == null || chainConstant === 1);
|
||||||
|
|
||||||
if (chainConstant === 0)
|
if (chainConstant === 0)
|
||||||
accounts[accountIndex] = { addressDepth: addressIndex };
|
accounts[accountIndex] = { addressDepth: addressIndex - gap };
|
||||||
else
|
else
|
||||||
accounts[accountIndex].changeDepth = addressIndex;
|
accounts[accountIndex].changeDepth = addressIndex - gap;
|
||||||
|
|
||||||
// 4. if no transactions are found on the
|
// 4. if no transactions are found on the
|
||||||
// external chain, stop discovery
|
// external chain, stop discovery
|
||||||
@ -410,9 +410,9 @@ HDPrivateKey.prototype.scan45 = function scan45(options, txByAddress, callback)
|
|||||||
assert(cosigners[cosignerIndex] == null || chainConstant === 1);
|
assert(cosigners[cosignerIndex] == null || chainConstant === 1);
|
||||||
|
|
||||||
if (chainConstant === 0)
|
if (chainConstant === 0)
|
||||||
cosigners[cosignerIndex] = { addressDepth: addressIndex };
|
cosigners[cosignerIndex] = { addressDepth: addressIndex - gap };
|
||||||
else
|
else
|
||||||
cosigners[cosginerIndex].changeDepth = addressIndex;
|
cosigners[cosginerIndex].changeDepth = addressIndex - gap;
|
||||||
|
|
||||||
if (total === 0) {
|
if (total === 0) {
|
||||||
if (chainConstant === 0)
|
if (chainConstant === 0)
|
||||||
|
|||||||
@ -636,149 +636,54 @@ Wallet.prototype.getOutputPaths = function getOutputPaths(tx) {
|
|||||||
|
|
||||||
Wallet.prototype.getOutputDepth = function getOutputDepth(tx) {
|
Wallet.prototype.getOutputDepth = function getOutputDepth(tx) {
|
||||||
var paths = this.getOutputPaths(tx);
|
var paths = this.getOutputPaths(tx);
|
||||||
var depth = { change: -1, receive: -1 };
|
var depth = { changeDepth: -1, receiveDepth: -1 };
|
||||||
var i, path;
|
var i, path;
|
||||||
|
|
||||||
for (i = 0; i < paths.length; i++) {
|
for (i = 0; i < paths.length; i++) {
|
||||||
path = this.parsePath(paths[i]);
|
path = this.parsePath(paths[i]);
|
||||||
if (path.change) {
|
if (path.change) {
|
||||||
if (path.index > depth.change)
|
if (path.index > depth.changeDepth)
|
||||||
depth.change = path.index;
|
depth.changeDepth = path.index;
|
||||||
} else {
|
} else {
|
||||||
if (path.index > depth.receive)
|
if (path.index > depth.receiveDepth)
|
||||||
depth.receive = path.index;
|
depth.receiveDepth = path.index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
depth.change++;
|
depth.changeDepth++;
|
||||||
depth.receive++;
|
depth.receiveDepth++;
|
||||||
|
|
||||||
return depth;
|
return depth;
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.syncOutputDepth = function syncOutputDepth(tx) {
|
Wallet.prototype.syncOutputDepth = function syncOutputDepth(tx) {
|
||||||
var depth = this.getOutputDepth(tx);
|
var depth = this.getOutputDepth(tx);
|
||||||
if (depth.change >= this.changeDepth)
|
if (depth.changeDepth >= this.changeDepth)
|
||||||
this.setChangeDepth(depth.change + 1);
|
this.setChangeDepth(depth.changeDepth + 1);
|
||||||
if (depth.receive >= this.receiveDepth)
|
if (depth.receiveDepth >= this.receiveDepth)
|
||||||
this.setReceiveDepth(depth.receive + 1);
|
this.setReceiveDepth(depth.receiveDepth + 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.scan = function scan(txByAddress, callback) {
|
Wallet.prototype.scan = function scan(txByAddress, callback) {
|
||||||
function done(err, depths) {
|
var self = this;
|
||||||
|
|
||||||
|
return this._scan({}, txByAddress, function(err, depth) {
|
||||||
if (err)
|
if (err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
|
|
||||||
if (depths.changeDepth >= this.changeDepth)
|
if (depth.changeDepth >= this.changeDepth)
|
||||||
this.setChangeDepth(depths.changeDepth + 1);
|
this.setChangeDepth(depth.changeDepth + 1);
|
||||||
|
|
||||||
if (depths.receiveDepth >= this.receiveDepth)
|
if (depth.receiveDepth >= this.receiveDepth)
|
||||||
this.setReceiveDepth(depths.receiveDepth + 1);
|
this.setReceiveDepth(depth.receiveDepth + 1);
|
||||||
}
|
|
||||||
|
|
||||||
if (this.derivation === 'bip44')
|
return callback(null, self);
|
||||||
return this._scan44({ current: true }, txByAddress, done);
|
});
|
||||||
|
|
||||||
if (this.derivation === 'bip45')
|
|
||||||
return this._scan45({}, txByAddress, done);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype._scan44 = function scan44(options, txByAddress, callback) {
|
Wallet.prototype._scan = function _scan(options, txByAddress, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var accounts = [];
|
var depth = { changeDepth: 0, receiveDepth: 0 };
|
||||||
var isAccount = this.master.isAccount44();
|
|
||||||
var _accountKey = this.accountKey;
|
|
||||||
|
|
||||||
assert(this._initialized);
|
|
||||||
|
|
||||||
return (function chainCheck(change) {
|
|
||||||
return (function scanner(accountIndex) {
|
|
||||||
var addressIndex = 0;
|
|
||||||
var total = 0;
|
|
||||||
var gap = 0;
|
|
||||||
|
|
||||||
if (options.current)
|
|
||||||
accountIndex = self.accountIndex;
|
|
||||||
|
|
||||||
// 1. derive the first account's node (index = 0)
|
|
||||||
self.accountKey = isAccount
|
|
||||||
? self.master
|
|
||||||
: self.master.deriveAccount44(accountIndex);
|
|
||||||
|
|
||||||
if (isAccount)
|
|
||||||
accountIndex = new bn(self.master.childIndex).toNumber() - constants.hd.hardened;
|
|
||||||
|
|
||||||
// 2. derive the external chain node of this account
|
|
||||||
// 3. scan addresses of the external chain;
|
|
||||||
// respect the gap limit described below
|
|
||||||
return (function next() {
|
|
||||||
var address = self.deriveAddress(change, addressIndex++);
|
|
||||||
var addr = address.getAddress();
|
|
||||||
|
|
||||||
return txByAddress(addr, function(err, txs) {
|
|
||||||
var result;
|
|
||||||
|
|
||||||
if (err) {
|
|
||||||
self.accountKey = _accountKey;
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (txs) {
|
|
||||||
if (typeof txs === 'boolean')
|
|
||||||
result = txs;
|
|
||||||
else if (typeof txs === 'number')
|
|
||||||
result = txs > 0;
|
|
||||||
else if (Array.isArray(txs))
|
|
||||||
result = txs.length > 0;
|
|
||||||
else
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
total++;
|
|
||||||
gap = 0;
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (++gap < 20)
|
|
||||||
return next();
|
|
||||||
|
|
||||||
assert(accounts[accountIndex] == null || change === true);
|
|
||||||
|
|
||||||
if (change === false)
|
|
||||||
accounts[accountIndex] = { receiveDepth: addressIndex };
|
|
||||||
else
|
|
||||||
accounts[accountIndex].changeDepth = addressIndex;
|
|
||||||
|
|
||||||
// 4. if no transactions are found on the
|
|
||||||
// external chain, stop discovery
|
|
||||||
if (total === 0) {
|
|
||||||
if (change === false)
|
|
||||||
return chainCheck(true);
|
|
||||||
self.accountKey = _accountKey;
|
|
||||||
if (isAccount || options.current)
|
|
||||||
return callback(null, accounts[accountIndex]);
|
|
||||||
return callback(null, accounts);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. if there are some transactions, increase
|
|
||||||
// the account index and go to step 1
|
|
||||||
if (isAccount || options.current) {
|
|
||||||
if (change === false)
|
|
||||||
return chainCheck(true);
|
|
||||||
self.accountKey = _accountKey;
|
|
||||||
return callback(null, accounts[accountIndex]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return scanner(accountIndex + 1);
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
})(0);
|
|
||||||
})(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
Wallet.prototype._scan45 = function scan45(options, txByAddress, callback) {
|
|
||||||
var depths = { changeDepth: 0, receiveDepth: 0 };
|
|
||||||
|
|
||||||
assert(this._initialized);
|
assert(this._initialized);
|
||||||
|
|
||||||
@ -789,9 +694,8 @@ Wallet.prototype._scan45 = function scan45(options, txByAddress, callback) {
|
|||||||
|
|
||||||
return (function next() {
|
return (function next() {
|
||||||
var address = self.deriveAddress(change, addressIndex++);
|
var address = self.deriveAddress(change, addressIndex++);
|
||||||
var addr = address.getAddress();
|
|
||||||
|
|
||||||
return txByAddress(addr, function(err, txs) {
|
return txByAddress(address.getAddress(), function(err, txs) {
|
||||||
var result;
|
var result;
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
@ -806,6 +710,9 @@ Wallet.prototype._scan45 = function scan45(options, txByAddress, callback) {
|
|||||||
result = txs.length > 0;
|
result = txs.length > 0;
|
||||||
else
|
else
|
||||||
result = false;
|
result = false;
|
||||||
|
|
||||||
|
if (Array.isArray(txs) && (txs[0] instanceof bcoin.tx))
|
||||||
|
txs.forEach(function(tx) { self.addTX(tx); });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
@ -817,41 +724,53 @@ Wallet.prototype._scan45 = function scan45(options, txByAddress, callback) {
|
|||||||
if (++gap < 20)
|
if (++gap < 20)
|
||||||
return next();
|
return next();
|
||||||
|
|
||||||
assert(depths.receiveDepth === 0 || change === true);
|
assert(depth.receiveDepth === 0 || change === true);
|
||||||
|
|
||||||
if (change === false)
|
if (change === false)
|
||||||
depths.receiveDepth = addressIndex;
|
depth.receiveDepth = addressIndex - gap;
|
||||||
else
|
else
|
||||||
depths.changeDepth = addressIndex;
|
depth.changeDepth = addressIndex - gap;
|
||||||
|
|
||||||
if (change === false)
|
if (change === false)
|
||||||
return chainCheck(true);
|
return chainCheck(true);
|
||||||
|
|
||||||
return callback(null, depths);
|
return callback(null, depth);
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
})(false);
|
})(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.scriptInputs = function scriptInputs(tx, index) {
|
Wallet.prototype.scriptInputs = function scriptInputs(tx, index) {
|
||||||
|
var addresses;
|
||||||
|
|
||||||
this.fillPrevout(tx);
|
this.fillPrevout(tx);
|
||||||
var addresses = this.deriveInputs(tx);
|
|
||||||
|
addresses = this.deriveInputs(tx);
|
||||||
|
|
||||||
return addresses.reduce(function(total, address) {
|
return addresses.reduce(function(total, address) {
|
||||||
return total + address.scriptInputs(tx, index);
|
return total + address.scriptInputs(tx, index);
|
||||||
}, 0);
|
}, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.signInputs = function signInputs(tx, type, index) {
|
Wallet.prototype.signInputs = function signInputs(tx, type, index) {
|
||||||
|
var addresses;
|
||||||
|
|
||||||
this.fillPrevout(tx);
|
this.fillPrevout(tx);
|
||||||
var addresses = this.deriveInputs(tx);
|
|
||||||
|
addresses = this.deriveInputs(tx);
|
||||||
|
|
||||||
return addresses.reduce(function(total, address) {
|
return addresses.reduce(function(total, address) {
|
||||||
return total + address.signInputs(tx, type, index);
|
return total + address.signInputs(tx, type, index);
|
||||||
}, 0);
|
}, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.sign = function sign(tx, type, index) {
|
Wallet.prototype.sign = function sign(tx, type, index) {
|
||||||
|
var addresses;
|
||||||
|
|
||||||
this.fillPrevout(tx);
|
this.fillPrevout(tx);
|
||||||
var addresses = this.deriveInputs(tx);
|
|
||||||
|
addresses = this.deriveInputs(tx);
|
||||||
|
|
||||||
return addresses.reduce(function(total, address) {
|
return addresses.reduce(function(total, address) {
|
||||||
return total + address.sign(tx, type, index);
|
return total + address.sign(tx, type, index);
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user