Skip to content

Commit 48f85d0

Browse files
authored
da: optionally support new tx client (#517)
1 parent 345f7c0 commit 48f85d0

File tree

10 files changed

+218
-32
lines changed

10 files changed

+218
-32
lines changed

op-batcher/batcher/driver.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1089,7 +1089,7 @@ func (l *BatchSubmitter) celestiaTxCandidate(ctx context.Context, data []byte) (
10891089
if err != nil {
10901090
return nil, err
10911091
}
1092-
height, err := l.DAClient.Client.Blob.Submit(ctx, []*blob.Blob{b}, state.NewTxConfig(state.WithGasPrice(l.DAClient.GasPrice)))
1092+
height, err := l.DAClient.Client.Submit(ctx, []*blob.Blob{b}, state.NewTxConfig(state.WithGasPrice(l.DAClient.GasPrice)))
10931093
if err != nil {
10941094
return nil, err
10951095
}

op-batcher/batcher/service.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ func (bs *BatcherService) initDA(cfg *CLIConfig) error {
461461
return nil
462462
}
463463

464-
client, err := celestia.NewDAClient(cfg.DaConfig.Rpc, cfg.DaConfig.AuthToken, cfg.DaConfig.Namespace, cfg.DaConfig.FallbackMode, cfg.DaConfig.GasPrice)
464+
client, err := celestia.NewDAClient(cfg.DaConfig.CelestiaConfig())
465465
if err != nil {
466466
return err
467467
}

op-celestia/cli.go

Lines changed: 122 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package celestia
22

33
import (
44
"encoding/hex"
5+
"errors"
56
"fmt"
67
"net/url"
78
"os"
@@ -25,6 +26,8 @@ const (
2526
const (
2627
// RPCFlagName defines the flag for the rpc url
2728
RPCFlagName = "da.rpc"
29+
// TLSEnabledFlagName defines the flag for whether rpc TLS is enabled
30+
TLSEnabledFlagName = "da.tls-enabled"
2831
// AuthTokenFlagName defines the flag for the auth token
2932
AuthTokenFlagName = "da.auth_token"
3033
// NamespaceFlagName defines the flag for the namespace
@@ -36,6 +39,14 @@ const (
3639
// GasPriceFlagName defines the flag for gas price
3740
GasPriceFlagName = "da.gas_price"
3841

42+
// tx client config flags
43+
DefaultKeyNameFlagName = "da.tx-client.key-name"
44+
KeyringPathFlagName = "da.tx-client.keyring-path"
45+
CoreGRPCAddrFlagName = "da.tx-client.core-grpc.addr"
46+
CoreGRPCTLSEnabledFlagName = "da.tx-client.core-grpc.tls-enabled"
47+
CoreGRPCAuthTokenFlagName = "da.tx-client.core-grpc.auth-token"
48+
P2PNetworkFlagName = "da.tx-client.p2p-network"
49+
3950
// NamespaceSize is the size of the hex encoded namespace string
4051
NamespaceSize = 58
4152

@@ -54,6 +65,12 @@ func CLIFlags(envPrefix string) []cli.Flag {
5465
Value: defaultRPC,
5566
EnvVars: opservice.PrefixEnvVar(envPrefix, "DA_RPC"),
5667
},
68+
&cli.BoolFlag{
69+
Name: TLSEnabledFlagName,
70+
Usage: "enable TLS for the data availability rpc client",
71+
EnvVars: opservice.PrefixEnvVar(envPrefix, "DA_TLS_ENABLED"),
72+
Value: true,
73+
},
5774
&cli.StringFlag{
5875
Name: AuthTokenFlagName,
5976
Usage: "authentication token of the data availability client",
@@ -93,25 +110,97 @@ func CLIFlags(envPrefix string) []cli.Flag {
93110
Value: defaultGasPrice,
94111
EnvVars: opservice.PrefixEnvVar(envPrefix, "DA_GAS_PRICE"),
95112
},
113+
&cli.StringFlag{
114+
Name: DefaultKeyNameFlagName,
115+
Usage: "celestia tx client key name",
116+
Value: "my_celes_key",
117+
EnvVars: opservice.PrefixEnvVar(envPrefix, "DA_TX_CLIENT_KEY_NAME"),
118+
},
119+
&cli.StringFlag{
120+
Name: KeyringPathFlagName,
121+
Usage: "celestia tx client keyring path e.g. ~/.celestia-light-mocha-4/keys",
122+
Value: "",
123+
EnvVars: opservice.PrefixEnvVar(envPrefix, "DA_TX_CLIENT_KEYRING_PATH"),
124+
},
125+
&cli.StringFlag{
126+
Name: CoreGRPCAddrFlagName,
127+
Usage: "celestia tx client core grpc addr",
128+
Value: "http://localhost:9090",
129+
EnvVars: opservice.PrefixEnvVar(envPrefix, "DA_TX_CLIENT_CORE_GRPC_ADDR"),
130+
},
131+
&cli.BoolFlag{
132+
Name: CoreGRPCTLSEnabledFlagName,
133+
Usage: "celestia tx client core grpc TLS",
134+
EnvVars: opservice.PrefixEnvVar(envPrefix, "DA_TX_CLIENT_CORE_GRPC_TLS_ENABLED"),
135+
Value: true,
136+
},
137+
&cli.StringFlag{
138+
Name: CoreGRPCAuthTokenFlagName,
139+
Usage: "celestia tx client core grpc auth token",
140+
Value: "",
141+
EnvVars: opservice.PrefixEnvVar(envPrefix, "DA_TX_CLIENT_CORE_GRPC_AUTH_TOKEN"),
142+
},
143+
&cli.StringFlag{
144+
Name: P2PNetworkFlagName,
145+
Usage: "celestia tx client p2p network",
146+
Value: "mocha-4",
147+
EnvVars: opservice.PrefixEnvVar(envPrefix, "DA_TX_CLIENT_P2P_NETWORK"),
148+
},
96149
}
97150
}
98151

99152
type CLIConfig struct {
100-
Rpc string
101-
AuthToken string
102-
Namespace string
103-
FallbackMode string
104-
GasPrice float64
153+
Rpc string
154+
TLSEnabled bool
155+
AuthToken string
156+
Namespace string
157+
FallbackMode string
158+
GasPrice float64
159+
TxClientConfig TxClientConfig
160+
}
161+
162+
func (c CLIConfig) TxClientEnabled() bool {
163+
return (c.TxClientConfig.KeyringPath != "" || c.TxClientConfig.CoreGRPCAuthToken != "")
105164
}
106165

107166
func (c CLIConfig) IsEnabled() bool {
108167
return c.Rpc != "" && c.AuthToken != "" && c.Namespace != ""
109168
}
110169

170+
func (c CLIConfig) CelestiaConfig() RPCClientConfig {
171+
ns, _ := hex.DecodeString(c.Namespace)
172+
var cfg *TxClientConfig
173+
if c.TxClientEnabled() {
174+
cfg = &c.TxClientConfig
175+
}
176+
return RPCClientConfig{
177+
URL: c.Rpc,
178+
TLSEnabled: c.TLSEnabled,
179+
AuthToken: c.AuthToken,
180+
Namespace: ns,
181+
TxClientConfig: cfg,
182+
}
183+
}
184+
111185
func (c CLIConfig) Check() error {
112186
if !c.IsEnabled() {
113187
return nil
114188
}
189+
if c.TxClientEnabled() {
190+
// If tx client is enabled, ensure tx client flags are set
191+
if c.TxClientConfig.DefaultKeyName == "" {
192+
return errors.New("--da.tx-client.key-name must be set")
193+
}
194+
if c.TxClientConfig.KeyringPath == "" {
195+
return errors.New("--da.tx-client.keyring-path must be set")
196+
}
197+
if c.TxClientConfig.CoreGRPCAddr == "" {
198+
return errors.New("--da.tx-client.core-grpc.addr must be set")
199+
}
200+
if c.TxClientConfig.P2PNetwork == "" {
201+
return errors.New("--da.tx-client.p2p-network must be set")
202+
}
203+
}
115204
if _, err := url.Parse(c.Rpc); err != nil {
116205
return fmt.Errorf("rpc url is invalid: %w", err)
117206
}
@@ -130,10 +219,19 @@ func NewCLIConfig() CLIConfig {
130219
func ReadCLIConfig(ctx *cli.Context) CLIConfig {
131220
return CLIConfig{
132221
Rpc: ctx.String(RPCFlagName),
222+
TLSEnabled: ctx.Bool(TLSEnabledFlagName),
133223
AuthToken: ctx.String(AuthTokenFlagName),
134224
Namespace: ctx.String(NamespaceFlagName),
135225
FallbackMode: ctx.String(FallbackModeFlagName),
136226
GasPrice: ctx.Float64(GasPriceFlagName),
227+
TxClientConfig: TxClientConfig{
228+
DefaultKeyName: ctx.String(DefaultKeyNameFlagName),
229+
KeyringPath: ctx.String(KeyringPathFlagName),
230+
CoreGRPCAddr: ctx.String(CoreGRPCAddrFlagName),
231+
CoreGRPCTLSEnabled: ctx.Bool(CoreGRPCTLSEnabledFlagName),
232+
CoreGRPCAuthToken: ctx.String(CoreGRPCAuthTokenFlagName),
233+
P2PNetwork: ctx.String(P2PNetworkFlagName),
234+
},
137235
}
138236
}
139237

@@ -173,5 +271,24 @@ func ReadCLIConfigFromEnv(envPrefix string) CLIConfig {
173271
}
174272
}
175273

274+
if value := os.Getenv(envPrefix + "_" + "DA_TX_CLIENT_KEY_NAME"); value != "" {
275+
result.TxClientConfig.DefaultKeyName = value
276+
}
277+
if value := os.Getenv(envPrefix + "_" + "DA_TX_CLIENT_KEYRING_PATH"); value != "" {
278+
result.TxClientConfig.KeyringPath = value
279+
}
280+
if value := os.Getenv(envPrefix + "_" + "DA_TX_CLIENT_CORE_GRPC_ADDR"); value != "" {
281+
result.TxClientConfig.CoreGRPCAddr = value
282+
}
283+
if value := os.Getenv(envPrefix + "_" + "DA_TX_CLIENT_CORE_GRPC_TLS_ENABLED"); value != "" {
284+
result.TxClientConfig.CoreGRPCTLSEnabled = value == "true"
285+
}
286+
if value := os.Getenv(envPrefix + "_" + "DA_TX_CLIENT_CORE_GRPC_AUTH_TOKEN"); value != "" {
287+
result.TxClientConfig.CoreGRPCAuthToken = value
288+
}
289+
if value := os.Getenv(envPrefix + "_" + "DA_TX_CLIENT_P2P_NETWORK"); value != "" {
290+
result.TxClientConfig.P2PNetwork = value
291+
}
292+
176293
return result
177294
}

op-celestia/da_client.go

Lines changed: 88 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@ package celestia
33
import (
44
"context"
55
"encoding/binary"
6-
"encoding/hex"
76
"fmt"
87
"time"
98

9+
txClient "github.com/celestiaorg/celestia-node/api/client"
1010
"github.com/celestiaorg/celestia-node/api/rpc/client"
11+
blobAPI "github.com/celestiaorg/celestia-node/nodebuilder/blob"
12+
"github.com/celestiaorg/celestia-node/nodebuilder/p2p"
13+
libshare "github.com/celestiaorg/go-square/v2/share"
14+
"github.com/cosmos/cosmos-sdk/crypto/keyring"
15+
"github.com/ethereum/go-ethereum/log"
1116
)
1217

1318
// heightLen is a length (in bytes) of serialized height.
@@ -30,33 +35,103 @@ func SplitID(id []byte) (uint64, []byte) {
3035
return binary.LittleEndian.Uint64(id[:heightLen]), commitment
3136
}
3237

38+
type TxClientConfig struct {
39+
DefaultKeyName string
40+
KeyringPath string
41+
CoreGRPCAddr string
42+
CoreGRPCTLSEnabled bool
43+
CoreGRPCAuthToken string
44+
P2PNetwork string
45+
}
46+
47+
type RPCClientConfig struct {
48+
URL string
49+
TLSEnabled bool
50+
AuthToken string
51+
Namespace []byte
52+
FallbackMode string
53+
GasPrice float64
54+
TxClientConfig *TxClientConfig
55+
}
56+
3357
type DAClient struct {
34-
Client *client.Client
58+
Client blobAPI.Module
3559
GetTimeout time.Duration
3660
SubmitTimeout time.Duration
3761
Namespace []byte
3862
FallbackMode string
3963
GasPrice float64
4064
}
4165

42-
func NewDAClient(rpc, token, namespace, fallbackMode string, gasPrice float64) (*DAClient, error) {
43-
client, err := client.NewClient(context.Background(), rpc, token)
66+
// initTxClient initializes a transaction client for Celestia.
67+
func initTxClient(cfg RPCClientConfig) (blobAPI.Module, error) {
68+
keyname := cfg.TxClientConfig.DefaultKeyName
69+
if keyname == "" {
70+
keyname = "my_celes_key"
71+
}
72+
kr, err := txClient.KeyringWithNewKey(txClient.KeyringConfig{
73+
KeyName: keyname,
74+
BackendName: keyring.BackendTest,
75+
}, cfg.TxClientConfig.KeyringPath)
4476
if err != nil {
45-
return nil, err
77+
return nil, fmt.Errorf("failed to create keyring: %w", err)
4678
}
47-
ns, err := hex.DecodeString(namespace)
79+
80+
// Configure client
81+
config := txClient.Config{
82+
ReadConfig: txClient.ReadConfig{
83+
BridgeDAAddr: cfg.URL,
84+
DAAuthToken: cfg.AuthToken,
85+
EnableDATLS: cfg.TLSEnabled,
86+
},
87+
SubmitConfig: txClient.SubmitConfig{
88+
DefaultKeyName: cfg.TxClientConfig.DefaultKeyName,
89+
Network: p2p.Network(cfg.TxClientConfig.P2PNetwork),
90+
CoreGRPCConfig: txClient.CoreGRPCConfig{
91+
Addr: cfg.TxClientConfig.CoreGRPCAddr,
92+
TLSEnabled: cfg.TxClientConfig.CoreGRPCTLSEnabled,
93+
AuthToken: cfg.TxClientConfig.CoreGRPCAuthToken,
94+
},
95+
},
96+
}
97+
ctx := context.Background()
98+
celestiaClient, err := txClient.New(ctx, config, kr)
4899
if err != nil {
49-
return nil, err
100+
return nil, fmt.Errorf("failed to create tx client: %w", err)
50101
}
51-
if fallbackMode != "disabled" && fallbackMode != "blobdata" && fallbackMode != "calldata" {
52-
return nil, fmt.Errorf("celestia: unknown fallback mode: %s", fallbackMode)
102+
return celestiaClient.Blob, nil
103+
}
104+
105+
// initRPCClient initializes an RPC client for Celestia.
106+
func initRPCClient(cfg RPCClientConfig) (blobAPI.Module, error) {
107+
celestiaClient, err := client.NewClient(context.Background(), cfg.URL, cfg.AuthToken)
108+
if err != nil {
109+
return nil, fmt.Errorf("failed to create rpc client: %w", err)
110+
}
111+
return &celestiaClient.Blob, nil
112+
}
113+
114+
func NewDAClient(cfg RPCClientConfig) (*DAClient, error) {
115+
var blobClient blobAPI.Module
116+
var err error
117+
if cfg.TxClientConfig != nil {
118+
blobClient, err = initTxClient(cfg)
119+
} else {
120+
blobClient, err = initRPCClient(cfg)
121+
}
122+
if err != nil {
123+
log.Crit("failed to initialize celestia client", "err", err)
124+
}
125+
_, err = libshare.NewNamespaceFromBytes(cfg.Namespace)
126+
if err != nil {
127+
log.Crit("failed to parse namespace", "err", err)
53128
}
54129
return &DAClient{
55-
Client: client,
130+
Client: blobClient,
56131
GetTimeout: time.Minute,
57132
SubmitTimeout: time.Minute,
58-
Namespace: ns,
59-
FallbackMode: fallbackMode,
60-
GasPrice: gasPrice,
133+
Namespace: cfg.Namespace,
134+
FallbackMode: cfg.FallbackMode,
135+
GasPrice: cfg.GasPrice,
61136
}, nil
62137
}

op-celestia/indexer/driver.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ func (d *IndexerDriver) processCelestiaFrames(id []byte, blockNum uint64) error
317317

318318
d.Log.Debug("Found Celestia reference", "height", height, "commitment", base64.StdEncoding.EncodeToString(commitment))
319319

320-
blob, err := d.CelestiaClient.Client.Blob.Get(ctx, height, namespace, commitment)
320+
blob, err := d.CelestiaClient.Client.Get(ctx, height, namespace, commitment)
321321
if err != nil {
322322
return fmt.Errorf("failed to fetch blobs from Celestia: %w", err)
323323
}

op-celestia/indexer/service.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,7 @@ func (is *IndexerService) initClients(ctx context.Context, cfg *CLIConfig) error
150150
is.L2Client = l2RpcClient
151151

152152
// Initialize Celestia client
153-
celestiaClient, err := celestia.NewDAClient(
154-
cfg.CelestiaConfig.Rpc,
155-
cfg.CelestiaConfig.AuthToken,
156-
cfg.CelestiaConfig.Namespace,
157-
cfg.CelestiaConfig.FallbackMode,
158-
cfg.CelestiaConfig.GasPrice,
159-
)
153+
celestiaClient, err := celestia.NewDAClient(cfg.CelestiaConfig.CelestiaConfig())
160154
if err != nil {
161155
return fmt.Errorf("failed to create Celestia client: %w", err)
162156
}

op-node/rollup/derive/celestia_data_source.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func (s *CelestiaDataSource) Next(ctx context.Context) (eth.Data, error) {
6161
if err != nil {
6262
return nil, err
6363
}
64-
blob, err := daClient.Client.Blob.Get(ctx, height, namespace, commitment)
64+
blob, err := daClient.Client.Get(ctx, height, namespace, commitment)
6565
if err != nil {
6666
// return temporary error so we can keep retrying.
6767
return nil, NewTemporaryError(fmt.Errorf("celestia: failed to resolve frame: %w", err))

op-node/rollup/driver/da.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func SetDAClient(cfg celestia.CLIConfig) error {
2020
if !cfg.IsEnabled() {
2121
return derive.SetCelestiaDA(nil)
2222
}
23-
client, err := celestia.NewDAClient(cfg.Rpc, cfg.AuthToken, cfg.Namespace, cfg.FallbackMode, cfg.GasPrice)
23+
client, err := celestia.NewDAClient(cfg.CelestiaConfig())
2424
if err != nil {
2525
return err
2626
}

op-program/client/program.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func Main(useInterop bool) {
4141
preimageHinter := preimage.ClientHinterChannel()
4242

4343
daCfg := celestia.ReadCLIConfigFromEnv("OP_E2E")
44-
daClient, err := celestia.NewDAClient(daCfg.Rpc, daCfg.AuthToken, daCfg.Namespace, daCfg.FallbackMode, daCfg.GasPrice)
44+
daClient, err := celestia.NewDAClient(daCfg.CelestiaConfig())
4545
if err != nil {
4646
log.Error("Cannot initialize daClient", "err", err)
4747
os.Exit(1)

0 commit comments

Comments
 (0)