@@ -94,6 +94,13 @@ type ManagerCfg struct {
9494
9595 // ErrChan is the channel that is used to send errors to the caller.
9696 ErrChan chan <- error
97+
98+ // DisableChainWatch, when true, prevents the supply verifier from
99+ // starting state machines to watch on-chain outputs for spends. This
100+ // option is intended for universe servers, where supply verification
101+ // should only occur for commitments submitted by peers, not via
102+ // on-chain spend detection.
103+ DisableChainWatch bool
97104}
98105
99106// Validate validates the ManagerCfg.
@@ -227,9 +234,19 @@ func (m *Manager) Start() error {
227234 m .startOnce .Do (func () {
228235 log .Infof ("Starting supply verifier manager" )
229236
230- // Initialize the state machine cache.
237+ // Initialize the state machine cache unconditionally to prevent
238+ // potential nil pointer dereferences, even if it ends up
239+ // unused.
231240 m .smCache = newStateMachineCache ()
232241
242+ // If chain watching is disabled, return early. We won't start
243+ // any state machines in this mode.
244+ if m .cfg .DisableChainWatch {
245+ log .Infof ("Supply verifier chain watch disabled, " +
246+ "skip state machine initialization" )
247+ return
248+ }
249+
233250 // Initialize state machines for each asset group that supports
234251 // supply commitments.
235252 err := m .InitStateMachines ()
@@ -400,10 +417,18 @@ func (m *Manager) Stop() error {
400417}
401418
402419// startAssetSM creates and starts a new supply commitment state machine for the
403- // given asset specifier.
420+ // given asset specifier. If DisableChainWatch is true, an error is returned.
404421func (m * Manager ) startAssetSM (ctx context.Context ,
405422 assetSpec asset.Specifier ) (* StateMachine , error ) {
406423
424+ // If chain watching is disabled, return an error.
425+ if m .cfg .DisableChainWatch {
426+ log .Debugf ("Supply verifier chain watch disabled, not " +
427+ "starting state machine (asset=%s)" , assetSpec .String ())
428+ return nil , fmt .Errorf ("supply verifier chain watch is " +
429+ "disabled" )
430+ }
431+
407432 log .Infof ("Starting supply verifier state machine (asset=%s)" ,
408433 assetSpec .String ())
409434
@@ -455,10 +480,18 @@ func (m *Manager) startAssetSM(ctx context.Context,
455480
456481// fetchStateMachine retrieves a state machine from the cache or creates a
457482// new one if it doesn't exist. If a new state machine is created, it is also
458- // started.
483+ // started. If DisableChainWatch is true, an error is returned.
459484func (m * Manager ) fetchStateMachine (assetSpec asset.Specifier ) (* StateMachine ,
460485 error ) {
461486
487+ // If chain watching is disabled, return an error.
488+ if m .cfg .DisableChainWatch {
489+ log .Debugf ("Supply verifier chain watch disabled, not " +
490+ "fetching state machine (asset=%s)" , assetSpec .String ())
491+ return nil , fmt .Errorf ("supply verifier chain watch is " +
492+ "disabled" )
493+ }
494+
462495 groupKey , err := assetSpec .UnwrapGroupKeyOrErr ()
463496 if err != nil {
464497 return nil , fmt .Errorf ("asset specifier missing group key: %w" ,
@@ -894,6 +927,10 @@ func newStateMachineCache() *stateMachineCache {
894927
895928// StopAll stops all state machines in the cache.
896929func (c * stateMachineCache ) StopAll () {
930+ if c == nil {
931+ return
932+ }
933+
897934 c .mu .RLock ()
898935 defer c .mu .RUnlock ()
899936
0 commit comments