trident-svm 0.2.0

Trident SVM implementation by Ackee Blockchain Security
Documentation
use std::collections::HashMap;

use serde::de::DeserializeOwned;
use solana_account::AccountSharedData;
use solana_account::ReadableAccount;
use solana_pubkey::Pubkey;
use solana_sysvar::clock::Clock;
use solana_sysvar::Sysvar;
use solana_sysvar_id::SysvarId;

use super::sysvar_tracker::SysvarTracker;

#[derive(Default)]
pub struct AccountsDB {
    pub(crate) accounts: HashMap<Pubkey, AccountSharedData>,
    pub(crate) permanent_accounts: HashMap<Pubkey, AccountSharedData>,
    pub(crate) programs: HashMap<Pubkey, AccountSharedData>,
    pub(crate) sysvars: HashMap<Pubkey, AccountSharedData>,
    pub(crate) sysvar_tracker: SysvarTracker,
}

impl AccountsDB {
    pub(crate) fn get_temporary_account(&self, pubkey: &Pubkey) -> Option<AccountSharedData> {
        self.accounts.get(pubkey).map(|acc| acc.to_owned())
    }
    pub(crate) fn get_permanent_account(&self, pubkey: &Pubkey) -> Option<AccountSharedData> {
        self.permanent_accounts
            .get(pubkey)
            .map(|acc| acc.to_owned())
    }
    pub(crate) fn get_program(&self, pubkey: &Pubkey) -> Option<AccountSharedData> {
        self.programs.get(pubkey).map(|acc| acc.to_owned())
    }
    pub(crate) fn get_sysvar_account(&self, pubkey: &Pubkey) -> Option<AccountSharedData> {
        self.sysvars.get(pubkey).map(|acc| acc.to_owned())
    }
    pub(crate) fn get_sysvar<T: SysvarId + DeserializeOwned>(&self) -> T {
        if T::id() == Clock::id() {
            self.update_clock();
        }
        self.deserialize_sysvar::<T>()
    }
    pub(crate) fn deserialize_sysvar<T: SysvarId + DeserializeOwned>(&self) -> T {
        let sysvar = self
            .get_sysvar_account(&T::id())
            .expect("The requested sysvar is not available");
        bincode::deserialize(sysvar.data()).expect("Failed to deserialize sysvar account")
    }
}

impl AccountsDB {
    pub(crate) fn set_temporary_account(&mut self, pubkey: &Pubkey, account: &AccountSharedData) {
        let _ = self.accounts.insert(pubkey.to_owned(), account.to_owned());
    }
    pub(crate) fn set_permanent_account(&mut self, pubkey: &Pubkey, account: &AccountSharedData) {
        let _ = self
            .permanent_accounts
            .insert(pubkey.to_owned(), account.to_owned());
    }
    pub(crate) fn set_program(&mut self, pubkey: &Pubkey, account: &AccountSharedData) {
        let _ = self.programs.insert(pubkey.to_owned(), account.to_owned());
    }
    pub(crate) fn set_sysvar<T: Sysvar + SysvarId>(&mut self, sysvar: &T) {
        let account =
            AccountSharedData::new_data(1, &sysvar, &solana_sdk_ids::sysvar::id()).unwrap();
        let _ = self.sysvars.insert(T::id(), account);

        if T::id() == Clock::id() {
            self.sysvar_tracker.refresh();
        }
    }
}

impl AccountsDB {
    pub(crate) fn reset_temp(&mut self) {
        self.accounts = Default::default();
    }
}