txdb. refactor. fixes.
This commit is contained in:
parent
55a7842f59
commit
57f37bba3c
@ -281,71 +281,19 @@ TXPool.prototype._add = function add(tx, map, callback, force) {
|
||||
unlock();
|
||||
if (callback)
|
||||
callback(err, result);
|
||||
};
|
||||
}
|
||||
|
||||
this.getTX(hash, function(err, existing) {
|
||||
// Attempt to confirm tx before adding it.
|
||||
this._confirm(tx, map, function(err, existing) {
|
||||
if (err)
|
||||
return done(err);
|
||||
|
||||
// Ignore if we already have this tx.
|
||||
if (existing)
|
||||
return done(null, true);
|
||||
|
||||
batch = self.db.batch();
|
||||
|
||||
if (existing) {
|
||||
// Tricky - update the tx and coin in storage,
|
||||
// and remove pending flag to mark as confirmed.
|
||||
if (existing.ts === 0 && tx.ts !== 0) {
|
||||
assert(tx.height >= 0);
|
||||
assert(existing.ps > 0);
|
||||
|
||||
batch.put(prefix + 't/t/' + hash, tx.toExtended());
|
||||
batch.del(prefix + 't/p/t/' + hash);
|
||||
batch.put(prefix + 't/h/h/' + pad32(tx.height) + '/' + hash, DUMMY);
|
||||
batch.del(prefix + 't/s/s/' + pad32(existing.ps) + '/' + hash);
|
||||
batch.put(prefix + 't/s/s/' + pad32(tx.ts) + '/' + hash, DUMMY);
|
||||
|
||||
map.all.forEach(function(id) {
|
||||
batch.del(prefix + 't/p/a/' + id + '/' + hash);
|
||||
batch.put(
|
||||
prefix + 't/h/a/' + id + '/' + pad32(tx.height) + '/' + hash, DUMMY);
|
||||
batch.del(
|
||||
prefix + 't/s/a/' + id + '/' + pad32(existing.ps) + '/' + hash);
|
||||
batch.put(
|
||||
prefix + 't/s/a/' + id + '/' + pad32(tx.ts) + '/' + hash, DUMMY);
|
||||
});
|
||||
|
||||
utils.forEachSerial(tx.outputs, function(output, next, i) {
|
||||
self.getCoin(hash, i, function(err, coin) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
if (!coin)
|
||||
return next();
|
||||
|
||||
coin.height = tx.height;
|
||||
|
||||
batch.put(prefix + 'u/t/' + hash + '/' + i, coin.toRaw());
|
||||
|
||||
next();
|
||||
});
|
||||
}, function(err) {
|
||||
if (err)
|
||||
return done(err);
|
||||
|
||||
batch.write(function(err) {
|
||||
if (err)
|
||||
return done(err);
|
||||
|
||||
self.emit('confirmed', tx, map);
|
||||
self.emit('tx', tx, map);
|
||||
|
||||
return done(null, true);
|
||||
});
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
return done(null, false);
|
||||
}
|
||||
|
||||
batch.put(prefix + 't/t/' + hash, tx.toExtended());
|
||||
|
||||
if (tx.ts === 0) {
|
||||
@ -547,6 +495,85 @@ TXPool.prototype._add = function add(tx, map, callback, force) {
|
||||
});
|
||||
};
|
||||
|
||||
TXPool.prototype._confirm = function _confirm(tx, map, callback) {
|
||||
var self = this;
|
||||
var prefix = this.prefix + '/';
|
||||
var hash = tx.hash('hex');
|
||||
var batch;
|
||||
|
||||
this.getTX(hash, function(err, existing) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
// Haven't seen this tx before, add it.
|
||||
if (!existing)
|
||||
return callback(null, false);
|
||||
|
||||
// Existing tx is already confirmed. Ignore.
|
||||
if (existing.ts !== 0)
|
||||
return callback(null, true);
|
||||
|
||||
// The incoming tx won't confirm the existing one anyway. Ignore.
|
||||
if (tx.ts === 0)
|
||||
return callback(null, true);
|
||||
|
||||
batch = self.db.batch();
|
||||
|
||||
// Tricky - update the tx and coin in storage,
|
||||
// and remove pending flag to mark as confirmed.
|
||||
assert(tx.height >= 0);
|
||||
assert(existing.ps > 0);
|
||||
|
||||
batch.put(prefix + 't/t/' + hash, tx.toExtended());
|
||||
batch.del(prefix + 't/p/t/' + hash);
|
||||
batch.put(prefix + 't/h/h/' + pad32(tx.height) + '/' + hash, DUMMY);
|
||||
batch.del(prefix + 't/s/s/' + pad32(existing.ps) + '/' + hash);
|
||||
batch.put(prefix + 't/s/s/' + pad32(tx.ts) + '/' + hash, DUMMY);
|
||||
|
||||
map.all.forEach(function(id) {
|
||||
batch.del(prefix + 't/p/a/' + id + '/' + hash);
|
||||
batch.put(prefix + 't/h/a/' + id + '/' + pad32(tx.height) + '/' + hash, DUMMY);
|
||||
batch.del(prefix + 't/s/a/' + id + '/' + pad32(existing.ps) + '/' + hash);
|
||||
batch.put(prefix + 't/s/a/' + id + '/' + pad32(tx.ts) + '/' + hash, DUMMY);
|
||||
});
|
||||
|
||||
utils.forEachSerial(tx.outputs, function(output, next, i) {
|
||||
var address = output.getAddress();
|
||||
|
||||
// Only update coins if this output is ours.
|
||||
if (!address || !map[address].length)
|
||||
return next();
|
||||
|
||||
self.getCoin(hash, i, function(err, coin) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
if (!coin)
|
||||
return next();
|
||||
|
||||
coin.height = tx.height;
|
||||
|
||||
batch.put(prefix + 'u/t/' + hash + '/' + i, coin.toRaw());
|
||||
|
||||
next();
|
||||
});
|
||||
}, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
batch.write(function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
self.emit('confirmed', tx, map);
|
||||
self.emit('tx', tx, map);
|
||||
|
||||
return callback(null, true);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
TXPool.prototype.remove = function remove(hash, callback) {
|
||||
var self = this;
|
||||
|
||||
@ -640,14 +667,15 @@ TXPool.prototype._remove = function remove(tx, map, callback) {
|
||||
if (!input.output)
|
||||
return;
|
||||
|
||||
if (address) {
|
||||
map[address].forEach(function(id) {
|
||||
batch.put(prefix + 'u/a/' + id
|
||||
+ '/' + input.prevout.hash
|
||||
+ '/' + input.prevout.index,
|
||||
DUMMY);
|
||||
});
|
||||
}
|
||||
if (!address || !map[address].length)
|
||||
return;
|
||||
|
||||
map[address].forEach(function(id) {
|
||||
batch.put(prefix + 'u/a/' + id
|
||||
+ '/' + input.prevout.hash
|
||||
+ '/' + input.prevout.index,
|
||||
DUMMY);
|
||||
});
|
||||
|
||||
batch.put(prefix + 'u/t/'
|
||||
+ input.prevout.hash
|
||||
@ -660,11 +688,12 @@ TXPool.prototype._remove = function remove(tx, map, callback) {
|
||||
tx.outputs.forEach(function(output, i) {
|
||||
var address = output.getAddress();
|
||||
|
||||
if (address) {
|
||||
map[address].forEach(function(id) {
|
||||
batch.del(prefix + 'u/a/' + id + '/' + hash + '/' + i);
|
||||
});
|
||||
}
|
||||
if (!address || !map[address].length)
|
||||
return;
|
||||
|
||||
map[address].forEach(function(id) {
|
||||
batch.del(prefix + 'u/a/' + id + '/' + hash + '/' + i);
|
||||
});
|
||||
|
||||
batch.del(prefix + 'u/t/' + hash + '/' + i);
|
||||
});
|
||||
@ -680,78 +709,6 @@ TXPool.prototype._remove = function remove(tx, map, callback) {
|
||||
});
|
||||
};
|
||||
|
||||
TXPool.prototype._confirm = function _confirm(tx, map, callback) {
|
||||
var self = this;
|
||||
var prefix = this.prefix + '/';
|
||||
var hash = tx.hash('hex');
|
||||
var height = tx.height;
|
||||
var ts = tx.ts;
|
||||
var batch;
|
||||
|
||||
this.getTX(hash, function(err, existing) {
|
||||
if (err)
|
||||
return done(err);
|
||||
|
||||
batch = self.db.batch();
|
||||
|
||||
if (!existing)
|
||||
return callback(null, false);
|
||||
|
||||
if (!(existing.ts === 0 && tx.ts !== 0))
|
||||
return callback(null, true);
|
||||
|
||||
// Tricky - update the tx and coin in storage,
|
||||
// and remove pending flag to mark as confirmed.
|
||||
assert(tx.height >= 0);
|
||||
assert(existing.ps > 0);
|
||||
|
||||
batch.put(prefix + 't/t/' + hash, tx.toExtended());
|
||||
batch.del(prefix + 't/p/t/' + hash);
|
||||
batch.put(prefix + 't/h/h/' + pad32(tx.height) + '/' + hash, DUMMY);
|
||||
batch.del(prefix + 't/s/s/' + pad32(existing.ps) + '/' + hash);
|
||||
batch.put(prefix + 't/s/s/' + pad32(tx.ts) + '/' + hash, DUMMY);
|
||||
|
||||
map.all.forEach(function(id) {
|
||||
batch.del(prefix + 't/p/a/' + id + '/' + hash);
|
||||
batch.put(
|
||||
prefix + 't/h/a/' + id + '/' + pad32(tx.height) + '/' + hash, DUMMY);
|
||||
batch.del(
|
||||
prefix + 't/s/a/' + id + '/' + pad32(existing.ps) + '/' + hash);
|
||||
batch.put(
|
||||
prefix + 't/s/a/' + id + '/' + pad32(tx.ts) + '/' + hash, DUMMY);
|
||||
});
|
||||
|
||||
utils.forEachSerial(tx.outputs, function(output, next, i) {
|
||||
self.getCoin(hash, i, function(err, coin) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
if (!coin)
|
||||
return next();
|
||||
|
||||
coin.height = tx.height;
|
||||
|
||||
batch.put(prefix + 'u/t/' + hash + '/' + i, coin.toRaw());
|
||||
|
||||
next();
|
||||
});
|
||||
}, function(err) {
|
||||
if (err)
|
||||
return done(err);
|
||||
|
||||
batch.write(function(err) {
|
||||
if (err)
|
||||
return done(err);
|
||||
|
||||
self.emit('confirmed', tx, map);
|
||||
self.emit('tx', tx, map);
|
||||
|
||||
return callback(null, true);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
TXPool.prototype.unconfirm = function unconfirm(hash, callback) {
|
||||
var self = this;
|
||||
|
||||
@ -823,6 +780,9 @@ TXPool.prototype._unconfirm = function unconfirm(tx, map, callback) {
|
||||
if (!coin)
|
||||
return next();
|
||||
|
||||
if (!address || !map[address].length)
|
||||
return next();
|
||||
|
||||
coin.height = tx.height;
|
||||
|
||||
batch.put(prefix + 'u/t/' + hash + '/' + i, coin.toRaw());
|
||||
|
||||
Loading…
Reference in New Issue
Block a user