From 1c8dda001307d2942035255ef8877057a61ec651 Mon Sep 17 00:00:00 2001 From: Jonathan Harvey-Buschel Date: Fri, 12 Jan 2024 18:08:36 -0500 Subject: [PATCH] rpc: add tapscript sibling to FinalizeBatch --- rpcserver.go | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/rpcserver.go b/rpcserver.go index f64ce85d9..e5f4316e8 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -18,6 +18,7 @@ import ( "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/btcutil/psbt" "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/davecgh/go-spew/spew" proxy "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" @@ -515,12 +516,44 @@ func (r *rpcServer) FinalizeBatch(_ context.Context, req *mintrpc.FinalizeBatchRequest) (*mintrpc.FinalizeBatchResponse, error) { + var batchSibling *asset.TapscriptTreeNodes + feeRate, err := checkFeeRateSanity(req.FeeRate) if err != nil { return nil, err } + feeRateOpt := fn.MaybeSome(feeRate) + + batchTapscriptTree := req.GetFullTree() + batchTapBranch := req.GetBranch() + + switch { + case batchTapscriptTree != nil && batchTapBranch != nil: + return nil, fmt.Errorf("cannot specify both tapscript tree " + + "and tapscript tree branches") + + case batchTapscriptTree != nil: + batchSibling, err = marshalTapscriptFullTree(batchTapscriptTree) + if err != nil { + return nil, fmt.Errorf("invalid tapscript tree: %w", + err) + } + + case batchTapBranch != nil: + batchSibling, err = marshalTapscriptBranch(batchTapBranch) + if err != nil { + return nil, fmt.Errorf("invalid tapscript branch: %w", + err) + } + } + tapTreeOpt := fn.MaybeSome(batchSibling) - batch, err := r.cfg.AssetMinter.FinalizeBatch(feeRate) + batch, err := r.cfg.AssetMinter.FinalizeBatch( + tapgarden.FinalizeParams{ + FeeRate: feeRateOpt, + TapTree: tapTreeOpt, + }, + ) if err != nil { return nil, fmt.Errorf("unable to finalize batch: %w", err) } @@ -2917,6 +2950,29 @@ func marshalBatchState(batch *tapgarden.MintingBatch) (mintrpc.BatchState, } } +func marshalTapscriptFullTree(tree *taprpc.TapscriptFullTree) ( + *asset.TapscriptTreeNodes, error) { + + rpcLeaves := tree.GetAllLeaves() + leaves := fn.Map(rpcLeaves, func(l *taprpc.TapLeaf) txscript.TapLeaf { + return txscript.NewBaseTapLeaf(l.Script) + }) + + return asset.TapTreeNodesFromLeaves(leaves) +} + +func marshalTapscriptBranch(branch *taprpc.TapBranch) (*asset.TapscriptTreeNodes, + error) { + + branchData := [][]byte{branch.LeftTaphash, branch.RightTaphash} + tapBranch, err := asset.DecodeTapBranchNodes(branchData) + if err != nil { + return nil, err + } + + return fn.Ptr(asset.FromBranch(*tapBranch)), nil +} + // UnmarshalScriptKey parses the RPC script key into the native counterpart. func UnmarshalScriptKey(rpcKey *taprpc.ScriptKey) (*asset.ScriptKey, error) { var (