Browse Source

fetch address by walletId/coin

feat/estimateFee-limit
Ivan Socolsky 8 years ago
parent
commit
30494a8133
No known key found for this signature in database GPG Key ID: FAECE6A05FAA4F56
  1. 10
      lib/blockchainmonitor.js
  2. 6
      lib/server.js
  3. 62
      lib/storage.js
  4. 69
      test/integration/server.js

10
lib/blockchainmonitor.js

@ -102,7 +102,7 @@ BlockchainMonitor.prototype._initExplorer = function(coin, network, explorer) {
socket.on('connect_error', function() {
log.error('Error connecting to ' + explorer.getConnectionInfo());
});
socket.on('tx', _.bind(self._handleIncomingTx, self));
socket.on('tx', _.bind(self._handleIncomingTx, self, coin, network));
socket.on('block', _.bind(self._handleNewBlock, self, coin, network));
};
@ -150,7 +150,7 @@ BlockchainMonitor.prototype._handleThirdPartyBroadcasts = function(data, process
});
};
BlockchainMonitor.prototype._handleIncomingPayments = function(data) {
BlockchainMonitor.prototype._handleIncomingPayments = function(coin, network, data) {
var self = this;
if (!data || !data.vout) return;
@ -166,7 +166,7 @@ BlockchainMonitor.prototype._handleIncomingPayments = function(data) {
if (_.isEmpty(outs)) return;
async.each(outs, function(out, next) {
self.storage.fetchAddress(out.address, function(err, address) {
self.storage.fetchAddressByCoin(coin, out.address, function(err, address) {
if (err) {
log.error('Could not fetch addresses from the db');
return next(err);
@ -219,9 +219,9 @@ BlockchainMonitor.prototype._updateActiveAddresses = function(address, cb) {
});
};
BlockchainMonitor.prototype._handleIncomingTx = function(data) {
BlockchainMonitor.prototype._handleIncomingTx = function(coin, network, data) {
this._handleThirdPartyBroadcasts(data);
this._handleIncomingPayments(data);
this._handleIncomingPayments(coin, network, data);
};
BlockchainMonitor.prototype._notifyNewBlock = function(coin, network, hash) {

6
lib/server.js

@ -427,7 +427,7 @@ WalletService.prototype.getWalletFromIdentifier = function(opts, cb) {
});
},
function(done) {
self.storage.fetchAddress(opts.identifier, function(err, address) {
self.storage.fetchAddressByCoin(Defaults.COIN, opts.identifier, function(err, address) {
if (address) walletId = address.walletId;
return done(err);
});
@ -461,7 +461,7 @@ WalletService.prototype.getWalletFromIdentifier = function(opts, cb) {
var outputs = _.first(self._normalizeTxHistory(tx)).outputs;
var toAddresses = _.pluck(outputs, 'address');
async.detect(toAddresses, function(addressStr, nextAddress) {
self.storage.fetchAddress(addressStr, function(err, address) {
self.storage.fetchAddressByCoin(coinNetwork.coin, addressStr, function(err, address) {
if (err || !address) return nextAddress(err, false);
walletId = address.walletId;
nextAddress(null, true);
@ -2047,7 +2047,7 @@ WalletService.prototype.createTx = function(opts, cb) {
});
} else {
if (opts.changeAddress) {
self.storage.fetchAddress(opts.changeAddress, function(err, address) {
self.storage.fetchAddressByWalletId(wallet.id, opts.changeAddress, function(err, address) {
if (err) return cb(Errors.INVALID_CHANGE_ADDRESS);
return cb(null, address);
});

62
lib/storage.js

@ -461,6 +461,7 @@ Storage.prototype.storeAddress = function(address, cb) {
var self = this;
self.db.collection(collections.ADDRESSES).update({
walletId: address.walletId,
address: address.address
}, address, {
w: 1,
@ -471,45 +472,22 @@ Storage.prototype.storeAddress = function(address, cb) {
Storage.prototype.storeAddressAndWallet = function(wallet, addresses, cb) {
var self = this;
function saveAddresses(addresses, cb) {
if (_.isEmpty(addresses)) return cb();
self.db.collection(collections.ADDRESSES).insert(addresses, {
w: 1
}, cb);
};
var addresses = [].concat(addresses);
if (addresses.length == 0) return cb();
if (_.isEmpty(addresses)) return cb();
async.filter(addresses, function(address, next) {
self.db.collection(collections.ADDRESSES).findOne({
address: address.address,
}, {
walletId: true,
}, function(err, result) {
if (err || !result) return next(true);
if (result.walletId != wallet.id) {
log.warn('Address ' + address.address + ' exists in more than one wallet.');
return next(true);
}
// Ignore if address was already in wallet
return next(false);
});
}, function(newAddresses) {
if (newAddresses.length < addresses.length) {
log.warn('Attempted to store already existing addresses on wallet ' + wallet.id);
}
saveAddresses(newAddresses, function(err) {
if (err) return cb(err);
self.storeWallet(wallet, cb);
});
self.db.collection(collections.ADDRESSES).insert(addresses, {
w: 1
}, function(err) {
if (err) return cb(err);
self.storeWallet(wallet, cb);
});
};
Storage.prototype.fetchAddress = function(address, cb) {
Storage.prototype.fetchAddressByWalletId = function(walletId, address, cb) {
var self = this;
this.db.collection(collections.ADDRESSES).findOne({
walletId: walletId,
address: address,
}, function(err, result) {
if (err) return cb(err);
@ -519,6 +497,27 @@ Storage.prototype.fetchAddress = function(address, cb) {
});
};
Storage.prototype.fetchAddressByCoin = function(coin, address, cb) {
var self = this;
this.db.collection(collections.ADDRESSES).find({
address: address,
}).toArray(function(err, result) {
if (err) return cb(err);
if (!result || _.isEmpty(result)) return cb();
if (result.length > 1) {
result = _.find(result, function(address) {
return coin == (address.coin || Defaults.COIN);
});
} else {
result = _.first(result);
}
if (!result) return cb();
return cb(null, Model.Address.fromObj(result));
});
};
Storage.prototype.fetchPreferences = function(walletId, copayerId, cb) {
this.db.collection(collections.PREFERENCES).find({
walletId: walletId,
@ -610,6 +609,7 @@ Storage.prototype.cleanActiveAddresses = function(walletId, cb) {
Storage.prototype.storeActiveAddresses = function(walletId, addresses, cb) {
var self = this;
if (_.isEmpty(addresses)) return cb();
async.each(addresses, function(address, next) {
var record = {
walletId: walletId,

69
test/integration/server.js

@ -1188,22 +1188,6 @@ describe('Wallet service', function() {
});
});
it('should protect against storing same address multiple times', function(done) {
server.createAddress({}, function(err, address) {
should.not.exist(err);
should.exist(address);
delete address._id;
server.storage.storeAddressAndWallet(wallet, address, function(err) {
should.not.exist(err);
server.getMainAddresses({}, function(err, addresses) {
should.not.exist(err);
addresses.length.should.equal(1);
done();
});
});
});
});
it('should create many addresses on simultaneous requests', function(done) {
var N = 5;
async.mapSeries(_.range(N), function(i, cb) {
@ -7615,42 +7599,57 @@ describe('Wallet service', function() {
});
});
describe.skip('BTC & BCH wallets with same seed', function() {
var server, wBtc, wBch;
describe('BTC & BCH wallets with same seed', function() {
var server = {},
wallet = {};
beforeEach(function(done) {
helpers.createAndJoinWallet(1, 1, function(s, w) {
server = s;
wBtc = w;
server.btc = s;
wallet.btc = w;
w.copayers[0].id.should.equal(TestData.copayers[0].id44btc);
helpers.createAndJoinWallet(1, 1, function(s, w) {
wBch = w;
w.copayers[0].id.should.equal(TestData.copayers[0].id44btc);
helpers.createAndJoinWallet(1, 1, {
coin: 'bch'
}, function(s, w) {
server.bch = s;
wallet.bch = w;
w.copayers[0].id.should.equal(TestData.copayers[0].id44bch);
done();
});
});
});
it('should create address', function(done) {
server.createAddress({}, function(err, address) {
server.btc.createAddress({}, function(err, address) {
should.not.exist(err);
should.exist(address);
address.walletId.should.equal(wallet.id);
address.walletId.should.equal(wallet.btc.id);
address.coin.should.equal('btc');
address.network.should.equal('livenet');
address.address.should.equal('1L3z9LPd861FWQhf3vDn89Fnc9dkdBo2CG');
address.isChange.should.be.false;
address.path.should.equal('m/0/0');
address.type.should.equal('P2PKH');
server.getNotifications({}, function(err, notifications) {
server.bch.createAddress({}, function(err, address) {
should.not.exist(err);
var notif = _.find(notifications, {
type: 'NewAddress'
should.exist(address);
address.walletId.should.equal(wallet.bch.id);
address.coin.should.equal('bch');
address.network.should.equal('livenet');
address.address.should.equal('1L3z9LPd861FWQhf3vDn89Fnc9dkdBo2CG');
server.btc.getMainAddresses({}, function(err, addresses) {
should.not.exist(err);
addresses.length.should.equal(1);
addresses[0].coin.should.equal('btc');
addresses[0].walletId.should.equal(wallet.btc.id);
addresses[0].address.should.equal('1L3z9LPd861FWQhf3vDn89Fnc9dkdBo2CG');
server.bch.getMainAddresses({}, function(err, addresses) {
should.not.exist(err);
addresses.length.should.equal(1);
addresses[0].coin.should.equal('bch');
addresses[0].walletId.should.equal(wallet.bch.id);
addresses[0].address.should.equal('1L3z9LPd861FWQhf3vDn89Fnc9dkdBo2CG');
done();
});
});
should.exist(notif);
notif.data.address.should.equal(address.address);
done();
});
});
});
});
});

Loading…
Cancel
Save