Skip to content

Commit

Permalink
Merge branch 'main' into custom-l1-price
Browse files Browse the repository at this point in the history
  • Loading branch information
vbar committed Jun 27, 2024
2 parents 74cc278 + dd6d2f4 commit cbc8f50
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
tar -xzf era_test_node-${{ matrix.os }}.tar.gz
chmod +x era_test_node
echo "Starting node in background"
./era_test_node run 2>&1 | tee era_test_node_output.log &
./era_test_node 2>&1 | tee era_test_node_output.log &
echo "PID=$!" >> $GITHUB_ENV
- name: Launch tests
Expand Down
2 changes: 1 addition & 1 deletion SUPPORTED_APIS.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ The `status` options are:
| `HARDHAT` | `hardhat_setNextBlockBaseFeePerGas` | `NOT IMPLEMENTED` | Sets the base fee per gas for the next block |
| `HARDHAT` | `hardhat_setPrevRandao` | `NOT IMPLEMENTED` | Sets the PREVRANDAO value of the next block |
| [`HARDHAT`](#hardhat-namespace) | [`hardhat_setNonce`](#hardhat_setnonce) | `SUPPORTED` | Sets the nonce of a given account |
| `HARDHAT` | `hardhat_setStorageAt` | `NOT IMPLEMENTED` | Sets the storage value at a given key for a given account |
| [`HARDHAT`](#hardhat-namespace) | [`hardhat_setStorageAt`](#hardhat_setstorageat) | `SUPPORTED` | Sets the storage value at a given key for a given account |
| [`HARDHAT`](#hardhat-namespace) | [`hardhat_stopImpersonatingAccount`](#hardhat_stopimpersonatingaccount) | `SUPPORTED` | Stop impersonating an account after having previously used `hardhat_impersonateAccount` |
| [`NETWORK`](#network-namespace) | [`net_version`](#net_version) | `SUPPORTED` | Returns the current network id <br />_(default is `260`)_ |
| [`NETWORK`](#network-namespace) | [`net_peerCount`](#net_peercount) | `SUPPORTED` | Returns the number of peers currently connected to the client <br/>_(hard-coded to `0`)_ |
Expand Down
28 changes: 28 additions & 0 deletions e2e-tests/test/eth-apis.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { expect } from "chai";
import { Wallet } from "zksync-web3";
import { expectThrowsAsync, getTestProvider } from "../helpers/utils";
import { RichAccounts } from "../helpers/constants";
import { ethers } from "ethers";
Expand All @@ -17,6 +18,33 @@ describe("eth_accounts", function () {
// Assert
expect(accounts).to.deep.equal(richAccounts);
});

it("Should have required fields in transaction receipt", async function () {
// Arrange
const wallet = new Wallet(RichAccounts[0].PrivateKey, provider);
const tx = await wallet.sendTransaction({
to: wallet.address,
value: ethers.utils.parseEther("3"),
});
const response = await tx.wait();
const txHash = response.transactionHash;

// Act
const receipt = await provider.send("eth_getTransactionReceipt", [txHash]);

// Assert
expect(receipt).to.have.property("blockHash");
expect(receipt).to.have.property("blockNumber");
expect(receipt).to.have.property("transactionHash");
expect(receipt).to.have.property("transactionIndex");
expect(receipt).to.have.property("from");
expect(receipt).to.have.property("to");
expect(receipt).to.have.property("cumulativeGasUsed");
expect(receipt).to.have.property("gasUsed");
expect(receipt).to.have.property("logs");
expect(receipt).to.have.property("logsBloom");
expect(receipt).to.have.property("type");
});
});

describe("eth_sendTransaction", function () {
Expand Down
8 changes: 5 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ enum DevSystemContracts {
#[command(author = "Matter Labs", version, about = "Test Node", long_about = None)]
struct Cli {
#[command(subcommand)]
command: Command,
command: Option<Command>,
#[arg(long, default_value = "8011")]
/// Port to listen on - default: 8011
port: u16,
Expand Down Expand Up @@ -339,7 +339,9 @@ async fn main() -> anyhow::Result<()> {
},
};

let fork_details = match &opt.command {
// Use `Command::Run` as default.
let command = opt.command.as_ref().unwrap_or(&Command::Run);
let fork_details = match &command {
Command::Run => None,
Command::Fork(fork) => {
Some(ForkDetails::from_network(&fork.network, fork.fork_at, cache_config).await)
Expand All @@ -351,7 +353,7 @@ async fn main() -> anyhow::Result<()> {

// If we're replaying the transaction, we need to sync to the previous block
// and then replay all the transactions that happened in
let transactions_to_replay = if let Command::ReplayTx(replay_tx) = &opt.command {
let transactions_to_replay = if let Command::ReplayTx(replay_tx) = command {
fork_details
.as_ref()
.unwrap()
Expand Down
14 changes: 14 additions & 0 deletions src/namespaces/hardhat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,18 @@ pub trait HardhatNamespaceT {
/// A `BoxFuture` containing a `Result` with a `bool` representing the success of the operation.
#[rpc(name = "hardhat_setCode")]
fn set_code(&self, address: Address, code: Vec<u8>) -> RpcResult<()>;

/// Directly modifies the storage of a contract at a specified slot.
///
/// # Arguments
///
/// * `address` - The contract address whose storage is to be modified.
/// * `slot` - The storage slot to modify.
/// * `value` - The value to be set at the specified slot.
///
/// # Returns
///
/// A `BoxFuture` containing a `Result` with a `bool` representing the success of the operation.
#[rpc(name = "hardhat_setStorageAt")]
fn set_storage_at(&self, address: Address, slot: U256, value: U256) -> RpcResult<bool>;
}
9 changes: 9 additions & 0 deletions src/node/hardhat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,13 @@ impl<S: ForkSource + std::fmt::Debug + Clone + Send + Sync + 'static> HardhatNam
})
.into_boxed_future()
}

fn set_storage_at(&self, address: Address, slot: U256, value: U256) -> RpcResult<bool> {
self.set_storage_at(address, slot, value)
.map_err(|err| {
tracing::error!("failed setting storage: {:?}", err);
into_jsrpc_error(Web3Error::InternalError(err))
})
.into_boxed_future()
}
}
4 changes: 3 additions & 1 deletion src/node/in_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1581,6 +1581,7 @@ impl<S: ForkSource + std::fmt::Debug + Clone> InMemoryNode<S> {
/// Runs L2 transaction and commits it to a new block.
pub fn run_l2_tx(&self, l2_tx: L2Tx, execution_mode: TxExecutionMode) -> Result<(), String> {
let tx_hash = l2_tx.hash();
let transaction_type = l2_tx.common_data.transaction_type;

tracing::info!("");
tracing::info!("Validating {}", format!("{:?}", tx_hash).bold());
Expand Down Expand Up @@ -1693,7 +1694,8 @@ impl<S: ForkSource + std::fmt::Debug + Clone> InMemoryNode<S> {
U64::from(1)
},
effective_gas_price: Some(inner.fee_input_provider.l2_gas_price.into()),
..Default::default()
transaction_type: Some((transaction_type as u32).into()),
logs_bloom: Default::default(),
};
let debug = create_debug_output(&l2_tx, &result, call_traces).expect("create debug output"); // OK to unwrap here as Halt is handled above
inner.tx_results.insert(
Expand Down
45 changes: 44 additions & 1 deletion src/node/in_memory_ext.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use anyhow::anyhow;
use zksync_basic_types::{Address, U256, U64};
use zksync_basic_types::{AccountTreeId, Address, U256, U64};
use zksync_types::{
get_code_key, get_nonce_key,
utils::{decompose_full_nonce, nonces_to_full_nonce, storage_key_for_eth_balance},
StorageKey,
};
use zksync_utils::{h256_to_u256, u256_to_h256};

Expand Down Expand Up @@ -323,6 +324,17 @@ impl<S: ForkSource + std::fmt::Debug + Clone + Send + Sync + 'static> InMemoryNo
Ok(())
})
}

pub fn set_storage_at(&self, address: Address, slot: U256, value: U256) -> Result<bool> {
self.get_inner()
.write()
.map_err(|err| anyhow!("failed acquiring lock: {:?}", err))
.map(|mut writer| {
let key = StorageKey::new(AccountTreeId::new(address), u256_to_h256(slot));
writer.fork_storage.set_value(key, u256_to_h256(value));
true
})
}
}

#[cfg(test)]
Expand All @@ -332,6 +344,7 @@ mod tests {
use crate::{http_fork_source::HttpForkSource, node::InMemoryNode};
use std::str::FromStr;
use zksync_basic_types::{Nonce, H256};
use zksync_state::ReadStorage;
use zksync_types::{api::BlockNumber, fee::Fee, l2::L2Tx, PackedEthSignature};

#[tokio::test]
Expand Down Expand Up @@ -529,6 +542,36 @@ mod tests {
assert_eq!(new_code, code_after);
}

#[tokio::test]
async fn test_set_storage_at() {
let node = InMemoryNode::<HttpForkSource>::default();
let address = Address::repeat_byte(0x1);
let slot = U256::from(37);
let value = U256::from(42);

let key = StorageKey::new(AccountTreeId::new(address), u256_to_h256(slot));
let value_before = node
.get_inner()
.write()
.unwrap()
.fork_storage
.read_value(&key);
assert_eq!(H256::default(), value_before);

let result = node
.set_storage_at(address, slot, value)
.expect("failed setting value");
assert!(result);

let value_after = node
.get_inner()
.write()
.unwrap()
.fork_storage
.read_value(&key);
assert_eq!(value, h256_to_u256(value_after));
}

#[tokio::test]
async fn test_increase_time_zero_value() {
let node = InMemoryNode::<HttpForkSource>::default();
Expand Down

0 comments on commit cbc8f50

Please sign in to comment.