Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add fast serde for basic type #1772

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ mod query;
mod results;
mod sections;
mod serde;
mod serde_basic_type;
mod storage;
mod timestamp;
mod traits;
Expand Down Expand Up @@ -92,6 +93,9 @@ pub use crate::results::{DistributionMsg, StakingMsg};
#[cfg(feature = "stargate")]
pub use crate::results::{GovMsg, VoteOption};
pub use crate::serde::{from_binary, from_slice, to_binary, to_vec};
pub use crate::serde_basic_type::{
deserialize_from_bytes, serialize_to_bytes, SerializeForBasicType,
};
pub use crate::storage::MemoryStorage;
pub use crate::timestamp::Timestamp;
pub use crate::traits::{Api, Querier, QuerierResult, QuerierWrapper, Storage};
Expand Down
93 changes: 93 additions & 0 deletions packages/std/src/serde_basic_type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
pub trait SerializeForBasicType {
fn serialize(&self, buf: &mut Vec<u8>);
fn deserialize(buf: &[u8]) -> Option<Self>
where
Self: Sized;
}

impl SerializeForBasicType for u32 {
fn serialize(&self, buf: &mut Vec<u8>) {
buf.extend_from_slice(&self.to_be_bytes());
}
fn deserialize(buf: &[u8]) -> Option<Self> {
if buf.len() < 4 {
return None;
}
Some(u32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]))
}
}

impl SerializeForBasicType for u64 {
fn serialize(&self, buf: &mut Vec<u8>) {
buf.extend_from_slice(&self.to_be_bytes());
}
fn deserialize(buf: &[u8]) -> Option<Self> {
if buf.len() < 8 {
return None;
}
Some(u64::from_be_bytes([
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7],
]))
}
}

impl SerializeForBasicType for String {
fn serialize(&self, buf: &mut Vec<u8>) {
let bytes = self.as_bytes();
buf.extend_from_slice(bytes);
}
fn deserialize(buf: &[u8]) -> Option<Self> {
Some(String::from_utf8_lossy(buf).to_string())
}
}

#[allow(dead_code)]
pub fn serialize_to_bytes<T: SerializeForBasicType>(value: &T) -> Vec<u8> {
let mut buf = Vec::new();
value.serialize(&mut buf);
buf
}

pub fn deserialize_from_bytes<T: SerializeForBasicType>(bytes: Vec<u8>) -> Option<T> {
T::deserialize(&bytes)
}

#[cfg(test)]
mod tests {
use crate::serde_basic_type::{deserialize_from_bytes, serialize_to_bytes};

#[test]
fn test_u32() {
let array: [u32; 4] = [std::u32::MIN, 1000, 99999, std::u32::MAX];
for element in array.iter() {
let ser_data = serialize_to_bytes(element);
let value: u32 = deserialize_from_bytes(ser_data).unwrap();
assert_eq!(*element, value)
}
}

#[test]
fn test_u64() {
let array: [u64; 4] = [std::u64::MIN, 1000, 99999, std::u64::MAX];
for element in array.iter() {
let ser_data = serialize_to_bytes(element);
let value: u64 = deserialize_from_bytes(ser_data).unwrap();
assert_eq!(*element, value)
}
}

#[test]
fn test_string() {
let array: [String; 4] = [
"okt to the moon".to_string(),
"abc".to_string(),
"hello world".to_string(),
"hello_world".to_string(),
];
for element in array.iter() {
let ser_data = serialize_to_bytes(element);
let value: String = deserialize_from_bytes(ser_data).unwrap();
assert_eq!(*element, value)
}
}
}
27 changes: 23 additions & 4 deletions packages/std/src/traits.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
use serde::{de::DeserializeOwned, Serialize};
use std::marker::PhantomData;
use std::ops::Deref;

use crate::addresses::{Addr, CanonicalAddr};
use crate::binary::Binary;
use crate::coin::Coin;
Expand All @@ -27,9 +23,13 @@ use crate::query::{
};
use crate::results::{ContractResult, Empty, SystemResult};
use crate::serde::{from_binary, to_binary, to_vec};
use crate::serde_basic_type::{deserialize_from_bytes, SerializeForBasicType};
use crate::ContractInfoResponse;
#[cfg(feature = "cosmwasm_1_3")]
use crate::{DenomMetadata, PageRequest};
use serde::{de::DeserializeOwned, Serialize};
use std::marker::PhantomData;
use std::ops::Deref;

/// Storage provides read and write access to a persistent storage.
/// If you only want to provide read access, provide `&Storage`
Expand Down Expand Up @@ -244,6 +244,25 @@ impl<'a, C: CustomQuery> QuerierWrapper<'a, C> {
SystemResult::Ok(ContractResult::Ok(value)) => from_binary(&value),
}
}
pub fn query_ex<U: SerializeForBasicType>(&self, request: &QueryRequest<C>) -> StdResult<U> {
let raw = to_vec(request).map_err(|serialize_err| {
StdError::generic_err(format!("Serializing QueryRequest: {serialize_err}"))
})?;
match self.raw_query(&raw) {
SystemResult::Err(system_err) => Err(StdError::generic_err(format!(
"Querier system error: {system_err}"
))),
SystemResult::Ok(ContractResult::Err(contract_err)) => Err(StdError::generic_err(
format!("Querier contract error: {contract_err}"),
)),
SystemResult::Ok(ContractResult::Ok(value)) => {
let de_value = deserialize_from_bytes(value.to_vec()).ok_or_else(|| {
StdError::generic_err("unexpected error: Deserialization failed")
})?;
Ok(de_value)
}
}
}

#[cfg(feature = "cosmwasm_1_1")]
pub fn query_supply(&self, denom: impl Into<String>) -> StdResult<Coin> {
Expand Down