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

The hydra node can publish hydra scripts via blockfrost using --blockfrost #1907

Open
wants to merge 18 commits into
base: master
Choose a base branch
from

Conversation

v0d1ch
Copy link
Contributor

@v0d1ch v0d1ch commented Mar 20, 2025

➜ nix run .#hydra-node -- publish-scripts \
    --blockfrost-project-path "/home/v0d1ch/code/hydra/blockfrost.txt" \
    --blockfrost-cardano-signing-key hydra-cluster/config/credentials/alice.sk
47d353a235d79df09cd9988de61d1996f91d1c8353a50a50b0e70d243f8c6db5,0e357d764666224e39af69ecaf1525980df57595340ac8895fdd023349b62522,68560aa902b388b9a226ad6ed0c33fbe2749353d36336ecce27623600ca43964




  • CHANGELOG updated or not needed
  • Documentation updated or not needed
  • Haddocks updated or not needed
  • No new TODOs introduced or explained herafter

@v0d1ch v0d1ch self-assigned this Mar 20, 2025
@v0d1ch v0d1ch force-pushed the handle-transaction-building-using-blockfrost-api branch from 61346f9 to 2df6034 Compare March 20, 2025 12:10
Copy link

github-actions bot commented Mar 20, 2025

Transaction cost differences

Script summary

Name Size (Bytes)
νInitial -
νCommit -
νHead -
μHead -
νDeposit -

Init transaction costs

Parties Tx size % max Mem % max CPU Min fee ₳
1 - - - -
2 - - - -
3 - - - -
5 - - - -
10 - - - -
40 - - - -

Commit transaction costs

UTxO Tx size % max Mem % max CPU Min fee ₳
1 - - - -
2 - - - -
3 - - - -
5 - - - -
10 - - - -
54 - - - -

CollectCom transaction costs

Parties UTxO (bytes) Tx size % max Mem % max CPU Min fee ₳
1 - - - - -
2 - - - - -
3 - - - - -
4 - - - - -
5 - - - - -
6 - - - - -
7 - - - - -
8 - - - - -

Cost of Increment Transaction

Parties Tx size % max Mem % max CPU Min fee ₳
1 - $${\color{green}-0.39}$$ $${\color{green}-0.09}$$ -
2 - - - -
3 - $${\color{green}-0.39}$$ $${\color{green}-0.09}$$ -
5 - - - -
10 - - - -
37 - - - -

Cost of Decrement Transaction

Parties Tx size % max Mem % max CPU Min fee ₳
1 - - - -
2 - - - -
3 - - - -
5 - - - -
10 - - - -
40 - - - -

Close transaction costs

Parties Tx size % max Mem % max CPU Min fee ₳
1 - - - -
2 - - - -
3 - - - -
5 - - - -
10 - - - -
34 - - - -

Contest transaction costs

Parties Tx size % max Mem % max CPU Min fee ₳
1 - - - -
2 - - - -
3 - - - -
5 - - - -
10 - - - -
27 - - - -

FanOut transaction costs

UTxO, Parties UTxO (bytes) Tx size % max Mem % max CPU Min fee ₳
(0, 10) - - - - -
(1, 10) - - - - -
(5, 10) - - - - -
(10, 10) - - - - -
(20, 10) - - - - -
(37, 10) - - - - -

Copy link

github-actions bot commented Mar 20, 2025

Transaction costs

Sizes and execution budgets for Hydra protocol transactions. Note that unlisted parameters are currently using arbitrary values and results are not fully deterministic and comparable to previous runs.

Metadata
Generated at 2025-04-02 14:57:46.162391975 UTC
Max. memory units 14000000
Max. CPU units 10000000000
Max. tx size (kB) 16384

Script summary

Name Hash Size (Bytes)
νInitial c8a101a5c8ac4816b0dceb59ce31fc2258e387de828f02961d2f2045 2652
νCommit 61458bc2f297fff3cc5df6ac7ab57cefd87763b0b7bd722146a1035c 685
νHead 0e35115a2c7c13c68ecd8d74e4987c04d4539e337643be20bb3274bd 14756
μHead 57166715eadb8d3135964325c016eea546c21e1c0aae974ca67df9a5* 5541
νDeposit ae01dade3a9c346d5c93ae3ce339412b90a0b8f83f94ec6baa24e30c 1102
  • The minting policy hash is only usable for comparison. As the script is parameterized, the actual script is unique per head.

Init transaction costs

Parties Tx size % max Mem % max CPU Min fee ₳
1 6095 10.80 3.35 0.53
2 6298 13.56 4.22 0.57
3 6495 15.71 4.88 0.60
5 6897 20.19 6.25 0.66
10 7904 31.18 9.61 0.82
40 13936 98.88 30.39 1.78

Commit transaction costs

This uses ada-only outputs for better comparability.

UTxO Tx size % max Mem % max CPU Min fee ₳
1 561 2.44 1.16 0.20
2 738 3.38 1.73 0.22
3 923 4.36 2.33 0.24
5 1277 6.41 3.60 0.28
10 2175 12.13 7.25 0.40
54 10077 98.61 68.52 1.88

CollectCom transaction costs

Parties UTxO (bytes) Tx size % max Mem % max CPU Min fee ₳
1 57 525 26.44 7.58 0.44
2 114 636 33.99 9.79 0.52
3 169 747 41.97 12.05 0.61
4 227 858 52.15 14.92 0.72
5 281 969 65.79 18.55 0.86
6 340 1081 68.92 19.64 0.90
7 395 1192 75.74 21.79 0.97
8 450 1303 92.24 26.14 1.14
9 508 1414 98.12 27.89 1.21

Cost of Increment Transaction

Parties Tx size % max Mem % max CPU Min fee ₳
1 1785 25.50 8.33 0.49
2 1921 27.03 9.47 0.52
3 2064 28.65 10.64 0.55
5 2280 30.55 12.52 0.59
10 3246 44.92 20.70 0.81
38 7319 97.56 56.13 1.67

Cost of Decrement Transaction

Parties Tx size % max Mem % max CPU Min fee ₳
1 615 23.99 7.61 0.43
2 827 26.90 9.08 0.47
3 989 29.14 10.36 0.50
5 1237 31.87 12.43 0.55
10 2087 45.55 19.54 0.75
38 6224 97.98 52.67 1.60

Close transaction costs

Parties Tx size % max Mem % max CPU Min fee ₳
1 688 29.19 9.22 0.48
2 841 30.98 10.44 0.51
3 1030 33.56 11.99 0.55
5 1261 37.18 14.42 0.61
10 2158 51.78 22.52 0.83
32 5427 95.00 51.36 1.53

Contest transaction costs

Parties Tx size % max Mem % max CPU Min fee ₳
1 670 35.95 11.00 0.55
2 847 38.85 12.63 0.59
3 900 39.66 13.34 0.61
5 1275 45.22 16.55 0.69
10 1948 56.90 23.44 0.86
26 4426 95.13 46.25 1.45

Abort transaction costs

There is some variation due to the random mixture of initial and already committed outputs.

Parties Tx size % max Mem % max CPU Min fee ₳
1 5990 28.20 9.30 0.71
2 6046 36.53 12.00 0.80
3 6286 47.74 15.78 0.93
4 6369 53.77 17.74 0.99
5 6567 67.83 22.41 1.15
6 6590 75.13 24.68 1.23
7 6828 84.71 28.00 1.34
8 6868 92.93 30.67 1.42

FanOut transaction costs

Involves spending head output and burning head tokens. Uses ada-only UTXO for better comparability.

Parties UTxO UTxO (bytes) Tx size % max Mem % max CPU Min fee ₳
10 0 0 6091 19.66 6.46 0.62
10 1 57 6126 21.79 7.29 0.65
10 5 284 6261 28.93 10.13 0.73
10 10 568 6429 42.80 15.34 0.89
10 30 1707 7111 84.49 31.56 1.37
10 37 2107 7350 98.48 37.03 1.54

End-to-end benchmark results

This page is intended to collect the latest end-to-end benchmark results produced by Hydra's continuous integration (CI) system from the latest master code.

Please note that these results are approximate as they are currently produced from limited cloud VMs and not controlled hardware. Rather than focusing on the absolute results, the emphasis should be on relative results, such as how the timings for a scenario evolve as the code changes.

Generated at 2025-04-02 15:00:05.226857177 UTC

Baseline Scenario

Number of nodes 1
Number of txs 300
Avg. Confirmation Time (ms) 4.396488833
P99 6.91553711ms
P95 5.2504213ms
P50 4.25732ms
Number of Invalid txs 0

Memory data

Time Used Free
2025-04-02 14:58:50.326026642 UTC 885M 3775M
2025-04-02 14:58:55.325900528 UTC 1008M 3622M
2025-04-02 14:59:00.325856902 UTC 1009M 3621M
2025-04-02 14:59:05.325835873 UTC 1009M 3621M
2025-04-02 14:59:10.325841569 UTC 1010M 3620M
2025-04-02 14:59:15.325835829 UTC 1012M 3617M

Three local nodes

Number of nodes 3
Number of txs 900
Avg. Confirmation Time (ms) 27.666624184
P99 40.72365471999998ms
P95 36.18284755ms
P50 26.853201499999997ms
Number of Invalid txs 0

Memory data

Time Used Free
2025-04-02 14:59:28.303909465 UTC 894M 3744M
2025-04-02 14:59:33.304475453 UTC 1192M 3441M
2025-04-02 14:59:38.306091961 UTC 1240M 3327M
2025-04-02 14:59:43.304299113 UTC 1247M 3280M
2025-04-02 14:59:48.304083686 UTC 1252M 3274M
2025-04-02 14:59:53.304154712 UTC 1253M 3272M
2025-04-02 14:59:58.30431092 UTC 1261M 3264M
2025-04-02 15:00:03.304191541 UTC 1263M 3262M

@v0d1ch v0d1ch requested a review from a team March 20, 2025 15:55
@v0d1ch v0d1ch force-pushed the handle-transaction-building-using-blockfrost-api branch from 64da63c to e13dbf2 Compare March 24, 2025 07:43
@v0d1ch v0d1ch mentioned this pull request Mar 24, 2025
4 tasks
@v0d1ch v0d1ch changed the title Handle transaction building using blockfrost api The hydra node can publish hydra scripts via blockfrost using --blockfrost Mar 25, 2025
@v0d1ch v0d1ch force-pushed the handle-transaction-building-using-blockfrost-api branch from 6e05445 to 6d70b75 Compare March 25, 2025 08:51
@ch1bo
Copy link
Member

ch1bo commented Mar 25, 2025

Unfortunately I had to use a fork of the official library since I could not find a workaround for overlapping json instance https://github.com/blockfrost/blockfrost-haskell/blob/1a5360a51a1b61a14ffac4827f30c1ed525dedf3/blockfrost-api/src/Blockfrost/Types/Cardano/Pools.hs#L170

@v0d1ch What issue concretely did you encounter with the instance overlap? i.e. which of our instances would overlap with this one?

@v0d1ch
Copy link
Contributor Author

v0d1ch commented Mar 25, 2025

@ch1bo json instance for Message type https://github.com/cardano-scaling/hydra/blob/master/hydra-node/src/Hydra/Network/Message.hs#L48 specifically incrementUTxO field

@ch1bo
Copy link
Member

ch1bo commented Mar 25, 2025

@ch1bo json instance for Message type https://github.com/cardano-scaling/hydra/blob/master/hydra-node/src/Hydra/Network/Message.hs#L48 specifically incrementUTxO field

Okay. This works for me:

diff --git a/hydra-node/src/Hydra/Network/Message.hs b/hydra-node/src/Hydra/Network/Message.hs
index b7ea84b91d..14c4441a70 100644
--- a/hydra-node/src/Hydra/Network/Message.hs
+++ b/hydra-node/src/Hydra/Network/Message.hs
@@ -45,8 +45,8 @@ data Message tx
 
 deriving stock instance IsTx tx => Eq (Message tx)
 deriving stock instance IsTx tx => Show (Message tx)
-deriving anyclass instance IsTx tx => ToJSON (Message tx)
-deriving anyclass instance IsTx tx => FromJSON (Message tx)
+deriving anyclass instance {-# OVERLAPPABLE #-} IsTx tx => ToJSON (Message tx)
+deriving anyclass instance {-# OVERLAPPABLE #-} IsTx tx => FromJSON (Message tx)
 
 instance ArbitraryIsTx tx => Arbitrary (Message tx) where
   arbitrary = genericArbitrary

We should add an explanation though and ideally we would have more fine-grained constraints in the future as that would make it more clear that Maybe (UTxOType tx) is the issue here (it depends on how UTxoType tx is instantiated and as soon as one concrete Maybe Type is in scope this can overlap).

@v0d1ch
Copy link
Contributor Author

v0d1ch commented Mar 25, 2025

Hmm... I already tried using OVERLAPPABLE but it didn't do the trick. I'll report back when I get to it.

@v0d1ch
Copy link
Contributor Author

v0d1ch commented Mar 25, 2025

Yup, this is what I used to get too:

src/Hydra/Network/Message.hs:48:1: error: [GHC-43085]
    • Overlapping instances for ToJSON (Maybe (UTxOType tx))
        arising from a use of ‘aeson-2.2.3.0:Data.Aeson.Types.ToJSON.$dmtoJSON’
      Matching instance:
        instance ToJSON a => ToJSON (Maybe a)
          -- Defined in ‘aeson-2.2.3.0:Data.Aeson.Types.ToJSON’
        ...plus one instance involving out-of-scope types
          Potentially matching instance:
            instance [overlap ok] ToJSON
                                    (Maybe
                                       blockfrost-api-0.12.1.0:Blockfrost.Types.Cardano.Pools.PoolMetadata)
      (The choice depends on the instantiation of ‘tx’
       and the result of evaluating ‘UTxOType’
       To pick the first instance above, use IncoherentInstances
       when compiling the other instance declarations)
    • In the expression:
        aeson-2.2.3.0:Data.Aeson.Types.ToJSON.$dmtoJSON @(Message tx)
      In an equation for ‘toJSON’:
          toJSON
            = aeson-2.2.3.0:Data.Aeson.Types.ToJSON.$dmtoJSON @(Message tx)
      When typechecking the code for ‘toJSON’
        in a derived instance for ‘ToJSON (Message tx)’:
        To see the code I am typechecking, use -ddump-deriv
      In the instance declaration for ‘ToJSON (Message tx)’
   |
48 | deriving anyclass instance {-# OVERLAPPABLE #-} IsTx tx => ToJSON (Message tx)
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

src/Hydra/Network/Message.hs:49:1: error: [GHC-43085]
    • Overlapping instances for FromJSON (Maybe (UTxOType tx))
        arising from a use of ‘aeson-2.2.3.0:Data.Aeson.Types.FromJSON.$dmparseJSON’
      Matching instance:
        instance FromJSON a => FromJSON (Maybe a)
          -- Defined in ‘aeson-2.2.3.0:Data.Aeson.Types.FromJSON’
        ...plus one instance involving out-of-scope types
          Potentially matching instance:
            instance [overlap ok] FromJSON
                                    (Maybe
                                       blockfrost-api-0.12.1.0:Blockfrost.Types.Cardano.Pools.PoolMetadata)
      (The choice depends on the instantiation of ‘tx’
       and the result of evaluating ‘UTxOType’
       To pick the first instance above, use IncoherentInstances
       when compiling the other instance declarations)
    • In the expression:
        aeson-2.2.3.0:Data.Aeson.Types.FromJSON.$dmparseJSON @(Message tx)
      In an equation for ‘parseJSON’:
          parseJSON
            = aeson-2.2.3.0:Data.Aeson.Types.FromJSON.$dmparseJSON
                @(Message tx)
      When typechecking the code for ‘parseJSON’
        in a derived instance for ‘FromJSON (Message tx)’:
        To see the code I am typechecking, use -ddump-deriv
      In the instance declaration for ‘FromJSON (Message tx)’
   |
49 | deriving anyclass instance {-# OVERLAPPABLE #-} IsTx tx => FromJSON (Message tx)

@v0d1ch v0d1ch force-pushed the handle-transaction-building-using-blockfrost-api branch 2 times, most recently from 95a1748 to d59b491 Compare March 25, 2025 14:41
@v0d1ch v0d1ch linked an issue Mar 25, 2025 that may be closed by this pull request
2 tasks
@v0d1ch v0d1ch force-pushed the handle-transaction-building-using-blockfrost-api branch 4 times, most recently from f5b5a55 to 01f471d Compare April 1, 2025 08:43
@v0d1ch v0d1ch force-pushed the handle-transaction-building-using-blockfrost-api branch from 4ae3950 to 7551449 Compare April 1, 2025 11:00
Copy link
Contributor

@noonio noonio left a comment

Choose a reason for hiding this comment

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

Looks really great.

I think perhaps only thing missing would be an example in hte docs of using this?

@ch1bo
Copy link
Member

ch1bo commented Apr 1, 2025

Created an upstream PR to get rid of the overlapping instances: blockfrost/blockfrost-haskell#71

@v0d1ch v0d1ch force-pushed the handle-transaction-building-using-blockfrost-api branch 2 times, most recently from e5bfa0f to 86bbb99 Compare April 1, 2025 16:48
@v0d1ch v0d1ch requested review from ch1bo and noonio April 1, 2025 16:49
@v0d1ch v0d1ch force-pushed the handle-transaction-building-using-blockfrost-api branch 4 times, most recently from eea10e7 to f113fcd Compare April 2, 2025 07:52
@noonio noonio force-pushed the handle-transaction-building-using-blockfrost-api branch from f113fcd to f72ed9e Compare April 2, 2025 11:01
ffakenz and others added 18 commits April 2, 2025 16:53
Signed-off-by: Sasha Bogicevic <[email protected]>
Signed-off-by: Sasha Bogicevic <[email protected]>
We submit a tx and wait to see it returned from blockfrost. Then
we get the tx output utxo and use that for the next tx.

Signed-off-by: Sasha Bogicevic <[email protected]>
There is an json instance for (Maybe PoolMetadata) which
overlaps with our instances for Maybe types. This is a ugly
workaround but I couldn't find anything else that works.

Signed-off-by: Sasha Bogicevic <[email protected]>
Remove extra diff and pragma

Signed-off-by: Sasha Bogicevic <[email protected]>
Introduce a function to re-map from blockfrost to ledger GenesisParameters

Signed-off-by: Sasha Bogicevic <[email protected]>
- small refactor

Signed-off-by: Sasha Bogicevic <[email protected]>
Signed-off-by: Sasha Bogicevic <[email protected]>
@v0d1ch v0d1ch force-pushed the handle-transaction-building-using-blockfrost-api branch from ca750b0 to 348303b Compare April 2, 2025 14:53
Copy link
Member

@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.

I do approve of these changes, but please consider my suggestions

```shell
hydra-node publish-scripts \
--blockfrost /path/to/node.socket \
--cardano-signing-key cardano.sk
Copy link
Member

Choose a reason for hiding this comment

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

👍

@@ -436,6 +436,7 @@ spec = around (showLogsOnFailure "DirectChainSpec") $ do
)
""
let hydraScriptsTxId = fromString <$> splitWhen (== ',') (filter (/= '\n') hydraScriptsTxIdStr)
threadDelay 1
Copy link
Member

Choose a reason for hiding this comment

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

Should: not be needed

, serialise
, sop-extras
Copy link
Member

Choose a reason for hiding this comment

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

Should: not need these extra packages

I'm surprised that these are needed - where?

txs <- publishHydraScripts' networkId socketPath sk
pure $ getTxId . getTxBody <$> txs

publishHydraScripts' ::
Copy link
Member

Choose a reason for hiding this comment

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

Should: not need so many variants of similar functions

This one is definitely odd.. do we need it only because of awaitTransaction? If yes, creating an awaitTransactionId instead is preferable.

maybe mempty UTxO.singleton $
UTxO.find (\o -> selectLovelace (txOutValue o) > totalDeposit) utxo
in case buildTransactionWithPParams' pparams systemStart eraHistory stakePools changeAddress utxoToSpend [] output of
Left e -> error $ show e
Copy link
Member

Choose a reason for hiding this comment

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

Should: not use error

Make the overall function an Either and throw an exception in IO if you want, but not create partial functions according to our style guide

, hydraScriptsTxId = defaultDirectChainConfig.hydraScriptsTxId
, startChainFrom = defaultDirectChainConfig.startChainFrom
, contestationPeriod = defaultDirectChainConfig.contestationPeriod
, depositDeadline = defaultDirectChainConfig.depositDeadline
Copy link
Member

Choose a reason for hiding this comment

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

Should: avoid the repetition of all changes above here

why are these even changed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: In review 👀
4 participants