From 99bc39839ad1bcf27970d5b6d8739b4df73ffc0a Mon Sep 17 00:00:00 2001 From: Filippo Costa Date: Fri, 5 Nov 2021 13:25:46 +0100 Subject: [PATCH] Create account with god template address --- crates/runtime-ffi/src/api.rs | 23 +++++++++++++---------- crates/runtime/src/runtime/runtime.rs | 4 ++-- crates/state/src/account_storage.rs | 23 +++++++++++++++-------- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/crates/runtime-ffi/src/api.rs b/crates/runtime-ffi/src/api.rs index 97d4984c0..7a9587d78 100644 --- a/crates/runtime-ffi/src/api.rs +++ b/crates/runtime-ffi/src/api.rs @@ -474,21 +474,18 @@ pub unsafe extern "C" fn svm_call( #[must_use] #[no_mangle] -pub unsafe extern "C" fn svm_rewind(runtime: *mut c_void, layer_id: u64) -> svm_result_t { +pub unsafe extern "C" fn svm_rewind(runtime_ptr: *mut c_void, layer_id: u64) -> svm_result_t { catch_unwind_or_fail(|| { - RUNTIME_TRACKER - .get(runtime) - .unwrap() - .rewind(Layer(layer_id))?; + get_runtime(runtime_ptr).rewind(Layer(layer_id))?; svm_result_t::OK }) } #[must_use] #[no_mangle] -pub unsafe extern "C" fn svm_commit(runtime: *mut c_void) -> svm_result_t { +pub unsafe extern "C" fn svm_commit(runtime_ptr: *mut c_void) -> svm_result_t { catch_unwind_or_fail(|| { - RUNTIME_TRACKER.get(runtime).unwrap().commit()?; + get_runtime(runtime_ptr).commit()?; svm_result_t::OK }) } @@ -504,7 +501,7 @@ pub unsafe extern "C" fn svm_get_account( template_addr: *mut u8, ) -> svm_result_t { catch_unwind_or_fail(|| { - let runtime = RUNTIME_TRACKER.get(runtime_ptr).unwrap(); + let runtime = get_runtime(runtime_ptr); let account_addr = Address::new(std::slice::from_raw_parts(account_addr, Address::N)); let template_addr = std::slice::from_raw_parts_mut(template_addr, TemplateAddr::N); let account_data = runtime.get_account(&account_addr).unwrap(); @@ -532,7 +529,7 @@ where C: Codec + UnwindSafe + std::fmt::Debug, { catch_unwind_or_fail(|| { - let runtime = RUNTIME_TRACKER.get(runtime_ptr).unwrap(); + let runtime = get_runtime(runtime_ptr); let message = slice::from_raw_parts(message, message_size as usize); let envelope = slice::from_raw_parts(envelope, Envelope::fixed_size().unwrap()); let context = slice::from_raw_parts(context, Context::fixed_size().unwrap()); @@ -559,7 +556,7 @@ where F: FnOnce(&mut Runtime, &[u8]) -> Result<(), ValidateError> + UnwindSafe, { catch_unwind_or_fail(|| { - let runtime = RUNTIME_TRACKER.get(runtime_ptr).unwrap(); + let runtime = get_runtime(runtime_ptr); let message = slice::from_raw_parts(message, message_size as usize); match validate_f(runtime, message) { @@ -575,6 +572,12 @@ where }) } +unsafe fn get_runtime(runtime_ptr: *mut c_void) -> &'static mut Runtime { + RUNTIME_TRACKER + .get(runtime_ptr) + .expect("The given runtime pointer doesn't point to a valid runtime.") +} + fn catch_unwind_or_fail(f: F) -> svm_result_t where F: FnOnce() -> svm_result_t + std::panic::UnwindSafe, diff --git a/crates/runtime/src/runtime/runtime.rs b/crates/runtime/src/runtime/runtime.rs index cf0a88dd8..470d34ea6 100644 --- a/crates/runtime/src/runtime/runtime.rs +++ b/crates/runtime/src/runtime/runtime.rs @@ -437,7 +437,7 @@ impl Runtime { Ok(()) } - /// Creates a new account with the given information. + /// Creates a new account at genesis with the given information. pub fn create_account( &mut self, account_addr: &Address, @@ -449,7 +449,7 @@ impl Runtime { self.gs.clone(), account_addr, name, - TemplateAddr::zeros(), + TemplateAddr::god_template(), balance, counter, ) diff --git a/crates/state/src/account_storage.rs b/crates/state/src/account_storage.rs index 27ab0b874..4afd66ca4 100644 --- a/crates/state/src/account_storage.rs +++ b/crates/state/src/account_storage.rs @@ -32,10 +32,7 @@ impl AccountStorage { balance: u64, counter: u128, ) -> StorageResult { - let template_storage = TemplateStorage::load(gs.clone(), &template_addr)?; - let sections = template_storage.sections()?; - let data_section = sections.get(SectionKind::Data).as_data(); - let layout = data_section.layouts()[0].as_fixed().clone(); + let layout = template_layout(gs.clone(), &template_addr)?; gs.encode_and_write( &AccountData { @@ -58,15 +55,13 @@ impl AccountStorage { /// Creates a new [`AccountStorage`]. pub fn load(gs: GlobalState, address: &Address) -> StorageResult { let account_data = AccountData::read(&gs, address)?; - let template_storage = TemplateStorage::load(gs.clone(), &account_data.template_addr)?; - let sections = template_storage.sections()?; - let data_section = sections.get(SectionKind::Data).as_data(); + let layout = template_layout(gs.clone(), &account_data.template_addr)?; Ok(Self { gs, address: address.clone(), template_addr: account_data.template_addr, - layout: data_section.layouts()[0].as_fixed().clone(), + layout, }) } @@ -271,6 +266,18 @@ fn key_account_var_segment(account_addr: &Address, segment: u32) -> String { ) } +fn template_layout(gs: GlobalState, template_addr: &TemplateAddr) -> StorageResult { + if *template_addr == TemplateAddr::god_template() { + Ok(FixedLayout::default()) + } else { + let template_storage = TemplateStorage::load(gs, &template_addr)?; + let sections = template_storage.sections()?; + let data_section = sections.get(SectionKind::Data).as_data(); + let layout = data_section.layouts()[0].as_fixed().clone(); + Ok(layout) + } +} + #[derive(Debug)] struct Segment { key: String,