Skip to content

Commit

Permalink
lang: Require Discriminator trait impl when using the zero constr…
Browse files Browse the repository at this point in the history
…aint (#3118)
  • Loading branch information
acheroncrypto authored Jul 25, 2024
1 parent fc765ff commit 293ee91
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ The minor version will be incremented upon a breaking change and the patch versi
- lang: Remove `EventData` trait ([#3083](https://github.com/coral-xyz/anchor/pull/3083)).
- client: Remove `async_rpc` method ([#3053](https://github.com/coral-xyz/anchor/pull/3053)).
- lang: Make discriminator type unsized ([#3098](https://github.com/coral-xyz/anchor/pull/3098)).
- lang: Require `Discriminator` trait impl when using the `zero` constraint ([#3118](https://github.com/coral-xyz/anchor/pull/3118)).

## [0.30.1] - 2024-06-20

Expand Down
10 changes: 6 additions & 4 deletions lang/syn/src/codegen/accounts/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,17 +198,19 @@ pub fn generate_constraint_init(
}

pub fn generate_constraint_zeroed(f: &Field, _c: &ConstraintZeroed) -> proc_macro2::TokenStream {
let account_ty = f.account_ty();
let discriminator = quote! { #account_ty::DISCRIMINATOR };

let field = &f.ident;
let name_str = field.to_string();
let ty_decl = f.ty_decl(true);
let from_account_info = f.from_account_info(None, false);
quote! {
let #field: #ty_decl = {
let mut __data: &[u8] = &#field.try_borrow_data()?;
let mut __disc_bytes = [0u8; 8];
__disc_bytes.copy_from_slice(&__data[..8]);
let __discriminator = u64::from_le_bytes(__disc_bytes);
if __discriminator != 0 {
let __disc = &__data[..#discriminator.len()];
let __has_disc = __disc.iter().any(|b| *b != 0);
if __has_disc {
return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintZero).with_account_name(#name_str));
}
#from_account_info
Expand Down
9 changes: 9 additions & 0 deletions lang/syn/src/parser/accounts/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1174,6 +1174,15 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
if self.init.is_some() {
return Err(ParseError::new(c.span(), "init already provided"));
}

// Require a known account type that implements the `Discriminator` trait so that we can
// get the discriminator length dynamically
if !matches!(&self.f_ty, Some(Ty::Account(_) | Ty::AccountLoader(_))) {
return Err(ParseError::new(
c.span(),
"`zero` constraint requires the type to implement the `Discriminator` trait",
));
}
self.zeroed.replace(c);
Ok(())
}
Expand Down

0 comments on commit 293ee91

Please sign in to comment.