armaniferrante 4 年之前
父节点
当前提交
424823b482
共有 3 个文件被更改,包括 167 次插入5 次删除
  1. 2 0
      Cargo.lock
  2. 5 3
      lang/Cargo.toml
  3. 160 2
      lang/src/fuzzing.rs

+ 2 - 0
Cargo.lock

@@ -180,9 +180,11 @@ dependencies = [
  "anchor-attribute-state",
  "anchor-derive-accounts",
  "base64 0.13.0",
+ "bincode",
  "borsh",
  "bumpalo",
  "lazy_static",
+ "num-derive",
  "rand 0.7.3",
  "safe-transmute",
  "solana-program",

+ 5 - 3
lang/Cargo.toml

@@ -9,7 +9,7 @@ description = "Solana Sealevel eDSL"
 
 [features]
 derive = []
-fuzzing = ["lazy_static", "spl-token", "bumpalo", "rand", "safe-transmute"]
+fuzzing = ["bincode", "lazy_static", "spl-token", "bumpalo", "rand", "safe-transmute", "num-derive"]
 default = []
 
 [dependencies]
@@ -27,8 +27,10 @@ thiserror = "1.0.20"
 base64 = "0.13.0"
 
 # Fuzz deps.
-lazy_static = { version = "1.4.0", optional = true }
-spl-token = { version = "3.0.1", features = ["no-entrypoint"], optional = true }
+bincode = { version = "1.3.1", optional = true }
 bumpalo = { version = "3.4.0", features = ["collections", "boxed"], optional = true }
+lazy_static = { version = "1.4.0", optional = true }
 rand = { version = "0.7.3", optional = true }
 safe-transmute = { version = "0.11.0", optional = true }
+spl-token = { version = "3.0.1", features = ["no-entrypoint"], optional = true }
+num-derive = { version = "0.3.3", optional = true }

+ 160 - 2
lang/src/fuzzing.rs

@@ -2,14 +2,18 @@
 
 use bumpalo::Bump;
 use safe_transmute::to_bytes::transmute_to_bytes;
+use solana_program::account_info::next_account_info;
 use solana_program::account_info::AccountInfo;
 use solana_program::bpf_loader;
 use solana_program::clock::Epoch;
 use solana_program::entrypoint::ProgramResult;
 use solana_program::instruction::Instruction;
+use solana_program::program_error::ProgramError;
 use solana_program::program_pack::Pack;
 use solana_program::pubkey::Pubkey;
 use solana_program::rent::Rent;
+use solana_program::system_instruction::SystemError;
+use solana_program::system_instruction::SystemInstruction;
 use solana_program::system_program;
 use solana_program::sysvar::{self, Sysvar};
 use spl_token::state::Account as TokenAccount;
@@ -18,6 +22,7 @@ use std::collections::HashMap;
 use std::fmt::Debug;
 use std::mem::size_of;
 use std::sync::{Arc, Mutex, MutexGuard};
+use thiserror::Error;
 
 lazy_static::lazy_static! {
     static ref ENV: Arc<Mutex<Environment>> = Arc::new(Mutex::new(Environment::new()));
@@ -238,9 +243,120 @@ impl Program for SplToken {
     }
 }
 
+// Bare minimum implementation of the system program. Not all instructions are
+// implemented. PRs are welcome.
 #[derive(Debug)]
 struct SystemProgram;
 
+impl SystemProgram {
+    fn create_account(
+        &self,
+        accounts: &[AccountInfo],
+        lamports: u64,
+        space: u64,
+        owner: Pubkey,
+    ) -> ProgramResult {
+        let acc_infos = &mut accounts.into_iter();
+
+        let from = next_account_info(acc_infos)?;
+        let created = next_account_info(acc_infos)?;
+
+        if **created.lamports.borrow() > 0 {
+            return Err(ProgramError::Custom(
+                SystemError::AccountAlreadyInUse.to_u32(),
+            ));
+        }
+
+        **from.lamports.borrow_mut() -= lamports;
+        **created.lamports.borrow_mut() += lamports;
+
+        Ok(())
+    }
+
+    fn transfer(&self, accounts: &[AccountInfo], lamports: u64) -> ProgramResult {
+        let acc_infos = &mut accounts.into_iter();
+
+        let from = next_account_info(acc_infos)?;
+        let to = next_account_info(acc_infos)?;
+
+        **from.lamports.borrow_mut() -= lamports;
+        **to.lamports.borrow_mut() += lamports;
+
+        Ok(())
+    }
+
+    fn create_account_with_seed(
+        &self,
+        accounts: &[AccountInfo],
+        base: Pubkey,
+        seed: String,
+        lamports: u64,
+        space: u64,
+        owner: Pubkey,
+    ) -> ProgramResult {
+        unimplemented!()
+    }
+
+    fn assign(&self, _accounts: &[AccountInfo], owner: Pubkey) -> ProgramResult {
+        unimplemented!()
+    }
+
+    fn advance_nonce_account(&self, _accounts: &[AccountInfo]) -> ProgramResult {
+        unimplemented!()
+    }
+
+    fn withdraw_nonce_account(&self, _accounts: &[AccountInfo], _lamports: u64) -> ProgramResult {
+        unimplemented!()
+    }
+
+    fn initialize_nonce_account(
+        &self,
+        _accounts: &[AccountInfo],
+        _entity: Pubkey,
+    ) -> ProgramResult {
+        unimplemented!()
+    }
+
+    fn authorize_nonce_account(&self, _accounts: &[AccountInfo], _entity: Pubkey) -> ProgramResult {
+        unimplemented!()
+    }
+
+    fn allocate(&self, _accounts: &[AccountInfo], _space: u64) -> ProgramResult {
+        unimplemented!()
+    }
+
+    fn allocate_with_seed(
+        &self,
+        _accounts: &[AccountInfo],
+        _base: Pubkey,
+        _seed: String,
+        _space: u64,
+        _owner: Pubkey,
+    ) -> ProgramResult {
+        unimplemented!()
+    }
+
+    fn assign_with_seed(
+        &self,
+        _accounts: &[AccountInfo],
+        _base: Pubkey,
+        _seed: String,
+        _owner: Pubkey,
+    ) -> ProgramResult {
+        unimplemented!()
+    }
+
+    fn transfer_with_seed(
+        &self,
+        _accounts: &[AccountInfo],
+        _lamports: u64,
+        _from_seed: String,
+        _from_owner: Pubkey,
+    ) -> ProgramResult {
+        unimplemented!()
+    }
+}
+
 impl Program for SystemProgram {
     fn entry(
         &self,
@@ -248,8 +364,50 @@ impl Program for SystemProgram {
         accounts: &[AccountInfo],
         ix_data: &[u8],
     ) -> ProgramResult {
-        // todo
-        Ok(())
+        let ix: SystemInstruction =
+            bincode::deserialize(ix_data).map_err(|_| ProgramError::InvalidInstructionData)?;
+
+        match ix {
+            SystemInstruction::CreateAccount {
+                lamports,
+                space,
+                owner,
+            } => self.create_account(accounts, lamports, space, owner),
+            SystemInstruction::Transfer { lamports } => self.transfer(accounts, lamports),
+            SystemInstruction::CreateAccountWithSeed {
+                base,
+                seed,
+                lamports,
+                space,
+                owner,
+            } => self.create_account_with_seed(accounts, base, seed, lamports, space, owner),
+            SystemInstruction::Assign { owner } => self.assign(accounts, owner),
+            SystemInstruction::AdvanceNonceAccount => self.advance_nonce_account(accounts),
+            SystemInstruction::WithdrawNonceAccount(lamports) => {
+                self.withdraw_nonce_account(accounts, lamports)
+            }
+            SystemInstruction::InitializeNonceAccount(entity) => {
+                self.initialize_nonce_account(accounts, entity)
+            }
+            SystemInstruction::AuthorizeNonceAccount(entity) => {
+                self.authorize_nonce_account(accounts, entity)
+            }
+            SystemInstruction::Allocate { space } => self.allocate(accounts, space),
+            SystemInstruction::AllocateWithSeed {
+                base,
+                seed,
+                space,
+                owner,
+            } => self.allocate_with_seed(accounts, base, seed, space, owner),
+            SystemInstruction::AssignWithSeed { base, seed, owner } => {
+                self.assign_with_seed(accounts, base, seed, owner)
+            }
+            SystemInstruction::TransferWithSeed {
+                lamports,
+                from_seed,
+                from_owner,
+            } => self.transfer_with_seed(accounts, lamports, from_seed, from_owner),
+        }
     }
     fn id(&self) -> Pubkey {
         system_program::ID