update#431
Open
itsmylife44 wants to merge 3073 commits into
Open
Conversation
Contributor
|
It is the biggest pull request in one hit that I have ever seen in Github. 🙈 To the moon 🚀. |
|
These changes will work on latest snipa pool if I add them? what is best way to implement them? it will work for Aeon still? I am worried about DB changes |
Contributor
|
It works with Aeon, of course. Aeon is a sibling of Monero, much simpler than other coins. |
c8f6dd3 to
3f45f35
Compare
8aa7251 to
054f3e1
Compare
Correct the misspelling in the human-readable subject/body of the sendAdminFyi block-submit-failure messages. The throttle/dedup keys (first argument) are unchanged, so notification behavior is identical.
Call the script_utils factory like the other user_/manage_ scripts instead of relying on the static createCli.init property. Behavior is identical since both resolve cli.init to initMini.init.
Remove unreachable `|| 0` fallback on miner.lastShareTime; Date.now()/1000 is always a positive number so the fallback is dead. Reorder the success path in block_reward_fix_common.js to close the cursor before committing the txn, matching the file's error/not-found paths and the dominant manage_scripts convention.
…ecosystem section
…on NaN
A login like "wallet+abc" set miner.difficulty = Number("abc") = NaN; the
min/max clamps are no-ops on NaN, so it reached the BigInt difficulty math
during the new-block broadcast and threw an uncaught RangeError that killed
the pool worker (an unauthenticated remote crash from any stratum client).
Fall back to the starting difficulty when the suffix is not a finite positive
number. Numeric suffixes are unaffected.
createBtcRpc.getAnyBlockHeaderByHash only checked that result.tx was a non-empty array, then parseBtcReward did 'for (const vout of block.tx[0].vout)' unguarded. A malformed/partial BTC-style daemon reply (tx[0] lacking vout, via reorg/resync/pruned/non-standard coinbase) threw an uncaught TypeError in the daemon-reply callback, crashing the block_manager into a payout crash-loop for RTM/RVN. Treat such a reply as a verify error (callback(true, body)) like the other error paths; valid replies are unaffected.
These daemon-reply callbacks run inside res.on('end') with no try/catch and no
process-level handler, so a malformed/partial reply threw an uncaught exception
that crashed the pool/block_manager process:
- createCryptonoteRpc: JSON.parse(body.result.json) + miner_tx.vout deref had
no guard -> wrap in try/catch and validate miner_tx.vout before use.
- Erg: accessed body.blockTransactions.transactions after only checking body.header.
- Xtm main/T: accessed body.result.header.* / body.result.metadata.* after only
checking body.result.
Each now returns a verify error (callback(true, body)) on a malformed reply,
matching the existing error paths. Well-formed replies are unaffected.
user_delete removed balance rows unconditionally, so deleting an account whose balance row has pending_batch_id set (reserved by an in-flight payout batch) would make the payment finalizer's reserved-row UPDATE mismatch and wedge payout recovery. Add the same pending_batch_id guard user_balance_move already has: refuse the delete (even under --force) when the row is reserved, and tell the operator to retry after the batch settles. Adds a regression test.
Flat config (eslint.config.js) for a CommonJS Node backend: sourceType "commonjs", ecmaVersion 2023, globals.node, ignoring node_modules plus the gitignored .cache (downloaded third-party miner code) and test-artifacts dirs. Adds "lint": "eslint ." and eslint/globals devDeps. Code fixes: underscore-prefixed unused catch bindings/args and a few unused local helpers, and dropped one unused destructured import. Relaxed rules to match existing prevalent style: no-prototype-builtins, no-useless-escape, no-regex-spaces, no-control-regex, no-constant-binary-expression off; no-empty set to allowEmptyCatch.
Adds a "pretest" npm script that runs "npm run lint" so eslint executes automatically before the test suite.
…ables
Restore the six rules that were previously relaxed/disabled in
eslint.config.js, addressing each violation in a behavior-preserving way:
- no-empty (was allowEmptyCatch:true -> "error"): every intentionally
empty best-effort catch block now carries an explanatory comment
describing why the error is swallowed (code fix; no inline disables).
- no-prototype-builtins (was off -> "error"): obj.hasOwnProperty(...)
calls rewritten to Object.hasOwn(...) / Object.prototype.hasOwnProperty.call(...)
(code fix).
- no-useless-escape (was off -> "error"): removed a provably redundant
backslash escape in the email-validation regex character class (code fix).
- no-regex-spaces (was off -> "error"): literal multi-space runs in
email-body assertion regexes rewritten with explicit { N } quantifiers
preserving the exact match (code fix).
- no-control-regex (was off -> "error"): the one intentional ANSI
escape-stripping regex keeps the control char and gets a scoped
// eslint-disable-next-line no-control-regex (inline disable).
- no-constant-binary-expression (was off -> "error"): statically-constant
"x || 0" guards simplified to their constant value (code fix).
npx eslint . exits 0.
Adds no-throw-literal, default-case-last, no-unused-expressions, no-var,
no-else-return, prefer-const, eqeqeq ({null:"ignore"}), no-implicit-coercion,
object-shorthand, prefer-template, no-shadow, no-param-reassign. Bulk applied via
eslint --fix; manual behavior-preserving fixes for the eqeqeq/no-shadow/
no-param-reassign sites.
Also fixes a bug the no-param-reassign rewrite introduced in createMiner: the
parameter `agent` was replaced by `const normalizedAgent`, but miner.proxy,
miner.xmrig_proxy and applyNiceHashDiff still read the raw, un-normalized `agent`
(behavior diverges when an agent string exceeds the 255-char retention cap). They
now read normalizedAgent, restoring the prior behavior.
Tests: 495 pass / 0 fail.
sendUntilSuccess retried a failed share/block POST via setImmediate -- a tight next-tick loop. When the central shareHost is down but its host is up (ECONNREFUSED, the typical outage) each of the ~cpus*32 held send-queue slots reconnects as fast as the event loop runs, pinning the pool master's CPU core and flooding the dead endpoint with connection attempts while the queue backs up unboundedly. Retry on a fixed 1s delay instead: still retries until success (no share dropped), but paced so an outage cannot spin the CPU or flood the endpoint. Adds a test that the retry is delayed.
isStorableShare only checked typeof share.raw_shares === "number", which accepts NaN/Infinity. raw_shares is a proto float, and wire NaN/Infinity decode to JS numbers that pass that check, then flow into the cumulative totalHashes/roundHashes accumulators and poison pool stats and the PPLNS round-share denominator. Tighten the guard to Number.isFinite (strictly tighter; unchanged for all valid finite hashrate values) so a malformed frame is dropped like an out-of-range blockHeight already is. Add a regression test asserting NaN/Infinity frames are dropped, the valid frame is still stored, and no non-finite stat is written.
… cleanup) A prior change made createTaskQueue.oldest() return pending[0]. The sole caller is the remote share-verify stale-task cleanup (lib/coins/index.js), whose queue is fed with unshift() -- so pending[0] is the NEWEST task, not the oldest. Under sustained share submission the head stays fresh, so the cleanup early-returns and never removes expired tasks, leaking queued verification tasks and per-wallet miner_address_verify counters until memory / share-processing availability degrades (reachable via public submissions when verify_shares_host is set). Track a monotonic enqueueOrder per task and return the minimum from oldest(), so it is correct regardless of push (FIFO tail) vs unshift (priority front). Adds a regression test for the push+unshift ordering.
…crash) resolveErgSubmittedBlockHash dereferenced body.powSolutions.pk with no guard when err === null. A non-error but malformed/partial header (missing powSolutions) from the daemon/relay threw a TypeError inside the setTimeout callback -- no surrounding try/catch, no process-level uncaughtException handler -- crashing the block-submit confirm path (ERG is a relayed coin; a crash here can stall/lose a found block). Treat a missing solution as "not our block" (same sentinel as the err!==null branch).
…d loss) ETH-family block headers carry no confirmations/topoheight, and the daemon returns non-canonical blocks by hash (verified against the live ETC daemon: getBlockByHash of an uncle / non-canonical hash returns the block). So an orphaned found block -- not canonical and not referenced as an uncle within the inclusion window -- came back from getAnyBlockHeaderByHash non-null with error=null: neither checkOrphans (mo_altblockmanager) nor isAltblockOrphanResponse (block_manager) detected it (both key off confirmations / topoheight === -1), and the height-fallback is gated behind a non-null error. The orphan was then traded to XMR and paid to miners for a block that earned nothing on-chain. Mark the true-orphan fallthrough with confirmations = -1, the sentinel both consumers already recognise, so it is invalidated instead of paid. The canonical (hash === canonical) and uncle (createEthUncleReward) branches return earlier and are untouched, so valid blocks and uncles are never misflagged (ETC uncle-inclusion distance <= 7 is inside the +-8 scan window). Verified against the live ETC daemon; full suite green.
Follow-up to the ETC-orphan fix, after a same-class sweep + live-daemon verification: - ERG (factories.js createErgRpc.getAnyBlockHeaderByHash): like ETC, the Ergo node serves forked/orphaned blocks by id with HTTP 200 and no orphan marker, and this handler had no canonical comparison at all, so an orphaned ERG found block returned as a clean success and was paid. Now compares against the single canonical id at the block's height and marks a non-canonical block confirmations=-1; ambiguous lookups fall through to the valid path. - Cryptonote alts (xla/ryo/zeph/sal/arq/ccx + XMR alt blocks): monerod get_block_header_by_hash returns an orphaned block non-null with orphan_status=true (verified vs the live XMR daemon: 13 alt chains present; alt header orphan_status=true, main=false), but isAltblockOrphanResponse only checked topoheight/confirmations/error -> the orphan passed and was paid. Added orphan_status===true to the check. Valid blocks unaffected (orphan_status=false; ERG marks only a confirmed-different canonical id). Full suite green.
mom v0.7.0 benchmarks the active GPU algos (autolykos2/etchash/kawpow/pearl) at startup by default (bench_algo_params=1); those aren't in MOM_NO_BENCH_ALGOS, so the "no-bench" live config still ran slow (and on some Intel Xe GPUs unstable) DAG benchmarks before mining. Set bench_algo_params=0 to skip benchmarking and go straight to the pool job.
…drop an accepted block submitEthBlock confirms acceptance on eth_submitWork===true, then resolveEthSubmittedBlockHash waited 30s and did a SINGLE ethBlockFind to discover the on-chain hash. If the daemon was down/slow/restarting in that window, ethBlockFind/ethBlockCheck return null, the function returned the zero-hash, and share_blocks dropped the already-accepted (on-chain) block uncredited (admin FYI only, no retry). Compounds with monitorNodes' daemon restarts. ethBlockFind is read-only/idempotent, so retry it a bounded number of times (ETH_BLOCK_RESOLVE_ATTEMPTS=10 x 30s) before falling back to the zero-hash. Single-attempt success is unchanged. Limits (option A, in-memory): retry state is not durable, so a pool restart inside the window still loses the in-flight block; outages longer than ~5 min still fall back to the zero-hash drop; a genuine orphan is dropped after the retries instead of immediately. A durable fix (persist the pending resolution) was deferred. + tests (transient-recover, exhausted-fallback). Suite green.
…ropping a refind (R14, partial) Main blocks are keyed by height, so saveResolvedBlock treated ANY existing blockDB[height] entry as a duplicate (hash-blind). After a reorg orphans block A at height N (unlocker sets valid=false) and the pool finds canonical block C at N, saveResolvedBlock saw the slot occupied and dropped C -> lost block, miners unpaid. Now: same hash -> genuine duplicate (unchanged); different hash but the recorded block was orphaned (valid===false) -> replace the orphan tombstone with the new valid block; a different still-valid block -> still "duplicate" (cannot hold two at one height key). Normal one-block-per- height operation is unchanged. The remaining two-still-valid-at-one-height window needs the full fix (height in the Block value + forward-probe, like AltBlock) -- tracked as R14 option 1. Suite green.
…c236fe / b31b6ed) Adds the coverage the cons-review flagged as missing for three money-path fixes: - basics.js: eth-family getAnyBlockHeaderByHash tags a true orphan (not canonical, no uncle reference) with confirmations=-1; erg getAnyBlockHeaderByHash tags a true orphan (a different canonical id occupies the height) with confirmations=-1. - block_jobs.js: saveResolvedBlock replaces an orphaned (valid=false) same-height block with the canonical refind, and keeps an existing still-valid block (treated as duplicate). Tests-only; no production code change.
… (safe-additive audit fixes)
The workerMax check pre-incremented (++count <= workerMax), so an over-limit login that is rejected still bumped the count; that worker never connects, so it is never decremented and the count drifts up over time until legitimate miners under the real limit are wrongly rejected. Check before incrementing (intent of refactor ef46e97 was only to bound worker count). Suite green.
…unt leak, long_runner key-0 resume, template one-shot - manage_scripts/exchange_recovery_cache_common.js: key buildBlockLookup by the LMDB `_key` the callback yields, not the non-existent block.id (was always NaN -> lookup 100% broken). - lib/pool/miner_registry.js: check proxy worker count before incrementing so a rejected over-limit login doesn't leak the count (twin of the protocol.js 302d649 fix). - lib/long_runner.js: compare goToRange() !== false in the reverse-resume branch so an LMDB key value of 0 isn't mis-treated as "not found" (mirrors the forward branch). - lib/pool/templates.js: make the header-fetch-error reschedule one-shot (requireTrue) like the success path, so a bootstrap (undefined repeating) call can't spawn a second poll loop. - factories.js + protocol.js: fix 'extranoces' -> 'extranonces' miner-facing typo (+ test). Suite green (504 pass).
…r guard/import, collapse duplicate coinHashFactor branches (behavior-preserving, eslint+tests green)
…(skip cycle, not crash) createBlockTemplate (RtmBlockTemplate/RavenBlockTemplate) runs inside the daemon-RPC reply callback, which jsonRequest invokes OUTSIDE its try/catch — so any template-build throw (malformed bits/version/ previousblockhash, too-many/unparseable txs) propagated uncaught and could crash the process. Wrap the build in try/catch and, on failure, log + return like a no-result reply so the pool skips that template cycle and retries next poll. Suite 504/504.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.