-
Notifications
You must be signed in to change notification settings - Fork 131
[tapdb]: add script key type enum, run Golang based post migration checks #1198
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
guggero
wants to merge
17
commits into
main
Choose a base branch
from
script-key-migrations
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
1059442
tapdb: fix comments and args
guggero e655078
tapdb: use embeddings for script key
guggero 0d33b28
tapdb: add script_keys.key_type column
guggero cda1bb3
multi: add type to script key
guggero 48b13a6
tapfreighter: set type for burn/tombstone keys correctly
guggero a72e74a
tapcfg+tapdb: move and export DatabaseBackend
guggero ea5bfbe
tapdb: turn dbAssetsToChainAssets into function
guggero 642c0e0
tapdb: add postmigration checks
guggero 914f109
taprpc: re-compile after update of protobuf library
guggero f8f67b1
taprpc+rpcserver: allow user to set script key type
guggero 8c230eb
multi: remove now unused DeclaredKnown field
guggero e3903d0
taprpc: add script key type to asset
guggero e1d3fe3
multi: add script key type filter to queries
guggero fa1a94e
multi: turn coin selection type into script key filter
guggero 946cdf6
tapdb: change script key exclusion mechanism
guggero a3c79c2
itest: query for all asset script types
guggero 450bb48
itest: add new balance assertions to multiple tests
guggero File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -108,6 +108,50 @@ const ( | |
EncodeSegwit | ||
) | ||
|
||
// ScriptKeyType denotes the type of script key used for an asset. This type is | ||
// serialized to the database, so we don't use iota for the values to ensure | ||
// they don't change by accident. | ||
type ScriptKeyType uint8 | ||
|
||
const ( | ||
// ScriptKeyUnknown is the default script key type used for assets that | ||
// we don't know the type of. This should only be stored for assets | ||
// where we don't know the internal key of the script key (e.g. for | ||
// imported proofs). | ||
ScriptKeyUnknown ScriptKeyType = 0 | ||
|
||
// ScriptKeyBip86 is the script key type used for assets that use the | ||
// BIP86 style tweak (e.g. an empty tweak). | ||
ScriptKeyBip86 ScriptKeyType = 1 | ||
|
||
// ScriptKeyScriptPathExternal is the script key type used for assets | ||
// that use a script path that is defined by an external application. | ||
// Keys with script paths are normally not shown in asset balances and | ||
// by default aren't used for coin selection unless specifically | ||
// requested. | ||
ScriptKeyScriptPathExternal ScriptKeyType = 2 | ||
|
||
// ScriptKeyBurn is the script key type used for assets that are burned | ||
// and not spendable. | ||
ScriptKeyBurn ScriptKeyType = 3 | ||
|
||
// ScriptKeyTombstone is the script key type used for assets that are | ||
// not spendable and have been marked as tombstones. This is only the | ||
// case for zero-value assets that result from a non-interactive (TAP | ||
// address) send where no change was left over. The script key used for | ||
// this is a NUMS key that is not spendable. | ||
ScriptKeyTombstone ScriptKeyType = 4 | ||
|
||
// ScriptKeyScriptPathChannel is the script key type used for assets | ||
// that use a script path that is somehow related to Taproot Asset | ||
// Channels. That means the script key is either a funding key | ||
// (OP_TRUE), a commitment output key (to_local, to_remote, htlc), or a | ||
// HTLC second-level transaction output key. | ||
// Keys related to channels are not shown in asset balances (unless | ||
// specifically requested) and are _never_ used for coin selection. | ||
ScriptKeyScriptPathChannel ScriptKeyType = 5 | ||
) | ||
|
||
var ( | ||
// ZeroPrevID is the blank prev ID used for genesis assets and also | ||
// asset split leaves. | ||
|
@@ -993,14 +1037,8 @@ type TweakedScriptKey struct { | |
// public key. If this is nil, then a BIP-0086 tweak is assumed. | ||
Tweak []byte | ||
|
||
// DeclaredKnown indicates that this script key has been explicitly | ||
// declared as being important to the local wallet, even if it might not | ||
// be fully known to the local wallet. This could perhaps also be named | ||
// "imported", though that might imply that the corresponding private | ||
// key was also somehow imported and available. The only relevance this | ||
// flag has is that assets with a declared key are shown in the asset | ||
// list/balance. | ||
DeclaredKnown bool | ||
// Type is the type of script key that is being used. | ||
Type ScriptKeyType | ||
} | ||
|
||
// IsEqual returns true is this tweaked script key is exactly equivalent to the | ||
|
@@ -1071,12 +1109,9 @@ func (s *ScriptKey) IsEqual(otherScriptKey *ScriptKey) bool { | |
// the local wallet or was explicitly declared to be known by using the | ||
// DeclareScriptKey RPC. Knowing the key conceptually means the key belongs to | ||
// the local wallet or is at least known by a software that operates on the | ||
// local wallet. The DeclaredAsKnown flag is never serialized in proofs, so this | ||
// is never explicitly set for keys foreign to the local wallet. Therefore, if | ||
// this method returns true for a script key, it means the asset with the script | ||
// key will be shown in the wallet balance. | ||
// local wallet. | ||
func (s *ScriptKey) DeclaredAsKnown() bool { | ||
return s.TweakedScriptKey != nil && s.TweakedScriptKey.DeclaredKnown | ||
return s.TweakedScriptKey != nil && s.Type != ScriptKeyUnknown | ||
} | ||
|
||
// HasScriptPath returns true if we know the internals of the script key and | ||
|
@@ -1086,15 +1121,49 @@ func (s *ScriptKey) HasScriptPath() bool { | |
return s.TweakedScriptKey != nil && len(s.TweakedScriptKey.Tweak) > 0 | ||
} | ||
|
||
// GuessType tries to guess the type of the script key based on the information | ||
// available. | ||
func (s *ScriptKey) GuessType() ScriptKeyType { | ||
Comment on lines
+1124
to
+1126
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think "guess" is misleading here. This method appears to classify decisively whenever possible, but it never seems to make a prediction when uncertainty would be warranted. I suggest we rename to |
||
// If we have an explicit script key type set, we can return that. | ||
if s.TweakedScriptKey != nil && | ||
s.TweakedScriptKey.Type != ScriptKeyUnknown { | ||
|
||
return s.TweakedScriptKey.Type | ||
} | ||
|
||
// If there is a known tweak, then we know that this is a script path | ||
// key. We never return the channel type, since those keys should always | ||
// be declared properly, and we never should need to guess their type. | ||
if s.HasScriptPath() { | ||
return ScriptKeyScriptPathExternal | ||
} | ||
|
||
// Is it the known NUMS key? Then this is a tombstone output. | ||
if s.PubKey != nil && s.PubKey.IsEqual(NUMSPubKey) { | ||
return ScriptKeyTombstone | ||
} | ||
|
||
// Do we know the internal key? Then we can check whether it is a | ||
// BIP-0086 key. | ||
if s.PubKey != nil && s.TweakedScriptKey != nil && | ||
s.TweakedScriptKey.RawKey.PubKey != nil { | ||
|
||
bip86 := NewScriptKeyBip86(s.TweakedScriptKey.RawKey) | ||
if bip86.PubKey.IsEqual(s.PubKey) { | ||
return ScriptKeyBip86 | ||
} | ||
} | ||
|
||
return ScriptKeyUnknown | ||
} | ||
|
||
// NewScriptKey constructs a ScriptKey with only the publicly available | ||
// information. This resulting key may or may not have a tweak applied to it. | ||
func NewScriptKey(key *btcec.PublicKey) ScriptKey { | ||
// Since we'll never query lnd for a tweaked key, it doesn't matter if | ||
// we lose the parity information here. And this will only ever be | ||
// serialized on chain in a 32-bit representation as well. | ||
key, _ = schnorr.ParsePubKey( | ||
schnorr.SerializePubKey(key), | ||
) | ||
key, _ = schnorr.ParsePubKey(schnorr.SerializePubKey(key)) | ||
return ScriptKey{ | ||
PubKey: key, | ||
} | ||
|
@@ -1106,9 +1175,7 @@ func NewScriptKey(key *btcec.PublicKey) ScriptKey { | |
func NewScriptKeyBip86(rawKey keychain.KeyDescriptor) ScriptKey { | ||
// Tweak the script key BIP-0086 style (such that we only commit to the | ||
// internal key when signing). | ||
tweakedPubKey := txscript.ComputeTaprootKeyNoScript( | ||
rawKey.PubKey, | ||
) | ||
tweakedPubKey := txscript.ComputeTaprootKeyNoScript(rawKey.PubKey) | ||
|
||
// Since we'll never query lnd for a tweaked key, it doesn't matter if | ||
// we lose the parity information here. And this will only ever be | ||
|
@@ -1121,6 +1188,7 @@ func NewScriptKeyBip86(rawKey keychain.KeyDescriptor) ScriptKey { | |
PubKey: tweakedPubKey, | ||
TweakedScriptKey: &TweakedScriptKey{ | ||
RawKey: rawKey, | ||
Type: ScriptKeyBip86, | ||
}, | ||
} | ||
} | ||
|
@@ -1507,7 +1575,7 @@ func (a *Asset) Copy() *Asset { | |
|
||
if a.ScriptKey.TweakedScriptKey != nil { | ||
assetCopy.ScriptKey.TweakedScriptKey = &TweakedScriptKey{ | ||
DeclaredKnown: a.ScriptKey.DeclaredKnown, | ||
Type: a.ScriptKey.Type, | ||
} | ||
assetCopy.ScriptKey.RawKey = a.ScriptKey.RawKey | ||
|
||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe
ScriptKeyUnknown
should be renamed toScriptKeyTypeUnknown
, because the type of script key is the thing that is unknown, even for a tracked script key. Have i understood that correctly?