Skip to content

Commit

Permalink
Add check for length of call data in transaction (#988)
Browse files Browse the repository at this point in the history
* Add check for MAX_FELTS_IN_CALLDATA

* fix typo

* Update src/eth_provider/error.rs

Co-authored-by: greged93 <82421016+greged93@users.noreply.github.com>

* fix comments

* retrigger checks

* restrict test to non hive cfg

* add env to hive

---------

Co-authored-by: greged93 <82421016+greged93@users.noreply.github.com>
  • Loading branch information
tcoratger and greged93 authored Apr 21, 2024
1 parent 3b3d333 commit 3fed33f
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,6 @@ COMPILED_KAKAROT_PATH=lib/kakarot/build
## An EVM private to define a default EOA for EVM related scripts
## This default value is Anvil first account private key
EVM_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80

# Number of Felt (bytes) allowed in a single call data
MAX_FELTS_IN_CALLDATA=22500
1 change: 1 addition & 0 deletions docker-compose.prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ services:
- KAKAROT_ADDRESS=0x612fb5de32723a19b073b3aba348e48a3d9f51448426d8931694e51db5795e6
- UNINITIALIZED_ACCOUNT_CLASS_HASH=0x1d8b8047e26b484d3f6262d1967217d980d0f2dfc69afa5661492bd5bfe2954
- ACCOUNT_CONTRACT_CLASS_HASH=0x56d311021950bf65ee500426e007b9e3ced0db97f9c1e0d29a9e03d79a9bf6c
- MAX_FELTS_IN_CALLDATA=22500
restart: on-failure
volumes:
# Mount the indexer code
Expand Down
1 change: 1 addition & 0 deletions docker-compose.staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ services:
- KAKAROT_ADDRESS=0x464f7e37179d2f93ea208795bdb2d0912e8257f6fb5f67ae2559251523aee19
- UNINITIALIZED_ACCOUNT_CLASS_HASH=0x1d8b8047e26b484d3f6262d1967217d980d0f2dfc69afa5661492bd5bfe2954
- ACCOUNT_CONTRACT_CLASS_HASH=0x56d311021950bf65ee500426e007b9e3ced0db97f9c1e0d29a9e03d79a9bf6c
- MAX_FELTS_IN_CALLDATA=22500
restart: on-failure
volumes:
# Mount the indexer code
Expand Down
1 change: 1 addition & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ services:
- RUST_LOG=kakarot_rpc=info
- MONGO_CONNECTION_STRING=mongodb://mongo:mongo@mongo:27017
- MONGO_DATABASE_NAME=kakarot-local
- MAX_FELTS_IN_CALLDATA=22500
volumes:
# Mount the volume on workdir and use .env stored in root of the volume
- deployments:/usr/src/app
Expand Down
3 changes: 2 additions & 1 deletion docker/hive/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ RUN apt-get update && apt-get install -y tini curl jq libssl-dev ca-certificates
#############
### Indexer environment variables
#### Indexer environment variables
ENV ALLOW_ENV_FROM_ENV=DEBUG,APIBARA_AUTH_TOKEN,STARTING_BLOCK,STREAM_URL,SINK_TYPE,MONGO_CONNECTION_STRING,MONGO_DATABASE_NAME,STARKNET_NETWORK,KAKAROT_ADDRESS,ALLOW_NET
ENV ALLOW_ENV_FROM_ENV=DEBUG,APIBARA_AUTH_TOKEN,STARTING_BLOCK,STREAM_URL,SINK_TYPE,MONGO_CONNECTION_STRING,MONGO_DATABASE_NAME,STARKNET_NETWORK,KAKAROT_ADDRESS,ALLOW_NET,MAX_FELTS_IN_CALLDATA
ENV DEBUG=""
ENV APIBARA_AUTH_TOKEN=""
ENV MONGO_CONNECTION_STRING=mongodb://localhost:27017
Expand All @@ -133,6 +133,7 @@ ENV ALLOW_NET=""
ENV KAKAROT_RPC_URL=0.0.0.0:8545
ENV STARKNET_NETWORK=http://localhost:5050
ENV RUST_LOG=kakarot_rpc=info
ENV MAX_FELTS_IN_CALLDATA=22500

HEALTHCHECK --interval=10s --timeout=10s --start-period=15s --retries=5 \
CMD response=$(curl --silent --request POST \
Expand Down
4 changes: 4 additions & 0 deletions src/eth_provider/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ pub enum EthApiError {
/// Other Kakarot error
#[error("kakarot error: {0}")]
KakarotError(KakarotError),
/// Error related to transaction calldata being too large.
#[error("calldata exceeded limit of {0}: {1}")]
CalldataExceededLimit(u64, u64),
}

impl std::fmt::Debug for EthApiError {
Expand All @@ -73,6 +76,7 @@ impl From<EthApiError> for ErrorObject<'static> {
EthApiError::InvalidBlockRange => rpc_err(EthRpcErrorCode::InvalidParams, msg),
EthApiError::TransactionError(err) => rpc_err(err.into(), msg),
EthApiError::SignatureError(_) => rpc_err(EthRpcErrorCode::InvalidParams, msg),
EthApiError::CalldataExceededLimit(_, _) => rpc_err(EthRpcErrorCode::InvalidParams, msg),
EthApiError::Unsupported(_) => rpc_err(EthRpcErrorCode::InternalError, msg),
EthApiError::EthereumDataFormatError(_) => rpc_err(EthRpcErrorCode::InvalidParams, msg),
EthApiError::KakarotError(err) => rpc_err(err.into(), msg),
Expand Down
38 changes: 38 additions & 0 deletions src/eth_provider/starknet/kakarot_core.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::str::FromStr;

#[cfg(not(feature = "hive"))]
use crate::eth_provider::error::EthApiError;
use crate::models::felt::Felt252Wrapper;
use alloy_rlp::Encodable;
use cainome::rs::abigen_legacy;
Expand Down Expand Up @@ -61,6 +63,12 @@ lazy_static! {

// Contract selectors
pub static ref ETH_SEND_TRANSACTION: FieldElement = selector!("eth_send_transaction");

// Maximum number of felts (bytes) in calldata
pub static ref MAX_FELTS_IN_CALLDATA: usize = usize::from_str(
&std::env::var("MAX_FELTS_IN_CALLDATA")
.unwrap_or_else(|_| panic!("Missing environment variable MAX_FELTS_IN_CALLDATA"))
).expect("failing to parse MAX_FELTS_IN_CALLDATA");
}

// Kakarot utils
Expand Down Expand Up @@ -115,6 +123,13 @@ pub fn to_starknet_transaction(

// Prepare the calldata for the Starknet invoke transaction
let capacity = 6 + signed_data.len();

// Check if call data is too large
#[cfg(not(feature = "hive"))]
if capacity > *MAX_FELTS_IN_CALLDATA {
return Err(EthApiError::CalldataExceededLimit(*MAX_FELTS_IN_CALLDATA as u64, capacity as u64));
}

let mut calldata = Vec::with_capacity(capacity);
calldata.append(&mut vec![
FieldElement::ONE, // call array length
Expand All @@ -135,3 +150,26 @@ pub fn to_starknet_transaction(
is_query: false,
}))
}

#[cfg(test)]
mod tests {
use super::*;
use alloy_rlp::Decodable;
use reth_primitives::hex;

#[test]
#[should_panic(expected = "calldata exceeded limit of 22500: 30032")]
fn to_starknet_transaction_too_large_calldata_test() {
// Test that an example create transaction from goerli decodes properly
let tx_bytes = hex!("b901f202f901ee05228459682f008459682f11830209bf8080b90195608060405234801561001057600080fd5b50610175806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80630c49c36c14610030575b600080fd5b61003861004e565b604051610045919061011d565b60405180910390f35b60606020600052600f6020527f68656c6c6f2073746174656d696e64000000000000000000000000000000000060405260406000f35b600081519050919050565b600082825260208201905092915050565b60005b838110156100be5780820151818401526020810190506100a3565b838111156100cd576000848401525b50505050565b6000601f19601f8301169050919050565b60006100ef82610084565b6100f9818561008f565b93506101098185602086016100a0565b610112816100d3565b840191505092915050565b6000602082019050818103600083015261013781846100e4565b90509291505056fea264697066735822122051449585839a4ea5ac23cae4552ef8a96b64ff59d0668f76bfac3796b2bdbb3664736f6c63430008090033c080a0136ebffaa8fc8b9fda9124de9ccb0b1f64e90fbd44251b4c4ac2501e60b104f9a07eb2999eec6d185ef57e91ed099afb0a926c5b536f0155dd67e537c7476e1471");

// Decode the transaction from the provided bytes
let mut transaction = TransactionSigned::decode(&mut &tx_bytes[..]).unwrap();

// Set the input of the transaction to be a vector of 30,000 zero bytes
transaction.transaction.set_input(vec![0; 30000].into());

// Attempt to convert the transaction into a Starknet transaction
to_starknet_transaction(&transaction, 1, transaction.recover_signer().unwrap(), 100000000).unwrap();
}
}

0 comments on commit 3fed33f

Please sign in to comment.