Skip to content

Commit

Permalink
tapdb: update InsertScriptKey to allow flipping known to true
Browse files Browse the repository at this point in the history
In this commit, we update `InsertScriptKey` to allow flipping known to
true, if it was false before.

This is useful as at times a script key from a smart contract might have
been inserting on disk, but with declared known as false. Then if we
tried to insert it again, with known as true, the upsert logic would end
up making no change on disk.
  • Loading branch information
Roasbeef committed Nov 9, 2024
1 parent eb9f19f commit 2b288da
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 2 deletions.
26 changes: 24 additions & 2 deletions tapdb/addrs.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ type AddrBook interface {
// FetchInternalKeyLocator fetches the key locator for an internal key.
FetchInternalKeyLocator(ctx context.Context, rawKey []byte) (KeyLocator,
error)

// DeclareScriptKeyKnown declares a script key as known to the wallet.
DeclareScriptKeyKnown(ctx context.Context, rawKey []byte) error
}

// AddrBookTxOptions defines the set of db txn options the AddrBook
Expand Down Expand Up @@ -681,22 +684,41 @@ func (t *TapAddressBook) InsertScriptKey(ctx context.Context,
scriptKey asset.ScriptKey, declaredKnown bool) error {

var writeTxOpts AddrBookTxOptions
return t.db.ExecTx(ctx, &writeTxOpts, func(q AddrBook) error {
err := t.db.ExecTx(ctx, &writeTxOpts, func(q AddrBook) error {
internalKeyID, err := insertInternalKey(
ctx, q, scriptKey.RawKey,
)
if err != nil {
return fmt.Errorf("error inserting internal key: %w",
err)
}

_, err = q.UpsertScriptKey(ctx, NewScriptKey{
InternalKeyID: internalKeyID,
TweakedScriptKey: scriptKey.PubKey.SerializeCompressed(),
Tweak: scriptKey.Tweak,
DeclaredKnown: sqlBool(declaredKnown),
})
return err
if err != nil {
return fmt.Errorf("error inserting script key: %w", err)
}

// This key might already exist, so we'll make sure that
// declared_known is set to true. Otherwise, if the key already
// existed, and we need to view it as ours, we'll fail to do so.
if declaredKnown {
return q.DeclareScriptKeyKnown(
ctx, scriptKey.PubKey.SerializeCompressed(),
)
}

return nil
})
if err != nil {
return fmt.Errorf("error inserting script key: %w", err)
}

return nil
}

// GetOrCreateEvent creates a new address event for the given status, address
Expand Down
44 changes: 44 additions & 0 deletions tapdb/addrs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ import (
"github.com/btcsuite/btcd/wire"
"github.com/lightninglabs/lndclient"
"github.com/lightninglabs/taproot-assets/address"
"github.com/lightninglabs/taproot-assets/asset"
"github.com/lightninglabs/taproot-assets/internal/test"
"github.com/lightninglabs/taproot-assets/tapdb/sqlc"
"github.com/lightningnetwork/lnd/clock"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -644,3 +646,45 @@ func TestAddressEventQuery(t *testing.T) {
})
}
}

// TestScriptKeyKnownUpsert tests that we can insert a script key, then insert
// it again declared as known.
func TestScriptKeyKnownUpsert(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()

// Make a random script key that we'll use to insert into the database.
scriptKey := asset.RandScriptKey(t)
scriptKey.TweakedScriptKey = &asset.TweakedScriptKey{
RawKey: keychain.KeyDescriptor{
PubKey: asset.RandScriptKey(t).PubKey,
},
}

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

// We'll fetch the script key and confirm that it's not known.
dbScriptKey, err := addrBook.FetchScriptKey(ctx, scriptKey.PubKey)
require.NoError(t, err)
require.False(t, dbScriptKey.DeclaredKnown)

known = true

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

// We'll fetch the script key and confirm that it's known.
dbScriptKey, err = addrBook.FetchScriptKey(ctx, scriptKey.PubKey)
require.NoError(t, err)
require.True(t, dbScriptKey.DeclaredKnown)
}

0 comments on commit 2b288da

Please sign in to comment.