Support Debug Bank (#13017)
This commit is contained in:
parent
6c55aaf4c7
commit
c0675968b1
|
@ -156,7 +156,7 @@ mod tests {
|
||||||
.get(&deserialized_bank.slot())
|
.get(&deserialized_bank.slot())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone();
|
.clone();
|
||||||
assert!(*bank == deserialized_bank);
|
assert_eq!(*bank, deserialized_bank);
|
||||||
|
|
||||||
let slot_snapshot_paths = snapshot_utils::get_snapshot_paths(&snapshot_path);
|
let slot_snapshot_paths = snapshot_utils::get_snapshot_paths(&snapshot_path);
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ use solana_sdk::{
|
||||||
program_utils::limited_deserialize,
|
program_utils::limited_deserialize,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
use std::{cell::RefCell, rc::Rc, sync::Arc};
|
use std::{cell::RefCell, fmt::Debug, rc::Rc, sync::Arc};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
solana_sdk::declare_builtin!(
|
solana_sdk::declare_builtin!(
|
||||||
|
@ -214,6 +214,14 @@ impl InstructionMeter for ThisInstructionMeter {
|
||||||
pub struct BPFExecutor {
|
pub struct BPFExecutor {
|
||||||
executable: Box<dyn Executable<BPFError>>,
|
executable: Box<dyn Executable<BPFError>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Well, implement Debug for solana_rbpf::vm::Executable in solana-rbpf...
|
||||||
|
impl Debug for BPFExecutor {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(f, "BPFExecutor({:p})", self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Executor for BPFExecutor {
|
impl Executor for BPFExecutor {
|
||||||
fn execute(
|
fn execute(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -17,7 +17,10 @@ use crate::{
|
||||||
instruction_recorder::InstructionRecorder,
|
instruction_recorder::InstructionRecorder,
|
||||||
log_collector::LogCollector,
|
log_collector::LogCollector,
|
||||||
message_processor::{Executors, MessageProcessor},
|
message_processor::{Executors, MessageProcessor},
|
||||||
process_instruction::{Executor, ProcessInstruction, ProcessInstructionWithContext},
|
process_instruction::{
|
||||||
|
ErasedProcessInstruction, ErasedProcessInstructionWithContext, Executor,
|
||||||
|
ProcessInstruction, ProcessInstructionWithContext,
|
||||||
|
},
|
||||||
rent_collector::RentCollector,
|
rent_collector::RentCollector,
|
||||||
stakes::Stakes,
|
stakes::Stakes,
|
||||||
status_cache::{SlotDelta, StatusCache},
|
status_cache::{SlotDelta, StatusCache},
|
||||||
|
@ -139,7 +142,31 @@ pub enum Entrypoint {
|
||||||
Loader(ProcessInstructionWithContext),
|
Loader(ProcessInstructionWithContext),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
impl fmt::Debug for Entrypoint {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum EntrypointForDebug {
|
||||||
|
Program(String),
|
||||||
|
Loader(String),
|
||||||
|
}
|
||||||
|
// rustc doesn't compile due to bug without this work around
|
||||||
|
// https://github.com/rust-lang/rust/issues/50280
|
||||||
|
// https://users.rust-lang.org/t/display-function-pointer/17073/2
|
||||||
|
let entrypoint = match self {
|
||||||
|
Entrypoint::Program(instruction) => EntrypointForDebug::Program(format!(
|
||||||
|
"{:p}",
|
||||||
|
*instruction as ErasedProcessInstruction
|
||||||
|
)),
|
||||||
|
Entrypoint::Loader(instruction) => EntrypointForDebug::Loader(format!(
|
||||||
|
"{:p}",
|
||||||
|
*instruction as ErasedProcessInstructionWithContext
|
||||||
|
)),
|
||||||
|
};
|
||||||
|
write!(f, "{:?}", entrypoint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
pub struct Builtin {
|
pub struct Builtin {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub id: Pubkey,
|
pub id: Pubkey,
|
||||||
|
@ -156,7 +183,7 @@ impl Builtin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Copy-on-write holder of CachedExecutors
|
/// Copy-on-write holder of CachedExecutors
|
||||||
#[derive(AbiExample, Default)]
|
#[derive(AbiExample, Debug, Default)]
|
||||||
struct CowCachedExecutors {
|
struct CowCachedExecutors {
|
||||||
shared: bool,
|
shared: bool,
|
||||||
executors: Arc<RwLock<CachedExecutors>>,
|
executors: Arc<RwLock<CachedExecutors>>,
|
||||||
|
@ -200,7 +227,7 @@ impl AbiExample for Builtin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Builtins {
|
pub struct Builtins {
|
||||||
/// Builtin programs that are always available
|
/// Builtin programs that are always available
|
||||||
pub genesis_builtins: Vec<Builtin>,
|
pub genesis_builtins: Vec<Builtin>,
|
||||||
|
@ -212,6 +239,7 @@ pub struct Builtins {
|
||||||
const MAX_CACHED_EXECUTORS: usize = 100; // 10 MB assuming programs are around 100k
|
const MAX_CACHED_EXECUTORS: usize = 100; // 10 MB assuming programs are around 100k
|
||||||
|
|
||||||
/// LFU Cache of executors
|
/// LFU Cache of executors
|
||||||
|
#[derive(Debug)]
|
||||||
struct CachedExecutors {
|
struct CachedExecutors {
|
||||||
max: usize,
|
max: usize,
|
||||||
executors: HashMap<Pubkey, (AtomicU64, Arc<dyn Executor>)>,
|
executors: HashMap<Pubkey, (AtomicU64, Arc<dyn Executor>)>,
|
||||||
|
@ -289,7 +317,7 @@ impl CachedExecutors {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, Debug)]
|
||||||
pub struct BankRc {
|
pub struct BankRc {
|
||||||
/// where all the Accounts are stored
|
/// where all the Accounts are stored
|
||||||
pub accounts: Arc<Accounts>,
|
pub accounts: Arc<Accounts>,
|
||||||
|
@ -330,7 +358,7 @@ impl BankRc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, AbiExample)]
|
#[derive(Default, Debug, AbiExample)]
|
||||||
pub struct StatusCacheRc {
|
pub struct StatusCacheRc {
|
||||||
/// where all the Accounts are stored
|
/// where all the Accounts are stored
|
||||||
/// A cache of signature statuses
|
/// A cache of signature statuses
|
||||||
|
@ -411,7 +439,7 @@ impl HashAgeKind {
|
||||||
// Bank's common fields shared by all supported snapshot versions for deserialization.
|
// Bank's common fields shared by all supported snapshot versions for deserialization.
|
||||||
// Sync fields with BankFieldsToSerialize! This is paired with it.
|
// Sync fields with BankFieldsToSerialize! This is paired with it.
|
||||||
// All members are made public to remain Bank's members private and to make versioned deserializer workable on this
|
// All members are made public to remain Bank's members private and to make versioned deserializer workable on this
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub(crate) struct BankFieldsToDeserialize {
|
pub(crate) struct BankFieldsToDeserialize {
|
||||||
pub(crate) blockhash_queue: BlockhashQueue,
|
pub(crate) blockhash_queue: BlockhashQueue,
|
||||||
pub(crate) ancestors: Ancestors,
|
pub(crate) ancestors: Ancestors,
|
||||||
|
@ -558,7 +586,7 @@ pub struct RewardInfo {
|
||||||
/// Manager for the state of all accounts and programs after processing its entries.
|
/// Manager for the state of all accounts and programs after processing its entries.
|
||||||
/// AbiExample is needed even without Serialize/Deserialize; actual (de-)serialization
|
/// AbiExample is needed even without Serialize/Deserialize; actual (de-)serialization
|
||||||
/// are implemented elsewhere for versioning
|
/// are implemented elsewhere for versioning
|
||||||
#[derive(AbiExample, Default)]
|
#[derive(AbiExample, Debug, Default)]
|
||||||
pub struct Bank {
|
pub struct Bank {
|
||||||
/// References to accounts, parent and signature status
|
/// References to accounts, parent and signature status
|
||||||
pub rc: BankRc,
|
pub rc: BankRc,
|
||||||
|
@ -9319,6 +9347,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct TestExecutor {}
|
struct TestExecutor {}
|
||||||
impl Executor for TestExecutor {
|
impl Executor for TestExecutor {
|
||||||
fn execute(
|
fn execute(
|
||||||
|
@ -9972,4 +10001,34 @@ mod tests {
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_debug_bank() {
|
||||||
|
let (genesis_config, _mint_keypair) = create_genesis_config(50000);
|
||||||
|
let mut bank = Bank::new(&genesis_config);
|
||||||
|
bank.finish_init(&genesis_config, None);
|
||||||
|
let debug = format!("{:#?}", bank);
|
||||||
|
assert!(!debug.is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_debug_entrypoint() {
|
||||||
|
fn mock_process_instruction(
|
||||||
|
_program_id: &Pubkey,
|
||||||
|
_keyed_accounts: &[KeyedAccount],
|
||||||
|
_data: &[u8],
|
||||||
|
) -> std::result::Result<(), InstructionError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn mock_ix_processor(
|
||||||
|
_pubkey: &Pubkey,
|
||||||
|
_ka: &[KeyedAccount],
|
||||||
|
_data: &[u8],
|
||||||
|
_context: &mut dyn InvokeContext,
|
||||||
|
) -> std::result::Result<(), InstructionError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
assert!(!format!("{:?}", Entrypoint::Program(mock_process_instruction)).is_empty());
|
||||||
|
assert!(!format!("{:?}", Entrypoint::Loader(mock_ix_processor)).is_empty());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,7 @@ lazy_static! {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `FeatureSet` holds the set of currently active/inactive runtime features
|
/// `FeatureSet` holds the set of currently active/inactive runtime features
|
||||||
#[derive(AbiExample, Clone)]
|
#[derive(AbiExample, Debug, Clone)]
|
||||||
pub struct FeatureSet {
|
pub struct FeatureSet {
|
||||||
pub active: HashSet<Pubkey>,
|
pub active: HashSet<Pubkey>,
|
||||||
pub inactive: HashSet<Pubkey>,
|
pub inactive: HashSet<Pubkey>,
|
||||||
|
|
|
@ -1679,7 +1679,7 @@ mod tests {
|
||||||
_ka: &[KeyedAccount],
|
_ka: &[KeyedAccount],
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
_context: &mut dyn InvokeContext,
|
_context: &mut dyn InvokeContext,
|
||||||
) -> std::result::Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
let program_id = Pubkey::new_rand();
|
let program_id = Pubkey::new_rand();
|
||||||
|
|
|
@ -8,7 +8,7 @@ use solana_sdk::{
|
||||||
message::Message,
|
message::Message,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
use std::{cell::RefCell, rc::Rc, sync::Arc};
|
use std::{cell::RefCell, fmt::Debug, rc::Rc, sync::Arc};
|
||||||
|
|
||||||
// Prototype of a native loader entry point
|
// Prototype of a native loader entry point
|
||||||
///
|
///
|
||||||
|
@ -174,7 +174,7 @@ pub trait Logger {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Program executor
|
/// Program executor
|
||||||
pub trait Executor: Send + Sync {
|
pub trait Executor: Debug + Send + Sync {
|
||||||
/// Execute the program
|
/// Execute the program
|
||||||
fn execute(
|
fn execute(
|
||||||
&self,
|
&self,
|
||||||
|
|
Loading…
Reference in New Issue