@@ -888,6 +888,7 @@ func (p *ChainPorter) storePackageAnchorTxConf(pkg *sendPackage) error {
888888		TxIndex :                int32 (pkg .TransferTxConfEvent .TxIndex ),
889889		FinalProofs :            pkg .FinalProofs ,
890890		PassiveAssetProofFiles : passiveAssetProofFiles ,
891+ 		ZeroValueInputs :        pkg .ZeroValueInputs ,
891892	}, burns )
892893	if  err  !=  nil  {
893894		return  fmt .Errorf ("unable to log parcel delivery " + 
@@ -1248,9 +1249,8 @@ func (p *ChainPorter) importLocalAddresses(ctx context.Context,
12481249	for  idx  :=  range  parcel .Outputs  {
12491250		out  :=  & parcel .Outputs [idx ]
12501251
1251- 		// Skip non-local outputs, those are going to a receiver outside 
1252- 		// of this daemon. 
1253- 		if  ! out .ScriptKeyLocal  {
1252+ 		// Determine if the output should be imported into the wallet. 
1253+ 		if  ! out .IsSpendable () {
12541254			continue 
12551255		}
12561256
@@ -1267,23 +1267,30 @@ func (p *ChainPorter) importLocalAddresses(ctx context.Context,
12671267			return  err 
12681268		}
12691269
1270+ 		log .Infof ("Importing anchor output key for output %d " + 
1271+ 			"(isTombstone=%v, isBurn=%v): outpoint=%v, key=%x" ,
1272+ 			idx , out .IsTombstone (), out .IsBurn (),
1273+ 			out .Anchor .OutPoint ,
1274+ 			anchorOutputKey .SerializeCompressed ())
1275+ 
12701276		// Before we broadcast the transaction to the network, we'll 
12711277		// import the new anchor output into the wallet so it watches 
12721278		// it for spends and also takes account of the BTC we used in 
12731279		// the transfer. 
12741280		_ , err  =  p .cfg .Wallet .ImportTaprootOutput (ctx , anchorOutputKey )
1275- 		switch  {
1276- 		case  err  ==  nil :
1277- 			break 
1278- 
1279- 		// On restart, we'll get an error that the output has already 
1280- 		// been added to the wallet, so we'll catch this now and move 
1281- 		// along if so. 
1282- 		case  strings .Contains (err .Error (), "already exists" ):
1283- 			break 
1281+ 		if  err  !=  nil  {
1282+ 			// On restart, we'll get an error that the output has 
1283+ 			// already been added to the wallet, so we'll catch this 
1284+ 			// now and move along if so. 
1285+ 			if  strings .Contains (err .Error (), "already exists" ) {
1286+ 				log .Tracef ("Anchor output key already exists " + 
1287+ 					"(outpoint=%v): %w" ,
1288+ 					out .Anchor .OutPoint , err )
1289+ 				continue 
1290+ 			}
12841291
1285- 		default : 
1286- 			return   err 
1292+ 			 return   fmt . Errorf ( "unable to import anchor output " + 
1293+ 				 "key: %w" ,  err ) 
12871294		}
12881295	}
12891296
@@ -1446,6 +1453,7 @@ func (p *ChainPorter) stateStep(currentPkg sendPackage) (*sendPackage, error) {
14461453
14471454		currentPkg .VirtualPackets  =  fundSendRes .VPackets 
14481455		currentPkg .InputCommitments  =  fundSendRes .InputCommitments 
1456+ 		currentPkg .ZeroValueInputs  =  fundSendRes .ZeroValueInputs 
14491457
14501458		currentPkg .SendState  =  SendStateVirtualSign 
14511459
@@ -1591,9 +1599,10 @@ func (p *ChainPorter) stateStep(currentPkg sendPackage) (*sendPackage, error) {
15911599
15921600		anchorTx , err  :=  wallet .AnchorVirtualTransactions (
15931601			ctx , & AnchorVTxnsParams {
1594- 				FeeRate :        feeRate ,
1595- 				ActivePackets :  currentPkg .VirtualPackets ,
1596- 				PassivePackets : currentPkg .PassiveAssets ,
1602+ 				FeeRate :         feeRate ,
1603+ 				ActivePackets :   currentPkg .VirtualPackets ,
1604+ 				PassivePackets :  currentPkg .PassiveAssets ,
1605+ 				ZeroValueInputs : currentPkg .ZeroValueInputs ,
15971606			},
15981607		)
15991608		if  err  !=  nil  {
@@ -1695,8 +1704,8 @@ func (p *ChainPorter) stateStep(currentPkg sendPackage) (*sendPackage, error) {
16951704		parcel , err  :=  ConvertToTransfer (
16961705			currentHeight , currentPkg .VirtualPackets ,
16971706			currentPkg .AnchorTx , currentPkg .PassiveAssets ,
1698- 			isLocalKey ,  currentPkg .Label ,
1699- 			currentPkg .SkipAnchorTxBroadcast ,
1707+ 			currentPkg .ZeroValueInputs ,  isLocalKey ,
1708+ 			currentPkg .Label ,  currentPkg . SkipAnchorTxBroadcast ,
17001709		)
17011710		if  err  !=  nil  {
17021711			p .unlockInputs (ctx , & currentPkg )
@@ -1715,6 +1724,8 @@ func (p *ChainPorter) stateStep(currentPkg sendPackage) (*sendPackage, error) {
17151724		// Write the parcel to disk as a pending parcel. This step also 
17161725		// records the transfer details (e.g., reference to the anchor 
17171726		// transaction ID, transfer outputs and inputs) to the database. 
1727+ 		// This will also extend the leases for both asset inputs and 
1728+ 		// zero-value UTXOs to prevent them from being used elsewhere. 
17181729		err  =  p .cfg .ExportLog .LogPendingParcel (
17191730			ctx , parcel , defaultWalletLeaseIdentifier ,
17201731			time .Now ().Add (defaultBroadcastCoinLeaseDuration ),
@@ -1883,18 +1894,33 @@ func (p *ChainPorter) unlockInputs(ctx context.Context, pkg *sendPackage) {
18831894	// sanity-check that we have known input commitments to unlock, since 
18841895	// that might not always be the case (for example if another party 
18851896	// contributes inputs). 
1886- 	if  pkg .SendState  <  SendStateStorePreBroadcast  && 
1887- 		len (pkg .InputCommitments ) >  0  {
1897+ 	// Also unlock any zero-value UTXOs that were leased for this package. 
1898+ 	if  pkg .SendState  <  SendStateStorePreBroadcast  {
1899+ 		// Gather all outpoints to unlock in a single array 
1900+ 		var  outpoints  []wire.OutPoint 
18881901
1902+ 		// Add input commitment outpoints 
18891903		for  prevID  :=  range  pkg .InputCommitments  {
18901904			log .Debugf ("Unlocking input %v" , prevID .OutPoint )
1905+ 			outpoints  =  append (outpoints , prevID .OutPoint )
1906+ 		}
1907+ 
1908+ 		// Add zero-value inputs 
1909+ 		zeroValueOutpoints  :=  fn .Map (
1910+ 			pkg .ZeroValueInputs ,
1911+ 			func (z  * ZeroValueInput ) wire.OutPoint  {
1912+ 				return  z .OutPoint 
1913+ 			},
1914+ 		)
1915+ 		outpoints  =  append (outpoints , zeroValueOutpoints ... )
18911916
1917+ 		// Release all coins in a single call 
1918+ 		if  len (outpoints ) >  0  {
18921919			err  :=  p .cfg .AssetWallet .ReleaseCoins (
1893- 				ctx , prevID . OutPoint ,
1920+ 				ctx , outpoints ... ,
18941921			)
18951922			if  err  !=  nil  {
1896- 				log .Warnf ("Unable to unlock input %v: %v" ,
1897- 					prevID .OutPoint , err )
1923+ 				log .Warnf ("Unable to unlock inputs: %v" , err )
18981924			}
18991925		}
19001926	}
0 commit comments