trident-svm 0.3.0-rc.1

Trident SVM implementation by Ackee Blockchain Security
Documentation
use solana_account::AccountSharedData;
use solana_pubkey::Pubkey;

use solana_account::WritableAccount;
use solana_loader_v3_interface::state::UpgradeableLoaderState;
use solana_sysvar::rent::Rent;

pub struct TridentAccountSharedData {
    pub address: Pubkey,
    pub account: AccountSharedData,
}
impl TridentAccountSharedData {
    pub fn new(address: Pubkey, account: AccountSharedData) -> TridentAccountSharedData {
        Self { address, account }
    }

    pub fn loader_v2_program(address: Pubkey, data: &[u8]) -> TridentAccountSharedData {
        let rent = Rent::default();

        let account_data = AccountSharedData::create(
            rent.minimum_balance(data.len()),
            data.to_vec(),
            solana_sdk_ids::bpf_loader::id(),
            true,
            Default::default(),
        );

        TridentAccountSharedData::new(address, account_data)
    }

    pub fn loader_v3_program(
        address: Pubkey,
        data: &[u8],
        authority: Option<Pubkey>,
    ) -> Vec<TridentAccountSharedData> {
        let mut accounts = Vec::new();

        let rent = Rent::default();

        let program_account = &address;

        let program_data_account =
            solana_loader_v3_interface::get_program_data_address(program_account);

        let state = UpgradeableLoaderState::Program {
            programdata_address: program_data_account,
        };

        let buffer = bincode::serialize(&state).unwrap();
        let account_data = AccountSharedData::create(
            rent.minimum_balance(buffer.len()),
            buffer,
            solana_sdk_ids::bpf_loader_upgradeable::id(),
            true,
            Default::default(),
        );

        accounts.push(TridentAccountSharedData::new(
            *program_account,
            account_data,
        ));

        let state = UpgradeableLoaderState::ProgramData {
            slot: 0,
            upgrade_authority_address: authority,
        };
        let mut header = bincode::serialize(&state).unwrap();

        let mut complement = vec![
            0;
            std::cmp::max(
                0,
                UpgradeableLoaderState::size_of_programdata_metadata().saturating_sub(header.len())
            )
        ];

        let mut buffer: Vec<u8> = data.to_vec();
        header.append(&mut complement);
        header.append(&mut buffer);

        let account_data = AccountSharedData::create(
            rent.minimum_balance(header.len()),
            header,
            solana_sdk_ids::bpf_loader_upgradeable::id(),
            true,
            Default::default(),
        );

        accounts.push(TridentAccountSharedData::new(
            program_data_account,
            account_data,
        ));

        accounts
    }
}