github.com/MetalBlockchain/metalgo@v1.11.9/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/MetalBlockchain/metalgo/ids" 13 "github.com/MetalBlockchain/metalgo/utils/crypto/bls" 14 "github.com/MetalBlockchain/metalgo/vms/platformvm/txs" 15 ) 16 17 var _ btree.LessFunc[*Staker] = (*Staker).Less 18 19 // StakerIterator defines an interface for iterating over a set of stakers. 20 type StakerIterator interface { 21 // Next attempts to move the iterator to the next staker. It returns false 22 // once there are no more stakers to return. 23 Next() bool 24 25 // Value returns the current staker. Value should only be called after a 26 // call to Next which returned true. 27 Value() *Staker 28 29 // Release any resources associated with the iterator. This must be called 30 // after the interator is no longer needed. 31 Release() 32 } 33 34 // Staker contains all information required to represent a validator or 35 // delegator in the current and pending validator sets. 36 // Invariant: Staker's size is bounded to prevent OOM DoS attacks. 37 type Staker struct { 38 TxID ids.ID 39 NodeID ids.NodeID 40 PublicKey *bls.PublicKey 41 SubnetID ids.ID 42 Weight uint64 43 StartTime time.Time 44 EndTime time.Time 45 PotentialReward uint64 46 47 // NextTime is the next time this staker will be moved from a validator set. 48 // If the staker is in the pending validator set, NextTime will equal 49 // StartTime. If the staker is in the current validator set, NextTime will 50 // equal EndTime. 51 NextTime time.Time 52 53 // Priority specifies how to break ties between stakers with the same 54 // NextTime. This ensures that stakers created by the same transaction type 55 // are grouped together. The ordering of these groups is documented in 56 // [priorities.go] and depends on if the stakers are in the pending or 57 // current validator set. 58 Priority txs.Priority 59 } 60 61 // A *Staker is considered to be less than another *Staker when: 62 // 63 // 1. If its NextTime is before the other's. 64 // 2. If the NextTimes are the same, the *Staker with the lesser priority is the 65 // lesser one. 66 // 3. If the priorities are also the same, the one with the lesser txID is 67 // lesser. 68 func (s *Staker) Less(than *Staker) bool { 69 if s.NextTime.Before(than.NextTime) { 70 return true 71 } 72 if than.NextTime.Before(s.NextTime) { 73 return false 74 } 75 76 if s.Priority < than.Priority { 77 return true 78 } 79 if than.Priority < s.Priority { 80 return false 81 } 82 83 return bytes.Compare(s.TxID[:], than.TxID[:]) == -1 84 } 85 86 func NewCurrentStaker( 87 txID ids.ID, 88 staker txs.Staker, 89 startTime time.Time, 90 potentialReward uint64, 91 ) (*Staker, error) { 92 publicKey, _, err := staker.PublicKey() 93 if err != nil { 94 return nil, err 95 } 96 endTime := staker.EndTime() 97 return &Staker{ 98 TxID: txID, 99 NodeID: staker.NodeID(), 100 PublicKey: publicKey, 101 SubnetID: staker.SubnetID(), 102 Weight: staker.Weight(), 103 StartTime: startTime, 104 EndTime: endTime, 105 PotentialReward: potentialReward, 106 NextTime: endTime, 107 Priority: staker.CurrentPriority(), 108 }, nil 109 } 110 111 func NewPendingStaker(txID ids.ID, staker txs.ScheduledStaker) (*Staker, error) { 112 publicKey, _, err := staker.PublicKey() 113 if err != nil { 114 return nil, err 115 } 116 startTime := staker.StartTime() 117 return &Staker{ 118 TxID: txID, 119 NodeID: staker.NodeID(), 120 PublicKey: publicKey, 121 SubnetID: staker.SubnetID(), 122 Weight: staker.Weight(), 123 StartTime: startTime, 124 EndTime: staker.EndTime(), 125 NextTime: startTime, 126 Priority: staker.PendingPriority(), 127 }, nil 128 }