darkfi/runtime/import/db/
db_del.rs1use darkfi_sdk::wasm;
20use darkfi_serial::Decodable;
21use tracing::error;
22use wasmer::{FunctionEnvMut, WasmPtr};
23
24use crate::runtime::{
25 import::{acl::acl_allow, util::wasm_mem_read},
26 vm_runtime::{ContractSection, Env},
27};
28
29pub(crate) fn db_del(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, ptr_len: u32) -> i64 {
37 db_del_internal(ctx, ptr, ptr_len, false)
38}
39
40pub(crate) fn db_del_local(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, ptr_len: u32) -> i64 {
48 db_del_internal(ctx, ptr, ptr_len, true)
49}
50
51fn db_del_internal(
57 mut ctx: FunctionEnvMut<Env>,
58 ptr: WasmPtr<u8>,
59 ptr_len: u32,
60 local: bool,
61) -> i64 {
62 let lt = if local { "db_del_local" } else { "db_del" };
63 let (env, mut store) = ctx.data_and_store_mut();
64 let cid = env.contract_id;
65
66 if let Err(e) = acl_allow(env, &[ContractSection::Deploy, ContractSection::Update]) {
68 error!(
69 target: "runtime::db::{lt}",
70 "[WASM] [{cid}] {lt}(): Called in unauthorized section: {e}",
71 );
72 return darkfi_sdk::error::CALLER_ACCESS_DENIED
73 }
74
75 env.subtract_gas(&mut store, 1);
78
79 let mut buf_reader = match wasm_mem_read(env, &store, ptr, ptr_len) {
81 Ok(v) => v,
82 Err(e) => {
83 error!(
84 target: "runtime::db::{lt}",
85 "[WASM] [{cid}] {lt}(): Failed to read WASM memory: {e}",
86 );
87 return darkfi_sdk::error::DB_DEL_FAILED
88 }
89 };
90
91 let db_handle_index: u32 = match Decodable::decode(&mut buf_reader) {
93 Ok(v) => v,
94 Err(e) => {
95 error!(
96 target: "runtime::db::{lt}",
97 "[WASM] [{cid}] {lt}(): Failed to decode DbHandle: {e}",
98 );
99 return darkfi_sdk::error::DB_DEL_FAILED
100 }
101 };
102
103 let db_handle_index = db_handle_index as usize;
104
105 if env.contract_section == ContractSection::Deploy && db_handle_index == 0 {
108 error!(
109 target: "runtime::db::{lt}",
110 "[WASM] [{cid}] {lt}(): Tried to write to zkas db",
111 );
112 return darkfi_sdk::error::CALLER_ACCESS_DENIED
113 }
114
115 let key: Vec<u8> = match Decodable::decode(&mut buf_reader) {
117 Ok(v) => v,
118 Err(e) => {
119 error!(
120 target: "runtime::db::{lt}",
121 "[WASM] [{cid}] {lt}(): Failed to decode key Vec: {e}",
122 );
123 return darkfi_sdk::error::DB_DEL_FAILED
124 }
125 };
126
127 if buf_reader.position() != ptr_len as u64 {
129 error!(
130 target: "runtime::db::{lt}",
131 "[WASM] [{cid}] {lt}(): Trailing bytes in argument stream",
132 );
133 return darkfi_sdk::error::DB_DEL_FAILED
134 }
135
136 let db_handles = if local { env.local_db_handles.borrow() } else { env.db_handles.borrow() };
138
139 if db_handles.len() <= db_handle_index {
141 error!(
142 target: "runtime::db::{lt}",
143 "[WASM] [{cid}] {lt}(): Requested DbHandle out of bounds",
144 );
145 return darkfi_sdk::error::DB_DEL_FAILED
146 }
147
148 let db_handle = &db_handles[db_handle_index];
150
151 if db_handle.contract_id != cid {
154 error!(
155 target: "runtime::db::{lt}",
156 "[WASM] [{cid}] {lt}(): Unauthorized write to DbHandle",
157 );
158 return darkfi_sdk::error::CALLER_ACCESS_DENIED
159 }
160
161 if local {
163 let mut db = env.tx_local.lock();
165 let db_cid = db.get_mut(&cid).unwrap();
166 let Some(tree) = db_cid.get_mut(&db_handle.tree) else {
167 error!(
168 target: "runtime::db::{lt}",
169 "[WASM] [{cid}] {lt}(): Could not remove key from tx-local tree",
170 );
171 return darkfi_sdk::error::DB_DEL_FAILED
172 };
173
174 tree.remove(&key);
175 } else if env
176 .blockchain
177 .lock()
178 .unwrap()
179 .overlay
180 .lock()
181 .unwrap()
182 .remove(&db_handle.tree, &key)
183 .is_err()
184 {
185 error!(
186 target: "runtime::db::{lt}",
187 "[WASM] [{cid}] {lt}(): Could not remove key from on-chain tree",
188 );
189 return darkfi_sdk::error::DB_DEL_FAILED
190 }
191
192 wasm::entrypoint::SUCCESS
193}