diff --git a/BTCPayServer.Data/Data/ApplicationDbContext.cs b/BTCPayServer.Data/Data/ApplicationDbContext.cs index 50cca746d..802ffae8e 100644 --- a/BTCPayServer.Data/Data/ApplicationDbContext.cs +++ b/BTCPayServer.Data/Data/ApplicationDbContext.cs @@ -48,6 +48,8 @@ namespace BTCPayServer.Data get; set; } + public DbSet OffchainTransactions { get; set; } + public DbSet HistoricalAddressInvoices { get; set; diff --git a/BTCPayServer.Data/Data/OffchainTransactionData.cs b/BTCPayServer.Data/Data/OffchainTransactionData.cs new file mode 100644 index 000000000..1541e29ad --- /dev/null +++ b/BTCPayServer.Data/Data/OffchainTransactionData.cs @@ -0,0 +1,12 @@ +using System.ComponentModel.DataAnnotations; + +namespace BTCPayServer.Data +{ + public class OffchainTransactionData + { + [Key] + [MaxLength(32*2)] + public string Id { get; set; } + public byte[] Blob { get; set; } + } +} diff --git a/BTCPayServer.Data/Migrations/20200413052418_PlannedTransactions.cs b/BTCPayServer.Data/Migrations/20200413052418_PlannedTransactions.cs index a011925c7..56419b9fc 100644 --- a/BTCPayServer.Data/Migrations/20200413052418_PlannedTransactions.cs +++ b/BTCPayServer.Data/Migrations/20200413052418_PlannedTransactions.cs @@ -33,6 +33,17 @@ namespace BTCPayServer.Migrations { table.PrimaryKey("PK_PayjoinLocks", x => x.Id); }); + migrationBuilder.CreateTable( + name: "OffchainTransactions", + columns: table => new + { + Id = table.Column(maxLength: 64, nullable: false), + Blob = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_OffchainTransactions", x => x.Id); + }); } protected override void Down(MigrationBuilder migrationBuilder) @@ -41,6 +52,8 @@ namespace BTCPayServer.Migrations name: "PayjoinLocks"); migrationBuilder.DropTable( name: "PlannedTransactions"); + migrationBuilder.DropTable( + name: "OffchainTransactions"); } } } diff --git a/BTCPayServer.Data/Migrations/ApplicationDbContextModelSnapshot.cs b/BTCPayServer.Data/Migrations/ApplicationDbContextModelSnapshot.cs index 47add10fe..5548d7f66 100644 --- a/BTCPayServer.Data/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/BTCPayServer.Data/Migrations/ApplicationDbContextModelSnapshot.cs @@ -240,6 +240,20 @@ namespace BTCPayServer.Migrations b.ToTable("InvoiceEvents"); }); + modelBuilder.Entity("BTCPayServer.Data.OffchainTransactionData", b => + { + b.Property("Id") + .HasColumnType("TEXT") + .HasMaxLength(64); + + b.Property("Blob") + .HasColumnType("BLOB"); + + b.HasKey("Id"); + + b.ToTable("OffchainTransactions"); + }); + modelBuilder.Entity("BTCPayServer.Data.PairedSINData", b => { b.Property("Id") diff --git a/BTCPayServer/Payments/PayJoin/PayJoinRepository.cs b/BTCPayServer/Payments/PayJoin/PayJoinRepository.cs index 87998db13..aee51c3b6 100644 --- a/BTCPayServer/Payments/PayJoin/PayJoinRepository.cs +++ b/BTCPayServer/Payments/PayJoin/PayJoinRepository.cs @@ -28,7 +28,7 @@ namespace BTCPayServer.Payments.PayJoin { return await ctx.SaveChangesAsync() == 1; } - catch (DbUpdateException e) + catch (DbUpdateException) { return false; } @@ -48,7 +48,7 @@ namespace BTCPayServer.Payments.PayJoin { return await ctx.SaveChangesAsync() == outPoints.Length; } - catch (DbUpdateException e) + catch (DbUpdateException) { return false; } @@ -70,7 +70,7 @@ namespace BTCPayServer.Payments.PayJoin { return await ctx.SaveChangesAsync() == outPoints.Length; } - catch (DbUpdateException e) + catch (DbUpdateException) { return false; } diff --git a/BTCPayServer/Services/Wallets/BTCPayWallet.cs b/BTCPayServer/Services/Wallets/BTCPayWallet.cs index d50de425b..16abb602e 100644 --- a/BTCPayServer/Services/Wallets/BTCPayWallet.cs +++ b/BTCPayServer/Services/Wallets/BTCPayWallet.cs @@ -13,6 +13,7 @@ using NBXplorer.Models; using Microsoft.Extensions.Caching.Memory; using BTCPayServer.Logging; using System.Collections.Concurrent; +using Microsoft.EntityFrameworkCore; namespace BTCPayServer.Services.Wallets { @@ -40,7 +41,8 @@ namespace BTCPayServer.Services.Wallets { private ExplorerClient _Client; private IMemoryCache _MemoryCache; - public BTCPayWallet(ExplorerClient client, IMemoryCache memoryCache, BTCPayNetwork network) + public BTCPayWallet(ExplorerClient client, IMemoryCache memoryCache, BTCPayNetwork network, + ApplicationDbContextFactory dbContextFactory) { if (client == null) throw new ArgumentNullException(nameof(client)); @@ -48,11 +50,14 @@ namespace BTCPayServer.Services.Wallets throw new ArgumentNullException(nameof(memoryCache)); _Client = client; _Network = network; + _dbContextFactory = dbContextFactory; _MemoryCache = memoryCache; } private readonly BTCPayNetwork _Network; + private readonly ApplicationDbContextFactory _dbContextFactory; + public BTCPayNetwork Network { get @@ -118,24 +123,31 @@ namespace BTCPayServer.Services.Wallets return tx; } - public Task GetOffchainTransactionAsync(uint256 txid) + public async Task GetOffchainTransactionAsync(uint256 txid) { - lock (offchain) + using var ctx = this._dbContextFactory.CreateContext(); + var txData = await ctx.OffchainTransactions.FindAsync(txid.ToString()); + if (txData is null) + return null; + return Transaction.Load(txData.Blob, this._Network.NBitcoinNetwork); + } + public async Task SaveOffchainTransactionAsync(Transaction tx) + { + using var ctx = this._dbContextFactory.CreateContext(); + ctx.OffchainTransactions.Add(new OffchainTransactionData() + { + Id = tx.GetHash().ToString(), + Blob = tx.ToBytes() + }); + try + { + await ctx.SaveChangesAsync(); + } + // Already in db + catch (DbUpdateException) { - return Task.FromResult(offchain.TryGet(txid)); } } - public Task SaveOffchainTransactionAsync(Transaction tx) - { - // TODO: Save in database - lock (offchain) - { - offchain.Add(tx.GetHash(), tx); - return Task.CompletedTask; - } - } - - private Dictionary offchain = new Dictionary(); public void InvalidateCache(DerivationStrategyBase strategy) { diff --git a/BTCPayServer/Services/Wallets/BTCPayWalletProvider.cs b/BTCPayServer/Services/Wallets/BTCPayWalletProvider.cs index a70b50014..33e49a52f 100644 --- a/BTCPayServer/Services/Wallets/BTCPayWalletProvider.cs +++ b/BTCPayServer/Services/Wallets/BTCPayWalletProvider.cs @@ -14,6 +14,7 @@ namespace BTCPayServer.Services.Wallets IOptions _Options; public BTCPayWalletProvider(ExplorerClientProvider client, IOptions memoryCacheOption, + Data.ApplicationDbContextFactory dbContextFactory, BTCPayNetworkProvider networkProvider) { if (client == null) @@ -27,7 +28,7 @@ namespace BTCPayServer.Services.Wallets var explorerClient = _Client.GetExplorerClient(network.CryptoCode); if (explorerClient == null) continue; - _Wallets.Add(network.CryptoCode.ToUpperInvariant(), new BTCPayWallet(explorerClient, new MemoryCache(_Options), network)); + _Wallets.Add(network.CryptoCode.ToUpperInvariant(), new BTCPayWallet(explorerClient, new MemoryCache(_Options), network, dbContextFactory)); } }