Skip to content

Commit

Permalink
feat(kurtosis-devnet): add spec data source
Browse files Browse the repository at this point in the history
This enables us to parse the input provided to kurtosis for the
enclave creation, and retrieve some basic information to organize the
dynamic information we'll get from the enclave directly.

Namely, the name and network ID for each chain created.
  • Loading branch information
sigma committed Dec 19, 2024
1 parent ea5d830 commit 33a7f33
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 1 deletion.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ require (
golang.org/x/sync v0.10.0
golang.org/x/term v0.25.0
golang.org/x/time v0.7.0
gopkg.in/yaml.v3 v3.0.1
)

require (
Expand Down Expand Up @@ -247,7 +248,6 @@ require (
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/blake3 v1.3.0 // indirect
rsc.io/tmplfunc v0.0.3 // indirect
)
Expand Down
81 changes: 81 additions & 0 deletions kurtosis-devnet/pkg/kurtosis/sources/spec/spec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package spec

import (
"fmt"
"io"

"gopkg.in/yaml.v3"
)

// ChainSpec represents the network parameters for a chain
type ChainSpec struct {
Name string
NetworkID string
}

// EnclaveSpec represents the parsed chain specifications from the YAML
type EnclaveSpec struct {
Chains []ChainSpec
}

// NetworkParams represents the network parameters section in the YAML
type NetworkParams struct {
Name string `yaml:"name"`
NetworkID string `yaml:"network_id"`
}

// ChainConfig represents a chain configuration in the YAML
type ChainConfig struct {
NetworkParams NetworkParams `yaml:"network_params"`
}

// OptimismPackage represents the optimism_package section in the YAML
type OptimismPackage struct {
Chains []ChainConfig `yaml:"chains"`
}

// YAMLSpec represents the root of the YAML document
type YAMLSpec struct {
OptimismPackage OptimismPackage `yaml:"optimism_package"`
}

type Spec struct{}

type SpecOption func(*Spec)

func NewSpec(opts ...SpecOption) *Spec {
s := &Spec{}
for _, opt := range opts {
opt(s)
}
return s
}

// ExtractData parses a YAML document and returns the chain specifications
func (s *Spec) ExtractData(r io.Reader) (*EnclaveSpec, error) {
var yamlSpec YAMLSpec
decoder := yaml.NewDecoder(r)
if err := decoder.Decode(&yamlSpec); err != nil {
if err == io.EOF {
// Return empty spec for empty input
return &EnclaveSpec{
Chains: make([]ChainSpec, 0),
}, nil
}
return nil, fmt.Errorf("failed to decode YAML: %w", err)
}

result := &EnclaveSpec{
Chains: make([]ChainSpec, 0, len(yamlSpec.OptimismPackage.Chains)),
}

// Extract chain specifications
for _, chain := range yamlSpec.OptimismPackage.Chains {
result.Chains = append(result.Chains, ChainSpec{
Name: chain.NetworkParams.Name,
NetworkID: chain.NetworkParams.NetworkID,
})
}

return result, nil
}
107 changes: 107 additions & 0 deletions kurtosis-devnet/pkg/kurtosis/sources/spec/spec_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package spec

import (
"strings"
"testing"
)

func TestParseSpec(t *testing.T) {
yamlContent := `
optimism_package:
chains:
- participants:
- el_type: op-geth
network_params:
name: op-rollup-one
network_id: "3151909"
additional_services:
- blockscout
- participants:
- el_type: op-geth
network_params:
name: op-rollup-two
network_id: "3151910"
additional_services:
- blockscout
ethereum_package:
participants:
- el_type: geth
- el_type: reth
network_params:
preset: minimal
genesis_delay: 5
`

result, err := NewSpec().ExtractData(strings.NewReader(yamlContent))
if err != nil {
t.Fatalf("Failed to parse YAML: %v", err)
}

expectedChains := []ChainSpec{
{
Name: "op-rollup-one",
NetworkID: "3151909",
},
{
Name: "op-rollup-two",
NetworkID: "3151910",
},
}

if len(result.Chains) != len(expectedChains) {
t.Fatalf("Expected %d chains, got %d", len(expectedChains), len(result.Chains))
}

for i, expected := range expectedChains {
actual := result.Chains[i]
if actual.Name != expected.Name {
t.Errorf("Chain %d: expected name %q, got %q", i, expected.Name, actual.Name)
}
if actual.NetworkID != expected.NetworkID {
t.Errorf("Chain %d: expected network ID %q, got %q", i, expected.NetworkID, actual.NetworkID)
}
}
}

func TestParseSpecErrors(t *testing.T) {
tests := []struct {
name string
yaml string
wantErr bool
}{
{
name: "empty yaml",
yaml: "",
},
{
name: "invalid yaml",
yaml: "invalid: [yaml: content",
wantErr: true,
},
{
name: "missing network params",
yaml: `
optimism_package:
chains:
- participants:
- el_type: op-geth
additional_services:
- blockscout`,
},
{
name: "missing chains",
yaml: `
optimism_package:
other_field: value`,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := NewSpec().ExtractData(strings.NewReader(tt.yaml))
if (err != nil) != tt.wantErr {
t.Errorf("ParseSpec() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

0 comments on commit 33a7f33

Please sign in to comment.