-
Notifications
You must be signed in to change notification settings - Fork 86
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
Add developing with hydra guide #433
Conversation
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.
Thanks for contributing this write-up! This is a very good start, but requires some more work IMO. See my suggestions and maybe you can add/update one or the other things per the comments? Thanks
|
||
## On-chain code | ||
|
||
On-chain code will be exactly the same between Cardano and a hydra head. This is one of the main selling points of the hydra design (heads are also called isomorphic state channels) the only caveat being that (at the time of writing 07-22) hydra heads do not support validity ranges for transactions, the reason for this is there is currently no notion of time inside of a hydra head. |
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.
On-chain code will be exactly the same between Cardano and a hydra head. This is one of the main selling points of the hydra design (heads are also called isomorphic state channels) the only caveat being that (at the time of writing 07-22) hydra heads do not support validity ranges for transactions, the reason for this is there is currently no notion of time inside of a hydra head. | |
On-chain code will be exactly the same between Cardano and a hydra Head. This is one of the main selling points of the hydra design (heads are also called isomorphic state channels) the only caveat being that (at the time of writing 07/22) Hydra Heads do not support validity ranges for transactions, the reason for this is there is currently no notion of time inside of a Hydra Head. See also this [feature on the roadmap](https://github.com/input-output-hk/hydra-poc/issues/196) |
|
||
Here is where the differences will begin. Usually, DApp developers will write some off-chain code to interact with their validators and minting policies. | ||
This off-chain code will usually be exposed through an HTTP interface that frontends can access to drive interactions with the application forward. | ||
Off-chain code is usually written in the Contract monad, which is used to build transactions and interact with the Cardano blockchain in a controlled way. |
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 don't the that the PAB is THE standard way of writing DApps. It might be that readers are familiar with it if they have taken part in the plutus pioneers program.
Can you make this a bit less opinionated? i.e. state that it's not like in the PPP because we there is also no PAB support (yet, there is also this ticket: #214 and has not been tackled because nobody shouted as us yet + the PAB is kind of getting redesigned).
The API reference is divided into two sections: Pub and Sub. | ||
The first one describes the commands that a hydra node will accept, while the second one describes the events that will be emitted through the websocket. | ||
|
||
An important event developers will be interested in is `SnaphotConfirmed`. This event is emitted once all the hydra nodes that are partaking in the head, have seen and signed a transaction submitted by one of them. |
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.
An important event developers will be interested in is `SnaphotConfirmed`. This event is emitted once all the hydra nodes that are partaking in the head, have seen and signed a transaction submitted by one of them. | |
An important event developers will be interested in is `SnaphotConfirmed`. This event is emitted once all the participants of the head, have seen and signed a transaction submitted by one of them. |
|
||
An important event developers will be interested in is `SnaphotConfirmed`. This event is emitted once all the hydra nodes that are partaking in the head, have seen and signed a transaction submitted by one of them. | ||
|
||
Once a transaction lands inside a snapshot, it is confirmed and there are no chances for it to be rolled back. This is an important distinction from L1: in that case, when a node sees a transaction there is still a chance that it might be rolled back (where the probability of this goes to 0 as more blocks are added), in the hydra world, the only way to make a snapshot is to have every single node in the head approve of it. |
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.
About rollbacks: this is only true after the head has been open long enough and the opening tx has become final. Might want to link this feature for more details: #185
|
||
The Hydra node will emit several commands through this websocket: the API is defined [here](https://hydra.family/head-protocol/api-reference). | ||
The API reference is divided into two sections: Pub and Sub. | ||
The first one describes the commands that a hydra node will accept, while the second one describes the events that will be emitted through the websocket. |
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.
Before diving into the API endpoints (below), is there something to consider on initializing & opening the head?
-- This starts the BFTNode as described above | ||
withBFTNode (contramap FromCardanoNode tracer) config $ \(RunningNode _ nodeSocket) -> do | ||
-- We create a temporary directory to contain all the files required to spin up the hydra nodes | ||
withTempDir "hydra-nodes-tmp-dir" $ \hTmpDir -> 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.
I would recommend to re-use the temp dir to make this simpler. No point in separating, both will now (soon #430) write to logs/cardano-node.log
and logs/hydra-node-x.log
.
withTempDir "cardano-node-tmp-dir" $ \cTmpDir -> do | ||
config <- newNodeConfig cTmpDir | ||
-- This starts the BFTNode as described above | ||
withBFTNode (contramap FromCardanoNode tracer) config $ \(RunningNode _ nodeSocket) -> 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.
withTempDir "cardano-node-tmp-dir" $ \cTmpDir -> do | |
config <- newNodeConfig cTmpDir | |
-- This starts the BFTNode as described above | |
withBFTNode (contramap FromCardanoNode tracer) config $ \(RunningNode _ nodeSocket) -> do | |
withTempDir "hydra-cluster-example-tmp-dir" $ \tmpDir -> do | |
-- This starts the cardano devnet as described above | |
withCardanoDevnet (contramap FromCardanoNode tracer) tmpDir $ \RunningNode{nodeSocket} -> do |
-- This will spin up `n` hydra nodes, where `n` is the length of the cardanoKeys list | ||
-- (which needs to match the length of hydraKeys) | ||
withHydraCluster tracer hTmpDir nodeSocket firstNodeId cardanoKeys hydraKeys $ \nodes -> 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.
If you do a pure ()
here, we could even think of making this whole thing doctestable / compilable?
I think this is missing distributing funds with the seedFromFaucet
stuff and maybe we also want to include some actual send "Init" ["contestationPeriod" .= 10]
etc.?
Your text below could become comments in between.
Remember that we must handle the whole head initialisation inside the test as well, so the first step will always be for one of the two nodes to `send` an `Init` command | ||
to start the opening of the head. | ||
|
||
Finally, hydra-node exposes several useful functions to wait for output from the hydra nodes themselves, both these functions have a timeout so they will function as assertions from a testing point of view; that is, if the node does not output what we expect within a certain timeframe, an error will be thrown and the whole test will fail. |
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.
There should not be anything to import from hydra-node
, what were you using from hydra-node
?
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 was a typo :( meant hydra-cluster
`waitFor` will take a list of hydra-nodes and an Aeson Value, and check if they all produce the expected output within the allowed timeframe. | ||
|
||
`waitMatch` instead can be used to parse the output and possibly extract some information from that to be used in subsequent steps of the test. | ||
For example, after we submit a transaction to the node, we can use `waitMatch` to parse the `SnaphotConfirmed` event and extract the transactions present in that snapshot to check if it contains the transaction we just sent. |
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.
Instead of documenting the functions here, probably better to just link the haddocks (https://hydra.family/head-protocol/haddock/hydra-cluster/HydraNode.html) and enumerate them as handy functions.
Should there be no haddocks -> move these docs there :)
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.
Looking good. Let's get this on the website and keep extending this tutorial :)
This guide was taken from https://github.com/mlabs-haskell/hydra-demo Change-type: patch Signed-off-by: Giovanni Garufi <[email protected]>
1e88b1e
to
5fa277f
Compare
This guide was taken from https://github.com/mlabs-haskell/hydra-demo
I am not sure if the whole guide makes sense in this context; the off-chain code section is possibly redundant and already covered in other parts of the main hydra documentation.
The section on testing is novel, and I think would be a good addition to have here. I wonder if it is worth refactoring this document into a guide specifically about that.
Change-type: patch
Signed-off-by: Giovanni Garufi [email protected]