Use better time precision for time in PaymentEntity

This commit is contained in:
nicolas.dorier 2020-04-05 23:57:43 +09:00
parent 4c966e2a09
commit 01a8c20ee8
No known key found for this signature in database
GPG Key ID: 6618763EF09186FE
3 changed files with 95 additions and 1 deletions

View File

@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Reflection;
using Newtonsoft.Json;
using NBitcoin.JsonConverters;
namespace BTCPayServer.JsonConverters
{
class DateTimeMilliJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(DateTime).GetTypeInfo().IsAssignableFrom(objectType.GetTypeInfo()) ||
typeof(DateTimeOffset).GetTypeInfo().IsAssignableFrom(objectType.GetTypeInfo()) ||
typeof(DateTimeOffset?).GetTypeInfo().IsAssignableFrom(objectType.GetTypeInfo());
}
static DateTimeOffset unixRef = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.Value == null)
return null;
if (reader.TokenType == JsonToken.Null)
return null;
var result = UnixTimeToDateTime((ulong)(long)reader.Value);
if (objectType == typeof(DateTime))
return result.UtcDateTime;
return result;
}
private DateTimeOffset UnixTimeToDateTime(ulong value)
{
var v = (long)value;
if(v < 0)
throw new FormatException("Invalid datetime (less than 1/1/1970)");
return unixRef + TimeSpan.FromMilliseconds((long)v);
}
private long DateTimeToUnixTime(in DateTime time)
{
var date = ((DateTimeOffset)time).ToUniversalTime();
long v = (long)(date - unixRef).TotalMilliseconds;
if(v < 0)
throw new FormatException("Invalid datetime (less than 1/1/1970)");
return v;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
DateTime time;
if (value is DateTime)
time = (DateTime)value;
else
time = ((DateTimeOffset)value).UtcDateTime;
if (time < UnixTimeToDateTime(0))
time = UnixTimeToDateTime(0).UtcDateTime;
writer.WriteValue(DateTimeToUnixTime(time));
}
}
}

View File

@ -40,6 +40,7 @@ namespace BTCPayServer.Payments.Bitcoin
public BitcoinAddress Address { get; set; }
public IMoney Value { get; set; }
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public PayjoinInformation PayjoinInformation { get; set; }
[JsonIgnore]

View File

@ -16,6 +16,7 @@ using BTCPayServer.Payments;
using NBitpayClient;
using BTCPayServer.Payments.Bitcoin;
using System.ComponentModel.DataAnnotations.Schema;
using BTCPayServer.JsonConverters;
namespace BTCPayServer.Services.Invoices
{
@ -919,10 +920,38 @@ namespace BTCPayServer.Services.Invoices
[JsonIgnore]
public BTCPayNetworkBase Network { get; set; }
public int Version { get; set; }
public DateTimeOffset ReceivedTime
// Old invoices use ReceivedTimeSeconds whose precision is not sufficient
[Obsolete("Use ReceivedTime instead")]
[JsonProperty("receivedTime", DefaultValueHandling = DefaultValueHandling.Ignore)]
public DateTimeOffset? ReceivedTimeSeconds
{
get; set;
}
[Obsolete("Use ReceivedTime instead")]
[JsonProperty("receivedTimeMs", DefaultValueHandling = DefaultValueHandling.Ignore)]
[JsonConverter(typeof(DateTimeMilliJsonConverter))]
public DateTimeOffset? ReceivedTimeMilli
{
get; set;
}
[JsonIgnore]
public DateTimeOffset ReceivedTime
{
get
{
#pragma warning disable 618
return (ReceivedTimeMilli ?? ReceivedTimeSeconds).Value;
#pragma warning restore 618
}
set
{
#pragma warning disable 618
ReceivedTimeMilli = value;
#pragma warning restore 618
}
}
public decimal NetworkFee { get; set; }
[Obsolete("Use ((BitcoinLikePaymentData)GetCryptoPaymentData()).Outpoint")]
public OutPoint Outpoint