Skip to content

Commit 6806b69

Browse files
committed
Handle redeclaration in estimate fee, closes #3253
commit-id:f3897b34
1 parent c851f3f commit 6806b69

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

crates/sncast/src/starknet_commands/declare.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ use sncast::helpers::rpc::RpcArgs;
99
use sncast::response::declare::{
1010
AlreadyDeclaredResponse, DeclareResponse, DeclareTransactionResponse,
1111
};
12-
use sncast::response::errors::StarknetCommandError;
12+
use sncast::response::errors::{SNCastProviderError, SNCastStarknetError, StarknetCommandError};
1313
use sncast::{ErrorData, WaitForTx, apply_optional_fields, handle_wait_for_tx};
1414
use starknet::accounts::AccountError::Provider;
1515
use starknet::accounts::{ConnectedAccount, DeclarationV3};
16-
use starknet::core::types::{DeclareTransactionResult, StarknetError};
16+
use starknet::core::types::{
17+
ContractExecutionError, DeclareTransactionResult, StarknetError, TransactionExecutionErrorData,
18+
};
1719
use starknet::providers::ProviderError;
1820
use starknet::{
1921
accounts::{Account, SingleOwnerAccount},
@@ -156,6 +158,21 @@ pub(crate) async fn declare_with_artifacts(
156158
class_hash: class_hash.into_(),
157159
}))
158160
}
161+
Err(Provider(ProviderError::StarknetError(StarknetError::TransactionExecutionError(
162+
TransactionExecutionErrorData {
163+
execution_error: ContractExecutionError::Message(message),
164+
..
165+
},
166+
)))) if message.contains("is already declared") && skip_on_already_declared => {
167+
Ok(DeclareResponse::AlreadyDeclared(AlreadyDeclaredResponse {
168+
class_hash: class_hash.into_(),
169+
}))
170+
}
171+
Err(Provider(ProviderError::StarknetError(StarknetError::TransactionExecutionError(
172+
TransactionExecutionErrorData { .. },
173+
)))) => Err(StarknetCommandError::ProviderError(
174+
SNCastProviderError::StarknetError(SNCastStarknetError::ClassAlreadyDeclared),
175+
)),
159176
Err(Provider(error)) => Err(StarknetCommandError::ProviderError(error.into())),
160177
Err(error) => Err(anyhow!(format!("Unexpected error occurred: {error}")).into()),
161178
}

crates/sncast/tests/e2e/declare.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ async fn test_contract_already_declared() {
244244
accounts_json_path.as_str(),
245245
"--account",
246246
"user1",
247+
"--wait",
247248
"declare",
248249
"--url",
249250
URL,
@@ -266,6 +267,47 @@ async fn test_contract_already_declared() {
266267
);
267268
}
268269

270+
#[tokio::test]
271+
async fn test_contract_already_declared_estimate_fee() {
272+
let contract_path = duplicate_contract_directory_with_salt(
273+
CONTRACTS_DIR.to_string() + "/map",
274+
"put",
275+
"74362345",
276+
);
277+
let tempdir = create_and_deploy_oz_account().await;
278+
join_tempdirs(&contract_path, &tempdir);
279+
280+
let args = vec![
281+
"--accounts-file",
282+
"accounts.json",
283+
"--account",
284+
"my_account",
285+
"--wait",
286+
"declare",
287+
"--url",
288+
URL,
289+
"--contract-name",
290+
"Map",
291+
];
292+
// Commented out because we explicitly do not want to set any resource bounds.
293+
// Transaction has to go through estimate fee endpoint first because it throws different errors
294+
// than the normal declare endpoint and we want to test them.
295+
// let args = apply_test_resource_bounds_flags(args);
296+
297+
runner(&args).current_dir(tempdir.path()).assert().success();
298+
299+
let snapbox = runner(&args).current_dir(tempdir.path());
300+
let output = snapbox.assert().success();
301+
302+
assert_stderr_contains(
303+
output,
304+
indoc! {r"
305+
Command: declare
306+
Error: Contract with the same class hash is already declared
307+
"},
308+
);
309+
}
310+
269311
#[tokio::test]
270312
async fn test_invalid_nonce() {
271313
let contract_path =

0 commit comments

Comments
 (0)