solana.rs 50 KB

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