The ouroboros-network1 is a component of the cardano-node2 including a specification of all mini-protocols. It provides necessary information about both node-to-node and node-to-client protocols. Please familiarize with the technical document The Shelley Networking Protocol3 beforehand.

Local State Query

The implementation of the mini protocols uses a generic framework for state machines. At any time, one side(client/server) has agency (is expected to transmit the next message) and the other side is awaiting for the message (or both sides agree that the protocol has terminated). If either side receives a message that is not expected according to the protocol the communication is aborted.

All mini-protocols are encoded using concise binary object representation (CBOR)4. The following specification follows a CDDL5 style.

Local State Query mini-protocol allows to query the consensus / ledger state. This mini protocol is part of the Node-to-Client protocol, hence it is only used by local (and thus trusted) clients. The protocol specifies basic operations like acquiring / releasing the consensus / ledger state which is done by the server, or running queries against the acquired ledger state.

Figure 1: State machine of the Local State Query mini-protocol.

Figure 1: State machine of the Local State Query mini-protocol.

The following documentation is tested against the cardano-node 1.34.1 and uses on its handshake the protocol version 10, or cardano-node 1.35.0 with handshake protocol version 13. When results differ, they are annotated in comments. Attached is a reference implementation Emacs-Lisp on how to perform the node-to-client communication and the local state queries. The language selection is due to its foreseeable integration with the cardano.el6 project. Aside it is a simple language that nears pseudocode semantics, thus its easily readable and its capabilities to use symbols make it even simple. Finally it provides interactive development, that is you can directly test code sections without running a complete program. You as a developer can take some of the computing tasks before the program/state machine is fully developed.

Review of common definitions

Type CDDL
point origin / blockHeaderHash
origin []
blockHeaderHash [slotNo, int]
slotNo word64

LocalStateQuery mini-protocol

Type CDDL Comment
msgAcquire [0, point] Request to acquire information corresponding to specific point
[8] Shortcut to request for current chain tip
msgAcquired [1] Successfully acquired requested point
msgFailure [2, failure] failure replies see following table.
msgQuery [3, query] query for something. Descriptions in next sections
msgResult [4, result] result to query. Descriptions in next sections
msgRelease [5] Release current point. No reply from server
msgReAcquire [6, point] Ask for new specific point
[9] Shortcut to ask for new current chain tip
lsqMsgDone [7] Terminate the protocol. (Communication channel closed as well)
Type/failure CDDL
acquireFailurePointTooOld 0
acquireFailurePointNotOnChain 1

Available queries and results

Each of the following sections is describes the query and corresponding result for the local state query in CDDL format. Values that are for the moment unknown are either copied verbatim from reply, they are some constants or the NA for a value that changes in results.

System-start

Type CDDL Comment
query [1] Request start date of blockchain
result start
start [a, b, c] a=year, b=day of year, c=picoseconds of day

Block-number

Type CDDL Comment
query [2] Request number current block pointed at
result [1 blockNo]

Chain-point

Type CDDL Comment
query [3] Request current block pointed at
result blockHeaderHash

Blockchain HardForks

HardForks (GetInterpreter)

Type CDDL Comment
query [0 [2 [0]]] Request history of Eras
result [ *eraSpan ]
eraSpan [begin, end, params] end is exclusive
params [epochLength, slotLength, [0 SlotsPerKESPeriod [0]]] slot length is in miliseconds
begin [0, 0, 0] Genesis
begin/end [#6.2(bytes), slotNo, epochNo] bytes is bytestring of timespan of in nanoseconds
begin/end [timespan, slotNo, epochNo] node-1.35 on Babbage this timespan changed to an unsigned number for picoseconds

Current Era

Type CDDL Comment
query [0 [2 [1]]] Request current Era
result 0 Byron
result 1 Shelley
result 2 Allegra
result 3 Mary
result 4 Alonzo
result 5 Babbage

Shelley queries

Each of this queries must be wrapped as follows [0 [0 [Era query]]]. Thus when you read query = [1] you must sent on the communication [0 [0 [4 [1]]]] if the node is currently the Alonzo Era. The Era numbering is your result from section: Current Era.

All results seem to by wrapped in a containing array. Thus you’ll find all CDDL enclosing the result with [], even when single values return.

chain-point

Type CDDL Comment
query [0] Request block hash at the current chain point
result [blockHeaderHash]

Epoch number

Type CDDL Comment
query [1] Request current epoch
result [epochNo]

Non Myopic member rewards

Type CDDL Comment
query [2 #6.258([*[0 int]]) int is the stake the user intends to delegate, the array must be sorted
result [{ *[0 int] => non_myopic_rewards }] for each stake display reward
non_myopic_rewards { *poolid => int } int is the amount of lovelaces each pool would reward

Current protocol params

Type CDDL Comment
query [3]
result [*ParamElement] Expanded in order bellow
ParamElement CDDL Comment
minFeeA
minFeeB
MaxBlockBodySize
maxTxSize
maxBlockHeaderSize
keyDeposit
poolDeposit
eMax poolRetireMaxEpoch
nOpt stakePoolTargetNum
a0 #6.30([num den]) poolPledgeInfluence
rho #6.30([num den]) monetaryExpansion
tau #6.30([num den]) treasuryCut
decentralizationParam #6.30([num den]) Doesn’t exist in Babbage
ProtocolVersionMajor
ProtocolVersionMinor
minPoolCost
NA
costModels TODO expand
executionUnitPrices [priceMemory priceSteps] both elements are fractions
maxTxExecutionUnits [memory steps]
maxBlockExecutionUnits [memory steps]
maxValueSize
collateralPercentage collateralPercentage

TODO Proposed Protocol params updates

Type CDDL Comment
query [4]
result NA

Stake distribution

Type CDDL Comment
query [5]
result [{ *poolid => [[num den] vrf-hash]}] num/den is the quotient representing the stake fractions

UTxO by Address

Type CDDL Comment
query [6 #6.258([ *addr ])] Sorting order for addr is important although not standardized.
result [{* utxo => value }]
addr bytestring bytestring follows the format of 8 bit header then payload
utxo [hash idx datum_hash?] datum_hash is optional. 2 or 3 element array
value coin / [coin multiasset<uint>]
multiasset<a> {*policy_id => {*asset_name => a}}
policy_id scripthash
asset_name bytes .size (0..32)

All addresses queried must follow a specific order in the query. Such order is not standardized, it is probably even a bug that an order is required.

Whole UTxO set

Type CDDL Comment
query [7]
result [{* utxo => value }]

TODO Debug Epoch state

Type CDDL Comment
query [8]
result [NA]

CBOR wrapped Shelley query

Type CDDL Comment
query [9 query ] where query is any of the queries in this section
result [ #6.24(bytestring) ] bytestring must be CBOR decoded again to read result

Filtered Delegation and reward accounts

Type CDDL Comment
query [10 #6.258([ *rwdr ])]
rwdr [flag bytestring] bytestring is the keyhash of the staking vkey
flag 0/1 0=keyhash 1=scripthash
result [[ delegation rewards] ]
delegation { * rwdr => poolid } poolid is a bytestring
rewards { * rwdr => int }

It seems to be a requirement to sort the reward addresses on the query. Scripthash addresses come first, then within a group the bytestring being a network order integer sort ascending.

Shelley Genesis configuration

The result vector is at the moment a best guess. Some values are not yet understood and thus named NA

Type CDDL Comment
query [11]
result [ *Element ] Expanded in order on the next rows.
Element CDDL Comment
start
network-magic
NetworkId 0/1 Testnet/Mainnet
activeSlotsCoeff
securityParam
epochLength
slotsPerKESPeriod
maxKESEvolutions
NA Maybe slotLength
updateQuorum
maxLovelaceSupply
protocolParams [ *ParamElement ] Expanded in order bellow
genDelegs {*hash=> [ delegate-hash vrf-hash]}
NA
NA
ParamElement CDDL Comment
minFeeA
minFeeB
MaxBlockBodySize
maxTxSize
maxBlockHeaderSize
keyDeposit
poolDeposit
eMax poolRetireMaxEpoch
nOpt stakePoolTargetNum
a0 #6.30([num den]) poolPledgeInfluence
rho #6.30([num den]) monetaryExpansion
tau #6.30([num den]) treasuryCut
decentralizationParam #6.30([num den])
NA Maybe extraEntropy
ProtocolVersionMajor
ProtocolVersionMinor
minUTxOValue
minPoolCost

TODO Debug New Epoch state

Type CDDL Comment
query [12]
result [NA]

TODO Debug Chain Dep State

Type CDDL Comment
query [13]
result [NA]

Reward Provenance

Type CDDL Comment
query [14]
result [ *Element ] Expanded in order on the next rows.
Element CDDL Comment
epochLength
poolMints { *poolid => block-count }
maxLovelaceSupply
NA
NA
NA
?circulatingsupply?
total-blocks
?decentralization? [num den]
?available block entries
success-rate [num den]
NA
NA ??treasuryCut
activeStakeGo
nil
nil

UTxO by TxIn

Type CDDL Comment
query [15 #6.258([ *txin ])] txin must be sorted.
result [{* utxo => value }]

Stake Pools

Type CDDL Comment
query [16]
result [#6.258([ *poolid ])]

Stake Pool Params

Type CDDL Comment
query [17 #6.258([*poolid])
result [{ *poolid => [ *pool_param ] }]
pool_param CDDL Comment
operator keyhash
vrf_keyhash keyhash
pledge coin
margin #6.30([num den])
reward_account
pool_owners set<addr_keyhash>
relays [ *relay ]
pool_metadata pool_metadata/null
relay CDDL Comment
single_host_addr [0 port/null ipv4/null ipv6/null]
single_host_name [1 port/null dns_name] An A or AAAA DNS
multi_host_name [2 dns_name] A SRV DNS record
Type CDDL Comment
port uint .le 65535
ipv4 bytes .size 4
ipv6 bytes .size 16
dns_name tstr .size (0..64)
pool_metadata [url metadata_hash]
url tstr .size (0..64)

TODO RewardInfoPools

Type CDDL Comment
query [18]
result [stuff pooldata]
stuff [nOpt tau A B ] A & B are maybe total_staked & circulatingsupply
pooldata { *poolid => [staked pledge NA cost margin nil] }