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  }