Skip to content

Commit

Permalink
refactor fatal level logs
Browse files Browse the repository at this point in the history
- emit fatal level logs from the caller , update funcs to returns errs instead
  • Loading branch information
kc1116 committed Apr 2, 2024
1 parent c6a1989 commit 32df104
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 65 deletions.
41 changes: 31 additions & 10 deletions cmd/bootstrap/cmd/final_list.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"fmt"
"github.com/spf13/cobra"

"github.com/onflow/flow-go/cmd"
Expand Down Expand Up @@ -233,7 +234,11 @@ func checkMismatchingNodes(localNodes []model.NodeInfo, registeredNodes []model.
}

func assembleInternalNodesWithoutWeight() []model.NodeInfo {
privInternals := common.ReadInternalNodes(log, flagInternalNodePrivInfoDir)
privInternals, err := common.ReadInternalNodeInfos(flagInternalNodePrivInfoDir)
if err != nil {
log.Fatal().Err(err).Msg("failed to read internal node infos")
}

log.Info().Msgf("read %v internal private node-info files", len(privInternals))

var nodes []model.NodeInfo
Expand All @@ -242,9 +247,13 @@ func assembleInternalNodesWithoutWeight() []model.NodeInfo {
common.ValidateAddressFormat(log, internal.Address)

// validate every single internal node
nodeID := common.ValidateNodeID(log, internal.NodeID)
err := common.ValidateNodeID(internal.NodeID)
if err != nil {
log.Fatal().Err(err).Msg(fmt.Sprintf("invalid node ID: %s", internal.NodeID))
}

node := model.NewPrivateNodeInfo(
nodeID,
internal.NodeID,
internal.Role,
internal.Address,
flow.DefaultInitialWeight,
Expand All @@ -259,7 +268,10 @@ func assembleInternalNodesWithoutWeight() []model.NodeInfo {
}

func assemblePartnerNodesWithoutWeight() []model.NodeInfo {
partners := common.ReadPartnerNodes(log, flagPartnerNodeInfoDir)
partners, err := common.ReadPartnerNodeInfos(flagPartnerNodeInfoDir)
if err != nil {
log.Fatal().Err(err).Msg("failed to read partner node infos")
}
log.Info().Msgf("read %v partner node configuration files", len(partners))
return createPublicNodeInfo(partners)
}
Expand All @@ -279,18 +291,27 @@ func createPublicNodeInfo(nodes []model.NodeInfoPub) []model.NodeInfo {
common.ValidateAddressFormat(log, n.Address)

// validate every single partner node
nodeID := common.ValidateNodeID(log, n.NodeID)
networkPubKey := common.ValidateNetworkPubKey(log, n.NetworkPubKey)
stakingPubKey := common.ValidateStakingPubKey(log, n.StakingPubKey)
err := common.ValidateNodeID(n.NodeID)
if err != nil {
log.Fatal().Err(err).Msg(fmt.Sprintf("invalid node ID: %s", n.NodeID))
}
err = common.ValidateNetworkPubKey(n.NetworkPubKey)
if err != nil {
log.Fatal().Err(err).Msg(fmt.Sprintf("invalid network public key: %s", n.NetworkPubKey))
}
err = common.ValidateStakingPubKey(n.StakingPubKey)
if err != nil {
log.Fatal().Err(err).Msg(fmt.Sprintf("invalid staking public key: %s", n.StakingPubKey))
}

// all nodes should have equal weight
node := model.NewPublicNodeInfo(
nodeID,
n.NodeID,
n.Role,
n.Address,
flow.DefaultInitialWeight,
networkPubKey,
stakingPubKey,
n.NetworkPubKey,
n.StakingPubKey,
)

publicInfoNodes = append(publicInfoNodes, node)
Expand Down
11 changes: 9 additions & 2 deletions cmd/bootstrap/cmd/finalize.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,18 @@ func finalize(cmd *cobra.Command, args []string) {
}

log.Info().Msg("collecting partner network and staking keys")
partnerNodes := common.ReadFullPartnerNodeInfos(log, flagPartnerWeights, flagPartnerNodeInfoDir)
partnerNodes, err := common.ReadFullPartnerNodeInfos(log, flagPartnerWeights, flagPartnerNodeInfoDir)
if err != nil {
log.Fatal().Err(err).Msg("failed to read full partner node infos")
}
log.Info().Msg("")

log.Info().Msg("generating internal private networking and staking keys")
internalNodes := common.ReadInternalNodeInfos(log, flagInternalNodePrivInfoDir, flagConfig)
internalNodes, err := common.ReadFullInternalNodeInfos(log, flagInternalNodePrivInfoDir, flagConfig)
if err != nil {
log.Fatal().Err(err).Msg("failed to read full internal node infos")
}

log.Info().Msg("")

log.Info().Msg("checking constraints on consensus nodes")
Expand Down
11 changes: 9 additions & 2 deletions cmd/bootstrap/cmd/rootblock.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,18 @@ func rootBlock(cmd *cobra.Command, args []string) {
}

log.Info().Msg("collecting partner network and staking keys")
partnerNodes := common.ReadFullPartnerNodeInfos(log, flagPartnerWeights, flagPartnerNodeInfoDir)
partnerNodes, err := common.ReadFullPartnerNodeInfos(log, flagPartnerWeights, flagPartnerNodeInfoDir)
if err != nil {
log.Fatal().Err(err).Msg("failed to read full partner node infos")
}
log.Info().Msg("")

log.Info().Msg("generating internal private networking and staking keys")
internalNodes := common.ReadInternalNodeInfos(log, flagInternalNodePrivInfoDir, flagConfig)
internalNodes, err := common.ReadFullInternalNodeInfos(log, flagInternalNodePrivInfoDir, flagConfig)
if err != nil {
log.Fatal().Err(err).Msg("failed to read full internal node infos")
}

log.Info().Msg("")

log.Info().Msg("checking constraints on consensus nodes")
Expand Down
106 changes: 67 additions & 39 deletions cmd/util/cmd/common/node_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,48 +13,61 @@ import (
// ReadFullPartnerNodeInfos reads partner node info and partner weight information from the specified paths and constructs
// a list of full bootstrap.NodeInfo for each partner node.
// Args:
// - log: the logger instance.
// - log: logger used to log debug information.
// - partnerWeightsPath: path to partner weights configuration file.
// - partnerNodeInfoDir: path to partner nodes configuration file.
// Returns:
// - []bootstrap.NodeInfo: the generated node info list.
// - error: if any error occurs. Any error returned from this function is irrecoverable.
func ReadFullPartnerNodeInfos(log zerolog.Logger, partnerWeightsPath, partnerNodeInfoDir string) []bootstrap.NodeInfo {
partners := ReadPartnerNodes(log, partnerNodeInfoDir)
func ReadFullPartnerNodeInfos(log zerolog.Logger, partnerWeightsPath, partnerNodeInfoDir string) ([]bootstrap.NodeInfo, error) {
partners, err := ReadPartnerNodeInfos(partnerNodeInfoDir)
if err != nil {
return nil, err
}
log.Info().Msgf("read %d partner node configuration files", len(partners))

weights, err := ReadPartnerWeights(partnerWeightsPath)
if err != nil {
log.Fatal().Err(fmt.Errorf("failed to read partner weights: %w", err))
return nil, err
}
log.Info().Msgf("read %d weights for partner nodes", len(weights))

var nodes []bootstrap.NodeInfo
for _, partner := range partners {
// validate every single partner node
nodeID := ValidateNodeID(log, partner.NodeID)
networkPubKey := ValidateNetworkPubKey(log, partner.NetworkPubKey)
stakingPubKey := ValidateStakingPubKey(log, partner.StakingPubKey)
weight, valid := ValidateWeight(weights[partner.NodeID])
if !valid {
log.Error().Msgf("weights: %v", weights)
log.Fatal().Msgf("partner node id %x has no weight", nodeID)
err = ValidateNodeID(partner.NodeID)
if err != nil {
return nil, fmt.Errorf("invalid node ID: %s", partner.NodeID)
}
err = ValidateNetworkPubKey(partner.NetworkPubKey)
if err != nil {
return nil, fmt.Errorf(fmt.Sprintf("invalid network public key: %s", partner.NetworkPubKey))
}
err = ValidateStakingPubKey(partner.StakingPubKey)
if err != nil {
return nil, fmt.Errorf(fmt.Sprintf("invalid staking public key: %s", partner.StakingPubKey))
}
weight := weights[partner.NodeID]
if valid := ValidateWeight(weight); !valid {
return nil, fmt.Errorf(fmt.Sprintf("invalid partner weight: %d", weight))
}

if weight != flow.DefaultInitialWeight {
log.Warn().Msgf("partner node (id=%x) has non-default weight (%d != %d)", partner.NodeID, weight, flow.DefaultInitialWeight)
}

node := bootstrap.NewPublicNodeInfo(
nodeID,
partner.NodeID,
partner.Role,
partner.Address,
weight,
networkPubKey.PublicKey,
stakingPubKey.PublicKey,
partner.NetworkPubKey.PublicKey,
partner.StakingPubKey.PublicKey,
)
nodes = append(nodes, node)
}

return nodes
return nodes, nil
}

// ReadPartnerWeights reads the partner weights configuration file and returns a list of PartnerWeights.
Expand All @@ -70,43 +83,52 @@ func ReadPartnerWeights(partnerWeightsPath string) (PartnerWeights, error) {
if err != nil {
return nil, fmt.Errorf("failed to read partner weights json: %w", err)
}

return weights, nil
}

// ReadPartnerNodes reads the partner node info from the configuration file and returns a list of []bootstrap.NodeInfoPub.
// ReadPartnerNodeInfos reads the partner node info from the configuration file and returns a list of []bootstrap.NodeInfoPub.
// Args:
// - partnerNodeInfoDir: path to partner nodes configuration file.
// Returns:
// - []bootstrap.NodeInfoPub: the generated partner node info list.
// - error: if any error occurs. Any error returned from this function is irrecoverable.
func ReadPartnerNodes(log zerolog.Logger, partnerNodeInfoDir string) []bootstrap.NodeInfoPub {
func ReadPartnerNodeInfos(partnerNodeInfoDir string) ([]bootstrap.NodeInfoPub, error) {
var partners []bootstrap.NodeInfoPub
files, err := FilesInDir(partnerNodeInfoDir)
if err != nil {
log.Fatal().Err(err).Msg("could not read partner node infos")
return nil, fmt.Errorf("could not read partner node infos: %w", err)
}
for _, f := range files {
// skip files that do not include node-infos
if !strings.Contains(f, bootstrap.PathPartnerNodeInfoPrefix) {
continue
}

// read file and append to partners
var p bootstrap.NodeInfoPub
err = ReadJSON(f, &p)
if err != nil {
log.Fatal().Err(err).Msg("failed to read node info")
return nil, fmt.Errorf("failed to read node info: %w", err)
}
partners = append(partners, p)
}
return partners
return partners, nil
}

// ReadInternalNodeInfos returns a list of internal nodes after collecting weights
// from configuration files.
func ReadInternalNodeInfos(log zerolog.Logger, internalNodePrivInfoDir, internalWeightsConfig string) []bootstrap.NodeInfo {
privInternals := ReadInternalNodes(log, internalNodePrivInfoDir)
// ReadFullInternalNodeInfos reads internal node info and internal node weight information from the specified paths and constructs
// a list of full bootstrap.NodeInfo for each internal node.
// Args:
// - log: logger used to log debug information.
// - internalNodePrivInfoDir: path to internal nodes private info.
// - internalWeightsConfig: path to internal weights configuration file.
// Returns:
// - []bootstrap.NodeInfo: the generated node info list.
// - error: if any error occurs. Any error returned from this function is irrecoverable.
func ReadFullInternalNodeInfos(log zerolog.Logger, internalNodePrivInfoDir, internalWeightsConfig string) ([]bootstrap.NodeInfo, error) {
privInternals, err := ReadInternalNodeInfos(internalNodePrivInfoDir)
if err != nil {
return nil, err
}

Check failure on line 131 in cmd/util/cmd/common/node_info.go

View workflow job for this annotation

GitHub Actions / Lint (./)

File is not `goimports`-ed with -local github.com/onflow/flow-go (goimports)
log.Info().Msgf("read %v internal private node-info files", len(privInternals))

weights := internalWeightsByAddress(log, internalWeightsConfig)
Expand All @@ -118,18 +140,20 @@ func ReadInternalNodeInfos(log zerolog.Logger, internalNodePrivInfoDir, internal
ValidateAddressFormat(log, internal.Address)

// validate every single internal node
nodeID := ValidateNodeID(log, internal.NodeID)
weight, valid := ValidateWeight(weights[internal.Address])
if !valid {
log.Error().Msgf("weights: %v", weights)
log.Fatal().Msgf("internal node %v has no weight. Did you forget to update the node address?", internal)
err := ValidateNodeID(internal.NodeID)
if err != nil {
return nil, fmt.Errorf(fmt.Sprintf("invalid internal node ID: %s", internal.NodeID))
}
weight := weights[internal.NodeID.String()]
if valid := ValidateWeight(weight); !valid {
return nil, fmt.Errorf(fmt.Sprintf("invalid partner weight: %d", weight))
}
if weight != flow.DefaultInitialWeight {
log.Warn().Msgf("internal node (id=%x) has non-default weight (%d != %d)", internal.NodeID, weight, flow.DefaultInitialWeight)
}

node := bootstrap.NewPrivateNodeInfo(
nodeID,
internal.NodeID,
internal.Role,
internal.Address,
weight,
Expand All @@ -140,18 +164,22 @@ func ReadInternalNodeInfos(log zerolog.Logger, internalNodePrivInfoDir, internal
nodes = append(nodes, node)
}

return nodes
return nodes, nil
}

// ReadInternalNodes reads our internal node private infos generated by
// `keygen` command and returns it
func ReadInternalNodes(log zerolog.Logger, internalNodePrivInfoDir string) []bootstrap.NodeInfoPriv {
// ReadInternalNodeInfos reads our internal node private infos generated by `keygen` command and returns it.
// Args:
// - internalNodePrivInfoDir: path to internal nodes private info.
// Returns:
// - []bootstrap.NodeInfo: the generated private node info list.
// - error: if any error occurs. Any error returned from this function is irrecoverable.
func ReadInternalNodeInfos(internalNodePrivInfoDir string) ([]bootstrap.NodeInfoPriv, error) {
var internalPrivInfos []bootstrap.NodeInfoPriv

// get files in internal priv node infos directory
files, err := FilesInDir(internalNodePrivInfoDir)
if err != nil {
log.Fatal().Err(err).Msg("could not read partner node infos")
return nil, fmt.Errorf("could not read partner node infos: %w", err)
}

// for each of the files
Expand All @@ -165,12 +193,12 @@ func ReadInternalNodes(log zerolog.Logger, internalNodePrivInfoDir string) []boo
var p bootstrap.NodeInfoPriv
err = ReadJSON(f, &p)
if err != nil {
log.Fatal().Err(err).Msg("failed to read json")
return nil, fmt.Errorf("failed to read json: %w", err)
}
internalPrivInfos = append(internalPrivInfos, p)
}

return internalPrivInfos
return internalPrivInfos, nil
}

// internalWeightsByAddress returns a mapping of node address by weight for internal nodes
Expand Down
42 changes: 31 additions & 11 deletions cmd/util/cmd/common/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,29 +130,49 @@ func ValidateAddressFormat(log zerolog.Logger, address string) {
checkErr(err)
}

func ValidateNodeID(lg zerolog.Logger, nodeID flow.Identifier) flow.Identifier {
// ValidateNodeID returns an error if node ID is non-zero.
// Args:
// - nodeID: the node ID to validate.
// Returns:
// - error: if node id is the zero value.
func ValidateNodeID(nodeID flow.Identifier) error {
if nodeID == flow.ZeroID {
lg.Fatal().Msg("NodeID must not be zero")
return fmt.Errorf("NodeID must not be zero")
}
return nodeID
return nil
}

func ValidateNetworkPubKey(lg zerolog.Logger, key encodable.NetworkPubKey) encodable.NetworkPubKey {
// ValidateNetworkPubKey returns an error if network public key is nil.
// Args:
// - key: the public key.
// Returns:
// - error: if the network key is nil.
func ValidateNetworkPubKey(key encodable.NetworkPubKey) error {
if key.PublicKey == nil {
lg.Fatal().Msg("NetworkPubKey must not be nil")
return fmt.Errorf("network public key must not be nil")
}
return key
return nil
}

func ValidateStakingPubKey(lg zerolog.Logger, key encodable.StakingPubKey) encodable.StakingPubKey {
// ValidateStakingPubKey returns an error if the staking key is nil.
// Args:
// - key: the public key.
// Returns:
// - error: if the staking key is nil.
func ValidateStakingPubKey(key encodable.StakingPubKey) error {
if key.PublicKey == nil {
lg.Fatal().Msg("StakingPubKey must not be nil")
return fmt.Errorf("staking public key must not be nil")
}
return key
return nil
}

func ValidateWeight(weight uint64) (uint64, bool) {
return weight, weight > 0
// ValidateWeight returns true if weight is greater than 0.
// Args:
// - weight: the weight to check.
// Returns:
// - bool: true if weight is greater than 0.
func ValidateWeight(weight uint64) bool {
return weight > 0
}

// PartnerWeights is the format of the JSON file specifying partner node weights.
Expand Down
Loading

0 comments on commit 32df104

Please sign in to comment.