Skip to content

Commit 961e664

Browse files
legion2002decofe
andcommitted
refactor(precompiles): read spec from storage context
Co-authored-by: Derek Cofausper <256792747+decofe@users.noreply.github.com>
1 parent 04aa0cf commit 961e664

7 files changed

Lines changed: 155 additions & 138 deletions

File tree

crates/precompiles/src/account_keychain.rs

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,24 @@
22
33
use alloy_primitives::Address;
44
use alloy_sol_types::SolInterface;
5-
use tempo_chainspec::hardfork::TempoHardfork;
65
use tempo_contracts::precompiles::IAccountKeychain;
76
use tempo_precompiles::dispatch::abi_decoder_config_for_spec;
87

98
use crate::{
109
execution::{CallCheck, CallRules},
1110
privacy::check_caller,
11+
storage::StorageCtx,
1212
};
1313

1414
/// Zone-specific rules applied before forwarding to upstream `AccountKeychain`.
1515
#[derive(Clone)]
1616
pub(crate) struct AccountKeychainRules;
1717

1818
impl CallRules for AccountKeychainRules {
19-
fn admit(&self, data: &[u8], caller: Address, spec: TempoHardfork) -> CallCheck {
19+
fn admit(&self, data: &[u8], caller: Address) -> CallCheck {
2020
let Ok(call) = IAccountKeychain::IAccountKeychainCalls::abi_decode_with_config(
2121
data,
22-
abi_decoder_config_for_spec(spec),
22+
abi_decoder_config_for_spec(StorageCtx::default().spec()),
2323
) else {
2424
// Preserve the upstream error and gas behavior for malformed or unknown calldata.
2525
return CallCheck::Continue;
@@ -64,13 +64,26 @@ mod tests {
6464
use super::*;
6565
use alloy_primitives::{Address, B256};
6666
use alloy_sol_types::{SolCall, SolError};
67+
use tempo_chainspec::hardfork::TempoHardfork;
6768
use tempo_zone_contracts::Unauthorized;
6869

6970
use crate::{
7071
storage::StorageCtx,
7172
test_utils::{test_context, test_storage_provider},
7273
};
7374

75+
fn admit_at(
76+
rules: &AccountKeychainRules,
77+
data: &[u8],
78+
caller: Address,
79+
spec: TempoHardfork,
80+
) -> CallCheck {
81+
let mut ctx = test_context();
82+
ctx.cfg.spec = spec;
83+
let mut storage = test_storage_provider(&mut ctx, u64::MAX, true);
84+
StorageCtx::enter(&mut storage, || rules.admit(data, caller))
85+
}
86+
7487
fn assert_account_scoped<C: SolCall + Clone>(
7588
rules: &AccountKeychainRules,
7689
call: C,
@@ -79,12 +92,12 @@ mod tests {
7992
outsider: Address,
8093
) {
8194
assert!(matches!(
82-
rules.admit(&call.abi_encode(), owner, TempoHardfork::T8),
95+
rules.admit(&call.abi_encode(), owner),
8396
CallCheck::Continue
8497
));
8598
for caller in [sequencer, outsider] {
8699
assert!(matches!(
87-
rules.admit(&call.clone().abi_encode(), caller, TempoHardfork::T8),
100+
rules.admit(&call.clone().abi_encode(), caller),
88101
CallCheck::Revert(data) if data == Unauthorized {}.abi_encode()
89102
));
90103
}
@@ -172,25 +185,27 @@ mod tests {
172185
let caller = Address::repeat_byte(0x11);
173186
let rules = AccountKeychainRules;
174187

175-
assert!(matches!(
176-
rules.admit(
177-
&IAccountKeychain::getTransactionKeyCall {}.abi_encode(),
178-
caller,
179-
TempoHardfork::T8,
180-
),
181-
CallCheck::Continue
182-
));
183-
assert!(matches!(
184-
rules.admit(
185-
&IAccountKeychain::revokeKeyCall {
186-
keyId: Address::repeat_byte(0x22),
187-
}
188-
.abi_encode(),
189-
caller,
190-
TempoHardfork::T8,
191-
),
192-
CallCheck::Continue
193-
));
188+
let mut ctx = test_context();
189+
let mut storage = test_storage_provider(&mut ctx, u64::MAX, true);
190+
StorageCtx::enter(&mut storage, || {
191+
assert!(matches!(
192+
rules.admit(
193+
&IAccountKeychain::getTransactionKeyCall {}.abi_encode(),
194+
caller,
195+
),
196+
CallCheck::Continue
197+
));
198+
assert!(matches!(
199+
rules.admit(
200+
&IAccountKeychain::revokeKeyCall {
201+
keyId: Address::repeat_byte(0x22),
202+
}
203+
.abi_encode(),
204+
caller,
205+
),
206+
CallCheck::Continue
207+
));
208+
});
194209
}
195210

196211
#[test]
@@ -206,11 +221,11 @@ mod tests {
206221
data[4] = 1;
207222

208223
assert!(matches!(
209-
rules.admit(&data, outsider, TempoHardfork::T8),
224+
admit_at(&rules, &data, outsider, TempoHardfork::T8),
210225
CallCheck::Revert(data) if data == Unauthorized {}.abi_encode()
211226
));
212227
assert!(matches!(
213-
rules.admit(&data, outsider, TempoHardfork::T11),
228+
admit_at(&rules, &data, outsider, TempoHardfork::T11),
214229
CallCheck::Continue
215230
));
216231
}

crates/precompiles/src/execution.rs

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ pub(crate) trait CallRules: 'static {
8888
None
8989
}
9090

91-
/// Applies Zone-specific admission rules using the active Tempo hardfork.
92-
fn admit(&self, _data: &[u8], _caller: Address, _spec: TempoHardfork) -> CallCheck {
91+
/// Applies Zone-specific admission rules.
92+
fn admit(&self, _data: &[u8], _caller: Address) -> CallCheck {
9393
CallCheck::Continue
9494
}
9595
}
@@ -153,19 +153,17 @@ pub(crate) fn create_precompile(
153153
storage.set_tip1060_storage_credits(false);
154154
}
155155

156-
let mut result = StorageCtx::enter(&mut storage, || {
157-
match rules.admit(data, caller, env.cfg.spec) {
158-
CallCheck::Continue => execute(data, caller),
159-
CallCheck::Revert(output) => {
160-
let s = StorageCtx::default();
161-
let output = s.revert_output(output);
162-
add_input_cost(s, data, Ok(output))
163-
}
164-
CallCheck::Error(error) => {
165-
let s = StorageCtx::default();
166-
let result = s.error_result(error);
167-
add_input_cost(s, data, result)
168-
}
156+
let mut result = StorageCtx::enter(&mut storage, || match rules.admit(data, caller) {
157+
CallCheck::Continue => execute(data, caller),
158+
CallCheck::Revert(output) => {
159+
let s = StorageCtx::default();
160+
let output = s.revert_output(output);
161+
add_input_cost(s, data, Ok(output))
162+
}
163+
CallCheck::Error(error) => {
164+
let s = StorageCtx::default();
165+
let result = s.error_result(error);
166+
add_input_cost(s, data, result)
169167
}
170168
});
171169
if let (Ok(output), Some(gas)) = (&mut result, fixed_gas) {
@@ -215,7 +213,7 @@ mod tests {
215213
Some(FIXED_GAS)
216214
}
217215

218-
fn admit(&self, data: &[u8], caller: Address, _spec: TempoHardfork) -> CallCheck {
216+
fn admit(&self, data: &[u8], caller: Address) -> CallCheck {
219217
*self.0.borrow_mut() = Some((
220218
Bytes::copy_from_slice(data),
221219
selector_from_calldata(data),
@@ -379,7 +377,7 @@ mod tests {
379377
Some(FIXED_GAS)
380378
}
381379

382-
fn admit(&self, _data: &[u8], _caller: Address, _spec: TempoHardfork) -> CallCheck {
380+
fn admit(&self, _data: &[u8], _caller: Address) -> CallCheck {
383381
self.0.set(true);
384382
CallCheck::Revert(Bytes::from_static(b"denied"))
385383
}
@@ -463,7 +461,7 @@ mod tests {
463461
struct FatalRules;
464462

465463
impl CallRules for FatalRules {
466-
fn admit(&self, _data: &[u8], _caller: Address, _spec: TempoHardfork) -> CallCheck {
464+
fn admit(&self, _data: &[u8], _caller: Address) -> CallCheck {
467465
StorageCtx::default().deduct_gas(10).unwrap();
468466
CallCheck::Error(TempoPrecompileError::Fatal("boom".into()))
469467
}

crates/precompiles/src/nonce.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,25 @@
22
33
use alloy_primitives::Address;
44
use alloy_sol_types::SolInterface;
5-
use tempo_chainspec::hardfork::TempoHardfork;
65
use tempo_contracts::precompiles::INonce;
76
use tempo_precompiles::dispatch::abi_decoder_config_for_spec;
87

98
use crate::{
109
execution::{CallCheck, CallRules},
1110
privacy::check_caller,
11+
storage::StorageCtx,
1212
};
1313

1414
/// Zone-specific rules applied before forwarding to upstream `NonceManager`.
1515
#[derive(Clone)]
1616
pub(crate) struct NonceRules;
1717

1818
impl CallRules for NonceRules {
19-
fn admit(&self, data: &[u8], caller: Address, spec: TempoHardfork) -> CallCheck {
20-
let Ok(call) =
21-
INonce::INonceCalls::abi_decode_with_config(data, abi_decoder_config_for_spec(spec))
22-
else {
19+
fn admit(&self, data: &[u8], caller: Address) -> CallCheck {
20+
let Ok(call) = INonce::INonceCalls::abi_decode_with_config(
21+
data,
22+
abi_decoder_config_for_spec(StorageCtx::default().spec()),
23+
) else {
2324
// Preserve the upstream error and gas behavior for malformed or unknown calldata.
2425
return CallCheck::Continue;
2526
};
@@ -36,13 +37,21 @@ mod tests {
3637
use super::*;
3738
use alloy_primitives::{Address, U256};
3839
use alloy_sol_types::{SolCall, SolError};
40+
use tempo_chainspec::hardfork::TempoHardfork;
3941
use tempo_zone_contracts::Unauthorized;
4042

4143
use crate::{
4244
storage::StorageCtx,
4345
test_utils::{test_context, test_storage_provider},
4446
};
4547

48+
fn admit_at(data: &[u8], caller: Address, spec: TempoHardfork) -> CallCheck {
49+
let mut ctx = test_context();
50+
ctx.cfg.spec = spec;
51+
let mut storage = test_storage_provider(&mut ctx, u64::MAX, true);
52+
StorageCtx::enter(&mut storage, || NonceRules.admit(data, caller))
53+
}
54+
4655
#[test]
4756
fn nonce_reads_allow_only_owner() {
4857
let owner = Address::repeat_byte(0x11);
@@ -59,12 +68,12 @@ mod tests {
5968

6069
StorageCtx::enter(&mut storage, || {
6170
assert!(matches!(
62-
rules.admit(&call.abi_encode(), owner, TempoHardfork::T8),
71+
rules.admit(&call.abi_encode(), owner),
6372
CallCheck::Continue
6473
));
6574
for caller in [sequencer, outsider, intermediary] {
6675
assert!(matches!(
67-
rules.admit(&call.abi_encode(), caller, TempoHardfork::T8),
76+
rules.admit(&call.abi_encode(), caller),
6877
CallCheck::Revert(data) if data == Unauthorized {}.abi_encode()
6978
));
7079
}
@@ -75,7 +84,6 @@ mod tests {
7584
fn t11_defers_noncanonical_address_calldata_to_upstream() {
7685
let owner = Address::repeat_byte(0x11);
7786
let outsider = Address::repeat_byte(0x22);
78-
let rules = NonceRules;
7987
let mut data = INonce::getNonceCall {
8088
account: owner,
8189
nonceKey: U256::from(1),
@@ -84,11 +92,11 @@ mod tests {
8492
data[4] = 1;
8593

8694
assert!(matches!(
87-
rules.admit(&data, outsider, TempoHardfork::T8),
95+
admit_at(&data, outsider, TempoHardfork::T8),
8896
CallCheck::Revert(data) if data == Unauthorized {}.abi_encode()
8997
));
9098
assert!(matches!(
91-
rules.admit(&data, outsider, TempoHardfork::T11),
99+
admit_at(&data, outsider, TempoHardfork::T11),
92100
CallCheck::Continue
93101
));
94102
}

0 commit comments

Comments
 (0)