wallet: add removing wallet functionality.
This commit is contained in:
parent
d896e221c0
commit
9dc6ebd8cf
@ -88,7 +88,9 @@ layouts.walletdb = {
|
|||||||
},
|
},
|
||||||
Tt: function Tt(key) {
|
Tt: function Tt(key) {
|
||||||
return [key.slice(1, 65)];
|
return [key.slice(1, 65)];
|
||||||
}
|
},
|
||||||
|
t: 't',
|
||||||
|
u: 'u'
|
||||||
};
|
};
|
||||||
|
|
||||||
layouts.txdb = {
|
layouts.txdb = {
|
||||||
|
|||||||
@ -176,7 +176,9 @@ layouts.walletdb = {
|
|||||||
assert(Buffer.isBuffer(key));
|
assert(Buffer.isBuffer(key));
|
||||||
assert(key.length === 33);
|
assert(key.length === 33);
|
||||||
return key.toString('hex', 1, 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
|
* c[hash][index] -> coin
|
||||||
* d[hash][index] -> undo coin
|
* d[hash][index] -> undo coin
|
||||||
* s[hash][index] -> spent by hash
|
* s[hash][index] -> spent by hash
|
||||||
* o[hash][index] -> orphan inputs
|
|
||||||
* p[hash] -> dummy (pending flag)
|
* p[hash] -> dummy (pending flag)
|
||||||
* m[time][hash] -> dummy (tx by time)
|
* m[time][hash] -> dummy (tx by time)
|
||||||
* h[height][hash] -> dummy (tx by height)
|
* h[height][hash] -> dummy (tx by height)
|
||||||
|
|||||||
@ -804,6 +804,136 @@ class WalletDB extends EventEmitter {
|
|||||||
this.saveAccount(b, account);
|
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.
|
* Get a wallet with token auth first.
|
||||||
* @param {WalletID} wid
|
* @param {WalletID} wid
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user