Skip to content
This repository has been archived by the owner on Oct 20, 2023. It is now read-only.

Commit

Permalink
Merge pull request #1077 from oliverw/oliverw
Browse files Browse the repository at this point in the history
Oliverw
  • Loading branch information
Oliver Weichhold authored Jan 8, 2022
2 parents f5a7f1a + 83cbdd2 commit f6ceed6
Show file tree
Hide file tree
Showing 46 changed files with 786 additions and 144 deletions.
14 changes: 14 additions & 0 deletions build-ubuntu-20.04.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

# add dotnet repo
wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb

# install dev-dependencies
sudo apt-get -y install dotnet-sdk-6.0 git cmake build-essential libssl-dev pkg-config libboost-all-dev libsodium-dev libzmq5

(cd src/Miningcore && \
BUILDIR=${1:-../../build} && \
echo "Building into $BUILDIR" && \
dotnet publish -c Release --framework net6.0 -o $BUILDIR)
Binary file added libs/runtimes/win-x64/librandomarq.dll
Binary file not shown.
90 changes: 90 additions & 0 deletions src/Miningcore.Tests/Crypto/RandomARQTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using System;
using System.Text;
using Miningcore.Extensions;
using Miningcore.Native;
using Xunit;

namespace Miningcore.Tests.Crypto;

public class RandomARQTests : TestBase
{
const string realm = "xmr";
private static readonly string seedHex = Encoding.UTF8.GetBytes("test key 000").ToHexString();
private static readonly byte[] input1 = Encoding.UTF8.GetBytes("This is a test");
private static readonly byte[] input2 = Encoding.UTF8.GetBytes("Lorem ipsum dolor sit amet");
private const string hashExpected1 = "27f66e4650eb5657513e76c140e09e59336786f21fbef1ed6ff40fc21538221e";
private const string hashExpected2 = "6b04e883e07e4e6c072cb064d9aed0fa5a8f7cbbeb7fd3ba653d274ebd4925b0";

[Fact]
public void CreateAndDeleteSeed()
{
// creation
RandomARQ.CreateSeed(realm, seedHex);
Assert.True(RandomARQ.realms.ContainsKey(realm));
Assert.True(RandomARQ.realms[realm].ContainsKey(seedHex));

// accessing the created seed should work
Assert.NotNull(RandomARQ.GetSeed(realm, seedHex));

// creating the same realm and key twice should not result in duplicates
RandomARQ.CreateSeed(realm, seedHex);
Assert.Equal(RandomARQ.realms.Count, 1);
Assert.Equal(RandomARQ.realms[realm].Count, 1);

// deletion
RandomARQ.DeleteSeed(realm, seedHex);
Assert.False(RandomARQ.realms[realm].ContainsKey(seedHex));
}

[Fact]
public void CalculateHashSlow()
{
var buf = new byte[32];

// light-mode
RandomARQ.CreateSeed(realm, seedHex);

RandomARQ.CalculateHash("xmr", seedHex, input1, buf);
var result = buf.ToHexString();
Assert.Equal(hashExpected1, result);

Array.Clear(buf, 0, buf.Length);

// second invocation should give the same result
RandomARQ.CalculateHash("xmr", seedHex, input1, buf);
result = buf.ToHexString();
Assert.Equal(hashExpected1, result);

RandomARQ.CalculateHash("xmr", seedHex, input2, buf);
result = buf.ToHexString();
Assert.Equal(hashExpected2, result);

RandomARQ.DeleteSeed(realm, seedHex);
}

[Fact]
public void CalculateHashFast()
{
var buf = new byte[32];

// fast-mode
RandomARQ.CreateSeed(realm, seedHex, null, RandomX.randomx_flags.RANDOMX_FLAG_FULL_MEM);

RandomARQ.CalculateHash("xmr", seedHex, input1, buf);
var result = buf.ToHexString();
Assert.Equal(hashExpected1, result);

Array.Clear(buf, 0, buf.Length);

// second invocation should give the same result
RandomARQ.CalculateHash("xmr", seedHex, input1, buf);
result = buf.ToHexString();
Assert.Equal(hashExpected1, result);

RandomARQ.CalculateHash("xmr", seedHex, input2, buf);
result = buf.ToHexString();
Assert.Equal(hashExpected2, result);

RandomARQ.DeleteSeed(realm, seedHex);
}
}
33 changes: 22 additions & 11 deletions src/Miningcore.Tests/Crypto/RandomXTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Text;
using Miningcore.Extensions;
using Miningcore.Native;
using Xunit;
Expand All @@ -8,9 +9,11 @@ namespace Miningcore.Tests.Crypto;
public class RandomXTests : TestBase
{
const string realm = "xmr";
const string seedHex = "7915d56de262bf23b1fb9104cf5d2a13fcbed2f6b4b9b657309c222b09f54bc0";
private static readonly byte[] data = "0106a2aaafd505583cf50bcc743d04d831d2b119dc94ad88679e359076ee3f18d258ee138b3b42580100a4b1e2f4baf6ab7109071ab59bc52dba740d1de99fa0ae0c4afd6ea9f40c5d87ec01".HexToByteArray();
private const string hashExpected = "55ef9dc0b8e0cb82c609a003c7d99504fc87f5e2dcd31f6fef318fc172cbc887";
private static readonly string seedHex = Encoding.UTF8.GetBytes("test key 000").ToHexString();
private static readonly byte[] input1 = Encoding.UTF8.GetBytes("This is a test");
private static readonly byte[] input2 = Encoding.UTF8.GetBytes("Lorem ipsum dolor sit amet");
private const string hashExpected1 = "639183aae1bf4c9a35884cb46b09cad9175f04efd7684e7262a0ac1c2f0b4e3f";
private const string hashExpected2 = "300a0adb47603dedb42228ccb2b211104f4da45af709cd7547cd049e9489c969";

[Fact]
public void CreateAndDeleteSeed()
Expand Down Expand Up @@ -41,16 +44,20 @@ public void CalculateHashSlow()
// light-mode
RandomX.CreateSeed(realm, seedHex);

RandomX.CalculateHash("xmr", seedHex, data, buf);
RandomX.CalculateHash("xmr", seedHex, input1, buf);
var result = buf.ToHexString();
Assert.Equal(hashExpected, result);
Assert.Equal(hashExpected1, result);

Array.Clear(buf, 0, buf.Length);

// second invocation should give the same result
RandomX.CalculateHash("xmr", seedHex, data, buf);
RandomX.CalculateHash("xmr", seedHex, input1, buf);
result = buf.ToHexString();
Assert.Equal(hashExpected, result);
Assert.Equal(hashExpected1, result);

RandomX.CalculateHash("xmr", seedHex, input2, buf);
result = buf.ToHexString();
Assert.Equal(hashExpected2, result);

RandomX.DeleteSeed(realm, seedHex);
}
Expand All @@ -63,16 +70,20 @@ public void CalculateHashFast()
// fast-mode
RandomX.CreateSeed(realm, seedHex, null, RandomX.randomx_flags.RANDOMX_FLAG_FULL_MEM);

RandomX.CalculateHash("xmr", seedHex, data, buf);
RandomX.CalculateHash("xmr", seedHex, input1, buf);
var result = buf.ToHexString();
Assert.Equal(hashExpected, result);
Assert.Equal(hashExpected1, result);

Array.Clear(buf, 0, buf.Length);

// second invocation should give the same result
RandomX.CalculateHash("xmr", seedHex, data, buf);
RandomX.CalculateHash("xmr", seedHex, input1, buf);
result = buf.ToHexString();
Assert.Equal(hashExpected1, result);

RandomX.CalculateHash("xmr", seedHex, input2, buf);
result = buf.ToHexString();
Assert.Equal(hashExpected, result);
Assert.Equal(hashExpected2, result);

RandomX.DeleteSeed(realm, seedHex);
}
Expand Down
13 changes: 12 additions & 1 deletion src/Miningcore/Api/Controllers/PoolApiController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,11 @@ public async Task<GetPoolsResponse> Get()
public ActionResult GetHelp()
{
var tmp = adcp.ActionDescriptors.Items
.Where(x => x.AttributeRouteInfo != null)
.Select(x =>
{
// Get and pad http method
var method = x?.ActionConstraints?.OfType<HttpMethodActionConstraint>().FirstOrDefault()?.HttpMethods.First();
var method = x.ActionConstraints?.OfType<HttpMethodActionConstraint>().FirstOrDefault()?.HttpMethods.First();
method = $"{method,-5}";

return $"{method} -> {x.AttributeRouteInfo.Template}";
Expand All @@ -102,6 +103,12 @@ public ActionResult GetHelp()
return Content(result);
}

[HttpGet("/api/health-check")]
public ActionResult GetHealthCheck()
{
return Content("👍");
}

[HttpGet("{poolId}")]
public async Task<GetPoolResponse> GetPoolInfoAsync(string poolId)
{
Expand Down Expand Up @@ -346,6 +353,10 @@ public async Task<MinerPerformanceStats[]> PagePoolMinersAsync(
{
stats = mapper.Map<Responses.MinerStats>(statsResult);

// pre-multiply pending shares to cause less confusion with users
if(pool.Template.Family == CoinFamily.Bitcoin)
stats.PendingShares *= pool.Template.As<BitcoinTemplate>().ShareMultiplier;

// optional fields
if(statsResult.LastPayment != null)
{
Expand Down
1 change: 1 addition & 0 deletions src/Miningcore/Blockchain/Bitcoin/BitcoinJobManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Miningcore.Extensions;
using Miningcore.JsonRpc;
using Miningcore.Messaging;
using Miningcore.Rpc;
using Miningcore.Stratum;
using Miningcore.Time;
using Newtonsoft.Json;
Expand Down
1 change: 1 addition & 0 deletions src/Miningcore/Blockchain/Bitcoin/BitcoinJobManagerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Miningcore.Messaging;
using Miningcore.Mining;
using Miningcore.Notifications.Messages;
using Miningcore.Rpc;
using Miningcore.Time;
using NBitcoin;
using Newtonsoft.Json;
Expand Down
1 change: 1 addition & 0 deletions src/Miningcore/Blockchain/Bitcoin/BitcoinPayoutHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Miningcore.Persistence;
using Miningcore.Persistence.Model;
using Miningcore.Persistence.Repositories;
using Miningcore.Rpc;
using Miningcore.Time;
using Miningcore.Util;
using Newtonsoft.Json;
Expand Down
6 changes: 2 additions & 4 deletions src/Miningcore/Blockchain/Bitcoin/BitcoinPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -467,11 +467,9 @@ protected override async Task OnVarDiffUpdateAsync(StratumConnection connection,

context.EnqueueNewDifficulty(newDiff);

// apply immediately and notify client
if(context.HasPendingDifficulty)
// apply immediately and notify
if(context.ApplyPendingDifficulty())
{
context.ApplyPendingDifficulty();

await connection.NotifyAsync(BitcoinStratumMethods.SetDifficulty, new object[] { context.Difficulty });
await connection.NotifyAsync(BitcoinStratumMethods.MiningNotify, currentJobParams);
}
Expand Down
46 changes: 35 additions & 11 deletions src/Miningcore/Blockchain/Cryptonote/CryptonoteJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Miningcore.Stratum;
using Miningcore.Util;
using Org.BouncyCastle.Math;
using static Miningcore.Native.Cryptonight.Algorithm;
using Contract = Miningcore.Contracts.Contract;

namespace Miningcore.Blockchain.Cryptonote;
Expand All @@ -23,19 +24,41 @@ public CryptonoteJob(GetBlockTemplateResponse blockTemplate, byte[] instanceId,
BlockTemplate = blockTemplate;
PrepareBlobTemplate(instanceId);
PrevHash = prevHash;
RandomXRealm = randomXRealm;

switch(coin.Hash)
{
case CryptonightHashType.RandomX:
hashFunc = (seedHex, data, result, height) =>
{
RandomX.CalculateHash(randomXRealm, seedHex, data, result);
};
break;
}
hashFunc = hashFuncs[coin.Hash];
}

public delegate void HashFunc(string seedHex, ReadOnlySpan<byte> data, Span<byte> result, ulong height);
protected delegate void HashFunc(string realm, string seedHex, ReadOnlySpan<byte> data, Span<byte> result, ulong height);

protected static readonly Dictionary<CryptonightHashType, HashFunc> hashFuncs = new()
{
{ CryptonightHashType.RandomX, (realm, seedHex, data, result, _) => RandomX.CalculateHash(realm, seedHex, data, result) },
{ CryptonightHashType.RandomARQ, (realm, seedHex, data, result, _) => RandomARQ.CalculateHash(realm, seedHex, data, result) },
{ CryptonightHashType.Crytonight0, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, CN_0, height) },
{ CryptonightHashType.Crytonight1, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, CN_1, height) },
{ CryptonightHashType.Crytonight2, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, CN_2, height) },
{ CryptonightHashType.CrytonightHalf, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, CN_HALF, height) },
{ CryptonightHashType.CrytonightDouble, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, CN_DOUBLE, height) },
{ CryptonightHashType.CrytonightR, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, CN_R, height) },
{ CryptonightHashType.CrytonightRTO, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, CN_RTO, height) },
{ CryptonightHashType.CrytonightRWZ, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, CN_RWZ, height) },
{ CryptonightHashType.CrytonightZLS, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, CN_ZLS, height) },
{ CryptonightHashType.CrytonightCCX, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, CN_CCX, height) },
{ CryptonightHashType.CrytonightGPU, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, CN_GPU, height) },
{ CryptonightHashType.CrytonightFast, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, CN_FAST, height) },
{ CryptonightHashType.CrytonightXAO, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, CN_XAO, height) },
{ CryptonightHashType.Ghostrider, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, GHOSTRIDER_RTM, height) },
{ CryptonightHashType.CrytonightLite0, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, CN_LITE_0, height) },
{ CryptonightHashType.CrytonightLite1, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, CN_LITE_1, height) },
{ CryptonightHashType.CrytonightHeavy, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, CN_HEAVY_0, height) },
{ CryptonightHashType.CrytonightHeavyXHV, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, CN_HEAVY_XHV, height) },
{ CryptonightHashType.CrytonightHeavyTube, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, CN_HEAVY_TUBE, height) },
{ CryptonightHashType.CrytonightPico, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, CN_PICO_0, height) },
{ CryptonightHashType.ArgonCHUKWA, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, AR2_CHUKWA, height) },
{ CryptonightHashType.ArgonCHUKWAV2, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, AR2_CHUKWA_V2, height) },
{ CryptonightHashType.ArgonWRKZ, (_, _, data, result, height) => Cryptonight.CryptonightHash(data, result, AR2_WRKZ, height) },
};

private byte[] blobTemplate;
private int extraNonce;
Expand Down Expand Up @@ -93,6 +116,7 @@ private void ComputeBlockHash(ReadOnlySpan<byte> blobConverted, Span<byte> resul

public string PrevHash { get; }
public GetBlockTemplateResponse BlockTemplate { get; }
public string RandomXRealm { get; set; }

public void PrepareWorkerJob(CryptonoteWorkerJob workerJob, out string blob, out string target)
{
Expand Down Expand Up @@ -138,7 +162,7 @@ public void PrepareWorkerJob(CryptonoteWorkerJob workerJob, out string blob, out

// hash it
Span<byte> headerHash = stackalloc byte[32];
hashFunc(BlockTemplate.SeedHash, blobConverted, headerHash, BlockTemplate.Height);
hashFunc(RandomXRealm, BlockTemplate.SeedHash, blobConverted, headerHash, BlockTemplate.Height);

var headerHashString = headerHash.ToHexString();
if(headerHashString != workerHash)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using Miningcore.Mining;
using Miningcore.Native;
using Miningcore.Notifications.Messages;
using Miningcore.Rpc;
using Miningcore.Stratum;
using Miningcore.Time;
using Miningcore.Util;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using Miningcore.Persistence;
using Miningcore.Persistence.Model;
using Miningcore.Persistence.Repositories;
using Miningcore.Rpc;
using Miningcore.Time;
using Miningcore.Util;
using Newtonsoft.Json;
Expand Down
4 changes: 1 addition & 3 deletions src/Miningcore/Blockchain/Cryptonote/CryptonotePool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -417,10 +417,8 @@ protected override async Task OnVarDiffUpdateAsync(StratumConnection connection,
// apply immediately and notify client
var context = connection.ContextAs<CryptonoteWorkerContext>();

if(context.HasPendingDifficulty)
if(context.ApplyPendingDifficulty())
{
context.ApplyPendingDifficulty();

// re-send job
var job = CreateWorkerJob(connection);
await connection.NotifyAsync(CryptonoteStratumMethods.JobNotify, job);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ public class ZCashBlockSubsidy
public decimal Miner { get; set; }
public decimal? Founders { get; set; }
public decimal? Community { get; set; }
public decimal? Securenodes { get; set; }
public decimal? Supernodes { get; set; }
public List<FundingStream> FundingStreams { get; set; }
}

Expand Down
18 changes: 18 additions & 0 deletions src/Miningcore/Blockchain/Equihash/EquihashJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,20 @@ protected virtual Transaction CreateOutputTransaction()
tx.Outputs.Add(amount, destination);
}
}
else if(networkParams.vOuts)
{
rewardToPool = new Money(Math.Round(blockReward * (1m - (networkParams.vPercentFoundersReward) / 100m)) + rewardFees, MoneyUnit.Satoshi);
tx.Outputs.Add(rewardToPool, poolAddressDestination);
var destination = FoundersAddressToScriptDestination(networkParams.vTreasuryRewardAddress);
var amount = new Money(Math.Round(blockReward * (networkParams.vPercentTreasuryReward / 100m)), MoneyUnit.Satoshi);
tx.Outputs.Add(amount, destination);
destination = FoundersAddressToScriptDestination(networkParams.vSecureNodesRewardAddress);
amount = new Money(Math.Round(blockReward * (networkParams.percentSecureNodesReward / 100m)), MoneyUnit.Satoshi);
tx.Outputs.Add(amount, destination);
destination = FoundersAddressToScriptDestination(networkParams.vSuperNodesRewardAddress);
amount = new Money(Math.Round(blockReward * (networkParams.percentSuperNodesReward / 100m)), MoneyUnit.Satoshi);
tx.Outputs.Add(amount, destination);
}
else if(networkParams.PayFoundersReward &&
(networkParams.LastFoundersRewardBlockHeight >= BlockTemplate.Height ||
networkParams.TreasuryRewardStartBlockHeight > 0))
Expand Down Expand Up @@ -370,6 +384,10 @@ public virtual void Init(EquihashBlockTemplate blockTemplate, string jobId,
fundingstreamTotal = blockTemplate.Subsidy.FundingStreams.Sum(x => x.Value);
blockReward = (blockTemplate.Subsidy.Miner + fundingstreamTotal) * BitcoinConstants.SatoshisPerBitcoin;
}
else if(networkParams?.vOuts == true)
{
blockReward = (decimal) ((blockTemplate.Subsidy.Miner + blockTemplate.Subsidy.Community + blockTemplate.Subsidy.Securenodes + blockTemplate.Subsidy.Supernodes) * BitcoinConstants.SatoshisPerBitcoin);
}
else if(networkParams?.PayFoundersReward == true)
{
var founders = blockTemplate.Subsidy.Founders ?? blockTemplate.Subsidy.Community;
Expand Down
Loading

0 comments on commit f6ceed6

Please sign in to comment.