solana.rs 50 KB

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