Merge remote-tracking branch 'btcpayserver/master' into feature/order-tolerance

This commit is contained in:
Andrew Camilleri
2018-05-04 17:46:39 +02:00
5 changed files with 33 additions and 16 deletions

View File

@@ -113,12 +113,21 @@ namespace BTCPayServer.Tests
builder.AppendLine("DOGE_BTC = 2000");
Assert.True(RateRules.TryParse(builder.ToString(), out rules));
rules.GlobalMultiplier = 1.1m;
rule2 = rules.GetRuleFor(CurrencyPair.Parse("DOGE_USD"));
Assert.Equal("(2000 * (-3 + coinbase(BTC_CAD) + 50 - 5)) * 1.1", rule2.ToString());
rule2.ExchangeRates.SetRate("coinbase", CurrencyPair.Parse("BTC_CAD"), 1000m);
Assert.True(rule2.Reevaluate());
Assert.Equal("(2000 * (-3 + 1000 + 50 - 5)) * 1.1", rule2.ToString(true));
Assert.Equal((2000m * (-3m + 1000m + 50m - 5m)) * 1.1m, rule2.Value.Value);
// Test inverse
rule2 = rules.GetRuleFor(CurrencyPair.Parse("USD_DOGE"));
Assert.Equal("(1 / (2000 * (-3 + coinbase(BTC_CAD) + 50 - 5))) * 1.1", rule2.ToString());
rule2.ExchangeRates.SetRate("coinbase", CurrencyPair.Parse("BTC_CAD"), 1000m);
Assert.True(rule2.Reevaluate());
Assert.Equal("(1 / (2000 * (-3 + 1000 + 50 - 5))) * 1.1", rule2.ToString(true));
Assert.Equal(( 1.0m / (2000m * (-3m + 1000m + 50m - 5m))) * 1.1m, rule2.Value.Value);
////////
}
}

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<Version>1.0.2.2</Version>
<Version>1.0.2.3</Version>
<NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn>
</PropertyGroup>
<ItemGroup>

View File

@@ -90,5 +90,10 @@ namespace BTCPayServer.Rating
{
return $"{Left}_{Right}";
}
public CurrencyPair Inverse()
{
return new CurrencyPair(Right, Left);
}
}
}

View File

@@ -133,28 +133,30 @@ namespace BTCPayServer.Rating
if (currencyPair.Left == "X" || currencyPair.Right == "X")
throw new ArgumentException(paramName: nameof(currencyPair), message: "Invalid X currency");
var candidate = FindBestCandidate(currencyPair);
if (GlobalMultiplier != decimal.One)
{
candidate = CreateExpression($"({candidate}) * {GlobalMultiplier.ToString(CultureInfo.InvariantCulture)}");
}
return new RateRule(this, currencyPair, candidate);
}
public ExpressionSyntax FindBestCandidate(CurrencyPair p)
{
var candidates = new List<(CurrencyPair Pair, int Prioriy, ExpressionSyntax Expression)>();
var invP = p.Inverse();
var candidates = new List<(CurrencyPair Pair, int Prioriy, ExpressionSyntax Expression, bool Inverse)>();
foreach (var pair in new[]
{
(Pair: p, Priority: 0),
(Pair: new CurrencyPair(p.Left, "X"), Priority: 1),
(Pair: new CurrencyPair("X", p.Right), Priority: 1),
(Pair: new CurrencyPair("X", "X"), Priority: 2)
(Pair: p, Priority: 0, Inverse: false),
(Pair: new CurrencyPair(p.Left, "X"), Priority: 1, Inverse: false),
(Pair: new CurrencyPair("X", p.Right), Priority: 1, Inverse: false),
(Pair: new CurrencyPair(invP.Left, "X"), Priority: 2, Inverse: true),
(Pair: new CurrencyPair("X", invP.Right), Priority: 2, Inverse: true),
(Pair: new CurrencyPair("X", "X"), Priority: 3, Inverse: false)
})
{
if (ruleList.ExpressionsByPair.TryGetValue(pair.Pair, out var expression))
{
candidates.Add((pair.Pair, pair.Priority, expression.Expression));
candidates.Add((pair.Pair, pair.Priority, expression.Expression, pair.Inverse));
}
}
if (candidates.Count == 0)
@@ -163,8 +165,9 @@ namespace BTCPayServer.Rating
.OrderBy(c => c.Prioriy)
.ThenBy(c => c.Expression.Span.Start)
.First();
return best.Expression;
return best.Inverse
? CreateExpression($"1 / {invP}")
: best.Expression;
}
internal static ExpressionSyntax CreateExpression(string str)
@@ -364,7 +367,7 @@ namespace BTCPayServer.Rating
string _ExchangeName = null;
public List<RateRulesErrors> Errors = new List<RateRulesErrors>();
const int MaxNestedCount = 6;
const int MaxNestedCount = 8;
public override SyntaxNode VisitIdentifierName(IdentifierNameSyntax node)
{
if (CurrencyPair.TryParse(node.Identifier.ValueText, out var currentPair))

View File

@@ -365,14 +365,14 @@ namespace BTCPayServer.Services.Invoices
var scheme = info.Network.UriScheme;
cryptoInfo.Url = ServerUrl.WithTrailingSlash() + $"i/{paymentId}/{Id}";
if (paymentId.PaymentType == PaymentTypes.BTCLike)
{
var cryptoSuffix = cryptoInfo.CryptoCode == "BTC" ? "" : "/" + cryptoInfo.CryptoCode;
cryptoInfo.PaymentUrls = new NBitpayClient.InvoicePaymentUrls()
{
BIP72 = $"{scheme}:{cryptoInfo.Address}?amount={cryptoInfo.Due}&r={cryptoInfo.Url}",
BIP72b = $"{scheme}:?r={cryptoInfo.Url}",
BIP73 = cryptoInfo.Url,
BIP72 = $"{scheme}:{cryptoInfo.Address}?amount={cryptoInfo.Due}&r={ServerUrl.WithTrailingSlash() + ($"i/{Id}{cryptoSuffix}")}",
BIP72b = $"{scheme}:?r={ServerUrl.WithTrailingSlash() + ($"i/{Id}{cryptoSuffix}")}",
BIP73 = ServerUrl.WithTrailingSlash() + ($"i/{Id}{cryptoSuffix}"),
BIP21 = $"{scheme}:{cryptoInfo.Address}?amount={cryptoInfo.Due}",
};
}