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

Export all events #10996

Merged
merged 1 commit into from
May 3, 2023
Merged

Export all events #10996

merged 1 commit into from
May 3, 2023

Conversation

chriseth
Copy link
Contributor

@chriseth chriseth commented Feb 23, 2021

Fixes #9765.
Fixes #13086.

@chriseth chriseth force-pushed the exportAllEvents branch 3 times, most recently from 63273d5 to 4eb4c5e Compare February 23, 2021 16:46
Changelog.md Outdated Show resolved Hide resolved
libsolidity/ast/AST.h Outdated Show resolved Hide resolved
@chriseth
Copy link
Contributor Author

Updated.

solAssert(annotation().creationCallGraph.set() == annotation().deployedCallGraph.set(), "");
if (annotation().creationCallGraph.set())
{
unfilteredEvents += (*annotation().creationCallGraph)->emittedEvents;
Copy link
Member

Choose a reason for hiding this comment

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

Not entirely sure if events emitted during creation should be part of this. Is it something that contracts actually do?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why shouldn't they? My intention was to include all events that can originate from this address (and which are not caused by a delegatecall).

libsolidity/ast/AST.cpp Outdated Show resolved Hide resolved
libsolidity/ast/ASTJsonConverter.cpp Outdated Show resolved Hide resolved
solAssert(function, "");
if (!function->interfaceFunctionType() && _ignoreErrors)
continue;
string eventSignature = function->externalSignature();
Copy link
Member

Choose a reason for hiding this comment

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

I think this would cause issues when in the following case:

  library L {
	  event e1(uint b);
  }

  function f() {
	  emit L.e1(5);
  }

  contract C {
	  event e1(uint indexed a);
	  function g() public {
		  f();
	  }
  }

Because the signature does not contain "indexed".

The ABI for this test case is:

[
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "a",
        "type": "uint256"
      }
    ],
    "name": "e1",
    "type": "event"
  },
  {
    "inputs": [],
    "name": "g",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  }
]

Which doesn't contain the library event.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We have the same problem during inheritance. Let me see what I can do.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I actually don't know why we do this filtering at all. Events can be overloaded but defining two events with the same name and parameter types in an inheritance hierarchy is an error anyway.

@chriseth
Copy link
Contributor Author

We ignore errors in #10996 (comment) because the ast can be exported for not fully valid source code.

@chriseth
Copy link
Contributor Author

chriseth commented Mar 1, 2021

Updated.

@chriseth chriseth force-pushed the exportAllEvents branch 2 times, most recently from 7e97630 to ddff575 Compare March 3, 2021 14:47
libsolidity/ast/ASTJsonConverter.cpp Outdated Show resolved Hide resolved
libsolidity/ast/AST.cpp Outdated Show resolved Hide resolved
@chriseth chriseth force-pushed the exportAllEvents branch 4 times, most recently from 4eadaf0 to f9ebbff Compare March 9, 2021 16:06
set<string> eventsSeen;
vector<EventDefinition const*> interfaceEvents;

std::set<EventDefinition const*, ASTNode::CompareByID> interfaceEvents;
Copy link
Member

Choose a reason for hiding this comment

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

In this example,

  library L1 {
	  event e();
  }

  library L2 {
	  event e();
  }

  contract C {
	  function f() public {
		  emit L1.e();
		  emit L2.e();
	  }
  }

The event e would be repeated twice. Technically, only one is enough. Maybe repetition in the abi would be an issue for front ends. Another example would be a contract having the same event as a library.

If you want, we can probably merge this already and potentially fix this issue later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is two different events. I think it's good to list multiple events. We could filter, but hm.

Copy link
Member

@hrkrshnn hrkrshnn Mar 9, 2021

Choose a reason for hiding this comment

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

Aren't they the same log from EVM's perspective? There is nothing distinguishing about them, is 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.

Yeah, maybe you are right. But I would propose to filter them at a different place.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll filter them if the json is exactly the same. If there is a difference e.g. in parameter names, then both will stay.

@hrkrshnn
Copy link
Member

About the NatSpec issue:

Concatenating the NatSpec of events with same signature sounds good.

There is this edge case, which should be two different events in the NatSpec, but ends up being the same since we omit the "indexed" part from signature.

library L {
    /// library
    event E(uint indexed a);
}
contract  C {
    constructor() {
        emit L.E(1);
    }
    /// contract
    event E(uint a);
}

@hrkrshnn
Copy link
Member

Also, web3.py seems to throw an error when accessing an event with name E if there are multiple events with name E in the ABI. Makes me wonder if we should disallow events with the same name, even though at EVM level they make sense.

@chriseth
Copy link
Contributor Author

Actually concatenating natspec does not really work. Do we concatenate the values of all the different fields? What if the parameters have different names?

cameel
cameel previously approved these changes Apr 28, 2023
Copy link
Member

@cameel cameel left a comment

Choose a reason for hiding this comment

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

Ok, now it looks good!

I have a small simplification suggestion for event processing, but other than that, I think we're finally done here.

libsolidity/interface/Natspec.cpp Outdated Show resolved Hide resolved
@cameel
Copy link
Member

cameel commented Apr 28, 2023

Please squash review fixes into the commits.

@matheusaaguiar
Copy link
Collaborator

There are these two pending questions/comments:

The first one, I didn't quite understand, I guess it is about events emitted in private/internal functions ?
The second one I am working on it.

@cameel
Copy link
Member

cameel commented Apr 29, 2023

We'd need to ask @chriseth about the comment, I think he's the one who wrote it. Would be best to find out, because it's confusing, but it's not serious enough to block the PR.

Asserts are also just nice to have. They shouldn't be anything elaborate. Only things you can check fairly easily without writing lots of support code that's not used for anything else.

cameel
cameel previously approved these changes Apr 29, 2023
Copy link
Member

@cameel cameel left a comment

Choose a reason for hiding this comment

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

The extra tweaks we discussed would be nice but I'm also already approving since they're not important enough to block merging the PR.

@matheusaaguiar
Copy link
Collaborator

matheusaaguiar commented Apr 29, 2023

The extra tweaks we discussed would be nice but I'm also already approving since they're not important enough to block merging the PR.

Ok. I just added the asserts in a different commit so they can be removed if we want to merge the PR without them.
Also, I thought that events could not be emitted from inherited interfaces. I was not sure so I added some tests about that.

Changelog.md Outdated Show resolved Hide resolved
@@ -485,6 +485,411 @@ BOOST_AUTO_TEST_CASE(event)
checkNatspec(sourceCode, "ERC20", userDoc, true);
}

BOOST_AUTO_TEST_CASE(emit_same_signature_event_library_contract)
Copy link
Member

Choose a reason for hiding this comment

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

Just for future reference: this is beyond the amount of hand-crafted cpp boost test cases, s.t. I'd have transitioned this stuff to nicer isoltest tests. But since we have them now like this, it's fine and we can keep them here. But yeah: general policy: more than one test of a few lines like this we should already think about adding a new isoltest test kind - the infrastructure for adding simple ones there is rather convenient these days.

Update tests.

Additional tests

Revert changes to the Natspec
@matheusaaguiar
Copy link
Collaborator

Rebased and squashed commits.

* Antlr Grammar: Fix discrepancy with the parser, which allowed octal numbers.
* Antlr Grammar: Fix of a discrepancy with the parser, which allowed numbers followed by an identifier with no whitespace.
* Antlr Grammar: Stricter rules for function definitions. The grammar will no longer accept as valid free functions having specifiers which are exclusive to contract functions.
* SMTChecker: Fix false positives in ternary operators that contain verification targets in its branches, directly or indirectly.


AST Changes:
* AST: add the ``internalFunctionID`` field to the AST nodes of functions that may be called via the internal dispatch. These IDs are always generated, but they are only used in via-IR code generation.
* AST: Add the ``internalFunctionID`` field to the AST nodes of functions that may be called via the internal dispatch. These IDs are always generated, but they are only used in via-IR code generation.
Copy link
Member

Choose a reason for hiding this comment

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

Why is this line showing up in the diff by the way? Not sure if I'm blind, but I don't see any change in it...

Copy link
Collaborator

@matheusaaguiar matheusaaguiar May 3, 2023

Choose a reason for hiding this comment

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

Capitalized A in Add at the beginning of the sentence... had to look a dozen of times to spot it :)

Copy link
Member

Choose a reason for hiding this comment

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

Haha, lol - but that's also a bug in github - it usually highlights the actual change, here it doesn't :-)

Copy link
Member

@ekpyron ekpyron left a comment

Choose a reason for hiding this comment

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
selected for development It's on our short-term development
Projects
Archived in project