Persist offchain transactions

This commit is contained in:
nicolas.dorier 2020-04-16 14:25:52 +09:00
parent 00d1c4ebcc
commit 7434163848
No known key found for this signature in database
GPG Key ID: 6618763EF09186FE
7 changed files with 73 additions and 19 deletions

View File

@ -48,6 +48,8 @@ namespace BTCPayServer.Data
get; set;
}
public DbSet<OffchainTransactionData> OffchainTransactions { get; set; }
public DbSet<HistoricalAddressInvoiceData> HistoricalAddressInvoices
{
get; set;

View File

@ -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; }
}
}

View File

@ -33,6 +33,17 @@ namespace BTCPayServer.Migrations
{
table.PrimaryKey("PK_PayjoinLocks", x => x.Id);
});
migrationBuilder.CreateTable(
name: "OffchainTransactions",
columns: table => new
{
Id = table.Column<string>(maxLength: 64, nullable: false),
Blob = table.Column<byte[]>(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");
}
}
}

View File

@ -240,6 +240,20 @@ namespace BTCPayServer.Migrations
b.ToTable("InvoiceEvents");
});
modelBuilder.Entity("BTCPayServer.Data.OffchainTransactionData", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT")
.HasMaxLength(64);
b.Property<byte[]>("Blob")
.HasColumnType("BLOB");
b.HasKey("Id");
b.ToTable("OffchainTransactions");
});
modelBuilder.Entity("BTCPayServer.Data.PairedSINData", b =>
{
b.Property<string>("Id")

View File

@ -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;
}

View File

@ -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<Transaction> GetOffchainTransactionAsync(uint256 txid)
public async Task<Transaction> 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<uint256, Transaction> offchain = new Dictionary<uint256, Transaction>();
public void InvalidateCache(DerivationStrategyBase strategy)
{

View File

@ -14,6 +14,7 @@ namespace BTCPayServer.Services.Wallets
IOptions<MemoryCacheOptions> _Options;
public BTCPayWalletProvider(ExplorerClientProvider client,
IOptions<MemoryCacheOptions> 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));
}
}