Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Commit eb70623

Browse files
committed
add option to skip nonce checking and add tests
1 parent 3c75978 commit eb70623

File tree

4 files changed

+69
-30
lines changed

4 files changed

+69
-30
lines changed

rpc_state_reader/src/lib.rs

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,15 @@ impl RpcState {
296296
)
297297
.unwrap();
298298

299-
Transaction::InvokeFunction(tx)
299+
// Note: we skip nonce checking because it can be increased twice in a single block
300+
// and it leads to a buggy behaviour when that's the case because the get_nonce_at method
301+
// returns a possibly higher nonce than the one we have in the transaction.
302+
// Example: Block contains 2 transactions that execute the same entrypoint with nonce=20.
303+
// - First tx has entrypoint with nonce=20
304+
// - Second tx has nonce=21
305+
// If we want to execute the first transaction the nonce check fails
306+
// since get_nonce_at for that block returns 21 and the first tx has 20.
307+
tx.create_for_simulation(false, false, false, false, true)
300308
}
301309

302310
_ => unimplemented!(),
@@ -864,13 +872,12 @@ mod transaction_tests {
864872
dbg!(&result.call_info.unwrap().internal_calls.len()); // Ok with explorer
865873
}
866874

867-
// tx_hash = 0x02e31c976f649ba05da82e4c6a054a9a41961adda4c3dea26e6b523f4f18b382
868-
// testnet
869-
// freeMint entrypoint
870-
// 6164000061640
871-
// 6191000061910
872-
// 0.004% difference
873-
// Link to explorer: https://testnet.starkscan.co/tx/0x02e31c976f649ba05da82e4c6a054a9a41961adda4c3dea26e6b523f4f18b382
875+
/// - Transaction Hash: 0x02e31c976f649ba05da82e4c6a054a9a41961adda4c3dea26e6b523f4f18b382
876+
/// - Network: testnet
877+
/// - Type: Invoke
878+
/// - Entrypoint: freeMint
879+
/// - Fee discrepancy: test=4940000049400, explorer=6191000061910, diff=25%
880+
/// - Link to explorer: https://testnet.starkscan.co/tx/0x02e31c976f649ba05da82e4c6a054a9a41961adda4c3dea26e6b523f4f18b382
874881
#[test]
875882
fn test_0x02e31c976f649ba05da82e4c6a054a9a41961adda4c3dea26e6b523f4f18b382() {
876883
let result = test_tx(
@@ -886,11 +893,12 @@ mod transaction_tests {
886893
dbg!(&result.call_info.unwrap().internal_calls.len()); // Ok with explorer
887894
}
888895

889-
/// tx: 0x26a1a5b5f2b3390302ade67c766cc94804fd41c86c5ee37e20c6415dc39358c
890-
/// Network: mainnet
891-
/// Fee: test=263050867669716, explorer=306031925226186, diff=16%
892-
/// Entrypoint evolve(game_id)
893-
/// Link to explorer: https://starkscan.co/tx/0x026a1a5b5f2b3390302ade67c766cc94804fd41c86c5ee37e20c6415dc39358c
896+
/// - Transaction Hash: 0x26a1a5b5f2b3390302ade67c766cc94804fd41c86c5ee37e20c6415dc39358c
897+
/// - Network: mainnet
898+
/// - Type: Invoke
899+
/// - Entrypoint: evolve(game_id)
900+
/// - Fee discrepancy: test=263050867669716, explorer=306031925226186, diff=16%
901+
/// - Link to explorer: https://starkscan.co/tx/0x026a1a5b5f2b3390302ade67c766cc94804fd41c86c5ee37e20c6415dc39358c
894902
#[test]
895903
fn test_0x26a1a5b5f2b3390302ade67c766cc94804fd41c86c5ee37e20c6415dc39358c() {
896904
let result = test_tx(
@@ -906,18 +914,19 @@ mod transaction_tests {
906914
dbg!(&result.call_info.unwrap().internal_calls.len()); // Ok with explorer
907915
}
908916

909-
#[test]
910-
fn test_0x00eef6ba6741da8769192fac9d28c6631cf66f9e7c4e880b886ef6a2e550e4e2() {
911-
let result = test_tx(
912-
"0x00eef6ba6741da8769192fac9d28c6631cf66f9e7c4e880b886ef6a2e550e4e2",
913-
RpcChain::MainNet,
914-
156105,
915-
18348936116,
916-
);
917-
918-
dbg!(&result.actual_resources);
919-
dbg!(&result.actual_fee); // test=6361070805216, explorer=47292465953700, diff=5888146145679 (0.13%)
920-
dbg!(&result.call_info.clone().unwrap().execution_resources); // Ok with explorer
921-
dbg!(&result.call_info.unwrap().internal_calls.len()); // Ok with explorer
922-
}
917+
// Fails because there is a problem with get_compiled_class_hash
918+
// #[test]
919+
// fn test_0x00eef6ba6741da8769192fac9d28c6631cf66f9e7c4e880b886ef6a2e550e4e2() {
920+
// let result = test_tx(
921+
// "0x00eef6ba6741da8769192fac9d28c6631cf66f9e7c4e880b886ef6a2e550e4e2",
922+
// RpcChain::MainNet,
923+
// 156105,
924+
// 18348936116,
925+
// );
926+
927+
// dbg!(&result.actual_resources);
928+
// dbg!(&result.actual_fee);
929+
// dbg!(&result.call_info.clone().unwrap().execution_resources);
930+
// dbg!(&result.call_info.unwrap().internal_calls.len());
931+
// }
923932
}

src/lib.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ pub fn simulate_transaction<S: StateReader>(
5959
skip_execute: bool,
6060
skip_fee_transfer: bool,
6161
ignore_max_fee: bool,
62+
skip_nonce_check: bool,
6263
) -> Result<Vec<TransactionExecutionInfo>, TransactionError> {
6364
let mut cache_state = CachedState::new(Arc::new(state), None, Some(HashMap::new()));
6465
let mut result = Vec::with_capacity(transactions.len());
@@ -68,6 +69,7 @@ pub fn simulate_transaction<S: StateReader>(
6869
skip_execute,
6970
skip_fee_transfer,
7071
ignore_max_fee,
72+
skip_nonce_check,
7173
);
7274
let tx_result =
7375
tx_for_simulation.execute(&mut cache_state, block_context, remaining_gas)?;
@@ -96,7 +98,7 @@ where
9698
// execute the transaction with the fake state.
9799

98100
// This is important, since we're interested in the fee estimation even if the account does not currently have sufficient funds.
99-
let tx_for_simulation = transaction.create_for_simulation(false, false, true, true);
101+
let tx_for_simulation = transaction.create_for_simulation(false, false, true, true, false);
100102

101103
let transaction_result =
102104
tx_for_simulation.execute(&mut cached_state, block_context, 100_000_000)?;
@@ -431,7 +433,7 @@ mod test {
431433

432434
let block_context = BlockContext::default();
433435
let Transaction::InvokeFunction(simul_invoke) =
434-
invoke.create_for_simulation(true, false, false, false) else {
436+
invoke.create_for_simulation(true, false, false, false, false) else {
435437
unreachable!()
436438
};
437439

@@ -558,6 +560,7 @@ mod test {
558560
true,
559561
true,
560562
false,
563+
false,
561564
)
562565
.unwrap();
563566

@@ -657,6 +660,7 @@ mod test {
657660
true,
658661
true,
659662
false,
663+
false,
660664
)
661665
.unwrap();
662666

@@ -699,6 +703,7 @@ mod test {
699703
false,
700704
false,
701705
false,
706+
false,
702707
)
703708
.unwrap();
704709
}
@@ -735,6 +740,7 @@ mod test {
735740
false,
736741
false,
737742
false,
743+
false,
738744
)
739745
.unwrap();
740746
}
@@ -795,6 +801,7 @@ mod test {
795801
false,
796802
false,
797803
false,
804+
false,
798805
)
799806
.unwrap();
800807
}
@@ -834,6 +841,7 @@ mod test {
834841
false,
835842
false,
836843
false,
844+
false,
837845
)
838846
.unwrap();
839847
}
@@ -878,6 +886,7 @@ mod test {
878886
false,
879887
true,
880888
false,
889+
false,
881890
)
882891
.unwrap();
883892
}
@@ -942,6 +951,7 @@ mod test {
942951
false,
943952
false,
944953
false, // won't have any effect
954+
false,
945955
)
946956
.unwrap();
947957
}
@@ -998,6 +1008,7 @@ mod test {
9981008
false,
9991009
false,
10001010
false,
1011+
false,
10011012
)
10021013
.unwrap();
10031014

src/transaction/invoke_function.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ pub struct InvokeFunction {
4545
skip_validation: bool,
4646
skip_execute: bool,
4747
skip_fee_transfer: bool,
48+
skip_nonce_check: bool,
4849
}
4950

5051
impl InvokeFunction {
@@ -115,6 +116,7 @@ impl InvokeFunction {
115116
skip_validation: false,
116117
skip_execute: false,
117118
skip_fee_transfer: false,
119+
skip_nonce_check: false,
118120
})
119121
}
120122

@@ -274,7 +276,9 @@ impl InvokeFunction {
274276
block_context: &BlockContext,
275277
remaining_gas: u128,
276278
) -> Result<TransactionExecutionInfo, TransactionError> {
277-
self.handle_nonce(state)?;
279+
if !self.skip_nonce_check {
280+
self.handle_nonce(state)?;
281+
}
278282
let mut tx_exec_info = self.apply(state, block_context, remaining_gas)?;
279283

280284
let mut tx_execution_context =
@@ -301,6 +305,7 @@ impl InvokeFunction {
301305
let contract_address = self.contract_address();
302306

303307
let current_nonce = state.get_nonce_at(contract_address)?;
308+
dbg!(&current_nonce);
304309
match &self.nonce {
305310
None => {
306311
// TODO: Remove this once we have a better way to handle the nonce.
@@ -327,11 +332,13 @@ impl InvokeFunction {
327332
skip_execute: bool,
328333
skip_fee_transfer: bool,
329334
ignore_max_fee: bool,
335+
skip_nonce_check: bool,
330336
) -> Transaction {
331337
let tx = InvokeFunction {
332338
skip_validation,
333339
skip_execute,
334340
skip_fee_transfer,
341+
skip_nonce_check,
335342
max_fee: if ignore_max_fee {
336343
u128::MAX
337344
} else {
@@ -424,6 +431,7 @@ mod tests {
424431
skip_validation: false,
425432
skip_execute: false,
426433
skip_fee_transfer: false,
434+
skip_nonce_check: false,
427435
};
428436

429437
// Instantiate CachedState
@@ -492,6 +500,7 @@ mod tests {
492500
skip_validation: false,
493501
skip_execute: false,
494502
skip_fee_transfer: false,
503+
skip_nonce_check: false,
495504
};
496505

497506
// Instantiate CachedState
@@ -556,6 +565,7 @@ mod tests {
556565
skip_validation: false,
557566
skip_execute: false,
558567
skip_fee_transfer: false,
568+
skip_nonce_check: false,
559569
};
560570

561571
// Instantiate CachedState
@@ -614,6 +624,7 @@ mod tests {
614624
skip_validation: false,
615625
skip_execute: false,
616626
skip_fee_transfer: false,
627+
skip_nonce_check: false,
617628
};
618629

619630
// Instantiate CachedState
@@ -678,6 +689,7 @@ mod tests {
678689
skip_validation: false,
679690
skip_execute: false,
680691
skip_fee_transfer: false,
692+
skip_nonce_check: false,
681693
};
682694

683695
// Instantiate CachedState
@@ -752,6 +764,7 @@ mod tests {
752764
skip_validation: false,
753765
skip_execute: false,
754766
skip_fee_transfer: false,
767+
skip_nonce_check: false,
755768
};
756769

757770
let mut state = CachedState::new(Arc::new(state_reader), None, None);
@@ -792,6 +805,7 @@ mod tests {
792805
skip_validation: false,
793806
skip_execute: false,
794807
skip_fee_transfer: true,
808+
skip_nonce_check: false,
795809
};
796810

797811
// Instantiate CachedState
@@ -849,6 +863,7 @@ mod tests {
849863
skip_validation: false,
850864
skip_execute: false,
851865
skip_fee_transfer: false,
866+
skip_nonce_check: false,
852867
};
853868

854869
// Instantiate CachedState
@@ -911,6 +926,7 @@ mod tests {
911926
skip_validation: false,
912927
skip_execute: false,
913928
skip_fee_transfer: false,
929+
skip_nonce_check: false,
914930
};
915931

916932
// Instantiate CachedState
@@ -1053,6 +1069,7 @@ mod tests {
10531069
skip_validation: true,
10541070
skip_execute: false,
10551071
skip_fee_transfer: true,
1072+
skip_nonce_check: false,
10561073
};
10571074

10581075
let mut state_reader = InMemoryStateReader::default();

src/transaction/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ impl Transaction {
9292
skip_execute: bool,
9393
skip_fee_transfer: bool,
9494
ignore_max_fee: bool,
95+
skip_nonce_check: bool,
9596
) -> Self {
9697
match self {
9798
Transaction::Declare(tx) => tx.create_for_simulation(
@@ -120,6 +121,7 @@ impl Transaction {
120121
skip_execute,
121122
skip_fee_transfer,
122123
ignore_max_fee,
124+
skip_nonce_check,
123125
),
124126
Transaction::L1Handler(tx) => tx.create_for_simulation(skip_validate, skip_execute),
125127
}

0 commit comments

Comments
 (0)