diff --git a/apiserver/config/config.go b/apiserver/config/config.go deleted file mode 100644 index feb24b17f..000000000 --- a/apiserver/config/config.go +++ /dev/null @@ -1,106 +0,0 @@ -package config - -import ( - "github.com/daglabs/btcd/apiserver/logger" - "github.com/daglabs/btcd/config" - "github.com/daglabs/btcd/util" - "github.com/jessevdk/go-flags" - "github.com/pkg/errors" - "path/filepath" -) - -const ( - defaultLogFilename = "apiserver.log" - defaultErrLogFilename = "apiserver_err.log" -) - -var ( - // Default configuration options - defaultLogDir = util.AppDataDir("apiserver", false) - defaultDBAddress = "localhost:3306" - defaultHTTPListen = "0.0.0.0:8080" - activeConfig *Config -) - -// ActiveConfig returns the active configuration struct -func ActiveConfig() *Config { - return activeConfig -} - -// Config defines the configuration options for the API server. -type Config struct { - LogDir string `long:"logdir" description:"Directory to log output."` - DebugLevel string `short:"d" long:"debuglevel" description:"Set log level {trace, debug, info, warn, error, critical}"` - RPCUser string `short:"u" long:"rpcuser" description:"RPC username"` - RPCPassword string `short:"P" long:"rpcpass" default-mask:"-" description:"RPC password"` - RPCServer string `short:"s" long:"rpcserver" description:"RPC server to connect to"` - RPCCert string `short:"c" long:"rpccert" description:"RPC server certificate chain for validation"` - DisableTLS bool `long:"notls" description:"Disable TLS"` - DBAddress string `long:"dbaddress" description:"Database address"` - DBUser string `long:"dbuser" description:"Database user" required:"true"` - DBPassword string `long:"dbpass" description:"Database password" required:"true"` - DBName string `long:"dbname" description:"Database name" required:"true"` - HTTPListen string `long:"listen" description:"HTTP address to listen on (default: 0.0.0.0:8080)"` - Migrate bool `long:"migrate" description:"Migrate the database to the latest version. The server will not start when using this flag."` - MQTTBrokerAddress string `long:"mqttaddress" description:"MQTT broker address" required:"false"` - MQTTUser string `long:"mqttuser" description:"MQTT server user" required:"false"` - MQTTPassword string `long:"mqttpass" description:"MQTT server password" required:"false"` - config.NetworkFlags -} - -// Parse parses the CLI arguments and returns a config struct. -func Parse() error { - activeConfig = &Config{ - LogDir: defaultLogDir, - DBAddress: defaultDBAddress, - HTTPListen: defaultHTTPListen, - } - parser := flags.NewParser(activeConfig, flags.PrintErrors|flags.HelpFlag) - _, err := parser.Parse() - if err != nil { - return err - } - - if !activeConfig.Migrate { - if activeConfig.RPCUser == "" { - return errors.New("--rpcuser is required if --migrate flag is not used") - } - if activeConfig.RPCPassword == "" { - return errors.New("--rpcpass is required if --migrate flag is not used") - } - if activeConfig.RPCServer == "" { - return errors.New("--rpcserver is required if --migrate flag is not used") - } - } - - if activeConfig.RPCCert == "" && !activeConfig.DisableTLS { - return errors.New("--notls has to be disabled if --cert is used") - } - - if activeConfig.RPCCert != "" && activeConfig.DisableTLS { - return errors.New("--cert should be omitted if --notls is used") - } - - if (activeConfig.MQTTBrokerAddress != "" || activeConfig.MQTTUser != "" || activeConfig.MQTTPassword != "") && - (activeConfig.MQTTBrokerAddress == "" || activeConfig.MQTTUser == "" || activeConfig.MQTTPassword == "") { - return errors.New("--mqttaddress, --mqttuser, and --mqttpass must be passed all together") - } - - err = activeConfig.ResolveNetwork(parser) - if err != nil { - return err - } - - logFile := filepath.Join(activeConfig.LogDir, defaultLogFilename) - errLogFile := filepath.Join(activeConfig.LogDir, defaultErrLogFilename) - logger.InitLog(logFile, errLogFile) - - if activeConfig.DebugLevel != "" { - err := logger.SetLogLevels(activeConfig.DebugLevel) - if err != nil { - return err - } - } - - return nil -} diff --git a/faucet/config/config.go b/faucet/config/config.go index 6ad412c46..0c8fa2737 100644 --- a/faucet/config/config.go +++ b/faucet/config/config.go @@ -1,8 +1,8 @@ package config import ( - "github.com/daglabs/btcd/apiserver/logger" "github.com/daglabs/btcd/dagconfig" + "github.com/daglabs/btcd/kasparov/logger" "github.com/daglabs/btcd/util" "github.com/jessevdk/go-flags" "github.com/pkg/errors" diff --git a/faucet/database/log.go b/faucet/database/log.go index 23bfa46ff..952e50b69 100644 --- a/faucet/database/log.go +++ b/faucet/database/log.go @@ -1,7 +1,7 @@ package database import "github.com/daglabs/btcd/util/panics" -import "github.com/daglabs/btcd/apiserver/logger" +import "github.com/daglabs/btcd/kasparov/logger" var ( log = logger.BackendLog.Logger("DTBS") diff --git a/faucet/faucet.go b/faucet/faucet.go index 87864eb11..ad419d9c5 100644 --- a/faucet/faucet.go +++ b/faucet/faucet.go @@ -5,10 +5,10 @@ import ( "encoding/hex" "encoding/json" "fmt" - "github.com/daglabs/btcd/apiserver/apimodels" "github.com/daglabs/btcd/blockdag" "github.com/daglabs/btcd/faucet/config" "github.com/daglabs/btcd/httpserverutils" + "github.com/daglabs/btcd/kasparov/server/apimodels" "github.com/daglabs/btcd/txscript" "github.com/daglabs/btcd/util" "github.com/daglabs/btcd/util/daghash" diff --git a/httpserverutils/log.go b/httpserverutils/log.go index 22bceb00b..cf8f68195 100644 --- a/httpserverutils/log.go +++ b/httpserverutils/log.go @@ -1,7 +1,7 @@ package httpserverutils import "github.com/daglabs/btcd/util/panics" -import "github.com/daglabs/btcd/apiserver/logger" +import "github.com/daglabs/btcd/kasparov/logger" var ( log = logger.BackendLog.Logger("UTIL") diff --git a/kasparov/config/config.go b/kasparov/config/config.go new file mode 100644 index 000000000..6b28c1f5b --- /dev/null +++ b/kasparov/config/config.go @@ -0,0 +1,69 @@ +package config + +import ( + "github.com/daglabs/btcd/config" + "github.com/daglabs/btcd/kasparov/logger" + "github.com/jessevdk/go-flags" + "github.com/pkg/errors" + "path/filepath" +) + +var ( + // Default configuration options + defaultDBAddress = "localhost:3306" +) + +// KasparovFlags holds configuration common to both the Kasparov server and the Kasparov daemon. +type KasparovFlags struct { + LogDir string `long:"logdir" description:"Directory to log output."` + DebugLevel string `short:"d" long:"debuglevel" description:"Set log level {trace, debug, info, warn, error, critical}"` + DBAddress string `long:"dbaddress" description:"Database address"` + DBUser string `long:"dbuser" description:"Database user" required:"true"` + DBPassword string `long:"dbpass" description:"Database password" required:"true"` + DBName string `long:"dbname" description:"Database name" required:"true"` + RPCUser string `short:"u" long:"rpcuser" description:"RPC username"` + RPCPassword string `short:"P" long:"rpcpass" default-mask:"-" description:"RPC password"` + RPCServer string `short:"s" long:"rpcserver" description:"RPC server to connect to"` + RPCCert string `short:"c" long:"rpccert" description:"RPC server certificate chain for validation"` + DisableTLS bool `long:"notls" description:"Disable TLS"` + config.NetworkFlags +} + +// ResolveKasparovFlags parses command line arguments and sets KasparovFlags accordingly. +func (kasparovFlags *KasparovFlags) ResolveKasparovFlags(parser *flags.Parser, + defaultLogDir, logFilename, errLogFilename string) error { + if kasparovFlags.LogDir == "" { + kasparovFlags.LogDir = defaultLogDir + } + logFile := filepath.Join(kasparovFlags.LogDir, logFilename) + errLogFile := filepath.Join(kasparovFlags.LogDir, errLogFilename) + logger.InitLog(logFile, errLogFile) + + if kasparovFlags.DebugLevel != "" { + err := logger.SetLogLevels(kasparovFlags.DebugLevel) + if err != nil { + return err + } + } + + if kasparovFlags.DBAddress == "" { + kasparovFlags.DBAddress = defaultDBAddress + } + if kasparovFlags.RPCUser == "" { + return errors.New("--rpcuser is required") + } + if kasparovFlags.RPCPassword == "" { + return errors.New("--rpcpass is required") + } + if kasparovFlags.RPCServer == "" { + return errors.New("--rpcserver is required") + } + + if kasparovFlags.RPCCert == "" && !kasparovFlags.DisableTLS { + return errors.New("--notls has to be disabled if --cert is used") + } + if kasparovFlags.RPCCert != "" && kasparovFlags.DisableTLS { + return errors.New("--cert should be omitted if --notls is used") + } + return kasparovFlags.ResolveNetwork(parser) +} diff --git a/apiserver/database/database.go b/kasparov/database/database.go similarity index 88% rename from apiserver/database/database.go rename to kasparov/database/database.go index 8d4b223ac..f295eb734 100644 --- a/apiserver/database/database.go +++ b/kasparov/database/database.go @@ -3,17 +3,17 @@ package database import ( nativeerrors "errors" "fmt" + "github.com/daglabs/btcd/kasparov/config" "github.com/pkg/errors" "os" - "github.com/daglabs/btcd/apiserver/config" "github.com/golang-migrate/migrate/v4/source" "github.com/jinzhu/gorm" "github.com/golang-migrate/migrate/v4" ) -// db is the API server database. +// db is the Kasparov database. var db *gorm.DB // DB returns a reference to the database connection @@ -33,8 +33,8 @@ func (l gormLogger) Print(v ...interface{}) { // Connect connects to the database mentioned in // config variable. -func Connect() error { - connectionString := buildConnectionString() +func Connect(cfg *config.KasparovFlags) error { + connectionString := buildConnectionString(cfg) migrator, driver, err := openMigrator(connectionString) if err != nil { return err @@ -67,8 +67,7 @@ func Close() error { return err } -func buildConnectionString() string { - cfg := config.ActiveConfig() +func buildConnectionString(cfg *config.KasparovFlags) string { return fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True", cfg.DBUser, cfg.DBPassword, cfg.DBAddress, cfg.DBName) } @@ -99,7 +98,7 @@ func isCurrent(migrator *migrate.Migrate, driver source.Driver) (bool, uint, err } func openMigrator(connectionString string) (*migrate.Migrate, source.Driver, error) { - driver, err := source.Open("file://migrations") + driver, err := source.Open("file://../database/migrations") if err != nil { return nil, nil, err } @@ -112,8 +111,8 @@ func openMigrator(connectionString string) (*migrate.Migrate, source.Driver, err } // Migrate database to the latest version. -func Migrate() error { - connectionString := buildConnectionString() +func Migrate(cfg *config.KasparovFlags) error { + connectionString := buildConnectionString(cfg) migrator, driver, err := openMigrator(connectionString) if err != nil { return err diff --git a/apiserver/database/log.go b/kasparov/database/log.go similarity index 74% rename from apiserver/database/log.go rename to kasparov/database/log.go index cc2f20ff7..2ea4ab615 100644 --- a/apiserver/database/log.go +++ b/kasparov/database/log.go @@ -1,7 +1,7 @@ package database import "github.com/daglabs/btcd/util/panics" -import "github.com/daglabs/btcd/apiserver/logger" +import "github.com/daglabs/btcd/kasparov/logger" var ( log = logger.Logger("DTBS") diff --git a/apiserver/migrations/000001_create_blocks_table.down.sql b/kasparov/database/migrations/000001_create_blocks_table.down.sql similarity index 100% rename from apiserver/migrations/000001_create_blocks_table.down.sql rename to kasparov/database/migrations/000001_create_blocks_table.down.sql diff --git a/apiserver/migrations/000001_create_blocks_table.up.sql b/kasparov/database/migrations/000001_create_blocks_table.up.sql similarity index 100% rename from apiserver/migrations/000001_create_blocks_table.up.sql rename to kasparov/database/migrations/000001_create_blocks_table.up.sql diff --git a/apiserver/migrations/000002_create_parent_blocks_table.down.sql b/kasparov/database/migrations/000002_create_parent_blocks_table.down.sql similarity index 100% rename from apiserver/migrations/000002_create_parent_blocks_table.down.sql rename to kasparov/database/migrations/000002_create_parent_blocks_table.down.sql diff --git a/apiserver/migrations/000002_create_parent_blocks_table.up.sql b/kasparov/database/migrations/000002_create_parent_blocks_table.up.sql similarity index 100% rename from apiserver/migrations/000002_create_parent_blocks_table.up.sql rename to kasparov/database/migrations/000002_create_parent_blocks_table.up.sql diff --git a/apiserver/migrations/000003_create_raw_blocks_table.down.sql b/kasparov/database/migrations/000003_create_raw_blocks_table.down.sql similarity index 100% rename from apiserver/migrations/000003_create_raw_blocks_table.down.sql rename to kasparov/database/migrations/000003_create_raw_blocks_table.down.sql diff --git a/apiserver/migrations/000003_create_raw_blocks_table.up.sql b/kasparov/database/migrations/000003_create_raw_blocks_table.up.sql similarity index 100% rename from apiserver/migrations/000003_create_raw_blocks_table.up.sql rename to kasparov/database/migrations/000003_create_raw_blocks_table.up.sql diff --git a/apiserver/migrations/000004_create_subnetworks_table.down.sql b/kasparov/database/migrations/000004_create_subnetworks_table.down.sql similarity index 100% rename from apiserver/migrations/000004_create_subnetworks_table.down.sql rename to kasparov/database/migrations/000004_create_subnetworks_table.down.sql diff --git a/apiserver/migrations/000004_create_subnetworks_table.up.sql b/kasparov/database/migrations/000004_create_subnetworks_table.up.sql similarity index 100% rename from apiserver/migrations/000004_create_subnetworks_table.up.sql rename to kasparov/database/migrations/000004_create_subnetworks_table.up.sql diff --git a/apiserver/migrations/000005_create_transactions_table.down.sql b/kasparov/database/migrations/000005_create_transactions_table.down.sql similarity index 100% rename from apiserver/migrations/000005_create_transactions_table.down.sql rename to kasparov/database/migrations/000005_create_transactions_table.down.sql diff --git a/apiserver/migrations/000005_create_transactions_table.up.sql b/kasparov/database/migrations/000005_create_transactions_table.up.sql similarity index 100% rename from apiserver/migrations/000005_create_transactions_table.up.sql rename to kasparov/database/migrations/000005_create_transactions_table.up.sql diff --git a/apiserver/migrations/000006_create_transactions_to_blocks_table.down.sql b/kasparov/database/migrations/000006_create_transactions_to_blocks_table.down.sql similarity index 100% rename from apiserver/migrations/000006_create_transactions_to_blocks_table.down.sql rename to kasparov/database/migrations/000006_create_transactions_to_blocks_table.down.sql diff --git a/apiserver/migrations/000006_create_transactions_to_blocks_table.up.sql b/kasparov/database/migrations/000006_create_transactions_to_blocks_table.up.sql similarity index 100% rename from apiserver/migrations/000006_create_transactions_to_blocks_table.up.sql rename to kasparov/database/migrations/000006_create_transactions_to_blocks_table.up.sql diff --git a/apiserver/migrations/000007_create_addresses_table.down.sql b/kasparov/database/migrations/000007_create_addresses_table.down.sql similarity index 100% rename from apiserver/migrations/000007_create_addresses_table.down.sql rename to kasparov/database/migrations/000007_create_addresses_table.down.sql diff --git a/apiserver/migrations/000007_create_addresses_table.up.sql b/kasparov/database/migrations/000007_create_addresses_table.up.sql similarity index 100% rename from apiserver/migrations/000007_create_addresses_table.up.sql rename to kasparov/database/migrations/000007_create_addresses_table.up.sql diff --git a/apiserver/migrations/000008_create_transaction_outputs_table.down.sql b/kasparov/database/migrations/000008_create_transaction_outputs_table.down.sql similarity index 100% rename from apiserver/migrations/000008_create_transaction_outputs_table.down.sql rename to kasparov/database/migrations/000008_create_transaction_outputs_table.down.sql diff --git a/apiserver/migrations/000008_create_transaction_outputs_table.up.sql b/kasparov/database/migrations/000008_create_transaction_outputs_table.up.sql similarity index 100% rename from apiserver/migrations/000008_create_transaction_outputs_table.up.sql rename to kasparov/database/migrations/000008_create_transaction_outputs_table.up.sql diff --git a/apiserver/migrations/000009_create_transaction_inputs_table.down.sql b/kasparov/database/migrations/000009_create_transaction_inputs_table.down.sql similarity index 100% rename from apiserver/migrations/000009_create_transaction_inputs_table.down.sql rename to kasparov/database/migrations/000009_create_transaction_inputs_table.down.sql diff --git a/apiserver/migrations/000009_create_transaction_inputs_table.up.sql b/kasparov/database/migrations/000009_create_transaction_inputs_table.up.sql similarity index 100% rename from apiserver/migrations/000009_create_transaction_inputs_table.up.sql rename to kasparov/database/migrations/000009_create_transaction_inputs_table.up.sql diff --git a/apiserver/dbmodels/models.go b/kasparov/dbmodels/dbmodels.go similarity index 100% rename from apiserver/dbmodels/models.go rename to kasparov/dbmodels/dbmodels.go diff --git a/apiserver/jsonrpc/client.go b/kasparov/jsonrpc/client.go similarity index 96% rename from apiserver/jsonrpc/client.go rename to kasparov/jsonrpc/client.go index 3f4facf4a..3a6291cbc 100644 --- a/apiserver/jsonrpc/client.go +++ b/kasparov/jsonrpc/client.go @@ -1,11 +1,11 @@ package jsonrpc import ( + "github.com/daglabs/btcd/kasparov/config" "github.com/pkg/errors" "io/ioutil" "time" - "github.com/daglabs/btcd/apiserver/config" "github.com/daglabs/btcd/util/daghash" "github.com/daglabs/btcd/rpcclient" @@ -54,8 +54,7 @@ func Close() { } // Connect initiates a connection to the JSON-RPC API Server -func Connect() error { - cfg := config.ActiveConfig() +func Connect(cfg *config.KasparovFlags) error { var cert []byte if !cfg.DisableTLS { var err error diff --git a/apiserver/jsonrpc/log.go b/kasparov/jsonrpc/log.go similarity index 84% rename from apiserver/jsonrpc/log.go rename to kasparov/jsonrpc/log.go index 3f4155726..e1a8271e4 100644 --- a/apiserver/jsonrpc/log.go +++ b/kasparov/jsonrpc/log.go @@ -1,7 +1,7 @@ package jsonrpc import ( - "github.com/daglabs/btcd/apiserver/logger" + "github.com/daglabs/btcd/kasparov/logger" "github.com/daglabs/btcd/rpcclient" "github.com/daglabs/btcd/util/panics" ) diff --git a/apiserver/logger/logger.go b/kasparov/logger/logger.go similarity index 98% rename from apiserver/logger/logger.go rename to kasparov/logger/logger.go index 61f49fc0e..601547d22 100644 --- a/apiserver/logger/logger.go +++ b/kasparov/logger/logger.go @@ -34,7 +34,7 @@ func Logger(subsystemTag string) logs.Logger { return logger } -// SetLogLevels sets the logging level for all of the subsystems in the API server. +// SetLogLevels sets the logging level for all of the subsystems in Kasparov. func SetLogLevels(level string) error { lvl, ok := logs.LevelFromString(level) if !ok { diff --git a/apiserver/apimodels/request_types.go b/kasparov/server/apimodels/request_types.go similarity index 57% rename from apiserver/apimodels/request_types.go rename to kasparov/server/apimodels/request_types.go index 6eeb1e66f..449cb89a8 100644 --- a/apiserver/apimodels/request_types.go +++ b/kasparov/server/apimodels/request_types.go @@ -1,6 +1,6 @@ package apimodels -// RawTransaction represents a raw transaction posted to the API server +// RawTransaction is a json representation of a raw transaction type RawTransaction struct { RawTransaction string `json:"rawTransaction"` } diff --git a/apiserver/apimodels/response_types.go b/kasparov/server/apimodels/response_types.go similarity index 100% rename from apiserver/apimodels/response_types.go rename to kasparov/server/apimodels/response_types.go diff --git a/kasparov/server/config/config.go b/kasparov/server/config/config.go new file mode 100644 index 000000000..b902cd57b --- /dev/null +++ b/kasparov/server/config/config.go @@ -0,0 +1,49 @@ +package config + +import ( + "github.com/daglabs/btcd/kasparov/config" + "github.com/daglabs/btcd/util" + "github.com/jessevdk/go-flags" +) + +const ( + logFilename = "apiserver.log" + errLogFilename = "apiserver_err.log" +) + +var ( + // Default configuration options + defaultLogDir = util.AppDataDir("apiserver", false) + defaultHTTPListen = "0.0.0.0:8080" + activeConfig *Config +) + +// ActiveConfig returns the active configuration struct +func ActiveConfig() *Config { + return activeConfig +} + +// Config defines the configuration options for the API server. +type Config struct { + HTTPListen string `long:"listen" description:"HTTP address to listen on (default: 0.0.0.0:8080)"` + config.KasparovFlags +} + +// Parse parses the CLI arguments and returns a config struct. +func Parse() error { + activeConfig = &Config{ + HTTPListen: defaultHTTPListen, + } + parser := flags.NewParser(activeConfig, flags.PrintErrors|flags.HelpFlag) + _, err := parser.Parse() + if err != nil { + return err + } + + err = activeConfig.ResolveKasparovFlags(parser, defaultLogDir, logFilename, errLogFilename) + if err != nil { + return err + } + + return nil +} diff --git a/apiserver/controllers/block.go b/kasparov/server/controllers/block.go similarity index 95% rename from apiserver/controllers/block.go rename to kasparov/server/controllers/block.go index 218b10ff2..49aaaf8eb 100644 --- a/apiserver/controllers/block.go +++ b/kasparov/server/controllers/block.go @@ -2,14 +2,14 @@ package controllers import ( "encoding/hex" + "github.com/daglabs/btcd/kasparov/database" + "github.com/daglabs/btcd/kasparov/dbmodels" + "github.com/daglabs/btcd/kasparov/server/apimodels" "net/http" - "github.com/daglabs/btcd/apiserver/apimodels" - "github.com/daglabs/btcd/apiserver/dbmodels" "github.com/daglabs/btcd/httpserverutils" "github.com/pkg/errors" - "github.com/daglabs/btcd/apiserver/database" "github.com/daglabs/btcd/util/daghash" ) diff --git a/apiserver/controllers/common.go b/kasparov/server/controllers/common.go similarity index 96% rename from apiserver/controllers/common.go rename to kasparov/server/controllers/common.go index 4b19f68de..f29bf0b3e 100644 --- a/apiserver/controllers/common.go +++ b/kasparov/server/controllers/common.go @@ -2,9 +2,9 @@ package controllers import ( "encoding/hex" - "github.com/daglabs/btcd/apiserver/apimodels" - "github.com/daglabs/btcd/apiserver/dbmodels" "github.com/daglabs/btcd/btcjson" + "github.com/daglabs/btcd/kasparov/dbmodels" + "github.com/daglabs/btcd/kasparov/server/apimodels" ) func convertTxDBModelToTxResponse(tx *dbmodels.Transaction) *apimodels.TransactionResponse { diff --git a/apiserver/controllers/feeestimate.go b/kasparov/server/controllers/feeestimate.go similarity index 85% rename from apiserver/controllers/feeestimate.go rename to kasparov/server/controllers/feeestimate.go index b77062679..0d40d38c1 100644 --- a/apiserver/controllers/feeestimate.go +++ b/kasparov/server/controllers/feeestimate.go @@ -1,7 +1,7 @@ package controllers import ( - "github.com/daglabs/btcd/apiserver/apimodels" + "github.com/daglabs/btcd/kasparov/server/apimodels" ) // GetFeeEstimatesHandler returns the fee estimates for different priorities diff --git a/apiserver/controllers/transaction.go b/kasparov/server/controllers/transaction.go similarity index 97% rename from apiserver/controllers/transaction.go rename to kasparov/server/controllers/transaction.go index 21b551214..993f85fb8 100644 --- a/apiserver/controllers/transaction.go +++ b/kasparov/server/controllers/transaction.go @@ -5,19 +5,19 @@ import ( "encoding/hex" "encoding/json" "fmt" + "github.com/daglabs/btcd/kasparov/database" + "github.com/daglabs/btcd/kasparov/dbmodels" + "github.com/daglabs/btcd/kasparov/jsonrpc" + "github.com/daglabs/btcd/kasparov/server/apimodels" "github.com/daglabs/btcd/util" "net/http" - "github.com/daglabs/btcd/apiserver/apimodels" - "github.com/daglabs/btcd/apiserver/config" - "github.com/daglabs/btcd/apiserver/dbmodels" "github.com/daglabs/btcd/blockdag" "github.com/daglabs/btcd/httpserverutils" + "github.com/daglabs/btcd/kasparov/server/config" "github.com/daglabs/btcd/util/subnetworkid" "github.com/pkg/errors" - "github.com/daglabs/btcd/apiserver/database" - "github.com/daglabs/btcd/apiserver/jsonrpc" "github.com/daglabs/btcd/btcjson" "github.com/daglabs/btcd/util/daghash" "github.com/daglabs/btcd/wire" diff --git a/kasparov/server/docker/Dockerfile b/kasparov/server/docker/Dockerfile new file mode 100644 index 000000000..e43a4f9ac --- /dev/null +++ b/kasparov/server/docker/Dockerfile @@ -0,0 +1,28 @@ +# -- multistage docker build: stage #1: build stage +FROM golang:1.13-alpine AS build + +RUN mkdir -p /go/src/github.com/daglabs/btcd + +WORKDIR /go/src/github.com/daglabs/btcd + +RUN apk add --no-cache curl git + +COPY go.mod . +COPY go.sum . + +RUN go mod download + +COPY . . + +RUN cd kasparov/server && CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o kasparov-server . + +# --- multistage docker build: stage #2: runtime image +FROM alpine +WORKDIR /app + +RUN apk add --no-cache tini + +COPY --from=build /go/src/github.com/daglabs/btcd/kasparov/server/ /app/ + +ENTRYPOINT ["/sbin/tini", "--"] +CMD ["/app/kasparov-server"] diff --git a/apiserver/log.go b/kasparov/server/log.go similarity index 60% rename from apiserver/log.go rename to kasparov/server/log.go index 92e365af3..564159129 100644 --- a/apiserver/log.go +++ b/kasparov/server/log.go @@ -1,11 +1,11 @@ package main import ( - "github.com/daglabs/btcd/apiserver/logger" + "github.com/daglabs/btcd/kasparov/logger" "github.com/daglabs/btcd/util/panics" ) var ( - log = logger.Logger("APIS") + log = logger.Logger("KVSV") spawn = panics.GoroutineWrapperFunc(log) ) diff --git a/kasparov/server/main.go b/kasparov/server/main.go new file mode 100644 index 000000000..744f917a5 --- /dev/null +++ b/kasparov/server/main.go @@ -0,0 +1,54 @@ +package main + +import ( + "fmt" + "github.com/pkg/errors" + "os" + + "github.com/daglabs/btcd/kasparov/database" + "github.com/daglabs/btcd/kasparov/jsonrpc" + "github.com/daglabs/btcd/kasparov/server/config" + "github.com/daglabs/btcd/kasparov/server/server" + "github.com/daglabs/btcd/signal" + "github.com/daglabs/btcd/util/panics" + _ "github.com/golang-migrate/migrate/v4/database/mysql" + _ "github.com/golang-migrate/migrate/v4/source/file" + _ "github.com/jinzhu/gorm/dialects/mysql" +) + +func main() { + defer panics.HandlePanic(log, nil, nil) + + err := config.Parse() + if err != nil { + errString := fmt.Sprintf("Error parsing command-line arguments: %s", err) + _, fErr := fmt.Fprintf(os.Stderr, errString) + if fErr != nil { + panic(errString) + } + return + } + + err = database.Connect(&config.ActiveConfig().KasparovFlags) + if err != nil { + panic(errors.Errorf("Error connecting to database: %s", err)) + } + defer func() { + err := database.Close() + if err != nil { + panic(errors.Errorf("Error closing the database: %s", err)) + } + }() + + err = jsonrpc.Connect(&config.ActiveConfig().KasparovFlags) + if err != nil { + panic(errors.Errorf("Error connecting to servers: %s", err)) + } + defer jsonrpc.Close() + + shutdownServer := server.Start(config.ActiveConfig().HTTPListen) + defer shutdownServer() + + interrupt := signal.InterruptListener() + <-interrupt +} diff --git a/apiserver/server/log.go b/kasparov/server/server/log.go similarity index 74% rename from apiserver/server/log.go rename to kasparov/server/server/log.go index 9609d76b0..7ca522b76 100644 --- a/apiserver/server/log.go +++ b/kasparov/server/server/log.go @@ -1,7 +1,7 @@ package server import "github.com/daglabs/btcd/util/panics" -import "github.com/daglabs/btcd/apiserver/logger" +import "github.com/daglabs/btcd/kasparov/logger" var ( log = logger.Logger("REST") diff --git a/apiserver/server/routes.go b/kasparov/server/server/routes.go similarity index 98% rename from apiserver/server/routes.go rename to kasparov/server/server/routes.go index 8d0f79fba..f6bbe5ca2 100644 --- a/apiserver/server/routes.go +++ b/kasparov/server/server/routes.go @@ -7,7 +7,7 @@ import ( "net/http" "strconv" - "github.com/daglabs/btcd/apiserver/controllers" + "github.com/daglabs/btcd/kasparov/server/controllers" "github.com/gorilla/mux" ) @@ -34,7 +34,7 @@ func mainHandler(_ *httpserverutils.ServerContext, _ *http.Request, _ map[string return struct { Message string `json:"message"` }{ - Message: "API server is running", + Message: "Kasparov server is running", }, nil } diff --git a/apiserver/server/server.go b/kasparov/server/server/server.go similarity index 100% rename from apiserver/server/server.go rename to kasparov/server/server/server.go diff --git a/kasparov/syncd/config/config.go b/kasparov/syncd/config/config.go new file mode 100644 index 000000000..7704922f7 --- /dev/null +++ b/kasparov/syncd/config/config.go @@ -0,0 +1,55 @@ +package config + +import ( + "github.com/daglabs/btcd/kasparov/config" + "github.com/daglabs/btcd/util" + "github.com/jessevdk/go-flags" + "github.com/pkg/errors" +) + +const ( + logFilename = "syncd.log" + errLogFilename = "syncd_err.log" +) + +var ( + // Default configuration options + defaultLogDir = util.AppDataDir("syncd", false) + activeConfig *Config +) + +// ActiveConfig returns the active configuration struct +func ActiveConfig() *Config { + return activeConfig +} + +// Config defines the configuration options for the sync daemon. +type Config struct { + Migrate bool `long:"migrate" description:"Migrate the database to the latest version. The daemon will not start when using this flag."` + MQTTBrokerAddress string `long:"mqttaddress" description:"MQTT broker address" required:"false"` + MQTTUser string `long:"mqttuser" description:"MQTT server user" required:"false"` + MQTTPassword string `long:"mqttpass" description:"MQTT server password" required:"false"` + config.KasparovFlags +} + +// Parse parses the CLI arguments and returns a config struct. +func Parse() error { + activeConfig = &Config{} + parser := flags.NewParser(activeConfig, flags.PrintErrors|flags.HelpFlag) + _, err := parser.Parse() + if err != nil { + return err + } + + err = activeConfig.ResolveKasparovFlags(parser, defaultLogDir, logFilename, errLogFilename) + if err != nil { + return err + } + + if (activeConfig.MQTTBrokerAddress != "" || activeConfig.MQTTUser != "" || activeConfig.MQTTPassword != "") && + (activeConfig.MQTTBrokerAddress == "" || activeConfig.MQTTUser == "" || activeConfig.MQTTPassword == "") { + return errors.New("--mqttaddress, --mqttuser, and --mqttpass must be passed all together") + } + + return nil +} diff --git a/apiserver/docker/Dockerfile b/kasparov/syncd/docker/Dockerfile similarity index 67% rename from apiserver/docker/Dockerfile rename to kasparov/syncd/docker/Dockerfile index 571da3f5e..87302cf7d 100644 --- a/apiserver/docker/Dockerfile +++ b/kasparov/syncd/docker/Dockerfile @@ -14,7 +14,7 @@ RUN go mod download COPY . . -RUN cd apiserver && CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o apiserver . +RUN cd kasparov/syncd && CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o kasparov-syncd . # --- multistage docker build: stage #2: runtime image FROM alpine @@ -22,7 +22,7 @@ WORKDIR /app RUN apk add --no-cache tini -COPY --from=build /go/src/github.com/daglabs/btcd/apiserver/ /app/ +COPY --from=build /go/src/github.com/daglabs/btcd/kasparov/syncd/ /app/ ENTRYPOINT ["/sbin/tini", "--"] -CMD ["/app/apiserver"] +CMD ["/app/kasparov-syncd"] diff --git a/kasparov/syncd/log.go b/kasparov/syncd/log.go new file mode 100644 index 000000000..e0ccec423 --- /dev/null +++ b/kasparov/syncd/log.go @@ -0,0 +1,11 @@ +package main + +import ( + "github.com/daglabs/btcd/kasparov/logger" + "github.com/daglabs/btcd/util/panics" +) + +var ( + log = logger.Logger("KVSD") + spawn = panics.GoroutineWrapperFunc(log) +) diff --git a/apiserver/main.go b/kasparov/syncd/main.go similarity index 77% rename from apiserver/main.go rename to kasparov/syncd/main.go index cbae1d7be..f9b68e3f4 100644 --- a/apiserver/main.go +++ b/kasparov/syncd/main.go @@ -2,19 +2,17 @@ package main import ( "fmt" - "github.com/daglabs/btcd/apiserver/mqtt" - "github.com/pkg/errors" - "os" - - "github.com/daglabs/btcd/apiserver/config" - "github.com/daglabs/btcd/apiserver/database" - "github.com/daglabs/btcd/apiserver/jsonrpc" - "github.com/daglabs/btcd/apiserver/server" + "github.com/daglabs/btcd/kasparov/database" + "github.com/daglabs/btcd/kasparov/jsonrpc" + "github.com/daglabs/btcd/kasparov/syncd/config" + "github.com/daglabs/btcd/kasparov/syncd/mqtt" "github.com/daglabs/btcd/signal" "github.com/daglabs/btcd/util/panics" _ "github.com/golang-migrate/migrate/v4/database/mysql" _ "github.com/golang-migrate/migrate/v4/source/file" _ "github.com/jinzhu/gorm/dialects/mysql" + "github.com/pkg/errors" + "os" ) func main() { @@ -31,14 +29,14 @@ func main() { } if config.ActiveConfig().Migrate { - err := database.Migrate() + err := database.Migrate(&config.ActiveConfig().KasparovFlags) if err != nil { panic(errors.Errorf("Error migrating database: %s", err)) } return } - err = database.Connect() + err = database.Connect(&config.ActiveConfig().KasparovFlags) if err != nil { panic(errors.Errorf("Error connecting to database: %s", err)) } @@ -55,15 +53,12 @@ func main() { } defer mqtt.Close() - err = jsonrpc.Connect() + err = jsonrpc.Connect(&config.ActiveConfig().KasparovFlags) if err != nil { panic(errors.Errorf("Error connecting to servers: %s", err)) } defer jsonrpc.Close() - shutdownServer := server.Start(config.ActiveConfig().HTTPListen) - defer shutdownServer() - doneChan := make(chan struct{}, 1) spawn(func() { err := startSync(doneChan) diff --git a/apiserver/mqtt/log.go b/kasparov/syncd/mqtt/log.go similarity index 73% rename from apiserver/mqtt/log.go rename to kasparov/syncd/mqtt/log.go index ee4e2210b..520d903ad 100644 --- a/apiserver/mqtt/log.go +++ b/kasparov/syncd/mqtt/log.go @@ -1,7 +1,7 @@ package mqtt import "github.com/daglabs/btcd/util/panics" -import "github.com/daglabs/btcd/apiserver/logger" +import "github.com/daglabs/btcd/kasparov/logger" var ( log = logger.Logger("MQTT") diff --git a/apiserver/mqtt/mqtt.go b/kasparov/syncd/mqtt/mqtt.go similarity index 97% rename from apiserver/mqtt/mqtt.go rename to kasparov/syncd/mqtt/mqtt.go index d69e43f64..43026c6eb 100644 --- a/apiserver/mqtt/mqtt.go +++ b/kasparov/syncd/mqtt/mqtt.go @@ -2,7 +2,7 @@ package mqtt import ( "encoding/json" - "github.com/daglabs/btcd/apiserver/config" + "github.com/daglabs/btcd/kasparov/syncd/config" mqtt "github.com/eclipse/paho.mqtt.golang" "github.com/pkg/errors" ) diff --git a/apiserver/mqtt/selected_tip.go b/kasparov/syncd/mqtt/selected_tip.go similarity index 87% rename from apiserver/mqtt/selected_tip.go rename to kasparov/syncd/mqtt/selected_tip.go index 9b7c8a24e..1e58442eb 100644 --- a/apiserver/mqtt/selected_tip.go +++ b/kasparov/syncd/mqtt/selected_tip.go @@ -1,7 +1,7 @@ package mqtt import ( - "github.com/daglabs/btcd/apiserver/controllers" + "github.com/daglabs/btcd/kasparov/server/controllers" ) const selectedTipTopic = "dag/selected-tip" diff --git a/apiserver/mqtt/transactions.go b/kasparov/syncd/mqtt/transactions.go similarity index 96% rename from apiserver/mqtt/transactions.go rename to kasparov/syncd/mqtt/transactions.go index 0fdc4ab26..0aaad5e5c 100644 --- a/apiserver/mqtt/transactions.go +++ b/kasparov/syncd/mqtt/transactions.go @@ -1,9 +1,9 @@ package mqtt import ( - "github.com/daglabs/btcd/apiserver/apimodels" - "github.com/daglabs/btcd/apiserver/controllers" "github.com/daglabs/btcd/btcjson" + "github.com/daglabs/btcd/kasparov/server/apimodels" + "github.com/daglabs/btcd/kasparov/server/controllers" "github.com/daglabs/btcd/rpcclient" "github.com/daglabs/btcd/util/daghash" "path" diff --git a/apiserver/sync.go b/kasparov/syncd/sync.go similarity index 98% rename from apiserver/sync.go rename to kasparov/syncd/sync.go index 23faea559..2d468f97e 100644 --- a/apiserver/sync.go +++ b/kasparov/syncd/sync.go @@ -3,15 +3,15 @@ package main import ( "bytes" "encoding/hex" - "github.com/daglabs/btcd/apiserver/mqtt" + "github.com/daglabs/btcd/kasparov/database" + "github.com/daglabs/btcd/kasparov/dbmodels" + "github.com/daglabs/btcd/kasparov/jsonrpc" + "github.com/daglabs/btcd/kasparov/syncd/config" + "github.com/daglabs/btcd/kasparov/syncd/mqtt" "strconv" "strings" "time" - "github.com/daglabs/btcd/apiserver/config" - "github.com/daglabs/btcd/apiserver/database" - "github.com/daglabs/btcd/apiserver/dbmodels" - "github.com/daglabs/btcd/apiserver/jsonrpc" "github.com/daglabs/btcd/blockdag" "github.com/daglabs/btcd/btcjson" "github.com/daglabs/btcd/httpserverutils" @@ -27,8 +27,8 @@ import ( // pendingChainChangedMsgs holds chainChangedMsgs in order of arrival var pendingChainChangedMsgs []*jsonrpc.ChainChangedMsg -// startSync keeps the node and the API server in sync. On start, it downloads -// all data that's missing from the API server, and once it's done it keeps +// startSync keeps the node and the database in sync. On start, it downloads +// all data that's missing from the dabase, and once it's done it keeps // sync with the node via notifications. func startSync(doneChan chan struct{}) error { client, err := jsonrpc.GetClient() @@ -42,7 +42,7 @@ func startSync(doneChan chan struct{}) error { return err } - // Keep the node and the API server in sync + // Keep the node and the database in sync return sync(client, doneChan) } @@ -63,7 +63,7 @@ func fetchInitialData(client *jsonrpc.Client) error { return nil } -// sync keeps the API server in sync with the node via notifications +// sync keeps the database in sync with the node via notifications func sync(client *jsonrpc.Client, doneChan chan struct{}) error { // Handle client notifications until we're told to stop for { @@ -1068,6 +1068,7 @@ func handleChainChangedMsg(chainChanged *jsonrpc.ChainChangedMsg) error { } log.Infof("Chain changed: removed %d blocks and added %d block", len(removedHashes), len(addedBlocks)) + err = mqtt.PublishAcceptedTransactionsNotifications(chainChanged.AddedChainBlocks) if err != nil { return errors.Wrap(err, "Error while publishing accepted transactions notifications")