Skip to content

Commit 28a5ccc

Browse files
committed
tapdb: update minting queries to set batch sibling
1 parent 8856f68 commit 28a5ccc

File tree

2 files changed

+106
-24
lines changed

2 files changed

+106
-24
lines changed

tapdb/asset_minting.go

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,21 @@ func (a *AssetMintingStore) CommitMintingBatch(ctx context.Context,
312312
"batch: %w", err)
313313
}
314314

315+
// With the batch key and batch itself inserted, we can insert
316+
// the batch tapscript sibling if present.
317+
newBatchSibling := newBatch.TapSibling()
318+
if newBatchSibling != nil {
319+
tapSibling := BatchTapSiblingUpdate{
320+
RawKey: rawBatchKey,
321+
TapscriptSibling: newBatchSibling,
322+
}
323+
err = q.BindMintingBatchWithTapSibling(ctx, tapSibling)
324+
if err != nil {
325+
return fmt.Errorf("unable to insert batch "+
326+
"sibling: %w", err)
327+
}
328+
}
329+
315330
// Now that our minting batch is in place, which references the
316331
// internal key inserted above, we can create the set of new
317332
// seedlings. We insert group anchors before other assets.
@@ -862,6 +877,15 @@ func marshalMintingBatch(ctx context.Context, q PendingAssetStore,
862877

863878
batch.UpdateState(batchState)
864879

880+
if len(dbBatch.TapscriptSibling) != 0 {
881+
batchSibling, err := chainhash.NewHash(dbBatch.TapscriptSibling)
882+
if err != nil {
883+
return nil, err
884+
}
885+
886+
batch.UpdateTapSibling(batchSibling)
887+
}
888+
865889
if dbBatch.MintingTxPsbt != nil {
866890
genesisPkt, err := psbt.NewFromRawBytes(
867891
bytes.NewReader(dbBatch.MintingTxPsbt), false,
@@ -929,6 +953,22 @@ func (a *AssetMintingStore) UpdateBatchState(ctx context.Context,
929953
})
930954
}
931955

956+
// CommitBatchTapSibling updates the tapscript sibling of a batch based on the
957+
// batch key.
958+
func (a *AssetMintingStore) CommitBatchTapSibling(ctx context.Context,
959+
batchKey *btcec.PublicKey, batchSibling *chainhash.Hash) error {
960+
961+
siblingUpdate := BatchTapSiblingUpdate{
962+
RawKey: batchKey.SerializeCompressed(),
963+
TapscriptSibling: batchSibling[:],
964+
}
965+
966+
var writeTxOpts AssetStoreTxOptions
967+
return a.db.ExecTx(ctx, &writeTxOpts, func(q PendingAssetStore) error {
968+
return q.BindMintingBatchWithTapSibling(ctx, siblingUpdate)
969+
})
970+
}
971+
932972
// encodeOutpoint encodes the outpoint point in Bitcoin wire format, returning
933973
// the final result.
934974
func encodeOutpoint(outPoint wire.OutPoint) ([]byte, error) {
@@ -1019,7 +1059,8 @@ func (a *AssetMintingStore) AddSproutsToBatch(ctx context.Context,
10191059
// root manually?
10201060
func (a *AssetMintingStore) CommitSignedGenesisTx(ctx context.Context,
10211061
batchKey *btcec.PublicKey, genesisPkt *tapgarden.FundedPsbt,
1022-
anchorOutputIndex uint32, merkleRoot []byte) error {
1062+
anchorOutputIndex uint32, merkleRoot, tapTreeRoot []byte,
1063+
tapSibling []byte) error {
10231064

10241065
// The managed UTXO we'll insert only contains the raw tx of the
10251066
// genesis packet, so we'll extract that now.
@@ -1087,13 +1128,11 @@ func (a *AssetMintingStore) CommitSignedGenesisTx(ctx context.Context,
10871128
// batch, we'll create a new managed UTXO for this batch as
10881129
// this is where all the assets will be anchored within.
10891130
utxoID, err := q.UpsertManagedUTXO(ctx, RawManagedUTXO{
1090-
RawKey: rawBatchKey,
1091-
Outpoint: anchorOutpoint,
1092-
AmtSats: anchorOutput.Value,
1093-
// When minting, we never have a tapscript sibling, so
1094-
// the TaprootAssetRoot root is always equal to the
1095-
// merkle root.
1096-
TaprootAssetRoot: merkleRoot,
1131+
RawKey: rawBatchKey,
1132+
Outpoint: anchorOutpoint,
1133+
AmtSats: anchorOutput.Value,
1134+
TaprootAssetRoot: tapTreeRoot,
1135+
TapscriptSibling: tapSibling,
10971136
MerkleRoot: merkleRoot,
10981137
TxnID: chainTXID,
10991138
})

tapdb/asset_minting_test.go

Lines changed: 59 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,18 @@ func assertBatchState(t *testing.T, batch *tapgarden.MintingBatch,
6767
require.Equal(t, state, batch.State())
6868
}
6969

70+
func assertBatchSibling(t *testing.T, batch *tapgarden.MintingBatch,
71+
sibling chainhash.Hash) {
72+
73+
require.Equal(t, sibling[:], batch.TapSibling())
74+
}
75+
7076
func assertBatchEqual(t *testing.T, a, b *tapgarden.MintingBatch) {
7177
t.Helper()
7278

7379
require.Equal(t, a.CreationTime.Unix(), b.CreationTime.Unix())
7480
require.Equal(t, a.State(), b.State())
81+
require.Equal(t, a.TapSibling(), b.TapSibling())
7582
require.Equal(t, a.BatchKey, b.BatchKey)
7683
require.Equal(t, a.Seedlings, b.Seedlings)
7784
require.Equal(t, a.GenesisPacket, b.GenesisPacket)
@@ -329,6 +336,22 @@ func addRandGroupToBatch(t *testing.T, store *AssetMintingStore,
329336
return genesisAmt, seedlingGroups, group
330337
}
331338

339+
// addRandSiblingToBatch generates a random hash and adds it to the given batch.
340+
func addRandSiblingToBatch(t *testing.T, batch *tapgarden.MintingBatch) (
341+
commitment.TapscriptPreimage, chainhash.Hash) {
342+
343+
tapSiblingSingleLeaf := test.RandTapLeaf(nil)
344+
siblingPreimage, err := commitment.NewPreimageFromLeaf(
345+
tapSiblingSingleLeaf,
346+
)
347+
require.NoError(t, err)
348+
tapSibling, err := siblingPreimage.TapHash()
349+
require.NoError(t, err)
350+
batch.UpdateTapSibling(tapSibling)
351+
352+
return *siblingPreimage, *tapSibling
353+
}
354+
332355
// addMultiAssetGroupToBatch selects a random seedling pair, where neither
333356
// seedling is being issued into an existing group, and creates a multi-asset
334357
// group. Specifically, one seedling will have emission enabled, and the other
@@ -384,6 +407,7 @@ func TestCommitMintingBatchSeedlings(t *testing.T) {
384407
// be a reissuance into a specific group.
385408
mintingBatch := tapgarden.RandSeedlingMintingBatch(t, numSeedlings)
386409
addRandGroupToBatch(t, assetStore, ctx, mintingBatch.Seedlings)
410+
_, randSiblingHash := addRandSiblingToBatch(t, mintingBatch)
387411
err := assetStore.CommitMintingBatch(ctx, mintingBatch)
388412
require.NoError(t, err)
389413

@@ -394,6 +418,7 @@ func TestCommitMintingBatchSeedlings(t *testing.T) {
394418
mintingBatches := noError1(t, assetStore.FetchNonFinalBatches, ctx)
395419
assertSeedlingBatchLen(t, mintingBatches, 1, numSeedlings)
396420
assertBatchEqual(t, mintingBatch, mintingBatches[0])
421+
assertBatchSibling(t, mintingBatch, randSiblingHash)
397422

398423
mintingBatchKeyed, err := assetStore.FetchMintingBatch(ctx, batchKey)
399424
require.NoError(t, err)
@@ -740,13 +765,16 @@ func TestAddSproutsToBatch(t *testing.T) {
740765
}
741766

742767
type randAssetCtx struct {
743-
batchKey *btcec.PublicKey
744-
groupKey *btcec.PublicKey
745-
groupGenAmt uint64
746-
genesisPkt *tapgarden.FundedPsbt
747-
scriptRoot []byte
748-
assetRoot *commitment.TapCommitment
749-
mintingBatch *tapgarden.MintingBatch
768+
batchKey *btcec.PublicKey
769+
groupKey *btcec.PublicKey
770+
groupGenAmt uint64
771+
genesisPkt *tapgarden.FundedPsbt
772+
assetRoot *commitment.TapCommitment
773+
merkleRoot []byte
774+
scriptRoot []byte
775+
tapSiblingBytes []byte
776+
tapSiblingHash chainhash.Hash
777+
mintingBatch *tapgarden.MintingBatch
750778
}
751779

752780
func addRandAssets(t *testing.T, ctx context.Context,
@@ -756,6 +784,7 @@ func addRandAssets(t *testing.T, ctx context.Context,
756784
genAmt, seedlingGroups, group := addRandGroupToBatch(
757785
t, assetStore, ctx, mintingBatch.Seedlings,
758786
)
787+
randSibling, randSiblingHash := addRandSiblingToBatch(t, mintingBatch)
759788
batchKey := mintingBatch.BatchKey.PubKey
760789
require.NoError(t, assetStore.CommitMintingBatch(ctx, mintingBatch))
761790

@@ -769,16 +798,24 @@ func addRandAssets(t *testing.T, ctx context.Context,
769798
ctx, batchKey, genesisPacket, assetRoot,
770799
))
771800

801+
merkleRoot := assetRoot.TapscriptRoot(&randSiblingHash)
772802
scriptRoot := assetRoot.TapscriptRoot(nil)
803+
siblingBytes, _, err := commitment.MaybeEncodeTapscriptPreimage(
804+
&randSibling,
805+
)
806+
require.NoError(t, err)
773807

774808
return randAssetCtx{
775-
batchKey: batchKey,
776-
groupKey: &group.GroupKey.GroupPubKey,
777-
groupGenAmt: genAmt,
778-
genesisPkt: genesisPacket,
779-
scriptRoot: scriptRoot[:],
780-
assetRoot: assetRoot,
781-
mintingBatch: mintingBatch,
809+
batchKey: batchKey,
810+
groupKey: &group.GroupKey.GroupPubKey,
811+
groupGenAmt: genAmt,
812+
genesisPkt: genesisPacket,
813+
assetRoot: assetRoot,
814+
merkleRoot: merkleRoot[:],
815+
scriptRoot: scriptRoot[:],
816+
tapSiblingBytes: siblingBytes,
817+
tapSiblingHash: randSiblingHash,
818+
mintingBatch: mintingBatch,
782819
}
783820
}
784821

@@ -812,7 +849,8 @@ func TestCommitBatchChainActions(t *testing.T) {
812849
// alongside any managed UTXOs.
813850
require.NoError(t, assetStore.CommitSignedGenesisTx(
814851
ctx, randAssetCtx.batchKey, randAssetCtx.genesisPkt, 2,
815-
randAssetCtx.scriptRoot,
852+
randAssetCtx.merkleRoot, randAssetCtx.scriptRoot,
853+
randAssetCtx.tapSiblingBytes,
816854
))
817855

818856
// The batch updated above should be found, with the batch state
@@ -825,6 +863,7 @@ func TestCommitBatchChainActions(t *testing.T) {
825863
assertPsbtEqual(
826864
t, randAssetCtx.genesisPkt, mintingBatches[0].GenesisPacket,
827865
)
866+
assertBatchSibling(t, mintingBatches[0], randAssetCtx.tapSiblingHash)
828867

829868
var rawTxBytes bytes.Buffer
830869
rawGenTx, err := psbt.Extract(randAssetCtx.genesisPkt.Pkt)
@@ -849,7 +888,11 @@ func TestCommitBatchChainActions(t *testing.T) {
849888
TxnID: sqlInt64(dbGenTx.TxnID),
850889
})
851890
require.NoError(t, err)
852-
require.Equal(t, randAssetCtx.scriptRoot, managedUTXO.MerkleRoot)
891+
require.Equal(t, randAssetCtx.merkleRoot, managedUTXO.MerkleRoot)
892+
require.Equal(t, randAssetCtx.scriptRoot, managedUTXO.TaprootAssetRoot)
893+
require.Equal(
894+
t, randAssetCtx.tapSiblingBytes, managedUTXO.TapscriptSibling,
895+
)
853896

854897
// Next, we'll confirm that all the assets inserted previously now are
855898
// able to be queried according to the anchor UTXO primary key.

0 commit comments

Comments
 (0)