code.vegaprotocol.io/vega@v0.79.0/core/delegation/engine_test.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package delegation
    17  
    18  import (
    19  	"bytes"
    20  	"context"
    21  	"fmt"
    22  	"math/rand"
    23  	"strconv"
    24  	"testing"
    25  	"time"
    26  
    27  	"code.vegaprotocol.io/vega/core/broker/mocks"
    28  	dmocks "code.vegaprotocol.io/vega/core/delegation/mocks"
    29  	"code.vegaprotocol.io/vega/core/events"
    30  	"code.vegaprotocol.io/vega/core/integration/stubs"
    31  	snp "code.vegaprotocol.io/vega/core/snapshot"
    32  	"code.vegaprotocol.io/vega/core/stats"
    33  	"code.vegaprotocol.io/vega/core/types"
    34  	"code.vegaprotocol.io/vega/core/validators"
    35  	"code.vegaprotocol.io/vega/libs/num"
    36  	"code.vegaprotocol.io/vega/libs/proto"
    37  	vgtest "code.vegaprotocol.io/vega/libs/test"
    38  	"code.vegaprotocol.io/vega/logging"
    39  	"code.vegaprotocol.io/vega/paths"
    40  	snapshot "code.vegaprotocol.io/vega/protos/vega/snapshot/v1"
    41  
    42  	"github.com/golang/mock/gomock"
    43  	"github.com/stretchr/testify/assert"
    44  	"github.com/stretchr/testify/require"
    45  )
    46  
    47  type testEngine struct {
    48  	engine          *Engine
    49  	ctrl            *gomock.Controller
    50  	broker          *mocks.MockBroker
    51  	stakingAccounts *TestStakingAccount
    52  	topology        *TestTopology
    53  }
    54  
    55  func Test(t *testing.T) {
    56  	// delegate tests
    57  	t.Run("Delegation to an unknown node fails", testDelegateInvalidNode)
    58  	t.Run("Delegation with no staking account fails", testDelegateNoStakingAccount)
    59  	t.Run("Delegation of an amount lower than min delegation amount fails", testDelegateLessThanMinDelegationAmount)
    60  	t.Run("Delegation of an amount greater than the available balance for delegation - no pending delegations, no active delegations fails", testDelegateInsufficientBalanceNoPendingNoCommitted)
    61  	t.Run("Delegation of an amount greater than the available balance for delegation - with pending delegations, no active delegations fails", testDelegateInsufficientBalanceIncludingPendingDelegation)
    62  	t.Run("Delegation of an amount greater than the available balance for delegation - no pending delegations, with active delegations fails", testDelegateInsufficientBalanceIncludingCommitted)
    63  	t.Run("Delegation of an amount greater than the available balance for delegation - with pending delegations and active delegations fails", testDelegateInsufficientBalanceIncludingPendingAndCommitted)
    64  	t.Run("Delegation of an amount greater than the available balance for delegation - with pending undelegations and active delegations fails", testDelegateInsufficientBalanceIncludingPendingUndelegations)
    65  	t.Run("Delegation of an amount less than the available balance for delegation - with no previous active delegation succeeds", testDelegateSuccesNoCommitted)
    66  	t.Run("Delegation of an amount less than the available balance for delegation with previous pending undelegations covered by delegation succeeds", testDelegateSuccessWithPreviousPendingUndelegateFullyCovered)
    67  	t.Run("Delegation of an amount less than the available balance for delegation with previous pending undelegations covered partly by delegation succeeds", testDelegateSuccessWithPreviousPendingUndelegatePartiallyCovered)
    68  	t.Run("Delegation of an amount less than the available balance for delegation with previous pending undelegations countering exactly the undelegated amount succeeds", testDelegateSuccessWithPreviousPendingUndelegateExactlyCovered)
    69  	t.Run("Delegation of an amount fails due to insufficient funds to cover existing committed delegations", testDelegateInsufficientBalanceCoveringExisting)
    70  	t.Run("Delegation of an amount fails due to insufficient funds to cover existing pending delegations", testDelegateInsufficientBalanceCoveringPending)
    71  
    72  	// undelegate tests
    73  	t.Run("Undelegation to an unknown node fails", testUndelegateInvalidNode)
    74  	t.Run("Undelegation more than the delegated balance fails", testUndelegateInvalidAmount)
    75  	t.Run("Undelegate incrememtntally the whole delegated balance succeeds", testUndelegateSuccessNoPreviousPending)
    76  	t.Run("Undelegate incrememtntally with pending exactly covered by undelegate succeeds", testUndelegateSuccessWithPreviousPendingDelegateExactlyCovered)
    77  	t.Run("Undelegate with pending delegated covered partly succeeds", testUndelegateSuccessWithPreviousPendingDelegatePartiallyCovered)
    78  	t.Run("Undelegate with pending delegated fully covered succeeds", testUndelegateSuccessWithPreviousPendingDelegateFullyCovered)
    79  
    80  	// undelegatenow tests
    81  	t.Run("Undelegate now of an amount larger than available fails", testUndelegateNowIncorrectAmount)
    82  	t.Run("Undelegate all with only pending delegation succeeds", testUndelegateNowAllWithPendingOnly)
    83  	t.Run("Undelegate all with only active delegation succeeds", testUndelegateNowAllWithCommittedOnly)
    84  	t.Run("Undelegate all with both active and pending delegation succeeds", testUndelegateNowAll)
    85  	t.Run("Undelegate an amount with pending only delegation succeeds", testUndelegateNowWithPendingOnly)
    86  	t.Run("Undelegate an amount with active only delegation succeeds", testUndelegateNowWithCommittedOnly)
    87  	t.Run("Undelegate an amount with both active and pending delegation - sufficient cover in pending succeeds", testUndelegateNowPendingCovers)
    88  	t.Run("Undelegate an amount with both active and pending delegation - insufficient cover in pending succeeds", testUndelegateNowCommittedCovers)
    89  	t.Run("Undelegate an amount with both active and pending delegation - all delegation removed", testUndelegateNowAllCleared)
    90  	t.Run("Undelegate twice", testUndelegateNowTwice)
    91  
    92  	// test preprocess
    93  	t.Run("preprocess with no forced undelegation needed", testPreprocessForRewardingNoForcedUndelegationNeeded)
    94  	t.Run("preprocess with forced undelegation needed single validator node", testPreprocessForRewardingWithForceUndelegateSingleValidator)
    95  	t.Run("preprocess with forced undelegation needed multiple validator nodes with no remainder", testPreprocessForRewardingWithForceUndelegateMultiValidatorNoRemainder)
    96  	t.Run("preprocess with forced undelegation needed multiple validator nodes with remainder", testPreprocessForRewardingWithForceUndelegateMultiValidatorWithRemainder)
    97  
    98  	// test process pending undelegation
    99  	t.Run("process pending undelegations empty succeeds", testPendingUndelegationEmpty)
   100  	t.Run("process pending undelegations with nothing left to undelegate succeeds", testPendingUndelegationNothingToUndelegate)
   101  	t.Run("process pending undelegations with more than the delegated balance succeeds", testPendingUndelegationGTDelegateddBalance)
   102  	t.Run("process pending undelegations with less than the delegated succeeds", testPendingUndelegationLTDelegateddBalance)
   103  	t.Run("process pending undelegations undeledate everything for a party succeeds", testPendingUndelegationAllBalanceForParty)
   104  	t.Run("process pending undelegations undeledate everything for a node succeeds", testPendingUndelegationAllBalanceForNode)
   105  
   106  	// test process pending delegation
   107  	t.Run("process pending delegations empty succeeds", testPendingDelegationEmpty)
   108  	t.Run("process pending delegations with insufficient staking account balance ignored", testPendingDelegationInsufficientBalance)
   109  	t.Run("process pending delegations no adjustment", testPendingDelegationSuccess)
   110  
   111  	// test process pending
   112  	t.Run("process pending is delegating and undelegating and clearing the pending state successfully", testProcessPending)
   113  
   114  	// test get validators
   115  	t.Run("get empty list of validators succeeds", testGetValidatorsEmpty)
   116  	t.Run("get list of validators succeeds", testGetValidatorsSuccess)
   117  	t.Run("setup delegation with self and parties", testGetValidatorsSuccessWithSelfDelegation)
   118  
   119  	// test auto delegation
   120  	t.Run("a party having all of their stake delegated get into auto delegation successfully", testCheckPartyEnteringAutoDelegation)
   121  	t.Run("a party is in auto delegation mode which gets cancelled by manually undelegating at the end of an epoch", testCheckPartyExitingAutoDelegationThroughUndelegateEOE)
   122  	t.Run("a party is in auto delegation mode which gets cancelled by manually undelegating during an epoch", testCheckPartyExitingAutoDelegationThroughUndelegateNow)
   123  	t.Run("auto delegation interrupted by manual delegations", testPartyInAutoDelegateModeWithManualIntervention)
   124  	// test checkpoints
   125  	t.Run("sorting consistently active delegations for checkpoint", testSortActive)
   126  	t.Run("test roundtrip of checkpoint calculation with no pending delegations", testCheckpointRoundTripNoPending)
   127  	t.Run("test roundtrip of checkpoint calculation with no active delegations", testCheckpointRoundTripOnlyPending)
   128  
   129  	// test snapshots
   130  	t.Run("test roundtrip snapshot for active delegations", testActiveSnapshotRoundTrip)
   131  	t.Run("test roundtrip snapshot for pending delegations", testPendingSnapshotRoundTrip)
   132  	t.Run("test roundtrip snapshot for auto delegations", testAutoSnapshotRoundTrip)
   133  	t.Run("test roundtrip snapshot for last reconciliation time delegations", testLastReconTimeRoundTrip)
   134  }
   135  
   136  func TestSnapshotRoundTripViaEngine(t *testing.T) {
   137  	delegationEngine1 := getEngine(t)
   138  	delegationEngine1.broker.EXPECT().SendBatch(gomock.Any()).AnyTimes()
   139  	setupDefaultDelegationState(delegationEngine1, 10, 5)
   140  	now := delegationEngine1.engine.lastReconciliation.Add(30 * time.Second)
   141  	delegationEngine1.engine.OnTick(context.Background(), now)
   142  	delegationEngine1.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 0})
   143  
   144  	ctx := vgtest.VegaContext("chainid", 100)
   145  
   146  	vegaPath := paths.New(t.TempDir())
   147  	log := logging.NewTestLogger()
   148  	timeService := stubs.NewTimeStub()
   149  	timeService.SetTime(now)
   150  	statsData := stats.New(log, stats.NewDefaultConfig())
   151  	config := snp.DefaultConfig()
   152  	snapshotEngine1, err := snp.NewEngine(vegaPath, config, log, timeService, statsData.Blockchain)
   153  	require.NoError(t, err)
   154  	snapshotEngine1CloseFn := vgtest.OnlyOnce(snapshotEngine1.Close)
   155  	defer snapshotEngine1CloseFn()
   156  
   157  	snapshotEngine1.AddProviders(delegationEngine1.engine)
   158  
   159  	require.NoError(t, snapshotEngine1.Start(ctx))
   160  
   161  	hash1, err := snapshotEngine1.SnapshotNow(ctx)
   162  	require.NoError(t, err)
   163  
   164  	delegationEngine1.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 1})
   165  	require.NoError(t, delegationEngine1.engine.UndelegateNow(context.Background(), "party1", "node1", num.NewUint(3)))
   166  	require.NoError(t, delegationEngine1.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(2)))
   167  
   168  	delegationEngine1.engine.OnTick(context.Background(), now.Add(30*time.Second))
   169  
   170  	state1 := map[string][]byte{}
   171  	for _, key := range delegationEngine1.engine.Keys() {
   172  		state, additionalProvider, err := delegationEngine1.engine.GetState(key)
   173  		require.NoError(t, err)
   174  		assert.Empty(t, additionalProvider)
   175  		state1[key] = state
   176  	}
   177  
   178  	snapshotEngine1CloseFn()
   179  
   180  	delegationEngine2 := getEngine(t)
   181  	delegationEngine2.broker.EXPECT().SendBatch(gomock.Any()).AnyTimes()
   182  	snapshotEngine2, err := snp.NewEngine(vegaPath, config, log, timeService, statsData.Blockchain)
   183  	require.NoError(t, err)
   184  	defer snapshotEngine2.Close()
   185  
   186  	snapshotEngine2.AddProviders(delegationEngine2.engine)
   187  
   188  	// This triggers the state restoration from the local snapshot.
   189  	require.NoError(t, snapshotEngine2.Start(ctx))
   190  
   191  	// Comparing the hash after restoration, to ensure it produces the same result.
   192  	hash2, _, _ := snapshotEngine2.Info()
   193  	require.Equal(t, hash1, hash2)
   194  
   195  	delegationEngine2.topology.nodeToIsValidator["node1"] = true
   196  	delegationEngine2.topology.nodeToIsValidator["node2"] = true
   197  	delegationEngine2.stakingAccounts.partyToStake["party1"] = delegationEngine1.stakingAccounts.partyToStake["party1"]
   198  	delegationEngine2.stakingAccounts.partyToStake["party2"] = delegationEngine1.stakingAccounts.partyToStake["party2"]
   199  
   200  	delegationEngine2.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 1})
   201  	require.NoError(t, delegationEngine2.engine.UndelegateNow(context.Background(), "party1", "node1", num.NewUint(3)))
   202  	require.NoError(t, delegationEngine2.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(2)))
   203  
   204  	delegationEngine2.engine.OnTick(context.Background(), now.Add(30*time.Second))
   205  
   206  	state2 := map[string][]byte{}
   207  	for _, key := range delegationEngine2.engine.Keys() {
   208  		state, additionalProvider, err := delegationEngine2.engine.GetState(key)
   209  		require.NoError(t, err)
   210  		assert.Empty(t, additionalProvider)
   211  		state2[key] = state
   212  	}
   213  
   214  	for key := range state1 {
   215  		assert.Equalf(t, state1[key], state2[key], "Key %q does not have the same data", key)
   216  	}
   217  }
   218  
   219  func testLastReconTimeRoundTrip(t *testing.T) {
   220  	testEngine := getEngine(t)
   221  	setupDefaultDelegationState(testEngine, 14, 7)
   222  
   223  	// get the serialised state
   224  	state, _, err := testEngine.engine.GetState(lastReconKey)
   225  	require.Nil(t, err)
   226  
   227  	// verify state is consistent in the absence of change
   228  	stateNoChange, _, err := testEngine.engine.GetState(lastReconKey)
   229  	require.Nil(t, err)
   230  	require.True(t, bytes.Equal(state, stateNoChange))
   231  
   232  	// advance 30 seconds
   233  	testEngine.engine.OnTick(context.Background(), testEngine.engine.lastReconciliation.Add(30*time.Second))
   234  	stateChanged, _, err := testEngine.engine.GetState(lastReconKey)
   235  	require.Nil(t, err)
   236  	require.False(t, bytes.Equal(state, stateChanged))
   237  
   238  	newEngine := getEngine(t)
   239  	var lastRecon snapshot.Payload
   240  	proto.Unmarshal(stateChanged, &lastRecon)
   241  	payload := types.PayloadFromProto(&lastRecon)
   242  
   243  	_, err = newEngine.engine.LoadState(context.Background(), payload)
   244  	require.Nil(t, err)
   245  
   246  	reloadedState, _, err := newEngine.engine.GetState(lastReconKey)
   247  	require.Nil(t, err)
   248  	require.True(t, bytes.Equal(reloadedState, stateChanged))
   249  }
   250  
   251  // test round trip of active snapshot serialisation.
   252  func testActiveSnapshotRoundTrip(t *testing.T) {
   253  	ctx := context.Background()
   254  	testEngine := getEngine(t)
   255  	setupDefaultDelegationState(testEngine, 14, 7)
   256  
   257  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 0})
   258  
   259  	// Move ahead a bit further
   260  	testEngine.engine.onEpochEvent(context.Background(), types.Epoch{Seq: 2, StartTime: time.Now()})
   261  
   262  	// get the serialised state
   263  	state, _, err := testEngine.engine.GetState(activeKey)
   264  	require.Nil(t, err)
   265  
   266  	// verify state is consistent in the absence of change
   267  	stateNoChange, _, err := testEngine.engine.GetState(activeKey)
   268  	require.Nil(t, err)
   269  	require.True(t, bytes.Equal(state, stateNoChange))
   270  
   271  	// reload the state
   272  	var active snapshot.Payload
   273  	proto.Unmarshal(state, &active)
   274  	payload := types.PayloadFromProto(&active)
   275  
   276  	// make a fresh engine
   277  	snapEngine := getEngine(t)
   278  	setupDefaultDelegationState(snapEngine, 14, 7)
   279  	snapEngine.broker.EXPECT().SendBatch(gomock.Any()).Times(1)
   280  	snapEngine.engine.LoadState(ctx, payload)
   281  
   282  	// signal loading of the epoch
   283  	snapEngine.engine.onEpochRestore(ctx, types.Epoch{Seq: 2})
   284  
   285  	// verify state match
   286  	statePostReload, _, _ := snapEngine.engine.GetState(activeKey)
   287  	require.True(t, bytes.Equal(state, statePostReload))
   288  }
   289  
   290  // test round trip of pending snapshot serialisation.
   291  func testPendingSnapshotRoundTrip(t *testing.T) {
   292  	testEngine := getEngine(t)
   293  	setupDefaultDelegationState(testEngine, 20, 7)
   294  
   295  	// setup pending delegations
   296  	testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(2))
   297  	testEngine.engine.Delegate(context.Background(), "party1", "node2", num.NewUint(3))
   298  	testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party2", "node1", num.NewUint(1))
   299  
   300  	// get the serialised state
   301  	state, _, err := testEngine.engine.GetState(pendingKey)
   302  	require.Nil(t, err)
   303  
   304  	// verify state is consistent in the absence of change
   305  	stateNoChange, _, err := testEngine.engine.GetState(pendingKey)
   306  	require.Nil(t, err)
   307  	require.True(t, bytes.Equal(state, stateNoChange))
   308  
   309  	// reload the state
   310  	var pending snapshot.Payload
   311  	proto.Unmarshal(state, &pending)
   312  	payload := types.PayloadFromProto(&pending)
   313  	testEngine.broker.EXPECT().SendBatch(gomock.Any()).Times(1)
   314  	_, err = testEngine.engine.LoadState(context.Background(), payload)
   315  	require.Nil(t, err)
   316  	statePostReload, _, _ := testEngine.engine.GetState(pendingKey)
   317  	require.True(t, bytes.Equal(state, statePostReload))
   318  }
   319  
   320  // test round trip of auto snapshot serialisation.
   321  func testAutoSnapshotRoundTrip(t *testing.T) {
   322  	testEngine := getEngine(t)
   323  	setupDefaultDelegationState(testEngine, 10, 5)
   324  
   325  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 0})
   326  
   327  	// by now, auto delegation should be set for both party1 and party2 as all of their association is nominated
   328  	state, _, err := testEngine.engine.GetState(autoKey)
   329  	require.Nil(t, err)
   330  
   331  	// verify state is consistent in the absence of change
   332  	stateNoChange, _, err := testEngine.engine.GetState(autoKey)
   333  	require.Nil(t, err)
   334  	require.True(t, bytes.Equal(state, stateNoChange))
   335  
   336  	// undelegate now to get out of auto for party1 to verify state changed
   337  	testEngine.engine.UndelegateNow(context.Background(), "party1", "node1", num.NewUint(3))
   338  	statePostUndelegate, _, err := testEngine.engine.GetState(autoKey)
   339  	require.Nil(t, err)
   340  	require.False(t, bytes.Equal(state, statePostUndelegate))
   341  
   342  	// reload the state
   343  	var auto snapshot.Payload
   344  	proto.Unmarshal(statePostUndelegate, &auto)
   345  	payload := types.PayloadFromProto(&auto)
   346  
   347  	_, err = testEngine.engine.LoadState(context.Background(), payload)
   348  	require.NoError(t, err)
   349  	statePostReload, _, _ := testEngine.engine.GetState(autoKey)
   350  	require.True(t, bytes.Equal(statePostUndelegate, statePostReload))
   351  }
   352  
   353  // pass an invalid node id
   354  // expect an ErrInvalidNodeID.
   355  func testDelegateInvalidNode(t *testing.T) {
   356  	testEngine := getEngine(t)
   357  	err := testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(10))
   358  	assert.EqualError(t, err, ErrInvalidNodeID.Error())
   359  }
   360  
   361  // pass a party with no staking account
   362  // expect ErrPartyHasNoStakingAccount.
   363  func testDelegateNoStakingAccount(t *testing.T) {
   364  	testEngine := getEngine(t)
   365  	testEngine.topology.nodeToIsValidator["node1"] = true
   366  	err := testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(10))
   367  	assert.EqualError(t, err, ErrPartyHasNoStakingAccount.Error())
   368  }
   369  
   370  // try to delegate less than the network param for min delegation amount
   371  // expect ErrAmountLTMinAmountForDelegation.
   372  func testDelegateLessThanMinDelegationAmount(t *testing.T) {
   373  	testEngine := getEngine(t)
   374  	testEngine.topology.nodeToIsValidator["node1"] = true
   375  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(5)
   376  	err := testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(1))
   377  	assert.EqualError(t, err, ErrAmountLTMinAmountForDelegation.Error())
   378  }
   379  
   380  // party has insufficient balance in their staking account to delegate - they have nothing pending and no committed delegation
   381  // expect ErrInsufficientBalanceForDelegation.
   382  func testDelegateInsufficientBalanceNoPendingNoCommitted(t *testing.T) {
   383  	testEngine := getEngine(t)
   384  	testEngine.topology.nodeToIsValidator["node1"] = true
   385  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(5)
   386  	err := testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(10))
   387  	assert.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   388  }
   389  
   390  func testDelegateInsufficientBalanceCoveringExisting(t *testing.T) {
   391  	// setup committed delegated state
   392  	testEngine := getEngine(t)
   393  	setupDefaultDelegationState(testEngine, 12, 7)
   394  
   395  	// party1 has delegation of 10 by now
   396  	// party1 withraws from their staking account
   397  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(5)
   398  
   399  	// now they don't have enough cover to their active delegations
   400  	// trying to delegate the min amount should error with insufficient balance
   401  	err := testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(2))
   402  
   403  	assert.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   404  }
   405  
   406  func testDelegateInsufficientBalanceCoveringPending(t *testing.T) {
   407  	// setup committed delegated state
   408  	testEngine := getEngine(t)
   409  	testEngine.topology.nodeToIsValidator["node1"] = true
   410  	testEngine.topology.nodeToIsValidator["node2"] = true
   411  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(10)
   412  
   413  	err := testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(5))
   414  	require.Nil(t, err)
   415  	err = testEngine.engine.Delegate(context.Background(), "party1", "node2", num.NewUint(5))
   416  	require.Nil(t, err)
   417  
   418  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node2", num.NewUint(2))
   419  	require.Nil(t, err)
   420  
   421  	// so party1 has 8 pending delegations in total and they withdraw 5 from their staking account
   422  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(5)
   423  
   424  	// trying to delegate min amount should error with insufficient balance
   425  	err = testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(2))
   426  	assert.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   427  
   428  	err = testEngine.engine.Delegate(context.Background(), "party1", "node2", num.NewUint(2))
   429  	assert.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   430  }
   431  
   432  // party has pending delegations and is trying to exceed their stake account balance delegation, i.e. the balance of their pending delegation + requested delegation exceeds stake account balance.
   433  func testDelegateInsufficientBalanceIncludingPendingDelegation(t *testing.T) {
   434  	// setup committed delegated state
   435  	testEngine := getEngine(t)
   436  	testEngine.topology.nodeToIsValidator["node1"] = true
   437  	testEngine.topology.nodeToIsValidator["node2"] = true
   438  
   439  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(10)
   440  	testEngine.stakingAccounts.partyToStake["party2"] = num.NewUint(7)
   441  
   442  	// setup pending
   443  	err := testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(5))
   444  	require.Nil(t, err)
   445  
   446  	err = testEngine.engine.Delegate(context.Background(), "party1", "node2", num.NewUint(3))
   447  	require.Nil(t, err)
   448  
   449  	err = testEngine.engine.Delegate(context.Background(), "party2", "node1", num.NewUint(6))
   450  	require.Nil(t, err)
   451  
   452  	err = testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(2))
   453  	require.Nil(t, err)
   454  
   455  	// by this point party1 has delegated 10 and party2 has delegate 6 which means party1 cannot delegage anything anymore and party2 can deleagate no more than 1
   456  	err = testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(2))
   457  	assert.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   458  
   459  	err = testEngine.engine.Delegate(context.Background(), "party1", "node2", num.NewUint(2))
   460  	assert.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   461  
   462  	err = testEngine.engine.Delegate(context.Background(), "party2", "node1", num.NewUint(2))
   463  	assert.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   464  
   465  	err = testEngine.engine.Delegate(context.Background(), "party2", "node2", num.NewUint(2))
   466  	assert.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   467  }
   468  
   469  // setup committed deletations (delegations in effect in current epoch):
   470  // node1 -> 8
   471  //
   472  //	    party1 -> 6
   473  //		party2 -> 2
   474  //
   475  // node 2 -> 7
   476  //
   477  //	party1 -> 4
   478  //	party2 -> 3
   479  func setupDefaultDelegationState(testEngine *testEngine, party1Balance uint64, party2Balance uint64) {
   480  	testEngine.topology.nodeToIsValidator["node1"] = true
   481  	testEngine.topology.nodeToIsValidator["node2"] = true
   482  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(party1Balance)
   483  	testEngine.stakingAccounts.partyToStake["party2"] = num.NewUint(party2Balance)
   484  
   485  	engine := testEngine.engine
   486  
   487  	engine.partyDelegationState["party1"] = &partyDelegation{
   488  		party:          "party1",
   489  		totalDelegated: num.NewUint(10),
   490  		nodeToAmount:   make(map[string]*num.Uint),
   491  	}
   492  	engine.nextPartyDelegationState["party1"] = &partyDelegation{
   493  		party:          "party1",
   494  		totalDelegated: num.NewUint(10),
   495  		nodeToAmount:   make(map[string]*num.Uint),
   496  	}
   497  
   498  	engine.partyDelegationState["party1"].nodeToAmount["node1"] = num.NewUint(6)
   499  	engine.partyDelegationState["party1"].nodeToAmount["node2"] = num.NewUint(4)
   500  	engine.nextPartyDelegationState["party1"].nodeToAmount["node1"] = num.NewUint(6)
   501  	engine.nextPartyDelegationState["party1"].nodeToAmount["node2"] = num.NewUint(4)
   502  
   503  	engine.partyDelegationState["party2"] = &partyDelegation{
   504  		party:          "party2",
   505  		totalDelegated: num.NewUint(5),
   506  		nodeToAmount:   make(map[string]*num.Uint),
   507  	}
   508  	engine.nextPartyDelegationState["party2"] = &partyDelegation{
   509  		party:          "party2",
   510  		totalDelegated: num.NewUint(5),
   511  		nodeToAmount:   make(map[string]*num.Uint),
   512  	}
   513  	engine.partyDelegationState["party2"].nodeToAmount["node1"] = num.NewUint(2)
   514  	engine.nextPartyDelegationState["party2"].nodeToAmount["node1"] = num.NewUint(2)
   515  	engine.partyDelegationState["party2"].nodeToAmount["node2"] = num.NewUint(3)
   516  	engine.nextPartyDelegationState["party2"].nodeToAmount["node2"] = num.NewUint(3)
   517  }
   518  
   519  // setup committed deletations (delegations in effect in current epoch):
   520  // node1 -> 6
   521  //
   522  //	party1 -> 6
   523  //
   524  // node 2 -> 3
   525  //
   526  //	party2 -> 3
   527  func defaultSimpleDelegationState(testEngine *testEngine) {
   528  	testEngine.topology.nodeToIsValidator["node1"] = true
   529  	testEngine.topology.nodeToIsValidator["node2"] = true
   530  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(12)
   531  	testEngine.stakingAccounts.partyToStake["party2"] = num.NewUint(7)
   532  
   533  	engine := testEngine.engine
   534  	engine.partyDelegationState["party1"] = &partyDelegation{
   535  		party:          "party1",
   536  		totalDelegated: num.NewUint(6),
   537  		nodeToAmount:   make(map[string]*num.Uint),
   538  	}
   539  	engine.nextPartyDelegationState["party1"] = &partyDelegation{
   540  		party:          "party1",
   541  		totalDelegated: num.NewUint(6),
   542  		nodeToAmount:   make(map[string]*num.Uint),
   543  	}
   544  	engine.partyDelegationState["party1"].nodeToAmount["node1"] = num.NewUint(6)
   545  	engine.nextPartyDelegationState["party1"].nodeToAmount["node1"] = num.NewUint(6)
   546  
   547  	engine.partyDelegationState["party2"] = &partyDelegation{
   548  		party:          "party2",
   549  		totalDelegated: num.NewUint(3),
   550  		nodeToAmount:   make(map[string]*num.Uint),
   551  	}
   552  	engine.nextPartyDelegationState["party2"] = &partyDelegation{
   553  		party:          "party2",
   554  		totalDelegated: num.NewUint(3),
   555  		nodeToAmount:   make(map[string]*num.Uint),
   556  	}
   557  	engine.partyDelegationState["party2"].nodeToAmount["node2"] = num.NewUint(3)
   558  	engine.nextPartyDelegationState["party2"].nodeToAmount["node2"] = num.NewUint(3)
   559  }
   560  
   561  // party has committed delegations and is trying to exceed their stake account balance delegations i.e. the balance of their pending delegation + requested delegation exceeds stake account balance.
   562  func testDelegateInsufficientBalanceIncludingCommitted(t *testing.T) {
   563  	testEngine := getEngine(t)
   564  	setupDefaultDelegationState(testEngine, 10, 7)
   565  
   566  	// by this point party1 has 10 tokens delegated which means they can't delegate anything more
   567  	err := testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(2))
   568  	require.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   569  
   570  	err = testEngine.engine.Delegate(context.Background(), "party1", "node2", num.NewUint(2))
   571  	require.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   572  
   573  	// by this point party2 has 5 tokens delegated which means they can delegate 2 more
   574  	err = testEngine.engine.Delegate(context.Background(), "party2", "node1", num.NewUint(3))
   575  	require.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   576  
   577  	err = testEngine.engine.Delegate(context.Background(), "party2", "node2", num.NewUint(3))
   578  	require.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   579  }
   580  
   581  // party has both committed delegations and pending delegations and an additional delegation will exceed the amount of available tokens for delegations in their staking account.
   582  func testDelegateInsufficientBalanceIncludingPendingAndCommitted(t *testing.T) {
   583  	// setup committed delegated state
   584  	testEngine := getEngine(t)
   585  	setupDefaultDelegationState(testEngine, 12, 7)
   586  
   587  	// setup pending
   588  	// by this point party1 has 10 tokens delegated which means they can delegate 2 more
   589  	err := testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(2))
   590  	require.Nil(t, err)
   591  
   592  	// by this point party2 has 5 tokens delegated which means they can delegate 2 more
   593  	err = testEngine.engine.Delegate(context.Background(), "party2", "node1", num.NewUint(2))
   594  	require.Nil(t, err)
   595  
   596  	// both parties maxed out their delegation balance
   597  	err = testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(2))
   598  	require.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   599  
   600  	err = testEngine.engine.Delegate(context.Background(), "party1", "node2", num.NewUint(2))
   601  	require.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   602  
   603  	err = testEngine.engine.Delegate(context.Background(), "party2", "node1", num.NewUint(2))
   604  	require.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   605  
   606  	err = testEngine.engine.Delegate(context.Background(), "party2", "node2", num.NewUint(2))
   607  	require.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   608  }
   609  
   610  // party has both committed delegations and pending undelegations.
   611  func testDelegateInsufficientBalanceIncludingPendingUndelegations(t *testing.T) {
   612  	// setup committed delegated state
   613  	testEngine := getEngine(t)
   614  	setupDefaultDelegationState(testEngine, 12, 7)
   615  
   616  	// setup pending
   617  	// by this point party1 has 10 tokens delegated which means they can delegate 2 more - with the undelegation they can delegate 4
   618  	err := testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(2))
   619  	require.Nil(t, err)
   620  
   621  	// by this point party2 has 5 tokens delegated which means they can delegate 2 more - with undelegation they can delegate 4
   622  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party2", "node1", num.NewUint(2))
   623  	require.Nil(t, err)
   624  
   625  	// try to delegate 1 more than available balance for delegation should fall
   626  	err = testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(5))
   627  	require.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   628  
   629  	err = testEngine.engine.Delegate(context.Background(), "party1", "node2", num.NewUint(5))
   630  	require.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   631  
   632  	err = testEngine.engine.Delegate(context.Background(), "party2", "node1", num.NewUint(5))
   633  	require.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   634  
   635  	err = testEngine.engine.Delegate(context.Background(), "party2", "node2", num.NewUint(5))
   636  	require.EqualError(t, err, ErrInsufficientBalanceForDelegation.Error())
   637  
   638  	// now delegate exacatly the balance available for delegation for success
   639  	err = testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(2))
   640  	require.Nil(t, err)
   641  
   642  	err = testEngine.engine.Delegate(context.Background(), "party1", "node2", num.NewUint(2))
   643  	require.Nil(t, err)
   644  
   645  	err = testEngine.engine.Delegate(context.Background(), "party2", "node1", num.NewUint(2))
   646  	require.Nil(t, err)
   647  
   648  	err = testEngine.engine.Delegate(context.Background(), "party2", "node2", num.NewUint(2))
   649  	require.Nil(t, err)
   650  }
   651  
   652  // balance available for delegation is greater than delegation amount, delegation succeeds.
   653  func testDelegateSuccesNoCommitted(t *testing.T) {
   654  	testEngine := getEngine(t)
   655  	testEngine.topology.nodeToIsValidator["node1"] = true
   656  	testEngine.topology.nodeToIsValidator["node2"] = true
   657  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(10)
   658  	testEngine.stakingAccounts.partyToStake["party2"] = num.NewUint(7)
   659  
   660  	err := testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(5))
   661  	require.Nil(t, err)
   662  
   663  	err = testEngine.engine.Delegate(context.Background(), "party1", "node2", num.NewUint(3))
   664  	require.Nil(t, err)
   665  
   666  	err = testEngine.engine.Delegate(context.Background(), "party2", "node1", num.NewUint(6))
   667  	require.Nil(t, err)
   668  
   669  	err = testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(2))
   670  	require.Nil(t, err)
   671  
   672  	// summary:
   673  	// party1 delegated 10 in total, 7 to node1 and 3 to node2
   674  	// party2 delegated 6 in total, all to node1
   675  	// verify the state
   676  
   677  	nextEpoch := testEngine.engine.nextPartyDelegationState
   678  	require.Equal(t, 2, len(nextEpoch))
   679  	require.Equal(t, num.NewUint(10), nextEpoch["party1"].totalDelegated)
   680  	require.Equal(t, num.NewUint(6), nextEpoch["party2"].totalDelegated)
   681  	require.Equal(t, num.NewUint(7), nextEpoch["party1"].nodeToAmount["node1"])
   682  	require.Equal(t, num.NewUint(3), nextEpoch["party1"].nodeToAmount["node2"])
   683  	require.Equal(t, num.NewUint(6), nextEpoch["party2"].nodeToAmount["node1"])
   684  	require.Equal(t, 2, len(nextEpoch["party1"].nodeToAmount))
   685  	require.Equal(t, 1, len(nextEpoch["party2"].nodeToAmount))
   686  	require.Equal(t, 0, len(testEngine.engine.partyDelegationState))
   687  }
   688  
   689  // test delegation when there is already pending undelegation but the deletation is more than fully covering the pending undelegation.
   690  func testDelegateSuccessWithPreviousPendingUndelegateFullyCovered(t *testing.T) {
   691  	// setup committed delegated state
   692  	testEngine := getEngine(t)
   693  	defaultSimpleDelegationState(testEngine)
   694  
   695  	// setup pending undelegation
   696  	err := testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(2))
   697  	require.Nil(t, err)
   698  
   699  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party2", "node2", num.NewUint(2))
   700  	require.Nil(t, err)
   701  
   702  	// show that the state before delegation matches expectation (i.e. that we have 2 for undelegation from party1 and party2 to node1 and node2 respectively)
   703  	nextEpoch := testEngine.engine.nextPartyDelegationState
   704  	require.Equal(t, num.NewUint(4), nextEpoch["party1"].totalDelegated)
   705  	require.Equal(t, num.NewUint(1), nextEpoch["party2"].totalDelegated)
   706  	require.Equal(t, num.NewUint(4), nextEpoch["party1"].nodeToAmount["node1"])
   707  	require.Equal(t, num.NewUint(1), nextEpoch["party2"].nodeToAmount["node2"])
   708  	require.Equal(t, 2, len(nextEpoch))
   709  
   710  	// delegte 4 from party 1 to node 1
   711  	err = testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(4))
   712  	require.Nil(t, err)
   713  
   714  	// delegate 5 from party 2 to node2
   715  	err = testEngine.engine.Delegate(context.Background(), "party2", "node2", num.NewUint(5))
   716  	require.Nil(t, err)
   717  
   718  	// summary:
   719  	// verify the state
   720  	require.Equal(t, num.NewUint(8), nextEpoch["party1"].totalDelegated)
   721  	require.Equal(t, num.NewUint(6), nextEpoch["party2"].totalDelegated)
   722  	require.Equal(t, num.NewUint(8), nextEpoch["party1"].nodeToAmount["node1"])
   723  	require.Equal(t, num.NewUint(6), nextEpoch["party2"].nodeToAmount["node2"])
   724  	require.Equal(t, 2, len(nextEpoch))
   725  }
   726  
   727  // test delegation when there is already pending undelegation and the delegation is covering part of the undelegation.
   728  func testDelegateSuccessWithPreviousPendingUndelegatePartiallyCovered(t *testing.T) {
   729  	// setup committed delegated state
   730  	testEngine := getEngine(t)
   731  	defaultSimpleDelegationState(testEngine)
   732  
   733  	// setup pending undelegation
   734  	err := testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(4))
   735  	require.Nil(t, err)
   736  
   737  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party2", "node2", num.NewUint(3))
   738  	require.Nil(t, err)
   739  
   740  	// show that the state before delegation matches expectation (i.e. that we have 2 for undelegation from party1 and party2 to node1 and node2 respectively)
   741  	nextEpoch := testEngine.engine.nextPartyDelegationState
   742  	require.Equal(t, num.NewUint(2), nextEpoch["party1"].totalDelegated)
   743  	require.Equal(t, num.NewUint(2), nextEpoch["party1"].nodeToAmount["node1"])
   744  	require.Equal(t, 1, len(nextEpoch))
   745  
   746  	// delegte 3 (< the pending undelegation of 4) from party 1 to node 1
   747  	err = testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(3))
   748  	require.Nil(t, err)
   749  
   750  	// delegate 2 (< the pending undelegation of 3) from party 2 to node2
   751  	err = testEngine.engine.Delegate(context.Background(), "party2", "node2", num.NewUint(2))
   752  	require.Nil(t, err)
   753  
   754  	// verify the state
   755  	require.Equal(t, num.NewUint(5), nextEpoch["party1"].totalDelegated)
   756  	require.Equal(t, num.NewUint(2), nextEpoch["party2"].totalDelegated)
   757  	require.Equal(t, num.NewUint(5), nextEpoch["party1"].nodeToAmount["node1"])
   758  	require.Equal(t, num.NewUint(2), nextEpoch["party2"].nodeToAmount["node2"])
   759  	require.Equal(t, 2, len(nextEpoch))
   760  }
   761  
   762  // test delegation when there is already pending undelegation and the delegation is countering exactly the undelegation.
   763  func testDelegateSuccessWithPreviousPendingUndelegateExactlyCovered(t *testing.T) {
   764  	// setup committed delegated state
   765  	testEngine := getEngine(t)
   766  	defaultSimpleDelegationState(testEngine)
   767  
   768  	// setup pending undelegation
   769  	err := testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(4))
   770  	require.Nil(t, err)
   771  
   772  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party2", "node2", num.NewUint(3))
   773  	require.Nil(t, err)
   774  
   775  	nextEpoch := testEngine.engine.nextPartyDelegationState
   776  	// show that the state before delegation matches expectation (i.e. that we have 2 for undelegation from party1 and party2 to node1 and node2 respectively)
   777  	require.Equal(t, num.NewUint(2), nextEpoch["party1"].totalDelegated)
   778  	require.Equal(t, num.NewUint(2), nextEpoch["party1"].nodeToAmount["node1"])
   779  	require.Equal(t, 1, len(nextEpoch))
   780  
   781  	// delegte 4 (= the pending undelegation of 4) from party 1 to node 1
   782  	err = testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(4))
   783  	require.Nil(t, err)
   784  
   785  	// delegate 3 (= the pending undelegation of 3) from party 2 to node2
   786  	err = testEngine.engine.Delegate(context.Background(), "party2", "node2", num.NewUint(3))
   787  	require.Nil(t, err)
   788  
   789  	// verify the state
   790  	// as we've countered all undelegation we expect the pending state to be empty
   791  	require.Equal(t, num.NewUint(6), nextEpoch["party1"].totalDelegated)
   792  	require.Equal(t, num.NewUint(3), nextEpoch["party2"].totalDelegated)
   793  	require.Equal(t, num.NewUint(6), nextEpoch["party1"].nodeToAmount["node1"])
   794  	require.Equal(t, num.NewUint(3), nextEpoch["party2"].nodeToAmount["node2"])
   795  	require.Equal(t, 2, len(nextEpoch))
   796  }
   797  
   798  // / undelegate.
   799  func testUndelegateInvalidNode(t *testing.T) {
   800  	testEngine := getEngine(t)
   801  	err := testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(10))
   802  	assert.EqualError(t, err, ErrInvalidNodeID.Error())
   803  }
   804  
   805  // trying to undelegate more than the delegated amount when no undelegation or more than the delegated - undelegated if there are some.
   806  func testUndelegateInvalidAmount(t *testing.T) {
   807  	testEngine := getEngine(t)
   808  	testEngine.topology.nodeToIsValidator["node1"] = true
   809  	testEngine.topology.nodeToIsValidator["node2"] = true
   810  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(10)
   811  	testEngine.stakingAccounts.partyToStake["party2"] = num.NewUint(7)
   812  
   813  	// first try undelegate with no delegation at all
   814  	err := testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(10))
   815  	assert.Error(t, err, ErrIncorrectTokenAmountForUndelegation)
   816  
   817  	// now delegate some token to node1 and try to undelegate more than the balance
   818  	err = testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(5))
   819  	assert.Nil(t, err)
   820  
   821  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(6))
   822  	assert.Error(t, err, ErrIncorrectTokenAmountForUndelegation)
   823  }
   824  
   825  // trying to undelegate then incresae the undelegated amount until all is undelegated.
   826  func testUndelegateSuccessNoPreviousPending(t *testing.T) {
   827  	// setup committed delegated state
   828  	testEngine := getEngine(t)
   829  	defaultSimpleDelegationState(testEngine)
   830  
   831  	// setup pending undelegation
   832  	err := testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(2))
   833  	require.Nil(t, err)
   834  
   835  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party2", "node2", num.NewUint(2))
   836  	require.Nil(t, err)
   837  
   838  	nextEpoch := testEngine.engine.nextPartyDelegationState
   839  	require.Equal(t, num.NewUint(4), nextEpoch["party1"].totalDelegated)
   840  	require.Equal(t, num.NewUint(1), nextEpoch["party2"].totalDelegated)
   841  	require.Equal(t, num.NewUint(4), nextEpoch["party1"].nodeToAmount["node1"])
   842  	require.Equal(t, num.NewUint(1), nextEpoch["party2"].nodeToAmount["node2"])
   843  	require.Equal(t, 2, len(nextEpoch))
   844  
   845  	// undelegate everything now
   846  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(4))
   847  	require.Nil(t, err)
   848  
   849  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party2", "node2", num.NewUint(1))
   850  	require.Nil(t, err)
   851  
   852  	// check that the state has updated correctly
   853  	require.Equal(t, 0, len(nextEpoch))
   854  
   855  	// trying to further undelegate will get an error
   856  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(1))
   857  	assert.Error(t, err, ErrIncorrectTokenAmountForUndelegation)
   858  
   859  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party2", "node2", num.NewUint(1))
   860  	assert.Error(t, err, ErrIncorrectTokenAmountForUndelegation)
   861  }
   862  
   863  // delegate an amount that leave some delegation for the party.
   864  func testUndelegateSuccessWithPreviousPendingDelegatePartiallyCovered(t *testing.T) {
   865  	// setup committed delegated state
   866  	testEngine := getEngine(t)
   867  	testEngine.topology.nodeToIsValidator["node1"] = true
   868  	testEngine.topology.nodeToIsValidator["node2"] = true
   869  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(12)
   870  	testEngine.stakingAccounts.partyToStake["party2"] = num.NewUint(7)
   871  
   872  	err := testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(10))
   873  	require.Nil(t, err)
   874  	err = testEngine.engine.Delegate(context.Background(), "party1", "node2", num.NewUint(2))
   875  	require.Nil(t, err)
   876  	err = testEngine.engine.Delegate(context.Background(), "party2", "node1", num.NewUint(4))
   877  	require.Nil(t, err)
   878  	err = testEngine.engine.Delegate(context.Background(), "party2", "node2", num.NewUint(3))
   879  	require.Nil(t, err)
   880  
   881  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(6))
   882  	require.Nil(t, err)
   883  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(4))
   884  	require.Nil(t, err)
   885  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party2", "node1", num.NewUint(4))
   886  	require.Nil(t, err)
   887  
   888  	nextEpoch := testEngine.engine.nextPartyDelegationState
   889  	require.Equal(t, num.NewUint(2), nextEpoch["party1"].totalDelegated)
   890  	require.Equal(t, num.NewUint(3), nextEpoch["party2"].totalDelegated)
   891  	require.Equal(t, num.NewUint(2), nextEpoch["party1"].nodeToAmount["node2"])
   892  	require.Equal(t, num.NewUint(3), nextEpoch["party2"].nodeToAmount["node2"])
   893  	require.Equal(t, 1, len(nextEpoch["party1"].nodeToAmount))
   894  	require.Equal(t, 1, len(nextEpoch["party2"].nodeToAmount))
   895  	require.Equal(t, 2, len(nextEpoch))
   896  }
   897  
   898  // undelegate incrementally to get all pending delegates countered.
   899  func testUndelegateSuccessWithPreviousPendingDelegateExactlyCovered(t *testing.T) {
   900  	// setup committed delegated state
   901  	testEngine := getEngine(t)
   902  	testEngine.topology.nodeToIsValidator["node1"] = true
   903  	testEngine.topology.nodeToIsValidator["node2"] = true
   904  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(12)
   905  	testEngine.stakingAccounts.partyToStake["party2"] = num.NewUint(7)
   906  
   907  	err := testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(10))
   908  	require.Nil(t, err)
   909  	err = testEngine.engine.Delegate(context.Background(), "party1", "node2", num.NewUint(2))
   910  	require.Nil(t, err)
   911  	err = testEngine.engine.Delegate(context.Background(), "party2", "node1", num.NewUint(4))
   912  	require.Nil(t, err)
   913  	err = testEngine.engine.Delegate(context.Background(), "party2", "node2", num.NewUint(3))
   914  	require.Nil(t, err)
   915  
   916  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(6))
   917  	require.Nil(t, err)
   918  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(4))
   919  	require.Nil(t, err)
   920  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node2", num.NewUint(2))
   921  	require.Nil(t, err)
   922  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party2", "node1", num.NewUint(4))
   923  	require.Nil(t, err)
   924  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party2", "node2", num.NewUint(3))
   925  	require.Nil(t, err)
   926  
   927  	nextEpoch := testEngine.engine.nextPartyDelegationState
   928  	require.Equal(t, 0, len(nextEpoch))
   929  }
   930  
   931  // undelegate such that delegation for some party and node goes from delegate to undelegate.
   932  func testUndelegateSuccessWithPreviousPendingDelegateFullyCovered(t *testing.T) {
   933  	testEngine := getEngine(t)
   934  	setupDefaultDelegationState(testEngine, 15, 10)
   935  
   936  	err := testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(2))
   937  	require.Nil(t, err)
   938  	err = testEngine.engine.Delegate(context.Background(), "party1", "node2", num.NewUint(3))
   939  	require.Nil(t, err)
   940  	err = testEngine.engine.Delegate(context.Background(), "party2", "node1", num.NewUint(3))
   941  	require.Nil(t, err)
   942  	err = testEngine.engine.Delegate(context.Background(), "party2", "node2", num.NewUint(2))
   943  	require.Nil(t, err)
   944  
   945  	// now undelegate more than pending delegation so that all pending delegation for a node is removed and pending undelegation is added
   946  
   947  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(7))
   948  	require.Nil(t, err)
   949  	err = testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party2", "node2", num.NewUint(4))
   950  	require.Nil(t, err)
   951  
   952  	nextEpoch := testEngine.engine.nextPartyDelegationState
   953  	require.Equal(t, num.NewUint(8), nextEpoch["party1"].totalDelegated)
   954  	require.Equal(t, 2, len(nextEpoch["party1"].nodeToAmount))
   955  	require.Equal(t, num.NewUint(1), nextEpoch["party1"].nodeToAmount["node1"])
   956  	require.Equal(t, num.NewUint(7), nextEpoch["party1"].nodeToAmount["node2"])
   957  	require.Equal(t, num.NewUint(6), nextEpoch["party2"].totalDelegated)
   958  	require.Equal(t, 2, len(nextEpoch["party2"].nodeToAmount))
   959  	require.Equal(t, num.NewUint(5), nextEpoch["party2"].nodeToAmount["node1"])
   960  	require.Equal(t, num.NewUint(1), nextEpoch["party2"].nodeToAmount["node2"])
   961  }
   962  
   963  // preprocess delegation state from last epoch for changes in stake balance - such that there were no changes so no forced undelegation is expected.
   964  func testPreprocessForRewardingNoForcedUndelegationNeeded(t *testing.T) {
   965  	testEngine := getEngine(t)
   966  
   967  	setupDefaultDelegationState(testEngine, 12, 10)
   968  	epochStart := time.Now()
   969  	epochEnd := time.Now()
   970  	testEngine.stakingAccounts.partyToStakeForEpoch[epochStart.UnixNano()] = make(map[string]*num.Uint)
   971  	testEngine.stakingAccounts.partyToStakeForEpoch[epochStart.UnixNano()]["party1"] = num.NewUint(12)
   972  	testEngine.stakingAccounts.partyToStakeForEpoch[epochStart.UnixNano()]["party2"] = num.NewUint(10)
   973  
   974  	// call preprocess to update the state based on the changes in staking account
   975  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{StartTime: epochStart, EndTime: epochEnd, Seq: 1})
   976  
   977  	// the stake account balance for the epoch covers the delegation for both parties so we expect no changes in delegated balances
   978  	require.Equal(t, num.NewUint(10), testEngine.engine.partyDelegationState["party1"].totalDelegated)
   979  	require.Equal(t, num.NewUint(6), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node1"])
   980  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"])
   981  	require.Equal(t, num.NewUint(5), testEngine.engine.partyDelegationState["party2"].totalDelegated)
   982  	require.Equal(t, num.NewUint(2), testEngine.engine.partyDelegationState["party2"].nodeToAmount["node1"])
   983  	require.Equal(t, num.NewUint(3), testEngine.engine.partyDelegationState["party2"].nodeToAmount["node2"])
   984  }
   985  
   986  // preprocess delegation state from last epoch for changes in stake balance - such that some tokens have been taken out of the staking account and require undelegation
   987  // from a single available node.
   988  func testPreprocessForRewardingWithForceUndelegateSingleValidator(t *testing.T) {
   989  	testEngine := getEngine(t)
   990  	defaultSimpleDelegationState(testEngine)
   991  	epochStart := time.Now()
   992  	epochEnd := time.Now()
   993  	testEngine.stakingAccounts.partyToStakeForEpoch[epochStart.UnixNano()] = make(map[string]*num.Uint)
   994  	testEngine.stakingAccounts.partyToStakeForEpoch[epochStart.UnixNano()]["party1"] = num.NewUint(2)
   995  	testEngine.stakingAccounts.partyToStakeForEpoch[epochStart.UnixNano()]["party2"] = num.NewUint(0)
   996  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(2)
   997  	testEngine.stakingAccounts.partyToStake["party2"] = num.UintZero()
   998  	testEngine.engine.onEpochEvent(context.Background(), types.Epoch{StartTime: epochStart, Seq: 1})
   999  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{StartTime: epochStart, EndTime: epochEnd, Seq: 1})
  1000  
  1001  	// both party1 and party2 withdrew tokens from their staking account that require undelegation
  1002  	// party1 requires undelegation of 4 tokens
  1003  	// party2 requires undelegation of 3 tokens
  1004  
  1005  	// node1 has 2 tokens left delegated to it altogether all by party1
  1006  	// node2 has nothing delegated to it
  1007  	require.Equal(t, 1, len(testEngine.engine.partyDelegationState))
  1008  	require.Equal(t, num.NewUint(2), testEngine.engine.partyDelegationState["party1"].totalDelegated)
  1009  	require.Equal(t, num.NewUint(2), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node1"])
  1010  }
  1011  
  1012  // preprocess delegation state from last epoch for changes in stake balance - such that some tokens have been taken out of the staking account and require undelegation
  1013  // from a multiple validator with equal proportion available node - with is no remainder.
  1014  func testPreprocessForRewardingWithForceUndelegateMultiValidatorNoRemainder(t *testing.T) {
  1015  	testEngine := getEngine(t)
  1016  	epochStart := time.Now()
  1017  	epochEnd := time.Now()
  1018  	testEngine.topology.nodeToIsValidator["node1"] = true
  1019  	testEngine.topology.nodeToIsValidator["node2"] = true
  1020  	testEngine.topology.nodeToIsValidator["node3"] = true
  1021  	testEngine.stakingAccounts.partyToStakeForEpoch[epochStart.UnixNano()] = make(map[string]*num.Uint)
  1022  	testEngine.stakingAccounts.partyToStakeForEpoch[epochStart.UnixNano()]["party1"] = num.NewUint(15)
  1023  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(15)
  1024  	testEngine.engine.onEpochEvent(context.Background(), types.Epoch{StartTime: epochStart, Seq: 1})
  1025  	// setup delegation
  1026  	// node1 -> 10
  1027  	// 		    party1 -> 10
  1028  	// node 2 -> 10
  1029  	//			party1 -> 10
  1030  	// node 3 -> 10
  1031  	//			party1 -> 10
  1032  
  1033  	// setup delegation for node3
  1034  	testEngine.engine.partyDelegationState["party1"] = &partyDelegation{
  1035  		party:          "party1",
  1036  		totalDelegated: num.NewUint(30),
  1037  		nodeToAmount:   make(map[string]*num.Uint),
  1038  	}
  1039  	testEngine.engine.partyDelegationState["party1"].nodeToAmount["node1"] = num.NewUint(10)
  1040  	testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"] = num.NewUint(10)
  1041  	testEngine.engine.partyDelegationState["party1"].nodeToAmount["node3"] = num.NewUint(10)
  1042  
  1043  	testEngine.engine.nextPartyDelegationState["party1"] = &partyDelegation{
  1044  		party:          "party1",
  1045  		totalDelegated: num.NewUint(30),
  1046  		nodeToAmount:   make(map[string]*num.Uint),
  1047  	}
  1048  	testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node1"] = num.NewUint(10)
  1049  	testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node2"] = num.NewUint(10)
  1050  	testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node3"] = num.NewUint(10)
  1051  
  1052  	// call preprocess to update the state based on the changes in staking account
  1053  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{StartTime: epochStart, EndTime: epochEnd, Seq: 1})
  1054  
  1055  	// the stake account balance has gone down for party1 to 15, and they have 30 tokens delegated meaning we need to undelegate 15
  1056  	// with equal balance in all validators we expect to remove 5 from each
  1057  
  1058  	require.Equal(t, 1, len(testEngine.engine.partyDelegationState))
  1059  	require.Equal(t, num.NewUint(15), testEngine.engine.partyDelegationState["party1"].totalDelegated)
  1060  	require.Equal(t, num.NewUint(5), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node1"])
  1061  	require.Equal(t, num.NewUint(5), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"])
  1062  	require.Equal(t, num.NewUint(5), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node3"])
  1063  }
  1064  
  1065  // preprocess delegation state from last epoch for changes in stake balance - such that some tokens have been taken out of the staking account and require undelegation
  1066  // from a multiple validator with equal proportion available node - with remainder.
  1067  func testPreprocessForRewardingWithForceUndelegateMultiValidatorWithRemainder(t *testing.T) {
  1068  	testEngine := getEngine(t)
  1069  	epochStart := time.Now()
  1070  	epochEnd := time.Now()
  1071  	testEngine.topology.nodeToIsValidator["node1"] = true
  1072  	testEngine.topology.nodeToIsValidator["node2"] = true
  1073  	testEngine.topology.nodeToIsValidator["node3"] = true
  1074  	testEngine.stakingAccounts.partyToStakeForEpoch[epochStart.UnixNano()] = make(map[string]*num.Uint)
  1075  	testEngine.stakingAccounts.partyToStakeForEpoch[epochStart.UnixNano()]["party1"] = num.NewUint(240)
  1076  	testEngine.stakingAccounts.partyToStakeForEpoch[epochStart.UnixNano()]["party2"] = num.NewUint(50)
  1077  	testEngine.stakingAccounts.partyToStakeForEpoch[epochStart.UnixNano()]["party3"] = num.NewUint(3)
  1078  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(240)
  1079  	testEngine.stakingAccounts.partyToStake["party2"] = num.NewUint(50)
  1080  	testEngine.stakingAccounts.partyToStake["party3"] = num.NewUint(3)
  1081  	testEngine.engine.onEpochEvent(context.Background(), types.Epoch{StartTime: epochStart, Seq: 1})
  1082  
  1083  	// setup delegation
  1084  	// node1 -> 120
  1085  	// 		    party1 -> 100
  1086  	// 		    party2 -> 20
  1087  	// node 2 -> 100
  1088  	//			party1 -> 90
  1089  	// 		    party2 -> 10
  1090  	// node 3 -> 85
  1091  	//			party1 -> 80
  1092  	//			party3 -> 5
  1093  
  1094  	testEngine.engine.partyDelegationState["party1"] = &partyDelegation{
  1095  		party:          "party1",
  1096  		totalDelegated: num.NewUint(270),
  1097  		nodeToAmount:   make(map[string]*num.Uint),
  1098  	}
  1099  	testEngine.engine.partyDelegationState["party1"].nodeToAmount["node1"] = num.NewUint(100)
  1100  	testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"] = num.NewUint(90)
  1101  	testEngine.engine.partyDelegationState["party1"].nodeToAmount["node3"] = num.NewUint(80)
  1102  
  1103  	testEngine.engine.nextPartyDelegationState["party1"] = &partyDelegation{
  1104  		party:          "party1",
  1105  		totalDelegated: num.NewUint(270),
  1106  		nodeToAmount:   make(map[string]*num.Uint),
  1107  	}
  1108  	testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node1"] = num.NewUint(100)
  1109  	testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node2"] = num.NewUint(90)
  1110  	testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node3"] = num.NewUint(80)
  1111  
  1112  	testEngine.engine.partyDelegationState["party2"] = &partyDelegation{
  1113  		party:          "party2",
  1114  		totalDelegated: num.NewUint(30),
  1115  		nodeToAmount:   make(map[string]*num.Uint),
  1116  	}
  1117  	testEngine.engine.partyDelegationState["party2"].nodeToAmount["node1"] = num.NewUint(20)
  1118  	testEngine.engine.partyDelegationState["party2"].nodeToAmount["node2"] = num.NewUint(10)
  1119  
  1120  	testEngine.engine.nextPartyDelegationState["party2"] = &partyDelegation{
  1121  		party:          "party2",
  1122  		totalDelegated: num.NewUint(30),
  1123  		nodeToAmount:   make(map[string]*num.Uint),
  1124  	}
  1125  	testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount["node1"] = num.NewUint(20)
  1126  	testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount["node2"] = num.NewUint(10)
  1127  
  1128  	testEngine.engine.partyDelegationState["party3"] = &partyDelegation{
  1129  		party:          "party3",
  1130  		totalDelegated: num.NewUint(5),
  1131  		nodeToAmount:   make(map[string]*num.Uint),
  1132  	}
  1133  	testEngine.engine.partyDelegationState["party3"].nodeToAmount["node3"] = num.NewUint(5)
  1134  
  1135  	testEngine.engine.nextPartyDelegationState["party3"] = &partyDelegation{
  1136  		party:          "party3",
  1137  		totalDelegated: num.NewUint(5),
  1138  		nodeToAmount:   make(map[string]*num.Uint),
  1139  	}
  1140  	testEngine.engine.nextPartyDelegationState["party3"].nodeToAmount["node3"] = num.NewUint(5)
  1141  
  1142  	// call preprocess to update the state based on the changes in staking account
  1143  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{StartTime: epochStart, EndTime: epochEnd, Seq: 1})
  1144  
  1145  	// the stake account balance for party1 has gone down by 30 so we need to undelegate 30 tokens in total from node1, node2, and node3
  1146  	// we do it proportionally to the delegation party1 has in them
  1147  	require.Equal(t, num.NewUint(240), testEngine.engine.partyDelegationState["party1"].totalDelegated)
  1148  	require.Equal(t, num.NewUint(88), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node1"])
  1149  	require.Equal(t, num.NewUint(80), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"])
  1150  	require.Equal(t, num.NewUint(72), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node3"])
  1151  
  1152  	require.Equal(t, num.NewUint(240), testEngine.engine.nextPartyDelegationState["party1"].totalDelegated)
  1153  	require.Equal(t, num.NewUint(88), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node1"])
  1154  	require.Equal(t, num.NewUint(80), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node2"])
  1155  	require.Equal(t, num.NewUint(72), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node3"])
  1156  
  1157  	// party2 stake account balance hasn't changed so no undelegation needed
  1158  	require.Equal(t, num.NewUint(30), testEngine.engine.partyDelegationState["party2"].totalDelegated)
  1159  	require.Equal(t, num.NewUint(20), testEngine.engine.partyDelegationState["party2"].nodeToAmount["node1"])
  1160  	require.Equal(t, num.NewUint(10), testEngine.engine.partyDelegationState["party2"].nodeToAmount["node2"])
  1161  	require.Equal(t, num.NewUint(30), testEngine.engine.nextPartyDelegationState["party2"].totalDelegated)
  1162  	require.Equal(t, num.NewUint(20), testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount["node1"])
  1163  	require.Equal(t, num.NewUint(10), testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount["node2"])
  1164  
  1165  	// party3 stake account balance is down by 2 so we need to undelegate 2 tokens
  1166  	require.Equal(t, num.NewUint(3), testEngine.engine.partyDelegationState["party3"].totalDelegated)
  1167  	require.Equal(t, num.NewUint(3), testEngine.engine.partyDelegationState["party3"].nodeToAmount["node3"])
  1168  	require.Equal(t, num.NewUint(3), testEngine.engine.nextPartyDelegationState["party3"].totalDelegated)
  1169  	require.Equal(t, num.NewUint(3), testEngine.engine.nextPartyDelegationState["party3"].nodeToAmount["node3"])
  1170  
  1171  	require.Equal(t, 3, len(testEngine.engine.partyDelegationState))
  1172  	require.Equal(t, 3, len(testEngine.engine.nextPartyDelegationState))
  1173  }
  1174  
  1175  // undelegate an empty slice of parties, no impact on state.
  1176  func testPendingUndelegationEmpty(t *testing.T) {
  1177  	// setup committed delegated state
  1178  	testEngine := getEngine(t)
  1179  	setupDefaultDelegationState(testEngine, 12, 7)
  1180  
  1181  	testEngine.engine.partyDelegationState["party2"] = &partyDelegation{
  1182  		party:          "party2",
  1183  		totalDelegated: num.NewUint(5),
  1184  		nodeToAmount:   make(map[string]*num.Uint),
  1185  	}
  1186  	testEngine.engine.partyDelegationState["party2"].nodeToAmount["node1"] = num.NewUint(2)
  1187  	testEngine.engine.partyDelegationState["party2"].nodeToAmount["node2"] = num.NewUint(3)
  1188  
  1189  	testEngine.engine.nextPartyDelegationState["party2"] = &partyDelegation{
  1190  		party:          "party2",
  1191  		totalDelegated: num.NewUint(5),
  1192  		nodeToAmount:   make(map[string]*num.Uint),
  1193  	}
  1194  	testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount["node1"] = num.NewUint(2)
  1195  	testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount["node2"] = num.NewUint(3)
  1196  
  1197  	// no pending undelegations
  1198  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 1})
  1199  
  1200  	require.Equal(t, num.NewUint(10), testEngine.engine.partyDelegationState["party1"].totalDelegated)
  1201  	require.Equal(t, num.NewUint(10), testEngine.engine.nextPartyDelegationState["party1"].totalDelegated)
  1202  	require.Equal(t, num.NewUint(6), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node1"])
  1203  	require.Equal(t, num.NewUint(6), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node1"])
  1204  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"])
  1205  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node2"])
  1206  	require.Equal(t, num.NewUint(5), testEngine.engine.partyDelegationState["party2"].totalDelegated)
  1207  	require.Equal(t, num.NewUint(5), testEngine.engine.nextPartyDelegationState["party2"].totalDelegated)
  1208  	require.Equal(t, num.NewUint(2), testEngine.engine.partyDelegationState["party2"].nodeToAmount["node1"])
  1209  	require.Equal(t, num.NewUint(2), testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount["node1"])
  1210  	require.Equal(t, num.NewUint(3), testEngine.engine.partyDelegationState["party2"].nodeToAmount["node2"])
  1211  	require.Equal(t, num.NewUint(3), testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount["node2"])
  1212  }
  1213  
  1214  // undelegate a party with no delegation, no impact on state.
  1215  func testPendingUndelegationNothingToUndelegate(t *testing.T) {
  1216  	// setup committed delegated state
  1217  	testEngine := getEngine(t)
  1218  	setupDefaultDelegationState(testEngine, 12, 7)
  1219  
  1220  	// in this case party3 had delegate state which must have been cleared by the preprocessing step as the party withdrew from the staking account
  1221  	// but it still has an undelegation pending for execution - which will have no impact when executed
  1222  	// expect no change in delegation state and clearing of the pending state
  1223  	require.Equal(t, num.NewUint(10), testEngine.engine.partyDelegationState["party1"].totalDelegated)
  1224  	require.Equal(t, num.NewUint(10), testEngine.engine.nextPartyDelegationState["party1"].totalDelegated)
  1225  	require.Equal(t, num.NewUint(6), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node1"])
  1226  	require.Equal(t, num.NewUint(6), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node1"])
  1227  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"])
  1228  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node2"])
  1229  	require.Equal(t, num.NewUint(5), testEngine.engine.partyDelegationState["party2"].totalDelegated)
  1230  	require.Equal(t, num.NewUint(5), testEngine.engine.nextPartyDelegationState["party2"].totalDelegated)
  1231  	require.Equal(t, num.NewUint(2), testEngine.engine.partyDelegationState["party2"].nodeToAmount["node1"])
  1232  	require.Equal(t, num.NewUint(2), testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount["node1"])
  1233  	require.Equal(t, num.NewUint(3), testEngine.engine.partyDelegationState["party2"].nodeToAmount["node2"])
  1234  	require.Equal(t, num.NewUint(3), testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount["node2"])
  1235  }
  1236  
  1237  // undelegate an more than the delegated balance of party - the whole balance for the party for the node is cleared.
  1238  func testPendingUndelegationGTDelegateddBalance(t *testing.T) {
  1239  	// setup committed delegated state
  1240  	testEngine := getEngine(t)
  1241  	setupDefaultDelegationState(testEngine, 12, 7)
  1242  
  1243  	// undelegate
  1244  	testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(6))
  1245  	testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party2", "node2", num.NewUint(3))
  1246  
  1247  	// update the delegation state to reflect forced undelegation taking place due to party withdrawing from their staking account so that
  1248  	// by the time the delegation command is executed the delegated balance is lower than the undelegated amount
  1249  
  1250  	testEngine.engine.partyDelegationState["party1"] = &partyDelegation{
  1251  		party:          "party1",
  1252  		totalDelegated: num.NewUint(9),
  1253  		nodeToAmount:   make(map[string]*num.Uint),
  1254  	}
  1255  	testEngine.engine.partyDelegationState["party1"].nodeToAmount["node1"] = num.NewUint(5)
  1256  	testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"] = num.NewUint(4)
  1257  
  1258  	testEngine.engine.partyDelegationState["party2"] = &partyDelegation{
  1259  		party:          "party2",
  1260  		totalDelegated: num.NewUint(4),
  1261  		nodeToAmount:   make(map[string]*num.Uint),
  1262  	}
  1263  	testEngine.engine.partyDelegationState["party2"].nodeToAmount["node1"] = num.NewUint(2)
  1264  	testEngine.engine.partyDelegationState["party2"].nodeToAmount["node2"] = num.NewUint(2)
  1265  
  1266  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 1})
  1267  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].totalDelegated)
  1268  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party1"].totalDelegated)
  1269  	require.Equal(t, 1, len(testEngine.engine.partyDelegationState["party1"].nodeToAmount))
  1270  	require.Equal(t, 1, len(testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount))
  1271  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"])
  1272  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node2"])
  1273  	require.Equal(t, num.NewUint(2), testEngine.engine.partyDelegationState["party2"].totalDelegated)
  1274  	require.Equal(t, num.NewUint(2), testEngine.engine.nextPartyDelegationState["party2"].totalDelegated)
  1275  	require.Equal(t, 1, len(testEngine.engine.partyDelegationState["party2"].nodeToAmount))
  1276  	require.Equal(t, 1, len(testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount))
  1277  	require.Equal(t, num.NewUint(2), testEngine.engine.partyDelegationState["party2"].nodeToAmount["node1"])
  1278  	require.Equal(t, num.NewUint(2), testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount["node1"])
  1279  }
  1280  
  1281  // undelegate less than the delegated balance of party - the difference between the balances is remained delegated.
  1282  func testPendingUndelegationLTDelegateddBalance(t *testing.T) {
  1283  	// setup committed delegated state
  1284  	testEngine := getEngine(t)
  1285  	setupDefaultDelegationState(testEngine, 12, 7)
  1286  
  1287  	// trying to undelegate more than the node has delegated from the party should just undelegate everything the party has on the node
  1288  	testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(3))
  1289  	testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party2", "node2", num.NewUint(1))
  1290  
  1291  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 1})
  1292  	require.Equal(t, num.NewUint(7), testEngine.engine.partyDelegationState["party1"].totalDelegated)
  1293  	require.Equal(t, num.NewUint(7), testEngine.engine.nextPartyDelegationState["party1"].totalDelegated)
  1294  	require.Equal(t, 2, len(testEngine.engine.partyDelegationState["party1"].nodeToAmount))
  1295  	require.Equal(t, 2, len(testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount))
  1296  	require.Equal(t, num.NewUint(3), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node1"])
  1297  	require.Equal(t, num.NewUint(3), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node1"])
  1298  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"])
  1299  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node2"])
  1300  
  1301  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party2"].totalDelegated)
  1302  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party2"].totalDelegated)
  1303  	require.Equal(t, 2, len(testEngine.engine.partyDelegationState["party2"].nodeToAmount))
  1304  	require.Equal(t, 2, len(testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount))
  1305  	require.Equal(t, num.NewUint(2), testEngine.engine.partyDelegationState["party2"].nodeToAmount["node1"])
  1306  	require.Equal(t, num.NewUint(2), testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount["node1"])
  1307  	require.Equal(t, num.NewUint(2), testEngine.engine.partyDelegationState["party2"].nodeToAmount["node2"])
  1308  	require.Equal(t, num.NewUint(2), testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount["node2"])
  1309  }
  1310  
  1311  // undelegate the whole balance of a given party from all nodes.
  1312  func testPendingUndelegationAllBalanceForParty(t *testing.T) {
  1313  	// setup committed delegated state
  1314  	testEngine := getEngine(t)
  1315  	setupDefaultDelegationState(testEngine, 12, 7)
  1316  
  1317  	// trying to undelegate more than the node has delegated from the party should just undelegate everything the party has on the node
  1318  	testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(6))
  1319  	testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party2", "node2", num.NewUint(3))
  1320  
  1321  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 1})
  1322  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].totalDelegated)
  1323  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party1"].totalDelegated)
  1324  	require.Equal(t, 1, len(testEngine.engine.partyDelegationState["party1"].nodeToAmount))
  1325  	require.Equal(t, 1, len(testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount))
  1326  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"])
  1327  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node2"])
  1328  	require.Equal(t, num.NewUint(2), testEngine.engine.partyDelegationState["party2"].totalDelegated)
  1329  	require.Equal(t, num.NewUint(2), testEngine.engine.nextPartyDelegationState["party2"].totalDelegated)
  1330  	require.Equal(t, 1, len(testEngine.engine.partyDelegationState["party2"].nodeToAmount))
  1331  	require.Equal(t, 1, len(testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount))
  1332  	require.Equal(t, num.NewUint(2), testEngine.engine.partyDelegationState["party2"].nodeToAmount["node1"])
  1333  	require.Equal(t, num.NewUint(2), testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount["node1"])
  1334  }
  1335  
  1336  // undelegate the whole balance of a given node.
  1337  func testPendingUndelegationAllBalanceForNode(t *testing.T) {
  1338  	// setup committed delegated state
  1339  	testEngine := getEngine(t)
  1340  	setupDefaultDelegationState(testEngine, 12, 7)
  1341  
  1342  	// trying to undelegate more than the node has delegated from the party should just undelegate everything the party has on the node
  1343  	testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(6))
  1344  	testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party2", "node1", num.NewUint(2))
  1345  
  1346  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 1})
  1347  
  1348  	require.Equal(t, 2, len(testEngine.engine.partyDelegationState))
  1349  	require.Equal(t, 2, len(testEngine.engine.nextPartyDelegationState))
  1350  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].totalDelegated)
  1351  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party1"].totalDelegated)
  1352  	require.Equal(t, 1, len(testEngine.engine.partyDelegationState["party1"].nodeToAmount))
  1353  	require.Equal(t, 1, len(testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount))
  1354  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"])
  1355  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node2"])
  1356  	require.Equal(t, num.NewUint(3), testEngine.engine.partyDelegationState["party2"].totalDelegated)
  1357  	require.Equal(t, num.NewUint(3), testEngine.engine.nextPartyDelegationState["party2"].totalDelegated)
  1358  	require.Equal(t, 1, len(testEngine.engine.partyDelegationState["party2"].nodeToAmount))
  1359  	require.Equal(t, 1, len(testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount))
  1360  	require.Equal(t, num.NewUint(3), testEngine.engine.partyDelegationState["party2"].nodeToAmount["node2"])
  1361  	require.Equal(t, num.NewUint(3), testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount["node2"])
  1362  }
  1363  
  1364  // no pending delegations to process.
  1365  func testPendingDelegationEmpty(t *testing.T) {
  1366  	testEngine := getEngine(t)
  1367  	testEngine.topology.nodeToIsValidator["node1"] = true
  1368  	testEngine.topology.nodeToIsValidator["node2"] = true
  1369  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(12)
  1370  	testEngine.stakingAccounts.partyToStake["party2"] = num.NewUint(7)
  1371  
  1372  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 1})
  1373  	require.Equal(t, 0, len(testEngine.engine.partyDelegationState))
  1374  }
  1375  
  1376  // delegation at the time of processing of the pending request has insufficient balance in the staking account.
  1377  func testPendingDelegationInsufficientBalance(t *testing.T) {
  1378  	testEngine := getEngine(t)
  1379  	testEngine.topology.nodeToIsValidator["node1"] = true
  1380  	testEngine.topology.nodeToIsValidator["node2"] = true
  1381  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(12)
  1382  	testEngine.stakingAccounts.partyToStake["party2"] = num.NewUint(7)
  1383  
  1384  	testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(10))
  1385  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(8)
  1386  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 1})
  1387  	require.Equal(t, 1, len(testEngine.engine.partyDelegationState))
  1388  	require.Equal(t, num.NewUint(8), testEngine.engine.partyDelegationState["party1"].totalDelegated)
  1389  	require.Equal(t, num.NewUint(8), testEngine.engine.nextPartyDelegationState["party1"].totalDelegated)
  1390  	require.Equal(t, num.NewUint(8), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node1"])
  1391  	require.Equal(t, num.NewUint(8), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node1"])
  1392  }
  1393  
  1394  // process pending delegation successfully.
  1395  func testPendingDelegationSuccess(t *testing.T) {
  1396  	// setup committed delegated state
  1397  	testEngine := getEngine(t)
  1398  	setupDefaultDelegationState(testEngine, 12, 7)
  1399  
  1400  	// party1 has sufficient balance in their staking account to delegate 2 more
  1401  	testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(2))
  1402  
  1403  	// the delegation has been applied on the state
  1404  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 1})
  1405  	require.Equal(t, num.NewUint(12), testEngine.engine.partyDelegationState["party1"].totalDelegated)
  1406  	require.Equal(t, num.NewUint(12), testEngine.engine.nextPartyDelegationState["party1"].totalDelegated)
  1407  	require.Equal(t, num.NewUint(8), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node1"])
  1408  	require.Equal(t, num.NewUint(8), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node1"])
  1409  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"])
  1410  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node2"])
  1411  }
  1412  
  1413  // process pending delegations and undelegations.
  1414  func testProcessPending(t *testing.T) {
  1415  	// setup committed delegated state
  1416  	testEngine := getEngine(t)
  1417  	setupDefaultDelegationState(testEngine, 12, 7)
  1418  
  1419  	// party1 has sufficient balance in their staking account to delegate 2 more
  1420  	testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(2))
  1421  	testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party2", "node2", num.NewUint(1))
  1422  
  1423  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 1})
  1424  
  1425  	require.Equal(t, num.NewUint(12), testEngine.engine.partyDelegationState["party1"].totalDelegated)
  1426  	require.Equal(t, num.NewUint(12), testEngine.engine.nextPartyDelegationState["party1"].totalDelegated)
  1427  	require.Equal(t, num.NewUint(8), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node1"])
  1428  	require.Equal(t, num.NewUint(8), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node1"])
  1429  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"])
  1430  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node2"])
  1431  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party2"].totalDelegated)
  1432  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party2"].totalDelegated)
  1433  	require.Equal(t, num.NewUint(2), testEngine.engine.partyDelegationState["party2"].nodeToAmount["node1"])
  1434  	require.Equal(t, num.NewUint(2), testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount["node1"])
  1435  	require.Equal(t, num.NewUint(2), testEngine.engine.partyDelegationState["party2"].nodeToAmount["node2"])
  1436  	require.Equal(t, num.NewUint(2), testEngine.engine.nextPartyDelegationState["party2"].nodeToAmount["node2"])
  1437  }
  1438  
  1439  func testGetValidatorsEmpty(t *testing.T) {
  1440  	testEngine := getEngine(t)
  1441  	validators := testEngine.engine.getValidatorData()
  1442  	require.Equal(t, 5, len(validators))
  1443  
  1444  	for i, v := range validators {
  1445  		require.Equal(t, "node"+strconv.Itoa(i+1), v.NodeID)
  1446  		require.Equal(t, num.UintZero(), v.SelfStake)
  1447  		require.Equal(t, num.UintZero(), v.StakeByDelegators)
  1448  	}
  1449  }
  1450  
  1451  func testGetValidatorsSuccess(t *testing.T) {
  1452  	testEngine := getEngine(t)
  1453  	testEngine.topology.nodeToIsValidator["node1"] = true
  1454  	testEngine.topology.nodeToIsValidator["node2"] = true
  1455  	testEngine.topology.nodeToIsValidator["node3"] = true
  1456  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(100)
  1457  	testEngine.stakingAccounts.partyToStake["party2"] = num.NewUint(100)
  1458  	testEngine.stakingAccounts.partyToStake["party3"] = num.NewUint(100)
  1459  	testEngine.stakingAccounts.partyToStake["party4"] = num.NewUint(100)
  1460  	testEngine.stakingAccounts.partyToStake["party5"] = num.NewUint(100)
  1461  
  1462  	testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(20))
  1463  	testEngine.engine.Delegate(context.Background(), "party1", "node2", num.NewUint(30))
  1464  	testEngine.engine.Delegate(context.Background(), "party1", "node3", num.NewUint(40))
  1465  	testEngine.engine.Delegate(context.Background(), "party2", "node1", num.NewUint(30))
  1466  	testEngine.engine.Delegate(context.Background(), "party2", "node2", num.NewUint(40))
  1467  	testEngine.engine.Delegate(context.Background(), "party2", "node3", num.NewUint(20))
  1468  	testEngine.engine.Delegate(context.Background(), "party3", "node1", num.NewUint(40))
  1469  	testEngine.engine.Delegate(context.Background(), "party3", "node2", num.NewUint(20))
  1470  	testEngine.engine.Delegate(context.Background(), "party3", "node3", num.NewUint(30))
  1471  
  1472  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 1})
  1473  	validators := testEngine.engine.getValidatorData()
  1474  	require.Equal(t, 5, len(validators))
  1475  	require.Equal(t, "node1", validators[0].NodeID)
  1476  	require.Equal(t, num.NewUint(90), validators[0].StakeByDelegators)
  1477  	require.Equal(t, 3, len(validators[0].Delegators))
  1478  	require.Equal(t, num.NewUint(20), validators[0].Delegators["party1"])
  1479  	require.Equal(t, num.NewUint(30), validators[0].Delegators["party2"])
  1480  	require.Equal(t, num.NewUint(40), validators[0].Delegators["party3"])
  1481  
  1482  	require.Equal(t, "node2", validators[1].NodeID)
  1483  	require.Equal(t, num.NewUint(90), validators[1].StakeByDelegators)
  1484  	require.Equal(t, 3, len(validators[1].Delegators))
  1485  	require.Equal(t, num.NewUint(30), validators[1].Delegators["party1"])
  1486  	require.Equal(t, num.NewUint(40), validators[1].Delegators["party2"])
  1487  	require.Equal(t, num.NewUint(20), validators[1].Delegators["party3"])
  1488  
  1489  	require.Equal(t, "node3", validators[2].NodeID)
  1490  	require.Equal(t, 3, len(validators[2].Delegators))
  1491  	require.Equal(t, num.NewUint(90), validators[2].StakeByDelegators)
  1492  	require.Equal(t, num.NewUint(40), validators[2].Delegators["party1"])
  1493  	require.Equal(t, num.NewUint(20), validators[2].Delegators["party2"])
  1494  	require.Equal(t, num.NewUint(30), validators[2].Delegators["party3"])
  1495  }
  1496  
  1497  func testGetValidatorsSuccessWithSelfDelegation(t *testing.T) {
  1498  	testEngine := getEngine(t)
  1499  	for i := 1; i < 6; i++ {
  1500  		testEngine.topology.nodeToIsValidator["node"+strconv.Itoa(i)] = true
  1501  	}
  1502  
  1503  	for i := 1; i < 6; i++ {
  1504  		testEngine.stakingAccounts.partyToStake["node"+strconv.Itoa(i)] = num.NewUint(10000)
  1505  		err := testEngine.engine.Delegate(context.Background(), "node"+strconv.Itoa(i), "node"+strconv.Itoa(i), num.NewUint(200))
  1506  		require.Nil(t, err)
  1507  		for j := 1; j < 6; j++ {
  1508  			if i != j {
  1509  				err = testEngine.engine.Delegate(context.Background(), "node"+strconv.Itoa(i), "node"+strconv.Itoa(j), num.NewUint(100))
  1510  				require.Nil(t, err)
  1511  			}
  1512  		}
  1513  	}
  1514  
  1515  	for i := 1; i < 11; i++ {
  1516  		testEngine.stakingAccounts.partyToStake["party"+strconv.Itoa(i)] = num.NewUint(100)
  1517  		for j := 1; j < 6; j++ {
  1518  			testEngine.engine.Delegate(context.Background(), "party"+strconv.Itoa(i), "node"+strconv.Itoa(j), num.NewUint(2))
  1519  		}
  1520  	}
  1521  
  1522  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 1})
  1523  	validators := testEngine.engine.getValidatorData()
  1524  
  1525  	require.Equal(t, 5, len(validators))
  1526  	for i := 1; i < 6; i++ {
  1527  		require.Equal(t, "node"+strconv.Itoa(i), validators[i-1].NodeID)
  1528  		// 100 from each other validator (400) + 2 from each party (20)
  1529  		require.Equal(t, num.NewUint(420), validators[i-1].StakeByDelegators)
  1530  		require.Equal(t, num.NewUint(200), validators[i-1].SelfStake)
  1531  		// 10 parties + 4 other validators
  1532  		require.Equal(t, 14, len(validators[i-1].Delegators))
  1533  
  1534  		for j := 1; j < 11; j++ {
  1535  			require.Equal(t, num.NewUint(2), validators[i-1].Delegators["party"+strconv.Itoa(j)])
  1536  		}
  1537  	}
  1538  }
  1539  
  1540  // try to undelegate more than delegated.
  1541  func testUndelegateNowIncorrectAmount(t *testing.T) {
  1542  	testEngine := getEngine(t)
  1543  
  1544  	testEngine.topology.nodeToIsValidator["node1"] = true
  1545  	testEngine.topology.nodeToIsValidator["node2"] = true
  1546  
  1547  	err := testEngine.engine.UndelegateNow(context.Background(), "party1", "node1", num.NewUint(10))
  1548  	require.EqualError(t, err, ErrIncorrectTokenAmountForUndelegation.Error())
  1549  
  1550  	// setup delegation state
  1551  	setupDefaultDelegationState(testEngine, 12, 7)
  1552  
  1553  	// party1/node1 has 6 delegated, try to undelegate 8
  1554  	err = testEngine.engine.UndelegateNow(context.Background(), "party1", "node1", num.NewUint(8))
  1555  	require.EqualError(t, err, ErrIncorrectTokenAmountForUndelegation.Error())
  1556  
  1557  	// add pending delegation of 2
  1558  	err = testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(2))
  1559  	require.Nil(t, err)
  1560  
  1561  	// party1 has 8 delegated in total to node1 (6 committed 2 pending) - try to undelegate 10 should error
  1562  	err = testEngine.engine.UndelegateNow(context.Background(), "party1", "node1", num.NewUint(10))
  1563  	require.EqualError(t, err, ErrIncorrectTokenAmountForUndelegation.Error())
  1564  
  1565  	// show that undelegating 8 doesn't error
  1566  	err = testEngine.engine.UndelegateNow(context.Background(), "party1", "node1", num.NewUint(8))
  1567  	require.Nil(t, err)
  1568  }
  1569  
  1570  // undelegate all now, there are no committed delegations for the node, only pending and they are all cleared.
  1571  func testUndelegateNowAllWithPendingOnly(t *testing.T) {
  1572  	testEngine := getEngine(t)
  1573  	testEngine.topology.nodeToIsValidator["node1"] = true
  1574  	testEngine.topology.nodeToIsValidator["node2"] = true
  1575  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(30)
  1576  	testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(10))
  1577  	testEngine.engine.Delegate(context.Background(), "party1", "node2", num.NewUint(10))
  1578  
  1579  	err := testEngine.engine.UndelegateNow(context.Background(), "party1", "node1", num.UintZero())
  1580  	require.Nil(t, err)
  1581  	nextEpoch := testEngine.engine.nextPartyDelegationState
  1582  
  1583  	require.Equal(t, 1, len(nextEpoch["party1"].nodeToAmount))
  1584  	require.Equal(t, num.NewUint(10), nextEpoch["party1"].totalDelegated)
  1585  	require.Equal(t, num.NewUint(10), nextEpoch["party1"].nodeToAmount["node2"])
  1586  }
  1587  
  1588  // there's no pending delegation, remove all committed delegation.
  1589  func testUndelegateNowAllWithCommittedOnly(t *testing.T) {
  1590  	testEngine := getEngine(t)
  1591  	// setup delegation state
  1592  	setupDefaultDelegationState(testEngine, 12, 7)
  1593  
  1594  	// undelegate now all for party1 node1
  1595  	err := testEngine.engine.UndelegateNow(context.Background(), "party1", "node1", num.UintZero())
  1596  	require.Nil(t, err)
  1597  
  1598  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].totalDelegated)
  1599  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party1"].totalDelegated)
  1600  	require.Equal(t, 1, len(testEngine.engine.partyDelegationState["party1"].nodeToAmount))
  1601  	require.Equal(t, 1, len(testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount))
  1602  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"])
  1603  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node2"])
  1604  
  1605  	// undelegate now all for party1 node2
  1606  	err = testEngine.engine.UndelegateNow(context.Background(), "party1", "node2", num.UintZero())
  1607  	require.Nil(t, err)
  1608  	require.Equal(t, 1, len(testEngine.engine.partyDelegationState))
  1609  	require.Equal(t, 1, len(testEngine.engine.nextPartyDelegationState))
  1610  }
  1611  
  1612  // there's both committed and pending delegation, take all from both.
  1613  func testUndelegateNowAll(t *testing.T) {
  1614  	testEngine := getEngine(t)
  1615  	// setup delegation state
  1616  	setupDefaultDelegationState(testEngine, 12, 7)
  1617  
  1618  	err := testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(2))
  1619  	require.Nil(t, err)
  1620  
  1621  	// undelegate now all for party1 node1 both committed and pending state should update
  1622  	err = testEngine.engine.UndelegateNow(context.Background(), "party1", "node1", num.UintZero())
  1623  	require.Nil(t, err)
  1624  
  1625  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].totalDelegated)
  1626  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party1"].totalDelegated)
  1627  	require.Equal(t, 1, len(testEngine.engine.partyDelegationState["party1"].nodeToAmount))
  1628  	require.Equal(t, 1, len(testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount))
  1629  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"])
  1630  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node2"])
  1631  
  1632  	// undelegate now all for party1 node2
  1633  	err = testEngine.engine.UndelegateNow(context.Background(), "party1", "node2", num.UintZero())
  1634  	require.Nil(t, err)
  1635  	require.Equal(t, 1, len(testEngine.engine.partyDelegationState))
  1636  	require.Equal(t, 1, len(testEngine.engine.nextPartyDelegationState))
  1637  }
  1638  
  1639  func testUndelegateNowWithPendingOnly(t *testing.T) {
  1640  	testEngine := getEngine(t)
  1641  	testEngine.topology.nodeToIsValidator["node1"] = true
  1642  	testEngine.topology.nodeToIsValidator["node2"] = true
  1643  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(30)
  1644  	testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(10))
  1645  	testEngine.engine.Delegate(context.Background(), "party1", "node2", num.NewUint(10))
  1646  
  1647  	err := testEngine.engine.UndelegateNow(context.Background(), "party1", "node1", num.NewUint(5))
  1648  	require.Nil(t, err)
  1649  
  1650  	nextEpoch := testEngine.engine.nextPartyDelegationState
  1651  	require.Equal(t, 2, len(nextEpoch["party1"].nodeToAmount))
  1652  	require.Equal(t, num.NewUint(15), nextEpoch["party1"].totalDelegated)
  1653  	require.Equal(t, num.NewUint(5), nextEpoch["party1"].nodeToAmount["node1"])
  1654  	require.Equal(t, num.NewUint(10), nextEpoch["party1"].nodeToAmount["node2"])
  1655  }
  1656  
  1657  func testUndelegateNowWithCommittedOnly(t *testing.T) {
  1658  	testEngine := getEngine(t)
  1659  	// setup delegation state
  1660  	setupDefaultDelegationState(testEngine, 12, 7)
  1661  
  1662  	// undelegate now all for party1 node1
  1663  	err := testEngine.engine.UndelegateNow(context.Background(), "party1", "node1", num.NewUint(4))
  1664  	require.Nil(t, err)
  1665  
  1666  	require.Equal(t, num.NewUint(6), testEngine.engine.partyDelegationState["party1"].totalDelegated)
  1667  	require.Equal(t, num.NewUint(6), testEngine.engine.nextPartyDelegationState["party1"].totalDelegated)
  1668  	require.Equal(t, 2, len(testEngine.engine.partyDelegationState["party1"].nodeToAmount))
  1669  	require.Equal(t, 2, len(testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount))
  1670  	require.Equal(t, num.NewUint(2), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node1"])
  1671  	require.Equal(t, num.NewUint(2), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node1"])
  1672  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"])
  1673  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node2"])
  1674  }
  1675  
  1676  // undelegate now amount is fully covered in pending delegation, the committed state is unchanged.
  1677  func testUndelegateNowPendingCovers(t *testing.T) {
  1678  	testEngine := getEngine(t)
  1679  	// setup delegation state
  1680  	setupDefaultDelegationState(testEngine, 13, 7)
  1681  
  1682  	err := testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(3))
  1683  	require.Nil(t, err)
  1684  
  1685  	// undelegate now all for party1 node1
  1686  	err = testEngine.engine.UndelegateNow(context.Background(), "party1", "node1", num.NewUint(3))
  1687  	require.Nil(t, err)
  1688  
  1689  	// committed state should have stayed the same
  1690  	require.Equal(t, num.NewUint(7), testEngine.engine.partyDelegationState["party1"].totalDelegated)
  1691  	require.Equal(t, num.NewUint(10), testEngine.engine.nextPartyDelegationState["party1"].totalDelegated)
  1692  	require.Equal(t, num.NewUint(3), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node1"])
  1693  	require.Equal(t, num.NewUint(6), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node1"])
  1694  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"])
  1695  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node2"])
  1696  }
  1697  
  1698  // undelegate now takes all pending and some of the committed delegation.
  1699  func testUndelegateNowCommittedCovers(t *testing.T) {
  1700  	testEngine := getEngine(t)
  1701  	// setup delegation state
  1702  	setupDefaultDelegationState(testEngine, 13, 7)
  1703  
  1704  	err := testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(3))
  1705  	require.Nil(t, err)
  1706  
  1707  	// undelegate now for party1 node1
  1708  	err = testEngine.engine.UndelegateNow(context.Background(), "party1", "node1", num.NewUint(7))
  1709  	require.Nil(t, err)
  1710  
  1711  	// committed state lost 4 delegated tokens for party1 node1
  1712  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].totalDelegated)
  1713  	require.Equal(t, num.NewUint(6), testEngine.engine.nextPartyDelegationState["party1"].totalDelegated)
  1714  	require.Equal(t, 1, len(testEngine.engine.partyDelegationState["party1"].nodeToAmount))
  1715  	require.Equal(t, 2, len(testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount))
  1716  	require.Equal(t, num.NewUint(2), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node1"])
  1717  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"])
  1718  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount["node2"])
  1719  }
  1720  
  1721  func testUndelegateNowTwice(t *testing.T) {
  1722  	testEngine := getEngine(t)
  1723  	// setup delegation state
  1724  	setupDefaultDelegationState(testEngine, 13, 7)
  1725  
  1726  	err := testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(3))
  1727  	require.Nil(t, err)
  1728  
  1729  	// undelegate now for party1 node1
  1730  	err = testEngine.engine.UndelegateNow(context.Background(), "party1", "node1", num.NewUint(0))
  1731  	require.Nil(t, err)
  1732  
  1733  	// undelegate now for party1 node2
  1734  	err = testEngine.engine.UndelegateNow(context.Background(), "party1", "node2", num.NewUint(0))
  1735  	require.Nil(t, err)
  1736  
  1737  	// undelegate now for party1 node1
  1738  	err = testEngine.engine.UndelegateNow(context.Background(), "party1", "node1", num.NewUint(0))
  1739  	require.Nil(t, err)
  1740  }
  1741  
  1742  // undelegate now with an amount equals to the total delegated (pending + committed).
  1743  func testUndelegateNowAllCleared(t *testing.T) {
  1744  	testEngine := getEngine(t)
  1745  	// setup delegation state
  1746  	setupDefaultDelegationState(testEngine, 13, 7)
  1747  
  1748  	err := testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(3))
  1749  	require.Nil(t, err)
  1750  
  1751  	// undelegate now for party1 node1
  1752  	err = testEngine.engine.UndelegateNow(context.Background(), "party1", "node1", num.NewUint(9))
  1753  	require.Nil(t, err)
  1754  
  1755  	// pending state cleared
  1756  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].totalDelegated)
  1757  	require.Equal(t, num.NewUint(4), testEngine.engine.nextPartyDelegationState["party1"].totalDelegated)
  1758  	require.Equal(t, 1, len(testEngine.engine.partyDelegationState["party1"].nodeToAmount))
  1759  	require.Equal(t, 1, len(testEngine.engine.nextPartyDelegationState["party1"].nodeToAmount))
  1760  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"])
  1761  	require.Equal(t, num.NewUint(4), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"])
  1762  
  1763  	// undelegate now all for party1 node2
  1764  	err = testEngine.engine.UndelegateNow(context.Background(), "party1", "node2", num.NewUint(4))
  1765  	require.Nil(t, err)
  1766  	require.Equal(t, 1, len(testEngine.engine.partyDelegationState))
  1767  	require.Equal(t, 1, len(testEngine.engine.nextPartyDelegationState))
  1768  }
  1769  
  1770  func testCheckPartyEnteringAutoDelegation(t *testing.T) {
  1771  	testEngine := getEngine(t)
  1772  	setupDefaultDelegationState(testEngine, 10, 5)
  1773  
  1774  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 1})
  1775  	require.Contains(t, testEngine.engine.autoDelegationMode, "party1")
  1776  	require.Contains(t, testEngine.engine.autoDelegationMode, "party2")
  1777  
  1778  	// increase the stake of party1 by 10000
  1779  	testEngine.stakingAccounts.partyToStake["party1"].AddSum(num.NewUint(10000))
  1780  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 2})
  1781  
  1782  	evts := testEngine.broker.GetAllByType(events.DelegationBalanceEvent)
  1783  	require.Equal(t, 2, len(evts))
  1784  	require.Equal(t, "node1", evts[0].StreamMessage().GetDelegationBalance().NodeId)
  1785  	require.Equal(t, "node2", evts[1].StreamMessage().GetDelegationBalance().NodeId)
  1786  
  1787  	// party 1 had 6 delegated to node1 and 4 delegated to node2
  1788  	// their stake has been increased by 10k so it is delegated proportionally to these to nodes resulting in the below.
  1789  	require.Equal(t, "6006", evts[0].StreamMessage().GetDelegationBalance().Amount)
  1790  	require.Equal(t, "4004", evts[1].StreamMessage().GetDelegationBalance().Amount)
  1791  }
  1792  
  1793  func testCheckPartyExitingAutoDelegationThroughUndelegateEOE(t *testing.T) {
  1794  	testEngine := getEngine(t)
  1795  	setupDefaultDelegationState(testEngine, 10, 5)
  1796  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 1})
  1797  	require.Contains(t, testEngine.engine.autoDelegationMode, "party1")
  1798  	require.Contains(t, testEngine.engine.autoDelegationMode, "party2")
  1799  
  1800  	testEngine.engine.onEpochEvent(context.Background(), types.Epoch{Seq: 2})
  1801  	testEngine.engine.UndelegateAtEndOfEpoch(context.Background(), "party1", "node1", num.NewUint(1))
  1802  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 2})
  1803  
  1804  	require.NotContains(t, testEngine.engine.autoDelegationMode, "party1")
  1805  	require.Contains(t, testEngine.engine.autoDelegationMode, "party2")
  1806  }
  1807  
  1808  func testCheckPartyExitingAutoDelegationThroughUndelegateNow(t *testing.T) {
  1809  	testEngine := getEngine(t)
  1810  	setupDefaultDelegationState(testEngine, 10, 5)
  1811  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 1})
  1812  	require.Contains(t, testEngine.engine.autoDelegationMode, "party1")
  1813  	require.Contains(t, testEngine.engine.autoDelegationMode, "party2")
  1814  
  1815  	testEngine.engine.onEpochEvent(context.Background(), types.Epoch{Seq: 2})
  1816  	testEngine.engine.UndelegateNow(context.Background(), "party1", "node1", num.NewUint(1))
  1817  	require.NotContains(t, testEngine.engine.autoDelegationMode, "party1")
  1818  	require.Contains(t, testEngine.engine.autoDelegationMode, "party2")
  1819  
  1820  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 2})
  1821  	require.NotContains(t, testEngine.engine.autoDelegationMode, "party1")
  1822  	require.Contains(t, testEngine.engine.autoDelegationMode, "party2")
  1823  }
  1824  
  1825  func testPartyInAutoDelegateModeWithManualIntervention(t *testing.T) {
  1826  	testEngine := getEngine(t)
  1827  
  1828  	// epoch 0 - setup delegations
  1829  	testEngine.engine.onEpochEvent(context.Background(), types.Epoch{Seq: 0})
  1830  	testEngine.topology.nodeToIsValidator["node1"] = true
  1831  	testEngine.topology.nodeToIsValidator["node2"] = true
  1832  	testEngine.topology.nodeToIsValidator["node3"] = true
  1833  	testEngine.topology.nodeToIsValidator["node4"] = true
  1834  	testEngine.topology.nodeToIsValidator["node5"] = true
  1835  	testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(1000)
  1836  	testEngine.stakingAccounts.partyToStake["party2"] = num.NewUint(1000)
  1837  	testEngine.stakingAccounts.partyToStake["node1"] = num.NewUint(10000)
  1838  	testEngine.stakingAccounts.partyToStake["node2"] = num.NewUint(10000)
  1839  	testEngine.stakingAccounts.partyToStake["node3"] = num.NewUint(10000)
  1840  	testEngine.stakingAccounts.partyToStake["node4"] = num.NewUint(10000)
  1841  	testEngine.stakingAccounts.partyToStake["node5"] = num.NewUint(10000)
  1842  
  1843  	testEngine.engine.Delegate(context.Background(), "node1", "node1", num.NewUint(10000))
  1844  	testEngine.engine.Delegate(context.Background(), "node2", "node2", num.NewUint(10000))
  1845  	testEngine.engine.Delegate(context.Background(), "node3", "node3", num.NewUint(10000))
  1846  	testEngine.engine.Delegate(context.Background(), "node4", "node4", num.NewUint(10000))
  1847  	testEngine.engine.Delegate(context.Background(), "node5", "node5", num.NewUint(10000))
  1848  
  1849  	testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(400))
  1850  	testEngine.engine.Delegate(context.Background(), "party1", "node2", num.NewUint(600))
  1851  	testEngine.engine.Delegate(context.Background(), "party2", "node1", num.NewUint(800))
  1852  	testEngine.engine.Delegate(context.Background(), "party2", "node2", num.NewUint(150))
  1853  
  1854  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 0})
  1855  
  1856  	require.Contains(t, testEngine.engine.autoDelegationMode, "party1")
  1857  	require.Contains(t, testEngine.engine.autoDelegationMode, "party2")
  1858  
  1859  	// // start epoch 1
  1860  	testEngine.engine.onEpochEvent(context.Background(), types.Epoch{Seq: 1})
  1861  	// increase association of party1 and party2
  1862  	testEngine.stakingAccounts.partyToStake["party1"].AddSum(num.NewUint(1000))
  1863  	testEngine.stakingAccounts.partyToStake["party2"].AddSum(num.NewUint(1500))
  1864  	testEngine.engine.Delegate(context.Background(), "party1", "node1", num.NewUint(100))
  1865  
  1866  	testEngine.engine.ProcessEpochDelegations(context.Background(), types.Epoch{Seq: 1})
  1867  	require.Contains(t, testEngine.engine.autoDelegationMode, "party1")
  1868  	require.Contains(t, testEngine.engine.autoDelegationMode, "party2")
  1869  
  1870  	// party1 has delegated during the epoch so they don't qualify for auto delegation. party1 had 6 and 4 respectively to node1 and node2 and they manually
  1871  	// delegate 5 more to node 1
  1872  	require.Equal(t, num.NewUint(1100), testEngine.engine.partyDelegationState["party1"].totalDelegated)
  1873  	require.Equal(t, num.NewUint(500), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node1"])
  1874  	require.Equal(t, num.NewUint(600), testEngine.engine.partyDelegationState["party1"].nodeToAmount["node2"])
  1875  
  1876  	// party2 has not delegated during the epoch so their newly available stake gets auto delegated
  1877  	// party2 had a delegation of 800 to node1 and 150 to node 2,
  1878  	// the same distribution is applied on the additional 1550 tokens and now they should have additional 1305 and 244 to node 1 and node 2 respectively
  1879  	require.Equal(t, num.NewUint(2499), testEngine.engine.partyDelegationState["party2"].totalDelegated)
  1880  	require.Equal(t, num.NewUint(2105), testEngine.engine.partyDelegationState["party2"].nodeToAmount["node1"])
  1881  	require.Equal(t, num.NewUint(394), testEngine.engine.partyDelegationState["party2"].nodeToAmount["node2"])
  1882  }
  1883  
  1884  func testSortActive(t *testing.T) {
  1885  	rand.Seed(time.Now().UnixNano())
  1886  	for k := 0; k < 100; k++ {
  1887  		testEngine := getEngine(t)
  1888  		for j := 0; j < 5; j++ {
  1889  			active := []*types.DelegationEntry{}
  1890  			var epochSeq uint64 = 1
  1891  
  1892  			active = append(active, &types.DelegationEntry{
  1893  				Party:    "party1",
  1894  				Node:     "node1",
  1895  				Amount:   num.NewUint(100),
  1896  				EpochSeq: epochSeq,
  1897  			})
  1898  			active = append(active, &types.DelegationEntry{
  1899  				Party:    "party1",
  1900  				Node:     "node2",
  1901  				Amount:   num.NewUint(200),
  1902  				EpochSeq: epochSeq,
  1903  			})
  1904  			active = append(active, &types.DelegationEntry{
  1905  				Party:    "party2",
  1906  				Node:     "node1",
  1907  				Amount:   num.NewUint(300),
  1908  				EpochSeq: epochSeq,
  1909  			})
  1910  			active = append(active, &types.DelegationEntry{
  1911  				Party:    "party2",
  1912  				Node:     "node2",
  1913  				Amount:   num.NewUint(400),
  1914  				EpochSeq: epochSeq,
  1915  			})
  1916  
  1917  			rand.Shuffle(len(active), func(i, j int) { active[i], active[j] = active[j], active[i] })
  1918  
  1919  			testEngine.engine.sortActive(active)
  1920  			require.Equal(t, "party1", active[0].Party)
  1921  			require.Equal(t, "node1", active[0].Node)
  1922  			require.Equal(t, "party1", active[1].Party)
  1923  			require.Equal(t, "node2", active[1].Node)
  1924  			require.Equal(t, "party2", active[2].Party)
  1925  			require.Equal(t, "node1", active[2].Node)
  1926  			require.Equal(t, "party2", active[3].Party)
  1927  			require.Equal(t, "node2", active[3].Node)
  1928  		}
  1929  	}
  1930  }
  1931  
  1932  func testCheckpointRoundTripNoPending(t *testing.T) {
  1933  	ctx := context.Background()
  1934  	for i := 0; i < 100; i++ {
  1935  		testEngine := getEngine(t)
  1936  		testEngine.broker.EXPECT().SendBatch(gomock.Any()).Times(2)
  1937  		setupDefaultDelegationState(testEngine, 12, 7)
  1938  
  1939  		checkpoint, err := testEngine.engine.Checkpoint()
  1940  		require.Nil(t, err)
  1941  
  1942  		testEngine.engine.Load(ctx, checkpoint)
  1943  		checkpoint2, err := testEngine.engine.Checkpoint()
  1944  		require.Nil(t, err)
  1945  		require.True(t, bytes.Equal(checkpoint, checkpoint2))
  1946  	}
  1947  }
  1948  
  1949  func testCheckpointRoundTripOnlyPending(t *testing.T) {
  1950  	ctx := context.Background()
  1951  	for i := 0; i < 100; i++ {
  1952  		testEngine := getEngine(t)
  1953  		testEngine.broker.EXPECT().SendBatch(gomock.Any()).Times(1)
  1954  
  1955  		testEngine.topology.nodeToIsValidator["node1"] = true
  1956  		testEngine.topology.nodeToIsValidator["node2"] = true
  1957  		testEngine.stakingAccounts.partyToStake["party1"] = num.NewUint(100)
  1958  		testEngine.stakingAccounts.partyToStake["party2"] = num.NewUint(200)
  1959  
  1960  		engine := testEngine.engine
  1961  		err := engine.Delegate(context.Background(), "party1", "node1", num.NewUint(60))
  1962  		require.Nil(t, err)
  1963  		err = engine.Delegate(context.Background(), "party1", "node2", num.NewUint(40))
  1964  		require.Nil(t, err)
  1965  
  1966  		err = engine.Delegate(context.Background(), "party2", "node1", num.NewUint(70))
  1967  		require.Nil(t, err)
  1968  		err = engine.Delegate(context.Background(), "party2", "node2", num.NewUint(130))
  1969  		require.Nil(t, err)
  1970  
  1971  		checkpoint, err := testEngine.engine.Checkpoint()
  1972  		require.Nil(t, err)
  1973  
  1974  		testEngine.engine.Load(ctx, checkpoint)
  1975  		checkpoint2, err := testEngine.engine.Checkpoint()
  1976  		require.Nil(t, err)
  1977  		require.True(t, bytes.Equal(checkpoint, checkpoint2))
  1978  	}
  1979  }
  1980  
  1981  func getEngine(t *testing.T) *testEngine {
  1982  	t.Helper()
  1983  	conf := NewDefaultConfig()
  1984  	ctrl := gomock.NewController(t)
  1985  	broker := mocks.NewMockBroker(ctrl)
  1986  	logger := logging.NewTestLogger()
  1987  	stakingAccounts := newTestStakingAccount()
  1988  	topology := newTestTopology()
  1989  	ts := dmocks.NewMockTimeService(ctrl)
  1990  
  1991  	engine := New(logger, conf, broker, topology, stakingAccounts, &TestEpochEngine{}, ts)
  1992  	engine.onEpochEvent(context.Background(), types.Epoch{Seq: 1, StartTime: time.Now()})
  1993  	engine.OnMinAmountChanged(context.Background(), num.NewDecimalFromFloat(2))
  1994  	broker.EXPECT().Send(gomock.Any()).AnyTimes()
  1995  
  1996  	return &testEngine{
  1997  		engine:          engine,
  1998  		ctrl:            ctrl,
  1999  		broker:          broker,
  2000  		stakingAccounts: stakingAccounts,
  2001  		topology:        topology,
  2002  	}
  2003  }
  2004  
  2005  type TestEpochEngine struct{}
  2006  
  2007  func (t *TestEpochEngine) NotifyOnEpoch(f func(context.Context, types.Epoch), r func(context.Context, types.Epoch)) {
  2008  }
  2009  
  2010  type TestStakingAccount struct {
  2011  	partyToStake         map[string]*num.Uint
  2012  	partyToStakeForEpoch map[int64]map[string]*num.Uint
  2013  }
  2014  
  2015  func newTestStakingAccount() *TestStakingAccount {
  2016  	return &TestStakingAccount{
  2017  		partyToStake:         make(map[string]*num.Uint),
  2018  		partyToStakeForEpoch: make(map[int64]map[string]*num.Uint),
  2019  	}
  2020  }
  2021  
  2022  func (t *TestStakingAccount) GetAvailableBalance(party string) (*num.Uint, error) {
  2023  	ret, ok := t.partyToStake[party]
  2024  	if !ok {
  2025  		return nil, fmt.Errorf("account not found")
  2026  	}
  2027  	return ret, nil
  2028  }
  2029  
  2030  func (t *TestStakingAccount) GetAvailableBalanceInRange(party string, from, to time.Time) (*num.Uint, error) {
  2031  	ret, ok := t.partyToStakeForEpoch[from.UnixNano()]
  2032  	if !ok {
  2033  		return nil, fmt.Errorf("account not found")
  2034  	}
  2035  
  2036  	p, ok := ret[party]
  2037  	if !ok {
  2038  		return nil, fmt.Errorf("account not found")
  2039  	}
  2040  	return p, nil
  2041  }
  2042  
  2043  type TestTopology struct {
  2044  	nodeToIsValidator map[string]bool
  2045  }
  2046  
  2047  func newTestTopology() *TestTopology {
  2048  	return &TestTopology{
  2049  		nodeToIsValidator: make(map[string]bool),
  2050  	}
  2051  }
  2052  
  2053  func (tt *TestTopology) IsValidatorNodeID(nodeID string) bool {
  2054  	v, ok := tt.nodeToIsValidator[nodeID]
  2055  	return ok && v
  2056  }
  2057  
  2058  func (tt *TestTopology) AllNodeIDs() []string {
  2059  	return []string{"node1", "node2", "node3", "node4", "node5"}
  2060  }
  2061  
  2062  func (tt *TestTopology) Get(key string) *validators.ValidatorData {
  2063  	return &validators.ValidatorData{
  2064  		ID:         key,
  2065  		VegaPubKey: key,
  2066  		TmPubKey:   key,
  2067  	}
  2068  }