diff options
| author | Nsable-sh <nsable-sh@noreply.git.bitflash.network> | 2026-08-07 11:40:46 -0300 |
|---|---|---|
| committer | Bitflash <admin@bitflash.network> | 2026-08-07 15:05:18 -0300 |
| commit | 8c2e375600c0eb9bedb8f85ee4fa860825f23521 (patch) | |
| tree | 5701227e984e768ae9ed003f3447bff2dae92ee4 /src | |
| parent | 0b01d6cfce8be68150f5e06c11e13e0443372c4d (diff) | |
test: cover pool Stratum share accounting
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile | 1 | ||||
| -rw-r--r-- | src/makefile.mingw | 1 | ||||
| -rw-r--r-- | src/rpc.cpp | 85 | ||||
| -rw-r--r-- | src/selftest.cpp | 6 |
4 files changed, 92 insertions, 1 deletions
diff --git a/src/Makefile b/src/Makefile index cc52fd6..bc15ef8 100644 --- a/src/Makefile +++ b/src/Makefile | |||
| @@ -191,5 +191,6 @@ tests: test_bip32 bitflash-node | |||
| 191 | ./bitflash-node -selftest=wallet-encrypt | 191 | ./bitflash-node -selftest=wallet-encrypt |
| 192 | ./bitflash-node -selftest=net-message | 192 | ./bitflash-node -selftest=net-message |
| 193 | ./bitflash-node -selftest=consensus-limits | 193 | ./bitflash-node -selftest=consensus-limits |
| 194 | ./bitflash-node -selftest=pool-stratum | ||
| 194 | 195 | ||
| 195 | .PHONY: tests fuzz-net-message-smoke fuzz-script-smoke | 196 | .PHONY: tests fuzz-net-message-smoke fuzz-script-smoke |
diff --git a/src/makefile.mingw b/src/makefile.mingw index e076c49..b946e50 100644 --- a/src/makefile.mingw +++ b/src/makefile.mingw | |||
| @@ -116,3 +116,4 @@ tests: test_bip32.exe bitflash.exe | |||
| 116 | ./bitflash.exe -selftest=wallet-encrypt | 116 | ./bitflash.exe -selftest=wallet-encrypt |
| 117 | ./bitflash.exe -selftest=net-message | 117 | ./bitflash.exe -selftest=net-message |
| 118 | ./bitflash.exe -selftest=consensus-limits | 118 | ./bitflash.exe -selftest=consensus-limits |
| 119 | ./bitflash.exe -selftest=pool-stratum | ||
diff --git a/src/rpc.cpp b/src/rpc.cpp index 8f3740d..383769a 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp | |||
| @@ -1180,6 +1180,91 @@ static bool HandleLine(Miner* m, const std::string& rawLine, | |||
| 1180 | return true; | 1180 | return true; |
| 1181 | } | 1181 | } |
| 1182 | 1182 | ||
| 1183 | int RunPoolStratumSelfTest() | ||
| 1184 | { | ||
| 1185 | int nFail = 0; | ||
| 1186 | auto check = [&](bool ok, const char* msg) { | ||
| 1187 | fprintf(stdout, " %s %s\n", ok ? "ok" : "FAIL", msg); | ||
| 1188 | if (!ok) nFail++; | ||
| 1189 | }; | ||
| 1190 | |||
| 1191 | fprintf(stdout, "pool-stratum self-test\n"); | ||
| 1192 | |||
| 1193 | StratumJob savedJob = gCurrentJob; | ||
| 1194 | bool savedHaveJob = gHaveJob; | ||
| 1195 | |||
| 1196 | CTransaction coinbase; | ||
| 1197 | coinbase.vin.resize(1); | ||
| 1198 | coinbase.vin[0].prevout.SetNull(); | ||
| 1199 | coinbase.vin[0].scriptSig << 1 << (CBigNum)1; | ||
| 1200 | coinbase.vout.resize(1); | ||
| 1201 | coinbase.vout[0].nValue = 50 * COIN; | ||
| 1202 | |||
| 1203 | CBlock block; | ||
| 1204 | block.vtx.push_back(coinbase); | ||
| 1205 | block.nVersion = 1; | ||
| 1206 | block.nBits = 0x1f0fffff; | ||
| 1207 | block.nTime = 1; | ||
| 1208 | block.nNonce = 1; | ||
| 1209 | block.hashMerkleRoot = block.BuildMerkleTree(); | ||
| 1210 | |||
| 1211 | gCurrentJob.jobId = "selftest"; | ||
| 1212 | gCurrentJob.block = block; | ||
| 1213 | gCurrentJob.target = 0; // accepted share, not a block candidate | ||
| 1214 | gCurrentJob.height = 1; | ||
| 1215 | gHaveJob = true; | ||
| 1216 | |||
| 1217 | Miner miner(INVALID_SOCKET); | ||
| 1218 | miner.authorised = true; | ||
| 1219 | miner.address = "selftest-address"; | ||
| 1220 | miner.worker = "worker"; | ||
| 1221 | miner.shareTarget = ~uint256(0); // every RandomX hash is a valid share | ||
| 1222 | miner.difficulty = 0.001; | ||
| 1223 | miner.vardiffWindowStart = GetTime(); | ||
| 1224 | |||
| 1225 | std::map<std::string, uint64> roundShareCount; | ||
| 1226 | uint64 roundShareTotal = 0; | ||
| 1227 | int blocksFound = 0; | ||
| 1228 | |||
| 1229 | uint256 targetFromNotify; | ||
| 1230 | CBlock minerBlock = BuildMinerBlock(gCurrentJob, miner.extranonce2); | ||
| 1231 | json params = MakeNotifyParams(gCurrentJob, minerBlock, miner.shareTarget, true); | ||
| 1232 | std::vector<unsigned char> targetBytes = FromHex(params[3].get<std::string>()); | ||
| 1233 | if (targetBytes.size() == 32) | ||
| 1234 | memcpy(&targetFromNotify, &targetBytes[0], 32); | ||
| 1235 | check(targetFromNotify == miner.shareTarget, | ||
| 1236 | "mining.notify exposes the same share target the pool validates"); | ||
| 1237 | |||
| 1238 | json submit = { | ||
| 1239 | {"id", 7}, | ||
| 1240 | {"method", "mining.submit"}, | ||
| 1241 | {"params", json::array({miner.address, "selftest", ToHex(&minerBlock.nNonce, 4)})} | ||
| 1242 | }; | ||
| 1243 | HandleLine(&miner, submit.dump(), roundShareCount, roundShareTotal, blocksFound); | ||
| 1244 | |||
| 1245 | check(roundShareTotal == 1, "fake low-difficulty share increments the round total"); | ||
| 1246 | check(roundShareCount[miner.address] == 1, "fake share is credited to the submitting address"); | ||
| 1247 | check(miner.sessionShares == 1 && miner.roundShares == 1 && miner.totalShares == 1, | ||
| 1248 | "miner share counters advance together"); | ||
| 1249 | check(blocksFound == 0, "share below block target is not counted as a found block"); | ||
| 1250 | |||
| 1251 | json stale = { | ||
| 1252 | {"id", 8}, | ||
| 1253 | {"method", "mining.submit"}, | ||
| 1254 | {"params", json::array({miner.address, "stale", ToHex(&minerBlock.nNonce, 4)})} | ||
| 1255 | }; | ||
| 1256 | HandleLine(&miner, stale.dump(), roundShareCount, roundShareTotal, blocksFound); | ||
| 1257 | check(roundShareTotal == 1, "stale submit does not increment shares"); | ||
| 1258 | |||
| 1259 | gCurrentJob = savedJob; | ||
| 1260 | gHaveJob = savedHaveJob; | ||
| 1261 | |||
| 1262 | fprintf(stdout, "%s (%d failure%s)\n", nFail == 0 ? "ALL TESTS PASSED" : "TESTS FAILED", | ||
| 1263 | nFail, nFail == 1 ? "" : "s"); | ||
| 1264 | fflush(stdout); | ||
| 1265 | return nFail == 0 ? 0 : 1; | ||
| 1266 | } | ||
| 1267 | |||
| 1183 | // --------------------------------------------------------------------------- | 1268 | // --------------------------------------------------------------------------- |
| 1184 | // Stats refresh -- called every 2s from event loop | 1269 | // Stats refresh -- called every 2s from event loop |
| 1185 | // --------------------------------------------------------------------------- | 1270 | // --------------------------------------------------------------------------- |
diff --git a/src/selftest.cpp b/src/selftest.cpp index ff0289b..fadc959 100644 --- a/src/selftest.cpp +++ b/src/selftest.cpp | |||
| @@ -10,6 +10,8 @@ | |||
| 10 | #include "selftest.h" | 10 | #include "selftest.h" |
| 11 | #include "walletcmd.h" | 11 | #include "walletcmd.h" |
| 12 | 12 | ||
| 13 | extern int RunPoolStratumSelfTest(); | ||
| 14 | |||
| 13 | // Test results go to the terminal, not to debug.log. | 15 | // Test results go to the terminal, not to debug.log. |
| 14 | // | 16 | // |
| 15 | // printf in this tree is OutputDebugStringF, which writes into the data | 17 | // printf in this tree is OutputDebugStringF, which writes into the data |
| @@ -1234,8 +1236,10 @@ int RunSelfTest(const std::string& name) | |||
| 1234 | return RunNetMessageSelfTest(); | 1236 | return RunNetMessageSelfTest(); |
| 1235 | if (name == "consensus-limits") | 1237 | if (name == "consensus-limits") |
| 1236 | return RunConsensusLimitsSelfTest(); | 1238 | return RunConsensusLimitsSelfTest(); |
| 1239 | if (name == "pool-stratum") | ||
| 1240 | return RunPoolStratumSelfTest(); | ||
| 1237 | 1241 | ||
| 1238 | printf("Unknown self-test '%s'\n", name.c_str()); | 1242 | printf("Unknown self-test '%s'\n", name.c_str()); |
| 1239 | printf("Known self-tests: wallet-keypool, wallet-hd, wallet-format, wallet-crypto, wallet-encrypt, net-message, consensus-limits\n"); | 1243 | printf("Known self-tests: wallet-keypool, wallet-hd, wallet-format, wallet-crypto, wallet-encrypt, net-message, consensus-limits, pool-stratum\n"); |
| 1240 | return 1; | 1244 | return 1; |
| 1241 | } | 1245 | } |