|
@@ -134,10 +134,19 @@ fn generate_constraint_composite(f: &CompositeField, c: &Constraint) -> proc_mac
|
|
|
fn generate_constraint_address(f: &Field, c: &ConstraintAddress) -> proc_macro2::TokenStream {
|
|
|
let field = &f.ident;
|
|
|
let addr = &c.address;
|
|
|
- let error = generate_custom_error(field, &c.error, quote! { ConstraintAddress });
|
|
|
+ let error = generate_custom_error(
|
|
|
+ field,
|
|
|
+ &c.error,
|
|
|
+ quote! { ConstraintAddress },
|
|
|
+ &Some(&(quote! { actual }, quote! { expected })),
|
|
|
+ );
|
|
|
quote! {
|
|
|
- if #field.key() != #addr {
|
|
|
- return #error;
|
|
|
+ {
|
|
|
+ let actual = #field.key();
|
|
|
+ let expected = #addr;
|
|
|
+ if actual != expected {
|
|
|
+ return #error;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -178,7 +187,7 @@ pub fn generate_constraint_close(f: &Field, c: &ConstraintClose) -> proc_macro2:
|
|
|
|
|
|
pub fn generate_constraint_mut(f: &Field, c: &ConstraintMut) -> proc_macro2::TokenStream {
|
|
|
let ident = &f.ident;
|
|
|
- let error = generate_custom_error(ident, &c.error, quote! { ConstraintMut });
|
|
|
+ let error = generate_custom_error(ident, &c.error, quote! { ConstraintMut }, &None);
|
|
|
quote! {
|
|
|
if !#ident.to_account_info().is_writable {
|
|
|
return #error;
|
|
@@ -194,10 +203,19 @@ pub fn generate_constraint_has_one(f: &Field, c: &ConstraintHasOne) -> proc_macr
|
|
|
Ty::AccountLoader(_) => quote! {#ident.load()?},
|
|
|
_ => quote! {#ident},
|
|
|
};
|
|
|
- let error = generate_custom_error(ident, &c.error, quote! { ConstraintHasOne });
|
|
|
+ let error = generate_custom_error(
|
|
|
+ ident,
|
|
|
+ &c.error,
|
|
|
+ quote! { ConstraintHasOne },
|
|
|
+ &Some(&(quote! { my_key }, quote! { target_key })),
|
|
|
+ );
|
|
|
quote! {
|
|
|
- if #field.#target != #target.key() {
|
|
|
- return #error;
|
|
|
+ {
|
|
|
+ let my_key = #field.#target;
|
|
|
+ let target_key = #target.key();
|
|
|
+ if my_key != target_key {
|
|
|
+ return #error;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -213,7 +231,7 @@ pub fn generate_constraint_signer(f: &Field, c: &ConstraintSigner) -> proc_macro
|
|
|
Ty::CpiAccount(_) => quote! { #ident.to_account_info() },
|
|
|
_ => panic!("Invalid syntax: signer cannot be specified."),
|
|
|
};
|
|
|
- let error = generate_custom_error(ident, &c.error, quote! { ConstraintSigner });
|
|
|
+ let error = generate_custom_error(ident, &c.error, quote! { ConstraintSigner }, &None);
|
|
|
quote! {
|
|
|
if !#info.is_signer {
|
|
|
return #error;
|
|
@@ -245,7 +263,7 @@ pub fn generate_constraint_literal(
|
|
|
|
|
|
pub fn generate_constraint_raw(ident: &Ident, c: &ConstraintRaw) -> proc_macro2::TokenStream {
|
|
|
let raw = &c.raw;
|
|
|
- let error = generate_custom_error(ident, &c.error, quote! { ConstraintRaw });
|
|
|
+ let error = generate_custom_error(ident, &c.error, quote! { ConstraintRaw }, &None);
|
|
|
quote! {
|
|
|
if !(#raw) {
|
|
|
return #error;
|
|
@@ -256,10 +274,19 @@ pub fn generate_constraint_raw(ident: &Ident, c: &ConstraintRaw) -> proc_macro2:
|
|
|
pub fn generate_constraint_owner(f: &Field, c: &ConstraintOwner) -> proc_macro2::TokenStream {
|
|
|
let ident = &f.ident;
|
|
|
let owner_address = &c.owner_address;
|
|
|
- let error = generate_custom_error(ident, &c.error, quote! { ConstraintOwner });
|
|
|
+ let error = generate_custom_error(
|
|
|
+ ident,
|
|
|
+ &c.error,
|
|
|
+ quote! { ConstraintOwner },
|
|
|
+ &Some(&(quote! { *my_owner }, quote! { owner_address })),
|
|
|
+ );
|
|
|
quote! {
|
|
|
- if #ident.as_ref().owner != &#owner_address {
|
|
|
- return #error;
|
|
|
+ {
|
|
|
+ let my_owner = #ident.as_ref().owner;
|
|
|
+ let owner_address = #owner_address;
|
|
|
+ if my_owner != &owner_address {
|
|
|
+ return #error;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -374,10 +401,10 @@ fn generate_constraint_init_group(f: &Field, c: &ConstraintInitGroup) -> proc_ma
|
|
|
let pa: #ty_decl = #from_account_info;
|
|
|
if #if_needed {
|
|
|
if pa.mint != #mint.key() {
|
|
|
- return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintTokenMint).with_account_name(#name_str));
|
|
|
+ return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintTokenMint).with_account_name(#name_str).with_pubkeys((pa.mint, #mint.key())));
|
|
|
}
|
|
|
if pa.owner != #owner.key() {
|
|
|
- return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintTokenOwner).with_account_name(#name_str));
|
|
|
+ return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintTokenOwner).with_account_name(#name_str).with_pubkeys((pa.owner, #owner.key())));
|
|
|
}
|
|
|
}
|
|
|
pa
|
|
@@ -409,10 +436,10 @@ fn generate_constraint_init_group(f: &Field, c: &ConstraintInitGroup) -> proc_ma
|
|
|
let pa: #ty_decl = #from_account_info;
|
|
|
if #if_needed {
|
|
|
if pa.mint != #mint.key() {
|
|
|
- return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintTokenMint).with_account_name(#name_str));
|
|
|
+ return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintTokenMint).with_account_name(#name_str).with_pubkeys((pa.mint, #mint.key())));
|
|
|
}
|
|
|
if pa.owner != #owner.key() {
|
|
|
- return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintTokenOwner).with_account_name(#name_str));
|
|
|
+ return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintTokenOwner).with_account_name(#name_str).with_pubkeys((pa.owner, #owner.key())));
|
|
|
}
|
|
|
|
|
|
if pa.key() != anchor_spl::associated_token::get_associated_token_address(&#owner.key(), &#mint.key()) {
|
|
@@ -471,7 +498,7 @@ fn generate_constraint_init_group(f: &Field, c: &ConstraintInitGroup) -> proc_ma
|
|
|
return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintMintFreezeAuthority).with_account_name(#name_str));
|
|
|
}
|
|
|
if pa.decimals != #decimals {
|
|
|
- return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintMintDecimals).with_account_name(#name_str));
|
|
|
+ return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintMintDecimals).with_account_name(#name_str).with_values((pa.decimals, #decimals)));
|
|
|
}
|
|
|
}
|
|
|
pa
|
|
@@ -525,11 +552,11 @@ fn generate_constraint_init_group(f: &Field, c: &ConstraintInitGroup) -> proc_ma
|
|
|
// Assert the account was created correctly.
|
|
|
if #if_needed {
|
|
|
if space != actual_field.data_len() {
|
|
|
- return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintSpace).with_account_name(#name_str));
|
|
|
+ return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintSpace).with_account_name(#name_str).with_values((space, actual_field.data_len())));
|
|
|
}
|
|
|
|
|
|
if actual_owner != #owner {
|
|
|
- return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintOwner).with_account_name(#name_str));
|
|
|
+ return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintOwner).with_account_name(#name_str).with_pubkeys((*actual_owner, *#owner)));
|
|
|
}
|
|
|
|
|
|
{
|
|
@@ -577,10 +604,10 @@ fn generate_constraint_seeds(f: &Field, c: &ConstraintSeedsGroup) -> proc_macro2
|
|
|
let b = c.bump.as_ref().unwrap();
|
|
|
quote! {
|
|
|
if #name.key() != __pda_address {
|
|
|
- return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintSeeds).with_account_name(#name_str));
|
|
|
+ return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintSeeds).with_account_name(#name_str).with_pubkeys((#name.key(), __pda_address)));
|
|
|
}
|
|
|
if __bump != #b {
|
|
|
- return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintSeeds).with_account_name(#name_str));
|
|
|
+ return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintSeeds).with_account_name(#name_str).with_values((__bump, #b)));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -592,7 +619,7 @@ fn generate_constraint_seeds(f: &Field, c: &ConstraintSeedsGroup) -> proc_macro2
|
|
|
else if c.is_init {
|
|
|
quote! {
|
|
|
if #name.key() != __pda_address {
|
|
|
- return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintSeeds).with_account_name(#name_str));
|
|
|
+ return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintSeeds).with_account_name(#name_str).with_pubkeys((#name.key(), __pda_address)));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -625,7 +652,7 @@ fn generate_constraint_seeds(f: &Field, c: &ConstraintSeedsGroup) -> proc_macro2
|
|
|
|
|
|
// Check it.
|
|
|
if #name.key() != __pda_address {
|
|
|
- return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintSeeds).with_account_name(#name_str));
|
|
|
+ return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintSeeds).with_account_name(#name_str).with_pubkeys((#name.key(), __pda_address)));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -640,12 +667,17 @@ fn generate_constraint_associated_token(
|
|
|
let wallet_address = &c.wallet;
|
|
|
let spl_token_mint_address = &c.mint;
|
|
|
quote! {
|
|
|
- if #name.owner != #wallet_address.key() {
|
|
|
- return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintTokenOwner).with_account_name(#name_str));
|
|
|
- }
|
|
|
- let __associated_token_address = anchor_spl::associated_token::get_associated_token_address(&#wallet_address.key(), &#spl_token_mint_address.key());
|
|
|
- if #name.key() != __associated_token_address {
|
|
|
- return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintAssociated).with_account_name(#name_str));
|
|
|
+ {
|
|
|
+ let my_owner = #name.owner;
|
|
|
+ let wallet_address = #wallet_address.key();
|
|
|
+ if my_owner != wallet_address {
|
|
|
+ return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintTokenOwner).with_account_name(#name_str).with_pubkeys((my_owner, wallet_address)));
|
|
|
+ }
|
|
|
+ let __associated_token_address = anchor_spl::associated_token::get_associated_token_address(&wallet_address, &#spl_token_mint_address.key());
|
|
|
+ let my_key = #name.key();
|
|
|
+ if my_key != __associated_token_address {
|
|
|
+ return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintAssociated).with_account_name(#name_str).with_pubkeys((my_key, __associated_token_address)));
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -743,14 +775,26 @@ fn generate_custom_error(
|
|
|
account_name: &Ident,
|
|
|
custom_error: &Option<Expr>,
|
|
|
error: proc_macro2::TokenStream,
|
|
|
+ compared_values: &Option<&(proc_macro2::TokenStream, proc_macro2::TokenStream)>,
|
|
|
) -> proc_macro2::TokenStream {
|
|
|
let account_name = account_name.to_string();
|
|
|
- match custom_error {
|
|
|
+ let mut error = match custom_error {
|
|
|
Some(error) => {
|
|
|
- quote! { Err(anchor_lang::error::Error::from(#error).with_account_name(#account_name)) }
|
|
|
+ quote! { anchor_lang::error::Error::from(#error).with_account_name(#account_name) }
|
|
|
}
|
|
|
None => {
|
|
|
- quote! { Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::#error).with_account_name(#account_name)) }
|
|
|
+ quote! { anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::#error).with_account_name(#account_name) }
|
|
|
}
|
|
|
+ };
|
|
|
+
|
|
|
+ let compared_values = match compared_values {
|
|
|
+ Some((left, right)) => quote! { .with_pubkeys((#left, #right)) },
|
|
|
+ None => quote! {},
|
|
|
+ };
|
|
|
+
|
|
|
+ error.extend(compared_values);
|
|
|
+
|
|
|
+ quote! {
|
|
|
+ Err(#error)
|
|
|
}
|
|
|
}
|