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 (
"strconv"
"strings"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/descriptors"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/sources/inspect"
)
......@@ -45,7 +46,7 @@ func NewServiceFinder(services inspect.ServiceMap, opts ...ServiceFinderOption)
}
// 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) {
// 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.
......@@ -60,7 +61,7 @@ func (f *ServiceFinder) FindL1Services() ([]Node, ServiceMap) {
}
// 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
return f.findRPCEndpoints(func(serviceName string) (string, int, bool) {
if strings.HasSuffix(serviceName, networkSuffix) {
......@@ -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
func (f *ServiceFinder) findRPCEndpoints(matchService func(string) (string, int, bool)) ([]Node, ServiceMap) {
serviceMap := make(ServiceMap)
var nodes []Node
func (f *ServiceFinder) findRPCEndpoints(matchService func(string) (string, int, bool)) ([]descriptors.Node, descriptors.ServiceMap) {
serviceMap := make(descriptors.ServiceMap)
var nodes []descriptors.Node
for serviceName, ports := range f.services {
if serviceIdentifier, num, ok := matchService(serviceName); ok {
......@@ -85,16 +86,16 @@ func (f *ServiceFinder) findRPCEndpoints(matchService func(string) (string, int,
if num > len(nodes) {
// Extend the slice to accommodate the required index
for i := len(nodes); i < num; i++ {
nodes = append(nodes, Node{
Services: make(ServiceMap),
nodes = append(nodes, descriptors.Node{
Services: make(descriptors.ServiceMap),
})
}
}
endpoints := make(EndpointMap)
endpoints := make(descriptors.EndpointMap)
for portName, portInfo := range ports {
endpoints[portName] = portInfo
}
nodes[num-1].Services[serviceIdentifier] = Service{
nodes[num-1].Services[serviceIdentifier] = descriptors.Service{
Name: serviceName,
Endpoints: endpoints,
}
......@@ -102,11 +103,11 @@ func (f *ServiceFinder) findRPCEndpoints(matchService func(string) (string, int,
}
}
if !allocated {
endpoints := make(EndpointMap)
endpoints := make(descriptors.EndpointMap)
for portName, portInfo := range ports {
endpoints[portName] = portInfo
}
serviceMap[serviceIdentifier] = Service{
serviceMap[serviceIdentifier] = descriptors.Service{
Name: serviceName,
Endpoints: endpoints,
}
......
......@@ -3,6 +3,7 @@ package kurtosis
import (
"testing"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/descriptors"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/sources/inspect"
"github.com/stretchr/testify/assert"
)
......@@ -52,31 +53,31 @@ func TestFindRPCEndpoints(t *testing.T) {
tests := []struct {
name string
services inspect.ServiceMap
findFn func(*ServiceFinder) ([]Node, ServiceMap)
wantNodes []Node
wantServices ServiceMap
findFn func(*ServiceFinder) ([]descriptors.Node, descriptors.ServiceMap)
wantNodes []descriptors.Node
wantServices descriptors.ServiceMap
}{
{
name: "find L1 endpoints",
services: testServices,
findFn: func(f *ServiceFinder) ([]Node, ServiceMap) {
findFn: func(f *ServiceFinder) ([]descriptors.Node, descriptors.ServiceMap) {
return f.FindL1Services()
},
wantNodes: []Node{
wantNodes: []descriptors.Node{
{
Services: ServiceMap{
"cl": Service{
Services: descriptors.ServiceMap{
"cl": descriptors.Service{
Name: "cl-1-lighthouse-geth",
Endpoints: EndpointMap{
Endpoints: descriptors.EndpointMap{
"metrics": {Port: 52691},
"tcp-discovery": {Port: 52692},
"udp-discovery": {Port: 58275},
"http": {Port: 52693},
},
},
"el": Service{
"el": descriptors.Service{
Name: "el-1-geth-lighthouse",
Endpoints: EndpointMap{
Endpoints: descriptors.EndpointMap{
"metrics": {Port: 52643},
"tcp-discovery": {Port: 52644},
"udp-discovery": {Port: 51936},
......@@ -88,28 +89,28 @@ func TestFindRPCEndpoints(t *testing.T) {
},
},
},
wantServices: ServiceMap{},
wantServices: descriptors.ServiceMap{},
},
{
name: "find op-kurtosis L2 endpoints",
services: testServices,
findFn: func(f *ServiceFinder) ([]Node, ServiceMap) {
findFn: func(f *ServiceFinder) ([]descriptors.Node, descriptors.ServiceMap) {
return f.FindL2Services("op-kurtosis")
},
wantNodes: []Node{
wantNodes: []descriptors.Node{
{
Services: ServiceMap{
"cl": Service{
Services: descriptors.ServiceMap{
"cl": descriptors.Service{
Name: "op-cl-1-op-node-op-geth-op-kurtosis",
Endpoints: EndpointMap{
Endpoints: descriptors.EndpointMap{
"udp-discovery": {Port: 50990},
"http": {Port: 53503},
"tcp-discovery": {Port: 53504},
},
},
"el": Service{
"el": descriptors.Service{
Name: "op-el-1-op-geth-op-node-op-kurtosis",
Endpoints: EndpointMap{
Endpoints: descriptors.EndpointMap{
"udp-discovery": {Port: 53233},
"engine-rpc": {Port: 53399},
"metrics": {Port: 53400},
......@@ -121,10 +122,10 @@ func TestFindRPCEndpoints(t *testing.T) {
},
},
},
wantServices: ServiceMap{
"batcher": Service{
wantServices: descriptors.ServiceMap{
"batcher": descriptors.Service{
Name: "op-batcher-op-kurtosis",
Endpoints: EndpointMap{
Endpoints: descriptors.EndpointMap{
"http": {Port: 53572},
},
},
......@@ -137,14 +138,14 @@ func TestFindRPCEndpoints(t *testing.T) {
"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")
},
wantNodes: nil,
wantServices: ServiceMap{
"batcher": Service{
wantServices: descriptors.ServiceMap{
"batcher": descriptors.Service{
Name: "op-batcher-custom-host",
Endpoints: EndpointMap{
Endpoints: descriptors.EndpointMap{
"http": {Host: "custom.host", Port: 8080},
},
},
......
......@@ -6,11 +6,11 @@ import (
"fmt"
"io"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/descriptors"
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/wrappers"
"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"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/sources/spec"
)
......@@ -20,40 +20,9 @@ const (
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
type KurtosisEnvironment struct {
L1 *Chain `json:"l1"`
L2 []*Chain `json:"l2"`
descriptors.DevnetEnvironment
}
// KurtosisDeployer handles deploying packages using Kurtosis
......@@ -162,10 +131,10 @@ func NewKurtosisDeployer(opts ...KurtosisDeployerOptions) (*KurtosisDeployer, er
return d, nil
}
func (d *KurtosisDeployer) getWallets(wallets deployer.WalletList) WalletMap {
walletMap := make(WalletMap)
func (d *KurtosisDeployer) getWallets(wallets deployer.WalletList) descriptors.WalletMap {
walletMap := make(descriptors.WalletMap)
for _, wallet := range wallets {
walletMap[wallet.Name] = Wallet{
walletMap[wallet.Name] = descriptors.Wallet{
Address: wallet.Address,
PrivateKey: wallet.PrivateKey,
}
......@@ -193,20 +162,22 @@ func (d *KurtosisDeployer) GetEnvironmentInfo(ctx context.Context, spec *spec.En
}
env := &KurtosisEnvironment{
L2: make([]*Chain, 0, len(spec.Chains)),
DevnetEnvironment: descriptors.DevnetEnvironment{
L2: make([]*descriptors.Chain, 0, len(spec.Chains)),
},
}
// Find L1 endpoint
finder := NewServiceFinder(inspectResult.UserServices)
if nodes, services := finder.FindL1Services(); len(nodes) > 0 {
chain := &Chain{
chain := &descriptors.Chain{
Name: "Ethereum",
Services: services,
Nodes: nodes,
JWT: jwtData.L1JWT,
}
if deployerState.State != nil {
chain.Addresses = deployerState.State.Addresses
chain.Addresses = descriptors.AddressMap(deployerState.State.Addresses)
chain.Wallets = d.getWallets(deployerState.Wallets)
}
env.L1 = chain
......@@ -216,7 +187,7 @@ func (d *KurtosisDeployer) GetEnvironmentInfo(ctx context.Context, spec *spec.En
for _, chainSpec := range spec.Chains {
nodes, services := finder.FindL2Services(chainSpec.Name)
chain := &Chain{
chain := &descriptors.Chain{
Name: chainSpec.Name,
ID: chainSpec.NetworkID,
Services: services,
......@@ -227,7 +198,7 @@ func (d *KurtosisDeployer) GetEnvironmentInfo(ctx context.Context, spec *spec.En
// Add contract addresses if available
if deployerState.State != nil && deployerState.State.Deployments != nil {
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 {
chain.Wallets = d.getWallets(wallets.Wallets)
......
......@@ -7,6 +7,7 @@ import (
"strings"
"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/interfaces"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/kurtosis/sources/deployer"
......@@ -248,11 +249,11 @@ func TestGetEnvironmentInfo(t *testing.T) {
}
// Create expected L1 services
l1Services := make(ServiceMap)
l1Services["el"] = Service{
l1Services := make(descriptors.ServiceMap)
l1Services["el"] = descriptors.Service{
Name: "el-1-geth-lighthouse",
Endpoints: EndpointMap{
"rpc": inspect.PortInfo{Port: 52645},
Endpoints: descriptors.EndpointMap{
"rpc": descriptors.PortInfo{Port: 52645},
},
}
......@@ -273,22 +274,24 @@ func TestGetEnvironmentInfo(t *testing.T) {
deploy: &deployer.DeployerData{Wallets: testWallets},
jwt: testJWTs,
want: &KurtosisEnvironment{
L1: &Chain{
Name: "Ethereum",
Services: make(ServiceMap),
Nodes: []Node{
{
Services: l1Services,
DevnetEnvironment: descriptors.DevnetEnvironment{
L1: &descriptors.Chain{
Name: "Ethereum",
Services: make(descriptors.ServiceMap),
Nodes: []descriptors.Node{
{
Services: l1Services,
},
},
JWT: testJWTs.L1JWT,
},
JWT: testJWTs.L1JWT,
},
L2: []*Chain{
{
Name: "op-kurtosis",
ID: "1234",
Services: make(ServiceMap),
JWT: testJWTs.L2JWT,
L2: []*descriptors.Chain{
{
Name: "op-kurtosis",
ID: "1234",
Services: make(descriptors.ServiceMap),
JWT: testJWTs.L2JWT,
},
},
},
},
......
......@@ -3,16 +3,11 @@ package inspect
import (
"context"
"github.com/ethereum-optimism/optimism/kurtosis-devnet/pkg/descriptors"
"github.com/kurtosis-tech/kurtosis/api/golang/engine/lib/kurtosis_context"
)
// PortInfo contains the host and port number for a service port
type PortInfo struct {
Host string `json:"host"`
Port int `json:"port"`
}
type PortMap map[string]PortInfo
type PortMap map[string]descriptors.PortInfo
type ServiceMap map[string]PortMap
......@@ -70,7 +65,7 @@ func (e *Inspector) ExtractData(ctx context.Context) (*InspectData, error) {
portMap := make(PortMap)
for port, portSpec := range svcCtx.GetPublicPorts() {
portMap[port] = PortInfo{
portMap[port] = descriptors.PortInfo{
Host: svcCtx.GetMaybePublicIPAddress(),
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