Skip to content

Commit

Permalink
The transaction confirmation workflow can now be configured (#3130)
Browse files Browse the repository at this point in the history
* transactionBlockTimeout, transactionConfirmationBlock, and transactionPollingTimeout property added to the Eth, Contract, and Method class

* CHANGELOG.md updated

* documentation updated

* default values added to the documentation for the newely introduced transaction fconfirmation workflow configuration properties

* test cases for the new properties added and adding of the Contract reference in the Eth module fixed

* missing space added

* Update docs/web3-eth.rst

Co-Authored-By: cgewecke <christophergewecke@gmail.com>

* Update docs/web3-eth-contract.rst

Co-Authored-By: cgewecke <christophergewecke@gmail.com>
  • Loading branch information
nivida and cgewecke authored Oct 16, 2019
1 parent f471981 commit d25d90b
Show file tree
Hide file tree
Showing 10 changed files with 366 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ Released with 1.0.0-beta.37 code base.
- getNetworkType method extended with Görli testnet (#3095)
- supportsSubscriptions method added to providers (#3116)
- Add `eth.getChainId` method (#3113)
- The transaction confirmation workflow can now be configured (#3130)

### Fixed

Expand Down
148 changes: 148 additions & 0 deletions docs/web3-eth-contract.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,154 @@ Example
= Properties =
=========

------------------------------------------------------------------------------

.. _eth-contract-defaultaccount
defaultAccount
=====================

.. code-block:: javascript
web3.eth.Contract.defaultAccount
contract.defaultAccount // on contract instance
This default address is used as the default ``"from"`` property, if no ``"from"`` property is specified in for the following methods:

- :ref:`web3.eth.sendTransaction() <eth-sendtransaction>`
- :ref:`web3.eth.call() <eth-call>`
- :ref:`new web3.eth.Contract() -> myContract.methods.myMethod().call() <eth-contract-call>`
- :ref:`new web3.eth.Contract() -> myContract.methods.myMethod().send() <eth-contract-send>`

--------
Property
--------


``String`` - 20 Bytes: Any ethereum address. You should have the private key for that address in your node or keystore. (Default is ``undefined``)


-------
Example
-------


.. code-block:: javascript
web3.eth.defaultAccount;
> undefined
// set the default account
web3.eth.defaultAccount = '0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe';
------------------------------------------------------------------------------

.. _eth-contract-defaultblock:

defaultBlock
=====================

.. code-block:: javascript
web3.eth.Contract.defaultBlock
contract.defaultBlock // on contract instance
The default block is used for certain methods. You can override it by passing in the defaultBlock as last parameter.
The default value of it is "latest".

----------
Property
----------


Default block parameters can be one of the following:

- ``Number``: A block number
- ``"genesis"`` - ``String``: The genesis block
- ``"latest"`` - ``String``: The latest block (current head of the blockchain)
- ``"pending"`` - ``String``: The currently mined block (including pending transactions)

Default is ``"latest"``


-------
Example
-------

.. code-block:: javascript
contract.defaultBlock;
> "latest"
// set the default block
contract.defaultBlock = 231;
------------------------------------------------------------------------------

.. _eth-contract-transactionblocktimeout:

transactionBlockTimeout
=====================

.. code-block:: javascript
web3.eth.Contract.transcationBlockTimeout
contract.transactionBlockTimeout // on contract instance
The ``transactionBlockTimeout`` will be used over a socket based connection. This option does define the amount of new blocks it should wait until the first confirmation happens.
This means the PromiEvent rejects with a timeout error when the timeout got exceeded.


-------
Returns
-------

``number``: The current value of transactionBlockTimeout (default: 50)

------------------------------------------------------------------------------

.. _eth-contract-module-transactionconfirmationblocks:

transactionConfirmationBlocks
=====================

.. code-block:: javascript
web3.eth.Contract.transactionConfirmationBlocks
contract.transactionConfirmationBlocks // on contract instance
This defines the number of blocks it requires until a transaction will be handled as confirmed.


-------
Returns
-------

``number``: The current value of transactionConfirmationBlocks (default: 24)

------------------------------------------------------------------------------

.. _eth-contract-module-transactionpollingtimeout:

transactionPollingTimeout
=====================

.. code-block:: javascript
web3.eth.Contract.transactionPollingTimeout
contract.transactionPollingTimeout // on contract instance
The ``transactionPollingTimeout`` will be used over a HTTP connection.
This option defines the number of seconds Web3 will wait for a receipt which confirms that a transaction was mined by the network. NB: If this method times out, the transaction may still be pending.


-------
Returns
-------

``number``: The current value of transactionPollingTimeout (default: 750)

------------------------------------------------------------------------------

Expand Down
63 changes: 63 additions & 0 deletions docs/web3-eth.rst
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ For ``web3.eth.net`` see the :ref:`net reference documentation <eth-net>`

------------------------------------------------------------------------------

.. _eth-defaultaccount
defaultAccount
=====================
Expand Down Expand Up @@ -207,6 +208,68 @@ Example
web3.eth.defaultBlock = 231;
------------------------------------------------------------------------------

.. _web3-module-transactionblocktimeout:

transactionBlockTimeout
=====================

.. code-block:: javascript
web3.eth.transactionBlockTimeout
The ``transactionBlockTimeout`` will be used over a socket based connection. This option does define the amount of new blocks it should wait until the first confirmation happens.
This means the PromiEvent rejects with a timeout error when the timeout got exceeded.


-------
Returns
-------

``number``: The current value of transactionBlockTimeout (default: 50)

------------------------------------------------------------------------------

.. _web3-module-transactionconfirmationblocks:

transactionConfirmationBlocks
=====================

.. code-block:: javascript
web3.eth.transactionConfirmationBlocks
This defines the number of blocks it requires until a transaction will be handled as confirmed.


-------
Returns
-------

``number``: The current value of transactionConfirmationBlocks (default: 24)

------------------------------------------------------------------------------

.. _web3-module-transactionpollingtimeout:

transactionPollingTimeout
=====================

.. code-block:: javascript
web3.eth.transactionPollingTimeout
The ``transactionPollingTimeout`` will be used over a HTTP connection.
This option defines the number of seconds Web3 will wait for a receipt which confirms that a transaction was mined by the network. NB: If this method times out, the transaction may still be pending.


-------
Returns
-------

``number``: The current value of transactionPollingTimeout (default: 750)

------------------------------------------------------------------------------

getProtocolVersion
Expand Down
4 changes: 3 additions & 1 deletion packages/web3-bzz/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 10 additions & 11 deletions packages/web3-core-method/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ var utils = require('web3-utils');
var promiEvent = require('web3-core-promievent');
var Subscriptions = require('web3-core-subscriptions').subscriptions;

var TIMEOUTBLOCK = 50;
var POLLINGTIMEOUT = 15 * TIMEOUTBLOCK; // ~average block time (seconds) * TIMEOUTBLOCK
var CONFIRMATIONBLOCKS = 24;

var Method = function Method(options) {

if(!options.call || !options.name) {
Expand All @@ -55,6 +51,9 @@ var Method = function Method(options) {

this.defaultBlock = options.defaultBlock || 'latest';
this.defaultAccount = options.defaultAccount || null;
this.transactionBlockTimeout = options.transactionBlockTimeout || 50;
this.transactionConfirmationBlocks = options.transactionConfirmationBlocks || 24;
this.transactionPollingTimeout = options.transactionPollingTimeout || 750;
};

Method.prototype.setRequestManager = function (requestManager, accounts) {
Expand Down Expand Up @@ -290,7 +289,7 @@ Method.prototype._confirmTransaction = function (defer, result, payload) {
canUnsubscribe = false;
confirmationCount++;

if (confirmationCount === CONFIRMATIONBLOCKS + 1) { // add 1 so we account for conf 0
if (confirmationCount === method.transactionConfirmationBlocks + 1) { // add 1 so we account for conf 0
sub.unsubscribe();
defer.eventEmitter.removeAllListeners();
}
Expand Down Expand Up @@ -410,22 +409,22 @@ Method.prototype._confirmTransaction = function (defer, result, payload) {

// check to see if we are http polling
if(!!isPolling) {
// polling timeout is different than TIMEOUTBLOCK blocks since we are triggering every second
if (timeoutCount - 1 >= POLLINGTIMEOUT) {
// polling timeout is different than transactionBlockTimeout blocks since we are triggering every second
if (timeoutCount - 1 >= method.transactionPollingTimeout) {
sub.unsubscribe();
promiseResolved = true;
utils._fireError(
new Error('Transaction was not mined within ' + POLLINGTIMEOUT + ' seconds, please make sure your transaction was properly sent. Be aware that it might still be mined!'),
defer.eventEmitter,
new Error('Transaction was not mined within ' + method.transactionPollingTimeout + ' seconds, please make sure your transaction was properly sent. Be aware that it might still be mined!'),
defer.eventEmitter,
defer.reject
);
}
} else {
if (timeoutCount - 1 >= TIMEOUTBLOCK) {
if (timeoutCount - 1 >= method.transactionBlockTimeout) {
sub.unsubscribe();
promiseResolved = true;
utils._fireError(
new Error('Transaction was not mined within 50 blocks, please make sure your transaction was properly sent. Be aware that it might still be mined!'),
new Error('Transaction was not mined within ' + method.transactionBlockTimeout + ' blocks, please make sure your transaction was properly sent. Be aware that it might still be mined!'),
defer.eventEmitter,
defer.reject
);
Expand Down
6 changes: 6 additions & 0 deletions packages/web3-eth-contract/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ var Contract = function Contract(jsonInterface, address, options) {
// get default account from the Class
var defaultAccount = this.constructor.defaultAccount;
var defaultBlock = this.constructor.defaultBlock || 'latest';
this.transactionBlockTimeout = this.constructor.transactionBlockTimeout;
this.transactionConfirmationBlocks = this.constructor.transactionConfirmationBlocks;
this.transactionPollingTimeout = this.constructor.transactionPollingTimeout;

Object.defineProperty(this, 'defaultAccount', {
get: function () {
Expand Down Expand Up @@ -891,6 +894,9 @@ Contract.prototype._executeMethod = function _executeMethod(){
accounts: _this.constructor._ethAccounts || _this._ethAccounts, // is eth.accounts (necessary for wallet signing)
defaultAccount: _this._parent.defaultAccount,
defaultBlock: _this._parent.defaultBlock,
transactionBlockTimeout: _this._parent.transactionBlockTimeout,
transactionConfirmationBlocks: _this._parent.transactionConfirmationBlocks,
transactionPollingTimeout: _this._parent.transactionPollingTimeout,
extraFormatters: extraFormatters
})).createFunction();

Expand Down
Loading

0 comments on commit d25d90b

Please sign in to comment.