Compare commits

..

3 Commits

Author SHA1 Message Date
Lin Huang 95077ed429 Bump Leap to release/3.1.5 2023-07-12 09:25:47 -04:00
Lin Huang 05e6cc8c18 Update eos-vm to release/3.x 2023-07-12 09:25:10 -04:00
Lin Huang 5caf5833ad A companion Leap changes for fixing WASM memory exhaustion 2023-07-12 09:18:25 -04:00
1780 changed files with 37381 additions and 109199 deletions
-128
View File
@@ -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/ /
+11
View File
@@ -0,0 +1,11 @@
{
"ubuntu18": {
"dockerfile": ".cicd/platforms/ubuntu18.Dockerfile"
},
"ubuntu20": {
"dockerfile": ".cicd/platforms/ubuntu20.Dockerfile"
},
"ubuntu22": {
"dockerfile": ".cicd/platforms/ubuntu22.Dockerfile"
}
}
+38
View File
@@ -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/
+17
View File
@@ -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
+17
View File
@@ -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
-19
View File
@@ -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
+201
View File
@@ -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
-150
View File
@@ -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"
-18
View File
@@ -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 }}"}'
+58
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
-52
View File
@@ -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
View File
@@ -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)
View File
View File
View File
+72 -72
View File
@@ -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()
+78 -81
View File
@@ -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
-9
View File
@@ -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
-5
View File
@@ -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:
+144 -341
View File
@@ -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) по возможным местам установки.
-8
View File
@@ -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"
)
-112
View File
@@ -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
-85
View File
@@ -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
-27
View File
@@ -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
-21
View File
@@ -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
-444
View File
@@ -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
-89
View File
@@ -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
-109
View File
@@ -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
-80
View File
@@ -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;
}
-72
View File
@@ -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).
+1
View File
@@ -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:
+39 -51
View File
@@ -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)
+13 -12
View File
@@ -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
+3
View File
@@ -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`.
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File

Some files were not shown because too many files have changed in this diff Show More