From 070bda3a2534f961138940819d77a4a62a68ecba Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Wed, 17 Oct 2018 00:55:36 -0400 Subject: [PATCH] Merge PR #2515: Fix gov deposit query lcd non-determinism * non deterministic addr ordering * sorted addrs at gen * fixed comment * fixed names and passwords --- client/lcd/lcd_test.go | 54 ++++++++++++++++---------------- client/lcd/test_helpers.go | 64 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 28 deletions(-) diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index f675afe14..94174398d 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -717,55 +717,53 @@ func TestUnjail(t *testing.T) { } func TestProposalsQuery(t *testing.T) { - name, password1 := "test", "1234567890" - name2, password2 := "test2", "1234567890" - addr, seed := CreateAddr(t, "test", password1, GetKeyBase(t)) - addr2, seed2 := CreateAddr(t, "test2", password2, GetKeyBase(t)) - cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr, addr2}) + addrs, seeds, names, passwords := CreateAddrs(t, GetKeyBase(t), 2) + + cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addrs[0], addrs[1]}) defer cleanup() // Addr1 proposes (and deposits) proposals #1 and #2 - resultTx := doSubmitProposal(t, port, seed, name, password1, addr, 5) + resultTx := doSubmitProposal(t, port, seeds[0], names[0], passwords[0], addrs[0], 5) var proposalID1 int64 cdc.UnmarshalBinaryBare(resultTx.DeliverTx.GetData(), &proposalID1) tests.WaitForHeight(resultTx.Height+1, port) - resultTx = doSubmitProposal(t, port, seed, name, password1, addr, 5) + resultTx = doSubmitProposal(t, port, seeds[0], names[0], passwords[0], addrs[0], 5) var proposalID2 int64 cdc.UnmarshalBinaryBare(resultTx.DeliverTx.GetData(), &proposalID2) tests.WaitForHeight(resultTx.Height+1, port) // Addr2 proposes (and deposits) proposals #3 - resultTx = doSubmitProposal(t, port, seed2, name2, password2, addr2, 5) + resultTx = doSubmitProposal(t, port, seeds[1], names[1], passwords[1], addrs[1], 5) var proposalID3 int64 cdc.UnmarshalBinaryBare(resultTx.DeliverTx.GetData(), &proposalID3) tests.WaitForHeight(resultTx.Height+1, port) // Addr2 deposits on proposals #2 & #3 - resultTx = doDeposit(t, port, seed2, name2, password2, addr2, proposalID2, 5) + resultTx = doDeposit(t, port, seeds[1], names[1], passwords[1], addrs[1], proposalID2, 5) tests.WaitForHeight(resultTx.Height+1, port) - resultTx = doDeposit(t, port, seed2, name2, password2, addr2, proposalID3, 5) + resultTx = doDeposit(t, port, seeds[1], names[1], passwords[1], addrs[1], proposalID3, 5) tests.WaitForHeight(resultTx.Height+1, port) // check deposits match proposal and individual deposits deposits := getDeposits(t, port, proposalID1) require.Len(t, deposits, 1) - deposit := getDeposit(t, port, proposalID1, addr) + deposit := getDeposit(t, port, proposalID1, addrs[0]) require.Equal(t, deposit, deposits[0]) deposits = getDeposits(t, port, proposalID2) require.Len(t, deposits, 2) - deposit = getDeposit(t, port, proposalID2, addr) - require.Equal(t, deposit, deposits[0]) - deposit = getDeposit(t, port, proposalID2, addr2) - require.Equal(t, deposit, deposits[1]) + deposit = getDeposit(t, port, proposalID2, addrs[0]) + require.True(t, deposit.Equals(deposits[0])) + deposit = getDeposit(t, port, proposalID2, addrs[1]) + require.True(t, deposit.Equals(deposits[1])) deposits = getDeposits(t, port, proposalID3) require.Len(t, deposits, 1) - deposit = getDeposit(t, port, proposalID3, addr2) + deposit = getDeposit(t, port, proposalID3, addrs[1]) require.Equal(t, deposit, deposits[0]) // increasing the amount of the deposit should update the existing one - resultTx = doDeposit(t, port, seed, name, password1, addr, proposalID1, 1) + resultTx = doDeposit(t, port, seeds[0], names[0], passwords[0], addrs[0], proposalID1, 1) tests.WaitForHeight(resultTx.Height+1, port) deposits = getDeposits(t, port, proposalID1) @@ -782,13 +780,13 @@ func TestProposalsQuery(t *testing.T) { require.Equal(t, proposalID3, proposals[1].GetProposalID()) // Addr1 votes on proposals #2 & #3 - resultTx = doVote(t, port, seed, name, password1, addr, proposalID2) + resultTx = doVote(t, port, seeds[0], names[0], passwords[0], addrs[0], proposalID2) tests.WaitForHeight(resultTx.Height+1, port) - resultTx = doVote(t, port, seed, name, password1, addr, proposalID3) + resultTx = doVote(t, port, seeds[0], names[0], passwords[0], addrs[0], proposalID3) tests.WaitForHeight(resultTx.Height+1, port) // Addr2 votes on proposal #3 - resultTx = doVote(t, port, seed2, name2, password2, addr2, proposalID3) + resultTx = doVote(t, port, seeds[1], names[1], passwords[1], addrs[1], proposalID3) tests.WaitForHeight(resultTx.Height+1, port) // Test query all proposals @@ -798,37 +796,37 @@ func TestProposalsQuery(t *testing.T) { require.Equal(t, proposalID3, (proposals[2]).GetProposalID()) // Test query deposited by addr1 - proposals = getProposalsFilterDepositer(t, port, addr) + proposals = getProposalsFilterDepositer(t, port, addrs[0]) require.Equal(t, proposalID1, (proposals[0]).GetProposalID()) // Test query deposited by addr2 - proposals = getProposalsFilterDepositer(t, port, addr2) + proposals = getProposalsFilterDepositer(t, port, addrs[1]) require.Equal(t, proposalID2, (proposals[0]).GetProposalID()) require.Equal(t, proposalID3, (proposals[1]).GetProposalID()) // Test query voted by addr1 - proposals = getProposalsFilterVoter(t, port, addr) + proposals = getProposalsFilterVoter(t, port, addrs[0]) require.Equal(t, proposalID2, (proposals[0]).GetProposalID()) require.Equal(t, proposalID3, (proposals[1]).GetProposalID()) // Test query voted by addr2 - proposals = getProposalsFilterVoter(t, port, addr2) + proposals = getProposalsFilterVoter(t, port, addrs[1]) require.Equal(t, proposalID3, (proposals[0]).GetProposalID()) // Test query voted and deposited by addr1 - proposals = getProposalsFilterVoterDepositer(t, port, addr, addr) + proposals = getProposalsFilterVoterDepositer(t, port, addrs[0], addrs[0]) require.Equal(t, proposalID2, (proposals[0]).GetProposalID()) // Test query votes on Proposal 2 votes := getVotes(t, port, proposalID2) require.Len(t, votes, 1) - require.Equal(t, addr, votes[0].Voter) + require.Equal(t, addrs[0], votes[0].Voter) // Test query votes on Proposal 3 votes = getVotes(t, port, proposalID3) require.Len(t, votes, 2) - require.True(t, addr.String() == votes[0].Voter.String() || addr.String() == votes[1].Voter.String()) - require.True(t, addr2.String() == votes[0].Voter.String() || addr2.String() == votes[1].Voter.String()) + require.True(t, addrs[0].String() == votes[0].Voter.String() || addrs[0].String() == votes[1].Voter.String()) + require.True(t, addrs[1].String() == votes[0].Voter.String() || addrs[1].String() == votes[1].Voter.String()) } //_____________________________________________________________________________ diff --git a/client/lcd/test_helpers.go b/client/lcd/test_helpers.go index cd48b89ea..3585023cd 100644 --- a/client/lcd/test_helpers.go +++ b/client/lcd/test_helpers.go @@ -9,6 +9,7 @@ import ( "net/http" "os" "path/filepath" + "sort" "strings" "testing" @@ -111,6 +112,69 @@ func CreateAddr(t *testing.T, name, password string, kb crkeys.Keybase) (sdk.Acc return sdk.AccAddress(info.GetPubKey().Address()), seed } +// Type that combines an Address with the pnemonic of the private key to that address +type AddrSeed struct { + Address sdk.AccAddress + Seed string + Name string + Password string +} + +// CreateAddr adds multiple address to the key store and returns the addresses and associated seeds in lexographical order by address. +// It also requires that the keys could be created. +func CreateAddrs(t *testing.T, kb crkeys.Keybase, numAddrs int) (addrs []sdk.AccAddress, seeds, names, passwords []string) { + var ( + err error + info crkeys.Info + seed string + ) + + addrSeeds := AddrSeedSlice{} + + for i := 0; i < numAddrs; i++ { + name := fmt.Sprintf("test%d", i) + password := "1234567890" + info, seed, err = kb.CreateMnemonic(name, crkeys.English, password, crkeys.Secp256k1) + require.NoError(t, err) + addrSeeds = append(addrSeeds, AddrSeed{Address: sdk.AccAddress(info.GetPubKey().Address()), Seed: seed, Name: name, Password: password}) + } + + sort.Sort(addrSeeds) + + for i := range addrSeeds { + addrs = append(addrs, addrSeeds[i].Address) + seeds = append(seeds, addrSeeds[i].Seed) + names = append(names, addrSeeds[i].Name) + passwords = append(passwords, addrSeeds[i].Password) + } + + return addrs, seeds, names, passwords +} + +// implement `Interface` in sort package. +type AddrSeedSlice []AddrSeed + +func (b AddrSeedSlice) Len() int { + return len(b) +} + +// Sorts lexographically by Address +func (b AddrSeedSlice) Less(i, j int) bool { + // bytes package already implements Comparable for []byte. + switch bytes.Compare(b[i].Address.Bytes(), b[j].Address.Bytes()) { + case -1: + return true + case 0, 1: + return false + default: + panic("not fail-able with `bytes.Comparable` bounded [-1, 1].") + } +} + +func (b AddrSeedSlice) Swap(i, j int) { + b[j], b[i] = b[i], b[j] +} + // InitializeTestLCD starts Tendermint and the LCD in process, listening on // their respective sockets where nValidators is the total number of validators // and initAddrs are the accounts to initialize with some steak tokens. It