Skip to content

Commit

Permalink
Cherry-pick kona structs that we are using for interop validation
Browse files Browse the repository at this point in the history
Implement SupervisorValidator to be used in rbuilder
Add additional primitives crate, that is used for storing external code
  • Loading branch information
SozinM committed Mar 5, 2025
1 parent 4ea890f commit 141120a
Show file tree
Hide file tree
Showing 14 changed files with 354 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ ethereum_ssz_derive = "0.8"
ethereum_ssz = "0.8"

alloy-primitives = { version = "0.8.15", default-features = false }
alloy-sol-types = { version = "0.8.15", default-features = false }
alloy-rlp = "0.3.10"
alloy-chains = "0.1.33"
alloy-provider = { version = "0.11.1", features = ["ipc", "pubsub"] }
Expand Down
2 changes: 2 additions & 0 deletions crates/op-rbuilder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ alloy-rpc-types-eth.workspace = true
alloy-rpc-client.workspace = true
alloy-transport.workspace = true
alloy-network.workspace = true
alloy-sol-types.workspace = true

# op
op-alloy-consensus.workspace = true
Expand Down Expand Up @@ -85,6 +86,7 @@ alloy-serde = "0.7"
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "json"] }

rollup-boost = { git = "http://github.com/flashbots/rollup-boost", rev = "e74a1fd01366e4ddd13515da4efda59cdc8fbce0" }
thiserror = "2.0.11"

[target.'cfg(unix)'.dependencies]
tikv-jemallocator = { version = "0.6", optional = true }
Expand Down
1 change: 1 addition & 0 deletions crates/op-rbuilder/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod integration;
pub mod primitives;
pub mod tester;
pub mod tx_signer;
1 change: 1 addition & 0 deletions crates/op-rbuilder/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ mod payload_builder_vanilla;
#[cfg(test)]
mod tester;
mod tx_signer;
mod primitives;

fn main() {
Cli::<OpChainSpecParser, args::OpRbuilderArgs>::parse()
Expand Down
15 changes: 15 additions & 0 deletions crates/op-rbuilder/src/primitives/kona/api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//! [Source](https://github.com/op-rs/kona/blob/a1d8ea603960cb4bd3cc19784f7c3365352f1849/crates/node/rpc/src/api.rs)
use crate::primitives::kona::{ExecutingMessage, SafetyLevel};
use jsonrpsee::{core::RpcResult, proc_macros::rpc};

/// Supervisor API for interop.
#[rpc(server, client, namespace = "supervisor")]
pub trait SupervisorApi {
/// Checks if the given messages meet the given minimum safety level.
#[method(name = "checkMessages")]
async fn check_messages(
&self,
messages: Vec<ExecutingMessage>,
min_safety: SafetyLevel,
) -> RpcResult<()>;
}
6 changes: 6 additions & 0 deletions crates/op-rbuilder/src/primitives/kona/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//! [Source](https://github.com/op-rs/kona/blob/a1d8ea603960cb4bd3cc19784f7c3365352f1849/crates/protocol/interop/src/constants.rs)
use alloy_primitives::{address, Address};

/// The address of the L2 cross chain inbox predeploy proxy.
pub const CROSS_L2_INBOX_ADDRESS: Address = address!("4200000000000000000000000000000000000022");
68 changes: 68 additions & 0 deletions crates/op-rbuilder/src/primitives/kona/message.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//! [Source](https://github.com/op-rs/kona/blob/a1d8ea603960cb4bd3cc19784f7c3365352f1849/crates/protocol/interop/src/message.rs)
use alloy_primitives::{keccak256, Bytes, Log};
use alloy_sol_types::{sol};
use derive_more::{AsRef, From};

sol! {
/// @notice The struct for a pointer to a message payload in a remote (or local) chain.
#[derive(Default, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
struct MessageIdentifier {
address origin;
uint256 blockNumber;
uint256 logIndex;
uint256 timestamp;
#[serde(rename = "chainID")]
uint256 chainId;
}

/// @notice Emitted when a cross chain message is being executed.
/// @param payloadHash Hash of message payload being executed.
/// @param identifier Encoded Identifier of the message.
///
/// Parameter names are derived from the `op-supervisor` JSON field names.
/// See the relevant definition in the Optimism repository:
/// [Ethereum-Optimism/op-supervisor](https://github.com/ethereum-optimism/optimism/blob/4ba2eb00eafc3d7de2c8ceb6fd83913a8c0a2c0d/op-supervisor/supervisor/types/types.go#L61-L64).
#[derive(Default, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
event ExecutingMessage(bytes32 indexed payloadHash, MessageIdentifier identifier);

/// @notice Executes a cross chain message on the destination chain.
/// @param _id Identifier of the message.
/// @param _target Target address to call.
/// @param _message Message payload to call target with.
function executeMessage(
MessageIdentifier calldata _id,
address _target,
bytes calldata _message
) external;
}

/// A [RawMessagePayload] is the raw payload of an initiating message.
#[derive(Debug, Clone, From, AsRef, PartialEq, Eq)]
pub struct RawMessagePayload(Bytes);

impl From<&Log> for RawMessagePayload {
fn from(log: &Log) -> Self {
let mut data = vec![0u8; log.topics().len() * 32 + log.data.data.len()];
for (i, topic) in log.topics().iter().enumerate() {
data[i * 32..(i + 1) * 32].copy_from_slice(topic.as_ref());
}
data[(log.topics().len() * 32)..].copy_from_slice(log.data.data.as_ref());
data.into()
}
}

impl From<Vec<u8>> for RawMessagePayload {
fn from(data: Vec<u8>) -> Self {
Self(Bytes::from(data))
}
}

impl From<executeMessageCall> for ExecutingMessage {
fn from(call: executeMessageCall) -> Self {
Self {
identifier: call._id,
payloadHash: keccak256(call._message.as_ref()),
}
}
}
12 changes: 12 additions & 0 deletions crates/op-rbuilder/src/primitives/kona/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
pub mod traits;
pub use traits::{ExecutingMessageValidator, ExecutingMessageValidatorError};
pub mod supervisor;
pub use supervisor::SupervisorValidator;
pub mod safety;
pub use safety::SafetyLevel;
pub mod api;
pub use api::SupervisorApiClient;
pub mod message;
pub use message::ExecutingMessage;
pub mod constants;
pub use constants::CROSS_L2_INBOX_ADDRESS;
41 changes: 41 additions & 0 deletions crates/op-rbuilder/src/primitives/kona/safety.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//! [Source](https://github.com/op-rs/kona/blob/a1d8ea603960cb4bd3cc19784f7c3365352f1849/crates/protocol/interop/src/safety.rs)
use derive_more::Display;
/// The safety level of a message.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Display, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum SafetyLevel {
/// The message is finalized.
Finalized,
/// The message is safe.
Safe,
/// The message is safe locally.
LocalSafe,
/// The message is unsafe across chains.
CrossUnsafe,
/// The message is unsafe.
Unsafe,
/// The message is invalid.
Invalid,
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_safety_level_serde() {
let level = SafetyLevel::Finalized;
let json = serde_json::to_string(&level).unwrap();
assert_eq!(json, r#""finalized""#);

let level: SafetyLevel = serde_json::from_str(&json).unwrap();
assert_eq!(level, SafetyLevel::Finalized);
}

#[test]
fn test_serde_safety_level_fails() {
let json = r#""failed""#;
let level: Result<SafetyLevel, _> = serde_json::from_str(json);
assert!(level.is_err());
}
}
12 changes: 12 additions & 0 deletions crates/op-rbuilder/src/primitives/kona/supervisor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//! This is our custom implementation of validator struct
use crate::primitives::kona::ExecutingMessageValidator;
use jsonrpsee::http_client::HttpClient;
use std::time::Duration;

pub struct SupervisorValidator;

impl ExecutingMessageValidator for SupervisorValidator {
type SupervisorClient = HttpClient;
const DEFAULT_TIMEOUT: Duration = Duration::from_millis(100);
}
Loading

0 comments on commit 141120a

Please sign in to comment.