-
Notifications
You must be signed in to change notification settings - Fork 249
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
Enforce Standard Logging Compliance by Abstraction #934
Enforce Standard Logging Compliance by Abstraction #934
Conversation
Changed to WIP because I would like to convert to a single derive attribute with kwargs, and I need to resolve issues with lifetimes. I also still need to privatize Another possible idea is to add it to the |
@coleFD Exposing events via ABI would be awesome! I feel it is a much heavier lift than the initial idea, but I see it as a cool challenge 😃 |
For sure, I dont think adding events to the abi should be added to this issue. I dont want to add to many changes into 1 issue, but If I utilize |
e486714
to
2a548aa
Compare
The implementation is done, but I still need to remove the previous logging functions. I do not know what that process should look like since it will affect all of the examples and smart-contract-standards contracts as well. I can update these as needed, but getting approval first would be better. We could even create another issue for the transition.. |
Please, clarify which logging functions you refer to. |
@austinabell Could you recommend someone to review this PR? |
The goal of this is to prevent logging without having the standard metadata fields Are there any concerns with doing this? |
bc1c77a
to
baa178d
Compare
log_str and its derivatives should be left as is. There is no problem with using logs in contracts, though, we should definitely promote usage of events. Also, I would imagine we reimplement NFT and FT events using this facility. I see that @austinabell is out of office until next week, so we will need to wait until he gets back and gets time to review it. |
By the way, I have just learned about this prior art: https://github.com/NEARFoundation/near-contract-tools#events |
interesting, is there still incentive to add this to |
I would like to hear what @austinabell thinks |
baa178d
to
f263fba
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this! I think this can be useful to have in the SDK somewhere (unsure if it should live in near_sdk
or near_contract_standards
crate, I'll think about that more.
@itegulov wdyt about this? Do you think the implications of enum vs struct annotation would have any implication on integrating into the ABI?
near-sdk/src/types/event.rs
Outdated
#[near_bindgen(events)] | ||
pub enum TestEvents<'a, 'b, T> | ||
where | ||
T: crate::serde::Serialize + Clone, | ||
{ | ||
#[event_meta(standard = "swap_standard", version = "1.0.0")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious why the decision to group all events in one enum? Would this not just be simpler if it was an attribute on a struct? I suppose this is a bit opinionated, but wondering if there is a reason this must be an enum
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went this route based on frol's comment above. It looked clean as an enum since it grouped events together. I can convert it to implement structs if we decide to go that route
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope, that's fine. It's opinionated, was just sharing my intuition. I suppose we could also just support both if it doesn't increase complexity meaningfully.
cc @itegulov wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I treat events as some sort of standard and an enum in my head represents the fact that there is a finite number of types of events that a contract can emit. That said, I would consider extracting standard = "..."
to the enum declaration level instead of the enum variants level. This way we could have FtEvents, NftEvents, MtEvents, FayyrEvents, etc, so one could import and use them in a composable way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the last thing I need clarification on before committing the new changes. Should I move forward with keeping this as an enum and moving standard
to the enum declaration level?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@itegulov wdyt about this? Do you think the implications of enum vs struct annotation would have any implication on integrating into the ABI?
I don't think it matters, we should be able to generate ABI for both options.
Personally, I find that having a mega-enum covering all standards used in this contract is a bit of an antipattern, but not a strong opinion. What @frol suggested makes more sense to me - having an enum per standard looks cleaner.
near-sdk/src/types/event.rs
Outdated
@@ -0,0 +1,95 @@ | |||
pub trait StandardEvent { | |||
fn format(&self) -> String; | |||
fn emit(&self); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could have a default implementation to prevent devs from having to implement it manually if they choose.
fn emit(&self); | |
fn emit(&self) { | |
crate::env::log_str(&format!("EVENT_JSON:{}", &standard_event.format())); | |
} |
Using Another benefit of using For example, this PR shows how |
00dffda
to
6eecebe
Compare
any feedback on the latest commit? |
There's actually a much simpler way to make sure there is no overlap here. I made the commit 1e6c09e. Feel free to cherry-pick, make a similar change yourself, or let me know if I can push it to this branch. It's a small nit but with this, you can still have a collision when you don't need that to be the case. |
Nice! you can push it to this branch! |
So when making that other change, it wasn't clear to me why the trait is necessary at all. Seems unergonomic to require devs to import that trait to use this. Why not just remove it like in 1cc5c19 ? |
Also, ignore CI failure, it's because of a Rust release. #955 fixes it |
initially the plan was to have a |
I just don't see the benefit in having a trait for this if all it's going to do is add the convenience I'll push that change to this branch then since it seems like you're on board. Would be nice to have a macro test for the codegen, since I was able to make both changes without any tests failing, which is not ideal. This is not required though, improved tests can come after this PR comes in. Sorry for so much back and forth, this is just an important interface and it would be painful to migrate later. |
@austinabell @coleFD Thanks for pushing it forward! I was out of the office, and I just had a chance to sync back. I see there was a huge progress! 🙏 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but would be good to have another approval since I was the last to make a commit on this branch
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, looks good to me. I only left a few nits in the comments
near-sdk/src/types/mod.rs
Outdated
#[cfg(test)] | ||
mod event_tests; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it actually the right place for the tests? Should we move it to near-sdk/tests
?
Co-authored-by: Vlad Frolov <frolvlad@gmail.com>
Co-authored-by: Vlad Frolov <frolvlad@gmail.com>
thank you! Sorry for all the back and forth |
No worries! thank you guys for being responsive and taking the time to dig into it! |
The goal of this commit is to force compliance of standard logging practices so more efficient indexing features can be developed in the future such as a logs bloom filter by event name. See the original discussion here: near/NEPs#297
! NOTE:
Please see discussion in the linked issue above to determine if it would be better to make the
standard
andversion
field optional! BREAKING CHANGE:
For this change to be useful, we will need to privatize/remove the
env::log()
andenv::log_str()
functions, which has not been implemented yet in this commit. May not be a breaking change, but adding this to this section, so it is recognized