Skip to content

Commit

Permalink
chore: odyssey_sendTransaction (#56)
Browse files Browse the repository at this point in the history
resolving #50 `wallet_sendTransaction` to
`wallet_odyssey_sendTransaction`

note: personally fan of `<namespace>_odyssey_*` as this contains eip's
suggestion `wallet_sendTransaction`

edit: q. saw foundry PR have alias `odyssey_sendTransaction` maybe i
should match into the one?
  • Loading branch information
rkdud007 authored Oct 23, 2024
1 parent a267080 commit db98fc9
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 19 deletions.
26 changes: 15 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,44 @@

<!-- [![Crates.io][crates-badge]][crates-io] -->
<!-- [![Downloads][downloads-badge]][crates-io] -->

[![MIT License][mit-badge]][mit-url]
[![Apache-2.0 License][apache-badge]][apache-url]
[![CI Status][actions-badge]][actions-url]

## 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
Expand Down Expand Up @@ -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
Expand All @@ -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

Expand All @@ -171,6 +174,7 @@ shall be dual licensed as above, without any additional terms or conditions.
<!-- [crates-badge]: https://img.shields.io/crates/v/odyssey.svg -->
<!-- [crates-io]: https://crates.io/crates/odyssey -->
<!-- [downloads-badge]: https://img.shields.io/crates/d/odyssey -->

[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
Expand Down
44 changes: 44 additions & 0 deletions crates/e2e-tests/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,47 @@ async fn test_wallet_api() -> Result<(), Box<dyn std::error::Error>> {

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<dyn std::error::Error>> {
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<U256, BTreeMap<String, BTreeMap<String, Vec<Address>>>> =
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(())
}
18 changes: 10 additions & 8 deletions crates/wallet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<TxHash>;
}

Expand Down Expand Up @@ -211,7 +213,7 @@ where
}

async fn send_transaction(&self, mut request: TransactionRequest) -> RpcResult<TxHash> {
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) {
Expand Down Expand Up @@ -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,
}

Expand Down

0 comments on commit db98fc9

Please sign in to comment.