Skip to content

Commit

Permalink
tapdb: allow tweak to be upserted
Browse files Browse the repository at this point in the history
This fixes a bug where if we ever inserted a script key before knowing
its tweak, we could never update the tweak later on when we learn it.
This meant that such keys would be seen as BIP-086 keys, even though we
later learn they aren't.
  • Loading branch information
guggero committed Nov 27, 2024
1 parent 3451af2 commit 38b28f2
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 6 deletions.
50 changes: 50 additions & 0 deletions tapdb/addrs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,14 @@ func assertKeyKnowledge(t *testing.T, ctx context.Context,
require.Equal(t, known, dbScriptKey.DeclaredKnown)
}

func assertTweak(t *testing.T, ctx context.Context, addrBook *TapAddressBook,
scriptKey asset.ScriptKey, tweak []byte) {

dbScriptKey, err := addrBook.FetchScriptKey(ctx, scriptKey.PubKey)
require.NoError(t, err)
require.Equal(t, tweak, dbScriptKey.Tweak)
}

// TestScriptKeyKnownUpsert tests that we can insert a script key, then insert
// it again declared as known.
func TestScriptKeyKnownUpsert(t *testing.T) {
Expand Down Expand Up @@ -757,3 +765,45 @@ func TestScriptKeyKnownUpsert(t *testing.T) {
assertKeyKnowledge(t, ctx, addrBook, scriptKey, known)
})
}

// TestScriptKeyTweakUpsert tests that we can insert a script key, then insert
// it again when we know the tweak for it.
func TestScriptKeyTweakUpsert(t *testing.T) {
t.Parallel()

// First, make a new addr book instance we'll use in the test below.
testClock := clock.NewTestClock(time.Now())
addrBook, _ := newAddrBook(t, testClock)

ctx := context.Background()

// In this test, we insert the tweak as NULL, and make sure we overwrite
// it with an actual value again later.
t.Run("null_to_value", func(t *testing.T) {
known := false
scriptKey := randScriptKey(t)
scriptKey.Tweak = nil

// We'll insert a random script key into the database. We won't
// declare it as known though, and it doesn't have the tweak.
err := addrBook.InsertScriptKey(ctx, scriptKey, known)
require.NoError(t, err)

// We'll fetch the script key and confirm that it's not known.
assertKeyKnowledge(t, ctx, addrBook, scriptKey, known)
assertTweak(t, ctx, addrBook, scriptKey, nil)

known = true
randTweak := test.RandBytes(32)
scriptKey.Tweak = randTweak

// We'll now insert it again, but this time declare it as known
// and also know the tweak.
err = addrBook.InsertScriptKey(ctx, scriptKey, known)
require.NoError(t, err)

// We'll fetch the script key and confirm that it's known.
assertKeyKnowledge(t, ctx, addrBook, scriptKey, known)
assertTweak(t, ctx, addrBook, scriptKey, randTweak)
})
}
12 changes: 9 additions & 3 deletions tapdb/sqlc/assets.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions tapdb/sqlc/queries/assets.sql
Original file line number Diff line number Diff line change
Expand Up @@ -852,8 +852,8 @@ INSERT INTO script_keys (
) VALUES (
$1, $2, $3, $4
) ON CONFLICT (tweaked_script_key)
-- As a NOP, we just set the script key to the one that triggered the
-- conflict.
-- Overwrite the declared_known and tweak fields if they were previously
-- unknown.
DO UPDATE SET
tweaked_script_key = EXCLUDED.tweaked_script_key,
-- If the script key was previously unknown, we'll update to the new
Expand All @@ -862,7 +862,13 @@ INSERT INTO script_keys (
WHEN script_keys.declared_known IS NULL OR script_keys.declared_known = FALSE
THEN COALESCE(EXCLUDED.declared_known, script_keys.declared_known)
ELSE script_keys.declared_known
END
END,
-- If the tweak was previously unknown, we'll update to the new value.
tweak = CASE
WHEN script_keys.tweak IS NULL
THEN COALESCE(EXCLUDED.tweak, script_keys.tweak)
ELSE script_keys.tweak
END
RETURNING script_key_id;

-- name: FetchScriptKeyIDByTweakedKey :one
Expand Down

0 comments on commit 38b28f2

Please sign in to comment.