mirror of
https://github.com/lightninglabs/loop.git
synced 2026-08-13 12:33:03 +02:00
loopdb: persist deposit address ownership
Associate every deposit with the static address parameters that created it. This lets restored deposits recover the correct script and signing keys instead of assuming the legacy root address.
This commit is contained in:
parent
1baf02e210
commit
29f5ce73ce
15 changed files with 498 additions and 43 deletions
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE deposits DROP COLUMN static_address_id;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
ALTER TABLE deposits ADD static_address_id INT REFERENCES static_addresses(id);
|
||||
|
||||
UPDATE deposits
|
||||
SET static_address_id = (
|
||||
SELECT id FROM static_addresses ORDER BY id ASC LIMIT 1
|
||||
)
|
||||
WHERE static_address_id IS NULL
|
||||
AND EXISTS (SELECT 1 FROM static_addresses);
|
||||
|
|
@ -20,6 +20,7 @@ type Deposit struct {
|
|||
ExpirySweepTxid []byte
|
||||
FinalizedWithdrawalTx sql.NullString
|
||||
SwapHash []byte
|
||||
StaticAddressID sql.NullInt32
|
||||
}
|
||||
|
||||
type DepositUpdate struct {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
)
|
||||
|
||||
type Querier interface {
|
||||
AllDeposits(ctx context.Context) ([]Deposit, error)
|
||||
AllDeposits(ctx context.Context) ([]AllDepositsRow, error)
|
||||
AllStaticAddresses(ctx context.Context) ([]StaticAddress, error)
|
||||
CancelBatch(ctx context.Context, id int32) error
|
||||
CreateDeposit(ctx context.Context, arg CreateDepositParams) error
|
||||
|
|
@ -18,19 +18,20 @@ type Querier interface {
|
|||
CreateStaticAddress(ctx context.Context, arg CreateStaticAddressParams) error
|
||||
CreateWithdrawal(ctx context.Context, arg CreateWithdrawalParams) error
|
||||
CreateWithdrawalDeposit(ctx context.Context, arg CreateWithdrawalDepositParams) error
|
||||
DepositForOutpoint(ctx context.Context, arg DepositForOutpointParams) (Deposit, error)
|
||||
DepositForOutpoint(ctx context.Context, arg DepositForOutpointParams) (DepositForOutpointRow, error)
|
||||
DepositIDsForSwapHash(ctx context.Context, swapHash []byte) ([][]byte, error)
|
||||
DepositsForSwapHash(ctx context.Context, swapHash []byte) ([]DepositsForSwapHashRow, error)
|
||||
FetchLiquidityParams(ctx context.Context) ([]byte, error)
|
||||
GetAllWithdrawals(ctx context.Context) ([]Withdrawal, error)
|
||||
GetBatchSweeps(ctx context.Context, batchID int32) ([]Sweep, error)
|
||||
GetBatchSweptAmount(ctx context.Context, batchID int32) (int64, error)
|
||||
GetDeposit(ctx context.Context, depositID []byte) (Deposit, error)
|
||||
GetDeposit(ctx context.Context, depositID []byte) (GetDepositRow, error)
|
||||
GetInstantOutSwap(ctx context.Context, swapHash []byte) (GetInstantOutSwapRow, error)
|
||||
GetInstantOutSwapUpdates(ctx context.Context, swapHash []byte) ([]InstantoutUpdate, error)
|
||||
GetInstantOutSwaps(ctx context.Context) ([]GetInstantOutSwapsRow, error)
|
||||
GetLastUpdateID(ctx context.Context, swapHash []byte) (int32, error)
|
||||
GetLatestDepositUpdate(ctx context.Context, depositID []byte) (DepositUpdate, error)
|
||||
GetLegacyAddress(ctx context.Context) (StaticAddress, error)
|
||||
GetLoopInSwap(ctx context.Context, swapHash []byte) (GetLoopInSwapRow, error)
|
||||
GetLoopInSwapUpdates(ctx context.Context, swapHash []byte) ([]StaticAddressSwapUpdate, error)
|
||||
GetLoopInSwaps(ctx context.Context) ([]GetLoopInSwapsRow, error)
|
||||
|
|
@ -42,6 +43,7 @@ type Querier interface {
|
|||
GetReservationUpdates(ctx context.Context, reservationID []byte) ([]ReservationUpdate, error)
|
||||
GetReservations(ctx context.Context) ([]Reservation, error)
|
||||
GetStaticAddress(ctx context.Context, pkscript []byte) (StaticAddress, error)
|
||||
GetStaticAddressID(ctx context.Context, pkscript []byte) (int32, error)
|
||||
GetStaticAddressLoopInSwap(ctx context.Context, swapHash []byte) (GetStaticAddressLoopInSwapRow, error)
|
||||
GetStaticAddressLoopInSwapsByStates(ctx context.Context, dollar_1 sql.NullString) ([]GetStaticAddressLoopInSwapsByStatesRow, error)
|
||||
GetSwapUpdates(ctx context.Context, swapHash []byte) ([]SwapUpdate, error)
|
||||
|
|
@ -68,6 +70,7 @@ type Querier interface {
|
|||
OverrideSelectedSwapAmount(ctx context.Context, arg OverrideSelectedSwapAmountParams) error
|
||||
OverrideSwapCosts(ctx context.Context, arg OverrideSwapCostsParams) error
|
||||
RecordStaticAddressRiskDecision(ctx context.Context, arg RecordStaticAddressRiskDecisionParams) error
|
||||
SetAllNullDepositsStaticAddressID(ctx context.Context, staticAddressID sql.NullInt32) error
|
||||
SwapHashForDepositID(ctx context.Context, depositID []byte) ([]byte, error)
|
||||
UpdateBatch(ctx context.Context, arg UpdateBatchParams) error
|
||||
UpdateDeposit(ctx context.Context, arg UpdateDepositParams) error
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ INSERT INTO deposits (
|
|||
confirmation_height,
|
||||
timeout_sweep_pk_script,
|
||||
expiry_sweep_txid,
|
||||
finalized_withdrawal_tx
|
||||
finalized_withdrawal_tx,
|
||||
static_address_id
|
||||
) VALUES (
|
||||
$1,
|
||||
$2,
|
||||
|
|
@ -16,7 +17,8 @@ INSERT INTO deposits (
|
|||
$5,
|
||||
$6,
|
||||
$7,
|
||||
$8
|
||||
$8,
|
||||
$9
|
||||
);
|
||||
|
||||
-- name: UpdateDeposit :exec
|
||||
|
|
@ -43,17 +45,35 @@ INSERT INTO deposit_updates (
|
|||
|
||||
-- name: GetDeposit :one
|
||||
SELECT
|
||||
*
|
||||
d.*,
|
||||
sa.client_pubkey client_pubkey,
|
||||
sa.server_pubkey server_pubkey,
|
||||
sa.expiry expiry,
|
||||
sa.client_key_family client_key_family,
|
||||
sa.client_key_index client_key_index,
|
||||
sa.pkscript pkscript,
|
||||
sa.protocol_version protocol_version,
|
||||
sa.initiation_height initiation_height
|
||||
FROM
|
||||
deposits
|
||||
deposits d
|
||||
LEFT JOIN static_addresses sa ON sa.id = d.static_address_id
|
||||
WHERE
|
||||
deposit_id = $1;
|
||||
|
||||
-- name: DepositForOutpoint :one
|
||||
SELECT
|
||||
*
|
||||
d.*,
|
||||
sa.client_pubkey client_pubkey,
|
||||
sa.server_pubkey server_pubkey,
|
||||
sa.expiry expiry,
|
||||
sa.client_key_family client_key_family,
|
||||
sa.client_key_index client_key_index,
|
||||
sa.pkscript pkscript,
|
||||
sa.protocol_version protocol_version,
|
||||
sa.initiation_height initiation_height
|
||||
FROM
|
||||
deposits
|
||||
deposits d
|
||||
LEFT JOIN static_addresses sa ON sa.id = d.static_address_id
|
||||
WHERE
|
||||
tx_hash = $1
|
||||
AND
|
||||
|
|
@ -61,11 +81,20 @@ AND
|
|||
|
||||
-- name: AllDeposits :many
|
||||
SELECT
|
||||
*
|
||||
d.*,
|
||||
sa.client_pubkey client_pubkey,
|
||||
sa.server_pubkey server_pubkey,
|
||||
sa.expiry expiry,
|
||||
sa.client_key_family client_key_family,
|
||||
sa.client_key_index client_key_index,
|
||||
sa.pkscript pkscript,
|
||||
sa.protocol_version protocol_version,
|
||||
sa.initiation_height initiation_height
|
||||
FROM
|
||||
deposits
|
||||
deposits d
|
||||
LEFT JOIN static_addresses sa ON sa.id = d.static_address_id
|
||||
ORDER BY
|
||||
id ASC;
|
||||
d.id ASC;
|
||||
|
||||
-- name: GetLatestDepositUpdate :one
|
||||
SELECT
|
||||
|
|
@ -76,4 +105,9 @@ WHERE
|
|||
deposit_id = $1
|
||||
ORDER BY
|
||||
update_timestamp DESC
|
||||
LIMIT 1;
|
||||
LIMIT 1;
|
||||
|
||||
-- name: SetAllNullDepositsStaticAddressID :exec
|
||||
UPDATE deposits
|
||||
SET static_address_id = $1
|
||||
WHERE static_address_id IS NULL;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
-- name: AllStaticAddresses :many
|
||||
SELECT * FROM static_addresses;
|
||||
SELECT * FROM static_addresses
|
||||
ORDER BY id ASC;
|
||||
|
||||
-- name: GetStaticAddress :one
|
||||
SELECT * FROM static_addresses
|
||||
WHERE pkscript=$1;
|
||||
|
||||
-- name: GetStaticAddressID :one
|
||||
SELECT id FROM static_addresses
|
||||
WHERE pkscript=$1;
|
||||
|
||||
-- name: CreateStaticAddress :exec
|
||||
INSERT INTO static_addresses (
|
||||
client_pubkey,
|
||||
|
|
@ -24,4 +29,9 @@ INSERT INTO static_addresses (
|
|||
$6,
|
||||
$7,
|
||||
$8
|
||||
);
|
||||
);
|
||||
|
||||
-- name: GetLegacyAddress :one
|
||||
SELECT * FROM static_addresses
|
||||
ORDER BY id ASC
|
||||
LIMIT 1;
|
||||
|
|
|
|||
|
|
@ -13,22 +13,53 @@ import (
|
|||
|
||||
const allDeposits = `-- name: AllDeposits :many
|
||||
SELECT
|
||||
id, deposit_id, tx_hash, out_index, amount, confirmation_height, timeout_sweep_pk_script, expiry_sweep_txid, finalized_withdrawal_tx, swap_hash
|
||||
d.id, d.deposit_id, d.tx_hash, d.out_index, d.amount, d.confirmation_height, d.timeout_sweep_pk_script, d.expiry_sweep_txid, d.finalized_withdrawal_tx, d.swap_hash, d.static_address_id,
|
||||
sa.client_pubkey client_pubkey,
|
||||
sa.server_pubkey server_pubkey,
|
||||
sa.expiry expiry,
|
||||
sa.client_key_family client_key_family,
|
||||
sa.client_key_index client_key_index,
|
||||
sa.pkscript pkscript,
|
||||
sa.protocol_version protocol_version,
|
||||
sa.initiation_height initiation_height
|
||||
FROM
|
||||
deposits
|
||||
deposits d
|
||||
LEFT JOIN static_addresses sa ON sa.id = d.static_address_id
|
||||
ORDER BY
|
||||
id ASC
|
||||
d.id ASC
|
||||
`
|
||||
|
||||
func (q *Queries) AllDeposits(ctx context.Context) ([]Deposit, error) {
|
||||
type AllDepositsRow struct {
|
||||
ID int32
|
||||
DepositID []byte
|
||||
TxHash []byte
|
||||
OutIndex int32
|
||||
Amount int64
|
||||
ConfirmationHeight int64
|
||||
TimeoutSweepPkScript []byte
|
||||
ExpirySweepTxid []byte
|
||||
FinalizedWithdrawalTx sql.NullString
|
||||
SwapHash []byte
|
||||
StaticAddressID sql.NullInt32
|
||||
ClientPubkey []byte
|
||||
ServerPubkey []byte
|
||||
Expiry sql.NullInt32
|
||||
ClientKeyFamily sql.NullInt32
|
||||
ClientKeyIndex sql.NullInt32
|
||||
Pkscript []byte
|
||||
ProtocolVersion sql.NullInt32
|
||||
InitiationHeight sql.NullInt32
|
||||
}
|
||||
|
||||
func (q *Queries) AllDeposits(ctx context.Context) ([]AllDepositsRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, allDeposits)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Deposit
|
||||
var items []AllDepositsRow
|
||||
for rows.Next() {
|
||||
var i Deposit
|
||||
var i AllDepositsRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.DepositID,
|
||||
|
|
@ -40,6 +71,15 @@ func (q *Queries) AllDeposits(ctx context.Context) ([]Deposit, error) {
|
|||
&i.ExpirySweepTxid,
|
||||
&i.FinalizedWithdrawalTx,
|
||||
&i.SwapHash,
|
||||
&i.StaticAddressID,
|
||||
&i.ClientPubkey,
|
||||
&i.ServerPubkey,
|
||||
&i.Expiry,
|
||||
&i.ClientKeyFamily,
|
||||
&i.ClientKeyIndex,
|
||||
&i.Pkscript,
|
||||
&i.ProtocolVersion,
|
||||
&i.InitiationHeight,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -63,7 +103,8 @@ INSERT INTO deposits (
|
|||
confirmation_height,
|
||||
timeout_sweep_pk_script,
|
||||
expiry_sweep_txid,
|
||||
finalized_withdrawal_tx
|
||||
finalized_withdrawal_tx,
|
||||
static_address_id
|
||||
) VALUES (
|
||||
$1,
|
||||
$2,
|
||||
|
|
@ -72,7 +113,8 @@ INSERT INTO deposits (
|
|||
$5,
|
||||
$6,
|
||||
$7,
|
||||
$8
|
||||
$8,
|
||||
$9
|
||||
)
|
||||
`
|
||||
|
||||
|
|
@ -85,6 +127,7 @@ type CreateDepositParams struct {
|
|||
TimeoutSweepPkScript []byte
|
||||
ExpirySweepTxid []byte
|
||||
FinalizedWithdrawalTx sql.NullString
|
||||
StaticAddressID sql.NullInt32
|
||||
}
|
||||
|
||||
func (q *Queries) CreateDeposit(ctx context.Context, arg CreateDepositParams) error {
|
||||
|
|
@ -97,15 +140,25 @@ func (q *Queries) CreateDeposit(ctx context.Context, arg CreateDepositParams) er
|
|||
arg.TimeoutSweepPkScript,
|
||||
arg.ExpirySweepTxid,
|
||||
arg.FinalizedWithdrawalTx,
|
||||
arg.StaticAddressID,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const depositForOutpoint = `-- name: DepositForOutpoint :one
|
||||
SELECT
|
||||
id, deposit_id, tx_hash, out_index, amount, confirmation_height, timeout_sweep_pk_script, expiry_sweep_txid, finalized_withdrawal_tx, swap_hash
|
||||
d.id, d.deposit_id, d.tx_hash, d.out_index, d.amount, d.confirmation_height, d.timeout_sweep_pk_script, d.expiry_sweep_txid, d.finalized_withdrawal_tx, d.swap_hash, d.static_address_id,
|
||||
sa.client_pubkey client_pubkey,
|
||||
sa.server_pubkey server_pubkey,
|
||||
sa.expiry expiry,
|
||||
sa.client_key_family client_key_family,
|
||||
sa.client_key_index client_key_index,
|
||||
sa.pkscript pkscript,
|
||||
sa.protocol_version protocol_version,
|
||||
sa.initiation_height initiation_height
|
||||
FROM
|
||||
deposits
|
||||
deposits d
|
||||
LEFT JOIN static_addresses sa ON sa.id = d.static_address_id
|
||||
WHERE
|
||||
tx_hash = $1
|
||||
AND
|
||||
|
|
@ -117,9 +170,31 @@ type DepositForOutpointParams struct {
|
|||
OutIndex int32
|
||||
}
|
||||
|
||||
func (q *Queries) DepositForOutpoint(ctx context.Context, arg DepositForOutpointParams) (Deposit, error) {
|
||||
type DepositForOutpointRow struct {
|
||||
ID int32
|
||||
DepositID []byte
|
||||
TxHash []byte
|
||||
OutIndex int32
|
||||
Amount int64
|
||||
ConfirmationHeight int64
|
||||
TimeoutSweepPkScript []byte
|
||||
ExpirySweepTxid []byte
|
||||
FinalizedWithdrawalTx sql.NullString
|
||||
SwapHash []byte
|
||||
StaticAddressID sql.NullInt32
|
||||
ClientPubkey []byte
|
||||
ServerPubkey []byte
|
||||
Expiry sql.NullInt32
|
||||
ClientKeyFamily sql.NullInt32
|
||||
ClientKeyIndex sql.NullInt32
|
||||
Pkscript []byte
|
||||
ProtocolVersion sql.NullInt32
|
||||
InitiationHeight sql.NullInt32
|
||||
}
|
||||
|
||||
func (q *Queries) DepositForOutpoint(ctx context.Context, arg DepositForOutpointParams) (DepositForOutpointRow, error) {
|
||||
row := q.db.QueryRowContext(ctx, depositForOutpoint, arg.TxHash, arg.OutIndex)
|
||||
var i Deposit
|
||||
var i DepositForOutpointRow
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.DepositID,
|
||||
|
|
@ -131,22 +206,62 @@ func (q *Queries) DepositForOutpoint(ctx context.Context, arg DepositForOutpoint
|
|||
&i.ExpirySweepTxid,
|
||||
&i.FinalizedWithdrawalTx,
|
||||
&i.SwapHash,
|
||||
&i.StaticAddressID,
|
||||
&i.ClientPubkey,
|
||||
&i.ServerPubkey,
|
||||
&i.Expiry,
|
||||
&i.ClientKeyFamily,
|
||||
&i.ClientKeyIndex,
|
||||
&i.Pkscript,
|
||||
&i.ProtocolVersion,
|
||||
&i.InitiationHeight,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getDeposit = `-- name: GetDeposit :one
|
||||
SELECT
|
||||
id, deposit_id, tx_hash, out_index, amount, confirmation_height, timeout_sweep_pk_script, expiry_sweep_txid, finalized_withdrawal_tx, swap_hash
|
||||
d.id, d.deposit_id, d.tx_hash, d.out_index, d.amount, d.confirmation_height, d.timeout_sweep_pk_script, d.expiry_sweep_txid, d.finalized_withdrawal_tx, d.swap_hash, d.static_address_id,
|
||||
sa.client_pubkey client_pubkey,
|
||||
sa.server_pubkey server_pubkey,
|
||||
sa.expiry expiry,
|
||||
sa.client_key_family client_key_family,
|
||||
sa.client_key_index client_key_index,
|
||||
sa.pkscript pkscript,
|
||||
sa.protocol_version protocol_version,
|
||||
sa.initiation_height initiation_height
|
||||
FROM
|
||||
deposits
|
||||
deposits d
|
||||
LEFT JOIN static_addresses sa ON sa.id = d.static_address_id
|
||||
WHERE
|
||||
deposit_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetDeposit(ctx context.Context, depositID []byte) (Deposit, error) {
|
||||
type GetDepositRow struct {
|
||||
ID int32
|
||||
DepositID []byte
|
||||
TxHash []byte
|
||||
OutIndex int32
|
||||
Amount int64
|
||||
ConfirmationHeight int64
|
||||
TimeoutSweepPkScript []byte
|
||||
ExpirySweepTxid []byte
|
||||
FinalizedWithdrawalTx sql.NullString
|
||||
SwapHash []byte
|
||||
StaticAddressID sql.NullInt32
|
||||
ClientPubkey []byte
|
||||
ServerPubkey []byte
|
||||
Expiry sql.NullInt32
|
||||
ClientKeyFamily sql.NullInt32
|
||||
ClientKeyIndex sql.NullInt32
|
||||
Pkscript []byte
|
||||
ProtocolVersion sql.NullInt32
|
||||
InitiationHeight sql.NullInt32
|
||||
}
|
||||
|
||||
func (q *Queries) GetDeposit(ctx context.Context, depositID []byte) (GetDepositRow, error) {
|
||||
row := q.db.QueryRowContext(ctx, getDeposit, depositID)
|
||||
var i Deposit
|
||||
var i GetDepositRow
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.DepositID,
|
||||
|
|
@ -158,6 +273,15 @@ func (q *Queries) GetDeposit(ctx context.Context, depositID []byte) (Deposit, er
|
|||
&i.ExpirySweepTxid,
|
||||
&i.FinalizedWithdrawalTx,
|
||||
&i.SwapHash,
|
||||
&i.StaticAddressID,
|
||||
&i.ClientPubkey,
|
||||
&i.ServerPubkey,
|
||||
&i.Expiry,
|
||||
&i.ClientKeyFamily,
|
||||
&i.ClientKeyIndex,
|
||||
&i.Pkscript,
|
||||
&i.ProtocolVersion,
|
||||
&i.InitiationHeight,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
|
@ -209,6 +333,17 @@ func (q *Queries) InsertDepositUpdate(ctx context.Context, arg InsertDepositUpda
|
|||
return err
|
||||
}
|
||||
|
||||
const setAllNullDepositsStaticAddressID = `-- name: SetAllNullDepositsStaticAddressID :exec
|
||||
UPDATE deposits
|
||||
SET static_address_id = $1
|
||||
WHERE static_address_id IS NULL
|
||||
`
|
||||
|
||||
func (q *Queries) SetAllNullDepositsStaticAddressID(ctx context.Context, staticAddressID sql.NullInt32) error {
|
||||
_, err := q.db.ExecContext(ctx, setAllNullDepositsStaticAddressID, staticAddressID)
|
||||
return err
|
||||
}
|
||||
|
||||
const updateDeposit = `-- name: UpdateDeposit :exec
|
||||
UPDATE deposits
|
||||
SET
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ func (q *Queries) DepositIDsForSwapHash(ctx context.Context, swapHash []byte) ([
|
|||
|
||||
const depositsForSwapHash = `-- name: DepositsForSwapHash :many
|
||||
SELECT
|
||||
d.id, d.deposit_id, d.tx_hash, d.out_index, d.amount, d.confirmation_height, d.timeout_sweep_pk_script, d.expiry_sweep_txid, d.finalized_withdrawal_tx, d.swap_hash,
|
||||
d.id, d.deposit_id, d.tx_hash, d.out_index, d.amount, d.confirmation_height, d.timeout_sweep_pk_script, d.expiry_sweep_txid, d.finalized_withdrawal_tx, d.swap_hash, d.static_address_id,
|
||||
u.update_state,
|
||||
u.update_timestamp
|
||||
FROM
|
||||
|
|
@ -73,6 +73,7 @@ type DepositsForSwapHashRow struct {
|
|||
ExpirySweepTxid []byte
|
||||
FinalizedWithdrawalTx sql.NullString
|
||||
SwapHash []byte
|
||||
StaticAddressID sql.NullInt32
|
||||
UpdateState sql.NullString
|
||||
UpdateTimestamp sql.NullTime
|
||||
}
|
||||
|
|
@ -97,6 +98,7 @@ func (q *Queries) DepositsForSwapHash(ctx context.Context, swapHash []byte) ([]D
|
|||
&i.ExpirySweepTxid,
|
||||
&i.FinalizedWithdrawalTx,
|
||||
&i.SwapHash,
|
||||
&i.StaticAddressID,
|
||||
&i.UpdateState,
|
||||
&i.UpdateTimestamp,
|
||||
); err != nil {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
|
||||
const allStaticAddresses = `-- name: AllStaticAddresses :many
|
||||
SELECT id, client_pubkey, server_pubkey, expiry, client_key_family, client_key_index, pkscript, protocol_version, initiation_height FROM static_addresses
|
||||
ORDER BY id ASC
|
||||
`
|
||||
|
||||
func (q *Queries) AllStaticAddresses(ctx context.Context) ([]StaticAddress, error) {
|
||||
|
|
@ -93,6 +94,29 @@ func (q *Queries) CreateStaticAddress(ctx context.Context, arg CreateStaticAddre
|
|||
return err
|
||||
}
|
||||
|
||||
const getLegacyAddress = `-- name: GetLegacyAddress :one
|
||||
SELECT id, client_pubkey, server_pubkey, expiry, client_key_family, client_key_index, pkscript, protocol_version, initiation_height FROM static_addresses
|
||||
ORDER BY id ASC
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
func (q *Queries) GetLegacyAddress(ctx context.Context) (StaticAddress, error) {
|
||||
row := q.db.QueryRowContext(ctx, getLegacyAddress)
|
||||
var i StaticAddress
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.ClientPubkey,
|
||||
&i.ServerPubkey,
|
||||
&i.Expiry,
|
||||
&i.ClientKeyFamily,
|
||||
&i.ClientKeyIndex,
|
||||
&i.Pkscript,
|
||||
&i.ProtocolVersion,
|
||||
&i.InitiationHeight,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getStaticAddress = `-- name: GetStaticAddress :one
|
||||
SELECT id, client_pubkey, server_pubkey, expiry, client_key_family, client_key_index, pkscript, protocol_version, initiation_height FROM static_addresses
|
||||
WHERE pkscript=$1
|
||||
|
|
@ -114,3 +138,15 @@ func (q *Queries) GetStaticAddress(ctx context.Context, pkscript []byte) (Static
|
|||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getStaticAddressID = `-- name: GetStaticAddressID :one
|
||||
SELECT id FROM static_addresses
|
||||
WHERE pkscript=$1
|
||||
`
|
||||
|
||||
func (q *Queries) GetStaticAddressID(ctx context.Context, pkscript []byte) (int32, error) {
|
||||
row := q.db.QueryRowContext(ctx, getStaticAddressID, pkscript)
|
||||
var id int32
|
||||
err := row.Scan(&id)
|
||||
return id, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,14 @@ func (s *SqlStore) CreateStaticAddress(ctx context.Context,
|
|||
return s.baseDB.Queries.CreateStaticAddress(ctx, createArgs)
|
||||
}
|
||||
|
||||
// GetAllStaticAddresses returns all address known to the server.
|
||||
// GetStaticAddressID retrieves the database ID for a static address script.
|
||||
func (s *SqlStore) GetStaticAddressID(ctx context.Context,
|
||||
pkScript []byte) (int32, error) {
|
||||
|
||||
return s.baseDB.Queries.GetStaticAddressID(ctx, pkScript)
|
||||
}
|
||||
|
||||
// GetAllStaticAddresses returns all addresses known to the client.
|
||||
func (s *SqlStore) GetAllStaticAddresses(ctx context.Context) (
|
||||
[]*script.Parameters, error) {
|
||||
|
||||
|
|
@ -64,6 +71,18 @@ func (s *SqlStore) GetAllStaticAddresses(ctx context.Context) (
|
|||
return result, nil
|
||||
}
|
||||
|
||||
// GetLegacyParameters returns the first static address created for this L402.
|
||||
func (s *SqlStore) GetLegacyParameters(ctx context.Context) (
|
||||
*script.Parameters, error) {
|
||||
|
||||
staticAddress, err := s.baseDB.Queries.GetLegacyAddress(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.toAddressParameters(staticAddress)
|
||||
}
|
||||
|
||||
// toAddressParameters transforms a database representation of a static address
|
||||
// to an AddressParameters struct.
|
||||
func (s *SqlStore) toAddressParameters(row sqlc.StaticAddress) (
|
||||
|
|
@ -80,6 +99,7 @@ func (s *SqlStore) toAddressParameters(row sqlc.StaticAddress) (
|
|||
}
|
||||
|
||||
return &script.Parameters{
|
||||
ID: row.ID,
|
||||
ClientPubkey: clientPubkey,
|
||||
ServerPubkey: serverPubkey,
|
||||
PkScript: row.Pkscript,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import (
|
|||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightninglabs/loop/fsm"
|
||||
"github.com/lightninglabs/loop/staticaddr/script"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
)
|
||||
|
||||
|
|
@ -70,6 +72,11 @@ type Deposit struct {
|
|||
// FinalizedWithdrawalTx is the coop-signed withdrawal transaction. It
|
||||
// is republished on new block arrivals and on client restarts.
|
||||
FinalizedWithdrawalTx *wire.MsgTx
|
||||
|
||||
// AddressParams are the static address parameters that produced this
|
||||
// deposit's pkScript. Spending code must use these per-deposit
|
||||
// parameters rather than assuming all deposits belong to one address.
|
||||
AddressParams *script.Parameters
|
||||
}
|
||||
|
||||
// IsInFinalState returns true if the deposit is final.
|
||||
|
|
@ -152,6 +159,19 @@ func (d *Deposit) GetConfirmationHeightNoLock() int64 {
|
|||
return d.ConfirmationHeight
|
||||
}
|
||||
|
||||
// GetStaticAddressScript reconstructs the static address script for this
|
||||
// deposit's matched address parameters.
|
||||
func (d *Deposit) GetStaticAddressScript() (*script.StaticAddress, error) {
|
||||
if d.AddressParams == nil {
|
||||
return nil, fmt.Errorf("missing static address parameters")
|
||||
}
|
||||
|
||||
return script.NewStaticAddress(
|
||||
input.MuSig2Version100RC2, int64(d.AddressParams.Expiry),
|
||||
d.AddressParams.ClientPubkey, d.AddressParams.ServerPubkey,
|
||||
)
|
||||
}
|
||||
|
||||
// GetRandomDepositID generates a random deposit ID.
|
||||
func GetRandomDepositID() (ID, error) {
|
||||
var id ID
|
||||
|
|
|
|||
|
|
@ -6,14 +6,19 @@ import (
|
|||
"database/sql"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightninglabs/loop/fsm"
|
||||
"github.com/lightninglabs/loop/loopdb"
|
||||
"github.com/lightninglabs/loop/loopdb/sqlc"
|
||||
"github.com/lightninglabs/loop/staticaddr/script"
|
||||
"github.com/lightninglabs/loop/staticaddr/version"
|
||||
"github.com/lightningnetwork/lnd/clock"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
)
|
||||
|
||||
|
|
@ -49,6 +54,17 @@ func (s *SqlStore) CreateDeposit(ctx context.Context, deposit *Deposit) error {
|
|||
Amount: int64(deposit.Value),
|
||||
ConfirmationHeight: deposit.GetConfirmationHeight(),
|
||||
TimeoutSweepPkScript: deposit.TimeOutSweepPkScript,
|
||||
StaticAddressID: sql.NullInt32{},
|
||||
}
|
||||
if deposit.AddressParams != nil {
|
||||
if deposit.AddressParams.ID <= 0 {
|
||||
return fmt.Errorf("static address ID must be set")
|
||||
}
|
||||
|
||||
createArgs.StaticAddressID = sql.NullInt32{
|
||||
Int32: deposit.AddressParams.ID,
|
||||
Valid: true,
|
||||
}
|
||||
}
|
||||
|
||||
updateArgs := sqlc.InsertDepositUpdateParams{
|
||||
|
|
@ -147,7 +163,9 @@ func (s *SqlStore) GetDeposit(ctx context.Context, id ID) (*Deposit, error) {
|
|||
return err
|
||||
}
|
||||
|
||||
deposit, err = ToDeposit(row, latestUpdate)
|
||||
deposit, err = toDeposit(
|
||||
depositRowFromGet(row), latestUpdate,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -193,7 +211,9 @@ func (s *SqlStore) DepositForOutpoint(ctx context.Context,
|
|||
return err
|
||||
}
|
||||
|
||||
deposit, err = ToDeposit(row, latestUpdate)
|
||||
deposit, err = toDeposit(
|
||||
depositRowFromOutpoint(row), latestUpdate,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -245,8 +265,105 @@ func (s *SqlStore) AllDeposits(ctx context.Context) ([]*Deposit, error) {
|
|||
return allDeposits, nil
|
||||
}
|
||||
|
||||
// ToDeposit converts an sql deposit to a deposit.
|
||||
func ToDeposit(row sqlc.Deposit, lastUpdate sqlc.DepositUpdate) (*Deposit,
|
||||
// ToDeposit converts an sql deposit row with joined static address metadata to
|
||||
// a deposit.
|
||||
func ToDeposit(row sqlc.AllDepositsRow, lastUpdate sqlc.DepositUpdate) (*Deposit,
|
||||
error) {
|
||||
|
||||
return toDeposit(depositRowFromAll(row), lastUpdate)
|
||||
}
|
||||
|
||||
type depositRow struct {
|
||||
DepositID []byte
|
||||
TxHash []byte
|
||||
OutIndex int32
|
||||
Amount int64
|
||||
ConfirmationHeight int64
|
||||
TimeoutSweepPkScript []byte
|
||||
ExpirySweepTxid []byte
|
||||
FinalizedWithdrawalTx sql.NullString
|
||||
SwapHash []byte
|
||||
StaticAddressID sql.NullInt32
|
||||
ClientPubkey []byte
|
||||
ServerPubkey []byte
|
||||
Expiry sql.NullInt32
|
||||
ClientKeyFamily sql.NullInt32
|
||||
ClientKeyIndex sql.NullInt32
|
||||
Pkscript []byte
|
||||
ProtocolVersion sql.NullInt32
|
||||
InitiationHeight sql.NullInt32
|
||||
}
|
||||
|
||||
func depositRowFromAll(row sqlc.AllDepositsRow) depositRow {
|
||||
return depositRow{
|
||||
DepositID: row.DepositID,
|
||||
TxHash: row.TxHash,
|
||||
OutIndex: row.OutIndex,
|
||||
Amount: row.Amount,
|
||||
ConfirmationHeight: row.ConfirmationHeight,
|
||||
TimeoutSweepPkScript: row.TimeoutSweepPkScript,
|
||||
ExpirySweepTxid: row.ExpirySweepTxid,
|
||||
FinalizedWithdrawalTx: row.FinalizedWithdrawalTx,
|
||||
SwapHash: row.SwapHash,
|
||||
StaticAddressID: row.StaticAddressID,
|
||||
ClientPubkey: row.ClientPubkey,
|
||||
ServerPubkey: row.ServerPubkey,
|
||||
Expiry: row.Expiry,
|
||||
ClientKeyFamily: row.ClientKeyFamily,
|
||||
ClientKeyIndex: row.ClientKeyIndex,
|
||||
Pkscript: row.Pkscript,
|
||||
ProtocolVersion: row.ProtocolVersion,
|
||||
InitiationHeight: row.InitiationHeight,
|
||||
}
|
||||
}
|
||||
|
||||
func depositRowFromGet(row sqlc.GetDepositRow) depositRow {
|
||||
return depositRow{
|
||||
DepositID: row.DepositID,
|
||||
TxHash: row.TxHash,
|
||||
OutIndex: row.OutIndex,
|
||||
Amount: row.Amount,
|
||||
ConfirmationHeight: row.ConfirmationHeight,
|
||||
TimeoutSweepPkScript: row.TimeoutSweepPkScript,
|
||||
ExpirySweepTxid: row.ExpirySweepTxid,
|
||||
FinalizedWithdrawalTx: row.FinalizedWithdrawalTx,
|
||||
SwapHash: row.SwapHash,
|
||||
StaticAddressID: row.StaticAddressID,
|
||||
ClientPubkey: row.ClientPubkey,
|
||||
ServerPubkey: row.ServerPubkey,
|
||||
Expiry: row.Expiry,
|
||||
ClientKeyFamily: row.ClientKeyFamily,
|
||||
ClientKeyIndex: row.ClientKeyIndex,
|
||||
Pkscript: row.Pkscript,
|
||||
ProtocolVersion: row.ProtocolVersion,
|
||||
InitiationHeight: row.InitiationHeight,
|
||||
}
|
||||
}
|
||||
|
||||
func depositRowFromOutpoint(row sqlc.DepositForOutpointRow) depositRow {
|
||||
return depositRow{
|
||||
DepositID: row.DepositID,
|
||||
TxHash: row.TxHash,
|
||||
OutIndex: row.OutIndex,
|
||||
Amount: row.Amount,
|
||||
ConfirmationHeight: row.ConfirmationHeight,
|
||||
TimeoutSweepPkScript: row.TimeoutSweepPkScript,
|
||||
ExpirySweepTxid: row.ExpirySweepTxid,
|
||||
FinalizedWithdrawalTx: row.FinalizedWithdrawalTx,
|
||||
SwapHash: row.SwapHash,
|
||||
StaticAddressID: row.StaticAddressID,
|
||||
ClientPubkey: row.ClientPubkey,
|
||||
ServerPubkey: row.ServerPubkey,
|
||||
Expiry: row.Expiry,
|
||||
ClientKeyFamily: row.ClientKeyFamily,
|
||||
ClientKeyIndex: row.ClientKeyIndex,
|
||||
Pkscript: row.Pkscript,
|
||||
ProtocolVersion: row.ProtocolVersion,
|
||||
InitiationHeight: row.InitiationHeight,
|
||||
}
|
||||
}
|
||||
|
||||
func toDeposit(row depositRow, lastUpdate sqlc.DepositUpdate) (*Deposit,
|
||||
error) {
|
||||
|
||||
id := ID{}
|
||||
|
|
@ -296,7 +413,7 @@ func ToDeposit(row sqlc.Deposit, lastUpdate sqlc.DepositUpdate) (*Deposit,
|
|||
swapHash = &hash
|
||||
}
|
||||
|
||||
return &Deposit{
|
||||
deposit := &Deposit{
|
||||
ID: id,
|
||||
state: fsm.StateType(lastUpdate.UpdateState),
|
||||
OutPoint: wire.OutPoint{
|
||||
|
|
@ -309,5 +426,57 @@ func ToDeposit(row sqlc.Deposit, lastUpdate sqlc.DepositUpdate) (*Deposit,
|
|||
ExpirySweepTxid: expirySweepTxid,
|
||||
SwapHash: swapHash,
|
||||
FinalizedWithdrawalTx: finalizedWithdrawalTx,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if row.StaticAddressID.Valid {
|
||||
clientPubkey, err := btcec.ParsePubKey(row.ClientPubkey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
serverPubkey, err := btcec.ParsePubKey(row.ServerPubkey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
deposit.AddressParams = &script.Parameters{
|
||||
ID: row.StaticAddressID.Int32,
|
||||
ClientPubkey: clientPubkey,
|
||||
ServerPubkey: serverPubkey,
|
||||
Expiry: uint32(row.Expiry.Int32),
|
||||
PkScript: row.Pkscript,
|
||||
KeyLocator: keychain.KeyLocator{
|
||||
Family: keychain.KeyFamily(
|
||||
row.ClientKeyFamily.Int32,
|
||||
),
|
||||
Index: uint32(row.ClientKeyIndex.Int32),
|
||||
},
|
||||
ProtocolVersion: version.AddressProtocolVersion(
|
||||
row.ProtocolVersion.Int32,
|
||||
),
|
||||
InitiationHeight: row.InitiationHeight.Int32,
|
||||
}
|
||||
}
|
||||
|
||||
return deposit, nil
|
||||
}
|
||||
|
||||
// BatchSetStaticAddressID sets the static address id for all deposits that
|
||||
// predate the deposit-to-address schema link.
|
||||
func (s *SqlStore) BatchSetStaticAddressID(ctx context.Context,
|
||||
staticAddressID int32) error {
|
||||
|
||||
if staticAddressID <= 0 {
|
||||
return fmt.Errorf("static address ID must be set")
|
||||
}
|
||||
|
||||
return s.baseDB.ExecTx(ctx, loopdb.NewSqlWriteOpts(),
|
||||
func(q *sqlc.Queries) error {
|
||||
return q.SetAllNullDepositsStaticAddressID(
|
||||
ctx, sql.NullInt32{
|
||||
Int32: staticAddressID,
|
||||
Valid: true,
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package deposit
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"testing"
|
||||
|
||||
|
|
@ -8,10 +9,21 @@ import (
|
|||
"github.com/jackc/pgx/v5"
|
||||
"github.com/lightninglabs/loop/fsm"
|
||||
"github.com/lightninglabs/loop/loopdb/sqlc"
|
||||
"github.com/lightninglabs/loop/staticaddr/script"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCreateDepositRejectsUnpersistedAddress(t *testing.T) {
|
||||
store := NewSqlStore(nil)
|
||||
deposit := &Deposit{
|
||||
AddressParams: &script.Parameters{},
|
||||
}
|
||||
|
||||
err := store.CreateDeposit(context.Background(), deposit)
|
||||
require.ErrorContains(t, err, "static address ID must be set")
|
||||
}
|
||||
|
||||
func TestToDeposit(t *testing.T) {
|
||||
depositID, err := GetRandomDepositID()
|
||||
require.NoError(t, err)
|
||||
|
|
@ -24,13 +36,13 @@ func TestToDeposit(t *testing.T) {
|
|||
|
||||
tests := []struct {
|
||||
name string
|
||||
row sqlc.Deposit
|
||||
row sqlc.AllDepositsRow
|
||||
lastUpdate sqlc.DepositUpdate
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
name: "fully valid data",
|
||||
row: sqlc.Deposit{
|
||||
row: sqlc.AllDepositsRow{
|
||||
DepositID: depositID[:],
|
||||
TxHash: txHash[:],
|
||||
Amount: 100000000,
|
||||
|
|
@ -44,7 +56,7 @@ func TestToDeposit(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "fully valid data",
|
||||
row: sqlc.Deposit{
|
||||
row: sqlc.AllDepositsRow{
|
||||
DepositID: depositID[:],
|
||||
TxHash: txHash[:],
|
||||
Amount: 100000000,
|
||||
|
|
|
|||
|
|
@ -601,7 +601,7 @@ func toStaticAddressLoopIn(_ context.Context, network *chaincfg.Params,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
sqlcDeposit := sqlc.Deposit{
|
||||
sqlcDeposit := sqlc.AllDepositsRow{
|
||||
DepositID: id[:],
|
||||
TxHash: d.TxHash,
|
||||
Amount: d.Amount,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ import (
|
|||
// Parameters holds all the necessary information for the 2-of-2 multisig
|
||||
// address.
|
||||
type Parameters struct {
|
||||
// ID is the database primary key of the static address row. A zero value
|
||||
// means the parameters have not been persisted yet.
|
||||
ID int32
|
||||
|
||||
// ClientPubkey is the client's pubkey for the static address. It is
|
||||
// used for the 2-of-2 funding output as well as for the client's
|
||||
// timeout path.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue