Skip to content

Commit 41615f7

Browse files
committed
graph/db: add test for SetSourceNode same timestamp behavior
This commit adds TestSetSourceNodeSameTimestamp to demonstrate the current behavior when SetSourceNode is called with the same last update timestamp. The test reveals a difference between the SQL and bbolt implementations: - SQL store returns sql.ErrNoRows when attempting to update with the same timestamp, as the upsert query's UPDATE clause requires the new timestamp to be strictly greater than the existing one - bbolt store silently ignores stale updates and returns no error This behavior is important to document because our own node announcements may change quickly with the same timestamp, unlike announcements from other nodes where same timestamp typically means identical parameters.
1 parent 4b1c499 commit 41615f7

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

graph/db/graph_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"context"
66
"crypto/sha256"
7+
"database/sql"
78
"encoding/hex"
89
"errors"
910
"fmt"
@@ -396,6 +397,62 @@ func TestSourceNode(t *testing.T) {
396397
compareNodes(t, testNode, sourceNode)
397398
}
398399

400+
// TestSetSourceNodeSameTimestamp demonstrates that SetSourceNode can return an
401+
// error when called with the same last update timestamp. Calling SetSourceNode
402+
// with the same timestamp should be allowed (unlike AddNode), as it is
403+
// possible that our own node announcement may change quickly. This will be
404+
// fixed in an upcoming commit.
405+
func TestSetSourceNodeSameTimestamp(t *testing.T) {
406+
t.Parallel()
407+
ctx := t.Context()
408+
409+
graph := MakeTestGraph(t)
410+
411+
_, isSQLStore := graph.V1Store.(*SQLStore)
412+
413+
// Create and set the initial source node.
414+
testNode := createTestVertex(t)
415+
require.NoError(t, graph.SetSourceNode(ctx, testNode))
416+
417+
// Verify the source node was set correctly.
418+
sourceNode, err := graph.SourceNode(ctx)
419+
require.NoError(t, err)
420+
compareNodes(t, testNode, sourceNode)
421+
422+
// Create a modified version of the node with the same timestamp but
423+
// different parameters (e.g., different alias and color). This
424+
// could well be the case for our own node announcement (unlike other
425+
// announcements where same timestamp means same parameters).
426+
modifiedNode := models.NewV1Node(
427+
testNode.PubKeyBytes, &models.NodeV1Fields{
428+
// Same timestamp.
429+
LastUpdate: testNode.LastUpdate,
430+
// Different alias.
431+
Alias: "different-alias",
432+
Color: color.RGBA{R: 100, G: 200, B: 50, A: 0},
433+
Addresses: testNode.Addresses,
434+
Features: testNode.Features.RawFeatureVector,
435+
AuthSigBytes: testNode.AuthSigBytes,
436+
},
437+
)
438+
439+
// Attempt to set the source node with the same timestamp but
440+
// different parameters.
441+
err = graph.SetSourceNode(ctx, modifiedNode)
442+
443+
// The SQL store will return sql.ErrNoRows because the UPDATE clause
444+
// in the upsert query requires the new timestamp to be strictly
445+
// greater than the existing one. When this condition is not met, no
446+
// rows are updated and the SQL query returns ErrNoRows. The bbolt KV
447+
// store, on the other hand, silently ignores stale updates and returns
448+
// no error.
449+
if isSQLStore {
450+
require.ErrorIs(t, err, sql.ErrNoRows)
451+
} else {
452+
require.NoError(t, err)
453+
}
454+
}
455+
399456
// TestEdgeInsertionDeletion tests the basic CRUD operations for channel edges.
400457
func TestEdgeInsertionDeletion(t *testing.T) {
401458
t.Parallel()

0 commit comments

Comments
 (0)