diff options
Diffstat (limited to 'test/e2e-go/features/participation/accountParticipationTransitions_test.go')
-rw-r--r-- | test/e2e-go/features/participation/accountParticipationTransitions_test.go | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/test/e2e-go/features/participation/accountParticipationTransitions_test.go b/test/e2e-go/features/participation/accountParticipationTransitions_test.go new file mode 100644 index 000000000..606ae7ce7 --- /dev/null +++ b/test/e2e-go/features/participation/accountParticipationTransitions_test.go @@ -0,0 +1,126 @@ +// Copyright (C) 2019-2021 Algorand, Inc. +// This file is part of go-algorand +// +// go-algorand is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// go-algorand is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with go-algorand. If not, see <https://www.gnu.org/licenses/>. + +package participation + +// Tests in this file are focused on testing how a specific account uses and +// manages its participation keys. DevMode is used to make things more +// deterministic. + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/algorand/go-algorand/daemon/algod/api/server/v2/generated" + "github.com/algorand/go-algorand/data/account" + "github.com/algorand/go-algorand/libgoal" + "github.com/algorand/go-algorand/test/framework/fixtures" + "github.com/algorand/go-algorand/test/partitiontest" +) + +// installParticipationKey generates a new key for a given account and installs it with the client. +func installParticipationKey(t *testing.T, client libgoal.Client, addr string, firstValid, lastValid uint64) (resp generated.PostParticipationResponse, part account.Participation, err error) { + dir, err := ioutil.TempDir("", "temporary_partkey_dir") + require.NoError(t, err) + defer os.RemoveAll(dir) + + // Install overlapping participation keys... + part, filePath, err := client.GenParticipationKeysTo(addr, firstValid, lastValid, 100, dir) + require.NoError(t, err) + require.NotNil(t, filePath) + require.Equal(t, addr, part.Parent.String()) + + resp, err = client.AddParticipationKey(filePath) + return +} + +func registerParticipationAndWait(t *testing.T, client libgoal.Client, part account.Participation) generated.NodeStatusResponse { + txParams, err := client.SuggestedParams() + require.NoError(t, err) + sAccount := part.Address().String() + sWH, err := client.GetUnencryptedWalletHandle() + require.NoError(t, err) + goOnlineTx, err := client.MakeUnsignedGoOnlineTx(sAccount, &part, txParams.LastRound+1, txParams.LastRound+1, txParams.Fee, [32]byte{}) + require.NoError(t, err) + require.Equal(t, sAccount, goOnlineTx.Src().String()) + onlineTxID, err := client.SignAndBroadcastTransaction(sWH, nil, goOnlineTx) + require.NoError(t, err) + require.NotEmpty(t, onlineTxID) + status, err := client.WaitForRound(txParams.LastRound) + require.NoError(t, err) + return status +} + +func TestKeyRegistration(t *testing.T) { + partitiontest.PartitionTest(t) + + if testing.Short() { + t.Skip() + } + + t.Parallel() + + // Start devmode network and initialize things for the test. + var fixture fixtures.RestClientFixture + fixture.SetupNoStart(t, filepath.Join("nettemplates", "DevModeOneWallet.json")) + fixture.Start() + sClient := fixture.GetLibGoalClientForNamedNode("Node") + minTxnFee, _, err := fixture.MinFeeAndBalance(0) + require.NoError(t, err) + accountResponse, err := fixture.GetRichestAccount() + require.NoError(t, err) + sAccount := accountResponse.Address + + // Add an overlapping participation keys for the account on round 1 and 2 + last := uint64(6_000_000) + numNew := 2 + for i := 0; i < numNew; i++ { + response, part, err := installParticipationKey(t, sClient, sAccount, 0, last) + require.NoError(t, err) + require.NotNil(t, response) + registerParticipationAndWait(t, sClient, part) + } + + // Make sure the new keys are installed. + keys, err := fixture.LibGoalClient.GetParticipationKeys() + require.NoError(t, err) + require.Len(t, keys, numNew+1) + + // Zip ahead MaxBalLookback. + params, err := fixture.CurrentConsensusParams() + require.NoError(t, err) + lookback := params.MaxBalLookback + for i := uint64(1); i < lookback; i++ { + fixture.SendMoneyAndWait(2+i, 0, minTxnFee, sAccount, sAccount, "") + } + + keys, err = fixture.LibGoalClient.GetParticipationKeys() + require.Equal(t, *(keys[0].EffectiveFirstValid), uint64(1)) + require.Equal(t, *(keys[0].EffectiveLastValid), lookback) + require.Equal(t, *(keys[0].LastBlockProposal), lookback) + + require.Equal(t, *(keys[1].EffectiveFirstValid), lookback+1) + require.Equal(t, *(keys[1].EffectiveLastValid), lookback+1) + require.Equal(t, *(keys[1].LastBlockProposal), lookback+1) + + require.Equal(t, *(keys[2].EffectiveFirstValid), lookback+2) + require.Equal(t, *(keys[2].EffectiveLastValid), last) + require.Equal(t, *(keys[2].LastBlockProposal), lookback+2) +} |