blockdb cleanup.
This commit is contained in:
parent
2a20e56f7b
commit
299126225c
@ -32,15 +32,21 @@ function BlockDB(options) {
|
|||||||
options = { file: options };
|
options = { file: options };
|
||||||
|
|
||||||
if (!options.file)
|
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.options = options;
|
||||||
|
|
||||||
this.parser = new bcoin.protocol.parser();
|
this.parser = new bcoin.protocol.parser();
|
||||||
|
|
||||||
this.data = new BlockData();
|
this.data = new BlockData();
|
||||||
|
|
||||||
this.index = levelup(options.file, {
|
this.index = levelup(options.file, {
|
||||||
keyEncoding: 'ascii',
|
keyEncoding: 'ascii',
|
||||||
valueEncoding: 'binary',
|
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();
|
var batch = this.index.batch();
|
||||||
|
|
||||||
this.data.saveAsync(block._raw, function(err, data) {
|
this.data.saveAsync(block._raw, function(err, data) {
|
||||||
|
var batch, blockOffset;
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
return callback(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/b/' + block.hash('hex'), blockOffset);
|
||||||
batch.put('b/h/' + block.height, blockOffset);
|
batch.put('b/h/' + block.height, blockOffset);
|
||||||
|
|
||||||
block.txs.forEach(function(tx, i) {
|
block.txs.forEach(function(tx, i) {
|
||||||
var txOffset = self.createOffset(
|
|
||||||
tx._size, data.offset + tx._offset,
|
|
||||||
block.height);
|
|
||||||
|
|
||||||
var hash = tx.hash('hex');
|
var hash = tx.hash('hex');
|
||||||
var uniq = {};
|
var uniq = {};
|
||||||
|
var txOffset;
|
||||||
|
|
||||||
|
txOffset = self.createOffset(
|
||||||
|
tx._size,
|
||||||
|
data.offset + tx._offset,
|
||||||
|
block.height
|
||||||
|
);
|
||||||
|
|
||||||
batch.put('t/t/' + hash, txOffset);
|
batch.put('t/t/' + hash, txOffset);
|
||||||
|
|
||||||
@ -122,8 +134,12 @@ BlockDB.prototype.saveBlock = function saveBlock(block, callback) {
|
|||||||
if (uaddr)
|
if (uaddr)
|
||||||
batch.put('t/a/' + uaddr + '/' + hash, txOffset);
|
batch.put('t/a/' + uaddr + '/' + hash, txOffset);
|
||||||
|
|
||||||
if (address)
|
if (address) {
|
||||||
batch.del('u/a/' + address + '/' + input.prevout.hash + '/' + input.prevout.index);
|
batch.del(
|
||||||
|
'u/a/' + address
|
||||||
|
+ '/' + input.prevout.hash
|
||||||
|
+ '/' + input.prevout.index);
|
||||||
|
}
|
||||||
|
|
||||||
batch.del('u/t/' + 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) {
|
tx.outputs.forEach(function(output) {
|
||||||
var type = output.getType();
|
var type = output.getType();
|
||||||
var address = output.getAddress();
|
var address = output.getAddress();
|
||||||
var uaddr;
|
var uaddr, coinOffset;
|
||||||
|
|
||||||
if (type === 'pubkey' || type === 'multisig')
|
if (type === 'pubkey' || type === 'multisig')
|
||||||
address = null;
|
address = null;
|
||||||
@ -145,10 +161,11 @@ BlockDB.prototype.saveBlock = function saveBlock(block, callback) {
|
|||||||
uaddr = null;
|
uaddr = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var coinOffset = self.createOffset(
|
coinOffset = self.createOffset(
|
||||||
output._size,
|
output._size,
|
||||||
data.offset + tx._offset + output._offset,
|
data.offset + tx._offset + output._offset,
|
||||||
block.height);
|
block.height
|
||||||
|
);
|
||||||
|
|
||||||
if (uaddr)
|
if (uaddr)
|
||||||
batch.put('t/a/' + uaddr + '/' + hash, txOffset);
|
batch.put('t/a/' + uaddr + '/' + hash, txOffset);
|
||||||
@ -207,7 +224,7 @@ BlockDB.prototype.removeBlock = function removeBlock(hash, callback) {
|
|||||||
tx.inputs.forEach(function(input) {
|
tx.inputs.forEach(function(input) {
|
||||||
var type = input.getType();
|
var type = input.getType();
|
||||||
var address = input.getAddress();
|
var address = input.getAddress();
|
||||||
var uaddr;
|
var uaddr, coinOffset;
|
||||||
|
|
||||||
if (type === 'pubkey' || type === 'multisig')
|
if (type === 'pubkey' || type === 'multisig')
|
||||||
address = null;
|
address = null;
|
||||||
@ -224,15 +241,23 @@ BlockDB.prototype.removeBlock = function removeBlock(hash, callback) {
|
|||||||
if (uaddr)
|
if (uaddr)
|
||||||
batch.del('t/a/' + uaddr + '/' + hash);
|
batch.del('t/a/' + uaddr + '/' + hash);
|
||||||
|
|
||||||
var coinOffset = self.createOffset(
|
coinOffset = self.createOffset(
|
||||||
input.output._size,
|
input.output._size,
|
||||||
block._fileOffset + tx._offset + input.output._offset,
|
block._fileOffset + tx._offset + input.output._offset,
|
||||||
block.height);
|
block.height
|
||||||
|
);
|
||||||
|
|
||||||
if (address)
|
if (address) {
|
||||||
batch.put('u/a/' + address + '/' + input.output.hash + '/' + input.output.index, coinOffset);
|
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) {
|
tx.outputs.forEach(function(output) {
|
||||||
@ -272,6 +297,11 @@ BlockDB.prototype.fillTX = function fillTX(tx, callback) {
|
|||||||
var self = this;
|
var self = this;
|
||||||
var pending = tx.inputs.length;
|
var pending = tx.inputs.length;
|
||||||
|
|
||||||
|
callback = utils.asyncify(callback);
|
||||||
|
|
||||||
|
if (!pending)
|
||||||
|
return callback();
|
||||||
|
|
||||||
tx.inputs.forEach(function(input) {
|
tx.inputs.forEach(function(input) {
|
||||||
if (input.output) {
|
if (input.output) {
|
||||||
if (!--pending)
|
if (!--pending)
|
||||||
@ -295,6 +325,11 @@ BlockDB.prototype.fillTX2 = function fillTX2(tx, callback) {
|
|||||||
var self = this;
|
var self = this;
|
||||||
var pending = tx.inputs.length;
|
var pending = tx.inputs.length;
|
||||||
|
|
||||||
|
callback = utils.asyncify(callback);
|
||||||
|
|
||||||
|
if (!pending)
|
||||||
|
return callback();
|
||||||
|
|
||||||
tx.inputs.forEach(function(input) {
|
tx.inputs.forEach(function(input) {
|
||||||
if (input.output) {
|
if (input.output) {
|
||||||
if (!--pending)
|
if (!--pending)
|
||||||
@ -324,7 +359,7 @@ BlockDB.prototype.getCoinsByAddress = function getCoinsByAddress(addresses, call
|
|||||||
|
|
||||||
addresses = utils.uniqs(addresses);
|
addresses = utils.uniqs(addresses);
|
||||||
|
|
||||||
var pending = addresses.length;
|
pending = addresses.length;
|
||||||
|
|
||||||
addresses.forEach(function(address) {
|
addresses.forEach(function(address) {
|
||||||
self._getCoinsByAddress(address, function(err, coin) {
|
self._getCoinsByAddress(address, function(err, coin) {
|
||||||
@ -345,10 +380,11 @@ BlockDB.prototype._getCoinsByAddress = function _getCoinsByAddress(address, call
|
|||||||
var pending = 0;
|
var pending = 0;
|
||||||
var coins = [];
|
var coins = [];
|
||||||
var done = false;
|
var done = false;
|
||||||
|
var stream;
|
||||||
|
|
||||||
callback = utils.asyncify(callback);
|
callback = utils.asyncify(callback);
|
||||||
|
|
||||||
var stream = this.index.createReadStream({
|
stream = this.index.createReadStream({
|
||||||
start: 'u/a/' + address,
|
start: 'u/a/' + address,
|
||||||
end: 'u/a/' + address + '~'
|
end: 'u/a/' + address + '~'
|
||||||
});
|
});
|
||||||
@ -366,7 +402,11 @@ BlockDB.prototype._getCoinsByAddress = function _getCoinsByAddress(address, call
|
|||||||
return callback(err);
|
return callback(err);
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
data = self.parser.parseTXOut(data);
|
try {
|
||||||
|
data = self.parser.parseTXOut(data);
|
||||||
|
} catch (e) {
|
||||||
|
return callback(e);
|
||||||
|
}
|
||||||
coin = bcoin.coin({
|
coin = bcoin.coin({
|
||||||
version: 1,
|
version: 1,
|
||||||
hash: hash,
|
hash: hash,
|
||||||
@ -403,7 +443,7 @@ BlockDB.prototype.getCoin = function getCoin(hash, index, callback) {
|
|||||||
var self = this;
|
var self = this;
|
||||||
var id = 'u/t/' + hash + '/' + index;
|
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) {
|
||||||
if (err.type === 'NotFoundError')
|
if (err.type === 'NotFoundError')
|
||||||
return callback();
|
return callback();
|
||||||
@ -419,7 +459,11 @@ BlockDB.prototype.getCoin = function getCoin(hash, index, callback) {
|
|||||||
return callback(err);
|
return callback(err);
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
data = self.parser.parseTXOut(data);
|
try {
|
||||||
|
data = self.parser.parseTXOut(data);
|
||||||
|
} catch (e) {
|
||||||
|
return callback(e);
|
||||||
|
}
|
||||||
coin = bcoin.coin({
|
coin = bcoin.coin({
|
||||||
version: 1,
|
version: 1,
|
||||||
hash: hash,
|
hash: hash,
|
||||||
@ -493,8 +537,13 @@ BlockDB.prototype._getTXByAddress = function _getTXByAddress(address, callback)
|
|||||||
return callback(err);
|
return callback(err);
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
tx = bcoin.tx.fromRaw(data);
|
try {
|
||||||
entry = bcoin.chain.global.db.get(record.height);
|
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.height = record.height;
|
||||||
tx.ts = entry.ts;
|
tx.ts = entry.ts;
|
||||||
tx.block = entry.hash;
|
tx.block = entry.hash;
|
||||||
@ -525,7 +574,7 @@ BlockDB.prototype.getTX = function getTX(hash, callback) {
|
|||||||
var self = this;
|
var self = this;
|
||||||
var id = 't/t/' + hash;
|
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) {
|
||||||
if (err.type === 'NotFoundError')
|
if (err.type === 'NotFoundError')
|
||||||
return callback();
|
return callback();
|
||||||
@ -541,8 +590,13 @@ BlockDB.prototype.getTX = function getTX(hash, callback) {
|
|||||||
return callback(err);
|
return callback(err);
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
tx = bcoin.tx.fromRaw(data);
|
try {
|
||||||
entry = bcoin.chain.global.db.get(record.height);
|
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.height = record.height;
|
||||||
tx.ts = entry.ts;
|
tx.ts = entry.ts;
|
||||||
tx.block = entry.hash;
|
tx.block = entry.hash;
|
||||||
@ -560,7 +614,7 @@ BlockDB.prototype.getBlock = function getBlock(hash, callback) {
|
|||||||
if (typeof hash === 'number')
|
if (typeof hash === 'number')
|
||||||
id = 'b/h/' + value;
|
id = 'b/h/' + value;
|
||||||
|
|
||||||
this.index.get(id, { valueEncoding: 'binary' }, function(err, record) {
|
this.index.get(id, function(err, record) {
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err.type === 'NotFoundError')
|
if (err.type === 'NotFoundError')
|
||||||
return callback();
|
return callback();
|
||||||
@ -576,7 +630,11 @@ BlockDB.prototype.getBlock = function getBlock(hash, callback) {
|
|||||||
return callback(err);
|
return callback(err);
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
block = bcoin.block.fromRaw(data);
|
try {
|
||||||
|
block = bcoin.block.fromRaw(data);
|
||||||
|
} catch (e) {
|
||||||
|
return callback(e);
|
||||||
|
}
|
||||||
block._fileOffset = record.offset;
|
block._fileOffset = record.offset;
|
||||||
block.height = record.height;
|
block.height = record.height;
|
||||||
}
|
}
|
||||||
@ -590,19 +648,18 @@ BlockDB.prototype.getBlock = function getBlock(hash, callback) {
|
|||||||
* BlockData
|
* BlockData
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function BlockData(chain, options) {
|
function BlockData(options) {
|
||||||
if (!(this instanceof BlockData))
|
if (!(this instanceof BlockData))
|
||||||
return new BlockData(chain, options);
|
return new BlockData(options);
|
||||||
|
|
||||||
if (!options)
|
if (!options)
|
||||||
options = {};
|
options = {};
|
||||||
|
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.chain = chain;
|
|
||||||
this.file = options.file;
|
this.file = options.file;
|
||||||
|
|
||||||
if (!this.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._queue = [];
|
||||||
this._cache = {};
|
this._cache = {};
|
||||||
@ -628,10 +685,8 @@ BlockData.prototype._init = function _init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.exists()) {
|
if (!this.exists())
|
||||||
fs.writeFileSync(this.file, new Buffer(0));
|
fs.writeFileSync(this.file, new Buffer([]));
|
||||||
fs.truncateSync(this.file, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.size = this.getSize();
|
this.size = this.getSize();
|
||||||
|
|
||||||
@ -757,9 +812,8 @@ BlockData.prototype.saveAsync = function saveAsync(data, callback) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockData.prototype.truncate = function truncate(height) {
|
BlockData.prototype.truncate = function truncate(size) {
|
||||||
this.size = (height + 1) * BLOCK_SIZE;
|
this.size = size;
|
||||||
this.tip = height;
|
|
||||||
|
|
||||||
if (!bcoin.fs) {
|
if (!bcoin.fs) {
|
||||||
this.ramdisk.truncate(this.size);
|
this.ramdisk.truncate(this.size);
|
||||||
|
|||||||
@ -33,7 +33,7 @@ function ChainDB(chain, options) {
|
|||||||
this.file = options.file;
|
this.file = options.file;
|
||||||
|
|
||||||
if (!this.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._queue = [];
|
||||||
this._cache = {};
|
this._cache = {};
|
||||||
@ -70,10 +70,8 @@ ChainDB.prototype._init = function _init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.exists()) {
|
if (!this.exists())
|
||||||
fs.writeFileSync(this.file, new Buffer(0));
|
fs.writeFileSync(this.file, new Buffer([]));
|
||||||
fs.truncateSync(this.file, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.size = this.getSize();
|
this.size = this.getSize();
|
||||||
|
|
||||||
|
|||||||
@ -148,7 +148,7 @@ TX.prototype.input = TX.prototype.addInput;
|
|||||||
// tx._addInput({ hash: hash, index: index })
|
// tx._addInput({ hash: hash, index: index })
|
||||||
// tx._addInput({ tx: tx, index: index })
|
// tx._addInput({ tx: tx, index: index })
|
||||||
TX.prototype._addInput = function _addInput(options, 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) {
|
if (options instanceof TX) {
|
||||||
options = { tx: options, index: index };
|
options = { tx: options, index: index };
|
||||||
@ -162,7 +162,6 @@ TX.prototype._addInput = function _addInput(options, index) {
|
|||||||
if (options.seq != null)
|
if (options.seq != null)
|
||||||
options.sequence = options.seq;
|
options.sequence = options.seq;
|
||||||
|
|
||||||
var isInput;
|
|
||||||
if (!options.prevout) {
|
if (!options.prevout) {
|
||||||
if (options instanceof bcoin.coin) {
|
if (options instanceof bcoin.coin) {
|
||||||
options = {
|
options = {
|
||||||
@ -780,8 +779,7 @@ TX.prototype.scriptOutput = function scriptOutput(index, options) {
|
|||||||
script = [
|
script = [
|
||||||
bcoin.script.array(options.locktime),
|
bcoin.script.array(options.locktime),
|
||||||
'checklocktimeverify',
|
'checklocktimeverify',
|
||||||
'drop',
|
'drop'
|
||||||
'codeseparator'
|
|
||||||
].concat(script);
|
].concat(script);
|
||||||
}
|
}
|
||||||
hash = utils.ripesha(bcoin.script.encode(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 copy = this.clone();
|
||||||
var i, msg, hash;
|
var i, msg, hash;
|
||||||
|
|
||||||
|
if (typeof index !== 'number')
|
||||||
|
index = this.inputs.indexOf(index);
|
||||||
|
|
||||||
if (!Array.isArray(s)) {
|
if (!Array.isArray(s)) {
|
||||||
type = s;
|
type = s;
|
||||||
s = this.inputs[index].output.script;
|
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);
|
s = bcoin.script.getRedeem(this.inputs[index].script);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof index !== 'number')
|
|
||||||
index = this.inputs.indexOf(index);
|
|
||||||
|
|
||||||
if (typeof type === 'string')
|
if (typeof type === 'string')
|
||||||
type = constants.hashType[type];
|
type = constants.hashType[type];
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user