Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changes/20260921_cardano_rpc_chain_follower_payload.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
project: cardano-rpc
pr: 1351
kind:
- breaking
description: |
`ChainChange` and `ChainFollower` in `Cardano.Rpc.Server.NodeKernelAccess` now take the type of the per-block payload as a parameter. `withFollower` keeps giving the raw block bytes together with the parsed block, as `ChainFollower (ByteString, BlockInMode)`, and the new `withBlockFollower` gives only the parsed block, as `ChainFollower BlockInMode`. Code that names the old unparameterised `ChainChange` or `ChainFollower` types must add the payload type. The follower API now lives in the internal module `Cardano.Rpc.Server.NodeKernelAccess.Internal.Follower` and is re-exported from `Cardano.Rpc.Server.NodeKernelAccess`.

`ChainFollower` also has a new `tryNextChange` field that returns the next change without blocking, and `NodeKernelAccess` now also exports the STM reads `readChainTipPoint`, `readMempoolSnapshot` and `readCurrentEra`, so callers can wait for the chain tip or mempool to change. The new `positionFollowerAtCurrentTip` moves a freshly opened follower to the current chain tip and returns that point.
6 changes: 6 additions & 0 deletions .changes/20260921_cardano_rpc_wait_for_tx.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
project: cardano-rpc
pr: 1351
kind:
- feature
description: |
Add the `WaitForTx` method to the UTxO RPC submit service, which streams the progress of the given transactions until they are confirmed on chain. A `WaitForTx` stream that sends no update for 10 minutes ends with `DEADLINE_EXCEEDED`. Clients can reopen it, but the new stream does not report confirmations that occurred before it opened. A request with more than 500 transaction references is rejected with `INVALID_ARGUMENT`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
project: cardano-rpc
pr: 1351
kind:
- breaking
description: |
`MempoolWatchSnapshot` in `Cardano.Rpc.Server.NodeKernelAccess` no longer has the `mempoolWatchTicketNumbers` and `mempoolWatchSlotNo` fields; only `mempoolWatchTxsAfter` remains, so read new entries through it. `nextMempoolWatchSnapshot` and the next-snapshot callback of `watchMempoolStream` now take the last seen `TicketNo` instead of the previous snapshot, and return once the mempool holds an entry newer than that ticket. A waiting `WatchMempool` stream therefore wakes only when a transaction newer than the last one it sent arrives, so removals and slot-only changes no longer wake it. Its messages are unchanged.
2 changes: 1 addition & 1 deletion cardano-rpc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ A predicate naming more than 20,000 address terms (repeated addresses count) is
|--------|--------|
| [SubmitTx](https://utxorpc.org/submit/spec/#submittx) | ✅ Supported |
| [EvalTx](https://utxorpc.org/submit/spec/#evaltx) | ✅ Supported |
| [WaitForTx](https://utxorpc.org/submit/spec/#waitfortx) | ⬜ Not supported |
| [WaitForTx](https://utxorpc.org/submit/spec/#waitfortx) | ✅ Supported |
| [ReadMempool](https://utxorpc.org/submit/spec/#readmempool) | ✅ Supported |
| [WatchMempool](https://utxorpc.org/submit/spec/#watchmempool) | ✅ Supported |

Expand Down
3 changes: 3 additions & 0 deletions cardano-rpc/cardano-rpc.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ library
Cardano.Rpc.Server.Internal.UtxoRpc.Type.Tx
Cardano.Rpc.Server.Internal.UtxoRpc.Type.TxEval
Cardano.Rpc.Server.Internal.UtxoRpc.Type.TxOutput
Cardano.Rpc.Server.Internal.UtxoRpc.WaitForTx
Cardano.Rpc.Server.NodeKernelAccess
Cardano.Rpc.Server.NodeKernelAccess.Internal.Follower

other-modules:
Cardano.Rpc.Server.Internal.Orphans
Expand Down Expand Up @@ -244,4 +246,5 @@ test-suite cardano-rpc-test
Test.Cardano.Rpc.Script
Test.Cardano.Rpc.TxOutput
Test.Cardano.Rpc.Type
Test.Cardano.Rpc.WaitForTxStream
Test.Cardano.Rpc.WatchMempoolStream
3 changes: 2 additions & 1 deletion cardano-rpc/src/Cardano/Rpc/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import Cardano.Rpc.Server.Internal.UtxoRpc.Mempool
import Cardano.Rpc.Server.Internal.UtxoRpc.Query
import Cardano.Rpc.Server.Internal.UtxoRpc.Submit
import Cardano.Rpc.Server.Internal.UtxoRpc.Sync
import Cardano.Rpc.Server.Internal.UtxoRpc.WaitForTx
import Cardano.Rpc.Server.NodeKernelAccess
( NodeKernelAccess
, mkNodeKernelAccess
Expand Down Expand Up @@ -100,7 +101,7 @@ methodsUtxoRpcSubmit =
Method (mkNonStreaming $ wrapInSpan TraceRpcEvalTxSpan . evalTxMethod)
. Method (mkNonStreaming $ wrapInSpan TraceRpcReadMempoolSpan . readMempoolMethod)
. Method (mkNonStreaming $ wrapInSpan TraceRpcSubmitSpan . submitTxMethod)
. UnsupportedMethod -- waitForTx
. Method (mkServerStreaming $ \req -> wrapInSpan TraceRpcWaitForTxSpan . waitForTxMethod req)
. Method (mkServerStreaming $ \req -> wrapInSpan TraceRpcWatchMempoolSpan . watchMempoolMethod req)
$ NoMoreMethods

Expand Down
4 changes: 4 additions & 0 deletions cardano-rpc/src/Cardano/Rpc/Server/Internal/Tracing.hs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ data TraceRpcSubmit
TraceRpcEvalTxSpan TraceSpanEvent
| -- | Mempool read span
TraceRpcReadMempoolSpan TraceSpanEvent
| -- | Transaction confirmation wait span
TraceRpcWaitForTxSpan TraceSpanEvent
| -- | Mempool watch span
TraceRpcWatchMempoolSpan TraceSpanEvent
deriving Show
Expand All @@ -106,6 +108,8 @@ instance Pretty TraceRpcSubmit where
TraceRpcEvalTxSpan (SpanEnd _) -> "Finished eval tx method"
TraceRpcReadMempoolSpan (SpanBegin _) -> "Started read mempool method"
TraceRpcReadMempoolSpan (SpanEnd _) -> "Finished read mempool method"
TraceRpcWaitForTxSpan (SpanBegin _) -> "Started wait for tx method"
TraceRpcWaitForTxSpan (SpanEnd _) -> "Finished wait for tx method"
TraceRpcWatchMempoolSpan (SpanBegin _) -> "Started watch mempool method"
TraceRpcWatchMempoolSpan (SpanEnd _) -> "Finished watch mempool method"
TraceRpcEvalTxDecodingError e -> "Failed to decode transaction for evaluation: " <> pshow e
Expand Down
15 changes: 6 additions & 9 deletions cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Mempool.hs
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,16 @@ watchMempoolMethod request send = do
-- | The @WatchMempool@ streaming loop. Emits every mempool entry newer than
-- the last one seen, oldest first, filtered by the predicate.
--
-- Removals and slot-only changes (no new ticket) produce no message: the
-- proto has no representation for eviction, and a max-ticket comparison
-- upstream would otherwise miss exactly these transitions (see
-- 'Cardano.Rpc.Server.NodeKernelAccess.nextMempoolWatchSnapshot').
-- Removals produce no message: the proto has no representation for eviction.
watchMempoolStream
:: forall m
. MonadIO m
=> m MempoolWatchSnapshot
-- ^ Read the current mempool watch snapshot, without blocking - used
-- once, for the initial baseline
-> (MempoolWatchSnapshot -> m MempoolWatchSnapshot)
-- ^ Block until the snapshot differs from the given one, then return the
-- new one
-> (Consensus.TicketNo -> m MempoolWatchSnapshot)
-- ^ Block until an entry newer than the given ticket exists, then return
-- the snapshot
-> Proto U5c.TxPredicate
-- ^ Predicate filtering which new entries are sent
-> (NextElem (Proto U5c.WatchMempoolResponse) -> IO ())
Expand All @@ -75,7 +72,7 @@ watchMempoolStream readSnapshot nextSnapshot predicate send = do
go Consensus.zeroTicketNo initial
where
go :: Consensus.TicketNo -> MempoolWatchSnapshot -> m ()
go lastSeenTicket snapshot@MempoolWatchSnapshot{mempoolWatchTxsAfter = txsAfter} = do
go lastSeenTicket MempoolWatchSnapshot{mempoolWatchTxsAfter = txsAfter} = do
let newEntries = txsAfter lastSeenTicket
forM_ newEntries $ \(txInMode, _ticketNo) ->
forM_ (txInModeToTxInMempool txInMode) $ \txInMempool ->
Expand All @@ -85,4 +82,4 @@ watchMempoolStream readSnapshot nextSnapshot predicate send = do
let lastSeenTicket' = case newEntries of
[] -> lastSeenTicket
_ -> snd (last newEntries)
nextSnapshot snapshot >>= go lastSeenTicket'
nextSnapshot lastSeenTicket' >>= go lastSeenTicket'
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ followTipStream
:: forall m
. HasCallStack
=> MonadIO m
=> ChainFollower
=> ChainFollower (ByteString, BlockInMode)
-- ^ Follower to stream changes from
-> m (Maybe (Proto U5c.BlockRef))
-- ^ Read the current chain tip, projected into a @BlockRef@
Expand Down
Loading
Loading