Skip to content

Commit

Permalink
Re-enable repeated firing of confirmation events (web3#1393)
Browse files Browse the repository at this point in the history
  • Loading branch information
cgewecke authored and nachomazzara committed Jun 4, 2020
1 parent 8c23383 commit 36d3730
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 14 deletions.
27 changes: 13 additions & 14 deletions packages/web3-core-method/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ Method.prototype._confirmTransaction = function (defer, result, payload) {


// fire "receipt" and confirmation events and resolve after
var checkConfirmation = function (err, blockHeader, sub, existingReceipt, isPolling) {
var checkConfirmation = function (existingReceipt, err, blockHeader, sub, isPolling) {
if (!err) {
// create fake unsubscribe
if (!sub) {
Expand All @@ -261,7 +261,6 @@ Method.prototype._confirmTransaction = function (defer, result, payload) {
})
// if CONFIRMATION listener exists check for confirmations, by setting canUnsubscribe = false
.then(function(receipt) {

if (!receipt || !receipt.blockHash) {
throw new Error('Receipt missing or blockHash null');
}
Expand All @@ -274,7 +273,12 @@ Method.prototype._confirmTransaction = function (defer, result, payload) {
// check if confirmation listener exists
if (defer.eventEmitter.listeners('confirmation').length > 0) {

defer.eventEmitter.emit('confirmation', confirmationCount, receipt);
// If there was an immediately retrieved receipt, it's already
// been confirmed by the direct call to checkConfirmation needed
// for parity instant-seal
if (existingReceipt === undefined || confirmationCount !== 0){
defer.eventEmitter.emit('confirmation', confirmationCount, receipt);
}

canUnsubscribe = false;
confirmationCount++;
Expand Down Expand Up @@ -396,15 +400,12 @@ Method.prototype._confirmTransaction = function (defer, result, payload) {
};

// start watching for confirmation depending on the support features of the provider
var startWatching = function() {
var startWatching = function(existingReceipt) {
// if provider allows PUB/SUB
if (_.isFunction(this.requestManager.provider.on)) {
_ethereumCall.subscribe('newBlockHeaders', checkConfirmation);
_ethereumCall.subscribe('newBlockHeaders', checkConfirmation.bind(null, existingReceipt));
} else {
// if provider is http and polling
intervalId = setInterval(function() {
checkConfirmation(null, null, null, null, true);
}, 1000);
intervalId = setInterval(checkConfirmation.bind(null, existingReceipt, null, null, null, true), 1000);
}
}.bind(this);

Expand All @@ -414,13 +415,11 @@ Method.prototype._confirmTransaction = function (defer, result, payload) {
.then(function(receipt) {
if (receipt && receipt.blockHash) {
if (defer.eventEmitter.listeners('confirmation').length > 0) {
// if the promise has not been resolved we must keep on watching for new Blocks, if a confrimation listener is present
setTimeout(function(){
if (!promiseResolved) startWatching();
}, 1000);
// We must keep on watching for new Blocks, if a confirmation listener is present
startWatching(receipt);
}
checkConfirmation(receipt, null, null, null);

return checkConfirmation(null, null, null, receipt);
} else if (!promiseResolved) {
startWatching();
}
Expand Down
96 changes: 96 additions & 0 deletions test/contract.js
Original file line number Diff line number Diff line change
Expand Up @@ -2130,6 +2130,102 @@ var runTests = function(contractFactory) {

});

it('should sendTransaction and receive multiple confirmations', function(done){
var provider = new FakeIpcProvider();
var signature = sha3('mySend(address,uint256)').slice(0, 10);

provider.injectValidation(function (payload) {
assert.equal(payload.method, 'eth_sendTransaction');
assert.deepEqual(payload.params, [{
data: signature +'000000000000000000000000'+ addressLowercase.replace('0x','') +'000000000000000000000000000000000000000000000000000000000000000a',
from: address2,
to: addressLowercase,
gasPrice: "0x1369ed97fb71"
}]);
});
provider.injectResult('0x1234000000000000000000000000000000000000000000000000000000056789');

provider.injectValidation(function (payload) {
assert.equal(payload.method, 'eth_getTransactionReceipt');
assert.deepEqual(payload.params, ['0x1234000000000000000000000000000000000000000000000000000000056789']);
});

provider.injectResult({
contractAddress: null,
cumulativeGasUsed: '0xa',
transactionIndex: '0x3',
transactionHash: '0x1234',
blockNumber: '0xa',
blockHash: '0x1234',
gasUsed: '0x0',
logs: []
});

provider.injectValidation(function (payload) {
assert.equal(payload.method, 'eth_subscribe');
assert.deepEqual(payload.params, ['newHeads']);
});
provider.injectResult('0x1234567');

var contract = contractFactory(abi, address, provider);

var count = 0;
contract.methods.mySend(address, 10).send({from: address2, gasPrice: '21345678654321'})
.on('confirmation', function (confirmationNumber, receipt) {
count++;
if(count === 1) {
assert.deepEqual(receipt, {
contractAddress: null,
cumulativeGasUsed: 10,
transactionIndex: 3,
transactionHash: '0x1234',
blockNumber: 10,
blockHash: '0x1234',
gasUsed: 0,
events: {}
});

assert.equal(confirmationNumber, 0)
}
if(count === 2) {
assert.deepEqual(receipt, {
contractAddress: null,
cumulativeGasUsed: 10,
transactionIndex: 3,
transactionHash: '0x1234',
blockNumber: 10,
blockHash: '0x1234',
gasUsed: 0,
events: {}
});

assert.equal(confirmationNumber, 1)
done();
};
});

// fake newBlocks
provider.injectNotification({
method: 'eth_subscription',
params: {
subscription: '0x1234567',
result: {
blockNumber: '0x10'
}
}
});

provider.injectNotification({
method: 'eth_subscription',
params: {
subscription: '0x1234567',
result: {
blockNumber: '0x11'
}
}
});
});

it('should sendTransaction to contract function', function () {
var provider = new FakeIpcProvider();
var signature = 'mySend(address,uint256)';
Expand Down

0 comments on commit 36d3730

Please sign in to comment.