Skip to content

Commit 1acfce1

Browse files
perfilev-devperfilev-farawaymacalinao
authored
Add missing events generation (#36)
* Add missing events generation * Add event discriminator * Add event discriminator * Fix hash bug * Fix hash bug --------- Co-authored-by: Sergey Perfilev <[email protected]> Co-authored-by: Ian Macalinao <[email protected]>
1 parent b8d58b2 commit 1acfce1

File tree

5 files changed

+77
-2
lines changed

5 files changed

+77
-2
lines changed

Cargo.lock

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/anchor-idl/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ darling = "0.14"
1717
heck = "0.4.1"
1818
proc-macro2 = "1"
1919
quote = "1"
20+
sha2 = "0.9.2"
2021
serde_json = "1.0.108"
2122
syn = { version = "1", features = ["full"] }
2223

crates/anchor-idl/src/event.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
use std::collections::BTreeMap;
2+
3+
use anchor_syn::idl::{IdlEvent, IdlField, IdlTypeDefinition};
4+
use proc_macro2::TokenStream;
5+
use quote::{format_ident, quote};
6+
use sha2::{Digest, Sha256};
7+
8+
use crate::{generate_struct, StructOpts};
9+
10+
/// Generates event structs.
11+
pub fn generate_events(
12+
events: Option<&[IdlEvent]>,
13+
typedefs: &[IdlTypeDefinition],
14+
struct_opts: &BTreeMap<String, StructOpts>,
15+
) -> TokenStream {
16+
match events {
17+
Some(events) => {
18+
let defined = events.iter().map(|def| {
19+
let struct_name = format_ident!("{}", def.name);
20+
let opts = struct_opts.get(&def.name).copied().unwrap_or_default();
21+
22+
let discriminator: proc_macro2::TokenStream = {
23+
let discriminator_preimage = format!("event:{}", struct_name);
24+
let mut discriminator = [0u8; 8];
25+
let mut hash = Sha256::default();
26+
hash.update(discriminator_preimage.as_bytes());
27+
discriminator.copy_from_slice(&hash.finalize()[..8]);
28+
format!("{:?}", discriminator).parse().unwrap()
29+
};
30+
31+
let fields = def
32+
.fields
33+
.iter()
34+
.map(|f| IdlField {
35+
name: f.name.clone(),
36+
ty: f.ty.clone(),
37+
})
38+
.collect::<Vec<_>>();
39+
40+
let struct_ts = generate_struct(&typedefs, &struct_name, &fields, opts);
41+
42+
quote! {
43+
#struct_ts
44+
45+
impl anchor_lang::Discriminator for #struct_name {
46+
const DISCRIMINATOR: [u8; 8] = #discriminator;
47+
fn discriminator() -> [u8; 8] {
48+
#discriminator
49+
}
50+
}
51+
}
52+
});
53+
quote! {
54+
#(#defined)*
55+
}
56+
}
57+
None => quote!(),
58+
}
59+
}

crates/anchor-idl/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
pub use anchor_lang_idl_spec::*;
44

55
mod account;
6+
mod event;
67
mod fields;
78
mod instruction;
89
mod program;
910
mod state;
1011
mod typedef;
1112

1213
pub use account::*;
14+
pub use event::*;
1315
pub use instruction::*;
1416
pub use program::*;
1517
pub use state::*;

crates/anchor-idl/src/program.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use proc_macro2::{Ident, TokenStream};
99
use quote::{format_ident, quote};
1010

1111
use crate::{
12-
generate_accounts, generate_ix_handlers, generate_ix_structs, generate_typedefs, GEN_VERSION,
12+
generate_accounts, generate_events, generate_ix_handlers, generate_ix_structs,
13+
generate_typedefs, GEN_VERSION,
1314
};
1415

1516
#[derive(Default, FromMeta)]
@@ -85,6 +86,11 @@ impl Generator {
8586
let program_name: Ident = format_ident!("{}", idl.metadata.name);
8687

8788
let accounts = generate_accounts(&idl.types, &idl.accounts, &self.struct_opts);
89+
let events = generate_events(
90+
idl.events.as_ref().map(|x| &x[..]),
91+
&idl.types,
92+
&self.struct_opts,
93+
);
8894
let typedefs = generate_typedefs(&idl.types, &self.struct_opts);
8995
let ix_handlers = generate_ix_handlers(&idl.instructions);
9096
let ix_structs = generate_ix_structs(&idl.instructions);
@@ -115,6 +121,12 @@ impl Generator {
115121
#accounts
116122
}
117123

124+
pub mod events {
125+
//! Structs of events generated by program.
126+
use super::*;
127+
#events
128+
}
129+
118130
pub mod ix_accounts {
119131
//! Accounts used in instructions.
120132
use super::*;

0 commit comments

Comments
 (0)