Compare commits
3 Commits
main
..
memory_fix
| Author | SHA1 | Date | |
|---|---|---|---|
| 95077ed429 | |||
| 05e6cc8c18 | |||
| 5caf5833ad |
@@ -1,128 +0,0 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
#
|
||||
# Multi-stage Dockerfile для публикации образа dicoop/blockchain.
|
||||
#
|
||||
# Сборка ожидает два build-context, передаваемых через docker buildx:
|
||||
# --build-context coopos=<path-to-coopos-checkout>
|
||||
# --build-context cdt=<path-to-cdt-checkout>
|
||||
#
|
||||
# Результат: тонкий runtime-образ, содержащий nodeos/cleos/keosd/leap-util,
|
||||
# trace_api_util и установленный CDT (cdt-cpp и компания) в /usr/local.
|
||||
# Сборочные артефакты, исходники и build-зависимости в финальный образ
|
||||
# не попадают.
|
||||
|
||||
# ============================================================
|
||||
# Stage 1: builder — собирает blockchain (coopos) и CDT
|
||||
# ============================================================
|
||||
FROM ubuntu:22.04 AS builder
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV NEEDRESTART_MODE=a
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
clang \
|
||||
clang-tidy \
|
||||
cmake \
|
||||
git \
|
||||
libcurl4-openssl-dev \
|
||||
libgmp-dev \
|
||||
llvm-11-dev \
|
||||
libxml2-dev \
|
||||
opam \
|
||||
ocaml-interp \
|
||||
python3 \
|
||||
python3-pip \
|
||||
time \
|
||||
file \
|
||||
zlib1g-dev \
|
||||
g++-10 \
|
||||
unzip \
|
||||
ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN python3 -m pip install --no-cache-dir pygments
|
||||
|
||||
COPY --from=coopos . /blockchain
|
||||
COPY --from=cdt . /cdt
|
||||
|
||||
# Сборка blockchain (coopos). ENABLE_LEAP_DEV_DEB=ON активирует
|
||||
# component-based install (base + dev) и нужен для cpack -G DEB ниже,
|
||||
# чтобы получить два deb-пакета: coopos (runtime) и coopos-dev (headers,
|
||||
# libs, cmake-config — нужны для сборки контрактов и mono-тестов).
|
||||
RUN cd /blockchain \
|
||||
&& rm -rf build \
|
||||
&& mkdir build && cd build \
|
||||
&& cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_PREFIX_PATH=/usr/lib/llvm-11 \
|
||||
-DENABLE_LEAP_DEV_DEB=ON \
|
||||
.. \
|
||||
&& make -j"$(nproc)" \
|
||||
&& make install
|
||||
|
||||
# DEB-сборка вынесена в отдельный RUN, чтобы изменения в cpack
|
||||
# не инвалидировали тяжёлый build выше — он остаётся cache-hit.
|
||||
# tools/tweak-deb.sh из leap-наследия не запускаем: он cosmetically
|
||||
# чистит libc deps в control file, но рассчитан на dpkg <22.04
|
||||
# (control.tar.gz vs новый control.tar.zst) и падает на новых cpack.
|
||||
RUN cd /blockchain/build \
|
||||
&& cpack -G DEB \
|
||||
&& mkdir -p /out/deb \
|
||||
&& cp /blockchain/build/coopos_*.deb /blockchain/build/coopos-dev_*.deb /out/deb/ \
|
||||
&& ls -la /out/deb/
|
||||
|
||||
# Сборка CDT
|
||||
RUN cd /cdt \
|
||||
&& rm -rf build \
|
||||
&& mkdir build && cd build \
|
||||
&& cmake .. \
|
||||
&& make -j"$(nproc)" \
|
||||
&& make install
|
||||
|
||||
# ============================================================
|
||||
# Stage 2: runtime — тонкий итоговый образ
|
||||
# ============================================================
|
||||
FROM ubuntu:22.04 AS runtime
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV NEEDRESTART_MODE=a
|
||||
|
||||
# Минимум для запуска nodeos/cleos/keosd и сборки контрактов
|
||||
# через cdt-cpp внутри контейнера (cmake + make используют mono*).
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
cmake \
|
||||
make \
|
||||
gcc \
|
||||
g++ \
|
||||
python3 \
|
||||
python3-pip \
|
||||
ca-certificates \
|
||||
libcurl4 \
|
||||
libgmp10 \
|
||||
libxml2 \
|
||||
libllvm11 \
|
||||
libstdc++6 \
|
||||
libz3-4 \
|
||||
zlib1g \
|
||||
&& python3 -m pip install --no-cache-dir pygments \
|
||||
&& rm -rf /var/lib/apt/lists/* /root/.cache
|
||||
|
||||
COPY --from=builder /usr/local /usr/local
|
||||
|
||||
# Совместимость с mono*/components/contracts/CMakeLists.txt и с CDT
|
||||
# toolchain-файлом: CDTWasmToolchain.cmake жёстко прописывает пути
|
||||
# /cdt/build/bin/cdt-cc, /cdt/build/include, /cdt/build/lib и т.п.
|
||||
# Симлинк на установленный prefix /usr/local/cdt делает все эти пути
|
||||
# валидными внутри slim runtime.
|
||||
RUN mkdir -p /cdt && ln -s /usr/local/cdt /cdt/build
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
|
||||
# ============================================================
|
||||
# Stage 3: deb — экспортирует только .deb файлы наружу
|
||||
# Используется в CI как `--target deb --output type=local,dest=./deb-out`,
|
||||
# чтобы выгрузить пакеты на runner для публикации в GitHub Release.
|
||||
# ============================================================
|
||||
FROM scratch AS deb
|
||||
COPY --from=builder /out/deb/ /
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"ubuntu18": {
|
||||
"dockerfile": ".cicd/platforms/ubuntu18.Dockerfile"
|
||||
},
|
||||
"ubuntu20": {
|
||||
"dockerfile": ".cicd/platforms/ubuntu20.Dockerfile"
|
||||
},
|
||||
"ubuntu22": {
|
||||
"dockerfile": ".cicd/platforms/ubuntu22.Dockerfile"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
FROM ubuntu:bionic
|
||||
|
||||
RUN apt-get update && apt-get upgrade -y && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y build-essential \
|
||||
cmake \
|
||||
curl \
|
||||
g++-8 \
|
||||
git \
|
||||
jq \
|
||||
libcurl4-openssl-dev \
|
||||
libgmp-dev \
|
||||
libssl-dev \
|
||||
libusb-1.0-0-dev \
|
||||
llvm-7-dev \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
python3 \
|
||||
software-properties-common \
|
||||
zlib1g-dev \
|
||||
zstd
|
||||
|
||||
# GitHub's actions/checkout requires git 2.18+ but Ubuntu 18 only provides 2.17
|
||||
RUN add-apt-repository ppa:git-core/ppa && apt update && apt install -y git
|
||||
|
||||
# Leap requires boost 1.67+ but Ubuntu 18 only provides 1.65
|
||||
# Probably need 1.70+ to work properly with old cmake provided in Ubuntu 18
|
||||
RUN curl -L https://boostorg.jfrog.io/artifactory/main/release/1.79.0/source/boost_1_79_0.tar.bz2 | tar jx && \
|
||||
cd boost_* && \
|
||||
./bootstrap.sh --prefix=/boost && \
|
||||
./b2 --with-iostreams --with-date_time --with-filesystem --with-system \
|
||||
--with-program_options --with-chrono --with-test -j$(nproc) install && \
|
||||
cd .. && \
|
||||
rm -rf boost_*
|
||||
|
||||
ENV CC=gcc-8
|
||||
ENV CXX=g++-8
|
||||
ENV BOOST_ROOT=/boost
|
||||
ENV LLVM_DIR=/usr/lib/llvm-7/
|
||||
@@ -0,0 +1,17 @@
|
||||
FROM ubuntu:focal
|
||||
|
||||
RUN apt-get update && apt-get upgrade -y && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y build-essential \
|
||||
cmake \
|
||||
curl \
|
||||
git \
|
||||
jq \
|
||||
libboost-all-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libgmp-dev \
|
||||
libssl-dev \
|
||||
libusb-1.0-0-dev \
|
||||
llvm-11-dev \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
zstd
|
||||
@@ -0,0 +1,17 @@
|
||||
FROM ubuntu:jammy
|
||||
|
||||
RUN apt-get update && apt-get upgrade -y && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y build-essential \
|
||||
cmake \
|
||||
curl \
|
||||
git \
|
||||
jq \
|
||||
libboost-all-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libgmp-dev \
|
||||
libssl-dev \
|
||||
libusb-1.0-0-dev \
|
||||
llvm-11-dev \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
zstd
|
||||
@@ -1,19 +0,0 @@
|
||||
# Применяется и к основному context, и к build-context coopos в CI.
|
||||
# Цель — не инвалидировать слой `COPY --from=coopos` при изменениях,
|
||||
# не относящихся к сборке blockchain (CI-конфиги).
|
||||
#
|
||||
# КОНСЕРВАТИВНО: исключаем только то, что точно не читается cmake
|
||||
# или сборкой. README/LICENSE/docs могут быть прочитаны через
|
||||
# configure_file()/install() — оставляем.
|
||||
|
||||
build
|
||||
*.log
|
||||
|
||||
# CI/Docker meta — не читаются cmake. Dockerfile.publish сам в .cicd,
|
||||
# но он подаётся buildkit-у через `file:`, не через context.
|
||||
.cicd
|
||||
.github
|
||||
.dockerignore
|
||||
|
||||
# Только картинки и логотипы — точно не нужны
|
||||
images
|
||||
@@ -0,0 +1,201 @@
|
||||
name: "Build & Test"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- "release/*"
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
run-lr-tests:
|
||||
description: 'Run long running tests'
|
||||
type: boolean
|
||||
|
||||
permissions:
|
||||
packages: write
|
||||
contents: read
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
d:
|
||||
name: Discover Platforms
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
missing-platforms: ${{steps.discover.outputs.missing-platforms}}
|
||||
p: ${{steps.discover.outputs.platforms}}
|
||||
steps:
|
||||
- name: Discover Platforms
|
||||
id: discover
|
||||
uses: AntelopeIO/discover-platforms-action@v1
|
||||
with:
|
||||
platform-file: .cicd/platforms.json
|
||||
password: ${{secrets.GITHUB_TOKEN}}
|
||||
package-name: builders
|
||||
build-platforms:
|
||||
name: Build Platforms
|
||||
needs: d
|
||||
if: needs.d.outputs.missing-platforms != '[]'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: ${{fromJSON(needs.d.outputs.missing-platforms)}}
|
||||
runs-on: ["self-hosted", "enf-x86-beefy"]
|
||||
steps:
|
||||
- name: Login to Container Registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{github.repository_owner}}
|
||||
password: ${{secrets.GITHUB_TOKEN}}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
push: true
|
||||
tags: ${{fromJSON(needs.d.outputs.p)[matrix.platform].image}}
|
||||
file: ${{fromJSON(needs.d.outputs.p)[matrix.platform].dockerfile}}
|
||||
Build:
|
||||
needs: [d, build-platforms]
|
||||
if: always() && needs.d.result == 'success' && (needs.build-platforms.result == 'success' || needs.build-platforms.result == 'skipped')
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [ubuntu18, ubuntu20, ubuntu22]
|
||||
outputs:
|
||||
lr-tests: ${{steps.build.outputs.lr-tests}}
|
||||
runs-on: ["self-hosted", "enf-x86-beefy"]
|
||||
container: ${{fromJSON(needs.d.outputs.p)[matrix.platform].image}}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Build
|
||||
id: build
|
||||
run: |
|
||||
# https://github.com/actions/runner/issues/2033
|
||||
chown -R $(id -u):$(id -g) $PWD
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -GNinja ..
|
||||
ninja
|
||||
# the correct approach is by far "--show-only=json-v1 | jq '.tests[].name' | jq -sc" but that doesn't work on U18's cmake 3.10 since it lacks json-v1
|
||||
echo ::set-output name=lr-tests::$(ctest -L "long_running_tests" --show-only | head -n -1 | cut -d ':' -f 2 -s | jq -cnR '[inputs | select(length>0)[1:]]')
|
||||
tar -pc -C .. --exclude "*.a" --exclude "*.o" build | zstd --long -T0 -9 > ../build.tar.gz
|
||||
- name: Upload builddir
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{matrix.platform}}-build
|
||||
path: build.tar.gz
|
||||
- name: Build dev package (Ubuntu 20 only)
|
||||
if: matrix.platform == 'ubuntu20'
|
||||
run: |
|
||||
cd build
|
||||
ninja package
|
||||
- name: Upload dev package (Ubuntu 20 only)
|
||||
if: matrix.platform == 'ubuntu20'
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: leap-dev-ubuntu20-amd64
|
||||
path: build/leap-dev*.deb
|
||||
tests:
|
||||
name: Tests
|
||||
needs: [d, Build]
|
||||
if: always() && needs.Build.result == 'success'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [ubuntu20]
|
||||
runs-on: ["self-hosted", "enf-x86-beefy"]
|
||||
container: ${{fromJSON(needs.d.outputs.p)[matrix.platform].image}}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true
|
||||
- name: Download builddir
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: ${{matrix.platform}}-build
|
||||
- name: Run Parallel Tests
|
||||
run: |
|
||||
# https://github.com/actions/runner/issues/2033 -- need this because of full version label test looking at git revs
|
||||
chown -R $(id -u):$(id -g) $PWD
|
||||
zstdcat build.tar.gz | tar x
|
||||
cd build
|
||||
ctest --output-on-failure -j $(nproc) -LE "(nonparallelizable_tests|long_running_tests)"
|
||||
np-tests:
|
||||
name: NP Tests
|
||||
needs: [d, Build]
|
||||
if: always() && needs.Build.result == 'success'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [ubuntu20]
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ${{fromJSON(needs.d.outputs.p)[matrix.platform].image}}
|
||||
options: --init
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Download builddir
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: ${{matrix.platform}}-build
|
||||
- name: Run NP Tests
|
||||
run: |
|
||||
zstdcat build.tar.gz | tar x
|
||||
cd build
|
||||
ctest --output-on-failure -L "nonparallelizable_tests"
|
||||
- name: Bundle logs from failed tests
|
||||
if: failure()
|
||||
run: tar --ignore-failed-read -czf ${{matrix.platform}}-serial-logs.tar.gz build/var build/etc build/leap-ignition-wd
|
||||
- name: Upload logs from failed tests
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: ${{matrix.platform}}-serial-logs
|
||||
path: ${{matrix.platform}}-serial-logs.tar.gz
|
||||
lr-tests:
|
||||
name: LR Tests
|
||||
needs: [d, Build]
|
||||
if: always() && needs.Build.result == 'success' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/') || inputs.run-lr-tests)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [ubuntu20]
|
||||
test-name: ${{fromJSON(needs.Build.outputs.lr-tests)}}
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ${{fromJSON(needs.d.outputs.p)[matrix.platform].image}}
|
||||
options: --init
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Download builddir
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: ${{matrix.platform}}-build
|
||||
- name: Run ${{matrix.test-name}} Test
|
||||
run: |
|
||||
zstdcat build.tar.gz | tar x
|
||||
cd build
|
||||
ctest --output-on-failure -R ${{matrix.test-name}}
|
||||
- name: Bundle logs from failed tests
|
||||
if: failure()
|
||||
run: tar --ignore-failed-read -czf ${{matrix.platform}}-${{matrix.test-name}}-logs.tar.gz build/var build/etc build/leap-ignition-wd
|
||||
- name: Upload logs from failed tests
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: ${{matrix.platform}}-${{matrix.test-name}}-logs
|
||||
path: ${{matrix.platform}}-${{matrix.test-name}}-logs.tar.gz
|
||||
|
||||
all-passing:
|
||||
name: All Required Tests Passed
|
||||
needs: [tests, np-tests]
|
||||
if: always()
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- if: needs.tests.result != 'success' || needs.np-tests.result != 'success'
|
||||
run: false
|
||||
@@ -1,150 +0,0 @@
|
||||
name: Build & Publish Docker Image
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
cdt-ref:
|
||||
description: 'CDT git ref (branch/tag/sha) for coopenomics/cdt'
|
||||
required: false
|
||||
default: 'v4.2.0'
|
||||
version-tag:
|
||||
description: 'Override docker image tag (default: git tag or short sha)'
|
||||
required: false
|
||||
push-latest:
|
||||
description: 'Also push :latest'
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
env:
|
||||
IMAGE_NAME: dicoop/blockchain
|
||||
CDT_REPO: coopenomics/cdt
|
||||
|
||||
permissions:
|
||||
contents: write # нужен для публикации .deb в GitHub Release
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 360
|
||||
steps:
|
||||
- name: Free disk space on runner
|
||||
run: |
|
||||
sudo rm -rf /usr/share/dotnet \
|
||||
/usr/local/lib/android \
|
||||
/opt/ghc \
|
||||
/opt/hostedtoolcache/CodeQL \
|
||||
/usr/local/share/boost \
|
||||
"$AGENT_TOOLSDIRECTORY" \
|
||||
/opt/microsoft || true
|
||||
docker image prune -af || true
|
||||
df -h
|
||||
|
||||
- name: Checkout coopos
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
path: coopos
|
||||
|
||||
- name: Determine CDT ref
|
||||
id: cdtref
|
||||
run: |
|
||||
REF="${{ inputs.cdt-ref }}"
|
||||
if [ -z "$REF" ]; then REF="v4.2.0"; fi
|
||||
echo "ref=$REF" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Checkout CDT (${{ steps.cdtref.outputs.ref }})
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ env.CDT_REPO }}
|
||||
ref: ${{ steps.cdtref.outputs.ref }}
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
path: cdt
|
||||
|
||||
- name: Compute image tags
|
||||
id: meta
|
||||
run: |
|
||||
VERSION="${{ inputs.version-tag }}"
|
||||
if [ -z "$VERSION" ]; then
|
||||
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
|
||||
VERSION="${GITHUB_REF#refs/tags/}"
|
||||
else
|
||||
VERSION="${GITHUB_SHA::7}"
|
||||
fi
|
||||
fi
|
||||
TAGS="${IMAGE_NAME}:${VERSION}"
|
||||
if [[ "${{ inputs.push-latest }}" != "false" ]]; then
|
||||
TAGS="${TAGS},${IMAGE_NAME}:latest"
|
||||
fi
|
||||
echo "tags=${TAGS}" >> "$GITHUB_OUTPUT"
|
||||
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||
echo "Will publish: ${TAGS}"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build & Push (${{ steps.meta.outputs.version }})
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: ./coopos
|
||||
file: ./coopos/.cicd/Dockerfile.publish
|
||||
target: runtime
|
||||
build-contexts: |
|
||||
coopos=./coopos
|
||||
cdt=./cdt
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
cache-from: type=gha,scope=docker-publish
|
||||
cache-to: type=gha,mode=max,scope=docker-publish
|
||||
|
||||
- name: Extract .deb packages from builder
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: ./coopos
|
||||
file: ./coopos/.cicd/Dockerfile.publish
|
||||
target: deb
|
||||
build-contexts: |
|
||||
coopos=./coopos
|
||||
cdt=./cdt
|
||||
platforms: linux/amd64
|
||||
outputs: type=local,dest=./deb-out
|
||||
cache-from: type=gha,scope=docker-publish
|
||||
cache-to: type=gha,mode=max,scope=docker-publish
|
||||
|
||||
- name: List extracted .deb files
|
||||
run: ls -la ./deb-out/
|
||||
|
||||
- name: Publish .deb to GitHub Release (only on tag)
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ steps.meta.outputs.version }}
|
||||
files: |
|
||||
./deb-out/coopos_*.deb
|
||||
./deb-out/coopos-dev_*.deb
|
||||
fail_on_unmatched_files: true
|
||||
|
||||
- name: Upload .deb as workflow artifact (always)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coopos-deb-${{ steps.meta.outputs.version }}
|
||||
path: ./deb-out/*.deb
|
||||
retention-days: 30
|
||||
|
||||
- name: Image summary
|
||||
run: |
|
||||
echo "Published: ${{ steps.meta.outputs.tags }}" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "CDT ref: ${{ steps.cdtref.outputs.ref }}" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "DEB files extracted:" >> "$GITHUB_STEP_SUMMARY"
|
||||
(cd deb-out && ls -la) >> "$GITHUB_STEP_SUMMARY"
|
||||
@@ -1,18 +0,0 @@
|
||||
# .github/workflows/trigger-coopenomics.yml
|
||||
name: Trigger Contracts Docs Deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main] # или когда нужно триггерить
|
||||
|
||||
jobs:
|
||||
trigger-coopenomics:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Trigger Coopenomics deployment
|
||||
uses: peter-evans/repository-dispatch@v2
|
||||
with:
|
||||
token: ${{ secrets.COOPENOMICS_PAT }}
|
||||
repository: coopenomics/coopenomics # укажи правильный owner/repo
|
||||
event-type: deploy_from_mono
|
||||
client-payload: '{"repository": "${{ github.repository }}", "sha": "${{ github.sha }}", "ref": "${{ github.ref }}", "actor": "${{ github.actor }}"}'
|
||||
@@ -0,0 +1,58 @@
|
||||
name: "Pinned Build"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
packages: read
|
||||
contents: read
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
Build:
|
||||
name: Build
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [ubuntu18, ubuntu20, ubuntu22]
|
||||
runs-on: ["self-hosted", "enf-x86-beefy-long"]
|
||||
container: ${{ matrix.platform == 'ubuntu18' && 'ubuntu:bionic' || matrix.platform == 'ubuntu20' && 'ubuntu:focal' || 'ubuntu:jammy' }}
|
||||
steps:
|
||||
- name: Conditionally update git repo
|
||||
if: ${{ matrix.platform == 'ubuntu18' }}
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install -y software-properties-common
|
||||
apt-get update
|
||||
add-apt-repository ppa:git-core/ppa
|
||||
- name: Update and Install git
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install -y git
|
||||
git --version
|
||||
- name: Clone leap
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
# https://github.com/actions/runner/issues/2033
|
||||
chown -R $(id -u):$(id -g) $PWD
|
||||
./scripts/install_deps.sh
|
||||
- name: Build Pinned Build
|
||||
env:
|
||||
LEAP_PINNED_INSTALL_PREFIX: /usr
|
||||
run: |
|
||||
./scripts/pinned_build.sh deps build "$(nproc)"
|
||||
- name: Upload package
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: leap-${{matrix.platform}}-pinned-amd64
|
||||
path: build/leap-3*.deb
|
||||
- name: Run Parallel Tests
|
||||
run: |
|
||||
cd build
|
||||
ctest --output-on-failure -j $(nproc) -LE "(nonparallelizable_tests|long_running_tests)" --timeout 420
|
||||
@@ -11,7 +11,7 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout
|
||||
run: |
|
||||
git clone https://x-access-token:${{github.token}}@github.com/${GITHUB_REPOSITORY} .
|
||||
git clone https://github.com/${GITHUB_REPOSITORY} .
|
||||
git fetch -v --prune origin +refs/pull/${PR_NUMBER}/merge:refs/remotes/pull/${PR_NUMBER}/merge
|
||||
git checkout --force --progress refs/remotes/pull/${PR_NUMBER}/merge
|
||||
git submodule sync --recursive
|
||||
|
||||
+10
-10
@@ -5,21 +5,25 @@
|
||||
*.bc
|
||||
*.wast
|
||||
*.wast.hpp
|
||||
*.s
|
||||
*.dot
|
||||
*.abi.hpp
|
||||
*.cmake
|
||||
!.cicd
|
||||
!CMakeModules/*.cmake
|
||||
*.ninja
|
||||
\#*
|
||||
\.#*
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
cmake-build-*/
|
||||
cmake_install.cmake
|
||||
cmake-build-debug/
|
||||
cmake-build-release/
|
||||
Makefile
|
||||
compile_commands.json
|
||||
moc_*
|
||||
*.moc
|
||||
|
||||
.cache
|
||||
|
||||
genesis.json
|
||||
hardfork.hpp
|
||||
|
||||
@@ -70,25 +74,21 @@ witness_node_data_dir
|
||||
*.pyc
|
||||
*.pyo
|
||||
|
||||
*.gdb_history
|
||||
|
||||
Testing/*
|
||||
build.tar.gz
|
||||
[Bb]uild*/*
|
||||
build/*
|
||||
build-debug/*
|
||||
deps/*
|
||||
dependencies/*
|
||||
|
||||
etc/eosio/node_*
|
||||
TestLogs*
|
||||
var/lib/node_*
|
||||
.vscode
|
||||
.idea/
|
||||
*.iws
|
||||
.DS_Store
|
||||
CMakeLists.txt.user
|
||||
|
||||
!*.swagger.*
|
||||
|
||||
node_modules
|
||||
package-lock.json
|
||||
|
||||
snapshots
|
||||
|
||||
+9
-27
@@ -7,36 +7,18 @@
|
||||
[submodule "libraries/eos-vm"]
|
||||
path = libraries/eos-vm
|
||||
url = https://github.com/AntelopeIO/eos-vm
|
||||
[submodule "libraries/fc"]
|
||||
path = libraries/fc
|
||||
url = https://github.com/AntelopeIO/fc
|
||||
[submodule "libraries/softfloat"]
|
||||
path = libraries/softfloat
|
||||
url = https://github.com/AntelopeIO/berkeley-softfloat-3
|
||||
[submodule "libraries/rapidjson"]
|
||||
path = libraries/rapidjson
|
||||
url = https://github.com/Tencent/rapidjson/
|
||||
[submodule "libraries/yubihsm"]
|
||||
path = libraries/yubihsm
|
||||
url = https://github.com/Yubico/yubihsm-shell
|
||||
[submodule "tests/abieos"]
|
||||
path = tests/abieos
|
||||
url = https://github.com/AntelopeIO/abieos
|
||||
[submodule "libraries/libfc/include/fc/crypto/webauthn_json"]
|
||||
path = libraries/libfc/include/fc/crypto/webauthn_json
|
||||
url = https://github.com/Tencent/rapidjson/
|
||||
[submodule "libraries/libfc/secp256k1/secp256k1"]
|
||||
path = libraries/libfc/secp256k1/secp256k1
|
||||
url = https://github.com/bitcoin-core/secp256k1
|
||||
[submodule "libraries/prometheus/prometheus-cpp"]
|
||||
path = libraries/prometheus/prometheus-cpp
|
||||
url = https://github.com/jupp0r/prometheus-cpp.git
|
||||
[submodule "libraries/libfc/libraries/bn256"]
|
||||
path = libraries/libfc/libraries/bn256
|
||||
url = https://github.com/AntelopeIO/bn256
|
||||
[submodule "libraries/cli11/cli11"]
|
||||
path = libraries/cli11/cli11
|
||||
url = https://github.com/AntelopeIO/CLI11.git
|
||||
[submodule "libraries/libfc/libraries/bls12-381"]
|
||||
path = libraries/libfc/libraries/bls12-381
|
||||
url = https://github.com/AntelopeIO/bls12-381
|
||||
[submodule "libraries/boost"]
|
||||
path = libraries/boost
|
||||
url = https://github.com/boostorg/boost.git
|
||||
[submodule "libraries/libfc/libraries/boringssl/boringssl"]
|
||||
path = libraries/libfc/libraries/boringssl/boringssl
|
||||
url = https://github.com/AntelopeIO/boringssl-build
|
||||
[submodule "wasm-spec-tests"]
|
||||
path = wasm-spec-tests
|
||||
url = https://github.com/AntelopeIO/wasm-spec-tests
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
# coopos — рабочие заметки
|
||||
|
||||
Репозиторий: `coopenomics/coopos` (форк Antelope/Leap). Сборка → `dicoop/blockchain` (Docker) + `.deb`. Соседи: `~/docker-hub/` (тест-харнесс миграций/снимков), `~/playbooks/` (Ansible для прод-нод).
|
||||
|
||||
## Миграции версий (подтверждено 2026-05-05: 5.1.0 → 5.2.0)
|
||||
|
||||
Минорный апгрейд бесшовен при одинаковом toolchain:
|
||||
|
||||
```
|
||||
systemctl stop nodeos
|
||||
dpkg -i coopos_X.Y.Z-…amd64.deb
|
||||
systemctl start nodeos
|
||||
```
|
||||
|
||||
Без replay, без двух нод. Перед роллаутом — `~/docker-hub/scripts/test-deb-compat.sh` с актуальными .deb на одном data dir.
|
||||
|
||||
**Когда replay реально нужен:** правки в `libraries/chain/include/eosio/chain/*_object.hpp` (поля chainbase) или смена major gcc/boost у CI runner'а. Тогда план — snapshot → clean `data/state*` → start `--snapshot`.
|
||||
|
||||
**Подвох legacy-образов:** `dicoop/blockchain:v5.1.0-dev` (апрель 2024, старый Dockerfile с .deb от Leap) с современным `latest` несовместим по shared_memory из-за разного build env, не из-за кода. Не использовать pre-built образы старше нескольких месяцев как baseline миграционного теста.
|
||||
|
||||
**Why:** `chainbase` (boost::interprocess managed_mapped_file) сериализует структуры через memcpy memory layout — критично совпадение gcc/boost у двух последовательных бинарников.
|
||||
|
||||
## Полная нода ≠ snapshot
|
||||
|
||||
При диагностике проблемных нод coopos (api prod, moochest:nodeos) **не предлагать snapshot-restart как путь**, даже если на порядки быстрее. Задача именно полный resync через blocks.log; snapshot скрывает проблемы (OOM, форки, застревания), а не диагностирует их.
|
||||
|
||||
**How to apply:** варианты восстановления выбирать из множества `{trim+replay, hard-replay, ручной rebuild reversible/state}`. Snapshot — только если пользователь сейчас прямо просит «возьми снапшот».
|
||||
|
||||
**Why:** инцидент 2026-05-18 — при анализе сиротского блока 113,273,321 я предложил A) full replay B) snapshot, получил «Snapshot работает, я знаю. У меня нет задачи со Snapshot запускаться. Задача — полную ноду синхронизировать нормально».
|
||||
|
||||
Связанные операционные пометки про nodeos (replay OOM, SIGHUP во время startup) — в `~/playbooks/CLAUDE.md` → раздел EOSIO ops.
|
||||
|
||||
## Dockerfile.publish — всегда явный target
|
||||
|
||||
В `coopos/.cicd/Dockerfile.publish` стадии: `builder → runtime → deb (FROM scratch)`. У `docker/build-push-action` без `target:` публикуется **последняя** стадия — это `deb` (scratch с .deb), не `runtime`. Результат: `dicoop/blockchain:latest` улетает неработающим scratch-артефактом.
|
||||
|
||||
**How to apply:** в `coopos/.github/workflows/docker-publish.yaml` у любого шага `docker/build-push-action`, который пушит runtime-образ, **обязателен** `target: runtime`. Нельзя полагаться на «последняя стадия = runnable image» когда после неё есть scratch-export. Любая правка `Dockerfile.publish` со сменой порядка стадий — перепроверять оба build-push шага в workflow.
|
||||
|
||||
**Why:** инцидент 2026-05-07 — закоммитил multi-stage с `deb` в конце, в workflow забыл `target: runtime`; commit 9b6cadb3be7 переключился на сломанный `:latest`.
|
||||
|
||||
## Заготовка `~/docker-hub/` (тест-харнесс)
|
||||
|
||||
- `scripts/start.sh --image <name> --tag <tag> [--from-snapshot --clean --replay --hard-replay --extra "..." --follow]` — параметризуемый запуск через docker compose.
|
||||
- `scripts/{stop,status,fetch-snapshot,fetch-debs,build-deb-image}.sh` — операции.
|
||||
- `scripts/test-compat.sh` — снапшот-совместимость двух тегов в Docker Hub.
|
||||
- `scripts/test-deb-compat.sh` — миграция .deb на одном data dir (главный тест перед прод-апгрейдом).
|
||||
- `scripts/fork-snapshot.sh` — снапшот → JSON → JQ-патч → бинарь через `leap-util snapshot to-json/from-json` (subcommand `from-json` добавлен в coopos v5.2.0+, см. `programs/leap-util/actions/snapshot.cpp`).
|
||||
- `scripts/start-fork.sh` — поднимает локальный writable fork (без p2p, eosio продьюсит сам под dev-key). Подтверждено 2026-05-05: `eosio::updateauth` от dev-key принят форкнутой нодой.
|
||||
- `patches/dev-fork.jq` — точечный патч под coopos-снапшот (single-producer mode).
|
||||
- `config-fork/config.ini` — конфиг форкнутой ноды.
|
||||
|
||||
**Структура снапшота coopos** (подтверждено 2026-05-05): верхний уровень JSON — секции как ключи (не `.sections[]`), формат `{"eosio::chain::permission_object": {rows: [...], num_rows: N}, ...}`. Ключевые секции для патча: `permission_object`, `block_state.rows[0].active_schedule.producers[*].authority[1].keys`, `block_state.rows[0].valid_block_signing_authority[1].keys`. Coopos в single-producer mode — `eosio` единственный продьюсер.
|
||||
+72
-113
@@ -1,6 +1,6 @@
|
||||
cmake_minimum_required( VERSION 3.16 )
|
||||
cmake_minimum_required( VERSION 3.8 )
|
||||
|
||||
project( coopos )
|
||||
project( leap )
|
||||
include(CTest) # suppresses DartConfiguration.tcl error
|
||||
enable_testing()
|
||||
|
||||
@@ -9,14 +9,14 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
|
||||
include( GNUInstallDirs )
|
||||
include( MASSigning )
|
||||
|
||||
set( CMAKE_CXX_STANDARD 20 )
|
||||
set( CMAKE_CXX_STANDARD 17 )
|
||||
set( CMAKE_CXX_EXTENSIONS ON )
|
||||
set( CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set(VERSION_MAJOR 5)
|
||||
set(VERSION_MINOR 3)
|
||||
set(VERSION_PATCH 3)
|
||||
set(VERSION_SUFFIX "" CACHE STRING "Optional pre-release suffix appended to version (e.g. rc1, beta). Empty = clean release.")
|
||||
set(VERSION_MAJOR 3)
|
||||
set(VERSION_MINOR 1)
|
||||
set(VERSION_PATCH 5)
|
||||
#set(VERSION_SUFFIX rc4)
|
||||
|
||||
if(VERSION_SUFFIX)
|
||||
set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}")
|
||||
@@ -24,21 +24,18 @@ else()
|
||||
set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
|
||||
endif()
|
||||
|
||||
|
||||
# Options
|
||||
option(ENABLE_WERROR "Enable `-Werror` compilation flag." Off)
|
||||
option(ENABLE_WEXTRA "Enable `-Wextra` compilation flag." Off)
|
||||
|
||||
|
||||
set( CLI_CLIENT_EXECUTABLE_NAME cleos )
|
||||
set( NODE_EXECUTABLE_NAME nodeos )
|
||||
set( KEY_STORE_EXECUTABLE_NAME keosd )
|
||||
set( LEAP_UTIL_EXECUTABLE_NAME leap-util )
|
||||
|
||||
# http://stackoverflow.com/a/18369825
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.2)
|
||||
message(FATAL_ERROR "GCC version must be at least 10.2.0!")
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0)
|
||||
message(FATAL_ERROR "GCC version must be at least 8.0!")
|
||||
endif()
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
|
||||
message(FATAL_ERROR "Clang version must be at least 5.0!")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -54,6 +51,13 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS "ON")
|
||||
set(BUILD_DOXYGEN FALSE CACHE BOOL "Build doxygen documentation on every make")
|
||||
set(ENABLE_MULTIVERSION_PROTOCOL_TEST FALSE CACHE BOOL "Enable nodeos multiversion protocol test")
|
||||
|
||||
# add defaults for openssl
|
||||
if(APPLE AND UNIX AND "${OPENSSL_ROOT_DIR}" STREQUAL "")
|
||||
set(OPENSSL_ROOT_DIR "/usr/local/opt/openssl@3;/usr/local/opt/openssl@1.1")
|
||||
endif()
|
||||
# fc also adds these definitions to its public interface. once fc becomes the sole importer of openssl, this should be removed
|
||||
add_definitions(-DOPENSSL_API_COMPAT=0x10100000L -DOPENSSL_NO_DEPRECATED)
|
||||
|
||||
option(ENABLE_OC "Enable eosvm-oc on supported platforms" ON)
|
||||
|
||||
# WASM runtimes to enable. Each runtime in this list will have:
|
||||
@@ -66,7 +70,7 @@ if(ENABLE_OC AND CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32)
|
||||
# can be created with the exact version found
|
||||
find_package(LLVM REQUIRED CONFIG)
|
||||
if(LLVM_VERSION_MAJOR VERSION_LESS 7 OR LLVM_VERSION_MAJOR VERSION_GREATER_EQUAL 12)
|
||||
message(FATAL_ERROR "Coopos requires an LLVM version 7 through 11")
|
||||
message(FATAL_ERROR "Leap requires an LLVM version 7 through 11")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
@@ -92,6 +96,12 @@ else()
|
||||
set(no_whole_archive_flag "--no-whole-archive")
|
||||
endif()
|
||||
|
||||
set(Boost_USE_MULTITHREADED ON)
|
||||
set( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" )
|
||||
# Most boost deps get implictly picked up via fc, as just about everything links to fc. In addition we pick up
|
||||
# the pthread dependency through fc.
|
||||
find_package(Boost 1.67 REQUIRED COMPONENTS program_options unit_test_framework system)
|
||||
|
||||
if( APPLE AND UNIX )
|
||||
# Apple Specific Options Here
|
||||
message( STATUS "Configuring Leap on macOS" )
|
||||
@@ -113,23 +123,13 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_WERROR)
|
||||
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror" )
|
||||
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror" )
|
||||
endif()
|
||||
if(ENABLE_WEXTRA)
|
||||
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wextra" )
|
||||
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra" )
|
||||
endif()
|
||||
|
||||
|
||||
option(EOSIO_ENABLE_DEVELOPER_OPTIONS "enable developer options for Coopos" OFF)
|
||||
option(EOSIO_ENABLE_DEVELOPER_OPTIONS "enable developer options for Leap" OFF)
|
||||
|
||||
# based on http://www.delorie.com/gnu/docs/gdb/gdb_70.html
|
||||
# uncomment this line to tell GDB about macros (slows compile times)
|
||||
# set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -gdwarf-2 -g3" )
|
||||
|
||||
set(ENABLE_COVERAGE_TESTING FALSE CACHE BOOL "Build Coopos for code coverage analysis")
|
||||
set(ENABLE_COVERAGE_TESTING FALSE CACHE BOOL "Build Leap for code coverage analysis")
|
||||
|
||||
if(ENABLE_COVERAGE_TESTING)
|
||||
SET(CMAKE_C_FLAGS "--coverage ${CMAKE_C_FLAGS}")
|
||||
@@ -159,10 +159,9 @@ endif()
|
||||
|
||||
message( STATUS "Using '${EOSIO_ROOT_KEY}' as public key for 'eosio' account" )
|
||||
|
||||
option(ENABLE_TCMALLOC "use tcmalloc (requires gperftools)" OFF)
|
||||
if( ENABLE_TCMALLOC )
|
||||
find_package( Gperftools REQUIRED )
|
||||
message( STATUS "Compiling Coopos with TCMalloc")
|
||||
find_package( Gperftools QUIET )
|
||||
if( GPERFTOOLS_FOUND )
|
||||
message( STATUS "Found gperftools; compiling Leap with TCMalloc")
|
||||
#if doing this by the book, simply link_libraries( ${GPERFTOOLS_TCMALLOC} ) here. That will
|
||||
#give the performance benefits of tcmalloc but since it won't be linked last
|
||||
#the heap profiler & checker may not be accurate. This here is rather undocumented behavior
|
||||
@@ -171,14 +170,6 @@ if( ENABLE_TCMALLOC )
|
||||
set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} ${GPERFTOOLS_TCMALLOC}")
|
||||
endif()
|
||||
|
||||
# leap includes a bundled BoringSSL which conflicts with OpenSSL. Make sure any other bundled libraries (such as boost)
|
||||
# do not attempt to use an external OpenSSL in any manner
|
||||
set(CMAKE_DISABLE_FIND_PACKAGE_OpenSSL On)
|
||||
|
||||
# many tests require handling of signals themselves and even when they don't we'd like for them to generate a core dump, this
|
||||
# is effectively --catch_system_errors=no broadly across all tests
|
||||
add_compile_definitions(BOOST_TEST_DEFAULTS_TO_CORE_DUMP)
|
||||
|
||||
add_subdirectory( libraries )
|
||||
add_subdirectory( plugins )
|
||||
add_subdirectory( programs )
|
||||
@@ -186,10 +177,16 @@ add_subdirectory( scripts )
|
||||
add_subdirectory( unittests )
|
||||
add_subdirectory( tests )
|
||||
add_subdirectory( tools )
|
||||
add_subdirectory( benchmark )
|
||||
|
||||
option(DISABLE_WASM_SPEC_TESTS "disable building of wasm spec unit tests" OFF)
|
||||
|
||||
if (NOT DISABLE_WASM_SPEC_TESTS)
|
||||
add_subdirectory( wasm-spec-tests/generated-tests )
|
||||
endif()
|
||||
|
||||
install(FILES testnet.template DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/eosio/launcher COMPONENT dev EXCLUDE_FROM_ALL)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/testnet.template ${CMAKE_CURRENT_BINARY_DIR}/etc/eosio/launcher/testnet.template COPYONLY)
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/eosio.version.in ${CMAKE_CURRENT_BINARY_DIR}/eosio.version.hpp)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/eosio.version.hpp DESTINATION ${CMAKE_INSTALL_FULL_INCLUDEDIR} COMPONENT dev EXCLUDE_FROM_ALL)
|
||||
|
||||
@@ -198,7 +195,7 @@ set(EOS_ROOT_DIR "${CMAKE_BINARY_DIR}/lib")
|
||||
configure_file(${CMAKE_SOURCE_DIR}/CMakeModules/eosio-config.cmake.in ${CMAKE_BINARY_DIR}/lib/cmake/eosio/eosio-config.cmake @ONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/CMakeModules/EosioTesterBuild.cmake.in ${CMAKE_BINARY_DIR}/lib/cmake/eosio/EosioTester.cmake @ONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/CMakeModules/EosioCheckVersion.cmake ${CMAKE_BINARY_DIR}/lib/cmake/eosio/EosioCheckVersion.cmake COPYONLY)
|
||||
# new coopos CMake files
|
||||
# new leap CMake files
|
||||
configure_file(${CMAKE_SOURCE_DIR}/CMakeModules/leap-config.cmake.in ${CMAKE_BINARY_DIR}/lib/cmake/leap/leap-config.cmake @ONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/CMakeModules/EosioTesterBuild.cmake.in ${CMAKE_BINARY_DIR}/lib/cmake/leap/EosioTester.cmake @ONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/CMakeModules/EosioCheckVersion.cmake ${CMAKE_BINARY_DIR}/lib/cmake/leap/EosioCheckVersion.cmake COPYONLY)
|
||||
@@ -210,80 +207,41 @@ configure_file(${CMAKE_SOURCE_DIR}/CMakeModules/eosio-config.cmake.in ${CMAKE_BI
|
||||
install(FILES ${CMAKE_BINARY_DIR}/modules/eosio-config.cmake DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/eosio COMPONENT dev EXCLUDE_FROM_ALL)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/modules/EosioTester.cmake DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/eosio COMPONENT dev EXCLUDE_FROM_ALL)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/CMakeModules/EosioCheckVersion.cmake DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/eosio COMPONENT dev EXCLUDE_FROM_ALL)
|
||||
# new coopos CMake files
|
||||
# new leap CMake files
|
||||
configure_file(${CMAKE_SOURCE_DIR}/CMakeModules/leap-config.cmake.in ${CMAKE_BINARY_DIR}/modules/leap-config.cmake @ONLY)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/modules/leap-config.cmake DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/leap COMPONENT dev EXCLUDE_FROM_ALL)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/modules/EosioTester.cmake DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/leap COMPONENT dev EXCLUDE_FROM_ALL)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/CMakeModules/EosioCheckVersion.cmake DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/leap COMPONENT dev EXCLUDE_FROM_ALL)
|
||||
|
||||
configure_file(LICENSE licenses/leap/LICENSE COPYONLY)
|
||||
configure_file(libraries/softfloat/COPYING.txt licenses/leap/LICENSE.softfloat COPYONLY)
|
||||
configure_file(libraries/wasm-jit/LICENSE licenses/leap/LICENSE.wavm COPYONLY)
|
||||
configure_file(libraries/libfc/secp256k1/secp256k1/COPYING licenses/leap/LICENSE.secp256k1 COPYONLY)
|
||||
configure_file(libraries/libfc/include/fc/crypto/webauthn_json/license.txt licenses/leap/LICENSE.rapidjson COPYONLY)
|
||||
configure_file(libraries/eos-vm/LICENSE licenses/leap/LICENSE.eos-vm COPYONLY)
|
||||
configure_file(libraries/prometheus/prometheus-cpp/LICENSE licenses/leap/LICENSE.prom COPYONLY)
|
||||
configure_file(programs/cleos/LICENSE.CLI11 licenses/leap/LICENSE.CLI11 COPYONLY)
|
||||
configure_file(libraries/libfc/libraries/bls12-381/LICENSE licenses/leap/LICENSE.bls12-381 COPYONLY)
|
||||
configure_file(libraries/libfc/libraries/boringssl/boringssl/src/LICENSE licenses/leap/LICENSE.boringssl COPYONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/LICENSE
|
||||
${CMAKE_BINARY_DIR}/licenses/leap/LICENSE COPYONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/libraries/softfloat/COPYING.txt
|
||||
${CMAKE_BINARY_DIR}/licenses/leap/LICENSE.softfloat COPYONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/libraries/wasm-jit/LICENSE
|
||||
${CMAKE_BINARY_DIR}/licenses/leap/LICENSE.wavm COPYONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/libraries/fc/secp256k1/secp256k1/COPYING
|
||||
${CMAKE_BINARY_DIR}/licenses/leap/LICENSE.secp256k1 COPYONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/libraries/fc/include/fc/crypto/webauthn_json/license.txt
|
||||
${CMAKE_BINARY_DIR}/licenses/leap/LICENSE.rapidjson COPYONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/libraries/fc/src/network/LICENSE.go
|
||||
${CMAKE_BINARY_DIR}/licenses/leap/LICENSE.go COPYONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/libraries/yubihsm/LICENSE
|
||||
${CMAKE_BINARY_DIR}/licenses/leap/LICENSE.yubihsm COPYONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/libraries/eos-vm/LICENSE
|
||||
${CMAKE_BINARY_DIR}/licenses/leap/LICENSE.eos-vm COPYONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/programs/cleos/LICENSE.CLI11
|
||||
${CMAKE_BINARY_DIR}/programs/cleos/LICENSE.CLI11 COPYONLY)
|
||||
|
||||
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/licenses/leap" DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/" COMPONENT base)
|
||||
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/libraries/testing/contracts DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_testing/libraries/testing COMPONENT dev EXCLUDE_FROM_ALL
|
||||
PATTERN "CMakeFiles" EXCLUDE
|
||||
PATTERN "*.cmake" EXCLUDE
|
||||
PATTERN "Makefile" EXCLUDE)
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/unittests/contracts DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_testing/unittests COMPONENT dev EXCLUDE_FROM_ALL
|
||||
PATTERN "CMakeFiles" EXCLUDE
|
||||
PATTERN "*.cmake" EXCLUDE
|
||||
PATTERN "Makefile" EXCLUDE)
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tests/TestHarness DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_testing/tests COMPONENT dev EXCLUDE_FROM_ALL
|
||||
FILES_MATCHING
|
||||
PATTERN "*.py"
|
||||
PATTERN "*.json"
|
||||
PATTERN "__pycache__" EXCLUDE
|
||||
PATTERN "CMakeFiles" EXCLUDE)
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21)
|
||||
# Cmake versions < 3.21 did not support installing symbolic links to a directory via install(FILES ...)
|
||||
# Cmake 3.21 fixed this (https://gitlab.kitware.com/cmake/cmake/-/commit/d71a7cc19d6e03f89581efdaa8d63db216184d40)
|
||||
# If/when the lowest cmake version supported becomes >= 3.21, the else block as well as the postinit and prerm scripts
|
||||
# would be a good option to remove in favor of using the facilities in cmake / cpack directly.
|
||||
|
||||
add_custom_target(link_target ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory lib/python3/dist-packages
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink ../../../share/leap_testing/tests/TestHarness lib/python3/dist-packages/TestHarness
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory share/leap_testing
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink ../../bin share/leap_testing/bin)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib/python3/dist-packages/TestHarness DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/python3/dist-packages COMPONENT dev EXCLUDE_FROM_ALL)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/share/leap_testing/bin DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_testing COMPONENT dev EXCLUDE_FROM_ALL)
|
||||
else()
|
||||
# The following install(SCRIPT ...) steps are necessary for `make dev-install` to work on cmake versions < 3.21.
|
||||
install(SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/scripts/install_testharness_symlinks.cmake COMPONENT dev EXCLUDE_FROM_ALL)
|
||||
|
||||
# The `make package` installation of symlinks happens via the `postinst` script installed in cmake.package via the line below
|
||||
endif()
|
||||
|
||||
configure_file(${CMAKE_SOURCE_DIR}/libraries/cli11/bash-completion/completions/leap-util
|
||||
${CMAKE_BINARY_DIR}/programs/leap-util/bash-completion/completions/leap-util COPYONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/libraries/cli11/bash-completion/completions/cleos
|
||||
${CMAKE_BINARY_DIR}/programs/cleos/bash-completion/completions/cleos COPYONLY)
|
||||
|
||||
install(FILES libraries/cli11/bash-completion/completions/leap-util DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/bash-completion/completions COMPONENT base)
|
||||
install(FILES libraries/cli11/bash-completion/completions/cleos DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/bash-completion/completions COMPONENT base)
|
||||
|
||||
# Add the boost submodule we used to build to our install package, so headers can be found for libtester
|
||||
install(DIRECTORY "${CMAKE_SOURCE_DIR}/libraries/boost/"
|
||||
DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_boost
|
||||
COMPONENT dev EXCLUDE_FROM_ALL
|
||||
PATTERN ".git/*" EXCLUDE
|
||||
PATTERN "example/*" EXCLUDE
|
||||
PATTERN "bench/*" EXCLUDE
|
||||
PATTERN "doc/*" EXCLUDE
|
||||
PATTERN "libs/*/test" EXCLUDE
|
||||
PATTERN "tools/*/test" EXCLUDE
|
||||
)
|
||||
install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ COMPONENT base)
|
||||
install(FILES libraries/softfloat/COPYING.txt DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ RENAME LICENSE.softfloat COMPONENT base)
|
||||
install(FILES libraries/wasm-jit/LICENSE DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ RENAME LICENSE.wavm COMPONENT base)
|
||||
install(FILES libraries/fc/secp256k1/secp256k1/COPYING DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ RENAME LICENSE.secp256k1 COMPONENT base)
|
||||
install(FILES libraries/fc/include/fc/crypto/webauthn_json/license.txt DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ RENAME LICENSE.rapidjson COMPONENT base)
|
||||
install(FILES libraries/fc/src/network/LICENSE.go DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ COMPONENT base)
|
||||
install(FILES libraries/yubihsm/LICENSE DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ RENAME LICENSE.yubihsm COMPONENT base)
|
||||
install(FILES libraries/eos-vm/LICENSE DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ RENAME LICENSE.eos-vm COMPONENT base)
|
||||
install(FILES libraries/fc/libraries/ff/LICENSE DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ RENAME LICENSE.libff COMPONENT base)
|
||||
install(FILES programs/cleos/LICENSE.CLI11 DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/leap/ COMPONENT base)
|
||||
|
||||
add_custom_target(dev-install
|
||||
COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}"
|
||||
@@ -292,9 +250,10 @@ add_custom_target(dev-install
|
||||
USES_TERMINAL
|
||||
)
|
||||
|
||||
include(doxygen)
|
||||
get_property(_CTEST_CUSTOM_TESTS_IGNORE GLOBAL PROPERTY CTEST_CUSTOM_TESTS_IGNORE)
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/CTestCustom.cmake" "SET(CTEST_CUSTOM_TESTS_IGNORE ${_CTEST_CUSTOM_TESTS_IGNORE})")
|
||||
|
||||
option(ENABLE_LEAP_DEV_DEB "Enable building the leap-dev .deb package" OFF)
|
||||
include(doxygen)
|
||||
|
||||
include(package.cmake)
|
||||
include(CPack)
|
||||
|
||||
Regular → Executable
Regular → Executable
Regular → Executable
@@ -14,13 +14,19 @@ if (LLVM_DIR STREQUAL "" OR NOT LLVM_DIR)
|
||||
set(LLVM_DIR @LLVM_DIR@)
|
||||
endif()
|
||||
|
||||
find_package( Gperftools QUIET )
|
||||
if( GPERFTOOLS_FOUND )
|
||||
message( STATUS "Found gperftools; compiling tests with TCMalloc")
|
||||
list( APPEND PLATFORM_SPECIFIC_LIBS tcmalloc )
|
||||
endif()
|
||||
|
||||
if(NOT "@LLVM_FOUND@" STREQUAL "")
|
||||
find_package(LLVM @LLVM_VERSION@ EXACT REQUIRED CONFIG)
|
||||
llvm_map_components_to_libnames(LLVM_LIBS support core passes mcjit native DebugInfoDWARF orcjit)
|
||||
link_directories(${LLVM_LIBRARY_DIR})
|
||||
endif()
|
||||
|
||||
set( CMAKE_CXX_STANDARD 20 )
|
||||
set( CMAKE_CXX_STANDARD 17 )
|
||||
set( CMAKE_CXX_EXTENSIONS ON )
|
||||
set( CXX_STANDARD_REQUIRED ON )
|
||||
|
||||
@@ -35,26 +41,38 @@ else ( APPLE )
|
||||
set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS} -Wall")
|
||||
endif ( APPLE )
|
||||
|
||||
set( Boost_USE_MULTITHREADED ON )
|
||||
### Remove after Boost 1.70 CMake fixes are in place
|
||||
set( Boost_NO_BOOST_CMAKE ON CACHE STRING "ON or OFF" )
|
||||
set( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" )
|
||||
set( BOOST_EXCLUDE_LIBRARIES "mysql" )
|
||||
|
||||
add_subdirectory( @CMAKE_INSTALL_FULL_DATAROOTDIR@/leap_boost ${PROJECT_BINARY_DIR}/libraries/boost EXCLUDE_FROM_ALL)
|
||||
find_package(Boost @Boost_MAJOR_VERSION@.@Boost_MINOR_VERSION@ EXACT REQUIRED COMPONENTS
|
||||
date_time
|
||||
filesystem
|
||||
system
|
||||
chrono
|
||||
iostreams
|
||||
unit_test_framework)
|
||||
|
||||
find_library(libtester eosio_testing @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
find_library(libchain eosio_chain @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
find_library(libfc fc @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
find_library(libsecp256k1 secp256k1 @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
find_library(libbn256 bn256 @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
find_library(libbls12-381 bls12-381 @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
if ( "${CMAKE_BUILD_TYPE}" STREQUAL "Debug" )
|
||||
find_library(libfc fc_debug @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
find_library(libsecp256k1 secp256k1_debug @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
else()
|
||||
find_library(libfc fc @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
find_library(libsecp256k1 secp256k1 @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
endif()
|
||||
|
||||
find_library(libff ff @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
find_library(libwasm WASM @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
find_library(libwast WAST @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
find_library(libir IR @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
find_library(liblogging Logging @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
find_library(libruntime Runtime @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
find_library(libsoftfloat softfloat @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
find_library(libbscrypto bscrypto @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
find_library(libdecrepit decrepit @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
get_filename_component(cryptodir @OPENSSL_CRYPTO_LIBRARY@ DIRECTORY)
|
||||
find_library(liboscrypto crypto "${cryptodir}" NO_DEFAULT_PATH)
|
||||
get_filename_component(ssldir @OPENSSL_SSL_LIBRARY@ DIRECTORY)
|
||||
find_library(libosssl ssl "${ssldir}" NO_DEFAULT_PATH)
|
||||
find_library(libchainbase chainbase @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
find_library(libbuiltins builtins @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH)
|
||||
|
||||
@@ -68,71 +86,53 @@ if("eos-vm-oc" IN_LIST EOSIO_WASM_RUNTIMES)
|
||||
set(WRAP_MAIN "-Wl,-wrap=main")
|
||||
endif()
|
||||
|
||||
add_library(EosioChain INTERFACE)
|
||||
|
||||
target_link_libraries(EosioChain INTERFACE
|
||||
${libchain}
|
||||
${libfc}
|
||||
${libwast}
|
||||
${libwasm}
|
||||
${libir}
|
||||
${libsoftfloat}
|
||||
${libbscrypto}
|
||||
${libdecrepit}
|
||||
${liblogging}
|
||||
${libchainbase}
|
||||
${libbuiltins}
|
||||
${libsecp256k1}
|
||||
${libbn256}
|
||||
${libbls12-381}
|
||||
@GMP_LIBRARY@
|
||||
|
||||
Boost::date_time
|
||||
Boost::filesystem
|
||||
Boost::system
|
||||
Boost::chrono
|
||||
Boost::multi_index
|
||||
Boost::multiprecision
|
||||
Boost::interprocess
|
||||
Boost::asio
|
||||
Boost::signals2
|
||||
Boost::iostreams
|
||||
"-lz" # Needed by Boost iostreams
|
||||
|
||||
${LLVM_LIBS}
|
||||
|
||||
${PLATFORM_SPECIFIC_LIBS}
|
||||
|
||||
${WRAP_MAIN}
|
||||
Threads::Threads
|
||||
)
|
||||
|
||||
target_include_directories(EosioChain INTERFACE
|
||||
@OPENSSL_INCLUDE_DIR@
|
||||
@CMAKE_INSTALL_PREFIX@
|
||||
@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||
@CMAKE_INSTALL_FULL_INCLUDEDIR@/wasm-jit
|
||||
@CMAKE_INSTALL_FULL_INCLUDEDIR@/leapboringssl
|
||||
@CMAKE_INSTALL_FULL_INCLUDEDIR@/softfloat )
|
||||
|
||||
#adds -ltr. Ubuntu eosio.contracts build breaks without this
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(EosioChain INTERFACE ${LIBRT})
|
||||
endif()
|
||||
|
||||
add_library(EosioTester INTERFACE)
|
||||
|
||||
target_link_libraries(EosioTester INTERFACE
|
||||
${libtester}
|
||||
Boost::unit_test_framework
|
||||
EosioChain
|
||||
)
|
||||
|
||||
macro(add_eosio_test_executable test_name)
|
||||
add_executable( ${test_name} ${ARGN} )
|
||||
target_link_libraries( ${test_name}
|
||||
EosioTester
|
||||
${libtester}
|
||||
${libchain}
|
||||
${libfc}
|
||||
${libwast}
|
||||
${libwasm}
|
||||
${libruntime}
|
||||
${libir}
|
||||
${libsoftfloat}
|
||||
${liboscrypto}
|
||||
${libosssl}
|
||||
${liblogging}
|
||||
${libchainbase}
|
||||
${libbuiltins}
|
||||
${libsecp256k1}
|
||||
${libff}
|
||||
@GMP_LIBRARY@
|
||||
|
||||
${Boost_FILESYSTEM_LIBRARY}
|
||||
${Boost_SYSTEM_LIBRARY}
|
||||
${Boost_CHRONO_LIBRARY}
|
||||
${Boost_IOSTREAMS_LIBRARY}
|
||||
"-lz" # Needed by Boost iostreams
|
||||
${Boost_DATE_TIME_LIBRARY}
|
||||
|
||||
${LLVM_LIBS}
|
||||
|
||||
${PLATFORM_SPECIFIC_LIBS}
|
||||
|
||||
${WRAP_MAIN}
|
||||
Threads::Threads
|
||||
)
|
||||
|
||||
#adds -ltr. Ubuntu eosio.contracts build breaks without this
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(${test_name} ${LIBRT})
|
||||
endif()
|
||||
|
||||
target_include_directories( ${test_name} PUBLIC
|
||||
${Boost_INCLUDE_DIRS}
|
||||
@OPENSSL_INCLUDE_DIR@
|
||||
@CMAKE_INSTALL_PREFIX@
|
||||
@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||
@CMAKE_INSTALL_FULL_INCLUDEDIR@/wasm-jit
|
||||
@CMAKE_INSTALL_FULL_INCLUDEDIR@/softfloat )
|
||||
|
||||
endmacro()
|
||||
|
||||
|
||||
@@ -12,13 +12,19 @@ if (LLVM_DIR STREQUAL "" OR NOT LLVM_DIR)
|
||||
set(LLVM_DIR @LLVM_DIR@)
|
||||
endif()
|
||||
|
||||
find_package( Gperftools QUIET )
|
||||
if( GPERFTOOLS_FOUND )
|
||||
message( STATUS "Found gperftools; compiling tests with TCMalloc")
|
||||
list( APPEND PLATFORM_SPECIFIC_LIBS tcmalloc )
|
||||
endif()
|
||||
|
||||
if(NOT "@LLVM_FOUND@" STREQUAL "")
|
||||
find_package(LLVM @LLVM_VERSION@ EXACT REQUIRED CONFIG)
|
||||
llvm_map_components_to_libnames(LLVM_LIBS support core passes mcjit native DebugInfoDWARF orcjit)
|
||||
link_directories(${LLVM_LIBRARY_DIR})
|
||||
endif()
|
||||
|
||||
set( CMAKE_CXX_STANDARD 20 )
|
||||
set( CMAKE_CXX_STANDARD 17 )
|
||||
set( CMAKE_CXX_EXTENSIONS ON )
|
||||
set( CXX_STANDARD_REQUIRED ON )
|
||||
|
||||
@@ -32,26 +38,39 @@ else ( APPLE )
|
||||
set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS} -Wall")
|
||||
endif ( APPLE )
|
||||
|
||||
set( Boost_USE_MULTITHREADED ON )
|
||||
### Remove after Boost 1.70 CMake fixes are in place
|
||||
set( Boost_NO_BOOST_CMAKE ON CACHE STRING "ON or OFF" )
|
||||
set( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" )
|
||||
set( BOOST_EXCLUDE_LIBRARIES "mysql" )
|
||||
|
||||
add_subdirectory( @CMAKE_SOURCE_DIR@/libraries/boost ${PROJECT_BINARY_DIR}/libraries/boost EXCLUDE_FROM_ALL)
|
||||
find_package(Boost @Boost_MAJOR_VERSION@.@Boost_MINOR_VERSION@ EXACT REQUIRED COMPONENTS
|
||||
date_time
|
||||
filesystem
|
||||
system
|
||||
chrono
|
||||
iostreams
|
||||
unit_test_framework)
|
||||
|
||||
find_library(libtester eosio_testing @CMAKE_BINARY_DIR@/libraries/testing NO_DEFAULT_PATH)
|
||||
find_library(libchain eosio_chain @CMAKE_BINARY_DIR@/libraries/chain NO_DEFAULT_PATH)
|
||||
find_library(libfc fc @CMAKE_BINARY_DIR@/libraries/libfc NO_DEFAULT_PATH)
|
||||
find_library(libsecp256k1 secp256k1 @CMAKE_BINARY_DIR@/libraries/libfc/secp256k1 NO_DEFAULT_PATH)
|
||||
find_library(libbn256 bn256 @CMAKE_BINARY_DIR@/libraries/libfc/libraries/bn256/src NO_DEFAULT_PATH)
|
||||
find_library(libbls12-381 bls12-381 @CMAKE_BINARY_DIR@/libraries/libfc/libraries/bls12-381 NO_DEFAULT_PATH)
|
||||
if ( "${CMAKE_BUILD_TYPE}" STREQUAL "Debug" )
|
||||
find_library(libfc fc_debug @CMAKE_BINARY_DIR@/libraries/fc NO_DEFAULT_PATH)
|
||||
find_library(libsecp256k1 secp256k1_debug @CMAKE_BINARY_DIR@/libraries/fc/secp256k1 NO_DEFAULT_PATH)
|
||||
|
||||
else()
|
||||
find_library(libfc fc @CMAKE_BINARY_DIR@/libraries/fc NO_DEFAULT_PATH)
|
||||
find_library(libsecp256k1 secp256k1 @CMAKE_BINARY_DIR@/libraries/fc/secp256k1 NO_DEFAULT_PATH)
|
||||
endif()
|
||||
|
||||
find_library(libff ff @CMAKE_BINARY_DIR@/libraries/fc/libraries/ff/libff NO_DEFAULT_PATH)
|
||||
find_library(libwasm WASM @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/WASM NO_DEFAULT_PATH)
|
||||
find_library(libwast WAST @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/WAST NO_DEFAULT_PATH)
|
||||
find_library(libir IR @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/IR NO_DEFAULT_PATH)
|
||||
find_library(liblogging Logging @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/Logging NO_DEFAULT_PATH)
|
||||
find_library(libruntime Runtime @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/Runtime NO_DEFAULT_PATH)
|
||||
find_library(libsoftfloat softfloat @CMAKE_BINARY_DIR@/libraries/softfloat NO_DEFAULT_PATH)
|
||||
find_library(libbscrypto bscrypto @CMAKE_BINARY_DIR@/libraries/libfc/libraries/boringssl/boringssl NO_DEFAULT_PATH)
|
||||
find_library(libdecrepit decrepit @CMAKE_BINARY_DIR@/libraries/libfc/libraries/boringssl/boringssl NO_DEFAULT_PATH)
|
||||
get_filename_component(cryptodir @OPENSSL_CRYPTO_LIBRARY@ DIRECTORY)
|
||||
find_library(liboscrypto crypto "${cryptodir}" NO_DEFAULT_PATH)
|
||||
get_filename_component(ssldir @OPENSSL_SSL_LIBRARY@ DIRECTORY)
|
||||
find_library(libosssl ssl "${ssldir}" NO_DEFAULT_PATH)
|
||||
find_library(libchainbase chainbase @CMAKE_BINARY_DIR@/libraries/chainbase NO_DEFAULT_PATH)
|
||||
find_library(libbuiltins builtins @CMAKE_BINARY_DIR@/libraries/builtins NO_DEFAULT_PATH)
|
||||
|
||||
@@ -65,79 +84,57 @@ if("eos-vm-oc" IN_LIST EOSIO_WASM_RUNTIMES)
|
||||
set(WRAP_MAIN "-Wl,-wrap=main")
|
||||
endif()
|
||||
|
||||
add_library(EosioChain INTERFACE)
|
||||
|
||||
target_link_libraries(EosioChain INTERFACE
|
||||
${libchain}
|
||||
${libfc}
|
||||
${libwast}
|
||||
${libwasm}
|
||||
${libir}
|
||||
${libsoftfloat}
|
||||
${libbscrypto}
|
||||
${libdecrepit}
|
||||
${liblogging}
|
||||
${libchainbase}
|
||||
${libbuiltins}
|
||||
${libsecp256k1}
|
||||
${libbn256}
|
||||
${libbls12-381}
|
||||
@GMP_LIBRARY@
|
||||
|
||||
Boost::date_time
|
||||
Boost::filesystem
|
||||
Boost::system
|
||||
Boost::chrono
|
||||
Boost::multi_index
|
||||
Boost::multiprecision
|
||||
Boost::interprocess
|
||||
Boost::asio
|
||||
Boost::signals2
|
||||
Boost::iostreams
|
||||
"-lz" # Needed by Boost iostreams
|
||||
|
||||
${LLVM_LIBS}
|
||||
|
||||
${PLATFORM_SPECIFIC_LIBS}
|
||||
|
||||
${WRAP_MAIN}
|
||||
Threads::Threads
|
||||
)
|
||||
|
||||
target_include_directories(EosioChain INTERFACE
|
||||
@OPENSSL_INCLUDE_DIR@
|
||||
@CMAKE_SOURCE_DIR@/libraries/chain/include
|
||||
@CMAKE_BINARY_DIR@/libraries/chain/include
|
||||
@CMAKE_SOURCE_DIR@/libraries/libfc/include
|
||||
@CMAKE_SOURCE_DIR@/libraries/libfc/libraries/boringssl/boringssl/src/include
|
||||
@CMAKE_SOURCE_DIR@/libraries/softfloat/source/include
|
||||
@CMAKE_SOURCE_DIR@/libraries/appbase/include
|
||||
@CMAKE_SOURCE_DIR@/libraries/chainbase/include
|
||||
@CMAKE_SOURCE_DIR@/libraries/wasm-jit/include )
|
||||
|
||||
|
||||
#adds -ltr. Ubuntu eosio.contracts build breaks without this
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(EosioChain INTERFACE ${LIBRT})
|
||||
endif()
|
||||
|
||||
add_library(EosioTester INTERFACE)
|
||||
|
||||
target_link_libraries(EosioTester INTERFACE
|
||||
${libtester}
|
||||
Boost::unit_test_framework
|
||||
EosioChain
|
||||
)
|
||||
|
||||
target_include_directories(EosioTester INTERFACE
|
||||
@CMAKE_SOURCE_DIR@/libraries/testing/include )
|
||||
|
||||
macro(add_eosio_test_executable test_name)
|
||||
add_executable( ${test_name} ${ARGN} )
|
||||
target_link_libraries( ${test_name}
|
||||
EosioTester
|
||||
)
|
||||
${libtester}
|
||||
${libchain}
|
||||
${libfc}
|
||||
${libwast}
|
||||
${libwasm}
|
||||
${libruntime}
|
||||
${libir}
|
||||
${libsoftfloat}
|
||||
${liboscrypto}
|
||||
${libosssl}
|
||||
${liblogging}
|
||||
${libchainbase}
|
||||
${libbuiltins}
|
||||
${libsecp256k1}
|
||||
${libff}
|
||||
@GMP_LIBRARY@
|
||||
|
||||
${Boost_FILESYSTEM_LIBRARY}
|
||||
${Boost_SYSTEM_LIBRARY}
|
||||
${Boost_CHRONO_LIBRARY}
|
||||
${Boost_IOSTREAMS_LIBRARY}
|
||||
"-lz" # Needed by Boost iostreams
|
||||
${Boost_DATE_TIME_LIBRARY}
|
||||
|
||||
${LLVM_LIBS}
|
||||
|
||||
${PLATFORM_SPECIFIC_LIBS}
|
||||
|
||||
${WRAP_MAIN}
|
||||
Threads::Threads
|
||||
)
|
||||
|
||||
#adds -ltr. Ubuntu eosio.contracts build breaks without this
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(${test_name} ${LIBRT})
|
||||
endif()
|
||||
|
||||
target_include_directories( ${test_name} PUBLIC
|
||||
${Boost_INCLUDE_DIRS}
|
||||
@OPENSSL_INCLUDE_DIR@
|
||||
@CMAKE_SOURCE_DIR@/libraries/chain/include
|
||||
@CMAKE_BINARY_DIR@/libraries/chain/include
|
||||
@CMAKE_SOURCE_DIR@/libraries/fc/include
|
||||
@CMAKE_SOURCE_DIR@/libraries/softfloat/source/include
|
||||
@CMAKE_SOURCE_DIR@/libraries/appbase/include
|
||||
@CMAKE_SOURCE_DIR@/libraries/chainbase/include
|
||||
@CMAKE_SOURCE_DIR@/libraries/testing/include
|
||||
@CMAKE_SOURCE_DIR@/libraries/wasm-jit/Include )
|
||||
endmacro()
|
||||
|
||||
macro(add_eosio_test test_name)
|
||||
@@ -179,7 +176,7 @@ if(ENABLE_COVERAGE_TESTING)
|
||||
|
||||
COMMAND ${LCOV_PATH} --directory . --capture --gcov-tool ${CMAKE_SOURCE_DIR}/tools/llvm-gcov.sh --output-file ${Coverage_NAME}.info
|
||||
|
||||
COMMAND ${LCOV_PATH} -remove ${Coverage_NAME}.info '*/boost/*' '/usr/lib/*' '/usr/include/*' '*/externals/*' '*/libfc/*' '*/wasm-jit/*' --output-file ${Coverage_NAME}_filtered.info
|
||||
COMMAND ${LCOV_PATH} -remove ${Coverage_NAME}.info '*/boost/*' '/usr/lib/*' '/usr/include/*' '*/externals/*' '*/fc/*' '*/wasm-jit/*' --output-file ${Coverage_NAME}_filtered.info
|
||||
|
||||
COMMAND ${GENHTML_PATH} -o ${Coverage_NAME} ${PROJECT_BINARY_DIR}/${Coverage_NAME}_filtered.info
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
FROM ubuntu:latest
|
||||
|
||||
WORKDIR /workdir
|
||||
COPY build/leap*.deb /workdir/build/
|
||||
|
||||
RUN apt-get update && cd build && \
|
||||
apt-get install -y ./leap*.deb -y && \
|
||||
rm leap*.deb
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
COOPOS/coopos
|
||||
Copyright (c) 2024-2025 CBS VOSKHOD and its contributors. All rights reserved.
|
||||
|
||||
The MIT License
|
||||
|
||||
AntelopeIO/leap
|
||||
Copyright (c) 2021-2022 EOS Network Foundation (ENF) and its contributors. All rights reserved.
|
||||
This ENF software is based upon:
|
||||
|
||||
@@ -1,454 +1,257 @@
|
||||
# Coopos
|
||||
# Leap
|
||||
Leap is a C++ implementation of the [Antelope](https://github.com/AntelopeIO) protocol. It contains blockchain node software and supporting tools for developers and node operators.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Coopos - операционная система смарт-контрактов платформы Кооперативной Экономики (https://coopenomics.world).
|
||||
## Branches
|
||||
The `main` branch is the development branch; do not use it for production. Refer to the [release page](https://github.com/AntelopeIO/leap/releases) for current information on releases, pre-releases, and obsolete releases, as well as the corresponding tags for those releases.
|
||||
|
||||
1. [Ветки](#branches)
|
||||
2. [Быстрый старт с Docker](#docker-quick-start)
|
||||
3. [Поддерживаемые операционные системы](#supported-operating-systems)
|
||||
4. [Бинарная установка](#binary-installation)
|
||||
5. [Запуск ноды на основной сети](#join-mainnet)
|
||||
6. [Сборка и установка из исходного кода](#build-and-install-from-source)
|
||||
7. [Bash автодополнение](#bash-autocomplete)
|
||||
|
||||
Coopos - это C++ реализация протокола [Antelope](https://github.com/AntelopeIO) с расширениями для кооперативной экономики. Содержит программное обеспечение блокчейн-узла и вспомогательные инструменты для разработчиков и операторов узлов.
|
||||
|
||||
## Ветки
|
||||
Ветка `main` является веткой разработки; не используйте её для продакшена. Обратитесь к [странице релизов](https://github.com/AntelopeIO/leap/releases) для получения актуальной информации о релизах, предварительных релизах и устаревших релизах, а также соответствующих тегах для этих релизов.
|
||||
|
||||
## Быстрый старт с Docker
|
||||
|
||||
Для быстрого знакомства с Coopos и разработки смарт-контрактов на любой операционной системе (Windows, macOS, Linux) рекомендуется использовать готовый Docker-контейнер.
|
||||
|
||||
### Запуск контейнера
|
||||
|
||||
```bash
|
||||
docker run -it --rm \
|
||||
-v $(pwd)/workspace:/workspace \
|
||||
-p 8888:8888 \
|
||||
-p 9876:9876 \
|
||||
-p 8070:8070 \
|
||||
dicoop/blockchain_v5.1.1:dev
|
||||
```
|
||||
|
||||
### Что включено в контейнер
|
||||
|
||||
Контейнер основан на том же исходном коде Coopos и дополнительно содержит:
|
||||
- **CDT (Contract Development Toolkit)** - инструменты для компиляции смарт-контрактов
|
||||
- **eosio-cpp** - компилятор смарт-контрактов
|
||||
- **cleos** - командная строка для взаимодействия с блокчейном
|
||||
- **nodeos** - блокчейн-узел
|
||||
- **leap-util** - дополнительные утилиты
|
||||
- **Все необходимые зависимости** для разработки и запуска
|
||||
|
||||
### Использование
|
||||
|
||||
```bash
|
||||
# В контейнере вы можете сразу начать разработку
|
||||
cd /workspace
|
||||
|
||||
# Создать новый смарт-контракт
|
||||
eosio-cpp -abigen hello.cpp -o hello.wasm
|
||||
|
||||
# Запустить локальный блокчейн-узел с полным набором параметров
|
||||
nodeos \
|
||||
# Основные плагины для работы блокчейн-узла
|
||||
--plugin eosio::chain_plugin \
|
||||
--plugin eosio::producer_plugin \
|
||||
--plugin eosio::chain_api_plugin \
|
||||
--plugin eosio::http_plugin \
|
||||
--plugin eosio::state_history_plugin \
|
||||
--plugin eosio::producer_api_plugin \
|
||||
--plugin eosio::resource_monitor_plugin \
|
||||
# Настройки производства блоков
|
||||
--enable-stale-production true \
|
||||
--read-only-read-window-time-us 120000 \
|
||||
--producer-name eosio \
|
||||
--producer-name core \
|
||||
--signature-provider EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV=KEY:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3 \
|
||||
# Сетевые настройки
|
||||
--net-threads 2 \
|
||||
--p2p-listen-endpoint 0.0.0.0:9876 \
|
||||
# HTTP API настройки
|
||||
--http-server-address 0.0.0.0:8888 \
|
||||
--access-control-allow-origin "*" \
|
||||
--access-control-allow-credentials false \
|
||||
--http-validate-host false \
|
||||
--verbose-http-errors true \
|
||||
--http-max-response-time-ms 30000 \
|
||||
--max-body-size 10485760 \
|
||||
# Настройки производительности и лимитов
|
||||
--max-transaction-time 2000 \
|
||||
--abi-serializer-max-time-ms 200000 \
|
||||
--max-block-cpu-usage-threshold-us 5000 \
|
||||
--max-block-net-usage-threshold-bytes 1024 \
|
||||
# Отладка и история
|
||||
--contracts-console true \
|
||||
--chain-state-history true \
|
||||
--trace-history true \
|
||||
--state-history-endpoint 0.0.0.0:8070 \
|
||||
# Мониторинг ресурсов
|
||||
--resource-monitor-space-threshold 90 \
|
||||
--resource-monitor-not-shutdown-on-threshold-exceeded true \
|
||||
# WASM runtime
|
||||
--wasm-runtime eos-vm
|
||||
```
|
||||
|
||||
### Монтирование рабочей директории
|
||||
|
||||
Параметр `-v $(pwd)/workspace:/workspace` монтирует вашу локальную папку `workspace` в контейнер, позволяя работать с файлами на хост-системе.
|
||||
|
||||
> ⚠️ **Важно:** Для регулярной стабильной работы и продакшена рекомендуется установка deb-пакета или сборка из исходного кода на нативной системе. Docker-контейнер предназначен для разработки и тестирования.
|
||||
|
||||
## Поддерживаемые операционные системы
|
||||
В настоящее время мы поддерживаем следующие операционные системы:
|
||||
## Supported Operating Systems
|
||||
We currently support the following operating systems.
|
||||
- Ubuntu 22.04 Jammy
|
||||
- Ubuntu 20.04 Focal
|
||||
- Ubuntu 18.04 Bionic
|
||||
|
||||
Другие Unix-производные, такие как macOS, поддерживаются в режиме best-effort и могут быть не полностью функциональными. Если вы не используете Ubuntu, посетите страницу "[Сборка неподдерживаемой ОС](./docs/00_install/01_build-from-source/00_build-unsupported-os.md)" для изучения ваших вариантов.
|
||||
Other Unix derivatives such as macOS are tended to on a best-effort basis and may not be full featured. If you aren't using Ubuntu, please visit the "[Build Unsupported OS](./docs/00_install/01_build-from-source/00_build-unsupported-os.md)" page to explore your options.
|
||||
|
||||
Если вы используете неподдерживаемую производную Ubuntu, такую как Linux Mint, вы можете узнать версию Ubuntu, на которой она основана, используя эту команду:
|
||||
If you are running an unsupported Ubuntu derivative, such as Linux Mint, you can find the version of Ubuntu your distribution was based on by using this command:
|
||||
```bash
|
||||
cat /etc/upstream-release/lsb-release
|
||||
```
|
||||
Ваш лучший вариант - следовать инструкциям для вашей базовой версии Ubuntu, но мы не даём никаких гарантий.
|
||||
Your best bet is to follow the instructions for your Ubuntu base, but we make no guarantees.
|
||||
|
||||
## Бинарная установка
|
||||
Это самый быстрый способ начать работу. Со [страницы последнего релиза](https://github.com/AntelopeIO/leap/releases/latest) скачайте бинарный файл для одной из наших [поддерживаемых операционных систем](#supported-operating-systems), или посетите [теги релизов](https://github.com/AntelopeIO/leap/releases) для скачивания бинарного файла конкретной версии Coopos.
|
||||
## Binary Installation
|
||||
This is the fastest way to get started. From the [latest release](https://github.com/AntelopeIO/leap/releases/latest) page, download a binary for one of our [supported operating systems](#supported-operating-systems), or visit the [release tags](https://github.com/AntelopeIO/leap/releases) page to download a binary for a specific version of Leap.
|
||||
|
||||
После того, как вы скачали файл `*.deb` для вашей версии Ubuntu, вы можете установить его следующим образом:
|
||||
Once you have a `*.deb` file downloaded for your version of Ubuntu, you can install it as follows:
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ~/Downloads/coopos*.deb
|
||||
sudo apt-get install -y ~/Downloads/leap*.deb
|
||||
```
|
||||
Ваш путь загрузки может отличаться. Если вы находитесь в Ubuntu docker контейнере, опустите `sudo`, поскольку вы работаете как `root` по умолчанию.
|
||||
Your download path may vary. If you are in an Ubuntu docker container, omit `sudo` because you run as `root` by default.
|
||||
|
||||
Наконец, проверьте, что Coopos был установлен корректно:
|
||||
Finally, verify Leap was installed correctly:
|
||||
```bash
|
||||
nodeos --full-version
|
||||
```
|
||||
Вы должны увидеть строку [семантической версии](https://semver.org), за которой следует git commit hash без ошибок. Например:
|
||||
You should see a [semantic version](https://semver.org) string followed by a `git` commit hash with no errors. For example:
|
||||
```
|
||||
v5.1.0-abc123def456...
|
||||
v3.1.2-0b64f879e3ebe2e4df09d2e62f1fc164cc1125d1
|
||||
```
|
||||
|
||||
<a id="join-mainnet"></a>
|
||||
## Запуск ноды на основной сети Кооперативной Экономики
|
||||
## Build and Install from Source
|
||||
You can also build and install Leap from source.
|
||||
|
||||
Чтобы свежая нода смогла подключиться к основной сети, ей нужно вычислить тот же `chain_id`, что у работающих пиров. `chain_id` — детерминированный хеш от стартовых параметров (`initial_timestamp`, `initial_key`, `initial_configuration`); при расхождении хотя бы одного бита пир отвечает `go_away_message reason=wrong chain` и закрывает соединение.
|
||||
### Prerequisites
|
||||
You will need to build on a [supported operating system](#supported-operating-systems).
|
||||
|
||||
Дефолтное значение `EOSIO_ROOT_KEY` в этой сборке не равно тому, с которым была инициирована основная сеть, поэтому при запуске на пустой `data-dir` нужно явно подать `genesis.json` с правильным `initial_key`.
|
||||
|
||||
### Genesis основной сети
|
||||
|
||||
Сохраните содержимое ниже в файл `genesis.json` (например, в `~/blockchain/config/genesis.json`):
|
||||
|
||||
```json
|
||||
{
|
||||
"initial_timestamp": "2024-07-01T10:00:00.000",
|
||||
"initial_key": "EOS7TjqL5YfQ7tKzzKr3i1Pa1JkTVrcY2BJhMFfyMPajfAiPThjH7",
|
||||
"initial_configuration": {
|
||||
"max_block_net_usage": 1048576,
|
||||
"target_block_net_usage_pct": 1000,
|
||||
"max_transaction_net_usage": 1048575,
|
||||
"base_per_transaction_net_usage": 12,
|
||||
"net_usage_leeway": 500,
|
||||
"context_free_discount_net_usage_num": 20,
|
||||
"context_free_discount_net_usage_den": 100,
|
||||
"max_block_cpu_usage": 200000,
|
||||
"target_block_cpu_usage_pct": 500,
|
||||
"max_transaction_cpu_usage": 180000,
|
||||
"min_transaction_cpu_usage": 100,
|
||||
"max_transaction_lifetime": 3600,
|
||||
"deferred_trx_expiration_window": 600,
|
||||
"max_transaction_delay": 3888000,
|
||||
"max_inline_action_size": 4096,
|
||||
"max_inline_action_depth": 4,
|
||||
"max_authority_depth": 6
|
||||
},
|
||||
"initial_chain_id": "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
}
|
||||
```
|
||||
|
||||
Ожидаемый `chain_id` основной сети: `6e37f9ac0f0ea717bfdbf57d1dd5d7f0e2d773227d9659a63bbf86eec0326c1b`.
|
||||
|
||||
### Полный ресинк mainnet — встроенные исторические исключения
|
||||
|
||||
Начиная с **v5.3.1** реестр исторических исключений (`chain_historical_exceptions`) поставляется *внутри бинаря* для известных production-цепочек. Для основной сети Кооперативной Экономики (chain_id `6e37f9ac…26c1b`) встроены два окна вокруг инцидента 2026-05-11 (релиз `v5.2.0-dev-294edf3b8`):
|
||||
|
||||
- `action_mroot_zero_windows = [113273322 .. 113275717]` — bypass расхождения action_mroot в окне;
|
||||
- `onblock_skip_windows = [113273322 .. 113275717]` — пропуск implicit-транзакции `onblock`, чтобы state нашего реплея не разъехался с канонической цепью. Окно включает блок 113275717 — в нём `eosio::setcode` восстановил системный контракт, но onblock в момент производства этого блока ещё падал; пользовательские транзакции внутри окна выполняются штатно.
|
||||
|
||||
Дополнительно — в `apply_block` снято строгое требование `action_mroot == 0` в bypass'е: внутри окна допускается *любое* расхождение action_mroot при условии полного совпадения остальных полей заголовка.
|
||||
|
||||
Никакого внешнего JSON-файла для mainnet больше не требуется. Достаточно установить `.deb` и запустить полный ресинк — bypass применится автоматически по совпадению `chain_id`. Форки и тестнеты с другим chain_id видят пустой реестр и работают идентично апстрим-Antelope.
|
||||
|
||||
Для разовой переопределения (например, расследование на одной ноде) ещё работает старая опция `chain-historical-exceptions = /path/to/file.json` — она полностью заменяет встроенную запись на этой ноде. JSON формата v5.3.0 (только `action_mroot_zero_windows`) грузится в v5.3.1 без правок.
|
||||
|
||||
### Первый запуск с genesis (полный ресинк с блока 1)
|
||||
|
||||
Начиная с **v5.3.3** канонические генезисы известных сетей вшиты в бинарь — внешний genesis.json хранить не нужно, он воспроизводится из пакета одной командой:
|
||||
|
||||
```bash
|
||||
leap-util genesis list # имена и chain_id вшитых генезисов
|
||||
leap-util genesis print mainnet > genesis.json # канонический genesis основной сети
|
||||
leap-util genesis print testnet > genesis.json # ... или тестнета
|
||||
```
|
||||
|
||||
`chain_id` печатается в stderr — сверьте его с `get_info` любого пира перед синком. Дев-форки не затронуты: дефолтный genesis (без аргументов nodeos) по-прежнему использует апстримовый `EOSIO_ROOT_KEY`.
|
||||
|
||||
`--genesis-json` принимается nodeos **только если `data-dir` пуст** (отсутствуют каталоги `state`, `blocks`, `state-history`, `snapshots`). Поэтому при первом запуске или при намеренном пересинке:
|
||||
|
||||
```bash
|
||||
sudo systemctl stop nodeos
|
||||
|
||||
# Полная очистка состояния (история и trace будут переслушаны с пира)
|
||||
sudo rm -rf ~/blockchain/data/blocks \
|
||||
~/blockchain/data/state \
|
||||
~/blockchain/data/state-history \
|
||||
~/blockchain/data/snapshots
|
||||
|
||||
# Подложить genesis (один раз, путь произвольный — главное чтобы совпадал с флагом ниже)
|
||||
sudo install -m 644 genesis.json ~/blockchain/config/genesis.json
|
||||
|
||||
# Подсунуть флаг --genesis-json в systemd unit на один запуск
|
||||
sudo sed -i 's|^\(ExecStart=/usr/local/bin/nodeos.*\)$|\1 --genesis-json /root/blockchain/config/genesis.json|' \
|
||||
/etc/systemd/system/nodeos.service
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl start nodeos
|
||||
|
||||
# Удостовериться, что нода ловит блоки от пира — не должно быть "wrong chain"/"go_away"
|
||||
sudo journalctl -u nodeos -f --since '30 seconds ago'
|
||||
|
||||
# Когда увидели "Received block ...", снять флаг из unit, чтобы он не мешал последующим рестартам
|
||||
sudo sed -i 's| --genesis-json /root/blockchain/config/genesis.json||' /etc/systemd/system/nodeos.service
|
||||
sudo systemctl daemon-reload
|
||||
```
|
||||
|
||||
При повторных рестартах флаг `--genesis-json` не нужен: nodeos продолжит работу из существующего `state`, дефолтное значение `EOSIO_ROOT_KEY` из бинарника при этом не используется.
|
||||
|
||||
### Быстрый старт со снапшота вместо полного ресинка
|
||||
|
||||
Полный ресинк восстанавливает всю историю блоков с блока 1 и занимает часы. Если история до текущего состояния не нужна, можно стартовать со снапшота — нода поднимется за минуты, а историю с момента снапшота и далее догонит по p2p:
|
||||
|
||||
```bash
|
||||
sudo systemctl stop nodeos
|
||||
|
||||
# Получить снапшот от любой ноды, на которой включён producer_api_plugin:
|
||||
# curl -X POST http://<peer>:8888/v1/producer/create_snapshot
|
||||
# Файл будет в /<data-dir>/snapshots/snapshot-<head_block_id>.bin — забрать
|
||||
# его и положить как /root/blockchain/snapshot.bin на целевой ноде.
|
||||
|
||||
sudo rm -rf ~/blockchain/data/blocks \
|
||||
~/blockchain/data/state \
|
||||
~/blockchain/data/state-history \
|
||||
~/blockchain/data/snapshots
|
||||
|
||||
sudo sed -i 's|^\(ExecStart=/usr/local/bin/nodeos.*\)$|\1 --snapshot /root/blockchain/snapshot.bin|' \
|
||||
/etc/systemd/system/nodeos.service
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl start nodeos
|
||||
sudo journalctl -u nodeos -f --since '30 seconds ago'
|
||||
|
||||
# После старта снять флаг
|
||||
sudo sed -i 's| --snapshot /root/blockchain/snapshot.bin||' /etc/systemd/system/nodeos.service
|
||||
sudo systemctl daemon-reload
|
||||
```
|
||||
|
||||
Снапшот несёт в себе `chain_id`, поэтому `--genesis-json` в этом сценарии не нужен.
|
||||
|
||||
## Сборка и установка из исходного кода
|
||||
Вы также можете собрать и установить Coopos из исходного кода.
|
||||
|
||||
### Системные требования
|
||||
|
||||
#### Требования к сборке
|
||||
Для успешной сборки Coopos из исходного кода рекомендуется использовать систему с:
|
||||
- **Процессор**: минимум 4 ядра (рекомендуется 8 ядер)
|
||||
- **Оперативная память**: минимум 8 GB RAM (рекомендуется 16 GB)
|
||||
- **Дисковое пространство**: минимум 20 GB для сборки и тестов
|
||||
|
||||
При меньших ресурсах сборка может быть невозможна или крайне медленной. Некоторые этапы компиляции требуют значительных ресурсов памяти.
|
||||
|
||||
#### Требования к работе
|
||||
Для работы блокчейн-узла Coopos достаточно:
|
||||
- **Процессор**: минимум 2 ядра
|
||||
- **Оперативная память**: минимум 4 GB RAM
|
||||
- **Дисковое пространство**: зависит от высоты цепочки блоков. На текущий момент для основной сети кооперативной экономики требуется около 20 GB, поэтому минимально рекомендуется 40 GB, оптимально - 160 GB для комфортной работы и хранения истории.
|
||||
|
||||
### Предварительные требования
|
||||
Вам нужно собирать на [поддерживаемой операционной системе](#supported-operating-systems).
|
||||
|
||||
Требования для сборки:
|
||||
- Компилятор C++20 и стандартная библиотека
|
||||
- CMake 3.16+
|
||||
- LLVM 7 - 11 - только для Linux
|
||||
- более новые версии не работают
|
||||
- libcurl 7.40.0+
|
||||
Requirements to build:
|
||||
- C++17 compiler and standard library
|
||||
- boost 1.67+
|
||||
- CMake 3.8+
|
||||
- LLVM 7 - 11 - for Linux only
|
||||
- newer versions do not work
|
||||
- openssl 1.1+
|
||||
- libcurl
|
||||
- curl
|
||||
- libusb
|
||||
- git
|
||||
- GMP
|
||||
- Python 3
|
||||
- python3-numpy
|
||||
- zlib
|
||||
|
||||
### Шаг 1 - Клонирование
|
||||
Если у вас ещё не клонирован репозиторий Coopos, [откройте терминал](https://itsfoss.com/open-terminal-ubuntu) и перейдите в папку, где хотите клонировать репозиторий Coopos:
|
||||
### Step 1 - Clone
|
||||
If you don't have the Leap repo cloned to your computer yet, [open a terminal](https://itsfoss.com/open-terminal-ubuntu) and navigate to the folder where you want to clone the Leap repository:
|
||||
```bash
|
||||
cd ~/Downloads
|
||||
```
|
||||
Клонируйте Coopos используя либо HTTPS...
|
||||
Clone Leap using either HTTPS...
|
||||
```bash
|
||||
git clone --recursive https://github.com/AntelopeIO/leap.git
|
||||
```
|
||||
...либо SSH:
|
||||
...or SSH:
|
||||
```bash
|
||||
git clone --recursive git@github.com:AntelopeIO/leap.git
|
||||
```
|
||||
|
||||
> ℹ️ **HTTPS vs. SSH Clone** ℹ️
|
||||
И HTTPS, и SSH клонирование дадут одинаковый результат - папку с именем `leap`, содержащую наш исходный код. Не важно, какой тип вы используете.
|
||||
Both an HTTPS or SSH git clone will yield the same result - a folder named `leap` containing our source code. It doesn't matter which type you use.
|
||||
|
||||
Перейдите в эту папку:
|
||||
Navigate into that folder:
|
||||
```bash
|
||||
cd leap
|
||||
```
|
||||
|
||||
### Шаг 2 - Переключение на тег релиза или ветку
|
||||
Выберите, какой [релиз](https://github.com/AntelopeIO/leap/releases) или [ветку](#branches) вы хотите собрать, затем переключитесь на неё. Если вы не уверены, используйте [последний релиз](https://github.com/AntelopeIO/leap/releases/latest). Например, если вы хотите собрать релиз 5.1.0, то переключитесь на его тег `v5.1.0`. В примере ниже замените `v0.0.0` на выбранный вами тег релиза:
|
||||
### Step 2 - Checkout Release Tag or Branch
|
||||
Choose which [release](https://github.com/AntelopeIO/leap/releases) or [branch](#branches) you would like to build, then check it out. If you are not sure, use the [latest release](https://github.com/AntelopeIO/leap/releases/latest). For example, if you want to build release 3.1.2 then you would check it out using its tag, `v3.1.2`. In the example below, replace `v0.0.0` with your selected release tag accordingly:
|
||||
```bash
|
||||
git fetch --all --tags
|
||||
git checkout v5.1.0
|
||||
git checkout v0.0.0
|
||||
```
|
||||
|
||||
После того, как вы находитесь на ветке или теге релиза, который хотите собрать, убедитесь, что всё обновлено:
|
||||
Once you are on the branch or release tag you want to build, make sure everything is up-to-date:
|
||||
```bash
|
||||
git pull
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
### Шаг 3 - Сборка
|
||||
Выберите инструкции по сборке ниже для [закреплённой сборки](#pinned-build) (предпочтительно) или [незакреплённой сборки](#unpinned-build).
|
||||
### Step 3 - Build
|
||||
Select build instructions below for a [pinned build](#pinned-build) (preferred) or an [unpinned build](#unpinned-build).
|
||||
|
||||
> ℹ️ **Закреплённая vs. Незакреплённая сборка** ℹ️
|
||||
У нас есть два типа сборок для Coopos: "закреплённая" и "незакреплённая". Закреплённая сборка - это воспроизводимая сборка с фиксированной средой сборки и версиями зависимостей, установленными командой разработчиков. В отличие от этого, незакреплённые сборки используют версии зависимостей, предоставляемые платформой сборки. Незакреплённые сборки обычно быстрее, потому что закреплённая среда сборки должна быть построена с нуля. Закреплённые сборки, помимо воспроизводимости, обеспечивают, чтобы компилятор оставался тем же между сборками разных основных версий Coopos. Coopos требует, чтобы версия компилятора оставалась той же, иначе его состояние может потребовать восстановления из портативного снимка или цепочка должна быть перезапущена.
|
||||
> ℹ️ **Pinned vs. Unpinned Build** ℹ️
|
||||
We have two types of builds for Leap: "pinned" and "unpinned." The only difference is that pinned builds use specific versions for some dependencies hand-picked by the Leap engineers - they are "pinned" to those versions. In contrast, unpinned builds use the default dependency versions available on the build system at the time. We recommend performing a "pinned" build to ensure the compiler and boost versions remain the same between builds of different Leap versions. Leap requires these versions to remain the same, otherwise its state might need to be recovered from a portable snapshot or the chain needs to be replayed.
|
||||
|
||||
> ⚠️ **Предупреждение о параллельных задачах компиляции (флаг `-j`)** ⚠️
|
||||
При сборке программного обеспечения C/C++, часто сборка выполняется параллельно с помощью команды типа `make -j "$(nproc)"`, которая использует все доступные потоки CPU. Однако учтите, что некоторые единицы компиляции (`*.cpp` файлы) в Coopos будут потреблять почти 4GB памяти. Сбои из-за исчерпания памяти обычно, но не всегда, проявляются как сбои компилятора. Использование всех доступных потоков CPU также может помешать вам делать другие вещи на вашем компьютере во время компиляции. По этим причинам рассмотрите возможность уменьшения этого значения.
|
||||
> ⚠️ **A Warning On Parallel Compilation Jobs (`-j` flag)** ⚠️
|
||||
When building C/C++ software, often the build is performed in parallel via a command such as `make -j "$(nproc)"` which uses all available CPU threads. However, be aware that some compilation units (`*.cpp` files) in Leap will consume nearly 4GB of memory. Failures due to memory exhaustion will typically, but not always, manifest as compiler crashes. Using all available CPU threads may also prevent you from doing other things on your computer during compilation. For these reasons, consider reducing this value.
|
||||
|
||||
> 🐋 **Docker и `sudo`** 🐋
|
||||
Если вы находитесь в Ubuntu docker контейнере, опустите `sudo` из всех команд, поскольку вы работаете как `root` по умолчанию. Большинство других docker контейнеров также исключают `sudo`, особенно Debian-семейные контейнеры. Если ваш промпт оболочки - хэш-тег (`#`), опустите `sudo`.
|
||||
> 🐋 **Docker and `sudo`** 🐋
|
||||
If you are in an Ubuntu docker container, omit `sudo` from all commands because you run as `root` by default. Most other docker containers also exclude `sudo`, especially Debian-family containers. If your shell prompt is a hash tag (`#`), omit `sudo`.
|
||||
|
||||
#### Закреплённая воспроизводимая сборка
|
||||
Закреплённая воспроизводимая сборка требует Docker. Убедитесь, что вы находитесь в корне репозитория `leap`, затем выполните
|
||||
#### Pinned Build
|
||||
Make sure you are in the root of the `leap` repo, then run the `install_depts.sh` script to install dependencies:
|
||||
```bash
|
||||
DOCKER_BUILDKIT=1 docker build -f tools/reproducible.Dockerfile -o . .
|
||||
```
|
||||
Эта команда займёт существенное время, потому что цепочка инструментов собирается с нуля. После завершения текущая директория будет содержать собранные `.deb` и `.tar.gz` файлы (вы можете изменить аргумент `-o .` для размещения вывода в другой директории). Если нужно уменьшить количество параллельных задач, как предупреждалось выше, выполните команду как:
|
||||
```bash
|
||||
DOCKER_BUILDKIT=1 docker build --build-arg LEAP_BUILD_JOBS=4 -f tools/reproducible.Dockerfile -o . .
|
||||
sudo scripts/install_deps.sh
|
||||
```
|
||||
|
||||
#### Незакреплённая сборка
|
||||
Следующие инструкции действительны для этой ветки. Другие ветки релизов могут иметь разные требования, поэтому убедитесь, что следуете указаниям в ветке или релизе, который собираетесь собирать. Если вы находитесь в Ubuntu docker контейнере, опустите `sudo`, поскольку вы работаете как `root` по умолчанию.
|
||||
Next, run the pinned build script. You have to give it three arguments, in the following order:
|
||||
- A temporary folder, for all dependencies that need to be built from source.
|
||||
- A build folder, where the binaries you need to install will be built to.
|
||||
- The number of jobs or CPU cores/threads to use (note the [jobs flag](#step-3---build) warning above).
|
||||
|
||||
Установите зависимости:
|
||||
The following command runs the `pinned_build.sh` script, specifies a `deps` and `build` folder in the root of the Leap repo for the first two arguments, then builds the packages using all of your computer's CPU threads (Note: you don't need `sudo` for this command):
|
||||
```bash
|
||||
scripts/pinned_build.sh deps build "$(nproc)"
|
||||
```
|
||||
Now you can optionally [test](#step-4---test) your build, or [install](#step-5---install) the `*.deb` binary packages, which will be in the root of your build directory.
|
||||
|
||||
#### Unpinned Build
|
||||
The following instructions are valid for this branch. Other release branches may have different requirements, so ensure you follow the directions in the branch or release you intend to build. If you are in an Ubuntu docker container, omit `sudo` because you run as `root` by default.
|
||||
|
||||
<details> <summary>Ubuntu 22.04 Jammy & Ubuntu 20.04 Focal</summary>
|
||||
|
||||
Install dependencies:
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
build-essential \
|
||||
cmake \
|
||||
curl \
|
||||
git \
|
||||
libboost-all-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libgmp-dev \
|
||||
libssl-dev \
|
||||
libusb-1.0-0-dev \
|
||||
llvm-11-dev \
|
||||
python3-numpy \
|
||||
file \
|
||||
zlib1g-dev
|
||||
pkg-config
|
||||
```
|
||||
|
||||
На Ubuntu 20.04 установите gcc-10, который имеет поддержку C++20:
|
||||
```bash
|
||||
sudo apt-get install -y g++-10
|
||||
```
|
||||
|
||||
Для сборки убедитесь, что вы находитесь в корне репозитория `leap`, затем выполните следующую команду:
|
||||
To build, make sure you are in the root of the `leap` repo, then run the following command:
|
||||
```bash
|
||||
mkdir -p build
|
||||
cd build
|
||||
|
||||
## на Ubuntu 20 укажите компилятор gcc-10
|
||||
cmake -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=/usr/lib/llvm-11 ..
|
||||
|
||||
## на Ubuntu 22 версия gcc по умолчанию 11, использование компилятора по умолчанию нормально
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=/usr/lib/llvm-11 ..
|
||||
make -j $(nproc) package
|
||||
```
|
||||
</details>
|
||||
|
||||
<details> <summary>Ubuntu 18.04 Bionic</summary>
|
||||
|
||||
Install dependencies:
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
build-essential \
|
||||
cmake \
|
||||
curl \
|
||||
g++-8 \
|
||||
git \
|
||||
libcurl4-openssl-dev \
|
||||
libgmp-dev \
|
||||
libssl-dev \
|
||||
libusb-1.0-0-dev \
|
||||
llvm-7-dev \
|
||||
pkg-config \
|
||||
python3 \
|
||||
zlib1g-dev
|
||||
```
|
||||
You need to build Boost from source on this distribution:
|
||||
```bash
|
||||
curl -fL https://boostorg.jfrog.io/artifactory/main/release/1.79.0/source/boost_1_79_0.tar.bz2 -o ~/Downloads/boost_1_79_0.tar.bz2
|
||||
tar -jvxf ~/Downloads/boost_1_79_0.tar.bz2 -C ~/Downloads/
|
||||
pushd ~/Downloads/boost_1_79_0
|
||||
./bootstrap.sh --prefix="$HOME/boost1.79"
|
||||
./b2 --with-iostreams --with-date_time --with-filesystem --with-system --with-program_options --with-chrono --with-test -j "$(nproc)" install
|
||||
popd
|
||||
```
|
||||
The Boost `*.tar.bz2` download and `boost_1_79_0` folder can be removed now if you want more space.
|
||||
```bash
|
||||
rm -r ~/Downloads/boost_1_79_0.tar.bz2 ~/Downloads/boost_1_79_0
|
||||
```
|
||||
From a terminal in the root of the `leap` repo, build.
|
||||
```bash
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -DCMAKE_C_COMPILER=gcc-8 -DCMAKE_CXX_COMPILER=g++-8 -DCMAKE_PREFIX_PATH="$HOME/boost1.79;/usr/lib/llvm-7/" -DCMAKE_BUILD_TYPE=Release ..
|
||||
make -j "$(nproc)" package
|
||||
```
|
||||
After building, you may remove the `~/boost1.79` directory or you may keep it around for your next build.
|
||||
</details>
|
||||
|
||||
Теперь вы можете опционально [протестировать](#step-4---test) вашу сборку, или [установить](#step-5---install) бинарные пакеты `*.deb`, которые будут в корне вашей директории сборки.
|
||||
Now you can optionally [test](#step-4---test) your build, or [install](#step-5---install) the `*.deb` binary packages, which will be in the root of your build directory.
|
||||
|
||||
### Шаг 4 - Тестирование
|
||||
Coopos поддерживает следующие наборы тестов:
|
||||
### Step 4 - Test
|
||||
Leap supports the following test suites:
|
||||
|
||||
Набор тестов | Тип теста | [Размер теста](https://testing.googleblog.com/2010/12/test-sizes.html) | Примечания
|
||||
Test Suite | Test Type | [Test Size](https://testing.googleblog.com/2010/12/test-sizes.html) | Notes
|
||||
---|:---:|:---:|---
|
||||
[Параллелизуемые тесты](#parallelizable-tests) | Модульные тесты | Маленький
|
||||
[WASM spec тесты](#wasm-spec-tests) | Модульные тесты | Маленький | Модульные тесты для нашего WASM runtime, каждый короткий но _очень_ CPU-интенсивный
|
||||
[Сериальные тесты](#serial-tests) | Компонент/Интеграция | Средний
|
||||
[Долго выполняемые тесты](#long-running-tests) | Интеграция | Средний-Крупный | Тесты, которые занимают чрезвычайно много времени на выполнение
|
||||
[Parallelizable tests](#parallelizable-tests) | Unit tests | Small
|
||||
[WASM spec tests](#wasm-spec-tests) | Unit tests | Small | Unit tests for our WASM runtime, each short but _very_ CPU-intensive
|
||||
[Serial tests](#serial-tests) | Component/Integration | Medium
|
||||
[Long-running tests](#long-running-tests) | Integration | Medium-to-Large | Tests which take an extraordinarily long amount of time to run
|
||||
|
||||
При сборке из исходного кода мы рекомендуем запускать как минимум [параллелизуемые тесты](#parallelizable-tests).
|
||||
When building from source, we recommended running at least the [parallelizable tests](#parallelizable-tests).
|
||||
|
||||
#### Параллелизуемые тесты
|
||||
Этот набор тестов состоит из любых тестов, которые не требуют разделяемых ресурсов, таких как файловые дескрипторы, специфические папки или порты, и поэтому могут выполняться параллельно в разных потоках без побочных эффектов (следовательно, легко параллелизуемы). Это в основном модульные тесты и [маленькие тесты](https://testing.googleblog.com/2010/12/test-sizes.html), которые завершаются за короткое время.
|
||||
#### Parallelizable Tests
|
||||
This test suite consists of any test that does not require shared resources, such as file descriptors, specific folders, or ports, and can therefore be run concurrently in different threads without side effects (hence, easily parallelized). These are mostly unit tests and [small tests](https://testing.googleblog.com/2010/12/test-sizes.html) which complete in a short amount of time.
|
||||
|
||||
Вы можете запустить их, выполнив `ctest` из терминала в вашей директории сборки Coopos и указав следующие аргументы:
|
||||
You can invoke them by running `ctest` from a terminal in your Leap build directory and specifying the following arguments:
|
||||
```bash
|
||||
ctest -j "$(nproc)" -LE _tests
|
||||
```
|
||||
|
||||
#### WASM Spec тесты
|
||||
WASM spec тесты проверяют, что наш движок выполнения WASM соответствует стандарту web assembly. Это очень [маленькие](https://testing.googleblog.com/2010/12/test-sizes.html), очень быстрые модульные тесты. Однако их более тысячи, так что набор может занять немного времени на выполнение. Эти тесты чрезвычайно CPU-интенсивны.
|
||||
#### WASM Spec Tests
|
||||
The WASM spec tests verify that our WASM execution engine is compliant with the web assembly standard. These are very [small](https://testing.googleblog.com/2010/12/test-sizes.html), very fast unit tests. However, there are over a thousand of them so the suite can take a little time to run. These tests are extremely CPU-intensive.
|
||||
|
||||
Вы можете запустить их, выполнив `ctest` из терминала в вашей директории сборки Coopos и указав следующие аргументы:
|
||||
You can invoke them by running `ctest` from a terminal in your Leap build directory and specifying the following arguments:
|
||||
```bash
|
||||
ctest -j "$(nproc)" -L wasm_spec_tests
|
||||
```
|
||||
Мы наблюдали серьёзные проблемы с производительностью, когда несколько виртуальных машин запускают этот набор тестов на одном физическом хосте одновременно, например в системе CICD. Это можно решить, отключив hyperthreading на хосте.
|
||||
We have observed severe performance issues when multiple virtual machines are running this test suite on the same physical host at the same time, for example in a CICD system. This can be resolved by disabling hyperthreading on the host.
|
||||
|
||||
#### Сериальные тесты
|
||||
Набор сериальных тестов состоит из [средних](https://testing.googleblog.com/2010/12/test-sizes.html) компонентных или интеграционных тестов, которые используют специфические пути, порты, полагаются на имена процессов или подобное, и не могут выполняться параллельно с другими тестами. Сериальные тесты могут быть чувствительны к другому программному обеспечению, работающему на том же хосте, и они могут отправлять `SIGKILL` другим процессам `nodeos`. Эти тесты занимают умеренное время на завершение, но мы рекомендуем их запускать.
|
||||
#### Serial Tests
|
||||
The serial test suite consists of [medium](https://testing.googleblog.com/2010/12/test-sizes.html) component or integration tests that use specific paths, ports, rely on process names, or similar, and cannot be run concurrently with other tests. Serial tests can be sensitive to other software running on the same host and they may `SIGKILL` other `nodeos` processes. These tests take a moderate amount of time to complete, but we recommend running them.
|
||||
|
||||
Вы можете запустить их, выполнив `ctest` из терминала в вашей директории сборки Coopos и указав следующие аргументы:
|
||||
You can invoke them by running `ctest` from a terminal in your Leap build directory and specifying the following arguments:
|
||||
```bash
|
||||
ctest -L "nonparallelizable_tests"
|
||||
```
|
||||
|
||||
#### Долго выполняемые тесты
|
||||
Долго выполняемые тесты - это [средние-крупные](https://testing.googleblog.com/2010/12/test-sizes.html) интеграционные тесты, которые полагаются на разделяемые ресурсы и занимают очень много времени на выполнение.
|
||||
#### Long-Running Tests
|
||||
The long-running tests are [medium-to-large](https://testing.googleblog.com/2010/12/test-sizes.html) integration tests that rely on shared resources and take a very long time to run.
|
||||
|
||||
Вы можете запустить их, выполнив `ctest` из терминала в вашей директории сборки Coopos и указав следующие аргументы:
|
||||
You can invoke them by running `ctest` from a terminal in your Leap build directory and specifying the following arguments:
|
||||
```bash
|
||||
ctest -L "long_running_tests"
|
||||
```
|
||||
|
||||
### Шаг 5 - Установка
|
||||
После того, как вы [собрали](#step-3---build-the-source-code) Coopos и [протестировали](#step-4---test) вашу сборку, вы можете установить Coopos в вашу систему. Не забудьте опустить `sudo`, если вы работаете в docker контейнере.
|
||||
### Step 5 - Install
|
||||
Once you have [built](#step-3---build-the-source-code) Leap and [tested](#step-4---test) your build, you can install Leap on your system. Don't forget to omit `sudo` if you are running in a docker container.
|
||||
|
||||
Мы рекомендуем установить бинарный пакет, который вы только что собрали. Перейдите в вашу директорию сборки Coopos в терминале и выполните эту команду:
|
||||
We recommend installing the binary package you just built. Navigate to your Leap build directory in a terminal and run this command:
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ./leap[-_][0-9]*.deb
|
||||
```
|
||||
|
||||
Также возможно установить используя `make`:
|
||||
It is also possible to install using `make` instead:
|
||||
```bash
|
||||
sudo make install
|
||||
```
|
||||
|
||||
## Bash автодополнение
|
||||
`cleos` и `leap-util` предлагают существенный объём функциональности. Рассмотрите использование поддержки автодополнения bash, которая облегчает обнаружение всех их различных опций.
|
||||
|
||||
Для наших предоставленных `.deb` пакетов просто установите Ubuntu пакет `bash-completion`: `apt-get install bash-completion` (вам может понадобиться выйти и войти снова после установки).
|
||||
|
||||
Если собираете из исходного кода, установите файлы `build/programs/cleos/bash-completion/completions/cleos` и `build/programs/leap-util/bash-completion/completions/leap-util` в вашу директорию bash-completion. Обратитесь к [документации bash-completion](https://github.com/scop/bash-completion#faq) по возможным местам установки.
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
file(GLOB BENCHMARK "*.cpp")
|
||||
add_executable( benchmark ${BENCHMARK} )
|
||||
|
||||
target_link_libraries( benchmark eosio_testing fc Boost::program_options bn256)
|
||||
target_include_directories( benchmark PUBLIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/../unittests/include"
|
||||
)
|
||||
@@ -1,112 +0,0 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <bn256/bn256.h>
|
||||
|
||||
#include <benchmark.hpp>
|
||||
|
||||
namespace eosio::benchmark {
|
||||
|
||||
using bytes = std::vector<char>;
|
||||
using g1g2_pair = std::vector<std::string>;
|
||||
|
||||
void add_benchmarking() {
|
||||
const unsigned char point1[64] = {
|
||||
12,175,215,144,98,95,151,228,179,85,31,170,172,159,40,255,250,252,68,28,235,65,172,180,69,164,153,29,187,239,220,201, // x
|
||||
18,102,219,76,79,148,120,28,39,149,42,172,41,248,120,249,255,69,42,51,160,239,13,219,239,183,77,174,217,158,130,10,}; // y
|
||||
const unsigned char point2[64] = {
|
||||
12,144,10,32,104,85,103,36,222,232,48,152,108,217,40,145,230,48,8,54,0,7,134,164,7,10,139,110,95,205,124,121, // x
|
||||
22,254,176,251,18,168,78,220,142,100,102,113,58,176,83,186,212,62,154,138,235,135,34,46,237,117,54,36,198,40,79,73,}; // y
|
||||
|
||||
unsigned char ans[64] ={};
|
||||
|
||||
|
||||
auto f = [&]() {
|
||||
auto res = bn256::g1_add(point1, point2, ans);
|
||||
if (res == -1) {
|
||||
std::cout << "alt_bn128_add failed" << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
benchmarking("alt_bn128_add", f);
|
||||
}
|
||||
|
||||
void mul_benchmarking() {
|
||||
const unsigned char point[64] = {
|
||||
12,175,215,144,98,95,151,228,179,85,31,170,172,159,40,255,250,252,68,28,235,65,172,180,69,164,153,29,187,239,220,201, // x
|
||||
18,102,219,76,79,148,120,28,39,149,42,172,41,248,120,249,255,69,42,51,160,239,13,219,239,183,77,174,217,158,130,10,}; // y
|
||||
const unsigned char scalar[32] = {
|
||||
25,62,182,170,104,140,135,90,37,150,0,77,2,77,146,71,54,101,113,69,177,216,157,4,229,213,33,215,169,99,150,91, }; // scaler size 256 bits
|
||||
|
||||
unsigned char ans[64] = {};
|
||||
|
||||
auto f = [&]() {
|
||||
auto res = bn256::g1_scalar_mul(point, scalar, ans);
|
||||
if (res == -1) {
|
||||
std::cout << "alt_bn128_mul failed" << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
benchmarking("alt_bn128_mul", f);
|
||||
}
|
||||
|
||||
void pair_benchmarking() {
|
||||
const unsigned char g1_g2_pairs[] = {
|
||||
/* pair 1 */
|
||||
12,175,215,144,98,95,151,228,179,85,31,170,172,159,40,255,250,252,68,28,235,65,172,180,69,164,153,29,187,239,220,201,18,102,219,76,79,148,120,28,39,149,42,172,41,248,120,249,255,69,42,51,160,239,13,219,239,183,77,174,217,158,130,10,
|
||||
46,24,234,176,148,82,198,136,44,30,157,18,217,25,49,241,63,197,2,151,14,150,136,210,114,4,74,124,145,225,131,139,13,60,0,50,236,103,39,15,150,226,246,189,209,113,0,46,151,39,41,6,87,119,228,213,45,225,29,234,161,110,43,87,3,237,74,227,93,23,171,129,49,118,228,173,154,111,168,220,161,46,140,103,155,56,168,207,254,90,228,76,188,232,25,34,44,102,159,35,193,216,177,31,131,247,226,19,170,222,26,227,86,37,81,149,202,144,188,126,120,168,9,195,32,169,147,161,
|
||||
/* pair,2,*/
|
||||
12,144,10,32,104,85,103,36,222,232,48,152,108,217,40,145,230,48,8,54,0,7,134,164,7,10,139,110,95,205,124,121,22,254,176,251,18,168,78,220,142,100,102,113,58,176,83,186,212,62,154,138,235,135,34,46,237,117,54,36,198,40,79,73,
|
||||
0,186,148,242,227,252,208,242,165,128,1,160,59,2,6,195,30,54,69,118,8,28,223,92,254,98,110,219,90,92,7,113,26,8,119,98,122,61,119,91,216,107,29,179,122,218,203,6,84,109,119,140,44,12,57,157,203,90,14,108,218,54,94,44,42,77,118,169,232,192,189,60,129,213,156,157,215,160,91,214,138,130,119,145,167,89,237,149,225,85,151,33,89,181,224,235,2,91,213,225,37,226,214,14,255,84,254,117,142,211,28,164,78,254,64,11,126,217,25,124,203,220,52,181,39,32,78,132,
|
||||
/* pair 3 */
|
||||
48,58,116,183,56,3,62,111,104,127,0,7,202,204,146,2,236,192,214,213,231,100,12,17,104,47,76,49,149,39,35,179,2,162,218,104,52,130,61,134,223,111,123,225,186,122,171,2,144,236,110,29,26,142,113,183,238,44,130,30,76,212,52,15,
|
||||
19,206,16,79,220,158,153,194,12,48,10,79,173,10,97,199,113,25,255,87,220,3,102,235,164,170,50,240,177,237,223,205,11,75,211,28,143,229,192,35,171,167,172,238,138,235,82,134,111,165,144,29,118,150,179,21,158,9,202,2,242,109,33,148,14,188,33,145,213,186,0,126,178,10,131,168,121,66,121,193,106,209,176,34,176,41,145,227,3,55,245,150,82,218,232,155,31,153,213,183,157,2,159,247,25,69,49,215,219,36,46,5,192,205,201,182,72,189,84,62,61,47,136,81,51,65,231,161,
|
||||
/* pair 4 */
|
||||
27,31,150,92,17,82,135,210,46,161,0,24,16,199,200,165,29,165,157,168,222,9,83,17,44,27,64,226,208,112,223,128,20,253,182,130,45,130,249,9,168,206,153,86,197,214,59,248,241,191,93,113,70,113,247,244,43,214,240,246,24,38,33,50,
|
||||
23,76,241,195,191,99,69,237,123,173,212,42,74,85,138,108,39,80,105,135,226,11,84,237,39,73,180,224,42,230,246,76,26,61,86,57,253,213,223,2,93,42,38,186,38,38,206,38,209,138,153,181,57,89,16,187,234,2,110,23,12,14,252,240,32,231,237,147,16,62,220,6,160,64,154,167,57,238,243,112,255,35,80,36,100,173,21,58,96,244,77,245,75,202,24,63,35,178,46,215,219,69,120,221,70,119,111,195,145,45,109,84,206,76,254,205,98,167,30,72,117,5,128,129,156,128,196,192,
|
||||
/* pair 5 */
|
||||
33,230,106,254,43,77,114,126,9,205,25,63,9,170,62,237,149,102,198,184,60,31,185,213,103,120,71,249,28,106,238,107,1,133,60,180,58,152,18,177,142,248,46,186,90,34,94,200,235,158,242,255,209,32,143,133,102,195,19,107,153,42,207,228,
|
||||
30,43,165,137,133,231,242,156,65,126,94,159,26,27,78,164,165,159,225,150,220,158,247,118,118,170,195,122,12,125,8,34,39,57,159,231,167,233,3,47,243,142,174,224,162,38,147,65,74,191,98,144,126,125,81,177,75,140,161,27,34,97,46,249,8,65,220,15,139,144,78,12,72,239,54,163,39,6,30,147,154,208,89,111,170,126,6,214,32,181,195,140,215,53,218,239,44,43,229,0,169,242,16,227,163,185,224,21,142,203,135,66,60,53,91,80,48,112,8,13,226,206,58,249,163,52,196,53,
|
||||
/* pair 6 */
|
||||
14,157,100,136,255,206,130,101,56,187,235,39,67,209,67,124,40,174,153,135,155,26,166,170,118,193,244,21,70,71,120,150,3,189,254,120,183,98,23,175,175,28,195,233,165,224,35,95,247,132,40,64,26,208,70,206,247,92,134,105,118,181,21,242,
|
||||
16,159,200,208,93,99,234,139,8,222,239,67,3,187,15,125,5,144,190,196,146,171,15,218,92,36,37,130,2,201,241,182,36,31,104,164,95,29,73,231,87,50,174,142,209,72,31,75,48,13,70,237,118,193,39,85,97,88,228,50,77,163,209,112,7,202,214,212,235,15,224,247,229,179,101,15,72,130,125,8,62,227,46,20,109,53,26,168,10,237,222,85,169,133,181,196,25,36,112,182,41,208,39,132,100,181,199,189,44,99,238,140,6,187,19,197,99,93,243,63,159,132,211,0,230,118,153,54,
|
||||
/* pair 7 */
|
||||
31,60,154,8,188,169,224,107,69,183,223,15,60,32,61,51,81,226,85,38,72,88,241,202,216,204,253,98,0,250,116,167,21,255,0,81,80,3,108,196,240,102,114,33,33,122,116,155,188,19,232,217,42,217,54,195,91,187,88,188,249,218,240,146,
|
||||
12,28,171,60,8,166,151,19,125,237,128,127,207,183,19,1,188,189,105,181,170,172,8,180,30,175,4,108,191,252,197,161,37,122,14,151,117,34,172,227,236,154,84,99,189,197,91,46,43,148,174,218,83,61,196,48,131,45,242,61,92,242,56,251,39,125,111,11,24,37,76,62,151,59,183,3,156,187,249,232,229,56,230,171,55,2,246,70,74,102,0,156,185,237,126,90,0,30,248,164,199,146,66,237,158,134,139,168,128,189,126,55,35,198,48,18,112,40,63,70,254,246,88,111,254,67,213,223,
|
||||
/* pair 8 */
|
||||
27,106,52,232,120,148,201,234,161,123,171,160,223,151,6,105,206,47,94,147,47,22,27,21,248,20,223,51,116,192,29,221,25,149,109,33,131,198,32,101,157,94,62,164,205,151,23,108,214,43,231,7,95,228,183,1,242,205,19,62,124,79,48,203,
|
||||
37,186,150,204,63,241,145,219,169,250,247,76,247,18,135,175,140,58,209,133,113,144,185,191,101,197,252,253,50,126,188,177,45,103,105,194,21,229,145,210,89,135,244,248,238,64,102,155,129,232,252,32,208,82,51,131,113,100,25,174,253,19,211,18,6,77,66,232,173,42,146,120,106,72,92,144,51,233,117,184,113,60,33,118,209,83,119,93,170,253,126,41,58,13,85,111,30,233,117,238,183,18,219,38,216,163,244,98,219,254,156,189,57,246,220,178,17,190,88,84,13,41,8,236,181,155,85,198,
|
||||
/* pair 9 */
|
||||
25,62,182,170,104,140,135,90,37,150,0,77,2,77,146,71,54,101,113,69,177,216,157,4,229,213,33,215,169,99,150,91,5,185,157,10,152,12,220,171,39,188,1,48,87,129,192,101,36,179,99,212,123,207,13,76,89,78,8,154,75,239,117,189,
|
||||
19,87,226,242,101,183,176,42,195,135,40,225,195,207,13,62,60,37,28,251,13,165,96,198,173,250,251,107,25,141,77,68,45,115,128,233,135,104,231,12,192,206,60,249,137,191,114,141,3,235,34,189,208,170,23,59,231,12,197,116,5,188,52,20,11,153,186,15,96,240,54,123,212,242,168,141,151,187,17,38,185,238,196,242,26,194,193,18,34,107,95,238,108,154,140,224,13,76,71,149,81,56,85,83,56,59,203,183,170,10,167,200,128,135,105,19,93,203,131,146,116,209,62,27,81,80,234,172,
|
||||
/* pair 10 */
|
||||
30,204,212,77,212,159,135,173,195,194,165,112,62,248,180,204,66,73,253,99,65,111,39,171,19,211,171,203,35,66,146,20,33,241,46,6,167,133,80,76,238,165,59,232,120,58,211,157,50,212,86,191,95,6,134,164,36,227,79,58,119,98,108,171,
|
||||
48,49,12,141,166,151,158,56,136,255,197,138,114,195,39,59,71,236,82,57,149,249,170,55,187,95,193,171,14,124,45,87,7,157,47,178,153,237,194,157,142,194,100,14,40,51,61,201,244,93,61,196,154,59,14,135,209,72,102,186,14,228,228,152,40,246,109,82,93,249,92,105,191,121,77,108,20,87,3,87,167,173,171,255,189,34,155,239,218,95,181,153,222,20,120,195,27,28,47,82,113,3,218,129,54,210,185,165,206,99,126,61,217,19,237,5,12,90,148,246,128,231,63,53,37,223,204,195
|
||||
};
|
||||
|
||||
// benchmarking 1 pair of points
|
||||
auto f_1_pair = [&]() {
|
||||
auto res = bn256::pairing_check({ g1_g2_pairs, 384}, [](){});
|
||||
if (res == -1) {
|
||||
std::cout << "alt_bn128_pair 1 pair failed" << std::endl;
|
||||
}
|
||||
};
|
||||
benchmarking("alt_bn128_pair (1 pair)", f_1_pair);
|
||||
|
||||
// benchmarking 10 pair of points
|
||||
auto f_10_pairs = [&]() {
|
||||
auto res = bn256::pairing_check(g1_g2_pairs, [](){});
|
||||
if (res == -1) {
|
||||
std::cout << "alt_bn128_pair 10 pair failed" << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
benchmarking("alt_bn128_pair (10 pairs)", f_10_pairs);
|
||||
}
|
||||
|
||||
void alt_bn_128_benchmarking() {
|
||||
add_benchmarking();
|
||||
mul_benchmarking();
|
||||
pair_benchmarking();
|
||||
}
|
||||
|
||||
} // benchmark
|
||||
@@ -1,85 +0,0 @@
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <locale>
|
||||
|
||||
#include <benchmark.hpp>
|
||||
|
||||
namespace eosio::benchmark {
|
||||
|
||||
// update this map when a new feature is supported
|
||||
// key is the name and value is the function doing benchmarking
|
||||
std::map<std::string, std::function<void()>> features {
|
||||
{ "alt_bn_128", alt_bn_128_benchmarking },
|
||||
{ "modexp", modexp_benchmarking },
|
||||
{ "key", key_benchmarking },
|
||||
{ "hash", hash_benchmarking },
|
||||
{ "blake2", blake2_benchmarking },
|
||||
{ "bls", bls_benchmarking }
|
||||
};
|
||||
|
||||
// values to control cout format
|
||||
constexpr auto name_width = 40;
|
||||
constexpr auto runs_width = 5;
|
||||
constexpr auto time_width = 12;
|
||||
constexpr auto ns_width = 2;
|
||||
|
||||
uint32_t num_runs = 1;
|
||||
|
||||
std::map<std::string, std::function<void()>> get_features() {
|
||||
return features;
|
||||
}
|
||||
|
||||
void set_num_runs(uint32_t runs) {
|
||||
num_runs = runs;
|
||||
}
|
||||
|
||||
void print_header() {
|
||||
std::cout << std::left << std::setw(name_width) << "function"
|
||||
<< std::setw(runs_width) << "runs"
|
||||
<< std::setw(time_width + ns_width) << std::right << "average"
|
||||
<< std::setw(time_width + ns_width) << "minimum"
|
||||
<< std::setw(time_width + ns_width) << "maximum"
|
||||
<< std::endl << std::endl;
|
||||
}
|
||||
|
||||
void print_results(std::string name, uint32_t runs, uint64_t total, uint64_t min, uint64_t max) {
|
||||
std::cout.imbue(std::locale(""));
|
||||
std::cout
|
||||
<< std::setw(name_width) << std::left << name
|
||||
// std::fixed for not printing 1234 in 1.234e3.
|
||||
// setprecision(0) for not printing fractions
|
||||
<< std::right << std::fixed << std::setprecision(0)
|
||||
<< std::setw(runs_width) << runs
|
||||
<< std::setw(time_width) << total/runs << std::setw(ns_width) << " ns"
|
||||
<< std::setw(time_width) << min << std::setw(ns_width) << " ns"
|
||||
<< std::setw(time_width) << max << std::setw(ns_width) << " ns"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
bytes to_bytes(const std::string& source) {
|
||||
bytes output(source.length()/2);
|
||||
fc::from_hex(source, output.data(), output.size());
|
||||
return output;
|
||||
};
|
||||
|
||||
void benchmarking(const std::string& name, const std::function<void()>& func) {
|
||||
uint64_t total{0};
|
||||
uint64_t min{std::numeric_limits<uint64_t>::max()};
|
||||
uint64_t max{0};
|
||||
|
||||
for (auto i = 0U; i < num_runs; ++i) {
|
||||
auto start_time = std::chrono::high_resolution_clock::now();
|
||||
func();
|
||||
auto end_time = std::chrono::high_resolution_clock::now();
|
||||
|
||||
uint64_t duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count();
|
||||
total += duration;
|
||||
min = std::min(min, duration);
|
||||
max = std::max(max, duration);
|
||||
}
|
||||
|
||||
print_results(name, num_runs, total, min, max);
|
||||
}
|
||||
|
||||
} // benchmark
|
||||
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
|
||||
#include <fc/crypto/hex.hpp>
|
||||
|
||||
namespace eosio::benchmark {
|
||||
using bytes = std::vector<char>;
|
||||
|
||||
void set_num_runs(uint32_t runs);
|
||||
std::map<std::string, std::function<void()>> get_features();
|
||||
void print_header();
|
||||
bytes to_bytes(const std::string& source);
|
||||
|
||||
void alt_bn_128_benchmarking();
|
||||
void modexp_benchmarking();
|
||||
void key_benchmarking();
|
||||
void hash_benchmarking();
|
||||
void blake2_benchmarking();
|
||||
void bls_benchmarking();
|
||||
|
||||
void benchmarking(const std::string& name, const std::function<void()>& func);
|
||||
|
||||
} // benchmark
|
||||
@@ -1,21 +0,0 @@
|
||||
#include <fc/crypto/blake2.hpp>
|
||||
|
||||
#include <benchmark.hpp>
|
||||
|
||||
namespace eosio::benchmark {
|
||||
|
||||
void blake2_benchmarking() {
|
||||
uint32_t _rounds = 0x0C;
|
||||
bytes _h = to_bytes( "48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b");
|
||||
bytes _m = to_bytes("6162630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
|
||||
bytes _t0_offset = to_bytes("0300000000000000");
|
||||
bytes _t1_offset = to_bytes("0000000000000000");
|
||||
bool _f = false;
|
||||
|
||||
auto blake2_f = [&]() {
|
||||
fc::blake2b(_rounds, _h, _m, _t0_offset, _t1_offset, _f, [](){});;
|
||||
};
|
||||
benchmarking("blake2", blake2_f);
|
||||
}
|
||||
|
||||
} // benchmark
|
||||
@@ -1,444 +0,0 @@
|
||||
#include <benchmark.hpp>
|
||||
#include <eosio/chain/apply_context.hpp>
|
||||
#include <eosio/chain/webassembly/interface.hpp>
|
||||
#include <eosio/testing/tester.hpp>
|
||||
#include <test_contracts.hpp>
|
||||
#include <bls12-381/bls12-381.hpp>
|
||||
#include <random>
|
||||
|
||||
using namespace eosio;
|
||||
using namespace eosio::chain;
|
||||
using namespace eosio::testing;
|
||||
using namespace bls12_381;
|
||||
|
||||
// Benchmark BLS host functions without relying on CDT wrappers.
|
||||
//
|
||||
// To run a benchmarking session, in the build directory, type
|
||||
// benchmark/benchmark -f bls
|
||||
|
||||
namespace eosio::benchmark {
|
||||
|
||||
// To benchmark host functions directly without CDT wrappers,
|
||||
// we need to contruct an eosio::chain::webassembly::interface object,
|
||||
// because host functions are implemented in
|
||||
// eosio::chain::webassembly::interface class.
|
||||
struct interface_in_benchmark {
|
||||
interface_in_benchmark() {
|
||||
// prevent logging from interwined with output benchmark results
|
||||
fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::off);
|
||||
|
||||
// create a chain
|
||||
fc::temp_directory tempdir;
|
||||
auto conf_genesis = tester::default_config( tempdir );
|
||||
auto& cfg = conf_genesis.second.initial_configuration;
|
||||
// configure large cpu usgaes so expensive BLS functions like pairing
|
||||
// can finish within a trasaction time
|
||||
cfg.max_block_cpu_usage = 999'999'999;
|
||||
cfg.max_transaction_cpu_usage = 999'999'990;
|
||||
cfg.min_transaction_cpu_usage = 1;
|
||||
chain = std::make_unique<tester>(conf_genesis.first, conf_genesis.second);
|
||||
chain->execute_setup_policy( setup_policy::full );
|
||||
|
||||
// create account and deploy contract for a temp transaction
|
||||
chain->create_accounts( {"payloadless"_n} );
|
||||
chain->set_code( "payloadless"_n, test_contracts::payloadless_wasm() );
|
||||
chain->set_abi( "payloadless"_n, test_contracts::payloadless_abi() );
|
||||
|
||||
// construct a signed transaction
|
||||
fc::variant pretty_trx = fc::mutable_variant_object()
|
||||
("actions", fc::variants({
|
||||
fc::mutable_variant_object()
|
||||
("account", name("payloadless"_n))
|
||||
("name", "doit")
|
||||
("authorization", fc::variants({
|
||||
fc::mutable_variant_object()
|
||||
("actor", name("payloadless"_n))
|
||||
("permission", name(config::active_name))
|
||||
}))
|
||||
("data", fc::mutable_variant_object()
|
||||
)
|
||||
})
|
||||
);
|
||||
trx = std::make_unique<signed_transaction>();
|
||||
abi_serializer::from_variant(pretty_trx, *trx, chain->get_resolver(), abi_serializer::create_yield_function( chain->abi_serializer_max_time ));
|
||||
chain->set_transaction_headers(*trx);
|
||||
trx->sign( chain->get_private_key( "payloadless"_n, "active" ), chain->control.get()->get_chain_id() );
|
||||
|
||||
// construct a packed transaction
|
||||
ptrx = std::make_unique<packed_transaction>(*trx, eosio::chain::packed_transaction::compression_type::zlib);
|
||||
|
||||
// build transaction context from the packed transaction
|
||||
timer = std::make_unique<platform_timer>();
|
||||
trx_timer = std::make_unique<transaction_checktime_timer>(*timer);
|
||||
trx_ctx = std::make_unique<transaction_context>(*chain->control.get(), *ptrx, ptrx->id(), std::move(*trx_timer));
|
||||
trx_ctx->max_transaction_time_subjective = fc::microseconds::maximum();
|
||||
trx_ctx->init_for_input_trx( ptrx->get_unprunable_size(), ptrx->get_prunable_size() );
|
||||
trx_ctx->exec(); // this is required to generate action traces to be used by apply_context constructor
|
||||
|
||||
// build apply context from the control and transaction context
|
||||
apply_ctx = std::make_unique<apply_context>(*chain->control.get(), *trx_ctx, 1);
|
||||
|
||||
// finally construct the interface
|
||||
interface = std::make_unique<webassembly::interface>(*apply_ctx);
|
||||
}
|
||||
|
||||
std::unique_ptr<tester> chain;
|
||||
std::unique_ptr<signed_transaction> trx;
|
||||
std::unique_ptr<packed_transaction> ptrx;
|
||||
std::unique_ptr<platform_timer> timer;
|
||||
std::unique_ptr<transaction_checktime_timer> trx_timer;
|
||||
std::unique_ptr<transaction_context> trx_ctx;
|
||||
std::unique_ptr<apply_context> apply_ctx;
|
||||
std::unique_ptr<webassembly::interface> interface;
|
||||
};
|
||||
|
||||
// utilility to create a random scalar
|
||||
std::array<uint64_t, 4> random_scalar()
|
||||
{
|
||||
std::random_device rd;
|
||||
std::mt19937_64 gen(rd());
|
||||
std::uniform_int_distribution<uint64_t> dis;
|
||||
|
||||
return {
|
||||
dis(gen) % bls12_381::fp::Q[0],
|
||||
dis(gen) % bls12_381::fp::Q[1],
|
||||
dis(gen) % bls12_381::fp::Q[2],
|
||||
dis(gen) % bls12_381::fp::Q[3]
|
||||
};
|
||||
}
|
||||
|
||||
// utilility to create a random fp
|
||||
fp random_fe()
|
||||
{
|
||||
std::random_device rd;
|
||||
std::mt19937_64 gen(rd());
|
||||
std::uniform_int_distribution<uint64_t> dis;
|
||||
|
||||
return fp({
|
||||
dis(gen) % 0xb9feffffffffaaab,
|
||||
dis(gen) % 0x1eabfffeb153ffff,
|
||||
dis(gen) % 0x6730d2a0f6b0f624,
|
||||
dis(gen) % 0x64774b84f38512bf,
|
||||
dis(gen) % 0x4b1ba7b6434bacd7,
|
||||
dis(gen) % 0x1a0111ea397fe69a
|
||||
});
|
||||
}
|
||||
|
||||
// utilility to create a random fp2
|
||||
fp2 random_fe2()
|
||||
{
|
||||
return fp2({
|
||||
random_fe(),
|
||||
random_fe()
|
||||
});
|
||||
}
|
||||
|
||||
// utilility to create a random g1
|
||||
bls12_381::g1 random_g1()
|
||||
{
|
||||
std::array<uint64_t, 4> k = random_scalar();
|
||||
return bls12_381::g1::one().scale(k);
|
||||
}
|
||||
|
||||
// utilility to create a random g2
|
||||
bls12_381::g2 random_g2()
|
||||
{
|
||||
std::array<uint64_t, 4> k = random_scalar();
|
||||
return bls12_381::g2::one().scale(k);
|
||||
}
|
||||
|
||||
// bls_g1_add benchmarking
|
||||
void benchmark_bls_g1_add() {
|
||||
// prepare g1 operand in Jacobian LE format
|
||||
g1 p = random_g1();
|
||||
std::array<char, 96> op;
|
||||
p.toAffineBytesLE(std::span<uint8_t, 96>((uint8_t*)op.data(), 96), from_mont::yes);
|
||||
|
||||
// prepare result operand
|
||||
std::array<char, 96> result;
|
||||
|
||||
// set up bls_g1_add to be benchmarked
|
||||
interface_in_benchmark interface;
|
||||
auto benchmarked_func = [&]() {
|
||||
interface.interface->bls_g1_add(op, op, result);
|
||||
};
|
||||
|
||||
benchmarking("bls_g1_add", benchmarked_func);
|
||||
}
|
||||
|
||||
// bls_g2_add benchmarking
|
||||
void benchmark_bls_g2_add() {
|
||||
// prepare g2 operand in Jacobian LE format
|
||||
g2 p = random_g2();
|
||||
std::array<char, 192> op;
|
||||
p.toAffineBytesLE(std::span<uint8_t, 192>((uint8_t*)op.data(), 192), from_mont::yes);
|
||||
|
||||
// prepare result operand
|
||||
std::array<char, 192> result;
|
||||
|
||||
// set up bls_g2_add to be benchmarked
|
||||
interface_in_benchmark interface;
|
||||
auto benchmarked_func = [&]() {
|
||||
interface.interface->bls_g2_add(op, op, result);
|
||||
};
|
||||
|
||||
benchmarking("bls_g2_add", benchmarked_func);
|
||||
}
|
||||
|
||||
// bls_g1_weighted_sum benchmarking utility
|
||||
void benchmark_bls_g1_weighted_sum_impl(const std::string& test_name, uint32_t num_points) {
|
||||
// prepare g1 points operand
|
||||
std::vector<char> g1_buf(96*num_points);
|
||||
for (auto i=0u; i < num_points; ++i) {
|
||||
g1 p = random_g1();
|
||||
p.toAffineBytesLE(std::span<uint8_t, 96>((uint8_t*)g1_buf.data() + i * 96, 96), from_mont::yes);
|
||||
}
|
||||
chain::span<const char> g1_points(g1_buf.data(), g1_buf.size());
|
||||
|
||||
// prepare scalars operand
|
||||
std::vector<char> scalars_buf(32*num_points);
|
||||
for (auto i=0u; i < num_points; ++i) {
|
||||
std::array<uint64_t, 4> s = random_scalar();
|
||||
scalar::toBytesLE(s, std::span<uint8_t, 32>((uint8_t*)scalars_buf.data() + i*32, 32));
|
||||
}
|
||||
chain::span<const char> scalars(scalars_buf.data(), scalars_buf.size());
|
||||
|
||||
// prepare result operand
|
||||
std::array<char, 96> result;
|
||||
|
||||
// set up bls_g1_weighted_sum to be benchmarked
|
||||
interface_in_benchmark interface;
|
||||
auto benchmarked_func = [&]() {
|
||||
interface.interface->bls_g1_weighted_sum(g1_points, scalars, num_points, result);
|
||||
};
|
||||
|
||||
benchmarking(test_name, benchmarked_func);
|
||||
}
|
||||
|
||||
// bls_g1_weighted_sum benchmarking with 1 input point
|
||||
void benchmark_bls_g1_weighted_sum_one_point() {
|
||||
benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum 1 point", 1);
|
||||
}
|
||||
|
||||
// bls_g1_weighted_sum benchmarking with 3 input points
|
||||
void benchmark_bls_g1_weighted_sum_three_point() {
|
||||
benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum 3 points", 3);
|
||||
}
|
||||
|
||||
// bls_g1_weighted_sum benchmarking with 5 input points
|
||||
void benchmark_bls_g1_weighted_sum_five_point() {
|
||||
benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum 5 points", 5);
|
||||
}
|
||||
|
||||
// bls_g2_weighted_sum benchmarking utility
|
||||
void benchmark_bls_g2_weighted_sum_impl(const std::string& test_name, uint32_t num_points) {
|
||||
// prepare g2 points operand
|
||||
std::vector<char> g2_buf(192*num_points);
|
||||
for (auto i=0u; i < num_points; ++i) {
|
||||
g2 p = random_g2();
|
||||
p.toAffineBytesLE(std::span<uint8_t, 192>((uint8_t*)g2_buf.data() + i * 192, 192), from_mont::yes);
|
||||
}
|
||||
eosio::chain::span<const char> g2_points(g2_buf.data(), g2_buf.size());
|
||||
|
||||
// prepare scalars operand
|
||||
std::vector<char> scalars_buf(32*num_points);
|
||||
for (auto i=0u; i < num_points; ++i) {
|
||||
std::array<uint64_t, 4> s = random_scalar();
|
||||
scalar::toBytesLE(s, std::span<uint8_t, 32>((uint8_t*)scalars_buf.data() + i*32, 32));
|
||||
}
|
||||
eosio::chain::span<const char> scalars(scalars_buf.data(), scalars_buf.size());
|
||||
|
||||
// prepare result operand
|
||||
std::array<char, 192> result;
|
||||
|
||||
// set up bls_g2_weighted_sum to be benchmarked
|
||||
interface_in_benchmark interface;
|
||||
auto benchmarked_func = [&]() {
|
||||
interface.interface->bls_g2_weighted_sum(g2_points, scalars, num_points, result);
|
||||
};
|
||||
|
||||
benchmarking(test_name, benchmarked_func);
|
||||
}
|
||||
|
||||
// bls_g2_weighted_sum benchmarking with 1 input point
|
||||
void benchmark_bls_g2_weighted_sum_one_point() {
|
||||
benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum 1 point", 1);
|
||||
}
|
||||
|
||||
// bls_g2_weighted_sum benchmarking with 3 input points
|
||||
void benchmark_bls_g2_weighted_sum_three_point() {
|
||||
benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum 3 points", 3);
|
||||
}
|
||||
|
||||
// bls_g2_weighted_sum benchmarking with 5 input points
|
||||
void benchmark_bls_g2_weighted_sum_five_point() {
|
||||
benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum 5 points", 5);
|
||||
}
|
||||
|
||||
// bls_pairing benchmarking utility
|
||||
void benchmark_bls_pairing_impl(const std::string& test_name, uint32_t num_pairs) {
|
||||
// prepare g1 operand
|
||||
std::vector<char> g1_buf(96*num_pairs);
|
||||
for (auto i=0u; i < num_pairs; ++i) {
|
||||
g1 p = random_g1();
|
||||
p.toAffineBytesLE(std::span<uint8_t, 96>((uint8_t*)g1_buf.data() + i * 96, 96), from_mont::yes);
|
||||
}
|
||||
eosio::chain::span<const char> g1_points(g1_buf.data(), g1_buf.size());
|
||||
|
||||
// prepare g2 operand
|
||||
std::vector<char> g2_buf(192*num_pairs);
|
||||
for (auto i=0u; i < num_pairs; ++i) {
|
||||
g2 p2 = random_g2();
|
||||
p2.toAffineBytesLE(std::span<uint8_t, (192)>((uint8_t*)g2_buf.data() + i * 192, (192)), from_mont::yes);
|
||||
}
|
||||
eosio::chain::span<const char> g2_points(g2_buf.data(), g2_buf.size());
|
||||
|
||||
// prepare result operand
|
||||
std::array<char, 576> result;
|
||||
|
||||
// set up bls_pairing to be benchmarked
|
||||
interface_in_benchmark interface;
|
||||
auto benchmarked_func = [&]() {
|
||||
interface.interface->bls_pairing(g1_points, g2_points, num_pairs, result);
|
||||
};
|
||||
|
||||
benchmarking(test_name, benchmarked_func);
|
||||
}
|
||||
|
||||
// bls_pairing benchmarking with 1 input pair
|
||||
void benchmark_bls_pairing_one_pair() {
|
||||
benchmark_bls_pairing_impl("bls_pairing 1 pair", 1);
|
||||
}
|
||||
|
||||
// bls_pairing benchmarking with 3 input pairs
|
||||
void benchmark_bls_pairing_three_pair() {
|
||||
benchmark_bls_pairing_impl("bls_pairing 3 pairs", 3);
|
||||
}
|
||||
|
||||
// bls_g1_map benchmarking
|
||||
void benchmark_bls_g1_map() {
|
||||
// prepare e operand. Must be fp LE.
|
||||
std::array<char, 48> e;
|
||||
fp a = random_fe();
|
||||
a.toBytesLE(std::span<uint8_t, 48>((uint8_t*)e.data(), 48), from_mont::yes);
|
||||
|
||||
// prepare result operand
|
||||
std::array<char, 96> result;
|
||||
|
||||
// set up bls_g1_map to be benchmarked
|
||||
interface_in_benchmark interface;
|
||||
auto benchmarked_func = [&]() {
|
||||
interface.interface->bls_g1_map(e, result);
|
||||
};
|
||||
|
||||
benchmarking("bls_g1_map", benchmarked_func);
|
||||
}
|
||||
|
||||
// bls_g2_map benchmarking
|
||||
void benchmark_bls_g2_map() {
|
||||
std::array<char, 96> e;
|
||||
fp2 a = random_fe2();
|
||||
a.toBytesLE(std::span<uint8_t, 96>((uint8_t*)e.data(), 96), from_mont::yes);
|
||||
|
||||
// prepare result operand
|
||||
std::array<char, 192> result;
|
||||
|
||||
// set up bls_g2_map to be benchmarked
|
||||
interface_in_benchmark interface;
|
||||
auto benchmarked_func = [&]() {
|
||||
interface.interface->bls_g2_map(e, result);
|
||||
};
|
||||
|
||||
benchmarking("bls_g2_map", benchmarked_func);
|
||||
}
|
||||
|
||||
// bls_fp_mod benchmarking
|
||||
void benchmark_bls_fp_mod() {
|
||||
// prepare scalar operand
|
||||
std::array<char, 64> scalar;
|
||||
// random_scalar returns 32 bytes. need to call it twice
|
||||
for (auto i=0u; i < 2; ++i) {
|
||||
std::array<uint64_t, 4> s = random_scalar();
|
||||
scalar::toBytesLE(s, std::span<uint8_t, 32>((uint8_t*)scalar.data() + i*32, 32));
|
||||
}
|
||||
|
||||
// prepare result operand
|
||||
std::array<char, 48> result;
|
||||
|
||||
// set up bls_fp_mod to be benchmarked
|
||||
interface_in_benchmark interface;
|
||||
auto benchmarked_func = [&]() {
|
||||
interface.interface->bls_fp_mod(scalar, result);
|
||||
};
|
||||
|
||||
benchmarking("bls_fp_mod", benchmarked_func);
|
||||
}
|
||||
|
||||
void benchmark_bls_fp_mul() {
|
||||
// prepare op1
|
||||
std::array<char, 48> op1;
|
||||
fp a = random_fe();
|
||||
a.toBytesLE(std::span<uint8_t, 48>((uint8_t*)op1.data(), 48), from_mont::yes);
|
||||
|
||||
// prepare op2
|
||||
std::array<char, 48> op2;
|
||||
fp b = random_fe();
|
||||
b.toBytesLE(std::span<uint8_t, 48>((uint8_t*)op2.data(), 48), from_mont::yes);
|
||||
|
||||
// prepare result operand
|
||||
std::array<char, 48> result;
|
||||
|
||||
// set up bls_fp_mul to be benchmarked
|
||||
interface_in_benchmark interface;
|
||||
auto benchmarked_func = [&]() {
|
||||
interface.interface->bls_fp_mul(op1, op2, result);
|
||||
};
|
||||
|
||||
benchmarking("bls_fp_mul", benchmarked_func);
|
||||
}
|
||||
|
||||
void benchmark_bls_fp_exp() {
|
||||
// prepare base
|
||||
std::array<char, 48> base;
|
||||
fp a = random_fe();
|
||||
a.toBytesLE(std::span<uint8_t, 48>((uint8_t*)base.data(), 48), from_mont::yes);
|
||||
|
||||
// prepare exp operand
|
||||
std::array<char, 64> exp;
|
||||
// random_scalar returns 32 bytes. need to call it twice
|
||||
for (auto i=0u; i < 2; ++i) {
|
||||
std::array<uint64_t, 4> s = random_scalar();
|
||||
scalar::toBytesLE(s, std::span<uint8_t, 32>((uint8_t*)exp.data() + i*32, 32));
|
||||
}
|
||||
|
||||
// prepare result operand
|
||||
std::array<char, 48> result;
|
||||
|
||||
// set up bls_fp_exp to be benchmarked
|
||||
interface_in_benchmark interface;
|
||||
auto benchmarked_func = [&]() {
|
||||
interface.interface->bls_fp_exp(base, exp, result);
|
||||
};
|
||||
|
||||
benchmarking("bls_fp_exp", benchmarked_func);
|
||||
}
|
||||
|
||||
// register benchmarking functions
|
||||
void bls_benchmarking() {
|
||||
benchmark_bls_g1_add();
|
||||
benchmark_bls_g2_add();
|
||||
benchmark_bls_pairing_one_pair();
|
||||
benchmark_bls_pairing_three_pair();
|
||||
benchmark_bls_g1_weighted_sum_one_point();
|
||||
benchmark_bls_g1_weighted_sum_three_point();
|
||||
benchmark_bls_g1_weighted_sum_five_point();
|
||||
benchmark_bls_g2_weighted_sum_one_point();
|
||||
benchmark_bls_g2_weighted_sum_three_point();
|
||||
benchmark_bls_g2_weighted_sum_five_point();
|
||||
benchmark_bls_g1_map();
|
||||
benchmark_bls_g2_map();
|
||||
benchmark_bls_fp_mod();
|
||||
benchmark_bls_fp_mul();
|
||||
benchmark_bls_fp_exp();
|
||||
}
|
||||
} // namespace benchmark
|
||||
@@ -1,89 +0,0 @@
|
||||
#include <fc/crypto/hex.hpp>
|
||||
#include <fc/crypto/sha1.hpp>
|
||||
#include <fc/crypto/sha3.hpp>
|
||||
#include <fc/crypto/sha256.hpp>
|
||||
#include <fc/crypto/sha512.hpp>
|
||||
#include <fc/crypto/ripemd160.hpp>
|
||||
#include <fc/utility.hpp>
|
||||
|
||||
#include <benchmark.hpp>
|
||||
|
||||
using namespace fc;
|
||||
|
||||
namespace eosio::benchmark {
|
||||
|
||||
void hash_benchmarking() {
|
||||
std::string small_message = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ01";
|
||||
|
||||
// build a large message
|
||||
constexpr auto large_msg_size = 4096;
|
||||
std::string large_message;
|
||||
large_message.reserve(large_msg_size);
|
||||
uint32_t num_concats = large_msg_size/small_message.length();
|
||||
for (uint32_t i = 0; i < num_concats; ++i) {
|
||||
large_message += small_message;
|
||||
}
|
||||
|
||||
auto sha1_small_msg = [&]() {
|
||||
fc::sha1::hash(small_message);
|
||||
};
|
||||
benchmarking("sha1 (" + std::to_string(small_message.length()) + " bytes)", sha1_small_msg);
|
||||
|
||||
auto sha1_large_msg = [&]() {
|
||||
fc::sha1::hash(large_message);
|
||||
};
|
||||
benchmarking("sha1 (" + std::to_string(large_message.length()) + " bytes)", sha1_large_msg);
|
||||
|
||||
auto sha256_small_msg = [&]() {
|
||||
fc::sha256::hash(small_message);
|
||||
};
|
||||
benchmarking("sha256 (" + std::to_string(small_message.length()) + " bytes)", sha256_small_msg);
|
||||
|
||||
auto sha256_large_msg = [&]() {
|
||||
fc::sha256::hash(large_message);
|
||||
};
|
||||
benchmarking("sha256 (" + std::to_string(large_message.length()) + " bytes)", sha256_large_msg);
|
||||
|
||||
auto sha512_small_msg = [&]() {
|
||||
fc::sha512::hash(small_message);
|
||||
};
|
||||
benchmarking("sha512 (" + std::to_string(small_message.length()) + " bytes)", sha512_small_msg);
|
||||
|
||||
auto sha512_large_msg = [&]() {
|
||||
fc::sha512::hash(large_message);
|
||||
};
|
||||
benchmarking("sha512 (" + std::to_string(large_message.length()) + " bytes)", sha512_large_msg);
|
||||
|
||||
auto ripemd160_small_msg = [&]() {
|
||||
fc::ripemd160::hash(small_message);
|
||||
};
|
||||
benchmarking("ripemd160 (" + std::to_string(small_message.length()) + " bytes)", ripemd160_small_msg);
|
||||
|
||||
auto ripemd160_large_msg = [&]() {
|
||||
fc::ripemd160::hash(large_message);
|
||||
};
|
||||
benchmarking("ripemd160 (" + std::to_string(large_message.length()) + " bytes)", ripemd160_large_msg);
|
||||
|
||||
auto sha3_small_msg = [&]() {
|
||||
fc::sha3::hash(small_message, true);
|
||||
};
|
||||
benchmarking("sha3-256 (" + std::to_string(small_message.length()) + " bytes)", sha3_small_msg);
|
||||
|
||||
auto sha3_large_msg = [&]() {
|
||||
fc::sha3::hash(large_message, true);
|
||||
};
|
||||
benchmarking("sha3-256 (" + std::to_string(large_message.length()) + " bytes)", sha3_large_msg);
|
||||
|
||||
auto keccak_small_msg = [&]() {
|
||||
fc::sha3::hash(small_message, false);
|
||||
};
|
||||
benchmarking("keccak256 (" + std::to_string(small_message.length()) + " bytes)", keccak_small_msg);
|
||||
|
||||
auto keccak_large_msg = [&]() {
|
||||
fc::sha3::hash(large_message, false);
|
||||
};
|
||||
benchmarking("keccak256 (" + std::to_string(large_message.length()) + " bytes)", keccak_large_msg);
|
||||
|
||||
}
|
||||
|
||||
} // benchmark
|
||||
@@ -1,109 +0,0 @@
|
||||
#include <fc/crypto/public_key.hpp>
|
||||
#include <fc/crypto/private_key.hpp>
|
||||
#include <fc/crypto/signature.hpp>
|
||||
#include <fc/crypto/k1_recover.hpp>
|
||||
|
||||
#include <benchmark.hpp>
|
||||
|
||||
using namespace fc::crypto;
|
||||
using namespace fc;
|
||||
using namespace std::literals;
|
||||
|
||||
namespace eosio::benchmark {
|
||||
|
||||
void k1_sign_benchmarking() {
|
||||
auto payload = "Test Cases";
|
||||
auto digest = sha256::hash(payload, const_strlen(payload));
|
||||
auto private_key_string = std::string("5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3");
|
||||
auto key = private_key(private_key_string);
|
||||
|
||||
auto sign_non_canonical_f = [&]() {
|
||||
key.sign(digest, false);
|
||||
};
|
||||
benchmarking("k1_sign_non_canonical", sign_non_canonical_f);
|
||||
}
|
||||
|
||||
void k1_recover_benchmarking() {
|
||||
auto signature = to_bytes( "1b323dd47a1dd5592c296ee2ee12e0af38974087a475e99098a440284f19c1f7642fa0baa10a8a3ab800dfdbe987dee68a09b6fa3db45a5cc4f3a5835a1671d4dd");
|
||||
auto digest = to_bytes( "92390316873c5a9d520b28aba61e7a8f00025ac069acd9c4d2a71d775a55fa5f");
|
||||
|
||||
auto recover_f = [&]() {
|
||||
fc::k1_recover(signature, digest);
|
||||
};
|
||||
benchmarking("k1_recover", recover_f);
|
||||
}
|
||||
|
||||
void k1_benchmarking() {
|
||||
k1_sign_benchmarking();
|
||||
k1_recover_benchmarking();
|
||||
}
|
||||
|
||||
void r1_benchmarking() {
|
||||
auto payload = "Test Cases";
|
||||
auto digest = sha256::hash(payload, const_strlen(payload));
|
||||
auto key = private_key::generate<r1::private_key_shim>();
|
||||
|
||||
auto sign_f = [&]() {
|
||||
key.sign(digest);
|
||||
};
|
||||
benchmarking("r1_sign", sign_f);
|
||||
|
||||
auto sig = key.sign(digest);
|
||||
auto recover_f = [&]() {
|
||||
public_key(sig, digest);;
|
||||
};
|
||||
benchmarking("r1_recover", recover_f);
|
||||
}
|
||||
|
||||
static fc::crypto::webauthn::signature make_webauthn_sig(const fc::crypto::r1::private_key& priv_key,
|
||||
std::vector<uint8_t>& auth_data,
|
||||
const std::string& json) {
|
||||
|
||||
//webauthn signature is sha256(auth_data || client_data_hash)
|
||||
fc::sha256 client_data_hash = fc::sha256::hash(json);
|
||||
fc::sha256::encoder e;
|
||||
e.write((char*)auth_data.data(), auth_data.size());
|
||||
e.write(client_data_hash.data(), client_data_hash.data_size());
|
||||
|
||||
r1::compact_signature sig = priv_key.sign_compact(e.result());
|
||||
|
||||
char buff[8192];
|
||||
datastream<char*> ds(buff, sizeof(buff));
|
||||
fc::raw::pack(ds, sig);
|
||||
fc::raw::pack(ds, auth_data);
|
||||
fc::raw::pack(ds, json);
|
||||
ds.seekp(0);
|
||||
|
||||
fc::crypto::webauthn::signature ret;
|
||||
fc::raw::unpack(ds, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void wa_benchmarking() {
|
||||
static const r1::private_key priv = fc::crypto::r1::private_key::generate();
|
||||
static const fc::sha256 d = fc::sha256::hash("sup"s);
|
||||
static const fc::sha256 origin_hash = fc::sha256::hash("fctesting.invalid"s);
|
||||
std::string json = "{\"origin\":\"https://fctesting.invalid\",\"type\":\"webauthn.get\", \"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
|
||||
std::vector<uint8_t> auth_data(37);
|
||||
memcpy(auth_data.data(), origin_hash.data(), sizeof(origin_hash));
|
||||
|
||||
auto sign = [&]() {
|
||||
make_webauthn_sig(priv, auth_data, json);
|
||||
};
|
||||
benchmarking("webauthn_sign", sign);
|
||||
|
||||
auto sig = make_webauthn_sig(priv, auth_data, json);
|
||||
auto recover= [&]() {
|
||||
sig.recover(d, true);
|
||||
};
|
||||
benchmarking("webauthn_recover", recover);
|
||||
}
|
||||
|
||||
void key_benchmarking() {
|
||||
k1_benchmarking();
|
||||
r1_benchmarking();
|
||||
wa_benchmarking();
|
||||
}
|
||||
|
||||
} // benchmark
|
||||
@@ -1,80 +0,0 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
#include <benchmark.hpp>
|
||||
|
||||
namespace bpo = boost::program_options;
|
||||
using bpo::options_description;
|
||||
using bpo::variables_map;
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
uint32_t num_runs = 1;
|
||||
std::string feature_name;
|
||||
|
||||
auto features = eosio::benchmark::get_features();
|
||||
|
||||
options_description cli ("benchmark command line options");
|
||||
cli.add_options()
|
||||
("feature,f", bpo::value<std::string>(), "feature to be benchmarked; if this option is not present, all features are benchmarked.")
|
||||
("list,l", "list of supported features")
|
||||
("runs,r", bpo::value<uint32_t>(&num_runs)->default_value(1000), "the number of times running a function during benchmarking")
|
||||
("help,h", "benchmark functions, and report average, minimum, and maximum execution time in nanoseconds");
|
||||
|
||||
variables_map vmap;
|
||||
try {
|
||||
bpo::store(bpo::parse_command_line(argc, argv, cli), vmap);
|
||||
bpo::notify(vmap);
|
||||
|
||||
if (vmap.count("help") > 0) {
|
||||
cli.print(std::cerr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vmap.count("list") > 0) {
|
||||
auto first = true;
|
||||
std::cout << "Supported features are ";
|
||||
for (auto& [name, f]: features) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
std::cout << ", ";
|
||||
}
|
||||
std::cout << name;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vmap.count("feature") > 0) {
|
||||
feature_name = vmap["feature"].as<std::string>();
|
||||
if (features.find(feature_name) == features.end()) {
|
||||
std::cout << feature_name << " is not supported" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} catch (bpo::unknown_option &ex) {
|
||||
std::cerr << ex.what() << std::endl;
|
||||
cli.print (std::cerr);
|
||||
return 1;
|
||||
} catch( ... ) {
|
||||
std::cerr << "unknown exception" << std::endl;
|
||||
}
|
||||
|
||||
eosio::benchmark::set_num_runs(num_runs);
|
||||
eosio::benchmark::print_header();
|
||||
|
||||
if (feature_name.empty()) {
|
||||
for (auto& [name, f]: features) {
|
||||
std::cout << name << ":" << std::endl;
|
||||
f();
|
||||
std::cout << std::endl;
|
||||
}
|
||||
} else {
|
||||
std::cout << feature_name << ":" << std::endl;
|
||||
features[feature_name]();
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
#include <fc/crypto/modular_arithmetic.hpp>
|
||||
#include <fc/exception/exception.hpp>
|
||||
|
||||
#include <random>
|
||||
|
||||
#include <benchmark.hpp>
|
||||
|
||||
namespace eosio::benchmark {
|
||||
|
||||
void modexp_benchmarking() {
|
||||
std::mt19937 r(0x11223344);
|
||||
|
||||
auto generate_random_bytes = [](std::mt19937& rand_eng, unsigned int num_bytes) {
|
||||
std::vector<char> result(num_bytes);
|
||||
|
||||
uint_fast32_t v = 0;
|
||||
for(int byte_pos = 0, end = result.size(); byte_pos < end; ++byte_pos) {
|
||||
if ((byte_pos & 0x03) == 0) { // if divisible by 4
|
||||
v = rand_eng();
|
||||
}
|
||||
result[byte_pos] = v & 0xFF;
|
||||
v >>= 8;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
static constexpr unsigned int start_num_bytes = 8;
|
||||
static constexpr unsigned int end_num_bytes = 256;
|
||||
|
||||
static_assert(start_num_bytes <= end_num_bytes);
|
||||
static_assert((start_num_bytes & (start_num_bytes - 1)) == 0);
|
||||
static_assert((end_num_bytes & (end_num_bytes - 1)) == 0);
|
||||
|
||||
for (unsigned int n = start_num_bytes; n <= end_num_bytes; n *= 2) {
|
||||
auto base = generate_random_bytes(r, n);
|
||||
auto exponent = generate_random_bytes(r, n);
|
||||
auto modulus = generate_random_bytes(r, n);
|
||||
|
||||
auto f = [&]() {
|
||||
fc::modexp(base, exponent, modulus);
|
||||
};
|
||||
|
||||
auto even_and_odd = [&](const std::string& bm) {
|
||||
//some modexp implementations have drastically different performance characteristics depending on whether the modulus is
|
||||
// even or odd (this can determine whether Montgomery multiplication is used). So test both cases.
|
||||
modulus.back() &= ~1;
|
||||
benchmarking(std::to_string(n*8) + " bit even M, " + bm, f);
|
||||
modulus.back() |= 1;
|
||||
benchmarking(std::to_string(n*8) + " bit odd M, " + bm, f);
|
||||
};
|
||||
|
||||
//some modexp implementations need to take a minor different path if base is greater than modulus, try both
|
||||
FC_ASSERT(modulus[0] != '\xff' && modulus[0] != 0);
|
||||
base.front() = 0;
|
||||
even_and_odd("B<M");
|
||||
base.front() = '\xff';
|
||||
even_and_odd("B>M");
|
||||
}
|
||||
|
||||
// Running the above benchmark (using commented values for num_trials and *_num_bytes) with a release build on an AMD 3.4 GHz CPU
|
||||
// provides average durations for executing mod_exp for increasing bit sizes for the value.
|
||||
|
||||
// For example: with 512-bit values, the average duration is approximately 40 microseconds; with 1024-bit values, the average duration
|
||||
// is approximately 260 microseconds; with 2048-bit values, the average duration is approximately 2 milliseconds; and, with 4096-bit
|
||||
// values, the average duration is approximately 14 milliseconds.
|
||||
|
||||
// It appears that a model of the average time that scales quadratically with the bit size fits the empirically generated data well.
|
||||
// TODO: See if theoretical analysis of the modular exponentiation algorithm also justifies quadratic scaling.
|
||||
}
|
||||
|
||||
} // benchmark
|
||||
@@ -4,9 +4,13 @@ content_title: Build Antelope from Source on Other Unix-based OS
|
||||
|
||||
**Please keep in mind that instructions for building from source on other unsupported operating systems provided here should be considered experimental and provided AS-IS on a best-effort basis and may not be fully featured.**
|
||||
|
||||
**A Warning On Parallel Compilation Jobs (`-j` flag)**: When building C/C++ software often the build is performed in parallel via a command such as `make -j $(nproc)` which uses the number of CPU cores as the number of compilation jobs to perform simultaneously. However, be aware that some compilation units (.cpp files) in leap are extremely complex and will consume nearly 4GB of memory to compile. You may need to reduce the level of parallelization depending on the amount of memory on your build host. e.g. instead of `make -j $(nproc)` run `make -j2`. Failures due to memory exhaustion will typically but not always manifest as compiler crashes.
|
||||
### Using DUNE
|
||||
|
||||
Generally we recommend performing what we refer to as a "pinned build" which ensures the compiler and boost version remain the same between builds of different leap versions (leap requires these versions remain the same otherwise its state needs to be repopulated from a portable snapshot).
|
||||
For the official multi-platform support try [Docker Utilities for Node Execution](https://github.com/AntelopeIO/DUNE) which runs in an ubuntu image via a docker container.
|
||||
|
||||
**A Warning On Parallel Compilation Jobs (`-j` flag)**: When building C/C++ software often the build is performed in parallel via a command such as `make -j $(nproc)` which uses the number of CPU cores as the number of compilation jobs to perform simultaneously. However, be aware that some compilation units (.cpp files) in mandel are extremely complex and will consume nearly 4GB of memory to compile. You may need to reduce the level of parallelization depending on the amount of memory on your build host. e.g. instead of `make -j $(nproc)` run `make -j2`. Failures due to memory exhaustion will typically but not always manifest as compiler crashes.
|
||||
|
||||
Generally we recommend performing what we refer to as a "pinned build" which ensures the compiler and boost version remain the same between builds of different mandel versions (mandel requires these versions remain the same otherwise its state needs to be repopulated from a portable snapshot).
|
||||
|
||||
<details>
|
||||
<summary>FreeBSD 13.1 Build Instructions</summary>
|
||||
@@ -19,6 +23,7 @@ pkg update && pkg install \
|
||||
curl \
|
||||
boost-all \
|
||||
python3 \
|
||||
openssl \
|
||||
llvm11 \
|
||||
pkgconf
|
||||
```
|
||||
|
||||
@@ -2,19 +2,19 @@
|
||||
content_title: Build Antelope from Source
|
||||
---
|
||||
|
||||
The shell scripts previously recommended for building the software have been removed in favor of a build process entirely driven by CMake. Those wishing to build from source are now responsible for installing the necessary dependencies. The list of dependencies and the recommended build procedure are in the [`README.md`](https://github.com/AntelopeIO/leap/blob/main/README.md) file. Instructions are also included for efficiently running the tests.
|
||||
The shell scripts previously recommended for building the software have been removed in favor of a build process entirely driven by CMake. Those wishing to build from source are now responsible for installing the necessary dependencies. The list of dependencies and the recommended build procedure are in the [`README.md`](https://github.com/AntelopeIO/leap/blob/release/3.1/README.md) file. Instructions are also included for efficiently running the tests.
|
||||
|
||||
### Using DUNE
|
||||
As an alternative to building from source, try [Docker Utilities for Node Execution](https://github.com/AntelopeIO/DUNE) for the easiest way to get started and for multi-platform support.
|
||||
|
||||
### Building From Source
|
||||
You can also build and install Leap from source. Instructions for that currently live [here](https://github.com/AntelopeIO/leap/blob/main/README.md#build-and-install-from-source).
|
||||
You can also build and install Leap from source. Instructions for that currently live [here](https://github.com/AntelopeIO/leap/blob/release/3.1/README.md#build-and-install-from-source).
|
||||
|
||||
#### Building Pinned Build Binary Packages
|
||||
The pinned build instructions have moved [here](https://github.com/AntelopeIO/leap/blob/main/README.md#pinned-build). You may want to look at the [prerequisites](https://github.com/AntelopeIO/leap/blob/main/README.md#prerequisites) and our warning on parallelization using the `-j` jobs flag [here](https://github.com/AntelopeIO/leap/blob/main/README.md#step-3---build) before you build.
|
||||
The pinned build instructions have moved [here](https://github.com/AntelopeIO/leap/blob/release/3.1/README.md#pinned-build). You may want to look at the [prerequisites](https://github.com/AntelopeIO/leap/blob/release/3.1/README.md#prerequisites) and our warning on parallelization using the `-j` jobs flag [here](https://github.com/AntelopeIO/leap/blob/release/3.1/README.md#step-3---build) before you build.
|
||||
|
||||
#### Manual (non "pinned") Build Instructions
|
||||
The unpinned build instructions have moved [here](https://github.com/AntelopeIO/leap/blob/main/README.md#unpinned-build). You may want to look at the [prerequisites](https://github.com/AntelopeIO/leap/blob/main/README.md#prerequisites) and our warning on parallelization using the `-j` jobs flag [here](https://github.com/AntelopeIO/leap/blob/main/README.md#step-3---build) before you build.
|
||||
The unpinned build instructions have moved [here](https://github.com/AntelopeIO/leap/blob/release/3.1/README.md#unpinned-build). You may want to look at the [prerequisites](https://github.com/AntelopeIO/leap/blob/release/3.1/README.md#prerequisites) and our warning on parallelization using the `-j` jobs flag [here](https://github.com/AntelopeIO/leap/blob/release/3.1/README.md#step-3---build) before you build.
|
||||
|
||||
### Running Tests
|
||||
Documentation on available test suites and how to run them has moved [here](https://github.com/AntelopeIO/leap/blob/main/README.md#test).
|
||||
Documentation on available test suites and how to run them has moved [here](https://github.com/AntelopeIO/leap/blob/release/3.1/README.md#test).
|
||||
|
||||
@@ -12,6 +12,7 @@ Antelope currently supports the following operating systems:
|
||||
|
||||
1. Ubuntu 22.04 Jammy
|
||||
2. Ubuntu 20.04 Focal
|
||||
3. Ubuntu 18.04 Bionic
|
||||
|
||||
[[info | Note]]
|
||||
| It may be possible to build and install Antelope on other Unix-based operating systems. We gathered helpful information on the following page but please keep in mind that it is experimental and not officially supported.
|
||||
|
||||
@@ -29,6 +29,7 @@ nodeos \
|
||||
--plugin eosio::http_plugin \
|
||||
--plugin eosio::state_history_plugin \
|
||||
--contracts-console \
|
||||
--disable-replay-opts \
|
||||
--access-control-allow-origin='*' \
|
||||
--http-validate-host=false \
|
||||
--verbose-http-errors \
|
||||
@@ -45,7 +46,7 @@ The above `nodeos` command starts a producing node by:
|
||||
* setting the blockchain data directory (`--data-dir`)
|
||||
* setting the `config.ini` directory (`--config-dir`)
|
||||
* loading plugins `producer_plugin`, `chain_plugin`, `http_plugin`, `state_history_plugin` (`--plugin`)
|
||||
* passing `chain_plugin` options (`--contracts-console`)
|
||||
* passing `chain_plugin` options (`--contracts-console`, `--disable-replay-opts`)
|
||||
* passing `http-plugin` options (`--access-control-allow-origin`, `--http-validate-host`, `--verbose-http-errors`)
|
||||
* passing `state_history` options (`--state-history-dir`, `--trace-history`, `--chain-state-history`)
|
||||
* redirecting both `stdout` and `stderr` to the `nodeos.log` file
|
||||
|
||||
@@ -143,7 +143,7 @@ We now have an account that is available to have a contract assigned to it, enab
|
||||
In the fourth terminal window, start a second `nodeos` instance. Notice that this command line is substantially longer than the one we used above to create the first producer. This is necessary to avoid collisions with the first `nodeos` instance. Fortunately, you can just cut and paste this command line and adjust the keys:
|
||||
|
||||
```sh
|
||||
nodeos --producer-name inita --plugin eosio::chain_api_plugin --plugin eosio::net_api_plugin --http-server-address 127.0.0.1:8889 --p2p-listen-endpoint 127.0.0.1:9877 --p2p-peer-address 127.0.0.1:9876 --config-dir node2 --data-dir node2 --signature-provider EOS6hMjoWRF2L8x9YpeqtUEcsDKAyxSuM1APicxgRU1E3oyV5sDEg=KEY:5JgbL2ZnoEAhTudReWH1RnMuQS6DBeLZt4ucV6t8aymVEuYg7sr
|
||||
nodeos --producer-name inita --plugin eosio::chain_api_plugin --plugin eosio::net_api_plugin --http-server-address 127.0.0.1:8889 --p2p-listen-endpoint 127.0.0.1:9877 --p2p-peer-address 127.0.0.1:9876 --config-dir node2 --data-dir node2 --private-key [\"EOS6hMjoWRF2L8x9YpeqtUEcsDKAyxSuM1APicxgRU1E3oyV5sDEg\",\"5JgbL2ZnoEAhTudReWH1RnMuQS6DBeLZt4ucV6t8aymVEuYg7sr\"]
|
||||
```
|
||||
|
||||
The output from this new node will show a little activity but will stop reporting until the last step in this tutorial, when the `inita` account is registered as a producer account and activated. Here is some example output from a newly started node. Your output might look a little different, depending on how much time you took entering each of these commands. Furthermore, this example is only the last few lines of output:
|
||||
|
||||
@@ -63,9 +63,6 @@ Config Options for eosio::chain_plugin:
|
||||
--blocks-dir arg (="blocks") the location of the blocks directory
|
||||
(absolute path or relative to
|
||||
application data dir)
|
||||
--state-dir arg (="state") the location of the state directory
|
||||
(absolute path or relative to
|
||||
application data dir)
|
||||
--protocol-features-dir arg (="protocol_features")
|
||||
the location of the protocol_features
|
||||
directory (absolute path or relative to
|
||||
@@ -119,25 +116,36 @@ Config Options for eosio::chain_plugin:
|
||||
subjective whitelist/blacklist checks
|
||||
applied to them (may specify multiple
|
||||
times)
|
||||
--read-mode arg (=head) Database read mode ("head",
|
||||
"irreversible", "speculative").
|
||||
In "head" mode: database contains state
|
||||
changes up to the head block;
|
||||
transactions received by the node are
|
||||
relayed if valid.
|
||||
In "irreversible" mode: database
|
||||
contains state changes up to the last
|
||||
irreversible block; transactions
|
||||
received via the P2P network are not
|
||||
relayed and transactions cannot be
|
||||
pushed via the chain API.
|
||||
--read-mode arg (=speculative) Database read mode ("speculative",
|
||||
"head", "read-only", "irreversible").
|
||||
In "speculative" mode: database
|
||||
contains state changes by transactions
|
||||
in the blockchain up to the head block
|
||||
as well as some transactions not yet
|
||||
included in the blockchain;
|
||||
included in the blockchain.
|
||||
In "head" mode: database contains state
|
||||
changes by only transactions in the
|
||||
blockchain up to the head block;
|
||||
transactions received by the node are
|
||||
relayed if valid.
|
||||
relayed if valid.
|
||||
In "read-only" mode: (DEPRECATED: see
|
||||
p2p-accept-transactions &
|
||||
api-accept-transactions) database
|
||||
contains state changes by only
|
||||
transactions in the blockchain up to
|
||||
the head block; transactions received
|
||||
via the P2P network are not relayed and
|
||||
transactions cannot be pushed via the
|
||||
chain API.
|
||||
In "irreversible" mode: database
|
||||
contains state changes by only
|
||||
transactions in the blockchain up to
|
||||
the last irreversible block;
|
||||
transactions received via the P2P
|
||||
network are not relayed and
|
||||
transactions cannot be pushed via the
|
||||
chain API.
|
||||
|
||||
--api-accept-transactions arg (=1) Allow API transactions to be evaluated
|
||||
and relayed if valid.
|
||||
--validation-mode arg (=full) Chain validation mode ("full" or
|
||||
@@ -163,14 +171,10 @@ Config Options for eosio::chain_plugin:
|
||||
headers signed by it will be fully
|
||||
validated, but transactions in those
|
||||
validated blocks will be trusted.
|
||||
--database-map-mode arg (=mapped) Database map mode ("mapped",
|
||||
"mapped_private", "heap", or "locked").
|
||||
--database-map-mode arg (=mapped) Database map mode ("mapped", "heap", or
|
||||
"locked").
|
||||
In "mapped" mode database is memory
|
||||
mapped as a file.
|
||||
In "mapped_private" mode database is
|
||||
memory mapped as a file using a private
|
||||
mapping (no disk writeback until
|
||||
program exit).
|
||||
In "heap" mode database is preloaded in
|
||||
to swappable memory and will use huge
|
||||
pages if available.
|
||||
@@ -182,35 +186,26 @@ Config Options for eosio::chain_plugin:
|
||||
code cache
|
||||
--eos-vm-oc-compile-threads arg (=1) Number of threads to use for EOS VM OC
|
||||
tier-up
|
||||
--eos-vm-oc-enable arg (=auto) Enable EOS VM OC tier-up runtime
|
||||
('auto', 'all', 'none').
|
||||
'auto' - EOS VM OC tier-up is enabled
|
||||
for eosio.* accounts, read-only trxs,
|
||||
and applying blocks.
|
||||
'all' - EOS VM OC tier-up is enabled
|
||||
for all contract execution.
|
||||
'none' - EOS VM OC tier-up is
|
||||
completely disabled.
|
||||
|
||||
--eos-vm-oc-enable Enable EOS VM OC tier-up runtime
|
||||
--enable-account-queries arg (=0) enable queries to find accounts by
|
||||
various metadata.
|
||||
--max-nonprivileged-inline-action-size arg (=4096)
|
||||
maximum allowed size (in bytes) of an
|
||||
inline action for a nonprivileged
|
||||
account
|
||||
--transaction-retry-max-storage-size-gb arg
|
||||
Maximum size (in GiB) allowed to be
|
||||
allocated for the Transaction Retry
|
||||
feature. Setting above 0 enables this
|
||||
feature.
|
||||
--transaction-retry-interval-sec arg (=20)
|
||||
How often, in seconds, to resend an
|
||||
incoming transaction to network if not
|
||||
How often, in seconds, to resend an
|
||||
incoming transaction to network if not
|
||||
seen in a block.
|
||||
Needs to be at least twice as large as
|
||||
p2p-dedup-cache-expire-time-sec.
|
||||
--transaction-retry-max-expiration-sec arg (=120)
|
||||
Maximum allowed transaction expiration
|
||||
for retry transactions, will retry
|
||||
Maximum allowed transaction expiration
|
||||
for retry transactions, will retry
|
||||
transactions up to this value.
|
||||
Should be larger than
|
||||
transaction-retry-interval-sec.
|
||||
--transaction-finality-status-max-storage-size-gb arg
|
||||
Maximum size (in GiB) allowed to be
|
||||
allocated for the Transaction Finality
|
||||
@@ -226,16 +221,9 @@ Config Options for eosio::chain_plugin:
|
||||
transaction's Finality Status will
|
||||
remain available from being first
|
||||
identified.
|
||||
--integrity-hash-on-start Log the state integrity hash on startup
|
||||
--integrity-hash-on-stop Log the state integrity hash on
|
||||
shutdown
|
||||
--block-log-retain-blocks arg If set to greater than 0, periodically
|
||||
prune the block log to store only
|
||||
configured number of most recent
|
||||
blocks.
|
||||
If set to 0, no blocks are be written
|
||||
to the block log; block log file is
|
||||
removed after startup.
|
||||
--block-log-retain-blocks arg if set, periodically prune the block
|
||||
log to store only configured number of
|
||||
most recent blocks
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
## Description
|
||||
|
||||
The `http_client_plugin` is an internal utility plugin, providing the `producer_plugin` the ability to use securely an external `keosd` instance as its block signer. It can only be used when the `producer_plugin` is configured to produce blocks.
|
||||
|
||||
## Usage
|
||||
|
||||
```console
|
||||
# config.ini
|
||||
plugin = eosio::http_client_plugin
|
||||
https-client-root-cert = "path/to/my/certificate.pem"
|
||||
https-client-validate-peers = 1
|
||||
```
|
||||
```sh
|
||||
# command-line
|
||||
nodeos ... --plugin eosio::http_client_plugin \
|
||||
--https-client-root-cert "path/to/my/certificate.pem" \
|
||||
--https-client-validate-peers 1
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
These can be specified from both the `nodeos` command-line or the `config.ini` file:
|
||||
|
||||
```console
|
||||
Config Options for eosio::http_client_plugin:
|
||||
--https-client-root-cert arg PEM encoded trusted root certificate
|
||||
(or path to file containing one) used
|
||||
to validate any TLS connections made.
|
||||
(may specify multiple times)
|
||||
|
||||
--https-client-validate-peers arg (=1)
|
||||
true: validate that the peer
|
||||
certificates are valid and trusted,
|
||||
false: ignore cert errors
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
* [`producer_plugin`](../producer_plugin/index.md)
|
||||
@@ -29,10 +29,20 @@ Config Options for eosio::http_plugin:
|
||||
The local IP and port to listen for
|
||||
incoming http connections; set blank to
|
||||
disable.
|
||||
--https-server-address arg The local IP and port to listen for
|
||||
incoming https connections; leave blank
|
||||
to disable.
|
||||
--https-certificate-chain-file arg Filename with the certificate chain to
|
||||
present on https connections. PEM
|
||||
format. Required for https.
|
||||
--https-private-key-file arg Filename with https private key in PEM
|
||||
format. Required for https
|
||||
--https-ecdh-curve arg (=secp384r1) Configure https ECDH curve to use:
|
||||
secp384r1 or prime256v1
|
||||
--access-control-allow-origin arg Specify the Access-Control-Allow-Origin
|
||||
to be returned on each request
|
||||
to be returned on each request.
|
||||
--access-control-allow-headers arg Specify the Access-Control-Allow-Header
|
||||
s to be returned on each request
|
||||
s to be returned on each request.
|
||||
--access-control-max-age arg Specify the Access-Control-Max-Age to
|
||||
be returned on each request.
|
||||
--access-control-allow-credentials Specify if Access-Control-Allow-Credent
|
||||
@@ -45,13 +55,7 @@ Config Options for eosio::http_plugin:
|
||||
should use for processing http
|
||||
requests. -1 for unlimited. 429 error
|
||||
response when exceeded.
|
||||
--http-max-in-flight-requests arg (=-1)
|
||||
Maximum number of requests http_plugin
|
||||
should use for processing http
|
||||
requests. 429 error response when
|
||||
exceeded.
|
||||
--http-max-response-time-ms arg (=30) Maximum time for processing a request,
|
||||
-1 for unlimited
|
||||
--http-max-response-time-ms arg (=30) Maximum time for processing a request.
|
||||
--verbose-http-errors Append the error log to HTTP responses
|
||||
--http-validate-host arg (=1) If set to false, then any incoming
|
||||
"Host" header is considered valid
|
||||
@@ -62,9 +66,6 @@ Config Options for eosio::http_plugin:
|
||||
by default.
|
||||
--http-threads arg (=2) Number of worker threads in http thread
|
||||
pool
|
||||
--http-keep-alive arg (=1) If set to false, do not keep HTTP
|
||||
connections alive, even if client
|
||||
requests.
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
@@ -11,7 +11,9 @@ For information on specific plugins, just select from the list below:
|
||||
* [`chain_api_plugin`](chain_api_plugin/index.md)
|
||||
* [`chain_plugin`](chain_plugin/index.md)
|
||||
* [`db_size_api_plugin`](db_size_api_plugin/index.md)
|
||||
* [`http_client_plugin`](http_client_plugin/index.md)
|
||||
* [`http_plugin`](http_plugin/index.md)
|
||||
* [`login_plugin`](login_plugin/index.md)
|
||||
* [`net_api_plugin`](net_api_plugin/index.md)
|
||||
* [`net_plugin`](net_plugin/index.md)
|
||||
* [`producer_plugin`](producer_plugin/index.md)
|
||||
@@ -19,6 +21,7 @@ For information on specific plugins, just select from the list below:
|
||||
* [`test_control_api_plugin`](test_control_api_plugin/index.md)
|
||||
* [`test_control_plugin`](test_control_plugin/index.md)
|
||||
* [`trace_api_plugin`](trace_api_plugin/index.md)
|
||||
* [`txn_test_gen_plugin`](txn_test_gen_plugin/index.md)
|
||||
|
||||
[[info | Nodeos is modular]]
|
||||
| Plugins add incremental functionality to `nodeos`. Unlike runtime plugins, `nodeos` plugins are built at compile-time.
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
## Description
|
||||
|
||||
The `login_plugin` supports the concept of applications authenticating with the Antelope blockchain. The `login_plugin` API allows an application to verify whether an account is allowed to sign in order to satisfy a specified authority.
|
||||
|
||||
## Usage
|
||||
|
||||
```console
|
||||
# config.ini
|
||||
plugin = eosio::login_plugin
|
||||
[options]
|
||||
```
|
||||
```sh
|
||||
# command-line
|
||||
nodeos ... --plugin eosio::login_plugin [options]
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
These can be specified from both the `nodeos` command-line or the `config.ini` file:
|
||||
|
||||
```console
|
||||
Config Options for eosio::login_plugin:
|
||||
--max-login-requests arg (=1000000) The maximum number of pending login
|
||||
requests
|
||||
--max-login-timeout arg (=60) The maximum timeout for pending login
|
||||
requests (in seconds)
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
* [`chain_plugin`](../chain_plugin/index.md)
|
||||
* [`http_plugin`](../http_plugin/index.md)
|
||||
|
||||
### Load Dependency Examples
|
||||
|
||||
```console
|
||||
# config.ini
|
||||
plugin = eosio::chain_plugin
|
||||
[options]
|
||||
plugin = eosio::http_plugin
|
||||
[options]
|
||||
```
|
||||
```sh
|
||||
# command-line
|
||||
nodeos ... --plugin eosio::chain_plugin [options] \
|
||||
--plugin eosio::http_plugin [options]
|
||||
```
|
||||
@@ -4,84 +4,87 @@ content_title: Block Production Explained
|
||||
|
||||
For simplicity of the explanation let's consider the following notations:
|
||||
|
||||
* `r` = `producer_repetitions = 12` (hard-coded value)
|
||||
* `m` = `max_block_cpu_usage` (on-chain consensus value)
|
||||
* `u` = `max_block_net_usage` (on-chain consensus value)
|
||||
* `t` = `block-time`
|
||||
* `e` = `produce-block-offset-ms` (nodeos configuration)
|
||||
* `w` = `block-time-interval = 500ms` (hard-coded value)
|
||||
* `a` = `produce-block-early-amount = w - (w - (e / r)) = e / r ms` (how much to release each block of round early by)
|
||||
* `l` = `produce-block-time = t - a`
|
||||
* `p` = `produce block time window = w - a` (amount of wall clock time to produce a block)
|
||||
* `c` = `billed_cpu_in_block = minimum(m, w - a)`
|
||||
* `n` = `network tcp/ip latency`
|
||||
* `h` = `block header validation time ms`
|
||||
m = max_block_cpu_usage
|
||||
|
||||
Peer validation for similar hardware/version/config will be <= `m`
|
||||
t = block-time
|
||||
|
||||
**Let's consider the example of the following two BPs and their network topology as depicted in the below diagram**
|
||||
e = last-block-cpu-effort-percent
|
||||
|
||||
```
|
||||
+------+ +------+ +------+ +------+
|
||||
-->| BP-A |---->| BP-A |------>| BP-B |---->| BP-B |
|
||||
+------+ | Peer | | Peer | +------+
|
||||
+------+ +------+
|
||||
w = block_time_interval = 500ms
|
||||
|
||||
a = produce-block-early-amount = (w - w*e/100) ms
|
||||
|
||||
p = produce-block-time; p = t - a
|
||||
|
||||
c = billed_cpu_in_block = minimum(m, w - a)
|
||||
|
||||
n = network tcp/ip latency
|
||||
|
||||
peer validation for similar hardware/eosio-version/config will be <= m
|
||||
|
||||
**Let's consider for exemplification the following four BPs and their network topology as depicted in below diagram**
|
||||
|
||||
|
||||
```dot-svg
|
||||
#p2p_local_chain_prunning.dot - local chain prunning
|
||||
#
|
||||
#notes: * to see image copy/paste to https://dreampuf.github.io/GraphvizOnline
|
||||
# * image will be rendered by gatsby-remark-graphviz plugin in eosio docs.
|
||||
|
||||
digraph {
|
||||
newrank=true #allows ranks inside subgraphs (important!)
|
||||
compound=true #allows edges connecting nodes with subgraphs
|
||||
graph [rankdir=LR]
|
||||
node [style=filled, fillcolor=lightgray, shape=square, fixedsize=true, width=.55, fontsize=10]
|
||||
edge [dir=both, arrowsize=.6, weight=100]
|
||||
splines=false
|
||||
|
||||
subgraph cluster_chain {
|
||||
label="Block Producers Peers"; labelloc="b"
|
||||
graph [color=invis]
|
||||
b0 [label="...", color=invis, style=""]
|
||||
b1 [label="BP-A"]; b2 [label="BP-A\nPeer"]; b3 [label="BP-B\nPeer"]; b4 [label="BP-B"]
|
||||
b5 [label="...", color=invis, style=""]
|
||||
b0 -> b1 -> b2 -> b3 -> b4 -> b5
|
||||
} //cluster_chain
|
||||
|
||||
} //digraph
|
||||
```
|
||||
|
||||
`BP-A` will send block at `l` and, `BP-B` needs block at time `t` or otherwise will drop it.
|
||||
`BP-A` will send block at `p` and,
|
||||
|
||||
`BP-B` needs block at time `t` or otherwise will drop it.
|
||||
|
||||
If `BP-A`is producing 12 blocks as follows `b(lock) at t(ime) 1`, `bt 1.5`, `bt 2`, `bt 2.5`, `bt 3`, `bt 3.5`, `bt 4`, `bt 4.5`, `bt 5`, `bt 5.5`, `bt 6`, `bt 6.5` then `BP-B` needs `bt 6.5` by time `6.5` so it has `.5` to produce `bt 7`.
|
||||
|
||||
Please notice that the time of `bt 7` minus `.5` equals the time of `bt 6.5` therefore time `t` is the last block time of `BP-A` and when `BP-B` needs to start its first block.
|
||||
|
||||
A block is produced and sent when either it reaches `m` or `u` or `p`.
|
||||
## Example 1
|
||||
`BP-A` has 50% e, m = 200ms, c = 200ms, n = 0ms, a = 250ms:
|
||||
`BP-A` sends at (t-250ms) <-> `BP-A-Peer` processes for 200ms and sends at (t - 50ms) <-> `BP-B-Peer` processes for 200ms and sends at (t + 150ms) <-> arrive at `BP-B` 150ms too late.
|
||||
|
||||
Starting in Leap 4.0, blocks are propagated after block header validation. This means instead of `BP-A Peer` & `BP-B Peer` taking `m` time to validate and forward a block it only takes a small number of milliseconds to verify the block header and then forward the block.
|
||||
## Example 2
|
||||
`BP-A` has 40% e and m = 200ms, c = 200ms, n = 0ms, a = 300ms:
|
||||
(t-300ms) <-> (+200ms) <-> (+200ms) <-> arrive at `BP-B` 100ms too late.
|
||||
|
||||
Starting in Leap 5.0, blocks in a round are started immediately after the completion of the previous block. Before 5.0, blocks were always started on `w` intervals and a node would "sleep" between blocks if needed. In 5.0, the "sleeps" are all moved to the end of the block production round.
|
||||
## Example 3
|
||||
`BP-A` has 30% e and m = 200ms, c = 150ms, n = 0ms, a = 350ms:
|
||||
(t-350ms) <-> (+150ms) <-> (+150ms) <-> arrive at `BP-B` with 50ms to spare.
|
||||
|
||||
## Example 1: block arrives 110ms early
|
||||
* Assuming zero network latency between all nodes.
|
||||
* Assuming blocks do not reach `m` and therefore take `w - a` time to produce.
|
||||
* Assume block completion including signing takes zero time.
|
||||
* `BP-A` has e = 120, n = 0ms, h = 5ms, a = 10ms
|
||||
* `BP-A` sends b1 at `t1-10ms` => `BP-A-Peer` processes `h=5ms`, sends at `t-5ms` => `BP-B-Peer` processes `h=5ms`, sends at `t-0ms` => arrives at `BP-B` at `t`.
|
||||
* `BP-A` starts b2 at `t1-10ms`, sends b2 at `t2-20ms` => `BP-A-Peer` processes `h=5ms`, sends at `t2-15ms` => `BP-B-Peer` processes `h=5ms`, sends at `t2-10ms` => arrives at `BP-B` at `t2-10ms`.
|
||||
* `BP-A` starts b3 at `t2-20ms`, ...
|
||||
* `BP-A` starts b12 at `t11-110ms`, sends b12 at `t12-120ms` => `BP-A-Peer` processes `h=5ms`, sends at `t12-115ms` => `BP-B-Peer` processes `h=5ms`, sends at `t12-110ms` => arrives at `BP-B` at `t12-110ms`
|
||||
## Example 4
|
||||
`BP-A` has 25% e and m = 200ms, c = 125ms, n = 0ms, a = 375ms:
|
||||
(t-375ms) <-> (+125ms) <-> (+125ms) <-> arrive at `BP-B` with 125ms to spare.
|
||||
|
||||
## Example 2: block arrives 80ms early
|
||||
* Assuming zero network latency between `BP-A` & `BP-A Peer` and between `BP-B Peer` & `BP-B`.
|
||||
* Assuming 150ms network latency between `BP-A Peer` & `BP-B Peer`.
|
||||
* Assuming blocks do not reach `m` and therefore take `w - a` time to produce.
|
||||
* Assume block completion including signing takes zero time.
|
||||
* `BP-A` has e = 240, n = 0ms/150ms, h = 5ms, a = 20ms
|
||||
* `BP-A` sends b1 at `t1-20ms` => `BP-A-Peer` processes `h=5ms`, sends at `t-15ms` =(150ms)> `BP-B-Peer` processes `h=5ms`, sends at `t+140ms` => arrives at `BP-B` at `t+140ms`.
|
||||
* `BP-A` starts b2 at `t1-20ms`, sends b2 at `t2-40ms` => `BP-A-Peer` processes `h=5ms`, sends at `t2-35ms` =(150ms)> `BP-B-Peer` processes `h=5ms`, sends at `t2+120ms` => arrives at `BP-B` at `t2+120ms`.
|
||||
* `BP-A` starts b3 at `t2-40ms`, ...
|
||||
* `BP-A` starts b12 at `t11-220ms`, sends b12 at `t12-240ms` => `BP-A-Peer` processes `h=5ms`, sends at `t12-235ms` =(150ms)> `BP-B-Peer` processes `h=5ms`, sends at `t12-80ms` => arrives at `BP-B` at `t12-80ms`
|
||||
## Example 5
|
||||
`BP-A` has 10% e and m = 200ms, c = 50ms, n = 0ms, a = 450ms:
|
||||
(t-450ms) <-> (+50ms) <-> (+50ms) <-> arrive at `BP-B` with 350ms to spare.
|
||||
|
||||
## Example 3: block arrives 16ms late and is dropped
|
||||
* Assuming zero network latency between `BP-A` & `BP-A Peer` and between `BP-B Peer` & `BP-B`.
|
||||
* Assuming 200ms network latency between `BP-A Peer` & `BP-B Peer`.
|
||||
* Assuming blocks do not reach `m` and therefore take `w - a` time to produce.
|
||||
* Assume block completion including signing takes zero time.
|
||||
* `BP-A` has e = 204, n = 0ms/200ms, h = 10ms, a = 17ms
|
||||
* `BP-A` sends b1 at `t1-17ms` => `BP-A-Peer` processes `h=10ms`, sends at `t-7ms` =(200ms)> `BP-B-Peer` processes `h=10ms`, sends at `t+203ms` => arrives at `BP-B` at `t+203ms`.
|
||||
* `BP-A` starts b2 at `t1-17ms`, sends b2 at `t2-34ms` => `BP-A-Peer` processes `h=10ms`, sends at `t2-24ms` =(200ms)> `BP-B-Peer` processes `h=10ms`, sends at `t2+186ms` => arrives at `BP-B` at `t2+186ms`.
|
||||
* `BP-A` starts b3 at `t2-34ms`, ...
|
||||
* `BP-A` starts b12 at `t11-187ms`, sends b12 at `t12-204ms` => `BP-A-Peer` processes `h=10ms`, sends at `t12-194ms` =(200ms)> `BP-B-Peer` processes `h=10ms`, sends at `t12+16ms` => arrives at `BP-B` at `t12+16ms`
|
||||
|
||||
## Example 4: full blocks are produced early
|
||||
* Assuming zero network latency between `BP-A` & `BP-A Peer` and between `BP-B Peer` & `BP-B`.
|
||||
* Assuming 200ms network latency between `BP-A Peer` & `BP-B Peer`.
|
||||
* Assume all blocks are full as there are enough queued up unapplied transactions ready to fill all blocks.
|
||||
* Assume a block can be produced with 200ms worth of transactions in 225ms worth of time. There is overhead for producing the block.
|
||||
* `BP-A` has e = 120, m = 200ms, n = 0ms/200ms, h = 10ms, a = 10ms
|
||||
* `BP-A` sends b1 at `t1-275s` => `BP-A-Peer` processes `h=10ms`, sends at `t-265ms` =(200ms)> `BP-B-Peer` processes `h=10ms`, sends at `t-55ms` => arrives at `BP-B` at `t-55ms`.
|
||||
* `BP-A` starts b2 at `t1-275ms`, sends b2 at `t2-550ms (t1-50ms)` => `BP-A-Peer` processes `h=10ms`, sends at `t2-540ms` =(200ms)> `BP-B-Peer` processes `h=10ms`, sends at `t2-330ms` => arrives at `BP-B` at `t2-330ms`.
|
||||
* `BP-A` starts b3 at `t2-550ms`, ...
|
||||
* `BP-A` starts b12 at `t11-3025ms`, sends b12 at `t12-3300ms` => `BP-A-Peer` processes `h=10ms`, sends at `t12-3290ms` =(200ms)> `BP-B-Peer` processes `h=10ms`, sends at `t12-3080ms` => arrives at `BP-B` at `t12-3080ms`
|
||||
## Example 6
|
||||
`BP-A` has 10% e and m = 200ms, c = 50ms, n = 15ms, a = 450ms:
|
||||
(t-450ms) <- +15ms -> (+50ms) <- +15ms -> (+50ms) <- +15ms -> `BP-B` <-> arrive with 305ms to spare.
|
||||
|
||||
## Example 7
|
||||
Example world-wide network:`BP-A`has 10% e and m = 200ms, c = 50ms, n = 15ms/250ms, a = 450ms:
|
||||
(t-450ms) <- +15ms -> (+50ms) <- +250ms -> (+50ms) <- +15ms -> `BP-B` <-> arrive with 70ms to spare.
|
||||
|
||||
Running wasm-runtime=eos-vm-jit eos-vm-oc-enable on relay node will reduce the validation time.
|
||||
|
||||
@@ -27,11 +27,10 @@ Config Options for eosio::producer_plugin:
|
||||
chain is stale.
|
||||
-x [ --pause-on-startup ] Start this node in a state where
|
||||
production is paused
|
||||
--max-transaction-time arg (=499) Setting this value (in milliseconds)
|
||||
will restrict the allowed transaction
|
||||
execution time to a value potentially
|
||||
lower than the on-chain consensus
|
||||
max_transaction_cpu_usage value.
|
||||
--max-transaction-time arg (=30) Limits the maximum time (in
|
||||
milliseconds) that is allowed a pushed
|
||||
transaction's code to execute before
|
||||
being considered invalid
|
||||
--max-irreversible-block-age arg (=-1)
|
||||
Limits the maximum age (in seconds) of
|
||||
the DPOS Irreversible Block for a chain
|
||||
@@ -40,6 +39,10 @@ Config Options for eosio::producer_plugin:
|
||||
-p [ --producer-name ] arg ID of producer controlled by this node
|
||||
(e.g. inita; may specify multiple
|
||||
times)
|
||||
--private-key arg (DEPRECATED - Use signature-provider
|
||||
instead) Tuple of [public key, WIF
|
||||
private key] (may specify multiple
|
||||
times)
|
||||
--signature-provider arg (=EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV=KEY:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3)
|
||||
Key=Value pairs in the form
|
||||
<public-key>=<provider-spec>
|
||||
@@ -52,7 +55,7 @@ Config Options for eosio::producer_plugin:
|
||||
form <provider-type>
|
||||
:<data>
|
||||
|
||||
<provider-type> is KEY, KEOSD, or SE
|
||||
<provider-type> is KEY, or KEOSD
|
||||
|
||||
KEY:<data> is a string form of
|
||||
a valid EOS
|
||||
@@ -65,6 +68,10 @@ Config Options for eosio::producer_plugin:
|
||||
and the approptiate
|
||||
wallet(s) are
|
||||
unlocked
|
||||
--keosd-provider-timeout arg (=5) Limits the maximum time (in
|
||||
milliseconds) that is allowed for
|
||||
sending blocks to a keosd provider for
|
||||
signing
|
||||
--greylist-account arg account that can not access to extended
|
||||
CPU/NET virtual resources
|
||||
--greylist-limit arg (=1000) Limit (between 1 and 1000) on the
|
||||
@@ -72,9 +79,20 @@ Config Options for eosio::producer_plugin:
|
||||
can extend during low usage (only
|
||||
enforced subjectively; use 1000 to not
|
||||
enforce any limit)
|
||||
--produce-block-offset-ms arg (=450) The minimum time to reserve at the end
|
||||
of a production round for blocks to
|
||||
propagate to the next block producer.
|
||||
--produce-time-offset-us arg (=0) Offset of non last block producing time
|
||||
in microseconds. Valid range 0 ..
|
||||
-block_time_interval.
|
||||
--last-block-time-offset-us arg (=-200000)
|
||||
Offset of last block producing time in
|
||||
microseconds. Valid range 0 ..
|
||||
-block_time_interval.
|
||||
--cpu-effort-percent arg (=80) Percentage of cpu block production time
|
||||
used to produce block. Whole number
|
||||
percentages, e.g. 80 for 80%
|
||||
--last-block-cpu-effort-percent arg (=80)
|
||||
Percentage of cpu block production time
|
||||
used to produce last block. Whole
|
||||
number percentages, e.g. 80 for 80%
|
||||
--max-block-cpu-usage-threshold-us arg (=5000)
|
||||
Threshold of CPU block production to
|
||||
consider block full; when within
|
||||
@@ -85,6 +103,12 @@ Config Options for eosio::producer_plugin:
|
||||
consider block full; when within
|
||||
threshold of max-block-net-usage block
|
||||
can be produced immediately
|
||||
--max-scheduled-transaction-time-per-block-ms arg (=100)
|
||||
Maximum wall-clock time, in
|
||||
milliseconds, spent retiring scheduled
|
||||
transactions in any block before
|
||||
returning to normal transaction
|
||||
processing.
|
||||
--subjective-cpu-leeway-us arg (=31000)
|
||||
Time in microseconds allowed for a
|
||||
transaction that starts with
|
||||
@@ -97,11 +121,18 @@ Config Options for eosio::producer_plugin:
|
||||
--subjective-account-decay-time-minutes arg (=1440)
|
||||
Sets the time to return full subjective
|
||||
cpu for accounts
|
||||
--incoming-defer-ratio arg (=1) ratio between incoming transactions and
|
||||
deferred transactions when both are
|
||||
queued for execution
|
||||
--incoming-transaction-queue-size-mb arg (=1024)
|
||||
Maximum size (in MiB) of the incoming
|
||||
transaction queue. Exceeding this value
|
||||
will subjectively drop transaction with
|
||||
resource exhaustion.
|
||||
--disable-api-persisted-trx Disable the re-apply of API
|
||||
transactions.
|
||||
--disable-subjective-billing arg (=1) Disable subjective CPU billing for
|
||||
API/P2P transactions
|
||||
--disable-subjective-account-billing arg
|
||||
Account which is excluded from
|
||||
subjective CPU billing
|
||||
@@ -111,6 +142,8 @@ Config Options for eosio::producer_plugin:
|
||||
--disable-subjective-api-billing arg (=1)
|
||||
Disable subjective CPU billing for API
|
||||
transactions
|
||||
--producer-threads arg (=2) Number of worker threads in producer
|
||||
thread pool
|
||||
--snapshots-dir arg (="snapshots") the location of the snapshots directory
|
||||
(absolute path or relative to
|
||||
application data dir)
|
||||
@@ -120,6 +153,21 @@ Config Options for eosio::producer_plugin:
|
||||
|
||||
* [`chain_plugin`](../chain_plugin/index.md)
|
||||
|
||||
## The priority of transaction
|
||||
|
||||
You can give one of the transaction types priority over another when the producer plugin has a queue of transactions pending.
|
||||
|
||||
The option below sets the ratio between the incoming transaction and the deferred transaction:
|
||||
|
||||
```console
|
||||
--incoming-defer-ratio arg (=1)
|
||||
```
|
||||
|
||||
By default value of `1`, the `producer` plugin processes one incoming transaction per deferred transaction. When `arg` sets to `10`, the `producer` plugin processes 10 incoming transactions per deferred transaction.
|
||||
|
||||
If the `arg` is set to a sufficiently large number, the plugin always processes the incoming transaction first until the queue of the incoming transactions is empty. Respectively, if the `arg` is 0, the `producer` plugin processes the deferred transactions queue first.
|
||||
|
||||
|
||||
### Load Dependency Examples
|
||||
|
||||
```console
|
||||
|
||||
@@ -42,15 +42,29 @@ Config Options for eosio::state_history_plugin:
|
||||
incoming connections. Caution: only
|
||||
expose this port to your internal
|
||||
network.
|
||||
--state-history-unix-socket-path arg the path (relative to data-dir) to
|
||||
create a unix socket upon which to
|
||||
listen for incoming connections.
|
||||
--trace-history-debug-mode enable debug mode for trace history
|
||||
--state-history-log-retain-blocks arg if set, periodically prune the state
|
||||
history files to store only configured
|
||||
number of most recent blocks
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
## Dependencies
|
||||
|
||||
* [`chain_plugin`](../chain_plugin/index.md)
|
||||
|
||||
### Load Dependency Examples
|
||||
|
||||
```console
|
||||
# config.ini
|
||||
plugin = eosio::chain_plugin --disable-replay-opts
|
||||
```
|
||||
```sh
|
||||
# command-line
|
||||
nodeos ... --plugin eosio::chain_plugin --disable-replay-opts
|
||||
```
|
||||
|
||||
## How-To Guides
|
||||
|
||||
* [How to fast start without history on existing chains](10_how-to-fast-start-without-old-history.md)
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
## Description
|
||||
|
||||
The `txn_test_gen_plugin` is used for transaction test purposes.
|
||||
|
||||
[[info | For More Information]]
|
||||
For more information, check the [txn_test_gen_plugin/README.md](https://github.com/AntelopeIO/leap/tree/main/plugins/txn_test_gen_plugin) on the `AntelopeIO/leap` repository.
|
||||
|
||||
## Usage
|
||||
|
||||
```console
|
||||
# config.ini
|
||||
plugin = eosio::txn_test_gen_plugin
|
||||
[options]
|
||||
```
|
||||
```sh
|
||||
# command-line
|
||||
nodeos ... --plugin eosio::txn_test_gen_plugin [options]
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
These can be specified from both the `nodeos` command-line or the `config.ini` file:
|
||||
|
||||
```console
|
||||
Config Options for eosio::txn_test_gen_plugin:
|
||||
--txn-reference-block-lag arg (=0) Lag in number of blocks from the head
|
||||
block when selecting the reference
|
||||
block for transactions (-1 means Last
|
||||
Irreversible Block)
|
||||
--txn-test-gen-threads arg (=2) Number of worker threads in
|
||||
txn_test_gen thread pool
|
||||
--txn-test-gen-account-prefix arg (=txn.test.)
|
||||
Prefix to use for accounts generated
|
||||
and used by this plugin
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
None
|
||||
@@ -64,24 +64,3 @@ Sample `logging.json`:
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Expected Output of Log Levels
|
||||
|
||||
* `error` - Log output that likely requires operator intervention.
|
||||
- Error level logging should be reserved for conditions that are completely unexpected or otherwise need human intervention.
|
||||
- Also used to indicate software errors such as: impossible values for an `enum`, out of bounds array access, null pointers, or other conditions that likely will throw an exception.
|
||||
- *Note*: Currently, there are numerous `error` level logging that likely should be `warn` as they do not require human intervention. The `net_plugin_impl`, for example, has a number of `error` level logs for bad network connections. This is handled and processed correctly. These should be changed to `warn` or `info`.
|
||||
* `warn` - Log output indicating unexpected but recoverable errors.
|
||||
- Although, `warn` level typically does not require human intervention, repeated output of `warn` level logs might indicate actions needed by an operator.
|
||||
- `warn` should not be used simply for conveying information. A `warn` level log is something to take notice of, but not necessarily be concerned about.
|
||||
* `info` (default) - Log output that provides useful information to an operator.
|
||||
- Can be just progress indication or other useful data to a user. Care is taken not to create excessive log output with `info` level logging. For example, no `info` level logging should be produced for every transaction.
|
||||
- For progress indication, some multiple of transactions should be processed between each log output; typically, every 1000 transactions.
|
||||
* `debug` - Useful log output for when non-default logging is enabled.
|
||||
- Answers the question: is this useful information for a user that is monitoring the log output. Care should be taken not to create excessive log output; similar to `info` level logging.
|
||||
- Enabling `debug` level logging should provide greater insight into behavior without overwhelming the output with log entries.
|
||||
- `debug` level should not be used for *trace* level logging; to that end, use `all` (see below).
|
||||
- Like `info`, no `debug` level logging should be produced for every transaction. There are specific transaction level loggers dedicated to transaction level logging: `transaction`, `transaction_trace_failure`, `transaction_trace_success`, `transaction_failure_tracing`, `transaction_success_tracing`, `transient_trx_success_tracing`, `transient_trx_failure_tracing`.
|
||||
* `all` (trace) - For logging that would be overwhelming if `debug` level logging were used.
|
||||
- Can be used for trace level logging. Only used in a few places and not completely supported.
|
||||
- *Note*: In the future a different logging library may provide better trace level logging support. The current logging framework is not performant enough to enable excess trace level output.
|
||||
|
||||
@@ -27,34 +27,44 @@ The `nodeos` service provides query access to the chain database via the HTTP [R
|
||||
|
||||
The `nodeos` service can be run in different "read" modes. These modes control how the node operates and how it processes blocks and transactions:
|
||||
|
||||
- `head`: this only includes the side effects of confirmed transactions, this mode processes unconfirmed transactions but does not include them.
|
||||
- `irreversible`: this mode also includes confirmed transactions only up to those included in the last irreversible block.
|
||||
- `speculative`: this includes the side effects of confirmed and unconfirmed transactions.
|
||||
- `head`: this only includes the side effects of confirmed transactions, this mode processes unconfirmed transactions but does not include them.
|
||||
- `read-only`: this mode is deprecated. Similar functionality can be achieved by combining options: `read-mode = head`, `p2p-accept-transactions = false`, `api-accept-transactions = false`. When these options are set, the local database will contain state changes made by transactions in the chain up to the head block. Also, transactions received via the P2P network are not relayed and transactions cannot be pushed via the chain API.
|
||||
- `irreversible`: this mode also includes confirmed transactions only up to those included in the last irreversible block.
|
||||
|
||||
A transaction is considered confirmed when a `nodeos` instance has received, processed, and written it to a block on the blockchain, i.e. it is in the head block or an earlier block.
|
||||
|
||||
### Speculative Mode
|
||||
|
||||
Clients such as `cleos` and the RPC API, will see database state as of the current head block plus changes made by all transactions known to this node but potentially not included in the chain, unconfirmed transactions for example.
|
||||
|
||||
Speculative mode is low latency but fragile, there is no guarantee that the transactions reflected in the state will be included in the chain OR that they will reflected in the same order the state implies.
|
||||
|
||||
This mode features the lowest latency, but is the least consistent.
|
||||
|
||||
In speculative mode `nodeos` is able to execute transactions which have TaPoS (Transaction as Proof of Stake) pointing to any valid block in a fork considered to be the best fork by this node.
|
||||
|
||||
### Head Mode
|
||||
|
||||
Clients such as `cleos` and the RPC API will see database state as of the current head block of the chain. Since current head block is not yet irreversible and short-lived forks are possible, state read in this mode may become inaccurate if `nodeos` switches to a better fork.
|
||||
Clients such as `cleos` and the RPC API will see database state as of the current head block of the chain. Since current head block is not yet irreversible and short-lived forks are possible, state read in this mode may become inaccurate if `nodeos` switches to a better fork. Note that this is also true of speculative mode.
|
||||
|
||||
This mode represents a good trade-off between highly consistent views of the data and latency.
|
||||
|
||||
In this mode `nodeos` is able to execute transactions which have TaPoS pointing to any valid block in a fork considered to be the best fork by this node.
|
||||
|
||||
### Read-Only Mode
|
||||
|
||||
[[caution | Deprecation Notice]]
|
||||
| The explicit `read-mode = read-only` mode is deprecated. Similar functionality can now be achieved in `head` mode by combining options: `read-mode = head`, `p2p-accept-transactions = false`, `api-accept-transactions = false`.
|
||||
|
||||
Clients such as `cleos` and the RPC API will see database state as of the current head block of the chain. It **will not** include changes made by transactions known to this node but not included in the chain, such as unconfirmed transactions.
|
||||
|
||||
### Irreversible Mode
|
||||
|
||||
When `nodeos` is configured to be in irreversible read mode, it will still track the most up-to-date blocks in the fork database, but the state will lag behind the current best head block, sometimes referred to as the fork DB head, to always reflect the state of the last irreversible block.
|
||||
|
||||
Clients such as `cleos` and the RPC API will see database state as of the current head block of the chain. It **will not** include changes made by transactions known to this node but not included in the chain, such as unconfirmed transactions.
|
||||
|
||||
### Speculative Mode ( Deprecated )
|
||||
|
||||
Clients such as `cleos` and the RPC API, will see database state as of the current head block plus changes made by all transactions known to this node but potentially not included in the chain, unconfirmed transactions for example.
|
||||
|
||||
Speculative mode is low latency but fragile, there is no guarantee that the transactions reflected in the state will be included in the chain OR that they will reflected in the same order the state implies.
|
||||
|
||||
This mode features the lowest latency, but is the least consistent.
|
||||
|
||||
In speculative mode `nodeos` is able to execute transactions which have TaPoS (Transaction as Proof of Stake) pointing to any valid block in a fork considered to be the best fork by this node.
|
||||
|
||||
## How To Specify the Read Mode
|
||||
|
||||
The mode in which `nodeos` is run can be specified using the `--read-mode` option from the `eosio::chain_plugin`.
|
||||
|
||||
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user