Files
lspd/postgresql/lsps2_store.go
2023-11-06 14:12:38 +01:00

201 lines
4.7 KiB
Go

package postgresql
import (
"context"
"fmt"
"strings"
"github.com/breez/lspd/basetypes"
"github.com/breez/lspd/lsps2"
"github.com/breez/lspd/shared"
"github.com/btcsuite/btcd/wire"
"github.com/jackc/pgx/v4"
"github.com/jackc/pgx/v4/pgxpool"
)
type Lsps2Store struct {
pool *pgxpool.Pool
}
func NewLsps2Store(pool *pgxpool.Pool) *Lsps2Store {
return &Lsps2Store{pool: pool}
}
func (s *Lsps2Store) RegisterBuy(
ctx context.Context,
req *lsps2.RegisterBuy,
) error {
_, err := s.pool.Exec(
ctx,
`INSERT INTO lsps2.buy_registrations (
lsp_id
, peer_id
, scid
, mode
, payment_size_msat
, params_min_fee_msat
, params_proportional
, params_valid_until
, params_min_lifetime
, params_max_client_to_self_delay
, params_promise
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)`,
req.LspId,
req.PeerId,
int64(uint64(req.Scid)),
int(req.Mode),
req.PaymentSizeMsat,
int64(req.OpeningFeeParams.MinFeeMsat),
req.OpeningFeeParams.Proportional,
req.OpeningFeeParams.ValidUntil,
req.OpeningFeeParams.MinLifetime,
req.OpeningFeeParams.MaxClientToSelfDelay,
req.OpeningFeeParams.Promise,
)
if err != nil {
if strings.Contains(err.Error(), "idx_lsps2_buy_registrations_scid") {
return lsps2.ErrScidExists
}
return err
}
return nil
}
func (s *Lsps2Store) GetBuyRegistration(ctx context.Context, scid basetypes.ShortChannelID) (*lsps2.BuyRegistration, error) {
row := s.pool.QueryRow(
ctx,
`SELECT r.id
, r.lsp_id
, r.peer_id
, r.scid
, r.mode
, r.payment_size_msat
, r.params_min_fee_msat
, r.params_proportional
, r.params_valid_until
, r.params_min_lifetime
, r.params_max_client_to_self_delay
, r.params_promise
, c.funding_tx_id
, c.funding_tx_outnum
, c.is_completed
FROM lsps2.buy_registrations r
LEFT JOIN lsps2.bought_channels c ON r.id = c.registration_id
WHERE r.scid = $1`,
int64(uint64(scid)),
)
var db_id uint64
var db_lsp_id string
var db_peer_id string
var db_scid int64
var db_mode int
var db_payment_size_msat *int64
var db_params_min_fee_msat int64
var db_params_proportional uint32
var db_params_valid_until string
var db_params_min_lifetime uint32
var db_params_max_client_to_self_delay uint32
var db_params_promise string
var db_funding_tx_id []byte
var db_funding_tx_outnum uint32
var db_is_completed bool
err := row.Scan(
&db_id,
&db_lsp_id,
&db_peer_id,
&db_scid,
db_payment_size_msat,
&db_params_min_fee_msat,
&db_params_proportional,
&db_params_valid_until,
&db_params_min_lifetime,
&db_params_max_client_to_self_delay,
&db_params_promise,
&db_funding_tx_id,
&db_funding_tx_outnum,
&db_is_completed,
)
if err == pgx.ErrNoRows {
return nil, lsps2.ErrNotFound
}
if err != nil {
return nil, err
}
var paymentSizeMsat *uint64
if db_payment_size_msat != nil {
p := uint64(*db_payment_size_msat)
paymentSizeMsat = &p
}
var cp *wire.OutPoint
if db_funding_tx_id != nil {
cp, err = basetypes.NewOutPoint(db_funding_tx_id, db_funding_tx_outnum)
if err != nil {
return nil, fmt.Errorf("invalid funding tx id in db: %x", db_funding_tx_id)
}
}
return &lsps2.BuyRegistration{
Id: db_id,
LspId: db_lsp_id,
PeerId: db_peer_id,
Scid: basetypes.ShortChannelID(uint64(db_scid)),
OpeningFeeParams: shared.OpeningFeeParams{
MinFeeMsat: uint64(db_params_min_fee_msat),
Proportional: db_params_proportional,
ValidUntil: db_params_valid_until,
MinLifetime: db_params_min_lifetime,
MaxClientToSelfDelay: db_params_max_client_to_self_delay,
Promise: db_params_promise,
},
PaymentSizeMsat: paymentSizeMsat,
Mode: lsps2.OpeningMode(db_mode),
ChannelPoint: cp,
IsComplete: db_is_completed,
}, nil
}
func (s *Lsps2Store) SetChannelOpened(ctx context.Context, channelOpened *lsps2.ChannelOpened) error {
_, err := s.pool.Exec(
ctx,
`INSERT INTO lsps2.bought_channels (
registration_id,
funding_tx_id,
funding_tx_outnum,
fee_msat,
payment_size_msat,
is_completed
) VALUES ($1, $2, $3, $4, $5, false)`,
channelOpened.RegistrationId,
channelOpened.Outpoint.Hash[:],
channelOpened.Outpoint.Index,
int64(channelOpened.FeeMsat),
int64(channelOpened.PaymentSizeMsat),
)
return err
}
func (s *Lsps2Store) SetCompleted(ctx context.Context, registrationId uint64) error {
rows, err := s.pool.Exec(
ctx,
`UPDATE lsps2.bought_channels
SET is_completed = true
WHERE registration_id = $1`,
registrationId,
)
if err != nil {
return err
}
if rows.RowsAffected() == 0 {
return fmt.Errorf("no rows were updated")
}
return nil
}