decred.org/dcrdex@v1.0.5/dex/networks/zec/script.go (about)

     1  // This code is available on the terms of the project LICENSE.md file,
     2  // also available online at https://blueoakcouncil.org
     3  
     4  package zec
     5  
     6  import (
     7  	"math"
     8  
     9  	dexbtc "decred.org/dcrdex/dex/networks/btc"
    10  	"github.com/btcsuite/btcd/wire"
    11  )
    12  
    13  // https://zips.z.cash/zip-0317
    14  
    15  // TransparentTxFeesZIP317 calculates the ZIP-0317 fees for a fully transparent
    16  // Zcash transaction, which only depends on the size of the tx_in and tx_out
    17  // fields.
    18  func TransparentTxFeesZIP317(txInSize, txOutSize uint64) uint64 {
    19  	return TxFeesZIP317(txInSize, txOutSize, 0, 0, 0, 0)
    20  }
    21  
    22  // TxFeexZIP317 calculates fees for a transaction. The caller must sum up the
    23  // txin and txout, which is the entire serialization size associated with the
    24  // respective field, including the size of the count varint.
    25  func TxFeesZIP317(transparentTxInsSize, transparentTxOutsSize uint64, nSpendsSapling, nOutputsSapling, nJoinSplit, nActionsOrchard uint64) uint64 {
    26  	const (
    27  		marginalFee           = 5000
    28  		graceActions          = 2
    29  		pkhStandardInputSize  = 150
    30  		pkhStandardOutputSize = 34
    31  	)
    32  
    33  	nIn := math.Ceil(float64(transparentTxInsSize) / pkhStandardInputSize)
    34  	nOut := math.Ceil(float64(transparentTxOutsSize) / pkhStandardOutputSize)
    35  
    36  	nSapling := uint64(math.Max(float64(nSpendsSapling), float64(nOutputsSapling)))
    37  	logicalActions := uint64(math.Max(nIn, nOut)) + 2*nJoinSplit + nSapling + nActionsOrchard
    38  
    39  	return marginalFee * uint64(math.Max(graceActions, float64(logicalActions)))
    40  }
    41  
    42  // RequiredOrderFunds is the ZIP-0317 compliant version of
    43  // calc.RequiredOrderFunds.
    44  func RequiredOrderFunds(swapVal, inputCount, inputsSize, maxSwaps uint64) uint64 {
    45  	// One p2sh output for the contract, 1 change output.
    46  	const txOutsSize = dexbtc.P2PKHOutputSize + dexbtc.P2SHOutputSize + 1 /* wire.VarIntSerializeSize(2) */
    47  	txInsSize := inputsSize + uint64(wire.VarIntSerializeSize(inputCount))
    48  	firstTxFees := TransparentTxFeesZIP317(txInsSize, txOutsSize)
    49  	if maxSwaps == 1 {
    50  		return swapVal + firstTxFees
    51  	}
    52  
    53  	otherTxsFees := TransparentTxFeesZIP317(dexbtc.RedeemP2PKHInputSize+1, txOutsSize)
    54  	fees := firstTxFees + (maxSwaps-1)*otherTxsFees
    55  	return swapVal + fees
    56  }
    57  
    58  // MinHTLCSize calculates the minimum value for the output of a chained
    59  // P2SH -> P2WPKH transaction pair where the spending tx size is known.
    60  func MinHTLCSize(redeemTxFees uint64) uint64 {
    61  	var outputSize uint64 = dexbtc.P2PKHOutputSize
    62  	sz := outputSize + 148                        // 148 accounts for an input on spending tx
    63  	const oneThirdDustThresholdRate = 100         // zats / kB
    64  	nFee := oneThirdDustThresholdRate * sz / 1000 // This is different from BTC
    65  	if nFee == 0 {
    66  		nFee = oneThirdDustThresholdRate
    67  	}
    68  	htlcOutputDustMin := 3 * nFee
    69  
    70  	return htlcOutputDustMin + redeemTxFees
    71  }
    72  
    73  // MinLotSize is the minimum lot size that avoids dust for a given max network
    74  // fee rate.
    75  func MinLotSize(maxFeeRate uint64) uint64 {
    76  	var inputsSize uint64 = dexbtc.TxInOverhead + dexbtc.RefundSigScriptSize + 1
    77  	var outputsSize uint64 = dexbtc.P2PKHOutputSize + 1
    78  	refundBondTxFees := TxFeesZIP317(inputsSize, outputsSize, 0, 0, 0, 0)
    79  	return MinHTLCSize(refundBondTxFees)
    80  }