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

Optimism RPC Types #2

Merged
merged 25 commits into from
Apr 27, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0582d5c
chore: add serde and alloy_primitives to the dependencies
EmperorOrokuSaki Apr 10, 2024
dbdcda9
feat: add transaction receipt type without tests + several dependencies.
EmperorOrokuSaki Apr 10, 2024
1ebd0e0
feat: add log
EmperorOrokuSaki Apr 10, 2024
15eb436
feat: add txtype, deposit nonce, and receipt version.
EmperorOrokuSaki Apr 10, 2024
599c9a2
feat: add block.
EmperorOrokuSaki Apr 10, 2024
2def3b0
feat: add txType as a separate file under transactions and update rec…
EmperorOrokuSaki Apr 10, 2024
6b0c42a
refactor: update optimism specific fields and their (de)serialization…
EmperorOrokuSaki Apr 10, 2024
87742c3
docs: remove outdated documentation.
EmperorOrokuSaki Apr 10, 2024
516eb59
feat: add transaction, and request types. Adjust block to use the cra…
EmperorOrokuSaki Apr 10, 2024
fafe2aa
feat: add op-consensus and receiptEnvelope
EmperorOrokuSaki Apr 11, 2024
2599060
feat: add call.rs and update visibility of transaction requests, type…
EmperorOrokuSaki Apr 11, 2024
d5c9b78
lint: cargo fmt.
EmperorOrokuSaki Apr 11, 2024
b9169e9
feat: add pubsub.rs
EmperorOrokuSaki Apr 12, 2024
f1675b9
feat: fix imports, add TODO comments, organize the code.
EmperorOrokuSaki Apr 12, 2024
d939344
lint: cargo fmt
EmperorOrokuSaki Apr 12, 2024
5dbd2f5
fix: receipt.rs imports are fixed.
EmperorOrokuSaki Apr 12, 2024
2304918
feat: add filters.rs
EmperorOrokuSaki Apr 12, 2024
2ad3438
feat: re-export all eth types.
EmperorOrokuSaki Apr 12, 2024
6a72e80
feat: review changes.
EmperorOrokuSaki Apr 15, 2024
93141f0
refactor: re-import instead of redefining.
EmperorOrokuSaki Apr 18, 2024
b5005c9
chore: bump alloy version.
EmperorOrokuSaki Apr 20, 2024
577749e
feat: use generics, remove unnecessary types.
EmperorOrokuSaki Apr 20, 2024
0744884
lint: fmt
EmperorOrokuSaki Apr 20, 2024
12195e1
refactor: use native types
EmperorOrokuSaki Apr 25, 2024
cf248d4
chore: bump alloy version
EmperorOrokuSaki Apr 25, 2024
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
21 changes: 21 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,27 @@ homepage = "https://github.com/alloy-rs/op-alloy"
repository = "https://github.com/alloy-rs/op-alloy"
exclude = ["benches/", "tests/"]

[workspace.dependencies]
# Alloy
alloy-primitives = { version = "0.7.0", default-features = false }
alloy = { git = "https://github.com/alloy-rs/alloy", rev = "89f14f9", features = [
"serde",
"rpc-types-eth",
"rpc-types","rlp","consensus"
] }
op-consensus = { version = "0.1.0", default-features = false, path = "crates/op-consensus" }
op-rpc-types = { version = "0.1.0", default-features = false, path = "crates/op-rpc-types" }

# Serde
serde = { version = "1.0", default-features = false, features = ["derive", "alloc"] }
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }

## misc-testing
arbitrary = { version = "1.3", features = ["derive"] }
rand = "0.8"
proptest = "1.4"
proptest-derive = "0.4"

[workspace.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
34 changes: 34 additions & 0 deletions crates/op-consensus/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[package]
name = "op-consensus"
description = "Optimism Consensus"

version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
homepage.workspace = true
authors.workspace = true
repository.workspace = true
exclude.workspace = true

[dependencies]
alloy-primitives = { workspace = true, features = ["rlp"] }
alloy = { workspace = true , features = ["serde", "rpc-types", "rpc-types-eth"]}

sha2 = { version = "0.10", default-features = false }

# arbitrary
arbitrary = { workspace = true, features = ["derive"], optional = true }

# serde
serde = { workspace = true, features = ["derive"], optional = true }
serde_json.workspace = true

[features]
serde = ["dep:serde"]

[dev-dependencies]
arbitrary = { workspace = true, features = ["derive"] }
proptest.workspace = true
proptest-derive.workspace = true
rand.workspace = true
1 change: 1 addition & 0 deletions crates/op-consensus/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod receipt;
196 changes: 196 additions & 0 deletions crates/op-consensus/src/receipt/envelope.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
use alloy::{
consensus::{Receipt, ReceiptWithBloom},
rpc::types::eth::Log,
};
use alloy_primitives::Bloom;

/// Receipt envelope, as defined in [EIP-2718].
///
/// This enum distinguishes between tagged and untagged legacy receipts, as the
/// in-protocol merkle tree may commit to EITHER 0-prefixed or raw. Therefore
/// we must ensure that encoding returns the precise byte-array that was
/// decoded, preserving the presence or absence of the `TransactionType` flag.
///
/// Transaction receipt payloads are specified in their respective EIPs.
///
/// [EIP-2718]: https://eips.ethereum.org/EIPS/eip-2718
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(tag = "type"))]
#[non_exhaustive]
pub enum ReceiptEnvelope<T = Log> {
/// Receipt envelope with no type flag.
#[cfg_attr(feature = "serde", serde(rename = "0x0", alias = "0x00"))]
Legacy(ReceiptWithBloom<T>),
/// Receipt envelope with type flag 1, containing a [EIP-2930] receipt.
///
/// [EIP-2930]: https://eips.ethereum.org/EIPS/eip-2930
#[cfg_attr(feature = "serde", serde(rename = "0x1", alias = "0x01"))]
Eip2930(ReceiptWithBloom<T>),
/// Receipt envelope with type flag 2, containing a [EIP-1559] receipt.
///
/// [EIP-1559]: https://eips.ethereum.org/EIPS/eip-1559
#[cfg_attr(feature = "serde", serde(rename = "0x2", alias = "0x02"))]
Eip1559(ReceiptWithBloom<T>),
/// Receipt envelope with type flag 2, containing a [EIP-4844] receipt.
///
/// [EIP-4844]: https://eips.ethereum.org/EIPS/eip-4844
#[cfg_attr(feature = "serde", serde(rename = "0x3", alias = "0x03"))]
Eip4844(ReceiptWithBloom<T>),
/// Receipt envelope for Optimism's deposit transactions
#[cfg_attr(feature = "serde", serde(rename = "0x7E", alias = "0x7E"))]
EmperorOrokuSaki marked this conversation as resolved.
Show resolved Hide resolved
Deposit(ReceiptWithBloom<T>),
}

impl<T> ReceiptEnvelope<T> {
/// Return the [`TxType`] of the inner receipt.
pub const fn tx_type(&self) -> TxType {
match self {
Self::Legacy(_) => TxType::Legacy,
Self::Eip2930(_) => TxType::Eip2930,
Self::Eip1559(_) => TxType::Eip1559,
Self::Eip4844(_) => TxType::Eip4844,
}
EmperorOrokuSaki marked this conversation as resolved.
Show resolved Hide resolved
}

/// Return true if the transaction was successful.
pub fn is_success(&self) -> bool {
self.status()
}

/// Returns the success status of the receipt's transaction.
pub fn status(&self) -> bool {
self.as_receipt().unwrap().status
}

/// Returns the cumulative gas used at this receipt.
pub fn cumulative_gas_used(&self) -> u128 {
self.as_receipt().unwrap().cumulative_gas_used
}

/// Return the receipt logs.
pub fn logs(&self) -> &[T] {
&self.as_receipt().unwrap().logs
}

/// Return the receipt's bloom.
pub fn logs_bloom(&self) -> &Bloom {
&self.as_receipt_with_bloom().unwrap().logs_bloom
}

/// Return the inner receipt with bloom. Currently this is infallible,
/// however, future receipt types may be added.
pub const fn as_receipt_with_bloom(&self) -> Option<&ReceiptWithBloom<T>> {
match self {
Self::Legacy(t) | Self::Eip2930(t) | Self::Eip1559(t) | Self::Eip4844(t) => Some(t),
}
}

/// Return the inner receipt. Currently this is infallible, however, future
/// receipt types may be added.
pub const fn as_receipt(&self) -> Option<&Receipt<T>> {
match self {
Self::Legacy(t) | Self::Eip2930(t) | Self::Eip1559(t) | Self::Eip4844(t) => {
Some(&t.receipt)
}
}
}
}

impl ReceiptEnvelope {
/// Get the length of the inner receipt in the 2718 encoding.
pub fn inner_length(&self) -> usize {
self.as_receipt_with_bloom().unwrap().length()
}

/// Calculate the length of the rlp payload of the network encoded receipt.
pub fn rlp_payload_length(&self) -> usize {
let length = self.as_receipt_with_bloom().unwrap().length();
match self {
Self::Legacy(_) => length,
_ => length + 1,
}
}
}

impl Encodable for ReceiptEnvelope {
fn encode(&self, out: &mut dyn alloy_rlp::BufMut) {
self.network_encode(out)
}

fn length(&self) -> usize {
let mut payload_length = self.rlp_payload_length();
if !self.is_legacy() {
payload_length += length_of_length(payload_length);
}
payload_length
}
}

impl Decodable for ReceiptEnvelope {
fn decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
match Self::network_decode(buf) {
Ok(t) => Ok(t),
Err(_) => Err(alloy_rlp::Error::Custom("Unexpected type")),
}
}
}

impl Encodable2718 for ReceiptEnvelope {
fn type_flag(&self) -> Option<u8> {
match self {
Self::Legacy(_) => None,
Self::Eip2930(_) => Some(TxType::Eip2930 as u8),
Self::Eip1559(_) => Some(TxType::Eip1559 as u8),
Self::Eip4844(_) => Some(TxType::Eip4844 as u8),
}
}

fn encode_2718_len(&self) -> usize {
self.inner_length() + !self.is_legacy() as usize
}

fn encode_2718(&self, out: &mut dyn BufMut) {
match self.type_flag() {
None => {}
Some(ty) => out.put_u8(ty),
}
self.as_receipt_with_bloom().unwrap().encode(out);
}
}

impl Decodable2718 for ReceiptEnvelope {
fn typed_decode(ty: u8, buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
let receipt = Decodable::decode(buf)?;
match ty.try_into().map_err(|_| alloy_rlp::Error::Custom("Unexpected type"))? {
TxType::Eip2930 => Ok(Self::Eip2930(receipt)),
TxType::Eip1559 => Ok(Self::Eip1559(receipt)),
TxType::Eip4844 => Ok(Self::Eip4844(receipt)),
TxType::Legacy => {
Err(alloy_rlp::Error::Custom("type-0 eip2718 transactions are not supported"))
}
}
}

fn fallback_decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
Ok(Self::Legacy(Decodable::decode(buf)?))
}
}

#[cfg(any(test, feature = "arbitrary"))]
impl<'a, T> arbitrary::Arbitrary<'a> for ReceiptEnvelope<T>
where
T: arbitrary::Arbitrary<'a>,
{
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
let receipt = ReceiptWithBloom::<T>::arbitrary(u)?;

match u.int_in_range(0..=3)? {
0 => Ok(Self::Legacy(receipt)),
1 => Ok(Self::Eip2930(receipt)),
2 => Ok(Self::Eip1559(receipt)),
3 => Ok(Self::Eip4844(receipt)),
_ => unreachable!(),
}
}
}
1 change: 1 addition & 0 deletions crates/op-consensus/src/receipt/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod envelope;
33 changes: 33 additions & 0 deletions crates/op-rpc-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,36 @@ homepage.workspace = true
authors.workspace = true
repository.workspace = true
exclude.workspace = true

[dependencies]
op-consensus = { workspace = true, features = ["serde"]}
# alloy-rlp = { workspace = true, features = ["arrayvec", "derive"] }
alloy-primitives = { workspace = true, features = ["rlp", "serde", "std"] }
# alloy-serde.workspace = true
# alloy-genesis.workspace = true

# alloy-consensus = { workspace = true, features = ["std", "serde"] }
# alloy-eips = { workspace = true, features = ["std", "serde"] }
EmperorOrokuSaki marked this conversation as resolved.
Show resolved Hide resolved

serde = { workspace = true, features = ["derive"] }
alloy = { workspace = true , features = ["serde", "rpc-types", "rpc-types-eth", "rlp", "consensus"]}
serde_json.workspace = true

# arbitrary
arbitrary = { version = "1.3", features = ["derive"], optional = true }
proptest = { version = "1.4", optional = true }
proptest-derive = { version = "0.4", optional = true }

[features]
arbitrary = [
"dep:arbitrary",
"dep:proptest-derive",
"dep:proptest",
"alloy-primitives/arbitrary",
]

[dev-dependencies]
arbitrary = { workspace = true, features = ["derive"] }
proptest.workspace = true
proptest-derive.workspace = true
rand.workspace = true
2 changes: 1 addition & 1 deletion crates/op-rpc-types/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@

mod op;
Loading
Loading