code.vegaprotocol.io/vega@v0.79.0/core/integration/steps/the_vesting_stats_should_be.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 steps 17 18 import ( 19 "errors" 20 "fmt" 21 "strings" 22 23 "code.vegaprotocol.io/vega/core/integration/stubs" 24 eventspb "code.vegaprotocol.io/vega/protos/vega/events/v1" 25 26 "github.com/cucumber/godog" 27 "golang.org/x/exp/maps" 28 "golang.org/x/exp/slices" 29 ) 30 31 func TheVestingStatsShouldBe(broker *stubs.BrokerStub, epochStr string, table *godog.Table) error { 32 epoch, err := U64(epochStr) 33 if err != nil { 34 return fmt.Errorf("could not parse epoch: %w", err) 35 } 36 37 expectedVestingStatsStats, err := parseVestingStatsShouldBeTable(table) 38 if err != nil { 39 return fmt.Errorf("table is invalid: %w", err) 40 } 41 42 vestingStats := broker.VestingStats() 43 44 foundStreaksForEpoch := map[string]eventspb.PartyVestingStats{} 45 for _, stats := range vestingStats { 46 if stats.AtEpoch == epoch { 47 return compareVestingStats(expectedVestingStatsStats, foundStreaksForEpoch) 48 } 49 } 50 51 return fmt.Errorf("no vesting stats found for epoch %q", epochStr) 52 } 53 54 func parseVestingStatsShouldBeTable(table *godog.Table) (map[string]eventspb.PartyVestingStats, error) { 55 rows := StrictParseTable(table, []string{ 56 "party", 57 "reward bonus multiplier", 58 }, []string{}) 59 60 stats := map[string]eventspb.PartyVestingStats{} 61 for _, row := range rows { 62 specificRow := newVestingStatsShouldBeRow(row) 63 partyID := specificRow.Party() 64 _, alreadyRegistered := stats[partyID] 65 if alreadyRegistered { 66 return nil, fmt.Errorf("cannot have more than one expectation for party %q", partyID) 67 } 68 stats[partyID] = eventspb.PartyVestingStats{ 69 PartyId: partyID, 70 RewardBonusMultiplier: specificRow.RewardBonusMultiplier(), 71 } 72 } 73 74 return stats, nil 75 } 76 77 func compareVestingStats(expectedVestingStats map[string]eventspb.PartyVestingStats, foundVestingStats map[string]eventspb.PartyVestingStats) error { 78 foundVestingStatsIDs := maps.Keys(expectedVestingStats) 79 expectedVestingStatsIDs := maps.Keys(expectedVestingStats) 80 81 slices.Sort(foundVestingStatsIDs) 82 slices.Sort(expectedVestingStatsIDs) 83 84 unexpectedParties := []string{} 85 partiesNotFound := []string{} 86 87 for _, expectedID := range expectedVestingStatsIDs { 88 if _, ok := foundVestingStats[expectedID]; !ok { 89 partiesNotFound = append(partiesNotFound, expectedID) 90 } 91 } 92 93 for _, foundID := range foundVestingStatsIDs { 94 if _, ok := expectedVestingStats[foundID]; !ok { 95 unexpectedParties = append(unexpectedParties, foundID) 96 } 97 } 98 99 var errStr string 100 if len(partiesNotFound) > 0 { 101 errStr = "parties not found: " + strings.Join(partiesNotFound, ", ") 102 } 103 if len(unexpectedParties) > 0 { 104 if errStr != "" { 105 errStr += ", and " 106 } 107 errStr += "unexpected parties: " + strings.Join(unexpectedParties, ", ") 108 } 109 if errStr != "" { 110 return errors.New(errStr) 111 } 112 113 for _, party := range expectedVestingStatsIDs { 114 foundActivityStreak := foundVestingStats[party] 115 expectedActivityStreak := expectedVestingStats[party] 116 117 if expectedActivityStreak.RewardBonusMultiplier != foundActivityStreak.RewardBonusMultiplier { 118 return formatDiff( 119 fmt.Sprintf("vesting stats did not match for party %q", party), 120 map[string]string{ 121 "reward bonus multiplier": expectedActivityStreak.RewardBonusMultiplier, 122 }, 123 map[string]string{ 124 "reward bonus multiplier": foundActivityStreak.RewardBonusMultiplier, 125 }, 126 ) 127 } 128 } 129 130 return nil 131 } 132 133 type vestingStatsShouldBeRow struct { 134 row RowWrapper 135 } 136 137 func newVestingStatsShouldBeRow(r RowWrapper) vestingStatsShouldBeRow { 138 return vestingStatsShouldBeRow{ 139 row: r, 140 } 141 } 142 143 func (r vestingStatsShouldBeRow) Party() string { 144 return r.row.MustStr("party") 145 } 146 147 func (r vestingStatsShouldBeRow) RewardBonusMultiplier() string { 148 return r.row.MustStr("reward bonus multiplier") 149 }