github.com/MetalBlockchain/metalgo@v1.11.9/vms/platformvm/state/stakers_test.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 "testing" 8 "time" 9 10 "github.com/stretchr/testify/require" 11 12 "github.com/MetalBlockchain/metalgo/database" 13 "github.com/MetalBlockchain/metalgo/ids" 14 "github.com/MetalBlockchain/metalgo/vms/platformvm/txs" 15 ) 16 17 func TestBaseStakersPruning(t *testing.T) { 18 require := require.New(t) 19 staker := newTestStaker() 20 delegator := newTestStaker() 21 delegator.SubnetID = staker.SubnetID 22 delegator.NodeID = staker.NodeID 23 24 v := newBaseStakers() 25 26 v.PutValidator(staker) 27 28 _, err := v.GetValidator(staker.SubnetID, staker.NodeID) 29 require.NoError(err) 30 31 v.PutDelegator(delegator) 32 33 _, err = v.GetValidator(staker.SubnetID, staker.NodeID) 34 require.NoError(err) 35 36 v.DeleteValidator(staker) 37 38 _, err = v.GetValidator(staker.SubnetID, staker.NodeID) 39 require.ErrorIs(err, database.ErrNotFound) 40 41 v.DeleteDelegator(delegator) 42 43 require.Empty(v.validators) 44 45 v.PutValidator(staker) 46 47 _, err = v.GetValidator(staker.SubnetID, staker.NodeID) 48 require.NoError(err) 49 50 v.PutDelegator(delegator) 51 52 _, err = v.GetValidator(staker.SubnetID, staker.NodeID) 53 require.NoError(err) 54 55 v.DeleteDelegator(delegator) 56 57 _, err = v.GetValidator(staker.SubnetID, staker.NodeID) 58 require.NoError(err) 59 60 v.DeleteValidator(staker) 61 62 _, err = v.GetValidator(staker.SubnetID, staker.NodeID) 63 require.ErrorIs(err, database.ErrNotFound) 64 65 require.Empty(v.validators) 66 } 67 68 func TestBaseStakersValidator(t *testing.T) { 69 require := require.New(t) 70 staker := newTestStaker() 71 delegator := newTestStaker() 72 73 v := newBaseStakers() 74 75 v.PutDelegator(delegator) 76 77 _, err := v.GetValidator(ids.GenerateTestID(), delegator.NodeID) 78 require.ErrorIs(err, database.ErrNotFound) 79 80 _, err = v.GetValidator(delegator.SubnetID, ids.GenerateTestNodeID()) 81 require.ErrorIs(err, database.ErrNotFound) 82 83 _, err = v.GetValidator(delegator.SubnetID, delegator.NodeID) 84 require.ErrorIs(err, database.ErrNotFound) 85 86 stakerIterator := v.GetStakerIterator() 87 assertIteratorsEqual(t, NewSliceIterator(delegator), stakerIterator) 88 89 v.PutValidator(staker) 90 91 returnedStaker, err := v.GetValidator(staker.SubnetID, staker.NodeID) 92 require.NoError(err) 93 require.Equal(staker, returnedStaker) 94 95 v.DeleteDelegator(delegator) 96 97 stakerIterator = v.GetStakerIterator() 98 assertIteratorsEqual(t, NewSliceIterator(staker), stakerIterator) 99 100 v.DeleteValidator(staker) 101 102 _, err = v.GetValidator(staker.SubnetID, staker.NodeID) 103 require.ErrorIs(err, database.ErrNotFound) 104 105 stakerIterator = v.GetStakerIterator() 106 assertIteratorsEqual(t, EmptyIterator, stakerIterator) 107 } 108 109 func TestBaseStakersDelegator(t *testing.T) { 110 staker := newTestStaker() 111 delegator := newTestStaker() 112 113 v := newBaseStakers() 114 115 delegatorIterator := v.GetDelegatorIterator(delegator.SubnetID, delegator.NodeID) 116 assertIteratorsEqual(t, EmptyIterator, delegatorIterator) 117 118 v.PutDelegator(delegator) 119 120 delegatorIterator = v.GetDelegatorIterator(delegator.SubnetID, ids.GenerateTestNodeID()) 121 assertIteratorsEqual(t, EmptyIterator, delegatorIterator) 122 123 delegatorIterator = v.GetDelegatorIterator(delegator.SubnetID, delegator.NodeID) 124 assertIteratorsEqual(t, NewSliceIterator(delegator), delegatorIterator) 125 126 v.DeleteDelegator(delegator) 127 128 delegatorIterator = v.GetDelegatorIterator(delegator.SubnetID, delegator.NodeID) 129 assertIteratorsEqual(t, EmptyIterator, delegatorIterator) 130 131 v.PutValidator(staker) 132 133 v.PutDelegator(delegator) 134 v.DeleteDelegator(delegator) 135 136 delegatorIterator = v.GetDelegatorIterator(staker.SubnetID, staker.NodeID) 137 assertIteratorsEqual(t, EmptyIterator, delegatorIterator) 138 } 139 140 func TestDiffStakersValidator(t *testing.T) { 141 require := require.New(t) 142 staker := newTestStaker() 143 delegator := newTestStaker() 144 145 v := diffStakers{} 146 147 v.PutDelegator(delegator) 148 149 // validators not available in the diff are marked as unmodified 150 _, status := v.GetValidator(ids.GenerateTestID(), delegator.NodeID) 151 require.Equal(unmodified, status) 152 153 _, status = v.GetValidator(delegator.SubnetID, ids.GenerateTestNodeID()) 154 require.Equal(unmodified, status) 155 156 // delegator addition shouldn't change validatorStatus 157 _, status = v.GetValidator(delegator.SubnetID, delegator.NodeID) 158 require.Equal(unmodified, status) 159 160 stakerIterator := v.GetStakerIterator(EmptyIterator) 161 assertIteratorsEqual(t, NewSliceIterator(delegator), stakerIterator) 162 163 v.PutValidator(staker) 164 165 returnedStaker, status := v.GetValidator(staker.SubnetID, staker.NodeID) 166 require.Equal(added, status) 167 require.Equal(staker, returnedStaker) 168 169 v.DeleteValidator(staker) 170 171 // Validators created and deleted in the same diff are marked as unmodified. 172 // This means they won't be pushed to baseState if diff.Apply(baseState) is 173 // called. 174 _, status = v.GetValidator(staker.SubnetID, staker.NodeID) 175 require.Equal(unmodified, status) 176 177 stakerIterator = v.GetStakerIterator(EmptyIterator) 178 assertIteratorsEqual(t, NewSliceIterator(delegator), stakerIterator) 179 } 180 181 func TestDiffStakersDeleteValidator(t *testing.T) { 182 require := require.New(t) 183 staker := newTestStaker() 184 delegator := newTestStaker() 185 186 v := diffStakers{} 187 188 _, status := v.GetValidator(ids.GenerateTestID(), delegator.NodeID) 189 require.Equal(unmodified, status) 190 191 v.DeleteValidator(staker) 192 193 returnedStaker, status := v.GetValidator(staker.SubnetID, staker.NodeID) 194 require.Equal(deleted, status) 195 require.Nil(returnedStaker) 196 } 197 198 func TestDiffStakersDelegator(t *testing.T) { 199 staker := newTestStaker() 200 delegator := newTestStaker() 201 202 v := diffStakers{} 203 204 v.PutValidator(staker) 205 206 delegatorIterator := v.GetDelegatorIterator(EmptyIterator, ids.GenerateTestID(), delegator.NodeID) 207 assertIteratorsEqual(t, EmptyIterator, delegatorIterator) 208 209 v.PutDelegator(delegator) 210 211 delegatorIterator = v.GetDelegatorIterator(EmptyIterator, delegator.SubnetID, delegator.NodeID) 212 assertIteratorsEqual(t, NewSliceIterator(delegator), delegatorIterator) 213 214 v.DeleteDelegator(delegator) 215 216 delegatorIterator = v.GetDelegatorIterator(EmptyIterator, ids.GenerateTestID(), delegator.NodeID) 217 assertIteratorsEqual(t, EmptyIterator, delegatorIterator) 218 } 219 220 func newTestStaker() *Staker { 221 startTime := time.Now().Round(time.Second) 222 endTime := startTime.Add(28 * 24 * time.Hour) 223 return &Staker{ 224 TxID: ids.GenerateTestID(), 225 NodeID: ids.GenerateTestNodeID(), 226 SubnetID: ids.GenerateTestID(), 227 Weight: 1, 228 StartTime: startTime, 229 EndTime: endTime, 230 PotentialReward: 1, 231 232 NextTime: endTime, 233 Priority: txs.PrimaryNetworkDelegatorCurrentPriority, 234 } 235 } 236 237 func assertIteratorsEqual(t *testing.T, expected, actual StakerIterator) { 238 require := require.New(t) 239 240 t.Helper() 241 242 for expected.Next() { 243 require.True(actual.Next()) 244 245 expectedStaker := expected.Value() 246 actualStaker := actual.Value() 247 248 require.Equal(expectedStaker, actualStaker) 249 } 250 require.False(actual.Next()) 251 252 expected.Release() 253 actual.Release() 254 }