diff --git a/Cargo.lock b/Cargo.lock index edb865ee..18280f3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,6 +70,7 @@ dependencies = [ name = "anchor-attribute-account" version = "0.21.0" dependencies = [ + "anchor-common", "anchor-syn", "anyhow", "bs58 0.4.0", @@ -102,6 +103,7 @@ dependencies = [ name = "anchor-attribute-event" version = "0.21.0" dependencies = [ + "anchor-common", "anchor-syn", "anyhow", "proc-macro2 1.0.32", @@ -190,6 +192,14 @@ dependencies = [ "url", ] +[[package]] +name = "anchor-common" +version = "0.21.0" +dependencies = [ + "arrayref", + "solana-program", +] + [[package]] name = "anchor-derive-accounts" version = "0.21.0" @@ -213,6 +223,7 @@ dependencies = [ "anchor-attribute-interface", "anchor-attribute-program", "anchor-attribute-state", + "anchor-common", "anchor-derive-accounts", "arrayref", "base64 0.13.0", @@ -239,6 +250,7 @@ name = "anchor-syn" version = "0.21.0" dependencies = [ "anyhow", + "arrayref", "bs58 0.3.1", "heck 0.3.3", "proc-macro2 1.0.32", @@ -247,6 +259,7 @@ dependencies = [ "serde", "serde_json", "sha2", + "solana-program", "syn 1.0.81", "thiserror", ] diff --git a/Cargo.toml b/Cargo.toml index 6d7db428..5220fa42 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ members = [ "client", "lang", "lang/attribute/*", + "lang/common", "lang/derive/*", "lang/syn", "spl", diff --git a/lang/Cargo.toml b/lang/Cargo.toml index d8dd796f..9991653e 100644 --- a/lang/Cargo.toml +++ b/lang/Cargo.toml @@ -34,6 +34,7 @@ anchor-attribute-state = { path = "./attribute/state", version = "0.21.0" } anchor-attribute-interface = { path = "./attribute/interface", version = "0.21.0" } anchor-attribute-event = { path = "./attribute/event", version = "0.21.0" } anchor-derive-accounts = { path = "./derive/accounts", version = "0.21.0" } +anchor-common = { path = "./common", version = "0.21.0" } arrayref = "0.3.6" base64 = "0.13.0" borsh = "0.9" diff --git a/lang/attribute/account/Cargo.toml b/lang/attribute/account/Cargo.toml index 60c54514..d45fa516 100644 --- a/lang/attribute/account/Cargo.toml +++ b/lang/attribute/account/Cargo.toml @@ -19,5 +19,6 @@ quote = "1.0" syn = { version = "1.0.60", features = ["full"] } anyhow = "1.0.32" anchor-syn = { path = "../../syn", version = "0.21.0", features = ["hash"] } +anchor-common = { path = "../../common", version = "0.21.0" } rustversion = "1.0.3" -bs58 = "0.4.0" \ No newline at end of file +bs58 = "0.4.0" diff --git a/lang/attribute/account/src/lib.rs b/lang/attribute/account/src/lib.rs index ff169eca..87bda554 100644 --- a/lang/attribute/account/src/lib.rs +++ b/lang/attribute/account/src/lib.rs @@ -104,41 +104,19 @@ pub fn account( }; let discriminator: proc_macro2::TokenStream = { - // Namespace the discriminator to prevent collisions. - let discriminator_preimage = { - // For now, zero copy accounts can't be namespaced. + let discriminator = anchor_common::header::create_discriminator( + &account_name.to_string(), if namespace.is_empty() { - format!("account:{}", account_name) + None } else { - format!("{}:{}", namespace, account_name) - } - }; - - if cfg!(feature = "deprecated-layout") { - let mut discriminator = [0u8; 8]; - discriminator.copy_from_slice( - &anchor_syn::hash::hash(discriminator_preimage.as_bytes()).to_bytes()[..8], - ); - format!("{:?}", discriminator).parse().unwrap() - } else { - let mut discriminator = [0u8; 4]; - discriminator.copy_from_slice( - &anchor_syn::hash::hash(discriminator_preimage.as_bytes()).to_bytes()[..4], - ); - format!("{:?}", discriminator).parse().unwrap() - } + Some(&namespace) + }, + ); + format!("{:?}", discriminator).parse().unwrap() }; - let disc_bytes = { - if cfg!(feature = "deprecated-layout") { - quote! { - let given_disc = &buf[..8]; - } - } else { - quote! { - let given_disc = &buf[2..6]; - } - } + let disc_bytes = quote! { + let given_disc = anchor_lang::accounts::header::read_discriminator(&buf); }; let disc_fn = { diff --git a/lang/attribute/event/Cargo.toml b/lang/attribute/event/Cargo.toml index f7fc57c0..e0dbbddb 100644 --- a/lang/attribute/event/Cargo.toml +++ b/lang/attribute/event/Cargo.toml @@ -19,3 +19,4 @@ quote = "1.0" syn = { version = "1.0.60", features = ["full"] } anyhow = "1.0.32" anchor-syn = { path = "../../syn", version = "0.21.0", features = ["hash"] } +anchor-common = { path = "../../common", version = "0.21.0" } diff --git a/lang/attribute/event/src/lib.rs b/lang/attribute/event/src/lib.rs index 8035404b..ad27d78f 100644 --- a/lang/attribute/event/src/lib.rs +++ b/lang/attribute/event/src/lib.rs @@ -17,24 +17,8 @@ pub fn event( let event_name = &event_strct.ident; let discriminator: proc_macro2::TokenStream = { - let discriminator_preimage = format!("event:{}", event_name); - - #[cfg(feature = "deprecated-layout")] - let discriminator = { - let mut discriminator = [0u8; 8]; - discriminator.copy_from_slice( - &anchor_syn::hash::hash(discriminator_preimage.as_bytes()).to_bytes()[..8], - ); - discriminator - }; - #[cfg(not(feature = "deprecated-layout"))] - let discriminator = { - let mut discriminator = [0u8; 4]; - discriminator.copy_from_slice( - &anchor_syn::hash::hash(discriminator_preimage.as_bytes()).to_bytes()[..4], - ); - discriminator - }; + let discriminator = + anchor_common::header::create_discriminator(&event_name.to_string(), Some("event")); format!("{:?}", discriminator).parse().unwrap() }; diff --git a/lang/common/Cargo.toml b/lang/common/Cargo.toml new file mode 100644 index 00000000..1c475aa1 --- /dev/null +++ b/lang/common/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "anchor-common" +version = "0.21.0" +authors = ["Serum Foundation "] +repository = "https://github.com/project-serum/anchor" +license = "Apache-2.0" +description = "Common utilities for internal anchor lang crates" +edition = "2018" + +[features] +default = [] + +[dependencies] +arrayref = "0.3.6" +solana-program = "1.8.5" diff --git a/lang/src/accounts/header.rs b/lang/common/src/header.rs similarity index 60% rename from lang/src/accounts/header.rs rename to lang/common/src/header.rs index 4a425002..12e5aa0f 100644 --- a/lang/src/accounts/header.rs +++ b/lang/common/src/header.rs @@ -1,4 +1,6 @@ use arrayref::array_ref; +use solana_program::hash; +use std::io::{Cursor, Write}; #[cfg(feature = "deprecated-layout")] pub fn read_discriminator(data: &[u8]) -> &[u8; 8] { @@ -14,9 +16,7 @@ pub fn read_discriminator(data: &[u8]) -> &[u8; 4] { pub fn create_discriminator(account_name: &str, namespace: Option<&str>) -> [u8; 8] { let discriminator_preimage = format!("{}:{}", namespace.unwrap_or("account"), account_name); let mut discriminator = [0u8; 8]; - discriminator.copy_from_slice( - &crate::solana_program::hash::hash(discriminator_preimage.as_bytes()).to_bytes()[..8], - ); + discriminator.copy_from_slice(&hash::hash(discriminator_preimage.as_bytes()).to_bytes()[..8]); discriminator } @@ -24,9 +24,7 @@ pub fn create_discriminator(account_name: &str, namespace: Option<&str>) -> [u8; pub fn create_discriminator(account_name: &str, namespace: Option<&str>) -> [u8; 4] { let discriminator_preimage = format!("{}:{}", namespace.unwrap_or("account"), account_name); let mut discriminator = [0u8; 4]; - discriminator.copy_from_slice( - &crate::solana_program::hash::hash(discriminator_preimage.as_bytes()).to_bytes()[..4], - ); + discriminator.copy_from_slice(&hash::hash(discriminator_preimage.as_bytes()).to_bytes()[..4]); discriminator } @@ -38,3 +36,17 @@ pub fn read_data(account_data: &[u8]) -> &[u8] { pub fn read_data_mut(account_data: &mut [u8]) -> &mut [u8] { &mut account_data[8..] } + +pub fn write_discriminator(account_data: &mut [u8], discriminator: &[u8]) { + #[cfg(feature = "deprecated_layout")] + { + let mut cursor = Cursor::new(account_dst); + cursor.write_all(discriminator).unwrap(); + } + #[cfg(not(feature = "deprecated_layout"))] + { + let dst: &mut [u8] = &mut account_data[2..]; + let mut cursor = Cursor::new(dst); + cursor.write_all(discriminator).unwrap(); + } +} diff --git a/lang/common/src/lib.rs b/lang/common/src/lib.rs new file mode 100644 index 00000000..f505d688 --- /dev/null +++ b/lang/common/src/lib.rs @@ -0,0 +1 @@ +pub mod header; diff --git a/lang/src/accounts/mod.rs b/lang/src/accounts/mod.rs index c94ff360..facd04ff 100644 --- a/lang/src/accounts/mod.rs +++ b/lang/src/accounts/mod.rs @@ -10,7 +10,6 @@ pub mod cpi_account; #[doc(hidden)] #[allow(deprecated)] pub mod cpi_state; -pub mod header; #[doc(hidden)] #[allow(deprecated)] pub mod loader; @@ -25,3 +24,5 @@ pub mod state; pub mod system_account; pub mod sysvar; pub mod unchecked_account; + +pub use anchor_common::header; diff --git a/lang/syn/Cargo.toml b/lang/syn/Cargo.toml index ee98c347..427430df 100644 --- a/lang/syn/Cargo.toml +++ b/lang/syn/Cargo.toml @@ -16,6 +16,7 @@ anchor-debug = [] seeds = [] [dependencies] +arrayref = "0.3.6" proc-macro2 = "1.0" proc-macro2-diagnostics = "0.9" quote = "1.0" @@ -25,5 +26,6 @@ heck = "0.3.1" serde = { version = "1.0.122", features = ["derive"] } serde_json = "1.0" sha2 = "0.9.2" +solana-program = "1.8.5" thiserror = "1.0" bs58 = "0.3.1" diff --git a/lang/syn/src/codegen/accounts/constraints.rs b/lang/syn/src/codegen/accounts/constraints.rs index ccda5edc..9b0c723f 100644 --- a/lang/syn/src/codegen/accounts/constraints.rs +++ b/lang/syn/src/codegen/accounts/constraints.rs @@ -147,23 +147,10 @@ pub fn generate_constraint_zeroed(f: &Field, _c: &ConstraintZeroed) -> proc_macr let ty_decl = f.ty_decl(); let account_ty = f.account_ty(); let from_account_info = f.from_account_info(None); - let header_write = { - if cfg!(feature = "deprecated-layout") { - quote! { - use std::io::{Write, Cursor}; - use anchor_lang::Discriminator; - let __dst: &mut [u8] = &mut __data; - let mut __cursor = Cursor::new(__dst); - Write::write_all(&mut __cursor, &#account_ty::discriminator()).unwrap(); - } - } else { - quote! { - use std::io::{Write, Cursor}; - use anchor_lang::Discriminator; - let __dst: &mut [u8] = &mut __data[2..]; - let mut __cursor = Cursor::new(__dst); - Write::write_all(&mut __cursor, &#account_ty::discriminator()).unwrap(); - } + let header_write = quote! { + { + use anchor_lang::Discriminator; + anchor_lang::accounts::header::write_discriminator(&mut __data, &#account_ty::discriminator()); } }; // Check the *entire* account header is zero. @@ -541,30 +528,14 @@ fn generate_constraint_init(f: &Field, c: &ConstraintInitGroup) -> proc_macro2:: | Ty::Loader(_) | Ty::AccountLoader(_) => { let account_ty = f.account_ty(); - if cfg!(feature = "deprecated-layout") { - quote! { - { - use std::io::{Write, Cursor}; - use anchor_lang::Discriminator; + quote! { + { - let mut __data = actual_field.try_borrow_mut_data()?; - let __dst: &mut [u8] = &mut __data; - let mut __cursor = Cursor::new(__dst); - Write::write_all(&mut __cursor, &#account_ty::discriminator()).unwrap(); - } - } - } else { - quote! { - { - use std::io::{Write, Seek, SeekFrom, Cursor}; - use anchor_lang::Discriminator; - - let mut __data = actual_field.try_borrow_mut_data()?; - let __dst: &mut [u8] = &mut __data; - let mut __cursor = Cursor::new(__dst); - Seek::seek(&mut __cursor, SeekFrom::Start(2)).unwrap(); - Write::write_all(&mut __cursor, &#account_ty::discriminator()).unwrap(); - } + let mut __data = actual_field.try_borrow_mut_data()?; + anchor_lang::accounts::header::write_discriminator( + &mut __data, + &#account_ty::discriminator(), + ); } } } diff --git a/lang/syn/src/codegen/program/handlers.rs b/lang/syn/src/codegen/program/handlers.rs index ba725e96..3858fabe 100644 --- a/lang/syn/src/codegen/program/handlers.rs +++ b/lang/syn/src/codegen/program/handlers.rs @@ -202,32 +202,13 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream { let ix_name: proc_macro2::TokenStream = generate_ctor_variant_name().parse().unwrap(); let ix_name_log = format!("Instruction: {}", ix_name); - let header_write = { - if cfg!(feature = "deprecated-layout") { - quote! { - { - use std::io::{Write, Cursor}; - use anchor_lang::Discriminator; - - let mut __data = ctor_accounts.to.try_borrow_mut_data()?; - let __dst: &mut [u8] = &mut __data; - let mut __cursor = Cursor::new(__dst); - Write::write_all(&mut __cursor, &#name::discriminator()).unwrap(); - } - } - } else { - quote! { - { - use std::io::{Write, Cursor, SeekFrom, Seek}; - use anchor_lang::Discriminator; - - let mut __data = ctor_accounts.to.try_borrow_mut_data()?; - let __dst: &mut [u8] = &mut __data; - let mut __cursor = Cursor::new(__dst); - Seek::seek(&mut __cursor, SeekFrom::Start(2)).unwrap(); - Write::write_all(&mut __cursor, &#name::discriminator()).unwrap(); - } - } + let header_write = quote! { + { + let mut __data = ctor_accounts.to.try_borrow_mut_data()?; + anchor_lang::accounts::header::write_discriminator( + &mut __data, + &#name::discriminator(), + ); } }; if state.is_zero_copy {