Skip to content

Commit 2f0cb8c

Browse files
committed
Add LBC asset
1 parent 10a94c0 commit 2f0cb8c

2 files changed

Lines changed: 216 additions & 0 deletions

File tree

server/asset/lbc/lbc.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// This code is available on the terms of the project LICENSE.md file,
2+
// also available online at https://blueoakcouncil.org/license/1.0.0.
3+
4+
package lbc
5+
6+
import (
7+
"fmt"
8+
9+
"decred.org/dcrdex/dex"
10+
dexbtc "decred.org/dcrdex/dex/networks/btc"
11+
dexlbc "decred.org/dcrdex/dex/networks/lbc"
12+
"decred.org/dcrdex/server/asset"
13+
"decred.org/dcrdex/server/asset/btc"
14+
"github.com/btcsuite/btcd/chaincfg"
15+
)
16+
17+
// Driver implements asset.Driver.
18+
type Driver struct{}
19+
20+
// Setup creates the LBC backend. Start the backend with its Run method.
21+
func (d *Driver) Setup(cfg *asset.BackendConfig) (asset.Backend, error) {
22+
return NewBackend(cfg)
23+
}
24+
25+
// DecodeCoinID creates a human-readable representation of a coin ID for LBRY Credits.
26+
func (d *Driver) DecodeCoinID(coinID []byte) (string, error) {
27+
// LBRY Credits and Bitcoin have the same tx hash and output format.
28+
return (&btc.Driver{}).DecodeCoinID(coinID)
29+
}
30+
31+
// UnitInfo returns the dex.UnitInfo for the asset.
32+
func (d *Driver) UnitInfo() dex.UnitInfo {
33+
return dexlbc.UnitInfo
34+
}
35+
36+
// Version returns the Backend implementation's version number.
37+
func (d *Driver) Version() uint32 {
38+
return version
39+
}
40+
41+
// MinBondSize calculates the minimum bond size for a given fee rate that avoids
42+
// dust outputs on the bond and refund txs, assuming the maxFeeRate doesn't
43+
// change.
44+
func (d *Driver) MinBondSize(maxFeeRate uint64) uint64 {
45+
return dexbtc.MinBondSize(maxFeeRate, true)
46+
}
47+
48+
// MinLotSize calculates the minimum bond size for a given fee rate that avoids
49+
// dust outputs on the swap and refund txs, assuming the maxFeeRate doesn't
50+
// change.
51+
func (d *Driver) MinLotSize(maxFeeRate uint64) uint64 {
52+
return dexbtc.MinLotSize(maxFeeRate, true)
53+
}
54+
55+
// Name is the asset's name.
56+
func (d *Driver) Name() string {
57+
return "LBRY Credits"
58+
}
59+
60+
func init() {
61+
asset.Register(BipID, &Driver{})
62+
}
63+
64+
const (
65+
version = 1
66+
BipID = 140
67+
assetName = "lbc"
68+
)
69+
70+
// NewBackend generates the network parameters and creates a lbc backend as a
71+
// btc clone using an asset/btc helper function.
72+
func NewBackend(cfg *asset.BackendConfig) (asset.Backend, error) {
73+
var params *chaincfg.Params
74+
switch cfg.Net {
75+
case dex.Mainnet:
76+
params = dexlbc.MainNetParams
77+
case dex.Testnet:
78+
params = dexlbc.TestNet4Params
79+
case dex.Regtest:
80+
params = dexlbc.RegressionNetParams
81+
default:
82+
return nil, fmt.Errorf("unknown network ID %v", cfg.Net)
83+
}
84+
85+
// Designate the clone ports. These will be overwritten by any explicit
86+
// settings in the configuration file.
87+
ports := dexbtc.NetPorts{
88+
Mainnet: "9245",
89+
Testnet: "19245",
90+
Simnet: "39245",
91+
}
92+
93+
configPath := cfg.ConfigPath
94+
if configPath == "" {
95+
configPath = dexbtc.SystemConfigPath("lbry-credits")
96+
}
97+
98+
return btc.NewBTCClone(&btc.BackendCloneConfig{
99+
Name: assetName,
100+
Segwit: true,
101+
ConfigPath: configPath,
102+
Logger: cfg.Logger,
103+
Net: cfg.Net,
104+
ChainParams: params,
105+
Ports: ports,
106+
BlockDeserializer: dexlbc.DeserializeBlockBytes,
107+
NoCompetitionFeeRate: 10,
108+
// It looks like if you set it to 1, lbcd just returns data for 2
109+
// anyway.
110+
FeeConfs: 2,
111+
MaxFeeBlocks: 20,
112+
RelayAddr: cfg.RelayAddr,
113+
})
114+
}

server/asset/lbc/live_test.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
//go:build lbclive
2+
3+
// go test -v -tags lbclive -run UTXOStats
4+
// -----------------------------------
5+
// Grab the most recent block and iterate it's outputs, taking account of
6+
// how many UTXOs are found, how many are of an unknown type, etc.
7+
//
8+
// go test -v -tags lbclive -run P2SHStats
9+
// -----------------------------------------
10+
// For each output in the last block, check it's previous outpoint to see if
11+
// it's a P2SH or P2WSH. If so, takes statistics on the script types, including
12+
// for the redeem script.
13+
//
14+
// go test -v -tags lbclive -run LiveFees
15+
// ------------------------------------------
16+
// Test that fees rates are parsed without error and that a few historical fee
17+
// rates are correct
18+
//
19+
// go test -v -tags lbclive -run TestMedianFeeRates
20+
// ------------------------------------------
21+
// Test that a median fee rate can be calculated.
22+
23+
package lbc
24+
25+
import (
26+
"context"
27+
"fmt"
28+
"os"
29+
"sync"
30+
"testing"
31+
32+
"decred.org/dcrdex/dex"
33+
"decred.org/dcrdex/server/asset"
34+
"decred.org/dcrdex/server/asset/btc"
35+
)
36+
37+
var (
38+
lbc *btc.Backend
39+
ctx context.Context
40+
)
41+
42+
func TestMain(m *testing.M) {
43+
// Wrap everything for defers.
44+
doIt := func() int {
45+
var cancel context.CancelFunc
46+
ctx, cancel = context.WithCancel(context.Background())
47+
wg := new(sync.WaitGroup)
48+
defer func() {
49+
cancel()
50+
wg.Wait()
51+
}()
52+
53+
logger := dex.StdOutLogger("LBCTEST", dex.LevelTrace)
54+
dexAsset, err := NewBackend(&asset.BackendConfig{
55+
AssetID: BipID,
56+
Logger: logger,
57+
Net: dex.Mainnet,
58+
})
59+
if err != nil {
60+
fmt.Printf("NewBackend error: %v\n", err)
61+
return 1
62+
}
63+
64+
var ok bool
65+
lbc, ok = dexAsset.(*btc.Backend)
66+
if !ok {
67+
fmt.Printf("Could not cast asset.Backend to *Backend")
68+
return 1
69+
}
70+
71+
wg, err = dexAsset.Connect(ctx)
72+
if err != nil {
73+
fmt.Printf("Connect failed: %v", err)
74+
return 1
75+
}
76+
77+
return m.Run()
78+
}
79+
80+
os.Exit(doIt())
81+
}
82+
83+
func TestUTXOStats(t *testing.T) {
84+
btc.LiveUTXOStats(lbc, t)
85+
}
86+
87+
func TestP2SHStats(t *testing.T) {
88+
btc.LiveP2SHStats(lbc, t, 1000)
89+
}
90+
91+
func TestLiveFees(t *testing.T) {
92+
btc.LiveFeeRates(lbc, t, map[string]uint64{
93+
"d9ec52f3d2c8497638b7de47f77b1e00e91ca98f88bf844b1ae3a2a8ca44bf0b": 1000,
94+
"da68b225de1650d69fb57216d8403f91ea0a4b04f7be89150061748863480980": 703,
95+
"6e7bfce6aee69312629b1f60afe6dcef02f367207642f2dc380a554c21181eb2": 888,
96+
"9387d8b2097ee23cc3da36daf90262dda9a98eb25063ddddb630cf15513fa9b8": 1,
97+
})
98+
}
99+
100+
func TestMedianFeeRates(t *testing.T) {
101+
btc.TestMedianFees(lbc, t)
102+
}

0 commit comments

Comments
 (0)