Skip to content

Commit

Permalink
Changed GlobalStateRequest from enum to struct, made Trie as variant …
Browse files Browse the repository at this point in the history
…of GetRequest which allowed to promote state_identifier to a field directly in GlobalStateRequest
  • Loading branch information
Jakub Zajkowski committed Oct 3, 2024
1 parent ad1f16d commit 94134be
Show file tree
Hide file tree
Showing 10 changed files with 426 additions and 360 deletions.
11 changes: 8 additions & 3 deletions binary_port/src/dictionary_item_identifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub enum DictionaryItemIdentifier {
impl DictionaryItemIdentifier {
#[cfg(test)]
pub(crate) fn random(rng: &mut TestRng) -> Self {
match rng.gen_range(0..4) {
match rng.gen_range(0..5) {
0 => DictionaryItemIdentifier::AccountNamedKey {
hash: rng.gen(),
dictionary_name: rng.random_string(32..64),
Expand All @@ -70,11 +70,16 @@ impl DictionaryItemIdentifier {
dictionary_name: rng.random_string(32..64),
dictionary_item_key: rng.random_string(32..64),
},
2 => DictionaryItemIdentifier::URef {
2 => DictionaryItemIdentifier::EntityNamedKey {
addr: rng.gen(),
dictionary_name: rng.random_string(32..64),
dictionary_item_key: rng.random_string(32..64),
},
3 => DictionaryItemIdentifier::URef {
seed_uref: rng.gen(),
dictionary_item_key: rng.random_string(32..64),
},
3 => DictionaryItemIdentifier::DictionaryItem(rng.gen()),
4 => DictionaryItemIdentifier::DictionaryItem(rng.gen()),
_ => unreachable!(),
}
}
Expand Down
193 changes: 193 additions & 0 deletions binary_port/src/entity_qualifier.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
use super::dictionary_item_identifier::DictionaryItemIdentifier;
use crate::{KeyPrefix, PurseIdentifier};
#[cfg(test)]
use casper_types::testing::TestRng;
use casper_types::{
bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH},
Key, KeyTag,
};
#[cfg(test)]
use rand::Rng;

const ITEM_TAG: u8 = 0;
const ALL_ITEMS_TAG: u8 = 1;
const DICTIONARY_ITEM_TAG: u8 = 2;
const BALANCE_TAG: u8 = 3;
const ITEMS_BY_PREFIX_TAG: u8 = 4;

/// A request to get data from the global state.
#[derive(Clone, Debug, PartialEq)]
pub enum GlobalStateEntityQualifier {
/// Gets an item from the global state.
Item {
/// Key under which data is stored.
base_key: Key,
/// Path under which the value is stored.
path: Vec<String>,
},
/// Get all items under the given key tag.
AllItems {
/// Key tag
key_tag: KeyTag,
},
/// Get a dictionary item by its identifier.
DictionaryItem {
/// Dictionary item identifier.
identifier: DictionaryItemIdentifier,
},
/// Get balance by state root and purse.
Balance {
/// Purse identifier.
purse_identifier: PurseIdentifier,
},
ItemsByPrefix {
/// Key prefix to search for.
key_prefix: KeyPrefix,
},
}

impl GlobalStateEntityQualifier {
#[cfg(test)]
pub(crate) fn random(rng: &mut TestRng) -> Self {
let gen_range = TestRng::gen_range(rng, 0..5);
random_for_variant(gen_range, rng)
}
}

#[cfg(test)]
fn random_for_variant(gen_range: u8, rng: &mut TestRng) -> GlobalStateEntityQualifier {
match gen_range {
ITEM_TAG => {
let path_count = rng.gen_range(10..20);
GlobalStateEntityQualifier::Item {
base_key: rng.gen(),
path: std::iter::repeat_with(|| rng.random_string(32..64))
.take(path_count)
.collect(),
}
}
ALL_ITEMS_TAG => GlobalStateEntityQualifier::AllItems {
key_tag: KeyTag::random(rng),
},
DICTIONARY_ITEM_TAG => GlobalStateEntityQualifier::DictionaryItem {
identifier: DictionaryItemIdentifier::random(rng),
},
BALANCE_TAG => GlobalStateEntityQualifier::Balance {
purse_identifier: PurseIdentifier::random(rng),
},
ITEMS_BY_PREFIX_TAG => GlobalStateEntityQualifier::ItemsByPrefix {
key_prefix: KeyPrefix::random(rng),
},
_ => unreachable!(),
}
}

impl ToBytes for GlobalStateEntityQualifier {
fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
let mut buffer = bytesrepr::allocate_buffer(self)?;
self.write_bytes(&mut buffer)?;
Ok(buffer)
}

fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
match self {
GlobalStateEntityQualifier::Item { base_key, path } => {
ITEM_TAG.write_bytes(writer)?;
base_key.write_bytes(writer)?;
path.write_bytes(writer)
}
GlobalStateEntityQualifier::AllItems { key_tag } => {
ALL_ITEMS_TAG.write_bytes(writer)?;
key_tag.write_bytes(writer)
}
GlobalStateEntityQualifier::DictionaryItem { identifier } => {
DICTIONARY_ITEM_TAG.write_bytes(writer)?;
identifier.write_bytes(writer)
}
GlobalStateEntityQualifier::Balance { purse_identifier } => {
BALANCE_TAG.write_bytes(writer)?;
purse_identifier.write_bytes(writer)
}
GlobalStateEntityQualifier::ItemsByPrefix { key_prefix } => {
ITEMS_BY_PREFIX_TAG.write_bytes(writer)?;
key_prefix.write_bytes(writer)
}
}
}

fn serialized_length(&self) -> usize {
U8_SERIALIZED_LENGTH
+ match self {
GlobalStateEntityQualifier::Item { base_key, path } => {
base_key.serialized_length() + path.serialized_length()
}
GlobalStateEntityQualifier::AllItems { key_tag } => key_tag.serialized_length(),
GlobalStateEntityQualifier::DictionaryItem { identifier } => {
identifier.serialized_length()
}
GlobalStateEntityQualifier::Balance { purse_identifier } => {
purse_identifier.serialized_length()
}
GlobalStateEntityQualifier::ItemsByPrefix { key_prefix } => {
key_prefix.serialized_length()
}
}
}
}

impl FromBytes for GlobalStateEntityQualifier {
fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
let (tag, remainder) = u8::from_bytes(bytes)?;
match tag {
ITEM_TAG => {
let (base_key, remainder) = FromBytes::from_bytes(remainder)?;
let (path, remainder) = FromBytes::from_bytes(remainder)?;
Ok((
GlobalStateEntityQualifier::Item { base_key, path },
remainder,
))
}
ALL_ITEMS_TAG => {
let (key_tag, remainder) = FromBytes::from_bytes(remainder)?;
Ok((GlobalStateEntityQualifier::AllItems { key_tag }, remainder))
}
DICTIONARY_ITEM_TAG => {
let (identifier, remainder) = FromBytes::from_bytes(remainder)?;
Ok((
GlobalStateEntityQualifier::DictionaryItem { identifier },
remainder,
))
}
BALANCE_TAG => {
let (purse_identifier, remainder) = FromBytes::from_bytes(remainder)?;
Ok((
GlobalStateEntityQualifier::Balance { purse_identifier },
remainder,
))
}
ITEMS_BY_PREFIX_TAG => {
let (key_prefix, remainder) = FromBytes::from_bytes(remainder)?;
Ok((
GlobalStateEntityQualifier::ItemsByPrefix { key_prefix },
remainder,
))
}
_ => Err(bytesrepr::Error::Formatting),
}
}
}

#[cfg(test)]
mod tests {
use super::*;
use casper_types::testing::TestRng;

#[test]
fn bytesrepr_roundtrip() {
let rng = &mut TestRng::new();
for i in 0..5 {
let qualifier = random_for_variant(i, rng);
bytesrepr::test_serialization_roundtrip(&qualifier);
}
}
}
25 changes: 23 additions & 2 deletions binary_port/src/get_request.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use casper_types::bytesrepr::{self, Bytes, FromBytes, ToBytes, U8_SERIALIZED_LENGTH};
use casper_types::{
bytesrepr::{self, Bytes, FromBytes, ToBytes, U8_SERIALIZED_LENGTH},
Digest,
};

use crate::state_request::GlobalStateRequest;

Expand All @@ -10,6 +13,7 @@ use rand::Rng;
const RECORD_TAG: u8 = 0;
const INFORMATION_TAG: u8 = 1;
const STATE_TAG: u8 = 2;
const TRIE_TAG: u8 = 3;

/// A request to get data from the node.
#[derive(Clone, Debug, PartialEq)]
Expand All @@ -30,12 +34,17 @@ pub enum GetRequest {
},
/// Retrieves data from the global state.
State(Box<GlobalStateRequest>),
/// Get a trie by its Digest.
Trie {
/// A trie key.
trie_key: Digest,
},
}

impl GetRequest {
#[cfg(test)]
pub(crate) fn random(rng: &mut TestRng) -> Self {
match rng.gen_range(0..3) {
match rng.gen_range(0..4) {
0 => GetRequest::Record {
record_type_tag: rng.gen(),
key: rng.random_vec(16..32),
Expand All @@ -45,6 +54,9 @@ impl GetRequest {
key: rng.random_vec(16..32),
},
2 => GetRequest::State(Box::new(GlobalStateRequest::random(rng))),
3 => GetRequest::Trie {
trie_key: Digest::random(rng),
},
_ => unreachable!(),
}
}
Expand Down Expand Up @@ -76,6 +88,10 @@ impl ToBytes for GetRequest {
STATE_TAG.write_bytes(writer)?;
req.write_bytes(writer)
}
GetRequest::Trie { trie_key } => {
TRIE_TAG.write_bytes(writer)?;
trie_key.write_bytes(writer)
}
}
}

Expand All @@ -90,6 +106,7 @@ impl ToBytes for GetRequest {
info_type_tag.serialized_length() + key.serialized_length()
}
GetRequest::State(req) => req.serialized_length(),
GetRequest::Trie { trie_key } => trie_key.serialized_length(),
}
}
}
Expand Down Expand Up @@ -124,6 +141,10 @@ impl FromBytes for GetRequest {
let (req, remainder) = FromBytes::from_bytes(remainder)?;
Ok((GetRequest::State(Box::new(req)), remainder))
}
TRIE_TAG => {
let (trie_key, remainder) = FromBytes::from_bytes(remainder)?;
Ok((GetRequest::Trie { trie_key }, remainder))
}
_ => Err(bytesrepr::Error::Formatting),
}
}
Expand Down
2 changes: 2 additions & 0 deletions binary_port/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod binary_response;
mod binary_response_and_request;
mod binary_response_header;
mod dictionary_item_identifier;
mod entity_qualifier;
mod era_identifier;
mod error;
mod error_code;
Expand All @@ -31,6 +32,7 @@ pub use binary_response::BinaryResponse;
pub use binary_response_and_request::BinaryResponseAndRequest;
pub use binary_response_header::BinaryResponseHeader;
pub use dictionary_item_identifier::DictionaryItemIdentifier;
pub use entity_qualifier::GlobalStateEntityQualifier;
pub use era_identifier::EraIdentifier;
pub use error::Error;
pub use error_code::ErrorCode;
Expand Down
Loading

0 comments on commit 94134be

Please sign in to comment.