chaindb: chain state buffer hash.

This commit is contained in:
Christopher Jeffrey 2016-08-17 19:58:25 -07:00
parent bf20425e11
commit 8ee0cf8604
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -290,7 +290,7 @@ ChainDB.prototype._open = function open(callback) {
self.logger.info('Chain successfully loaded.');
self.logger.info('Chain State: hash=%s tx=%d coin=%d value=%s.',
utils.revHex(self.state.hash),
self.state.rhash,
self.state.tx,
self.state.coin,
utils.btc(self.state.value)
@ -303,7 +303,7 @@ ChainDB.prototype._open = function open(callback) {
if (err)
return done(err);
self.db.has(layout.h(self.network.genesis.hash), function(err, exists) {
self.db.has(layout.e(self.network.genesis.hash), function(err, exists) {
if (err)
return done(err);
@ -394,17 +394,29 @@ ChainDB.prototype.drop = function drop() {
ChainDB.prototype.commit = function commit(callback) {
var self = this;
assert(this.current);
assert(this.pending);
this.current.write(function(err) {
if (err) {
self.current = null;
self.pending = null;
return callback(err);
}
self.current = null;
self.state = self.pending;
// Overwrite the entire state
// with our new best state
// only if it is committed.
// Note that alternate chain
// tips do not commit anything.
if (self.pending.committed)
self.state = self.pending;
self.pending = null;
callback();
});
};
@ -689,7 +701,7 @@ ChainDB.prototype.save = function save(entry, block, view, connect, callback) {
self.drop();
return callback(err);
}
self.put(layout.R, self.pending.mark(hash));
self.put(layout.R, self.pending.commit(hash));
self.commit(callback);
});
};
@ -742,22 +754,13 @@ ChainDB.prototype.reconnect = function reconnect(entry, block, view, callback) {
this.cacheHash.set(entry.hash, entry);
this.cacheHeight.set(entry.height, entry);
if (this.options.spv) {
this.put(layout.R, this.pending.mark(hash));
return this.commit(function(err) {
if (err)
return callback(err);
return callback(null, entry, block);
});
}
this.connectBlock(block, view, function(err) {
if (err) {
self.drop();
return callback(err);
}
self.put(layout.R, self.pending.mark(hash));
self.put(layout.R, self.pending.commit(hash));
self.commit(function(err) {
if (err)
return callback(err);
@ -783,7 +786,7 @@ ChainDB.prototype.disconnect = function disconnect(entry, callback) {
this.cacheHeight.remove(entry.height);
if (this.options.spv) {
this.put(layout.R, this.pending.mark(entry.prevBlock));
this.put(layout.R, this.pending.commit(entry.prevBlock));
return this.commit(function(err) {
if (err)
return callback(err);
@ -808,7 +811,7 @@ ChainDB.prototype.disconnect = function disconnect(entry, callback) {
return callback(err);
}
self.put(layout.R, self.pending.mark(entry.prevBlock));
self.put(layout.R, self.pending.commit(entry.prevBlock));
self.commit(function(err) {
if (err)
return callback(err);
@ -848,8 +851,10 @@ ChainDB.prototype.isMainChain = function isMainChain(hash, callback) {
query = hash;
}
if (hash === this.chain.tip.hash || hash === this.network.genesis.hash)
if (hash === this.chain.tip.hash
|| hash === this.network.genesis.hash) {
return utils.asyncify(callback)(null, true);
}
this.getHeight(query, function(err, height) {
if (err)
@ -901,7 +906,7 @@ ChainDB.prototype.reset = function reset(block, callback) {
self.start();
if (tip.hash === entry.hash) {
self.put(layout.R, self.pending.mark(tip.hash));
self.put(layout.R, self.pending.commit(tip.hash));
return self.commit(callback);
}
@ -985,9 +990,6 @@ ChainDB.prototype.removeBlock = function removeBlock(hash, callback) {
self.del(layout.b(block.hash()));
if (self.options.spv)
return callback(null, block);
self.disconnectBlock(block, callback);
});
};
@ -1082,7 +1084,7 @@ ChainDB.prototype.connectBlock = function connectBlock(block, view, callback) {
if (undo.written > 0)
this.put(layout.u(block.hash()), undo.render());
this._pruneBlock(block, function(err) {
this.pruneBlock(block, function(err) {
if (err)
return callback(err);
callback(null, block);
@ -1727,7 +1729,7 @@ ChainDB.prototype.hasCoins = function hasCoins(hash, callback) {
* @param {Function} callback
*/
ChainDB.prototype._pruneBlock = function _pruneBlock(block, callback) {
ChainDB.prototype.pruneBlock = function pruneBlock(block, callback) {
var futureHeight, key;
if (this.options.spv)
@ -1764,15 +1766,24 @@ ChainDB.prototype._pruneBlock = function _pruneBlock(block, callback) {
};
function ChainState() {
this.hash = null;
this.tip = constants.ZERO_HASH;
this.tx = 0;
this.coin = 0;
this.value = 0;
this.committed = false;
}
ChainState.prototype.__defineGetter__('hash', function() {
return this.tip.toString('hex');
});
ChainState.prototype.__defineGetter__('rhash', function() {
return utils.revHex(this.hash);
});
ChainState.prototype.clone = function clone() {
var state = new ChainState();
state.hash = this.hash;
state.tip = this.tip;
state.tx = this.tx;
state.coin = this.coin;
state.value = this.value;
@ -1797,16 +1808,17 @@ ChainState.prototype.spend = function spend(coin) {
this.value -= coin.value;
};
ChainState.prototype.mark = function mark(hash) {
this.hash = hash;
if (typeof this.hash !== 'string')
this.hash = this.hash.toString('hex');
return this.toRaw(hash);
ChainState.prototype.commit = function commit(hash) {
if (typeof hash === 'string')
hash = new Buffer(hash, 'hex');
this.tip = hash;
this.committed = true;
return this.toRaw();
};
ChainState.prototype.toRaw = function toRaw(hash) {
ChainState.prototype.toRaw = function toRaw() {
var p = new BufferWriter();
p.writeHash(hash || this.hash);
p.writeHash(this.tip);
p.writeU64(this.tx);
p.writeU64(this.coin);
p.writeU64(this.value);
@ -1816,7 +1828,7 @@ ChainState.prototype.toRaw = function toRaw(hash) {
ChainState.fromRaw = function fromRaw(data) {
var state = new ChainState();
var p = new BufferReader(data);
state.hash = p.readHash('hex');
state.tip = p.readHash();
// XXX Allow just a hash until I write a migration.
if (p.left() > 0) {
state.tx = p.readU53();