diff --git a/src/Miningcore.Tests/Miningcore.Tests.csproj b/src/Miningcore.Tests/Miningcore.Tests.csproj index 1da5ff8bf2..96f0d3d14c 100644 --- a/src/Miningcore.Tests/Miningcore.Tests.csproj +++ b/src/Miningcore.Tests/Miningcore.Tests.csproj @@ -33,12 +33,12 @@ - - - + + + - - + + diff --git a/src/Miningcore/AutofacModule.cs b/src/Miningcore/AutofacModule.cs index ef2b595b9a..3302d19245 100644 --- a/src/Miningcore/AutofacModule.cs +++ b/src/Miningcore/AutofacModule.cs @@ -1,29 +1,30 @@ using System.Reflection; using Autofac; +using Microsoft.AspNetCore.Mvc; +using Microsoft.IO; using Miningcore.Api; using Miningcore.Banning; using Miningcore.Blockchain.Bitcoin; using Miningcore.Blockchain.Conceal; using Miningcore.Blockchain.Cryptonote; using Miningcore.Blockchain.Equihash; +using Miningcore.Blockchain.Ergo; using Miningcore.Blockchain.Ethereum; using Miningcore.Configuration; using Miningcore.Crypto; using Miningcore.Crypto.Hashing.Equihash; +using Miningcore.Crypto.Hashing.Ethash; using Miningcore.Messaging; using Miningcore.Mining; +using Miningcore.Nicehash; using Miningcore.Notifications; using Miningcore.Payments; using Miningcore.Payments.PaymentSchemes; +using Miningcore.Pushover; using Miningcore.Time; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using Module = Autofac.Module; -using Microsoft.AspNetCore.Mvc; -using Microsoft.IO; -using Miningcore.Blockchain.Ergo; -using Miningcore.Nicehash; -using Miningcore.Pushover; namespace Miningcore; @@ -78,7 +79,19 @@ protected override void Load(ContainerBuilder builder) builder.RegisterAssemblyTypes(ThisAssembly) .Where(t => t.GetCustomAttributes().Any() && t.GetInterfaces().Any(i => i.IsAssignableFrom(typeof(IHashAlgorithm)))) - .Named(t=> t.GetCustomAttributes().First().Name) + .Named(t => t.GetCustomAttributes().First().Name) + .PropertiesAutowired(); + + builder.RegisterAssemblyTypes(ThisAssembly) + .Where(t => t.GetCustomAttributes().Any() && + t.GetInterfaces().Any(i => i.IsAssignableFrom(typeof(IEthashFull)))) + .Named(t => t.GetCustomAttributes().First().Name) + .PropertiesAutowired(); + + builder.RegisterAssemblyTypes(ThisAssembly) + .Where(t => t.GetCustomAttributes().Any() && + t.GetInterfaces().Any(i => i.IsAssignableFrom(typeof(IEthashDag)))) + .Named(t => t.GetCustomAttributes().First().Name) .PropertiesAutowired(); builder.RegisterAssemblyTypes(ThisAssembly) @@ -148,12 +161,12 @@ protected override void Load(ContainerBuilder builder) // Bitcoin and family builder.RegisterType(); - + ////////////////////// // Conceal builder.RegisterType(); - + ////////////////////// // Cryptonote diff --git a/src/Miningcore/Blockchain/Conceal/ConcealPool.cs b/src/Miningcore/Blockchain/Conceal/ConcealPool.cs index 99806e9987..cbf5d6012c 100644 --- a/src/Miningcore/Blockchain/Conceal/ConcealPool.cs +++ b/src/Miningcore/Blockchain/Conceal/ConcealPool.cs @@ -314,7 +314,7 @@ protected override async Task SetupJobManager(CancellationToken ct) disposables.Add(manager.Blocks .Select(_ => Observable.FromAsync(() => Guard(OnNewJobAsync, - ex=> logger.Debug(() => $"{nameof(OnNewJobAsync)}: {ex.Message}")))) + ex => logger.Debug(() => $"{nameof(OnNewJobAsync)}: {ex.Message}")))) .Concat() .Subscribe(_ => { }, ex => { @@ -338,7 +338,7 @@ private string GetMinerAlgo() { case CryptonightHashType.CryptonightCCX: return $"cn-ccx"; - + case CryptonightHashType.CryptonightGPU: return $"cn-gpu"; } diff --git a/src/Miningcore/Blockchain/Ethereum/EthereumJob.cs b/src/Miningcore/Blockchain/Ethereum/EthereumJob.cs index a7a181e499..a432f8be5f 100644 --- a/src/Miningcore/Blockchain/Ethereum/EthereumJob.cs +++ b/src/Miningcore/Blockchain/Ethereum/EthereumJob.cs @@ -1,8 +1,6 @@ using System.Globalization; using System.Numerics; -using Miningcore.Crypto.Hashing.Etchash; using Miningcore.Crypto.Hashing.Ethash; -using Miningcore.Crypto.Hashing.Ubqhash; using Miningcore.Extensions; using Miningcore.Stratum; using NBitcoin; @@ -12,11 +10,12 @@ namespace Miningcore.Blockchain.Ethereum; public class EthereumJob { - public EthereumJob(string id, EthereumBlockTemplate blockTemplate, ILogger logger) + public EthereumJob(string id, EthereumBlockTemplate blockTemplate, ILogger logger, IEthashFull ethashFull) { Id = id; BlockTemplate = blockTemplate; this.logger = logger; + this.ethashFull = ethashFull; var target = blockTemplate.Target; if(target.StartsWith("0x")) @@ -31,6 +30,7 @@ public EthereumJob(string id, EthereumBlockTemplate blockTemplate, ILogger logge public EthereumBlockTemplate BlockTemplate { get; } private readonly uint256 blockTarget; private readonly ILogger logger; + private readonly IEthashFull ethashFull; public record SubmitResult(Share Share, string FullNonceHex = null, string HeaderHash = null, string MixHash = null); @@ -52,155 +52,9 @@ private void RegisterNonce(StratumConnection worker, string nonce) nonces.Add(nonceLower); } } - - public async Task ProcessShareEtcHashAsync(StratumConnection worker, - string workerName, string fullNonceHex, EtchashFull etchash, CancellationToken ct) - { - // dupe check - lock(workerNonces) - { - RegisterNonce(worker, fullNonceHex); - } - - var context = worker.ContextAs(); - - if(!ulong.TryParse(fullNonceHex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var fullNonce)) - throw new StratumException(StratumError.MinusOne, "bad nonce " + fullNonceHex); - - // get dag for block - var dag = await etchash.GetDagAsync(BlockTemplate.Height, logger, CancellationToken.None); - - // compute - if(!dag.Compute(logger, BlockTemplate.Header.HexToByteArray(), fullNonce, out var mixDigest, out var resultBytes)) - throw new StratumException(StratumError.MinusOne, "bad hash"); - - // test if share meets at least workers current difficulty - resultBytes.ReverseInPlace(); - var resultValue = new uint256(resultBytes); - var resultValueBig = resultBytes.AsSpan().ToBigInteger(); - var shareDiff = (double) BigInteger.Divide(EthereumConstants.BigMaxValue, resultValueBig) / EthereumConstants.Pow2x32; - var stratumDifficulty = context.Difficulty; - var ratio = shareDiff / stratumDifficulty; - var isBlockCandidate = resultValue <= blockTarget; - - if(!isBlockCandidate && ratio < 0.99) - { - // check if share matched the previous difficulty from before a vardiff retarget - if(context.VarDiff?.LastUpdate != null && context.PreviousDifficulty.HasValue) - { - ratio = shareDiff / context.PreviousDifficulty.Value; - - if(ratio < 0.99) - throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})"); - - // use previous difficulty - stratumDifficulty = context.PreviousDifficulty.Value; - } - - else - throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})"); - } - - var share = new Share - { - BlockHeight = (long) BlockTemplate.Height, - IpAddress = worker.RemoteEndpoint?.Address?.ToString(), - Miner = context.Miner, - Worker = workerName, - UserAgent = context.UserAgent, - IsBlockCandidate = isBlockCandidate, - Difficulty = stratumDifficulty * EthereumConstants.Pow2x32 - }; - - if(share.IsBlockCandidate) - { - fullNonceHex = "0x" + fullNonceHex; - var headerHash = BlockTemplate.Header; - var mixHash = mixDigest.ToHexString(true); - - share.TransactionConfirmationData = ""; - - return new SubmitResult(share, fullNonceHex, headerHash, mixHash); - } - - return new SubmitResult(share); - } public async Task ProcessShareAsync(StratumConnection worker, - string workerName, string fullNonceHex, EthashFull ethash, CancellationToken ct) - { - // dupe check - lock(workerNonces) - { - RegisterNonce(worker, fullNonceHex); - } - - var context = worker.ContextAs(); - - if(!ulong.TryParse(fullNonceHex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var fullNonce)) - throw new StratumException(StratumError.MinusOne, "bad nonce " + fullNonceHex); - - // get dag for block - var dag = await ethash.GetDagAsync(BlockTemplate.Height, logger, CancellationToken.None); - - // compute - if(!dag.Compute(logger, BlockTemplate.Header.HexToByteArray(), fullNonce, out var mixDigest, out var resultBytes)) - throw new StratumException(StratumError.MinusOne, "bad hash"); - - // test if share meets at least workers current difficulty - resultBytes.ReverseInPlace(); - var resultValue = new uint256(resultBytes); - var resultValueBig = resultBytes.AsSpan().ToBigInteger(); - var shareDiff = (double) BigInteger.Divide(EthereumConstants.BigMaxValue, resultValueBig) / EthereumConstants.Pow2x32; - var stratumDifficulty = context.Difficulty; - var ratio = shareDiff / stratumDifficulty; - var isBlockCandidate = resultValue <= blockTarget; - - if(!isBlockCandidate && ratio < 0.99) - { - // check if share matched the previous difficulty from before a vardiff retarget - if(context.VarDiff?.LastUpdate != null && context.PreviousDifficulty.HasValue) - { - ratio = shareDiff / context.PreviousDifficulty.Value; - - if(ratio < 0.99) - throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})"); - - // use previous difficulty - stratumDifficulty = context.PreviousDifficulty.Value; - } - - else - throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})"); - } - - var share = new Share - { - BlockHeight = (long) BlockTemplate.Height, - IpAddress = worker.RemoteEndpoint?.Address?.ToString(), - Miner = context.Miner, - Worker = workerName, - UserAgent = context.UserAgent, - IsBlockCandidate = isBlockCandidate, - Difficulty = stratumDifficulty * EthereumConstants.Pow2x32 - }; - - if(share.IsBlockCandidate) - { - fullNonceHex = "0x" + fullNonceHex; - var headerHash = BlockTemplate.Header; - var mixHash = mixDigest.ToHexString(true); - - share.TransactionConfirmationData = ""; - - return new SubmitResult(share, fullNonceHex, headerHash, mixHash); - } - - return new SubmitResult(share); - } - - public async Task ProcessShareUbqHashAsync(StratumConnection worker, - string workerName, string fullNonceHex, UbqhashFull ubqhash, CancellationToken ct) + string workerName, string fullNonceHex, CancellationToken ct) { // dupe check lock(workerNonces) @@ -214,7 +68,7 @@ public async Task ProcessShareUbqHashAsync(StratumConnection worke throw new StratumException(StratumError.MinusOne, "bad nonce " + fullNonceHex); // get dag for block - var dag = await ubqhash.GetDagAsync(BlockTemplate.Height, logger, CancellationToken.None); + var dag = await ethashFull.GetDagAsync(BlockTemplate.Height, logger, CancellationToken.None); // compute if(!dag.Compute(logger, BlockTemplate.Header.HexToByteArray(), fullNonce, out var mixDigest, out var resultBytes)) diff --git a/src/Miningcore/Blockchain/Ethereum/EthereumJobManager.cs b/src/Miningcore/Blockchain/Ethereum/EthereumJobManager.cs index e1a82b7696..d65c629974 100644 --- a/src/Miningcore/Blockchain/Ethereum/EthereumJobManager.cs +++ b/src/Miningcore/Blockchain/Ethereum/EthereumJobManager.cs @@ -1,5 +1,6 @@ using System.Globalization; using System.Numerics; +using System.Reactive; using System.Reactive.Linq; using System.Reactive.Threading.Tasks; using System.Text; @@ -8,25 +9,22 @@ using Miningcore.Blockchain.Ethereum.Configuration; using Miningcore.Blockchain.Ethereum.DaemonResponses; using Miningcore.Configuration; -using Miningcore.Crypto.Hashing.Etchash; -using Miningcore.Crypto.Hashing.Ethash; -using Miningcore.Crypto.Hashing.Ubqhash; using Miningcore.Extensions; using Miningcore.JsonRpc; using Miningcore.Messaging; +using Miningcore.Mining; using Miningcore.Notifications.Messages; +using Miningcore.Rpc; using Miningcore.Stratum; using Miningcore.Time; +using NBitcoin; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using NLog; +using static Miningcore.Util.ActionUtils; using Block = Miningcore.Blockchain.Ethereum.DaemonResponses.Block; using Contract = Miningcore.Contracts.Contract; using EC = Miningcore.Blockchain.Ethereum.EthCommands; -using static Miningcore.Util.ActionUtils; -using System.Reactive; -using Miningcore.Mining; -using Miningcore.Rpc; -using Newtonsoft.Json.Linq; namespace Miningcore.Blockchain.Ethereum; @@ -48,13 +46,11 @@ public EthereumJobManager( this.extraNonceProvider = extraNonceProvider; } + private EthereumCoinTemplate coin; private DaemonEndpointConfig[] daemonEndpoints; private RpcClient rpc; private EthereumNetworkType networkType; private GethChainType chainType; - private EtchashFull etchash; - private EthashFull ethash; - private UbqhashFull ubqhash; private readonly IMasterClock clock; private readonly IExtraNonceProvider extraNonceProvider; private const int MaxBlockBacklog = 6; @@ -106,7 +102,7 @@ protected bool UpdateJob(EthereumBlockTemplate blockTemplate, string via = null) var jobId = NextJobId("x8"); // update template - job = new EthereumJob(jobId, blockTemplate, logger); + job = new EthereumJob(jobId, blockTemplate, logger, coin.EthashFull); lock(jobLock) { @@ -339,6 +335,7 @@ public object[] GetWorkParamsForStratum(EthereumWorkerContext context) public override void Configure(PoolConfig pc, ClusterConfig cc) { extraPoolConfig = pc.Extra.SafeExtensionDataAs(); + coin = pc.Template.As(); // extract standard daemon endpoints daemonEndpoints = pc.Daemons @@ -350,49 +347,19 @@ public override void Configure(PoolConfig pc, ClusterConfig cc) if(pc.EnableInternalStratum == true) { var coin = pc.Template.As(); - + // ensure dag location is configured - string dagDir = null; - - if(!string.IsNullOrEmpty(extraPoolConfig?.DagDir)) - { - dagDir = Environment.ExpandEnvironmentVariables(extraPoolConfig.DagDir); - } - else - { - // Default DAG folder - switch(coin.Symbol) - { - case "ETC": - dagDir = DagEtchash.GetDefaultDagDirectory(); - break; - case "UBIQ": - dagDir = DagUbqhash.GetDefaultDagDirectory(); - break; - default: - dagDir = Dag.GetDefaultDagDirectory(); - break; - } - } + var dagDir = !string.IsNullOrEmpty(extraPoolConfig?.DagDir) ? + Environment.ExpandEnvironmentVariables(extraPoolConfig.DagDir) : + coin.EthashFull.GetDefaultDagDirectory(); // create it if necessary Directory.CreateDirectory(dagDir); - // setup ethash - switch(coin.Symbol) - { - case "ETC": - var hardForkBlock = extraPoolConfig?.ChainTypeOverride == "Classic" ? EthereumClassicConstants.HardForkBlockMainnet : EthereumClassicConstants.HardForkBlockMordor; - logger.Debug(() => $"Hard fork block on `{extraPoolConfig?.ChainTypeOverride}`: {hardForkBlock}"); - etchash = new EtchashFull(3, dagDir, hardForkBlock); - break; - case "UBIQ": - ubqhash = new UbqhashFull(3, dagDir); - break; - default: - ethash = new EthashFull(3, dagDir); - break; - } + logger.Info(() => $"Ethasher is: {coin.Ethasher}"); + + var hardForkBlock = extraPoolConfig?.ChainTypeOverride == "Classic" ? EthereumClassicConstants.HardForkBlockMainnet : EthereumClassicConstants.HardForkBlockMordor; + coin.EthashFull.Setup(3, dagDir, hardForkBlock); } } @@ -466,86 +433,31 @@ private async Task SubmitShareAsync(StratumConnection worker, EthereumWorkerContext context, string workerName, EthereumJob job, string nonce, CancellationToken ct) { var coin = poolConfig.Template.As(); - - // validate & process - switch(coin.Symbol) - { - case "ETC": - var (shareEtchash, fullNonceHexEtchash, headerHashEtchash, mixHashEtchash) = await job.ProcessShareEtcHashAsync(worker, workerName, nonce, etchash, ct); - - // enrich share with common data - shareEtchash.PoolId = poolConfig.Id; - shareEtchash.NetworkDifficulty = BlockchainStats.NetworkDifficulty; - shareEtchash.Source = clusterConfig.ClusterName; - shareEtchash.Created = clock.Now; - - // if block candidate, submit & check if accepted by network - if(shareEtchash.IsBlockCandidate) - { - logger.Info(() => $"Submitting block {shareEtchash.BlockHeight}"); - - shareEtchash.IsBlockCandidate = await SubmitBlockAsync(shareEtchash, fullNonceHexEtchash, headerHashEtchash, mixHashEtchash); - - if(shareEtchash.IsBlockCandidate) - { - logger.Info(() => $"Daemon accepted block {shareEtchash.BlockHeight} submitted by {context.Miner}"); - - OnBlockFound(); - } - } - - return shareEtchash; - case "UBIQ": - var (shareUbqhash, fullNonceHexUbqhash, headerHashUbqhash, mixHashUbqhash) = await job.ProcessShareUbqHashAsync(worker, workerName, nonce, ubqhash, ct); - - // enrich share with common data - shareUbqhash.PoolId = poolConfig.Id; - shareUbqhash.NetworkDifficulty = BlockchainStats.NetworkDifficulty; - shareUbqhash.Source = clusterConfig.ClusterName; - shareUbqhash.Created = clock.Now; - - // if block candidate, submit & check if accepted by network - if(shareUbqhash.IsBlockCandidate) - { - logger.Info(() => $"Submitting block {shareUbqhash.BlockHeight}"); - shareUbqhash.IsBlockCandidate = await SubmitBlockAsync(shareUbqhash, fullNonceHexUbqhash, headerHashUbqhash, mixHashUbqhash); + var (share, fullNonceHex, headerHash, mixHash) = await job.ProcessShareAsync(worker, workerName, nonce, ct); - if(shareUbqhash.IsBlockCandidate) - { - logger.Info(() => $"Daemon accepted block {shareUbqhash.BlockHeight} submitted by {context.Miner}"); + // enrich share with common data + share.PoolId = poolConfig.Id; + share.NetworkDifficulty = BlockchainStats.NetworkDifficulty; + share.Source = clusterConfig.ClusterName; + share.Created = clock.Now; - OnBlockFound(); - } - } - - return shareUbqhash; - default: - var (share, fullNonceHex, headerHash, mixHash) = await job.ProcessShareAsync(worker, workerName, nonce, ethash, ct); - - // enrich share with common data - share.PoolId = poolConfig.Id; - share.NetworkDifficulty = BlockchainStats.NetworkDifficulty; - share.Source = clusterConfig.ClusterName; - share.Created = clock.Now; - - // if block candidate, submit & check if accepted by network - if(share.IsBlockCandidate) - { - logger.Info(() => $"Submitting block {share.BlockHeight}"); + // if block candidate, submit & check if accepted by network + if(share.IsBlockCandidate) + { + logger.Info(() => $"Submitting block {share.BlockHeight}"); - share.IsBlockCandidate = await SubmitBlockAsync(share, fullNonceHex, headerHash, mixHash); + share.IsBlockCandidate = await SubmitBlockAsync(share, fullNonceHex, headerHash, mixHash); - if(share.IsBlockCandidate) - { - logger.Info(() => $"Daemon accepted block {share.BlockHeight} submitted by {context.Miner}"); + if(share.IsBlockCandidate) + { + logger.Info(() => $"Daemon accepted block {share.BlockHeight} submitted by {context.Miner}"); - OnBlockFound(); - } - } - - return share; + OnBlockFound(); + } } + + return share; } public BlockchainStats BlockchainStats { get; } = new(); @@ -641,8 +553,8 @@ protected override async Task PostStartInitAsync(CancellationToken ct) // Periodically update network stats Observable.Interval(TimeSpan.FromMinutes(10)) .Select(via => Observable.FromAsync(() => - Guard(()=> UpdateNetworkStatsAsync(ct), - ex=> logger.Error(ex)))) + Guard(() => UpdateNetworkStatsAsync(ct), + ex => logger.Error(ex)))) .Concat() .Subscribe(); @@ -658,21 +570,9 @@ protected override async Task PostStartInitAsync(CancellationToken ct) if(blockTemplate != null) { logger.Info(() => "Loading current DAG ..."); - - // setup dag file - switch(coin.Symbol) - { - case "ETC": - await etchash.GetDagAsync(blockTemplate.Height, logger, ct); - break; - case "UBIQ": - await ubqhash.GetDagAsync(blockTemplate.Height, logger, ct); - break; - default: - await ethash.GetDagAsync(blockTemplate.Height, logger, ct); - break; - } - + + await coin.EthashFull.GetDagAsync(blockTemplate.Height, logger, ct); + logger.Info(() => "Loaded current DAG"); break; } @@ -698,7 +598,7 @@ protected virtual async Task SetupJobUpdates(CancellationToken ct) var endpointExtra = daemonEndpoints .Where(x => x.Extra.SafeExtensionDataAs() != null) - .Select(x=> Tuple.Create(x, x.Extra.SafeExtensionDataAs())) + .Select(x => Tuple.Create(x, x.Extra.SafeExtensionDataAs())) .FirstOrDefault(); if(endpointExtra?.Item2?.PortWs.HasValue == true) diff --git a/src/Miningcore/Configuration/ClusterConfig.cs b/src/Miningcore/Configuration/ClusterConfig.cs index 0fa3c07ad1..775c6f4339 100644 --- a/src/Miningcore/Configuration/ClusterConfig.cs +++ b/src/Miningcore/Configuration/ClusterConfig.cs @@ -24,7 +24,7 @@ public enum CoinFamily [EnumMember(Value = "conceal")] Conceal, - + [EnumMember(Value = "cryptonote")] Cryptonote, @@ -435,13 +435,13 @@ public partial class ConcealCoinTemplate : CoinTemplate /// [JsonProperty(Order = -4, DefaultValueHandling = DefaultValueHandling.Include)] public int HashVariant { get; set; } - + /// /// Conceal network hashrate = `Difficulty / DifficultyTarget` /// See: parameter -> DIFFICULTY_TARGET in src/CryptoNoteConfig.h /// public ulong DifficultyTarget { get; set; } - + /// /// Smallest unit for Blockreward formatting /// @@ -578,6 +578,11 @@ public partial class EthereumCoinTemplate : CoinTemplate [DefaultValue(EthereumSubfamily.None)] [JsonConverter(typeof(StringEnumConverter), true)] public EthereumSubfamily Subfamily { get; set; } + + /// + /// Which hashing algorithm to use. (ethash, etchash or ubqhash) + /// + public string Ethasher { get; set; } = "ethash"; } public partial class ErgoCoinTemplate : CoinTemplate @@ -827,7 +832,7 @@ public partial class ClusterPaymentProcessingConfig /// /// Indentifier used in coinbase transactions to identify the pool /// - public string CoinbaseString { get; set; } + public string CoinbaseString { get; set; } } public partial class PersistenceConfig diff --git a/src/Miningcore/Configuration/ClusterConfigExtensions.cs b/src/Miningcore/Configuration/ClusterConfigExtensions.cs index d7c783306b..d24ba57b8c 100644 --- a/src/Miningcore/Configuration/ClusterConfigExtensions.cs +++ b/src/Miningcore/Configuration/ClusterConfigExtensions.cs @@ -4,6 +4,7 @@ using JetBrains.Annotations; using Miningcore.Crypto; using Miningcore.Crypto.Hashing.Algorithms; +using Miningcore.Crypto.Hashing.Ethash; using NBitcoin; using Newtonsoft.Json; @@ -152,11 +153,11 @@ public partial class ConcealCoinTemplate public override string GetAlgorithmName() { -// switch(Hash) -// { -// case CryptonightHashType.RandomX: -// return "RandomX"; -// } + // switch(Hash) + // { + // case CryptonightHashType.RandomX: + // return "RandomX"; + // } return Hash.ToString(); } @@ -170,11 +171,11 @@ public partial class CryptonoteCoinTemplate public override string GetAlgorithmName() { -// switch(Hash) -// { -// case CryptonightHashType.RandomX: -// return "RandomX"; -// } + // switch(Hash) + // { + // case CryptonightHashType.RandomX: + // return "RandomX"; + // } return Hash.ToString(); } @@ -186,9 +187,21 @@ public partial class EthereumCoinTemplate { #region Overrides of CoinTemplate + public EthereumCoinTemplate() + { + ethashFullValue = new Lazy(() => + EthashFactory.GetEthashFull(ComponentContext, Ethasher)); + } + + private readonly Lazy ethashFullValue; + + public IComponentContext ComponentContext { get; [UsedImplicitly] init; } + + public IEthashFull EthashFull => ethashFullValue.Value; + public override string GetAlgorithmName() { - return "Ethhash"; + return EthashFull.AlgoName; } #endregion diff --git a/src/Miningcore/Crypto/Hashing/Ethash/Abstractions.cs b/src/Miningcore/Crypto/Hashing/Ethash/Abstractions.cs new file mode 100644 index 0000000000..602bded2b2 --- /dev/null +++ b/src/Miningcore/Crypto/Hashing/Ethash/Abstractions.cs @@ -0,0 +1,16 @@ +using NLog; + +namespace Miningcore.Crypto.Hashing.Ethash; + +public interface IEthashDag : IDisposable +{ + bool Compute(ILogger logger, byte[] hash, ulong nonce, out byte[] mixDigest, out byte[] result); +} + +public interface IEthashFull : IDisposable +{ + string GetDefaultDagDirectory(); + void Setup(int numCaches, string dagDir, ulong hardForkBlock); + Task GetDagAsync(ulong block, ILogger logger, CancellationToken ct); + string AlgoName { get; } +} \ No newline at end of file diff --git a/src/Miningcore/Crypto/Hashing/Etchash/DagEtchash.cs b/src/Miningcore/Crypto/Hashing/Ethash/Etchash/Dag.cs similarity index 81% rename from src/Miningcore/Crypto/Hashing/Etchash/DagEtchash.cs rename to src/Miningcore/Crypto/Hashing/Ethash/Etchash/Dag.cs index 447c372cef..33bf49a0e4 100644 --- a/src/Miningcore/Crypto/Hashing/Etchash/DagEtchash.cs +++ b/src/Miningcore/Crypto/Hashing/Ethash/Etchash/Dag.cs @@ -8,11 +8,12 @@ using Miningcore.Notifications.Messages; using NLog; -namespace Miningcore.Crypto.Hashing.Etchash; +namespace Miningcore.Crypto.Hashing.Ethash.Etchash; -public class DagEtchash : IDisposable +[Identifier("etchash")] +public class Dag : IEthashDag { - public DagEtchash(ulong epoch) + public Dag(ulong epoch) { Epoch = epoch; } @@ -26,27 +27,6 @@ public DagEtchash(ulong epoch) public DateTime LastUsed { get; set; } - public static unsafe string GetDefaultDagDirectory() - { - var chars = new byte[512]; - - fixed (byte* data = chars) - { - if(EtcHash.ethash_get_default_dirname(data, chars.Length)) - { - int length; - for(length = 0; length < chars.Length; length++) - { - if(data[length] == 0) - break; - } - - return Encoding.UTF8.GetString(data, length); - } - } - - return null; - } public void Dispose() { @@ -77,7 +57,7 @@ await Task.Run(() => var started = DateTime.Now; var block = Epoch * dagEpochLength; - + logger.Debug(() => $"Epoch length used: {dagEpochLength}"); // Generate a temporary cache @@ -125,7 +105,7 @@ public unsafe bool Compute(ILogger logger, byte[] hash, ulong nonce, out byte[] var value = new EtcHash.ethash_return_value(); - fixed (byte* input = hash) + fixed(byte* input = hash) { EtcHash.ethash_full_compute(handle, input, nonce, ref value); } diff --git a/src/Miningcore/Crypto/Hashing/Etchash/EtchashFull.cs b/src/Miningcore/Crypto/Hashing/Ethash/Etchash/EtchashFull.cs similarity index 70% rename from src/Miningcore/Crypto/Hashing/Etchash/EtchashFull.cs rename to src/Miningcore/Crypto/Hashing/Ethash/Etchash/EtchashFull.cs index a5edd7aa0b..215d7c93b7 100644 --- a/src/Miningcore/Crypto/Hashing/Etchash/EtchashFull.cs +++ b/src/Miningcore/Crypto/Hashing/Ethash/Etchash/EtchashFull.cs @@ -1,15 +1,20 @@ +using System.Text; using Miningcore.Blockchain.Ethereum; using Miningcore.Contracts; +using Miningcore.Native; using NLog; -namespace Miningcore.Crypto.Hashing.Etchash; -public class EtchashFull : IDisposable +namespace Miningcore.Crypto.Hashing.Ethash.Etchash; + +[Identifier("etchash")] +public class EtchashFull : IEthashFull { - public EtchashFull(int numCaches, string dagDir, ulong hardForkBlock) + public void Setup(int numCaches, string dagDir, ulong hardForkBlock) { + Contract.Requires(!string.IsNullOrEmpty(dagDir)); - + this.numCaches = numCaches; this.dagDir = dagDir; this.hardForkBlock = hardForkBlock; @@ -17,10 +22,11 @@ public EtchashFull(int numCaches, string dagDir, ulong hardForkBlock) private int numCaches; // Maximum number of caches to keep before eviction (only init, don't modify) private readonly object cacheLock = new(); - private readonly Dictionary caches = new(); - private DagEtchash future; - private readonly string dagDir; - private readonly ulong hardForkBlock; + private readonly Dictionary caches = new(); + private Dag future; + private string dagDir; + private ulong hardForkBlock; + public string AlgoName { get; } = "Etchash"; public void Dispose() { @@ -28,12 +34,12 @@ public void Dispose() value.Dispose(); } - public async Task GetDagAsync(ulong block, ILogger logger, CancellationToken ct) + public async Task GetDagAsync(ulong block, ILogger logger, CancellationToken ct) { var dagEpochLength = block >= hardForkBlock ? EthereumClassicConstants.EpochLength : EthereumConstants.EpochLength; logger.Debug(() => $"Epoch length used: {dagEpochLength}"); var epoch = block / dagEpochLength; - DagEtchash result; + Dag result; lock(cacheLock) { @@ -66,7 +72,7 @@ public async Task GetDagAsync(ulong block, ILogger logger, Cancellat else { logger.Info(() => $"No pre-generated DAG available, creating new for epoch {epoch}"); - result = new DagEtchash(epoch); + result = new Dag(epoch); } caches[epoch] = result; @@ -76,7 +82,7 @@ public async Task GetDagAsync(ulong block, ILogger logger, Cancellat else if(future == null || future.Epoch <= epoch) { logger.Info(() => $"Pre-generating DAG for epoch {epoch + 1}"); - future = new DagEtchash(epoch + 1); + future = new Dag(epoch + 1); #pragma warning disable 4014 future.GenerateAsync(dagDir, dagEpochLength, logger, ct); @@ -91,4 +97,26 @@ public async Task GetDagAsync(ulong block, ILogger logger, Cancellat return result; } + + public unsafe string GetDefaultDagDirectory() + { + var chars = new byte[512]; + + fixed(byte* data = chars) + { + if(EtcHash.ethash_get_default_dirname(data, chars.Length)) + { + int length; + for(length = 0; length < chars.Length; length++) + { + if(data[length] == 0) + break; + } + + return Encoding.UTF8.GetString(data, length); + } + } + + return null; + } } diff --git a/src/Miningcore/Crypto/Hashing/Ethash/Dag.cs b/src/Miningcore/Crypto/Hashing/Ethash/Ethash/Dag.cs similarity index 82% rename from src/Miningcore/Crypto/Hashing/Ethash/Dag.cs rename to src/Miningcore/Crypto/Hashing/Ethash/Ethash/Dag.cs index 5bb3936d28..dbc941131e 100644 --- a/src/Miningcore/Crypto/Hashing/Ethash/Dag.cs +++ b/src/Miningcore/Crypto/Hashing/Ethash/Ethash/Dag.cs @@ -1,5 +1,4 @@ using System.Diagnostics; -using System.Text; using Miningcore.Blockchain.Ethereum; using Miningcore.Contracts; using Miningcore.Extensions; @@ -8,9 +7,10 @@ using Miningcore.Notifications.Messages; using NLog; -namespace Miningcore.Crypto.Hashing.Ethash; +namespace Miningcore.Crypto.Hashing.Ethash.Ethash; -public class Dag : IDisposable +[Identifier("ethash")] +public class Dag : IEthashDag { public Dag(ulong epoch) { @@ -26,27 +26,6 @@ public Dag(ulong epoch) public DateTime LastUsed { get; set; } - public static unsafe string GetDefaultDagDirectory() - { - var chars = new byte[512]; - - fixed (byte* data = chars) - { - if(EthHash.ethash_get_default_dirname(data, chars.Length)) - { - int length; - for(length = 0; length < chars.Length; length++) - { - if(data[length] == 0) - break; - } - - return Encoding.UTF8.GetString(data, length); - } - } - - return null; - } public void Dispose() { @@ -123,7 +102,7 @@ public unsafe bool Compute(ILogger logger, byte[] hash, ulong nonce, out byte[] var value = new EthHash.ethash_return_value(); - fixed (byte* input = hash) + fixed(byte* input = hash) { EthHash.ethash_full_compute(handle, input, nonce, ref value); } diff --git a/src/Miningcore/Crypto/Hashing/Ethash/EthashFull.cs b/src/Miningcore/Crypto/Hashing/Ethash/Ethash/EthashFull.cs similarity index 73% rename from src/Miningcore/Crypto/Hashing/Ethash/EthashFull.cs rename to src/Miningcore/Crypto/Hashing/Ethash/Ethash/EthashFull.cs index a625010a57..359f5d88e8 100644 --- a/src/Miningcore/Crypto/Hashing/Ethash/EthashFull.cs +++ b/src/Miningcore/Crypto/Hashing/Ethash/Ethash/EthashFull.cs @@ -1,12 +1,15 @@ +using System.Text; using Miningcore.Blockchain.Ethereum; using Miningcore.Contracts; +using Miningcore.Native; using NLog; -namespace Miningcore.Crypto.Hashing.Ethash; +namespace Miningcore.Crypto.Hashing.Ethash.Ethash; -public class EthashFull : IDisposable +[Identifier("ethash")] +public class EthashFull : IEthashFull { - public EthashFull(int numCaches, string dagDir) + public void Setup(int numCaches, string dagDir, ulong hardForkBlock) { Contract.Requires(!string.IsNullOrEmpty(dagDir)); @@ -18,7 +21,8 @@ public EthashFull(int numCaches, string dagDir) private readonly object cacheLock = new(); private readonly Dictionary caches = new(); private Dag future; - private readonly string dagDir; + private string dagDir; + public string AlgoName { get; } = "Ethash"; public void Dispose() { @@ -26,7 +30,7 @@ public void Dispose() value.Dispose(); } - public async Task GetDagAsync(ulong block, ILogger logger, CancellationToken ct) + public async Task GetDagAsync(ulong block, ILogger logger, CancellationToken ct) { var epoch = block / EthereumConstants.EpochLength; Dag result; @@ -87,4 +91,26 @@ public async Task GetDagAsync(ulong block, ILogger logger, CancellationToke return result; } + + public unsafe string GetDefaultDagDirectory() + { + var chars = new byte[512]; + + fixed(byte* data = chars) + { + if(EthHash.ethash_get_default_dirname(data, chars.Length)) + { + int length; + for(length = 0; length < chars.Length; length++) + { + if(data[length] == 0) + break; + } + + return Encoding.UTF8.GetString(data, length); + } + } + + return null; + } } diff --git a/src/Miningcore/Crypto/Hashing/Ethash/EthashFactory.cs b/src/Miningcore/Crypto/Hashing/Ethash/EthashFactory.cs new file mode 100644 index 0000000000..bded75b948 --- /dev/null +++ b/src/Miningcore/Crypto/Hashing/Ethash/EthashFactory.cs @@ -0,0 +1,25 @@ +using System.Collections.Concurrent; +using Autofac; + +namespace Miningcore.Crypto.Hashing.Ethash; + +public static class EthashFactory +{ + private static readonly ConcurrentDictionary cacheFull = new(); + + public static IEthashFull GetEthashFull(IComponentContext ctx, string name) + { + if(name == "") + return null; + + // check cache + if(cacheFull.TryGetValue(name, out var result)) + return result; + + result = ctx.ResolveNamed(name); + + cacheFull.TryAdd(name, result); + + return result; + } +} \ No newline at end of file diff --git a/src/Miningcore/Crypto/Hashing/Ubqhash/DagUbqhash.cs b/src/Miningcore/Crypto/Hashing/Ethash/Ubqhash/Dag.cs similarity index 81% rename from src/Miningcore/Crypto/Hashing/Ubqhash/DagUbqhash.cs rename to src/Miningcore/Crypto/Hashing/Ethash/Ubqhash/Dag.cs index 9902f7cabe..e9882efdeb 100644 --- a/src/Miningcore/Crypto/Hashing/Ubqhash/DagUbqhash.cs +++ b/src/Miningcore/Crypto/Hashing/Ethash/Ubqhash/Dag.cs @@ -8,11 +8,12 @@ using Miningcore.Notifications.Messages; using NLog; -namespace Miningcore.Crypto.Hashing.Ubqhash; +namespace Miningcore.Crypto.Hashing.Ethash.Ubqhash; -public class DagUbqhash : IDisposable +[Identifier("ubqhash")] +public class Dag : IEthashDag { - public DagUbqhash(ulong epoch) + public Dag(ulong epoch) { Epoch = epoch; } @@ -26,28 +27,6 @@ public DagUbqhash(ulong epoch) public DateTime LastUsed { get; set; } - public static unsafe string GetDefaultDagDirectory() - { - var chars = new byte[512]; - - fixed (byte* data = chars) - { - if(UbqHash.ethash_get_default_dirname(data, chars.Length)) - { - int length; - for(length = 0; length < chars.Length; length++) - { - if(data[length] == 0) - break; - } - - return Encoding.UTF8.GetString(data, length); - } - } - - return null; - } - public void Dispose() { if(handle != IntPtr.Zero) @@ -123,7 +102,7 @@ public unsafe bool Compute(ILogger logger, byte[] hash, ulong nonce, out byte[] var value = new UbqHash.ethash_return_value(); - fixed (byte* input = hash) + fixed(byte* input = hash) { UbqHash.ethash_full_compute(handle, input, nonce, ref value); } diff --git a/src/Miningcore/Crypto/Hashing/Ubqhash/UbqhashFull.cs b/src/Miningcore/Crypto/Hashing/Ethash/Ubqhash/UbqhashFull.cs similarity index 68% rename from src/Miningcore/Crypto/Hashing/Ubqhash/UbqhashFull.cs rename to src/Miningcore/Crypto/Hashing/Ethash/Ubqhash/UbqhashFull.cs index dbbb62bc36..85cc0b36b7 100644 --- a/src/Miningcore/Crypto/Hashing/Ubqhash/UbqhashFull.cs +++ b/src/Miningcore/Crypto/Hashing/Ethash/Ubqhash/UbqhashFull.cs @@ -1,12 +1,15 @@ +using System.Text; using Miningcore.Blockchain.Ethereum; using Miningcore.Contracts; +using Miningcore.Native; using NLog; -namespace Miningcore.Crypto.Hashing.Ubqhash; +namespace Miningcore.Crypto.Hashing.Ethash.Ubqhash; -public class UbqhashFull : IDisposable +[Identifier("ubqhash")] +public class UbqhashFull : IEthashFull { - public UbqhashFull(int numCaches, string dagDir) + public void Setup(int numCaches, string dagDir, ulong hardForkBlock) { Contract.Requires(!string.IsNullOrEmpty(dagDir)); @@ -16,9 +19,10 @@ public UbqhashFull(int numCaches, string dagDir) private int numCaches; // Maximum number of caches to keep before eviction (only init, don't modify) private readonly object cacheLock = new(); - private readonly Dictionary caches = new(); - private DagUbqhash future; - private readonly string dagDir; + private readonly Dictionary caches = new(); + private Dag future; + private string dagDir; + public string AlgoName { get; } = "Ubqhash"; public void Dispose() { @@ -26,10 +30,10 @@ public void Dispose() value.Dispose(); } - public async Task GetDagAsync(ulong block, ILogger logger, CancellationToken ct) + public async Task GetDagAsync(ulong block, ILogger logger, CancellationToken ct) { var epoch = block / EthereumConstants.EpochLength; - DagUbqhash result; + Dag result; lock(cacheLock) { @@ -62,7 +66,7 @@ public async Task GetDagAsync(ulong block, ILogger logger, Cancellat else { logger.Info(() => $"No pre-generated DAG available, creating new for epoch {epoch}"); - result = new DagUbqhash(epoch); + result = new Dag(epoch); } caches[epoch] = result; @@ -72,7 +76,7 @@ public async Task GetDagAsync(ulong block, ILogger logger, Cancellat else if(future == null || future.Epoch <= epoch) { logger.Info(() => $"Pre-generating DAG for epoch {epoch + 1}"); - future = new DagUbqhash(epoch + 1); + future = new Dag(epoch + 1); #pragma warning disable 4014 future.GenerateAsync(dagDir, logger, ct); @@ -87,4 +91,26 @@ public async Task GetDagAsync(ulong block, ILogger logger, Cancellat return result; } + + public unsafe string GetDefaultDagDirectory() + { + var chars = new byte[512]; + + fixed(byte* data = chars) + { + if(UbqHash.ethash_get_default_dirname(data, chars.Length)) + { + int length; + for(length = 0; length < chars.Length; length++) + { + if(data[length] == 0) + break; + } + + return Encoding.UTF8.GetString(data, length); + } + } + + return null; + } } diff --git a/src/Miningcore/Miningcore.csproj b/src/Miningcore/Miningcore.csproj index 4e1d428a22..04d397bd75 100644 --- a/src/Miningcore/Miningcore.csproj +++ b/src/Miningcore/Miningcore.csproj @@ -41,46 +41,46 @@ - - + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + - + - + - - - - - - - + + + + + + + - - - + + + - + diff --git a/src/Miningcore/Program.cs b/src/Miningcore/Program.cs index 42bc7761da..6ba8590086 100644 --- a/src/Miningcore/Program.cs +++ b/src/Miningcore/Program.cs @@ -27,7 +27,7 @@ using Miningcore.Configuration; using Miningcore.Crypto.Hashing.Algorithms; using Miningcore.Crypto.Hashing.Equihash; -using Miningcore.Crypto.Hashing.Ethash; +using Miningcore.Crypto.Hashing.Ethash.Ethash; using Miningcore.Extensions; using Miningcore.Messaging; using Miningcore.Mining; @@ -53,9 +53,9 @@ using NLog.Targets; using Prometheus; using WebSocketManager; +using static Miningcore.Util.ActionUtils; using ILogger = NLog.ILogger; using LogLevel = Microsoft.Extensions.Logging.LogLevel; -using static Miningcore.Util.ActionUtils; // ReSharper disable AssignNullToNotNullAttribute // ReSharper disable PossibleNullReferenceException @@ -183,12 +183,12 @@ public static async Task Main(string[] args) }); // NSwag - #if DEBUG +#if DEBUG services.AddOpenApiDocument(settings => { settings.DocumentProcessors.Insert(0, new NSwagDocumentProcessor()); }); - #endif +#endif services.AddResponseCompression(); services.AddCors(); @@ -218,9 +218,9 @@ public static async Task Main(string[] args) "/metrics" }, clusterConfig.Api?.MetricsIpWhitelist); - #if DEBUG +#if DEBUG app.UseOpenApi(); - #endif +#endif app.UseResponseCompression(); app.UseCors(corsPolicyBuilder => corsPolicyBuilder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()); @@ -369,20 +369,20 @@ protected override async Task ExecuteAsync(CancellationToken ct) .Where(config => config.Enabled) .Select(config => RunPool(config, coinTemplates, ct)); - await Guard(()=> Task.WhenAll(tasks), ex => + await Guard(() => Task.WhenAll(tasks), ex => { switch(ex) { case PoolStartupException pse: - { - var _logger = pse.PoolId != null ? LogUtil.GetPoolScopedLogger(GetType(), pse.PoolId) : logger; - _logger.Error(() => $"{pse.Message}"); + { + var _logger = pse.PoolId != null ? LogUtil.GetPoolScopedLogger(GetType(), pse.PoolId) : logger; + _logger.Error(() => $"{pse.Message}"); - logger.Error(() => "Cluster cannot start. Good Bye!"); + logger.Error(() => "Cluster cannot start. Good Bye!"); - hal.StopApplication(); - break; - } + hal.StopApplication(); + break; + } default: throw ex; @@ -533,7 +533,7 @@ private static CommandLineApplication ParseCommandLine(string[] args) versionOption = app.Option("-v|--version", "Version Information", CommandOptionType.NoValue); configFileOption = app.Option("-c|--config ", "Configuration File", CommandOptionType.SingleValue); - dumpConfigOption = app.Option("-dc|--dumpconfig", "Dump the configuration (useful for trouble-shooting typos in the config file)",CommandOptionType.NoValue); + dumpConfigOption = app.Option("-dc|--dumpconfig", "Dump the configuration (useful for trouble-shooting typos in the config file)", CommandOptionType.NoValue); shareRecoveryOption = app.Option("-rs", "Import lost shares using existing recovery file", CommandOptionType.SingleValue); generateSchemaOption = app.Option("-gcs|--generate-config-schema ", "Generate JSON schema from configuration options", CommandOptionType.SingleValue); app.HelpOption("-? | -h | --help"); @@ -560,7 +560,7 @@ private static ClusterConfig ReadConfig(string file) { using(var validatingReader = new JSchemaValidatingReader(jsonReader) { - Schema = LoadSchema() + Schema = LoadSchema() }) { return serializer.Deserialize(validatingReader); @@ -781,8 +781,14 @@ private static async Task PreFlightChecks(IServiceProvider services) EquihashSolver.messageBus = messageBus; EquihashSolver.MaxThreads = clusterConfig.EquihashMaxThreads ?? 1; - // Configure Ethhash - Dag.messageBus = messageBus; + // Configure Ethash + Miningcore.Crypto.Hashing.Ethash.Ethash.Dag.messageBus = messageBus; + + // Configure Etchash + Miningcore.Crypto.Hashing.Ethash.Etchash.Dag.messageBus = messageBus; + + // Configure Ubqhash + Miningcore.Crypto.Hashing.Ethash.Ubqhash.Dag.messageBus = messageBus; // Configure Verthash Verthash.messageBus = messageBus; @@ -823,7 +829,7 @@ private static async Task ConfigurePostgresCompatibilityOptions(IServiceProvider if(enableLegacyTimestampBehavior) { - logger.Info(()=> "Enabling Npgsql Legacy Timestamp Behavior"); + logger.Info(() => "Enabling Npgsql Legacy Timestamp Behavior"); AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true); } @@ -886,7 +892,7 @@ private static void ConfigurePostgres(PostgresConfig pgConfig, ContainerBuilder connectionString.Append($"CommandTimeout={pgConfig.CommandTimeout ?? 300};"); - logger.Debug(()=> $"Using postgres connection string: {connectionString}"); + logger.Debug(() => $"Using postgres connection string: {connectionString}"); // register connection factory builder.RegisterInstance(new PgConnectionFactory(connectionString.ToString())) diff --git a/src/Miningcore/coins.json b/src/Miningcore/coins.json index 80c1c11bdf..064c033599 100644 --- a/src/Miningcore/coins.json +++ b/src/Miningcore/coins.json @@ -4276,7 +4276,8 @@ "uncle": "https://explorer.callisto.network/blocks/$height$" }, "explorerTxLink": "https://explorer.callisto.network/tx/{0}", - "explorerAccountLink": "https://explorer.callisto.network/address/{0}" + "explorerAccountLink": "https://explorer.callisto.network/address/{0}", + "ethasher": "ethash" }, "ethereum": { "name": "Ethereum", @@ -4293,7 +4294,8 @@ "uncle": "https://etherscan.io/uncle/$height$" }, "explorerTxLink": "https://etherscan.io/tx/{0}", - "explorerAccountLink": "https://etherscan.io/address/{0}" + "explorerAccountLink": "https://etherscan.io/address/{0}", + "ethasher": "ethash" }, "ethereumclassic": { "name": "Ethereum Classic", @@ -4310,7 +4312,8 @@ "uncle": "https://blockscout.com/etc/mainnet/block/$height$" }, "explorerTxLink": "https://blockscout.com/etc/mainnet/tx/{0}", - "explorerAccountLink": "https://blockscout.com/etc/mainnet/address/{0}" + "explorerAccountLink": "https://blockscout.com/etc/mainnet/address/{0}", + "ethasher": "etchash" }, "ethereum-pow": { "name": "EthereumPoW", @@ -4327,7 +4330,8 @@ "uncle": "https://www.oklink.com/en/ethw/uncle/$height$" }, "explorerTxLink": "https://www.oklink.com/en/ethw/tx/{0}", - "explorerAccountLink": "https://www.oklink.com/en/ethw/address/{0}" + "explorerAccountLink": "https://www.oklink.com/en/ethw/address/{0}", + "ethasher": "ethash" }, "etherone": { "name": "EtherOne", @@ -4344,7 +4348,8 @@ "uncle": "https://blockscout.etherone.one/uncles/$height$" }, "explorerTxLink": "https://blockscout.etherone.one/tx/{0}", - "explorerAccountLink": "https://blockscout.etherone.one/address/{0}" + "explorerAccountLink": "https://blockscout.etherone.one/address/{0}", + "ethasher": "ethash" }, "pinkchain": { "name": "PinkChain", @@ -4361,7 +4366,8 @@ "uncle": "https://pinkscan.org/uncle/$height$" }, "explorerTxLink": "https://pinkscan.org/tx/{0}", - "explorerAccountLink": "https://pinkscan.org/address/{0}" + "explorerAccountLink": "https://pinkscan.org/address/{0}", + "ethasher": "ethash" }, "ubiq": { "name": "Ubiq", @@ -4378,7 +4384,8 @@ "uncle": "https://ubiqscan.io/uncle/$height$" }, "explorerTxLink": "https://ubiqscan.io/tx/{0}", - "explorerAccountLink": "https://ubiqscan.io/address/{0}" + "explorerAccountLink": "https://ubiqscan.io/address/{0}", + "ethasher": "ubqhash" }, "ergo": { "name": "Ergo", diff --git a/src/Native/libetchash/libetchash.sln b/src/Native/libetchash/libetchash.sln index 3490adb5fe..9264baf453 100644 --- a/src/Native/libetchash/libetchash.sln +++ b/src/Native/libetchash/libetchash.sln @@ -1,31 +1,31 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31229.75 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmultihash", "libetchash.vcxproj", "{2DE74E14-BF6D-4046-951B-8EBC8A1BA009}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Debug|x64.ActiveCfg = Debug|x64 - {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Debug|x64.Build.0 = Debug|x64 - {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Debug|x86.ActiveCfg = Debug|Win32 - {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Debug|x86.Build.0 = Debug|Win32 - {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Release|x64.ActiveCfg = Release|x64 - {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Release|x64.Build.0 = Release|x64 - {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Release|x86.ActiveCfg = Release|Win32 - {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {DDE0FE54-030A-4DFD-98A1-952779FB461F} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31229.75 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmultihash", "libetchash.vcxproj", "{2DE74E14-BF6D-4046-951B-8EBC8A1BA009}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Debug|x64.ActiveCfg = Debug|x64 + {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Debug|x64.Build.0 = Debug|x64 + {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Debug|x86.ActiveCfg = Debug|Win32 + {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Debug|x86.Build.0 = Debug|Win32 + {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Release|x64.ActiveCfg = Release|x64 + {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Release|x64.Build.0 = Release|x64 + {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Release|x86.ActiveCfg = Release|Win32 + {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DDE0FE54-030A-4DFD-98A1-952779FB461F} + EndGlobalSection +EndGlobal diff --git a/src/Native/libetchash/libetchash.vcxproj b/src/Native/libetchash/libetchash.vcxproj index 160fd65676..22b28c95df 100644 --- a/src/Native/libetchash/libetchash.vcxproj +++ b/src/Native/libetchash/libetchash.vcxproj @@ -1,202 +1,202 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942} - Win32Proj - netmultihashnative - 10.0 - libetchash - - - - DynamicLibrary - true - v143 - Unicode - - - DynamicLibrary - false - v143 - true - Unicode - - - DynamicLibrary - true - v143 - Unicode - - - DynamicLibrary - false - v143 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - $(SolutionDir)\..\..\..\..\boost_1_62_0;$(ProjectDir)..\libethhash\windows\include\libsodium;$(IncludePath);$(ProjectDir) - $(SolutionDir)\..\..\..\..\boost_1_62_0\lib32-msvc-14.0;$(LibraryPath) - - - true - $(SolutionDir)\..\..\..\..\boost_1_62_0;$(ProjectDir)..\libethhash\windows\include\libsodium;$(IncludePath);$(ProjectDir) - $(SolutionDir)\..\..\..\..\boost_1_62_0\lib64-msvc-14.0;$(ProjectDir)..\libethhash\windows\lib\x64;$(LibraryPath) - - - false - $(SolutionDir)\..\..\..\..\boost_1_62_0;$(ProjectDir)..\libethhash\windows\include\libsodium;$(IncludePath);$(ProjectDir) - $(SolutionDir)\..\..\..\..\boost_1_62_0\lib32-msvc-14.0;$(LibraryPath) - - - false - $(SolutionDir)\..\..\..\..\boost_1_62_0;$(ProjectDir)..\libethhash\windows\include\libsodium;$(ProjectDir)..\libethhash\windows\include\libsodium;$(IncludePath);$(ProjectDir) - $(SolutionDir)\..\..\..\..\boost_1_62_0\lib64-msvc-14.0;$(LibraryPath) - - - - - - Level3 - Disabled - SODIUM_STATIC;_CRT_SECURE_NO_WARNINGS;HAVE_SSE2 - true - MultiThreadedDebug - stdcpp14 - - - Windows - true - Ws2_32.lib;$(ProjectDir)..\libethhash\windows\lib\x86\libsodium.lib;%(AdditionalDependencies) - - - - - - - Level3 - Disabled - SODIUM_STATIC;_CRT_SECURE_NO_WARNINGS;HAVE_SSE2 - true - MultiThreadedDebug - stdcpp14 - - - Windows - true - Ws2_32.lib;$(ProjectDir)..\libethhash\windows\lib\x64\libsodium.lib;%(AdditionalDependencies) - - - - - - - Level3 - MaxSpeed - true - true - SODIUM_STATIC;_CRT_SECURE_NO_WARNINGS;HAVE_SSE2 - true - MultiThreaded - stdcpp14 - - - Windows - true - true - true - Ws2_32.lib;$(ProjectDir)..\libethhash\windows\lib\x86\libsodium.lib;%(AdditionalDependencies) - - - - - - - Level3 - MaxSpeed - true - true - SODIUM_STATIC;_CRT_SECURE_NO_WARNINGS;HAVE_SSE2 - true - MultiThreaded - stdcpp14 - - - Windows - true - true - true - Ws2_32.lib;$(ProjectDir)..\libethhash\windows\lib\x64\libsodium.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942} + Win32Proj + netmultihashnative + 10.0 + libetchash + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\..\..\..\..\boost_1_62_0;$(ProjectDir)..\libethhash\windows\include\libsodium;$(IncludePath);$(ProjectDir) + $(SolutionDir)\..\..\..\..\boost_1_62_0\lib32-msvc-14.0;$(LibraryPath) + + + true + $(SolutionDir)\..\..\..\..\boost_1_62_0;$(ProjectDir)..\libethhash\windows\include\libsodium;$(IncludePath);$(ProjectDir) + $(SolutionDir)\..\..\..\..\boost_1_62_0\lib64-msvc-14.0;$(ProjectDir)..\libethhash\windows\lib\x64;$(LibraryPath) + + + false + $(SolutionDir)\..\..\..\..\boost_1_62_0;$(ProjectDir)..\libethhash\windows\include\libsodium;$(IncludePath);$(ProjectDir) + $(SolutionDir)\..\..\..\..\boost_1_62_0\lib32-msvc-14.0;$(LibraryPath) + + + false + $(SolutionDir)\..\..\..\..\boost_1_62_0;$(ProjectDir)..\libethhash\windows\include\libsodium;$(ProjectDir)..\libethhash\windows\include\libsodium;$(IncludePath);$(ProjectDir) + $(SolutionDir)\..\..\..\..\boost_1_62_0\lib64-msvc-14.0;$(LibraryPath) + + + + + + Level3 + Disabled + SODIUM_STATIC;_CRT_SECURE_NO_WARNINGS;HAVE_SSE2 + true + MultiThreadedDebug + stdcpp14 + + + Windows + true + Ws2_32.lib;$(ProjectDir)..\libethhash\windows\lib\x86\libsodium.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + SODIUM_STATIC;_CRT_SECURE_NO_WARNINGS;HAVE_SSE2 + true + MultiThreadedDebug + stdcpp14 + + + Windows + true + Ws2_32.lib;$(ProjectDir)..\libethhash\windows\lib\x64\libsodium.lib;%(AdditionalDependencies) + + + + + + + Level3 + MaxSpeed + true + true + SODIUM_STATIC;_CRT_SECURE_NO_WARNINGS;HAVE_SSE2 + true + MultiThreaded + stdcpp14 + + + Windows + true + true + true + Ws2_32.lib;$(ProjectDir)..\libethhash\windows\lib\x86\libsodium.lib;%(AdditionalDependencies) + + + + + + + Level3 + MaxSpeed + true + true + SODIUM_STATIC;_CRT_SECURE_NO_WARNINGS;HAVE_SSE2 + true + MultiThreaded + stdcpp14 + + + Windows + true + true + true + Ws2_32.lib;$(ProjectDir)..\libethhash\windows\lib\x64\libsodium.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Native/libubqhash/libubqhash.sln b/src/Native/libubqhash/libubqhash.sln index 895257b66e..f8af08e076 100644 --- a/src/Native/libubqhash/libubqhash.sln +++ b/src/Native/libubqhash/libubqhash.sln @@ -1,31 +1,31 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31229.75 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmultihash", "libubqhash.vcxproj", "{2DE74E14-BF6D-4046-951B-8EBC8A1BA009}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Debug|x64.ActiveCfg = Debug|x64 - {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Debug|x64.Build.0 = Debug|x64 - {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Debug|x86.ActiveCfg = Debug|Win32 - {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Debug|x86.Build.0 = Debug|Win32 - {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Release|x64.ActiveCfg = Release|x64 - {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Release|x64.Build.0 = Release|x64 - {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Release|x86.ActiveCfg = Release|Win32 - {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {DDE0FE54-030A-4DFD-98A1-952779FB461F} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31229.75 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmultihash", "libubqhash.vcxproj", "{2DE74E14-BF6D-4046-951B-8EBC8A1BA009}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Debug|x64.ActiveCfg = Debug|x64 + {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Debug|x64.Build.0 = Debug|x64 + {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Debug|x86.ActiveCfg = Debug|Win32 + {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Debug|x86.Build.0 = Debug|Win32 + {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Release|x64.ActiveCfg = Release|x64 + {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Release|x64.Build.0 = Release|x64 + {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Release|x86.ActiveCfg = Release|Win32 + {2DE74E14-BF6D-4046-951B-8EBC8A1BA009}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DDE0FE54-030A-4DFD-98A1-952779FB461F} + EndGlobalSection +EndGlobal diff --git a/src/Native/libubqhash/libubqhash.vcxproj b/src/Native/libubqhash/libubqhash.vcxproj index b8d6360b1d..c2d6950bf8 100644 --- a/src/Native/libubqhash/libubqhash.vcxproj +++ b/src/Native/libubqhash/libubqhash.vcxproj @@ -1,205 +1,205 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942} - Win32Proj - netmultihashnative - 10.0 - libubqhash - - - - DynamicLibrary - true - v143 - Unicode - - - DynamicLibrary - false - v143 - true - Unicode - - - DynamicLibrary - true - v143 - Unicode - - - DynamicLibrary - false - v143 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - $(SolutionDir)\..\..\..\..\boost_1_62_0;$(ProjectDir)..\libethhash\windows\include\libsodium;$(IncludePath);$(ProjectDir) - $(SolutionDir)\..\..\..\..\boost_1_62_0\lib32-msvc-14.0;$(LibraryPath) - - - true - $(SolutionDir)\..\..\..\..\boost_1_62_0;$(ProjectDir)..\libethhash\windows\include\libsodium;$(IncludePath);$(ProjectDir) - $(SolutionDir)\..\..\..\..\boost_1_62_0\lib64-msvc-14.0;$(ProjectDir)windows\lib\x64;$(LibraryPath) - - - false - $(SolutionDir)\..\..\..\..\boost_1_62_0;$(ProjectDir)..\libethhash\windows\include\libsodium;$(IncludePath);$(ProjectDir) - $(SolutionDir)\..\..\..\..\boost_1_62_0\lib32-msvc-14.0;$(LibraryPath) - - - false - $(SolutionDir)\..\..\..\..\boost_1_62_0;$(ProjectDir)..\libethhash\windows\include\libsodium;$(ProjectDir)..\libethhash\windows\include\libsodium;$(IncludePath);$(ProjectDir) - $(SolutionDir)\..\..\..\..\boost_1_62_0\lib64-msvc-14.0;$(LibraryPath) - - - - - - Level3 - Disabled - SODIUM_STATIC;_CRT_SECURE_NO_WARNINGS;HAVE_SSE2 - true - MultiThreadedDebug - stdcpp14 - - - Windows - true - Ws2_32.lib;$(ProjectDir)..\libethhash\windows\lib\x86\libsodium.lib;%(AdditionalDependencies) - - - - - - - Level3 - Disabled - SODIUM_STATIC;_CRT_SECURE_NO_WARNINGS;HAVE_SSE2 - true - MultiThreadedDebug - stdcpp14 - - - Windows - true - Ws2_32.lib;$(ProjectDir)..\libethhash\windows\lib\x64\libsodium.lib;%(AdditionalDependencies) - - - - - - - Level3 - MaxSpeed - true - true - SODIUM_STATIC;_CRT_SECURE_NO_WARNINGS;HAVE_SSE2 - true - MultiThreaded - stdcpp14 - - - Windows - true - true - true - Ws2_32.lib;$(ProjectDir)..\libethhash\windows\lib\x86\libsodium.lib;%(AdditionalDependencies) - - - - - - - Level3 - MaxSpeed - true - true - SODIUM_STATIC;_CRT_SECURE_NO_WARNINGS;HAVE_SSE2 - true - MultiThreaded - stdcpp14 - - - Windows - true - true - true - Ws2_32.lib;$(ProjectDir)..\libethhash\windows\lib\x64\libsodium.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942} + Win32Proj + netmultihashnative + 10.0 + libubqhash + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\..\..\..\..\boost_1_62_0;$(ProjectDir)..\libethhash\windows\include\libsodium;$(IncludePath);$(ProjectDir) + $(SolutionDir)\..\..\..\..\boost_1_62_0\lib32-msvc-14.0;$(LibraryPath) + + + true + $(SolutionDir)\..\..\..\..\boost_1_62_0;$(ProjectDir)..\libethhash\windows\include\libsodium;$(IncludePath);$(ProjectDir) + $(SolutionDir)\..\..\..\..\boost_1_62_0\lib64-msvc-14.0;$(ProjectDir)windows\lib\x64;$(LibraryPath) + + + false + $(SolutionDir)\..\..\..\..\boost_1_62_0;$(ProjectDir)..\libethhash\windows\include\libsodium;$(IncludePath);$(ProjectDir) + $(SolutionDir)\..\..\..\..\boost_1_62_0\lib32-msvc-14.0;$(LibraryPath) + + + false + $(SolutionDir)\..\..\..\..\boost_1_62_0;$(ProjectDir)..\libethhash\windows\include\libsodium;$(ProjectDir)..\libethhash\windows\include\libsodium;$(IncludePath);$(ProjectDir) + $(SolutionDir)\..\..\..\..\boost_1_62_0\lib64-msvc-14.0;$(LibraryPath) + + + + + + Level3 + Disabled + SODIUM_STATIC;_CRT_SECURE_NO_WARNINGS;HAVE_SSE2 + true + MultiThreadedDebug + stdcpp14 + + + Windows + true + Ws2_32.lib;$(ProjectDir)..\libethhash\windows\lib\x86\libsodium.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + SODIUM_STATIC;_CRT_SECURE_NO_WARNINGS;HAVE_SSE2 + true + MultiThreadedDebug + stdcpp14 + + + Windows + true + Ws2_32.lib;$(ProjectDir)..\libethhash\windows\lib\x64\libsodium.lib;%(AdditionalDependencies) + + + + + + + Level3 + MaxSpeed + true + true + SODIUM_STATIC;_CRT_SECURE_NO_WARNINGS;HAVE_SSE2 + true + MultiThreaded + stdcpp14 + + + Windows + true + true + true + Ws2_32.lib;$(ProjectDir)..\libethhash\windows\lib\x86\libsodium.lib;%(AdditionalDependencies) + + + + + + + Level3 + MaxSpeed + true + true + SODIUM_STATIC;_CRT_SECURE_NO_WARNINGS;HAVE_SSE2 + true + MultiThreaded + stdcpp14 + + + Windows + true + true + true + Ws2_32.lib;$(ProjectDir)..\libethhash\windows\lib\x64\libsodium.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file