mirror of
https://github.com/lightninglabs/loop.git
synced 2026-08-13 12:33:03 +02:00
staticaddr/loopin: use generated change addresses
Create a fresh static change address for fractional loop-ins and persist its key locator with the selected HTLC outpoint. Recovery reconstructs the same change output instead of returning funds to the legacy root address.
This commit is contained in:
parent
d1b29e0bb5
commit
b2f37bfa78
18 changed files with 878 additions and 90 deletions
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE static_address_swaps DROP COLUMN change_static_address_id;
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
ALTER TABLE static_address_swaps
|
||||
ADD change_static_address_id INT REFERENCES static_addresses(id);
|
||||
|
||||
-- Existing fractional swaps sent change back to the legacy static address.
|
||||
-- Backfill that relation so in-flight swaps remain recoverable after the
|
||||
-- client starts requiring explicit per-swap change metadata.
|
||||
UPDATE static_address_swaps
|
||||
SET change_static_address_id = (
|
||||
SELECT id FROM static_addresses ORDER BY id ASC LIMIT 1
|
||||
)
|
||||
WHERE selected_amount > 0
|
||||
AND change_static_address_id IS NULL
|
||||
AND EXISTS (SELECT 1 FROM static_addresses);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
ALTER TABLE static_address_swaps
|
||||
DROP COLUMN confirmed_htlc_output_value;
|
||||
|
||||
ALTER TABLE static_address_swaps
|
||||
DROP COLUMN confirmed_htlc_output_index;
|
||||
|
||||
ALTER TABLE static_address_swaps
|
||||
DROP COLUMN confirmed_htlc_tx_id;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
ALTER TABLE static_address_swaps
|
||||
ADD confirmed_htlc_tx_id TEXT;
|
||||
|
||||
ALTER TABLE static_address_swaps
|
||||
ADD confirmed_htlc_output_index INTEGER;
|
||||
|
||||
ALTER TABLE static_address_swaps
|
||||
ADD confirmed_htlc_output_value BIGINT;
|
||||
|
|
@ -152,6 +152,10 @@ type StaticAddressSwap struct {
|
|||
Fast bool
|
||||
ConfirmationRiskDecision string
|
||||
ConfirmationRiskDecisionTime sql.NullTime
|
||||
ChangeStaticAddressID sql.NullInt32
|
||||
ConfirmedHtlcTxID sql.NullString
|
||||
ConfirmedHtlcOutputIndex sql.NullInt32
|
||||
ConfirmedHtlcOutputValue sql.NullInt64
|
||||
}
|
||||
|
||||
type StaticAddressSwapUpdate struct {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ INSERT INTO static_address_swaps (
|
|||
htlc_tx_fee_rate_sat_kw,
|
||||
htlc_timeout_sweep_tx_id,
|
||||
htlc_timeout_sweep_address,
|
||||
fast
|
||||
fast,
|
||||
change_static_address_id
|
||||
) VALUES (
|
||||
$1,
|
||||
$2,
|
||||
|
|
@ -22,14 +23,18 @@ INSERT INTO static_address_swaps (
|
|||
$8,
|
||||
$9,
|
||||
$10,
|
||||
$11
|
||||
$11,
|
||||
$12
|
||||
);
|
||||
|
||||
-- name: UpdateStaticAddressLoopIn :exec
|
||||
UPDATE static_address_swaps
|
||||
SET
|
||||
htlc_tx_fee_rate_sat_kw = $2,
|
||||
htlc_timeout_sweep_tx_id = $3
|
||||
htlc_timeout_sweep_tx_id = $3,
|
||||
confirmed_htlc_tx_id = $4,
|
||||
confirmed_htlc_output_index = $5,
|
||||
confirmed_htlc_output_value = $6
|
||||
WHERE
|
||||
swap_hash = $1;
|
||||
|
||||
|
|
@ -64,13 +69,24 @@ INSERT INTO static_address_swap_updates (
|
|||
SELECT
|
||||
swaps.*,
|
||||
static_address_swaps.*,
|
||||
htlc_keys.*
|
||||
htlc_keys.*,
|
||||
change_address.client_pubkey change_client_pubkey,
|
||||
change_address.server_pubkey change_server_pubkey,
|
||||
change_address.expiry change_expiry,
|
||||
change_address.client_key_family change_client_key_family,
|
||||
change_address.client_key_index change_client_key_index,
|
||||
change_address.pkscript change_pkscript,
|
||||
change_address.protocol_version change_protocol_version,
|
||||
change_address.initiation_height change_initiation_height
|
||||
FROM
|
||||
swaps
|
||||
JOIN
|
||||
static_address_swaps ON swaps.swap_hash = static_address_swaps.swap_hash
|
||||
JOIN
|
||||
htlc_keys ON swaps.swap_hash = htlc_keys.swap_hash
|
||||
LEFT JOIN
|
||||
static_addresses change_address
|
||||
ON static_address_swaps.change_static_address_id = change_address.id
|
||||
WHERE
|
||||
swaps.swap_hash = $1;
|
||||
|
||||
|
|
@ -78,13 +94,24 @@ WHERE
|
|||
SELECT
|
||||
swaps.*,
|
||||
static_address_swaps.*,
|
||||
htlc_keys.*
|
||||
htlc_keys.*,
|
||||
change_address.client_pubkey change_client_pubkey,
|
||||
change_address.server_pubkey change_server_pubkey,
|
||||
change_address.expiry change_expiry,
|
||||
change_address.client_key_family change_client_key_family,
|
||||
change_address.client_key_index change_client_key_index,
|
||||
change_address.pkscript change_pkscript,
|
||||
change_address.protocol_version change_protocol_version,
|
||||
change_address.initiation_height change_initiation_height
|
||||
FROM
|
||||
swaps
|
||||
JOIN
|
||||
static_address_swaps ON swaps.swap_hash = static_address_swaps.swap_hash
|
||||
JOIN
|
||||
htlc_keys ON swaps.swap_hash = htlc_keys.swap_hash
|
||||
LEFT JOIN
|
||||
static_addresses change_address
|
||||
ON static_address_swaps.change_static_address_id = change_address.id
|
||||
JOIN
|
||||
static_address_swap_updates u ON swaps.swap_hash = u.swap_hash
|
||||
-- This subquery ensures that we are checking only the latest update for
|
||||
|
|
@ -170,5 +197,3 @@ FROM
|
|||
)
|
||||
WHERE
|
||||
d.swap_hash = $1;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -180,14 +180,25 @@ func (q *Queries) GetLoopInSwapUpdates(ctx context.Context, swapHash []byte) ([]
|
|||
const getStaticAddressLoopInSwap = `-- name: GetStaticAddressLoopInSwap :one
|
||||
SELECT
|
||||
swaps.id, swaps.swap_hash, swaps.preimage, swaps.initiation_time, swaps.amount_requested, swaps.cltv_expiry, swaps.max_miner_fee, swaps.max_swap_fee, swaps.initiation_height, swaps.protocol_version, swaps.label,
|
||||
static_address_swaps.id, static_address_swaps.swap_hash, static_address_swaps.swap_invoice, static_address_swaps.last_hop, static_address_swaps.payment_timeout_seconds, static_address_swaps.quoted_swap_fee_satoshis, static_address_swaps.deposit_outpoints, static_address_swaps.htlc_tx_fee_rate_sat_kw, static_address_swaps.htlc_timeout_sweep_tx_id, static_address_swaps.htlc_timeout_sweep_address, static_address_swaps.selected_amount, static_address_swaps.fast, static_address_swaps.confirmation_risk_decision, static_address_swaps.confirmation_risk_decision_time,
|
||||
htlc_keys.swap_hash, htlc_keys.sender_script_pubkey, htlc_keys.receiver_script_pubkey, htlc_keys.sender_internal_pubkey, htlc_keys.receiver_internal_pubkey, htlc_keys.client_key_family, htlc_keys.client_key_index
|
||||
static_address_swaps.id, static_address_swaps.swap_hash, static_address_swaps.swap_invoice, static_address_swaps.last_hop, static_address_swaps.payment_timeout_seconds, static_address_swaps.quoted_swap_fee_satoshis, static_address_swaps.deposit_outpoints, static_address_swaps.htlc_tx_fee_rate_sat_kw, static_address_swaps.htlc_timeout_sweep_tx_id, static_address_swaps.htlc_timeout_sweep_address, static_address_swaps.selected_amount, static_address_swaps.fast, static_address_swaps.confirmation_risk_decision, static_address_swaps.confirmation_risk_decision_time, static_address_swaps.change_static_address_id, static_address_swaps.confirmed_htlc_tx_id, static_address_swaps.confirmed_htlc_output_index, static_address_swaps.confirmed_htlc_output_value,
|
||||
htlc_keys.swap_hash, htlc_keys.sender_script_pubkey, htlc_keys.receiver_script_pubkey, htlc_keys.sender_internal_pubkey, htlc_keys.receiver_internal_pubkey, htlc_keys.client_key_family, htlc_keys.client_key_index,
|
||||
change_address.client_pubkey change_client_pubkey,
|
||||
change_address.server_pubkey change_server_pubkey,
|
||||
change_address.expiry change_expiry,
|
||||
change_address.client_key_family change_client_key_family,
|
||||
change_address.client_key_index change_client_key_index,
|
||||
change_address.pkscript change_pkscript,
|
||||
change_address.protocol_version change_protocol_version,
|
||||
change_address.initiation_height change_initiation_height
|
||||
FROM
|
||||
swaps
|
||||
JOIN
|
||||
static_address_swaps ON swaps.swap_hash = static_address_swaps.swap_hash
|
||||
JOIN
|
||||
htlc_keys ON swaps.swap_hash = htlc_keys.swap_hash
|
||||
LEFT JOIN
|
||||
static_addresses change_address
|
||||
ON static_address_swaps.change_static_address_id = change_address.id
|
||||
WHERE
|
||||
swaps.swap_hash = $1
|
||||
`
|
||||
|
|
@ -218,6 +229,10 @@ type GetStaticAddressLoopInSwapRow struct {
|
|||
Fast bool
|
||||
ConfirmationRiskDecision string
|
||||
ConfirmationRiskDecisionTime sql.NullTime
|
||||
ChangeStaticAddressID sql.NullInt32
|
||||
ConfirmedHtlcTxID sql.NullString
|
||||
ConfirmedHtlcOutputIndex sql.NullInt32
|
||||
ConfirmedHtlcOutputValue sql.NullInt64
|
||||
SwapHash_3 []byte
|
||||
SenderScriptPubkey []byte
|
||||
ReceiverScriptPubkey []byte
|
||||
|
|
@ -225,6 +240,14 @@ type GetStaticAddressLoopInSwapRow struct {
|
|||
ReceiverInternalPubkey []byte
|
||||
ClientKeyFamily int32
|
||||
ClientKeyIndex int32
|
||||
ChangeClientPubkey []byte
|
||||
ChangeServerPubkey []byte
|
||||
ChangeExpiry sql.NullInt32
|
||||
ChangeClientKeyFamily sql.NullInt32
|
||||
ChangeClientKeyIndex sql.NullInt32
|
||||
ChangePkscript []byte
|
||||
ChangeProtocolVersion sql.NullInt32
|
||||
ChangeInitiationHeight sql.NullInt32
|
||||
}
|
||||
|
||||
func (q *Queries) GetStaticAddressLoopInSwap(ctx context.Context, swapHash []byte) (GetStaticAddressLoopInSwapRow, error) {
|
||||
|
|
@ -256,6 +279,10 @@ func (q *Queries) GetStaticAddressLoopInSwap(ctx context.Context, swapHash []byt
|
|||
&i.Fast,
|
||||
&i.ConfirmationRiskDecision,
|
||||
&i.ConfirmationRiskDecisionTime,
|
||||
&i.ChangeStaticAddressID,
|
||||
&i.ConfirmedHtlcTxID,
|
||||
&i.ConfirmedHtlcOutputIndex,
|
||||
&i.ConfirmedHtlcOutputValue,
|
||||
&i.SwapHash_3,
|
||||
&i.SenderScriptPubkey,
|
||||
&i.ReceiverScriptPubkey,
|
||||
|
|
@ -263,6 +290,14 @@ func (q *Queries) GetStaticAddressLoopInSwap(ctx context.Context, swapHash []byt
|
|||
&i.ReceiverInternalPubkey,
|
||||
&i.ClientKeyFamily,
|
||||
&i.ClientKeyIndex,
|
||||
&i.ChangeClientPubkey,
|
||||
&i.ChangeServerPubkey,
|
||||
&i.ChangeExpiry,
|
||||
&i.ChangeClientKeyFamily,
|
||||
&i.ChangeClientKeyIndex,
|
||||
&i.ChangePkscript,
|
||||
&i.ChangeProtocolVersion,
|
||||
&i.ChangeInitiationHeight,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
|
@ -270,14 +305,25 @@ func (q *Queries) GetStaticAddressLoopInSwap(ctx context.Context, swapHash []byt
|
|||
const getStaticAddressLoopInSwapsByStates = `-- name: GetStaticAddressLoopInSwapsByStates :many
|
||||
SELECT
|
||||
swaps.id, swaps.swap_hash, swaps.preimage, swaps.initiation_time, swaps.amount_requested, swaps.cltv_expiry, swaps.max_miner_fee, swaps.max_swap_fee, swaps.initiation_height, swaps.protocol_version, swaps.label,
|
||||
static_address_swaps.id, static_address_swaps.swap_hash, static_address_swaps.swap_invoice, static_address_swaps.last_hop, static_address_swaps.payment_timeout_seconds, static_address_swaps.quoted_swap_fee_satoshis, static_address_swaps.deposit_outpoints, static_address_swaps.htlc_tx_fee_rate_sat_kw, static_address_swaps.htlc_timeout_sweep_tx_id, static_address_swaps.htlc_timeout_sweep_address, static_address_swaps.selected_amount, static_address_swaps.fast, static_address_swaps.confirmation_risk_decision, static_address_swaps.confirmation_risk_decision_time,
|
||||
htlc_keys.swap_hash, htlc_keys.sender_script_pubkey, htlc_keys.receiver_script_pubkey, htlc_keys.sender_internal_pubkey, htlc_keys.receiver_internal_pubkey, htlc_keys.client_key_family, htlc_keys.client_key_index
|
||||
static_address_swaps.id, static_address_swaps.swap_hash, static_address_swaps.swap_invoice, static_address_swaps.last_hop, static_address_swaps.payment_timeout_seconds, static_address_swaps.quoted_swap_fee_satoshis, static_address_swaps.deposit_outpoints, static_address_swaps.htlc_tx_fee_rate_sat_kw, static_address_swaps.htlc_timeout_sweep_tx_id, static_address_swaps.htlc_timeout_sweep_address, static_address_swaps.selected_amount, static_address_swaps.fast, static_address_swaps.confirmation_risk_decision, static_address_swaps.confirmation_risk_decision_time, static_address_swaps.change_static_address_id, static_address_swaps.confirmed_htlc_tx_id, static_address_swaps.confirmed_htlc_output_index, static_address_swaps.confirmed_htlc_output_value,
|
||||
htlc_keys.swap_hash, htlc_keys.sender_script_pubkey, htlc_keys.receiver_script_pubkey, htlc_keys.sender_internal_pubkey, htlc_keys.receiver_internal_pubkey, htlc_keys.client_key_family, htlc_keys.client_key_index,
|
||||
change_address.client_pubkey change_client_pubkey,
|
||||
change_address.server_pubkey change_server_pubkey,
|
||||
change_address.expiry change_expiry,
|
||||
change_address.client_key_family change_client_key_family,
|
||||
change_address.client_key_index change_client_key_index,
|
||||
change_address.pkscript change_pkscript,
|
||||
change_address.protocol_version change_protocol_version,
|
||||
change_address.initiation_height change_initiation_height
|
||||
FROM
|
||||
swaps
|
||||
JOIN
|
||||
static_address_swaps ON swaps.swap_hash = static_address_swaps.swap_hash
|
||||
JOIN
|
||||
htlc_keys ON swaps.swap_hash = htlc_keys.swap_hash
|
||||
LEFT JOIN
|
||||
static_addresses change_address
|
||||
ON static_address_swaps.change_static_address_id = change_address.id
|
||||
JOIN
|
||||
static_address_swap_updates u ON swaps.swap_hash = u.swap_hash
|
||||
-- This subquery ensures that we are checking only the latest update for
|
||||
|
|
@ -319,6 +365,10 @@ type GetStaticAddressLoopInSwapsByStatesRow struct {
|
|||
Fast bool
|
||||
ConfirmationRiskDecision string
|
||||
ConfirmationRiskDecisionTime sql.NullTime
|
||||
ChangeStaticAddressID sql.NullInt32
|
||||
ConfirmedHtlcTxID sql.NullString
|
||||
ConfirmedHtlcOutputIndex sql.NullInt32
|
||||
ConfirmedHtlcOutputValue sql.NullInt64
|
||||
SwapHash_3 []byte
|
||||
SenderScriptPubkey []byte
|
||||
ReceiverScriptPubkey []byte
|
||||
|
|
@ -326,6 +376,14 @@ type GetStaticAddressLoopInSwapsByStatesRow struct {
|
|||
ReceiverInternalPubkey []byte
|
||||
ClientKeyFamily int32
|
||||
ClientKeyIndex int32
|
||||
ChangeClientPubkey []byte
|
||||
ChangeServerPubkey []byte
|
||||
ChangeExpiry sql.NullInt32
|
||||
ChangeClientKeyFamily sql.NullInt32
|
||||
ChangeClientKeyIndex sql.NullInt32
|
||||
ChangePkscript []byte
|
||||
ChangeProtocolVersion sql.NullInt32
|
||||
ChangeInitiationHeight sql.NullInt32
|
||||
}
|
||||
|
||||
func (q *Queries) GetStaticAddressLoopInSwapsByStates(ctx context.Context, dollar_1 sql.NullString) ([]GetStaticAddressLoopInSwapsByStatesRow, error) {
|
||||
|
|
@ -363,6 +421,10 @@ func (q *Queries) GetStaticAddressLoopInSwapsByStates(ctx context.Context, dolla
|
|||
&i.Fast,
|
||||
&i.ConfirmationRiskDecision,
|
||||
&i.ConfirmationRiskDecisionTime,
|
||||
&i.ChangeStaticAddressID,
|
||||
&i.ConfirmedHtlcTxID,
|
||||
&i.ConfirmedHtlcOutputIndex,
|
||||
&i.ConfirmedHtlcOutputValue,
|
||||
&i.SwapHash_3,
|
||||
&i.SenderScriptPubkey,
|
||||
&i.ReceiverScriptPubkey,
|
||||
|
|
@ -370,6 +432,14 @@ func (q *Queries) GetStaticAddressLoopInSwapsByStates(ctx context.Context, dolla
|
|||
&i.ReceiverInternalPubkey,
|
||||
&i.ClientKeyFamily,
|
||||
&i.ClientKeyIndex,
|
||||
&i.ChangeClientPubkey,
|
||||
&i.ChangeServerPubkey,
|
||||
&i.ChangeExpiry,
|
||||
&i.ChangeClientKeyFamily,
|
||||
&i.ChangeClientKeyIndex,
|
||||
&i.ChangePkscript,
|
||||
&i.ChangeProtocolVersion,
|
||||
&i.ChangeInitiationHeight,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -396,7 +466,8 @@ INSERT INTO static_address_swaps (
|
|||
htlc_tx_fee_rate_sat_kw,
|
||||
htlc_timeout_sweep_tx_id,
|
||||
htlc_timeout_sweep_address,
|
||||
fast
|
||||
fast,
|
||||
change_static_address_id
|
||||
) VALUES (
|
||||
$1,
|
||||
$2,
|
||||
|
|
@ -408,7 +479,8 @@ INSERT INTO static_address_swaps (
|
|||
$8,
|
||||
$9,
|
||||
$10,
|
||||
$11
|
||||
$11,
|
||||
$12
|
||||
)
|
||||
`
|
||||
|
||||
|
|
@ -424,6 +496,7 @@ type InsertStaticAddressLoopInParams struct {
|
|||
HtlcTimeoutSweepTxID sql.NullString
|
||||
HtlcTimeoutSweepAddress string
|
||||
Fast bool
|
||||
ChangeStaticAddressID sql.NullInt32
|
||||
}
|
||||
|
||||
func (q *Queries) InsertStaticAddressLoopIn(ctx context.Context, arg InsertStaticAddressLoopInParams) error {
|
||||
|
|
@ -439,6 +512,7 @@ func (q *Queries) InsertStaticAddressLoopIn(ctx context.Context, arg InsertStati
|
|||
arg.HtlcTimeoutSweepTxID,
|
||||
arg.HtlcTimeoutSweepAddress,
|
||||
arg.Fast,
|
||||
arg.ChangeStaticAddressID,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
|
@ -565,18 +639,31 @@ const updateStaticAddressLoopIn = `-- name: UpdateStaticAddressLoopIn :exec
|
|||
UPDATE static_address_swaps
|
||||
SET
|
||||
htlc_tx_fee_rate_sat_kw = $2,
|
||||
htlc_timeout_sweep_tx_id = $3
|
||||
htlc_timeout_sweep_tx_id = $3,
|
||||
confirmed_htlc_tx_id = $4,
|
||||
confirmed_htlc_output_index = $5,
|
||||
confirmed_htlc_output_value = $6
|
||||
WHERE
|
||||
swap_hash = $1
|
||||
`
|
||||
|
||||
type UpdateStaticAddressLoopInParams struct {
|
||||
SwapHash []byte
|
||||
HtlcTxFeeRateSatKw int64
|
||||
HtlcTimeoutSweepTxID sql.NullString
|
||||
SwapHash []byte
|
||||
HtlcTxFeeRateSatKw int64
|
||||
HtlcTimeoutSweepTxID sql.NullString
|
||||
ConfirmedHtlcTxID sql.NullString
|
||||
ConfirmedHtlcOutputIndex sql.NullInt32
|
||||
ConfirmedHtlcOutputValue sql.NullInt64
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateStaticAddressLoopIn(ctx context.Context, arg UpdateStaticAddressLoopInParams) error {
|
||||
_, err := q.db.ExecContext(ctx, updateStaticAddressLoopIn, arg.SwapHash, arg.HtlcTxFeeRateSatKw, arg.HtlcTimeoutSweepTxID)
|
||||
_, err := q.db.ExecContext(ctx, updateStaticAddressLoopIn,
|
||||
arg.SwapHash,
|
||||
arg.HtlcTxFeeRateSatKw,
|
||||
arg.HtlcTimeoutSweepTxID,
|
||||
arg.ConfirmedHtlcTxID,
|
||||
arg.ConfirmedHtlcOutputIndex,
|
||||
arg.ConfirmedHtlcOutputValue,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue