Skip to content

Commit

Permalink
Cleaned blockifier contract to flattened sierra conversion (#95)
Browse files Browse the repository at this point in the history
  • Loading branch information
antiyro authored May 4, 2024
1 parent 447fb4f commit b3c6ff0
Show file tree
Hide file tree
Showing 8 changed files with 699 additions and 101 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ git # Deoxys Changelog

## Next release

- fix(classes): Fixed classes on the RPC level by adding ordering and complete deserialisation
- fix: class update
- feat: store key/value in `--disble-root` mode
- fix: storage nonce and key/value
Expand Down
328 changes: 244 additions & 84 deletions Cargo.lock

Large diffs are not rendered by default.

13 changes: 7 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ deoxys-tui = { path = "crates/tui" }

# Starknet dependencies
# Cairo Virtual Machine
cairo-vm = { git = "https://github.com/bidzyyys/cairo-vm", branch = "feature/scale-codec", default-features = false, features = [
cairo-vm = { git = "https://github.com/kasarlabs/cairo-vm", branch = "feature/scale-codec", default-features = false, features = [
"cairo-1-hints",
"parity-scale-codec",
"std",
Expand All @@ -264,17 +264,17 @@ starknet-signers = { git = "https://github.com/kasarlabs/starknet-rs.git", branc

starknet-types-core = { git = "https://github.com/starknet-io/types-rs.git", branch = "main", default-features = false }

blockifier = { git = "https://github.com/bidzyyys/blockifier", branch = "feature/scale-codec" }
blockifier = { git = "https://github.com/kasarlabs/blockifier", branch = "feature/scale-codec" }
starknet_api = { git = "https://github.com/bidzyyys/starknet-api", branch = "feature/scale-codec", features = [
"testing",
"parity-scale-codec",
] }

# Cairo lang
cairo-lang-starknet = { git = "https://github.com/bidzyyys/cairo.git", branch = "feature/scale-codec" }
cairo-lang-starknet-classes = { git = "https://github.com/bidzyyys/cairo.git", branch = "feature/scale-codec" }
cairo-lang-casm = { git = "https://github.com/bidzyyys/cairo.git", branch = "feature/scale-codec" }
cairo-lang-utils = { git = "https://github.com/bidzyyys/cairo.git", branch = "feature/scale-codec" }
cairo-lang-starknet = { git = "https://github.com/kasarlabs/cairo.git", branch = "feature/scale-codec" }
cairo-lang-starknet-classes = { git = "https://github.com/kasarlabs/cairo.git", branch = "feature/scale-codec" }
cairo-lang-casm = { git = "https://github.com/kasarlabs/cairo.git", branch = "feature/scale-codec" }
cairo-lang-utils = { git = "https://github.com/kasarlabs/cairo.git", branch = "feature/scale-codec" }

# Ethers: using the same versions as in Anvil
ethers = { git = "https://github.com/gakonst/ethers-rs" }
Expand All @@ -284,6 +284,7 @@ anyhow = "1.0.75"
assert_matches = "1.5.0"
async-trait = "0.1.74"
bitvec = { version = "1.0.1", default-features = false, features = ["std"] }
base64 = "0.13.1"
clap = { version = "4.4.8", default-features = false, features = ["std"] }
derive_more = { version = "0.99.17", default-features = false }
flate2 = "1.0.28"
Expand Down
4 changes: 3 additions & 1 deletion crates/client/db/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ repository = "https://github.com/kasarlabs/deoxys"
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
# Substrate crates
cairo-lang-starknet-classes = { workspace = true }
cairo-vm = { workspace = true }
flate2 = { workspace = true }
indexmap = { workspace = true }
Expand Down Expand Up @@ -51,6 +51,7 @@ starknet_api = { workspace = true, default-features = true }
# Other crates
anyhow.workspace = true
async-trait = { workspace = true }
base64 = { workspace = true }
bincode = { workspace = true }
bitvec = { workspace = true }
crossbeam-skiplist = { workspace = true }
Expand All @@ -61,6 +62,7 @@ rocksdb = { version = "0.21", features = [
# "multi-threaded-cf",
] }
serde = { workspace = true }
serde_json = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true }
uuid = "1.4.1"
73 changes: 63 additions & 10 deletions crates/client/db/src/storage_handler/primitives/contract_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ use std::sync::Arc;

use anyhow::anyhow;
use blockifier::execution::contract_class::{
ContractClass as ContractClassBlockifier, ContractClassV0, ContractClassV0Inner, ContractClassV1,
ContractClass as ContractClassBlockifier, ContractClassV0, ContractClassV0Inner, ContractClassV1, EntryPointV1,
};
use cairo_vm::types::program::Program;
use flate2::read::GzDecoder;
use flate2::write::GzEncoder;
use indexmap::IndexMap;
use mp_felt::Felt252Wrapper;
use mp_transactions::from_broadcasted_transactions::flattened_sierra_to_casm_contract_class;
use parity_scale_codec::{Decode, Encode};
use starknet_api::core::{ClassHash, EntryPointSelector, Nonce};
Expand All @@ -18,7 +19,7 @@ use starknet_api::hash::StarkFelt;
use starknet_core::types::{
CompressedLegacyContractClass, ContractClass as ContractClassCore, EntryPointsByType, FieldElement,
FlattenedSierraClass, FromByteArrayError, LegacyContractAbiEntry, LegacyContractEntryPoint,
LegacyEntryPointsByType,
LegacyEntryPointsByType, SierraEntryPoint,
};

#[derive(Debug, Encode, Decode)]
Expand Down Expand Up @@ -156,19 +157,33 @@ pub fn from_rpc_contract_class(contract_class: ContractClassCore) -> anyhow::Res
}
}

pub fn to_contract_class_sierra(_: &ContractClassV1, abi: String) -> anyhow::Result<ContractClassCore> {
/// Converts a [ContractClassBlockifier] to a [ContractClassCore]
///
/// This is after extracting the contract classes.
pub fn to_contract_class_sierra(sierra_class: &ContractClassV1, abi: String) -> anyhow::Result<ContractClassCore> {
let entry_points_by_type: HashMap<_, _> =
sierra_class.entry_points_by_type.iter().map(|(k, v)| (*k, v.clone())).collect();
let entry_points_by_type = to_entry_points_by_type(&entry_points_by_type)?;

let sierra_program = sierra_class
.program
.iter_data()
.filter_map(|maybe_relocatable| {
maybe_relocatable.get_int_ref().map(|felt| Felt252Wrapper::from((*felt).clone()))
})
.collect::<Vec<Felt252Wrapper>>();

Ok(ContractClassCore::Sierra(FlattenedSierraClass {
sierra_program: vec![], // TODO: implement this
contract_class_version: option_env!("COMPILER_VERSION").unwrap_or("0.11.2").into(),
entry_points_by_type: EntryPointsByType { constructor: vec![], external: vec![], l1_handler: vec![] }, /* TODO: add entry_points_by_type */
sierra_program: sierra_program.into_iter().map(Into::into).collect(),
contract_class_version: "0.1.0".to_string(),
entry_points_by_type,
abi,
}))
}

/// Converts a [FlattenedSierraClass] to a [ContractClassBlockifier]
///
/// Note: The conversion between the different legacy class versions is handled by an intermediate
/// json representation.
/// This is used before storing the contract classes.
pub fn from_contract_class_sierra(contract_class: FlattenedSierraClass) -> anyhow::Result<ContractClassBlockifier> {
let raw_casm_contract = flattened_sierra_to_casm_contract_class(&Arc::new(contract_class))?;
let blockifier_contract = ContractClassV1::try_from(raw_casm_contract).unwrap();
Expand All @@ -182,9 +197,13 @@ pub fn to_contract_class_cairo(
let entry_points_by_type: HashMap<_, _> =
contract_class.entry_points_by_type.iter().map(|(k, v)| (*k, v.clone())).collect();
let entry_points_by_type = to_legacy_entry_points_by_type(&entry_points_by_type)?;
let compressed_program = compress(&contract_class.program.serialize()?)?;
// Here we order the program passing it to a wrapper of BTreeMaps in order to always obtain the same
// result due to HashMap disruptions
let ordered_program = order_program(&contract_class.program);
let compressed_program = compress(&serialize_program(&ordered_program)?)?;
let encoded_program = base64::encode(compressed_program);
Ok(ContractClassCore::Legacy(CompressedLegacyContractClass {
program: compressed_program,
program: encoded_program.into(),
entry_points_by_type,
abi,
}))
Expand Down Expand Up @@ -248,6 +267,29 @@ fn to_legacy_entry_points_by_type(
Ok(LegacyEntryPointsByType { constructor, external, l1_handler })
}

/// Returns a [anyhow::Result<LegacyEntryPointsByType>] (starknet-rs type) from
/// a [HashMap<EntryPointType, Vec<EntryPoinV1>>]
fn to_entry_points_by_type(entries: &HashMap<EntryPointType, Vec<EntryPointV1>>) -> anyhow::Result<EntryPointsByType> {
fn collect_entry_points(
entries: &HashMap<EntryPointType, Vec<EntryPointV1>>,
entry_point_type: EntryPointType,
) -> anyhow::Result<Vec<SierraEntryPoint>> {
Ok(entries
.get(&entry_point_type)
.ok_or(anyhow!("Missing {:?} entry point", entry_point_type))?
.iter()
.enumerate()
.map(|(index, e)| to_entry_point(e.clone(), index.try_into().unwrap()))
.collect::<Result<Vec<SierraEntryPoint>, FromByteArrayError>>()?)
}

let constructor = collect_entry_points(entries, EntryPointType::Constructor).unwrap_or_default();
let external = collect_entry_points(entries, EntryPointType::External)?;
let l1_handler = collect_entry_points(entries, EntryPointType::L1Handler).unwrap_or_default();

Ok(EntryPointsByType { constructor, external, l1_handler })
}

/// Returns a [IndexMap<EntryPointType, Vec<EntryPoint>>] from a
/// [LegacyEntryPointsByType]
fn from_legacy_entry_points_by_type(entries: &LegacyEntryPointsByType) -> IndexMap<EntryPointType, Vec<EntryPoint>> {
Expand All @@ -269,6 +311,14 @@ fn to_legacy_entry_point(entry_point: EntryPoint) -> Result<LegacyContractEntryP
Ok(LegacyContractEntryPoint { selector, offset })
}

/// Returns a [SierraEntryPoint] (starknet-rs) from a [EntryPointV1]
/// (starknet-api)
fn to_entry_point(entry_point: EntryPointV1, index: u64) -> Result<SierraEntryPoint, FromByteArrayError> {
let selector = FieldElement::from_bytes_be(&entry_point.selector.0.0)?;
let function_idx = index;
Ok(SierraEntryPoint { selector, function_idx })
}

/// Returns a [EntryPoint] (starknet-api) from a [LegacyContractEntryPoint]
/// (starknet-rs)
fn from_legacy_entry_point(entry_point: &LegacyContractEntryPoint) -> EntryPoint {
Expand All @@ -282,6 +332,9 @@ use starknet_core::types::{
LegacyStructAbiEntry, LegacyStructAbiType, LegacyStructMember, LegacyTypedParameter,
};

use crate::storage_handler::primitives::program::order_program;
use crate::storage_handler::primitives::program_serializer::serialize_program;

// Wrapper Class conversion

impl TryFrom<ContractClassCore> for ContractClassWrapper {
Expand Down
2 changes: 2 additions & 0 deletions crates/client/db/src/storage_handler/primitives/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
pub mod contract;
pub mod contract_class;
pub mod program;
pub mod program_serializer;
Loading

0 comments on commit b3c6ff0

Please sign in to comment.