Add simulation detection countermeasure (#22880)

* Add simulation detection countermeasures

* Add program and test using TestValidator

* Remove incinerator deposit

* Remove incinerator

* Update Cargo.lock

* Add more features to simulation bank

* Update Cargo.lock per rebase

Co-authored-by: Jon Cinque <jon.cinque@gmail.com>
This commit is contained in:
Michael Vines
2022-02-15 04:09:59 -08:00
committed by GitHub
parent d2a407a9a7
commit c42b80f099
11 changed files with 2824 additions and 166 deletions

View File

@ -0,0 +1,28 @@
[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"]

View File

@ -0,0 +1,39 @@
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(())
}

View File

@ -0,0 +1,41 @@
#![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();
}

View File

@ -0,0 +1,38 @@
#![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();
}