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 }