Heads up EDX miners — I found a serious bug in the node, please read before you commit rigsHey all 👋
Like some of you I got curious about EdgeX (EDX) and dug into the v1.0.0 code
(
https://github.com/edgexNetwork/EdgeX-Network) before pointing hardware at it.
Unfortunately I hit a serious consensus bug and I'd feel bad not sharing it — better
you hear it now than after burning time and electricity. Purely technical, no drama,
no claims about anyone's intentions.
What's wrongIn block validation (
packages/core/src/state.ts,
applyBlock), the node
validates every transaction against the state from
before the block, and only
mutates the UTXO set afterwards (the code even says so: "Mutations happen only after
every transaction in the candidate is valid"). It de-duplicates transaction ids, and
inputs
within a single tx — but it never tracks coins already spent by
earlier transactions in the same block. So you can put two different,
properly-signed transactions that spend the
same coin into one block and both
pass. The mutation step then deletes the input once but creates
both sets of
outputs. In plain terms: you can mint EDX out of thin air.
Why it mattersIt breaks the 2.1B hard cap — balances and total supply can't be trusted, and anyone
who mines a block can inflate at will. Fixing it is a hard fork + fresh genesis, since
blocks accepted under the bug become invalid.
I didn't just eyeball it — here's the proofRan against the project's own validation code, offline and in memory (nothing done to
mainnet), using the same state.clone() the real accept path uses. I also checked the
whole path — acceptBlock -> addBlock -> PoW check -> state.clone().applyBlock — and
there is no double-spend guard anywhere outside applyBlock.
One 400 EDX coin, two different signed txs spending it:
tx1 alone -> ACCEPTED (recipient 399 EDX) <- each tx is individually valid
tx2 alone -> ACCEPTED (recipient 398 EDX)
tx1 + tx2 block -> ACCEPTED (recipient 797 EDX from a single 400 EDX coin)
Each transaction is valid on its own, so this isn't junk slipping through — it's two
legit spends of the same coin, both honored. 797 out of 400, in one block. Repeat at will.
The good news: it's a small fixTrack spent inputs across the whole block during validation:
const spentInBlock = new Set<string>();
// ...in the per-input loop:
const key = utxoKey(input.txid, input.index);
if (spentInBlock.has(key)) throw new UtxoValidationError(`double spend within block ${key}`);
spentInBlock.add(key);
I applied exactly this and re-ran: single txs still accepted, the two-in-one-block
attack is now rejected. No false positives.
One more thing — the "run your own node" story doesn't hold upI checked how you'd actually join the network, and it's a mess:
- The release ships six prebuilt binaries and they're ALL wallets
(dexcoin-wallet-{linux,darwin,win}-{x64,arm64}). There is no node binary. I
inspected the Linux build: it contains no P2P, no RandomX, no mining/validation
code — it's a wallet that just talks to a local node RPC. So the advertised
"curl | bash then run one command to mine and validate" actually installs a
wallet only, not the full node it promises.
- The open-source node (from source) ships with zero seed nodes: EDX_SEEDS is
empty by default, no DNS seeds, no hardcoded peers.
- No peer/seed address is published anywhere public — not the README, the ANN,
the website or the pool page.
[/list]
Net result: from every public artifact, you cannot actually sync a node or join the
P2P network — you'd need a peer address handed to you out-of-band. For a project whose
whole pitch is "run a full node on any edge device," that's a big gap. Not a
vulnerability like the double-spend above, but it means right now you can't
independently verify the chain even if you wanted to.
A couple of smaller thingsThe P2P transaction handler isn't wrapped in try/catch (the block handler is), so a
malformed gossiped tx could crash a node. And the node RPC has no auth — fine on
localhost, risky if exposed. Credit where due: the RandomX binding looked clean and
there's genuinely no premine (genesis issues nothing, coinbase amount is validated),
so the core isn't sloppy everywhere — this one bug is just a big one.
My honest takeI'd hold off putting rigs or money on EDX until this is fixed and the chain relaunches.
Not trying to FUD anyone — I just don't want people burning power on a chain whose
supply can be forged. Devs: happy to hand over the full reproducible PoC. Mine safe out there o/