Skip to content

Commit

Permalink
feat(starknet_api): the StarknetVersion type is now an enum
Browse files Browse the repository at this point in the history
  • Loading branch information
dorimedini-starkware committed Oct 14, 2024
1 parent 8f378b7 commit e8e7154
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 28 deletions.
6 changes: 3 additions & 3 deletions crates/papyrus_rpc/src/v0_8/api/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ async fn get_block_w_full_transactions() {
let block_hash = BlockHash(random::<u64>().into());
let sequencer_address = SequencerContractAddress(random::<u64>().into());
let timestamp = BlockTimestamp(random::<u64>());
let starknet_version = StarknetVersion(vec![123]);
let starknet_version = StarknetVersion::V0_10_0;
block.header.block_hash = block_hash;
block.header.block_header_without_hash.sequencer = sequencer_address;
block.header.block_header_without_hash.timestamp = timestamp;
Expand Down Expand Up @@ -680,7 +680,7 @@ async fn get_block_w_full_transactions_and_receipts() {
let block_hash = BlockHash(random::<u64>().into());
let sequencer_address = SequencerContractAddress(random::<u64>().into());
let timestamp = BlockTimestamp(random::<u64>());
let starknet_version = StarknetVersion(vec![123]);
let starknet_version = StarknetVersion::V0_10_0;
let block_number = block.header.block_header_without_hash.block_number;
block.header.block_hash = block_hash;
block.header.block_header_without_hash.sequencer = sequencer_address;
Expand Down Expand Up @@ -882,7 +882,7 @@ async fn get_block_w_transaction_hashes() {
let block_hash = BlockHash(random::<u64>().into());
let sequencer_address = SequencerContractAddress(random::<u64>().into());
let timestamp = BlockTimestamp(random::<u64>());
let starknet_version = StarknetVersion(vec![123]);
let starknet_version = StarknetVersion::V0_10_0;
block.header.block_hash = block_hash;
block.header.block_header_without_hash.sequencer = sequencer_address;
block.header.block_header_without_hash.timestamp = timestamp;
Expand Down
4 changes: 2 additions & 2 deletions crates/papyrus_storage/src/header_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,8 @@ async fn starknet_version() {
reader.begin_ro_txn().unwrap().get_starknet_version(BlockNumber(1)).unwrap();
assert!(non_existing_block_starknet_version.is_none());

let second_version = StarknetVersion(vec![2]);
let yet_another_version = StarknetVersion(vec![3]);
let second_version = StarknetVersion::V0_9_1;
let yet_another_version = StarknetVersion::V0_12_0;

writer
.begin_rw_txn()
Expand Down
22 changes: 21 additions & 1 deletion crates/papyrus_storage/src/serialization/serializers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,27 @@ auto_storage_serde! {
pub enum StructType {
Struct = 0,
}
pub struct StarknetVersion(pub Vec<u8>);
pub enum StarknetVersion {
V0_9_1 = 0,
V0_10_0 = 1,
V0_10_1 = 2,
V0_10_2 = 3,
V0_10_3 = 4,
V0_11_0 = 5,
V0_11_0_2 = 6,
V0_11_1 = 7,
V0_11_2 = 8,
V0_12_0 = 9,
V0_12_1 = 10,
V0_12_2 = 11,
V0_12_3 = 12,
V0_13_0 = 13,
V0_13_1 = 14,
V0_13_1_1 = 15,
V0_13_2 = 16,
V0_13_2_1 = 17,
V0_13_3 = 18,
}
pub struct StateDiffCommitment(pub PoseidonHash);
pub struct Tip(pub u64);
pub struct TransactionCommitment(pub StarkHash);
Expand Down
22 changes: 21 additions & 1 deletion crates/papyrus_test_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,27 @@ auto_impl_get_test_instance! {
MulMod = 9,
RangeCheck96 = 10,
}
pub struct StarknetVersion(pub Vec<u8>);
pub enum StarknetVersion {
V0_9_1 = 0,
V0_10_0 = 1,
V0_10_1 = 2,
V0_10_2 = 3,
V0_10_3 = 4,
V0_11_0 = 5,
V0_11_0_2 = 6,
V0_11_1 = 7,
V0_11_2 = 8,
V0_12_0 = 9,
V0_12_1 = 10,
V0_12_2 = 11,
V0_12_3 = 12,
V0_13_0 = 13,
V0_13_1 = 14,
V0_13_1_1 = 15,
V0_13_2 = 16,
V0_13_2_1 = 17,
V0_13_3 = 18,
}
pub struct Calldata(pub Arc<Vec<Felt>>);
pub struct ClassHash(pub StarkHash);
pub struct CompiledClassHash(pub StarkHash);
Expand Down
102 changes: 95 additions & 7 deletions crates/starknet_api/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,97 @@ pub struct Block {
}

/// A version of the Starknet protocol used when creating a block.
#[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]
pub struct StarknetVersion(pub Vec<u8>);
#[cfg_attr(any(test, feature = "testing"), derive(strum_macros::EnumIter))]
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash, PartialOrd, Ord)]
pub enum StarknetVersion {
V0_9_1,
V0_10_0,
V0_10_1,
V0_10_2,
V0_10_3,
V0_11_0,
V0_11_0_2,
V0_11_1,
V0_11_2,
V0_12_0,
V0_12_1,
V0_12_2,
V0_12_3,
V0_13_0,
V0_13_1,
V0_13_1_1,
V0_13_2,
V0_13_2_1,
#[default]
V0_13_3,
}

impl Default for StarknetVersion {
fn default() -> Self {
Self(vec![0, 0, 0])
impl From<&StarknetVersion> for Vec<u8> {
fn from(value: &StarknetVersion) -> Self {
match value {
StarknetVersion::V0_9_1 => vec![0, 9, 1],
StarknetVersion::V0_10_0 => vec![0, 10, 0],
StarknetVersion::V0_10_1 => vec![0, 10, 1],
StarknetVersion::V0_10_2 => vec![0, 10, 2],
StarknetVersion::V0_10_3 => vec![0, 10, 3],
StarknetVersion::V0_11_0 => vec![0, 11, 0],
StarknetVersion::V0_11_0_2 => vec![0, 11, 0, 2],
StarknetVersion::V0_11_1 => vec![0, 11, 1],
StarknetVersion::V0_11_2 => vec![0, 11, 2],
StarknetVersion::V0_12_0 => vec![0, 12, 0],
StarknetVersion::V0_12_1 => vec![0, 12, 1],
StarknetVersion::V0_12_2 => vec![0, 12, 2],
StarknetVersion::V0_12_3 => vec![0, 12, 3],
StarknetVersion::V0_13_0 => vec![0, 13, 0],
StarknetVersion::V0_13_1 => vec![0, 13, 1],
StarknetVersion::V0_13_1_1 => vec![0, 13, 1, 1],
StarknetVersion::V0_13_2 => vec![0, 13, 2],
StarknetVersion::V0_13_2_1 => vec![0, 13, 2, 1],
StarknetVersion::V0_13_3 => vec![0, 13, 3],
}
}
}

impl From<StarknetVersion> for Vec<u8> {
fn from(value: StarknetVersion) -> Self {
Vec::<u8>::from(&value)
}
}

impl TryFrom<Vec<u8>> for StarknetVersion {
type Error = StarknetApiError;
fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
if value.len() != 3 && value.len() != 4 {
return Err(StarknetApiError::InvalidStarknetVersion(value));
}
match (value[0], value[1], value[2], value.get(3)) {
(0, 9, 1, None) => Ok(Self::V0_9_1),
(0, 10, 0, None) => Ok(Self::V0_10_0),
(0, 10, 1, None) => Ok(Self::V0_10_1),
(0, 10, 2, None) => Ok(Self::V0_10_2),
(0, 10, 3, None) => Ok(Self::V0_10_3),
(0, 11, 0, None) => Ok(Self::V0_11_0),
(0, 11, 0, Some(2)) => Ok(Self::V0_11_0_2),
(0, 11, 1, None) => Ok(Self::V0_11_1),
(0, 11, 2, None) => Ok(Self::V0_11_2),
(0, 12, 0, None) => Ok(Self::V0_12_0),
(0, 12, 1, None) => Ok(Self::V0_12_1),
(0, 12, 2, None) => Ok(Self::V0_12_2),
(0, 12, 3, None) => Ok(Self::V0_12_3),
(0, 13, 0, None) => Ok(Self::V0_13_0),
(0, 13, 1, None) => Ok(Self::V0_13_1),
(0, 13, 1, Some(1)) => Ok(Self::V0_13_1_1),
(0, 13, 2, None) => Ok(Self::V0_13_2),
(0, 13, 2, Some(1)) => Ok(Self::V0_13_2_1),
(0, 13, 3, None) => Ok(Self::V0_13_3),
_ => Err(StarknetApiError::InvalidStarknetVersion(value)),
}
}
}

impl Display for StarknetVersion {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0.iter().map(|x| x.to_string()).join("."))
write!(f, "{}", Vec::<u8>::from(self).iter().map(|x| x.to_string()).join("."))
}
}

Expand All @@ -57,7 +136,16 @@ impl TryFrom<String> for StarknetVersion {

/// Parses a string separated by dots into a StarknetVersion.
fn try_from(starknet_version: String) -> Result<Self, StarknetApiError> {
Ok(Self(starknet_version.split('.').map(|x| x.parse::<u8>()).try_collect()?))
let version: Vec<u8> =
starknet_version.split('.').map(|x| x.parse::<u8>()).try_collect()?;
Ok(Self::try_from(version)?)
}
}

impl TryFrom<&str> for StarknetVersion {
type Error = StarknetApiError;
fn try_from(starknet_version: &str) -> Result<Self, StarknetApiError> {
Self::try_from(starknet_version.to_string())
}
}

Expand Down
4 changes: 2 additions & 2 deletions crates/starknet_api/src/block_hash/block_hash_calculator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ pub enum BlockHashVersion {
impl From<BlockHashVersion> for StarknetVersion {
fn from(value: BlockHashVersion) -> Self {
match value {
BlockHashVersion::VO_13_2 => StarknetVersion(vec![0, 13, 2]),
BlockHashVersion::VO_13_3 => StarknetVersion(vec![0, 13, 3]),
BlockHashVersion::VO_13_2 => StarknetVersion::V0_13_2,
BlockHashVersion::VO_13_3 => StarknetVersion::V0_13_3,
}
}
}
Expand Down
31 changes: 19 additions & 12 deletions crates/starknet_api/src/block_test.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use serde_json::json;
use strum::IntoEnumIterator;

use super::{verify_block_signature, StarknetVersion};
use crate::block::{BlockHash, BlockNumber, BlockSignature};
Expand Down Expand Up @@ -49,18 +50,24 @@ fn block_signature_verification() {
}

#[test]
fn test_vec_version() {
assert_eq!(StarknetVersion::default().to_string(), "0.0.0");

let version_123 = StarknetVersion::try_from("1.2.3".to_owned()).unwrap();
assert_eq!(version_123, StarknetVersion(vec![1, 2, 3]));
fn test_version_serde() {
for version in StarknetVersion::iter() {
// To/from Vec<u8>.
assert_eq!(StarknetVersion::try_from(Vec::<u8>::from(&version)).unwrap(), version);
// To/from json.
assert_eq!(serde_json::from_value::<StarknetVersion>(json!(version)).unwrap(), version);
}

let serialized_123 = json!(version_123);
assert_eq!(serialized_123, "1.2.3".to_owned());
assert_eq!(serde_json::from_value::<StarknetVersion>(serialized_123).unwrap(), version_123);
// Sanity check substring deserialization.
assert_eq!(StarknetVersion::try_from("0.13.1").unwrap(), StarknetVersion::V0_13_1);
assert_eq!(StarknetVersion::try_from("0.13.1.1").unwrap(), StarknetVersion::V0_13_1_1);
}

assert!(StarknetVersion(vec![0, 10, 0]) > StarknetVersion(vec![0, 2, 5]));
assert!(StarknetVersion(vec![0, 13, 1]) > StarknetVersion(vec![0, 12, 2]));
assert!(StarknetVersion(vec![0, 13, 0, 1]) > StarknetVersion(vec![0, 13, 0]));
assert!(StarknetVersion(vec![0, 13, 0]) > StarknetVersion(vec![0, 13]));
/// Order of version variants should match byte-vector lexicographic order.
#[test]
fn test_version_byte_vec_order() {
let versions = StarknetVersion::iter().collect::<Vec<_>>();
for i in 0..(versions.len() - 1) {
assert!(Vec::<u8>::from(versions[i]) <= Vec::<u8>::from(versions[i + 1]));
}
}
2 changes: 2 additions & 0 deletions crates/starknet_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ pub enum StarknetApiError {
/// Missing resource type / duplicated resource type.
#[error("Missing resource type / duplicated resource type; got {0}.")]
InvalidResourceMappingInitializer(String),
#[error("Invalid Starknet version: {0:?}")]
InvalidStarknetVersion(Vec<u8>),
#[error("NonzeroGasPrice cannot be zero.")]
ZeroGasPrice,
}
Expand Down

0 comments on commit e8e7154

Please sign in to comment.