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

Executing of a state changing method with "method.call()" #2617

Merged
merged 8 commits into from
Apr 1, 2019
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
8 changes: 4 additions & 4 deletions packages/web3-core-method/src/proxy/MethodProxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,21 @@ export default class MethodProxy {
const method = methodFactory.createMethod(name, target);

/* eslint-disable no-inner-declarations */
function anonymousFunction() {
function RpcMethod() {
method.setArguments(arguments);

return method.execute();
}
/* eslint-enable no-inner-declarations */

anonymousFunction.method = method;
anonymousFunction.request = function() {
RpcMethod.method = method;
RpcMethod.request = function() {
method.setArguments(arguments);

return method;
};

return anonymousFunction;
return RpcMethod;
}

return target[name];
Expand Down
17 changes: 0 additions & 17 deletions packages/web3-eth-contract/src/models/AbiItemModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,6 @@ export default class AbiItemModel {
this.contractMethodParameters = [];
}

/**
* Getter for the requestType of this ABI item.
*
* @property requestType
*
* @returns {String}
*/
get requestType() {
if (this.abiItem.type === 'function' || this.abiItem.type === 'constructor') {
if (this.abiItem.constant === true) {
return 'call';
}

return 'send';
}
}

/**
* TODO: rename getInputLength to getInputsLength
* Returns the input length of the abiItem
Expand Down
42 changes: 22 additions & 20 deletions packages/web3-eth-contract/src/proxies/MethodsProxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,10 @@ export default class MethodsProxy {
get: (target, name) => {
if (this.contract.abiModel.hasMethod(name)) {
let abiItemModel = this.contract.abiModel.getMethod(name);
let requestType = abiItemModel.requestType;

// TODO: Improve the requestType detection and defining of the call/send method.
if (isArray(abiItemModel)) {
requestType = abiItemModel[0].requestType;
}

// TODO: Find a better solution for the handling of the contractMethodParameters
/* eslint-disable no-inner-declarations */
function anonymousFunction() {
function ContractMethod() {
let methodArguments = [...arguments];

// Because of the possibility to overwrite the contract data if I call contract.deploy()
Expand All @@ -80,12 +74,12 @@ export default class MethodsProxy {
abiItemModel.contractMethodParameters = methodArguments[0]['arguments'];
}

return anonymousFunction;
return ContractMethod;
}

abiItemModel.contractMethodParameters = [];

return anonymousFunction;
return ContractMethod;
}

// If there exists more than one method with this name then find the correct abiItemModel
Expand All @@ -107,30 +101,38 @@ export default class MethodsProxy {

abiItemModel.contractMethodParameters = methodArguments;

return anonymousFunction;
return ContractMethod;
}

anonymousFunction[requestType] = function() {
ContractMethod.call = function() {
return target.executeMethod(abiItemModel, arguments, 'call');
};

ContractMethod.send = function() {
if (abiItemModel.isOfType('constructor')) {
return target.executeMethod(abiItemModel, arguments, 'contract-deployment');
}

return target.executeMethod(abiItemModel, arguments, requestType);
return target.executeMethod(abiItemModel, arguments, 'send');
};

ContractMethod.call.request = function() {
return target.createMethod(abiItemModel, arguments, 'call');
};

anonymousFunction[requestType].request = function() {
return target.createMethod(abiItemModel, arguments, requestType);
ContractMethod.send.request = function() {
return target.createMethod(abiItemModel, arguments, 'send');
};

anonymousFunction.estimateGas = function() {
ContractMethod.estimateGas = function() {
return target.executeMethod(abiItemModel, arguments, 'estimate');
};

anonymousFunction.encodeABI = function() {
ContractMethod.encodeABI = function() {
return target.methodEncoder.encode(abiItemModel, target.contract.data);
};

return anonymousFunction;
return ContractMethod;
/* eslint-enable no-inner-declarations */
}

Expand Down Expand Up @@ -184,7 +186,7 @@ export default class MethodsProxy {
* @returns {AbstractMethod}
*/
createMethod(abiItemModel, methodArguments, requestType) {
// Get correct rpc method model
// Get correct method class
const method = this.methodFactory.createMethodByRequestType(abiItemModel, this.contract, requestType);
method.setArguments(methodArguments);

Expand All @@ -196,10 +198,10 @@ export default class MethodsProxy {
// Encode contract method
method.parameters[0]['data'] = this.methodEncoder.encode(abiItemModel, this.contract.data);

// Set default options in the TxObject if required
// Set default options in the transaction object if required
method.parameters[0] = this.methodOptionsMapper.map(this.contract, method.parameters[0]);

// Validate TxObject
// Validate transaction object
this.methodOptionsValidator.validate(abiItemModel, method);

return method;
Expand Down
12 changes: 0 additions & 12 deletions packages/web3-eth-contract/tests/src/models/AbiItemModelTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,6 @@ describe('AbiItemModelTest', () => {
expect(abiItemModel.abiItem).toEqual(abiItem);
});

it('gets the requestType property of the AbiItemModel and it returns the value "send"', () => {
abiItem.constant = false;

expect(abiItemModel.requestType).toEqual('send');
});

it('gets the requestType property of the AbiItemModel and it returns the value "call"', () => {
abiItem.constant = true;

expect(abiItemModel.requestType).toEqual('call');
});

it('calls getInputLength and returns "0" because inputs is not of type array', () => {
expect(abiItemModel.getInputLength()).toEqual(0);
});
Expand Down
47 changes: 34 additions & 13 deletions packages/web3-eth-contract/tests/src/proxies/MethodsProxyTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ describe('MethodsProxyTest', () => {
});

it('calls a call method over the proxy', async () => {
abiItemModelMock.requestType = 'call';

abiModelMock.hasMethod.mockReturnValueOnce(true);

abiModelMock.getMethod.mockReturnValueOnce(abiItemModelMock);
Expand Down Expand Up @@ -118,8 +116,6 @@ describe('MethodsProxyTest', () => {
});

it('calls the constructor method over the proxy', async () => {
abiItemModelMock.requestType = 'send';

abiModelMock.hasMethod.mockReturnValueOnce(true);

abiModelMock.getMethod.mockReturnValueOnce(abiItemModelMock);
Expand Down Expand Up @@ -169,8 +165,6 @@ describe('MethodsProxyTest', () => {
});

it('calls a method that exists with different arguments over the proxy', async () => {
abiItemModelMock.requestType = 'send';

abiItemModelMock.getInputLength.mockReturnValueOnce(1);

abiModelMock.hasMethod.mockReturnValueOnce(true);
Expand Down Expand Up @@ -214,8 +208,6 @@ describe('MethodsProxyTest', () => {
});

it('calls a method that exists with different arguments but with a invalid arguments length and throws an error', async () => {
abiItemModelMock.requestType = 'send';

abiItemModelMock.givenParametersLengthIsValid = jest.fn(() => {
throw new Error('ERROR');
});
Expand Down Expand Up @@ -264,9 +256,7 @@ describe('MethodsProxyTest', () => {
expect(method.setArguments).toHaveBeenCalledWith([true]);
});

it('calls the request method on a contract method and returns the expect AbstractMethod object', () => {
abiItemModelMock.requestType = 'call';

it('calls the request method on a contract call method and returns the expect AbstractMethod object', () => {
abiModelMock.hasMethod.mockReturnValueOnce(true);

abiModelMock.getMethod.mockReturnValueOnce(abiItemModelMock);
Expand Down Expand Up @@ -299,9 +289,40 @@ describe('MethodsProxyTest', () => {
expect(methodOptionsValidatorMock.validate).toHaveBeenCalledWith(abiItemModelMock, callMethodMock);
});

it('calls the estimateGas method on a contract method and returns the expect value', async () => {
abiItemModelMock.requestType = 'call';
it('calls the request method on a contract send method and returns the expect AbstractMethod object', () => {
abiModelMock.hasMethod.mockReturnValueOnce(true);

abiModelMock.getMethod.mockReturnValueOnce(abiItemModelMock);

const callMethodMock = {};
callMethodMock.parameters = [{}];
callMethodMock.setArguments = jest.fn();
callMethodMock.execute = jest.fn();

methodFactoryMock.createMethodByRequestType.mockReturnValueOnce(callMethodMock);

methodEncoderMock.encode.mockReturnValueOnce('0x0');

methodOptionsMapperMock.map.mockReturnValueOnce({options: true});

expect(methodsProxy.myMethod(true).send.request({options: false})).toEqual(callMethodMock);

expect(methodFactoryMock.createMethodByRequestType).toHaveBeenCalledWith(
abiItemModelMock,
contractMock,
'send'
);

expect(callMethodMock.parameters[0]).toEqual({options: true});

expect(methodEncoderMock.encode).toHaveBeenCalledWith(abiItemModelMock, contractMock.data);

expect(methodOptionsMapperMock.map).toHaveBeenCalledWith(contractMock, {data: '0x0'});

expect(methodOptionsValidatorMock.validate).toHaveBeenCalledWith(abiItemModelMock, callMethodMock);
});

it('calls the estimateGas method on a contract method and returns the expect value', async () => {
abiModelMock.hasMethod.mockReturnValueOnce(true);

abiModelMock.getMethod.mockReturnValueOnce(abiItemModelMock);
Expand Down