Commit 9742e404 authored by Yann Hodique's avatar Yann Hodique Committed by GitHub

fix(kurtosis-devnet): accommodate new wallets format (#13622)

parent d590f97d
......@@ -28,6 +28,7 @@ type Chain struct {
Services EndpointMap `json:"services,omitempty"`
Nodes []Node `json:"nodes"`
Addresses deployer.DeploymentAddresses `json:"addresses,omitempty"`
Wallets WalletMap `json:"wallets,omitempty"`
}
type Wallet struct {
......@@ -41,7 +42,6 @@ type WalletMap map[string]Wallet
type KurtosisEnvironment struct {
L1 *Chain `json:"l1"`
L2 []*Chain `json:"l2"`
Wallets WalletMap `json:"wallets"`
}
// KurtosisDeployer handles deploying packages using Kurtosis
......@@ -165,7 +165,6 @@ func (d *KurtosisDeployer) getEnvironmentInfo(ctx context.Context, spec *spec.En
env := &KurtosisEnvironment{
L2: make([]*Chain, 0, len(spec.Chains)),
Wallets: d.getWallets(deployerState.Wallets),
}
// Find L1 endpoint
......@@ -178,6 +177,7 @@ func (d *KurtosisDeployer) getEnvironmentInfo(ctx context.Context, spec *spec.En
}
if deployerState.State != nil {
chain.Addresses = deployerState.State.Addresses
chain.Wallets = d.getWallets(deployerState.Wallets)
}
env.L1 = chain
}
......@@ -196,7 +196,10 @@ 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
chain.Addresses = addresses.Addresses
}
if wallets, ok := deployerState.State.Deployments[chainSpec.NetworkID]; ok {
chain.Wallets = d.getWallets(wallets.Wallets)
}
}
......
......@@ -7,7 +7,6 @@ import (
"fmt"
"io"
"math/big"
"os/exec"
"strings"
)
......@@ -25,8 +24,13 @@ type DeploymentAddresses map[string]string
// DeploymentStateAddresses maps chain IDs to their contract addresses
type DeploymentStateAddresses map[string]DeploymentAddresses
type DeploymentState struct {
Addresses DeploymentAddresses `json:"addresses"`
Wallets WalletList `json:"wallets"`
}
type DeployerState struct {
Deployments DeploymentStateAddresses `json:"l2s"`
Deployments map[string]DeploymentState `json:"l2s"`
Addresses DeploymentAddresses `json:"superchain"`
}
......@@ -111,7 +115,9 @@ func NewDeployer(enclave string, opts ...DeployerOption) *Deployer {
}
// parseWalletsFile parses a JSON file containing wallet information
func parseWalletsFile(r io.Reader) (WalletList, error) {
func parseWalletsFile(r io.Reader) (map[string]WalletList, error) {
result := make(map[string]WalletList)
// Read all data from reader
data, err := io.ReadAll(r)
if err != nil {
......@@ -119,16 +125,17 @@ func parseWalletsFile(r io.Reader) (WalletList, error) {
}
// Unmarshal into a map first
var rawData map[string]string
var rawData map[string]map[string]string
if err := json.Unmarshal(data, &rawData); err != nil {
return nil, fmt.Errorf("failed to decode wallet file: %w", err)
}
for id, chain := range rawData {
// Create a map to store wallets by name
walletMap := make(map[string]Wallet)
// Process each key-value pair
for key, value := range rawData {
for key, value := range chain {
if strings.HasSuffix(key, "Address") {
name := strings.TrimSuffix(key, "Address")
wallet := walletMap[name]
......@@ -145,26 +152,19 @@ func parseWalletsFile(r io.Reader) (WalletList, error) {
}
// Convert map to list
result := make(WalletList, 0, len(walletMap))
wl := make(WalletList, 0, len(walletMap))
for _, wallet := range walletMap {
// Only include wallets that have at least an address
if wallet.Address != "" {
result = append(result, &wallet)
wl = append(wl, &wallet)
}
}
return result, nil
}
// downloadArtifact downloads a kurtosis artifact to a temporary directory
// TODO: reimplement this using the kurtosis SDK
func downloadArtifact(enclave, artifact, destDir string) error {
cmd := exec.Command("kurtosis", "files", "download", enclave, artifact, destDir)
if err := cmd.Run(); err != nil {
return fmt.Errorf("failed to download artifact %s: %w", artifact, err)
result[id] = wl
}
return nil
return result, nil
}
// hexToDecimal converts a hex string (with or without 0x prefix) to a decimal string
......@@ -190,7 +190,7 @@ func parseStateFile(r io.Reader) (*DeployerState, error) {
}
result := &DeployerState{
Deployments: make(DeploymentStateAddresses),
Deployments: make(map[string]DeploymentState),
Addresses: make(DeploymentAddresses),
}
......@@ -225,7 +225,9 @@ func parseStateFile(r io.Reader) (*DeployerState, error) {
addresses := mapDeployment(deployment)
if len(addresses) > 0 {
result.Deployments[id] = addresses
result.Deployments[id] = DeploymentState{
Addresses: addresses,
}
}
}
......@@ -269,12 +271,17 @@ func (d *Deployer) ExtractData(ctx context.Context) (*DeployerData, error) {
return nil, err
}
for id, wallets := range wallets {
if deployment, exists := state.Deployments[id]; exists {
deployment.Wallets = wallets
state.Deployments[id] = deployment
}
}
knownWallets, err := d.getKnownWallets(ctx, fs)
if err != nil {
return nil, err
}
wallets = append(wallets, knownWallets...)
return &DeployerData{State: state, Wallets: wallets}, nil
return &DeployerData{State: state, Wallets: knownWallets}, nil
}
package deployer
import (
"os"
"sort"
"strings"
"testing"
......@@ -67,7 +66,7 @@ func TestParseStateFile(t *testing.T) {
require.True(t, ok, "Chain %s not found in result", tt.chainID)
for key, expected := range tt.expected {
actual := chain[key]
actual := chain.Addresses[key]
require.Equal(t, expected, actual, "Chain %s, %s: expected %s, got %s", tt.chainID, key, expected, actual)
}
}
......@@ -138,33 +137,25 @@ func TestParseStateFileErrors(t *testing.T) {
}
}
func TestDownloadArtifact(t *testing.T) {
// Create a temporary directory for testing
tmpDir, err := os.MkdirTemp("", "test-artifact-*")
require.NoError(t, err, "Failed to create temp dir")
defer os.RemoveAll(tmpDir)
// Test with invalid enclave
err = downloadArtifact("invalid-enclave", "invalid-artifact", tmpDir)
require.Error(t, err, "Expected error for invalid enclave")
}
func TestParseWalletsFile(t *testing.T) {
tests := []struct {
name string
input string
want WalletList
want map[string]WalletList
wantErr bool
}{
{
name: "successful parse",
input: `{
"chain1": {
"proposerPrivateKey": "0xe1ec816e9ad0372e458c474a06e1e6d9e7f7985cbf642a5e5fa44be639789531",
"proposerAddress": "0xDFfA3C478Be83a91286c04721d2e5DF9A133b93F",
"batcherPrivateKey": "0x557313b816b8fb354340883edf86627b3de680a9f3e15aa1f522cbe6f9c7b967",
"batcherAddress": "0x6bd90c2a1AE00384AD9F4BcD76310F54A9CcdA11"
}
}`,
want: WalletList{
want: map[string]WalletList{
"chain1": {
{
Name: "proposer",
Address: "0xDFfA3C478Be83a91286c04721d2e5DF9A133b93F",
......@@ -176,28 +167,36 @@ func TestParseWalletsFile(t *testing.T) {
PrivateKey: "0x557313b816b8fb354340883edf86627b3de680a9f3e15aa1f522cbe6f9c7b967",
},
},
},
wantErr: false,
},
{
name: "address only",
input: `{
"chain1": {
"proposerAddress": "0xDFfA3C478Be83a91286c04721d2e5DF9A133b93F"
}
}`,
want: WalletList{
want: map[string]WalletList{
"chain1": {
{
Name: "proposer",
Address: "0xDFfA3C478Be83a91286c04721d2e5DF9A133b93F",
},
},
},
wantErr: false,
},
{
name: "private key only - should be ignored",
input: `{
"chain1": {
"proposerPrivateKey": "0xe1ec816e9ad0372e458c474a06e1e6d9e7f7985cbf642a5e5fa44be639789531"
}
}`,
want: WalletList{},
want: map[string]WalletList{
"chain1": {},
},
wantErr: false,
},
{
......@@ -209,7 +208,7 @@ func TestParseWalletsFile(t *testing.T) {
{
name: "empty input",
input: `{}`,
want: WalletList{},
want: map[string]WalletList{},
wantErr: false,
},
}
......@@ -234,10 +233,12 @@ func TestParseWalletsFile(t *testing.T) {
})
}
sortWallets(got)
sortWallets(tt.want)
require.Equal(t, tt.want, got)
for chainID, wallets := range got {
sortWallets(wallets)
wantWallets := tt.want[chainID]
sortWallets(wantWallets)
require.Equal(t, wantWallets, wallets)
}
})
}
}
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