diff --git a/tapdb/addrs_test.go b/tapdb/addrs_test.go index 443197fe4..c3e306ace 100644 --- a/tapdb/addrs_test.go +++ b/tapdb/addrs_test.go @@ -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) { @@ -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) + }) +} diff --git a/tapdb/sqlc/assets.sql.go b/tapdb/sqlc/assets.sql.go index fa1ca8f87..a518ebbc3 100644 --- a/tapdb/sqlc/assets.sql.go +++ b/tapdb/sqlc/assets.sql.go @@ -2878,8 +2878,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 @@ -2888,7 +2888,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 ` diff --git a/tapdb/sqlc/queries/assets.sql b/tapdb/sqlc/queries/assets.sql index a16302d27..78bfa313b 100644 --- a/tapdb/sqlc/queries/assets.sql +++ b/tapdb/sqlc/queries/assets.sql @@ -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 @@ -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