walletdb: better mapping.

This commit is contained in:
Christopher Jeffrey 2016-10-18 06:38:41 -07:00
parent aa0f73b27d
commit da6a575469
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 122 additions and 22 deletions

View File

@ -11,28 +11,28 @@ var pad32 = utils.pad32;
var layout = exports;
layout.walletdb = {
p: function(hash) {
p: function p(hash) {
return 'p' + hash;
},
pp: function(key) {
pp: function pp(key) {
return key.slice(1);
},
P: function(wid, hash) {
P: function P(wid, hash) {
return 'p' + pad32(wid) + hash;
},
Pp: function(key) {
Pp: function Pp(key) {
return key.slice(11);
},
w: function(wid) {
w: function w(wid) {
return 'w' + pad32(wid);
},
ww: function(key) {
ww: function ww(key) {
return +key.slice(1);
},
l: function(id) {
l: function l(id) {
return 'l' + id;
},
ll: function(key) {
ll: function ll(key) {
return key.slice(1);
},
a: function a(wid, index) {
@ -50,6 +50,9 @@ layout.walletdb = {
},
e: function e(hash) {
return 'e' + hash;
},
ee: function ee(key) {
return key.slice(1);
}
};
@ -120,6 +123,12 @@ layout.txdb = {
ss: function ss(key) {
return this.hii(key);
},
S: function S(hash, index) {
return this.hi('S', hash, index);
},
Ss: function Ss(key) {
return this.hii(key);
},
p: function p(hash) {
return this.ha('p', hash);
},

View File

@ -42,35 +42,35 @@ var TXDB = require('./txdb');
*/
var layout = {
p: function(hash) {
p: function p(hash) {
var key = new Buffer(1 + (hash.length / 2));
key[0] = 0x70;
key.write(hash, 1, 'hex');
return key;
},
pp: function(key) {
pp: function pp(key) {
return key.toString('hex', 1);
},
P: function(wid, hash) {
P: function P(wid, hash) {
var key = new Buffer(1 + 4 + (hash.length / 2));
key[0] = 0x50;
key.writeUInt32BE(wid, 1, true);
key.write(hash, 5, 'hex');
return key;
},
Pp: function(key) {
Pp: function Pp(key) {
return key.toString('hex', 5);
},
w: function(wid) {
w: function w(wid) {
var key = new Buffer(5);
key[0] = 0x77;
key.writeUInt32BE(wid, 1, true);
return key;
},
ww: function(key) {
ww: function ww(key) {
return key.readUInt32BE(1, true);
},
l: function(id) {
l: function l(id) {
var len = Buffer.byteLength(id, 'ascii');
var key = new Buffer(1 + len);
key[0] = 0x6c;
@ -78,7 +78,7 @@ var layout = {
key.write(id, 1, 'ascii');
return key;
},
ll: function(key) {
ll: function ll(key) {
return key.toString('ascii', 1);
},
a: function a(wid, index) {
@ -112,7 +112,10 @@ var layout = {
key[0] = 0x65;
key.write(hash, 1, 'hex');
return key;
}
},
ee: function ee(key) {
return key.toString('hex', 1);
},
};
if (utils.isBrowser)
@ -370,6 +373,21 @@ WalletDB.prototype.loadFilter = co(function* loadFilter() {
hash = layout.pp(item.key);
this.filter.add(hash, 'hex');
}
iter = this.db.iterator({
gte: layout.e(constants.NULL_HASH),
lte: layout.e(constants.HIGH_HASH)
});
for (;;) {
item = yield iter.next();
if (!item)
break;
hash = layout.ee(item.key);
this.filter.add(hash, 'hex');
}
});
/**
@ -1183,8 +1201,9 @@ WalletDB.prototype.resend = co(function* resend() {
* @returns {Promise}
*/
WalletDB.prototype.getWalletsByHashes = co(function* getWalletsByHashes(hashes) {
WalletDB.prototype.getWalletsByHashes = co(function* getWalletsByHashes(tx) {
var result = [];
var hashes = tx.getHashes('hex');
var i, j, hash, wids;
for (i = 0; i < hashes.length; i++) {
@ -1208,6 +1227,53 @@ WalletDB.prototype.getWalletsByHashes = co(function* getWalletsByHashes(hashes)
return result;
});
/**
* Get all wallet ids by multiple address hashes.
* @param {Hash[]} hashes
* @returns {Promise}
*/
WalletDB.prototype.getWalletsByInsert = co(function* getWalletsByInsert(tx) {
var result = [];
var hashes = tx.getOutputHashes('hex');
var i, j, input, hash, wids;
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
if (!this.testFilter(input.prevout.hash))
continue;
wids = yield this.getWalletsByTX(input.prevout.hash);
if (!wids)
continue;
for (j = 0; j < wids.length; j++)
utils.binaryInsert(result, wids[j], cmp, true);
}
for (i = 0; i < hashes.length; i++) {
hash = hashes[i];
if (!this.testFilter(hash))
continue;
wids = yield this.getWalletsByHash(hash);
if (!wids)
continue;
for (j = 0; j < wids.length; j++)
utils.binaryInsert(result, wids[j], cmp, true);
}
if (result.length === 0)
return;
return result;
});
/**
* Write the genesis block as the best hash.
* @returns {Promise}
@ -1371,12 +1437,15 @@ WalletDB.prototype._addBlock = co(function* addBlock(entry, txs) {
for (i = 0; i < txs.length; i++) {
tx = txs[i];
wallets = yield this._addTX(tx);
wallets = yield this._insertTX(tx);
if (!wallets)
continue;
hash = tx.hash('hex');
this.filter.add(hash, 'hex');
block.hashes.push(hash);
matches.push(wallets);
}
@ -1469,12 +1538,34 @@ WalletDB.prototype.addTX = co(function* addTX(tx) {
*/
WalletDB.prototype._addTX = co(function* addTX(tx) {
var i, hashes, wallets, wid, wallet;
var wallets = yield this._insertTX(tx);
var hash;
if (!wallets)
return;
hash = tx.hash('hex');
yield this.db.put(layout.e(hash), serializeWallets(wallets));
this.filter.add(hash, 'hex');
return wallets;
});
/**
* Add a transaction to the database without a lock.
* @private
* @param {TX} tx
* @returns {Promise}
*/
WalletDB.prototype._insertTX = co(function* insertTX(tx) {
var i, wallets, wid, wallet;
assert(!tx.mutable, 'Cannot add mutable TX to wallet.');
hashes = tx.getHashes('hex');
wallets = yield this.getWalletsByHashes(hashes);
wallets = yield this.getWalletsByInsert(tx);
if (!wallets)
return;