-
-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Kupo x Hydra #117
Kupo x Hydra #117
Conversation
9a8bf3d
to
418f735
Compare
418f735
to
c2c32af
Compare
This way the default is still to compile with -Werror, but it allows a local override in a cabal.project.local file with: constraints: kupo -production
We need to keep the transactions around until a SnapshotConfirmed will yield a "block" containing them.
This should make much of a difference, but is a more idiomatic way to store things by key.
cc666a9
to
09e560e
Compare
We are re-using the ServerOutput golden files from the hydra repository to test compatibility with the hydra-node websocket API.
- Stub for TxValid decoder by using empty values (apart from txId) - Add confirmedTransactionIds parsing for Snapshot
This should already give use enough information to index some UTxO in the head.
Simulates transactions for each UTxO in the initial snapshot to make kupo index this "genesis" block.
The decoder is copy & pasted from ogmios with only ada/lovelace needing replacing. We should DRY this (or change our apis to be compatible).
b6efbd4
to
0d1009a
Compare
--since origin \ | ||
--match * \ | ||
--workdir ./db | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
src/Kupo/App/ChainSync/Hydra.hs
Outdated
-> [Point] | ||
-> WS.Connection | ||
-> m IntersectionNotFoundException | ||
runChainSyncClient mailbox beforeMainLoop _pts ws = do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're still doing nothing with the intersection points here, which means that we'll constantly re-index everything from scratch. This might re-insert previously deleted UTxO.
If I recall correctly, we discussed that a while back and settled on simply "skipping" messages from Hydra here until the intersection point as a first 'naive' implementation and until Hydra provides more reliable mechanisms for negotiating an intersection.
src/Kupo/App/ChainSync/Hydra.hs
Outdated
HeadIsOpen{genesisTxs} -> | ||
atomically (putHighFrequencyMessage mailbox (mkHydraBlock 0 genesisTxs)) | ||
TxValid{tx} -> | ||
pushTx tx |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose that this will work for lack of better options, but this will cause Kupo's memory to grow possibly unbounded.
Transactions are 'popped' on snapshot confirmed, which means that the memory should likely just grow and shrink on every snapshot, but that also means that any non-confirmed transaction will sit in the memory forever.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true. It's not ideal, but necessary given the current API. We should, however, record kupo's use case for a need of a more "complete" SnapshotConfirmed
message.. there is an ADR about making the Hydra API more resource based: cardano-scaling/hydra#1028.
src/Kupo/App/ChainSync/Hydra.hs
Outdated
pushTx :: PartialTransaction -> m () | ||
, -- | Resolves a transaction id and removes it. Throws | ||
-- 'TransactionNotInStore' when not found. | ||
popTxById :: MonadThrow m => TransactionId -> m PartialTransaction |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: it might be better to take a Set TransactionId
to avoid the repeated readTVar/writeTVar
since transactions are always removed in batches from the store.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In practice, hydra will snapshot after every transaction. So rarely we would receive a SnapshotConfirmed
with more than one tx inside. So batching things up is likely not going to be of big impact and I'd argue the singular API is a bit easier to use?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd argue the singular API is a bit easier to use?
I'd argue for the opposite; taking a foldable makes the API more generic and thus more easily composable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've solved your argument by accepting a [PartialTransaction]
for popTxByIds
;)
src/Kupo/Data/Hydra.hs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't looked at that module yet. But it seems like it's mostly about the Hydra's API and the underlying plumbing.
tx' <- popTxById txId | ||
tx' `shouldBe` tx | ||
popTxById txId `shouldThrow` \case | ||
TransactionNotInStore txId' -> txId' == txId |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small note: this test is 'misplaced' as it's testing stuff from Kupo.App.ChainSync.Hydra
, not from Kupo.Data.Hydra
.
I can move things around eventually, so consider this is just a note for myself 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's have @v0d1ch do it? :P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved to appropriate place.
So that we remove many elements from the store in a single atomic transaction.
a259e6b
to
397a4d8
Compare
We do this by skipping blocks because we don't really have much alternative. This is therefore relatively unsound for very long running head. Though is it more sound that actually replaying all events from that head onto an existing database; so it's kind of a best effort solution.
397a4d8
to
f28b673
Compare
🐉 Adds
--hydra-host
and--hydra-port
command line options to connect and index the head state of ahydra-node
🐉 Internally,
Hydra
is just anotherChainProducer
andHeadIsOpen
andSnapshotConfirmed
messages are mapped to rollforward of blocks.TODO:
hydra-node
easily (e.g. re-using the benchmarks in https://github.com/input-output-hk/hydra)HeadIsClosed
message? Use a rollbackward?