Merge pull request #3773 from NicolasDorier/wefiou

Remove HistoricalAddresses table
This commit is contained in:
Nicolas Dorier 2022-05-24 19:06:08 +09:00 committed by GitHub
commit 1d3c4b6f90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 46 additions and 195 deletions

View File

@ -36,7 +36,6 @@ namespace BTCPayServer.Data
public DbSet<AppData> Apps { get; set; }
public DbSet<CustodianAccountData> CustodianAccount { get; set; }
public DbSet<StoredFile> Files { get; set; }
public DbSet<HistoricalAddressInvoiceData> HistoricalAddressInvoices { get; set; }
public DbSet<InvoiceEventData> InvoiceEvents { get; set; }
public DbSet<InvoiceSearchData> InvoiceSearches { get; set; }
public DbSet<InvoiceWebhookDeliveryData> InvoiceWebhookDeliveries { get; set; }
@ -85,7 +84,6 @@ namespace BTCPayServer.Data
AppData.OnModelCreating(builder);
CustodianAccountData.OnModelCreating(builder);
//StoredFile.OnModelCreating(builder);
HistoricalAddressInvoiceData.OnModelCreating(builder);
InvoiceEventData.OnModelCreating(builder);
InvoiceSearchData.OnModelCreating(builder);
InvoiceWebhookDeliveryData.OnModelCreating(builder);

View File

@ -1,41 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore;
namespace BTCPayServer.Data
{
public class HistoricalAddressInvoiceData
{
public string InvoiceDataId { get; set; }
public InvoiceData InvoiceData { get; set; }
/// <summary>
/// Some crypto currencies share same address prefix
/// For not having exceptions thrown by two address on different network, we suffix by "#CRYPTOCODE"
/// </summary>
[Obsolete("Use GetCryptoCode instead")]
public string Address { get; set; }
[Obsolete("Use GetCryptoCode instead")]
public string CryptoCode { get; set; }
public DateTimeOffset Assigned { get; set; }
public DateTimeOffset? UnAssigned { get; set; }
internal static void OnModelCreating(ModelBuilder builder)
{
builder.Entity<HistoricalAddressInvoiceData>()
.HasOne(o => o.InvoiceData)
.WithMany(i => i.HistoricalAddressInvoices).OnDelete(DeleteBehavior.Cascade);
builder.Entity<HistoricalAddressInvoiceData>()
.HasKey(o => new
{
o.InvoiceDataId,
#pragma warning disable CS0618
o.Address
#pragma warning restore CS0618
});
}
}
}

View File

@ -16,8 +16,6 @@ namespace BTCPayServer.Data
public List<PaymentData> Payments { get; set; }
public List<InvoiceEventData> Events { get; set; }
public List<HistoricalAddressInvoiceData> HistoricalAddressInvoices { get; set; }
public byte[] Blob { get; set; }
public string ItemCode { get; set; }
public string OrderId { get; set; }

View File

@ -0,0 +1,44 @@
using System;
using BTCPayServer.Data;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BTCPayServer.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20220523022603_remove_historical_addresses")]
public partial class remove_historical_addresses : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "HistoricalAddressInvoices");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "HistoricalAddressInvoices",
columns: table => new
{
InvoiceDataId = table.Column<string>(type: "TEXT", nullable: false),
Address = table.Column<string>(type: "TEXT", nullable: false),
Assigned = table.Column<DateTimeOffset>(type: "TEXT", nullable: false),
CryptoCode = table.Column<string>(type: "TEXT", nullable: true),
UnAssigned = table.Column<DateTimeOffset>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_HistoricalAddressInvoices", x => new { x.InvoiceDataId, x.Address });
table.ForeignKey(
name: "FK_HistoricalAddressInvoices_Invoices_InvoiceDataId",
column: x => x.InvoiceDataId,
principalTable: "Invoices",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
}
}
}

View File

@ -254,28 +254,6 @@ namespace BTCPayServer.Migrations
b.ToTable("Fido2Credentials");
});
modelBuilder.Entity("BTCPayServer.Data.HistoricalAddressInvoiceData", b =>
{
b.Property<string>("InvoiceDataId")
.HasColumnType("TEXT");
b.Property<string>("Address")
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("Assigned")
.HasColumnType("TEXT");
b.Property<string>("CryptoCode")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("UnAssigned")
.HasColumnType("TEXT");
b.HasKey("InvoiceDataId", "Address");
b.ToTable("HistoricalAddressInvoices");
});
modelBuilder.Entity("BTCPayServer.Data.InvoiceData", b =>
{
b.Property<string>("Id")
@ -1106,17 +1084,6 @@ namespace BTCPayServer.Migrations
b.Navigation("ApplicationUser");
});
modelBuilder.Entity("BTCPayServer.Data.HistoricalAddressInvoiceData", b =>
{
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
.WithMany("HistoricalAddressInvoices")
.HasForeignKey("InvoiceDataId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("InvoiceData");
});
modelBuilder.Entity("BTCPayServer.Data.InvoiceData", b =>
{
b.HasOne("BTCPayServer.Data.StoreData", "StoreData")
@ -1435,8 +1402,6 @@ namespace BTCPayServer.Migrations
b.Navigation("Events");
b.Navigation("HistoricalAddressInvoices");
b.Navigation("InvoiceSearchData");
b.Navigation("Payments");

View File

@ -2110,8 +2110,6 @@ namespace BTCPayServer.Tests
cashCow.SendToAddress(invoiceAddress, firstPayment);
var invoiceEntity = repo.GetInvoice(invoice.Id, true).GetAwaiter().GetResult();
Assert.Single(invoiceEntity.HistoricalAddresses);
Assert.Null(invoiceEntity.HistoricalAddresses[0].UnAssigned);
Money secondPayment = Money.Zero;
@ -2128,13 +2126,6 @@ namespace BTCPayServer.Tests
Assert.True(IsMapped(localInvoice, ctx));
invoiceEntity = repo.GetInvoice(invoice.Id, true).GetAwaiter().GetResult();
var historical1 =
invoiceEntity.HistoricalAddresses.FirstOrDefault(h => h.GetAddress() == invoice.BitcoinAddress);
Assert.NotNull(historical1.UnAssigned);
var historical2 =
invoiceEntity.HistoricalAddresses.FirstOrDefault(h =>
h.GetAddress() == localInvoice.BitcoinAddress);
Assert.Null(historical2.UnAssigned);
invoiceAddress = BitcoinAddress.Create(localInvoice.BitcoinAddress, cashCow.Network);
secondPayment = localInvoice.BtcDue;
});

View File

@ -132,13 +132,6 @@ namespace BTCPayServer.Controllers
CanMarkInvalid = invoiceState.CanMarkInvalid(),
CanMarkSettled = invoiceState.CanMarkComplete(),
};
model.Addresses = invoice.HistoricalAddresses.Select(h =>
new InvoiceDetailsModel.AddressModel
{
Destination = h.GetAddress(),
PaymentMethod = h.GetPaymentMethodId().ToPrettyString(),
Current = !h.UnAssigned.HasValue
}).ToArray();
var details = InvoicePopulatePayments(invoice);
model.CryptoPayments = details.CryptoPayments;

View File

@ -1,30 +0,0 @@
using System;
namespace BTCPayServer.Data
{
public static class HistoricalAddressInvoiceDataExtensions
{
#pragma warning disable CS0618
public static Payments.PaymentMethodId GetPaymentMethodId(this HistoricalAddressInvoiceData historicalAddressInvoiceData)
{
return string.IsNullOrEmpty(historicalAddressInvoiceData.CryptoCode) ? new Payments.PaymentMethodId("BTC", Payments.PaymentTypes.BTCLike)
: Payments.PaymentMethodId.Parse(historicalAddressInvoiceData.CryptoCode);
}
public static string GetAddress(this HistoricalAddressInvoiceData historicalAddressInvoiceData)
{
if (historicalAddressInvoiceData.Address == null)
return null;
var index = historicalAddressInvoiceData.Address.IndexOf("#", StringComparison.InvariantCulture);
if (index == -1)
return historicalAddressInvoiceData.Address;
return historicalAddressInvoiceData.Address.Substring(0, index);
}
public static HistoricalAddressInvoiceData SetAddress(this HistoricalAddressInvoiceData historicalAddressInvoiceData, string depositAddress, string cryptoCode)
{
historicalAddressInvoiceData.Address = depositAddress + "#" + cryptoCode;
historicalAddressInvoiceData.CryptoCode = cryptoCode;
return historicalAddressInvoiceData;
}
#pragma warning restore CS0618
}
}

View File

@ -36,13 +36,7 @@ namespace BTCPayServer.HostedServices
_Dirty = true;
}
public void UnaffectAddresses()
{
_Unaffect = true;
}
public bool Dirty => _Dirty;
public bool Unaffect => _Unaffect;
bool _IsBlobUpdated;
public bool IsBlobUpdated => _IsBlobUpdated;
@ -84,7 +78,6 @@ namespace BTCPayServer.HostedServices
if (invoice.Status == InvoiceStatusLegacy.New && invoice.ExpirationTime <= DateTimeOffset.UtcNow)
{
context.MarkDirty();
context.UnaffectAddresses();
invoice.Status = InvoiceStatusLegacy.Expired;
var paidPartial = invoice.ExceptionStatus == InvoiceExceptionStatus.PaidPartial;
context.Events.Add(new InvoiceEvent(invoice, InvoiceEvent.Expired) { PaidPartial = paidPartial });
@ -133,7 +126,6 @@ namespace BTCPayServer.HostedServices
{
invoice.ExceptionStatus = accounting.Paid > accounting.TotalDue ? InvoiceExceptionStatus.PaidOver : InvoiceExceptionStatus.None;
}
context.UnaffectAddresses();
context.MarkDirty();
}
else if (invoice.Status == InvoiceStatusLegacy.Expired && invoice.ExceptionStatus != InvoiceExceptionStatus.PaidLate)
@ -186,14 +178,12 @@ namespace BTCPayServer.HostedServices
// And not enough amount confirmed
(confirmedAccounting.Paid < accounting.MinimumTotalDue))
{
context.UnaffectAddresses();
context.Events.Add(new InvoiceEvent(invoice, InvoiceEvent.FailedToConfirm));
invoice.Status = InvoiceStatusLegacy.Invalid;
context.MarkDirty();
}
else if (confirmedAccounting.Paid >= accounting.MinimumTotalDue)
{
context.UnaffectAddresses();
invoice.Status = InvoiceStatusLegacy.Confirmed;
context.Events.Add(new InvoiceEvent(invoice, InvoiceEvent.Confirmed));
context.MarkDirty();
@ -329,10 +319,6 @@ namespace BTCPayServer.HostedServices
break;
var updateContext = new UpdateInvoiceContext(invoice);
UpdateInvoice(updateContext);
if (updateContext.Unaffect)
{
await _invoiceRepository.UnaffectAddress(invoice.Id);
}
if (updateContext.Dirty)
{
await _invoiceRepository.UpdateInvoiceStatus(invoice.Id, invoice.GetInvoiceState());

View File

@ -120,7 +120,6 @@ namespace BTCPayServer.Models.InvoicingModels
set;
}
public InvoiceMetadata TypedMetadata { get; set; }
public AddressModel[] Addresses { get; set; }
public DateTimeOffset MonitoringDate { get; internal set; }
public List<Data.InvoiceEventData> Events { get; internal set; }
public string NotificationEmail { get; internal set; }

View File

@ -430,7 +430,6 @@ namespace BTCPayServer.Services.Invoices
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
public DateTimeOffset MonitoringExpiration { get; set; }
public HistoricalAddressInvoiceData[] HistoricalAddresses { get; set; }
public HashSet<string> AvailableAddressHashes { get; set; }
public bool ExtendedNotifications { get; set; }

View File

@ -183,12 +183,6 @@ namespace BTCPayServer.Services.Invoices
InvoiceDataId = invoice.Id,
CreatedTime = DateTimeOffset.UtcNow,
}.Set(address, paymentMethod.GetId()));
await context.HistoricalAddressInvoices.AddAsync(new HistoricalAddressInvoiceData()
{
InvoiceDataId = invoice.Id,
Assigned = DateTimeOffset.UtcNow
}.SetAddress(paymentDestination, paymentMethod.GetId().ToString()));
textSearch.Add(paymentDestination);
textSearch.Add(paymentMethod.Calculate().TotalDue.ToString());
}
@ -270,10 +264,6 @@ namespace BTCPayServer.Services.Invoices
return false;
var existingPaymentMethod = paymentMethod.GetPaymentMethodDetails();
if (existingPaymentMethod.GetPaymentDestination() != null)
{
MarkUnassigned(invoiceId, context, paymentMethod.GetId());
}
paymentMethod.SetPaymentMethodDetails(paymentMethodDetails);
#pragma warning disable CS0618
if (network.IsBTC)
@ -290,11 +280,6 @@ namespace BTCPayServer.Services.Invoices
CreatedTime = DateTimeOffset.UtcNow
}
.Set(GetDestination(paymentMethod), paymentMethod.GetId()));
await context.HistoricalAddressInvoices.AddAsync(new HistoricalAddressInvoiceData()
{
InvoiceDataId = invoiceId,
Assigned = DateTimeOffset.UtcNow
}.SetAddress(paymentMethodDetails.GetPaymentDestination(), network.CryptoCode));
AddToTextSearch(context, invoice, paymentMethodDetails.GetPaymentDestination());
await context.SaveChangesAsync();
@ -319,11 +304,6 @@ namespace BTCPayServer.Services.Invoices
CreatedTime = DateTimeOffset.UtcNow
}
.Set(GetDestination(paymentMethod), paymentMethod.GetId()));
await context.HistoricalAddressInvoices.AddAsync(new HistoricalAddressInvoiceData()
{
InvoiceDataId = invoiceId,
Assigned = DateTimeOffset.UtcNow
}.SetAddress(paymentMethod.GetPaymentMethodDetails().GetPaymentDestination(), network.CryptoCode));
}
invoiceEntity.SetPaymentMethod(paymentMethod);
invoice.Blob = ToBytes(invoiceEntity, network);
@ -363,33 +343,6 @@ namespace BTCPayServer.Services.Invoices
catch (DbUpdateException) { } // Probably the invoice does not exists anymore
}
private static void MarkUnassigned(string invoiceId, ApplicationDbContext context,
PaymentMethodId paymentMethodId)
{
var paymentMethodIdStr = paymentMethodId?.ToString();
var addresses = context.HistoricalAddressInvoices.Where(data =>
(data.InvoiceDataId == invoiceId && paymentMethodIdStr == null ||
#pragma warning disable CS0618 // Type or member is obsolete
data.CryptoCode == paymentMethodIdStr) &&
#pragma warning restore CS0618 // Type or member is obsolete
data.UnAssigned == null);
foreach (var historicalAddressInvoiceData in addresses)
{
historicalAddressInvoiceData.UnAssigned = DateTimeOffset.UtcNow;
}
}
public async Task UnaffectAddress(string invoiceId)
{
await using var context = _applicationDbContextFactory.CreateContext();
MarkUnassigned(invoiceId, context, null);
try
{
await context.SaveChangesAsync();
}
catch (DbUpdateException) { } //Possibly, it was unassigned before
}
public static void AddToTextSearch(ApplicationDbContext context, InvoiceData invoice, params string[] terms)
{
var filteredTerms = terms.Where(t => !string.IsNullOrWhiteSpace(t)
@ -564,7 +517,7 @@ namespace BTCPayServer.Services.Invoices
.Invoices
.Include(o => o.Payments);
if (includeAddressData)
query = query.Include(o => o.HistoricalAddressInvoices).Include(o => o.AddressInvoices);
query = query.Include(o => o.AddressInvoices);
query = query.Where(i => i.Id == id);
var invoice = (await query.ToListAsync()).FirstOrDefault();
@ -605,10 +558,6 @@ namespace BTCPayServer.Services.Invoices
entity.Status = state.Status;
entity.RefundMail = invoice.CustomerEmail;
entity.Refundable = false;
if (invoice.HistoricalAddressInvoices != null)
{
entity.HistoricalAddresses = invoice.HistoricalAddressInvoices.ToArray();
}
if (invoice.AddressInvoices != null)
{
entity.AvailableAddressHashes = invoice.AddressInvoices.Select(a => a.GetAddress() + a.GetPaymentMethodId().ToString()).ToHashSet();
@ -742,7 +691,7 @@ namespace BTCPayServer.Services.Invoices
var query = GetInvoiceQuery(context, queryObject);
query = query.Include(o => o.Payments);
if (queryObject.IncludeAddresses)
query = query.Include(o => o.HistoricalAddressInvoices).Include(o => o.AddressInvoices);
query = query.Include(o => o.AddressInvoices);
if (queryObject.IncludeEvents)
query = query.Include(o => o.Events);
var data = await query.ToArrayAsync().ConfigureAwait(false);