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

Commit 8e4af41

Browse files
committed
depl acc revert test
1 parent 1a5a917 commit 8e4af41

File tree

4 files changed

+185
-19
lines changed

4 files changed

+185
-19
lines changed

rpc_state_reader/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,7 @@ mod tests {
530530
rpc_state.get_transaction(tx_hash);
531531
}
532532

533+
#[ignore]
533534
#[test]
534535
fn test_get_block_info() {
535536
let rpc_state = RpcState::new(

src/transaction/deploy_account.rs

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
use super::fee::charge_fee;
1+
use super::fee::{calculate_tx_fee, charge_fee};
22
use super::{invoke_function::verify_no_calls_to_other_contracts, Transaction};
33
use crate::definitions::constants::QUERY_VERSION_BASE;
44
use crate::execution::execution_entry_point::ExecutionResult;
55
use crate::services::api::contract_classes::deprecated_contract_class::EntryPointType;
66
use crate::state::cached_state::CachedState;
7+
use crate::state::StateDiff;
78
use crate::{
89
core::{
910
errors::state_errors::StateError,
@@ -156,22 +157,46 @@ impl DeployAccount {
156157
block_context: &BlockContext,
157158
) -> Result<TransactionExecutionInfo, TransactionError> {
158159
self.handle_nonce(state)?;
159-
let mut tx_info = self.apply(state, block_context)?;
160+
161+
let mut transactional_state = state.create_transactional();
162+
let mut tx_exec_info = self.apply(&mut transactional_state, block_context)?;
163+
164+
let actual_fee = calculate_tx_fee(
165+
&tx_exec_info.actual_resources,
166+
block_context.starknet_os_config.gas_price,
167+
block_context,
168+
)?;
169+
170+
if let Some(revert_error) = tx_exec_info.revert_error.clone() {
171+
// execution error
172+
tx_exec_info = tx_exec_info.to_revert_error(&revert_error);
173+
} else if actual_fee > self.max_fee {
174+
// max_fee exceeded
175+
tx_exec_info = tx_exec_info.to_revert_error(
176+
format!(
177+
"Calculated fee ({}) exceeds max fee ({})",
178+
actual_fee, self.max_fee
179+
)
180+
.as_str(),
181+
);
182+
} else {
183+
state.apply_state_update(&StateDiff::from_cached_state(transactional_state)?)?;
184+
}
160185

161186
let mut tx_execution_context =
162187
self.get_execution_context(block_context.invoke_tx_max_n_steps);
163188
let (fee_transfer_info, actual_fee) = charge_fee(
164189
state,
165-
&tx_info.actual_resources,
190+
&tx_exec_info.actual_resources,
166191
block_context,
167192
self.max_fee,
168193
&mut tx_execution_context,
169194
self.skip_fee_transfer,
170195
)?;
171196

172-
tx_info.set_fee_info(actual_fee, fee_transfer_info);
197+
tx_exec_info.set_fee_info(actual_fee, fee_transfer_info);
173198

174-
Ok(tx_info)
199+
Ok(tx_exec_info)
175200
}
176201

177202
fn constructor_entry_points_empty(

src/transaction/invoke_function.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,6 @@ impl InvokeFunction {
315315
} else {
316316
state.apply_state_update(&StateDiff::from_cached_state(transactional_state)?)?;
317317
}
318-
// TODO: add balance not enough case.
319318

320319
let mut tx_execution_context =
321320
self.get_execution_context(block_context.invoke_tx_max_n_steps)?;

tests/internals.rs

Lines changed: 154 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,7 +1495,7 @@ fn test_invoke_with_declarev2_tx() {
14951495
fn test_deploy_account() {
14961496
let (block_context, mut state) = create_account_tx_test_state().unwrap();
14971497

1498-
let expected_fee = 6157;
1498+
let expected_fee = 3709;
14991499

15001500
let deploy_account_tx = DeployAccount::new(
15011501
felt_to_hash(&TEST_ACCOUNT_CONTRACT_CLASS_HASH),
@@ -1573,12 +1573,12 @@ fn test_deploy_account() {
15731573
("n_steps".to_string(), 3625),
15741574
("range_check_builtin".to_string(), 83),
15751575
("pedersen_builtin".to_string(), 23),
1576-
("l1_gas_usage".to_string(), 6120),
1576+
("l1_gas_usage".to_string(), 3672),
15771577
]);
15781578

15791579
let fee = calculate_tx_fee(&resources, *GAS_PRICE, &block_context).unwrap();
15801580

1581-
assert_eq!(fee, 6157);
1581+
assert_eq!(fee, 3709);
15821582

15831583
let expected_execution_info = TransactionExecutionInfo::new(
15841584
expected_validate_call_info.into(),
@@ -1608,11 +1608,161 @@ fn test_deploy_account() {
16081608
assert_eq!(class_hash_from_state, *deploy_account_tx.class_hash());
16091609
}
16101610

1611+
#[test]
1612+
fn test_deploy_account_revert() {
1613+
let (block_context, mut state) = create_account_tx_test_state().unwrap();
1614+
1615+
let expected_fee = 1;
1616+
1617+
let deploy_account_tx = DeployAccount::new(
1618+
felt_to_hash(&TEST_ACCOUNT_CONTRACT_CLASS_HASH),
1619+
1,
1620+
TRANSACTION_VERSION.clone(),
1621+
Default::default(),
1622+
Default::default(),
1623+
Default::default(),
1624+
Default::default(),
1625+
StarknetChainId::TestNet.to_felt(),
1626+
)
1627+
.unwrap();
1628+
1629+
state.set_storage_at(
1630+
&(
1631+
block_context
1632+
.starknet_os_config()
1633+
.fee_token_address()
1634+
.clone(),
1635+
felt_to_hash(&TEST_ERC20_DEPLOYED_ACCOUNT_BALANCE_KEY),
1636+
),
1637+
INITIAL_BALANCE.clone(),
1638+
);
1639+
1640+
let (mut state_before, mut state_after) = expected_deploy_account_states();
1641+
1642+
assert_eq!(&state.cache(), &state_before.cache());
1643+
assert_eq!(&state.contract_classes(), &state_before.contract_classes());
1644+
assert_eq!(
1645+
&state.casm_contract_classes(),
1646+
&state_before.casm_contract_classes()
1647+
);
1648+
1649+
let tx_info = deploy_account_tx
1650+
.execute(&mut state, &block_context)
1651+
.unwrap();
1652+
1653+
assert_eq!(
1654+
state.casm_contract_classes(),
1655+
state_before.casm_contract_classes()
1656+
);
1657+
1658+
let mut state_reverted = state_before.clone();
1659+
1660+
// Add initial writes (these 'bypass' the transactional state because it's a state reader and
1661+
// it will cache initial values when looking for them).
1662+
state_reverted
1663+
.cache_mut()
1664+
.class_hash_initial_values_mut()
1665+
.extend(
1666+
state_after
1667+
.cache_mut()
1668+
.class_hash_initial_values_mut()
1669+
.clone(),
1670+
);
1671+
state_reverted
1672+
.cache_mut()
1673+
.nonce_initial_values_mut()
1674+
.extend(state_after.cache_mut().nonce_initial_values_mut().clone());
1675+
state_reverted
1676+
.cache_mut()
1677+
.storage_initial_values_mut()
1678+
.extend(state_after.cache_mut().storage_initial_values_mut().clone());
1679+
state_reverted
1680+
.cache_mut()
1681+
.storage_initial_values_mut()
1682+
.extend(state_after.cache_mut().storage_initial_values_mut().clone());
1683+
1684+
// Set storage writes related to the fee transfer
1685+
state_reverted
1686+
.cache_mut()
1687+
.storage_writes_mut()
1688+
.extend(state_after.cache_mut().storage_writes().clone());
1689+
state_reverted.set_storage_at(
1690+
&(
1691+
Address(0x1001.into()),
1692+
felt_to_hash(&TEST_ERC20_DEPLOYED_ACCOUNT_BALANCE_KEY),
1693+
),
1694+
INITIAL_BALANCE.clone() - Felt252::one(), // minus the max fee that will be transfered
1695+
);
1696+
state_reverted.cache_mut().storage_writes_mut().insert(
1697+
(
1698+
Address(0x1001.into()),
1699+
felt_to_hash(&TEST_ERC20_SEQUENCER_BALANCE_KEY),
1700+
),
1701+
Felt252::one(), // the max fee received by the sequencer
1702+
);
1703+
1704+
// Set nonce
1705+
state_reverted
1706+
.cache_mut()
1707+
.nonce_writes_mut()
1708+
.extend(state_after.cache_mut().nonce_writes_mut().clone());
1709+
1710+
assert_eq!(state.cache(), state_reverted.cache());
1711+
1712+
let expected_fee_transfer_call_info = expected_fee_transfer_call_info(
1713+
&block_context,
1714+
deploy_account_tx.contract_address(),
1715+
expected_fee as u64,
1716+
);
1717+
1718+
let resources = HashMap::from([
1719+
("n_steps".to_string(), 3625),
1720+
("range_check_builtin".to_string(), 83),
1721+
("pedersen_builtin".to_string(), 23),
1722+
("l1_gas_usage".to_string(), 3672),
1723+
]);
1724+
1725+
let fee = calculate_tx_fee(&resources, *GAS_PRICE, &block_context).unwrap();
1726+
1727+
assert_eq!(fee, 3709);
1728+
1729+
let mut expected_execution_info = TransactionExecutionInfo::new(
1730+
None,
1731+
None,
1732+
None,
1733+
None,
1734+
expected_fee,
1735+
// Entry **not** in blockifier.
1736+
// Default::default(),
1737+
resources,
1738+
TransactionType::DeployAccount.into(),
1739+
)
1740+
.to_revert_error(format!("Calculated fee ({}) exceeds max fee ({})", 3709, 1).as_str());
1741+
1742+
expected_execution_info.set_fee_info(expected_fee, expected_fee_transfer_call_info.into());
1743+
1744+
assert_eq!(tx_info, expected_execution_info);
1745+
1746+
let nonce_from_state = state
1747+
.get_nonce_at(deploy_account_tx.contract_address())
1748+
.unwrap();
1749+
assert_eq!(nonce_from_state, Felt252::one());
1750+
1751+
let hash = TEST_ERC20_DEPLOYED_ACCOUNT_BALANCE_KEY.to_be_bytes();
1752+
1753+
validate_final_balances(&mut state, &block_context, &hash, expected_fee);
1754+
1755+
let class_hash_from_state = state
1756+
.get_class_hash_at(deploy_account_tx.contract_address())
1757+
.unwrap();
1758+
assert_eq!(class_hash_from_state, [0; 32]);
1759+
}
1760+
16111761
fn expected_deploy_account_states() -> (
16121762
CachedState<InMemoryStateReader>,
16131763
CachedState<InMemoryStateReader>,
16141764
) {
1615-
let fee = Felt252::from(6157);
1765+
let fee = Felt252::from(3709);
16161766
let mut state_before = CachedState::new(
16171767
Arc::new(InMemoryStateReader::new(
16181768
HashMap::from([
@@ -1671,15 +1821,6 @@ fn expected_deploy_account_states() -> (
16711821
.cache_mut()
16721822
.class_hash_initial_values_mut()
16731823
.insert(Address(0x1001.into()), felt_to_hash(&0x1010.into()));
1674-
state_after
1675-
.cache_mut()
1676-
.class_hash_initial_values_mut()
1677-
.insert(
1678-
Address(felt_str!(
1679-
"386181506763903095743576862849245034886954647214831045800703908858571591162"
1680-
)),
1681-
[0; 32],
1682-
);
16831824
state_after.cache_mut().storage_initial_values_mut().insert(
16841825
(
16851826
Address(0x1001.into()),

0 commit comments

Comments
 (0)