Commit dcc3d7f0 authored by Yann Hodique's avatar Yann Hodique Committed by GitHub

feat(kurtosis-devnet): provide standalone descriptors (#13758)

parent 965163ab
package descriptors
type PortInfo struct {
Host string `json:"host"`
Port int `json:"port"`
}
// EndpointMap is a map of service names to their endpoints.
type EndpointMap map[string]PortInfo
// Service represents a chain service.
type Service struct {
Name string `json:"name"`
Endpoints EndpointMap `json:"endpoints"`
}
// ServiceMap is a map of service names to services.
type ServiceMap map[string]Service
// Node represents a node for a chain.
type Node struct {
Services ServiceMap `json:"services"`
}
// AddressMap is a map of addresses to their corresponding chain IDs.
type AddressMap map[string]string
// Chain represents a chain (L1 or L2) in a devnet.
type Chain struct {
Name string `json:"name"`
ID string `json:"id,omitempty"`
Services ServiceMap `json:"services,omitempty"`
Nodes []Node `json:"nodes"`
Addresses AddressMap `json:"addresses,omitempty"`
Wallets WalletMap `json:"wallets,omitempty"`
JWT string `json:"jwt,omitempty"`
}
// Wallet represents a wallet with an address and optional private key.
type Wallet struct {
Address string `json:"address"`
PrivateKey string `json:"private_key,omitempty"`
}
// WalletMap is a map of wallet names to wallets.
type WalletMap map[string]Wallet
// DevnetEnvironment exposes the relevant information to interact with a devnet.
type DevnetEnvironment struct {
L1 *Chain `json:"l1"`
L2 []*Chain `json:"l2"`
}
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/descriptors"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/sources/inspect" "github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/sources/inspect"
) )
...@@ -45,7 +46,7 @@ func NewServiceFinder(services inspect.ServiceMap, opts ...ServiceFinderOption) ...@@ -45,7 +46,7 @@ func NewServiceFinder(services inspect.ServiceMap, opts ...ServiceFinderOption)
} }
// FindL1Services finds L1 nodes. // FindL1Services finds L1 nodes.
func (f *ServiceFinder) FindL1Services() ([]Node, ServiceMap) { func (f *ServiceFinder) FindL1Services() ([]descriptors.Node, descriptors.ServiceMap) {
return f.findRPCEndpoints(func(serviceName string) (string, int, bool) { return f.findRPCEndpoints(func(serviceName string) (string, int, bool) {
// Only match services that start with one of the node service identifiers. // Only match services that start with one of the node service identifiers.
// We might have to change this if we need to support L1 services beyond nodes. // We might have to change this if we need to support L1 services beyond nodes.
...@@ -60,7 +61,7 @@ func (f *ServiceFinder) FindL1Services() ([]Node, ServiceMap) { ...@@ -60,7 +61,7 @@ func (f *ServiceFinder) FindL1Services() ([]Node, ServiceMap) {
} }
// FindL2Services finds L2 nodes and services for a specific network // FindL2Services finds L2 nodes and services for a specific network
func (f *ServiceFinder) FindL2Services(network string) ([]Node, ServiceMap) { func (f *ServiceFinder) FindL2Services(network string) ([]descriptors.Node, descriptors.ServiceMap) {
networkSuffix := "-" + network networkSuffix := "-" + network
return f.findRPCEndpoints(func(serviceName string) (string, int, bool) { return f.findRPCEndpoints(func(serviceName string) (string, int, bool) {
if strings.HasSuffix(serviceName, networkSuffix) { if strings.HasSuffix(serviceName, networkSuffix) {
...@@ -73,9 +74,9 @@ func (f *ServiceFinder) FindL2Services(network string) ([]Node, ServiceMap) { ...@@ -73,9 +74,9 @@ func (f *ServiceFinder) FindL2Services(network string) ([]Node, ServiceMap) {
} }
// findRPCEndpoints looks for services matching the given predicate that have an RPC port // findRPCEndpoints looks for services matching the given predicate that have an RPC port
func (f *ServiceFinder) findRPCEndpoints(matchService func(string) (string, int, bool)) ([]Node, ServiceMap) { func (f *ServiceFinder) findRPCEndpoints(matchService func(string) (string, int, bool)) ([]descriptors.Node, descriptors.ServiceMap) {
serviceMap := make(ServiceMap) serviceMap := make(descriptors.ServiceMap)
var nodes []Node var nodes []descriptors.Node
for serviceName, ports := range f.services { for serviceName, ports := range f.services {
if serviceIdentifier, num, ok := matchService(serviceName); ok { if serviceIdentifier, num, ok := matchService(serviceName); ok {
...@@ -85,16 +86,16 @@ func (f *ServiceFinder) findRPCEndpoints(matchService func(string) (string, int, ...@@ -85,16 +86,16 @@ func (f *ServiceFinder) findRPCEndpoints(matchService func(string) (string, int,
if num > len(nodes) { if num > len(nodes) {
// Extend the slice to accommodate the required index // Extend the slice to accommodate the required index
for i := len(nodes); i < num; i++ { for i := len(nodes); i < num; i++ {
nodes = append(nodes, Node{ nodes = append(nodes, descriptors.Node{
Services: make(ServiceMap), Services: make(descriptors.ServiceMap),
}) })
} }
} }
endpoints := make(EndpointMap) endpoints := make(descriptors.EndpointMap)
for portName, portInfo := range ports { for portName, portInfo := range ports {
endpoints[portName] = portInfo endpoints[portName] = portInfo
} }
nodes[num-1].Services[serviceIdentifier] = Service{ nodes[num-1].Services[serviceIdentifier] = descriptors.Service{
Name: serviceName, Name: serviceName,
Endpoints: endpoints, Endpoints: endpoints,
} }
...@@ -102,11 +103,11 @@ func (f *ServiceFinder) findRPCEndpoints(matchService func(string) (string, int, ...@@ -102,11 +103,11 @@ func (f *ServiceFinder) findRPCEndpoints(matchService func(string) (string, int,
} }
} }
if !allocated { if !allocated {
endpoints := make(EndpointMap) endpoints := make(descriptors.EndpointMap)
for portName, portInfo := range ports { for portName, portInfo := range ports {
endpoints[portName] = portInfo endpoints[portName] = portInfo
} }
serviceMap[serviceIdentifier] = Service{ serviceMap[serviceIdentifier] = descriptors.Service{
Name: serviceName, Name: serviceName,
Endpoints: endpoints, Endpoints: endpoints,
} }
......
...@@ -3,6 +3,7 @@ package kurtosis ...@@ -3,6 +3,7 @@ package kurtosis
import ( import (
"testing" "testing"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/descriptors"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/sources/inspect" "github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/sources/inspect"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
...@@ -52,31 +53,31 @@ func TestFindRPCEndpoints(t *testing.T) { ...@@ -52,31 +53,31 @@ func TestFindRPCEndpoints(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
services inspect.ServiceMap services inspect.ServiceMap
findFn func(*ServiceFinder) ([]Node, ServiceMap) findFn func(*ServiceFinder) ([]descriptors.Node, descriptors.ServiceMap)
wantNodes []Node wantNodes []descriptors.Node
wantServices ServiceMap wantServices descriptors.ServiceMap
}{ }{
{ {
name: "find L1 endpoints", name: "find L1 endpoints",
services: testServices, services: testServices,
findFn: func(f *ServiceFinder) ([]Node, ServiceMap) { findFn: func(f *ServiceFinder) ([]descriptors.Node, descriptors.ServiceMap) {
return f.FindL1Services() return f.FindL1Services()
}, },
wantNodes: []Node{ wantNodes: []descriptors.Node{
{ {
Services: ServiceMap{ Services: descriptors.ServiceMap{
"cl": Service{ "cl": descriptors.Service{
Name: "cl-1-lighthouse-geth", Name: "cl-1-lighthouse-geth",
Endpoints: EndpointMap{ Endpoints: descriptors.EndpointMap{
"metrics": {Port: 52691}, "metrics": {Port: 52691},
"tcp-discovery": {Port: 52692}, "tcp-discovery": {Port: 52692},
"udp-discovery": {Port: 58275}, "udp-discovery": {Port: 58275},
"http": {Port: 52693}, "http": {Port: 52693},
}, },
}, },
"el": Service{ "el": descriptors.Service{
Name: "el-1-geth-lighthouse", Name: "el-1-geth-lighthouse",
Endpoints: EndpointMap{ Endpoints: descriptors.EndpointMap{
"metrics": {Port: 52643}, "metrics": {Port: 52643},
"tcp-discovery": {Port: 52644}, "tcp-discovery": {Port: 52644},
"udp-discovery": {Port: 51936}, "udp-discovery": {Port: 51936},
...@@ -88,28 +89,28 @@ func TestFindRPCEndpoints(t *testing.T) { ...@@ -88,28 +89,28 @@ func TestFindRPCEndpoints(t *testing.T) {
}, },
}, },
}, },
wantServices: ServiceMap{}, wantServices: descriptors.ServiceMap{},
}, },
{ {
name: "find op-kurtosis L2 endpoints", name: "find op-kurtosis L2 endpoints",
services: testServices, services: testServices,
findFn: func(f *ServiceFinder) ([]Node, ServiceMap) { findFn: func(f *ServiceFinder) ([]descriptors.Node, descriptors.ServiceMap) {
return f.FindL2Services("op-kurtosis") return f.FindL2Services("op-kurtosis")
}, },
wantNodes: []Node{ wantNodes: []descriptors.Node{
{ {
Services: ServiceMap{ Services: descriptors.ServiceMap{
"cl": Service{ "cl": descriptors.Service{
Name: "op-cl-1-op-node-op-geth-op-kurtosis", Name: "op-cl-1-op-node-op-geth-op-kurtosis",
Endpoints: EndpointMap{ Endpoints: descriptors.EndpointMap{
"udp-discovery": {Port: 50990}, "udp-discovery": {Port: 50990},
"http": {Port: 53503}, "http": {Port: 53503},
"tcp-discovery": {Port: 53504}, "tcp-discovery": {Port: 53504},
}, },
}, },
"el": Service{ "el": descriptors.Service{
Name: "op-el-1-op-geth-op-node-op-kurtosis", Name: "op-el-1-op-geth-op-node-op-kurtosis",
Endpoints: EndpointMap{ Endpoints: descriptors.EndpointMap{
"udp-discovery": {Port: 53233}, "udp-discovery": {Port: 53233},
"engine-rpc": {Port: 53399}, "engine-rpc": {Port: 53399},
"metrics": {Port: 53400}, "metrics": {Port: 53400},
...@@ -121,10 +122,10 @@ func TestFindRPCEndpoints(t *testing.T) { ...@@ -121,10 +122,10 @@ func TestFindRPCEndpoints(t *testing.T) {
}, },
}, },
}, },
wantServices: ServiceMap{ wantServices: descriptors.ServiceMap{
"batcher": Service{ "batcher": descriptors.Service{
Name: "op-batcher-op-kurtosis", Name: "op-batcher-op-kurtosis",
Endpoints: EndpointMap{ Endpoints: descriptors.EndpointMap{
"http": {Port: 53572}, "http": {Port: 53572},
}, },
}, },
...@@ -137,14 +138,14 @@ func TestFindRPCEndpoints(t *testing.T) { ...@@ -137,14 +138,14 @@ func TestFindRPCEndpoints(t *testing.T) {
"http": {Host: "custom.host", Port: 8080}, "http": {Host: "custom.host", Port: 8080},
}, },
}, },
findFn: func(f *ServiceFinder) ([]Node, ServiceMap) { findFn: func(f *ServiceFinder) ([]descriptors.Node, descriptors.ServiceMap) {
return f.FindL2Services("custom-host") return f.FindL2Services("custom-host")
}, },
wantNodes: nil, wantNodes: nil,
wantServices: ServiceMap{ wantServices: descriptors.ServiceMap{
"batcher": Service{ "batcher": descriptors.Service{
Name: "op-batcher-custom-host", Name: "op-batcher-custom-host",
Endpoints: EndpointMap{ Endpoints: descriptors.EndpointMap{
"http": {Host: "custom.host", Port: 8080}, "http": {Host: "custom.host", Port: 8080},
}, },
}, },
......
...@@ -6,11 +6,11 @@ import ( ...@@ -6,11 +6,11 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/descriptors"
apiInterfaces "github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/api/interfaces" apiInterfaces "github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/api/interfaces"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/api/run" "github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/api/run"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/api/wrappers" "github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/api/wrappers"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/sources/deployer" "github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/sources/deployer"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/sources/inspect"
srcInterfaces "github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/sources/interfaces" srcInterfaces "github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/sources/interfaces"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/sources/spec" "github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/sources/spec"
) )
...@@ -20,40 +20,9 @@ const ( ...@@ -20,40 +20,9 @@ const (
DefaultEnclave = "devnet" DefaultEnclave = "devnet"
) )
type EndpointMap map[string]inspect.PortInfo
type ServiceMap map[string]Service
type Service struct {
Name string `json:"name"`
Endpoints EndpointMap `json:"endpoints"`
}
type Node struct {
Services ServiceMap `json:"services"`
}
type Chain struct {
Name string `json:"name"`
ID string `json:"id,omitempty"`
Services ServiceMap `json:"services,omitempty"`
Nodes []Node `json:"nodes"`
Addresses deployer.DeploymentAddresses `json:"addresses,omitempty"`
Wallets WalletMap `json:"wallets,omitempty"`
JWT string `json:"jwt,omitempty"`
}
type Wallet struct {
Address string `json:"address"`
PrivateKey string `json:"private_key,omitempty"`
}
type WalletMap map[string]Wallet
// KurtosisEnvironment represents the output of a Kurtosis deployment // KurtosisEnvironment represents the output of a Kurtosis deployment
type KurtosisEnvironment struct { type KurtosisEnvironment struct {
L1 *Chain `json:"l1"` descriptors.DevnetEnvironment
L2 []*Chain `json:"l2"`
} }
// KurtosisDeployer handles deploying packages using Kurtosis // KurtosisDeployer handles deploying packages using Kurtosis
...@@ -162,10 +131,10 @@ func NewKurtosisDeployer(opts ...KurtosisDeployerOptions) (*KurtosisDeployer, er ...@@ -162,10 +131,10 @@ func NewKurtosisDeployer(opts ...KurtosisDeployerOptions) (*KurtosisDeployer, er
return d, nil return d, nil
} }
func (d *KurtosisDeployer) getWallets(wallets deployer.WalletList) WalletMap { func (d *KurtosisDeployer) getWallets(wallets deployer.WalletList) descriptors.WalletMap {
walletMap := make(WalletMap) walletMap := make(descriptors.WalletMap)
for _, wallet := range wallets { for _, wallet := range wallets {
walletMap[wallet.Name] = Wallet{ walletMap[wallet.Name] = descriptors.Wallet{
Address: wallet.Address, Address: wallet.Address,
PrivateKey: wallet.PrivateKey, PrivateKey: wallet.PrivateKey,
} }
...@@ -193,20 +162,22 @@ func (d *KurtosisDeployer) GetEnvironmentInfo(ctx context.Context, spec *spec.En ...@@ -193,20 +162,22 @@ func (d *KurtosisDeployer) GetEnvironmentInfo(ctx context.Context, spec *spec.En
} }
env := &KurtosisEnvironment{ env := &KurtosisEnvironment{
L2: make([]*Chain, 0, len(spec.Chains)), DevnetEnvironment: descriptors.DevnetEnvironment{
L2: make([]*descriptors.Chain, 0, len(spec.Chains)),
},
} }
// Find L1 endpoint // Find L1 endpoint
finder := NewServiceFinder(inspectResult.UserServices) finder := NewServiceFinder(inspectResult.UserServices)
if nodes, services := finder.FindL1Services(); len(nodes) > 0 { if nodes, services := finder.FindL1Services(); len(nodes) > 0 {
chain := &Chain{ chain := &descriptors.Chain{
Name: "Ethereum", Name: "Ethereum",
Services: services, Services: services,
Nodes: nodes, Nodes: nodes,
JWT: jwtData.L1JWT, JWT: jwtData.L1JWT,
} }
if deployerState.State != nil { if deployerState.State != nil {
chain.Addresses = deployerState.State.Addresses chain.Addresses = descriptors.AddressMap(deployerState.State.Addresses)
chain.Wallets = d.getWallets(deployerState.Wallets) chain.Wallets = d.getWallets(deployerState.Wallets)
} }
env.L1 = chain env.L1 = chain
...@@ -216,7 +187,7 @@ func (d *KurtosisDeployer) GetEnvironmentInfo(ctx context.Context, spec *spec.En ...@@ -216,7 +187,7 @@ func (d *KurtosisDeployer) GetEnvironmentInfo(ctx context.Context, spec *spec.En
for _, chainSpec := range spec.Chains { for _, chainSpec := range spec.Chains {
nodes, services := finder.FindL2Services(chainSpec.Name) nodes, services := finder.FindL2Services(chainSpec.Name)
chain := &Chain{ chain := &descriptors.Chain{
Name: chainSpec.Name, Name: chainSpec.Name,
ID: chainSpec.NetworkID, ID: chainSpec.NetworkID,
Services: services, Services: services,
...@@ -227,7 +198,7 @@ func (d *KurtosisDeployer) GetEnvironmentInfo(ctx context.Context, spec *spec.En ...@@ -227,7 +198,7 @@ func (d *KurtosisDeployer) GetEnvironmentInfo(ctx context.Context, spec *spec.En
// Add contract addresses if available // Add contract addresses if available
if deployerState.State != nil && deployerState.State.Deployments != nil { if deployerState.State != nil && deployerState.State.Deployments != nil {
if addresses, ok := deployerState.State.Deployments[chainSpec.NetworkID]; ok { if addresses, ok := deployerState.State.Deployments[chainSpec.NetworkID]; ok {
chain.Addresses = addresses.Addresses chain.Addresses = descriptors.AddressMap(addresses.Addresses)
} }
if wallets, ok := deployerState.State.Deployments[chainSpec.NetworkID]; ok { if wallets, ok := deployerState.State.Deployments[chainSpec.NetworkID]; ok {
chain.Wallets = d.getWallets(wallets.Wallets) chain.Wallets = d.getWallets(wallets.Wallets)
......
...@@ -7,6 +7,7 @@ import ( ...@@ -7,6 +7,7 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/descriptors"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/api/fake" "github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/api/fake"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/api/interfaces" "github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/api/interfaces"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/sources/deployer" "github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/sources/deployer"
...@@ -248,11 +249,11 @@ func TestGetEnvironmentInfo(t *testing.T) { ...@@ -248,11 +249,11 @@ func TestGetEnvironmentInfo(t *testing.T) {
} }
// Create expected L1 services // Create expected L1 services
l1Services := make(ServiceMap) l1Services := make(descriptors.ServiceMap)
l1Services["el"] = Service{ l1Services["el"] = descriptors.Service{
Name: "el-1-geth-lighthouse", Name: "el-1-geth-lighthouse",
Endpoints: EndpointMap{ Endpoints: descriptors.EndpointMap{
"rpc": inspect.PortInfo{Port: 52645}, "rpc": descriptors.PortInfo{Port: 52645},
}, },
} }
...@@ -273,26 +274,28 @@ func TestGetEnvironmentInfo(t *testing.T) { ...@@ -273,26 +274,28 @@ func TestGetEnvironmentInfo(t *testing.T) {
deploy: &deployer.DeployerData{Wallets: testWallets}, deploy: &deployer.DeployerData{Wallets: testWallets},
jwt: testJWTs, jwt: testJWTs,
want: &KurtosisEnvironment{ want: &KurtosisEnvironment{
L1: &Chain{ DevnetEnvironment: descriptors.DevnetEnvironment{
L1: &descriptors.Chain{
Name: "Ethereum", Name: "Ethereum",
Services: make(ServiceMap), Services: make(descriptors.ServiceMap),
Nodes: []Node{ Nodes: []descriptors.Node{
{ {
Services: l1Services, Services: l1Services,
}, },
}, },
JWT: testJWTs.L1JWT, JWT: testJWTs.L1JWT,
}, },
L2: []*Chain{ L2: []*descriptors.Chain{
{ {
Name: "op-kurtosis", Name: "op-kurtosis",
ID: "1234", ID: "1234",
Services: make(ServiceMap), Services: make(descriptors.ServiceMap),
JWT: testJWTs.L2JWT, JWT: testJWTs.L2JWT,
}, },
}, },
}, },
}, },
},
{ {
name: "inspect error", name: "inspect error",
spec: testSpec, spec: testSpec,
......
...@@ -3,16 +3,11 @@ package inspect ...@@ -3,16 +3,11 @@ package inspect
import ( import (
"context" "context"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/descriptors"
"github.com/kurtosis-tech/kurtosis/api/golang/engine/lib/kurtosis_context" "github.com/kurtosis-tech/kurtosis/api/golang/engine/lib/kurtosis_context"
) )
// PortInfo contains the host and port number for a service port type PortMap map[string]descriptors.PortInfo
type PortInfo struct {
Host string `json:"host"`
Port int `json:"port"`
}
type PortMap map[string]PortInfo
type ServiceMap map[string]PortMap type ServiceMap map[string]PortMap
...@@ -70,7 +65,7 @@ func (e *Inspector) ExtractData(ctx context.Context) (*InspectData, error) { ...@@ -70,7 +65,7 @@ func (e *Inspector) ExtractData(ctx context.Context) (*InspectData, error) {
portMap := make(PortMap) portMap := make(PortMap)
for port, portSpec := range svcCtx.GetPublicPorts() { for port, portSpec := range svcCtx.GetPublicPorts() {
portMap[port] = PortInfo{ portMap[port] = descriptors.PortInfo{
Host: svcCtx.GetMaybePublicIPAddress(), Host: svcCtx.GetMaybePublicIPAddress(),
Port: int(portSpec.GetNumber()), Port: int(portSpec.GetNumber()),
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment