diff --git a/.gitignore b/.gitignore index 3fbf3ff..3c503b3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ *.exe log.txt *debug_bin -*.yaml diff --git a/Config Default.yaml b/Config Default.yaml new file mode 100644 index 0000000..5c02a93 --- /dev/null +++ b/Config Default.yaml @@ -0,0 +1,2 @@ +LogFile: Log.txt +SeedList: [] diff --git a/Settings.go b/Config.go similarity index 54% rename from Settings.go rename to Config.go index 372fc05..925a0b1 100644 --- a/Settings.go +++ b/Config.go @@ -7,11 +7,10 @@ Author: Peter Kleissner package core import ( - "fmt" + _ "embed" // Required for embedding default Config file "io/ioutil" "log" "os" - "strings" "gopkg.in/yaml.v3" ) @@ -19,8 +18,6 @@ import ( // Version is the current core library version const Version = "0.1" -const configFile = "Settings.yaml" - var config struct { LogFile string `yaml:"LogFile"` // Log file @@ -40,34 +37,35 @@ type peerSeed struct { Address []string `yaml:"Address"` // IP:Port } -// loadConfig reads the YAML configuration file -func loadConfig() { - cfg, err := ioutil.ReadFile(configFile) - if err != nil && strings.Contains(err.Error(), "system cannot find the file specified") { - // Does not exist. Use default values. - config.LogFile = "Log.txt" +var configFile string +//go:embed "Config Default.yaml" +var defaultConfig []byte + +// LoadConfig reads the YAML configuration file +// If an error is returned, the application shall exit. +// Status: 0 = Unknown error checking config file, 1 = Error reading config file, 2 = Error parsing config file, 3 = Success +func LoadConfig(filename string) (status int, err error) { + var configData []byte + configFile = filename + + // check if the file is non existent or empty + stats, err := os.Stat(filename) + if err != nil && os.IsNotExist(err) || err == nil && stats.Size() == 0 { + configData = defaultConfig } else if err != nil { - fmt.Printf("Configuration file '%s' could not be read. Error: %s\n", configFile, err.Error()) - os.Exit(1) - } else { - // read existing config - err = yaml.Unmarshal(cfg, &config) - if err != nil { - fmt.Printf("Configuration file '%s' could not be read. Please make sure it contains valid YAML data. Error: %v\n", configFile, err.Error()) - os.Exit(1) - } + return 0, err + } else if configData, err = ioutil.ReadFile(filename); err != nil { + return 1, err } - // redirect all output to the log file - logFile, err := os.OpenFile(config.LogFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + // parse the config + err = yaml.Unmarshal(configData, &config) if err != nil { - fmt.Printf("Error creating log file '%s': %v\n", config.LogFile, err) + return 2, err } - // defer logFile.Close() // has to remain open until program closes - log.SetOutput(logFile) - log.Printf("---- Peernet Command-Line Client " + Version + " ----\n") + return 3, nil } func saveConfig() { @@ -83,3 +81,17 @@ func saveConfig() { return } } + +// InitLog redirects subsequent log messages into the default log file specified in the configuration +func InitLog() (err error) { + logFile, err := os.OpenFile(config.LogFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + if err != nil { + return err + } + //defer logFile.Close() // has to remain open until program closes + + log.SetOutput(logFile) + log.Printf("---- Peernet Command-Line Client " + Version + " ----\n") + + return nil +} diff --git a/Peernet.go b/Peernet.go index 593f550..2964417 100644 --- a/Peernet.go +++ b/Peernet.go @@ -6,8 +6,8 @@ Author: Peter Kleissner package core -func init() { - loadConfig() +// Init initializes the client. The config must be loaded first! +func Init() { initPeerID() initMulticastIPv6() initBroadcastIPv4() diff --git a/README.md b/README.md index f3046ba..e58b73e 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Current version: 0.1 (pre-alpha) ## Dependencies -Before compiling, make sure to download and update all 3rd party packages: +Go 1.16 or higher is required. Before compiling, make sure to download and update all 3rd party packages: ``` go get -u github.com/btcsuite/btcd/btcec @@ -24,12 +24,17 @@ go get -u lukechampine.com/blake3 Peernet follows a "zeroconf" approach, meaning there is no manual configuration required. However, in certain cases such as providing root peers [1] that shall listen on a fixed IP and port, it is desirable to create a config file. -The name of the config file is hard-coded to `Settings.yaml`. If it does not exist, it will be created with default values. It uses the YAML format. Any public/private keys in the config are hex encoded. Here are some notable settings: +The name of the config file is passed to the function `LoadConfig`. If it does not exist, it will be created with the values from the file `Config Default.yaml`. It uses the YAML format. Any public/private keys in the config are hex encoded. Here are some notable settings: +* `PrivateKey` The users Private Key hex encoded. The users public key is derived from it. * `ListenWorkers` defines the count of concurrent workers processing packets (decrypting them and then taking action). Default 2. * `Listen` defines IP:Port combinations to listen on. If not specified, it will listen on all IPs. You can specify an IP but port 0 for auto port selection. IPv6 addresses must be in the format "[IPv6]:Port". -[1] Root peer = A peer operated by a known trusted entity. They allow to speed up the network including discovery of peers and data. +[1] Root peer = A peer operated by a known trusted entity. They allow to speed up the network including discovery of peers and data. + +### Private Key + +The Private Key is required to make any changes to the user's blockchain, including deleting, renaming, and adding files on Peernet, or nuking the blockchain. If the private key is lost, no write access will be possible. Users should always create a secure backup of their private key. ## Contributing