Commit 37c44291 authored by Yann Hodique's avatar Yann Hodique Committed by GitHub

fix(kurtosis-devnet): ensure localPrestate is idempotent (#13725)

parent 86632e48
......@@ -110,18 +110,36 @@ type PrestateInfo struct {
Hashes map[string]string `json:"hashes"`
}
func (m *Main) localPrestateOption(dir string) tmpl.TemplateContextOptions {
prestateBuilder := build.NewPrestateBuilder(
build.WithPrestateBaseDir(m.cfg.baseDir),
build.WithPrestateDryRun(m.cfg.dryRun),
)
type localPrestateHolder struct {
info *PrestateInfo
baseDir string
buildDir string
dryRun bool
builder *build.PrestateBuilder
}
func newLocalPrestateHolder(baseDir string, buildDir string, dryRun bool) *localPrestateHolder {
return &localPrestateHolder{
baseDir: baseDir,
buildDir: buildDir,
dryRun: dryRun,
builder: build.NewPrestateBuilder(
build.WithPrestateBaseDir(baseDir),
build.WithPrestateDryRun(dryRun),
),
}
}
func (h *localPrestateHolder) GetPrestateInfo() (*PrestateInfo, error) {
if h.info != nil {
return h.info, nil
}
return tmpl.WithFunction("localPrestate", func() (*PrestateInfo, error) {
prestatePath := []string{"proofs", "op-program", "cannon"}
prestateURL := fileserverURL(prestatePath...)
// Create build directory with the final path structure
buildDir := filepath.Join(append([]string{dir}, prestatePath...)...)
buildDir := filepath.Join(append([]string{h.buildDir}, prestatePath...)...)
if err := os.MkdirAll(buildDir, 0755); err != nil {
return nil, fmt.Errorf("failed to create prestate build directory: %w", err)
}
......@@ -131,7 +149,8 @@ func (m *Main) localPrestateOption(dir string) tmpl.TemplateContextOptions {
Hashes: make(map[string]string),
}
if m.cfg.dryRun {
if h.dryRun {
h.info = info
return info, nil
}
......@@ -143,7 +162,7 @@ func (m *Main) localPrestateOption(dir string) tmpl.TemplateContextOptions {
}
// Build all prestate files directly in the target directory
if err := prestateBuilder.Build(buildDir); err != nil {
if err := h.builder.Build(buildDir); err != nil {
return nil, fmt.Errorf("failed to build prestates: %w", err)
}
......@@ -190,7 +209,15 @@ func (m *Main) localPrestateOption(dir string) tmpl.TemplateContextOptions {
log.Printf("%s available at: %s/%s\n", filepath.Base(binFilePath), prestateURL, newBinFileName)
}
h.info = info
return info, nil
}
func (m *Main) localPrestateOption(dir string) tmpl.TemplateContextOptions {
holder := newLocalPrestateHolder(m.cfg.baseDir, dir, m.cfg.dryRun)
return tmpl.WithFunction("localPrestate", func() (*PrestateInfo, error) {
return holder.GetPrestateInfo()
})
}
......
......@@ -15,6 +15,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/urfave/cli/v2"
"gopkg.in/yaml.v3"
)
type mockDeployer struct {
......@@ -290,8 +291,17 @@ _prestate-build target:
// Create template context with just the prestate function
tmplCtx := tmpl.NewTemplateContext(m.localPrestateOption(tmpDir))
// Test template
template := `prestate_url: {{(localPrestate).URL}}`
// Test template with multiple calls to localPrestate
template := `first:
url: {{(localPrestate).URL}}
hashes:
game: {{index (localPrestate).Hashes "game"}}
proof: {{index (localPrestate).Hashes "proof"}}
second:
url: {{(localPrestate).URL}}
hashes:
game: {{index (localPrestate).Hashes "game"}}
proof: {{index (localPrestate).Hashes "proof"}}`
buf := bytes.NewBuffer(nil)
err = tmplCtx.InstantiateTemplate(bytes.NewBufferString(template), buf)
......@@ -305,7 +315,25 @@ _prestate-build target:
output := buf.String()
assert.Contains(t, output, "url: http://fileserver/proofs/op-program/cannon")
// Verify the directory was created
// Verify both calls return the same values
var result struct {
First struct {
URL string `yaml:"url"`
Hashes map[string]string `yaml:"hashes"`
} `yaml:"first"`
Second struct {
URL string `yaml:"url"`
Hashes map[string]string `yaml:"hashes"`
} `yaml:"second"`
}
err = yaml.Unmarshal(buf.Bytes(), &result)
require.NoError(t, err)
// Check that both calls returned identical results
assert.Equal(t, result.First.URL, result.Second.URL, "URLs should match")
assert.Equal(t, result.First.Hashes, result.Second.Hashes, "Hashes should match")
// Verify the directory was created only once
prestateDir := filepath.Join(tmpDir, "proofs", "op-program", "cannon")
assert.DirExists(t, prestateDir)
})
......
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