Skip to content
This repository has been archived by the owner on Mar 5, 2025. It is now read-only.

Commit

Permalink
Merge pull request #3550 from ethereum/issue/3438
Browse files Browse the repository at this point in the history
Add events `sending` and `sent` to tx submission, add arg `latestBlockHash` to event `confirmation`
  • Loading branch information
ryanio authored Jun 2, 2020
2 parents 3107c98 + 3cef72c commit 242bfd0
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 23 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ Released with 1.0.0-beta.37 code base.
### Added

- Documentation about testing & ci resources for Web3.js development (#3528)
- Add events `sending` and `sent` to transaction submission, add `latestBlockHash` to `confirmation` (#3550)

### Changed

Expand Down
4 changes: 3 additions & 1 deletion docs/callbacks-promises-events.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ This way developers can watch for additional events like on "receipt" or "transa
.. code-block:: javascript
web3.eth.sendTransaction({from: '0x123...', data: '0x432...'})
.once('sending', function(payload){ ... })
.once('sent', function(payload){ ... })
.once('transactionHash', function(hash){ ... })
.once('receipt', function(receipt){ ... })
.on('confirmation', function(confNumber, receipt){ ... })
.on('confirmation', function(confNumber, receipt, latestBlockHash){ ... })
.on('error', function(error){ ... })
.then(function(receipt){
// will be fired once the receipt is mined
Expand Down
10 changes: 6 additions & 4 deletions docs/web3-eth-contract.rst
Original file line number Diff line number Diff line change
Expand Up @@ -848,10 +848,12 @@ The **callback** will return the 32 bytes transaction hash.

``PromiEvent``: A :ref:`promise combined event emitter <promiEvent>`. Resolves when the transaction *receipt* is available, OR if this ``send()`` is called from a ``someContract.deploy()``, then the promise will resolve with the *new contract instance*. Additionally the following events are available:

- ``"transactionHash"`` returns ``String``: is fired right after the transaction is sent and a transaction hash is available.
- ``"receipt"`` returns ``Object``: is fired when the transaction *receipt* is available. Receipts from contracts will have no ``logs`` property, but instead an ``events`` property with event names as keys and events as properties. See :ref:`getPastEvents return values <contract-events-return>` for details about the returned event object.
- ``"confirmation"`` returns ``Number``, ``Object``: is fired for every confirmation up to the 24th confirmation. Receives the confirmation number as the first and the receipt as the second argument. Fired from confirmation 1 on, which is the block where it's minded.
- ``"error"`` returns ``Error`` and ``Object|undefined``: Is fired if an error occurs during sending. If the transaction was rejected by the network with a receipt, the second parameter will be the receipt.
- ``sending`` returns ``payload: Object``: Fired immediately before transmitting the transaction request.
- ``sent`` returns ``payload: Object``: Fired immediately after the request body has been written to the client, but before the transaction hash is received.
- ``"transactionHash"`` returns ``transactionHash: String``: Fired when the transaction hash is available.
- ``"receipt"`` returns ``receipt: Object``: Fired when the transaction *receipt* is available. Receipts from contracts will have no ``logs`` property, but instead an ``events`` property with event names as keys and events as properties. See :ref:`getPastEvents return values <contract-events-return>` for details about the returned event object.
- ``"confirmation"`` returns ``confirmation: Number``, ``receipt: Object``, ``latestBlockHash: String``: Fired for every confirmation up to the 24th confirmation.
- ``"error"`` returns ``error: Error``: Fired if an error occurs during sending. If the transaction was rejected by the network with a receipt, the receipt will be available as a property on the error object.


-------
Expand Down
10 changes: 6 additions & 4 deletions docs/web3-eth.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1412,10 +1412,12 @@ The **callback** will return the 32 bytes transaction hash.

``PromiEvent``: A :ref:`promise combined event emitter <promiEvent>`. Resolves when the transaction :ref:`receipt <eth-gettransactionreceipt-return>` is available. The following events are also available:

- ``"transactionHash"`` returns ``String``: Is fired right after the transaction is sent and a transaction hash is available.
- ``"receipt"`` returns ``Object``: Is fired when the transaction receipt is available.
- ``"confirmation"`` returns ``Number``, ``Object``: Is fired for every confirmation up to the 12th confirmation. Receives the confirmation number as the first and the :ref:`receipt <eth-gettransactionreceipt-return>` as the second argument. Fired from confirmation 0 on, which is the block where it's mined.
``"error"`` returns ``Error`` and ``Object|undefined``: Is fired if an error occurs during sending. If the transaction was rejected by the network with a receipt, the second parameter will be the receipt.
- ``sending`` returns ``payload: Object``: Fired immediately before transmitting the transaction request.
- ``sent`` returns ``payload: Object``: Fired immediately after the request body has been written to the client, but before the transaction hash is received.
- ``"transactionHash"`` returns ``transactionHash: String``: Fired when the transaction hash is available.
- ``"receipt"`` returns ``receipt: Object``: Fired when the transaction receipt is available.
- ``"confirmation"`` returns ``confirmationNumber: Number``, ``receipt: Object``, ``latestBlockHash: String``: Fired for every confirmation up to the 12th confirmation. Receives the confirmation number as the first and the :ref:`receipt <eth-gettransactionreceipt-return>` as the second argument. Fired from confirmation 0 on, which is the block where it's mined.
``"error"`` returns ``error: Error``: Fired if an error occurs during sending. If the transaction was rejected by the network with a receipt, the receipt will be available as a property on the error object.


-------
Expand Down
29 changes: 26 additions & 3 deletions packages/web3-core-method/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,20 +309,24 @@ Method.prototype._confirmTransaction = function (defer, result, payload) {
// been confirmed by the direct call to checkConfirmation needed
// for parity instant-seal
if (existingReceipt === undefined || confirmationCount !== 0) {
// Get latest block to emit with confirmation
var latestBlock = await _ethereumCall.getBlockByNumber('latest');
var latestBlockHash = latestBlock ? latestBlock.hash : null;

if (isPolling) { // Check if actually a new block is existing on polling
if (lastBlock) {
block = await _ethereumCall.getBlockByNumber(lastBlock.number + 1);
if (block) {
lastBlock = block;
defer.eventEmitter.emit('confirmation', confirmationCount, receipt);
defer.eventEmitter.emit('confirmation', confirmationCount, receipt, latestBlockHash);
}
} else {
block = await _ethereumCall.getBlockByNumber(receipt.blockNumber);
lastBlock = block;
defer.eventEmitter.emit('confirmation', confirmationCount, receipt);
defer.eventEmitter.emit('confirmation', confirmationCount, receipt, latestBlockHash);
}
} else {
defer.eventEmitter.emit('confirmation', confirmationCount, receipt);
defer.eventEmitter.emit('confirmation', confirmationCount, receipt, latestBlockHash);
}
}

Expand Down Expand Up @@ -742,6 +746,7 @@ Method.prototype.buildCall = function () {
}
}


return method.requestManager.send(payload, sendTxCallback);
};

Expand All @@ -759,13 +764,31 @@ Method.prototype.buildCall = function () {
if (gasPrice) {
payload.params[0].gasPrice = gasPrice;
}

if (isSendTx) {
setTimeout(() => {
defer.eventEmitter.emit('sending', payload);
}, 0);
}

sendRequest(payload, method);
});

} else {
if (isSendTx) {
setTimeout(() => {
defer.eventEmitter.emit('sending', payload);
}, 0);
}

sendRequest(payload, method);
}

if (isSendTx) {
setTimeout(() => {
defer.eventEmitter.emit('sent', payload);
}, 0);
}

return defer.eventEmitter;
};
Expand Down
16 changes: 13 additions & 3 deletions packages/web3-core/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,19 @@ export interface Providers {
}

export interface PromiEvent<T> extends Promise<T> {
once(
type: 'sending',
handler: (payload: object) => void
): PromiEvent<T>;

once(
type: 'sent',
handler: (payload: object) => void
): PromiEvent<T>;

once(
type: 'transactionHash',
handler: (receipt: string) => void
handler: (transactionHash: string) => void
): PromiEvent<T>;

once(
Expand All @@ -71,7 +81,7 @@ export interface PromiEvent<T> extends Promise<T> {

once(
type: 'confirmation',
handler: (confNumber: number, receipt: TransactionReceipt) => void
handler: (confirmationNumber: number, receipt: TransactionReceipt, latestBlockHash?: string) => void
): PromiEvent<T>;

once(type: 'error', handler: (error: Error) => void): PromiEvent<T>;
Expand All @@ -93,7 +103,7 @@ export interface PromiEvent<T> extends Promise<T> {

on(
type: 'confirmation',
handler: (confNumber: number, receipt: TransactionReceipt) => void
handler: (confNumber: number, receipt: TransactionReceipt, latestBlockHash?: string) => void
): PromiEvent<T>;

on(type: 'error', handler: (error: Error) => void): PromiEvent<T>;
Expand Down
4 changes: 2 additions & 2 deletions packages/web3-eth-ens/src/contracts/Registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ var namehash = require('eth-ens-namehash');
var PromiEvent = require('web3-core-promievent');
var formatters = require('web3-core-helpers').formatters;
var utils = require('web3-utils');
var REGISTRY_ABI = require('../ressources/ABI/Registry');
var RESOLVER_ABI = require('../ressources/ABI/Resolver');
var REGISTRY_ABI = require('../resources/ABI/Registry');
var RESOLVER_ABI = require('../resources/ABI/Resolver');


/**
Expand Down
6 changes: 6 additions & 0 deletions packages/web3-eth-ens/src/lib/ResolverMethodHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@ ResolverMethodHandler.prototype.handleCall = function (promiEvent, method, prepa
*/
ResolverMethodHandler.prototype.handleSend = function (promiEvent, method, preparedArguments, sendOptions, callback) {
method.apply(this, preparedArguments).send(sendOptions)
.on('sending', function () {
promiEvent.eventEmitter.emit('sending');
})
.on('sent', function () {
promiEvent.eventEmitter.emit('sent');
})
.on('transactionHash', function (hash) {
promiEvent.eventEmitter.emit('transactionHash', hash);
})
Expand Down
34 changes: 28 additions & 6 deletions test/e2e.contract.deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,13 @@ describe('contract.deploy [ @E2E ]', function() {
await basic
.deploy()
.send({from: accounts[0]})
.on('confirmation', async (number, receipt) => {
.on('confirmation', async (number, receipt, latestBlockHash) => {
assert(receipt.contractAddress);

if (number === 1) { // Confirmation numbers are zero indexed
var endBlock = await web3.eth.getBlockNumber();
assert(endBlock >= (startBlock + 2));
var endBlock = await web3.eth.getBlock('latest');
assert(endBlock.number >= (startBlock + 2));
assert(endBlock.hash === latestBlockHash);
resolve();
}
})
Expand Down Expand Up @@ -198,6 +199,26 @@ describe('contract.deploy [ @E2E ]', function() {
}
});

it('fires the sending event with the payload', function(done){
basic
.deploy()
.send({from: accounts[0]})
.on('sending', (payload) => {
assert(basic.options.data === payload.params[0].data)
done();
})
});

it('fires the sent event with the payload', function(done){
basic
.deploy()
.send({from: accounts[0]})
.on('sent', (payload) => {
assert(basic.options.data === payload.params[0].data)
done();
})
});

it('fires the transactionHash event', function(done){
basic
.deploy()
Expand Down Expand Up @@ -225,10 +246,11 @@ describe('contract.deploy [ @E2E ]', function() {
await basic
.deploy()
.send({from: accounts[0]})
.on('confirmation', async (number, receipt) => {
.on('confirmation', async (number, receipt, latestBlockHash) => {
if (number === 1) { // Confirmation numbers are zero indexed
var endBlock = await web3.eth.getBlockNumber();
assert(endBlock >= (startBlock + 2));
var endBlock = await web3.eth.getBlock('latest');
assert(endBlock.number >= (startBlock + 2));
assert(endBlock.hash === latestBlockHash);
resolve();
}
})
Expand Down

0 comments on commit 242bfd0

Please sign in to comment.