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