Skip to content

Commit

Permalink
chore(cleanup): Finish removing the AppConfig singleton and move Opti…
Browse files Browse the repository at this point in the history
…ons processing to the config package (#630)

* Remove the AppConfig singleton

* Move Options handling to the config package

* Add NodeOptions test
  • Loading branch information
mcamou authored Nov 15, 2024
1 parent 5d12c5e commit cc24d57
Show file tree
Hide file tree
Showing 17 changed files with 239 additions and 98 deletions.
26 changes: 12 additions & 14 deletions cmd/masa-node/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"github.com/masa-finance/masa-oracle/pkg/api"
"github.com/masa-finance/masa-oracle/pkg/config"
"github.com/masa-finance/masa-oracle/pkg/db"
"github.com/masa-finance/masa-oracle/pkg/masacrypto"
"github.com/masa-finance/masa-oracle/pkg/staking"
)

Expand All @@ -30,20 +29,19 @@ func main() {
os.Exit(0)
}

cfg := config.GetInstance()
cfg.LogConfig()
cfg.SetupLogging()

keyManager, err := masacrypto.NewKeyManager(cfg.PrivateKey, cfg.PrivateKeyFile)
cfg, err := config.GetConfig()
if err != nil {
logrus.Fatal("[-] Failed to initialize keys:", err)
logrus.Fatalf("[-] %v", err)
}

cfg.SetupLogging()
cfg.LogConfig()

// Create a cancellable context
ctx, cancel := context.WithCancel(context.Background())

if cfg.Faucet {
err := handleFaucet(cfg.RpcUrl, keyManager.EcdsaPrivKey)
err := handleFaucet(cfg.RpcUrl, cfg.KeyManager.EcdsaPrivKey)
if err != nil {
logrus.Errorf("[-] %v", err)
os.Exit(1)
Expand All @@ -54,7 +52,7 @@ func main() {
}

if cfg.StakeAmount != "" {
err := handleStaking(cfg.RpcUrl, keyManager.EcdsaPrivKey, cfg.StakeAmount)
err := handleStaking(cfg.RpcUrl, cfg.KeyManager.EcdsaPrivKey, cfg.StakeAmount)
if err != nil {
logrus.Warningf("%v", err)
} else {
Expand All @@ -64,7 +62,7 @@ func main() {
}

// Verify the staking event
isStaked, err := staking.VerifyStakingEvent(cfg.RpcUrl, keyManager.EthAddress)
isStaked, err := staking.VerifyStakingEvent(cfg.RpcUrl, cfg.KeyManager.EthAddress)
if err != nil {
logrus.Error(err)
}
Expand All @@ -73,7 +71,7 @@ func main() {
logrus.Warn("No staking event found for this address")
}

masaNodeOptions, workHandlerManager, pubKeySub := initOptions(cfg, keyManager)
masaNodeOptions, workHandlerManager, pubKeySub := config.InitOptions(cfg)
// Create a new OracleNode
masaNode, err := node.NewOracleNode(ctx, masaNodeOptions...)

Expand All @@ -91,14 +89,14 @@ func main() {

if cfg.AllowedPeer {
cfg.AllowedPeerId = masaNode.Host.ID().String()
cfg.AllowedPeerPublicKey = keyManager.HexPubKey
cfg.AllowedPeerPublicKey = cfg.KeyManager.HexPubKey
logrus.Infof("[+] Allowed peer with ID: %s and PubKey: %s", cfg.AllowedPeerId, cfg.AllowedPeerPublicKey)
} else {
logrus.Warn("[-] This node is not set as the allowed peer")
}

// Init cache resolver
db.InitResolverCache(masaNode, keyManager, cfg.AllowedPeerId, cfg.AllowedPeerPublicKey, cfg.Validator)
db.InitResolverCache(masaNode, cfg.KeyManager, cfg.AllowedPeerId, cfg.AllowedPeerPublicKey, cfg.Validator)

// Cancel the context when SIGINT is received
go handleSignals(cancel, masaNode, cfg)
Expand All @@ -122,7 +120,7 @@ func main() {
logrus.Errorf("[-] Error while getting node IP address from %v: %v", multiAddr, err)
}
// Display the welcome message with the multiaddress and IP address
config.DisplayWelcomeMessage(multiAddr.String(), ipAddr, keyManager.EthAddress, isStaked, cfg.Validator, cfg.TwitterScraper, cfg.TelegramScraper, cfg.DiscordScraper, cfg.WebScraper, versioning.ApplicationVersion, versioning.ProtocolVersion)
config.DisplayWelcomeMessage(multiAddr.String(), ipAddr, cfg.KeyManager.EthAddress, isStaked, cfg.Validator, cfg.TwitterScraper, cfg.TelegramScraper, cfg.DiscordScraper, cfg.WebScraper, versioning.ApplicationVersion, versioning.ProtocolVersion)

<-ctx.Done()
}
Expand Down
46 changes: 45 additions & 1 deletion node/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,15 @@ type NodeOption struct {
Version string
MasaDir string
CachePath string
KeyManager *masacrypto.KeyManager

OracleProtocol string
NodeDataSyncProtocol string
NodeGossipTopic string
Rendezvous string
WorkerProtocol string
PageSize int

KeyManager *masacrypto.KeyManager
}

type PubSubHandlers struct {
Expand Down Expand Up @@ -167,3 +175,39 @@ func WithKeyManager(km *masacrypto.KeyManager) Option {
o.KeyManager = km
}
}

func WithOracleProtocol(s string) Option {
return func(o *NodeOption) {
o.OracleProtocol = s
}
}

func WithNodeDataSyncProtocol(s string) Option {
return func(o *NodeOption) {
o.NodeDataSyncProtocol = s
}
}

func WithNodeGossipTopic(s string) Option {
return func(o *NodeOption) {
o.NodeGossipTopic = s
}
}

func WithRendezvous(s string) Option {
return func(o *NodeOption) {
o.Rendezvous = s
}
}

func WithWorkerProtocol(s string) Option {
return func(o *NodeOption) {
o.WorkerProtocol = s
}
}

func WithPageSize(size int) Option {
return func(o *NodeOption) {
o.PageSize = size
}
}
10 changes: 4 additions & 6 deletions node/oracle_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (

"github.com/masa-finance/masa-oracle/internal/versioning"
"github.com/masa-finance/masa-oracle/pkg/chain"
"github.com/masa-finance/masa-oracle/pkg/config"
myNetwork "github.com/masa-finance/masa-oracle/pkg/network"
"github.com/masa-finance/masa-oracle/pkg/pubsub"
)
Expand All @@ -47,7 +46,6 @@ type OracleNode struct {
Blockchain *chain.Chain
Options NodeOption
Context context.Context
Config *config.AppConfig
}

// GetMultiAddrs returns the priority multiaddr for this node.
Expand Down Expand Up @@ -150,7 +148,7 @@ func NewOracleNode(ctx context.Context, opts ...Option) (*OracleNode, error) {
Options: *o,
}

n.Protocol = n.protocolWithVersion(config.OracleProtocol)
n.Protocol = n.protocolWithVersion(n.Options.OracleProtocol)
return n, nil
}

Expand Down Expand Up @@ -204,7 +202,7 @@ func (node *OracleNode) Start() (err error) {
logrus.Infof("[+] Starting node with ID: %s", node.GetMultiAddrs().String())

node.Host.SetStreamHandler(node.Protocol, node.handleStream)
node.Host.SetStreamHandler(node.protocolWithVersion(config.NodeDataSyncProtocol), node.ReceiveNodeData)
node.Host.SetStreamHandler(node.protocolWithVersion(node.Options.NodeDataSyncProtocol), node.ReceiveNodeData)

for pid, n := range node.Options.ProtocolHandlers {
node.Host.SetStreamHandler(pid, n)
Expand All @@ -215,7 +213,7 @@ func (node *OracleNode) Start() (err error) {
}

if node.Options.IsStaked {
node.Host.SetStreamHandler(node.protocolWithVersion(config.NodeGossipTopic), node.GossipNodeData)
node.Host.SetStreamHandler(node.protocolWithVersion(node.Options.NodeGossipTopic), node.GossipNodeData)
}

node.Host.Network().Notify(node.NodeTracker)
Expand All @@ -236,7 +234,7 @@ func (node *OracleNode) Start() (err error) {
return err
}

err = myNetwork.EnableMDNS(node.Host, config.Rendezvous, node.PeerChan)
err = myNetwork.EnableMDNS(node.Host, node.Options.Rendezvous, node.PeerChan)
if err != nil {
return err
}
Expand Down
13 changes: 6 additions & 7 deletions node/oracle_node_listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/libp2p/go-libp2p/core/peer"
"github.com/sirupsen/logrus"

"github.com/masa-finance/masa-oracle/pkg/config"
pubsub2 "github.com/masa-finance/masa-oracle/pkg/pubsub"
)

Expand Down Expand Up @@ -42,7 +41,7 @@ func (node *OracleNode) ListenToNodeTracker() {
continue
}
// Publish the JSON data on the node.topic
err = node.PublishTopic(config.NodeGossipTopic, jsonData)
err = node.PublishTopic(node.Options.NodeGossipTopic, jsonData)
if err != nil {
logrus.Errorf("[-] Error publishing node data: %v", err)
}
Expand Down Expand Up @@ -88,10 +87,10 @@ type NodeDataPage struct {
func (node *OracleNode) SendNodeDataPage(allNodeData []pubsub2.NodeData, stream network.Stream, pageNumber int) {
logrus.Debugf("[+] SendNodeDataPage --> %s: Page: %d", stream.Conn().RemotePeer(), pageNumber)
totalRecords := len(allNodeData)
totalPages := int(math.Ceil(float64(totalRecords) / config.PageSize))
totalPages := int(math.Ceil(float64(totalRecords) / float64(node.Options.PageSize)))

startIndex := pageNumber * config.PageSize
endIndex := startIndex + config.PageSize
startIndex := pageNumber * node.Options.PageSize
endIndex := startIndex + node.Options.PageSize
if endIndex > totalRecords {
endIndex = totalRecords
}
Expand Down Expand Up @@ -133,9 +132,9 @@ func (node *OracleNode) SendNodeData(peerID peer.ID) {
nodeData = node.NodeTracker.GetUpdatedNodes(sinceTime)
}
totalRecords := len(nodeData)
totalPages := int(math.Ceil(float64(totalRecords) / float64(config.PageSize)))
totalPages := int(math.Ceil(float64(totalRecords) / float64(node.Options.PageSize)))

stream, err := node.Host.NewStream(node.Context, peerID, node.protocolWithVersion(config.NodeDataSyncProtocol))
stream, err := node.Host.NewStream(node.Context, peerID, node.protocolWithVersion(node.Options.NodeDataSyncProtocol))
if err != nil {
// node.NodeTracker.RemoveNodeData(peerID.String())
return
Expand Down
3 changes: 1 addition & 2 deletions node/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/core/protocol"
"github.com/masa-finance/masa-oracle/pkg/config"
)

const (
Expand Down Expand Up @@ -50,7 +49,7 @@ func (node *OracleNode) subscribeToTopics() error {
}

// Subscribe to NodeGossipTopic to participate in the network's gossip protocol.
if err := node.SubscribeTopic(config.NodeGossipTopic, node.NodeTracker, false); err != nil {
if err := node.SubscribeTopic(node.Options.NodeGossipTopic, node.NodeTracker, false); err != nil {
return err
}

Expand Down
65 changes: 30 additions & 35 deletions pkg/config/app.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package config

import (
"fmt"
"log"
"os/user"
"path/filepath"
"reflect"
"strings"
"sync"

"github.com/masa-finance/masa-oracle/internal/versioning"
"github.com/masa-finance/masa-oracle/pkg/masacrypto"

"github.com/gotd/contrib/bg"
"github.com/joho/godotenv"
Expand All @@ -17,11 +18,6 @@ import (
"github.com/spf13/viper"
)

var (
instance *AppConfig
once sync.Once
)

// AppConfig represents the configuration settings for the application.
// It holds various parameters and settings that control the behavior and runtime environment of the application.
// The fields in this struct are tagged with `mapstructure` to facilitate configuration loading from various sources
Expand Down Expand Up @@ -63,44 +59,43 @@ type AppConfig struct {
WebScraper bool `mapstructure:"webScraper"`
APIEnabled bool `mapstructure:"api_enabled"`

KeyManager *masacrypto.KeyManager
TelegramStop bg.StopFunc
}

// GetInstance returns the singleton instance of AppConfig.
//
// If the instance has not been initialized yet, GetInstance will initialize it by:
// 1. Creating a new AppConfig instance.
// 2. Setting default configuration values.
// 3. Overriding defaults with values from environment variables.
// 4. Overriding defaults and environment variables with values from the configuration file.
// 5. Overriding all previous values with command-line flags.
// 6. Unmarshalling the configuration into the AppConfig instance.
// GetConfig parses and fills in the AppConfig. The configuration values are generated
// by the following steps in order:
//
// If the unmarshalling fails, the instance is set to nil.
// 1. Set default configuration values.
// 2. Override with values from environment variables.
// 3. Override with values from the configuration file.
// 4. Override with command-line flags.
//
// Subsequent calls to GetInstance will return the same initialized instance.
func GetInstance() *AppConfig {
once.Do(func() {
instance = &AppConfig{}

instance.setDefaultConfig()
// TODO Shouldn't the env vars override the file config, instead of the other way around?
instance.setEnvVariableConfig()
// In case of any errors it returns nill with an error object
func GetConfig() (*AppConfig, error) {
instance := &AppConfig{}
instance.setDefaultConfig()
// TODO Shouldn't the env vars override the file config, instead of the other way around?
instance.setEnvVariableConfig()
instance.setFileConfig(viper.GetString("FILE_PATH"))

if err := instance.setCommandLineConfig(); err != nil {
return nil, err
}

instance.setFileConfig(viper.GetString("FILE_PATH"))
if err := viper.Unmarshal(instance); err != nil {
return nil, fmt.Errorf("Unable to unmarshal config into struct, %v", err)
}

if err := instance.setCommandLineConfig(); err != nil {
logrus.Fatal(err)
}
instance.APIEnabled = viper.GetBool("api_enabled")

if err := viper.Unmarshal(instance); err != nil {
logrus.Errorf("[-] Unable to unmarshal config into struct, %v", err)
instance = nil
}
keyManager, err := masacrypto.NewKeyManager(instance.PrivateKey, instance.PrivateKeyFile)
if err != nil {
return nil, fmt.Errorf("Failed to initialize keys: %v", err)
}
instance.KeyManager = keyManager

instance.APIEnabled = viper.GetBool("api_enabled")
})
return instance
return instance, nil
}

// setDefaultConfig sets the default configuration values for the AppConfig instance.
Expand Down
13 changes: 13 additions & 0 deletions pkg/config/config_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package config_test

import (
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestConfig(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Config Suite")
}
Loading

0 comments on commit cc24d57

Please sign in to comment.