code.vegaprotocol.io/vega@v0.79.0/core/governance/market_cp_restore_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 governance_test 17 18 import ( 19 "context" 20 "encoding/base64" 21 "encoding/json" 22 "testing" 23 "time" 24 25 "code.vegaprotocol.io/vega/core/assets" 26 amocks "code.vegaprotocol.io/vega/core/assets/mocks" 27 bmocks "code.vegaprotocol.io/vega/core/broker/mocks" 28 "code.vegaprotocol.io/vega/core/checkpoint" 29 "code.vegaprotocol.io/vega/core/collateral" 30 "code.vegaprotocol.io/vega/core/execution" 31 "code.vegaprotocol.io/vega/core/execution/common" 32 emocks "code.vegaprotocol.io/vega/core/execution/common/mocks" 33 fmocks "code.vegaprotocol.io/vega/core/fee/mocks" 34 "code.vegaprotocol.io/vega/core/governance" 35 "code.vegaprotocol.io/vega/core/governance/mocks" 36 "code.vegaprotocol.io/vega/core/netparams" 37 "code.vegaprotocol.io/vega/core/nodewallets" 38 "code.vegaprotocol.io/vega/core/types" 39 "code.vegaprotocol.io/vega/libs/num" 40 "code.vegaprotocol.io/vega/libs/proto" 41 vgrand "code.vegaprotocol.io/vega/libs/rand" 42 vgtesting "code.vegaprotocol.io/vega/libs/testing" 43 "code.vegaprotocol.io/vega/logging" 44 "code.vegaprotocol.io/vega/paths" 45 checkpointpb "code.vegaprotocol.io/vega/protos/vega/checkpoint/v1" 46 47 "github.com/golang/mock/gomock" 48 "github.com/pkg/errors" 49 "github.com/stretchr/testify/require" 50 51 _ "embed" 52 ) 53 54 //go:embed testcp/checkpoint.cp 55 var cpFile []byte 56 57 //go:embed testcp/scp.cp 58 var cpSuccessorFile []byte 59 60 // Disable 'TestMarketRestoreFromCheckpoint' for now. 'testcp/checkpoint.cp' needs to be regenerated for the new data sourcing types. 61 // Rest of functions disabled because linter complains. 62 63 func TestMarketRestoreFromCheckpoint(t *testing.T) { 64 t.Skipf("Skipping test as need to regenerate testcp/checkpoint.cp with appropriate values for LP - Zohar to fix") 65 now := time.Now() 66 ex, gov, cpEng := createExecutionEngine(t, now) 67 genesis := &checkpoint.GenesisState{ 68 CheckpointHash: "b60aa26b5b167ecf72620778b481a65d029367c1a56bd280b55614b5586f3e8c", 69 CheckpointState: base64.StdEncoding.EncodeToString(cpFile), 70 } 71 gd := &struct { 72 Checkpoint *checkpoint.GenesisState `json:"checkpoint"` 73 }{} 74 75 gd.Checkpoint = genesis 76 gdBytes, _ := json.Marshal(gd) 77 78 require.NoError(t, cpEng.UponGenesis(context.Background(), gdBytes)) 79 80 expectedMarkets := []string{ 81 "86948f946a64e14bb2e284f825cd46879d1cb581ce405cc62e4f74fcded190d3", 82 "3fed7242cce2cbe7df8cc3a2808969fc6e108f2047838c4af323c10430dfe041", 83 "5ed56476934d952229c0d796e143be4d1a96871d1607f9188dfa3727bdd6f7a0", 84 "2bf3cab7a239f34f40145a0700f8f12bc504bd2ec3a65d5915c4e58881dfcb52", 85 "eda61c9948ae97182c344b6a900e960a6c85271a4db1926eb26c82d847d9ba78", 86 "954410d873a6d1a419b8a11e7e3a5178f65b976f3140bb78fc97d21daf08877f", 87 "14719259af09239e479c107c6a69dbdae05dbde619ad06632af27a2fc2c9a9c7", 88 "3201812426fed4cc6d5cfbacdaa54e738791deb9f72743f8b18d3e9f6a3e222c", 89 } 90 govProposalsCP, _ := gov.Checkpoint() 91 proposals := &checkpointpb.Proposals{} 92 err := proto.Unmarshal(govProposalsCP, proposals) 93 require.NoError(t, err) 94 require.Equal(t, len(expectedMarkets), len(proposals.Proposals)) 95 96 for i, expectedMarket := range expectedMarkets { 97 m, exists := ex.GetMarket(expectedMarket, false) 98 require.True(t, exists) 99 require.Equal(t, types.MarketTradingModeOpeningAuction, m.TradingMode) 100 require.Equal(t, types.MarketStatePending, m.State) 101 require.Equal(t, expectedMarket, proposals.Proposals[i].Id) 102 } 103 } 104 105 // Disable 'TestMarketRestoreFromCheckpoint' for now. 'testcp/scp.cp' needs to be regenerated for the new data sourcing types. 106 func TestMarketRestoreFromCheckpointWithEmptySuccessor(t *testing.T) { 107 t.Skipf("Skipping test as need to regenerate testcp/scp.cp with appropriate values for LP - Zohar to fix") 108 109 now := time.Now() 110 ex, gov, cpEng := createExecutionEngine(t, now) 111 genesis := &checkpoint.GenesisState{ 112 CheckpointHash: "45ff656ab5f434ceb47329d109874a8d81c7f987d1e08f913f22265a809da766", 113 CheckpointState: base64.StdEncoding.EncodeToString(cpSuccessorFile), 114 } 115 gd := &struct { 116 Checkpoint *checkpoint.GenesisState `json:"checkpoint"` 117 }{} 118 119 gd.Checkpoint = genesis 120 gdBytes, _ := json.Marshal(gd) 121 122 require.NoError(t, cpEng.UponGenesis(context.Background(), gdBytes)) 123 124 expectedMarkets := []string{ 125 "2dca7baa5f7269b08d053668bca03f97f72e9a162327eebd941c54f1f9fb8f80", 126 } 127 govProposalsCP, _ := gov.Checkpoint() 128 proposals := &checkpointpb.Proposals{} 129 err := proto.Unmarshal(govProposalsCP, proposals) 130 require.NoError(t, err) 131 proposedMarkets := []string{} 132 marketPropIDs := map[string]struct{}{} 133 for _, proposal := range proposals.Proposals { 134 if nm := proposal.Terms.GetNewMarket(); nm != nil { 135 proposedMarkets = append(proposedMarkets, proposal.Id) 136 marketPropIDs[proposal.Id] = struct{}{} 137 } 138 } 139 require.Equal(t, len(expectedMarkets), len(proposedMarkets)) 140 // this is a real cp file, we expect asset proposals etc... to be included, so 141 // the total number of proposals must be > just the market proposals 142 require.Less(t, len(expectedMarkets), len(proposals.Proposals)) 143 144 for _, expectedMarket := range expectedMarkets { 145 m, exists := ex.GetMarket(expectedMarket, false) 146 require.True(t, exists) 147 require.Equal(t, types.MarketTradingModeOpeningAuction, m.TradingMode) 148 require.Equal(t, types.MarketStatePending, m.State) 149 _, ok := marketPropIDs[expectedMarket] 150 require.True(t, ok) 151 } 152 } 153 154 func getNodeWallet() *nodewallets.NodeWallets { 155 vegaPaths, cleanupFn := vgtesting.NewVegaPaths() 156 defer cleanupFn() 157 registryPass := vgrand.RandomStr(10) 158 walletsPass := vgrand.RandomStr(10) 159 config := nodewallets.NewDefaultConfig() 160 createTestNodeWallets(vegaPaths, registryPass, walletsPass) 161 nw, _ := nodewallets.GetNodeWallets(config, vegaPaths, registryPass) 162 return nw 163 } 164 165 func createTestNodeWallets(vegaPaths paths.Paths, registryPass, walletPass string) { 166 if _, err := nodewallets.GenerateEthereumWallet(vegaPaths, registryPass, walletPass, "", false); err != nil { 167 panic("couldn't generate Ethereum node wallet for tests") 168 } 169 170 if _, err := nodewallets.GenerateVegaWallet(vegaPaths, registryPass, walletPass, false); err != nil { 171 panic("couldn't generate Vega node wallet for tests") 172 } 173 } 174 175 func createExecutionEngine(t *testing.T, tm time.Time) (*execution.Engine, *governance.Engine, *checkpoint.Engine) { 176 t.Helper() 177 ctrl := gomock.NewController(t) 178 log := logging.NewTestLogger() 179 executionConfig := execution.NewDefaultConfig() 180 broker := bmocks.NewMockBroker(ctrl) 181 broker.EXPECT().Send(gomock.Any()).AnyTimes() 182 broker.EXPECT().SendBatch(gomock.Any()).AnyTimes() 183 timeService := mocks.NewMockTimeService(ctrl) 184 timeService.EXPECT().GetTimeNow().Return(tm).AnyTimes() 185 186 collateralService := collateral.New(log, collateral.NewDefaultConfig(), timeService, broker) 187 oracleService := emocks.NewMockOracleEngine(ctrl) 188 oracleService.EXPECT().Subscribe(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() 189 190 statevar := emocks.NewMockStateVarEngine(ctrl) 191 statevar.EXPECT().RegisterStateVariable(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() 192 statevar.EXPECT().NewEvent(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() 193 194 epochEngine := emocks.NewMockEpochEngine(ctrl) 195 epochEngine.EXPECT().NotifyOnEpoch(gomock.Any(), gomock.Any()).Times(1) 196 197 primaryBridgeView := amocks.NewMockERC20BridgeView(ctrl) 198 secondaryBridgeView := amocks.NewMockERC20BridgeView(ctrl) 199 notary := amocks.NewMockNotary(ctrl) 200 201 asset, _ := assets.New(context.Background(), log, assets.NewDefaultConfig(), getNodeWallet().Ethereum, nil, nil, broker, primaryBridgeView, secondaryBridgeView, notary, false) 202 teams := emocks.NewMockTeams(ctrl) 203 bc := emocks.NewMockAccountBalanceChecker(ctrl) 204 marketTracker := common.NewMarketActivityTracker(log, teams, bc, broker, collateralService) 205 epochEngine.NotifyOnEpoch(marketTracker.OnEpochEvent, marketTracker.OnEpochRestore) 206 referralDiscountReward := fmocks.NewMockReferralDiscountRewardService(ctrl) 207 volumeDiscount := fmocks.NewMockVolumeDiscountService(ctrl) 208 volumeRebateService := fmocks.NewMockVolumeRebateService(ctrl) 209 referralDiscountReward.EXPECT().GetReferrer(gomock.Any()).Return(types.PartyID(""), errors.New("no referrer")).AnyTimes() 210 referralDiscountReward.EXPECT().ReferralDiscountFactorsForParty(gomock.Any()).Return(types.EmptyFactors).AnyTimes() 211 referralDiscountReward.EXPECT().RewardsFactorsMultiplierAppliedForParty(gomock.Any()).Return(types.EmptyFactors).AnyTimes() 212 volumeDiscount.EXPECT().VolumeDiscountFactorForParty(gomock.Any()).Return(num.DecimalZero()).AnyTimes() 213 execBanking := emocks.NewMockBanking(ctrl) 214 parties := emocks.NewMockParties(ctrl) 215 delayTarget := emocks.NewMockDelayTransactionsTarget(ctrl) 216 delayTarget.EXPECT().MarketDelayRequiredUpdated(gomock.Any(), gomock.Any()).AnyTimes() 217 exec := execution.NewEngine(log, executionConfig, timeService, collateralService, oracleService, broker, statevar, marketTracker, asset, referralDiscountReward, volumeDiscount, volumeRebateService, execBanking, parties, delayTarget) 218 accounts := mocks.NewMockStakingAccounts(ctrl) 219 220 witness := mocks.NewMockWitness(ctrl) 221 netp := netparams.New(log, netparams.NewDefaultConfig(), broker) 222 223 govBanking := mocks.NewMockBanking(ctrl) 224 gov := governance.NewEngine(log, governance.NewDefaultConfig(), accounts, timeService, broker, asset, witness, exec, netp, govBanking) 225 valFake := fakeCPComponent{ 226 name: types.ValidatorsCheckpoint, 227 } 228 epochFake := fakeCPComponent{ 229 name: types.EpochCheckpoint, 230 } 231 msFake := fakeCPComponent{ 232 name: types.MultisigControlCheckpoint, 233 } 234 stakeFake := fakeCPComponent{ 235 name: types.StakingCheckpoint, 236 } 237 delFake := fakeCPComponent{ 238 name: types.DelegationCheckpoint, 239 } 240 prFake := fakeCPComponent{ 241 name: types.PendingRewardsCheckpoint, 242 } 243 bankFake := fakeCPComponent{ 244 name: types.BankingCheckpoint, 245 } 246 cpEngine, _ := checkpoint.New(log, checkpoint.NewDefaultConfig(), gov, netp, asset, collateralService, marketTracker, exec, valFake, epochFake, msFake, stakeFake, delFake, prFake, bankFake) 247 248 return exec, gov, cpEngine 249 } 250 251 type fakeCPComponent struct { 252 name types.CheckpointName 253 } 254 255 func (f fakeCPComponent) Name() types.CheckpointName { 256 return f.name 257 } 258 259 func (fakeCPComponent) Load(_ context.Context, _ []byte) error { 260 return nil 261 } 262 263 func (fakeCPComponent) Checkpoint() ([]byte, error) { 264 return []byte{}, nil 265 }