solana.rs 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752
  1. // SPDX-License-Identifier: Apache-2.0
  2. use crate::borsh_encoding::{decode_at_offset, encode_arguments, BorshToken};
  3. use anchor_syn::idl::Idl;
  4. use base58::{FromBase58, ToBase58};
  5. use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
  6. use libc::c_char;
  7. use rand::Rng;
  8. use serde::{Deserialize, Serialize};
  9. use sha2::{Digest, Sha256};
  10. use solana_rbpf::{
  11. ebpf,
  12. elf::Executable,
  13. error::EbpfError,
  14. memory_region::{AccessType, MemoryMapping, MemoryRegion},
  15. verifier::RequisiteVerifier,
  16. vm::{
  17. BuiltInProgram, Config, ContextObject, EbpfVm, ProgramResult, StableResult,
  18. VerifiedExecutable,
  19. },
  20. };
  21. use solang::{
  22. abi::anchor::{discriminator, generate_anchor_idl},
  23. compile,
  24. file_resolver::FileResolver,
  25. Target,
  26. };
  27. use std::{
  28. cell::{RefCell, RefMut},
  29. collections::HashMap,
  30. convert::TryInto,
  31. ffi::OsStr,
  32. io::Write,
  33. mem::size_of,
  34. rc::Rc,
  35. sync::Arc,
  36. };
  37. use tiny_keccak::{Hasher, Keccak};
  38. mod borsh_encoding;
  39. mod solana_tests;
  40. /// Error handling for syscall methods
  41. macro_rules! question_mark {
  42. ( $value:expr, $result:ident ) => {{
  43. let value = $value;
  44. match value {
  45. Err(err) => {
  46. *$result = ProgramResult::Err(err.into());
  47. return;
  48. }
  49. Ok(value) => value,
  50. }
  51. }};
  52. }
  53. pub type Account = [u8; 32];
  54. pub fn account_new() -> Account {
  55. let mut rng = rand::thread_rng();
  56. let mut a = [0u8; 32];
  57. rng.fill(&mut a[..]);
  58. a
  59. }
  60. #[derive(Default)]
  61. struct AccountState {
  62. data: Vec<u8>,
  63. owner: Option<Account>,
  64. lamports: u64,
  65. }
  66. /// We have a special callback function which tests that the correct
  67. /// parameters are passed in during CPI.
  68. type CallParametersCheck = fn(vm: &VirtualMachine, instr: &Instruction, pda: &[Pubkey]);
  69. struct VirtualMachine {
  70. account_data: HashMap<Account, AccountState>,
  71. origin: Account,
  72. programs: Vec<Contract>,
  73. stack: Vec<Contract>,
  74. logs: String,
  75. events: Vec<Vec<Vec<u8>>>,
  76. return_data: Option<(Account, Vec<u8>)>,
  77. call_params_check: HashMap<Pubkey, CallParametersCheck>,
  78. }
  79. #[derive(Clone)]
  80. struct Contract {
  81. program: Account,
  82. idl: Option<Idl>,
  83. data: Account,
  84. }
  85. #[derive(Serialize)]
  86. struct ClockLayout {
  87. slot: u64,
  88. epoch_start_timestamp: u64,
  89. epoch: u64,
  90. leader_schedule_epoch: u64,
  91. unix_timestamp: u64,
  92. }
  93. #[derive(Deserialize)]
  94. struct CreateAccount {
  95. instruction: u32,
  96. _lamports: u64,
  97. space: u64,
  98. program_id: Account,
  99. }
  100. #[derive(Deserialize)]
  101. struct CreateAccountWithSeed {
  102. instruction: u32,
  103. base: Account,
  104. seed: String,
  105. _lamports: u64,
  106. space: u64,
  107. program_id: Account,
  108. }
  109. #[derive(Deserialize)]
  110. struct Allocate {
  111. instruction: u32,
  112. space: u64,
  113. }
  114. #[derive(Deserialize)]
  115. struct Assign {
  116. instruction: u32,
  117. owner: Account,
  118. }
  119. fn build_solidity(src: &str) -> VirtualMachine {
  120. let mut cache = FileResolver::new();
  121. cache.set_file_contents("test.sol", src.to_string());
  122. let (res, ns) = compile(
  123. OsStr::new("test.sol"),
  124. &mut cache,
  125. inkwell::OptimizationLevel::Default,
  126. Target::Solana,
  127. false,
  128. true,
  129. true,
  130. #[cfg(feature = "wasm_opt")]
  131. None,
  132. );
  133. ns.print_diagnostics_in_plain(&cache, false);
  134. assert!(!res.is_empty());
  135. let mut account_data = HashMap::new();
  136. let mut programs = Vec::new();
  137. for contract_no in 0..ns.contracts.len() {
  138. let contract = &ns.contracts[contract_no];
  139. if !contract.instantiable {
  140. continue;
  141. }
  142. let code = contract.code.get().unwrap();
  143. let idl = generate_anchor_idl(contract_no, &ns);
  144. let program = if let Some(program_id) = &contract.program_id {
  145. program_id.clone().try_into().unwrap()
  146. } else {
  147. account_new()
  148. };
  149. account_data.insert(
  150. program,
  151. AccountState {
  152. data: code.clone(),
  153. owner: None,
  154. lamports: 0,
  155. },
  156. );
  157. let data = account_new();
  158. account_data.insert(
  159. data,
  160. AccountState {
  161. data: [0u8; 4096].to_vec(),
  162. owner: Some(program),
  163. lamports: 0,
  164. },
  165. );
  166. programs.push(Contract {
  167. program,
  168. idl: Some(idl),
  169. data,
  170. });
  171. }
  172. // Add clock account
  173. let clock_account: Account = "SysvarC1ock11111111111111111111111111111111"
  174. .from_base58()
  175. .unwrap()
  176. .try_into()
  177. .unwrap();
  178. let clock_layout = ClockLayout {
  179. slot: 70818331,
  180. epoch: 102,
  181. epoch_start_timestamp: 946684800,
  182. leader_schedule_epoch: 1231231312,
  183. unix_timestamp: 1620656423,
  184. };
  185. account_data.insert(
  186. clock_account,
  187. AccountState {
  188. data: bincode::serialize(&clock_layout).unwrap(),
  189. owner: None,
  190. lamports: 0,
  191. },
  192. );
  193. let cur = programs.last().unwrap().clone();
  194. let origin = account_new();
  195. account_data.insert(
  196. origin,
  197. AccountState {
  198. data: Vec::new(),
  199. owner: None,
  200. lamports: 0,
  201. },
  202. );
  203. VirtualMachine {
  204. account_data,
  205. origin,
  206. programs,
  207. stack: vec![cur],
  208. logs: String::new(),
  209. events: Vec::new(),
  210. return_data: None,
  211. call_params_check: HashMap::new(),
  212. }
  213. }
  214. const MAX_PERMITTED_DATA_INCREASE: usize = 10 * 1024;
  215. struct AccountRef {
  216. account: Account,
  217. owner_offset: usize,
  218. data_offset: usize,
  219. length: usize,
  220. }
  221. enum SerializableAccount {
  222. Unique(AccountMeta),
  223. Duplicate(usize),
  224. }
  225. fn remove_duplicates(metas: &[AccountMeta]) -> Vec<SerializableAccount> {
  226. let mut serializable_format: Vec<SerializableAccount> = Vec::new();
  227. let mut inserted: HashMap<AccountMeta, usize> = HashMap::new();
  228. for (idx, account) in metas.iter().enumerate() {
  229. if let Some(idx) = inserted.get(account) {
  230. serializable_format.push(SerializableAccount::Duplicate(*idx));
  231. } else {
  232. serializable_format.push(SerializableAccount::Unique(account.clone()));
  233. inserted.insert(account.clone(), idx);
  234. }
  235. }
  236. serializable_format
  237. }
  238. fn serialize_parameters(
  239. input: &[u8],
  240. metas: &[AccountMeta],
  241. vm: &VirtualMachine,
  242. ) -> (Vec<u8>, Vec<AccountRef>) {
  243. let mut refs = Vec::new();
  244. let mut v: Vec<u8> = Vec::new();
  245. #[allow(clippy::ptr_arg)]
  246. fn serialize_account(
  247. v: &mut Vec<u8>,
  248. refs: &mut Vec<AccountRef>,
  249. meta: &AccountMeta,
  250. acc: &AccountState,
  251. ) {
  252. // dup_info
  253. v.write_u8(0xff).unwrap();
  254. // signer
  255. v.write_u8(meta.is_signer.into()).unwrap();
  256. // is_writable
  257. v.write_u8(meta.is_writable.into()).unwrap();
  258. // executable
  259. v.write_u8(1).unwrap();
  260. // padding
  261. v.write_all(&[0u8; 4]).unwrap();
  262. // key
  263. v.write_all(&meta.pubkey.0).unwrap();
  264. // owner
  265. let owner_offset = v.len();
  266. v.write_all(&acc.owner.unwrap_or([0u8; 32])).unwrap();
  267. // lamports
  268. v.write_u64::<LittleEndian>(acc.lamports).unwrap();
  269. // account data
  270. v.write_u64::<LittleEndian>(acc.data.len() as u64).unwrap();
  271. refs.push(AccountRef {
  272. account: meta.pubkey.0,
  273. owner_offset,
  274. data_offset: v.len(),
  275. length: acc.data.len(),
  276. });
  277. v.write_all(&acc.data).unwrap();
  278. v.write_all(&[0u8; MAX_PERMITTED_DATA_INCREASE]).unwrap();
  279. let padding = v.len() % 8;
  280. if padding != 0 {
  281. let mut p = Vec::new();
  282. p.resize(8 - padding, 0);
  283. v.extend_from_slice(&p);
  284. }
  285. // rent epoch
  286. v.write_u64::<LittleEndian>(0).unwrap();
  287. }
  288. let no_duplicates_meta = remove_duplicates(metas);
  289. // ka_num
  290. v.write_u64::<LittleEndian>(no_duplicates_meta.len() as u64)
  291. .unwrap();
  292. for account_item in &no_duplicates_meta {
  293. match account_item {
  294. SerializableAccount::Unique(account) => {
  295. serialize_account(
  296. &mut v,
  297. &mut refs,
  298. account,
  299. &vm.account_data[&account.pubkey.0],
  300. );
  301. }
  302. SerializableAccount::Duplicate(idx) => {
  303. v.write_u64::<LittleEndian>(*idx as u64).unwrap();
  304. }
  305. }
  306. }
  307. // calldata
  308. v.write_u64::<LittleEndian>(input.len() as u64).unwrap();
  309. v.write_all(input).unwrap();
  310. // program id
  311. v.write_all(&vm.stack[0].program).unwrap();
  312. (v, refs)
  313. }
  314. // We want to extract the account data
  315. fn deserialize_parameters(
  316. input: &[u8],
  317. refs: &[AccountRef],
  318. accounts_data: &mut HashMap<Account, AccountState>,
  319. ) {
  320. for r in refs {
  321. if let Some(entry) = accounts_data.get_mut(&r.account) {
  322. let data = input[r.data_offset..r.data_offset + r.length].to_vec();
  323. entry.data = data;
  324. entry.lamports = u64::from_ne_bytes(
  325. input[r.data_offset - 16..r.data_offset - 8]
  326. .try_into()
  327. .unwrap(),
  328. );
  329. }
  330. }
  331. }
  332. // We want to extract the account data
  333. fn update_parameters(
  334. input: &[u8],
  335. mut refs: RefMut<&mut Vec<AccountRef>>,
  336. accounts_data: &HashMap<Account, AccountState>,
  337. ) {
  338. for r in refs.iter_mut() {
  339. if let Some(entry) = accounts_data.get(&r.account) {
  340. r.length = entry.data.len();
  341. unsafe {
  342. std::ptr::copy(
  343. r.length.to_le_bytes().as_ptr(),
  344. input[r.data_offset - 8..].as_ptr() as *mut u8,
  345. 8,
  346. );
  347. }
  348. unsafe {
  349. std::ptr::copy(
  350. entry.data.as_ptr(),
  351. input[r.data_offset..].as_ptr() as *mut u8,
  352. r.length,
  353. );
  354. }
  355. if let Some(owner) = &entry.owner {
  356. unsafe {
  357. std::ptr::copy(
  358. owner.as_ptr(),
  359. input[r.owner_offset..].as_ptr() as *mut u8,
  360. 32,
  361. );
  362. }
  363. }
  364. }
  365. }
  366. }
  367. #[derive(Clone)]
  368. struct SyscallContext<'a> {
  369. vm: Rc<RefCell<&'a mut VirtualMachine>>,
  370. input_len: usize,
  371. refs: Rc<RefCell<&'a mut Vec<AccountRef>>>,
  372. heap: *const u8,
  373. pub remaining: u64,
  374. }
  375. impl<'a> ContextObject for SyscallContext<'a> {
  376. fn trace(&mut self, _state: [u64; 12]) {}
  377. fn consume(&mut self, amount: u64) {
  378. debug_assert!(amount <= self.remaining, "Execution count exceeded");
  379. self.remaining = self.remaining.saturating_sub(amount);
  380. }
  381. fn get_remaining(&self) -> u64 {
  382. self.remaining
  383. }
  384. }
  385. impl<'a> SyscallContext<'a> {
  386. pub fn heap_verify(&self) {
  387. const VERBOSE: bool = false;
  388. let heap: &[u8] = unsafe { std::slice::from_raw_parts(self.heap, DEFAULT_HEAP_SIZE) };
  389. const HEAP_START: u64 = 0x3_0000_0000;
  390. let mut current_elem = HEAP_START;
  391. let mut last_elem = 0;
  392. let read_u64 = |offset: u64| {
  393. let offset = (offset - HEAP_START) as usize;
  394. u64::from_le_bytes(heap[offset..offset + 8].try_into().unwrap())
  395. };
  396. if VERBOSE {
  397. println!("heap verify:");
  398. }
  399. loop {
  400. let next: u64 = read_u64(current_elem);
  401. let prev: u64 = read_u64(current_elem + 8);
  402. let length: u64 = read_u64(current_elem + 16);
  403. let allocated: u64 = read_u64(current_elem + 24);
  404. if VERBOSE {
  405. println!("next:{next:08x} prev:{prev:08x} length:{length} allocated:{allocated}");
  406. }
  407. let start = (current_elem + 8 * 4 - HEAP_START) as usize;
  408. let buf = &heap[start..start + length as usize];
  409. if allocated == 0 {
  410. if VERBOSE {
  411. println!("{:08x} {} not allocated", current_elem + 32, length);
  412. }
  413. } else {
  414. if VERBOSE {
  415. println!("{:08x} {} allocated", current_elem + 32, length);
  416. }
  417. assert_eq!(allocated & 0xffff, 1);
  418. for offset in (0..buf.len()).step_by(16) {
  419. use std::fmt::Write;
  420. let mut hex = "\t".to_string();
  421. let mut chars = "\t".to_string();
  422. for i in 0..16 {
  423. if offset + i >= buf.len() {
  424. break;
  425. }
  426. let b = buf[offset + i];
  427. write!(hex, " {b:02x}").unwrap();
  428. if b.is_ascii() && !b.is_ascii_control() {
  429. write!(chars, " {}", b as char).unwrap();
  430. } else {
  431. chars.push_str(" ");
  432. }
  433. }
  434. if VERBOSE {
  435. println!("{hex}\n{chars}");
  436. }
  437. }
  438. }
  439. assert_eq!(last_elem, prev);
  440. if next == 0 {
  441. break;
  442. }
  443. last_elem = current_elem;
  444. current_elem = next;
  445. }
  446. if VERBOSE {
  447. println!("heap verify done");
  448. }
  449. }
  450. }
  451. fn sol_panic_(
  452. _context: &mut SyscallContext,
  453. _src: u64,
  454. _len: u64,
  455. _dest: u64,
  456. _arg4: u64,
  457. _arg5: u64,
  458. _memory_mapping: &mut MemoryMapping,
  459. result: &mut ProgramResult,
  460. ) {
  461. println!("sol_panic_()");
  462. *result = ProgramResult::Err(EbpfError::ExecutionOverrun(0));
  463. }
  464. fn sol_log(
  465. context: &mut SyscallContext,
  466. vm_addr: u64,
  467. len: u64,
  468. _arg3: u64,
  469. _arg4: u64,
  470. _arg5: u64,
  471. memory_mapping: &mut MemoryMapping,
  472. result: &mut ProgramResult,
  473. ) {
  474. context.heap_verify();
  475. let host_addr = memory_mapping
  476. .map(AccessType::Load, vm_addr, len, 0)
  477. .unwrap();
  478. let c_buf: *const c_char = host_addr as *const c_char;
  479. unsafe {
  480. for i in 0..len {
  481. let c = std::ptr::read(c_buf.offset(i as isize));
  482. if c == 0 {
  483. break;
  484. }
  485. }
  486. let message = std::str::from_utf8(std::slice::from_raw_parts(
  487. host_addr as *const u8,
  488. len as usize,
  489. ))
  490. .unwrap();
  491. println!("log: {message}");
  492. if let Ok(mut vm) = context.vm.try_borrow_mut() {
  493. vm.logs.push_str(message);
  494. }
  495. *result = ProgramResult::Ok(0)
  496. }
  497. }
  498. fn sol_log_pubkey(
  499. context: &mut SyscallContext,
  500. pubkey_addr: u64,
  501. _arg2: u64,
  502. _arg3: u64,
  503. _arg4: u64,
  504. _arg5: u64,
  505. memory_mapping: &mut MemoryMapping,
  506. result: &mut ProgramResult,
  507. ) {
  508. context.heap_verify();
  509. let account = translate_slice::<Account>(memory_mapping, pubkey_addr, 1).unwrap();
  510. let message = account[0].to_base58();
  511. println!("log pubkey: {message}");
  512. if let Ok(mut vm) = context.vm.try_borrow_mut() {
  513. vm.logs.push_str(&message);
  514. }
  515. *result = ProgramResult::Ok(0)
  516. }
  517. fn sol_log_u64(
  518. context: &mut SyscallContext,
  519. arg1: u64,
  520. arg2: u64,
  521. arg3: u64,
  522. arg4: u64,
  523. arg5: u64,
  524. _memory_mapping: &mut MemoryMapping,
  525. result: &mut ProgramResult,
  526. ) {
  527. let message = format!("{arg1:#x}, {arg2:#x}, {arg3:#x}, {arg4:#x}, {arg5:#x}");
  528. println!("log64: {message}");
  529. context.heap_verify();
  530. if let Ok(mut vm) = context.vm.try_borrow_mut() {
  531. vm.logs.push_str(&message);
  532. }
  533. *result = ProgramResult::Ok(0)
  534. }
  535. fn sol_sha256(
  536. context: &mut SyscallContext,
  537. src: u64,
  538. len: u64,
  539. dest: u64,
  540. _arg4: u64,
  541. _arg5: u64,
  542. memory_mapping: &mut MemoryMapping,
  543. result: &mut ProgramResult,
  544. ) {
  545. context.heap_verify();
  546. let arrays = question_mark!(
  547. translate_slice::<(u64, u64)>(memory_mapping, src, len),
  548. result
  549. );
  550. let mut hasher = Sha256::new();
  551. for (addr, len) in arrays {
  552. let buf = question_mark!(translate_slice::<u8>(memory_mapping, *addr, *len), result);
  553. println!("hashing: {}", hex::encode(buf));
  554. hasher.update(buf);
  555. }
  556. let hash = hasher.finalize();
  557. let hash_result = question_mark!(
  558. translate_slice_mut::<u8>(memory_mapping, dest, hash.len() as u64),
  559. result
  560. );
  561. hash_result.copy_from_slice(&hash);
  562. println!("sol_sha256: {}", hex::encode(hash));
  563. *result = ProgramResult::Ok(0)
  564. }
  565. fn sol_keccak256(
  566. context: &mut SyscallContext,
  567. src: u64,
  568. len: u64,
  569. dest: u64,
  570. _arg4: u64,
  571. _arg5: u64,
  572. memory_mapping: &mut MemoryMapping,
  573. result: &mut ProgramResult,
  574. ) {
  575. context.heap_verify();
  576. let arrays = question_mark!(
  577. translate_slice::<(u64, u64)>(memory_mapping, src, len),
  578. result
  579. );
  580. let mut hasher = Keccak::v256();
  581. let mut hash = [0u8; 32];
  582. for (addr, len) in arrays {
  583. let buf = question_mark!(translate_slice::<u8>(memory_mapping, *addr, *len), result);
  584. println!("hashing: {}", hex::encode(buf));
  585. hasher.update(buf);
  586. }
  587. hasher.finalize(&mut hash);
  588. let hash_result = question_mark!(
  589. translate_slice_mut::<u8>(memory_mapping, dest, hash.len() as u64),
  590. result
  591. );
  592. hash_result.copy_from_slice(&hash);
  593. println!("sol_keccak256: {}", hex::encode(hash));
  594. *result = ProgramResult::Ok(0)
  595. }
  596. fn sol_create_program_address(
  597. _context: &mut SyscallContext,
  598. seed_ptr: u64,
  599. seed_len: u64,
  600. program_id: u64,
  601. dest: u64,
  602. _arg5: u64,
  603. memory_mapping: &mut MemoryMapping,
  604. result: &mut ProgramResult,
  605. ) {
  606. assert!(seed_len <= 16);
  607. let arrays = question_mark!(
  608. translate_slice::<(u64, u64)>(memory_mapping, seed_ptr, seed_len),
  609. result
  610. );
  611. let mut seeds = Vec::new();
  612. for (addr, len) in arrays {
  613. assert!(*len < 32);
  614. let buf = question_mark!(translate_slice::<u8>(memory_mapping, *addr, *len), result);
  615. println!("seed:{}", hex::encode(buf));
  616. seeds.push(buf);
  617. }
  618. let program_id = question_mark!(
  619. translate_type::<Account>(memory_mapping, program_id),
  620. result
  621. );
  622. println!("program_id:{}", program_id.to_base58());
  623. let pda = create_program_address(program_id, &seeds);
  624. let hash_result = question_mark!(translate_slice_mut::<u8>(memory_mapping, dest, 32), result);
  625. hash_result.copy_from_slice(&pda.0);
  626. println!("sol_create_program_address: {}", pda.0.to_base58());
  627. *result = ProgramResult::Ok(0)
  628. }
  629. fn sol_try_find_program_address(
  630. _context: &mut SyscallContext,
  631. seed_ptr: u64,
  632. seed_len: u64,
  633. program_id: u64,
  634. dest: u64,
  635. bump: u64,
  636. memory_mapping: &mut MemoryMapping,
  637. result: &mut ProgramResult,
  638. ) {
  639. assert!(seed_len <= 16);
  640. let arrays = question_mark!(
  641. translate_slice::<(u64, u64)>(memory_mapping, seed_ptr, seed_len),
  642. result
  643. );
  644. let mut seeds = Vec::new();
  645. for (addr, len) in arrays {
  646. assert!(*len < 32);
  647. let buf = translate_slice::<u8>(memory_mapping, *addr, *len).unwrap();
  648. println!("seed:{}", hex::encode(buf));
  649. seeds.push(buf);
  650. }
  651. let program_id = question_mark!(
  652. translate_type::<Account>(memory_mapping, program_id),
  653. result
  654. );
  655. println!("program_id:{}", program_id.to_base58());
  656. let bump_seed = [std::u8::MAX];
  657. let mut seeds_with_bump = seeds.to_vec();
  658. seeds_with_bump.push(&bump_seed);
  659. let pda = create_program_address(program_id, &seeds_with_bump);
  660. let hash_result = question_mark!(translate_slice_mut::<u8>(memory_mapping, dest, 32), result);
  661. hash_result.copy_from_slice(&pda.0);
  662. let bump_result = question_mark!(translate_slice_mut::<u8>(memory_mapping, bump, 1), result);
  663. bump_result.copy_from_slice(&bump_seed);
  664. println!(
  665. "sol_try_find_program_address: {} {:x}",
  666. pda.0.to_base58(),
  667. bump_seed[0]
  668. );
  669. *result = ProgramResult::Ok(0)
  670. }
  671. fn sol_set_return_data(
  672. context: &mut SyscallContext,
  673. addr: u64,
  674. len: u64,
  675. _arg3: u64,
  676. _arg4: u64,
  677. _arg5: u64,
  678. memory_mapping: &mut MemoryMapping,
  679. result: &mut ProgramResult,
  680. ) {
  681. context.heap_verify();
  682. assert!(len <= 1024, "sol_set_return_data: length is {len}");
  683. let buf = question_mark!(translate_slice::<u8>(memory_mapping, addr, len), result);
  684. println!("sol_set_return_data: {}", hex::encode(buf));
  685. if let Ok(mut vm) = context.vm.try_borrow_mut() {
  686. if len == 0 {
  687. vm.return_data = None;
  688. } else {
  689. vm.return_data = Some((vm.stack[0].program, buf.to_vec()));
  690. }
  691. *result = ProgramResult::Ok(0);
  692. } else {
  693. panic!();
  694. }
  695. }
  696. fn sol_get_return_data(
  697. context: &mut SyscallContext,
  698. addr: u64,
  699. len: u64,
  700. program_id_addr: u64,
  701. _arg4: u64,
  702. _arg5: u64,
  703. memory_mapping: &mut MemoryMapping,
  704. result: &mut ProgramResult,
  705. ) {
  706. context.heap_verify();
  707. if let Ok(vm) = context.vm.try_borrow() {
  708. if let Some((program_id, return_data)) = &vm.return_data {
  709. let length = std::cmp::min(len, return_data.len() as u64);
  710. if len > 0 {
  711. let set_result = question_mark!(
  712. translate_slice_mut::<u8>(memory_mapping, addr, length),
  713. result
  714. );
  715. set_result.copy_from_slice(&return_data[..length as usize]);
  716. let program_id_result = question_mark!(
  717. translate_slice_mut::<u8>(memory_mapping, program_id_addr, 32),
  718. result
  719. );
  720. program_id_result.copy_from_slice(program_id);
  721. }
  722. *result = ProgramResult::Ok(return_data.len() as u64);
  723. } else {
  724. *result = ProgramResult::Ok(0);
  725. }
  726. } else {
  727. panic!();
  728. }
  729. }
  730. fn sol_log_data(
  731. context: &mut SyscallContext,
  732. addr: u64,
  733. len: u64,
  734. _arg3: u64,
  735. _arg4: u64,
  736. _arg5: u64,
  737. memory_mapping: &mut MemoryMapping,
  738. result: &mut ProgramResult,
  739. ) {
  740. context.heap_verify();
  741. if let Ok(mut vm) = context.vm.try_borrow_mut() {
  742. print!("sol_log_data");
  743. let untranslated_events =
  744. question_mark!(translate_slice::<&[u8]>(memory_mapping, addr, len), result);
  745. let mut events = Vec::with_capacity(untranslated_events.len());
  746. for untranslated_event in untranslated_events {
  747. let event = question_mark!(
  748. translate_slice_mut::<u8>(
  749. memory_mapping,
  750. untranslated_event.as_ptr() as u64,
  751. untranslated_event.len() as u64,
  752. ),
  753. result
  754. );
  755. print!(" {}", hex::encode(&event));
  756. events.push(event.to_vec());
  757. }
  758. println!();
  759. vm.events.push(events.to_vec());
  760. *result = ProgramResult::Ok(0);
  761. } else {
  762. panic!();
  763. }
  764. }
  765. #[derive(Debug, Clone, PartialEq, Eq)]
  766. pub enum Ed25519SigCheckError {
  767. InvalidPublicKey,
  768. InvalidSignature,
  769. VerifyFailed,
  770. }
  771. impl From<u64> for Ed25519SigCheckError {
  772. fn from(v: u64) -> Ed25519SigCheckError {
  773. match v {
  774. 1 => Ed25519SigCheckError::InvalidPublicKey,
  775. 2 => Ed25519SigCheckError::InvalidSignature,
  776. 3 => Ed25519SigCheckError::VerifyFailed,
  777. _ => panic!("Unsupported Ed25519SigCheckError"),
  778. }
  779. }
  780. }
  781. impl From<Ed25519SigCheckError> for u64 {
  782. fn from(v: Ed25519SigCheckError) -> u64 {
  783. match v {
  784. Ed25519SigCheckError::InvalidPublicKey => 1,
  785. Ed25519SigCheckError::InvalidSignature => 2,
  786. Ed25519SigCheckError::VerifyFailed => 3,
  787. }
  788. }
  789. }
  790. const DEFAULT_HEAP_SIZE: usize = 32 * 1024;
  791. /// Rust representation of C's SolInstruction
  792. #[derive(Debug)]
  793. struct SolInstruction {
  794. program_id_addr: u64,
  795. accounts_addr: u64,
  796. accounts_len: usize,
  797. data_addr: u64,
  798. data_len: usize,
  799. }
  800. /// Rust representation of C's SolAccountMeta
  801. #[derive(Debug)]
  802. struct SolAccountMeta {
  803. pubkey_addr: u64,
  804. is_writable: bool,
  805. is_signer: bool,
  806. }
  807. /// Rust representation of C's SolSignerSeed
  808. #[derive(Debug)]
  809. struct SolSignerSeedC {
  810. addr: u64,
  811. len: u64,
  812. }
  813. /// Rust representation of C's SolSignerSeeds
  814. #[derive(Debug)]
  815. struct SolSignerSeedsC {
  816. addr: u64,
  817. len: u64,
  818. }
  819. #[derive(Debug)]
  820. pub struct Instruction {
  821. /// Pubkey of the instruction processor that executes this instruction
  822. pub program_id: Pubkey,
  823. /// Metadata for what accounts should be passed to the instruction processor
  824. pub accounts: Vec<AccountMeta>,
  825. /// Opaque data passed to the instruction processor
  826. pub data: Vec<u8>,
  827. }
  828. #[derive(Debug, PartialEq, Eq, Hash, Clone)]
  829. pub struct Pubkey([u8; 32]);
  830. impl Pubkey {
  831. fn is_system_instruction(&self) -> bool {
  832. self.0 == [0u8; 32]
  833. }
  834. }
  835. #[derive(Debug, PartialEq, Eq, Clone, Hash)]
  836. pub struct AccountMeta {
  837. /// An account's public key
  838. pub pubkey: Pubkey,
  839. /// True if the `pubkey` can be loaded as a read-write account.
  840. pub is_writable: bool,
  841. /// True if an Instruction requires a Transaction signature matching `pubkey`.
  842. pub is_signer: bool,
  843. }
  844. fn translate(
  845. memory_mapping: &MemoryMapping,
  846. access_type: AccessType,
  847. vm_addr: u64,
  848. len: u64,
  849. ) -> ProgramResult {
  850. memory_mapping.map(access_type, vm_addr, len, 0)
  851. }
  852. fn translate_type_inner<'a, T>(
  853. memory_mapping: &MemoryMapping,
  854. access_type: AccessType,
  855. vm_addr: u64,
  856. ) -> Result<&'a mut T, EbpfError> {
  857. unsafe {
  858. match translate(memory_mapping, access_type, vm_addr, size_of::<T>() as u64) {
  859. ProgramResult::Ok(value) => Ok(&mut *(value as *mut T)),
  860. ProgramResult::Err(e) => Err(e),
  861. }
  862. }
  863. }
  864. fn translate_type<'a, T>(memory_mapping: &MemoryMapping, vm_addr: u64) -> Result<&'a T, EbpfError> {
  865. translate_type_inner::<T>(memory_mapping, AccessType::Load, vm_addr).map(|value| &*value)
  866. }
  867. fn translate_slice<'a, T>(
  868. memory_mapping: &MemoryMapping,
  869. vm_addr: u64,
  870. len: u64,
  871. ) -> Result<&'a [T], EbpfError> {
  872. translate_slice_inner::<T>(memory_mapping, AccessType::Load, vm_addr, len).map(|value| &*value)
  873. }
  874. fn translate_slice_mut<'a, T>(
  875. memory_mapping: &MemoryMapping,
  876. vm_addr: u64,
  877. len: u64,
  878. ) -> Result<&'a mut [T], EbpfError> {
  879. translate_slice_inner::<T>(memory_mapping, AccessType::Store, vm_addr, len)
  880. }
  881. fn translate_slice_inner<'a, T>(
  882. memory_mapping: &MemoryMapping,
  883. access_type: AccessType,
  884. vm_addr: u64,
  885. len: u64,
  886. ) -> Result<&'a mut [T], EbpfError> {
  887. if len == 0 {
  888. Ok(&mut [])
  889. } else {
  890. match translate(
  891. memory_mapping,
  892. access_type,
  893. vm_addr,
  894. len.saturating_mul(size_of::<T>() as u64),
  895. ) {
  896. ProgramResult::Ok(value) => {
  897. Ok(unsafe { std::slice::from_raw_parts_mut(value as *mut T, len as usize) })
  898. }
  899. ProgramResult::Err(e) => Err(e),
  900. }
  901. }
  902. }
  903. fn translate_instruction(
  904. addr: u64,
  905. memory_mapping: &MemoryMapping,
  906. ) -> Result<Instruction, EbpfError> {
  907. let ix_c = translate_type::<SolInstruction>(memory_mapping, addr)?;
  908. let program_id = translate_type::<Pubkey>(memory_mapping, ix_c.program_id_addr)?;
  909. let meta_cs = translate_slice::<SolAccountMeta>(
  910. memory_mapping,
  911. ix_c.accounts_addr,
  912. ix_c.accounts_len as u64,
  913. )?;
  914. let data =
  915. translate_slice::<u8>(memory_mapping, ix_c.data_addr, ix_c.data_len as u64)?.to_vec();
  916. let accounts = meta_cs
  917. .iter()
  918. .map(|meta_c| {
  919. let pubkey = translate_type::<Pubkey>(memory_mapping, meta_c.pubkey_addr)?;
  920. Ok(AccountMeta {
  921. pubkey: pubkey.clone(),
  922. is_signer: meta_c.is_signer,
  923. is_writable: meta_c.is_writable,
  924. })
  925. })
  926. .collect::<Result<Vec<AccountMeta>, EbpfError>>()?;
  927. Ok(Instruction {
  928. program_id: program_id.clone(),
  929. accounts,
  930. data,
  931. })
  932. }
  933. fn create_program_address(program_id: &Account, seeds: &[&[u8]]) -> Pubkey {
  934. let mut hasher = Sha256::new();
  935. for seed in seeds {
  936. hasher.update(seed);
  937. }
  938. hasher.update(program_id);
  939. hasher.update(b"ProgramDerivedAddress");
  940. let hash = hasher.finalize();
  941. let new_address: [u8; 32] = hash.try_into().unwrap();
  942. // the real runtime does checks if this address exists on the ed25519 curve
  943. Pubkey(new_address)
  944. }
  945. fn sol_invoke_signed_c(
  946. context: &mut SyscallContext,
  947. instruction_addr: u64,
  948. _account_infos_addr: u64,
  949. _account_infos_len: u64,
  950. signers_seeds_addr: u64,
  951. signers_seeds_len: u64,
  952. memory_mapping: &mut MemoryMapping,
  953. result: &mut ProgramResult,
  954. ) {
  955. let instruction =
  956. translate_instruction(instruction_addr, memory_mapping).expect("instruction not valid");
  957. println!(
  958. "sol_invoke_signed_c input:{}",
  959. hex::encode(&instruction.data)
  960. );
  961. let seeds = question_mark!(
  962. translate_slice::<SolSignerSeedsC>(memory_mapping, signers_seeds_addr, signers_seeds_len),
  963. result
  964. );
  965. if let Ok(mut vm) = context.vm.try_borrow_mut() {
  966. let signers: Vec<Pubkey> = seeds
  967. .iter()
  968. .map(|seed| {
  969. let seeds: Vec<&[u8]> =
  970. translate_slice::<SolSignerSeedC>(memory_mapping, seed.addr, seed.len)
  971. .unwrap()
  972. .iter()
  973. .map(|seed| {
  974. translate_slice::<u8>(memory_mapping, seed.addr, seed.len).unwrap()
  975. })
  976. .collect();
  977. let pda = create_program_address(&vm.stack[0].program, &seeds);
  978. println!(
  979. "pda: {} seeds {}",
  980. pda.0.to_base58(),
  981. seeds
  982. .iter()
  983. .map(hex::encode)
  984. .collect::<Vec<String>>()
  985. .join(" ")
  986. );
  987. pda
  988. })
  989. .collect();
  990. vm.return_data = None;
  991. if let Some(handle) = vm.call_params_check.get(&instruction.program_id) {
  992. handle(&vm, &instruction, &signers);
  993. } else if instruction.program_id.is_system_instruction() {
  994. match bincode::deserialize::<u32>(&instruction.data).unwrap() {
  995. 0 => {
  996. let create_account: CreateAccount =
  997. bincode::deserialize(&instruction.data).unwrap();
  998. let address = &instruction.accounts[1].pubkey;
  999. assert!(instruction.accounts[1].is_signer);
  1000. println!("new address: {}", address.0.to_base58());
  1001. for s in &signers {
  1002. println!("signer: {}", s.0.to_base58());
  1003. }
  1004. if !signers.is_empty() {
  1005. assert!(signers.contains(address));
  1006. }
  1007. assert_eq!(create_account.instruction, 0);
  1008. println!(
  1009. "creating account {} with space {} owner {}",
  1010. address.0.to_base58(),
  1011. create_account.space,
  1012. create_account.program_id.to_base58()
  1013. );
  1014. assert_eq!(vm.account_data[&address.0].data.len(), 0);
  1015. if let Some(entry) = vm.account_data.get_mut(&address.0) {
  1016. entry.data = vec![0; create_account.space as usize];
  1017. entry.owner = Some(create_account.program_id);
  1018. }
  1019. let mut refs = context.refs.try_borrow_mut().unwrap();
  1020. for r in refs.iter_mut() {
  1021. if r.account == address.0 {
  1022. r.length = create_account.space as usize;
  1023. }
  1024. }
  1025. }
  1026. 1 => {
  1027. let assign: Assign = bincode::deserialize(&instruction.data).unwrap();
  1028. let address = &instruction.accounts[0].pubkey;
  1029. println!("assign address: {}", address.0.to_base58());
  1030. for s in &signers {
  1031. println!("signer: {}", s.0.to_base58());
  1032. }
  1033. assert!(signers.contains(address));
  1034. assert_eq!(assign.instruction, 1);
  1035. println!(
  1036. "assign account {} owner {}",
  1037. address.0.to_base58(),
  1038. assign.owner.to_base58(),
  1039. );
  1040. if let Some(entry) = vm.account_data.get_mut(&address.0) {
  1041. entry.owner = Some(assign.owner);
  1042. }
  1043. }
  1044. 3 => {
  1045. let create_account: CreateAccountWithSeed =
  1046. bincode::deserialize(&instruction.data).unwrap();
  1047. assert_eq!(create_account.instruction, 3);
  1048. let mut hasher = Sha256::new();
  1049. hasher.update(create_account.base);
  1050. hasher.update(create_account.seed);
  1051. hasher.update(create_account.program_id);
  1052. let hash = hasher.finalize();
  1053. let new_address: [u8; 32] = hash.try_into().unwrap();
  1054. println!(
  1055. "creating account {} with space {} owner {}",
  1056. hex::encode(new_address),
  1057. create_account.space,
  1058. hex::encode(create_account.program_id)
  1059. );
  1060. vm.account_data.insert(
  1061. new_address,
  1062. AccountState {
  1063. data: vec![0; create_account.space as usize],
  1064. owner: Some(create_account.program_id),
  1065. lamports: 0,
  1066. },
  1067. );
  1068. vm.programs.push(Contract {
  1069. program: create_account.program_id,
  1070. idl: None,
  1071. data: new_address,
  1072. });
  1073. }
  1074. 8 => {
  1075. let allocate: Allocate = bincode::deserialize(&instruction.data).unwrap();
  1076. let address = &instruction.accounts[0].pubkey;
  1077. println!("new address: {}", address.0.to_base58());
  1078. for s in &signers {
  1079. println!("signer: {}", s.0.to_base58());
  1080. }
  1081. assert!(signers.contains(address));
  1082. assert_eq!(allocate.instruction, 8);
  1083. println!(
  1084. "allocate account {} with space {}",
  1085. address.0.to_base58(),
  1086. allocate.space,
  1087. );
  1088. assert_eq!(vm.account_data[&address.0].data.len(), 0);
  1089. if let Some(entry) = vm.account_data.get_mut(&address.0) {
  1090. entry.data = vec![0; allocate.space as usize];
  1091. }
  1092. let mut refs = context.refs.try_borrow_mut().unwrap();
  1093. for r in refs.iter_mut() {
  1094. if r.account == address.0 {
  1095. r.length = allocate.space as usize;
  1096. }
  1097. }
  1098. }
  1099. instruction => panic!("instruction {instruction} not supported"),
  1100. }
  1101. } else {
  1102. let data_id: Account = instruction.accounts[0].pubkey.0;
  1103. println!(
  1104. "calling {} program_id {}",
  1105. data_id.to_base58(),
  1106. instruction.program_id.0.to_base58()
  1107. );
  1108. assert_eq!(data_id, instruction.accounts[0].pubkey.0);
  1109. let mut p = vm
  1110. .programs
  1111. .iter()
  1112. .find(|p| p.program == instruction.program_id.0)
  1113. .unwrap()
  1114. .clone();
  1115. p.data = data_id;
  1116. vm.stack.insert(0, p);
  1117. let res = vm.execute(&instruction.accounts, &instruction.data);
  1118. assert!(matches!(res, StableResult::Ok(0)), "external call failed");
  1119. let refs = context.refs.try_borrow_mut().unwrap();
  1120. let input = translate_slice_mut::<u8>(
  1121. memory_mapping,
  1122. ebpf::MM_INPUT_START,
  1123. context.input_len as u64,
  1124. )
  1125. .unwrap();
  1126. update_parameters(input, refs, &vm.account_data);
  1127. vm.stack.remove(0);
  1128. }
  1129. }
  1130. *result = ProgramResult::Ok(0)
  1131. }
  1132. impl VirtualMachine {
  1133. fn execute(&mut self, metas: &[AccountMeta], calldata: &[u8]) -> ProgramResult {
  1134. println!("running bpf with calldata:{}", hex::encode(calldata));
  1135. let (mut parameter_bytes, mut refs) = serialize_parameters(calldata, metas, self);
  1136. let mut heap = vec![0_u8; DEFAULT_HEAP_SIZE];
  1137. let program = &self.stack[0];
  1138. let mut loader: BuiltInProgram<SyscallContext> = BuiltInProgram::new_loader(Config {
  1139. static_syscalls: false,
  1140. enable_symbol_and_section_labels: true,
  1141. dynamic_stack_frames: false,
  1142. ..Config::default()
  1143. });
  1144. loader
  1145. .register_function_by_name("sol_panic_", sol_panic_)
  1146. .unwrap();
  1147. loader
  1148. .register_function_by_name("sol_log_", sol_log)
  1149. .unwrap();
  1150. loader
  1151. .register_function_by_name("sol_log_pubkey", sol_log_pubkey)
  1152. .unwrap();
  1153. loader
  1154. .register_function_by_name("sol_log_64_", sol_log_u64)
  1155. .unwrap();
  1156. loader
  1157. .register_function_by_name("sol_sha256", sol_sha256)
  1158. .unwrap();
  1159. loader
  1160. .register_function_by_name("sol_keccak256", sol_keccak256)
  1161. .unwrap();
  1162. loader
  1163. .register_function_by_name("sol_create_program_address", sol_create_program_address)
  1164. .unwrap();
  1165. loader
  1166. .register_function_by_name("sol_try_find_program_address", sol_try_find_program_address)
  1167. .unwrap();
  1168. loader
  1169. .register_function_by_name("sol_invoke_signed_c", sol_invoke_signed_c)
  1170. .unwrap();
  1171. loader
  1172. .register_function_by_name("sol_set_return_data", sol_set_return_data)
  1173. .unwrap();
  1174. loader
  1175. .register_function_by_name("sol_get_return_data", sol_get_return_data)
  1176. .unwrap();
  1177. loader
  1178. .register_function_by_name("sol_log_data", sol_log_data)
  1179. .unwrap();
  1180. // program.program
  1181. println!("program: {}", program.program.to_base58());
  1182. let executable = Executable::<SyscallContext>::from_elf(
  1183. &self.account_data[&program.program].data,
  1184. Arc::new(loader),
  1185. )
  1186. .expect("should work");
  1187. let verified_executable =
  1188. VerifiedExecutable::<RequisiteVerifier, SyscallContext>::from_executable(executable)
  1189. .unwrap();
  1190. let mut context = SyscallContext {
  1191. vm: Rc::new(RefCell::new(self)),
  1192. input_len: parameter_bytes.len(),
  1193. refs: Rc::new(RefCell::new(&mut refs)),
  1194. heap: heap.as_ptr(),
  1195. remaining: 1000000,
  1196. };
  1197. let parameter_region =
  1198. MemoryRegion::new_writable(&mut parameter_bytes, ebpf::MM_INPUT_START);
  1199. let mut vm = EbpfVm::new(
  1200. &verified_executable,
  1201. &mut context,
  1202. &mut heap,
  1203. vec![parameter_region],
  1204. )
  1205. .unwrap();
  1206. let (_, res) = vm.execute_program(true);
  1207. deserialize_parameters(&parameter_bytes, &refs, &mut self.account_data);
  1208. self.validate_account_data_heap();
  1209. if let Some((_, return_data)) = &self.return_data {
  1210. println!("return: {}", hex::encode(return_data));
  1211. }
  1212. res
  1213. }
  1214. fn constructor(&mut self, args: &[BorshToken]) {
  1215. let default_metas = self.default_metas();
  1216. self.constructor_expected(0, &default_metas, args)
  1217. }
  1218. fn constructor_expected(&mut self, expected: u64, metas: &[AccountMeta], args: &[BorshToken]) {
  1219. self.return_data = None;
  1220. let program = &self.stack[0];
  1221. println!("constructor for {}", hex::encode(program.data));
  1222. let mut calldata = discriminator("global", "new");
  1223. if program
  1224. .idl
  1225. .as_ref()
  1226. .unwrap()
  1227. .instructions
  1228. .iter()
  1229. .any(|instr| instr.name == "new")
  1230. {
  1231. let mut encoded_data = encode_arguments(args);
  1232. calldata.append(&mut encoded_data);
  1233. };
  1234. let res = self.execute(metas, &calldata);
  1235. if let ProgramResult::Ok(res) = res {
  1236. assert_eq!(res, expected);
  1237. } else {
  1238. panic!("{res:?}");
  1239. }
  1240. if let Some((_, return_data)) = &self.return_data {
  1241. assert_eq!(return_data.len(), 0);
  1242. }
  1243. }
  1244. fn function(&mut self, name: &str, args: &[BorshToken]) -> Option<BorshToken> {
  1245. let default_metas = self.default_metas();
  1246. self.function_metas(name, &default_metas, args)
  1247. }
  1248. fn function_metas(
  1249. &mut self,
  1250. name: &str,
  1251. metas: &[AccountMeta],
  1252. args: &[BorshToken],
  1253. ) -> Option<BorshToken> {
  1254. self.return_data = None;
  1255. let program = &self.stack[0];
  1256. println!("function {} for {}", name, hex::encode(program.data));
  1257. let mut calldata = discriminator("global", name);
  1258. let instruction = if let Some(instr) = program
  1259. .idl
  1260. .as_ref()
  1261. .unwrap()
  1262. .instructions
  1263. .iter()
  1264. .find(|item| item.name == name)
  1265. {
  1266. instr.clone()
  1267. } else {
  1268. panic!("Function '{name}' not found");
  1269. };
  1270. let mut encoded_args = encode_arguments(args);
  1271. calldata.append(&mut encoded_args);
  1272. println!("input: {}", hex::encode(&calldata));
  1273. let res = self.execute(metas, &calldata);
  1274. match res {
  1275. ProgramResult::Ok(0) => (),
  1276. ProgramResult::Ok(error_code) => panic!("unexpected return {error_code:#x}"),
  1277. ProgramResult::Err(e) => panic!("error: {e:?}"),
  1278. };
  1279. let return_data = if let Some((_, return_data)) = &self.return_data {
  1280. return_data.as_slice()
  1281. } else {
  1282. &[]
  1283. };
  1284. if let Some(ret) = &instruction.returns {
  1285. let mut offset: usize = 0;
  1286. let decoded = decode_at_offset(
  1287. return_data,
  1288. &mut offset,
  1289. ret,
  1290. &self.stack[0].idl.as_ref().unwrap().types,
  1291. );
  1292. assert_eq!(offset, return_data.len());
  1293. Some(decoded)
  1294. } else {
  1295. assert_eq!(return_data.len(), 0);
  1296. None
  1297. }
  1298. }
  1299. fn function_must_fail(&mut self, name: &str, args: &[BorshToken]) -> ProgramResult {
  1300. let program = &self.stack[0];
  1301. println!("function for {}", hex::encode(program.data));
  1302. let mut calldata = Vec::new();
  1303. if !self.stack[0]
  1304. .idl
  1305. .as_ref()
  1306. .unwrap()
  1307. .instructions
  1308. .iter()
  1309. .any(|item| item.name == name)
  1310. {
  1311. panic!("Function '{name}' not found");
  1312. }
  1313. let selector = discriminator("global", name);
  1314. calldata.extend_from_slice(&selector);
  1315. let mut encoded = encode_arguments(args);
  1316. calldata.append(&mut encoded);
  1317. let default_metas = self.default_metas();
  1318. println!("input: {}", hex::encode(&calldata));
  1319. self.execute(&default_metas, &calldata)
  1320. }
  1321. fn default_metas(&self) -> Vec<AccountMeta> {
  1322. // Just include everything
  1323. let mut accounts = vec![AccountMeta {
  1324. pubkey: Pubkey(self.stack[0].data),
  1325. is_writable: true,
  1326. is_signer: false,
  1327. }];
  1328. for acc in self.account_data.keys() {
  1329. if *acc != accounts[0].pubkey.0 {
  1330. accounts.push(AccountMeta {
  1331. pubkey: Pubkey(*acc),
  1332. is_signer: false,
  1333. is_writable: true,
  1334. });
  1335. }
  1336. }
  1337. accounts
  1338. }
  1339. fn data(&self) -> &Vec<u8> {
  1340. let program = &self.stack[0];
  1341. &self.account_data[&program.data].data
  1342. }
  1343. fn set_program(&mut self, no: usize) {
  1344. let cur = self.programs[no].clone();
  1345. self.stack = vec![cur];
  1346. }
  1347. fn create_pda(&mut self, program_id: &Account) -> (Account, Vec<u8>) {
  1348. let mut rng = rand::thread_rng();
  1349. let mut seed = [0u8; 7];
  1350. rng.fill(&mut seed[..]);
  1351. let pk = create_program_address(program_id, &[&seed]);
  1352. let account = pk.0;
  1353. println!(
  1354. "new empty account {} with seed {}",
  1355. account.to_base58(),
  1356. hex::encode(seed)
  1357. );
  1358. self.create_empty_account(&account, program_id);
  1359. (account, seed.to_vec())
  1360. }
  1361. fn create_empty_account(&mut self, account: &Account, program_id: &Account) {
  1362. self.account_data.insert(
  1363. *account,
  1364. AccountState {
  1365. data: vec![],
  1366. owner: Some([0u8; 32]),
  1367. lamports: 0,
  1368. },
  1369. );
  1370. self.programs.push(Contract {
  1371. program: *program_id,
  1372. idl: None,
  1373. data: *account,
  1374. });
  1375. }
  1376. fn validate_account_data_heap(&self) -> usize {
  1377. if let Some(acc) = self.account_data.get(&self.stack[0].data) {
  1378. let data = &acc.data;
  1379. let mut count = 0;
  1380. if data.len() < 4 || LittleEndian::read_u32(&data[0..]) == 0 {
  1381. return count;
  1382. }
  1383. let mut prev_offset = 0;
  1384. let return_len = LittleEndian::read_u32(&data[4..]) as usize;
  1385. let return_offset = LittleEndian::read_u32(&data[8..]) as usize;
  1386. let mut offset = LittleEndian::read_u32(&data[12..]) as usize;
  1387. // The return_offset/len fields are no longer used (we should remove them at some point)
  1388. assert_eq!(return_len, 0);
  1389. assert_eq!(return_offset, 0);
  1390. println!(
  1391. "static: length:{:x} {}",
  1392. offset - 16,
  1393. hex::encode(&data[16..offset])
  1394. );
  1395. if offset >= data.len() {
  1396. return count;
  1397. }
  1398. loop {
  1399. let next = LittleEndian::read_u32(&data[offset..]) as usize;
  1400. let prev = LittleEndian::read_u32(&data[offset + 4..]) as usize;
  1401. let length = LittleEndian::read_u32(&data[offset + 8..]) as usize;
  1402. let allocate = LittleEndian::read_u32(&data[offset + 12..]) as usize;
  1403. if allocate == 1 {
  1404. count += 1;
  1405. }
  1406. println!(
  1407. "offset:{:x} prev:{:x} next:{:x} length:{} allocated:{} {}",
  1408. offset + 16,
  1409. prev + 16,
  1410. next + 16,
  1411. length,
  1412. allocate,
  1413. hex::encode(&data[offset + 16..offset + 16 + length])
  1414. );
  1415. assert_eq!(prev, prev_offset);
  1416. prev_offset = offset;
  1417. if next == 0 {
  1418. assert_eq!(length, 0);
  1419. assert_eq!(allocate, 0);
  1420. break;
  1421. }
  1422. let space = next - offset - 16;
  1423. assert!(length <= space);
  1424. offset = next;
  1425. }
  1426. count
  1427. } else {
  1428. 0
  1429. }
  1430. }
  1431. }