Skip to content

Commit cbf1dff

Browse files
authored
Merge pull request #1796 from lightninglabs/wip/supplyverify/disable-output-watch
tapd: add universe.disable-supply-verifier-chain-watch config flag
2 parents cee9add + d5611dd commit cbf1dff

File tree

7 files changed

+84
-9
lines changed

7 files changed

+84
-9
lines changed

docs/release-notes/release-notes-0.7.0.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
- https://github.com/lightninglabs/taproot-assets/pull/1674
7575
- https://github.com/lightninglabs/taproot-assets/pull/1784
7676
- https://github.com/lightninglabs/taproot-assets/pull/1777
77+
- https://github.com/lightninglabs/taproot-assets/pull/1796
7778

7879
- A new [address version 2 was introduced that supports grouped assets and
7980
custom (sender-defined)

itest/tapd_harness.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,13 @@ type harnessOpts struct {
138138
// sendPriceHint indicates whether the tapd should send price hints from
139139
// the local oracle to the counterparty when requesting a quote.
140140
sendPriceHint bool
141+
142+
// disableSupplyVerifierChainWatch when true prevents the supply
143+
// verifier from starting state machines to watch on-chain outputs for
144+
// spends. This option is intended for universe servers, where supply
145+
// verification should only occur for commitments submitted by peers,
146+
// not via on-chain spend detection.
147+
disableSupplyVerifierChainWatch bool
141148
}
142149

143150
type harnessOption func(*harnessOpts)
@@ -154,6 +161,16 @@ func withOracleAddress(addr string) harnessOption {
154161
}
155162
}
156163

164+
// withDisableSupplyVerifierChainWatch is a functional option that disables
165+
// the supply verifier chain watch functionality. This is intended for universe
166+
// servers where supply verification should only occur for commitments submitted
167+
// by peers, not via on-chain spend detection.
168+
func withDisableSupplyVerifierChainWatch() harnessOption {
169+
return func(ho *harnessOpts) {
170+
ho.disableSupplyVerifierChainWatch = true
171+
}
172+
}
173+
157174
// newTapdHarness creates a new tapd server harness with the given
158175
// configuration.
159176
func newTapdHarness(t *testing.T, ht *harnessTest, cfg tapdConfig,
@@ -234,6 +251,11 @@ func newTapdHarness(t *testing.T, ht *harnessTest, cfg tapdConfig,
234251
// was not set, this will be false, which is the default.
235252
tapCfg.AddrBook.DisableSyncer = opts.addrAssetSyncerDisable
236253

254+
// Pass through the supply verifier chain watch disable flag. If the option
255+
// was not set, this will be false, which is the default.
256+
// nolint: lll
257+
tapCfg.Universe.DisableSupplyVerifierChainWatch = opts.disableSupplyVerifierChainWatch
258+
237259
switch {
238260
case len(opts.oracleServerAddress) > 0:
239261
tapCfg.Experimental.Rfq.PriceOracleAddress =

itest/universe_server_harness.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@ type universeServerHarness struct {
2323
func newUniverseServerHarness(t *testing.T, ht *harnessTest,
2424
lndHarness *node.HarnessNode) *universeServerHarness {
2525

26-
service, err := newTapdHarness(t, ht, tapdConfig{
27-
NetParams: harnessNetParams,
28-
LndNode: lndHarness,
29-
})
26+
service, err := newTapdHarness(
27+
t, ht, tapdConfig{
28+
NetParams: harnessNetParams,
29+
LndNode: lndHarness,
30+
}, withDisableSupplyVerifierChainWatch(),
31+
)
3032
require.NoError(t, err)
3133

3234
return &universeServerHarness{

sample-tapd.conf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,13 @@
379379
; LRU cache.
380380
; universe.supply-ignore-cache-size=10000
381381

382+
; Disable chain outpoint watching in supply verifier. If true, the supply
383+
; verifier will not start state machines to watch on-chain outputs for spends.
384+
; This option is intended for universe servers, where supply verification should
385+
; only occur for commitments submitted by peers, not via on-chain spend
386+
; detection.
387+
; universe.disable-supply-verifier-chain-watch=false
388+
382389
[multiverse-caches]
383390

384391
; The number of proofs that are cached per universe. (default: 5)

tapcfg/config.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,8 @@ type UniverseConfig struct {
304304
MultiverseCaches *tapdb.MultiverseCacheConfig `group:"multiverse-caches" namespace:"multiverse-caches"`
305305

306306
SupplyIgnoreCacheSize uint64 `long:"supply-ignore-cache-size" description:"The maximum number of entries in the supply ignore checker's negative lookup LRU cache."`
307+
308+
DisableSupplyVerifierChainWatch bool `long:"disable-supply-verifier-chain-watch" description:"Disable chain outpoint watching in supply verifier. If true, the supply verifier will not start state machines to watch on-chain outputs for spends. This option is intended for universe servers, where supply verification should only occur for commitments submitted by peers, not via on-chain spend detection."`
307309
}
308310

309311
// AddrBookConfig is the config that houses any address Book related config
@@ -467,8 +469,9 @@ func DefaultConfig() Config {
467469
MultiverseCaches: fn.Ptr(
468470
tapdb.DefaultMultiverseCacheConfig(),
469471
),
470-
MboxAuthTimeout: defaultMailboxAuthTimeout,
471-
SupplyIgnoreCacheSize: tapdb.DefaultNegativeLookupCacheSize,
472+
MboxAuthTimeout: defaultMailboxAuthTimeout,
473+
SupplyIgnoreCacheSize: tapdb.DefaultNegativeLookupCacheSize,
474+
DisableSupplyVerifierChainWatch: false,
472475
},
473476
AddrBook: &AddrBookConfig{
474477
DisableSyncer: false,

tapcfg/server.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,8 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger,
549549

550550
// Set up the supply verifier, which validates supply commitment leaves
551551
// published by asset issuers.
552+
//
553+
// nolint: lll
552554
supplyVerifyManager, err := supplyverifier.NewManager(
553555
supplyverifier.ManagerCfg{
554556
Chain: chainBridge,
@@ -560,6 +562,7 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger,
560562
GroupFetcher: assetMintingStore,
561563
IssuanceSubscriptions: universeSyncer,
562564
DaemonAdapters: lndFsmDaemonAdapters,
565+
DisableChainWatch: cfg.Universe.DisableSupplyVerifierChainWatch,
563566
},
564567
)
565568
if err != nil {

universe/supplyverifier/manager.go

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
404421
func (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.
459484
func (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.
896929
func (c *stateMachineCache) StopAll() {
930+
if c == nil {
931+
return
932+
}
933+
897934
c.mu.RLock()
898935
defer c.mu.RUnlock()
899936

0 commit comments

Comments
 (0)