github.com/MetalBlockchain/metalgo@v1.11.9/ids/node_id.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package ids
     5  
     6  import (
     7  	"bytes"
     8  	"errors"
     9  	"fmt"
    10  
    11  	"github.com/MetalBlockchain/metalgo/staking"
    12  	"github.com/MetalBlockchain/metalgo/utils"
    13  	"github.com/MetalBlockchain/metalgo/utils/hashing"
    14  )
    15  
    16  const (
    17  	NodeIDPrefix = "NodeID-"
    18  	NodeIDLen    = ShortIDLen
    19  )
    20  
    21  var (
    22  	EmptyNodeID = NodeID{}
    23  
    24  	errShortNodeID = errors.New("insufficient NodeID length")
    25  
    26  	_ utils.Sortable[NodeID] = NodeID{}
    27  )
    28  
    29  type NodeID ShortID
    30  
    31  func (id NodeID) String() string {
    32  	return ShortID(id).PrefixedString(NodeIDPrefix)
    33  }
    34  
    35  func (id NodeID) Bytes() []byte {
    36  	return id[:]
    37  }
    38  
    39  func (id NodeID) MarshalJSON() ([]byte, error) {
    40  	return []byte(`"` + id.String() + `"`), nil
    41  }
    42  
    43  func (id NodeID) MarshalText() ([]byte, error) {
    44  	return []byte(id.String()), nil
    45  }
    46  
    47  func (id *NodeID) UnmarshalJSON(b []byte) error {
    48  	str := string(b)
    49  	if str == nullStr { // If "null", do nothing
    50  		return nil
    51  	} else if len(str) <= 2+len(NodeIDPrefix) {
    52  		return fmt.Errorf("%w: expected to be > %d", errShortNodeID, 2+len(NodeIDPrefix))
    53  	}
    54  
    55  	lastIndex := len(str) - 1
    56  	if str[0] != '"' || str[lastIndex] != '"' {
    57  		return errMissingQuotes
    58  	}
    59  
    60  	var err error
    61  	*id, err = NodeIDFromString(str[1:lastIndex])
    62  	return err
    63  }
    64  
    65  func (id *NodeID) UnmarshalText(text []byte) error {
    66  	return id.UnmarshalJSON(text)
    67  }
    68  
    69  func (id NodeID) Compare(other NodeID) int {
    70  	return bytes.Compare(id[:], other[:])
    71  }
    72  
    73  // ToNodeID attempt to convert a byte slice into a node id
    74  func ToNodeID(bytes []byte) (NodeID, error) {
    75  	nodeID, err := ToShortID(bytes)
    76  	return NodeID(nodeID), err
    77  }
    78  
    79  func NodeIDFromCert(cert *staking.Certificate) NodeID {
    80  	return hashing.ComputeHash160Array(
    81  		hashing.ComputeHash256(cert.Raw),
    82  	)
    83  }
    84  
    85  // NodeIDFromString is the inverse of NodeID.String()
    86  func NodeIDFromString(nodeIDStr string) (NodeID, error) {
    87  	asShort, err := ShortFromPrefixedString(nodeIDStr, NodeIDPrefix)
    88  	if err != nil {
    89  		return NodeID{}, err
    90  	}
    91  	return NodeID(asShort), nil
    92  }