blockdb cleanup.

This commit is contained in:
Christopher Jeffrey 2016-02-15 01:49:06 -08:00
parent 2a20e56f7b
commit 299126225c
3 changed files with 104 additions and 54 deletions

View File

@ -32,15 +32,21 @@ function BlockDB(options) {
options = { file: options };
if (!options.file)
options.file = process.env.HOME + '/bcoin-server-' + network.type + '.ldb';
options.file = process.env.HOME + '/bcoin-index-' + network.type + '.db';
this.options = options;
this.parser = new bcoin.protocol.parser();
this.data = new BlockData();
this.index = levelup(options.file, {
keyEncoding: 'ascii',
valueEncoding: 'binary',
cacheSize: 16 * 1024 * 1024
cacheSize: 16 * 1024 * 1024,
db: bcoin.isBrowser
? require('memdown')
: require('level' + 'down')
});
}
@ -83,22 +89,28 @@ BlockDB.prototype.saveBlock = function saveBlock(block, callback) {
var batch = this.index.batch();
this.data.saveAsync(block._raw, function(err, data) {
var batch, blockOffset;
if (err)
return callback(err);
var blockOffset = self.createOffset(data.size, data.offset, block.height);
batch = self.index.batch();
blockOffset = self.createOffset(data.size, data.offset, block.height);
var batch = self.index.batch();
batch.put('b/b/' + block.hash('hex'), blockOffset);
batch.put('b/h/' + block.height, blockOffset);
block.txs.forEach(function(tx, i) {
var txOffset = self.createOffset(
tx._size, data.offset + tx._offset,
block.height);
var hash = tx.hash('hex');
var uniq = {};
var txOffset;
txOffset = self.createOffset(
tx._size,
data.offset + tx._offset,
block.height
);
batch.put('t/t/' + hash, txOffset);
@ -122,8 +134,12 @@ BlockDB.prototype.saveBlock = function saveBlock(block, callback) {
if (uaddr)
batch.put('t/a/' + uaddr + '/' + hash, txOffset);
if (address)
batch.del('u/a/' + address + '/' + input.prevout.hash + '/' + input.prevout.index);
if (address) {
batch.del(
'u/a/' + address
+ '/' + input.prevout.hash
+ '/' + input.prevout.index);
}
batch.del('u/t/' + input.prevout.hash + '/' + input.prevout.index);
});
@ -131,7 +147,7 @@ BlockDB.prototype.saveBlock = function saveBlock(block, callback) {
tx.outputs.forEach(function(output) {
var type = output.getType();
var address = output.getAddress();
var uaddr;
var uaddr, coinOffset;
if (type === 'pubkey' || type === 'multisig')
address = null;
@ -145,10 +161,11 @@ BlockDB.prototype.saveBlock = function saveBlock(block, callback) {
uaddr = null;
}
var coinOffset = self.createOffset(
coinOffset = self.createOffset(
output._size,
data.offset + tx._offset + output._offset,
block.height);
block.height
);
if (uaddr)
batch.put('t/a/' + uaddr + '/' + hash, txOffset);
@ -207,7 +224,7 @@ BlockDB.prototype.removeBlock = function removeBlock(hash, callback) {
tx.inputs.forEach(function(input) {
var type = input.getType();
var address = input.getAddress();
var uaddr;
var uaddr, coinOffset;
if (type === 'pubkey' || type === 'multisig')
address = null;
@ -224,15 +241,23 @@ BlockDB.prototype.removeBlock = function removeBlock(hash, callback) {
if (uaddr)
batch.del('t/a/' + uaddr + '/' + hash);
var coinOffset = self.createOffset(
coinOffset = self.createOffset(
input.output._size,
block._fileOffset + tx._offset + input.output._offset,
block.height);
block.height
);
if (address)
batch.put('u/a/' + address + '/' + input.output.hash + '/' + input.output.index, coinOffset);
if (address) {
batch.put('u/a/' + address
+ '/' + input.output.hash
+ '/' + input.output.index,
coinOffset);
}
batch.put('u/t/' + input.output.hash + '/' + input.output.index, coinOffset);
batch.put('u/t/'
+ input.output.hash
+ '/' + input.output.index,
coinOffset);
});
tx.outputs.forEach(function(output) {
@ -272,6 +297,11 @@ BlockDB.prototype.fillTX = function fillTX(tx, callback) {
var self = this;
var pending = tx.inputs.length;
callback = utils.asyncify(callback);
if (!pending)
return callback();
tx.inputs.forEach(function(input) {
if (input.output) {
if (!--pending)
@ -295,6 +325,11 @@ BlockDB.prototype.fillTX2 = function fillTX2(tx, callback) {
var self = this;
var pending = tx.inputs.length;
callback = utils.asyncify(callback);
if (!pending)
return callback();
tx.inputs.forEach(function(input) {
if (input.output) {
if (!--pending)
@ -324,7 +359,7 @@ BlockDB.prototype.getCoinsByAddress = function getCoinsByAddress(addresses, call
addresses = utils.uniqs(addresses);
var pending = addresses.length;
pending = addresses.length;
addresses.forEach(function(address) {
self._getCoinsByAddress(address, function(err, coin) {
@ -345,10 +380,11 @@ BlockDB.prototype._getCoinsByAddress = function _getCoinsByAddress(address, call
var pending = 0;
var coins = [];
var done = false;
var stream;
callback = utils.asyncify(callback);
var stream = this.index.createReadStream({
stream = this.index.createReadStream({
start: 'u/a/' + address,
end: 'u/a/' + address + '~'
});
@ -366,7 +402,11 @@ BlockDB.prototype._getCoinsByAddress = function _getCoinsByAddress(address, call
return callback(err);
if (data) {
data = self.parser.parseTXOut(data);
try {
data = self.parser.parseTXOut(data);
} catch (e) {
return callback(e);
}
coin = bcoin.coin({
version: 1,
hash: hash,
@ -403,7 +443,7 @@ BlockDB.prototype.getCoin = function getCoin(hash, index, callback) {
var self = this;
var id = 'u/t/' + hash + '/' + index;
this.index.get(id, { valueEncoding: 'binary' }, function(err, record) {
this.index.get(id, function(err, record) {
if (err) {
if (err.type === 'NotFoundError')
return callback();
@ -419,7 +459,11 @@ BlockDB.prototype.getCoin = function getCoin(hash, index, callback) {
return callback(err);
if (data) {
data = self.parser.parseTXOut(data);
try {
data = self.parser.parseTXOut(data);
} catch (e) {
return callback(e);
}
coin = bcoin.coin({
version: 1,
hash: hash,
@ -493,8 +537,13 @@ BlockDB.prototype._getTXByAddress = function _getTXByAddress(address, callback)
return callback(err);
if (data) {
tx = bcoin.tx.fromRaw(data);
entry = bcoin.chain.global.db.get(record.height);
try {
tx = bcoin.tx.fromRaw(data);
entry = bcoin.chain.global.db.get(record.height);
assert(entry);
} catch (e) {
return callback(e);
}
tx.height = record.height;
tx.ts = entry.ts;
tx.block = entry.hash;
@ -525,7 +574,7 @@ BlockDB.prototype.getTX = function getTX(hash, callback) {
var self = this;
var id = 't/t/' + hash;
this.index.get(id, { valueEncoding: 'binary' }, function(err, record) {
this.index.get(id, function(err, record) {
if (err) {
if (err.type === 'NotFoundError')
return callback();
@ -541,8 +590,13 @@ BlockDB.prototype.getTX = function getTX(hash, callback) {
return callback(err);
if (data) {
tx = bcoin.tx.fromRaw(data);
entry = bcoin.chain.global.db.get(record.height);
try {
tx = bcoin.tx.fromRaw(data);
entry = bcoin.chain.global.db.get(record.height);
assert(entry);
} catch (e) {
return callback(e);
}
tx.height = record.height;
tx.ts = entry.ts;
tx.block = entry.hash;
@ -560,7 +614,7 @@ BlockDB.prototype.getBlock = function getBlock(hash, callback) {
if (typeof hash === 'number')
id = 'b/h/' + value;
this.index.get(id, { valueEncoding: 'binary' }, function(err, record) {
this.index.get(id, function(err, record) {
if (err) {
if (err.type === 'NotFoundError')
return callback();
@ -576,7 +630,11 @@ BlockDB.prototype.getBlock = function getBlock(hash, callback) {
return callback(err);
if (data) {
block = bcoin.block.fromRaw(data);
try {
block = bcoin.block.fromRaw(data);
} catch (e) {
return callback(e);
}
block._fileOffset = record.offset;
block.height = record.height;
}
@ -590,19 +648,18 @@ BlockDB.prototype.getBlock = function getBlock(hash, callback) {
* BlockData
*/
function BlockData(chain, options) {
function BlockData(options) {
if (!(this instanceof BlockData))
return new BlockData(chain, options);
return new BlockData(options);
if (!options)
options = {};
this.options = options;
this.chain = chain;
this.file = options.file;
if (!this.file)
this.file = process.env.HOME + '/bcoin-' + network.type + '.data';
this.file = process.env.HOME + '/bcoin-data-' + network.type + '.db';
this._queue = [];
this._cache = {};
@ -628,10 +685,8 @@ BlockData.prototype._init = function _init() {
}
}
if (!this.exists()) {
fs.writeFileSync(this.file, new Buffer(0));
fs.truncateSync(this.file, 0);
}
if (!this.exists())
fs.writeFileSync(this.file, new Buffer([]));
this.size = this.getSize();
@ -757,9 +812,8 @@ BlockData.prototype.saveAsync = function saveAsync(data, callback) {
});
};
BlockData.prototype.truncate = function truncate(height) {
this.size = (height + 1) * BLOCK_SIZE;
this.tip = height;
BlockData.prototype.truncate = function truncate(size) {
this.size = size;
if (!bcoin.fs) {
this.ramdisk.truncate(this.size);

View File

@ -33,7 +33,7 @@ function ChainDB(chain, options) {
this.file = options.file;
if (!this.file)
this.file = process.env.HOME + '/bcoin-' + network.type + '.blockchain';
this.file = process.env.HOME + '/bcoin-chain-' + network.type + '.db';
this._queue = [];
this._cache = {};
@ -70,10 +70,8 @@ ChainDB.prototype._init = function _init() {
}
}
if (!this.exists()) {
fs.writeFileSync(this.file, new Buffer(0));
fs.truncateSync(this.file, 0);
}
if (!this.exists())
fs.writeFileSync(this.file, new Buffer([]));
this.size = this.getSize();

View File

@ -148,7 +148,7 @@ TX.prototype.input = TX.prototype.addInput;
// tx._addInput({ hash: hash, index: index })
// tx._addInput({ tx: tx, index: index })
TX.prototype._addInput = function _addInput(options, index) {
var coin, input, ex, i, prevout;
var coin, input, ex, i, prevout, isInput;
if (options instanceof TX) {
options = { tx: options, index: index };
@ -162,7 +162,6 @@ TX.prototype._addInput = function _addInput(options, index) {
if (options.seq != null)
options.sequence = options.seq;
var isInput;
if (!options.prevout) {
if (options instanceof bcoin.coin) {
options = {
@ -780,8 +779,7 @@ TX.prototype.scriptOutput = function scriptOutput(index, options) {
script = [
bcoin.script.array(options.locktime),
'checklocktimeverify',
'drop',
'codeseparator'
'drop'
].concat(script);
}
hash = utils.ripesha(bcoin.script.encode(script));
@ -808,6 +806,9 @@ TX.prototype.signatureHash = function signatureHash(index, s, type) {
var copy = this.clone();
var i, msg, hash;
if (typeof index !== 'number')
index = this.inputs.indexOf(index);
if (!Array.isArray(s)) {
type = s;
s = this.inputs[index].output.script;
@ -815,9 +816,6 @@ TX.prototype.signatureHash = function signatureHash(index, s, type) {
s = bcoin.script.getRedeem(this.inputs[index].script);
}
if (typeof index !== 'number')
index = this.inputs.indexOf(index);
if (typeof type === 'string')
type = constants.hashType[type];