code.vegaprotocol.io/vega@v0.79.0/core/protocol/l2_eth_call_engines.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 protocol 17 18 // circling around import cycle here... 19 20 import ( 21 "context" 22 23 "code.vegaprotocol.io/vega/core/client/eth" 24 "code.vegaprotocol.io/vega/core/datasource/external/ethcall" 25 "code.vegaprotocol.io/vega/core/datasource/external/ethverifier" 26 "code.vegaprotocol.io/vega/core/datasource/spec" 27 "code.vegaprotocol.io/vega/core/types" 28 vgcontext "code.vegaprotocol.io/vega/libs/context" 29 "code.vegaprotocol.io/vega/logging" 30 ) 31 32 type SpecActivationListener func(listener spec.SpecActivationsListener) 33 34 type L2EthCallEngines struct { 35 log *logging.Logger 36 cfg ethcall.Config 37 isValidator bool 38 clients *eth.L2Clients 39 forwarder ethcall.Forwarder 40 41 // chain id -> engine 42 engines map[string]*ethcall.Engine 43 specActivationListener SpecActivationListener 44 } 45 46 func NewL2EthCallEngines(log *logging.Logger, cfg ethcall.Config, isValidator bool, clients *eth.L2Clients, forwarder ethcall.Forwarder, specActivationListener SpecActivationListener) *L2EthCallEngines { 47 return &L2EthCallEngines{ 48 log: log, 49 cfg: cfg, 50 isValidator: isValidator, 51 clients: clients, 52 forwarder: forwarder, 53 engines: map[string]*ethcall.Engine{}, 54 specActivationListener: specActivationListener, 55 } 56 } 57 58 func (v *L2EthCallEngines) GetOrInstantiate(chainID string) (ethverifier.EthCallEngine, error) { 59 if e, ok := v.engines[chainID]; ok { 60 return e, nil 61 } 62 63 v.log.Panic("should be instantiated by now really?") 64 return nil, nil 65 } 66 67 func (v *L2EthCallEngines) OnEthereumL2ConfigsUpdated( 68 ctx context.Context, ethCfg *types.EthereumL2Configs, 69 ) error { 70 // new L2 configured, instatiate the verifier for it. 71 for _, c := range ethCfg.Configs { 72 // if already exists, do nothing 73 if e, ok := v.engines[c.ChainID]; ok { 74 // the blockInterval might have changed, so let just call that. 75 e.EnsureChainID(ctx, c.ChainID, c.BlockInterval, v.isValidator) 76 continue 77 } 78 79 var clt *eth.L2Client 80 if v.isValidator { 81 var ok bool 82 clt, _, ok = v.clients.Get(c.ChainID) 83 if !ok { 84 v.log.Panic("ethereum client not configured for L2", 85 logging.String("chain-id", c.ChainID), 86 logging.String("network-id", c.NetworkID), 87 ) 88 } 89 } 90 91 e := ethcall.NewEngine(v.log, v.cfg, v.isValidator, clt, v.forwarder) 92 e.EnsureChainID(ctx, c.ChainID, c.BlockInterval, v.isValidator) 93 v.engines[c.ChainID] = e 94 95 // if we are restoring from a snapshot we want to delay starting the engine 96 // until we know what block height to use. If we aren't restoring from a snapshot 97 // we are either loading from genesis, or the engine has been added dynamically and 98 // so we want to kick it off 99 if !vgcontext.InProgressSnapshotRestore(ctx) { 100 e.Start() 101 } 102 103 // setup activation listener 104 v.specActivationListener(v.engines[c.ChainID]) 105 } 106 107 return nil 108 }