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

Transaction confirmation workflow improvements #2466

Merged
merged 91 commits into from
Mar 14, 2019
Merged
Show file tree
Hide file tree
Changes from 57 commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
5225a1a
transaction confirmation and signing logic moved to the Eth module, c…
Mar 4, 2019
e2d1b70
transaction confirmation and signing logic moved to the Eth module, c…
Mar 4, 2019
2407b9e
POC TransactionObserver
Mar 4, 2019
b8d4d72
parameters for the execute method updated
Mar 4, 2019
c456be2
Dependency handling of AbstractWeb3Module updated because of the remo…
Mar 4, 2019
717133c
last exposed factory from the web3 core removed. I've changed this be…
Mar 4, 2019
5a9bf13
AbstractObservedSendTransactionMethod renamed and updated for using t…
Mar 4, 2019
ff688d1
TransactionObserver POC
Mar 4, 2019
69b4d96
TransactionObserver updated
Mar 4, 2019
58169b3
TransactionObserver updated
Mar 4, 2019
4a38fb5
methods in Eth module updated
Mar 4, 2019
bc2f034
MethodFactory in eth-module updated
Mar 4, 2019
108270e
code style and other improvements in the eth-module
Mar 4, 2019
5746996
Dependecy handling updated
Mar 4, 2019
1ff399e
eslint executed and errors fixed
Mar 4, 2019
bfc7500
import updated in MethodFactory of the eth module
Mar 4, 2019
39b13f3
PromiEvent moved to core module
Mar 4, 2019
331b1ce
Merge branch '1.0' into enhacement/transaction-confirmations
Mar 5, 2019
c831d66
Merge branch '1.0' into enhacement/transaction-confirmations
Mar 6, 2019
53c442b
custom eth block methods logic moved to eth module for having a clear…
Mar 6, 2019
0de7249
custom eth method names improved
Mar 6, 2019
3efd3cc
methods checked and GetTransactionFromBlockMethod implemented in the …
Mar 6, 2019
ff0345c
exports updated in core-method module
Mar 6, 2019
e2efecc
TransactionObserver updated
Mar 6, 2019
43e7933
eslint executed and errors fixed
Mar 6, 2019
efc0798
build fixed
Mar 6, 2019
459d954
eth-contract dependencies fixed
Mar 6, 2019
2f44666
dependency handling fixed
Mar 6, 2019
518e542
TranasctionObserver with contract deployment tested and fixed
Mar 7, 2019
b0a2edd
MethodFactory in Eth module updated and TransactionObserver fixed
Mar 7, 2019
1d56911
TransactionObserver startSocketObserver method updated
Mar 7, 2019
53030b5
beforeExecution added to ObservedSendTransactionmethod
Mar 7, 2019
cd0f8a1
dependency handling checked and fixed
Mar 7, 2019
6824591
startSocketObserver updated for chain reorg in TransactionObserver
Mar 7, 2019
afc6920
unsused method removed, dependency removed and wrongly used method up…
Mar 7, 2019
863bb83
subscription and error handling of TransactionObserver improved
Mar 7, 2019
fc7c85c
error message updated
Mar 7, 2019
aab8b01
TransactionObserver improved
Mar 7, 2019
884fc8e
options handling of eth.Contract improved, dependency handling update…
Mar 7, 2019
dd9ed3c
naming fixed
Mar 7, 2019
f8f8a64
AbstractMethodFactoryTest updated, package.json depeendencies updated…
Mar 7, 2019
357800c
AbstractMethodTest updated
Mar 7, 2019
5464143
block methods tests updated in core-method module
Mar 8, 2019
597154c
transaction methods structure simplified
Mar 8, 2019
08bc754
imports updated in eth modules and parameters length validation move…
Mar 8, 2019
705ac24
promiEvent handling improved
Mar 11, 2019
d987b88
AbstractObservedTransactionMethod and the related test updated
Mar 11, 2019
103520e
AbstractGetTransactionFromBlockMethodTest created
Mar 11, 2019
01842e5
method tests updated in core-method module
Mar 11, 2019
3c64591
MethodProxyTest updated
Mar 11, 2019
f984315
TransactionReceiptValidator removed and logic moved to AbstractObserv…
Mar 11, 2019
dbcf3f5
TransactionObserver updated and AbstractObservedTransactionMethod imp…
Mar 11, 2019
e197457
AbstractMethodFactory, AbstractObservedTransactionMethod, EthSendTran…
Mar 11, 2019
f92c288
static getter with name 'Type' added for a better detection of the ty…
Mar 11, 2019
f249067
dependency handing updated in the eth-contract module
Mar 11, 2019
6c791bb
AbstractObservedTransactionMethodTest updated
Mar 11, 2019
09ae3fd
stop method removed because of the o'bserver.closed' property
Mar 11, 2019
b8f4d9c
TransactionObserver test created
Mar 12, 2019
6be4975
code style fixes and AbstractMethodFactoryTest updated. The core-meth…
Mar 12, 2019
619228a
contract deployment and calling of methods tested and fixed
Mar 12, 2019
f31c372
core module tests updated
Mar 12, 2019
3b7d739
Shh module tests upddated
Mar 13, 2019
09b50ea
EthSendTransactionMethodTest created in core-method module
Mar 13, 2019
e7f1b01
method tests updated in eth module
Mar 13, 2019
826d5e4
EthTest updated and MethodFactoryTest created
Mar 13, 2019
3513aba
eth module tests updated
Mar 13, 2019
3646b16
naming of the AbstractGetUncleMethod class in fixed
Mar 13, 2019
a01f856
eslint-plugin-jest updated and eslint executed
Mar 13, 2019
6d605cf
AbstractWeb3ModuleTest updated
Mar 13, 2019
3e6a89f
test case added to AbstractWeb3ModuleTest
Mar 13, 2019
e6907de
net module tests updated
Mar 13, 2019
56e642b
eth-accounts tests updated
Mar 13, 2019
f5bf42e
eth-personal module tests updated
Mar 13, 2019
1a0f8aa
code style improvements
Mar 13, 2019
3d8ae8e
MethodsProxyTest updated and athe accsessors for the arguments proper…
Mar 13, 2019
f4b4920
factory tests updated in eth-contract module
Mar 13, 2019
870716b
eth-contract methods tests updated
Mar 13, 2019
f39b189
code style improvements and AbiItemModelTest updated
Mar 13, 2019
46c9e62
AbstractMethodTest updated
Mar 13, 2019
87286dc
ens module tests updated
Mar 14, 2019
0d83389
Web3 class updated for the new ProviderDetector
Mar 14, 2019
ebba124
code style and jest config improved
Mar 14, 2019
1c30a5e
types updated
Mar 14, 2019
988e402
Merge branch '1.0' into enhacement/transaction-confirmations
Mar 14, 2019
346f159
code tested, eslintignore updated and package.json updated
Mar 14, 2019
cd608d4
dtslint dependency fixed
Mar 14, 2019
7409d6e
parsimon removed from root package.json and travis.yml updated
Mar 14, 2019
408a68d
duplicated env in travis.yml removed
Mar 14, 2019
1a77830
lerna bootstrap command updated in package.json with '--hoist'
Mar 14, 2019
54d3cd6
dtslint version in web3-providers package updated and 'npm ci' change…
Mar 14, 2019
ecef7a8
hoist removed from lerna bootstrap and dtslint downgraded
Mar 14, 2019
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
1 change: 0 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ const config = {
transform: {
'^.+\\.js$': '<rootDir>/../../jest.preprocessor.js'
},
transformIgnorePatterns: ['node_modules/(?!(underscore-es)/)'],
bail: true
};

Expand Down
202 changes: 101 additions & 101 deletions packages/web3-bzz/package-lock.json

Large diffs are not rendered by default.

91 changes: 0 additions & 91 deletions packages/web3-core-method/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,97 +10,6 @@ The Method module abstracts the JSON-RPC method and is used within most [web3.js
npm install web3-core-method
```

## Exported classes

``` js
MethodModuleFactory
AbstractMethod
AbstractMethodFactory

/**
* Methods
*/

// Network
GetProtocolVersionMethod
VersionMethod
ListeningMethod
PeerCountMethod

// Node
GetNodeInfoMethod
GetCoinbaseMethod
IsMiningMethod
GetHashrateMethod
IsSyncingMethod
GetGasPriceMethod
SubmitWorkMethod
GetWorkMethod

// Account
GetAccountsMethod
GetBalanceMethod
GetTransactionCountMethod
RequestAccountsMethod

// Block
GetBlockNumberMethod
GetBlockMethod
GetUncleMethod
GetBlockTransactionCountMethod
GetBlockUncleCountMethod

// Transaction
GetTransactionMethod
GetTransactionFromBlockMethod
GetTransactionReceipt
SendRawTransactionMethod
SignTransactionMethod
SendTransactionMethod

// Global
GetCodeMethod
SignMethod
CallMethod
GetStorageAtMethod
EstimateGasMethod
GetPastLogsMethod

// Personal
EcRecoverMethod
ImportRawKeyMethod
ListAccountsMethod
LockAccountMethod
NewAccountMethod
PersonalSendTransactionMethod
PersonalSignMethod
PersonalSignTransactionMethod
UnlockAccountMethod

// SHH
AddPrivateKeyMethod
AddSymKeyMethod
DeleteKeyPairMethod
DeleteMessageFilterMethod
DeleteSymKeyMethod
GenerateSymKeyFromPasswordMethod
GetFilterMessagesMethod
GetInfoMethod
GetPrivateKeyMethod
GetPublicKeyMethod
GetSymKeyMethod
HasKeyPairMethod
HasSymKeyMethod
MarkTrustedPeerMethod
NewKeyPairMethod
NewMessageFilterMethod
NewSymKeyMethod
PostMethod
SetMaxMessageSizeMethod
SetMinPoWMethod
ShhVersionMethod
```

## Types

All the typescript typings are placed in the types folder.
Expand Down
3 changes: 0 additions & 3 deletions packages/web3-core-method/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,5 @@ module.exports = jestConfig({
'AbstractWeb3Module': 'web3-core',
'Utils': 'web3-utils',
'formatters': 'web3-core-helpers',
'PromiEvent': 'web3-core-promievent',
'Subscription': 'web3-core-subscriptions',
'SubscriptionsFactory': 'web3-core-subscriptions',
'AbstractSubscription': 'web3-core-subscriptions'
});
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@
*/
/**
* @file PromiEvent.js
* @author Samuel Furter <samuel@ethereum.org>
* @author Fabian Vogelsteller <fabian@ethereum.org>, Samuel Furter <samuel@ethereum.org>
* @date 2018
*/

import EventEmitter from 'eventemitter3';

// TODO: Remove this module and use the EventEmitter or Promise separately. This kind of object could be implemented in
// TODO: the AbstractSendMethod. I think the better way would be a API with just Observable and Promise objects.
// TODO: add handleSuccess() and handleError() method instead of having them in the send method class
export default class PromiEvent {
/**
* @constructor
Expand Down
61 changes: 30 additions & 31 deletions packages/web3-core-method/lib/factories/AbstractMethodFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,19 @@
* @date 2018
*/

import SendRawTransactionMethod from '../../src/methods/transaction/SendRawTransactionMethod';
import GetTransactionCountMethod from '../../src/methods/account/GetTransactionCountMethod';
import ChainIdMethod from '../../src/methods/network/ChainIdMethod';
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';

export default class AbstractMethodFactory {
/**
* @param {MethodModuleFactory} methodModuleFactory
* @param {Utils} utils
* @param {Object} formatters
*
* @constructor
*/
constructor(methodModuleFactory, utils, formatters) {
this.methodModuleFactory = methodModuleFactory;
constructor(utils, formatters) {
this.utils = utils;
this.formatters = formatters;
this._methods = null;
Expand Down Expand Up @@ -79,41 +78,41 @@ export default class AbstractMethodFactory {
}

/**
* TODO: Find a cleaner way for the dependency resolution here.
*
* Returns an MethodModel
*
* @param {String} name
* @param {AbstractWeb3Module} moduleInstance
*
* @returns {AbstractMethod}
*/
createMethod(name) {
createMethod(name, moduleInstance) {
const method = this.methods[name];

/* eslint-disable new-cap */
switch (method.Type) {
case 'CALL':
return new method(this.utils, this.formatters);
case 'SEND':
if (method.name === 'SendTransactionMethod') {
const transactionConfirmationWorkflow = this.methodModuleFactory.createTransactionConfirmationWorkflow();
if (method.Type === 'observed-transaction-method') {
let timeout = moduleInstance.transactionBlockTimeout;
const providerName = moduleInstance.currentProvider.constructor.name;

return new method(
this.utils,
this.formatters,
transactionConfirmationWorkflow,
new SendRawTransactionMethod(this.utils, this.formatters, transactionConfirmationWorkflow),
new ChainIdMethod(this.utils, this.formatters),
new GetTransactionCountMethod(this.utils, this.formatters)
);
}
if (providerName === 'HttpProvider' || providerName === 'CustomProvider') {
timeout = moduleInstance.transactionPollingTimeout;
}

return new method(
this.utils,
this.formatters,
this.methodModuleFactory.createTransactionConfirmationWorkflow()
);
// eslint-disable-next-line new-cap
return new method(
this.utils,
this.formatters,
moduleInstance,
new TransactionObserver(
moduleInstance.currentProvider,
timeout,
moduleInstance.transactionConfirmationBlocks,
new GetTransactionReceiptMethod(this.utils, this.formatters, moduleInstance),
new GetBlockByNumberMethod(this.utils, this.formatters, moduleInstance),
new NewHeadsSubscription(this.utils, this.formatters, moduleInstance)
)
);
}
/* eslint-enable new-cap */

// eslint-disable-next-line new-cap
return new method(this.utils, this.formatters, moduleInstance);
}
}
51 changes: 42 additions & 9 deletions packages/web3-core-method/lib/methods/AbstractMethod.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,21 @@
import isFunction from 'lodash/isFunction';
import isString from 'lodash/isString';
import cloneDeep from 'lodash/cloneDeep';
import {PromiEvent} from 'web3-core-promievent';

export default class AbstractMethod {
/**
* @param {String} rpcMethod
* @param {Number} parametersAmount
* @param {Utils} utils
* @param {Object} formatters
* @param {AbstractWeb3Module} moduleInstance
*
* @constructor
*/
constructor(rpcMethod, parametersAmount, utils, formatters) {
constructor(rpcMethod, parametersAmount, utils, formatters, moduleInstance) {
this.utils = utils;
this.formatters = formatters;
this.promiEvent = new PromiEvent();
this.moduleInstance = moduleInstance;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it's not my place to ask, but wouldn't this add a copy of the module to all methods? I haven't tested this branch, but instead of copying the whole module instance, perhaps modules could have a concrete moduleInstance.config? (I don't remember the full structure of the package, but this might also avoid circular references somewhere unexpected.)

Maybe this is preemptive optimization, but I thought I'd put it out there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The garbage collector of JS will collect and remove the AbstractMethod after the execution of the method. The AbstractMethod classes will be created in the MethodProxy when a declared method gets called. It will not copy the moduleInstance each time. It will just set the reference of the pointer. This means this.moduleInstance is just a "symlink" to the actual object.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I wasn't sure if the moduleInstance would end up as a pointer or as a copy. It only takes one random line referencing the object to end up allocated till unmounting.

Copy link

@OFRBG OFRBG Mar 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bildschirmfoto 2019-03-11 um 22 05 04

Maybe it works directly with the ES6 structure, but the .umd.js files don't seem to be correctly collected. Maybe for this release working on the .umd.js transpiler settings would be beneficial. The image above is taken from the (semi-)production build of the getBlock example with webpack. https://codesandbox.io/s/0ykmkv2380

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the actual production build heap snapshot after some digging. I've tested the .umd.js every now and then and its behavior strays quite a bit from its .esm.js counterpart.

Bildschirmfoto 2019-03-11 um 22 43 14

Copy link
Contributor Author

@nivida nivida Mar 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are still some points I could optimize the memory usage and other stuff. But I will do this later because I've already broken the heap snapshot down from ~550mb to ~280mb. Thanks for your tests! :-)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry if I came across as pedantic. What worries me overall is that the
transpiling to browser JS might end up having unexpected behavior. Every
now and then it happens to me that the ES6 or CJS code works but the
browser code doesn't. Probably not a pressing issue, but something I'd
avoid neglecting since the package is widely used client-side, but the
tests don't strictly cover it.

this._arguments = {
parameters: []
};
Expand Down Expand Up @@ -68,15 +68,42 @@ export default class AbstractMethod {
}

/**
* Checks which command should be executed
* Sends a JSON-RPC call request
*
* @method execute
*
* @param {AbstractWeb3Module} moduleInstance
*
* @returns {Promise<Object|String>|PromiEvent|String}
* @callback callback callback(error, result)
* @returns {Promise<Object|String>}
*/
execute(moduleInstance) {}
async execute() {
this.beforeExecution(this.moduleInstance);

if (this.parameters.length !== this.parametersAmount) {
throw new Error(
`Invalid Arguments length: expected: ${this.parametersAmount}, given: ${this.parameters.length}`
);
}

try {
let response = await this.moduleInstance.currentProvider.send(this.rpcMethod, this.parameters);

if (response) {
response = this.afterExecution(response);
}

if (this.callback) {
this.callback(false, response);
}

return response;
} catch (error) {
if (this.callback) {
this.callback(error, null);
}

throw error;
}
}

/**
* Setter for the rpcMethod property
Expand Down Expand Up @@ -189,6 +216,12 @@ export default class AbstractMethod {
callback,
parameters
};

if (this.parameters.length !== this.parametersAmount) {
throw new Error(
`Invalid Arguments length: expected: ${this.parametersAmount}, given: ${this.parameters.length}`
);
}
}

/**
Expand All @@ -212,6 +245,6 @@ export default class AbstractMethod {
* @returns {Boolean}
*/
isHash(parameter) {
return isString(parameter) && parameter.indexOf('0x') === 0;
return isString(parameter) && parameter.startsWith('0x');
}
}
Loading