Skip to content

Commit

Permalink
multi: Use common fee for split tx
Browse files Browse the repository at this point in the history
Instead of relying on the wallet to specify the rate for split
transactions, this unifies buyers to using a single source for fee rate
determination, which prevents problems with wallets that have changed
their default fee rate.
  • Loading branch information
matheusd committed Dec 17, 2018
1 parent 77771bc commit f75a306
Show file tree
Hide file tree
Showing 8 changed files with 16 additions and 15 deletions.
4 changes: 2 additions & 2 deletions pkg/buyer/wallet-client.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ func (wc *WalletClient) generateSplitTxInputs(ctx context.Context, session *Sess
}

req := &pb.ConstructTransactionRequest{
FeePerKb: 0, // whatever is the default wallet fee
FeePerKb: int32(splitticket.TxFeeRate),
RequiredConfirmations: splitticket.MinimumSplitInputConfirms,
SourceAccount: cfg.SourceAccount,
NonChangeOutputs: outputs,
Expand Down Expand Up @@ -656,7 +656,7 @@ func (wc *WalletClient) testFunds(ctx context.Context, cfg *Config) error {
}

req := &pb.ConstructTransactionRequest{
FeePerKb: 0,
FeePerKb: int32(splitticket.TxFeeRate),
RequiredConfirmations: splitticket.MinimumSplitInputConfirms,
SourceAccount: cfg.SourceAccount,
NonChangeOutputs: outputs,
Expand Down
8 changes: 8 additions & 0 deletions pkg/splitticket/const.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package splitticket

import "github.com/decred/dcrd/dcrutil"

const (
// SplitTicketSrvService is the _service_ part of an SRV record that is
// looked up prior to connecting to the split ticket service
Expand All @@ -24,4 +26,10 @@ const (
// As of 2018-11-09 only ~3% of all mainnet txs used more than 20 inputs, so
// this should be reasonable.
MaximumSplitInputs = 20

// TxFeeRate is the expected transaction fee rate for the split and ticket
// transactions of participants of split tickets.
//
// Measured as Atoms/KB. 1e5 = 0.001 DCR
TxFeeRate dcrutil.Amount = 1e5
)
7 changes: 2 additions & 5 deletions pkg/splitticket/fees.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ const (
1 + 108 + // TxIn len(ScriptSig) + ScriptSig
8 + 2 + 1 + 32 + // Stake Commitment TxOut = amount + version + script
8 + 2 + 1 + 26 // Stake Change TxOut = amount + version + script

// TicketFeeEstimate is the fee rate estimate (in dcr/byte) of the fee in
// a ticket purchase
TicketFeeEstimate float64 = 0.001 / 1000
)

// TicketSizeEstimate returns the size estimate for the ticket transaction for
Expand All @@ -41,8 +37,9 @@ func TicketSizeEstimate(numParticipants int) int {
// SessionParticipantFee returns the fee that a single participant of a ticket
// split tx with the given number of participants should pay
func SessionParticipantFee(numParticipants int) dcrutil.Amount {
feeRate := float64(TxFeeRate) / 1e11 // 1e11 = 1e8 * 1e3
txSize := TicketSizeEstimate(numParticipants)
ticketFee, _ := dcrutil.NewAmount(float64(txSize) * TicketFeeEstimate)
ticketFee, _ := dcrutil.NewAmount(float64(txSize) * feeRate)
partFee := dcrutil.Amount(math.Ceil(float64(ticketFee) / float64(numParticipants)))
return partFee
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/splitticket/revocation.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func RevocationFeeRate(params *chaincfg.Params) dcrutil.Amount {
return 1e4
}

return minRelayFeeRate
return TxFeeRate
}

// CheckRevocation checks whether the revocation for the given ticket respects
Expand Down
2 changes: 1 addition & 1 deletion pkg/splitticket/revocation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func TestCreateUnsignedRevocation(t *testing.T) {

revocation.TxIn[0].SignatureScript = revocationSigScript
size := revocation.SerializeSize()
minFee := dcrutil.Amount((size * int(minRelayFeeRate)) / 1000)
minFee := dcrutil.Amount((size * int(TxFeeRate)) / 1000)

fee, err := FindRevocationTxFee(ticket, revocation)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/splitticket/splittx.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func CheckSignedSplit(split *wire.MsgTx, utxos UtxoMap, params *chaincfg.Params)
txFee := totalAmountIn - int64(totalAmountOut)

serializedSize := int64(split.SerializeSize())
minFee := (serializedSize * int64(minRelayFeeRate)) / 1000
minFee := (serializedSize * int64(TxFeeRate)) / 1000
if txFee < minFee {
return errors.Errorf("split tx fee (%s) less than minimum required "+
"amount (%s)", dcrutil.Amount(txFee), dcrutil.Amount(minFee))
Expand Down
2 changes: 1 addition & 1 deletion pkg/splitticket/ticket.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ func CheckSignedTicket(split, ticket *wire.MsgTx, params *chaincfg.Params) error
}
txFee := totalAmountIn - totalAmountOut
serializedSize := int64(ticket.SerializeSize())
minFee := (serializedSize * int64(minRelayFeeRate)) / 1000
minFee := (serializedSize * int64(TxFeeRate)) / 1000
if txFee < minFee {
return errors.Errorf("ticket fee (%s) less than minimum required amount (%s)",
dcrutil.Amount(txFee), dcrutil.Amount(minFee))
Expand Down
4 changes: 0 additions & 4 deletions pkg/splitticket/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ var currentScriptFlags = txscript.ScriptDiscourageUpgradableNops |
txscript.ScriptVerifyCheckSequenceVerify |
txscript.ScriptVerifySHA256

// minRelayFeeRate is the minimum tx fee rate for inclusion on the network.
// Measured as Atoms/KB. 1e5 = 0.001 DCR
const minRelayFeeRate dcrutil.Amount = 1e5

// totalOutputAmount calculates the total amount of outputs for a transaction.
// Only safe to be called on transactions which passed
// blockchain.CheckTransactionSanity()
Expand Down

0 comments on commit f75a306

Please sign in to comment.