-
Notifications
You must be signed in to change notification settings - Fork 120
staticaddr: persist withdrawal info #938
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
d5722e4
eaeb9e7
9d0c423
cc1d386
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
package withdraw | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"strings" | ||
|
||
"github.com/btcsuite/btcd/btcutil" | ||
"github.com/btcsuite/btcd/chaincfg/chainhash" | ||
"github.com/btcsuite/btcd/wire" | ||
"github.com/lightninglabs/loop/loopdb" | ||
"github.com/lightninglabs/loop/loopdb/sqlc" | ||
"github.com/lightninglabs/loop/staticaddr/deposit" | ||
"github.com/lightningnetwork/lnd/clock" | ||
) | ||
|
||
// SqlStore is the backing store for static address withdrawals. | ||
type SqlStore struct { | ||
baseDB *loopdb.BaseDB | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this exposes the full queries to this package, which IMO is not neccessary. as we usually define a Querier interface. |
||
|
||
clock clock.Clock | ||
} | ||
|
||
// NewSqlStore constructs a new SQLStore from a BaseDB. The BaseDB is agnostic | ||
// to the underlying driver which can be postgres or sqlite. | ||
func NewSqlStore(db *loopdb.BaseDB) *SqlStore { | ||
return &SqlStore{ | ||
baseDB: db, | ||
|
||
clock: clock.NewDefaultClock(), | ||
} | ||
} | ||
|
||
// CreateWithdrawal creates a static address withdrawal record in the database. | ||
func (s *SqlStore) CreateWithdrawal(ctx context.Context, tx *wire.MsgTx, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I propose adding a light unit test for future regressions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 |
||
confirmationHeight uint32, deposits []*deposit.Deposit, | ||
changePkScript []byte) error { | ||
|
||
strOutpoints := make([]string, len(deposits)) | ||
totalAmount := int64(0) | ||
for i, deposit := range deposits { | ||
strOutpoints[i] = deposit.OutPoint.String() | ||
totalAmount += int64(deposit.Value) | ||
} | ||
|
||
// Populate the optional change amount. | ||
withdrawnAmount, changeAmount := int64(0), int64(0) | ||
if len(tx.TxOut) == 1 { | ||
withdrawnAmount = tx.TxOut[0].Value | ||
} else if len(tx.TxOut) == 2 { | ||
withdrawnAmount, changeAmount = tx.TxOut[0].Value, tx.TxOut[1].Value | ||
if bytes.Equal(changePkScript, tx.TxOut[0].PkScript) { | ||
changeAmount = tx.TxOut[0].Value | ||
withdrawnAmount = tx.TxOut[1].Value | ||
} | ||
} | ||
|
||
createArgs := sqlc.CreateWithdrawalParams{ | ||
WithdrawalTxID: tx.TxHash().String(), | ||
DepositOutpoints: strings.Join(strOutpoints, ","), | ||
TotalDepositAmount: totalAmount, | ||
WithdrawnAmount: withdrawnAmount, | ||
ChangeAmount: changeAmount, | ||
ConfirmationHeight: int64(confirmationHeight), | ||
} | ||
|
||
return s.baseDB.ExecTx(ctx, &loopdb.SqliteTxOptions{}, | ||
func(q *sqlc.Queries) error { | ||
return q.CreateWithdrawal(ctx, createArgs) | ||
}) | ||
} | ||
|
||
// AllWithdrawals retrieves all known withdrawals. | ||
func (s *SqlStore) AllWithdrawals(ctx context.Context) ([]*Withdrawal, error) { | ||
var allWithdrawals []*Withdrawal | ||
|
||
err := s.baseDB.ExecTx(ctx, loopdb.NewSqlReadOpts(), | ||
func(q *sqlc.Queries) error { | ||
var err error | ||
|
||
withdrawals, err := q.AllWithdrawals(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
for _, withdrawal := range withdrawals { | ||
w, err := s.toWithdrawal(withdrawal) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
allWithdrawals = append(allWithdrawals, w) | ||
} | ||
|
||
return nil | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return allWithdrawals, nil | ||
} | ||
|
||
// toDeposit converts an sql deposit to a deposit. | ||
func (s *SqlStore) toWithdrawal(row sqlc.Withdrawal) (*Withdrawal, error) { | ||
txHash, err := chainhash.NewHashFromStr(row.WithdrawalTxID) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &Withdrawal{ | ||
TxID: *txHash, | ||
DepositOutpoints: strings.Split(row.DepositOutpoints, ","), | ||
TotalDepositAmount: btcutil.Amount(row.TotalDepositAmount), | ||
WithdrawnAmount: btcutil.Amount(row.WithdrawnAmount), | ||
ChangeAmount: btcutil.Amount(row.ChangeAmount), | ||
ConfirmationHeight: uint32(row.ConfirmationHeight), | ||
}, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package withdraw | ||
|
||
import ( | ||
"github.com/btcsuite/btcd/btcutil" | ||
"github.com/btcsuite/btcd/chaincfg/chainhash" | ||
) | ||
|
||
// Withdrawal represents a finalized static address withdrawal record in the | ||
// database. | ||
type Withdrawal struct { | ||
// TxID is the transaction ID of the withdrawal. | ||
TxID chainhash.Hash | ||
|
||
// DepositOutpoints is a list of outpoints that were used to fund the | ||
// withdrawal. | ||
DepositOutpoints []string | ||
|
||
// TotalDepositAmount is the total amount of all deposits used to fund | ||
// the withdrawal. | ||
TotalDepositAmount btcutil.Amount | ||
|
||
// WithdrawnAmount is the amount withdrawn. It represents the total | ||
// value of selected deposits minus fees and change. | ||
WithdrawnAmount btcutil.Amount | ||
|
||
// ChangeAmount is the optional change returned to the static address. | ||
ChangeAmount btcutil.Amount | ||
|
||
// ConfirmationHeight is the block height at which the withdrawal was | ||
// confirmed. | ||
ConfirmationHeight uint32 | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be nicer to add the withdrawal at the time it is requested then later on set it to confirmed.