github.com/MetalBlockchain/metalgo@v1.11.9/snow/validators/gvalidators/validator_state_client.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package gvalidators
     5  
     6  import (
     7  	"context"
     8  	"errors"
     9  
    10  	"google.golang.org/protobuf/types/known/emptypb"
    11  
    12  	"github.com/MetalBlockchain/metalgo/ids"
    13  	"github.com/MetalBlockchain/metalgo/snow/validators"
    14  	"github.com/MetalBlockchain/metalgo/utils/crypto/bls"
    15  
    16  	pb "github.com/MetalBlockchain/metalgo/proto/pb/validatorstate"
    17  )
    18  
    19  var (
    20  	_                             validators.State = (*Client)(nil)
    21  	errFailedPublicKeyDeserialize                  = errors.New("couldn't deserialize public key")
    22  )
    23  
    24  type Client struct {
    25  	client pb.ValidatorStateClient
    26  }
    27  
    28  func NewClient(client pb.ValidatorStateClient) *Client {
    29  	return &Client{client: client}
    30  }
    31  
    32  func (c *Client) GetMinimumHeight(ctx context.Context) (uint64, error) {
    33  	resp, err := c.client.GetMinimumHeight(ctx, &emptypb.Empty{})
    34  	if err != nil {
    35  		return 0, err
    36  	}
    37  	return resp.Height, nil
    38  }
    39  
    40  func (c *Client) GetCurrentHeight(ctx context.Context) (uint64, error) {
    41  	resp, err := c.client.GetCurrentHeight(ctx, &emptypb.Empty{})
    42  	if err != nil {
    43  		return 0, err
    44  	}
    45  	return resp.Height, nil
    46  }
    47  
    48  func (c *Client) GetSubnetID(ctx context.Context, chainID ids.ID) (ids.ID, error) {
    49  	resp, err := c.client.GetSubnetID(ctx, &pb.GetSubnetIDRequest{
    50  		ChainId: chainID[:],
    51  	})
    52  	if err != nil {
    53  		return ids.Empty, err
    54  	}
    55  	return ids.ToID(resp.SubnetId)
    56  }
    57  
    58  func (c *Client) GetValidatorSet(
    59  	ctx context.Context,
    60  	height uint64,
    61  	subnetID ids.ID,
    62  ) (map[ids.NodeID]*validators.GetValidatorOutput, error) {
    63  	resp, err := c.client.GetValidatorSet(ctx, &pb.GetValidatorSetRequest{
    64  		Height:   height,
    65  		SubnetId: subnetID[:],
    66  	})
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  
    71  	vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, len(resp.Validators))
    72  	for _, validator := range resp.Validators {
    73  		nodeID, err := ids.ToNodeID(validator.NodeId)
    74  		if err != nil {
    75  			return nil, err
    76  		}
    77  		var publicKey *bls.PublicKey
    78  		if len(validator.PublicKey) > 0 {
    79  			// This is a performance optimization to avoid the cost of
    80  			// compression and key re-verification with
    81  			// PublicKeyFromCompressedBytes. We can safely assume that the BLS
    82  			// Public Keys are verified before being added to the P-Chain and
    83  			// served by the gRPC server.
    84  			publicKey = bls.PublicKeyFromValidUncompressedBytes(validator.PublicKey)
    85  			if publicKey == nil {
    86  				return nil, errFailedPublicKeyDeserialize
    87  			}
    88  		}
    89  		vdrs[nodeID] = &validators.GetValidatorOutput{
    90  			NodeID:    nodeID,
    91  			PublicKey: publicKey,
    92  			Weight:    validator.Weight,
    93  		}
    94  	}
    95  	return vdrs, nil
    96  }