Просмотр исходного кода

runtime/import: General function cleanup and use darkfi_sdk error codes

The general idea is that functional stuff inside wasm ends at 32-bits
and anything above is considered an error as per darkfi_sdk::error.
parazyd 2 лет назад
Родитель
Сommit
3240221614
3 измененных файлов с 762 добавлено и 449 удалено
  1. 381 187
      src/runtime/import/db.rs
  2. 272 197
      src/runtime/import/merkle.rs
  3. 109 65
      src/runtime/import/util.rs

Разница между файлами не показана из-за своего большого размера
+ 381 - 187
src/runtime/import/db.rs


+ 272 - 197
src/runtime/import/merkle.rs

@@ -23,213 +23,288 @@ use darkfi_serial::{serialize, Decodable, Encodable, WriteExt};
 use log::{debug, error};
 use wasmer::{FunctionEnvMut, WasmPtr};
 
+use super::acl::acl_allow;
 use crate::runtime::vm_runtime::{ContractSection, Env};
 
 /// Adds data to merkle tree. The tree, database connection, and new data to add is
 /// read from `ptr` at offset specified by `len`.
-/// Returns `0` on success; otherwise, returns a negative error-code corresponding to a
+/// Returns `0` on success; otherwise, returns an error-code corresponding to a
 /// [`ContractError`] (defined in the SDK).
 /// See also the method `merkle_add` in `sdk/src/merkle.rs`.
-pub(crate) fn merkle_add(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i32 {
+pub(crate) fn merkle_add(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i64 {
     let env = ctx.data();
-    match env.contract_section {
-        ContractSection::Update => {
-            let memory_view = env.memory_view(&ctx);
-
-            let Ok(mem_slice) = ptr.slice(&memory_view, len) else {
-                error!(target: "runtime::merkle", "Failed to make slice from ptr");
-                return -2
-            };
-
-            let mut buf = vec![0_u8; len as usize];
-            if let Err(e) = mem_slice.read_slice(&mut buf) {
-                error!(target: "runtime::merkle", "Failed to read from memory slice: {}", e);
-                return -2
-            };
-
-            // The buffer should deserialize into:
-            // - db_info
-            // - db_roots
-            // - root_key (as Vec<u8>) (key being the name of the sled key in info_db where the latest root is)
-            // - tree_key (as Vec<u8>) (key being the name of the sled key in info_db where the Merkle tree is)
-            // - coins (as Vec<MerkleNode>) (the coins being added into the Merkle tree)
-            let mut buf_reader = Cursor::new(buf);
-            // FIXME: There's a type DbHandle=u32, but this should maybe be renamed
-            let db_info_index: u32 = match Decodable::decode(&mut buf_reader) {
-                Ok(v) => v,
-                Err(e) => {
-                    error!(target: "runtime::merkle", "Failed to decode db_info DbHandle: {}", e);
-                    return -2
-                }
-            };
-            let db_info_index = db_info_index as usize;
-
-            let db_roots_index: u32 = match Decodable::decode(&mut buf_reader) {
-                Ok(v) => v,
-                Err(e) => {
-                    error!(target: "runtime::merkle", "Failed to decode db_roots DbHandle: {}", e);
-                    return -2
-                }
-            };
-            let db_roots_index = db_roots_index as usize;
-
-            let db_handles = env.db_handles.borrow();
-            let n_dbs = db_handles.len();
-
-            if n_dbs <= db_info_index || n_dbs <= db_roots_index {
-                error!(target: "runtime::merkle", "Requested DbHandle that is out of bounds");
-                return -2
-            }
-            let db_info = &db_handles[db_info_index];
-            let db_roots = &db_handles[db_roots_index];
-
-            if db_info.contract_id != env.contract_id || db_roots.contract_id != env.contract_id {
-                error!(target: "runtime::merkle", "Unauthorized to write to DbHandle");
-                return -2
-            }
-
-            // This `key` represents the sled key in info where the latest root is
-            let root_key: Vec<u8> = match Decodable::decode(&mut buf_reader) {
-                Ok(v) => v,
-                Err(e) => {
-                    error!(target: "runtime::merkle", "Failed to decode key vec: {}", e);
-                    return -2
-                }
-            };
-
-            // This `key` represents the sled database tree name
-            let tree_key: Vec<u8> = match Decodable::decode(&mut buf_reader) {
-                Ok(v) => v,
-                Err(e) => {
-                    error!(target: "runtime::merkle", "Failed to decode key vec: {}", e);
-                    return -2
-                }
-            };
-
-            // This `coin` represents the leaf we're adding to the Merkle tree
-            let coins: Vec<MerkleNode> = match Decodable::decode(&mut buf_reader) {
-                Ok(v) => v,
-                Err(e) => {
-                    error!(target: "runtime::merkle", "Failed to decode MerkleNode: {}", e);
-                    return -2
-                }
-            };
-
-            if buf_reader.position() != (len as u64) {
-                error!(target: "runtime::merkle", "Mismatch between given length, and cursor length");
-                return -2
-            }
-
-            // Read the current tree
-            let ret = match env
-                .blockchain
-                .lock()
-                .unwrap()
-                .overlay
-                .lock()
-                .unwrap()
-                .get(&db_info.tree, &tree_key)
-            {
-                Ok(v) => v,
-                Err(e) => {
-                    error!(target: "runtime::merkle", "Internal error getting from tree: {}", e);
-                    return -2
-                }
-            };
-
-            let Some(return_data) = ret else {
-                error!(target: "runtime::merkle", "Return data is empty");
-                return -2
-            };
-
-            debug!(
-                target: "runtime::merkle",
-                "Serialized tree: {} bytes",
-                return_data.len()
+    let cid = &env.contract_id;
+
+    // Enforce function ACL
+    if let Err(e) = acl_allow(env, &[ContractSection::Update]) {
+        error!(
+            target: "runtime::merkle::merkle_add",
+            "[WASM] [{}] merkle_add(): Called in unauthorized section: {}", cid, e,
+        );
+        return darkfi_sdk::error::CALLER_ACCESS_DENIED
+    }
+
+    let memory_view = env.memory_view(&ctx);
+    let Ok(mem_slice) = ptr.slice(&memory_view, len) else {
+        error!(
+            target: "runtime::merkle::merkle_add",
+            "[WASM] [{}] merkle_add(): Failed to make slice from ptr", cid,
+        );
+        return darkfi_sdk::error::INTERNAL_ERROR
+    };
+
+    let mut buf = vec![0_u8; len as usize];
+    if let Err(e) = mem_slice.read_slice(&mut buf) {
+        error!(
+            target: "runtime::merkle::merkle_add",
+            "[WASM] [{}] merkle_add(): Failed to read from memory slice: {}", cid, e,
+        );
+        return darkfi_sdk::error::INTERNAL_ERROR
+    };
+
+    // The buffer should deserialize into:
+    // - db_info
+    // - db_roots
+    // - root_key (as Vec<u8>) (key being the name of the sled key in info_db where the latest root is)
+    // - tree_key (as Vec<u8>) (key being the name of the sled key in info_db where the Merkle tree is)
+    // - coins (as Vec<MerkleNode>) (the coins being added into the Merkle tree)
+    let mut buf_reader = Cursor::new(buf);
+    // FIXME: There's a type DbHandle=u32, but this should maybe be renamed
+    let db_info_index: u32 = match Decodable::decode(&mut buf_reader) {
+        Ok(v) => v,
+        Err(e) => {
+            error!(
+                target: "runtime::merkle::merkle_add",
+                "[WASM] [{}] merkle_add(): Failed to decode db_info DbHandle: {}", cid, e,
             );
-            debug!(
-                target: "runtime::merkle",
-                "                 {:02x?}",
-                return_data
+            return darkfi_sdk::error::INTERNAL_ERROR
+        }
+    };
+    let db_info_index = db_info_index as usize;
+
+    let db_roots_index: u32 = match Decodable::decode(&mut buf_reader) {
+        Ok(v) => v,
+        Err(e) => {
+            error!(
+                target: "runtime::merkle::merkle_add",
+                "[WASM] [{}] merkle_add(): Failed to decode db_roots DbHandle: {}", cid, e,
             );
+            return darkfi_sdk::error::INTERNAL_ERROR
+        }
+    };
+    let db_roots_index = db_roots_index as usize;
+
+    let db_handles = env.db_handles.borrow();
+    let n_dbs = db_handles.len();
+
+    if n_dbs <= db_info_index || n_dbs <= db_roots_index {
+        error!(
+            target: "runtime::merkle::merkle_add",
+            "[WASM] [{}] merkle_add(): Requested DbHandle that is out of bounds", cid,
+        );
+        return darkfi_sdk::error::INTERNAL_ERROR
+    }
+    let db_info = &db_handles[db_info_index];
+    let db_roots = &db_handles[db_roots_index];
 
-            let mut decoder = Cursor::new(&return_data);
-
-            let set_size: u32 = match Decodable::decode(&mut decoder) {
-                Ok(v) => v,
-                Err(e) => {
-                    error!(target: "runtime::merkle", "Unable to read set size: {}", e);
-                    return -2
-                }
-            };
-
-            let mut tree: MerkleTree = match Decodable::decode(&mut decoder) {
-                Ok(v) => v,
-                Err(e) => {
-                    error!(target: "runtime::merkle", "Unable to deserialize tree: {}", e);
-                    return -2
-                }
-            };
-
-            // Here we add the new coins into the tree.
-            let mut new_roots = vec![];
-
-            for coin in coins {
-                tree.append(coin);
-                let Some(root) = tree.root(0) else {
-                    error!(target: "runtime::merkle", "Unable to read the root of tree");
-                    return -2
-                };
-                new_roots.push(root);
-            }
-
-            // And we serialize the tree back to bytes
-            let mut tree_data = Vec::new();
-            if tree_data.write_u32(set_size + new_roots.len() as u32).is_err() ||
-                tree.encode(&mut tree_data).is_err()
-            {
-                error!(target: "runtime::merkle", "Couldn't reserialize modified tree");
-                return -2
-            }
-
-            // Apply changes to overlay
-            let lock = env.blockchain.lock().unwrap();
-            let mut overlay = lock.overlay.lock().unwrap();
-            if overlay.insert(&db_info.tree, &tree_key, &tree_data).is_err() {
-                error!(target: "runtime::merkle", "Couldn't insert to db_info tree");
-                return -2
-            }
-
-            // Here we add the Merkle root to our set of roots
-            // TODO: We should probably make sure that this root isn't in the set
-            for root in new_roots.iter() {
-                // FIXME: Why were we writing the set size here?
-                //let root_index: Vec<u8> = serialize(&(set_size as u32));
-                //assert_eq!(root_index.len(), 4);
-                debug!(target: "runtime::merkle", "Appending Merkle root to db: {:?}", root);
-                let root_value: Vec<u8> = serialize(root);
-                if root_value.len() != 32 {
-                    error!(target: "runtime::merkle", "Couldn't serialize root value");
-                    return -2
-                }
-                if overlay.insert(&db_roots.tree, &root_value, &[]).is_err() {
-                    error!(target: "runtime::merkle", "Couldn't insert to db_roots tree");
-                    return -2
-                }
-            }
-
-            // Write a pointer to the latest known root
-            if !new_roots.is_empty() {
-                debug!(target: "runtime::merkle", "Replacing latest Merkle root pointer");
-                let latest_root = serialize(new_roots.last().unwrap());
-                if overlay.insert(&db_info.tree, &root_key, &latest_root).is_err() {
-                    error!(target: "runtime::merkle", "Couldn't insert latest root to db_info tree");
-                    return -2
-                }
-            }
-
-            0
+    // Make sure that the contract owns the dbs it wants to write to
+    if db_info.contract_id != env.contract_id || db_roots.contract_id != env.contract_id {
+        error!(
+            target: "runtime::merkle::merkle_add",
+            "[WASM] [{}] merkle_add(): Unauthorized to write to DbHandle", cid,
+        );
+        return darkfi_sdk::error::CALLER_ACCESS_DENIED
+    }
+
+    // This `key` represents the sled key in info where the latest root is
+    let root_key: Vec<u8> = match Decodable::decode(&mut buf_reader) {
+        Ok(v) => v,
+        Err(e) => {
+            error!(
+                target: "runtime::merkle::merkle_add",
+                "[WASM] [{}] merkle_add(): Failed to decode key vec: {}", cid, e,
+            );
+            return darkfi_sdk::error::INTERNAL_ERROR
         }
-        _ => -1,
+    };
+
+    // This `key` represents the sled database tree name
+    let tree_key: Vec<u8> = match Decodable::decode(&mut buf_reader) {
+        Ok(v) => v,
+        Err(e) => {
+            error!(
+                target: "runtime::merkle::merkle_add",
+                "[WASM] [{}] merkle_add(): Failed to decode key vec: {}", cid, e,
+            );
+            return darkfi_sdk::error::INTERNAL_ERROR
+        }
+    };
+
+    // This `coin` represents the leaf we're adding to the Merkle tree
+    let coins: Vec<MerkleNode> = match Decodable::decode(&mut buf_reader) {
+        Ok(v) => v,
+        Err(e) => {
+            error!(
+                target: "runtime::merkle::merkle_add",
+                "[WASM] [{}] merkle_add(): Failed to decode MerkleNode: {}", cid, e,
+            );
+            return darkfi_sdk::error::INTERNAL_ERROR
+        }
+    };
+
+    // Make sure we've read the entire buffer
+    if buf_reader.position() != (len as u64) {
+        error!(
+            target: "runtime::merkle::merkle_add",
+            "[WASM] [{}] merkle_add(): Mismatch between given length, and cursor length", cid,
+        );
+        return darkfi_sdk::error::INTERNAL_ERROR
     }
+
+    // Read the current tree
+    let ret = match env
+        .blockchain
+        .lock()
+        .unwrap()
+        .overlay
+        .lock()
+        .unwrap()
+        .get(&db_info.tree, &tree_key)
+    {
+        Ok(v) => v,
+        Err(e) => {
+            error!(
+                target: "runtime::merkle::merkle_add",
+                "[WASM] [{}] merkle_add(): Internal error getting from tree: {}", cid, e,
+            );
+            return darkfi_sdk::error::INTERNAL_ERROR
+        }
+    };
+
+    let Some(return_data) = ret else {
+        error!(
+            target: "runtime::merkle::merkle_add",
+            "[WASM] [{}] merkle_add(): Return data is empty", cid,
+        );
+        return darkfi_sdk::error::INTERNAL_ERROR
+    };
+
+    debug!(
+        target: "runtime::merkle::merkle_add",
+        "Serialized tree: {} bytes",
+        return_data.len()
+    );
+    debug!(
+        target: "runtime::merkle::merkle_add",
+        "                 {:02x?}",
+        return_data
+    );
+
+    let mut decoder = Cursor::new(&return_data);
+    let set_size: u32 = match Decodable::decode(&mut decoder) {
+        Ok(v) => v,
+        Err(e) => {
+            error!(
+                target: "runtime::merkle::merkle_add",
+                "[WASM] [{}] merkle_add(): Unable to read set size: {}", cid, e,
+            );
+            return darkfi_sdk::error::INTERNAL_ERROR
+        }
+    };
+
+    let mut tree: MerkleTree = match Decodable::decode(&mut decoder) {
+        Ok(v) => v,
+        Err(e) => {
+            error!(
+                target: "runtime::merkle::merkle_add",
+                "[WASM] [{}] merkle_add(): Unable to deserialize Merkle tree: {}", cid, e,
+            );
+            return darkfi_sdk::error::INTERNAL_ERROR
+        }
+    };
+
+    // Here we add the new coins into the tree.
+    let mut new_roots = vec![];
+
+    for coin in coins {
+        tree.append(coin);
+        let Some(root) = tree.root(0) else {
+            error!(
+                target: "runtime::merkle::merkle_add",
+                "[WASM] [{}] merkle_add(): Unable to read the root of tree", cid,
+            );
+            return darkfi_sdk::error::INTERNAL_ERROR
+        };
+        new_roots.push(root);
+    }
+
+    // And we serialize the tree back to bytes
+    let mut tree_data = Vec::new();
+    if tree_data.write_u32(set_size + new_roots.len() as u32).is_err() ||
+        tree.encode(&mut tree_data).is_err()
+    {
+        error!(
+            target: "runtime::merkle::merkle_add",
+            "[WASM] [{}] merkle_add(): Couldn't reserialize modified tree", cid,
+        );
+        return darkfi_sdk::error::INTERNAL_ERROR
+    }
+
+    // Apply changes to overlay
+    let lock = env.blockchain.lock().unwrap();
+    let mut overlay = lock.overlay.lock().unwrap();
+    if overlay.insert(&db_info.tree, &tree_key, &tree_data).is_err() {
+        error!(
+            target: "runtime::merkle::merkle_add",
+            "[WASM] [{}] merkle_add(): Couldn't insert to db_info tree", cid,
+        );
+        return darkfi_sdk::error::INTERNAL_ERROR
+    }
+
+    // Here we add the Merkle root to our set of roots
+    // TODO: We should probably make sure that this root isn't in the set
+    for root in new_roots.iter() {
+        // FIXME: Why were we writing the set size here?
+        //let root_index: Vec<u8> = serialize(&(set_size as u32));
+        //assert_eq!(root_index.len(), 4);
+        debug!(
+            target: "runtime::merkle::merkle_add",
+            "[WASM] [{}] merkle_add(): Appending Merkle root to db: {:?}", cid, root,
+        );
+        let root_value: Vec<u8> = serialize(root);
+        if root_value.len() != 32 {
+            error!(
+                target: "runtime::merkle::merkle_add",
+                "[WASM] [{}] merkle_add(): Couldn't serialize root value", cid,
+            );
+            return darkfi_sdk::error::INTERNAL_ERROR
+        }
+
+        if overlay.insert(&db_roots.tree, &root_value, &[]).is_err() {
+            error!(
+                target: "runtime::merkle::merkle_add",
+                "[WASM] [{}] merkle_add(): Couldn't insert to db_roots tree", cid,
+            );
+            return darkfi_sdk::error::INTERNAL_ERROR
+        }
+    }
+
+    // Write a pointer to the latest known root
+    if !new_roots.is_empty() {
+        debug!(
+            target: "runtime::merkle::merkle_add",
+            "[WASM] [{}] merkle_add(): Replacing latest Merkle root pointer", cid,
+        );
+
+        let latest_root = serialize(new_roots.last().unwrap());
+        if overlay.insert(&db_info.tree, &root_key, &latest_root).is_err() {
+            error!(
+                target: "runtime::merkle::merkle_add",
+                "[WASM] [{}] merkle_add(): Couldn't insert latest root to db_info tree", cid,
+            );
+            return darkfi_sdk::error::INTERNAL_ERROR
+        }
+    }
+
+    darkfi_sdk::entrypoint::SUCCESS
 }

+ 109 - 65
src/runtime/import/util.rs

@@ -16,16 +16,16 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-use darkfi_sdk::db::{CALLER_ACCESS_DENIED, DB_GET_FAILED};
 use log::error;
 use wasmer::{FunctionEnvMut, WasmPtr};
 
+use super::acl::acl_allow;
 use crate::runtime::vm_runtime::{ContractSection, Env};
 
 /// Host function for logging strings.
-/// This is injected into the runtime with wasmer's `imports!` macro.
 pub(crate) fn drk_log(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) {
     let env = ctx.data();
+    let cid = &env.contract_id;
     let memory_view = env.memory_view(&ctx);
 
     match ptr.read_utf8_string(&memory_view, len) {
@@ -35,47 +35,53 @@ pub(crate) fn drk_log(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) {
             std::mem::drop(logs);
         }
         Err(_) => {
-            error!(target: "runtime::util", "Failed to read UTF-8 string from VM memory");
+            error!(
+                target: "runtime::util::drk_log",
+                "[WASM] [{}] drk_log(): Failed to read UTF-8 string from VM memory", cid,
+            );
         }
     }
 }
 
-/// Writes data to the `contract_return_data` field of [`Env`]. The data will
-/// be read from `ptr` at a memory offset specified by `len`.
-/// Returns `0` on success, otherwise returns a positive error code
-/// corresponding to a [`ContractError`]. Note that this is in contrast to other
-/// methods in this file that return negative error codes or else return positive
-/// integers that correspond to success states.
+/// Writes data to the `contract_return_data` field of [`Env`].
+/// The data will be read from `ptr` at a memory offset specified by `len`.
+///
+/// Returns `SUCCESS` on success, otherwise returns an error code corresponding
+/// to a [`ContractError`].
 pub(crate) fn set_return_data(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i64 {
     let env = ctx.data();
-    match env.contract_section {
-        ContractSection::Exec | ContractSection::Metadata => {
-            let memory_view = env.memory_view(&ctx);
-
-            let Ok(slice) = ptr.slice(&memory_view, len) else {
-                return darkfi_sdk::error::INTERNAL_ERROR
-            };
-
-            let Ok(return_data) = slice.read_to_vec() else {
-                return darkfi_sdk::error::INTERNAL_ERROR
-            };
-
-            // This function should only ever be called once on the runtime.
-            if env.contract_return_data.take().is_some() {
-                return darkfi_sdk::error::SET_RETVAL_ERROR
-            }
-            env.contract_return_data.set(Some(return_data));
-            0
-        }
-        _ => darkfi_sdk::error::CALLER_ACCESS_DENIED,
+    let cid = &env.contract_id;
+
+    // Enforce function ACL
+    if let Err(e) = acl_allow(env, &[ContractSection::Metadata, ContractSection::Exec]) {
+        error!(
+            target: "runtime::util::set_return_data",
+            "[WASM] [{}] set_return_data(): Called in unauthorized section: {}", cid, e,
+        );
+        return darkfi_sdk::error::CALLER_ACCESS_DENIED
+    }
+
+    let memory_view = env.memory_view(&ctx);
+    let Ok(slice) = ptr.slice(&memory_view, len) else { return darkfi_sdk::error::INTERNAL_ERROR };
+    let Ok(return_data) = slice.read_to_vec() else { return darkfi_sdk::error::INTERNAL_ERROR };
+
+    // This function should only ever be called once on the runtime.
+    if env.contract_return_data.take().is_some() {
+        return darkfi_sdk::error::SET_RETVAL_ERROR
     }
+    env.contract_return_data.set(Some(return_data));
+
+    darkfi_sdk::entrypoint::SUCCESS
 }
 
-/// Appends a new object to the objects store. The data for the object is read from
-/// `ptr`. Returns an index corresponding to the new object's index in the objects
+/// Appends a new object to the [`Env`] objects store.
+/// The data for the object is read from `ptr`.
+///
+/// Returns an index corresponding to the new object's index in the objects
 /// store. (This index is equal to the last index in the store.)
 pub(crate) fn put_object_bytes(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i64 {
     let env = ctx.data();
+    let cid = &env.contract_id;
     let memory_view = env.memory_view(&ctx);
 
     //debug!(target: "runtime::util", "diagnostic:");
@@ -83,14 +89,20 @@ pub(crate) fn put_object_bytes(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len:
     //debug!(target: "runtime::util", "    pages: {}", pages);
 
     let Ok(slice) = ptr.slice(&memory_view, len) else {
-        error!(target: "runtime::util", "Failed to make slice from ptr");
-        return -2
+        error!(
+            target: "runtime::util::put_object_bytes",
+            "[WASM] [{}] put_object_bytes(): Failed to make slice from ptr", cid,
+        );
+        return darkfi_sdk::error::INTERNAL_ERROR
     };
 
     let mut buf = vec![0_u8; len as usize];
     if let Err(e) = slice.read_slice(&mut buf) {
-        error!(target: "runtime::util", "Failed to read from memory slice: {}", e);
-        return -2
+        error!(
+            target: "runtime::util::put_object_bytes",
+            "[WASM] [{}] put_object_bytes(): Failed to read from memory slice: {}", cid, e,
+        );
+        return darkfi_sdk::error::INTERNAL_ERROR
     };
 
     // There would be a serious problem if this is zero.
@@ -99,67 +111,86 @@ pub(crate) fn put_object_bytes(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len:
 
     //debug!(target: "runtime::util", "    memory: {:02x?}", &buf[0..32]);
     //debug!(target: "runtime::util", "            {:x?}", &buf[32..64]);
-
     //debug!(target: "runtime::util", "    ptr location: {}", ptr.offset());
 
     let mut objects = env.objects.borrow_mut();
     objects.push(buf);
     let obj_idx = objects.len() - 1;
 
+    if obj_idx > u32::MAX as usize {
+        return darkfi_sdk::error::DATA_TOO_LARGE
+    }
+
     obj_idx as i64
 }
 
-/// Retrieve an object from the object store specified by the index `idx`. The object's
-/// data is written to `ptr`. Returns `0` on success and an error code otherwise.
+/// Retrieve an object from the object store specified by the index `idx`.
+/// The object's data is written to `ptr`.
+///
+/// Returns `SUCCESS` on success and an error code otherwise.
 pub(crate) fn get_object_bytes(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, idx: u32) -> i64 {
     // Get the slice, where we will read the size of the buffer
-
     let env = ctx.data();
+    let cid = &env.contract_id;
     let memory_view = env.memory_view(&ctx);
 
     // Get the object from env
-
     let objects = env.objects.borrow();
     if idx as usize >= objects.len() {
-        error!(target: "runtime::util", "Tried to access object out of bounds");
-        return -5
+        error!(
+            target: "runtime::util::get_object_bytes",
+            "[WASM] [{}] get_object_bytes(): Tried to access object out of bounds", cid,
+        );
+        return darkfi_sdk::error::DATA_TOO_LARGE
     }
     let obj = &objects[idx as usize];
+    if obj.len() > u32::MAX as usize {
+        return darkfi_sdk::error::DATA_TOO_LARGE
+    }
 
     // Read N bytes from the object and write onto the ptr.
-
-    // We need to re-read the slice, since in the first run, we just read n
     let Ok(slice) = ptr.slice(&memory_view, obj.len() as u32) else {
-        error!(target: "runtime::util", "Failed to make slice from ptr");
-        return -2
+        error!(
+            target: "runtime::util::get_object_bytes",
+            "[WASM] [{}] get_object_bytes(): Failed to make slice from ptr", cid,
+        );
+        return darkfi_sdk::error::INTERNAL_ERROR
     };
 
     // Put the result in the VM
     if let Err(e) = slice.write_slice(obj) {
-        error!(target: "runtime::util", "Failed to write to memory slice: {}", e);
-        return -4
+        error!(
+            target: "runtime::util::get_object_bytes",
+            "[WASM] [{}] get_object_bytes(): Failed to write to memory slice: {}", cid, e,
+        );
+        return darkfi_sdk::error::INTERNAL_ERROR
     };
 
-    0
+    darkfi_sdk::entrypoint::SUCCESS
 }
 
-// Returns the size (number of bytes) of an object in the object store
-// specified by index `idx`.
+/// Returns the size (number of bytes) of an object in the object store
+/// specified by index `idx`.
 pub(crate) fn get_object_size(ctx: FunctionEnvMut<Env>, idx: u32) -> i64 {
     // Get the slice, where we will read the size of the buffer
-
     let env = ctx.data();
-    //let memory_view = env.memory_view(&ctx);
+    let cid = &env.contract_id;
 
     // Get the object from env
-
     let objects = env.objects.borrow();
     if idx as usize >= objects.len() {
-        error!(target: "runtime::util", "Tried to access object out of bounds");
-        return -5
+        error!(
+            target: "runtime::util::get_object_size",
+            "[WASM] [{}] get_object_size(): Tried to access object out of bounds", cid,
+        );
+        return darkfi_sdk::error::DATA_TOO_LARGE
     }
 
     let obj = &objects[idx as usize];
+    if obj.len() > u32::MAX as usize {
+        return darkfi_sdk::error::DATA_TOO_LARGE
+    }
+
     obj.len() as i64
 }
 
@@ -184,30 +215,43 @@ pub(crate) fn get_verifying_slot_epoch(ctx: FunctionEnvMut<Env>) -> u64 {
 }
 
 /// Copies the data of requested slot from `SlotStore` into the VM by appending
-/// the data to the VM's object store. On success, returns the index of the new object in
-/// the object store. Otherwise, returns an error code (negative value).
+/// the data to the VM's object store.
+///
+/// On success, returns the index of the new object in the object store.
+/// Otherwise, returns an error code.
 pub(crate) fn get_slot(ctx: FunctionEnvMut<Env>, slot: u64) -> i64 {
     let env = ctx.data();
+    let cid = &env.contract_id;
 
-    if env.contract_section != ContractSection::Deploy &&
-        env.contract_section != ContractSection::Exec &&
-        env.contract_section != ContractSection::Metadata
+    // Enforce function ACL
+    if let Err(e) =
+        acl_allow(env, &[ContractSection::Deploy, ContractSection::Metadata, ContractSection::Exec])
     {
-        error!(target: "runtime::db::db_get_slot()", "db_get_slot called in unauthorized section");
-        return CALLER_ACCESS_DENIED
+        error!(
+            target: "runtime::db::db_get_slot",
+            "[WASM] [{}] get_slot({}): Called in unauthorized section: {}", cid, slot, e,
+        );
+        return darkfi_sdk::error::CALLER_ACCESS_DENIED
     }
 
     let ret = match env.blockchain.lock().unwrap().slots.get_by_id(slot) {
         Ok(v) => v,
         Err(e) => {
-            error!(target: "runtime::db::db_get_slot()", "Internal error getting from slots tree: {}", e);
-            return DB_GET_FAILED
+            error!(
+                target: "runtime::db::db_get_slot",
+                "[WASM] [{}] db_get_slot(): Internal error getting from slots tree: {}", cid, e,
+            );
+            return darkfi_sdk::error::DB_GET_FAILED
         }
     };
 
     // Copy Vec<u8> to the VM
     let mut objects = env.objects.borrow_mut();
     objects.push(ret.to_vec());
+    if objects.len() > u32::MAX as usize {
+        return darkfi_sdk::error::DATA_TOO_LARGE
+    }
+
     (objects.len() - 1) as i64
 }
 

Некоторые файлы не были показаны из-за большого количества измененных файлов