mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-31 06:55:59 +00:00
decred: Fix fee estimation.
This commit is contained in:
parent
f0a8e3e879
commit
234e9ad607
4 changed files with 92 additions and 11 deletions
|
@ -146,10 +146,14 @@ Map balance(String walletName) {
|
|||
return jsonDecode(res.payload);
|
||||
}
|
||||
|
||||
int calculateEstimatedFeeWithFeeRate(int feeRate, int amount) {
|
||||
// Ideally we create a tx with wallet going to this amount and just return
|
||||
// the fee we get back. TODO.
|
||||
return 123000;
|
||||
String estimateFee(String walletName, int numBlocks) {
|
||||
final cName = walletName.toCString();
|
||||
final cNumBlocks = numBlocks.toString().toCString();
|
||||
final res = executePayloadFn(
|
||||
fn: () => dcrwalletApi.estimateFee(cName, cNumBlocks),
|
||||
ptrsToFree: [cName, cNumBlocks],
|
||||
);
|
||||
return res.payload;
|
||||
}
|
||||
|
||||
String createSignedTransaction(
|
||||
|
|
|
@ -52,3 +52,22 @@ class DecredTransactionPriority extends TransactionPriority {
|
|||
|
||||
String labelWithRate(int rate) => '${toString()} ($rate ${units}/byte)';
|
||||
}
|
||||
|
||||
class FeeCache {
|
||||
int _feeRate;
|
||||
DateTime stamp;
|
||||
FeeCache(this._feeRate) : this.stamp = DateTime(0, 0, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
bool isOld() {
|
||||
return this.stamp.add(const Duration(minutes: 30)).isBefore(DateTime.now());
|
||||
}
|
||||
|
||||
void update(int feeRate) {
|
||||
this._feeRate = feeRate;
|
||||
this.stamp = DateTime.now();
|
||||
}
|
||||
|
||||
int feeRate() {
|
||||
return this._feeRate;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,11 +44,17 @@ abstract class DecredWalletBase extends WalletBase<DecredBalance,
|
|||
transactionHistory = DecredTransactionHistory();
|
||||
}
|
||||
|
||||
final defaultFeeRate = 10000;
|
||||
// NOTE: Hitting this max fee would be unexpected with current on chain use
|
||||
// but this may need to be updated in the future.
|
||||
final maxFeeRate = 100000;
|
||||
static final defaultFeeRate = 10000;
|
||||
final String _password;
|
||||
final idPrefix = "decred_";
|
||||
bool connecting = false;
|
||||
String persistantPeer = "";
|
||||
FeeCache feeRateFast = FeeCache(defaultFeeRate);
|
||||
FeeCache feeRateMedium = FeeCache(defaultFeeRate);
|
||||
FeeCache feeRateSlow = FeeCache(defaultFeeRate);
|
||||
Timer? syncTimer;
|
||||
Box<UnspentCoinsInfo> unspentCoinsInfo;
|
||||
|
||||
|
@ -240,7 +246,6 @@ abstract class DecredWalletBase extends WalletBase<DecredBalance,
|
|||
outputs.add(o);
|
||||
}
|
||||
;
|
||||
// TODO: Fix fee rate.
|
||||
final signReq = {
|
||||
"inputs": inputs,
|
||||
"ignoreInputs": ignoreInputs,
|
||||
|
@ -264,17 +269,67 @@ abstract class DecredWalletBase extends WalletBase<DecredBalance,
|
|||
}
|
||||
|
||||
int feeRate(TransactionPriority priority) {
|
||||
// TODO
|
||||
return 1000;
|
||||
if (!(priority is DecredTransactionPriority)) {
|
||||
return defaultFeeRate;
|
||||
}
|
||||
int Function(int nb) feeForNb = (int nb) {
|
||||
try {
|
||||
final feeStr = libdcrwallet.estimateFee(walletInfo.name, nb);
|
||||
var fee = int.parse(feeStr);
|
||||
if (fee > maxFeeRate) {
|
||||
throw "dcr fee returned from estimate fee was over max";
|
||||
} else if (fee <= 0) {
|
||||
throw "dcr fee returned from estimate fee was zero";
|
||||
}
|
||||
return fee;
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return defaultFeeRate;
|
||||
}
|
||||
};
|
||||
final p = priority as DecredTransactionPriority;
|
||||
switch (p) {
|
||||
case DecredTransactionPriority.slow:
|
||||
if (feeRateSlow.isOld()) {
|
||||
feeRateSlow.update(feeForNb(4));
|
||||
}
|
||||
return feeRateSlow.feeRate();
|
||||
case DecredTransactionPriority.medium:
|
||||
if (feeRateMedium.isOld()) {
|
||||
feeRateMedium.update(feeForNb(2));
|
||||
}
|
||||
return feeRateMedium.feeRate();
|
||||
case DecredTransactionPriority.fast:
|
||||
if (feeRateFast.isOld()) {
|
||||
feeRateFast.update(feeForNb(1));
|
||||
}
|
||||
return feeRateFast.feeRate();
|
||||
}
|
||||
return defaultFeeRate;
|
||||
}
|
||||
|
||||
@override
|
||||
int calculateEstimatedFee(TransactionPriority priority, int? amount) {
|
||||
if (priority is DecredTransactionPriority) {
|
||||
return libdcrwallet.calculateEstimatedFeeWithFeeRate(
|
||||
this.feeRate(priority), amount ?? 0);
|
||||
}
|
||||
final P2PKHOutputSize =
|
||||
36; // 8 bytes value + 2 bytes version + at least 1 byte varint script size + P2PKHPkScriptSize
|
||||
// MsgTxOverhead is 4 bytes version (lower 2 bytes for the real transaction
|
||||
// version and upper 2 bytes for the serialization type) + 4 bytes locktime
|
||||
// + 4 bytes expiry + 3 bytes of varints for the number of transaction
|
||||
// inputs (x2 for witness and prefix) and outputs
|
||||
final MsgTxOverhead = 15;
|
||||
// TxInOverhead is the overhead for a wire.TxIn with a scriptSig length <
|
||||
// 254. prefix (41 bytes) + ValueIn (8 bytes) + BlockHeight (4 bytes) +
|
||||
// BlockIndex (4 bytes) + sig script var int (at least 1 byte)
|
||||
final TxInOverhead = 57;
|
||||
final P2PKHInputSize = TxInOverhead +
|
||||
109; // TxInOverhead (57) + var int (1) + P2PKHSigScriptSize (108)
|
||||
|
||||
// Estimate using a transaction consuming three inputs and paying to one
|
||||
// address with change.
|
||||
return this.feeRate(priority) *
|
||||
(MsgTxOverhead + P2PKHInputSize * 3 + P2PKHOutputSize * 2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:cake_wallet/haven/haven.dart';
|
|||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/polygon/polygon.dart';
|
||||
import 'package:cake_wallet/wownero/wownero.dart';
|
||||
import 'package:cake_wallet/decred/decred.dart';
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
|
||||
|
@ -32,6 +33,8 @@ List<TransactionPriority> priorityForWalletType(WalletType type) {
|
|||
case WalletType.solana:
|
||||
case WalletType.tron:
|
||||
return [];
|
||||
case WalletType.decred:
|
||||
return decred!.getTransactionPriorities();
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue