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 }