Skip to content

Commit 1353bd8

Browse files
authored
Breaking: Remove request body size limit; set class size declaration limits; reduce gas prices (#743)
* Reduce all gas prices from 1e11 to 1e9 FRI
1 parent 7301e02 commit 1353bd8

File tree

19 files changed

+142
-176
lines changed

19 files changed

+142
-176
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Compiled with:
2+
scarb 2.9.2 (5070ff374 2024-12-11)
3+
cairo: 2.9.2 (https://crates.io/crates/cairo-lang-compiler/2.9.2)
4+
sierra: 1.6.0
5+
6+
Intercepted declaration, logged; this exceeds bytecode size, but not the serialized class size
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
if [ $# -ne 1 ]; then
6+
echo >&2 "Error! Usage: $0 <N_PROPERTIES>"
7+
exit 1
8+
fi
9+
10+
N="$1"
11+
12+
echo '#[starknet::contract]'
13+
echo 'pub mod Dummy {'
14+
echo ' use core::starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess};'
15+
echo ''
16+
echo ' #[storage]'
17+
echo ' pub struct Storage {'
18+
19+
for i in $(seq 1 $N); do
20+
echo " balance_$i: felt252,"
21+
done
22+
23+
echo ' }'
24+
echo ''
25+
26+
for i in $(seq 1 $N); do
27+
echo ' #[external(v0)]'
28+
echo " pub fn increment_balance_$i(ref self: ContractState) {"
29+
echo " self.balance_$i.write(self.balance_$i.read() + 1)"
30+
echo ' }'
31+
echo ''
32+
echo ' #[external(v0)]'
33+
echo " pub fn get_balance_$i(self: @ContractState) -> felt252 {"
34+
echo " self.balance_$i.read()"
35+
echo ' }'
36+
echo ''
37+
done
38+
39+
echo '}'

contracts/test_artifacts/cairo1/too_big/too_big.sierra

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

crates/starknet-devnet-core/src/constants.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,14 @@ pub const DEVNET_DEFAULT_SEED: u32 = 123;
9090
pub const DEVNET_DEFAULT_TEST_SEED: u32 = 123;
9191
pub const DEVNET_DEFAULT_TOTAL_ACCOUNTS: u8 = 10;
9292
pub const DEVNET_DEFAULT_INITIAL_BALANCE: u128 = 1_000_000_000_000_000_000_000;
93-
pub const DEVNET_DEFAULT_L1_GAS_PRICE: NonZeroU128 = nonzero!(100_000_000_000u128);
94-
pub const DEVNET_DEFAULT_L1_DATA_GAS_PRICE: NonZeroU128 = nonzero!(100_000_000_000u128);
95-
pub const DEVNET_DEFAULT_L2_GAS_PRICE: NonZeroU128 = nonzero!(100_000_000_000u128);
93+
pub const DEVNET_DEFAULT_L1_GAS_PRICE: NonZeroU128 = nonzero!(1_000_000_000u128);
94+
pub const DEVNET_DEFAULT_L1_DATA_GAS_PRICE: NonZeroU128 = nonzero!(1_000_000_000u128);
95+
pub const DEVNET_DEFAULT_L2_GAS_PRICE: NonZeroU128 = nonzero!(1_000_000_000u128);
9696
pub const DEVNET_DEFAULT_HOST: IpAddr = IpAddr::V4(Ipv4Addr::LOCALHOST);
9797
pub const DEVNET_DEFAULT_PORT: u16 = 5050;
9898
pub const DEVNET_DEFAULT_TIMEOUT: u16 = 120;
9999
pub const DEVNET_DEFAULT_CHAIN_ID: ChainId = ChainId::Testnet;
100100
pub const DEVNET_DEFAULT_STARTING_BLOCK_NUMBER: u64 = 0;
101-
pub const DEVNET_DEFAULT_REQUEST_BODY_SIZE_LIMIT: usize = 2_000_000;
102101

103102
pub const USE_KZG_DA: bool = true;
104103

@@ -111,3 +110,7 @@ pub const CHARGEABLE_ACCOUNT_ADDRESS: &str =
111110

112111
pub const ENTRYPOINT_NOT_FOUND_ERROR_ENCODED: Felt =
113112
Felt::from_hex_unchecked("0x454e545259504f494e545f4e4f545f464f554e44");
113+
114+
pub const MAXIMUM_CONTRACT_CLASS_SIZE: usize = 4_089_446;
115+
pub const MAXIMUM_CONTRACT_BYTECODE_SIZE: usize = 81_920;
116+
pub const MAXIMUM_SIERRA_LENGTH: usize = 81_920;

crates/starknet-devnet-core/src/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ pub enum Error {
7878
ClassAlreadyDeclared { msg: String },
7979
#[error("Requested entrypoint does not exist in the contract")]
8080
EntrypointNotFound,
81+
#[error("Contract class size it too large")]
82+
ContractClassSizeIsTooLarge,
8183
}
8284

8385
impl From<starknet_types_core::felt::FromStrError> for Error {

crates/starknet-devnet-core/src/starknet/add_declare_transaction.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,41 @@ use starknet_types::rpc::transactions::{
99
BroadcastedDeclareTransaction, DeclareTransaction, Transaction, TransactionWithHash,
1010
};
1111

12+
use crate::constants::{
13+
MAXIMUM_CONTRACT_BYTECODE_SIZE, MAXIMUM_CONTRACT_CLASS_SIZE, MAXIMUM_SIERRA_LENGTH,
14+
};
1215
use crate::error::{DevnetResult, Error, TransactionValidationError};
1316
use crate::starknet::Starknet;
1417
use crate::state::CustomState;
1518

19+
fn check_class_size(
20+
executable_tx: &starknet_api::executable_transaction::DeclareTransaction,
21+
) -> DevnetResult<()> {
22+
let serialized_class = serde_json::to_vec(&executable_tx.contract_class()).map_err(|e| {
23+
Error::UnexpectedInternalError {
24+
msg: format!("Could not determine class size via serialization: {e}"),
25+
}
26+
})?;
27+
28+
let sierra_length = executable_tx.class_info.sierra_program_length();
29+
let casm_length = executable_tx.class_info.bytecode_length();
30+
tracing::info!(
31+
"Declaring class: serialized size: {} bytes, sierra: {} felts, casm: {} felts",
32+
serialized_class.len(),
33+
sierra_length,
34+
casm_length,
35+
);
36+
37+
if serialized_class.len() > MAXIMUM_CONTRACT_CLASS_SIZE
38+
|| sierra_length > MAXIMUM_SIERRA_LENGTH
39+
|| casm_length > MAXIMUM_CONTRACT_BYTECODE_SIZE
40+
{
41+
return Err(Error::ContractClassSizeIsTooLarge);
42+
}
43+
44+
Ok(())
45+
}
46+
1647
pub fn add_declare_transaction(
1748
starknet: &mut Starknet,
1849
broadcasted_declare_transaction: BroadcastedDeclareTransaction,
@@ -30,6 +61,8 @@ pub fn add_declare_transaction(
3061
let executable_tx =
3162
broadcasted_declare_transaction.create_sn_api_declare(&starknet.chain_id().to_felt())?;
3263

64+
check_class_size(&executable_tx)?;
65+
3366
let transaction_hash = executable_tx.tx_hash.0;
3467
let class_hash = executable_tx.class_hash().0;
3568

crates/starknet-devnet-server/src/api/json_rpc/error.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ pub enum ApiError {
7171
InvalidSubscriptionId,
7272
#[error("Devnet doesn't support storage proofs")] // slightly modified spec message
7373
StorageProofNotSupported,
74+
#[error("Contract class size it too large")]
75+
ContractClassSizeIsTooLarge,
7476
}
7577

7678
impl ApiError {
@@ -236,6 +238,11 @@ impl ApiError {
236238
message: error_message.into(),
237239
data: None,
238240
},
241+
ApiError::ContractClassSizeIsTooLarge => RpcError {
242+
code: crate::rpc_core::error::ErrorCode::ServerError(57),
243+
message: error_message.into(),
244+
data: None,
245+
},
239246
}
240247
}
241248

@@ -271,6 +278,7 @@ impl ApiError {
271278
| Self::InvalidSubscriptionId
272279
| Self::InsufficientResourcesForValidate
273280
| Self::StorageProofNotSupported
281+
| Self::ContractClassSizeIsTooLarge
274282
| Self::CompiledClassHashMismatch => false,
275283
}
276284
}

crates/starknet-devnet-server/src/api/json_rpc/write_endpoints.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ impl JsonRpcHandler {
3939
starknet_core::error::Error::ClassAlreadyDeclared { .. } => {
4040
ApiError::ClassAlreadyDeclared
4141
}
42+
starknet_core::error::Error::ContractClassSizeIsTooLarge => {
43+
ApiError::ContractClassSizeIsTooLarge
44+
}
4245
unknown_error => ApiError::StarknetDevnetError(unknown_error),
4346
},
4447
)?;

crates/starknet-devnet-server/src/config.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ pub struct ServerConfig {
77
pub host: IpAddr,
88
pub port: u16,
99
pub timeout: u16,
10-
pub request_body_size_limit: usize,
1110
#[serde(skip)]
1211
pub log_request: bool,
1312
#[serde(skip)]

crates/starknet-devnet-server/src/server.rs

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ use tower_http::trace::TraceLayer;
1818
use crate::api::http::{HttpApiHandler, endpoints as http};
1919
use crate::api::json_rpc::JsonRpcHandler;
2020
use crate::restrictive_mode::is_uri_path_restricted;
21-
use crate::rpc_core::error::RpcError;
22-
use crate::rpc_core::response::ResponseResult;
2321
use crate::rpc_handler::RpcHandler;
2422
use crate::{ServerConfig, http_rpc_router, rpc_handler};
2523
pub type StarknetDevnetServer = axum::serve::Serve<IntoMakeService<Router>, Router>;
@@ -108,10 +106,6 @@ pub async fn serve_http_api_json_rpc(
108106
routes = routes
109107
.layer(TimeoutLayer::new(Duration::from_secs(server_config.timeout.into())))
110108
.layer(DefaultBodyLimit::disable())
111-
.layer(axum::middleware::from_fn_with_state(
112-
server_config.request_body_size_limit,
113-
reject_too_big,
114-
))
115109
.layer(
116110
// More details: https://docs.rs/tower-http/latest/tower_http/cors/index.html
117111
CorsLayer::new()
@@ -172,40 +166,6 @@ async fn request_logging_middleware(
172166
Ok(next.run(Request::from_parts(parts, body)).await)
173167
}
174168

175-
async fn reject_too_big(
176-
State(payload_limit): State<usize>,
177-
request: Request,
178-
next: Next,
179-
) -> Result<impl IntoResponse, (StatusCode, String)> {
180-
fn bad_request(e: impl std::fmt::Display) -> (StatusCode, String) {
181-
(StatusCode::BAD_REQUEST, format!("Invalid Content-Length: {e}"))
182-
}
183-
184-
if let Some(content_length) = request.headers().get(header::CONTENT_LENGTH) {
185-
let content_length: usize =
186-
content_length.to_str().map_err(bad_request)?.parse().map_err(bad_request)?;
187-
188-
if content_length > payload_limit {
189-
return Err((
190-
StatusCode::PAYLOAD_TOO_LARGE,
191-
serde_json::to_string(&ResponseResult::Error(RpcError {
192-
code: crate::rpc_core::error::ErrorCode::InvalidRequest,
193-
message: format!(
194-
"Request too big! Server received: {content_length} bytes; maximum \
195-
(specifiable via --request-body-size-limit): {payload_limit} bytes"
196-
)
197-
.into(),
198-
data: None,
199-
}))
200-
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?,
201-
));
202-
}
203-
}
204-
205-
let response = next.run(request).await;
206-
Ok(response)
207-
}
208-
209169
async fn response_logging_middleware(
210170
request: Request,
211171
next: Next,

0 commit comments

Comments
 (0)