solana.rs 50 KB

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