code.vegaprotocol.io/vega@v0.79.0/core/activitystreak/activitiystreak_snapshot.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 activitystreak 17 18 import ( 19 "context" 20 "fmt" 21 "sort" 22 23 "code.vegaprotocol.io/vega/core/types" 24 "code.vegaprotocol.io/vega/libs/num" 25 "code.vegaprotocol.io/vega/libs/proto" 26 "code.vegaprotocol.io/vega/logging" 27 snapshotpb "code.vegaprotocol.io/vega/protos/vega/snapshot/v1" 28 ) 29 30 var ActivityStreakKey = (&types.PayloadActivityStreak{}).Key() 31 32 type SnapshotEngine struct { 33 *Engine 34 } 35 36 func NewSnapshotEngine( 37 log *logging.Logger, 38 marketStats MarketsStatsAggregator, 39 broker Broker, 40 ) *SnapshotEngine { 41 se := &SnapshotEngine{ 42 Engine: New(log, marketStats, broker), 43 } 44 45 return se 46 } 47 48 func (e *SnapshotEngine) Namespace() types.SnapshotNamespace { 49 return types.ActivityStreakSnapshot 50 } 51 52 func (e *SnapshotEngine) Keys() []string { 53 return []string{ActivityStreakKey} 54 } 55 56 func (e *SnapshotEngine) Stopped() bool { 57 return false 58 } 59 60 func (e *SnapshotEngine) GetState(k string) ([]byte, []types.StateProvider, error) { 61 state, err := e.serialise(k) 62 return state, nil, err 63 } 64 65 func (e *SnapshotEngine) LoadState(_ context.Context, p *types.Payload) ([]types.StateProvider, error) { 66 if e.Namespace() != p.Data.Namespace() { 67 return nil, types.ErrInvalidSnapshotNamespace 68 } 69 70 switch data := p.Data.(type) { 71 case *types.PayloadActivityStreak: 72 e.loadStateFromSnapshot(data.ActivityStreak) 73 return nil, nil 74 default: 75 return nil, types.ErrUnknownSnapshotType 76 } 77 } 78 79 func (e *SnapshotEngine) loadStateFromSnapshot(state *snapshotpb.ActivityStreak) { 80 for _, v := range state.PartiesActivityStreak { 81 var rewardDistributionActivityMultiplier num.Decimal 82 if len(v.RewardDistributionMultiplier) > 0 { 83 rewardDistributionActivityMultiplier, _ = num.UnmarshalBinaryDecimal(v.RewardDistributionMultiplier) 84 } 85 86 var rewardVestingActivityMultiplier num.Decimal 87 if len(v.RewardVestingMultiplier) > 0 { 88 rewardVestingActivityMultiplier, _ = num.UnmarshalBinaryDecimal(v.RewardVestingMultiplier) 89 } 90 91 e.partiesActivity[v.Party] = &PartyActivity{ 92 Active: v.Active, 93 Inactive: v.Inactive, 94 RewardDistributionActivityMultiplier: rewardDistributionActivityMultiplier, 95 RewardVestingActivityMultiplier: rewardVestingActivityMultiplier, 96 } 97 } 98 } 99 100 func (e *SnapshotEngine) serialise(k string) ([]byte, error) { 101 switch k { 102 case ActivityStreakKey: 103 return e.serialiseAll() 104 default: 105 return nil, types.ErrSnapshotKeyDoesNotExist 106 } 107 } 108 109 func (e *SnapshotEngine) serialiseAll() ([]byte, error) { 110 out := snapshotpb.ActivityStreak{ 111 PartiesActivityStreak: make([]*snapshotpb.PartyActivityStreak, 0, len(e.partiesActivity)), 112 } 113 114 for party, activity := range e.partiesActivity { 115 rewardDistributionMultiplier, _ := activity.RewardDistributionActivityMultiplier.MarshalBinary() 116 rewardVestingMultiplier, _ := activity.RewardVestingActivityMultiplier.MarshalBinary() 117 out.PartiesActivityStreak = append(out.PartiesActivityStreak, &snapshotpb.PartyActivityStreak{ 118 Party: party, 119 Active: activity.Active, 120 Inactive: activity.Inactive, 121 RewardDistributionMultiplier: rewardDistributionMultiplier, 122 RewardVestingMultiplier: rewardVestingMultiplier, 123 }) 124 } 125 126 sort.Slice(out.PartiesActivityStreak, func(i, j int) bool { 127 return out.PartiesActivityStreak[i].Party < out.PartiesActivityStreak[j].Party 128 }) 129 130 payload := &snapshotpb.Payload{ 131 Data: &snapshotpb.Payload_ActivityStreak{ 132 ActivityStreak: &out, 133 }, 134 } 135 136 serialized, err := proto.Marshal(payload) 137 if err != nil { 138 return nil, fmt.Errorf("could not serialize team switches payload: %w", err) 139 } 140 141 return serialized, nil 142 }