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.
 
 
 
 
 
 

66 lines
1.8 KiB

package types
import (
"encoding/hex"
"errors"
"fmt"
"regexp"
"strings"
"github.com/tendermint/tendermint/crypto"
)
// NodeIDByteLength is the length of a crypto.Address. Currently only 20.
// FIXME: support other length addresses?
const NodeIDByteLength = crypto.AddressSize
// reNodeID is a regexp for valid node IDs.
var reNodeID = regexp.MustCompile(`^[0-9a-f]{40}$`)
// NodeID is a hex-encoded crypto.Address. It must be lowercased
// (for uniqueness) and of length 2*NodeIDByteLength.
type NodeID string
// NewNodeID returns a lowercased (normalized) NodeID, or errors if the
// node ID is invalid.
func NewNodeID(nodeID string) (NodeID, error) {
n := NodeID(strings.ToLower(nodeID))
return n, n.Validate()
}
// IDAddressString returns id@hostPort. It strips the leading
// protocol from protocolHostPort if it exists.
func (id NodeID) AddressString(protocolHostPort string) string {
return fmt.Sprintf("%s@%s", id, removeProtocolIfDefined(protocolHostPort))
}
// NodeIDFromPubKey creates a node ID from a given PubKey address.
func NodeIDFromPubKey(pubKey crypto.PubKey) NodeID {
return NodeID(hex.EncodeToString(pubKey.Address()))
}
// Bytes converts the node ID to its binary byte representation.
func (id NodeID) Bytes() ([]byte, error) {
bz, err := hex.DecodeString(string(id))
if err != nil {
return nil, fmt.Errorf("invalid node ID encoding: %w", err)
}
return bz, nil
}
// Validate validates the NodeID.
func (id NodeID) Validate() error {
switch {
case len(id) == 0:
return errors.New("empty node ID")
case len(id) != 2*NodeIDByteLength:
return fmt.Errorf("invalid node ID length %d, expected %d", len(id), 2*NodeIDByteLength)
case !reNodeID.MatchString(string(id)):
return fmt.Errorf("node ID can only contain lowercased hex digits")
default:
return nil
}
}