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
130 changes: 130 additions & 0 deletions espresso/cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package espresso

import (
"crypto/ecdsa"
"fmt"
"strings"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/urfave/cli/v2"
)

// espressoFlags returns the flag names for espresso
func espressoFlags(v string) string {
return "espresso." + v
}

func espressoEnvs(envprefix, v string) []string {
return []string{envprefix + "_ESPRESSO_" + v}
}

var (
EnabledFlagName = espressoFlags("enabled")
PollIntervalFlagName = espressoFlags("poll-interval")
UseFetchApiFlagName = espressoFlags("fetch-api")
QueryServiceUrlsFlagName = espressoFlags("urls")
LightClientAddrFlagName = espressoFlags("light-client-addr")
L1UrlFlagName = espressoFlags("l1-url")
TestingBatcherPrivateKeyFlagName = espressoFlags("testing-batcher-private-key")
)

func CLIFlags(envPrefix string, category string) []cli.Flag {
return []cli.Flag{
&cli.BoolFlag{
Name: EnabledFlagName,
Usage: "Enable Espresso mode",
Value: false,
EnvVars: espressoEnvs(envPrefix, "ENABLED"),
Category: category,
},
&cli.DurationFlag{
Name: PollIntervalFlagName,
Usage: "Polling interval for Espresso queries",
Value: 250 * time.Millisecond,
EnvVars: espressoEnvs(envPrefix, "POLL_INTERVAL"),
Category: category,
},
&cli.BoolFlag{
Name: UseFetchApiFlagName,
Usage: "Use fetch API for Espresso queries",
Value: false,
EnvVars: espressoEnvs(envPrefix, "FETCH_API"),
Category: category,
},
&cli.StringSliceFlag{
Name: QueryServiceUrlsFlagName,
Usage: "Comma-separated list of Espresso query service URLs",
EnvVars: espressoEnvs(envPrefix, "URLS"),
Category: category,
},
&cli.StringFlag{
Name: LightClientAddrFlagName,
Usage: "Address of the Espresso light client",
EnvVars: espressoEnvs(envPrefix, "LIGHT_CLIENT_ADDR"),
Category: category,
},
&cli.StringFlag{
Name: L1UrlFlagName,
Usage: "L1 RPC URL Espresso contracts are deployed on",
EnvVars: espressoEnvs(envPrefix, "L1_URL"),
Category: category,
},
&cli.StringFlag{
Name: TestingBatcherPrivateKeyFlagName,
Usage: "Pre-approved batcher ephemeral key (testing only)",
EnvVars: espressoEnvs(envPrefix, "TESTING_BATCHER_PRIVATE_KEY"),
Category: category,
},
}
}

type CLIConfig struct {
Enabled bool
PollInterval time.Duration
UseFetchAPI bool
QueryServiceURLs []string
LightClientAddr common.Address
L1URL string
TestingBatcherPrivateKey *ecdsa.PrivateKey
}

func (c CLIConfig) Check() error {
if c.Enabled {
// Check required fields when Espresso is enabled
if len(c.QueryServiceURLs) == 0 {
return fmt.Errorf("query service URLs are required when Espresso is enabled")
}
if c.LightClientAddr == (common.Address{}) {
return fmt.Errorf("light client address is required when Espresso is enabled")
}
if c.L1URL == "" {
return fmt.Errorf("L1 URL is required when Espresso is enabled")
}
}
return nil
}

func ReadCLIConfig(c *cli.Context) CLIConfig {
config := CLIConfig{
Enabled: c.Bool(EnabledFlagName),
PollInterval: c.Duration(PollIntervalFlagName),
UseFetchAPI: c.Bool(UseFetchApiFlagName),
L1URL: c.String(L1UrlFlagName),
}

config.QueryServiceURLs = c.StringSlice(QueryServiceUrlsFlagName)

addrStr := c.String(LightClientAddrFlagName)
config.LightClientAddr = common.HexToAddress(addrStr)

pkStr := c.String(TestingBatcherPrivateKeyFlagName)
pkStr = strings.TrimPrefix(pkStr, "0x")
pk, err := crypto.HexToECDSA(pkStr)
if err == nil {
config.TestingBatcherPrivateKey = pk
}

return config
}
49 changes: 26 additions & 23 deletions espresso/docker-compose.yml
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As commented on Asana: https://app.asana.com/1/1208976916964769/task/1211756453742026/comment/1211764601533943?focus=true, I think we need another task to update the Terraform based on the changes here. I can probably work on this in parallel.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm already working on that, I'm currently experimenting with TF stuff, so no need to pick this up separately
I guess we could make this a separate task, but it's basically just find-replacing a couple argument names, not sure we need to explicitly track this

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just created a task: https://app.asana.com/1/1208976916964769/project/1209392461754458/task/1211764601533955?focus=true. But no need to complete it now. Feel free to experiment with Terraform more.

There were a few times when we forgot to update Terraform after changes to the Docker Compose, so I'd like to have something on Asana so we won't forget.

Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ services:
l1-genesis:
condition: service_completed_successfully
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:${L1_HTTP_PORT}" ]
test: ["CMD", "curl", "-f", "http://localhost:${L1_HTTP_PORT}"]
interval: 3s
timeout: 2s
retries: 40
Expand Down Expand Up @@ -191,7 +191,7 @@ services:
dockerfile: espresso/docker/op-stack/Dockerfile
target: op-node-target
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:${ROLLUP_PORT}" ]
test: ["CMD", "curl", "-f", "http://localhost:${ROLLUP_PORT}"]
interval: 3s
timeout: 2s
retries: 40
Expand Down Expand Up @@ -233,7 +233,7 @@ services:
dockerfile: espresso/docker/op-stack/Dockerfile
target: op-node-target
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:${VERIFIER_PORT}" ]
test: ["CMD", "curl", "-f", "http://localhost:${VERIFIER_PORT}"]
interval: 3s
timeout: 2s
retries: 40
Expand Down Expand Up @@ -271,7 +271,7 @@ services:
dockerfile: espresso/docker/op-stack/Dockerfile
target: op-node-target
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:${CAFF_PORT}" ]
test: ["CMD", "curl", "-f", "http://localhost:${CAFF_PORT}"]
interval: 3s
timeout: 2s
retries: 40
Expand All @@ -287,9 +287,9 @@ services:
OP_NODE_L1_ETH_RPC: http://l1-geth:${L1_HTTP_PORT}
OP_NODE_L1_BEACON: http://l1-beacon:${L1_BEACON_PORT}
OP_NODE_L2_ENGINE_RPC: http://op-geth-caff-node:${OP_ENGINE_PORT}
OP_NODE_CAFF_L1_ETH_RPC: http://l1-geth:${L1_HTTP_PORT}
OP_NODE_CAFF_ESPRESSO_LIGHT_CLIENT_ADDR: "0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797"
OP_NODE_CAFF_HOTSHOT_URLS: http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT},http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT}
OP_NODE_ESPRESSO_L1_URL: http://l1-geth:${L1_HTTP_PORT}
OP_NODE_ESPRESSO_LIGHT_CLIENT_ADDR: "0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797"
OP_NODE_ESPRESSO_URLS: http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT},http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT}
OP_NODE_RPC_PORT: ${CAFF_PORT}
ports:
- "${CAFF_PORT}:${CAFF_PORT}"
Expand All @@ -301,22 +301,21 @@ services:
- --rollup.config=/config/rollup.json
- --rpc.addr=0.0.0.0
- --sequencer.enabled=false
- --caff.node=true
- --espresso.enabled=true
- --verifier.l1-confs=0
- --rollup.load-protocol-versions=false
- --rollup.halt=none
- --l1.trustrpc=true
- --rpc.enable-admin=true
- --caff.next-hotshot-block-num=1
- --caff.polling-hotshot-polling-interval=500ms
- --espresso.poll-interval=500ms
- --log.level=debug
- --p2p.disable=true
- --l1.http-poll-interval=1s
- --l1.epoch-poll-interval=1s
restart: "no"

op-batcher:
profiles: [ "default" ]
profiles: ["default"]
build:
context: ../
dockerfile: espresso/docker/op-stack/Dockerfile
Expand All @@ -339,30 +338,35 @@ services:
OP_BATCHER_L1_ETH_RPC: http://l1-geth:${L1_HTTP_PORT}
OP_BATCHER_L2_ETH_RPC: http://op-geth-sequencer:${OP_HTTP_PORT}
OP_BATCHER_ROLLUP_RPC: http://op-node-sequencer:${ROLLUP_PORT}
OP_BATCHER_ESPRESSO_URL: http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT},http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT}
OP_BATCHER_ESPRESSO_URLS: http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT},http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT}
volumes:
- ../packages/contracts-bedrock/lib/superchain-registry/ops/testdata/monorepo:/config
command:
- op-batcher
- --espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797
- --testing-espresso-batcher-private-key=${OP_TESTING_BATCHER_PRIVATE_KEY:-$OPERATOR_PRIVATE_KEY}
- --espresso.enabled=true
- --espresso.poll-interval=1s
- --espresso.light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797
- --espresso.testing-batcher-private-key=${OP_TESTING_BATCHER_PRIVATE_KEY:-$OPERATOR_PRIVATE_KEY}
- --private-key=${OP_BATCHER_PRIVATE_KEY:-$OPERATOR_PRIVATE_KEY}
- --throttle-threshold=0
- --max-channel-duration=2
- --target-num-frames=1
- --max-pending-tx=32
- --altda.max-concurrent-da-requests=32
- --espresso-poll-interval=1s

op-batcher-tee:
profiles: [ "tee" ]
profiles: ["tee"]
build:
context: ../
dockerfile: espresso/docker/op-stack/Dockerfile
target: op-batcher-enclave-target
image: op-batcher-tee:espresso
healthcheck:
test: [ "CMD-SHELL", "test -f /tmp/enclave-tools.pid && kill -0 $(cat /tmp/enclave-tools.pid) 2>/dev/null || exit 1" ]
test:
[
"CMD-SHELL",
"test -f /tmp/enclave-tools.pid && kill -0 $(cat /tmp/enclave-tools.pid) 2>/dev/null || exit 1",
]
interval: 30s
timeout: 10s
retries: 3
Expand Down Expand Up @@ -408,7 +412,7 @@ services:
/source/espresso/docker/op-batcher-tee/run-enclave.sh

op-proposer:
profiles: [ "default" ]
profiles: ["default"]
build:
context: ../
dockerfile: espresso/docker/op-stack/Dockerfile
Expand All @@ -432,10 +436,10 @@ services:
OP_PROPOSER_PROPOSAL_INTERVAL: 6s
OP_PROPOSER_MNEMONIC: "test test test test test test test test test test test junk"
OP_PROPOSER_HD_PATH: "m/44'/60'/0'/0/1"
OP_PROPOSER_GAME_TYPE: '1'
OP_PROPOSER_GAME_TYPE: "1"

op-proposer-tee:
profiles: [ "tee" ]
profiles: ["tee"]
build:
context: ../
dockerfile: espresso/docker/op-stack/Dockerfile
Expand All @@ -459,11 +463,10 @@ services:
OP_PROPOSER_PROPOSAL_INTERVAL: 6s
OP_PROPOSER_MNEMONIC: "test test test test test test test test test test test junk"
OP_PROPOSER_HD_PATH: "m/44'/60'/0'/0/1"
OP_PROPOSER_GAME_TYPE: '1'

OP_PROPOSER_GAME_TYPE: "1"

op-challenger:
profiles: [ "default" ]
profiles: ["default"]
build:
context: ../
dockerfile: espresso/docker/op-stack/Dockerfile
Expand Down
8 changes: 4 additions & 4 deletions espresso/docker/op-batcher-tee/run-enclave.sh
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a reminder to @dailinsubjam: you may need to sync with this PR (or main if it's merged) before working on the shared script task for the TEE batcher.

Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ echo "====================================="
BATCHER_ARGS="--l1-eth-rpc=$L1_RPC_URL"
BATCHER_ARGS="$BATCHER_ARGS,--l2-eth-rpc=$L2_RPC_URL"
BATCHER_ARGS="$BATCHER_ARGS,--rollup-rpc=$ROLLUP_RPC_URL"
BATCHER_ARGS="$BATCHER_ARGS,--espresso-url=$ESPRESSO_URL1"
BATCHER_ARGS="$BATCHER_ARGS,--espresso-url=$ESPRESSO_URL2"
BATCHER_ARGS="$BATCHER_ARGS,--testing-espresso-batcher-private-key=$OPERATOR_PRIVATE_KEY"
BATCHER_ARGS="$BATCHER_ARGS,--espresso.enabled=true"
BATCHER_ARGS="$BATCHER_ARGS,--espresso.urls=$ESPRESSO_URL1"
BATCHER_ARGS="$BATCHER_ARGS,--espresso.urls=$ESPRESSO_URL2"
BATCHER_ARGS="$BATCHER_ARGS,--mnemonic=test test test test test test test test test test test junk"
BATCHER_ARGS="$BATCHER_ARGS,--hd-path=m/44'/60'/0'/0/0"
BATCHER_ARGS="$BATCHER_ARGS,--throttle-threshold=0"
BATCHER_ARGS="$BATCHER_ARGS,--max-channel-duration=1"
BATCHER_ARGS="$BATCHER_ARGS,--target-num-frames=1"
BATCHER_ARGS="$BATCHER_ARGS,--espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797"
BATCHER_ARGS="$BATCHER_ARGS,--espresso.light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797"

# Add debug arguments if enabled
if [ "$ENCLAVE_DEBUG" = "true" ]; then
Expand Down
19 changes: 12 additions & 7 deletions espresso/environment/enclave_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"testing"
"time"

"github.com/ethereum-optimism/optimism/espresso"
altda "github.com/ethereum-optimism/optimism/op-alt-da"
"github.com/ethereum-optimism/optimism/op-batcher/batcher"
"github.com/ethereum-optimism/optimism/op-batcher/bindings"
Expand Down Expand Up @@ -92,6 +93,7 @@ func LaunchBatcherInEnclave() E2eDevnetLauncherOption {
l1Rpc := sys.L1.UserRPC().(endpoint.HttpRPC).HttpRPC()
appendArg(&args, flags.L1EthRpcFlag.Name, l1Rpc)
appendArg(&args, txmgr.L1RPCFlagName, l1Rpc)
appendArg(&args, espresso.L1UrlFlagName, l1Rpc)
l2EthRpc := sys.EthInstances[e2esys.RoleSeq].UserRPC().(endpoint.HttpRPC).HttpRPC()
appendArg(&args, flags.L2EthRpcFlag.Name, l2EthRpc)
rollupRpc := sys.RollupNodes[e2esys.RoleSeq].UserRPC().(endpoint.HttpRPC).HttpRPC()
Expand All @@ -105,8 +107,6 @@ func LaunchBatcherInEnclave() E2eDevnetLauncherOption {
appendArg(&args, flags.CompressionAlgoFlag.Name, c.CompressionAlgo.String())
appendArg(&args, flags.CompressorFlag.Name, c.Compressor)
appendArg(&args, flags.DataAvailabilityTypeFlag.Name, c.DataAvailabilityType.String())
appendArg(&args, flags.EspressoLCAddrFlag.Name, c.EspressoLightClientAddr)
appendArg(&args, flags.EspressoPollIntervalFlag.Name, c.EspressoPollInterval)
appendArg(&args, flags.MaxBlocksPerSpanBatch.Name, c.MaxBlocksPerSpanBatch)
appendArg(&args, flags.MaxChannelDurationFlag.Name, c.MaxChannelDuration)
appendArg(&args, flags.MaxL1TxSizeBytesFlag.Name, c.MaxL1TxSize)
Expand All @@ -120,11 +120,6 @@ func LaunchBatcherInEnclave() E2eDevnetLauncherOption {
appendArg(&args, flags.ThrottleThresholdFlag.Name, c.ThrottleThreshold)
appendArg(&args, flags.ThrottleTxSizeFlag.Name, c.ThrottleTxSize)
appendArg(&args, flags.WaitNodeSyncFlag.Name, c.WaitNodeSync)
for _, url := range c.EspressoUrls {
appendArg(&args, flags.EspressoUrlsFlag.Name, url)
}
appendArg(&args, flags.EspressoLCAddrFlag.Name, c.EspressoLightClientAddr)
appendArg(&args, flags.TestingEspressoBatcherPrivateKeyFlag.Name, c.TestingEspressoBatcherPrivateKey)

// TxMgr flags
appendArg(&args, txmgr.MnemonicFlagName, c.TxMgrConfig.Mnemonic)
Expand Down Expand Up @@ -175,6 +170,16 @@ func LaunchBatcherInEnclave() E2eDevnetLauncherOption {
appendArg(&args, altda.GetTimeoutFlagName, c.AltDA.GetTimeout)
appendArg(&args, altda.MaxConcurrentRequestsFlagName, c.AltDA.MaxConcurrentRequests)

// Espresso flags
appendArg(&args, espresso.EnabledFlagName, c.Espresso.Enabled)
appendArg(&args, espresso.PollIntervalFlagName, c.Espresso.PollInterval)
appendArg(&args, espresso.LightClientAddrFlagName, c.Espresso.LightClientAddr)
appendArg(&args, espresso.TestingBatcherPrivateKeyFlagName, hexutil.Encode(crypto.FromECDSA(c.Espresso.TestingBatcherPrivateKey)))
appendArg(&args, espresso.UseFetchApiFlagName, c.Espresso.UseFetchAPI)
for _, url := range c.Espresso.QueryServiceURLs {
appendArg(&args, espresso.QueryServiceUrlsFlagName, url)
}

err := SetupEnclaver(ct.Ctx, sys, args...)
if err != nil {
panic(fmt.Sprintf("failed to setup enclaver: %v", err))
Expand Down
15 changes: 8 additions & 7 deletions espresso/environment/espresso_caff_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ import (
"testing"
"time"

"github.com/ethereum-optimism/optimism/espresso"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/opnode"
"github.com/ethereum-optimism/optimism/op-e2e/system/e2esys"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum/go-ethereum/common"
)

const (
Expand Down Expand Up @@ -111,13 +112,13 @@ func LaunchCaffNode(t *testing.T, system *e2esys.System, espressoDevNode Espress

caffNodeConfig := *system.Cfg.Nodes[e2esys.RoleVerif]
caffNodeConfig.Rollup = *system.RollupConfig
caffNodeConfig.Rollup.CaffNodeConfig = rollup.CaffNodeConfig{
IsCaffNode: true,
PollingHotShotPollingInterval: 30 * time.Millisecond,
caffNodeConfig.Rollup.CaffNodeConfig = espresso.CLIConfig{
Enabled: true,
PollInterval: 30 * time.Millisecond,
// To create a valid multiple nodes client, we need to provide at least 2 URLs.
HotShotUrls: []string{u.String(), u.String()},
L1EthRpc: system.L1.UserRPC().RPC(),
EspressoLightClientAddr: ESPRESSO_LIGHT_CLIENT_ADDRESS,
QueryServiceURLs: []string{u.String(), u.String()},
L1URL: system.L1.UserRPC().RPC(),
LightClientAddr: common.HexToAddress(ESPRESSO_LIGHT_CLIENT_ADDRESS),
}

// Configure
Expand Down
Loading
Loading