diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..0011a492 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,18 @@ +target/ +dist/ +build/ +.git/ +.github/ +.gitignore +*.rs.bk +*.log +*.tmp +*.bak +*.swp +output.log +docs/ +tests/ +.env +docker-compose.yml +README.md +Dockerfile \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 47c4f214..00000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,148 +0,0 @@ -name: Build - -on: - push: - branches: ["master"] - workflow_dispatch: - -env: - CARGO_TERM_COLOR: always - BINARY_NAME: ore - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} - cancel-in-progress: false - -jobs: - version: - runs-on: ubuntu-latest - outputs: - version: ${{ steps.version.outputs.version }} - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - id: version - run: echo version="$(cargo metadata --no-deps --quiet --color never | jq -r '.packages[].version')-$(git describe --always --dirty=_modified)" >> "$GITHUB_OUTPUT" - build: - name: Build - needs: version - runs-on: ${{ matrix.os }} - strategy: - matrix: - include: - - os: macos-latest - target: x86_64-apple-darwin - - os: macos-latest - target: aarch64-apple-darwin - - os: ubuntu-latest - target: x86_64-unknown-linux-gnu - - os: ubuntu-latest - target: x86_64-unknown-linux-musl - - os: ubuntu-latest - target: aarch64-unknown-linux-gnu - # it requires unofficial prebuilt toolchain, disable it for security, consider it later - # - os: ubuntu-latest - # target: aarch64-unknown-linux-musl - - os: windows-latest - target: x86_64-pc-windows-msvc - # https://github.com/briansmith/ring/issues/1167 - # it's an issue of the upstream's upstream - # - os: windows-latest - # target: aarch64-pc-windows-msvc - - os: ubuntu-latest - target: x86_64-pc-windows-gnu - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Setup Rust - run: rustup target add ${{ matrix.target }} - # https://github.com/mozilla/grcov/blob/cc77ce34164fc3ea80ac579d1c15f36c9734133c/.github/workflows/release.yml#L34 - - name: Install additional toolchains - if: ${{ matrix.os == 'ubuntu-latest' }} - run: | - set -x - case "${{ matrix.target }}" in - x86_64-unknown-linux-gnu) - ;; - x86_64-unknown-linux-musl) - sudo apt-get update - sudo apt-get install -y musl-tools - ;; - aarch64-unknown-linux-gnu) - sudo apt-get update - sudo apt-get install -y gcc-aarch64-linux-gnu - - mkdir -p .cargo - echo '[target.aarch64-unknown-linux-gnu]' >> .cargo/config - echo 'linker = "aarch64-linux-gnu-gcc"' >> .cargo/config - ;; - x86_64-pc-windows-gnu) - sudo apt-get update - sudo apt-get install -y gcc-mingw-w64-x86-64-win32 - ;; - esac - - name: Configure cache - uses: actions/cache@v4 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: release-${{ runner.os }}-cargo-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }} - - name: Lint - run: cargo fmt --check - - name: Build - # run: cargo build --release --locked --target ${{ matrix.target }} - run: cargo build --release --target ${{ matrix.target }} - - name: Strip binary - if: ${{ matrix.os != 'windows-latest' }} - run: | - set -x - strip="strip" - file_extension="" - case "${{ matrix.target }}" in - x86_64-unknown-linux-gnu) - ;; - x86_64-unknown-linux-musl) - ;; - aarch64-unknown-linux-gnu) - strip=aarch64-linux-gnu-strip - ;; - aarch64-unknown-linux-musl) - strip=aarch64-linux-musl-strip - ;; - x86_64-pc-windows-gnu) - strip=x86_64-w64-mingw32-strip - file_extension=".exe" - ;; - esac - - ${strip} target/${{ matrix.target }}/release/${{ env.BINARY_NAME }}${file_extension} - - name: Package (unix) - if: ${{ matrix.os != 'windows-latest' }} - run: | - set -x - file_extension="" - case "${{ matrix.target }}" in - x86_64-pc-windows-gnu) - file_extension=".exe" - ;; - esac - rm -rf target/dist - mkdir target/dist - cd target/${{ matrix.target }}/release - cp ${{ env.BINARY_NAME }}${file_extension} ../../dist/${{ env.BINARY_NAME }}-${{ needs.version.outputs.version }}-${{ matrix.target }}${file_extension} - - name: Package (windows) - if: ${{ matrix.os == 'windows-latest' }} - run: | - if (Test-Path target/dist) { rm -Recurse -Force target/dist } - mkdir target/dist - cd target/${{ matrix.target }}/release - cp "${{ env.BINARY_NAME }}.exe" "../../dist/${{ env.BINARY_NAME }}-${{ needs.version.outputs.version }}-${{ matrix.target }}.exe" - - name: Upload archive - uses: actions/upload-artifact@v4 - with: - name: ${{ env.BINARY_NAME }}-${{ needs.version.outputs.version }}-${{ matrix.target }} - path: target/dist/* diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 00000000..050bec4e --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,107 @@ +name: Docker Build + +on: + release: + types: [published] + +env: + REGISTRY: ghcr.io + +jobs: + version: + runs-on: ubuntu-latest + outputs: + version: ${{ steps.version.outputs.version }} + image_name: ${{ steps.image_name.outputs.image_name }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - id: version + run: | + VERSION=$(cargo metadata --no-deps --quiet --color never | jq -r '.packages[].version') + VERSION_LOWER=$(echo "$VERSION" | tr '[:upper:]' '[:lower:]') + echo "version=${VERSION_LOWER}" >> "$GITHUB_OUTPUT" + + - id: image_name + run: | + IMAGE_NAME=$(echo "${{ github.repository_owner }}/ore" | tr '[:upper:]' '[:lower:]') + echo "image_name=${IMAGE_NAME}" >> "$GITHUB_OUTPUT" + + build: + needs: version + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write + security-events: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Install cosign + uses: sigstore/cosign-installer@v3.5.0 + with: + cosign-release: 'v2.2.4' + + - name: Log into registry ${{ env.REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ needs.version.outputs.image_name }} + tags: | + type=raw,value=${{ needs.version.outputs.version }} + type=raw,value=latest + type=sha + + - name: Build and push Docker image + id: build-and-push + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + platforms: linux/amd64,linux/arm64 + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Sign the images with GitHub OIDC Token + env: + DIGEST: ${{ steps.build-and-push.outputs.digest }} + TAGS: ${{ steps.meta.outputs.tags }} + run: | + images="" + for tag in ${TAGS}; do + images+="${tag}@${DIGEST} " + done + cosign sign --yes ${images} + + - name: Run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@0.24.0 + with: + image-ref: '${{ env.REGISTRY }}/${{ needs.version.outputs.image_name }}:${{ needs.version.outputs.version }}' + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + severity: 'CRITICAL,HIGH' + + - name: Upload Trivy scan results to GitHub Security tab + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: 'trivy-results.sarif' + wait-for-processing: true \ No newline at end of file diff --git a/.github/workflows/rust-build.yml b/.github/workflows/rust-build.yml new file mode 100644 index 00000000..c74e5329 --- /dev/null +++ b/.github/workflows/rust-build.yml @@ -0,0 +1,254 @@ +name: Rust Build + +on: + release: + types: [published] + +env: + CARGO_TERM_COLOR: always + BINARY_NAME: ore + +jobs: + version: + runs-on: ubuntu-latest + outputs: + version: ${{ steps.version.outputs.version }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - id: version + run: echo version="$(cargo metadata --no-deps --quiet --color never | jq -r '.packages[].version')-$(git describe --always --dirty=_modified)" >> "$GITHUB_OUTPUT" + + build-ubuntu: + name: Build on Ubuntu + needs: version + runs-on: ubuntu-latest + strategy: + matrix: + target: [x86_64-unknown-linux-gnu, x86_64-pc-windows-gnu] + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Rust + run: rustup target add ${{ matrix.target }} + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + ${{ matrix.target == 'x86_64-pc-windows-gnu' && 'mingw-w64' || 'openssl pkg-config libssl-dev' }} + - name: Configure cache + uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: release-${{ runner.os }}-cargo-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }} + + - name: Build + run: cargo build --release --target ${{ matrix.target }} + + - name: Strip binary + run: | + if [ "${{ matrix.target }}" = "x86_64-pc-windows-gnu" ]; then + x86_64-w64-mingw32-strip target/${{ matrix.target }}/release/${{ env.BINARY_NAME }}.exe + else + strip target/${{ matrix.target }}/release/${{ env.BINARY_NAME }} + fi + + - name: Package + run: | + rm -rf target/dist + mkdir -p target/dist + cp target/${{ matrix.target }}/release/${{ env.BINARY_NAME }}${{ matrix.target == 'x86_64-pc-windows-gnu' && '.exe' || '' }} target/dist/${{ env.BINARY_NAME }}-${{ needs.version.outputs.version }}-${{ matrix.target }}${{ matrix.target == 'x86_64-pc-windows-gnu' && '.exe' || '' }} + + - name: Upload archive + uses: actions/upload-artifact@v4 + with: + name: ${{ env.BINARY_NAME }}-${{ needs.version.outputs.version }}-${{ matrix.target }} + path: target/dist/* + + - name: Upload release asset + uses: actions/upload-release-asset@v1 + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: target/dist/${{ env.BINARY_NAME }}-${{ needs.version.outputs.version }}-${{ matrix.target }}${{ matrix.target == 'x86_64-pc-windows-gnu' && '.exe' || '' }} + asset_name: ${{ env.BINARY_NAME }}-${{ needs.version.outputs.version }}-${{ matrix.target }}${{ matrix.target == 'x86_64-pc-windows-gnu' && '.exe' || '' }} + asset_content_type: application/octet-stream + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + build-macos: + name: Build on macOS + needs: version + runs-on: macos-latest + strategy: + matrix: + target: [x86_64-apple-darwin, aarch64-apple-darwin] + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install dependencies + run: brew install openssl pkg-config + + - name: Setup Rust + run: rustup target add ${{ matrix.target }} + + - name: Configure cache + uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: release-${{ runner.os }}-cargo-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }} + + - name: Build + run: cargo build --release --target ${{ matrix.target }} + + - name: Strip binary + run: strip target/${{ matrix.target }}/release/${{ env.BINARY_NAME }} + + - name: Package + run: | + rm -rf target/dist + mkdir -p target/dist + cp target/${{ matrix.target }}/release/${{ env.BINARY_NAME }} target/dist/${{ env.BINARY_NAME }}-${{ needs.version.outputs.version }}-${{ matrix.target }} + - name: Upload archive + uses: actions/upload-artifact@v4 + with: + name: ${{ env.BINARY_NAME }}-${{ needs.version.outputs.version }}-${{ matrix.target }} + path: target/dist/* + + - name: Upload release asset + uses: actions/upload-release-asset@v1 + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: target/dist/${{ env.BINARY_NAME }}-${{ needs.version.outputs.version }}-${{ matrix.target }} + asset_name: ${{ env.BINARY_NAME }}-${{ needs.version.outputs.version }}-${{ matrix.target }} + asset_content_type: application/octet-stream + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + build-windows-msvc: + name: Build on Windows (MSVC) + needs: version + runs-on: windows-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Rust + run: rustup target add x86_64-pc-windows-msvc + + - name: Configure cache + uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: release-${{ runner.os }}-cargo-x86_64-pc-windows-msvc-${{ hashFiles('**/Cargo.lock') }} + + - name: Build + run: cargo build --release --target x86_64-pc-windows-msvc + + - name: Package + run: | + if (Test-Path target/dist) { Remove-Item -Recurse -Force target/dist } + New-Item -ItemType Directory -Force -Path target/dist + Copy-Item target/x86_64-pc-windows-msvc/release/${{ env.BINARY_NAME }}.exe target/dist/${{ env.BINARY_NAME }}-${{ needs.version.outputs.version }}-x86_64-pc-windows-msvc.exe + - name: Upload archive + uses: actions/upload-artifact@v4 + with: + name: ${{ env.BINARY_NAME }}-${{ needs.version.outputs.version }}-x86_64-pc-windows-msvc + path: target/dist/* + + - name: Upload release asset + uses: actions/upload-release-asset@v1 + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: target/dist/${{ env.BINARY_NAME }}-${{ needs.version.outputs.version }}-x86_64-pc-windows-msvc.exe + asset_name: ${{ env.BINARY_NAME }}-${{ needs.version.outputs.version }}-x86_64-pc-windows-msvc.exe + asset_content_type: application/octet-stream + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # build-arm64: + # name: Build on ARM64 (Ubuntu 22.04) + # needs: version + # runs-on: ubuntu-latest + # steps: + # - name: Checkout repository + # uses: actions/checkout@v4 + + # - name: Setup Rust + # run: | + # curl https://sh.rustup.rs -sSf | sh -s -- -y + # source "$HOME/.cargo/env" + # rustup target add aarch64-unknown-linux-gnu + + # - name: Install dependencies + # run: | + # sudo apt-get update && sudo apt-get install -y \ + # musl-tools \ + # clang \ + # gcc-aarch64-linux-gnu \ + # g++-aarch64-linux-gnu \ + # libc6-dev \ + # libc6-dev-arm64-cross + + # - name: Configure cache + # uses: actions/cache@v4 + # with: + # path: | + # ~/.cargo/bin/ + # ~/.cargo/registry/index/ + # ~/.cargo/registry/cache/ + # ~/.cargo/git/db/ + # target/ + # key: release-${{ runner.os }}-cargo-aarch64-unknown-linux-gnu-${{ hashFiles('**/Cargo.lock') }} + + # - name: Build + # run: | + # env BINDGEN_EXTRA_CLANG_ARGS='--sysroot /usr/aarch64-linux-gnu' \ + # CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=/usr/bin/aarch64-linux-gnu-gcc \ + # cargo build --release --target aarch64-unknown-linux-gnu + + # - name: Strip binary + # run: strip target/aarch64-unknown-linux-gnu/release/${{ env.BINARY_NAME }} + + # - name: Package + # run: | + # rm -rf target/dist + # mkdir -p target/dist + # cp target/aarch64-unknown-linux-gnu/release/${{ env.BINARY_NAME }} target/dist/${{ env.BINARY_NAME }}-${{ needs.version.outputs.version }}-aarch64-unknown-linux-gnu + + # - name: Upload archive + # uses: actions/upload-artifact@v4 + # with: + # name: ${{ env.BINARY_NAME }}-${{ needs.version.outputs.version }}-aarch64-unknown-linux-gnu + # path: target/dist/* + + # - name: Debug - Check file existence + # run: ls -alh target/dist + + # - name: Upload release asset + # uses: actions/upload-release-asset@v1 + # with: + # upload_url: ${{ github.event.release.upload_url }} + # asset_path: target/dist/${{ env.BINARY_NAME }}-${{ needs.version.outputs.version }}-aarch64-unknown-linux-gnu + # asset_name: ${{ env.BINARY_NAME }}-${{ needs.version.outputs.version }}-aarch64-unknown-linux-gnu + # asset_content_type: application/octet-stream + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/rust-test.yml b/.github/workflows/rust-test.yml new file mode 100644 index 00000000..e617f9c9 --- /dev/null +++ b/.github/workflows/rust-test.yml @@ -0,0 +1,54 @@ +name: Rust Tests & Linting + +on: + push: + branches: + - '**' + paths: + - 'src/**' + - 'Cargo.lock' + - 'Cargo.toml' + - 'rust-toolchain.toml' + +jobs: + build_and_test: + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + components: clippy + override: true + + - name: Install required cargo + run: cargo install clippy-sarif sarif-fmt cargo-audit + - name: Build + run: cargo test --no-run --workspace --all-features + + - name: Default features + run: cargo test --workspace + + - name: All features + run: cargo test --workspace --all-features + + - name: No-default features + run: cargo test --workspace --no-default-features + + - name: Run Clippy + run: | + cargo clippy --all-features --message-format=json | clippy-sarif | tee results_clippy.sarif | sarif-fmt + continue-on-error: true + + - name: Upload clippy results to GitHub + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: results_clippy.sarif + wait-for-processing: true \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..1558ac31 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,42 @@ +FROM rust:bookworm AS builder + +RUN apt-get update && apt-get install -y \ + openssl \ + pkg-config \ + libssl-dev + +WORKDIR /usr/src/ore-cli + +COPY Cargo.toml Cargo.lock rust-toolchain.toml . +COPY src ./src + +RUN cargo clean && cargo update && cargo build --release + +FROM registry.access.redhat.com/ubi9/ubi-minimal AS intermediate + +RUN microdnf update -y && \ + groupadd -g 1000 ore && \ + useradd -u 1000 -g ore -d /ore -m ore && \ + mkdir -p /ore/.config/solana && chown -R ore:ore /ore/.config + +FROM registry.access.redhat.com/ubi9/ubi-micro + +COPY --from=intermediate /usr/bin/grep /usr/bin/grep +COPY --from=intermediate /etc/passwd /etc/passwd +COPY --from=intermediate /etc/group /etc/group +COPY --from=intermediate /etc/shadow /etc/shadow +COPY --from=intermediate --chown=ore:ore --chmod=500 /ore /ore +COPY --from=intermediate /usr/lib64/libssl.so.3 /usr/lib64/libssl.so.3 +COPY --from=intermediate /usr/lib64/libcrypto.so.3 /usr/lib64/libcrypto.so.3 +COPY --from=intermediate /usr/lib64/libz.so.1 /usr/lib64/libz.so.1 +COPY --from=intermediate /usr/lib64/libpcre.so.1 /usr/lib64/libpcre.so.1 +COPY --from=intermediate /usr/lib64/libsigsegv.so.2 /usr/lib64/libsigsegv.so.2 + +WORKDIR /ore + +COPY --from=builder --chown=ore:ore --chmod=500 /usr/src/ore-cli/target/release/ore /usr/local/bin/ore +COPY --chown=ore:ore --chmod=500 entrypoint.sh /usr/local/bin/entrypoint.sh + +USER ore + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] \ No newline at end of file diff --git a/README.md b/README.md index 5a7e0a06..d345b82b 100644 --- a/README.md +++ b/README.md @@ -50,4 +50,71 @@ Add the `-h` flag on any command to pull up a help menu with documentation: ore -h ``` -For support, please [join the Discord](https://discord.gg/7xymAXZP8Y) and ask your question in the Help channel. +## Running with Docker + +Run the Docker image with your wallet mapped: + +```sh +docker run -it \ + -e RPC=mainnet \ + -e BUFFER_TIME=5 \ + -e CORES=4 \ + -v /local/path/to/id.json:/ore/id.json:ro \ + ghcr.io/regolith-labs/ore:latest +``` + +### Functions + +The Docker image supports the following functions: + +- `balance`: Fetch an account balance. +- `benchmark`: Benchmark your hashpower. +- `busses`: Fetch the bus account balances. +- `claim`: Claim your mining rewards. +- `close`: Close your account to recover rent. +- `config`: Fetch the program config. +- `mine`: Start mining. +- `proof`: Fetch a proof account by address. +- `rewards`: Fetch the current reward rate for each difficulty level. +- `stake`: Stake to earn a rewards multiplier. +- `transfer`: Send ORE to anyone, anywhere in the world. +- `upgrade`: Upgrade your ORE tokens from v1 to v2. + +### Environment Variables + +- `RPC`: Set the RPC URL (mainnet, devnet, or custom URL). Default is `devnet`. +- `BUFFER_TIME`: The number of seconds before the deadline to stop mining and start submitting (default: 5). +- `CORES`: Number of CPU cores to allocate to mining (default: 1). +- `PRIORITY_FEE`: Price to pay for compute units. If dynamic fee URL is also set, this value will be the max (default: 500000). +- `DYNAMIC_FEE_URL`: RPC URL to use for dynamic fee estimation. +- `DYNAMIC_FEE_STRATEGY`: Strategy to use for dynamic fee estimation. Must be one of 'helius' or 'triton'. + +### Volumes + +To use your wallet files, mount them as volumes: + +- Mount your wallet file: + ```sh + -v /path/to/your/id.json:/ore/id.json + ``` +- Mount your payer wallet file, which is used to pay fees for transactions: + ```sh + -v /path/to/your/payer.json:/ore/payer.json + ``` + +### Examples + +- Display balance account: + ```sh + docker run --rm -it \ + -v /path/to/your/id.json:/ore/id.json:ro \ + ghcr.io/regolith-labs/ore:latest balance + ``` +- Display help: + ```sh + docker run --rm -it ghcr.io/regolith-labs/ore:latest --help + ``` +- Benchmark your hashpower: + ```sh + docker run --rm -it ghcr.io/regolith-labs/ore:latest benchmark + ``` diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 00000000..0e982c73 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,141 @@ +#!/bin/sh + +MAINNET_URL="https://api.mainnet-beta.solana.com" +DEVNET_URL="https://api.devnet.solana.com" +WALLET_PATH="/ore/id.json" +WALLET_PAYER_PATH="/ore/payer.json" +FUNCTION="mine" + +RED='\033[0;31m' +NC='\033[0m' + +show_help() { + echo " +Usage: $0 [OPTIONS] [FUNCTION] + +Options: + --help Show this help message and exit + +Functions: + balance Fetch an account balance + benchmark Benchmark your hashpower + busses Fetch the bus account balances + claim Claim your mining rewards + close Close your account to recover rent + config Fetch the program config + mine Start mining + proof Fetch a proof account by address + rewards Fetch the current reward rate for each difficulty level + stake Stake to earn a rewards multiplier + transfer Send ORE to anyone, anywhere in the world. + upgrade Upgrade your ORE tokens from v1 to v2 + +Environment Variables: + RPC Set the RPC URL (mainnet, devnet, or custom URL) + BUFFER_TIME The number seconds before the deadline to stop mining and start submitting [default: 5] + CORES The number of CPU cores to allocate to mining [default: 1] + PRIORITY_FEE Price to pay for compute unit. If dynamic fee url is also set, this value will be the max. [default: 500000] + DYNAMIC_FEE_URL RPC URL to use for dynamic fee estimation. + DYNAMIC_FEE_STRATEGY Strategy to use for dynamic fee estimation. Must be one of 'helius', or 'triton'. + JITO Add jito tip to the miner. [default: false] + +Volumes: + To use your wallet files, mount them as volumes: + -v /path/to/your/id.json:/ore/id.json + Mount your wallet file, allowing the ore binary to access your wallet. + -v /path/to/your/payer.json:/ore/payer.json + Mount your payer wallet file, which is used to pay fees for transactions if the mine function is executed. + +Examples: + docker run -it -v /path/to/your/id.json:/ore/id.json myimage --help + docker run -it -v /path/to/your/id.json:/ore/id.json myimage mine + docker run -it -v /path/to/your/id.json:/ore/id.json myimage benchmark + docker run -it -v /path/to/your/id.json:/ore/id.json myimage config + docker run -it -v /path/to/your/id.json:/ore/id.json myimage rewards + docker run -it -v /path/to/your/id.json:/ore/id.json myimage busses +" +} + +set_rpc_url() { + case "$RPC" in + mainnet) RPC_URL="$MAINNET_URL" ;; + devnet | "") RPC_URL="$DEVNET_URL" ;; + *) RPC_URL="$RPC" ;; + esac +} + +display_header() { + echo " +############################################# +# _____ _____ _____ # +# | || __ || __| # +# | | || -|| __| # +# |_____||__|__||_____| # +# # +############################################# +# RPC URL: ${RPC_URL} +# BUFFER TIME: ${BUFFER_TIME:-5} +# CORES COUNT: ${CORES:-1} +# PRIORITY FEE: ${PRIORITY_FEE:-500000} +# DYNAMIC FEE URL: ${DYNAMIC_FEE_URL:-Not set} +# DYNAMIC FEE STRATEGY: ${DYNAMIC_FEE_STRATEGY:-Not set} +" +} + +validate_params() { + if [ "$FUNCTION" != "benchmark" ] && [ "$FUNCTION" != "config" ] && [ "$FUNCTION" != "rewards" ] && [ "$FUNCTION" != "busses" ]; then + [ ! -f "$WALLET_PATH" ] && echo -e "${RED}Error: Wallet file not found at $WALLET_PATH${NC}" && exit 1 + fi + [ ! -x "$(command -v ore)" ] && echo -e "${RED}Error: ore binary not found or not executable${NC}" && exit 1 + [ -z "$RPC_URL" ] && RPC_URL="$DEVNET_URL" + ! echo "$RPC_URL" | grep -qE '^https?://' && echo -e "${RED}Error: Invalid RPC_URL: $RPC_URL${NC}" && exit 1 + [ -n "$BUFFER_TIME" ] && ! echo "$BUFFER_TIME" | grep -qE '^[0-9]+$' && echo -e "${RED}Error: BUFFER_TIME must be a positive integer${NC}" && exit 1 + [ -n "$CORES" ] && ! echo "$CORES" | grep -qE '^[1-9][0-9]*$' && echo -e "${RED}Error: CORES must be a positive integer${NC}" && exit 1 + [ -n "$PRIORITY_FEE" ] && ! echo "$PRIORITY_FEE" | grep -qE '^[0-9]+$' && echo -e "${RED}Error: PRIORITY_FEE must be a non-negative integer${NC}" && exit 1 + [ -n "$DYNAMIC_FEE_URL" ] && ! echo "$DYNAMIC_FEE_URL" | grep -qE '^https?://' && echo -e "${RED}Error: Invalid DYNAMIC_FEE_URL: $DYNAMIC_FEE_URL${NC}" && exit 1 + [ -n "$DYNAMIC_FEE_STRATEGY" ] && ! echo "$DYNAMIC_FEE_STRATEGY" | grep -qE '^(helius|triton)$' && echo -e "${RED}Error: DYNAMIC_FEE_STRATEGY must be 'helius' or 'triton'${NC}" && exit 1 + [ -n "$JITO" ] && ! echo "$JITO" | grep -qE '^(true|false)$' && echo -e "${RED}Error: JITO must be 'true' or 'false'${NC}" && exit 1 +} + +build_command() { + if [ "$FUNCTION" = "benchmark" ] || [ "$FUNCTION" = "config" ] || [ "$FUNCTION" = "rewards" ] || [ "$FUNCTION" = "busses" ]; then + cmd="ore $FUNCTION" + [ -n "$CORES" ] && cmd="$cmd --cores \"$CORES\"" + else + cmd="ore --keypair \"$WALLET_PATH\" --rpc \"$RPC_URL\" $FUNCTION" + [ -f "$WALLET_PAYER_PATH" ] && cmd="$cmd --fee-payer \"$WALLET_PAYER_PATH\"" + if [ "$FUNCTION" = "mine" ]; then + [ -n "$BUFFER_TIME" ] && cmd="$cmd --buffer-time \"$BUFFER_TIME\"" + [ -n "$CORES" ] && cmd="$cmd --cores \"$CORES\"" + [ -n "$PRIORITY_FEE" ] && cmd="$cmd --priority-fee \"$PRIORITY_FEE\"" + [ -n "$DYNAMIC_FEE_URL" ] && cmd="$cmd --dynamic-fee-url \"$DYNAMIC_FEE_URL\"" + [ -n "$DYNAMIC_FEE_STRATEGY" ] && cmd="$cmd --dynamic-fee-strategy \"$DYNAMIC_FEE_STRATEGY\"" + [ "$JITO" = "true" ] && cmd="$cmd --jito" + fi + fi +} + +execute_command() { + sh -c "$cmd" + if [ $? -ne 0 ]; then + echo -e "${RED}Error: ore binary exited with non-zero status${NC}" + echo "Command executed: $cmd" + exit 1 + fi +} + +for arg in "$@" +do + case "$arg" in + --help) show_help; exit 0 ;; + balance|benchmark|busses|claim|close|config|proof|rewards|stake|upgrade) FUNCTION="$arg" ;; + esac +done + +set_rpc_url +if [ "$FUNCTION" = "mine" ]; then + display_header +fi +validate_params +build_command +execute_command \ No newline at end of file