better coin amounts distribution
MODIFY
WalletWasabi.Tests/UnitTests/WabiSabi/Integration/Participant.cs
WalletWasabi.Tests/UnitTests/WabiSabi/Integration/Participant.cs
@@ -27,17 +27,48 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Integration
public IRPCClient Rpc { get; }
public WabiSabiHttpApiClient ApiClient { get; }
- public async Task InitializeAsync(int numberOfCoins, CancellationToken cancellationToken)
- {
- var keys = KeyManager.GetKeys().Take(numberOfCoins).ToArray();
- foreach (var key in keys)
+ private Coin? SourceCoin { get; set; }
+
+ public async Task GenerateSourceCoinAsync(CancellationToken cancellationToken)
{
- cancellationToken.ThrowIfCancellationRequested();
- var blockIds = await Rpc.GenerateToAddressAsync(1, key.GetP2wpkhAddress(Rpc.Network)).ConfigureAwait(false);
+ var minerKey = KeyManager.GetNextReceiveKey("coinbase", out _);
+ var blockIds = await Rpc.GenerateToAddressAsync(1, minerKey.GetP2wpkhAddress(Rpc.Network)).ConfigureAwait(false);
var block = await Rpc.GetBlockAsync(blockIds.First()).ConfigureAwait(false);
- var coin = block.Transactions[0].Outputs.GetCoins(key.P2wpkhScript).First();
- Coins.Add(coin);
+ SourceCoin = block.Transactions[0].Outputs.GetCoins(minerKey.P2wpkhScript).First();
+ minerKey.SetKeyState(KeyState.Used);
+ }
+
+ public async Task GenerateCoinsAsync(int numberOfCoins, CancellationToken cancellationToken)
+ {
+ var feeRate = new FeeRate(4.0m);
+ var splitTx = Transaction.Create(Rpc.Network);
+ splitTx.Inputs.Add(new TxIn(SourceCoin!.Outpoint));
+
+ var rnd = new Random();
+ var sampling = Enumerable
+ .Range(0, numberOfCoins-1)
+ .Select(_ => rnd.NextDouble())
+ .Prepend(0)
+ .Prepend(1)
+ .OrderBy(x => x)
+ .ToArray();
+
+ var amounts = sampling
+ .Zip(sampling.Skip(1), (x, y) => y - x)
+ .Select(x => x * SourceCoin.Amount.Satoshi)
+ .Select(x => Money.Satoshis((long)x));
+
+ foreach (var amount in amounts)
+ {
+ var key = KeyManager.GetNextReceiveKey("no-label", out _);
+ var scriptPubKey = key.P2wpkhScript;
+ var effectiveOutputValue = amount - feeRate.GetFee(scriptPubKey.EstimateOutputVsize());
+ splitTx.Outputs.Add(new TxOut(effectiveOutputValue, scriptPubKey));
}
+ var minerKey = KeyManager.GetSecrets("", SourceCoin.ScriptPubKey).First();
+ splitTx.Sign(minerKey.PrivateKey.GetBitcoinSecret(Rpc.Network), SourceCoin);
+ Coins.AddRange(splitTx.Outputs.AsCoins());
+ await Rpc.SendRawTransactionAsync(splitTx).ConfigureAwait(false);
}
public async Task StartParticipatingAsync(CancellationToken cancellationToken)

MODIFY
WalletWasabi.Tests/UnitTests/WabiSabi/Integration/WabiSabiHttpApiIntegrationTests.cs
WalletWasabi.Tests/UnitTests/WabiSabi/Integration/WabiSabiHttpApiIntegrationTests.cs
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
@@ -172,10 +173,15 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Integration
foreach (var participant in participants)
{
- await participant.InitializeAsync(NumberOfCoinsPerParticipant, cts.Token);
+ await participant.GenerateSourceCoinAsync(cts.Token);
}
using var dummyKey = new Key();
await rpc.GenerateToAddressAsync(101, dummyKey.PubKey.GetAddress(ScriptPubKeyType.Segwit, rpc.Network));
+ foreach (var participant in participants)
+ {
+ await participant.GenerateCoinsAsync(NumberOfCoinsPerParticipant, cts.Token);
+ }
+ await rpc.GenerateToAddressAsync(101, dummyKey.PubKey.GetAddress(ScriptPubKeyType.Segwit, rpc.Network));
var tasks = participants.Select(x => x.StartParticipatingAsync(cts.Token)).ToArray();

better coin amounts distribution