Fix wallet transaction info merging logic and compute color as fallback for labels to not crash

This commit is contained in:
Kukks 2022-12-22 14:17:23 +01:00
parent c7baa66a4d
commit 0534261759
No known key found for this signature in database
GPG key ID: 8E5530D9D1C93097
4 changed files with 52 additions and 22 deletions

View file

@ -311,14 +311,10 @@ namespace BTCPayServer.Controllers.Greenfield
utxos.SelectMany(GetWalletObjectsQuery.Get).Distinct().ToArray());
return Ok(utxos.Select(coin =>
{
walletTransactionsInfoAsync.TryGetValue(coin.OutPoint.Hash.ToString(), out var info);
walletTransactionsInfoAsync.TryGetValue(coin.ScriptPubKey.ToHex(), out var info2);
if (info is not null && info2 is not null)
{
info.Merge(info2);
}
info ??= info2;
walletTransactionsInfoAsync.TryGetValue(coin.OutPoint.Hash.ToString(), out var info1);
walletTransactionsInfoAsync.TryGetValue(coin.Address.ToString(), out var info2);
walletTransactionsInfoAsync.TryGetValue(coin.OutPoint.ToString(), out var info3);
var info = _walletRepository.Merge(info1, info2, info3);
return new OnChainWalletUTXOData()
{

View file

@ -582,14 +582,10 @@ namespace BTCPayServer.Controllers
utxos.SelectMany(u => GetWalletObjectsQuery.Get(u)).Distinct().ToArray());
vm.InputsAvailable = utxos.Select(coin =>
{
walletTransactionsInfoAsync.TryGetValue(coin.OutPoint.Hash.ToString(), out var info);
walletTransactionsInfoAsync.TryGetValue(coin.ScriptPubKey.ToHex(), out var info2);
if (info is not null && info2 is not null)
{
info.Merge(info2);
}
info ??= info2;
walletTransactionsInfoAsync.TryGetValue(coin.OutPoint.Hash.ToString(), out var info1);
walletTransactionsInfoAsync.TryGetValue(coin.Address.ToString(), out var info2);
walletTransactionsInfoAsync.TryGetValue(coin.OutPoint.ToString(), out var info3);
var info = WalletRepository.Merge(info1, info2, info3);
return new WalletSendModel.InputSelectionOption()
{
Outpoint = coin.OutPoint.ToString(),

View file

@ -84,21 +84,31 @@ namespace BTCPayServer.Data
public string Type { get; set; }
public void Merge(WalletTransactionInfo? value)
public WalletTransactionInfo Merge(WalletTransactionInfo? value)
{
var result = new WalletTransactionInfo(WalletId);
if (value is null)
return;
return result;
if (result.WalletId != value.WalletId)
{
return result;
}
result.LabelColors = new Dictionary<string, string>(LabelColors);
result.Attachments = new List<Attachment>(Attachments);
foreach (var valueLabelColor in value.LabelColors)
{
LabelColors.TryAdd(valueLabelColor.Key, valueLabelColor.Value);
result.LabelColors.TryAdd(valueLabelColor.Key, valueLabelColor.Value);
}
foreach (var valueAttachment in value.Attachments.Where(valueAttachment => !Attachments.Any(attachment =>
attachment.Id == valueAttachment.Id && attachment.Type == valueAttachment.Type)))
{
Attachments.Add(valueAttachment);
result.Attachments.Add(valueAttachment);
}
return result;
}
}
}

View file

@ -256,6 +256,25 @@ namespace BTCPayServer.Services
return GetWalletTransactionsInfoCore(walletId, wos);
}
public WalletTransactionInfo Merge(params WalletTransactionInfo[] infos)
{
WalletTransactionInfo result = null;
foreach (WalletTransactionInfo walletTransactionInfo in infos.Where(info => info is not null))
{
if (result is null)
{
result ??= walletTransactionInfo;
}
else
{
result = result.Merge(walletTransactionInfo);
}
}
return result;
}
private Dictionary<string, WalletTransactionInfo> GetWalletTransactionsInfoCore(WalletId walletId,
Dictionary<WalletObjectId, WalletObjectData> wos)
@ -275,7 +294,7 @@ namespace BTCPayServer.Services
var neighbourData = neighbour.Data is null ? null : JObject.Parse(neighbour.Data);
if (neighbour.Type == WalletObjectData.Types.Label)
{
info.LabelColors.TryAdd(neighbour.Id, neighbourData?["color"]?.Value<string>() ?? "#000");
info.LabelColors.TryAdd(neighbour.Id, neighbourData?["color"]?.Value<string>() ?? ColorPalette.Default.DeterministicColor(neighbour.Id));
}
else
{
@ -295,7 +314,16 @@ namespace BTCPayServer.Services
return (await
ctx.WalletObjects.AsNoTracking().Where(w => w.WalletId == walletId.ToString() && w.Type == WalletObjectData.Types.Label)
.ToArrayAsync())
.Select(o => (o.Id, JObject.Parse(o.Data)["color"]!.Value<string>()!)).ToArray();
.Select(o =>
{
if (o.Data is null)
{
return (o.Id,ColorPalette.Default.DeterministicColor(o.Id));
}
return (o.Id,
JObject.Parse(o.Data)["color"]?.Value<string>() ??
ColorPalette.Default.DeterministicColor(o.Id));
}).ToArray();
}
public async Task<bool> RemoveWalletObjects(WalletObjectId walletObjectId)