code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/volume_rebate_programs_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 sqlstore_test 17 18 import ( 19 "testing" 20 "time" 21 22 "code.vegaprotocol.io/vega/datanode/entities" 23 "code.vegaprotocol.io/vega/datanode/sqlstore" 24 "code.vegaprotocol.io/vega/libs/ptr" 25 "code.vegaprotocol.io/vega/protos/vega" 26 eventspb "code.vegaprotocol.io/vega/protos/vega/events/v1" 27 28 "github.com/georgysavva/scany/pgxscan" 29 "github.com/stretchr/testify/assert" 30 "github.com/stretchr/testify/require" 31 ) 32 33 func setupVolumeRebateProgramTest(t *testing.T) (*sqlstore.Blocks, *sqlstore.VolumeRebatePrograms) { 34 t.Helper() 35 36 bs := sqlstore.NewBlocks(connectionSource) 37 rs := sqlstore.NewVolumeRebatePrograms(connectionSource) 38 39 return bs, rs 40 } 41 42 func TestVolumeRebatePrograms_AddVolumeRebateProgram(t *testing.T) { 43 bs, rs := setupVolumeRebateProgramTest(t) 44 ctx := tempTransaction(t) 45 46 block := addTestBlock(t, ctx, bs) 47 block2 := addTestBlock(t, ctx, bs) 48 one64 := uint64(1) 49 50 t.Run("AddVolumeRebateProgram should create a new volume rebate program record", func(t *testing.T) { 51 endTime := block.VegaTime.Add(time.Hour) 52 endTime2 := block2.VegaTime.Add(time.Hour) 53 54 programs := []*eventspb.VolumeRebateProgramStarted{ 55 { 56 Program: &vega.VolumeRebateProgram{ 57 Version: 1, 58 Id: GenerateID(), 59 BenefitTiers: []*vega.VolumeRebateBenefitTier{ 60 { 61 MinimumPartyMakerVolumeFraction: "1", 62 AdditionalMakerRebate: "0.01", 63 TierNumber: ptr.From(one64), 64 }, 65 { 66 MinimumPartyMakerVolumeFraction: "2", 67 AdditionalMakerRebate: "0.1", 68 TierNumber: ptr.From(one64 * 2), 69 }, 70 }, 71 EndOfProgramTimestamp: endTime.Unix(), 72 WindowLength: 100, 73 }, 74 }, 75 { 76 Program: &vega.VolumeRebateProgram{ 77 Version: 1, 78 Id: GenerateID(), 79 BenefitTiers: []*vega.VolumeRebateBenefitTier{ 80 { 81 MinimumPartyMakerVolumeFraction: "3", 82 AdditionalMakerRebate: "0.02", 83 TierNumber: ptr.From(one64), 84 }, 85 { 86 MinimumPartyMakerVolumeFraction: "4", 87 AdditionalMakerRebate: "0.2", 88 TierNumber: ptr.From(one64 * 2), 89 }, 90 }, 91 EndOfProgramTimestamp: endTime2.Unix(), 92 WindowLength: 200, 93 }, 94 }, 95 } 96 97 want := entities.VolumeRebateProgramFromProto(programs[0].Program, block.VegaTime, 0) 98 err := rs.AddVolumeRebateProgram(ctx, want) 99 require.NoError(t, err) 100 101 var got []entities.VolumeRebateProgram 102 require.NoError(t, pgxscan.Select(ctx, connectionSource, &got, "SELECT * FROM volume_rebate_programs")) 103 require.Len(t, got, 1) 104 assert.Equal(t, *want, got[0]) 105 106 want2 := entities.VolumeRebateProgramFromProto(programs[1].Program, block2.VegaTime, 0) 107 err = rs.AddVolumeRebateProgram(ctx, want2) 108 require.NoError(t, err) 109 110 err = pgxscan.Select(ctx, connectionSource, &got, "SELECT * FROM volume_rebate_programs") 111 require.NoError(t, err) 112 require.Len(t, got, 2) 113 wantAll := []entities.VolumeRebateProgram{*want, *want2} 114 assert.Equal(t, wantAll, got) 115 }) 116 } 117 118 func getVolumeRebateEvents(t *testing.T, endTime time.Time) (*eventspb.VolumeRebateProgramStarted, 119 *eventspb.VolumeRebateProgramUpdated, *eventspb.VolumeRebateProgramEnded, 120 ) { 121 t.Helper() 122 123 one64 := uint64(1) 124 started := eventspb.VolumeRebateProgramStarted{ 125 Program: &vega.VolumeRebateProgram{ 126 Version: 1, 127 Id: GenerateID(), 128 BenefitTiers: []*vega.VolumeRebateBenefitTier{ 129 { 130 MinimumPartyMakerVolumeFraction: "1000", 131 AdditionalMakerRebate: "0.01", 132 TierNumber: ptr.From(one64), 133 }, 134 { 135 MinimumPartyMakerVolumeFraction: "10000", 136 AdditionalMakerRebate: "0.1", 137 TierNumber: ptr.From(one64 * 2), 138 }, 139 }, 140 EndOfProgramTimestamp: endTime.Unix(), 141 WindowLength: 100, 142 }, 143 StartedAt: endTime.Add(-1 * time.Hour).UnixNano(), 144 AtEpoch: 1, 145 } 146 147 updated := eventspb.VolumeRebateProgramUpdated{ 148 Program: &vega.VolumeRebateProgram{ 149 Version: 2, 150 Id: GenerateID(), 151 BenefitTiers: []*vega.VolumeRebateBenefitTier{ 152 { 153 MinimumPartyMakerVolumeFraction: "2000", 154 AdditionalMakerRebate: "0.02", 155 TierNumber: ptr.From(one64), 156 }, 157 { 158 MinimumPartyMakerVolumeFraction: "20000", 159 AdditionalMakerRebate: "0.2", 160 TierNumber: ptr.From(one64 * 2), 161 }, 162 }, 163 EndOfProgramTimestamp: endTime.Unix(), 164 WindowLength: 200, 165 }, 166 UpdatedAt: endTime.Add(-30 * time.Minute).UnixNano(), 167 AtEpoch: 2, 168 } 169 170 ended := eventspb.VolumeRebateProgramEnded{ 171 Version: 2, 172 Id: updated.Program.Id, 173 EndedAt: endTime.UnixNano(), 174 AtEpoch: 3, 175 } 176 177 return &started, &updated, &ended 178 } 179 180 func TestVolumeRebatePrograms_UpdateVolumeRebateProgram(t *testing.T) { 181 bs, rs := setupVolumeRebateProgramTest(t) 182 ctx := tempTransaction(t) 183 184 block := addTestBlock(t, ctx, bs) 185 endTime := block.VegaTime.Add(time.Hour) 186 started, updated, _ := getVolumeRebateEvents(t, endTime) 187 188 var want, wantUpdated *entities.VolumeRebateProgram 189 t.Run("UpdateVolumeRebateProgram should create a new referral program record with the updated data", func(t *testing.T) { 190 want = entities.VolumeRebateProgramFromProto(started.Program, block.VegaTime, 0) 191 err := rs.AddVolumeRebateProgram(ctx, want) 192 require.NoError(t, err) 193 194 var got []entities.VolumeRebateProgram 195 err = pgxscan.Select(ctx, connectionSource, &got, "SELECT * FROM volume_rebate_programs") 196 require.NoError(t, err) 197 198 require.Len(t, got, 1) 199 assert.Equal(t, *want, got[0]) 200 201 block = addTestBlock(t, ctx, bs) 202 wantUpdated = entities.VolumeRebateProgramFromProto(updated.Program, block.VegaTime, 0) 203 err = rs.UpdateVolumeRebateProgram(ctx, wantUpdated) 204 require.NoError(t, err) 205 206 err = pgxscan.Select(ctx, connectionSource, &got, "SELECT * FROM volume_rebate_programs") 207 require.NoError(t, err) 208 209 require.Len(t, got, 2) 210 211 wantAll := []entities.VolumeRebateProgram{*want, *wantUpdated} 212 assert.Equal(t, wantAll, got) 213 }) 214 215 t.Run("The current_rebate view should list the updated rebate program record", func(t *testing.T) { 216 var got []entities.VolumeRebateProgram 217 err := pgxscan.Select(ctx, connectionSource, &got, "SELECT * FROM current_volume_rebate_program") 218 require.NoError(t, err) 219 require.Len(t, got, 1) 220 assert.Equal(t, *wantUpdated, got[0]) 221 }) 222 } 223 224 func TestVolumeRebatePrograms_EndVolumeRebateProgram(t *testing.T) { 225 bs, rs := setupVolumeRebateProgramTest(t) 226 ctx := tempTransaction(t) 227 228 t.Run("EndVolumeRebateProgram should create a new rebate program record with the data from the current rebate program and set the ended_at timestamp", func(t *testing.T) { 229 block := addTestBlock(t, ctx, bs) 230 endTime := block.VegaTime.Add(time.Hour) 231 startedEvent, updatedEvent, endedEvent := getVolumeRebateEvents(t, endTime) 232 233 started := entities.VolumeRebateProgramFromProto(startedEvent.Program, block.VegaTime, 1) 234 err := rs.AddVolumeRebateProgram(ctx, started) 235 require.NoError(t, err) 236 237 block = addTestBlock(t, ctx, bs) 238 updated := entities.VolumeRebateProgramFromProto(updatedEvent.Program, block.VegaTime, 2) 239 err = rs.UpdateVolumeRebateProgram(ctx, updated) 240 require.NoError(t, err) 241 242 block = addTestBlock(t, ctx, bs) 243 err = rs.EndVolumeRebateProgram(ctx, endedEvent.Version, endTime, block.VegaTime, 3) 244 require.NoError(t, err) 245 246 ended := entities.VolumeRebateProgramFromProto(updatedEvent.Program, block.VegaTime, 3) 247 ended.Version = endedEvent.Version 248 ended.EndedAt = &endTime 249 250 var got []entities.VolumeRebateProgram 251 err = pgxscan.Select(ctx, connectionSource, &got, "SELECT * FROM volume_rebate_programs order by vega_time") 252 require.NoError(t, err) 253 require.Len(t, got, 3) 254 wantAll := []entities.VolumeRebateProgram{*started, *updated, *ended} 255 assert.Equal(t, wantAll, got) 256 257 err = pgxscan.Select(ctx, connectionSource, &got, "SELECT * FROM current_volume_rebate_program") 258 require.NoError(t, err) 259 require.Len(t, got, 1) 260 assert.Equal(t, *ended, got[0]) 261 }) 262 } 263 264 func TestVolumeRebatePrograms_GetCurrentVolumeRebateProgram(t *testing.T) { 265 bs, rs := setupVolumeRebateProgramTest(t) 266 ctx := tempTransaction(t) 267 268 t.Run("GetCurrentVolumeRebateProgram should return the current rebate program information", func(t *testing.T) { 269 block := addTestBlock(t, ctx, bs) 270 endTime := block.VegaTime.Add(time.Hour) 271 startedEvent, updatedEvent, endedEvent := getVolumeRebateEvents(t, endTime) 272 273 started := entities.VolumeRebateProgramFromProto(startedEvent.Program, block.VegaTime, 1) 274 err := rs.AddVolumeRebateProgram(ctx, started) 275 require.NoError(t, err) 276 277 got, err := rs.GetCurrentVolumeRebateProgram(ctx) 278 require.NoError(t, err) 279 assert.Equal(t, *started, got) 280 281 block = addTestBlock(t, ctx, bs) 282 updated := entities.VolumeRebateProgramFromProto(updatedEvent.Program, block.VegaTime, 2) 283 err = rs.UpdateVolumeRebateProgram(ctx, updated) 284 require.NoError(t, err) 285 286 got, err = rs.GetCurrentVolumeRebateProgram(ctx) 287 require.NoError(t, err) 288 assert.Equal(t, *updated, got) 289 290 block = addTestBlock(t, ctx, bs) 291 err = rs.EndVolumeRebateProgram(ctx, endedEvent.Version, endTime, block.VegaTime, 3) 292 require.NoError(t, err) 293 294 ended := entities.VolumeRebateProgramFromProto(updatedEvent.Program, block.VegaTime, 3) 295 ended.Version = endedEvent.Version 296 ended.EndedAt = &endTime 297 298 got, err = rs.GetCurrentVolumeRebateProgram(ctx) 299 require.NoError(t, err) 300 assert.Equal(t, *ended, got) 301 }) 302 }