Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serialize network constants and logging with anchors #153

Merged
merged 4 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions pkg/config/anchors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package config

import (
"reflect"

"gopkg.in/yaml.v3"
)

// MarshalYAML marshals the NetworkOverrides value to yaml handling anchors where necessary
func (nc *NetworkOverrides) MarshalYAML() (interface{}, error) {
return anchorHelper(nc, "network_overrides")
}

// MarshalYAML marshals the LoggingConfig value to yaml handling anchors where necessary
func (lc *LoggingConfig) MarshalYAML() (interface{}, error) {
return anchorHelper(lc, "logging")
}

// Anchorable defines the methods a type must implement to support anchors
type Anchorable interface {
AnchorNode() *yaml.Node
SetAnchorNode(*yaml.Node)
}

func anchorHelper(in Anchorable, tag string) (*yaml.Node, error) {
if in.AnchorNode() != nil {
node := &yaml.Node{
Kind: yaml.AliasNode,
Alias: in.AnchorNode(),
Value: tag,
}
return node, nil
}

// Get the underlying value of 'in' for marshalling or else we end up recursively in this function
value := reflect.ValueOf(in)
if value.Kind() == reflect.Ptr {
// Dereference if it's a pointer
value = value.Elem()
}

// Marshal the struct to a yaml.Node
var node yaml.Node
if err := node.Encode(value.Interface()); err != nil {
return nil, err
}
node.Anchor = tag

// Store the node as the anchor for future iterations
in.SetAnchorNode(&node)

// Return the node to be marshalled
return &node, nil
}
80 changes: 80 additions & 0 deletions pkg/config/anchors_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package config_test

import (
"testing"

"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"

"github.com/chia-network/go-chia-libs/pkg/config"
)

// TestLoggingConfigAnchors verifies that logging is serialized with anchors
func TestLoggingConfigAnchors(t *testing.T) {
type testStruct struct {
LoggingConfig1 *config.LoggingConfig `yaml:"logging1"`
LoggingConfig2 *config.LoggingConfig `yaml:"logging2"`
}
loggingCfg := config.LoggingConfig{}
testInstance := &testStruct{
LoggingConfig1: &loggingCfg,
LoggingConfig2: &loggingCfg,
}

expected := `logging1: &logging
log_stdout: false
log_filename: ""
log_level: ""
log_maxfilesrotation: 0
log_maxbytesrotation: 0
log_use_gzip: false
log_syslog: false
log_syslog_host: ""
log_syslog_port: 0
logging2: *logging
`

out, err := yaml.Marshal(testInstance)
assert.NoError(t, err)
assert.Equal(t, expected, string(out))
}

// TestNetworkOverridesAnchors verifies that logging is serialized with anchors
func TestNetworkOverridesAnchors(t *testing.T) {
type testStruct struct {
Network1 *config.NetworkOverrides `yaml:"network_overrides1"`
Network2 *config.NetworkOverrides `yaml:"network_overrides2"`
}
no := config.NetworkOverrides{
Constants: map[string]config.NetworkConstants{
"mainnet": {},
},
Config: map[string]config.NetworkConfig{
"mainnet": {
AddressPrefix: "xch",
DefaultFullNodePort: 8444,
},
},
}
testInstance := &testStruct{
Network1: &no,
Network2: &no,
}

expected := `network_overrides1: &network_overrides
constants:
mainnet:
GENESIS_CHALLENGE: ""
GENESIS_PRE_FARM_POOL_PUZZLE_HASH: ""
GENESIS_PRE_FARM_FARMER_PUZZLE_HASH: ""
config:
mainnet:
address_prefix: xch
default_full_node_port: 8444
network_overrides2: *network_overrides
`

out, err := yaml.Marshal(testInstance)
assert.NoError(t, err)
assert.Equal(t, expected, string(out))
}
102 changes: 63 additions & 39 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package config

import (
"gopkg.in/yaml.v3"

"github.com/chia-network/go-chia-libs/pkg/types"
)

Expand All @@ -25,7 +27,7 @@ type ChiaConfig struct {
PrivateSSLCA CAConfig `yaml:"private_ssl_ca"`
ChiaSSLCA CAConfig `yaml:"chia_ssl_ca"`
DaemonSSL SSLConfig `yaml:"daemon_ssl"`
Logging LoggingConfig `yaml:"logging"` // @TODO this would usually be an anchor
Logging *LoggingConfig `yaml:"logging"`
Seeder SeederConfig `yaml:"seeder"`
Harvester HarvesterConfig `yaml:"harvester"`
Pool PoolConfig `yaml:"pool"`
Expand Down Expand Up @@ -69,8 +71,19 @@ type Peer struct {

// NetworkOverrides is all network settings
type NetworkOverrides struct {
Constants map[string]NetworkConstants `yaml:"constants"`
Config map[string]NetworkConfig `yaml:"config"`
yamlAnchor *yaml.Node `yaml:"-"` // Helps with serializing the anchors to yaml
Constants map[string]NetworkConstants `yaml:"constants"`
Config map[string]NetworkConfig `yaml:"config"`
}

// AnchorNode returns the node to be used in yaml anchors
func (nc *NetworkOverrides) AnchorNode() *yaml.Node {
return nc.yamlAnchor
}

// SetAnchorNode sets the yaml.Node reference when marshaling
func (nc *NetworkOverrides) SetAnchorNode(node *yaml.Node) {
nc.yamlAnchor = node
}

// NetworkConstants the constants for each network
Expand Down Expand Up @@ -102,15 +115,26 @@ type NetworkConfig struct {

// LoggingConfig configuration settings for the logger
type LoggingConfig struct {
LogStdout bool `yaml:"log_stdout"`
LogFilename string `yaml:"log_filename"`
LogLevel string `yaml:"log_level"`
LogMaxFilesRotation uint8 `yaml:"log_maxfilesrotation"`
LogMaxBytesRotation uint32 `yaml:"log_maxbytesrotation"`
LogUseGzip bool `yaml:"log_use_gzip"`
LogSyslog bool `yaml:"log_syslog"`
LogSyslogHost string `yaml:"log_syslog_host"`
LogSyslogPort uint16 `yaml:"log_syslog_port"`
yamlAnchor *yaml.Node `yaml:"-"` // Helps with serializing the anchors to yaml
LogStdout bool `yaml:"log_stdout"`
LogFilename string `yaml:"log_filename"`
LogLevel string `yaml:"log_level"`
LogMaxFilesRotation uint8 `yaml:"log_maxfilesrotation"`
LogMaxBytesRotation uint32 `yaml:"log_maxbytesrotation"`
LogUseGzip bool `yaml:"log_use_gzip"`
LogSyslog bool `yaml:"log_syslog"`
LogSyslogHost string `yaml:"log_syslog_host"`
LogSyslogPort uint16 `yaml:"log_syslog_port"`
}

// AnchorNode returns the node to be used in yaml anchors
func (lc *LoggingConfig) AnchorNode() *yaml.Node {
return lc.yamlAnchor
}

// SetAnchorNode sets the yaml.Node reference when marshaling
func (lc *LoggingConfig) SetAnchorNode(node *yaml.Node) {
lc.yamlAnchor = node
}

// SeederConfig seeder configuration section
Expand All @@ -129,7 +153,7 @@ type SeederConfig struct {
SOA SeederSOA `yaml:"soa"`
NetworkOverrides *NetworkOverrides `yaml:"network_overrides"`
SelectedNetwork *string `yaml:"selected_network"`
Logging LoggingConfig `yaml:"logging"`
Logging *LoggingConfig `yaml:"logging"`
CrawlerConfig CrawlerConfig `yaml:"crawler"`
}

Expand Down Expand Up @@ -157,7 +181,7 @@ type HarvesterConfig struct {
NumThreads uint8 `yaml:"num_threads"`
PlotsRefreshParameter PlotsRefreshParameter `yaml:"plots_refresh_parameter"`
ParallelRead bool `yaml:"parallel_read"`
Logging LoggingConfig `yaml:"logging"`
Logging *LoggingConfig `yaml:"logging"`
NetworkOverrides *NetworkOverrides `yaml:"network_overrides"`
SelectedNetwork *string `yaml:"selected_network"`
PlotDirectories []string `yaml:"plot_directories"`
Expand Down Expand Up @@ -187,7 +211,7 @@ type PlotsRefreshParameter struct {
// PoolConfig configures pool settings
type PoolConfig struct {
XCHTargetAddress string `yaml:"xch_target_address,omitempty"`
Logging LoggingConfig `yaml:"logging"`
Logging *LoggingConfig `yaml:"logging"`
NetworkOverrides *NetworkOverrides `yaml:"network_overrides"`
SelectedNetwork *string `yaml:"selected_network"`
}
Expand All @@ -200,7 +224,7 @@ type FarmerConfig struct {
StartRPCServer bool `yaml:"start_rpc_server"`
EnableProfiler bool `yaml:"enable_profiler"`
PoolShareThreshold uint32 `yaml:"pool_share_threshold"`
Logging LoggingConfig `yaml:"logging"`
Logging *LoggingConfig `yaml:"logging"`
NetworkOverrides *NetworkOverrides `yaml:"network_overrides"`
SelectedNetwork *string `yaml:"selected_network"`
PortConfig `yaml:",inline"`
Expand All @@ -209,10 +233,10 @@ type FarmerConfig struct {

// TimelordLauncherConfig settings for vdf_client launcher
type TimelordLauncherConfig struct {
Host string `yaml:"host"`
Port uint16 `yaml:"port"`
ProcessCount uint8 `yaml:"process_count"`
Logging LoggingConfig `yaml:"logging"`
Host string `yaml:"host"`
Port uint16 `yaml:"port"`
ProcessCount uint8 `yaml:"process_count"`
Logging *LoggingConfig `yaml:"logging"`
}

// TimelordConfig timelord configuration section
Expand All @@ -221,7 +245,7 @@ type TimelordConfig struct {
FullNodePeers []Peer `yaml:"full_node_peers"`
MaxConnectionTime uint16 `yaml:"max_connection_time"`
VDFServer Peer `yaml:"vdf_server"`
Logging LoggingConfig `yaml:"logging"`
Logging *LoggingConfig `yaml:"logging"`
NetworkOverrides *NetworkOverrides `yaml:"network_overrides"`
SelectedNetwork *string `yaml:"selected_network"`
FastAlgorithm bool `yaml:"fast_algorithm"`
Expand Down Expand Up @@ -282,7 +306,7 @@ type FullNodeConfig struct {
TrustedMaxSubscribeResponseItems uint32 `yaml:"trusted_max_subscribe_response_items"`
DNSServers []string `yaml:"dns_servers"`
IntroducerPeer Peer `yaml:"introducer_peer"`
Logging LoggingConfig `yaml:"logging"`
Logging *LoggingConfig `yaml:"logging"`
NetworkOverrides *NetworkOverrides `yaml:"network_overrides"`
SelectedNetwork *string `yaml:"selected_network"`
TrustedPeers map[string]string `yaml:"trusted_peers"`
Expand All @@ -294,7 +318,7 @@ type FullNodeConfig struct {
type UIConfig struct {
PortConfig `yaml:",inline"`
SSHFilename string `yaml:"ssh_filename"`
Logging LoggingConfig `yaml:"logging"`
Logging *LoggingConfig `yaml:"logging"`
NetworkOverrides *NetworkOverrides `yaml:"network_overrides"`
SelectedNetwork *string `yaml:"selected_network"`
DaemonHost string `yaml:"daemon_host"`
Expand All @@ -308,7 +332,7 @@ type IntroducerConfig struct {
PortConfig `yaml:",inline"`
MaxPeersToSend uint16 `yaml:"max_peers_to_send"`
RecentPeerThreshold uint16 `yaml:"recent_peer_threshold"`
Logging LoggingConfig `yaml:"logging"`
Logging *LoggingConfig `yaml:"logging"`
NetworkOverrides *NetworkOverrides `yaml:"network_overrides"`
SelectedNetwork *string `yaml:"selected_network"`
SSL SSLConfig `yaml:"ssl"`
Expand All @@ -334,7 +358,7 @@ type WalletConfig struct {
WalletPeersPath string `yaml:"wallet_peers_path"`
WalletPeersFilePath string `yaml:"wallet_peers_file_path"`
LogSqliteCmds bool `yaml:"log_sqlite_cmds"`
Logging LoggingConfig `yaml:"logging"`
Logging *LoggingConfig `yaml:"logging"`
NetworkOverrides *NetworkOverrides `yaml:"network_overrides"`
SelectedNetwork *string `yaml:"selected_network"`
TargetPeerCount uint16 `yaml:"target_peer_count"`
Expand Down Expand Up @@ -370,20 +394,20 @@ type AutoClaim struct {

// DataLayerConfig datalayer configuration section
type DataLayerConfig struct {
WalletPeer Peer `yaml:"wallet_peer"`
DatabasePath string `yaml:"database_path"`
ServerFilesLocation string `yaml:"server_files_location"`
ClientTimeout uint16 `yaml:"client_timeout"`
ProxyURL string `yaml:"proxy_url,omitempty"`
HostIP string `yaml:"host_ip"`
HostPort uint16 `yaml:"host_port"`
ManageDataInterval uint16 `yaml:"manage_data_interval"`
SelectedNetwork *string `yaml:"selected_network"`
StartRPCServer bool `yaml:"start_rpc_server"`
RPCServerMaxRequestBodySize uint32 `yaml:"rpc_server_max_request_body_size"`
LogSqliteCmds bool `yaml:"log_sqlite_cmds"`
EnableBatchAutoinsert bool `yaml:"enable_batch_autoinsert"`
Logging LoggingConfig `yaml:"logging"`
WalletPeer Peer `yaml:"wallet_peer"`
DatabasePath string `yaml:"database_path"`
ServerFilesLocation string `yaml:"server_files_location"`
ClientTimeout uint16 `yaml:"client_timeout"`
ProxyURL string `yaml:"proxy_url,omitempty"`
HostIP string `yaml:"host_ip"`
HostPort uint16 `yaml:"host_port"`
ManageDataInterval uint16 `yaml:"manage_data_interval"`
SelectedNetwork *string `yaml:"selected_network"`
StartRPCServer bool `yaml:"start_rpc_server"`
RPCServerMaxRequestBodySize uint32 `yaml:"rpc_server_max_request_body_size"`
LogSqliteCmds bool `yaml:"log_sqlite_cmds"`
EnableBatchAutoinsert bool `yaml:"enable_batch_autoinsert"`
Logging *LoggingConfig `yaml:"logging"`
PortConfig `yaml:",inline"`
SSL SSLConfig `yaml:"ssl"`
Plugins DataLayerPlugins `yaml:"plugins"`
Expand Down
15 changes: 15 additions & 0 deletions pkg/config/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,19 @@ func (c *ChiaConfig) dealWithAnchors() {
c.Introducer.SelectedNetwork = c.SelectedNetwork
c.Wallet.SelectedNetwork = c.SelectedNetwork
c.DataLayer.SelectedNetwork = c.SelectedNetwork

if c.Logging == nil {
c.Logging = &LoggingConfig{}
}
c.Seeder.Logging = c.Logging
c.Harvester.Logging = c.Logging
c.Pool.Logging = c.Logging
c.Farmer.Logging = c.Logging
c.TimelordLauncher.Logging = c.Logging
c.Timelord.Logging = c.Logging
c.FullNode.Logging = c.Logging
c.UI.Logging = c.Logging
c.Introducer.Logging = c.Logging
c.Wallet.Logging = c.Logging
c.DataLayer.Logging = c.Logging
}