spl_governance/processor/
process_flag_transaction_error.rs

1//! Program state processor
2
3use {
4    crate::state::{
5        enums::{ProposalState, TransactionExecutionStatus},
6        proposal::get_proposal_data,
7        proposal_transaction::get_proposal_transaction_data_for_proposal,
8        token_owner_record::get_token_owner_record_data_for_proposal_owner,
9    },
10    solana_program::{
11        account_info::{next_account_info, AccountInfo},
12        clock::Clock,
13        entrypoint::ProgramResult,
14        pubkey::Pubkey,
15        sysvar::Sysvar,
16    },
17};
18
19/// Processes FlagTransactionError instruction
20pub fn process_flag_transaction_error(
21    program_id: &Pubkey,
22    accounts: &[AccountInfo],
23) -> ProgramResult {
24    let account_info_iter = &mut accounts.iter();
25
26    let proposal_info = next_account_info(account_info_iter)?; // 0
27    let token_owner_record_info = next_account_info(account_info_iter)?; // 1
28    let governance_authority_info = next_account_info(account_info_iter)?; // 2
29
30    let proposal_transaction_info = next_account_info(account_info_iter)?; // 3
31
32    let clock = Clock::get()?;
33
34    let mut proposal_data = get_proposal_data(program_id, proposal_info)?;
35
36    let mut proposal_transaction_data = get_proposal_transaction_data_for_proposal(
37        program_id,
38        proposal_transaction_info,
39        proposal_info.key,
40    )?;
41
42    proposal_data
43        .assert_can_flag_transaction_error(&proposal_transaction_data, clock.unix_timestamp)?;
44
45    let token_owner_record_data = get_token_owner_record_data_for_proposal_owner(
46        program_id,
47        token_owner_record_info,
48        &proposal_data.token_owner_record,
49    )?;
50
51    token_owner_record_data.assert_token_owner_or_delegate_is_signer(governance_authority_info)?;
52
53    // If this is the first instruction to be executed then set executing_at
54    // timestamp It indicates when we started executing instructions for the
55    // Proposal and the fact we only flag it as error is irrelevant here
56    if proposal_data.state == ProposalState::Succeeded {
57        proposal_data.executing_at = Some(clock.unix_timestamp);
58    }
59
60    proposal_data.state = ProposalState::ExecutingWithErrors;
61    proposal_data.serialize(&mut proposal_info.data.borrow_mut()[..])?;
62
63    proposal_transaction_data.execution_status = TransactionExecutionStatus::Error;
64    proposal_transaction_data.serialize(&mut proposal_transaction_info.data.borrow_mut()[..])?;
65
66    Ok(())
67}