1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
use std::convert::TryFrom;
use solana_sdk::{
  signature::{Keypair},
  transaction::TransactionError,
  transport::TransportError,
  instruction::InstructionError,
  program_error::ProgramError,
};

pub enum ProgramInstructionError {
  /// Incorrect authority provided
  IncorrectAuthority = 600,

  /// Cross-program invocation with unauthorized signer or writable account
  PrivilegeEscalation,
}

impl From<ProgramInstructionError> for ProgramError {
  fn from(e: ProgramInstructionError) -> Self {
    ProgramError::Custom(e as u32)
  }
}

pub fn clone_keypair(source: &Keypair) -> Keypair {
  Keypair::from_bytes(&source.to_bytes()).unwrap()
}

pub fn map_transaction_error(transport_error: TransportError) -> ProgramError {
  match transport_error {
    TransportError::TransactionError(TransactionError::InstructionError(
        _,
        InstructionError::Custom(error_index),
    )) => ProgramError::Custom(error_index),
    TransportError::TransactionError(TransactionError::InstructionError(
        _,
        instruction_error,
    )) => ProgramError::try_from(instruction_error).unwrap_or_else(|ie| match ie {
        InstructionError::IncorrectAuthority => {
            ProgramInstructionError::IncorrectAuthority.into()
        }
        InstructionError::PrivilegeEscalation => {
            ProgramInstructionError::PrivilegeEscalation.into()
        }
        _ => panic!("TEST-INSTRUCTION-ERROR {:?}", ie),
    }),

    _ => panic!("TEST-TRANSPORT-ERROR: {:?}", transport_error),
  }
}