Use mempool information to improve estimations
Splits the mempool transactions in 1Mvb blocks and calculates
the minimum fee rate a tx has to pay in order to confirm in a given
target.
Use this info to improve the bitcoin core estimations.
MODIFY
WalletWasabi/Extensions/RPCClientExtensions.cs
WalletWasabi/Extensions/RPCClientExtensions.cs
@@ -77,9 +77,33 @@ namespace NBitcoin.RPC
var mempoolInfo = await rpc.GetMempoolInfoAsync().ConfigureAwait(false);
var sanityFeeRate = mempoolInfo.GetSanityFeeRate();
+ const int BlockSize = 1_000_000;
+ static IEnumerable<(int Size, FeeRate From, FeeRate To)> SplitFeeGroupInBlocks(FeeRateGroup group)
+ => Enumerable
+ .Range(0, (int)group.Sizes / BlockSize)
+ .Select(b => (Sizes: BlockSize, From: group.From, To: group.To));
+
+ var minFeeRatePerTarget = mempoolInfo.Histogram
+ .OrderByDescending(x => x.Group)
+ .SkipWhile(x => x.Count < mempoolInfo.Size / 100 ) // Filter those groups with very fee transactions (less than 1%)
+ .SelectMany(x => SplitFeeGroupInBlocks(x))
+ .Scan((Group: default((int Size, FeeRate From, FeeRate To)), Size: 0), (acc, c) => (c, acc.Size + c.Size))
+ .Select(x => (From: x.Group.From, To: x.Group.To, MvB: x.Size, Target: 1 + x.Size / BlockSize))
+ .GroupBy(x => x.Target,
+ (target, feeGroups) => (Target: target, To: feeGroups.First().To, From: (feeGroups.LastOrDefault().From ?? FeeRate.Zero), MvB: feeGroups.Sum(xx => (decimal)xx.MvB)))
+ .ToDictionary(x => x.Target, x => (int)Math.Ceiling(x.From.SatoshiPerByte));
+
+ var fixedEstimations = estimations.GroupJoin(minFeeRatePerTarget,
+ outer => outer.Key,
+ inner => inner.Key,
+ (outer, inner) => new { Estimation = outer, MinimumFromMemPool = inner})
+ .SelectMany(x => x.MinimumFromMemPool.DefaultIfEmpty(),
+ (a, b) => (Target: a.Estimation.Key, FeeRate: Math.Max(Math.Max(a.Estimation.Value, b.Value), (int)sanityFeeRate.SatoshiPerByte)))
+ .ToDictionary(x => x.Target, x => x.FeeRate);
+
return new AllFeeEstimate(
estimateMode,
- estimations.ToDictionary(x => x.Key, x => Math.Max(x.Value, (int)sanityFeeRate.SatoshiPerByte)),
+ fixedEstimations,
rpcStatus.Synchronized);
}

Use mempool information to improve estimations

Splits the mempool transactions in 1Mvb blocks and calculates
the minimum fee rate a tx has to pay in order to confirm in a given
target.
Use this info to improve the bitcoin core estimations.