|
|
@ -2,6 +2,7 @@ |
|
|
|
|
|
|
|
var _ = require('lodash'); |
|
|
|
var levelup = require('levelup'); |
|
|
|
var async = require('async'); |
|
|
|
var $ = require('preconditions').singleton(); |
|
|
|
var log = require('npmlog'); |
|
|
|
log.debug = log.verbose; |
|
|
@ -19,6 +20,10 @@ var Storage = function(opts) { |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
var walletPrefix = function(id) { |
|
|
|
return 'w!' + id; |
|
|
|
}; |
|
|
|
|
|
|
|
var opKey = function(key) { |
|
|
|
return key ? '!' + key : ''; |
|
|
|
}; |
|
|
@ -30,20 +35,20 @@ var opKeyTs = function(key) { |
|
|
|
|
|
|
|
|
|
|
|
var KEY = { |
|
|
|
WALLET: function(id) { |
|
|
|
return 'wallet!' + id; |
|
|
|
WALLET: function(walletId) { |
|
|
|
return walletPrefix(walletId) + '!main'; |
|
|
|
}, |
|
|
|
COPAYER: function(id) { |
|
|
|
return 'copayer!' + id; |
|
|
|
}, |
|
|
|
TXP: function(walletId, txProposalId) { |
|
|
|
return 'txp!' + walletId + opKey(txProposalId); |
|
|
|
return walletPrefix(walletId) + '!txp' + opKey(txProposalId); |
|
|
|
}, |
|
|
|
PENDING_TXP: function(walletId, txProposalId) { |
|
|
|
return 'pending-txp-ts!' + walletId + opKey(txProposalId); |
|
|
|
return walletPrefix(walletId) + '!ptxp' + opKey(txProposalId); |
|
|
|
}, |
|
|
|
ADDRESS: function(walletId, address) { |
|
|
|
return 'address!' + walletId + opKey(address); |
|
|
|
return walletPrefix(walletId) + '!addr' + opKey(address); |
|
|
|
}, |
|
|
|
}; |
|
|
|
|
|
|
@ -182,6 +187,104 @@ Storage.prototype.storeTx = function(walletId, txp, cb) { |
|
|
|
this.db.batch(ops, cb); |
|
|
|
}; |
|
|
|
|
|
|
|
Storage.prototype.removeTx = function(walletId, txProposalId, cb) { |
|
|
|
var ops = [{ |
|
|
|
type: 'del', |
|
|
|
key: KEY.TXP(walletId, txp.id), |
|
|
|
}, { |
|
|
|
type: 'del', |
|
|
|
key: KEY.PENDING_TXP(walletId, txp.id), |
|
|
|
value: txp, |
|
|
|
}]; |
|
|
|
|
|
|
|
this.db.batch(ops, cb); |
|
|
|
}; |
|
|
|
|
|
|
|
Storage.prototype._delByKey = function(key, cb) { |
|
|
|
var self = this; |
|
|
|
var keys = []; |
|
|
|
this.db.createKeyStream({ |
|
|
|
gte: key, |
|
|
|
lt: key + '~', |
|
|
|
}) |
|
|
|
.on('data', function(key) { |
|
|
|
keys.push(key); |
|
|
|
}) |
|
|
|
.on('error', function(err) { |
|
|
|
if (err.notFound) return cb(); |
|
|
|
|
|
|
|
console.log('[storage.js.252]'); //TODO
|
|
|
|
return cb(err); |
|
|
|
}) |
|
|
|
.on('end', function(err) { |
|
|
|
self.db.batch(_.map(keys, function(k) { |
|
|
|
return { |
|
|
|
key: k, |
|
|
|
type: 'del' |
|
|
|
}; |
|
|
|
}), function(err) { |
|
|
|
return cb(err); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
Storage.prototype.removeAllPendingTxs = function(walletId, cb) { |
|
|
|
this._delByKey(KEY.PENDING_TXP(walletId), cb); |
|
|
|
}; |
|
|
|
|
|
|
|
Storage.prototype.removeAllTxs = function(walletId, cb) { |
|
|
|
this._delByKey(KEY.TXP(walletId), cb); |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
Storage.prototype._removeCopayers = function(walletId, cb) { |
|
|
|
var self = this; |
|
|
|
|
|
|
|
this.fetchWallet(walletId, function(err, w) { |
|
|
|
if (err || !w) return cb(err); |
|
|
|
|
|
|
|
self.db.batch(_.map(w.copayers, function(c) { |
|
|
|
return { |
|
|
|
type: 'del', |
|
|
|
key: KEY.COPAYER(c.id), |
|
|
|
}; |
|
|
|
}), cb); |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Storage.prototype._removeAllAddresses = function(walletId, cb) { |
|
|
|
this._delByKey(KEY.ADDRESS(walletId), cb); |
|
|
|
}; |
|
|
|
|
|
|
|
Storage.prototype.removeWallet = function(walletId, cb) { |
|
|
|
var self = this; |
|
|
|
|
|
|
|
async.series([ |
|
|
|
function(next) { |
|
|
|
self._removeCopayers(walletId, next); |
|
|
|
}, |
|
|
|
function(next) { |
|
|
|
self._removeAllAddresses(walletId, next); |
|
|
|
}, |
|
|
|
function(next) { |
|
|
|
self.removeAllPendingTxs(walletId, next); |
|
|
|
}, |
|
|
|
function(next) { |
|
|
|
self.removeAllTxs(walletId, next); |
|
|
|
}, |
|
|
|
function(next) { |
|
|
|
var ops = [{ |
|
|
|
type: 'del', |
|
|
|
key: KEY.WALLET(walletId), |
|
|
|
}]; |
|
|
|
self.db.batch(ops, next); |
|
|
|
}, |
|
|
|
], cb); |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
Storage.prototype.fetchAddresses = function(walletId, cb) { |
|
|
|
var addresses = []; |
|
|
|
var key = KEY.ADDRESS(walletId); |
|
|
@ -219,9 +322,11 @@ Storage.prototype.removeAddress = function(walletId, address, cb) { |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
Storage.prototype._dump = function(cb) { |
|
|
|
Storage.prototype._dump = function(cb, fn) { |
|
|
|
fn = fn || console.log; |
|
|
|
|
|
|
|
this.db.readStream() |
|
|
|
.on('data', console.log) |
|
|
|
.on('data', fn) |
|
|
|
.on('end', function() { |
|
|
|
if (cb) return cb(); |
|
|
|
}); |
|
|
|