Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

This page describes proposed changes that are not yet part of the Cardano mainnet. They are specified as part of Leios (CIP-0164), an extension to the Ouroboros consensus protocol aimed at significantly increasing transaction throughput. Details are subject to change.

LeiosNotify

Mini-protocol number: 18

LeiosNotify is the mini-protocol responsible for announcing Endorser Blocks (EBs) and offering EB bodies and their associated transaction closures to peers. It is a pull-based protocol: the client drives progress by requesting the next notification, and the server replies with whatever is available.

Leios introduces Endorser Blocks as a mechanism to endorse and achieve consensus on transaction inclusion independently and overlayed on the Praos block chain. LeiosNotify is the dissemination layer that lets peers discover new EBs before fetching them via LeiosFetch. The protocol is intended to run in a pipelined fashion where the client issues multiple MsgRequestNext even before receiving a notification, so that the server can push announcements to downstream peers with minimal latency.

Warning

TODO: Add more detail about admitted pipeline depth and other punishable requirements

State machine

graph LR
   classDef client color:black,fill:PaleGreen,stroke:DarkGreen;
   classDef server color:black,fill:PowderBlue,stroke:DarkBlue;
   linkStyle default stroke:gray

   StDone(((StDone)))

   i(( )) --> StIdle
   StIdle --MsgQuit--> StQuit
   StQuit --MsgDone--> StDone
   StIdle --MsgLeiosNotificationRequestNext--> StBusy
   StBusy --MsgLeiosBlockAnnouncement--> StIdle
   StBusy --MsgLeiosBlockOffer--> StIdle
   StBusy --MsgLeiosBlockTxsOffer--> StIdle
   StBusy --MsgLeiosVotes--> StIdle
   StBusy --MsgCanceled--> StIdle

   class StIdle client
   class StBusy server
   class StQuit server

Terminating

The client cannot simply stop. It only has agency in StIdle, and a request leaves it in StBusy awaiting a reply the server may have no reason to send: under light load there may be nothing to announce for a long while. A node being demoted from hot to warm has a bounded time to shut the protocol down cleanly, and losing that race costs the whole connection rather than just this mini-protocol.

Two messages resolve that. MsgCanceled lets the server answer “nothing for you” and hand agency back, so the client is never stranded in StBusy. And MsgQuit lets the client declare it is leaving without first draining the replies it has outstanding – it may be pipelining many requests, and waiting for each in turn would make shutdown latency a function of pipeline depth. The server closes with MsgDone, so termination is a two-step handshake rather than a unilateral act by either side.

State agencies

StateAgency
StIdleInitiator
StBusyResponder
StQuitResponder

State transitions

From stateMessageParametersTo state
StIdleMsgQuitStQuit
StQuitMsgDoneEnd
StIdleMsgLeiosNotificationRequestNextStBusy
StBusyMsgLeiosBlockAnnouncementannouncementStIdle
StBusyMsgLeiosBlockOfferpoint, eb_sizeStIdle
StBusyMsgLeiosBlockTxsOfferpointStIdle
StBusyMsgLeiosVotes[1* vote]StIdle
StBusyMsgCanceledStIdle

Codecs

The messages depicted in the state machine follow this CDDL specification:

;; messages.cddl
; Termination first, then the request, then the responses it can draw. Votes
; come last so a future votes mini-protocol can take them away without
; renumbering anything else.
leiosNotifyMessage
     = msgDone
     / msgQuit
     / msgCanceled
     / msgLeiosNotificationRequestNext
     / msgLeiosBlockAnnouncement
     / msgLeiosBlockOffer
     / msgLeiosBlockTxsOffer
     / msgLeiosVotes

msgDone                         = [0]
msgQuit                         = [1]
msgCanceled                     = [2]
msgLeiosNotificationRequestNext = [3]
msgLeiosBlockAnnouncement       = [4, announcement]
msgLeiosBlockOffer              = [5, point, eb_size]
msgLeiosBlockTxsOffer           = [6, point]
msgLeiosVotes                   = [7, [1* vote]]

announcement = any ; TODO
point = [slot, eb_hash]

; Not redundant with the announcement's size: the point alone does not say
; which announcement is being offered, and two announcements -- even from
; different elections -- can name one endorser block in one slot at different
; sizes.
eb_size = base.word32
slot = base.slotno
eb_hash = base.hash

vote =
  [ announcing_rb_hash    : base.hash
  , voter_id              : base.word16
  , vote_signature        : leios_bls_signature
  ]

leios_bls_signature = bytes .size 48

;# import base as base

Note

The CBOR tags in this specification are provisional. Several types remain underspecified (any) pending further protocol design. See CIP-0164 for rationale and ongoing discussion.