Skip to content

Commit

Permalink
Merge pull request matter-labs#2 from zkLinkProtocol/add-linea-estima…
Browse files Browse the repository at this point in the history
…te-gas

Add linea estimate gas
  • Loading branch information
zkcarter authored Mar 7, 2024
2 parents fb2441a + 06eed9b commit d072302
Show file tree
Hide file tree
Showing 11 changed files with 98 additions and 35 deletions.
12 changes: 8 additions & 4 deletions core/lib/eth_client/src/clients/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ use zksync_types::{
contract::Options,
ethabi,
types::{
Address, Block, BlockId, BlockNumber, Filter, Log, Transaction, TransactionReceipt,
H160, H256, U256, U64,
Address, Block, BlockId, BlockNumber, CallRequest, Filter, Log, Transaction,
TransactionReceipt, H160, H256, U256, U64,
},
},
L1ChainId,
};

use crate::{
BoundEthInterface, ContractCall, Error, EthInterface, ExecutedTxStatus, FailureInfo,
RawTransactionBytes, SignedCallResult,
clients::LineaEstimateGas, BoundEthInterface, ContractCall, Error, EthInterface,
ExecutedTxStatus, FailureInfo, RawTransactionBytes, SignedCallResult,
};

#[async_trait]
Expand Down Expand Up @@ -63,6 +63,10 @@ impl<C: EthInterface + ?Sized> EthInterface for Arc<C> {
self.as_ref().send_raw_tx(tx).await
}

async fn linea_estimate_gas(&self, req: CallRequest) -> Result<LineaEstimateGas, Error> {
self.as_ref().linea_estimate_gas(req).await
}

async fn get_tx_status(
&self,
hash: H256,
Expand Down
1 change: 1 addition & 0 deletions core/lib/eth_client/src/clients/http/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ enum Method {
BlockNumber,
GetGasPrice,
SendRawTx,
EstimateGas,
BaseFeeHistory,
#[metrics(name = "get_pending_block_base_fee_per_gas")]
PendingBlockBaseFee,
Expand Down
28 changes: 23 additions & 5 deletions core/lib/eth_client/src/clients/http/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@ use async_trait::async_trait;
use zksync_types::web3::{
self,
contract::Contract,
ethabi,
ethabi, helpers,
helpers::CallFuture,
transports::Http,
types::{
Address, Block, BlockId, BlockNumber, Bytes, Filter, Log, Transaction, TransactionId,
TransactionReceipt, H256, U256, U64,
Address, Block, BlockId, BlockNumber, Bytes, CallRequest, Filter, Log, Transaction,
TransactionId, TransactionReceipt, H256, U256, U64,
},
Web3,
Transport, Web3,
};

use crate::{
clients::http::{Method, COUNTERS, LATENCIES},
clients::{
http::{Method, COUNTERS, LATENCIES},
LineaEstimateGas,
},
types::{Error, ExecutedTxStatus, FailureInfo, RawTokens},
ContractCall, EthInterface, RawTransactionBytes,
};
Expand Down Expand Up @@ -288,4 +292,18 @@ impl EthInterface for QueryClient {
latency.observe();
Ok(block)
}

async fn linea_estimate_gas(&self, req: CallRequest) -> Result<LineaEstimateGas, Error> {
let latency = LATENCIES.direct[&Method::EstimateGas].start();
let req = helpers::serialize(&req);

let res = CallFuture::new(
self.web3
.transport()
.execute("linea_estimateGas", vec![req]),
)
.await?;
latency.observe();
Ok(res)
}
}
9 changes: 7 additions & 2 deletions core/lib/eth_client/src/clients/http/signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@ use zksync_types::{
ethabi,
transports::Http,
types::{
Address, Block, BlockId, BlockNumber, Filter, Log, Transaction, TransactionReceipt,
H160, H256, U256, U64,
Address, Block, BlockId, BlockNumber, CallRequest, Filter, Log, Transaction,
TransactionReceipt, H160, H256, U256, U64,
},
},
L1ChainId, PackedEthSignature, EIP_1559_TX_TYPE,
};

use super::{query::QueryClient, Method, LATENCIES};
use crate::{
clients::LineaEstimateGas,
types::{Error, ExecutedTxStatus, FailureInfo, SignedCallResult},
BoundEthInterface, CallFunctionArgs, ContractCall, EthInterface, RawTransactionBytes,
};
Expand Down Expand Up @@ -192,6 +193,10 @@ impl<S: EthereumSigner> EthInterface for SigningClient<S> {
) -> Result<Option<Block<H256>>, Error> {
self.query_client.block(block_id, component).await
}

async fn linea_estimate_gas(&self, req: CallRequest) -> Result<LineaEstimateGas, Error> {
self.query_client.linea_estimate_gas(req).await
}
}

#[async_trait]
Expand Down
10 changes: 9 additions & 1 deletion core/lib/eth_client/src/clients/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@ use zksync_types::{
web3::{
contract::{tokens::Tokenize, Options},
ethabi,
types::{Block, BlockId, BlockNumber, Filter, Log, Transaction, TransactionReceipt, U64},
types::{
Block, BlockId, BlockNumber, CallRequest, Filter, Log, Transaction, TransactionReceipt,
U64,
},
Error as Web3Error,
},
Address, L1ChainId, ProtocolVersionId, H160, H256, U256,
};

use crate::{
clients::LineaEstimateGas,
types::{Error, ExecutedTxStatus, FailureInfo, SignedCallResult},
BoundEthInterface, ContractCall, EthInterface, RawTransactionBytes,
};
Expand Down Expand Up @@ -364,6 +368,10 @@ impl EthInterface for MockEthereum {
) -> Result<Option<Block<H256>>, Error> {
unimplemented!("Not needed right now")
}

async fn linea_estimate_gas(&self, _req: CallRequest) -> Result<LineaEstimateGas, Error> {
unimplemented!("Not needed right now")
}
}

#[async_trait::async_trait]
Expand Down
10 changes: 10 additions & 0 deletions core/lib/eth_client/src/clients/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,17 @@ mod generic;
mod http;
mod mock;

use serde::{Deserialize, Serialize};
use zksync_types::H256;

pub use self::{
http::{PKSigningClient, QueryClient, SigningClient},
mock::MockEthereum,
};

#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize)]
pub struct LineaEstimateGas {
pub base_fee_per_gas: H256,
pub gas_limit: H256,
pub priority_fee_per_gas: H256,
}
8 changes: 6 additions & 2 deletions core/lib/eth_client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ use zksync_types::{
contract::Options,
ethabi,
types::{
Address, Block, BlockId, BlockNumber, Filter, Log, Transaction, TransactionReceipt,
H160, H256, U256, U64,
Address, Block, BlockId, BlockNumber, CallRequest, Filter, Log, Transaction,
TransactionReceipt, H160, H256, U256, U64,
},
},
L1ChainId,
};

use crate::clients::LineaEstimateGas;
pub use crate::types::{
CallFunctionArgs, ContractCall, Error, ExecutedTxStatus, FailureInfo, RawTransactionBytes,
SignedCallResult,
Expand Down Expand Up @@ -73,6 +74,9 @@ pub trait EthInterface: 'static + Sync + Send + fmt::Debug {
/// Sends a transaction to the Ethereum network.
async fn send_raw_tx(&self, tx: RawTransactionBytes) -> Result<H256, Error>;

/// Call a contract without changing the state of the blockchain to estimate gas usage.
async fn linea_estimate_gas(&self, req: CallRequest) -> Result<LineaEstimateGas, Error>;

/// Fetches the transaction status for a specified transaction hash.
///
/// Returns `Ok(None)` if the transaction is either not found or not executed yet.
Expand Down
12 changes: 2 additions & 10 deletions core/lib/zksync_core/src/eth_sender/eth_tx_aggregator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,8 @@ impl EthTxAggregator {
.save_eth_tx(storage, &agg_op, contracts_are_pre_boojum)
.await?;
Self::report_eth_tx_saving(storage, agg_op, &tx).await;
} else {
tracing::info!("Waiting for batches synced......");
}
}
Ok(())
Expand All @@ -376,16 +378,6 @@ impl EthTxAggregator {
let is_batches_synced = &*self.functions.is_batches_synced.name;

let params = op.get_eth_tx_args().pop().unwrap();
tracing::info!(
"is_batches_synced: {:?}",
hex::encode(
self.functions
.is_batches_synced
.encode_input(&op.get_eth_tx_args())
.unwrap()
)
);

let args = CallFunctionArgs::new(is_batches_synced, params).for_contract(
self.main_zksync_contract_address,
self.functions.zksync_contract.clone(),
Expand Down
32 changes: 26 additions & 6 deletions core/lib/zksync_core/src/eth_sender/eth_tx_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use tokio::sync::watch;
use zksync_config::configs::eth_sender::SenderConfig;
use zksync_dal::{ConnectionPool, StorageProcessor};
use zksync_eth_client::{
BoundEthInterface, Error, ExecutedTxStatus, RawTransactionBytes, SignedCallResult,
BoundEthInterface, Error, EthInterface, ExecutedTxStatus, RawTransactionBytes, SignedCallResult,
};
use zksync_types::{
eth_sender::EthTx,
Expand All @@ -14,7 +14,7 @@ use zksync_types::{
error::Error as Web3Error,
types::{BlockId, BlockNumber},
},
L1BlockNumber, Nonce, H256, U256,
L1BlockNumber, L1ChainId, Nonce, H256, U256,
};
use zksync_utils::time::seconds_since_epoch;

Expand Down Expand Up @@ -186,10 +186,30 @@ impl EthTxManager {
time_in_mempool: u32,
current_block: L1BlockNumber,
) -> Result<H256, ETHSenderError> {
let EthFee {
base_fee_per_gas,
priority_fee_per_gas,
} = self.calculate_fee(storage, tx, time_in_mempool).await?;
const LINEA_TEST_CHAIN_ID: L1ChainId = L1ChainId::from(59140);
const LINEA_MAINNET_CHAIN_ID: L1ChainId = L1ChainId::from(59144);
let current_gate_way_chain_id = self.ethereum_gateway.chain_id();
let (base_fee_per_gas, priority_fee_per_gas) = if current_gate_way_chain_id
== LINEA_TEST_CHAIN_ID
|| current_gate_way_chain_id == LINEA_MAINNET_CHAIN_ID
{
let call_request = zksync_types::web3::types::CallRequest::builder()
.from(self.ethereum_gateway.sender_account())
.to(tx.contract_address)
.data(tx.raw_tx.clone().into())
.build();
let fee = self
.ethereum_gateway
.linea_estimate_gas(call_request)
.await?;
(
fee.base_fee_per_gas.to_low_u64_be(),
fee.priority_fee_per_gas.to_low_u64_be(),
)
} else {
let fee = self.calculate_fee(storage, tx, time_in_mempool).await?;
(fee.base_fee_per_gas, fee.priority_fee_per_gas)
};

METRICS.used_base_fee_per_gas.observe(base_fee_per_gas);
METRICS
Expand Down
9 changes: 5 additions & 4 deletions core/lib/zksync_core/src/metadata_calculator/updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,14 @@ impl TreeUpdater {
None // Don't need to load the next L1 batch after the last one we're processing.
}
};
let ((header, metadata, object_key), next_l1_batch_data) =
let ((header, tree_metadata, object_key), next_l1_batch_data) =
future::join(process_l1_batch_task, load_next_l1_batch_task).await;

let check_consistency_latency = METRICS.start_stage(TreeUpdateStage::CheckConsistency);
Self::check_initial_writes_consistency(
storage,
header.number,
&metadata.initial_writes,
&tree_metadata.initial_writes,
)
.await;
check_consistency_latency.observe();
Expand All @@ -134,7 +134,7 @@ impl TreeUpdater {

let build_metadata_latency = METRICS.start_stage(TreeUpdateStage::BuildMetadata);
let metadata = MetadataCalculator::build_l1_batch_metadata(
metadata,
tree_metadata,
&header,
events_queue_commitment,
bootloader_initial_content_commitment,
Expand Down Expand Up @@ -348,10 +348,11 @@ impl TreeUpdater {
tracing::info!("Stop signal received, metadata_calculator is shutting down");
break;
}
let storage = pool.access_storage_tagged("metadata_calculator").await?;

let snapshot = *next_l1_batch_to_seal;
let storage = pool.access_storage_tagged("metadata_calculator").await?;
self.step(storage, &mut next_l1_batch_to_seal).await;

let delay = if snapshot == *next_l1_batch_to_seal {
tracing::trace!(
"Metadata calculator (next L1 batch: #{next_l1_batch_to_seal}) \
Expand Down
2 changes: 1 addition & 1 deletion docs/specs/zk_evm/fee_model.md
Original file line number Diff line number Diff line change
Expand Up @@ -518,5 +518,5 @@ not charge for it.
- On-Chain L2 Revenue
- L2 Transaction Fee
- This fee is what the user pays to complete a transaction on zkEVM. It is calculated as
`gasLimit x baseFeePerGas - refundedGas x baseFeePerGas`, or more simply, `gasUsed x baseFeePerGas`.
`gasLimit x base_fee_per_gas - refundedGas x base_fee_per_gas`, or more simply, `gasUsed x base_fee_per_gas`.
- Profit = L2 Revenue - L1 Costs - Off Chain Infrastructure Costs

0 comments on commit d072302

Please sign in to comment.