Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-enable repeated firing of confirmation events #1393

Merged
merged 3 commits into from
Mar 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -2142,6 +2142,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