github.com/ava-labs/avalanchego@v1.11.11/vms/platformvm/state/staker.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package state
     5  
     6  import (
     7  	"bytes"
     8  	"time"
     9  
    10  	"github.com/google/btree"
    11  
    12  	"github.com/ava-labs/avalanchego/ids"
    13  	"github.com/ava-labs/avalanchego/utils/crypto/bls"
    14  	"github.com/ava-labs/avalanchego/vms/platformvm/txs"
    15  )
    16  
    17  var _ btree.LessFunc[*Staker] = (*Staker).Less
    18  
    19  // Staker contains all information required to represent a validator or
    20  // delegator in the current and pending validator sets.
    21  // Invariant: Staker's size is bounded to prevent OOM DoS attacks.
    22  type Staker struct {
    23  	TxID            ids.ID
    24  	NodeID          ids.NodeID
    25  	PublicKey       *bls.PublicKey
    26  	SubnetID        ids.ID
    27  	Weight          uint64
    28  	StartTime       time.Time
    29  	EndTime         time.Time
    30  	PotentialReward uint64
    31  
    32  	// NextTime is the next time this staker will be moved from a validator set.
    33  	// If the staker is in the pending validator set, NextTime will equal
    34  	// StartTime. If the staker is in the current validator set, NextTime will
    35  	// equal EndTime.
    36  	NextTime time.Time
    37  
    38  	// Priority specifies how to break ties between stakers with the same
    39  	// NextTime. This ensures that stakers created by the same transaction type
    40  	// are grouped together. The ordering of these groups is documented in
    41  	// [priorities.go] and depends on if the stakers are in the pending or
    42  	// current validator set.
    43  	Priority txs.Priority
    44  }
    45  
    46  // A *Staker is considered to be less than another *Staker when:
    47  //
    48  //  1. If its NextTime is before the other's.
    49  //  2. If the NextTimes are the same, the *Staker with the lesser priority is the
    50  //     lesser one.
    51  //  3. If the priorities are also the same, the one with the lesser txID is
    52  //     lesser.
    53  func (s *Staker) Less(than *Staker) bool {
    54  	if s.NextTime.Before(than.NextTime) {
    55  		return true
    56  	}
    57  	if than.NextTime.Before(s.NextTime) {
    58  		return false
    59  	}
    60  
    61  	if s.Priority < than.Priority {
    62  		return true
    63  	}
    64  	if than.Priority < s.Priority {
    65  		return false
    66  	}
    67  
    68  	return bytes.Compare(s.TxID[:], than.TxID[:]) == -1
    69  }
    70  
    71  func NewCurrentStaker(
    72  	txID ids.ID,
    73  	staker txs.Staker,
    74  	startTime time.Time,
    75  	potentialReward uint64,
    76  ) (*Staker, error) {
    77  	publicKey, _, err := staker.PublicKey()
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  	endTime := staker.EndTime()
    82  	return &Staker{
    83  		TxID:            txID,
    84  		NodeID:          staker.NodeID(),
    85  		PublicKey:       publicKey,
    86  		SubnetID:        staker.SubnetID(),
    87  		Weight:          staker.Weight(),
    88  		StartTime:       startTime,
    89  		EndTime:         endTime,
    90  		PotentialReward: potentialReward,
    91  		NextTime:        endTime,
    92  		Priority:        staker.CurrentPriority(),
    93  	}, nil
    94  }
    95  
    96  func NewPendingStaker(txID ids.ID, staker txs.ScheduledStaker) (*Staker, error) {
    97  	publicKey, _, err := staker.PublicKey()
    98  	if err != nil {
    99  		return nil, err
   100  	}
   101  	startTime := staker.StartTime()
   102  	return &Staker{
   103  		TxID:      txID,
   104  		NodeID:    staker.NodeID(),
   105  		PublicKey: publicKey,
   106  		SubnetID:  staker.SubnetID(),
   107  		Weight:    staker.Weight(),
   108  		StartTime: startTime,
   109  		EndTime:   staker.EndTime(),
   110  		NextTime:  startTime,
   111  		Priority:  staker.PendingPriority(),
   112  	}, nil
   113  }