Skip to content

Commit a618cfd

Browse files
committed
Merge branch 'main' into custom-l1-price
2 parents d034439 + 9c66ac3 commit a618cfd

8 files changed

+226
-99
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "era_test_node"
3-
version = "0.1.0-alpha.21"
3+
version = "0.1.0-alpha.23"
44
edition = "2018"
55
authors = ["The Matter Labs Team <hello@matterlabs.dev>"]
66
homepage = "https://zksync.io/"

src/fork.rs

+111-48
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,12 @@ use zksync_web3_decl::{
3333
};
3434
use zksync_web3_decl::{namespaces::EthNamespaceClient, types::Index};
3535

36-
use crate::system_contracts;
3736
use crate::{cache::CacheConfig, node::TEST_NODE_NETWORK_ID};
3837
use crate::{deps::InMemoryStorage, http_fork_source::HttpForkSource};
38+
use crate::{
39+
node::{DEFAULT_ESTIMATE_GAS_PRICE_SCALE_FACTOR, DEFAULT_ESTIMATE_GAS_SCALE_FACTOR},
40+
system_contracts,
41+
};
3942

4043
pub fn block_on<F: Future + Send + 'static>(future: F) -> F::Output
4144
where
@@ -52,6 +55,40 @@ where
5255
.unwrap()
5356
}
5457

58+
/// The possible networks to fork from.
59+
#[derive(Debug, Clone)]
60+
pub enum ForkNetwork {
61+
Mainnet,
62+
SepoliaTestnet,
63+
GoerliTestnet,
64+
Other(String),
65+
}
66+
67+
impl ForkNetwork {
68+
/// Return the URL for the underlying fork source.
69+
pub fn to_url(&self) -> &str {
70+
match self {
71+
ForkNetwork::Mainnet => "https://mainnet.era.zksync.io:443",
72+
ForkNetwork::SepoliaTestnet => "https://sepolia.era.zksync.dev:443",
73+
ForkNetwork::GoerliTestnet => "https://testnet.era.zksync.dev:443",
74+
ForkNetwork::Other(url) => url,
75+
}
76+
}
77+
78+
/// Returns the local gas scale factors currently in use by the upstream network.
79+
pub fn local_gas_scale_factors(&self) -> (f64, f32) {
80+
match self {
81+
ForkNetwork::Mainnet => (1.5, 1.2),
82+
ForkNetwork::SepoliaTestnet => (2.0, 1.2),
83+
ForkNetwork::GoerliTestnet => (1.2, 1.2),
84+
ForkNetwork::Other(_) => (
85+
DEFAULT_ESTIMATE_GAS_PRICE_SCALE_FACTOR,
86+
DEFAULT_ESTIMATE_GAS_SCALE_FACTOR,
87+
),
88+
}
89+
}
90+
}
91+
5592
/// In memory storage, that allows 'forking' from other network.
5693
/// If forking is enabled, it reads missing data from remote location.
5794
/// S - is a struct that is used for source of the fork.
@@ -100,77 +137,77 @@ impl<S: ForkSource> ForkStorage<S> {
100137
}
101138
}
102139

103-
fn read_value_internal(&self, key: &StorageKey) -> zksync_types::StorageValue {
140+
pub fn read_value_internal(
141+
&self,
142+
key: &StorageKey,
143+
) -> eyre::Result<zksync_types::StorageValue> {
104144
let mut mutator = self.inner.write().unwrap();
105145
let local_storage = mutator.raw_storage.read_value(key);
106146

107147
if let Some(fork) = &mutator.fork {
108148
if !H256::is_zero(&local_storage) {
109-
return local_storage;
149+
return Ok(local_storage);
110150
}
111151

112152
if let Some(value) = mutator.value_read_cache.get(key) {
113-
return *value;
153+
return Ok(*value);
114154
}
115155
let l2_miniblock = fork.l2_miniblock;
116156
let key_ = *key;
117157

118-
let result = fork
119-
.fork_source
120-
.get_storage_at(
121-
*key_.account().address(),
122-
h256_to_u256(*key_.key()),
123-
Some(BlockIdVariant::BlockNumber(BlockNumber::Number(U64::from(
124-
l2_miniblock,
125-
)))),
126-
)
127-
.unwrap();
158+
let result = fork.fork_source.get_storage_at(
159+
*key_.account().address(),
160+
h256_to_u256(*key_.key()),
161+
Some(BlockIdVariant::BlockNumber(BlockNumber::Number(U64::from(
162+
l2_miniblock,
163+
)))),
164+
)?;
128165

129166
mutator.value_read_cache.insert(*key, result);
130-
result
167+
Ok(result)
131168
} else {
132-
local_storage
169+
Ok(local_storage)
133170
}
134171
}
135172

136-
fn load_factory_dep_internal(&self, hash: H256) -> Option<Vec<u8>> {
173+
pub fn load_factory_dep_internal(&self, hash: H256) -> eyre::Result<Option<Vec<u8>>> {
137174
let mut mutator = self.inner.write().unwrap();
138175
let local_storage = mutator.raw_storage.load_factory_dep(hash);
139176
if let Some(fork) = &mutator.fork {
140177
if local_storage.is_some() {
141-
return local_storage;
178+
return Ok(local_storage);
142179
}
143180
if let Some(value) = mutator.factory_dep_cache.get(&hash) {
144-
return value.clone();
181+
return Ok(value.clone());
145182
}
146183

147-
let result = fork.fork_source.get_bytecode_by_hash(hash).unwrap();
184+
let result = fork.fork_source.get_bytecode_by_hash(hash)?;
148185
mutator.factory_dep_cache.insert(hash, result.clone());
149-
result
186+
Ok(result)
150187
} else {
151-
local_storage
188+
Ok(local_storage)
152189
}
153190
}
154191

155192
/// Check if this is the first time when we're ever writing to this key.
156193
/// This has impact on amount of pubdata that we have to spend for the write.
157-
fn is_write_initial_internal(&self, key: &StorageKey) -> bool {
194+
pub fn is_write_initial_internal(&self, key: &StorageKey) -> eyre::Result<bool> {
158195
// Currently we don't have the zks API to return us the information on whether a given
159196
// key was written to before a given block.
160197
// This means, we have to depend on the following heuristic: we'll read the value of the slot.
161198
// - if value != 0 -> this means that the slot was written to in the past (so we can return intitial_write = false)
162199
// - but if the value = 0 - there is a chance, that slot was written to in the past - and later was reset.
163200
// but unfortunately we cannot detect that with the current zks api, so we'll attempt to do it
164201
// only on local storage.
165-
let value = self.read_value_internal(key);
202+
let value = self.read_value_internal(key)?;
166203
if value != H256::zero() {
167-
return false;
204+
return Ok(false);
168205
}
169206

170207
// If value was 0, there is still a chance, that the slot was written to in the past - and only now set to 0.
171208
// We unfortunately don't have the API to check it on the fork, but we can at least try to check it on local storage.
172209
let mut mutator = self.inner.write().unwrap();
173-
mutator.raw_storage.is_write_initial(key)
210+
Ok(mutator.raw_storage.is_write_initial(key))
174211
}
175212

176213
/// Retrieves the enumeration index for a given `key`.
@@ -182,15 +219,15 @@ impl<S: ForkSource> ForkStorage<S> {
182219

183220
impl<S: std::fmt::Debug + ForkSource> ReadStorage for ForkStorage<S> {
184221
fn is_write_initial(&mut self, key: &StorageKey) -> bool {
185-
self.is_write_initial_internal(key)
222+
self.is_write_initial_internal(key).unwrap()
186223
}
187224

188225
fn load_factory_dep(&mut self, hash: H256) -> Option<Vec<u8>> {
189-
self.load_factory_dep_internal(hash)
226+
self.load_factory_dep_internal(hash).unwrap()
190227
}
191228

192229
fn read_value(&mut self, key: &StorageKey) -> zksync_types::StorageValue {
193-
self.read_value_internal(key)
230+
self.read_value_internal(key).unwrap()
194231
}
195232

196233
fn get_enumeration_index(&mut self, key: &StorageKey) -> Option<u64> {
@@ -200,15 +237,15 @@ impl<S: std::fmt::Debug + ForkSource> ReadStorage for ForkStorage<S> {
200237

201238
impl<S: std::fmt::Debug + ForkSource> ReadStorage for &ForkStorage<S> {
202239
fn read_value(&mut self, key: &StorageKey) -> zksync_types::StorageValue {
203-
self.read_value_internal(key)
240+
self.read_value_internal(key).unwrap()
204241
}
205242

206243
fn is_write_initial(&mut self, key: &StorageKey) -> bool {
207-
self.is_write_initial_internal(key)
244+
self.is_write_initial_internal(key).unwrap()
208245
}
209246

210247
fn load_factory_dep(&mut self, hash: H256) -> Option<Vec<u8>> {
211-
self.load_factory_dep_internal(hash)
248+
self.load_factory_dep_internal(hash).unwrap()
212249
}
213250

214251
fn get_enumeration_index(&mut self, key: &StorageKey) -> Option<u64> {
@@ -321,6 +358,10 @@ pub struct ForkDetails<S> {
321358
pub overwrite_chain_id: Option<L2ChainId>,
322359
pub l1_gas_price: u64,
323360
pub l2_fair_gas_price: u64,
361+
/// L1 Gas Price Scale Factor for gas estimation.
362+
pub estimate_gas_price_scale_factor: f64,
363+
/// The factor by which to scale the gasLimit.
364+
pub estimate_gas_scale_factor: f32,
324365
}
325366

326367
const SUPPORTED_VERSIONS: &[ProtocolVersionId] = &[
@@ -356,13 +397,14 @@ pub fn supported_versions_to_string() -> String {
356397
}
357398

358399
impl ForkDetails<HttpForkSource> {
359-
pub async fn from_url_and_miniblock_and_chain(
360-
url: &str,
400+
pub async fn from_network_and_miniblock_and_chain(
401+
network: ForkNetwork,
361402
client: Client<L2>,
362403
miniblock: u64,
363404
chain_id: Option<L2ChainId>,
364405
cache_config: CacheConfig,
365406
) -> Self {
407+
let url = network.to_url();
366408
let block_details = client
367409
.get_block_details(L2BlockNumber(miniblock as u32))
368410
.await
@@ -402,6 +444,8 @@ impl ForkDetails<HttpForkSource> {
402444
);
403445
}
404446

447+
let (estimate_gas_price_scale_factor, estimate_gas_scale_factor) =
448+
network.local_gas_scale_factors();
405449
ForkDetails {
406450
fork_source: HttpForkSource::new(url.to_owned(), cache_config),
407451
l1_block: l1_batch_number,
@@ -412,23 +456,32 @@ impl ForkDetails<HttpForkSource> {
412456
overwrite_chain_id: chain_id,
413457
l1_gas_price: block_details.base.l1_gas_price,
414458
l2_fair_gas_price: block_details.base.l2_fair_gas_price,
459+
estimate_gas_price_scale_factor,
460+
estimate_gas_scale_factor,
415461
}
416462
}
417463
/// Create a fork from a given network at a given height.
418464
pub async fn from_network(fork: &str, fork_at: Option<u64>, cache_config: CacheConfig) -> Self {
419-
let (url, client) = Self::fork_to_url_and_client(fork);
465+
let (network, client) = Self::fork_network_and_client(fork);
420466
let l2_miniblock = if let Some(fork_at) = fork_at {
421467
fork_at
422468
} else {
423469
client.get_block_number().await.unwrap().as_u64()
424470
};
425-
Self::from_url_and_miniblock_and_chain(url, client, l2_miniblock, None, cache_config).await
471+
Self::from_network_and_miniblock_and_chain(
472+
network,
473+
client,
474+
l2_miniblock,
475+
None,
476+
cache_config,
477+
)
478+
.await
426479
}
427480

428481
/// Create a fork from a given network, at a height BEFORE a transaction.
429482
/// This will allow us to apply this transaction locally on top of this fork.
430483
pub async fn from_network_tx(fork: &str, tx: H256, cache_config: CacheConfig) -> Self {
431-
let (url, client) = Self::fork_to_url_and_client(fork);
484+
let (network, client) = Self::fork_network_and_client(fork);
432485
let tx_details = client.get_transaction_by_hash(tx).await.unwrap().unwrap();
433486
let overwrite_chain_id = Some(
434487
L2ChainId::try_from(tx_details.chain_id.as_u64()).unwrap_or_else(|err| {
@@ -439,8 +492,8 @@ impl ForkDetails<HttpForkSource> {
439492
// We have to sync to the one-miniblock before the one where transaction is.
440493
let l2_miniblock = miniblock_number.saturating_sub(1) as u64;
441494

442-
Self::from_url_and_miniblock_and_chain(
443-
url,
495+
Self::from_network_and_miniblock_and_chain(
496+
network,
444497
client,
445498
l2_miniblock,
446499
overwrite_chain_id,
@@ -451,22 +504,23 @@ impl ForkDetails<HttpForkSource> {
451504
}
452505

453506
impl<S: ForkSource> ForkDetails<S> {
454-
/// Return URL and HTTP client for a given fork name.
455-
pub fn fork_to_url_and_client(fork: &str) -> (&str, Client<L2>) {
456-
let url = match fork {
457-
"mainnet" => "https://mainnet.era.zksync.io:443",
458-
"sepolia-testnet" => "https://sepolia.era.zksync.dev:443",
459-
"goerli-testnet" => "https://testnet.era.zksync.dev:443",
460-
_ => fork,
507+
/// Return [`ForkNetwork`] and HTTP client for a given fork name.
508+
pub fn fork_network_and_client(fork: &str) -> (ForkNetwork, Client<L2>) {
509+
let network = match fork {
510+
"mainnet" => ForkNetwork::Mainnet,
511+
"sepolia-testnet" => ForkNetwork::SepoliaTestnet,
512+
"goerli-testnet" => ForkNetwork::GoerliTestnet,
513+
_ => ForkNetwork::Other(fork.to_string()),
461514
};
462515

516+
let url = network.to_url();
463517
let parsed_url = SensitiveUrl::from_str(url)
464518
.unwrap_or_else(|_| panic!("Unable to parse client URL: {}", &url));
465519
let client = Client::http(parsed_url)
466520
.unwrap_or_else(|_| panic!("Unable to create a client for fork: {}", &url))
467521
.build();
468522

469-
(url, client)
523+
(network, client)
470524
}
471525

472526
/// Returns transactions that are in the same L2 miniblock as replay_tx, but were executed before it.
@@ -508,7 +562,14 @@ mod tests {
508562
use zksync_state::ReadStorage;
509563
use zksync_types::{api::TransactionVariant, StorageKey};
510564

511-
use crate::{deps::InMemoryStorage, node::DEFAULT_L2_GAS_PRICE, system_contracts, testing};
565+
use crate::{
566+
deps::InMemoryStorage,
567+
node::{
568+
DEFAULT_ESTIMATE_GAS_PRICE_SCALE_FACTOR, DEFAULT_ESTIMATE_GAS_SCALE_FACTOR,
569+
DEFAULT_L2_GAS_PRICE,
570+
},
571+
system_contracts, testing,
572+
};
512573

513574
use super::{ForkDetails, ForkStorage};
514575

@@ -538,6 +599,8 @@ mod tests {
538599
overwrite_chain_id: None,
539600
l1_gas_price: 100,
540601
l2_fair_gas_price: DEFAULT_L2_GAS_PRICE,
602+
estimate_gas_price_scale_factor: DEFAULT_ESTIMATE_GAS_PRICE_SCALE_FACTOR,
603+
estimate_gas_scale_factor: DEFAULT_ESTIMATE_GAS_SCALE_FACTOR,
541604
};
542605

543606
let mut fork_storage = ForkStorage::new(Some(fork_details), &options);

0 commit comments

Comments
 (0)