Skip to content

Commit

Permalink
Add support for EVM contracts deployment (#231)
Browse files Browse the repository at this point in the history
* Update functions to support None address to deploy EVM contract

* Update contracts submodule

* Update compiled contracts for multivm bootloader

* Add evm simulator code hash to the decommitment processor
  • Loading branch information
IAvecilla authored Aug 14, 2024
1 parent 3c36c88 commit 2a10e16
Show file tree
Hide file tree
Showing 78 changed files with 262 additions and 159 deletions.
2 changes: 1 addition & 1 deletion contracts
4 changes: 2 additions & 2 deletions core/bin/system-constants-generator/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ pub(super) fn get_l2_tx(
pubdata_price: u32,
) -> L2Tx {
L2Tx::new_signed(
contract_address,
Some(contract_address),
vec![],
Nonce(0),
Fee {
Expand Down Expand Up @@ -139,7 +139,7 @@ pub(super) fn get_l1_tx(
) -> L1Tx {
L1Tx {
execute: Execute {
contract_address,
contract_address: Some(contract_address),
calldata: custom_calldata.unwrap_or_default(),
value: U256::from(0),
factory_deps,
Expand Down
16 changes: 12 additions & 4 deletions core/lib/dal/src/consensus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,9 +371,11 @@ impl ProtoRepr for proto::Transaction {
}
},
execute: Execute {
contract_address: required(&execute.contract_address)
.and_then(|x| parse_h160(x))
.context("execute.contract_address")?,
contract_address: Some(
required(&execute.contract_address)
.and_then(|x| parse_h160(x))
.context("execute.contract_address")?,
),
calldata: required(&execute.calldata).context("calldata")?.clone(),
value: required(&execute.value)
.and_then(|x| parse_h256(x))
Expand Down Expand Up @@ -457,7 +459,13 @@ impl ProtoRepr for proto::Transaction {
}
};
let execute = proto::Execute {
contract_address: Some(this.execute.contract_address.as_bytes().into()),
contract_address: Some(
this.execute
.contract_address
.unwrap_or_default()
.as_bytes()
.into(),
),
calldata: Some(this.execute.calldata.clone()),
value: Some(u256_to_h256(this.execute.value).as_bytes().into()),
factory_deps: this.execute.factory_deps.clone(),
Expand Down
12 changes: 9 additions & 3 deletions core/lib/dal/src/models/storage_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,11 +364,11 @@ impl From<StorageTransactionReceipt> for TransactionReceipt {
.transfer_to
.or(storage_receipt.execute_contract_address)
.map(|addr| {
serde_json::from_value::<Address>(addr)
serde_json::from_value::<Option<Address>>(addr)
.expect("invalid address value in the database")
})
// For better compatibility with various clients, we never return null.
.or_else(|| Some(Address::default())),
.flatten(),
cumulative_gas_used: Default::default(), // TODO: Should be actually calculated (SMA-1183).
gas_used: {
let refunded_gas: U256 = storage_receipt.refunded_gas.into();
Expand Down Expand Up @@ -507,14 +507,20 @@ impl StorageApiTransaction {
.signature
.and_then(|signature| PackedEthSignature::deserialize_packed(&signature).ok());

let to = if let Ok(address) = serde_json::from_value(self.execute_contract_address) {
Some(address)
} else {
Some(Address::zero())
};

let mut tx = api::Transaction {
hash: H256::from_slice(&self.tx_hash),
nonce: U256::from(self.nonce.unwrap_or(0) as u64),
block_hash: self.block_hash.map(|hash| H256::from_slice(&hash)),
block_number: self.block_number.map(|number| U64::from(number as u64)),
transaction_index: self.index_in_block.map(|idx| U64::from(idx as u64)),
from: Some(Address::from_slice(&self.initiator_address)),
to: Some(serde_json::from_value(self.execute_contract_address).unwrap()),
to,
value: bigdecimal_to_u256(self.value),
gas_price: Some(bigdecimal_to_u256(
self.effective_gas_price
Expand Down
2 changes: 1 addition & 1 deletion core/lib/dal/src/models/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{models::storage_transaction::StorageTransaction, BigDecimal};

fn default_execute() -> Execute {
Execute {
contract_address: H160::random(),
contract_address: Some(H160::random()),
value: U256::from(10i32),
calldata: hex::decode(
"a9059cbb00000000000000000000000058d595f318167d5af45d9e44ade4348dd4e\
Expand Down
6 changes: 3 additions & 3 deletions core/lib/dal/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ pub(crate) fn mock_l2_transaction() -> L2Tx {
gas_per_pubdata_limit: U256::from(DEFAULT_GAS_PER_PUBDATA),
};
let mut l2_tx = L2Tx::new_signed(
Address::random(),
Address::random().into(),
vec![],
zksync_types::Nonce(0),
fee,
Expand Down Expand Up @@ -107,7 +107,7 @@ pub(crate) fn mock_l1_execute() -> L1Tx {
};

let execute = Execute {
contract_address: H160::random(),
contract_address: H160::random().into(),
value: Default::default(),
calldata: vec![],
factory_deps: vec![],
Expand Down Expand Up @@ -135,7 +135,7 @@ pub(crate) fn mock_protocol_upgrade_transaction() -> ProtocolUpgradeTx {
};

let execute = Execute {
contract_address: H160::random(),
contract_address: H160::random().into(),
value: Default::default(),
calldata: vec![],
factory_deps: vec![],
Expand Down
75 changes: 61 additions & 14 deletions core/lib/dal/src/transactions_dal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,13 @@ impl TransactionsDal<'_, '_> {
tx: &L1Tx,
l1_block_number: L1BlockNumber,
) -> DalResult<()> {
let contract_address = tx.execute.contract_address.as_bytes();
let contract_address = tx.execute.contract_address;
let unwrapped_contract_address = contract_address.unwrap_or_default();
let contract_address_b: &[u8] = if contract_address.is_none() {
&[]
} else {
unwrapped_contract_address.as_bytes()
};
let tx_hash = tx.hash();
let tx_hash_bytes = tx_hash.as_bytes();
let json_data = serde_json::to_value(&tx.execute)
Expand Down Expand Up @@ -146,7 +152,7 @@ impl TransactionsDal<'_, '_> {
serial_id,
full_fee,
layer_2_tip_fee,
contract_address,
contract_address_b,
l1_block_number.0 as i32,
value,
empty_address.as_bytes(),
Expand All @@ -164,7 +170,13 @@ impl TransactionsDal<'_, '_> {
}

pub async fn insert_system_transaction(&mut self, tx: &ProtocolUpgradeTx) -> DalResult<()> {
let contract_address = tx.execute.contract_address.as_bytes().to_vec();
let contract_address = tx.execute.contract_address;
let unwrapped_contract_address = contract_address.unwrap_or_default();
let contract_address_b: &[u8] = if contract_address.is_none() {
&[]
} else {
unwrapped_contract_address.as_bytes()
};
let tx_hash = tx.common_data.hash().0.to_vec();
let json_data = serde_json::to_value(&tx.execute)
.unwrap_or_else(|_| panic!("cannot serialize tx {:?} to json", tx.common_data.hash()));
Expand Down Expand Up @@ -241,7 +253,7 @@ impl TransactionsDal<'_, '_> {
gas_per_pubdata_limit,
json_data,
upgrade_id,
contract_address,
contract_address_b,
l1_block_number,
value,
&Address::default().0.to_vec(),
Expand Down Expand Up @@ -287,7 +299,13 @@ impl TransactionsDal<'_, '_> {
}

let initiator_address = tx.initiator_account();
let contract_address = tx.execute.contract_address.as_bytes();
let contract_address = tx.execute.contract_address;
let unwrapped_contract_address = contract_address.unwrap_or_default();
let contract_address_b: &[u8] = if contract_address.is_none() {
&[]
} else {
unwrapped_contract_address.as_bytes()
};
let json_data = serde_json::to_value(&tx.execute)
.unwrap_or_else(|_| panic!("cannot serialize tx {:?} to json", tx.hash()));
let gas_limit = u256_to_big_decimal(tx.common_data.fee.gas_limit);
Expand Down Expand Up @@ -416,7 +434,7 @@ impl TransactionsDal<'_, '_> {
input_data,
&json_data,
tx_format,
contract_address,
contract_address_b,
value,
&paymaster,
&paymaster_input,
Expand Down Expand Up @@ -700,8 +718,15 @@ impl TransactionsDal<'_, '_> {
.arg_error(&format!("transactions[{index_in_block}].refunded_gas"), err)
})?;

let contract_address = transaction.execute.contract_address;
let unwrapped_contract_address = contract_address.unwrap_or_default();
let contract_address_b: Vec<u8> = if contract_address.is_none() {
Vec::new()
} else {
unwrapped_contract_address.as_bytes().to_vec()
};
l2_values.push(u256_to_big_decimal(transaction.execute.value));
l2_contract_addresses.push(transaction.execute.contract_address.as_bytes());
l2_contract_addresses.push(contract_address_b);
l2_paymaster_input.push(&common_data.paymaster_params.paymaster_input[..]);
l2_paymaster.push(common_data.paymaster_params.paymaster.as_bytes());
l2_hashes.push(tx_res.hash.as_bytes());
Expand Down Expand Up @@ -821,7 +846,7 @@ impl TransactionsDal<'_, '_> {
&l2_inputs as &[&[u8]],
&l2_datas,
&l2_tx_formats,
&l2_contract_addresses as &[&[u8]],
&l2_contract_addresses,
&l2_values,
&l2_paymaster as &[&[u8]],
&l2_paymaster_input as &[&[u8]],
Expand Down Expand Up @@ -904,8 +929,15 @@ impl TransactionsDal<'_, '_> {
.arg_error(&format!("transactions[{index_in_block}].refunded_gas"), err)
})?;

let contract_address = transaction.execute.contract_address;
let unwrapped_contract_address = contract_address.unwrap_or_default();
let contract_address_b: Vec<u8> = if contract_address.is_none() {
Vec::new()
} else {
unwrapped_contract_address.as_bytes().to_vec()
};
l2_values.push(u256_to_big_decimal(transaction.execute.value));
l2_contract_addresses.push(transaction.execute.contract_address.as_bytes());
l2_contract_addresses.push(contract_address_b);
l2_paymaster_input.push(&common_data.paymaster_params.paymaster_input[..]);
l2_paymaster.push(common_data.paymaster_params.paymaster.as_bytes());
l2_hashes.push(tx_res.hash.as_bytes());
Expand Down Expand Up @@ -1016,7 +1048,7 @@ impl TransactionsDal<'_, '_> {
&l2_datas,
&l2_refunded_gas,
&l2_values,
&l2_contract_addresses as &[&[u8]],
&l2_contract_addresses,
&l2_paymaster as &[&[u8]],
&l2_paymaster_input as &[&[u8]],
l2_block_number.0 as i32,
Expand Down Expand Up @@ -1086,6 +1118,13 @@ impl TransactionsDal<'_, '_> {
.arg_error(&format!("transactions[{index_in_block}].refunded_gas"), err)
})?;

let contract_address = transaction.execute.contract_address;
let unwrapped_contract_address = contract_address.unwrap_or_default();
let contract_address_b: Vec<u8> = if contract_address.is_none() {
Vec::new()
} else {
unwrapped_contract_address.as_bytes().to_vec()
};
let tx = &tx_res.transaction;
l1_hashes.push(tx_res.hash.as_bytes());
l1_initiator_address.push(common_data.sender.as_bytes());
Expand All @@ -1099,7 +1138,7 @@ impl TransactionsDal<'_, '_> {
l1_priority_op_id.push(common_data.serial_id.0 as i64);
l1_full_fee.push(u256_to_big_decimal(common_data.full_fee));
l1_layer_2_tip_fee.push(u256_to_big_decimal(common_data.layer_2_tip_fee));
l1_contract_address.push(tx.execute.contract_address.as_bytes());
l1_contract_address.push(contract_address_b);
l1_l1_block_number.push(common_data.eth_block as i32);
l1_value.push(u256_to_big_decimal(tx.execute.value));
l1_tx_format.push(common_data.tx_format() as i32);
Expand Down Expand Up @@ -1206,7 +1245,7 @@ impl TransactionsDal<'_, '_> {
&l1_priority_op_id,
&l1_full_fee,
&l1_layer_2_tip_fee,
&l1_contract_address as &[&[u8]],
&l1_contract_address,
&l1_l1_block_number,
&l1_value,
&l1_tx_format,
Expand Down Expand Up @@ -1376,6 +1415,14 @@ impl TransactionsDal<'_, '_> {
.arg_error(&format!("transactions[{index_in_block}].refunded_gas"), err)
})?;

let contract_address = transaction.execute.contract_address;
let unwrapped_contract_address = contract_address.unwrap_or_default();
let contract_address_b: Vec<u8> = if contract_address.is_none() {
Vec::new()
} else {
unwrapped_contract_address.as_bytes().to_vec()
};

let tx = &tx_res.transaction;
upgrade_hashes.push(tx_res.hash.as_bytes());
upgrade_initiator_address.push(common_data.sender.as_bytes());
Expand All @@ -1388,7 +1435,7 @@ impl TransactionsDal<'_, '_> {
.unwrap_or_else(|_| panic!("cannot serialize tx {:?} to json", tx.hash())),
);
upgrade_upgrade_id.push(common_data.upgrade_id as i32);
upgrade_contract_address.push(tx.execute.contract_address.as_bytes());
upgrade_contract_address.push(contract_address_b);
upgrade_l1_block_number.push(common_data.eth_block as i32);
upgrade_value.push(u256_to_big_decimal(tx.execute.value));
upgrade_tx_format.push(common_data.tx_format() as i32);
Expand Down Expand Up @@ -1487,7 +1534,7 @@ impl TransactionsDal<'_, '_> {
&upgrade_gas_per_pubdata_limit,
&upgrade_data,
&upgrade_upgrade_id,
&upgrade_contract_address as &[&[u8]],
&upgrade_contract_address,
&upgrade_l1_block_number,
&upgrade_value,
&upgrade_tx_format,
Expand Down
3 changes: 3 additions & 0 deletions core/lib/env_config/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ mod tests {
default_aa_hash: Some(hash(
"0x0100055b041eb28aff6e3a6e0f37c31fd053fc9ef142683b05e5f0aee6934066",
)),
evm_simulator_hash: Some(hash(
"0x01000f197081a9906cc411d0698c4961aeb5c74877f37f7071681da6e8ef3f31",
)),
l1_batch_commit_data_generator_mode,
max_circuits_per_batch: 24100,
protective_reads_persistence_enabled: true,
Expand Down
4 changes: 2 additions & 2 deletions core/lib/mempool/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ fn gen_l2_tx(address: Address, nonce: Nonce) -> Transaction {

fn gen_l2_tx_with_timestamp(address: Address, nonce: Nonce, received_at_ms: u64) -> Transaction {
let mut txn = L2Tx::new(
Address::default(),
Address::default().into(),
Vec::new(),
nonce,
Fee::default(),
Expand All @@ -386,7 +386,7 @@ fn gen_l2_tx_with_timestamp(address: Address, nonce: Nonce, received_at_ms: u64)

fn gen_l1_tx(priority_id: PriorityOpId) -> Transaction {
let execute = Execute {
contract_address: Address::repeat_byte(0x11),
contract_address: Address::repeat_byte(0x11).into(),
calldata: vec![1, 2, 3],
factory_deps: vec![],
value: U256::zero(),
Expand Down
2 changes: 1 addition & 1 deletion core/lib/multivm/src/versions/vm_1_3_2/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ pub fn get_create_execute(code: &[u8], calldata: &[u8]) -> Execute {
.expect("failed to encode parameters");

Execute {
contract_address: CONTRACT_DEPLOYER_ADDRESS,
contract_address: Some(CONTRACT_DEPLOYER_ADDRESS),
calldata,
factory_deps: vec![code.to_vec()],
value: U256::zero(),
Expand Down
6 changes: 3 additions & 3 deletions core/lib/multivm/src/versions/vm_1_3_2/transaction_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::vm_1_3_2::vm_with_bootloader::{
pub struct TransactionData {
pub tx_type: u8,
pub from: Address,
pub to: Address,
pub to: Option<Address>,
pub gas_limit: U256,
pub pubdata_price_limit: U256,
pub max_fee_per_gas: U256,
Expand Down Expand Up @@ -170,7 +170,7 @@ impl TransactionData {
encode(&[Token::Tuple(vec![
Token::Uint(U256::from_big_endian(&self.tx_type.to_be_bytes())),
Token::Address(self.from),
Token::Address(self.to),
Token::Address(self.to.unwrap_or_default()),
Token::Uint(self.gas_limit),
Token::Uint(self.pubdata_price_limit),
Token::Uint(self.max_fee_per_gas),
Expand Down Expand Up @@ -593,7 +593,7 @@ mod tests {
let transaction = TransactionData {
tx_type: 113,
from: Address::random(),
to: Address::random(),
to: Address::random().into(),
gas_limit: U256::from(1u32),
pubdata_price_limit: U256::from(1u32),
max_fee_per_gas: U256::from(1u32),
Expand Down
Loading

0 comments on commit 2a10e16

Please sign in to comment.