Skip to content

Commit e1e1405

Browse files
committed
multi: rename mock oracle flags, add secondary option
To make the use of the mock oracle price flag way more clear, we first rename it to correctly represent its usage. We then also make sure a minimum value is set, otherwise one asset unit would just cost too much and cause issues when trying to send them over the network. To make it easier to express what one unit should cost, we also add a second price flag that can specify the number of satoshis per asset unit, which will make it easier for users that want to represent something that doesn't have an official exchange rate.
1 parent 04d914c commit e1e1405

File tree

5 files changed

+79
-15
lines changed

5 files changed

+79
-15
lines changed

itest/tapd_harness.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,9 @@ func newTapdHarness(t *testing.T, ht *harnessTest, cfg tapdConfig,
222222
// Set the experimental config for the RFQ service.
223223
tapCfg.Experimental = &tapcfg.ExperimentalConfig{
224224
Rfq: rfq.CliConfig{
225-
PriceOracleAddress: rfq.MockPriceOracleServiceAddress,
226-
MockOracleCentPerSat: 5_820_600,
225+
//nolint:lll
226+
PriceOracleAddress: rfq.MockPriceOracleServiceAddress,
227+
MockOracleAssetsPerBTC: 5_820_600,
227228
},
228229
}
229230

rfq/cli.go

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ import (
77
const (
88
MockPriceOracleServiceAddress = "use_mock_price_oracle_service_" +
99
"promise_to_not_use_on_mainnet"
10+
11+
// MinAssetsPerBTC is the minimum number of asset units that one BTC
12+
// should cost. If the value is lower, then one asset unit would cost
13+
// too much to be able to represent small amounts of satoshis. With this
14+
// value, one asset unit would still cost 1k sats.
15+
MinAssetsPerBTC = 100_000
1016
)
1117

1218
// CliConfig is a struct that holds tapd cli configuration options for the RFQ
@@ -18,18 +24,21 @@ type CliConfig struct {
1824

1925
SkipAcceptQuotePriceCheck bool `long:"skipacceptquotepricecheck" description:"Accept any price quote returned by RFQ peer, skipping price validation"`
2026

21-
MockOracleCentPerSat uint64 `long:"mockoraclecentpersat" description:"Mock price oracle static USD cent per sat rate"`
27+
MockOracleAssetsPerBTC uint64 `long:"mockoracleassetsperbtc" description:"Mock price oracle static asset units per BTC rate (for example number of USD cents per BTC if one asset unit represents a USD cent); whole numbers only, use either this or mockoraclesatsperasset depending on required precision"`
28+
29+
MockOracleSatsPerAsset uint64 `long:"mockoraclesatsperasset" description:"Mock price oracle static satoshis per asset unit rate (for example number of satoshis to pay for one USD cent if one asset unit represents a USD cent); whole numbers only, use either this or mockoracleassetsperbtc depending on required precision"`
2230
}
2331

2432
// Validate returns an error if the configuration is invalid.
2533
func (c *CliConfig) Validate() error {
2634
// If the user has specified a mock oracle USD per BTC rate but the
2735
// price oracle address is not the mock price oracle service address,
2836
// then we'll return an error.
29-
if c.MockOracleCentPerSat > 0 &&
37+
if (c.MockOracleAssetsPerBTC > 0 || c.MockOracleSatsPerAsset > 0) &&
3038
c.PriceOracleAddress != MockPriceOracleServiceAddress {
3139

32-
return fmt.Errorf("mockoraclecentpersat can only be used "+
40+
return fmt.Errorf("mockoracleassetsperbtc or "+
41+
"mockoraclesatsperasset can only be used "+
3342
"with the mock price oracle service, set "+
3443
"priceoracleaddress to %s",
3544
MockPriceOracleServiceAddress)
@@ -39,12 +48,35 @@ func (c *CliConfig) Validate() error {
3948
// has not set the mock oracle USD per BTC rate, then we'll return an
4049
// error.
4150
if c.PriceOracleAddress == MockPriceOracleServiceAddress &&
42-
c.MockOracleCentPerSat == 0 {
51+
c.MockOracleAssetsPerBTC == 0 && c.MockOracleSatsPerAsset == 0 {
4352

44-
return fmt.Errorf("mockoraclecentpersat must be set when " +
53+
return fmt.Errorf("mockoracleassetsperbtc or " +
54+
"mockoraclesatsperasset must be set when " +
4555
"using the mock price oracle service")
4656
}
4757

58+
// Only one of the mock oracle rates can be set.
59+
if c.MockOracleAssetsPerBTC > 0 && c.MockOracleSatsPerAsset > 0 {
60+
return fmt.Errorf("only one of mockoracleassetsperbtc or " +
61+
"mockoraclesatsperasset can be set")
62+
}
63+
64+
// The MockOracleAssetsPerBTC is more precise for tracking the actual
65+
// BTC price but less optimal for just specifying a dummy or test rate
66+
// for an asset that isn't BTC. The smaller the value, the more one
67+
// asset costs. If we allowed a value of 1, then one asset unit would
68+
// cost 1 BTC, which cannot really easily be transported over the
69+
// network. So we require a value of at least 100k, which would still
70+
// mean that one asset unit costs 1k sats.
71+
if c.MockOracleAssetsPerBTC > 0 &&
72+
c.MockOracleAssetsPerBTC < MinAssetsPerBTC {
73+
74+
return fmt.Errorf("mockoracleassetsperbtc must be at least "+
75+
"%d asset units per BTC, otherwise one asset "+
76+
"unit would cost more than 1k sats per unit",
77+
MinAssetsPerBTC)
78+
}
79+
4880
// Ensure that if the price oracle address not the mock price oracle
4981
// service address then it must be a valid gRPC address.
5082
if c.PriceOracleAddress != "" &&

rfq/oracle.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,17 @@ func NewMockPriceOracle(expiryDelay, assetsPerBTC uint64) *MockPriceOracle {
383383
}
384384
}
385385

386+
// NewMockPriceOracleSatPerAsset creates a new mock price oracle with a
387+
// specified satoshis per asset rate.
388+
func NewMockPriceOracleSatPerAsset(expiryDelay uint64,
389+
satPerAsset btcutil.Amount) *MockPriceOracle {
390+
391+
return &MockPriceOracle{
392+
expiryDelay: expiryDelay,
393+
mSatPerAsset: lnwire.NewMSatFromSatoshis(satPerAsset),
394+
}
395+
}
396+
386397
// QueryAskPrice returns the ask price for the given asset amount.
387398
func (m *MockPriceOracle) QueryAskPrice(_ context.Context,
388399
_ *asset.ID, _ *btcec.PublicKey, _ uint64,

sample-tapd.conf

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,5 +320,13 @@
320320
; Accept any price quote returned by RFQ peer, skipping price validation
321321
; experimental.rfq.skipacceptquotepricecheck=false
322322

323-
; Mock price oracle static USD cent per sat rate
324-
; experimental.rfq.mockoraclecentpersat=
323+
; Mock price oracle static asset units per BTC rate (for example number of USD
324+
; cents per BTC if one asset unit represents a USD cent); whole numbers only,
325+
; use either this or mockoraclesatsperasset depending on required precision
326+
; experimental.rfq.mockoracleassetsperbtc=
327+
328+
; Mock price oracle static satoshis per asset unit rate (for example number of
329+
; satoshis to pay for one USD cent if one asset unit represents a USD cent);
330+
; whole numbers only, use either this or mockoracleassetsperbtc depending on
331+
; required precision
332+
; experimental.rfq.mockoraclesatsperasset=

tapcfg/server.go

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"encoding/binary"
88
"fmt"
99

10+
"github.com/btcsuite/btcd/btcutil"
1011
"github.com/btcsuite/btclog"
1112
"github.com/lightninglabs/lndclient"
1213
tap "github.com/lightninglabs/taproot-assets"
@@ -330,11 +331,22 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger,
330331
// real price oracle service.
331332
var priceOracle rfq.PriceOracle
332333

333-
switch cfg.Experimental.Rfq.PriceOracleAddress {
334+
rfqCfg := cfg.Experimental.Rfq
335+
switch rfqCfg.PriceOracleAddress {
334336
case rfq.MockPriceOracleServiceAddress:
335-
priceOracle = rfq.NewMockPriceOracle(
336-
3600, cfg.Experimental.Rfq.MockOracleCentPerSat,
337-
)
337+
switch {
338+
case rfqCfg.MockOracleAssetsPerBTC > 0:
339+
priceOracle = rfq.NewMockPriceOracle(
340+
3600, rfqCfg.MockOracleAssetsPerBTC,
341+
)
342+
343+
case rfqCfg.MockOracleSatsPerAsset > 0:
344+
priceOracle = rfq.NewMockPriceOracleSatPerAsset(
345+
3600, btcutil.Amount(
346+
rfqCfg.MockOracleSatsPerAsset,
347+
),
348+
)
349+
}
338350

339351
case "":
340352
// Leave the price oracle as nil, which will cause the RFQ
@@ -343,7 +355,7 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger,
343355

344356
default:
345357
priceOracle, err = rfq.NewRpcPriceOracle(
346-
cfg.Experimental.Rfq.PriceOracleAddress, false,
358+
rfqCfg.PriceOracleAddress, false,
347359
)
348360
if err != nil {
349361
return nil, fmt.Errorf("unable to create price "+
@@ -360,7 +372,7 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger,
360372
ChannelLister: walletAnchor,
361373
AliasManager: lndRouterClient,
362374
// nolint: lll
363-
SkipAcceptQuotePriceCheck: cfg.Experimental.Rfq.SkipAcceptQuotePriceCheck,
375+
SkipAcceptQuotePriceCheck: rfqCfg.SkipAcceptQuotePriceCheck,
364376
ErrChan: mainErrChan,
365377
},
366378
)

0 commit comments

Comments
 (0)