# mnr - method policy table

_Generated from `mnr-core::policy::render_markdown`. The code is canonical; this table is regenerated from it._

Tip safety depth: 10 blocks (`TIP_SAFETY_DEPTH`). Data within that distance of the quorum tip is never cached; requests above the safety line fall back to SWR or pass through. Unknown methods are denied (allow-list).

The allow-list is verified against monerod's endpoint registry (`crates/core/fixtures/monerod-core_rpc_server.h`, fetched 2026-09-04). 86 rows, 16 of them aliases.

| Method | Transport | Class | Cache rule | Quorum rule | Verification | Timeout (ms) | Note |
|---|---|---|---|---|---|---|---|
| `get_block` | json-rpc | IMMUTABLE | Cache 30 d only if requested height <= quorum_tip - TIP_SAFETY_DEPTH; requests above the safety line fall back to SWR. Cache key includes the block hash returned by the node. | Height/hash must match the quorum-tip chain (validated against the header chain). | authenticated | 3000 | Block hash recomputed from the blob and matched to the requested hash or height. |
| `get_block_header_by_height` | json-rpc | IMMUTABLE | Cache 30 d only if requested height <= quorum_tip - TIP_SAFETY_DEPTH; requests above the safety line fall back to SWR. Cache key includes the block hash returned by the node. | Height/hash must match the quorum-tip chain (validated against the header chain). | authenticated | 3000 | Header hash matched to the header chain at that height. |
| `get_block_header_by_hash` | json-rpc | IMMUTABLE | Cache 30 d only if requested height <= quorum_tip - TIP_SAFETY_DEPTH; requests above the safety line fall back to SWR. Cache key includes the block hash returned by the node. | Height/hash must match the quorum-tip chain (validated against the header chain). | authenticated | 3000 | Recomputed header hash matched to the requested hash. |
| `get_block_headers_range` | json-rpc | IMMUTABLE | Cache 30 d only if requested height <= quorum_tip - TIP_SAFETY_DEPTH; requests above the safety line fall back to SWR. Cache key includes the block hash returned by the node. | Height/hash must match the quorum-tip chain (validated against the header chain). | authenticated | 3000 | Every header checked against the header chain; a range that crosses the safety line is verified but not cached. |
| `on_get_block_hash` | json-rpc | IMMUTABLE | Cache 30 d only if requested height <= quorum_tip - TIP_SAFETY_DEPTH; requests above the safety line fall back to SWR. Cache key includes the block hash returned by the node. | Height/hash must match the quorum-tip chain (validated against the header chain). | authenticated | 3000 | Takes a height, returns the block hash; matched to the header chain. |
| `getblock` | json-rpc | IMMUTABLE | Cache 30 d only if requested height <= quorum_tip - TIP_SAFETY_DEPTH; requests above the safety line fall back to SWR. Cache key includes the block hash returned by the node. | Height/hash must match the quorum-tip chain (validated against the header chain). | authenticated | 3000 | Alias of get_block. |
| `getblockheaderbyhash` | json-rpc | IMMUTABLE | Cache 30 d only if requested height <= quorum_tip - TIP_SAFETY_DEPTH; requests above the safety line fall back to SWR. Cache key includes the block hash returned by the node. | Height/hash must match the quorum-tip chain (validated against the header chain). | authenticated | 3000 | Alias of get_block_header_by_hash. |
| `getblockheaderbyheight` | json-rpc | IMMUTABLE | Cache 30 d only if requested height <= quorum_tip - TIP_SAFETY_DEPTH; requests above the safety line fall back to SWR. Cache key includes the block hash returned by the node. | Height/hash must match the quorum-tip chain (validated against the header chain). | authenticated | 3000 | Alias of get_block_header_by_height. |
| `getblockheadersrange` | json-rpc | IMMUTABLE | Cache 30 d only if requested height <= quorum_tip - TIP_SAFETY_DEPTH; requests above the safety line fall back to SWR. Cache key includes the block hash returned by the node. | Height/hash must match the quorum-tip chain (validated against the header chain). | authenticated | 3000 | Alias of get_block_headers_range. |
| `on_getblockhash` | json-rpc | IMMUTABLE | Cache 30 d only if requested height <= quorum_tip - TIP_SAFETY_DEPTH; requests above the safety line fall back to SWR. Cache key includes the block hash returned by the node. | Height/hash must match the quorum-tip chain (validated against the header chain). | authenticated | 3000 | Alias of on_get_block_hash. |
| `get_info` | json-rpc | SWR | SWR 1/5/15 s (max-age=1, stale-while-revalidate=5, stale-if-error=15) with single-flight coalescing; node-specific fields normalised. Staleness bound <=6 s normal, <=15 s during upstream error. | Majority of >=3 upstreams on quorum tip (each probe height >= quorum_tip - 1). | majority (>=3) | 1500 | Consensus state; node-specific fields (connections, peerlist, update_available, start_time) normalised. |
| `/get_info` | legacy | SWR | SWR 1/5/15 s (max-age=1, stale-while-revalidate=5, stale-if-error=15) with single-flight coalescing; node-specific fields normalised. Staleness bound <=6 s normal, <=15 s during upstream error. | Majority of >=3 upstreams on quorum tip (each probe height >= quorum_tip - 1). | majority (>=3) | 1500 | Legacy form of get_info; same normalisation. |
| `/get_height` | legacy | SWR | SWR 1/5/15 s (max-age=1, stale-while-revalidate=5, stale-if-error=15) with single-flight coalescing; node-specific fields normalised. Staleness bound <=6 s normal, <=15 s during upstream error. | Majority of >=3 upstreams on quorum tip (each probe height >= quorum_tip - 1). | majority (>=3) | 1500 | Consensus state; majority of >=3 upstreams. |
| `get_last_block_header` | json-rpc | SWR | SWR 1/5/15 s (max-age=1, stale-while-revalidate=5, stale-if-error=15) with single-flight coalescing; node-specific fields normalised. Staleness bound <=6 s normal, <=15 s during upstream error. | Majority of >=3 upstreams on quorum tip (each probe height >= quorum_tip - 1). | majority (>=3) | 1500 | Header verified against the header chain. |
| `get_fee_estimate` | json-rpc | SWR | SWR 1/5/15 s (max-age=1, stale-while-revalidate=5, stale-if-error=15) with single-flight coalescing; node-specific fields normalised. Staleness bound <=6 s normal, <=15 s during upstream error. | Majority of >=3 upstreams on quorum tip (each probe height >= quorum_tip - 1). | majority (>=3) | 1500 | Fee estimate = median of upstream estimates. |
| `hard_fork_info` | json-rpc | SWR | SWR 1/5/15 s (max-age=1, stale-while-revalidate=5, stale-if-error=15) with single-flight coalescing; node-specific fields normalised. Staleness bound <=6 s normal, <=15 s during upstream error. | Majority of >=3 upstreams on quorum tip (each probe height >= quorum_tip - 1). | majority (>=3) | 1500 | Fork/version agreement across upstreams. |
| `get_version` | json-rpc | SWR | SWR 1/5/15 s (max-age=1, stale-while-revalidate=5, stale-if-error=15) with single-flight coalescing; node-specific fields normalised. Staleness bound <=6 s normal, <=15 s during upstream error. | Majority of >=3 upstreams on quorum tip (each probe height >= quorum_tip - 1). | majority (>=3) | 1500 | Node version; checked against the directory minimum in Stage 2. |
| `get_block_count` | json-rpc | SWR | SWR 1/5/15 s (max-age=1, stale-while-revalidate=5, stale-if-error=15) with single-flight coalescing; node-specific fields normalised. Staleness bound <=6 s normal, <=15 s during upstream error. | Majority of >=3 upstreams on quorum tip (each probe height >= quorum_tip - 1). | majority (>=3) | 1500 | Equivalent of get_height by block count; majority of >=3 upstreams. |
| `/getheight` | legacy | SWR | SWR 1/5/15 s (max-age=1, stale-while-revalidate=5, stale-if-error=15) with single-flight coalescing; node-specific fields normalised. Staleness bound <=6 s normal, <=15 s during upstream error. | Majority of >=3 upstreams on quorum tip (each probe height >= quorum_tip - 1). | majority (>=3) | 1500 | Alias of /get_height. |
| `/getinfo` | legacy | SWR | SWR 1/5/15 s (max-age=1, stale-while-revalidate=5, stale-if-error=15) with single-flight coalescing; node-specific fields normalised. Staleness bound <=6 s normal, <=15 s during upstream error. | Majority of >=3 upstreams on quorum tip (each probe height >= quorum_tip - 1). | majority (>=3) | 1500 | Alias of /get_info. |
| `getlastblockheader` | json-rpc | SWR | SWR 1/5/15 s (max-age=1, stale-while-revalidate=5, stale-if-error=15) with single-flight coalescing; node-specific fields normalised. Staleness bound <=6 s normal, <=15 s during upstream error. | Majority of >=3 upstreams on quorum tip (each probe height >= quorum_tip - 1). | majority (>=3) | 1500 | Alias of get_last_block_header. |
| `getblockcount` | json-rpc | SWR | SWR 1/5/15 s (max-age=1, stale-while-revalidate=5, stale-if-error=15) with single-flight coalescing; node-specific fields normalised. Staleness bound <=6 s normal, <=15 s during upstream error. | Majority of >=3 upstreams on quorum tip (each probe height >= quorum_tip - 1). | majority (>=3) | 1500 | Alias of get_block_count. |
| `/get_transactions` | legacy | IMMUTABLE-CONDITIONAL | Cache 30 d per tx hash only for txs with block_height <= quorum_tip - TIP_SAFETY_DEPTH; mempool/young txs pass through. Per-tx-hash, not per request body; batches reassembled at the edge. | Single node on quorum tip. | authenticated | 5000 | Tx blob hashed to txid; pruned-tx hash form verified where applicable. |
| `/get_outs.bin` | legacy | IMMUTABLE-CONDITIONAL | Cache 24 h only if all requested indices belong to blocks <= quorum_tip - TIP_SAFETY_DEPTH; else pass through. Stage 0: only get_output_distribution with to_height <= the safety line is cached (needs the distribution to map indices to heights for the rest). | Single node on quorum tip. | agreement free=1 pro=2 | 10000 | Ring construction; correctness > hit rate. Stage 0: two-upstream agreement for Pro tokens, single upstream (owned node preferred) for Free (plan §10 item 3, decided). |
| `/get_outs` | legacy | IMMUTABLE-CONDITIONAL | Cache 24 h only if all requested indices belong to blocks <= quorum_tip - TIP_SAFETY_DEPTH; else pass through. Stage 0: only get_output_distribution with to_height <= the safety line is cached (needs the distribution to map indices to heights for the rest). | Single node on quorum tip. | agreement free=1 pro=2 | 10000 | JSON twin of /get_outs.bin; same per-tier agreement. |
| `/get_o_indexes.bin` | legacy | IMMUTABLE-CONDITIONAL | Cache 24 h only if all requested indices belong to blocks <= quorum_tip - TIP_SAFETY_DEPTH; else pass through. Stage 0: only get_output_distribution with to_height <= the safety line is cached (needs the distribution to map indices to heights for the rest). | Single node on quorum tip. | agreement free=1 pro=2 | 10000 | Tx global output indexes; same per-tier agreement. |
| `/get_output_distribution.bin` | legacy | IMMUTABLE-CONDITIONAL | Cache 24 h only if all requested indices belong to blocks <= quorum_tip - TIP_SAFETY_DEPTH; else pass through. Stage 0: only get_output_distribution with to_height <= the safety line is cached (needs the distribution to map indices to heights for the rest). | Single node on quorum tip. | agreement free=1 pro=2 | 10000 | Binary form of get_output_distribution. |
| `get_output_distribution` | json-rpc | IMMUTABLE-CONDITIONAL | Cache 24 h only if all requested indices belong to blocks <= quorum_tip - TIP_SAFETY_DEPTH; else pass through. Stage 0: only get_output_distribution with to_height <= the safety line is cached (needs the distribution to map indices to heights for the rest). | Single node on quorum tip. | agreement free=1 pro=2 | 10000 | Ring-construction data; not self-authenticating from a single response. |
| `get_output_histogram` | json-rpc | IMMUTABLE-CONDITIONAL | Cache 24 h only if all requested indices belong to blocks <= quorum_tip - TIP_SAFETY_DEPTH; else pass through. Stage 0: only get_output_distribution with to_height <= the safety line is cached (needs the distribution to map indices to heights for the rest). | Single node on quorum tip. | agreement free=1 pro=2 | 10000 | Ring-construction data; not self-authenticating from a single response. |
| `/gettransactions` | legacy | IMMUTABLE-CONDITIONAL | Cache 30 d per tx hash only for txs with block_height <= quorum_tip - TIP_SAFETY_DEPTH; mempool/young txs pass through. Per-tx-hash, not per request body; batches reassembled at the edge. | Single node on quorum tip. | authenticated | 5000 | Alias of /get_transactions. |
| `/get_blocks.bin` | legacy | PASSTHROUGH-STREAM | None - streamed body-through, no buffering. | Route to the healthiest full node on quorum tip (pruned node only if request has prune=true). | annotated | 60000 | Wallet sync path; largest bandwidth consumer, metered separately (bytes). Stage 0: not verified - Mnr-Verify: none; owned node preferred; idle timeout 15 s. |
| `/get_blocks_by_height.bin` | legacy | PASSTHROUGH-STREAM | None - streamed body-through, no buffering. | Route to the healthiest full node on quorum tip (pruned node only if request has prune=true). | annotated | 60000 | Same as get_blocks.bin by height; Mnr-Verify: none in Stage 0; idle timeout 15 s. |
| `/get_hashes.bin` | legacy | PASSTHROUGH-STREAM | None - streamed body-through, no buffering. | Route to the healthiest full node on quorum tip (pruned node only if request has prune=true). | annotated | 60000 | Block hashes for sync; Mnr-Verify: none in Stage 0; idle timeout 15 s. |
| `/getblocks.bin` | legacy | PASSTHROUGH-STREAM | None - streamed body-through, no buffering. | Route to the healthiest full node on quorum tip (pruned node only if request has prune=true). | annotated | 60000 | Alias of /get_blocks.bin. |
| `/getblocks_by_height.bin` | legacy | PASSTHROUGH-STREAM | None - streamed body-through, no buffering. | Route to the healthiest full node on quorum tip (pruned node only if request has prune=true). | annotated | 60000 | Alias of /get_blocks_by_height.bin. |
| `/gethashes.bin` | legacy | PASSTHROUGH-STREAM | None - streamed body-through, no buffering. | Route to the healthiest full node on quorum tip (pruned node only if request has prune=true). | annotated | 60000 | Alias of /get_hashes.bin. |
| `/get_transaction_pool_hashes.bin` | legacy | PASSTHROUGH | None (mempool is per-node by nature). | Single node; response annotated Mnr-Upstream (opaque id). | annotated | 3000 | Mempool is per-node by nature; never cached. |
| `/get_transaction_pool_hashes` | legacy | PASSTHROUGH | None (mempool is per-node by nature). | Single node; response annotated Mnr-Upstream (opaque id). | annotated | 3000 | Mempool is per-node by nature; never cached. |
| `/get_transaction_pool_stats` | legacy | PASSTHROUGH | None (mempool is per-node by nature). | Single node; response annotated Mnr-Upstream (opaque id). | annotated | 3000 | Mempool is per-node by nature; never cached. |
| `/is_key_image_spent` | legacy | PASSTHROUGH | None (spent status changes with the mempool). | Single node on quorum tip. | annotated | 3000 | Restricted-safe; used by wallets during sync. |
| `/get_public_nodes` | legacy | PASSTHROUGH | None. | Single node on quorum tip. | annotated | 3000 | Public node list; we never forward client identity (no client IP, no X-Forwarded-For). |
| `/get_limit` | legacy | PASSTHROUGH | None. | Single node on quorum tip. | annotated | 3000 | Daemon bandwidth limits; we never forward client identity. |
| `get_txpool_backlog` | json-rpc | PASSTHROUGH | None. | Single node on quorum tip. | annotated | 3000 | Mempool backlog metrics; per-node by nature. |
| `get_txids_loose` | json-rpc | PASSTHROUGH | None. | Single node on quorum tip. | annotated | 3000 | Mempool txids by prefix; per-node by nature. |
| `/send_raw_transaction` | legacy | BROADCAST | None. | Fan out to all healthy upstreams in parallel; success if >=1 returns status OK. | annotated | 5000 | do_not_relay honoured; no retries (tx is idempotent on-chain); overall budget 6 s; result header Mnr-Relayed: k/n. If all reject, return the first error verbatim. |
| `/sendrawtransaction` | legacy | BROADCAST | None. | Fan out to all healthy upstreams in parallel; success if >=1 returns status OK. | annotated | 5000 | Alias of /send_raw_transaction. |
| `check_tx_key` | json-rpc | NOT-DAEMON | n/a | n/a | not-daemon | 0 | Wallet-RPC method, not a daemon method; return -32601 method not found with a hint. |
| `check_tx_proof` | json-rpc | NOT-DAEMON | n/a | n/a | not-daemon | 0 | Wallet-RPC method, not a daemon method; return -32601 method not found with a hint. |
| `check_spend_proof` | json-rpc | NOT-DAEMON | n/a | n/a | not-daemon | 0 | Wallet-RPC method, not a daemon method; return -32601 method not found with a hint. |
| `check_reserve_proof` | json-rpc | NOT-DAEMON | n/a | n/a | not-daemon | 0 | Wallet-RPC method, not a daemon method; return -32601 method not found with a hint. |
| `/get_alt_blocks_hashes` | legacy | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `/start_mining` | legacy | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `/stop_mining` | legacy | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `/mining_status` | legacy | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `/save_bc` | legacy | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `/get_peer_list` | legacy | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `/set_log_hash_rate` | legacy | DENY | n/a | n/a | n/a | 0 | Logging control; denied at the edge (403 / -32601). |
| `/set_log_level` | legacy | DENY | n/a | n/a | n/a | 0 | Logging control; denied at the edge (403 / -32601). |
| `/set_log_categories` | legacy | DENY | n/a | n/a | n/a | 0 | Logging control; denied at the edge (403 / -32601). |
| `/get_transaction_pool` | legacy | COMPOSED | None as a whole. Verified pool transactions are held by hash for 10 min, so a poll costs the listing plus one light call per transaction not seen before (charged as extra work units). | Listing from one node (the relay's own node first: it sees every broadcast the relay relays), annotated Mnr-Upstream; each transaction hash-verified through the /get_transactions path. | authenticated | 5000 | Composed from /get_transaction_pool_hashes and hash-verified /get_transactions (plan decision 8): every entry is proven to hash to its id, which no daemon offers. monerod after commit 57ae55e refuses this on restricted RPC; the relay answers it from public nodes regardless. receive_time is when the relay first saw the hash, never a node's claim; the fields a daemon fills from its own pool state (max_used_block_*, last_failed_*, kept_by_block, last_relayed_time, do_not_relay) are zero, false or empty. tx_json is the node's rendering of the verified blob; tx_blob is authoritative. |
| `/stop_daemon` | legacy | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `/get_net_stats` | legacy | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `/set_limit` | legacy | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `/out_peers` | legacy | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `/in_peers` | legacy | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `/update` | legacy | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `/pop_blocks` | legacy | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `get_connections` | json-rpc | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `get_bans` | json-rpc | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `set_bans` | json-rpc | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `banned` | json-rpc | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `flush_txpool` | json-rpc | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `relay_tx` | json-rpc | DENY | n/a | n/a | n/a | 0 | Restricted-gated (!m_restricted); cannot be served from a public node. Broadcast is available via /send_raw_transaction. |
| `sync_info` | json-rpc | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `prune_blockchain` | json-rpc | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `get_coinbase_tx_sum` | json-rpc | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `get_alternate_chains` | json-rpc | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `flush_cache` | json-rpc | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `get_block_template` | json-rpc | DENY | n/a | n/a | n/a | 0 | Mining/admin; denied at the edge (403 / -32601). |
| `getblocktemplate` | json-rpc | DENY | n/a | n/a | n/a | 0 | Alias of get_block_template (denied). |
| `get_miner_data` | json-rpc | DENY | n/a | n/a | n/a | 0 | Mining/admin; denied at the edge (403 / -32601). |
| `calc_pow` | json-rpc | DENY | n/a | n/a | n/a | 0 | Denied at the edge (403 / -32601); nodes also run --restricted-rpc as defence in depth. |
| `add_aux_pow` | json-rpc | DENY | n/a | n/a | n/a | 0 | Mining/admin; denied at the edge (403 / -32601). |
| `submit_block` | json-rpc | DENY | n/a | n/a | n/a | 0 | Mining/admin; denied at the edge (403 / -32601). |
| `submitblock` | json-rpc | DENY | n/a | n/a | n/a | 0 | Alias of submit_block (denied). |
| `generateblocks` | json-rpc | DENY | n/a | n/a | n/a | 0 | Mining/admin; denied at the edge (403 / -32601). |
