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

feat: add logs, add log dynamic decoding #271

Merged
merged 5 commits into from
Oct 3, 2023
Merged

feat: add logs, add log dynamic decoding #271

merged 5 commits into from
Oct 3, 2023

Conversation

DaniPopes
Copy link
Member

@DaniPopes DaniPopes commented Sep 15, 2023

Motivation

Closes #210

Common Log structure

Solution

  • Add Log structure
  • Dynamic coding support and add EventExt trait

PR Checklist

  • Added Tests
  • Added Documentation
  • Breaking changes

Copy link
Member

@prestwich prestwich left a comment

Choose a reason for hiding this comment

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

1 change, a couple interface ideas/questions

)]
pub struct Log {
/// The indexed topic list.
pub topics: Vec<B256>,
Copy link
Member

Choose a reason for hiding this comment

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

pub allows for construction of invalid logs with 5+ topics

Copy link
Member Author

Choose a reason for hiding this comment

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

Skill issue

Copy link
Member

Choose a reason for hiding this comment

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

types exist to solve skill issues :P

Copy link
Member

Choose a reason for hiding this comment

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

i would agree we can add getters instead

Copy link
Member Author

Choose a reason for hiding this comment

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

They might be invalid in EVM, but we can use invalid states for testing and maybe other usecases in the futures. I don't think we should lock ourselves into using arrays since it doesn't really improve anything, might be even worse by bloating the stack size of one log to 160 bytes or more. If you box it well you're back to a vec basically

@@ -151,4 +151,9 @@ pub trait SolEvent: Sized {
let body = Self::decode_data(data, validate)?;
Ok(Self::new(topics, body))
}

Copy link
Member

Choose a reason for hiding this comment

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

hot take. We should consider #[doc(hide)] all the trait methods that do not operate on &Log or output Log, as users should generally not use them directly

Copy link
Member Author

Choose a reason for hiding this comment

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

They should because Log can't borrow data while the other can

/// Provides event encoding and decoding for the [`Event`] type.
///
/// This trait is sealed and cannot be implemented for types outside of this
/// crate. It is implemented only for [`Event`].
Copy link
Member

Choose a reason for hiding this comment

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

Should this be a Resolve like interface that outputs a DynEvent and then uses that to (en/de)code?

Copy link
Member Author

Choose a reason for hiding this comment

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

The only thing it would do is resolve the types, I don't think so

Copy link
Member

Choose a reason for hiding this comment

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

i guess this is a question of how we conceptualize dyn-abi. if it has the same scope as sol-types then we should have dyn equivalents to everything in sol-types

the original idea was to have a runtime representation that was format-independent, and then be able to convert JSON or solidity lines, or type strings to the runtime representation. we're now kinda mixing that, where some things are resolved to the runtime repr, and some aren't. which leads to a somewhat weird API

Copy link
Member

@prestwich prestwich Sep 15, 2023

Choose a reason for hiding this comment

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

or for a concrete thing, if we do this as an ext trait then we duplicate code across these two impls

impl EventExt for Event {}
impl EventExt for syn_solidity::ItemEvent {}

I would prefer something like this to avoid duplication and move all coding through a specific runtime repr

trait ResolveEvent {
    fn resolve(&self) -> DynEvent
}

impl ResolveEvent for JsonEvent {}
impl ResolveEvent for syn_soldity::ItemEvent {}

Copy link
Member

@gakonst gakonst left a comment

Choose a reason for hiding this comment

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

supportive w/o many opinions beyond maybe providing a LogMeta-style type which may include more information? e.g. thinking Revm addresses, thinking how in ethers-providers we returned logs w/ txhashes etc. in them

)]
pub struct Log {
/// The indexed topic list.
pub topics: Vec<B256>,
Copy link
Member

Choose a reason for hiding this comment

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

i would agree we can add getters instead

@@ -92,8 +92,8 @@ impl JsonAbiExt for Constructor {
}

#[inline]
fn decode_input(&self, data: &[u8]) -> Result<Vec<DynSolValue>> {
decode(data, &self.inputs)
fn decode_input(&self, data: &[u8], validate: bool) -> Result<Vec<DynSolValue>> {
Copy link
Member

Choose a reason for hiding this comment

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

What's our general stance on functions which have validate: bool? When is it OK to not validate?

Copy link
Member Author

@DaniPopes DaniPopes Sep 18, 2023

Choose a reason for hiding this comment

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

validate set to true is the same as calling the _whole version of the function in ethabi, which I didn't know existed prior to this

Comment on lines +296 to +297
// TODO: How do we verify here?
// wrong_event.decode_log_object(&log, true).unwrap_err();
Copy link
Member

Choose a reason for hiding this comment

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

what do we want to check?

Copy link
Member Author

Choose a reason for hiding this comment

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

I guess that decoding 2 words into 1 (non indexed address) should fail? But currently doesn't, I'm not really sure how to fix this and it's out of scope

Copy link
Member Author

Choose a reason for hiding this comment

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

ethabi::decode_whole says it "Fails, if some data left to decode" so I guess that would be enough to fix this

DaniPopes and others added 3 commits October 3, 2023 18:36
* refactor: DynSolEvent and ResolveSolEvent

* fix: num_topics

* feature: Log::is_valid

* test: make assertion

* chore: getters on DynSolEvent

* chore: remove dbg

* lint: clippy

* lint: clippy

* nit: indent
@prestwich prestwich merged commit fe4a535 into main Oct 3, 2023
20 checks passed
DaniPopes added a commit that referenced this pull request Oct 4, 2023
* feat: add logs, add log dynamic decoding

* feat: logs bloom function

* merge fixes

* DynSolEvent & ResolveSolEvent (#309)

* refactor: DynSolEvent and ResolveSolEvent

* fix: num_topics

* feature: Log::is_valid

* test: make assertion

* chore: getters on DynSolEvent

* chore: remove dbg

* lint: clippy

* lint: clippy

* nit: indent

---------

Co-authored-by: James Prestwich <[email protected]>
@gakonst gakonst deleted the dani/logs branch October 4, 2023 22:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature] Simple API to resolve json-abi item types
3 participants