light_merkle_tree_program/transaction_merkle_tree/update_instructions/
insert_root.rs1use std::ops::DerefMut;
2
3use anchor_lang::{
4 prelude::*,
5 solana_program::{clock::Clock, pubkey::Pubkey, sysvar::Sysvar},
6};
7
8use crate::{
9 errors::ErrorCode,
10 transaction_merkle_tree::{
11 instructions::insert_last_double,
12 state::{TransactionMerkleTree, TwoLeavesBytesPda},
13 },
14 utils::constants::{IX_ORDER, ROOT_INSERT, STORAGE_SEED},
15 MerkleTreeUpdateState,
16};
17#[derive(Accounts)]
18pub struct InsertRoot<'info> {
19 #[account(mut, address=merkle_tree_update_state.load()?.relayer @ErrorCode::InvalidAuthority)]
20 pub authority: Signer<'info>,
21 #[account(
26 mut,
27 seeds = [authority.key().to_bytes().as_ref(), STORAGE_SEED],
28 bump,
29 constraint= transaction_merkle_tree.load()?.pubkey_locked == merkle_tree_update_state.key() @ErrorCode::ContractStillLocked,
30 constraint= IX_ORDER[usize::try_from(merkle_tree_update_state.load()?.current_instruction_index).unwrap()] == ROOT_INSERT @ErrorCode::MerkleTreeUpdateNotInRootInsert,
31 close = authority
32 )]
33 pub merkle_tree_update_state: AccountLoader<'info, MerkleTreeUpdateState>,
36 #[account(mut, address= merkle_tree_update_state.load()?.merkle_tree_pda_pubkey @ErrorCode::InvalidMerkleTree)]
38 pub transaction_merkle_tree: AccountLoader<'info, TransactionMerkleTree>,
39 pub log_wrapper: UncheckedAccount<'info>,
41 pub system_program: Program<'info, System>,
42}
43
44pub fn close_account(account: &AccountInfo, dest_account: &AccountInfo) -> Result<()> {
45 let dest_starting_lamports = dest_account.lamports();
47 **dest_account.lamports.borrow_mut() = dest_starting_lamports
48 .checked_add(account.lamports())
49 .ok_or(ErrorCode::CloseAccountFailed)?;
50 **account.lamports.borrow_mut() = 0;
51 let mut data = account.try_borrow_mut_data()?;
52 for byte in data.deref_mut().iter_mut() {
53 *byte = 0;
54 }
55 Ok(())
56}
57
58pub fn process_insert_root<'a, 'b, 'c, 'info>(
59 ctx: &mut Context<'a, 'b, 'c, 'info, InsertRoot<'info>>,
60) -> Result<()> {
61 let merkle_tree_update_state_data = &mut ctx.accounts.merkle_tree_update_state.load_mut()?;
62 let merkle_tree_pda_data = &mut ctx.accounts.transaction_merkle_tree.load_mut()?;
63
64 let id =
65 IX_ORDER[usize::try_from(merkle_tree_update_state_data.current_instruction_index).unwrap()];
66 msg!("Root insert Instruction: {}", id);
67
68 msg!(
69 "merkle_tree_pda_data.pubkey_locked: {:?}",
70 merkle_tree_pda_data.pubkey_locked
71 );
72
73 msg!(
74 "ctx.accounts.merkle_tree_update_state.key(): {:?}",
75 ctx.accounts.merkle_tree_update_state.key()
76 );
77
78 let mut tmp_index = merkle_tree_pda_data.next_index;
79 msg!("tmp_index: {}", tmp_index);
80
81 msg!("Lock set at slot: {}", merkle_tree_pda_data.time_locked);
85 msg!("Lock released at slot: {}", <Clock as Sysvar>::get()?.slot);
86 merkle_tree_pda_data.time_locked = 0;
87 merkle_tree_pda_data.pubkey_locked =
88 Pubkey::try_from([0; 32]).map_err(|_| ErrorCode::PubkeyTryFromFailed)?;
89
90 msg!("start loop {}", ctx.remaining_accounts.len());
91 for (index, account) in ctx.remaining_accounts.iter().enumerate() {
100 msg!("Copying leaves pair {}", index);
101 msg!("account {:?}", account);
102 let leaves_pda_data: Account<'info, TwoLeavesBytesPda> = Account::try_from(account)?;
103
104 if leaves_pda_data.left_leaf_index < merkle_tree_pda_data.next_index {
106 msg!(
107 "Leaf pda state with address {:?} is already inserted",
108 *account.key
109 );
110 return err!(ErrorCode::LeafAlreadyInserted);
111 }
112
113 if leaves_pda_data.merkle_tree_pubkey != ctx.accounts.transaction_merkle_tree.key() {
115 msg!(
116 "Leaf pda state merkle tree {} is different than passed in merkle tree {:?}",
117 leaves_pda_data.merkle_tree_pubkey,
118 ctx.accounts.transaction_merkle_tree.key()
119 );
120 return err!(ErrorCode::LeavesOfWrongTree);
121 }
122
123 if leaves_pda_data.left_leaf_index != tmp_index {
126 return err!(ErrorCode::FirstLeavesPdaIncorrectIndex);
127 }
128 close_account(account, &ctx.accounts.authority.to_account_info())?;
129
130 tmp_index += 2;
131 }
132
133 insert_last_double(merkle_tree_pda_data, merkle_tree_update_state_data)?;
134
135 Ok(())
136}