refactor(blockchain): align service names with AX paths
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
2818f1fed9
commit
d6d05e5399
8 changed files with 76 additions and 46 deletions
|
|
@ -46,7 +46,7 @@ func runExplorer(dataDir, seed string, testnet bool) error {
|
|||
defer s.Close()
|
||||
|
||||
c := chain.New(s)
|
||||
cfg, forks := resolveConfig(testnet, &seed)
|
||||
cfg, forks := resolveChainConfig(testnet, &seed)
|
||||
|
||||
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT)
|
||||
defer cancel()
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ func runServe(dataDir, seed string, testnet bool, rpcBind, rpcPort, walletRPC st
|
|||
defer s.Close()
|
||||
|
||||
c := chain.New(s)
|
||||
cfg, forks := resolveConfig(testnet, &seed)
|
||||
cfg, forks := resolveChainConfig(testnet, &seed)
|
||||
|
||||
// Set genesis hash for testnet.
|
||||
if testnet {
|
||||
|
|
@ -124,9 +124,9 @@ func rpcSyncLoop(ctx context.Context, c *chain.Chain, cfg *config.ChainConfig, f
|
|||
Forks: forks,
|
||||
}
|
||||
|
||||
// Derive RPC URL from seed address (replace P2P port with RPC port).
|
||||
// Derive the RPC URL from the seed address.
|
||||
rpcURL := core.Sprintf("http://%s", seed)
|
||||
// If seed has P2P port, swap to RPC.
|
||||
// Swap the peer port for the RPC port when the seed uses a default network address.
|
||||
if core.Contains(seed, ":46942") {
|
||||
rpcURL = "http://127.0.0.1:46941"
|
||||
} else if core.Contains(seed, ":36942") {
|
||||
|
|
|
|||
|
|
@ -12,18 +12,18 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newStatusCmd(dataDir, seed *string, testnet *bool) *cobra.Command {
|
||||
func newStatusCmd(seed *string) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "status",
|
||||
Short: "Show chain and network status",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runStatus(*seed, *testnet)
|
||||
return runStatus(*seed)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func runStatus(seed string, testnet bool) error {
|
||||
rpcURL := seedToRPC(seed, testnet)
|
||||
func runStatus(seed string) error {
|
||||
rpcURL := seedToRPC(seed)
|
||||
client := rpc.NewClient(rpcURL)
|
||||
|
||||
info, err := client.GetInfo()
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ func runSyncForeground(dataDir, seed string, testnet bool) error {
|
|||
defer s.Close()
|
||||
|
||||
c := chain.New(s)
|
||||
cfg, forks := resolveConfig(testnet, &seed)
|
||||
cfg, forks := resolveChainConfig(testnet, &seed)
|
||||
|
||||
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer cancel()
|
||||
|
|
@ -100,7 +100,7 @@ func runSyncDaemon(dataDir, seed string, testnet bool) error {
|
|||
defer s.Close()
|
||||
|
||||
c := chain.New(s)
|
||||
cfg, forks := resolveConfig(testnet, &seed)
|
||||
cfg, forks := resolveChainConfig(testnet, &seed)
|
||||
|
||||
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer cancel()
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ func newWalletSeedCmd(walletFile *string) *cobra.Command {
|
|||
|
||||
func runWalletCreate(walletFile string) error {
|
||||
if walletFile == "" {
|
||||
walletFile = core.JoinPath(defaultDataDir(), "wallet.db")
|
||||
walletFile = core.JoinPath(defaultChainDataDir(), "wallet.db")
|
||||
}
|
||||
|
||||
if err := ensureDataDir(core.PathBase(walletFile)); err != nil {
|
||||
|
|
@ -114,7 +114,7 @@ func runWalletCreate(walletFile string) error {
|
|||
|
||||
func runWalletAddress(walletFile string) error {
|
||||
if walletFile == "" {
|
||||
walletFile = core.JoinPath(defaultDataDir(), "wallet.db")
|
||||
walletFile = core.JoinPath(defaultChainDataDir(), "wallet.db")
|
||||
}
|
||||
|
||||
s, err := store.New(walletFile)
|
||||
|
|
@ -135,7 +135,7 @@ func runWalletAddress(walletFile string) error {
|
|||
|
||||
func runWalletSeed(walletFile string) error {
|
||||
if walletFile == "" {
|
||||
walletFile = core.JoinPath(defaultDataDir(), "wallet.db")
|
||||
walletFile = core.JoinPath(defaultChainDataDir(), "wallet.db")
|
||||
}
|
||||
|
||||
s, err := store.New(walletFile)
|
||||
|
|
@ -175,7 +175,7 @@ func newWalletScanCmd(walletFile *string) *cobra.Command {
|
|||
|
||||
func runWalletScan(walletFile, daemonURL string) error {
|
||||
if walletFile == "" {
|
||||
walletFile = core.JoinPath(defaultDataDir(), "wallet.db")
|
||||
walletFile = core.JoinPath(defaultChainDataDir(), "wallet.db")
|
||||
}
|
||||
|
||||
s, err := store.New(walletFile)
|
||||
|
|
@ -312,7 +312,7 @@ func newWalletRestoreCmd(walletFile *string) *cobra.Command {
|
|||
|
||||
func runWalletRestore(walletFile, seed string) error {
|
||||
if walletFile == "" {
|
||||
walletFile = core.JoinPath(defaultDataDir(), "wallet-restored.db")
|
||||
walletFile = core.JoinPath(defaultChainDataDir(), "wallet-restored.db")
|
||||
}
|
||||
|
||||
account, err := wallet.RestoreFromSeed(seed)
|
||||
|
|
@ -405,7 +405,7 @@ func newWalletInfoCmd(walletFile *string) *cobra.Command {
|
|||
|
||||
func runWalletInfo(walletFile string) error {
|
||||
if walletFile == "" {
|
||||
walletFile = core.JoinPath(defaultDataDir(), "wallet.db")
|
||||
walletFile = core.JoinPath(defaultChainDataDir(), "wallet.db")
|
||||
}
|
||||
|
||||
s, err := store.New(walletFile)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ func AddChainCommands(root *cobra.Command) {
|
|||
Long: "Manage the Lethean blockchain — sync, explore, and mine.",
|
||||
}
|
||||
|
||||
chainCmd.PersistentFlags().StringVar(&dataDir, "data-dir", defaultDataDir(), "blockchain data directory")
|
||||
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().BoolVar(&testnet, "testnet", false, "use testnet")
|
||||
|
||||
|
|
@ -38,13 +38,13 @@ func AddChainCommands(root *cobra.Command) {
|
|||
newExplorerCmd(&dataDir, &seed, &testnet),
|
||||
newSyncCmd(&dataDir, &seed, &testnet),
|
||||
newServeCmd(&dataDir, &seed, &testnet),
|
||||
newStatusCmd(&dataDir, &seed, &testnet),
|
||||
newStatusCmd(&seed),
|
||||
)
|
||||
|
||||
root.AddCommand(chainCmd)
|
||||
}
|
||||
|
||||
func resolveConfig(testnet bool, seed *string) (config.ChainConfig, []config.HardFork) {
|
||||
func resolveChainConfig(testnet bool, seed *string) (config.ChainConfig, []config.HardFork) {
|
||||
if testnet {
|
||||
if *seed == "seeds.lthn.io:36942" {
|
||||
*seed = "localhost:46942"
|
||||
|
|
@ -54,7 +54,7 @@ func resolveConfig(testnet bool, seed *string) (config.ChainConfig, []config.Har
|
|||
return config.Mainnet, config.MainnetForks
|
||||
}
|
||||
|
||||
func defaultDataDir() string {
|
||||
func defaultChainDataDir() string {
|
||||
home := core.Env("DIR_HOME")
|
||||
if home == "" {
|
||||
return ".lethean"
|
||||
|
|
|
|||
56
service.go
56
service.go
|
|
@ -6,8 +6,8 @@ package blockchain
|
|||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"dappco.re/go/core"
|
||||
|
||||
|
|
@ -18,18 +18,29 @@ import (
|
|||
)
|
||||
|
||||
// BlockchainOptions configures the blockchain service.
|
||||
//
|
||||
// Usage: opts := blockchain.BlockchainOptions{DataDir: "/var/lib/core", Testnet: true}
|
||||
type BlockchainOptions struct {
|
||||
// DataDir is the persistent chain data directory.
|
||||
// Usage: opts := blockchain.BlockchainOptions{DataDir: "/var/lib/core"}
|
||||
DataDir string
|
||||
Seed string
|
||||
// Seed is the bootstrap peer address used for RPC sync.
|
||||
// Usage: opts := blockchain.BlockchainOptions{Seed: "127.0.0.1:46942"}
|
||||
Seed string
|
||||
// Testnet switches the service onto the testnet genesis and forks.
|
||||
// Usage: opts := blockchain.BlockchainOptions{Testnet: true}
|
||||
Testnet bool
|
||||
// RPCPort is the JSON-RPC port exposed by the embedded daemon.
|
||||
// Usage: opts := blockchain.BlockchainOptions{RPCPort: "47941"}
|
||||
RPCPort string
|
||||
// RPCBind is the bind address for the embedded daemon.
|
||||
// Usage: opts := blockchain.BlockchainOptions{RPCBind: "127.0.0.1"}
|
||||
RPCBind string
|
||||
}
|
||||
|
||||
// BlockchainService is a Core-managed blockchain node.
|
||||
//
|
||||
// svc := blockchain.NewBlockchainService(c, opts)
|
||||
// c.RegisterService("blockchain", svc)
|
||||
// Usage: svc := blockchain.NewBlockchainService(c, opts)
|
||||
type BlockchainService struct {
|
||||
core *core.Core
|
||||
opts BlockchainOptions
|
||||
|
|
@ -43,7 +54,7 @@ type BlockchainService struct {
|
|||
|
||||
// NewBlockchainService creates and registers the blockchain as a Core service.
|
||||
//
|
||||
// svc := blockchain.NewBlockchainService(c, opts)
|
||||
// Usage: svc := blockchain.NewBlockchainService(c, opts)
|
||||
func NewBlockchainService(c *core.Core, opts BlockchainOptions) *BlockchainService {
|
||||
svc := &BlockchainService{core: c, opts: opts}
|
||||
|
||||
|
|
@ -56,11 +67,11 @@ func NewBlockchainService(c *core.Core, opts BlockchainOptions) *BlockchainServi
|
|||
})
|
||||
|
||||
// Register blockchain actions.
|
||||
c.Action("blockchain.height", svc.actionHeight)
|
||||
c.Action("blockchain.info", svc.actionInfo)
|
||||
c.Action("blockchain.block", svc.actionBlock)
|
||||
c.Action("blockchain.aliases", svc.actionAliases)
|
||||
c.Action("blockchain.alias", svc.actionAlias)
|
||||
c.Action("blockchain.chain.height", svc.actionChainHeight)
|
||||
c.Action("blockchain.chain.info", svc.actionChainInfo)
|
||||
c.Action("blockchain.chain.block", svc.actionChainBlock)
|
||||
c.Action("blockchain.alias.list", svc.actionAliasList)
|
||||
c.Action("blockchain.alias.get", svc.actionAliasGet)
|
||||
c.Action("blockchain.wallet.create", svc.actionWalletCreate)
|
||||
|
||||
return svc
|
||||
|
|
@ -94,20 +105,20 @@ func (s *BlockchainService) start() core.Result {
|
|||
// Wire sync progress events
|
||||
s.chain.SetSyncCallback(func(localHeight, remoteHeight uint64, blocksPerSecond float64) {
|
||||
s.events.Emit(Event{Type: EventSyncProgress, Height: localHeight, Data: map[string]interface{}{
|
||||
"local_height": localHeight,
|
||||
"remote_height": remoteHeight,
|
||||
"blocks_per_sec": blocksPerSecond,
|
||||
"local_height": localHeight,
|
||||
"remote_height": remoteHeight,
|
||||
"blocks_per_sec": blocksPerSecond,
|
||||
}})
|
||||
})
|
||||
|
||||
cfg, forks := resolveConfig(s.opts.Testnet, &s.opts.Seed)
|
||||
cfg, forks := resolveChainConfig(s.opts.Testnet, &s.opts.Seed)
|
||||
|
||||
// Start background sync.
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
s.cancel = cancel
|
||||
|
||||
go func() {
|
||||
client := rpc.NewClient(seedToRPC(s.opts.Seed, s.opts.Testnet))
|
||||
client := rpc.NewClient(seedToRPC(s.opts.Seed))
|
||||
opts := chain.SyncOptions{Forks: forks}
|
||||
for {
|
||||
select {
|
||||
|
|
@ -154,12 +165,12 @@ func (s *BlockchainService) stop() core.Result {
|
|||
|
||||
// --- Actions ---
|
||||
|
||||
func (s *BlockchainService) actionHeight(ctx context.Context, opts core.Options) core.Result {
|
||||
func (s *BlockchainService) actionChainHeight(ctx context.Context, opts core.Options) core.Result {
|
||||
h, _ := s.chain.Height()
|
||||
return core.Result{Value: h, OK: true}
|
||||
}
|
||||
|
||||
func (s *BlockchainService) actionInfo(ctx context.Context, opts core.Options) core.Result {
|
||||
func (s *BlockchainService) actionChainInfo(ctx context.Context, opts core.Options) core.Result {
|
||||
h, _ := s.chain.Height()
|
||||
_, meta, _ := s.chain.TopBlock()
|
||||
aliases := s.chain.GetAllAliases()
|
||||
|
|
@ -171,7 +182,7 @@ func (s *BlockchainService) actionInfo(ctx context.Context, opts core.Options) c
|
|||
}, OK: true}
|
||||
}
|
||||
|
||||
func (s *BlockchainService) actionBlock(ctx context.Context, opts core.Options) core.Result {
|
||||
func (s *BlockchainService) actionChainBlock(ctx context.Context, opts core.Options) core.Result {
|
||||
height := uint64(opts.Int("height"))
|
||||
blk, meta, err := s.chain.GetBlockByHeight(height)
|
||||
if err != nil {
|
||||
|
|
@ -184,11 +195,11 @@ func (s *BlockchainService) actionBlock(ctx context.Context, opts core.Options)
|
|||
}, OK: true}
|
||||
}
|
||||
|
||||
func (s *BlockchainService) actionAliases(ctx context.Context, opts core.Options) core.Result {
|
||||
func (s *BlockchainService) actionAliasList(ctx context.Context, opts core.Options) core.Result {
|
||||
return core.Result{Value: s.chain.GetAllAliases(), OK: true}
|
||||
}
|
||||
|
||||
func (s *BlockchainService) actionAlias(ctx context.Context, opts core.Options) core.Result {
|
||||
func (s *BlockchainService) actionAliasGet(ctx context.Context, opts core.Options) core.Result {
|
||||
name := opts.String("name")
|
||||
alias, err := s.chain.GetAlias(name)
|
||||
if err != nil {
|
||||
|
|
@ -204,7 +215,8 @@ func (s *BlockchainService) actionWalletCreate(ctx context.Context, opts core.Op
|
|||
|
||||
// --- Helpers ---
|
||||
|
||||
func seedToRPC(seed string, testnet bool) string {
|
||||
// Usage: url := seedToRPC("127.0.0.1:46942")
|
||||
func seedToRPC(seed string) string {
|
||||
if core.Contains(seed, ":46942") {
|
||||
return "http://127.0.0.1:46941"
|
||||
}
|
||||
|
|
@ -215,6 +227,8 @@ func seedToRPC(seed string, testnet bool) string {
|
|||
}
|
||||
|
||||
// SyncStatus returns the current sync state.
|
||||
//
|
||||
// Usage: status := svc.SyncStatus()
|
||||
func (s *BlockchainService) SyncStatus() map[string]interface{} {
|
||||
if s.chain == nil {
|
||||
return map[string]interface{}{"synced": false, "height": 0}
|
||||
|
|
|
|||
|
|
@ -22,16 +22,32 @@ func TestBlockchainService_New_Good(t *testing.T) {
|
|||
if svc.opts.Testnet != true {
|
||||
t.Error("expected testnet")
|
||||
}
|
||||
expectedActions := []string{
|
||||
"blockchain.chain.height",
|
||||
"blockchain.chain.info",
|
||||
"blockchain.chain.block",
|
||||
"blockchain.alias.list",
|
||||
"blockchain.alias.get",
|
||||
"blockchain.wallet.create",
|
||||
}
|
||||
for _, name := range expectedActions {
|
||||
if !c.Action(name).Exists() {
|
||||
t.Fatalf("expected action %s to be registered", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBlockchainService_SeedToRPC_Good(t *testing.T) {
|
||||
tests := []struct{ seed string; testnet bool; want string }{
|
||||
{"127.0.0.1:46942", true, "http://127.0.0.1:46941"},
|
||||
{"127.0.0.1:36942", false, "http://127.0.0.1:36941"},
|
||||
{"10.0.0.1:9999", false, "http://10.0.0.1:9999"},
|
||||
tests := []struct {
|
||||
seed string
|
||||
want string
|
||||
}{
|
||||
{"127.0.0.1:46942", "http://127.0.0.1:46941"},
|
||||
{"127.0.0.1:36942", "http://127.0.0.1:36941"},
|
||||
{"10.0.0.1:9999", "http://10.0.0.1:9999"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
got := seedToRPC(tt.seed, tt.testnet)
|
||||
got := seedToRPC(tt.seed)
|
||||
if got != tt.want {
|
||||
t.Errorf("seedToRPC(%s): got %s, want %s", tt.seed, got, tt.want)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue