From 8bf70f1597130c61e6934505bce12e0fa7790e64 Mon Sep 17 00:00:00 2001 From: kangeunchan Date: Fri, 27 Feb 2026 10:25:15 +0900 Subject: [PATCH] refactor(architecture): remove app-layer infra dependencies Signed-off-by: kangeunchan --- cmd/devnet-builder/commands/manage/deploy.go | 12 +-- internal/application/devnet/docker_deploy.go | 5 +- internal/application/devnet/export.go | 90 +++++++++++++++---- internal/application/devnet/export_test.go | 39 +++++--- internal/application/devnet/provision.go | 71 ++++++++++----- .../application/ports/export_dependencies.go | 19 ++++ internal/application/ports/provisioner.go | 40 +++++++-- internal/application/ports/repositories.go | 8 ++ internal/application/service.go | 33 ++----- internal/di/container.go | 6 +- internal/di/providers/devnet.go | 6 +- internal/infrastructure/export/repository.go | 15 ++++ internal/plugin/types/genesis.go | 43 +++------ 13 files changed, 252 insertions(+), 135 deletions(-) create mode 100644 internal/application/ports/export_dependencies.go diff --git a/cmd/devnet-builder/commands/manage/deploy.go b/cmd/devnet-builder/commands/manage/deploy.go index 84dfd747..15f4df17 100644 --- a/cmd/devnet-builder/commands/manage/deploy.go +++ b/cmd/devnet-builder/commands/manage/deploy.go @@ -343,18 +343,8 @@ For more information, see: https://github.com/altuslabsxyz/devnet-builder/blob/m return fmt.Errorf("unknown blockchain network: %s (available: %v)", deployBlockchainNetwork, available) } - // Get network module for DI container - networkModule, err := network.Get(deployBlockchainNetwork) - if err != nil { - return fmt.Errorf("failed to get network module: %w", err) - } - // Check if devnet already exists - svc, err := application.GetServiceWithConfig(application.ServiceConfig{ - HomeDir: homeDir, - NetworkModule: networkModule, - DockerMode: deployMode == string(types.ExecutionModeDocker), - }) + svc, err := application.GetService(homeDir) if err != nil { return fmt.Errorf("failed to initialize service: %w", err) } diff --git a/internal/application/devnet/docker_deploy.go b/internal/application/devnet/docker_deploy.go index 1f3bc54a..869e1cc4 100644 --- a/internal/application/devnet/docker_deploy.go +++ b/internal/application/devnet/docker_deploy.go @@ -11,7 +11,6 @@ import ( "github.com/altuslabsxyz/devnet-builder/internal/application/dto" "github.com/altuslabsxyz/devnet-builder/internal/application/ports" domainports "github.com/altuslabsxyz/devnet-builder/internal/domain/ports" - "github.com/altuslabsxyz/devnet-builder/internal/infrastructure/node" "github.com/altuslabsxyz/devnet-builder/types" ) @@ -281,9 +280,9 @@ func (uc *DockerDestroyUseCase) findDevnetContainers(ctx context.Context, networ } // GetDefaultNodePorts returns default ports for a node at given index in Docker mode -func GetDefaultNodePorts(basePort, nodeIndex int) *node.NodePorts { +func GetDefaultNodePorts(basePort, nodeIndex int) *ports.PortConfig { offset := nodeIndex * 100 - return &node.NodePorts{ + return &ports.PortConfig{ RPC: basePort + offset, P2P: basePort + offset + 1, GRPC: basePort + offset + 2, diff --git a/internal/application/devnet/export.go b/internal/application/devnet/export.go index a0544ba5..e196dc5e 100644 --- a/internal/application/devnet/export.go +++ b/internal/application/devnet/export.go @@ -10,8 +10,6 @@ import ( "github.com/altuslabsxyz/devnet-builder/internal/application/dto" "github.com/altuslabsxyz/devnet-builder/internal/application/ports" domainExport "github.com/altuslabsxyz/devnet-builder/internal/domain/export" - infraExport "github.com/altuslabsxyz/devnet-builder/internal/infrastructure/export" - infraprocess "github.com/altuslabsxyz/devnet-builder/internal/infrastructure/process" "github.com/altuslabsxyz/devnet-builder/types" ) @@ -23,10 +21,9 @@ type ExportUseCase struct { nodeRepo ports.NodeRepository exportRepo ports.ExportRepository nodeLifecycle ports.NodeLifecycleManager // Injected for stop-export-start workflow - hashCalc *infraExport.HashCalculator - heightResolver *infraExport.HeightResolver - exportExec *infraExport.ExportExecutor - processExec ports.ProcessExecutor + hashCalc ports.ExportHashCalculator + heightResolver ports.ExportHeightResolver + exportExec ports.ExportExecutor logger ports.Logger } @@ -41,17 +38,49 @@ func NewExportUseCase( nodeLifecycle ports.NodeLifecycleManager, logger ports.Logger, ) *ExportUseCase { - processExec := infraprocess.NewLocalExecutor() + return NewExportUseCaseWithDeps( + ctx, + devnetRepo, + nodeRepo, + exportRepo, + nodeLifecycle, + logger, + &missingExportHashCalculator{}, + &missingExportHeightResolver{}, + &missingExportExecutor{}, + ) +} + +// NewExportUseCaseWithDeps creates an ExportUseCase with explicitly injected dependencies. +func NewExportUseCaseWithDeps( + ctx context.Context, + devnetRepo ports.DevnetRepository, + nodeRepo ports.NodeRepository, + exportRepo ports.ExportRepository, + nodeLifecycle ports.NodeLifecycleManager, + logger ports.Logger, + hashCalc ports.ExportHashCalculator, + heightResolver ports.ExportHeightResolver, + exportExec ports.ExportExecutor, +) *ExportUseCase { + if hashCalc == nil { + hashCalc = &missingExportHashCalculator{} + } + if heightResolver == nil { + heightResolver = &missingExportHeightResolver{} + } + if exportExec == nil { + exportExec = &missingExportExecutor{} + } return &ExportUseCase{ devnetRepo: devnetRepo, nodeRepo: nodeRepo, exportRepo: exportRepo, nodeLifecycle: nodeLifecycle, - hashCalc: infraExport.NewHashCalculator(), - heightResolver: infraExport.NewHeightResolver(), - exportExec: infraExport.NewExportExecutor(), - processExec: processExec, + hashCalc: hashCalc, + heightResolver: heightResolver, + exportExec: exportExec, logger: logger, } } @@ -319,18 +348,23 @@ func (uc *ExportUseCase) Inspect(ctx context.Context, exportPath string) (*dto.E return nil, fmt.Errorf("failed to validate export: %w", err) } - result, ok := resultInterface.(*infraExport.ValidationResult) + result, ok := resultInterface.(ports.ExportValidationResult) if !ok { return nil, fmt.Errorf("invalid validation result type") } + exportEntity, ok := result.ExportEntity().(*domainExport.Export) + if !ok { + return nil, fmt.Errorf("invalid export entity type") + } + // Calculate directory size size, _ := calculateDirectorySize(exportPath) // Calculate genesis file checksum if the file exists var genesisChecksum string - if result.Export.GenesisFilePath != "" { - checksum, err := uc.hashCalc.CalculateHash(result.Export.GenesisFilePath) + if exportEntity.GenesisFilePath != "" { + checksum, err := uc.hashCalc.CalculateHash(exportEntity.GenesisFilePath) if err == nil { genesisChecksum = checksum } @@ -338,10 +372,10 @@ func (uc *ExportUseCase) Inspect(ctx context.Context, exportPath string) (*dto.E } output := &dto.ExportInspectOutput{ - Metadata: result.Export.Metadata, + Metadata: exportEntity.Metadata, GenesisChecksum: genesisChecksum, - IsComplete: result.IsComplete, - MissingFiles: result.MissingFiles, + IsComplete: result.IsExportComplete(), + MissingFiles: result.ExportMissingFiles(), SizeBytes: size, } @@ -364,3 +398,25 @@ func calculateDirectorySize(path string) (int64, error) { return size, err } + +type missingExportHashCalculator struct{} + +func (m *missingExportHashCalculator) CalculateHash(_ string) (string, error) { + return "", fmt.Errorf("export hash calculator is not configured") +} + +type missingExportHeightResolver struct{} + +func (m *missingExportHeightResolver) GetCurrentHeight(_ context.Context, _ string) (int64, error) { + return 0, fmt.Errorf("export height resolver is not configured") +} + +type missingExportExecutor struct{} + +func (m *missingExportExecutor) GetBinaryVersion(_ context.Context, _ string) (string, error) { + return "", fmt.Errorf("export executor is not configured") +} + +func (m *missingExportExecutor) ExportAtHeight(_ context.Context, _, _ string, _ int64, _ string) (string, error) { + return "", fmt.Errorf("export executor is not configured") +} diff --git a/internal/application/devnet/export_test.go b/internal/application/devnet/export_test.go index 965bae24..9b1e86e1 100644 --- a/internal/application/devnet/export_test.go +++ b/internal/application/devnet/export_test.go @@ -11,7 +11,6 @@ import ( "github.com/altuslabsxyz/devnet-builder/internal/application/dto" "github.com/altuslabsxyz/devnet-builder/internal/application/ports" domainExport "github.com/altuslabsxyz/devnet-builder/internal/domain/export" - infraExport "github.com/altuslabsxyz/devnet-builder/internal/infrastructure/export" "github.com/altuslabsxyz/devnet-builder/types" ) @@ -114,9 +113,25 @@ func (m *mockExportRepository) Validate(ctx context.Context, exportPath string) if m.validateFunc != nil { return m.validateFunc(ctx, exportPath) } - return &infraExport.ValidationResult{ - IsComplete: true, - }, nil + return &mockExportValidationResult{isComplete: true}, nil +} + +type mockExportValidationResult struct { + export *domainExport.Export + isComplete bool + missingFile []string +} + +func (m *mockExportValidationResult) ExportEntity() interface{} { + return m.export +} + +func (m *mockExportValidationResult) IsExportComplete() bool { + return m.isComplete +} + +func (m *mockExportValidationResult) ExportMissingFiles() []string { + return m.missingFile } type mockLogger struct{} @@ -366,10 +381,10 @@ func TestExportUseCase_Inspect_Success(t *testing.T) { exportRepo := &mockExportRepository{ validateFunc: func(ctx context.Context, exportPath string) (interface{}, error) { - return &infraExport.ValidationResult{ - Export: export, - IsComplete: true, - MissingFiles: []string{}, + return &mockExportValidationResult{ + export: export, + isComplete: true, + missingFile: []string{}, }, nil }, } @@ -437,10 +452,10 @@ func TestExportUseCase_Inspect_IncompleteExport(t *testing.T) { exportRepo := &mockExportRepository{ validateFunc: func(ctx context.Context, exportPath string) (interface{}, error) { - return &infraExport.ValidationResult{ - Export: export, - IsComplete: false, - MissingFiles: []string{"genesis.json"}, + return &mockExportValidationResult{ + export: export, + isComplete: false, + missingFile: []string{"genesis.json"}, }, domainExport.ErrExportIncomplete }, } diff --git a/internal/application/devnet/provision.go b/internal/application/devnet/provision.go index 428090cf..ba6ceae6 100644 --- a/internal/application/devnet/provision.go +++ b/internal/application/devnet/provision.go @@ -10,11 +10,10 @@ import ( "time" "github.com/cosmos/cosmos-sdk/types/bech32" + "github.com/pelletier/go-toml/v2" "github.com/altuslabsxyz/devnet-builder/internal/application/dto" "github.com/altuslabsxyz/devnet-builder/internal/application/ports" - "github.com/altuslabsxyz/devnet-builder/internal/infrastructure/stateexport" - "github.com/altuslabsxyz/devnet-builder/internal/infrastructure/tomlutil" "github.com/altuslabsxyz/devnet-builder/internal/paths" "github.com/altuslabsxyz/devnet-builder/types" ) @@ -689,7 +688,7 @@ func (uc *ProvisionUseCase) mergeConfig(filePath string, override []byte) error return fmt.Errorf("failed to read config: %w", err) } - merged, err := tomlutil.MergeTOML(base, override) + merged, err := mergeTOML(base, override) if err != nil { return err } @@ -701,6 +700,52 @@ func (uc *ProvisionUseCase) mergeConfig(filePath string, override []byte) error return nil } +func mergeTOML(base, override []byte) ([]byte, error) { + if len(override) == 0 { + return base, nil + } + if len(base) == 0 { + return override, nil + } + + var baseMap map[string]any + if err := toml.Unmarshal(base, &baseMap); err != nil { + return nil, fmt.Errorf("failed to parse base TOML: %w", err) + } + + var overrideMap map[string]any + if err := toml.Unmarshal(override, &overrideMap); err != nil { + return nil, fmt.Errorf("failed to parse override TOML: %w", err) + } + + deepMergeTOML(baseMap, overrideMap) + + merged, err := toml.Marshal(baseMap) + if err != nil { + return nil, fmt.Errorf("failed to marshal merged TOML: %w", err) + } + + return merged, nil +} + +func deepMergeTOML(base, override map[string]any) { + for key, overrideVal := range override { + baseVal, exists := base[key] + if !exists { + base[key] = overrideVal + continue + } + + baseMap, baseIsMap := baseVal.(map[string]any) + overrideMap, overrideIsMap := overrideVal.(map[string]any) + if baseIsMap && overrideIsMap { + deepMergeTOML(baseMap, overrideMap) + continue + } + base[key] = overrideVal + } +} + // buildPersistentPeers builds the persistent peers string from node metadata. // Format: node_id@127.0.0.1:p2p_port,node_id@127.0.0.1:p2p_port,... func (uc *ProvisionUseCase) buildPersistentPeers(nodes []*ports.NodeMetadata) string { @@ -758,26 +803,6 @@ func (uc *ProvisionUseCase) exportGenesisFromSnapshot(ctx context.Context, input uc.logger.Success("Using cached snapshot") } - // Step 1.5: Check genesis cache BEFORE extraction - // If snapshot was cached and genesis cache exists, use it directly - if fromCache && cacheKey != "" && !input.NoCache { - cache, err := stateexport.GetValidGenesisCache(input.HomeDir, cacheKey) - if err == nil && cache != nil { - // Verify the cached genesis is from the same snapshot - if cache.SnapshotURL == snapshotURL { - // Read cached genesis - genesis, err := os.ReadFile(cache.FilePath) - if err == nil { - uc.logger.Info("Using cached genesis export (expires in %s)", cache.TimeUntilExpiry().Round(time.Minute)) - return genesis, nil - } - uc.logger.Debug("Failed to read cached genesis: %v", err) - } else { - uc.logger.Debug("Cached genesis is from different snapshot, will re-export") - } - } - } - // Create temp directory for extraction and export // The snapshot file itself stays in the cache directory exportDir := filepath.Join(input.HomeDir, "tmp", "state-export") diff --git a/internal/application/ports/export_dependencies.go b/internal/application/ports/export_dependencies.go new file mode 100644 index 00000000..a95d67d1 --- /dev/null +++ b/internal/application/ports/export_dependencies.go @@ -0,0 +1,19 @@ +package ports + +import "context" + +// ExportHashCalculator calculates hashes for exported artifacts. +type ExportHashCalculator interface { + CalculateHash(binaryPath string) (string, error) +} + +// ExportHeightResolver resolves current block height from an RPC endpoint. +type ExportHeightResolver interface { + GetCurrentHeight(ctx context.Context, rpcURL string) (int64, error) +} + +// ExportExecutor executes binary export commands. +type ExportExecutor interface { + GetBinaryVersion(ctx context.Context, binaryPath string) (string, error) + ExportAtHeight(ctx context.Context, binaryPath, homeDir string, height int64, outputPath string) (string, error) +} diff --git a/internal/application/ports/provisioner.go b/internal/application/ports/provisioner.go index 27e56e4f..2706b05a 100644 --- a/internal/application/ports/provisioner.go +++ b/internal/application/ports/provisioner.go @@ -5,10 +5,38 @@ package ports import ( "context" "time" +) + +// GenesisMode specifies how to obtain genesis. +type GenesisMode string - "github.com/altuslabsxyz/devnet-builder/internal/plugin/types" +const ( + GenesisModeRPC GenesisMode = "rpc" + GenesisModeSnapshot GenesisMode = "snapshot" + GenesisModeLocal GenesisMode = "local" + GenesisModeFresh GenesisMode = "fresh" ) +// GenesisSource specifies where to get genesis from. +type GenesisSource struct { + Mode GenesisMode + RPCURL string + SnapshotURL string + LocalPath string + NetworkType string +} + +// GenesisPatchOptions specifies modifications to apply to genesis. +type GenesisPatchOptions struct { + ChainID string + VotingPeriod time.Duration + UnbondingTime time.Duration + InflationRate string + MinGasPrice string + BinaryVersion string + Validators []ValidatorInfo +} + // ============================================================================= // GenesisForker Interface // ============================================================================= @@ -35,10 +63,10 @@ type GenesisForker interface { // ForkOptions specifies options for forking genesis. type ForkOptions struct { // Source specifies where to get genesis from (RPC, snapshot, or local file) - Source types.GenesisSource + Source GenesisSource // PatchOpts specifies modifications to apply to the forked genesis - PatchOpts types.GenesisPatchOptions + PatchOpts GenesisPatchOptions // BinaryPath is required for snapshot export mode BinaryPath string @@ -59,7 +87,7 @@ type ForkResult struct { NewChainID string // SourceMode indicates how the genesis was obtained - SourceMode types.GenesisMode + SourceMode GenesisMode // FetchedAt is when the genesis was fetched FetchedAt time.Time @@ -170,10 +198,10 @@ type ProvisionOptions struct { NumFullNodes int // GenesisSource specifies where to get genesis from - GenesisSource types.GenesisSource + GenesisSource GenesisSource // GenesisPatchOpts specifies modifications to apply to genesis - GenesisPatchOpts types.GenesisPatchOptions + GenesisPatchOpts GenesisPatchOptions // BinaryVersion specifies the version of the binary to use BinaryVersion string diff --git a/internal/application/ports/repositories.go b/internal/application/ports/repositories.go index 2c4c168d..7bc0d60c 100644 --- a/internal/application/ports/repositories.go +++ b/internal/application/ports/repositories.go @@ -204,3 +204,11 @@ type ExportRepository interface { // Validate checks export completeness Validate(ctx context.Context, exportPath string) (interface{}, error) } + +// ExportValidationResult provides a typed view over validation results without +// exposing infrastructure-layer concrete types to the application layer. +type ExportValidationResult interface { + ExportEntity() interface{} + IsExportComplete() bool + ExportMissingFiles() []string +} diff --git a/internal/application/service.go b/internal/application/service.go index 25d6b2a5..6bd04469 100644 --- a/internal/application/service.go +++ b/internal/application/service.go @@ -14,7 +14,6 @@ import ( "github.com/altuslabsxyz/devnet-builder/internal/application/dto" "github.com/altuslabsxyz/devnet-builder/internal/application/ports" "github.com/altuslabsxyz/devnet-builder/internal/di" - "github.com/altuslabsxyz/devnet-builder/internal/infrastructure/network" "github.com/altuslabsxyz/devnet-builder/internal/output" "github.com/altuslabsxyz/devnet-builder/internal/paths" "github.com/altuslabsxyz/devnet-builder/types" @@ -35,7 +34,7 @@ type DevnetService struct { type ServiceConfig struct { HomeDir string Logger *output.Logger - NetworkModule network.NetworkModule + NetworkModule ports.NetworkModule DockerMode bool Options []di.Option } @@ -59,9 +58,10 @@ func NewDevnetServiceWithConfig(cfg ServiceConfig) (*DevnetService, error) { // Create infrastructure factory factory := di.NewInfrastructureFactory(cfg.HomeDir, logger) - // Apply network module if provided + wireOpts := make([]di.Option, 0, len(cfg.Options)+1) + wireOpts = append(wireOpts, cfg.Options...) if cfg.NetworkModule != nil { - factory = factory.WithNetworkModule(cfg.NetworkModule) + wireOpts = append(wireOpts, di.WithNetworkModule(cfg.NetworkModule)) } // Apply docker mode if specified @@ -70,7 +70,7 @@ func NewDevnetServiceWithConfig(cfg ServiceConfig) (*DevnetService, error) { } // Wire container with options - container, err := factory.WireContainer(cfg.Options...) + container, err := factory.WireContainer(wireOpts...) if err != nil { return nil, err } @@ -818,30 +818,7 @@ func (e *NodeNotFoundError) Error() string { } // GetService returns a DevnetService instance using global homeDir. -// It automatically loads the network module if devnet exists with stored blockchain network. func GetService(homeDir string) (*DevnetService, error) { - // Try to load network module from existing devnet metadata - var networkModule network.NetworkModule - - // Check if devnet exists and load its metadata to get blockchain network - metadataPath := paths.DevnetMetadataPath(homeDir) - if data, err := os.ReadFile(metadataPath); err == nil { - var meta struct { - BlockchainNetwork string `json:"blockchain_network"` - } - if json.Unmarshal(data, &meta) == nil && meta.BlockchainNetwork != "" { - if module, err := network.Get(meta.BlockchainNetwork); err == nil { - networkModule = module - } - } - } - - if networkModule != nil { - return GetServiceWithConfig(ServiceConfig{ - HomeDir: homeDir, - NetworkModule: networkModule, - }) - } return NewDevnetService(homeDir, output.DefaultLogger) } diff --git a/internal/di/container.go b/internal/di/container.go index 7647352e..d45e7a94 100644 --- a/internal/di/container.go +++ b/internal/di/container.go @@ -16,6 +16,7 @@ import ( "github.com/altuslabsxyz/devnet-builder/internal/application/dto" "github.com/altuslabsxyz/devnet-builder/internal/application/ports" "github.com/altuslabsxyz/devnet-builder/internal/application/upgrade" + infraexport "github.com/altuslabsxyz/devnet-builder/internal/infrastructure/export" "github.com/altuslabsxyz/devnet-builder/internal/infrastructure/network" "github.com/altuslabsxyz/devnet-builder/internal/infrastructure/persistence" "github.com/altuslabsxyz/devnet-builder/internal/infrastructure/plugin" @@ -852,13 +853,16 @@ func (c *Container) ExportUseCase(ctx context.Context) *appdevnet.ExportUseCase defer c.mu.Unlock() if c.exportUC == nil { - c.exportUC = appdevnet.NewExportUseCase( + c.exportUC = appdevnet.NewExportUseCaseWithDeps( ctx, c.devnetRepo, c.nodeRepo, c.exportRepo, nodeLifecycle, c.LoggerPort(), + infraexport.NewHashCalculator(), + infraexport.NewHeightResolver(), + infraexport.NewExportExecutor(), ) } return c.exportUC diff --git a/internal/di/providers/devnet.go b/internal/di/providers/devnet.go index 425dd5bd..9d083222 100644 --- a/internal/di/providers/devnet.go +++ b/internal/di/providers/devnet.go @@ -8,6 +8,7 @@ import ( appdevnet "github.com/altuslabsxyz/devnet-builder/internal/application/devnet" "github.com/altuslabsxyz/devnet-builder/internal/application/dto" "github.com/altuslabsxyz/devnet-builder/internal/application/ports" + infraexport "github.com/altuslabsxyz/devnet-builder/internal/infrastructure/export" ) // DevnetUseCasesProvider provides access to devnet-related use cases. @@ -165,13 +166,16 @@ func (d *devnetUseCases) ExportUseCase(ctx context.Context) *appdevnet.ExportUse defer d.mu.Unlock() if d.exportUC == nil { - d.exportUC = appdevnet.NewExportUseCase( + d.exportUC = appdevnet.NewExportUseCaseWithDeps( ctx, d.infra.DevnetRepository(), d.infra.NodeRepository(), d.infra.ExportRepository(), nodeLifecycle, d.infra.Logger(), + infraexport.NewHashCalculator(), + infraexport.NewHeightResolver(), + infraexport.NewExportExecutor(), ) } return d.exportUC diff --git a/internal/infrastructure/export/repository.go b/internal/infrastructure/export/repository.go index 289c8624..d74c8253 100644 --- a/internal/infrastructure/export/repository.go +++ b/internal/infrastructure/export/repository.go @@ -261,6 +261,21 @@ type ValidationResult struct { MissingFiles []string } +// ExportEntity exposes the validated export entity through an interface. +func (v *ValidationResult) ExportEntity() interface{} { + return v.Export +} + +// IsExportComplete indicates whether the export is complete. +func (v *ValidationResult) IsExportComplete() bool { + return v.IsComplete +} + +// ExportMissingFiles returns missing files for incomplete exports. +func (v *ValidationResult) ExportMissingFiles() []string { + return v.MissingFiles +} + // GetExportsDirectory returns the exports directory path for a devnet. func (r *Repository) GetExportsDirectory(devnetHomeDir string) string { return paths.ExportsPath(devnetHomeDir) diff --git a/internal/plugin/types/genesis.go b/internal/plugin/types/genesis.go index b015f99e..87234ac9 100644 --- a/internal/plugin/types/genesis.go +++ b/internal/plugin/types/genesis.go @@ -3,55 +3,32 @@ package types import ( "time" + + appports "github.com/altuslabsxyz/devnet-builder/internal/application/ports" ) // GenesisMode specifies how to obtain genesis -type GenesisMode string +type GenesisMode = appports.GenesisMode const ( // GenesisModeRPC fetches genesis directly from RPC endpoint - GenesisModeRPC GenesisMode = "rpc" + GenesisModeRPC GenesisMode = appports.GenesisModeRPC // GenesisModeSnapshot downloads snapshot and exports genesis from state - GenesisModeSnapshot GenesisMode = "snapshot" + GenesisModeSnapshot GenesisMode = appports.GenesisModeSnapshot // GenesisModeLocal uses a local genesis file - GenesisModeLocal GenesisMode = "local" + GenesisModeLocal GenesisMode = appports.GenesisModeLocal // GenesisModeFresh generates a fresh genesis (no forking) - GenesisModeFresh GenesisMode = "fresh" + GenesisModeFresh GenesisMode = appports.GenesisModeFresh ) // GenesisSource specifies where to get genesis from -type GenesisSource struct { - Mode GenesisMode - RPCURL string // for RPC mode - SnapshotURL string // for snapshot mode - LocalPath string // for local mode - NetworkType string // e.g., "mainnet", "testnet" -} +type GenesisSource = appports.GenesisSource // ValidatorInfo represents validator information for genesis injection. -type ValidatorInfo struct { - Moniker string // validator display name - ConsPubKey string // Base64 encoded Ed25519 consensus pubkey - OperatorAddress string // Bech32 valoper address - SelfDelegation string // amount of tokens to self-delegate -} +type ValidatorInfo = appports.ValidatorInfo // GenesisPatchOptions specifies modifications to apply to genesis -type GenesisPatchOptions struct { - ChainID string // new chain ID for the forked network - VotingPeriod time.Duration // governance voting period (e.g., 30s for devnet) - UnbondingTime time.Duration // staking unbonding time (e.g., 60s for devnet) - InflationRate string // inflation rate (e.g., "0.0" for no inflation) - // MinGasPrice is the minimum gas price for node configuration. - // NOTE: This is applied via app.toml node configuration, not genesis patching. - // It is preserved here for completeness but not consumed by PatchGenesis. - MinGasPrice string // minimum gas price (applied via app.toml, not genesis) - BinaryVersion string // binary version/ref used for genesis modification (e.g., "v1.0.0" or commit hash) - // Validators contains validator entries for genesis. - // NOTE: Validator injection is handled by the provisioner/generator layer, - // not by PatchGenesis. This field is passed through for reference. - Validators []ValidatorInfo // validator entries (injected by provisioner, not PatchGenesis) -} +type GenesisPatchOptions = appports.GenesisPatchOptions // DefaultDevnetPatchOptions returns patch options suitable for local devnets func DefaultDevnetPatchOptions(chainID string) GenesisPatchOptions {