walletdb: use buffer keys.

This commit is contained in:
Christopher Jeffrey 2016-08-15 11:05:09 -07:00
parent 16204a4794
commit b77c0995ba
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
5 changed files with 244 additions and 14 deletions

View File

@ -34,6 +34,75 @@ var BufferReader = require('./reader');
* q[height] -> block hash to be pruned
*/
/* String keys
var layout = {
R: 'R',
e: function e(hash) {
return 'e' + hash;
},
h: function h(hash) {
return 'h' + hash;
},
H: function H(height) {
return 'H' + pad32(height);
},
n: function n(hash) {
return 'n' + hash;
},
b: function b(hash) {
return 'b' + hash;
},
t: function t(hash) {
return 't' + hash;
},
c: function c(hash) {
return 'c' + hash;
},
u: function u(hash) {
return 'u' + hash;
},
q: function q(height) {
return 'q' + pad32(height);
},
T: function T(address, hash) {
var len = address.length;
var key;
if (address.length === 64)
return 'W' + address + hash;
return 'T' + address + hash;
},
C: function C(address, hash, index) {
var len = address.length;
var key;
if (address.length === 64)
return 'X' + address + hash + pad32(index);
return 'C' + address + hash + pad32(index);
},
Cc: function Cc(key) {
var hash, index;
if (key.length === 139) {
hash = key.slice(65, 129);
index = +key.slice(129);
} else {
hash = key.slice(41, 105).toString('hex');
index = +key.slice(105);
}
return [hash, index];
},
Tt: function Tt(key) {
return key.length === 129
? key.slice(64)
: key.slice(41);
}
};
*/
var layout = {
R: new Buffer([0x52]),
e: function e(hash) {
@ -96,12 +165,16 @@ var layout = {
key[0] = 0x9a; // W + C
write(key, address, 1);
write(key, hash, 33);
// TODO: Change this to big
// endian for saner sorting.
key.writeUInt32LE(index, 65, true);
} else {
key = new Buffer(57);
key[0] = 0x43; // C
write(key, address, 1);
write(key, hash, 21);
// TODO: Change this to big
// endian for saner sorting.
key.writeUInt32LE(index, 53, true);
}
@ -1253,7 +1326,6 @@ ChainDB.prototype.getCoinsByAddress = function getCoinsByAddress(addresses, call
self.db.iterate({
gte: layout.C(address, constants.ZERO_HASH, 0),
lte: layout.C(address, constants.MAX_HASH, 0xffffffff),
keyAsBuffer: true,
transform: layout.Cc
}, function(err, keys) {
if (err)
@ -1289,7 +1361,6 @@ ChainDB.prototype.getEntries = function getEntries(callback) {
gte: layout.e(constants.ZERO_HASH),
lte: layout.e(constants.MAX_HASH),
values: true,
keyAsBuffer: true,
parse: function(data) {
return bcoin.chainentry.fromRaw(self.chain, data);
}
@ -1319,7 +1390,6 @@ ChainDB.prototype.getTXByAddress = function getTXByAddress(addresses, callback)
self.db.lookup({
gte: layout.T(address, constants.ZERO_HASH),
lte: layout.T(address, constants.MAX_HASH),
keyAsBuffer: true,
transform: function(key) {
var hash = layout.Tt(key);
@ -1583,6 +1653,8 @@ function pair(prefix, hash) {
function ipair(prefix, num) {
var key = new Buffer(5);
key[0] = prefix;
// TODO: Change this to big
// endian for saner sorting.
key.writeUInt32LE(num, 1, true);
return key;
}

View File

@ -37,6 +37,7 @@ function LowlevelUp(file, options) {
this.options = options;
this.backend = options.db;
this.location = file;
this.bufferKeys = options.bufferKeys === true;
this.db = new options.db(file);
@ -268,7 +269,7 @@ LowlevelUp.prototype.each = function each(options, handler, callback) {
keys: true,
values: options.values || false,
fillCache: options.fillCache || false,
keyAsBuffer: options.keyAsBuffer || false,
keyAsBuffer: options.keyAsBuffer || this.bufferKeys,
valueAsBuffer: true,
reverse: options.reverse || false
};
@ -328,7 +329,7 @@ LowlevelUp.prototype.iterate = function iterate(options, callback) {
keys: true,
values: options.values || false,
fillCache: options.fillCache || false,
keyAsBuffer: options.keyAsBuffer || false,
keyAsBuffer: options.keyAsBuffer || this.bufferKeys,
valueAsBuffer: true,
reverse: options.reverse || false
};

View File

@ -37,6 +37,7 @@ function Layout(wallet) {
this.wallet = wallet;
}
/* String Keys
Layout.prototype.prefix = function prefix(key) {
assert(this.wallet.wid);
return 't' + pad32(this.wallet.wid) + key;
@ -86,8 +87,92 @@ Layout.prototype.haa = function haa(key) {
key = key.slice(12);
return key;
};
*/
Layout.prototype.prefix = function prefix(key) {
var out = new Buffer(5 + key.length);
assert(this.wallet.wid);
out[0] = 0x74;
out.writeUInt32BE(this.wallet.wid, 1);
key.copy(out, 5);
return out;
};
Layout.prototype.hi = function hi(ch, hash, index) {
var key = new Buffer(37);
key[0] = ch.charCodeAt(0);
key.write(hash, 1, 'hex');
key.writeUInt32BE(index, 33, true);
return this.prefix(key);
};
Layout.prototype.hii = function hii(key) {
key = key.slice(6);
return [key.toString('hex', 0, 32), key.readUInt32BE(32, true)];
};
Layout.prototype.ih = function ih(ch, index, hash) {
var key = new Buffer(37);
key[0] = ch.charCodeAt(0);
key.writeUInt32BE(index, 1, true);
key.write(hash, 5, 'hex');
return this.prefix(key);
};
Layout.prototype.ihh = function ihh(key) {
key = key.slice(6);
return [key.readUInt32BE(0, true), key.toString('hex', 4, 36)];
};
Layout.prototype.iih = function iih(ch, index, num, hash) {
var key = new Buffer(41);
key[0] = ch.charCodeAt(0);
key.writeUInt32BE(index, 1, true);
key.writeUInt32BE(num, 5, true);
key.write(hash, 9, 'hex');
return this.prefix(key);
};
Layout.prototype.iihh = function iihh(key) {
key = key.slice(6);
return [
key.readUInt32BE(0, true),
key.readUInt32BE(4, true),
key.toString('hex', 8, 40)
];
};
Layout.prototype.ihi = function ihi(ch, index, hash, num) {
var key = new Buffer(41);
key[0] = ch.charCodeAt(0);
key.writeUInt32BE(index, 1, true);
key.write(hash, 5, 'hex');
key.writeUInt32BE(num, 37, true);
return this.prefix(key);
};
Layout.prototype.ihii = function ihii(key) {
key = key.slice(6);
return [
key.readUInt32BE(0, true),
key.toString('hex', 4, 36),
key.readUInt32BE(36, true)
];
};
Layout.prototype.ha = function ha(ch, hash) {
var key = new Buffer(33);
key[0] = ch.charCodeAt(0);
key.write(hash, 1, 'hex');
return this.prefix(key);
};
Layout.prototype.haa = function haa(key) {
return key.toString('hex', 1);
};
Layout.prototype.t = function t(hash) {
// 0x74
return this.ha('t', hash);
};
@ -96,6 +181,7 @@ Layout.prototype.tt = function tt(key) {
};
Layout.prototype.c = function c(hash, index) {
// 0x63
return this.hi('c', hash, index);
};
@ -104,6 +190,7 @@ Layout.prototype.cc = function cc(key) {
};
Layout.prototype.d = function d(hash, index) {
// 0x64
return this.hi('d', hash, index);
};
@ -112,6 +199,7 @@ Layout.prototype.dd = function dd(key) {
};
Layout.prototype.s = function s(hash, index) {
// 0x73
return this.hi('s', hash, index);
};
@ -120,6 +208,7 @@ Layout.prototype.ss = function ss(key) {
};
Layout.prototype.o = function o(hash, index) {
// 0x6f
return this.hi('o', hash, index);
};
@ -128,6 +217,7 @@ Layout.prototype.oo = function oo(key) {
};
Layout.prototype.p = function p(hash) {
// 0x70
return this.ha('p', hash);
};
@ -136,6 +226,7 @@ Layout.prototype.pp = function pp(key) {
};
Layout.prototype.m = function m(time, hash) {
// 0x6d
return this.ih('m', time, hash);
};
@ -144,6 +235,7 @@ Layout.prototype.mm = function mm(key) {
};
Layout.prototype.h = function h(height, hash) {
// 0x68
return this.ih('h', height, hash);
};
@ -152,6 +244,7 @@ Layout.prototype.hh = function hh(key) {
};
Layout.prototype.T = function T(account, hash) {
// 0x54
return this.ih('T', account, hash);
};
@ -160,6 +253,7 @@ Layout.prototype.Tt = function Tt(key) {
};
Layout.prototype.P = function P(account, hash) {
// 0x50
return this.ih('P', account, hash);
};
@ -168,6 +262,7 @@ Layout.prototype.Pp = function Pp(key) {
};
Layout.prototype.M = function M(account, time, hash) {
// 0x4d
return this.iih('M', account, time, hash);
};
@ -176,6 +271,7 @@ Layout.prototype.Mm = function Mm(key) {
};
Layout.prototype.H = function H(account, height, hash) {
// 0x48
return this.iih('H', account, height, hash);
};
@ -184,6 +280,7 @@ Layout.prototype.Hh = function Hh(key) {
};
Layout.prototype.C = function C(account, hash, index) {
// 0x43
return this.ihi('C', account, hash, index);
};

View File

@ -2410,10 +2410,9 @@ utils._paths = {};
utils.isAlpha = function isAlpha(key) {
if (typeof key !== 'string')
return false;
// We allow /-~ (exclusive), 0-} (inclusive)
return key.length >= 1
&& key.length <= 40
&& /^[\u0030-\u007d]+$/.test(key);
&& /^[\u0020-\u007e]+$/.test(key);
};
/**

View File

@ -31,6 +31,7 @@ var BufferWriter = require('./writer');
var TXDB = require('./txdb');
var keyTypes = bcoin.keyring.types;
/* String Keys
var layout = {
p: function(hash) {
return 'p' + hash;
@ -67,6 +68,68 @@ var layout = {
return 'e' + hash;
}
};
*/
var layout = {
p: function(hash) {
var key = new Buffer(1 + (hash.length / 2));
key[0] = 0x70;
key.write(hash, 1, 'hex');
return key;
},
pp: function(key) {
return key.toString('hex', 1);
},
w: function(wid) {
var key = new Buffer(5);
key[0] = 0x77;
key.writeUInt32BE(wid, 1, true);
return key;
},
ww: function(key) {
return key.readUInt32BE(1, true);
},
l: function(id) {
var key = new Buffer(1 + id.length);
key[0] = 0x6c;
key.write(id, 1, 'ascii');
return key;
},
ll: function(key) {
return key.toString('ascii', 1);
},
a: function a(wid, index) {
var key = new Buffer(9);
key[0] = 0x61;
key.writeUInt32BE(wid, 1, true);
key.writeUInt32BE(index, 5, true);
return key;
},
i: function i(wid, name) {
var key = new Buffer(5 + name.length);
key[0] = 0x69;
key.writeUInt32BE(wid, 1, true);
key.write(name, 5, 'ascii');
return key;
},
ii: function ii(key) {
return [+key.readUInt32BE(1, true), key.toString('ascii', 5)];
},
R: 'R',
b: function b(hash) {
var key = new Buffer(33);
key[0] = 0x62;
key.write(hash, 1, 'hex');
return key;
},
e: function e(hash) {
var key = new Buffer(33);
key[0] = 0x65;
key.write(hash, 1, 'hex');
return key;
}
};
/**
* WalletDB
@ -126,7 +189,8 @@ function WalletDB(options) {
location: this.options.location,
db: this.options.db,
cacheSize: 8 << 20,
writeBufferSize: 4 << 20
writeBufferSize: 4 << 20,
bufferKeys: true
});
if (bcoin.useWorkers)
@ -235,10 +299,7 @@ WalletDB.prototype.getDepth = function getDepth(callback) {
lte: layout.w(0xffffffff),
reverse: true,
keys: true,
values: false,
fillCache: false,
keyAsBuffer: false,
valueAsBuffer: true
fillCache: false
});
iter.next(function(err, key, value) {
@ -701,7 +762,7 @@ WalletDB.prototype.getAccounts = function getAccounts(wid, callback) {
this.db.iterate({
gte: layout.i(wid, ''),
lte: layout.i(wid, '~'),
lte: layout.i(wid, '\xff'),
values: true,
parse: function(value, key) {
var name = layout.ii(key)[1];
@ -983,7 +1044,7 @@ WalletDB.prototype.getAddresses = function getAddresses(wid, callback) {
WalletDB.prototype.getWallets = function getWallets(callback) {
this.db.iterate({
gte: layout.l(''),
lte: layout.l('~'),
lte: layout.l('\xff'),
transform: function(key) {
return layout.ll(key);
}