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

Merge branch 'testnet' into block-generation

This commit is contained in:
SpyCheese 2023-07-14 16:00:39 +03:00
commit 8e85bfa6e6
26 changed files with 432 additions and 321 deletions

View file

@ -27,22 +27,6 @@ jobs:
workflow_conclusion: success workflow_conclusion: success
skip_unpack: false skip_unpack: false
# - name: Download Linux arm64 artifacts
# uses: dawidd6/action-download-artifact@v2
# with:
# workflow: ton-aarch64-linux.yml
# path: artifacts
# workflow_conclusion: success
# skip_unpack: true
#
# - name: Download and unzip Linux arm64 artifacts
# uses: dawidd6/action-download-artifact@v2
# with:
# workflow: ton-aarch64-linux.yml
# path: artifacts
# workflow_conclusion: success
# skip_unpack: false
- name: Download Mac x86-64 artifacts - name: Download Mac x86-64 artifacts
uses: dawidd6/action-download-artifact@v2 uses: dawidd6/action-download-artifact@v2
with: with:
@ -59,22 +43,6 @@ jobs:
workflow_conclusion: success workflow_conclusion: success
skip_unpack: false skip_unpack: false
# - name: Download Mac arm64 artifacts
# uses: dawidd6/action-download-artifact@v2
# with:
# workflow: ton-aarch64-macos.yml
# path: artifacts
# workflow_conclusion: success
# skip_unpack: true
#
# - name: Download and unzip Mac arm64 artifacts
# uses: dawidd6/action-download-artifact@v2
# with:
# workflow: ton-aarch64-macos.yml
# path: artifacts
# workflow_conclusion: success
# skip_unpack: false
- name: Download Windows artifacts - name: Download Windows artifacts
uses: dawidd6/action-download-artifact@v2 uses: dawidd6/action-download-artifact@v2
with: with:
@ -207,6 +175,14 @@ jobs:
asset_name: storage-daemon-cli.exe asset_name: storage-daemon-cli.exe
tag: ${{ steps.tag.outputs.TAG }} tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Windows 2019 single artifact - storage-daemon
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-win-binaries/storage-daemon.exe
asset_name: storage-daemon.exe
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Windows 2019 single artifact - tonlibjson - name: Upload Windows 2019 single artifact - tonlibjson
uses: svenstaro/upload-release-action@v2 uses: svenstaro/upload-release-action@v2
with: with:
@ -281,6 +257,14 @@ jobs:
asset_name: storage-daemon-cli-mac-x86-64 asset_name: storage-daemon-cli-mac-x86-64
tag: ${{ steps.tag.outputs.TAG }} tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Mac x86-64 single artifact - storage-daemon
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-macos-binaries/storage-daemon
asset_name: storage-daemon-mac-x86-64
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Mac x86-64 single artifact - tonlibjson - name: Upload Mac x86-64 single artifact - tonlibjson
uses: svenstaro/upload-release-action@v2 uses: svenstaro/upload-release-action@v2
with: with:
@ -355,6 +339,14 @@ jobs:
asset_name: storage-daemon-cli-linux-x86_64 asset_name: storage-daemon-cli-linux-x86_64
tag: ${{ steps.tag.outputs.TAG }} tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Linux x86-64 single artifact - storage-daemon
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/ton-x86_64-linux-binaries/storage-daemon
asset_name: storage-daemon-linux-x86_64
tag: ${{ steps.tag.outputs.TAG }}
- name: Upload Linux x86-64 single artifact - tonlibjson - name: Upload Linux x86-64 single artifact - tonlibjson
uses: svenstaro/upload-release-action@v2 uses: svenstaro/upload-release-action@v2
with: with:
@ -371,22 +363,6 @@ jobs:
asset_name: tonlib-cli-linux-x86_64 asset_name: tonlib-cli-linux-x86_64
tag: ${{ steps.tag.outputs.TAG }} tag: ${{ steps.tag.outputs.TAG }}
# - name: Upload Linux arm64 artifacts
# uses: svenstaro/upload-release-action@v2
# with:
# repo_token: ${{ secrets.GITHUB_TOKEN }}
# file: artifacts/ton-aarch64-linux-binaries.zip
# asset_name: ton-linux-arm64.zip
# tag: ${{ steps.tag.outputs.TAG }}
#
# - name: Upload Mac arm64 artifacts
# uses: svenstaro/upload-release-action@v2
# with:
# repo_token: ${{ secrets.GITHUB_TOKEN }}
# file: artifacts/ton-aarch64-macos-binaries
# asset_name: ton-mac-arm64.zip
# tag: ${{ steps.tag.outputs.TAG }}
- name: Upload WASM artifacts - name: Upload WASM artifacts
uses: svenstaro/upload-release-action@v2 uses: svenstaro/upload-release-action@v2
with: with:

View file

@ -1,57 +0,0 @@
name: Docker Ubuntu Compile arm64
on: [push,workflow_dispatch,workflow_call]
jobs:
build:
strategy:
fail-fast: false
max-parallel: 3
matrix:
arch: [arm64]
ver: [22.04, 20.04 ]
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Set output
id: vars
run: echo ::set-output name=short_ref::${GITHUB_REF#refs/*/}
- name: Check output
run: echo branch ${{ steps.vars.outputs.short_ref }}
- name: Build with docker buildx
run: |
mkdir build-${{matrix.ver}}-${{matrix.arch}}
docker buildx build --build-arg REPO=${{ github.repository }} --build-arg BRANCH=${{ steps.vars.outputs.short_ref }} --platform=linux/${{matrix.arch}} --progress=plain --load . -t build-${{matrix.ver}}-${{matrix.arch}} -f .github/script/${{matrix.arch}}-${{matrix.ver}}.Dockerfile
container_id=$(docker create --platform=linux/${{matrix.arch}} build-${{matrix.ver}}-${{matrix.arch}})
docker cp $container_id:/ton/build/dht-server/dht-server build-${{matrix.ver}}-${{matrix.arch}}/
docker cp -a $container_id:/ton/build/validator-engine/validator-engine build-${{matrix.ver}}-${{matrix.arch}}/
docker cp -a $container_id:/ton/build/validator-engine-console/validator-engine-console build-${{matrix.ver}}-${{matrix.arch}}/
docker cp -a $container_id:/ton/build/storage/storage-daemon/storage-daemon build-${{matrix.ver}}-${{matrix.arch}}/
docker cp -a $container_id:/ton/build/storage/storage-daemon/storage-daemon-cli build-${{matrix.ver}}-${{matrix.arch}}/
docker cp -a $container_id:/ton/build/crypto/fift build-${{matrix.ver}}-${{matrix.arch}}/
docker cp -a $container_id:/ton/build/crypto/func build-${{matrix.ver}}-${{matrix.arch}}/
docker cp -a $container_id:/ton/build/crypto/create-state build-${{matrix.ver}}-${{matrix.arch}}/
docker cp -a $container_id:/ton/build/blockchain-explorer/blockchain-explorer build-${{matrix.ver}}-${{matrix.arch}}/
docker cp -a $container_id:/ton/build/lite-client/lite-client build-${{matrix.ver}}-${{matrix.arch}}/
docker cp -a $container_id:/ton/build/utils/generate-random-id build-${{matrix.ver}}-${{matrix.arch}}/
docker cp -a $container_id:/ton/build/tonlib/libtonlibjson.so.0.5 build-${{matrix.ver}}-${{matrix.arch}}/tonlibjson.so
docker cp -a $container_id:/ton/crypto/smartcont build-${{matrix.ver}}-${{matrix.arch}}/
docker cp -a $container_id:/ton/crypto/fift/lib build-${{matrix.ver}}-${{matrix.arch}}/
- name: Upload artifacts
uses: actions/upload-artifact@v1
with:
name: ton-ubuntu-${{matrix.ver}}-${{matrix.arch}}
path: build-${{matrix.ver}}-${{matrix.arch}}

View file

@ -11,7 +11,7 @@ jobs:
with: with:
submodules: 'recursive' submodules: 'recursive'
- uses: cachix/install-nix-action@v18 - uses: cachix/install-nix-action@v22
with: with:
extra_nix_config: | extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}

View file

@ -56,8 +56,8 @@ jobs:
- name: Install pre-compiled libmicrohttpd Win64 - name: Install pre-compiled libmicrohttpd Win64
run: | run: |
curl -Lo libmicrohttpd-latest-w32-bin.zip https://ftpmirror.gnu.org/libmicrohttpd/libmicrohttpd-latest-w32-bin.zip 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
unzip libmicrohttpd-latest-w32-bin.zip unzip libmicrohttpd-0.9.77-w32-bin.zip
- name: Install pre-compiled Readline Win64 - name: Install pre-compiled Readline Win64
run: | run: |
@ -72,7 +72,7 @@ jobs:
echo %SODIUM_DIR% echo %SODIUM_DIR%
mkdir build mkdir build
cd build cd build
cmake -DCMAKE_BUILD_TYPE=Release -DSODIUM_USE_STATIC_LIBS=1 -DSECP256K1_INCLUDE_DIR=%root%\secp256k1\include -DSECP256K1_LIBRARY=%root%\secp256k1\bin\x64\Release\v142\static\secp256k1.lib -DREADLINE_INCLUDE_DIR=%root%\readline-5.0-1-lib\include\readline -DREADLINE_LIBRARY=%root%\readline-5.0-1-lib\lib\readline.lib -DPORTABLE=1 -DZLIB_FOUND=1 -DMHD_FOUND=1 -DMHD_LIBRARY=%root%\libmicrohttpd-0.9.75-w32-bin\x86_64\VS2019\Release-static\libmicrohttpd.lib -DMHD_INCLUDE_DIR=%root%\libmicrohttpd-0.9.75-w32-bin\x86_64\VS2019\Release-static -DZLIB_INCLUDE_DIR=%root%\zlib -DZLIB_LIBRARY=%root%\zlib\contrib\vstudio\vc14\x64\ZlibStatReleaseWithoutAsm\zlibstat.lib -DOPENSSL_FOUND=1 -DOPENSSL_INCLUDE_DIR=%root%/openssl-1.1.1j/include -DOPENSSL_CRYPTO_LIBRARY=%root%/openssl-1.1.1j/lib/libcrypto_static.lib -DCMAKE_CXX_FLAGS="/DTD_WINDOWS=1 /EHsc /bigobj /W0" .. cmake -DCMAKE_BUILD_TYPE=Release -DSODIUM_USE_STATIC_LIBS=1 -DSECP256K1_INCLUDE_DIR=%root%\secp256k1\include -DSECP256K1_LIBRARY=%root%\secp256k1\bin\x64\Release\v142\static\secp256k1.lib -DREADLINE_INCLUDE_DIR=%root%\readline-5.0-1-lib\include\readline -DREADLINE_LIBRARY=%root%\readline-5.0-1-lib\lib\readline.lib -DPORTABLE=1 -DZLIB_FOUND=1 -DMHD_FOUND=1 -DMHD_LIBRARY=%root%\libmicrohttpd-0.9.77-w32-bin\x86_64\VS2019\Release-static\libmicrohttpd.lib -DMHD_INCLUDE_DIR=%root%\libmicrohttpd-0.9.77-w32-bin\x86_64\VS2019\Release-static -DZLIB_INCLUDE_DIR=%root%\zlib -DZLIB_LIBRARY=%root%\zlib\contrib\vstudio\vc14\x64\ZlibStatReleaseWithoutAsm\zlibstat.lib -DOPENSSL_FOUND=1 -DOPENSSL_INCLUDE_DIR=%root%/openssl-1.1.1j/include -DOPENSSL_CRYPTO_LIBRARY=%root%/openssl-1.1.1j/lib/libcrypto_static.lib -DCMAKE_CXX_FLAGS="/DTD_WINDOWS=1 /EHsc /bigobj /W0" ..
cmake --build . --target storage-daemon storage-daemon-cli blockchain-explorer fift func tonlib tonlibjson tonlib-cli validator-engine lite-client pow-miner validator-engine-console generate-random-id json2tlo dht-server http-proxy rldp-http-proxy adnl-proxy create-state create-hardfork emulator --config Release cmake --build . --target storage-daemon storage-daemon-cli blockchain-explorer fift func tonlib tonlibjson tonlib-cli validator-engine lite-client pow-miner validator-engine-console generate-random-id json2tlo dht-server http-proxy rldp-http-proxy adnl-proxy create-state create-hardfork emulator --config Release
- name: Show executables - name: Show executables

View file

@ -373,10 +373,10 @@ add_library(src_parser ${PARSER_SOURCE})
target_include_directories(src_parser PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>) target_include_directories(src_parser PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
target_link_libraries(src_parser PUBLIC ton_crypto_core) target_link_libraries(src_parser PUBLIC ton_crypto_core)
add_library(ton_block ${BLOCK_SOURCE}) add_library(ton_block STATIC ${BLOCK_SOURCE})
target_include_directories(ton_block PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> target_include_directories(ton_block PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/block> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>) $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/block> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>)
target_link_libraries(ton_block PUBLIC ton_crypto_core tdutils tdactor tl_api) target_link_libraries(ton_block PUBLIC ton_crypto tdutils tdactor tl_api)
add_executable(func func/func-main.cpp ${FUNC_LIB_SOURCE}) add_executable(func func/func-main.cpp ${FUNC_LIB_SOURCE})
target_include_directories(func PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>) target_include_directories(func PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)

View file

@ -610,7 +610,7 @@ _ dns_root_addr:bits256 = ConfigParam 4; // root TON DNS resolver
burning_config#01 burning_config#01
blackhole_addr:(Maybe bits256) blackhole_addr:(Maybe bits256)
fee_burn_nom:# fee_burn_denom:# { fee_burn_nom <= fee_burn_denom } { fee_burn_denom >= 1 } = BurningConfig; fee_burn_num:# fee_burn_denom:# { fee_burn_num <= fee_burn_denom } { fee_burn_denom >= 1 } = BurningConfig;
_ BurningConfig = ConfigParam 5; _ BurningConfig = ConfigParam 5;
_ mint_new_price:Grams mint_add_price:Grams = ConfigParam 6; _ mint_new_price:Grams mint_add_price:Grams = ConfigParam 6;

View file

@ -1963,7 +1963,7 @@ BurningConfig Config::get_burning_config() const {
return {}; return {};
} }
BurningConfig c; BurningConfig c;
c.fee_burn_nom = rec.fee_burn_nom; c.fee_burn_num = rec.fee_burn_num;
c.fee_burn_denom = rec.fee_burn_denom; c.fee_burn_denom = rec.fee_burn_denom;
vm::CellSlice& addr = rec.blackhole_addr.write(); vm::CellSlice& addr = rec.blackhole_addr.write();
if (addr.fetch_long(1)) { if (addr.fetch_long(1)) {

View file

@ -506,13 +506,13 @@ class ShardConfig {
struct BurningConfig { struct BurningConfig {
td::optional<td::Bits256> blackhole_addr; td::optional<td::Bits256> blackhole_addr;
td::uint32 fee_burn_nom = 0, fee_burn_denom = 1; td::uint32 fee_burn_num = 0, fee_burn_denom = 1;
td::RefInt256 calculate_burned_fees(const td::RefInt256& x) const { td::RefInt256 calculate_burned_fees(const td::RefInt256& x) const {
if (x.is_null()) { if (x.is_null()) {
return x; return x;
} }
return x * fee_burn_nom / td::make_refint(fee_burn_denom); return x * fee_burn_num / td::make_refint(fee_burn_denom);
} }
CurrencyCollection calculate_burned_fees(const CurrencyCollection& x) const { CurrencyCollection calculate_burned_fees(const CurrencyCollection& x) const {

View file

@ -596,7 +596,7 @@ long parse_bitstring_hex_literal(unsigned char* buff, std::size_t buff_size, con
unsigned char* ptr = buff; unsigned char* ptr = buff;
const char* rptr = str; const char* rptr = str;
while (rptr < str_end) { while (rptr < str_end) {
int c = *rptr++; char c = *rptr++;
if (c == ' ' || c == '\t') { if (c == ' ' || c == '\t') {
continue; continue;
} }
@ -627,14 +627,14 @@ long parse_bitstring_hex_literal(unsigned char* buff, std::size_t buff_size, con
if (cmpl && bits) { if (cmpl && bits) {
int t = (hex_digits_count & 1) ? (0x100 + *ptr) >> 4 : (0x100 + *--ptr); int t = (hex_digits_count & 1) ? (0x100 + *ptr) >> 4 : (0x100 + *--ptr);
while (bits > 0) { while (bits > 0) {
if (t == 1) {
t = 0x100 + *--ptr;
}
--bits; --bits;
if (t & 1) { if (t & 1) {
break; break;
} }
t >>= 1; t >>= 1;
if (t == 1) {
t = 0x100 + *--ptr;
}
} }
} }
return bits; return bits;

View file

@ -246,10 +246,10 @@ SmartContract::Answer run_smartcont(SmartContract::State state, td::Ref<vm::Stac
LOG(DEBUG) << "VM accepted: " << res.accepted; LOG(DEBUG) << "VM accepted: " << res.accepted;
LOG(DEBUG) << "VM success: " << res.success; LOG(DEBUG) << "VM success: " << res.success;
} }
td::ConstBitPtr mlib = vm.get_missing_library(); auto mlib = vm.get_missing_library();
if (!mlib.is_null()) { if (mlib) {
LOG(DEBUG) << "Missing library: " << mlib.to_hex(256); LOG(DEBUG) << "Missing library: " << mlib.value().to_hex();
res.missing_library = mlib; res.missing_library = mlib.value();
} }
if (res.success) { if (res.success) {
res.new_state.data = vm.get_c4(); res.new_state.data = vm.get_c4();
@ -257,7 +257,7 @@ SmartContract::Answer run_smartcont(SmartContract::State state, td::Ref<vm::Stac
LOG(DEBUG) << "output actions:\n" LOG(DEBUG) << "output actions:\n"
<< block::gen::OutList{res.output_actions_count(res.actions)}.as_string_ref(res.actions); << block::gen::OutList{res.output_actions_count(res.actions)}.as_string_ref(res.actions);
} }
LOG_IF(ERROR, gas_credit != 0 && (res.accepted && !res.success) && mlib.is_null()) LOG_IF(ERROR, gas_credit != 0 && (res.accepted && !res.success) && !mlib)
<< "Accepted but failed with code " << res.code << "\n" << "Accepted but failed with code " << res.code << "\n"
<< res.gas_used << "\n"; << res.gas_used << "\n";
return res; return res;

View file

@ -49,7 +49,7 @@ class SmartContract : public td::CntObject {
td::Ref<vm::Cell> actions; td::Ref<vm::Cell> actions;
td::int32 code; td::int32 code;
td::int64 gas_used; td::int64 gas_used;
td::ConstBitPtr missing_library{0}; td::optional<td::Bits256> missing_library;
std::string vm_log; std::string vm_log;
static int output_actions_count(td::Ref<vm::Cell> list); static int output_actions_count(td::Ref<vm::Cell> list);
}; };

View file

@ -55,20 +55,23 @@ td::Ref<vm::Cell> WalletInterface::create_int_message(const Gift &gift) {
} else { } else {
cbi.store_zeroes(1); cbi.store_zeroes(1);
} }
cbi.store_zeroes(1);
store_gift_message(cbi, gift); store_gift_message(cbi, gift);
return cbi.finalize(); return cbi.finalize();
} }
void WalletInterface::store_gift_message(vm::CellBuilder &cb, const Gift &gift) { void WalletInterface::store_gift_message(vm::CellBuilder &cb, const Gift &gift) {
if (gift.body.not_null()) { if (gift.body.not_null()) {
auto body = vm::load_cell_slice(gift.body); auto body = vm::load_cell_slice(gift.body);
//TODO: handle error if (cb.can_extend_by(1 + body.size(), body.size_refs())) {
CHECK(cb.append_cellslice_bool(body)); CHECK(cb.store_zeroes_bool(1) && cb.append_cellslice_bool(body));
} else {
CHECK(cb.store_ones_bool(1) && cb.store_ref_bool(gift.body));
}
return; return;
} }
cb.store_zeroes(1);
if (gift.is_encrypted) { if (gift.is_encrypted) {
cb.store_long(1, 32); cb.store_long(0x2167da4b, 32);
} else { } else {
cb.store_long(0, 32); cb.store_long(0, 32);
} }

View file

@ -73,6 +73,8 @@ class WalletInterface : public SmartContract {
td::uint32 valid_until = std::numeric_limits<td::uint32>::max()) const; td::uint32 valid_until = std::numeric_limits<td::uint32>::max()) const;
static td::Ref<vm::Cell> create_int_message(const Gift &gift); static td::Ref<vm::Cell> create_int_message(const Gift &gift);
private:
static void store_gift_message(vm::CellBuilder &cb, const Gift &gift); static void store_gift_message(vm::CellBuilder &cb, const Gift &gift);
}; };

View file

@ -142,28 +142,57 @@ td::Ref<vm::Cell> CellText::do_store(td::BitSlice slice) {
} }
template <class F> template <class F>
void CellText::for_each(F &&f, CellSlice cs) { td::Status CellText::for_each(F &&f, CellSlice cs) {
if (!cs.have(8)) {
return td::Status::Error("Cell underflow");
}
auto depth = cs.fetch_ulong(8); auto depth = cs.fetch_ulong(8);
if (depth > max_chain_length) {
return td::Status::Error("Too deep string");
}
for (td::uint32 i = 0; i < depth; i++) { for (td::uint32 i = 0; i < depth; i++) {
auto size = cs.fetch_ulong(8); if (!cs.have(8)) {
f(cs.fetch_bits(td::narrow_cast<int>(size) * 8)); return td::Status::Error("Cell underflow");
}
auto size = td::narrow_cast<int>(cs.fetch_ulong(8));
if (!cs.have(size * 8)) {
return td::Status::Error("Cell underflow");
}
TRY_STATUS(f(cs.fetch_bits(size * 8)));
if (i + 1 < depth) { if (i + 1 < depth) {
if (!cs.have_refs()) {
return td::Status::Error("Cell underflow");
}
cs = vm::load_cell_slice(cs.prefetch_ref()); cs = vm::load_cell_slice(cs.prefetch_ref());
} }
} }
return td::Status::OK();
} }
td::Result<td::string> CellText::load(CellSlice &cs) { td::Result<td::string> CellText::load(CellSlice &cs) {
unsigned int size = 0; unsigned int size = 0;
for_each([&](auto slice) { size += slice.size(); }, cs); TRY_STATUS(for_each(
[&](auto slice) {
size += slice.size();
if (size > max_bytes * 8) {
return td::Status::Error("String is too long");
}
return td::Status::OK();
},
cs));
if (size % 8 != 0) { if (size % 8 != 0) {
return td::Status::Error("Size is not divisible by 8"); return td::Status::Error("Size is not divisible by 8");
} }
std::string res(size / 8, 0); std::string res(size / 8, 0);
td::BitPtr to(td::MutableSlice(res).ubegin()); td::BitPtr to(td::MutableSlice(res).ubegin());
for_each([&](auto slice) { to.concat(slice); }, cs); TRY_STATUS(for_each(
[&](auto slice) {
to.concat(slice);
return td::Status::OK();
},
cs));
CHECK(to.offs == (int)size); CHECK(to.offs == (int)size);
return res; return res;
} }

View file

@ -52,7 +52,7 @@ class CellText {
private: private:
template <class F> template <class F>
static void for_each(F &&f, CellSlice cs); static td::Status for_each(F &&f, CellSlice cs);
static td::Ref<vm::Cell> do_store(td::BitSlice slice); static td::Ref<vm::Cell> do_store(td::BitSlice slice);
}; };

View file

@ -633,7 +633,7 @@ Ref<Cell> VmState::load_library(td::ConstBitPtr hash) {
return lib; return lib;
} }
} }
missing_library = hash; missing_library = td::Bits256{hash};
return {}; return {};
} }

View file

@ -25,6 +25,7 @@
#include "vm/log.h" #include "vm/log.h"
#include "vm/continuation.h" #include "vm/continuation.h"
#include "td/utils/HashSet.h" #include "td/utils/HashSet.h"
#include "td/utils/optional.h"
namespace vm { namespace vm {
@ -97,7 +98,7 @@ class VmState final : public VmStateInterface {
td::HashSet<CellHash> loaded_cells; td::HashSet<CellHash> loaded_cells;
int stack_trace{0}, debug_off{0}; int stack_trace{0}, debug_off{0};
bool chksig_always_succeed{false}; bool chksig_always_succeed{false};
td::ConstBitPtr missing_library{0}; td::optional<td::Bits256> missing_library;
td::uint16 max_data_depth = 512; // Default value td::uint16 max_data_depth = 512; // Default value
int global_version{0}; int global_version{0};
size_t chksgn_counter = 0; size_t chksgn_counter = 0;
@ -128,25 +129,25 @@ class VmState final : public VmStateInterface {
chksgn_gas_price = 4000, chksgn_gas_price = 4000,
p256_chksgn_gas_price = 3500, p256_chksgn_gas_price = 3500,
bls_verify_gas_price = 61300, bls_verify_gas_price = 61000,
bls_aggregate_base_gas_price = -2645, bls_aggregate_base_gas_price = -2650,
bls_aggregate_element_gas_price = 4355, bls_aggregate_element_gas_price = 4350,
bls_fast_aggregate_verify_base_gas_price = 58400, bls_fast_aggregate_verify_base_gas_price = 58000,
bls_fast_aggregate_verify_element_gas_price = 2990, bls_fast_aggregate_verify_element_gas_price = 3000,
bls_aggregate_verify_base_gas_price = 37275, bls_aggregate_verify_base_gas_price = 38500,
bls_aggregate_verify_element_gas_price = 22290, bls_aggregate_verify_element_gas_price = 22500,
bls_g1_add_sub_gas_price = 3925, bls_g1_add_sub_gas_price = 3900,
bls_g1_neg_gas_price = 765, bls_g1_neg_gas_price = 750,
bls_g1_mul_gas_price = 5180, bls_g1_mul_gas_price = 5200,
bls_map_to_g1_gas_price = 2330, bls_map_to_g1_gas_price = 2350,
bls_g1_in_group_gas_price = 2930, bls_g1_in_group_gas_price = 2950,
bls_g2_add_sub_gas_price = 6100, bls_g2_add_sub_gas_price = 6100,
bls_g2_neg_gas_price = 1550, bls_g2_neg_gas_price = 1550,
bls_g2_mul_gas_price = 10530, bls_g2_mul_gas_price = 10550,
bls_map_to_g2_gas_price = 7970, bls_map_to_g2_gas_price = 7950,
bls_g2_in_group_gas_price = 4255, bls_g2_in_group_gas_price = 4250,
// multiexp gas = base + n * coef1 + n/floor(max(log2(n), 4)) * coef2 // multiexp gas = base + n * coef1 + n/floor(max(log2(n), 4)) * coef2
bls_g1_multiexp_base_gas_price = 11375, bls_g1_multiexp_base_gas_price = 11375,
@ -157,7 +158,7 @@ class VmState final : public VmStateInterface {
bls_g2_multiexp_coef2_gas_price = 22840, bls_g2_multiexp_coef2_gas_price = 22840,
bls_pairing_base_gas_price = 20000, bls_pairing_base_gas_price = 20000,
bls_pairing_element_gas_price = 11770 bls_pairing_element_gas_price = 11800
}; };
VmState(); VmState();
VmState(Ref<CellSlice> _code); VmState(Ref<CellSlice> _code);
@ -383,7 +384,7 @@ class VmState final : public VmStateInterface {
Ref<OrdCont> ref_to_cont(Ref<Cell> cell) const { Ref<OrdCont> ref_to_cont(Ref<Cell> cell) const {
return td::make_ref<OrdCont>(load_cell_slice_ref(std::move(cell)), get_cp()); return td::make_ref<OrdCont>(load_cell_slice_ref(std::move(cell)), get_cp());
} }
td::ConstBitPtr get_missing_library() const { td::optional<td::Bits256> get_missing_library() const {
return missing_library; return missing_library;
} }
void set_max_data_depth(td::uint16 depth) { void set_max_data_depth(td::uint16 depth) {

View file

@ -522,10 +522,10 @@ const char *tvm_emulator_run_get_method(void *tvm_emulator, int method_id, const
json_obj("gas_used", std::to_string(result.gas_used)); json_obj("gas_used", std::to_string(result.gas_used));
json_obj("vm_exit_code", result.code); json_obj("vm_exit_code", result.code);
json_obj("vm_log", result.vm_log); json_obj("vm_log", result.vm_log);
if (result.missing_library.is_null()) { if (!result.missing_library) {
json_obj("missing_library", td::JsonNull()); json_obj("missing_library", td::JsonNull());
} else { } else {
json_obj("missing_library", td::Bits256(result.missing_library).to_hex()); json_obj("missing_library", result.missing_library.value().to_hex());
} }
json_obj.leave(); json_obj.leave();
@ -548,10 +548,10 @@ const char *tvm_emulator_send_external_message(void *tvm_emulator, const char *m
json_obj("vm_exit_code", result.code); json_obj("vm_exit_code", result.code);
json_obj("accepted", td::JsonBool(result.accepted)); json_obj("accepted", td::JsonBool(result.accepted));
json_obj("vm_log", result.vm_log); json_obj("vm_log", result.vm_log);
if (result.missing_library.is_null()) { if (!result.missing_library) {
json_obj("missing_library", td::JsonNull()); json_obj("missing_library", td::JsonNull());
} else { } else {
json_obj("missing_library", td::Bits256(result.missing_library).to_hex()); json_obj("missing_library", result.missing_library.value().to_hex());
} }
if (result.actions.is_null()) { if (result.actions.is_null()) {
json_obj("actions", td::JsonNull()); json_obj("actions", td::JsonNull());
@ -581,10 +581,10 @@ const char *tvm_emulator_send_internal_message(void *tvm_emulator, const char *m
json_obj("vm_exit_code", result.code); json_obj("vm_exit_code", result.code);
json_obj("accepted", td::JsonBool(result.accepted)); json_obj("accepted", td::JsonBool(result.accepted));
json_obj("vm_log", result.vm_log); json_obj("vm_log", result.vm_log);
if (result.missing_library.is_null()) { if (!result.missing_library) {
json_obj("missing_library", td::JsonNull()); json_obj("missing_library", td::JsonNull());
} else { } else {
json_obj("missing_library", td::Bits256(result.missing_library).to_hex()); json_obj("missing_library", result.missing_library.value().to_hex());
} }
if (result.actions.is_null()) { if (result.actions.is_null()) {
json_obj("actions", td::JsonNull()); json_obj("actions", td::JsonNull());

View file

@ -68,13 +68,23 @@ void TorrentHeader::parse(ParserT &parser) {
parser.set_error("Unknown fec type"); parser.set_error("Unknown fec type");
return; return;
} }
name_index.resize(files_count); name_index.clear();
for (auto &x : name_index) { for (size_t i = 0; i < files_count; ++i) {
td::uint64 x;
parse(x, parser); parse(x, parser);
if (parser.get_error()) {
return;
} }
data_index.resize(files_count); name_index.push_back(x);
for (auto &x : data_index) { }
data_index.clear();
for (size_t i = 0; i < files_count; ++i) {
td::uint64 x;
parse(x, parser); parse(x, parser);
if (parser.get_error()) {
return;
}
data_index.push_back(x);
} }
names = parser.template fetch_string_raw<std::string>(tot_names_size); names = parser.template fetch_string_raw<std::string>(tot_names_size);
} }

View file

@ -184,6 +184,10 @@ smc.runResult gas_used:int53 stack:vector<tvm.StackEntry> exit_code:int32 = smc.
smc.libraryEntry hash:int256 data:bytes = smc.LibraryEntry; smc.libraryEntry hash:int256 data:bytes = smc.LibraryEntry;
smc.libraryResult result:(vector smc.libraryEntry) = smc.LibraryResult; smc.libraryResult result:(vector smc.libraryEntry) = smc.LibraryResult;
smc.libraryQueryExt.one hash:int256 = smc.LibraryQueryExt;
smc.libraryQueryExt.scanBoc boc:bytes max_libs:int32 = smc.LibraryQueryExt;
smc.libraryResultExt dict_boc:bytes libs_ok:(vector int256) libs_not_found:(vector int256) = smc.LibraryResultExt;
updateSendLiteServerQuery id:int64 data:bytes workchain:int32 shard:int64 = Update; updateSendLiteServerQuery id:int64 data:bytes workchain:int32 shard:int64 = Update;
updateSyncState sync_state:SyncState = Update; updateSyncState sync_state:SyncState = Update;
@ -306,6 +310,7 @@ smc.getState id:int53 = tvm.Cell;
smc.runGetMethod id:int53 method:smc.MethodId stack:vector<tvm.StackEntry> = smc.RunResult; smc.runGetMethod id:int53 method:smc.MethodId stack:vector<tvm.StackEntry> = smc.RunResult;
smc.getLibraries library_list:(vector int256) = smc.LibraryResult; smc.getLibraries library_list:(vector int256) = smc.LibraryResult;
smc.getLibrariesExt list:(vector smc.LibraryQueryExt) = smc.LibraryResultExt;
dns.resolve account_address:accountAddress name:string category:int256 ttl:int32 = dns.Resolved; dns.resolve account_address:accountAddress name:string category:int256 ttl:int32 = dns.Resolved;

Binary file not shown.

View file

@ -60,6 +60,7 @@
#include "td/utils/port/path.h" #include "td/utils/port/path.h"
#include "common/util.h" #include "common/util.h"
#include "td/actor/MultiPromise.h"
template <class Type> template <class Type>
using lite_api_ptr = ton::lite_api::object_ptr<Type>; using lite_api_ptr = ton::lite_api::object_ptr<Type>;
@ -100,6 +101,11 @@ struct RemoteRunSmcMethodReturnType {
// libs // libs
}; };
struct ScanAndLoadGlobalLibs {
td::Ref<vm::Cell> root;
using ReturnType = vm::Dictionary;
};
struct GetPrivateKey { struct GetPrivateKey {
KeyStorage::InputKey input_key; KeyStorage::InputKey input_key;
using ReturnType = KeyStorage::PrivateKey; using ReturnType = KeyStorage::PrivateKey;
@ -1668,11 +1674,11 @@ class GetShardBlockProof : public td::actor::Actor {
auto to_lite_api(const tonlib_api::ton_blockIdExt& blk) -> td::Result<lite_api_ptr<ton::lite_api::tonNode_blockIdExt>>; auto to_lite_api(const tonlib_api::ton_blockIdExt& blk) -> td::Result<lite_api_ptr<ton::lite_api::tonNode_blockIdExt>>;
auto to_tonlib_api(const ton::lite_api::liteServer_transactionId& txid) -> tonlib_api_ptr<tonlib_api::blocks_shortTxId>; auto to_tonlib_api(const ton::lite_api::liteServer_transactionId& txid) -> tonlib_api_ptr<tonlib_api::blocks_shortTxId>;
class RunEmulator : public td::actor::Actor { class RunEmulator : public TonlibQueryActor {
public: public:
RunEmulator(ExtClientRef ext_client_ref, int_api::GetAccountStateByTransaction request, RunEmulator(ExtClientRef ext_client_ref, int_api::GetAccountStateByTransaction request,
td::actor::ActorShared<> parent, td::Promise<td::unique_ptr<AccountState>>&& promise) td::actor::ActorShared<TonlibClient> parent, td::Promise<td::unique_ptr<AccountState>>&& promise)
: request_(std::move(request)), parent_(std::move(parent)), promise_(std::move(promise)) { : TonlibQueryActor(std::move(parent)), request_(std::move(request)), promise_(std::move(promise)) {
client_.set_client(ext_client_ref); client_.set_client(ext_client_ref);
} }
@ -1686,7 +1692,6 @@ class RunEmulator : public td::actor::Actor {
ExtClient client_; ExtClient client_;
int_api::GetAccountStateByTransaction request_; int_api::GetAccountStateByTransaction request_;
td::actor::ActorShared<> parent_;
td::Promise<td::unique_ptr<AccountState>> promise_; td::Promise<td::unique_ptr<AccountState>> promise_;
std::map<td::int64, td::actor::ActorOwn<>> actors_; std::map<td::int64, td::actor::ActorOwn<>> actors_;
@ -1695,6 +1700,7 @@ class RunEmulator : public td::actor::Actor {
FullBlockId block_id_; FullBlockId block_id_;
td::Ref<vm::Cell> mc_state_root_; // ^ShardStateUnsplit td::Ref<vm::Cell> mc_state_root_; // ^ShardStateUnsplit
td::unique_ptr<AccountState> account_state_; td::unique_ptr<AccountState> account_state_;
vm::Dictionary global_libraries_{256};
std::vector<td::Ref<vm::Cell>> transactions_; // std::vector<^Transaction> std::vector<td::Ref<vm::Cell>> transactions_; // std::vector<^Transaction>
size_t count_{0}; size_t count_{0};
@ -1805,6 +1811,8 @@ class RunEmulator : public td::actor::Actor {
if (bTxes->incomplete_) { if (bTxes->incomplete_) {
self->check(self->get_transactions(last_lt)); self->check(self->get_transactions(last_lt));
} else {
self->check(td::Status::Error("Transaction not found"));
} }
}); });
return td::Status::OK(); return td::Status::OK();
@ -1854,6 +1862,16 @@ class RunEmulator : public td::actor::Actor {
check(account_state.move_as_error()); check(account_state.move_as_error());
} else { } else {
account_state_ = account_state.move_as_ok(); account_state_ = account_state.move_as_ok();
send_query(int_api::ScanAndLoadGlobalLibs{account_state_->get_raw_state()},
[self = this](td::Result<vm::Dictionary> R) { self->set_global_libraries(std::move(R)); });
}
}
void set_global_libraries(td::Result<vm::Dictionary> R) {
if (R.is_error()) {
check(R.move_as_error());
} else {
global_libraries_ = R.move_as_ok();
inc(); inc();
} }
} }
@ -1879,6 +1897,7 @@ class RunEmulator : public td::actor::Actor {
return; return;
} }
try {
auto r_config = block::ConfigInfo::extract_config(mc_state_root_, 0b11'11111111); auto r_config = block::ConfigInfo::extract_config(mc_state_root_, 0b11'11111111);
if (r_config.is_error()) { if (r_config.is_error()) {
check(r_config.move_as_error()); check(r_config.move_as_error());
@ -1886,13 +1905,6 @@ class RunEmulator : public td::actor::Actor {
} }
std::unique_ptr<block::ConfigInfo> config = r_config.move_as_ok(); std::unique_ptr<block::ConfigInfo> config = r_config.move_as_ok();
block::gen::ShardStateUnsplit::Record shard_state;
if (!tlb::unpack_cell(mc_state_root_, shard_state)) {
check(td::Status::Error("Failed to unpack masterchain state"));
return;
}
vm::Dictionary libraries(shard_state.r1.libraries->prefetch_ref(), 256);
auto r_shard_account = account_state_->to_shardAccountCellSlice(); auto r_shard_account = account_state_->to_shardAccountCellSlice();
if (r_shard_account.is_error()) { if (r_shard_account.is_error()) {
check(r_shard_account.move_as_error()); check(r_shard_account.move_as_error());
@ -1914,11 +1926,13 @@ class RunEmulator : public td::actor::Actor {
check(prev_blocks_info.move_as_error()); check(prev_blocks_info.move_as_error());
return; return;
} }
vm::Dictionary libraries = global_libraries_;
emulator::TransactionEmulator trans_emulator(std::move(*config)); emulator::TransactionEmulator trans_emulator(std::move(*config));
trans_emulator.set_prev_blocks_info(prev_blocks_info.move_as_ok()); trans_emulator.set_prev_blocks_info(prev_blocks_info.move_as_ok());
trans_emulator.set_libs(std::move(libraries)); trans_emulator.set_libs(std::move(libraries));
trans_emulator.set_rand_seed(block_id_.rand_seed); trans_emulator.set_rand_seed(block_id_.rand_seed);
td::Result<emulator::TransactionEmulator::EmulationChain> emulation_result = trans_emulator.emulate_transactions_chain(std::move(account), std::move(transactions_)); td::Result<emulator::TransactionEmulator::EmulationChain> emulation_result =
trans_emulator.emulate_transactions_chain(std::move(account), std::move(transactions_));
if (emulation_result.is_error()) { if (emulation_result.is_error()) {
promise_.set_error(emulation_result.move_as_error()); promise_.set_error(emulation_result.move_as_error());
@ -1942,6 +1956,10 @@ class RunEmulator : public td::actor::Actor {
promise_.set_value(td::make_unique<AccountState>(address, std::move(raw), 0)); promise_.set_value(td::make_unique<AccountState>(address, std::move(raw), 0));
} }
} catch (vm::VmVirtError& err) {
check(td::Status::Error(PSLICE() << "virtualization error while emulating transaction: " << err.get_msg()));
return;
}
stopped_ = true; stopped_ = true;
try_stop(); try_stop();
} }
@ -2877,8 +2895,9 @@ struct ToRawTransactions {
auto get_data = [body = std::move(body), body_cell = std::move(body_cell), auto get_data = [body = std::move(body), body_cell = std::move(body_cell),
init_state_cell = std::move(init_state_cell), this](td::Slice salt) mutable { init_state_cell = std::move(init_state_cell), this](td::Slice salt) mutable {
tonlib_api::object_ptr<tonlib_api::msg_Data> data; tonlib_api::object_ptr<tonlib_api::msg_Data> data;
if (try_decode_messages_ && body->size() >= 32 && static_cast<td::uint32>(body->prefetch_long(32)) <= 1) { if (try_decode_messages_ && body->size() >= 32) {
auto type = body.write().fetch_long(32); auto type = static_cast<td::uint32>(body.write().fetch_long(32));
if (type == 0 || type == 0x2167da4b) {
td::Status status; td::Status status;
auto r_body_message = vm::CellString::load(body.write()); auto r_body_message = vm::CellString::load(body.write());
@ -2904,6 +2923,7 @@ struct ToRawTransactions {
} }
} }
} }
}
if (!data) { if (!data) {
data = tonlib_api::make_object<tonlib_api::msg_dataRaw>(to_bytes(std::move(body_cell)), data = tonlib_api::make_object<tonlib_api::msg_dataRaw>(to_bytes(std::move(body_cell)),
to_bytes(std::move(init_state_cell))); to_bytes(std::move(init_state_cell)));
@ -3930,9 +3950,9 @@ class GenericCreateSendGrams : public TonlibQueryActor {
} }
} }
// if (!o_public_key) { // todo: (tolya-yanot) temporary disable msg comment encryption (The exchanges/payment services needs to read the comment of incoming messages). This will be uncommented when a general standard is developed. if (!o_public_key) {
return TonlibError::MessageEncryption("Get public key (in destination)"); return TonlibError::MessageEncryption("Cannot get public key of destination (possibly unknown wallet type)");
// } }
auto addr = source_->get_address(); auto addr = source_->get_address();
addr.bounceable = true; addr.bounceable = true;
@ -4278,7 +4298,7 @@ auto to_tonlib_api(const vm::StackEntry& entry, int& limit) -> td::Result<tonlib
return tonlib_api::make_object<tonlib_api::tvm_stackEntryNumber>( return tonlib_api::make_object<tonlib_api::tvm_stackEntryNumber>(
tonlib_api::make_object<tonlib_api::tvm_numberDecimal>(dec_string(entry.as_int()))); tonlib_api::make_object<tonlib_api::tvm_numberDecimal>(dec_string(entry.as_int())));
case vm::StackEntry::Type::t_slice: case vm::StackEntry::Type::t_slice:
return tonlib_api::make_object<tonlib_api::tvm_stackEntryCell>(tonlib_api::make_object<tonlib_api::tvm_cell>( return tonlib_api::make_object<tonlib_api::tvm_stackEntrySlice>(tonlib_api::make_object<tonlib_api::tvm_slice>(
to_bytes(vm::CellBuilder().append_cellslice(entry.as_slice()).finalize()))); to_bytes(vm::CellBuilder().append_cellslice(entry.as_slice()).finalize())));
case vm::StackEntry::Type::t_cell: case vm::StackEntry::Type::t_cell:
return tonlib_api::make_object<tonlib_api::tvm_stackEntryCell>( return tonlib_api::make_object<tonlib_api::tvm_stackEntryCell>(
@ -4363,9 +4383,9 @@ td::Result<vm::StackEntry> from_tonlib_api(tonlib_api::tvm_StackEntry& entry) {
})); }));
} }
void deep_library_search(std::set<td::Bits256>& set, std::set<vm::Cell::Hash>& visited, vm::Dictionary& libs, void deep_library_search(std::set<td::Bits256>& set, std::set<vm::Cell::Hash>& visited,
td::Ref<vm::Cell> cell, int depth) { vm::Dictionary& libs, td::Ref<vm::Cell> cell, int depth, size_t max_libs = 16) {
if (depth <= 0 || set.size() >= 16 || visited.size() >= 256) { if (depth <= 0 || set.size() >= max_libs || visited.size() >= 256) {
return; return;
} }
auto ins = visited.insert(cell->get_hash()); auto ins = visited.insert(cell->get_hash());
@ -4449,6 +4469,72 @@ td::Status TonlibClient::do_request(const tonlib_api::smc_getLibraries& request,
return td::Status::OK(); return td::Status::OK();
} }
td::Status TonlibClient::do_request(const tonlib_api::smc_getLibrariesExt& request,
td::Promise<object_ptr<tonlib_api::smc_libraryResultExt>>&& promise) {
std::set<td::Bits256> request_libs;
for (auto& x : request.list_) {
td::Status status = td::Status::OK();
downcast_call(*x, td::overloaded([&](tonlib_api::smc_libraryQueryExt_one& one) { request_libs.insert(one.hash_); },
[&](tonlib_api::smc_libraryQueryExt_scanBoc& scan) {
std::set<vm::Cell::Hash> visited;
vm::Dictionary empty{256};
td::Result<td::Ref<vm::Cell>> r_cell = vm::std_boc_deserialize(scan.boc_);
if (r_cell.is_error()) {
status = r_cell.move_as_error();
return;
}
size_t max_libs = scan.max_libs_ < 0 ? (1 << 30) : (size_t)scan.max_libs_;
std::set<td::Bits256> new_libs;
deep_library_search(new_libs, visited, empty, r_cell.move_as_ok(), 1024,
max_libs);
request_libs.insert(new_libs.begin(), new_libs.end());
}));
TRY_STATUS(std::move(status));
}
std::vector<td::Bits256> not_cached;
for (const td::Bits256& h : request_libs) {
if (libraries.lookup(h).is_null()) {
not_cached.push_back(h);
}
}
td::MultiPromise mp;
auto ig = mp.init_guard();
LOG(DEBUG) << "Requesting " << not_cached.size() << " libraries";
for (size_t i = 0; i < not_cached.size(); i += 16) {
size_t r = std::min(i + 16, not_cached.size());
client_.send_query(
ton::lite_api::liteServer_getLibraries(
std::vector<td::Bits256>(not_cached.begin() + i, not_cached.begin() + r)),
[self = this, promise = ig.get_promise()](
td::Result<ton::lite_api::object_ptr<ton::lite_api::liteServer_libraryResult>> r_libraries) mutable {
self->process_new_libraries(std::move(r_libraries));
promise.set_result(td::Unit());
});
}
ig.add_promise(promise.wrap([self = this, libs = std::move(request_libs)](td::Unit&&) {
vm::Dictionary dict{256};
std::vector<td::Bits256> libs_ok, libs_not_found;
for (const auto& h : libs) {
auto lib = self->libraries.lookup_ref(h);
if (lib.is_null()) {
libs_not_found.push_back(h);
} else {
libs_ok.push_back(h);
dict.set_ref(h, lib);
}
}
td::BufferSlice dict_boc;
if (!dict.is_empty()) {
dict_boc = vm::std_boc_serialize(dict.get_root_cell()).move_as_ok();
}
return ton::create_tl_object<tonlib_api::smc_libraryResultExt>(dict_boc.as_slice().str(), std::move(libs_ok),
std::move(libs_not_found));
}));
return td::Status::OK();
}
td::Status TonlibClient::do_request(const tonlib_api::smc_runGetMethod& request, td::Status TonlibClient::do_request(const tonlib_api::smc_runGetMethod& request,
td::Promise<object_ptr<tonlib_api::smc_runResult>>&& promise) { td::Promise<object_ptr<tonlib_api::smc_runResult>>&& promise) {
auto it = smcs_.find(request.id_); auto it = smcs_.find(request.id_);
@ -4490,19 +4576,35 @@ td::Status TonlibClient::do_request(const tonlib_api::smc_runGetMethod& request,
ton::lite_api::liteServer_getLibraries(std::move(libraryList)), ton::lite_api::liteServer_getLibraries(std::move(libraryList)),
[self, smc = std::move(smc), args = std::move(args), promise = std::move(promise)]( [self, smc = std::move(smc), args = std::move(args), promise = std::move(promise)](
td::Result<ton::lite_api::object_ptr<ton::lite_api::liteServer_libraryResult>> r_libraries) mutable { td::Result<ton::lite_api::object_ptr<ton::lite_api::liteServer_libraryResult>> r_libraries) mutable {
self->process_new_libraries(std::move(r_libraries));
self->perform_smc_execution(std::move(smc), std::move(args), std::move(promise));
});
} else {
self->perform_smc_execution(std::move(smc), std::move(args), std::move(promise));
}
}
else {
self->perform_smc_execution(std::move(smc), std::move(args), std::move(promise));
}
});
return td::Status::OK();
}
void TonlibClient::process_new_libraries(
td::Result<ton::lite_api::object_ptr<ton::lite_api::liteServer_libraryResult>> r_libraries) {
if (r_libraries.is_error()) { if (r_libraries.is_error()) {
LOG(WARNING) << "cannot obtain found libraries: " << r_libraries.move_as_error().to_string(); LOG(WARNING) << "cannot obtain found libraries: " << r_libraries.move_as_error().to_string();
} else { } else {
auto libraries = r_libraries.move_as_ok(); auto new_libraries = r_libraries.move_as_ok();
bool updated = false; bool updated = false;
for (auto& lr : libraries->result_) { for (auto& lr : new_libraries->result_) {
auto contents = vm::std_boc_deserialize(lr->data_); auto contents = vm::std_boc_deserialize(lr->data_);
if (contents.is_ok() && contents.ok().not_null()) { if (contents.is_ok() && contents.ok().not_null()) {
if (contents.ok()->get_hash().bits().compare(lr->hash_.cbits(), 256)) { if (contents.ok()->get_hash().bits().compare(lr->hash_.cbits(), 256)) {
LOG(WARNING) << "hash mismatch for library " << lr->hash_.to_hex(); LOG(WARNING) << "hash mismatch for library " << lr->hash_.to_hex();
continue; continue;
} }
self->libraries.set_ref(lr->hash_, contents.move_as_ok()); libraries.set_ref(lr->hash_, contents.move_as_ok());
updated = true; updated = true;
LOG(DEBUG) << "registered library " << lr->hash_.to_hex(); LOG(DEBUG) << "registered library " << lr->hash_.to_hex();
} else { } else {
@ -4510,19 +4612,9 @@ td::Status TonlibClient::do_request(const tonlib_api::smc_runGetMethod& request,
} }
} }
if (updated) { if (updated) {
self->store_libs_to_disk(); store_libs_to_disk();
} }
} }
self->perform_smc_execution(std::move(smc), std::move(args), std::move(promise));
});
} else {
self->perform_smc_execution(std::move(smc), std::move(args), std::move(promise));
}
} else {
self->perform_smc_execution(std::move(smc), std::move(args), std::move(promise));
}
});
return td::Status::OK();
} }
void TonlibClient::perform_smc_execution(td::Ref<ton::SmartContract> smc, ton::SmartContract::Args args, void TonlibClient::perform_smc_execution(td::Ref<ton::SmartContract> smc, ton::SmartContract::Args args,
@ -4539,19 +4631,18 @@ void TonlibClient::perform_smc_execution(td::Ref<ton::SmartContract> smc, ton::S
} }
auto res_stack = R.move_as_ok(); auto res_stack = R.move_as_ok();
if (res.missing_library.not_null()) { if (res.missing_library) {
td::Bits256 hash = res.missing_library; td::Bits256 hash = res.missing_library.value();
LOG(DEBUG) << "Requesting missing library: " << hash.to_hex(); LOG(DEBUG) << "Requesting missing library: " << hash.to_hex();
std::vector<td::Bits256> req = {std::move(hash)}; std::vector<td::Bits256> req = {hash};
client_.send_query( client_.send_query(ton::lite_api::liteServer_getLibraries(std::move(req)),
ton::lite_api::liteServer_getLibraries(std::move(req)), [self = this, res = std::move(res), res_stack = std::move(res_stack), hash,
[self = this, res = std::move(res), res_stack = std::move(res_stack), hash = std::move(hash), smc = std::move(smc), args = std::move(args), promise = std::move(promise)]
smc = std::move(smc), args = std::move(args), promise = std::move(promise)]( (td::Result<ton::lite_api::object_ptr<ton::lite_api::liteServer_libraryResult>> r_libraries) mutable
td::Result<ton::lite_api::object_ptr<ton::lite_api::liteServer_libraryResult>> r_libraries) mutable { {
if (r_libraries.is_error()) { if (r_libraries.is_error()) {
LOG(WARNING) << "cannot obtain missing library: " << r_libraries.move_as_error().to_string(); LOG(WARNING) << "cannot obtain missing library: " << r_libraries.move_as_error().to_string();
promise.set_value( promise.set_value(tonlib_api::make_object<tonlib_api::smc_runResult>(res.gas_used, std::move(res_stack), res.code));
tonlib_api::make_object<tonlib_api::smc_runResult>(res.gas_used, std::move(res_stack), res.code));
return; return;
} }
bool found = false, updated = false; bool found = false, updated = false;
@ -4576,13 +4667,13 @@ void TonlibClient::perform_smc_execution(td::Ref<ton::SmartContract> smc, ton::S
} }
if (!found) { if (!found) {
LOG(WARNING) << "cannot obtain library " << hash.to_hex() << ", it may not exist"; LOG(WARNING) << "cannot obtain library " << hash.to_hex() << ", it may not exist";
promise.set_value( promise.set_value(tonlib_api::make_object<tonlib_api::smc_runResult>(res.gas_used, std::move(res_stack), res.code));
tonlib_api::make_object<tonlib_api::smc_runResult>(res.gas_used, std::move(res_stack), res.code));
} else { } else {
self->perform_smc_execution(std::move(smc), std::move(args), std::move(promise)); self->perform_smc_execution(std::move(smc), std::move(args), std::move(promise));
} }
}); });
} else { }
else {
promise.set_value(tonlib_api::make_object<tonlib_api::smc_runResult>(res.gas_used, std::move(res_stack), res.code)); promise.set_value(tonlib_api::make_object<tonlib_api::smc_runResult>(res.gas_used, std::move(res_stack), res.code));
} }
} }
@ -5608,6 +5699,30 @@ void TonlibClient::store_libs_to_disk() { // NB: Dictionary.get_root_cell does
LOG(DEBUG) << "stored libraries to disk cache"; LOG(DEBUG) << "stored libraries to disk cache";
} }
td::Status TonlibClient::do_request(const int_api::ScanAndLoadGlobalLibs& request, td::Promise<vm::Dictionary> promise) {
if (request.root.is_null()) {
promise.set_value(vm::Dictionary{256});
return td::Status::OK();
}
std::set<td::Bits256> to_load;
std::set<vm::Cell::Hash> visited;
deep_library_search(to_load, visited, libraries, request.root, 24);
if (to_load.empty()) {
promise.set_result(libraries);
return td::Status::OK();
}
std::vector<td::Bits256> to_load_list(to_load.begin(), to_load.end());
LOG(DEBUG) << "Requesting found libraries in account state (" << to_load_list.size() << ")";
client_.send_query(
ton::lite_api::liteServer_getLibraries(std::move(to_load_list)),
[self = this, promise = std::move(promise)](
td::Result<ton::lite_api::object_ptr<ton::lite_api::liteServer_libraryResult>> r_libraries) mutable {
self->process_new_libraries(std::move(r_libraries));
promise.set_result(self->libraries);
});
return td::Status::OK();
}
template <class P> template <class P>
td::Status TonlibClient::do_request(const tonlib_api::runTests& request, P&&) { td::Status TonlibClient::do_request(const tonlib_api::runTests& request, P&&) {
UNREACHABLE(); UNREACHABLE();

View file

@ -46,6 +46,7 @@ struct GetDnsResolver;
struct SendMessage; struct SendMessage;
struct RemoteRunSmcMethod; struct RemoteRunSmcMethod;
struct RemoteRunSmcMethodReturnType; struct RemoteRunSmcMethodReturnType;
struct ScanAndLoadGlobalLibs;
inline std::string to_string(const int_api::SendMessage&) { inline std::string to_string(const int_api::SendMessage&) {
return "Send message"; return "Send message";
@ -331,6 +332,9 @@ class TonlibClient : public td::actor::Actor {
td::Status do_request(const tonlib_api::smc_getLibraries& request, td::Status do_request(const tonlib_api::smc_getLibraries& request,
td::Promise<object_ptr<tonlib_api::smc_libraryResult>>&& promise); td::Promise<object_ptr<tonlib_api::smc_libraryResult>>&& promise);
td::Status do_request(const tonlib_api::smc_getLibrariesExt& request,
td::Promise<object_ptr<tonlib_api::smc_libraryResultExt>>&& promise);
td::Status do_request(const tonlib_api::dns_resolve& request, td::Status do_request(const tonlib_api::dns_resolve& request,
td::Promise<object_ptr<tonlib_api::dns_resolved>>&& promise); td::Promise<object_ptr<tonlib_api::dns_resolved>>&& promise);
@ -342,6 +346,8 @@ class TonlibClient : public td::actor::Actor {
td::Status do_request(tonlib_api::pchan_unpackPromise& request, td::Status do_request(tonlib_api::pchan_unpackPromise& request,
td::Promise<object_ptr<tonlib_api::pchan_promise>>&& promise); td::Promise<object_ptr<tonlib_api::pchan_promise>>&& promise);
void process_new_libraries(
td::Result<ton::lite_api::object_ptr<ton::lite_api::liteServer_libraryResult>> r_libraries);
void perform_smc_execution(td::Ref<ton::SmartContract> smc, ton::SmartContract::Args args, void perform_smc_execution(td::Ref<ton::SmartContract> smc, ton::SmartContract::Args args,
td::Promise<object_ptr<tonlib_api::smc_runResult>>&& promise); td::Promise<object_ptr<tonlib_api::smc_runResult>>&& promise);
@ -409,5 +415,7 @@ class TonlibClient : public td::actor::Actor {
td::Status guess_revisions(std::vector<Target> targets, td::Status guess_revisions(std::vector<Target> targets,
td::Promise<object_ptr<tonlib_api::accountRevisionList>>&& promise); td::Promise<object_ptr<tonlib_api::accountRevisionList>>&& promise);
td::Status do_request(const int_api::ScanAndLoadGlobalLibs& request, td::Promise<vm::Dictionary> promise);
}; };
} // namespace tonlib } // namespace tonlib

View file

@ -71,6 +71,7 @@
#include "git.h" #include "git.h"
#include "block-auto.h" #include "block-auto.h"
#include "block-parse.h" #include "block-parse.h"
#include "common/delay.h"
Config::Config() { Config::Config() {
out_port = 3278; out_port = 3278;
@ -1243,6 +1244,18 @@ void ValidatorEngine::set_global_config(std::string str) {
void ValidatorEngine::set_db_root(std::string db_root) { void ValidatorEngine::set_db_root(std::string db_root) {
db_root_ = db_root; db_root_ = db_root;
} }
void ValidatorEngine::schedule_shutdown(double at) {
td::Timestamp ts = td::Timestamp::at_unix(at);
if (ts.is_in_past()) {
LOG(DEBUG) << "Scheduled shutdown is in past (" << at << ")";
} else {
LOG(INFO) << "Schedule shutdown for " << at << " (in " << ts.in() << "s)";
ton::delay_action([]() {
LOG(WARNING) << "Shutting down as scheduled";
std::_Exit(0);
}, ts);
}
}
void ValidatorEngine::start_up() { void ValidatorEngine::start_up() {
alarm_timestamp() = td::Timestamp::in(1.0 + td::Random::fast(0, 100) * 0.01); alarm_timestamp() = td::Timestamp::in(1.0 + td::Random::fast(0, 100) * 0.01);
} }
@ -4040,6 +4053,11 @@ int main(int argc, char *argv[]) {
return td::Status::OK(); return td::Status::OK();
}); });
p.add_checked_option('u', "user", "change user", [&](td::Slice user) { return td::change_user(user.str()); }); p.add_checked_option('u', "user", "change user", [&](td::Slice user) { return td::change_user(user.str()); });
p.add_checked_option('\0', "shutdown-at", "stop validator at the given time (unix timestamp)", [&](td::Slice arg) {
TRY_RESULT(at, td::to_integer_safe<td::uint32>(arg));
acts.push_back([&x, at]() { td::actor::send_closure(x, &ValidatorEngine::schedule_shutdown, (double)at); });
return td::Status::OK();
});
auto S = p.run(argc, argv); auto S = p.run(argc, argv);
if (S.is_error()) { if (S.is_error()) {
LOG(ERROR) << "failed to parse options: " << S.move_as_error(); LOG(ERROR) << "failed to parse options: " << S.move_as_error();

View file

@ -273,6 +273,7 @@ class ValidatorEngine : public td::actor::Actor {
void add_key_to_set(ton::PublicKey key) { void add_key_to_set(ton::PublicKey key) {
keys_[key.compute_short_id()] = key; keys_[key.compute_short_id()] = key;
} }
void schedule_shutdown(double at);
void set_not_all_shards() { void set_not_all_shards() {
not_all_shards_ = true; not_all_shards_ = true;
} }

View file

@ -129,7 +129,7 @@ class Collator final : public td::actor::Actor {
BlockIdExt mc_block_id_; BlockIdExt mc_block_id_;
Ref<vm::Cell> mc_state_root; Ref<vm::Cell> mc_state_root;
Ref<vm::Cell> mc_block_root; Ref<vm::Cell> mc_block_root;
td::BitArray<256> rand_seed_; td::BitArray<256> rand_seed_ = td::Bits256::zero();
std::unique_ptr<block::ConfigInfo> config_; std::unique_ptr<block::ConfigInfo> config_;
std::unique_ptr<block::ShardConfig> shard_conf_; std::unique_ptr<block::ShardConfig> shard_conf_;
std::map<BlockSeqno, Ref<MasterchainStateQ>> aux_mc_states_; std::map<BlockSeqno, Ref<MasterchainStateQ>> aux_mc_states_;