mirror of
https://github.com/ton-blockchain/ton
synced 2025-02-14 20:22:19 +00:00
Merge pull request #1427 from ton-blockchain/testnet
Merge developer branch
This commit is contained in:
commit
ea0dc16163
199 changed files with 7261 additions and 2157 deletions
|
@ -21,6 +21,8 @@ jobs:
|
|||
|
||||
- name: Build TON
|
||||
run: |
|
||||
git submodule sync --recursive
|
||||
git submodule update
|
||||
cp assembly/android/build-android-tonlib.sh .
|
||||
chmod +x build-android-tonlib.sh
|
||||
./build-android-tonlib.sh -a
|
||||
|
|
|
@ -35,6 +35,8 @@ jobs:
|
|||
|
||||
- name: Build TON
|
||||
run: |
|
||||
git submodule sync --recursive
|
||||
git submodule update
|
||||
cp assembly/native/build-ubuntu-shared.sh .
|
||||
chmod +x build-ubuntu-shared.sh
|
||||
./build-ubuntu-shared.sh -t -a
|
||||
|
|
|
@ -14,6 +14,8 @@ jobs:
|
|||
|
||||
- name: Build TON
|
||||
run: |
|
||||
git submodule sync --recursive
|
||||
git submodule update
|
||||
cp assembly/native/build-macos-shared.sh .
|
||||
chmod +x build-macos-shared.sh
|
||||
./build-macos-shared.sh -t -a
|
||||
|
|
|
@ -14,6 +14,8 @@ jobs:
|
|||
|
||||
- name: Build TON
|
||||
run: |
|
||||
git submodule sync --recursive
|
||||
git submodule update
|
||||
cp assembly/native/build-macos-shared.sh .
|
||||
chmod +x build-macos-shared.sh
|
||||
./build-macos-shared.sh -t -a
|
||||
|
|
|
@ -4,7 +4,7 @@ on: [push,workflow_dispatch,workflow_call]
|
|||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: macos-12
|
||||
runs-on: macos-13
|
||||
|
||||
steps:
|
||||
- name: Check out repository
|
||||
|
@ -14,6 +14,8 @@ jobs:
|
|||
|
||||
- name: Build TON
|
||||
run: |
|
||||
git submodule sync --recursive
|
||||
git submodule update
|
||||
cp assembly/native/build-macos-shared.sh .
|
||||
chmod +x build-macos-shared.sh
|
||||
./build-macos-shared.sh -t -a
|
||||
|
@ -21,5 +23,5 @@ jobs:
|
|||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: ton-binaries-macos-12
|
||||
name: ton-binaries-macos-13
|
||||
path: artifacts
|
||||
|
|
|
@ -15,10 +15,12 @@ jobs:
|
|||
- 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
|
||||
sudo apt-get install -y build-essential git openssl cmake ninja-build zlib1g-dev libssl-dev libsecp256k1-dev libmicrohttpd-dev libsodium-dev liblz4-dev libjemalloc-dev
|
||||
|
||||
- name: Build TON WASM artifacts
|
||||
run: |
|
||||
git submodule sync --recursive
|
||||
git submodule update
|
||||
cp assembly/wasm/fift-func-wasm-build-ubuntu.sh .
|
||||
chmod +x fift-func-wasm-build-ubuntu.sh
|
||||
./fift-func-wasm-build-ubuntu.sh -a
|
||||
|
|
52
.github/workflows/create-release.yml
vendored
52
.github/workflows/create-release.yml
vendored
|
@ -12,7 +12,7 @@ jobs:
|
|||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Download Linux x86-64 artifacts
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: ton-x86-64-linux.yml
|
||||
path: artifacts
|
||||
|
@ -20,7 +20,7 @@ jobs:
|
|||
skip_unpack: true
|
||||
|
||||
- name: Download and unzip Linux x86-64 artifacts
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: ton-x86-64-linux.yml
|
||||
path: artifacts
|
||||
|
@ -28,7 +28,7 @@ jobs:
|
|||
skip_unpack: false
|
||||
|
||||
- name: Download Mac x86-64 artifacts
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: ton-x86-64-macos.yml
|
||||
path: artifacts
|
||||
|
@ -36,7 +36,7 @@ jobs:
|
|||
skip_unpack: true
|
||||
|
||||
- name: Download Mac arm64 artifacts
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: ton-arm64-macos.yml
|
||||
path: artifacts
|
||||
|
@ -44,7 +44,7 @@ jobs:
|
|||
skip_unpack: true
|
||||
|
||||
- name: Download and unzip Mac x86-64 artifacts
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: ton-x86-64-macos.yml
|
||||
path: artifacts
|
||||
|
@ -52,7 +52,7 @@ jobs:
|
|||
skip_unpack: false
|
||||
|
||||
- name: Download and unzip arm64 artifacts
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: ton-arm64-macos.yml
|
||||
path: artifacts
|
||||
|
@ -60,7 +60,7 @@ jobs:
|
|||
skip_unpack: false
|
||||
|
||||
- name: Download Windows artifacts
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: ton-x86-64-windows.yml
|
||||
path: artifacts
|
||||
|
@ -68,7 +68,7 @@ jobs:
|
|||
skip_unpack: true
|
||||
|
||||
- name: Download and unzip Windows artifacts
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: ton-x86-64-windows.yml
|
||||
path: artifacts
|
||||
|
@ -76,7 +76,7 @@ jobs:
|
|||
skip_unpack: false
|
||||
|
||||
- name: Download WASM artifacts
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: build-ton-wasm-emscripten.yml
|
||||
path: artifacts
|
||||
|
@ -84,7 +84,7 @@ jobs:
|
|||
skip_unpack: true
|
||||
|
||||
- name: Download Android Tonlib artifacts
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: build-ton-linux-android-tonlib.yml
|
||||
path: artifacts
|
||||
|
@ -183,6 +183,14 @@ jobs:
|
|||
asset_name: lite-client.exe
|
||||
tag: ${{ steps.tag.outputs.TAG }}
|
||||
|
||||
- name: Upload Windows 2019 single artifact - proxy-liteserver
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: artifacts/ton-win-binaries/proxy-liteserver.exe
|
||||
asset_name: proxy-liteserver.exe
|
||||
tag: ${{ steps.tag.outputs.TAG }}
|
||||
|
||||
- name: Upload Windows 2019 single artifact - rldp-http-proxy
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
|
@ -281,6 +289,14 @@ jobs:
|
|||
asset_name: lite-client-mac-x86-64
|
||||
tag: ${{ steps.tag.outputs.TAG }}
|
||||
|
||||
- name: Upload Mac x86-64 single artifact - proxy-liteserver
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: artifacts/ton-x86_64-macos-binaries/proxy-liteserver
|
||||
asset_name: proxy-liteserver-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:
|
||||
|
@ -380,6 +396,14 @@ jobs:
|
|||
asset_name: lite-client-mac-arm64
|
||||
tag: ${{ steps.tag.outputs.TAG }}
|
||||
|
||||
- name: Upload Mac arm64 single artifact - proxy-liteserver
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: artifacts/ton-arm64-macos-binaries/proxy-liteserver
|
||||
asset_name: proxy-liteserver-mac-arm64
|
||||
tag: ${{ steps.tag.outputs.TAG }}
|
||||
|
||||
- name: Upload Mac arm64 single artifact - rldp-http-proxy
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
|
@ -478,6 +502,14 @@ jobs:
|
|||
asset_name: lite-client-linux-x86_64
|
||||
tag: ${{ steps.tag.outputs.TAG }}
|
||||
|
||||
- name: Upload Linux x86-64 single artifact - proxy-liteserver
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: artifacts/ton-x86_64-linux-binaries/proxy-liteserver
|
||||
asset_name: proxy-liteserver-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:
|
||||
|
|
|
@ -41,7 +41,7 @@ jobs:
|
|||
id: docker_build
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
platforms: linux/amd64
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
context: ./
|
||||
tags: |
|
||||
|
|
2
.github/workflows/ton-arm64-macos.yml
vendored
2
.github/workflows/ton-arm64-macos.yml
vendored
|
@ -18,6 +18,8 @@ jobs:
|
|||
|
||||
- name: Build TON
|
||||
run: |
|
||||
git submodule sync --recursive
|
||||
git submodule update
|
||||
cp assembly/nix/build-macos-nix.sh .
|
||||
chmod +x build-macos-nix.sh
|
||||
./build-macos-nix.sh -t
|
||||
|
|
2
.github/workflows/ton-x86-64-linux.yml
vendored
2
.github/workflows/ton-x86-64-linux.yml
vendored
|
@ -22,6 +22,8 @@ jobs:
|
|||
|
||||
- name: Build TON
|
||||
run: |
|
||||
git submodule sync --recursive
|
||||
git submodule update
|
||||
cp assembly/nix/build-linux-x86-64-nix.sh .
|
||||
chmod +x build-linux-x86-64-nix.sh
|
||||
./build-linux-x86-64-nix.sh -t
|
||||
|
|
4
.github/workflows/ton-x86-64-macos.yml
vendored
4
.github/workflows/ton-x86-64-macos.yml
vendored
|
@ -4,7 +4,7 @@ on: [push,workflow_dispatch,workflow_call]
|
|||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: macos-12
|
||||
runs-on: macos-13
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
@ -18,6 +18,8 @@ jobs:
|
|||
|
||||
- name: Build TON
|
||||
run: |
|
||||
git submodule sync --recursive
|
||||
git submodule update
|
||||
cp assembly/nix/build-macos-nix.sh .
|
||||
chmod +x build-macos-nix.sh
|
||||
./build-macos-nix.sh -t
|
||||
|
|
2
.github/workflows/ton-x86-64-windows.yml
vendored
2
.github/workflows/ton-x86-64-windows.yml
vendored
|
@ -23,6 +23,8 @@ jobs:
|
|||
|
||||
- name: Build TON
|
||||
run: |
|
||||
git submodule sync --recursive
|
||||
git submodule update
|
||||
copy assembly\native\build-windows-github-2019.bat .
|
||||
copy assembly\native\build-windows-2019.bat .
|
||||
build-windows-github-2019.bat Enterprise
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -19,7 +19,6 @@ 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
|
||||
|
|
4
.gitmodules
vendored
4
.gitmodules
vendored
|
@ -13,3 +13,7 @@
|
|||
[submodule "third-party/blst"]
|
||||
path = third-party/blst
|
||||
url = https://github.com/supranational/blst.git
|
||||
[submodule "third-party/secp256k1"]
|
||||
path = third-party/secp256k1
|
||||
url = https://github.com/bitcoin-core/secp256k1
|
||||
branch = v0.3.2
|
||||
|
|
55
CMake/BuildSECP256K1.cmake
Normal file
55
CMake/BuildSECP256K1.cmake
Normal file
|
@ -0,0 +1,55 @@
|
|||
if (NOT SECP256K1_LIBRARY)
|
||||
|
||||
set(SECP256K1_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third-party/secp256k1)
|
||||
set(SECP256K1_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/third-party/secp256k1)
|
||||
set(SECP256K1_INCLUDE_DIR ${SECP256K1_BINARY_DIR}/include)
|
||||
|
||||
file(MAKE_DIRECTORY ${SECP256K1_BINARY_DIR})
|
||||
file(MAKE_DIRECTORY "${SECP256K1_BINARY_DIR}/include")
|
||||
|
||||
if (MSVC)
|
||||
set(SECP256K1_BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third-party/secp256k1)
|
||||
set(SECP256K1_LIBRARY ${SECP256K1_SOURCE_DIR}/build/src/Release/libsecp256k1.lib)
|
||||
set(SECP256K1_INCLUDE_DIR ${SECP256K1_BINARY_DIR}/include)
|
||||
add_custom_command(
|
||||
WORKING_DIRECTORY ${SECP256K1_SOURCE_DIR}
|
||||
COMMAND cmake -E env CFLAGS="/WX" cmake -A x64 -B build -DSECP256K1_ENABLE_MODULE_RECOVERY=ON -DSECP256K1_ENABLE_MODULE_EXTRAKEYS=ON -DSECP256K1_BUILD_EXAMPLES=OFF -DBUILD_SHARED_LIBS=OFF
|
||||
COMMAND cmake --build build --config Release
|
||||
COMMENT "Build Secp256k1"
|
||||
DEPENDS ${SECP256K1_SOURCE_DIR}
|
||||
OUTPUT ${SECP256K1_LIBRARY}
|
||||
)
|
||||
elseif (EMSCRIPTEN)
|
||||
set(SECP256K1_BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third-party/secp256k1)
|
||||
set(SECP256K1_LIBRARY ${SECP256K1_BINARY_DIR}/.libs/libsecp256k1.a)
|
||||
set(SECP256K1_INCLUDE_DIR ${SECP256K1_SOURCE_DIR}/include)
|
||||
add_custom_command(
|
||||
WORKING_DIRECTORY ${SECP256K1_SOURCE_DIR}
|
||||
COMMAND ./autogen.sh
|
||||
COMMAND emconfigure ./configure --enable-module-recovery --enable-module-extrakeys --disable-tests --disable-benchmark
|
||||
COMMAND emmake make clean
|
||||
COMMAND emmake make
|
||||
COMMENT "Build Secp256k1 with emscripten"
|
||||
DEPENDS ${SECP256K1_SOURCE_DIR}
|
||||
OUTPUT ${SECP256K1_LIBRARY}
|
||||
)
|
||||
else()
|
||||
if (NOT NIX)
|
||||
set(SECP256K1_LIBRARY ${SECP256K1_BINARY_DIR}/lib/libsecp256k1.a)
|
||||
add_custom_command(
|
||||
WORKING_DIRECTORY ${SECP256K1_SOURCE_DIR}
|
||||
COMMAND ./autogen.sh
|
||||
COMMAND ./configure -q --disable-option-checking --enable-module-recovery --enable-module-extrakeys --prefix ${SECP256K1_BINARY_DIR} --with-pic --disable-shared --enable-static --disable-tests --disable-benchmark
|
||||
COMMAND make -j16
|
||||
COMMAND make install
|
||||
COMMENT "Build secp256k1"
|
||||
DEPENDS ${SECP256K1_SOURCE_DIR}
|
||||
OUTPUT ${SECP256K1_LIBRARY}
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Use Secp256k1: ${SECP256K1_LIBRARY}")
|
||||
endif()
|
||||
|
||||
add_custom_target(secp256k1 DEPENDS ${SECP256K1_LIBRARY})
|
|
@ -1,9 +1,8 @@
|
|||
# - Try to find SECP256K1
|
||||
# - 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
|
||||
# SECP256K1_INCLUDE_DIR - the Secp256k1 include directory
|
||||
# SECP256K1_LIBRARY - Link these to use Secp256k1
|
||||
|
||||
if (NOT SECP256K1_LIBRARY)
|
||||
find_path(
|
||||
|
|
|
@ -183,6 +183,7 @@ message("Add ton")
|
|||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH})
|
||||
|
||||
include(BuildBLST)
|
||||
include(BuildSECP256K1)
|
||||
|
||||
# Configure CCache if available
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
|
@ -237,6 +238,11 @@ if (TON_USE_JEMALLOC)
|
|||
find_package(jemalloc REQUIRED)
|
||||
endif()
|
||||
|
||||
if (NIX)
|
||||
find_package(Secp256k1 REQUIRED)
|
||||
endif()
|
||||
|
||||
|
||||
set(MEMPROF "" CACHE STRING "Use one of \"ON\", \"FAST\" or \"SAFE\" to enable memory profiling. \
|
||||
Works under macOS and Linux when compiled using glibc. \
|
||||
In FAST mode stack is unwinded only using frame pointers, which may fail. \
|
||||
|
|
14
Changelog.md
14
Changelog.md
|
@ -1,3 +1,17 @@
|
|||
## 2024.12 Update
|
||||
|
||||
1. FunC 0.4.6: Fix in try/catch handling, fixing pure flag for functions stored in variables
|
||||
2. Merging parts of Accelerator: support of specific shard monitoring, archive/liteserver slice format, support for partial liteservers, proxy liteserver, on-demand neighbour queue loading
|
||||
3. Fix of asynchronous cell loading
|
||||
4. Various improvements: caching certificates checks, better block overloading detection, `_malloc` in emulator
|
||||
5. Introduction of telemetry in overlays
|
||||
6. Use non-null local-id for tonlib-LS interaction - mitigates MitM attack.
|
||||
7. Adding `SECP256K1_XONLY_PUBKEY_TWEAK_ADD`, `SETCONTCTRMANY` instructions to TVM (activated by `Config8.version >= 9`)
|
||||
8. Private keys export via validator-engine-console - required for better backups
|
||||
9. Fix proof checking in tonlib, `hash` in `raw.Message` in tonlib_api
|
||||
|
||||
Besides the work of the core team, this update is based on the efforts of OtterSec and LayerZero (FunC), tg:@throwunless (FunC), Aviv Frenkel and Dima Kogan from Fordefi (LS MitM), @hacker-volodya (Tonlib), OKX team (async cell loading), @krigga (emulator)
|
||||
|
||||
## 2024.10 Update
|
||||
|
||||
1. Parallel write to celldb: substantial improvement of sync and GC speed, especially with slow disks.
|
||||
|
|
22
Dockerfile
22
Dockerfile
|
@ -1,6 +1,6 @@
|
|||
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 libjemalloc-dev lsb-release software-properties-common gnupg
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y build-essential cmake clang openssl libssl-dev zlib1g-dev gperf wget git ninja-build libsodium-dev libmicrohttpd-dev liblz4-dev pkg-config autoconf automake libtool libjemalloc-dev lsb-release software-properties-common gnupg
|
||||
|
||||
RUN wget https://apt.llvm.org/llvm.sh && \
|
||||
chmod +x llvm.sh && \
|
||||
|
@ -20,14 +20,17 @@ COPY ./ ./
|
|||
RUN mkdir build && \
|
||||
cd build && \
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DPORTABLE=1 -DTON_ARCH= -DTON_USE_JEMALLOC=ON .. && \
|
||||
ninja storage-daemon storage-daemon-cli tonlibjson fift func validator-engine validator-engine-console generate-random-id dht-server lite-client
|
||||
ninja storage-daemon storage-daemon-cli tonlibjson fift func validator-engine validator-engine-console \
|
||||
generate-random-id dht-server lite-client tolk rldp-http-proxy dht-server proxy-liteserver create-state \
|
||||
blockchain-explorer emulator tonlibjson http-proxy adnl-proxy
|
||||
|
||||
FROM ubuntu:22.04
|
||||
RUN apt-get update && \
|
||||
apt-get install -y wget curl libatomic1 openssl libsecp256k1-dev libsodium-dev libmicrohttpd-dev liblz4-dev libjemalloc-dev htop net-tools netcat iptraf-ng jq tcpdump pv plzip && \
|
||||
apt-get install -y wget curl libatomic1 openssl libsodium-dev libmicrohttpd-dev liblz4-dev libjemalloc-dev htop \
|
||||
net-tools netcat iptraf-ng jq tcpdump pv plzip && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN mkdir -p /var/ton-work/db /var/ton-work/scripts /usr/share/ton/smartcont/ /usr/lib/fift/
|
||||
RUN mkdir -p /var/ton-work/db /var/ton-work/scripts /usr/share/ton/smartcont/auto /usr/lib/fift/
|
||||
|
||||
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/
|
||||
|
@ -35,9 +38,20 @@ 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/
|
||||
COPY --from=builder /ton/build/blockchain-explorer/blockchain-explorer /usr/local/bin/
|
||||
COPY --from=builder /ton/build/crypto/create-state /usr/local/bin/
|
||||
COPY --from=builder /ton/build/utils/proxy-liteserver /usr/local/bin/
|
||||
COPY --from=builder /ton/build/dht-server/dht-server /usr/local/bin/
|
||||
COPY --from=builder /ton/build/rldp-http-proxy/rldp-http-proxy /usr/local/bin/
|
||||
COPY --from=builder /ton/build/http/http-proxy /usr/local/bin/
|
||||
COPY --from=builder /ton/build/adnl/adnl-proxy /usr/local/bin/
|
||||
COPY --from=builder /ton/build/tonlib/libtonlibjson.so /usr/local/bin/
|
||||
COPY --from=builder /ton/build/emulator/libemulator.so /usr/local/bin/
|
||||
COPY --from=builder /ton/build/tolk/tolk /usr/local/bin/
|
||||
COPY --from=builder /ton/build/crypto/fift /usr/local/bin/
|
||||
COPY --from=builder /ton/build/crypto/func /usr/local/bin/
|
||||
COPY --from=builder /ton/crypto/smartcont/* /usr/share/ton/smartcont/
|
||||
COPY --from=builder /ton/crypto/smartcont/auto/* /usr/share/ton/smartcont/auto/
|
||||
COPY --from=builder /ton/crypto/fift/lib/* /usr/lib/fift/
|
||||
|
||||
WORKDIR /var/ton-work/db
|
||||
|
|
|
@ -43,7 +43,10 @@ class AdnlOutboundConnection : public AdnlExtConnection {
|
|||
public:
|
||||
AdnlOutboundConnection(td::SocketFd fd, std::unique_ptr<AdnlExtConnection::Callback> callback, AdnlNodeIdFull dst,
|
||||
td::actor::ActorId<AdnlExtClientImpl> ext_client)
|
||||
: AdnlExtConnection(std::move(fd), std::move(callback), true), dst_(std::move(dst)), ext_client_(ext_client) {
|
||||
: AdnlExtConnection(std::move(fd), std::move(callback), true)
|
||||
, dst_(std::move(dst))
|
||||
, local_id_(privkeys::Ed25519::random())
|
||||
, ext_client_(ext_client) {
|
||||
}
|
||||
AdnlOutboundConnection(td::SocketFd fd, std::unique_ptr<AdnlExtConnection::Callback> callback, AdnlNodeIdFull dst,
|
||||
PrivateKey local_id, td::actor::ActorId<AdnlExtClientImpl> ext_client)
|
||||
|
|
|
@ -8,14 +8,19 @@ while getopts 'a' flag; do
|
|||
esac
|
||||
done
|
||||
|
||||
export CC=$(which clang-16)
|
||||
export CXX=$(which clang++-16)
|
||||
export CCACHE_DISABLE=1
|
||||
|
||||
if [ ! -d android-ndk-r25b ]; then
|
||||
rm android-ndk-r25b-linux.zip
|
||||
echo "Downloading https://dl.google.com/android/repository/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
|
||||
echo "Android NDK extracted"
|
||||
else
|
||||
echo Using extracted Android NDK
|
||||
echo "Using extracted Android NDK"
|
||||
fi
|
||||
|
||||
export JAVA_AWT_LIBRARY=NotNeeded
|
||||
|
|
|
@ -52,21 +52,6 @@ else
|
|||
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
|
||||
|
@ -135,9 +120,6 @@ cmake -GNinja .. \
|
|||
-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 \
|
||||
|
@ -158,35 +140,16 @@ if [ "$with_tests" = true ]; then
|
|||
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-emulator
|
||||
test-rldp2 test-catchain test-fec test-tddb test-db test-validator-session-state test-emulator proxy-liteserver
|
||||
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 tolk 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
|
||||
http-proxy rldp-http-proxy adnl-proxy create-state create-hardfork tlbc emulator proxy-liteserver
|
||||
test $? -eq 0 || { echo "Can't compile ton"; exit 1; }
|
||||
fi
|
||||
|
||||
strip -s storage/storage-daemon/storage-daemon
|
||||
strip -s storage/storage-daemon/storage-daemon-cli
|
||||
strip -s blockchain-explorer/blockchain-explorer
|
||||
strip -s crypto/fift
|
||||
strip -s crypto/func
|
||||
strip -s tolk/tolk
|
||||
strip -s crypto/create-state
|
||||
strip -s crypto/tlbc
|
||||
strip -s validator-engine-console/validator-engine-console
|
||||
strip -s tonlib/tonlib-cli
|
||||
strip -s http/http-proxy
|
||||
strip -s rldp-http-proxy/rldp-http-proxy
|
||||
strip -s dht-server/dht-server
|
||||
strip -s lite-client/lite-client
|
||||
strip -s validator-engine/validator-engine
|
||||
strip -s utils/generate-random-id
|
||||
strip -s utils/json2tlo
|
||||
strip -s adnl/adnl-proxy
|
||||
|
||||
cd ..
|
||||
|
||||
if [ "$with_artifacts" = true ]; then
|
||||
|
@ -211,6 +174,7 @@ if [ "$with_artifacts" = true ]; then
|
|||
cp build/validator-engine/validator-engine artifacts/
|
||||
cp build/utils/generate-random-id artifacts/
|
||||
cp build/utils/json2tlo artifacts/
|
||||
cp build/utils/proxy-liteserver artifacts/
|
||||
cp build/adnl/adnl-proxy artifacts/
|
||||
cp build/emulator/libemulator.dylib artifacts/
|
||||
rsync -r crypto/smartcont artifacts/
|
||||
|
|
|
@ -36,21 +36,6 @@ else
|
|||
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
|
||||
|
@ -70,9 +55,6 @@ 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
|
||||
|
@ -86,36 +68,16 @@ if [ "$with_tests" = true ]; then
|
|||
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-emulator
|
||||
test-rldp2 test-catchain test-fec test-tddb test-db test-validator-session-state test-emulator proxy-liteserver
|
||||
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 tolk 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
|
||||
http-proxy rldp-http-proxy adnl-proxy create-state create-hardfork tlbc emulator proxy-liteserver
|
||||
test $? -eq 0 || { echo "Can't compile ton"; exit 1; }
|
||||
fi
|
||||
|
||||
|
||||
strip -s storage/storage-daemon/storage-daemon
|
||||
strip -s storage/storage-daemon/storage-daemon-cli
|
||||
strip -s blockchain-explorer/blockchain-explorer
|
||||
strip -s crypto/fift
|
||||
strip -s crypto/func
|
||||
strip -s tolk/tolk
|
||||
strip -s crypto/create-state
|
||||
strip -s crypto/tlbc
|
||||
strip -s validator-engine-console/validator-engine-console
|
||||
strip -s tonlib/tonlib-cli
|
||||
strip -s http/http-proxy
|
||||
strip -s rldp-http-proxy/rldp-http-proxy
|
||||
strip -s dht-server/dht-server
|
||||
strip -s lite-client/lite-client
|
||||
strip -s validator-engine/validator-engine
|
||||
strip -s utils/generate-random-id
|
||||
strip -s utils/json2tlo
|
||||
strip -s adnl/adnl-proxy
|
||||
|
||||
cd ..
|
||||
|
||||
if [ "$with_artifacts" = true ]; then
|
||||
|
@ -140,6 +102,7 @@ if [ "$with_artifacts" = true ]; then
|
|||
cp build/validator-engine/validator-engine artifacts/
|
||||
cp build/utils/generate-random-id artifacts/
|
||||
cp build/utils/json2tlo artifacts/
|
||||
cp build/utils/proxy-liteserver artifacts/
|
||||
cp build/adnl/adnl-proxy artifacts/
|
||||
cp build/emulator/libemulator.dylib artifacts/
|
||||
cp -R crypto/smartcont artifacts/
|
||||
|
|
|
@ -43,23 +43,6 @@ else
|
|||
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
|
||||
|
@ -126,9 +109,6 @@ cmake -GNinja .. \
|
|||
-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 \
|
||||
|
@ -150,39 +130,16 @@ ninja storage-daemon storage-daemon-cli fift func tolk tonlib tonlibjson tonlib-
|
|||
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-emulator
|
||||
test-fec test-tddb test-db test-validator-session-state test-emulator proxy-liteserver
|
||||
test $? -eq 0 || { echo "Can't compile ton"; exit 1; }
|
||||
else
|
||||
ninja storage-daemon storage-daemon-cli fift func tolk 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
|
||||
adnl-proxy create-state emulator proxy-liteserver
|
||||
test $? -eq 0 || { echo "Can't compile ton"; exit 1; }
|
||||
fi
|
||||
|
||||
strip -s storage/storage-daemon/storage-daemon \
|
||||
storage/storage-daemon/storage-daemon-cli \
|
||||
blockchain-explorer/blockchain-explorer \
|
||||
crypto/fift \
|
||||
crypto/tlbc \
|
||||
crypto/func \
|
||||
tolk/tolk \
|
||||
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
|
||||
|
@ -197,7 +154,7 @@ if [ "$with_artifacts" = true ]; then
|
|||
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/tolk/tolk build/crypto/create-state build/blockchain-explorer/blockchain-explorer \
|
||||
build/validator-engine-console/validator-engine-console build/tonlib/tonlib-cli \
|
||||
build/validator-engine-console/validator-engine-console build/tonlib/tonlib-cli build/utils/proxy-liteserver \
|
||||
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 \
|
||||
|
|
|
@ -58,39 +58,16 @@ ninja storage-daemon storage-daemon-cli fift func tolk tonlib tonlibjson tonlib-
|
|||
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-emulator
|
||||
test-fec test-tddb test-db test-validator-session-state test-emulator proxy-liteserver
|
||||
test $? -eq 0 || { echo "Can't compile ton"; exit 1; }
|
||||
else
|
||||
ninja storage-daemon storage-daemon-cli fift func tolk 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
|
||||
adnl-proxy create-state emulator proxy-liteserver
|
||||
test $? -eq 0 || { echo "Can't compile ton"; exit 1; }
|
||||
fi
|
||||
|
||||
strip -s storage/storage-daemon/storage-daemon \
|
||||
storage/storage-daemon/storage-daemon-cli \
|
||||
blockchain-explorer/blockchain-explorer \
|
||||
crypto/fift \
|
||||
crypto/tlbc \
|
||||
crypto/func \
|
||||
tolk/tolk \
|
||||
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
|
||||
|
@ -107,7 +84,7 @@ if [ "$with_artifacts" = true ]; then
|
|||
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/tolk/tolk build/crypto/create-state build/blockchain-explorer/blockchain-explorer \
|
||||
build/validator-engine-console/validator-engine-console build/tonlib/tonlib-cli \
|
||||
build/validator-engine-console/validator-engine-console build/tonlib/tonlib-cli build/utils/proxy-liteserver \
|
||||
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 \
|
||||
|
|
|
@ -26,129 +26,109 @@ IF %errorlevel% NEQ 0 (
|
|||
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=v142
|
||||
|
||||
echo Installing nasm...
|
||||
choco install -y nasm
|
||||
where nasm
|
||||
SET PATH=%PATH%;C:\Program Files\NASM
|
||||
IF %errorlevel% NEQ 0 (
|
||||
echo Can't install zlib
|
||||
echo Can't install nasm
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
cd ..\..\..\..
|
||||
|
||||
mkdir third_libs
|
||||
cd third_libs
|
||||
|
||||
set third_libs=%cd%
|
||||
echo %third_libs%
|
||||
|
||||
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=v142
|
||||
cd ..\..\..\..
|
||||
) else (
|
||||
echo Using zlib...
|
||||
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=v142
|
||||
|
||||
IF %errorlevel% NEQ 0 (
|
||||
echo Can't install lz4
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
cd ..\..\..\..
|
||||
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=v142
|
||||
cd ..\..\..\..
|
||||
) else (
|
||||
echo Using lz4...
|
||||
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 16 2019" -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%
|
||||
if not exist "libsodium" (
|
||||
git clone https://github.com/jedisct1/libsodium
|
||||
cd libsodium
|
||||
git checkout 1.0.18-RELEASE
|
||||
msbuild libsodium.vcxproj /p:Configuration=Release /p:platform=x64 -p:PlatformToolset=v142
|
||||
cd ..
|
||||
) else (
|
||||
echo Using libsodium...
|
||||
)
|
||||
cmake --build build --config Release
|
||||
IF %errorlevel% NEQ 0 (
|
||||
echo Can't install secp256k1
|
||||
exit /b %errorlevel%
|
||||
|
||||
if not exist "openssl" (
|
||||
git clone https://github.com/openssl/openssl.git
|
||||
cd openssl
|
||||
git checkout openssl-3.1.4
|
||||
where perl
|
||||
perl Configure VC-WIN64A
|
||||
IF %errorlevel% NEQ 0 (
|
||||
echo Can't configure openssl
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
nmake
|
||||
cd ..
|
||||
) else (
|
||||
echo Using openssl...
|
||||
)
|
||||
|
||||
if not exist "libmicrohttpd" (
|
||||
git clone https://github.com/Karlson2k/libmicrohttpd.git
|
||||
cd libmicrohttpd
|
||||
git checkout v1.0.1
|
||||
cd w32\VS2019
|
||||
msbuild libmicrohttpd.vcxproj /p:Configuration=Release-static /p:platform=x64 -p:PlatformToolset=v142
|
||||
IF %errorlevel% NEQ 0 (
|
||||
echo Can't compile libmicrohttpd
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
cd ../../..
|
||||
) else (
|
||||
echo Using libmicrohttpd...
|
||||
)
|
||||
|
||||
cd ..
|
||||
) else (
|
||||
echo Using secp256k1...
|
||||
)
|
||||
|
||||
|
||||
curl --retry 5 --retry-delay 10 -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
|
||||
echo Current dir %cd%
|
||||
|
||||
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 ^
|
||||
-DSODIUM_LIBRARY_RELEASE=%third_libs%\libsodium\Build\Release\x64\libsodium.lib ^
|
||||
-DSODIUM_LIBRARY_DEBUG=%third_libs%\libsodium\Build\Release\x64\libsodium.lib ^
|
||||
-DSODIUM_INCLUDE_DIR=%third_libs%\libsodium\src\libsodium\include ^
|
||||
-DLZ4_FOUND=1 ^
|
||||
-DLZ4_INCLUDE_DIRS=%root%\lz4\lib ^
|
||||
-DLZ4_LIBRARIES=%root%\lz4\build\VS2017\liblz4\bin\x64_Release\liblz4_static.lib ^
|
||||
-DLZ4_INCLUDE_DIRS=%third_libs%\lz4\lib ^
|
||||
-DLZ4_LIBRARIES=%third_libs%\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 ^
|
||||
-DMHD_LIBRARY=%third_libs%\libmicrohttpd\w32\VS2019\Output\x64\libmicrohttpd.lib ^
|
||||
-DMHD_INCLUDE_DIR=%third_libs%\libmicrohttpd\src\include ^
|
||||
-DZLIB_FOUND=1 ^
|
||||
-DZLIB_INCLUDE_DIR=%root%\zlib ^
|
||||
-DZLIB_LIBRARIES=%root%\zlib\contrib\vstudio\vc14\x64\ZlibStatReleaseWithoutAsm\zlibstat.lib ^
|
||||
-DZLIB_INCLUDE_DIR=%third_libs%\zlib ^
|
||||
-DZLIB_LIBRARIES=%third_libs%\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 ^
|
||||
-DOPENSSL_INCLUDE_DIR=%third_libs%\openssl\include ^
|
||||
-DOPENSSL_CRYPTO_LIBRARY=%third_libs%\openssl\libcrypto_static.lib ^
|
||||
-DCMAKE_CXX_FLAGS="/DTD_WINDOWS=1 /EHsc /bigobj" ..
|
||||
|
||||
IF %errorlevel% NEQ 0 (
|
||||
echo Can't configure TON
|
||||
exit /b %errorlevel%
|
||||
|
@ -160,7 +140,7 @@ tonlib-cli validator-engine lite-client pow-miner validator-engine-console gener
|
|||
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 test-emulator
|
||||
test-fec test-tddb test-db test-validator-session-state test-emulator proxy-liteserver
|
||||
IF %errorlevel% NEQ 0 (
|
||||
echo Can't compile TON
|
||||
exit /b %errorlevel%
|
||||
|
@ -168,7 +148,7 @@ IF %errorlevel% NEQ 0 (
|
|||
) else (
|
||||
ninja storage-daemon storage-daemon-cli blockchain-explorer fift func tolk 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
|
||||
json2tlo dht-server http-proxy rldp-http-proxy adnl-proxy create-state create-hardfork emulator proxy-liteserver
|
||||
IF %errorlevel% NEQ 0 (
|
||||
echo Can't compile TON
|
||||
exit /b %errorlevel%
|
||||
|
@ -191,32 +171,38 @@ REM ctest -C Release --output-on-failure -E "test-catchain|test-actors|test-val
|
|||
)
|
||||
)
|
||||
|
||||
|
||||
echo Creating artifacts...
|
||||
echo Strip and copy artifacts
|
||||
cd ..
|
||||
echo where strip
|
||||
where strip
|
||||
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\tolk\tolk.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 -s %%I & copy %%I artifacts\)
|
||||
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\tolk\tolk.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\utils\proxy-liteserver.exe ^
|
||||
build\adnl\adnl-proxy.exe ^
|
||||
build\emulator\emulator.dll) do (
|
||||
echo strip -s %%I & copy %%I artifacts\
|
||||
strip -s %%I & copy %%I artifacts\
|
||||
)
|
||||
|
||||
xcopy /e /k /h /i crypto\smartcont artifacts\smartcont
|
||||
xcopy /e /k /h /i crypto\fift\lib artifacts\lib
|
||||
|
|
|
@ -26,130 +26,109 @@ IF %errorlevel% NEQ 0 (
|
|||
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
|
||||
|
||||
echo Installing nasm...
|
||||
choco install -y nasm
|
||||
where nasm
|
||||
SET PATH=%PATH%;C:\Program Files\NASM
|
||||
IF %errorlevel% NEQ 0 (
|
||||
echo Can't install zlib
|
||||
echo Can't install nasm
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
cd ..\..\..\..
|
||||
|
||||
mkdir third_libs
|
||||
cd third_libs
|
||||
|
||||
set third_libs=%cd%
|
||||
echo %third_libs%
|
||||
|
||||
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
|
||||
cd ..\..\..\..
|
||||
) else (
|
||||
echo Using zlib...
|
||||
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 ..\..\..\..
|
||||
git clone https://github.com/lz4/lz4.git
|
||||
cd lz4
|
||||
git checkout v1.9.4
|
||||
cd build\VS2022\liblz4
|
||||
msbuild liblz4.vcxproj /p:Configuration=Release /p:platform=x64 -p:PlatformToolset=v143
|
||||
cd ..\..\..\..
|
||||
) else (
|
||||
echo Using lz4...
|
||||
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
|
||||
git clone https://github.com/jedisct1/libsodium
|
||||
cd libsodium
|
||||
git checkout 1.0.18-RELEASE
|
||||
msbuild libsodium.vcxproj /p:Configuration=Release /p:platform=x64 -p:PlatformToolset=v143
|
||||
cd ..
|
||||
) else (
|
||||
echo Using libsodium...
|
||||
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
|
||||
if not exist "openssl" (
|
||||
git clone https://github.com/openssl/openssl.git
|
||||
cd openssl
|
||||
git checkout openssl-3.1.4
|
||||
where perl
|
||||
perl Configure VC-WIN64A
|
||||
IF %errorlevel% NEQ 0 (
|
||||
echo Can't configure openssl
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
nmake
|
||||
cd ..
|
||||
) else (
|
||||
echo Using openssl...
|
||||
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
|
||||
if not exist "libmicrohttpd" (
|
||||
git clone https://github.com/Karlson2k/libmicrohttpd.git
|
||||
cd libmicrohttpd
|
||||
git checkout v1.0.1
|
||||
cd w32\VS2022
|
||||
msbuild libmicrohttpd.vcxproj /p:Configuration=Release-static /p:platform=x64 -p:PlatformToolset=v143
|
||||
IF %errorlevel% NEQ 0 (
|
||||
echo Can't compile libmicrohttpd
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
cd ../../..
|
||||
) else (
|
||||
echo Using libmicrohttpd...
|
||||
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
|
||||
cd ..
|
||||
echo Current dir %cd%
|
||||
|
||||
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 ^
|
||||
-DSODIUM_LIBRARY_RELEASE=%third_libs%\libsodium\Build\Release\x64\libsodium.lib ^
|
||||
-DSODIUM_LIBRARY_DEBUG=%third_libs%\libsodium\Build\Release\x64\libsodium.lib ^
|
||||
-DSODIUM_INCLUDE_DIR=%third_libs%\libsodium\src\libsodium\include ^
|
||||
-DLZ4_FOUND=1 ^
|
||||
-DLZ4_INCLUDE_DIRS=%root%\lz4\lib ^
|
||||
-DLZ4_LIBRARIES=%root%\lz4\build\VS2017\liblz4\bin\x64_Release\liblz4_static.lib ^
|
||||
-DLZ4_INCLUDE_DIRS=%third_libs%\lz4\lib ^
|
||||
-DLZ4_LIBRARIES=%third_libs%\lz4\build\VS2022\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 ^
|
||||
-DMHD_LIBRARY=%third_libs%\libmicrohttpd\w32\VS2022\Output\x64\libmicrohttpd.lib ^
|
||||
-DMHD_INCLUDE_DIR=%third_libs%\libmicrohttpd\src\include ^
|
||||
-DZLIB_FOUND=1 ^
|
||||
-DZLIB_INCLUDE_DIR=%root%\zlib ^
|
||||
-DZLIB_LIBRARIES=%root%\zlib\contrib\vstudio\vc14\x64\ZlibStatReleaseWithoutAsm\zlibstat.lib ^
|
||||
-DZLIB_INCLUDE_DIR=%third_libs%\zlib ^
|
||||
-DZLIB_LIBRARIES=%third_libs%\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 ^
|
||||
-DOPENSSL_INCLUDE_DIR=%third_libs%\openssl\include ^
|
||||
-DOPENSSL_CRYPTO_LIBRARY=%third_libs%\openssl\libcrypto_static.lib ^
|
||||
-DCMAKE_CXX_FLAGS="/DTD_WINDOWS=1 /EHsc /bigobj" ..
|
||||
|
||||
IF %errorlevel% NEQ 0 (
|
||||
echo Can't configure TON
|
||||
exit /b %errorlevel%
|
||||
|
@ -161,7 +140,7 @@ tonlib-cli validator-engine lite-client pow-miner validator-engine-console gener
|
|||
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 test-emulator
|
||||
test-fec test-tddb test-db test-validator-session-state test-emulator proxy-liteserver
|
||||
IF %errorlevel% NEQ 0 (
|
||||
echo Can't compile TON
|
||||
exit /b %errorlevel%
|
||||
|
@ -169,7 +148,7 @@ IF %errorlevel% NEQ 0 (
|
|||
) else (
|
||||
ninja storage-daemon storage-daemon-cli blockchain-explorer fift func tolk 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
|
||||
json2tlo dht-server http-proxy rldp-http-proxy adnl-proxy create-state create-hardfork emulator proxy-liteserver
|
||||
IF %errorlevel% NEQ 0 (
|
||||
echo Can't compile TON
|
||||
exit /b %errorlevel%
|
||||
|
@ -192,32 +171,38 @@ REM ctest -C Release --output-on-failure -E "test-catchain|test-actors|test-val
|
|||
)
|
||||
)
|
||||
|
||||
|
||||
echo Creating artifacts...
|
||||
echo Strip and copy artifacts
|
||||
cd ..
|
||||
echo where strip
|
||||
where strip
|
||||
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\tolk\tolk.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 -s %%I & copy %%I artifacts\)
|
||||
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\tolk\tolk.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\utils\proxy-liteserver.exe ^
|
||||
build\adnl\adnl-proxy.exe ^
|
||||
build\emulator\emulator.dll) do (
|
||||
echo strip -s %%I & copy %%I artifacts\
|
||||
strip -s %%I & copy %%I artifacts\
|
||||
)
|
||||
|
||||
xcopy /e /k /h /i crypto\smartcont artifacts\smartcont
|
||||
xcopy /e /k /h /i crypto\fift\lib artifacts\lib
|
||||
|
|
|
@ -36,23 +36,3 @@ cp ./result/lib/libemulator.so artifacts/
|
|||
cp ./result/lib/fift/* artifacts/lib/
|
||||
cp -r ./result/share/ton/smartcont artifacts/
|
||||
chmod -R +x artifacts
|
||||
cd artifacts
|
||||
sudo strip -s storage-daemon \
|
||||
storage-daemon-cli \
|
||||
blockchain-explorer \
|
||||
fift \
|
||||
tlbc \
|
||||
func \
|
||||
tolk \
|
||||
create-state \
|
||||
validator-engine-console \
|
||||
tonlib-cli \
|
||||
http-proxy \
|
||||
rldp-http-proxy \
|
||||
dht-server \
|
||||
lite-client \
|
||||
validator-engine \
|
||||
generate-random-id \
|
||||
adnl-proxy \
|
||||
libemulator.so \
|
||||
libtonlibjson.so
|
||||
|
|
|
@ -36,23 +36,3 @@ cp ./result/lib/libemulator.so artifacts/
|
|||
cp ./result/lib/fift/* artifacts/lib/
|
||||
cp -r ./result/share/ton/smartcont artifacts/
|
||||
chmod -R +x artifacts
|
||||
cd artifacts
|
||||
sudo strip -s storage-daemon \
|
||||
storage-daemon-cli \
|
||||
blockchain-explorer \
|
||||
fift \
|
||||
tlbc \
|
||||
func \
|
||||
tolk \
|
||||
create-state \
|
||||
validator-engine-console \
|
||||
tonlib-cli \
|
||||
http-proxy \
|
||||
rldp-http-proxy \
|
||||
dht-server \
|
||||
lite-client \
|
||||
validator-engine \
|
||||
generate-random-id \
|
||||
adnl-proxy \
|
||||
libemulator.so \
|
||||
libtonlibjson.so
|
||||
|
|
|
@ -36,23 +36,3 @@ cp ./result/lib/libemulator.dylib artifacts/
|
|||
cp ./result/lib/fift/* artifacts/lib/
|
||||
cp -r ./result/share/ton/smartcont artifacts/
|
||||
chmod -R +x artifacts
|
||||
cd artifacts
|
||||
sudo strip -xSX storage-daemon \
|
||||
storage-daemon-cli \
|
||||
blockchain-explorer \
|
||||
fift \
|
||||
tlbc \
|
||||
func \
|
||||
tolk \
|
||||
create-state \
|
||||
validator-engine-console \
|
||||
tonlib-cli \
|
||||
http-proxy \
|
||||
rldp-http-proxy \
|
||||
dht-server \
|
||||
lite-client \
|
||||
validator-engine \
|
||||
generate-random-id \
|
||||
adnl-proxy \
|
||||
libemulator.dylib \
|
||||
libtonlibjson.dylib
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# sudo apt update
|
||||
# sudo apt install -y build-essential git make cmake ninja-build clang libgflags-dev zlib1g-dev libssl-dev \
|
||||
# libreadline-dev libmicrohttpd-dev pkg-config libgsl-dev python3 python3-dev python3-pip \
|
||||
# nodejs libsecp256k1-dev libsodium-dev automake libtool
|
||||
# nodejs libsodium-dev automake libtool libjemalloc-dev
|
||||
|
||||
# wget https://apt.llvm.org/llvm.sh
|
||||
# chmod +x llvm.sh
|
||||
|
@ -26,13 +26,14 @@ export CCACHE_DISABLE=1
|
|||
|
||||
echo `pwd`
|
||||
if [ "$scratch_new" = true ]; then
|
||||
echo Compiling openssl zlib lz4 emsdk secp256k1 libsodium emsdk ton
|
||||
rm -rf openssl zlib lz4 emsdk secp256k1 libsodium build
|
||||
echo Compiling openssl zlib lz4 emsdk libsodium emsdk ton
|
||||
rm -rf openssl zlib lz4 emsdk libsodium build openssl_em
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -d "openssl" ]; then
|
||||
git clone https://github.com/openssl/openssl.git
|
||||
cp -r openssl openssl_em
|
||||
cd openssl
|
||||
git checkout openssl-3.1.4
|
||||
./config
|
||||
|
@ -47,21 +48,20 @@ fi
|
|||
if [ ! -d "build" ]; then
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_CXX_STANDARD=17 \
|
||||
-DOPENSSL_FOUND=1 \
|
||||
cmake -GNinja -DTON_USE_JEMALLOC=ON .. \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DOPENSSL_ROOT_DIR=$OPENSSL_DIR \
|
||||
-DOPENSSL_INCLUDE_DIR=$OPENSSL_DIR/include \
|
||||
-DOPENSSL_CRYPTO_LIBRARY=$OPENSSL_DIR/libcrypto.so \
|
||||
-DTON_USE_ABSEIL=OFF ..
|
||||
-DOPENSSL_CRYPTO_LIBRARY=$OPENSSL_DIR/libcrypto.so
|
||||
|
||||
test $? -eq 0 || { echo "Can't configure TON build"; exit 1; }
|
||||
ninja fift smc-envelope
|
||||
test $? -eq 0 || { echo "Can't compile fift "; exit 1; }
|
||||
rm -rf *
|
||||
rm -rf * .ninja* CMakeCache.txt
|
||||
cd ..
|
||||
else
|
||||
echo cleaning build...
|
||||
rm -rf build/*
|
||||
rm -rf build/* build/.ninja* build/CMakeCache.txt
|
||||
fi
|
||||
|
||||
if [ ! -d "emsdk" ]; then
|
||||
|
@ -71,8 +71,8 @@ echo
|
|||
fi
|
||||
|
||||
cd emsdk
|
||||
./emsdk install 3.1.19
|
||||
./emsdk activate 3.1.19
|
||||
./emsdk install 3.1.40
|
||||
./emsdk activate 3.1.40
|
||||
EMSDK_DIR=`pwd`
|
||||
|
||||
. $EMSDK_DIR/emsdk_env.sh
|
||||
|
@ -82,9 +82,8 @@ export CCACHE_DISABLE=1
|
|||
|
||||
cd ..
|
||||
|
||||
if [ ! -f "openssl/openssl_em" ]; then
|
||||
cd openssl
|
||||
make clean
|
||||
if [ ! -f "openssl_em/openssl_em" ]; then
|
||||
cd openssl_em
|
||||
emconfigure ./Configure linux-generic32 no-shared no-dso no-engine no-unit-test no-tests no-fuzz-afl no-fuzz-libfuzzer
|
||||
sed -i 's/CROSS_COMPILE=.*/CROSS_COMPILE=/g' Makefile
|
||||
sed -i 's/-ldl//g' Makefile
|
||||
|
@ -92,10 +91,12 @@ if [ ! -f "openssl/openssl_em" ]; then
|
|||
emmake make depend
|
||||
emmake make -j16
|
||||
test $? -eq 0 || { echo "Can't compile OpenSSL with emmake "; exit 1; }
|
||||
OPENSSL_DIR=`pwd`
|
||||
touch openssl_em
|
||||
cd ..
|
||||
else
|
||||
echo Using compiled openssl with emscripten
|
||||
OPENSSL_DIR=`pwd`/openssl_em
|
||||
echo Using compiled with empscripten openssl at $OPENSSL_DIR
|
||||
fi
|
||||
|
||||
if [ ! -d "zlib" ]; then
|
||||
|
@ -125,21 +126,6 @@ else
|
|||
echo Using compiled lz4 with emscripten at $LZ4_DIR
|
||||
fi
|
||||
|
||||
if [ ! -d "secp256k1" ]; then
|
||||
git clone https://github.com/bitcoin-core/secp256k1.git
|
||||
cd secp256k1
|
||||
git checkout v0.3.2
|
||||
./autogen.sh
|
||||
SECP256K1_DIR=`pwd`
|
||||
emconfigure ./configure --enable-module-recovery
|
||||
emmake make -j16
|
||||
test $? -eq 0 || { echo "Can't compile secp256k1 with emmake "; exit 1; }
|
||||
cd ..
|
||||
else
|
||||
SECP256K1_DIR=`pwd`/secp256k1
|
||||
echo Using compiled secp256k1 with emscripten at $SECP256K1_DIR
|
||||
fi
|
||||
|
||||
if [ ! -d "libsodium" ]; then
|
||||
git clone https://github.com/jedisct1/libsodium
|
||||
cd libsodium
|
||||
|
@ -168,9 +154,9 @@ emcmake cmake -DUSE_EMSCRIPTEN=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_VERBOSE_MAK
|
|||
-DOPENSSL_CRYPTO_LIBRARY=$OPENSSL_DIR/libcrypto.a \
|
||||
-DCMAKE_TOOLCHAIN_FILE=$EMSDK_DIR/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake \
|
||||
-DCMAKE_CXX_FLAGS="-sUSE_ZLIB=1" \
|
||||
-DSECP256K1_INCLUDE_DIR=$SECP256K1_DIR/include \
|
||||
-DSECP256K1_LIBRARY=$SECP256K1_DIR/.libs/libsecp256k1.a \
|
||||
-DSODIUM_FOUND=1 \
|
||||
-DSODIUM_INCLUDE_DIR=$SODIUM_DIR/src/libsodium/include \
|
||||
-DSODIUM_USE_STATIC_LIBS=1 \
|
||||
-DSODIUM_LIBRARY_RELEASE=$SODIUM_DIR/src/libsodium/.libs/libsodium.a \
|
||||
..
|
||||
|
||||
|
@ -194,5 +180,3 @@ if [ "$with_artifacts" = true ]; then
|
|||
cp -R crypto/smartcont artifacts
|
||||
cp -R crypto/fift/lib artifacts
|
||||
fi
|
||||
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ endif()
|
|||
|
||||
target_include_directories(blockchain-explorer PUBLIC ${MHD_INCLUDE_DIR})
|
||||
target_link_libraries(blockchain-explorer tdactor adnllite tl_lite_api tl-lite-utils ton_crypto ${MHD_LIBRARY})
|
||||
target_link_libraries(blockchain-explorer lite-client-common)
|
||||
|
||||
install(TARGETS blockchain-explorer RUNTIME DESTINATION bin)
|
||||
|
||||
|
|
|
@ -1432,7 +1432,7 @@ void HttpQueryStatus::finish_query() {
|
|||
for (td::uint32 i = 0; i < results_.ips.size(); i++) {
|
||||
A << "<tr>";
|
||||
if (results_.ips[i].is_valid()) {
|
||||
A << "<td>" << results_.ips[i] << "</td>";
|
||||
A << "<td>" << results_.ips[i].get_ip_str() << ":" << results_.ips[i].get_port() << "</td>";
|
||||
} else {
|
||||
A << "<td>hidden</td>";
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include "auto/tl/lite_api.h"
|
||||
#include "ton/lite-tl.hpp"
|
||||
#include "tl-utils/lite-utils.hpp"
|
||||
#include "lite-client/ext-client.h"
|
||||
|
||||
#include <microhttpd.h>
|
||||
|
||||
|
@ -127,7 +128,7 @@ class CoreActor : public CoreActorInterface {
|
|||
private:
|
||||
std::string global_config_ = "ton-global.config";
|
||||
|
||||
std::vector<td::actor::ActorOwn<ton::adnl::AdnlExtClient>> clients_;
|
||||
td::actor::ActorOwn<liteclient::ExtClient> client_;
|
||||
|
||||
td::uint32 http_port_ = 80;
|
||||
MHD_Daemon* daemon_ = nullptr;
|
||||
|
@ -137,35 +138,29 @@ class CoreActor : public CoreActorInterface {
|
|||
|
||||
bool hide_ips_ = false;
|
||||
|
||||
std::unique_ptr<ton::adnl::AdnlExtClient::Callback> make_callback(td::uint32 idx) {
|
||||
class Callback : public ton::adnl::AdnlExtClient::Callback {
|
||||
td::unique_ptr<liteclient::ExtClient::Callback> make_callback() {
|
||||
class Callback : public liteclient::ExtClient::Callback {
|
||||
public:
|
||||
void on_ready() override {
|
||||
td::actor::send_closure(id_, &CoreActor::conn_ready, idx_);
|
||||
}
|
||||
void on_stop_ready() override {
|
||||
td::actor::send_closure(id_, &CoreActor::conn_closed, idx_);
|
||||
}
|
||||
Callback(td::actor::ActorId<CoreActor> id, td::uint32 idx) : id_(std::move(id)), idx_(idx) {
|
||||
Callback(td::actor::ActorId<CoreActor> id) : id_(std::move(id)) {
|
||||
}
|
||||
|
||||
private:
|
||||
td::actor::ActorId<CoreActor> id_;
|
||||
td::uint32 idx_;
|
||||
};
|
||||
|
||||
return std::make_unique<Callback>(actor_id(this), idx);
|
||||
return td::make_unique<Callback>(actor_id(this));
|
||||
}
|
||||
|
||||
std::shared_ptr<RemoteNodeStatus> new_result_;
|
||||
td::int32 attempt_ = 0;
|
||||
td::int32 waiting_ = 0;
|
||||
|
||||
std::vector<bool> ready_;
|
||||
size_t n_servers_ = 0;
|
||||
|
||||
void run_queries();
|
||||
void got_result(td::uint32 idx, td::int32 attempt, td::Result<td::BufferSlice> data);
|
||||
void send_query(td::uint32 idx);
|
||||
void got_servers_ready(td::int32 attempt, std::vector<bool> ready);
|
||||
void send_ping(td::uint32 idx);
|
||||
void got_ping_result(td::uint32 idx, td::int32 attempt, td::Result<td::BufferSlice> data);
|
||||
|
||||
void add_result() {
|
||||
if (new_result_) {
|
||||
|
@ -196,12 +191,6 @@ class CoreActor : public CoreActorInterface {
|
|||
static CoreActor* instance_;
|
||||
td::actor::ActorId<CoreActor> self_id_;
|
||||
|
||||
void conn_ready(td::uint32 idx) {
|
||||
ready_.at(idx) = true;
|
||||
}
|
||||
void conn_closed(td::uint32 idx) {
|
||||
ready_.at(idx) = false;
|
||||
}
|
||||
void set_global_config(std::string str) {
|
||||
global_config_ = str;
|
||||
}
|
||||
|
@ -226,10 +215,7 @@ class CoreActor : public CoreActorInterface {
|
|||
hide_ips_ = value;
|
||||
}
|
||||
|
||||
void send_lite_query(td::uint32 idx, td::BufferSlice query, td::Promise<td::BufferSlice> promise);
|
||||
void send_lite_query(td::BufferSlice data, td::Promise<td::BufferSlice> promise) override {
|
||||
return send_lite_query(0, std::move(data), std::move(promise));
|
||||
}
|
||||
void send_lite_query(td::BufferSlice query, td::Promise<td::BufferSlice> promise) override;
|
||||
void get_last_result(td::Promise<std::shared_ptr<RemoteNodeStatus>> promise) override {
|
||||
}
|
||||
void get_results(td::uint32 max, td::Promise<RemoteNodeStatusList> promise) override {
|
||||
|
@ -449,33 +435,27 @@ class CoreActor : public CoreActorInterface {
|
|||
}
|
||||
|
||||
void run() {
|
||||
std::vector<liteclient::LiteServerConfig> servers;
|
||||
if (remote_public_key_.empty()) {
|
||||
auto G = td::read_file(global_config_).move_as_ok();
|
||||
auto gc_j = td::json_decode(G.as_slice()).move_as_ok();
|
||||
ton::ton_api::liteclient_config_global gc;
|
||||
ton::ton_api::from_json(gc, gc_j.get_object()).ensure();
|
||||
|
||||
CHECK(gc.liteservers_.size() > 0);
|
||||
td::uint32 size = static_cast<td::uint32>(gc.liteservers_.size());
|
||||
ready_.resize(size, false);
|
||||
|
||||
for (td::uint32 i = 0; i < size; i++) {
|
||||
auto& cli = gc.liteservers_[i];
|
||||
td::IPAddress addr;
|
||||
addr.init_host_port(td::IPAddress::ipv4_to_str(cli->ip_), cli->port_).ensure();
|
||||
addrs_.push_back(addr);
|
||||
clients_.emplace_back(ton::adnl::AdnlExtClient::create(ton::adnl::AdnlNodeIdFull::create(cli->id_).move_as_ok(),
|
||||
addr, make_callback(i)));
|
||||
auto r_servers = liteclient::LiteServerConfig::parse_global_config(gc);
|
||||
r_servers.ensure();
|
||||
servers = r_servers.move_as_ok();
|
||||
for (const auto& serv : servers) {
|
||||
addrs_.push_back(serv.addr);
|
||||
}
|
||||
} else {
|
||||
if (!remote_addr_.is_valid()) {
|
||||
LOG(FATAL) << "remote addr not set";
|
||||
}
|
||||
ready_.resize(1, false);
|
||||
addrs_.push_back(remote_addr_);
|
||||
clients_.emplace_back(ton::adnl::AdnlExtClient::create(ton::adnl::AdnlNodeIdFull{remote_public_key_},
|
||||
remote_addr_, make_callback(0)));
|
||||
servers.push_back(liteclient::LiteServerConfig{ton::adnl::AdnlNodeIdFull{remote_public_key_}, remote_addr_});
|
||||
}
|
||||
n_servers_ = servers.size();
|
||||
client_ = liteclient::ExtClient::create(std::move(servers), make_callback(), true);
|
||||
daemon_ = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, static_cast<td::uint16>(http_port_), nullptr, nullptr,
|
||||
&process_http_request, nullptr, MHD_OPTION_NOTIFY_COMPLETED, request_completed, nullptr,
|
||||
MHD_OPTION_THREAD_POOL_SIZE, 16, MHD_OPTION_END);
|
||||
|
@ -483,7 +463,46 @@ class CoreActor : public CoreActorInterface {
|
|||
}
|
||||
};
|
||||
|
||||
void CoreActor::got_result(td::uint32 idx, td::int32 attempt, td::Result<td::BufferSlice> R) {
|
||||
void CoreActor::run_queries() {
|
||||
waiting_ = 0;
|
||||
new_result_ = std::make_shared<RemoteNodeStatus>(n_servers_, td::Timestamp::at_unix(attempt_ * 60));
|
||||
td::actor::send_closure(client_, &liteclient::ExtClient::get_servers_status,
|
||||
[SelfId = actor_id(this), attempt = attempt_](td::Result<std::vector<bool>> R) {
|
||||
R.ensure();
|
||||
td::actor::send_closure(SelfId, &CoreActor::got_servers_ready, attempt, R.move_as_ok());
|
||||
});
|
||||
}
|
||||
|
||||
void CoreActor::got_servers_ready(td::int32 attempt, std::vector<bool> ready) {
|
||||
if (attempt != attempt_) {
|
||||
return;
|
||||
}
|
||||
CHECK(ready.size() == n_servers_);
|
||||
for (td::uint32 i = 0; i < n_servers_; i++) {
|
||||
if (ready[i]) {
|
||||
send_ping(i);
|
||||
}
|
||||
}
|
||||
CHECK(waiting_ >= 0);
|
||||
if (waiting_ == 0) {
|
||||
add_result();
|
||||
}
|
||||
}
|
||||
|
||||
void CoreActor::send_ping(td::uint32 idx) {
|
||||
waiting_++;
|
||||
auto query = ton::create_tl_object<ton::lite_api::liteServer_getMasterchainInfo>();
|
||||
auto q = ton::create_tl_object<ton::lite_api::liteServer_query>(serialize_tl_object(query, true));
|
||||
|
||||
auto P =
|
||||
td::PromiseCreator::lambda([SelfId = actor_id(this), idx, attempt = attempt_](td::Result<td::BufferSlice> R) {
|
||||
td::actor::send_closure(SelfId, &CoreActor::got_ping_result, idx, attempt, std::move(R));
|
||||
});
|
||||
td::actor::send_closure(client_, &liteclient::ExtClient::send_query_to_server, "query", serialize_tl_object(q, true),
|
||||
idx, td::Timestamp::in(10.0), std::move(P));
|
||||
}
|
||||
|
||||
void CoreActor::got_ping_result(td::uint32 idx, td::int32 attempt, td::Result<td::BufferSlice> R) {
|
||||
if (attempt != attempt_) {
|
||||
return;
|
||||
}
|
||||
|
@ -524,39 +543,7 @@ void CoreActor::got_result(td::uint32 idx, td::int32 attempt, td::Result<td::Buf
|
|||
}
|
||||
}
|
||||
|
||||
void CoreActor::send_query(td::uint32 idx) {
|
||||
if (!ready_[idx]) {
|
||||
return;
|
||||
}
|
||||
waiting_++;
|
||||
auto query = ton::create_tl_object<ton::lite_api::liteServer_getMasterchainInfo>();
|
||||
auto q = ton::create_tl_object<ton::lite_api::liteServer_query>(serialize_tl_object(query, true));
|
||||
|
||||
auto P =
|
||||
td::PromiseCreator::lambda([SelfId = actor_id(this), idx, attempt = attempt_](td::Result<td::BufferSlice> R) {
|
||||
td::actor::send_closure(SelfId, &CoreActor::got_result, idx, attempt, std::move(R));
|
||||
});
|
||||
td::actor::send_closure(clients_[idx], &ton::adnl::AdnlExtClient::send_query, "query", serialize_tl_object(q, true),
|
||||
td::Timestamp::in(10.0), std::move(P));
|
||||
}
|
||||
|
||||
void CoreActor::run_queries() {
|
||||
waiting_ = 0;
|
||||
new_result_ = std::make_shared<RemoteNodeStatus>(ready_.size(), td::Timestamp::at_unix(attempt_ * 60));
|
||||
for (td::uint32 i = 0; i < ready_.size(); i++) {
|
||||
send_query(i);
|
||||
}
|
||||
CHECK(waiting_ >= 0);
|
||||
if (waiting_ == 0) {
|
||||
add_result();
|
||||
}
|
||||
}
|
||||
|
||||
void CoreActor::send_lite_query(td::uint32 idx, td::BufferSlice query, td::Promise<td::BufferSlice> promise) {
|
||||
if (!ready_[idx]) {
|
||||
promise.set_error(td::Status::Error(ton::ErrorCode::notready, "ext conn not ready"));
|
||||
return;
|
||||
}
|
||||
void CoreActor::send_lite_query(td::BufferSlice query, td::Promise<td::BufferSlice> promise) {
|
||||
auto P = td::PromiseCreator::lambda([promise = std::move(promise)](td::Result<td::BufferSlice> R) mutable {
|
||||
if (R.is_error()) {
|
||||
promise.set_error(R.move_as_error());
|
||||
|
@ -574,7 +561,7 @@ void CoreActor::send_lite_query(td::uint32 idx, td::BufferSlice query, td::Promi
|
|||
promise.set_value(std::move(B));
|
||||
});
|
||||
auto q = ton::create_tl_object<ton::lite_api::liteServer_query>(std::move(query));
|
||||
td::actor::send_closure(clients_[idx], &ton::adnl::AdnlExtClient::send_query, "query", serialize_tl_object(q, true),
|
||||
td::actor::send_closure(client_, &liteclient::ExtClient::send_query, "query", serialize_tl_object(q, true),
|
||||
td::Timestamp::in(10.0), std::move(P));
|
||||
}
|
||||
|
||||
|
|
|
@ -236,9 +236,8 @@ class HardforkCreator : public td::actor::Actor {
|
|||
td::actor::send_closure(id_, &ton::validator::ValidatorManager::sync_complete,
|
||||
td::PromiseCreator::lambda([](td::Unit) {}));
|
||||
}
|
||||
void add_shard(ton::ShardIdFull) override {
|
||||
}
|
||||
void del_shard(ton::ShardIdFull) override {
|
||||
void on_new_masterchain_block(td::Ref<ton::validator::MasterchainState> state,
|
||||
std::set<ton::ShardIdFull> shards_to_monitor) override {
|
||||
}
|
||||
void send_ihr_message(ton::AccountIdPrefixFull dst, td::BufferSlice data) override {
|
||||
}
|
||||
|
@ -270,13 +269,19 @@ class HardforkCreator : public td::actor::Actor {
|
|||
void get_next_key_blocks(ton::BlockIdExt block_id, td::Timestamp timeout,
|
||||
td::Promise<std::vector<ton::BlockIdExt>> promise) override {
|
||||
}
|
||||
void download_archive(ton::BlockSeqno masterchain_seqno, std::string tmp_dir, td::Timestamp timeout,
|
||||
|
||||
td::Promise<std::string> promise) override {
|
||||
void download_archive(ton::BlockSeqno masterchain_seqno, ton::ShardIdFull shard_prefix, std::string tmp_dir,
|
||||
td::Timestamp timeout, td::Promise<std::string> promise) override {
|
||||
}
|
||||
void download_out_msg_queue_proof(
|
||||
ton::ShardIdFull dst_shard, std::vector<ton::BlockIdExt> blocks, block::ImportedMsgQueueLimits limits,
|
||||
td::Timestamp timeout, td::Promise<std::vector<td::Ref<ton::validator::OutMsgQueueProof>>> promise) override {
|
||||
}
|
||||
|
||||
void new_key_block(ton::validator::BlockHandle handle) override {
|
||||
}
|
||||
void send_validator_telemetry(ton::PublicKeyHash key,
|
||||
ton::tl_object_ptr<ton::ton_api::validator_telemetry> telemetry) override {
|
||||
}
|
||||
};
|
||||
|
||||
td::actor::send_closure(validator_manager_, &ton::validator::ValidatorManagerInterface::install_callback,
|
||||
|
|
|
@ -318,20 +318,20 @@ endif()
|
|||
target_include_directories(ton_crypto SYSTEM PUBLIC $<BUILD_INTERFACE:${OPENSSL_INCLUDE_DIR}>)
|
||||
|
||||
add_dependencies(ton_crypto blst)
|
||||
add_dependencies(ton_crypto_core secp256k1)
|
||||
|
||||
target_include_directories(ton_crypto PRIVATE ${BLST_INCLUDE_DIR})
|
||||
target_link_libraries(ton_crypto PRIVATE ${BLST_LIB})
|
||||
|
||||
if (NOT USE_EMSCRIPTEN)
|
||||
find_package(Secp256k1 REQUIRED)
|
||||
endif()
|
||||
target_include_directories(ton_crypto_core PUBLIC $<BUILD_INTERFACE:${SECP256K1_INCLUDE_DIR}>)
|
||||
|
||||
if (MSVC)
|
||||
find_package(Sodium REQUIRED)
|
||||
target_compile_definitions(ton_crypto PUBLIC SODIUM_STATIC)
|
||||
target_include_directories(ton_crypto_core PUBLIC $<BUILD_INTERFACE:${SECP256K1_INCLUDE_DIR}>)
|
||||
target_link_libraries(ton_crypto_core PUBLIC ${SECP256K1_LIBRARY})
|
||||
target_link_libraries(ton_crypto PUBLIC ${SECP256K1_LIBRARY})
|
||||
elseif (ANDROID OR EMSCRIPTEN)
|
||||
target_include_directories(ton_crypto_core PUBLIC $<BUILD_INTERFACE:${SECP256K1_INCLUDE_DIR}>)
|
||||
elseif (EMSCRIPTEN)
|
||||
target_link_libraries(ton_crypto_core PUBLIC $<BUILD_INTERFACE:${SECP256K1_LIBRARY}>)
|
||||
target_link_libraries(ton_crypto PUBLIC $<BUILD_INTERFACE:${SECP256K1_LIBRARY}>)
|
||||
else()
|
||||
if (NOT SODIUM_FOUND)
|
||||
|
@ -340,11 +340,10 @@ else()
|
|||
message(STATUS "Using Sodium ${SODIUM_LIBRARY_RELEASE}")
|
||||
endif()
|
||||
target_compile_definitions(ton_crypto PUBLIC SODIUM_STATIC)
|
||||
target_include_directories(ton_crypto_core PUBLIC $<BUILD_INTERFACE:${SECP256K1_INCLUDE_DIR}>)
|
||||
target_link_libraries(ton_crypto_core PUBLIC ${SECP256K1_LIBRARY})
|
||||
target_link_libraries(ton_crypto PUBLIC ${SECP256K1_LIBRARY})
|
||||
endif()
|
||||
|
||||
target_link_libraries(ton_crypto_core PUBLIC ${SECP256K1_LIBRARY})
|
||||
target_include_directories(ton_crypto_core PUBLIC $<BUILD_INTERFACE:${SODIUM_INCLUDE_DIR}>)
|
||||
target_link_libraries(ton_crypto PUBLIC ${SODIUM_LIBRARY_RELEASE})
|
||||
|
||||
|
|
|
@ -660,6 +660,12 @@ bool EnqueuedMsgDescr::check_key(td::ConstBitPtr key) const {
|
|||
hash_ == key + 96;
|
||||
}
|
||||
|
||||
bool ImportedMsgQueueLimits::deserialize(vm::CellSlice& cs) {
|
||||
return cs.fetch_ulong(8) == 0xd3 // imported_msg_queue_limits#d3
|
||||
&& cs.fetch_uint_to(32, max_bytes) // max_bytes:#
|
||||
&& cs.fetch_uint_to(32, max_msgs); // max_msgs:#
|
||||
}
|
||||
|
||||
bool ParamLimits::deserialize(vm::CellSlice& cs) {
|
||||
return cs.fetch_ulong(8) == 0xc3 // param_limits#c3
|
||||
&& cs.fetch_uint_to(32, limits_[0]) // underload:uint32
|
||||
|
|
|
@ -216,6 +216,16 @@ static inline std::ostream& operator<<(std::ostream& os, const MsgProcessedUptoC
|
|||
return proc_coll.print(os);
|
||||
}
|
||||
|
||||
struct ImportedMsgQueueLimits {
|
||||
// Default values
|
||||
td::uint32 max_bytes = 1 << 16;
|
||||
td::uint32 max_msgs = 30;
|
||||
bool deserialize(vm::CellSlice& cs);
|
||||
ImportedMsgQueueLimits operator*(td::uint32 x) const {
|
||||
return {max_bytes * x, max_msgs * x};
|
||||
}
|
||||
};
|
||||
|
||||
struct ParamLimits {
|
||||
enum { limits_cnt = 4 };
|
||||
enum { cl_underload = 0, cl_normal = 1, cl_soft = 2, cl_medium = 3, cl_hard = 4 };
|
||||
|
|
|
@ -818,7 +818,7 @@ _ OracleBridgeParams = ConfigParam 72; // Binance Smart Chain bridge
|
|||
_ OracleBridgeParams = ConfigParam 73; // Polygon bridge
|
||||
|
||||
// Note that chains in which bridge, minter and jetton-wallet operate are fixated
|
||||
jetton_bridge_prices#_ bridge_burn_fee:Coins bridge_mint_fee:Coins
|
||||
jetton_bridge_prices#_ bridge_burn_fee:Coins bridge_mint_fee:Coins
|
||||
wallet_min_tons_for_storage:Coins
|
||||
wallet_gas_consumption:Coins
|
||||
minter_min_tons_for_storage:Coins
|
||||
|
|
|
@ -554,11 +554,7 @@ class BitArray {
|
|||
set_same(0);
|
||||
}
|
||||
void set_zero_s() {
|
||||
volatile uint8* p = data();
|
||||
auto x = m;
|
||||
while (x--) {
|
||||
*p++ = 0;
|
||||
}
|
||||
as_slice().fill_zero_secure();
|
||||
}
|
||||
void set_ones() {
|
||||
set_same(1);
|
||||
|
|
|
@ -17,13 +17,22 @@
|
|||
|
||||
#include "secp256k1.h"
|
||||
#include "td/utils/check.h"
|
||||
#include "td/utils/logging.h"
|
||||
|
||||
#include <secp256k1_recovery.h>
|
||||
#include <secp256k1_extrakeys.h>
|
||||
#include <cstring>
|
||||
|
||||
namespace td {
|
||||
namespace td::secp256k1 {
|
||||
|
||||
static const secp256k1_context* get_context() {
|
||||
static secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
|
||||
LOG_CHECK(ctx) << "Failed to create secp256k1_context";
|
||||
return ctx;
|
||||
}
|
||||
|
||||
bool ecrecover(const unsigned char* hash, const unsigned char* signature, unsigned char* public_key) {
|
||||
static secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
|
||||
const secp256k1_context* ctx = get_context();
|
||||
secp256k1_ecdsa_recoverable_signature ecdsa_signature;
|
||||
if (signature[64] > 3 ||
|
||||
!secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &ecdsa_signature, signature, signature[64])) {
|
||||
|
@ -39,4 +48,22 @@ bool ecrecover(const unsigned char* hash, const unsigned char* signature, unsign
|
|||
return true;
|
||||
}
|
||||
|
||||
bool xonly_pubkey_tweak_add(const unsigned char* xonly_pubkey_bytes, const unsigned char* tweak,
|
||||
unsigned char* output_pubkey_bytes) {
|
||||
const secp256k1_context* ctx = get_context();
|
||||
|
||||
secp256k1_xonly_pubkey xonly_pubkey;
|
||||
secp256k1_pubkey output_pubkey;
|
||||
if (!secp256k1_xonly_pubkey_parse(ctx, &xonly_pubkey, xonly_pubkey_bytes)) {
|
||||
return false;
|
||||
}
|
||||
if (!secp256k1_xonly_pubkey_tweak_add(ctx, &output_pubkey, &xonly_pubkey, tweak)) {
|
||||
return false;
|
||||
}
|
||||
size_t len = 65;
|
||||
secp256k1_ec_pubkey_serialize(ctx, output_pubkey_bytes, &len, &output_pubkey, SECP256K1_EC_UNCOMPRESSED);
|
||||
CHECK(len == 65);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace td::secp256k1
|
||||
|
|
|
@ -16,8 +16,10 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
namespace td {
|
||||
namespace td::secp256k1 {
|
||||
|
||||
bool ecrecover(const unsigned char* hash, const unsigned char* signature, unsigned char* public_key);
|
||||
bool xonly_pubkey_tweak_add(const unsigned char* xonly_pubkey_bytes, const unsigned char* tweak,
|
||||
unsigned char* output_pubkey_bytes);
|
||||
|
||||
}
|
||||
} // namespace td::secp256k1
|
||||
|
|
|
@ -1015,6 +1015,10 @@ x{EDC} dup @Defop(c) SAVEBOTH @Defop(c) SAVEBOTHCTR
|
|||
x{EDE0} @Defop PUSHCTRX
|
||||
x{EDE1} @Defop POPCTRX
|
||||
x{EDE2} @Defop SETCONTCTRX
|
||||
x{EDE3} @Defop(8u) SETCONTCTRMANY
|
||||
x{EDE3} @Defop(8u) SETCONTMANY
|
||||
x{EDE4} @Defop SETCONTCTRMANYX
|
||||
x{EDE4} @Defop SETCONTMANYX
|
||||
x{EDF0} dup @Defop BOOLAND @Defop COMPOS
|
||||
x{EDF1} dup @Defop BOOLOR @Defop COMPOSALT
|
||||
x{EDF2} @Defop COMPOSBOTH
|
||||
|
@ -1354,6 +1358,7 @@ x{F90704} @Defop HASHEXTAR_KECCAK512
|
|||
x{F910} @Defop CHKSIGNU
|
||||
x{F911} @Defop CHKSIGNS
|
||||
x{F912} @Defop ECRECOVER
|
||||
x{F913} @Defop SECP256K1_XONLY_PUBKEY_TWEAK_ADD
|
||||
x{F914} @Defop P256_CHKSIGNU
|
||||
x{F915} @Defop P256_CHKSIGNS
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
int foo(int x) method_id(11) {
|
||||
int foo(int x) {
|
||||
try {
|
||||
if (x == 7) {
|
||||
throw(44);
|
||||
|
@ -9,7 +9,7 @@ int foo(int x) method_id(11) {
|
|||
}
|
||||
}
|
||||
|
||||
int foo_inline(int x) inline method_id(12) {
|
||||
int foo_inline(int x) inline {
|
||||
try {
|
||||
if (x == 7) {
|
||||
throw(44);
|
||||
|
@ -20,7 +20,7 @@ int foo_inline(int x) inline method_id(12) {
|
|||
}
|
||||
}
|
||||
|
||||
int foo_inlineref(int x) inline_ref method_id(13) {
|
||||
int foo_inlineref(int x) inline_ref {
|
||||
try {
|
||||
if (x == 7) {
|
||||
throw(44);
|
||||
|
@ -31,17 +31,17 @@ int foo_inlineref(int x) inline_ref method_id(13) {
|
|||
}
|
||||
}
|
||||
|
||||
int test(int x, int y, int z) method_id(1) {
|
||||
int test(int x, int y, int z) method_id(101) {
|
||||
y = foo(y);
|
||||
return x * 100 + y * 10 + z;
|
||||
}
|
||||
|
||||
int test_inline(int x, int y, int z) method_id(2) {
|
||||
int test_inline(int x, int y, int z) method_id(102) {
|
||||
y = foo_inline(y);
|
||||
return x * 100 + y * 10 + z;
|
||||
}
|
||||
|
||||
int test_inlineref(int x, int y, int z) method_id(3) {
|
||||
int test_inlineref(int x, int y, int z) method_id(103) {
|
||||
y = foo_inlineref(y);
|
||||
return x * 100 + y * 10 + z;
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ int test_inlineref(int x, int y, int z) method_id(3) {
|
|||
int foo_inline_big(
|
||||
int x1, int x2, int x3, int x4, int x5, int x6, int x7, int x8, int x9, int x10,
|
||||
int x11, int x12, int x13, int x14, int x15, int x16, int x17, int x18, int x19, int x20
|
||||
) inline method_id(14) {
|
||||
) inline {
|
||||
try {
|
||||
if (x1 == 7) {
|
||||
throw(44);
|
||||
|
@ -60,7 +60,7 @@ int foo_inline_big(
|
|||
}
|
||||
}
|
||||
|
||||
int test_inline_big(int x, int y, int z) method_id(4) {
|
||||
int test_inline_big(int x, int y, int z) method_id(104) {
|
||||
y = foo_inline_big(
|
||||
y, y + 1, y + 2, y + 3, y + 4, y + 5, y + 6, y + 7, y + 8, y + 9,
|
||||
y + 10, y + 11, y + 12, y + 13, y + 14, y + 15, y + 16, y + 17, y + 18, y + 19);
|
||||
|
@ -70,7 +70,7 @@ int test_inline_big(int x, int y, int z) method_id(4) {
|
|||
int foo_big(
|
||||
int x1, int x2, int x3, int x4, int x5, int x6, int x7, int x8, int x9, int x10,
|
||||
int x11, int x12, int x13, int x14, int x15, int x16, int x17, int x18, int x19, int x20
|
||||
) method_id(15) {
|
||||
) {
|
||||
try {
|
||||
if (x1 == 7) {
|
||||
throw(44);
|
||||
|
@ -81,29 +81,69 @@ int foo_big(
|
|||
}
|
||||
}
|
||||
|
||||
int test_big(int x, int y, int z) method_id(5) {
|
||||
int test_big(int x, int y, int z) method_id(105) {
|
||||
y = foo_big(
|
||||
y, y + 1, y + 2, y + 3, y + 4, y + 5, y + 6, y + 7, y + 8, y + 9,
|
||||
y + 10, y + 11, y + 12, y + 13, y + 14, y + 15, y + 16, y + 17, y + 18, y + 19);
|
||||
return x * 1000000 + y * 1000 + z;
|
||||
}
|
||||
|
||||
|
||||
() some_throwing(int op) impure {
|
||||
if (op == 1) {
|
||||
return ();
|
||||
} elseif (op == 2) {
|
||||
return ();
|
||||
} else {
|
||||
throw(1);
|
||||
}
|
||||
}
|
||||
|
||||
int test106() method_id(106) {
|
||||
try {
|
||||
some_throwing(1337);
|
||||
return 1337;
|
||||
} catch(_, code) {
|
||||
return code;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
global int g_reg;
|
||||
|
||||
(int, int) test107() method_id(107) {
|
||||
int l_reg = 10;
|
||||
g_reg = 10;
|
||||
try {
|
||||
;; note, that regardless of assignment, an exception RESTORES them to previous (to 10)
|
||||
;; it's very unexpected, but is considered to be a TVM feature, not a bug
|
||||
g_reg = 999;
|
||||
l_reg = 999;
|
||||
some_throwing(999);
|
||||
} catch(_, _) {
|
||||
}
|
||||
;; returns (10,10) because of an exception, see a comment above
|
||||
return (g_reg, l_reg);
|
||||
}
|
||||
|
||||
() main() {
|
||||
}
|
||||
|
||||
{-
|
||||
method_id | in | out
|
||||
TESTCASE | 1 | 1 2 3 | 123
|
||||
TESTCASE | 1 | 3 8 9 | 389
|
||||
TESTCASE | 1 | 3 7 9 | 329
|
||||
TESTCASE | 2 | 1 2 3 | 123
|
||||
TESTCASE | 2 | 3 8 9 | 389
|
||||
TESTCASE | 2 | 3 7 9 | 329
|
||||
TESTCASE | 3 | 1 2 3 | 123
|
||||
TESTCASE | 3 | 3 8 9 | 389
|
||||
TESTCASE | 3 | 3 7 9 | 329
|
||||
TESTCASE | 4 | 4 8 9 | 4350009
|
||||
TESTCASE | 4 | 4 7 9 | 4001009
|
||||
TESTCASE | 5 | 4 8 9 | 4350009
|
||||
TESTCASE | 5 | 4 7 9 | 4001009
|
||||
method_id | in | out
|
||||
TESTCASE | 101 | 1 2 3 | 123
|
||||
TESTCASE | 101 | 3 8 9 | 389
|
||||
TESTCASE | 101 | 3 7 9 | 329
|
||||
TESTCASE | 102 | 1 2 3 | 123
|
||||
TESTCASE | 102 | 3 8 9 | 389
|
||||
TESTCASE | 102 | 3 7 9 | 329
|
||||
TESTCASE | 103 | 1 2 3 | 123
|
||||
TESTCASE | 103 | 3 8 9 | 389
|
||||
TESTCASE | 103 | 3 7 9 | 329
|
||||
TESTCASE | 104 | 4 8 9 | 4350009
|
||||
TESTCASE | 104 | 4 7 9 | 4001009
|
||||
TESTCASE | 105 | 4 8 9 | 4350009
|
||||
TESTCASE | 105 | 4 7 9 | 4001009
|
||||
TESTCASE | 106 | | 1
|
||||
TESTCASE | 107 | | 10 10
|
||||
-}
|
||||
|
|
132
crypto/func/auto-tests/tests/var-apply.fc
Normal file
132
crypto/func/auto-tests/tests/var-apply.fc
Normal file
|
@ -0,0 +1,132 @@
|
|||
tuple empty_tuple() asm "NIL";
|
||||
forall X -> (tuple, ()) ~tpush(tuple t, X value) asm "TPUSH";
|
||||
builder begin_cell() asm "NEWC";
|
||||
cell end_cell(builder b) asm "ENDC";
|
||||
slice begin_parse(cell c) asm "CTOS";
|
||||
|
||||
|
||||
_ getBeginCell() {
|
||||
return begin_cell;
|
||||
}
|
||||
|
||||
_ getBeginParse() {
|
||||
return begin_parse;
|
||||
}
|
||||
|
||||
(int, int) test101() method_id(101) {
|
||||
var (_, f_end_cell) = (0, end_cell);
|
||||
builder b = (getBeginCell())().store_int(1, 32);
|
||||
b~store_int(2, 32);
|
||||
var s = (getBeginParse())(f_end_cell(b));
|
||||
return (s~load_int(32), s~load_int(32));
|
||||
}
|
||||
|
||||
() my_throw_always() inline {
|
||||
throw(1000);
|
||||
}
|
||||
|
||||
_ get_raiser() inline {
|
||||
return my_throw_always;
|
||||
}
|
||||
|
||||
int test102() method_id(102) {
|
||||
try {
|
||||
var raiser = get_raiser();
|
||||
raiser(); ;; `some_var()` is always impure, the compiler has no considerations about its runtime value
|
||||
return 0;
|
||||
} catch (_, code) {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
int sum(int a, int b) impure inline {
|
||||
throw_unless(1000, a + b < 24);
|
||||
return a + b;
|
||||
}
|
||||
|
||||
int mul(int a, int b) impure inline {
|
||||
throw_unless(1001, a * b < 24);
|
||||
return a * b;
|
||||
}
|
||||
|
||||
int sum_pure(int a, int b) inline {
|
||||
throw_unless(1000, a + b < 24);
|
||||
return a + b;
|
||||
}
|
||||
|
||||
int mul_pure(int a, int b) inline {
|
||||
throw_unless(1001, a * b < 24);
|
||||
return a * b;
|
||||
}
|
||||
|
||||
int demo_handler(int op, int query_id, int a, int b) {
|
||||
if (op == 0xF2) {
|
||||
var func = query_id % 2 == 0 ? sum : mul;
|
||||
int result = func(a, b);
|
||||
return 0; ;; result not used, we test that func is nevertheless called
|
||||
}
|
||||
if (op == 0xF3) {
|
||||
var func = query_id % 2 == 0 ? sum_pure : mul_pure;
|
||||
int result = func(a, b);
|
||||
return 0; ;; the same for sum_pure, since `some_var()` is always impure
|
||||
}
|
||||
if (op == 0xF4) {
|
||||
var func = query_id % 2 == 0 ? sum : mul;
|
||||
int result = func(a, b);
|
||||
return result;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
tuple test103() method_id(103) {
|
||||
tuple t = empty_tuple();
|
||||
try {
|
||||
t~tpush(demo_handler(0xF2, 122, 100, 200));
|
||||
} catch(_, code) {
|
||||
t~tpush(code);
|
||||
}
|
||||
try {
|
||||
t~tpush(demo_handler(0xF4, 122, 100, 200));
|
||||
} catch(_, code) {
|
||||
t~tpush(code);
|
||||
}
|
||||
try {
|
||||
t~tpush(demo_handler(0xF3, 122, 10, 10));
|
||||
} catch(_, code) {
|
||||
t~tpush(code);
|
||||
}
|
||||
try {
|
||||
t~tpush(demo_handler(0xF3, 123, 10, 10));
|
||||
} catch(_, code) {
|
||||
t~tpush(code);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
() always_throw2(int x) impure {
|
||||
throw (239 + x);
|
||||
}
|
||||
|
||||
global int -> () global_f;
|
||||
|
||||
int test104() method_id(104) {
|
||||
try {
|
||||
global_f = always_throw2;
|
||||
global_f(1);
|
||||
return 0;
|
||||
} catch (_, code) {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
() main() {
|
||||
}
|
||||
|
||||
|
||||
{-
|
||||
method_id | in | out
|
||||
TESTCASE | 101 | | 1 2
|
||||
TESTCASE | 102 | | 1000
|
||||
TESTCASE | 103 | | [ 1000 1000 0 1001 ]
|
||||
TESTCASE | 104 | | 240
|
||||
-}
|
|
@ -830,6 +830,8 @@ bool Op::generate_code_step(Stack& stack) {
|
|||
catch_stack.push_new_var(left[1]);
|
||||
stack.rearrange_top(catch_vars, catch_last);
|
||||
stack.opt_show();
|
||||
stack.o << "c1 PUSH";
|
||||
stack.o << "c3 PUSH";
|
||||
stack.o << "c4 PUSH";
|
||||
stack.o << "c5 PUSH";
|
||||
stack.o << "c7 PUSH";
|
||||
|
@ -846,6 +848,8 @@ bool Op::generate_code_step(Stack& stack) {
|
|||
stack.o << "c7 SETCONT";
|
||||
stack.o << "c5 SETCONT";
|
||||
stack.o << "c4 SETCONT";
|
||||
stack.o << "c3 SETCONT";
|
||||
stack.o << "c1 SETCONT";
|
||||
for (size_t begin = catch_vars.size(), end = begin; end > 0; end = begin) {
|
||||
begin = end >= block_size ? end - block_size : 0;
|
||||
stack.o << std::to_string(end - begin) + " PUSHINT";
|
||||
|
|
|
@ -45,7 +45,7 @@ extern std::string generated_from;
|
|||
|
||||
constexpr int optimize_depth = 20;
|
||||
|
||||
const std::string func_version{"0.4.5"};
|
||||
const std::string func_version{"0.4.6"};
|
||||
|
||||
enum Keyword {
|
||||
_Eof = -1,
|
||||
|
|
|
@ -380,7 +380,10 @@ std::vector<var_idx_t> Expr::pre_compile(CodeBlob& code, std::vector<std::pair<S
|
|||
}
|
||||
res.push_back(tfunc[0]);
|
||||
auto rvect = new_tmp_vect(code);
|
||||
code.emplace_back(here, Op::_CallInd, rvect, std::move(res));
|
||||
auto& op = code.emplace_back(here, Op::_CallInd, rvect, std::move(res));
|
||||
if (flags & _IsImpure) {
|
||||
op.flags |= Op::_Impure;
|
||||
}
|
||||
return rvect;
|
||||
}
|
||||
case _Const: {
|
||||
|
|
|
@ -427,7 +427,7 @@ Expr* make_func_apply(Expr* fun, Expr* x) {
|
|||
res->flags = Expr::_IsRvalue | (fun->flags & Expr::_IsImpure);
|
||||
} else {
|
||||
res = new Expr{Expr::_VarApply, {fun, x}};
|
||||
res->flags = Expr::_IsRvalue;
|
||||
res->flags = Expr::_IsRvalue | Expr::_IsImpure; // for `some_var()`, don't make any considerations about runtime value, it's impure
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -167,3 +167,7 @@ TEST(Fift, test_bls_ops) {
|
|||
TEST(Fift, test_levels) {
|
||||
run_fift("levels.fif");
|
||||
}
|
||||
|
||||
TEST(Fift, test_secp256k1) {
|
||||
run_fift("secp256k1.fif");
|
||||
}
|
||||
|
|
82
crypto/test/fift/secp256k1.fif
Normal file
82
crypto/test/fift/secp256k1.fif
Normal file
|
@ -0,0 +1,82 @@
|
|||
"Asm.fif" include
|
||||
"FiftExt.fif" include
|
||||
|
||||
{
|
||||
=: expected_result
|
||||
=: tweak
|
||||
=: pubkey
|
||||
B{e80fe1639c9ca050e3af1b39c143c63e429cbceb15d940fbb5c5a1f4af57c5e9e80fe1639c9ca050e3af1b39c143c63e429cbceb15d940fbb5c5a1f4af57c5e9}
|
||||
@' pubkey 256 u>B @' tweak 256 u>B B+ B+ Bhashu =: tweak2
|
||||
@' pubkey @' tweak2
|
||||
[[ <{ SECP256K1_XONLY_PUBKEY_TWEAK_ADD }>s ]] 0 runvmx
|
||||
abort"exitcode != 0" -1 <> abort"xonly_pubkey_tweak_add failed"
|
||||
drop
|
||||
=: result
|
||||
."Pubkey = " @' pubkey x. cr
|
||||
."Tweak = " @' tweak x. cr
|
||||
."Tweak2 = " @' tweak2 x. cr
|
||||
@' expected_result @' result <> { ."Expected = " @' expected_result x. cr ."Found = " @' result x. cr -1 abort"result mismatch" } if
|
||||
."Result = " @' result x. cr
|
||||
4 <> abort"first byte is expected to be 4"
|
||||
cr
|
||||
} : run-test
|
||||
|
||||
0x4be5f2020ebe2f37b65fb1bcd8aecf2ab0a333427208a5e6dd3dc691f1fb6ae2
|
||||
0x7eeda5cc8b219363ffc29a77d170f923dbb939ea5164b71db862d4a192f2680f
|
||||
0x5a001d32f9fc59c2965ef36d9ff154469a3ba87f00b95879f3b5198bb557494d
|
||||
run-test
|
||||
|
||||
0x3ad84c3844e66aa255a121ed46d0e69e7b98f31233941c5197917c97c7aeaec5
|
||||
0x3f339347d8b1dde7edade3dc59fc63d18cb21fc2326ffbd30f0711a02d25075a
|
||||
0xc621ca417b8915474020c0c9471a13918b6a02fd20d48a0e526c896923457fcd
|
||||
run-test
|
||||
|
||||
0x57bb69f0d446ee2cf9f77a2bdca7a3a462a61d85997a1154f2321a2717951b02
|
||||
0x3197d6b03d78ebbe694d2b89945a21a5a671ca78393481d44739b7351767adef
|
||||
0xcbf0da3bbb498fd575506060d04db426164cb9d1477f07481fc6e3a2f84b01ea
|
||||
run-test
|
||||
|
||||
0x4af537be1a1ae11770eef23e6087f83ce1019fbee7a5876837107f84929a1d19
|
||||
0xcf9bfedc7251c2f8e233ae1e2c8b7a6cbe25d96a46a38b79e45d5684d026b64c
|
||||
0x19b1aa4551bf08363b2533c146c02fa61e26941336aaa16cdd4393a5440392ea
|
||||
run-test
|
||||
|
||||
0x4be5f2020ebe2f37b65fb1bcd8aecf2ab0a333427208a5e6dd3dc691f1fb6ae2
|
||||
0x1762cbfa935318fb1395b50c64f961baab3ecaed4afad3068ba2f7f3a9d15cec
|
||||
0x38be4b9791c0cb4952b9fb944eb0fe9256ce0d48be7b92129caafdf2f521248a
|
||||
run-test
|
||||
|
||||
0x3ad84c3844e66aa255a121ed46d0e69e7b98f31233941c5197917c97c7aeaec5
|
||||
0x099ec2e6ee1c40f533a61abca2860733727204c2f31d078297194d5e93e148f7
|
||||
0x8e9d15851e9aeb652216378f6bc0b88fb66b491697c9b9588f37c11d0b0fbced
|
||||
run-test
|
||||
|
||||
0x57bb69f0d446ee2cf9f77a2bdca7a3a462a61d85997a1154f2321a2717951b02
|
||||
0x63494cee8217ca2a10076e2031534fdda39f132dbdf91606aa65021709cb3116
|
||||
0x5dd1aa62a438469f4934e1ab9ada9ba3945651a2641316ec91d0780ca71891f8
|
||||
run-test
|
||||
|
||||
0x4af537be1a1ae11770eef23e6087f83ce1019fbee7a5876837107f84929a1d19
|
||||
0x36e26133dc62474040eae511ce89610dae6bb0359aa80738baf812ecfa03d2a1
|
||||
0xf9ab8bbbee0ad1e90492c952b362d43d56412debdd1224e9729dc79aff931943
|
||||
run-test
|
||||
|
||||
0x4be5f2020ebe2f37b65fb1bcd8aecf2ab0a333427208a5e6dd3dc691f1fb6ae2
|
||||
0x94f8fb43dd6001bb8acd2c53d094f9c919766dad596498d3d582cebdb39c63da
|
||||
0xf7b4c76d79925f62e7969cb0e4af0673808f646add78563f711dc33a2687dc1b
|
||||
run-test
|
||||
|
||||
0x3ad84c3844e66aa255a121ed46d0e69e7b98f31233941c5197917c97c7aeaec5
|
||||
0xa2f55c34c4eee5881584714bd5c7a63c397ef38ff1afedd04ada10fdeb541cef
|
||||
0x73f9a15b76612ca4254e6c2758508589c0112eb724f42dbb4c65ff8b025d2103
|
||||
run-test
|
||||
|
||||
0x57bb69f0d446ee2cf9f77a2bdca7a3a462a61d85997a1154f2321a2717951b02
|
||||
0x05130a68853e5e4aff579fa21ff10010410a3be47b94d908e203f69ec9dc7d00
|
||||
0x4ce6b5b1bd77b1666d33a0c9fd37b98952078bcc451d6de2d0bff65e8f2b46ed
|
||||
run-test
|
||||
|
||||
0x4af537be1a1ae11770eef23e6087f83ce1019fbee7a5876837107f84929a1d19
|
||||
0x9765369cb4467bebc8a468d44aa60f0154f04ee32fbcf1c8bdf646d4840163d1
|
||||
0x118953c642b8f25fea3519bcaab3ae6cea25402088e11a8efdc2e0bd222958ad
|
||||
run-test
|
|
@ -923,6 +923,41 @@ int exec_setcont_ctr_var(VmState* st) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int exec_setcont_ctr_many(VmState* st, unsigned args) {
|
||||
unsigned mask = args & 255;
|
||||
VM_LOG(st) << "execute SETCONTCTRMANY " << mask;
|
||||
if (mask & (1 << 6)) {
|
||||
throw VmError{Excno::range_chk, "no control register c6"};
|
||||
}
|
||||
Stack& stack = st->get_stack();
|
||||
auto cont = stack.pop_cont();
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (mask & (1 << i)) {
|
||||
throw_typechk(force_cregs(cont)->define(i, st->get(i)));
|
||||
}
|
||||
}
|
||||
st->get_stack().push_cont(std::move(cont));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exec_setcont_ctr_many_var(VmState* st) {
|
||||
VM_LOG(st) << "execute SETCONTCTRMANYX";
|
||||
Stack& stack = st->get_stack();
|
||||
stack.check_underflow(2);
|
||||
int mask = stack.pop_smallint_range(255);
|
||||
if (mask & (1 << 6)) {
|
||||
throw VmError{Excno::range_chk, "no control register c6"};
|
||||
}
|
||||
auto cont = stack.pop_cont();
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (mask & (1 << i)) {
|
||||
throw_typechk(force_cregs(cont)->define(i, st->get(i)));
|
||||
}
|
||||
}
|
||||
st->get_stack().push_cont(std::move(cont));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exec_compos(VmState* st, unsigned mask, const char* name) {
|
||||
Stack& stack = st->get_stack();
|
||||
VM_LOG(st) << "execute " << name;
|
||||
|
@ -1037,6 +1072,8 @@ void register_continuation_change_ops(OpcodeTable& cp0) {
|
|||
cp0.insert(OpcodeInstr::mksimple(0xede0, 16, "PUSHCTRX", exec_push_ctr_var))
|
||||
.insert(OpcodeInstr::mksimple(0xede1, 16, "POPCTRX", exec_pop_ctr_var))
|
||||
.insert(OpcodeInstr::mksimple(0xede2, 16, "SETCONTCTRX", exec_setcont_ctr_var))
|
||||
.insert(OpcodeInstr::mkfixed(0xede3, 16, 8, instr::dump_1c_l_add(1, "SETCONTCTRMANY "), exec_setcont_ctr_many)->require_version(9))
|
||||
.insert(OpcodeInstr::mksimple(0xede4, 16, "SETCONTCTRMANYX", exec_setcont_ctr_many_var)->require_version(9))
|
||||
.insert(OpcodeInstr::mksimple(0xedf0, 16, "BOOLAND", std::bind(exec_compos, _1, 1, "BOOLAND")))
|
||||
.insert(OpcodeInstr::mksimple(0xedf1, 16, "BOOLOR", std::bind(exec_compos, _1, 2, "BOOLOR")))
|
||||
.insert(OpcodeInstr::mksimple(0xedf2, 16, "COMPOSBOTH", std::bind(exec_compos, _1, 3, "COMPOSBOTH")))
|
||||
|
|
|
@ -111,14 +111,16 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat
|
|||
}
|
||||
void load_cell_async(td::Slice hash, std::shared_ptr<AsyncExecutor> executor,
|
||||
td::Promise<Ref<DataCell>> promise) override {
|
||||
auto promise_ptr = std::make_shared<td::Promise<Ref<DataCell>>>(std::move(promise));
|
||||
auto info = hash_table_.get_if_exists(hash);
|
||||
if (info && info->sync_with_db) {
|
||||
TRY_RESULT_PROMISE(promise, loaded_cell, info->cell->load_cell());
|
||||
promise.set_result(loaded_cell.data_cell);
|
||||
executor->execute_async([promise = std::move(promise_ptr), cell = info->cell]() mutable {
|
||||
TRY_RESULT_PROMISE((*promise), loaded_cell, cell->load_cell());
|
||||
promise->set_result(loaded_cell.data_cell);
|
||||
});
|
||||
return;
|
||||
}
|
||||
SimpleExtCellCreator ext_cell_creator(cell_db_reader_);
|
||||
auto promise_ptr = std::make_shared<td::Promise<Ref<DataCell>>>(std::move(promise));
|
||||
executor->execute_async(
|
||||
[executor, loader = *loader_, hash = CellHash::from_slice(hash), db = this,
|
||||
ext_cell_creator = std::move(ext_cell_creator), promise = std::move(promise_ptr)]() mutable {
|
||||
|
|
|
@ -661,7 +661,38 @@ int exec_ecrecover(VmState* st) {
|
|||
}
|
||||
st->consume_gas(VmState::ecrecover_gas_price);
|
||||
unsigned char public_key[65];
|
||||
if (td::ecrecover(hash_bytes, signature, public_key)) {
|
||||
if (td::secp256k1::ecrecover(hash_bytes, signature, public_key)) {
|
||||
td::uint8 h = public_key[0];
|
||||
td::RefInt256 x1{true}, x2{true};
|
||||
CHECK(x1.write().import_bytes(public_key + 1, 32, false));
|
||||
CHECK(x2.write().import_bytes(public_key + 33, 32, false));
|
||||
stack.push_smallint(h);
|
||||
stack.push_int(std::move(x1));
|
||||
stack.push_int(std::move(x2));
|
||||
stack.push_bool(true);
|
||||
} else {
|
||||
stack.push_bool(false);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exec_secp256k1_xonly_pubkey_tweak_add(VmState* st) {
|
||||
VM_LOG(st) << "execute SECP256K1_XONLY_PUBKEY_TWEAK_ADD";
|
||||
Stack& stack = st->get_stack();
|
||||
stack.check_underflow(2);
|
||||
auto tweak_int = stack.pop_int();
|
||||
auto key_int = stack.pop_int();
|
||||
|
||||
unsigned char key[32], tweak[32];
|
||||
if (!key_int->export_bytes(key, 32, false)) {
|
||||
throw VmError{Excno::range_chk, "key must fit in an unsigned 256-bit integer"};
|
||||
}
|
||||
if (!tweak_int->export_bytes(tweak, 32, false)) {
|
||||
throw VmError{Excno::range_chk, "tweak must fit in an unsigned 256-bit integer"};
|
||||
}
|
||||
st->consume_gas(VmState::secp256k1_xonly_pubkey_tweak_add_gas_price);
|
||||
unsigned char public_key[65];
|
||||
if (td::secp256k1::xonly_pubkey_tweak_add(key, tweak, public_key)) {
|
||||
td::uint8 h = public_key[0];
|
||||
td::RefInt256 x1{true}, x2{true};
|
||||
CHECK(x1.write().import_bytes(public_key + 1, 32, false));
|
||||
|
@ -1214,6 +1245,7 @@ void register_ton_crypto_ops(OpcodeTable& cp0) {
|
|||
.insert(OpcodeInstr::mksimple(0xf910, 16, "CHKSIGNU", std::bind(exec_ed25519_check_signature, _1, false)))
|
||||
.insert(OpcodeInstr::mksimple(0xf911, 16, "CHKSIGNS", std::bind(exec_ed25519_check_signature, _1, true)))
|
||||
.insert(OpcodeInstr::mksimple(0xf912, 16, "ECRECOVER", exec_ecrecover)->require_version(4))
|
||||
.insert(OpcodeInstr::mksimple(0xf913, 16, "SECP256K1_XONLY_PUBKEY_TWEAK_ADD", exec_secp256k1_xonly_pubkey_tweak_add)->require_version(9))
|
||||
.insert(OpcodeInstr::mksimple(0xf914, 16, "P256_CHKSIGNU", std::bind(exec_p256_chksign, _1, false))->require_version(4))
|
||||
.insert(OpcodeInstr::mksimple(0xf915, 16, "P256_CHKSIGNS", std::bind(exec_p256_chksign, _1, true))->require_version(4))
|
||||
|
||||
|
|
|
@ -127,6 +127,7 @@ class VmState final : public VmStateInterface {
|
|||
rist255_validate_gas_price = 200,
|
||||
|
||||
ecrecover_gas_price = 1500,
|
||||
secp256k1_xonly_pubkey_tweak_add_gas_price = 1250,
|
||||
chksgn_free_count = 10,
|
||||
chksgn_gas_price = 4000,
|
||||
p256_chksgn_gas_price = 3500,
|
||||
|
|
|
@ -54,7 +54,7 @@ Config::Config() {
|
|||
out_port = 3278;
|
||||
}
|
||||
|
||||
Config::Config(ton::ton_api::engine_validator_config &config) {
|
||||
Config::Config(const ton::ton_api::engine_validator_config &config) {
|
||||
out_port = static_cast<td::uint16>(config.out_port_);
|
||||
if (!out_port) {
|
||||
out_port = 3278;
|
||||
|
@ -162,6 +162,7 @@ ton::tl_object_ptr<ton::ton_api::engine_validator_config> Config::tl() const {
|
|||
control_vec.push_back(ton::create_tl_object<ton::ton_api::engine_controlInterface>(x.second.key.tl(), x.first,
|
||||
std::move(control_proc_vec)));
|
||||
}
|
||||
std::vector<ton::tl_object_ptr<ton::ton_api::tonNode_shardId>> shard_vec;
|
||||
|
||||
auto gc_vec = ton::create_tl_object<ton::ton_api::engine_gc>(std::vector<td::Bits256>{});
|
||||
for (auto &id : gc) {
|
||||
|
@ -170,7 +171,7 @@ ton::tl_object_ptr<ton::ton_api::engine_validator_config> Config::tl() const {
|
|||
return ton::create_tl_object<ton::ton_api::engine_validator_config>(
|
||||
out_port, std::move(addrs_vec), std::move(adnl_vec), std::move(dht_vec), std::move(val_vec),
|
||||
ton::PublicKeyHash::zero().tl(), std::move(full_node_slaves_vec), std::move(full_node_masters_vec),
|
||||
nullptr, nullptr, std::move(liteserver_vec), std::move(control_vec), std::move(gc_vec));
|
||||
nullptr, nullptr, std::move(liteserver_vec), std::move(control_vec), std::move(shard_vec), std::move(gc_vec));
|
||||
}
|
||||
|
||||
td::Result<bool> Config::config_add_network_addr(td::IPAddress in_ip, td::IPAddress out_ip,
|
||||
|
|
|
@ -94,7 +94,7 @@ struct Config {
|
|||
ton::tl_object_ptr<ton::ton_api::engine_validator_config> tl() const;
|
||||
|
||||
Config();
|
||||
Config(ton::ton_api::engine_validator_config &config);
|
||||
Config(const ton::ton_api::engine_validator_config &config);
|
||||
};
|
||||
|
||||
class DhtServer : public td::actor::Actor {
|
||||
|
|
|
@ -113,6 +113,13 @@ Operations for working with Merkle proofs, where cells can have non-zero level a
|
|||
|
||||
## Version 9
|
||||
|
||||
### New TVM instructions
|
||||
- `SECP256K1_XONLY_PUBKEY_TWEAK_ADD` (`key tweak - 0 or f x y -1`) - performs [`secp256k1_xonly_pubkey_tweak_add`](https://github.com/bitcoin-core/secp256k1/blob/master/include/secp256k1_extrakeys.h#L120).
|
||||
`key` and `tweak` are 256-bit unsigned integers. 65-byte public key is returned as `uint8 f`, `uint256 x, y` (as in `ECRECOVER`). Gas cost: `1276`.
|
||||
- `mask SETCONTCTRMANY` (`cont - cont'`) - takes continuation, performs the equivalent of `c[i] PUSHCTR SWAP c[i] SETCONTCNR` for each `i` that is set in `mask` (mask is in `0..255`).
|
||||
- `SETCONTCTRMANYX` (`cont mask - cont'`) - same as `SETCONTCTRMANY`, but takes `mask` from stack.
|
||||
|
||||
### Other changes
|
||||
- Fix `RAWRESERVE` action with flag `4` (use original balance of the account) by explicitly setting `original_balance` to `balance - msg_balance_remaining`.
|
||||
- Previously it did not work if storage fee was greater than the original balance.
|
||||
- Jumps to nested continuations of depth more than 8 consume 1 gas for eact subsequent continuation (this does not affect most of TVM code).
|
|
@ -47,8 +47,8 @@ endif()
|
|||
if (USE_EMSCRIPTEN)
|
||||
add_executable(emulator-emscripten ${EMULATOR_EMSCRIPTEN_SOURCE})
|
||||
target_link_libraries(emulator-emscripten PUBLIC emulator)
|
||||
target_link_options(emulator-emscripten PRIVATE -sEXPORTED_RUNTIME_METHODS=_malloc,free,UTF8ToString,stringToUTF8,allocate,ALLOC_NORMAL,lengthBytesUTF8)
|
||||
target_link_options(emulator-emscripten PRIVATE -sEXPORTED_FUNCTIONS=_emulate,_free,_run_get_method,_create_emulator,_destroy_emulator,_emulate_with_emulator,_version)
|
||||
target_link_options(emulator-emscripten PRIVATE -sEXPORTED_RUNTIME_METHODS=UTF8ToString,stringToUTF8,allocate,ALLOC_NORMAL,lengthBytesUTF8)
|
||||
target_link_options(emulator-emscripten PRIVATE -sEXPORTED_FUNCTIONS=_emulate,_free,_malloc,_run_get_method,_create_emulator,_destroy_emulator,_emulate_with_emulator,_version)
|
||||
target_link_options(emulator-emscripten PRIVATE -sEXPORT_NAME=EmulatorModule)
|
||||
target_link_options(emulator-emscripten PRIVATE -sERROR_ON_UNDEFINED_SYMBOLS=0)
|
||||
target_link_options(emulator-emscripten PRIVATE -Oz)
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
# Sets the minimum version of CMake required to build the native library.
|
||||
|
||||
cmake_minimum_required(VERSION 3.4.1 FATAL_ERROR)
|
||||
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
|
||||
|
||||
project(TON_ANDROID VERSION 0.5 LANGUAGES C CXX)
|
||||
|
||||
option(TONLIB_ENABLE_JNI "Enable JNI-compatible TonLib API" ON)
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ mkdir -p build-$ARCH
|
|||
cd build-$ARCH
|
||||
|
||||
cmake .. -GNinja \
|
||||
-DPORTABLE=1 \
|
||||
-DTON_ONLY_TONLIB=ON \
|
||||
-DTON_ARCH="" \
|
||||
-DANDROID_ABI=x86 \
|
||||
|
@ -58,12 +57,12 @@ cmake .. -GNinja \
|
|||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DANDROID_ABI=${ABI} \
|
||||
-DOPENSSL_ROOT_DIR=${OPENSSL_DIR}/${ORIG_ARCH} \
|
||||
-DSECP256K1_FOUND=1 \
|
||||
-DSECP256K1_INCLUDE_DIR=${SECP256K1_INCLUDE_DIR} \
|
||||
-DSECP256K1_LIBRARY=${SECP256K1_LIBRARY} \
|
||||
-DLZ4_FOUND=1 \
|
||||
-DLZ4_INCLUDE_DIRS=${LZ4_INCLUDE_DIR} \
|
||||
-DLZ4_LIBRARIES=${LZ4_LIBRARY} \
|
||||
-DSODIUM_FOUND=1 \
|
||||
-DSODIUM_INCLUDE_DIR=${SODIUM_INCLUDE_DIR} \
|
||||
-DSODIUM_LIBRARY_RELEASE=${SODIUM_LIBRARY_RELEASE} \
|
||||
-DSODIUM_USE_STATIC_LIBS=1 \
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
30
example/android/third_party/secp256k1/build.sh
vendored
Normal file → Executable file
30
example/android/third_party/secp256k1/build.sh
vendored
Normal file → Executable file
|
@ -5,28 +5,32 @@ export CC=
|
|||
export CXX=
|
||||
|
||||
rm -rf secp256k1
|
||||
git clone https://github.com/libbitcoin/secp256k1.git
|
||||
git clone https://github.com/bitcoin-core/secp256k1
|
||||
|
||||
cd secp256k1
|
||||
git checkout v0.3.2
|
||||
|
||||
./autogen.sh
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
./configure --enable-module-recovery --enable-experimental --with-asm=arm --host=arm-linux-androideabi CC=armv7a-linux-androideabi21-clang CFLAGS="-mthumb -march=armv7-a" CCASFLAGS="-Wa,-mthumb -Wa,-march=armv7-a"
|
||||
cmake .. -DSECP256K1_ENABLE_MODULE_RECOVERY=ON -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake" -DANDROID_ABI=armeabi-v7a -DANDROID_PLATFORM=21 -DBUILD_SHARED_LIBS=OFF -DANDROID_TOOLCHAIN_NAME=arm-linux-androideabi
|
||||
make
|
||||
cp .libs/libsecp256k1.a ../armv7/
|
||||
cp .libs/libsecp256k1.so ../armv7/
|
||||
cp lib/libsecp256k1.a ../../armv7/
|
||||
rm -rf *
|
||||
|
||||
./configure --enable-module-recovery --host=aarch64-linux-android CC=aarch64-linux-android21-clang CFLAGS="-mthumb -march=armv8-a" CCASFLAGS="-Wa,-mthumb -Wa,-march=armv8-a"
|
||||
cmake .. -DSECP256K1_ENABLE_MODULE_RECOVERY=ON -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake" -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=21 -DBUILD_SHARED_LIBS=OFF -DANDROID_TOOLCHAIN_NAME=aarch64-linux-android
|
||||
make
|
||||
cp .libs/libsecp256k1.a ../armv8/
|
||||
cp .libs/libsecp256k1.so ../armv8/
|
||||
cp lib/libsecp256k1.a ../../armv8/
|
||||
rm -rf *
|
||||
|
||||
./configure --enable-module-recovery --host=x86_64-linux-android CC=x86_64-linux-android21-clang
|
||||
cmake .. -DSECP256K1_ENABLE_MODULE_RECOVERY=ON -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake" -DANDROID_ABI=x86_64 -DANDROID_PLATFORM=21 -DBUILD_SHARED_LIBS=OFF -DANDROID_TOOLCHAIN_NAME=x86_64
|
||||
make
|
||||
cp .libs/libsecp256k1.a ../x86-64/
|
||||
cp .libs/libsecp256k1.so ../x86-64/
|
||||
cp lib/libsecp256k1.a ../../x86-64/
|
||||
rm -rf *
|
||||
|
||||
./configure --enable-module-recovery --host=i686-linux-android CC=i686-linux-android21-clang
|
||||
cmake .. -DSECP256K1_ENABLE_MODULE_RECOVERY=ON -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake" -DANDROID_ABI= -DANDROID_PLATFORM=21 -DBUILD_SHARED_LIBS=OFF -DANDROID_TOOLCHAIN_NAME=x86-
|
||||
make
|
||||
cp .libs/libsecp256k1.a ../i686/
|
||||
cp .libs/libsecp256k1.so ../i686/
|
||||
cp lib/libsecp256k1.a ../../i686/
|
||||
rm -rf *
|
||||
rm -rf ../secp256k1
|
||||
|
|
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load diff
|
@ -7,43 +7,51 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** A pointer to a function that applies hash function to a point
|
||||
/** A pointer to a function that hashes an EC point to obtain an ECDH secret
|
||||
*
|
||||
* Returns: 1 if a point was successfully hashed. 0 will cause ecdh to fail
|
||||
* Out: output: pointer to an array to be filled by the function
|
||||
* In: x: pointer to a 32-byte x coordinate
|
||||
* y: pointer to a 32-byte y coordinate
|
||||
* data: Arbitrary data pointer that is passed through
|
||||
* Returns: 1 if the point was successfully hashed.
|
||||
* 0 will cause secp256k1_ecdh to fail and return 0.
|
||||
* Other return values are not allowed, and the behaviour of
|
||||
* secp256k1_ecdh is undefined for other return values.
|
||||
* Out: output: pointer to an array to be filled by the function
|
||||
* In: x32: pointer to a 32-byte x coordinate
|
||||
* y32: pointer to a 32-byte y coordinate
|
||||
* data: arbitrary data pointer that is passed through
|
||||
*/
|
||||
typedef int (*secp256k1_ecdh_hash_function)(
|
||||
unsigned char *output,
|
||||
const unsigned char *x,
|
||||
const unsigned char *y,
|
||||
const unsigned char *x32,
|
||||
const unsigned char *y32,
|
||||
void *data
|
||||
);
|
||||
|
||||
/** An implementation of SHA256 hash function that applies to compressed public key. */
|
||||
SECP256K1_API extern const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256;
|
||||
/** An implementation of SHA256 hash function that applies to compressed public key.
|
||||
* Populates the output parameter with 32 bytes. */
|
||||
SECP256K1_API const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256;
|
||||
|
||||
/** A default ecdh hash function (currently equal to secp256k1_ecdh_hash_function_sha256). */
|
||||
SECP256K1_API extern const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default;
|
||||
/** A default ECDH hash function (currently equal to secp256k1_ecdh_hash_function_sha256).
|
||||
* Populates the output parameter with 32 bytes. */
|
||||
SECP256K1_API const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default;
|
||||
|
||||
/** Compute an EC Diffie-Hellman secret in constant time
|
||||
*
|
||||
* Returns: 1: exponentiation was successful
|
||||
* 0: scalar was invalid (zero or overflow)
|
||||
* Args: ctx: pointer to a context object (cannot be NULL)
|
||||
* Out: output: pointer to an array to be filled by the function
|
||||
* In: pubkey: a pointer to a secp256k1_pubkey containing an
|
||||
* initialized public key
|
||||
* privkey: a 32-byte scalar with which to multiply the point
|
||||
* hashfp: pointer to a hash function. If NULL, secp256k1_ecdh_hash_function_sha256 is used
|
||||
* data: Arbitrary data pointer that is passed through
|
||||
* 0: scalar was invalid (zero or overflow) or hashfp returned 0
|
||||
* Args: ctx: pointer to a context object.
|
||||
* Out: output: pointer to an array to be filled by hashfp.
|
||||
* In: pubkey: pointer to a secp256k1_pubkey containing an initialized public key.
|
||||
* seckey: a 32-byte scalar with which to multiply the point.
|
||||
* hashfp: pointer to a hash function. If NULL,
|
||||
* secp256k1_ecdh_hash_function_sha256 is used
|
||||
* (in which case, 32 bytes will be written to output).
|
||||
* data: arbitrary data pointer that is passed through to hashfp
|
||||
* (can be NULL for secp256k1_ecdh_hash_function_sha256).
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *output,
|
||||
const secp256k1_pubkey *pubkey,
|
||||
const unsigned char *privkey,
|
||||
const unsigned char *seckey,
|
||||
secp256k1_ecdh_hash_function hashfp,
|
||||
void *data
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
|
200
example/android/third_party/secp256k1/include/secp256k1_ellswift.h
vendored
Normal file
200
example/android/third_party/secp256k1/include/secp256k1_ellswift.h
vendored
Normal file
|
@ -0,0 +1,200 @@
|
|||
#ifndef SECP256K1_ELLSWIFT_H
|
||||
#define SECP256K1_ELLSWIFT_H
|
||||
|
||||
#include "secp256k1.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* This module provides an implementation of ElligatorSwift as well as a
|
||||
* version of x-only ECDH using it (including compatibility with BIP324).
|
||||
*
|
||||
* ElligatorSwift is described in https://eprint.iacr.org/2022/759 by
|
||||
* Chavez-Saab, Rodriguez-Henriquez, and Tibouchi. It permits encoding
|
||||
* uniformly chosen public keys as 64-byte arrays which are indistinguishable
|
||||
* from uniformly random arrays.
|
||||
*
|
||||
* Let f be the function from pairs of field elements to point X coordinates,
|
||||
* defined as follows (all operations modulo p = 2^256 - 2^32 - 977)
|
||||
* f(u,t):
|
||||
* - Let C = 0xa2d2ba93507f1df233770c2a797962cc61f6d15da14ecd47d8d27ae1cd5f852,
|
||||
* a square root of -3.
|
||||
* - If u=0, set u=1 instead.
|
||||
* - If t=0, set t=1 instead.
|
||||
* - If u^3 + t^2 + 7 = 0, multiply t by 2.
|
||||
* - Let X = (u^3 + 7 - t^2) / (2 * t)
|
||||
* - Let Y = (X + t) / (C * u)
|
||||
* - Return the first in [u + 4 * Y^2, (-X/Y - u) / 2, (X/Y - u) / 2] that is an
|
||||
* X coordinate on the curve (at least one of them is, for any u and t).
|
||||
*
|
||||
* Then an ElligatorSwift encoding of x consists of the 32-byte big-endian
|
||||
* encodings of field elements u and t concatenated, where f(u,t) = x.
|
||||
* The encoding algorithm is described in the paper, and effectively picks a
|
||||
* uniformly random pair (u,t) among those which encode x.
|
||||
*
|
||||
* If the Y coordinate is relevant, it is given the same parity as t.
|
||||
*
|
||||
* Changes w.r.t. the paper:
|
||||
* - The u=0, t=0, and u^3+t^2+7=0 conditions result in decoding to the point
|
||||
* at infinity in the paper. Here they are remapped to finite points.
|
||||
* - The paper uses an additional encoding bit for the parity of y. Here the
|
||||
* parity of t is used (negating t does not affect the decoded x coordinate,
|
||||
* so this is possible).
|
||||
*
|
||||
* For mathematical background about the scheme, see the doc/ellswift.md file.
|
||||
*/
|
||||
|
||||
/** A pointer to a function used by secp256k1_ellswift_xdh to hash the shared X
|
||||
* coordinate along with the encoded public keys to a uniform shared secret.
|
||||
*
|
||||
* Returns: 1 if a shared secret was successfully computed.
|
||||
* 0 will cause secp256k1_ellswift_xdh to fail and return 0.
|
||||
* Other return values are not allowed, and the behaviour of
|
||||
* secp256k1_ellswift_xdh is undefined for other return values.
|
||||
* Out: output: pointer to an array to be filled by the function
|
||||
* In: x32: pointer to the 32-byte serialized X coordinate
|
||||
* of the resulting shared point (will not be NULL)
|
||||
* ell_a64: pointer to the 64-byte encoded public key of party A
|
||||
* (will not be NULL)
|
||||
* ell_b64: pointer to the 64-byte encoded public key of party B
|
||||
* (will not be NULL)
|
||||
* data: arbitrary data pointer that is passed through
|
||||
*/
|
||||
typedef int (*secp256k1_ellswift_xdh_hash_function)(
|
||||
unsigned char *output,
|
||||
const unsigned char *x32,
|
||||
const unsigned char *ell_a64,
|
||||
const unsigned char *ell_b64,
|
||||
void *data
|
||||
);
|
||||
|
||||
/** An implementation of an secp256k1_ellswift_xdh_hash_function which uses
|
||||
* SHA256(prefix64 || ell_a64 || ell_b64 || x32), where prefix64 is the 64-byte
|
||||
* array pointed to by data. */
|
||||
SECP256K1_API const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_prefix;
|
||||
|
||||
/** An implementation of an secp256k1_ellswift_xdh_hash_function compatible with
|
||||
* BIP324. It returns H_tag(ell_a64 || ell_b64 || x32), where H_tag is the
|
||||
* BIP340 tagged hash function with tag "bip324_ellswift_xonly_ecdh". Equivalent
|
||||
* to secp256k1_ellswift_xdh_hash_function_prefix with prefix64 set to
|
||||
* SHA256("bip324_ellswift_xonly_ecdh")||SHA256("bip324_ellswift_xonly_ecdh").
|
||||
* The data argument is ignored. */
|
||||
SECP256K1_API const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_bip324;
|
||||
|
||||
/** Construct a 64-byte ElligatorSwift encoding of a given pubkey.
|
||||
*
|
||||
* Returns: 1 always.
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: ell64: pointer to a 64-byte array to be filled
|
||||
* In: pubkey: pointer to a secp256k1_pubkey containing an
|
||||
* initialized public key
|
||||
* rnd32: pointer to 32 bytes of randomness
|
||||
*
|
||||
* It is recommended that rnd32 consists of 32 uniformly random bytes, not
|
||||
* known to any adversary trying to detect whether public keys are being
|
||||
* encoded, though 16 bytes of randomness (padded to an array of 32 bytes,
|
||||
* e.g., with zeros) suffice to make the result indistinguishable from
|
||||
* uniform. The randomness in rnd32 must not be a deterministic function of
|
||||
* the pubkey (it can be derived from the private key, though).
|
||||
*
|
||||
* It is not guaranteed that the computed encoding is stable across versions
|
||||
* of the library, even if all arguments to this function (including rnd32)
|
||||
* are the same.
|
||||
*
|
||||
* This function runs in variable time.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ellswift_encode(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *ell64,
|
||||
const secp256k1_pubkey *pubkey,
|
||||
const unsigned char *rnd32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Decode a 64-bytes ElligatorSwift encoded public key.
|
||||
*
|
||||
* Returns: always 1
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: pubkey: pointer to a secp256k1_pubkey that will be filled
|
||||
* In: ell64: pointer to a 64-byte array to decode
|
||||
*
|
||||
* This function runs in variable time.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ellswift_decode(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_pubkey *pubkey,
|
||||
const unsigned char *ell64
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Compute an ElligatorSwift public key for a secret key.
|
||||
*
|
||||
* Returns: 1: secret was valid, public key was stored.
|
||||
* 0: secret was invalid, try again.
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: ell64: pointer to a 64-byte array to receive the ElligatorSwift
|
||||
* public key
|
||||
* In: seckey32: pointer to a 32-byte secret key
|
||||
* auxrnd32: (optional) pointer to 32 bytes of randomness
|
||||
*
|
||||
* Constant time in seckey and auxrnd32, but not in the resulting public key.
|
||||
*
|
||||
* It is recommended that auxrnd32 contains 32 uniformly random bytes, though
|
||||
* it is optional (and does result in encodings that are indistinguishable from
|
||||
* uniform even without any auxrnd32). It differs from the (mandatory) rnd32
|
||||
* argument to secp256k1_ellswift_encode in this regard.
|
||||
*
|
||||
* This function can be used instead of calling secp256k1_ec_pubkey_create
|
||||
* followed by secp256k1_ellswift_encode. It is safer, as it uses the secret
|
||||
* key as entropy for the encoding (supplemented with auxrnd32, if provided).
|
||||
*
|
||||
* Like secp256k1_ellswift_encode, this function does not guarantee that the
|
||||
* computed encoding is stable across versions of the library, even if all
|
||||
* arguments (including auxrnd32) are the same.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ellswift_create(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *ell64,
|
||||
const unsigned char *seckey32,
|
||||
const unsigned char *auxrnd32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Given a private key, and ElligatorSwift public keys sent in both directions,
|
||||
* compute a shared secret using x-only Elliptic Curve Diffie-Hellman (ECDH).
|
||||
*
|
||||
* Returns: 1: shared secret was successfully computed
|
||||
* 0: secret was invalid or hashfp returned 0
|
||||
* Args: ctx: pointer to a context object.
|
||||
* Out: output: pointer to an array to be filled by hashfp.
|
||||
* In: ell_a64: pointer to the 64-byte encoded public key of party A
|
||||
* (will not be NULL)
|
||||
* ell_b64: pointer to the 64-byte encoded public key of party B
|
||||
* (will not be NULL)
|
||||
* seckey32: pointer to our 32-byte secret key
|
||||
* party: boolean indicating which party we are: zero if we are
|
||||
* party A, non-zero if we are party B. seckey32 must be
|
||||
* the private key corresponding to that party's ell_?64.
|
||||
* This correspondence is not checked.
|
||||
* hashfp: pointer to a hash function.
|
||||
* data: arbitrary data pointer passed through to hashfp.
|
||||
*
|
||||
* Constant time in seckey32.
|
||||
*
|
||||
* This function is more efficient than decoding the public keys, and performing
|
||||
* ECDH on them.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ellswift_xdh(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *output,
|
||||
const unsigned char *ell_a64,
|
||||
const unsigned char *ell_b64,
|
||||
const unsigned char *seckey32,
|
||||
int party,
|
||||
secp256k1_ellswift_xdh_hash_function hashfp,
|
||||
void *data
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(7);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SECP256K1_ELLSWIFT_H */
|
250
example/android/third_party/secp256k1/include/secp256k1_extrakeys.h
vendored
Normal file
250
example/android/third_party/secp256k1/include/secp256k1_extrakeys.h
vendored
Normal file
|
@ -0,0 +1,250 @@
|
|||
#ifndef SECP256K1_EXTRAKEYS_H
|
||||
#define SECP256K1_EXTRAKEYS_H
|
||||
|
||||
#include "secp256k1.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Opaque data structure that holds a parsed and valid "x-only" public key.
|
||||
* An x-only pubkey encodes a point whose Y coordinate is even. It is
|
||||
* serialized using only its X coordinate (32 bytes). See BIP-340 for more
|
||||
* information about x-only pubkeys.
|
||||
*
|
||||
* The exact representation of data inside is implementation defined and not
|
||||
* guaranteed to be portable between different platforms or versions. It is
|
||||
* however guaranteed to be 64 bytes in size, and can be safely copied/moved.
|
||||
* If you need to convert to a format suitable for storage, transmission, use
|
||||
* use secp256k1_xonly_pubkey_serialize and secp256k1_xonly_pubkey_parse. To
|
||||
* compare keys, use secp256k1_xonly_pubkey_cmp.
|
||||
*/
|
||||
typedef struct secp256k1_xonly_pubkey {
|
||||
unsigned char data[64];
|
||||
} secp256k1_xonly_pubkey;
|
||||
|
||||
/** Opaque data structure that holds a keypair consisting of a secret and a
|
||||
* public key.
|
||||
*
|
||||
* The exact representation of data inside is implementation defined and not
|
||||
* guaranteed to be portable between different platforms or versions. It is
|
||||
* however guaranteed to be 96 bytes in size, and can be safely copied/moved.
|
||||
*/
|
||||
typedef struct secp256k1_keypair {
|
||||
unsigned char data[96];
|
||||
} secp256k1_keypair;
|
||||
|
||||
/** Parse a 32-byte sequence into a xonly_pubkey object.
|
||||
*
|
||||
* Returns: 1 if the public key was fully valid.
|
||||
* 0 if the public key could not be parsed or is invalid.
|
||||
*
|
||||
* Args: ctx: pointer to a context object.
|
||||
* Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a
|
||||
* parsed version of input. If not, it's set to an invalid value.
|
||||
* In: input32: pointer to a serialized xonly_pubkey.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_parse(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_xonly_pubkey *pubkey,
|
||||
const unsigned char *input32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Serialize an xonly_pubkey object into a 32-byte sequence.
|
||||
*
|
||||
* Returns: 1 always.
|
||||
*
|
||||
* Args: ctx: pointer to a context object.
|
||||
* Out: output32: pointer to a 32-byte array to place the serialized key in.
|
||||
* In: pubkey: pointer to a secp256k1_xonly_pubkey containing an initialized public key.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_xonly_pubkey_serialize(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *output32,
|
||||
const secp256k1_xonly_pubkey *pubkey
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Compare two x-only public keys using lexicographic order
|
||||
*
|
||||
* Returns: <0 if the first public key is less than the second
|
||||
* >0 if the first public key is greater than the second
|
||||
* 0 if the two public keys are equal
|
||||
* Args: ctx: pointer to a context object.
|
||||
* In: pubkey1: first public key to compare
|
||||
* pubkey2: second public key to compare
|
||||
*/
|
||||
SECP256K1_API int secp256k1_xonly_pubkey_cmp(
|
||||
const secp256k1_context *ctx,
|
||||
const secp256k1_xonly_pubkey *pk1,
|
||||
const secp256k1_xonly_pubkey *pk2
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Converts a secp256k1_pubkey into a secp256k1_xonly_pubkey.
|
||||
*
|
||||
* Returns: 1 always.
|
||||
*
|
||||
* Args: ctx: pointer to a context object.
|
||||
* Out: xonly_pubkey: pointer to an x-only public key object for placing the converted public key.
|
||||
* pk_parity: Ignored if NULL. Otherwise, pointer to an integer that
|
||||
* will be set to 1 if the point encoded by xonly_pubkey is
|
||||
* the negation of the pubkey and set to 0 otherwise.
|
||||
* In: pubkey: pointer to a public key that is converted.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_from_pubkey(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_xonly_pubkey *xonly_pubkey,
|
||||
int *pk_parity,
|
||||
const secp256k1_pubkey *pubkey
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Tweak an x-only public key by adding the generator multiplied with tweak32
|
||||
* to it.
|
||||
*
|
||||
* Note that the resulting point can not in general be represented by an x-only
|
||||
* pubkey because it may have an odd Y coordinate. Instead, the output_pubkey
|
||||
* is a normal secp256k1_pubkey.
|
||||
*
|
||||
* Returns: 0 if the arguments are invalid or the resulting public key would be
|
||||
* invalid (only when the tweak is the negation of the corresponding
|
||||
* secret key). 1 otherwise.
|
||||
*
|
||||
* Args: ctx: pointer to a context object.
|
||||
* Out: output_pubkey: pointer to a public key to store the result. Will be set
|
||||
* to an invalid value if this function returns 0.
|
||||
* In: internal_pubkey: pointer to an x-only pubkey to apply the tweak to.
|
||||
* tweak32: pointer to a 32-byte tweak, which must be valid
|
||||
* according to secp256k1_ec_seckey_verify or 32 zero
|
||||
* bytes. For uniformly random 32-byte tweaks, the chance of
|
||||
* being invalid is negligible (around 1 in 2^128).
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_pubkey *output_pubkey,
|
||||
const secp256k1_xonly_pubkey *internal_pubkey,
|
||||
const unsigned char *tweak32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Checks that a tweaked pubkey is the result of calling
|
||||
* secp256k1_xonly_pubkey_tweak_add with internal_pubkey and tweak32.
|
||||
*
|
||||
* The tweaked pubkey is represented by its 32-byte x-only serialization and
|
||||
* its pk_parity, which can both be obtained by converting the result of
|
||||
* tweak_add to a secp256k1_xonly_pubkey.
|
||||
*
|
||||
* Note that this alone does _not_ verify that the tweaked pubkey is a
|
||||
* commitment. If the tweak is not chosen in a specific way, the tweaked pubkey
|
||||
* can easily be the result of a different internal_pubkey and tweak.
|
||||
*
|
||||
* Returns: 0 if the arguments are invalid or the tweaked pubkey is not the
|
||||
* result of tweaking the internal_pubkey with tweak32. 1 otherwise.
|
||||
* Args: ctx: pointer to a context object.
|
||||
* In: tweaked_pubkey32: pointer to a serialized xonly_pubkey.
|
||||
* tweaked_pk_parity: the parity of the tweaked pubkey (whose serialization
|
||||
* is passed in as tweaked_pubkey32). This must match the
|
||||
* pk_parity value that is returned when calling
|
||||
* secp256k1_xonly_pubkey with the tweaked pubkey, or
|
||||
* this function will fail.
|
||||
* internal_pubkey: pointer to an x-only public key object to apply the tweak to.
|
||||
* tweak32: pointer to a 32-byte tweak.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add_check(
|
||||
const secp256k1_context *ctx,
|
||||
const unsigned char *tweaked_pubkey32,
|
||||
int tweaked_pk_parity,
|
||||
const secp256k1_xonly_pubkey *internal_pubkey,
|
||||
const unsigned char *tweak32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
/** Compute the keypair for a valid secret key.
|
||||
*
|
||||
* See the documentation of `secp256k1_ec_seckey_verify` for more information
|
||||
* about the validity of secret keys.
|
||||
*
|
||||
* Returns: 1: secret key is valid
|
||||
* 0: secret key is invalid
|
||||
* Args: ctx: pointer to a context object (not secp256k1_context_static).
|
||||
* Out: keypair: pointer to the created keypair.
|
||||
* In: seckey: pointer to a 32-byte secret key.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_create(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_keypair *keypair,
|
||||
const unsigned char *seckey
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Get the secret key from a keypair.
|
||||
*
|
||||
* Returns: 1 always.
|
||||
* Args: ctx: pointer to a context object.
|
||||
* Out: seckey: pointer to a 32-byte buffer for the secret key.
|
||||
* In: keypair: pointer to a keypair.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_sec(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *seckey,
|
||||
const secp256k1_keypair *keypair
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Get the public key from a keypair.
|
||||
*
|
||||
* Returns: 1 always.
|
||||
* Args: ctx: pointer to a context object.
|
||||
* Out: pubkey: pointer to a pubkey object, set to the keypair public key.
|
||||
* In: keypair: pointer to a keypair.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_pub(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_pubkey *pubkey,
|
||||
const secp256k1_keypair *keypair
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Get the x-only public key from a keypair.
|
||||
*
|
||||
* This is the same as calling secp256k1_keypair_pub and then
|
||||
* secp256k1_xonly_pubkey_from_pubkey.
|
||||
*
|
||||
* Returns: 1 always.
|
||||
* Args: ctx: pointer to a context object.
|
||||
* Out: pubkey: pointer to an xonly_pubkey object, set to the keypair
|
||||
* public key after converting it to an xonly_pubkey.
|
||||
* pk_parity: Ignored if NULL. Otherwise, pointer to an integer that will be set to the
|
||||
* pk_parity argument of secp256k1_xonly_pubkey_from_pubkey.
|
||||
* In: keypair: pointer to a keypair.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_pub(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_xonly_pubkey *pubkey,
|
||||
int *pk_parity,
|
||||
const secp256k1_keypair *keypair
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Tweak a keypair by adding tweak32 to the secret key and updating the public
|
||||
* key accordingly.
|
||||
*
|
||||
* Calling this function and then secp256k1_keypair_pub results in the same
|
||||
* public key as calling secp256k1_keypair_xonly_pub and then
|
||||
* secp256k1_xonly_pubkey_tweak_add.
|
||||
*
|
||||
* Returns: 0 if the arguments are invalid or the resulting keypair would be
|
||||
* invalid (only when the tweak is the negation of the keypair's
|
||||
* secret key). 1 otherwise.
|
||||
*
|
||||
* Args: ctx: pointer to a context object.
|
||||
* In/Out: keypair: pointer to a keypair to apply the tweak to. Will be set to
|
||||
* an invalid value if this function returns 0.
|
||||
* In: tweak32: pointer to a 32-byte tweak, which must be valid according to
|
||||
* secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly
|
||||
* random 32-byte tweaks, the chance of being invalid is
|
||||
* negligible (around 1 in 2^128).
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_tweak_add(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_keypair *keypair,
|
||||
const unsigned char *tweak32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SECP256K1_EXTRAKEYS_H */
|
588
example/android/third_party/secp256k1/include/secp256k1_musig.h
vendored
Normal file
588
example/android/third_party/secp256k1/include/secp256k1_musig.h
vendored
Normal file
|
@ -0,0 +1,588 @@
|
|||
#ifndef SECP256K1_MUSIG_H
|
||||
#define SECP256K1_MUSIG_H
|
||||
|
||||
#include "secp256k1_extrakeys.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/** This module implements BIP 327 "MuSig2 for BIP340-compatible
|
||||
* Multi-Signatures"
|
||||
* (https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki)
|
||||
* v1.0.0. You can find an example demonstrating the musig module in
|
||||
* examples/musig.c.
|
||||
*
|
||||
* The module also supports BIP 341 ("Taproot") public key tweaking.
|
||||
*
|
||||
* It is recommended to read the documentation in this include file carefully.
|
||||
* Further notes on API usage can be found in doc/musig.md
|
||||
*
|
||||
* Since the first version of MuSig is essentially replaced by MuSig2, we use
|
||||
* MuSig, musig and MuSig2 synonymously unless noted otherwise.
|
||||
*/
|
||||
|
||||
/** Opaque data structures
|
||||
*
|
||||
* The exact representation of data inside the opaque data structures is
|
||||
* implementation defined and not guaranteed to be portable between different
|
||||
* platforms or versions. With the exception of `secp256k1_musig_secnonce`, the
|
||||
* data structures can be safely copied/moved. If you need to convert to a
|
||||
* format suitable for storage, transmission, or comparison, use the
|
||||
* corresponding serialization and parsing functions.
|
||||
*/
|
||||
|
||||
/** Opaque data structure that caches information about public key aggregation.
|
||||
*
|
||||
* Guaranteed to be 197 bytes in size. No serialization and parsing functions
|
||||
* (yet).
|
||||
*/
|
||||
typedef struct secp256k1_musig_keyagg_cache {
|
||||
unsigned char data[197];
|
||||
} secp256k1_musig_keyagg_cache;
|
||||
|
||||
/** Opaque data structure that holds a signer's _secret_ nonce.
|
||||
*
|
||||
* Guaranteed to be 132 bytes in size.
|
||||
*
|
||||
* WARNING: This structure MUST NOT be copied or read or written to directly. A
|
||||
* signer who is online throughout the whole process and can keep this
|
||||
* structure in memory can use the provided API functions for a safe standard
|
||||
* workflow.
|
||||
*
|
||||
* Copying this data structure can result in nonce reuse which will leak the
|
||||
* secret signing key.
|
||||
*/
|
||||
typedef struct secp256k1_musig_secnonce {
|
||||
unsigned char data[132];
|
||||
} secp256k1_musig_secnonce;
|
||||
|
||||
/** Opaque data structure that holds a signer's public nonce.
|
||||
*
|
||||
* Guaranteed to be 132 bytes in size. Serialized and parsed with
|
||||
* `musig_pubnonce_serialize` and `musig_pubnonce_parse`.
|
||||
*/
|
||||
typedef struct secp256k1_musig_pubnonce {
|
||||
unsigned char data[132];
|
||||
} secp256k1_musig_pubnonce;
|
||||
|
||||
/** Opaque data structure that holds an aggregate public nonce.
|
||||
*
|
||||
* Guaranteed to be 132 bytes in size. Serialized and parsed with
|
||||
* `musig_aggnonce_serialize` and `musig_aggnonce_parse`.
|
||||
*/
|
||||
typedef struct secp256k1_musig_aggnonce {
|
||||
unsigned char data[132];
|
||||
} secp256k1_musig_aggnonce;
|
||||
|
||||
/** Opaque data structure that holds a MuSig session.
|
||||
*
|
||||
* This structure is not required to be kept secret for the signing protocol to
|
||||
* be secure. Guaranteed to be 133 bytes in size. No serialization and parsing
|
||||
* functions (yet).
|
||||
*/
|
||||
typedef struct secp256k1_musig_session {
|
||||
unsigned char data[133];
|
||||
} secp256k1_musig_session;
|
||||
|
||||
/** Opaque data structure that holds a partial MuSig signature.
|
||||
*
|
||||
* Guaranteed to be 36 bytes in size. Serialized and parsed with
|
||||
* `musig_partial_sig_serialize` and `musig_partial_sig_parse`.
|
||||
*/
|
||||
typedef struct secp256k1_musig_partial_sig {
|
||||
unsigned char data[36];
|
||||
} secp256k1_musig_partial_sig;
|
||||
|
||||
/** Parse a signer's public nonce.
|
||||
*
|
||||
* Returns: 1 when the nonce could be parsed, 0 otherwise.
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: nonce: pointer to a nonce object
|
||||
* In: in66: pointer to the 66-byte nonce to be parsed
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubnonce_parse(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_musig_pubnonce *nonce,
|
||||
const unsigned char *in66
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Serialize a signer's public nonce
|
||||
*
|
||||
* Returns: 1 always
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: out66: pointer to a 66-byte array to store the serialized nonce
|
||||
* In: nonce: pointer to the nonce
|
||||
*/
|
||||
SECP256K1_API int secp256k1_musig_pubnonce_serialize(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *out66,
|
||||
const secp256k1_musig_pubnonce *nonce
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Parse an aggregate public nonce.
|
||||
*
|
||||
* Returns: 1 when the nonce could be parsed, 0 otherwise.
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: nonce: pointer to a nonce object
|
||||
* In: in66: pointer to the 66-byte nonce to be parsed
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_aggnonce_parse(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_musig_aggnonce *nonce,
|
||||
const unsigned char *in66
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Serialize an aggregate public nonce
|
||||
*
|
||||
* Returns: 1 always
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: out66: pointer to a 66-byte array to store the serialized nonce
|
||||
* In: nonce: pointer to the nonce
|
||||
*/
|
||||
SECP256K1_API int secp256k1_musig_aggnonce_serialize(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *out66,
|
||||
const secp256k1_musig_aggnonce *nonce
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Parse a MuSig partial signature.
|
||||
*
|
||||
* Returns: 1 when the signature could be parsed, 0 otherwise.
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: sig: pointer to a signature object
|
||||
* In: in32: pointer to the 32-byte signature to be parsed
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_parse(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_musig_partial_sig *sig,
|
||||
const unsigned char *in32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Serialize a MuSig partial signature
|
||||
*
|
||||
* Returns: 1 always
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: out32: pointer to a 32-byte array to store the serialized signature
|
||||
* In: sig: pointer to the signature
|
||||
*/
|
||||
SECP256K1_API int secp256k1_musig_partial_sig_serialize(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *out32,
|
||||
const secp256k1_musig_partial_sig *sig
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Computes an aggregate public key and uses it to initialize a keyagg_cache
|
||||
*
|
||||
* Different orders of `pubkeys` result in different `agg_pk`s.
|
||||
*
|
||||
* Before aggregating, the pubkeys can be sorted with `secp256k1_ec_pubkey_sort`
|
||||
* which ensures the same `agg_pk` result for the same multiset of pubkeys.
|
||||
* This is useful to do before `pubkey_agg`, such that the order of pubkeys
|
||||
* does not affect the aggregate public key.
|
||||
*
|
||||
* Returns: 0 if the arguments are invalid, 1 otherwise
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: agg_pk: the MuSig-aggregated x-only public key. If you do not need it,
|
||||
* this arg can be NULL.
|
||||
* keyagg_cache: if non-NULL, pointer to a musig_keyagg_cache struct that
|
||||
* is required for signing (or observing the signing session
|
||||
* and verifying partial signatures).
|
||||
* In: pubkeys: input array of pointers to public keys to aggregate. The order
|
||||
* is important; a different order will result in a different
|
||||
* aggregate public key.
|
||||
* n_pubkeys: length of pubkeys array. Must be greater than 0.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_agg(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_xonly_pubkey *agg_pk,
|
||||
secp256k1_musig_keyagg_cache *keyagg_cache,
|
||||
const secp256k1_pubkey * const *pubkeys,
|
||||
size_t n_pubkeys
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Obtain the aggregate public key from a keyagg_cache.
|
||||
*
|
||||
* This is only useful if you need the non-xonly public key, in particular for
|
||||
* plain (non-xonly) tweaking or batch-verifying multiple key aggregations
|
||||
* (not implemented).
|
||||
*
|
||||
* Returns: 0 if the arguments are invalid, 1 otherwise
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: agg_pk: the MuSig-aggregated public key.
|
||||
* In: keyagg_cache: pointer to a `musig_keyagg_cache` struct initialized by
|
||||
* `musig_pubkey_agg`
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_get(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_pubkey *agg_pk,
|
||||
const secp256k1_musig_keyagg_cache *keyagg_cache
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Apply plain "EC" tweaking to a public key in a given keyagg_cache by adding
|
||||
* the generator multiplied with `tweak32` to it. This is useful for deriving
|
||||
* child keys from an aggregate public key via BIP 32 where `tweak32` is set to
|
||||
* a hash as defined in BIP 32.
|
||||
*
|
||||
* Callers are responsible for deriving `tweak32` in a way that does not reduce
|
||||
* the security of MuSig (for example, by following BIP 32).
|
||||
*
|
||||
* The tweaking method is the same as `secp256k1_ec_pubkey_tweak_add`. So after
|
||||
* the following pseudocode buf and buf2 have identical contents (absent
|
||||
* earlier failures).
|
||||
*
|
||||
* secp256k1_musig_pubkey_agg(..., keyagg_cache, pubkeys, ...)
|
||||
* secp256k1_musig_pubkey_get(..., agg_pk, keyagg_cache)
|
||||
* secp256k1_musig_pubkey_ec_tweak_add(..., output_pk, tweak32, keyagg_cache)
|
||||
* secp256k1_ec_pubkey_serialize(..., buf, ..., output_pk, ...)
|
||||
* secp256k1_ec_pubkey_tweak_add(..., agg_pk, tweak32)
|
||||
* secp256k1_ec_pubkey_serialize(..., buf2, ..., agg_pk, ...)
|
||||
*
|
||||
* This function is required if you want to _sign_ for a tweaked aggregate key.
|
||||
* If you are only computing a public key but not intending to create a
|
||||
* signature for it, use `secp256k1_ec_pubkey_tweak_add` instead.
|
||||
*
|
||||
* Returns: 0 if the arguments are invalid, 1 otherwise
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: output_pubkey: pointer to a public key to store the result. Will be set
|
||||
* to an invalid value if this function returns 0. If you
|
||||
* do not need it, this arg can be NULL.
|
||||
* In/Out: keyagg_cache: pointer to a `musig_keyagg_cache` struct initialized by
|
||||
* `musig_pubkey_agg`
|
||||
* In: tweak32: pointer to a 32-byte tweak. The tweak is valid if it passes
|
||||
* `secp256k1_ec_seckey_verify` and is not equal to the
|
||||
* secret key corresponding to the public key represented
|
||||
* by keyagg_cache or its negation. For uniformly random
|
||||
* 32-byte arrays the chance of being invalid is
|
||||
* negligible (around 1 in 2^128).
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_ec_tweak_add(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_pubkey *output_pubkey,
|
||||
secp256k1_musig_keyagg_cache *keyagg_cache,
|
||||
const unsigned char *tweak32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Apply x-only tweaking to a public key in a given keyagg_cache by adding the
|
||||
* generator multiplied with `tweak32` to it. This is useful for creating
|
||||
* Taproot outputs where `tweak32` is set to a TapTweak hash as defined in BIP
|
||||
* 341.
|
||||
*
|
||||
* Callers are responsible for deriving `tweak32` in a way that does not reduce
|
||||
* the security of MuSig (for example, by following Taproot BIP 341).
|
||||
*
|
||||
* The tweaking method is the same as `secp256k1_xonly_pubkey_tweak_add`. So in
|
||||
* the following pseudocode xonly_pubkey_tweak_add_check (absent earlier
|
||||
* failures) returns 1.
|
||||
*
|
||||
* secp256k1_musig_pubkey_agg(..., agg_pk, keyagg_cache, pubkeys, ...)
|
||||
* secp256k1_musig_pubkey_xonly_tweak_add(..., output_pk, keyagg_cache, tweak32)
|
||||
* secp256k1_xonly_pubkey_serialize(..., buf, output_pk)
|
||||
* secp256k1_xonly_pubkey_tweak_add_check(..., buf, ..., agg_pk, tweak32)
|
||||
*
|
||||
* This function is required if you want to _sign_ for a tweaked aggregate key.
|
||||
* If you are only computing a public key but not intending to create a
|
||||
* signature for it, use `secp256k1_xonly_pubkey_tweak_add` instead.
|
||||
*
|
||||
* Returns: 0 if the arguments are invalid, 1 otherwise
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: output_pubkey: pointer to a public key to store the result. Will be set
|
||||
* to an invalid value if this function returns 0. If you
|
||||
* do not need it, this arg can be NULL.
|
||||
* In/Out: keyagg_cache: pointer to a `musig_keyagg_cache` struct initialized by
|
||||
* `musig_pubkey_agg`
|
||||
* In: tweak32: pointer to a 32-byte tweak. The tweak is valid if it passes
|
||||
* `secp256k1_ec_seckey_verify` and is not equal to the
|
||||
* secret key corresponding to the public key represented
|
||||
* by keyagg_cache or its negation. For uniformly random
|
||||
* 32-byte arrays the chance of being invalid is
|
||||
* negligible (around 1 in 2^128).
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_xonly_tweak_add(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_pubkey *output_pubkey,
|
||||
secp256k1_musig_keyagg_cache *keyagg_cache,
|
||||
const unsigned char *tweak32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Starts a signing session by generating a nonce
|
||||
*
|
||||
* This function outputs a secret nonce that will be required for signing and a
|
||||
* corresponding public nonce that is intended to be sent to other signers.
|
||||
*
|
||||
* MuSig differs from regular Schnorr signing in that implementers _must_ take
|
||||
* special care to not reuse a nonce. This can be ensured by following these rules:
|
||||
*
|
||||
* 1. Each call to this function must have a UNIQUE session_secrand32 that must
|
||||
* NOT BE REUSED in subsequent calls to this function and must be KEPT
|
||||
* SECRET (even from other signers).
|
||||
* 2. If you already know the seckey, message or aggregate public key
|
||||
* cache, they can be optionally provided to derive the nonce and increase
|
||||
* misuse-resistance. The extra_input32 argument can be used to provide
|
||||
* additional data that does not repeat in normal scenarios, such as the
|
||||
* current time.
|
||||
* 3. Avoid copying (or serializing) the secnonce. This reduces the possibility
|
||||
* that it is used more than once for signing.
|
||||
*
|
||||
* If you don't have access to good randomness for session_secrand32, but you
|
||||
* have access to a non-repeating counter, then see
|
||||
* secp256k1_musig_nonce_gen_counter.
|
||||
*
|
||||
* Remember that nonce reuse will leak the secret key!
|
||||
* Note that using the same seckey for multiple MuSig sessions is fine.
|
||||
*
|
||||
* Returns: 0 if the arguments are invalid and 1 otherwise
|
||||
* Args: ctx: pointer to a context object (not secp256k1_context_static)
|
||||
* Out: secnonce: pointer to a structure to store the secret nonce
|
||||
* pubnonce: pointer to a structure to store the public nonce
|
||||
* In/Out:
|
||||
* session_secrand32: a 32-byte session_secrand32 as explained above. Must be unique to this
|
||||
* call to secp256k1_musig_nonce_gen and must be uniformly
|
||||
* random. If the function call is successful, the
|
||||
* session_secrand32 buffer is invalidated to prevent reuse.
|
||||
* In:
|
||||
* seckey: the 32-byte secret key that will later be used for signing, if
|
||||
* already known (can be NULL)
|
||||
* pubkey: public key of the signer creating the nonce. The secnonce
|
||||
* output of this function cannot be used to sign for any
|
||||
* other public key. While the public key should correspond
|
||||
* to the provided seckey, a mismatch will not cause the
|
||||
* function to return 0.
|
||||
* msg32: the 32-byte message that will later be signed, if already known
|
||||
* (can be NULL)
|
||||
* keyagg_cache: pointer to the keyagg_cache that was used to create the aggregate
|
||||
* (and potentially tweaked) public key if already known
|
||||
* (can be NULL)
|
||||
* extra_input32: an optional 32-byte array that is input to the nonce
|
||||
* derivation function (can be NULL)
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_nonce_gen(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_musig_secnonce *secnonce,
|
||||
secp256k1_musig_pubnonce *pubnonce,
|
||||
unsigned char *session_secrand32,
|
||||
const unsigned char *seckey,
|
||||
const secp256k1_pubkey *pubkey,
|
||||
const unsigned char *msg32,
|
||||
const secp256k1_musig_keyagg_cache *keyagg_cache,
|
||||
const unsigned char *extra_input32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(6);
|
||||
|
||||
|
||||
/** Alternative way to generate a nonce and start a signing session
|
||||
*
|
||||
* This function outputs a secret nonce that will be required for signing and a
|
||||
* corresponding public nonce that is intended to be sent to other signers.
|
||||
*
|
||||
* This function differs from `secp256k1_musig_nonce_gen` by accepting a
|
||||
* non-repeating counter value instead of a secret random value. This requires
|
||||
* that a secret key is provided to `secp256k1_musig_nonce_gen_counter`
|
||||
* (through the keypair argument), as opposed to `secp256k1_musig_nonce_gen`
|
||||
* where the seckey argument is optional.
|
||||
*
|
||||
* MuSig differs from regular Schnorr signing in that implementers _must_ take
|
||||
* special care to not reuse a nonce. This can be ensured by following these rules:
|
||||
*
|
||||
* 1. The nonrepeating_cnt argument must be a counter value that never repeats,
|
||||
* i.e., you must never call `secp256k1_musig_nonce_gen_counter` twice with
|
||||
* the same keypair and nonrepeating_cnt value. For example, this implies
|
||||
* that if the same keypair is used with `secp256k1_musig_nonce_gen_counter`
|
||||
* on multiple devices, none of the devices should have the same counter
|
||||
* value as any other device.
|
||||
* 2. If the seckey, message or aggregate public key cache is already available
|
||||
* at this stage, any of these can be optionally provided, in which case
|
||||
* they will be used in the derivation of the nonce and increase
|
||||
* misuse-resistance. The extra_input32 argument can be used to provide
|
||||
* additional data that does not repeat in normal scenarios, such as the
|
||||
* current time.
|
||||
* 3. Avoid copying (or serializing) the secnonce. This reduces the possibility
|
||||
* that it is used more than once for signing.
|
||||
*
|
||||
* Remember that nonce reuse will leak the secret key!
|
||||
* Note that using the same keypair for multiple MuSig sessions is fine.
|
||||
*
|
||||
* Returns: 0 if the arguments are invalid and 1 otherwise
|
||||
* Args: ctx: pointer to a context object (not secp256k1_context_static)
|
||||
* Out: secnonce: pointer to a structure to store the secret nonce
|
||||
* pubnonce: pointer to a structure to store the public nonce
|
||||
* In:
|
||||
* nonrepeating_cnt: the value of a counter as explained above. Must be
|
||||
* unique to this call to secp256k1_musig_nonce_gen.
|
||||
* keypair: keypair of the signer creating the nonce. The secnonce
|
||||
* output of this function cannot be used to sign for any
|
||||
* other keypair.
|
||||
* msg32: the 32-byte message that will later be signed, if already known
|
||||
* (can be NULL)
|
||||
* keyagg_cache: pointer to the keyagg_cache that was used to create the aggregate
|
||||
* (and potentially tweaked) public key if already known
|
||||
* (can be NULL)
|
||||
* extra_input32: an optional 32-byte array that is input to the nonce
|
||||
* derivation function (can be NULL)
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_nonce_gen_counter(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_musig_secnonce *secnonce,
|
||||
secp256k1_musig_pubnonce *pubnonce,
|
||||
uint64_t nonrepeating_cnt,
|
||||
const secp256k1_keypair *keypair,
|
||||
const unsigned char *msg32,
|
||||
const secp256k1_musig_keyagg_cache *keyagg_cache,
|
||||
const unsigned char *extra_input32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
/** Aggregates the nonces of all signers into a single nonce
|
||||
*
|
||||
* This can be done by an untrusted party to reduce the communication
|
||||
* between signers. Instead of everyone sending nonces to everyone else, there
|
||||
* can be one party receiving all nonces, aggregating the nonces with this
|
||||
* function and then sending only the aggregate nonce back to the signers.
|
||||
*
|
||||
* If the aggregator does not compute the aggregate nonce correctly, the final
|
||||
* signature will be invalid.
|
||||
*
|
||||
* Returns: 0 if the arguments are invalid, 1 otherwise
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: aggnonce: pointer to an aggregate public nonce object for
|
||||
* musig_nonce_process
|
||||
* In: pubnonces: array of pointers to public nonces sent by the
|
||||
* signers
|
||||
* n_pubnonces: number of elements in the pubnonces array. Must be
|
||||
* greater than 0.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_musig_nonce_agg(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_musig_aggnonce *aggnonce,
|
||||
const secp256k1_musig_pubnonce * const *pubnonces,
|
||||
size_t n_pubnonces
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Takes the aggregate nonce and creates a session that is required for signing
|
||||
* and verification of partial signatures.
|
||||
*
|
||||
* Returns: 0 if the arguments are invalid, 1 otherwise
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: session: pointer to a struct to store the session
|
||||
* In: aggnonce: pointer to an aggregate public nonce object that is the
|
||||
* output of musig_nonce_agg
|
||||
* msg32: the 32-byte message to sign
|
||||
* keyagg_cache: pointer to the keyagg_cache that was used to create the
|
||||
* aggregate (and potentially tweaked) pubkey
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_nonce_process(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_musig_session *session,
|
||||
const secp256k1_musig_aggnonce *aggnonce,
|
||||
const unsigned char *msg32,
|
||||
const secp256k1_musig_keyagg_cache *keyagg_cache
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
/** Produces a partial signature
|
||||
*
|
||||
* This function overwrites the given secnonce with zeros and will abort if given a
|
||||
* secnonce that is all zeros. This is a best effort attempt to protect against nonce
|
||||
* reuse. However, this is of course easily defeated if the secnonce has been
|
||||
* copied (or serialized). Remember that nonce reuse will leak the secret key!
|
||||
*
|
||||
* For signing to succeed, the secnonce provided to this function must have
|
||||
* been generated for the provided keypair. This means that when signing for a
|
||||
* keypair consisting of a seckey and pubkey, the secnonce must have been
|
||||
* created by calling musig_nonce_gen with that pubkey. Otherwise, the
|
||||
* illegal_callback is called.
|
||||
*
|
||||
* This function does not verify the output partial signature, deviating from
|
||||
* the BIP 327 specification. It is recommended to verify the output partial
|
||||
* signature with `secp256k1_musig_partial_sig_verify` to prevent random or
|
||||
* adversarially provoked computation errors.
|
||||
*
|
||||
* Returns: 0 if the arguments are invalid or the provided secnonce has already
|
||||
* been used for signing, 1 otherwise
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: partial_sig: pointer to struct to store the partial signature
|
||||
* In/Out: secnonce: pointer to the secnonce struct created in
|
||||
* musig_nonce_gen that has been never used in a
|
||||
* partial_sign call before and has been created for the
|
||||
* keypair
|
||||
* In: keypair: pointer to keypair to sign the message with
|
||||
* keyagg_cache: pointer to the keyagg_cache that was output when the
|
||||
* aggregate public key for this session
|
||||
* session: pointer to the session that was created with
|
||||
* musig_nonce_process
|
||||
*/
|
||||
SECP256K1_API int secp256k1_musig_partial_sign(
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_musig_partial_sig *partial_sig,
|
||||
secp256k1_musig_secnonce *secnonce,
|
||||
const secp256k1_keypair *keypair,
|
||||
const secp256k1_musig_keyagg_cache *keyagg_cache,
|
||||
const secp256k1_musig_session *session
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
|
||||
|
||||
/** Verifies an individual signer's partial signature
|
||||
*
|
||||
* The signature is verified for a specific signing session. In order to avoid
|
||||
* accidentally verifying a signature from a different or non-existing signing
|
||||
* session, you must ensure the following:
|
||||
* 1. The `keyagg_cache` argument is identical to the one used to create the
|
||||
* `session` with `musig_nonce_process`.
|
||||
* 2. The `pubkey` argument must be identical to the one sent by the signer
|
||||
* before aggregating it with `musig_pubkey_agg` to create the
|
||||
* `keyagg_cache`.
|
||||
* 3. The `pubnonce` argument must be identical to the one sent by the signer
|
||||
* before aggregating it with `musig_nonce_agg` and using the result to
|
||||
* create the `session` with `musig_nonce_process`.
|
||||
*
|
||||
* It is not required to call this function in regular MuSig sessions, because
|
||||
* if any partial signature does not verify, the final signature will not
|
||||
* verify either, so the problem will be caught. However, this function
|
||||
* provides the ability to identify which specific partial signature fails
|
||||
* verification.
|
||||
*
|
||||
* Returns: 0 if the arguments are invalid or the partial signature does not
|
||||
* verify, 1 otherwise
|
||||
* Args ctx: pointer to a context object
|
||||
* In: partial_sig: pointer to partial signature to verify, sent by
|
||||
* the signer associated with `pubnonce` and `pubkey`
|
||||
* pubnonce: public nonce of the signer in the signing session
|
||||
* pubkey: public key of the signer in the signing session
|
||||
* keyagg_cache: pointer to the keyagg_cache that was output when the
|
||||
* aggregate public key for this signing session
|
||||
* session: pointer to the session that was created with
|
||||
* `musig_nonce_process`
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_verify(
|
||||
const secp256k1_context *ctx,
|
||||
const secp256k1_musig_partial_sig *partial_sig,
|
||||
const secp256k1_musig_pubnonce *pubnonce,
|
||||
const secp256k1_pubkey *pubkey,
|
||||
const secp256k1_musig_keyagg_cache *keyagg_cache,
|
||||
const secp256k1_musig_session *session
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
|
||||
|
||||
/** Aggregates partial signatures
|
||||
*
|
||||
* Returns: 0 if the arguments are invalid, 1 otherwise (which does NOT mean
|
||||
* the resulting signature verifies).
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: sig64: complete (but possibly invalid) Schnorr signature
|
||||
* In: session: pointer to the session that was created with
|
||||
* musig_nonce_process
|
||||
* partial_sigs: array of pointers to partial signatures to aggregate
|
||||
* n_sigs: number of elements in the partial_sigs array. Must be
|
||||
* greater than 0.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_musig_partial_sig_agg(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *sig64,
|
||||
const secp256k1_musig_session *session,
|
||||
const secp256k1_musig_partial_sig * const *partial_sigs,
|
||||
size_t n_sigs
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -52,17 +52,19 @@ SECP256K1_API size_t secp256k1_context_preallocated_size(
|
|||
* in the memory. In simpler words, the prealloc pointer (or any pointer derived
|
||||
* from it) should not be used during the lifetime of the context object.
|
||||
*
|
||||
* Returns: a newly created context object.
|
||||
* In: prealloc: a pointer to a rewritable contiguous block of memory of
|
||||
* Returns: pointer to newly created context object.
|
||||
* In: prealloc: pointer to a rewritable contiguous block of memory of
|
||||
* size at least secp256k1_context_preallocated_size(flags)
|
||||
* bytes, as detailed above (cannot be NULL)
|
||||
* bytes, as detailed above.
|
||||
* flags: which parts of the context to initialize.
|
||||
*
|
||||
* See secp256k1_context_create (in secp256k1.h) for further details.
|
||||
*
|
||||
* See also secp256k1_context_randomize (in secp256k1.h)
|
||||
* and secp256k1_context_preallocated_destroy.
|
||||
*/
|
||||
SECP256K1_API secp256k1_context* secp256k1_context_preallocated_create(
|
||||
void* prealloc,
|
||||
SECP256K1_API secp256k1_context *secp256k1_context_preallocated_create(
|
||||
void *prealloc,
|
||||
unsigned int flags
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT;
|
||||
|
||||
|
@ -70,10 +72,10 @@ SECP256K1_API secp256k1_context* secp256k1_context_preallocated_create(
|
|||
* caller-provided memory.
|
||||
*
|
||||
* Returns: the required size of the caller-provided memory block.
|
||||
* In: ctx: an existing context to copy (cannot be NULL)
|
||||
* In: ctx: pointer to a context to copy.
|
||||
*/
|
||||
SECP256K1_API size_t secp256k1_context_preallocated_clone_size(
|
||||
const secp256k1_context* ctx
|
||||
const secp256k1_context *ctx
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT;
|
||||
|
||||
/** Copy a secp256k1 context object into caller-provided memory.
|
||||
|
@ -86,15 +88,18 @@ SECP256K1_API size_t secp256k1_context_preallocated_clone_size(
|
|||
* the lifetime of this context object, see the description of
|
||||
* secp256k1_context_preallocated_create for details.
|
||||
*
|
||||
* Returns: a newly created context object.
|
||||
* Args: ctx: an existing context to copy (cannot be NULL)
|
||||
* In: prealloc: a pointer to a rewritable contiguous block of memory of
|
||||
* Cloning secp256k1_context_static is not possible, and should not be emulated by
|
||||
* the caller (e.g., using memcpy). Create a new context instead.
|
||||
*
|
||||
* Returns: pointer to a newly created context object.
|
||||
* Args: ctx: pointer to a context to copy (not secp256k1_context_static).
|
||||
* In: prealloc: pointer to a rewritable contiguous block of memory of
|
||||
* size at least secp256k1_context_preallocated_size(flags)
|
||||
* bytes, as detailed above (cannot be NULL)
|
||||
* bytes, as detailed above.
|
||||
*/
|
||||
SECP256K1_API secp256k1_context* secp256k1_context_preallocated_clone(
|
||||
const secp256k1_context* ctx,
|
||||
void* prealloc
|
||||
SECP256K1_API secp256k1_context *secp256k1_context_preallocated_clone(
|
||||
const secp256k1_context *ctx,
|
||||
void *prealloc
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_WARN_UNUSED_RESULT;
|
||||
|
||||
/** Destroy a secp256k1 context object that has been created in
|
||||
|
@ -113,13 +118,14 @@ SECP256K1_API secp256k1_context* secp256k1_context_preallocated_clone(
|
|||
* preallocated pointer given to secp256k1_context_preallocated_create or
|
||||
* secp256k1_context_preallocated_clone.
|
||||
*
|
||||
* Args: ctx: an existing context to destroy, constructed using
|
||||
* Args: ctx: pointer to a context to destroy, constructed using
|
||||
* secp256k1_context_preallocated_create or
|
||||
* secp256k1_context_preallocated_clone (cannot be NULL)
|
||||
* secp256k1_context_preallocated_clone
|
||||
* (i.e., not secp256k1_context_static).
|
||||
*/
|
||||
SECP256K1_API void secp256k1_context_preallocated_destroy(
|
||||
secp256k1_context* ctx
|
||||
);
|
||||
secp256k1_context *ctx
|
||||
) SECP256K1_ARG_NONNULL(1);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Opaque data structured that holds a parsed ECDSA signature,
|
||||
/** Opaque data structure that holds a parsed ECDSA signature,
|
||||
* supporting pubkey recovery.
|
||||
*
|
||||
* The exact representation of data inside is implementation defined and not
|
||||
|
@ -21,21 +21,21 @@ extern "C" {
|
|||
* recoverability) will have identical representation, so they can be
|
||||
* memcmp'ed.
|
||||
*/
|
||||
typedef struct {
|
||||
typedef struct secp256k1_ecdsa_recoverable_signature {
|
||||
unsigned char data[65];
|
||||
} secp256k1_ecdsa_recoverable_signature;
|
||||
|
||||
/** Parse a compact ECDSA signature (64 bytes + recovery id).
|
||||
*
|
||||
* Returns: 1 when the signature could be parsed, 0 otherwise
|
||||
* Args: ctx: a secp256k1 context object
|
||||
* Out: sig: a pointer to a signature object
|
||||
* In: input64: a pointer to a 64-byte compact signature
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: sig: pointer to a signature object
|
||||
* In: input64: pointer to a 64-byte compact signature
|
||||
* recid: the recovery id (0, 1, 2 or 3)
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_ecdsa_recoverable_signature* sig,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_ecdsa_recoverable_signature *sig,
|
||||
const unsigned char *input64,
|
||||
int recid
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
@ -43,45 +43,48 @@ SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact(
|
|||
/** Convert a recoverable signature into a normal signature.
|
||||
*
|
||||
* Returns: 1
|
||||
* Out: sig: a pointer to a normal signature (cannot be NULL).
|
||||
* In: sigin: a pointer to a recoverable signature (cannot be NULL).
|
||||
* Args: ctx: pointer to a context object.
|
||||
* Out: sig: pointer to a normal signature.
|
||||
* In: sigin: pointer to a recoverable signature.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_ecdsa_signature* sig,
|
||||
const secp256k1_ecdsa_recoverable_signature* sigin
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_ecdsa_signature *sig,
|
||||
const secp256k1_ecdsa_recoverable_signature *sigin
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Serialize an ECDSA signature in compact format (64 bytes + recovery id).
|
||||
*
|
||||
* Returns: 1
|
||||
* Args: ctx: a secp256k1 context object
|
||||
* Out: output64: a pointer to a 64-byte array of the compact signature (cannot be NULL)
|
||||
* recid: a pointer to an integer to hold the recovery id (can be NULL).
|
||||
* In: sig: a pointer to an initialized signature object (cannot be NULL)
|
||||
* Args: ctx: pointer to a context object.
|
||||
* Out: output64: pointer to a 64-byte array of the compact signature.
|
||||
* recid: pointer to an integer to hold the recovery id.
|
||||
* In: sig: pointer to an initialized signature object.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *output64,
|
||||
int *recid,
|
||||
const secp256k1_ecdsa_recoverable_signature* sig
|
||||
const secp256k1_ecdsa_recoverable_signature *sig
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Create a recoverable ECDSA signature.
|
||||
*
|
||||
* Returns: 1: signature created
|
||||
* 0: the nonce generation function failed, or the private key was invalid.
|
||||
* Args: ctx: pointer to a context object, initialized for signing (cannot be NULL)
|
||||
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
|
||||
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
|
||||
* seckey: pointer to a 32-byte secret key (cannot be NULL)
|
||||
* noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used
|
||||
* ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
|
||||
* 0: the nonce generation function failed, or the secret key was invalid.
|
||||
* Args: ctx: pointer to a context object (not secp256k1_context_static).
|
||||
* Out: sig: pointer to an array where the signature will be placed.
|
||||
* In: msghash32: the 32-byte message hash being signed.
|
||||
* seckey: pointer to a 32-byte secret key.
|
||||
* noncefp: pointer to a nonce generation function. If NULL,
|
||||
* secp256k1_nonce_function_default is used.
|
||||
* ndata: pointer to arbitrary data used by the nonce generation function
|
||||
* (can be NULL for secp256k1_nonce_function_default).
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_sign_recoverable(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_ecdsa_recoverable_signature *sig,
|
||||
const unsigned char *msg32,
|
||||
const unsigned char *msghash32,
|
||||
const unsigned char *seckey,
|
||||
secp256k1_nonce_function noncefp,
|
||||
const void *ndata
|
||||
|
@ -91,16 +94,16 @@ SECP256K1_API int secp256k1_ecdsa_sign_recoverable(
|
|||
*
|
||||
* Returns: 1: public key successfully recovered (which guarantees a correct signature).
|
||||
* 0: otherwise.
|
||||
* Args: ctx: pointer to a context object, initialized for verification (cannot be NULL)
|
||||
* Out: pubkey: pointer to the recovered public key (cannot be NULL)
|
||||
* In: sig: pointer to initialized signature that supports pubkey recovery (cannot be NULL)
|
||||
* msg32: the 32-byte message hash assumed to be signed (cannot be NULL)
|
||||
* Args: ctx: pointer to a context object.
|
||||
* Out: pubkey: pointer to the recovered public key.
|
||||
* In: sig: pointer to initialized signature that supports pubkey recovery.
|
||||
* msghash32: the 32-byte message hash assumed to be signed.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_pubkey *pubkey,
|
||||
const secp256k1_ecdsa_recoverable_signature *sig,
|
||||
const unsigned char *msg32
|
||||
const unsigned char *msghash32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
190
example/android/third_party/secp256k1/include/secp256k1_schnorrsig.h
vendored
Normal file
190
example/android/third_party/secp256k1/include/secp256k1_schnorrsig.h
vendored
Normal file
|
@ -0,0 +1,190 @@
|
|||
#ifndef SECP256K1_SCHNORRSIG_H
|
||||
#define SECP256K1_SCHNORRSIG_H
|
||||
|
||||
#include "secp256k1.h"
|
||||
#include "secp256k1_extrakeys.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** This module implements a variant of Schnorr signatures compliant with
|
||||
* Bitcoin Improvement Proposal 340 "Schnorr Signatures for secp256k1"
|
||||
* (https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki).
|
||||
*/
|
||||
|
||||
/** A pointer to a function to deterministically generate a nonce.
|
||||
*
|
||||
* Same as secp256k1_nonce function with the exception of accepting an
|
||||
* additional pubkey argument and not requiring an attempt argument. The pubkey
|
||||
* argument can protect signature schemes with key-prefixed challenge hash
|
||||
* inputs against reusing the nonce when signing with the wrong precomputed
|
||||
* pubkey.
|
||||
*
|
||||
* Returns: 1 if a nonce was successfully generated. 0 will cause signing to
|
||||
* return an error.
|
||||
* Out: nonce32: pointer to a 32-byte array to be filled by the function
|
||||
* In: msg: the message being verified. Is NULL if and only if msglen
|
||||
* is 0.
|
||||
* msglen: the length of the message
|
||||
* key32: pointer to a 32-byte secret key (will not be NULL)
|
||||
* xonly_pk32: the 32-byte serialized xonly pubkey corresponding to key32
|
||||
* (will not be NULL)
|
||||
* algo: pointer to an array describing the signature
|
||||
* algorithm (will not be NULL)
|
||||
* algolen: the length of the algo array
|
||||
* data: arbitrary data pointer that is passed through
|
||||
*
|
||||
* Except for test cases, this function should compute some cryptographic hash of
|
||||
* the message, the key, the pubkey, the algorithm description, and data.
|
||||
*/
|
||||
typedef int (*secp256k1_nonce_function_hardened)(
|
||||
unsigned char *nonce32,
|
||||
const unsigned char *msg,
|
||||
size_t msglen,
|
||||
const unsigned char *key32,
|
||||
const unsigned char *xonly_pk32,
|
||||
const unsigned char *algo,
|
||||
size_t algolen,
|
||||
void *data
|
||||
);
|
||||
|
||||
/** An implementation of the nonce generation function as defined in Bitcoin
|
||||
* Improvement Proposal 340 "Schnorr Signatures for secp256k1"
|
||||
* (https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki).
|
||||
*
|
||||
* If a data pointer is passed, it is assumed to be a pointer to 32 bytes of
|
||||
* auxiliary random data as defined in BIP-340. If the data pointer is NULL,
|
||||
* the nonce derivation procedure follows BIP-340 by setting the auxiliary
|
||||
* random data to zero. The algo argument must be non-NULL, otherwise the
|
||||
* function will fail and return 0. The hash will be tagged with algo.
|
||||
* Therefore, to create BIP-340 compliant signatures, algo must be set to
|
||||
* "BIP0340/nonce" and algolen to 13.
|
||||
*/
|
||||
SECP256K1_API const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340;
|
||||
|
||||
/** Data structure that contains additional arguments for schnorrsig_sign_custom.
|
||||
*
|
||||
* A schnorrsig_extraparams structure object can be initialized correctly by
|
||||
* setting it to SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT.
|
||||
*
|
||||
* Members:
|
||||
* magic: set to SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC at initialization
|
||||
* and has no other function than making sure the object is
|
||||
* initialized.
|
||||
* noncefp: pointer to a nonce generation function. If NULL,
|
||||
* secp256k1_nonce_function_bip340 is used
|
||||
* ndata: pointer to arbitrary data used by the nonce generation function
|
||||
* (can be NULL). If it is non-NULL and
|
||||
* secp256k1_nonce_function_bip340 is used, then ndata must be a
|
||||
* pointer to 32-byte auxiliary randomness as per BIP-340.
|
||||
*/
|
||||
typedef struct secp256k1_schnorrsig_extraparams {
|
||||
unsigned char magic[4];
|
||||
secp256k1_nonce_function_hardened noncefp;
|
||||
void *ndata;
|
||||
} secp256k1_schnorrsig_extraparams;
|
||||
|
||||
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC { 0xda, 0x6f, 0xb3, 0x8c }
|
||||
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT {\
|
||||
SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC,\
|
||||
NULL,\
|
||||
NULL\
|
||||
}
|
||||
|
||||
/** Create a Schnorr signature.
|
||||
*
|
||||
* Does _not_ strictly follow BIP-340 because it does not verify the resulting
|
||||
* signature. Instead, you can manually use secp256k1_schnorrsig_verify and
|
||||
* abort if it fails.
|
||||
*
|
||||
* This function only signs 32-byte messages. If you have messages of a
|
||||
* different size (or the same size but without a context-specific tag
|
||||
* prefix), it is recommended to create a 32-byte message hash with
|
||||
* secp256k1_tagged_sha256 and then sign the hash. Tagged hashing allows
|
||||
* providing an context-specific tag for domain separation. This prevents
|
||||
* signatures from being valid in multiple contexts by accident.
|
||||
*
|
||||
* Returns 1 on success, 0 on failure.
|
||||
* Args: ctx: pointer to a context object (not secp256k1_context_static).
|
||||
* Out: sig64: pointer to a 64-byte array to store the serialized signature.
|
||||
* In: msg32: the 32-byte message being signed.
|
||||
* keypair: pointer to an initialized keypair.
|
||||
* aux_rand32: 32 bytes of fresh randomness. While recommended to provide
|
||||
* this, it is only supplemental to security and can be NULL. A
|
||||
* NULL argument is treated the same as an all-zero one. See
|
||||
* BIP-340 "Default Signing" for a full explanation of this
|
||||
* argument and for guidance if randomness is expensive.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_schnorrsig_sign32(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *sig64,
|
||||
const unsigned char *msg32,
|
||||
const secp256k1_keypair *keypair,
|
||||
const unsigned char *aux_rand32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Same as secp256k1_schnorrsig_sign32, but DEPRECATED. Will be removed in
|
||||
* future versions. */
|
||||
SECP256K1_API int secp256k1_schnorrsig_sign(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *sig64,
|
||||
const unsigned char *msg32,
|
||||
const secp256k1_keypair *keypair,
|
||||
const unsigned char *aux_rand32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
|
||||
SECP256K1_DEPRECATED("Use secp256k1_schnorrsig_sign32 instead");
|
||||
|
||||
/** Create a Schnorr signature with a more flexible API.
|
||||
*
|
||||
* Same arguments as secp256k1_schnorrsig_sign except that it allows signing
|
||||
* variable length messages and accepts a pointer to an extraparams object that
|
||||
* allows customizing signing by passing additional arguments.
|
||||
*
|
||||
* Equivalent to secp256k1_schnorrsig_sign32(..., aux_rand32) if msglen is 32
|
||||
* and extraparams is initialized as follows:
|
||||
* ```
|
||||
* secp256k1_schnorrsig_extraparams extraparams = SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT;
|
||||
* extraparams.ndata = (unsigned char*)aux_rand32;
|
||||
* ```
|
||||
*
|
||||
* Returns 1 on success, 0 on failure.
|
||||
* Args: ctx: pointer to a context object (not secp256k1_context_static).
|
||||
* Out: sig64: pointer to a 64-byte array to store the serialized signature.
|
||||
* In: msg: the message being signed. Can only be NULL if msglen is 0.
|
||||
* msglen: length of the message.
|
||||
* keypair: pointer to an initialized keypair.
|
||||
* extraparams: pointer to an extraparams object (can be NULL).
|
||||
*/
|
||||
SECP256K1_API int secp256k1_schnorrsig_sign_custom(
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *sig64,
|
||||
const unsigned char *msg,
|
||||
size_t msglen,
|
||||
const secp256k1_keypair *keypair,
|
||||
secp256k1_schnorrsig_extraparams *extraparams
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
/** Verify a Schnorr signature.
|
||||
*
|
||||
* Returns: 1: correct signature
|
||||
* 0: incorrect signature
|
||||
* Args: ctx: pointer to a context object.
|
||||
* In: sig64: pointer to the 64-byte signature to verify.
|
||||
* msg: the message being verified. Can only be NULL if msglen is 0.
|
||||
* msglen: length of the message
|
||||
* pubkey: pointer to an x-only public key to verify with
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_verify(
|
||||
const secp256k1_context *ctx,
|
||||
const unsigned char *sig64,
|
||||
const unsigned char *msg,
|
||||
size_t msglen,
|
||||
const secp256k1_xonly_pubkey *pubkey
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SECP256K1_SCHNORRSIG_H */
|
BIN
example/android/third_party/secp256k1/libsecp256k1.a
vendored
BIN
example/android/third_party/secp256k1/libsecp256k1.a
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -28,7 +28,7 @@ namespace ton {
|
|||
namespace keyring {
|
||||
|
||||
KeyringImpl::PrivateKeyDescr::PrivateKeyDescr(PrivateKey private_key, bool is_temp)
|
||||
: public_key(private_key.compute_public_key()), is_temp(is_temp) {
|
||||
: public_key(private_key.compute_public_key()), private_key(private_key), is_temp(is_temp) {
|
||||
auto D = private_key.create_decryptor_async();
|
||||
D.ensure();
|
||||
decryptor_sign = D.move_as_ok();
|
||||
|
@ -190,6 +190,16 @@ void KeyringImpl::decrypt_message(PublicKeyHash key_hash, td::BufferSlice data,
|
|||
}
|
||||
}
|
||||
|
||||
void KeyringImpl::export_all_private_keys(td::Promise<std::vector<PrivateKey>> promise) {
|
||||
std::vector<PrivateKey> keys;
|
||||
for (auto& [_, descr] : map_) {
|
||||
if (!descr->is_temp && descr->private_key.exportable()) {
|
||||
keys.push_back(descr->private_key);
|
||||
}
|
||||
}
|
||||
promise.set_value(std::move(keys));
|
||||
}
|
||||
|
||||
td::actor::ActorOwn<Keyring> Keyring::create(std::string db_root) {
|
||||
return td::actor::create_actor<KeyringImpl>("keyring", db_root);
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@ class Keyring : public td::actor::Actor {
|
|||
|
||||
virtual void decrypt_message(PublicKeyHash key_hash, td::BufferSlice data, td::Promise<td::BufferSlice> promise) = 0;
|
||||
|
||||
virtual void export_all_private_keys(td::Promise<std::vector<PrivateKey>> promise) = 0;
|
||||
|
||||
static td::actor::ActorOwn<Keyring> create(std::string db_root);
|
||||
};
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ class KeyringImpl : public Keyring {
|
|||
td::actor::ActorOwn<DecryptorAsync> decryptor_sign;
|
||||
td::actor::ActorOwn<DecryptorAsync> decryptor_decrypt;
|
||||
PublicKey public_key;
|
||||
PrivateKey private_key;
|
||||
bool is_temp;
|
||||
PrivateKeyDescr(PrivateKey private_key, bool is_temp);
|
||||
};
|
||||
|
@ -56,6 +57,8 @@ class KeyringImpl : public Keyring {
|
|||
|
||||
void decrypt_message(PublicKeyHash key_hash, td::BufferSlice data, td::Promise<td::BufferSlice> promise) override;
|
||||
|
||||
void export_all_private_keys(td::Promise<std::vector<PrivateKey>> promise) override;
|
||||
|
||||
KeyringImpl(std::string db_root) : db_root_(db_root) {
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
|
||||
|
||||
add_library(lite-client-common STATIC lite-client-common.cpp lite-client-common.h)
|
||||
add_library(lite-client-common STATIC lite-client-common.cpp lite-client-common.h ext-client.cpp ext-client.h
|
||||
query-utils.hpp query-utils.cpp)
|
||||
target_link_libraries(lite-client-common PUBLIC tdactor adnllite tl_api tl_lite_api tl-lite-utils ton_crypto)
|
||||
|
||||
add_executable(lite-client lite-client.cpp lite-client.h)
|
||||
add_executable(lite-client lite-client.cpp lite-client.h ext-client.h ext-client.cpp)
|
||||
target_link_libraries(lite-client tdutils tdactor adnllite tl_api tl_lite_api tl-lite-utils terminal lite-client-common git)
|
||||
|
||||
install(TARGETS lite-client RUNTIME DESTINATION bin)
|
||||
|
|
228
lite-client/ext-client.cpp
Normal file
228
lite-client/ext-client.cpp
Normal file
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
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/>.
|
||||
*/
|
||||
#include "ext-client.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "ton/ton-shard.h"
|
||||
|
||||
namespace liteclient {
|
||||
|
||||
class ExtClientImpl : public ExtClient {
|
||||
public:
|
||||
ExtClientImpl(std::vector<LiteServerConfig> liteservers, td::unique_ptr<Callback> callback, bool connect_to_all)
|
||||
: callback_(std::move(callback)), connect_to_all_(connect_to_all) {
|
||||
CHECK(!liteservers.empty());
|
||||
servers_.resize(liteservers.size());
|
||||
for (size_t i = 0; i < servers_.size(); ++i) {
|
||||
servers_[i].config = std::move(liteservers[i]);
|
||||
servers_[i].idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
void start_up() override {
|
||||
LOG(INFO) << "Started ext client, " << servers_.size() << " liteservers";
|
||||
td::Random::Fast rnd;
|
||||
td::random_shuffle(td::as_mutable_span(servers_), rnd);
|
||||
server_indices_.resize(servers_.size());
|
||||
for (size_t i = 0; i < servers_.size(); ++i) {
|
||||
server_indices_[servers_[i].idx] = i;
|
||||
}
|
||||
|
||||
if (connect_to_all_) {
|
||||
for (size_t i = 0; i < servers_.size(); ++i) {
|
||||
prepare_server(i, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void send_query(std::string name, td::BufferSlice data, td::Timestamp timeout,
|
||||
td::Promise<td::BufferSlice> promise) override {
|
||||
QueryInfo query_info = get_query_info(data);
|
||||
TRY_RESULT_PROMISE(promise, server_idx, select_server(query_info));
|
||||
send_query_internal(std::move(name), std::move(data), std::move(query_info), server_idx, timeout,
|
||||
std::move(promise));
|
||||
}
|
||||
|
||||
void send_query_to_server(std::string name, td::BufferSlice data, size_t server_idx, td::Timestamp timeout,
|
||||
td::Promise<td::BufferSlice> promise) override {
|
||||
if (server_idx >= servers_.size()) {
|
||||
promise.set_error(td::Status::Error(PSTRING() << "server idx " << server_idx << " is too big"));
|
||||
return;
|
||||
}
|
||||
server_idx = server_indices_[server_idx];
|
||||
QueryInfo query_info = get_query_info(data);
|
||||
prepare_server(server_idx, &query_info);
|
||||
send_query_internal(std::move(name), std::move(data), std::move(query_info), server_idx, timeout,
|
||||
std::move(promise));
|
||||
}
|
||||
|
||||
void get_servers_status(td::Promise<std::vector<bool>> promise) override {
|
||||
std::vector<bool> status(servers_.size());
|
||||
for (const Server& s : servers_) {
|
||||
status[s.idx] = s.alive;
|
||||
}
|
||||
promise.set_result(std::move(status));
|
||||
}
|
||||
|
||||
void reset_servers() override {
|
||||
LOG(INFO) << "Force resetting all liteservers";
|
||||
for (Server& server : servers_) {
|
||||
server.alive = false;
|
||||
server.timeout = {};
|
||||
server.ignore_until = {};
|
||||
server.client.reset();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void send_query_internal(std::string name, td::BufferSlice data, QueryInfo query_info, size_t server_idx,
|
||||
td::Timestamp timeout, td::Promise<td::BufferSlice> promise) {
|
||||
auto& server = servers_[server_idx];
|
||||
CHECK(!server.client.empty());
|
||||
if (!connect_to_all_) {
|
||||
alarm_timestamp().relax(server.timeout = td::Timestamp::in(MAX_NO_QUERIES_TIMEOUT));
|
||||
}
|
||||
td::Promise<td::BufferSlice> P = [SelfId = actor_id(this), server_idx,
|
||||
promise = std::move(promise)](td::Result<td::BufferSlice> R) mutable {
|
||||
if (R.is_error() &&
|
||||
(R.error().code() == ton::ErrorCode::timeout || R.error().code() == ton::ErrorCode::cancelled)) {
|
||||
td::actor::send_closure(SelfId, &ExtClientImpl::on_server_error, server_idx);
|
||||
}
|
||||
promise.set_result(std::move(R));
|
||||
};
|
||||
LOG(DEBUG) << "Sending query " << query_info.to_str() << " to server #" << server.idx << " ("
|
||||
<< server.config.addr.get_ip_str() << ":" << server.config.addr.get_port() << ")";
|
||||
send_closure(server.client, &ton::adnl::AdnlExtClient::send_query, std::move(name), std::move(data), timeout,
|
||||
std::move(P));
|
||||
}
|
||||
|
||||
td::Result<size_t> select_server(const QueryInfo& query_info) {
|
||||
for (size_t i = 0; i < servers_.size(); ++i) {
|
||||
if (servers_[i].alive && servers_[i].config.accepts_query(query_info)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
size_t server_idx = servers_.size();
|
||||
int cnt = 0;
|
||||
int best_priority = -1;
|
||||
for (size_t i = 0; i < servers_.size(); ++i) {
|
||||
Server& server = servers_[i];
|
||||
if (!server.config.accepts_query(query_info)) {
|
||||
continue;
|
||||
}
|
||||
int priority = 0;
|
||||
priority += (server.ignore_until && !server.ignore_until.is_in_past() ? 0 : 10);
|
||||
if (priority < best_priority) {
|
||||
continue;
|
||||
}
|
||||
if (priority > best_priority) {
|
||||
best_priority = priority;
|
||||
cnt = 0;
|
||||
}
|
||||
if (td::Random::fast(0, cnt) == 0) {
|
||||
server_idx = i;
|
||||
}
|
||||
++cnt;
|
||||
}
|
||||
if (server_idx == servers_.size()) {
|
||||
return td::Status::Error(PSTRING() << "no liteserver for query " << query_info.to_str());
|
||||
}
|
||||
prepare_server(server_idx, &query_info);
|
||||
return server_idx;
|
||||
}
|
||||
|
||||
void prepare_server(size_t server_idx, const QueryInfo* query_info) {
|
||||
Server& server = servers_[server_idx];
|
||||
if (server.alive) {
|
||||
return;
|
||||
}
|
||||
server.alive = true;
|
||||
server.ignore_until = {};
|
||||
if (!connect_to_all_) {
|
||||
alarm_timestamp().relax(server.timeout = td::Timestamp::in(MAX_NO_QUERIES_TIMEOUT));
|
||||
}
|
||||
if (!server.client.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
class Callback : public ton::adnl::AdnlExtClient::Callback {
|
||||
public:
|
||||
explicit Callback(td::actor::ActorId<ExtClientImpl> parent, size_t idx) : parent_(std::move(parent)), idx_(idx) {
|
||||
}
|
||||
void on_ready() override {
|
||||
}
|
||||
void on_stop_ready() override {
|
||||
td::actor::send_closure(parent_, &ExtClientImpl::on_server_error, idx_);
|
||||
}
|
||||
|
||||
private:
|
||||
td::actor::ActorId<ExtClientImpl> parent_;
|
||||
size_t idx_;
|
||||
};
|
||||
LOG(INFO) << "Connecting to liteserver #" << server.idx << " (" << server.config.addr.get_ip_str() << ":"
|
||||
<< server.config.addr.get_port() << ") for query " << (query_info ? query_info->to_str() : "[none]");
|
||||
server.client = ton::adnl::AdnlExtClient::create(server.config.adnl_id, server.config.addr,
|
||||
std::make_unique<Callback>(actor_id(this), server_idx));
|
||||
}
|
||||
|
||||
struct Server {
|
||||
LiteServerConfig config;
|
||||
size_t idx = 0;
|
||||
td::actor::ActorOwn<ton::adnl::AdnlExtClient> client;
|
||||
bool alive = false;
|
||||
td::Timestamp timeout = td::Timestamp::never();
|
||||
td::Timestamp ignore_until = td::Timestamp::never();
|
||||
};
|
||||
std::vector<Server> servers_;
|
||||
std::vector<size_t> server_indices_;
|
||||
|
||||
td::unique_ptr<Callback> callback_;
|
||||
bool connect_to_all_ = false;
|
||||
static constexpr double MAX_NO_QUERIES_TIMEOUT = 100.0;
|
||||
static constexpr double BAD_SERVER_TIMEOUT = 30.0;
|
||||
|
||||
void alarm() override {
|
||||
if (connect_to_all_) {
|
||||
return;
|
||||
}
|
||||
for (Server& server : servers_) {
|
||||
if (server.timeout && server.timeout.is_in_past()) {
|
||||
LOG(INFO) << "Closing connection to liteserver #" << server.idx << " (" << server.config.addr.get_ip_str()
|
||||
<< ":" << server.config.addr.get_port() << ")";
|
||||
server.client.reset();
|
||||
server.alive = false;
|
||||
server.ignore_until = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void on_server_error(size_t idx) {
|
||||
servers_[idx].alive = false;
|
||||
servers_[idx].ignore_until = td::Timestamp::in(BAD_SERVER_TIMEOUT);
|
||||
}
|
||||
};
|
||||
|
||||
td::actor::ActorOwn<ExtClient> ExtClient::create(ton::adnl::AdnlNodeIdFull dst, td::IPAddress dst_addr,
|
||||
td::unique_ptr<Callback> callback) {
|
||||
return create({LiteServerConfig{dst, dst_addr}}, std::move(callback));
|
||||
}
|
||||
|
||||
td::actor::ActorOwn<ExtClient> ExtClient::create(std::vector<LiteServerConfig> liteservers,
|
||||
td::unique_ptr<Callback> callback, bool connect_to_all) {
|
||||
return td::actor::create_actor<ExtClientImpl>("ExtClient", std::move(liteservers), std::move(callback),
|
||||
connect_to_all);
|
||||
}
|
||||
} // namespace liteclient
|
48
lite-client/ext-client.h
Normal file
48
lite-client/ext-client.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
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/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "td/actor/actor.h"
|
||||
#include "ton/ton-types.h"
|
||||
#include "adnl/adnl-ext-client.h"
|
||||
#include "query-utils.hpp"
|
||||
|
||||
namespace liteclient {
|
||||
class ExtClient : public td::actor::Actor {
|
||||
public:
|
||||
class Callback {
|
||||
public:
|
||||
virtual ~Callback() = default;
|
||||
};
|
||||
|
||||
virtual void send_query(std::string name, td::BufferSlice data, td::Timestamp timeout,
|
||||
td::Promise<td::BufferSlice> promise) = 0;
|
||||
virtual void send_query_to_server(std::string name, td::BufferSlice data, size_t server_idx, td::Timestamp timeout,
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
promise.set_error(td::Status::Error("not supported"));
|
||||
}
|
||||
virtual void get_servers_status(td::Promise<std::vector<bool>> promise) {
|
||||
promise.set_error(td::Status::Error("not supported"));
|
||||
}
|
||||
virtual void reset_servers() {
|
||||
}
|
||||
|
||||
static td::actor::ActorOwn<ExtClient> create(ton::adnl::AdnlNodeIdFull dst, td::IPAddress dst_addr,
|
||||
td::unique_ptr<Callback> callback);
|
||||
static td::actor::ActorOwn<ExtClient> create(std::vector<LiteServerConfig> liteservers,
|
||||
td::unique_ptr<Callback> callback, bool connect_to_all = false);
|
||||
};
|
||||
} // namespace liteclient
|
|
@ -29,22 +29,16 @@
|
|||
|
||||
#include "lite-client-common.h"
|
||||
|
||||
#include "adnl/adnl-ext-client.h"
|
||||
#include "tl-utils/lite-utils.hpp"
|
||||
#include "auto/tl/ton_api_json.h"
|
||||
#include "auto/tl/lite_api.hpp"
|
||||
#include "td/utils/OptionParser.h"
|
||||
#include "td/utils/Time.h"
|
||||
#include "td/utils/filesystem.h"
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/crypto.h"
|
||||
#include "td/utils/overloaded.h"
|
||||
#include "td/utils/port/signals.h"
|
||||
#include "td/utils/port/stacktrace.h"
|
||||
#include "td/utils/port/StdStreams.h"
|
||||
#include "td/utils/port/FileFd.h"
|
||||
#include "terminal/terminal.h"
|
||||
#include "ton/lite-tl.hpp"
|
||||
#include "block/block-db.h"
|
||||
#include "block/block.h"
|
||||
|
@ -58,18 +52,14 @@
|
|||
#include "vm/vm.h"
|
||||
#include "vm/cp0.h"
|
||||
#include "vm/memo.h"
|
||||
#include "ton/ton-shard.h"
|
||||
#include "openssl/rand.hpp"
|
||||
#include "crypto/vm/utils.h"
|
||||
#include "crypto/common/util.h"
|
||||
#include "common/checksum.h"
|
||||
|
||||
#if TD_DARWIN || TD_LINUX
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include "git.h"
|
||||
|
||||
using namespace std::literals::string_literals;
|
||||
|
@ -77,24 +67,6 @@ using td::Ref;
|
|||
|
||||
int verbosity;
|
||||
|
||||
std::unique_ptr<ton::adnl::AdnlExtClient::Callback> TestNode::make_callback() {
|
||||
class Callback : public ton::adnl::AdnlExtClient::Callback {
|
||||
public:
|
||||
void on_ready() override {
|
||||
td::actor::send_closure(id_, &TestNode::conn_ready);
|
||||
}
|
||||
void on_stop_ready() override {
|
||||
td::actor::send_closure(id_, &TestNode::conn_closed);
|
||||
}
|
||||
Callback(td::actor::ActorId<TestNode> id) : id_(std::move(id)) {
|
||||
}
|
||||
|
||||
private:
|
||||
td::actor::ActorId<TestNode> id_;
|
||||
};
|
||||
return std::make_unique<Callback>(actor_id(this));
|
||||
}
|
||||
|
||||
void TestNode::run() {
|
||||
class Cb : public td::TerminalIO::Callback {
|
||||
public:
|
||||
|
@ -110,19 +82,20 @@ void TestNode::run() {
|
|||
io_ = td::TerminalIO::create("> ", readline_enabled_, ex_mode_, std::make_unique<Cb>(actor_id(this)));
|
||||
td::actor::send_closure(io_, &td::TerminalIO::set_log_interface);
|
||||
|
||||
if (remote_public_key_.empty()) {
|
||||
std::vector<liteclient::LiteServerConfig> servers;
|
||||
if (!single_remote_public_key_.empty()) { // Use single provided liteserver
|
||||
servers.push_back(
|
||||
liteclient::LiteServerConfig{ton::adnl::AdnlNodeIdFull{single_remote_public_key_}, single_remote_addr_});
|
||||
td::TerminalIO::out() << "using liteserver " << single_remote_addr_ << "\n";
|
||||
} else {
|
||||
auto G = td::read_file(global_config_).move_as_ok();
|
||||
auto gc_j = td::json_decode(G.as_slice()).move_as_ok();
|
||||
ton::ton_api::liteclient_config_global gc;
|
||||
ton::ton_api::from_json(gc, gc_j.get_object()).ensure();
|
||||
CHECK(gc.liteservers_.size() > 0);
|
||||
auto idx = liteserver_idx_ >= 0 ? liteserver_idx_
|
||||
: td::Random::fast(0, static_cast<td::uint32>(gc.liteservers_.size() - 1));
|
||||
CHECK(idx >= 0 && static_cast<td::uint32>(idx) <= gc.liteservers_.size());
|
||||
auto& cli = gc.liteservers_[idx];
|
||||
remote_addr_.init_host_port(td::IPAddress::ipv4_to_str(cli->ip_), cli->port_).ensure();
|
||||
remote_public_key_ = ton::PublicKey{cli->id_};
|
||||
td::TerminalIO::out() << "using liteserver " << idx << " with addr " << remote_addr_ << "\n";
|
||||
auto r_servers = liteclient::LiteServerConfig::parse_global_config(gc);
|
||||
r_servers.ensure();
|
||||
servers = r_servers.move_as_ok();
|
||||
|
||||
if (gc.validator_ && gc.validator_->zero_state_) {
|
||||
zstate_id_.workchain = gc.validator_->zero_state_->workchain_;
|
||||
if (zstate_id_.workchain != ton::workchainInvalid) {
|
||||
|
@ -131,10 +104,19 @@ void TestNode::run() {
|
|||
td::TerminalIO::out() << "zerostate set to " << zstate_id_.to_str() << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client_ =
|
||||
ton::adnl::AdnlExtClient::create(ton::adnl::AdnlNodeIdFull{remote_public_key_}, remote_addr_, make_callback());
|
||||
if (single_liteserver_idx_ != -1) { // Use single liteserver from config
|
||||
CHECK(single_liteserver_idx_ >= 0 && (size_t)single_liteserver_idx_ < servers.size());
|
||||
td::TerminalIO::out() << "using liteserver #" << single_liteserver_idx_ << " with addr "
|
||||
<< servers[single_liteserver_idx_].addr << "\n";
|
||||
servers = {servers[single_liteserver_idx_]};
|
||||
}
|
||||
}
|
||||
CHECK(!servers.empty());
|
||||
client_ = liteclient::ExtClient::create(std::move(servers), nullptr);
|
||||
ready_ = true;
|
||||
|
||||
run_init_queries();
|
||||
}
|
||||
|
||||
void TestNode::got_result(td::Result<td::BufferSlice> R, td::Promise<td::BufferSlice> promise) {
|
||||
|
@ -191,8 +173,8 @@ bool TestNode::envelope_send_query(td::BufferSlice query, td::Promise<td::Buffer
|
|||
});
|
||||
td::BufferSlice b =
|
||||
ton::serialize_tl_object(ton::create_tl_object<ton::lite_api::liteServer_query>(std::move(query)), true);
|
||||
td::actor::send_closure(client_, &ton::adnl::AdnlExtClient::send_query, "query", std::move(b),
|
||||
td::Timestamp::in(10.0), std::move(P));
|
||||
td::actor::send_closure(client_, &liteclient::ExtClient::send_query, "query", std::move(b), td::Timestamp::in(10.0),
|
||||
std::move(P));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -319,9 +301,10 @@ bool TestNode::get_server_time() {
|
|||
if (F.is_error()) {
|
||||
LOG(ERROR) << "cannot parse answer to liteServer.getTime";
|
||||
} else {
|
||||
server_time_ = F.move_as_ok()->now_;
|
||||
server_time_got_at_ = now();
|
||||
LOG(INFO) << "server time is " << server_time_ << " (delta " << server_time_ - server_time_got_at_ << ")";
|
||||
mc_server_time_ = F.move_as_ok()->now_;
|
||||
mc_server_time_got_at_ = now();
|
||||
LOG(INFO) << "server time is " << mc_server_time_ << " (delta " << mc_server_time_ - mc_server_time_got_at_
|
||||
<< ")";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -335,7 +318,7 @@ bool TestNode::get_server_version(int mode) {
|
|||
};
|
||||
|
||||
void TestNode::got_server_version(td::Result<td::BufferSlice> res, int mode) {
|
||||
server_ok_ = false;
|
||||
mc_server_ok_ = false;
|
||||
if (res.is_error()) {
|
||||
LOG(ERROR) << "cannot get server version and time (server too old?)";
|
||||
} else {
|
||||
|
@ -344,11 +327,11 @@ void TestNode::got_server_version(td::Result<td::BufferSlice> res, int mode) {
|
|||
LOG(ERROR) << "cannot parse answer to liteServer.getVersion";
|
||||
} else {
|
||||
auto a = F.move_as_ok();
|
||||
set_server_version(a->version_, a->capabilities_);
|
||||
set_server_time(a->now_);
|
||||
set_mc_server_version(a->version_, a->capabilities_);
|
||||
set_mc_server_time(a->now_);
|
||||
}
|
||||
}
|
||||
if (!server_ok_) {
|
||||
if (!mc_server_ok_) {
|
||||
LOG(ERROR) << "server version is too old (at least " << (min_ls_version >> 8) << "." << (min_ls_version & 0xff)
|
||||
<< " with capabilities " << min_ls_capabilities << " required), some queries are unavailable";
|
||||
}
|
||||
|
@ -357,24 +340,24 @@ void TestNode::got_server_version(td::Result<td::BufferSlice> res, int mode) {
|
|||
}
|
||||
}
|
||||
|
||||
void TestNode::set_server_version(td::int32 version, td::int64 capabilities) {
|
||||
if (server_version_ != version || server_capabilities_ != capabilities) {
|
||||
server_version_ = version;
|
||||
server_capabilities_ = capabilities;
|
||||
LOG(WARNING) << "server version is " << (server_version_ >> 8) << "." << (server_version_ & 0xff)
|
||||
<< ", capabilities " << server_capabilities_;
|
||||
void TestNode::set_mc_server_version(td::int32 version, td::int64 capabilities) {
|
||||
if (mc_server_version_ != version || mc_server_capabilities_ != capabilities) {
|
||||
mc_server_version_ = version;
|
||||
mc_server_capabilities_ = capabilities;
|
||||
LOG(WARNING) << "server version is " << (mc_server_version_ >> 8) << "." << (mc_server_version_ & 0xff)
|
||||
<< ", capabilities " << mc_server_capabilities_;
|
||||
}
|
||||
server_ok_ = (server_version_ >= min_ls_version) && !(~server_capabilities_ & min_ls_capabilities);
|
||||
mc_server_ok_ = (mc_server_version_ >= min_ls_version) && !(~mc_server_capabilities_ & min_ls_capabilities);
|
||||
}
|
||||
|
||||
void TestNode::set_server_time(int server_utime) {
|
||||
server_time_ = server_utime;
|
||||
server_time_got_at_ = now();
|
||||
LOG(INFO) << "server time is " << server_time_ << " (delta " << server_time_ - server_time_got_at_ << ")";
|
||||
void TestNode::set_mc_server_time(int server_utime) {
|
||||
mc_server_time_ = server_utime;
|
||||
mc_server_time_got_at_ = now();
|
||||
LOG(INFO) << "server time is " << mc_server_time_ << " (delta " << mc_server_time_ - mc_server_time_got_at_ << ")";
|
||||
}
|
||||
|
||||
bool TestNode::get_server_mc_block_id() {
|
||||
int mode = (server_capabilities_ & 2) ? 0 : -1;
|
||||
int mode = (mc_server_capabilities_ & 2) ? 0 : -1;
|
||||
if (mode < 0) {
|
||||
auto b = ton::serialize_tl_object(ton::create_tl_object<ton::lite_api::liteServer_getMasterchainInfo>(), true);
|
||||
return envelope_send_query(std::move(b), [Self = actor_id(this)](td::Result<td::BufferSlice> res) -> void {
|
||||
|
@ -448,8 +431,8 @@ void TestNode::got_server_mc_block_id(ton::BlockIdExt blkid, ton::ZeroStateIdExt
|
|||
|
||||
void TestNode::got_server_mc_block_id_ext(ton::BlockIdExt blkid, ton::ZeroStateIdExt zstateid, int mode, int version,
|
||||
long long capabilities, int last_utime, int server_now) {
|
||||
set_server_version(version, capabilities);
|
||||
set_server_time(server_now);
|
||||
set_mc_server_version(version, capabilities);
|
||||
set_mc_server_time(server_now);
|
||||
if (last_utime > server_now) {
|
||||
LOG(WARNING) << "server claims to have a masterchain block " << blkid.to_str() << " created at " << last_utime
|
||||
<< " (" << last_utime - server_now << " seconds in the future)";
|
||||
|
@ -457,10 +440,10 @@ void TestNode::got_server_mc_block_id_ext(ton::BlockIdExt blkid, ton::ZeroStateI
|
|||
LOG(WARNING) << "server appears to be out of sync: its newest masterchain block is " << blkid.to_str()
|
||||
<< " created at " << last_utime << " (" << server_now - last_utime
|
||||
<< " seconds ago according to the server's clock)";
|
||||
} else if (last_utime < server_time_got_at_ - 60) {
|
||||
} else if (last_utime < mc_server_time_got_at_ - 60) {
|
||||
LOG(WARNING) << "either the server is out of sync, or the local clock is set incorrectly: the newest masterchain "
|
||||
"block known to server is "
|
||||
<< blkid.to_str() << " created at " << last_utime << " (" << server_now - server_time_got_at_
|
||||
<< blkid.to_str() << " created at " << last_utime << " (" << server_now - mc_server_time_got_at_
|
||||
<< " seconds ago according to the local clock)";
|
||||
}
|
||||
got_server_mc_block_id(blkid, zstateid, last_utime);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
#include "ext-client.h"
|
||||
#include "adnl/adnl-ext-client.h"
|
||||
#include "tl-utils/tl-utils.hpp"
|
||||
#include "ton/ton-types.h"
|
||||
|
@ -46,22 +47,24 @@ class TestNode : public td::actor::Actor {
|
|||
min_ls_version = 0x101,
|
||||
min_ls_capabilities = 1
|
||||
}; // server version >= 1.1, capabilities at least +1 = build proof chains
|
||||
td::actor::ActorOwn<ton::adnl::AdnlExtClient> client_;
|
||||
td::actor::ActorOwn<liteclient::ExtClient> client_;
|
||||
td::actor::ActorOwn<td::TerminalIO> io_;
|
||||
bool ready_ = false;
|
||||
|
||||
td::int32 single_liteserver_idx_ = -1;
|
||||
td::IPAddress single_remote_addr_;
|
||||
ton::PublicKey single_remote_public_key_;
|
||||
|
||||
bool readline_enabled_ = true;
|
||||
bool server_ok_ = false;
|
||||
td::int32 liteserver_idx_ = -1;
|
||||
int print_limit_ = 1024;
|
||||
|
||||
bool ready_ = false;
|
||||
bool inited_ = false;
|
||||
std::string db_root_;
|
||||
|
||||
int server_time_ = 0;
|
||||
int server_time_got_at_ = 0;
|
||||
int server_version_ = 0;
|
||||
long long server_capabilities_ = 0;
|
||||
int mc_server_time_ = 0;
|
||||
int mc_server_time_got_at_ = 0;
|
||||
int mc_server_version_ = 0;
|
||||
long long mc_server_capabilities_ = 0;
|
||||
bool mc_server_ok_ = false;
|
||||
|
||||
ton::ZeroStateIdExt zstate_id_;
|
||||
ton::BlockIdExt mc_last_id_;
|
||||
|
@ -76,9 +79,6 @@ class TestNode : public td::actor::Actor {
|
|||
const char *parse_ptr_, *parse_end_;
|
||||
td::Status error_;
|
||||
|
||||
td::IPAddress remote_addr_;
|
||||
ton::PublicKey remote_public_key_;
|
||||
|
||||
std::vector<ton::BlockIdExt> known_blk_ids_;
|
||||
std::size_t shown_blk_ids_ = 0;
|
||||
|
||||
|
@ -89,8 +89,6 @@ class TestNode : public td::actor::Actor {
|
|||
|
||||
std::map<td::Bits256, Ref<vm::Cell>> cell_cache_;
|
||||
|
||||
std::unique_ptr<ton::adnl::AdnlExtClient::Callback> make_callback();
|
||||
|
||||
using creator_stats_func_t =
|
||||
std::function<bool(const td::Bits256&, const block::DiscountedCounter&, const block::DiscountedCounter&)>;
|
||||
|
||||
|
@ -183,8 +181,8 @@ class TestNode : public td::actor::Actor {
|
|||
void got_server_mc_block_id(ton::BlockIdExt blkid, ton::ZeroStateIdExt zstateid, int created_at);
|
||||
void got_server_mc_block_id_ext(ton::BlockIdExt blkid, ton::ZeroStateIdExt zstateid, int mode, int version,
|
||||
long long capabilities, int last_utime, int server_now);
|
||||
void set_server_version(td::int32 version, td::int64 capabilities);
|
||||
void set_server_time(int server_utime);
|
||||
void set_mc_server_version(td::int32 version, td::int64 capabilities);
|
||||
void set_mc_server_time(int server_utime);
|
||||
bool request_block(ton::BlockIdExt blkid);
|
||||
bool request_state(ton::BlockIdExt blkid);
|
||||
void got_mc_block(ton::BlockIdExt blkid, td::BufferSlice data);
|
||||
|
@ -370,9 +368,6 @@ class TestNode : public td::actor::Actor {
|
|||
bool parse_shard_id(ton::ShardIdFull& shard);
|
||||
bool parse_block_id_ext(ton::BlockIdExt& blkid, bool allow_incomplete = false);
|
||||
bool parse_block_id_ext(std::string blk_id_string, ton::BlockIdExt& blkid, bool allow_incomplete = false) const;
|
||||
bool parse_stack_value(td::Slice str, vm::StackEntry& value);
|
||||
bool parse_stack_value(vm::StackEntry& value);
|
||||
bool parse_stack_values(std::vector<vm::StackEntry>& values);
|
||||
bool register_blkid(const ton::BlockIdExt& blkid);
|
||||
bool show_new_blkids(bool all = false);
|
||||
bool complete_blkid(ton::BlockId partial_blkid, ton::BlockIdExt& complete_blkid) const;
|
||||
|
@ -391,16 +386,6 @@ class TestNode : public td::actor::Actor {
|
|||
static const tlb::TypenameLookup& get_tlb_dict();
|
||||
|
||||
public:
|
||||
void conn_ready() {
|
||||
LOG(ERROR) << "conn ready";
|
||||
ready_ = true;
|
||||
if (!inited_) {
|
||||
run_init_queries();
|
||||
}
|
||||
}
|
||||
void conn_closed() {
|
||||
ready_ = false;
|
||||
}
|
||||
void set_global_config(std::string str) {
|
||||
global_config_ = str;
|
||||
}
|
||||
|
@ -411,10 +396,10 @@ class TestNode : public td::actor::Actor {
|
|||
readline_enabled_ = value;
|
||||
}
|
||||
void set_liteserver_idx(td::int32 idx) {
|
||||
liteserver_idx_ = idx;
|
||||
single_liteserver_idx_ = idx;
|
||||
}
|
||||
void set_remote_addr(td::IPAddress addr) {
|
||||
remote_addr_ = addr;
|
||||
single_remote_addr_ = addr;
|
||||
}
|
||||
void set_public_key(td::BufferSlice file_name) {
|
||||
auto R = [&]() -> td::Result<ton::PublicKey> {
|
||||
|
@ -425,7 +410,7 @@ class TestNode : public td::actor::Actor {
|
|||
if (R.is_error()) {
|
||||
LOG(FATAL) << "bad server public key: " << R.move_as_error();
|
||||
}
|
||||
remote_public_key_ = R.move_as_ok();
|
||||
single_remote_public_key_ = R.move_as_ok();
|
||||
}
|
||||
void decode_public_key(td::BufferSlice b64_key) {
|
||||
auto R = [&]() -> td::Result<ton::PublicKey> {
|
||||
|
@ -437,7 +422,7 @@ class TestNode : public td::actor::Actor {
|
|||
if (R.is_error()) {
|
||||
LOG(FATAL) << "bad b64 server public key: " << R.move_as_error();
|
||||
}
|
||||
remote_public_key_ = R.move_as_ok();
|
||||
single_remote_public_key_ = R.move_as_ok();
|
||||
}
|
||||
void set_fail_timeout(td::Timestamp ts) {
|
||||
fail_timeout_ = ts;
|
||||
|
@ -475,8 +460,7 @@ class TestNode : public td::actor::Actor {
|
|||
bool envelope_send_query(td::BufferSlice query, td::Promise<td::BufferSlice> promise);
|
||||
void parse_line(td::BufferSlice data);
|
||||
|
||||
TestNode() {
|
||||
}
|
||||
TestNode() = default;
|
||||
|
||||
void run();
|
||||
};
|
||||
|
|
400
lite-client/query-utils.cpp
Normal file
400
lite-client/query-utils.cpp
Normal file
|
@ -0,0 +1,400 @@
|
|||
/*
|
||||
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/>.
|
||||
*/
|
||||
#include "query-utils.hpp"
|
||||
|
||||
#include "block-parse.h"
|
||||
#include "td/utils/overloaded.h"
|
||||
#include "tl-utils/common-utils.hpp"
|
||||
|
||||
#include "block/block-auto.h"
|
||||
#include "auto/tl/lite_api.hpp"
|
||||
#include "overlay/overlay-broadcast.hpp"
|
||||
#include "tl-utils/lite-utils.hpp"
|
||||
#include "ton/lite-tl.hpp"
|
||||
#include "ton/ton-shard.h"
|
||||
|
||||
#include <ton/ton-tl.hpp>
|
||||
|
||||
namespace liteclient {
|
||||
|
||||
using namespace ton;
|
||||
|
||||
std::string QueryInfo::to_str() const {
|
||||
td::StringBuilder sb;
|
||||
sb << "[ " << lite_query_name_by_id(query_id) << " " << shard_id.to_str();
|
||||
switch (type) {
|
||||
case t_simple:
|
||||
break;
|
||||
case t_seqno:
|
||||
sb << " seqno=" << value;
|
||||
break;
|
||||
case t_utime:
|
||||
sb << " utime=" << value;
|
||||
break;
|
||||
case t_lt:
|
||||
sb << " lt=" << value;
|
||||
break;
|
||||
case t_mc_seqno:
|
||||
sb << " mc_seqno=" << value;
|
||||
break;
|
||||
}
|
||||
sb << " ]";
|
||||
return sb.as_cslice().str();
|
||||
}
|
||||
|
||||
QueryInfo get_query_info(td::Slice data) {
|
||||
auto F = fetch_tl_object<lite_api::liteServer_query>(data, true);
|
||||
if (F.is_ok()) {
|
||||
data = F.ok()->data_;
|
||||
} else {
|
||||
fetch_tl_prefix<lite_api::liteServer_queryPrefix>(data, true).ignore();
|
||||
}
|
||||
fetch_tl_prefix<lite_api::liteServer_waitMasterchainSeqno>(data, true).ignore();
|
||||
auto Q = fetch_tl_object<lite_api::Function>(data, true);
|
||||
if (Q.is_error()) {
|
||||
return {};
|
||||
}
|
||||
return get_query_info(*Q.ok());
|
||||
}
|
||||
|
||||
QueryInfo get_query_info(const lite_api::Function& f) {
|
||||
QueryInfo info;
|
||||
info.query_id = f.get_id();
|
||||
auto from_block_id = [&](const tl_object_ptr<lite_api::tonNode_blockIdExt>& id) {
|
||||
BlockIdExt block_id = create_block_id(id);
|
||||
info.shard_id = block_id.shard_full();
|
||||
info.type = QueryInfo::t_seqno;
|
||||
info.value = block_id.seqno();
|
||||
};
|
||||
downcast_call(
|
||||
const_cast<lite_api::Function&>(f),
|
||||
td::overloaded([&](const lite_api::liteServer_getTime& q) { /* t_simple */ },
|
||||
[&](const lite_api::liteServer_getVersion& q) { /* t_simple */ },
|
||||
[&](const lite_api::liteServer_getMasterchainInfo& q) { /* t_simple */ },
|
||||
[&](const lite_api::liteServer_getMasterchainInfoExt& q) { /* t_simple */ },
|
||||
[&](const lite_api::liteServer_getBlock& q) { from_block_id(q.id_); },
|
||||
[&](const lite_api::liteServer_getBlockHeader& q) { from_block_id(q.id_); },
|
||||
[&](const lite_api::liteServer_getState& q) { from_block_id(q.id_); },
|
||||
[&](const lite_api::liteServer_getAccountState& q) {
|
||||
BlockIdExt block_id = create_block_id(q.id_);
|
||||
AccountIdPrefixFull acc_id_prefix = extract_addr_prefix(q.account_->workchain_, q.account_->id_);
|
||||
info.shard_id = acc_id_prefix.as_leaf_shard();
|
||||
// See LiteQuery::perform_getAccountState
|
||||
if (block_id.id.workchain != masterchainId) {
|
||||
info.type = QueryInfo::t_seqno;
|
||||
info.value = block_id.seqno();
|
||||
} else if (block_id.id.seqno != ~0U) {
|
||||
info.type = QueryInfo::t_mc_seqno;
|
||||
info.value = block_id.seqno();
|
||||
} else {
|
||||
info.type = QueryInfo::t_simple;
|
||||
}
|
||||
},
|
||||
[&](const lite_api::liteServer_getAccountStatePrunned& q) {
|
||||
BlockIdExt block_id = create_block_id(q.id_);
|
||||
AccountIdPrefixFull acc_id_prefix = extract_addr_prefix(q.account_->workchain_, q.account_->id_);
|
||||
info.shard_id = acc_id_prefix.as_leaf_shard();
|
||||
// See LiteQuery::perform_getAccountState
|
||||
if (block_id.id.workchain != masterchainId) {
|
||||
info.type = QueryInfo::t_seqno;
|
||||
info.value = block_id.seqno();
|
||||
} else if (block_id.id.seqno != ~0U) {
|
||||
info.type = QueryInfo::t_mc_seqno;
|
||||
info.value = block_id.seqno();
|
||||
} else {
|
||||
info.type = QueryInfo::t_simple;
|
||||
}
|
||||
},
|
||||
[&](const lite_api::liteServer_getOneTransaction& q) { from_block_id(q.id_); },
|
||||
[&](const lite_api::liteServer_getTransactions& q) {
|
||||
AccountIdPrefixFull acc_id_prefix = extract_addr_prefix(q.account_->workchain_, q.account_->id_);
|
||||
info.shard_id = acc_id_prefix.as_leaf_shard();
|
||||
info.type = QueryInfo::t_lt;
|
||||
info.value = q.lt_;
|
||||
},
|
||||
[&](const lite_api::liteServer_sendMessage& q) {
|
||||
info.type = QueryInfo::t_simple;
|
||||
auto r_root = vm::std_boc_deserialize(q.body_);
|
||||
if (r_root.is_error()) {
|
||||
return;
|
||||
}
|
||||
block::gen::CommonMsgInfo::Record_ext_in_msg_info msg_info;
|
||||
if (!tlb::unpack_cell_inexact(r_root.ok(), msg_info)) {
|
||||
return;
|
||||
}
|
||||
auto dest_prefix = block::tlb::MsgAddressInt::get_prefix(msg_info.dest);
|
||||
if (!dest_prefix.is_valid()) {
|
||||
return;
|
||||
}
|
||||
info.shard_id = dest_prefix.as_leaf_shard();
|
||||
},
|
||||
[&](const lite_api::liteServer_getShardInfo& q) { from_block_id(q.id_); },
|
||||
[&](const lite_api::liteServer_getAllShardsInfo& q) { from_block_id(q.id_); },
|
||||
[&](const lite_api::liteServer_lookupBlock& q) {
|
||||
BlockId block_id = create_block_id_simple(q.id_);
|
||||
info.shard_id = block_id.shard_full();
|
||||
// See LiteQuery::perform_lookupBlock
|
||||
if (q.mode_ & 1) {
|
||||
info.type = QueryInfo::t_seqno;
|
||||
info.value = block_id.seqno;
|
||||
} else if (q.mode_ == 2) {
|
||||
info.type = QueryInfo::t_lt;
|
||||
info.value = q.lt_;
|
||||
} else if (q.mode_ == 4) {
|
||||
info.type = QueryInfo::t_utime;
|
||||
info.value = q.utime_;
|
||||
}
|
||||
},
|
||||
[&](const lite_api::liteServer_lookupBlockWithProof& q) {
|
||||
BlockId block_id = create_block_id_simple(q.id_);
|
||||
info.shard_id = block_id.shard_full();
|
||||
// See LiteQuery::perform_lookupBlockWithProof
|
||||
if (q.mode_ & 1) {
|
||||
info.type = QueryInfo::t_seqno;
|
||||
info.value = block_id.seqno;
|
||||
} else if (q.mode_ == 2) {
|
||||
info.type = QueryInfo::t_lt;
|
||||
info.value = q.lt_;
|
||||
} else if (q.mode_ == 4) {
|
||||
info.type = QueryInfo::t_utime;
|
||||
info.value = q.utime_;
|
||||
}
|
||||
},
|
||||
[&](const lite_api::liteServer_listBlockTransactions& q) { from_block_id(q.id_); },
|
||||
[&](const lite_api::liteServer_listBlockTransactionsExt& q) { from_block_id(q.id_); },
|
||||
[&](const lite_api::liteServer_getConfigParams& q) { from_block_id(q.id_); },
|
||||
[&](const lite_api::liteServer_getConfigAll& q) { from_block_id(q.id_); },
|
||||
[&](const lite_api::liteServer_getBlockProof& q) {
|
||||
info.shard_id = ShardIdFull{masterchainId};
|
||||
BlockIdExt from = create_block_id(q.known_block_);
|
||||
// See LiteQuery::perform_getBlockProof
|
||||
if ((q.mode_ & 1) && (q.mode_ & 0x1000)) {
|
||||
BlockIdExt to = create_block_id(q.target_block_); // target_block is non-null if (mode & 1)
|
||||
info.type = QueryInfo::t_seqno;
|
||||
info.value = std::max(from.seqno(), to.seqno());
|
||||
} else {
|
||||
info.type = QueryInfo::t_simple;
|
||||
}
|
||||
},
|
||||
[&](const lite_api::liteServer_getValidatorStats& q) { from_block_id(q.id_); },
|
||||
[&](const lite_api::liteServer_runSmcMethod& q) {
|
||||
BlockIdExt block_id = create_block_id(q.id_);
|
||||
AccountIdPrefixFull acc_id_prefix = extract_addr_prefix(q.account_->workchain_, q.account_->id_);
|
||||
info.shard_id = acc_id_prefix.as_leaf_shard();
|
||||
// See LiteQuery::perform_getAccountState
|
||||
if (block_id.id.workchain != masterchainId) {
|
||||
info.type = QueryInfo::t_seqno;
|
||||
info.value = block_id.seqno();
|
||||
} else if (block_id.id.seqno != ~0U) {
|
||||
info.type = QueryInfo::t_mc_seqno;
|
||||
info.value = block_id.seqno();
|
||||
} else {
|
||||
info.type = QueryInfo::t_simple;
|
||||
}
|
||||
},
|
||||
[&](const lite_api::liteServer_getLibraries& q) { /* t_simple */ },
|
||||
[&](const lite_api::liteServer_getLibrariesWithProof& q) { from_block_id(q.id_); },
|
||||
[&](const lite_api::liteServer_getShardBlockProof& q) { from_block_id(q.id_); },
|
||||
[&](const lite_api::liteServer_nonfinal_getCandidate& q) { /* t_simple */ },
|
||||
[&](const lite_api::liteServer_nonfinal_getValidatorGroups& q) { /* t_simple */ },
|
||||
[&](const lite_api::liteServer_getOutMsgQueueSizes& q) {
|
||||
// This query is expected to be removed, as it is not fully compatible with separated liteservers
|
||||
/* t_simple */
|
||||
},
|
||||
[&](const lite_api::liteServer_getBlockOutMsgQueueSize& q) { from_block_id(q.id_); },
|
||||
[&](const lite_api::liteServer_getDispatchQueueInfo& q) { from_block_id(q.id_); },
|
||||
[&](const lite_api::liteServer_getDispatchQueueMessages& q) { from_block_id(q.id_); },
|
||||
[&](const auto&) { /* t_simple */ }));
|
||||
if (info.shard_id.workchain == masterchainId) {
|
||||
info.shard_id.shard = shardIdAll;
|
||||
}
|
||||
if (!info.shard_id.is_valid_ext()) {
|
||||
info.shard_id = ShardIdFull{masterchainId};
|
||||
info.type = QueryInfo::t_simple;
|
||||
info.value = 0;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
bool LiteServerConfig::accepts_query(const QueryInfo& query_info) const {
|
||||
if (is_full) {
|
||||
return true;
|
||||
}
|
||||
for (const Slice& s : slices) {
|
||||
if (s.accepts_query(query_info)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LiteServerConfig::Slice::accepts_query(const QueryInfo& query_info) const {
|
||||
if (unlimited) {
|
||||
for (const ShardInfo& shard : shards_from) {
|
||||
if (shard_intersects(shard.shard_id, query_info.shard_id)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (!shards_from.empty()) {
|
||||
bool from_ok = false;
|
||||
DCHECK(shards_from[0].shard_id.is_masterchain());
|
||||
for (const ShardInfo& shard : shards_from) {
|
||||
if (shard_intersects(shard.shard_id, query_info.shard_id)) {
|
||||
switch (query_info.type) {
|
||||
case QueryInfo::t_simple:
|
||||
from_ok = true;
|
||||
break;
|
||||
case QueryInfo::t_seqno:
|
||||
from_ok = shard.seqno <= query_info.value;
|
||||
break;
|
||||
case QueryInfo::t_utime:
|
||||
from_ok = shard.utime <= query_info.value;
|
||||
break;
|
||||
case QueryInfo::t_lt:
|
||||
from_ok = shard.lt <= query_info.value;
|
||||
break;
|
||||
case QueryInfo::t_mc_seqno:
|
||||
from_ok = shards_from[0].seqno <= query_info.value;
|
||||
break;
|
||||
}
|
||||
if (from_ok) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!from_ok) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!shards_to.empty()) {
|
||||
bool to_ok = false;
|
||||
DCHECK(shards_to[0].shard_id.is_masterchain());
|
||||
for (const ShardInfo& shard : shards_to) {
|
||||
if (shard_intersects(shard.shard_id, query_info.shard_id)) {
|
||||
switch (query_info.type) {
|
||||
case QueryInfo::t_simple:
|
||||
break;
|
||||
case QueryInfo::t_seqno:
|
||||
to_ok = shard.seqno >= query_info.value;
|
||||
break;
|
||||
case QueryInfo::t_utime:
|
||||
to_ok = shard.utime >= query_info.value;
|
||||
break;
|
||||
case QueryInfo::t_lt:
|
||||
to_ok = shard.lt >= query_info.value;
|
||||
break;
|
||||
case QueryInfo::t_mc_seqno:
|
||||
to_ok = shards_from[0].seqno >= query_info.value;
|
||||
break;
|
||||
}
|
||||
if (to_ok) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!to_ok) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
td::Result<std::vector<LiteServerConfig>> LiteServerConfig::parse_global_config(
|
||||
const ton_api::liteclient_config_global& config) {
|
||||
std::vector<LiteServerConfig> servers;
|
||||
for (const auto& f : config.liteservers_) {
|
||||
LiteServerConfig server;
|
||||
TRY_STATUS(server.addr.init_host_port(td::IPAddress::ipv4_to_str(f->ip_), f->port_));
|
||||
server.adnl_id = adnl::AdnlNodeIdFull{PublicKey{f->id_}};
|
||||
server.is_full = true;
|
||||
servers.push_back(std::move(server));
|
||||
}
|
||||
for (const auto& f : config.liteservers_v2_) {
|
||||
LiteServerConfig server;
|
||||
TRY_STATUS(server.addr.init_host_port(td::IPAddress::ipv4_to_str(f->ip_), f->port_));
|
||||
server.adnl_id = adnl::AdnlNodeIdFull{PublicKey{f->id_}};
|
||||
server.is_full = false;
|
||||
for (const auto& slice_obj : f->slices_) {
|
||||
Slice slice;
|
||||
td::Status S = td::Status::OK();
|
||||
downcast_call(*slice_obj,
|
||||
td::overloaded(
|
||||
[&](const ton_api::liteserver_descV2_sliceSimple& s) {
|
||||
slice.unlimited = true;
|
||||
slice.shards_from.push_back({ShardIdFull{masterchainId}, 0, 0, 0});
|
||||
for (const auto& shard_obj : s.shards_) {
|
||||
ShardIdFull shard_id = create_shard_id(shard_obj);
|
||||
if (!shard_id.is_valid_ext()) {
|
||||
S = td::Status::Error(PSTRING() << "invalid shard id " << shard_id.to_str());
|
||||
break;
|
||||
}
|
||||
if (!shard_id.is_masterchain()) {
|
||||
slice.shards_from.push_back({shard_id, 0, 0, 0});
|
||||
}
|
||||
}
|
||||
},
|
||||
[&](const ton_api::liteserver_descV2_sliceTimed& s) {
|
||||
auto parse_shards =
|
||||
[](const std::vector<tl_object_ptr<ton_api::liteserver_descV2_shardInfo>>& shard_objs,
|
||||
std::vector<ShardInfo>& shards) -> td::Status {
|
||||
if (shard_objs.empty()) {
|
||||
return td::Status::OK();
|
||||
}
|
||||
size_t i = 0;
|
||||
int mc_idx = -1;
|
||||
for (const auto& shard_obj : shard_objs) {
|
||||
ShardIdFull shard_id = create_shard_id(shard_obj->shard_id_);
|
||||
if (!shard_id.is_valid_ext()) {
|
||||
return td::Status::Error(PSTRING() << "invalid shard id " << shard_id.to_str());
|
||||
}
|
||||
if (shard_id.is_masterchain()) {
|
||||
shard_id = ShardIdFull{masterchainId};
|
||||
if (mc_idx != -1) {
|
||||
return td::Status::Error("duplicate masterchain shard in sliceTimed");
|
||||
}
|
||||
mc_idx = (int)i;
|
||||
}
|
||||
shards.push_back({shard_id, (BlockSeqno)shard_obj->seqno_, (UnixTime)shard_obj->utime_,
|
||||
(LogicalTime)shard_obj->lt_});
|
||||
++i;
|
||||
}
|
||||
if (mc_idx == -1) {
|
||||
return td::Status::Error("no masterchain shard in sliceTimed");
|
||||
}
|
||||
std::swap(shards[0], shards[mc_idx]);
|
||||
return td::Status::OK();
|
||||
};
|
||||
S = parse_shards(s.shards_from_, slice.shards_from);
|
||||
if (S.is_ok()) {
|
||||
S = parse_shards(s.shards_to_, slice.shards_to);
|
||||
}
|
||||
if (S.is_ok() && slice.shards_from.empty() && slice.shards_to.empty()) {
|
||||
S = td::Status::Error("shards_from and shards_to are both empty");
|
||||
}
|
||||
}));
|
||||
TRY_STATUS(std::move(S));
|
||||
server.slices.push_back(slice);
|
||||
}
|
||||
|
||||
servers.push_back(std::move(server));
|
||||
}
|
||||
return servers;
|
||||
}
|
||||
|
||||
} // namespace liteclient
|
89
lite-client/query-utils.hpp
Normal file
89
lite-client/query-utils.hpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
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/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "ton/ton-types.h"
|
||||
#include "auto/tl/lite_api.h"
|
||||
#include "td/utils/port/IPAddress.h"
|
||||
#include "adnl/adnl-node-id.hpp"
|
||||
|
||||
namespace liteclient {
|
||||
|
||||
struct QueryInfo {
|
||||
enum Type { t_simple, t_seqno, t_utime, t_lt, t_mc_seqno };
|
||||
int query_id = 0;
|
||||
ton::ShardIdFull shard_id{ton::masterchainId};
|
||||
Type type = t_simple;
|
||||
td::uint64 value = 0;
|
||||
/* Query types and examples:
|
||||
* t_simple - query to the recent blocks in a shard, or general info. value = 0.
|
||||
* getTime, getMasterchainInfo (shard_id = masterchain)
|
||||
* sendMessage
|
||||
* getAccountState, runSmcMethod - when no block is given
|
||||
* t_seqno - query to block with seqno in a shard. value = seqno.
|
||||
* lookupBlock by seqno
|
||||
* getBlock, getBlockHeader
|
||||
* getAccountState, runSmcMethod - when shard block is given
|
||||
* t_utime - query to a block with given unixtime in a shard. value = utime.
|
||||
* lookupBlock by utime
|
||||
* t_lt - query to a block with given lt in a shard. value = lt.
|
||||
* lookupBlock by lt
|
||||
* getTransactions
|
||||
* t_mc_seqno - query to a block in a shard, masterchain seqno is given. value = mc_seqno.
|
||||
* getAccountState, runSmcMethod - when mc block is given
|
||||
*/
|
||||
|
||||
std::string to_str() const;
|
||||
};
|
||||
|
||||
QueryInfo get_query_info(td::Slice data);
|
||||
QueryInfo get_query_info(const ton::lite_api::Function& f);
|
||||
|
||||
struct LiteServerConfig {
|
||||
private:
|
||||
struct ShardInfo {
|
||||
ton::ShardIdFull shard_id;
|
||||
ton::BlockSeqno seqno;
|
||||
ton::UnixTime utime;
|
||||
ton::LogicalTime lt;
|
||||
};
|
||||
|
||||
struct Slice {
|
||||
std::vector<ShardInfo> shards_from, shards_to;
|
||||
bool unlimited = false;
|
||||
|
||||
bool accepts_query(const QueryInfo& query_info) const;
|
||||
};
|
||||
|
||||
bool is_full = false;
|
||||
std::vector<Slice> slices;
|
||||
|
||||
public:
|
||||
ton::adnl::AdnlNodeIdFull adnl_id;
|
||||
td::IPAddress addr;
|
||||
|
||||
LiteServerConfig() = default;
|
||||
LiteServerConfig(ton::adnl::AdnlNodeIdFull adnl_id, td::IPAddress addr)
|
||||
: is_full(true), adnl_id(adnl_id), addr(addr) {
|
||||
}
|
||||
|
||||
bool accepts_query(const QueryInfo& query_info) const;
|
||||
|
||||
static td::Result<std::vector<LiteServerConfig>> parse_global_config(
|
||||
const ton::ton_api::liteclient_config_global& config);
|
||||
};
|
||||
|
||||
} // namespace liteclient
|
|
@ -68,6 +68,9 @@ void OverlayManager::register_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdS
|
|||
}
|
||||
overlays_[local_id][overlay_id] = OverlayDescription{std::move(overlay), std::move(cert)};
|
||||
|
||||
if (!with_db_) {
|
||||
return;
|
||||
}
|
||||
auto P =
|
||||
td::PromiseCreator::lambda([id = overlays_[local_id][overlay_id].overlay.get()](td::Result<DbType::GetResult> R) {
|
||||
R.ensure();
|
||||
|
@ -417,13 +420,19 @@ OverlayManager::OverlayManager(std::string db_root, td::actor::ActorId<keyring::
|
|||
}
|
||||
|
||||
void OverlayManager::start_up() {
|
||||
std::shared_ptr<td::KeyValue> kv =
|
||||
std::make_shared<td::RocksDb>(td::RocksDb::open(PSTRING() << db_root_ << "/overlays").move_as_ok());
|
||||
db_ = DbType{std::move(kv)};
|
||||
if (!db_root_.empty()) {
|
||||
with_db_ = true;
|
||||
std::shared_ptr<td::KeyValue> kv =
|
||||
std::make_shared<td::RocksDb>(td::RocksDb::open(PSTRING() << db_root_ << "/overlays").move_as_ok());
|
||||
db_ = DbType{std::move(kv)};
|
||||
}
|
||||
}
|
||||
|
||||
void OverlayManager::save_to_db(adnl::AdnlNodeIdShort local_id, OverlayIdShort overlay_id,
|
||||
std::vector<OverlayNode> nodes) {
|
||||
if (!with_db_) {
|
||||
return;
|
||||
}
|
||||
std::vector<tl_object_ptr<ton_api::overlay_node>> nodes_vec;
|
||||
for (auto &n : nodes) {
|
||||
nodes_vec.push_back(n.tl());
|
||||
|
@ -564,7 +573,7 @@ td::Result<std::shared_ptr<Certificate>> Certificate::create(tl_object_ptr<ton_a
|
|||
}
|
||||
|
||||
BroadcastCheckResult Certificate::check(PublicKeyHash node, OverlayIdShort overlay_id, td::int32 unix_time,
|
||||
td::uint32 size, bool is_fec) const {
|
||||
td::uint32 size, bool is_fec, bool skip_check_signature) const {
|
||||
if (size > max_size_) {
|
||||
return BroadcastCheckResult::Forbidden;
|
||||
}
|
||||
|
@ -575,16 +584,16 @@ BroadcastCheckResult Certificate::check(PublicKeyHash node, OverlayIdShort overl
|
|||
return BroadcastCheckResult::Forbidden;
|
||||
}
|
||||
|
||||
auto R1 = issued_by_.get<PublicKey>().create_encryptor();
|
||||
if (R1.is_error()) {
|
||||
return BroadcastCheckResult::Forbidden;
|
||||
}
|
||||
auto E = R1.move_as_ok();
|
||||
|
||||
auto B = to_sign(overlay_id, node);
|
||||
|
||||
if (E->check_signature(B.as_slice(), signature_.as_slice()).is_error()) {
|
||||
return BroadcastCheckResult::Forbidden;
|
||||
if (!skip_check_signature) {
|
||||
auto R1 = issued_by_.get<PublicKey>().create_encryptor();
|
||||
if (R1.is_error()) {
|
||||
return BroadcastCheckResult::Forbidden;
|
||||
}
|
||||
auto E = R1.move_as_ok();
|
||||
auto B = to_sign(overlay_id, node);
|
||||
if (E->check_signature(B.as_slice(), signature_.as_slice()).is_error()) {
|
||||
return BroadcastCheckResult::Forbidden;
|
||||
}
|
||||
}
|
||||
|
||||
return (flags_ & CertificateFlags::Trusted) ? BroadcastCheckResult::Allowed : BroadcastCheckResult::NeedCheck;
|
||||
|
|
|
@ -131,6 +131,7 @@ class OverlayManager : public Overlays {
|
|||
td::actor::ActorId<dht::Dht> dht_node_;
|
||||
|
||||
using DbType = td::KeyValueAsync<td::Bits256, td::BufferSlice>;
|
||||
bool with_db_ = false;
|
||||
DbType db_;
|
||||
|
||||
class AdnlCallback : public adnl::Adnl::Callback {
|
||||
|
|
|
@ -213,7 +213,7 @@ void OverlayImpl::add_peer(OverlayNode node) {
|
|||
peer_list_.peers_.insert(id, OverlayPeer(std::move(node)));
|
||||
del_some_peers();
|
||||
auto X = peer_list_.peers_.get(id);
|
||||
if (X != nullptr && peer_list_.neighbours_.size() < max_neighbours() &&
|
||||
if (X != nullptr && !X->is_neighbour() && peer_list_.neighbours_.size() < max_neighbours() &&
|
||||
!(X->get_node()->flags() & OverlayMemberFlags::DoNotReceiveBroadcasts) && X->get_id() != local_id_) {
|
||||
peer_list_.neighbours_.push_back(X->get_id());
|
||||
X->set_neighbour(true);
|
||||
|
@ -440,7 +440,7 @@ void OverlayImpl::update_neighbours(td::uint32 nodes_to_change) {
|
|||
VLOG(OVERLAY_INFO) << this << ": adding new neighbour " << X->get_id();
|
||||
peer_list_.neighbours_.push_back(X->get_id());
|
||||
X->set_neighbour(true);
|
||||
} else {
|
||||
} else if (X->is_alive()) {
|
||||
CHECK(nodes_to_change > 0);
|
||||
auto i = td::Random::fast(0, static_cast<td::uint32>(peer_list_.neighbours_.size()) - 1);
|
||||
auto Y = peer_list_.peers_.get(peer_list_.neighbours_[i]);
|
||||
|
|
|
@ -347,7 +347,12 @@ void OverlayImpl::alarm() {
|
|||
update_db_at_ = td::Timestamp::in(60.0);
|
||||
}
|
||||
|
||||
update_neighbours(0);
|
||||
if (update_neighbours_at_.is_in_past()) {
|
||||
update_neighbours(2);
|
||||
update_neighbours_at_ = td::Timestamp::in(td::Random::fast(30.0, 120.0));
|
||||
} else {
|
||||
update_neighbours(0);
|
||||
}
|
||||
alarm_timestamp() = td::Timestamp::in(1.0);
|
||||
} else {
|
||||
update_neighbours(0);
|
||||
|
@ -503,37 +508,44 @@ td::Status OverlayImpl::check_date(td::uint32 date) {
|
|||
return td::Status::OK();
|
||||
}
|
||||
|
||||
BroadcastCheckResult OverlayImpl::check_source_eligible(const PublicKeyHash &source, const Certificate *cert,
|
||||
BroadcastCheckResult OverlayImpl::check_source_eligible(const PublicKeyHash& source, const Certificate* cert,
|
||||
td::uint32 size, bool is_fec) {
|
||||
if (size == 0) {
|
||||
return BroadcastCheckResult::Forbidden;
|
||||
}
|
||||
|
||||
auto r = rules_.check_rules(source, size, is_fec);
|
||||
if (!cert || r == BroadcastCheckResult::Allowed) {
|
||||
return r;
|
||||
}
|
||||
td::Bits256 cert_hash = get_tl_object_sha_bits256(cert->tl());
|
||||
auto cached_cert = checked_certificates_cache_.find(source);
|
||||
bool cached = cached_cert != checked_certificates_cache_.end() && cached_cert->second->cert_hash == cert_hash;
|
||||
|
||||
auto r2 = cert->check(source, overlay_id_, static_cast<td::int32>(td::Clocks::system()), size, is_fec);
|
||||
auto r2 = cert->check(source, overlay_id_, static_cast<td::int32>(td::Clocks::system()), size, is_fec,
|
||||
/* skip_check_signature = */ cached);
|
||||
if (r2 != BroadcastCheckResult::Forbidden) {
|
||||
if (cached_cert == checked_certificates_cache_.end()) {
|
||||
cached_cert = checked_certificates_cache_.emplace(
|
||||
source, std::make_unique<CachedCertificate>(source, cert_hash)).first;
|
||||
} else {
|
||||
cached_cert->second->cert_hash = cert_hash;
|
||||
cached_cert->second->remove();
|
||||
}
|
||||
checked_certificates_cache_lru_.put(cached_cert->second.get());
|
||||
while (checked_certificates_cache_.size() > max_checked_certificates_cache_size_) {
|
||||
auto to_remove = (CachedCertificate*)checked_certificates_cache_lru_.get();
|
||||
CHECK(to_remove);
|
||||
to_remove->remove();
|
||||
checked_certificates_cache_.erase(to_remove->source);
|
||||
}
|
||||
}
|
||||
r2 = broadcast_check_result_min(r2, rules_.check_rules(cert->issuer_hash(), size, is_fec));
|
||||
return broadcast_check_result_max(r, r2);
|
||||
}
|
||||
|
||||
BroadcastCheckResult OverlayImpl::check_source_eligible(PublicKey source, const Certificate *cert, td::uint32 size,
|
||||
BroadcastCheckResult OverlayImpl::check_source_eligible(PublicKey source, const Certificate* cert, td::uint32 size,
|
||||
bool is_fec) {
|
||||
if (size == 0) {
|
||||
return BroadcastCheckResult::Forbidden;
|
||||
}
|
||||
auto short_id = source.compute_short_id();
|
||||
|
||||
auto r = rules_.check_rules(short_id, size, is_fec);
|
||||
if (!cert || r == BroadcastCheckResult::Allowed) {
|
||||
return r;
|
||||
}
|
||||
|
||||
auto r2 = cert->check(short_id, overlay_id_, static_cast<td::int32>(td::Clocks::system()), size, is_fec);
|
||||
r2 = broadcast_check_result_min(r2, rules_.check_rules(cert->issuer_hash(), size, is_fec));
|
||||
return broadcast_check_result_max(r, r2);
|
||||
return check_source_eligible(source.compute_short_id(), cert, size, is_fec);
|
||||
}
|
||||
|
||||
td::Status OverlayImpl::check_delivered(BroadcastHash hash) {
|
||||
|
|
|
@ -391,6 +391,7 @@ class OverlayImpl : public Overlay {
|
|||
td::Timestamp next_dht_store_query_ = td::Timestamp::in(1.0);
|
||||
td::Timestamp update_db_at_;
|
||||
td::Timestamp update_throughput_at_;
|
||||
td::Timestamp update_neighbours_at_;
|
||||
td::Timestamp last_throughput_update_;
|
||||
|
||||
std::unique_ptr<Overlays::Callback> callback_;
|
||||
|
@ -466,6 +467,19 @@ class OverlayImpl : public Overlay {
|
|||
TrafficStats total_traffic_responses, total_traffic_responses_ctr;
|
||||
|
||||
OverlayOptions opts_;
|
||||
|
||||
struct CachedCertificate : td::ListNode {
|
||||
CachedCertificate(PublicKeyHash source, td::Bits256 cert_hash)
|
||||
: source(source)
|
||||
, cert_hash(cert_hash) {
|
||||
}
|
||||
|
||||
PublicKeyHash source;
|
||||
td::Bits256 cert_hash;
|
||||
};
|
||||
std::map<PublicKeyHash, std::unique_ptr<CachedCertificate>> checked_certificates_cache_;
|
||||
td::ListNode checked_certificates_cache_lru_;
|
||||
size_t max_checked_certificates_cache_size_ = 1000;
|
||||
};
|
||||
|
||||
} // namespace overlay
|
||||
|
|
|
@ -149,7 +149,7 @@ class Certificate {
|
|||
td::BufferSlice to_sign(OverlayIdShort overlay_id, PublicKeyHash issued_to) const;
|
||||
|
||||
BroadcastCheckResult check(PublicKeyHash node, OverlayIdShort overlay_id, td::int32 unix_time, td::uint32 size,
|
||||
bool is_fec) const;
|
||||
bool is_fec, bool skip_check_signature = false) const;
|
||||
tl_object_ptr<ton_api::overlay_Certificate> tl() const;
|
||||
const PublicKey &issuer() const;
|
||||
const PublicKeyHash issuer_hash() const;
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
## 2024.10 Update
|
||||
|
||||
1. Parallel write to celldb: substantial improvement of sync and GC speed, especially with slow disks.
|
||||
2. Decreased network traffic: only first block candidate is sent optimistically.
|
||||
3. Improved channel creation and dht lookups, introduction of semi-private overlays
|
||||
4. New LS dispatch queue related methods and improvement security
|
||||
5. Fixing recursion in TVM continuations
|
||||
6. Improved stats for actors, validator sessions, perf counters, overlays, adnl, rocksdb
|
||||
7. Migration to C++20
|
||||
8. Improved block size estimates: account for depth in various structures
|
||||
9. Fix bug with `<<` optimization in FunC
|
||||
10. Minor changes of TVM which will be activated by `Config8.version >= 9`
|
||||
11. Multiple minor improvements
|
||||
|
||||
Besides the work of the core team, this update is based on the efforts of @krigga (emulator), Arayz @ TonBit (LS security, TVM recursion), @ret2happy (UB in BLST).
|
||||
## 2024.12 Update
|
||||
|
||||
1. FunC 0.4.6: Fix in try/catch handling, fixing pure flag for functions stored in variables
|
||||
2. Merging parts of Accelerator: support of specific shard monitoring, archive/liteserver slice format, support for partial liteservers, proxy liteserver, on-demand neighbour queue loading
|
||||
3. Fix of asynchronous cell loading
|
||||
4. Various improvements: caching certificates checks, better block overloading detection, `_malloc` in emulator
|
||||
5. Introduction of telemetry in overlays
|
||||
6. Use non-null local-id for tonlib-LS interaction - mitigates MitM attack.
|
||||
7. Adding `SECP256K1_XONLY_PUBKEY_TWEAK_ADD`, `SETCONTCTRMANY` instructions to TVM (activated by `Config8.version >= 9`)
|
||||
8. Private keys export via validator-engine-console - required for better backups
|
||||
9. Fix proof checking in tonlib, `hash` in `raw.Message` in tonlib_api
|
||||
|
||||
Besides the work of the core team, this update is based on the efforts of OtterSec and LayerZero (FunC), tg:@throwunless (FunC), Aviv Frenkel and Dima Kogan from Fordefi (LS MitM), @hacker-volodya (Tonlib), OKX team (async cell loading), @krigga (emulator)
|
||||
|
|
|
@ -149,4 +149,19 @@ std::enable_if_t<std::is_arithmetic<T>::value, string> to_string(const T &x) {
|
|||
return sb.as_cslice().str();
|
||||
}
|
||||
|
||||
template <class SB>
|
||||
struct LambdaPrintHelper {
|
||||
SB& sb;
|
||||
};
|
||||
template <class SB, class F>
|
||||
SB& operator<<(const LambdaPrintHelper<SB>& helper, F&& f) {
|
||||
f(helper.sb);
|
||||
return helper.sb;
|
||||
}
|
||||
struct LambdaPrint {};
|
||||
|
||||
inline LambdaPrintHelper<td::StringBuilder> operator<<(td::StringBuilder& sb, const LambdaPrint&) {
|
||||
return LambdaPrintHelper<td::StringBuilder>{sb};
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
|
||||
#define LOG(level) LOG_IMPL(level, level, true, ::td::Slice())
|
||||
#define LOG_IF(level, condition) LOG_IMPL(level, level, condition, #condition)
|
||||
#define FLOG(level) LOG_IMPL(level, level, true, ::td::Slice()) << td::LambdaPrint{} << [&](auto &sb)
|
||||
|
||||
#define VLOG(level) LOG_IMPL(DEBUG, level, true, TD_DEFINE_STR(level))
|
||||
#define VLOG_IF(level, condition) LOG_IMPL(DEBUG, level, condition, TD_DEFINE_STR(level) " " #condition)
|
||||
|
@ -95,13 +96,13 @@ inline bool no_return_func() {
|
|||
#define DUMMY_LOG_CHECK(condition) LOG_IF(NEVER, !(condition))
|
||||
|
||||
#ifdef TD_DEBUG
|
||||
#if TD_MSVC
|
||||
#if TD_MSVC
|
||||
#define LOG_CHECK(condition) \
|
||||
__analysis_assume(!!(condition)); \
|
||||
LOG_IMPL(FATAL, FATAL, !(condition), #condition)
|
||||
#else
|
||||
#else
|
||||
#define LOG_CHECK(condition) LOG_IMPL(FATAL, FATAL, !(condition) && no_return_func(), #condition)
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#define LOG_CHECK DUMMY_LOG_CHECK
|
||||
#endif
|
||||
|
@ -263,6 +264,9 @@ class Logger {
|
|||
sb_ << other;
|
||||
return *this;
|
||||
}
|
||||
LambdaPrintHelper<td::Logger> operator<<(const LambdaPrint &) {
|
||||
return LambdaPrintHelper<td::Logger>{*this};
|
||||
}
|
||||
|
||||
MutableCSlice as_cslice() {
|
||||
return sb_.as_cslice();
|
||||
|
|
|
@ -472,4 +472,45 @@ Result<TotalMemStat> get_total_mem_stat() {
|
|||
#endif
|
||||
}
|
||||
|
||||
Result<uint32> get_cpu_cores() {
|
||||
#if TD_LINUX
|
||||
uint32 result = 0;
|
||||
TRY_RESULT(fd, FileFd::open("/proc/cpuinfo", FileFd::Read));
|
||||
SCOPE_EXIT {
|
||||
fd.close();
|
||||
};
|
||||
std::string data;
|
||||
char buf[10000];
|
||||
while (true) {
|
||||
TRY_RESULT(size, fd.read(MutableSlice{buf, sizeof(buf) - 1}));
|
||||
if (size == 0) {
|
||||
break;
|
||||
}
|
||||
buf[size] = '\0';
|
||||
data += buf;
|
||||
}
|
||||
size_t i = 0;
|
||||
while (i < data.size()) {
|
||||
const char *line_begin = data.data() + i;
|
||||
while (i < data.size() && data[i] != '\n') {
|
||||
++i;
|
||||
}
|
||||
auto line_end = data.data() + i;
|
||||
++i;
|
||||
Slice line{line_begin, line_end};
|
||||
size_t j = 0;
|
||||
while (j < line.size() && line[j] != ' ' && line[j] != '\t' && line[j] != ':') {
|
||||
++j;
|
||||
}
|
||||
Slice name = line.substr(0, j);
|
||||
if (name == "processor") {
|
||||
++result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
return Status::Error("Not supported");
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue