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  }