Skip to content

Commit

Permalink
feat(vm): EVM emulator support – base (#2979)
Browse files Browse the repository at this point in the history
## What ❔

Modifies the Era codebase to support the EVM emulator. Intentionally
avoids changing the `contracts` submodule yet; as a consequence, there
are no EVM emulation tests.

## Why ❔

Stepping stone for EVM equivalence.

## Checklist

- [x] PR title corresponds to the body of PR (we generate changelog
entries from PRs).
- [x] Tests for the changes have been added / updated.
- [x] Documentation comments have been added / updated.
- [x] Code has been formatted via `zk fmt` and `zk lint`.

---------

Co-authored-by: IAvecilla <ignacio.avecilla@lambdaclass.com>
Co-authored-by: Javier Chatruc <jrchatruc@gmail.com>
  • Loading branch information
3 people authored Oct 8, 2024
1 parent 3fd2fb1 commit deafa46
Show file tree
Hide file tree
Showing 152 changed files with 2,189 additions and 487 deletions.
1 change: 1 addition & 0 deletions core/bin/genesis_generator/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ async fn generate_new_config(
genesis_commitment: None,
bootloader_hash: Some(base_system_contracts.bootloader),
default_aa_hash: Some(base_system_contracts.default_aa),
evm_emulator_hash: base_system_contracts.evm_emulator,
..genesis_config
};

Expand Down
3 changes: 3 additions & 0 deletions core/bin/system-constants-generator/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,14 @@ pub static GAS_TEST_SYSTEM_CONTRACTS: Lazy<BaseSystemContracts> = Lazy::new(|| {

let bytecode = read_sys_contract_bytecode("", "DefaultAccount", ContractLanguage::Sol);
let hash = hash_bytecode(&bytecode);

BaseSystemContracts {
default_aa: SystemContractCode {
code: bytes_to_be_words(bytecode),
hash,
},
bootloader,
evm_emulator: None,
}
});

Expand Down Expand Up @@ -221,6 +223,7 @@ pub(super) fn execute_internal_transfer_test() -> u32 {
let base_system_smart_contracts = BaseSystemContracts {
bootloader,
default_aa,
evm_emulator: None,
};

let system_env = SystemEnv {
Expand Down
3 changes: 3 additions & 0 deletions core/lib/config/src/configs/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ pub struct StateKeeperConfig {
pub bootloader_hash: Option<H256>,
#[deprecated(note = "Use GenesisConfig::default_aa_hash instead")]
pub default_aa_hash: Option<H256>,
#[deprecated(note = "Use GenesisConfig::evm_emulator_hash instead")]
pub evm_emulator_hash: Option<H256>,
#[deprecated(note = "Use GenesisConfig::l1_batch_commit_data_generator_mode instead")]
#[serde(default)]
pub l1_batch_commit_data_generator_mode: L1BatchCommitmentMode,
Expand Down Expand Up @@ -178,6 +180,7 @@ impl StateKeeperConfig {
protective_reads_persistence_enabled: true,
bootloader_hash: None,
default_aa_hash: None,
evm_emulator_hash: None,
l1_batch_commit_data_generator_mode: L1BatchCommitmentMode::Rollup,
}
}
Expand Down
2 changes: 2 additions & 0 deletions core/lib/config/src/configs/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub struct GenesisConfig {
pub genesis_commitment: Option<H256>,
pub bootloader_hash: Option<H256>,
pub default_aa_hash: Option<H256>,
pub evm_emulator_hash: Option<H256>,
pub l1_chain_id: L1ChainId,
pub sl_chain_id: Option<SLChainId>,
pub l2_chain_id: L2ChainId,
Expand Down Expand Up @@ -49,6 +50,7 @@ impl GenesisConfig {
genesis_commitment: Some(H256::repeat_byte(0x17)),
bootloader_hash: Default::default(),
default_aa_hash: Default::default(),
evm_emulator_hash: Default::default(),
l1_chain_id: L1ChainId(9),
sl_chain_id: None,
protocol_version: Some(ProtocolSemanticVersion {
Expand Down
2 changes: 2 additions & 0 deletions core/lib/config/src/testonly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ impl Distribution<configs::chain::StateKeeperConfig> for EncodeDist {
fee_account_addr: None,
bootloader_hash: None,
default_aa_hash: None,
evm_emulator_hash: None,
l1_batch_commit_data_generator_mode: Default::default(),
}
}
Expand Down Expand Up @@ -732,6 +733,7 @@ impl Distribution<configs::GenesisConfig> for EncodeDist {
genesis_commitment: Some(rng.gen()),
bootloader_hash: Some(rng.gen()),
default_aa_hash: Some(rng.gen()),
evm_emulator_hash: Some(rng.gen()),
fee_account: rng.gen(),
l1_chain_id: L1ChainId(self.sample(rng)),
sl_chain_id: None,
Expand Down
5 changes: 5 additions & 0 deletions core/lib/constants/src/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ pub const CODE_ORACLE_ADDRESS: Address = H160([
0x00, 0x00, 0x80, 0x12,
]);

pub const EVM_GAS_MANAGER_ADDRESS: Address = H160([
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0x13,
]);

/// Note, that the `Create2Factory` is explicitly deployed on a non-system-contract address.
pub const CREATE2_FACTORY_ADDRESS: Address = H160([
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Expand Down
22 changes: 21 additions & 1 deletion core/lib/contracts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ fn read_zbin_bytecode_from_path(bytecode_path: PathBuf) -> Vec<u8> {
fs::read(&bytecode_path)
.unwrap_or_else(|err| panic!("Can't read .zbin bytecode at {:?}: {}", bytecode_path, err))
}

/// Hash of code and code which consists of 32 bytes words
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemContractCode {
Expand All @@ -304,18 +305,23 @@ pub struct SystemContractCode {
pub struct BaseSystemContracts {
pub bootloader: SystemContractCode,
pub default_aa: SystemContractCode,
/// Never filled in constructors for now. The only way to get the EVM emulator enabled is to call [`Self::with_evm_emulator()`].
pub evm_emulator: Option<SystemContractCode>,
}

#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq)]
pub struct BaseSystemContractsHashes {
pub bootloader: H256,
pub default_aa: H256,
pub evm_emulator: Option<H256>,
}

impl PartialEq for BaseSystemContracts {
fn eq(&self, other: &Self) -> bool {
self.bootloader.hash == other.bootloader.hash
&& self.default_aa.hash == other.default_aa.hash
&& self.evm_emulator.as_ref().map(|contract| contract.hash)
== other.evm_emulator.as_ref().map(|contract| contract.hash)
}
}

Expand All @@ -339,14 +345,27 @@ impl BaseSystemContracts {
BaseSystemContracts {
bootloader,
default_aa,
evm_emulator: None,
}
}
// BaseSystemContracts with proved bootloader - for handling transactions.

/// BaseSystemContracts with proved bootloader - for handling transactions.
pub fn load_from_disk() -> Self {
let bootloader_bytecode = read_proved_batch_bootloader_bytecode();
BaseSystemContracts::load_with_bootloader(bootloader_bytecode)
}

/// Loads the latest EVM emulator for these base system contracts. Logically, it only makes sense to do for the latest protocol version.
pub fn with_latest_evm_emulator(mut self) -> Self {
let bytecode = read_sys_contract_bytecode("", "EvmInterpreter", ContractLanguage::Yul);
let hash = hash_bytecode(&bytecode);
self.evm_emulator = Some(SystemContractCode {
code: bytes_to_be_words(bytecode),
hash,
});
self
}

/// BaseSystemContracts with playground bootloader - used for handling eth_calls.
pub fn playground() -> Self {
let bootloader_bytecode = read_playground_batch_bootloader_bytecode();
Expand Down Expand Up @@ -475,6 +494,7 @@ impl BaseSystemContracts {
BaseSystemContractsHashes {
bootloader: self.bootloader.hash,
default_aa: self.default_aa.hash,
evm_emulator: self.evm_emulator.as_ref().map(|contract| contract.hash),
}
}
}
Expand Down

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

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

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

Loading

0 comments on commit deafa46

Please sign in to comment.