-
Notifications
You must be signed in to change notification settings - Fork 9
Leios's Voting Demo #600
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Leios's Voting Demo #600
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
e3d2749
1st version of demo: add scripts and README
hjeljeli32 9b080fe
update pretty_print_cert to print voter IDs in summary
hjeljeli32 e3cccc9
add minimal ui that summarizes certificate
hjeljeli32 20a1498
make UI visualize committee, voters and certificate info
hjeljeli32 11fb574
make UI visualize Pools in appealing way
hjeljeli32 0edd25d
make UI visualize Pools, Committee and Voters
hjeljeli32 c0b0adb
enhance UI visualization of Pools, Committee Selection and Voting
hjeljeli32 51ff6d3
make UI shows all steps of Voting
hjeljeli32 05babe5
make UI show all steps: CM selection, voting, aggregation, verification
hjeljeli32 4647c86
clean UI code
hjeljeli32 dbcbbdd
rename/clean scripts
hjeljeli32 7b7a08d
clean server.py
hjeljeli32 aac588d
clean README
hjeljeli32 e04ee6a
display environment information in the UI
hjeljeli32 b18db7e
remove old dependencies from README
hjeljeli32 27dd526
display CPU in the demo UI
hjeljeli32 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,14 @@ | ||
| target/ | ||
| *.cbor | ||
| *.txt | ||
|
|
||
| # Demo artifacts | ||
| demo/**/*.pretty.json | ||
| demo/**/*.json | ||
| demo/**/*.png | ||
| demo/**/*.csv | ||
| demo/scripts/.env_cli | ||
|
|
||
| # Python cache | ||
| __pycache__/ | ||
| *.pyc |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
|
|
||
|
|
||
| # Demo Scripts for Leios Crypto Benchmarks | ||
|
|
||
| This folder contains scripts that orchestrate end-to-end demonstrations of BLS-based vote aggregation and certificate generation/verification for the Leios project. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - Ensure the CLI built from the repository root is available; see `crypto-benchmarks.rs/ReadMe.md` for build instructions and usage details. | ||
| - Ensure Python 3 is available with `cbor2` installed. | ||
| For example: | ||
|
|
||
| ```bash | ||
| python3 -m venv .venv | ||
| source .venv/bin/activate | ||
| pip install cbor2 | ||
| ``` | ||
|
|
||
| ## Workflow | ||
|
|
||
| The scripts are designed to be run from the `demo/` directory. | ||
|
|
||
| ### Run Step by Step (Manual Mode) | ||
|
|
||
| You can run each script individually to understand and control each step of the process for a given number of voters (e.g., 100). Use the `-d` option to specify the output directory (e.g., `run100`). | ||
|
|
||
| #### 10_init_inputs.sh | ||
|
|
||
| Initialize inputs for N voters: | ||
|
|
||
| ```bash | ||
| scripts/10_init_inputs.sh -d run100 --pools 500 --stake 100000 --alpha 9 --beta 1 | ||
| ``` | ||
|
|
||
| #### 20_make_registry.sh | ||
|
|
||
| Build the registry from initialized inputs: | ||
|
|
||
| ```bash | ||
| ./scripts/20_make_registry.sh -d run100 -n 100 | ||
| ``` | ||
|
|
||
| #### 30_cast_votes.sh | ||
|
|
||
| Cast votes with a specified fraction of voters voting (e.g., 1.0 means all vote): | ||
|
|
||
| ```bash | ||
| scripts/30_cast_votes.sh -d run100 -f 0.75 | ||
| ``` | ||
|
|
||
| #### 40_make_certificate.sh | ||
|
|
||
| Generate the aggregated certificate: | ||
|
|
||
| ```bash | ||
| scripts/40_make_certificate.sh -d run100 | ||
| ``` | ||
|
|
||
| #### 50_verify_certificate.sh | ||
|
|
||
| Verify the generated certificate: | ||
|
|
||
| ```bash | ||
| scripts/50_verify_certificate.sh -d run100 | ||
| ``` | ||
|
|
||
| ### Run a Single End-to-End Demo | ||
|
|
||
| ```bash | ||
| scripts/70_run_one.sh -d run100 -p 500 -n 100 -f 0.75 | ||
| ``` | ||
|
|
||
| This will: | ||
|
|
||
| 1. Initialize inputs (`10_init_inputs.sh`) | ||
| 2. Build a registry (`20_make_registry.sh`) | ||
| 3. Cast votes (`30_cast_votes.sh`) | ||
| 4. Make a certificate (`40_make_certificate.sh`) | ||
| 5. Verify the certificate (`50_verify_certificate.sh`) | ||
| 6. Export data for the UI (`60_export_demo_json.sh`) | ||
|
|
||
| All files are placed in `demo/run100/`. | ||
|
|
||
| ### Launch the Demo UI | ||
|
|
||
| After generating a demo run (for example via `scripts/70_run_one.sh`), start the UI server from this directory: | ||
|
|
||
| ```bash | ||
| python3 ui/server.py | ||
| ``` | ||
|
|
||
| Then open your browser at [http://127.0.0.1:5050/ui](http://127.0.0.1:5050/ui) to explore the results. | ||
|
|
||
| ## Notes | ||
|
|
||
| - All scripts must be run from within the `demo/` directory. | ||
| - Directories passed via `-d` will be created automatically under `demo/`. | ||
| - Compression ratio is defined as: | ||
|
|
||
| ``` | ||
| votes_bytes / certificate_bytes | ||
| ``` | ||
|
|
||
| which illustrates the storage/bandwidth savings achieved by BLS aggregation. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
| # Usage: demo/scripts/00_set_cli.sh [-p /abs/path/to/leios_crypto_benchmarks] | ||
| # Writes demo/scripts/.env_cli with an absolute CLI path so other scripts can source it. | ||
|
|
||
| DIR_SCRIPT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| ENV_FILE="$DIR_SCRIPT/.env_cli" | ||
| CLI_PATH="" | ||
|
|
||
| while getopts ":p:" opt; do | ||
| case "$opt" in | ||
| p) CLI_PATH="$OPTARG" ;; | ||
| *) echo "Usage: $0 [-p /abs/path/to/leios_crypto_benchmarks]"; exit 2 ;; | ||
| esac | ||
| done | ||
|
|
||
| if [[ -z "${CLI_PATH}" ]]; then | ||
| read -r -p "Absolute path to leios_crypto_benchmarks binary: " CLI_PATH | ||
| fi | ||
|
|
||
| if [[ ! -x "${CLI_PATH}" ]]; then | ||
| echo "Error: '${CLI_PATH}' is not an executable file." >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| mkdir -p "$DIR_SCRIPT" | ||
| cat > "$ENV_FILE" <<EOF | ||
| # Auto-generated by 00_set_cli.sh | ||
| export CLI="${CLI_PATH}" | ||
| EOF | ||
|
|
||
| echo "Saved CLI path to $ENV_FILE" | ||
| echo "Example: source \"$ENV_FILE\" && \$CLI --help" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
| # Usage: demo/scripts/10_init_inputs.sh [-d DEMO_DIR] [--pools 5000] [--stake 100000] [--alpha 5] [--beta 1] | ||
| DIR_SCRIPT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| source "$DIR_SCRIPT/.env_cli" | ||
|
|
||
| DEMO_DIR="$(cd "$DIR_SCRIPT/.." && pwd)" | ||
| POOLS=500 | ||
| TOTAL_STAKE=1000000 | ||
| ALPHA=9 | ||
| BETA=1 | ||
|
|
||
| while [[ $# -gt 0 ]]; do | ||
| case "$1" in | ||
| -d) DEMO_DIR="$2"; shift 2;; | ||
| --pools) POOLS="$2"; shift 2;; | ||
| --stake) TOTAL_STAKE="$2"; shift 2;; | ||
| --alpha) ALPHA="$2"; shift 2;; | ||
| --beta) BETA="$2"; shift 2;; | ||
| *) echo "Unknown arg: $1"; exit 2;; | ||
| esac | ||
| done | ||
|
|
||
| mkdir -p "$DEMO_DIR" | ||
|
|
||
| echo "== [10_init_inputs] DIR=${DEMO_DIR} POOLS=${POOLS} TOTAL_STAKE=${TOTAL_STAKE} ==" | ||
|
|
||
| pushd "$DEMO_DIR" >/dev/null | ||
| "$CLI" gen-eid > eid.txt | ||
| "$CLI" gen-eb-hash > ebhash.txt | ||
|
|
||
| "$CLI" gen-stake \ | ||
| --pool-count "${POOLS}" \ | ||
| --total-stake "${TOTAL_STAKE}" \ | ||
| --shape-alpha "${ALPHA}" \ | ||
| --shape-beta "${BETA}" \ | ||
| --stake-file stake.cbor | ||
|
|
||
| "$CLI" gen-pools \ | ||
| --stake-file stake.cbor \ | ||
| --pools-file pools.cbor | ||
|
|
||
| # Pretty-print some of the generated values | ||
| echo "EID: $(cat eid.txt)" | ||
| echo "EB Hash: $(cat ebhash.txt)" | ||
|
|
||
| # Print first 3 pools and their stakes from pools.cbor using cbor2 | ||
| PYTHON_EXEC="${VIRTUAL_ENV:+$VIRTUAL_ENV/bin/python}" | ||
| PYTHON_EXEC="${PYTHON_EXEC:-python3}" | ||
| "$PYTHON_EXEC" - <<'PY' | ||
| import sys, os | ||
| try: | ||
| import cbor2 | ||
| except ImportError: | ||
| print('cbor2 not installed! (pip install cbor2)', file=sys.stderr) | ||
| sys.exit(1) | ||
|
|
||
| if not os.path.exists('pools.cbor'): | ||
| print('pools.cbor not found', file=sys.stderr) | ||
| sys.exit(1) | ||
|
|
||
| with open('pools.cbor', 'rb') as f: | ||
| pools = cbor2.load(f) | ||
|
|
||
| print('First 3 pools and their stakes:') | ||
| for i, entry in enumerate(pools[:3]): | ||
| # Expected structure: {"secret": <bytes>, "reg": {"pool": "<hex>", ...}, "stake": <int>} | ||
| reg = entry.get('reg', {}) | ||
| pool_id = reg.get('pool', '<unknown>') | ||
| stake = entry.get('stake', '<unknown>') | ||
| print(f' {i:>2}: pool={pool_id} stake={stake}') | ||
| PY | ||
| popd >/dev/null | ||
|
|
||
| echo "Initialized inputs in ${DEMO_DIR}" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
|
|
||
|
|
||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
| # Usage: demo/scripts/20_make_registry.sh -d RUN_DIR -n N | ||
| # Example (from demo/): scripts/20_make_registry.sh -d run16 -n 16 | ||
| DIR_SCRIPT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| source "$DIR_SCRIPT/.env_cli" | ||
|
|
||
| RUN_DIR="" | ||
| N="" | ||
|
|
||
| while [[ $# -gt 0 ]]; do | ||
| case "$1" in | ||
| -d) RUN_DIR="$2"; shift 2;; | ||
| -n) N="$2"; shift 2;; | ||
| *) echo "Usage: $0 -d RUN_DIR -n N"; exit 2;; | ||
| esac | ||
| done | ||
|
|
||
| if [[ -z "$RUN_DIR" || -z "$N" ]]; then | ||
| echo "Error: need -d RUN_DIR and -n N" >&2; exit 2 | ||
| fi | ||
|
|
||
| RUN_DIR="$(cd "$DIR_SCRIPT/.."; cd "$RUN_DIR" && pwd)" | ||
| echo "== [20_make_registry] DIR=${RUN_DIR} N=${N} ==" | ||
|
|
||
| pushd "$RUN_DIR" >/dev/null | ||
| "$CLI" make-registry \ | ||
| --pools-file pools.cbor \ | ||
| --voter-count "$N" \ | ||
| --registry-file registry.cbor | ||
| popd >/dev/null | ||
|
|
||
| # --- Pretty-print a short registry summary for the audience --- | ||
| PYTHON_EXEC="${VIRTUAL_ENV:+$VIRTUAL_ENV/bin/python}" | ||
| PYTHON_EXEC="${PYTHON_EXEC:-python3}" | ||
| pushd "$RUN_DIR" >/dev/null | ||
| "$PYTHON_EXEC" - <<'PY' | ||
| import sys, os | ||
| try: | ||
| import cbor2 | ||
| except ImportError: | ||
| print("CBOR summary skipped (cbor2 not installed). Run: pip install cbor2", file=sys.stderr) | ||
| raise SystemExit(0) | ||
|
|
||
| path = "registry.cbor" | ||
| if not os.path.exists(path): | ||
| print("CBOR summary skipped (registry.cbor missing).", file=sys.stderr) | ||
| raise SystemExit(0) | ||
|
|
||
| c = cbor2.load(open(path, "rb")) | ||
|
|
||
| voters = c.get("voters") | ||
| total_stake = c.get("total_stake") | ||
| persistent_pool = c.get("persistent_pool") or {} | ||
| info = c.get("info") or {} | ||
|
|
||
| print("Registry summary:") | ||
| print(f" Seats requested (N): {voters}") | ||
| print(f" Persistent seats: {len(persistent_pool)}") | ||
| print(f" Total stake: {total_stake}") | ||
|
|
||
| # Top 3 stakepools by stake (from .info) | ||
| tops = [] | ||
| for pool_id, rec in info.items(): | ||
| stake = rec.get("stake") | ||
| if isinstance(stake, int): | ||
| tops.append((stake, pool_id)) | ||
| tops.sort(reverse=True) | ||
| tops = tops[:3] | ||
|
|
||
| if tops: | ||
| print(" Top 3 stakepools by stake:") | ||
| for i, (stake, pool) in enumerate(tops, 1): | ||
| print(f" {i}. pool={pool} stake={stake}") | ||
|
|
||
| # Show up to first 3 persistent IDs → pools | ||
| if isinstance(persistent_pool, dict) and persistent_pool: | ||
| items = sorted(persistent_pool.items(), key=lambda kv: kv[0])[:3] | ||
| print(" Persistent mapping (first 3):") | ||
| for pid, pool in items: | ||
| print(f" id={pid} -> pool={pool}") | ||
| PY | ||
| popd >/dev/null | ||
| # --- End summary --- |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The scripts were a bit annoying to run for me:
PATHto point to the binary at first (as required on line 9)CLIneeds to be set, which I didscripts/.env_clineeds to exist00_set_cli.shscript, but that did not accept the binary in my aseI would suggest to lower the specific requirements and just expec the
leios_crypto_benchmarkson thePATH, or be explicit about needingCLIto be set.FWIW I was using
direnvand anix-shellto get the binaries and python packages in place, but this is different for each user.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for the feedback, @ch1bo — and apologies for the confusion with the README setup instructions.
I reviewed the steps and have now created a PR that updates the README with corrected and simplified instructions for running the demo.
Because my laptop currently has limited disk space, I wasn’t able to use Nix for this setup — so I focused on making sure the demo can also be run easily without it.
Here’s the PR with the fixes:
👉 #606