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

getPastEvents() causes an error if an event has a function as argument #2826

Closed
haltman-at opened this issue May 20, 2019 · 8 comments · Fixed by #3586
Closed

getPastEvents() causes an error if an event has a function as argument #2826

haltman-at opened this issue May 20, 2019 · 8 comments · Fixed by #3586
Labels
1.x 1.0 related issues Bug Addressing a bug

Comments

@haltman-at
Copy link
Contributor

Description

The getPastEvents() function in web3.eth.Contract will cause an error if one of the events has a function external as an argument. (I assume the same problem is present in other similar functions as well.) While I realize it might not be practical at the moment to decode such values, especially as currently you're relying on another package to do the decoding for you, having it cause an error in the whole function is inconvenient because it means one can't get at any of the other events, or, for that matter, the other properties of this event. In short, the error should be localized.

Expected behavior

Instead of causing an error, the function should return as normal, but the returnValues entry for that parameter should be undefined or null or some other way of indicating an error, rather than having the entire function error.

Actual behavior

An error occurs. In my case, doing this from within truffle console, I got the following:

{ Error: invalid type (arg="type", value="function")
    at XMLHttpRequest._onHttpResponseEnd (/home/sniffnoy/truffle/truffle/node_modules/xhr2-cookies/xml-http-request.ts:345:8)
    at XMLHttpRequest._setReadyState (/home/sniffnoy/truffle/truffle/node_modules/xhr2-cookies/xml-http-request.ts:219:8)
    at XMLHttpRequestEventTarget.dispatchEvent (/home/sniffnoy/truffle/truffle/node_modules/xhr2-cookies/xml-http-request-event-target.ts:44:13)
    at XMLHttpRequest.request.onreadystatechange (/home/sniffnoy/truffle/truffle/node_modules/web3/node_modules/web3-providers-http/src/index.js:96:13)
    at /home/sniffnoy/truffle/truffle/packages/truffle-provider/wrapper.js:112:9
    at /home/sniffnoy/truffle/truffle/node_modules/web3-eth-contract/node_modules/web3-core-requestmanager/src/index.js:147:9
    at sendTxCallback (/home/sniffnoy/truffle/truffle/node_modules/web3-eth-contract/node_modules/web3-core-method/src/index.js:473:33)
    at Method.formatOutput (/home/sniffnoy/truffle/truffle/node_modules/web3-eth-contract/node_modules/web3-core-method/src/index.js:159:23)
    at Array.map (<anonymous>)
    at /home/sniffnoy/truffle/truffle/node_modules/web3-eth-contract/node_modules/web3-core-method/src/index.js:160:57
    at Object.Contract._decodeEventABI (/home/sniffnoy/truffle/truffle/node_modules/web3-eth-contract/src/index.js:377:31)
    at ABICoder.decodeLog (/home/sniffnoy/truffle/truffle/node_modules/web3-eth-abi/src/index.js:283:52)
    at ABICoder.decodeParameters (/home/sniffnoy/truffle/truffle/node_modules/web3-eth-abi/src/index.js:229:30)
    at AbiCoder.decode (/home/sniffnoy/truffle/truffle/node_modules/web3-eth-abi/node_modules/ethers/utils/abi-coder.js:901:15)
    at Array.forEach (<anonymous>)
    at AbiCoder.<anonymous> (/home/sniffnoy/truffle/truffle/node_modules/web3-eth-abi/node_modules/ethers/utils/abi-coder.js:910:25)
    at getParamCoder (/home/sniffnoy/truffle/truffle/node_modules/web3-eth-abi/node_modules/ethers/utils/abi-coder.js:862:12)
    at Object.throwError (/home/sniffnoy/truffle/truffle/node_modules/web3-eth-abi/node_modules/ethers/utils/errors.js:68:17)
  reason: 'invalid type',
  code: 'INVALID_ARGUMENT',
  arg: 'type',
  value: 'function' }

Steps to reproduce the behavior

  1. Write a Solidity contract with an event that takes a function external parameter. E.g.:
pragma solidity ^0.5.8;

contract EventsTest {
  event takesFunction(function() external);

  function run() public {
    emit takesFunction(this.run);
  }
}
  1. Deploy the contract, then cause it to emit such an event. (In this case, deploy it and then run run.)
  2. Create a new web3.eth.Contract object for it, and then call that object's getPastEvents method. (Although in my case I was using truffle console and relied on the object created by EventsTest.deployed().)

Error Logs

See above.

Versions

  • web3.js: 1.0.0-beta37
  • nodejs: 10.15.3
  • browser: N/A
  • ethereum node: Ganache 2.0.1
@nivida
Copy link
Contributor

nivida commented May 22, 2019

Thanks for opening this issue! Does this error still occur in the latest version of Web3?

@haltman-at
Copy link
Contributor Author

I'm having some trouble trying to test this manually without Truffle (I'm getting errors from getPastEvents regardless of whether such an event is present or not, and it's not obvious to me why), so it's a little hard to say. That said, skimming the code, I don't see anything that would handle it, so my guess is that it's still there.

@nivida nivida added Needs Clarification Requires additional input and removed more information needed labels May 22, 2019
@haltman-at
Copy link
Contributor Author

By the way, it seems that attempting to decode indexed parameters of reference type (which as we know cannot actually be decoded) can also crash the event decoder. Also worth accounting for, I think.

@sshelton76
Copy link

What could possibly be the use case for passing an external function into an event? I'm genuinely curious.

@nivida nivida added the 1.x 1.0 related issues label Jun 20, 2019
@digulla
Copy link

digulla commented Dec 9, 2019

I have a similar problem when trying to call a contract method which expect a function type/pointer as parameter. See https://ethereum.stackexchange.com/questions/78080/how-do-i-pass-a-function-pointer-to-a-contract-method-from-a-unit-test for a code example.

To see the error, this code is sufficent:

web3.eth.abi.encodeParameter('function', ac.onlyOwner);

where ac is a contract and onlyOwner is a method on that contract.

Is there a way to manually encode the whole function call? Or does that mean I can no longer unit test my code?

@radiant-alex
Copy link

Having same issue with web3.eth.abi.decodeLog(CONTRACT_ABI, evenntdata, eventtopics)
when CONTRACT_ABI has 'function' among types, check the contract 0x57ab1e02fee23774580c119740129eac7081e9d3

@digulla
Copy link

digulla commented Feb 6, 2020

@nivida Does my comment above contain the clarification you asked for?

@nivida
Copy link
Contributor

nivida commented Feb 6, 2020

@digulla Yep, thanks!:)

@nivida nivida added Bug Addressing a bug and removed Needs Clarification Requires additional input labels Feb 6, 2020
@ryanio ryanio mentioned this issue Jul 9, 2020
14 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1.x 1.0 related issues Bug Addressing a bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants