Initial commit
This commit is contained in:
commit
c76e19b502
15
README.md
Normal file
15
README.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# <p align="center">Hydra Head Demo, Reflex-DOM edition</p>
|
||||||
|
|
||||||
|
This is an extended, graphical re-implementation of the original [Hydra Heads demo](https://github.com/input-output-hk/hydra-poc/tree/master/demo) implemented with [Reflex FRP](https://reflex-frp.org/).
|
||||||
|
It allows starting and closing a head with an arbitrary number of nodes, each with some initial amount of Ada to perform transactions within the head.
|
||||||
|
|
||||||
|
# Running
|
||||||
|
|
||||||
|
To run the demo enter a Nix shell and run it with `cabal`:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ nix-shell -A shells.ghc default.nix
|
||||||
|
$ cabal run
|
||||||
|
```
|
||||||
|
|
||||||
|
The demo can then be viewed in Chrome at `http://localhost:3003/`.
|
37
default.nix
Normal file
37
default.nix
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# default.nix
|
||||||
|
{ system ? builtins.currentSystem }:
|
||||||
|
let
|
||||||
|
nix-thunk = import ./dep/nix-thunk { };
|
||||||
|
sources = nix-thunk.mapSubdirectories nix-thunk.thunkSource ./dep;
|
||||||
|
reflex-platform = import sources.reflex-platform { inherit system; };
|
||||||
|
hydra-poc = import sources.hydra-poc { };
|
||||||
|
in reflex-platform.project ({ pkgs, ... }:
|
||||||
|
let haskellLib = pkgs.haskell.lib;
|
||||||
|
in {
|
||||||
|
packages = { hydra-head-demo = ./.; };
|
||||||
|
|
||||||
|
shellToolOverrides = ghc: super: {
|
||||||
|
};
|
||||||
|
|
||||||
|
overrides = self: super: {
|
||||||
|
hydra-head-demo = haskellLib.overrideCabal super.hydra-head-demo (drv: {
|
||||||
|
librarySystemDepends = (drv.librarySystemDepends or [ ]) ++ [
|
||||||
|
hydra-poc.cardano-node.cardano-node
|
||||||
|
hydra-poc.cardano-node.cardano-cli
|
||||||
|
hydra-poc.hsPkgs.hydra-node.components.exes.hydra-node
|
||||||
|
hydra-poc.hsPkgs.hydra-node.components.exes.hydra-tools
|
||||||
|
pkgs.jq
|
||||||
|
pkgs.coreutils
|
||||||
|
];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useWarp = true;
|
||||||
|
|
||||||
|
withHoogle = true;
|
||||||
|
|
||||||
|
shells = {
|
||||||
|
ghc = [ "hydra-head-demo" ];
|
||||||
|
ghcjs = [ ];
|
||||||
|
};
|
||||||
|
})
|
203
demo/LICENSE
Normal file
203
demo/LICENSE
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
[Original license of https://github.com/input-output-hk/hydra-poc below.]
|
||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [2021-2022] [IOG]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
5
demo/credentials/faucet.sk
Normal file
5
demo/credentials/faucet.sk
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"type": "PaymentSigningKeyShelley_ed25519",
|
||||||
|
"description": "Payment Signing Key",
|
||||||
|
"cborHex": "5820a5e4238b67ebb1108c52a01ac850bbce82c915d77bad94331892f3edf612883c"
|
||||||
|
}
|
5
demo/credentials/faucet.vk
Normal file
5
demo/credentials/faucet.vk
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"type": "PaymentVerificationKeyShelley_ed25519",
|
||||||
|
"description": "Payment Verification Key",
|
||||||
|
"cborHex": "5820ce13cd433cdcb3dfb00c04e216956aeb622dcd7f282b03304d9fc9de804723b2"
|
||||||
|
}
|
BIN
demo/devnet/byron-delegate.key
Normal file
BIN
demo/devnet/byron-delegate.key
Normal file
Binary file not shown.
8
demo/devnet/byron-delegation.cert
Normal file
8
demo/devnet/byron-delegation.cert
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{ "omega": 0
|
||||||
|
, "issuerPk":
|
||||||
|
"NclXQiNNEpaaLdSxP3VFeOPIfSuFqBcNtmv8/7fftBKtgW1Aig7UqHJ/czsywkWFFVmBYPRnGjXspUl3wEMvuQ=="
|
||||||
|
, "delegatePk":
|
||||||
|
"24ejRK+kCDs1g4f3PcodFEUFVgNFWtfmuoEtVQf8/Ii2j2ruXHebJmZZPrwtAdbJYwDiSEvsHr95+BAF1ifGsA=="
|
||||||
|
, "cert":
|
||||||
|
"498c72e35ef30cd4657b48bfcc0a84a555a67981e3b6104a0d1708ab84510367d81e1ba3f47619565b1ee1098e31dcb8eb648d8030e061b568de113fdf3d6a09"
|
||||||
|
}
|
79
demo/devnet/cardano-node.json
Normal file
79
demo/devnet/cardano-node.json
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
{
|
||||||
|
"Protocol": "Cardano",
|
||||||
|
|
||||||
|
"ByronGenesisFile": "genesis-byron.json",
|
||||||
|
"ShelleyGenesisFile": "genesis-shelley.json",
|
||||||
|
"AlonzoGenesisFile": "genesis-alonzo.json",
|
||||||
|
|
||||||
|
"ApplicationName": "cardano-sl",
|
||||||
|
"ApplicationVersion": 1,
|
||||||
|
"MaxKnownMajorProtocolVersion": 2,
|
||||||
|
"LastKnownBlockVersion-Alt": 0,
|
||||||
|
"LastKnownBlockVersion-Major": 6,
|
||||||
|
"LastKnownBlockVersion-Minor": 0,
|
||||||
|
|
||||||
|
"TestShelleyHardForkAtEpoch": 0,
|
||||||
|
"TestAllegraHardForkAtEpoch": 0,
|
||||||
|
"TestMaryHardForkAtEpoch": 0,
|
||||||
|
"TestAlonzoHardForkAtEpoch": 0,
|
||||||
|
"TestBabbageHardForkAtEpoch": 0,
|
||||||
|
|
||||||
|
"RequiresNetworkMagic": "RequiresNoMagic",
|
||||||
|
|
||||||
|
"minSeverity": "Info",
|
||||||
|
"defaultBackends": ["KatipBK"],
|
||||||
|
"defaultScribes": [[ "StdoutSK", "stdout" ]],
|
||||||
|
"setupBackends": ["KatipBK"],
|
||||||
|
"setupScribes": [
|
||||||
|
{
|
||||||
|
"scFormat": "ScJson",
|
||||||
|
"scKind": "StdoutSK",
|
||||||
|
"scName": "stdout",
|
||||||
|
"scRotation": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"TurnOnLogMetrics": true,
|
||||||
|
"TurnOnLogging": true,
|
||||||
|
|
||||||
|
"TracingVerbosity": "NormalVerbosity",
|
||||||
|
"TraceBlockFetchClient": false,
|
||||||
|
"TraceBlockFetchDecisions": false,
|
||||||
|
"TraceBlockFetchProtocol": false,
|
||||||
|
"TraceBlockFetchProtocolSerialised": false,
|
||||||
|
"TraceBlockFetchServer": false,
|
||||||
|
"TraceChainDb": true,
|
||||||
|
"TraceChainSyncBlockServer": false,
|
||||||
|
"TraceChainSyncClient": false,
|
||||||
|
"TraceChainSyncHeaderServer": false,
|
||||||
|
"TraceChainSyncProtocol": false,
|
||||||
|
"TraceDNSResolver": false,
|
||||||
|
"TraceDNSSubscription": false,
|
||||||
|
"TraceErrorPolicy": false,
|
||||||
|
"TraceForge": true,
|
||||||
|
"TraceHandshake": false,
|
||||||
|
"TraceIpSubscription": false,
|
||||||
|
"TraceLocalChainSyncProtocol": true,
|
||||||
|
"TraceLocalErrorPolicy": false,
|
||||||
|
"TraceLocalHandshake": false,
|
||||||
|
"TraceLocalTxSubmissionProtocol": true,
|
||||||
|
"TraceLocalTxSubmissionServer": true,
|
||||||
|
"TraceMempool": true,
|
||||||
|
"TraceMux": false,
|
||||||
|
"TraceTxInbound": false,
|
||||||
|
"TraceTxOutbound": false,
|
||||||
|
"TraceTxSubmissionProtocol": false,
|
||||||
|
|
||||||
|
"options": {
|
||||||
|
"mapBackends": {
|
||||||
|
"cardano.node.metrics": [ "EKGViewBK" ],
|
||||||
|
"cardano.node.resources": [ "EKGViewBK" ]
|
||||||
|
},
|
||||||
|
"mapSubtrace": {
|
||||||
|
"cardano.node.metrics": { "subtrace": "Neutral" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"TestEnableDevelopmentHardForkEras": true,
|
||||||
|
"TestEnableDevelopmentNetworkProtocols": true
|
||||||
|
}
|
365
demo/devnet/genesis-alonzo.json
Normal file
365
demo/devnet/genesis-alonzo.json
Normal file
@ -0,0 +1,365 @@
|
|||||||
|
{
|
||||||
|
"collateralPercentage": 150,
|
||||||
|
"costModels": {
|
||||||
|
"PlutusV1": {
|
||||||
|
"addInteger-cpu-arguments-intercept": 197209,
|
||||||
|
"addInteger-cpu-arguments-slope": 0,
|
||||||
|
"addInteger-memory-arguments-intercept": 1,
|
||||||
|
"addInteger-memory-arguments-slope": 1,
|
||||||
|
"appendByteString-cpu-arguments-intercept": 396231,
|
||||||
|
"appendByteString-cpu-arguments-slope": 621,
|
||||||
|
"appendByteString-memory-arguments-intercept": 0,
|
||||||
|
"appendByteString-memory-arguments-slope": 1,
|
||||||
|
"appendString-cpu-arguments-intercept": 150000,
|
||||||
|
"appendString-cpu-arguments-slope": 1000,
|
||||||
|
"appendString-memory-arguments-intercept": 0,
|
||||||
|
"appendString-memory-arguments-slope": 1,
|
||||||
|
"bData-cpu-arguments": 150000,
|
||||||
|
"bData-memory-arguments": 32,
|
||||||
|
"blake2b_256-cpu-arguments-intercept": 2477736,
|
||||||
|
"blake2b_256-cpu-arguments-slope": 29175,
|
||||||
|
"blake2b_256-memory-arguments": 4,
|
||||||
|
"cekApplyCost-exBudgetCPU": 29773,
|
||||||
|
"cekApplyCost-exBudgetMemory": 100,
|
||||||
|
"cekBuiltinCost-exBudgetCPU": 29773,
|
||||||
|
"cekBuiltinCost-exBudgetMemory": 100,
|
||||||
|
"cekConstCost-exBudgetCPU": 29773,
|
||||||
|
"cekConstCost-exBudgetMemory": 100,
|
||||||
|
"cekDelayCost-exBudgetCPU": 29773,
|
||||||
|
"cekDelayCost-exBudgetMemory": 100,
|
||||||
|
"cekForceCost-exBudgetCPU": 29773,
|
||||||
|
"cekForceCost-exBudgetMemory": 100,
|
||||||
|
"cekLamCost-exBudgetCPU": 29773,
|
||||||
|
"cekLamCost-exBudgetMemory": 100,
|
||||||
|
"cekStartupCost-exBudgetCPU": 100,
|
||||||
|
"cekStartupCost-exBudgetMemory": 100,
|
||||||
|
"cekVarCost-exBudgetCPU": 29773,
|
||||||
|
"cekVarCost-exBudgetMemory": 100,
|
||||||
|
"chooseData-cpu-arguments": 150000,
|
||||||
|
"chooseData-memory-arguments": 32,
|
||||||
|
"chooseList-cpu-arguments": 150000,
|
||||||
|
"chooseList-memory-arguments": 32,
|
||||||
|
"chooseUnit-cpu-arguments": 150000,
|
||||||
|
"chooseUnit-memory-arguments": 32,
|
||||||
|
"consByteString-cpu-arguments-intercept": 150000,
|
||||||
|
"consByteString-cpu-arguments-slope": 1000,
|
||||||
|
"consByteString-memory-arguments-intercept": 0,
|
||||||
|
"consByteString-memory-arguments-slope": 1,
|
||||||
|
"constrData-cpu-arguments": 150000,
|
||||||
|
"constrData-memory-arguments": 32,
|
||||||
|
"decodeUtf8-cpu-arguments-intercept": 150000,
|
||||||
|
"decodeUtf8-cpu-arguments-slope": 1000,
|
||||||
|
"decodeUtf8-memory-arguments-intercept": 0,
|
||||||
|
"decodeUtf8-memory-arguments-slope": 8,
|
||||||
|
"divideInteger-cpu-arguments-constant": 148000,
|
||||||
|
"divideInteger-cpu-arguments-model-arguments-intercept": 425507,
|
||||||
|
"divideInteger-cpu-arguments-model-arguments-slope": 118,
|
||||||
|
"divideInteger-memory-arguments-intercept": 0,
|
||||||
|
"divideInteger-memory-arguments-minimum": 1,
|
||||||
|
"divideInteger-memory-arguments-slope": 1,
|
||||||
|
"encodeUtf8-cpu-arguments-intercept": 150000,
|
||||||
|
"encodeUtf8-cpu-arguments-slope": 1000,
|
||||||
|
"encodeUtf8-memory-arguments-intercept": 0,
|
||||||
|
"encodeUtf8-memory-arguments-slope": 8,
|
||||||
|
"equalsByteString-cpu-arguments-constant": 150000,
|
||||||
|
"equalsByteString-cpu-arguments-intercept": 112536,
|
||||||
|
"equalsByteString-cpu-arguments-slope": 247,
|
||||||
|
"equalsByteString-memory-arguments": 1,
|
||||||
|
"equalsData-cpu-arguments-intercept": 150000,
|
||||||
|
"equalsData-cpu-arguments-slope": 10000,
|
||||||
|
"equalsData-memory-arguments": 1,
|
||||||
|
"equalsInteger-cpu-arguments-intercept": 136542,
|
||||||
|
"equalsInteger-cpu-arguments-slope": 1326,
|
||||||
|
"equalsInteger-memory-arguments": 1,
|
||||||
|
"equalsString-cpu-arguments-constant": 1000,
|
||||||
|
"equalsString-cpu-arguments-intercept": 150000,
|
||||||
|
"equalsString-cpu-arguments-slope": 1000,
|
||||||
|
"equalsString-memory-arguments": 1,
|
||||||
|
"fstPair-cpu-arguments": 150000,
|
||||||
|
"fstPair-memory-arguments": 32,
|
||||||
|
"headList-cpu-arguments": 150000,
|
||||||
|
"headList-memory-arguments": 32,
|
||||||
|
"iData-cpu-arguments": 150000,
|
||||||
|
"iData-memory-arguments": 32,
|
||||||
|
"ifThenElse-cpu-arguments": 1,
|
||||||
|
"ifThenElse-memory-arguments": 1,
|
||||||
|
"indexByteString-cpu-arguments": 150000,
|
||||||
|
"indexByteString-memory-arguments": 1,
|
||||||
|
"lengthOfByteString-cpu-arguments": 150000,
|
||||||
|
"lengthOfByteString-memory-arguments": 4,
|
||||||
|
"lessThanByteString-cpu-arguments-intercept": 103599,
|
||||||
|
"lessThanByteString-cpu-arguments-slope": 248,
|
||||||
|
"lessThanByteString-memory-arguments": 1,
|
||||||
|
"lessThanEqualsByteString-cpu-arguments-intercept": 103599,
|
||||||
|
"lessThanEqualsByteString-cpu-arguments-slope": 248,
|
||||||
|
"lessThanEqualsByteString-memory-arguments": 1,
|
||||||
|
"lessThanEqualsInteger-cpu-arguments-intercept": 145276,
|
||||||
|
"lessThanEqualsInteger-cpu-arguments-slope": 1366,
|
||||||
|
"lessThanEqualsInteger-memory-arguments": 1,
|
||||||
|
"lessThanInteger-cpu-arguments-intercept": 179690,
|
||||||
|
"lessThanInteger-cpu-arguments-slope": 497,
|
||||||
|
"lessThanInteger-memory-arguments": 1,
|
||||||
|
"listData-cpu-arguments": 150000,
|
||||||
|
"listData-memory-arguments": 32,
|
||||||
|
"mapData-cpu-arguments": 150000,
|
||||||
|
"mapData-memory-arguments": 32,
|
||||||
|
"mkCons-cpu-arguments": 150000,
|
||||||
|
"mkCons-memory-arguments": 32,
|
||||||
|
"mkNilData-cpu-arguments": 150000,
|
||||||
|
"mkNilData-memory-arguments": 32,
|
||||||
|
"mkNilPairData-cpu-arguments": 150000,
|
||||||
|
"mkNilPairData-memory-arguments": 32,
|
||||||
|
"mkPairData-cpu-arguments": 150000,
|
||||||
|
"mkPairData-memory-arguments": 32,
|
||||||
|
"modInteger-cpu-arguments-constant": 148000,
|
||||||
|
"modInteger-cpu-arguments-model-arguments-intercept": 425507,
|
||||||
|
"modInteger-cpu-arguments-model-arguments-slope": 118,
|
||||||
|
"modInteger-memory-arguments-intercept": 0,
|
||||||
|
"modInteger-memory-arguments-minimum": 1,
|
||||||
|
"modInteger-memory-arguments-slope": 1,
|
||||||
|
"multiplyInteger-cpu-arguments-intercept": 61516,
|
||||||
|
"multiplyInteger-cpu-arguments-slope": 11218,
|
||||||
|
"multiplyInteger-memory-arguments-intercept": 0,
|
||||||
|
"multiplyInteger-memory-arguments-slope": 1,
|
||||||
|
"nullList-cpu-arguments": 150000,
|
||||||
|
"nullList-memory-arguments": 32,
|
||||||
|
"quotientInteger-cpu-arguments-constant": 148000,
|
||||||
|
"quotientInteger-cpu-arguments-model-arguments-intercept": 425507,
|
||||||
|
"quotientInteger-cpu-arguments-model-arguments-slope": 118,
|
||||||
|
"quotientInteger-memory-arguments-intercept": 0,
|
||||||
|
"quotientInteger-memory-arguments-minimum": 1,
|
||||||
|
"quotientInteger-memory-arguments-slope": 1,
|
||||||
|
"remainderInteger-cpu-arguments-constant": 148000,
|
||||||
|
"remainderInteger-cpu-arguments-model-arguments-intercept": 425507,
|
||||||
|
"remainderInteger-cpu-arguments-model-arguments-slope": 118,
|
||||||
|
"remainderInteger-memory-arguments-intercept": 0,
|
||||||
|
"remainderInteger-memory-arguments-minimum": 1,
|
||||||
|
"remainderInteger-memory-arguments-slope": 1,
|
||||||
|
"sha2_256-cpu-arguments-intercept": 2477736,
|
||||||
|
"sha2_256-cpu-arguments-slope": 29175,
|
||||||
|
"sha2_256-memory-arguments": 4,
|
||||||
|
"sha3_256-cpu-arguments-intercept": 0,
|
||||||
|
"sha3_256-cpu-arguments-slope": 82363,
|
||||||
|
"sha3_256-memory-arguments": 4,
|
||||||
|
"sliceByteString-cpu-arguments-intercept": 150000,
|
||||||
|
"sliceByteString-cpu-arguments-slope": 5000,
|
||||||
|
"sliceByteString-memory-arguments-intercept": 0,
|
||||||
|
"sliceByteString-memory-arguments-slope": 1,
|
||||||
|
"sndPair-cpu-arguments": 150000,
|
||||||
|
"sndPair-memory-arguments": 32,
|
||||||
|
"subtractInteger-cpu-arguments-intercept": 197209,
|
||||||
|
"subtractInteger-cpu-arguments-slope": 0,
|
||||||
|
"subtractInteger-memory-arguments-intercept": 1,
|
||||||
|
"subtractInteger-memory-arguments-slope": 1,
|
||||||
|
"tailList-cpu-arguments": 150000,
|
||||||
|
"tailList-memory-arguments": 32,
|
||||||
|
"trace-cpu-arguments": 150000,
|
||||||
|
"trace-memory-arguments": 32,
|
||||||
|
"unBData-cpu-arguments": 150000,
|
||||||
|
"unBData-memory-arguments": 32,
|
||||||
|
"unConstrData-cpu-arguments": 150000,
|
||||||
|
"unConstrData-memory-arguments": 32,
|
||||||
|
"unIData-cpu-arguments": 150000,
|
||||||
|
"unIData-memory-arguments": 32,
|
||||||
|
"unListData-cpu-arguments": 150000,
|
||||||
|
"unListData-memory-arguments": 32,
|
||||||
|
"unMapData-cpu-arguments": 150000,
|
||||||
|
"unMapData-memory-arguments": 32,
|
||||||
|
"verifyEd25519Signature-cpu-arguments-intercept": 3345831,
|
||||||
|
"verifyEd25519Signature-cpu-arguments-slope": 1,
|
||||||
|
"verifyEd25519Signature-memory-arguments": 1
|
||||||
|
},
|
||||||
|
"PlutusV2": {
|
||||||
|
"addInteger-cpu-arguments-intercept": 205665,
|
||||||
|
"addInteger-cpu-arguments-slope": 812,
|
||||||
|
"addInteger-memory-arguments-intercept": 1,
|
||||||
|
"addInteger-memory-arguments-slope": 1,
|
||||||
|
"appendByteString-cpu-arguments-intercept": 1000,
|
||||||
|
"appendByteString-cpu-arguments-slope": 571,
|
||||||
|
"appendByteString-memory-arguments-intercept": 0,
|
||||||
|
"appendByteString-memory-arguments-slope": 1,
|
||||||
|
"appendString-cpu-arguments-intercept": 1000,
|
||||||
|
"appendString-cpu-arguments-slope": 24177,
|
||||||
|
"appendString-memory-arguments-intercept": 4,
|
||||||
|
"appendString-memory-arguments-slope": 1,
|
||||||
|
"bData-cpu-arguments": 1000,
|
||||||
|
"bData-memory-arguments": 32,
|
||||||
|
"blake2b_256-cpu-arguments-intercept": 117366,
|
||||||
|
"blake2b_256-cpu-arguments-slope": 10475,
|
||||||
|
"blake2b_256-memory-arguments": 4,
|
||||||
|
"cekApplyCost-exBudgetCPU": 23000,
|
||||||
|
"cekApplyCost-exBudgetMemory": 100,
|
||||||
|
"cekBuiltinCost-exBudgetCPU": 23000,
|
||||||
|
"cekBuiltinCost-exBudgetMemory": 100,
|
||||||
|
"cekConstCost-exBudgetCPU": 23000,
|
||||||
|
"cekConstCost-exBudgetMemory": 100,
|
||||||
|
"cekDelayCost-exBudgetCPU": 23000,
|
||||||
|
"cekDelayCost-exBudgetMemory": 100,
|
||||||
|
"cekForceCost-exBudgetCPU": 23000,
|
||||||
|
"cekForceCost-exBudgetMemory": 100,
|
||||||
|
"cekLamCost-exBudgetCPU": 23000,
|
||||||
|
"cekLamCost-exBudgetMemory": 100,
|
||||||
|
"cekStartupCost-exBudgetCPU": 100,
|
||||||
|
"cekStartupCost-exBudgetMemory": 100,
|
||||||
|
"cekVarCost-exBudgetCPU": 23000,
|
||||||
|
"cekVarCost-exBudgetMemory": 100,
|
||||||
|
"chooseData-cpu-arguments": 19537,
|
||||||
|
"chooseData-memory-arguments": 32,
|
||||||
|
"chooseList-cpu-arguments": 175354,
|
||||||
|
"chooseList-memory-arguments": 32,
|
||||||
|
"chooseUnit-cpu-arguments": 46417,
|
||||||
|
"chooseUnit-memory-arguments": 4,
|
||||||
|
"consByteString-cpu-arguments-intercept": 221973,
|
||||||
|
"consByteString-cpu-arguments-slope": 511,
|
||||||
|
"consByteString-memory-arguments-intercept": 0,
|
||||||
|
"consByteString-memory-arguments-slope": 1,
|
||||||
|
"constrData-cpu-arguments": 89141,
|
||||||
|
"constrData-memory-arguments": 32,
|
||||||
|
"decodeUtf8-cpu-arguments-intercept": 497525,
|
||||||
|
"decodeUtf8-cpu-arguments-slope": 14068,
|
||||||
|
"decodeUtf8-memory-arguments-intercept": 4,
|
||||||
|
"decodeUtf8-memory-arguments-slope": 2,
|
||||||
|
"divideInteger-cpu-arguments-constant": 196500,
|
||||||
|
"divideInteger-cpu-arguments-model-arguments-intercept": 453240,
|
||||||
|
"divideInteger-cpu-arguments-model-arguments-slope": 220,
|
||||||
|
"divideInteger-memory-arguments-intercept": 0,
|
||||||
|
"divideInteger-memory-arguments-minimum": 1,
|
||||||
|
"divideInteger-memory-arguments-slope": 1,
|
||||||
|
"encodeUtf8-cpu-arguments-intercept": 1000,
|
||||||
|
"encodeUtf8-cpu-arguments-slope": 28662,
|
||||||
|
"encodeUtf8-memory-arguments-intercept": 4,
|
||||||
|
"encodeUtf8-memory-arguments-slope": 2,
|
||||||
|
"equalsByteString-cpu-arguments-constant": 245000,
|
||||||
|
"equalsByteString-cpu-arguments-intercept": 216773,
|
||||||
|
"equalsByteString-cpu-arguments-slope": 62,
|
||||||
|
"equalsByteString-memory-arguments": 1,
|
||||||
|
"equalsData-cpu-arguments-intercept": 1060367,
|
||||||
|
"equalsData-cpu-arguments-slope": 12586,
|
||||||
|
"equalsData-memory-arguments": 1,
|
||||||
|
"equalsInteger-cpu-arguments-intercept": 208512,
|
||||||
|
"equalsInteger-cpu-arguments-slope": 421,
|
||||||
|
"equalsInteger-memory-arguments": 1,
|
||||||
|
"equalsString-cpu-arguments-constant": 187000,
|
||||||
|
"equalsString-cpu-arguments-intercept": 1000,
|
||||||
|
"equalsString-cpu-arguments-slope": 52998,
|
||||||
|
"equalsString-memory-arguments": 1,
|
||||||
|
"fstPair-cpu-arguments": 80436,
|
||||||
|
"fstPair-memory-arguments": 32,
|
||||||
|
"headList-cpu-arguments": 43249,
|
||||||
|
"headList-memory-arguments": 32,
|
||||||
|
"iData-cpu-arguments": 1000,
|
||||||
|
"iData-memory-arguments": 32,
|
||||||
|
"ifThenElse-cpu-arguments": 80556,
|
||||||
|
"ifThenElse-memory-arguments": 1,
|
||||||
|
"indexByteString-cpu-arguments": 57667,
|
||||||
|
"indexByteString-memory-arguments": 4,
|
||||||
|
"lengthOfByteString-cpu-arguments": 1000,
|
||||||
|
"lengthOfByteString-memory-arguments": 10,
|
||||||
|
"lessThanByteString-cpu-arguments-intercept": 197145,
|
||||||
|
"lessThanByteString-cpu-arguments-slope": 156,
|
||||||
|
"lessThanByteString-memory-arguments": 1,
|
||||||
|
"lessThanEqualsByteString-cpu-arguments-intercept": 197145,
|
||||||
|
"lessThanEqualsByteString-cpu-arguments-slope": 156,
|
||||||
|
"lessThanEqualsByteString-memory-arguments": 1,
|
||||||
|
"lessThanEqualsInteger-cpu-arguments-intercept": 204924,
|
||||||
|
"lessThanEqualsInteger-cpu-arguments-slope": 473,
|
||||||
|
"lessThanEqualsInteger-memory-arguments": 1,
|
||||||
|
"lessThanInteger-cpu-arguments-intercept": 208896,
|
||||||
|
"lessThanInteger-cpu-arguments-slope": 511,
|
||||||
|
"lessThanInteger-memory-arguments": 1,
|
||||||
|
"listData-cpu-arguments": 52467,
|
||||||
|
"listData-memory-arguments": 32,
|
||||||
|
"mapData-cpu-arguments": 64832,
|
||||||
|
"mapData-memory-arguments": 32,
|
||||||
|
"mkCons-cpu-arguments": 65493,
|
||||||
|
"mkCons-memory-arguments": 32,
|
||||||
|
"mkNilData-cpu-arguments": 22558,
|
||||||
|
"mkNilData-memory-arguments": 32,
|
||||||
|
"mkNilPairData-cpu-arguments": 16563,
|
||||||
|
"mkNilPairData-memory-arguments": 32,
|
||||||
|
"mkPairData-cpu-arguments": 76511,
|
||||||
|
"mkPairData-memory-arguments": 32,
|
||||||
|
"modInteger-cpu-arguments-constant": 196500,
|
||||||
|
"modInteger-cpu-arguments-model-arguments-intercept": 453240,
|
||||||
|
"modInteger-cpu-arguments-model-arguments-slope": 220,
|
||||||
|
"modInteger-memory-arguments-intercept": 0,
|
||||||
|
"modInteger-memory-arguments-minimum": 1,
|
||||||
|
"modInteger-memory-arguments-slope": 1,
|
||||||
|
"multiplyInteger-cpu-arguments-intercept": 69522,
|
||||||
|
"multiplyInteger-cpu-arguments-slope": 11687,
|
||||||
|
"multiplyInteger-memory-arguments-intercept": 0,
|
||||||
|
"multiplyInteger-memory-arguments-slope": 1,
|
||||||
|
"nullList-cpu-arguments": 60091,
|
||||||
|
"nullList-memory-arguments": 32,
|
||||||
|
"quotientInteger-cpu-arguments-constant": 196500,
|
||||||
|
"quotientInteger-cpu-arguments-model-arguments-intercept": 453240,
|
||||||
|
"quotientInteger-cpu-arguments-model-arguments-slope": 220,
|
||||||
|
"quotientInteger-memory-arguments-intercept": 0,
|
||||||
|
"quotientInteger-memory-arguments-minimum": 1,
|
||||||
|
"quotientInteger-memory-arguments-slope": 1,
|
||||||
|
"remainderInteger-cpu-arguments-constant": 196500,
|
||||||
|
"remainderInteger-cpu-arguments-model-arguments-intercept": 453240,
|
||||||
|
"remainderInteger-cpu-arguments-model-arguments-slope": 220,
|
||||||
|
"remainderInteger-memory-arguments-intercept": 0,
|
||||||
|
"remainderInteger-memory-arguments-minimum": 1,
|
||||||
|
"remainderInteger-memory-arguments-slope": 1,
|
||||||
|
"serialiseData-cpu-arguments-intercept": 1159724,
|
||||||
|
"serialiseData-cpu-arguments-slope": 392670,
|
||||||
|
"serialiseData-memory-arguments-intercept": 0,
|
||||||
|
"serialiseData-memory-arguments-slope": 2,
|
||||||
|
"sha2_256-cpu-arguments-intercept": 806990,
|
||||||
|
"sha2_256-cpu-arguments-slope": 30482,
|
||||||
|
"sha2_256-memory-arguments": 4,
|
||||||
|
"sha3_256-cpu-arguments-intercept": 1927926,
|
||||||
|
"sha3_256-cpu-arguments-slope": 82523,
|
||||||
|
"sha3_256-memory-arguments": 4,
|
||||||
|
"sliceByteString-cpu-arguments-intercept": 265318,
|
||||||
|
"sliceByteString-cpu-arguments-slope": 0,
|
||||||
|
"sliceByteString-memory-arguments-intercept": 4,
|
||||||
|
"sliceByteString-memory-arguments-slope": 0,
|
||||||
|
"sndPair-cpu-arguments": 85931,
|
||||||
|
"sndPair-memory-arguments": 32,
|
||||||
|
"subtractInteger-cpu-arguments-intercept": 205665,
|
||||||
|
"subtractInteger-cpu-arguments-slope": 812,
|
||||||
|
"subtractInteger-memory-arguments-intercept": 1,
|
||||||
|
"subtractInteger-memory-arguments-slope": 1,
|
||||||
|
"tailList-cpu-arguments": 41182,
|
||||||
|
"tailList-memory-arguments": 32,
|
||||||
|
"trace-cpu-arguments": 212342,
|
||||||
|
"trace-memory-arguments": 32,
|
||||||
|
"unBData-cpu-arguments": 31220,
|
||||||
|
"unBData-memory-arguments": 32,
|
||||||
|
"unConstrData-cpu-arguments": 32696,
|
||||||
|
"unConstrData-memory-arguments": 32,
|
||||||
|
"unIData-cpu-arguments": 43357,
|
||||||
|
"unIData-memory-arguments": 32,
|
||||||
|
"unListData-cpu-arguments": 32247,
|
||||||
|
"unListData-memory-arguments": 32,
|
||||||
|
"unMapData-cpu-arguments": 38314,
|
||||||
|
"unMapData-memory-arguments": 32,
|
||||||
|
"verifyEcdsaSecp256k1Signature-cpu-arguments": 35892428,
|
||||||
|
"verifyEcdsaSecp256k1Signature-memory-arguments": 10,
|
||||||
|
"verifyEd25519Signature-cpu-arguments-intercept": 9462713,
|
||||||
|
"verifyEd25519Signature-cpu-arguments-slope": 1021,
|
||||||
|
"verifyEd25519Signature-memory-arguments": 10,
|
||||||
|
"verifySchnorrSecp256k1Signature-cpu-arguments-intercept": 38887044,
|
||||||
|
"verifySchnorrSecp256k1Signature-cpu-arguments-slope": 32947,
|
||||||
|
"verifySchnorrSecp256k1Signature-memory-arguments": 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"executionPrices": {
|
||||||
|
"prMem": 5.77e-2,
|
||||||
|
"prSteps": 7.21e-5
|
||||||
|
},
|
||||||
|
"lovelacePerUTxOWord": 34482,
|
||||||
|
"maxBlockExUnits": {
|
||||||
|
"exUnitsMem": 80000000,
|
||||||
|
"exUnitsSteps": 40000000000
|
||||||
|
},
|
||||||
|
"maxCollateralInputs": 3,
|
||||||
|
"maxTxExUnits": {
|
||||||
|
"exUnitsMem": 16000000,
|
||||||
|
"exUnitsSteps": 10000000000
|
||||||
|
},
|
||||||
|
"maxValueSize": 5000
|
||||||
|
}
|
36
demo/devnet/genesis-byron.json
Normal file
36
demo/devnet/genesis-byron.json
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"protocolConsts": {
|
||||||
|
"k": 2160,
|
||||||
|
"protocolMagic": 42
|
||||||
|
},
|
||||||
|
"startTime": 1657186415,
|
||||||
|
"blockVersionData": {
|
||||||
|
"scriptVersion": 0,
|
||||||
|
"slotDuration": "250",
|
||||||
|
"maxBlockSize": "2000000",
|
||||||
|
"maxHeaderSize": "2000000",
|
||||||
|
"maxTxSize": "4096",
|
||||||
|
"maxProposalSize": "700",
|
||||||
|
"mpcThd": "20000000000000",
|
||||||
|
"heavyDelThd": "300000000000",
|
||||||
|
"updateVoteThd": "1000000000000",
|
||||||
|
"updateProposalThd": "100000000000000",
|
||||||
|
"updateImplicit": "10000",
|
||||||
|
"softforkRule": {
|
||||||
|
"initThd": "900000000000000",
|
||||||
|
"minThd": "600000000000000",
|
||||||
|
"thdDecrement": "50000000000000"
|
||||||
|
},
|
||||||
|
"txFeePolicy": {
|
||||||
|
"summand": "155381000000000",
|
||||||
|
"multiplier": "43000000000"
|
||||||
|
},
|
||||||
|
"unlockStakeEpoch": "18446744073709551615"
|
||||||
|
},
|
||||||
|
"bootStakeholders": {
|
||||||
|
"7a4519c93d7be4577dd85bd524c644e6b809e44eae0457b43128c1c7": 1
|
||||||
|
},
|
||||||
|
"heavyDelegation": {},
|
||||||
|
"nonAvvmBalances": {},
|
||||||
|
"avvmDistr": {}
|
||||||
|
}
|
65
demo/devnet/genesis-shelley.json
Normal file
65
demo/devnet/genesis-shelley.json
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
{
|
||||||
|
"epochLength": 432000,
|
||||||
|
"activeSlotsCoeff": 1.0,
|
||||||
|
"slotLength": 0.1,
|
||||||
|
"securityParam": 2160,
|
||||||
|
"genDelegs": {},
|
||||||
|
"initialFunds": {
|
||||||
|
"00813c32c92aad21770ff8001de0918f598df8c06775f77f8e8839d2a0074a515f7f32bf31a4f41c7417a8136e8152bfb42f06d71b389a6896": 900000000000,
|
||||||
|
"609783be7d3c54f11377966dfabc9284cd6c32fca1cd42ef0a4f1cc45b": 900000000000
|
||||||
|
},
|
||||||
|
"maxKESEvolutions": 60,
|
||||||
|
"maxLovelaceSupply": 2000000000000,
|
||||||
|
"networkId": "Testnet",
|
||||||
|
"networkMagic": 42,
|
||||||
|
"protocolParams": {
|
||||||
|
"a0": 0.0,
|
||||||
|
"decentralisationParam": 0,
|
||||||
|
"eMax": 18,
|
||||||
|
"extraEntropy": {
|
||||||
|
"tag": "NeutralNonce"
|
||||||
|
},
|
||||||
|
"keyDeposit": 0,
|
||||||
|
"maxBlockBodySize": 65536,
|
||||||
|
"maxBlockHeaderSize": 1100,
|
||||||
|
"maxTxSize": 16384,
|
||||||
|
"minFeeA": 44,
|
||||||
|
"minFeeB": 155381,
|
||||||
|
"minPoolCost": 0,
|
||||||
|
"minUTxOValue": 0,
|
||||||
|
"nOpt": 100,
|
||||||
|
"poolDeposit": 0,
|
||||||
|
"protocolVersion": {
|
||||||
|
"major": 7,
|
||||||
|
"minor": 0
|
||||||
|
},
|
||||||
|
"rho": 0.1,
|
||||||
|
"tau": 0.1
|
||||||
|
},
|
||||||
|
"slotsPerKESPeriod": 129600,
|
||||||
|
"staking": {
|
||||||
|
"pools": {
|
||||||
|
"8a219b698d3b6e034391ae84cee62f1d76b6fbc45ddfe4e31e0d4b60": {
|
||||||
|
"cost": 0,
|
||||||
|
"margin": 0.0,
|
||||||
|
"metadata": null,
|
||||||
|
"owners": [],
|
||||||
|
"pledge": 0,
|
||||||
|
"publicKey": "8a219b698d3b6e034391ae84cee62f1d76b6fbc45ddfe4e31e0d4b60",
|
||||||
|
"relays": [],
|
||||||
|
"rewardAccount": {
|
||||||
|
"credential": {
|
||||||
|
"key hash": "b6ffb20cf821f9286802235841d4348a2c2bafd4f73092b7de6655ea"
|
||||||
|
},
|
||||||
|
"network": "Testnet"
|
||||||
|
},
|
||||||
|
"vrf": "fec17ed60cbf2ec5be3f061fb4de0b6ef1f20947cfbfce5fb2783d12f3f69ff5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stake": {
|
||||||
|
"074a515f7f32bf31a4f41c7417a8136e8152bfb42f06d71b389a6896": "8a219b698d3b6e034391ae84cee62f1d76b6fbc45ddfe4e31e0d4b60"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systemStart": "2022-07-07T09:33:35Z",
|
||||||
|
"updateQuorum": 2
|
||||||
|
}
|
5
demo/devnet/kes.skey
Normal file
5
demo/devnet/kes.skey
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"type": "KesSigningKey_ed25519_kes_2^6",
|
||||||
|
"description": "KES Signing Key",
|
||||||
|
"cborHex": "590260a199f16b11da6c7f5c1e0f1eb0b9bbe278d3d8f35bfd50d0951c2ff94d0344cd57df5f64c9bac1dd60b4482f9c636168f40737d526625a2ec82f22ec0c72de0013f86ef743a7bba0286db6ddf3d85bf8e49ddbf14d9d3b7ee22f4857c77b740948f84f2e72f6bcf91f405e34ea50a2c53fa4876b43cfce2bcfe87c06a903de8bb33d968ca7930b67d0c23f5cb2d74e422d773ba80e388de384691000d6ba8a9b4dc7d3187f76048fbef9a52b72d80d835bb76eced7c0e0cdc5b58869b73c095dffa01db4ff51765afcead565395a5ed1cf74e5f2134d61076fece21aacd080bbbfaab94125401d7bbc74eafc7e7e3a2235f59dc03d6e332e53d558493a1e22213b92c77b1328ff1b83855da704fc366bf4415490602481d1939136eeaf252c65184912a779d9d94a90e32b72c1877ef60b6d79e707ce5a762acb4bed46436efe4fe62aae50b39068cc508a09427c92791cbcbea44318529cc68d297ca24e1b73b2394c385ec63fcd85ed56eec3de48860a1ec950aad4f91cbf741dbd7bf1d3c278875bd20e31ff5372339f6aa5280ad9b8bf3514889ac44600fe57ca0b535d6dc6b0b981e079595aad186ee0be9b07e837391ab165e4ca406601c876a86e246a3f53311e21199cccc0b080f28d18f4dc6987731e10e4ade00df7c6921c5ef3022b6f49a29ba307a2c8f4bd2ba42fcfa0aad68a2f0ad31fff69a99d3471f9036d3f5817a3edfeff7fc3c14e1151d767aaa043481cfd1a6ee55e8e5d7853ecdaf9da2bb36c716beae8d706bc648a790d4697e1d044a11a49f305ab8bc64a094bd81bda7395fe6f77dd5557c39919dd9bb9cf22a87fe47408ae3ec2247007d015a5"
|
||||||
|
}
|
5
demo/devnet/opcert.cert
Normal file
5
demo/devnet/opcert.cert
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"type": "NodeOperationalCertificate",
|
||||||
|
"description": "",
|
||||||
|
"cborHex": "828458204cd49bb05e9885142fe7af1481107995298771fd1a24e72b506a4d600ee2b3120000584089fc9e9f551b2ea873bf31643659d049152d5c8e8de86be4056370bccc5fa62dd12e3f152f1664e614763e46eaa7a17ed366b5cef19958773d1ab96941442e0b58205a3d778e76741a009e29d23093cfe046131808d34d7c864967b515e98dfc3583"
|
||||||
|
}
|
5
demo/devnet/vrf.skey
Normal file
5
demo/devnet/vrf.skey
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"type": "VrfSigningKey_PraosVRF",
|
||||||
|
"description": "VRF Signing Key",
|
||||||
|
"cborHex": "5840899795b70e9f34b737159fe21a6170568d6031e187f0cc84555c712b7c29b45cb882007593ef70f86e5c0948561a3b8e8851529a4f98975f2b24e768dda38ce2"
|
||||||
|
}
|
21
demo/prepare-devnet.sh
Executable file
21
demo/prepare-devnet.sh
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Prepare a "devnet" directory holding credentials, a dummy topology and
|
||||||
|
# "up-to-date" genesis files. If the directory exists, it is wiped out.
|
||||||
|
set -e
|
||||||
|
|
||||||
|
BASEDIR=$(dirname $(realpath $0))
|
||||||
|
TARGETDIR="${BASEDIR}/../devnet"
|
||||||
|
|
||||||
|
[ -d "$TARGETDIR" ] && { echo "Cleaning up directory $TARGETDIR" ; rm -r $TARGETDIR ; }
|
||||||
|
|
||||||
|
cp -af "$BASEDIR/devnet/" "$TARGETDIR"
|
||||||
|
cp -af "$BASEDIR/credentials" "$TARGETDIR"
|
||||||
|
cp -af "$BASEDIR/protocol-parameters.json" "$TARGETDIR"
|
||||||
|
echo '{"Producers": []}' > "$TARGETDIR/topology.json"
|
||||||
|
sed -i "s/\"startTime\": [0-9]*/\"startTime\": $(date +%s)/" "$TARGETDIR/genesis-byron.json" && \
|
||||||
|
sed -i "s/\"systemStart\": \".*\"/\"systemStart\": \"$(date -u +%FT%TZ)\"/" "$TARGETDIR/genesis-shelley.json"
|
||||||
|
|
||||||
|
find $TARGETDIR -type f -exec chmod 0400 {} \;
|
||||||
|
mkdir "$TARGETDIR/ipc"
|
||||||
|
echo "Prepared devnet, you can start the cluster now"
|
386
demo/protocol-parameters.json
Normal file
386
demo/protocol-parameters.json
Normal file
@ -0,0 +1,386 @@
|
|||||||
|
{
|
||||||
|
"collateralPercentage": 150,
|
||||||
|
"costModels": {
|
||||||
|
"PlutusScriptV1": {
|
||||||
|
"addInteger-cpu-arguments-intercept": 197209,
|
||||||
|
"addInteger-cpu-arguments-slope": 0,
|
||||||
|
"addInteger-memory-arguments-intercept": 1,
|
||||||
|
"addInteger-memory-arguments-slope": 1,
|
||||||
|
"appendByteString-cpu-arguments-intercept": 396231,
|
||||||
|
"appendByteString-cpu-arguments-slope": 621,
|
||||||
|
"appendByteString-memory-arguments-intercept": 0,
|
||||||
|
"appendByteString-memory-arguments-slope": 1,
|
||||||
|
"appendString-cpu-arguments-intercept": 150000,
|
||||||
|
"appendString-cpu-arguments-slope": 1000,
|
||||||
|
"appendString-memory-arguments-intercept": 0,
|
||||||
|
"appendString-memory-arguments-slope": 1,
|
||||||
|
"bData-cpu-arguments": 150000,
|
||||||
|
"bData-memory-arguments": 32,
|
||||||
|
"blake2b_256-cpu-arguments-intercept": 2477736,
|
||||||
|
"blake2b_256-cpu-arguments-slope": 29175,
|
||||||
|
"blake2b_256-memory-arguments": 4,
|
||||||
|
"cekApplyCost-exBudgetCPU": 29773,
|
||||||
|
"cekApplyCost-exBudgetMemory": 100,
|
||||||
|
"cekBuiltinCost-exBudgetCPU": 29773,
|
||||||
|
"cekBuiltinCost-exBudgetMemory": 100,
|
||||||
|
"cekConstCost-exBudgetCPU": 29773,
|
||||||
|
"cekConstCost-exBudgetMemory": 100,
|
||||||
|
"cekDelayCost-exBudgetCPU": 29773,
|
||||||
|
"cekDelayCost-exBudgetMemory": 100,
|
||||||
|
"cekForceCost-exBudgetCPU": 29773,
|
||||||
|
"cekForceCost-exBudgetMemory": 100,
|
||||||
|
"cekLamCost-exBudgetCPU": 29773,
|
||||||
|
"cekLamCost-exBudgetMemory": 100,
|
||||||
|
"cekStartupCost-exBudgetCPU": 100,
|
||||||
|
"cekStartupCost-exBudgetMemory": 100,
|
||||||
|
"cekVarCost-exBudgetCPU": 29773,
|
||||||
|
"cekVarCost-exBudgetMemory": 100,
|
||||||
|
"chooseData-cpu-arguments": 150000,
|
||||||
|
"chooseData-memory-arguments": 32,
|
||||||
|
"chooseList-cpu-arguments": 150000,
|
||||||
|
"chooseList-memory-arguments": 32,
|
||||||
|
"chooseUnit-cpu-arguments": 150000,
|
||||||
|
"chooseUnit-memory-arguments": 32,
|
||||||
|
"consByteString-cpu-arguments-intercept": 150000,
|
||||||
|
"consByteString-cpu-arguments-slope": 1000,
|
||||||
|
"consByteString-memory-arguments-intercept": 0,
|
||||||
|
"consByteString-memory-arguments-slope": 1,
|
||||||
|
"constrData-cpu-arguments": 150000,
|
||||||
|
"constrData-memory-arguments": 32,
|
||||||
|
"decodeUtf8-cpu-arguments-intercept": 150000,
|
||||||
|
"decodeUtf8-cpu-arguments-slope": 1000,
|
||||||
|
"decodeUtf8-memory-arguments-intercept": 0,
|
||||||
|
"decodeUtf8-memory-arguments-slope": 8,
|
||||||
|
"divideInteger-cpu-arguments-constant": 148000,
|
||||||
|
"divideInteger-cpu-arguments-model-arguments-intercept": 425507,
|
||||||
|
"divideInteger-cpu-arguments-model-arguments-slope": 118,
|
||||||
|
"divideInteger-memory-arguments-intercept": 0,
|
||||||
|
"divideInteger-memory-arguments-minimum": 1,
|
||||||
|
"divideInteger-memory-arguments-slope": 1,
|
||||||
|
"encodeUtf8-cpu-arguments-intercept": 150000,
|
||||||
|
"encodeUtf8-cpu-arguments-slope": 1000,
|
||||||
|
"encodeUtf8-memory-arguments-intercept": 0,
|
||||||
|
"encodeUtf8-memory-arguments-slope": 8,
|
||||||
|
"equalsByteString-cpu-arguments-constant": 150000,
|
||||||
|
"equalsByteString-cpu-arguments-intercept": 112536,
|
||||||
|
"equalsByteString-cpu-arguments-slope": 247,
|
||||||
|
"equalsByteString-memory-arguments": 1,
|
||||||
|
"equalsData-cpu-arguments-intercept": 150000,
|
||||||
|
"equalsData-cpu-arguments-slope": 10000,
|
||||||
|
"equalsData-memory-arguments": 1,
|
||||||
|
"equalsInteger-cpu-arguments-intercept": 136542,
|
||||||
|
"equalsInteger-cpu-arguments-slope": 1326,
|
||||||
|
"equalsInteger-memory-arguments": 1,
|
||||||
|
"equalsString-cpu-arguments-constant": 1000,
|
||||||
|
"equalsString-cpu-arguments-intercept": 150000,
|
||||||
|
"equalsString-cpu-arguments-slope": 1000,
|
||||||
|
"equalsString-memory-arguments": 1,
|
||||||
|
"fstPair-cpu-arguments": 150000,
|
||||||
|
"fstPair-memory-arguments": 32,
|
||||||
|
"headList-cpu-arguments": 150000,
|
||||||
|
"headList-memory-arguments": 32,
|
||||||
|
"iData-cpu-arguments": 150000,
|
||||||
|
"iData-memory-arguments": 32,
|
||||||
|
"ifThenElse-cpu-arguments": 1,
|
||||||
|
"ifThenElse-memory-arguments": 1,
|
||||||
|
"indexByteString-cpu-arguments": 150000,
|
||||||
|
"indexByteString-memory-arguments": 1,
|
||||||
|
"lengthOfByteString-cpu-arguments": 150000,
|
||||||
|
"lengthOfByteString-memory-arguments": 4,
|
||||||
|
"lessThanByteString-cpu-arguments-intercept": 103599,
|
||||||
|
"lessThanByteString-cpu-arguments-slope": 248,
|
||||||
|
"lessThanByteString-memory-arguments": 1,
|
||||||
|
"lessThanEqualsByteString-cpu-arguments-intercept": 103599,
|
||||||
|
"lessThanEqualsByteString-cpu-arguments-slope": 248,
|
||||||
|
"lessThanEqualsByteString-memory-arguments": 1,
|
||||||
|
"lessThanEqualsInteger-cpu-arguments-intercept": 145276,
|
||||||
|
"lessThanEqualsInteger-cpu-arguments-slope": 1366,
|
||||||
|
"lessThanEqualsInteger-memory-arguments": 1,
|
||||||
|
"lessThanInteger-cpu-arguments-intercept": 179690,
|
||||||
|
"lessThanInteger-cpu-arguments-slope": 497,
|
||||||
|
"lessThanInteger-memory-arguments": 1,
|
||||||
|
"listData-cpu-arguments": 150000,
|
||||||
|
"listData-memory-arguments": 32,
|
||||||
|
"mapData-cpu-arguments": 150000,
|
||||||
|
"mapData-memory-arguments": 32,
|
||||||
|
"mkCons-cpu-arguments": 150000,
|
||||||
|
"mkCons-memory-arguments": 32,
|
||||||
|
"mkNilData-cpu-arguments": 150000,
|
||||||
|
"mkNilData-memory-arguments": 32,
|
||||||
|
"mkNilPairData-cpu-arguments": 150000,
|
||||||
|
"mkNilPairData-memory-arguments": 32,
|
||||||
|
"mkPairData-cpu-arguments": 150000,
|
||||||
|
"mkPairData-memory-arguments": 32,
|
||||||
|
"modInteger-cpu-arguments-constant": 148000,
|
||||||
|
"modInteger-cpu-arguments-model-arguments-intercept": 425507,
|
||||||
|
"modInteger-cpu-arguments-model-arguments-slope": 118,
|
||||||
|
"modInteger-memory-arguments-intercept": 0,
|
||||||
|
"modInteger-memory-arguments-minimum": 1,
|
||||||
|
"modInteger-memory-arguments-slope": 1,
|
||||||
|
"multiplyInteger-cpu-arguments-intercept": 61516,
|
||||||
|
"multiplyInteger-cpu-arguments-slope": 11218,
|
||||||
|
"multiplyInteger-memory-arguments-intercept": 0,
|
||||||
|
"multiplyInteger-memory-arguments-slope": 1,
|
||||||
|
"nullList-cpu-arguments": 150000,
|
||||||
|
"nullList-memory-arguments": 32,
|
||||||
|
"quotientInteger-cpu-arguments-constant": 148000,
|
||||||
|
"quotientInteger-cpu-arguments-model-arguments-intercept": 425507,
|
||||||
|
"quotientInteger-cpu-arguments-model-arguments-slope": 118,
|
||||||
|
"quotientInteger-memory-arguments-intercept": 0,
|
||||||
|
"quotientInteger-memory-arguments-minimum": 1,
|
||||||
|
"quotientInteger-memory-arguments-slope": 1,
|
||||||
|
"remainderInteger-cpu-arguments-constant": 148000,
|
||||||
|
"remainderInteger-cpu-arguments-model-arguments-intercept": 425507,
|
||||||
|
"remainderInteger-cpu-arguments-model-arguments-slope": 118,
|
||||||
|
"remainderInteger-memory-arguments-intercept": 0,
|
||||||
|
"remainderInteger-memory-arguments-minimum": 1,
|
||||||
|
"remainderInteger-memory-arguments-slope": 1,
|
||||||
|
"sha2_256-cpu-arguments-intercept": 2477736,
|
||||||
|
"sha2_256-cpu-arguments-slope": 29175,
|
||||||
|
"sha2_256-memory-arguments": 4,
|
||||||
|
"sha3_256-cpu-arguments-intercept": 0,
|
||||||
|
"sha3_256-cpu-arguments-slope": 82363,
|
||||||
|
"sha3_256-memory-arguments": 4,
|
||||||
|
"sliceByteString-cpu-arguments-intercept": 150000,
|
||||||
|
"sliceByteString-cpu-arguments-slope": 5000,
|
||||||
|
"sliceByteString-memory-arguments-intercept": 0,
|
||||||
|
"sliceByteString-memory-arguments-slope": 1,
|
||||||
|
"sndPair-cpu-arguments": 150000,
|
||||||
|
"sndPair-memory-arguments": 32,
|
||||||
|
"subtractInteger-cpu-arguments-intercept": 197209,
|
||||||
|
"subtractInteger-cpu-arguments-slope": 0,
|
||||||
|
"subtractInteger-memory-arguments-intercept": 1,
|
||||||
|
"subtractInteger-memory-arguments-slope": 1,
|
||||||
|
"tailList-cpu-arguments": 150000,
|
||||||
|
"tailList-memory-arguments": 32,
|
||||||
|
"trace-cpu-arguments": 150000,
|
||||||
|
"trace-memory-arguments": 32,
|
||||||
|
"unBData-cpu-arguments": 150000,
|
||||||
|
"unBData-memory-arguments": 32,
|
||||||
|
"unConstrData-cpu-arguments": 150000,
|
||||||
|
"unConstrData-memory-arguments": 32,
|
||||||
|
"unIData-cpu-arguments": 150000,
|
||||||
|
"unIData-memory-arguments": 32,
|
||||||
|
"unListData-cpu-arguments": 150000,
|
||||||
|
"unListData-memory-arguments": 32,
|
||||||
|
"unMapData-cpu-arguments": 150000,
|
||||||
|
"unMapData-memory-arguments": 32,
|
||||||
|
"verifyEd25519Signature-cpu-arguments-intercept": 3345831,
|
||||||
|
"verifyEd25519Signature-cpu-arguments-slope": 1,
|
||||||
|
"verifyEd25519Signature-memory-arguments": 1
|
||||||
|
},
|
||||||
|
"PlutusScriptV2": {
|
||||||
|
"addInteger-cpu-arguments-intercept": 205665,
|
||||||
|
"addInteger-cpu-arguments-slope": 812,
|
||||||
|
"addInteger-memory-arguments-intercept": 1,
|
||||||
|
"addInteger-memory-arguments-slope": 1,
|
||||||
|
"appendByteString-cpu-arguments-intercept": 1000,
|
||||||
|
"appendByteString-cpu-arguments-slope": 571,
|
||||||
|
"appendByteString-memory-arguments-intercept": 0,
|
||||||
|
"appendByteString-memory-arguments-slope": 1,
|
||||||
|
"appendString-cpu-arguments-intercept": 1000,
|
||||||
|
"appendString-cpu-arguments-slope": 24177,
|
||||||
|
"appendString-memory-arguments-intercept": 4,
|
||||||
|
"appendString-memory-arguments-slope": 1,
|
||||||
|
"bData-cpu-arguments": 1000,
|
||||||
|
"bData-memory-arguments": 32,
|
||||||
|
"blake2b_256-cpu-arguments-intercept": 117366,
|
||||||
|
"blake2b_256-cpu-arguments-slope": 10475,
|
||||||
|
"blake2b_256-memory-arguments": 4,
|
||||||
|
"cekApplyCost-exBudgetCPU": 23000,
|
||||||
|
"cekApplyCost-exBudgetMemory": 100,
|
||||||
|
"cekBuiltinCost-exBudgetCPU": 23000,
|
||||||
|
"cekBuiltinCost-exBudgetMemory": 100,
|
||||||
|
"cekConstCost-exBudgetCPU": 23000,
|
||||||
|
"cekConstCost-exBudgetMemory": 100,
|
||||||
|
"cekDelayCost-exBudgetCPU": 23000,
|
||||||
|
"cekDelayCost-exBudgetMemory": 100,
|
||||||
|
"cekForceCost-exBudgetCPU": 23000,
|
||||||
|
"cekForceCost-exBudgetMemory": 100,
|
||||||
|
"cekLamCost-exBudgetCPU": 23000,
|
||||||
|
"cekLamCost-exBudgetMemory": 100,
|
||||||
|
"cekStartupCost-exBudgetCPU": 100,
|
||||||
|
"cekStartupCost-exBudgetMemory": 100,
|
||||||
|
"cekVarCost-exBudgetCPU": 23000,
|
||||||
|
"cekVarCost-exBudgetMemory": 100,
|
||||||
|
"chooseData-cpu-arguments": 19537,
|
||||||
|
"chooseData-memory-arguments": 32,
|
||||||
|
"chooseList-cpu-arguments": 175354,
|
||||||
|
"chooseList-memory-arguments": 32,
|
||||||
|
"chooseUnit-cpu-arguments": 46417,
|
||||||
|
"chooseUnit-memory-arguments": 4,
|
||||||
|
"consByteString-cpu-arguments-intercept": 221973,
|
||||||
|
"consByteString-cpu-arguments-slope": 511,
|
||||||
|
"consByteString-memory-arguments-intercept": 0,
|
||||||
|
"consByteString-memory-arguments-slope": 1,
|
||||||
|
"constrData-cpu-arguments": 89141,
|
||||||
|
"constrData-memory-arguments": 32,
|
||||||
|
"decodeUtf8-cpu-arguments-intercept": 497525,
|
||||||
|
"decodeUtf8-cpu-arguments-slope": 14068,
|
||||||
|
"decodeUtf8-memory-arguments-intercept": 4,
|
||||||
|
"decodeUtf8-memory-arguments-slope": 2,
|
||||||
|
"divideInteger-cpu-arguments-constant": 196500,
|
||||||
|
"divideInteger-cpu-arguments-model-arguments-intercept": 453240,
|
||||||
|
"divideInteger-cpu-arguments-model-arguments-slope": 220,
|
||||||
|
"divideInteger-memory-arguments-intercept": 0,
|
||||||
|
"divideInteger-memory-arguments-minimum": 1,
|
||||||
|
"divideInteger-memory-arguments-slope": 1,
|
||||||
|
"encodeUtf8-cpu-arguments-intercept": 1000,
|
||||||
|
"encodeUtf8-cpu-arguments-slope": 28662,
|
||||||
|
"encodeUtf8-memory-arguments-intercept": 4,
|
||||||
|
"encodeUtf8-memory-arguments-slope": 2,
|
||||||
|
"equalsByteString-cpu-arguments-constant": 245000,
|
||||||
|
"equalsByteString-cpu-arguments-intercept": 216773,
|
||||||
|
"equalsByteString-cpu-arguments-slope": 62,
|
||||||
|
"equalsByteString-memory-arguments": 1,
|
||||||
|
"equalsData-cpu-arguments-intercept": 1060367,
|
||||||
|
"equalsData-cpu-arguments-slope": 12586,
|
||||||
|
"equalsData-memory-arguments": 1,
|
||||||
|
"equalsInteger-cpu-arguments-intercept": 208512,
|
||||||
|
"equalsInteger-cpu-arguments-slope": 421,
|
||||||
|
"equalsInteger-memory-arguments": 1,
|
||||||
|
"equalsString-cpu-arguments-constant": 187000,
|
||||||
|
"equalsString-cpu-arguments-intercept": 1000,
|
||||||
|
"equalsString-cpu-arguments-slope": 52998,
|
||||||
|
"equalsString-memory-arguments": 1,
|
||||||
|
"fstPair-cpu-arguments": 80436,
|
||||||
|
"fstPair-memory-arguments": 32,
|
||||||
|
"headList-cpu-arguments": 43249,
|
||||||
|
"headList-memory-arguments": 32,
|
||||||
|
"iData-cpu-arguments": 1000,
|
||||||
|
"iData-memory-arguments": 32,
|
||||||
|
"ifThenElse-cpu-arguments": 80556,
|
||||||
|
"ifThenElse-memory-arguments": 1,
|
||||||
|
"indexByteString-cpu-arguments": 57667,
|
||||||
|
"indexByteString-memory-arguments": 4,
|
||||||
|
"lengthOfByteString-cpu-arguments": 1000,
|
||||||
|
"lengthOfByteString-memory-arguments": 10,
|
||||||
|
"lessThanByteString-cpu-arguments-intercept": 197145,
|
||||||
|
"lessThanByteString-cpu-arguments-slope": 156,
|
||||||
|
"lessThanByteString-memory-arguments": 1,
|
||||||
|
"lessThanEqualsByteString-cpu-arguments-intercept": 197145,
|
||||||
|
"lessThanEqualsByteString-cpu-arguments-slope": 156,
|
||||||
|
"lessThanEqualsByteString-memory-arguments": 1,
|
||||||
|
"lessThanEqualsInteger-cpu-arguments-intercept": 204924,
|
||||||
|
"lessThanEqualsInteger-cpu-arguments-slope": 473,
|
||||||
|
"lessThanEqualsInteger-memory-arguments": 1,
|
||||||
|
"lessThanInteger-cpu-arguments-intercept": 208896,
|
||||||
|
"lessThanInteger-cpu-arguments-slope": 511,
|
||||||
|
"lessThanInteger-memory-arguments": 1,
|
||||||
|
"listData-cpu-arguments": 52467,
|
||||||
|
"listData-memory-arguments": 32,
|
||||||
|
"mapData-cpu-arguments": 64832,
|
||||||
|
"mapData-memory-arguments": 32,
|
||||||
|
"mkCons-cpu-arguments": 65493,
|
||||||
|
"mkCons-memory-arguments": 32,
|
||||||
|
"mkNilData-cpu-arguments": 22558,
|
||||||
|
"mkNilData-memory-arguments": 32,
|
||||||
|
"mkNilPairData-cpu-arguments": 16563,
|
||||||
|
"mkNilPairData-memory-arguments": 32,
|
||||||
|
"mkPairData-cpu-arguments": 76511,
|
||||||
|
"mkPairData-memory-arguments": 32,
|
||||||
|
"modInteger-cpu-arguments-constant": 196500,
|
||||||
|
"modInteger-cpu-arguments-model-arguments-intercept": 453240,
|
||||||
|
"modInteger-cpu-arguments-model-arguments-slope": 220,
|
||||||
|
"modInteger-memory-arguments-intercept": 0,
|
||||||
|
"modInteger-memory-arguments-minimum": 1,
|
||||||
|
"modInteger-memory-arguments-slope": 1,
|
||||||
|
"multiplyInteger-cpu-arguments-intercept": 69522,
|
||||||
|
"multiplyInteger-cpu-arguments-slope": 11687,
|
||||||
|
"multiplyInteger-memory-arguments-intercept": 0,
|
||||||
|
"multiplyInteger-memory-arguments-slope": 1,
|
||||||
|
"nullList-cpu-arguments": 60091,
|
||||||
|
"nullList-memory-arguments": 32,
|
||||||
|
"quotientInteger-cpu-arguments-constant": 196500,
|
||||||
|
"quotientInteger-cpu-arguments-model-arguments-intercept": 453240,
|
||||||
|
"quotientInteger-cpu-arguments-model-arguments-slope": 220,
|
||||||
|
"quotientInteger-memory-arguments-intercept": 0,
|
||||||
|
"quotientInteger-memory-arguments-minimum": 1,
|
||||||
|
"quotientInteger-memory-arguments-slope": 1,
|
||||||
|
"remainderInteger-cpu-arguments-constant": 196500,
|
||||||
|
"remainderInteger-cpu-arguments-model-arguments-intercept": 453240,
|
||||||
|
"remainderInteger-cpu-arguments-model-arguments-slope": 220,
|
||||||
|
"remainderInteger-memory-arguments-intercept": 0,
|
||||||
|
"remainderInteger-memory-arguments-minimum": 1,
|
||||||
|
"remainderInteger-memory-arguments-slope": 1,
|
||||||
|
"serialiseData-cpu-arguments-intercept": 1159724,
|
||||||
|
"serialiseData-cpu-arguments-slope": 392670,
|
||||||
|
"serialiseData-memory-arguments-intercept": 0,
|
||||||
|
"serialiseData-memory-arguments-slope": 2,
|
||||||
|
"sha2_256-cpu-arguments-intercept": 806990,
|
||||||
|
"sha2_256-cpu-arguments-slope": 30482,
|
||||||
|
"sha2_256-memory-arguments": 4,
|
||||||
|
"sha3_256-cpu-arguments-intercept": 1927926,
|
||||||
|
"sha3_256-cpu-arguments-slope": 82523,
|
||||||
|
"sha3_256-memory-arguments": 4,
|
||||||
|
"sliceByteString-cpu-arguments-intercept": 265318,
|
||||||
|
"sliceByteString-cpu-arguments-slope": 0,
|
||||||
|
"sliceByteString-memory-arguments-intercept": 4,
|
||||||
|
"sliceByteString-memory-arguments-slope": 0,
|
||||||
|
"sndPair-cpu-arguments": 85931,
|
||||||
|
"sndPair-memory-arguments": 32,
|
||||||
|
"subtractInteger-cpu-arguments-intercept": 205665,
|
||||||
|
"subtractInteger-cpu-arguments-slope": 812,
|
||||||
|
"subtractInteger-memory-arguments-intercept": 1,
|
||||||
|
"subtractInteger-memory-arguments-slope": 1,
|
||||||
|
"tailList-cpu-arguments": 41182,
|
||||||
|
"tailList-memory-arguments": 32,
|
||||||
|
"trace-cpu-arguments": 212342,
|
||||||
|
"trace-memory-arguments": 32,
|
||||||
|
"unBData-cpu-arguments": 31220,
|
||||||
|
"unBData-memory-arguments": 32,
|
||||||
|
"unConstrData-cpu-arguments": 32696,
|
||||||
|
"unConstrData-memory-arguments": 32,
|
||||||
|
"unIData-cpu-arguments": 43357,
|
||||||
|
"unIData-memory-arguments": 32,
|
||||||
|
"unListData-cpu-arguments": 32247,
|
||||||
|
"unListData-memory-arguments": 32,
|
||||||
|
"unMapData-cpu-arguments": 38314,
|
||||||
|
"unMapData-memory-arguments": 32,
|
||||||
|
"verifyEcdsaSecp256k1Signature-cpu-arguments": 35892428,
|
||||||
|
"verifyEcdsaSecp256k1Signature-memory-arguments": 10,
|
||||||
|
"verifyEd25519Signature-cpu-arguments-intercept": 9462713,
|
||||||
|
"verifyEd25519Signature-cpu-arguments-slope": 1021,
|
||||||
|
"verifyEd25519Signature-memory-arguments": 10,
|
||||||
|
"verifySchnorrSecp256k1Signature-cpu-arguments-intercept": 38887044,
|
||||||
|
"verifySchnorrSecp256k1Signature-cpu-arguments-slope": 32947,
|
||||||
|
"verifySchnorrSecp256k1Signature-memory-arguments": 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"decentralization": null,
|
||||||
|
"executionUnitPrices": {
|
||||||
|
"priceMemory": 5.77e-2,
|
||||||
|
"priceSteps": 7.21e-5
|
||||||
|
},
|
||||||
|
"extraPraosEntropy": null,
|
||||||
|
"maxBlockBodySize": 65536,
|
||||||
|
"maxBlockExecutionUnits": {
|
||||||
|
"memory": 80000000,
|
||||||
|
"steps": 40000000000
|
||||||
|
},
|
||||||
|
"maxBlockHeaderSize": 1100,
|
||||||
|
"maxCollateralInputs": 3,
|
||||||
|
"maxTxExecutionUnits": {
|
||||||
|
"memory": 16000000,
|
||||||
|
"steps": 10000000000
|
||||||
|
},
|
||||||
|
"maxTxSize": 16384,
|
||||||
|
"maxValueSize": 5000,
|
||||||
|
"minPoolCost": 0,
|
||||||
|
"minUTxOValue": null,
|
||||||
|
"monetaryExpansion": 1.78650067e-3,
|
||||||
|
"poolPledgeInfluence": 0.1,
|
||||||
|
"poolRetireMaxEpoch": 18,
|
||||||
|
"protocolVersion": {
|
||||||
|
"major": 7,
|
||||||
|
"minor": 0
|
||||||
|
},
|
||||||
|
"stakeAddressDeposit": 400000,
|
||||||
|
"stakePoolDeposit": 500000000,
|
||||||
|
"stakePoolTargetNum": 50,
|
||||||
|
"treasuryCut": 0.1,
|
||||||
|
"txFeeFixed": 0,
|
||||||
|
"txFeePerByte": 0,
|
||||||
|
"utxoCostPerWord": 34488,
|
||||||
|
"utxoCostPerByte": 4310
|
||||||
|
}
|
2
dep/aeson-gadt-th/default.nix
Normal file
2
dep/aeson-gadt-th/default.nix
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# DO NOT HAND-EDIT THIS FILE
|
||||||
|
import (import ./thunk.nix)
|
7
dep/aeson-gadt-th/github.json
Normal file
7
dep/aeson-gadt-th/github.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"owner": "obsidiansystems",
|
||||||
|
"repo": "aeson-gadt-th",
|
||||||
|
"private": false,
|
||||||
|
"rev": "71a315a4873c2875ad737a3320320849bdcf8a2a",
|
||||||
|
"sha256": "1sjl0a0ig0xfssl4bglakk1b7sj8wqz8hwbg7k2fk10qi7z5hb50"
|
||||||
|
}
|
9
dep/aeson-gadt-th/thunk.nix
Normal file
9
dep/aeson-gadt-th/thunk.nix
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# DO NOT HAND-EDIT THIS FILE
|
||||||
|
let fetch = { private ? false, fetchSubmodules ? false, owner, repo, rev, sha256, ... }:
|
||||||
|
if !fetchSubmodules && !private then builtins.fetchTarball {
|
||||||
|
url = "https://github.com/${owner}/${repo}/archive/${rev}.tar.gz"; inherit sha256;
|
||||||
|
} else (import <nixpkgs> {}).fetchFromGitHub {
|
||||||
|
inherit owner repo rev sha256 fetchSubmodules private;
|
||||||
|
};
|
||||||
|
json = builtins.fromJSON (builtins.readFile ./github.json);
|
||||||
|
in fetch json
|
2
dep/aeson/default.nix
Normal file
2
dep/aeson/default.nix
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# DO NOT HAND-EDIT THIS FILE
|
||||||
|
import (import ./thunk.nix)
|
8
dep/aeson/github.json
Normal file
8
dep/aeson/github.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"owner": "haskell",
|
||||||
|
"repo": "aeson",
|
||||||
|
"branch": "aeson-1.5",
|
||||||
|
"private": false,
|
||||||
|
"rev": "78e838df44288ac7d7ac2cd77863d2c026d86dbb",
|
||||||
|
"sha256": "181v1nz05jq992wgmz6ns7iwqx0c5w003hv5ki1kvc9zlg5dh3vf"
|
||||||
|
}
|
9
dep/aeson/thunk.nix
Normal file
9
dep/aeson/thunk.nix
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# DO NOT HAND-EDIT THIS FILE
|
||||||
|
let fetch = { private ? false, fetchSubmodules ? false, owner, repo, rev, sha256, ... }:
|
||||||
|
if !fetchSubmodules && !private then builtins.fetchTarball {
|
||||||
|
url = "https://github.com/${owner}/${repo}/archive/${rev}.tar.gz"; inherit sha256;
|
||||||
|
} else (import <nixpkgs> {}).fetchFromGitHub {
|
||||||
|
inherit owner repo rev sha256 fetchSubmodules private;
|
||||||
|
};
|
||||||
|
json = builtins.fromJSON (builtins.readFile ./github.json);
|
||||||
|
in fetch json
|
2
dep/constraints-extras/default.nix
Normal file
2
dep/constraints-extras/default.nix
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# DO NOT HAND-EDIT THIS FILE
|
||||||
|
import (import ./thunk.nix)
|
8
dep/constraints-extras/github.json
Normal file
8
dep/constraints-extras/github.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"owner": "obsidiansystems",
|
||||||
|
"repo": "constraints-extras",
|
||||||
|
"branch": "release/0.3.2.0",
|
||||||
|
"private": false,
|
||||||
|
"rev": "42835fd9e1b4b3c4a72cd1237c04789f01c92dd0",
|
||||||
|
"sha256": "0z7yfxxi4jywzhlkphs8ss3hd7fll8c90bbl6nr2bj63c87jx6sw"
|
||||||
|
}
|
9
dep/constraints-extras/thunk.nix
Normal file
9
dep/constraints-extras/thunk.nix
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# DO NOT HAND-EDIT THIS FILE
|
||||||
|
let fetch = { private ? false, fetchSubmodules ? false, owner, repo, rev, sha256, ... }:
|
||||||
|
if !fetchSubmodules && !private then builtins.fetchTarball {
|
||||||
|
url = "https://github.com/${owner}/${repo}/archive/${rev}.tar.gz"; inherit sha256;
|
||||||
|
} else (import <nixpkgs> {}).fetchFromGitHub {
|
||||||
|
inherit owner repo rev sha256 fetchSubmodules private;
|
||||||
|
};
|
||||||
|
json = builtins.fromJSON (builtins.readFile ./github.json);
|
||||||
|
in fetch json
|
2
dep/entropy/default.nix
Normal file
2
dep/entropy/default.nix
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# DO NOT HAND-EDIT THIS FILE
|
||||||
|
import (import ./thunk.nix)
|
8
dep/entropy/github.json
Normal file
8
dep/entropy/github.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"owner": "obsidiansystems",
|
||||||
|
"repo": "entropy",
|
||||||
|
"branch": "aa/nonwindow-contexts",
|
||||||
|
"private": false,
|
||||||
|
"rev": "ddda007c44390d0ec8cad58810710864dee60ddd",
|
||||||
|
"sha256": "00b7cqdqbjf953r5gmwmkn2mn36zdxqwx90xih925cni94vi4vw9"
|
||||||
|
}
|
9
dep/entropy/thunk.nix
Normal file
9
dep/entropy/thunk.nix
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# DO NOT HAND-EDIT THIS FILE
|
||||||
|
let fetch = { private ? false, fetchSubmodules ? false, owner, repo, rev, sha256, ... }:
|
||||||
|
if !fetchSubmodules && !private then builtins.fetchTarball {
|
||||||
|
url = "https://github.com/${owner}/${repo}/archive/${rev}.tar.gz"; inherit sha256;
|
||||||
|
} else (import <nixpkgs> {}).fetchFromGitHub {
|
||||||
|
inherit owner repo rev sha256 fetchSubmodules private;
|
||||||
|
};
|
||||||
|
json = builtins.fromJSON (builtins.readFile ./github.json);
|
||||||
|
in fetch json
|
2
dep/hydra-poc/default.nix
Normal file
2
dep/hydra-poc/default.nix
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# DO NOT HAND-EDIT THIS FILE
|
||||||
|
import (import ./thunk.nix)
|
7
dep/hydra-poc/github.json
Normal file
7
dep/hydra-poc/github.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"owner": "input-output-hk",
|
||||||
|
"repo": "hydra-poc",
|
||||||
|
"private": false,
|
||||||
|
"rev": "b0ebec965f27553a1c99e5457441219dcb9306d6",
|
||||||
|
"sha256": "0i9sflwpy87hhrbb6c0wbjs1mj2nsln69yah6vnacb6l0j47ik4b"
|
||||||
|
}
|
9
dep/hydra-poc/thunk.nix
Normal file
9
dep/hydra-poc/thunk.nix
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# DO NOT HAND-EDIT THIS FILE
|
||||||
|
let fetch = { private ? false, fetchSubmodules ? false, owner, repo, rev, sha256, ... }:
|
||||||
|
if !fetchSubmodules && !private then builtins.fetchTarball {
|
||||||
|
url = "https://github.com/${owner}/${repo}/archive/${rev}.tar.gz"; inherit sha256;
|
||||||
|
} else (import <nixpkgs> {}).fetchFromGitHub {
|
||||||
|
inherit owner repo rev sha256 fetchSubmodules private;
|
||||||
|
};
|
||||||
|
json = builtins.fromJSON (builtins.readFile ./github.json);
|
||||||
|
in fetch json
|
2
dep/logging-effect/default.nix
Normal file
2
dep/logging-effect/default.nix
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# DO NOT HAND-EDIT THIS FILE
|
||||||
|
import (import ./thunk.nix)
|
7
dep/logging-effect/github.json
Normal file
7
dep/logging-effect/github.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"owner": "ocharles",
|
||||||
|
"repo": "logging-effect",
|
||||||
|
"private": false,
|
||||||
|
"rev": "efc856b62aec15f0087be0edb7ba621ed49b0bb1",
|
||||||
|
"sha256": "13nr3zw39415js1af2vd322vhzwqb2rkrv7b5lkd97h211d7zbj9"
|
||||||
|
}
|
9
dep/logging-effect/thunk.nix
Normal file
9
dep/logging-effect/thunk.nix
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# DO NOT HAND-EDIT THIS FILE
|
||||||
|
let fetch = { private ? false, fetchSubmodules ? false, owner, repo, rev, sha256, ... }:
|
||||||
|
if !fetchSubmodules && !private then builtins.fetchTarball {
|
||||||
|
url = "https://github.com/${owner}/${repo}/archive/${rev}.tar.gz"; inherit sha256;
|
||||||
|
} else (import <nixpkgs> {}).fetchFromGitHub {
|
||||||
|
inherit owner repo rev sha256 fetchSubmodules private;
|
||||||
|
};
|
||||||
|
json = builtins.fromJSON (builtins.readFile ./github.json);
|
||||||
|
in fetch json
|
2
dep/nix-thunk/default.nix
Normal file
2
dep/nix-thunk/default.nix
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# DO NOT HAND-EDIT THIS FILE
|
||||||
|
import (import ./thunk.nix)
|
7
dep/nix-thunk/github.json
Normal file
7
dep/nix-thunk/github.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"owner": "obsidiansystems",
|
||||||
|
"repo": "nix-thunk",
|
||||||
|
"private": false,
|
||||||
|
"rev": "bd0de53129ca4ac5ce313a3e021edf3638a3a22c",
|
||||||
|
"sha256": "0cn74ylcfr9v2w94jpga9v18jn6zafb9k996afszn59iqlcfi74q"
|
||||||
|
}
|
12
dep/nix-thunk/thunk.nix
Normal file
12
dep/nix-thunk/thunk.nix
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# DO NOT HAND-EDIT THIS FILE
|
||||||
|
let fetch = { private ? false, fetchSubmodules ? false, owner, repo, rev, sha256, ... }:
|
||||||
|
if !fetchSubmodules && !private then builtins.fetchTarball {
|
||||||
|
url = "https://github.com/${owner}/${repo}/archive/${rev}.tar.gz"; inherit sha256;
|
||||||
|
} else (import (builtins.fetchTarball {
|
||||||
|
url = "https://github.com/NixOS/nixpkgs/archive/3aad50c30c826430b0270fcf8264c8c41b005403.tar.gz";
|
||||||
|
sha256 = "0xwqsf08sywd23x0xvw4c4ghq0l28w2ki22h0bdn766i16z9q2gr";
|
||||||
|
}) {}).fetchFromGitHub {
|
||||||
|
inherit owner repo rev sha256 fetchSubmodules private;
|
||||||
|
};
|
||||||
|
json = builtins.fromJSON (builtins.readFile ./github.json);
|
||||||
|
in fetch json
|
2
dep/reflex-gadt-api/default.nix
Normal file
2
dep/reflex-gadt-api/default.nix
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# DO NOT HAND-EDIT THIS FILE
|
||||||
|
import (import ./thunk.nix)
|
8
dep/reflex-gadt-api/github.json
Normal file
8
dep/reflex-gadt-api/github.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"owner": "reflex-frp",
|
||||||
|
"repo": "reflex-gadt-api",
|
||||||
|
"branch": "develop",
|
||||||
|
"private": false,
|
||||||
|
"rev": "69aca72b57a74fbf0d06a1b2ac1d247ce9aa207f",
|
||||||
|
"sha256": "116c6lna8pkas95lclm4halagc4f6rxv5hmf7rnl10lxqi9m48qw"
|
||||||
|
}
|
9
dep/reflex-gadt-api/thunk.nix
Normal file
9
dep/reflex-gadt-api/thunk.nix
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# DO NOT HAND-EDIT THIS FILE
|
||||||
|
let fetch = { private ? false, fetchSubmodules ? false, owner, repo, rev, sha256, ... }:
|
||||||
|
if !fetchSubmodules && !private then builtins.fetchTarball {
|
||||||
|
url = "https://github.com/${owner}/${repo}/archive/${rev}.tar.gz"; inherit sha256;
|
||||||
|
} else (import <nixpkgs> {}).fetchFromGitHub {
|
||||||
|
inherit owner repo rev sha256 fetchSubmodules private;
|
||||||
|
};
|
||||||
|
json = builtins.fromJSON (builtins.readFile ./github.json);
|
||||||
|
in fetch json
|
2
dep/reflex-platform/default.nix
Normal file
2
dep/reflex-platform/default.nix
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# DO NOT HAND-EDIT THIS FILE
|
||||||
|
import (import ./thunk.nix)
|
8
dep/reflex-platform/github.json
Normal file
8
dep/reflex-platform/github.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"owner": "reflex-frp",
|
||||||
|
"repo": "reflex-platform",
|
||||||
|
"branch": "release/0.9.2.0",
|
||||||
|
"private": false,
|
||||||
|
"rev": "123a6f487ca954fd983f6d4cd6b2a69d4c463d10",
|
||||||
|
"sha256": "16q1rq0rwi6l28fv46q8m0hvb9rxrzf574j865vaz04xy8d5p1ya"
|
||||||
|
}
|
12
dep/reflex-platform/thunk.nix
Normal file
12
dep/reflex-platform/thunk.nix
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# DO NOT HAND-EDIT THIS FILE
|
||||||
|
let fetch = { private ? false, fetchSubmodules ? false, owner, repo, rev, sha256, ... }:
|
||||||
|
if !fetchSubmodules && !private then builtins.fetchTarball {
|
||||||
|
url = "https://github.com/${owner}/${repo}/archive/${rev}.tar.gz"; inherit sha256;
|
||||||
|
} else (import (builtins.fetchTarball {
|
||||||
|
url = "https://github.com/NixOS/nixpkgs/archive/3aad50c30c826430b0270fcf8264c8c41b005403.tar.gz";
|
||||||
|
sha256 = "0xwqsf08sywd23x0xvw4c4ghq0l28w2ki22h0bdn766i16z9q2gr";
|
||||||
|
}) {}).fetchFromGitHub {
|
||||||
|
inherit owner repo rev sha256 fetchSubmodules private;
|
||||||
|
};
|
||||||
|
json = builtins.fromJSON (builtins.readFile ./github.json);
|
||||||
|
in fetch json
|
4
hie.yaml
Normal file
4
hie.yaml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
cradle:
|
||||||
|
cabal:
|
||||||
|
- path: "src"
|
||||||
|
component: "exe:hydra-head-demo"
|
55
hydra-head-demo.cabal
Normal file
55
hydra-head-demo.cabal
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
name: hydra-head-demo
|
||||||
|
version: 0.1
|
||||||
|
cabal-version: >= 1.8
|
||||||
|
build-type: Simple
|
||||||
|
|
||||||
|
|
||||||
|
executable hydra-head-demo
|
||||||
|
main-is: Main.hs
|
||||||
|
hs-source-dirs: src
|
||||||
|
ghc-options: -Wall -Wredundant-constraints -Wincomplete-uni-patterns -Wincomplete-record-updates -O -threaded -fno-show-valid-hole-fits
|
||||||
|
if impl(ghcjs)
|
||||||
|
buildable: False
|
||||||
|
other-modules: Hydra.ClientInput
|
||||||
|
, Hydra.Devnet
|
||||||
|
, Hydra.ServerOutput
|
||||||
|
, Hydra.Types
|
||||||
|
, Paths
|
||||||
|
build-depends: base
|
||||||
|
, process
|
||||||
|
, async
|
||||||
|
, which
|
||||||
|
-- , monad-logger
|
||||||
|
-- , logging-effect
|
||||||
|
, prettyprinter
|
||||||
|
, string-interpolate
|
||||||
|
, containers
|
||||||
|
, text
|
||||||
|
, witherable
|
||||||
|
-- , io-streams
|
||||||
|
, some
|
||||||
|
, directory
|
||||||
|
, aeson
|
||||||
|
, resource-pool
|
||||||
|
, bytestring
|
||||||
|
, uuid
|
||||||
|
, time
|
||||||
|
, reflex
|
||||||
|
, reflex-dom
|
||||||
|
, mtl
|
||||||
|
, jsaddle
|
||||||
|
|
||||||
|
default-extensions:
|
||||||
|
OverloadedStrings
|
||||||
|
LambdaCase
|
||||||
|
GADTs
|
||||||
|
ScopedTypeVariables
|
||||||
|
OverloadedStrings
|
||||||
|
FlexibleContexts
|
||||||
|
QuasiQuotes
|
||||||
|
DeriveGeneric
|
||||||
|
RecursiveDo
|
||||||
|
RankNTypes
|
||||||
|
PartialTypeSignatures
|
||||||
|
TypeFamilies
|
||||||
|
TypeApplications
|
26
src/Hydra/ClientInput.hs
Normal file
26
src/Hydra/ClientInput.hs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
-- |
|
||||||
|
|
||||||
|
module Hydra.ClientInput where
|
||||||
|
|
||||||
|
import GHC.Generics
|
||||||
|
import Data.Aeson
|
||||||
|
import qualified Data.Text as T
|
||||||
|
import Hydra.Types
|
||||||
|
|
||||||
|
-- Copied and adapted from hydra-poc:hydra-node/src/hydra/ServerOutput.hs
|
||||||
|
-- Anything that took effort was replaced by Value
|
||||||
|
|
||||||
|
data ClientInput
|
||||||
|
= Init {contestationPeriod :: ContestationPeriod}
|
||||||
|
| Abort
|
||||||
|
| Commit {utxo :: WholeUTXO}
|
||||||
|
| NewTx {transaction :: T.Text}
|
||||||
|
| GetUTxO
|
||||||
|
| Close
|
||||||
|
| Contest
|
||||||
|
| Fanout
|
||||||
|
deriving (Eq, Generic, Show)
|
||||||
|
|
||||||
|
|
||||||
|
instance ToJSON ClientInput
|
||||||
|
instance FromJSON ClientInput
|
377
src/Hydra/Devnet.hs
Normal file
377
src/Hydra/Devnet.hs
Normal file
@ -0,0 +1,377 @@
|
|||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
{-# LANGUAGE TupleSections #-}
|
||||||
|
|
||||||
|
-- |
|
||||||
|
|
||||||
|
module Hydra.Devnet
|
||||||
|
( HydraScriptTxId
|
||||||
|
, HydraKeyInfo(..)
|
||||||
|
, SigningKey
|
||||||
|
, KeyPair(..)
|
||||||
|
, getCardanoAddress
|
||||||
|
, seedAddressFromFaucetAndWait
|
||||||
|
, publishReferenceScripts
|
||||||
|
, queryAddressUTXOs
|
||||||
|
, buildSignedHydraTx
|
||||||
|
, generateKeys
|
||||||
|
, cardanoNodePath
|
||||||
|
, hydraNodePath
|
||||||
|
, prepareDevnet
|
||||||
|
, devnetMagic
|
||||||
|
, minTxLovelace
|
||||||
|
)
|
||||||
|
|
||||||
|
where
|
||||||
|
|
||||||
|
import System.Which
|
||||||
|
import System.Directory
|
||||||
|
import System.Process
|
||||||
|
|
||||||
|
import Control.Monad
|
||||||
|
import Control.Monad.IO.Class
|
||||||
|
import Data.Aeson
|
||||||
|
|
||||||
|
import Control.Concurrent
|
||||||
|
|
||||||
|
|
||||||
|
import Data.Map (Map)
|
||||||
|
|
||||||
|
import Data.Bool
|
||||||
|
import qualified Data.Text as T
|
||||||
|
import qualified Data.Map as Map
|
||||||
|
import Data.String.Interpolate (i)
|
||||||
|
import Paths
|
||||||
|
|
||||||
|
import qualified Data.ByteString.Lazy.Char8 as BS
|
||||||
|
|
||||||
|
import Hydra.Types
|
||||||
|
import qualified Data.UUID.V4 as UUIDV4
|
||||||
|
import qualified Data.UUID as UUID
|
||||||
|
import Data.UUID (UUID)
|
||||||
|
import Data.Maybe (fromMaybe)
|
||||||
|
|
||||||
|
|
||||||
|
devnetMagic :: Int
|
||||||
|
devnetMagic = 42
|
||||||
|
|
||||||
|
prepareDevnet :: IO ()
|
||||||
|
prepareDevnet = do
|
||||||
|
output <- readCreateProcess (shell "[ -d devnet ] || ./demo/prepare-devnet.sh") ""
|
||||||
|
putStrLn output
|
||||||
|
|
||||||
|
cardanoNodePath :: FilePath
|
||||||
|
cardanoNodePath = $(staticWhich "cardano-node")
|
||||||
|
|
||||||
|
cardanoCliPath :: FilePath
|
||||||
|
cardanoCliPath = $(staticWhich "cardano-cli")
|
||||||
|
|
||||||
|
hydraNodePath :: FilePath
|
||||||
|
hydraNodePath = $(staticWhich "hydra-node")
|
||||||
|
|
||||||
|
jqPath :: FilePath
|
||||||
|
jqPath = $(staticWhich "jq")
|
||||||
|
|
||||||
|
type TxId = T.Text
|
||||||
|
|
||||||
|
type HydraScriptTxId = T.Text
|
||||||
|
|
||||||
|
type DraftTx = FilePath
|
||||||
|
type SignedTx = FilePath
|
||||||
|
|
||||||
|
devnetNetworkId :: Int
|
||||||
|
devnetNetworkId = 42
|
||||||
|
|
||||||
|
generateKeys :: (MonadIO m) => m HydraKeyInfo
|
||||||
|
generateKeys = do
|
||||||
|
basePath <- liftIO getTempPath'
|
||||||
|
HydraKeyInfo <$> generateCardanoKeys basePath <*> generateHydraKeys basePath
|
||||||
|
|
||||||
|
|
||||||
|
type SigningKey = String
|
||||||
|
type VerificationKey = String
|
||||||
|
|
||||||
|
data KeyPair = KeyPair
|
||||||
|
{ _signingKey :: SigningKey
|
||||||
|
, _verificationKey :: VerificationKey
|
||||||
|
}
|
||||||
|
deriving (Show,Read)
|
||||||
|
|
||||||
|
|
||||||
|
data HydraKeyInfo = HydraKeyInfo
|
||||||
|
{ _cardanoKeys :: KeyPair
|
||||||
|
, _hydraKeys :: KeyPair
|
||||||
|
}
|
||||||
|
deriving (Show,Read)
|
||||||
|
|
||||||
|
-- | Generate Cardano keys. Calling with an e.g. "my/keys/alice"
|
||||||
|
-- argument results in "my/keys/alice.cardano.{vk,sk}" keys being
|
||||||
|
-- written.
|
||||||
|
generateCardanoKeys :: (MonadIO m) => String -> m KeyPair
|
||||||
|
generateCardanoKeys path = do
|
||||||
|
output <- liftIO $
|
||||||
|
readCreateProcess
|
||||||
|
(proc cardanoCliPath [ "address"
|
||||||
|
, "key-gen"
|
||||||
|
, "--verification-key-file"
|
||||||
|
, [i|#{path}.cardano.vk|]
|
||||||
|
, "--signing-key-file"
|
||||||
|
, [i|#{path}.cardano.sk|]
|
||||||
|
])
|
||||||
|
""
|
||||||
|
liftIO $ putStrLn output
|
||||||
|
pure $ KeyPair [i|#{path}.cardano.sk|] [i|#{path}.cardano.vk|]
|
||||||
|
|
||||||
|
-- | Generate Hydra keys. Calling with an e.g. "my/keys/alice"
|
||||||
|
-- argument results in "my/keys/alice.hydra.{vk,sk}" keys being
|
||||||
|
-- written.
|
||||||
|
generateHydraKeys :: (MonadIO m) => String -> m KeyPair
|
||||||
|
generateHydraKeys path = do
|
||||||
|
output <- liftIO $
|
||||||
|
readCreateProcess
|
||||||
|
(proc hydraToolsPath [ "gen-hydra-key"
|
||||||
|
, "--output-file"
|
||||||
|
, [i|#{path}.hydra|]
|
||||||
|
])
|
||||||
|
""
|
||||||
|
liftIO $ putStrLn output
|
||||||
|
pure $ KeyPair [i|#{path}.hydra.sk|] [i|#{path}.hydra.vk|]
|
||||||
|
|
||||||
|
|
||||||
|
publishReferenceScripts :: (MonadIO m) => m HydraScriptTxId
|
||||||
|
publishReferenceScripts = do
|
||||||
|
liftIO . putStrLn $ "Publishing reference scripts ('νInitial' & 'νCommit')..."
|
||||||
|
fmap (T.strip . T.pack) $ liftIO $ readCreateProcess cp ""
|
||||||
|
where
|
||||||
|
cp = proc hydraNodePath [ "publish-scripts"
|
||||||
|
, "--network-id"
|
||||||
|
, show devnetNetworkId
|
||||||
|
, "--node-socket"
|
||||||
|
, "devnet/node.socket"
|
||||||
|
, "--cardano-signing-key"
|
||||||
|
, "devnet/credentials/faucet.sk"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
waitForTxIn :: (MonadIO m) => TxIn -> m ()
|
||||||
|
waitForTxIn txin = do
|
||||||
|
liftIO . putStrLn $ "Waiting for utxo " <> show txin <> ".."
|
||||||
|
liftIO waitFn
|
||||||
|
where
|
||||||
|
waitFn = do
|
||||||
|
exists <- txInExists txin
|
||||||
|
threadDelay 10000
|
||||||
|
unless exists waitFn
|
||||||
|
|
||||||
|
txInExists :: TxIn -> IO Bool
|
||||||
|
txInExists txin = do
|
||||||
|
result <- fmap (T.strip . T.pack) $ readCreateProcess cp "" >>= readProcess jqPath (pure $ ".\"" <> asStr <> "\"")
|
||||||
|
pure $ case result of
|
||||||
|
"null" -> False
|
||||||
|
_ -> True
|
||||||
|
where
|
||||||
|
asStr = T.unpack txin
|
||||||
|
cp = (proc cardanoCliPath [ "query"
|
||||||
|
, "utxo"
|
||||||
|
, "--tx-in"
|
||||||
|
, asStr
|
||||||
|
, "--out-file"
|
||||||
|
, "/dev/stdout"
|
||||||
|
, "--testnet-magic"
|
||||||
|
, "42"
|
||||||
|
]) { env = Just [("CARDANO_NODE_SOCKET_PATH", "devnet/node.socket")] }
|
||||||
|
|
||||||
|
txInput :: Int -> TxId -> TxIn
|
||||||
|
txInput index txid = txid <> "#" <> (T.pack . show) index
|
||||||
|
|
||||||
|
-- TODO: use this in checks?
|
||||||
|
minTxLovelace :: Int
|
||||||
|
minTxLovelace = 857690
|
||||||
|
|
||||||
|
queryAddressUTXOs :: MonadIO m => Address -> m WholeUTXO
|
||||||
|
queryAddressUTXOs addr = liftIO $ do
|
||||||
|
let queryProc =
|
||||||
|
(proc cardanoCliPath [ "query"
|
||||||
|
, "utxo"
|
||||||
|
, "--address"
|
||||||
|
, addr
|
||||||
|
, "--testnet-magic"
|
||||||
|
, "42"
|
||||||
|
, "--out-file"
|
||||||
|
, "/dev/stdout"
|
||||||
|
])
|
||||||
|
{ env = Just [("CARDANO_NODE_SOCKET_PATH", "devnet/node.socket")] }
|
||||||
|
str <- readCreateProcess queryProc ""
|
||||||
|
pure $ fromMaybe mempty $ decode $ BS.pack str
|
||||||
|
|
||||||
|
|
||||||
|
getTempPath' :: IO FilePath
|
||||||
|
getTempPath' = snd <$> getTempPath
|
||||||
|
|
||||||
|
getTempPath :: IO (UUID, FilePath)
|
||||||
|
getTempPath = do
|
||||||
|
createDirectoryIfMissing True "tmp"
|
||||||
|
uid <- UUIDV4.nextRandom
|
||||||
|
pure . (uid,) . ("tmp/" <>) . UUID.toString $ uid
|
||||||
|
|
||||||
|
-- TODO(skylar): Check lovelace vs the full amount!
|
||||||
|
buildSignedHydraTx :: SigningKey -> Address -> Address -> Map TxIn Lovelace -> Lovelace -> IO String
|
||||||
|
buildSignedHydraTx signingKey fromAddr toAddr txInAmounts amount = do
|
||||||
|
let fullAmount = sum txInAmounts
|
||||||
|
txBodyPath <- snd <$> getTempPath
|
||||||
|
void $ readCreateProcess (proc cardanoCliPath
|
||||||
|
([ "transaction"
|
||||||
|
, "build-raw"
|
||||||
|
, "--babbage-era"
|
||||||
|
]
|
||||||
|
<> (concatMap (\txin -> ["--tx-in", T.unpack txin]) . Map.keys $ txInAmounts)
|
||||||
|
<>
|
||||||
|
[ "--tx-out"
|
||||||
|
, [i|#{toAddr}+#{amount}|]
|
||||||
|
, "--tx-out"
|
||||||
|
, [i|#{fromAddr}+#{fullAmount - amount}|]
|
||||||
|
, "--fee"
|
||||||
|
, "0"
|
||||||
|
, "--out-file"
|
||||||
|
, txBodyPath
|
||||||
|
]))
|
||||||
|
""
|
||||||
|
readCreateProcess
|
||||||
|
(proc cardanoCliPath
|
||||||
|
[ "transaction"
|
||||||
|
, "sign"
|
||||||
|
, "--tx-body-file"
|
||||||
|
, txBodyPath
|
||||||
|
, "--signing-key-file"
|
||||||
|
, signingKey
|
||||||
|
, "--out-file"
|
||||||
|
, "/dev/stdout"
|
||||||
|
])
|
||||||
|
""
|
||||||
|
-- { env = Just [("CARDANO_NODE_SOCKET_PATH", "devnet/node.socket")] }
|
||||||
|
|
||||||
|
-- | Convenience for getting faucet Output for seeding
|
||||||
|
getFirstTxIn :: Address -> IO TxIn
|
||||||
|
getFirstTxIn addr =
|
||||||
|
readCreateProcess cp "" >>= readProcess jqPath ["-r", "keys[0]"] >>= \a -> pure $ T.strip $ T.pack a
|
||||||
|
where
|
||||||
|
cp = (proc cardanoCliPath [ "query"
|
||||||
|
, "utxo"
|
||||||
|
, "--address"
|
||||||
|
, addr
|
||||||
|
, "--testnet-magic"
|
||||||
|
, "42"
|
||||||
|
, "--out-file"
|
||||||
|
, "/dev/stdout"
|
||||||
|
]) { env = Just [("CARDANO_NODE_SOCKET_PATH", "devnet/node.socket")] }
|
||||||
|
|
||||||
|
|
||||||
|
getCardanoAddress :: VerificationKey -> IO Address
|
||||||
|
getCardanoAddress keyPath =
|
||||||
|
readCreateProcess cp ""
|
||||||
|
where
|
||||||
|
cp = (proc cardanoCliPath [ "address"
|
||||||
|
, "build"
|
||||||
|
, "--payment-verification-key-file"
|
||||||
|
, keyPath
|
||||||
|
, "--testnet-magic"
|
||||||
|
, "42"
|
||||||
|
]) { env = Just [("CARDANO_NODE_SOCKET_PATH", "devnet/node.socket")] }
|
||||||
|
|
||||||
|
|
||||||
|
getFaucetAddress :: IO Address
|
||||||
|
getFaucetAddress = readCreateProcess cp ""
|
||||||
|
where
|
||||||
|
cp = (proc cardanoCliPath [ "address"
|
||||||
|
, "build"
|
||||||
|
, "--payment-verification-key-file"
|
||||||
|
, "devnet/credentials/faucet.vk"
|
||||||
|
, "--testnet-magic"
|
||||||
|
, "42"
|
||||||
|
]) { env = Just [("CARDANO_NODE_SOCKET_PATH", "devnet/node.socket")] }
|
||||||
|
|
||||||
|
seedAddressFromFaucetAndWait :: (MonadIO m) => Address -> Lovelace -> Bool -> m TxIn
|
||||||
|
seedAddressFromFaucetAndWait addr amount isFuel = do
|
||||||
|
txin <- liftIO $ seedAddressFromFaucet addr amount isFuel
|
||||||
|
waitForTxIn txin
|
||||||
|
pure txin
|
||||||
|
|
||||||
|
-- | Send an amount in lovelace to the named actor
|
||||||
|
seedAddressFromFaucet :: Address -> Lovelace -> Bool -> IO TxIn
|
||||||
|
seedAddressFromFaucet addr amount isFuel = do
|
||||||
|
draftTx <- buildSeedTxForAddress addr amount isFuel
|
||||||
|
signedTx <- signSeedTx' draftTx
|
||||||
|
txin <- txInput 0 <$> seedTxIdFromSignedTx signedTx
|
||||||
|
submitTx signedTx
|
||||||
|
pure txin
|
||||||
|
|
||||||
|
|
||||||
|
buildSeedTxForAddress :: Address -> Lovelace -> Bool -> IO DraftTx
|
||||||
|
buildSeedTxForAddress addr amount isFuel = do
|
||||||
|
filename <- getTempPath'
|
||||||
|
-- when (amount < minTxLovelace) $ error $ "Minmum required UTxO: Lovelace " <> show minTxLovelace
|
||||||
|
let cp faucet hash = (proc cardanoCliPath $ filter (/= "")
|
||||||
|
[ "transaction"
|
||||||
|
, "build"
|
||||||
|
, "--babbage-era"
|
||||||
|
, "--cardano-mode"
|
||||||
|
, "--change-address"
|
||||||
|
, faucet
|
||||||
|
, "--tx-in"
|
||||||
|
, hash
|
||||||
|
, "--tx-out"
|
||||||
|
, addr <> "+" <> show amount
|
||||||
|
]
|
||||||
|
<> bool [] [ "--tx-out-datum-hash", T.unpack fuelMarkerDatumHash ] isFuel
|
||||||
|
<>
|
||||||
|
[ "--out-file"
|
||||||
|
, filename
|
||||||
|
, "--testnet-magic"
|
||||||
|
, "42"
|
||||||
|
])
|
||||||
|
{ env = Just [("CARDANO_NODE_SOCKET_PATH", "devnet/node.socket")] }
|
||||||
|
faucet <- getFaucetAddress
|
||||||
|
hash <- getFirstTxIn faucet
|
||||||
|
_ <- readCreateProcess (cp faucet (T.unpack hash)) ""
|
||||||
|
pure filename
|
||||||
|
|
||||||
|
|
||||||
|
signSeedTx' :: DraftTx -> IO SignedTx
|
||||||
|
signSeedTx' draftFile = do
|
||||||
|
outFile <- getTempPath'
|
||||||
|
let cp = (proc cardanoCliPath [ "transaction"
|
||||||
|
, "sign"
|
||||||
|
, "--tx-body-file"
|
||||||
|
, draftFile
|
||||||
|
, "--signing-key-file"
|
||||||
|
, "devnet/credentials/faucet.sk"
|
||||||
|
, "--out-file"
|
||||||
|
, outFile
|
||||||
|
, "--testnet-magic"
|
||||||
|
, "42"
|
||||||
|
])
|
||||||
|
{ env = Just [("CARDANO_NODE_SOCKET_PATH", "devnet/node.socket")] }
|
||||||
|
_ <- readCreateProcess cp ""
|
||||||
|
pure outFile
|
||||||
|
|
||||||
|
seedTxIdFromSignedTx :: SignedTx -> IO TxId
|
||||||
|
seedTxIdFromSignedTx filename =
|
||||||
|
T.strip . T.pack <$> readCreateProcess cp ""
|
||||||
|
where
|
||||||
|
cp = (proc cardanoCliPath [ "transaction"
|
||||||
|
, "txid"
|
||||||
|
, "--tx-file"
|
||||||
|
, filename
|
||||||
|
]) { env = Just [("CARDANO_NODE_SOCKET_PATH", "devnet/node.socket")] }
|
||||||
|
|
||||||
|
submitTx :: SignedTx -> IO ()
|
||||||
|
submitTx signedFile = do
|
||||||
|
_ <- readCreateProcess cp ""
|
||||||
|
pure ()
|
||||||
|
where
|
||||||
|
cp = (proc cardanoCliPath [ "transaction"
|
||||||
|
, "submit"
|
||||||
|
, "--tx-file"
|
||||||
|
, signedFile
|
||||||
|
, "--testnet-magic"
|
||||||
|
, "42"
|
||||||
|
]) { env = Just [("CARDANO_NODE_SOCKET_PATH", "devnet/node.socket")] }
|
1
src/Hydra/NodeTypes.hs
Normal file
1
src/Hydra/NodeTypes.hs
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
54
src/Hydra/ServerOutput.hs
Normal file
54
src/Hydra/ServerOutput.hs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
-- |
|
||||||
|
|
||||||
|
module Hydra.ServerOutput where
|
||||||
|
|
||||||
|
import GHC.Generics
|
||||||
|
import Data.Aeson
|
||||||
|
|
||||||
|
import Data.Time (UTCTime)
|
||||||
|
import Data.Text (Text)
|
||||||
|
import Hydra.Types
|
||||||
|
import Hydra.ClientInput
|
||||||
|
|
||||||
|
-- Copied and adapted from hydra-poc:hydra-node/src/hydra/ServerOutput.hs
|
||||||
|
-- Anything that took effort was replaced by Value
|
||||||
|
|
||||||
|
data ServerOutput tx
|
||||||
|
= PeerConnected {peer :: Host}
|
||||||
|
| PeerDisconnected {peer :: Host}
|
||||||
|
| ReadyToCommit {parties :: Value}
|
||||||
|
| Committed {party :: Party, utxo :: WholeUTXO}
|
||||||
|
| HeadIsOpen {utxo :: WholeUTXO}
|
||||||
|
| HeadIsClosed
|
||||||
|
{ snapshotNumber :: SnapshotNumber
|
||||||
|
, -- | Nominal deadline until which contest can be submitted and after
|
||||||
|
-- which fanout is possible. NOTE: Use this only for informational
|
||||||
|
-- purpose and wait for 'ReadyToFanout' instead before sending 'Fanout'
|
||||||
|
-- as the ledger of our cardano-node might not have progressed
|
||||||
|
-- sufficiently in time yet and we do not re-submit transactions (yet).
|
||||||
|
contestationDeadline :: UTCTime
|
||||||
|
}
|
||||||
|
| HeadIsContested {snapshotNumber :: SnapshotNumber}
|
||||||
|
| ReadyToFanout
|
||||||
|
| HeadIsAborted {utxo :: WholeUTXO}
|
||||||
|
| HeadIsFinalized {utxo :: WholeUTXO}
|
||||||
|
| CommandFailed {clientInput :: ClientInput}
|
||||||
|
| TxSeen {transaction :: tx}
|
||||||
|
| TxValid {transaction :: tx}
|
||||||
|
| TxInvalid {utxo :: WholeUTXO, transaction :: tx, validationError :: ValidationError}
|
||||||
|
| SnapshotConfirmed
|
||||||
|
{ snapshot :: Snapshot tx
|
||||||
|
, signatures :: MultiSignature (Snapshot tx)
|
||||||
|
}
|
||||||
|
| GetUTxOResponse {utxo :: WholeUTXO}
|
||||||
|
| InvalidInput {reason :: String, input :: Text}
|
||||||
|
| -- | A friendly welcome message which tells a client something about the
|
||||||
|
-- node. Currently used for knowing what signing key the server uses (it
|
||||||
|
-- only knows one).
|
||||||
|
Greetings {me :: Party}
|
||||||
|
| PostTxOnChainFailed {postChainTx :: PostChainTx tx, postTxError :: PostTxError tx}
|
||||||
|
| RolledBack
|
||||||
|
deriving (Eq, Show, Generic)
|
||||||
|
|
||||||
|
instance (ToJSON tx) => ToJSON (ServerOutput tx)
|
||||||
|
instance (FromJSON tx) => FromJSON (ServerOutput tx)
|
63
src/Hydra/Types.hs
Normal file
63
src/Hydra/Types.hs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
-- |
|
||||||
|
|
||||||
|
module Hydra.Types where
|
||||||
|
|
||||||
|
import GHC.Generics
|
||||||
|
import Data.Aeson
|
||||||
|
|
||||||
|
import Data.Map (Map)
|
||||||
|
import qualified Data.Text as T
|
||||||
|
import Data.Text (Text)
|
||||||
|
import Numeric.Natural (Natural)
|
||||||
|
|
||||||
|
-- | Cardano address
|
||||||
|
type Address = String
|
||||||
|
|
||||||
|
type Lovelace = Int
|
||||||
|
|
||||||
|
type TxIn = T.Text
|
||||||
|
type WholeUTXO = Map TxIn TxInInfo
|
||||||
|
|
||||||
|
data TxInInfo = TxInInfo
|
||||||
|
{ address :: Address
|
||||||
|
, datumhash :: Maybe T.Text
|
||||||
|
, value :: Map T.Text Int
|
||||||
|
}
|
||||||
|
deriving (Eq, Show, Generic)
|
||||||
|
|
||||||
|
instance FromJSON TxInInfo
|
||||||
|
instance ToJSON TxInInfo
|
||||||
|
|
||||||
|
fuelMarkerDatumHash :: T.Text
|
||||||
|
fuelMarkerDatumHash = "a654fb60d21c1fed48db2c320aa6df9737ec0204c0ba53b9b94a09fb40e757f3"
|
||||||
|
|
||||||
|
|
||||||
|
-- REVIEW(SN): This is also used in hydra-tui
|
||||||
|
|
||||||
|
-- Below various types copied/adapted from hydra-poc code
|
||||||
|
|
||||||
|
data Host = Host
|
||||||
|
{ hostname :: Text
|
||||||
|
, port :: PortNumber
|
||||||
|
}
|
||||||
|
deriving (Ord, Generic, Eq, Show)
|
||||||
|
|
||||||
|
instance ToJSON Host
|
||||||
|
instance FromJSON Host
|
||||||
|
|
||||||
|
|
||||||
|
newtype Party = Party {vkey :: T.Text}
|
||||||
|
deriving (Eq, Show, Read, Generic)
|
||||||
|
|
||||||
|
instance ToJSON Party
|
||||||
|
instance FromJSON Party
|
||||||
|
|
||||||
|
type UTxOType tx = Value
|
||||||
|
type Snapshot tx = Value
|
||||||
|
type MultiSignature x = Value
|
||||||
|
type PostChainTx tx = Value
|
||||||
|
type PostTxError tx = Value
|
||||||
|
type ValidationError = Value
|
||||||
|
type SnapshotNumber = Natural
|
||||||
|
type PortNumber = Natural
|
||||||
|
type ContestationPeriod = Natural
|
650
src/Main.hs
Normal file
650
src/Main.hs
Normal file
@ -0,0 +1,650 @@
|
|||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
{-# LANGUAGE PartialTypeSignatures #-}
|
||||||
|
{-# OPTIONS_GHC -Wno-unused-do-bind #-}
|
||||||
|
{-# LANGUAGE TupleSections #-}
|
||||||
|
{-# LANGUAGE ConstraintKinds #-}
|
||||||
|
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
|
||||||
|
|
||||||
|
|
||||||
|
module Main
|
||||||
|
|
||||||
|
(main)
|
||||||
|
|
||||||
|
where
|
||||||
|
|
||||||
|
import Prelude hiding (filter)
|
||||||
|
|
||||||
|
import Hydra.Devnet
|
||||||
|
|
||||||
|
import Control.Monad
|
||||||
|
|
||||||
|
import System.Directory
|
||||||
|
import Control.Monad.IO.Class (MonadIO, liftIO)
|
||||||
|
|
||||||
|
import qualified Data.Map as Map
|
||||||
|
import Data.Map (Map, (!))
|
||||||
|
import Data.Witherable
|
||||||
|
import Data.String.Interpolate ( i, iii, __i )
|
||||||
|
import qualified Data.Text as T
|
||||||
|
|
||||||
|
import Control.Concurrent
|
||||||
|
import System.Process
|
||||||
|
|
||||||
|
import Data.Aeson as Aeson
|
||||||
|
( decode, (.:), withObject, Value )
|
||||||
|
|
||||||
|
import Data.Aeson.Text (encodeToTextBuilder)
|
||||||
|
import Data.Text.Lazy (toStrict)
|
||||||
|
import Data.Text.Lazy.Builder (toLazyText)
|
||||||
|
|
||||||
|
import qualified Data.Map.Merge.Lazy as Map
|
||||||
|
import qualified Hydra.Types as HT
|
||||||
|
import Data.Maybe (fromJust, fromMaybe)
|
||||||
|
import Data.Aeson.Types (parseMaybe)
|
||||||
|
import System.IO (IOMode(WriteMode), openFile)
|
||||||
|
import Data.IORef (readIORef, writeIORef, IORef, newIORef)
|
||||||
|
import Hydra.Types
|
||||||
|
import Data.Text (Text)
|
||||||
|
import qualified Data.ByteString.Lazy.Char8 as ByteString.Char8
|
||||||
|
import Data.Time (UTCTime, diffUTCTime)
|
||||||
|
|
||||||
|
import Reflex
|
||||||
|
import Reflex.Dom
|
||||||
|
import Control.Monad.Fix
|
||||||
|
import Hydra.ClientInput
|
||||||
|
import Hydra.ServerOutput
|
||||||
|
import Data.Bool (bool)
|
||||||
|
import Text.Read (readMaybe)
|
||||||
|
import Data.Traversable (for)
|
||||||
|
import Data.Semigroup (First(getFirst, First))
|
||||||
|
import Data.Aeson
|
||||||
|
|
||||||
|
import Control.Monad.Trans (lift)
|
||||||
|
import Language.Javascript.JSaddle.Types ( MonadJSM )
|
||||||
|
|
||||||
|
standupDemoHydraNetwork :: (MonadIO m)
|
||||||
|
=> HydraScriptTxId
|
||||||
|
-> Map Text HydraKeyInfo
|
||||||
|
-> m (Map Text (ProcessHandle, HydraNodeInfo))
|
||||||
|
standupDemoHydraNetwork hstxid actors = do
|
||||||
|
liftIO $ createDirectoryIfMissing True "demo-logs"
|
||||||
|
liftIO $ sequence . flip Map.mapWithKey nodes $ \name node'' -> do
|
||||||
|
logHndl <- openFile [iii|demo-logs/hydra-node-#{name}.log|] WriteMode
|
||||||
|
errHndl <- openFile [iii|demo-logs/phydra-node-#{name}.error.log|] WriteMode
|
||||||
|
let cp = (mkHydraNodeCP sharedInfo node'' (filter ((/= _nodeId node'') . _nodeId) (Map.elems nodes)))
|
||||||
|
{ std_out = UseHandle logHndl
|
||||||
|
, std_err = UseHandle errHndl
|
||||||
|
}
|
||||||
|
(_,_,_,handle) <- createProcess cp
|
||||||
|
pure (handle, node'')
|
||||||
|
where
|
||||||
|
portNum p n = p * 1000 + n
|
||||||
|
node' (n, (name, keys)) =
|
||||||
|
( name
|
||||||
|
, HydraNodeInfo n (portNum 5 n) (portNum 9 n) (portNum 6 n) keys
|
||||||
|
)
|
||||||
|
nodes = Map.fromList . fmap node' $ zip [1 ..] (Map.toList actors)
|
||||||
|
sharedInfo = HydraSharedInfo
|
||||||
|
{ _hydraScriptsTxId = T.unpack hstxid
|
||||||
|
, _ledgerGenesis = "devnet/genesis-shelley.json"
|
||||||
|
, _ledgerProtocolParameters = "devnet/protocol-parameters.json"
|
||||||
|
, _networkId = show devnetMagic
|
||||||
|
, _nodeSocket = "devnet/node.socket"
|
||||||
|
}
|
||||||
|
|
||||||
|
-- | Takes the node participant and the list of peers
|
||||||
|
mkHydraNodeCP :: HydraSharedInfo -> HydraNodeInfo -> [HydraNodeInfo] -> CreateProcess
|
||||||
|
mkHydraNodeCP sharedInfo node peers =
|
||||||
|
(proc hydraNodePath $ sharedArgs sharedInfo <> nodeArgs node <> concatMap peerArgs peers)
|
||||||
|
{ std_out = Inherit
|
||||||
|
}
|
||||||
|
|
||||||
|
data HydraSharedInfo = HydraSharedInfo
|
||||||
|
{ _hydraScriptsTxId :: String
|
||||||
|
, _ledgerGenesis :: FilePath
|
||||||
|
, _ledgerProtocolParameters :: FilePath
|
||||||
|
, _networkId :: String
|
||||||
|
, _nodeSocket :: FilePath
|
||||||
|
}
|
||||||
|
|
||||||
|
data HydraNodeInfo = HydraNodeInfo
|
||||||
|
{ _nodeId :: Int
|
||||||
|
, _port :: Int
|
||||||
|
, _apiPort :: Int
|
||||||
|
, _monitoringPort :: Int
|
||||||
|
, _keys :: HydraKeyInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
sharedArgs :: HydraSharedInfo -> [String]
|
||||||
|
sharedArgs (HydraSharedInfo hydraScriptsTxId ledgerGenesis protocolParams networkId nodeSocket) =
|
||||||
|
[ "--ledger-genesis"
|
||||||
|
, ledgerGenesis
|
||||||
|
, "--ledger-protocol-parameters"
|
||||||
|
, protocolParams
|
||||||
|
, "--network-id"
|
||||||
|
, networkId
|
||||||
|
, "--node-socket"
|
||||||
|
, nodeSocket
|
||||||
|
, "--hydra-scripts-tx-id"
|
||||||
|
, hydraScriptsTxId
|
||||||
|
]
|
||||||
|
|
||||||
|
nodeArgs :: HydraNodeInfo -> [String]
|
||||||
|
nodeArgs (HydraNodeInfo nodeId port' apiPort monitoringPort
|
||||||
|
(HydraKeyInfo
|
||||||
|
(KeyPair cskPath _cvkPath)
|
||||||
|
(KeyPair hskPath _hvkPath))) =
|
||||||
|
[ "--node-id"
|
||||||
|
, show nodeId
|
||||||
|
, "--port"
|
||||||
|
, show port'
|
||||||
|
, "--api-port"
|
||||||
|
, show apiPort
|
||||||
|
, "--monitoring-port"
|
||||||
|
, show monitoringPort
|
||||||
|
, "--hydra-signing-key"
|
||||||
|
, hskPath
|
||||||
|
, "--cardano-signing-key"
|
||||||
|
, cskPath
|
||||||
|
]
|
||||||
|
|
||||||
|
peerArgs :: HydraNodeInfo -> [String]
|
||||||
|
peerArgs ni =
|
||||||
|
[ "--peer"
|
||||||
|
, [i|127.0.0.1:#{_port ni}|]
|
||||||
|
, "--hydra-verification-key"
|
||||||
|
, _verificationKey . _hydraKeys . _keys $ ni
|
||||||
|
, "--cardano-verification-key"
|
||||||
|
, _verificationKey . _cardanoKeys . _keys $ ni
|
||||||
|
]
|
||||||
|
|
||||||
|
cardanoNodeCreateProcess :: CreateProcess
|
||||||
|
cardanoNodeCreateProcess =
|
||||||
|
(proc cardanoNodePath
|
||||||
|
[ "run"
|
||||||
|
, "--config"
|
||||||
|
, "devnet/cardano-node.json"
|
||||||
|
, "--topology"
|
||||||
|
, "devnet/topology.json"
|
||||||
|
, "--database-path"
|
||||||
|
, "devnet/db"
|
||||||
|
, "--socket-path"
|
||||||
|
, "devnet/node.socket"
|
||||||
|
, "--shelley-operational-certificate"
|
||||||
|
, "devnet/opcert.cert"
|
||||||
|
, "--shelley-kes-key"
|
||||||
|
, "devnet/kes.skey"
|
||||||
|
, "--shelley-vrf-key"
|
||||||
|
, "devnet/vrf.skey"
|
||||||
|
]) { std_out = CreatePipe
|
||||||
|
}
|
||||||
|
|
||||||
|
runHydraDemo :: (MonadIO m)
|
||||||
|
=> HydraDemo
|
||||||
|
-> m (Map Text ( ProcessHandle
|
||||||
|
, Address -- Cardano address
|
||||||
|
, HydraNodeInfo
|
||||||
|
))
|
||||||
|
runHydraDemo nodes = do
|
||||||
|
keysAddresses <- forM nodes $ \(actorSeed, fuelSeed) -> do
|
||||||
|
keys@(HydraKeyInfo (KeyPair _ vk) _) <- generateKeys
|
||||||
|
addr <- liftIO $ getCardanoAddress vk
|
||||||
|
void $ seedAddressFromFaucetAndWait addr actorSeed False
|
||||||
|
void $ seedAddressFromFaucetAndWait addr fuelSeed True
|
||||||
|
pure (keys, addr)
|
||||||
|
liftIO . putStrLn $ "Publishing reference scripts"
|
||||||
|
hstxid <- publishReferenceScripts
|
||||||
|
handles <- standupDemoHydraNetwork hstxid (fmap fst keysAddresses)
|
||||||
|
liftIO . putStrLn $ [i|"Hydra Network Running for nodes #{Map.keys nodes}|]
|
||||||
|
pure $ Map.merge Map.dropMissing Map.dropMissing (Map.zipWithMatched (\_ addr (handle, nodeInfo) -> (handle, addr, nodeInfo))) (fmap snd keysAddresses) handles
|
||||||
|
|
||||||
|
|
||||||
|
type State = Map Text ( ProcessHandle
|
||||||
|
, Address -- Cardano address
|
||||||
|
, HydraNodeInfo
|
||||||
|
)
|
||||||
|
|
||||||
|
headElement :: forall t m. ( TriggerEvent t m, DomBuilder t m) =>m ()
|
||||||
|
headElement = do
|
||||||
|
el "title" $ text "Hydra Head Demo"
|
||||||
|
elAttr "script" ("src"=:"https://cdn.tailwindcss.com") blank
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = liftIO $ do
|
||||||
|
prepareDevnet
|
||||||
|
withCreateProcess cardanoNodeCreateProcess $ \_ _stdout _ _handle -> do
|
||||||
|
putStrLn "Devnet is running"
|
||||||
|
threadDelay $ seconds 3
|
||||||
|
mainWidgetWithHead headElement app
|
||||||
|
|
||||||
|
makeTx :: () => IORef State -> Text
|
||||||
|
-> Map TxIn TxInInfo -> Lovelace -> Text -> IO Text
|
||||||
|
makeTx hydraProcessHandlesRef fromName utxos lovelace toName = do
|
||||||
|
print (fromName, utxos, toName)
|
||||||
|
let lovelaceUtxos = mapMaybe (Map.lookup "lovelace" . HT.value) utxos
|
||||||
|
actors <- readIORef hydraProcessHandlesRef
|
||||||
|
jsonStr <-
|
||||||
|
buildSignedHydraTx
|
||||||
|
(_signingKey . _cardanoKeys . _keys . (\(_, _, hn) -> hn) $ actors ! fromName)
|
||||||
|
((\(_, addr, _) -> addr) $ actors ! fromName)
|
||||||
|
((\(_, addr, _) -> addr) $ actors ! toName)
|
||||||
|
lovelaceUtxos
|
||||||
|
lovelace
|
||||||
|
let jsonTx :: Aeson.Value = fromMaybe (error "Failed to parse TX") . Aeson.decode . ByteString.Char8.pack $ jsonStr
|
||||||
|
pure . fromJust . parseMaybe (withObject "signed tx" (.: "cborHex")) $ jsonTx
|
||||||
|
|
||||||
|
startDemo :: MonadIO m => IORef State -> HydraDemo -> m RunningNodes
|
||||||
|
startDemo hydraProcessHandlesRef demo = do
|
||||||
|
liftIO (mapM (terminateProcess . (\(hndl, _, _) -> hndl)) =<< readIORef hydraProcessHandlesRef)
|
||||||
|
nodeInfos <- runHydraDemo demo
|
||||||
|
liftIO . writeIORef hydraProcessHandlesRef $ nodeInfos
|
||||||
|
actorList :: RunningNodes <- forM nodeInfos $ \(_, addr, nInfo) -> do
|
||||||
|
pure
|
||||||
|
( addr,
|
||||||
|
[iii|ws://localhost:#{_apiPort nInfo}|]
|
||||||
|
)
|
||||||
|
pure actorList
|
||||||
|
|
||||||
|
-- | Friendly name for a Hydra node.
|
||||||
|
type DemoNodeName = Text
|
||||||
|
|
||||||
|
-- | WebSocket URL
|
||||||
|
type ApiUrl = Text
|
||||||
|
|
||||||
|
type RunningNodes = Map DemoNodeName ( Address -- Cardano address
|
||||||
|
, ApiUrl
|
||||||
|
)
|
||||||
|
|
||||||
|
type HydraDemo = Map
|
||||||
|
DemoNodeName
|
||||||
|
( Lovelace -- Seed for actor
|
||||||
|
, Lovelace -- Seed for fuel
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
seconds :: Int -> Int
|
||||||
|
seconds = (* 1000000)
|
||||||
|
|
||||||
|
alicebobcarolDemo :: HydraDemo
|
||||||
|
alicebobcarolDemo = Map.fromList [("Alice", (1000000000, 100000000)), ("Bob", (500000000, 100000000)), ("Carol", (250000000, 100000000))]
|
||||||
|
|
||||||
|
|
||||||
|
filterOutFuel :: WholeUTXO -> WholeUTXO
|
||||||
|
filterOutFuel = Map.filter (not . isFuel)
|
||||||
|
|
||||||
|
isFuel :: TxInInfo -> Bool
|
||||||
|
isFuel txinfo = datumhash txinfo == Just fuelMarkerDatumHash
|
||||||
|
|
||||||
|
-- | Tracks the state of the head based on Hydra Node responses
|
||||||
|
data HeadState
|
||||||
|
= Idle
|
||||||
|
| Initializing
|
||||||
|
| Open
|
||||||
|
| Closed UTCTime
|
||||||
|
| StateReadyToFanout
|
||||||
|
deriving (Eq, Show)
|
||||||
|
|
||||||
|
|
||||||
|
buttonClass :: (PostBuild t m, DomBuilder t m) => Dynamic t T.Text -> m b -> m (Event t ())
|
||||||
|
buttonClass cls content = do
|
||||||
|
(buttonEl, _) <- elDynClass' "button" cls content
|
||||||
|
pure $ domEvent Click buttonEl
|
||||||
|
|
||||||
|
|
||||||
|
utxoPicker :: forall t m. (DomBuilder t m, MonadFix m, MonadHold t m, PostBuild t m) => Bool -> WholeUTXO -> m (Dynamic t (Maybe WholeUTXO))
|
||||||
|
utxoPicker pickable wholeUtxo = mdo
|
||||||
|
elClass "div" "font-semibold text-lg mb-2" $ text "UTxOs"
|
||||||
|
|
||||||
|
currentUtxo <- holdDyn Nothing selectedUtxo
|
||||||
|
selectedUtxo <- fmap (leftmost . Map.elems) $ elClass "div" "flex flex-row flex-wrap gap-2" $ flip Map.traverseWithKey wholeUtxo $ \k v -> mdo
|
||||||
|
let amiSelected = maybe False ((k ==) . fst) <$> currentUtxo
|
||||||
|
let cls = ("text-white font-bold text-xl px-4 py-2 rounded-md flex flex-row cursor-pointer mr-2 " <>)
|
||||||
|
. bool
|
||||||
|
"bg-gray-500 hover:bg-gray-400 active:bg-gray-300"
|
||||||
|
"bg-blue-500 hover:bg-blue-400 active:bg-blue-300"
|
||||||
|
<$> amiSelected
|
||||||
|
(buttonEl, _) <- elDynClass' "button" cls $ do
|
||||||
|
elClass "div" "text-sm text-gray-300 font-semibold flex justify-between" $ do
|
||||||
|
elClass "div" "flex flex-col" $ do
|
||||||
|
elClass "div" "w-full flex flex-row justify-between" $ do
|
||||||
|
elClass "div" "text-gray-400 mr-4" $ text "lovelace"
|
||||||
|
when (isFuel v) $ elClass "div" "px-2 py-0 flex items-center justify-center leading-node bg-green-500 text-xs text-white font-semibold text-sm rounded-full flex" $
|
||||||
|
el "div" $ text "FUEL"
|
||||||
|
elClass "div" "text-lg text-left font-semibold" $ text $ maybe "" (T.pack . show) (Map.lookup "lovelace" $ HT.value v)
|
||||||
|
|
||||||
|
pure $ bool Nothing (Just (k, v)) . (pickable &&) . not <$> current amiSelected <@ domEvent Click buttonEl
|
||||||
|
pure $ fmap (uncurry Map.singleton) <$> currentUtxo
|
||||||
|
|
||||||
|
demoSettings :: (DomBuilder t m, PostBuild t m, MonadHold t m, MonadFix m) => HydraDemo -> m (Dynamic t HydraDemo)
|
||||||
|
demoSettings setngs = elClass "div" "flex flex-col pl-4 pr-4" $ do
|
||||||
|
let initSize = Map.size setngs
|
||||||
|
let initialList = Map.fromList (zip [1 .. ] (Map.toList setngs))
|
||||||
|
rec
|
||||||
|
nextIdentityNumber <- fmap (1 + initSize +) <$> count newNode
|
||||||
|
let updates =
|
||||||
|
((\n -> Map.singleton n (Just ([i|Node #{n}|], (100000000, 100000000)))) <$> current nextIdentityNumber <@ newNode)
|
||||||
|
<> deleteEs
|
||||||
|
(((), deleteEs), demoDyn) <- runDynamicWriterT $ runEventWriterT $ void $ elClass "div" "flex-col space-y-2" $ do
|
||||||
|
elClass "p" "text-white text-2xl my-4" $ text "Configure a Hydra Head by specifying the node names and their initial funds in Lovelace."
|
||||||
|
listHoldWithKey initialList updates $ \k (name, (actorSeed, _hydraSeed)) -> elClass "div" "flex flex-col" $ do
|
||||||
|
name' <- elClass "div" "flex flex-row space-x-2" $ do
|
||||||
|
name' <- fmap _inputElement_value . inputElement $
|
||||||
|
def & inputElementConfig_initialValue .~ name
|
||||||
|
& initialAttributes .~ ("class" =: "text-white bg-gray-800 text-2xl font-bold focus:outline-none p-2" <> "type" =: "text")
|
||||||
|
amount' <- fmap _inputElement_value . inputElement $
|
||||||
|
def & inputElementConfig_initialValue .~ (T.pack . show $ actorSeed)
|
||||||
|
& initialAttributes .~ ("class" =: "text-white bg-gray-800 text-2xl font-bold focus:outline-none p-2" <> "type" =: "number")
|
||||||
|
deleteE <- buttonClass "bg-gray-400 hover:bg-gray-300 active:bg-gray-200 text-white font-bold text-xl px-4 py-2 rounded-md" $
|
||||||
|
text "×"
|
||||||
|
let actorSeed' = (\n a -> (n,) <$> readMaybe (T.unpack a)) <$> name' <*> amount'
|
||||||
|
tellDyn (maybe mempty (Map.singleton k. (\(actor,sd) -> (actor, (sd, 100000000)))) <$> actorSeed')
|
||||||
|
tellEvent (Map.singleton k Nothing <$ deleteE)
|
||||||
|
pure name'
|
||||||
|
let hasDuplicateName = (\n ns -> (> 1) . Map.size . Map.filter (\(n',_) -> n == n') $ ns) <$> name' <*> demoDyn
|
||||||
|
let duplicateNameMsg = elClass "div" "text-red-400 m-2" $ text "Duplicate name"
|
||||||
|
dyn_ (bool blank duplicateNameMsg <$> fromUniqDynamic (uniqDynamic hasDuplicateName))
|
||||||
|
pure ()
|
||||||
|
newNode <- buttonClass "bg-gray-400 hover:bg-gray-300 active:bg-gray-200 text-white font-bold text-xl my-4 px-4 py-2 rounded-md w-32" $
|
||||||
|
text "Add node"
|
||||||
|
let demoDyn' = Map.fromList . Map.elems <$> demoDyn
|
||||||
|
pure demoDyn'
|
||||||
|
|
||||||
|
startStopDemoControls ::
|
||||||
|
( DomBuilder t m,
|
||||||
|
MonadFix m,
|
||||||
|
PostBuild t m,
|
||||||
|
MonadHold t m, MonadIO (Performable m), PerformEvent t m) =>
|
||||||
|
IORef State ->
|
||||||
|
m (Event t RunningNodes)
|
||||||
|
startStopDemoControls hydraProcessHandlesRef = mdo
|
||||||
|
headRunning <- toggle False headStartedOrStoppedE
|
||||||
|
((), demoConfig) <- runDynamicWriterT $ dyn_ (bool (tellDyn =<< demoSettings alicebobcarolDemo) blank <$> headRunning)
|
||||||
|
startStopHeadE <- buttonClass ((\running ->
|
||||||
|
let color :: Text = bool "green" "red" running
|
||||||
|
in [__i|bg-#{color}-500 hover:bg-#{color}-400 active:bg-#{color}-300
|
||||||
|
text-white font-bold text-xl m-4 px-4 py-2 rounded-md|]
|
||||||
|
:: Text)
|
||||||
|
<$> headRunning)
|
||||||
|
$ dynText (bool "Start head" "Stop head" <$> headRunning)
|
||||||
|
let startStopWithConfE = current demoConfig <@ startStopHeadE
|
||||||
|
headStartedOrStoppedE <- performEvent $
|
||||||
|
-- Start with mempty to stop the demo:
|
||||||
|
(\running conf -> startDemo hydraProcessHandlesRef $ bool conf mempty running)
|
||||||
|
<$> current headRunning
|
||||||
|
<@> startStopWithConfE
|
||||||
|
let headStartingDom conf =
|
||||||
|
if Map.null conf
|
||||||
|
then blank
|
||||||
|
else elClass "div" "text-white text-2xl m-4" $ text "Head starting..."
|
||||||
|
void $ runWithReplace blank $ leftmost [ headStartingDom <$> startStopWithConfE
|
||||||
|
, blank <$ headStartedOrStoppedE
|
||||||
|
]
|
||||||
|
pure headStartedOrStoppedE
|
||||||
|
|
||||||
|
|
||||||
|
app ::
|
||||||
|
forall t m.
|
||||||
|
( PostBuild t m,
|
||||||
|
DomBuilder t m,
|
||||||
|
MonadFix m,
|
||||||
|
MonadJSM m, MonadJSM (Performable m),
|
||||||
|
MonadHold t m, PerformEvent t m, TriggerEvent t m) =>
|
||||||
|
m ()
|
||||||
|
app = do
|
||||||
|
hydraProcessHandlesRef :: IORef State <- liftIO (newIORef mempty)
|
||||||
|
elClass "div" "w-screen h-screen bg-gray-900 overflow-y-scroll overflow-x-hidden" $ do
|
||||||
|
elClass "div" "p-4 m-4 text-white text-5xl font-bold" $ text "Hydra Proof Of Concept Demo"
|
||||||
|
mdo
|
||||||
|
headStartedE <- startStopDemoControls hydraProcessHandlesRef
|
||||||
|
void $ runWithReplace blank $ ffor headStartedE $ \actors -> mdo
|
||||||
|
let actorNames = ffor (Map.toList actors) $ \(name, (_,_)) -> name
|
||||||
|
headState <- holdDyn Idle newState
|
||||||
|
let headStateDom = elClass "div" "text-lg" . text . ("Head State: " <>)
|
||||||
|
unless (null actors) $ elClass "div" "ml-4 mt-8 mr-4 mb-2 w-full font-black text-green-500" $ dyn_ $ ffor headState $ \case
|
||||||
|
Idle -> do
|
||||||
|
headStateDom "Idle"
|
||||||
|
elClass "div" "text-green-700 text-sm" $ text "Waiting for participant to init..."
|
||||||
|
Initializing -> do
|
||||||
|
headStateDom "Initializing"
|
||||||
|
elClass "div" "text-green-700 text-sm" $ text $ "Waiting for commits from: " <> T.intercalate ", " actorNames
|
||||||
|
Open -> headStateDom "Open"
|
||||||
|
Closed _ -> headStateDom "Closed/Contestation period"
|
||||||
|
StateReadyToFanout -> headStateDom "Ready to fanout"
|
||||||
|
|
||||||
|
newState <- elClass "div" "ml-4 mr-4 overflow-hidden rounded-lg hover:drop-shadow-xl transition-all drop-shadow bg-gray-800" $ mdo
|
||||||
|
rec
|
||||||
|
currentTab <- holdDyn (head actorNames) changeTab
|
||||||
|
|
||||||
|
changeTab <- fmap leftmost $ elClass "div" "w-full flex flex-row justify-start" $ for actorNames $ \name -> do
|
||||||
|
let
|
||||||
|
isSelected = (== name) <$> currentTab
|
||||||
|
mkClasses selected =
|
||||||
|
T.intercalate " " [ "leading-none p-4 font-bold text-2xl text-gray-100 flex items-center justify-center"
|
||||||
|
, bool "bg-gray-800 text-gray-300 pointer-cursor" "bg-gray-700 text-gray-100" selected
|
||||||
|
]
|
||||||
|
(buttonEl, _) <- elDynClass' "button" (mkClasses <$> isSelected) $ text name
|
||||||
|
pure $ name <$ domEvent Click buttonEl
|
||||||
|
fmap (fmap getFirst . snd) . runEventWriterT $ forM (Map.toList actors) $ \(name, (actorAddress, wsUrl)) -> mdo
|
||||||
|
let wsCfg = (WebSocketConfig @t @ClientInput) action never True []
|
||||||
|
ws <- jsonWebSocket wsUrl wsCfg
|
||||||
|
let isSelected = (== name) <$> currentTab
|
||||||
|
let mkClasses selected =
|
||||||
|
T.intercalate " " [ "p-2 bg-gray-700 text-white flex flex-col items-left"
|
||||||
|
, bool "hidden" "" selected
|
||||||
|
]
|
||||||
|
(_, action) <- elDynClass "div" (mkClasses <$> isSelected) $ runEventWriterT $ runWithReplace (elClass "div" "text-white" $ text "Connecting to node...") . ffor (_webSocket_open ws) $ \() -> do
|
||||||
|
let
|
||||||
|
webSocketMessage :: Event t (ServerOutput Aeson.Value) =
|
||||||
|
fromMaybe (error "Parsing message from Hydra node failed") <$> _webSocket_recv ws
|
||||||
|
processLog = \case
|
||||||
|
ReadyToCommit {} -> Just Initializing
|
||||||
|
HeadIsOpen {} -> Just Open
|
||||||
|
HeadIsClosed _ fanoutTime -> Just (Closed fanoutTime)
|
||||||
|
ReadyToFanout {} -> Just StateReadyToFanout
|
||||||
|
HeadIsAborted {} -> Just Idle
|
||||||
|
HeadIsFinalized {} -> Just Idle
|
||||||
|
_ -> Nothing
|
||||||
|
let stateChange = fmapMaybe processLog webSocketMessage
|
||||||
|
let
|
||||||
|
|
||||||
|
myVKeyB :: Behavior t (Maybe T.Text) <-
|
||||||
|
hold Nothing
|
||||||
|
. fmap Just
|
||||||
|
. mapMaybe (\case
|
||||||
|
Greetings (Party vkey') -> Just vkey'
|
||||||
|
_ -> Nothing)
|
||||||
|
$ webSocketMessage
|
||||||
|
headStateE <- mdo
|
||||||
|
void $ dyn $ ffor headState $ \case
|
||||||
|
Idle -> idleScreen name
|
||||||
|
Initializing -> initializingScreen actorAddress myVKeyB webSocketMessage
|
||||||
|
Open -> openScreen hydraProcessHandlesRef name actorNames actorAddress webSocketMessage
|
||||||
|
Closed fanoutTime -> closedScreen fanoutTime
|
||||||
|
StateReadyToFanout ->
|
||||||
|
tellAction
|
||||||
|
. (Fanout <$)
|
||||||
|
<=< buttonClass "bg-green-400 hover:bg-green-400 active:bg-green-200 text-white font-bold text-xl my-2 px-4 py-2 rounded-md w-32" $ text "Do fanout"
|
||||||
|
elClass "div" "mt-4" $ do
|
||||||
|
elClass "div" "mb-1 font-semibold text-sm" $ text "Hydra Node Log"
|
||||||
|
elClass "div" "p-2 bg-gray-800 rounded-md drop-shadow" $
|
||||||
|
el "ul" $ do
|
||||||
|
comms <- foldDyn (++) [] $
|
||||||
|
((:[]) . ("Rcv: " <>) . toStrict . toLazyText . encodeToTextBuilder . toJSON <$> webSocketMessage)
|
||||||
|
<>
|
||||||
|
fmap (fmap (("Snd: " <>) . toStrict . toLazyText . encodeToTextBuilder . toJSON)) action
|
||||||
|
dyn_ $ mapM (el "li" . text) <$> comms
|
||||||
|
pure stateChange
|
||||||
|
lift $ tellEvent (First <$> headStateE)
|
||||||
|
pure ()
|
||||||
|
pure ()
|
||||||
|
|
||||||
|
filterUtxos :: Address -> WholeUTXO -> WholeUTXO
|
||||||
|
filterUtxos addr = Map.filter ((== addr) . HT.address)
|
||||||
|
|
||||||
|
tellAction :: (EventWriter t [a] m, Reflex t) => Event t a -> m ()
|
||||||
|
tellAction = tellEvent . fmap (:[])
|
||||||
|
|
||||||
|
idleScreen :: (EventWriter t [ClientInput] m, DomBuilder t m) => Text -> m ()
|
||||||
|
idleScreen name =
|
||||||
|
elClass "div" "p-2 flex flex-row" $ do
|
||||||
|
(buttonEl, _) <- elClass' "button" "bg-blue-500 hover:bg-blue-400 active:bg-blue-300 text-white font-bold text-xl px-4 py-2 rounded-md" $ text $ "Initialize head as " <> name
|
||||||
|
tellAction $ Init 10 <$ domEvent Click buttonEl
|
||||||
|
|
||||||
|
initializingScreen ::
|
||||||
|
( EventWriter t [ClientInput] m,
|
||||||
|
DomBuilder t m,
|
||||||
|
MonadFix m,
|
||||||
|
MonadHold t m,
|
||||||
|
PostBuild t m, MonadIO m) =>
|
||||||
|
Address ->
|
||||||
|
Behavior t (Maybe Text) ->
|
||||||
|
Event t (ServerOutput tx) ->
|
||||||
|
m ()
|
||||||
|
initializingScreen actorAddress myVKeyB webSocketMessage = do
|
||||||
|
elClass "div" "p-2 flex flex-col" $ do
|
||||||
|
-- TODO: did not use performEvent here
|
||||||
|
newUTXOs <- liftIO $ queryAddressUTXOs actorAddress -- fmapMaybe eitherToMaybe <$> (undefined . (DemoApi_GetActorUTXO actorAddress <$) =<< getPostBuild)
|
||||||
|
let commitSelection doCommit = do
|
||||||
|
(_, currentSet) <-
|
||||||
|
runDynamicWriterT $ (tellDyn <=< utxoPicker True) newUTXOs
|
||||||
|
-- runWithReplace (elClass "div" "p-4 bg-gray-800 rounded mb-2" $ text $ "Getting " <> name <> "'s UTXOs...") $
|
||||||
|
-- (tellDyn <=< utxoPicker True) <$> newUTXOs
|
||||||
|
tellAction $ fmap (Commit . fromMaybe mempty) $ current currentSet <@ doCommit
|
||||||
|
let hasCommitted =
|
||||||
|
attachWithMaybe
|
||||||
|
( \mvkey -> \case
|
||||||
|
Committed (Party vk) _ -> guard (Just vk == mvkey)
|
||||||
|
_ -> Nothing
|
||||||
|
)
|
||||||
|
myVKeyB
|
||||||
|
webSocketMessage
|
||||||
|
|
||||||
|
mdo
|
||||||
|
void . runWithReplace (commitSelection doCommit) . ffor hasCommitted $ \() ->
|
||||||
|
elClass "div" "text-xl py-4" $ text "Committed, waiting for the others."
|
||||||
|
doCommit <- elClass "div" "flex flex-row mt-4" $ do
|
||||||
|
-- Until the head is committed starting the head can be aborted:
|
||||||
|
tellAction
|
||||||
|
. (Hydra.ClientInput.Abort <$)
|
||||||
|
<=< buttonClass "bg-gray-400 hover:bg-gray-300 active:bg-gray-200 text-white font-bold text-xl px-4 py-2 rounded-md mr-2"
|
||||||
|
$ text "Abort"
|
||||||
|
isDisabled <- holdDyn False (True <$ hasCommitted)
|
||||||
|
let cls =
|
||||||
|
(bool "bg-blue-500 hover:bg-blue-400 active:bg-blue-300" "bg-gray-500 hover:bg-gray-500 active:bg-gray-500 cursor-not-allowed " <$> isDisabled)
|
||||||
|
<> " text-white font-bold text-xl px-4 py-2 rounded-md"
|
||||||
|
buttonClass cls $ text "Commit"
|
||||||
|
pure ()
|
||||||
|
pure ()
|
||||||
|
|
||||||
|
|
||||||
|
openScreen ::
|
||||||
|
( EventWriter t [ClientInput] m,
|
||||||
|
DomBuilder t m,
|
||||||
|
MonadFix m,
|
||||||
|
MonadHold t m,
|
||||||
|
PostBuild t m,
|
||||||
|
MonadIO (Performable m), PerformEvent t m) =>
|
||||||
|
IORef State ->
|
||||||
|
Text ->
|
||||||
|
[Text] ->
|
||||||
|
Address ->
|
||||||
|
Event t (ServerOutput tx) ->
|
||||||
|
m ()
|
||||||
|
openScreen hydraProcessHandlesRef name actorNames actorAddress webSocketMessage = do
|
||||||
|
-- Get your UTxOs on page load and when we observe a transaction
|
||||||
|
tellAction . (GetUTxO <$)
|
||||||
|
. ( ( void $
|
||||||
|
filter
|
||||||
|
( \case
|
||||||
|
TxSeen {} -> True
|
||||||
|
_ -> False
|
||||||
|
)
|
||||||
|
webSocketMessage
|
||||||
|
)
|
||||||
|
<>
|
||||||
|
)
|
||||||
|
=<< getPostBuild
|
||||||
|
let updatedUTXOs =
|
||||||
|
fmap (filterUtxos actorAddress)
|
||||||
|
. mapMaybe
|
||||||
|
( \case
|
||||||
|
GetUTxOResponse utxoz -> Just utxoz
|
||||||
|
_ -> Nothing
|
||||||
|
)
|
||||||
|
$ webSocketMessage
|
||||||
|
currentUTXOs <- holdDyn mempty updatedUTXOs
|
||||||
|
let ifUTXOs yes no = dyn_ (bool yes no <$> fmap Map.null currentUTXOs)
|
||||||
|
ifUTXOsDyn yes no = dyn (bool yes no <$> fmap Map.null currentUTXOs)
|
||||||
|
mdo
|
||||||
|
(_, currentSet) <-
|
||||||
|
runDynamicWriterT
|
||||||
|
. runWithReplace (elClass "div" "text-white text-2xl" $ text "Getting your UTxOs")
|
||||||
|
$ fmap (tellDyn <=< (pure . pure . filterOutFuel)) updatedUTXOs
|
||||||
|
_ <- elClass "div" "mb-4 ml-2" $ dyn_ $ utxoPicker False <$> currentSet
|
||||||
|
elClass "div" "text-xl mb-8 ml-2" $ ifUTXOs (text "Send Ada to a participant:") (text "No UTXOs for this participant")
|
||||||
|
flip ifUTXOs blank $ do
|
||||||
|
(recipientDyn, lovelaceDyn) <- elClass "div" "flex ml-2 mb-2" $
|
||||||
|
elClass "div" "w-auto flex flex-row rounded bg-gray-800 mb-2 overflow-hidden" $ do
|
||||||
|
ie <- elClass "div" "flex flex-col p-2" $ do
|
||||||
|
elClass "div" "text-gray-600 text-sm font-semibold" $ text "LOVELACES"
|
||||||
|
inputElement $
|
||||||
|
def
|
||||||
|
& initialAttributes .~ ("class" =: "bg-gray-800 text-2xl font-bold focus:outline-none p-2" <> "type" =: "number")
|
||||||
|
& inputElementConfig_initialValue .~ "1000000"
|
||||||
|
recipient <- fmap Reflex.Dom.value $
|
||||||
|
elClass "div" "flex flex-col p-2" $ do
|
||||||
|
elClass "div" "text-gray-600 text-sm font-semibold uppercase" $ text "To"
|
||||||
|
-- FIXME: unsafe head, will crash with <= 1 actors
|
||||||
|
dropdown
|
||||||
|
(head $ filter (/= name) actorNames)
|
||||||
|
(pure (Map.filter (/= name) $ Map.fromList (fmap (\n -> (n, n)) actorNames)))
|
||||||
|
$ def & dropdownConfig_attributes .~ pure ("class" =: "bg-gray-800 hover:bg-gray-700 active:bg-gray-900 text-gray-100 font-semibold text-xl px-4 py-2 rounded-md m-2")
|
||||||
|
pure (recipient, readMaybe . T.unpack <$> _inputElement_value ie)
|
||||||
|
elClass "div" "flex" $ do
|
||||||
|
signedTxE <-
|
||||||
|
performEvent . fmap liftIO $
|
||||||
|
makeTx hydraProcessHandlesRef name
|
||||||
|
<$> current currentSet
|
||||||
|
-- NOTE/TODO(skylar): This is just to default to the minimum
|
||||||
|
<*> current (fromMaybe 1000000 <$> lovelaceDyn)
|
||||||
|
<*> current recipientDyn
|
||||||
|
<@ doSend
|
||||||
|
tellAction
|
||||||
|
. fmap NewTx
|
||||||
|
$ signedTxE
|
||||||
|
|
||||||
|
doSend <- elClass "div" "flex flex-row ml-2" $ do
|
||||||
|
sendButtonClick <- flip ifUTXOsDyn (pure never) $ do
|
||||||
|
buttonClass "bg-green-500 hover:bg-green-400 active:bg-green-200 text-white font-bold text-xl mr-2 px-4 py-2 rounded-md" $ text "Send"
|
||||||
|
tellAction
|
||||||
|
. (Close <$)
|
||||||
|
<=< buttonClass "bg-red-500 hover:bg-red-400 active:bg-red-200 text-white font-bold text-xl px-4 py-2 rounded-md"
|
||||||
|
$ text "Close Head"
|
||||||
|
switchHold never sendButtonClick
|
||||||
|
pure ()
|
||||||
|
pure ()
|
||||||
|
|
||||||
|
closedScreen ::
|
||||||
|
( MonadFix m,
|
||||||
|
MonadIO m,
|
||||||
|
MonadIO (Performable m),
|
||||||
|
DomBuilder t m,
|
||||||
|
PostBuild t m,
|
||||||
|
TriggerEvent t m,
|
||||||
|
PerformEvent t m,
|
||||||
|
MonadHold t m
|
||||||
|
) =>
|
||||||
|
UTCTime ->
|
||||||
|
m ()
|
||||||
|
closedScreen fanoutTime = do
|
||||||
|
countDownDyn <- clockLossy 1 fanoutTime
|
||||||
|
elClass "div" "text-white text-2xl my-4 ml-2" $ do
|
||||||
|
text "Fanout time left: "
|
||||||
|
dyn_
|
||||||
|
( text . T.pack . show @Integer
|
||||||
|
. ceiling
|
||||||
|
. diffUTCTime fanoutTime
|
||||||
|
. _tickInfo_lastUTC
|
||||||
|
<$> countDownDyn
|
||||||
|
)
|
||||||
|
text " seconds"
|
14
src/Paths.hs
Normal file
14
src/Paths.hs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
module Paths where
|
||||||
|
|
||||||
|
import System.Which (staticWhich)
|
||||||
|
|
||||||
|
hydraToolsPath :: FilePath
|
||||||
|
hydraToolsPath = $(staticWhich "hydra-tools")
|
||||||
|
|
||||||
|
realpathPath :: FilePath
|
||||||
|
realpathPath = $(staticWhich "realpath")
|
||||||
|
|
||||||
|
dirnamePath :: FilePath
|
||||||
|
dirnamePath = $(staticWhich "dirname")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user