code.vegaprotocol.io/vega@v0.79.0/core/protocol/all_services.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  import (
    19  	"context"
    20  	"fmt"
    21  
    22  	"code.vegaprotocol.io/vega/core/activitystreak"
    23  	"code.vegaprotocol.io/vega/core/assets"
    24  	"code.vegaprotocol.io/vega/core/banking"
    25  	"code.vegaprotocol.io/vega/core/blockchain"
    26  	"code.vegaprotocol.io/vega/core/blockchain/abci"
    27  	"code.vegaprotocol.io/vega/core/blockchain/nullchain"
    28  	"code.vegaprotocol.io/vega/core/bridges"
    29  	"code.vegaprotocol.io/vega/core/broker"
    30  	"code.vegaprotocol.io/vega/core/checkpoint"
    31  	ethclient "code.vegaprotocol.io/vega/core/client/eth"
    32  	"code.vegaprotocol.io/vega/core/collateral"
    33  	"code.vegaprotocol.io/vega/core/config"
    34  	"code.vegaprotocol.io/vega/core/datasource"
    35  	"code.vegaprotocol.io/vega/core/datasource/external/ethcall"
    36  	"code.vegaprotocol.io/vega/core/datasource/external/ethverifier"
    37  	"code.vegaprotocol.io/vega/core/datasource/spec"
    38  	"code.vegaprotocol.io/vega/core/datasource/spec/adaptors"
    39  	oracleAdaptors "code.vegaprotocol.io/vega/core/datasource/spec/adaptors"
    40  	"code.vegaprotocol.io/vega/core/delegation"
    41  	"code.vegaprotocol.io/vega/core/epochtime"
    42  	"code.vegaprotocol.io/vega/core/evtforward"
    43  	"code.vegaprotocol.io/vega/core/evtforward/ethereum"
    44  	"code.vegaprotocol.io/vega/core/execution"
    45  	"code.vegaprotocol.io/vega/core/execution/common"
    46  	"code.vegaprotocol.io/vega/core/genesis"
    47  	"code.vegaprotocol.io/vega/core/governance"
    48  	"code.vegaprotocol.io/vega/core/limits"
    49  	"code.vegaprotocol.io/vega/core/netparams"
    50  	"code.vegaprotocol.io/vega/core/netparams/checks"
    51  	"code.vegaprotocol.io/vega/core/netparams/dispatch"
    52  	"code.vegaprotocol.io/vega/core/nodewallets"
    53  	"code.vegaprotocol.io/vega/core/notary"
    54  	"code.vegaprotocol.io/vega/core/parties"
    55  	"code.vegaprotocol.io/vega/core/pow"
    56  	"code.vegaprotocol.io/vega/core/processor"
    57  	"code.vegaprotocol.io/vega/core/protocolupgrade"
    58  	"code.vegaprotocol.io/vega/core/referral"
    59  	"code.vegaprotocol.io/vega/core/rewards"
    60  	"code.vegaprotocol.io/vega/core/snapshot"
    61  	"code.vegaprotocol.io/vega/core/spam"
    62  	"code.vegaprotocol.io/vega/core/staking"
    63  	"code.vegaprotocol.io/vega/core/statevar"
    64  	"code.vegaprotocol.io/vega/core/stats"
    65  	"code.vegaprotocol.io/vega/core/teams"
    66  	"code.vegaprotocol.io/vega/core/txcache"
    67  	"code.vegaprotocol.io/vega/core/types"
    68  	"code.vegaprotocol.io/vega/core/validators"
    69  	"code.vegaprotocol.io/vega/core/validators/erc20multisig"
    70  	"code.vegaprotocol.io/vega/core/vegatime"
    71  	"code.vegaprotocol.io/vega/core/vesting"
    72  	"code.vegaprotocol.io/vega/core/volumediscount"
    73  	"code.vegaprotocol.io/vega/core/volumerebate"
    74  	"code.vegaprotocol.io/vega/libs/subscribers"
    75  	"code.vegaprotocol.io/vega/logging"
    76  	"code.vegaprotocol.io/vega/paths"
    77  	"code.vegaprotocol.io/vega/version"
    78  )
    79  
    80  type EthCallEngine interface {
    81  	Start()
    82  	StartAtHeight(height uint64, timestamp uint64)
    83  	Stop()
    84  	MakeResult(specID string, bytes []byte) (ethcall.Result, error)
    85  	CallSpec(ctx context.Context, id string, atBlock uint64) (ethcall.Result, error)
    86  	GetEthTime(ctx context.Context, atBlock uint64) (uint64, error)
    87  	GetRequiredConfirmations(id string) (uint64, error)
    88  	GetInitialTriggerTime(id string) (uint64, error)
    89  	OnSpecActivated(ctx context.Context, spec datasource.Spec) error
    90  	OnSpecDeactivated(ctx context.Context, spec datasource.Spec)
    91  	EnsureChainID(ctx context.Context, chainID string, blockInterval uint64, confirmWithClient bool)
    92  }
    93  
    94  type allServices struct {
    95  	ctx             context.Context
    96  	log             *logging.Logger
    97  	confWatcher     *config.Watcher
    98  	confListenerIDs []int
    99  	conf            config.Config
   100  
   101  	broker *broker.Broker
   102  
   103  	timeService  *vegatime.Svc
   104  	epochService *epochtime.Svc
   105  	eventService *subscribers.Service
   106  
   107  	blockchainClient *blockchain.Client
   108  
   109  	stats *stats.Stats
   110  
   111  	vegaPaths paths.Paths
   112  
   113  	marketActivityTracker   *common.MarketActivityTracker
   114  	statevar                *statevar.Engine
   115  	snapshotEngine          *snapshot.Engine
   116  	executionEngine         *execution.Engine
   117  	governance              *governance.Engine
   118  	collateral              *collateral.Engine
   119  	oracle                  *spec.Engine
   120  	oracleAdaptors          *adaptors.Adaptors
   121  	netParams               *netparams.Store
   122  	delegation              *delegation.Engine
   123  	limits                  *limits.Engine
   124  	rewards                 *rewards.Engine
   125  	checkpoint              *checkpoint.Engine
   126  	spam                    *spam.Engine
   127  	pow                     processor.PoWEngine
   128  	builtinOracle           *spec.Builtin
   129  	codec                   abci.Codec
   130  	ethereumOraclesVerifier *ethverifier.Verifier
   131  
   132  	partiesEngine *parties.SnapshottedEngine
   133  	txCache       *txcache.TxCache
   134  
   135  	assets                *assets.Service
   136  	topology              *validators.Topology
   137  	notary                *notary.SnapshotNotary
   138  	ethCallEngine         EthCallEngine
   139  	witness               *validators.Witness
   140  	banking               *banking.Engine
   141  	genesisHandler        *genesis.Handler
   142  	protocolUpgradeEngine *protocolupgrade.Engine
   143  
   144  	teamsEngine     *teams.SnapshottedEngine
   145  	referralProgram *referral.SnapshottedEngine
   146  
   147  	primaryEventForwarder       *evtforward.Forwarder
   148  	forwarderHeartbeat          *evtforward.Tracker
   149  	primaryEventForwarderEngine EventForwarderEngine
   150  	primaryEthConfirmations     *ethclient.EthereumConfirmations
   151  	primaryEthClient            *ethclient.PrimaryClient
   152  	primaryBridgeView           *bridges.ERC20LogicView
   153  	primaryMultisig             *erc20multisig.Topology
   154  
   155  	secondaryEventForwarderEngine EventForwarderEngine
   156  	secondaryEthConfirmations     *ethclient.EthereumConfirmations
   157  	secondaryEthClient            *ethclient.SecondaryClient
   158  	secondaryBridgeView           *bridges.ERC20LogicView
   159  	secondaryMultisig             *erc20multisig.Topology
   160  
   161  	// staking
   162  	stakingAccounts *staking.Accounting
   163  	stakeVerifier   *staking.StakeVerifier
   164  	stakeCheckpoint *staking.Checkpoint
   165  
   166  	commander  *nodewallets.Commander
   167  	gastimator *processor.Gastimator
   168  
   169  	activityStreak *activitystreak.SnapshotEngine
   170  	vesting        *vesting.SnapshotEngine
   171  	volumeDiscount *volumediscount.SnapshottedEngine
   172  	volumeRebate   *volumerebate.SnapshottedEngine
   173  
   174  	// l2 stuff
   175  	// TODO: instantiate
   176  	l2Clients     *ethclient.L2Clients
   177  	l2Verifiers   *ethverifier.L2Verifiers
   178  	l2CallEngines *L2EthCallEngines
   179  }
   180  
   181  func newServices(
   182  	ctx context.Context,
   183  	log *logging.Logger,
   184  	conf *config.Watcher,
   185  	nodeWallets *nodewallets.NodeWallets,
   186  	primaryEthClient *ethclient.PrimaryClient,
   187  	secondaryEthClient *ethclient.SecondaryClient,
   188  	primaryEthConfirmations *ethclient.EthereumConfirmations,
   189  	secondaryEthConfirmations *ethclient.EthereumConfirmations,
   190  	blockchainClient *blockchain.Client,
   191  	vegaPaths paths.Paths,
   192  	stats *stats.Stats,
   193  	l2Clients *ethclient.L2Clients,
   194  ) (_ *allServices, err error) {
   195  	svcs := &allServices{
   196  		ctx:                       ctx,
   197  		log:                       log,
   198  		confWatcher:               conf,
   199  		conf:                      conf.Get(),
   200  		primaryEthClient:          primaryEthClient,
   201  		secondaryEthClient:        secondaryEthClient,
   202  		l2Clients:                 l2Clients,
   203  		primaryEthConfirmations:   primaryEthConfirmations,
   204  		secondaryEthConfirmations: secondaryEthConfirmations,
   205  		blockchainClient:          blockchainClient,
   206  		stats:                     stats,
   207  		vegaPaths:                 vegaPaths,
   208  	}
   209  
   210  	svcs.broker, err = broker.New(svcs.ctx, svcs.log, svcs.conf.Broker, stats.Blockchain)
   211  	if err != nil {
   212  		svcs.log.Error("unable to initialise broker", logging.Error(err))
   213  		return nil, err
   214  	}
   215  
   216  	svcs.timeService = vegatime.New(svcs.conf.Time, svcs.broker)
   217  	svcs.epochService = epochtime.NewService(svcs.log, svcs.conf.Epoch, svcs.broker)
   218  
   219  	// if we are not a validator, no need to instantiate the commander
   220  	if svcs.conf.IsValidator() {
   221  		// we cannot pass the Chain dependency here (that's set by the blockchain)
   222  		svcs.commander, err = nodewallets.NewCommander(
   223  			svcs.conf.NodeWallet, svcs.log, blockchainClient, nodeWallets.Vega, svcs.stats)
   224  		if err != nil {
   225  			return nil, err
   226  		}
   227  	}
   228  
   229  	svcs.genesisHandler = genesis.New(svcs.log, svcs.conf.Genesis)
   230  	svcs.genesisHandler.OnGenesisTimeLoaded(svcs.timeService.SetTimeNow)
   231  
   232  	svcs.eventService = subscribers.NewService(svcs.log, svcs.broker, svcs.conf.Broker.EventBusClientBufferSize)
   233  	svcs.collateral = collateral.New(svcs.log, svcs.conf.Collateral, svcs.timeService, svcs.broker)
   234  	svcs.epochService.NotifyOnEpoch(svcs.collateral.OnEpochEvent, svcs.collateral.OnEpochRestore)
   235  	svcs.limits = limits.New(svcs.log, svcs.conf.Limits, svcs.timeService, svcs.broker)
   236  
   237  	svcs.netParams = netparams.New(svcs.log, svcs.conf.NetworkParameters, svcs.broker)
   238  
   239  	svcs.primaryMultisig = erc20multisig.NewERC20MultisigTopology(svcs.conf.ERC20MultiSig, svcs.log, nil, svcs.broker, svcs.primaryEthClient, svcs.primaryEthConfirmations, svcs.netParams, "primary")
   240  	svcs.secondaryMultisig = erc20multisig.NewERC20MultisigTopology(svcs.conf.ERC20MultiSig, svcs.log, nil, svcs.broker, svcs.secondaryEthClient, svcs.secondaryEthConfirmations, svcs.netParams, "secondary")
   241  
   242  	if svcs.conf.IsValidator() {
   243  		svcs.topology = validators.NewTopology(svcs.log, svcs.conf.Validators, validators.WrapNodeWallets(nodeWallets), svcs.broker, svcs.conf.IsValidator(), svcs.commander, svcs.primaryMultisig, svcs.secondaryMultisig, svcs.timeService)
   244  	} else {
   245  		svcs.topology = validators.NewTopology(svcs.log, svcs.conf.Validators, nil, svcs.broker, svcs.conf.IsValidator(), nil, svcs.primaryMultisig, svcs.secondaryMultisig, svcs.timeService)
   246  	}
   247  
   248  	svcs.protocolUpgradeEngine = protocolupgrade.New(svcs.log, svcs.conf.ProtocolUpgrade, svcs.broker, svcs.topology, version.Get())
   249  	svcs.witness = validators.NewWitness(svcs.ctx, svcs.log, svcs.conf.Validators, svcs.topology, svcs.commander, svcs.timeService)
   250  
   251  	// this is done to go around circular deps...
   252  	svcs.primaryMultisig.SetWitness(svcs.witness)
   253  	svcs.secondaryMultisig.SetWitness(svcs.witness)
   254  	svcs.primaryEventForwarder = evtforward.New(svcs.log, svcs.conf.EvtForward, svcs.commander, svcs.timeService, svcs.topology)
   255  	svcs.forwarderHeartbeat = evtforward.NewTracker(log, svcs.witness, svcs.timeService)
   256  
   257  	if svcs.conf.HaveEthClient() {
   258  		if len(svcs.conf.EvtForward.EVMBridges) != 1 {
   259  			return nil, fmt.Errorf("require exactly 1 [[EvtForward.EVMBridges]] in configuration file, got: %d", len(svcs.conf.EvtForward.EVMBridges))
   260  		}
   261  
   262  		svcs.primaryBridgeView = bridges.NewERC20LogicView(primaryEthClient, primaryEthConfirmations)
   263  		svcs.secondaryBridgeView = bridges.NewERC20LogicView(secondaryEthClient, secondaryEthConfirmations)
   264  		svcs.primaryEventForwarderEngine = evtforward.NewEngine(svcs.log, svcs.conf.EvtForward.Ethereum)
   265  		svcs.secondaryEventForwarderEngine = evtforward.NewEngine(svcs.log, svcs.conf.EvtForward.EVMBridges[0])
   266  	} else {
   267  		svcs.primaryEventForwarderEngine = evtforward.NewNoopEngine(svcs.log, svcs.conf.EvtForward.Ethereum)
   268  		svcs.secondaryEventForwarderEngine = evtforward.NewNoopEngine(svcs.log, ethereum.NewDefaultConfig())
   269  	}
   270  
   271  	svcs.oracle = spec.NewEngine(svcs.log, svcs.conf.Oracles, svcs.timeService, svcs.broker)
   272  
   273  	svcs.ethCallEngine = ethcall.NewEngine(svcs.log, svcs.conf.EvtForward.EthCall, svcs.conf.IsValidator(), svcs.primaryEthClient, svcs.primaryEventForwarder)
   274  
   275  	svcs.l2CallEngines = NewL2EthCallEngines(svcs.log, svcs.conf.EvtForward.EthCall, svcs.conf.IsValidator(), svcs.l2Clients, svcs.primaryEventForwarder, svcs.oracle.AddSpecActivationListener)
   276  
   277  	svcs.ethereumOraclesVerifier = ethverifier.New(svcs.log, svcs.witness, svcs.timeService, svcs.broker,
   278  		svcs.oracle, svcs.ethCallEngine, svcs.primaryEthConfirmations, svcs.conf.HaveEthClient())
   279  
   280  	svcs.l2Verifiers = ethverifier.NewL2Verifiers(svcs.log, svcs.witness, svcs.timeService, svcs.broker,
   281  		svcs.oracle, svcs.l2Clients, svcs.l2CallEngines, svcs.conf.IsValidator())
   282  
   283  	// Not using the activation event bus event here as on recovery the ethCallEngine needs to have all specs - is this necessary?
   284  	svcs.oracle.AddSpecActivationListener(svcs.ethCallEngine)
   285  
   286  	svcs.builtinOracle = spec.NewBuiltin(svcs.oracle, svcs.timeService)
   287  	svcs.oracleAdaptors = oracleAdaptors.New()
   288  
   289  	// this is done to go around circular deps again..s
   290  	svcs.primaryMultisig.SetEthereumEventSource(svcs.forwarderHeartbeat)
   291  	svcs.secondaryMultisig.SetEthereumEventSource(svcs.forwarderHeartbeat)
   292  
   293  	svcs.stakingAccounts, svcs.stakeVerifier, svcs.stakeCheckpoint = staking.New(
   294  		svcs.log, svcs.conf.Staking, svcs.timeService, svcs.broker, svcs.witness, svcs.primaryEthClient, svcs.netParams, svcs.primaryEventForwarder, svcs.conf.HaveEthClient(), svcs.primaryEthConfirmations, svcs.forwarderHeartbeat,
   295  	)
   296  	svcs.epochService.NotifyOnEpoch(svcs.topology.OnEpochEvent, svcs.topology.OnEpochRestore)
   297  	svcs.epochService.NotifyOnEpoch(stats.OnEpochEvent, stats.OnEpochRestore)
   298  
   299  	svcs.teamsEngine = teams.NewSnapshottedEngine(svcs.broker, svcs.timeService)
   300  
   301  	svcs.partiesEngine = parties.NewSnapshottedEngine(svcs.broker)
   302  	svcs.txCache = txcache.NewTxCache(svcs.commander)
   303  
   304  	svcs.statevar = statevar.New(svcs.log, svcs.conf.StateVar, svcs.broker, svcs.topology, svcs.commander)
   305  	svcs.marketActivityTracker = common.NewMarketActivityTracker(svcs.log, svcs.teamsEngine, svcs.stakingAccounts, svcs.broker, svcs.collateral)
   306  
   307  	svcs.notary = notary.NewWithSnapshot(svcs.log, svcs.conf.Notary, svcs.topology, svcs.broker, svcs.commander)
   308  
   309  	if svcs.conf.IsValidator() {
   310  		svcs.assets, err = assets.New(ctx, svcs.log, svcs.conf.Assets, nodeWallets.Ethereum, svcs.primaryEthClient, svcs.secondaryEthClient, svcs.broker, svcs.primaryBridgeView, svcs.secondaryBridgeView, svcs.notary, svcs.conf.HaveEthClient())
   311  		if err != nil {
   312  			return nil, fmt.Errorf("could not initialize assets engine: %w", err)
   313  		}
   314  	} else {
   315  		svcs.assets, err = assets.New(ctx, svcs.log, svcs.conf.Assets, nil, nil, nil, svcs.broker, nil, nil, svcs.notary, svcs.conf.HaveEthClient())
   316  		if err != nil {
   317  			return nil, fmt.Errorf("could not initialize assets engine: %w", err)
   318  		}
   319  	}
   320  
   321  	// TODO(): this is not pretty
   322  	svcs.topology.SetNotary(svcs.notary)
   323  
   324  	// The referral program is used to compute rewards, and can end when reaching
   325  	// the end of epoch. Since the engine will reject computations when the program
   326  	// is marked as ended, it needs to be one of the last service to register on
   327  	// epoch update, so the computation can happen for this epoch.
   328  	svcs.referralProgram = referral.NewSnapshottedEngine(svcs.broker, svcs.timeService, svcs.marketActivityTracker, svcs.stakingAccounts)
   329  	// The referral program engine must be notified of the epoch change *after* the
   330  	// market activity tracker, as it relies on computation that must happen, at
   331  	// the end of the epoch, in market activity tracker.
   332  	svcs.epochService.NotifyOnEpoch(svcs.referralProgram.OnEpoch, svcs.referralProgram.OnEpochRestore)
   333  
   334  	svcs.volumeDiscount = volumediscount.NewSnapshottedEngine(svcs.broker, svcs.marketActivityTracker)
   335  	svcs.epochService.NotifyOnEpoch(
   336  		svcs.volumeDiscount.OnEpoch,
   337  		svcs.volumeDiscount.OnEpochRestore,
   338  	)
   339  
   340  	svcs.volumeRebate = volumerebate.NewSnapshottedEngine(svcs.broker, svcs.marketActivityTracker)
   341  	svcs.banking = banking.New(svcs.log, svcs.conf.Banking, svcs.collateral, svcs.witness, svcs.timeService,
   342  		svcs.assets, svcs.notary, svcs.broker, svcs.topology, svcs.marketActivityTracker, svcs.primaryBridgeView,
   343  		svcs.secondaryBridgeView, svcs.forwarderHeartbeat, svcs.partiesEngine, svcs.stakingAccounts)
   344  
   345  	// instantiate the execution engine
   346  	svcs.executionEngine = execution.NewEngine(
   347  		svcs.log, svcs.conf.Execution, svcs.timeService, svcs.collateral, svcs.oracle, svcs.broker, svcs.statevar,
   348  		svcs.marketActivityTracker, svcs.assets, svcs.referralProgram, svcs.volumeDiscount, svcs.volumeRebate, svcs.banking, svcs.partiesEngine,
   349  		svcs.txCache,
   350  	)
   351  	svcs.epochService.NotifyOnEpoch(svcs.executionEngine.OnEpochEvent, svcs.executionEngine.OnEpochRestore)
   352  	svcs.epochService.NotifyOnEpoch(svcs.marketActivityTracker.OnEpochEvent, svcs.marketActivityTracker.OnEpochRestore)
   353  	svcs.epochService.NotifyOnEpoch(svcs.banking.OnEpoch, svcs.banking.OnEpochRestore)
   354  	svcs.epochService.NotifyOnEpoch(svcs.volumeRebate.OnEpoch, svcs.volumeRebate.OnEpochRestore)
   355  
   356  	svcs.gastimator = processor.NewGastimator(svcs.executionEngine)
   357  
   358  	svcs.spam = spam.New(svcs.log, svcs.conf.Spam, svcs.epochService, svcs.stakingAccounts)
   359  
   360  	if svcs.conf.Blockchain.ChainProvider == blockchain.ProviderNullChain {
   361  		// Use staking-loop to pretend a dummy builtin assets deposited with the faucet was staked
   362  		svcs.codec = &processor.NullBlockchainTxCodec{}
   363  
   364  		if svcs.conf.HaveEthClient() {
   365  			svcs.governance = governance.NewEngine(svcs.log, svcs.conf.Governance, svcs.stakingAccounts, svcs.timeService, svcs.broker, svcs.assets, svcs.witness, svcs.executionEngine, svcs.netParams, svcs.banking)
   366  			svcs.delegation = delegation.New(svcs.log, svcs.conf.Delegation, svcs.broker, svcs.topology, svcs.stakingAccounts, svcs.epochService, svcs.timeService)
   367  		} else {
   368  			stakingLoop := nullchain.NewStakingLoop(svcs.collateral, svcs.assets)
   369  			svcs.netParams.Watch([]netparams.WatchParam{
   370  				{
   371  					Param:   netparams.RewardAsset,
   372  					Watcher: stakingLoop.OnStakingAsstUpdate,
   373  				},
   374  			}...)
   375  			svcs.governance = governance.NewEngine(svcs.log, svcs.conf.Governance, stakingLoop, svcs.timeService, svcs.broker, svcs.assets, svcs.witness, svcs.executionEngine, svcs.netParams, svcs.banking)
   376  			svcs.delegation = delegation.New(svcs.log, svcs.conf.Delegation, svcs.broker, svcs.topology, stakingLoop, svcs.epochService, svcs.timeService)
   377  		}
   378  
   379  		// disable spam protection based on config
   380  		if !svcs.conf.Blockchain.Null.SpamProtection {
   381  			svcs.spam.DisableSpamProtection() // Disable evaluation for the spam policies by the Spam Engine
   382  		}
   383  	} else {
   384  		svcs.codec = &processor.TxCodec{}
   385  		svcs.governance = governance.NewEngine(svcs.log, svcs.conf.Governance, svcs.stakingAccounts, svcs.timeService, svcs.broker, svcs.assets, svcs.witness, svcs.executionEngine, svcs.netParams, svcs.banking)
   386  		svcs.delegation = delegation.New(svcs.log, svcs.conf.Delegation, svcs.broker, svcs.topology, svcs.stakingAccounts, svcs.epochService, svcs.timeService)
   387  	}
   388  
   389  	svcs.activityStreak = activitystreak.NewSnapshotEngine(svcs.log, svcs.executionEngine, svcs.broker)
   390  	svcs.epochService.NotifyOnEpoch(
   391  		svcs.activityStreak.OnEpochEvent,
   392  		svcs.activityStreak.OnEpochRestore,
   393  	)
   394  
   395  	svcs.vesting = vesting.NewSnapshotEngine(svcs.log, svcs.collateral, svcs.activityStreak, svcs.broker, svcs.assets, svcs.partiesEngine, svcs.timeService, svcs.stakingAccounts)
   396  	svcs.timeService.NotifyOnTick(svcs.vesting.OnTick)
   397  	svcs.rewards = rewards.New(svcs.log, svcs.conf.Rewards, svcs.broker, svcs.delegation, svcs.epochService, svcs.collateral, svcs.timeService, svcs.marketActivityTracker, svcs.topology, svcs.vesting, svcs.banking, svcs.activityStreak)
   398  
   399  	// register this after the rewards engine is created to make sure the on epoch is called in the right order.
   400  	svcs.epochService.NotifyOnEpoch(svcs.vesting.OnEpochEvent, svcs.vesting.OnEpochRestore)
   401  
   402  	svcs.registerTimeServiceCallbacks()
   403  
   404  	// checkpoint engine
   405  	svcs.checkpoint, err = checkpoint.New(svcs.log, svcs.conf.Checkpoint, svcs.assets, svcs.collateral, svcs.governance, svcs.netParams, svcs.delegation, svcs.epochService, svcs.topology, svcs.banking, svcs.stakeCheckpoint, svcs.primaryMultisig, svcs.marketActivityTracker, svcs.executionEngine)
   406  	if err != nil {
   407  		return nil, err
   408  	}
   409  
   410  	// register the callback to startup stuff when checkpoint is loaded
   411  	svcs.checkpoint.RegisterOnCheckpointLoaded(func(_ context.Context) {
   412  		// checkpoint have been loaded
   413  		// which means that genesis has been loaded as well
   414  		// we should be fully ready to start the event sourcing from ethereum
   415  		svcs.vesting.OnCheckpointLoaded()
   416  	})
   417  
   418  	svcs.genesisHandler.OnGenesisAppStateLoaded(
   419  		// be sure to keep this in order.
   420  		// the node upon genesis will load all asset first in the node
   421  		// state. This is important to happened first as we will load the
   422  		// asset which will be considered as the governance tokesvcs.
   423  		svcs.UponGenesis,
   424  		// This needs to happen always after, as it defined the network
   425  		// parameters, one of them is  the Governance Token asset ID.
   426  		// which if not loaded in the previous state, then will make the node
   427  		// panic at startup.
   428  		svcs.netParams.UponGenesis,
   429  		svcs.topology.LoadValidatorsOnGenesis,
   430  		svcs.limits.UponGenesis,
   431  		svcs.checkpoint.UponGenesis,
   432  	)
   433  
   434  	svcs.snapshotEngine, err = snapshot.NewEngine(svcs.vegaPaths, svcs.conf.Snapshot, svcs.log, svcs.timeService, svcs.stats.Blockchain)
   435  	if err != nil {
   436  		return nil, fmt.Errorf("could not initialize the snapshot engine: %w", err)
   437  	}
   438  
   439  	// notify delegation, rewards, and accounting on changes in the validator pub key
   440  	svcs.topology.NotifyOnKeyChange(svcs.governance.ValidatorKeyChanged)
   441  
   442  	svcs.snapshotEngine.AddProviders(
   443  		svcs.txCache,
   444  		svcs.checkpoint,
   445  		svcs.collateral,
   446  		svcs.governance,
   447  		svcs.delegation,
   448  		svcs.netParams,
   449  		svcs.epochService,
   450  		svcs.assets,
   451  		svcs.banking,
   452  		svcs.witness,
   453  		svcs.notary,
   454  		svcs.stakingAccounts,
   455  		svcs.stakeVerifier,
   456  		svcs.limits,
   457  		svcs.topology,
   458  		svcs.primaryEventForwarder,
   459  		svcs.executionEngine,
   460  		svcs.marketActivityTracker,
   461  		svcs.statevar,
   462  		svcs.primaryMultisig,
   463  		erc20multisig.NewEVMTopologies(svcs.secondaryMultisig),
   464  		svcs.protocolUpgradeEngine,
   465  		svcs.ethereumOraclesVerifier,
   466  		svcs.vesting,
   467  		svcs.activityStreak,
   468  		svcs.referralProgram,
   469  		svcs.volumeDiscount,
   470  		svcs.teamsEngine,
   471  		svcs.spam,
   472  		svcs.l2Verifiers,
   473  		svcs.partiesEngine,
   474  		svcs.forwarderHeartbeat,
   475  		svcs.volumeRebate,
   476  	)
   477  
   478  	pow := pow.New(svcs.log, svcs.conf.PoW)
   479  
   480  	if svcs.conf.Blockchain.ChainProvider == blockchain.ProviderNullChain {
   481  		pow.DisableVerification()
   482  	}
   483  	svcs.pow = pow
   484  	svcs.snapshotEngine.AddProviders(pow)
   485  	powWatchers := []netparams.WatchParam{
   486  		{
   487  			Param:   netparams.SpamPoWNumberOfPastBlocks,
   488  			Watcher: pow.UpdateSpamPoWNumberOfPastBlocks,
   489  		},
   490  		{
   491  			Param:   netparams.SpamPoWDifficulty,
   492  			Watcher: pow.UpdateSpamPoWDifficulty,
   493  		},
   494  		{
   495  			Param:   netparams.SpamPoWHashFunction,
   496  			Watcher: pow.UpdateSpamPoWHashFunction,
   497  		},
   498  		{
   499  			Param:   netparams.SpamPoWIncreasingDifficulty,
   500  			Watcher: pow.UpdateSpamPoWIncreasingDifficulty,
   501  		},
   502  		{
   503  			Param:   netparams.SpamPoWNumberOfTxPerBlock,
   504  			Watcher: pow.UpdateSpamPoWNumberOfTxPerBlock,
   505  		},
   506  	}
   507  
   508  	// The team engine is used to know the team a party belongs to. The computation
   509  	// of the referral program rewards requires this information. Since the team
   510  	// switches happen when the end of epoch is reached, it needs to be one of the
   511  	// last services to register on epoch update, so the computation is made based
   512  	// on the team the parties belonged to during the epoch and not the new one.
   513  	svcs.epochService.NotifyOnEpoch(svcs.teamsEngine.OnEpoch, svcs.teamsEngine.OnEpochRestore)
   514  
   515  	// setup config reloads for all engines / services /etc
   516  	svcs.registerConfigWatchers()
   517  
   518  	// setup some network parameters runtime validations and network parameters
   519  	// updates dispatches this must come before we try to load from a snapshot,
   520  	// which happens in startBlockchain
   521  	if err := svcs.setupNetParameters(powWatchers); err != nil {
   522  		return nil, err
   523  	}
   524  
   525  	return svcs, nil
   526  }
   527  
   528  func (svcs *allServices) registerTimeServiceCallbacks() {
   529  	svcs.timeService.NotifyOnTick(
   530  		svcs.broker.OnTick,
   531  		svcs.epochService.OnTick,
   532  		svcs.builtinOracle.OnTick,
   533  		svcs.netParams.OnTick,
   534  		svcs.primaryMultisig.OnTick,
   535  		svcs.secondaryMultisig.OnTick,
   536  		svcs.witness.OnTick,
   537  
   538  		svcs.primaryEventForwarder.OnTick,
   539  		svcs.stakeVerifier.OnTick,
   540  		svcs.statevar.OnTick,
   541  		svcs.executionEngine.OnTick,
   542  		svcs.delegation.OnTick,
   543  		svcs.notary.OnTick,
   544  		svcs.banking.OnTick,
   545  		svcs.assets.OnTick,
   546  		svcs.limits.OnTick,
   547  
   548  		svcs.ethereumOraclesVerifier.OnTick,
   549  		svcs.l2Verifiers.OnTick,
   550  		svcs.forwarderHeartbeat.OnTick,
   551  	)
   552  }
   553  
   554  func (svcs *allServices) Stop() {
   555  	svcs.confWatcher.Unregister(svcs.confListenerIDs)
   556  	svcs.primaryEventForwarderEngine.Stop()
   557  	svcs.secondaryEventForwarderEngine.Stop()
   558  	svcs.snapshotEngine.Close()
   559  	svcs.ethCallEngine.Stop()
   560  }
   561  
   562  func (svcs *allServices) registerConfigWatchers() {
   563  	svcs.confListenerIDs = svcs.confWatcher.OnConfigUpdateWithID(
   564  		func(cfg config.Config) { svcs.executionEngine.ReloadConf(cfg.Execution) },
   565  		func(cfg config.Config) { svcs.notary.ReloadConf(cfg.Notary) },
   566  		func(cfg config.Config) { svcs.primaryEventForwarderEngine.ReloadConf(cfg.EvtForward.Ethereum) },
   567  		func(cfg config.Config) { svcs.primaryEventForwarder.ReloadConf(cfg.EvtForward) },
   568  		func(cfg config.Config) {
   569  			if len(cfg.EvtForward.EVMBridges) > 0 {
   570  				svcs.secondaryEventForwarderEngine.ReloadConf(cfg.EvtForward.EVMBridges[0])
   571  			}
   572  		},
   573  		func(cfg config.Config) { svcs.topology.ReloadConf(cfg.Validators) },
   574  		func(cfg config.Config) { svcs.witness.ReloadConf(cfg.Validators) },
   575  		func(cfg config.Config) { svcs.assets.ReloadConf(cfg.Assets) },
   576  		func(cfg config.Config) { svcs.banking.ReloadConf(cfg.Banking) },
   577  		func(cfg config.Config) { svcs.governance.ReloadConf(cfg.Governance) },
   578  		func(cfg config.Config) { svcs.stats.ReloadConf(cfg.Stats) },
   579  		func(cfg config.Config) { svcs.broker.ReloadConf(cfg.Broker) },
   580  	)
   581  
   582  	if svcs.conf.HaveEthClient() {
   583  		svcs.confListenerIDs = svcs.confWatcher.OnConfigUpdateWithID(
   584  			func(cfg config.Config) { svcs.l2Clients.ReloadConf(cfg.Ethereum) },
   585  		)
   586  	}
   587  
   588  	svcs.timeService.NotifyOnTick(svcs.confWatcher.OnTimeUpdate)
   589  }
   590  
   591  func (svcs *allServices) setupNetParameters(powWatchers []netparams.WatchParam) error {
   592  	// now we are going to setup some network parameters which can be done
   593  	// through runtime checks
   594  	// e.g: changing the governance asset require the Assets and Collateral engines, so we can ensure any changes there are made for a valid asset
   595  
   596  	if err := svcs.netParams.AddRules(
   597  		netparams.ParamStringRules(
   598  			netparams.RewardAsset,
   599  			checks.RewardAssetUpdate(svcs.log, svcs.assets, svcs.collateral),
   600  		),
   601  	); err != nil {
   602  		return err
   603  	}
   604  
   605  	spamWatchers := []netparams.WatchParam{}
   606  	if svcs.spam != nil {
   607  		spamWatchers = []netparams.WatchParam{
   608  			{
   609  				Param:   netparams.MarketAggressiveOrderBlockDelay,
   610  				Watcher: svcs.txCache.OnNumBlocksToDelayUpdated,
   611  			},
   612  			{
   613  				Param:   netparams.SpamProtectionMaxVotes,
   614  				Watcher: svcs.spam.OnMaxVotesChanged,
   615  			},
   616  			{
   617  				Param:   netparams.StakingAndDelegationRewardMinimumValidatorStake,
   618  				Watcher: svcs.spam.OnMinValidatorTokensChanged,
   619  			},
   620  			{
   621  				Param:   netparams.SpamProtectionMaxProposals,
   622  				Watcher: svcs.spam.OnMaxProposalsChanged,
   623  			},
   624  			{
   625  				Param:   netparams.SpamProtectionMaxDelegations,
   626  				Watcher: svcs.spam.OnMaxDelegationsChanged,
   627  			},
   628  			{
   629  				Param:   netparams.SpamProtectionMinTokensForProposal,
   630  				Watcher: svcs.spam.OnMinTokensForProposalChanged,
   631  			},
   632  			{
   633  				Param:   netparams.SpamProtectionMinTokensForVoting,
   634  				Watcher: svcs.spam.OnMinTokensForVotingChanged,
   635  			},
   636  			{
   637  				Param:   netparams.SpamProtectionMinTokensForDelegation,
   638  				Watcher: svcs.spam.OnMinTokensForDelegationChanged,
   639  			},
   640  			{
   641  				Param:   netparams.TransferMaxCommandsPerEpoch,
   642  				Watcher: svcs.spam.OnMaxTransfersChanged,
   643  			},
   644  			{
   645  				Param:   netparams.SpamProtectionMinMultisigUpdates,
   646  				Watcher: svcs.spam.OnMinTokensForMultisigUpdatesChanged,
   647  			},
   648  			{
   649  				Param:   netparams.SpamProtectionMaxMultisigUpdates,
   650  				Watcher: svcs.spam.OnMaxMultisigUpdatesChanged,
   651  			},
   652  			{
   653  				Param:   netparams.ReferralProgramMinStakedVegaTokens,
   654  				Watcher: svcs.spam.OnMinTokensForReferral,
   655  			},
   656  			{
   657  				Param:   netparams.SpamProtectionMaxCreateReferralSet,
   658  				Watcher: svcs.spam.OnMaxCreateReferralSet,
   659  			},
   660  			{
   661  				Param:   netparams.SpamProtectionMaxUpdatePartyProfile,
   662  				Watcher: svcs.spam.OnMaxPartyProfile,
   663  			},
   664  			{
   665  				Param:   netparams.SpamProtectionMaxUpdateReferralSet,
   666  				Watcher: svcs.spam.OnMaxUpdateReferralSet,
   667  			},
   668  			{
   669  				Param:   netparams.SpamProtectionMaxApplyReferralCode,
   670  				Watcher: svcs.spam.OnMaxApplyReferralCode,
   671  			},
   672  		}
   673  	}
   674  
   675  	watchers := []netparams.WatchParam{
   676  		{
   677  			Param:   netparams.RewardAsset,
   678  			Watcher: svcs.banking.OnStakingAsset,
   679  		},
   680  		{
   681  			Param:   netparams.RewardAsset,
   682  			Watcher: svcs.vesting.OnStakingAssetUpdate,
   683  		},
   684  		{
   685  			Param:   netparams.SpamProtectionBalanceSnapshotFrequency,
   686  			Watcher: svcs.collateral.OnBalanceSnapshotFrequencyUpdated,
   687  		},
   688  		{
   689  			Param:   netparams.MinEpochsInTeamForMetricRewardEligibility,
   690  			Watcher: svcs.marketActivityTracker.OnMinEpochsInTeamForRewardEligibilityUpdated,
   691  		},
   692  		{
   693  			Param:   netparams.MinBlockCapacity,
   694  			Watcher: svcs.gastimator.OnMinBlockCapacityUpdate,
   695  		},
   696  		{
   697  			Param:   netparams.MaxGasPerBlock,
   698  			Watcher: svcs.gastimator.OnMaxGasUpdate,
   699  		},
   700  		{
   701  			Param:   netparams.DefaultGas,
   702  			Watcher: svcs.gastimator.OnDefaultGasUpdate,
   703  		},
   704  		{
   705  			Param:   netparams.ValidatorsVoteRequired,
   706  			Watcher: svcs.protocolUpgradeEngine.OnRequiredMajorityChanged,
   707  		},
   708  		{
   709  			Param:   netparams.ValidatorPerformanceScalingFactor,
   710  			Watcher: svcs.topology.OnPerformanceScalingChanged,
   711  		},
   712  		{
   713  			Param:   netparams.ValidatorsEpochLength,
   714  			Watcher: svcs.topology.OnEpochLengthUpdate,
   715  		},
   716  		{
   717  			Param:   netparams.NumberOfTendermintValidators,
   718  			Watcher: svcs.topology.UpdateNumberOfTendermintValidators,
   719  		},
   720  		{
   721  			Param:   netparams.ValidatorIncumbentBonus,
   722  			Watcher: svcs.topology.UpdateValidatorIncumbentBonusFactor,
   723  		},
   724  		{
   725  			Param:   netparams.NumberEthMultisigSigners,
   726  			Watcher: svcs.topology.UpdateNumberEthMultisigSigners,
   727  		},
   728  		{
   729  			Param:   netparams.MultipleOfTendermintValidatorsForEtsatzSet,
   730  			Watcher: svcs.topology.UpdateErsatzValidatorsFactor,
   731  		},
   732  		{
   733  			Param:   netparams.MinimumEthereumEventsForNewValidator,
   734  			Watcher: svcs.topology.UpdateMinimumEthereumEventsForNewValidator,
   735  		},
   736  		{
   737  			Param:   netparams.StakingAndDelegationRewardMinimumValidatorStake,
   738  			Watcher: svcs.topology.UpdateMinimumRequireSelfStake,
   739  		},
   740  		{
   741  			Param:   netparams.DelegationMinAmount,
   742  			Watcher: svcs.delegation.OnMinAmountChanged,
   743  		},
   744  		{
   745  			Param:   netparams.RewardAsset,
   746  			Watcher: dispatch.RewardAssetUpdate(svcs.log, svcs.assets),
   747  		},
   748  		{
   749  			Param:   netparams.MinimumMarginQuantumMultiple,
   750  			Watcher: svcs.executionEngine.OnMinimalMarginQuantumMultipleUpdate,
   751  		},
   752  		{
   753  			Param:   netparams.MinimumHoldingQuantumMultiple,
   754  			Watcher: svcs.executionEngine.OnMinimalHoldingQuantumMultipleUpdate,
   755  		},
   756  		{
   757  			Param:   netparams.MarketMarginScalingFactors,
   758  			Watcher: svcs.executionEngine.OnMarketMarginScalingFactorsUpdate,
   759  		},
   760  		{
   761  			Param:   netparams.MarketFeeFactorsMakerFee,
   762  			Watcher: svcs.executionEngine.OnMarketFeeFactorsMakerFeeUpdate,
   763  		},
   764  		{
   765  			Param:   netparams.MarketFeeFactorsInfrastructureFee,
   766  			Watcher: svcs.executionEngine.OnMarketFeeFactorsInfrastructureFeeUpdate,
   767  		},
   768  		{
   769  			Param:   netparams.MarketFeeFactorsTreasuryFee,
   770  			Watcher: svcs.executionEngine.OnMarketFeeFactorsTreasuryFeeUpdate,
   771  		},
   772  		{
   773  			Param:   netparams.MarketFeeFactorsBuyBackFee,
   774  			Watcher: svcs.executionEngine.OnMarketFeeFactorsBuyBackFeeUpdate,
   775  		},
   776  		{
   777  			Param:   netparams.MarketFeeFactorsTreasuryFee,
   778  			Watcher: svcs.volumeRebate.OnMarketFeeFactorsTreasuryFeeUpdate,
   779  		},
   780  		{
   781  			Param:   netparams.MarketFeeFactorsBuyBackFee,
   782  			Watcher: svcs.volumeRebate.OnMarketFeeFactorsBuyBackFeeUpdate,
   783  		},
   784  		{
   785  			Param:   netparams.MarketValueWindowLength,
   786  			Watcher: svcs.executionEngine.OnMarketValueWindowLengthUpdate,
   787  		},
   788  		{
   789  			Param:   netparams.NetworkWideAuctionDuration,
   790  			Watcher: svcs.executionEngine.OnNetworkWideAuctionDurationUpdated,
   791  		},
   792  		{
   793  			Param: netparams.BlockchainsPrimaryEthereumConfig,
   794  			Watcher: func(ctx context.Context, cfg interface{}) error {
   795  				ethCfg, err := types.EthereumConfigFromUntypedProto(cfg)
   796  				if err != nil {
   797  					return fmt.Errorf("invalid primary ethereum configuration: %w", err)
   798  				}
   799  
   800  				if err := svcs.primaryEthClient.UpdateEthereumConfig(ctx, ethCfg); err != nil {
   801  					return err
   802  				}
   803  
   804  				svcs.assets.SetBridgeChainID(ethCfg.ChainID(), true)
   805  				if err := svcs.primaryEventForwarderEngine.SetupEthereumEngine(
   806  					svcs.primaryEthClient,
   807  					svcs.primaryEventForwarder,
   808  					svcs.conf.EvtForward.Ethereum,
   809  					ethCfg,
   810  					svcs.assets); err != nil {
   811  					return err
   812  				}
   813  				svcs.forwarderHeartbeat.RegisterForwarder(
   814  					svcs.primaryEventForwarderEngine,
   815  					ethCfg.ChainID(),
   816  					ethCfg.CollateralBridge().HexAddress(),
   817  					ethCfg.StakingBridge().HexAddress(),
   818  					ethCfg.VestingBridge().HexAddress(),
   819  					ethCfg.MultiSigControl().HexAddress(),
   820  				)
   821  				return nil
   822  			},
   823  		},
   824  		{
   825  			Param: netparams.BlockchainsEVMBridgeConfigs,
   826  			Watcher: func(ctx context.Context, cfg interface{}) error {
   827  				cfgs, err := types.EVMChainConfigFromUntypedProto(cfg)
   828  				if err != nil {
   829  					return fmt.Errorf("invalid secondary ethereum configuration: %w", err)
   830  				}
   831  
   832  				ethCfg := cfgs.Configs[0]
   833  
   834  				if err := svcs.secondaryEthClient.UpdateEthereumConfig(ctx, ethCfg); err != nil {
   835  					return err
   836  				}
   837  
   838  				svcs.assets.SetBridgeChainID(ethCfg.ChainID(), false)
   839  
   840  				var bridgeCfg ethereum.Config
   841  				if svcs.conf.HaveEthClient() {
   842  					bridgeCfg = svcs.conf.EvtForward.EVMBridges[0]
   843  				}
   844  
   845  				if err := svcs.secondaryEventForwarderEngine.SetupSecondaryEthereumEngine(
   846  					svcs.secondaryEthClient,
   847  					svcs.primaryEventForwarder,
   848  					bridgeCfg,
   849  					ethCfg,
   850  					svcs.assets,
   851  				); err != nil {
   852  					return err
   853  				}
   854  
   855  				svcs.forwarderHeartbeat.RegisterForwarder(
   856  					svcs.secondaryEventForwarderEngine,
   857  					ethCfg.ChainID(),
   858  					ethCfg.CollateralBridge().HexAddress(),
   859  					ethCfg.MultiSigControl().HexAddress(),
   860  				)
   861  
   862  				return nil
   863  			},
   864  		},
   865  		{
   866  			Param:   netparams.MaxPeggedOrders,
   867  			Watcher: svcs.executionEngine.OnMaxPeggedOrderUpdate,
   868  		},
   869  		{
   870  			Param:   netparams.MarketMinLpStakeQuantumMultiple,
   871  			Watcher: svcs.executionEngine.OnMinLpStakeQuantumMultipleUpdate,
   872  		},
   873  		{
   874  			Param:   netparams.RewardMarketCreationQuantumMultiple,
   875  			Watcher: svcs.executionEngine.OnMarketCreationQuantumMultipleUpdate,
   876  		},
   877  		{
   878  			Param:   netparams.MarketLiquidityMaximumLiquidityFeeFactorLevel,
   879  			Watcher: svcs.executionEngine.OnMarketLiquidityMaximumLiquidityFeeFactorLevelUpdate,
   880  		},
   881  		{
   882  			Param:   netparams.MarketAuctionMinimumDuration,
   883  			Watcher: svcs.executionEngine.OnMarketAuctionMinimumDurationUpdate,
   884  		},
   885  		{
   886  			Param:   netparams.MarketAuctionMaximumDuration,
   887  			Watcher: svcs.executionEngine.OnMarketAuctionMaximumDurationUpdate,
   888  		},
   889  		{
   890  			Param:   netparams.MarketProbabilityOfTradingTauScaling,
   891  			Watcher: svcs.executionEngine.OnMarketProbabilityOfTradingTauScalingUpdate,
   892  		},
   893  		{
   894  			Param:   netparams.MarketMinProbabilityOfTradingForLPOrders,
   895  			Watcher: svcs.executionEngine.OnMarketMinProbabilityOfTradingForLPOrdersUpdate,
   896  		},
   897  		// Liquidity version 2.
   898  		{
   899  			Param:   netparams.MarketLiquidityBondPenaltyParameter,
   900  			Watcher: svcs.executionEngine.OnMarketLiquidityV2BondPenaltyUpdate,
   901  		},
   902  		{
   903  			Param:   netparams.MarketLiquidityEarlyExitPenalty,
   904  			Watcher: svcs.executionEngine.OnMarketLiquidityV2EarlyExitPenaltyUpdate,
   905  		},
   906  		{
   907  			Param:   netparams.MarketLiquidityMaximumLiquidityFeeFactorLevel,
   908  			Watcher: svcs.executionEngine.OnMarketLiquidityV2MaximumLiquidityFeeFactorLevelUpdate,
   909  		},
   910  		{
   911  			Param:   netparams.MarketLiquiditySLANonPerformanceBondPenaltySlope,
   912  			Watcher: svcs.executionEngine.OnMarketLiquidityV2SLANonPerformanceBondPenaltySlopeUpdate,
   913  		},
   914  		{
   915  			Param:   netparams.MarketLiquiditySLANonPerformanceBondPenaltyMax,
   916  			Watcher: svcs.executionEngine.OnMarketLiquidityV2SLANonPerformanceBondPenaltyMaxUpdate,
   917  		},
   918  		{
   919  			Param:   netparams.MarketLiquidityStakeToCCYVolume,
   920  			Watcher: svcs.executionEngine.OnMarketLiquidityV2StakeToCCYVolumeUpdate,
   921  		},
   922  		{
   923  			Param:   netparams.MarketLiquidityProvidersFeeCalculationTimeStep,
   924  			Watcher: svcs.executionEngine.OnMarketLiquidityV2ProvidersFeeCalculationTimeStep,
   925  		},
   926  		// End of liquidity version 2.
   927  		{
   928  			Param:   netparams.ValidatorsEpochLength,
   929  			Watcher: svcs.epochService.OnEpochLengthUpdate,
   930  		},
   931  		{
   932  			Param:   netparams.StakingAndDelegationRewardMaxPayoutPerParticipant,
   933  			Watcher: svcs.rewards.UpdateMaxPayoutPerParticipantForStakingRewardScheme,
   934  		},
   935  		{
   936  			Param:   netparams.StakingAndDelegationRewardDelegatorShare,
   937  			Watcher: svcs.rewards.UpdateDelegatorShareForStakingRewardScheme,
   938  		},
   939  		{
   940  			Param:   netparams.StakingAndDelegationRewardMinimumValidatorStake,
   941  			Watcher: svcs.rewards.UpdateMinimumValidatorStakeForStakingRewardScheme,
   942  		},
   943  		{
   944  			Param:   netparams.RewardAsset,
   945  			Watcher: svcs.rewards.UpdateAssetForStakingAndDelegation,
   946  		},
   947  		{
   948  			Param:   netparams.StakingAndDelegationRewardCompetitionLevel,
   949  			Watcher: svcs.rewards.UpdateCompetitionLevelForStakingRewardScheme,
   950  		},
   951  		{
   952  			Param:   netparams.StakingAndDelegationRewardsMinValidators,
   953  			Watcher: svcs.rewards.UpdateMinValidatorsStakingRewardScheme,
   954  		},
   955  		{
   956  			Param:   netparams.StakingAndDelegationRewardOptimalStakeMultiplier,
   957  			Watcher: svcs.rewards.UpdateOptimalStakeMultiplierStakingRewardScheme,
   958  		},
   959  		{
   960  			Param:   netparams.ErsatzvalidatorsRewardFactor,
   961  			Watcher: svcs.rewards.UpdateErsatzRewardFactor,
   962  		},
   963  		{
   964  			Param:   netparams.ValidatorsVoteRequired,
   965  			Watcher: svcs.witness.OnDefaultValidatorsVoteRequiredUpdate,
   966  		},
   967  		{
   968  			Param:   netparams.ValidatorsVoteRequired,
   969  			Watcher: svcs.notary.OnDefaultValidatorsVoteRequiredUpdate,
   970  		},
   971  		{
   972  			Param:   netparams.NetworkCheckpointTimeElapsedBetweenCheckpoints,
   973  			Watcher: svcs.checkpoint.OnTimeElapsedUpdate,
   974  		},
   975  		{
   976  			Param:   netparams.SnapshotIntervalLength,
   977  			Watcher: svcs.snapshotEngine.OnSnapshotIntervalUpdate,
   978  		},
   979  		{
   980  			Param:   netparams.ValidatorsVoteRequired,
   981  			Watcher: svcs.statevar.OnDefaultValidatorsVoteRequiredUpdate,
   982  		},
   983  		{
   984  			Param:   netparams.FloatingPointUpdatesDuration,
   985  			Watcher: svcs.statevar.OnFloatingPointUpdatesDurationUpdate,
   986  		},
   987  		{
   988  			Param:   netparams.TransferFeeFactor,
   989  			Watcher: svcs.banking.OnTransferFeeFactorUpdate,
   990  		},
   991  		{
   992  			Param:   netparams.RewardsUpdateFrequency,
   993  			Watcher: svcs.banking.OnRewardsUpdateFrequencyUpdate,
   994  		},
   995  		{
   996  			Param:   netparams.TransferFeeMaxQuantumAmount,
   997  			Watcher: svcs.banking.OnMaxQuantumAmountUpdate,
   998  		},
   999  		{
  1000  			Param:   netparams.TransferFeeDiscountDecayFraction,
  1001  			Watcher: svcs.banking.OnTransferFeeDiscountDecayFractionUpdate,
  1002  		},
  1003  		{
  1004  			Param:   netparams.TransferFeeDiscountMinimumTrackedAmount,
  1005  			Watcher: svcs.banking.OnTransferFeeDiscountMinimumTrackedAmountUpdate,
  1006  		},
  1007  		{
  1008  			Param:   netparams.GovernanceTransferMaxFraction,
  1009  			Watcher: svcs.banking.OnMaxFractionChanged,
  1010  		},
  1011  		{
  1012  			Param:   netparams.GovernanceTransferMaxAmount,
  1013  			Watcher: svcs.banking.OnMaxAmountChanged,
  1014  		},
  1015  		{
  1016  			Param:   netparams.TransferMinTransferQuantumMultiple,
  1017  			Watcher: svcs.banking.OnMinTransferQuantumMultiple,
  1018  		},
  1019  		{
  1020  			Param:   netparams.SpamProtectionMinimumWithdrawalQuantumMultiple,
  1021  			Watcher: svcs.banking.OnMinWithdrawQuantumMultiple,
  1022  		},
  1023  		{
  1024  			Param: netparams.BlockchainsPrimaryEthereumConfig,
  1025  			Watcher: func(_ context.Context, cfg interface{}) error {
  1026  				// nothing to do if not a validator
  1027  				if !svcs.conf.HaveEthClient() {
  1028  					return nil
  1029  				}
  1030  				ethCfg, err := types.EthereumConfigFromUntypedProto(cfg)
  1031  				if err != nil {
  1032  					return fmt.Errorf("invalid primary ethereum configuration: %w", err)
  1033  				}
  1034  
  1035  				svcs.primaryEthConfirmations.UpdateConfirmations(ethCfg.Confirmations())
  1036  				return nil
  1037  			},
  1038  		},
  1039  		{
  1040  			Param: netparams.BlockchainsEVMBridgeConfigs,
  1041  			Watcher: func(_ context.Context, cfg interface{}) error {
  1042  				// nothing to do if not a validator
  1043  				if !svcs.conf.HaveEthClient() {
  1044  					return nil
  1045  				}
  1046  				ethCfg, err := types.EVMChainConfigFromUntypedProto(cfg)
  1047  				if err != nil {
  1048  					return fmt.Errorf("invalid secondary ethereum configuration: %w", err)
  1049  				}
  1050  
  1051  				svcs.secondaryEthConfirmations.UpdateConfirmations(ethCfg.Configs[0].Confirmations())
  1052  				return nil
  1053  			},
  1054  		},
  1055  		{
  1056  			Param: netparams.BlockchainsPrimaryEthereumConfig,
  1057  			Watcher: func(ctx context.Context, cfg interface{}) error {
  1058  				ethCfg, err := types.EthereumConfigFromUntypedProto(cfg)
  1059  				if err != nil {
  1060  					return fmt.Errorf("invalid primary ethereum configuration: %w", err)
  1061  				}
  1062  
  1063  				// every 1 block for the main ethereum chain is acceptable
  1064  				svcs.ethCallEngine.EnsureChainID(ctx, ethCfg.ChainID(), 1, svcs.conf.HaveEthClient())
  1065  
  1066  				// nothing to do if not a validator
  1067  				if !svcs.conf.HaveEthClient() {
  1068  					return nil
  1069  				}
  1070  
  1071  				svcs.witness.SetPrimaryDefaultConfirmations(ethCfg.ChainID(), ethCfg.Confirmations())
  1072  				return nil
  1073  			},
  1074  		},
  1075  		{
  1076  			Param: netparams.BlockchainsPrimaryEthereumConfig,
  1077  			Watcher: func(_ context.Context, cfg interface{}) error {
  1078  				ethCfg, err := types.EthereumConfigFromUntypedProto(cfg)
  1079  				if err != nil {
  1080  					return fmt.Errorf("invalid primary ethereum configuration: %w", err)
  1081  				}
  1082  
  1083  				svcs.banking.OnPrimaryEthChainIDUpdated(ethCfg.ChainID(), ethCfg.CollateralBridge().HexAddress())
  1084  				return nil
  1085  			},
  1086  		},
  1087  		{
  1088  			Param: netparams.BlockchainsEVMBridgeConfigs,
  1089  			Watcher: func(_ context.Context, cfgs interface{}) error {
  1090  				ethCfgs, err := types.EVMChainConfigFromUntypedProto(cfgs)
  1091  				if err != nil {
  1092  					return fmt.Errorf("invalid secondary ethereum configuration: %w", err)
  1093  				}
  1094  
  1095  				ethCfg := ethCfgs.Configs[0]
  1096  				svcs.banking.OnSecondaryEthChainIDUpdated(ethCfg.ChainID(), ethCfg.CollateralBridge().HexAddress())
  1097  				svcs.witness.SetSecondaryDefaultConfirmations(ethCfg.ChainID(), ethCfg.Confirmations(), ethCfg.BlockTime())
  1098  				return nil
  1099  			},
  1100  		},
  1101  		{
  1102  			Param: netparams.BlockchainsEthereumL2Configs,
  1103  			Watcher: func(ctx context.Context, cfg interface{}) error {
  1104  				ethCfg, err := types.EthereumL2ConfigsFromUntypedProto(cfg)
  1105  				if err != nil {
  1106  					return fmt.Errorf("invalid ethereum l2 configuration: %w", err)
  1107  				}
  1108  
  1109  				if svcs.conf.HaveEthClient() {
  1110  					svcs.l2Clients.UpdateConfirmations(ethCfg)
  1111  				}
  1112  
  1113  				// non-validators still need to create these engine's for consensus reasons
  1114  				svcs.l2CallEngines.OnEthereumL2ConfigsUpdated(ctx, ethCfg)
  1115  				svcs.l2Verifiers.OnEthereumL2ConfigsUpdated(ctx, ethCfg)
  1116  
  1117  				return nil
  1118  			},
  1119  		},
  1120  		{
  1121  			Param:   netparams.LimitsProposeMarketEnabledFrom,
  1122  			Watcher: svcs.limits.OnLimitsProposeMarketEnabledFromUpdate,
  1123  		},
  1124  		{
  1125  			Param:   netparams.SpotMarketTradingEnabled,
  1126  			Watcher: svcs.limits.OnLimitsProposeSpotMarketEnabledFromUpdate,
  1127  		},
  1128  		{
  1129  			Param:   netparams.PerpsMarketTradingEnabled,
  1130  			Watcher: svcs.limits.OnLimitsProposePerpsMarketEnabledFromUpdate,
  1131  		},
  1132  		{
  1133  			Param:   netparams.AMMMarketTradingEnabled,
  1134  			Watcher: svcs.limits.OnLimitsProposeAMMEnabledUpdate,
  1135  		},
  1136  		{
  1137  			Param:   netparams.LimitsProposeAssetEnabledFrom,
  1138  			Watcher: svcs.limits.OnLimitsProposeAssetEnabledFromUpdate,
  1139  		},
  1140  		{
  1141  			Param:   netparams.MarkPriceUpdateMaximumFrequency,
  1142  			Watcher: svcs.executionEngine.OnMarkPriceUpdateMaximumFrequency,
  1143  		},
  1144  		{
  1145  			Param:   netparams.InternalCompositePriceUpdateFrequency,
  1146  			Watcher: svcs.executionEngine.OnInternalCompositePriceUpdateFrequency,
  1147  		},
  1148  		{
  1149  			Param:   netparams.MarketSuccessorLaunchWindow,
  1150  			Watcher: svcs.executionEngine.OnSuccessorMarketTimeWindowUpdate,
  1151  		},
  1152  		{
  1153  			Param:   netparams.SpamProtectionMaxStopOrdersPerMarket,
  1154  			Watcher: svcs.executionEngine.OnMarketPartiesMaximumStopOrdersUpdate,
  1155  		},
  1156  		{
  1157  			Param:   netparams.RewardsVestingMinimumTransfer,
  1158  			Watcher: svcs.vesting.OnRewardVestingMinimumTransferUpdate,
  1159  		},
  1160  		{
  1161  			Param:   netparams.RewardsVestingBaseRate,
  1162  			Watcher: svcs.vesting.OnRewardVestingBaseRateUpdate,
  1163  		},
  1164  		{
  1165  			Param:   netparams.RewardsVestingBenefitTiers,
  1166  			Watcher: svcs.vesting.OnBenefitTiersUpdate,
  1167  		},
  1168  		{
  1169  			Param:   netparams.ReferralProgramMaxPartyNotionalVolumeByQuantumPerEpoch,
  1170  			Watcher: svcs.referralProgram.OnReferralProgramMaxPartyNotionalVolumeByQuantumPerEpochUpdate,
  1171  		},
  1172  		{
  1173  			Param:   netparams.ReferralProgramMaxReferralRewardProportion,
  1174  			Watcher: svcs.referralProgram.OnReferralProgramMaxReferralRewardProportionUpdate,
  1175  		},
  1176  		{
  1177  			Param:   netparams.ReferralProgramMinStakedVegaTokens,
  1178  			Watcher: svcs.referralProgram.OnReferralProgramMinStakedVegaTokensUpdate,
  1179  		},
  1180  		{
  1181  			Param:   netparams.ReferralProgramMinStakedVegaTokens,
  1182  			Watcher: svcs.teamsEngine.OnReferralProgramMinStakedVegaTokensUpdate,
  1183  		},
  1184  		{
  1185  			Param:   netparams.SpamProtectionApplyReferralMinFunds,
  1186  			Watcher: svcs.referralProgram.OnMinBalanceForApplyReferralCodeUpdated,
  1187  		},
  1188  		{
  1189  			Param:   netparams.SpamProtectionReferralSetMinFunds,
  1190  			Watcher: svcs.referralProgram.OnMinBalanceForReferralProgramUpdated,
  1191  		},
  1192  		{
  1193  			Param:   netparams.SpamProtectionUpdateProfileMinFunds,
  1194  			Watcher: svcs.partiesEngine.OnMinBalanceForUpdatePartyProfileUpdated,
  1195  		},
  1196  		{
  1197  			Param:   netparams.RewardsActivityStreakBenefitTiers,
  1198  			Watcher: svcs.activityStreak.OnBenefitTiersUpdate,
  1199  		},
  1200  		{
  1201  			Param:   netparams.RewardsActivityStreakMinQuantumOpenVolume,
  1202  			Watcher: svcs.activityStreak.OnMinQuantumOpenNationalVolumeUpdate,
  1203  		},
  1204  		{
  1205  			Param:   netparams.RewardsActivityStreakMinQuantumTradeVolume,
  1206  			Watcher: svcs.activityStreak.OnMinQuantumTradeVolumeUpdate,
  1207  		},
  1208  		{
  1209  			Param:   netparams.RewardsActivityStreakInactivityLimit,
  1210  			Watcher: svcs.activityStreak.OnRewardsActivityStreakInactivityLimit,
  1211  		},
  1212  		{
  1213  			Param:   netparams.MarketAMMMinCommitmentQuantum,
  1214  			Watcher: svcs.executionEngine.OnMarketAMMMinCommitmentQuantum,
  1215  		},
  1216  		{
  1217  			Param:   netparams.MarketAMMMaxCalculationLevels,
  1218  			Watcher: svcs.executionEngine.OnMarketAMMMaxCalculationLevels,
  1219  		},
  1220  		{
  1221  			Param:   netparams.MarketLiquidityEquityLikeShareFeeFraction,
  1222  			Watcher: svcs.executionEngine.OnMarketLiquidityEquityLikeShareFeeFractionUpdate,
  1223  		},
  1224  	}
  1225  
  1226  	watchers = append(watchers, powWatchers...)
  1227  	watchers = append(watchers, spamWatchers...)
  1228  
  1229  	// now add some watcher for our netparams
  1230  	return svcs.netParams.Watch(watchers...)
  1231  }