Skip to content

Commit

Permalink
feat(en): Fetch old L1 batch hashes from L1
Browse files Browse the repository at this point in the history
  • Loading branch information
vivijj committed Jun 7, 2024
1 parent ec094bd commit dece80d
Show file tree
Hide file tree
Showing 30 changed files with 944 additions and 299 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion core/bin/external_node/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,8 @@ async fn init_tasks(
"Running tree data fetcher (allows a node to operate w/o a Merkle tree or w/o waiting the tree to catch up). \
This is an experimental feature; do not use unless you know what you're doing"
);
let fetcher = TreeDataFetcher::new(main_node_client.clone(), connection_pool.clone());
let fetcher = TreeDataFetcher::new(main_node_client.clone(), connection_pool.clone())
.with_l1_data(eth_client.clone(), config.remote.diamond_proxy_addr)?;
app_health.insert_component(fetcher.health_check())?;
task_handles.push(tokio::spawn(fetcher.run(stop_receiver.clone())));
}
Expand Down
43 changes: 34 additions & 9 deletions core/lib/basic_types/src/web3/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,30 +138,36 @@ impl<'a> Visitor<'a> for BytesVisitor {
// `Log`: from `web3::types::log`

/// Filter
#[derive(Default, Debug, PartialEq, Clone, Serialize)]
#[derive(Default, Debug, PartialEq, Clone, Serialize, Deserialize)]
pub struct Filter {
/// From Block
#[serde(rename = "fromBlock", skip_serializing_if = "Option::is_none")]
from_block: Option<BlockNumber>,
pub from_block: Option<BlockNumber>,
/// To Block
#[serde(rename = "toBlock", skip_serializing_if = "Option::is_none")]
to_block: Option<BlockNumber>,
pub to_block: Option<BlockNumber>,
/// Block Hash
#[serde(rename = "blockHash", skip_serializing_if = "Option::is_none")]
block_hash: Option<H256>,
pub block_hash: Option<H256>,
/// Address
#[serde(skip_serializing_if = "Option::is_none")]
address: Option<ValueOrArray<H160>>,
pub address: Option<ValueOrArray<H160>>,
/// Topics
#[serde(skip_serializing_if = "Option::is_none")]
topics: Option<Vec<Option<ValueOrArray<H256>>>>,
pub topics: Option<Vec<Option<ValueOrArray<H256>>>>,
/// Limit
#[serde(skip_serializing_if = "Option::is_none")]
limit: Option<usize>,
pub limit: Option<usize>,
}

#[derive(Default, Debug, PartialEq, Clone)]
struct ValueOrArray<T>(Vec<T>);
pub struct ValueOrArray<T>(Vec<T>);

impl<T> ValueOrArray<T> {
pub fn flatten(self) -> Vec<T> {
self.0
}
}

impl<T> Serialize for ValueOrArray<T>
where
Expand All @@ -179,6 +185,25 @@ where
}
}

impl<'de, T> Deserialize<'de> for ValueOrArray<T>
where
T: Deserialize<'de>,
{
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(untagged)]
enum Repr<T> {
Single(T),
Sequence(Vec<T>),
}

Ok(match Repr::<T>::deserialize(deserializer)? {
Repr::Single(element) => Self(vec![element]),
Repr::Sequence(elements) => Self(elements),
})
}
}

// Filter Builder
#[derive(Default, Clone)]
pub struct FilterBuilder {
Expand Down Expand Up @@ -271,7 +296,7 @@ fn topic_to_option<T>(topic: ethabi::Topic<T>) -> Option<Vec<T>> {
}

/// A log produced by a transaction.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
pub struct Log {
/// H160
pub address: H160,
Expand Down
47 changes: 26 additions & 21 deletions core/lib/eth_client/src/clients/http/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ use std::fmt;
use async_trait::async_trait;
use jsonrpsee::core::ClientError;
use zksync_types::{web3, Address, L1ChainId, H256, U256, U64};
use zksync_web3_decl::error::{ClientRpcContext, EnrichedClientError};
use zksync_web3_decl::error::{ClientRpcContext, EnrichedClientError, EnrichedClientResult};

use super::{decl::L1EthNamespaceClient, Method, COUNTERS, LATENCIES};
use crate::{
types::{Error, ExecutedTxStatus, FailureInfo},
types::{ExecutedTxStatus, FailureInfo},
EthInterface, RawTransactionBytes,
};

Expand All @@ -16,15 +16,14 @@ impl<T> EthInterface for T
where
T: L1EthNamespaceClient + fmt::Debug + Send + Sync,
{
async fn fetch_chain_id(&self) -> Result<L1ChainId, Error> {
async fn fetch_chain_id(&self) -> EnrichedClientResult<L1ChainId> {
COUNTERS.call[&(Method::ChainId, self.component())].inc();
let latency = LATENCIES.direct[&Method::ChainId].start();
let raw_chain_id = self.chain_id().rpc_context("chain_id").await?;
latency.observe();
let chain_id = u64::try_from(raw_chain_id).map_err(|err| {
let err = ClientError::Custom(format!("invalid chainId: {err}"));
let err = EnrichedClientError::new(err, "chain_id").with_arg("chain_id", &raw_chain_id);
Error::EthereumGateway(err)
EnrichedClientError::new(err, "chain_id").with_arg("chain_id", &raw_chain_id)
})?;
Ok(L1ChainId(chain_id))
}
Expand All @@ -33,7 +32,7 @@ where
&self,
account: Address,
block: web3::BlockNumber,
) -> Result<U256, Error> {
) -> EnrichedClientResult<U256> {
COUNTERS.call[&(Method::NonceAtForAccount, self.component())].inc();
let latency = LATENCIES.direct[&Method::NonceAtForAccount].start();
let nonce = self
Expand All @@ -46,7 +45,7 @@ where
Ok(nonce)
}

async fn block_number(&self) -> Result<U64, Error> {
async fn block_number(&self) -> EnrichedClientResult<U64> {
COUNTERS.call[&(Method::BlockNumber, self.component())].inc();
let latency = LATENCIES.direct[&Method::BlockNumber].start();
let block_number = self
Expand All @@ -57,15 +56,15 @@ where
Ok(block_number)
}

async fn get_gas_price(&self) -> Result<U256, Error> {
async fn get_gas_price(&self) -> EnrichedClientResult<U256> {
COUNTERS.call[&(Method::GetGasPrice, self.component())].inc();
let latency = LATENCIES.direct[&Method::GetGasPrice].start();
let network_gas_price = self.gas_price().rpc_context("gas_price").await?;
latency.observe();
Ok(network_gas_price)
}

async fn send_raw_tx(&self, tx: RawTransactionBytes) -> Result<H256, Error> {
async fn send_raw_tx(&self, tx: RawTransactionBytes) -> EnrichedClientResult<H256> {
let latency = LATENCIES.direct[&Method::SendRawTx].start();
let tx = self
.send_raw_transaction(web3::Bytes(tx.0))
Expand All @@ -79,7 +78,7 @@ where
&self,
upto_block: usize,
block_count: usize,
) -> Result<Vec<u64>, Error> {
) -> EnrichedClientResult<Vec<u64>> {
const MAX_REQUEST_CHUNK: usize = 1024;

COUNTERS.call[&(Method::BaseFeeHistory, self.component())].inc();
Expand Down Expand Up @@ -111,7 +110,7 @@ where
Ok(history.into_iter().map(|fee| fee.as_u64()).collect())
}

async fn get_pending_block_base_fee_per_gas(&self) -> Result<U256, Error> {
async fn get_pending_block_base_fee_per_gas(&self) -> EnrichedClientResult<U256> {
COUNTERS.call[&(Method::PendingBlockBaseFee, self.component())].inc();
let latency = LATENCIES.direct[&Method::PendingBlockBaseFee].start();

Expand Down Expand Up @@ -140,7 +139,7 @@ where
Ok(block.base_fee_per_gas.unwrap())
}

async fn get_tx_status(&self, hash: H256) -> Result<Option<ExecutedTxStatus>, Error> {
async fn get_tx_status(&self, hash: H256) -> EnrichedClientResult<Option<ExecutedTxStatus>> {
COUNTERS.call[&(Method::GetTxStatus, self.component())].inc();
let latency = LATENCIES.direct[&Method::GetTxStatus].start();

Expand All @@ -162,7 +161,7 @@ where
Ok(res)
}

async fn failure_reason(&self, tx_hash: H256) -> Result<Option<FailureInfo>, Error> {
async fn failure_reason(&self, tx_hash: H256) -> EnrichedClientResult<Option<FailureInfo>> {
let latency = LATENCIES.direct[&Method::FailureReason].start();
let transaction = self
.get_transaction_by_hash(tx_hash)
Expand Down Expand Up @@ -218,7 +217,7 @@ where
gas_limit,
}))
} else {
Err(err.into())
Err(err)
}
}
Ok(_) => Ok(None),
Expand All @@ -231,7 +230,7 @@ where
}
}

async fn get_tx(&self, hash: H256) -> Result<Option<web3::Transaction>, Error> {
async fn get_tx(&self, hash: H256) -> EnrichedClientResult<Option<web3::Transaction>> {
COUNTERS.call[&(Method::GetTx, self.component())].inc();
let tx = self
.get_transaction_by_hash(hash)
Expand All @@ -245,7 +244,7 @@ where
&self,
request: web3::CallRequest,
block: Option<web3::BlockId>,
) -> Result<web3::Bytes, Error> {
) -> EnrichedClientResult<web3::Bytes> {
let latency = LATENCIES.direct[&Method::CallContractFunction].start();
let block = block.unwrap_or_else(|| web3::BlockNumber::Latest.into());
let output_bytes = self
Expand All @@ -258,7 +257,10 @@ where
Ok(output_bytes)
}

async fn tx_receipt(&self, tx_hash: H256) -> Result<Option<web3::TransactionReceipt>, Error> {
async fn tx_receipt(
&self,
tx_hash: H256,
) -> EnrichedClientResult<Option<web3::TransactionReceipt>> {
COUNTERS.call[&(Method::TxReceipt, self.component())].inc();
let latency = LATENCIES.direct[&Method::TxReceipt].start();
let receipt = self
Expand All @@ -270,7 +272,7 @@ where
Ok(receipt)
}

async fn eth_balance(&self, address: Address) -> Result<U256, Error> {
async fn eth_balance(&self, address: Address) -> EnrichedClientResult<U256> {
COUNTERS.call[&(Method::EthBalance, self.component())].inc();
let latency = LATENCIES.direct[&Method::EthBalance].start();
let balance = self
Expand All @@ -282,19 +284,22 @@ where
Ok(balance)
}

async fn logs(&self, filter: web3::Filter) -> Result<Vec<web3::Log>, Error> {
async fn logs(&self, filter: &web3::Filter) -> EnrichedClientResult<Vec<web3::Log>> {
COUNTERS.call[&(Method::Logs, self.component())].inc();
let latency = LATENCIES.direct[&Method::Logs].start();
let logs = self
.get_logs(filter.clone())
.rpc_context("get_logs")
.with_arg("filter", &filter)
.with_arg("filter", filter)
.await?;
latency.observe();
Ok(logs)
}

async fn block(&self, block_id: web3::BlockId) -> Result<Option<web3::Block<H256>>, Error> {
async fn block(
&self,
block_id: web3::BlockId,
) -> EnrichedClientResult<Option<web3::Block<H256>>> {
COUNTERS.call[&(Method::Block, self.component())].inc();
let latency = LATENCIES.direct[&Method::Block].start();
let block = match block_id {
Expand Down
12 changes: 6 additions & 6 deletions core/lib/eth_client/src/clients/http/signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use zksync_web3_decl::client::{DynClient, L1};

use super::{Method, LATENCIES};
use crate::{
types::{encode_blob_tx_with_sidecar, Error, SignedCallResult},
types::{encode_blob_tx_with_sidecar, ContractCallError, SignedCallResult, SigningError},
BoundEthInterface, CallFunctionArgs, EthInterface, Options, RawTransactionBytes,
};

Expand Down Expand Up @@ -115,7 +115,7 @@ impl<S: EthereumSigner> BoundEthInterface for SigningClient<S> {
data: Vec<u8>,
contract_addr: H160,
options: Options,
) -> Result<SignedCallResult, Error> {
) -> Result<SignedCallResult, SigningError> {
let latency = LATENCIES.direct[&Method::SignPreparedTx].start();
// Fetch current max priority fee per gas
let max_priority_fee_per_gas = match options.max_priority_fee_per_gas {
Expand All @@ -125,10 +125,10 @@ impl<S: EthereumSigner> BoundEthInterface for SigningClient<S> {

if options.transaction_type == Some(EIP_4844_TX_TYPE.into()) {
if options.max_fee_per_blob_gas.is_none() {
return Err(Error::Eip4844MissingMaxFeePerBlobGas);
return Err(SigningError::Eip4844MissingMaxFeePerBlobGas);
}
if options.blob_versioned_hashes.is_none() {
return Err(Error::Eip4844MissingBlobVersionedHashes);
return Err(SigningError::Eip4844MissingBlobVersionedHashes);
}
}

Expand All @@ -141,7 +141,7 @@ impl<S: EthereumSigner> BoundEthInterface for SigningClient<S> {
};

if max_fee_per_gas < max_priority_fee_per_gas {
return Err(Error::WrongFeeProvided(
return Err(SigningError::WrongFeeProvided(
max_fee_per_gas,
max_priority_fee_per_gas,
));
Expand Down Expand Up @@ -198,7 +198,7 @@ impl<S: EthereumSigner> BoundEthInterface for SigningClient<S> {
token_address: Address,
address: Address,
erc20_abi: &ethabi::Contract,
) -> Result<U256, Error> {
) -> Result<U256, ContractCallError> {
let latency = LATENCIES.direct[&Method::Allowance].start();
let allowance: U256 =
CallFunctionArgs::new("allowance", (self.inner.sender_account, address))
Expand Down
8 changes: 4 additions & 4 deletions core/lib/eth_client/src/clients/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use zksync_types::{
use zksync_web3_decl::client::{DynClient, MockClient, L1};

use crate::{
types::{Error, SignedCallResult},
types::{ContractCallError, SignedCallResult, SigningError},
BoundEthInterface, Options, RawTransactionBytes,
};

Expand Down Expand Up @@ -475,7 +475,7 @@ impl MockEthereum {
mut raw_tx: Vec<u8>,
contract_addr: Address,
options: Options,
) -> Result<SignedCallResult, Error> {
) -> Result<SignedCallResult, SigningError> {
let max_fee_per_gas = options.max_fee_per_gas.unwrap_or(self.max_fee_per_gas);
let max_priority_fee_per_gas = options
.max_priority_fee_per_gas
Expand Down Expand Up @@ -570,7 +570,7 @@ impl BoundEthInterface for MockEthereum {
data: Vec<u8>,
contract_addr: H160,
options: Options,
) -> Result<SignedCallResult, Error> {
) -> Result<SignedCallResult, SigningError> {
self.sign_prepared_tx(data, contract_addr, options)
}

Expand All @@ -579,7 +579,7 @@ impl BoundEthInterface for MockEthereum {
_token_address: Address,
_contract_address: Address,
_erc20_abi: &ethabi::Contract,
) -> Result<U256, Error> {
) -> Result<U256, ContractCallError> {
unimplemented!("Not needed right now")
}
}
Expand Down
Loading

0 comments on commit dece80d

Please sign in to comment.