I have a smart contract i am working with, in the acceptOffer function, i need to invalidate all previous Offer, by using isAccepted(boolean) back to false,I have search online looking for a way to get it working, and also tried
#[derive(Accounts)]
#[instruction()]
pub struct AcceptOffer<'info> {
#[account(
mut,
seeds = [USER_TAG,authority.key().as_ref()],
bump,
has_one = authority
)]
pub user: Box<Account<'info, User>>,
#[account(mut)]
pub authority: Signer<'info>,
#[account(mut)]
pub offer: Box<Account<'info, Offer>>,
#[account(mut)]
pub previous_offers: Box<Account<'info, Offer>>, // added this line
#[account(mut)]
pub request: Box<Account<'info, Request>>,
pub system_program: Program<'info, System>,
}
but i get error proc-macro panicked: Invariant violation: composite constraints can only be raw or literals
this are my code snippet,the commented section is what I am trying to achieve
#[derive(Accounts)]
#[instruction()]
pub struct AcceptOffer<'info> {
#[account(
mut,
seeds = [USER_TAG,authority.key().as_ref()],
bump,
has_one = authority
)]
pub user: Box<Account<'info, User>>,
#[account(mut)]
pub authority: Signer<'info>,
#[account(mut)]
pub offer: Box<Account<'info, Offer>>,
#[account(mut)]
pub request: Box<Account<'info, Request>>,
pub system_program: Program<'info, System>,
}
pub fn accept_offer(ctx: Context<AcceptOffer>) -> Result<()> {
let user = &mut ctx.accounts.user;
let offer = &mut ctx.accounts.offer;
let request = &mut ctx.accounts.request;
if user.account_type != AccountType::Buyer {
return err!(MarketplaceError::OnlyBuyersAllowed);
}
if request.buyer_id != user.id {
return err!(MarketplaceError::UnauthorizedBuyer);
}
if offer.is_accepted {
return err!(MarketplaceError::OfferAlreadyAccepted);
}
if Clock::get().unwrap().unix_timestamp as u64 > request.updated_at + TIME_TO_LOCK
&& request.lifecycle == RequestLifecycle::AcceptedByBuyer
{
return err!(MarketplaceError::RequestLocked);
}
//TODO: fix this reset
// for prev_offer_id in request.offer_ids.iter() {
// // let previous_offer = &mut ctx.accounts.offers[*prev_offer_id as usize];
// // previous_offer.is_accepted = false;
// // emit!(OfferAccepted {
// // offer_id: previous_offer.id,
// // buyer_address: *ctx.accounts.user.to_account_info().key,
// // is_accepted: false,
// // });
// }
offer.is_accepted = true;
offer.updated_at = Clock::get().unwrap().unix_timestamp as u64;
request.offer_ids.push(offer.id);
request.locked_seller_id = offer.seller_id;
request.sellers_price_quote = offer.price;
request.lifecycle = RequestLifecycle::AcceptedByBuyer;
request.updated_at = Clock::get().unwrap().unix_timestamp as u64;
emit!(RequestAccepted {
request_id: request.id,
offer_id: offer.id,
seller_id: offer.seller_id,
updated_at: request.updated_at,
sellers_price_quote: request.sellers_price_quote,
});
emit!(OfferAccepted {
offer_id: offer.id,
buyer_address: *ctx.accounts.user.to_account_info().key,
is_accepted: true,
});
Ok(())
}
#[account]
pub struct Offer {
pub authority: Pubkey,
pub id: u64,
pub request_id: u64,
pub price: i64,
pub images: Vec<String>,
pub store_name: String,
pub seller_id: u64,
pub is_accepted: bool,
pub created_at: u64,
pub updated_at: u64,
}
#[account]
pub struct Request {
pub authority: Pubkey,
pub id: u64,
pub name: String,
pub buyer_id: u64,
pub description: String,
pub images: Vec<String>,
pub sellers_price_quote: i64,
pub seller_ids: Vec<u64>,
pub offer_ids: Vec<u64>,
pub locked_seller_id: u64,
pub location: Location,
pub created_at: u64,
pub updated_at: u64,
pub lifecycle: RequestLifecycle,
}
#[account]
#[derive(Debug)]
pub struct User {
pub id: u64,
pub username: String,
pub phone: String,
pub location: Location,
pub created_at: i64,
pub updated_at: i64,
pub account_type: AccountType,
pub authority: Pubkey,
}