Skip to content
This repository has been archived by the owner on Oct 10, 2023. It is now read-only.

feat: op-zeth #1

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
4 changes: 4 additions & 0 deletions lib/src/host/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ pub fn get_initial_data(
let provider_db =
crate::host::provider_db::ProviderDb::new(provider, init_block.number.unwrap().as_u64());

info!("Created provider db ...");

// Create input
let input = Input {
beneficiary: fini_block.author.map(from_ethers_h160).unwrap_or_default(),
Expand All @@ -120,6 +122,8 @@ pub fn get_initial_data(
..Default::default()
};

info!("Created input: {:?}", input);

// Create the block builder, run the transactions and extract the DB
let mut builder = BlockBuilder::new(&ETH_MAINNET_CHAIN_SPEC, input)
.with_db(provider_db)
Expand Down
1 change: 1 addition & 0 deletions primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ serde_json = "1.0"
[features]
ethers = ["dep:ethers-core"]
revm = ["dep:revm-primitives"]
optimism = ["dep:revm-primitives"]
3 changes: 3 additions & 0 deletions primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ pub mod ethers;
#[cfg(feature = "revm")]
pub mod revm;

#[cfg(feature = "optimism")]
pub mod optimism;

pub use alloy_primitives::*;
pub use alloy_rlp as rlp;

Expand Down
162 changes: 162 additions & 0 deletions primitives/src/optimism.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
// Copyright 2023 RISC Zero, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use alloy_primitives::{Address, Bytes, TxHash};
use alloy_rlp::{Encodable, EMPTY_STRING_CODE};
use serde::{Deserialize, Serialize};

use crate::transaction::TransactionKind;

// use reth_codecs::{main_codec, Compact};
// use reth_rlp::{length_of_length, Decodable, DecodeError, Encodable, Header,
// EMPTY_STRING_CODE};

/// Deposit transactions, also known as deposits, are initiated on L1, and executed on L2.
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
pub struct TxDeposit {
/// Hash that uniquely identifies the source of the deposit.
pub source_hash: TxHash,
/// The address of the sender account.
pub from: Address,
/// The address of the recipient account, or the null (zero-length) address if the
/// deposited transaction is a contract creation.
pub to: TransactionKind,
/// The ETH value to mint on L2.
pub mint: Option<u128>,
/// The ETH value to send to the recipient account.
pub value: u128,
/// The gas limit for the L2 transaction.
pub gas_limit: u64,
/// Field indicating if this transaction is exempt from the L2 gas limit.
pub is_system_transaction: bool,
/// Input has two uses depending if transaction is Create or Call (if `to` field is
/// None or Some).
pub input: Bytes,
}

impl TxDeposit {
/// Computes the length of the RLP-encoded payload in bytes.
///
/// This method calculates the combined length of all the individual fields
/// of the transaction when they are RLP-encoded.
pub(crate) fn payload_length(&self) -> usize {
let mut len = 0;
len += self.source_hash.length();
len += self.from.length();
len += self.to.length();
len += self.mint.map_or(1, |mint| mint.length());
len += self.value.length();
len += self.gas_limit.length();
len += self.is_system_transaction.length();
len += self.input.0.length();
len
}

/// Encodes the transaction into the provided `out` buffer for the purpose of signing.
pub(crate) fn signing_encode(&self, out: &mut dyn alloy_rlp::BufMut) {
self.encode(out);
}

/// Computes the length of the RLP-encoded transaction essence in bytes for signing.
///
/// This method calculates the total length of the transaction when it is RLP-encoded,
/// including any additional bytes required for the encoding format.
pub(crate) fn signing_length(&self) -> usize {
let payload_length = self.payload_length();
// 'tx type' + 'header length' + 'payload length'
let len = 1 + alloy_rlp::length_of_length(payload_length) + payload_length;
alloy_rlp::length_of_length(len) + len
}

/// Encodes only the transaction's fields into the desired buffer, without a RLP
/// header. <https://github.com/ethereum-optimism/optimism/blob/develop/specs/deposits.md#the-deposited-transaction-type>
pub(crate) fn encode_fields(&self, out: &mut dyn bytes::BufMut) {
self.source_hash.encode(out);
self.from.encode(out);
self.to.encode(out);
if let Some(mint) = self.mint {
mint.encode(out);
} else {
out.put_u8(EMPTY_STRING_CODE);
}
self.value.encode(out);
self.gas_limit.encode(out);
self.is_system_transaction.encode(out);
self.input.encode(out);
}

/// Get the transaction type
pub(crate) fn tx_type(&self) -> u8 {
0x7e
}
}

// Implement the Encodable trait for `TxDeposit`.
impl Encodable for TxDeposit {
/// Encodes the [TxDeposit] instance into the provided `out` buffer.
fn encode(&self, out: &mut dyn alloy_rlp::BufMut) {
let payload_length = self.payload_length();
// if with_header {
// alloy_rlp::Header {
// list: false,
// payload_length: 1 + alloy_rlp::length_of_length(payload_length) +
// payload_length, }
// .encode(out);
// }
out.put_u8(self.tx_type());
let header = alloy_rlp::Header {
list: true,
payload_length,
};
header.encode(out);
self.encode_fields(out);
}

/// Computes the length of the RLP-encoded [TxDeposit] instance in bytes.
///
/// This method calculates the total length of the transaction when it is RLP-encoded.
fn length(&self) -> usize {
let payload_length = self.payload_length();
// 'tx type' + 'header length' + 'payload length'
let len = 1 + alloy_rlp::length_of_length(payload_length) + payload_length;
alloy_rlp::length_of_length(len) + len
}
}

// #[cfg(test)]
// mod tests {
// use crate::{Bytes, TransactionSigned};
// use bytes::BytesMut;
// use reth_rlp::Decodable;
// use revm_primitives::hex_literal::hex;
//
// #[test]
// fn test_rlp_roundtrip() {
// let bytes =
// hex!("7ef9015aa044bae9d41b8380d781187b426c6fe43df5fb2fb57bd4466ef6a701e1f01e015694deaddeaddeaddeaddeaddeaddeaddeaddead000194420000000000000000000000000000000000001580808408f0d18001b90104015d8eb900000000000000000000000000000000000000000000000000000000008057650000000000000000000000000000000000000000000000000000000063d96d10000000000000000000000000000000000000000000000000000000000009f35273d89754a1e0387b89520d989d3be9c37c1f32495a88faf1ea05c61121ab0d1900000000000000000000000000000000000000000000000000000000000000010000000000000000000000002d679b567db6187c0c8323fa982cfb88b74dbcc7000000000000000000000000000000000000000000000000000000000000083400000000000000000000000000000000000000000000000000000000000f4240"
// );
//
// let tx_a =
// TransactionSigned::decode_enveloped(Bytes::from(&bytes[..])).unwrap(); let tx_b
// = TransactionSigned::decode(&mut &bytes[..]).unwrap();
//
// let mut buf_a = BytesMut::default();
// tx_a.encode_enveloped(&mut buf_a);
// assert_eq!(&buf_a[..], &bytes[..]);
//
// let mut buf_b = BytesMut::default();
// tx_b.encode_enveloped(&mut buf_b);
// assert_eq!(&buf_b[..], &bytes[..]);
// }
// }
24 changes: 24 additions & 0 deletions primitives/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ use alloy_rlp::{Encodable, EMPTY_STRING_CODE};
use alloy_rlp_derive::RlpEncodable;
use serde::{Deserialize, Serialize};

#[cfg(feature = "optimism")]
use crate::optimism::TxDeposit;
use crate::{access_list::AccessList, keccak::keccak, signature::TxSignature};

/// Represents a legacy Ethereum transaction as detailed in [EIP-155](https://eips.ethereum.org/EIPS/eip-155).
Expand Down Expand Up @@ -218,6 +220,9 @@ pub enum TxEssence {
/// This mechanism aims to improve the predictability of gas fees and enhances the
/// overall user experience.
Eip1559(TxEssenceEip1559),
/// Optimism deposit transaction.
#[cfg(feature = "optimism")]
Deposit(TxDeposit),
}

// Implement the Encodable trait for the TxEssence enum.
Expand All @@ -232,6 +237,8 @@ impl Encodable for TxEssence {
TxEssence::Legacy(tx) => tx.encode(out),
TxEssence::Eip2930(tx) => tx.encode(out),
TxEssence::Eip1559(tx) => tx.encode(out),
#[cfg(feature = "optimism")]
TxEssence::Deposit(tx) => tx.encode(out),
}
}

Expand All @@ -244,6 +251,8 @@ impl Encodable for TxEssence {
TxEssence::Legacy(tx) => tx.length(),
TxEssence::Eip2930(tx) => tx.length(),
TxEssence::Eip1559(tx) => tx.length(),
#[cfg(feature = "optimism")]
TxEssence::Deposit(tx) => tx.length(),
}
}
}
Expand Down Expand Up @@ -281,6 +290,13 @@ impl TxEssence {
tx.encode(&mut buf);
buf
}
#[cfg(feature = "optimism")]
TxEssence::Deposit(tx) => {
let mut buf = Vec::with_capacity(tx.length() + 1);
buf.push(0x7e);
tx.encode(&mut buf);
buf
}
}
}

Expand All @@ -294,6 +310,8 @@ impl TxEssence {
TxEssence::Legacy(tx) => tx.payload_length(),
TxEssence::Eip2930(tx) => tx._alloy_rlp_payload_length(),
TxEssence::Eip1559(tx) => tx._alloy_rlp_payload_length(),
#[cfg(feature = "optimism")]
TxEssence::Deposit(tx) => tx.payload_length(),
}
}
}
Expand Down Expand Up @@ -442,6 +460,8 @@ impl Transaction {
TxEssence::Legacy(_) => 0x00,
TxEssence::Eip2930(_) => 0x01,
TxEssence::Eip1559(_) => 0x02,
#[cfg(feature = "optimism")]
TxEssence::Deposit(_) => 0x7e,
}
}

Expand All @@ -454,6 +474,8 @@ impl Transaction {
TxEssence::Legacy(tx) => tx.gas_limit,
TxEssence::Eip2930(tx) => tx.gas_limit,
TxEssence::Eip1559(tx) => tx.gas_limit,
#[cfg(feature = "optimism")]
TxEssence::Deposit(tx) => U256::from(tx.gas_limit),
}
}

Expand All @@ -466,6 +488,8 @@ impl Transaction {
TxEssence::Legacy(tx) => tx.to.into(),
TxEssence::Eip2930(tx) => tx.to.into(),
TxEssence::Eip1559(tx) => tx.to.into(),
#[cfg(feature = "optimism")]
TxEssence::Deposit(tx) => tx.to.into(),
}
}
}
Expand Down