arch_program 0.6.4

A Rust library for building programs that run inside the Arch Virtual Machine. Provides core functionality for creating instructions, managing accounts, handling program errors, and interacting with the Arch runtime environment. Includes utilities for logging, transaction handling, and Bitcoin UTXO management.
Documentation
use crate::{
    account::AccountMeta,
    decode_error::DecodeError,
    instruction::{Instruction, InstructionError},
    pubkey::Pubkey,
    system_instruction,
    vote::state::VoteState,
};
use num_derive::{FromPrimitive, ToPrimitive};
use thiserror::Error;

use super::{program::VOTE_PROGRAM_ID, state::VoteInit};

#[derive(Error, Debug, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
pub enum VoteError {
    #[error("not enough credits to redeem")]
    NoCreditsToRedeem,
    #[error("too soon to reauthorize")]
    TooSoonToReauthorize,
}

impl From<VoteError> for InstructionError {
    fn from(error: VoteError) -> Self {
        InstructionError::VoteError(error)
    }
}

impl<E> DecodeError<E> for VoteError {
    fn type_of() -> &'static str {
        "VoteError"
    }
}

#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub enum VoteInstruction {
    /// Initialize a stake with lockup and authorization information
    ///
    /// # Account references
    ///   0. `[WRITE]` Uninitialized validator account
    ///   1. `[]` Rent sysvar
    ///
    /// Authorized carries pubkeys that must sign staker transactions
    ///   and withdrawer transactions.
    /// Lockup carries information about withdrawal restrictions
    Initialize(VoteInit),
    Authorize(Pubkey),
    UpdateCommission(u8),
    InitializeSharedValidatorAccount(Vec<u8>, Vec<u8>, Vec<Vec<u8>>),
    UpdatePubkeyPackage(Vec<u8>),
    AddPeerToWhitelist(Vec<u8>),
    RemovePeerFromWhitelist(Vec<u8>),
}

pub fn initialize(vote_pubkey: &Pubkey, vote_init: &VoteInit) -> Instruction {
    Instruction::new_with_bincode(
        VOTE_PROGRAM_ID,
        VoteInstruction::Initialize(*vote_init),
        vec![AccountMeta::new(*vote_pubkey, false)],
    )
}

pub fn create_account(
    from_pubkey: &Pubkey,
    vote_pubkey: &Pubkey,
    vote_init: &VoteInit,
    lamports: u64,
) -> Vec<Instruction> {
    vec![
        system_instruction::create_account(
            from_pubkey,
            vote_pubkey,
            lamports,
            VoteState::size_of_new() as u64,
            &VOTE_PROGRAM_ID,
        ),
        initialize(vote_pubkey, vote_init),
    ]
}

pub fn authorize(vote_pubkey: &Pubkey, authority: &Pubkey, new_authority: &Pubkey) -> Instruction {
    Instruction::new_with_bincode(
        VOTE_PROGRAM_ID,
        VoteInstruction::Authorize(*new_authority),
        vec![
            AccountMeta::new(*vote_pubkey, false),
            AccountMeta::new(*authority, true),
        ],
    )
}

pub fn update_commission(vote_pubkey: &Pubkey, authority: &Pubkey, commission: u8) -> Instruction {
    Instruction::new_with_bincode(
        VOTE_PROGRAM_ID,
        VoteInstruction::UpdateCommission(commission),
        vec![
            AccountMeta::new(*vote_pubkey, false),
            AccountMeta::new(*authority, true),
        ],
    )
}

pub fn initialize_shared_validator_account(
    shared_validator_pubkey: &Pubkey,
    bootnode_pubkey: &[u8; 33],
    serialized_pubkey_package: &[u8],
    whitelist: &[[u8; 33]],
) -> Instruction {
    Instruction::new_with_bincode(
        VOTE_PROGRAM_ID,
        VoteInstruction::InitializeSharedValidatorAccount(
            bootnode_pubkey.to_vec(),
            serialized_pubkey_package.to_vec(),
            whitelist.iter().map(|p| p.to_vec()).collect(),
        ),
        vec![AccountMeta::new(*shared_validator_pubkey, false)],
    )
}

pub fn update_pubkey_package(
    shared_validator_pubkey: &Pubkey,
    serialized_pubkey_package: &[u8],
) -> Instruction {
    Instruction::new_with_bincode(
        VOTE_PROGRAM_ID,
        VoteInstruction::UpdatePubkeyPackage(serialized_pubkey_package.to_vec()),
        vec![AccountMeta::new(*shared_validator_pubkey, false)],
    )
}

pub fn add_peer_to_whitelist(
    shared_validator_pubkey: &Pubkey,
    bootnode_pubkey: &[u8; 33],
    peer_pubkey: &[u8; 33],
) -> Instruction {
    Instruction::new_with_bincode(
        VOTE_PROGRAM_ID,
        VoteInstruction::AddPeerToWhitelist(peer_pubkey.to_vec()),
        vec![
            AccountMeta::new(*shared_validator_pubkey, false),
            AccountMeta::new(Pubkey::from_slice(&bootnode_pubkey[1..33]), true),
        ],
    )
}

pub fn remove_peer_from_whitelist(
    shared_validator_pubkey: &Pubkey,
    bootnode_pubkey: &[u8; 33],
    peer_pubkey: &[u8; 33],
) -> Instruction {
    Instruction::new_with_bincode(
        VOTE_PROGRAM_ID,
        VoteInstruction::RemovePeerFromWhitelist(peer_pubkey.to_vec()),
        vec![
            AccountMeta::new(*shared_validator_pubkey, false),
            AccountMeta::new(Pubkey::from_slice(&bootnode_pubkey[1..33]), true),
        ],
    )
}