Refactors the common code of test and bench targets into the solana_runtime::bpf_test_utils module. (#13203)
This commit is contained in:
committed by
GitHub
parent
a9f339a3ed
commit
65ee3a6bdd
@ -6,24 +6,22 @@ extern crate test;
|
|||||||
extern crate solana_bpf_loader_program;
|
extern crate solana_bpf_loader_program;
|
||||||
|
|
||||||
use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
|
use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
|
||||||
use solana_bpf_loader_program::syscalls::SyscallError;
|
|
||||||
use solana_measure::measure::Measure;
|
use solana_measure::measure::Measure;
|
||||||
use solana_rbpf::vm::{EbpfVm, InstructionMeter};
|
use solana_rbpf::vm::{EbpfVm, InstructionMeter};
|
||||||
use solana_runtime::{
|
use solana_runtime::{
|
||||||
bank::Bank,
|
bank::Bank,
|
||||||
bank_client::BankClient,
|
bank_client::BankClient,
|
||||||
|
bpf_test_utils::MockInvokeContext,
|
||||||
genesis_utils::{create_genesis_config, GenesisConfigInfo},
|
genesis_utils::{create_genesis_config, GenesisConfigInfo},
|
||||||
loader_utils::load_program,
|
loader_utils::load_program,
|
||||||
process_instruction::{
|
process_instruction::{ComputeMeter, InvokeContext},
|
||||||
ComputeBudget, ComputeMeter, Executor, InvokeContext, Logger, ProcessInstruction,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account::Account,
|
account::Account,
|
||||||
bpf_loader,
|
bpf_loader,
|
||||||
client::SyncClient,
|
client::SyncClient,
|
||||||
entrypoint::SUCCESS,
|
entrypoint::SUCCESS,
|
||||||
instruction::{AccountMeta, CompiledInstruction, Instruction, InstructionError},
|
instruction::{AccountMeta, Instruction},
|
||||||
message::Message,
|
message::Message,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
signature::{Keypair, Signer},
|
signature::{Keypair, Signer},
|
||||||
@ -193,7 +191,7 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
|
|||||||
const BUDGET: u64 = 200_000;
|
const BUDGET: u64 = 200_000;
|
||||||
let loader_id = bpf_loader::id();
|
let loader_id = bpf_loader::id();
|
||||||
let mut invoke_context = MockInvokeContext::default();
|
let mut invoke_context = MockInvokeContext::default();
|
||||||
invoke_context.compute_meter.borrow_mut().remaining = BUDGET;
|
invoke_context.compute_meter.remaining = BUDGET;
|
||||||
let compute_meter = invoke_context.get_compute_meter();
|
let compute_meter = invoke_context.get_compute_meter();
|
||||||
|
|
||||||
let elf = load_elf("tuner").unwrap();
|
let elf = load_elf("tuner").unwrap();
|
||||||
@ -248,80 +246,6 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
pub struct MockInvokeContext {
|
|
||||||
key: Pubkey,
|
|
||||||
logger: MockLogger,
|
|
||||||
compute_budget: ComputeBudget,
|
|
||||||
compute_meter: Rc<RefCell<MockComputeMeter>>,
|
|
||||||
}
|
|
||||||
impl InvokeContext for MockInvokeContext {
|
|
||||||
fn push(&mut self, _key: &Pubkey) -> Result<(), InstructionError> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
fn pop(&mut self) {}
|
|
||||||
fn verify_and_update(
|
|
||||||
&mut self,
|
|
||||||
_message: &Message,
|
|
||||||
_instruction: &CompiledInstruction,
|
|
||||||
_accounts: &[Rc<RefCell<Account>>],
|
|
||||||
) -> Result<(), InstructionError> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
fn get_caller(&self) -> Result<&Pubkey, InstructionError> {
|
|
||||||
Ok(&self.key)
|
|
||||||
}
|
|
||||||
fn get_programs(&self) -> &[(Pubkey, ProcessInstruction)] {
|
|
||||||
&[]
|
|
||||||
}
|
|
||||||
fn get_logger(&self) -> Rc<RefCell<dyn Logger>> {
|
|
||||||
Rc::new(RefCell::new(self.logger.clone()))
|
|
||||||
}
|
|
||||||
fn get_compute_budget(&self) -> &ComputeBudget {
|
|
||||||
&self.compute_budget
|
|
||||||
}
|
|
||||||
fn get_compute_meter(&self) -> Rc<RefCell<dyn ComputeMeter>> {
|
|
||||||
self.compute_meter.clone()
|
|
||||||
}
|
|
||||||
fn add_executor(&mut self, _pubkey: &Pubkey, _executor: Arc<dyn Executor>) {}
|
|
||||||
fn get_executor(&mut self, _pubkey: &Pubkey) -> Option<Arc<dyn Executor>> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
fn record_instruction(&self, _instruction: &Instruction) {}
|
|
||||||
fn is_feature_active(&self, _feature_id: &Pubkey) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[derive(Debug, Default, Clone)]
|
|
||||||
pub struct MockLogger {
|
|
||||||
pub log: Rc<RefCell<Vec<String>>>,
|
|
||||||
}
|
|
||||||
impl Logger for MockLogger {
|
|
||||||
fn log_enabled(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
fn log(&mut self, message: &str) {
|
|
||||||
self.log.borrow_mut().push(message.to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[derive(Debug, Default, Clone)]
|
|
||||||
pub struct MockComputeMeter {
|
|
||||||
pub remaining: u64,
|
|
||||||
}
|
|
||||||
impl ComputeMeter for MockComputeMeter {
|
|
||||||
fn consume(&mut self, amount: u64) -> Result<(), InstructionError> {
|
|
||||||
let exceeded = self.remaining < amount;
|
|
||||||
self.remaining = self.remaining.saturating_sub(amount);
|
|
||||||
if exceeded {
|
|
||||||
return Err(InstructionError::ComputationalBudgetExceeded);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
fn get_remaining(&self) -> u64 {
|
|
||||||
self.remaining
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Passed to the VM to enforce the compute budget
|
/// Passed to the VM to enforce the compute budget
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct MockInstructionMeter {
|
struct MockInstructionMeter {
|
||||||
|
@ -7,15 +7,14 @@ use solana_bpf_loader_program::{
|
|||||||
create_vm,
|
create_vm,
|
||||||
serialization::{deserialize_parameters, serialize_parameters},
|
serialization::{deserialize_parameters, serialize_parameters},
|
||||||
};
|
};
|
||||||
use solana_rbpf::vm::{EbpfVm, InstructionMeter};
|
use solana_rbpf::vm::EbpfVm;
|
||||||
use solana_runtime::{
|
use solana_runtime::{
|
||||||
bank::Bank,
|
bank::Bank,
|
||||||
bank_client::BankClient,
|
bank_client::BankClient,
|
||||||
|
bpf_test_utils::MockInvokeContext,
|
||||||
genesis_utils::{create_genesis_config, GenesisConfigInfo},
|
genesis_utils::{create_genesis_config, GenesisConfigInfo},
|
||||||
loader_utils::load_program,
|
loader_utils::load_program,
|
||||||
process_instruction::{
|
process_instruction::ComputeBudget,
|
||||||
ComputeBudget, ComputeMeter, Executor, InvokeContext, Logger, ProcessInstruction,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account::Account,
|
account::Account,
|
||||||
@ -31,7 +30,7 @@ use solana_sdk::{
|
|||||||
sysvar::{clock, fees, rent, slot_hashes, stake_history},
|
sysvar::{clock, fees, rent, slot_hashes, stake_history},
|
||||||
transaction::{Transaction, TransactionError},
|
transaction::{Transaction, TransactionError},
|
||||||
};
|
};
|
||||||
use std::{cell::RefCell, env, fs::File, io::Read, path::PathBuf, rc::Rc, sync::Arc};
|
use std::{cell::RefCell, env, fs::File, io::Read, path::PathBuf, sync::Arc};
|
||||||
|
|
||||||
/// BPF program file extension
|
/// BPF program file extension
|
||||||
const PLATFORM_FILE_EXTENSION_BPF: &str = "so";
|
const PLATFORM_FILE_EXTENSION_BPF: &str = "so";
|
||||||
@ -776,82 +775,6 @@ fn assert_instruction_count() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mock InvokeContext
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
struct MockInvokeContext {
|
|
||||||
pub key: Pubkey,
|
|
||||||
pub logger: MockLogger,
|
|
||||||
pub compute_budget: ComputeBudget,
|
|
||||||
pub compute_meter: MockComputeMeter,
|
|
||||||
}
|
|
||||||
impl InvokeContext for MockInvokeContext {
|
|
||||||
fn push(&mut self, _key: &Pubkey) -> Result<(), InstructionError> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
fn pop(&mut self) {}
|
|
||||||
fn verify_and_update(
|
|
||||||
&mut self,
|
|
||||||
_message: &Message,
|
|
||||||
_instruction: &CompiledInstruction,
|
|
||||||
_accounts: &[Rc<RefCell<Account>>],
|
|
||||||
) -> Result<(), InstructionError> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
fn get_caller(&self) -> Result<&Pubkey, InstructionError> {
|
|
||||||
Ok(&self.key)
|
|
||||||
}
|
|
||||||
fn get_programs(&self) -> &[(Pubkey, ProcessInstruction)] {
|
|
||||||
&[]
|
|
||||||
}
|
|
||||||
fn get_logger(&self) -> Rc<RefCell<dyn Logger>> {
|
|
||||||
Rc::new(RefCell::new(self.logger.clone()))
|
|
||||||
}
|
|
||||||
fn get_compute_budget(&self) -> &ComputeBudget {
|
|
||||||
&self.compute_budget
|
|
||||||
}
|
|
||||||
fn get_compute_meter(&self) -> Rc<RefCell<dyn ComputeMeter>> {
|
|
||||||
Rc::new(RefCell::new(self.compute_meter.clone()))
|
|
||||||
}
|
|
||||||
fn add_executor(&mut self, _pubkey: &Pubkey, _executor: Arc<dyn Executor>) {}
|
|
||||||
fn get_executor(&mut self, _pubkey: &Pubkey) -> Option<Arc<dyn Executor>> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
fn record_instruction(&self, _instruction: &Instruction) {}
|
|
||||||
fn is_feature_active(&self, _feature_id: &Pubkey) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
|
||||||
struct MockComputeMeter {}
|
|
||||||
impl ComputeMeter for MockComputeMeter {
|
|
||||||
fn consume(&mut self, _amount: u64) -> Result<(), InstructionError> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
fn get_remaining(&self) -> u64 {
|
|
||||||
u64::MAX
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[derive(Debug, Default, Clone)]
|
|
||||||
struct MockLogger {}
|
|
||||||
impl Logger for MockLogger {
|
|
||||||
fn log_enabled(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
fn log(&mut self, _message: &str) {
|
|
||||||
// println!("{}", message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct TestInstructionMeter {}
|
|
||||||
impl InstructionMeter for TestInstructionMeter {
|
|
||||||
fn consume(&mut self, _amount: u64) {}
|
|
||||||
fn get_remaining(&self) -> u64 {
|
|
||||||
u64::MAX
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(feature = "bpf_rust"))]
|
#[cfg(any(feature = "bpf_rust"))]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_program_bpf_instruction_introspection() {
|
fn test_program_bpf_instruction_introspection() {
|
||||||
|
@ -313,102 +313,14 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use solana_runtime::{
|
use solana_runtime::{
|
||||||
|
bpf_test_utils::MockInvokeContext,
|
||||||
feature_set::FeatureSet,
|
feature_set::FeatureSet,
|
||||||
message_processor::{Executors, ThisInvokeContext},
|
message_processor::{Executors, ThisInvokeContext},
|
||||||
process_instruction::{ComputeBudget, Logger, ProcessInstruction},
|
process_instruction::ComputeBudget,
|
||||||
};
|
|
||||||
use solana_sdk::{
|
|
||||||
account::Account, instruction::CompiledInstruction, instruction::Instruction,
|
|
||||||
message::Message, rent::Rent,
|
|
||||||
};
|
};
|
||||||
|
use solana_sdk::{account::Account, rent::Rent};
|
||||||
use std::{cell::RefCell, fs::File, io::Read, ops::Range, rc::Rc};
|
use std::{cell::RefCell, fs::File, io::Read, ops::Range, rc::Rc};
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
|
||||||
pub struct MockComputeMeter {
|
|
||||||
pub remaining: u64,
|
|
||||||
}
|
|
||||||
impl ComputeMeter for MockComputeMeter {
|
|
||||||
fn consume(&mut self, amount: u64) -> Result<(), InstructionError> {
|
|
||||||
let exceeded = self.remaining < amount;
|
|
||||||
self.remaining = self.remaining.saturating_sub(amount);
|
|
||||||
if exceeded {
|
|
||||||
return Err(InstructionError::ComputationalBudgetExceeded);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
fn get_remaining(&self) -> u64 {
|
|
||||||
self.remaining
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[derive(Debug, Default, Clone)]
|
|
||||||
pub struct MockLogger {
|
|
||||||
pub log: Rc<RefCell<Vec<String>>>,
|
|
||||||
}
|
|
||||||
impl Logger for MockLogger {
|
|
||||||
fn log_enabled(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
fn log(&mut self, message: &str) {
|
|
||||||
self.log.borrow_mut().push(message.to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct MockInvokeContext {
|
|
||||||
pub key: Pubkey,
|
|
||||||
pub logger: MockLogger,
|
|
||||||
pub compute_budget: ComputeBudget,
|
|
||||||
pub compute_meter: MockComputeMeter,
|
|
||||||
}
|
|
||||||
impl Default for MockInvokeContext {
|
|
||||||
fn default() -> Self {
|
|
||||||
MockInvokeContext {
|
|
||||||
key: Pubkey::default(),
|
|
||||||
logger: MockLogger::default(),
|
|
||||||
compute_budget: ComputeBudget::default(),
|
|
||||||
compute_meter: MockComputeMeter {
|
|
||||||
remaining: std::u64::MAX,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl InvokeContext for MockInvokeContext {
|
|
||||||
fn push(&mut self, _key: &Pubkey) -> Result<(), InstructionError> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
fn pop(&mut self) {}
|
|
||||||
fn verify_and_update(
|
|
||||||
&mut self,
|
|
||||||
_message: &Message,
|
|
||||||
_instruction: &CompiledInstruction,
|
|
||||||
_accounts: &[Rc<RefCell<Account>>],
|
|
||||||
) -> Result<(), InstructionError> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
fn get_caller(&self) -> Result<&Pubkey, InstructionError> {
|
|
||||||
Ok(&self.key)
|
|
||||||
}
|
|
||||||
fn get_programs(&self) -> &[(Pubkey, ProcessInstruction)] {
|
|
||||||
&[]
|
|
||||||
}
|
|
||||||
fn get_logger(&self) -> Rc<RefCell<dyn Logger>> {
|
|
||||||
Rc::new(RefCell::new(self.logger.clone()))
|
|
||||||
}
|
|
||||||
fn get_compute_budget(&self) -> &ComputeBudget {
|
|
||||||
&self.compute_budget
|
|
||||||
}
|
|
||||||
fn get_compute_meter(&self) -> Rc<RefCell<dyn ComputeMeter>> {
|
|
||||||
Rc::new(RefCell::new(self.compute_meter.clone()))
|
|
||||||
}
|
|
||||||
fn add_executor(&mut self, _pubkey: &Pubkey, _executor: Arc<dyn Executor>) {}
|
|
||||||
fn get_executor(&mut self, _pubkey: &Pubkey) -> Option<Arc<dyn Executor>> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
fn record_instruction(&self, _instruction: &Instruction) {}
|
|
||||||
fn is_feature_active(&self, _feature_id: &Pubkey) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct TestInstructionMeter {
|
struct TestInstructionMeter {
|
||||||
remaining: u64,
|
remaining: u64,
|
||||||
}
|
}
|
||||||
|
@ -1237,7 +1237,7 @@ fn call<'a>(
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::tests::{MockComputeMeter, MockLogger};
|
use solana_runtime::bpf_test_utils::{MockComputeMeter, MockLogger};
|
||||||
use solana_sdk::hash::hashv;
|
use solana_sdk::hash::hashv;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
96
runtime/src/bpf_test_utils.rs
Normal file
96
runtime/src/bpf_test_utils.rs
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
use crate::process_instruction::{
|
||||||
|
ComputeBudget, ComputeMeter, Executor, InvokeContext, Logger, ProcessInstruction,
|
||||||
|
};
|
||||||
|
use solana_sdk::{
|
||||||
|
account::Account, instruction::CompiledInstruction, instruction::Instruction,
|
||||||
|
instruction::InstructionError, message::Message, pubkey::Pubkey,
|
||||||
|
};
|
||||||
|
use std::{cell::RefCell, rc::Rc, sync::Arc};
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
|
pub struct MockComputeMeter {
|
||||||
|
pub remaining: u64,
|
||||||
|
}
|
||||||
|
impl ComputeMeter for MockComputeMeter {
|
||||||
|
fn consume(&mut self, amount: u64) -> Result<(), InstructionError> {
|
||||||
|
let exceeded = self.remaining < amount;
|
||||||
|
self.remaining = self.remaining.saturating_sub(amount);
|
||||||
|
if exceeded {
|
||||||
|
return Err(InstructionError::ComputationalBudgetExceeded);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn get_remaining(&self) -> u64 {
|
||||||
|
self.remaining
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
|
pub struct MockLogger {
|
||||||
|
pub log: Rc<RefCell<Vec<String>>>,
|
||||||
|
}
|
||||||
|
impl Logger for MockLogger {
|
||||||
|
fn log_enabled(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
fn log(&mut self, message: &str) {
|
||||||
|
self.log.borrow_mut().push(message.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct MockInvokeContext {
|
||||||
|
pub key: Pubkey,
|
||||||
|
pub logger: MockLogger,
|
||||||
|
pub compute_budget: ComputeBudget,
|
||||||
|
pub compute_meter: MockComputeMeter,
|
||||||
|
}
|
||||||
|
impl Default for MockInvokeContext {
|
||||||
|
fn default() -> Self {
|
||||||
|
MockInvokeContext {
|
||||||
|
key: Pubkey::default(),
|
||||||
|
logger: MockLogger::default(),
|
||||||
|
compute_budget: ComputeBudget::default(),
|
||||||
|
compute_meter: MockComputeMeter {
|
||||||
|
remaining: std::i64::MAX as u64,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl InvokeContext for MockInvokeContext {
|
||||||
|
fn push(&mut self, _key: &Pubkey) -> Result<(), InstructionError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn pop(&mut self) {}
|
||||||
|
fn verify_and_update(
|
||||||
|
&mut self,
|
||||||
|
_message: &Message,
|
||||||
|
_instruction: &CompiledInstruction,
|
||||||
|
_accounts: &[Rc<RefCell<Account>>],
|
||||||
|
) -> Result<(), InstructionError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn get_caller(&self) -> Result<&Pubkey, InstructionError> {
|
||||||
|
Ok(&self.key)
|
||||||
|
}
|
||||||
|
fn get_programs(&self) -> &[(Pubkey, ProcessInstruction)] {
|
||||||
|
&[]
|
||||||
|
}
|
||||||
|
fn get_logger(&self) -> Rc<RefCell<dyn Logger>> {
|
||||||
|
Rc::new(RefCell::new(self.logger.clone()))
|
||||||
|
}
|
||||||
|
fn get_compute_budget(&self) -> &ComputeBudget {
|
||||||
|
&self.compute_budget
|
||||||
|
}
|
||||||
|
fn get_compute_meter(&self) -> Rc<RefCell<dyn ComputeMeter>> {
|
||||||
|
Rc::new(RefCell::new(self.compute_meter.clone()))
|
||||||
|
}
|
||||||
|
fn add_executor(&mut self, _pubkey: &Pubkey, _executor: Arc<dyn Executor>) {}
|
||||||
|
fn get_executor(&mut self, _pubkey: &Pubkey) -> Option<Arc<dyn Executor>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
fn record_instruction(&self, _instruction: &Instruction) {}
|
||||||
|
fn is_feature_active(&self, _feature_id: &Pubkey) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ pub mod bank_forks;
|
|||||||
pub mod bank_utils;
|
pub mod bank_utils;
|
||||||
mod blockhash_queue;
|
mod blockhash_queue;
|
||||||
pub mod bloom;
|
pub mod bloom;
|
||||||
|
pub mod bpf_test_utils;
|
||||||
pub mod builtins;
|
pub mod builtins;
|
||||||
pub mod commitment;
|
pub mod commitment;
|
||||||
pub mod epoch_stakes;
|
pub mod epoch_stakes;
|
||||||
|
Reference in New Issue
Block a user