Skip to content

Commit a60f7aa

Browse files
committed
tapgarden: show asset group info in ListBatches
1 parent c2e1cfd commit a60f7aa

File tree

5 files changed

+318
-37
lines changed

5 files changed

+318
-37
lines changed

monitoring/garden_collector.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ func (a *gardenCollector) Collect(ch chan<- prometheus.Metric) {
7373
a.completedBatches.Set(0)
7474

7575
// Get the number of pending batches.
76-
batches, err := a.cfg.AssetMinter.ListBatches(nil)
76+
batches, err := a.cfg.AssetMinter.ListBatches(
77+
tapgarden.ListBatchesParams{},
78+
)
7779
if err != nil {
7880
log.Errorf("unable to list batches: %v", err)
7981
return

tapgarden/batch.go

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/btcsuite/btcd/txscript"
1111
"github.com/lightninglabs/taproot-assets/asset"
1212
"github.com/lightninglabs/taproot-assets/commitment"
13+
"github.com/lightninglabs/taproot-assets/fn"
1314
"github.com/lightninglabs/taproot-assets/proof"
1415
"github.com/lightninglabs/taproot-assets/tapscript"
1516
"github.com/lightninglabs/taproot-assets/tapsend"
@@ -75,6 +76,62 @@ type MintingBatch struct {
7576
taprootAssetScriptRoot []byte
7677
}
7778

79+
type VerboseBatch struct {
80+
// CreationTime is the time that this batch was created.
81+
CreationTime time.Time
82+
83+
// HeightHint is the recorded block height at time of creating this
84+
// batch. We use it to know where to start looking for the signed batch
85+
// transaction.
86+
HeightHint uint32
87+
88+
// batchState is the state of the batch.
89+
batchState atomic.Uint32
90+
91+
// BatchKey is the unique identifier for a batch.
92+
BatchKey keychain.KeyDescriptor
93+
94+
// Seedlings is the set of unsealed seedlings for this batch. This maps
95+
// an asset's name to the seedling itself.
96+
//
97+
// NOTE: This field is only set if the state is BatchStateFrozen or
98+
// BatchStatePending.
99+
Seedlings map[string]*UnsealedSeedling
100+
101+
// GenesisPacket is the funded genesis packet that may or may not be
102+
// fully signed. When broadcast, this will create all assets stored
103+
// within this batch.
104+
GenesisPacket *tapsend.FundedPsbt
105+
106+
// RootAssetCommitment is the root Taproot Asset commitment for all the
107+
// assets contained in this batch.
108+
//
109+
// NOTE: This field is only set if the state is beyond
110+
// BatchStateCommitted.
111+
RootAssetCommitment *commitment.TapCommitment
112+
113+
// AssetMetas maps the serialized script key of an asset to the meta
114+
// reveal for that asset, if it has one.
115+
AssetMetas AssetMetas
116+
117+
// mintingPubKey is the top-level Taproot output key that will be used
118+
// to commit to the Taproot Asset commitment above.
119+
mintingPubKey *btcec.PublicKey
120+
121+
// tapSibling is an optional root hash of a tapscript tree that will be
122+
// used with the taprootAssetScriptRoot to construct the mintingPubKey.
123+
tapSibling *chainhash.Hash
124+
125+
// taprootAssetScriptRoot is the root hash of the Taproot Asset
126+
// commitment. If this is nil, then the mintingPubKey will be as well.
127+
taprootAssetScriptRoot []byte
128+
}
129+
130+
type MinterBatch interface {
131+
*MintingBatch | *VerboseBatch
132+
State() BatchState
133+
}
134+
78135
// validateGroupAnchor checks if the group anchor for a seedling is valid.
79136
// A valid anchor must already be part of the batch and have emission enabled.
80137
func (m *MintingBatch) validateGroupAnchor(s *Seedling) error {
@@ -173,6 +230,84 @@ func (m *MintingBatch) UpdateTapSibling(sibling *chainhash.Hash) {
173230
m.tapSibling = sibling
174231
}
175232

233+
// IsFunded checks if the batch already has a funded genesis packet.
176234
func (m *MintingBatch) IsFunded() bool {
177235
return m.GenesisPacket != nil
178236
}
237+
238+
// HasSeedlings checks if the batch has any seedlings. A batch with no seedlings
239+
// cannot be sealed nor finalized.
240+
func (m *MintingBatch) HasSeedlings() bool {
241+
return len(m.Seedlings) != 0
242+
}
243+
244+
func (m *MintingBatch) ToVerbose() *VerboseBatch {
245+
newBatch := &VerboseBatch{
246+
CreationTime: m.CreationTime,
247+
HeightHint: m.HeightHint,
248+
BatchKey: m.BatchKey,
249+
GenesisPacket: m.GenesisPacket,
250+
RootAssetCommitment: m.RootAssetCommitment,
251+
AssetMetas: m.AssetMetas,
252+
mintingPubKey: m.mintingPubKey,
253+
tapSibling: m.tapSibling,
254+
taprootAssetScriptRoot: m.taprootAssetScriptRoot,
255+
}
256+
newBatch.batchState.Store(uint32(m.State()))
257+
seedlings := make(map[string]*UnsealedSeedling, len(m.Seedlings))
258+
toUnsealed := func(seedlingName string, seedling *Seedling) {
259+
seedlings[seedlingName] = &UnsealedSeedling{
260+
seedling,
261+
nil,
262+
}
263+
}
264+
fn.ForEachMapItem(m.Seedlings, toUnsealed)
265+
266+
newBatch.Seedlings = seedlings
267+
268+
return newBatch
269+
}
270+
271+
func (v *VerboseBatch) ToMintingBatch() *MintingBatch {
272+
newBatch := &MintingBatch{
273+
CreationTime: v.CreationTime,
274+
HeightHint: v.HeightHint,
275+
BatchKey: v.BatchKey,
276+
GenesisPacket: v.GenesisPacket,
277+
RootAssetCommitment: v.RootAssetCommitment,
278+
AssetMetas: v.AssetMetas,
279+
mintingPubKey: v.mintingPubKey,
280+
tapSibling: v.tapSibling,
281+
taprootAssetScriptRoot: v.taprootAssetScriptRoot,
282+
}
283+
newBatch.batchState.Store(uint32(v.State()))
284+
seedlings := make(map[string]*Seedling, len(v.Seedlings))
285+
toUnsealed := func(seedlingName string, seedling *UnsealedSeedling) {
286+
seedlings[seedlingName] = seedling.Seedling
287+
}
288+
fn.ForEachMapItem(v.Seedlings, toUnsealed)
289+
290+
newBatch.Seedlings = seedlings
291+
292+
return newBatch
293+
}
294+
295+
// State returns the private state of the batch.
296+
func (v *VerboseBatch) State() BatchState {
297+
currentBatchState := v.batchState.Load()
298+
299+
// Drop the error when converting the stored state to a BatchState, as
300+
// we verify the batch state before storing it.
301+
batchStateCopy, _ := NewBatchState(uint8(currentBatchState))
302+
return batchStateCopy
303+
}
304+
305+
// TapSibling returns the optional tapscript sibling for the batch, which is a
306+
// root hash of a tapscript tree.
307+
func (v *VerboseBatch) TapSibling() []byte {
308+
if v.tapSibling == nil {
309+
return nil
310+
}
311+
312+
return v.tapSibling.CloneBytes()
313+
}

tapgarden/interface.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ type Planter interface {
3535

3636
// ListBatches lists the set of batches submitted for minting, or the
3737
// details of a specific batch.
38-
ListBatches(batchKey *btcec.PublicKey) ([]*MintingBatch, error)
38+
ListBatches(params ListBatchesParams) ([]*VerboseBatch, error)
3939

4040
// CancelSeedling attempts to cancel the creation of a new asset
4141
// identified by its name. If the seedling has already progressed to a

0 commit comments

Comments
 (0)