solana.rs 50 KB

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