graph/db+sqldb: implement AddChannelEdge on SQLStore

In this commit, the `AddChannelEdge` method of the SQLStore is
implemented. Like the KVStore implementation, it makes use of the
available channel `batch.Scheduler` and also updates the reject and
channel caches.

This then lets us convert the following 2 unit tests to run against the
SQL backends:
- TestPartialNode
- TestAddChannelEdgeShellNodes
This commit is contained in:
Elle Mouton
2025-05-24 15:09:37 +02:00
parent c5f159f485
commit d93d104a66
5 changed files with 383 additions and 2 deletions

View File

@ -26,6 +26,81 @@ func (q *Queries) AddSourceNode(ctx context.Context, nodeID int64) error {
return err
}
const createChannel = `-- name: CreateChannel :one
/* ─────────────────────────────────────────────
channels table queries
─────────────────────────────────────────────
*/
INSERT INTO channels (
version, scid, node_id_1, node_id_2,
outpoint, capacity, bitcoin_key_1, bitcoin_key_2,
node_1_signature, node_2_signature, bitcoin_1_signature,
bitcoin_2_signature
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12
)
RETURNING id
`
type CreateChannelParams struct {
Version int16
Scid []byte
NodeID1 int64
NodeID2 int64
Outpoint string
Capacity sql.NullInt64
BitcoinKey1 []byte
BitcoinKey2 []byte
Node1Signature []byte
Node2Signature []byte
Bitcoin1Signature []byte
Bitcoin2Signature []byte
}
func (q *Queries) CreateChannel(ctx context.Context, arg CreateChannelParams) (int64, error) {
row := q.db.QueryRowContext(ctx, createChannel,
arg.Version,
arg.Scid,
arg.NodeID1,
arg.NodeID2,
arg.Outpoint,
arg.Capacity,
arg.BitcoinKey1,
arg.BitcoinKey2,
arg.Node1Signature,
arg.Node2Signature,
arg.Bitcoin1Signature,
arg.Bitcoin2Signature,
)
var id int64
err := row.Scan(&id)
return id, err
}
const createChannelExtraType = `-- name: CreateChannelExtraType :exec
/* ─────────────────────────────────────────────
channel_extra_types table queries
─────────────────────────────────────────────
*/
INSERT INTO channel_extra_types (
channel_id, type, value
)
VALUES ($1, $2, $3)
`
type CreateChannelExtraTypeParams struct {
ChannelID int64
Type int64
Value []byte
}
func (q *Queries) CreateChannelExtraType(ctx context.Context, arg CreateChannelExtraTypeParams) error {
_, err := q.db.ExecContext(ctx, createChannelExtraType, arg.ChannelID, arg.Type, arg.Value)
return err
}
const deleteExtraNodeType = `-- name: DeleteExtraNodeType :exec
DELETE FROM node_extra_types
WHERE node_id = $1
@ -83,6 +158,37 @@ func (q *Queries) DeleteNodeFeature(ctx context.Context, arg DeleteNodeFeaturePa
return err
}
const getChannelBySCID = `-- name: GetChannelBySCID :one
SELECT id, version, scid, node_id_1, node_id_2, outpoint, capacity, bitcoin_key_1, bitcoin_key_2, node_1_signature, node_2_signature, bitcoin_1_signature, bitcoin_2_signature FROM channels
WHERE scid = $1 AND version = $2
`
type GetChannelBySCIDParams struct {
Scid []byte
Version int16
}
func (q *Queries) GetChannelBySCID(ctx context.Context, arg GetChannelBySCIDParams) (Channel, error) {
row := q.db.QueryRowContext(ctx, getChannelBySCID, arg.Scid, arg.Version)
var i Channel
err := row.Scan(
&i.ID,
&i.Version,
&i.Scid,
&i.NodeID1,
&i.NodeID2,
&i.Outpoint,
&i.Capacity,
&i.BitcoinKey1,
&i.BitcoinKey2,
&i.Node1Signature,
&i.Node2Signature,
&i.Bitcoin1Signature,
&i.Bitcoin2Signature,
)
return i, err
}
const getExtraNodeTypes = `-- name: GetExtraNodeTypes :many
SELECT node_id, type, value
FROM node_extra_types
@ -323,6 +429,29 @@ func (q *Queries) GetSourceNodesByVersion(ctx context.Context, version int16) ([
return items, nil
}
const insertChannelFeature = `-- name: InsertChannelFeature :exec
/* ─────────────────────────────────────────────
channel_features table queries
─────────────────────────────────────────────
*/
INSERT INTO channel_features (
channel_id, feature_bit
) VALUES (
$1, $2
)
`
type InsertChannelFeatureParams struct {
ChannelID int64
FeatureBit int32
}
func (q *Queries) InsertChannelFeature(ctx context.Context, arg InsertChannelFeatureParams) error {
_, err := q.db.ExecContext(ctx, insertChannelFeature, arg.ChannelID, arg.FeatureBit)
return err
}
const insertNodeAddress = `-- name: InsertNodeAddress :exec
/* ─────────────────────────────────────────────
node_addresses table queries

View File

@ -13,6 +13,8 @@ import (
type Querier interface {
AddSourceNode(ctx context.Context, nodeID int64) error
ClearKVInvoiceHashIndex(ctx context.Context) error
CreateChannel(ctx context.Context, arg CreateChannelParams) (int64, error)
CreateChannelExtraType(ctx context.Context, arg CreateChannelExtraTypeParams) error
DeleteCanceledInvoices(ctx context.Context) (sql.Result, error)
DeleteExtraNodeType(ctx context.Context, arg DeleteExtraNodeTypeParams) error
DeleteInvoice(ctx context.Context, arg DeleteInvoiceParams) (sql.Result, error)
@ -24,6 +26,7 @@ type Querier interface {
FetchSettledAMPSubInvoices(ctx context.Context, arg FetchSettledAMPSubInvoicesParams) ([]FetchSettledAMPSubInvoicesRow, error)
FilterInvoices(ctx context.Context, arg FilterInvoicesParams) ([]Invoice, error)
GetAMPInvoiceID(ctx context.Context, setID []byte) (int64, error)
GetChannelBySCID(ctx context.Context, arg GetChannelBySCIDParams) (Channel, error)
GetDatabaseVersion(ctx context.Context) (int32, error)
GetExtraNodeTypes(ctx context.Context, nodeID int64) ([]NodeExtraType, error)
// This method may return more than one invoice if filter using multiple fields
@ -45,6 +48,7 @@ type Querier interface {
GetSourceNodesByVersion(ctx context.Context, version int16) ([]GetSourceNodesByVersionRow, error)
InsertAMPSubInvoice(ctx context.Context, arg InsertAMPSubInvoiceParams) error
InsertAMPSubInvoiceHTLC(ctx context.Context, arg InsertAMPSubInvoiceHTLCParams) error
InsertChannelFeature(ctx context.Context, arg InsertChannelFeatureParams) error
InsertInvoice(ctx context.Context, arg InsertInvoiceParams) (int64, error)
InsertInvoiceFeature(ctx context.Context, arg InsertInvoiceFeatureParams) error
InsertInvoiceHTLC(ctx context.Context, arg InsertInvoiceHTLCParams) (int64, error)

View File

@ -132,3 +132,46 @@ SELECT sn.node_id, n.pub_key
FROM source_nodes sn
JOIN nodes n ON sn.node_id = n.id
WHERE n.version = $1;
/* ─────────────────────────────────────────────
channels table queries
─────────────────────────────────────────────
*/
-- name: CreateChannel :one
INSERT INTO channels (
version, scid, node_id_1, node_id_2,
outpoint, capacity, bitcoin_key_1, bitcoin_key_2,
node_1_signature, node_2_signature, bitcoin_1_signature,
bitcoin_2_signature
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12
)
RETURNING id;
-- name: GetChannelBySCID :one
SELECT * FROM channels
WHERE scid = $1 AND version = $2;
/* ─────────────────────────────────────────────
channel_features table queries
─────────────────────────────────────────────
*/
-- name: InsertChannelFeature :exec
INSERT INTO channel_features (
channel_id, feature_bit
) VALUES (
$1, $2
);
/* ─────────────────────────────────────────────
channel_extra_types table queries
─────────────────────────────────────────────
*/
-- name: CreateChannelExtraType :exec
INSERT INTO channel_extra_types (
channel_id, type, value
)
VALUES ($1, $2, $3);