Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

small changes #89

Merged
merged 5 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,9 @@ PROVER_SERVICE="sharp"
SETTLEMENT_LAYER="ethereum"
DATA_STORAGE="s3"
MONGODB_CONNECTION_STRING="mongodb://localhost:27017"

DEFAULT_SETTLEMENT_CLIENT_RPC="http://localhost:3000"

# Ethereum Settlement
DEFAULT_SETTLEMENT_CLIENT_RPC="http://localhost:3000"
Copy link
Contributor

@heemankv heemankv Aug 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is needed in test cases outside of Settlement Client, hence keeping

DEFAULT_L1_CORE_CONTRACT_ADDRESS="0xc662c410C0ECf747543f5bA90660f6ABeBD9C8c4"
SHOULD_IMPERSONATE_ACCOUNT="true"
TEST_DUMMY_CONTRACT_ADDRESS="0xE5b6F5e695BA6E4aeD92B68c4CC8Df1160D69A81"
112 changes: 62 additions & 50 deletions crates/settlement-clients/ethereum/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ use alloy::{
signers::local::PrivateKeySigner,
};

// use eyre::Result;
use alloy::eips::eip2930::AccessList;
use alloy::eips::eip4844::BYTES_PER_BLOB;
use alloy::hex;
// use alloy::node_bindings::Anvil;
use alloy::rpc::types::TransactionRequest;
use alloy_primitives::Bytes;
use async_trait::async_trait;
Expand All @@ -29,6 +27,8 @@ use mockall::{automock, lazy_static, predicate::*};
use alloy::providers::ProviderBuilder;
use conversion::{get_input_data_for_eip_4844, prepare_sidecar};
use settlement_client_interface::{SettlementClient, SettlementVerificationStatus, SETTLEMENT_SETTINGS_NAME};
#[cfg(test)]
use url::Url;
use utils::{env_utils::get_env_var_or_panic, settings::SettingsProvider};

use crate::clients::interfaces::validity_interface::StarknetValidityContractTrait;
Expand All @@ -39,13 +39,6 @@ pub mod clients;
pub mod config;
pub mod conversion;

// IMPORTANT to understand #[cfg(test)], #[cfg(not(test))] and SHOULD_IMPERSONATE_ACCOUNT
// Two tests : `update_state_blob_with_dummy_contract_works` & `update_state_blob_with_impersonation_works` use a env var `SHOULD_IMPERSONATE_ACCOUNT` to inform the function `update_state_with_blobs` about the kind of testing,
// `SHOULD_IMPERSONATE_ACCOUNT` can have any of "0" or "1" value :
// - if "0" then : Testing via default Anvil address.
// - if "1" then : Testing via impersonating `Starknet Operator Address`.
// Note : changing between "0" and "1" is handled automatically by each test function, `no` manual change in `env.test` is needed.

#[cfg(test)]
mod tests;
pub mod types;
Expand All @@ -62,12 +55,13 @@ lazy_static! {
.expect("Error loading trusted setup file");
}

#[allow(dead_code)]
pub struct EthereumSettlementClient {
core_contract_client: StarknetValidityContractClient,
wallet: EthereumWallet,
wallet_address: Address,
provider: RootProvider<Http<Client>>,
provider: Arc<RootProvider<Http<Client>>>,
#[cfg(test)]
impersonate_account: Option<Address>,
}

impl EthereumSettlementClient {
Expand All @@ -79,50 +73,56 @@ impl EthereumSettlementClient {
let wallet_address = signer.address();
let wallet = EthereumWallet::from(signer);

let fill_provider = Arc::new(
ProviderBuilder::new()
.with_recommended_fillers()
.wallet(wallet.clone())
.on_http(settlement_cfg.rpc_url.clone()),
// provider without wallet
let provider = Arc::new(ProviderBuilder::new().on_http(settlement_cfg.rpc_url.clone()));

// provider with wallet
let filler_provider = Arc::new(
ProviderBuilder::new().with_recommended_fillers().wallet(wallet.clone()).on_http(settlement_cfg.rpc_url),
);
let provider = ProviderBuilder::new().on_http(settlement_cfg.rpc_url);

let core_contract_client = StarknetValidityContractClient::new(
Address::from_str(&settlement_cfg.core_contract_address)
.expect("Failed to convert the validity contract address.")
.0
.into(),
fill_provider.clone(),
filler_provider,
);

EthereumSettlementClient { provider, core_contract_client, wallet, wallet_address }
EthereumSettlementClient {
provider,
core_contract_client,
wallet,
wallet_address,
#[cfg(test)]
impersonate_account: None,
}
}

#[cfg(test)]
pub fn with_test_settings(settings: &impl SettingsProvider, provider: RootProvider<Http<Client>>) -> Self {
use tests::{SHOULD_IMPERSONATE_ACCOUNT, TEST_DUMMY_CONTRACT_ADDRESS};
let settlement_cfg: EthereumSettlementConfig = settings.get_settings(SETTLEMENT_SETTINGS_NAME).unwrap();

pub fn with_test_settings(
provider: RootProvider<Http<Client>>,
core_contract_address: Address,
rpc_url: Url,
impersonate_account: Option<Address>,
) -> Self {
let private_key = get_env_var_or_panic(ENV_PRIVATE_KEY);
let signer: PrivateKeySigner = private_key.parse().expect("Failed to parse private key");
let wallet_address = signer.address();
let wallet = EthereumWallet::from(signer);

let fill_provider = Arc::new(
ProviderBuilder::new().with_recommended_fillers().wallet(wallet.clone()).on_http(settlement_cfg.rpc_url),
);
let fill_provider =
Arc::new(ProviderBuilder::new().with_recommended_fillers().wallet(wallet.clone()).on_http(rpc_url));

let core_contract_address = if *SHOULD_IMPERSONATE_ACCOUNT {
&settlement_cfg.core_contract_address
} else {
&*TEST_DUMMY_CONTRACT_ADDRESS
};
let core_contract_client = StarknetValidityContractClient::new(core_contract_address, fill_provider);

let core_contract_client = StarknetValidityContractClient::new(
Address::from_str(core_contract_address).unwrap().0.into(),
fill_provider,
);

EthereumSettlementClient { provider, core_contract_client, wallet, wallet_address }
EthereumSettlementClient {
provider: Arc::new(provider),
core_contract_client,
wallet,
wallet_address,
impersonate_account,
}
}

/// Build kzg proof for the x_0 point evaluation
Expand Down Expand Up @@ -180,12 +180,6 @@ impl SettlementClient for EthereumSettlementClient {
}

/// Should be used to update state on core contract when DA is in blobs/alt DA
async fn update_state_blobs(&self, program_output: Vec<[u8; 32]>, kzg_proof: [u8; 48]) -> Result<String> {
let program_output: Vec<U256> = vec_u8_32_to_vec_u256(&program_output)?;
let tx_receipt = self.core_contract_client.update_state_kzg(program_output, kzg_proof).await?;
Ok(format!("0x{:x}", tx_receipt.transaction_hash))
}

async fn update_state_with_blobs(
&self,
program_output: Vec<[u8; 32]>,
Expand Down Expand Up @@ -242,13 +236,19 @@ impl SettlementClient for EthereumSettlementClient {
let signature = self.wallet.default_signer().sign_transaction(&mut variant).await?;
let tx_signed = variant.into_signed(signature);
let tx_envelope: TxEnvelope = tx_signed.into();
// IMP: this conversion strips signature from the transaction

// IMP: this conversion strips signature from the transaction
#[cfg(not(test))]
let txn_request: TransactionRequest = tx_envelope.into();

#[cfg(test)]
let txn_request = test_config::configure_transaction(tx_envelope);
let txn_request = test_config::configure_transaction(
// self.provider.clone(),
tx_envelope,
self.impersonate_account,
nonce,
)
.await;

let pending_transaction = self.provider.send_transaction(txn_request).await?;
return Ok(pending_transaction.tx_hash().to_string());
Expand Down Expand Up @@ -293,14 +293,26 @@ impl SettlementClient for EthereumSettlementClient {
mod test_config {
use super::*;
use alloy::network::TransactionBuilder;
use tests::{ADDRESS_TO_IMPERSONATE, SHOULD_IMPERSONATE_ACCOUNT, TEST_NONCE};

pub fn configure_transaction(tx_envelope: TxEnvelope) -> TransactionRequest {
pub async fn configure_transaction(
// provider: Arc<RootProvider<Http<Client>>>,
tx_envelope: TxEnvelope,
impersonate_account: Option<Address>,
nonce: u64,
) -> TransactionRequest {
let mut txn_request: TransactionRequest = tx_envelope.into();

if *SHOULD_IMPERSONATE_ACCOUNT {
txn_request.set_nonce(*TEST_NONCE);
txn_request = txn_request.with_from(*ADDRESS_TO_IMPERSONATE);
// IMPORTANT to understand #[cfg(test)], #[cfg(not(test))] and SHOULD_IMPERSONATE_ACCOUNT
// Two tests : `update_state_blob_with_dummy_contract_works` & `update_state_blob_with_impersonation_works` use a env var `SHOULD_IMPERSONATE_ACCOUNT` to inform the function `update_state_with_blobs` about the kind of testing,
// `SHOULD_IMPERSONATE_ACCOUNT` can have any of "0" or "1" value :
// - if "0" then : Testing via default Anvil address.
// - if "1" then : Testing via impersonating `Starknet Operator Address`.
// Note : changing between "0" and "1" is handled automatically by each test function, `no` manual change in `env.test` is needed.
if let Some(impersonate_account) = impersonate_account {
// let nonce =
// provider.get_transaction_count(impersonate_account).await.unwrap().to_string().parse::<u64>().unwrap();
txn_request.set_nonce(nonce);
txn_request = txn_request.with_from(impersonate_account);
}

txn_request
Expand Down
Loading
Loading