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(zink-codegen): introduce derive macro for events #281

Closed
wants to merge 13 commits into from
Closed
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
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

183 changes: 99 additions & 84 deletions examples/log.rs
Original file line number Diff line number Diff line change
@@ -1,99 +1,114 @@
//! Addition example.
#![cfg_attr(target_arch = "wasm32", no_std)]
#![cfg_attr(target_arch = "wasm32", no_main)]

extern crate zink;

use zink::Event;
use zink::{primitives::U256, Asm, Event};

/// A `Ping` event.
#[derive(Event)]
struct Ping;

#[zink::external]
pub fn log0() {
Ping.log0();
}

#[zink::external]
pub fn log1() {
Ping.log1(b"pong");
pub enum MyEvent {
/// Event with no topics
Topic0,
/// Event with one topic
Topic1(U256),
/// Event with two topics
Topic2(U256, U256),
/// Event with three topics
Topic3(U256, U256, U256),
/// Event with four topics
Topic4(U256, U256, U256, U256),
}

#[zink::external]
pub fn log2() {
Ping.log2(b"pong", b"ping");
pub mod event_tests {
use super::*;

/// Test log0
#[zink::external]
pub fn test_log0() {
unsafe { zink::ffi::evm::log0(b"MyEvent") }
}

/// Test log1
#[zink::external]
pub fn test_log1(value: U256) {
unsafe {
let topic = value.to_bytes32();
zink::ffi::evm::log1(b"MyEvent", topic)
}
}

/// Test log2
#[zink::external]
pub fn test_log2(value1: U256, value2: U256) {
unsafe {
let topic1 = value1.to_bytes32();
let topic2 = value2.to_bytes32();
zink::ffi::evm::log2(b"MyEvent", topic1, topic2)
}
}

/// Test log3
#[zink::external]
pub fn test_log3(value1: U256, value2: U256, value3: U256) {
unsafe {
let topic1 = value1.to_bytes32();
let topic2 = value2.to_bytes32();
let topic3 = value3.to_bytes32();
zink::ffi::evm::log3(b"MyEvent", topic1, topic2, topic3)
}
}

/// Test log4
#[zink::external]
pub fn test_log4(value1: U256, value2: U256, value3: U256, value4: U256) {
unsafe {
let topic1 = value1.to_bytes32();
let topic2 = value2.to_bytes32();
let topic3 = value3.to_bytes32();
let topic4 = value4.to_bytes32();
zink::ffi::evm::log4(b"MyEvent", topic1, topic2, topic3, topic4)
}
}

/// Test multiple event logs in one transaction
#[zink::external]
pub fn test_multiple_logs(
value1: U256,
value2: U256,
value3: U256,
value4: U256,
) -> Result<(), ()> {
test_log0();
test_log1(value1);
test_log2(value1, value2);
test_log3(value1, value2, value3);
test_log4(value1, value2, value3, value4);
Ok(())
}
}

#[zink::external]
pub fn log3() {
Ping.log3(b"pong", b"ping", b"pong");
}

#[zink::external]
pub fn log4() {
Ping.log4(b"pong", b"ping", b"pong", b"pong");
#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_events() {
let value1 = U256::from(U256::empty());
let value2 = U256::from(U256::empty());
let value3 = U256::from(U256::empty());
let value4 = U256::from(U256::empty());

// Test each log function
event_tests::test_log0();
event_tests::test_log1(value1);
event_tests::test_log2(value1, value2);
event_tests::test_log3(value1, value2, value3);
event_tests::test_log4(value1, value2, value3, value4);

// Test multiple logs
event_tests::test_multiple_logs(value1, value2, value3, value4).unwrap();
}
Comment on lines +101 to +109
Copy link
Member

Choose a reason for hiding this comment

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

should compile the contract and then call these interfaces to complete the tests

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@clearloop how do we assert the output, logs don't return yet

Copy link
Member

Choose a reason for hiding this comment

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

for example here:

https://github.com/zink-lang/zink/blob/main/examples/log.rs#L44-L50

  1. we deploy the contract to our testing EVM
  2. we call the method, in the returned info, there is a log field, see https://docs.zink-lang.org/rustdocs/zint/struct.Info.html#structfield.logs

}

#[cfg(not(target_arch = "wasm32"))]
fn main() {}

#[test]
fn test() -> anyhow::Result<()> {
use zint::{Bytes32, Contract};
let mut contract = Contract::search("log")?.compile()?;

let info = contract.execute(["log0()"])?;
assert_eq!(
info.logs[0].data.data.to_vec(),
b"Ping".to_vec().to_bytes32()
);

let info = contract.execute(["log1()"])?;
assert_eq!(
info.logs[0].data.data.to_vec(),
b"Ping".to_vec().to_bytes32()
);
assert_eq!(info.logs[0].topics(), vec![b"pong".to_vec().to_bytes32()]);

let info = contract.execute(["log2()"])?;
assert_eq!(
info.logs[0].data.data.to_vec(),
b"Ping".to_vec().to_bytes32()
);
assert_eq!(
info.logs[0].topics(),
vec![b"pong".to_vec().to_bytes32(), b"ping".to_vec().to_bytes32()]
);

let info = contract.execute(["log3()"])?;
assert_eq!(
info.logs[0].data.data.to_vec(),
b"Ping".to_vec().to_bytes32()
);
assert_eq!(
info.logs[0].topics(),
vec![
b"pong".to_vec().to_bytes32(),
b"ping".to_vec().to_bytes32(),
b"pong".to_vec().to_bytes32()
]
);

let info = contract.execute(["log4()"])?;
assert_eq!(
info.logs[0].data.data.to_vec(),
b"Ping".to_vec().to_bytes32()
);
assert_eq!(
info.logs[0].topics(),
vec![
b"pong".to_vec().to_bytes32(),
b"ping".to_vec().to_bytes32(),
b"pong".to_vec().to_bytes32(),
b"pong".to_vec().to_bytes32()
]
);

Ok(())
}
1 change: 1 addition & 0 deletions zink/codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ heck.workspace = true
hex.workspace = true
proc-macro2.workspace = true
quote.workspace = true
sha3 = "0.10.8"
syn.workspace = true
zabi = { workspace = true, features = [ "hex", "syn" ] }
Loading
Loading