code.vegaprotocol.io/vega@v0.79.0/core/validators/erc20multisig/evm_topologies.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  
    21  	"code.vegaprotocol.io/vega/core/types"
    22  	"code.vegaprotocol.io/vega/libs/proto"
    23  	"code.vegaprotocol.io/vega/logging"
    24  	snapshotpb "code.vegaprotocol.io/vega/protos/vega/snapshot/v1"
    25  )
    26  
    27  // Topology keeps track of all the validators
    28  // registered in the erc20 bridge.
    29  type EVMTopologies struct {
    30  	topologies []*Topology
    31  }
    32  
    33  func NewEVMTopologies(
    34  	secondBridge *Topology,
    35  ) *EVMTopologies {
    36  	return &EVMTopologies{
    37  		topologies: []*Topology{secondBridge},
    38  	}
    39  }
    40  
    41  func (t *EVMTopologies) Namespace() types.SnapshotNamespace {
    42  	return types.EVMMultiSigTopologiesSnapshot
    43  }
    44  
    45  func (t *EVMTopologies) Keys() []string {
    46  	return []string{
    47  		(&types.PayloadEventForwarder{}).Key(),
    48  	}
    49  }
    50  
    51  func (t *EVMTopologies) GetState(k string) ([]byte, []types.StateProvider, error) {
    52  	if k != (&types.PayloadEventForwarder{}).Key() {
    53  		return nil, nil, types.ErrSnapshotKeyDoesNotExist
    54  	}
    55  	data, err := t.serialise()
    56  	return data, nil, err
    57  }
    58  
    59  func (t *EVMTopologies) Stopped() bool {
    60  	return false
    61  }
    62  
    63  func (t *EVMTopologies) LoadState(ctx context.Context, payload *types.Payload) ([]types.StateProvider, error) {
    64  	if t.Namespace() != payload.Data.Namespace() {
    65  		return nil, types.ErrInvalidSnapshotNamespace
    66  	}
    67  
    68  	switch pl := payload.Data.(type) {
    69  	case *types.PayloadEVMMultisigTopologies:
    70  		return nil, t.restore(ctx, pl.Topologies)
    71  	default:
    72  		return nil, types.ErrUnknownSnapshotType
    73  	}
    74  }
    75  
    76  // get the serialised form of the given key.
    77  func (t *EVMTopologies) restore(ctx context.Context, topologies []*snapshotpb.EVMMultisigTopology) error {
    78  	secondBridge := t.topologies[0]
    79  	if err := secondBridge.restorePendingState(ctx, topologies[0].Pending); err != nil {
    80  		return err
    81  	}
    82  	if err := secondBridge.restoreVerifiedState(ctx, topologies[0].Verified); err != nil {
    83  		return err
    84  	}
    85  	return nil
    86  }
    87  
    88  // get the serialised form of the given key.
    89  func (t *EVMTopologies) serialise() ([]byte, error) {
    90  	payload := types.Payload{
    91  		Data: &types.PayloadEVMMultisigTopologies{
    92  			Topologies: []*snapshotpb.EVMMultisigTopology{
    93  				{
    94  					Verified: t.topologies[0].constructVerifiedState(),
    95  					Pending:  t.topologies[0].constructPendingState(),
    96  					ChainId:  t.topologies[0].chainID,
    97  				},
    98  			},
    99  		},
   100  	}
   101  	return proto.Marshal(payload.IntoProto())
   102  }
   103  
   104  func (t *EVMTopologies) OnStateLoaded(ctx context.Context) error {
   105  	// tell the internal EEF where it got up to so we do not resend events we're already seen
   106  
   107  	topology := t.topologies[0]
   108  	lastSeen := topology.getLastBlockSeen()
   109  	if lastSeen != 0 {
   110  		// TODO snapshot migration stuff
   111  		topology.log.Info("restoring multisig starting block", logging.Uint64("block", lastSeen), logging.String("chain-id", topology.chainID))
   112  		// topology.ethEventSource.UpdateMultisigControlStartingBlock(topology.getLastBlockSeen())
   113  	}
   114  	return nil
   115  }