diff --git a/README.md b/README.md index 57424ae..8b6c498 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ + [![MIT License][mit-badge]][mit-url] [![Apache-2.0 License][apache-badge]][apache-url] [![CI Status][actions-badge]][actions-url] @@ -9,34 +10,36 @@ ## What is Odyssey? Odyssey is a testnet OP Stack rollup aimed at enabling experimentation of bleeding edge Ethereum Research. -Odyssey is __not__ a fork of reth. +Odyssey is **not** a fork of reth. Odyssey implements traits provided by the [reth node builder API](https://paradigmxyz.github.io/reth/docs/reth_node_builder/index.html), allowing implementation of precompiles and instructions of experimental EIPs without forking the node. Specifically, Odyssey currently implements the following EIPs: - - [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702): Set EOA account code. - - [RIP-7212](https://ethereum-magicians.org/t/eip-7212-precompiled-for-secp256r1-curve-support/14789): Precompile for secp256r1 curve support. - - [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537): Precompiles for BLS12-381 curve operations. + +- [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702): Set EOA account code. +- [RIP-7212](https://ethereum-magicians.org/t/eip-7212-precompiled-for-secp256r1-curve-support/14789): Precompile for secp256r1 curve support. +- [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537): Precompiles for BLS12-381 curve operations. Odyssey also implements the EIPs for EOF, or [The EVM Object Format](https://evmobjectformat.org/). ### Why Odyssey? Odyssey has 2 goals: + 1. Showcase Reth's performance at the extremes. We intend to launch a hosted version of Odyssey on [Conduit](https://conduit.xyz/), targeting 50mgas/s, and eventually ramping up to 1ggas/s and beyond. In the process we hope to hit the state growth performance bottleneck, and discover ways to solve it. If our hosted chains end up getting too big, we may possibly restart the experiment from zero, and try again. 2. Showcase how Reth's modular architecture can serve as a distribution channel for research ideas. Specifically, -Odyssey's node extensions were chosen for their ability to enable applications that enhance the onchain user experience, and -drastically reduce cost for existing applications that improve UX. + Odyssey's node extensions were chosen for their ability to enable applications that enhance the onchain user experience, and + drastically reduce cost for existing applications that improve UX. ### Odyssey Testnet -> [!TIP] -> [The Odyssey Testnet](https://www.ithaca.xyz/updates/odyssey#odyssey-chapter-1-is-live-on-testnet) is now live on Sepolia and is built with Reth, the OP Stack, and [deployed on Conduit](https://app.conduit.xyz/published/view/odyssey). +> [!TIP] > [The Odyssey Testnet](https://www.ithaca.xyz/updates/odyssey#odyssey-chapter-1-is-live-on-testnet) is now live on Sepolia and is built with Reth, the OP Stack, and [deployed on Conduit](https://app.conduit.xyz/published/view/odyssey). ### Odyssey Local Development Odyssey can be run locally for development and testing purposes. To do this, the binary can be run with the `--dev` flag, which will start the node with a development configuration. First, odyssey should be built locally: + ```bash git clone https://github.com/ithacaxyz/odyssey cd odyssey @@ -130,12 +133,12 @@ Consult the [Kurtosis OP package](https://github.com/ethpandaops/optimism-packag Odyssey has a custom `wallet_` namespace, that allows users to delegate their EOAs to a contract using EIP-7702, and perform transactions on those accounts, all funded by the sequencer. -To enable this namespace, set the environment variable `EXP1_SK` to a private key that will sign the transactions, and `EXP1_WHITELIST` to a comma-delimited list of checksummed addresses accounts are allowed to delegate to. The new RPC method, `wallet_sendTransaction`, will only sign transactions that either: +To enable this namespace, set the environment variable `EXP1_SK` to a private key that will sign the transactions, and `EXP1_WHITELIST` to a comma-delimited list of checksummed addresses accounts are allowed to delegate to. The new RPC method, `odyssey_sendTransaction`, will only sign transactions that either: 1. Delegate accounts to one of the whitelisted addresses using EIP-7702, or 1. Send transactions to an EIP-7702 EOA that is already delegated to a whitelisted address -The `wallet_sendTransaction` endpoint accepts the same fields as `eth_sendTransaction`, with these notable exceptions: +The `odyssey_sendTransaction` endpoint accepts the same fields as `eth_sendTransaction`, with these notable exceptions: 1. `nonce` must not be set, as this is managed by the node 1. `value` must be unset or 0 @@ -147,7 +150,7 @@ The following fields are ignored, as they are overwritten internally: 1. `gasLimit` 1. `chainId` -To get the list of contracts that are whitelisted for `wallet_sendTransaction`, you can query `wallet_getCapabilities`. +To get the list of contracts that are whitelisted for `odyssey_sendTransaction`, you can query `wallet_getCapabilities`. ### Security @@ -171,6 +174,7 @@ shall be dual licensed as above, without any additional terms or conditions. + [mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg [apache-badge]: https://img.shields.io/badge/license-Apache--2.0-blue.svg [mit-url]: LICENSE-MIT diff --git a/crates/e2e-tests/src/tests.rs b/crates/e2e-tests/src/tests.rs index 8749a89..b96820c 100644 --- a/crates/e2e-tests/src/tests.rs +++ b/crates/e2e-tests/src/tests.rs @@ -83,3 +83,47 @@ async fn test_wallet_api() -> Result<(), Box> { Ok(()) } + +// This is new endpoint `odyssey_sendTransaction`, upper test will be deprecate in the future. +#[tokio::test] +async fn test_new_wallet_api() -> Result<(), Box> { + if !ci_info::is_ci() { + return Ok(()); + } + + let provider = ProviderBuilder::new().on_http(REPLICA_RPC.clone()); + let signer = PrivateKeySigner::from_bytes(&b256!( + "59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d" + ))?; + + let capabilities: BTreeMap>>> = + provider.client().request_noparams("wallet_getCapabilities").await?; + + let chain_id = U256::from(provider.get_chain_id().await?); + + let delegation_address = + capabilities.get(&chain_id).unwrap().get("delegation").unwrap().get("addresses").unwrap() + [0]; + + let auth = Authorization { + chain_id: provider.get_chain_id().await?, + address: delegation_address, + nonce: provider.get_transaction_count(signer.address()).await?, + }; + + let signature = signer.sign_hash_sync(&auth.signature_hash())?; + let auth = auth.into_signed(signature); + + let tx = + TransactionRequest::default().with_authorization_list(vec![auth]).with_to(signer.address()); + + let tx_hash: B256 = provider.client().request("odyssey_sendTransaction", vec![tx]).await?; + + let receipt = PendingTransactionBuilder::new(provider.clone(), tx_hash).get_receipt().await?; + + assert!(receipt.status()); + + assert!(!provider.get_code_at(signer.address()).await?.is_empty()); + + Ok(()) +} diff --git a/crates/wallet/src/lib.rs b/crates/wallet/src/lib.rs index c39839a..5988224 100644 --- a/crates/wallet/src/lib.rs +++ b/crates/wallet/src/lib.rs @@ -4,13 +4,15 @@ //! //! - `wallet_getCapabilities` based on [EIP-5792][eip-5792], with the only capability being //! `delegation`. -//! - `wallet_sendTransaction` that can perform sequencer-sponsored [EIP-7702][eip-7702] delegations -//! and send other sequencer-sponsored transactions on behalf of EOAs with delegated code. +//! - `odyssey_sendTransaction` that can perform sequencer-sponsored [EIP-7702][eip-7702] +//! delegations and send other sequencer-sponsored transactions on behalf of EOAs with delegated +//! code. //! //! # Restrictions //! -//! `wallet_sendTransaction` has additional verifications in place to prevent some rudimentary abuse -//! of the sequencer's funds. For example, transactions cannot contain any `value`. +//! `odyssey_sendTransaction` has additional verifications in place to prevent some +//! rudimentary abuse of the sequencer's funds. For example, transactions cannot contain any +//! `value`. //! //! [eip-5792]: https://eips.ethereum.org/EIPS/eip-5792 //! [eip-7702]: https://eips.ethereum.org/EIPS/eip-7702 @@ -98,7 +100,7 @@ pub trait OdysseyWalletApi { /// /// [eip-7702]: https://eips.ethereum.org/EIPS/eip-7702 /// [eip-1559]: https://eips.ethereum.org/EIPS/eip-1559 - #[method(name = "sendTransaction")] + #[method(name = "sendTransaction", aliases = ["odyssey_sendTransaction"])] async fn send_transaction(&self, request: TransactionRequest) -> RpcResult; } @@ -211,7 +213,7 @@ where } async fn send_transaction(&self, mut request: TransactionRequest) -> RpcResult { - trace!(target: "rpc::wallet", ?request, "Serving wallet_sendTransaction"); + trace!(target: "rpc::wallet", ?request, "Serving odyssey_sendTransaction"); // validate fields common to eip-7702 and eip-1559 if let Err(err) = validate_tx_request(&request) { @@ -379,9 +381,9 @@ fn validate_tx_request(request: &TransactionRequest) -> Result<(), OdysseyWallet #[derive(Metrics)] #[metrics(scope = "wallet")] struct WalletMetrics { - /// Number of invalid calls to `wallet_sendTransaction` + /// Number of invalid calls to `odyssey_sendTransaction` invalid_send_transaction_calls: Counter, - /// Number of valid calls to `wallet_sendTransaction` + /// Number of valid calls to `odyssey_sendTransaction` valid_send_transaction_calls: Counter, }