solana.rs 49 KB

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