code.vegaprotocol.io/vega@v0.79.0/core/validators/erc20multisig/checkpoint.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 erc20multisig 17 18 import ( 19 "context" 20 "sort" 21 22 "code.vegaprotocol.io/vega/core/types" 23 "code.vegaprotocol.io/vega/libs/proto" 24 "code.vegaprotocol.io/vega/logging" 25 checkpoint "code.vegaprotocol.io/vega/protos/vega/checkpoint/v1" 26 events "code.vegaprotocol.io/vega/protos/vega/events/v1" 27 ) 28 29 func (t *Topology) Name() types.CheckpointName { 30 return types.MultisigControlCheckpoint 31 } 32 33 func (t *Topology) Checkpoint() ([]byte, error) { 34 var thresholdSet *events.ERC20MultiSigThresholdSetEvent 35 if t.threshold != nil { 36 thresholdSet = t.threshold.IntoProto() 37 } 38 39 msg := &checkpoint.MultisigControl{ 40 Signers: t.getSigners(), 41 ThresholdSet: thresholdSet, 42 LastBlockSeen: t.getLastBlockSeen(), 43 } 44 ret, err := proto.Marshal(msg) 45 if err != nil { 46 return nil, err 47 } 48 return ret, nil 49 } 50 51 func (t *Topology) Load(ctx context.Context, data []byte) error { 52 mc := checkpoint.MultisigControl{} 53 if err := proto.Unmarshal(data, &mc); err != nil { 54 return err 55 } 56 57 // load signers 58 for _, sevt := range mc.Signers { 59 signerEvent := types.SignerEventFromEventProto(sevt) 60 t.addSignerEvent(ctx, signerEvent) 61 62 // now ensure that the seen map is OK 63 if !t.ensureNotDuplicate(signerEvent.Hash()) { 64 t.log.Panic("invalid checkpoint data, duplicated signer event", 65 logging.String("event-id", signerEvent.ID)) 66 } 67 } 68 69 // load threshold 70 if mc.ThresholdSet != nil { 71 t.setThresholdSetEvent( 72 ctx, types.SignerThresholdSetEventFromEventProto(mc.ThresholdSet)) 73 } 74 75 // 0 is default value, we assume that it was then not set 76 //if mc.LastBlockSeen != 0 { 77 // t.ethEventSource.UpdateMultisigControlStartingBlock(mc.LastBlockSeen) 78 //} 79 80 return nil 81 } 82 83 func (t *Topology) getSigners() []*events.ERC20MultiSigSignerEvent { 84 // we only keep the list of all verified events 85 out := []*events.ERC20MultiSigSignerEvent{} 86 for _, evts := range t.eventsPerAddress { 87 for _, evt := range evts { 88 out = append(out, evt.IntoProto()) 89 } 90 } 91 92 sort.Slice(out, func(i, j int) bool { 93 return out[i].Id < out[j].Id 94 }) 95 96 return out 97 } 98 99 func (t *Topology) getLastBlockSeen() uint64 { 100 var block uint64 101 102 for _, evts := range t.eventsPerAddress { 103 for _, evt := range evts { 104 if evt.BlockNumber > block { 105 block = evt.BlockNumber 106 } 107 } 108 } 109 110 return block 111 }