code.vegaprotocol.io/vega@v0.79.0/core/staking/accounting_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 staking_test 17 18 import ( 19 "context" 20 "encoding/hex" 21 "testing" 22 "time" 23 24 "code.vegaprotocol.io/vega/core/broker/mocks" 25 "code.vegaprotocol.io/vega/core/staking" 26 smocks "code.vegaprotocol.io/vega/core/staking/mocks" 27 "code.vegaprotocol.io/vega/core/types" 28 "code.vegaprotocol.io/vega/libs/num" 29 "code.vegaprotocol.io/vega/logging" 30 31 "github.com/golang/mock/gomock" 32 "github.com/stretchr/testify/assert" 33 "github.com/stretchr/testify/require" 34 ) 35 36 type accountingTest struct { 37 *staking.Accounting 38 log *logging.Logger 39 ctrl *gomock.Controller 40 tsvc *smocks.MockTimeService 41 broker *mocks.MockBroker 42 evtfwd *smocks.MockEvtForwarder 43 witness *smocks.MockWitness 44 45 onTick func(context.Context, time.Time) 46 } 47 48 func getAccountingTest(t *testing.T) *accountingTest { 49 t.Helper() 50 log := logging.NewTestLogger() 51 ctrl := gomock.NewController(t) 52 ts := smocks.NewMockTimeService(ctrl) 53 broker := mocks.NewMockBroker(ctrl) 54 evtfwd := smocks.NewMockEvtForwarder(ctrl) 55 witness := smocks.NewMockWitness(ctrl) 56 ethsource := smocks.NewMockEthereumEventSource(ctrl) 57 var onTick func(context.Context, time.Time) 58 59 return &accountingTest{ 60 Accounting: staking.NewAccounting( 61 log, staking.NewDefaultConfig(), ts, broker, nil, evtfwd, witness, true, ethsource), 62 log: log, 63 ctrl: ctrl, 64 tsvc: ts, 65 broker: broker, 66 evtfwd: evtfwd, 67 witness: witness, 68 onTick: onTick, 69 } 70 } 71 72 func TestStakingAccounting(t *testing.T) { 73 t.Run("error party don't exists", testPartyDontExists) 74 t.Run("get available balance at", testAccountingGetAvailableBalanceAt) 75 t.Run("get available balance in range", testAccountingGetAvailableBalanceInRange) 76 t.Run("generate Hash", testAccountingGenerateHash) 77 } 78 79 func testPartyDontExists(t *testing.T) { 80 acc := getAccountingTest(t) 81 defer acc.ctrl.Finish() 82 83 balance, err := acc.GetAvailableBalance("nope") 84 assert.EqualError(t, err, staking.ErrNoBalanceForParty.Error()) 85 assert.Equal(t, num.UintZero(), balance) 86 balance, err = acc.GetAvailableBalanceAt("nope", time.Unix(10, 0)) 87 assert.EqualError(t, err, staking.ErrNoBalanceForParty.Error()) 88 assert.Equal(t, num.UintZero(), balance) 89 balance, err = acc.GetAvailableBalanceInRange("nope", time.Unix(10, 0), time.Unix(20, 0)) 90 assert.EqualError(t, err, staking.ErrNoBalanceForParty.Error()) 91 assert.Equal(t, num.UintZero(), balance) 92 } 93 94 func testAccountingGetAvailableBalanceInRange(t *testing.T) { 95 acc := getAccountingTest(t) 96 defer acc.ctrl.Finish() 97 cases := []struct { 98 evt types.StakeLinking 99 expect error 100 }{ 101 { 102 evt: types.StakeLinking{ 103 ID: "someid1", 104 Type: types.StakeLinkingTypeDeposited, 105 TS: 100, 106 Party: testParty, 107 Amount: num.NewUint(10), 108 }, 109 expect: nil, 110 }, 111 { 112 evt: types.StakeLinking{ 113 ID: "someid2", 114 Type: types.StakeLinkingTypeRemoved, 115 TS: 105, 116 Party: testParty, 117 Amount: num.NewUint(1), 118 }, 119 expect: nil, 120 }, 121 { 122 evt: types.StakeLinking{ 123 ID: "someid3", 124 Type: types.StakeLinkingTypeDeposited, 125 TS: 106, 126 Party: testParty, 127 Amount: num.NewUint(3), 128 }, 129 expect: nil, 130 }, 131 { 132 evt: types.StakeLinking{ 133 ID: "someid4", 134 Type: types.StakeLinkingTypeRemoved, 135 TS: 107, 136 Party: testParty, 137 Amount: num.NewUint(4), 138 }, 139 expect: nil, 140 }, 141 { 142 evt: types.StakeLinking{ 143 ID: "someid5", 144 Type: types.StakeLinkingTypeDeposited, 145 TS: 120, 146 Party: testParty, 147 Amount: num.NewUint(5), 148 }, 149 expect: nil, 150 }, 151 { 152 evt: types.StakeLinking{ 153 ID: "someid6", 154 Type: types.StakeLinkingTypeRemoved, 155 TS: 125, 156 Party: testParty, 157 Amount: num.NewUint(6), 158 }, 159 expect: nil, 160 }, 161 } 162 163 acc.broker.EXPECT().Send(gomock.Any()).Times(1) 164 165 for _, c := range cases { 166 c := c 167 acc.AddEvent(context.Background(), &c.evt) 168 } 169 170 balance, err := acc.GetAvailableBalanceInRange( 171 testParty, time.Unix(0, 10), time.Unix(0, 20)) 172 assert.NoError(t, err) 173 assert.Equal(t, num.NewUint(0), balance) 174 175 balance, err = acc.GetAvailableBalanceInRange( 176 testParty, time.Unix(0, 10), time.Unix(0, 110)) 177 assert.NoError(t, err) 178 assert.Equal(t, num.NewUint(0), balance) 179 180 balance, err = acc.GetAvailableBalanceInRange( 181 testParty, time.Unix(0, 101), time.Unix(0, 109)) 182 assert.NoError(t, err) 183 assert.Equal(t, num.NewUint(8), balance) 184 185 balance, err = acc.GetAvailableBalanceInRange( 186 testParty, time.Unix(0, 101), time.Unix(0, 111)) 187 assert.NoError(t, err) 188 assert.Equal(t, num.NewUint(8), balance) 189 190 balance, err = acc.GetAvailableBalanceInRange( 191 testParty, time.Unix(0, 101), time.Unix(0, 121)) 192 assert.NoError(t, err) 193 assert.Equal(t, num.NewUint(8), balance) 194 195 balance, err = acc.GetAvailableBalanceInRange( 196 testParty, time.Unix(0, 101), time.Unix(0, 126)) 197 assert.NoError(t, err) 198 assert.Equal(t, num.NewUint(7), balance) 199 } 200 201 func testAccountingGetAvailableBalanceAt(t *testing.T) { 202 acc := getAccountingTest(t) 203 defer acc.ctrl.Finish() 204 cases := []struct { 205 evt types.StakeLinking 206 expect error 207 }{ 208 { 209 evt: types.StakeLinking{ 210 ID: "someid1", 211 Type: types.StakeLinkingTypeDeposited, 212 TS: 100, 213 Party: testParty, 214 Amount: num.NewUint(10), 215 }, 216 expect: nil, 217 }, 218 { 219 evt: types.StakeLinking{ 220 ID: "someid2", 221 Type: types.StakeLinkingTypeRemoved, 222 TS: 110, 223 Party: testParty, 224 Amount: num.NewUint(1), 225 }, 226 expect: nil, 227 }, 228 { 229 evt: types.StakeLinking{ 230 ID: "someid3", 231 Type: types.StakeLinkingTypeDeposited, 232 TS: 120, 233 Party: testParty, 234 Amount: num.NewUint(5), 235 }, 236 expect: nil, 237 }, 238 } 239 240 acc.broker.EXPECT().Send(gomock.Any()).Times(1) 241 242 for _, c := range cases { 243 c := c 244 acc.AddEvent(context.Background(), &c.evt) 245 } 246 247 balance, err := acc.GetAvailableBalanceAt(testParty, time.Unix(0, 10)) 248 assert.NoError(t, err) 249 assert.Equal(t, num.NewUint(0), balance) 250 balance, err = acc.GetAvailableBalanceAt(testParty, time.Unix(0, 120)) 251 assert.NoError(t, err) 252 assert.Equal(t, num.NewUint(14), balance) 253 balance, err = acc.GetAvailableBalanceAt(testParty, time.Unix(0, 115)) 254 assert.NoError(t, err) 255 assert.Equal(t, num.NewUint(9), balance) 256 } 257 258 func testAccountingGenerateHash(t *testing.T) { 259 acc := getAccountingTest(t) 260 defer acc.ctrl.Finish() 261 cases := []struct { 262 evt types.StakeLinking 263 expect error 264 }{ 265 { 266 evt: types.StakeLinking{ 267 ID: "someid1", 268 Type: types.StakeLinkingTypeDeposited, 269 TS: 100, 270 Party: "party1", 271 Amount: num.NewUint(10), 272 }, 273 expect: nil, 274 }, 275 { 276 evt: types.StakeLinking{ 277 ID: "someid2", 278 Type: types.StakeLinkingTypeRemoved, 279 TS: 110, 280 Party: "party1", 281 Amount: num.NewUint(1), 282 }, 283 expect: nil, 284 }, 285 { 286 evt: types.StakeLinking{ 287 ID: "someid3", 288 Type: types.StakeLinkingTypeDeposited, 289 TS: 120, 290 Party: "party2", 291 Amount: num.NewUint(5), 292 }, 293 expect: nil, 294 }, 295 { 296 evt: types.StakeLinking{ 297 ID: "someid4", 298 Type: types.StakeLinkingTypeDeposited, 299 TS: 120, 300 Party: "party3", 301 Amount: num.NewUint(42), 302 }, 303 expect: nil, 304 }, 305 } 306 307 acc.broker.EXPECT().Send(gomock.Any()).Times(3) 308 309 for _, c := range cases { 310 c := c 311 acc.AddEvent(context.Background(), &c.evt) 312 } 313 314 require.Equal(t, 315 "ab5a48b34ac9f8c33a0441b6af04c84e2759086882b93aec972f4a709f93f8e9", 316 hex.EncodeToString(acc.Hash()), 317 "hash is not deterministic", 318 ) 319 }