Skip to content
Merged
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
2 changes: 2 additions & 0 deletions scenarios/scenarios.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/ethpandaops/spamoor/scenarios/geastx"
"github.com/ethpandaops/spamoor/scenarios/setcodetx"
erc20bloater "github.com/ethpandaops/spamoor/scenarios/statebloat/erc20_bloater"
storagetriebrancher "github.com/ethpandaops/spamoor/scenarios/statebloat/storage_trie_brancher"
"github.com/ethpandaops/spamoor/scenarios/storagespam"
"github.com/ethpandaops/spamoor/scenarios/taskrunner"
uniswapswaps "github.com/ethpandaops/spamoor/scenarios/uniswap-swaps"
Expand All @@ -44,6 +45,7 @@ var ScenarioDescriptors = []*scenario.Descriptor{
&gasburnertx.ScenarioDescriptor,
&geastx.ScenarioDescriptor,
&setcodetx.ScenarioDescriptor,
&storagetriebrancher.ScenarioDescriptor,
&storagespam.ScenarioDescriptor,
&taskrunner.ScenarioDescriptor,
&uniswapswaps.ScenarioDescriptor,
Expand Down
203 changes: 203 additions & 0 deletions scenarios/statebloat/storage_trie_brancher/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
# Depth Benchmark Tests

This directory contains tests for worst-case depth attacks on Ethereum state and account tries.

## Scenario Description

These benchmarks test the worst-case scenario for Ethereum clients when dealing with extremely deep state and account tries. The attack involves:

1. **Pre-deployed contracts** with deep storage tries that maximize trie traversal costs
2. **CREATE2-based addressing** for deterministic contract addresses across test runs
3. **Optimized batched attacks** using an AttackOrchestrator contract that can execute up to 2,510 attacks per transaction (8.3x improvement over previous implementation)
4. **Account trie depth** increased by funding auxiliary accounts that make the path deeper

The test measures the performance impact of state root recomputation and IO when modifying deep storage slots across thousands of contracts, simulating the maximum theoretical load on the state trie.

For complete deployment setup and instructions, see the gist: https://gist.github.com/CPerezz/44d521c0f9e6adf7d84187a4f2c11978

## Prerequisites

- Python with `uv` package manager
- Anvil (Ethereum node implementation)
- Solc (Solidity compiler)
- Nick's factory deployed at `0x4e59b44847b379578588920ca78fbf26c0b4956c`

## Workflow

### Step 1: Generate Artifacts

Use [worst_case_miner](https://github.com/CPerezz/worst_case_miner) to generate the necessary artifacts:

```bash
# Clone and build worst_case_miner
git clone https://github.com/CPerezz/worst_case_miner
cd worst_case_miner
cargo build --release

# Generate artifacts (example for depth 9, account depth 3)
./target/release/worst_case_miner --storage-depth 9 --account-depth 3 --output s9_acc3.json
```

This generates:
- `depth_9.sol` - Solidity contract with deep storage trie
- `s9_acc3.json` - Pre-computed CREATE2 addresses and auxiliary accounts

### Step 2: Start the Node (Anvil in this example)

```bash
# Start Anvil with high gas limit and auto-mining
anvil --hardfork prague --block-time 6 --steps-tracing --gas-limit 500000000 --balance 99999999999999 --port 8545
```

### Step 3: Deploy Contracts

Deploy contracts using the provided script with batched transactions:

```bash
# Deploy 1,000 contracts (recommended for testing)
uv run python deploy_worst_case_contracts.py \
--rpc-url http://localhost:8546 \
--private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \
--storage-depth 9 \
--account-depth 3 \
--num-contracts 1000 \
--output deployed_contracts.json


The script:
- Funds auxiliary accounts in batches (3 accounts per contract)
- Deploys contracts via CREATE2 for deterministic addresses
- Dynamically calculates batch sizes based on network gas limit

### Step 4: Run Attack Test

Execute the worst-case depth attack test:

```bash
# Update NUM_CONTRACTS in deep_branch_testing.py to match deployed count (1000 or 15000)

# Run the attack test
uv run execute remote \
--rpc-endpoint=http://localhost:8546 \
--rpc-seed-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \
--rpc-chain-id=31337 \
--gas-benchmark-values 60 \
--fork Prague \
-m stateful \
deep_branch_testing.py::test_worst_depth_stateroot_recomp
```

## Spamoor Scenario Usage

### Command Line Usage

```bash
./bin/spamoor storage-trie-brancher \
--count 1000 \
--storage-depth 10 \
--account-depth 5 \
--data-file "https://example.com/s10_acc5.json" \
--bytecode "https://example.com/depth_10.bin" \
--rpchost http://localhost:8545 \
--privkey 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \
--seed "test-seed" \
--basefee 20 \
--tipfee 2 \
--max-wallets 50
```

Note: Both `--data-file` and `--bytecode` are required parameters and can be:
- Local file paths
- HTTP/HTTPS URLs
- For bytecode: direct hex string (e.g., "0x608060...")

### YAML Configuration Example

Create a file `storage_trie_brancher_config.yaml`:

```yaml
scenarios:
- name: storage-trie-brancher
config:
# Number of contracts to deploy
total_contracts: 1000

# Storage trie depth (9 or 10)
storage_depth: 10

# Account trie depth (3, 4, or 5)
account_depth: 5

# Maximum number of wallets for parallel execution
max_wallets: 50

# Skip contract deployment (only fund EOAs)
skip_contracts: false

# Skip EOA funding (only deploy contracts)
skip_funding: false

# Path or URL to CREATE2 data JSON file (required)
# Can be a local file path or HTTP/HTTPS URL
data_file: "https://raw.githubusercontent.com/example/repo/main/s10_acc5.json"

# Contract bytecode (required)
# Can be:
# - Direct hex string: "0x608060405260..."
# - Local file path: "./bytecode.bin"
# - URL: "https://raw.githubusercontent.com/example/repo/main/depth_10.bin"
bytecode: "https://raw.githubusercontent.com/example/repo/main/depth_10.bin"

# Gas settings (in gwei)
base_fee: 20
tip_fee: 2

# Client group for transaction routing (optional)
client_group: ""

# Log all submitted transactions
log_txs: true
```

Run with the YAML config:

```bash
# Using spamoor directly with config file
./bin/spamoor storage-trie-brancher \
--config storage_trie_brancher_config.yaml \
--rpchost http://localhost:8545 \
--privkey 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \
--seed "test-seed"

# Or using spamoor-daemon for web interface
./bin/spamoor-daemon \
--rpchost http://localhost:8545 \
--privkey 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \
--scenario-file storage_trie_brancher_config.yaml
```

### Using External URLs

The scenario supports loading files from external sources:

```yaml
scenarios:
- name: storage-trie-brancher
config:
total_contracts: 5000
storage_depth: 10
account_depth: 5
max_wallets: 100

# Load from GitHub raw URLs or any HTTP server
data_file: "https://raw.githubusercontent.com/CPerezz/worst-case-artifacts/main/s10_acc5.json"
bytecode: "https://raw.githubusercontent.com/CPerezz/worst-case-artifacts/main/depth_10.bin"

base_fee: 20
tip_fee: 2
log_txs: true
```

## Configuration

Adjust `NUM_CONTRACTS` in `deep_branch_testing.py` to match your deployment:
Loading