Mining methods

A mining pool needs only the node. It asks getblocktemplate for work paying its own address, grinds Equihash over the template's pow_input, and submits the winning nonce and solution with submitblock. The node builds and proves the shielded coinbase itself.

These methods are served by nulld on its --rpc-http listener, with the same token and conventions as the node methods. For the full pool walk-through, including Stratum and payouts, see Mining pools.

How the work fits together

  • The template. getblocktemplate builds a coinbase paying the block subsidy plus the fees of the selected mempool transactions to your payout_address, proves it, and returns every header field except the nonce and the solution. Proving takes about a second. The proving key is built on the first call, which takes longer.
  • Reuse and expiry. A template for the same payout address and tip is reused for 5 seconds, so a pool that asks every second pays for one proof every five seconds. A new tip always gets a new template. A template can be submitted against for 10 minutes (expires_at). The node keeps at most 64 templates; the oldest go first.
  • Long polling. Pass the longpollid of your last template. The call waits up to 60 seconds for the tip to change before answering. Alternatively run the node with --blocknotify '<command>', which runs on every new tip with %s replaced by the block hash.
  • Readiness. Templates are refused with -2 until the node is caught up: on mainnet it needs at least one peer past the handshake, and no sync may be running and no peer may report a longer chain. The messages are not ready to mine: no peers yet and not ready to mine: catching up with the network.
  • What to hash. pow_input is the header serialized without nonce and solution: version (1 byte), previous block hash (32), height (LE32), timestamp (LE64), commitment root (32), tx root (32), compact target (LE32). Equihash runs over pow_input || nonce with the equihash parameters and the personalization nullPoW_ (hex 6e756c6c506f575f). The block hash is BLAKE2b-256 with personalization null_BlockHash__ over the full header (pow_input || nonce || solution). Read as a big-endian 256-bit number, it must be at or below target_hex. If you change the timestamp, rebuild pow_input with it. Check that your own serialization reproduces pow_input before you grind.
  • Maturity and reorgs. A coinbase reward mined at height h is spendable from block h + 100 on mainnet. Reorganizations deeper than 200 blocks are refused.

RPCgetmininginfo

getmininginfo

The tip, the next block's target and subsidy, and a network work estimate. No parameters.

Result

  • Name
    height
    Type
    number
    Description

    Tip height.

  • Name
    best_block_hash
    Type
    hex
    Description

    Tip hash.

  • Name
    syncing
    Type
    boolean
    Description

    Whether a sync from a peer is in progress.

  • Name
    next_height
    Type
    number
    Description

    Height of the next block.

  • Name
    next_target
    Type
    string
    Description

    Compact target the next block must meet.

  • Name
    next_target_hex
    Type
    hex
    Description

    The same as a 256-bit value.

  • Name
    pow_limit
    Type
    string
    Description

    Compact easiest target allowed for the next block.

  • Name
    subsidy
    Type
    string
    Description

    Block subsidy of the next block in units, without fees.

  • Name
    mempool
    Type
    number
    Description

    Transactions in the mempool.

  • Name
    work_per_second
    Type
    string
    Description

    Decimal estimate of the Equihash solutions the whole network tries per second: the work of the blocks in the last difficulty window, divided by the seconds they span, where one block's work is 2^256 / (target + 1). A coarse estimate from block timestamps.

  • Name
    block_interval
    Type
    number
    Description

    Target seconds between blocks.

  • Name
    equihash
    Type
    object
    Description

    n, k, personalization (hex) and solution_length (bytes).

Request

RPC
getmininginfo
curl -s http://127.0.0.1:18446/ \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"jsonrpc":"2.0","id":1,"method":"getmininginfo","params":[]}'

Response

{
  "jsonrpc": "2.0",
  "result": {
    "height": 6206,
    "best_block_hash": "00000fc8d37f816b43e79acbaba7d736adbbcbfdca48182361e0dd943a456273",
    "syncing": false,
    "next_height": 6207,
    "next_target": "1e11e4e5",
    "next_target_hex": "000011e4e5000000000000000000000000000000000000000000000000000000",
    "pow_limit": "200fffff",
    "subsidy": "970000000",
    "mempool": 0,
    "work_per_second": "7813",
    "block_interval": 120,
    "equihash": {
      "n": 144,
      "k": 5,
      "personalization": "6e756c6c506f575f",
      "solution_length": 100
    }
  },
  "id": 1
}

RPCgetblocktemplate

getblocktemplate

A block template whose coinbase pays payout_address. The coinbase is already built and proved. Grind the nonce and solution over pow_input and submit with submitblock.

Parameters

  • Name
    payout_address
    Type
    string
    Description

    Required. A shielded address of this network (null1…) that receives the subsidy and fees.

  • Name
    longpollid
    Type
    hex
    Description

    Optional. The longpollid of your previous template. The call waits until the tip changes, up to 60 seconds, then answers.

Result

  • Name
    template_id
    Type
    string
    Description

    Id to submit against.

  • Name
    height
    Type
    number
    Description

    Height of the block being built.

  • Name
    prev_hash
    Type
    hex
    Description

    Parent block hash.

  • Name
    longpollid
    Type
    hex
    Description

    Equal to prev_hash. Pass it back to long-poll.

  • Name
    branch
    Type
    string
    Description

    Branch id in force at this height.

  • Name
    version
    Type
    number
    Description

    Header version.

  • Name
    timestamp
    Type
    number
    Description

    The node's timestamp for the header: the later of its clock and the parent's timestamp plus one.

  • Name
    min_timestamp
    Type
    number
    Description

    The lowest timestamp to use. Equal to timestamp.

  • Name
    max_timestamp
    Type
    number
    Description

    The highest timestamp the network accepts now (clock plus 7,200 seconds).

  • Name
    commitment_root
    Type
    hex
    Description

    Note commitment tree root after this block.

  • Name
    tx_root
    Type
    hex
    Description

    Commitment to the template's transaction ids.

  • Name
    target
    Type
    string
    Description

    Compact target.

  • Name
    target_hex
    Type
    hex
    Description

    The full 256-bit target the block hash must not exceed.

  • Name
    pow_input
    Type
    hex
    Description

    The 113 header bytes Equihash commits to, before the nonce.

  • Name
    equihash
    Type
    object
    Description

    n, k, personalization (hex) and solution_length (bytes).

  • Name
    transaction_count
    Type
    number
    Description

    Transactions in the template, coinbase included.

  • Name
    coinbase_value
    Type
    string
    Description

    Subsidy plus fees paid to payout_address, in units.

  • Name
    fees
    Type
    string
    Description

    Fees of the included mempool transactions, in units.

  • Name
    expires_at
    Type
    number
    Description

    Unix time after which the template can no longer be submitted.

Errors

-32602 if the address does not decode for this network. -2 if the node is not ready to mine, or tip moved; ask again if the tip changed while the template was being built.

Request

RPC
getblocktemplate
curl -s http://127.0.0.1:18446/ \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"jsonrpc":"2.0","id":1,"method":"getblocktemplate","params":{"payout_address":"null1drhkpmr7np84jr6ww2s8f7hf2rgddg88yrdw34kqhger9v6vc9e8hfaktdcuhnqr29usu8drf8r"}}'

Response

{
  "jsonrpc": "2.0",
  "result": {
    "template_id": "00000000000000a3",
    "height": 6207,
    "prev_hash": "00000fc8d37f816b43e79acbaba7d736adbbcbfdca48182361e0dd943a456273",
    "longpollid": "00000fc8d37f816b43e79acbaba7d736adbbcbfdca48182361e0dd943a456273",
    "branch": "0x4d41494e",
    "version": 1,
    "timestamp": 1793000850,
    "min_timestamp": 1793000850,
    "max_timestamp": 1793008050,
    "commitment_root": "00dab8af3e1c209aca1c4186d5ceed2a058bcf2c650256802466274f9e98e975",
    "tx_root": "09abb9b7262af9f1f345896ecb84bdb2ce396c198fb6ee60fff78029bfcb2637",
    "target": "1e11e4e5",
    "target_hex": "000011e4e5000000000000000000000000000000000000000000000000000000",
    "pow_input": "0100000fc8d37f816b43e79acbaba7d736adbbcbfdca48182361e0dd943a4562733f1800009205df6a0000000000dab8af3e1c209aca1c4186d5ceed2a058bcf2c650256802466274f9e98e97509abb9b7262af9f1f345896ecb84bdb2ce396c198fb6ee60fff78029bfcb2637e5e4111e",
    "equihash": {
      "n": 144,
      "k": 5,
      "personalization": "6e756c6c506f575f",
      "solution_length": 100
    },
    "transaction_count": 1,
    "coinbase_value": "970000000",
    "fees": "0",
    "expires_at": 1793001450
  },
  "id": 1
}

RPCsubmitblock

submitblock

Submits a solved block. There are two forms.

  • By template (the usual one): send the template_id and only what you changed, the timestamp, nonce and solution. The node rebuilds the block from its cached template. The call is treated as this form whenever a timestamp is given.
  • Full block: send the whole serialized block as block. This is for pools that assemble their own blocks from a template's transactions.

The node imports the block exactly as it would a block from a peer.

Parameters (by template)

  • Name
    template_id
    Type
    string
    Description

    Required. From getblocktemplate.

  • Name
    timestamp
    Type
    number
    Description

    Required. The header timestamp you hashed, between min_timestamp and max_timestamp.

  • Name
    nonce
    Type
    hex
    Description

    Required. 32 bytes.

  • Name
    solution
    Type
    hex
    Description

    Required. The Equihash solution, at most 100 bytes; shorter values are zero-padded.

Parameters (full block)

  • Name
    block
    Type
    hex
    Description

    Required. The serialized block.

Result

  • Name
    status
    Type
    string
    Description

    accepted: the block extended the main chain or reorganized onto it. duplicate: the block was already known. stale: valid, but on a side chain.

  • Name
    hash
    Type
    hex
    Description

    The block hash.

Errors

-2 with unknown or expired template, or with the validator's reason when the block is invalid (for example a hash above the target). -32602 for a nonce that is not 32 bytes, a solution longer than 100 bytes, or a block that does not decode.

Request

RPC
submitblock
curl -s http://127.0.0.1:18446/ \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"jsonrpc":"2.0","id":1,"method":"submitblock","params":{
        "template_id":"00000000000000a3",
        "timestamp":1793000850,
        "nonce":"5c0e1a7700000000000000000000000000000000000000000000000000000000",
        "solution":"9f13c2…"}}'

Response

{
  "jsonrpc": "2.0",
  "result": {
    "status": "accepted",
    "hash": "000007a2c4e9b13f5d8e6a0c2b7f49d1e3a5c8b06f2d4e7a9c1b3d5f7e9a0c2b"
  },
  "id": 1
}

Expired template

{
  "jsonrpc": "2.0",
  "error": { "code": -2, "message": "unknown or expired template" },
  "id": 1
}