-
Notifications
You must be signed in to change notification settings - Fork 87
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
Keep ServerOutput type at the api boundary #1849
Conversation
df99bee
to
bc1bea1
Compare
Transaction cost differencesScript summary
|
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 | - | - | - | - |
2 | - | - | - | - |
3 | - | - | - | - |
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) | - | - | - | - | - |
4914fc7
to
47d9cf4
Compare
Signed-off-by: Sasha Bogicevic <[email protected]>
Signed-off-by: Sasha Bogicevic <[email protected]>
Signed-off-by: Sasha Bogicevic <[email protected]>
Signed-off-by: Sasha Bogicevic <[email protected]>
47d9cf4
to
d8f8b61
Compare
Transaction costsSizes and execution budgets for Hydra protocol transactions. Note that unlisted parameters are currently using
Script summary
|
Parties | Tx size | % max Mem | % max CPU | Min fee ₳ |
---|---|---|---|---|
1 | 6098 | 10.98 | 3.42 | 0.53 |
2 | 6294 | 13.47 | 4.19 | 0.57 |
3 | 6495 | 15.50 | 4.80 | 0.60 |
5 | 6897 | 20.25 | 6.27 | 0.66 |
10 | 7908 | 31.40 | 9.68 | 0.82 |
40 | 13935 | 98.57 | 30.28 | 1.78 |
Commit
transaction costs
This uses ada-only outputs for better comparability.
UTxO | Tx size | % max Mem | % max CPU | Min fee ₳ |
---|---|---|---|---|
1 | 558 | 2.44 | 1.16 | 0.20 |
2 | 740 | 3.38 | 1.73 | 0.22 |
3 | 915 | 4.36 | 2.33 | 0.24 |
5 | 1283 | 6.41 | 3.60 | 0.28 |
10 | 2176 | 12.13 | 7.25 | 0.40 |
54 | 10057 | 98.61 | 68.52 | 1.88 |
CollectCom
transaction costs
Parties | UTxO (bytes) | Tx size | % max Mem | % max CPU | Min fee ₳ |
---|---|---|---|---|---|
1 | 57 | 525 | 25.64 | 7.39 | 0.43 |
2 | 114 | 636 | 33.79 | 9.72 | 0.52 |
3 | 169 | 747 | 45.82 | 12.98 | 0.65 |
4 | 227 | 858 | 56.00 | 15.82 | 0.75 |
5 | 282 | 974 | 62.09 | 17.66 | 0.82 |
6 | 339 | 1081 | 71.77 | 20.48 | 0.93 |
7 | 395 | 1192 | 82.26 | 23.31 | 1.04 |
8 | 450 | 1303 | 97.80 | 27.32 | 1.19 |
9 | 505 | 1414 | 93.73 | 26.96 | 1.16 |
Cost of Increment Transaction
Parties | Tx size | % max Mem | % max CPU | Min fee ₳ |
---|---|---|---|---|
1 | 1821 | 25.03 | 8.23 | 0.49 |
2 | 1983 | 27.83 | 9.81 | 0.53 |
3 | 2017 | 27.24 | 10.17 | 0.53 |
5 | 2330 | 31.61 | 12.91 | 0.60 |
10 | 3152 | 43.28 | 20.03 | 0.78 |
38 | 7425 | 98.19 | 56.49 | 1.68 |
Cost of Decrement Transaction
Parties | Tx size | % max Mem | % max CPU | Min fee ₳ |
---|---|---|---|---|
1 | 636 | 23.99 | 7.62 | 0.43 |
2 | 733 | 24.85 | 8.49 | 0.44 |
3 | 879 | 26.90 | 9.76 | 0.48 |
5 | 1133 | 30.13 | 11.98 | 0.53 |
10 | 1981 | 41.17 | 18.32 | 0.70 |
37 | 5987 | 94.78 | 51.12 | 1.55 |
Close
transaction costs
Parties | Tx size | % max Mem | % max CPU | Min fee ₳ |
---|---|---|---|---|
1 | 681 | 29.19 | 9.21 | 0.48 |
2 | 866 | 31.60 | 10.72 | 0.52 |
3 | 925 | 34.74 | 12.17 | 0.56 |
5 | 1255 | 37.14 | 14.40 | 0.61 |
10 | 2135 | 51.75 | 22.50 | 0.82 |
32 | 5314 | 97.46 | 51.59 | 1.54 |
Contest
transaction costs
Parties | Tx size | % max Mem | % max CPU | Min fee ₳ |
---|---|---|---|---|
1 | 688 | 35.95 | 11.01 | 0.55 |
2 | 810 | 38.15 | 12.32 | 0.58 |
3 | 942 | 40.32 | 13.64 | 0.62 |
5 | 1245 | 45.25 | 16.54 | 0.69 |
10 | 2146 | 58.18 | 24.14 | 0.89 |
27 | 4628 | 98.98 | 48.19 | 1.50 |
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 | 5999 | 28.20 | 9.31 | 0.71 |
2 | 6090 | 37.31 | 12.30 | 0.81 |
3 | 6246 | 44.07 | 14.54 | 0.89 |
4 | 6320 | 50.05 | 16.46 | 0.95 |
5 | 6442 | 65.76 | 21.63 | 1.12 |
6 | 6700 | 79.13 | 26.20 | 1.27 |
7 | 6783 | 80.85 | 26.67 | 1.29 |
8 | 6962 | 93.38 | 30.77 | 1.43 |
9 | 6942 | 95.88 | 31.57 | 1.46 |
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 | 6092 | 20.12 | 6.62 | 0.63 |
10 | 1 | 57 | 6126 | 20.87 | 6.98 | 0.64 |
10 | 20 | 1136 | 6767 | 62.26 | 22.99 | 1.12 |
10 | 30 | 1705 | 7109 | 83.76 | 31.32 | 1.37 |
10 | 38 | 2164 | 7384 | 99.70 | 37.55 | 1.55 |
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-02-13 09:23:14.653382791 UTC
Baseline Scenario
Number of nodes | 1 |
---|---|
Number of txs | 300 |
Avg. Confirmation Time (ms) | 4.681026186 |
P99 | 10.323488329999988ms |
P95 | 5.8677638000000005ms |
P50 | 4.4834115ms |
Number of Invalid txs | 0 |
Memory data
Time | Used | Free |
---|---|---|
2025-02-13 09:21:50.410163168 UTC | 938M | 5894M |
2025-02-13 09:21:55.40995516 UTC | 1049M | 5688M |
2025-02-13 09:22:00.409972504 UTC | 1050M | 5686M |
2025-02-13 09:22:05.409970415 UTC | 1062M | 5674M |
2025-02-13 09:22:10.409954265 UTC | 1064M | 5672M |
2025-02-13 09:22:15.409909617 UTC | 1062M | 5673M |
Three local nodes
Number of nodes | 3 |
---|---|
Number of txs | 900 |
Avg. Confirmation Time (ms) | 25.465739552 |
P99 | 120.88882986ms |
P95 | 32.1110264ms |
P50 | 22.492632999999998ms |
Number of Invalid txs | 0 |
Memory data
Time | Used | Free |
---|---|---|
2025-02-13 09:22:27.788427608 UTC | 985M | 5762M |
2025-02-13 09:22:32.788570613 UTC | 1159M | 5588M |
2025-02-13 09:22:37.788516687 UTC | 1160M | 5586M |
2025-02-13 09:22:42.788473495 UTC | 1165M | 5580M |
2025-02-13 09:22:47.789641814 UTC | 1220M | 5457M |
2025-02-13 09:22:52.788583275 UTC | 1248M | 5347M |
2025-02-13 09:22:57.788572923 UTC | 1250M | 5343M |
2025-02-13 09:23:02.788577674 UTC | 1258M | 5336M |
2025-02-13 09:23:07.788476273 UTC | 1257M | 5336M |
2025-02-13 09:23:12.788455631 UTC | 1266M | 5327M |
4a3eac5
to
9a6f54a
Compare
import Test.QuickCheck (oneof) | ||
import Test.QuickCheck.Arbitrary.ADT (ToADTArbitrary) | ||
|
||
-- | Analogous to inputs, the pure head logic "core" can have effects emited to | ||
-- the "shell" layers and we distinguish the same: effects onto the client, the | ||
-- network and the chain. | ||
data Effect tx | ||
= -- | Effect to be handled by the "Hydra.API", results in sending this 'ServerOutput'. | ||
ClientEffect {serverOutput :: ServerOutput tx} | ||
= -- | Effect to be handled by the "Hydra.API", results in sending this 'StateChanged'. |
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 think this comment is outdated.
= -- | Effect to be handled by the "Hydra.API", results in sending this 'ServerOutput'. | ||
ClientEffect {serverOutput :: ServerOutput tx} | ||
= -- | Effect to be handled by the "Hydra.API", results in sending this 'StateChanged'. | ||
ClientEffect {serverOutput :: StateChanged 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.
The type and attribute names feel misleading to me.
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.
Would you call the field stateChanged
?
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.
@ffakenz is right. It's not only misleading, but IMO we should not even have this ClientEffect
anymore.
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.
or eventToPersist
| CommandFailed {clientInput :: ClientInput tx, state :: HeadState tx} | ||
| GetUTxOResponse {headId :: HeadId, utxo :: UTxOType tx} | ||
| InvalidInput {reason :: String, input :: Text} | ||
| Greetings |
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.
It feels misleading for these types to be considered StateChanged, as it seems to contradict this ADR.
IMO, a 1:1 mapping here isn’t feasible nor desirable, since ServerOutputs also represent responses from the node, not just state changes.
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 agree the situation is not ideal. What do you propose? I see this pr just as a small step forward separating ServerOutput
from the HeadLogic
code. Next steps should improve situation and if you have a specific plan in mind please share it so that we end up with much nicer code/types to deal with.
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.
to me there should be server outputs that are not part of state changes, even if that maintains some coupling.
in a next step i would think about how to deal with those (like CommandFailed/InvalidInput) but outputs like Greetings should definetly not be a StateChanged imo.
@@ -164,6 +234,9 @@ wait reason = Wait reason [] | |||
newState :: StateChanged tx -> Outcome tx | |||
newState change = Continue [change] [] | |||
|
|||
newStateWithEffect :: StateChanged tx -> Outcome tx | |||
newStateWithEffect change = Continue [change] [ClientEffect change] |
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 ServerOutputs are being decoupled from HeadLogic, perhaps we could introduce an EventSink that generates API outputs on demand.
Not sure if this is within the scope of this PR, but we might consider running a separate thread to handle projecting server outputs instead of embedding this loop in the node logic.
WDYT?
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.
StateChanged.PeerHandshakeFailure{remoteHost, ourVersion, theirVersions} -> | ||
Just $ | ||
PeerHandshakeFailure{remoteHost, ourVersion, theirVersions} | ||
StateChanged.HeadInitialized{headId, parties} -> Just $ HeadIsInitializing{headId, parties} |
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.
How do we feel abort RecordWildCards
?
At the minor cost of:
{-# LANGUAGE RecordWildCards #-}
this (and almost all the others) become:
StateChanged.HeadInitialized{..} -> Just $ HeadIsInitializing{..}
I kind of prefer it here, because all this destructuring is just noise.
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.
Our coding standards don't mention this extension and I am kinda loving/hating it since it sweeps some stuff under the carpet but is also handy. Here is how the diff looks, I could also change some field names to reduce the noise further 715f689
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 vote we use it here; I think it's not good to turn on globally, but I think this is one of those places where we just get a strict improvement.
And indeed, as you point out, it hints to inconsistencies that can be resolved as we see fit.
Signed-off-by: Sasha Bogicevic <[email protected]>
9a6f54a
to
0735022
Compare
Signed-off-by: Sasha Bogicevic <[email protected]>
Signed-off-by: Sasha Bogicevic <[email protected]>
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 not do this right now, and instead focus on #1618 changes themselves. We might realize that most of these changes are not needed.
= -- | Effect to be handled by the "Hydra.API", results in sending this 'ServerOutput'. | ||
ClientEffect {serverOutput :: ServerOutput tx} | ||
= -- | Effect to be handled by the "Hydra.API", results in sending this 'StateChanged'. | ||
ClientEffect {serverOutput :: StateChanged 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.
@ffakenz is right. It's not only misleading, but IMO we should not even have this ClientEffect
anymore.
deriving anyclass (ToJSON, FromJSON) | ||
|
||
instance Arbitrary HeadStatus where | ||
arbitrary = genericArbitrary |
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.
This should not need to be here. It's an API specific type and not relevant for the HeadLogic
at all.
{ time | ||
, seq | ||
, output = greetings | ||
} |
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.
Why is this not just producing the Greetings
message as before?
Consequently, there should not be a Greetings :: StateChanged
ServerOutput
type out ofHeadLogic
that now deals only withStateChanged
type. There is a mapping fromStateChanged -> ServerOutput
now so that we can output state events from Head logic but deal only withServerOutput
on the api boundary.