Skip to content

Commit fd73afd

Browse files
committed
assets: add manager
1 parent d548c20 commit fd73afd

File tree

2 files changed

+226
-0
lines changed

2 files changed

+226
-0
lines changed

assets/manager.go

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
package assets
2+
3+
import (
4+
"context"
5+
"sync"
6+
"time"
7+
8+
"github.com/lightninglabs/lndclient"
9+
"github.com/lightninglabs/loop/fsm"
10+
loop_rpc "github.com/lightninglabs/loop/swapserverrpc"
11+
"github.com/lightninglabs/loop/utils"
12+
"github.com/lightninglabs/taproot-assets/taprpc"
13+
"github.com/lightningnetwork/lnd/lntypes"
14+
)
15+
16+
const (
17+
ClientKeyFamily = 696969
18+
)
19+
20+
type Config struct {
21+
AssetClient *TapdClient
22+
Wallet lndclient.WalletKitClient
23+
// ExchangeRateProvider is the exchange rate provider.
24+
ExchangeRateProvider *FixedExchangeRateProvider
25+
Signer lndclient.SignerClient
26+
ChainNotifier lndclient.ChainNotifierClient
27+
Router lndclient.RouterClient
28+
LndClient lndclient.LightningClient
29+
Store *PostgresStore
30+
ServerClient loop_rpc.AssetsSwapServerClient
31+
}
32+
33+
type AssetsSwapManager struct {
34+
cfg *Config
35+
36+
expiryManager *utils.ExpiryManager
37+
txConfManager *utils.TxSubscribeConfirmationManager
38+
39+
blockHeight int32
40+
runCtx context.Context
41+
activeSwapOuts map[lntypes.Hash]*OutFSM
42+
43+
sync.Mutex
44+
}
45+
46+
func NewAssetSwapServer(config *Config) *AssetsSwapManager {
47+
return &AssetsSwapManager{
48+
cfg: config,
49+
50+
activeSwapOuts: make(map[lntypes.Hash]*OutFSM),
51+
}
52+
}
53+
54+
func (m *AssetsSwapManager) Run(ctx context.Context, blockHeight int32) error {
55+
m.runCtx = ctx
56+
m.blockHeight = blockHeight
57+
58+
// Get our tapd client info.
59+
tapdInfo, err := m.cfg.AssetClient.GetInfo(
60+
ctx, &taprpc.GetInfoRequest{},
61+
)
62+
if err != nil {
63+
return err
64+
}
65+
log.Infof("Tapd info: %v", tapdInfo)
66+
67+
// Create our subscriptionManagers.
68+
m.expiryManager = utils.NewExpiryManager(m.cfg.ChainNotifier)
69+
m.txConfManager = utils.NewTxSubscribeConfirmationManager(
70+
m.cfg.ChainNotifier,
71+
)
72+
73+
// Start the expiry manager.
74+
errChan := make(chan error, 1)
75+
wg := &sync.WaitGroup{}
76+
wg.Add(1)
77+
go func() {
78+
defer wg.Done()
79+
err := m.expiryManager.Start(ctx, blockHeight)
80+
if err != nil {
81+
log.Errorf("Expiry manager failed: %v", err)
82+
errChan <- err
83+
log.Errorf("Gude1")
84+
}
85+
}()
86+
87+
// Recover all the active asset swap outs from the database.
88+
err = m.recoverSwapOuts(ctx)
89+
if err != nil {
90+
return err
91+
}
92+
93+
for {
94+
select {
95+
case err := <-errChan:
96+
log.Errorf("Gude2")
97+
return err
98+
99+
case <-ctx.Done():
100+
log.Errorf("Gude3")
101+
// wg.Wait()
102+
log.Errorf("Gude4")
103+
return nil
104+
}
105+
}
106+
}
107+
108+
func (m *AssetsSwapManager) NewSwapOut(ctx context.Context,
109+
amt uint64, asset []byte) (*OutFSM, error) {
110+
111+
// Create a new out fsm.
112+
outFSM := NewOutFSM(m.runCtx, m.getFSMOutConfig())
113+
114+
// Send the initial event to the fsm.
115+
err := outFSM.SendEvent(
116+
ctx, OnRequestAssetOut, &InitSwapOutContext{
117+
Amount: amt,
118+
AssetId: asset,
119+
BlockHeightHint: uint32(m.blockHeight),
120+
},
121+
)
122+
if err != nil {
123+
return nil, err
124+
}
125+
// Check if the fsm has an error.
126+
if outFSM.LastActionError != nil {
127+
return nil, outFSM.LastActionError
128+
}
129+
130+
// Wait for the fsm to be in the state we expect.
131+
err = outFSM.DefaultObserver.WaitForState(
132+
ctx, time.Second*15, PayPrepay,
133+
fsm.WithAbortEarlyOnErrorOption(),
134+
)
135+
if err != nil {
136+
return nil, err
137+
}
138+
139+
// Add the swap to the active swap outs.
140+
m.Lock()
141+
m.activeSwapOuts[outFSM.SwapOut.SwapHash] = outFSM
142+
m.Unlock()
143+
144+
return outFSM, nil
145+
}
146+
147+
// recoverSwapOuts recovers all the active asset swap outs from the database.
148+
func (m *AssetsSwapManager) recoverSwapOuts(ctx context.Context) error {
149+
// Fetch all the active asset swap outs from the database.
150+
activeSwapOuts, err := m.cfg.Store.GetActiveAssetOuts(ctx)
151+
if err != nil {
152+
return err
153+
}
154+
155+
for _, swapOut := range activeSwapOuts {
156+
log.Debugf("Recovering asset out %v with state %v",
157+
swapOut.SwapHash, swapOut.State)
158+
159+
swapOutFSM := NewOutFSMFromSwap(
160+
ctx, m.getFSMOutConfig(), swapOut,
161+
)
162+
163+
m.Lock()
164+
m.activeSwapOuts[swapOut.SwapHash] = swapOutFSM
165+
m.Unlock()
166+
167+
// As SendEvent can block, we'll start a goroutine to process
168+
// the event.
169+
go func() {
170+
err := swapOutFSM.SendEvent(ctx, OnRecover, nil)
171+
if err != nil {
172+
log.Errorf("FSM %v Error sending recover "+
173+
"event %v, state: %v",
174+
swapOutFSM.SwapOut.SwapHash,
175+
err, swapOutFSM.SwapOut.State)
176+
}
177+
}()
178+
}
179+
180+
return nil
181+
}
182+
183+
// getFSMOutConfig returns a fsmconfig from the manager.
184+
func (m *AssetsSwapManager) getFSMOutConfig() *FSMConfig {
185+
return &FSMConfig{
186+
TapdClient: m.cfg.AssetClient,
187+
AssetClient: m.cfg.ServerClient,
188+
BlockHeightSubscriber: m.expiryManager,
189+
TxConfSubscriber: m.txConfManager,
190+
ExchangeRateProvider: m.cfg.ExchangeRateProvider,
191+
Wallet: m.cfg.Wallet,
192+
Router: m.cfg.Router,
193+
194+
Store: m.cfg.Store,
195+
Signer: m.cfg.Signer,
196+
}
197+
}
198+
199+
func (m *AssetsSwapManager) ListSwapOutoutputs(ctx context.Context) ([]*SwapOut,
200+
error) {
201+
202+
return m.cfg.Store.GetAllAssetOuts(ctx)
203+
}

assets/rateprovider.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package assets
2+
3+
import "github.com/btcsuite/btcd/btcutil"
4+
5+
const (
6+
fixedPrice = 100
7+
)
8+
9+
// FixedExchangeRateProvider is a fixed exchange rate provider.
10+
type FixedExchangeRateProvider struct {
11+
}
12+
13+
// NewFixedExchangeRateProvider creates a new fixed exchange rate provider.
14+
func NewFixedExchangeRateProvider() *FixedExchangeRateProvider {
15+
return &FixedExchangeRateProvider{}
16+
}
17+
18+
// GetSatsPerAssetUnit returns the fixed price in sats per asset unit.
19+
func (e *FixedExchangeRateProvider) GetSatsPerAssetUnit(assetId []byte) (
20+
btcutil.Amount, error) {
21+
22+
return btcutil.Amount(fixedPrice), nil
23+
}

0 commit comments

Comments
 (0)