From ec14fba163343fcb434143dde9cfec6e6da73e8f Mon Sep 17 00:00:00 2001 From: Oliver Weichhold Date: Thu, 11 Oct 2018 15:06:42 +0200 Subject: [PATCH] Dev (#427) --- examples/dash_pool.json | 4 +- examples/dash_pool_no_polling.json | 4 +- examples/digibyte_scrypt_pool.json | 5 +- examples/digibyte_sha256_pool.json | 5 +- examples/ethereum_pool.json | 4 +- examples/flo_pool.json | 4 +- examples/litecoin_dash_pool.json | 8 +- examples/litecoin_pool.json | 4 +- examples/monero_pool.json | 4 +- examples/pakcoin_pool.json | 5 +- examples/straks_pool.json | 121 ------------------ examples/zcash_pool.json | 4 +- .../Cryptonote/CryptonoteJobTests.cs | 4 +- src/Miningcore.Tests/Crypto/CrytonoteTests.cs | 27 ++-- .../Api/Responses/GetPoolsResponse.cs | 1 + .../Blockchain/Bitcoin/BitcoinPool.cs | 4 +- .../Bitcoin/BitcoinWorkerContext.cs | 11 +- .../Blockchain/Cryptonote/CryptonoteJob.cs | 29 ++++- .../Cryptonote/CryptonoteJobManager.cs | 8 +- .../Blockchain/Cryptonote/CryptonotePool.cs | 46 ++++--- .../Cryptonote/CryptonoteWorkerContext.cs | 14 +- .../Blockchain/Equihash/EquihashPool.cs | 4 +- .../Blockchain/Ethereum/EthereumJob.cs | 4 +- .../Blockchain/Ethereum/EthereumJobManager.cs | 6 +- .../Blockchain/Ethereum/EthereumPool.cs | 4 +- .../Ethereum/EthereumWorkerContext.cs | 12 +- src/Miningcore/Blockchain/Share.cs | 26 ++-- src/Miningcore/Extensions/StringExtensions.cs | 8 ++ src/Miningcore/Mining/ShareReceiver.cs | 4 +- src/Miningcore/Mining/StatsRecorder.cs | 25 +++- src/Miningcore/Native/LibCryptonight.cs | 32 +++-- .../PaymentSchemes/PPLNSPaymentScheme.cs | 6 - src/Miningcore/Persistence/Model/Share.cs | 1 - .../Persistence/Postgres/Entities/Share.cs | 1 - .../Postgres/Repositories/ShareRepository.cs | 4 +- .../Postgres/Repositories/StatsRepository.cs | 18 +++ .../Persistence/Postgres/Scripts/createdb.sql | 1 - .../Repositories/IStatsRepository.cs | 2 + src/Miningcore/Stratum/StratumClient.cs | 23 ++-- src/Miningcore/coins.json | 8 +- src/Native/libcryptonight/exports.cpp | 21 ++- 41 files changed, 243 insertions(+), 283 deletions(-) delete mode 100644 examples/straks_pool.json diff --git a/examples/dash_pool.json b/examples/dash_pool.json index 603701bc7..0de889f86 100644 --- a/examples/dash_pool.json +++ b/examples/dash_pool.json @@ -45,9 +45,7 @@ "pools": [{ "id": "dash1", "enabled": true, - "coin": { - "type": "DASH" - }, + "coin": "dash", "address": "XgmfWd5DXWGcYhxPcDPUJk44Cnh2e8tZk7", "rewardRecipients": [{ "address": "XgmfWd5DXWGcYhxPcDPUJk44Cnh2e8tZk7", diff --git a/examples/dash_pool_no_polling.json b/examples/dash_pool_no_polling.json index 203ac77c2..3378f92ab 100644 --- a/examples/dash_pool_no_polling.json +++ b/examples/dash_pool_no_polling.json @@ -45,9 +45,7 @@ "pools": [{ "id": "dash1", "enabled": true, - "coin": { - "type": "DASH" - }, + "coin": "dash", "address": "XgmfWd5DXWGcYhxPcDPUJk44Cnh2e8tZk7", "rewardRecipients": [{ "address": "XgmfWd5DXWGcYhxPcDPUJk44Cnh2e8tZk7", diff --git a/examples/digibyte_scrypt_pool.json b/examples/digibyte_scrypt_pool.json index 9f60fe06e..27833a8a0 100644 --- a/examples/digibyte_scrypt_pool.json +++ b/examples/digibyte_scrypt_pool.json @@ -45,10 +45,7 @@ "pools": [{ "id": "dgb-scrypt-1", "enabled": true, - "coin": { - "type": "DGB", - "algorithm": "scrypt" - }, + "coin": "digibyte-scrypt", "address": "DAFtYMGVdNtqHJoBGg2xqZZwSuYAaEs2Bn", "rewardRecipients": [ { diff --git a/examples/digibyte_sha256_pool.json b/examples/digibyte_sha256_pool.json index bb1636b0b..e41f98e5c 100644 --- a/examples/digibyte_sha256_pool.json +++ b/examples/digibyte_sha256_pool.json @@ -45,10 +45,7 @@ "pools": [{ "id": "dgb-sha256-1", "enabled": true, - "coin": { - "type": "DGB", - "algorithm": "sha256d" - }, + "coin": "digibyte-sha256", "address": "DAFtYMGVdNtqHJoBGg2xqZZwSuYAaEs2Bn", "rewardRecipients": [ { diff --git a/examples/ethereum_pool.json b/examples/ethereum_pool.json index e9f3bcc40..ac5a15c46 100644 --- a/examples/ethereum_pool.json +++ b/examples/ethereum_pool.json @@ -45,9 +45,7 @@ "pools": [{ "id": "eth1", "enabled": true, - "coin": { - "type": "ETH" - }, + "coin": "ethereum", "address": "0x0942e9144606ad43f2e61a7ee332fe9914424712", "rewardRecipients": [{ "type": "op", diff --git a/examples/flo_pool.json b/examples/flo_pool.json index da9c1950c..d2c566f61 100644 --- a/examples/flo_pool.json +++ b/examples/flo_pool.json @@ -46,9 +46,7 @@ { "id": "flo1", "enabled": true, - "coin": { - "type": "FLO" - }, + "coin": "florincoin", "address": "FC3d6JT1Z3uZvKVNWjKt3qN8PX8knhAU7d", "rewardRecipients": [ { diff --git a/examples/litecoin_dash_pool.json b/examples/litecoin_dash_pool.json index f8a5c97d8..dddbd0a61 100644 --- a/examples/litecoin_dash_pool.json +++ b/examples/litecoin_dash_pool.json @@ -45,9 +45,7 @@ "pools": [{ "id": "ltc1", "enabled": true, - "coin": { - "type": "LTC" - }, + "coin": "litecoin", "address": "LNDA11u4HWzbJaBGiHDvs6SmA8M6avB3wH", "rewardRecipients": [{ "address": "LUWYwkz6DQLVeqJqHRtGjNhWUxBvBmE3SX", @@ -93,9 +91,7 @@ { "id": "dash1", "enabled": true, - "coin": { - "type": "DASH" - }, + "coin": "dash", "address": "XgmfWd5DXWGcYhxPcDPUJk44Cnh2e8tZk7", "rewardRecipients": [{ "type": "op", diff --git a/examples/litecoin_pool.json b/examples/litecoin_pool.json index 542a193a0..13d17e1dc 100644 --- a/examples/litecoin_pool.json +++ b/examples/litecoin_pool.json @@ -45,9 +45,7 @@ "pools": [{ "id": "ltc1", "enabled": true, - "coin": { - "type": "LTC" - }, + "coin": "litecoin", "address": "LNDA11u4HWzbJaBGiHDvs6SmA8M6avB3wH", "rewardRecipients": [ { diff --git a/examples/monero_pool.json b/examples/monero_pool.json index 44c0ea650..c5238f808 100644 --- a/examples/monero_pool.json +++ b/examples/monero_pool.json @@ -45,9 +45,7 @@ "pools": [{ "id": "xmr1", "enabled": true, - "coin": { - "type": "XMR" - }, + "coin": "monero", "address": "43g9avHw8WYHnq749LU1Nw1BZ8FCwS2B7GLoW4vif7cPjJB7e9f6WgU8ptDFM7kyNS9kz1zy334dAYFKgP2KJU8vMoZ3hYD", "rewardRecipients": [ { diff --git a/examples/pakcoin_pool.json b/examples/pakcoin_pool.json index 54d64c707..85c65df0a 100644 --- a/examples/pakcoin_pool.json +++ b/examples/pakcoin_pool.json @@ -45,10 +45,7 @@ "pools": [{ "id": "pak1", "enabled": true, - "coin": { - "type": "PAK", - "algorithm": "scrypt" - }, + "coin": "pakcoin", "hasLegacyDaemon": true, "address": "PSWsdRBXui6nnhV9FJ4NduC2KdFkeudtEz", "rewardRecipients": [ diff --git a/examples/straks_pool.json b/examples/straks_pool.json deleted file mode 100644 index 0958e4c95..000000000 --- a/examples/straks_pool.json +++ /dev/null @@ -1,121 +0,0 @@ -{ - "logging": { - "level": "info", - "enableConsoleLog": true, - "enableConsoleColors": true, - "logFile": "", - "logBaseDirectory": "", - "perPoolLogFile": false - }, - "banning": { - "manager": "integrated" - }, - "notifications": { - "enabled": false, - "email": { - "host": "smtp.example.com", - "port": 587, - "user": "user", - "password": "password", - "fromAddress": "info@yourpool.org", - "fromName": "support" - }, - "admin": { - "enabled": false, - "emailAddress": "user@example.com", - "notifyBlockFound": true - } - }, - "persistence": { - "postgres": { - "host": "127.0.0.1", - "port": 5432, - "user": "miningcore", - "password": "miningcore", - "database": "miningcore" - } - }, - "paymentProcessing": { - "enabled": true, - "interval": 600, - "shareRecoveryFile": "recovered-shares.txt" - }, - "api": { - "enabled": true, - "listenAddress": "*", - "port": 4000 - }, - "pools": [ - { - "treasuryAddresses": [ - "3K3bPrW5h7DYEMp2RcXawTCXajcm4ZU9Zh", - "33Ssxmn3ehVMgyxgegXhpLGSBpubPjLZQ6", - "3HFPNAjesiBY5sSVUmuBFnMEGut69R49ca", - "37jLjjfUXQU4bdqVzvpUXyzAqPQSmxyByi" - ], - "id": "straks1", - "enabled": true, - "coin": { - "type": "STAK" - }, - "address": "tW3nPvwAwF6XyBxucyN3NLcG4iohB9XyPS", - "rewardRecipients": [ - - { - "address": "SP5BMTez7GyCzn1AmtdkpkwrsNJsnqukf8", - "percentage": 1.0 - } - ], - "blockRefreshInterval": 500, - "jobRebroadcastTimeout": 10, - "clientConnectionTimeout": 600, - "banning": { - "enabled": true, - "time": 600, - "invalidPercent": 50, - "checkThreshold": 50 - }, - "ports": { - "4500": { - "listenAddress": "0.0.0.0", - "difficulty": 1, - "name": "1Difficulty", - "varDiff": { - "minDiff": 0.5, - "targetTime": 15, - "retargetTime": 90, - "variancePercent": 30 - } - }, - "4501": { - "listenAddress": "0.0.0.0", - "difficulty": 10, - "name": "1Difficulty", - "varDiff": { - "minDiff": 5, - "targetTime": 15, - "retargetTime": 90, - "variancePercent": 30 - } - } - }, - - "daemons": [ - { - "host": "127.0.0.1", - "port": 19333, - "user": "straks", - "password": "straks" - } - ], - "paymentProcessing": { - "enabled": true, - "minimumPayment": 0.5, - "payoutScheme": "PPLNS", - "payoutSchemeConfig": { - "factor": 2.0 - } - } - } - ] -} \ No newline at end of file diff --git a/examples/zcash_pool.json b/examples/zcash_pool.json index bfec39dd5..76c4facc1 100644 --- a/examples/zcash_pool.json +++ b/examples/zcash_pool.json @@ -46,9 +46,7 @@ "pools": [{ "id": "zec1", "enabled": true, - "coin": { - "type": "ZEC" - }, + "coin": "zcash", "address": "t1YHZHz2DGVMJiggD2P4fBQ2TAPgtLSUwZ7", "z-address": "zca7tCyUqn6axyZTWfiFTufI28sJNOnC2p3PHV4txH1XdDGsAjw1AKM8qiHznMTSw5GXUbWqS7P7Qc1sDw93CQePCLuPXXr", "rewardRecipients": [ diff --git a/src/Miningcore.Tests/Blockchain/Cryptonote/CryptonoteJobTests.cs b/src/Miningcore.Tests/Blockchain/Cryptonote/CryptonoteJobTests.cs index 965d4da7e..b22a5ed6a 100644 --- a/src/Miningcore.Tests/Blockchain/Cryptonote/CryptonoteJobTests.cs +++ b/src/Miningcore.Tests/Blockchain/Cryptonote/CryptonoteJobTests.cs @@ -58,11 +58,11 @@ public void MoneroJob_Should_Accept_Valid_Share() "{\"blocktemplate_blob\":\"0106e7eabdcf058234351e2e6ea901a56b33bb531587424321873072d80a9e97295b6c43152b9d00000000019c0201ffe00106e3a1a0cc010275d92c0a057aa5f073079694a153d426f837f49fdb9654da10a5364e79a2086280a0d9e61d028b46dca0d04998500b40b046fd6f8bb33229e6380fd465dbb1327aa6f813d8bd80c0fc82aa0202372f076459e769116d604d30aabff7160782acc0d20e0c5cdc8963ed4e16372f8090cad2c60e02f009504ce65538bbb684b466b21be3a90e3740f185d7089d37b75f0cf62b6e7680e08d84ddcb0102cf01b85c0b592bb6e508e20b5d317052b75de121908390363201abff3476ef0180c0caf384a302024b81076c8ad0cfe84cc32fe0813d63cdd0f7d8d0e56d82aa3f58cbbe49d4c61e2b017aaf3074be7ecb30a769595758e4da7c7c87ead864baf89b679b73153dfa352c0208000000000000000000\",\"Difficulty\":2,\"Height\":224,\"prev_hash\":\"8234351e2e6ea901a56b33bb531587424321873072d80a9e97295b6c43152b9d\",\"reserved_offset\":322,\"Status\":\"OK\"}"); var job = new CryptonoteJob(bt, "d150da".HexToByteArray(), "1", poolConfig, clusterConfig); - var (share, blobHex, blobHash) = job.ProcessShare("040100a4", 1, "f29c7fbf57d97eeedb61555857d7a34314250da20742b8157f96e0be89530a00", worker); + var (share, blobHex) = job.ProcessShare("040100a4", 1, "f29c7fbf57d97eeedb61555857d7a34314250da20742b8157f96e0be89530a00", worker); Assert.NotNull(share); Assert.True(share.IsBlockCandidate); - Assert.Equal(blobHash, "9258faf2dff5daf026681b5fa5d94a34dbb5bade1d9e2070865ba8c68f8f0454"); + Assert.Equal(share.BlockHash, "9258faf2dff5daf026681b5fa5d94a34dbb5bade1d9e2070865ba8c68f8f0454"); Assert.Equal(blobHex, "0106e7eabdcf058234351e2e6ea901a56b33bb531587424321873072d80a9e97295b6c43152b9d040100a4019c0201ffe00106e3a1a0cc010275d92c0a057aa5f073079694a153d426f837f49fdb9654da10a5364e79a2086280a0d9e61d028b46dca0d04998500b40b046fd6f8bb33229e6380fd465dbb1327aa6f813d8bd80c0fc82aa0202372f076459e769116d604d30aabff7160782acc0d20e0c5cdc8963ed4e16372f8090cad2c60e02f009504ce65538bbb684b466b21be3a90e3740f185d7089d37b75f0cf62b6e7680e08d84ddcb0102cf01b85c0b592bb6e508e20b5d317052b75de121908390363201abff3476ef0180c0caf384a302024b81076c8ad0cfe84cc32fe0813d63cdd0f7d8d0e56d82aa3f58cbbe49d4c61e2b017aaf3074be7ecb30a769595758e4da7c7c87ead864baf89b679b73153dfa352c02080000000001d150da00"); Assert.Equal(share.BlockHeight, 224); Assert.Equal(share.Difficulty, 1000); diff --git a/src/Miningcore.Tests/Crypto/CrytonoteTests.cs b/src/Miningcore.Tests/Crypto/CrytonoteTests.cs index fbbf725ea..824add085 100644 --- a/src/Miningcore.Tests/Crypto/CrytonoteTests.cs +++ b/src/Miningcore.Tests/Crypto/CrytonoteTests.cs @@ -2,7 +2,8 @@ using Miningcore.Extensions; using Miningcore.Native; using Xunit; - +using static Miningcore.Native.LibCryptonight; + namespace Miningcore.Tests.Crypto { public class CrytonoteTests : TestBase @@ -13,13 +14,13 @@ public void Crytonight() var blobConverted = "0106a2aaafd505583cf50bcc743d04d831d2b119dc94ad88679e359076ee3f18d258ee138b3b42580100a4b1e2f4baf6ab7109071ab59bc52dba740d1de99fa0ae0c4afd6ea9f40c5d87ec01".HexToByteArray(); var buf = new byte[32]; - LibCryptonight.Cryptonight(blobConverted, buf, 0); + LibCryptonight.Cryptonight(blobConverted, buf, CryptonightVariant.VARIANT_0); var result = buf.ToHexString(); Assert.Equal("a845ffbdf83ae9a8ffa504a1011efbd5ed2294bb9da591d3b583740568402c00", result); Array.Clear(buf,0, buf.Length); - LibCryptonight.Cryptonight(blobConverted, buf, 0); + LibCryptonight.Cryptonight(blobConverted, buf, CryptonightVariant.VARIANT_0); result = buf.ToHexString(); Assert.Equal("a845ffbdf83ae9a8ffa504a1011efbd5ed2294bb9da591d3b583740568402c00", result); } @@ -30,13 +31,13 @@ public void Crytonight_Variant_1() var blobConverted = "0106a2aaafd505583cf50bcc743d04d831d2b119dc94ad88679e359076ee3f18d258ee138b3b42580100a4b1e2f4baf6ab7109071ab59bc52dba740d1de99fa0ae0c4afd6ea9f40c5d87ec01".HexToByteArray(); var buf = new byte[32]; - LibCryptonight.Cryptonight(blobConverted, buf, 1); + LibCryptonight.Cryptonight(blobConverted, buf, CryptonightVariant.VARIANT_1); var result = buf.ToHexString(); Assert.Equal("c41ec6434df8b2307ff3105ae15206f3fbdf5a99b35879c0a27b8b85a8e2704f", result); Array.Clear(buf, 0, buf.Length); - LibCryptonight.Cryptonight(blobConverted, buf, 1); + LibCryptonight.Cryptonight(blobConverted, buf, CryptonightVariant.VARIANT_1); result = buf.ToHexString(); Assert.Equal("c41ec6434df8b2307ff3105ae15206f3fbdf5a99b35879c0a27b8b85a8e2704f", result); } @@ -58,13 +59,13 @@ public void Crytonight_Light() var blobConverted = "0106f1adafd505583cf50bcc743d04d831d2b119dc94ad88679e359076ee3f18d258ee138b3b42597710c48c6d885e2622f40f82ecd9b9fd538f28df9b0557e07cd3237a31c76569ada98001".HexToByteArray(); var buf = new byte[32]; - LibCryptonight.CryptonightLight(blobConverted, buf, 0); + LibCryptonight.CryptonightLight(blobConverted, buf, CryptonightVariant.VARIANT_0); var result = buf.ToHexString(); Assert.Equal("0769caee428a232cffb76fa200f174ff962734f24e7b3bf8d1b0d4e8ba6ceebf", result); Array.Clear(buf, 0, buf.Length); - LibCryptonight.CryptonightLight(blobConverted, buf, 0); + LibCryptonight.CryptonightLight(blobConverted, buf, CryptonightVariant.VARIANT_0); result = buf.ToHexString(); Assert.Equal("0769caee428a232cffb76fa200f174ff962734f24e7b3bf8d1b0d4e8ba6ceebf", result); } @@ -75,13 +76,13 @@ public void Crytonight_Light_Variant_1() var blobConverted = "0106f1adafd505583cf50bcc743d04d831d2b119dc94ad88679e359076ee3f18d258ee138b3b42597710c48c6d885e2622f40f82ecd9b9fd538f28df9b0557e07cd3237a31c76569ada98001".HexToByteArray(); var buf = new byte[32]; - LibCryptonight.CryptonightLight(blobConverted, buf, 0); + LibCryptonight.CryptonightLight(blobConverted, buf, CryptonightVariant.VARIANT_0); var result = buf.ToHexString(); Assert.Equal("0769caee428a232cffb76fa200f174ff962734f24e7b3bf8d1b0d4e8ba6ceebf", result); Array.Clear(buf, 0, buf.Length); - LibCryptonight.CryptonightLight(blobConverted, buf, 0); + LibCryptonight.CryptonightLight(blobConverted, buf, CryptonightVariant.VARIANT_0); result = buf.ToHexString(); Assert.Equal("0769caee428a232cffb76fa200f174ff962734f24e7b3bf8d1b0d4e8ba6ceebf", result); } @@ -92,13 +93,13 @@ public void Crytonight_Heavy() var blobConverted = "0106f1adafd505583cf50bcc743d04d831d2b119dc94ad88679e359076ee3f18d258ee138b3b42597710c48c6d885e2622f40f82ecd9b9fd538f28df9b0557e07cd3237a31c76569ada98001".HexToByteArray(); var buf = new byte[32]; - LibCryptonight.CryptonightHeavy(blobConverted, buf, 0); + LibCryptonight.CryptonightHeavy(blobConverted, buf, CryptonightVariant.VARIANT_0); var result = buf.ToHexString(); Assert.Equal("1559665f933c0aab5bf2b11db406b9db170a78d82d180ee5a7cf88f1c2041f9e", result); Array.Clear(buf, 0, buf.Length); - LibCryptonight.CryptonightHeavy(blobConverted, buf, 0); + LibCryptonight.CryptonightHeavy(blobConverted, buf, CryptonightVariant.VARIANT_0); result = buf.ToHexString(); Assert.Equal("1559665f933c0aab5bf2b11db406b9db170a78d82d180ee5a7cf88f1c2041f9e", result); } @@ -109,13 +110,13 @@ public void Crytonight_Heavy_Variant_1() var blobConverted = "0106f1adafd505583cf50bcc743d04d831d2b119dc94ad88679e359076ee3f18d258ee138b3b42597710c48c6d885e2622f40f82ecd9b9fd538f28df9b0557e07cd3237a31c76569ada98001".HexToByteArray(); var buf = new byte[32]; - LibCryptonight.CryptonightHeavy(blobConverted, buf, 1); + LibCryptonight.CryptonightHeavy(blobConverted, buf, CryptonightVariant.VARIANT_1); var result = buf.ToHexString(); Assert.Equal("342418ec4bf806aafb102b34d64fc33ab91d89ad40786b92d1b54ceeb4d50822", result); Array.Clear(buf, 0, buf.Length); - LibCryptonight.CryptonightHeavy(blobConverted, buf, 1); + LibCryptonight.CryptonightHeavy(blobConverted, buf, CryptonightVariant.VARIANT_1); result = buf.ToHexString(); Assert.Equal("342418ec4bf806aafb102b34d64fc33ab91d89ad40786b92d1b54ceeb4d50822", result); } diff --git a/src/Miningcore/Api/Responses/GetPoolsResponse.cs b/src/Miningcore/Api/Responses/GetPoolsResponse.cs index 87236aa4f..c190828b8 100644 --- a/src/Miningcore/Api/Responses/GetPoolsResponse.cs +++ b/src/Miningcore/Api/Responses/GetPoolsResponse.cs @@ -30,6 +30,7 @@ namespace Miningcore.Api.Responses public class ApiCoinConfig { public string Type { get; set; } + public string Name { get; set; } public string Algorithm { get; set; } } diff --git a/src/Miningcore/Blockchain/Bitcoin/BitcoinPool.cs b/src/Miningcore/Blockchain/Bitcoin/BitcoinPool.cs index 1fe9c052c..dd55a16fe 100644 --- a/src/Miningcore/Blockchain/Bitcoin/BitcoinPool.cs +++ b/src/Miningcore/Blockchain/Bitcoin/BitcoinPool.cs @@ -120,8 +120,8 @@ protected virtual async Task OnAuthorizeAsync(StratumClient client, Timestamped< // assumes that workerName is an address context.IsAuthorized = !string.IsNullOrEmpty(minerName) && await manager.ValidateAddressAsync(minerName, ct); - context.MinerName = minerName; - context.WorkerName = workerName; + context.Miner = minerName; + context.Worker = workerName; if (context.IsAuthorized) { diff --git a/src/Miningcore/Blockchain/Bitcoin/BitcoinWorkerContext.cs b/src/Miningcore/Blockchain/Bitcoin/BitcoinWorkerContext.cs index 53b4a03e7..c9f2daf32 100644 --- a/src/Miningcore/Blockchain/Bitcoin/BitcoinWorkerContext.cs +++ b/src/Miningcore/Blockchain/Bitcoin/BitcoinWorkerContext.cs @@ -24,8 +24,15 @@ namespace Miningcore.Blockchain.Bitcoin { public class BitcoinWorkerContext : WorkerContextBase { - public string MinerName { get; set; } - public string WorkerName { get; set; } + /// + /// Usually a wallet address + /// + public string Miner { get; set; } + + /// + /// Arbitrary worker identififer for miners using multiple rigs + /// + public string Worker { get; set; } public string ExtraNonce1 { get; set; } } diff --git a/src/Miningcore/Blockchain/Cryptonote/CryptonoteJob.cs b/src/Miningcore/Blockchain/Cryptonote/CryptonoteJob.cs index 142dca89c..44e2ad730 100644 --- a/src/Miningcore/Blockchain/Cryptonote/CryptonoteJob.cs +++ b/src/Miningcore/Blockchain/Cryptonote/CryptonoteJob.cs @@ -28,6 +28,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. using Miningcore.Stratum; using Miningcore.Util; using NBitcoin.BouncyCastle.Math; +using static Miningcore.Native.LibCryptonight; using Contract = Miningcore.Contracts.Contract; namespace Miningcore.Blockchain.Cryptonote @@ -162,11 +163,31 @@ public void PrepareWorkerJob(CryptonoteWorkerJob workerJob, out string blob, out if (blobConverted == null) throw new StratumException(StratumError.MinusOne, "malformed blob"); - // hash it - Span headerHash = stackalloc byte[32]; - var variant = coin.HashVariant != 0 ? - coin.HashVariant : ((blobConverted[0] >= 7 ? blobConverted[0] - 6 : 0)); + // determine variant + CryptonightVariant variant; + if (coin.HashVariant != 0) + variant = (CryptonightVariant)coin.HashVariant; + else + { + switch(blobConverted[0]) + { + case 9: + variant = CryptonightVariant.VARIANT_2; + break; + + case 7: + variant = CryptonightVariant.VARIANT_1; + break; + + default: + variant = CryptonightVariant.VARIANT_0; + break; + } + } + + // hash it + Span headerHash = stackalloc byte[32]; hashFunc(blobConverted, headerHash, variant); var headerHashString = headerHash.ToHexString(); diff --git a/src/Miningcore/Blockchain/Cryptonote/CryptonoteJobManager.cs b/src/Miningcore/Blockchain/Cryptonote/CryptonoteJobManager.cs index 16694336b..8d5338f69 100644 --- a/src/Miningcore/Blockchain/Cryptonote/CryptonoteJobManager.cs +++ b/src/Miningcore/Blockchain/Cryptonote/CryptonoteJobManager.cs @@ -40,6 +40,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. using Miningcore.Messaging; using Miningcore.Native; using Miningcore.Notifications.Messages; +using Miningcore.Payments; using Miningcore.Stratum; using Miningcore.Time; using Miningcore.Util; @@ -321,9 +322,8 @@ public async Task SubmitShareAsync(StratumClient worker, // enrich share with common data share.PoolId = poolConfig.Id; share.IpAddress = worker.RemoteEndpoint.Address.ToString(); - share.Miner = context.MinerName; - share.Worker = context.WorkerName; - share.PayoutInfo = context.PaymentId; + share.Miner = context.Miner; + share.Worker = context.Worker; share.UserAgent = context.UserAgent; share.Source = clusterConfig.ClusterName; share.NetworkDifficulty = job.BlockTemplate.Difficulty; @@ -338,7 +338,7 @@ public async Task SubmitShareAsync(StratumClient worker, if (share.IsBlockCandidate) { - logger.Info(() => $"Daemon accepted block {share.BlockHeight} [{share.BlockHash.Substring(0, 6)}] submitted by {context.MinerName}"); + logger.Info(() => $"Daemon accepted block {share.BlockHeight} [{share.BlockHash.Substring(0, 6)}] submitted by {context.Miner}"); blockSubmissionSubject.OnNext(Unit.Default); share.TransactionConfirmationData = share.BlockHash; diff --git a/src/Miningcore/Blockchain/Cryptonote/CryptonotePool.cs b/src/Miningcore/Blockchain/Cryptonote/CryptonotePool.cs index d2e00456d..dcea90737 100644 --- a/src/Miningcore/Blockchain/Cryptonote/CryptonotePool.cs +++ b/src/Miningcore/Blockchain/Cryptonote/CryptonotePool.cs @@ -34,6 +34,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. using Miningcore.Messaging; using Miningcore.Mining; using Miningcore.Notifications.Messages; +using Miningcore.Payments; using Miningcore.Persistence; using Miningcore.Persistence.Repositories; using Miningcore.Stratum; @@ -63,7 +64,6 @@ public CryptonotePool(IComponentContext ctx, private async Task OnLoginAsync(StratumClient client, Timestamped tsRequest) { var request = tsRequest.Value; - var context = client.ContextAs(); if (request.Id == null) @@ -76,33 +76,37 @@ private async Task OnLoginAsync(StratumClient client, Timestamped 1 ? split[1].Trim() : null; + context.Miner = split[0].Trim(); + context.Worker = split.Length > 1 ? split[1].Trim() : null; context.UserAgent = loginRequest.UserAgent?.Trim(); - var passParts = loginRequest.Password?.Split(PasswordControlVarsSeparator); + var addressToValidate = context.Miner; + // extract paymentid - var index = context.MinerName.IndexOf('#'); + var index = context.Miner.IndexOf('#'); if (index != -1) { - context.PaymentId = context.MinerName.Substring(index + 1).Trim(); - context.MinerName = context.MinerName.Substring(0, index).Trim(); - } - - // validate login - var result = manager.ValidateAddress(context.MinerName); + var paymentId = context.Miner.Substring(index + 1).Trim(); + + // validate + if (!string.IsNullOrEmpty(paymentId) && paymentId.Length != CryptonoteConstants.PaymentIdHexLength) + throw new StratumException(StratumError.MinusOne, "invalid payment id"); + + // re-append to address + addressToValidate = context.Miner.Substring(0, index).Trim(); + context.Miner = addressToValidate + PayoutConstants.PayoutInfoSeperator + paymentId; + } + + // validate login + var result = manager.ValidateAddress(addressToValidate); + if (!result) + throw new StratumException(StratumError.MinusOne, "invalid login"); context.IsSubscribed = result; context.IsAuthorized = result; - if (!context.IsAuthorized) - throw new StratumException(StratumError.MinusOne, "invalid login"); - - // validate payment Id - if (!string.IsNullOrEmpty(context.PaymentId) && context.PaymentId.Length != CryptonoteConstants.PaymentIdHexLength) - throw new StratumException(StratumError.MinusOne, "invalid payment id"); - // extract control vars from password + var passParts = loginRequest.Password?.Split(PasswordControlVarsSeparator); var staticDiff = GetStaticDiffFromPassparts(passParts); if (staticDiff.HasValue && (context.VarDiff != null && staticDiff.Value >= context.VarDiff.Config.MinDiff || @@ -124,13 +128,15 @@ private async Task OnLoginAsync(StratumClient client, Timestamped $"[{client.ConnectionId}] Authorized worker {loginRequest.Login}"); + if(!string.IsNullOrEmpty(context.Worker)) + logger.Info(() => $"[{client.ConnectionId}] Authorized worker {context.Worker}@{context.Miner}"); + else + logger.Info(() => $"[{client.ConnectionId}] Authorized miner {context.Miner}"); } private async Task OnGetJobAsync(StratumClient client, Timestamped tsRequest) { var request = tsRequest.Value; - var context = client.ContextAs(); if (request.Id == null) diff --git a/src/Miningcore/Blockchain/Cryptonote/CryptonoteWorkerContext.cs b/src/Miningcore/Blockchain/Cryptonote/CryptonoteWorkerContext.cs index bea8ccb4f..ed5e33450 100644 --- a/src/Miningcore/Blockchain/Cryptonote/CryptonoteWorkerContext.cs +++ b/src/Miningcore/Blockchain/Cryptonote/CryptonoteWorkerContext.cs @@ -21,15 +21,21 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. using System.Collections.Generic; using System.Linq; using Miningcore.Mining; -using Miningcore.Time; namespace Miningcore.Blockchain.Cryptonote { public class CryptonoteWorkerContext : WorkerContextBase { - public string MinerName { get; set; } - public string WorkerName { get; set; } - public string PaymentId { get; set; } + /// + /// Usually a wallet address + /// NOTE: May include paymentid (seperated by a dot .) + /// + public string Miner { get; set; } + + /// + /// Arbitrary worker identififer for miners using multiple rigs + /// + public string Worker { get; set; } private List validJobs { get; } = new List(); diff --git a/src/Miningcore/Blockchain/Equihash/EquihashPool.cs b/src/Miningcore/Blockchain/Equihash/EquihashPool.cs index a42f9600f..1643e7f31 100644 --- a/src/Miningcore/Blockchain/Equihash/EquihashPool.cs +++ b/src/Miningcore/Blockchain/Equihash/EquihashPool.cs @@ -171,8 +171,8 @@ protected async Task OnAuthorizeAsync(StratumClient client, Timestamped SubmitShareAsync(StratumClient worker, if (share.IsBlockCandidate) { - logger.Info(() => $"Daemon accepted block {share.BlockHeight} submitted by {context.MinerName}"); + logger.Info(() => $"Daemon accepted block {share.BlockHeight} submitted by {context.Miner}"); } } diff --git a/src/Miningcore/Blockchain/Ethereum/EthereumPool.cs b/src/Miningcore/Blockchain/Ethereum/EthereumPool.cs index 10856856d..48c498000 100644 --- a/src/Miningcore/Blockchain/Ethereum/EthereumPool.cs +++ b/src/Miningcore/Blockchain/Ethereum/EthereumPool.cs @@ -114,8 +114,8 @@ private async Task OnAuthorizeAsync(StratumClient client, Timestamped + /// Usually a wallet address + /// + public string Miner { get; set; } + + /// + /// Arbitrary worker identififer for miners using multiple rigs + /// + public string Worker { get; set; } + public bool IsInitialWorkSent { get; set; } = false; public string ExtraNonce1 { get; set; } diff --git a/src/Miningcore/Blockchain/Share.cs b/src/Miningcore/Blockchain/Share.cs index 82cdcd85a..1ffe63ae1 100644 --- a/src/Miningcore/Blockchain/Share.cs +++ b/src/Miningcore/Blockchain/Share.cs @@ -1,20 +1,20 @@ -/* +/* Copyright 2017 Coin Foundry (coinfoundry.org) Authors: Oliver Weichhold (oliver@weichhold.com) -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all copies or substantial +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT -LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ @@ -44,12 +44,6 @@ public class Share [ProtoMember(3)] public string Worker { get; set; } - /// - /// Extra information for payout processing - /// - [ProtoMember(4)] - public string PayoutInfo { get; set; } - /// /// Mining Software /// diff --git a/src/Miningcore/Extensions/StringExtensions.cs b/src/Miningcore/Extensions/StringExtensions.cs index 9d34f334b..ea770af92 100644 --- a/src/Miningcore/Extensions/StringExtensions.cs +++ b/src/Miningcore/Extensions/StringExtensions.cs @@ -95,6 +95,14 @@ public static string ToStringHexWithPrefix(this int value) return "0x" + value.ToString("x", CultureInfo.InvariantCulture); } + public static string StripHexPrefix(this string value) + { + if (value?.ToLower().StartsWith("0x") == true) + return value.Substring(2); + + return value; + } + public static T IntegralFromHex(this string value) { var underlyingType = Nullable.GetUnderlyingType(typeof(T)); diff --git a/src/Miningcore/Mining/ShareReceiver.cs b/src/Miningcore/Mining/ShareReceiver.cs index 2784c85fb..41506f3c9 100644 --- a/src/Miningcore/Mining/ShareReceiver.cs +++ b/src/Miningcore/Mining/ShareReceiver.cs @@ -12,6 +12,7 @@ using Miningcore.Crypto; using Miningcore.Extensions; using Miningcore.Messaging; +using Miningcore.Payments; using Miningcore.Time; using Miningcore.Util; using Newtonsoft.Json; @@ -57,8 +58,6 @@ public PoolContext(IMiningPool pool, ILogger logger) public long BlockHeight; } - private readonly TimeSpan relayReceiveTimeout = TimeSpan.FromSeconds(60); - private void StartListeners() { var serializer = new JsonSerializer @@ -84,7 +83,6 @@ private void StartListeners() using(var subSocket = new ZSocket(ZSocketType.SUB)) { subSocket.SetupCurveTlsClient(relay.SharedEncryptionKey, logger); - subSocket.ReceiveTimeout = relayReceiveTimeout; subSocket.Connect(url); subSocket.SubscribeAll(); diff --git a/src/Miningcore/Mining/StatsRecorder.cs b/src/Miningcore/Mining/StatsRecorder.cs index c25069b05..9628a27f6 100644 --- a/src/Miningcore/Mining/StatsRecorder.cs +++ b/src/Miningcore/Mining/StatsRecorder.cs @@ -91,6 +91,7 @@ public void Start() try { UpdatePoolHashrates(); + PerformStatsGc(); } catch(Exception ex) @@ -132,9 +133,7 @@ private void UpdatePoolHashrates() Created = start }; - var poolIds = pools.Keys; - - foreach(var poolId in poolIds) + foreach(var poolId in pools.Keys) { stats.PoolId = poolId; @@ -214,6 +213,26 @@ private void UpdatePoolHashrates() } } + private void PerformStatsGc() + { + logger.Info(() => $"Performing Stats GC"); + + cf.Run(con => + { + var cutOff = DateTime.UtcNow.AddMonths(-3); + + var rowCount = statsRepo.DeletePoolStatsBefore(con, cutOff); + if(rowCount > 0) + logger.Info(() => $"Deleted {rowCount} old poolstats records"); + + rowCount = statsRepo.DeleteMinerStatsBefore(con, cutOff); + if (rowCount > 0) + logger.Info(() => $"Deleted {rowCount} old minerstats records"); + }); + + logger.Info(() => $"Stats GC complete"); + } + private void BuildFaultHandlingPolicy() { var retry = Policy diff --git a/src/Miningcore/Native/LibCryptonight.cs b/src/Miningcore/Native/LibCryptonight.cs index 83eac56ac..1089d9be7 100644 --- a/src/Miningcore/Native/LibCryptonight.cs +++ b/src/Miningcore/Native/LibCryptonight.cs @@ -103,21 +103,37 @@ internal void Return(Lazy ctx) private static extern void cryptonight_free_context(IntPtr ptr); [DllImport("libcryptonight", EntryPoint = "cryptonight_export", CallingConvention = CallingConvention.Cdecl)] - private static extern int cryptonight(IntPtr ctx, byte* input, byte* output, uint inputLength, int variant); + private static extern int cryptonight(IntPtr ctx, byte* input, byte* output, uint inputLength, CryptonightVariant variant); [DllImport("libcryptonight", EntryPoint = "cryptonight_light_export", CallingConvention = CallingConvention.Cdecl)] - private static extern int cryptonight_light(IntPtr ctx, byte* input, byte* output, uint inputLength, int variant); + private static extern int cryptonight_light(IntPtr ctx, byte* input, byte* output, uint inputLength, CryptonightVariant variant); [DllImport("libcryptonight", EntryPoint = "cryptonight_heavy_export", CallingConvention = CallingConvention.Cdecl)] - private static extern int cryptonight_heavy(IntPtr ctx, byte* input, byte* output, uint inputLength, int variant); + private static extern int cryptonight_heavy(IntPtr ctx, byte* input, byte* output, uint inputLength, CryptonightVariant variant); - public delegate void CryptonightHash(ReadOnlySpan data, Span result, int variant); + public delegate void CryptonightHash(ReadOnlySpan data, Span result, CryptonightVariant variant); + + // see https://github.com/xmrig/xmrig/blob/master/src/common/xmrig.h + public enum CryptonightVariant + { + VARIANT_AUTO = -1, // Autodetect + VARIANT_0 = 0, // Original CryptoNight or CryptoNight-Heavy + VARIANT_1 = 1, // CryptoNight variant 1 also known as Monero7 and CryptoNightV7 + VARIANT_TUBE = 2, // Modified CryptoNight-Heavy (TUBE only) + VARIANT_XTL = 3, // Modified CryptoNight variant 1 (Stellite only) + VARIANT_MSR = 4, // Modified CryptoNight variant 1 (Masari only) + VARIANT_XHV = 5, // Modified CryptoNight-Heavy (Haven Protocol only) + VARIANT_XAO = 6, // Modified CryptoNight variant 0 (Alloy only) + VARIANT_RTO = 7, // Modified CryptoNight variant 1 (Arto only) + VARIANT_2 = 8, // CryptoNight variant 2 + VARIANT_MAX + }; /// /// Cryptonight Hash (Monero, Monero v7, v8 etc.) /// /// Algorithm variant - public static void Cryptonight(ReadOnlySpan data, Span result, int variant) + public static void Cryptonight(ReadOnlySpan data, Span result, CryptonightVariant variant) { Contract.Requires(result.Length >= 32, $"{nameof(result)} must be greater or equal 32 bytes"); @@ -144,7 +160,7 @@ public static void Cryptonight(ReadOnlySpan data, Span result, int v /// Cryptonight Lite Hash (AEON etc.) /// /// Algorithm variant - public static void CryptonightLight(ReadOnlySpan data, Span result, int variant) + public static void CryptonightLight(ReadOnlySpan data, Span result, CryptonightVariant variant) { Contract.Requires(result.Length >= 32, $"{nameof(result)} must be greater or equal 32 bytes"); @@ -171,7 +187,7 @@ public static void CryptonightLight(ReadOnlySpan data, Span result, /// Cryptonight Heavy Hash (TUBE etc.) /// /// Algorithm variant - public static void CryptonightHeavy(ReadOnlySpan data, Span result, int variant) + public static void CryptonightHeavy(ReadOnlySpan data, Span result, CryptonightVariant variant) { Contract.Requires(result.Length >= 32, $"{nameof(result)} must be greater or equal 32 bytes"); @@ -192,6 +208,6 @@ public static void CryptonightHeavy(ReadOnlySpan data, Span result, { ctxsHeavy.Return(ctx); } - } + } } } diff --git a/src/Miningcore/Payments/PaymentSchemes/PPLNSPaymentScheme.cs b/src/Miningcore/Payments/PaymentSchemes/PPLNSPaymentScheme.cs index 9a81675f0..dbbcdc30c 100644 --- a/src/Miningcore/Payments/PaymentSchemes/PPLNSPaymentScheme.cs +++ b/src/Miningcore/Payments/PaymentSchemes/PPLNSPaymentScheme.cs @@ -147,11 +147,7 @@ private void LogDiscardedShares(PoolConfig poolConfig, Block block, DateTime val for(var i = 0; i < page.Length; i++) { var share = page[i]; - - // build address var address = share.Miner; - if (!string.IsNullOrEmpty(share.PayoutInfo)) - address += PayoutConstants.PayoutInfoSeperator + share.PayoutInfo; // record attributed shares for diagnostic purposes if (!shares.ContainsKey(address)) @@ -209,8 +205,6 @@ private void LogDiscardedShares(PoolConfig poolConfig, Block block, DateTime val // build address var address = share.Miner; - if (!string.IsNullOrEmpty(share.PayoutInfo)) - address += PayoutConstants.PayoutInfoSeperator + share.PayoutInfo; // record attributed shares for diagnostic purposes if (!shares.ContainsKey(address)) diff --git a/src/Miningcore/Persistence/Model/Share.cs b/src/Miningcore/Persistence/Model/Share.cs index 73dafefc6..5b81f2c61 100644 --- a/src/Miningcore/Persistence/Model/Share.cs +++ b/src/Miningcore/Persistence/Model/Share.cs @@ -26,7 +26,6 @@ public class Share { public string PoolId { get; set; } public ulong BlockHeight { get; set; } - public string PayoutInfo { get; set; } public string Miner { get; set; } public string Worker { get; set; } public string UserAgent { get; set; } diff --git a/src/Miningcore/Persistence/Postgres/Entities/Share.cs b/src/Miningcore/Persistence/Postgres/Entities/Share.cs index bdc5cac87..7e21e72d4 100644 --- a/src/Miningcore/Persistence/Postgres/Entities/Share.cs +++ b/src/Miningcore/Persistence/Postgres/Entities/Share.cs @@ -26,7 +26,6 @@ public class Share { public string PoolId { get; set; } public long BlockHeight { get; set; } - public string PayoutInfo { get; set; } public string Miner { get; set; } public string Worker { get; set; } public string UserAgent { get; set; } diff --git a/src/Miningcore/Persistence/Postgres/Repositories/ShareRepository.cs b/src/Miningcore/Persistence/Postgres/Repositories/ShareRepository.cs index 8d0c87b28..b8419cdba 100644 --- a/src/Miningcore/Persistence/Postgres/Repositories/ShareRepository.cs +++ b/src/Miningcore/Persistence/Postgres/Repositories/ShareRepository.cs @@ -49,9 +49,9 @@ public void Insert(IDbConnection con, IDbTransaction tx, Share share) var mapped = mapper.Map(share); var query = "INSERT INTO shares(poolid, blockheight, difficulty, " + - "networkdifficulty, miner, worker, payoutinfo, useragent, ipaddress, source, created) " + + "networkdifficulty, miner, worker, useragent, ipaddress, source, created) " + "VALUES(@poolid, @blockheight, @difficulty, " + - "@networkdifficulty, @miner, @worker, @payoutinfo, @useragent, @ipaddress, @source, @created)"; + "@networkdifficulty, @miner, @worker, @useragent, @ipaddress, @source, @created)"; con.Execute(query, mapped, tx); } diff --git a/src/Miningcore/Persistence/Postgres/Repositories/StatsRepository.cs b/src/Miningcore/Persistence/Postgres/Repositories/StatsRepository.cs index 6c8872c9a..cb1a3dad0 100644 --- a/src/Miningcore/Persistence/Postgres/Repositories/StatsRepository.cs +++ b/src/Miningcore/Persistence/Postgres/Repositories/StatsRepository.cs @@ -306,5 +306,23 @@ public MinerWorkerPerformanceStats[] PagePoolMinersByHashrate(IDbConnection con, .Select(mapper.Map) .ToArray(); } + + public int DeletePoolStatsBefore(IDbConnection con, DateTime date) + { + logger.LogInvoke(); + + var query = "DELETE FROM poolstats WHERE created < @date"; + + return con.Execute(query, new { date }); + } + + public int DeleteMinerStatsBefore(IDbConnection con, DateTime date) + { + logger.LogInvoke(); + + var query = "DELETE FROM minerstats WHERE created < @date"; + + return con.Execute(query, new { date }); + } } } diff --git a/src/Miningcore/Persistence/Postgres/Scripts/createdb.sql b/src/Miningcore/Persistence/Postgres/Scripts/createdb.sql index 7f9588a4b..4bcecdd5d 100644 --- a/src/Miningcore/Persistence/Postgres/Scripts/createdb.sql +++ b/src/Miningcore/Persistence/Postgres/Scripts/createdb.sql @@ -6,7 +6,6 @@ CREATE TABLE shares blockheight BIGINT NOT NULL, difficulty DOUBLE PRECISION NOT NULL, networkdifficulty DOUBLE PRECISION NOT NULL, - payoutinfo TEXT NULL, miner TEXT NOT NULL, worker TEXT NULL, useragent TEXT NULL, diff --git a/src/Miningcore/Persistence/Repositories/IStatsRepository.cs b/src/Miningcore/Persistence/Repositories/IStatsRepository.cs index 660928d6a..13d5fd7c6 100644 --- a/src/Miningcore/Persistence/Repositories/IStatsRepository.cs +++ b/src/Miningcore/Persistence/Repositories/IStatsRepository.cs @@ -37,5 +37,7 @@ public interface IStatsRepository MinerWorkerPerformanceStats[] PagePoolMinersByHashrate(IDbConnection con, string poolId, DateTime from, int page, int pageSize); WorkerPerformanceStatsContainer[] GetMinerPerformanceBetweenHourly(IDbConnection con, string poolId, string miner, DateTime start, DateTime end); WorkerPerformanceStatsContainer[] GetMinerPerformanceBetweenDaily(IDbConnection con, string poolId, string miner, DateTime start, DateTime end); + int DeletePoolStatsBefore(IDbConnection con, DateTime date); + int DeleteMinerStatsBefore(IDbConnection con, DateTime date); } } diff --git a/src/Miningcore/Stratum/StratumClient.cs b/src/Miningcore/Stratum/StratumClient.cs index d9101bb6d..b2e719f94 100644 --- a/src/Miningcore/Stratum/StratumClient.cs +++ b/src/Miningcore/Stratum/StratumClient.cs @@ -259,8 +259,11 @@ private async Task SendAsync(T payload) { ctsTimeout.CancelAfter(sendTimeout); - if (!await sendQueue.SendAsync(payload, ctsComposite.Token)) - throw new IOException($"Send queue stalled at {sendQueue.Count} of {SendQueueCapacity} items"); + if (!await sendQueue.SendAsync(payload, ctsComposite.Token)) + { + // this will force a disconnect down the line + throw new IOException($"Send queue stalled at {sendQueue.Count} of {SendQueueCapacity} items"); + } } } } @@ -271,15 +274,17 @@ private async Task FillReceivePipeAsync() { var memory = receivePipe.Writer.GetMemory(MaxInboundRequestLength + 1); + // read from network directly into pipe memory var cb = await networkStream.ReadAsync(memory, cts.Token); if (cb == 0) break; // EOF LastReceive = clock.Now; + + // hand off to pipe receivePipe.Writer.Advance(cb); var result = await receivePipe.Writer.FlushAsync(cts.Token); - if (result.IsCompleted) break; } @@ -328,24 +333,24 @@ private async Task ProcessSendQueueAsync() { while (true) { - var payload = await sendQueue.ReceiveAsync(cts.Token); + var msg = await sendQueue.ReceiveAsync(cts.Token); - await SendResponse(payload); + await SendMessage(msg); } } - private async Task SendResponse(object payload) + private async Task SendMessage(object msg) { - logger.Trace(() => $"[{ConnectionId}] Sending: {JsonConvert.SerializeObject(payload)}"); + logger.Trace(() => $"[{ConnectionId}] Sending: {JsonConvert.SerializeObject(msg)}"); using(var ctsTimeout = new CancellationTokenSource()) { using(var ctsComposite = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, ctsTimeout.Token)) { - // serialize to JSON + // serialize to JSON directly onto network stream using(var writer = new StreamWriter(networkStream, StratumConstants.Encoding, MaxOutboundRequestLength, true)) { - serializer.Serialize(writer, payload); + serializer.Serialize(writer, msg); } // append terminator diff --git a/src/Miningcore/coins.json b/src/Miningcore/coins.json index 4ecee7eed..c9132e51a 100644 --- a/src/Miningcore/coins.json +++ b/src/Miningcore/coins.json @@ -347,9 +347,9 @@ "args": [{ "hash": "x16r" }] }, "shareMultiplier": 256, - "explorerBlockLink": "http://explorer.threeeyed.info/block/$hash$", - "explorerTxLink": "http://explorer.threeeyed.info/tx/{0}", - "explorerAccountLink": "http://explorer.threeeyed.info/address/{0}" + "explorerBlockLink": "https://ravencoin.network/block/$hash$", + "explorerTxLink": "https://ravencoin.network/tx/{0}", + "explorerAccountLink": "https://ravencoin.network/address/{0}" }, "pigeoncoin": { "name": "Pigeoncoin", @@ -1213,4 +1213,4 @@ "explorerTxLink": "https://gastracker.io/tx/{0}", "explorerAccountLink": "https://gastracker.io/addr/{0}" } -} \ No newline at end of file +} diff --git a/src/Native/libcryptonight/exports.cpp b/src/Native/libcryptonight/exports.cpp index 0e7904f77..5a5a1c4d4 100644 --- a/src/Native/libcryptonight/exports.cpp +++ b/src/Native/libcryptonight/exports.cpp @@ -99,23 +99,30 @@ extern "C" MODULE_API void cryptonight_export(cryptonight_ctx* ctx, const char* extern "C" MODULE_API void cryptonight_light_export(cryptonight_ctx* ctx, const char* input, unsigned char *output, uint32_t inputSize, uint32_t variant) { switch (variant) { - case 0: cryptonight_single_hash(reinterpret_cast(input), inputSize, reinterpret_cast(output), &ctx); + case 0: + cryptonight_single_hash(reinterpret_cast(input), inputSize, reinterpret_cast(output), &ctx); break; - case 1: cryptonight_single_hash(reinterpret_cast(input), inputSize, reinterpret_cast(output), &ctx); + case 1: + cryptonight_single_hash(reinterpret_cast(input), inputSize, reinterpret_cast(output), &ctx); break; - default: cryptonight_single_hash(reinterpret_cast(input), inputSize, reinterpret_cast(output), &ctx); + default: + cryptonight_single_hash(reinterpret_cast(input), inputSize, reinterpret_cast(output), &ctx); } } extern "C" MODULE_API void cryptonight_heavy_export(cryptonight_ctx* ctx, const char* input, unsigned char *output, uint32_t inputSize, uint32_t variant) { switch (variant) { - case 0: cryptonight_single_hash(reinterpret_cast(input), inputSize, reinterpret_cast(output), &ctx); + case 0: + cryptonight_single_hash(reinterpret_cast(input), inputSize, reinterpret_cast(output), &ctx); break; - case 1: cryptonight_single_hash(reinterpret_cast(input), inputSize, reinterpret_cast(output), &ctx); + case 1: + cryptonight_single_hash(reinterpret_cast(input), inputSize, reinterpret_cast(output), &ctx); break; - case 2: cryptonight_single_hash(reinterpret_cast(input), inputSize, reinterpret_cast(output), &ctx); + case 2: + cryptonight_single_hash(reinterpret_cast(input), inputSize, reinterpret_cast(output), &ctx); break; - default: cryptonight_single_hash(reinterpret_cast(input), inputSize, reinterpret_cast(output), &ctx); + default: + cryptonight_single_hash(reinterpret_cast(input), inputSize, reinterpret_cast(output), &ctx); } }