diff --git a/package.json b/package.json index e02351e..25c4ae8 100644 --- a/package.json +++ b/package.json @@ -1,49 +1,50 @@ -{ - "name": "clb-docs", - "version": "0.0.1", - "description": "CLB Docs", - "scripts": { - "lint": "eslint . --ext mdx --max-warnings 0 && pnpm spellcheck:lint", - "fix": "eslint . --ext mdx --fix && pnpm spellcheck:fix", - "spellcheck:lint": "cspell lint \"**/*.mdx\"", - "spellcheck:fix": "cspell --words-only --unique \"**/*.mdx\" | sort --ignore-case | uniq > words.txt", - "linkcheck": "lychee --config ./lychee.toml --quiet \"./pages\"", - "dev": "next dev", - "build": "next build", - "start": "next build && npx serve@latest out", - "postbuild": "next-sitemap" - }, - "dependencies": { - "@feelback/react": "latest", - "next": "latest", - "next-sitemap": "latest", - "nextra": "latest", - "nextra-theme-docs": "latest", - "react": "latest", - "react-dom": "latest" - }, - "devDependencies": { - "@double-great/remark-lint-alt-text": "latest", - "@types/node": "latest", - "cspell": "latest", - "eslint": "latest", - "eslint-plugin-mdx": "latest", - "ethers": "^5", - "remark": "latest", - "remark-code-import": "latest", - "remark-frontmatter": "latest", - "remark-gfm": "latest", - "remark-lint-frontmatter-schema": "latest", - "remark-lint-heading-style": "latest", - "remark-lint-list-item-indent": "latest", - "remark-lint-table-cell-padding": "latest", - "remark-lint-table-pipe-alignment": "latest", - "remark-lint-table-pipes": "latest", - "remark-lint-unordered-list-marker-style": "latest", - "remark-preset-lint-consistent": "latest", - "remark-preset-lint-recommended": "latest", - "typescript": "latest", - "unified-lint-rule": "latest", - "unist-util-visit": "latest" - } -} +{ + "name": "clb-docs", + "version": "0.0.1", + "description": "CLB Docs", + "scripts": { + "lint": "eslint . --ext mdx --max-warnings 0 && pnpm spellcheck:lint", + "fix": "eslint . --ext mdx --fix && pnpm spellcheck:fix", + "spellcheck:lint": "cspell lint \"**/*.mdx\"", + "spellcheck:fix": "cspell --words-only --unique \"**/*.mdx\" | sort --ignore-case | uniq > words.txt", + "linkcheck": "lychee --config ./lychee.toml --quiet \"./pages\"", + "dev": "next dev", + "build": "next build", + "start": "next build && npx serve@latest out", + "postbuild": "next-sitemap" + }, + "dependencies": { + "@feelback/react": "latest", + "next": "latest", + "next-sitemap": "latest", + "nextra": "latest", + "nextra-theme-docs": "latest", + "react": "latest", + "react-dom": "latest" + }, + "devDependencies": { + "@double-great/remark-lint-alt-text": "latest", + "@types/node": "latest", + "@types/react": "19.0.2", + "cspell": "latest", + "eslint": "latest", + "eslint-plugin-mdx": "latest", + "ethers": "^5", + "remark": "latest", + "remark-code-import": "latest", + "remark-frontmatter": "latest", + "remark-gfm": "latest", + "remark-lint-frontmatter-schema": "latest", + "remark-lint-heading-style": "latest", + "remark-lint-list-item-indent": "latest", + "remark-lint-table-cell-padding": "latest", + "remark-lint-table-pipe-alignment": "latest", + "remark-lint-table-pipes": "latest", + "remark-lint-unordered-list-marker-style": "latest", + "remark-preset-lint-consistent": "latest", + "remark-preset-lint-recommended": "latest", + "typescript": "latest", + "unified-lint-rule": "latest", + "unist-util-visit": "latest" + } +} diff --git a/pages/atlas.mdx b/pages/atlas.mdx new file mode 100644 index 0000000..8ce5e79 --- /dev/null +++ b/pages/atlas.mdx @@ -0,0 +1,5 @@ +--- +title: Use CLB with Atlas +lang: en-US +description: How to pair CLB with Atlas and use higher-level API. +--- diff --git a/pages/build.mdx b/pages/build.mdx new file mode 100644 index 0000000..0a6ae12 --- /dev/null +++ b/pages/build.mdx @@ -0,0 +1,13 @@ +--- +title: Building CLB +lang: en-US +description: How to use CLB in the node mode. +--- + +# Building CLB + +## Building locally + +## Using CLB from CHaP + +## Using CLB executable with Nix diff --git a/pages/index.mdx b/pages/index.mdx index c86c801..e3e12d5 100644 --- a/pages/index.mdx +++ b/pages/index.mdx @@ -4,25 +4,60 @@ lang: en-US description: General information about CLB. --- +> TODO: reprecation note on PSM + # CLB - Cardano Emulator that works -Welcome to the CLB! (Pronounced /klʌb/). +Welcome to CLB (pronounced /klʌb/)! -CLB (stands for _cardano-ledger backend_) is two-in-one Cardano emulator +[CLB](https://github.com/mlabs-haskell/clb) +(stands for _cardano-ledger backend_) is two-in-one Cardano emulator which can be used in two modes of operation depending on your needs: * as a Haskell library * as a cardano-node emualator These two modes have different behaviour described in [variants of use](/modes). +# Maintenance + +CLB is maintained by [MLabs](https://www.mlabs.city) as a part of its core-tools endevor. +Please submit an [issue](https://github.com/mlabs-haskell/clb/issues/new) +or ask a [question](https://github.com/mlabs-haskell/clb/discussions/new/choose) on GitHub. +CLB is an open-source project, so PRs are highly welcomed as well. + +# Adoption + +Here goes the list of projects that uses CLB or its parts: + +* [Atlas](https://github.com/geniusyield/atlas), +the modern PAB by [GeniusYield](https://www.geniusyield.co/) and others +uses CLB in lieu of decomissioned [PSM](https://github.com/mlabs-haskell/plutus-simple-model) library. +* [CTL](https://github.com/Plutonomicon/cardano-transaction-lib), +a Purescript-based set of tools for building sApps for browsers +developed by [MLabs](https://www.mlabs.city) provides a way to use CLB +instead of `cardano-node` to speed up private network tests. +* [CEM Script](https://github.com/mlabs-haskell/cem-script), + a high-level Cardano SDK for building dApps from state-machine-like definition by + [MLabs](https://www.mlabs.city) uses bare CLB API for verifying its models. + +If you use CLB and your project is not on the list, +please give us a [shout](https://github.com/mlabs-haskell/clb-docs/issues/new). + +# History + +In the case you are interested in the CLB's story we recommend reading this +[report](https://github.com/mlabs-haskell/clb/blob/master/docs/reports/ms1/MS1-REPORT.md) +that goes great lengths to present the whole story, particularly: +* How the predecessor of CLB, PSM library [was born](https://github.com/mlabs-haskell/clb/blob/master/docs/reports/ms1/MS1-REPORT.md#psm-brief-history-recap). +* What PSM looked like when [CLB was incepted](https://github.com/mlabs-haskell/clb/blob/master/docs/reports/ms1/MS1-REPORT.md#the-current-state). +* CLB as the [next-gen of PSM](https://github.com/mlabs-haskell/clb/blob/master/docs/reports/ms1/MS1-REPORT.md#the-current-state). + # Credits CLB was funded by Catalyst Fund10 [proposal](https://milestones.projectcatalyst.io/projects/1000121) and developed by [MLabs](https://mlabs.city)' team: -* Ilia Rodionov -* George Flerovsky -* Gregory Gerasev -* Rajdeep Maity -* Mazen Khaddaj - -TODO: mention PSM \ No newline at end of file + * George Flerovsky + * Gregory Gerasev + * Ilia Rodionov + * Mazen Khaddaj + * Rajdeep Maity diff --git a/pages/lib.mdx b/pages/lib.mdx new file mode 100644 index 0000000..233ee9d --- /dev/null +++ b/pages/lib.mdx @@ -0,0 +1,5 @@ +--- +title: Bare CLB as a library +lang: en-US +description: Using CLB as a library. +--- \ No newline at end of file diff --git a/pages/node.mdx b/pages/node.mdx new file mode 100644 index 0000000..8bcd6ef --- /dev/null +++ b/pages/node.mdx @@ -0,0 +1,83 @@ +--- +title: Node mode +lang: en-US +description: How to use CLB in the node mode. +--- + +> TODO: cardano-node compatibility matrix + +> TODO: the number of nodes run by cardano-testnet + +# Node emulator mode + +For description of how this mode operates see a short +[introduction](/use#node-emulator-mode) +on the [Variants of use](/use) page. + +## Getting CLB executable + +The executable `cardano-node-socket-emulator` to run CLB +is a separate cabal project located in the project repository under +[emulator](https://github.com/mlabs-haskell/clb/tree/master/emulator) folder. + +Currently, no binary distribution is available so you have to include it into +your project using [Nix](/build#using-clb-with-nix) +or [build](/build#standalone-building) it separately. + +## Spinning up CLB instance + +Almost like with a real `cardano-node` you have to provide a lot of things to the +binary to spin up an instance of emualator which is effectively a degenerated network +that consists of one only node which is in change of producing blokcs. + + Whereas you can prepare all things manually, the recommended way is to use + [cardano-testnet](https://github.com/IntersectMBO/cardano-node/tree/master/cardano-testnet) from + [cardano-node](https://github.com/IntersectMBO/cardano-node) repository. + + This tool is capable of generating network genesis and configuration + based on your preferences and running any executable that can understand it + by utilising `CARDANO_NODE` environment variable. + + That way having `cardano-testnet` executable at hand you can do this + (pay attention that currently only text logging is supported): + + ```bash + $ export CARDANO_NODE=/path/to/cardano-node-socket-emulator + $ cardano-testnet \ + cardano + --conway-era + --testnet-magic 764824073 + --nodeLoggingFormat text + ``` + + Under the hood `cardano-testnet` generates a temporary folder which contains: + * configuration, topology and genesis files + * signing keys of genesis wallets + * IPC socket for the nodes + * logs + + Then it runs the binary set in `CARDANO_NODE` with the following set of parameters + (listed here for informational purposes): + + ```bash + $ cardano-node-socket-emulator run \ + --config /tmp/configuration.yaml + --topology /tmp/pools-keys/pool2/topology.json + --database-path /tmp/pools-keys/pool2/db + --shelley-kes-key /tmp/pools-keys/pool2/kes.skey + --shelley-vrf-key /tmp/pools-keys/pool2/vrf.skey + --byron-delegation-certificate /tmp/pools-keys/pool2/byron-delegation.cert + --byron-signing-key /tmp/pools-keys/pool2/byron-delegate.key + --shelley-operational-certificate /tmp/pools-keys/pool2/opcert.cert + --socket-path /tmp/socket/pool2/sock + --host-addr 127.0. 0.1 + --port 43159 + ``` + +## Example: CLB as backend for privnet tests in CTL + +As a reference example you can use the way CLB is integrated with +[cardano-transaction-lib](https://github.com/Plutonomicon/cardano-transaction-lib) +as it's done in this [PR](https://github.com/Plutonomicon/cardano-transaction-lib/pull/1655). + + diff --git a/pages/use.mdx b/pages/use.mdx new file mode 100644 index 0000000..63eb605 --- /dev/null +++ b/pages/use.mdx @@ -0,0 +1,55 @@ +--- +title: Variants of use +lang: en-US +description: Describes different options how CLB can be used. +--- + +# Variants of use + +There are two basic ways to use CLB within a project. + +The preferred way is to plug it as a Haskell library into your project. +Depending on your needs you can use low-level [CLB's bare API](/lib) +or use high-level API by pairing it with [Atlas capabilities](/atlas) +to build transactions and tests. + +An alternative option is running CLB as a standalone node emulator. +This is the only option for non-haskell projects or in cases when +the functionality of the library is too lean for one's purposes. + +## Library mode + +In the library mode CLB emulator just maintains the pure ledger in-memory state. +Neither is there notion of time, nor blocks. +The genesis is also absent and a user is expected +to provide initial fund distribution. + +When a transaction comes in, it is validated against the state. +If it is valid then the state is immediately gets cranked, +moving into the next imaginary slot, +and the transaction is discarded. +The only information that is preserved is transaction's datums. +If the transaction happens to be invalid +a negative validation result with the reason is returned to the submitter. + +TODO: links + +## Node emulator mode + +In the [node emulator mode](/node) +(also can be reffered to as the socket mode or the node mode) +things get more entangled. +In contrast to the library mode when the emulator is just a pure state in the memory +in the node mode the emulator represents a standalone process +that mimics a full-fledged Cardano node behaviour to some extent. +The process maintains an IPC socket the way the node does, +so one can use Ouroboros mini-protocols direcrtly +or pull in Ogmios to get more usable API. + +The following additional things come into play when CLB is run in the node mode: +* A separate thread to count slots which emulates time. +* A mempool that maintains its own so-called "cached" state. +* A trivial block producing procedure that forges blocks +from the content of the mempool. + + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0208e38..826291c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,16 +13,16 @@ importers: version: 0.3.4(react@18.2.0) next: specifier: latest - version: 14.1.4(react-dom@18.2.0)(react@18.2.0) + version: 14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) next-sitemap: specifier: latest - version: 4.2.3(next@14.1.4) + version: 4.2.3(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0)) nextra: specifier: latest - version: 2.13.2(next@14.1.4)(react-dom@18.2.0)(react@18.2.0) + version: 2.13.2(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) nextra-theme-docs: specifier: latest - version: 2.13.2(next@14.1.4)(nextra@2.13.2)(react-dom@18.2.0)(react@18.2.0) + version: 2.13.2(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(nextra@2.13.2(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: specifier: latest version: 18.2.0 @@ -36,6 +36,9 @@ importers: '@types/node': specifier: latest version: 20.12.2 + '@types/react': + specifier: 19.0.2 + version: 19.0.2 cspell: specifier: latest version: 8.6.1 @@ -709,14 +712,8 @@ packages: '@types/node@20.12.2': resolution: {integrity: sha512-zQ0NYO87hyN6Xrclcqp7f8ZbXNbRfoGWNcMvHTPQp9UUrwI0mI7XBz+cu7/W6/VClYo2g63B0cjull/srU7LgQ==} - '@types/prop-types@15.7.9': - resolution: {integrity: sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==} - - '@types/react@18.2.36': - resolution: {integrity: sha512-o9XFsHYLLZ4+sb9CWUYwHqFVoG61SesydF353vFMMsQziiyRu8np4n2OYMUSDZ8XuImxDr9c5tR7gidlH29Vnw==} - - '@types/scheduler@0.16.5': - resolution: {integrity: sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw==} + '@types/react@19.0.2': + resolution: {integrity: sha512-USU8ZI/xyKJwFTpjSVIrSeHBVAGagkHQKPNbxeWwql/vDmnTIBgx+TJnhFnj1NXgz8XfprU0egV2dROLGpsBEg==} '@types/supports-color@8.1.3': resolution: {integrity: sha512-Hy6UMpxhE3j1tLpl27exp1XqHD7n8chAiNPzWfz16LPZoMMoSc4dzLl6w9qijkEb/r5O1ozdu1CWGA2L83ZeZg==} @@ -3576,7 +3573,7 @@ snapshots: '@feelback/js': 0.3.4 react: 18.2.0 - '@headlessui/react@1.7.17(react-dom@18.2.0)(react@18.2.0)': + '@headlessui/react@1.7.17(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: client-only: 0.0.1 react: 18.2.0 @@ -3630,7 +3627,7 @@ snapshots: '@mdx-js/react@2.3.0(react@18.2.0)': dependencies: '@types/mdx': 2.0.9 - '@types/react': 18.2.36 + '@types/react': 19.0.2 react: 18.2.0 '@napi-rs/simple-git-android-arm-eabi@0.1.9': @@ -3831,16 +3828,10 @@ snapshots: dependencies: undici-types: 5.26.5 - '@types/prop-types@15.7.9': {} - - '@types/react@18.2.36': + '@types/react@19.0.2': dependencies: - '@types/prop-types': 15.7.9 - '@types/scheduler': 0.16.5 csstype: 3.1.2 - '@types/scheduler@0.16.5': {} - '@types/supports-color@8.1.3': {} '@types/unist@2.0.9': {} @@ -3866,7 +3857,7 @@ snapshots: aes-js@3.0.0: {} ajv-formats@2.1.1(ajv@8.12.0): - dependencies: + optionalDependencies: ajv: 8.12.0 ajv@6.12.6: @@ -6050,7 +6041,7 @@ snapshots: natural-compare@1.4.0: {} - next-mdx-remote@4.4.1(react-dom@18.2.0)(react@18.2.0): + next-mdx-remote@4.4.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: '@mdx-js/mdx': 2.3.0 '@mdx-js/react': 2.3.0(react@18.2.0) @@ -6061,27 +6052,27 @@ snapshots: transitivePeerDependencies: - supports-color - next-seo@6.4.0(next@14.1.4)(react-dom@18.2.0)(react@18.2.0): + next-seo@6.4.0(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: - next: 14.1.4(react-dom@18.2.0)(react@18.2.0) + next: 14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - next-sitemap@4.2.3(next@14.1.4): + next-sitemap@4.2.3(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0)): dependencies: '@corex/deepmerge': 4.0.43 '@next/env': 13.5.6 fast-glob: 3.3.2 minimist: 1.2.8 - next: 14.1.4(react-dom@18.2.0)(react@18.2.0) + next: 14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - next-themes@0.2.1(next@14.1.4)(react-dom@18.2.0)(react@18.2.0): + next-themes@0.2.1(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: - next: 14.1.4(react-dom@18.2.0)(react@18.2.0) + next: 14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - next@14.1.4(react-dom@18.2.0)(react@18.2.0): + next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: '@next/env': 14.1.4 '@swc/helpers': 0.5.2 @@ -6106,9 +6097,9 @@ snapshots: - '@babel/core' - babel-plugin-macros - nextra-theme-docs@2.13.2(next@14.1.4)(nextra@2.13.2)(react-dom@18.2.0)(react@18.2.0): + nextra-theme-docs@2.13.2(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(nextra@2.13.2(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: - '@headlessui/react': 1.7.17(react-dom@18.2.0)(react@18.2.0) + '@headlessui/react': 1.7.17(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@popperjs/core': 2.11.8 clsx: 2.0.0 escape-string-regexp: 5.0.0 @@ -6117,18 +6108,18 @@ snapshots: git-url-parse: 13.1.1 intersection-observer: 0.12.2 match-sorter: 6.3.1 - next: 14.1.4(react-dom@18.2.0)(react@18.2.0) - next-seo: 6.4.0(next@14.1.4)(react-dom@18.2.0)(react@18.2.0) - next-themes: 0.2.1(next@14.1.4)(react-dom@18.2.0)(react@18.2.0) - nextra: 2.13.2(next@14.1.4)(react-dom@18.2.0)(react@18.2.0) + next: 14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + next-seo: 6.4.0(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + next-themes: 0.2.1(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + nextra: 2.13.2(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) scroll-into-view-if-needed: 3.1.0 zod: 3.22.4 - nextra@2.13.2(next@14.1.4)(react-dom@18.2.0)(react@18.2.0): + nextra@2.13.2(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: - '@headlessui/react': 1.7.17(react-dom@18.2.0)(react@18.2.0) + '@headlessui/react': 1.7.17(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@mdx-js/mdx': 2.3.0 '@mdx-js/react': 2.3.0(react@18.2.0) '@napi-rs/simple-git': 0.1.9 @@ -6140,8 +6131,8 @@ snapshots: gray-matter: 4.0.3 katex: 0.16.9 lodash.get: 4.4.2 - next: 14.1.4(react-dom@18.2.0)(react@18.2.0) - next-mdx-remote: 4.4.1(react-dom@18.2.0)(react@18.2.0) + next: 14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + next-mdx-remote: 4.4.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) p-limit: 3.1.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0)