Skip to content
Permalink
Browse files

Automatically supply the #skipcbcheck fragment when mining NiceHash

* Fix fragments passed to BFGMiner - unescape the URI, BFGMiner doesn't look for %23 only #
  • Loading branch information...
nwoolls committed Dec 30, 2017
1 parent 425bb48 commit 8c426e52b68493d7f2dc1a8efceaa3f0777e3114

This file was deleted.

Oops, something went wrong.
@@ -179,10 +179,7 @@ public static bool ParseHostAndPort(this string hostAndPort, out string host, ou
host = uri.Scheme + "://" + host;
}

if (host.Last().Equals('/'))
{
host = host.Substring(0, host.Length - 1);
}
host = host.TrimEnd('/');

return true;
}
@@ -59,7 +59,6 @@
<Compile Include="Data\Configuration\PoolDefaults.cs" />
<Compile Include="Data\CredentialsEventArgs.cs" />
<Compile Include="Data\NotificationEventArgs.cs" />
<Compile Include="Data\PoolFeatureAnchors.cs" />
<Compile Include="Data\ProgressEventArgs.cs" />
<Compile Include="Data\PromptButtons.cs" />
<Compile Include="Data\PromptIcon.cs" />
@@ -565,13 +565,13 @@ private void button1_Click(object sender, EventArgs e)

private void poolFeaturesMenu_Opening(object sender, System.ComponentModel.CancelEventArgs e)
{
extraNonceSubscriptToolStripMenuItem.Checked = hostEdit.Text.Contains(PoolFeatureAnchors.ExtraNonceSubscribe);
disableCoinbaseCheckToolStripMenuItem.Checked = hostEdit.Text.Contains(PoolFeatureAnchors.SkipCoinbaseCheck);
extraNonceSubscriptToolStripMenuItem.Checked = hostEdit.Text.Contains(PoolFeatures.XNSubFragment);
disableCoinbaseCheckToolStripMenuItem.Checked = hostEdit.Text.Contains(PoolFeatures.SkipCBCheckFragment);
}

private void extraNonceSubscriptToolStripMenuItem_Click(object sender, EventArgs e)
{
UpdatePoolFeature(PoolFeatureAnchors.ExtraNonceSubscribe, extraNonceSubscriptToolStripMenuItem.Checked);
UpdatePoolFeature(PoolFeatures.XNSubFragment, extraNonceSubscriptToolStripMenuItem.Checked);
}

private void featuresButton_Click(object sender, EventArgs e)
@@ -585,7 +585,7 @@ private void featuresButton_Click(object sender, EventArgs e)

private void disableCoinbaseCheckToolStripMenuItem_Click(object sender, EventArgs e)
{
UpdatePoolFeature(PoolFeatureAnchors.SkipCoinbaseCheck, disableCoinbaseCheckToolStripMenuItem.Checked);
UpdatePoolFeature(PoolFeatures.SkipCBCheckFragment, disableCoinbaseCheckToolStripMenuItem.Checked);
}

private void UpdatePoolFeature(string anchor, bool enabled)
@@ -372,27 +372,23 @@ private void featuresButton_Click(object sender, EventArgs e)

private void poolFeaturesMenu_Opening(object sender, System.ComponentModel.CancelEventArgs e)
{
extraNonceSubscriptToolStripMenuItem.Checked = hostEdit.Text.Contains(PoolFeatureAnchors.ExtraNonceSubscribe);
disableCoinbaseCheckToolStripMenuItem.Checked = hostEdit.Text.Contains(PoolFeatureAnchors.SkipCoinbaseCheck);
extraNonceSubscriptToolStripMenuItem.Checked = hostEdit.Text.Contains(PoolFeatures.XNSubFragment);
disableCoinbaseCheckToolStripMenuItem.Checked = hostEdit.Text.Contains(PoolFeatures.SkipCBCheckFragment);
}

private void UpdatePoolFeature(string anchor, bool enabled)
private void UpdatePoolFeature(string fragment, bool enabled)
{
string uriSegment = "/" + anchor;
if (enabled)
hostEdit.Text = hostEdit.Text + uriSegment;
else
hostEdit.Text = hostEdit.Text.Replace(uriSegment, String.Empty);
hostEdit.Text = PoolFeatures.UpdatePoolFeature(hostEdit.Text, fragment, enabled);
}

private void extraNonceSubscriptToolStripMenuItem_Click(object sender, EventArgs e)
{
UpdatePoolFeature(PoolFeatureAnchors.ExtraNonceSubscribe, extraNonceSubscriptToolStripMenuItem.Checked);
UpdatePoolFeature(PoolFeatures.XNSubFragment, extraNonceSubscriptToolStripMenuItem.Checked);
}

private void disableCoinbaseCheckToolStripMenuItem_Click(object sender, EventArgs e)
{
UpdatePoolFeature(PoolFeatureAnchors.SkipCoinbaseCheck, disableCoinbaseCheckToolStripMenuItem.Checked);
UpdatePoolFeature(PoolFeatures.SkipCBCheckFragment, disableCoinbaseCheckToolStripMenuItem.Checked);
}
}
}
@@ -0,0 +1,40 @@
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MultiMiner.Xgminer.Data;

namespace MultiMiner.Xgminer.Tests
{
[TestClass]
public class MiningPoolTests
{
[TestMethod]
public void BuildPoolUri_Succeeds()
{
// arrange
MiningPool pool = new MiningPool();
pool.Host = "stratum+tcp://example.com";
pool.Port = 3333;

// act
string poolUri = pool.BuildPoolUri();

// assert
Assert.AreEqual("stratum+tcp://example.com:3333", poolUri);
}

[TestMethod]
public void BuildPoolUri_UnescapesData()
{
// arrange
MiningPool pool = new MiningPool();
pool.Host = "stratum+tcp://example.com/#fragment";
pool.Port = 3333;

// act
string poolUri = pool.BuildPoolUri();

// assert
Assert.AreEqual("stratum+tcp://example.com:3333/#fragment", poolUri);
}
}
}
@@ -53,6 +53,8 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="MinerTests.cs" />
<Compile Include="DeviceListParserTests.cs" />
<Compile Include="PoolFeaturesTests.cs" />
<Compile Include="MiningPoolTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MultiMiner.Xgminer\MultiMiner.Xgminer.csproj">
@@ -0,0 +1,145 @@
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MultiMiner.Xgminer.Data;

namespace MultiMiner.Xgminer.Tests
{
[TestClass]
public class PoolFeaturesTests
{
[TestMethod]
public void UpdatePoolFeature_EnableExisingFeature_Succeeds()
{
// arrange
string host = "google.com/#xnsub";
string fragment = PoolFeatures.XNSubFragment;
bool enabled = true;

// act
string result = PoolFeatures.UpdatePoolFeature(host, fragment, enabled);

// assert
Assert.AreEqual("google.com/#xnsub", result);
}

[TestMethod]
public void UpdatePoolFeature_EnableMissingFeature_Succeeds()
{
// arrange
string host = "google.com";
string fragment = PoolFeatures.XNSubFragment;
bool enabled = true;

// act
string result = PoolFeatures.UpdatePoolFeature(host, fragment, enabled);

// assert
Assert.AreEqual("google.com/#xnsub", result);
}

[TestMethod]
public void UpdatePoolFeature_EnableFeature_RemovesDupeSlashes()
{
// arrange
string host = "google.com/";
string fragment = PoolFeatures.XNSubFragment;
bool enabled = true;

// act
string result = PoolFeatures.UpdatePoolFeature(host, fragment, enabled);

// assert
Assert.AreEqual("google.com/#xnsub", result);
}

[TestMethod]
public void UpdatePoolFeature_EnableMultipleFeatures_A_Succeeds()
{
// arrange
string host = "google.com";
bool enabled = true;

// act
string result = PoolFeatures.UpdatePoolFeature(host, PoolFeatures.XNSubFragment, enabled);
result = PoolFeatures.UpdatePoolFeature(result, PoolFeatures.SkipCBCheckFragment, enabled);

// assert
Assert.AreEqual("google.com/#xnsub/#skipcbcheck", result);
}

[TestMethod]
public void UpdatePoolFeature_EnableMultipleFeatures_B_Succeeds()
{
// arrange
string host = "google.com/#xnsub/";
bool enabled = true;

// act
string result = PoolFeatures.UpdatePoolFeature(host, PoolFeatures.XNSubFragment, enabled);
result = PoolFeatures.UpdatePoolFeature(result, PoolFeatures.SkipCBCheckFragment, enabled);

// assert
Assert.AreEqual("google.com/#xnsub/#skipcbcheck", result);
}

[TestMethod]
public void UpdatePoolFeature_EnableMultipleFeatures_C_Succeeds()
{
// arrange
string host = "google.com/#xnsub/#skipcbcheck";
bool enabled = true;

// act
string result = PoolFeatures.UpdatePoolFeature(host, PoolFeatures.XNSubFragment, enabled);
result = PoolFeatures.UpdatePoolFeature(result, PoolFeatures.SkipCBCheckFragment, enabled);

// assert
Assert.AreEqual("google.com/#xnsub/#skipcbcheck", result);
}

[TestMethod]
public void UpdatePoolFeature_EnableMultipleFeatures_D_Succeeds()
{
// arrange
string host = "google.com/#skipcbcheck/#xnsub";
bool enabled = true;

// act
string result = PoolFeatures.UpdatePoolFeature(host, PoolFeatures.XNSubFragment, enabled);
result = PoolFeatures.UpdatePoolFeature(result, PoolFeatures.SkipCBCheckFragment, enabled);

// assert
Assert.AreEqual("google.com/#skipcbcheck/#xnsub", result);
}

[TestMethod]
public void UpdatePoolFeature_DisableExistingFeature_Succeeds()
{
// arrange
string host = "google.com/#xnsub";
string fragment = PoolFeatures.XNSubFragment;
bool enabled = false;

// act
string result = PoolFeatures.UpdatePoolFeature(host, fragment, enabled);

// assert
Assert.AreEqual("google.com", result);
}

[TestMethod]
public void UpdatePoolFeature_DisableMissingFeature_Succeeds()
{
// arrange
string host = "google.com";
string fragment = PoolFeatures.XNSubFragment;
bool enabled = false;

// act
string result = PoolFeatures.UpdatePoolFeature(host, fragment, enabled);

// assert
Assert.AreEqual("google.com", result);
}
}
}
@@ -21,5 +21,23 @@ public MiningPool()
public int Quota { get; set; } //see bfgminer README about quotas
public bool QuotaEnabled { get; set; }
public string MinerFlags { get; set; }

public string BuildPoolUri()
{
//trim Host to ensure proper formatting
//don't just concatenate - we need to support URI paths and #fragments
string hostText = Host.Trim();

UriBuilder builder = new UriBuilder(hostText);
builder.Port = Port;
string poolUri = builder.Uri
.ToString()
.TrimEnd('/');

// any fragment at this point will be URI encoded - e.g. %23xnsub - but BFGMiner only looks for #
poolUri = Uri.UnescapeDataString(poolUri);

return poolUri;
}
}
}
@@ -0,0 +1,29 @@
using System;

namespace MultiMiner.Xgminer.Data
{
public class PoolFeatures
{
public const string XNSubFragment = "#xnsub";
public const string SkipCBCheckFragment = "#skipcbcheck";

public static string UpdatePoolFeature(string host, string fragment, bool enabled)
{
string result = host;

string uriSegment = "/" + fragment;

if (enabled)
{
if (!result.Contains(uriSegment))
{
result = result.TrimEnd('/') + uriSegment;
}
}
else
result = result.Replace(uriSegment, String.Empty);

return result;
}
}
}
@@ -239,30 +239,24 @@ public Process Launch(string reason = "")
{
string argument;

//trim Host to ensure proper formatting
//don't just concatenate - we need to support URI paths and #anchors
UriBuilder builder;
string hostText = pool.Host.Trim();
string poolUri;
try
{
builder = new UriBuilder(hostText);
poolUri = pool.BuildPoolUri();
}
catch (UriFormatException ex)
{
throw new MinerLaunchException(String.Format("The '{0}' pool host '{1}' is not a valid URI.", this.minerConfiguration.CoinName, hostText)
throw new MinerLaunchException(String.Format("The '{0}' pool host '{1}' is not a valid URI.", this.minerConfiguration.CoinName, pool.Host)
+ Environment.NewLine + Environment.NewLine + ex.Message);
}

builder.Port = pool.Port;

//automatically add the #xnsub fragment to pool URIs when mining NiceHash with BFGMiner
//automatically add the #xnsub & #skipcbcheck fragments to pool URIs when mining NiceHash with BFGMiner
if (!legacyApi && pool.Host.ToLower().Contains("nicehash.com"))
{
builder.Fragment = "xnsub";
poolUri = PoolFeatures.UpdatePoolFeature(poolUri, PoolFeatures.XNSubFragment, true);
poolUri = PoolFeatures.UpdatePoolFeature(poolUri, PoolFeatures.SkipCBCheckFragment, true);
}

string poolUri = builder.Uri.ToString();

if (pool.QuotaEnabled)
argument = string.Format("--quota \"{2};{0}\" -u {1}", poolUri, pool.Username, pool.Quota);
else
@@ -51,6 +51,7 @@
<Compile Include="Data\Device\DevicePlatform.cs" />
<Compile Include="Data\KnownAlgorithm.cs" />
<Compile Include="Data\KnownAlgorithms.cs" />
<Compile Include="Data\PoolFeatures.cs" />
<Compile Include="LaunchFailedArgs.cs" />
<Compile Include="LogLaunchArgs.cs" />
<Compile Include="MinerLaunchException.cs" />

0 comments on commit 8c426e5

Please sign in to comment.
You can’t perform that action at this time.