@@ -231,6 +231,102 @@ func TestGroupKeyIsEqual(t *testing.T) {
231231 }
232232}
233233
234+ // TestGenesisAssetClassification tests that the multiple forms of genesis asset
235+ // are recognized correctly.
236+ func TestGenesisAssetClassification (t * testing.T ) {
237+ t .Parallel ()
238+
239+ baseGen := RandGenesis (t , Normal )
240+ baseScriptKey := RandScriptKey (t )
241+ baseAsset := RandAssetWithValues (t , baseGen , nil , baseScriptKey )
242+ assetValidGroup := RandAsset (t , Collectible )
243+ assetNeedsWitness := baseAsset .Copy ()
244+ assetNeedsWitness .GroupKey = & GroupKey {
245+ GroupPubKey : * test .RandPubKey (t ),
246+ }
247+ nonGenAsset := baseAsset .Copy ()
248+ nonGenAsset .PrevWitnesses = []Witness {{
249+ PrevID : & PrevID {
250+ OutPoint : wire.OutPoint {
251+ Hash : hashBytes1 ,
252+ Index : 1 ,
253+ },
254+ ID : hashBytes1 ,
255+ ScriptKey : ToSerialized (pubKey ),
256+ },
257+ TxWitness : sigWitness ,
258+ SplitCommitment : nil ,
259+ }}
260+ groupMemberNonGen := nonGenAsset .Copy ()
261+ groupMemberNonGen .GroupKey = & GroupKey {
262+ GroupPubKey : * test .RandPubKey (t ),
263+ }
264+ splitAsset := nonGenAsset .Copy ()
265+ splitAsset .PrevWitnesses [0 ].TxWitness = nil
266+ splitAsset .PrevWitnesses [0 ].SplitCommitment = & SplitCommitment {}
267+
268+ tests := []struct {
269+ name string
270+ genAsset * Asset
271+ isGenesis , needsWitness , hasWitness bool
272+ }{
273+ {
274+ name : "group anchor with witness" ,
275+ genAsset : assetValidGroup ,
276+ isGenesis : false ,
277+ needsWitness : false ,
278+ hasWitness : true ,
279+ },
280+ {
281+ name : "ungrouped genesis asset" ,
282+ genAsset : baseAsset ,
283+ isGenesis : true ,
284+ needsWitness : false ,
285+ hasWitness : false ,
286+ },
287+ {
288+ name : "group anchor without witness" ,
289+ genAsset : assetNeedsWitness ,
290+ isGenesis : true ,
291+ needsWitness : true ,
292+ hasWitness : false ,
293+ },
294+ {
295+ name : "non-genesis asset" ,
296+ genAsset : nonGenAsset ,
297+ isGenesis : false ,
298+ needsWitness : false ,
299+ hasWitness : false ,
300+ },
301+ {
302+ name : "non-genesis grouped asset" ,
303+ genAsset : groupMemberNonGen ,
304+ isGenesis : false ,
305+ needsWitness : false ,
306+ hasWitness : false ,
307+ },
308+ {
309+ name : "split asset" ,
310+ genAsset : splitAsset ,
311+ isGenesis : false ,
312+ needsWitness : false ,
313+ hasWitness : false ,
314+ },
315+ }
316+
317+ for _ , testCase := range tests {
318+ testCase := testCase
319+ a := testCase .genAsset
320+
321+ hasGenWitness := a .HasGenesisWitness ()
322+ require .Equal (t , testCase .isGenesis , hasGenWitness )
323+ needsGroupWitness := a .NeedsGenesisWitnessForGroup ()
324+ require .Equal (t , testCase .needsWitness , needsGroupWitness )
325+ hasGroupWitness := a .HasGenesisWitnessForGroup ()
326+ require .Equal (t , testCase .hasWitness , hasGroupWitness )
327+ }
328+ }
329+
234330// TestValidateAssetName tests that asset names are validated correctly.
235331func TestValidateAssetName (t * testing.T ) {
236332 t .Parallel ()
@@ -510,11 +606,12 @@ func TestAssetGroupKey(t *testing.T) {
510606 t .Parallel ()
511607
512608 privKey , err := btcec .NewPrivateKey ()
609+ groupPub := privKey .PubKey ()
513610 require .NoError (t , err )
514611 privKeyCopy := btcec .PrivKeyFromScalar (& privKey .Key )
515612 genSigner := NewMockGenesisSigner (privKeyCopy )
516613 genBuilder := MockGroupTxBuilder {}
517- fakeKeyDesc := test .PubToKeyDesc (privKeyCopy . PubKey () )
614+ fakeKeyDesc := test .PubToKeyDesc (groupPub )
518615 fakeScriptKey := NewScriptKeyBip86 (fakeKeyDesc )
519616
520617 g := Genesis {
@@ -544,6 +641,79 @@ func TestAssetGroupKey(t *testing.T) {
544641 t , schnorr .SerializePubKey (tweakedKey .PubKey ()),
545642 schnorr .SerializePubKey (& keyGroup .GroupPubKey ),
546643 )
644+
645+ // Group key tweaking should fail when given invalid tweaks.
646+ badTweak := test .RandBytes (33 )
647+ _ , err = GroupPubKey (groupPub , badTweak , badTweak )
648+ require .Error (t , err )
649+
650+ _ , err = GroupPubKey (groupPub , groupTweak [:], badTweak )
651+ require .Error (t , err )
652+ }
653+
654+ // TestDeriveGroupKey tests that group key derivation fails for assets that are
655+ // not eligible to be group anchors.
656+ func TestDeriveGroupKey (t * testing.T ) {
657+ t .Parallel ()
658+
659+ groupPriv := test .RandPrivKey (t )
660+ groupPub := groupPriv .PubKey ()
661+ groupKeyDesc := test .PubToKeyDesc (groupPub )
662+ genSigner := NewMockGenesisSigner (groupPriv )
663+ genBuilder := MockGroupTxBuilder {}
664+
665+ baseGen := RandGenesis (t , Normal )
666+ collectGen := RandGenesis (t , Collectible )
667+ baseScriptKey := RandScriptKey (t )
668+ protoAsset := RandAssetWithValues (t , baseGen , nil , baseScriptKey )
669+ nonGenProtoAsset := protoAsset .Copy ()
670+ nonGenProtoAsset .PrevWitnesses = []Witness {{
671+ PrevID : & PrevID {
672+ OutPoint : wire.OutPoint {
673+ Hash : hashBytes1 ,
674+ Index : 1 ,
675+ },
676+ ID : hashBytes1 ,
677+ ScriptKey : ToSerialized (pubKey ),
678+ },
679+ TxWitness : sigWitness ,
680+ SplitCommitment : nil ,
681+ }}
682+ groupedProtoAsset := protoAsset .Copy ()
683+ groupedProtoAsset .GroupKey = & GroupKey {
684+ GroupPubKey : * groupPub ,
685+ }
686+
687+ // A prototype asset is required for building the genesis virtual TX.
688+ _ , err := DeriveGroupKey (
689+ genSigner , & genBuilder , groupKeyDesc , baseGen , nil ,
690+ )
691+ require .Error (t , err )
692+
693+ // The prototype asset must have a genesis witness.
694+ _ , err = DeriveGroupKey (
695+ genSigner , & genBuilder , groupKeyDesc , baseGen , nonGenProtoAsset ,
696+ )
697+ require .Error (t , err )
698+
699+ // The prototype asset must not have a group key set.
700+ _ , err = DeriveGroupKey (
701+ genSigner , & genBuilder , groupKeyDesc , baseGen , groupedProtoAsset ,
702+ )
703+ require .Error (t , err )
704+
705+ // The anchor genesis used for signing must have the same asset type
706+ // as the prototype asset being signed.
707+ _ , err = DeriveGroupKey (
708+ genSigner , & genBuilder , groupKeyDesc , collectGen , protoAsset ,
709+ )
710+ require .Error (t , err )
711+
712+ groupKey , err := DeriveGroupKey (
713+ genSigner , & genBuilder , groupKeyDesc , baseGen , protoAsset ,
714+ )
715+ require .NoError (t , err )
716+ require .NotNil (t , groupKey )
547717}
548718
549719// TestAssetWitness tests that the asset group witness can be serialized and
0 commit comments