You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
336 lines
9.1 KiB
336 lines
9.1 KiB
// Package nodeconfig includes all the configuration variables for a node.
|
|
// It is a global configuration for node and other services.
|
|
// It will be included in node module, and other modules.
|
|
package nodeconfig
|
|
|
|
import (
|
|
"fmt"
|
|
"math/big"
|
|
"strings"
|
|
"sync"
|
|
|
|
bls_core "github.com/harmony-one/bls/ffi/go/bls"
|
|
"github.com/harmony-one/harmony/crypto/bls"
|
|
shardingconfig "github.com/harmony-one/harmony/internal/configs/sharding"
|
|
"github.com/harmony-one/harmony/internal/params"
|
|
"github.com/harmony-one/harmony/multibls"
|
|
"github.com/harmony-one/harmony/webhooks"
|
|
p2p_crypto "github.com/libp2p/go-libp2p-core/crypto"
|
|
"github.com/libp2p/go-libp2p-core/peer"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// Role defines a role of a node.
|
|
type Role byte
|
|
|
|
// All constants for different node roles.
|
|
const (
|
|
Unknown Role = iota
|
|
Validator
|
|
ExplorerNode
|
|
)
|
|
|
|
func (role Role) String() string {
|
|
switch role {
|
|
case Validator:
|
|
return "Validator"
|
|
case ExplorerNode:
|
|
return "ExplorerNode"
|
|
default:
|
|
return "Unknown"
|
|
}
|
|
}
|
|
|
|
// NetworkType describes the type of Harmony network
|
|
type NetworkType string
|
|
|
|
// Constants for NetworkType
|
|
// TODO: replace this with iota. Leave the string parsing in command line
|
|
const (
|
|
Mainnet = "mainnet"
|
|
Testnet = "testnet"
|
|
Pangaea = "pangaea"
|
|
Partner = "partner"
|
|
Stressnet = "stressnet"
|
|
Devnet = "devnet"
|
|
Localnet = "localnet"
|
|
)
|
|
|
|
// Global is the index of the global node configuration
|
|
const (
|
|
Global = 0
|
|
MaxShards = 32 // maximum number of shards. It is also the maxium number of configs.
|
|
)
|
|
|
|
var version string
|
|
var peerID peer.ID // PeerID of the node
|
|
|
|
// ConfigType is the structure of all node related configuration variables
|
|
type ConfigType struct {
|
|
// The three groupID design, please refer to https://github.com/harmony-one/harmony/blob/master/node/node.md#libp2p-integration
|
|
beacon GroupID // the beacon group ID
|
|
group GroupID // the group ID of the shard (note: for beacon chain node, the beacon and shard group are the same)
|
|
client GroupID // the client group ID of the shard
|
|
isClient bool // whether this node is a client node, such as wallet
|
|
ShardID uint32 // ShardID of this node; TODO ek – revisit when resharding
|
|
role Role // Role of the node
|
|
Port string // Port of the node.
|
|
IP string // IP of the node.
|
|
RPCServer RPCServerConfig // RPC server port and ip
|
|
RosettaServer RosettaServerConfig // rosetta server port and ip
|
|
PrometheusServer PrometheusServerConfig // prometheus server port and ip
|
|
IsOffline bool
|
|
NtpServer string
|
|
StringRole string
|
|
P2PPriKey p2p_crypto.PrivKey
|
|
ConsensusPriKey multibls.PrivateKeys
|
|
// Database directory
|
|
DBDir string
|
|
networkType NetworkType
|
|
shardingSchedule shardingconfig.Schedule
|
|
DNSZone string
|
|
isArchival bool
|
|
WebHooks struct {
|
|
Hooks *webhooks.Hooks
|
|
}
|
|
}
|
|
|
|
// RPCServerConfig is the config for rpc listen addresses
|
|
type RPCServerConfig struct {
|
|
HTTPEnabled bool
|
|
HTTPIp string
|
|
HTTPPort int
|
|
|
|
WSEnabled bool
|
|
WSIp string
|
|
WSPort int
|
|
|
|
DebugEnabled bool
|
|
}
|
|
|
|
// RosettaServerConfig is the config for the rosetta server
|
|
type RosettaServerConfig struct {
|
|
HTTPEnabled bool
|
|
HTTPIp string
|
|
HTTPPort int
|
|
}
|
|
|
|
// PrometheusServerConfig is the config for the prometheus server
|
|
type PrometheusServerConfig struct {
|
|
HTTPEnabled bool
|
|
HTTPIp string
|
|
HTTPPort int
|
|
}
|
|
|
|
// configs is a list of node configuration.
|
|
// It has at least one configuration.
|
|
// The first one is the default, global node configuration
|
|
var shardConfigs []ConfigType
|
|
var defaultConfig ConfigType
|
|
var onceForConfigs sync.Once
|
|
|
|
func ensureShardConfigs() {
|
|
onceForConfigs.Do(func() {
|
|
shardConfigs = make([]ConfigType, MaxShards)
|
|
for i := range shardConfigs {
|
|
shardConfigs[i].ShardID = uint32(i)
|
|
}
|
|
})
|
|
}
|
|
|
|
// GetShardConfig return the shard's ConfigType variable
|
|
func GetShardConfig(shardID uint32) *ConfigType {
|
|
ensureShardConfigs()
|
|
if int(shardID) >= cap(shardConfigs) {
|
|
return nil
|
|
}
|
|
return &shardConfigs[shardID]
|
|
}
|
|
|
|
// GetDefaultConfig returns default config.
|
|
func GetDefaultConfig() *ConfigType {
|
|
return &defaultConfig
|
|
}
|
|
|
|
// SetDefaultRole ..
|
|
func SetDefaultRole(r Role) {
|
|
defaultConfig.role = r
|
|
}
|
|
|
|
func (conf *ConfigType) String() string {
|
|
return fmt.Sprintf("%s/%s/%s:%v,%v", conf.beacon, conf.group, conf.client, conf.isClient, conf.ShardID)
|
|
}
|
|
|
|
// SetBeaconGroupID set the groupID for beacon group
|
|
func (conf *ConfigType) SetBeaconGroupID(g GroupID) {
|
|
conf.beacon = g
|
|
}
|
|
|
|
// SetShardGroupID set the groupID for shard group
|
|
func (conf *ConfigType) SetShardGroupID(g GroupID) {
|
|
conf.group = g
|
|
}
|
|
|
|
// SetClientGroupID set the groupID for client group
|
|
func (conf *ConfigType) SetClientGroupID(g GroupID) {
|
|
conf.client = g
|
|
}
|
|
|
|
// SetShardID set the ShardID
|
|
func (conf *ConfigType) SetShardID(s uint32) {
|
|
conf.ShardID = s
|
|
}
|
|
|
|
// SetRole set the role
|
|
func (conf *ConfigType) SetRole(r Role) {
|
|
conf.role = r
|
|
}
|
|
|
|
// GetBeaconGroupID returns the groupID for beacon group
|
|
func (conf *ConfigType) GetBeaconGroupID() GroupID {
|
|
return conf.beacon
|
|
}
|
|
|
|
// GetShardGroupID returns the groupID for shard group
|
|
func (conf *ConfigType) GetShardGroupID() GroupID {
|
|
return conf.group
|
|
}
|
|
|
|
// GetShardID returns the shardID.
|
|
func (conf *ConfigType) GetShardID() uint32 {
|
|
return conf.ShardID
|
|
}
|
|
|
|
// GetClientGroupID returns the groupID for client group
|
|
func (conf *ConfigType) GetClientGroupID() GroupID {
|
|
return conf.client
|
|
}
|
|
|
|
// GetArchival returns archival mode
|
|
func (conf *ConfigType) GetArchival() bool {
|
|
return conf.isArchival
|
|
}
|
|
|
|
// Role returns the role
|
|
func (conf *ConfigType) Role() Role {
|
|
return conf.role
|
|
}
|
|
|
|
// SetNetworkType set the networkType
|
|
func SetNetworkType(networkType NetworkType) {
|
|
ensureShardConfigs()
|
|
defaultConfig.networkType = networkType
|
|
for i := range shardConfigs {
|
|
shardConfigs[i].networkType = networkType
|
|
}
|
|
}
|
|
|
|
// SetArchival set archival mode
|
|
func (conf *ConfigType) SetArchival(archival bool) {
|
|
defaultConfig.isArchival = archival
|
|
}
|
|
|
|
// GetNetworkType gets the networkType
|
|
func (conf *ConfigType) GetNetworkType() NetworkType {
|
|
return conf.networkType
|
|
}
|
|
|
|
// SetVersion set the version of the node binary
|
|
func SetVersion(ver string) {
|
|
version = ver
|
|
}
|
|
|
|
// GetVersion return the version of the node binary
|
|
func GetVersion() string {
|
|
return version
|
|
}
|
|
|
|
// SetPeerID set the peer ID of the node
|
|
func SetPeerID(pid peer.ID) {
|
|
peerID = pid
|
|
}
|
|
|
|
// GetPeerID returns the peer ID of the node
|
|
func GetPeerID() peer.ID {
|
|
return peerID
|
|
}
|
|
|
|
// ShardingSchedule returns the sharding schedule for this node config.
|
|
func (conf *ConfigType) ShardingSchedule() shardingconfig.Schedule {
|
|
return conf.shardingSchedule
|
|
}
|
|
|
|
// SetShardingSchedule sets the sharding schedule for this node config.
|
|
func (conf *ConfigType) SetShardingSchedule(schedule shardingconfig.Schedule) {
|
|
conf.shardingSchedule = schedule
|
|
}
|
|
|
|
// SetShardingSchedule sets the sharding schedule for all config instances.
|
|
func SetShardingSchedule(schedule shardingconfig.Schedule) {
|
|
ensureShardConfigs()
|
|
defaultConfig.SetShardingSchedule(schedule)
|
|
for _, config := range shardConfigs {
|
|
config.SetShardingSchedule(schedule)
|
|
}
|
|
}
|
|
|
|
// ShardIDFromKey returns the shard ID statically determined from the input key
|
|
func (conf *ConfigType) ShardIDFromKey(key *bls_core.PublicKey) (uint32, error) {
|
|
var pubKey bls.SerializedPublicKey
|
|
if err := pubKey.FromLibBLSPublicKey(key); err != nil {
|
|
return 0, errors.Wrapf(err,
|
|
"cannot convert libbls public key %s to internal form",
|
|
key.SerializeToHexStr())
|
|
}
|
|
epoch := conf.networkType.ChainConfig().StakingEpoch
|
|
numShards := conf.shardingSchedule.InstanceForEpoch(epoch).NumShards()
|
|
shardID := new(big.Int).Mod(pubKey.Big(), big.NewInt(int64(numShards)))
|
|
return uint32(shardID.Uint64()), nil
|
|
}
|
|
|
|
// ShardIDFromConsensusKey returns the shard ID statically determined from the
|
|
// consensus key.
|
|
func (conf *ConfigType) ShardIDFromConsensusKey() (uint32, error) {
|
|
return conf.ShardIDFromKey(conf.ConsensusPriKey[0].Pub.Object)
|
|
}
|
|
|
|
// ValidateConsensusKeysForSameShard checks if all consensus public keys belong to the same shard
|
|
func (conf *ConfigType) ValidateConsensusKeysForSameShard(pubkeys multibls.PublicKeys, sID uint32) error {
|
|
keyShardStrs := []string{}
|
|
isSameShard := true
|
|
for _, key := range pubkeys {
|
|
shardID, err := conf.ShardIDFromKey(key.Object)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if shardID != sID {
|
|
isSameShard = false
|
|
}
|
|
keyShardStrs = append(
|
|
keyShardStrs,
|
|
fmt.Sprintf("key: %s, shard id: %d", key.Bytes.Hex(), shardID),
|
|
)
|
|
}
|
|
if !isSameShard {
|
|
return errors.Errorf("bls keys do not belong to same shard\n%s", strings.Join(keyShardStrs, "\n"))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ChainConfig returns the chain configuration for the network type.
|
|
func (t NetworkType) ChainConfig() params.ChainConfig {
|
|
switch t {
|
|
case Mainnet:
|
|
return *params.MainnetChainConfig
|
|
case Pangaea:
|
|
return *params.PangaeaChainConfig
|
|
case Partner:
|
|
return *params.PartnerChainConfig
|
|
case Stressnet:
|
|
return *params.StressnetChainConfig
|
|
case Localnet:
|
|
return *params.LocalnetChainConfig
|
|
default:
|
|
return *params.TestnetChainConfig
|
|
}
|
|
}
|
|
|