Skip to content
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

Merged
merged 2 commits into from
Aug 5, 2022

Conversation

nazrhom
Copy link
Contributor

@nazrhom nazrhom commented Jul 20, 2022

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]

Copy link
Collaborator

@ch1bo ch1bo left a 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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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.
Copy link
Collaborator

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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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.
Copy link
Collaborator

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.
Copy link
Collaborator

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
Copy link
Collaborator

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.

Comment on lines 51 to 54
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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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
...
Copy link
Collaborator

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.
Copy link
Collaborator

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?

Copy link
Contributor Author

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.
Copy link
Collaborator

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 :)

Copy link
Collaborator

@ch1bo ch1bo left a 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 :)

nazrhom and others added 2 commits August 3, 2022 09:57
@ch1bo ch1bo requested review from ffakenz and KtorZ August 3, 2022 07:58
@ch1bo ch1bo merged commit a69339d into cardano-scaling:master Aug 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants