code.vegaprotocol.io/vega@v0.79.0/core/epochtime/snapshot_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 epochtime_test 17 18 import ( 19 "context" 20 "encoding/hex" 21 "testing" 22 "time" 23 24 "code.vegaprotocol.io/vega/core/types" 25 "code.vegaprotocol.io/vega/libs/crypto" 26 "code.vegaprotocol.io/vega/libs/proto" 27 "code.vegaprotocol.io/vega/protos/vega" 28 eventspb "code.vegaprotocol.io/vega/protos/vega/events/v1" 29 snapshot "code.vegaprotocol.io/vega/protos/vega/snapshot/v1" 30 31 "github.com/golang/mock/gomock" 32 "github.com/stretchr/testify/require" 33 ) 34 35 func TestEpochSnapshotFunctionallyAfterReload(t *testing.T) { 36 now := time.Unix(0, 0).UTC() 37 38 ctx := context.Background() 39 service := getEpochServiceMT(t) 40 defer service.ctrl.Finish() 41 42 service.broker.EXPECT().Send(gomock.Any()).Times(3) 43 // Force creation of first epoch to trigger a snapshot of the first epoch 44 service.cb(ctx, now) 45 // Force creation of first epoch to trigger a snapshot of the first epoch 46 47 data, _, err := service.GetState("all") 48 require.Nil(t, err) 49 50 snapService := getEpochServiceMT(t) 51 defer snapService.ctrl.Finish() 52 53 snapService.broker.EXPECT().Send(gomock.Any()).Times(2) 54 // Fiddle it into a payload by hand 55 snap := &snapshot.Payload{} 56 err = proto.Unmarshal(data, snap) 57 require.Nil(t, err) 58 59 service.NotifyOnEpoch(onEpoch, onEpochRestore) 60 snapService.NotifyOnEpoch(onEpoch, onEpochRestore) 61 62 _, err = snapService.LoadState( 63 ctx, 64 types.PayloadFromProto(snap), 65 ) 66 require.Nil(t, err) 67 68 // Check functional equivalence by stepping forward in time/blocks 69 // Reset global used in callback so that is doesn't pick up state from another test 70 epochs = []types.Epoch{} 71 72 // Move time forward in time a small amount that should cause no change 73 nt := now.Add(time.Hour) 74 service.cb(ctx, nt) 75 snapService.cb(ctx, nt) 76 require.Equal(t, 0, len(epochs)) 77 78 // Now send end block 79 service.OnBlockEnd(ctx) 80 snapService.OnBlockEnd((ctx)) 81 service.cb(ctx, nt) 82 snapService.cb(ctx, nt) 83 require.Equal(t, 0, len(epochs)) 84 85 // Move even further forward 86 nt = now.Add(time.Hour * 25) 87 service.cb(ctx, nt) 88 snapService.cb(ctx, nt) 89 service.OnBlockEnd(ctx) 90 snapService.OnBlockEnd((ctx)) 91 nt = now.Add(time.Hour * 50) 92 service.cb(ctx, nt) 93 snapService.cb(ctx, nt) 94 require.Equal(t, 4, len(epochs)) 95 96 // epochs = {start, end, start, end} 97 require.Equal(t, epochs[0], epochs[2]) 98 require.Equal(t, epochs[1], epochs[3]) 99 } 100 101 func TestEpochSnapshotHash(t *testing.T) { 102 now := time.Unix(0, 0).UTC() 103 104 ctx := context.Background() 105 service := getEpochServiceMT(t) 106 defer service.ctrl.Finish() 107 108 service.broker.EXPECT().Send(gomock.Any()).Times(3) 109 // Trigger initial block 110 service.cb(ctx, now) 111 s, _, err := service.GetState("all") 112 require.Nil(t, err) 113 require.Equal(t, "41a9839f4dc60ac14461f58658c0e1bf7542bd54cbd635f3c0402bef2f07f60f", hex.EncodeToString(crypto.Hash(s))) 114 115 // Shuffle time along 116 now = now.Add(25 * time.Hour) 117 service.cb(ctx, now) 118 service.OnBlockEnd(ctx) 119 s, _, err = service.GetState("all") 120 require.Nil(t, err) 121 require.Equal(t, "074677210f20ebb3427064339ebbd46dbfd5d2381bcd3b3fd126bbdcb05b6697", hex.EncodeToString(crypto.Hash(s))) 122 123 // Shuffle time a bit more 124 now = now.Add(25 * time.Hour) 125 service.cb(ctx, now) 126 s, _, err = service.GetState("all") 127 require.Nil(t, err) 128 require.Equal(t, "2fb572edea4af9154edeff680e23689ed076d08934c60f8a4c1f5743a614954e", hex.EncodeToString(crypto.Hash(s))) 129 } 130 131 func TestEpochSnapshotCompare(t *testing.T) { 132 now := time.Unix(0, 0).UTC() 133 134 ctx := context.Background() 135 service := getEpochServiceMT(t) 136 defer service.ctrl.Finish() 137 138 service.broker.EXPECT().Send(gomock.Any()).Times(1) 139 140 // Force creation of first epoch to trigger a snapshot of the first epoch 141 service.cb(ctx, now) 142 143 data, _, err := service.GetState("all") 144 require.Nil(t, err) 145 146 snapService := getEpochServiceMT(t) 147 defer snapService.ctrl.Finish() 148 149 // Fiddle it into a payload by hand 150 snap := &snapshot.Payload{} 151 err = proto.Unmarshal(data, snap) 152 require.Nil(t, err) 153 154 _, err = snapService.LoadState( 155 ctx, 156 types.PayloadFromProto(snap), 157 ) 158 require.Nil(t, err) 159 160 // Check that the snapshot of the snapshot is the same as the original snapshot 161 newData, _, err := service.GetState("all") 162 require.Nil(t, err) 163 require.Equal(t, data, newData) 164 } 165 166 func TestEpochSnapshotAfterCheckpoint(t *testing.T) { 167 ctx := context.Background() 168 service := getEpochServiceMT(t) 169 defer service.ctrl.Finish() 170 171 service.broker.EXPECT().Send(gomock.Any()).AnyTimes() 172 173 // load from a checkpoint 174 pb := &eventspb.EpochEvent{ 175 Seq: 10, 176 Action: vega.EpochAction_EPOCH_ACTION_START, 177 ExpireTime: 1664369813556378344, 178 EndTime: 1664362613556378344, 179 } 180 181 cpt, err := proto.Marshal(pb) 182 require.NoError(t, err) 183 require.NoError(t, service.Load(ctx, cpt)) 184 185 // Force creation of first epoch to trigger a snapshot of the first epoch 186 service.cb(ctx, time.Unix(0, 1664364245193844630)) 187 188 d, _, err := service.GetState("all") 189 require.NoError(t, err) 190 snap := &snapshot.Payload{} 191 err = proto.Unmarshal(d, snap) 192 require.Nil(t, err) 193 194 require.NotNil(t, snap.GetEpoch()) 195 require.Equal(t, uint64(10), snap.GetEpoch().Seq) 196 }