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 15, 2024
1 parent 57a15a3 commit 2a06947
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 27 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
87 changes: 81 additions & 6 deletions crates/starknet_api/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,85 @@ pub struct Block {
pub body: BlockBody,
}

/// 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>);
macro_rules! starknet_version_enum {
(
$(($variant:ident, $major:literal, $minor:literal, $patch:literal $(, $fourth:literal)?)),+,
$latest:ident
) => {
/// A version of the Starknet protocol used when creating a block.
#[cfg_attr(any(test, feature = "testing"), derive(strum_macros::EnumIter))]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]
pub enum StarknetVersion {
$($variant,)+
}

impl StarknetVersion {
pub const LATEST: Self = Self::$latest;
}

impl From<&StarknetVersion> for Vec<u8> {
fn from(value: &StarknetVersion) -> Self {
match value {
$(
StarknetVersion::$variant => vec![$major, $minor, $patch $(, $fourth)?],
)+
}
}
}

impl TryFrom<Vec<u8>> for StarknetVersion {
type Error = StarknetApiError;

fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
match value[..] {
$(
[$major, $minor, $patch $(, $fourth)?] => Ok(Self::$variant),
)+
_ => Err(StarknetApiError::InvalidStarknetVersion(value)),
}
}
}
}
}

starknet_version_enum! {
(V0_9_1, 0, 9, 1),
(V0_10_0, 0, 10, 0),
(V0_10_1, 0, 10, 1),
(V0_10_2, 0, 10, 2),
(V0_10_3, 0, 10, 3),
(V0_11_0, 0, 11, 0),
(V0_11_0_2, 0, 11, 0, 2),
(V0_11_1, 0, 11, 1),
(V0_11_2, 0, 11, 2),
(V0_12_0, 0, 12, 0),
(V0_12_1, 0, 12, 1),
(V0_12_2, 0, 12, 2),
(V0_12_3, 0, 12, 3),
(V0_13_0, 0, 13, 0),
(V0_13_1, 0, 13, 1),
(V0_13_1_1, 0, 13, 1, 1),
(V0_13_2, 0, 13, 2),
(V0_13_2_1, 0, 13, 2, 1),
(V0_13_3, 0, 13, 3),
V0_13_3
}

impl Default for StarknetVersion {
fn default() -> Self {
Self(vec![0, 0, 0])
Self::LATEST
}
}

impl From<StarknetVersion> for Vec<u8> {
fn from(value: StarknetVersion) -> Self {
Vec::<u8>::from(&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 +123,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 @@ -45,6 +45,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 2a06947

Please sign in to comment.