wallet: add removing wallet functionality.

This commit is contained in:
Christopher Jeffrey 2017-11-27 16:56:18 -08:00
parent d896e221c0
commit 9dc6ebd8cf
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
3 changed files with 136 additions and 3 deletions

View File

@ -88,7 +88,9 @@ layouts.walletdb = {
},
Tt: function Tt(key) {
return [key.slice(1, 65)];
}
},
t: 't',
u: 'u'
};
layouts.txdb = {

View File

@ -176,7 +176,9 @@ layouts.walletdb = {
assert(Buffer.isBuffer(key));
assert(key.length === 33);
return key.toString('hex', 1, 33);
}
},
t: Buffer.from([0x74]),
u: Buffer.from([0x75])
};
/*
@ -185,7 +187,6 @@ layouts.walletdb = {
* c[hash][index] -> coin
* d[hash][index] -> undo coin
* s[hash][index] -> spent by hash
* o[hash][index] -> orphan inputs
* p[hash] -> dummy (pending flag)
* m[time][hash] -> dummy (tx by time)
* h[height][hash] -> dummy (tx by height)

View File

@ -804,6 +804,136 @@ class WalletDB extends EventEmitter {
this.saveAccount(b, account);
}
/**
* Remove a wallet.
* @param {WalletID} wid
* @returns {Promise}
*/
async remove(id) {
const wid = await this.getWID(id);
if (!wid)
return false;
const unlock1 = await this.readLock.lock(wid);
const unlock2 = await this.txLock.lock();
try {
return await this._remove(wid);
} finally {
unlock2();
unlock1();
}
}
/**
* Remove a wallet (without a lock).
* @private
* @param {WalletID} wid
* @returns {Promise}
*/
async _remove(wid) {
const data = await this.db.get(layout.w(wid));
if (!data)
return false;
const {id} = Wallet.fromRaw(this, data);
const b = this.db.batch();
b.del(layout.w(wid));
b.del(layout.l(id));
const pathIter = this.db.iterator({
gte: layout.P(wid, encoding.NULL_HASH),
lte: layout.P(wid, encoding.HIGH_HASH),
keys: true
});
await pathIter.each(async (key, value) => {
const hash = layout.Pp(key);
b.del(key);
return this.removePathMap(b, hash, wid);
});
const removeRange = async (opt) => {
return this.db.iterator(opt).each(key => b.del(key));
};
await removeRange({
gte: layout.r(wid, 0x00000000, encoding.NULL_HASH),
lte: layout.r(wid, 0xffffffff, encoding.HIGH_HASH)
});
await removeRange({
gte: layout.a(wid, 0x00000000),
lte: layout.a(wid, 0xffffffff)
});
await removeRange({
gte: layout.i(wid, '\x00'),
lte: layout.i(wid, '\xff')
});
await removeRange({
gte: layout.n(wid, 0x00000000),
lte: layout.n(wid, 0xffffffff)
});
await removeRange({
gte: layout.t,
lt: layout.u
});
const tlayout = layouts.txdb;
const prefix = tlayout.prefix(wid);
const bucket = this.db.bucket(prefix);
const biter = bucket.iterator({
gte: tlayout.b(0x00000000),
lte: tlayout.b(0xffffffff),
keys: true
});
await biter.each(async (key, value) => {
const height = layout.bb(key);
return this.removeBlockMap(b, height, wid);
});
const siter = bucket.iterator({
gte: tlayout.s(encoding.NULL_HASH, 0x00000000),
lte: tlayout.s(encoding.HIGH_HASH, 0xffffffff),
keys: true
});
await siter.each(async (key, value) => {
const [hash, index] = layout.ss(key);
return this.removeOutpointMap(b, hash, index, wid);
});
const piter = bucket.iterator({
gte: tlayout.p(encoding.NULL_HASH),
lte: tlayout.p(encoding.HIGH_HASH),
keys: true
});
await piter.each(async (key, value) => {
const hash = layout.pp(key);
return this.removeTXMap(b, hash, wid);
});
const w = await this._get(wid);
await w.destroy();
this.unregister(w);
await b.write();
return true;
}
/**
* Get a wallet with token auth first.
* @param {WalletID} wid