Skip to content

Commit

Permalink
Merge pull request #1324 from lightninglabs/small-minting-cleanup
Browse files Browse the repository at this point in the history
Cleanup Asset Minting Code in Preparation for Universe Commitments
  • Loading branch information
ffranr authored Jan 27, 2025
2 parents fa26891 + 01eb2f6 commit 6c73a87
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 15 deletions.
2 changes: 1 addition & 1 deletion rpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,7 @@ func (r *rpcServer) MintAsset(ctx context.Context,
}

rpcsLog.Infof("[MintAsset]: version=%v, type=%v, name=%v, amt=%v, "+
"issuance=%v", seedling.AssetVersion, seedling.AssetType,
"enable_emission=%v", seedling.AssetVersion, seedling.AssetType,
seedling.AssetName, seedling.Amount, seedling.EnableEmission)

if scriptKey != nil {
Expand Down
4 changes: 4 additions & 0 deletions tapgarden/batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ func (m *MintingBatch) Copy() *MintingBatch {
// validateGroupAnchor checks if the group anchor for a seedling is valid.
// A valid anchor must already be part of the batch and have emission enabled.
func (m *MintingBatch) validateGroupAnchor(s *Seedling) error {
if s.GroupAnchor == nil {
return fmt.Errorf("group anchor unspecified")
}

anchor, ok := m.Seedlings[*s.GroupAnchor]

if anchor == nil || !ok {
Expand Down
22 changes: 15 additions & 7 deletions tapgarden/caretaker.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ const (
// BatchCaretakerConfig houses all the items that the BatchCaretaker needs to
// carry out its duties.
type BatchCaretakerConfig struct {
// Batch is the minting batch that this caretaker is responsible for?
// Batch is the minting batch that this caretaker is responsible for.
Batch *MintingBatch

// BatchFeeRate is an optional manually-set feerate specified when
// BatchFeeRate is an optional manually-set fee rate specified when
// finalizing a batch.
BatchFeeRate *chainfee.SatPerKWeight

Expand Down Expand Up @@ -414,16 +414,20 @@ func (b *BatchCaretaker) assetCultivator() {

// extractAnchorOutputIndex extracts the anchor output index from a funded
// genesis packet.
func extractAnchorOutputIndex(genesisPkt *tapsend.FundedPsbt) uint32 {
func extractAnchorOutputIndex(genesisPkt *tapsend.FundedPsbt) (uint32, error) {
if len(genesisPkt.Pkt.UnsignedTx.TxOut) != 2 {
return 0, fmt.Errorf("funded genesis packet has unexpected "+
"number of outputs, expected 2 (txout_len=%d)",
len(genesisPkt.Pkt.UnsignedTx.TxOut))
}

anchorOutputIndex := uint32(0)

// TODO(jhb): Does funding guarantee that minting TXs always have
// exactly two outputs? If not this func should be fallible.
if genesisPkt.ChangeOutputIndex == 0 {
anchorOutputIndex = 1
}

return anchorOutputIndex
return anchorOutputIndex, nil
}

// extractGenesisOutpoint extracts the genesis point (the first input from the
Expand Down Expand Up @@ -614,9 +618,13 @@ func (b *BatchCaretaker) stateStep(currentState BatchState) (BatchState, error)
// and vice versa.
// TODO(jhb): return the anchor index instead of change? or both
// so this works for N outputs
b.anchorOutputIndex = extractAnchorOutputIndex(
b.anchorOutputIndex, err = extractAnchorOutputIndex(
b.cfg.Batch.GenesisPacket,
)
if err != nil {
return 0, err
}

genesisPoint := extractGenesisOutpoint(genesisTxPkt.UnsignedTx)

// First, we'll turn all the seedlings into actual taproot assets.
Expand Down
29 changes: 22 additions & 7 deletions tapgarden/planter.go
Original file line number Diff line number Diff line change
Expand Up @@ -1032,7 +1032,11 @@ func fetchFinalizedBatch(ctx context.Context, batchStore MintingStore,

// Collect genesis TX information from the batch to build the proof
// locators.
anchorOutputIndex := extractAnchorOutputIndex(batch.GenesisPacket)
anchorOutputIndex, err := extractAnchorOutputIndex(batch.GenesisPacket)
if err != nil {
return nil, err
}

signedTx, err := psbt.Extract(batch.GenesisPacket.Pkt)
if err != nil {
return nil, err
Expand Down Expand Up @@ -1268,9 +1272,13 @@ func newVerboseBatch(currentBatch *MintingBatch,

// Before we can build the group key requests for each seedling, we must
// fetch the genesis point and anchor index for the batch.
anchorOutputIndex := extractAnchorOutputIndex(
anchorOutputIndex, err := extractAnchorOutputIndex(
currentBatch.GenesisPacket,
)
if err != nil {
return nil, err
}

genesisPoint := extractGenesisOutpoint(
currentBatch.GenesisPacket.Pkt.UnsignedTx,
)
Expand Down Expand Up @@ -1437,6 +1445,10 @@ func (c *ChainPlanter) gardener() {
// After some basic validation, prepare the asset
// seedling (soon to be a sprout) by committing it to
// disk as part of the latest batch.
//
// This method will also include the seedling in any
// existing pending batch or create a new pending batch
// if necessary.
ctx, cancel := c.WithCtxQuit()
err := c.prepAssetSeedling(ctx, req)
cancel()
Expand Down Expand Up @@ -1843,9 +1855,13 @@ func (c *ChainPlanter) sealBatch(ctx context.Context, params SealParams,

// Before we can build the group key requests for each seedling, we must
// fetch the genesis point and anchor index for the batch.
anchorOutputIndex := extractAnchorOutputIndex(
anchorOutputIndex, err := extractAnchorOutputIndex(
workingBatch.GenesisPacket,
)
if err != nil {
return nil, err
}

genesisPoint := extractGenesisOutpoint(
workingBatch.GenesisPacket.Pkt.UnsignedTx,
)
Expand Down Expand Up @@ -2136,8 +2152,8 @@ func (c *ChainPlanter) finalizeBatch(params FinalizeParams) (*BatchCaretaker,
return caretaker, nil
}

// PendingBatch returns the current pending batch. If there's no pending batch,
// then an error is returned.
// PendingBatch returns the current pending batch, or nil if no batch is
// pending.
func (c *ChainPlanter) PendingBatch() (*MintingBatch, error) {
req := newStateReq[*MintingBatch](reqTypePendingBatch)

Expand Down Expand Up @@ -2223,8 +2239,7 @@ func (c *ChainPlanter) CancelBatch() (*btcec.PublicKey, error) {
}

// prepAssetSeedling performs some basic validation for the Seedling, then
// either adds it to an existing pending batch or creates a new batch for it. A
// bool indicating if a new batch should immediately be created is returned.
// either adds it to an existing pending batch or creates a new batch for it.
func (c *ChainPlanter) prepAssetSeedling(ctx context.Context,
req *Seedling) error {

Expand Down
6 changes: 6 additions & 0 deletions tapgarden/planter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1658,6 +1658,12 @@ func testFundSealBeforeFinalize(t *mintingTestHarness) {
// harness.
t.refreshChainPlanter()

// A pending batch should not exist yet. Therefore, `PendingBatch`
// should return nil and no error.
batch, err := t.planter.PendingBatch()
require.Nil(t, batch)
require.NoError(t, err)

var (
wg sync.WaitGroup
respChan = make(chan *FundBatchResp, 1)
Expand Down

0 comments on commit 6c73a87

Please sign in to comment.