Address: Fixed race condition with transaction event handlers
This commit is contained in:
parent
c5c8e21c6c
commit
0ea035c4f0
@ -223,8 +223,10 @@ AddressService.prototype.transactionLeaveHandler = function(txInfo) {
|
|||||||
* @param {Buffer} txInfo.buffer - The transaction buffer
|
* @param {Buffer} txInfo.buffer - The transaction buffer
|
||||||
* @param {Boolean} txInfo.mempool - If the transaction was accepted in the mempool
|
* @param {Boolean} txInfo.mempool - If the transaction was accepted in the mempool
|
||||||
* @param {String} txInfo.hash - The hash of the transaction
|
* @param {String} txInfo.hash - The hash of the transaction
|
||||||
|
* @param {Function} [callback] - Optional callback
|
||||||
*/
|
*/
|
||||||
AddressService.prototype.transactionHandler = function(txInfo) {
|
AddressService.prototype.transactionHandler = function(txInfo, callback) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
// Basic transaction format is handled by the daemon
|
// Basic transaction format is handled by the daemon
|
||||||
// and we can safely assume the buffer is properly formatted.
|
// and we can safely assume the buffer is properly formatted.
|
||||||
@ -237,15 +239,31 @@ AddressService.prototype.transactionHandler = function(txInfo) {
|
|||||||
this.transactionOutputHandler(messages, tx, i, !txInfo.mempool);
|
this.transactionOutputHandler(messages, tx, i, !txInfo.mempool);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update mempool index
|
if (!callback) {
|
||||||
if (txInfo.mempool) {
|
callback = function(err) {
|
||||||
this.updateMempoolIndex(tx, true);
|
if (err) {
|
||||||
|
return log.error(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var key in messages) {
|
function finish(err) {
|
||||||
this.transactionEventHandler(messages[key]);
|
if (err) {
|
||||||
this.balanceEventHandler(null, messages[key].addressInfo);
|
return callback(err);
|
||||||
|
}
|
||||||
|
for (var key in messages) {
|
||||||
|
self.transactionEventHandler(messages[key]);
|
||||||
|
self.balanceEventHandler(null, messages[key].addressInfo);
|
||||||
|
}
|
||||||
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (txInfo.mempool) {
|
||||||
|
self.updateMempoolIndex(tx, true, finish);
|
||||||
|
} else {
|
||||||
|
setImmediate(finish);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -254,7 +272,7 @@ AddressService.prototype.transactionHandler = function(txInfo) {
|
|||||||
* @param {Transaction} - An instance of a Bitcore Transaction
|
* @param {Transaction} - An instance of a Bitcore Transaction
|
||||||
* @param {Boolean} - Add/remove from the index
|
* @param {Boolean} - Add/remove from the index
|
||||||
*/
|
*/
|
||||||
AddressService.prototype.updateMempoolIndex = function(tx, add) {
|
AddressService.prototype.updateMempoolIndex = function(tx, add, callback) {
|
||||||
/* jshint maxstatements: 100 */
|
/* jshint maxstatements: 100 */
|
||||||
|
|
||||||
var operations = [];
|
var operations = [];
|
||||||
@ -362,11 +380,15 @@ AddressService.prototype.updateMempoolIndex = function(tx, add) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.mempoolIndex.batch(operations, function(err) {
|
if (!callback) {
|
||||||
if (err) {
|
callback = function(err) {
|
||||||
return log.error(err);
|
if (err) {
|
||||||
}
|
return log.error(err);
|
||||||
});
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mempoolIndex.batch(operations, callback);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -357,24 +357,30 @@ describe('Address Service', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('#transactionHandler', function() {
|
describe('#transactionHandler', function() {
|
||||||
it('will pass outputs to transactionOutputHandler and call transactionEventHandler and balanceEventHandler', function() {
|
it('will pass outputs to transactionOutputHandler and call transactionEventHandler and balanceEventHandler', function(done) {
|
||||||
var txBuf = new Buffer('01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0104ffffffff0100f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac00000000', 'hex');
|
var txBuf = new Buffer('01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0104ffffffff0100f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac00000000', 'hex');
|
||||||
var am = new AddressService({
|
var am1 = new AddressService({
|
||||||
mempoolMemoryIndex: true,
|
mempoolMemoryIndex: true,
|
||||||
node: mocknode
|
node: mocknode
|
||||||
});
|
});
|
||||||
var address = '12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX';
|
var address = '12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX';
|
||||||
var message = {};
|
var message = {};
|
||||||
am.transactionOutputHandler = function(messages) {
|
am1.transactionOutputHandler = function(messages) {
|
||||||
messages[address] = message;
|
messages[address] = message;
|
||||||
};
|
};
|
||||||
am.transactionEventHandler = sinon.spy();
|
am1.transactionEventHandler = sinon.stub();
|
||||||
am.balanceEventHandler = sinon.spy();
|
am1.balanceEventHandler = sinon.stub();
|
||||||
am.transactionHandler({
|
am1.transactionHandler({
|
||||||
buffer: txBuf
|
buffer: txBuf
|
||||||
|
}, function(err) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
am1.transactionEventHandler.callCount.should.equal(1);
|
||||||
|
am1.balanceEventHandler.callCount.should.equal(1);
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
am.transactionEventHandler.callCount.should.equal(1);
|
|
||||||
am.balanceEventHandler.callCount.should.equal(1);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user