1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

Merged master into func-unused

This commit is contained in:
Skydev0h 2024-05-24 03:19:01 +03:00
commit fa2aa90dfc
1784 changed files with 161530 additions and 20820 deletions

View file

@ -1,5 +1,5 @@
-xc++
-std=c++14
-std=c++17
-iquote .
-iquote tdtl/
-iquote tl/

8
.editorconfig Normal file
View file

@ -0,0 +1,8 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
indent_style = space
indent_size = 2

13
.github/ISSUE_TEMPLATE.md vendored Normal file
View file

@ -0,0 +1,13 @@
<!-- Describe the issue -->
<!--- What behavior did you expect? -->
<!--- What was the actual behavior? -->
<!--- How reliably can you reproduce the issue, what are the steps to do so? -->
<!-- What version of TON are you using, where did you get it (github actions, self-compiled, etc)? -->
<!-- What type of machine are you observing the error on (OS/CPU and disk type)? -->
<!-- Any extra information that might be useful in the debugging process. -->
<!--- This is normally the contents of a `debug.log` or `config.log` file. Raw text or a link to a pastebin type site are preferred. -->

20
.github/script/amd64-20.04.Dockerfile vendored Normal file
View file

@ -0,0 +1,20 @@
FROM ubuntu:20.04
RUN apt update
RUN DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install tzdata
RUN apt install -y build-essential cmake clang openssl libssl-dev zlib1g-dev gperf wget git curl libreadline-dev ccache libmicrohttpd-dev ninja-build libsecp256k1-dev libsodium-dev pkg-config
WORKDIR /
ARG BRANCH
ARG REPO
RUN git clone --recurse-submodules https://github.com/$REPO ton && cd ton && git checkout $BRANCH && git submodule update
WORKDIR /ton
RUN mkdir /ton/build
WORKDIR /ton/build
ENV CC clang
ENV CXX clang++
ENV CCACHE_DISABLE 1
RUN cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DPORTABLE=1 -DTON_ARCH= -DCMAKE_CXX_FLAGS="-mavx2" ..
RUN ninja storage-daemon storage-daemon-cli tonlibjson blockchain-explorer fift func validator-engine validator-engine-console create-state generate-random-id create-hardfork dht-server lite-client

20
.github/script/amd64-22.04.Dockerfile vendored Normal file
View file

@ -0,0 +1,20 @@
FROM ubuntu:22.04
RUN apt update
RUN DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install tzdata
RUN apt install -y build-essential cmake clang openssl libssl-dev zlib1g-dev gperf wget git curl libreadline-dev ccache libmicrohttpd-dev ninja-build libsecp256k1-dev libsodium-dev pkg-config
WORKDIR /
ARG BRANCH
ARG REPO
RUN git clone --recurse-submodules https://github.com/$REPO ton && cd ton && git checkout $BRANCH && git submodule update
WORKDIR /ton
RUN mkdir /ton/build
WORKDIR /ton/build
ENV CC clang
ENV CXX clang++
ENV CCACHE_DISABLE 1
RUN cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DPORTABLE=1 -DTON_ARCH= -DCMAKE_CXX_FLAGS="-mavx2" ..
RUN ninja storage-daemon storage-daemon-cli tonlibjson blockchain-explorer fift func validator-engine validator-engine-console create-state generate-random-id create-hardfork dht-server lite-client

20
.github/script/arm64-20.04.Dockerfile vendored Normal file
View file

@ -0,0 +1,20 @@
FROM ubuntu:20.04
RUN apt update
RUN DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install tzdata
RUN apt install -y build-essential cmake clang openssl libssl-dev zlib1g-dev gperf wget git curl libreadline-dev ccache libmicrohttpd-dev ninja-build libsecp256k1-dev libsodium-dev pkg-config
WORKDIR /
ARG BRANCH
ARG REPO
RUN git clone --recurse-submodules https://github.com/$REPO ton && cd ton && git checkout $BRANCH && git submodule update
WORKDIR /ton
RUN mkdir /ton/build
WORKDIR /ton/build
ENV CC clang
ENV CXX clang++
ENV CCACHE_DISABLE 1
RUN cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DPORTABLE=1 -DTON_ARCH= ..
RUN ninja storage-daemon storage-daemon-cli tonlibjson blockchain-explorer fift func validator-engine validator-engine-console create-state generate-random-id dht-server lite-client

20
.github/script/arm64-22.04.Dockerfile vendored Normal file
View file

@ -0,0 +1,20 @@
FROM ubuntu:22.04
RUN apt update
RUN DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install tzdata
RUN apt install -y build-essential cmake clang openssl libssl-dev zlib1g-dev gperf wget git curl libreadline-dev ccache libmicrohttpd-dev ninja-build libsecp256k1-dev libsodium-dev pkg-config
WORKDIR /
ARG BRANCH
ARG REPO
RUN git clone --recurse-submodules https://github.com/$REPO ton && cd ton && git checkout $BRANCH && git submodule update
WORKDIR /ton
RUN mkdir /ton/build
WORKDIR /ton/build
ENV CC clang
ENV CXX clang++
ENV CCACHE_DISABLE 1
RUN cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DPORTABLE=1 -DTON_ARCH= ..
RUN ninja storage-daemon storage-daemon-cli tonlibjson blockchain-explorer fift func validator-engine validator-engine-console create-state generate-random-id dht-server lite-client

View file

@ -0,0 +1,32 @@
name: Tonlib Android
on: [push,workflow_dispatch,workflow_call]
jobs:
build:
runs-on: ubuntu-22.04
steps:
- name: Check out repository
uses: actions/checkout@v3
with:
submodules: 'recursive'
- name: Install system libraries
run: |
sudo apt-get update
sudo apt-get install -y build-essential git cmake ninja-build automake libtool texinfo autoconf libgflags-dev \
zlib1g-dev libssl-dev libreadline-dev libmicrohttpd-dev pkg-config libgsl-dev python3 python3-dev \
libtool autoconf libsodium-dev libsecp256k1-dev liblz4-dev
- name: Build TON
run: |
cp assembly/android/build-android-tonlib.sh .
chmod +x build-android-tonlib.sh
./build-android-tonlib.sh -a
- name: Upload artifacts
uses: actions/upload-artifact@master
with:
name: tonlib-android
path: artifacts

View file

@ -0,0 +1,40 @@
name: Ubuntu TON build (shared, x86-64)
on: [push,workflow_dispatch,workflow_call]
jobs:
build:
strategy:
fail-fast: false
matrix:
os: [ubuntu-20.04, ubuntu-22.04]
runs-on: ${{ matrix.os }}
steps:
- name: Check out repository
uses: actions/checkout@v3
with:
submodules: 'recursive'
- name: Install system libraries
run: |
sudo apt-get update
sudo apt-get install -y build-essential git cmake ninja-build zlib1g-dev libsecp256k1-dev libmicrohttpd-dev libsodium-dev liblz4-dev
- name: Install clang-16
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 16 all
- name: Build TON
run: |
cp assembly/native/build-ubuntu-shared.sh .
chmod +x build-ubuntu-shared.sh
./build-ubuntu-shared.sh -t -a
- name: Upload artifacts
uses: actions/upload-artifact@master
with:
name: ton-binaries-${{ matrix.os }}
path: artifacts

View file

@ -0,0 +1,25 @@
name: MacOS TON build (shared, x86-64)
on: [push,workflow_dispatch,workflow_call]
jobs:
build:
runs-on: macos-12
steps:
- name: Check out repository
uses: actions/checkout@v3
with:
submodules: 'recursive'
- name: Build TON
run: |
cp assembly/native/build-macos-shared.sh .
chmod +x build-macos-shared.sh
./build-macos-shared.sh -t -a
- name: Upload artifacts
uses: actions/upload-artifact@master
with:
name: ton-binaries-macos-12
path: artifacts

View file

@ -0,0 +1,30 @@
name: Emscripten TON build (wasm)
on: [push,workflow_dispatch,workflow_call]
jobs:
build:
runs-on: ubuntu-22.04
steps:
- name: Check out repository
uses: actions/checkout@v3
with:
submodules: 'recursive'
- name: Install system libraries
run: |
sudo apt-get update
sudo apt-get install -y build-essential git openssl cmake ninja-build zlib1g-dev libssl-dev libsecp256k1-dev libmicrohttpd-dev libsodium-dev liblz4-dev
- name: Build TON WASM artifacts
run: |
cd assembly/wasm
chmod +x fift-func-wasm-build-ubuntu.sh
./fift-func-wasm-build-ubuntu.sh -a
- name: Upload artifacts
uses: actions/upload-artifact@master
with:
name: ton-wasm-binaries
path: artifacts

396
.github/workflows/create-release.yml vendored Normal file
View file

@ -0,0 +1,396 @@
name: Create release
on: [workflow_dispatch]
permissions: write-all
jobs:
create-release:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Download Linux x86-64 artifacts
uses: dawidd6/action-download-artifact@v2
with:
workflow: ton-x86-64-linux.yml
path: artifacts
workflow_conclusion: success
skip_unpack: true
- name: Download and unzip Linux x86-64 artifacts
uses: dawidd6/action-download-artifact@v2
with:
workflow: ton-x86-64-linux.yml
path: artifacts
workflow_conclusion: success
skip_unpack: false
- name: Download Mac x86-64 artifacts
uses: dawidd6/action-download-artifact@v2
with:
workflow: ton-x86-64-macos.yml
path: artifacts
workflow_conclusion: success
skip_unpack: true
- name: Download and unzip Mac x86-64 artifacts
uses: dawidd6/action-download-artifact@v2
with:
workflow: ton-x86-64-macos.yml
path: artifacts
workflow_conclusion: success
skip_unpack: false
- name: Download Windows artifacts
uses: dawidd6/action-download-artifact@v2
with:
workflow: ton-x86-64-windows.yml
path: artifacts
workflow_conclusion: success
skip_unpack: true
- name: Download and unzip Windows artifacts
uses: dawidd6/action-download-artifact@v2
with:
workflow: ton-x86-64-windows.yml
path: artifacts
workflow_conclusion: success
skip_unpack: false
- name: Download WASM artifacts
uses: dawidd6/action-download-artifact@v2
with:
workflow: build-ton-wasm-emscripten.yml
path: artifacts
workflow_conclusion: success
skip_unpack: true
- name: Show all artifacts
run: |
tree artifacts
# create release
- name: Read Changelog.md and use it as a body of new release
id: read_release
shell: bash
run: |
r=$(cat recent_changelog.md)
r="${r//'%'/'%25'}"
r="${r//$'\n'/'%0A'}"
r="${r//$'\r'/'%0D'}"
echo "::set-output name=CHANGELOG_BODY::$r"
- name: Get next tag
id: tag
run: |
git fetch --all --tags
git tag -l
NEW_TAG=v$(date +'%Y.%m')
FOUND=$(git tag -l | grep $NEW_TAG | wc -l)
if [ $FOUND -eq 0 ]; then
echo "TAG=$NEW_TAG" >> $GITHUB_OUTPUT
else
echo "TAG=$NEW_TAG-$FOUND" >> $GITHUB_OUTPUT
fi
- name: Get registration token
id: getRegToken
run: |
curl -X POST -H \"Accept: application/vnd.github+json\" -H 'Authorization: token ${{ secrets.GITHUB_TOKEN }}' https://api.github.com/repos/ton-blockchain/ton/actions/runners/registration-token
- name: Create release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.tag.outputs.TAG }}
release_name: TON ${{ steps.tag.outputs.TAG }}
body: |
${{ steps.read_release.outputs.CHANGELOG_BODY }}
draft: false
prerelease: false
# upload
# win
- name: Upload Windows 2019 artifacts
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-win-binaries.zip
asset_name: ton-win-x86-64.zip
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Windows 2019 single artifact - fift
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-win-binaries/fift.exe
asset_name: fift.exe
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Windows 2019 single artifact - func
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-win-binaries/func.exe
asset_name: func.exe
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Windows 2019 single artifact - lite-client
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-win-binaries/lite-client.exe
asset_name: lite-client.exe
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Windows 2019 single artifact - rldp-http-proxy
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-win-binaries/rldp-http-proxy.exe
asset_name: rldp-http-proxy.exe
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Windows 2019 single artifact - http-proxy
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-win-binaries/http-proxy.exe
asset_name: http-proxy.exe
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Windows 2019 single artifact - storage-daemon-cli
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-win-binaries/storage-daemon-cli.exe
asset_name: storage-daemon-cli.exe
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Windows 2019 single artifact - storage-daemon
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-win-binaries/storage-daemon.exe
asset_name: storage-daemon.exe
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Windows 2019 single artifact - tonlibjson
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-win-binaries/tonlibjson.dll
asset_name: tonlibjson.dll
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Windows 2019 single artifact - libemulator
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-win-binaries/emulator.dll
asset_name: libemulator.dll
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Windows 2019 single artifact - tonlib-cli
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-win-binaries/tonlib-cli.exe
asset_name: tonlib-cli.exe
tag: ${{ steps.tag.outputs.TAG }}
# mac x86-64
- name: Upload Mac x86-64 artifacts
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-macos-binaries.zip
asset_name: ton-mac-x86-64.zip
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Mac x86-64 single artifact - fift
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-macos-binaries/fift
asset_name: fift-mac-x86-64
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Mac x86-64 single artifact - func
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-macos-binaries/func
asset_name: func-mac-x86-64
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Mac x86-64 single artifact - lite-client
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-macos-binaries/lite-client
asset_name: lite-client-mac-x86-64
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Mac x86-64 single artifact - rldp-http-proxy
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-macos-binaries/rldp-http-proxy
asset_name: rldp-http-proxy-mac-x86-64
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Mac x86-64 single artifact - http-proxy
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-macos-binaries/http-proxy
asset_name: http-proxy-mac-x86-64
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Mac x86-64 single artifact - storage-daemon-cli
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-macos-binaries/storage-daemon-cli
asset_name: storage-daemon-cli-mac-x86-64
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Mac x86-64 single artifact - storage-daemon
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-macos-binaries/storage-daemon
asset_name: storage-daemon-mac-x86-64
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Mac x86-64 single artifact - tonlibjson
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-macos-binaries/libtonlibjson.dylib
asset_name: tonlibjson-mac-x86-64.dylib
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Mac x86-64 single artifact - libemulator
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-macos-binaries/libemulator.dylib
asset_name: libemulator-mac-x86-64.dylib
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Mac x86-64 single artifact - tonlib-cli
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-macos-binaries/tonlib-cli
asset_name: tonlib-cli-mac-x86-64
tag: ${{ steps.tag.outputs.TAG }}
# linux x86-64
- name: Upload Linux x86-64 artifacts
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-linux-binaries.zip
asset_name: ton-linux-x86_64.zip
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Linux x86-64 single artifact - fift
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-linux-binaries/fift
asset_name: fift-linux-x86_64
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Linux x86-64 single artifact - func
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-linux-binaries/func
asset_name: func-linux-x86_64
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Linux x86-64 single artifact - lite-client
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-linux-binaries/lite-client
asset_name: lite-client-linux-x86_64
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Linux x86-64 single artifact - rldp-http-proxy
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-linux-binaries/rldp-http-proxy
asset_name: rldp-http-proxy-linux-x86_64
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Linux x86-64 single artifact - http-proxy
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-linux-binaries/http-proxy
asset_name: http-proxy-linux-x86_64
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Linux x86-64 single artifact - storage-daemon-cli
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-linux-binaries/storage-daemon-cli
asset_name: storage-daemon-cli-linux-x86_64
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Linux x86-64 single artifact - storage-daemon
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-linux-binaries/storage-daemon
asset_name: storage-daemon-linux-x86_64
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Linux x86-64 single artifact - tonlibjson
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-linux-binaries/libtonlibjson.so
asset_name: tonlibjson-linux-x86_64.so
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Linux x86-64 single artifact - libemulator
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-linux-binaries/libemulator.so
asset_name: libemulator-linux-x86_64.so
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Linux x86-64 single artifact - tonlib-cli
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-linux-binaries/tonlib-cli
asset_name: tonlib-cli-linux-x86_64
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload WASM artifacts
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-wasm-binaries.zip
asset_name: ton-wasm-binaries.zip
tag: ${{ steps.tag.outputs.TAG }}

View file

@ -0,0 +1,41 @@
name: Docker Ubuntu 22.04 image
on:
workflow_dispatch:
push:
branches:
- 'master'
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push:
runs-on: ubuntu-22.04
steps:
- name: Check out repository
uses: actions/checkout@v3
with:
submodules: 'recursive'
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to GitHub Container Registry
uses: docker/login-action@v1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2
with:
push: true
context: ./
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest

26
.github/workflows/ton-ccpcheck.yml vendored Normal file
View file

@ -0,0 +1,26 @@
name: TON Static Code Analysis
on: [push,workflow_dispatch,workflow_call]
jobs:
build:
runs-on: ubuntu-22.04
steps:
- name: Check out repository
uses: actions/checkout@v3
with:
submodules: 'recursive'
- name: Run Cppcheck
uses: Bedzior/run-cppcheck@master
with:
enabled checks: all
enable inconclusive: true
generate report: true
- name: Upload report
uses: actions/upload-artifact@v1
with:
name: ton-ccpcheck-report
path: output

41
.github/workflows/ton-x86-64-linux.yml vendored Normal file
View file

@ -0,0 +1,41 @@
name: Ubuntu TON build (portable, x86-64)
on: [push,workflow_dispatch,workflow_call]
jobs:
build:
runs-on: ubuntu-22.04
steps:
- run: |
sudo apt update
sudo apt install -y apt-utils
- uses: actions/checkout@v3
with:
submodules: 'recursive'
- uses: cachix/install-nix-action@v23
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Build TON
run: |
cp assembly/nix/build-linux-x86-64-nix.sh .
chmod +x build-linux-x86-64-nix.sh
./build-linux-x86-64-nix.sh -t
- name: Simple binaries test
run: |
sudo mv /nix/store /nix/store2
artifacts/validator-engine -V
artifacts/lite-client -V
artifacts/fift -V
artifacts/func -V
- name: Upload artifacts
uses: actions/upload-artifact@master
with:
name: ton-x86_64-linux-binaries
path: artifacts

37
.github/workflows/ton-x86-64-macos.yml vendored Normal file
View file

@ -0,0 +1,37 @@
name: MacOS TON build (portable, x86-64)
on: [push,workflow_dispatch,workflow_call]
jobs:
build:
runs-on: macos-12
steps:
- uses: actions/checkout@v3
with:
submodules: 'recursive'
- uses: cachix/install-nix-action@v23
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Build TON
run: |
cp assembly/nix/build-macos-nix.sh .
chmod +x build-macos-nix.sh
./build-macos-nix.sh -t
- name: Simple binaries test
run: |
sudo mv /nix/store /nix/store2
artifacts/validator-engine -V
artifacts/lite-client -V
artifacts/fift -V
artifacts/func -V
- name: Upload artifacts
uses: actions/upload-artifact@master
with:
name: ton-x86_64-macos-binaries
path: artifacts

View file

@ -0,0 +1,34 @@
name: Windows TON build (portable, x86-64)
on: [push,workflow_dispatch,workflow_call]
defaults:
run:
shell: cmd
jobs:
build:
runs-on: windows-2022
steps:
- name: Get Current OS version
run: |
systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
- name: Check out current repository
uses: actions/checkout@v3
with:
submodules: 'recursive'
- name: Build TON
run: |
copy assembly\native\build-windows-github.bat .
copy assembly\native\build-windows.bat .
build-windows-github.bat Enterprise
- name: Upload artifacts
uses: actions/upload-artifact@master
with:
name: ton-win-binaries
path: artifacts

13
.gitignore vendored
View file

@ -7,8 +7,19 @@ tl/generate/auto/
compile_commands.json
crypto/block/block-auto.cpp
crypto/block/block-auto.h
crypto/smartcont/*-code.fif
crypto/smartcont/auto/
test/regression-tests.cache/
*.swp
**/*build*/
.idea
.vscode
zlib/
libsodium/
libmicrohttpd-0.9.77-w32-bin/
readline-5.0-1-lib/
secp256k1/
openssl-3.1.4/
libsodium-1.0.18-stable-msvc.zip
libmicrohttpd-0.9.77-w32-bin.zip
openssl-3.1.4.zip
readline-5.0-1-lib.zip

3
.gitmodules vendored
View file

@ -10,3 +10,6 @@
[submodule "third-party/libraptorq"]
path = third-party/libraptorq
url = https://github.com/ton-blockchain/libRaptorQ
[submodule "third-party/blst"]
path = third-party/blst
url = https://github.com/supranational/blst.git

30
CMake/BuildBLST.cmake Normal file
View file

@ -0,0 +1,30 @@
set(BLST_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third-party/blst)
set(BLST_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/third-party/blst)
set(BLST_INCLUDE_DIR ${BLST_SOURCE_DIR}/bindings)
if (NOT BLST_LIB)
if (WIN32)
set(BLST_LIB ${BLST_BINARY_DIR}/blst.lib)
set(BLST_BUILD_COMMAND ${BLST_SOURCE_DIR}/build.bat)
else()
set(BLST_LIB ${BLST_BINARY_DIR}/libblst.a)
if (PORTABLE)
set(BLST_BUILD_COMMAND ${BLST_SOURCE_DIR}/build.sh -D__BLST_PORTABLE__)
else()
set(BLST_BUILD_COMMAND ${BLST_SOURCE_DIR}/build.sh)
endif()
endif()
file(MAKE_DIRECTORY ${BLST_BINARY_DIR})
add_custom_command(
WORKING_DIRECTORY ${BLST_BINARY_DIR}
COMMAND ${BLST_BUILD_COMMAND}
COMMENT "Build blst"
DEPENDS ${BLST_SOURCE_DIR}
OUTPUT ${BLST_LIB}
)
else()
message(STATUS "Use BLST: ${BLST_LIB}")
endif()
add_custom_target(blst DEPENDS ${BLST_LIB})

View file

@ -2,37 +2,27 @@
# Once done this will define
#
# MHD_FOUND - system has MHD
# MHD_INCLUDE_DIRS - the MHD include directory
# MHD_INCLUDE_DIR - the MHD include directory
# MHD_LIBRARY - Link these to use MHD
find_path(
MHD_INCLUDE_DIR
NAMES microhttpd.h
DOC "microhttpd include dir"
)
find_library(
MHD_LIBRARY
NAMES microhttpd microhttpd-10 libmicrohttpd libmicrohttpd-dll
DOC "microhttpd library"
)
set(MHD_INCLUDE_DIRS ${MHD_INCLUDE_DIR})
set(MHD_LIBRARIES ${MHD_LIBRARY})
# debug library on windows
# same naming convention as in qt (appending debug library with d)
# boost is using the same "hack" as us with "optimized" and "debug"
# official MHD project actually uses _d suffix
if (MSVC)
find_library(
MHD_LIBRARY_DEBUG
NAMES microhttpd_d microhttpd-10_d libmicrohttpd_d libmicrohttpd-dll_d
DOC "mhd debug library"
if (NOT MHD_LIBRARY)
find_path(
MHD_INCLUDE_DIR
NAMES microhttpd.h
DOC "microhttpd include dir"
)
set(MHD_LIBRARIES optimized ${MHD_LIBRARIES} debug ${MHD_LIBRARY_DEBUG})
find_library(
MHD_LIBRARY
NAMES microhttpd microhttpd-10 libmicrohttpd libmicrohttpd-dll
DOC "microhttpd library"
)
endif()
if (MHD_LIBRARY)
message(STATUS "Found MHD: ${MHD_LIBRARY}")
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(mhd DEFAULT_MSG MHD_INCLUDE_DIR MHD_LIBRARY)
find_package_handle_standard_args(MHD DEFAULT_MSG MHD_INCLUDE_DIR MHD_LIBRARY)
mark_as_advanced(MHD_INCLUDE_DIR MHD_LIBRARY)

28
CMake/FindSecp256k1.cmake Normal file
View file

@ -0,0 +1,28 @@
# - Try to find SECP256K1
# Once done this will define
#
# SECP256K1_FOUND - system has SECP256K1
# SECP256K1_INCLUDE_DIR - the SECP256K1 include directory
# SECP256K1_LIBRARY - Link these to use SECP256K1
if (NOT SECP256K1_LIBRARY)
find_path(
SECP256K1_INCLUDE_DIR
NAMES secp256k1_recovery.h
DOC "secp256k1_recovery.h include dir"
)
find_library(
SECP256K1_LIBRARY
NAMES secp256k1 libsecp256k1
DOC "secp256k1 library"
)
endif()
if (SECP256K1_LIBRARY)
message(STATUS "Found Secp256k1: ${SECP256K1_LIBRARY}")
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Secp256k1 DEFAULT_MSG SECP256K1_INCLUDE_DIR SECP256K1_LIBRARY)
mark_as_advanced(SECP256K1_INCLUDE_DIR SECP256K1_LIBRARY)

298
CMake/FindSodium.cmake Normal file
View file

@ -0,0 +1,298 @@
# Written in 2016 by Henrik Steffen Gaßmann <henrik@gassmann.onl>
#
# To the extent possible under law, the author(s) have dedicated all
# copyright and related and neighboring rights to this software to the
# public domain worldwide. This software is distributed without any warranty.
#
# You should have received a copy of the CC0 Public Domain Dedication
# along with this software. If not, see
#
# http://creativecommons.org/publicdomain/zero/1.0/
#
########################################################################
# Tries to find the local libsodium installation.
#
# On Windows the SODIUM_DIR environment variable is used as a default
# hint which can be overridden by setting the corresponding cmake variable.
#
# Once done the following variables will be defined:
#
# SODIUM_FOUND
# SODIUM_INCLUDE_DIR
# SODIUM_LIBRARY_DEBUG
# SODIUM_LIBRARY_RELEASE
#
#
# Furthermore an imported "sodium" target is created.
#
if (CMAKE_C_COMPILER_ID STREQUAL "GNU"
OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
set(_GCC_COMPATIBLE 1)
endif()
# static library option
if (NOT DEFINED SODIUM_USE_STATIC_LIBS)
option(SODIUM_USE_STATIC_LIBS "enable to statically link against sodium" OFF)
endif()
if(NOT (SODIUM_USE_STATIC_LIBS EQUAL SODIUM_USE_STATIC_LIBS_LAST))
unset(sodium_LIBRARY CACHE)
unset(SODIUM_LIBRARY_DEBUG CACHE)
unset(SODIUM_LIBRARY_RELEASE CACHE)
unset(sodium_DLL_DEBUG CACHE)
unset(sodium_DLL_RELEASE CACHE)
set(SODIUM_USE_STATIC_LIBS_LAST ${SODIUM_USE_STATIC_LIBS} CACHE INTERNAL "internal change tracking variable")
endif()
########################################################################
# UNIX
if (UNIX)
# import pkg-config
find_package(PkgConfig QUIET)
if (PKG_CONFIG_FOUND)
pkg_check_modules(sodium_PKG QUIET libsodium)
endif()
if(SODIUM_USE_STATIC_LIBS)
foreach(_libname ${sodium_PKG_STATIC_LIBRARIES})
if (NOT _libname MATCHES "^lib.*\\.a$") # ignore strings already ending with .a
list(INSERT sodium_PKG_STATIC_LIBRARIES 0 "lib${_libname}.a")
endif()
endforeach()
list(REMOVE_DUPLICATES sodium_PKG_STATIC_LIBRARIES)
# if pkgconfig for libsodium doesn't provide
# static lib info, then override PKG_STATIC here..
if (NOT sodium_PKG_STATIC_FOUND)
set(sodium_PKG_STATIC_LIBRARIES libsodium.a)
endif()
set(XPREFIX sodium_PKG_STATIC)
else()
if (NOT sodium_PKG_FOUND)
set(sodium_PKG_LIBRARIES sodium)
endif()
set(XPREFIX sodium_PKG)
endif()
find_path(SODIUM_INCLUDE_DIR sodium.h
HINTS ${${XPREFIX}_INCLUDE_DIRS}
)
find_library(SODIUM_LIBRARY_DEBUG NAMES ${${XPREFIX}_LIBRARIES}
HINTS ${${XPREFIX}_LIBRARY_DIRS}
)
find_library(SODIUM_LIBRARY_RELEASE NAMES ${${XPREFIX}_LIBRARIES}
HINTS ${${XPREFIX}_LIBRARY_DIRS}
)
########################################################################
# Windows
elseif (WIN32)
set(SODIUM_DIR "$ENV{SODIUM_DIR}" CACHE FILEPATH "sodium install directory")
mark_as_advanced(SODIUM_DIR)
find_path(SODIUM_INCLUDE_DIR
NAMES sodium.h
HINTS ${SODIUM_DIR}
PATH_SUFFIXES include
)
if (MSVC)
# detect target architecture
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/arch.cpp" [=[
#if defined _M_IX86
#error ARCH_VALUE x86_32
#elif defined _M_X64
#error ARCH_VALUE x86_64
#endif
#error ARCH_VALUE unknown
]=])
try_compile(_UNUSED_VAR "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/arch.cpp"
OUTPUT_VARIABLE _COMPILATION_LOG
)
string(REGEX REPLACE ".*ARCH_VALUE ([a-zA-Z0-9_]+).*" "\\1" _TARGET_ARCH "${_COMPILATION_LOG}")
# construct library path
if (_TARGET_ARCH STREQUAL "x86_32")
string(APPEND _PLATFORM_PATH "Win32")
elseif(_TARGET_ARCH STREQUAL "x86_64")
string(APPEND _PLATFORM_PATH "x64")
else()
message(FATAL_ERROR "the ${_TARGET_ARCH} architecture is not supported by Findsodium.cmake.")
endif()
string(APPEND _PLATFORM_PATH "/$$CONFIG$$")
if (MSVC_VERSION LESS 1900)
math(EXPR _VS_VERSION "${MSVC_VERSION} / 10 - 60")
else()
math(EXPR _VS_VERSION "${MSVC_VERSION} / 10 - 50")
endif()
string(APPEND _PLATFORM_PATH "/v${_VS_VERSION}")
if (SODIUM_USE_STATIC_LIBS)
string(APPEND _PLATFORM_PATH "/static")
else()
string(APPEND _PLATFORM_PATH "/dynamic")
endif()
string(REPLACE "$$CONFIG$$" "Debug" _DEBUG_PATH_SUFFIX "${_PLATFORM_PATH}")
string(REPLACE "$$CONFIG$$" "Release" _RELEASE_PATH_SUFFIX "${_PLATFORM_PATH}")
find_library(SODIUM_LIBRARY_DEBUG libsodium.lib
HINTS ${SODIUM_DIR}
PATH_SUFFIXES ${_DEBUG_PATH_SUFFIX}
)
find_library(SODIUM_LIBRARY_RELEASE libsodium.lib
HINTS ${SODIUM_DIR}
PATH_SUFFIXES ${_RELEASE_PATH_SUFFIX}
)
if (NOT SODIUM_USE_STATIC_LIBS)
set(CMAKE_FIND_LIBRARY_SUFFIXES_BCK ${CMAKE_FIND_LIBRARY_SUFFIXES})
set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll")
find_library(sodium_DLL_DEBUG libsodium
HINTS ${SODIUM_DIR}
PATH_SUFFIXES ${_DEBUG_PATH_SUFFIX}
)
find_library(sodium_DLL_RELEASE libsodium
HINTS ${SODIUM_DIR}
PATH_SUFFIXES ${_RELEASE_PATH_SUFFIX}
)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_BCK})
endif()
elseif(_GCC_COMPATIBLE)
if (SODIUM_USE_STATIC_LIBS)
find_library(SODIUM_LIBRARY_DEBUG libsodium.a
HINTS ${SODIUM_DIR}
PATH_SUFFIXES lib
)
find_library(SODIUM_LIBRARY_RELEASE libsodium.a
HINTS ${SODIUM_DIR}
PATH_SUFFIXES lib
)
else()
find_library(SODIUM_LIBRARY_DEBUG libsodium.dll.a
HINTS ${SODIUM_DIR}
PATH_SUFFIXES lib
)
find_library(SODIUM_LIBRARY_RELEASE libsodium.dll.a
HINTS ${SODIUM_DIR}
PATH_SUFFIXES lib
)
file(GLOB _DLL
LIST_DIRECTORIES false
RELATIVE "${SODIUM_DIR}/bin"
"${SODIUM_DIR}/bin/libsodium*.dll"
)
find_library(sodium_DLL_DEBUG ${_DLL} libsodium
HINTS ${SODIUM_DIR}
PATH_SUFFIXES bin
)
find_library(sodium_DLL_RELEASE ${_DLL} libsodium
HINTS ${SODIUM_DIR}
PATH_SUFFIXES bin
)
endif()
else()
message(FATAL_ERROR "this platform is not supported by FindSodium.cmake")
endif()
########################################################################
# unsupported
else()
message(FATAL_ERROR "this platform is not supported by FindSodium.cmake")
endif()
########################################################################
# common stuff
# extract sodium version
if (SODIUM_INCLUDE_DIR)
set(_VERSION_HEADER "${_INCLUDE_DIR}/sodium/version.h")
if (EXISTS _VERSION_HEADER)
file(READ "${_VERSION_HEADER}" _VERSION_HEADER_CONTENT)
string(REGEX REPLACE ".*#[ \t]*define[ \t]*SODIUM_VERSION_STRING[ \t]*\"([^\n]*)\".*" "\\1"
sodium_VERSION "${_VERSION_HEADER_CONTENT}")
set(sodium_VERSION "${sodium_VERSION}" PARENT_SCOPE)
endif()
endif()
# communicate results
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
Sodium # The name must be either uppercase or match the filename case.
REQUIRED_VARS
SODIUM_LIBRARY_RELEASE
SODIUM_LIBRARY_DEBUG
SODIUM_INCLUDE_DIR
VERSION_VAR
sodium_VERSION
)
if(SODIUM_FOUND)
set(SODIUM_LIBRARIES
optimized ${SODIUM_LIBRARY_RELEASE} debug ${SODIUM_LIBRARY_DEBUG})
endif()
# mark file paths as advanced
mark_as_advanced(SODIUM_INCLUDE_DIR)
mark_as_advanced(SODIUM_LIBRARY_DEBUG)
mark_as_advanced(SODIUM_LIBRARY_RELEASE)
if (WIN32)
mark_as_advanced(sodium_DLL_DEBUG)
mark_as_advanced(sodium_DLL_RELEASE)
endif()
# create imported target
if(SODIUM_USE_STATIC_LIBS)
set(_LIB_TYPE STATIC)
else()
set(_LIB_TYPE SHARED)
endif()
if(NOT TARGET sodium)
add_library(sodium ${_LIB_TYPE} IMPORTED)
endif()
set_target_properties(sodium PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${SODIUM_INCLUDE_DIR}"
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
)
if (SODIUM_USE_STATIC_LIBS)
set_target_properties(sodium PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "SODIUM_STATIC"
IMPORTED_LOCATION "${SODIUM_LIBRARY_RELEASE}"
IMPORTED_LOCATION_DEBUG "${SODIUM_LIBRARY_DEBUG}"
)
else()
if (UNIX)
set_target_properties(sodium PROPERTIES
IMPORTED_LOCATION "${SODIUM_LIBRARY_RELEASE}"
IMPORTED_LOCATION_DEBUG "${SODIUM_LIBRARY_DEBUG}"
)
elseif (WIN32)
set_target_properties(sodium PROPERTIES
IMPORTED_IMPLIB "${SODIUM_LIBRARY_RELEASE}"
IMPORTED_IMPLIB_DEBUG "${SODIUM_LIBRARY_DEBUG}"
)
if (NOT (sodium_DLL_DEBUG MATCHES ".*-NOTFOUND"))
set_target_properties(sodium PROPERTIES
IMPORTED_LOCATION_DEBUG "${sodium_DLL_DEBUG}"
)
endif()
if (NOT (sodium_DLL_RELEASE MATCHES ".*-NOTFOUND"))
set_target_properties(sodium PROPERTIES
IMPORTED_LOCATION_RELWITHDEBINFO "${sodium_DLL_RELEASE}"
IMPORTED_LOCATION_MINSIZEREL "${sodium_DLL_RELEASE}"
IMPORTED_LOCATION_RELEASE "${sodium_DLL_RELEASE}"
)
endif()
endif()
endif()

View file

@ -1,9 +1,19 @@
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project(TON VERSION 0.5 LANGUAGES C CXX)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
#set(OPENSSL_USE_STATIC_LIBS TRUE)
# Define the two required variables before including the source code for watching a git repository.
set(PRE_CONFIGURE_FILE "git.cc.in")
set(POST_CONFIGURE_FILE "${CMAKE_CURRENT_BINARY_DIR}/git.cc")
include(git_watcher.cmake)
# Create a library out of the compiled post-configure file.
add_library(git STATIC ${POST_CONFIGURE_FILE})
target_include_directories(git PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
add_dependencies(git check_git)
# Prevent in-source build
get_filename_component(TON_REAL_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" REALPATH)
get_filename_component(TON_REAL_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" REALPATH)
@ -69,8 +79,16 @@ else()
set(HAVE_SSE42 FALSE)
endif()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
set(CMAKE_CXX_EXTENSIONS FALSE)
#BEGIN internal
option(USE_EMSCRIPTEN "Use \"ON\" for config building wasm." OFF)
option(TON_ONLY_TONLIB "Use \"ON\" to build only tonlib." OFF)
if (USE_EMSCRIPTEN)
set(TON_ONLY_TONLIB true)
endif()
if (TON_ONLY_TONLIB)
set(NOT_TON_ONLY_TONLIB false)
else()
@ -87,8 +105,18 @@ option(TON_USE_TSAN "Use \"ON\" to enable ThreadSanitizer." OFF)
option(TON_USE_UBSAN "Use \"ON\" to enable UndefinedBehaviorSanitizer." OFF)
set(TON_ARCH "native" CACHE STRING "Architecture, will be passed to -march=")
#BEGIN M1 support
EXECUTE_PROCESS( COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE ARCHITECTURE )
if ((ARCHITECTURE MATCHES "arm64") AND (CMAKE_SYSTEM_NAME STREQUAL "Darwin") AND
(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13.0)) # only clang 13+ supports cpu=apple-m1
set(TON_ARCH "apple-m1")
endif()
#END M1 support
if (TON_USE_ABSEIL)
message("Add abseil-cpp")
set(ABSL_PROPAGATE_CXX_STD TRUE)
add_subdirectory(third-party/abseil-cpp EXCLUDE_FROM_ALL)
set(ABSL_FOUND 1)
endif()
@ -108,13 +136,23 @@ set(CRC32C_BUILD_BENCHMARKS OFF CACHE BOOL "Build CRC32C's benchmarks")
set(CRC32C_USE_GLOG OFF CACHE BOOL "Build CRC32C's tests with Google Logging")
set(CRC32C_INSTALL OFF CACHE BOOL "Install CRC32C's header and library")
message("Add crc32c")
add_subdirectory(third-party/crc32c EXCLUDE_FROM_ALL)
if (NOT MSVC)
set(OLD_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
# fix aarch64 build @ crc32c/src/crc32c_arm64_linux_check.h
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=address")
add_subdirectory(third-party/crc32c EXCLUDE_FROM_ALL)
set(CMAKE_CXX_FLAGS ${OLD_CMAKE_CXX_FLAGS})
unset(OLD_CMAKE_CXX_FLAGS)
else()
add_subdirectory(third-party/crc32c EXCLUDE_FROM_ALL)
endif()
set(CRC32C_FOUND 1)
if (TON_USE_ROCKSDB)
if (ANDROID)
if (ANDROID)
set(PORTABLE ON CACHE BOOL "portable")
endif()
set(WITH_GFLAGS OFF CACHE BOOL "build with GFlags")
set(WITH_TESTS OFF CACHE BOOL "build with tests")
set(WITH_TOOLS OFF CACHE BOOL "build with tools")
set(FAIL_ON_WARNINGS OFF CACHE BOOL "fail on warnings")
@ -144,6 +182,8 @@ endif()
message("Add ton")
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH})
include(BuildBLST)
# Configure CCache if available
find_program(CCACHE_FOUND ccache)
#set(CCACHE_FOUND 0)
@ -167,33 +207,27 @@ endif()
include(CheckCXXCompilerFlag)
if (GCC OR CLANG OR INTEL)
if (WIN32 AND INTEL)
set(STD14_FLAG /Qstd=c++14)
else()
set(STD14_FLAG -std=c++14)
endif()
check_cxx_compiler_flag(${STD14_FLAG} HAVE_STD14)
if (NOT HAVE_STD14)
string(REPLACE "c++14" "c++1y" STD14_FLAG "${STD14_FLAG}")
check_cxx_compiler_flag(${STD14_FLAG} HAVE_STD1Y)
set(HAVE_STD14 ${HAVE_STD1Y})
endif()
elseif (MSVC)
set(HAVE_STD14 MSVC_VERSION>=1900)
endif()
if (NOT HAVE_STD14)
message(FATAL_ERROR "No C++14 support in the compiler. Please upgrade the compiler.")
endif()
set(CMAKE_THREAD_PREFER_PTHREAD ON)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
find_package(ZLIB REQUIRED)
find_package(PkgConfig REQUIRED)
if (NOT ZLIB_FOUND)
find_package(ZLIB REQUIRED)
else()
message(STATUS "Using zlib ${ZLIB_LIBRARIES}")
endif()
if (TON_ARCH AND NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${TON_ARCH}")
CHECK_CXX_COMPILER_FLAG( "-march=${TON_ARCH}" COMPILER_OPT_ARCH_SUPPORTED )
if (TON_ARCH STREQUAL "apple-m1")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=${TON_ARCH}")
elseif(COMPILER_OPT_ARCH_SUPPORTED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${TON_ARCH}")
elseif(NOT TON_ARCH STREQUAL "native")
message(FATAL_ERROR "Compiler doesn't support arch ${TON_ARCH}")
endif()
endif()
if (THREADS_HAVE_PTHREAD_ARG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
@ -227,21 +261,26 @@ if (MSVC)
add_definitions(-D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /W4 /wd4100 /wd4127 /wd4324 /wd4456 /wd4457 /wd4458 /wd4505 /wd4702")
elseif (CLANG OR GCC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${STD14_FLAG} -fno-omit-frame-pointer")
if (GCC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstrong-eval-order=some")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer")
if (APPLE)
#use "-Wl,-exported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/export_list" for exported symbols
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fvisibility=hidden -Wl,-dead_strip,-x,-S")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fvisibility=hidden -Wl,-dead_strip,-x,-S")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -fvisibility=hidden -Wl,-dead_strip,-x,-S")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections -Wl,--exclude-libs,ALL")
if (NOT USE_EMSCRIPTEN)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections -Wl,--exclude-libs,ALL")
endif()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
if (NOT TON_USE_ASAN AND NOT TON_USE_TSAN AND NOT MEMPROF)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--exclude-libs,ALL")
if (NOT USE_EMSCRIPTEN)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--exclude-libs,ALL")
endif()
endif()
endif()
elseif (INTEL)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${STD14_FLAG}")
endif()
if (WIN32)
@ -255,14 +294,27 @@ if (NOT ANDROID) # _FILE_OFFSET_BITS is broken in ndk r15 and r15b and doesn't w
add_definitions(-D_FILE_OFFSET_BITS=64)
endif()
set(INTERNAL_COMPILE "0")
#BEGIN internal
add_definitions(-D_INTERNAL_COMPILE=1)
set(INTERNAL_COMPILE "1")
#END internal
set(TONLIB_COMPILE "0")
#BEGIN tonlib
add_definitions(-D_TONLIB_COMPILE=1)
set(TONLIB_COMPILE "1")
#END tonlib
include(AddCXXCompilerFlag)
if (MSVC)
add_cxx_compiler_flag("/experimental:external /external:anglebrackets /external:W0")
endif()
if (NOT MSVC)
add_cxx_compiler_flag("-Wall")
add_cxx_compiler_flag("-Wextra")
endif()
add_cxx_compiler_flag("-Wextra")
add_cxx_compiler_flag("-Wimplicit-fallthrough=2")
add_cxx_compiler_flag("-Wpointer-arith")
add_cxx_compiler_flag("-Wcast-qual")
@ -323,6 +375,10 @@ if (LATEX_FOUND)
add_latex_document(doc/tvm.tex TARGET_NAME ton_vm_description)
add_latex_document(doc/tblkch.tex TARGET_NAME ton_blockchain_description)
add_latex_document(doc/fiftbase.tex TARGET_NAME fift_basic_description)
add_latex_document(doc/catchain.tex TARGET_NAME catchain_consensus_description)
endif()
if (NOT LATEX_FOUND)
message(STATUS "Could NOT find LATEX (this is NOT an error)")
endif()
#END internal
@ -352,6 +408,7 @@ add_subdirectory(tl-utils)
add_subdirectory(adnl)
add_subdirectory(crypto)
add_subdirectory(lite-client)
add_subdirectory(emulator)
#BEGIN tonlib
add_subdirectory(tonlib)
@ -364,16 +421,21 @@ add_subdirectory(tdfec)
add_subdirectory(keyring)
add_subdirectory(fec)
add_subdirectory(rldp)
add_subdirectory(rldp2)
add_subdirectory(dht)
add_subdirectory(overlay)
add_subdirectory(catchain)
add_subdirectory(validator-session)
add_subdirectory(validator)
add_subdirectory(blockchain-explorer)
add_subdirectory(storage)
add_subdirectory(validator-engine)
add_subdirectory(validator-engine-console)
add_subdirectory(create-hardfork)
add_subdirectory(dht-server)
add_subdirectory(utils)
add_subdirectory(http)
add_subdirectory(rldp-http-proxy)
endif()
#END internal
@ -394,6 +456,13 @@ target_link_libraries(test-vm PRIVATE ton_crypto fift-lib)
add_executable(test-smartcont test/test-td-main.cpp ${SMARTCONT_TEST_SOURCE})
target_link_libraries(test-smartcont PRIVATE smc-envelope fift-lib ton_db)
add_executable(test-bigint ${BIGINT_TEST_SOURCE})
target_link_libraries(test-bigint PRIVATE ton_crypto)
if (WINGETOPT_FOUND)
target_link_libraries_system(test-bigint wingetopt)
endif()
add_executable(test-cells test/test-td-main.cpp ${CELLS_TEST_SOURCE})
target_link_libraries(test-cells PRIVATE ton_crypto)
@ -428,7 +497,13 @@ endif()
#BEGIN internal
if (NOT TON_ONLY_TONLIB)
add_executable(test-db test/test-td-main.cpp ${TONDB_TEST_SOURCE})
target_link_libraries(test-db PRIVATE ton_db memprof)
target_link_libraries(test-db PRIVATE ton_db memprof tdfec)
add_executable(test-storage test/test-td-main.cpp ${STORAGE_TEST_SOURCE})
target_link_libraries(test-storage PRIVATE storage ton_db memprof tl_api tl-utils fec rldp2)
add_executable(test-rocksdb test/test-rocksdb.cpp)
target_link_libraries(test-rocksdb PRIVATE memprof tddb tdutils)
add_executable(test-tddb test/test-td-main.cpp ${TDDB_TEST_SOURCE})
target_link_libraries(test-tddb PRIVATE tdutils tddb ${CMAKE_THREAD_LIBS_INIT} memprof)
@ -449,29 +524,20 @@ add_executable(test-dht test/test-dht.cpp)
target_link_libraries(test-dht adnl adnltest dht tl_api)
add_executable(test-rldp test/test-rldp.cpp)
target_link_libraries(test-rldp adnl adnltest dht rldp tl_api)
add_executable(test-rldp2 test/test-rldp2.cpp)
target_link_libraries(test-rldp2 adnl adnltest dht rldp2 tl_api)
add_executable(test-validator-session-state test/test-validator-session-state.cpp)
target_link_libraries(test-validator-session-state adnl dht rldp validatorsession tl_api)
#add_executable(test-node test/test-node.cpp)
#target_link_libraries(test-node overlay tdutils tdactor adnl tl_api dht
# catchain validatorsession)
add_executable(test-catchain test/test-catchain.cpp)
target_link_libraries(test-catchain overlay tdutils tdactor adnl adnltest rldp tl_api dht
catchain )
#add_executable(test-validator-session test/test-validator-session.cpp)
#target_link_libraries(test-validator-session overlay tdutils tdactor adnl tl_api dht
# catchain validatorsession)
add_executable(test-ton-collator test/test-ton-collator.cpp)
target_link_libraries(test-ton-collator overlay tdutils tdactor adnl tl_api dht
catchain validatorsession validator-disk ton_validator validator-disk )
#add_executable(test-validator test/test-validator.cpp)
#target_link_libraries(test-validator overlay tdutils tdactor adnl tl_api dht
# rldp catchain validatorsession ton-node validator ton_validator validator memprof ${JEMALLOC_LIBRARIES})
#add_executable(test-ext-server test/test-ext-server.cpp)
#target_link_libraries(test-ext-server tdutils tdactor adnl tl_api dht )
#add_executable(test-ext-client test/test-ext-client.cpp)
#target_link_libraries(test-ext-client tdutils tdactor adnl tl_api tl-lite-utils)
add_executable(test-http test/test-http.cpp)
target_link_libraries(test-http PRIVATE tonhttp)
get_directory_property(HAS_PARENT PARENT_DIRECTORY)
if (HAS_PARENT)
@ -483,6 +549,7 @@ if (HAS_PARENT)
${FEC_TEST_SOURCE}
${ED25519_TEST_SOURCE}
${TONDB_TEST_SOURCE}
${BIGNUM_TEST_SOURCE}
${CELLS_TEST_SOURCE} # ${TONVM_TEST_SOURCE} ${FIFT_TEST_SOURCE} ${TONLIB_ONLINE_TEST_SOURCE}
PARENT_SCOPE)
endif()
@ -496,6 +563,7 @@ set(TEST_OPTIONS "--regression ${CMAKE_CURRENT_SOURCE_DIR}/test/regression-tests
separate_arguments(TEST_OPTIONS)
add_test(test-ed25519-crypto crypto/test-ed25519-crypto)
add_test(test-ed25519 test-ed25519)
add_test(test-bigint test-bigint)
add_test(test-vm test-vm ${TEST_OPTIONS})
add_test(test-fift test-fift ${TEST_OPTIONS})
add_test(test-cells test-cells ${TEST_OPTIONS})
@ -508,11 +576,52 @@ add_test(test-tdutils test-tdutils)
add_test(test-tonlib-offline test-tonlib-offline)
#END tonlib
# FunC tests
if (NOT NIX)
if (MSVC)
set(PYTHON_VER "python")
else()
set(PYTHON_VER "python3")
endif()
add_test(
NAME test-func
COMMAND ${PYTHON_VER} run_tests.py tests/
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/crypto/func/auto-tests)
if (WIN32)
set_property(TEST test-func PROPERTY ENVIRONMENT
"FUNC_EXECUTABLE=${CMAKE_CURRENT_BINARY_DIR}/crypto/func.exe"
"FIFT_EXECUTABLE=${CMAKE_CURRENT_BINARY_DIR}/crypto/fift.exe"
"FIFTPATH=${CMAKE_CURRENT_SOURCE_DIR}/crypto/fift/lib/")
else()
set_property(TEST test-func PROPERTY ENVIRONMENT
"FUNC_EXECUTABLE=${CMAKE_CURRENT_BINARY_DIR}/crypto/func"
"FIFT_EXECUTABLE=${CMAKE_CURRENT_BINARY_DIR}/crypto/fift"
"FIFTPATH=${CMAKE_CURRENT_SOURCE_DIR}/crypto/fift/lib/")
endif()
add_test(
NAME test-func-legacy
COMMAND ${PYTHON_VER} legacy_tester.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/crypto/func/auto-tests)
if (WIN32)
set_property(TEST test-func-legacy PROPERTY ENVIRONMENT
"FUNC_EXECUTABLE=${CMAKE_CURRENT_BINARY_DIR}/crypto/func.exe"
"FIFT_EXECUTABLE=${CMAKE_CURRENT_BINARY_DIR}/crypto/fift.exe"
"FIFTPATH=${CMAKE_CURRENT_SOURCE_DIR}/crypto/fift/lib/")
else()
set_property(TEST test-func-legacy PROPERTY ENVIRONMENT
"FUNC_EXECUTABLE=${CMAKE_CURRENT_BINARY_DIR}/crypto/func"
"FIFT_EXECUTABLE=${CMAKE_CURRENT_BINARY_DIR}/crypto/fift"
"FIFTPATH=${CMAKE_CURRENT_SOURCE_DIR}/crypto/fift/lib/")
endif()
endif()
#BEGIN internal
if (NOT TON_ONLY_TONLIB)
add_test(test-adnl test-adnl)
add_test(test-dht test-dht)
add_test(test-rldp test-rldp)
add_test(test-rldp2 test-rldp2)
add_test(test-validator-session-state test-validator-session-state)
add_test(test-catchain test-catchain)
@ -521,4 +630,3 @@ add_test(test-tddb test-tddb ${TEST_OPTIONS})
add_test(test-db test-db ${TEST_OPTIONS})
endif()
#END internal

178
Changelog.md Normal file
View file

@ -0,0 +1,178 @@
## 2024.04 Update
1. Emulator: Single call optimized runGetMethod added
2. Tonlib: a series of proof improvements, also breaking Change in `liteServer.getAllShardsInfo` method (see below)
3. DB: usage statistics now collected, outdated persistent states are not serialized
4. LS: fast `getOutMsgQueueSizes` added, preliminary support of non-final block requests
5. Network: lz4 compression of block candidates (disabled by default).
6. Overlays: add custom overlays
7. Transaction Executor: fixed issue with due_payment collection
* `liteServer.getAllShardsInfo` method was updated for better efficiency. Previously, field proof contained BoC with two roots: one for BlockState from block's root and another for ShardHashes from BlockState. Now, it returns a single-root proof BoC, specifically the merkle proof of ShardHashes directly from the block's root, streamlining data access and integrity. Checking of the proof requires to check that ShardHashes in the `data` correspond to ShardHashes from the block.
Besides the work of the core team, this update is based on the efforts of @akifoq (due_payment issue).
## 2024.03 Update
1. Preparatory (not enabled yet) code for pre-compiled smart-contract.
2. Minor fixes for fee-related opcodes.
## 2024.02 Update
1. Improvement of validator synchronisation:
* Better handling of block broadcasts -> faster sync
* Additional separate overlay among validators as second option for synchronisation
2. Improvements in LS:
* c7 and library context is fully filled up for server-side rungetmethod
* Cache for runmethods and successfull external messages
* Logging of LS requests statistic
3. Precise control of open files:
* almost instantaneous validator start
* `--max-archive-fd` option
* autoremoval of not used temp archive files
* `--archive-preload-period` option
4. Preparatory (not enabled yet) code for addition on new TVM instructions for cheaper fee calculation onchain.
## 2024.01 Update
1. Fixes in how gas in transactions on special accounts is accounted in block limit. Previously, gas was counted as usual, so to conduct elections that costs >30m gas block limit in masterchain was set to 37m gas. To lower the limit for safety reasons it is proposed to caunt gas on special accounts separately. Besides `gas_max` is set to `special_gas_limit` for all types of transactions on special accounts. New behavior is activated through setting `version >= 5` in `ConfigParam 8;`.
* Besides update of config temporally increases gas limit on `EQD_v9j1rlsuHHw2FIhcsCFFSD367ldfDdCKcsNmNpIRzUlu` to `special_gas_limit`, see [details](https://t.me/tonstatus/88).
2. Improvements in LS behavior
* Improved detection of the state with all shards applied to decrease rate of `Block is not applied` error
* Better error logs: `block not in db` and `block is not applied` separation
* Fix error in proof generation for blocks after merge
* Fix most of `block is not applied` issues related to sending too recent block in Proofs
* LS now check external messages till `accept_message` (`set_gas`).
3. Improvements in DHT work and storage, CellDb, config.json ammendment, peer misbehavior detection, validator session stats collection, emulator.
4. Change in CTOS and XLOAD behavior activated through setting `version >= 5` in `ConfigParam 8;`:
* Loading "nested libraries" (i.e. a library cell that points to another library cell) throws an exception.
* Loading a library consumes gas for cell load only once (for the library cell), not twice (both for the library cell and the cell in the library).
* `XLOAD` now works differently. When it takes a library cell, it returns the cell that it points to. This allows loading "nested libraries", if needed.
Besides the work of the Core team, this update is based on the efforts of @XaBbl4 (peer misbehavior detection) and @akifoq (CTOS behavior and gas limit scheme for special accounts).
## 2023.12 Update
1. Optimized message queue handling, now queue cleaning speed doesn't depend on total queue size
* Cleaning delivered messages using lt augmentation instead of random search / consequtive walk
* Keeping root cell of queue message in memory until outdated (caching)
2. Changes to block collation/validation limits
3. Stop accepting new external message if message queue is overloaded
4. Introducing conditions for shard split/merge based on queue size
Read [more](https://blog.ton.org/technical-report-december-5-inscriptions-launch-on-ton) on that update.
## 2023.11 Update
1. New TVM Functionality. (Disabled by default)
2. A series of emulator improvements: libraries support, higher max stack size, etc
3. A series of tonlib and tonlib-cli improvements: wallet-v4 support, getconfig, showtransactions, etc
4. Changes to public libraries: now contract can not publish more than 256 libraries (config parameter) and contracts can not be deployed with public libraries in initstate (instead contracts need explicitly publish all libraries)
5. Changes to storage due payment: now due payment is collected in Storage Phase, however for bouncable messages fee amount can not exceed balance of account prior to message.
Besides the work of the core team, this update is based on the efforts of @aleksej-paschenko (emulator improvements), @akifoq (security improvements), Trail of Bits auditor as well as all participants of [TEP-88 discussion](https://github.com/ton-blockchain/TEPs/pull/88).
## 2023.10 Update
1. A series of additional security checks in node: special cells in action list, init state in external messages, peers data prior to saving to disk.
2. Human-readable timestamps in explorer
Besides the work of the core team, this update is based on the efforts of @akifoq and @mr-tron.
## 2023.06 Update
1. (disabled by default) New deflation mechanisms: partial fee burning and blackhole address
2. Storage-contract improvement
Besides the work of the core team, this update is based on the efforts of @DearJohnDoe from Tonbyte (Storage-contract improvement).
## 2023.05 Update
1. Archive manager optimization
2. A series of catchain (basic consensus protocol) security improvements
3. Update for Fift libraries and FunC: better error-handling, fixes for `catch` stack recovery
4. A series of out message queue handling optimization (already deployed during emergency upgrades between releases)
5. Improvement of binaries portability
Besides the work of the core team, this update is based on the efforts of @aleksej-paschenko (portability improvement), [Disintar team](https://github.com/disintar/) (archive manager optimization) and [sec3-service](https://github.com/sec3-service) security auditors (funC improvements).
## 2023.04 Update
1. CPU load optimization: previous DHT reconnect policy was too aggressive
2. Network throughput improvements: granular control on external message broadcast, optimize celldb GC, adjust state serialization and block downloading timings, rldp2 for states and archives
3. Update for Fift (namespaces) and Fift libraries (list of improvements: https://github.com/ton-blockchain/ton/issues/631)
4. Better handling of incorrect inputs in funC: fix UB and prevent crashes on some inputs, improve optimizing int consts and unused variables in FunC, fix analyzing repeat loop. FunC version is increase to 0.4.3.
5. `listBlockTransactionsExt` in liteserver added
6. Tvm emulator improvements
Besides the work of the core team, this update is based on the efforts of @krigga (tvm emulator improvement), @ex3ndr (`PUSHSLICE` fift-asm improvement) and [sec3-service](https://github.com/sec3-service) security auditors (funC improvements).
## 2023.03 Update
1. Improvement of ADNL connection stability
2. Transaction emulator support and getAccountStateByTransaction method
3. Fixes of typos, undefined behavior and timer warnings
4. Handling incorrect integer literal values in funC; funC version bumped to 0.4.2
5. FunC Mathlib
## 2023.01 Update
1. Added ConfigParam 44: `SuspendedAddressList`. Upon being set this config suspends initialisation of **uninit** addresses from the list for given time.
2. FunC: `v0.4.1` added pragmas for precise control of computation order
3. FunC: fixed compiler crashes for some exotic inputs
4. FunC: added legacy tester, a collection of smart-contracts which is used to check whether compilator update change compilation result
5. Improved archive manager: proper handling of recently garbage-collected blocks
## 2022.12 Update
Node update:
1. Improvements of ton-proxy: fixed few bugs, improved stability
2. Improved collator/validator checks, added optimization of storage stat calculation, generation and validation of new blocks is made safer
3. Some previously hard-coded parameters such as split/merge timings, max sizes and depths of internal and external messages, and others now can be updated by validators through setting ConfigParams. Max contract size added to configs.
4. Tonlib: updated raw.getTransactions (now it contains InitState), fixed long bytestrings truncation
5. abseil-cpp is updated to newer versions
6. Added configs for Token Bridge
7. LiteServers: a few bug fixes, added liteServer.getAccountStatePrunned method, improved work with not yet applied blocks.
8. Improved DHT: works for some NAT configurations, optimized excessive requests, added option for DHT network segregation.
9. FunC v0.4.0: added try/catch statements, added throw_arg functions, allowed in-place modification of global variables, forbidden ambiguous modification of local variables after it's usage in the same expression.
10. TON Storage: added storage-daemon (create, download bag of Files, storage-provider staff), added storage-daemon-cli
Besides the work of the core team, this update is based on the efforts of @vtamara (help with abseil-cpp upgrade), @krigga(in-place modification of global variables) and third-party security auditors.
## 2022.10 Update
* Added extended block creation and general perfomance stats gathering
* Forbidden report data on blocks not committed to the master chain for LS
* Improved debug in TVM
* FunC 0.3.0: multi-line asms, bitwise operations for constants, duplication of identical definition for constants and asms now allowed
* New tonlib methods: sendMessageReturnHash, getTransactionsV2, getMasterchainBlockSignatures, getShardBlockProof, getLibraries.
* Fixed bugs related to invalid TVM output (c4, c5, libaries) and non-validated network data; avoided too deep recursion in libraries loading
* Fixed multiple undefined behavior issues
* Added build of FunC and Fift to WASM
Besides the work of the core team, this update is based on the efforts of @tvorogme (debug improvements), @AlexeyFSL (WASM builds) and third-party security auditors.
## 2022.08 Update
* Blockchain state serialization now works via separate db-handler which simplfies memory clearing after serialization
* CellDB now works asynchronously which substantially increase database access throughput
* Abseil-cpp and crc32 updated: solve issues with compilation on recent OS distributives
* Fixed a series of UBs and issues for exotic endianness hosts
* Added detailed network stats for overlays (can be accessed via `validator-console`)
* Improved auto-builds for wide range of systems.
* Added extended error information for unaccepted external messages: `exit_code` and TVM trace (where applicable).
* [Improved catchain DoS resistance](https://github.com/ton-blockchain/ton/blob/master/doc/catchain-dos.md)
* A series of FunC improvements, summarized [here](https://github.com/ton-blockchain/ton/pull/378)
#### Update delay
Update coincided with persistent state serialization event which lead to block production speed deterioration (issue substantially mitigated in update itself). This phenomena was aggravated by the fact that after update some validators lost ability to participate in block creation. The last was caused by threshold based hardcoded protocol version bump, where threshold was set in such manner (based on block height with value higher than 9m), that it eluded detection in private net tests. The update was temporarily paused and resumed after persistent state serialization ended and issues with block creation were resolved.
Besides the work of the core team, this update is based on the efforts of @awesome-doge (help with abseil-cpp upgrade), @rec00rsiff (noted issues for exotic endianess and implemented network stats) and third-party security auditors.
## 2022.05 Update
* Initial synchronization improved: adjusted timeouts for state download and the way of choosing which state to download. Nodes with low network speed and/or bad connectivity will synchronize faster and consistently.
* Improved peer-to-peer network stability and DDoS resistance: now peers will only relay valid messages to the network. Large messages, which require splitting for relaying, will be retranslated as well, but only after the node gets all parts, and reassembles and checks them. Validators may sign certificates for network peers, which allow relaying large messages by parts without checks. It is used now by validators to faster relay new blocks. Sign and import certificate commands are exposed via `validator-engine-console`.
* Fixed some rare edge cases in TVM arithmetic operations related to big numbers (`2**63+`)
* Improved fixes used to combat wrong activate-destruct-activate contract behavior last November.
* Improved tonlib: support libraries (with client-side caching), getmethods completely fill c7 register, getmethods support slice arguments, improved messages listing for transactions, added extended block header params, added getConfig method.
* RocksDB updated to a newer version.
* Improved persistent state serialization: memory usage during serialization was optimized; the start of serialization on different nodes was sparsed.
* FunC update: support for string literals and constants (including precompiled constant expressions), semver, `include` expressions.
* Fixed rarely manifested bugs in `Asm.fif`.
* LiteClient supports key as cli parameter.
* Improved Liteserver DoS resistance for running getmethods.
Besides the work of the core team, this update is based on the efforts of @tvorogme (added support for slice arguments and noted bugs in Asm.fif), @akifoq (fixed bug in Asm.fif), @cryshado (noted strange behavior of LS, which, upon inspection, turned out to be a vector of DoS attack).

39
Dockerfile Normal file
View file

@ -0,0 +1,39 @@
FROM ubuntu:22.04 as builder
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y build-essential cmake clang openssl libssl-dev zlib1g-dev gperf wget git ninja-build libsecp256k1-dev libsodium-dev libmicrohttpd-dev liblz4-dev pkg-config autoconf automake libtool && \
rm -rf /var/lib/apt/lists/*
ENV CC clang
ENV CXX clang++
ENV CCACHE_DISABLE 1
WORKDIR /
RUN mkdir ton
WORKDIR /ton
COPY ./ ./
RUN mkdir build && \
cd build && \
cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DPORTABLE=1 -DTON_ARCH= .. && \
ninja storage-daemon storage-daemon-cli tonlibjson fift func validator-engine validator-engine-console generate-random-id dht-server lite-client
FROM ubuntu:22.04
RUN apt-get update && \
apt-get install -y wget libatomic1 openssl libsecp256k1-dev libsodium-dev libmicrohttpd-dev liblz4-dev && \
rm -rf /var/lib/apt/lists/*
RUN mkdir -p /var/ton-work/db && \
mkdir -p /var/ton-work/db/static
COPY --from=builder /ton/build/storage/storage-daemon/storage-daemon /usr/local/bin/
COPY --from=builder /ton/build/storage/storage-daemon/storage-daemon-cli /usr/local/bin/
COPY --from=builder /ton/build/lite-client/lite-client /usr/local/bin/
COPY --from=builder /ton/build/validator-engine/validator-engine /usr/local/bin/
COPY --from=builder /ton/build/validator-engine-console/validator-engine-console /usr/local/bin/
COPY --from=builder /ton/build/utils/generate-random-id /usr/local/bin/
WORKDIR /var/ton-work/db
COPY ./docker/init.sh ./docker/control.template ./
RUN chmod +x init.sh
ENTRYPOINT ["/var/ton-work/db/init.sh"]

18
GPLv2
View file

@ -1,4 +1,4 @@
/*
/*
This file is part of TON Blockchain source code.
TON Blockchain is free software; you can redistribute it and/or
@ -14,14 +14,14 @@
You should have received a copy of the GNU General Public License
along with TON Blockchain. If not, see <http://www.gnu.org/licenses/>.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
You must obey the GNU General Public License in all respects for all
of the code used other than OpenSSL. If you modify file(s) with this
exception, you may extend this exception to your version of the file(s),
but you are not obligated to do so. If you do not wish to do so, delete this
exception statement from your version. If you delete this exception statement
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
You must obey the GNU General Public License in all respects for all
of the code used other than OpenSSL. If you modify file(s) with this
exception, you may extend this exception to your version of the file(s),
but you are not obligated to do so. If you do not wish to do so, delete this
exception statement from your version. If you delete this exception statement
from all source files in the program, then also delete it here.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/

2
LGPLv2
View file

@ -14,5 +14,5 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/

159
README.md Normal file
View file

@ -0,0 +1,159 @@
<div align="center">
<a href="https://ton.org">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://ton.org/download/ton_logo_dark_background.svg">
<img alt="TON logo" src="https://ton.org/download/ton_logo_light_background.svg">
</picture>
</a>
<h3>Reference implementation of TON Node and tools</h3>
<hr/>
</div>
##
<p align="center">
<a href="https://tonresear.ch">
<img src="https://img.shields.io/badge/TON%20Research-0098EA?style=flat&logo=discourse&label=Forum&labelColor=gray" alt="Ton Research">
</a>
<a href="https://t.me/toncoin">
<img src="https://img.shields.io/badge/TON%20Community-0098EA?logo=telegram&logoColor=white&style=flat" alt="Telegram Community Group">
</a>
<a href="https://t.me/tonblockchain">
<img src="https://img.shields.io/badge/TON%20Foundation-0098EA?logo=telegram&logoColor=white&style=flat" alt="Telegram Foundation Group">
</a>
<a href="https://t.me/tondev_eng">
<img src="https://img.shields.io/badge/chat-TONDev-0098EA?logo=telegram&logoColor=white&style=flat" alt="Telegram Community Chat">
</a>
</p>
<p align="center">
<a href="https://twitter.com/ton_blockchain">
<img src="https://img.shields.io/twitter/follow/ton_blockchain" alt="Twitter Group">
</a>
<a href="https://answers.ton.org">
<img src="https://img.shields.io/badge/-TON%20Overflow-FE7A16?style=flat&logo=stack-overflow&logoColor=white" alt="TON Overflow Group">
</a>
<a href="https://stackoverflow.com/questions/tagged/ton">
<img src="https://img.shields.io/badge/-Stack%20Overflow-FE7A16?style=flat&logo=stack-overflow&logoColor=white" alt="Stack Overflow Group">
</a>
</p>
Main TON monorepo, which includes the code of the node/validator, lite-client, tonlib, FunC compiler, etc.
## The Open Network
__The Open Network (TON)__ is a fast, secure, scalable blockchain focused on handling _millions of transactions per second_ (TPS) with the goal of reaching hundreds of millions of blockchain users.
- To learn more about different aspects of TON blockchain and its underlying ecosystem check [documentation](https://ton.org/docs)
- To run node, validator or lite-server check [Participate section](https://ton.org/docs/participate/nodes/run-node)
- To develop decentralised apps check [Tutorials](https://ton.org/docs/develop/smart-contracts/), [FunC docs](https://ton.org/docs/develop/func/overview) and [DApp tutorials](https://ton.org/docs/develop/dapps/)
- To work on TON check [wallets](https://ton.app/wallets), [explorers](https://ton.app/explorers), [DEXes](https://ton.app/dex) and [utilities](https://ton.app/utilities)
- To interact with TON check [APIs](https://ton.org/docs/develop/dapps/apis/)
## Updates flow
* **master branch** - mainnet is running on this stable branch.
Only emergency updates, urgent updates, or updates that do not affect the main codebase (GitHub workflows / docker images / documentation) are committed directly to this branch.
* **testnet branch** - testnet is running on this branch. The branch contains a set of new updates. After testing, the testnet branch is merged into the master branch and then a new set of updates is added to testnet branch.
* **backlog** - other branches that are candidates to getting into the testnet branch in the next iteration.
Usually, the response to your pull request will indicate which section it falls into.
## "Soft" Pull Request rules
* Thou shall not merge your own PRs, at least one person should review the PR and merge it (4-eyes rule)
* Thou shall make sure that workflows are cleanly completed for your PR before considering merge
## Build TON blockchain
### Ubuntu 20.4, 22.04 (x86-64, aarch64)
Install additional system libraries
```bash
sudo apt-get update
sudo apt-get install -y build-essential git cmake ninja-build zlib1g-dev libsecp256k1-dev libmicrohttpd-dev libsodium-dev
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 16 all
```
Compile TON binaries
```bash
cp assembly/native/build-ubuntu-shared.sh .
chmod +x build-ubuntu-shared.sh
./build-ubuntu-shared.sh
```
### MacOS 11, 12 (x86-64, aarch64)
```bash
cp assembly/native/build-macos-shared.sh .
chmod +x build-macos-shared.sh
./build-macos-shared.sh
```
### Windows 10, 11, Server (x86-64)
You need to install `MS Visual Studio 2022` first.
Go to https://www.visualstudio.com/downloads/ and download `MS Visual Studio 2022 Community`.
Launch installer and select `Desktop development with C++`.
After installation, also make sure that `cmake` is globally available by adding
`C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin` to the system `PATH` (adjust the path per your needs).
Open an elevated (Run as Administrator) `x86-64 Native Tools Command Prompt for VS 2022`, go to the root folder and execute:
```bash
copy assembly\native\build-windows.bat .
build-windows.bat
```
### Building TON to WebAssembly
Install additional system libraries on Ubuntu
```bash
sudo apt-get update
sudo apt-get install -y build-essential git cmake ninja-build zlib1g-dev libsecp256k1-dev libmicrohttpd-dev libsodium-dev
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 16 all
```
Compile TON binaries with emscripten
```bash
cd assembly/wasm
chmod +x fift-func-wasm-build-ubuntu.sh
./fift-func-wasm-build-ubuntu.sh
```
### Building TON tonlib library for Android (arm64-v8a, armeabi-v7a, x86, x86-64)
Install additional system libraries on Ubuntu
```bash
sudo apt-get update
sudo apt-get install -y build-essential git cmake ninja-build automake libtool texinfo autoconf libgflags-dev \
zlib1g-dev libssl-dev libreadline-dev libmicrohttpd-dev pkg-config libgsl-dev python3 python3-dev \
libtool autoconf libsodium-dev libsecp256k1-dev
```
Compile TON tonlib library
```bash
cp assembly/android/build-android-tonlib.sh .
chmod +x build-android-tonlib.sh
./build-android-tonlib.sh
```
### Build TON portable binaries with Nix package manager
You need to install Nix first.
```bash
sh <(curl -L https://nixos.org/nix/install) --daemon
```
Then compile TON with Nix by executing below command from the root folder:
```bash
cp -r assembly/nix/* .
export NIX_PATH=nixpkgs=https://github.com/nixOS/nixpkgs/archive/23.05.tar.gz
nix-build linux-x86-64-static.nix
```
More examples for other platforms can be found under `assembly/nix`.
## Running tests
Tests are executed by running `ctest` in the build directory. See `doc/Tests.md` for more information.

View file

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
#BEGIN internal
if (NOT TON_ONLY_TONLIB)
@ -42,6 +42,7 @@ set(ADNL_SOURCE
adnl-message.cpp
adnl-network-manager.cpp
adnl-node.cpp
adnl-node-id.cpp
adnl-packet.cpp
adnl-peer-table.cpp
adnl-peer.cpp
@ -88,20 +89,22 @@ target_link_libraries(adnl PUBLIC tdactor ton_crypto tl_api tdnet tddb keys keyr
add_executable(adnl-proxy ${ADNL_PROXY_SOURCE})
target_include_directories(adnl-proxy PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>)
target_link_libraries(adnl-proxy PUBLIC tdactor ton_crypto tl_api tdnet common
tl-utils)
tl-utils git)
add_executable(adnl-pong adnl-pong.cpp)
target_include_directories(adnl-pong PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>)
target_link_libraries(adnl-pong PUBLIC tdactor ton_crypto tl_api tdnet common
tl-utils adnl dht)
tl-utils adnl dht git)
add_library(adnltest STATIC ${ADNL_TEST_SOURCE})
target_include_directories(adnltest PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>)
target_link_libraries(adnltest PUBLIC adnl )
install(TARGETS adnl-proxy RUNTIME DESTINATION bin)
endif()
#END internal
add_library(adnllite STATIC ${ADNL_LITE_SOURCE})
target_include_directories(adnllite PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>)
target_link_libraries(adnllite PUBLIC tdactor ton_crypto tl_lite_api tdnet keys )
target_link_libraries(adnllite PUBLIC tdactor ton_crypto tl_lite_api tdnet keys)

View file

@ -14,13 +14,14 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "adnl-address-list.hpp"
#include "adnl-peer-table.h"
#include "auto/tl/ton_api.hpp"
#include "td/utils/overloaded.h"
#include "td/net/UdpServer.h"
#include "keys/encryptor.h"
namespace ton {
@ -38,6 +39,9 @@ class AdnlNetworkConnectionUdp : public AdnlNetworkConnection {
void start_up() override {
callback_->on_change_state(true);
}
void get_ip_str(td::Promise<td::string> promise) override {
promise.set_value(PSTRING() << addr_.get_ip_str().str() << ":" << addr_.get_port());
}
AdnlNetworkConnectionUdp(td::actor::ActorId<AdnlNetworkManager> network_manager, td::uint32 ip, td::uint16 port,
std::unique_ptr<AdnlNetworkConnection::Callback> callback);
@ -50,6 +54,62 @@ class AdnlNetworkConnectionUdp : public AdnlNetworkConnection {
std::unique_ptr<AdnlNetworkConnection::Callback> callback_;
};
class AdnlNetworkConnectionTunnel : public AdnlNetworkConnection {
public:
void send(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::uint32 priority, td::BufferSlice message) override {
if (!encryptor_) {
VLOG(ADNL_INFO) << "tunnel: message [" << src << "->" << dst << "to bad tunnel. dropping";
return;
}
auto dataR = encryptor_->encrypt(message.as_slice());
if (dataR.is_error()) {
VLOG(ADNL_INFO) << "tunnel: message [" << src << "->" << dst << ": failed to encrypt: " << dataR.move_as_error();
return;
}
auto data = dataR.move_as_ok();
td::BufferSlice enc_message{data.size() + 32};
auto S = enc_message.as_slice();
S.copy_from(pub_key_hash_.as_slice());
S.remove_prefix(32);
S.copy_from(data.as_slice());
td::actor::send_closure(adnl_, &Adnl::send_message_ex, src, adnl_id_, std::move(enc_message),
Adnl::SendFlags::direct_only);
}
bool is_alive() const override {
return ready_.load(std::memory_order_consume);
}
bool is_active() const override {
return ready_.load(std::memory_order_consume);
}
void start_up() override {
auto R = pub_key_.create_encryptor();
if (R.is_error()) {
VLOG(ADNL_INFO) << "tunnel: bad public key: " << R.move_as_error();
return;
}
encryptor_ = R.move_as_ok();
pub_key_hash_ = pub_key_.compute_short_id();
//ready_.store(true, std::memory_order_release);
}
void get_ip_str(td::Promise<td::string> promise) override {
promise.set_value("tunnel");
}
AdnlNetworkConnectionTunnel(td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl,
adnl::AdnlNodeIdShort adnl_id, PublicKey pubkey,
std::unique_ptr<AdnlNetworkConnection::Callback> callback);
private:
td::actor::ActorId<AdnlNetworkManager> network_manager_;
td::actor::ActorId<Adnl> adnl_;
AdnlNodeIdShort adnl_id_;
PublicKey pub_key_;
PublicKeyHash pub_key_hash_;
std::unique_ptr<Encryptor> encryptor_;
std::atomic<bool> ready_{false};
std::unique_ptr<AdnlNetworkConnection::Callback> callback_;
};
void AdnlNetworkConnectionUdp::send(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::uint32 priority,
td::BufferSlice message) {
LOG_CHECK(message.size() <= AdnlNetworkManager::get_mtu()) << "dst=" << addr_ << " size=" << message.size();
@ -71,12 +131,23 @@ AdnlNetworkConnectionUdp::AdnlNetworkConnectionUdp(td::actor::ActorId<AdnlNetwor
addr_.init_host_port(td::IPAddress::ipv6_to_str(ip.as_slice()), port).ensure();
}
AdnlNetworkConnectionTunnel::AdnlNetworkConnectionTunnel(td::actor::ActorId<AdnlNetworkManager> network_manager,
td::actor::ActorId<Adnl> adnl, adnl::AdnlNodeIdShort adnl_id,
PublicKey pubkey,
std::unique_ptr<AdnlNetworkConnection::Callback> callback)
: network_manager_(std::move(network_manager))
, adnl_(std::move(adnl))
, adnl_id_(adnl_id)
, pub_key_(std::move(pubkey))
, callback_(std::move(callback)) {
}
AdnlAddressImpl::Hash AdnlAddressImpl::get_hash() const {
return get_tl_object_sha_bits256(tl());
}
td::actor::ActorOwn<AdnlNetworkConnection> AdnlAddressUdp::create_connection(
td::actor::ActorId<AdnlNetworkManager> network_manager,
td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl,
std::unique_ptr<AdnlNetworkConnection::Callback> callback) const {
return td::actor::create_actor<AdnlNetworkConnectionUdp>("udpconn", network_manager, ip_, port_, std::move(callback));
}
@ -87,7 +158,7 @@ AdnlAddressUdp::AdnlAddressUdp(const ton_api::adnl_address_udp &obj) {
}
td::actor::ActorOwn<AdnlNetworkConnection> AdnlAddressUdp6::create_connection(
td::actor::ActorId<AdnlNetworkManager> network_manager,
td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl,
std::unique_ptr<AdnlNetworkConnection::Callback> callback) const {
return td::actor::create_actor<AdnlNetworkConnectionUdp>("udpconn", network_manager, ip_, port_, std::move(callback));
}
@ -97,16 +168,25 @@ AdnlAddressUdp6::AdnlAddressUdp6(const ton_api::adnl_address_udp6 &obj) {
port_ = static_cast<td::uint16>(obj.port_);
}
td::actor::ActorOwn<AdnlNetworkConnection> AdnlAddressTunnel::create_connection(
td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl,
std::unique_ptr<AdnlNetworkConnection::Callback> callback) const {
return td::actor::create_actor<AdnlNetworkConnectionTunnel>("tunnelconn", network_manager, adnl, adnl_id_, pub_key_,
std::move(callback));
}
AdnlAddressTunnel::AdnlAddressTunnel(const ton_api::adnl_address_tunnel &obj) {
adnl_id_ = AdnlNodeIdShort{obj.to_};
pub_key_ = ton::PublicKey{obj.pubkey_};
}
td::Ref<AdnlAddressImpl> AdnlAddressImpl::create(const tl_object_ptr<ton_api::adnl_Address> &addr) {
td::Ref<AdnlAddressImpl> res = td::Ref<AdnlAddressImpl>{};
ton_api::downcast_call(*const_cast<ton_api::adnl_Address *>(addr.get()),
td::overloaded(
[&](const ton_api::adnl_address_udp &obj) {
res = td::Ref<AdnlAddressUdp>{true, obj};
},
[&](const ton_api::adnl_address_udp6 &obj) {
res = td::Ref<AdnlAddressUdp6>{true, obj};
}));
ton_api::downcast_call(
*const_cast<ton_api::adnl_Address *>(addr.get()),
td::overloaded([&](const ton_api::adnl_address_udp &obj) { res = td::make_ref<AdnlAddressUdp>(obj); },
[&](const ton_api::adnl_address_udp6 &obj) { res = td::make_ref<AdnlAddressUdp6>(obj); },
[&](const ton_api::adnl_address_tunnel &obj) { res = td::make_ref<AdnlAddressTunnel>(obj); },
[&](const ton_api::adnl_address_reverse &obj) { res = td::make_ref<AdnlAddressReverse>(); }));
return res;
}
@ -123,7 +203,12 @@ AdnlAddressList::AdnlAddressList(const tl_object_ptr<ton_api::adnl_addressList>
version_ = static_cast<td::uint32>(addrs->version_);
std::vector<td::Ref<AdnlAddressImpl>> vec;
for (auto &addr : addrs->addrs_) {
vec.push_back(AdnlAddressImpl::create(addr));
auto obj = AdnlAddressImpl::create(addr);
if (obj->is_reverse()) {
has_reverse_ = true;
} else {
vec.push_back(std::move(obj));
}
}
addrs_ = std::move(vec);
reinit_date_ = addrs->reinit_date_;
@ -136,6 +221,9 @@ tl_object_ptr<ton_api::adnl_addressList> AdnlAddressList::tl() const {
for (auto &v : addrs_) {
addrs.emplace_back(v->tl());
}
if (has_reverse_) {
addrs.push_back(create_tl_object<ton_api::adnl_address_reverse>());
}
return create_tl_object<ton_api::adnl_addressList>(std::move(addrs), version_, reinit_date_, priority_, expire_at_);
}
@ -155,6 +243,16 @@ td::Result<AdnlAddressList> AdnlAddressList::create(const tl_object_ptr<ton_api:
return A;
}
td::Status AdnlAddressList::add_udp_address(td::IPAddress addr) {
if (addr.is_ipv4()) {
auto r = td::make_ref<AdnlAddressUdp>(addr.get_ipv4(), static_cast<td::uint16>(addr.get_port()));
addrs_.push_back(std::move(r));
return td::Status::OK();
} else {
return td::Status::Error(ErrorCode::protoviolation, "only works with ipv4");
}
}
} // namespace adnl
} // namespace ton

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
@ -25,6 +25,8 @@ namespace ton {
namespace adnl {
class Adnl;
class AdnlAddressImpl : public td::CntObject {
public:
using Hash = td::Bits256;
@ -35,8 +37,11 @@ class AdnlAddressImpl : public td::CntObject {
virtual td::uint32 serialized_size() const = 0;
virtual tl_object_ptr<ton_api::adnl_Address> tl() const = 0;
virtual td::actor::ActorOwn<AdnlNetworkConnection> create_connection(
td::actor::ActorId<AdnlNetworkManager> network_manager,
td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl,
std::unique_ptr<AdnlNetworkConnection::Callback> callback) const = 0;
virtual bool is_reverse() const {
return false;
}
static td::Ref<AdnlAddressImpl> create(const tl_object_ptr<ton_api::adnl_Address> &addr);
};
@ -52,6 +57,7 @@ class AdnlAddressList {
td::int32 priority_;
td::int32 expire_at_;
std::vector<AdnlAddress> addrs_;
bool has_reverse_{false};
public:
static constexpr td::uint32 max_serialized_size() {
@ -88,9 +94,10 @@ class AdnlAddressList {
void add_addr(AdnlAddress addr) {
addrs_.push_back(addr);
}
void update(td::IPAddress addr);
bool public_only() const;
td::uint32 size() const {
return static_cast<td::uint32>(addrs_.size());
return td::narrow_cast<td::uint32>(addrs_.size());
}
td::uint32 serialized_size() const;
tl_object_ptr<ton_api::adnl_addressList> tl() const;
@ -98,6 +105,14 @@ class AdnlAddressList {
}
static td::Result<AdnlAddressList> create(const tl_object_ptr<ton_api::adnl_addressList> &addr_list);
td::Status add_udp_address(td::IPAddress addr);
void set_reverse(bool x = true) {
has_reverse_ = x;
}
bool has_reverse() const {
return has_reverse_;
}
};
} // namespace adnl

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
@ -51,7 +51,7 @@ class AdnlAddressUdp : public AdnlAddressImpl {
return create_tl_object<ton_api::adnl_address_udp>(ip_, port_);
}
td::actor::ActorOwn<AdnlNetworkConnection> create_connection(
td::actor::ActorId<AdnlNetworkManager> network_manager,
td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl,
std::unique_ptr<AdnlNetworkConnection::Callback> callback) const override;
};
@ -81,10 +81,66 @@ class AdnlAddressUdp6 : public AdnlAddressImpl {
return create_tl_object<ton_api::adnl_address_udp6>(ip_, port_);
}
td::actor::ActorOwn<AdnlNetworkConnection> create_connection(
td::actor::ActorId<AdnlNetworkManager> network_manager,
td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl,
std::unique_ptr<AdnlNetworkConnection::Callback> callback) const override;
};
class AdnlAddressTunnel : public AdnlAddressImpl {
private:
AdnlNodeIdShort adnl_id_;
PublicKey pub_key_;
public:
explicit AdnlAddressTunnel(const ton_api::adnl_address_tunnel &obj);
AdnlAddressTunnel(AdnlNodeIdShort adnl_id, PublicKey pub_key)
: adnl_id_(std::move(adnl_id)), pub_key_(std::move(pub_key)) {
}
AdnlAddressTunnel *make_copy() const override {
return new AdnlAddressTunnel{*this};
}
bool is_public() const override {
return false;
}
td::uint32 serialized_size() const override {
return 4 + 32 + pub_key_.serialized_size();
}
tl_object_ptr<ton_api::adnl_Address> tl() const override {
return create_tl_object<ton_api::adnl_address_tunnel>(adnl_id_.bits256_value(), pub_key_.tl());
}
td::actor::ActorOwn<AdnlNetworkConnection> create_connection(
td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl,
std::unique_ptr<AdnlNetworkConnection::Callback> callback) const override;
};
class AdnlAddressReverse : public AdnlAddressImpl {
public:
AdnlAddressReverse *make_copy() const override {
return new AdnlAddressReverse();
}
bool is_public() const override {
return true;
}
td::uint32 serialized_size() const override {
return 4;
}
tl_object_ptr<ton_api::adnl_Address> tl() const override {
return create_tl_object<ton_api::adnl_address_reverse>();
}
td::actor::ActorOwn<AdnlNetworkConnection> create_connection(
td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl,
std::unique_ptr<AdnlNetworkConnection::Callback> callback) const override {
LOG(ERROR) << "Cannot create connection for AdnlAddressReverse";
return {};
}
bool is_reverse() const override {
return true;
}
};
} // namespace adnl
} // namespace ton

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "adnl-channel.hpp"
#include "adnl-peer.h"
@ -111,13 +111,15 @@ void AdnlChannelImpl::send_message(td::uint32 priority, td::actor::ActorId<AdnlN
td::actor::send_closure(conn, &AdnlNetworkConnection::send, local_id_, peer_id_, priority, std::move(B));
}
void AdnlChannelImpl::receive(td::BufferSlice data) {
void AdnlChannelImpl::receive(td::IPAddress addr, td::BufferSlice data) {
auto P = td::PromiseCreator::lambda(
[peer = peer_pair_, channel_id = channel_in_id_, id = print_id()](td::Result<AdnlPacket> R) {
[peer = peer_pair_, channel_id = channel_in_id_, addr, id = print_id()](td::Result<AdnlPacket> R) {
if (R.is_error()) {
VLOG(ADNL_WARNING) << id << ": dropping IN message: can not decrypt: " << R.move_as_error();
} else {
td::actor::send_closure(peer, &AdnlPeerPair::receive_packet_from_channel, channel_id, R.move_as_ok());
auto packet = R.move_as_ok();
packet.set_remote_addr(addr);
td::actor::send_closure(peer, &AdnlPeerPair::receive_packet_from_channel, channel_id, std::move(packet));
}
});

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
@ -35,7 +35,7 @@ class AdnlChannel : public td::actor::Actor {
AdnlNodeIdShort local_id, AdnlNodeIdShort peer_id,
AdnlChannelIdShort &out_id, AdnlChannelIdShort &in_id,
td::actor::ActorId<AdnlPeerPair> peer_pair);
virtual void receive(td::BufferSlice data) = 0;
virtual void receive(td::IPAddress addr, td::BufferSlice data) = 0;
virtual void send_message(td::uint32 priority, td::actor::ActorId<AdnlNetworkConnection> conn,
td::BufferSlice data) = 0;
virtual ~AdnlChannel() = default;

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
@ -33,7 +33,7 @@ class AdnlChannelImpl : public AdnlChannel {
AdnlChannelIdShort in_id, AdnlChannelIdShort out_id, std::unique_ptr<Encryptor> encryptor,
std::unique_ptr<Decryptor> decryptor);
void decrypt(td::BufferSlice data, td::Promise<AdnlPacket> promise);
void receive(td::BufferSlice data) override;
void receive(td::IPAddress addr, td::BufferSlice data) override;
void send_message(td::uint32 priority, td::actor::ActorId<AdnlNetworkConnection> conn, td::BufferSlice data) override;
struct AdnlChannelPrintId {

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "adnl-db.hpp"
#include "td/db/RocksDb.h"

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "adnl-ext-client.hpp"
#include "adnl-ext-client.h"

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
@ -80,6 +80,9 @@ class AdnlExtClientImpl : public AdnlExtClient {
if (!conn_.empty() && conn_.get() == conn) {
callback_->on_stop_ready();
conn_ = {};
for (auto& q : out_queries_) {
td::actor::send_closure(q.second, &AdnlQuery::set_error, td::Status::Error(ErrorCode::cancelled));
}
alarm_timestamp() = next_create_at_;
try_stop();
}

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "adnl-ext-connection.hpp"

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "adnl-ext-server.hpp"
#include "keys/encryptor.h"

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "td/utils/crypto.h"
#include "td/utils/Random.h"
@ -40,13 +40,15 @@ AdnlAddressList AdnlLocalId::get_addr_list() const {
return addr_list_;
}
void AdnlLocalId::receive(td::BufferSlice data) {
void AdnlLocalId::receive(td::IPAddress addr, td::BufferSlice data) {
auto P = td::PromiseCreator::lambda(
[peer_table = peer_table_, dst = short_id_, id = print_id()](td::Result<AdnlPacket> R) {
[peer_table = peer_table_, dst = short_id_, addr, id = print_id()](td::Result<AdnlPacket> R) {
if (R.is_error()) {
VLOG(ADNL_WARNING) << id << ": dropping IN message: cannot decrypt: " << R.move_as_error();
} else {
td::actor::send_closure(peer_table, &AdnlPeerTable::receive_decrypted_packet, dst, R.move_as_ok());
auto packet = R.move_as_ok();
packet.set_remote_addr(addr);
td::actor::send_closure(peer_table, &AdnlPeerTable::receive_decrypted_packet, dst, std::move(packet));
}
});
@ -77,7 +79,9 @@ void AdnlLocalId::deliver_query(AdnlNodeIdShort src, td::BufferSlice data, td::P
}
VLOG(ADNL_INFO) << this << ": dropping IN message from " << src
<< ": no callbacks for custom query. firstint=" << td::TlParser(s.as_slice()).fetch_int();
promise.set_error(td::Status::Error(ErrorCode::warning, "no callbacks for query"));
promise.set_error(td::Status::Error(ErrorCode::warning, PSTRING() << "dropping IN message from " << src
<< ": no callbacks for custom query. firstint="
<< td::TlParser(s.as_slice()).fetch_int()));
}
void AdnlLocalId::subscribe(std::string prefix, std::unique_ptr<AdnlPeerTable::Callback> callback) {
@ -117,7 +121,7 @@ void AdnlLocalId::update_address_list(AdnlAddressList addr_list) {
}
void AdnlLocalId::publish_address_list() {
if (dht_node_.empty() || addr_list_.empty()) {
if (dht_node_.empty() || addr_list_.empty() || (addr_list_.size() == 0 && !addr_list_.has_reverse())) {
VLOG(ADNL_NOTICE) << this << ": skipping public addr list, because localid (or dht node) not fully initialized";
return;
}
@ -171,19 +175,33 @@ void AdnlLocalId::publish_address_list() {
td::actor::send_closure(keyring_, &keyring::Keyring::sign_message, short_id_.pubkey_hash(), std::move(B),
std::move(P));
if (addr_list_.has_reverse()) {
td::actor::send_closure(
dht_node_, &dht::Dht::register_reverse_connection, id_, [print_id = print_id()](td::Result<td::Unit> R) {
if (R.is_error()) {
VLOG(ADNL_NOTICE) << print_id << ": failed to register reverse connection in DHT: " << R.move_as_error();
} else {
VLOG(ADNL_INFO) << print_id << ": registered reverse connection";
}
});
}
}
AdnlLocalId::AdnlLocalId(AdnlNodeIdFull id, AdnlAddressList addr_list, td::actor::ActorId<AdnlPeerTable> peer_table,
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<dht::Dht> dht_node) {
id_ = std::move(id);
AdnlLocalId::AdnlLocalId(AdnlNodeIdFull id, AdnlAddressList addr_list, td::uint32 mode,
td::actor::ActorId<AdnlPeerTable> peer_table, td::actor::ActorId<keyring::Keyring> keyring,
td::actor::ActorId<dht::Dht> dht_node)
: peer_table_(std::move(peer_table))
, keyring_(std::move(keyring))
, dht_node_(std::move(dht_node))
, addr_list_(std::move(addr_list))
, id_(std::move(id))
, mode_(mode) {
short_id_ = id_.compute_short_id();
addr_list_ = std::move(addr_list);
if (addr_list_.addrs().size() > 0) {
if (!addr_list_.empty()) {
addr_list_.set_reinit_date(Adnl::adnl_start_time());
addr_list_.set_version(static_cast<td::int32>(td::Clocks::system()));
}
peer_table_ = peer_table;
keyring_ = keyring;
dht_node_ = dht_node;
VLOG(ADNL_INFO) << this << ": created local id " << short_id_;
}

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
@ -54,7 +54,7 @@ class AdnlLocalId : public td::actor::Actor {
void decrypt_message(td::BufferSlice data, td::Promise<td::BufferSlice> promise);
void deliver(AdnlNodeIdShort src, td::BufferSlice data);
void deliver_query(AdnlNodeIdShort src, td::BufferSlice data, td::Promise<td::BufferSlice> promise);
void receive(td::BufferSlice data);
void receive(td::IPAddress addr, td::BufferSlice data);
void subscribe(std::string prefix, std::unique_ptr<AdnlPeerTable::Callback> callback);
void unsubscribe(std::string prefix);
@ -67,8 +67,9 @@ class AdnlLocalId : public td::actor::Actor {
void sign_batch_async(std::vector<td::BufferSlice> data,
td::Promise<std::vector<td::Result<td::BufferSlice>>> promise);
AdnlLocalId(AdnlNodeIdFull id, AdnlAddressList addr_list, td::actor::ActorId<AdnlPeerTable> peer_table,
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<dht::Dht> dht_node);
AdnlLocalId(AdnlNodeIdFull id, AdnlAddressList addr_list, td::uint32 mode,
td::actor::ActorId<AdnlPeerTable> peer_table, td::actor::ActorId<keyring::Keyring> keyring,
td::actor::ActorId<dht::Dht> dht_node);
void start_up() override;
void alarm() override;
@ -76,6 +77,10 @@ class AdnlLocalId : public td::actor::Actor {
void update_packet(AdnlPacket packet, bool update_id, bool sign, td::int32 update_addr_list_if,
td::int32 update_priority_addr_list_if, td::Promise<AdnlPacket> promise);
td::uint32 get_mode() {
return mode_;
}
struct PrintId {
AdnlNodeIdShort id;
};
@ -94,6 +99,8 @@ class AdnlLocalId : public td::actor::Actor {
AdnlNodeIdFull id_;
AdnlNodeIdShort short_id_;
td::uint32 mode_;
void publish_address_list();
};

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "adnl/adnl-message.h"
#include "auto/tl/ton_api.hpp"

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
@ -249,6 +249,40 @@ class AdnlMessage {
}
};
class OutboundAdnlMessage {
public:
template <class T>
OutboundAdnlMessage(T m, td::uint32 flags) : message_{std::move(m)}, flags_(flags) {
}
td::uint32 flags() const {
return flags_;
}
void set_flags(td::uint32 f) {
flags_ = f;
}
tl_object_ptr<ton_api::adnl_Message> tl() const {
return message_.tl();
}
td::uint32 size() const {
return message_.size();
}
template <class F>
void visit(F &&f) {
message_.visit(std::move(f));
}
template <class F>
void visit(F &&f) const {
message_.visit(std::move(f));
}
AdnlMessage release() {
return std::move(message_);
}
private:
AdnlMessage message_;
td::uint32 flags_;
};
class AdnlMessageList {
public:
AdnlMessageList() {
@ -291,6 +325,48 @@ class AdnlMessageList {
std::vector<AdnlMessage> messages_;
};
class OutboundAdnlMessageList {
public:
OutboundAdnlMessageList() {
}
OutboundAdnlMessageList(tl_object_ptr<ton_api::adnl_Message> message, td::uint32 flags) {
auto msg = OutboundAdnlMessage{std::move(message), flags};
messages_.emplace_back(std::move(msg));
}
OutboundAdnlMessageList(std::vector<tl_object_ptr<ton_api::adnl_Message>> messages, td::uint32 flags) {
for (auto &message : messages) {
messages_.push_back(OutboundAdnlMessage{std::move(message), flags});
}
}
void push_back(OutboundAdnlMessage message) {
messages_.push_back(std::move(message));
}
td::uint32 size() const {
return static_cast<td::uint32>(messages_.size());
}
tl_object_ptr<ton_api::adnl_Message> one_message() const {
CHECK(size() == 1);
return messages_[0].tl();
}
std::vector<tl_object_ptr<ton_api::adnl_Message>> mult_messages() const {
std::vector<tl_object_ptr<ton_api::adnl_Message>> vec;
for (auto &m : messages_) {
vec.emplace_back(m.tl());
}
return vec;
}
static std::vector<tl_object_ptr<ton_api::adnl_Message>> empty_vector() {
return std::vector<tl_object_ptr<ton_api::adnl_Message>>{};
}
auto &vector() {
return messages_;
}
private:
std::vector<OutboundAdnlMessage> messages_;
};
} // namespace adnl
} // namespace ton

View file

@ -14,11 +14,15 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "adnl-network-manager.hpp"
#include "adnl-peer-table.h"
#include "auto/tl/ton_api.hpp"
#include "td/utils/overloaded.h"
namespace ton {
namespace adnl {
@ -27,25 +31,84 @@ td::actor::ActorOwn<AdnlNetworkManager> AdnlNetworkManager::create(td::uint16 po
return td::actor::create_actor<AdnlNetworkManagerImpl>("NetworkManager", port);
}
void AdnlNetworkManagerImpl::add_listening_udp_port(td::uint16 port) {
AdnlNetworkManagerImpl::OutDesc *AdnlNetworkManagerImpl::choose_out_iface(td::uint8 cat, td::uint32 priority) {
auto it = out_desc_.upper_bound(priority);
while (true) {
if (it == out_desc_.begin()) {
return nullptr;
}
it--;
auto &v = it->second;
for (auto &x : v) {
if (x.cat_mask.test(cat)) {
return &x;
}
}
}
}
size_t AdnlNetworkManagerImpl::add_listening_udp_port(td::uint16 port) {
auto it = port_2_socket_.find(port);
if (it != port_2_socket_.end()) {
return it->second;
}
class Callback : public td::UdpServer::Callback {
public:
Callback(td::actor::ActorShared<AdnlNetworkManagerImpl> manager) : manager_(std::move(manager)) {
Callback(td::actor::ActorShared<AdnlNetworkManagerImpl> manager, size_t idx)
: manager_(std::move(manager)), idx_(idx) {
}
private:
td::actor::ActorShared<AdnlNetworkManagerImpl> manager_;
size_t idx_;
void on_udp_message(td::UdpMessage udp_message) override {
td::actor::send_closure_later(manager_, &AdnlNetworkManagerImpl::receive_udp_message, std::move(udp_message));
td::actor::send_closure_later(manager_, &AdnlNetworkManagerImpl::receive_udp_message, std::move(udp_message),
idx_);
}
};
auto X = td::UdpServer::create("udp server", port, std::make_unique<Callback>(actor_shared(this)));
auto idx = udp_sockets_.size();
auto X = td::UdpServer::create("udp server", port, std::make_unique<Callback>(actor_shared(this), idx));
X.ensure();
udp_servers_.emplace(port, X.move_as_ok());
port_2_socket_[port] = idx;
udp_sockets_.push_back(UdpSocketDesc{port, X.move_as_ok()});
return idx;
}
void AdnlNetworkManagerImpl::receive_udp_message(td::UdpMessage message) {
void AdnlNetworkManagerImpl::add_self_addr(td::IPAddress addr, AdnlCategoryMask cat_mask, td::uint32 priority) {
auto port = td::narrow_cast<td::uint16>(addr.get_port());
size_t idx = add_listening_udp_port(port);
add_in_addr(InDesc{port, nullptr, cat_mask}, idx);
auto d = OutDesc{port, td::IPAddress{}, nullptr, idx};
for (auto &it : out_desc_[priority]) {
if (it == d) {
it.cat_mask |= cat_mask;
return;
}
}
d.cat_mask = cat_mask;
out_desc_[priority].push_back(std::move(d));
}
void AdnlNetworkManagerImpl::add_proxy_addr(td::IPAddress addr, td::uint16 local_port, std::shared_ptr<AdnlProxy> proxy,
AdnlCategoryMask cat_mask, td::uint32 priority) {
size_t idx = add_listening_udp_port(local_port);
add_in_addr(InDesc{local_port, proxy, cat_mask}, idx);
auto d = OutDesc{local_port, addr, proxy, idx};
for (auto &it : out_desc_[priority]) {
if (it == d) {
it.cat_mask |= cat_mask;
return;
}
}
d.cat_mask = cat_mask;
proxy_register(d);
out_desc_[priority].push_back(std::move(d));
}
void AdnlNetworkManagerImpl::receive_udp_message(td::UdpMessage message, size_t idx) {
if (!callback_) {
LOG(ERROR) << this << ": dropping IN message [?->?]: peer table unitialized";
return;
@ -54,58 +117,180 @@ void AdnlNetworkManagerImpl::receive_udp_message(td::UdpMessage message) {
VLOG(ADNL_WARNING) << this << ": dropping ERROR message: " << message.error;
return;
}
if (message.data.size() < 32) {
VLOG(ADNL_WARNING) << this << ": received too small proxy packet of size " << message.data.size();
return;
}
if (message.data.size() >= get_mtu() + 128) {
VLOG(ADNL_NOTICE) << this << ": received huge packet of size " << message.data.size();
}
CHECK(idx < udp_sockets_.size());
auto &socket = udp_sockets_[idx];
AdnlCategoryMask cat_mask;
bool from_proxy = false;
if (socket.allow_proxy) {
td::Bits256 x;
x.as_slice().copy_from(message.data.as_slice().truncate(32));
auto it = proxy_addrs_.find(x);
if (it != proxy_addrs_.end()) {
from_proxy = true;
CHECK(it->second < in_desc_.size());
auto &proxy_iface = in_desc_[it->second];
CHECK(proxy_iface.is_proxy());
auto R = in_desc_[it->second].proxy->decrypt(std::move(message.data));
if (R.is_error()) {
VLOG(ADNL_WARNING) << this << ": failed to decrypt proxy mesage: " << R.move_as_error();
return;
}
auto packet = R.move_as_ok();
if (packet.flags & 1) {
message.address.init_host_port(td::IPAddress::ipv4_to_str(packet.ip), packet.port).ensure();
} else {
message.address = td::IPAddress{};
}
if ((packet.flags & 6) == 6) {
if (proxy_iface.received.packet_is_delivered(packet.adnl_start_time, packet.seqno)) {
VLOG(ADNL_WARNING) << this << ": dropping duplicate proxy packet";
return;
}
}
if (packet.flags & 8) {
if (packet.date < td::Clocks::system() - 60 || packet.date > td::Clocks::system() + 60) {
VLOG(ADNL_WARNING) << this << ": dropping proxy packet: bad time " << packet.date;
return;
}
}
if (!(packet.flags & (1 << 16))) {
VLOG(ADNL_WARNING) << this << ": dropping proxy packet: packet has outbound flag";
return;
}
if (packet.flags & (1 << 17)) {
auto F = fetch_tl_object<ton_api::adnl_ProxyControlPacket>(std::move(packet.data), true);
if (F.is_error()) {
VLOG(ADNL_WARNING) << this << ": dropping proxy packet: bad control packet";
return;
}
ton_api::downcast_call(*F.move_as_ok().get(),
td::overloaded(
[&](const ton_api::adnl_proxyControlPacketPing &f) {
auto &v = *proxy_iface.out_desc;
auto data =
create_serialize_tl_object<ton_api::adnl_proxyControlPacketPong>(f.id_);
AdnlProxy::Packet p;
p.flags = 6 | (1 << 17);
p.ip = 0;
p.port = 0;
p.data = std::move(data);
p.adnl_start_time = Adnl::adnl_start_time();
p.seqno = ++v.out_seqno;
auto enc = v.proxy->encrypt(std::move(p));
td::UdpMessage M;
M.address = v.proxy_addr;
M.data = std::move(enc);
td::actor::send_closure(socket.server, &td::UdpServer::send, std::move(M));
},
[&](const ton_api::adnl_proxyControlPacketPong &f) {},
[&](const ton_api::adnl_proxyControlPacketRegister &f) {}));
return;
}
message.data = std::move(packet.data);
cat_mask = in_desc_[it->second].cat_mask;
}
}
if (!from_proxy) {
if (socket.in_desc == std::numeric_limits<size_t>::max()) {
VLOG(ADNL_WARNING) << this << ": received bad packet to proxy-only listenung port";
return;
}
cat_mask = in_desc_[socket.in_desc].cat_mask;
}
if (message.data.size() >= get_mtu()) {
VLOG(ADNL_NOTICE) << this << ": received huge packet of size " << message.data.size();
}
received_messages_++;
if (received_messages_ % 64 == 0) {
VLOG(ADNL_DEBUG) << this << ": received " << received_messages_ << "udp messages";
VLOG(ADNL_DEBUG) << this << ": received " << received_messages_ << " udp messages";
}
VLOG(ADNL_EXTRA_DEBUG) << this << ": received message of size " << message.data.size();
callback_->receive_packet(message.address, std::move(message.data));
callback_->receive_packet(message.address, cat_mask, std::move(message.data));
}
void AdnlNetworkManagerImpl::send_udp_packet(AdnlNodeIdShort src_id, AdnlNodeIdShort dst_id, td::IPAddress dst_addr,
td::uint32 priority, td::BufferSlice data) {
auto randseed = 1; // use DST?
while (priority > 0) {
if (out_desc_[priority].size() > 0) {
break;
}
priority--;
}
if (out_desc_[priority].size() == 0) {
VLOG(ADNL_WARNING) << this << ": dropping OUT message [" << src_id << "->" << dst_id << "]: no out desc";
auto it = adnl_id_2_cat_.find(src_id);
if (it == adnl_id_2_cat_.end()) {
VLOG(ADNL_WARNING) << this << ": dropping OUT message [" << src_id << "->" << dst_id << "]: unknown src";
return;
}
auto &dv = out_desc_[priority];
auto &v = dv[randseed % dv.size()];
auto out = choose_out_iface(it->second, priority);
if (!out) {
VLOG(ADNL_WARNING) << this << ": dropping OUT message [" << src_id << "->" << dst_id << "]: no out rules";
return;
}
auto &v = *out;
auto &socket = udp_sockets_[v.socket_idx];
if (!v.is_proxy()) {
auto it = udp_servers_.find(static_cast<td::uint16>(v.addr.get_port()));
CHECK(it != udp_servers_.end());
td::UdpMessage M;
M.address = dst_addr;
M.data = std::move(data);
CHECK(M.data.size() <= get_mtu());
td::actor::send_closure(it->second, &td::UdpServer::send, std::move(M));
td::actor::send_closure(socket.server, &td::UdpServer::send, std::move(M));
} else {
auto it = udp_servers_.find(out_udp_port_);
CHECK(it != udp_servers_.end());
AdnlProxy::Packet p;
p.flags = 7;
p.ip = dst_addr.get_ipv4();
p.port = static_cast<td::uint16>(dst_addr.get_port());
p.data = std::move(data);
p.adnl_start_time = Adnl::adnl_start_time();
p.seqno = ++v.out_seqno;
auto enc = v.proxy->encrypt(
AdnlProxy::Packet{dst_addr.get_ipv4(), static_cast<td::uint16>(dst_addr.get_port()), std::move(data)});
auto enc = v.proxy->encrypt(std::move(p));
td::UdpMessage M;
M.address = v.addr;
M.address = v.proxy_addr;
M.data = std::move(enc);
td::actor::send_closure(it->second, &td::UdpServer::send, std::move(M));
td::actor::send_closure(socket.server, &td::UdpServer::send, std::move(M));
}
}
void AdnlNetworkManagerImpl::proxy_register(OutDesc &desc) {
auto data = create_serialize_tl_object<ton_api::adnl_proxyControlPacketRegister>(0, 0);
AdnlProxy::Packet p;
p.flags = 6 | (1 << 17);
p.ip = 0;
p.port = 0;
p.data = std::move(data);
p.adnl_start_time = Adnl::adnl_start_time();
p.seqno = ++desc.out_seqno;
auto enc = desc.proxy->encrypt(std::move(p));
td::UdpMessage M;
M.address = desc.proxy_addr;
M.data = std::move(enc);
auto &socket = udp_sockets_[desc.socket_idx];
td::actor::send_closure(socket.server, &td::UdpServer::send, std::move(M));
}
void AdnlNetworkManagerImpl::alarm() {
alarm_timestamp() = td::Timestamp::in(60.0);
for (auto &vec : out_desc_) {
for (auto &desc : vec.second) {
if (desc.is_proxy()) {
proxy_register(desc);
}
}
}
}

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
@ -26,6 +26,8 @@
#include "adnl-node-id.hpp"
#include "adnl-proxy-types.h"
#include <bitset>
namespace td {
class UdpServer;
}
@ -36,6 +38,8 @@ namespace adnl {
class AdnlPeerTable;
using AdnlCategoryMask = std::bitset<256>;
class AdnlNetworkConnection : public td::actor::Actor {
public:
class Callback {
@ -46,6 +50,8 @@ class AdnlNetworkConnection : public td::actor::Actor {
virtual void send(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::uint32 priority, td::BufferSlice message) = 0;
virtual bool is_alive() const = 0;
virtual bool is_active() const = 0;
virtual void get_ip_str(td::Promise<td::string> promise) = 0;
virtual ~AdnlNetworkConnection() = default;
};
@ -56,7 +62,7 @@ class AdnlNetworkManager : public td::actor::Actor {
public:
virtual ~Callback() = default;
//virtual void receive_packet(td::IPAddress addr, ConnHandle conn_handle, td::BufferSlice data) = 0;
virtual void receive_packet(td::IPAddress addr, td::BufferSlice data) = 0;
virtual void receive_packet(td::IPAddress addr, AdnlCategoryMask cat_mask, td::BufferSlice data) = 0;
};
static td::actor::ActorOwn<AdnlNetworkManager> create(td::uint16 out_port);
@ -64,14 +70,16 @@ class AdnlNetworkManager : public td::actor::Actor {
virtual void install_callback(std::unique_ptr<Callback> callback) = 0;
virtual void add_self_addr(td::IPAddress addr, td::uint32 priority) = 0;
virtual void add_proxy_addr(td::IPAddress addr, std::shared_ptr<AdnlProxy> proxy, td::uint32 priority) = 0;
virtual void add_self_addr(td::IPAddress addr, AdnlCategoryMask cat_mask, td::uint32 priority) = 0;
virtual void add_proxy_addr(td::IPAddress addr, td::uint16 local_port, std::shared_ptr<AdnlProxy> proxy,
AdnlCategoryMask cat_mask, td::uint32 priority) = 0;
virtual void send_udp_packet(AdnlNodeIdShort src_id, AdnlNodeIdShort dst_id, td::IPAddress dst_addr,
td::uint32 priority, td::BufferSlice data) = 0;
//virtual void send_tcp_packet(AdnlNodeIdShort src_id, AdnlNodeIdShort dst_id, td::IPAddress dst_addr,
// td::uint32 priority, td::BufferSlice data) = 0;
//virtual void send_answer_packet(AdnlNodeIdShort src_id, AdnlNodeIdShort dst_id, td::IPAddress dst_addr,
// ConnHandle conn_handle, td::uint32 priority, td::BufferSlice data) = 0;
virtual void set_local_id_category(AdnlNodeIdShort id, td::uint8 cat) = 0;
static constexpr td::uint32 get_mtu() {
return 1440;

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
@ -25,6 +25,7 @@
#include "td/actor/PromiseFuture.h"
#include "adnl-network-manager.h"
#include "adnl-received-mask.h"
#include <map>
@ -41,16 +42,61 @@ class AdnlPeerTable;
class AdnlNetworkManagerImpl : public AdnlNetworkManager {
public:
struct OutDesc {
td::IPAddress addr;
td::uint16 port;
td::IPAddress proxy_addr;
std::shared_ptr<AdnlProxy> proxy;
size_t socket_idx;
td::int64 out_seqno{0};
AdnlCategoryMask cat_mask{0};
bool is_proxy() const {
return proxy != nullptr;
}
bool operator==(const OutDesc &with) const {
return addr == with.addr && is_proxy() == with.is_proxy();
if (port != with.port) {
return false;
}
if (!is_proxy()) {
return !with.is_proxy();
}
if (!with.is_proxy()) {
return false;
}
return proxy_addr == with.proxy_addr && proxy->id() == with.proxy->id();
}
};
struct InDesc {
td::uint16 port;
std::shared_ptr<AdnlProxy> proxy;
AdnlCategoryMask cat_mask;
AdnlReceivedMaskVersion received{};
OutDesc *out_desc = nullptr;
bool is_proxy() const {
return proxy != nullptr;
}
bool operator==(const InDesc &with) const {
if (port != with.port) {
return false;
}
if (!is_proxy()) {
return !with.is_proxy();
}
if (!with.is_proxy()) {
return false;
}
return proxy->id() == with.proxy->id();
}
};
struct UdpSocketDesc {
UdpSocketDesc(td::uint16 port, td::actor::ActorOwn<td::UdpServer> server) : port(port), server(std::move(server)) {
}
td::uint16 port;
td::actor::ActorOwn<td::UdpServer> server;
size_t in_desc{std::numeric_limits<size_t>::max()};
bool allow_proxy{false};
};
OutDesc *choose_out_iface(td::uint8 cat, td::uint32 priority);
AdnlNetworkManagerImpl(td::uint16 out_udp_port) : out_udp_port_(out_udp_port) {
}
@ -59,45 +105,60 @@ class AdnlNetworkManagerImpl : public AdnlNetworkManager {
callback_ = std::move(callback);
}
void add_self_addr(td::IPAddress addr, td::uint32 priority) override {
auto x = OutDesc{addr, nullptr};
auto &v = out_desc_[priority];
for (auto &y : v) {
if (x == y) {
void alarm() override;
void start_up() override {
alarm_timestamp() = td::Timestamp::in(60.0);
}
void add_in_addr(InDesc desc, size_t socket_idx) {
for (size_t idx = 0; idx < in_desc_.size(); idx++) {
if (in_desc_[idx] == desc) {
in_desc_[idx].cat_mask |= desc.cat_mask;
return;
}
}
out_desc_[priority].push_back(std::move(x));
add_listening_udp_port(static_cast<td::uint16>(addr.get_port()));
}
void add_proxy_addr(td::IPAddress addr, std::shared_ptr<AdnlProxy> proxy, td::uint32 priority) override {
auto x = OutDesc{addr, std::move(proxy)};
auto &v = out_desc_[priority];
for (auto &y : v) {
if (x == y) {
return;
}
}
out_desc_[priority].push_back(std::move(x));
if (!udp_servers_.count(out_udp_port_)) {
add_listening_udp_port(out_udp_port_);
if (desc.is_proxy()) {
udp_sockets_[socket_idx].allow_proxy = true;
proxy_addrs_[desc.proxy->id()] = in_desc_.size();
} else {
CHECK(udp_sockets_[socket_idx].in_desc == std::numeric_limits<size_t>::max());
udp_sockets_[socket_idx].in_desc = in_desc_.size();
}
in_desc_.push_back(std::move(desc));
}
void add_self_addr(td::IPAddress addr, AdnlCategoryMask cat_mask, td::uint32 priority) override;
void add_proxy_addr(td::IPAddress addr, td::uint16 local_port, std::shared_ptr<AdnlProxy> proxy,
AdnlCategoryMask cat_mask, td::uint32 priority) override;
void send_udp_packet(AdnlNodeIdShort src_id, AdnlNodeIdShort dst_id, td::IPAddress dst_addr, td::uint32 priority,
td::BufferSlice data) override;
void add_listening_udp_port(td::uint16 port);
void receive_udp_message(td::UdpMessage message);
void set_local_id_category(AdnlNodeIdShort id, td::uint8 cat) override {
if (cat == 255) {
adnl_id_2_cat_.erase(id);
} else {
adnl_id_2_cat_[id] = cat;
}
}
size_t add_listening_udp_port(td::uint16 port);
void receive_udp_message(td::UdpMessage message, size_t idx);
void proxy_register(OutDesc &desc);
private:
std::unique_ptr<Callback> callback_;
std::map<td::uint32, std::vector<OutDesc>> out_desc_;
std::vector<InDesc> in_desc_;
std::map<td::Bits256, size_t> proxy_addrs_;
td::uint64 received_messages_ = 0;
td::uint64 sent_messages_ = 0;
std::map<td::uint16, td::actor::ActorOwn<td::UdpServer>> udp_servers_;
std::vector<UdpSocketDesc> udp_sockets_;
std::map<td::uint16, size_t> port_2_socket_;
std::map<AdnlNodeIdShort, td::uint8> adnl_id_2_cat_;
td::uint16 out_udp_port_;
};

35
adnl/adnl-node-id.cpp Normal file
View file

@ -0,0 +1,35 @@
/*
This file is part of TON Blockchain Library.
TON Blockchain Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
TON Blockchain Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2020 Telegram Systems LLP
*/
#include "adnl-node-id.hpp"
#include "common/util.h"
namespace ton {
namespace adnl {
td::Result<AdnlNodeIdShort> AdnlNodeIdShort::parse(td::Slice id) {
TRY_RESULT(str, td::adnl_id_decode(id));
return AdnlNodeIdShort(str);
}
std::string AdnlNodeIdShort::serialize() {
return adnl_id_encode(hash_.as_slice()).move_as_ok();
}
} // namespace adnl
} // namespace ton

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
@ -75,6 +75,10 @@ class AdnlNodeIdShort {
return hash_.is_zero();
}
static td::Result<AdnlNodeIdShort> parse(td::Slice key);
std::string serialize();
private:
PublicKeyHash hash_;
};

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "adnl-node.h"

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "adnl-packet.h"
#include "td/utils/Random.h"

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
@ -132,6 +132,9 @@ class AdnlPacket {
auto signature() const {
return signature_.clone();
}
auto remote_addr() const {
return remote_addr_;
}
void init_random();
@ -188,6 +191,10 @@ class AdnlPacket {
flags_ |= Flags::f_reinit_date;
}
void set_remote_addr(td::IPAddress addr) {
remote_addr_ = addr;
}
private:
td::BufferSlice rand1_;
td::uint32 flags_{0};
@ -204,6 +211,8 @@ class AdnlPacket {
td::int32 dst_reinit_date_{0};
td::BufferSlice signature_;
td::BufferSlice rand2_;
td::IPAddress remote_addr_;
};
} // namespace adnl

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "adnl-peer-table.hpp"
#include "adnl-peer.h"
@ -30,6 +30,7 @@
#include "utils.hpp"
#include "adnl-query.h"
#include "adnl-ext-client.h"
#include "adnl-tunnel.h"
namespace ton {
@ -49,7 +50,7 @@ td::actor::ActorOwn<Adnl> Adnl::create(std::string db, td::actor::ActorId<keyrin
return td::actor::ActorOwn<Adnl>(td::actor::create_actor<AdnlPeerTableImpl>("PeerTable", db, keyring));
}
void AdnlPeerTableImpl::receive_packet(td::BufferSlice data) {
void AdnlPeerTableImpl::receive_packet(td::IPAddress addr, AdnlCategoryMask cat_mask, td::BufferSlice data) {
if (data.size() < 32) {
VLOG(ADNL_WARNING) << this << ": dropping IN message [?->?]: message too short: len=" << data.size();
return;
@ -58,16 +59,24 @@ void AdnlPeerTableImpl::receive_packet(td::BufferSlice data) {
AdnlNodeIdShort dst{data.as_slice().truncate(32)};
data.confirm_read(32);
auto it = local_ids_own_.find(dst);
if (it != local_ids_own_.end()) {
td::actor::send_closure(it->second, &AdnlLocalId::receive, std::move(data));
auto it = local_ids_.find(dst);
if (it != local_ids_.end()) {
if (!cat_mask.test(it->second.cat)) {
VLOG(ADNL_WARNING) << this << ": dropping IN message [?->" << dst << "]: category mismatch";
return;
}
td::actor::send_closure(it->second.local_id, &AdnlLocalId::receive, addr, std::move(data));
return;
}
AdnlChannelIdShort dst_chan_id{dst.pubkey_hash()};
auto it2 = channels_.find(dst_chan_id);
if (it2 != channels_.end()) {
td::actor::send_closure(it2->second, &AdnlChannel::receive, std::move(data));
if (!cat_mask.test(it2->second.second)) {
VLOG(ADNL_WARNING) << this << ": dropping IN message to channel [?->" << dst << "]: category mismatch";
return;
}
td::actor::send_closure(it2->second.first, &AdnlChannel::receive, addr, std::move(data));
return;
}
@ -103,21 +112,22 @@ void AdnlPeerTableImpl::receive_decrypted_packet(AdnlNodeIdShort dst, AdnlPacket
CHECK(it != peers_.end());
}
auto it2 = local_ids_own_.find(dst);
if (it2 == local_ids_own_.end()) {
auto it2 = local_ids_.find(dst);
if (it2 == local_ids_.end()) {
VLOG(ADNL_ERROR) << this << ": dropping IN message [" << packet.from_short() << "->" << dst
<< "]: unknown dst (but how did we decrypt message?)";
return;
}
td::actor::send_closure(it->second, &AdnlPeer::receive_packet, dst, it2->second.get(), std::move(packet));
td::actor::send_closure(it->second, &AdnlPeer::receive_packet, dst, it2->second.mode, it2->second.local_id.get(),
std::move(packet));
}
void AdnlPeerTableImpl::add_peer(AdnlNodeIdShort local_id, AdnlNodeIdFull id, AdnlAddressList addr_list) {
auto id_short = id.compute_short_id();
VLOG(ADNL_DEBUG) << this << ": adding peer " << id_short << " for local id " << local_id;
auto it2 = local_ids_own_.find(local_id);
CHECK(it2 != local_ids_own_.end());
auto it2 = local_ids_.find(local_id);
CHECK(it2 != local_ids_.end());
auto it = peers_.find(id_short);
if (it == peers_.end()) {
@ -126,7 +136,8 @@ void AdnlPeerTableImpl::add_peer(AdnlNodeIdShort local_id, AdnlNodeIdFull id, Ad
}
td::actor::send_closure(it->second, &AdnlPeer::update_id, std::move(id));
if (!addr_list.empty()) {
td::actor::send_closure(it->second, &AdnlPeer::update_addr_list, local_id, it2->second.get(), std::move(addr_list));
td::actor::send_closure(it->second, &AdnlPeer::update_addr_list, local_id, it2->second.mode,
it2->second.local_id.get(), std::move(addr_list));
}
}
@ -136,20 +147,22 @@ void AdnlPeerTableImpl::add_static_nodes_from_config(AdnlNodesList nodes) {
}
}
void AdnlPeerTableImpl::send_message_in(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlMessage message) {
void AdnlPeerTableImpl::send_message_in(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlMessage message,
td::uint32 flags) {
auto it = peers_.find(dst);
if (it == peers_.end()) {
it = peers_.emplace(dst, AdnlPeer::create(network_manager_, actor_id(this), dht_node_, dst)).first;
}
auto it2 = local_ids_own_.find(src);
if (it2 == local_ids_own_.end()) {
auto it2 = local_ids_.find(src);
if (it2 == local_ids_.end()) {
LOG(ERROR) << this << ": dropping OUT message [" << src << "->" << dst << "]: unknown src";
return;
}
td::actor::send_closure(it->second, &AdnlPeer::send_one_message, src, it2->second.get(), std::move(message));
td::actor::send_closure(it->second, &AdnlPeer::send_one_message, src, it2->second.mode, it2->second.local_id.get(),
OutboundAdnlMessage{std::move(message), flags});
}
void AdnlPeerTableImpl::answer_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlQueryId query_id,
@ -159,7 +172,7 @@ void AdnlPeerTableImpl::answer_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, A
<< "]: message too big: size=" << data.size();
return;
}
send_message_in(src, dst, adnlmessage::AdnlMessageAnswer{query_id, std::move(data)});
send_message_in(src, dst, adnlmessage::AdnlMessageAnswer{query_id, std::move(data)}, 0);
}
void AdnlPeerTableImpl::send_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, std::string name,
@ -175,59 +188,70 @@ void AdnlPeerTableImpl::send_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, std
it = peers_.emplace(dst, AdnlPeer::create(network_manager_, actor_id(this), dht_node_, dst)).first;
}
auto it2 = local_ids_own_.find(src);
if (it2 == local_ids_own_.end()) {
auto it2 = local_ids_.find(src);
if (it2 == local_ids_.end()) {
LOG(ERROR) << this << ": dropping OUT message [" << src << "->" << dst << "]: unknown src";
return;
}
td::actor::send_closure(it->second, &AdnlPeer::send_query, src, it2->second.get(), name, std::move(promise), timeout,
std::move(data));
td::actor::send_closure(it->second, &AdnlPeer::send_query, src, it2->second.mode, it2->second.local_id.get(), name,
std::move(promise), timeout, std::move(data), 0);
}
void AdnlPeerTableImpl::add_id(AdnlNodeIdFull id, AdnlAddressList addr_list) {
void AdnlPeerTableImpl::add_id_ex(AdnlNodeIdFull id, AdnlAddressList addr_list, td::uint8 cat, td::uint32 mode) {
auto a = id.compute_short_id();
VLOG(ADNL_INFO) << "adnl: adding local id " << a;
auto it = local_ids_own_.find(a);
auto it = local_ids_.find(a);
if (it != local_ids_own_.end()) {
td::actor::send_closure(it->second, &AdnlLocalId::update_address_list, std::move(addr_list));
if (it != local_ids_.end()) {
if (it->second.cat != cat) {
it->second.cat = cat;
if (!network_manager_.empty()) {
td::actor::send_closure(network_manager_, &AdnlNetworkManager::set_local_id_category, a, cat);
}
}
td::actor::send_closure(it->second.local_id, &AdnlLocalId::update_address_list, std::move(addr_list));
} else {
local_ids_own_[a] = td::actor::create_actor<AdnlLocalId>("localid", std::move(id), std::move(addr_list),
actor_id(this), keyring_, dht_node_);
local_ids_.emplace(
a, LocalIdInfo{td::actor::create_actor<AdnlLocalId>("localid", std::move(id), std::move(addr_list), mode,
actor_id(this), keyring_, dht_node_),
cat, mode});
if (!network_manager_.empty()) {
td::actor::send_closure(network_manager_, &AdnlNetworkManager::set_local_id_category, a, cat);
}
}
}
void AdnlPeerTableImpl::del_id(AdnlNodeIdShort id, td::Promise<td::Unit> promise) {
VLOG(ADNL_INFO) << "adnl: deleting local id " << id;
local_ids_own_.erase(id);
local_ids_.erase(id);
promise.set_value(td::Unit());
}
void AdnlPeerTableImpl::subscribe(AdnlNodeIdShort dst, std::string prefix, std::unique_ptr<Callback> callback) {
auto it = local_ids_own_.find(dst);
LOG_CHECK(it != local_ids_own_.end()) << "dst=" << dst;
auto it = local_ids_.find(dst);
LOG_CHECK(it != local_ids_.end()) << "dst=" << dst;
td::actor::send_closure(it->second, &AdnlLocalId::subscribe, prefix, std::move(callback));
td::actor::send_closure(it->second.local_id, &AdnlLocalId::subscribe, prefix, std::move(callback));
}
void AdnlPeerTableImpl::unsubscribe(AdnlNodeIdShort dst, std::string prefix) {
auto it = local_ids_own_.find(dst);
auto it = local_ids_.find(dst);
if (it != local_ids_own_.end()) {
td::actor::send_closure(it->second, &AdnlLocalId::unsubscribe, prefix);
if (it != local_ids_.end()) {
td::actor::send_closure(it->second.local_id, &AdnlLocalId::unsubscribe, prefix);
}
}
void AdnlPeerTableImpl::register_dht_node(td::actor::ActorId<dht::Dht> dht_node) {
dht_node_ = dht_node;
for (auto it = peers_.begin(); it != peers_.end(); it++) {
td::actor::send_closure(it->second, &AdnlPeer::update_dht_node, dht_node_);
for (auto &peer : peers_) {
td::actor::send_closure(peer.second, &AdnlPeer::update_dht_node, dht_node_);
}
for (auto it = local_ids_own_.begin(); it != local_ids_own_.end(); it++) {
td::actor::send_closure(it->second, &AdnlLocalId::update_dht_node, dht_node_);
for (auto &local_id : local_ids_) {
td::actor::send_closure(local_id.second.local_id, &AdnlLocalId::update_dht_node, dht_node_);
}
}
@ -236,8 +260,8 @@ void AdnlPeerTableImpl::register_network_manager(td::actor::ActorId<AdnlNetworkM
class Cb : public AdnlNetworkManager::Callback {
public:
void receive_packet(td::IPAddress addr, td::BufferSlice data) override {
td::actor::send_closure(id_, &AdnlPeerTableImpl::receive_packet, std::move(data));
void receive_packet(td::IPAddress addr, AdnlCategoryMask cat_mask, td::BufferSlice data) override {
td::actor::send_closure(id_, &AdnlPeerTableImpl::receive_packet, addr, std::move(cat_mask), std::move(data));
}
Cb(td::actor::ActorId<AdnlPeerTableImpl> id) : id_(id) {
}
@ -248,28 +272,35 @@ void AdnlPeerTableImpl::register_network_manager(td::actor::ActorId<AdnlNetworkM
auto cb = std::make_unique<Cb>(actor_id(this));
td::actor::send_closure(network_manager_, &AdnlNetworkManager::install_callback, std::move(cb));
for (auto &id : local_ids_) {
td::actor::send_closure(network_manager_, &AdnlNetworkManager::set_local_id_category, id.first, id.second.cat);
}
}
void AdnlPeerTableImpl::get_addr_list(AdnlNodeIdShort id, td::Promise<AdnlAddressList> promise) {
auto it = local_ids_own_.find(id);
if (it == local_ids_own_.end()) {
auto it = local_ids_.find(id);
if (it == local_ids_.end()) {
promise.set_error(td::Status::Error(ErrorCode::notready));
return;
}
td::actor::send_closure(it->second, &AdnlLocalId::get_addr_list_async, std::move(promise));
td::actor::send_closure(it->second.local_id, &AdnlLocalId::get_addr_list_async, std::move(promise));
}
void AdnlPeerTableImpl::get_self_node(AdnlNodeIdShort id, td::Promise<AdnlNode> promise) {
auto it = local_ids_own_.find(id);
if (it == local_ids_own_.end()) {
auto it = local_ids_.find(id);
if (it == local_ids_.end()) {
promise.set_error(td::Status::Error(ErrorCode::notready));
return;
}
td::actor::send_closure(it->second, &AdnlLocalId::get_self_node, std::move(promise));
td::actor::send_closure(it->second.local_id, &AdnlLocalId::get_self_node, std::move(promise));
}
void AdnlPeerTableImpl::register_channel(AdnlChannelIdShort id, td::actor::ActorId<AdnlChannel> channel) {
auto success = channels_.emplace(id, channel).second;
void AdnlPeerTableImpl::register_channel(AdnlChannelIdShort id, AdnlNodeIdShort local_id,
td::actor::ActorId<AdnlChannel> channel) {
auto it = local_ids_.find(local_id);
auto cat = (it != local_ids_.end()) ? it->second.cat : 255;
auto success = channels_.emplace(id, std::make_pair(channel, cat)).second;
CHECK(success);
}
@ -309,16 +340,16 @@ AdnlPeerTableImpl::AdnlPeerTableImpl(std::string db_root, td::actor::ActorId<key
}
void AdnlPeerTableImpl::deliver(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::BufferSlice data) {
auto it = local_ids_own_.find(dst);
if (it != local_ids_own_.end()) {
td::actor::send_closure(it->second, &AdnlLocalId::deliver, src, std::move(data));
auto it = local_ids_.find(dst);
if (it != local_ids_.end()) {
td::actor::send_closure(it->second.local_id, &AdnlLocalId::deliver, src, std::move(data));
}
}
void AdnlPeerTableImpl::deliver_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::BufferSlice data,
td::Promise<td::BufferSlice> promise) {
auto it = local_ids_own_.find(dst);
if (it != local_ids_own_.end()) {
td::actor::send_closure(it->second, &AdnlLocalId::deliver_query, src, std::move(data), std::move(promise));
auto it = local_ids_.find(dst);
if (it != local_ids_.end()) {
td::actor::send_closure(it->second.local_id, &AdnlLocalId::deliver_query, src, std::move(data), std::move(promise));
} else {
LOG(WARNING) << "deliver query: unknown dst " << dst;
promise.set_error(td::Status::Error(ErrorCode::notready, "cannot deliver: unknown DST"));
@ -327,9 +358,9 @@ void AdnlPeerTableImpl::deliver_query(AdnlNodeIdShort src, AdnlNodeIdShort dst,
void AdnlPeerTableImpl::decrypt_message(AdnlNodeIdShort dst, td::BufferSlice data,
td::Promise<td::BufferSlice> promise) {
auto it = local_ids_own_.find(dst);
if (it != local_ids_own_.end()) {
td::actor::send_closure(it->second, &AdnlLocalId::decrypt_message, std::move(data), std::move(promise));
auto it = local_ids_.find(dst);
if (it != local_ids_.end()) {
td::actor::send_closure(it->second.local_id, &AdnlLocalId::decrypt_message, std::move(data), std::move(promise));
} else {
LOG(WARNING) << "decrypt message: unknown dst " << dst;
promise.set_error(td::Status::Error(ErrorCode::notready, "cannot decrypt: unknown DST"));
@ -341,6 +372,19 @@ void AdnlPeerTableImpl::create_ext_server(std::vector<AdnlNodeIdShort> ids, std:
promise.set_value(AdnlExtServerCreator::create(actor_id(this), std::move(ids), std::move(ports)));
}
void AdnlPeerTableImpl::create_tunnel(AdnlNodeIdShort dst, td::uint32 size,
td::Promise<std::pair<td::actor::ActorOwn<AdnlTunnel>, AdnlAddress>> promise) {
}
void AdnlPeerTableImpl::get_conn_ip_str(AdnlNodeIdShort l_id, AdnlNodeIdShort p_id, td::Promise<td::string> promise) {
auto it = peers_.find(p_id);
if (it == peers_.end()) {
promise.set_value("undefined");
return;
}
td::actor::send_closure(it->second, &AdnlPeer::get_conn_ip_str, l_id, std::move(promise));
}
} // namespace adnl
} // namespace ton

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
@ -89,11 +89,12 @@ class AdnlPeerTable : public Adnl {
virtual void answer_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlQueryId query_id, td::BufferSlice data) = 0;
virtual void receive_packet(td::BufferSlice data) = 0;
virtual void receive_packet(td::IPAddress addr, AdnlCategoryMask cat_mask, td::BufferSlice data) = 0;
virtual void receive_decrypted_packet(AdnlNodeIdShort dst, AdnlPacket packet) = 0;
virtual void send_message_in(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlMessage message) = 0;
virtual void send_message_in(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlMessage message, td::uint32 flags) = 0;
virtual void register_channel(AdnlChannelIdShort id, td::actor::ActorId<AdnlChannel> channel) = 0;
virtual void register_channel(AdnlChannelIdShort id, AdnlNodeIdShort local_id,
td::actor::ActorId<AdnlChannel> channel) = 0;
virtual void unregister_channel(AdnlChannelIdShort id) = 0;
virtual void add_static_node(AdnlNode node) = 0;
@ -109,6 +110,7 @@ class AdnlPeerTable : public Adnl {
virtual void deliver_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::BufferSlice data,
td::Promise<td::BufferSlice> promise) = 0;
virtual void decrypt_message(AdnlNodeIdShort dst, td::BufferSlice data, td::Promise<td::BufferSlice> promise) = 0;
virtual void get_conn_ip_str(AdnlNodeIdShort l_id, AdnlNodeIdShort p_id, td::Promise<td::string> promise) = 0;
};
} // namespace adnl

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
@ -43,16 +43,19 @@ class AdnlPeerTableImpl : public AdnlPeerTable {
void add_peer(AdnlNodeIdShort local_id, AdnlNodeIdFull id, AdnlAddressList addr_list) override;
void add_static_nodes_from_config(AdnlNodesList nodes) override;
void receive_packet(td::BufferSlice data) override;
void receive_packet(td::IPAddress addr, AdnlCategoryMask cat_mask, td::BufferSlice data) override;
void receive_decrypted_packet(AdnlNodeIdShort dst, AdnlPacket data) override;
void send_message_in(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlMessage message) override;
void send_message_in(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlMessage message, td::uint32 flags) override;
void send_message(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::BufferSlice data) override {
send_message_ex(src, dst, std::move(data), 0);
}
void send_message_ex(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::BufferSlice data, td::uint32 flags) override {
if (data.size() > huge_packet_max_size()) {
VLOG(ADNL_WARNING) << "dropping too big packet [" << src << "->" << dst << "]: size=" << data.size();
VLOG(ADNL_WARNING) << "DUMP: " << td::buffer_to_hex(data.as_slice().truncate(128));
return;
}
send_message_in(src, dst, AdnlMessage{adnlmessage::AdnlMessageCustom{std::move(data)}});
send_message_in(src, dst, AdnlMessage{adnlmessage::AdnlMessageCustom{std::move(data)}}, flags);
}
void answer_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlQueryId query_id, td::BufferSlice data) override;
void send_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, std::string name, td::Promise<td::BufferSlice> promise,
@ -61,7 +64,7 @@ class AdnlPeerTableImpl : public AdnlPeerTable {
td::Timestamp timeout, td::BufferSlice data, td::uint64 max_answer_size) override {
send_query(src, dst, name, std::move(promise), timeout, std::move(data));
}
void add_id(AdnlNodeIdFull id, AdnlAddressList addr_list) override;
void add_id_ex(AdnlNodeIdFull id, AdnlAddressList addr_list, td::uint8 cat, td::uint32 mode) override;
void del_id(AdnlNodeIdShort id, td::Promise<td::Unit> promise) override;
void subscribe(AdnlNodeIdShort dst, std::string prefix, std::unique_ptr<Callback> callback) override;
void unsubscribe(AdnlNodeIdShort dst, std::string prefix) override;
@ -70,9 +73,14 @@ class AdnlPeerTableImpl : public AdnlPeerTable {
void get_addr_list(AdnlNodeIdShort id, td::Promise<AdnlAddressList> promise) override;
void get_self_node(AdnlNodeIdShort id, td::Promise<AdnlNode> promise) override;
void start_up() override;
void register_channel(AdnlChannelIdShort id, td::actor::ActorId<AdnlChannel> channel) override;
void register_channel(AdnlChannelIdShort id, AdnlNodeIdShort local_id,
td::actor::ActorId<AdnlChannel> channel) override;
void unregister_channel(AdnlChannelIdShort id) override;
void check_id_exists(AdnlNodeIdShort id, td::Promise<bool> promise) override {
promise.set_value(local_ids_.count(id));
}
void write_new_addr_list_to_db(AdnlNodeIdShort local_id, AdnlNodeIdShort peer_id, AdnlDbItem node,
td::Promise<td::Unit> promise) override;
void get_addr_list_from_db(AdnlNodeIdShort local_id, AdnlNodeIdShort peer_id,
@ -96,12 +104,21 @@ class AdnlPeerTableImpl : public AdnlPeerTable {
void create_ext_server(std::vector<AdnlNodeIdShort> ids, std::vector<td::uint16> ports,
td::Promise<td::actor::ActorOwn<AdnlExtServer>> promise) override;
void create_tunnel(AdnlNodeIdShort dst, td::uint32 size,
td::Promise<std::pair<td::actor::ActorOwn<AdnlTunnel>, AdnlAddress>> promise) override;
void get_conn_ip_str(AdnlNodeIdShort l_id, AdnlNodeIdShort p_id, td::Promise<td::string> promise) override;
struct PrintId {};
PrintId print_id() const {
return PrintId{};
}
private:
struct LocalIdInfo {
td::actor::ActorOwn<AdnlLocalId> local_id;
td::uint8 cat;
td::uint32 mode;
};
td::actor::ActorId<keyring::Keyring> keyring_;
td::actor::ActorId<AdnlNetworkManager> network_manager_;
@ -111,13 +128,14 @@ class AdnlPeerTableImpl : public AdnlPeerTable {
void deliver_one_message(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlMessage message);
std::map<AdnlNodeIdShort, td::actor::ActorOwn<AdnlPeer>> peers_;
std::map<AdnlNodeIdShort, td::actor::ActorOwn<AdnlLocalId>> local_ids_own_;
std::map<AdnlChannelIdShort, td::actor::ActorId<AdnlChannel>> channels_;
std::map<AdnlNodeIdShort, LocalIdInfo> local_ids_;
std::map<AdnlChannelIdShort, std::pair<td::actor::ActorId<AdnlChannel>, td::uint8>> channels_;
td::actor::ActorOwn<AdnlDb> db_;
td::actor::ActorOwn<AdnlExtServer> ext_server_;
AdnlNodeIdShort proxy_addr_;
//std::map<td::uint64, td::actor::ActorId<AdnlQuery>> out_queries_;
//td::uint64 last_query_id_ = 1;
};

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "adnl-peer.h"
#include "adnl-peer.hpp"
@ -68,7 +68,9 @@ void AdnlPeerPairImpl::alarm() {
}
if (retry_send_at_ && retry_send_at_.is_in_past()) {
retry_send_at_ = td::Timestamp::never();
send_messages_in(std::move(pending_messages_), false);
auto messages = std::move(pending_messages_);
pending_messages_.clear();
send_messages_in(std::move(messages), false);
}
alarm_timestamp().relax(next_dht_query_at_);
alarm_timestamp().relax(next_db_update_at_);
@ -113,6 +115,9 @@ void AdnlPeerPairImpl::discover() {
}
void AdnlPeerPairImpl::receive_packet_checked(AdnlPacket packet) {
last_received_packet_ = td::Timestamp::now();
try_reinit_at_ = td::Timestamp::never();
request_reverse_ping_after_ = td::Timestamp::in(15.0);
auto d = Adnl::adnl_start_time();
if (packet.dst_reinit_date() > d) {
VLOG(ADNL_WARNING) << this << ": dropping IN message: too new our reinit date " << packet.dst_reinit_date();
@ -131,18 +136,24 @@ void AdnlPeerPairImpl::receive_packet_checked(AdnlPacket packet) {
}
if (packet.dst_reinit_date() > 0 && packet.dst_reinit_date() < d) {
if (!packet.addr_list().empty()) {
update_addr_list(packet.addr_list());
auto addr_list = packet.addr_list();
if (packet.remote_addr().is_valid() && addr_list.size() == 0) {
VLOG(ADNL_DEBUG) << "adding implicit address " << packet.remote_addr();
addr_list.add_udp_address(packet.remote_addr());
}
update_addr_list(std::move(addr_list));
}
if (!packet.priority_addr_list().empty()) {
update_addr_list(packet.priority_addr_list());
}
VLOG(ADNL_NOTICE) << this << ": dropping IN message old our reinit date " << packet.reinit_date() << " date=" << d;
auto M = AdnlMessage{adnlmessage::AdnlMessageNop{}};
VLOG(ADNL_NOTICE) << this << ": dropping IN message old our reinit date " << packet.dst_reinit_date()
<< " date=" << d;
auto M = OutboundAdnlMessage{adnlmessage::AdnlMessageNop{}, 0};
send_message(std::move(M));
return;
}
if (packet.seqno() > 0) {
if (received_packet(static_cast<td::uint32>(packet.seqno()))) {
if (received_packet(packet.seqno())) {
VLOG(ADNL_INFO) << this << ": dropping IN message: old seqno: " << packet.seqno() << " (current max " << in_seqno_
<< ")";
return;
@ -159,7 +170,9 @@ void AdnlPeerPairImpl::receive_packet_checked(AdnlPacket packet) {
// accepted
// delivering
add_received_packet(static_cast<td::uint32>(packet.seqno()));
if (packet.seqno() > 0) {
add_received_packet(packet.seqno());
}
if (packet.confirm_seqno() > ack_seqno_) {
ack_seqno_ = packet.confirm_seqno();
@ -174,7 +187,12 @@ void AdnlPeerPairImpl::receive_packet_checked(AdnlPacket packet) {
}
if (!packet.addr_list().empty()) {
update_addr_list(packet.addr_list());
auto addr_list = packet.addr_list();
if (packet.remote_addr().is_valid() && addr_list.size() == 0) {
VLOG(ADNL_DEBUG) << "adding implicit address " << packet.remote_addr();
addr_list.add_udp_address(packet.remote_addr());
}
update_addr_list(std::move(addr_list));
}
if (!packet.priority_addr_list().empty()) {
update_addr_list(packet.priority_addr_list());
@ -194,7 +212,9 @@ void AdnlPeerPairImpl::receive_packet_from_channel(AdnlChannelIdShort id, AdnlPa
VLOG(ADNL_NOTICE) << this << ": dropping IN message: outdated channel id" << id;
return;
}
channel_ready_ = true;
if (channel_inited_) {
channel_ready_ = true;
}
receive_packet_checked(std::move(packet));
}
@ -219,113 +239,133 @@ void AdnlPeerPairImpl::deliver_message(AdnlMessage message) {
message.visit([&](const auto &obj) { this->process_message(obj); });
}
void AdnlPeerPairImpl::send_messages_in(std::vector<AdnlMessage> messages, bool allow_postpone) {
auto connR = get_conn();
if (connR.is_error()) {
if (!allow_postpone) {
VLOG(ADNL_NOTICE) << this << ": dropping OUT messages: cannot get conn: " << connR.move_as_error();
void AdnlPeerPairImpl::send_messages_in(std::vector<OutboundAdnlMessage> messages, bool allow_postpone) {
for (td::int32 idx = 0; idx < 2; idx++) {
std::vector<OutboundAdnlMessage> not_sent;
auto connR = get_conn(idx == 1);
if (connR.is_error()) {
if (!allow_postpone) {
VLOG(ADNL_NOTICE) << this << ": dropping OUT messages: cannot get conn: " << connR.move_as_error();
return;
}
VLOG(ADNL_INFO) << this << ": delaying OUT messages: cannot get conn: " << connR.move_as_error();
if (!retry_send_at_) {
retry_send_at_.relax(td::Timestamp::in(10.0));
alarm_timestamp().relax(retry_send_at_);
}
for (auto &m : messages) {
pending_messages_.push_back(std::move(m));
}
return;
}
VLOG(ADNL_INFO) << this << ": delaying OUT messages: cannot get conn: " << connR.move_as_error();
if (!retry_send_at_) {
retry_send_at_.relax(td::Timestamp::in(10.0));
alarm_timestamp().relax(retry_send_at_);
auto C = connR.move_as_ok();
bool is_direct = C.second;
auto conn = std::move(C.first);
if (idx == 1) {
CHECK(is_direct);
}
for (auto &m : messages) {
pending_messages_.push_back(std::move(m));
size_t ptr = 0;
bool first = true;
do {
bool try_reinit = try_reinit_at_ && try_reinit_at_.is_in_past();
bool via_channel = channel_ready_ && !try_reinit;
size_t s = (via_channel ? channel_packet_header_max_size() : packet_header_max_size());
if (first) {
s += 2 * addr_list_max_size();
}
AdnlPacket packet;
packet.set_seqno(++out_seqno_);
packet.set_confirm_seqno(in_seqno_);
if (first) {
if (!channel_inited_) {
auto M = adnlmessage::AdnlMessageCreateChannel{channel_pub_, channel_pk_date_};
s += M.size();
packet.add_message(std::move(M));
} else if (!channel_ready_) {
auto M = adnlmessage::AdnlMessageConfirmChannel{channel_pub_, peer_channel_pub_, channel_pk_date_};
s += M.size();
packet.add_message(std::move(M));
}
}
if (!addr_list_.empty()) {
packet.set_received_addr_list_version(addr_list_.version());
}
if (!priority_addr_list_.empty()) {
packet.set_received_priority_addr_list_version(priority_addr_list_.version());
}
while (ptr < messages.size()) {
auto &M = messages[ptr];
if (!is_direct && (M.flags() & Adnl::SendFlags::direct_only)) {
not_sent.push_back(std::move(M));
continue;
}
CHECK(M.size() <= get_mtu());
if (s + M.size() <= AdnlNetworkManager::get_mtu()) {
s += M.size();
packet.add_message(M.release());
ptr++;
} else {
break;
}
}
if (!via_channel) {
packet.set_reinit_date(Adnl::adnl_start_time(), reinit_date_);
packet.set_source(local_id_);
}
if (!first) {
if (!channel_inited_) {
auto M = adnlmessage::AdnlMessageCreateChannel{channel_pub_, channel_pk_date_};
if (s + M.size() <= AdnlNetworkManager::get_mtu()) {
s += M.size();
packet.add_message(std::move(M));
}
} else if (!channel_ready_) {
auto M = adnlmessage::AdnlMessageConfirmChannel{channel_pub_, peer_channel_pub_, channel_pk_date_};
if (s + M.size() <= AdnlNetworkManager::get_mtu()) {
s += M.size();
packet.add_message(std::move(M));
}
}
}
packet.run_basic_checks().ensure();
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), conn, id = print_id(),
via_channel](td::Result<AdnlPacket> res) {
if (res.is_error()) {
LOG(ERROR) << id << ": dropping OUT message: error while creating packet: " << res.move_as_error();
} else {
td::actor::send_closure(SelfId, &AdnlPeerPairImpl::send_packet_continue, res.move_as_ok(), conn, via_channel);
}
});
td::actor::send_closure(local_actor_, &AdnlLocalId::update_packet, std::move(packet),
(!channel_ready_ && ack_seqno_ == 0 && in_seqno_ == 0) || try_reinit, !via_channel,
(first || s + addr_list_max_size() <= AdnlNetworkManager::get_mtu())
? (try_reinit ? 0 : peer_recv_addr_list_version_)
: 0x7fffffff,
(first || s + 2 * addr_list_max_size() <= AdnlNetworkManager::get_mtu())
? peer_recv_priority_addr_list_version_
: 0x7fffffff,
std::move(P));
first = false;
} while (ptr < messages.size());
messages = std::move(not_sent);
if (!messages.size()) {
break;
}
return;
}
auto conn = connR.move_as_ok();
size_t ptr = 0;
bool first = true;
do {
size_t s = (channel_ready_ ? channel_packet_header_max_size() : packet_header_max_size());
if (first) {
s += 2 * addr_list_max_size();
}
AdnlPacket packet;
packet.set_seqno(++out_seqno_);
packet.set_confirm_seqno(in_seqno_);
if (first) {
if (!channel_inited_) {
auto M = adnlmessage::AdnlMessageCreateChannel{channel_pub_, channel_pk_date_};
s += M.size();
packet.add_message(std::move(M));
} else if (!channel_ready_) {
auto M = adnlmessage::AdnlMessageConfirmChannel{channel_pub_, peer_channel_pub_, channel_pk_date_};
s += M.size();
packet.add_message(std::move(M));
}
}
if (!addr_list_.empty()) {
packet.set_received_addr_list_version(addr_list_.version());
}
if (!priority_addr_list_.empty()) {
packet.set_received_priority_addr_list_version(priority_addr_list_.version());
}
while (ptr < messages.size()) {
auto &M = messages[ptr];
CHECK(M.size() <= get_mtu());
if (s + M.size() <= AdnlNetworkManager::get_mtu()) {
s += M.size();
packet.add_message(std::move(M));
ptr++;
} else {
break;
}
}
if (!channel_ready_) {
packet.set_reinit_date(Adnl::adnl_start_time(), reinit_date_);
packet.set_source(local_id_);
}
if (!first) {
if (!channel_inited_) {
auto M = adnlmessage::AdnlMessageCreateChannel{channel_pub_, channel_pk_date_};
if (s + M.size() <= AdnlNetworkManager::get_mtu()) {
s += M.size();
packet.add_message(std::move(M));
}
} else if (!channel_ready_) {
auto M = adnlmessage::AdnlMessageConfirmChannel{channel_pub_, peer_channel_pub_, channel_pk_date_};
if (s + M.size() <= AdnlNetworkManager::get_mtu()) {
s += M.size();
packet.add_message(std::move(M));
}
}
}
packet.run_basic_checks().ensure();
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), conn, id = print_id(),
via_channel = channel_ready_](td::Result<AdnlPacket> res) {
if (res.is_error()) {
LOG(ERROR) << id << ": dropping OUT message: error while creating packet: " << res.move_as_error();
} else {
td::actor::send_closure(SelfId, &AdnlPeerPairImpl::send_packet_continue, res.move_as_ok(), conn, via_channel);
}
});
td::actor::send_closure(
local_actor_, &AdnlLocalId::update_packet, std::move(packet),
!channel_ready_ && ack_seqno_ == 0 && in_seqno_ == 0, !channel_ready_,
(first || s + addr_list_max_size() <= AdnlNetworkManager::get_mtu()) ? peer_recv_addr_list_version_
: 0x7fffffff,
(first || s + 2 * addr_list_max_size() <= AdnlNetworkManager::get_mtu()) ? peer_recv_priority_addr_list_version_
: 0x7fffffff,
std::move(P));
first = false;
} while (ptr < messages.size());
}
void AdnlPeerPairImpl::send_messages(std::vector<AdnlMessage> messages) {
std::vector<AdnlMessage> new_vec;
void AdnlPeerPairImpl::send_messages(std::vector<OutboundAdnlMessage> messages) {
std::vector<OutboundAdnlMessage> new_vec;
for (auto &M : messages) {
if (M.size() <= get_mtu()) {
new_vec.push_back(std::move(M));
@ -345,7 +385,8 @@ void AdnlPeerPairImpl::send_messages(std::vector<AdnlMessage> messages) {
}
B.confirm_read(data.size());
new_vec.push_back(AdnlMessage{adnlmessage::AdnlMessagePart{hash, size, offset, std::move(data)}});
new_vec.push_back(
OutboundAdnlMessage{adnlmessage::AdnlMessagePart{hash, size, offset, std::move(data)}, M.flags()});
offset += part_size;
}
}
@ -355,6 +396,9 @@ void AdnlPeerPairImpl::send_messages(std::vector<AdnlMessage> messages) {
void AdnlPeerPairImpl::send_packet_continue(AdnlPacket packet, td::actor::ActorId<AdnlNetworkConnection> conn,
bool via_channel) {
if (!try_reinit_at_ && last_received_packet_ < td::Timestamp::in(-5.0)) {
try_reinit_at_ = td::Timestamp::in(10.0);
}
packet.run_basic_checks().ensure();
auto B = serialize_tl_object(packet.tl(), true);
if (via_channel) {
@ -390,7 +434,7 @@ void AdnlPeerPairImpl::send_packet_continue(AdnlPacket packet, td::actor::ActorI
}
void AdnlPeerPairImpl::send_query(std::string name, td::Promise<td::BufferSlice> promise, td::Timestamp timeout,
td::BufferSlice data) {
td::BufferSlice data, td::uint32 flags) {
AdnlQueryId id = AdnlQuery::random_query_id();
CHECK(out_queries_.count(id) == 0);
@ -400,7 +444,7 @@ void AdnlPeerPairImpl::send_query(std::string name, td::Promise<td::BufferSlice>
out_queries_[id] = AdnlQuery::create(std::move(promise), std::move(P), name, timeout, id);
send_message(adnlmessage::AdnlMessageQuery{id, std::move(data)});
send_message(OutboundAdnlMessage{adnlmessage::AdnlMessageQuery{id, std::move(data)}, flags});
}
void AdnlPeerPairImpl::alarm_query(AdnlQueryId id) {
@ -408,7 +452,7 @@ void AdnlPeerPairImpl::alarm_query(AdnlQueryId id) {
}
AdnlPeerPairImpl::AdnlPeerPairImpl(td::actor::ActorId<AdnlNetworkManager> network_manager,
td::actor::ActorId<AdnlPeerTable> peer_table,
td::actor::ActorId<AdnlPeerTable> peer_table, td::uint32 local_mode,
td::actor::ActorId<AdnlLocalId> local_actor, td::actor::ActorId<AdnlPeer> peer,
td::actor::ActorId<dht::Dht> dht_node, AdnlNodeIdShort local_id,
AdnlNodeIdShort peer_id) {
@ -417,6 +461,7 @@ AdnlPeerPairImpl::AdnlPeerPairImpl(td::actor::ActorId<AdnlNetworkManager> networ
local_actor_ = local_actor;
peer_ = peer;
dht_node_ = dht_node;
mode_ = local_mode;
local_id_ = local_id;
peer_id_short_ = peer_id;
@ -450,7 +495,8 @@ void AdnlPeerPairImpl::create_channel(pubkeys::Ed25519 pub, td::uint32 date) {
channel_ = R.move_as_ok();
channel_inited_ = true;
td::actor::send_closure_later(peer_table_, &AdnlPeerTable::register_channel, channel_in_id_, channel_.get());
td::actor::send_closure_later(peer_table_, &AdnlPeerTable::register_channel, channel_in_id_, local_id_,
channel_.get());
} else {
VLOG(ADNL_WARNING) << this << ": failed to create channel: " << R.move_as_error();
}
@ -486,20 +532,20 @@ void AdnlPeerPairImpl::process_message(const adnlmessage::AdnlMessageReinit &mes
}
void AdnlPeerPairImpl::process_message(const adnlmessage::AdnlMessageQuery &message) {
auto P = td::PromiseCreator::lambda(
[SelfId = actor_id(this), query_id = message.query_id()](td::Result<td::BufferSlice> R) {
if (R.is_error()) {
LOG(WARNING) << "failed to answer query: " << R.move_as_error();
} else {
auto data = R.move_as_ok();
if (data.size() > Adnl::huge_packet_max_size()) {
LOG(WARNING) << "dropping too big answer query: size=" << data.size();
} else {
td::actor::send_closure(SelfId, &AdnlPeerPairImpl::send_message,
AdnlMessage{adnlmessage::AdnlMessageAnswer{query_id, std::move(data)}});
}
}
});
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), query_id = message.query_id(),
flags = static_cast<td::uint32>(0)](td::Result<td::BufferSlice> R) {
if (R.is_error()) {
LOG(WARNING) << "failed to answer query: " << R.move_as_error();
} else {
auto data = R.move_as_ok();
if (data.size() > Adnl::huge_packet_max_size()) {
LOG(WARNING) << "dropping too big answer query: size=" << data.size();
} else {
td::actor::send_closure(SelfId, &AdnlPeerPairImpl::send_message,
OutboundAdnlMessage{adnlmessage::AdnlMessageAnswer{query_id, std::move(data)}, flags});
}
}
});
td::actor::send_closure(local_actor_, &AdnlLocalId::deliver_query, peer_id_short_, message.data(), std::move(P));
}
@ -612,27 +658,32 @@ void AdnlPeerPairImpl::reinit(td::int32 date) {
}
}
td::Result<td::actor::ActorId<AdnlNetworkConnection>> AdnlPeerPairImpl::get_conn() {
td::Result<std::pair<td::actor::ActorId<AdnlNetworkConnection>, bool>> AdnlPeerPairImpl::get_conn(bool direct_only) {
if (!priority_addr_list_.empty() && priority_addr_list_.expire_at() < td::Clocks::system()) {
priority_addr_list_ = AdnlAddressList{};
priority_conns_.clear();
}
if (conns_.size() == 0 && priority_conns_.size() == 0) {
return td::Status::Error(ErrorCode::notready, PSTRING()
<< "empty network information: version=" << addr_list_.version()
<< " reinit_date=" << addr_list_.reinit_date()
<< " real_reinit_date=" << reinit_date_);
if (has_reverse_addr_) {
request_reverse_ping();
return td::Status::Error(ErrorCode::notready, "waiting for reverse ping");
} else {
return td::Status::Error(ErrorCode::notready, PSTRING()
<< "empty network information: version=" << addr_list_.version()
<< " reinit_date=" << addr_list_.reinit_date()
<< " real_reinit_date=" << reinit_date_);
}
}
for (auto &conn : priority_conns_) {
if (conn.ready()) {
return conn.conn.get();
if (conn.ready() && (!direct_only || conn.is_direct())) {
return std::make_pair(conn.conn.get(), conn.is_direct());
}
}
for (auto &conn : conns_) {
if (conn.ready()) {
return conn.conn.get();
if (conn.ready() && (!direct_only || conn.is_direct())) {
return std::make_pair(conn.conn.get(), conn.is_direct());
}
}
return td::Status::Error(ErrorCode::notready, "no active connections");
@ -642,7 +693,7 @@ void AdnlPeerPairImpl::update_addr_list(AdnlAddressList addr_list) {
if (addr_list.empty()) {
return;
}
CHECK(addr_list.size() > 0);
//CHECK(addr_list.size() > 0);
if (addr_list.reinit_date() > td::Clocks::system() + 60) {
VLOG(ADNL_WARNING) << "dropping addr list with too new reinit date";
@ -670,24 +721,56 @@ void AdnlPeerPairImpl::update_addr_list(AdnlAddressList addr_list) {
VLOG(ADNL_INFO) << this << ": updating addr list to version " << addr_list.version() << " size=" << addr_list.size();
const auto addrs = addr_list.addrs();
has_reverse_addr_ = addr_list.has_reverse();
if (has_reverse_addr_ && addrs.empty()) {
return;
}
std::vector<Conn> conns;
conns.resize(std::min(addr_list.size(), 3u));
auto &old_conns = priority ? priority_conns_ : conns_;
for (size_t i = 0; i < conns.size(); i++) {
auto &addr = addrs[i];
auto hash = addr->get_hash();
if (i < old_conns.size() && old_conns[i].addr->get_hash() == hash) {
conns[i] = std::move(old_conns[i]);
} else {
conns[i] = Conn{addr, actor_id(this), network_manager_};
size_t idx = 0;
for (const auto &addr : addrs) {
if (addr->is_reverse()) {
continue;
}
if ((mode_ & static_cast<td::uint32>(AdnlLocalIdMode::direct_only)) && !addr->is_public()) {
continue;
}
auto hash = addr->get_hash();
if (idx < old_conns.size() && old_conns[idx].addr->get_hash() == hash) {
conns.push_back(std::move(old_conns[idx]));
} else {
conns.push_back(Conn{addr, actor_id(this), network_manager_, peer_table_});
}
idx++;
}
old_conns = std::move(conns);
(priority ? priority_addr_list_ : addr_list_) = addr_list;
}
void AdnlPeerPairImpl::get_conn_ip_str(td::Promise<td::string> promise) {
if (conns_.size() == 0 && priority_conns_.size() == 0) {
promise.set_value("undefined");
return;
}
for (auto &conn : priority_conns_) {
if (conn.ready()) {
td::actor::send_closure(conn.conn, &AdnlNetworkConnection::get_ip_str, std::move(promise));
return;
}
}
for (auto &conn : conns_) {
if (conn.ready()) {
td::actor::send_closure(conn.conn, &AdnlNetworkConnection::get_ip_str, std::move(promise));
return;
}
}
promise.set_value("undefined");
}
void AdnlPeerImpl::update_id(AdnlNodeIdFull id) {
CHECK(id.compute_short_id() == peer_id_short_);
if (!peer_id_.empty()) {
@ -702,28 +785,29 @@ void AdnlPeerImpl::update_id(AdnlNodeIdFull id) {
}
void AdnlPeerPairImpl::Conn::create_conn(td::actor::ActorId<AdnlPeerPairImpl> peer,
td::actor::ActorId<AdnlNetworkManager> network_manager) {
td::actor::ActorId<AdnlNetworkManager> network_manager,
td::actor::ActorId<Adnl> adnl) {
auto id = addr->get_hash();
conn = addr->create_connection(network_manager, std::make_unique<ConnCallback>(peer, id));
conn = addr->create_connection(network_manager, adnl, std::make_unique<ConnCallback>(peer, id));
}
void AdnlPeerPairImpl::conn_change_state(AdnlConnectionIdShort id, bool ready) {
if (ready) {
if (pending_messages_.size() > 0) {
send_messages_in(std::move(pending_messages_), true);
auto messages = std::move(pending_messages_);
pending_messages_.clear();
send_messages_in(std::move(messages), true);
}
}
}
td::actor::ActorOwn<AdnlPeerPair> AdnlPeerPair::create(td::actor::ActorId<AdnlNetworkManager> network_manager,
td::actor::ActorId<AdnlPeerTable> peer_table,
td::actor::ActorId<AdnlLocalId> local_actor,
td::actor::ActorId<AdnlPeer> peer_actor,
td::actor::ActorId<dht::Dht> dht_node, AdnlNodeIdShort local_id,
AdnlNodeIdShort peer_id) {
auto X = td::actor::create_actor<AdnlPeerPairImpl>("peerpair", network_manager, peer_table, local_actor, peer_actor,
dht_node, local_id, peer_id);
td::actor::ActorOwn<AdnlPeerPair> AdnlPeerPair::create(
td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<AdnlPeerTable> peer_table,
td::uint32 local_mode, td::actor::ActorId<AdnlLocalId> local_actor, td::actor::ActorId<AdnlPeer> peer_actor,
td::actor::ActorId<dht::Dht> dht_node, AdnlNodeIdShort local_id, AdnlNodeIdShort peer_id) {
auto X = td::actor::create_actor<AdnlPeerPairImpl>("peerpair", network_manager, peer_table, local_mode, local_actor,
peer_actor, dht_node, local_id, peer_id);
return td::actor::ActorOwn<AdnlPeerPair>(std::move(X));
}
@ -734,15 +818,16 @@ td::actor::ActorOwn<AdnlPeer> AdnlPeer::create(td::actor::ActorId<AdnlNetworkMan
return td::actor::ActorOwn<AdnlPeer>(std::move(X));
}
void AdnlPeerImpl::receive_packet(AdnlNodeIdShort dst, td::actor::ActorId<AdnlLocalId> dst_actor, AdnlPacket packet) {
void AdnlPeerImpl::receive_packet(AdnlNodeIdShort dst, td::uint32 dst_mode, td::actor::ActorId<AdnlLocalId> dst_actor,
AdnlPacket packet) {
if (packet.inited_from()) {
update_id(packet.from());
}
auto it = peer_pairs_.find(dst);
if (it == peer_pairs_.end()) {
auto X =
AdnlPeerPair::create(network_manager_, peer_table_, dst_actor, actor_id(this), dht_node_, dst, peer_id_short_);
auto X = AdnlPeerPair::create(network_manager_, peer_table_, dst_mode, dst_actor, actor_id(this), dht_node_, dst,
peer_id_short_);
peer_pairs_.emplace(dst, std::move(X));
it = peer_pairs_.find(dst);
CHECK(it != peer_pairs_.end());
@ -752,15 +837,15 @@ void AdnlPeerImpl::receive_packet(AdnlNodeIdShort dst, td::actor::ActorId<AdnlLo
}
}
td::actor::send_closure(it->second.get(), &AdnlPeerPair::receive_packet_checked, std::move(packet));
td::actor::send_closure(it->second.get(), &AdnlPeerPair::receive_packet, std::move(packet));
}
void AdnlPeerImpl::send_messages(AdnlNodeIdShort src, td::actor::ActorId<AdnlLocalId> src_actor,
std::vector<AdnlMessage> messages) {
void AdnlPeerImpl::send_messages(AdnlNodeIdShort src, td::uint32 src_mode, td::actor::ActorId<AdnlLocalId> src_actor,
std::vector<OutboundAdnlMessage> messages) {
auto it = peer_pairs_.find(src);
if (it == peer_pairs_.end()) {
auto X =
AdnlPeerPair::create(network_manager_, peer_table_, src_actor, actor_id(this), dht_node_, src, peer_id_short_);
auto X = AdnlPeerPair::create(network_manager_, peer_table_, src_mode, src_actor, actor_id(this), dht_node_, src,
peer_id_short_);
peer_pairs_.emplace(src, std::move(X));
it = peer_pairs_.find(src);
CHECK(it != peer_pairs_.end());
@ -773,12 +858,13 @@ void AdnlPeerImpl::send_messages(AdnlNodeIdShort src, td::actor::ActorId<AdnlLoc
td::actor::send_closure(it->second, &AdnlPeerPair::send_messages, std::move(messages));
}
void AdnlPeerImpl::send_query(AdnlNodeIdShort src, td::actor::ActorId<AdnlLocalId> src_actor, std::string name,
td::Promise<td::BufferSlice> promise, td::Timestamp timeout, td::BufferSlice data) {
void AdnlPeerImpl::send_query(AdnlNodeIdShort src, td::uint32 src_mode, td::actor::ActorId<AdnlLocalId> src_actor,
std::string name, td::Promise<td::BufferSlice> promise, td::Timestamp timeout,
td::BufferSlice data, td::uint32 flags) {
auto it = peer_pairs_.find(src);
if (it == peer_pairs_.end()) {
auto X =
AdnlPeerPair::create(network_manager_, peer_table_, src_actor, actor_id(this), dht_node_, src, peer_id_short_);
auto X = AdnlPeerPair::create(network_manager_, peer_table_, src_mode, src_actor, actor_id(this), dht_node_, src,
peer_id_short_);
peer_pairs_.emplace(src, std::move(X));
it = peer_pairs_.find(src);
CHECK(it != peer_pairs_.end());
@ -788,7 +874,8 @@ void AdnlPeerImpl::send_query(AdnlNodeIdShort src, td::actor::ActorId<AdnlLocalI
}
}
td::actor::send_closure(it->second, &AdnlPeerPair::send_query, name, std::move(promise), timeout, std::move(data));
td::actor::send_closure(it->second, &AdnlPeerPair::send_query, name, std::move(promise), timeout, std::move(data),
flags);
}
void AdnlPeerImpl::del_local_id(AdnlNodeIdShort local_id) {
@ -802,12 +889,22 @@ void AdnlPeerImpl::update_dht_node(td::actor::ActorId<dht::Dht> dht_node) {
}
}
void AdnlPeerImpl::update_addr_list(AdnlNodeIdShort local_id, td::actor::ActorId<AdnlLocalId> local_actor,
AdnlAddressList addr_list) {
void AdnlPeerImpl::get_conn_ip_str(AdnlNodeIdShort l_id, td::Promise<td::string> promise) {
auto it = peer_pairs_.find(l_id);
if (it == peer_pairs_.end()) {
promise.set_value("undefined");
return;
}
td::actor::send_closure(it->second, &AdnlPeerPair::get_conn_ip_str, std::move(promise));
}
void AdnlPeerImpl::update_addr_list(AdnlNodeIdShort local_id, td::uint32 local_mode,
td::actor::ActorId<AdnlLocalId> local_actor, AdnlAddressList addr_list) {
auto it = peer_pairs_.find(local_id);
if (it == peer_pairs_.end()) {
auto X = AdnlPeerPair::create(network_manager_, peer_table_, local_actor, actor_id(this), dht_node_, local_id,
peer_id_short_);
auto X = AdnlPeerPair::create(network_manager_, peer_table_, local_mode, local_actor, actor_id(this), dht_node_,
local_id, peer_id_short_);
peer_pairs_.emplace(local_id, std::move(X));
it = peer_pairs_.find(local_id);
CHECK(it != peer_pairs_.end());
@ -873,6 +970,36 @@ void AdnlPeerPairImpl::update_peer_id(AdnlNodeIdFull id) {
CHECK(!peer_id_.empty());
}
void AdnlPeerPairImpl::request_reverse_ping() {
if (request_reverse_ping_active_ || !request_reverse_ping_after_.is_in_past()) {
return;
}
VLOG(ADNL_INFO) << this << ": requesting reverse ping";
request_reverse_ping_after_ = td::Timestamp::in(15.0);
request_reverse_ping_active_ = true;
td::actor::send_closure(
local_actor_, &AdnlLocalId::get_self_node,
[SelfId = actor_id(this), peer = peer_id_short_, dht = dht_node_](td::Result<AdnlNode> R) {
if (R.is_error()) {
td::actor::send_closure(SelfId, &AdnlPeerPairImpl::request_reverse_ping_result, R.move_as_error());
return;
}
td::actor::send_closure(
dht, &dht::Dht::request_reverse_ping, R.move_as_ok(), peer, [SelfId](td::Result<td::Unit> R) {
td::actor::send_closure(SelfId, &AdnlPeerPairImpl::request_reverse_ping_result, std::move(R));
});
});
}
void AdnlPeerPairImpl::request_reverse_ping_result(td::Result<td::Unit> R) {
request_reverse_ping_active_ = false;
if (R.is_ok()) {
VLOG(ADNL_INFO) << this << ": reverse ping requested";
} else {
VLOG(ADNL_INFO) << this << ": failed to request reverse ping: " << R.move_as_error();
}
}
} // namespace adnl
} // namespace ton

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
@ -43,9 +43,9 @@ class AdnlPeerPair : public td::actor::Actor {
virtual void receive_packet_checked(AdnlPacket packet) = 0;
virtual void receive_packet(AdnlPacket packet) = 0;
virtual void send_messages(std::vector<AdnlMessage> message) = 0;
inline void send_message(AdnlMessage message) {
std::vector<AdnlMessage> vec;
virtual void send_messages(std::vector<OutboundAdnlMessage> message) = 0;
inline void send_message(OutboundAdnlMessage message) {
std::vector<OutboundAdnlMessage> vec;
vec.push_back(std::move(message));
send_messages(std::move(vec));
}
@ -53,14 +53,15 @@ class AdnlPeerPair : public td::actor::Actor {
return Adnl::get_mtu() + 128;
}
virtual void send_query(std::string name, td::Promise<td::BufferSlice> promise, td::Timestamp timeout,
td::BufferSlice data) = 0;
td::BufferSlice data, td::uint32 flags) = 0;
virtual void alarm_query(AdnlQueryId query_id) = 0;
virtual void update_dht_node(td::actor::ActorId<dht::Dht> dht_node) = 0;
virtual void update_peer_id(AdnlNodeIdFull id) = 0;
virtual void update_addr_list(AdnlAddressList addr_list) = 0;
virtual void get_conn_ip_str(td::Promise<td::string> promise) = 0;
static td::actor::ActorOwn<AdnlPeerPair> create(td::actor::ActorId<AdnlNetworkManager> network_manager,
td::actor::ActorId<AdnlPeerTable> peer_table,
td::actor::ActorId<AdnlPeerTable> peer_table, td::uint32 local_mode,
td::actor::ActorId<AdnlLocalId> local_actor,
td::actor::ActorId<AdnlPeer> peer_actor,
td::actor::ActorId<dht::Dht> dht_node, AdnlNodeIdShort local_id,
@ -69,20 +70,24 @@ class AdnlPeerPair : public td::actor::Actor {
class AdnlPeer : public td::actor::Actor {
public:
virtual void receive_packet(AdnlNodeIdShort dst, td::actor::ActorId<AdnlLocalId> dst_actor, AdnlPacket message) = 0;
virtual void send_messages(AdnlNodeIdShort src, td::actor::ActorId<AdnlLocalId> src_actor,
std::vector<AdnlMessage> messages) = 0;
virtual void send_query(AdnlNodeIdShort src, td::actor::ActorId<AdnlLocalId> src_actor, std::string name,
td::Promise<td::BufferSlice> promise, td::Timestamp timeout, td::BufferSlice data) = 0;
void send_one_message(AdnlNodeIdShort src, td::actor::ActorId<AdnlLocalId> src_actor, AdnlMessage message) {
std::vector<AdnlMessage> vec;
virtual void receive_packet(AdnlNodeIdShort dst, td::uint32 dst_mode, td::actor::ActorId<AdnlLocalId> dst_actor,
AdnlPacket message) = 0;
virtual void send_messages(AdnlNodeIdShort src, td::uint32 src_mode, td::actor::ActorId<AdnlLocalId> src_actor,
std::vector<OutboundAdnlMessage> messages) = 0;
virtual void send_query(AdnlNodeIdShort src, td::uint32 src_mode, td::actor::ActorId<AdnlLocalId> src_actor,
std::string name, td::Promise<td::BufferSlice> promise, td::Timestamp timeout,
td::BufferSlice data, td::uint32 flags) = 0;
void send_one_message(AdnlNodeIdShort src, td::uint32 src_mode, td::actor::ActorId<AdnlLocalId> src_actor,
OutboundAdnlMessage message) {
std::vector<OutboundAdnlMessage> vec;
vec.push_back(std::move(message));
send_messages(src, src_actor, std::move(vec));
send_messages(src, src_mode, src_actor, std::move(vec));
}
void send_message(AdnlNodeIdShort src, td::actor::ActorId<AdnlLocalId> src_actor, td::BufferSlice data) {
auto M = AdnlMessage{adnlmessage::AdnlMessageCustom{std::move(data)}};
send_one_message(src, src_actor, std::move(M));
void send_message(AdnlNodeIdShort src, td::uint32 src_mode, td::actor::ActorId<AdnlLocalId> src_actor,
td::BufferSlice data, td::uint32 flags) {
auto M = OutboundAdnlMessage{adnlmessage::AdnlMessageCustom{std::move(data)}, flags};
send_one_message(src, src_mode, src_actor, std::move(M));
}
static td::actor::ActorOwn<AdnlPeer> create(td::actor::ActorId<AdnlNetworkManager> network_manager,
@ -91,9 +96,10 @@ class AdnlPeer : public td::actor::Actor {
virtual void del_local_id(AdnlNodeIdShort local_id) = 0;
virtual void update_id(AdnlNodeIdFull id) = 0;
virtual void update_addr_list(AdnlNodeIdShort local_id, td::actor::ActorId<AdnlLocalId> local_actor,
AdnlAddressList addr_list) = 0;
virtual void update_addr_list(AdnlNodeIdShort local_id, td::uint32 local_mode,
td::actor::ActorId<AdnlLocalId> local_actor, AdnlAddressList addr_list) = 0;
virtual void update_dht_node(td::actor::ActorId<dht::Dht> dht_node) = 0;
virtual void get_conn_ip_str(AdnlNodeIdShort l_id, td::Promise<td::string> promise) = 0;
};
} // namespace adnl

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
@ -58,8 +58,9 @@ class AdnlPeerPairImpl : public AdnlPeerPair {
}
AdnlPeerPairImpl(td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<AdnlPeerTable> peer_table,
td::actor::ActorId<AdnlLocalId> local_actor, td::actor::ActorId<AdnlPeer> peer,
td::actor::ActorId<dht::Dht> dht_node, AdnlNodeIdShort local_id, AdnlNodeIdShort peer_id);
td::uint32 local_mode, td::actor::ActorId<AdnlLocalId> local_actor,
td::actor::ActorId<AdnlPeer> peer, td::actor::ActorId<dht::Dht> dht_node, AdnlNodeIdShort local_id,
AdnlNodeIdShort peer_id);
void start_up() override;
void alarm() override;
@ -70,11 +71,11 @@ class AdnlPeerPairImpl : public AdnlPeerPair {
void receive_packet(AdnlPacket packet) override;
void deliver_message(AdnlMessage message);
void send_messages_in(std::vector<AdnlMessage> messages, bool allow_postpone);
void send_messages(std::vector<AdnlMessage> messages) override;
void send_messages_in(std::vector<OutboundAdnlMessage> messages, bool allow_postpone);
void send_messages(std::vector<OutboundAdnlMessage> messages) override;
void send_packet_continue(AdnlPacket packet, td::actor::ActorId<AdnlNetworkConnection> conn, bool via_channel);
void send_query(std::string name, td::Promise<td::BufferSlice> promise, td::Timestamp timeout,
td::BufferSlice data) override;
void send_query(std::string name, td::Promise<td::BufferSlice> promise, td::Timestamp timeout, td::BufferSlice data,
td::uint32 flags) override;
void alarm_query(AdnlQueryId id) override;
@ -87,6 +88,8 @@ class AdnlPeerPairImpl : public AdnlPeerPair {
void update_addr_list(AdnlAddressList addr_list) override;
void update_peer_id(AdnlNodeIdFull id) override;
void get_conn_ip_str(td::Promise<td::string> promise) override;
void got_data_from_db(td::Result<AdnlDbItem> R);
void got_data_from_static_nodes(td::Result<AdnlNode> R);
void got_data_from_dht(td::Result<AdnlNode> R);
@ -120,10 +123,10 @@ class AdnlPeerPairImpl : public AdnlPeerPair {
private:
void reinit(td::int32 date);
td::Result<td::actor::ActorId<AdnlNetworkConnection>> get_conn();
td::Result<std::pair<td::actor::ActorId<AdnlNetworkConnection>, bool>> get_conn(bool direct_only);
void create_channel(pubkeys::Ed25519 pub, td::uint32 date);
bool received_packet(td::uint32 seqno) const {
bool received_packet(td::uint64 seqno) const {
CHECK(seqno > 0);
if (seqno + 64 <= in_seqno_) {
return true;
@ -134,7 +137,7 @@ class AdnlPeerPairImpl : public AdnlPeerPair {
return recv_seqno_mask_ & (1ull << (in_seqno_ - seqno));
}
void add_received_packet(td::uint32 seqno) {
void add_received_packet(td::uint64 seqno) {
CHECK(!received_packet(seqno));
if (seqno <= in_seqno_) {
recv_seqno_mask_ |= (1ull << (in_seqno_ - seqno));
@ -150,6 +153,9 @@ class AdnlPeerPairImpl : public AdnlPeerPair {
}
}
void request_reverse_ping();
void request_reverse_ping_result(td::Result<td::Unit> R);
struct Conn {
class ConnCallback : public AdnlNetworkConnection::Callback {
public:
@ -169,9 +175,9 @@ class AdnlPeerPairImpl : public AdnlPeerPair {
td::actor::ActorOwn<AdnlNetworkConnection> conn;
Conn(AdnlAddress addr, td::actor::ActorId<AdnlPeerPairImpl> peer,
td::actor::ActorId<AdnlNetworkManager> network_manager)
td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl)
: addr(std::move(addr)) {
create_conn(peer, network_manager);
create_conn(peer, network_manager, adnl);
}
Conn() {
}
@ -180,10 +186,15 @@ class AdnlPeerPairImpl : public AdnlPeerPair {
return !conn.empty() && conn.get_actor_unsafe().is_active();
}
void create_conn(td::actor::ActorId<AdnlPeerPairImpl> peer, td::actor::ActorId<AdnlNetworkManager> network_manager);
bool is_direct() {
return addr->is_public();
}
void create_conn(td::actor::ActorId<AdnlPeerPairImpl> peer, td::actor::ActorId<AdnlNetworkManager> network_manager,
td::actor::ActorId<Adnl> adnl);
};
std::vector<AdnlMessage> pending_messages_;
std::vector<OutboundAdnlMessage> pending_messages_;
td::actor::ActorId<AdnlNetworkManager> network_manager_;
td::actor::ActorId<AdnlPeerTable> peer_table_;
@ -232,6 +243,8 @@ class AdnlPeerPairImpl : public AdnlPeerPair {
std::map<AdnlQueryId, td::actor::ActorId<AdnlQuery>> out_queries_;
td::uint32 mode_;
td::uint32 received_messages_ = 0;
bool received_from_db_ = false;
bool received_from_static_nodes_ = false;
@ -240,21 +253,31 @@ class AdnlPeerPairImpl : public AdnlPeerPair {
td::Timestamp next_dht_query_at_ = td::Timestamp::never();
td::Timestamp next_db_update_at_ = td::Timestamp::never();
td::Timestamp retry_send_at_ = td::Timestamp::never();
td::Timestamp last_received_packet_ = td::Timestamp::never();
td::Timestamp try_reinit_at_ = td::Timestamp::never();
bool has_reverse_addr_ = false;
td::Timestamp request_reverse_ping_after_ = td::Timestamp::now();
bool request_reverse_ping_active_ = false;
};
class AdnlPeerImpl : public AdnlPeer {
public:
void receive_packet(AdnlNodeIdShort dst, td::actor::ActorId<AdnlLocalId> dst_actor, AdnlPacket packet) override;
void send_messages(AdnlNodeIdShort src, td::actor::ActorId<AdnlLocalId> src_actor,
std::vector<AdnlMessage> messages) override;
void send_query(AdnlNodeIdShort src, td::actor::ActorId<AdnlLocalId> src_actor, std::string name,
td::Promise<td::BufferSlice> promise, td::Timestamp timeout, td::BufferSlice data) override;
void receive_packet(AdnlNodeIdShort dst, td::uint32 dst_mode, td::actor::ActorId<AdnlLocalId> dst_actor,
AdnlPacket packet) override;
void send_messages(AdnlNodeIdShort src, td::uint32 src_mode, td::actor::ActorId<AdnlLocalId> src_actor,
std::vector<OutboundAdnlMessage> messages) override;
void send_query(AdnlNodeIdShort src, td::uint32 src_mode, td::actor::ActorId<AdnlLocalId> src_actor, std::string name,
td::Promise<td::BufferSlice> promise, td::Timestamp timeout, td::BufferSlice data,
td::uint32 flags) override;
void del_local_id(AdnlNodeIdShort local_id) override;
void update_id(AdnlNodeIdFull id) override;
void update_addr_list(AdnlNodeIdShort local_id, td::actor::ActorId<AdnlLocalId> local_actor,
void update_addr_list(AdnlNodeIdShort local_id, td::uint32 local_mode, td::actor::ActorId<AdnlLocalId> local_actor,
AdnlAddressList addr_list) override;
void update_dht_node(td::actor::ActorId<dht::Dht> dht_node) override;
void get_conn_ip_str(AdnlNodeIdShort l_id, td::Promise<td::string> promise) override;
//void check_signature(td::BufferSlice data, td::BufferSlice signature, td::Promise<td::Unit> promise) override;
AdnlPeerImpl(td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<AdnlPeerTable> peer_table,

View file

@ -1,4 +1,4 @@
/*
/*
This file is part of TON Blockchain source code.
TON Blockchain is free software; you can redistribute it and/or
@ -14,23 +14,23 @@
You should have received a copy of the GNU General Public License
along with TON Blockchain. If not, see <http://www.gnu.org/licenses/>.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
You must obey the GNU General Public License in all respects for all
of the code used other than OpenSSL. If you modify file(s) with this
exception, you may extend this exception to your version of the file(s),
but you are not obligated to do so. If you do not wish to do so, delete this
exception statement from your version. If you delete this exception statement
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
You must obey the GNU General Public License in all respects for all
of the code used other than OpenSSL. If you modify file(s) with this
exception, you may extend this exception to your version of the file(s),
but you are not obligated to do so. If you do not wish to do so, delete this
exception statement from your version. If you delete this exception statement
from all source files in the program, then also delete it here.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "td/actor/actor.h"
#include "td/utils/buffer.h"
#include "td/utils/port/IPAddress.h"
#include "td/net/UdpServer.h"
#include "td/utils/port/signals.h"
#include "td/utils/OptionsParser.h"
#include "td/utils/OptionParser.h"
#include "td/utils/FileLog.h"
#include "td/utils/port/path.h"
#include "td/utils/port/user.h"
@ -41,6 +41,7 @@
#include "auto/tl/ton_api_json.h"
#include "adnl/adnl.h"
#include <map>
#include "git.h"
#if TD_DARWIN || TD_LINUX
#include <unistd.h>
@ -91,12 +92,15 @@ int main(int argc, char *argv[]) {
std::string config = "/var/ton-work/etc/adnl-proxy.conf.json";
td::OptionsParser p;
td::OptionParser p;
p.set_description("adnl pinger");
p.add_option('v', "verbosity", "set verbosity level", [&](td::Slice arg) {
int v = VERBOSITY_NAME(FATAL) + (td::to_integer<int>(arg));
SET_VERBOSITY_LEVEL(v);
return td::Status::OK();
});
p.add_option('V', "version", "shows adnl-pong build information", [&]() {
std::cout << "adnl-pong build information: [ Commit: " << GitMetadata::CommitSHA1() << ", Date: " << GitMetadata::CommitDate() << "]\n";
std::exit(0);
});
p.add_option('h', "help", "prints_help", [&]() {
char b[10240];
@ -104,7 +108,6 @@ int main(int argc, char *argv[]) {
sb << p;
std::cout << sb.as_cslice().c_str();
std::exit(2);
return td::Status::OK();
});
p.add_option('d', "daemonize", "set SIGHUP", [&]() {
#if TD_DARWIN || TD_LINUX
@ -112,9 +115,8 @@ int main(int argc, char *argv[]) {
setsid();
#endif
td::set_signal_handler(td::SignalType::HangUp, force_rotate_logs).ensure();
return td::Status::OK();
});
p.add_option('l', "logname", "log to file", [&](td::Slice fname) {
p.add_checked_option('l', "logname", "log to file", [&](td::Slice fname) {
auto F = std::make_unique<td::FileLog>();
TRY_STATUS(F->init(fname.str(), std::numeric_limits<td::uint64>::max(), true));
logger_ = std::move(F);
@ -122,25 +124,26 @@ int main(int argc, char *argv[]) {
return td::Status::OK();
});
td::uint32 threads = 7;
p.add_option('t', "threads", PSTRING() << "number of threads (default=" << threads << ")", [&](td::Slice fname) {
td::int32 v;
try {
v = std::stoi(fname.str());
} catch (...) {
return td::Status::Error(ton::ErrorCode::error, "bad value for --threads: not a number");
}
if (v < 1 || v > 256) {
return td::Status::Error(ton::ErrorCode::error, "bad value for --threads: should be in range [1..256]");
}
threads = v;
return td::Status::OK();
});
p.add_option('u', "user", "change user", [&](td::Slice user) { return td::change_user(user); });
p.add_option('k', "key", "private key", [&](td::Slice key) {
p.add_checked_option(
't', "threads", PSTRING() << "number of threads (default=" << threads << ")", [&](td::Slice fname) {
td::int32 v;
try {
v = std::stoi(fname.str());
} catch (...) {
return td::Status::Error(ton::ErrorCode::error, "bad value for --threads: not a number");
}
if (v < 1 || v > 256) {
return td::Status::Error(ton::ErrorCode::error, "bad value for --threads: should be in range [1..256]");
}
threads = v;
return td::Status::OK();
});
p.add_checked_option('u', "user", "change user", [&](td::Slice user) { return td::change_user(user.str()); });
p.add_checked_option('k', "key", "private key", [&](td::Slice key) {
TRY_RESULT_ASSIGN(pk, ton::PrivateKey::import(key));
return td::Status::OK();
});
p.add_option('a', "addr", "ip:port of instance", [&](td::Slice key) {
p.add_checked_option('a', "addr", "ip:port of instance", [&](td::Slice key) {
TRY_STATUS(addr.init_host_port(key.str()));
return td::Status::OK();
});
@ -170,7 +173,10 @@ int main(int argc, char *argv[]) {
network_manager = ton::adnl::AdnlNetworkManager::create(static_cast<td::uint16>(addr.get_port()));
td::actor::send_closure(network_manager, &ton::adnl::AdnlNetworkManager::add_self_addr, addr, 0);
ton::adnl::AdnlCategoryMask cat_mask;
cat_mask[0] = true;
td::actor::send_closure(network_manager, &ton::adnl::AdnlNetworkManager::add_self_addr, addr, std::move(cat_mask),
0);
auto tladdr = ton::create_tl_object<ton::ton_api::adnl_address_udp>(addr.get_ipv4(), addr.get_port());
auto addr_vec = std::vector<ton::tl_object_ptr<ton::ton_api::adnl_Address>>();
@ -179,7 +185,8 @@ int main(int argc, char *argv[]) {
std::move(addr_vec), ton::adnl::Adnl::adnl_start_time(), ton::adnl::Adnl::adnl_start_time(), 0, 2000000000);
auto addrlist = ton::adnl::AdnlAddressList::create(tladdrlist).move_as_ok();
td::actor::send_closure(adnl, &ton::adnl::Adnl::add_id, ton::adnl::AdnlNodeIdFull{pub}, std::move(addrlist));
td::actor::send_closure(adnl, &ton::adnl::Adnl::add_id, ton::adnl::AdnlNodeIdFull{pub}, std::move(addrlist),
static_cast<td::uint8>(0));
td::actor::send_closure(adnl, &ton::adnl::Adnl::subscribe, ton::adnl::AdnlNodeIdShort{pub.compute_short_id()},
ton::adnl::Adnl::int_to_bytestring(ton::ton_api::adnl_ping::ID),
std::make_unique<ton::adnl::Callback>());

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "adnl-proxy-types.hpp"
#include "tl-utils/tl-utils.hpp"
@ -27,59 +27,84 @@ namespace ton {
namespace adnl {
td::Result<AdnlProxy::Packet> AdnlProxyNone::decrypt(td::BufferSlice packet) const {
if (packet.size() < 32) {
return td::Status::Error(ErrorCode::protoviolation, "bad signature");
}
if (packet.as_slice().truncate(32) != id_.as_slice()) {
return td::Status::Error(ErrorCode::protoviolation, "bad proxy id");
}
Packet p{};
p.flags = 0;
p.ip = 0;
p.port = 0;
p.adnl_start_time = 0;
p.seqno = 0;
p.date = 0;
p.data = std::move(packet);
p.data.confirm_read(32);
return std::move(p);
}
td::BufferSlice AdnlProxyFast::encrypt(Packet packet) const {
auto date = static_cast<td::uint32>(td::Clocks::system());
auto signature = create_hash_tl_object<ton_api::adnl_proxyToFastHash>(
packet.ip, packet.port, date, sha256_bits256(packet.data.as_slice()), shared_secret_);
auto obj = create_serialize_tl_object<ton_api::adnl_proxyToFast>(packet.ip, packet.port, date, signature);
td::BufferSlice res{32 + obj.size() + packet.data.size()};
auto S = res.as_slice();
S.copy_from(td::Bits256::zero().as_slice());
if (!packet.date) {
packet.date = static_cast<td::int32>(td::Clocks::system());
packet.flags |= 8;
}
auto obj = create_tl_object<ton_api::adnl_proxyPacketHeader>(id_, packet.flags, packet.ip, packet.port,
packet.adnl_start_time, packet.seqno, packet.date,
td::sha256_bits256(packet.data.as_slice()));
char data[64];
td::MutableSlice S{data, 64};
S.copy_from(get_tl_object_sha256(obj).as_slice());
S.remove_prefix(32);
S.copy_from(obj.as_slice());
S.remove_prefix(obj.size());
S.copy_from(packet.data.as_slice());
S.copy_from(shared_secret_.as_slice());
return res;
obj->signature_ = td::sha256_bits256(td::Slice(data, 64));
return serialize_tl_object(obj, false, std::move(packet.data));
}
td::Result<AdnlProxy::Packet> AdnlProxyFast::decrypt(td::BufferSlice packet) const {
if (packet.size() < 36) {
return td::Status::Error(ErrorCode::protoviolation, "too short packet");
TRY_RESULT(obj, fetch_tl_prefix<ton_api::adnl_proxyPacketHeader>(packet, false));
if (obj->proxy_id_ != id_) {
return td::Status::Error(ErrorCode::protoviolation, "bad proxy id");
}
td::Bits256 v;
v.as_slice().copy_from(packet.as_slice().truncate(32));
if (!v.is_zero()) {
return td::Status::Error(ErrorCode::protoviolation, "non-zero DST");
}
packet.confirm_read(32);
auto signature = std::move(obj->signature_);
obj->signature_ = td::sha256_bits256(packet.as_slice());
TRY_RESULT(R, fetch_tl_prefix<ton_api::adnl_proxyToFast>(packet, true));
char data[64];
td::MutableSlice S{data, 64};
S.copy_from(get_tl_object_sha256(obj).as_slice());
S.remove_prefix(32);
S.copy_from(shared_secret_.as_slice());
if (R->date_ < td::Clocks::system() - 8) {
return td::Status::Error(ErrorCode::protoviolation, "too old date");
}
auto signature = create_hash_tl_object<ton_api::adnl_proxyToFastHash>(
R->ip_, R->port_, R->date_, sha256_bits256(packet.as_slice()), shared_secret_);
if (signature != R->signature_) {
if (td::sha256_bits256(td::Slice(data, 64)) != signature) {
return td::Status::Error(ErrorCode::protoviolation, "bad signature");
}
return Packet{static_cast<td::uint32>(R->ip_), static_cast<td::uint16>(R->port_), std::move(packet)};
Packet p;
p.flags = obj->flags_;
p.ip = (p.flags & 1) ? obj->ip_ : 0;
p.port = (p.flags & 1) ? static_cast<td::uint16>(obj->port_) : 0;
p.adnl_start_time = (p.flags & 2) ? obj->adnl_start_time_ : 0;
p.seqno = (p.flags & 4) ? obj->seqno_ : 0;
p.date = (p.flags & 8) ? obj->date_ : 0;
p.data = std::move(packet);
return std::move(p);
}
td::Result<std::shared_ptr<AdnlProxy>> AdnlProxy::create(const ton_api::adnl_Proxy &proxy_type) {
std::shared_ptr<AdnlProxy> R;
ton_api::downcast_call(
const_cast<ton_api::adnl_Proxy &>(proxy_type),
td::overloaded([&](const ton_api::adnl_proxy_none &x) { R = std::make_shared<AdnlProxyNone>(); },
td::overloaded([&](const ton_api::adnl_proxy_none &x) { R = std::make_shared<AdnlProxyNone>(x.id_); },
[&](const ton_api::adnl_proxy_fast &x) {
R = std::make_shared<AdnlProxyFast>(x.shared_secret_.as_slice());
R = std::make_shared<AdnlProxyFast>(x.id_, x.shared_secret_.as_slice());
}));
return R;
return std::move(R);
}
} // namespace adnl

View file

@ -14,11 +14,12 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
#include "td/utils/buffer.h"
#include "td/utils/Status.h"
#include "auto/tl/ton_api.h"
namespace ton {
@ -28,14 +29,19 @@ namespace adnl {
class AdnlProxy {
public:
struct Packet {
td::uint32 flags;
td::uint32 ip;
td::uint16 port;
td::int32 adnl_start_time;
td::int64 seqno;
td::int32 date{0};
td::BufferSlice data;
};
virtual ~AdnlProxy() = default;
virtual td::BufferSlice encrypt(Packet packet) const = 0;
virtual td::Result<Packet> decrypt(td::BufferSlice packet) const = 0;
virtual tl_object_ptr<ton_api::adnl_Proxy> tl() const = 0;
virtual const td::Bits256 &id() const = 0;
static td::Result<std::shared_ptr<AdnlProxy>> create(const ton_api::adnl_Proxy &proxy_type);
};

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
@ -28,31 +28,42 @@ namespace adnl {
class AdnlProxyNone : public AdnlProxy {
public:
AdnlProxyNone() {
AdnlProxyNone(td::Bits256 id) : id_(id) {
}
td::BufferSlice encrypt(Packet packet) const override {
return std::move(packet.data);
}
td::Result<Packet> decrypt(td::BufferSlice packet) const override {
return Packet{0, 0, std::move(packet)};
td::BufferSlice d{packet.data.size() + 32};
d.as_slice().copy_from(id_.as_slice());
d.as_slice().remove_prefix(32).copy_from(packet.data.as_slice());
return d;
}
td::Result<Packet> decrypt(td::BufferSlice packet) const override;
tl_object_ptr<ton_api::adnl_Proxy> tl() const override {
return create_tl_object<ton_api::adnl_proxy_none>();
return create_tl_object<ton_api::adnl_proxy_none>(id_);
}
const td::Bits256 &id() const override {
return id_;
}
private:
td::Bits256 id_;
};
class AdnlProxyFast : public AdnlProxy {
public:
AdnlProxyFast(td::Slice shared_secret)
: shared_secret_(sha256_bits256(shared_secret)), shared_secret_raw_(shared_secret) {
AdnlProxyFast(td::Bits256 id, td::Slice shared_secret)
: id_(id), shared_secret_(sha256_bits256(shared_secret)), shared_secret_raw_(shared_secret) {
}
td::BufferSlice encrypt(Packet packet) const override;
td::Result<Packet> decrypt(td::BufferSlice packet) const override;
tl_object_ptr<ton_api::adnl_Proxy> tl() const override {
return create_tl_object<ton_api::adnl_proxy_fast>(shared_secret_raw_.clone_as_buffer_slice());
return create_tl_object<ton_api::adnl_proxy_fast>(id_, shared_secret_raw_.clone_as_buffer_slice());
}
const td::Bits256 &id() const override {
return id_;
}
private:
td::Bits256 id_;
td::Bits256 shared_secret_;
td::SharedSlice shared_secret_raw_;
};

View file

@ -1,4 +1,4 @@
/*
/*
This file is part of TON Blockchain source code.
TON Blockchain is free software; you can redistribute it and/or
@ -14,33 +14,36 @@
You should have received a copy of the GNU General Public License
along with TON Blockchain. If not, see <http://www.gnu.org/licenses/>.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
You must obey the GNU General Public License in all respects for all
of the code used other than OpenSSL. If you modify file(s) with this
exception, you may extend this exception to your version of the file(s),
but you are not obligated to do so. If you do not wish to do so, delete this
exception statement from your version. If you delete this exception statement
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
You must obey the GNU General Public License in all respects for all
of the code used other than OpenSSL. If you modify file(s) with this
exception, you may extend this exception to your version of the file(s),
but you are not obligated to do so. If you do not wish to do so, delete this
exception statement from your version. If you delete this exception statement
from all source files in the program, then also delete it here.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "td/actor/actor.h"
#include "td/utils/buffer.h"
#include "td/utils/port/IPAddress.h"
#include "td/net/UdpServer.h"
#include "td/utils/port/signals.h"
#include "td/utils/OptionsParser.h"
#include "td/utils/OptionParser.h"
#include "td/utils/FileLog.h"
#include "td/utils/port/path.h"
#include "td/utils/port/user.h"
#include "td/utils/filesystem.h"
#include "td/utils/overloaded.h"
#include "common/checksum.h"
#include "common/errorcode.h"
#include "tl-utils/tl-utils.hpp"
#include "auto/tl/ton_api_json.h"
#include "adnl-proxy-types.h"
#include "adnl-received-mask.h"
#include <map>
#include "git.h"
#if TD_DARWIN || TD_LINUX
#include <unistd.h>
@ -50,12 +53,19 @@ namespace ton {
namespace adnl {
namespace {
td::int32 start_time() {
static td::int32 t = static_cast<td::int32>(td::Clocks::system());
return t;
}
} // namespace
class Receiver : public td::actor::Actor {
public:
void start_up() override;
void receive_common(td::BufferSlice data);
void receive_from_client(td::BufferSlice data);
void receive_to_client(td::BufferSlice data);
void receive_common(td::IPAddress addr, td::BufferSlice data);
void receive_from_client(td::IPAddress addr, td::BufferSlice data);
void receive_to_client(td::IPAddress addr, td::BufferSlice data);
Receiver(td::uint16 in_port, td::uint16 out_port, std::shared_ptr<AdnlProxy> proxy, td::IPAddress client_addr)
: in_port_(in_port), out_port_(out_port), proxy_(std::move(proxy)), addr_(client_addr) {
@ -68,6 +78,10 @@ class Receiver : public td::actor::Actor {
td::IPAddress addr_;
td::actor::ActorOwn<td::UdpServer> out_udp_server_;
td::actor::ActorOwn<td::UdpServer> in_udp_server_;
td::int32 client_start_time_{0};
td::uint64 out_seqno_{0};
AdnlReceivedMaskVersion received_;
};
void Receiver::start_up() {
@ -81,15 +95,18 @@ void Receiver::start_up() {
const td::uint32 mode_;
void on_udp_message(td::UdpMessage udp_message) override {
if (udp_message.error.is_error()) {
LOG(DEBUG) << udp_message.error;
LOG(INFO) << "receifed udp message with error: " << udp_message.error;
return;
}
if (mode_ == 0) {
td::actor::send_closure_later(manager_, &Receiver::receive_common, std::move(udp_message.data));
td::actor::send_closure_later(manager_, &Receiver::receive_common, udp_message.address,
std::move(udp_message.data));
} else if (mode_ == 1) {
td::actor::send_closure_later(manager_, &Receiver::receive_from_client, std::move(udp_message.data));
td::actor::send_closure_later(manager_, &Receiver::receive_from_client, udp_message.address,
std::move(udp_message.data));
} else {
td::actor::send_closure_later(manager_, &Receiver::receive_to_client, std::move(udp_message.data));
td::actor::send_closure_later(manager_, &Receiver::receive_to_client, udp_message.address,
std::move(udp_message.data));
}
}
};
@ -108,46 +125,151 @@ void Receiver::start_up() {
}
}
void Receiver::receive_common(td::BufferSlice data) {
void Receiver::receive_common(td::IPAddress addr, td::BufferSlice data) {
if (data.size() <= 32) {
LOG(INFO) << "dropping too short packet: size=" << data.size();
return;
}
td::Bits256 id;
id.as_slice().copy_from(data.as_slice().truncate(32));
if (id.is_zero()) {
receive_from_client(std::move(data));
if (proxy_->id().as_slice() == data.as_slice().truncate(32)) {
receive_from_client(addr, std::move(data));
} else {
receive_to_client(std::move(data));
receive_to_client(addr, std::move(data));
}
}
void Receiver::receive_from_client(td::BufferSlice data) {
void Receiver::receive_from_client(td::IPAddress addr, td::BufferSlice data) {
auto F = proxy_->decrypt(std::move(data));
if (F.is_error()) {
LOG(INFO) << "proxy: failed to decrypt message from client: " << F.move_as_error();
return;
}
auto f = F.move_as_ok();
if (f.flags & (1 << 16)) {
LOG(INFO) << "proxy: dropping message from client: flag 16 is set";
return;
}
if (f.date) {
if (f.date + 60.0 < td::Clocks::system() || f.date - 60.0 > td::Clocks::system()) {
LOG(INFO) << "proxy: dropping message from client: date mismatch";
return;
}
}
if ((f.flags & 6) == 6) {
if (received_.packet_is_delivered(f.adnl_start_time, f.seqno)) {
LOG(INFO) << "proxy: dropping message from client: duplicate packet (or old seqno/start_time)";
return;
}
received_.deliver_packet(f.adnl_start_time, f.seqno);
}
if (f.flags & (1 << 17)) {
auto F = fetch_tl_object<ton_api::adnl_ProxyControlPacket>(std::move(f.data), true);
if (F.is_error()) {
LOG(INFO) << this << ": dropping proxy packet: bad control packet: " << F.move_as_error();
return;
}
ton_api::downcast_call(*F.move_as_ok().get(),
td::overloaded(
[&](const ton_api::adnl_proxyControlPacketPing &f) {
auto data = create_serialize_tl_object<ton_api::adnl_proxyControlPacketPong>(f.id_);
AdnlProxy::Packet p;
p.flags = 6 | (1 << 16) | (1 << 17);
if (addr.is_valid() && addr.is_ipv4()) {
p.flags |= 1;
p.ip = addr.get_ipv4();
p.port = static_cast<td::uint16>(addr.get_port());
} else {
p.ip = 0;
p.port = 0;
}
p.data = std::move(data);
p.adnl_start_time = start_time();
p.seqno = out_seqno_;
auto enc = proxy_->encrypt(std::move(p));
td::UdpMessage M;
M.address = addr;
M.data = std::move(enc);
td::actor::send_closure(
in_udp_server_.empty() ? out_udp_server_.get() : in_udp_server_.get(),
&td::UdpServer::send, std::move(M));
},
[&](const ton_api::adnl_proxyControlPacketPong &f) {},
[&](const ton_api::adnl_proxyControlPacketRegister &f) {
if (f.ip_ == 0 && f.port_ == 0) {
if (addr.is_valid() && addr.is_ipv4()) {
addr_ = addr;
}
} else {
td::IPAddress a;
auto S = a.init_host_port(td::IPAddress::ipv4_to_str(f.ip_), f.port_);
if (S.is_ok()) {
addr_ = a;
} else {
LOG(INFO) << "failed to init remote addr: " << S.move_as_error();
}
}
}));
return;
}
if (!(f.flags & 1)) {
LOG(INFO) << this << ": dropping proxy packet: no destination";
return;
}
td::IPAddress a;
if (a.init_ipv4_port(td::IPAddress::ipv4_to_str(f.ip), f.port).is_error()) {
LOG(INFO) << this << ": dropping proxy packet: invalid destination";
return;
}
if (!a.is_valid()) {
LOG(INFO) << this << ": dropping proxy packet: invalid destination";
return;
}
td::UdpMessage M;
M.address = a;
M.data = std::move(f.data);
LOG(DEBUG) << this << ": proxying DOWN packet of length " << M.data.size() << " to " << a;
td::actor::send_closure(out_udp_server_.empty() ? in_udp_server_.get() : out_udp_server_.get(), &td::UdpServer::send,
std::move(M));
}
void Receiver::receive_to_client(td::BufferSlice data) {
void Receiver::receive_to_client(td::IPAddress addr, td::BufferSlice data) {
LOG(DEBUG) << "proxying to " << addr_;
if (!addr_.is_valid() || !addr_.is_ipv4() || !addr_.get_ipv4()) {
LOG(INFO) << this << ": dropping external packet: client not inited";
return;
}
AdnlProxy::Packet p;
p.flags = (1 << 16);
if (addr.is_valid() && addr.is_ipv4()) {
p.flags |= 1;
p.ip = addr.get_ipv4();
p.port = static_cast<td::uint16>(addr.get_port());
} else {
p.ip = 0;
p.port = 0;
}
p.flags |= 2;
p.adnl_start_time = start_time();
p.flags |= 4;
p.seqno = ++out_seqno_;
p.data = std::move(data);
LOG(DEBUG) << this << ": proxying UP packet of length " << p.data.size() << " to " << addr_;
td::UdpMessage M;
M.address = addr_;
M.data = std::move(data);
M.data = proxy_->encrypt(std::move(p));
td::actor::send_closure(in_udp_server_.empty() ? out_udp_server_.get() : in_udp_server_.get(), &td::UdpServer::send,
std::move(M));
@ -175,12 +297,15 @@ int main(int argc, char *argv[]) {
std::string config = "/var/ton-work/etc/adnl-proxy.conf.json";
td::OptionsParser p;
td::OptionParser p;
p.set_description("validator or full node for TON network");
p.add_option('v', "verbosity", "set verbosity level", [&](td::Slice arg) {
int v = VERBOSITY_NAME(FATAL) + (td::to_integer<int>(arg));
SET_VERBOSITY_LEVEL(v);
return td::Status::OK();
});
p.add_option('V', "version", "shows adnl-proxy build information", [&]() {
std::cout << "adnl-proxy build information: [ Commit: " << GitMetadata::CommitSHA1() << ", Date: " << GitMetadata::CommitDate() << "]\n";
std::exit(0);
});
p.add_option('h', "help", "prints_help", [&]() {
char b[10240];
@ -188,42 +313,38 @@ int main(int argc, char *argv[]) {
sb << p;
std::cout << sb.as_cslice().c_str();
std::exit(2);
return td::Status::OK();
});
p.add_option('c', "config", "config file", [&](td::Slice arg) {
config = arg.str();
return td::Status::OK();
});
p.add_option('c', "config", "config file", [&](td::Slice arg) { config = arg.str(); });
p.add_option('d', "daemonize", "set SIGHUP", [&]() {
#if TD_DARWIN || TD_LINUX
close(0);
setsid();
#endif
td::set_signal_handler(td::SignalType::HangUp, force_rotate_logs).ensure();
return td::Status::OK();
});
p.add_option('l', "logname", "log to file", [&](td::Slice fname) {
p.add_checked_option('l', "logname", "log to file", [&](td::Slice fname) {
auto F = std::make_unique<td::FileLog>();
TRY_STATUS(F->init(fname.str(), std::numeric_limits<td::uint64>::max(), true));
TRY_STATUS(F->init(fname.str(), std::numeric_limits<td::int64>::max(), true));
logger_ = std::move(F);
td::log_interface = logger_.get();
return td::Status::OK();
});
td::uint32 threads = 7;
p.add_option('t', "threads", PSTRING() << "number of threads (default=" << threads << ")", [&](td::Slice fname) {
td::int32 v;
try {
v = std::stoi(fname.str());
} catch (...) {
return td::Status::Error(ton::ErrorCode::error, "bad value for --threads: not a number");
}
if (v < 1 || v > 256) {
return td::Status::Error(ton::ErrorCode::error, "bad value for --threads: should be in range [1..256]");
}
threads = v;
return td::Status::OK();
});
p.add_option('u', "user", "change user", [&](td::Slice user) { return td::change_user(user); });
p.add_checked_option(
't', "threads", PSTRING() << "number of threads (default=" << threads << ")", [&](td::Slice fname) {
td::int32 v;
try {
v = std::stoi(fname.str());
} catch (...) {
return td::Status::Error(ton::ErrorCode::error, "bad value for --threads: not a number");
}
if (v < 1 || v > 256) {
return td::Status::Error(ton::ErrorCode::error, "bad value for --threads: should be in range [1..256]");
}
threads = v;
return td::Status::OK();
});
p.add_checked_option('u', "user", "change user", [&](td::Slice user) { return td::change_user(user.str()); });
p.run(argc, argv).ensure();
@ -248,7 +369,9 @@ int main(int argc, char *argv[]) {
}
TRY_RESULT(proxy, ton::adnl::AdnlProxy::create(*y->proxy_type_.get()));
td::IPAddress a;
a.init_ipv4_port(td::IPAddress::ipv4_to_str(y->dst_ip_), static_cast<td::uint16>(y->dst_port_)).ensure();
if (y->dst_ip_ || y->dst_port_) {
a.init_ipv4_port(td::IPAddress::ipv4_to_str(y->dst_ip_), static_cast<td::uint16>(y->dst_port_)).ensure();
}
scheduler.run_in_context([&] {
x.push_back(td::actor::create_actor<ton::adnl::Receiver>("adnl-proxy", in_port, out_port, std::move(proxy), a));

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "adnl-query.h"
#include "common/errorcode.h"
@ -25,13 +25,16 @@ namespace ton {
namespace adnl {
void AdnlQuery::alarm() {
promise_.set_error(td::Status::Error(ErrorCode::timeout, "adnl query timeout"));
stop();
set_error(td::Status::Error(ErrorCode::timeout, "adnl query timeout"));
}
void AdnlQuery::result(td::BufferSlice data) {
promise_.set_value(std::move(data));
stop();
}
void AdnlQuery::set_error(td::Status error) {
promise_.set_error(std::move(error));
stop();
}
AdnlQueryId AdnlQuery::random_query_id() {
AdnlQueryId q_id;

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
@ -48,6 +48,7 @@ class AdnlQuery : public td::actor::Actor {
}
void alarm() override;
void result(td::BufferSlice data);
void set_error(td::Status error);
void start_up() override {
alarm_timestamp() = timeout_;
}

102
adnl/adnl-received-mask.h Normal file
View file

@ -0,0 +1,102 @@
/*
This file is part of TON Blockchain Library.
TON Blockchain Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
TON Blockchain Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
#include "td/utils/int_types.h"
#include "td/utils/logging.h"
namespace ton {
namespace adnl {
class AdnlReceivedMask {
public:
void reset() {
seqno_ = 0;
mask_ = 0;
}
bool packet_is_delivered(td::int64 seqno) const {
if (seqno <= 0) {
return false;
}
if (seqno + 64 <= seqno_) {
return true;
}
if (seqno > seqno_) {
return false;
}
return mask_ & (1ull << (seqno_ - seqno));
}
void deliver_packet(td::int64 seqno) {
CHECK(!packet_is_delivered(seqno));
CHECK(seqno > 0);
if (seqno <= seqno_) {
mask_ |= (1ull << (seqno_ - seqno));
} else {
auto old = seqno_;
seqno_ = seqno;
if (seqno_ - old >= 64) {
mask_ = 1;
} else {
mask_ = mask_ << (seqno_ - old);
mask_ |= 1;
}
}
}
private:
td::int64 seqno_{0};
td::uint64 mask_{0};
};
class AdnlReceivedMaskVersion {
public:
bool packet_is_delivered(td::int32 utime, td::uint64 seqno) {
if (utime < utime_) {
return true;
} else if (utime == utime_) {
return mask_.packet_is_delivered(seqno);
} else {
return false;
}
}
void deliver_packet(td::int32 utime, td::uint64 seqno) {
CHECK(utime >= utime_);
if (utime == utime_) {
mask_.deliver_packet(seqno);
} else {
utime_ = utime;
mask_.reset();
mask_.deliver_packet(seqno);
}
}
void reset() {
mask_.reset();
utime_ = 0;
}
private:
AdnlReceivedMask mask_;
td::int32 utime_{0};
};
} // namespace adnl
} // namespace ton

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "adnl-static-nodes.h"
#include "adnl-static-nodes.hpp"

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "adnl-test-loopback-implementation.h"

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
@ -34,9 +34,10 @@ class TestLoopbackNetworkManager : public ton::adnl::AdnlNetworkManager {
callback_ = std::move(callback);
}
void add_self_addr(td::IPAddress addr, td::uint32 priority) override {
void add_self_addr(td::IPAddress addr, AdnlCategoryMask cat_mask, td::uint32 priority) override {
}
void add_proxy_addr(td::IPAddress addr, std::shared_ptr<AdnlProxy> proxy, td::uint32 priority) override {
void add_proxy_addr(td::IPAddress addr, td::uint16 local_port, std::shared_ptr<AdnlProxy> proxy,
AdnlCategoryMask cat_mask, td::uint32 priority) override {
}
void send_udp_packet(ton::adnl::AdnlNodeIdShort src_id, ton::adnl::AdnlNodeIdShort dst_id, td::IPAddress dst_addr,
td::uint32 priority, td::BufferSlice data) override {
@ -48,7 +49,9 @@ class TestLoopbackNetworkManager : public ton::adnl::AdnlNetworkManager {
return;
}
CHECK(callback_);
callback_->receive_packet(dst_addr, std::move(data));
AdnlCategoryMask m;
m[0] = true;
callback_->receive_packet(dst_addr, std::move(m), std::move(data));
}
void add_node_id(AdnlNodeIdShort id, bool allow_send, bool allow_receive) {
@ -68,6 +71,8 @@ class TestLoopbackNetworkManager : public ton::adnl::AdnlNetworkManager {
CHECK(p >= 0 && p <= 1);
loss_probability_ = p;
}
void set_local_id_category(AdnlNodeIdShort id, td::uint8 cat) override {
}
TestLoopbackNetworkManager() {
}

115
adnl/adnl-tunnel.cpp Normal file
View file

@ -0,0 +1,115 @@
/*
This file is part of TON Blockchain Library.
TON Blockchain Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
TON Blockchain Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2020 Telegram Systems LLP
*/
#include "adnl-tunnel.h"
#include "adnl-peer-table.h"
namespace ton {
namespace adnl {
void AdnlInboundTunnelEndpoint::receive_packet(AdnlNodeIdShort src, td::IPAddress src_addr, td::BufferSlice datagram) {
receive_packet_cont(src, src_addr, std::move(datagram), 0);
}
void AdnlInboundTunnelEndpoint::receive_packet_cont(AdnlNodeIdShort src, td::IPAddress src_addr,
td::BufferSlice datagram, size_t idx) {
if (datagram.size() <= 32) {
VLOG(ADNL_INFO) << "dropping too short datagram";
return;
}
if (datagram.as_slice().truncate(32) != decrypt_via_[idx].as_slice()) {
VLOG(ADNL_INFO) << "invalid tunnel midpoint";
return;
}
datagram.confirm_read(32);
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), src, src_addr, idx](td::Result<td::BufferSlice> R) {
if (R.is_error()) {
VLOG(ADNL_INFO) << "dropping tunnel packet: failed to decrypt: " << R.move_as_error();
return;
} else {
td::actor::send_closure(SelfId, &AdnlInboundTunnelEndpoint::decrypted_packet, src, src_addr, R.move_as_ok(), idx);
}
});
td::actor::send_closure(keyring_, &keyring::Keyring::decrypt_message, decrypt_via_[idx], std::move(datagram),
std::move(P));
}
void AdnlInboundTunnelEndpoint::decrypted_packet(AdnlNodeIdShort src, td::IPAddress src_addr, td::BufferSlice data,
size_t idx) {
if (idx == decrypt_via_.size() - 1) {
td::actor::send_closure(adnl_, &AdnlPeerTable::receive_packet, src_addr, std::move(data));
return;
}
auto F = fetch_tl_object<ton_api::adnl_tunnelPacketContents>(std::move(data), true);
if (F.is_error()) {
VLOG(ADNL_INFO) << "dropping tunnel packet: failed to fetch: " << F.move_as_error();
return;
}
auto packet = F.move_as_ok();
td::IPAddress addr;
if (packet->flags_ & 1) {
addr.init_host_port(td::IPAddress::ipv4_to_str(packet->from_ip_), packet->from_port_).ignore();
}
if (packet->flags_ & 2) {
receive_packet_cont(src, addr, std::move(packet->message_), idx + 1);
}
}
void AdnlInboundTunnelMidpoint::start_up() {
encrypt_key_hash_ = encrypt_via_.compute_short_id();
auto R = encrypt_via_.create_encryptor();
if (R.is_error()) {
return;
}
encryptor_ = R.move_as_ok();
}
void AdnlInboundTunnelMidpoint::receive_packet(AdnlNodeIdShort src, td::IPAddress src_addr, td::BufferSlice datagram) {
if (!encryptor_) {
return;
}
auto obj = create_tl_object<ton_api::adnl_tunnelPacketContents>();
obj->flags_ = 2;
obj->message_ = std::move(datagram);
if (src_addr.is_valid() && src_addr.is_ipv4()) {
obj->flags_ |= 1;
obj->from_ip_ = src_addr.get_ipv4();
obj->from_port_ = src_addr.get_port();
}
auto packet = serialize_tl_object(std::move(obj), true);
auto dataR = encryptor_->encrypt(packet.as_slice());
if (dataR.is_error()) {
return;
}
auto data = dataR.move_as_ok();
td::BufferSlice enc{data.size() + 32};
auto S = enc.as_slice();
S.copy_from(encrypt_key_hash_.as_slice());
S.remove_prefix(32);
S.copy_from(data.as_slice());
td::actor::send_closure(adnl_, &Adnl::send_message_ex, proxy_as_, proxy_to_, std::move(enc),
Adnl::SendFlags::direct_only);
}
} // namespace adnl
} // namespace ton

91
adnl/adnl-tunnel.h Normal file
View file

@ -0,0 +1,91 @@
/*
This file is part of TON Blockchain Library.
TON Blockchain Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
TON Blockchain Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
#include "adnl.h"
#include "adnl-peer-table.h"
#include "keys/encryptor.h"
#include <map>
namespace ton {
namespace adnl {
class AdnlInboundTunnelPoint : public AdnlTunnel {
public:
virtual ~AdnlInboundTunnelPoint() = default;
virtual void receive_packet(AdnlNodeIdShort src, td::IPAddress src_addr, td::BufferSlice datagram) = 0;
};
class AdnlInboundTunnelEndpoint : public AdnlInboundTunnelPoint {
public:
AdnlInboundTunnelEndpoint(PublicKeyHash pubkey_hash, std::vector<PublicKeyHash> decrypt_via, AdnlNodeIdShort proxy_to,
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<AdnlPeerTable> adnl)
: pubkey_hash_(std::move(pubkey_hash))
, decrypt_via_(std::move(decrypt_via))
, proxy_to_(std::move(proxy_to))
, keyring_(std::move(keyring))
, adnl_(std::move(adnl)) {
}
void receive_packet(AdnlNodeIdShort src, td::IPAddress src_addr, td::BufferSlice datagram) override;
void receive_packet_cont(AdnlNodeIdShort src, td::IPAddress src_addr, td::BufferSlice datagram, size_t idx);
void decrypted_packet(AdnlNodeIdShort src, td::IPAddress src_addr, td::BufferSlice data, size_t idx);
private:
PublicKeyHash pubkey_hash_;
std::vector<PublicKeyHash> decrypt_via_;
AdnlNodeIdShort proxy_to_;
td::actor::ActorId<keyring::Keyring> keyring_;
td::actor::ActorId<AdnlPeerTable> adnl_;
};
class AdnlInboundTunnelMidpoint : public AdnlInboundTunnelPoint {
public:
AdnlInboundTunnelMidpoint(ton::PublicKey encrypt_via, AdnlNodeIdShort proxy_to, AdnlNodeIdShort proxy_as,
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<AdnlPeerTable> adnl)
: encrypt_via_(std::move(encrypt_via)), proxy_to_(proxy_to), proxy_as_(proxy_as), keyring_(keyring), adnl_(adnl) {
}
void start_up() override;
void receive_packet(AdnlNodeIdShort src, td::IPAddress src_addr, td::BufferSlice datagram) override;
private:
ton::PublicKeyHash encrypt_key_hash_;
ton::PublicKey encrypt_via_;
std::unique_ptr<Encryptor> encryptor_;
AdnlNodeIdShort proxy_to_;
AdnlNodeIdShort proxy_as_;
td::actor::ActorId<keyring::Keyring> keyring_;
td::actor::ActorId<AdnlPeerTable> adnl_;
};
class AdnlProxyNode : public td::actor::Actor {
public:
void receive_message(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::BufferSlice data);
void receive_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::BufferSlice data,
td::Promise<td::BufferSlice> promise);
private:
std::map<PublicKeyHash, td::actor::ActorOwn<AdnlInboundTunnelMidpoint>> mid_;
};
} // namespace adnl
} // namespace ton

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
@ -34,6 +34,8 @@ class Dht;
namespace adnl {
enum class AdnlLocalIdMode : td::uint32 { direct_only = 1, drop_from_net = 2 };
class AdnlNetworkManager;
class AdnlExtServer : public td::actor::Actor {
@ -54,8 +56,11 @@ class AdnlSenderInterface : public td::actor::Actor {
virtual void send_query_ex(AdnlNodeIdShort src, AdnlNodeIdShort dst, std::string name,
td::Promise<td::BufferSlice> promise, td::Timestamp timeout, td::BufferSlice data,
td::uint64 max_answer_size) = 0;
virtual void get_conn_ip_str(AdnlNodeIdShort l_id, AdnlNodeIdShort p_id, td::Promise<td::string> promise) = 0;
};
class AdnlTunnel : public td::actor::Actor {};
class Adnl : public AdnlSenderInterface {
public:
class Callback {
@ -73,6 +78,11 @@ class Adnl : public AdnlSenderInterface {
return 1024 * 8;
}
struct SendFlags {
enum Flags : td::uint32 { direct_only = 1 };
};
virtual void send_message_ex(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::BufferSlice data, td::uint32 flags) = 0;
// adds node to peer table
// used mostly from DHT to avoid loops
virtual void add_peer(AdnlNodeIdShort local_id, AdnlNodeIdFull id, AdnlAddressList addr_list) = 0;
@ -81,9 +91,14 @@ class Adnl : public AdnlSenderInterface {
virtual void add_static_nodes_from_config(AdnlNodesList nodes) = 0;
// adds local id. After that you can send/receive messages from/to this id
virtual void add_id(AdnlNodeIdFull id, AdnlAddressList addr_list) = 0;
void add_id(AdnlNodeIdFull id, AdnlAddressList addr_list, td::uint8 cat) {
add_id_ex(std::move(id), std::move(addr_list), cat, 0);
}
virtual void add_id_ex(AdnlNodeIdFull id, AdnlAddressList addr_list, td::uint8 cat, td::uint32 mode) = 0;
virtual void del_id(AdnlNodeIdShort id, td::Promise<td::Unit> promise) = 0;
virtual void check_id_exists(AdnlNodeIdShort id, td::Promise<bool> promise) = 0;
// subscribe to (some) messages(+queries) to this local id
virtual void subscribe(AdnlNodeIdShort dst, std::string prefix, std::unique_ptr<Callback> callback) = 0;
virtual void unsubscribe(AdnlNodeIdShort dst, std::string prefix) = 0;
@ -103,6 +118,8 @@ class Adnl : public AdnlSenderInterface {
virtual void create_ext_server(std::vector<AdnlNodeIdShort> ids, std::vector<td::uint16> ports,
td::Promise<td::actor::ActorOwn<AdnlExtServer>> promise) = 0;
virtual void create_tunnel(AdnlNodeIdShort dst, td::uint32 size,
td::Promise<std::pair<td::actor::ActorOwn<AdnlTunnel>, AdnlAddress>> promise) = 0;
static td::actor::ActorOwn<Adnl> create(std::string db, td::actor::ActorId<keyring::Keyring> keyring);

View file

@ -23,7 +23,7 @@
exception statement from your version. If you delete this exception statement
from all source files in the program, then also delete it here.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "adnl/adnl-network-manager.h"
#include "adnl/adnl-peer-table.h"
@ -31,7 +31,7 @@
#include "keys/encryptor.h"
#include "td/utils/Time.h"
#include "td/utils/format.h"
#include "td/utils/OptionsParser.h"
#include "td/utils/OptionParser.h"
#include <iostream>
#include <sstream>
@ -168,7 +168,7 @@ td::Result<td::UInt256> get_uint256(std::string str) {
int main(int argc, char *argv[]) {
td::actor::ActorOwn<AdnlNode> x;
td::OptionsParser p;
td::OptionParser p;
p.set_description("test basic adnl functionality");
p.add_option('h', "help", "prints_help", [&]() {
char b[10240];

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "utils.hpp"
#include "tl/tl_object_store.h"

View file

@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once

View file

@ -0,0 +1,55 @@
with_artifacts=false
while getopts 'a' flag; do
case "${flag}" in
a) with_artifacts=true ;;
*) break
;;
esac
done
if [ ! -d android-ndk-r25b ]; then
rm android-ndk-r25b-linux.zip
wget -q https://dl.google.com/android/repository/android-ndk-r25b-linux.zip
unzip -q android-ndk-r25b-linux.zip
test $? -eq 0 || { echo "Can't unzip android-ndk-r25b-linux.zip"; exit 1; }
echo Android NDK extracted
else
echo Using extracted Android NDK
fi
export JAVA_AWT_LIBRARY=NotNeeded
export JAVA_JVM_LIBRARY=NotNeeded
export JAVA_INCLUDE_PATH=${JAVA_HOME}/include
export JAVA_AWT_INCLUDE_PATH=${JAVA_HOME}/include
export JAVA_INCLUDE_PATH2=${JAVA_HOME}/include/linux
export ANDROID_NDK_ROOT=$(pwd)/android-ndk-r25b
export NDK_PLATFORM="android-21"
export ANDROID_PLATFORM="android-21"
export OPENSSL_DIR=$(pwd)/example/android/third_party/crypto
rm -rf example/android/src/drinkless/org/ton/TonApi.java
cd example/android/
rm CMakeCache.txt .ninja_*
cmake -GNinja -DTON_ONLY_TONLIB=ON .
test $? -eq 0 || { echo "Can't configure TON"; exit 1; }
ninja prepare_cross_compiling
test $? -eq 0 || { echo "Can't compile prepare_cross_compiling"; exit 1; }
rm CMakeCache.txt .ninja_*
. ./build-all.sh
find . -name "*.debug" -type f -delete
if [ "$with_artifacts" = true ]; then
cd ../..
mkdir -p artifacts/tonlib-android-jni
cp example/android/src/drinkless/org/ton/TonApi.java artifacts/tonlib-android-jni/
cp -R example/android/libs/* artifacts/tonlib-android-jni/
fi

View file

@ -0,0 +1,236 @@
pipeline {
agent none
stages {
stage('Run Builds') {
parallel {
stage('Ubuntu 20.04 x86-64 (shared)') {
agent {
label 'Ubuntu_x86-64'
}
steps {
timeout(time: 180, unit: 'MINUTES') {
sh '''
cp assembly/native/build-ubuntu-shared.sh .
chmod +x build-ubuntu-shared.sh
./build-ubuntu-shared.sh -t -a
'''
sh '''
cd artifacts
zip -9r ton-x86_64-linux-shared ./*
'''
archiveArtifacts artifacts: 'artifacts/ton-x86_64-linux-shared.zip'
}
}
}
stage('Ubuntu 20.04 x86-64 (portable)') {
agent {
label 'Ubuntu_x86-64'
}
steps {
timeout(time: 180, unit: 'MINUTES') {
sh '''
cp assembly/nix/build-linux-x86-64-nix.sh .
chmod +x build-linux-x86-64-nix.sh
./build-linux-x86-64-nix.sh -t
'''
sh '''
cd artifacts
zip -9r ton-x86-64-linux-portable ./*
'''
archiveArtifacts artifacts: 'artifacts/ton-x86-64-linux-portable.zip'
}
}
}
stage('Ubuntu 20.04 aarch64 (shared)') {
agent {
label 'Ubuntu_arm64'
}
steps {
timeout(time: 180, unit: 'MINUTES') {
sh '''
cp assembly/native/build-ubuntu-shared.sh .
chmod +x build-ubuntu-shared.sh
./build-ubuntu-shared.sh -t -a
'''
sh '''
cd artifacts
zip -9r ton-arm64-linux-shared ./*
'''
archiveArtifacts artifacts: 'artifacts/ton-arm64-linux-shared.zip'
}
}
}
stage('Ubuntu 20.04 aarch64 (portable)') {
agent {
label 'Ubuntu_arm64'
}
steps {
timeout(time: 180, unit: 'MINUTES') {
sh '''
cp assembly/nix/build-linux-arm64-nix.sh .
chmod +x build-linux-arm64-nix.sh
./build-linux-arm64-nix.sh -t
'''
sh '''
cd artifacts
zip -9r ton-arm64-linux-portable ./*
'''
archiveArtifacts artifacts: 'artifacts/ton-arm64-linux-portable.zip'
}
}
}
stage('macOS 12.7 x86-64 (shared)') {
agent {
label 'macOS_12.7_x86-64'
}
steps {
timeout(time: 180, unit: 'MINUTES') {
sh '''
cp assembly/native/build-macos-shared.sh .
chmod +x build-macos-shared.sh
./build-macos-shared.sh -t -a
'''
sh '''
cd artifacts
zip -9r ton-x86-64-macos-shared ./*
'''
archiveArtifacts artifacts: 'artifacts/ton-x86-64-macos-shared.zip'
}
}
}
stage('macOS 12.7 x86-64 (portable)') {
agent {
label 'macOS_12.7_x86-64'
}
steps {
timeout(time: 180, unit: 'MINUTES') {
sh '''
cp assembly/nix/build-macos-nix.sh .
chmod +x build-macos-nix.sh
./build-macos-nix.sh -t
'''
sh '''
cd artifacts
zip -9r ton-x86-64-macos-portable ./*
'''
archiveArtifacts artifacts: 'artifacts/ton-x86-64-macos-portable.zip'
}
}
}
stage('macOS 12.6 aarch64 (shared)') {
agent {
label 'macOS_12.6-arm64-m1'
}
steps {
timeout(time: 180, unit: 'MINUTES') {
sh '''
cp assembly/native/build-macos-shared.sh .
chmod +x build-macos-shared.sh
./build-macos-shared.sh -t -a
'''
sh '''
cd artifacts
zip -9r ton-arm64-macos-m1-shared ./*
'''
archiveArtifacts artifacts: 'artifacts/ton-arm64-macos-m1-shared.zip'
}
}
}
stage('macOS 12.6 aarch64 (portable)') {
agent {
label 'macOS_12.6-arm64-m1'
}
steps {
timeout(time: 180, unit: 'MINUTES') {
sh '''
cp assembly/nix/build-macos-nix.sh .
chmod +x build-macos-nix.sh
./build-macos-nix.sh -t
'''
sh '''
cd artifacts
zip -9r ton-arm64-macos-portable ./*
'''
archiveArtifacts artifacts: 'artifacts/ton-arm64-macos-portable.zip'
}
}
}
stage('macOS 13.2 aarch64 (shared)') {
agent {
label 'macOS_13.2-arm64-m2'
}
steps {
timeout(time: 180, unit: 'MINUTES') {
sh '''
cp assembly/native/build-macos-shared.sh .
chmod +x build-macos-shared.sh
./build-macos-shared.sh -t -a
'''
sh '''
cd artifacts
zip -9r ton-arm64-macos-m2-shared ./*
'''
archiveArtifacts artifacts: 'artifacts/ton-arm64-macos-m2-shared.zip'
}
}
}
stage('Windows Server 2022 x86-64') {
agent {
label 'Windows_x86-64'
}
steps {
timeout(time: 180, unit: 'MINUTES') {
bat '''
copy assembly\\native\\build-windows.bat .
build-windows.bat -t
'''
bat '''
cd artifacts
zip -9r ton-x86-64-windows ./*
'''
archiveArtifacts artifacts: 'artifacts/ton-x86-64-windows.zip'
}
}
}
stage('Android Tonlib') {
agent {
label 'Ubuntu_x86-64'
}
steps {
timeout(time: 180, unit: 'MINUTES') {
sh '''
cp assembly/android/build-android-tonlib.sh .
chmod +x build-android-tonlib.sh
./build-android-tonlib.sh -a
'''
sh '''
cd artifacts/tonlib-android-jni
zip -9r ton-android-tonlib ./*
'''
archiveArtifacts artifacts: 'artifacts/tonlib-android-jni/ton-android-tonlib.zip'
}
}
}
stage('WASM fift func emulator') {
agent {
label 'Ubuntu_x86-64'
}
steps {
timeout(time: 180, unit: 'MINUTES') {
sh '''
cd assembly/wasm
chmod +x fift-func-wasm-build-ubuntu.sh
./fift-func-wasm-build-ubuntu.sh -a
'''
sh '''
cd artifacts
zip -9r ton-wasm-binaries ./*
'''
archiveArtifacts artifacts: 'artifacts/ton-wasm-binaries.zip'
}
}
}
}
}
}
}

View file

@ -0,0 +1,225 @@
#/bin/bash
with_tests=false
with_artifacts=false
OSX_TARGET=10.15
while getopts 'tao:' flag; do
case "${flag}" in
t) with_tests=true ;;
a) with_artifacts=true ;;
o) OSX_TARGET=${OPTARG} ;;
*) break
;;
esac
done
if [ ! -d "build" ]; then
mkdir build
cd build
else
cd build
rm -rf .ninja* CMakeCache.txt
fi
export NONINTERACTIVE=1
brew install ninja pkg-config automake libtool autoconf
brew install llvm@16
if [ -f /opt/homebrew/opt/llvm@16/bin/clang ]; then
export CC=/opt/homebrew/opt/llvm@16/bin/clang
export CXX=/opt/homebrew/opt/llvm@16/bin/clang++
else
export CC=/usr/local/opt/llvm@16/bin/clang
export CXX=/usr/local/opt/llvm@16/bin/clang++
fi
export CCACHE_DISABLE=1
if [ ! -d "lz4" ]; then
git clone https://github.com/lz4/lz4.git
cd lz4
lz4Path=`pwd`
git checkout v1.9.4
make -j12
test $? -eq 0 || { echo "Can't compile lz4"; exit 1; }
cd ..
# ./lib/liblz4.a
# ./lib
else
lz4Path=$(pwd)/lz4
echo "Using compiled lz4"
fi
if [ ! -d "secp256k1" ]; then
git clone https://github.com/bitcoin-core/secp256k1.git
cd secp256k1
secp256k1Path=`pwd`
git checkout v0.3.2
./autogen.sh
./configure --enable-module-recovery --enable-static --disable-tests --disable-benchmark --with-pic
make -j12
test $? -eq 0 || { echo "Can't compile secp256k1"; exit 1; }
cd ..
else
secp256k1Path=$(pwd)/secp256k1
echo "Using compiled secp256k1"
fi
if [ ! -d "libsodium" ]; then
export LIBSODIUM_FULL_BUILD=1
git clone https://github.com/jedisct1/libsodium.git
cd libsodium
sodiumPath=`pwd`
git checkout 1.0.18
./autogen.sh
./configure --with-pic --enable-static
make -j12
test $? -eq 0 || { echo "Can't compile libsodium"; exit 1; }
cd ..
else
sodiumPath=$(pwd)/libsodium
echo "Using compiled libsodium"
fi
if [ ! -d "openssl_3" ]; then
git clone https://github.com/openssl/openssl openssl_3
cd openssl_3
opensslPath=`pwd`
git checkout openssl-3.1.4
./config -static
make build_libs -j12
test $? -eq 0 || { echo "Can't compile openssl_3"; exit 1; }
cd ..
else
opensslPath=$(pwd)/openssl_3
echo "Using compiled openssl_3"
fi
if [ ! -d "zlib" ]; then
git clone https://github.com/madler/zlib.git
cd zlib
zlibPath=`pwd`
./configure --static
make -j12
test $? -eq 0 || { echo "Can't compile zlib"; exit 1; }
cd ..
else
zlibPath=$(pwd)/zlib
echo "Using compiled zlib"
fi
if [ ! -d "libmicrohttpd" ]; then
git clone https://git.gnunet.org/libmicrohttpd.git
cd libmicrohttpd
libmicrohttpdPath=`pwd`
./autogen.sh
./configure --enable-static --disable-tests --disable-benchmark --disable-shared --disable-https --with-pic
make -j12
test $? -eq 0 || { echo "Can't compile libmicrohttpd"; exit 1; }
cd ..
else
libmicrohttpdPath=$(pwd)/libmicrohttpd
echo "Using compiled libmicrohttpd"
fi
cmake -GNinja .. \
-DPORTABLE=1 \
-DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=$OSX_TARGET \
-DCMAKE_CXX_FLAGS="-stdlib=libc++" \
-DCMAKE_BUILD_TYPE=Release \
-DOPENSSL_FOUND=1 \
-DOPENSSL_INCLUDE_DIR=$opensslPath/include \
-DOPENSSL_CRYPTO_LIBRARY=$opensslPath/libcrypto.a \
-DZLIB_FOUND=1 \
-DZLIB_INCLUDE_DIR=$zlibPath \
-DZLIB_LIBRARIES=$zlibPath/libz.a \
-DSECP256K1_FOUND=1 \
-DSECP256K1_INCLUDE_DIR=$secp256k1Path/include \
-DSECP256K1_LIBRARY=$secp256k1Path/.libs/libsecp256k1.a \
-DSODIUM_FOUND=1 \
-DSODIUM_INCLUDE_DIR=$sodiumPath/src/libsodium/include \
-DSODIUM_LIBRARY_RELEASE=$sodiumPath/src/libsodium/.libs/libsodium.a \
-DMHD_FOUND=1 \
-DMHD_INCLUDE_DIR=$libmicrohttpdPath/src/include \
-DMHD_LIBRARY=$libmicrohttpdPath/src/microhttpd/.libs/libmicrohttpd.a \
-DLZ4_FOUND=1 \
-DLZ4_INCLUDE_DIRS=$lz4Path/lib \
-DLZ4_LIBRARIES=$lz4Path/lib/liblz4.a
test $? -eq 0 || { echo "Can't configure ton"; exit 1; }
if [ "$with_tests" = true ]; then
ninja storage-daemon storage-daemon-cli blockchain-explorer \
tonlib tonlibjson tonlib-cli validator-engine func fift \
lite-client pow-miner validator-engine-console generate-random-id json2tlo dht-server \
http-proxy rldp-http-proxy adnl-proxy create-state create-hardfork tlbc emulator \
test-ed25519 test-ed25519-crypto test-bigint test-vm test-fift test-cells test-smartcont \
test-net test-tdactor test-tdutils test-tonlib-offline test-adnl test-dht test-rldp \
test-rldp2 test-catchain test-fec test-tddb test-db test-validator-session-state
test $? -eq 0 || { echo "Can't compile ton"; exit 1; }
else
ninja storage-daemon storage-daemon-cli blockchain-explorer \
tonlib tonlibjson tonlib-cli validator-engine func fift \
lite-client pow-miner validator-engine-console generate-random-id json2tlo dht-server \
http-proxy rldp-http-proxy adnl-proxy create-state create-hardfork tlbc emulator
test $? -eq 0 || { echo "Can't compile ton"; exit 1; }
fi
strip storage/storage-daemon/storage-daemon
strip storage/storage-daemon/storage-daemon-cli
strip blockchain-explorer/blockchain-explorer
strip crypto/fift
strip crypto/func
strip crypto/create-state
strip crypto/tlbc
strip validator-engine-console/validator-engine-console
strip tonlib/tonlib-cli
strip http/http-proxy
strip rldp-http-proxy/rldp-http-proxy
strip dht-server/dht-server
strip lite-client/lite-client
strip validator-engine/validator-engine
strip utils/generate-random-id
strip utils/json2tlo
strip adnl/adnl-proxy
cd ..
if [ "$with_artifacts" = true ]; then
echo Creating artifacts...
rm -rf artifacts
mkdir artifacts
cp crypto/fift/lib artifacts/
cp -R crypto/smartcont/ artifacts/
cp build/storage/storage-daemon/storage-daemon artifacts/
cp build/storage/storage-daemon/storage-daemon-cli artifacts/
cp build/blockchain-explorer/blockchain-explorer artifacts/
cp build/crypto/fift artifacts/
cp build/crypto/func artifacts/
cp build/crypto/create-state artifacts/
cp build/crypto/tlbc artifacts/
cp build/validator-engine-console/validator-engine-console artifacts/
cp build/tonlib/tonlib-cli artifacts/
cp build/tonlib/libtonlibjson.0.5.dylib artifacts/libtonlibjson.dylib
cp build/http/http-proxy artifacts/
cp build/rldp-http-proxy/rldp-http-proxy artifacts/
cp build/dht-server/dht-server artifacts/
cp build/lite-client/lite-client artifacts/
cp build/validator-engine/validator-engine artifacts/
cp build/utils/generate-random-id artifacts/
cp build/utils/json2tlo artifacts/
cp build/adnl/adnl-proxy artifacts/
cp build/emulator/libemulator.dylib artifacts/
chmod +x artifacts/*
rsync -r crypto/smartcont artifacts/
rsync -r crypto/fift/lib artifacts/
fi
if [ "$with_tests" = true ]; then
cd build
# ctest --output-on-failure -E "test-catchain|test-actors"
ctest --output-on-failure
fi

View file

@ -0,0 +1,152 @@
#/bin/bash
with_tests=false
with_artifacts=false
OSX_TARGET=10.15
while getopts 'tao:' flag; do
case "${flag}" in
t) with_tests=true ;;
a) with_artifacts=true ;;
o) OSX_TARGET=${OPTARG} ;;
*) break
;;
esac
done
if [ ! -d "build" ]; then
mkdir build
cd build
else
cd build
rm -rf .ninja* CMakeCache.txt
fi
export NONINTERACTIVE=1
brew install ninja libsodium libmicrohttpd pkg-config automake libtool autoconf gnutls
brew install llvm@16
if [ -f /opt/homebrew/opt/llvm@16/bin/clang ]; then
export CC=/opt/homebrew/opt/llvm@16/bin/clang
export CXX=/opt/homebrew/opt/llvm@16/bin/clang++
else
export CC=/usr/local/opt/llvm@16/bin/clang
export CXX=/usr/local/opt/llvm@16/bin/clang++
fi
export CCACHE_DISABLE=1
if [ ! -d "secp256k1" ]; then
git clone https://github.com/bitcoin-core/secp256k1.git
cd secp256k1
secp256k1Path=`pwd`
git checkout v0.3.2
./autogen.sh
./configure --enable-module-recovery --enable-static --disable-tests --disable-benchmark
make -j12
test $? -eq 0 || { echo "Can't compile secp256k1"; exit 1; }
cd ..
else
secp256k1Path=$(pwd)/secp256k1
echo "Using compiled secp256k1"
fi
if [ ! -d "lz4" ]; then
git clone https://github.com/lz4/lz4
cd lz4
lz4Path=`pwd`
git checkout v1.9.4
make -j12
test $? -eq 0 || { echo "Can't compile lz4"; exit 1; }
cd ..
else
lz4Path=$(pwd)/lz4
echo "Using compiled lz4"
fi
brew unlink openssl@1.1
brew install openssl@3
brew unlink openssl@3 && brew link --overwrite openssl@3
cmake -GNinja -DCMAKE_BUILD_TYPE=Release .. \
-DCMAKE_CXX_FLAGS="-stdlib=libc++" \
-DSECP256K1_FOUND=1 \
-DSECP256K1_INCLUDE_DIR=$secp256k1Path/include \
-DSECP256K1_LIBRARY=$secp256k1Path/.libs/libsecp256k1.a \
-DLZ4_FOUND=1 \
-DLZ4_LIBRARIES=$lz4Path/lib/liblz4.a \
-DLZ4_INCLUDE_DIRS=$lz4Path/lib
test $? -eq 0 || { echo "Can't configure ton"; exit 1; }
if [ "$with_tests" = true ]; then
ninja storage-daemon storage-daemon-cli blockchain-explorer \
tonlib tonlibjson tonlib-cli validator-engine func fift \
lite-client pow-miner validator-engine-console generate-random-id json2tlo dht-server \
http-proxy rldp-http-proxy adnl-proxy create-state create-hardfork tlbc emulator \
test-ed25519 test-ed25519-crypto test-bigint test-vm test-fift test-cells test-smartcont \
test-net test-tdactor test-tdutils test-tonlib-offline test-adnl test-dht test-rldp \
test-rldp2 test-catchain test-fec test-tddb test-db test-validator-session-state
test $? -eq 0 || { echo "Can't compile ton"; exit 1; }
else
ninja storage-daemon storage-daemon-cli blockchain-explorer \
tonlib tonlibjson tonlib-cli validator-engine func fift \
lite-client pow-miner validator-engine-console generate-random-id json2tlo dht-server \
http-proxy rldp-http-proxy adnl-proxy create-state create-hardfork tlbc emulator
test $? -eq 0 || { echo "Can't compile ton"; exit 1; }
fi
strip storage/storage-daemon/storage-daemon
strip storage/storage-daemon/storage-daemon-cli
strip blockchain-explorer/blockchain-explorer
strip crypto/fift
strip crypto/func
strip crypto/create-state
strip crypto/tlbc
strip validator-engine-console/validator-engine-console
strip tonlib/tonlib-cli
strip http/http-proxy
strip rldp-http-proxy/rldp-http-proxy
strip dht-server/dht-server
strip lite-client/lite-client
strip validator-engine/validator-engine
strip utils/generate-random-id
strip utils/json2tlo
strip adnl/adnl-proxy
cd ..
if [ "$with_artifacts" = true ]; then
echo Creating artifacts...
rm -rf artifacts
mkdir artifacts
cp build/storage/storage-daemon/storage-daemon artifacts/
cp build/storage/storage-daemon/storage-daemon-cli artifacts/
cp build/blockchain-explorer/blockchain-explorer artifacts/
cp build/crypto/fift artifacts/
cp build/crypto/func artifacts/
cp build/crypto/create-state artifacts/
cp build/crypto/tlbc artifacts/
cp build/validator-engine-console/validator-engine-console artifacts/
cp build/tonlib/tonlib-cli artifacts/
cp build/tonlib/libtonlibjson.0.5.dylib artifacts/libtonlibjson.dylib
cp build/http/http-proxy artifacts/
cp build/rldp-http-proxy/rldp-http-proxy artifacts/
cp build/dht-server/dht-server artifacts/
cp build/lite-client/lite-client artifacts/
cp build/validator-engine/validator-engine artifacts/
cp build/utils/generate-random-id artifacts/
cp build/utils/json2tlo artifacts/
cp build/adnl/adnl-proxy artifacts/
cp build/emulator/libemulator.dylib artifacts/
chmod +x artifacts/*
rsync -r crypto/smartcont artifacts/
rsync -r crypto/fift/lib artifacts/
fi
if [ "$with_tests" = true ]; then
cd build
# ctest --output-on-failure -E "test-catchain|test-actors"
ctest --output-on-failure --timeout 1800
fi

View file

@ -0,0 +1,216 @@
#/bin/bash
#sudo apt-get update
#sudo apt-get install -y build-essential git cmake ninja-build automake libtool texinfo autoconf
with_tests=false
with_artifacts=false
while getopts 'ta' flag; do
case "${flag}" in
t) with_tests=true ;;
a) with_artifacts=true ;;
*) break
;;
esac
done
if [ ! -d "build" ]; then
mkdir build
cd build
else
cd build
rm -rf .ninja* CMakeCache.txt
fi
export CC=$(which clang-16)
export CXX=$(which clang++-16)
export CCACHE_DISABLE=1
if [ ! -d "lz4" ]; then
git clone https://github.com/lz4/lz4.git
cd lz4
lz4Path=`pwd`
git checkout v1.9.4
make -j12
test $? -eq 0 || { echo "Can't compile lz4"; exit 1; }
cd ..
# ./lib/liblz4.a
# ./lib
else
lz4Path=$(pwd)/lz4
echo "Using compiled lz4"
fi
if [ ! -d "secp256k1" ]; then
git clone https://github.com/bitcoin-core/secp256k1.git
cd secp256k1
secp256k1Path=`pwd`
git checkout v0.3.2
./autogen.sh
./configure --enable-module-recovery --enable-static --disable-tests --disable-benchmark --with-pic
make -j12
test $? -eq 0 || { echo "Can't compile secp256k1"; exit 1; }
cd ..
# ./.libs/libsecp256k1.a
# ./include
else
secp256k1Path=$(pwd)/secp256k1
echo "Using compiled secp256k1"
fi
if [ ! -d "libsodium" ]; then
export LIBSODIUM_FULL_BUILD=1
git clone https://github.com/jedisct1/libsodium.git
cd libsodium
sodiumPath=`pwd`
git checkout 1.0.18
./autogen.sh
./configure --with-pic --enable-static
make -j12
test $? -eq 0 || { echo "Can't compile libsodium"; exit 1; }
cd ..
else
sodiumPath=$(pwd)/libsodium
echo "Using compiled libsodium"
fi
if [ ! -d "openssl_3" ]; then
git clone https://github.com/openssl/openssl openssl_3
cd openssl_3
opensslPath=`pwd`
git checkout openssl-3.1.4
./config -static
make build_libs -j12
test $? -eq 0 || { echo "Can't compile openssl_3"; exit 1; }
cd ..
else
opensslPath=$(pwd)/openssl_3
echo "Using compiled openssl_3"
fi
if [ ! -d "zlib" ]; then
git clone https://github.com/madler/zlib.git
cd zlib
zlibPath=`pwd`
./configure --static
make -j12
test $? -eq 0 || { echo "Can't compile zlib"; exit 1; }
cd ..
else
zlibPath=$(pwd)/zlib
echo "Using compiled zlib"
fi
if [ ! -d "libmicrohttpd" ]; then
git clone https://git.gnunet.org/libmicrohttpd.git
cd libmicrohttpd
libmicrohttpdPath=`pwd`
./autogen.sh
./configure --enable-static --disable-tests --disable-benchmark --disable-shared --disable-https --with-pic
make -j12
test $? -eq 0 || { echo "Can't compile libmicrohttpd"; exit 1; }
cd ..
else
libmicrohttpdPath=$(pwd)/libmicrohttpd
echo "Using compiled libmicrohttpd"
fi
cmake -GNinja .. \
-DPORTABLE=1 \
-DCMAKE_BUILD_TYPE=Release \
-DOPENSSL_FOUND=1 \
-DOPENSSL_INCLUDE_DIR=$opensslPath/include \
-DOPENSSL_CRYPTO_LIBRARY=$opensslPath/libcrypto.a \
-DZLIB_FOUND=1 \
-DZLIB_INCLUDE_DIR=$zlibPath \
-DZLIB_LIBRARIES=$zlibPath/libz.a \
-DSECP256K1_FOUND=1 \
-DSECP256K1_INCLUDE_DIR=$secp256k1Path/include \
-DSECP256K1_LIBRARY=$secp256k1Path/.libs/libsecp256k1.a \
-DSODIUM_FOUND=1 \
-DSODIUM_INCLUDE_DIR=$sodiumPath/src/libsodium/include \
-DSODIUM_LIBRARY_RELEASE=$sodiumPath/src/libsodium/.libs/libsodium.a \
-DMHD_FOUND=1 \
-DMHD_INCLUDE_DIR=$libmicrohttpdPath/src/include \
-DMHD_LIBRARY=$libmicrohttpdPath/src/microhttpd/.libs/libmicrohttpd.a \
-DLZ4_FOUND=1 \
-DLZ4_INCLUDE_DIRS=$lz4Path/lib \
-DLZ4_LIBRARIES=$lz4Path/lib/liblz4.a
test $? -eq 0 || { echo "Can't configure ton"; exit 1; }
if [ "$with_tests" = true ]; then
ninja storage-daemon storage-daemon-cli fift func tonlib tonlibjson tonlib-cli \
validator-engine lite-client pow-miner validator-engine-console blockchain-explorer \
generate-random-id json2tlo dht-server http-proxy rldp-http-proxy \
adnl-proxy create-state emulator test-ed25519 test-ed25519-crypto test-bigint \
test-vm test-fift test-cells test-smartcont test-net test-tdactor test-tdutils \
test-tonlib-offline test-adnl test-dht test-rldp test-rldp2 test-catchain \
test-fec test-tddb test-db test-validator-session-state
test $? -eq 0 || { echo "Can't compile ton"; exit 1; }
else
ninja storage-daemon storage-daemon-cli fift func tonlib tonlibjson tonlib-cli \
validator-engine lite-client pow-miner validator-engine-console blockchain-explorer \
generate-random-id json2tlo dht-server http-proxy rldp-http-proxy \
adnl-proxy create-state emulator
test $? -eq 0 || { echo "Can't compile ton"; exit 1; }
fi
strip -g storage/storage-daemon/storage-daemon \
storage/storage-daemon/storage-daemon-cli \
blockchain-explorer/blockchain-explorer \
crypto/fift \
crypto/tlbc \
crypto/func \
crypto/create-state \
validator-engine-console/validator-engine-console \
tonlib/tonlib-cli \
tonlib/libtonlibjson.so.0.5 \
http/http-proxy \
rldp-http-proxy/rldp-http-proxy \
dht-server/dht-server \
lite-client/lite-client \
validator-engine/validator-engine \
utils/generate-random-id \
utils/json2tlo \
adnl/adnl-proxy \
emulator/libemulator.*
test $? -eq 0 || { echo "Can't strip final binaries"; exit 1; }
# simple binaries' test
./storage/storage-daemon/storage-daemon -V || exit 1
./validator-engine/validator-engine -V || exit 1
./lite-client/lite-client -V || exit 1
./crypto/fift -V || exit 1
cd ..
if [ "$with_artifacts" = true ]; then
rm -rf artifacts
mkdir artifacts
cp crypto/fift/lib artifacts/
cp -R crypto/smartcont/ artifacts/
mv build/tonlib/libtonlibjson.so.0.5 build/tonlib/libtonlibjson.so
cp build/storage/storage-daemon/storage-daemon build/storage/storage-daemon/storage-daemon-cli \
build/crypto/fift build/crypto/tlbc build/crypto/func build/crypto/create-state build/blockchain-explorer/blockchain-explorer \
build/validator-engine-console/validator-engine-console build/tonlib/tonlib-cli \
build/tonlib/libtonlibjson.so build/http/http-proxy build/rldp-http-proxy/rldp-http-proxy \
build/dht-server/dht-server build/lite-client/lite-client build/validator-engine/validator-engine \
build/utils/generate-random-id build/utils/json2tlo build/adnl/adnl-proxy build/emulator/libemulator.so \
artifacts
test $? -eq 0 || { echo "Can't copy final binaries"; exit 1; }
chmod +x artifacts/*
cp -R crypto/smartcont artifacts
cp -R crypto/fift/lib artifacts
fi
if [ "$with_tests" = true ]; then
cd build
# ctest --output-on-failure -E "test-catchain|test-actors|test-smartcont|test-adnl|test-validator-session-state|test-dht|test-rldp"
ctest --output-on-failure -E "test-adnl"
fi

View file

@ -0,0 +1,122 @@
#/bin/bash
#sudo apt-get update
#sudo apt-get install -y build-essential git cmake ninja-build zlib1g-dev libsecp256k1-dev libmicrohttpd-dev libsodium-dev liblz4-dev
with_tests=false
with_artifacts=false
while getopts 'ta' flag; do
case "${flag}" in
t) with_tests=true ;;
a) with_artifacts=true ;;
*) break
;;
esac
done
if [ ! -d "build" ]; then
mkdir build
cd build
else
cd build
rm -rf .ninja* CMakeCache.txt
fi
export CC=$(which clang-16)
export CXX=$(which clang++-16)
export CCACHE_DISABLE=1
if [ ! -d "openssl_3" ]; then
git clone https://github.com/openssl/openssl openssl_3
cd openssl_3
opensslPath=`pwd`
git checkout openssl-3.1.4
./config
make build_libs -j12
test $? -eq 0 || { echo "Can't compile openssl_3"; exit 1; }
cd ..
else
opensslPath=$(pwd)/openssl_3
echo "Using compiled openssl_3"
fi
cmake -GNinja .. \
-DCMAKE_BUILD_TYPE=Release \
-DOPENSSL_ROOT_DIR=$opensslPath \
-DOPENSSL_INCLUDE_DIR=$opensslPath/include \
-DOPENSSL_CRYPTO_LIBRARY=$opensslPath/libcrypto.so
test $? -eq 0 || { echo "Can't configure ton"; exit 1; }
if [ "$with_tests" = true ]; then
ninja storage-daemon storage-daemon-cli fift func tonlib tonlibjson tonlib-cli \
validator-engine lite-client pow-miner validator-engine-console blockchain-explorer \
generate-random-id json2tlo dht-server http-proxy rldp-http-proxy \
adnl-proxy create-state emulator test-ed25519 test-ed25519-crypto test-bigint \
test-vm test-fift test-cells test-smartcont test-net test-tdactor test-tdutils \
test-tonlib-offline test-adnl test-dht test-rldp test-rldp2 test-catchain \
test-fec test-tddb test-db test-validator-session-state
test $? -eq 0 || { echo "Can't compile ton"; exit 1; }
else
ninja storage-daemon storage-daemon-cli fift func tonlib tonlibjson tonlib-cli \
validator-engine lite-client pow-miner validator-engine-console blockchain-explorer \
generate-random-id json2tlo dht-server http-proxy rldp-http-proxy \
adnl-proxy create-state emulator
test $? -eq 0 || { echo "Can't compile ton"; exit 1; }
fi
strip -g storage/storage-daemon/storage-daemon \
storage/storage-daemon/storage-daemon-cli \
blockchain-explorer/blockchain-explorer \
crypto/fift \
crypto/tlbc \
crypto/func \
crypto/create-state \
validator-engine-console/validator-engine-console \
tonlib/tonlib-cli \
tonlib/libtonlibjson.so.0.5 \
http/http-proxy \
rldp-http-proxy/rldp-http-proxy \
dht-server/dht-server \
lite-client/lite-client \
validator-engine/validator-engine \
utils/generate-random-id \
utils/json2tlo \
adnl/adnl-proxy \
emulator/libemulator.*
test $? -eq 0 || { echo "Can't strip final binaries"; exit 1; }
# simple binaries' test
./storage/storage-daemon/storage-daemon -V || exit 1
./validator-engine/validator-engine -V || exit 1
./lite-client/lite-client -V || exit 1
./crypto/fift -V || exit 1
cd ..
if [ "$with_artifacts" = true ]; then
rm -rf artifacts
mkdir artifacts
mv build/tonlib/libtonlibjson.so.0.5 build/tonlib/libtonlibjson.so
cp build/storage/storage-daemon/storage-daemon build/storage/storage-daemon/storage-daemon-cli \
build/crypto/fift build/crypto/tlbc build/crypto/func build/crypto/create-state build/blockchain-explorer/blockchain-explorer \
build/validator-engine-console/validator-engine-console build/tonlib/tonlib-cli \
build/tonlib/libtonlibjson.so build/http/http-proxy build/rldp-http-proxy/rldp-http-proxy \
build/dht-server/dht-server build/lite-client/lite-client build/validator-engine/validator-engine \
build/utils/generate-random-id build/utils/json2tlo build/adnl/adnl-proxy build/emulator/libemulator.so \
artifacts
test $? -eq 0 || { echo "Can't copy final binaries"; exit 1; }
chmod +x artifacts/*
cp -R crypto/smartcont artifacts
cp -R crypto/fift/lib artifacts
fi
if [ "$with_tests" = true ]; then
cd build
# ctest --output-on-failure -E "test-catchain|test-actors|test-smartcont|test-adnl|test-validator-session-state|test-dht|test-rldp"
ctest --output-on-failure --timeout 1800
fi

View file

@ -0,0 +1,2 @@
call "C:\Program Files\Microsoft Visual Studio\2022\%1\VC\Auxiliary\Build\vcvars64.bat"
call build-windows.bat -t

View file

@ -0,0 +1,222 @@
REM execute this script inside elevated (Run as Administrator) console "x64 Native Tools Command Prompt for VS 2022"
echo off
echo Installing chocolatey windows package manager...
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
choco -?
IF %errorlevel% NEQ 0 (
echo Can't install chocolatey
exit /b %errorlevel%
)
choco feature enable -n allowEmptyChecksums
echo Installing pkgconfiglite...
choco install -y pkgconfiglite
IF %errorlevel% NEQ 0 (
echo Can't install pkgconfiglite
exit /b %errorlevel%
)
echo Installing ninja...
choco install -y ninja
IF %errorlevel% NEQ 0 (
echo Can't install ninja
exit /b %errorlevel%
)
if not exist "zlib" (
git clone https://github.com/madler/zlib.git
cd zlib
git checkout v1.3.1
cd contrib\vstudio\vc14
msbuild zlibstat.vcxproj /p:Configuration=ReleaseWithoutAsm /p:platform=x64 -p:PlatformToolset=v143
IF %errorlevel% NEQ 0 (
echo Can't install zlib
exit /b %errorlevel%
)
cd ..\..\..\..
) else (
echo Using zlib...
)
if not exist "lz4" (
git clone https://github.com/lz4/lz4.git
cd lz4
git checkout v1.9.4
cd build\VS2017\liblz4
msbuild liblz4.vcxproj /p:Configuration=Release /p:platform=x64 -p:PlatformToolset=v143
dir /s
IF %errorlevel% NEQ 0 (
echo Can't install lz4
exit /b %errorlevel%
)
cd ..\..\..\..
) else (
echo Using lz4...
)
if not exist "secp256k1" (
git clone https://github.com/bitcoin-core/secp256k1.git
cd secp256k1
git checkout v0.3.2
cmake -G "Visual Studio 17 2022" -A x64 -S . -B build -DSECP256K1_ENABLE_MODULE_RECOVERY=ON -DBUILD_SHARED_LIBS=OFF
IF %errorlevel% NEQ 0 (
echo Can't configure secp256k1
exit /b %errorlevel%
)
cmake --build build --config Release
IF %errorlevel% NEQ 0 (
echo Can't install secp256k1
exit /b %errorlevel%
)
cd ..
) else (
echo Using secp256k1...
)
if not exist "libsodium" (
curl -Lo libsodium-1.0.18-stable-msvc.zip https://download.libsodium.org/libsodium/releases/libsodium-1.0.18-stable-msvc.zip
IF %errorlevel% NEQ 0 (
echo Can't download libsodium
exit /b %errorlevel%
)
unzip libsodium-1.0.18-stable-msvc.zip
) else (
echo Using libsodium...
)
if not exist "openssl-3.1.4" (
curl -Lo openssl-3.1.4.zip https://github.com/neodiX42/precompiled-openssl-win64/raw/main/openssl-3.1.4.zip
IF %errorlevel% NEQ 0 (
echo Can't download OpenSSL
exit /b %errorlevel%
)
unzip -q openssl-3.1.4.zip
) else (
echo Using openssl...
)
if not exist "libmicrohttpd-0.9.77-w32-bin" (
curl -Lo libmicrohttpd-0.9.77-w32-bin.zip https://github.com/neodiX42/precompiled-openssl-win64/raw/main/libmicrohttpd-0.9.77-w32-bin.zip
IF %errorlevel% NEQ 0 (
echo Can't download libmicrohttpd
exit /b %errorlevel%
)
unzip -q libmicrohttpd-0.9.77-w32-bin.zip
) else (
echo Using libmicrohttpd...
)
if not exist "readline-5.0-1-lib" (
curl -Lo readline-5.0-1-lib.zip https://github.com/neodiX42/precompiled-openssl-win64/raw/main/readline-5.0-1-lib.zip
IF %errorlevel% NEQ 0 (
echo Can't download readline
exit /b %errorlevel%
)
unzip -q -d readline-5.0-1-lib readline-5.0-1-lib.zip
) else (
echo Using readline...
)
set root=%cd%
echo %root%
set SODIUM_DIR=%root%\libsodium
mkdir build
cd build
cmake -GNinja -DCMAKE_BUILD_TYPE=Release ^
-DPORTABLE=1 ^
-DSODIUM_USE_STATIC_LIBS=1 ^
-DSECP256K1_FOUND=1 ^
-DSECP256K1_INCLUDE_DIR=%root%\secp256k1\include ^
-DSECP256K1_LIBRARY=%root%\secp256k1\build\src\Release\libsecp256k1.lib ^
-DLZ4_FOUND=1 ^
-DLZ4_INCLUDE_DIRS=%root%\lz4\lib ^
-DLZ4_LIBRARIES=%root%\lz4\build\VS2017\liblz4\bin\x64_Release\liblz4_static.lib ^
-DMHD_FOUND=1 ^
-DMHD_LIBRARY=%root%\libmicrohttpd-0.9.77-w32-bin\x86_64\VS2019\Release-static\libmicrohttpd.lib ^
-DMHD_INCLUDE_DIR=%root%\libmicrohttpd-0.9.77-w32-bin\x86_64\VS2019\Release-static ^
-DZLIB_FOUND=1 ^
-DZLIB_INCLUDE_DIR=%root%\zlib ^
-DZLIB_LIBRARIES=%root%\zlib\contrib\vstudio\vc14\x64\ZlibStatReleaseWithoutAsm\zlibstat.lib ^
-DOPENSSL_FOUND=1 ^
-DOPENSSL_INCLUDE_DIR=%root%\openssl-3.1.4\x64\include ^
-DOPENSSL_CRYPTO_LIBRARY=%root%\openssl-3.1.4\x64\lib\libcrypto_static.lib ^
-DREADLINE_INCLUDE_DIR=%root%\readline-5.0-1-lib\include ^
-DREADLINE_LIBRARY=%root%\readline-5.0-1-lib\lib\readline.lib ^
-DCMAKE_CXX_FLAGS="/DTD_WINDOWS=1 /EHsc /bigobj" ..
IF %errorlevel% NEQ 0 (
echo Can't configure TON
exit /b %errorlevel%
)
IF "%1"=="-t" (
ninja storage-daemon storage-daemon-cli blockchain-explorer fift func tonlib tonlibjson ^
tonlib-cli validator-engine lite-client pow-miner validator-engine-console generate-random-id ^
json2tlo dht-server http-proxy rldp-http-proxy adnl-proxy create-state create-hardfork emulator ^
test-ed25519 test-ed25519-crypto test-bigint test-vm test-fift test-cells test-smartcont test-net ^
test-tdactor test-tdutils test-tonlib-offline test-adnl test-dht test-rldp test-rldp2 test-catchain ^
test-fec test-tddb test-db test-validator-session-state
IF %errorlevel% NEQ 0 (
echo Can't compile TON
exit /b %errorlevel%
)
) else (
ninja storage-daemon storage-daemon-cli blockchain-explorer fift func tonlib tonlibjson ^
tonlib-cli validator-engine lite-client pow-miner validator-engine-console generate-random-id ^
json2tlo dht-server http-proxy rldp-http-proxy adnl-proxy create-state create-hardfork emulator
IF %errorlevel% NEQ 0 (
echo Can't compile TON
exit /b %errorlevel%
)
)
copy validator-engine\validator-engine.exe test
IF %errorlevel% NEQ 0 (
echo validator-engine.exe does not exist
exit /b %errorlevel%
)
IF "%1"=="-t" (
echo Running tests...
REM ctest -C Release --output-on-failure -E "test-catchain|test-actors|test-validator-session-state"
ctest -C Release --output-on-failure -E "test-bigint" --timeout 1800
IF %errorlevel% NEQ 0 (
echo Some tests failed
exit /b %errorlevel%
)
)
echo Creating artifacts...
cd ..
mkdir artifacts
mkdir artifacts\smartcont
mkdir artifacts\lib
for %%I in (build\storage\storage-daemon\storage-daemon.exe ^
build\storage\storage-daemon\storage-daemon-cli.exe ^
build\blockchain-explorer\blockchain-explorer.exe ^
build\crypto\fift.exe ^
build\crypto\tlbc.exe ^
build\crypto\func.exe ^
build\crypto\create-state.exe ^
build\validator-engine-console\validator-engine-console.exe ^
build\tonlib\tonlib-cli.exe ^
build\tonlib\tonlibjson.dll ^
build\http\http-proxy.exe ^
build\rldp-http-proxy\rldp-http-proxy.exe ^
build\dht-server\dht-server.exe ^
build\lite-client\lite-client.exe ^
build\validator-engine\validator-engine.exe ^
build\utils\generate-random-id.exe ^
build\utils\json2tlo.exe ^
build\adnl\adnl-proxy.exe ^
build\emulator\emulator.dll) do (strip -g %%I & copy %%I artifacts\)
xcopy /e /k /h /i crypto\smartcont artifacts\smartcont
xcopy /e /k /h /i crypto\fift\lib artifacts\lib

View file

@ -0,0 +1,37 @@
#/bin/bash
nix-build --version
test $? -eq 0 || { echo "Nix is not installed!"; exit 1; }
with_tests=false
while getopts 't' flag; do
case "${flag}" in
t) with_tests=true ;;
*) break
;;
esac
done
cp assembly/nix/linux-arm64* .
cp assembly/nix/microhttpd.nix .
cp assembly/nix/openssl.nix .
export NIX_PATH=nixpkgs=https://github.com/nixOS/nixpkgs/archive/23.05.tar.gz
if [ "$with_tests" = true ]; then
nix-build linux-arm64-static.nix --arg testing true
else
nix-build linux-arm64-static.nix
fi
mkdir -p artifacts/lib
cp ./result/bin/* artifacts/
test $? -eq 0 || { echo "No artifacts have been built..."; exit 1; }
chmod +x artifacts/*
rm -rf result
nix-build linux-arm64-tonlib.nix
cp ./result/lib/libtonlibjson.so.0.5 artifacts/libtonlibjson.so
cp ./result/lib/libemulator.so artifacts/
cp ./result/lib/fift/* artifacts/lib/
cp -r ./result/share/ton/smartcont artifacts/

View file

@ -0,0 +1,37 @@
#/bin/bash
nix-build --version
test $? -eq 0 || { echo "Nix is not installed!"; exit 1; }
with_tests=false
while getopts 't' flag; do
case "${flag}" in
t) with_tests=true ;;
*) break
;;
esac
done
cp assembly/nix/linux-x86-64* .
cp assembly/nix/microhttpd.nix .
cp assembly/nix/openssl.nix .
export NIX_PATH=nixpkgs=https://github.com/nixOS/nixpkgs/archive/23.05.tar.gz
if [ "$with_tests" = true ]; then
nix-build linux-x86-64-static.nix --arg testing true
else
nix-build linux-x86-64-static.nix
fi
mkdir -p artifacts/lib
cp ./result/bin/* artifacts/
test $? -eq 0 || { echo "No artifacts have been built..."; exit 1; }
chmod +x artifacts/*
rm -rf result
nix-build linux-x86-64-tonlib.nix
cp ./result/lib/libtonlibjson.so.0.5 artifacts/libtonlibjson.so
cp ./result/lib/libemulator.so artifacts/
cp ./result/lib/fift/* artifacts/lib/
cp -r ./result/share/ton/smartcont artifacts/

View file

@ -0,0 +1,35 @@
#/bin/bash
nix-build --version
test $? -eq 0 || { echo "Nix is not installed!"; exit 1; }
with_tests=false
while getopts 't' flag; do
case "${flag}" in
t) with_tests=true ;;
*) break
;;
esac
done
cp assembly/nix/macos-* .
export NIX_PATH=nixpkgs=https://github.com/nixOS/nixpkgs/archive/23.05.tar.gz
if [ "$with_tests" = true ]; then
nix-build macos-static.nix --arg testing true
else
nix-build macos-static.nix
fi
mkdir -p artifacts/lib
cp ./result-bin/bin/* artifacts/
test $? -eq 0 || { echo "No artifacts have been built..."; exit 1; }
chmod +x artifacts/*
rm -rf result-bin
nix-build macos-tonlib.nix
cp ./result/lib/libtonlibjson.dylib artifacts/
cp ./result/lib/libemulator.dylib artifacts/
cp ./result/lib/fift/* artifacts/lib/
cp -r ./result/share/ton/smartcont artifacts/

94
assembly/nix/flakes/flake.lock generated Normal file
View file

@ -0,0 +1,94 @@
{
"nodes": {
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1673956053,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1681202837,
"narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1698846319,
"narHash": "sha256-4jyW/dqFBVpWFnhl0nvP6EN4lP7/ZqPxYRjl6var0Oc=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "50fc86b75d2744e1ab3837ef74b53f103a9b55a0",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-23.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-trunk": {
"locked": {
"lastModified": 1683098912,
"narHash": "sha256-bFHOixPoHZ5y44FvFgpEuZV0UYTQPNDZK/XqeUi1Lbs=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "abc97d3572dec126eba9fec358eb2f359a944683",
"type": "github"
},
"original": {
"owner": "nixos",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-compat": "flake-compat",
"flake-utils": "flake-utils",
"nixpkgs-stable": "nixpkgs-stable",
"nixpkgs-trunk": "nixpkgs-trunk"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

View file

@ -0,0 +1,158 @@
{
inputs = {
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-23.05";
nixpkgs-trunk.url = "github:nixos/nixpkgs";
flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
};
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs-stable, nixpkgs-trunk, flake-compat, flake-utils }:
let
ton = { host, pkgs ? host, stdenv ? pkgs.stdenv, staticGlibc ? false
, staticMusl ? false, staticExternalDeps ? staticGlibc }:
with host.lib;
stdenv.mkDerivation {
pname = "ton";
version = "dev";
src = ./.;
nativeBuildInputs = with host;
[ cmake ninja pkg-config git ] ++
optionals stdenv.isLinux [ dpkg rpm createrepo_c pacman ];
buildInputs = with pkgs;
# at some point nixpkgs' pkgsStatic will build with static glibc
# then we can skip these manual overrides
# and switch between pkgsStatic and pkgsStatic.pkgsMusl for static glibc and musl builds
if !staticExternalDeps then [
openssl
zlib
libmicrohttpd
libsodium
secp256k1
] else
[
(openssl.override { static = true; }).dev
(zlib.override { shared = false; }).dev
]
++ optionals (!stdenv.isDarwin) [ pkgsStatic.libmicrohttpd.dev pkgsStatic.libsodium.dev secp256k1 ]
++ optionals stdenv.isDarwin [ (libiconv.override { enableStatic = true; enableShared = false; }) ]
++ optionals stdenv.isDarwin (forEach [ libmicrohttpd.dev libsodium.dev secp256k1 gmp.dev nettle.dev (gnutls.override { withP11-kit = false; }).dev libtasn1.dev libidn2.dev libunistring.dev gettext ] (x: x.overrideAttrs(oldAttrs: rec { configureFlags = (oldAttrs.configureFlags or []) ++ [ "--enable-static" "--disable-shared" ]; dontDisableStatic = true; })))
++ optionals staticGlibc [ glibc.static ];
dontAddStaticConfigureFlags = stdenv.isDarwin;
cmakeFlags = [ "-DTON_USE_ABSEIL=OFF" "-DNIX=ON" ] ++ optionals staticMusl [
"-DCMAKE_CROSSCOMPILING=OFF" # pkgsStatic sets cross
] ++ optionals (staticGlibc || staticMusl) [
"-DCMAKE_LINK_SEARCH_START_STATIC=ON"
"-DCMAKE_LINK_SEARCH_END_STATIC=ON"
] ++ optionals (stdenv.isDarwin) [
"-DCMAKE_CXX_FLAGS=-stdlib=libc++" "-DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=11.7"
];
LDFLAGS = optional staticExternalDeps (concatStringsSep " " [
(optionalString stdenv.cc.isGNU "-static-libgcc")
(optionalString stdenv.isDarwin "-framework CoreFoundation")
"-static-libstdc++"
]);
GIT_REVISION = if self ? rev then self.rev else "dirty";
GIT_REVISION_DATE = (builtins.concatStringsSep "-" (builtins.match "(.{4})(.{2})(.{2}).*" self.lastModifiedDate)) + " " + (builtins.concatStringsSep ":" (builtins.match "^........(.{2})(.{2})(.{2}).*" self.lastModifiedDate));
postInstall = ''
moveToOutput bin "$bin"
'';
preFixup = optionalString stdenv.isDarwin ''
for fn in "$bin"/bin/* "$out"/lib/*.dylib; do
echo Fixing libc++ in "$fn"
install_name_tool -change "$(otool -L "$fn" | grep libc++.1 | cut -d' ' -f1 | xargs)" libc++.1.dylib "$fn"
install_name_tool -change "$(otool -L "$fn" | grep libc++abi.1 | cut -d' ' -f1 | xargs)" libc++abi.dylib "$fn"
done
'';
outputs = [ "bin" "out" ];
};
hostPkgs = system:
import nixpkgs-stable {
inherit system;
overlays = [
(self: super: {
zchunk = nixpkgs-trunk.legacyPackages.${system}.zchunk;
})
];
};
in with flake-utils.lib;
(nixpkgs-stable.lib.recursiveUpdate
(eachSystem (with system; [ x86_64-linux aarch64-linux ]) (system:
let
host = hostPkgs system;
# look out for https://github.com/NixOS/nixpkgs/issues/129595 for progress on better infra for this
#
# nixos 19.09 ships with glibc 2.27
# we could also just override glibc source to a particular release
# but then we'd need to port patches as well
nixos1909 = (import (builtins.fetchTarball {
url = "https://channels.nixos.org/nixos-19.09/nixexprs.tar.xz";
sha256 = "1vp1h2gkkrckp8dzkqnpcc6xx5lph5d2z46sg2cwzccpr8ay58zy";
}) { inherit system; });
glibc227 = nixos1909.glibc // { pname = "glibc"; };
stdenv227 = let
cc = host.wrapCCWith {
cc = nixos1909.buildPackages.gcc-unwrapped;
libc = glibc227;
bintools = host.binutils.override { libc = glibc227; };
};
in (host.overrideCC host.stdenv cc);
in rec {
packages = rec {
ton-normal = ton { inherit host; };
ton-static = ton {
inherit host;
stdenv = host.makeStatic host.stdenv;
staticGlibc = true;
};
ton-musl =
let pkgs = nixpkgs-stable.legacyPackages.${system}.pkgsStatic;
in ton {
inherit host;
inherit pkgs;
stdenv =
pkgs.gcc12Stdenv; # doesn't build on aarch64-linux w/default GCC 9
staticMusl = true;
};
ton-oldglibc = (ton {
inherit host;
stdenv = stdenv227;
staticExternalDeps = true;
});
ton-oldglibc_staticbinaries = host.symlinkJoin {
name = "ton";
paths = [ ton-musl.bin ton-oldglibc.out ];
};
};
devShells.default =
host.mkShell { inputsFrom = [ packages.ton-normal ]; };
})) (eachSystem (with system; [ x86_64-darwin aarch64-darwin ]) (system:
let host = hostPkgs system;
in rec {
packages = rec {
ton-normal = ton { inherit host; };
ton-static = ton {
inherit host;
stdenv = host.makeStatic host.stdenv;
staticExternalDeps = true;
};
ton-staticbin-dylib = host.symlinkJoin {
name = "ton";
paths = [ ton-static.bin ton-static.out ];
};
};
devShells.default =
host.mkShell { inputsFrom = [ packages.ton-normal ]; };
})));
}

View file

@ -0,0 +1,10 @@
(import
(
let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in
fetchTarball {
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
sha256 = lock.nodes.flake-compat.locked.narHash;
}
)
{ src = ./.; }
).shellNix

View file

@ -0,0 +1,46 @@
# export NIX_PATH=nixpkgs=https://github.com/nixOS/nixpkgs/archive/23.05.tar.gz
{ pkgs ? import <nixpkgs> { system = builtins.currentSystem; }
, lib ? pkgs.lib
, stdenv ? pkgs.stdenv
, testing ? false
}:
let
microhttpdmy = (import ./microhttpd.nix) {};
in
with import microhttpdmy;
stdenv.mkDerivation {
pname = "ton";
version = "dev-bin";
src = ./.;
nativeBuildInputs = with pkgs;
[
cmake ninja git pkg-config
];
buildInputs = with pkgs;
[
pkgsStatic.openssl microhttpdmy pkgsStatic.zlib pkgsStatic.libsodium.dev pkgsStatic.secp256k1 glibc.static pkgsStatic.lz4
];
makeStatic = true;
doCheck = testing;
cmakeFlags = [
"-DTON_USE_ABSEIL=OFF"
"-DNIX=ON"
"-DBUILD_SHARED_LIBS=OFF"
"-DCMAKE_LINK_SEARCH_START_STATIC=ON"
"-DCMAKE_LINK_SEARCH_END_STATIC=ON"
"-DMHD_FOUND=1"
"-DMHD_INCLUDE_DIR=${microhttpdmy}/usr/local/include"
"-DMHD_LIBRARY=${microhttpdmy}/usr/local/lib/libmicrohttpd.a"
"-DCMAKE_CTEST_ARGUMENTS=--timeout;1800"
];
LDFLAGS = [
"-static-libgcc" "-static-libstdc++" "-static"
];
}

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