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();
|
unlock();
|
||||||
if (callback)
|
if (callback)
|
||||||
callback(err, result);
|
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)
|
if (err)
|
||||||
return done(err);
|
return done(err);
|
||||||
|
|
||||||
|
// Ignore if we already have this tx.
|
||||||
|
if (existing)
|
||||||
|
return done(null, true);
|
||||||
|
|
||||||
batch = self.db.batch();
|
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());
|
batch.put(prefix + 't/t/' + hash, tx.toExtended());
|
||||||
|
|
||||||
if (tx.ts === 0) {
|
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) {
|
TXPool.prototype.remove = function remove(hash, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
@ -640,14 +667,15 @@ TXPool.prototype._remove = function remove(tx, map, callback) {
|
|||||||
if (!input.output)
|
if (!input.output)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (address) {
|
if (!address || !map[address].length)
|
||||||
map[address].forEach(function(id) {
|
return;
|
||||||
batch.put(prefix + 'u/a/' + id
|
|
||||||
+ '/' + input.prevout.hash
|
map[address].forEach(function(id) {
|
||||||
+ '/' + input.prevout.index,
|
batch.put(prefix + 'u/a/' + id
|
||||||
DUMMY);
|
+ '/' + input.prevout.hash
|
||||||
});
|
+ '/' + input.prevout.index,
|
||||||
}
|
DUMMY);
|
||||||
|
});
|
||||||
|
|
||||||
batch.put(prefix + 'u/t/'
|
batch.put(prefix + 'u/t/'
|
||||||
+ input.prevout.hash
|
+ input.prevout.hash
|
||||||
@ -660,11 +688,12 @@ TXPool.prototype._remove = function remove(tx, map, callback) {
|
|||||||
tx.outputs.forEach(function(output, i) {
|
tx.outputs.forEach(function(output, i) {
|
||||||
var address = output.getAddress();
|
var address = output.getAddress();
|
||||||
|
|
||||||
if (address) {
|
if (!address || !map[address].length)
|
||||||
map[address].forEach(function(id) {
|
return;
|
||||||
batch.del(prefix + 'u/a/' + id + '/' + hash + '/' + i);
|
|
||||||
});
|
map[address].forEach(function(id) {
|
||||||
}
|
batch.del(prefix + 'u/a/' + id + '/' + hash + '/' + i);
|
||||||
|
});
|
||||||
|
|
||||||
batch.del(prefix + 'u/t/' + 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) {
|
TXPool.prototype.unconfirm = function unconfirm(hash, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
@ -823,6 +780,9 @@ TXPool.prototype._unconfirm = function unconfirm(tx, map, callback) {
|
|||||||
if (!coin)
|
if (!coin)
|
||||||
return next();
|
return next();
|
||||||
|
|
||||||
|
if (!address || !map[address].length)
|
||||||
|
return next();
|
||||||
|
|
||||||
coin.height = tx.height;
|
coin.height = tx.height;
|
||||||
|
|
||||||
batch.put(prefix + 'u/t/' + hash + '/' + i, coin.toRaw());
|
batch.put(prefix + 'u/t/' + hash + '/' + i, coin.toRaw());
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user