Skip to content

Commit

Permalink
primitives: get rid of Cursor
Browse files Browse the repository at this point in the history
As per the TODO, take `&[u8; 36]` in ValueRef::decode and stop using
Cursor.  This makes the method considerably simpler without making the
call site more complex.  While dealing with ValueRef, stop using
Cursor in account_id_to_shard_id as well.

Issue: near#7327
  • Loading branch information
mina86 committed Dec 9, 2022
1 parent c5610cd commit f2d2dd8
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 24 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion core/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ This crate provides the base set of primitives used by other nearcore crates
[dependencies]
arbitrary.workspace = true
borsh.workspace = true
byteorder.workspace = true
bytesize.workspace = true
cfg-if.workspace = true
chrono.workspace = true
Expand All @@ -31,6 +30,7 @@ reed-solomon-erasure.workspace = true
serde.workspace = true
serde_json.workspace = true
smart-default.workspace = true
stdx.workspace = true
strum.workspace = true
thiserror.workspace = true
tracing.workspace = true
Expand Down
8 changes: 3 additions & 5 deletions core/primitives/src/shard_layout.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
use std::cmp::Ordering::Greater;
use std::{fmt, str};

use byteorder::{LittleEndian, ReadBytesExt};
use serde::{Deserialize, Serialize};

use near_primitives_core::hash::hash;
use near_primitives_core::types::ShardId;

use crate::borsh::maybestd::io::Cursor;
use crate::hash::CryptoHash;
use crate::types::{AccountId, NumShards};
use std::collections::HashMap;
Expand Down Expand Up @@ -251,8 +248,9 @@ impl ShardLayout {
pub fn account_id_to_shard_id(account_id: &AccountId, shard_layout: &ShardLayout) -> ShardId {
match shard_layout {
ShardLayout::V0(ShardLayoutV0 { num_shards, .. }) => {
let mut cursor = Cursor::new(hash(account_id.as_ref().as_bytes()).0);
cursor.read_u64::<LittleEndian>().expect("Must not happened") % (num_shards)
let hash = CryptoHash::hash_bytes(account_id.as_ref().as_bytes());
let (bytes, _) = stdx::split_array::<32, 8, 24>(hash.as_bytes());
u64::from_le_bytes(*bytes) % num_shards
}
ShardLayout::V1(ShardLayoutV1 { fixed_shards, boundary_accounts, .. }) => {
for (shard_id, fixed_account) in fixed_shards.iter().enumerate() {
Expand Down
16 changes: 5 additions & 11 deletions core/primitives/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use borsh::{BorshDeserialize, BorshSerialize};

use byteorder::{LittleEndian, ReadBytesExt};
use near_primitives_core::hash::{hash, CryptoHash};
use std::io::{Cursor, Read};

/// State value reference. Used to charge fees for value length before retrieving the value itself.
#[derive(BorshSerialize, BorshDeserialize, Clone, PartialEq, Eq, Debug)]
Expand All @@ -22,14 +20,10 @@ impl ValueRef {
}

/// Decode value reference from the raw byte array.
/// TODO (#7327): use &[u8; 36] and get rid of Cursor; also check that there are no leftover bytes
pub fn decode(bytes: &[u8]) -> Result<Self, std::io::Error> {
let mut cursor = Cursor::new(bytes);
let value_length = cursor.read_u32::<LittleEndian>()?;
let mut arr = [0; 32];
cursor.read_exact(&mut arr)?;
let value_hash = CryptoHash(arr);
Ok(ValueRef { length: value_length, hash: value_hash })
pub fn decode(bytes: &[u8; 36]) -> Self {
let (length, hash) = stdx::split_array(bytes);
let length = u32::from_le_bytes(*length);
ValueRef { length, hash: CryptoHash(*hash) }
}
}

Expand All @@ -45,7 +39,7 @@ mod tests {
let mut value_ref_ser = [0u8; 36];
value_ref_ser[0..4].copy_from_slice(&old_value_ref.length.to_le_bytes());
value_ref_ser[4..36].copy_from_slice(&old_value_ref.hash.0);
let value_ref = ValueRef::decode(&value_ref_ser).unwrap();
let value_ref = ValueRef::decode(&value_ref_ser);
assert_eq!(value_ref.length, value.len() as u32);
assert_eq!(value_ref.hash, hash(&value));
}
Expand Down
15 changes: 9 additions & 6 deletions core/store/src/flat_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,12 +561,15 @@ pub mod store_helper {
pub(crate) fn get_ref(store: &Store, key: &[u8]) -> Result<Option<ValueRef>, FlatStorageError> {
let raw_ref = store
.get(crate::DBCol::FlatState, key)
.map_err(|_| FlatStorageError::StorageInternalError);
match raw_ref? {
Some(bytes) => ValueRef::decode(&bytes)
.map(Some)
.map_err(|_| FlatStorageError::StorageInternalError),
None => Ok(None),
.map_err(|_| FlatStorageError::StorageInternalError)?;
if let Some(raw_ref) = raw_ref {
let bytes = raw_ref
.as_slice()
.try_into()
.map_err(|_| FlatStorageError::StorageInternalError)?;
Ok(Some(ValueRef::decode(bytes)))
} else {
Ok(None)
}
}

Expand Down

0 comments on commit f2d2dd8

Please sign in to comment.