Skip to content

Commit b6f2250

Browse files
tkumor3THenry14
andauthored
1336 set proper nonce (#1500)
<!-- Reference any GitHub issues resolved by this PR --> Closes # ## Introduced changes Change the way of getting nonce. Instead of obtaining it from the latest block, it gets it from the pending. map_script test from `crates/sncast/tests/e2e/script/general.rs` cover this changes ## Checklist <!-- Make sure all of these are complete --> - [x] Linked relevant issue - [x] Updated relevant documentation - [x] Added relevant tests - [x] Performed self-review of the code - [x] Added changes to `CHANGELOG.md` --------- Co-authored-by: Wojciech Szymczyk <[email protected]>
1 parent 240bd5e commit b6f2250

File tree

8 files changed

+33
-13
lines changed

8 files changed

+33
-13
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2222

2323
- Error message for tests that should panic but pass
2424

25+
### Cast
26+
27+
#### Changed
28+
29+
- the 'pending' block is used instead of 'latest' as the default when obtaining the nonce
30+
2531
## [0.14.0] - 2024-01-11
2632

2733
### Forge

crates/sncast/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,13 @@ pub async fn get_account<'a>(
168168
keystore: Option<Utf8PathBuf>,
169169
) -> Result<SingleOwnerAccount<&'a JsonRpcClient<HttpTransport>, LocalWallet>> {
170170
let chain_id = get_chain_id(provider).await?;
171-
let account = if let Some(keystore) = keystore {
171+
let mut account = if let Some(keystore) = keystore {
172172
get_account_from_keystore(provider, chain_id, &keystore, account)?
173173
} else {
174174
get_account_from_accounts_file(account, accounts_file, provider, chain_id)?
175175
};
176-
Ok(account)
176+
177+
Ok(account.set_block_id(get_block_id("pending")?).clone())
177178
}
178179

179180
fn get_account_from_keystore<'a>(

crates/sncast/src/starknet_commands/declare.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ use anyhow::{anyhow, Context, Result};
22
use camino::Utf8PathBuf;
33
use clap::Args;
44
use scarb_api::{get_contracts_map, ScarbCommand};
5+
56
use sncast::helpers::scarb_utils::get_package_metadata;
67
use sncast::helpers::scarb_utils::get_scarb_manifest;
78
use sncast::response::structs::DeclareResponse;
89
use sncast::response::structs::Hex;
910
use sncast::{apply_optional, handle_rpc_error, handle_wait_for_tx, WaitForTx};
1011
use starknet::accounts::AccountError::Provider;
1112
use starknet::accounts::{ConnectedAccount, Declaration};
13+
1214
use starknet::core::types::FieldElement;
1315
use starknet::{
1416
accounts::{Account, SingleOwnerAccount},
@@ -83,10 +85,10 @@ pub async fn declare(
8385
let casm_class_hash = casm_contract_definition.class_hash()?;
8486

8587
let declaration = account.declare(Arc::new(contract_definition.flatten()?), casm_class_hash);
88+
8689
let declaration = apply_optional(declaration, max_fee, Declaration::max_fee);
8790
let declaration = apply_optional(declaration, nonce, Declaration::nonce);
8891
let declared = declaration.send().await;
89-
9092
match declared {
9193
Ok(result) => {
9294
handle_wait_for_tx(

crates/sncast/src/starknet_commands/deploy.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,21 @@ pub async fn deploy(
5353
wait_config: WaitForTx,
5454
) -> Result<DeployResponse> {
5555
let salt = extract_or_generate_salt(salt);
56-
5756
let factory = ContractFactory::new(class_hash, account);
58-
let deployment = factory.deploy(constructor_calldata.clone(), salt, unique);
57+
let execution = factory.deploy(constructor_calldata.clone(), salt, unique);
5958

6059
// TODO(#1396): use apply_optional here when `Deployment` in starknet-rs is public
6160
// otherwise we cannot pass the necessary reference to a function
62-
let execution_with_fee = if let Some(max_fee) = max_fee {
63-
deployment.max_fee(max_fee)
61+
let execution = if let Some(max_fee) = max_fee {
62+
execution.max_fee(max_fee)
6463
} else {
65-
deployment
64+
execution
6665
};
6766

6867
let execution = if let Some(nonce) = nonce {
69-
execution_with_fee.nonce(nonce)
68+
execution.nonce(nonce)
7069
} else {
71-
execution_with_fee
70+
execution
7271
};
7372

7473
let result = execution.send().await;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
SingleOwnerAccount { provider: JsonRpcClient { transport: HttpTransport { client: Client { accepts: Accepts, proxies: [Proxy(System({}), None)], referer: true, default_headers: {"accept": "*/*"} }, url: Url { scheme: "http", cannot_be_a_base: false, username: "", password: None, host: Some(Ipv4(127.0.0.1)), port: Some(5055), path: "/rpc", query: None, fragment: None } } }, signer: LocalWallet { private_key: SigningKey { secret_scalar: FieldElement { inner: 0x00000000000000000000000000000000ffd33878eed7767e7c546ce3fc026295 } } }, address: FieldElement { inner: 0x00f6ecd22832b7c3713cfa7826ee309ce96a2769833f093795fafa1b8f20c48b }, chain_id: FieldElement { inner: 0x0000000000000000000000000000000000000000000000534e5f474f45524c49 }, block_id: Tag(Latest), encoding: Legacy }
1+
SingleOwnerAccount { provider: JsonRpcClient { transport: HttpTransport { client: Client { accepts: Accepts, proxies: [Proxy(System({}), None)], referer: true, default_headers: {"accept": "*/*"} }, url: Url { scheme: "http", cannot_be_a_base: false, username: "", password: None, host: Some(Ipv4(127.0.0.1)), port: Some(5055), path: "/rpc", query: None, fragment: None } } }, signer: LocalWallet { private_key: SigningKey { secret_scalar: FieldElement { inner: 0x00000000000000000000000000000000ffd33878eed7767e7c546ce3fc026295 } } }, address: FieldElement { inner: 0x00f6ecd22832b7c3713cfa7826ee309ce96a2769833f093795fafa1b8f20c48b }, chain_id: FieldElement { inner: 0x0000000000000000000000000000000000000000000000534e5f474f45524c49 }, block_id: Tag(Pending), encoding: Legacy }

crates/sncast/tests/data/scripts/map_script/scripts/src/map_script.cairo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ fn main() {
3131
let declare_result = declare('Mapa', Option::Some(max_fee), Option::Some(declare_nonce));
3232

3333
let class_hash = declare_result.class_hash;
34-
let deploy_nonce = get_nonce('latest');
34+
let deploy_nonce = get_nonce('pending');
3535
let deploy_result = deploy(
3636
class_hash,
3737
ArrayTrait::new(),

crates/sncast/tests/integration/wait_for_tx.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ async fn test_rejected_transaction() {
4747
.deploy(Vec::new(), FieldElement::ONE, false)
4848
.max_fee(FieldElement::ONE);
4949
let resp = deployment.send().await.unwrap_err();
50-
dbg!(&resp);
5150

5251
assert!(resp.to_string().contains("InsufficientMaxFee"));
5352
}

docs/src/starknet/script.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,19 @@ have a `main` function in the module you want to run. `cast_std` docs can be fou
1313
Please note that **`sncast script` is in development**. While it is already possible to declare, deploy, invoke and call
1414
contracts from within Cairo, its interface, internals and feature set can change rapidly each version.
1515

16+
> ⚠️⚠️ By default, the nonce for each transaction is being taken from the pending block ⚠️⚠️
17+
>
18+
> Some RPC nodes can be configured with higher poll itervals, which means they may return "older" nonces
19+
> in pending blocks, or even not be able to obtain pending blocks at all. When running a script you get an error like
20+
> "Invalid transaction nonce", this might be the case and you may need to manually set both nonce and max_fee for
21+
> transactions.
22+
>
23+
> Example:
24+
>
25+
>```cairo
26+
> let declare_result = declare('Map', Option::Some(max_fee), Option::Some(nonce));
27+
>```
28+
1629
Some of the planned features that will be included in future versions are:
1730
1831
- scripts idempotency

0 commit comments

Comments
 (0)