Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restrictive mode #558

Merged
merged 43 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
4712b21
http api restrictions
marioiordanov Jul 15, 2024
3fe3640
integration tests
marioiordanov Jul 15, 2024
d64d216
refactor
marioiordanov Jul 15, 2024
3a0cc00
json-rpc handling
marioiordanov Jul 16, 2024
54f4bd1
integration test
marioiordanov Jul 16, 2024
44c9be2
remove disable account impersonation flag
marioiordanov Jul 16, 2024
fc0a944
fix wording
marioiordanov Jul 16, 2024
a70b2e5
updated docs
marioiordanov Jul 16, 2024
5484c4e
updated docs
marioiordanov Jul 16, 2024
ccd169f
Merge branch 'main' into restrictive
marioiordanov Jul 16, 2024
5fca64e
Merge branch 'main' into restrictive
marioiordanov Jul 16, 2024
0302147
integration test
marioiordanov Jul 17, 2024
6d7bf89
updated docs
marioiordanov Jul 17, 2024
11cd241
removed comment [skip ci]
marioiordanov Jul 18, 2024
b1dec49
renamed file [skip ci]
marioiordanov Jul 18, 2024
f6d8a8b
change error message [skip ci]
marioiordanov Jul 19, 2024
4f546a8
renamed mappings [skip ci]
marioiordanov Jul 19, 2024
727c587
removed unit test [skip ci]
marioiordanov Jul 19, 2024
26c3ebe
moved mapping to test file [skip ci]
marioiordanov Jul 19, 2024
991c537
docs fix [skip ci]
marioiordanov Jul 19, 2024
74b5ada
changed explanation of restrictive mode [skip ci]
marioiordanov Jul 19, 2024
e688300
docs reorder [skip ci]
marioiordanov Jul 19, 2024
5fb4bbd
added default restricted method [skip ci]
marioiordanov Jul 19, 2024
edf343c
refactor static mappings
marioiordanov Jul 19, 2024
f352426
clippy
marioiordanov Jul 29, 2024
0f0fd9a
renamed file [skip ci]
marioiordanov Jul 30, 2024
37ceb32
renaming [skip ci]
marioiordanov Jul 30, 2024
17b09cb
renaming to constants
marioiordanov Jul 30, 2024
9e8b310
Merge branch 'main' into restrictive
marioiordanov Jul 30, 2024
882e8eb
clippy
marioiordanov Jul 30, 2024
635a707
spaces [skip ci]
marioiordanov Jul 30, 2024
bd705fa
remove leading lashes when user specify methods
marioiordanov Jul 30, 2024
c857060
introduced enum-helper-macros
marioiordanov Aug 5, 2024
adcb70e
added another macro
marioiordanov Aug 5, 2024
0dd445a
unit tests
marioiordanov Aug 5, 2024
11e8f9c
logging an error
marioiordanov Aug 5, 2024
b7bfae6
moved check just after parsing cli args
marioiordanov Aug 5, 2024
c69066c
move restricted_methods check to cli.rs
marioiordanov Aug 5, 2024
d0d8c62
updated docs [skip ci]
marioiordanov Aug 5, 2024
3d1063a
formatted error
marioiordanov Aug 5, 2024
25d6637
unit test
marioiordanov Aug 5, 2024
f459720
update docs [skip ci]
marioiordanov Aug 12, 2024
34cb8ef
enhanced unit test
marioiordanov Aug 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ url = "2.4"
usc = { version = "2.2.0-rc.1", package = "universal-sierra-compiler" }
num-bigint = { version = "0.4" }
bigdecimal = { version = "0.4.5" }
enum-helper-macros = "0.0.1"

# Starknet dependencies
starknet-types-core = "0.1.5"
Expand Down
10 changes: 0 additions & 10 deletions crates/starknet-devnet-core/src/starknet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1310,11 +1310,6 @@ impl Starknet {
msg: "Account impersonation is supported when forking mode is enabled.".to_string(),
});
}
if self.config.disable_account_impersonation {
return Err(Error::UnsupportedAction {
msg: "Account impersonation is disabled.".to_string(),
});
}
if self.pending_state.is_contract_deployed_locally(account)? {
return Err(Error::UnsupportedAction {
msg: "Account is in local state, cannot be impersonated".to_string(),
Expand Down Expand Up @@ -1348,11 +1343,6 @@ impl Starknet {
msg: "Account impersonation is supported when forking mode is enabled.".to_string(),
});
}
if self.config.disable_account_impersonation {
return Err(Error::UnsupportedAction {
msg: "Account impersonation is disabled.".to_string(),
});
}
self.cheats.set_auto_impersonate(auto_impersonation);

Ok(())
Expand Down
2 changes: 0 additions & 2 deletions crates/starknet-devnet-core/src/starknet/starknet_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ pub struct StarknetConfig {
pub re_execute_on_init: bool,
pub state_archive: StateArchiveCapacity,
pub fork_config: ForkConfig,
pub disable_account_impersonation: bool,
}

impl Default for StarknetConfig {
Expand Down Expand Up @@ -146,7 +145,6 @@ impl Default for StarknetConfig {
re_execute_on_init: true,
state_archive: StateArchiveCapacity::default(),
fork_config: ForkConfig::default(),
disable_account_impersonation: false,
}
}
}
2 changes: 2 additions & 0 deletions crates/starknet-devnet-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ serde_json = { workspace = true }
serde = { workspace = true }
thiserror = { workspace = true }
anyhow = { workspace = true }
lazy_static = { workspace = true }
enum-helper-macros = { workspace = true }

# devnet
starknet-core = { workspace = true }
Expand Down
120 changes: 44 additions & 76 deletions crates/starknet-devnet-server/src/api/json_rpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mod write_endpoints;

pub const RPC_SPEC_VERSION: &str = "0.7.1";

use enum_helper_macros::{AllVariantsSerdeRenames, VariantName};
use models::{
BlockAndClassHashInput, BlockAndContractAddressInput, BlockAndIndexInput, CallInput,
EstimateFeeInput, EventsInput, GetStorageInput, TransactionHashInput, TransactionHashOutput,
Expand Down Expand Up @@ -51,9 +52,10 @@ use crate::api::json_rpc::models::{
BroadcastedInvokeTransactionEnumWrapper, SimulateTransactionsInput,
};
use crate::api::serde_helpers::{empty_params, optional_params};
use crate::restrictive_mode::is_json_rpc_method_restricted;
use crate::rpc_core::error::RpcError;
use crate::rpc_core::request::RpcMethodCall;
use crate::rpc_core::response::ResponseResult;
use crate::rpc_core::response::{ResponseResult, RpcResponse};
use crate::rpc_handler::RpcHandler;
use crate::ServerConfig;

Expand Down Expand Up @@ -109,6 +111,45 @@ impl RpcHandler for JsonRpcHandler {
info!(target: "rpc", "received method in on_request {}", request);
self.execute(request, original_call).await
}

async fn on_call(&mut self, call: RpcMethodCall) -> RpcResponse {
trace!(target: "rpc", id = ?call.id , method = ?call.method, "received method call");
let RpcMethodCall { method, params, id, .. } = call.clone();

let params: serde_json::Value = params.into();
let deserializable_call = serde_json::json!({
"method": &method,
"params": params
});

match serde_json::from_value::<Self::Request>(deserializable_call) {
Ok(req) => {
if let Some(restricted_methods) = &self.server_config.restricted_methods {
if is_json_rpc_method_restricted(&method, restricted_methods) {
return RpcResponse::new(
id,
RpcError::new(crate::rpc_core::error::ErrorCode::MethodForbidden),
);
}
}
let result = self.on_request(req, call).await;
RpcResponse::new(id, result)
}
Err(err) => {
let err = err.to_string();
// since JSON-RPC specification requires returning a Method Not Found error,
// we apply a hacky way to induce this - checking the stringified error message
let distinctive_error = format!("unknown variant `{method}`");
if err.contains(&distinctive_error) {
error!(target: "rpc", ?method, "failed to deserialize method due to unknown variant");
RpcResponse::new(id, RpcError::method_not_found())
} else {
error!(target: "rpc", ?method, ?err, "failed to deserialize method");
RpcResponse::new(id, RpcError::invalid_params(err))
}
}
}
}
}

impl JsonRpcHandler {
Expand Down Expand Up @@ -275,7 +316,7 @@ impl JsonRpcHandler {
}
}

#[derive(Deserialize)]
#[derive(Deserialize, AllVariantsSerdeRenames, VariantName)]
#[cfg_attr(test, derive(Debug))]
#[serde(tag = "method", content = "params")]
pub enum JsonRpcRequest {
Expand Down Expand Up @@ -378,82 +419,9 @@ pub enum JsonRpcRequest {
#[serde(rename = "devnet_getConfig", with = "empty_params")]
DevnetConfig,
}

impl std::fmt::Display for JsonRpcRequest {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
JsonRpcRequest::SpecVersion => write!(f, "starknet_specVersion"),
JsonRpcRequest::BlockWithTransactionHashes(_) => {
write!(f, "starknet_getBlockWithTxHashes")
}
JsonRpcRequest::BlockWithFullTransactions(_) => write!(f, "starknet_getBlockWithTxs"),
JsonRpcRequest::BlockWithReceipts(_) => write!(f, "starknet_getBlockWithReceipts"),
JsonRpcRequest::StateUpdate(_) => write!(f, "starknet_getStateUpdate"),
JsonRpcRequest::StorageAt(_) => write!(f, "starknet_getStorageAt"),
JsonRpcRequest::TransactionByHash(_) => write!(f, "starknet_getTransactionByHash"),
JsonRpcRequest::TransactionStatusByHash(_) => {
write!(f, "starknet_getTransactionStatus")
}
JsonRpcRequest::TransactionByBlockAndIndex(_) => {
write!(f, "starknet_getTransactionByBlockIdAndIndex")
}
JsonRpcRequest::TransactionReceiptByTransactionHash(_) => {
write!(f, "starknet_getTransactionReceipt")
}
JsonRpcRequest::ClassByHash(_) => write!(f, "starknet_getClass"),
JsonRpcRequest::ClassHashAtContractAddress(_) => write!(f, "starknet_getClassHashAt"),
JsonRpcRequest::ClassAtContractAddress(_) => write!(f, "starknet_getClassAt"),
JsonRpcRequest::BlockTransactionCount(_) => {
write!(f, "starknet_getBlockTransactionCount")
}
JsonRpcRequest::Call(_) => write!(f, "starknet_call"),
JsonRpcRequest::EstimateFee(_) => write!(f, "starknet_estimateFee"),
JsonRpcRequest::BlockNumber => write!(f, "starknet_blockNumber"),
JsonRpcRequest::BlockHashAndNumber => write!(f, "starknet_blockHashAndNumber"),
JsonRpcRequest::ChainId => write!(f, "starknet_chainId"),
JsonRpcRequest::Syncing => write!(f, "starknet_syncing"),
JsonRpcRequest::Events(_) => write!(f, "starknet_getEvents"),
JsonRpcRequest::ContractNonce(_) => write!(f, "starknet_getNonce"),
JsonRpcRequest::AddDeclareTransaction(_) => {
write!(f, "starknet_addDeclareTransaction")
}
JsonRpcRequest::AddDeployAccountTransaction(_) => {
write!(f, "starknet_addDeployAccountTransaction")
}
JsonRpcRequest::AddInvokeTransaction(_) => write!(f, "starknet_addInvokeTransaction"),
JsonRpcRequest::EstimateMessageFee(_) => write!(f, "starknet_estimateMessageFee"),
JsonRpcRequest::SimulateTransactions(_) => write!(f, "starknet_simulateTransactions"),
JsonRpcRequest::TraceTransaction(_) => write!(f, "starknet_traceTransaction"),
JsonRpcRequest::BlockTransactionTraces(_) => {
write!(f, "starknet_traceBlockTransactions")
}
JsonRpcRequest::ImpersonateAccount(_) => write!(f, "devnet_impersonateAccount"),
JsonRpcRequest::StopImpersonateAccount(_) => {
write!(f, "devnet_stopImpersonateAccount")
}
JsonRpcRequest::AutoImpersonate => write!(f, "devnet_autoImpersonate"),
JsonRpcRequest::StopAutoImpersonate => write!(f, "devnet_stopAutoImpersonate"),
JsonRpcRequest::Dump(_) => write!(f, "devnet_dump"),
JsonRpcRequest::Load(_) => write!(f, "devnet_load"),
JsonRpcRequest::PostmanLoadL1MessagingContract(_) => write!(f, "devnet_postmanLoad"),
JsonRpcRequest::PostmanFlush(_) => write!(f, "devnet_postmanFlush"),
JsonRpcRequest::PostmanSendMessageToL2(_) => {
write!(f, "devnet_postmanSendMessageToL2")
}
JsonRpcRequest::PostmanConsumeMessageFromL2(_) => {
write!(f, "devnet_postmanConsumeMessageFromL2")
}
JsonRpcRequest::CreateBlock => write!(f, "devnet_createBlock"),
JsonRpcRequest::AbortBlocks(_) => write!(f, "devnet_abortBlocks"),
JsonRpcRequest::SetGasPrice(_) => write!(f, "devnet_setGasPrice"),
JsonRpcRequest::Restart => write!(f, "devnet_restart"),
JsonRpcRequest::SetTime(_) => write!(f, "devnet_setTime"),
JsonRpcRequest::IncreaseTime(_) => write!(f, "devnet_increaseTime"),
JsonRpcRequest::PredeployedAccounts(_) => write!(f, "devnet_getPredeployedAccounts"),
JsonRpcRequest::AccountBalance(_) => write!(f, "devnet_getAccountBalance"),
JsonRpcRequest::Mint(_) => write!(f, "devnet_mint"),
JsonRpcRequest::DevnetConfig => write!(f, "devnet_getConfig"),
}
write!(f, "{}", self.variant_name())
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/starknet-devnet-server/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ pub struct ServerConfig {
pub log_request: bool,
#[serde(skip)]
pub log_response: bool,
pub restricted_methods: Option<Vec<String>>,
}
1 change: 1 addition & 0 deletions crates/starknet-devnet-server/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod api;
mod config;
pub mod error;
pub mod restrictive_mode;
pub mod rpc_core;
/// handlers for axum server
pub mod rpc_handler;
Expand Down
Loading