diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..233172d
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,12 @@
+version: 2
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "daily"
+
+ - package-ecosystem: "cargo"
+ directory: "/"
+ schedule:
+ interval: "daily"
+
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..9d042f7
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,81 @@
+name: Build
+
+on:
+ push:
+ branches:
+ - main
+ - release-*
+ pull_request:
+ branches:
+ - main
+ - release-*
+ workflow_dispatch:
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ env:
+ RUSTFLAGS: "--cfg async_executor_impl=\"async-std\" --cfg async_channel_impl=\"async-std\""
+ RUST_LOG: info
+ steps:
+ - uses: styfle/cancel-workflow-action@0.12.0
+ name: Cancel Outdated Builds
+ with:
+ all_but_latest: true
+ access_token: ${{ github.token }}
+
+ - uses: actions/checkout@v4
+ name: Checkout Repository
+
+ - name: Install Protoc
+ uses: arduino/setup-protoc@v2
+
+ - uses: dtolnay/rust-toolchain@stable
+
+ - name: Configure Git
+ run: |
+ git config --global url."https://ancient123:${{ secrets.ORG_GITHUB_PAT }}@github.com".insteadOf git://github.com
+ git config --global url."https://ancient123:${{ secrets.ORG_GITHUB_PAT }}@github.com".insteadOf ssh://git@github.com
+
+ - uses: Swatinem/rust-cache@v2
+ name: Enable Rust Caching
+
+ - name: Format Check
+ run: cargo fmt -- --check
+
+ # Run Clippy on all targets. The lint workflow doesn't run Clippy on tests, because the tests
+ # don't compile with all combinations of features.
+ - uses: actions-rs/clippy-check@v1
+ name: Clippy
+ with:
+ token: ${{ github.token }}
+ args: --workspace --all-features --all-targets -- -D warnings
+
+ - name: Audit
+ run: cargo audit --ignore RUSTSEC-2023-0018 --ignore RUSTSEC-2023-0052 --ignore RUSTSEC-2023-0065
+
+ - name: Build
+ # Build in release without `testing` feature, this should work without `hotshot_example` config.
+ run: |
+ cargo build --workspace --release
+
+ - name: Test
+ # Build test binary with `testing` feature, which requires `hotshot_example` config
+ run: |
+ export RUSTFLAGS="$RUSTFLAGS --cfg hotshot_example"
+ cargo test --workspace --release --all-features --no-run
+ cargo test --workspace --release --all-features --verbose -- --test-threads 2
+ timeout-minutes: 60
+
+ - name: Generate Documentation
+ run: |
+ cargo doc --no-deps --lib --release
+ echo '' > target/doc/index.html
+
+ - name: Deploy Documentation
+ uses: peaceiris/actions-gh-pages@v3
+ if: ${{ github.ref == 'refs/heads/main' }}
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_dir: ./target/doc
+ cname: tide-disco.docs.espressosys.com
diff --git a/.github/workflows/build_nix.yml b/.github/workflows/build_nix.yml
new file mode 100644
index 0000000..8dcab5a
--- /dev/null
+++ b/.github/workflows/build_nix.yml
@@ -0,0 +1,47 @@
+name: Nix
+
+on:
+ push:
+ branches:
+ - main
+ - release-*
+ schedule:
+ - cron: '0 0 * * 1'
+ workflow_dispatch:
+
+jobs:
+ nix:
+ runs-on: ubuntu-latest
+ timeout-minutes: 90
+ steps:
+ - name: Configure Git
+ run: |
+ git config --global url."https://ancient123:${{ secrets.ORG_GITHUB_PAT }}@github.com/".insteadOf git://github.com/
+ git config --global url."https://ancient123:${{ secrets.ORG_GITHUB_PAT }}@github.com/".insteadOf ssh://git@github.com/
+
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+
+ - name: Install Nix
+ uses: cachix/install-nix-action@v24
+
+ # - uses: cachix/cachix-action@v12
+ # with:
+ # name: espresso-systems-private
+ # authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
+
+ - name: Cache cargo
+ uses: actions/cache@v3.3.2
+ with:
+ path: |
+ ~/.cargo-nix/registry/index
+ ~/.cargo-nix/registry/cache
+ ~/.cargo-nix/git
+ target
+ key: espresso-nix-v2-${{ hashFiles('Cargo.lock') }}
+
+ - name: "Sanity Check: nix environment loads"
+ run: nix-shell --run "echo Success"
+
+ - name: "Sanity Check: nix environment builds all targets"
+ run: nix-shell --run "cargo build --all-targets --all-features --release --workspace"
diff --git a/.github/workflows/build_windows.yml b/.github/workflows/build_windows.yml
new file mode 100644
index 0000000..acd52bc
--- /dev/null
+++ b/.github/workflows/build_windows.yml
@@ -0,0 +1,57 @@
+# Copyright (c) 2022 Espresso Systems (espressosys.com)
+# This file is part of the Tide Disco library.
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+# You should have received a copy of the GNU General Public License along with this program. If not,
+# see .
+
+name: Windows build
+
+on:
+ push:
+ branches:
+ - main
+ - release-*
+ pull_request:
+ branches:
+ - main
+ - release-*
+ workflow_dispatch:
+
+jobs:
+ windows:
+ runs-on: windows-latest
+ env:
+ RUSTFLAGS: "--cfg async_executor_impl=\"async-std\" --cfg async_channel_impl=\"async-std\" --cfg hotshot_example"
+ RUST_LOG: info
+ steps:
+ - name: Configure Git
+ run: |
+ git config --global url."https://ancient123:${{ secrets.ORG_GITHUB_PAT }}@github.com/".insteadOf git://github.com/
+ git config --global url."https://ancient123:${{ secrets.ORG_GITHUB_PAT }}@github.com/".insteadOf ssh://git@github.com/
+
+ - uses: dtolnay/rust-toolchain@stable
+
+ - name: Install Protoc
+ uses: arduino/setup-protoc@v2
+
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+
+ - uses: Swatinem/rust-cache@v2
+ name: Enable Rust Caching
+
+ - name: Build
+ run: |
+ cargo build --workspace --release
+
+ - name: Test
+ run: |
+ cargo test --workspace --release --all-features --no-run
+ cargo test --workspace --release --all-features --verbose -- --test-threads 2
+ timeout-minutes: 60
diff --git a/.github/workflows/combine-prs.yml b/.github/workflows/combine-prs.yml
new file mode 100644
index 0000000..6693abe
--- /dev/null
+++ b/.github/workflows/combine-prs.yml
@@ -0,0 +1,24 @@
+name: Combine PRs
+
+on:
+ schedule:
+ - cron: "0 1 * * MON"
+ workflow_dispatch: # allows to manually trigger the workflow
+
+# The minimum permissions required to run this Action
+permissions:
+ contents: write
+ pull-requests: write
+ checks: read
+
+jobs:
+ combine-prs:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: combine-prs
+ id: combine-prs
+ uses: github/combine-prs@v5.0.0
+ with:
+ github_token: ${{ secrets.ORG_GITHUB_PAT }}
+ labels: "dependabot,combined-pr"
diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
new file mode 100644
index 0000000..770257d
--- /dev/null
+++ b/.github/workflows/coverage.yml
@@ -0,0 +1,58 @@
+name: Code Coverage Workflow
+
+on:
+ push:
+ branches:
+ - main
+ - release-*
+ schedule:
+ - cron: "0 1 * * 1"
+ workflow_dispatch:
+
+jobs:
+ code-coverage:
+ runs-on: ubuntu-latest
+ timeout-minutes: 120
+ steps:
+ - name: Configure Git
+ run: |
+ git config --global url."https://ancient123:${{ secrets.ORG_GITHUB_PAT }}@github.com/".insteadOf git://github.com/
+ git config --global url."https://ancient123:${{ secrets.ORG_GITHUB_PAT }}@github.com/".insteadOf ssh://git@github.com/
+
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+
+ - name: Install Nix
+ uses: cachix/install-nix-action@v24
+
+ - name: Enable Cachix
+ uses: cachix/cachix-action@v13
+ # If PR is from a non-collaborator (e.g. dependabot) the secrets are missing and the login to cachix fails.
+ continue-on-error: true
+ with:
+ name: espresso-systems-private
+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+ extraPullNames: nix-community
+ skipPush: ${{ github.actor == 'dependabot[bot]' }}
+
+ - name: Cache cargo
+ uses: actions/cache@v3.3.2
+ with:
+ path: |
+ ~/.cargo/registry/index
+ ~/.cargo/registry/cache
+ ~/.cargo/git
+ target
+ key: hotshot-query-service-codecov-v1-${{ hashFiles('Cargo.lock') }}
+
+ - name: Generate coverage reports
+ run: |
+ git config --global --add safe.directory "$PWD"
+ nix run "github:NixOS/nix?ref=1849e6a1f64734c488c2b1469249d65ce08cef93" -- develop .#perfShell -c cargo llvm-cov --profile=release --all-features --all-targets --lcov --output-path lcov.info -- --test-threads 1
+
+ - name: Coveralls upload
+ uses: coverallsapp/github-action@master
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ path-to-lcov: lcov.info
+ fail_ci_if_error: true
diff --git a/.github/workflows/debug_build.yml b/.github/workflows/debug_build.yml
new file mode 100644
index 0000000..2e27082
--- /dev/null
+++ b/.github/workflows/debug_build.yml
@@ -0,0 +1,45 @@
+name: Debug Build
+
+on:
+ schedule:
+ - cron: "0 0 * * *"
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ env:
+ RUSTFLAGS: "--cfg async_executor_impl=\"async-std\" --cfg async_channel_impl=\"async-std\""
+ RUST_LOG: info
+ RUST_MIN_STACK: '3145728'
+ steps:
+ - name: Install Protoc
+ uses: arduino/setup-protoc@v2
+
+ - uses: dtolnay/rust-toolchain@stable
+
+ - uses: styfle/cancel-workflow-action@0.12.0
+ name: Cancel Outdated Builds
+ with:
+ all_but_latest: true
+ access_token: ${{ github.token }}
+
+ - uses: actions/checkout@v4
+ name: Checkout Repository
+
+ - name: Configure Git
+ run: |
+ git config --global url."https://ancient123:${{ secrets.ORG_GITHUB_PAT }}@github.com".insteadOf git://github.com
+ git config --global url."https://ancient123:${{ secrets.ORG_GITHUB_PAT }}@github.com".insteadOf ssh://git@github.com
+
+ - uses: Swatinem/rust-cache@v2
+ name: Enable Rust Caching
+
+ - name: Build
+ run: |
+ cargo build --workspace --all-features
+
+ - name: Test
+ run: |
+ cargo test --workspace --all-features --no-run
+ cargo test --workspace --all-features --verbose -- --test-threads 2
+ timeout-minutes: 60
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 0000000..27858f7
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,59 @@
+name: Lint
+
+on:
+ push:
+ branches:
+ - main
+ - release-*
+ pull_request:
+ branches:
+ - main
+ - release-*
+ workflow_dispatch:
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ # Lint with many combinations of feature flags
+ features:
+ # No optional features
+ - ''
+ # Each optional feature on its own
+ - sql-data-source
+ - file-system-data-source
+ - metrics-data-source
+ # All optional features together
+ - sql-data-source,file-system-data-source,metrics-data-source
+ env:
+ RUSTFLAGS: "--cfg async_executor_impl=\"async-std\" --cfg async_channel_impl=\"async-std\""
+ RUST_LOG: info
+ steps:
+ - uses: styfle/cancel-workflow-action@0.12.0
+ name: Cancel Outdated Builds
+ with:
+ all_but_latest: true
+ access_token: ${{ github.token }}
+
+ - uses: actions/checkout@v4
+ name: Checkout Repository
+
+ - name: Install Protoc
+ uses: arduino/setup-protoc@v2
+
+ - uses: dtolnay/rust-toolchain@stable
+
+ - name: Configure Git
+ run: |
+ git config --global url."https://ancient123:${{ secrets.ORG_GITHUB_PAT }}@github.com".insteadOf git://github.com
+ git config --global url."https://ancient123:${{ secrets.ORG_GITHUB_PAT }}@github.com".insteadOf ssh://git@github.com
+
+ - uses: Swatinem/rust-cache@v2
+ name: Enable Rust Caching
+
+ - uses: actions-rs/clippy-check@v1
+ name: Clippy
+ with:
+ token: ${{ github.token }}
+ args: --workspace --no-default-features --features "${{ matrix.features }}" -- -D warnings
diff --git a/.github/workflows/update_nix.yml b/.github/workflows/update_nix.yml
new file mode 100644
index 0000000..8affd87
--- /dev/null
+++ b/.github/workflows/update_nix.yml
@@ -0,0 +1,26 @@
+name: update-flake-lock
+
+on:
+ workflow_dispatch: # allows manual triggering
+ schedule:
+ - cron: '0 0 * * 0' # runs weekly on Sunday at 00:00
+
+jobs:
+ lockfile:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Install Nix
+ uses: cachix/install-nix-action@v24
+
+ - uses: cachix/cachix-action@v13
+ with:
+ name: espresso-systems-private
+ authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
+
+ - name: Update flake.lock
+ uses: DeterminateSystems/update-flake-lock@v20
+ with:
+ pr-title: "Weekly PR to bump flake.nix" # Title of PR to be created
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2c1151d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,25 @@
+# Generated by Cargo
+# will have compiled files and executables
+debug/
+target/
+
+# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
+# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
+Cargo.lock
+
+# These are backup files generated by rustfmt
+**/*.rs.bk
+
+# MSVC Windows builds of rustc generate these, which store debugging information
+*.pdb
+
+**/target
+**/result
+**/out*.txt
+**/out*.json
+**/.idea
+/*.pdf
+**/target_dirs
+/target_dirs
+/.vscode/settings.json
+**/.DS_Store
diff --git a/.vscode/settings.json.example b/.vscode/settings.json.example
new file mode 100644
index 0000000..f01b5af
--- /dev/null
+++ b/.vscode/settings.json.example
@@ -0,0 +1,5 @@
+// Sets features for Rust Analyzer, since some features are required to be set for compilation
+{
+ "rust-analyzer.cargo.features": [
+ ],
+}
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..4e861bb
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "hs-builder-api"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+async-trait = "0.1"
+hotshot-types = { git = "https://github.com/EspressoSystems/HotShot.git", tag = "0.5.7.1" }
+serde = { version = "1.0", features = ["derive"] }
+sha2 = "0.10"
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c9161d3
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# hs-builder-api
+Minimal dependencies shared API definitions for HotShot Builder protocol
diff --git a/api/builder.toml b/api/builder.toml
new file mode 100644
index 0000000..7db1070
--- /dev/null
+++ b/api/builder.toml
@@ -0,0 +1,45 @@
+# Copyright (c) 2024 Espresso Systems (espressosys.com)
+# This file is part of the HotShot Builder Protocol.
+#
+# TODO: License
+
+[meta]
+NAME = "hs-builder"
+DESCRIPTION = ""
+FORMAT_VERSION = "0.1.0"
+
+[route.available_blocks]
+PATH = ["availableblocks/:parent_hash"]
+":parent_hash" = "TaggedBase64"
+DOC = """
+Get descriptions for all block candidates based on a specific parent block.
+
+Returns
+```
+[
+ "block_metadata": {
+ "block_hash": TaggedBase64,
+ "block_size": integer,
+ "offered_fee": integer,
+ },
+]
+```
+"""
+
+[route.claim_block]
+PATH = ["claimblock/:block_hash/:signature"]
+":block_hash" = "TaggedBase64"
+":signature" = "TaggedBase64"
+DOC = """
+Get the specified block candidate.
+
+Returns application-specific encoded transactions type
+"""
+
+[route.submit_txn]
+PATH = ["submittxn/:txn"]
+":txn" = "TaggedBase64"
+DOC = """
+
+Returns ---
+"""
diff --git a/src/block_metadata.rs b/src/block_metadata.rs
new file mode 100644
index 0000000..ee335de
--- /dev/null
+++ b/src/block_metadata.rs
@@ -0,0 +1,17 @@
+use std::marker::PhantomData;
+
+use hotshot_types::traits::node_implementation::NodeType;
+use serde::{Deserialize, Serialize};
+use sha2::digest::{generic_array::GenericArray, typenum};
+
+pub type BlockHash = GenericArray;
+
+#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[serde(bound = "")]
+pub struct BlockMetadata {
+ block_hash: BlockHash,
+ block_size: u64,
+ offered_fee: u64,
+ _phantom: PhantomData,
+}
+
diff --git a/src/data_source.rs b/src/data_source.rs
new file mode 100644
index 0000000..11f35ae
--- /dev/null
+++ b/src/data_source.rs
@@ -0,0 +1,13 @@
+use std::sync::Arc;
+
+use async_trait::async_trait;
+use hotshot_types::{data::VidCommitment, traits::{node_implementation::NodeType, signature_key::SignatureKey}};
+
+use crate::block_metadata::{BlockHash, BlockMetadata};
+
+#[async_trait]
+pub trait BuilderDataSource {
+ async fn get_available_blocks(&self, for_parent: &VidCommitment) -> Vec>;
+ async fn claim_block(&self, block_hash: BlockHash, signature: <::SignatureKey as SignatureKey>::PureAssembledSignatureType) -> Arc>;
+ async fn submit_txn(&self, txn: ::Transaction);
+}
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..737f7bf
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,4 @@
+mod block_metadata;
+mod data_source;
+mod query_data;
+
diff --git a/src/query_data.rs b/src/query_data.rs
new file mode 100644
index 0000000..b2bb9e9
--- /dev/null
+++ b/src/query_data.rs
@@ -0,0 +1,16 @@
+// Copyright (c) 2024 Espresso Systems (espressosys.com)
+// This file is part of the HotShot HotShot Builder Protocol.
+//
+// TODO: License
+
+
+use hotshot_types::traits::node_implementation::NodeType;
+use serde::{Deserialize, Serialize};
+
+use crate::block_metadata::BlockMetadata;
+
+#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[serde(bound = "")]
+pub struct AvailableBlocksQueryData {
+ pub blocks: Vec>,
+}