Skip to content

win.31 - Dashboard serving/coverage rows, getnodestats RPC, fix RPC server actually listens

Choose a tag to compare

@chopperbriano chopperbriano released this 12 Apr 01:27

Headline fix: the RPC server actually listens now. For the first time.

src/boost/asio.hpp in this fork was a hand-written no-op stub that silently emulated boost::asio's socket API with empty implementations. Because src/ sat on the include path, #include <boost/asio.hpp> in RPC/Server.cpp resolved to the stub, not to real boost. Every bind() / listen() / accept() call was a no-op:

class acceptor {
    void open(int) {}
    void set_option(const reuse_address&) {}
    void bind(const endpoint&) {}
    void listen() {}
    void accept(socket&) {
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
};

The RPC Server listening on port 14024 log line was printed after a no-op listen() returned. The RPC call # received debug entries were the stub's sleeping accept loop spinning once per second, not real inbound connections. netstat never showed port 14024 bound because no socket was ever actually created.

DigiAssetCore-cli.exe has never worked on this Windows fork for any RPC command. Not version, not getblockcount, not listassets, nothing. Every call failed with a libcurl-style error because there was nothing listening to connect to.

Upstream src/CMakeLists.txt even acknowledged the stub existed, for WebServer.cpp:

# WebServer.cpp needs real Boost Beast headers (not the stub in src/boost/)

…but nothing else got the fix. RPC::Server silently compiled against the stub for every previous release. This commit finally fixes it globally by adding the real boost headers to the front of the include path for every source file, and switching Server.h/Server.cpp to explicit sub-header includes as a belt-and-braces guarantee.

After this release:

  • netstat -ano | findstr 14024 shows TCP 0.0.0.0:14024 0.0.0.0:0 LISTENING <pid> for the first time.
  • DigiAssetCore-cli.exe version returns "0.3.0-win.31".
  • DigiAssetCore-cli.exe getnodestats returns a real JSON snapshot of the node.
  • Every pre-existing RPC method (version, listassets, getblockcount, getassetdata, etc.) now works from the cli because there's finally something listening.

New features (the original reason for this release)

Dashboard: Serving: row

Polls IPFS bitswap stats every 30 seconds via POST /api/v0/stats/bitswap and displays total blocks sent, rate per minute, and total bytes sent, in a human-readable form. Answers "is this node actually serving DigiAsset content out to the network?" with a direct measurement, not a guess.

Dashboard: Asset index: row

Every 10 minutes, walks /permanent/<page>.json on mctrivia's server (24 pages, ~3,442 assetIds total as of this release) and cross-checks each assetId against the local assets table. Reports local count, tracked count, and coverage percentage. 100% is strong evidence the chain analyzer is not missing any issuances, because PSP-enrolled and non-PSP-enrolled assets go through the same parse path. Missing assetIds are logged at WARNING so they're visible without flipping to DEBUG.

RPC: new getnodestats method

Returns a snapshot of buildVersion, syncHeight, assetCount, bitswap stats, and permanent-list coverage as JSON. Designed for side-by-side node comparison:

DigiAssetCore-cli.exe getnodestats

Run it on two nodes at the same syncHeight. If assetCount differs, one of them has a chain-analyzer bug. If permanentCoverage.missingCount > 0, that node is missing specific assets that the other has.

Expanded [H] help

Pressing H now prints a multi-section plain-English explanation of every dashboard row, what each number means, and what the node is actually doing. Readable by a first-time operator with no DigiAsset background.

Latent bugs fixed along the way

  • Server::Server work_guard was a local variable. Changed to a member so _io stays alive. (Previously the 16 worker threads exited immediately after construction — invisible against the stub since run() was a no-op, but fatal once real boost was linked.)
  • Server::Server _acceptor now initialized in the member init list with the executor. Real boost::asio::basic_socket_acceptor has no default constructor.
  • Server::start() now clears AppMain::_rpcServer to nullptr when accept() returns, so the dashboard's RPC probe reports honestly if the accept loop ever dies in a future build instead of showing a green dangling pointer.
  • DigiByteCore::makeConnection() prints the RPC URL to stderr when DGBCORE_DEBUG_URL=1 is set — diagnostic hook for libcurl URL-parser errors.
  • Dashboard spawn-race guards for the bitswap poll and coverage scan now rely only on the elapsed >= interval check. Previously the || !_probed fallback caused the 500ms render loop to fire duplicate probe threads during the ~2s window before the first probe completed.
  • cli/main.cpp drops an unused #include "RPC/Server.h" so the cli build doesn't need real boost headers at all.

Known current state

  • mctrivia's pool still doesn't pay. That's a server-side bug at ipfs.digiassetx.com (HTTP 500 on the payout registration endpoint, broken since ~July 2024) and the pool operator is uncontactable. No client-side fix can change this; see the win.30 release notes for the full story. This release doesn't fix payment — but it does make the RPC server work for everything else, and the node continues to contribute storage to the network.

Files

  • DigiAssetCore-0.3.0-win.31-x64.zip — both exes in a folder
  • DigiAssetCore.exe — main binary
  • DigiAssetCore-cli.exe — command-line helper