code.vegaprotocol.io/vega@v0.79.0/core/datasource/external/ethverifier/l2_verifiers.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 ethverifier 17 18 import ( 19 "context" 20 "errors" 21 "fmt" 22 "sort" 23 "time" 24 25 "code.vegaprotocol.io/vega/core/client/eth" 26 "code.vegaprotocol.io/vega/core/datasource/external/ethcall" 27 "code.vegaprotocol.io/vega/core/types" 28 "code.vegaprotocol.io/vega/logging" 29 30 "golang.org/x/exp/maps" 31 ) 32 33 type L2Clients interface { 34 Get(chainID string) (*eth.L2Client, *eth.EthereumConfirmations, bool) 35 } 36 37 type EthL2CallEngines interface { 38 GetOrInstantiate(chainID string) (EthCallEngine, error) 39 } 40 41 type L2Verifiers struct { 42 log *logging.Logger 43 witness Witness 44 ts TimeService 45 broker Broker 46 oracleBroadcaster OracleDataBroadcaster 47 48 isValidator bool 49 50 clients L2Clients 51 52 // chain id -> Verifier 53 verifiers map[string]*Verifier 54 55 // eth L2 call engines 56 ethL2CallEngine EthL2CallEngines 57 } 58 59 func NewL2Verifiers( 60 log *logging.Logger, 61 witness Witness, 62 ts TimeService, 63 broker Broker, 64 oracleBroadcaster OracleDataBroadcaster, 65 clients L2Clients, 66 callEngines EthL2CallEngines, 67 isValidator bool, 68 ) (sv *L2Verifiers) { 69 return &L2Verifiers{ 70 log: log, 71 witness: witness, 72 ts: ts, 73 broker: broker, 74 oracleBroadcaster: oracleBroadcaster, 75 clients: clients, 76 verifiers: map[string]*Verifier{}, 77 ethL2CallEngine: callEngines, 78 isValidator: isValidator, 79 } 80 } 81 82 func (v *L2Verifiers) OnEthereumL2ConfigsUpdated( 83 ctx context.Context, ethCfg *types.EthereumL2Configs, 84 ) error { 85 // new L2 configured, instatiate the verifier for it. 86 for _, c := range ethCfg.Configs { 87 // if already exists, do nothing 88 if _, ok := v.verifiers[c.ChainID]; ok { 89 continue 90 } 91 v.verifiers[c.ChainID] = v.instantiate(c.ChainID) 92 } 93 94 return nil 95 } 96 97 func (v *L2Verifiers) instantiate(chainID string) *Verifier { 98 var confs *eth.EthereumConfirmations 99 if v.isValidator { 100 var ok bool 101 _, confs, ok = v.clients.Get(chainID) 102 if !ok { 103 v.log.Panic("ethereum client not configured for L2", 104 logging.String("chain-id", chainID), 105 ) 106 } 107 } 108 109 ethCallEngine, err := v.ethL2CallEngine.GetOrInstantiate(chainID) 110 if err != nil { 111 v.log.Panic("could not get call engine for L2", logging.String("chain-id", chainID)) 112 } 113 114 return New(v.log, v.witness, v.ts, v.broker, v.oracleBroadcaster, ethCallEngine, confs, v.isValidator) 115 } 116 117 func (v *L2Verifiers) OnTick(ctx context.Context, t time.Time) { 118 ids := maps.Keys(v.verifiers) 119 sort.Strings(ids) 120 for _, id := range ids { 121 v.verifiers[id].OnTick(ctx, t) 122 } 123 } 124 125 func (v *L2Verifiers) ProcessEthereumContractCallResult(callEvent ethcall.ContractCallEvent) error { 126 if callEvent.SourceChainID == nil { 127 return errors.New("invalid non l2 event") 128 } 129 130 verifier, ok := v.verifiers[fmt.Sprintf("%v", *callEvent.SourceChainID)] 131 if !ok { 132 return errors.New("unsupported l2 chain") 133 } 134 135 return verifier.ProcessEthereumContractCallResult(callEvent) 136 } 137 138 func (v *L2Verifiers) FromProtoSnapshot() {} 139 140 func (v *L2Verifiers) ToProtoSnapshot() []byte { return nil }