-
Notifications
You must be signed in to change notification settings - Fork 223
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
4901: Changed from enum to struct, moved variant as a variant which allo… r=zajko a=zajko …wed to promote to a field directly on Please consider the following when creating a PR: * Provide a useful description of this PR, suitably verbose, aimed at helping reviewers and contributors * Update all relevant changelogs * Provide a link to the GitHub issue relating to this PR * Identify if any downstream impact as in to, SDKs, SmartContracts etc Co-authored-by: Jakub Zajkowski <[email protected]>
- Loading branch information
Showing
11 changed files
with
427 additions
and
361 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.