From a2df164822b7055598faa7fbef4835d0c7e14ac4 Mon Sep 17 00:00:00 2001 From: Virgil Date: Sat, 4 Apr 2026 04:18:37 +0000 Subject: [PATCH] refactor(blockchain): spell out command sync names Co-Authored-By: Charon --- chain_commands.go | 22 ++++++++++++---------- explorer_command.go | 21 +++++++++++++-------- sync_command.go | 45 ++++++++++++++++++++++++++------------------- sync_loop.go | 36 ++++++++++++++++++------------------ 4 files changed, 69 insertions(+), 55 deletions(-) diff --git a/chain_commands.go b/chain_commands.go index d80833c..08cd8ce 100644 --- a/chain_commands.go +++ b/chain_commands.go @@ -16,6 +16,8 @@ import ( "github.com/spf13/cobra" ) +const defaultChainSeed = "seeds.lthn.io:36942" + // AddChainCommands registers the `chain` command group on a Cobra root. // // Example: @@ -37,8 +39,8 @@ func AddChainCommands(root *cobra.Command) { Long: "Manage the Lethean blockchain — sync, explore, and mine.", } - chainCmd.PersistentFlags().StringVar(&dataDir, "data-dir", defaultChainDataDir(), "blockchain data directory") - chainCmd.PersistentFlags().StringVar(&seed, "seed", "seeds.lthn.io:36942", "seed peer address (host:port)") + chainCmd.PersistentFlags().StringVar(&dataDir, "data-dir", defaultChainDataDirPath(), "blockchain data directory") + chainCmd.PersistentFlags().StringVar(&seed, "seed", defaultChainSeed, "seed peer address (host:port)") chainCmd.PersistentFlags().BoolVar(&testnet, "testnet", false, "use testnet") chainCmd.AddCommand( @@ -49,17 +51,17 @@ func AddChainCommands(root *cobra.Command) { root.AddCommand(chainCmd) } -func resolveChainConfig(testnet bool, seed *string) (config.ChainConfig, []config.HardFork) { +func chainConfigForSeed(testnet bool, seed string) (config.ChainConfig, []config.HardFork, string) { if testnet { - if *seed == "seeds.lthn.io:36942" { - *seed = "localhost:46942" + if seed == defaultChainSeed { + seed = "localhost:46942" } - return config.Testnet, config.TestnetForks + return config.Testnet, config.TestnetForks, seed } - return config.Mainnet, config.MainnetForks + return config.Mainnet, config.MainnetForks, seed } -func defaultChainDataDir() string { +func defaultChainDataDirPath() string { home, err := os.UserHomeDir() if err != nil { return ".lethean" @@ -67,9 +69,9 @@ func defaultChainDataDir() string { return filepath.Join(home, ".lethean", "chain") } -func ensureChainDataDir(dataDir string) error { +func ensureChainDataDirExists(dataDir string) error { if err := coreio.Local.EnsureDir(dataDir); err != nil { - return coreerr.E("ensureChainDataDir", "create data dir", err) + return coreerr.E("ensureChainDataDirExists", "create data dir", err) } return nil } diff --git a/explorer_command.go b/explorer_command.go index a3a5d27..e6f9cca 100644 --- a/explorer_command.go +++ b/explorer_command.go @@ -23,6 +23,11 @@ import ( ) // newChainExplorerCommand builds the interactive `chain explorer` command. +// +// Example: +// +// chain explorer --data-dir ~/.lethean/chain +// // Use it alongside `AddChainCommands` to expose the TUI node view. func newChainExplorerCommand(dataDir, seed *string, testnet *bool) *cobra.Command { return &cobra.Command{ @@ -36,19 +41,19 @@ func newChainExplorerCommand(dataDir, seed *string, testnet *bool) *cobra.Comman } func runChainExplorer(dataDir, seed string, testnet bool) error { - if err := ensureChainDataDir(dataDir); err != nil { + if err := ensureChainDataDirExists(dataDir); err != nil { return err } dbPath := filepath.Join(dataDir, "chain.db") - s, err := store.New(dbPath) + chainStore, err := store.New(dbPath) if err != nil { return coreerr.E("runChainExplorer", "open store", err) } - defer s.Close() + defer chainStore.Close() - c := chain.New(s) - cfg, forks := resolveChainConfig(testnet, &seed) + blockchain := chain.New(chainStore) + chainConfig, hardForks, resolvedSeed := chainConfigForSeed(testnet, seed) ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) defer cancel() @@ -57,12 +62,12 @@ func runChainExplorer(dataDir, seed string, testnet bool) error { wg.Add(1) go func() { defer wg.Done() - runChainSyncLoop(ctx, c, &cfg, forks, seed) + runChainSyncLoop(ctx, blockchain, &chainConfig, hardForks, resolvedSeed) }() - node := tui.NewNode(c) + node := tui.NewNode(blockchain) status := tui.NewStatusModel(node) - explorer := tui.NewExplorerModel(c) + explorer := tui.NewExplorerModel(blockchain) hints := tui.NewKeyHintsModel() frame := cli.NewFrame("HCF") diff --git a/sync_command.go b/sync_command.go index 983a4dc..1a2e3ce 100644 --- a/sync_command.go +++ b/sync_command.go @@ -24,6 +24,13 @@ import ( ) // newChainSyncCommand builds the `chain sync` command family. +// +// Example: +// +// chain sync +// chain sync --daemon +// chain sync --stop +// // It keeps the foreground and daemon modes behind a predictable command path. func newChainSyncCommand(dataDir, seed *string, testnet *bool) *cobra.Command { var ( @@ -53,37 +60,37 @@ func newChainSyncCommand(dataDir, seed *string, testnet *bool) *cobra.Command { } func runChainSyncForeground(dataDir, seed string, testnet bool) error { - if err := ensureChainDataDir(dataDir); err != nil { + if err := ensureChainDataDirExists(dataDir); err != nil { return err } dbPath := filepath.Join(dataDir, "chain.db") - s, err := store.New(dbPath) + chainStore, err := store.New(dbPath) if err != nil { return coreerr.E("runChainSyncForeground", "open store", err) } - defer s.Close() + defer chainStore.Close() - c := chain.New(s) - cfg, forks := resolveChainConfig(testnet, &seed) + blockchain := chain.New(chainStore) + chainConfig, hardForks, resolvedSeed := chainConfigForSeed(testnet, seed) ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer cancel() log.Println("Starting headless P2P sync...") - runChainSyncLoop(ctx, c, &cfg, forks, seed) + runChainSyncLoop(ctx, blockchain, &chainConfig, hardForks, resolvedSeed) log.Println("Sync stopped.") return nil } func runChainSyncDaemon(dataDir, seed string, testnet bool) error { - if err := ensureChainDataDir(dataDir); err != nil { + if err := ensureChainDataDirExists(dataDir); err != nil { return err } pidFile := filepath.Join(dataDir, "sync.pid") - d := process.NewDaemon(process.DaemonOptions{ + daemon := process.NewDaemon(process.DaemonOptions{ PIDFile: pidFile, Registry: process.DefaultRegistry(), RegistryEntry: process.DaemonEntry{ @@ -92,35 +99,35 @@ func runChainSyncDaemon(dataDir, seed string, testnet bool) error { }, }) - if err := d.Start(); err != nil { + if err := daemon.Start(); err != nil { return coreerr.E("runChainSyncDaemon", "daemon start", err) } dbPath := filepath.Join(dataDir, "chain.db") - s, err := store.New(dbPath) + chainStore, err := store.New(dbPath) if err != nil { - _ = d.Stop() + _ = daemon.Stop() return coreerr.E("runChainSyncDaemon", "open store", err) } - defer s.Close() + defer chainStore.Close() - c := chain.New(s) - cfg, forks := resolveChainConfig(testnet, &seed) + blockchain := chain.New(chainStore) + chainConfig, hardForks, resolvedSeed := chainConfigForSeed(testnet, seed) ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer cancel() - d.SetReady(true) + daemon.SetReady(true) log.Println("Sync daemon started.") var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() - runChainSyncLoop(ctx, c, &cfg, forks, seed) + runChainSyncLoop(ctx, blockchain, &chainConfig, hardForks, resolvedSeed) }() - err = d.Run(ctx) + err = daemon.Run(ctx) wg.Wait() // Wait for the sync loop to finish before closing the store. return err } @@ -132,12 +139,12 @@ func stopChainSyncDaemon(dataDir string) error { return coreerr.E("stopChainSyncDaemon", "no running sync daemon found", nil) } - proc, err := os.FindProcess(pid) + processHandle, err := os.FindProcess(pid) if err != nil { return coreerr.E("stopChainSyncDaemon", fmt.Sprintf("find process %d", pid), err) } - if err := proc.Signal(syscall.SIGTERM); err != nil { + if err := processHandle.Signal(syscall.SIGTERM); err != nil { return coreerr.E("stopChainSyncDaemon", fmt.Sprintf("signal process %d", pid), err) } diff --git a/sync_loop.go b/sync_loop.go index 6172487..7125ee9 100644 --- a/sync_loop.go +++ b/sync_loop.go @@ -22,10 +22,10 @@ import ( levin "dappco.re/go/core/p2p/node/levin" ) -func runChainSyncLoop(ctx context.Context, c *chain.Chain, cfg *config.ChainConfig, forks []config.HardFork, seed string) { +func runChainSyncLoop(ctx context.Context, blockchain *chain.Chain, chainConfig *config.ChainConfig, hardForks []config.HardFork, seed string) { opts := chain.SyncOptions{ VerifySignatures: false, - Forks: forks, + Forks: hardForks, } for { @@ -35,7 +35,7 @@ func runChainSyncLoop(ctx context.Context, c *chain.Chain, cfg *config.ChainConf default: } - if err := runChainSyncOnce(ctx, c, cfg, opts, seed); err != nil { + if err := runChainSyncOnce(ctx, blockchain, chainConfig, opts, seed); err != nil { log.Printf("sync: %v (retrying in 10s)", err) select { case <-ctx.Done(): @@ -53,24 +53,24 @@ func runChainSyncLoop(ctx context.Context, c *chain.Chain, cfg *config.ChainConf } } -func runChainSyncOnce(ctx context.Context, c *chain.Chain, cfg *config.ChainConfig, opts chain.SyncOptions, seed string) error { +func runChainSyncOnce(ctx context.Context, blockchain *chain.Chain, chainConfig *config.ChainConfig, opts chain.SyncOptions, seed string) error { conn, err := net.DialTimeout("tcp", seed, 10*time.Second) if err != nil { return coreerr.E("runChainSyncOnce", fmt.Sprintf("dial %s", seed), err) } defer conn.Close() - lc := levin.NewConnection(conn) + levinConn := levin.NewConnection(conn) - var peerIDBuf [8]byte - rand.Read(peerIDBuf[:]) - peerID := binary.LittleEndian.Uint64(peerIDBuf[:]) + var peerIDBytes [8]byte + rand.Read(peerIDBytes[:]) + peerID := binary.LittleEndian.Uint64(peerIDBytes[:]) - localHeight, _ := c.Height() + localHeight, _ := blockchain.Height() - req := p2p.HandshakeRequest{ + handshakeReq := p2p.HandshakeRequest{ NodeData: p2p.NodeData{ - NetworkID: cfg.NetworkID, + NetworkID: chainConfig.NetworkID, PeerID: peerID, LocalTime: time.Now().Unix(), MyPort: 0, @@ -81,15 +81,15 @@ func runChainSyncOnce(ctx context.Context, c *chain.Chain, cfg *config.ChainConf NonPruningMode: true, }, } - payload, err := p2p.EncodeHandshakeRequest(&req) + payload, err := p2p.EncodeHandshakeRequest(&handshakeReq) if err != nil { return coreerr.E("runChainSyncOnce", "encode handshake", err) } - if err := lc.WritePacket(p2p.CommandHandshake, payload, true); err != nil { + if err := levinConn.WritePacket(p2p.CommandHandshake, payload, true); err != nil { return coreerr.E("runChainSyncOnce", "write handshake", err) } - hdr, data, err := lc.ReadPacket() + hdr, data, err := levinConn.ReadPacket() if err != nil { return coreerr.E("runChainSyncOnce", "read handshake", err) } @@ -97,8 +97,8 @@ func runChainSyncOnce(ctx context.Context, c *chain.Chain, cfg *config.ChainConf return coreerr.E("runChainSyncOnce", fmt.Sprintf("unexpected command %d", hdr.Command), nil) } - var resp p2p.HandshakeResponse - if err := resp.Decode(data); err != nil { + var handshakeResp p2p.HandshakeResponse + if err := handshakeResp.Decode(data); err != nil { return coreerr.E("runChainSyncOnce", "decode handshake", err) } @@ -107,7 +107,7 @@ func runChainSyncOnce(ctx context.Context, c *chain.Chain, cfg *config.ChainConf ClientVersion: config.ClientVersion, NonPruningMode: true, } - p2pConn := chain.NewLevinP2PConn(lc, resp.PayloadData.CurrentHeight, localSync) + p2pConn := chain.NewLevinP2PConn(levinConn, handshakeResp.PayloadData.CurrentHeight, localSync) - return c.P2PSync(ctx, p2pConn, opts) + return blockchain.P2PSync(ctx, p2pConn, opts) }