Skip to content

Commit

Permalink
instant-mine option added (#3008)
Browse files Browse the repository at this point in the history
- automine and Instant Seal support added 
- default value of transactionConfirmationBlocks changed to 0 
- TransactionObserver splitted up to HttpTransactionObserver and SocketTransactionObserver 
- Property handling for the Ens module fixed
  • Loading branch information
nivida committed Aug 8, 2019
1 parent 3c8e0f7 commit c96a09e
Show file tree
Hide file tree
Showing 39 changed files with 1,688 additions and 630 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ addons:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
services:
- xvfb
before_script:
- npm i -g typescript@next
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
install:
- npm install
- npm run bootstrap
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [2.0.0-alpha.2]

### Added

- ``automine`` and ``Instant Seal`` support added (#2940)

### Changed

- default value of ``transactionConfirmationBlocks`` changed to ``0`` (#3008)
- ``TransactionObserver`` splitted up to ``HttpTransactionObserver`` and ``SocketTransactionObserver`` (#3008)

### Fixed

- Error handling of the HttpProvider fixed (#2887)
- Property handling for the Ens module fixed (#3008)

22 changes: 16 additions & 6 deletions packages/web3-core-method/lib/factories/AbstractMethodFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@
import {NewHeadsSubscription} from 'web3-core-subscriptions';
import GetBlockByNumberMethod from '../../src/methods/block/GetBlockByNumberMethod';
import GetTransactionReceiptMethod from '../../src/methods/transaction/GetTransactionReceiptMethod';
import TransactionObserver from '../../src/observers/TransactionObserver';
import GetTransactionCountMethod from '../../src/methods/account/GetTransactionCountMethod';
import ChainIdMethod from '../../src/methods/network/ChainIdMethod';
import SocketTransactionObserver from '../../src/observers/SocketTransactionObserver';
import HttpTransactionObserver from '../../src/observers/HttpTransactionObserver';

export default class AbstractMethodFactory {
/**
Expand Down Expand Up @@ -137,22 +138,31 @@ export default class AbstractMethodFactory {
}

/**
* Returns a object of type TransactionObserver
* Returns a object of type AbstractTransactionObserver
*
* @method createTransactionObserver
*
* @param {AbstractWeb3Module} moduleInstance
*
* @returns {TransactionObserver}
* @returns {AbstractTransactionObserver}
*/
createTransactionObserver(moduleInstance) {
return new TransactionObserver(
if (moduleInstance.currentProvider.supportsSubscriptions()) {
return new SocketTransactionObserver(
moduleInstance.currentProvider,
this.getTimeout(moduleInstance),
moduleInstance.transactionConfirmationBlocks,
new GetTransactionReceiptMethod(this.utils, this.formatters, moduleInstance),
new NewHeadsSubscription(this.utils, this.formatters, moduleInstance)
);
}

return new HttpTransactionObserver(
moduleInstance.currentProvider,
this.getTimeout(moduleInstance),
moduleInstance.transactionConfirmationBlocks,
new GetTransactionReceiptMethod(this.utils, this.formatters, moduleInstance),
new GetBlockByNumberMethod(this.utils, this.formatters, moduleInstance),
new NewHeadsSubscription(this.utils, this.formatters, moduleInstance)
new GetBlockByNumberMethod(this.utils, this.formatters, moduleInstance)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default class AbstractObservedTransactionMethod extends AbstractMethod {
* @param {Utils} utils
* @param {Object} formatters
* @param {AbstractWeb3Module} moduleInstance
* @param {TransactionObserver} transactionObserver
* @param {AbstractTransactionObserver} transactionObserver
*
* @constructor
*/
Expand Down
118 changes: 118 additions & 0 deletions packages/web3-core-method/lib/observers/AbstractTransactionObserver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
This file is part of web3.js.
web3.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
web3.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with web3.js. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file AbstractTransactionObserver.js
* @author Samuel Furter <samuel@ethereum.org>
* @author Josh Stevens <joshstevens19@hotmail.co.uk>
* @date 2019
*/

export default class AbstractTransactionObserver {
/**
* @param {AbstractSocketProvider|HttpProvider|CustomProvider} provider
* @param {Number} timeout
* @param {Number} blockConfirmations
* @param {GetTransactionReceiptMethod} getTransactionReceiptMethod
*
* @constructor
*/
constructor(provider, timeout, blockConfirmations, getTransactionReceiptMethod) {
this.provider = provider;
this.timeout = timeout;
this.blockConfirmations = blockConfirmations;
this.getTransactionReceiptMethod = getTransactionReceiptMethod;

this.confirmations = 0;
this.confirmationChecks = 0;
}

/**
* Observes the transaction by the given transactionHash
*
* @method observe
*
* @param {String} transactionHash
*
* @returns {Observable}
*/
observe(transactionHash) {}

/**
* Calls the next callback method of the Observer
*
* @method emitNext
*
* @param {Object} receipt
* @param {Observer} observer
*/
emitNext(receipt, observer) {
observer.next({receipt, confirmations: this.confirmations});
}

/**
* Calls the error callback method of the Observer
*
* @method emitError
*
* @param {Error} error
* @param {Object} receipt
* @param {Observer} observer
*/
emitError(error, receipt, observer) {
observer.error({
error,
receipt,
confirmations: this.confirmations,
confirmationChecks: this.confirmationChecks
});
}

/**
* Checks if enough confirmations happened
*
* @method isConfirmed
*
*
* @returns {Boolean}
*/
isConfirmed() {
return this.confirmations === this.blockConfirmations;
}

/**
* Checks if the timeout time is reached
*
* @method isTimeoutTimeExceeded
*
* @returns {Boolean}
*/
isTimeoutTimeExceeded() {
return this.confirmationChecks === this.timeout;
}

/**
* Returns the transaction receipt
*
* @method getTransactionReceipt
*
* @param {String} transactionHash
*
* @returns {Promise<Object|null>}
*/
getTransactionReceipt(transactionHash) {
this.getTransactionReceiptMethod.parameters = [transactionHash];

return this.getTransactionReceiptMethod.execute();
}
}
4 changes: 3 additions & 1 deletion packages/web3-core-method/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ export PromiEvent from '../lib/PromiEvent';
export AbstractMethodFactory from '../lib/factories/AbstractMethodFactory';
export AbstractMethod from '../lib/methods/AbstractMethod';
export MethodProxy from './proxy/MethodProxy';
export TransactionObserver from './observers/TransactionObserver';
export AbstractTransactionObserver from '../lib/observers/AbstractTransactionObserver';
export HttpTransactionObserver from './observers/HttpTransactionObserver';
export SocketTransactionObserver from './observers/SocketTransactionObserver';

// Network
export GetProtocolVersionMethod from './methods/network/GetProtocolVersionMethod';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default class EthSendTransactionMethod extends SendTransactionMethod {
* @param {Utils} utils
* @param {Object} formatters
* @param {AbstractWeb3Module} moduleInstance
* @param {TransactionObserver} transactionObserver
* @param {AbstractTransactionObserver} transactionObserver
* @param {ChainIdMethod} chainIdMethod
* @param {GetTransactionCountMethod} getTransactionCountMethod
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default class SendRawTransactionMethod extends AbstractObservedTransactio
* @param {Utils} utils
* @param {Object} formatters
* @param {AbstractWeb3Module} moduleInstance
* @param {TransactionObserver} transactionObserver
* @param {AbstractTransactionObserver} transactionObserver
*
* @constructor
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default class SendTransactionMethod extends AbstractObservedTransactionMe
* @param {Utils} utils
* @param {Object} formatters
* @param {AbstractWeb3Module} moduleInstance
* @param {TransactionObserver} transactionObserver
* @param {AbstractTransactionObserver} transactionObserver
*
* @constructor
*/
Expand Down
139 changes: 139 additions & 0 deletions packages/web3-core-method/src/observers/HttpTransactionObserver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
This file is part of web3.js.
web3.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
web3.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with web3.js. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file TransactionHttpObserver.js
* @author Samuel Furter <samuel@ethereum.org>
* @author Josh Stevens <joshstevens19@hotmail.co.uk>
* @date 2019
*/

import {Observable} from 'rxjs';
import AbstractTransactionObserver from '../../lib/observers/AbstractTransactionObserver';

export default class HttpTransactionObserver extends AbstractTransactionObserver {
/**
* @param {AbstractSocketProvider|HttpProvider|CustomProvider} provider
* @param {Number} timeout
* @param {Number} blockConfirmations
* @param {GetTransactionReceiptMethod} getTransactionReceiptMethod
* @param {GetBlockByNumberMethod} getBlockByNumberMethod
*
* @constructor
*/
constructor(provider, timeout, blockConfirmations, getTransactionReceiptMethod, getBlockByNumberMethod) {
super(provider, timeout, blockConfirmations, getTransactionReceiptMethod);

this.getBlockByNumberMethod = getBlockByNumberMethod;
this.lastBlock = false;
}

/**
* Observes the transaction by the given transactionHash
*
* @method observe
*
* @param {String} transactionHash
*
* @returns {Observable}
*/
observe(transactionHash) {
return Observable.create((observer) => {
this.getTransactionReceipt(transactionHash)
.then((receipt) => {
if (this.blockConfirmations === 0) {
if (receipt) {
this.emitNext(receipt, observer);
observer.complete();

return;
}

this.emitError(
new Error(
'No transaction receipt found! Increase the transactionConfirmationBlocks property or be sure automine is activated in your development environment.'
),
false,
observer
);

return;
}

const interval = setInterval(async () => {
receipt = await this.getTransactionReceipt(transactionHash);

if (observer.closed) {
clearInterval(interval);

return;
}

// on parity nodes you can get the receipt without it being mined
// so the receipt may not have a block number at this point
if (receipt && receipt.blockNumber) {
if (this.lastBlock) {
const block = await this.getBlockByNumber(this.lastBlock.number + 1);
if (block) {
this.lastBlock = block;
this.confirmations++;
this.emitNext(receipt, observer);
}
} else {
this.lastBlock = await this.getBlockByNumber(receipt.blockNumber);
this.confirmations++;
this.emitNext(receipt, observer);
}

if (this.isConfirmed()) {
observer.complete();
clearInterval(interval);
}
}

this.confirmationChecks++;

if (this.isTimeoutTimeExceeded()) {
clearInterval(interval);

this.emitError(
new Error(
'Timeout exceeded during the transaction confirmation process. Be aware the transaction could still get confirmed!'
),
receipt,
observer
);
}
}, 1000);
})
.catch((error) => {
this.emitError(error, false, observer);
});
});
}

/**
* Returns a block by the given blockNumber
*
* @method getBlockByNumber
*
* @param {String} blockNumber
*
* @returns {Promise<Object>}
*/
getBlockByNumber(blockNumber) {
this.getBlockByNumberMethod.parameters = [blockNumber];

return this.getBlockByNumberMethod.execute();
}
}
Loading

0 comments on commit c96a09e

Please sign in to comment.