cardano-rpc
Safe HaskellNone
LanguageHaskell2010

Cardano.Rpc.Server.Internal.UtxoRpc.WaitForTx

Description

Handler for the UTxO RPC WaitForTx SubmitService method: stream stage transitions for a set of requested transactions until every one of them reaches STAGE_CONFIRMED.

Synopsis

Documentation

waitForTxMethod Source #

Arguments

:: MonadRpc e m 
=> Proto WaitForTxRequest

Request containing the transaction ids to wait for

-> (NextElem (Proto WaitForTxResponse) -> IO ())

Callback used to send each streamed response

-> m () 

Handle the WaitForTx SubmitService RPC method.

Reports STAGE_MEMPOOL when a ref enters the mempool and STAGE_CONFIRMED when a ref appears in a block applied after the stream opened, and closes the stream once every ref has reached STAGE_CONFIRMED.

Threading model: one thread per call, with no shared state. Each step is one STM wait on the chain tip and the pending refs' mempool membership, bounded by timeout; on a tip move the follower is drained without blocking.

Idle timeout: grapesy notices a gone client only when the handler sends to it, so a stream that has sent nothing for ten minutes ends with DEADLINE_EXCEEDED. A client that still wants the outcome reopens it.

Race contract: a transaction that reaches the chain between submission and this call is invisible - it is no longer in the mempool and will not appear in any block applied after the stream opens, so the stream never reports that ref. Clients must open WaitForTx before or concurrently with submitting the transaction.

Reconnect gap: for the same reason, a confirmation that lands between an idle close and the reopen is missed.

Rollbacks are not reported: a ref confirmed in a block that is later rolled back is not announced again; FollowTip's undo stream is the client-side tool for that.

Eviction is non-terminal: a ref that leaves the mempool without on-chain inclusion produces no message; the stream keeps waiting, since chain churn can legitimately re-add it later.

Mempool delivery follows observed membership: a ref gets STAGE_MEMPOOL when first observed in the mempool, and again after an observed removal and re-entry. Removal and re-entry between snapshots can be missed.

Duplicate refs in the request are treated as one. An empty request closes the stream immediately, with no messages sent - vacuously satisfied, and without opening a follower.

Throws INVALID_ARGUMENT if a ref is not a well-formed transaction id or the request has more than maxWaitForTxRefs refs, and DEADLINE_EXCEEDED when the idle timeout expires.

Internals, exported for tests

maxWaitForTxRefs :: Int Source #

The most refs one WaitForTx request may carry. Each pending ref is checked against the mempool on every wake-up.

parseRequestRefs :: MonadIO m => [ByteString] -> m (Set TxId) Source #

Parse the request refs into a set of transaction ids. Throws INVALID_ARGUMENT if there are more than maxWaitForTxRefs refs, duplicates included, or if a ref is not a well-formed transaction id.

waitForTxIdleTimeout :: DiffTime Source #

How long a WaitForTx stream may go without sending a message before it ends with DEADLINE_EXCEEDED: ten minutes.

idleTimeLeft Source #

Arguments

:: DiffTime

The idle deadline, on the monotonic clock

-> DiffTime

Monotonic time now

-> Maybe Int 

The microseconds left until the idle deadline, rounded up so that they never become a zero wait, or Nothing once the deadline has passed.

nextIdleDeadline Source #

Arguments

:: DiffTime

Monotonic time now, after sending

-> DiffTime

The current idle deadline

-> [Proto WaitForTxResponse]

The responses the step sent

-> DiffTime 

The idle deadline after a step: one waitForTxIdleTimeout from now if the step sent a response, unchanged otherwise.

idleDeadlineAfterStep Source #

Arguments

:: Bool

Whether the change was taken past the idle deadline

-> DiffTime

Monotonic time now, after sending

-> DiffTime

The current idle deadline

-> [Proto WaitForTxResponse]

The responses the step sent

-> Maybe DiffTime 

The idle deadline after a step, or Nothing if the stream must end with DEADLINE_EXCEEDED: a change taken past the deadline that sent no response.

data DrainedChange Source #

A chain update taken by drainFollower, reduced to what WaitForTx needs.

Constructors

DrainedBlock ChainPoint (Set TxId)

An applied block's point and the pending refs in it.

DrainedRollBack ChainPoint

A rollback to the given point.

drainedBlocks :: [DrainedChange] -> [Set TxId] Source #

The refs of each drained block that no later rollback in the same drain undid, oldest block first. A rollback to a point before every drained block undoes them all.

data WaitForTxEvent Source #

An event stepWaitForTx handles.

Constructors

TipBlocks [Set TxId]

The chain tip moved: the transaction ids in the blocks applied since the previous tip move, one set per block, oldest first. Ids that are not pending may be left out.

MempoolMembership (Set TxId)

The pending refs now in the mempool, after that set changed.

data WaitForTxState Source #

The per-ref state of a WaitForTx stream: refs still awaiting confirmation, and the refs already announced as in the mempool and still in it (so an evicted-then-re-added ref is announced again).

Constructors

WaitForTxState 

initialWaitForTxState :: Set TxId -> Maybe WaitForTxState Source #

The state of a new stream for the given refs, already deduplicated, or Nothing if there are none and the stream closes at once.

stepWaitForTx :: WaitForTxState -> WaitForTxEvent -> (Maybe WaitForTxState, [Proto WaitForTxResponse]) Source #

One step of the WaitForTx state machine: the next state, or Nothing once every ref is confirmed and the stream closes, and the responses to send, in order. Confirmations follow block order.