From 89b09d25cb19836b9a2c0703ee1368ec760016cc Mon Sep 17 00:00:00 2001 From: Arni Hod Date: Thu, 13 Jun 2024 11:24:12 +0300 Subject: [PATCH] feat: check that the compiled class hash matches the supplied class --- crates/gateway/src/errors.rs | 10 ++++++++-- crates/gateway/src/gateway.rs | 12 ++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/crates/gateway/src/errors.rs b/crates/gateway/src/errors.rs index fa3c075d9..9c155a988 100644 --- a/crates/gateway/src/errors.rs +++ b/crates/gateway/src/errors.rs @@ -5,6 +5,7 @@ use blockifier::state::errors::StateError; use blockifier::transaction::errors::TransactionExecutionError; use cairo_vm::types::errors::program_errors::ProgramError; use starknet_api::block::BlockNumber; +use starknet_api::core::CompiledClassHash; use starknet_api::transaction::{Resource, ResourceBounds}; use starknet_api::StarknetApiError; use thiserror::Error; @@ -15,16 +16,21 @@ use tokio::task::JoinError; pub enum GatewayError { #[error(transparent)] CompilationError(#[from] starknet_sierra_compile::compile::CompilationUtilError), + #[error( + "The supplied compiled class hash {supplied:?} does not match the hash of the Casm class \ + compiled from the supplied Sierra {hash_result:?}." + )] + CompiledClassHashMismatch { supplied: CompiledClassHash, hash_result: CompiledClassHash }, #[error("Internal server error: {0}")] InternalServerError(#[from] JoinError), #[error("Error sending message: {0}")] MessageSendError(String), #[error(transparent)] + ProgramError(#[from] ProgramError), + #[error(transparent)] StatefulTransactionValidatorError(#[from] StatefulTransactionValidatorError), #[error(transparent)] StatelessTransactionValidatorError(#[from] StatelessTransactionValidatorError), - #[error(transparent)] - ProgramError(#[from] ProgramError), } impl IntoResponse for GatewayError { diff --git a/crates/gateway/src/gateway.rs b/crates/gateway/src/gateway.rs index 502456e71..14456c341 100644 --- a/crates/gateway/src/gateway.rs +++ b/crates/gateway/src/gateway.rs @@ -8,6 +8,8 @@ use axum::routing::{get, post}; use axum::{Json, Router}; use blockifier::execution::contract_class::{ClassInfo, ContractClassV1}; use blockifier::execution::errors::ContractClassError; +use blockifier::execution::execution_utils::felt_to_stark_felt; +use starknet_api::core::CompiledClassHash; use starknet_api::external_transaction::{ExternalDeclareTransaction, ExternalTransaction}; use starknet_api::transaction::TransactionHash; use starknet_mempool_types::communication::SharedMempoolClient; @@ -158,6 +160,16 @@ fn compile_contract_class(declare_tx: &ExternalDeclareTransaction) -> GatewayRes } }; + // TODO: Handle unwrap. + let hash_result = + CompiledClassHash(felt_to_stark_felt(&casm_contract_class.compiled_class_hash())); + if hash_result != tx.compiled_class_hash { + return Err(GatewayError::CompiledClassHashMismatch { + supplied: tx.compiled_class_hash, + hash_result, + }); + } + // Convert Casm contract class to Starknet contract class directly. let blockifier_contract_class = ContractClassV1::try_from(casm_contract_class)?.into(); let class_info = match ClassInfo::new(