public void BitcoinJob_Should_Accept_Valid_Share() { var worker = new StratumClient(); worker.SetContext(new BitcoinWorkerContext { Difficulty = 0.5, ExtraNonce1 = "01000058", }); var bt = JsonConvert.DeserializeObject <Miningcore.Blockchain.Bitcoin.DaemonResponses.BlockTemplate>( "{\"Version\":536870912,\"PreviousBlockhash\":\"000000000909578519b5be7b37fdc53b2923817921c43108a907b72264da76bb\",\"CoinbaseValue\":5000000000,\"Target\":\"7fffff0000000000000000000000000000000000000000000000000000000000\",\"NonceRange\":\"00000000ffffffff\",\"CurTime\":1508869874,\"Bits\":\"207fffff\",\"Height\":14,\"Transactions\":[],\"CoinbaseAux\":{\"Flags\":\"0b2f454231362f414431322f\"},\"default_witness_commitment\":null}"); var job = new BitcoinJob(); // set clock to job creation time var clock = new MockMasterClock { CurrentTime = DateTimeOffset.FromUnixTimeSeconds(1508869874).UtcDateTime }; job.Init(bt, "1", poolConfig, clusterConfig, clock, poolAddressDestination, Network.RegTest, false, 1, sha256d, sha256d, sha256dReverse); // set clock to submission time clock.CurrentTime = DateTimeOffset.FromUnixTimeSeconds(1508869907).UtcDateTime; var(share, blockHex) = job.ProcessShare(worker, "01000000", "59ef86f2", "8d84ae6a"); Assert.NotNull(share); Assert.True(share.IsBlockCandidate); Assert.Equal(share.BlockHash, "601ed85039804bcecbbdb53e0ca358aeb8dabef2366fb64c216aac3aba02b716"); Assert.Equal(blockHex, "00000020bb76da6422b707a90831c421798123293bc5fd377bbeb5198557090900000000fd5418fe788ef961678e4bacdd1fe3903185b9ec63865bb3d2d279bb0eb48c0bf286ef59ffff7f206aae848d0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff295e0c0b2f454231362f414431322f04f286ef590001000058010000000c2f4d696e696e67436f72652f000000000100f2052a010000001976a9142ebb5cccf9a6bb927661d2953655c43c04accc3788ac00000000"); Assert.Equal(share.BlockHeight, 14); Assert.Equal(share.Difficulty, 0.5); }
public void MoneroJob_Should_Not_Accept_Invalid_Share() { var worker = new StratumClient(); worker.SetContext(new MoneroWorkerContext { Difficulty = 1000, }); var bt = JsonConvert.DeserializeObject <MiningCore.Blockchain.Monero.DaemonResponses.GetBlockTemplateResponse>( "{\"blocktemplate_blob\":\"0106e7eabdcf058234351e2e6ea901a56b33bb531587424321873072d80a9e97295b6c43152b9d00000000019c0201ffe00106e3a1a0cc010275d92c0a057aa5f073079694a153d426f837f49fdb9654da10a5364e79a2086280a0d9e61d028b46dca0d04998500b40b046fd6f8bb33229e6380fd465dbb1327aa6f813d8bd80c0fc82aa0202372f076459e769116d604d30aabff7160782acc0d20e0c5cdc8963ed4e16372f8090cad2c60e02f009504ce65538bbb684b466b21be3a90e3740f185d7089d37b75f0cf62b6e7680e08d84ddcb0102cf01b85c0b592bb6e508e20b5d317052b75de121908390363201abff3476ef0180c0caf384a302024b81076c8ad0cfe84cc32fe0813d63cdd0f7d8d0e56d82aa3f58cbbe49d4c61e2b017aaf3074be7ecb30a769595758e4da7c7c87ead864baf89b679b73153dfa352c0208000000000000000000\",\"Difficulty\":2,\"Height\":224,\"prev_hash\":\"8234351e2e6ea901a56b33bb531587424321873072d80a9e97295b6c43152b9d\",\"reserved_offset\":322,\"Status\":\"OK\"}"); var job = new MoneroJob(bt, "d150da".HexToByteArray(), "1", poolConfig, clusterConfig); // invalid nonce Assert.Throws <StratumException>(() => job.ProcessShare("040100a5", 1, "f29c7fbf57d97eeedb61555857d7a34314250da20742b8157f96e0be89530a00", worker)); // invalid extra-nonce Assert.Throws <StratumException>(() => job.ProcessShare("040100a4", 2, "f29c7fbf57d97eeedb61555857d7a34314250da20742b8157f96e0be89530a00", worker)); // invalid hash Assert.Throws <StratumException>(() => job.ProcessShare("040100a4", 1, "a29c7fbf57d97eeedb61555857d7a34314250da20742b8157f96e0be89530a00", worker)); // invalid hash 2 Assert.Throws <StratumException>(() => job.ProcessShare("040100a4", 1, "9c7fbf57d97eeedb61555857d7a34314250da20742b8157f96e0be89530a00", worker)); }
protected override void OnConnect(StratumClient client) { // client setup var context = CreateClientContext(); var poolEndpoint = poolConfig.Ports[client.PoolEndpoint.Port]; context.Init(poolConfig, poolEndpoint.Difficulty, poolConfig.EnableInternalStratum == true ? poolEndpoint.VarDiff : null, clock); client.SetContext(context); // expect miner to establish communication within a certain time EnsureNoZombieClient(client); }
public void BitcoinJob_Should_Not_Accept_Invalid_Share() { var worker = new StratumClient(); worker.SetContext(new BitcoinWorkerContext { Difficulty = 0.5, ExtraNonce1 = "01000058", }); var bt = JsonConvert.DeserializeObject <MiningCore.Blockchain.Bitcoin.DaemonResponses.BlockTemplate>( "{\"Version\":536870912,\"PreviousBlockhash\":\"000000000909578519b5be7b37fdc53b2923817921c43108a907b72264da76bb\",\"CoinbaseValue\":5000000000,\"Target\":\"7fffff0000000000000000000000000000000000000000000000000000000000\",\"NonceRange\":\"00000000ffffffff\",\"CurTime\":1508869874,\"Bits\":\"207fffff\",\"Height\":14,\"Transactions\":[],\"CoinbaseAux\":{\"Flags\":\"0b2f454231362f414431322f\"},\"default_witness_commitment\":null}"); var job = new BitcoinJob <MiningCore.Blockchain.Bitcoin.DaemonResponses.BlockTemplate>(); // set clock to job creation time var clock = new MockMasterClock { CurrentTime = DateTimeOffset.FromUnixTimeSeconds(1508869874).UtcDateTime }; job.Init(bt, "1", poolConfig, clusterConfig, clock, poolAddressDestination, BitcoinNetworkType.RegTest, false, 1, 1, sha256d, sha256d, sha256dReverse); // set clock to submission time clock.CurrentTime = DateTimeOffset.FromUnixTimeSeconds(1508869907).UtcDateTime; // invalid extra-nonce 2 Assert.Throws <StratumException>(() => job.ProcessShare(worker, "02000000", "59ef86f2", "8d84ae6a")); // make sure we don't accept case-sensitive duplicate shares as basically 0xdeadbeaf = 0xDEADBEAF. var share = job.ProcessShare(worker, "01000000", "59ef86f2", "8d84ae6a"); Assert.Throws <StratumException>(() => job.ProcessShare(worker, "01000000", "59ef86f2", "8D84AE6A")); // invalid time Assert.Throws <StratumException>(() => job.ProcessShare(worker, "01000000", "69ef86f2", "8d84ae6a")); // invalid nonce Assert.Throws <StratumException>(() => job.ProcessShare(worker, "01000000", "59ef86f2", "ad84be6a")); // valid share data but invalid submission time clock.CurrentTime = DateTimeOffset.FromUnixTimeSeconds(1408869907).UtcDateTime; Assert.Throws <StratumException>(() => job.ProcessShare(worker, "01000000", "59ef86f2", "8d84ae6a")); }
protected override void OnConnect(StratumClient client) { var context = CreateClientContext(); var poolEndpoint = poolConfig.Ports[client.PoolEndpoint.Port]; context.Init(poolConfig, poolEndpoint.Difficulty, poolConfig.EnableInternalStratum == true ? poolEndpoint.VarDiff : null, clock); client.SetContext(context); if (context.VarDiff != null) { lock (context.VarDiff) { StartVarDiffIdleUpdate(client, poolEndpoint); } } EnsureNoZombieClient(client); }
public void MoneroJob_PrepareWorkerJob() { var worker = new StratumClient(); worker.SetContext(new MoneroWorkerContext { Difficulty = 1000, }); var bt = JsonConvert.DeserializeObject <MiningCore.Blockchain.Monero.DaemonResponses.GetBlockTemplateResponse>( "{\"blocktemplate_blob\":\"0106e7eabdcf058234351e2e6ea901a56b33bb531587424321873072d80a9e97295b6c43152b9d00000000019c0201ffe00106e3a1a0cc010275d92c0a057aa5f073079694a153d426f837f49fdb9654da10a5364e79a2086280a0d9e61d028b46dca0d04998500b40b046fd6f8bb33229e6380fd465dbb1327aa6f813d8bd80c0fc82aa0202372f076459e769116d604d30aabff7160782acc0d20e0c5cdc8963ed4e16372f8090cad2c60e02f009504ce65538bbb684b466b21be3a90e3740f185d7089d37b75f0cf62b6e7680e08d84ddcb0102cf01b85c0b592bb6e508e20b5d317052b75de121908390363201abff3476ef0180c0caf384a302024b81076c8ad0cfe84cc32fe0813d63cdd0f7d8d0e56d82aa3f58cbbe49d4c61e2b017aaf3074be7ecb30a769595758e4da7c7c87ead864baf89b679b73153dfa352c0208000000000000000000\",\"Difficulty\":2,\"Height\":224,\"prev_hash\":\"8234351e2e6ea901a56b33bb531587424321873072d80a9e97295b6c43152b9d\",\"reserved_offset\":322,\"Status\":\"OK\"}"); var job = new MoneroJob(bt, "d150da".HexToByteArray(), "1", poolConfig, clusterConfig); var workerJob = new MoneroWorkerJob(1.ToString(), 10000); job.PrepareWorkerJob(workerJob, out var blob, out var target); Assert.Equal(blob, "0106e7eabdcf058234351e2e6ea901a56b33bb531587424321873072d80a9e97295b6c43152b9d00000000b7dff217012da3129b6e6a4b8705a598f8928469398b3479b711b6ceee16072301"); Assert.Equal(target, "b88d0600"); }
protected override void OnConnect(StratumClient client) { // client setup var context = CreateClientContext(); var poolEndpoint = poolConfig.Ports[client.PoolEndpoint.Port]; context.Init(poolConfig, poolEndpoint.Difficulty, !poolConfig.ExternalStratum ? poolEndpoint.VarDiff : null, clock); client.SetContext(context); // varDiff setup if (context.VarDiff != null) { lock (context.VarDiff) { StartVarDiffIdleUpdate(client, poolEndpoint); } } // expect miner to establish communication within a certain time EnsureNoZombieClient(client); }
public void BitcoinJob_Should_Accept_Valid_Share() { var worker = new StratumClient(); worker.SetContext(new BitcoinWorkerContext { Difficulty = 0.5, ExtraNonce1 = "01000058", }); var bt = JsonConvert.DeserializeObject <MiningCore.Blockchain.Bitcoin.DaemonResponses.BlockTemplate>( "{\"Version\":536870912,\"PreviousBlockhash\":\"000000000909578519b5be7b37fdc53b2923817921c43108a907b72264da76bb\",\"CoinbaseValue\":5000000000,\"Target\":\"7fffff0000000000000000000000000000000000000000000000000000000000\",\"NonceRange\":\"00000000ffffffff\",\"CurTime\":1508869874,\"Bits\":\"207fffff\",\"Height\":14,\"Transactions\":[],\"CoinbaseAux\":{\"Flags\":\"0b2f454231362f414431322f\"},\"default_witness_commitment\":null}"); var job = new BitcoinJob <MiningCore.Blockchain.Bitcoin.DaemonResponses.BlockTemplate>(); // set clock to job creation time var clock = new MockMasterClock { CurrentTime = DateTimeOffset.FromUnixTimeSeconds(1508869874).UtcDateTime }; job.Init(bt, "1", poolConfig, clusterConfig, clock, poolAddressDestination, BitcoinNetworkType.RegTest, false, 1, 1, sha256d, sha256d, sha256dReverse); // set clock to submission time clock.CurrentTime = DateTimeOffset.FromUnixTimeSeconds(1508869907).UtcDateTime; var share = job.ProcessShare(worker, "01000000", "59ef86f2", "8d84ae6a"); Assert.NotNull(share); Assert.True(share.IsBlockCandidate); Assert.Equal(share.BlockHash, "000000000fccf11cd0b7d9057441e430c320384b95b034bd28092c4553594b4a"); Assert.Equal(share.BlockHex, "00000020bb76da6422b707a90831c421798123293bc5fd377bbeb51985570909000000008677145722cbe6f1ebec19fecc724cab5487f3292a69f6908bd512f645bb0635f286ef59ffff7f206aae848d0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff295e0c0b2f454231362f414431322f04f286ef590801000058010000000c2f4d696e696e67436f72652f000000000100f2052a010000001976a9142ebb5cccf9a6bb927661d2953655c43c04accc3788ac00000000"); Assert.Equal(share.BlockHeight, 14); Assert.Equal(share.BlockReward, 50); Assert.Equal(share.Difficulty, 0.5); }
protected override void OnConnect(StratumClient client) { // update stats lock (clients) { poolStats.ConnectedMiners = clients.Count; } // client setup var context = CreateClientContext(); var poolEndpoint = poolConfig.Ports[client.PoolEndpoint.Port]; context.Init(poolConfig, poolEndpoint.Difficulty, poolEndpoint.VarDiff, clock); client.SetContext(context); // varDiff setup if (context.VarDiff != null) { // get or create manager lock (varDiffManagers) { if (!varDiffManagers.TryGetValue(poolEndpoint, out var varDiffManager)) { varDiffManager = new VarDiffManager(poolEndpoint.VarDiff, clock); varDiffManagers[poolEndpoint] = varDiffManager; } } // wire updates lock (context.VarDiff) { context.VarDiff.Subscription = Shares .Where(x => x.Item1 == client) .Timestamp() .Select(x => x.Timestamp.ToUnixTimeMilliseconds()) .Buffer(TimeSpan.FromSeconds(poolEndpoint.VarDiff.RetargetTime), VarDiffSampleCount) .Subscribe(timestamps => { try { VarDiffManager varDiffManager; lock (varDiffManagers) { varDiffManager = varDiffManagers[poolEndpoint]; } var newDiff = varDiffManager.Update(context, timestamps, client.ConnectionId, logger); if (newDiff.HasValue) { logger.Info(() => $"[{LogCat}] [{client.ConnectionId}] VarDiff update to {Math.Round(newDiff.Value, 2)}"); OnVarDiffUpdate(client, newDiff.Value); } } catch (Exception ex) { logger.Error(ex); } }); } } // expect miner to establish communication within a certain time EnsureNoZombieClient(client); }