This reverts commit c42b80f099
.
This commit is contained in:
parent
ebe3d2d59d
commit
7e08ae1d0c
|
@ -1593,10 +1593,7 @@ impl ReplayStage {
|
|||
root_slot,
|
||||
my_pubkey,
|
||||
rpc_subscriptions,
|
||||
NewBankOptions {
|
||||
vote_only_bank,
|
||||
simulation_bank: false,
|
||||
},
|
||||
NewBankOptions { vote_only_bank },
|
||||
);
|
||||
|
||||
let tpu_bank = bank_forks.write().unwrap().insert(tpu_bank);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,7 +26,6 @@ itertools = "0.10.1"
|
|||
log = "0.4.11"
|
||||
miow = "0.3.6"
|
||||
net2 = "0.2.37"
|
||||
solana-account-decoder = { path = "../../account-decoder", version = "=1.10.0" }
|
||||
solana-bpf-rust-invoke = { path = "rust/invoke", version = "=1.10.0"}
|
||||
solana-bpf-loader-program = { path = "../bpf_loader", version = "=1.10.0"}
|
||||
solana-bpf-rust-realloc = { path = "rust/realloc", version = "=1.10.0"}
|
||||
|
@ -39,6 +38,7 @@ solana-runtime = { path = "../../runtime", version = "=1.10.0" }
|
|||
solana-program-runtime = { path = "../../program-runtime", version = "=1.10.0" }
|
||||
solana-sdk = { path = "../../sdk", version = "=1.10.0" }
|
||||
solana-transaction-status = { path = "../../transaction-status", version = "=1.10.0" }
|
||||
solana-account-decoder = { path = "../../account-decoder", version = "=1.10.0" }
|
||||
|
||||
[[bench]]
|
||||
name = "bpf_loader"
|
||||
|
@ -83,7 +83,6 @@ members = [
|
|||
"rust/sha",
|
||||
"rust/sibling_inner_instruction",
|
||||
"rust/sibling_instruction",
|
||||
"rust/simulation",
|
||||
"rust/spoof1",
|
||||
"rust/spoof1_system",
|
||||
"rust/sysvar",
|
||||
|
|
|
@ -93,7 +93,6 @@ fn main() {
|
|||
"sha",
|
||||
"sibling_inner_instruction",
|
||||
"sibling_instruction",
|
||||
"simulation",
|
||||
"spoof1",
|
||||
"spoof1_system",
|
||||
"upgradeable",
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
[package]
|
||||
name = "solana-bpf-rust-simulation"
|
||||
version = "1.10.0"
|
||||
description = "Solana BPF Program Simulation Differences"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
documentation = "https://docs.rs/solana-bpf-rust-simulation"
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
test-bpf = []
|
||||
|
||||
[dependencies]
|
||||
solana-program = { path = "../../../../sdk/program", version = "=1.10.0" }
|
||||
|
||||
[dev-dependencies]
|
||||
solana-logger = { path = "../../../../logger", version = "=1.10.0" }
|
||||
solana-program-test = { path = "../../../../program-test", version = "=1.10.0" }
|
||||
solana-sdk = { path = "../../../../sdk", version = "=1.10.0" }
|
||||
solana-validator = { path = "../../../../validator", version = "=1.10.0" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "lib"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
|
@ -1,39 +0,0 @@
|
|||
use solana_program::{
|
||||
account_info::{next_account_info, AccountInfo},
|
||||
clock::Clock,
|
||||
declare_id, entrypoint,
|
||||
entrypoint::ProgramResult,
|
||||
msg,
|
||||
pubkey::Pubkey,
|
||||
sysvar::Sysvar,
|
||||
};
|
||||
use std::convert::TryInto;
|
||||
|
||||
declare_id!("Sim1jD5C35odT8mzctm8BWnjic8xW5xgeb5MbcbErTo");
|
||||
|
||||
entrypoint!(process_instruction);
|
||||
|
||||
pub fn process_instruction(
|
||||
_program_id: &Pubkey,
|
||||
accounts: &[AccountInfo],
|
||||
_instruction_data: &[u8],
|
||||
) -> ProgramResult {
|
||||
let account_info_iter = &mut accounts.iter();
|
||||
let slot_account = next_account_info(account_info_iter)?;
|
||||
|
||||
// Slot is an u64 at the end of the structure
|
||||
let data = slot_account.data.borrow();
|
||||
let slot: u64 = u64::from_le_bytes(data[data.len() - 8..].try_into().unwrap());
|
||||
|
||||
let clock = Clock::get().unwrap();
|
||||
|
||||
msg!("next_slot is {:?} ", slot);
|
||||
msg!("clock is in slot {:?} ", clock.slot);
|
||||
if clock.slot >= slot {
|
||||
msg!("On-chain");
|
||||
} else {
|
||||
panic!("Simulation");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
#![cfg(feature = "test-bpf")]
|
||||
|
||||
use {
|
||||
solana_bpf_rust_simulation::process_instruction,
|
||||
solana_program_test::{processor, tokio, ProgramTest},
|
||||
solana_sdk::{
|
||||
instruction::{AccountMeta, Instruction},
|
||||
pubkey::Pubkey,
|
||||
signature::Signer,
|
||||
sysvar,
|
||||
transaction::Transaction,
|
||||
},
|
||||
};
|
||||
|
||||
#[tokio::test]
|
||||
async fn no_panic() {
|
||||
let program_id = Pubkey::new_unique();
|
||||
let program_test = ProgramTest::new(
|
||||
"solana_bpf_rust_simulation",
|
||||
program_id,
|
||||
processor!(process_instruction),
|
||||
);
|
||||
|
||||
let mut context = program_test.start_with_context().await;
|
||||
let transaction = Transaction::new_signed_with_payer(
|
||||
&[Instruction {
|
||||
program_id,
|
||||
accounts: vec![AccountMeta::new_readonly(sysvar::slot_history::id(), false)],
|
||||
data: vec![],
|
||||
}],
|
||||
Some(&context.payer.pubkey()),
|
||||
&[&context.payer],
|
||||
context.last_blockhash,
|
||||
);
|
||||
|
||||
context
|
||||
.banks_client
|
||||
.process_transaction_with_preflight(transaction)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
#![cfg(feature = "test-bpf")]
|
||||
|
||||
use {
|
||||
solana_program::{
|
||||
instruction::{AccountMeta, Instruction},
|
||||
pubkey::Pubkey,
|
||||
sysvar,
|
||||
},
|
||||
solana_sdk::{signature::Signer, transaction::Transaction},
|
||||
solana_validator::test_validator::*,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn no_panic() {
|
||||
solana_logger::setup_with_default("solana_program_runtime=debug");
|
||||
let program_id = Pubkey::new_unique();
|
||||
|
||||
let (test_validator, payer) = TestValidatorGenesis::default()
|
||||
.add_program("solana_bpf_rust_simulation", program_id)
|
||||
.start();
|
||||
let rpc_client = test_validator.get_rpc_client();
|
||||
let blockhash = rpc_client.get_latest_blockhash().unwrap();
|
||||
|
||||
let transaction = Transaction::new_signed_with_payer(
|
||||
&[Instruction {
|
||||
program_id,
|
||||
accounts: vec![AccountMeta::new_readonly(sysvar::slot_history::id(), false)],
|
||||
data: vec![],
|
||||
}],
|
||||
Some(&payer.pubkey()),
|
||||
&[&payer],
|
||||
blockhash,
|
||||
);
|
||||
|
||||
rpc_client
|
||||
.send_and_confirm_transaction(&transaction)
|
||||
.unwrap();
|
||||
}
|
|
@ -3472,7 +3472,7 @@ pub mod rpc_full {
|
|||
let preflight_commitment = config
|
||||
.preflight_commitment
|
||||
.map(|commitment| CommitmentConfig { commitment });
|
||||
let preflight_bank = meta.bank(preflight_commitment);
|
||||
let preflight_bank = &*meta.bank(preflight_commitment);
|
||||
let transaction = sanitize_transaction(unsanitized_tx)?;
|
||||
let signature = *transaction.signature();
|
||||
|
||||
|
@ -3569,7 +3569,7 @@ pub mod rpc_full {
|
|||
let (_, mut unsanitized_tx) =
|
||||
decode_and_deserialize::<VersionedTransaction>(data, encoding)?;
|
||||
|
||||
let bank = meta.bank(config.commitment);
|
||||
let bank = &*meta.bank(config.commitment);
|
||||
if config.replace_recent_blockhash {
|
||||
if config.sig_verify {
|
||||
return Err(Error::invalid_params(
|
||||
|
@ -3637,7 +3637,7 @@ pub mod rpc_full {
|
|||
};
|
||||
|
||||
Ok(new_response(
|
||||
&bank,
|
||||
bank,
|
||||
RpcSimulateTransactionResult {
|
||||
err: result.err(),
|
||||
logs: Some(logs),
|
||||
|
|
|
@ -199,16 +199,9 @@ impl Accounts {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new_from_parent(
|
||||
parent: &Accounts,
|
||||
slot: Slot,
|
||||
parent_slot: Slot,
|
||||
simulation_bank: bool,
|
||||
) -> Self {
|
||||
pub fn new_from_parent(parent: &Accounts, slot: Slot, parent_slot: Slot) -> Self {
|
||||
let accounts_db = parent.accounts_db.clone();
|
||||
if !simulation_bank {
|
||||
accounts_db.set_hash(slot, parent_slot);
|
||||
}
|
||||
Self {
|
||||
accounts_db,
|
||||
account_locks: Mutex::new(AccountLocks::default()),
|
||||
|
|
|
@ -1035,18 +1035,6 @@ pub trait DropCallback: fmt::Debug {
|
|||
fn clone_box(&self) -> Box<dyn DropCallback + Send + Sync>;
|
||||
}
|
||||
|
||||
/// Noop callback on dropping banks is useful for simulation banks, which are
|
||||
/// new banks created from a frozen bank, but should not be purged in the same
|
||||
/// way.
|
||||
#[derive(Debug, Clone)]
|
||||
struct NoopDropCallback;
|
||||
impl DropCallback for NoopDropCallback {
|
||||
fn callback(&self, _b: &Bank) {}
|
||||
fn clone_box(&self) -> Box<dyn DropCallback + Send + Sync> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize, AbiExample, Clone, Copy)]
|
||||
pub struct RewardInfo {
|
||||
pub reward_type: RewardType,
|
||||
|
@ -1265,7 +1253,6 @@ struct LoadVoteAndStakeAccountsResult {
|
|||
#[derive(Debug, Default)]
|
||||
pub struct NewBankOptions {
|
||||
pub vote_only_bank: bool,
|
||||
pub simulation_bank: bool,
|
||||
}
|
||||
|
||||
impl Bank {
|
||||
|
@ -1540,10 +1527,7 @@ impl Bank {
|
|||
new_bank_options: NewBankOptions,
|
||||
) -> Self {
|
||||
let mut time = Measure::start("bank::new_from_parent");
|
||||
let NewBankOptions {
|
||||
vote_only_bank,
|
||||
simulation_bank,
|
||||
} = new_bank_options;
|
||||
let NewBankOptions { vote_only_bank } = new_bank_options;
|
||||
|
||||
parent.freeze();
|
||||
assert_ne!(slot, parent.slot());
|
||||
|
@ -1557,7 +1541,6 @@ impl Bank {
|
|||
&parent.rc.accounts,
|
||||
slot,
|
||||
parent.slot(),
|
||||
simulation_bank,
|
||||
)),
|
||||
parent: RwLock::new(Some(parent.clone())),
|
||||
slot,
|
||||
|
@ -1647,20 +1630,6 @@ impl Bank {
|
|||
let (feature_set, feature_set_time) =
|
||||
Measure::this(|_| parent.feature_set.clone(), (), "feature_set_creation");
|
||||
|
||||
let drop_callback = if simulation_bank {
|
||||
RwLock::new(OptionalDropCallback(Some(Box::new(NoopDropCallback))))
|
||||
} else {
|
||||
RwLock::new(OptionalDropCallback(
|
||||
parent
|
||||
.drop_callback
|
||||
.read()
|
||||
.unwrap()
|
||||
.0
|
||||
.as_ref()
|
||||
.map(|drop_callback| drop_callback.clone_box()),
|
||||
))
|
||||
};
|
||||
|
||||
let mut new = Bank {
|
||||
rc,
|
||||
src,
|
||||
|
@ -1714,7 +1683,15 @@ impl Bank {
|
|||
transaction_log_collector_config,
|
||||
transaction_log_collector: Arc::new(RwLock::new(TransactionLogCollector::default())),
|
||||
feature_set,
|
||||
drop_callback,
|
||||
drop_callback: RwLock::new(OptionalDropCallback(
|
||||
parent
|
||||
.drop_callback
|
||||
.read()
|
||||
.unwrap()
|
||||
.0
|
||||
.as_ref()
|
||||
.map(|drop_callback| drop_callback.clone_box()),
|
||||
)),
|
||||
freeze_started: AtomicBool::new(false),
|
||||
cost_tracker: RwLock::new(CostTracker::default()),
|
||||
sysvar_cache: RwLock::new(SysvarCache::default()),
|
||||
|
@ -3495,26 +3472,12 @@ impl Bank {
|
|||
|
||||
/// Run transactions against a frozen bank without committing the results
|
||||
pub fn simulate_transaction(
|
||||
self: &Arc<Bank>,
|
||||
&self,
|
||||
transaction: SanitizedTransaction,
|
||||
) -> TransactionSimulationResult {
|
||||
assert!(self.is_frozen(), "simulation bank must be frozen");
|
||||
|
||||
// Simulation detection countermeasure 1: Create a new child bank for the simulation. This
|
||||
// ensures comparing the slot values between the Clock and SlotHistory sysvars does not
|
||||
// reveal that the program is running in simulation.
|
||||
//
|
||||
// Reference: https://opcodes.fr/en/publications/2022-01/detecting-transaction-simulation/
|
||||
let bank = Bank::new_from_parent_with_options(
|
||||
self,
|
||||
&Pubkey::default(),
|
||||
self.slot().saturating_add(1),
|
||||
NewBankOptions {
|
||||
simulation_bank: true,
|
||||
..NewBankOptions::default()
|
||||
},
|
||||
);
|
||||
bank.simulate_transaction_unchecked(transaction)
|
||||
self.simulate_transaction_unchecked(transaction)
|
||||
}
|
||||
|
||||
/// Run transactions against a bank without committing the results; does not check if the bank
|
||||
|
|
Loading…
Reference in New Issue