mirror of
https://github.com/ton-blockchain/ton
synced 2025-02-12 11:12:16 +00:00
deleted unused code, support for logrotate, update in block validation code
This commit is contained in:
parent
2b734e170c
commit
47814dca3d
44 changed files with 175 additions and 4196 deletions
|
@ -19,6 +19,56 @@ if (TON_REAL_BINARY_DIR STREQUAL TON_REAL_SOURCE_DIR)
|
|||
message(FATAL_ERROR "In-source build failed.")
|
||||
endif()
|
||||
|
||||
# HAVE_SSE42 for crc32c and rocksdb
|
||||
include(CheckCXXSourceCompiles)
|
||||
# Check for SSE4.2 support in the compiler.
|
||||
set(OLD_CMAKE_REQURED_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} /arch:AVX")
|
||||
else(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -msse4.2")
|
||||
endif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
check_cxx_source_compiles("
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
#else // !defined(_MSC_VER)
|
||||
#include <cpuid.h>
|
||||
#include <nmmintrin.h>
|
||||
#endif // defined(_MSC_VER)
|
||||
|
||||
int main() {
|
||||
_mm_crc32_u8(0, 0); _mm_crc32_u32(0, 0);
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
_mm_crc32_u64(0, 0);
|
||||
#endif // defined(_M_X64) || defined(__x86_64__)
|
||||
return 0;
|
||||
}
|
||||
" CRC32C_HAVE_SSE42)
|
||||
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQURED_FLAGS})
|
||||
|
||||
if(NOT MSVC)
|
||||
set(CMAKE_REQUIRED_FLAGS "-msse4.2 -mpclmul")
|
||||
endif()
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <cstdint>
|
||||
#include <nmmintrin.h>
|
||||
#include <wmmintrin.h>
|
||||
int main() {
|
||||
volatile uint32_t x = _mm_crc32_u32(0, 0);
|
||||
const auto a = _mm_set_epi64x(0, 0);
|
||||
const auto b = _mm_set_epi64x(0, 0);
|
||||
const auto c = _mm_clmulepi64_si128(a, b, 0x00);
|
||||
auto d = _mm_cvtsi128_si64(c);
|
||||
}
|
||||
" ROCKSDB_HAVE_SSE42)
|
||||
unset(CMAKE_REQUIRED_FLAGS)
|
||||
|
||||
if (ROCKSDB_HAVE_SSE42 AND CRC32C_HAVE_SSE42)
|
||||
set(HAVE_SSE42 TRUE)
|
||||
else()
|
||||
set(HAVE_SSE42 FALSE)
|
||||
endif()
|
||||
|
||||
#BEGIN internal
|
||||
option(TON_USE_ROCKSDB "Use \"ON\" to enable RocksDb." ON)
|
||||
option(TON_USE_ABSEIL "Use \"ON\" to enable Abseil." ON)
|
||||
|
@ -391,16 +441,6 @@ target_link_libraries(test-catchain overlay tdutils tdactor adnl adnltest rldp t
|
|||
#add_executable(test-validator-session test/test-validator-session.cpp)
|
||||
#target_link_libraries(test-validator-session overlay tdutils tdactor adnl tl_api dht
|
||||
# catchain validatorsession)
|
||||
#add_executable(test-ton-dummy-0 test/test-ton-dummy-0.cpp)
|
||||
#target_link_libraries(test-ton-dummy-0 overlay tdutils tdactor adnl tl_api dht
|
||||
# catchain validatorsession ton-node validator dummy_validator validator )
|
||||
#add_executable(test-dummy-0-lite-client test/test-dummy-0-lite-client.cpp)
|
||||
#target_link_libraries(test-dummy-0-lite-client overlay tdutils tdactor adnl tl_api dht
|
||||
# catchain validatorsession ton-node validator dummy_validator validator
|
||||
# terminal )
|
||||
#add_executable(test-ton-dummy-0-collator test/test-ton-collator.cpp)
|
||||
#target_link_libraries(test-ton-dummy-0-collator overlay tdutils tdactor adnl tl_api
|
||||
# dht catchain validatorsession ton-node validator_disk dummy_validator validator_disk )
|
||||
add_executable(test-ton-collator test/test-ton-collator.cpp)
|
||||
target_link_libraries(test-ton-collator overlay tdutils tdactor adnl tl_api dht
|
||||
catchain validatorsession validator-disk ton_validator validator-disk )
|
||||
|
|
|
@ -157,6 +157,11 @@ void Receiver::receive_to_client(td::BufferSlice data) {
|
|||
|
||||
} // namespace ton
|
||||
|
||||
std::atomic<bool> rotate_logs_flags{false};
|
||||
void force_rotate_logs(int sig) {
|
||||
rotate_logs_flags.store(true);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
SET_VERBOSITY_LEVEL(verbosity_INFO);
|
||||
|
||||
|
@ -190,23 +195,20 @@ int main(int argc, char *argv[]) {
|
|||
return td::Status::OK();
|
||||
});
|
||||
p.add_option('d', "daemonize", "set SIGHUP", [&]() {
|
||||
td::set_signal_handler(td::SignalType::HangUp, [](int sig) {
|
||||
#if TD_DARWIN || TD_LINUX
|
||||
close(0);
|
||||
setsid();
|
||||
close(0);
|
||||
setsid();
|
||||
#endif
|
||||
}).ensure();
|
||||
td::set_signal_handler(td::SignalType::HangUp, force_rotate_logs).ensure();
|
||||
return td::Status::OK();
|
||||
});
|
||||
#if TD_DARWIN || TD_LINUX
|
||||
p.add_option('l', "logname", "log to file", [&](td::Slice fname) {
|
||||
auto F = std::make_unique<td::FileLog>();
|
||||
TRY_STATUS(F->init(fname.str()));
|
||||
TRY_STATUS(F->init(fname.str(), std::numeric_limits<td::uint64>::max(), true));
|
||||
logger_ = std::move(F);
|
||||
td::log_interface = logger_.get();
|
||||
return td::Status::OK();
|
||||
});
|
||||
#endif
|
||||
td::uint32 threads = 7;
|
||||
p.add_option('t', "threads", PSTRING() << "number of threads (default=" << threads << ")", [&](td::Slice fname) {
|
||||
td::int32 v;
|
||||
|
@ -261,5 +263,10 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
while (scheduler.run(1)) {
|
||||
if (rotate_logs_flags.exchange(false)) {
|
||||
if (td::log_interface) {
|
||||
td::log_interface->rotate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,14 +131,17 @@ td::Result<block::StdAddress> parse_account_addr(std::map<std::string, std::stri
|
|||
return td::Status::Error(ton::ErrorCode::error, "no account id");
|
||||
}
|
||||
std::string acc_string = it->second;
|
||||
block::StdAddress a{acc_string};
|
||||
if (a.is_valid()) {
|
||||
block::StdAddress a;
|
||||
if (a.parse_addr(td::Slice(acc_string))) {
|
||||
return a;
|
||||
}
|
||||
ton::WorkchainId workchain_id;
|
||||
it = opts.find("accountworkchain");
|
||||
if (it == opts.end()) {
|
||||
return td::Status::Error(ton::ErrorCode::error, "no account workchain id");
|
||||
it = opts.find("workchain");
|
||||
if (it == opts.end()) {
|
||||
return td::Status::Error(ton::ErrorCode::error, "no account workchain id");
|
||||
}
|
||||
}
|
||||
try {
|
||||
workchain_id = std::stoi(it->second);
|
||||
|
|
|
@ -27,19 +27,23 @@ config.workchains!
|
|||
|
||||
// SmartContract #1 (Simple wallet)
|
||||
|
||||
<{ SETCP0 DUP IFNOTRET INC 32 THROWIF // return if recv_internal, fail unless recv_external
|
||||
512 INT LDSLICEX DUP 32 PLDU // sign cs cnt
|
||||
c4 PUSHCTR CTOS 32 LDU 256 LDU ENDS // sign cs cnt cnt' pubk
|
||||
s1 s2 XCPU // sign cs cnt pubk cnt' cnt
|
||||
EQUAL 33 THROWIFNOT // ( seqno mismatch? )
|
||||
s2 PUSH HASHSU // sign cs cnt pubk hash
|
||||
s0 s4 s4 XC2PU // pubk cs cnt hash sign pubk
|
||||
CHKSIGNU // pubk cs cnt ?
|
||||
34 THROWIFNOT // signature mismatch
|
||||
ACCEPT
|
||||
SWAP 32 LDU NIP 8 LDU LDREF ENDS // pubk cnt mode msg
|
||||
SWAP SENDRAWMSG // pubk cnt ; ( message sent )
|
||||
INC NEWC 32 STU 256 STU ENDC c4 POPCTR
|
||||
<{ SETCP0 DUP IFNOTRET // return if recv_internal
|
||||
DUP 85143 INT EQUAL IFJMP:<{ // "seqno" get-method
|
||||
DROP c4 PUSHCTR CTOS 32 PLDU // cnt
|
||||
}>
|
||||
INC 32 THROWIF // fail unless recv_external
|
||||
512 INT LDSLICEX DUP 32 PLDU // sign cs cnt
|
||||
c4 PUSHCTR CTOS 32 LDU 256 LDU ENDS // sign cs cnt cnt' pubk
|
||||
s1 s2 XCPU // sign cs cnt pubk cnt' cnt
|
||||
EQUAL 33 THROWIFNOT // ( seqno mismatch? )
|
||||
s2 PUSH HASHSU // sign cs cnt pubk hash
|
||||
s0 s4 s4 XC2PU // pubk cs cnt hash sign pubk
|
||||
CHKSIGNU // pubk cs cnt ?
|
||||
34 THROWIFNOT // signature mismatch
|
||||
ACCEPT
|
||||
SWAP 32 LDU NIP 8 LDU LDREF ENDS // pubk cnt mode msg
|
||||
SWAP SENDRAWMSG // pubk cnt ; ( message sent )
|
||||
INC NEWC 32 STU 256 STU ENDC c4 POPCTR
|
||||
}>c
|
||||
// code
|
||||
<b 0 32 u,
|
||||
|
@ -61,7 +65,10 @@ Masterchain over
|
|||
"main-wallet" +suffix +".addr" save-address-verbose
|
||||
|
||||
// SmartContract #2 (Simple money giver for test network)
|
||||
<{ SETCP0 DUP IFNOTRET INC 32 THROWIF // return if recv_internal, fail unless recv_external
|
||||
<{ SETCP0 DUP IFNOTRET // return if recv_internal
|
||||
DUP 85143 INT EQUAL IFJMP:<{ // "seqno" get-method
|
||||
DROP c4 PUSHCTR CTOS 32 PLDU // cnt
|
||||
}>
|
||||
32 LDU SWAP // cs cnt
|
||||
c4 PUSHCTR CTOS 32 LDU ENDS // cs cnt cnt'
|
||||
TUCK EQUAL 33 THROWIFNOT // ( seqno mismatch? )
|
||||
|
@ -157,7 +164,8 @@ config_addr config.config_smc!
|
|||
// elector-addr
|
||||
elector_addr config.elector_smc!
|
||||
|
||||
1 sg* 100 sg* 1000 sg* 1000000 sg* config.storage_prices!
|
||||
// 1 sg* 100 sg* 1000 sg* 1000000 sg* config.storage_prices! // old values (too high)
|
||||
1 500 1000 500000 config.storage_prices!
|
||||
config.special!
|
||||
|
||||
// gas_price gas_limit gas_credit block_gas_limit freeze_due_limit delete_due_limit --
|
||||
|
|
|
@ -15,23 +15,28 @@ def? $2 { @' $2 } { "new-wallet" } cond constant file-base
|
|||
."Creating new wallet in workchain " wc . cr
|
||||
|
||||
// Create new simple wallet
|
||||
<{ SETCP0 DUP IFNOTRET INC 32 THROWIF // return if recv_internal, fail unless recv_external
|
||||
512 INT LDSLICEX DUP 32 PLDU // sign cs cnt
|
||||
c4 PUSHCTR CTOS 32 LDU 256 LDU ENDS // sign cs cnt cnt' pubk
|
||||
s1 s2 XCPU // sign cs cnt pubk cnt' cnt
|
||||
EQUAL 33 THROWIFNOT // ( seqno mismatch? )
|
||||
s2 PUSH HASHSU // sign cs cnt pubk hash
|
||||
s0 s4 s4 XC2PU // pubk cs cnt hash sign pubk
|
||||
CHKSIGNU // pubk cs cnt ?
|
||||
34 THROWIFNOT // signature mismatch
|
||||
ACCEPT
|
||||
SWAP 32 LDU NIP
|
||||
DUP SREFS IF:<{
|
||||
8 LDU LDREF // pubk cnt mode msg cs
|
||||
s0 s2 XCHG SENDRAWMSG // pubk cnt cs ; ( message sent )
|
||||
}>
|
||||
ENDS
|
||||
INC NEWC 32 STU 256 STU ENDC c4 POPCTR
|
||||
<{ SETCP0 DUP IFNOTRET // return if recv_internal
|
||||
DUP 85143 INT EQUAL IFJMP:<{ // "seqno" get-method
|
||||
DROP c4 PUSHCTR CTOS 32 PLDU // cnt
|
||||
}>
|
||||
INC 32 THROWIF // fail unless recv_external
|
||||
512 INT LDSLICEX DUP 32 PLDU // sign cs cnt
|
||||
c4 PUSHCTR CTOS 32 LDU 256 LDU ENDS // sign cs cnt cnt' pubk
|
||||
s1 s2 XCPU // sign cs cnt pubk cnt' cnt
|
||||
EQUAL 33 THROWIFNOT // ( seqno mismatch? )
|
||||
s2 PUSH HASHSU // sign cs cnt pubk hash
|
||||
s0 s4 s4 XC2PU // pubk cs cnt hash sign pubk
|
||||
CHKSIGNU // pubk cs cnt ?
|
||||
34 THROWIFNOT // signature mismatch
|
||||
ACCEPT
|
||||
SWAP 32 LDU NIP
|
||||
DUP SREFS IF:<{
|
||||
// 3 INT 35 LSHIFT# 3 INT RAWRESERVE // reserve all but 103 Grams from the balance
|
||||
8 LDU LDREF // pubk cnt mode msg cs
|
||||
s0 s2 XCHG SENDRAWMSG // pubk cnt cs ; ( message sent )
|
||||
}>
|
||||
ENDS
|
||||
INC NEWC 32 STU 256 STU ENDC c4 POPCTR
|
||||
}>c // >libref
|
||||
// code
|
||||
<b 0 32 u,
|
||||
|
|
|
@ -1108,6 +1108,10 @@ std::atomic<bool> need_stats_flag{false};
|
|||
void need_stats(int sig) {
|
||||
need_stats_flag.store(true);
|
||||
}
|
||||
std::atomic<bool> rotate_logs_flags{false};
|
||||
void force_rotate_logs(int sig) {
|
||||
rotate_logs_flags.store(true);
|
||||
}
|
||||
void dump_memory_stats() {
|
||||
if (!is_memprof_on()) {
|
||||
return;
|
||||
|
@ -1184,21 +1188,18 @@ int main(int argc, char *argv[]) {
|
|||
return td::Status::OK();
|
||||
});
|
||||
p.add_option('d', "daemonize", "set SIGHUP", [&]() {
|
||||
td::set_signal_handler(td::SignalType::HangUp, [](int sig) {
|
||||
#if TD_DARWIN || TD_LINUX
|
||||
close(0);
|
||||
setsid();
|
||||
close(0);
|
||||
setsid();
|
||||
#endif
|
||||
}).ensure();
|
||||
td::set_signal_handler(td::SignalType::HangUp, force_rotate_logs).ensure();
|
||||
return td::Status::OK();
|
||||
});
|
||||
#if TD_DARWIN || TD_LINUX
|
||||
p.add_option('l', "logname", "log to file", [&](td::Slice fname) {
|
||||
logger_ = td::TsFileLog::create(fname.str()).move_as_ok();
|
||||
td::log_interface = logger_.get();
|
||||
return td::Status::OK();
|
||||
});
|
||||
#endif
|
||||
td::uint32 threads = 7;
|
||||
p.add_option('t', "threads", PSTRING() << "number of threads (default=" << threads << ")", [&](td::Slice fname) {
|
||||
td::int32 v;
|
||||
|
@ -1232,6 +1233,11 @@ int main(int argc, char *argv[]) {
|
|||
if (need_stats_flag.exchange(false)) {
|
||||
dump_stats();
|
||||
}
|
||||
if (rotate_logs_flags.exchange(false)) {
|
||||
if (td::log_interface) {
|
||||
td::log_interface->rotate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -5,7 +5,7 @@ Notice that you need a machine with a public IP address and a high-bandwidth net
|
|||
0. Downloading and compiling
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The complete TON Blockchain Library and Validator software is downloaded and compiled similarly to the Lite Client. This process is outlined in the corresponding README file. The most important difference is that you have to download the complete source archive available at https://test.ton.org/ton-blockchain-full.tar.xz instead of the smaller Lite Client source archive. You should also build all goals defined in CMakeLists.txt (e.g. by running `cmake <path-to-source-directory>` and `make` in your build directory), not only those specifically related to the Lite Client (which is also included in the larger distribution).
|
||||
The complete TON Blockchain Library and Validator software is downloaded and compiled similarly to the Lite Client. This process is outlined in the corresponding README file. The most important difference is that you have to download the complete source archive available at https://test.ton.org/ton-blockchain-full.tar.xz instead of the smaller Lite Client source archive. You should also build all goals defined in CMakeLists.txt (e.g. by running `cmake <path-to-source-directory>` and `make` in your build directory), not only those specifically related to the Lite Client (which is also included in the larger distribution; you don't have to download and build it separately). We strongly recommend building a "release" or a "release with debug information" version of the TON Blockchain Library and especially of the Validator/Full Node by passing `-DCMAKE_BUILD_TYPE=Release` or `-DCMAKE_BUILD_TYPE=RelWithDebInfo` as an extra argument to `cmake` during its first run (if you forgot to do this, you can later delete file `CMakeCache.txt` from your build directory and re-run `cmake` with the appropriate options).
|
||||
|
||||
1. Full Node binaries
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -49,7 +49,7 @@ We'll discuss the structure of this file later in more detail. For now, let us r
|
|||
|
||||
All instances of the TON Blockchain use the same "global" TON Network (i.e., the TON Network is not fragmented into several instances for each blockchain instance). While the global network configuration is therefore independent of the particular TON Blockchain instance chosen, the Full Nodes belonging to different instances will later connect to different overlay subnetworks inside the TON Network.
|
||||
|
||||
It is important to distinguish this "global configuration file", used for setting up a TON Blockchain Full Node, and the "local" or "automatic configuration file", automatically updated by validator-engine and usually stored in ${DB_ROOT}/config.json. The global configuration is used only once to generate the initial automatic configuration file, which is thereafter updated by validator-engine itself (e.g., by adding new DHT nodes or storing hashes of newer masterchain blocks).
|
||||
It is important to distinguish this "global configuration file", used for setting up a TON Blockchain Full Node, and the "local" or "automatic configuration file", automatically updated by validator-engine and usually stored in ${DB_ROOT}/config.json. The global configuration is used to generate the initial automatic configuration file, which is thereafter updated by validator-engine itself (e.g., by adding new DHT nodes or storing hashes of newer masterchain blocks).
|
||||
|
||||
5. Initializing the local configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -60,7 +60,7 @@ $ validator-engine -C /var/ton-work/etc/ton-global.config.json --db /var/ton-wor
|
|||
|
||||
Here `/var/ton-work/log` is the log directory of `validator-engine`, where it will create its log files. The argument to the `-C` command-line option is the global configuration file downloaded from test.ton.org as explained above, and `/var/ton-work/db/` is the working directory ${DB_ROOT}. Finally, <IP>:<PORT> are the global IP address of this full node (you need to indicate a public IPv4 address here) and the UDP port used to run TON Network protocols such as ADNL and RLDP. Make sure that your firewall is configured to pass UDP packets with source or destination <IP>:<PORT> at least for the `validator-engine` binary.
|
||||
|
||||
When validator-engine is invoked as above, and ${DB_ROOT}/config.json does not exist, it creates a new local configuration file ${DB_ROOT}/config.json using the information from the global configuration file and from the command-line options such as --ip, and then exits. If ${DB_ROOT}/config.json already exists, it is not rewritten; instead the global configuration is ignored, and validator-engine starts up as a daemon using the local configuration.
|
||||
When validator-engine is invoked as above, and ${DB_ROOT}/config.json does not exist, it creates a new local configuration file ${DB_ROOT}/config.json using the information from the global configuration file and from the command-line options such as --ip, and then exits. If ${DB_ROOT}/config.json already exists, it is not rewritten; instead validator-engine starts up as a daemon using both the local and the global configuration.
|
||||
|
||||
If you need to change the local configuration afterwards, you'll need to either delete this file and regenerate it from the global configuration (potentially forgetting other important information accumulated in the local configuration), or edit the local configuration in a text editor (when validator-engine is not running).
|
||||
|
||||
|
@ -114,9 +114,9 @@ Replace it with the following:
|
|||
|
||||
To run the full node, simply run the validator-engine binary in a console:
|
||||
|
||||
$ validator-engine --db ${DB_ROOT} -l /var/ton-work/log
|
||||
$ validator-engine --db ${DB_ROOT} -C /var/ton-work/etc/ton-global.config.json -l /var/ton-work/log
|
||||
|
||||
It will read the local configuration from ${DB_ROOT}/config.json, and continue running silently. You should write suitable scripts for invoking validator-engine as a daemon (so that it does not terminate when the console is closed), but we'll skip these considerations for simplicity. (Using "nohup" is a cheap way of achieving this on some Linux systems.)
|
||||
It will read the global configuration from /var/ton-work/etc/ton-global.config.json, the local configuration from ${DB_ROOT}/config.json, and continue running silently. You should write suitable scripts for invoking validator-engine as a daemon (so that it does not terminate when the console is closed), but we'll skip these considerations for simplicity. (The command-line option `-d` of validator-engine should be sufficient for this on most *nix systems.)
|
||||
|
||||
If the configuration is invalid, validator-engine will terminate immediately and, in most cases, output nothing. You'll have to study the log files under /var/ton-work/log to find out what went wrong. Otherwise, validator-engine will keep working silently. Again, you can understand what's going on by inspecting the log files, and by looking into subdirectories of the ${DB_ROOT} directory.
|
||||
|
||||
|
|
|
@ -1,24 +1,21 @@
|
|||
# TDLib C++ basic usage examples
|
||||
# Tonlib C++ basic usage examples
|
||||
|
||||
TDLib should be prebuilt and installed to local subdirectory `td/`:
|
||||
Tonlib should be prebuilt and installed to local subdirectory `tonlib/`:
|
||||
```
|
||||
cd <path to TDLib sources>
|
||||
cd <path to Ton sources>
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=../example/cpp/td ..
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=../example/cpp/tonlib ..
|
||||
cmake --build . --target install
|
||||
```
|
||||
Also see [building](https://github.com/tdlib/td#building) for additional details on TDLib building.
|
||||
|
||||
Then you can build the examples:
|
||||
```
|
||||
cd <path to TDLib sources>/example/cpp
|
||||
cd <path to Ton sources>/example/cpp
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DTonlib_DIR=<full path to TDLib sources>/example/cpp/tonlib/lib/cmake/Tonlib ..
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DTonlib_DIR=<full path to Ton sources>/example/cpp/tonlib/lib/cmake/Tonlib ..
|
||||
cmake --build .
|
||||
```
|
||||
|
||||
Documentation for all available classes and methods can be found at https://core.telegram.org/tdlib/docs.
|
||||
|
||||
To run `tdjson_example` you may need to manually copy a `tdjson` shared library from `td/bin` to a directory containing built binaries.
|
||||
To run `tonjson_example` you may need to manually copy a `tonlibjson` shared library from `tonlib/bin` to a directory containing built binaries.
|
||||
|
|
|
@ -1,148 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
binary="../../ton-build/generate-random-id"
|
||||
|
||||
die() {
|
||||
echo "$@" 1>&2 ;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
run_help() {
|
||||
echo "generates config for ton"
|
||||
echo " server-list - list of core DHT servers"
|
||||
echo " server-list.local - list of additional servers"
|
||||
echo " also expects generate-random-id binary to be accessible by path '$binary'"
|
||||
die
|
||||
}
|
||||
|
||||
get_line() {
|
||||
x=`grep -h -e "^$1 " server-list server-list.local`
|
||||
echo $x
|
||||
}
|
||||
|
||||
get_ip_block() {
|
||||
echo $1 | cut -f $2 -d"."
|
||||
}
|
||||
|
||||
get_ip() {
|
||||
ip=`echo $1 | cut -f 2 -d" "`
|
||||
a=$(get_ip_block $ip 1)
|
||||
b=$(get_ip_block $ip 2)
|
||||
c=$(get_ip_block $ip 3)
|
||||
d=$(get_ip_block $ip 4)
|
||||
ip=$(( $a * 256 * 256 * 256 + $b * 256 * 256 + $c * 256 + $d ))
|
||||
|
||||
if [ "$ip" -gt "2147483647" ] ; then
|
||||
ip=$((256*256*256*256 - $ip))
|
||||
ip="-$ip"
|
||||
fi
|
||||
|
||||
echo $ip
|
||||
}
|
||||
|
||||
get_port() {
|
||||
echo $1 | cut -f 3 -d" "
|
||||
}
|
||||
|
||||
get_pk() {
|
||||
#echo \'$1\' | cut -f 4 -d" "
|
||||
echo $1 | cut -f 4 -d" "
|
||||
}
|
||||
|
||||
get_addr_list() {
|
||||
line=$1
|
||||
|
||||
ip=$(get_ip "$line")
|
||||
port=$(get_port "$line")
|
||||
addr_list="{\"@type\":\"adnl.addressList\",\"version\":0,\"addrs\":[{\"ip\":$ip,\"port\":$port,\"@type\":\"adnl.address.udp\"}]}"
|
||||
|
||||
echo $addr_list
|
||||
}
|
||||
|
||||
get_node() {
|
||||
line=$1
|
||||
|
||||
addr_list=$(get_addr_list "$line")
|
||||
|
||||
pk=$(get_pk "$line")
|
||||
|
||||
res=`$binary -k $pk -a $addr_list | tail -1`
|
||||
echo $res
|
||||
}
|
||||
|
||||
get_id_short() {
|
||||
pk=$(get_pk "$1")
|
||||
res=`$binary -k $pk | tail -1`
|
||||
echo $res
|
||||
}
|
||||
|
||||
|
||||
action=$1
|
||||
|
||||
if [ "$action" == "global" ] ; then
|
||||
|
||||
[ -f "$binary" ] || die "can not file '$binary'"
|
||||
[ -f "server-list" ] || die "can not file 'server-list'"
|
||||
[ -f "server-list.local" ] || die "can not file 'server-list.local'"
|
||||
|
||||
if [ "x$2" == "x" ] ; then
|
||||
config_filename="ton-global.config.json"
|
||||
else
|
||||
config_filename=$2
|
||||
fi
|
||||
list=`cat server-list | awk '{ print $1}'`
|
||||
|
||||
config='{"@type":"config.global","dht":{"@type":"dht.config.global","k":10,"a":3,"static_nodes":{"@type":"adnl.nodes","nodes":'
|
||||
|
||||
cnt=0
|
||||
|
||||
for name in $list ; do
|
||||
if [ $cnt -eq 0 ] ; then
|
||||
config="$config["
|
||||
else
|
||||
config="$config,"
|
||||
fi
|
||||
cnt=$(($cnt + 1))
|
||||
line=$(get_line $name)
|
||||
node=$(get_node "$line")
|
||||
config="$config$node"
|
||||
done
|
||||
|
||||
config="$config]}}}"
|
||||
#name=$1
|
||||
#line=$(get_line $name)
|
||||
#echo $line
|
||||
#res=$(get_node "$line")
|
||||
#echo $res
|
||||
echo $config > $config_filename
|
||||
elif [ "$action" == "local" ] ; then
|
||||
|
||||
[ -f "$binary" ] || die "can not file '$binary'"
|
||||
[ -f "server-list" ] || die "can not file 'server-list'"
|
||||
[ -f "server-list.local" ] || die "can not file 'server-list.local'"
|
||||
|
||||
name=$2
|
||||
if [ "x$3" == "x" ] ; then
|
||||
config_filename="ton-local.config.$name.json"
|
||||
else
|
||||
config_filename=$3
|
||||
fi
|
||||
line=$(get_line $name)
|
||||
config='{"@type":"config.local","local_ids":['
|
||||
id=$(get_pk "$line")
|
||||
id_short=$(get_id_short "$line")
|
||||
addr_list=$(get_addr_list "$line")
|
||||
config="$config{\"@type\":\"id.config.local\",\"id\":$id,\"addr_list\":$addr_list}]"
|
||||
config="$config,\"net\":$addr_list"
|
||||
config="$config,\"dht\":[{\"@type\":\"dht.config.local\",\"id\":$id_short}]"
|
||||
config="$config,\"dht_random\":{\"@type\":\"config.dht.random\",\"cnt\":0,\"addr_list\":$addr_list}"
|
||||
config="$config,\"public_overlays\":[{\"@type\":\"overlay.config.local\",\"name\":\"testoverlay\",\"id\":$id_short}]"
|
||||
config="$config,\"public_overlays_random\":{\"@type\":\"overlay.config.random\",\"cnt\":0,\"name\":\"testoverlay\",\"addr_list\":$addr_list}"
|
||||
config="$config}"
|
||||
|
||||
echo $config > $config_filename
|
||||
elif [ "$action" == "-h" ] ; then
|
||||
run_help
|
||||
elif [ "$action" == "--help" ] ; then
|
||||
run_help
|
||||
fi
|
|
@ -1,2 +0,0 @@
|
|||
|1|ZHWS4UqZvNaFSyJtpsIjaxt81x0=|EcIbvL5PRC309C1xvWmahWmxS+0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
|
||||
|1|J3+q3mgMPZ5MP5OhvjE5owUKTUk=|tH2DPyqGRjXkrRy2rZBOm/F34vs= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
|
|
@ -1,41 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
host=$1
|
||||
user="root"
|
||||
ssh=$user@$host
|
||||
|
||||
die() {
|
||||
echo "$@" 1>&2 ;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
run_help() {
|
||||
echo "tries to initialize new server"
|
||||
echo "uses these files: "
|
||||
echo " tonkey - RSA key that allows to access git repository"
|
||||
echo " server-list - list of core DHT servers"
|
||||
echo " server-list.local - list of additional servers"
|
||||
die
|
||||
}
|
||||
|
||||
if [ "$1" == "-h" ] ; then
|
||||
run_help
|
||||
fi
|
||||
|
||||
if [ "$1" == "--help" ] ; then
|
||||
run_help
|
||||
fi
|
||||
|
||||
scp tonkey $ssh:.ssh/id_rsa || die "cannot copy id_rsa"
|
||||
ssh $ssh chmod 0600 .ssh/id_rsa || die "cannot chmod id_rsa"
|
||||
scp known_hosts $ssh:.ssh/known_hosts || die "cannot copy known_hosts"
|
||||
ssh $ssh "apt-get update && apt-get -y install git libssl-dev cmake g++ gperf libz-dev" || die "cannot install packets"
|
||||
ssh $ssh "git clone git@bitbucket.org:toin/ton.git ; cd ton && git submodule init ; git submodule update && cd third-party/libraptorq && git submodule init && git submodule update" || die "cannot clone git"
|
||||
ssh $ssh "cd ton && git submodule update" || die "can not init submodules"
|
||||
ssh $ssh "if [ ! -d ton-build ]; then mkdir ton-build ; fi"
|
||||
ssh $ssh "cd ton-build && cmake ../ton" || die "cannot prepare for build"
|
||||
ssh $ssh "cd ton-build && make -j 8 test-node" || die "cannot build"
|
||||
sh generate-config.sh global ton-global.config.json || die "cannot create global config"
|
||||
sh generate-config.sh local $host ton-local.config.json || die "cannot create local config"
|
||||
scp ton-global.config.json ton-local.config.json $ssh:
|
|
@ -50,7 +50,7 @@ class TsFileLog : public LogInterface {
|
|||
private:
|
||||
struct Info {
|
||||
FileLog log;
|
||||
bool is_inited;
|
||||
std::atomic<bool> is_inited{false};
|
||||
int id;
|
||||
};
|
||||
static constexpr int MAX_THREAD_ID = 128;
|
||||
|
@ -59,7 +59,7 @@ class TsFileLog : public LogInterface {
|
|||
|
||||
LogInterface *get_current_logger() {
|
||||
auto *info = get_current_info();
|
||||
if (!info->is_inited) {
|
||||
if (!info->is_inited.load(std::memory_order_relaxed)) {
|
||||
CHECK(init_info(info).is_ok());
|
||||
}
|
||||
return &info->log;
|
||||
|
@ -79,7 +79,15 @@ class TsFileLog : public LogInterface {
|
|||
if (info->id == 0) {
|
||||
return path_;
|
||||
}
|
||||
return PSTRING() << path_ << "." << info->id;
|
||||
return PSTRING() << path_ << ".thread" << info->id << ".log";
|
||||
}
|
||||
|
||||
void rotate() override {
|
||||
for (auto &info : logs_) {
|
||||
if (info.is_inited.load(std::memory_order_consume)) {
|
||||
info.log.rotate();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
|
|
@ -1,236 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain source code.
|
||||
|
||||
TON Blockchain is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU 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 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with TON Blockchain. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the file(s),
|
||||
but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. If you delete this exception statement
|
||||
from all source files in the program, then also delete it here.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "adnl/adnl.h"
|
||||
#include "adnl/adnl-ext-client.h"
|
||||
#include "adnl/utils.hpp"
|
||||
#include "auto/tl/ton_api_json.h"
|
||||
#include "td/utils/OptionsParser.h"
|
||||
#include "td/utils/Time.h"
|
||||
#include "td/utils/filesystem.h"
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/port/signals.h"
|
||||
#include "td/utils/port/FileFd.h"
|
||||
#include "terminal/terminal.h"
|
||||
|
||||
#if TD_DARWIN || TD_LINUX
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
template <std::size_t size>
|
||||
std::ostream &operator<<(std::ostream &stream, const td::UInt<size> &x) {
|
||||
for (size_t i = 0; i < size / 8; i++) {
|
||||
stream << td::format::hex_digit((x.raw[i] >> 4) & 15) << td::format::hex_digit(x.raw[i] & 15);
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
class TestNode : public td::actor::Actor {
|
||||
private:
|
||||
td::actor::ActorOwn<ton::adnl::Adnl> adnl_;
|
||||
|
||||
std::string local_config_ = "ton-local.config";
|
||||
std::string global_config_ = "ton-global.config";
|
||||
|
||||
td::actor::ActorOwn<ton::adnl::AdnlExtClient> client_;
|
||||
td::actor::ActorOwn<td::TerminalIO> io_;
|
||||
|
||||
std::unique_ptr<ton::adnl::AdnlExtClient::Callback> 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));
|
||||
}
|
||||
|
||||
bool ready_ = false;
|
||||
std::string db_root_;
|
||||
|
||||
public:
|
||||
void conn_ready() {
|
||||
LOG(ERROR) << "conn ready";
|
||||
ready_ = true;
|
||||
}
|
||||
void conn_closed() {
|
||||
ready_ = false;
|
||||
}
|
||||
void set_local_config(std::string str) {
|
||||
local_config_ = str;
|
||||
}
|
||||
void set_global_config(std::string str) {
|
||||
global_config_ = str;
|
||||
}
|
||||
void set_db_root(std::string db_root) {
|
||||
db_root_ = db_root;
|
||||
}
|
||||
void start_up() override {
|
||||
class Cb : public td::TerminalIO::Callback {
|
||||
public:
|
||||
void line_cb(td::BufferSlice line) override {
|
||||
LOG(ERROR) << "read line";
|
||||
td::actor::send_closure(id_, &TestNode::send_query, std::move(line));
|
||||
}
|
||||
Cb(td::actor::ActorId<TestNode> id) : id_(id) {
|
||||
}
|
||||
|
||||
private:
|
||||
td::actor::ActorId<TestNode> id_;
|
||||
};
|
||||
io_ = td::TerminalIO::create("", false, std::make_unique<Cb>(actor_id(this)));
|
||||
td::actor::send_closure(io_, &td::TerminalIO::set_log_interface);
|
||||
}
|
||||
void send_query(td::BufferSlice data) {
|
||||
if (ready_ && !client_.empty()) {
|
||||
LOG(ERROR) << "sending query";
|
||||
auto P = td::PromiseCreator::lambda([](td::Result<td::BufferSlice> R) {
|
||||
if (R.is_error()) {
|
||||
LOG(ERROR) << "failed query: " << R.move_as_error();
|
||||
return;
|
||||
}
|
||||
auto F = ton::fetch_tl_object<ton::ton_api::Object>(R.move_as_ok(), true);
|
||||
if (F.is_error()) {
|
||||
LOG(ERROR) << "failed to parse answer: " << F.move_as_error();
|
||||
return;
|
||||
}
|
||||
auto obj = F.move_as_ok();
|
||||
LOG(ERROR) << "got answer: " << ton::ton_api::to_string(obj);
|
||||
});
|
||||
td::BufferSlice b =
|
||||
ton::serialize_tl_object(ton::create_tl_object<ton::ton_api::liteServer_query>(std::move(data)), true);
|
||||
td::actor::send_closure(client_, &ton::adnl::AdnlExtClient::send_query, "query", std::move(b),
|
||||
td::Timestamp::in(10.0), std::move(P));
|
||||
}
|
||||
}
|
||||
TestNode() {
|
||||
}
|
||||
void run() {
|
||||
adnl_ = ton::adnl::Adnl::create(db_root_);
|
||||
|
||||
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::config_global gc;
|
||||
ton::ton_api::from_json(gc, gc_j.get_object()).ensure();
|
||||
|
||||
//td::actor::send_closure(network_manager_, &ton::adnl::AdnlNetworkManager::load_local_config, std::move(lc.net_));
|
||||
if (gc.adnl_) {
|
||||
td::actor::send_closure(adnl_, &ton::adnl::Adnl::add_static_nodes_from_config,
|
||||
std::move(gc.adnl_->static_nodes_));
|
||||
}
|
||||
|
||||
CHECK(gc.liteclients_.size() > 0);
|
||||
auto &cli = gc.liteclients_[0];
|
||||
td::IPAddress addr;
|
||||
addr.init_host_port(td::IPAddress::ipv4_to_str(cli->ip_), cli->port_).ensure();
|
||||
client_ = ton::adnl::AdnlExtClient::create(ton::adnl::AdnlNodeIdFull{cli->id_}, addr, make_callback());
|
||||
}
|
||||
};
|
||||
|
||||
td::Result<td::UInt256> get_uint256(std::string str) {
|
||||
if (str.size() != 64) {
|
||||
return td::Status::Error("uint256 must have 64 bytes");
|
||||
}
|
||||
td::UInt256 res;
|
||||
for (size_t i = 0; i < 32; i++) {
|
||||
res.raw[i] = static_cast<td::uint8>(td::hex_to_int(str[2 * i]) * 16 + td::hex_to_int(str[2 * i + 1]));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
SET_VERBOSITY_LEVEL(verbosity_DEBUG);
|
||||
td::set_default_failure_signal_handler().ensure();
|
||||
|
||||
td::actor::ActorOwn<TestNode> x;
|
||||
|
||||
td::OptionsParser p;
|
||||
p.set_description("test basic adnl functionality");
|
||||
p.add_option('h', "help", "prints_help", [&]() {
|
||||
char b[10240];
|
||||
td::StringBuilder sb(td::MutableSlice{b, 10000});
|
||||
sb << p;
|
||||
std::cout << sb.as_cslice().c_str();
|
||||
std::exit(2);
|
||||
return td::Status::OK();
|
||||
});
|
||||
p.add_option('C', "global-config", "file to read global config", [&](td::Slice fname) {
|
||||
td::actor::send_closure(x, &TestNode::set_global_config, fname.str());
|
||||
return td::Status::OK();
|
||||
});
|
||||
p.add_option('c', "local-config", "file to read local config", [&](td::Slice fname) {
|
||||
td::actor::send_closure(x, &TestNode::set_local_config, fname.str());
|
||||
return td::Status::OK();
|
||||
});
|
||||
p.add_option('D', "db", "root for dbs", [&](td::Slice fname) {
|
||||
td::actor::send_closure(x, &TestNode::set_db_root, fname.str());
|
||||
return td::Status::OK();
|
||||
});
|
||||
p.add_option('d', "daemonize", "set SIGHUP", [&]() {
|
||||
td::set_signal_handler(td::SignalType::HangUp, [](int sig) {
|
||||
#if TD_DARWIN || TD_LINUX
|
||||
close(0);
|
||||
setsid();
|
||||
#endif
|
||||
}).ensure();
|
||||
return td::Status::OK();
|
||||
});
|
||||
#if TD_DARWIN || TD_LINUX
|
||||
p.add_option('l', "logname", "log to file", [&](td::Slice fname) {
|
||||
auto FileLog = td::FileFd::open(td::CSlice(fname.str().c_str()),
|
||||
td::FileFd::Flags::Create | td::FileFd::Flags::Append | td::FileFd::Flags::Write)
|
||||
.move_as_ok();
|
||||
|
||||
dup2(FileLog.get_native_fd().fd(), 1);
|
||||
dup2(FileLog.get_native_fd().fd(), 2);
|
||||
return td::Status::OK();
|
||||
});
|
||||
#endif
|
||||
|
||||
td::actor::Scheduler scheduler({2});
|
||||
|
||||
scheduler.run_in_context([&] { x = td::actor::create_actor<TestNode>("testnode"); });
|
||||
|
||||
scheduler.run_in_context([&] { p.run(argc, argv).ensure(); });
|
||||
scheduler.run_in_context([&] { td::actor::send_closure(x, &TestNode::run); });
|
||||
scheduler.run();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,236 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain source code.
|
||||
|
||||
TON Blockchain is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU 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 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with TON Blockchain. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the file(s),
|
||||
but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. If you delete this exception statement
|
||||
from all source files in the program, then also delete it here.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "adnl/adnl.h"
|
||||
#include "adnl/utils.hpp"
|
||||
#include "auto/tl/ton_api_json.h"
|
||||
#include "dht/dht.h"
|
||||
#include "overlay/overlays.h"
|
||||
#include "td/utils/OptionsParser.h"
|
||||
#include "td/utils/Time.h"
|
||||
#include "td/utils/filesystem.h"
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/port/signals.h"
|
||||
#include "td/utils/port/FileFd.h"
|
||||
#include "catchain/catchain.h"
|
||||
#include "validator-session/validator-session.h"
|
||||
#include "ton-node/ton-node.h"
|
||||
#include "validator/manager.h"
|
||||
#include "td/utils/filesystem.h"
|
||||
#include "td/utils/port/path.h"
|
||||
|
||||
#if TD_DARWIN || TD_LINUX
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
template <std::size_t size>
|
||||
std::ostream &operator<<(std::ostream &stream, const td::UInt<size> &x) {
|
||||
for (size_t i = 0; i < size / 8; i++) {
|
||||
stream << td::format::hex_digit((x.raw[i] >> 4) & 15) << td::format::hex_digit(x.raw[i] & 15);
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
class TestNode : public td::actor::Actor {
|
||||
private:
|
||||
td::actor::ActorOwn<ton::adnl::Adnl> adnl_;
|
||||
std::vector<td::actor::ActorOwn<ton::dht::Dht>> dht_nodes_;
|
||||
td::actor::ActorOwn<ton::overlay::Overlays> overlay_manager_;
|
||||
td::actor::ActorOwn<ton::ValidatorManager> validator_manager_;
|
||||
td::actor::ActorOwn<ton::TonNodeManager> ton_node_;
|
||||
std::vector<td::actor::ActorOwn<ton::adnl::AdnlFileTransfer>> file_transfers_;
|
||||
|
||||
std::string local_config_ = "ton-local.config";
|
||||
std::string global_config_ = "ton-global.config";
|
||||
|
||||
std::string inst_id_ = "";
|
||||
std::string db_root_ = "/var/ton-work/db/";
|
||||
|
||||
std::unique_ptr<ton::adnl::Adnl::Callback> make_callback() {
|
||||
class Callback : public ton::adnl::Adnl::Callback {
|
||||
public:
|
||||
void receive_message(td::UInt256 src, td::UInt256 dst, td::BufferSlice data) override {
|
||||
td::actor::send_closure(id_, &TestNode::adnl_receive_message, src, dst, std::move(data));
|
||||
}
|
||||
void receive_query(td::UInt256 src, td::UInt256 dst, td::BufferSlice data,
|
||||
td::Promise<td::BufferSlice> promise) override {
|
||||
}
|
||||
Callback(td::actor::ActorId<TestNode> id) : id_(std::move(id)) {
|
||||
}
|
||||
|
||||
private:
|
||||
td::actor::ActorId<TestNode> id_;
|
||||
};
|
||||
|
||||
return std::make_unique<Callback>(actor_id(this));
|
||||
}
|
||||
|
||||
public:
|
||||
void adnl_receive_message(td::UInt256 src, td::UInt256 dst, td::BufferSlice data) {
|
||||
LOG(ERROR) << "ADNL MESSAGE FROM " << src << ": size=" << data.size() << "\n";
|
||||
}
|
||||
|
||||
void set_local_config(std::string str) {
|
||||
local_config_ = str;
|
||||
}
|
||||
void set_local_id(std::string id) {
|
||||
inst_id_ = id;
|
||||
}
|
||||
void set_global_config(std::string str) {
|
||||
global_config_ = str;
|
||||
}
|
||||
void set_db_root(std::string db_root) {
|
||||
db_root_ = db_root;
|
||||
}
|
||||
void start_up() override {
|
||||
}
|
||||
void alarm() override {
|
||||
}
|
||||
TestNode() {
|
||||
}
|
||||
void run() {
|
||||
td::mkdir(db_root_).ensure();
|
||||
|
||||
auto L = td::read_file(local_config_).move_as_ok();
|
||||
auto lc_j = td::json_decode(L.as_slice()).move_as_ok();
|
||||
ton::ton_api::config_local lc;
|
||||
ton::ton_api::from_json(lc, lc_j.get_object()).ensure();
|
||||
|
||||
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::config_global gc;
|
||||
ton::ton_api::from_json(gc, gc_j.get_object()).ensure();
|
||||
|
||||
CHECK(lc.dummy0_.size() == 1);
|
||||
CHECK(gc.dummy0_.size() == 1);
|
||||
|
||||
validator_manager_ = ton::ValidatorManagerFactory::create(lc.dummy0_[0]->id_->id_, gc.dummy0_[0]->zero_state_hash_,
|
||||
gc.dummy0_[0]->zero_state_hash_, db_root_, adnl_.get());
|
||||
class Callback : public ton::ValidatorManager::Callback {
|
||||
private:
|
||||
td::actor::ActorId<ton::ValidatorManager> id_;
|
||||
|
||||
public:
|
||||
Callback(td::actor::ActorId<ton::ValidatorManager> id) : id_(id) {
|
||||
}
|
||||
|
||||
void initial_read_complete(ton::WorkchainId workchain, ton::ShardId shard, ton::adnl::AdnlNodeIdShort who,
|
||||
std::vector<ton::BlockHandle> top_blocks) override {
|
||||
td::actor::send_closure(id_, &ton::ValidatorManager::sync_complete, workchain, shard,
|
||||
td::PromiseCreator::lambda([](td::Unit) {}));
|
||||
}
|
||||
void new_ihr_message(ton::WorkchainId workchain, ton::adnl::AdnlNodeIdShort who, td::UInt256 dst,
|
||||
td::BufferSlice data) override {
|
||||
}
|
||||
void download_block(ton::BlockIdExt block_id, td::Timestamp timeout, ton::adnl::AdnlNodeIdShort who,
|
||||
td::Promise<ton::ReceivedBlock> promise) override {
|
||||
}
|
||||
};
|
||||
|
||||
td::actor::send_closure(validator_manager_, &ton::ValidatorManager::install_callback,
|
||||
std::make_unique<Callback>(validator_manager_.get()),
|
||||
td::PromiseCreator::lambda([](td::Unit) {}));
|
||||
}
|
||||
};
|
||||
|
||||
td::Result<td::UInt256> get_uint256(std::string str) {
|
||||
if (str.size() != 64) {
|
||||
return td::Status::Error("uint256 must have 64 bytes");
|
||||
}
|
||||
td::UInt256 res;
|
||||
for (size_t i = 0; i < 32; i++) {
|
||||
res.raw[i] = static_cast<td::uint8>(td::hex_to_int(str[2 * i]) * 16 + td::hex_to_int(str[2 * i + 1]));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
SET_VERBOSITY_LEVEL(verbosity_INFO);
|
||||
td::set_default_failure_signal_handler().ensure();
|
||||
|
||||
td::actor::ActorOwn<TestNode> x;
|
||||
|
||||
td::OptionsParser p;
|
||||
p.set_description("test basic adnl functionality");
|
||||
p.add_option('h', "help", "prints_help", [&]() {
|
||||
char b[10240];
|
||||
td::StringBuilder sb(td::MutableSlice{b, 10000});
|
||||
sb << p;
|
||||
std::cout << sb.as_cslice().c_str();
|
||||
std::exit(2);
|
||||
return td::Status::OK();
|
||||
});
|
||||
p.add_option('C', "global-config", "file to read global config", [&](td::Slice fname) {
|
||||
td::actor::send_closure(x, &TestNode::set_global_config, fname.str());
|
||||
return td::Status::OK();
|
||||
});
|
||||
p.add_option('c', "local-config", "file to read local config", [&](td::Slice fname) {
|
||||
td::actor::send_closure(x, &TestNode::set_local_config, fname.str());
|
||||
return td::Status::OK();
|
||||
});
|
||||
p.add_option('i', "id", "id of instance", [&](td::Slice fname) {
|
||||
td::actor::send_closure(x, &TestNode::set_local_id, fname.str());
|
||||
return td::Status::OK();
|
||||
});
|
||||
p.add_option('D', "db", "root for dbs", [&](td::Slice fname) {
|
||||
td::actor::send_closure(x, &TestNode::set_db_root, fname.str());
|
||||
return td::Status::OK();
|
||||
});
|
||||
p.add_option('d', "daemonize", "set SIGHUP", [&]() {
|
||||
td::set_signal_handler(td::SignalType::HangUp, [](int sig) {
|
||||
#if TD_DARWIN || TD_LINUX
|
||||
close(0);
|
||||
setsid();
|
||||
#endif
|
||||
}).ensure();
|
||||
return td::Status::OK();
|
||||
});
|
||||
#if TD_DARWIN || TD_LINUX
|
||||
p.add_option('l', "logname", "log to file", [&](td::Slice fname) {
|
||||
auto FileLog = td::FileFd::open(td::CSlice(fname.str().c_str()),
|
||||
td::FileFd::Flags::Create | td::FileFd::Flags::Append | td::FileFd::Flags::Write)
|
||||
.move_as_ok();
|
||||
|
||||
dup2(FileLog.get_native_fd().fd(), 1);
|
||||
dup2(FileLog.get_native_fd().fd(), 2);
|
||||
return td::Status::OK();
|
||||
});
|
||||
#endif
|
||||
|
||||
td::actor::Scheduler scheduler({7});
|
||||
scheduler.run_in_context([&] { x = td::actor::create_actor<TestNode>("testnode"); });
|
||||
|
||||
scheduler.run_in_context([&] { p.run(argc, argv).ensure(); });
|
||||
scheduler.run_in_context([&] { td::actor::send_closure(x, &TestNode::run); });
|
||||
scheduler.run();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,277 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain source code.
|
||||
|
||||
TON Blockchain is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU 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 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with TON Blockchain. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the file(s),
|
||||
but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. If you delete this exception statement
|
||||
from all source files in the program, then also delete it here.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "adnl/adnl.h"
|
||||
#include "adnl/utils.hpp"
|
||||
#include "auto/tl/ton_api_json.h"
|
||||
#include "dht/dht.h"
|
||||
#include "overlay/overlays.h"
|
||||
#include "td/utils/OptionsParser.h"
|
||||
#include "td/utils/Time.h"
|
||||
#include "td/utils/filesystem.h"
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/port/signals.h"
|
||||
#include "td/utils/port/FileFd.h"
|
||||
#include "catchain/catchain.h"
|
||||
#include "validator-session/validator-session.h"
|
||||
#include "ton-node/ton-node.h"
|
||||
#include "validator/manager.h"
|
||||
#include "td/utils/filesystem.h"
|
||||
#include "td/utils/port/path.h"
|
||||
#include "crypto/vm/cp0.h"
|
||||
|
||||
#if TD_DARWIN || TD_LINUX
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
template <std::size_t size>
|
||||
std::ostream &operator<<(std::ostream &stream, const td::UInt<size> &x) {
|
||||
for (size_t i = 0; i < size / 8; i++) {
|
||||
stream << td::format::hex_digit((x.raw[i] >> 4) & 15) << td::format::hex_digit(x.raw[i] & 15);
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
class TestNode : public td::actor::Actor {
|
||||
private:
|
||||
td::actor::ActorOwn<ton::Keyring> keyring_;
|
||||
td::actor::ActorOwn<ton::adnl::Adnl> adnl_;
|
||||
td::actor::ActorOwn<ton::rldp::Rldp> rldp_;
|
||||
std::vector<td::actor::ActorOwn<ton::dht::Dht>> dht_nodes_;
|
||||
td::actor::ActorOwn<ton::overlay::Overlays> overlay_manager_;
|
||||
td::actor::ActorOwn<ton::ValidatorManager> validator_manager_;
|
||||
td::actor::ActorOwn<ton::TonNodeManager> ton_node_;
|
||||
|
||||
std::string local_config_ = "ton-local.config";
|
||||
std::string global_config_ = "ton-global.config";
|
||||
|
||||
std::string db_root_ = "/var/ton-work/db/";
|
||||
std::string zero_state_ = "";
|
||||
|
||||
public:
|
||||
void set_local_config(std::string str) {
|
||||
local_config_ = str;
|
||||
}
|
||||
void set_global_config(std::string str) {
|
||||
global_config_ = str;
|
||||
}
|
||||
void set_db_root(std::string db_root) {
|
||||
db_root_ = db_root;
|
||||
}
|
||||
void set_zero_state(std::string zero_state) {
|
||||
zero_state_ = zero_state;
|
||||
}
|
||||
void start_up() override {
|
||||
}
|
||||
void alarm() override {
|
||||
}
|
||||
TestNode() {
|
||||
}
|
||||
void run() {
|
||||
td::mkdir(db_root_).ensure();
|
||||
|
||||
keyring_ = ton::Keyring::create();
|
||||
adnl_ = ton::adnl::Adnl::create(db_root_, keyring_.get());
|
||||
|
||||
auto L = td::read_file(local_config_).move_as_ok();
|
||||
auto lc_j = td::json_decode(L.as_slice()).move_as_ok();
|
||||
ton::ton_api::config_local lc;
|
||||
ton::ton_api::from_json(lc, lc_j.get_object()).ensure();
|
||||
|
||||
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::config_global gc;
|
||||
ton::ton_api::from_json(gc, gc_j.get_object()).ensure();
|
||||
|
||||
for (auto &port : lc.udp_ports_) {
|
||||
td::actor::send_closure(adnl_, &ton::adnl::Adnl::add_listening_udp_port, "0.0.0.0",
|
||||
static_cast<td::uint16>(port));
|
||||
}
|
||||
/*if (!lc.net_) {
|
||||
LOG(FATAL) << "local config does not contain NET section";
|
||||
}*/
|
||||
|
||||
//td::actor::send_closure(network_manager_, &ton::adnl::AdnlNetworkManager::load_local_config, std::move(lc.net_));
|
||||
td::actor::send_closure(adnl_, &ton::adnl::Adnl::add_ids_from_config, std::move(lc.local_ids_));
|
||||
if (gc.adnl_) {
|
||||
td::actor::send_closure(adnl_, &ton::adnl::Adnl::add_static_nodes_from_config,
|
||||
std::move(gc.adnl_->static_nodes_));
|
||||
}
|
||||
if (!gc.dht_) {
|
||||
LOG(FATAL) << "global config does not contain dht section";
|
||||
}
|
||||
|
||||
for (auto &it : lc.dht_) {
|
||||
if (it->get_id() == ton::ton_api::dht_config_local::ID) {
|
||||
auto R = ton::dht::Dht::create_from_json(ton::clone_tl_object(gc.dht_),
|
||||
ton::move_tl_object_as<ton::ton_api::dht_config_local>(it),
|
||||
keyring_.get(), adnl_.get());
|
||||
if (R.is_error()) {
|
||||
LOG(FATAL) << "fail creating dht node: " << R.move_as_error();
|
||||
}
|
||||
dht_nodes_.push_back(R.move_as_ok());
|
||||
} else {
|
||||
auto I = ton::move_tl_object_as<ton::ton_api::dht_config_random_local>(it);
|
||||
for (int i = 0; i < I->cnt_; i++) {
|
||||
auto R = ton::dht::Dht::create_random(ton::clone_tl_object(gc.dht_), ton::clone_tl_object(I->addr_list_),
|
||||
keyring_.get(), adnl_.get());
|
||||
if (R.is_error()) {
|
||||
LOG(FATAL) << "fail creating dht node: " << R.move_as_error();
|
||||
}
|
||||
dht_nodes_.push_back(R.move_as_ok());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(dht_nodes_.size() > 0);
|
||||
|
||||
td::actor::send_closure(adnl_, &ton::adnl::Adnl::register_dht_node, dht_nodes_[0].get());
|
||||
//td::actor::send_closure(overlay_manager_, &ton::overlay::Overlays::register_dht_node, dht_nodes_[0].get());
|
||||
|
||||
overlay_manager_ = ton::overlay::Overlays::create(keyring_.get(), adnl_.get(), dht_nodes_[0].get());
|
||||
|
||||
//auto C = ton::CatChainActor::create(nullptr, adnl_.get(), overlay_manager_.get(),
|
||||
// std::vector<ton::tl_object_ptr<ton::ton_api::adnl_id_Full>>());
|
||||
|
||||
CHECK(lc.dummy0_.size() <= 1);
|
||||
CHECK(gc.dummy0_.size() <= 1);
|
||||
|
||||
if (lc.dummy0_.size() == 1) {
|
||||
CHECK(gc.dummy0_.size() == 1);
|
||||
auto zero_state_id = ton::BlockIdExt{ton::masterchainId, ton::shardIdAll, 0,
|
||||
ton::UInt256_2_Bits256(gc.dummy0_[0]->zero_state_hash_),
|
||||
ton::UInt256_2_Bits256(gc.dummy0_[0]->zero_state_hash_)};
|
||||
validator_manager_ = ton::ValidatorManagerFactory::create(
|
||||
ton::PublicKeyHash{lc.dummy0_[0]->id_->id_}, zero_state_id, "", zero_state_,
|
||||
{ton::ShardIdFull{ton::basechainId, ton::shardIdAll}}, db_root_, keyring_.get(), adnl_.get(), rldp_.get(),
|
||||
overlay_manager_.get());
|
||||
ton_node_ =
|
||||
ton::TonNodeManager::create(ton::adnl::AdnlNodeIdShort{lc.dummy0_[0]->id_->id_}, adnl_.get(), rldp_.get(),
|
||||
dht_nodes_[0].get(), overlay_manager_.get(), validator_manager_.get(), db_root_);
|
||||
|
||||
for (auto &x : lc.liteservers_) {
|
||||
auto pk = ton::PrivateKey{x->id_};
|
||||
auto pub_k = ton::adnl::AdnlNodeIdFull{pk.compute_public_key()};
|
||||
auto id = pub_k.compute_short_id();
|
||||
|
||||
td::actor::send_closure(keyring_, &ton::Keyring::add_key, std::move(pk));
|
||||
td::actor::send_closure(adnl_, &ton::adnl::Adnl::add_id, pub_k, ton::adnl::AdnlAddressList{});
|
||||
td::actor::send_closure(validator_manager_, &ton::ValidatorManager::add_ext_server_id, id);
|
||||
td::actor::send_closure(validator_manager_, &ton::ValidatorManager::add_ext_server_port,
|
||||
static_cast<td::uint16>(x->port_));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
td::Result<td::UInt256> get_uint256(std::string str) {
|
||||
if (str.size() != 64) {
|
||||
return td::Status::Error("uint256 must have 64 bytes");
|
||||
}
|
||||
td::UInt256 res;
|
||||
for (size_t i = 0; i < 32; i++) {
|
||||
res.raw[i] = static_cast<td::uint8>(td::hex_to_int(str[2 * i]) * 16 + td::hex_to_int(str[2 * i + 1]));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
SET_VERBOSITY_LEVEL(verbosity_INFO);
|
||||
|
||||
td::set_default_failure_signal_handler().ensure();
|
||||
|
||||
CHECK(vm::init_op_cp0());
|
||||
|
||||
td::actor::ActorOwn<TestNode> x;
|
||||
|
||||
td::OptionsParser p;
|
||||
p.set_description("test basic adnl functionality");
|
||||
p.add_option('v', "verbosity", "set verbosity level", [&](td::Slice arg) {
|
||||
int v = VERBOSITY_NAME(FATAL) + (td::to_integer<int>(arg));
|
||||
SET_VERBOSITY_LEVEL(v);
|
||||
return td::Status::OK();
|
||||
});
|
||||
p.add_option('h', "help", "prints_help", [&]() {
|
||||
char b[10240];
|
||||
td::StringBuilder sb(td::MutableSlice{b, 10000});
|
||||
sb << p;
|
||||
std::cout << sb.as_cslice().c_str();
|
||||
std::exit(2);
|
||||
return td::Status::OK();
|
||||
});
|
||||
p.add_option('C', "global-config", "file to read global config", [&](td::Slice fname) {
|
||||
td::actor::send_closure(x, &TestNode::set_global_config, fname.str());
|
||||
return td::Status::OK();
|
||||
});
|
||||
p.add_option('c', "local-config", "file to read local config", [&](td::Slice fname) {
|
||||
td::actor::send_closure(x, &TestNode::set_local_config, fname.str());
|
||||
return td::Status::OK();
|
||||
});
|
||||
p.add_option('i', "id", "id of instance", [&](td::Slice fname) { return td::Status::OK(); });
|
||||
p.add_option('D', "db", "root for dbs", [&](td::Slice fname) {
|
||||
td::actor::send_closure(x, &TestNode::set_db_root, fname.str());
|
||||
return td::Status::OK();
|
||||
});
|
||||
p.add_option('z', "zero-state", "file with serialized zero state", [&](td::Slice fname) {
|
||||
td::actor::send_closure(x, &TestNode::set_zero_state, fname.str());
|
||||
return td::Status::OK();
|
||||
});
|
||||
p.add_option('d', "daemonize", "set SIGHUP", [&]() {
|
||||
td::set_signal_handler(td::SignalType::HangUp, [](int sig) {
|
||||
#if TD_DARWIN || TD_LINUX
|
||||
close(0);
|
||||
setsid();
|
||||
#endif
|
||||
}).ensure();
|
||||
return td::Status::OK();
|
||||
});
|
||||
#if TD_DARWIN || TD_LINUX
|
||||
p.add_option('l', "logname", "log to file", [&](td::Slice fname) {
|
||||
auto FileLog = td::FileFd::open(td::CSlice(fname.str().c_str()),
|
||||
td::FileFd::Flags::Create | td::FileFd::Flags::Append | td::FileFd::Flags::Write)
|
||||
.move_as_ok();
|
||||
|
||||
dup2(FileLog.get_native_fd().fd(), 1);
|
||||
dup2(FileLog.get_native_fd().fd(), 2);
|
||||
return td::Status::OK();
|
||||
});
|
||||
#endif
|
||||
|
||||
td::actor::Scheduler scheduler({7});
|
||||
|
||||
scheduler.run_in_context([&] { x = td::actor::create_actor<TestNode>("testnode"); });
|
||||
|
||||
scheduler.run_in_context([&] { p.run(argc, argv).ensure(); });
|
||||
scheduler.run_in_context([&] { td::actor::send_closure(x, &TestNode::run); });
|
||||
scheduler.run();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -64,7 +64,11 @@ std::string load_source(std::string name) {
|
|||
|
||||
td::Ref<vm::Cell> get_test_wallet_source() {
|
||||
std::string code = R"ABCD(
|
||||
SETCP0 DUP IFNOTRET INC 32 THROWIF // return if recv_internal, fail unless recv_external
|
||||
SETCP0 DUP IFNOTRET // return if recv_internal
|
||||
DUP 85143 INT EQUAL IFJMP:<{ // "seqno" get-method
|
||||
DROP c4 PUSHCTR CTOS 32 PLDU // cnt
|
||||
}>
|
||||
INC 32 THROWIF // fail unless recv_external
|
||||
512 INT LDSLICEX DUP 32 PLDU // sign cs cnt
|
||||
c4 PUSHCTR CTOS 32 LDU 256 LDU ENDS // sign cs cnt cnt' pubk
|
||||
s1 s2 XCPU // sign cs cnt pubk cnt' cnt
|
||||
|
@ -76,6 +80,7 @@ CHKSIGNU // pubk cs cnt ?
|
|||
ACCEPT
|
||||
SWAP 32 LDU NIP
|
||||
DUP SREFS IF:<{
|
||||
// 3 INT 35 LSHIFT# 3 INT RAWRESERVE // reserve all but 103 Grams from the balance
|
||||
8 LDU LDREF // pubk cnt mode msg cs
|
||||
s0 s2 XCHG SENDRAWMSG // pubk cnt cs ; ( message sent )
|
||||
}>
|
||||
|
@ -86,6 +91,7 @@ INC NEWC 32 STU 256 STU ENDC c4 POPCTR
|
|||
}
|
||||
|
||||
TEST(Tonlib, TestWallet) {
|
||||
LOG(ERROR) << td::base64_encode(std_boc_serialize(get_test_wallet_source()).move_as_ok());
|
||||
CHECK(get_test_wallet_source()->get_hash() == TestWallet::get_init_code()->get_hash());
|
||||
auto fift_output = fift::mem_run_fift(load_source("smartcont/new-wallet.fif"), {"aba", "0"}).move_as_ok();
|
||||
|
||||
|
|
|
@ -198,7 +198,7 @@ int main(int argc, char* argv[]) {
|
|||
{
|
||||
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>(global_config_str, "."))).ensure();
|
||||
}
|
||||
dump_transaction_history(client, get_test_giver_address(client));
|
||||
//dump_transaction_history(client, get_test_giver_address(client));
|
||||
auto wallet_a = create_wallet(client);
|
||||
auto wallet_b = create_empty_wallet(client);
|
||||
transfer_grams(client, wallet_a.address, wallet_b.address, 3000000000, wallet_a.key.get_input_key());
|
||||
|
|
|
@ -56,7 +56,7 @@ td::Ref<vm::Cell> TestWallet::make_a_gift_message(const td::Ed25519::PrivateKey&
|
|||
td::Ref<vm::Cell> TestWallet::get_init_code() {
|
||||
static auto res = [] {
|
||||
auto serialized_code = td::base64_decode(
|
||||
"te6ccgEEAQEAAAAARAAAhP8AIN2k8mCBAgDXGCDXCx/tRNDTH9P/"
|
||||
"te6ccgEEAQEAAAAAUwAAov8AIN0gggFMl7qXMO1E0NcLH+Ck8mCBAgDXGCDXCx/tRNDTH9P/"
|
||||
"0VESuvKhIvkBVBBE+RDyovgAAdMfMSDXSpbTB9QC+wDe0aTIyx/L/8ntVA==")
|
||||
.move_as_ok();
|
||||
return vm::std_boc_deserialize(serialized_code).move_as_ok();
|
||||
|
|
|
@ -2602,6 +2602,11 @@ std::atomic<bool> need_stats_flag{false};
|
|||
void need_stats(int sig) {
|
||||
need_stats_flag.store(true);
|
||||
}
|
||||
std::atomic<bool> rotate_logs_flags{false};
|
||||
void force_rotate_logs(int sig) {
|
||||
rotate_logs_flags.store(true);
|
||||
}
|
||||
|
||||
void dump_memory_stats() {
|
||||
if (!is_memprof_on()) {
|
||||
return;
|
||||
|
@ -2685,21 +2690,18 @@ int main(int argc, char *argv[]) {
|
|||
return td::Status::OK();
|
||||
});
|
||||
p.add_option('d', "daemonize", "set SIGHUP", [&]() {
|
||||
td::set_signal_handler(td::SignalType::HangUp, [](int sig) {
|
||||
#if TD_DARWIN || TD_LINUX
|
||||
close(0);
|
||||
setsid();
|
||||
close(0);
|
||||
setsid();
|
||||
#endif
|
||||
}).ensure();
|
||||
td::set_signal_handler(td::SignalType::HangUp, force_rotate_logs).ensure();
|
||||
return td::Status::OK();
|
||||
});
|
||||
#if TD_DARWIN || TD_LINUX
|
||||
p.add_option('l', "logname", "log to file", [&](td::Slice fname) {
|
||||
logger_ = td::TsFileLog::create(fname.str()).move_as_ok();
|
||||
td::log_interface = logger_.get();
|
||||
return td::Status::OK();
|
||||
});
|
||||
#endif
|
||||
p.add_option('s', "state-ttl", "state will be gc'd after this time (in seconds) default=3600", [&](td::Slice fname) {
|
||||
auto v = td::to_double(fname);
|
||||
acts.push_back([&x, v]() { td::actor::send_closure(x, &ValidatorEngine::set_state_ttl, v); });
|
||||
|
@ -2755,6 +2757,11 @@ int main(int argc, char *argv[]) {
|
|||
if (need_stats_flag.exchange(false)) {
|
||||
dump_stats();
|
||||
}
|
||||
if (rotate_logs_flags.exchange(false)) {
|
||||
if (td::log_interface) {
|
||||
td::log_interface->rotate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -480,7 +480,7 @@ struct BlockHandleImpl : public BlockHandleInterface {
|
|||
}
|
||||
BlockHandleImpl(td::BufferSlice data);
|
||||
~BlockHandleImpl() {
|
||||
CHECK(!need_flush());
|
||||
LOG_CHECK(!need_flush()) << "flags=" << flags_;
|
||||
get_thread_safe_counter().add(-1);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
|
||||
|
||||
if (NOT OPENSSL_FOUND)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
endif()
|
||||
|
||||
set(DUMMY_VALIDATOR_SOURCE
|
||||
accept-block.cpp
|
||||
fake-accept-block.cpp
|
||||
check-proof.cpp
|
||||
collate-query.cpp
|
||||
fabric.cpp
|
||||
shard.cpp
|
||||
signature-set.cpp
|
||||
top-shard-description.cpp
|
||||
validate-query.cpp
|
||||
validator-set.cpp
|
||||
|
||||
check-proof.hpp
|
||||
collate-query.hpp
|
||||
external-message.hpp
|
||||
proof.hpp
|
||||
shard.hpp
|
||||
signature-set.hpp
|
||||
top-shard-description.hpp
|
||||
validate-query.hpp
|
||||
validator-set.hpp
|
||||
)
|
||||
|
||||
add_library(dummy_validator STATIC ${DUMMY_VALIDATOR_SOURCE})
|
||||
|
||||
target_include_directories(dummy_validator PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/..
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/../crypto
|
||||
${OPENSSL_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(dummy_validator PRIVATE tdutils tdactor adnl tl_api dht tdfec
|
||||
overlay catchain validatorsession ton_crypto ton_block)
|
|
@ -1,332 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "accept-block.hpp"
|
||||
#include "adnl/utils.hpp"
|
||||
#include "validator/interfaces/validator-manager.h"
|
||||
#include "ton/ton-tl.hpp"
|
||||
#include "ton/ton-io.hpp"
|
||||
|
||||
#include "validator/fabric.h"
|
||||
#include "validator/invariants.hpp"
|
||||
|
||||
#include "top-shard-description.hpp"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
void AcceptBlockQuery::abort_query(td::Status reason) {
|
||||
if (promise_) {
|
||||
LOG(WARNING) << "aborting accept block " << id_ << " query: " << reason;
|
||||
promise_.set_error(std::move(reason));
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::finish_query() {
|
||||
ValidatorInvariants::check_post_accept(handle_);
|
||||
if (promise_) {
|
||||
promise_.set_value(td::Unit());
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::alarm() {
|
||||
abort_query(td::Status::Error(ErrorCode::timeout, "timeout"));
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::start_up() {
|
||||
alarm_timestamp() = timeout_;
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<BlockHandle> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::got_block_handle, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::get_block_handle, id_, true, std::move(P));
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::got_block_handle(BlockHandle handle) {
|
||||
handle_ = std::move(handle);
|
||||
if (handle_->processed() && handle_->received() && handle_->received_state() && handle_->inited_signatures() &&
|
||||
handle_->inited_split_after() && handle_->inited_merge_before() && handle_->inited_prev() &&
|
||||
(id_.is_masterchain() ? handle_->inited_proof() : handle_->inited_proof_link())) {
|
||||
send_block_description();
|
||||
return;
|
||||
}
|
||||
if (data_.not_null() && !handle_->received()) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::written_block_data);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_data, handle_, data_, std::move(P));
|
||||
} else {
|
||||
written_block_data();
|
||||
}
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::written_block_data() {
|
||||
if (handle_->inited_signatures()) {
|
||||
written_block_signatures();
|
||||
return;
|
||||
}
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::written_block_signatures);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_signatures, handle_, signatures_, std::move(P));
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::written_block_signatures() {
|
||||
if (prev_.size() == 2) {
|
||||
handle_->set_merge(true);
|
||||
} else {
|
||||
handle_->set_merge(false);
|
||||
}
|
||||
|
||||
for (auto &p : prev_) {
|
||||
handle_->set_prev(p);
|
||||
}
|
||||
|
||||
if (handle_->need_flush()) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::written_block_info);
|
||||
}
|
||||
});
|
||||
|
||||
handle_->flush(manager_, handle_, std::move(P));
|
||||
} else {
|
||||
written_block_info();
|
||||
}
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::written_block_info() {
|
||||
LOG(WARNING) << "written block info";
|
||||
if (data_.not_null()) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::got_prev_state, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
CHECK(prev_.size() <= 2);
|
||||
td::actor::send_closure(manager_, &ValidatorManager::wait_prev_block_state, handle_, timeout_, std::move(P));
|
||||
} else {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<BlockData>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::failed_to_get_block_candidate);
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::got_block_data, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::get_block_candidate_data_from_db, id_, std::move(P));
|
||||
}
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::failed_to_get_block_candidate() {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<BlockData>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::got_block_data, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::wait_block_data, handle_, timeout_, std::move(P));
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::got_block_data(td::Ref<BlockData> data) {
|
||||
data_ = std::move(data);
|
||||
if (handle_->received()) {
|
||||
written_block_info();
|
||||
} else {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::written_block_data);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_data, handle_, data_, std::move(P));
|
||||
}
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::got_prev_state(td::Ref<ShardState> state) {
|
||||
LOG(WARNING) << "got prev state";
|
||||
state_ = std::move(state);
|
||||
|
||||
state_.write().apply_block(id_, data_).ensure();
|
||||
|
||||
handle_->set_split(state_->before_split());
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::written_state);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_state, handle_, state_, std::move(P));
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::written_state() {
|
||||
LOG(WARNING) << "written state";
|
||||
|
||||
// generate proof
|
||||
|
||||
CHECK(prev_.size() == 1);
|
||||
std::vector<tl_object_ptr<ton_api::tonNode_blockIdExt>> prev;
|
||||
for (auto &p : prev_) {
|
||||
prev.emplace_back(create_tl_block_id(p));
|
||||
}
|
||||
|
||||
auto proof_link = create_tl_object<ton_api::test0_proofLink>(
|
||||
create_tl_block_id(id_), std::move(prev), Bits256_2_UInt256(state_->root_hash()), handle_->split_after());
|
||||
proof_link_ = create_proof_link(serialize_tl_object(proof_link, true)).move_as_ok();
|
||||
|
||||
if (id_.is_masterchain()) {
|
||||
auto proof = create_tl_object<ton_api::test0_proof>(
|
||||
std::move(proof_link), catchain_seqno_, validator_set_hash_,
|
||||
fetch_tl_object<ton_api::test0_blockSignatures>(signatures_->serialize(), true).move_as_ok());
|
||||
proof_ = create_proof(prev_[0], serialize_tl_object(proof, true)).move_as_ok();
|
||||
}
|
||||
|
||||
if (handle_->id().is_masterchain()) {
|
||||
CHECK(prev_.size() == 1);
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::written_block_next);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_next_block, prev_[0], id_, std::move(P));
|
||||
} else {
|
||||
written_block_next();
|
||||
}
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::written_block_next() {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::written_block_proof);
|
||||
}
|
||||
});
|
||||
|
||||
if (id_.is_masterchain()) {
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_proof, handle_, proof_, std::move(P));
|
||||
} else {
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_proof_link, handle_, proof_link_, std::move(P));
|
||||
}
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::written_block_proof() {
|
||||
if (handle_->need_flush()) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::written_block_info_2);
|
||||
}
|
||||
});
|
||||
|
||||
handle_->flush(manager_, handle_, std::move(P));
|
||||
} else {
|
||||
written_block_info_2();
|
||||
}
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::written_block_info_2() {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AcceptBlockQuery::send_block_description);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::new_block, handle_, state_, std::move(P));
|
||||
}
|
||||
|
||||
void AcceptBlockQuery::send_block_description() {
|
||||
if (!handle_->id().is_masterchain()) {
|
||||
bool after_split = prev_.size() == 1 && handle_->id().id.shard != prev_[0].id.shard;
|
||||
if (after_split) {
|
||||
CHECK(shard_parent(handle_->id().shard_full()) == prev_[0].shard_full());
|
||||
}
|
||||
bool after_merge = prev_.size() == 2;
|
||||
|
||||
auto desc = td::Ref<ShardTopBlockDescriptionImpl>{true,
|
||||
handle_->id(),
|
||||
after_split,
|
||||
after_merge,
|
||||
handle_->split_after(),
|
||||
catchain_seqno_,
|
||||
validator_set_hash_,
|
||||
signatures_->serialize()};
|
||||
td::actor::send_closure(manager_, &ValidatorManager::send_top_shard_block_description, std::move(desc));
|
||||
}
|
||||
finish_query();
|
||||
}
|
||||
|
||||
AcceptBlockQuery::AcceptBlockQuery(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
|
||||
UnixTime catchain_seqno, td::uint32 validator_set_hash,
|
||||
td::Ref<BlockSignatureSet> signatures, bool send_broadcast,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise)
|
||||
: id_(id)
|
||||
, data_(std::move(data))
|
||||
, prev_(std::move(prev))
|
||||
, catchain_seqno_(catchain_seqno)
|
||||
, validator_set_hash_(validator_set_hash)
|
||||
, signatures_(std::move(signatures))
|
||||
, send_broadcast_(send_broadcast)
|
||||
, manager_(manager)
|
||||
, promise_(std::move(promise)) {
|
||||
CHECK(prev_.size() > 0);
|
||||
}
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
#include "ton/ton-types.h"
|
||||
#include "ton/ton-shard.h"
|
||||
#include "interfaces/validator-manager.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
/*
|
||||
*
|
||||
* block data (if not given) can be obtained from:
|
||||
* db as part of collated block
|
||||
* db as block
|
||||
* net
|
||||
* must write block data, block signatures and block state
|
||||
* initialize prev, before_split, after_merge
|
||||
* for masterchain write block proof and set next for prev block
|
||||
* for masterchain run new_block callback
|
||||
*
|
||||
*/
|
||||
|
||||
class AcceptBlockQuery : public td::actor::Actor {
|
||||
public:
|
||||
AcceptBlockQuery(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev, CatchainSeqno catchain_seqno,
|
||||
td::uint32 validator_set_hash, td::Ref<BlockSignatureSet> signatures, bool send_broadcast,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise);
|
||||
|
||||
void abort_query(td::Status reason);
|
||||
void finish_query();
|
||||
void alarm() override;
|
||||
|
||||
void start_up() override;
|
||||
void written_block_data();
|
||||
void written_block_signatures();
|
||||
void got_block_handle(BlockHandle handle);
|
||||
void written_block_info();
|
||||
void failed_to_get_block_candidate();
|
||||
void got_block_data(td::Ref<BlockData> data);
|
||||
void got_prev_state(td::Ref<ShardState> state);
|
||||
void written_state();
|
||||
void written_block_proof();
|
||||
void written_block_next();
|
||||
void written_block_info_2();
|
||||
void applied();
|
||||
void send_block_description();
|
||||
|
||||
private:
|
||||
BlockIdExt id_;
|
||||
td::Ref<BlockData> data_;
|
||||
std::vector<BlockIdExt> prev_;
|
||||
CatchainSeqno catchain_seqno_;
|
||||
td::uint32 validator_set_hash_;
|
||||
td::Ref<BlockSignatureSet> signatures_;
|
||||
bool send_broadcast_;
|
||||
td::Timestamp timeout_ = td::Timestamp::in(600);
|
||||
td::actor::ActorId<ValidatorManager> manager_;
|
||||
td::Promise<td::Unit> promise_;
|
||||
|
||||
FileHash signatures_hash_;
|
||||
BlockHandle handle_;
|
||||
td::Ref<Proof> proof_;
|
||||
td::Ref<ProofLink> proof_link_;
|
||||
|
||||
td::Ref<ShardState> state_;
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "validator/interfaces/block.h"
|
||||
|
||||
#include "adnl/utils.hpp"
|
||||
|
||||
#include "ton/ton-types.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
class Block : public BlockData {
|
||||
private:
|
||||
td::BufferSlice data_;
|
||||
BlockIdExt id_;
|
||||
|
||||
public:
|
||||
td::BufferSlice data() const override {
|
||||
return data_.clone();
|
||||
}
|
||||
FileHash file_hash() const override {
|
||||
return id_.file_hash;
|
||||
}
|
||||
BlockIdExt block_id() const override {
|
||||
return id_;
|
||||
}
|
||||
td::Ref<vm::Cell> root_cell() const override {
|
||||
return {};
|
||||
}
|
||||
Block *make_copy() const override {
|
||||
return new Block(id_, data_.clone());
|
||||
}
|
||||
Block(BlockIdExt id, td::BufferSlice data) : data_(std::move(data)), id_(id) {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,225 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "check-proof.hpp"
|
||||
#include "adnl/utils.hpp"
|
||||
#include "ton/ton-io.hpp"
|
||||
#include "ton/ton-tl.hpp"
|
||||
#include "validator/fabric.h"
|
||||
#include "validator/invariants.hpp"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
void CheckProofLink::alarm() {
|
||||
abort_query(td::Status::Error(ErrorCode::timeout, "timeout"));
|
||||
}
|
||||
|
||||
void CheckProofLink::abort_query(td::Status reason) {
|
||||
if (promise_) {
|
||||
LOG(WARNING) << "aborting check proof link for " << id_ << " query: " << reason;
|
||||
promise_.set_error(std::move(reason));
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void CheckProofLink::finish_query() {
|
||||
ValidatorInvariants::check_post_check_proof_link(handle_);
|
||||
if (promise_) {
|
||||
LOG(WARNING) << "checked proof link for " << handle_->id();
|
||||
promise_.set_result(handle_);
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void CheckProofLink::start_up() {
|
||||
alarm_timestamp() = timeout_;
|
||||
|
||||
auto F = fetch_tl_object<ton_api::test0_proofLink>(proof_->data(), true);
|
||||
if (F.is_error()) {
|
||||
abort_query(F.move_as_error());
|
||||
return;
|
||||
}
|
||||
|
||||
unserialized_proof_ = F.move_as_ok();
|
||||
if (create_block_id(unserialized_proof_->id_) != id_) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "proof for wrong block"));
|
||||
return;
|
||||
}
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<BlockHandle> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CheckProofLink::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CheckProofLink::got_block_handle, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::get_block_handle, id_, true, std::move(P));
|
||||
}
|
||||
|
||||
void CheckProofLink::got_block_handle(BlockHandle handle) {
|
||||
// RUN CHECKS
|
||||
// SHOULD ONLY BE SOME MERKLE PROOFS
|
||||
// DUMMY0 DOES NOT DO IT
|
||||
|
||||
handle_ = std::move(handle);
|
||||
|
||||
std::vector<BlockIdExt> prev;
|
||||
for (auto &p : unserialized_proof_->prev_) {
|
||||
prev.push_back(create_block_id(p));
|
||||
}
|
||||
for (auto &p : prev) {
|
||||
handle_->set_prev(p);
|
||||
}
|
||||
handle_->set_merge(prev.size() == 2);
|
||||
handle_->set_split(unserialized_proof_->split_);
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CheckProofLink::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CheckProofLink::finish_query);
|
||||
}
|
||||
});
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_proof_link, handle_, proof_, std::move(P));
|
||||
}
|
||||
void CheckProof::alarm() {
|
||||
abort_query(td::Status::Error(ErrorCode::timeout, "timeout"));
|
||||
}
|
||||
|
||||
void CheckProof::abort_query(td::Status reason) {
|
||||
if (promise_) {
|
||||
LOG(WARNING) << "aborting check proof for " << id_ << " query: " << reason;
|
||||
promise_.set_error(std::move(reason));
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void CheckProof::finish_query() {
|
||||
ValidatorInvariants::check_post_check_proof(handle_);
|
||||
if (promise_) {
|
||||
LOG(WARNING) << "checked proof for " << handle_->id();
|
||||
promise_.set_result(handle_);
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void CheckProof::start_up() {
|
||||
alarm_timestamp() = timeout_;
|
||||
|
||||
auto F = fetch_tl_object<ton_api::test0_proof>(proof_->data(), true);
|
||||
if (F.is_error()) {
|
||||
abort_query(F.move_as_error());
|
||||
return;
|
||||
}
|
||||
|
||||
unserialized_proof_ = F.move_as_ok();
|
||||
|
||||
auto proof_link_R = create_proof_link(serialize_tl_object(unserialized_proof_->link_, true));
|
||||
if (proof_link_R.is_error()) {
|
||||
abort_query(proof_link_R.move_as_error());
|
||||
return;
|
||||
}
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<BlockHandle> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CheckProof::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CheckProof::got_block_handle, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
run_check_proof_link_query(id_, proof_link_R.move_as_ok(), manager_, timeout_, std::move(P));
|
||||
}
|
||||
|
||||
void CheckProof::got_block_handle(BlockHandle handle) {
|
||||
handle_ = std::move(handle);
|
||||
if (handle_ && handle_->inited_proof()) {
|
||||
finish_query();
|
||||
return;
|
||||
}
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CheckProof::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CheckProof::got_masterchain_state, td::Ref<MasterchainState>{R.move_as_ok()});
|
||||
}
|
||||
});
|
||||
CHECK(!handle_->merge_before());
|
||||
td::actor::send_closure(manager_, &ValidatorManager::wait_block_state_short, handle_->one_prev(true), timeout_,
|
||||
std::move(P));
|
||||
}
|
||||
|
||||
void CheckProof::got_masterchain_state(td::Ref<MasterchainState> state) {
|
||||
state_ = std::move(state);
|
||||
|
||||
auto s = state_->get_validator_set(id_.shard_full());
|
||||
if (s->get_catchain_seqno() != static_cast<CatchainSeqno>(unserialized_proof_->catchain_seqno_)) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "bad validator set ts"));
|
||||
return;
|
||||
}
|
||||
if (s->get_validator_set_hash() != static_cast<td::uint32>(unserialized_proof_->validator_set_hash_)) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "bad validator set hash"));
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<BlockSignature> vec;
|
||||
for (auto &v : unserialized_proof_->signatures_->signatures_) {
|
||||
vec.emplace_back(BlockSignature{UInt256_2_Bits256(v->who_), std::move(v->signature_)});
|
||||
}
|
||||
|
||||
auto sigs = create_signature_set(std::move(vec));
|
||||
|
||||
auto S = s->check_signatures(id_.root_hash, id_.file_hash, sigs);
|
||||
if (S.is_error()) {
|
||||
abort_query(S.move_as_error());
|
||||
return;
|
||||
}
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CheckProof::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CheckProof::set_next);
|
||||
}
|
||||
});
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_next_block, handle_->one_prev(true), handle_->id(),
|
||||
std::move(P));
|
||||
}
|
||||
|
||||
void CheckProof::set_next() {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CheckProof::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CheckProof::finish_query);
|
||||
}
|
||||
});
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_proof, handle_, proof_, std::move(P));
|
||||
}
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
#include "ton/interfaces/block-handle.h"
|
||||
#include "validator/interfaces/validator-manager.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
/*
|
||||
*
|
||||
* check block proof
|
||||
* write proof
|
||||
* initialize prev, before_split, after_merge
|
||||
* initialize prev's next
|
||||
*
|
||||
*/
|
||||
|
||||
class CheckProofLink : public td::actor::Actor {
|
||||
public:
|
||||
CheckProofLink(BlockIdExt id, td::Ref<ProofLink> proof, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Timestamp timeout, td::Promise<BlockHandle> promise)
|
||||
: id_(id), proof_(std::move(proof)), manager_(manager), timeout_(timeout), promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void abort_query(td::Status reason);
|
||||
void finish_query();
|
||||
void alarm() override;
|
||||
|
||||
void start_up() override;
|
||||
void got_block_handle(BlockHandle handle);
|
||||
|
||||
private:
|
||||
BlockIdExt id_;
|
||||
td::Ref<ProofLink> proof_;
|
||||
|
||||
td::actor::ActorId<ValidatorManager> manager_;
|
||||
td::Timestamp timeout_;
|
||||
td::Promise<BlockHandle> promise_;
|
||||
|
||||
BlockHandle handle_;
|
||||
tl_object_ptr<ton_api::test0_proofLink> unserialized_proof_;
|
||||
};
|
||||
|
||||
class CheckProof : public td::actor::Actor {
|
||||
public:
|
||||
CheckProof(BlockIdExt id, td::Ref<Proof> proof, td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
td::Promise<BlockHandle> promise)
|
||||
: id_(id), proof_(std::move(proof)), manager_(manager), timeout_(timeout), promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void abort_query(td::Status reason);
|
||||
void finish_query();
|
||||
void alarm() override;
|
||||
|
||||
void start_up() override;
|
||||
void got_block_handle(BlockHandle handle);
|
||||
void got_masterchain_state(td::Ref<MasterchainState> state);
|
||||
void set_next();
|
||||
|
||||
private:
|
||||
BlockIdExt id_;
|
||||
td::Ref<Proof> proof_;
|
||||
|
||||
td::actor::ActorId<ValidatorManager> manager_;
|
||||
td::Timestamp timeout_;
|
||||
td::Promise<BlockHandle> promise_;
|
||||
|
||||
BlockHandle handle_;
|
||||
td::Ref<MasterchainState> state_;
|
||||
tl_object_ptr<ton_api::test0_proof> unserialized_proof_;
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,238 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "collate-query.hpp"
|
||||
#include "adnl/utils.hpp"
|
||||
#include "td/utils/Random.h"
|
||||
#include "ton/ton-tl.hpp"
|
||||
#include "shard.hpp"
|
||||
#include "validator/fabric.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
void CollateQuery::abort_query(td::Status reason) {
|
||||
if (promise_) {
|
||||
LOG(WARNING) << "aborting collate query: " << reason;
|
||||
promise_.set_error(std::move(reason));
|
||||
}
|
||||
stop();
|
||||
}
|
||||
void CollateQuery::finish_query() {
|
||||
if (promise_) {
|
||||
promise_.set_value(std::move(candidate_));
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void CollateQuery::alarm() {
|
||||
abort_query(td::Status::Error(ErrorCode::timeout, "timeout"));
|
||||
}
|
||||
|
||||
void CollateQuery::start_up() {
|
||||
//CHECK(shard_.workchain == masterchainId);
|
||||
//CHECK(shard_.shard == shardIdAll);
|
||||
LOG(WARNING) << "collate query: prev=" << prev_.size() << " ts=" << validator_set_->get_catchain_seqno();
|
||||
|
||||
alarm_timestamp() = timeout_;
|
||||
ts_ = static_cast<UnixTime>(td::Clocks::system());
|
||||
if (ts_ < min_ts_) {
|
||||
ts_ = min_ts_;
|
||||
}
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::got_prev_state, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
if (prev_.size() == 1) {
|
||||
td::actor::send_closure(manager_, &ValidatorManager::wait_block_state_short, prev_[0], timeout_, std::move(P));
|
||||
} else {
|
||||
CHECK(prev_.size() == 2);
|
||||
td::actor::send_closure(manager_, &ValidatorManager::wait_block_state_merge, prev_[0], prev_[1], timeout_,
|
||||
std::move(P));
|
||||
}
|
||||
}
|
||||
|
||||
void CollateQuery::got_prev_state(td::Ref<ShardState> recv_state) {
|
||||
prev_state_ = td::Ref<ShardStateImpl>{std::move(recv_state)};
|
||||
CHECK(prev_state_.not_null());
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<MasterchainState>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::got_masterchain_state, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
td::actor::send_closure(manager_, &ValidatorManager::get_top_masterchain_state, std::move(P));
|
||||
}
|
||||
|
||||
void CollateQuery::got_masterchain_state(td::Ref<MasterchainState> state) {
|
||||
masterchain_state_ = std::move(state);
|
||||
|
||||
if (masterchain_state_->get_block_id() < min_masterchain_block_id_) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::got_masterchain_state,
|
||||
td::Ref<MasterchainState>{R.move_as_ok()});
|
||||
}
|
||||
});
|
||||
td::actor::send_closure(manager_, &ValidatorManager::wait_block_state_short, min_masterchain_block_id_, timeout_,
|
||||
std::move(P));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!shard_.is_masterchain()) {
|
||||
generate();
|
||||
} else {
|
||||
auto P = td::PromiseCreator::lambda(
|
||||
[SelfId = actor_id(this)](td::Result<std::vector<td::Ref<ShardTopBlockDescription>>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::got_shard_messages, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
td::actor::send_closure(manager_, &ValidatorManager::get_shard_blocks, prev_[0], std::move(P));
|
||||
}
|
||||
}
|
||||
|
||||
void CollateQuery::generate() {
|
||||
BlockSeqno seqno;
|
||||
if (prev_.size() == 1) {
|
||||
seqno = prev_[0].id.seqno + 1;
|
||||
} else {
|
||||
CHECK(prev_.size() == 2);
|
||||
seqno = std::max(prev_[0].id.seqno, prev_[1].id.seqno) + 1;
|
||||
}
|
||||
|
||||
if (shard_.is_masterchain()) {
|
||||
if (seqno <= masterchain_state_->get_seqno()) {
|
||||
abort_query(td::Status::Error(ErrorCode::notready, "generating block, but newer already accepted"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto v = masterchain_state_->get_validator_set(shard_);
|
||||
if (v->get_catchain_seqno() != validator_set_->get_catchain_seqno()) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "bad validator set"));
|
||||
return;
|
||||
}
|
||||
CHECK(v->get_validator_set_hash() == validator_set_->get_validator_set_hash());
|
||||
|
||||
std::vector<tl_object_ptr<ton_api::tonNode_blockIdExt>> prev;
|
||||
for (auto& p : prev_) {
|
||||
prev.emplace_back(create_tl_block_id(p));
|
||||
}
|
||||
|
||||
auto data = td::BufferSlice{10000};
|
||||
td::Random::secure_bytes(data.as_slice());
|
||||
|
||||
auto block = create_tl_object<ton_api::test0_shardchain_block>(
|
||||
shard_.workchain, shard_.shard, seqno, std::move(prev), false, ts_, td::UInt256::zero(),
|
||||
validator_set_->get_catchain_seqno(), validator_set_->get_validator_set_hash(), std::move(data),
|
||||
create_tl_object<ton_api::test0_masterchainBlockExtra_empty>());
|
||||
|
||||
if (shard_.is_masterchain()) {
|
||||
auto m_state = td::Ref<MasterchainStateImpl>{prev_state_};
|
||||
|
||||
bool rotate = ts_ >= m_state->next_validator_rotate_at();
|
||||
|
||||
auto x = create_tl_object<ton_api::test0_masterchainBlockExtra_extra>(td::Random::fast_uint32(), rotate,
|
||||
std::move(shards_));
|
||||
block->extra_ = std::move(x);
|
||||
}
|
||||
|
||||
Bits256 x;
|
||||
x.set_zero();
|
||||
auto block_R =
|
||||
create_block(BlockIdExt{shard_.workchain, shard_.shard, seqno, x, x}, serialize_tl_object(block, true));
|
||||
if (block_R.is_error()) {
|
||||
abort_query(block_R.move_as_error());
|
||||
return;
|
||||
}
|
||||
auto s =
|
||||
prev_state_.write().apply_block(BlockIdExt{shard_.workchain, shard_.shard, seqno, x, x}, block_R.move_as_ok());
|
||||
if (s.is_error()) {
|
||||
abort_query(std::move(s));
|
||||
return;
|
||||
}
|
||||
block->state_ = Bits256_2_UInt256(prev_state_->root_hash());
|
||||
|
||||
auto B = serialize_tl_object(block, true);
|
||||
auto file_hash = UInt256_2_Bits256(sha256_uint256(B.as_slice()));
|
||||
auto root_hash = file_hash;
|
||||
|
||||
auto collated_data = td::BufferSlice{10000};
|
||||
td::Random::secure_bytes(collated_data.as_slice());
|
||||
auto collated_data_file_hash = UInt256_2_Bits256(sha256_uint256(collated_data.as_slice()));
|
||||
|
||||
candidate_.collated_data = std::move(collated_data);
|
||||
candidate_.collated_file_hash = collated_data_file_hash;
|
||||
candidate_.data = std::move(B);
|
||||
candidate_.id = BlockIdExt{BlockId{shard_.workchain, shard_.shard, seqno}, root_hash, file_hash};
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &CollateQuery::finish_query);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_candidate, candidate_.id, candidate_.clone(),
|
||||
std::move(P));
|
||||
}
|
||||
|
||||
void CollateQuery::got_shard_messages(std::vector<td::Ref<ShardTopBlockDescription>> shards) {
|
||||
for (auto& s : shards) {
|
||||
// TODO validate
|
||||
shards_.emplace_back(create_tl_object<ton_api::test0_masterchain_shardInfo>(
|
||||
create_tl_block_id(s->block_id()), false, s->before_split(), false, false));
|
||||
}
|
||||
generate();
|
||||
}
|
||||
|
||||
CollateQuery::CollateQuery(ShardIdFull shard, UnixTime min_ts, BlockIdExt min_masterchain_block_id,
|
||||
std::vector<BlockIdExt> prev, td::Ref<ValidatorSet> validator_set,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
td::Promise<BlockCandidate> promise)
|
||||
: shard_(shard)
|
||||
, min_ts_(min_ts)
|
||||
, min_masterchain_block_id_{min_masterchain_block_id}
|
||||
, prev_(std::move(prev))
|
||||
, validator_set_(std::move(validator_set))
|
||||
, manager_(manager)
|
||||
, timeout_(timeout)
|
||||
, promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "validator/interfaces/validator-manager.h"
|
||||
#include "shard.hpp"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
class CollateQuery : public td::actor::Actor {
|
||||
public:
|
||||
CollateQuery(ShardIdFull shard, td::uint32 min_ts, BlockIdExt min_masterchain_block_id, std::vector<BlockIdExt> prev,
|
||||
td::Ref<ValidatorSet> validator_set, td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
td::Promise<BlockCandidate> promise);
|
||||
|
||||
void alarm() override;
|
||||
|
||||
void abort_query(td::Status reason);
|
||||
void finish_query();
|
||||
|
||||
void start_up() override;
|
||||
void got_prev_state(td::Ref<ShardState> state);
|
||||
void got_masterchain_state(td::Ref<MasterchainState> state);
|
||||
void got_shard_messages(std::vector<td::Ref<ShardTopBlockDescription>> shards);
|
||||
void generate();
|
||||
void written_block_data();
|
||||
void written_block_collated_data();
|
||||
|
||||
private:
|
||||
ShardIdFull shard_;
|
||||
UnixTime min_ts_;
|
||||
BlockIdExt min_masterchain_block_id_;
|
||||
|
||||
std::vector<BlockIdExt> prev_;
|
||||
td::Ref<ValidatorSet> validator_set_;
|
||||
td::actor::ActorId<ValidatorManager> manager_;
|
||||
td::Timestamp timeout_;
|
||||
td::Promise<BlockCandidate> promise_;
|
||||
|
||||
td::Ref<MasterchainState> masterchain_state_;
|
||||
td::Ref<ShardStateImpl> prev_state_;
|
||||
|
||||
BlockCandidate candidate_;
|
||||
UnixTime ts_;
|
||||
|
||||
std::vector<tl_object_ptr<ton_api::test0_masterchain_shardInfo>> shards_;
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "validator/interfaces/external-message.h"
|
||||
#include "auto/tl/ton_api.h"
|
||||
#include "adnl/utils.hpp"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
class ExtMessageImpl : public ExtMessage {
|
||||
public:
|
||||
AccountIdPrefixFull shard() const override {
|
||||
return shard_;
|
||||
}
|
||||
td::BufferSlice serialize() const override {
|
||||
return data_.clone();
|
||||
}
|
||||
td::Ref<vm::Cell> root_cell() const override {
|
||||
UNREACHABLE();
|
||||
}
|
||||
Hash hash() const override {
|
||||
return hash_;
|
||||
}
|
||||
|
||||
ExtMessageImpl *make_copy() const override {
|
||||
return new ExtMessageImpl{shard_, data_.clone(), hash_};
|
||||
}
|
||||
|
||||
ExtMessageImpl(AccountIdPrefixFull shard, td::BufferSlice data, Hash hash)
|
||||
: shard_(shard), data_(std::move(data)), hash_(hash) {
|
||||
}
|
||||
|
||||
ExtMessageImpl(tl_object_ptr<ton_api::test0_extMessage> data) {
|
||||
data_ = serialize_tl_object(data, true);
|
||||
hash_ = UInt256_2_Bits256(get_tl_object_sha256(data));
|
||||
shard_ = AccountIdPrefixFull{data->workchain_, static_cast<AccountIdPrefix>(data->shard_)};
|
||||
}
|
||||
|
||||
private:
|
||||
AccountIdPrefixFull shard_;
|
||||
td::BufferSlice data_;
|
||||
Hash hash_;
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,169 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "validator/fabric.h"
|
||||
#include "block.hpp"
|
||||
#include "external-message.hpp"
|
||||
#include "proof.hpp"
|
||||
#include "signature-set.hpp"
|
||||
#include "shard.hpp"
|
||||
#include "accept-block.hpp"
|
||||
#include "fake-accept-block.hpp"
|
||||
#include "check-proof.hpp"
|
||||
#include "collate-query.hpp"
|
||||
#include "validate-query.hpp"
|
||||
#include "top-shard-description.hpp"
|
||||
|
||||
#include "validator/db/rootdb.hpp"
|
||||
#include "validator/block-handle.hpp"
|
||||
#include "validator/apply-block.hpp"
|
||||
|
||||
#include "td/utils/Random.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
td::actor::ActorOwn<Db> create_db_actor(td::actor::ActorId<ValidatorManager> manager, std::string db_root_) {
|
||||
return td::actor::create_actor<RootDb>("db", manager, db_root_);
|
||||
}
|
||||
|
||||
td::Result<td::Ref<BlockData>> create_block(BlockIdExt block_id, td::BufferSlice data) {
|
||||
return td::Ref<dummy0::Block>{true, block_id, std::move(data)};
|
||||
}
|
||||
|
||||
td::Result<td::Ref<BlockData>> create_block(ReceivedBlock data) {
|
||||
return td::Ref<dummy0::Block>{true, data.id, std::move(data.data)};
|
||||
}
|
||||
|
||||
td::Result<td::Ref<Proof>> create_proof(BlockIdExt masterchain_block_id, td::BufferSlice proof) {
|
||||
return td::Ref<dummy0::ProofImpl>{true, masterchain_block_id, std::move(proof)};
|
||||
}
|
||||
|
||||
td::Result<td::Ref<ProofLink>> create_proof_link(td::BufferSlice proof) {
|
||||
return td::Ref<dummy0::ProofLinkImpl>{true, std::move(proof)};
|
||||
}
|
||||
|
||||
td::Result<td::Ref<BlockSignatureSet>> create_signature_set(td::BufferSlice sig_set) {
|
||||
return dummy0::BlockSignatureSetImpl::fetch(std::move(sig_set));
|
||||
}
|
||||
|
||||
td::Result<td::Ref<ShardState>> create_shard_state(BlockIdExt block_id, td::BufferSlice data) {
|
||||
return dummy0::ShardStateImpl::fetch(block_id, std::move(data));
|
||||
}
|
||||
|
||||
td::Result<td::Ref<ShardState>> create_shard_state(BlockIdExt block_id, td::Ref<vm::DataCell> root_cell) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
td::Result<BlockHandle> create_block_handle(td::BufferSlice data) {
|
||||
return ton::validator::BlockHandleImpl::create(std::move(data));
|
||||
}
|
||||
|
||||
BlockHandle create_empty_block_handle(BlockIdExt id) {
|
||||
return ton::validator::BlockHandleImpl::create_empty(id);
|
||||
}
|
||||
|
||||
//td::Ref<McShardHash> create_mc_shard(ShardIdFull id, ZeroStateIdExt zero_top_block) {
|
||||
// return td::Ref<dummy0::McShardHashImpl>{true, zero_top_block};
|
||||
//}
|
||||
|
||||
td::Ref<BlockSignatureSet> create_signature_set(std::vector<BlockSignature> sig_set) {
|
||||
return td::Ref<dummy0::BlockSignatureSetImpl>{true, std::move(sig_set)};
|
||||
}
|
||||
|
||||
td::Result<td::Ref<ExtMessage>> create_ext_message(td::BufferSlice data) {
|
||||
TRY_RESULT(B, fetch_tl_object<ton_api::test0_extMessage>(std::move(data), true));
|
||||
return td::Ref<dummy0::ExtMessageImpl>{true, std::move(B)};
|
||||
}
|
||||
|
||||
void run_accept_block_query(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
|
||||
td::Ref<ValidatorSet> validator_set, td::Ref<BlockSignatureSet> signatures,
|
||||
bool send_broadcast, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Promise<td::Unit> promise) {
|
||||
td::actor::create_actor<dummy0::AcceptBlockQuery>(
|
||||
"accept", id, std::move(data), prev, validator_set->get_catchain_seqno(), validator_set->get_validator_set_hash(),
|
||||
std::move(signatures), send_broadcast, manager, std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
void run_fake_accept_block_query(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
|
||||
td::Ref<ValidatorSet> validator_set, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Promise<td::Unit> promise) {
|
||||
td::actor::create_actor<FakeAcceptBlockQuery>("fakeaccept", id, std::move(data), std::move(prev), 0, 0,
|
||||
td::Ref<BlockSignatureSet>{}, std::move(manager), std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
void run_apply_block_query(BlockIdExt id, td::Ref<BlockData> block, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Timestamp timeout, td::Promise<td::Unit> promise) {
|
||||
td::actor::create_actor<ApplyBlock>("apply", id, std::move(block), manager, timeout, std::move(promise)).release();
|
||||
}
|
||||
|
||||
void run_check_proof_query(BlockIdExt id, td::Ref<Proof> proof, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Timestamp timeout, td::Promise<BlockHandle> promise) {
|
||||
td::actor::create_actor<dummy0::CheckProof>("checkproof", id, std::move(proof), manager, timeout, std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
void run_check_proof_link_query(BlockIdExt id, td::Ref<ProofLink> proof, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Timestamp timeout, td::Promise<BlockHandle> promise) {
|
||||
td::actor::create_actor<dummy0::CheckProofLink>("checkprooflink", id, std::move(proof), manager, timeout,
|
||||
std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
void run_validate_query(ShardIdFull shard, UnixTime min_ts, BlockIdExt min_masterchain_block_id,
|
||||
std::vector<BlockIdExt> prev, BlockCandidate candidate, td::Ref<ValidatorSet> validator_set,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
td::Promise<ValidateCandidateResult> promise) {
|
||||
td::actor::create_actor<dummy0::ValidateQuery>(
|
||||
"validateblock", shard, min_ts, min_masterchain_block_id, std::move(prev), std::move(candidate),
|
||||
validator_set->get_catchain_seqno(), validator_set->get_validator_set_hash(), manager, timeout,
|
||||
std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
void run_collate_query(ShardIdFull shard, td::uint32 min_ts, const BlockIdExt& min_masterchain_block_id,
|
||||
std::vector<BlockIdExt> prev, td::Ref<ValidatorSet> validator_set,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
td::Promise<BlockCandidate> promise) {
|
||||
td::actor::create_actor<dummy0::CollateQuery>("collator", shard, min_ts, min_masterchain_block_id, std::move(prev),
|
||||
std::move(validator_set), manager, timeout, std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
void run_liteserver_query(td::BufferSlice data, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
LOG(ERROR) << "answering";
|
||||
promise.set_value(serialize_tl_object(create_tl_object<ton_api::testInt>(td::Random::fast_uint32()), true));
|
||||
}
|
||||
|
||||
void run_validate_shard_block_description(td::BufferSlice data, BlockHandle masterchain_block,
|
||||
td::Ref<MasterchainState> masterchain_state,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
td::Promise<td::Ref<ShardTopBlockDescription>> promise, bool is_fake) {
|
||||
td::actor::create_actor<dummy0::ValidateShardTopBlockDescription>(
|
||||
"topshardfetch", std::move(data), std::move(masterchain_block), std::move(masterchain_state), manager, timeout,
|
||||
std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,227 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "fake-accept-block.hpp"
|
||||
#include "adnl/utils.hpp"
|
||||
#include "interfaces/validator-manager.h"
|
||||
#include "ton/ton-tl.hpp"
|
||||
|
||||
#include "fabric.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
void FakeAcceptBlockQuery::abort_query(td::Status reason) {
|
||||
if (promise_) {
|
||||
LOG(WARNING) << "aborting accept block query: " << reason;
|
||||
promise_.set_error(std::move(reason));
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::finish_query() {
|
||||
if (promise_) {
|
||||
promise_.set_value(td::Unit());
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::alarm() {
|
||||
abort_query(td::Status::Error(ErrorCode::timeout, "timeout"));
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::start_up() {
|
||||
alarm_timestamp() = timeout_;
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<BlockHandle> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::got_block_handle, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::get_block_handle, id_, true, std::move(P));
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::got_block_handle(BlockHandle handle) {
|
||||
handle_ = std::move(handle);
|
||||
CHECK(!handle_->received());
|
||||
CHECK(data_.not_null());
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::written_block_data);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_data, handle_, data_, std::move(P));
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::written_block_data() {
|
||||
written_block_signatures();
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::written_block_signatures() {
|
||||
if (prev_.size() == 2) {
|
||||
handle_->set_merge(true);
|
||||
} else {
|
||||
handle_->set_merge(false);
|
||||
}
|
||||
|
||||
for (auto &p : prev_) {
|
||||
handle_->set_prev(p);
|
||||
}
|
||||
|
||||
if (handle_->need_flush()) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::written_block_info);
|
||||
}
|
||||
});
|
||||
|
||||
handle_->flush(manager_, handle_, std::move(P));
|
||||
} else {
|
||||
written_block_info();
|
||||
}
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::written_block_info() {
|
||||
LOG(WARNING) << "written block info";
|
||||
CHECK(handle_->received());
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::got_prev_state, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
CHECK(prev_.size() <= 2);
|
||||
td::actor::send_closure(manager_, &ValidatorManager::wait_prev_block_state, handle_, timeout_, std::move(P));
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::got_prev_state(td::Ref<ShardState> state) {
|
||||
LOG(WARNING) << "got prev state";
|
||||
state_ = std::move(state);
|
||||
|
||||
state_.write().apply_block(id_, data_).ensure();
|
||||
|
||||
handle_->set_split(state_->before_split());
|
||||
|
||||
handle_->set_state_root_hash(state_->root_hash());
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::written_state);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_state, handle_, state_, std::move(P));
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::written_state() {
|
||||
LOG(WARNING) << "written state";
|
||||
if (!id_.id.is_masterchain()) {
|
||||
finish_query();
|
||||
return;
|
||||
}
|
||||
|
||||
// generate proof
|
||||
|
||||
CHECK(prev_.size() == 1);
|
||||
proof_ = create_proof(prev_[0], td::BufferSlice()).move_as_ok();
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::written_block_proof);
|
||||
}
|
||||
});
|
||||
//handle_->set_masterchain_block(prev_[0]);
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_proof, handle_, proof_, std::move(P));
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::written_block_proof() {
|
||||
CHECK(prev_.size() <= 1);
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::written_block_next);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_next_block, prev_[0], id_, std::move(P));
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::written_block_next() {
|
||||
if (handle_->need_flush()) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::written_block_info_2);
|
||||
}
|
||||
});
|
||||
|
||||
handle_->flush(manager_, handle_, std::move(P));
|
||||
} else {
|
||||
written_block_info_2();
|
||||
}
|
||||
}
|
||||
|
||||
void FakeAcceptBlockQuery::written_block_info_2() {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &FakeAcceptBlockQuery::finish_query);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::new_block, handle_, state_, std::move(P));
|
||||
}
|
||||
|
||||
FakeAcceptBlockQuery::FakeAcceptBlockQuery(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
|
||||
UnixTime validator_set_ts, td::uint32 validator_set_hash,
|
||||
td::Ref<BlockSignatureSet> signatures,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise)
|
||||
: id_(id)
|
||||
, data_(std::move(data))
|
||||
, prev_(std::move(prev))
|
||||
, validator_set_ts_(validator_set_ts)
|
||||
, validator_set_hash_(validator_set_hash)
|
||||
, signatures_(std::move(signatures))
|
||||
, manager_(manager)
|
||||
, promise_(std::move(promise)) {
|
||||
CHECK(prev_.size() > 0);
|
||||
}
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,88 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
#include "ton/ton-types.h"
|
||||
#include "ton/ton-shard.h"
|
||||
#include "interfaces/validator-manager.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
/*
|
||||
*
|
||||
* block data (if not given) can be obtained from:
|
||||
* db as part of collated block
|
||||
* db as block
|
||||
* net
|
||||
* must write block data, block signatures and block state
|
||||
* initialize prev, before_split, after_merge
|
||||
* for masterchain write block proof and set next for prev block
|
||||
* for masterchain run new_block callback
|
||||
*
|
||||
*/
|
||||
|
||||
class FakeAcceptBlockQuery : public td::actor::Actor {
|
||||
public:
|
||||
FakeAcceptBlockQuery(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev, UnixTime validator_set_ts,
|
||||
td::uint32 validator_set_hash, td::Ref<BlockSignatureSet> signatures,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise);
|
||||
|
||||
void abort_query(td::Status reason);
|
||||
void finish_query();
|
||||
void alarm() override;
|
||||
|
||||
void start_up() override;
|
||||
void written_block_data();
|
||||
void written_block_signatures();
|
||||
void got_block_handle(BlockHandle handle);
|
||||
void written_block_info();
|
||||
void failed_to_get_block_candidate();
|
||||
void got_block_data(td::Ref<BlockData> data);
|
||||
void got_prev_state(td::Ref<ShardState> state);
|
||||
void written_state();
|
||||
void written_block_proof();
|
||||
void written_block_next();
|
||||
void written_block_info_2();
|
||||
void applied();
|
||||
|
||||
private:
|
||||
BlockIdExt id_;
|
||||
td::Ref<BlockData> data_;
|
||||
std::vector<BlockIdExt> prev_;
|
||||
UnixTime validator_set_ts_;
|
||||
td::uint32 validator_set_hash_;
|
||||
td::Ref<BlockSignatureSet> signatures_;
|
||||
td::Timestamp timeout_;
|
||||
td::actor::ActorId<ValidatorManager> manager_;
|
||||
td::Promise<td::Unit> promise_;
|
||||
|
||||
FileHash signatures_hash_;
|
||||
BlockHandle handle_;
|
||||
FileHash proof_hash_;
|
||||
td::Ref<Proof> proof_;
|
||||
|
||||
td::Ref<ShardState> state_;
|
||||
};
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,85 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "validator/interfaces/proof.h"
|
||||
#include "adnl/utils.hpp"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
class ProofImpl : public ton::validator::Proof {
|
||||
private:
|
||||
BlockIdExt masterchain_block_id_;
|
||||
td::BufferSlice data_;
|
||||
FileHash file_hash_;
|
||||
|
||||
public:
|
||||
td::BufferSlice data() const override {
|
||||
return data_.clone();
|
||||
}
|
||||
FileHash file_hash() const override {
|
||||
return file_hash_;
|
||||
}
|
||||
BlockIdExt masterchain_block_id() const override {
|
||||
return masterchain_block_id_;
|
||||
}
|
||||
|
||||
ProofImpl *make_copy() const override {
|
||||
return new ProofImpl(masterchain_block_id_, data_.clone(), file_hash_);
|
||||
}
|
||||
ProofImpl(BlockIdExt masterchain_block_id, td::BufferSlice data, FileHash file_hash)
|
||||
: masterchain_block_id_(masterchain_block_id), data_(std::move(data)), file_hash_(file_hash) {
|
||||
}
|
||||
ProofImpl(BlockIdExt masterchain_block_id, td::BufferSlice data)
|
||||
: masterchain_block_id_(masterchain_block_id), data_(std::move(data)) {
|
||||
file_hash_ = UInt256_2_Bits256(sha256_uint256(data_.as_slice()));
|
||||
}
|
||||
};
|
||||
|
||||
class ProofLinkImpl : public ton::validator::ProofLink {
|
||||
private:
|
||||
td::BufferSlice data_;
|
||||
FileHash file_hash_;
|
||||
|
||||
public:
|
||||
td::BufferSlice data() const override {
|
||||
return data_.clone();
|
||||
}
|
||||
FileHash file_hash() const override {
|
||||
return file_hash_;
|
||||
}
|
||||
ProofLinkImpl *make_copy() const override {
|
||||
return new ProofLinkImpl(data_.clone(), file_hash_);
|
||||
}
|
||||
ProofLinkImpl(td::BufferSlice data, FileHash file_hash) : data_(std::move(data)), file_hash_(file_hash) {
|
||||
}
|
||||
ProofLinkImpl(td::BufferSlice data) : data_(std::move(data)) {
|
||||
file_hash_ = UInt256_2_Bits256(sha256_uint256(data_.as_slice()));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,324 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "shard.hpp"
|
||||
#include "adnl/utils.hpp"
|
||||
#include "validator-set.hpp"
|
||||
#include "validator/interfaces/block.h"
|
||||
#include "ton/ton-tl.hpp"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
td::Ref<ton::validator::ValidatorSet> MasterchainStateImpl::calculate_validator_set(ShardIdFull shard, td::uint32 cnt,
|
||||
UnixTime ts,
|
||||
td::uint32 randseed) const {
|
||||
auto hash = ts ^ randseed;
|
||||
auto hash2 = 1000000007;
|
||||
|
||||
auto idx = hash % validators_.size();
|
||||
|
||||
std::vector<std::pair<ValidatorFullId, ValidatorWeight>> vec;
|
||||
std::map<NodeIdShort, size_t> m;
|
||||
while (cnt-- > 0) {
|
||||
auto &d = validators_[idx];
|
||||
auto id = d.short_id();
|
||||
auto it = m.find(id);
|
||||
if (it != m.end()) {
|
||||
vec[it->second].second++;
|
||||
} else {
|
||||
vec.emplace_back(d, 1);
|
||||
m[id] = vec.size() - 1;
|
||||
}
|
||||
idx = (idx + hash2) % validators_.size();
|
||||
}
|
||||
|
||||
return td::Ref<ValidatorSetImpl>{true, ts, shard.shard, std::move(vec)};
|
||||
}
|
||||
|
||||
td::Ref<ValidatorSet> MasterchainStateImpl::get_validator_set(ShardIdFull shard) const {
|
||||
//CHECK(shard.is_masterchain());
|
||||
return calculate_validator_set(shard, 200, cur_validator_ts_, cur_randseed_);
|
||||
}
|
||||
|
||||
td::Ref<ValidatorSet> MasterchainStateImpl::get_next_validator_set(ShardIdFull shard) const {
|
||||
//CHECK(shard.is_masterchain());
|
||||
return calculate_validator_set(shard, 200, cur_validator_ts_ + 1, next_randseed_);
|
||||
}
|
||||
|
||||
td::Ref<ValidatorSet> MasterchainStateImpl::get_validator_set(ShardIdFull shard, UnixTime ts) const {
|
||||
if (ts == cur_validator_ts_) {
|
||||
return get_validator_set(shard);
|
||||
} else if (ts == cur_validator_ts_ + 1) {
|
||||
return get_next_validator_set(shard);
|
||||
} else {
|
||||
return td::Ref<ValidatorSet>{};
|
||||
}
|
||||
}
|
||||
|
||||
td::Status MasterchainStateImpl::apply_block(BlockIdExt id, td::Ref<BlockData> block) {
|
||||
TRY_STATUS(ShardStateImpl::apply_block(id, block));
|
||||
TRY_RESULT(B, fetch_tl_object<ton_api::test0_shardchain_block>(block->data(), true));
|
||||
|
||||
if (B->extra_->get_id() != ton_api::test0_masterchainBlockExtra_extra::ID) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "bad block extra");
|
||||
}
|
||||
auto E = static_cast<const ton_api::test0_masterchainBlockExtra_extra *>(B->extra_.get());
|
||||
|
||||
if (B->prev_.size() != 1) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "bad prev size");
|
||||
}
|
||||
auto prev = create_block_id(B->prev_[0]);
|
||||
CHECK(prev.id.seqno == prev_blocks_.size());
|
||||
prev_blocks_.push_back(prev);
|
||||
|
||||
if (E->rotate_) {
|
||||
CHECK(static_cast<UnixTime>(B->ts_) >= next_validator_rotate_at_);
|
||||
next_validator_rotate_at_ = B->ts_ + 300;
|
||||
cur_validator_ts_++;
|
||||
cur_randseed_ = next_randseed_;
|
||||
next_randseed_ = E->randseed_;
|
||||
} else {
|
||||
CHECK(static_cast<UnixTime>(B->ts_) < next_validator_rotate_at_);
|
||||
}
|
||||
|
||||
for (auto &shard : E->shards_) {
|
||||
ShardDescr S{shard};
|
||||
auto shard_B = S.top_block;
|
||||
if (shard_B.id.seqno == 0) {
|
||||
for (auto &X : shards_) {
|
||||
if (X.top_block.id.workchain == shard_B.id.workchain) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "bad new block: duplicate zero block");
|
||||
}
|
||||
}
|
||||
shards_.emplace(std::move(S));
|
||||
} else {
|
||||
if (S.after_split) {
|
||||
if (S.top_block.id.shard == shardIdAll) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "cannot merge fullshard");
|
||||
}
|
||||
auto L = S;
|
||||
L.top_block.id.shard = shard_parent(S.top_block.id.shard);
|
||||
if (shards_.count(L) != 1) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "unknown parent shard");
|
||||
}
|
||||
shards_.erase(L);
|
||||
shards_.emplace(std::move(S));
|
||||
} else if (S.after_merge) {
|
||||
auto L = S;
|
||||
L.top_block.id.shard = shard_child(S.top_block.id.shard, true);
|
||||
if (shards_.count(L) != 1) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "unknown child L shard");
|
||||
}
|
||||
auto R = S;
|
||||
R.top_block.id.shard = shard_child(S.top_block.id.shard, false);
|
||||
if (shards_.count(R) != 1) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "unknown child R shard");
|
||||
}
|
||||
shards_.erase(L);
|
||||
shards_.erase(R);
|
||||
shards_.emplace(std::move(S));
|
||||
} else {
|
||||
if (shards_.count(S) != 1) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "unknown shard");
|
||||
}
|
||||
shards_.erase(S);
|
||||
shards_.emplace(std::move(S));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return td::Status::OK();
|
||||
}
|
||||
|
||||
td::Result<td::BufferSlice> MasterchainStateImpl::serialize() const {
|
||||
TRY_RESULT(B, ShardStateImpl::serialize());
|
||||
auto F = fetch_tl_object<ton_api::test0_shardchain_state>(std::move(B), true).move_as_ok();
|
||||
|
||||
std::vector<tl_object_ptr<ton_api::PublicKey>> pool;
|
||||
for (auto &v : validators_) {
|
||||
pool.emplace_back(v.tl());
|
||||
}
|
||||
|
||||
std::vector<tl_object_ptr<ton_api::tonNode_blockIdExt>> prev;
|
||||
for (auto &p : prev_blocks_) {
|
||||
prev.emplace_back(create_tl_block_id(p));
|
||||
}
|
||||
|
||||
std::vector<tl_object_ptr<ton_api::test0_masterchain_shardInfo>> shards;
|
||||
for (auto &shard : shards_) {
|
||||
shards.emplace_back(shard.tl());
|
||||
}
|
||||
auto obj = create_tl_object<ton_api::test0_masterchainStateExtra_extra>(
|
||||
cur_validator_ts_, cur_randseed_, next_randseed_, next_validator_rotate_at_, std::move(prev), std::move(shards),
|
||||
std::move(pool));
|
||||
F->extra_ = std::move(obj);
|
||||
return serialize_tl_object(F, true);
|
||||
}
|
||||
|
||||
td::Result<td::Ref<MasterchainState>> MasterchainStateImpl::fetch(BlockIdExt block_id, td::BufferSlice data) {
|
||||
TRY_RESULT(F, fetch_tl_object<ton_api::test0_shardchain_state>(std::move(data), true));
|
||||
|
||||
return td::Ref<MasterchainStateImpl>{true, F, block_id};
|
||||
}
|
||||
|
||||
td::Result<td::Ref<ShardState>> ShardStateImpl::fetch(BlockIdExt block_id, td::BufferSlice data) {
|
||||
TRY_RESULT(F, fetch_tl_object<ton_api::test0_shardchain_state>(std::move(data), true));
|
||||
|
||||
if (block_id.id.workchain == masterchainId) {
|
||||
return td::Ref<MasterchainStateImpl>{true, F, block_id};
|
||||
} else {
|
||||
return td::Ref<ShardStateImpl>{true, F, block_id};
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<td::Ref<McShardHash>> MasterchainStateImpl::get_shards() const {
|
||||
std::vector<td::Ref<McShardHash>> shards;
|
||||
for (auto &shard : shards_) {
|
||||
shards.emplace_back(shard.mc_shard());
|
||||
}
|
||||
return shards;
|
||||
}
|
||||
|
||||
MasterchainStateImpl::MasterchainStateImpl(const tl_object_ptr<ton_api::test0_shardchain_state> &state,
|
||||
BlockIdExt block_id)
|
||||
: ShardStateImpl{state, block_id} {
|
||||
CHECK(state->extra_->get_id() == ton_api::test0_masterchainStateExtra_extra::ID);
|
||||
auto E = static_cast<const ton_api::test0_masterchainStateExtra_extra *>(state->extra_.get());
|
||||
|
||||
cur_validator_ts_ = E->validator_ts_;
|
||||
cur_randseed_ = E->validator_randseed_;
|
||||
next_randseed_ = E->next_randseed_;
|
||||
next_validator_rotate_at_ = E->next_rotate_at_;
|
||||
|
||||
for (auto &v : E->pool_) {
|
||||
validators_.emplace_back(PublicKey{v});
|
||||
}
|
||||
|
||||
for (auto &p : E->prev_blocks_) {
|
||||
prev_blocks_.push_back(create_block_id(p));
|
||||
}
|
||||
|
||||
for (auto &shard : E->shards_) {
|
||||
shards_.emplace(shard);
|
||||
}
|
||||
}
|
||||
|
||||
bool MasterchainStateImpl::ancestor_is_valid(BlockIdExt id) const {
|
||||
if (id.id.seqno > get_seqno()) {
|
||||
return false;
|
||||
}
|
||||
if (id.id.seqno == get_seqno()) {
|
||||
return get_block_id() == id;
|
||||
}
|
||||
return prev_blocks_[id.id.seqno] == id;
|
||||
}
|
||||
|
||||
MasterchainStateImpl::ShardDescr::ShardDescr(const tl_object_ptr<ton_api::test0_masterchain_shardInfo> &from) {
|
||||
top_block = create_block_id(from->last_block_);
|
||||
before_merge = from->before_merge_;
|
||||
before_split = from->before_split_;
|
||||
after_merge = from->after_merge_;
|
||||
after_split = from->after_split_;
|
||||
}
|
||||
tl_object_ptr<ton_api::test0_masterchain_shardInfo> MasterchainStateImpl::ShardDescr::tl() const {
|
||||
return create_tl_object<ton_api::test0_masterchain_shardInfo>(create_tl_block_id(top_block), before_merge,
|
||||
before_split, after_merge, after_split);
|
||||
}
|
||||
td::Ref<McShardHash> MasterchainStateImpl::ShardDescr::mc_shard() const {
|
||||
return td::Ref<McShardHashImpl>{true, top_block, before_split, before_merge};
|
||||
}
|
||||
|
||||
RootHash ShardStateImpl::root_hash() const {
|
||||
auto h = sha256_uint256(serialize().move_as_ok());
|
||||
return UInt256_2_Bits256(h);
|
||||
}
|
||||
|
||||
td::Result<td::BufferSlice> ShardStateImpl::serialize() const {
|
||||
auto obj =
|
||||
create_tl_object<ton_api::test0_shardchain_state>(shard_.workchain, shard_.shard, seqno_, ts_, before_split_,
|
||||
create_tl_object<ton_api::test0_masterchainStateExtra_empty>());
|
||||
return serialize_tl_object(obj, true);
|
||||
}
|
||||
|
||||
td::Status ShardStateImpl::apply_block(BlockIdExt id, td::Ref<BlockData> block) {
|
||||
TRY_RESULT(B, fetch_tl_object<ton_api::test0_shardchain_block>(block->data(), true));
|
||||
if (static_cast<BlockSeqno>(B->seqno_) != seqno_ + 1) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "bad seqno");
|
||||
}
|
||||
if (static_cast<UnixTime>(B->ts_) <= ts_) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "time goes back");
|
||||
}
|
||||
if (B->workchain_ != shard_.workchain) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "bad workchain");
|
||||
}
|
||||
if (static_cast<ShardId>(B->shard_) != shard_.shard) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "bad shard");
|
||||
}
|
||||
seqno_++;
|
||||
ts_ = B->ts_;
|
||||
before_split_ = B->split_;
|
||||
return td::Status::OK();
|
||||
}
|
||||
|
||||
ShardStateImpl::ShardStateImpl(const tl_object_ptr<ton_api::test0_shardchain_state> &state, BlockIdExt block_id) {
|
||||
blocks_id_ = {block_id};
|
||||
shard_ = ShardIdFull{state->workchain_, static_cast<ShardId>(state->shard_)};
|
||||
seqno_ = state->seqno_;
|
||||
ts_ = state->ts_;
|
||||
|
||||
before_split_ = state->split_;
|
||||
}
|
||||
|
||||
td::Result<td::Ref<ShardState>> ShardStateImpl::merge_with(const ShardState &with) const {
|
||||
auto &x = dynamic_cast<const ShardStateImpl &>(with);
|
||||
CHECK(blocks_id_.size() == 1);
|
||||
CHECK(x.blocks_id_.size() == 1);
|
||||
|
||||
return td::Ref<ShardStateImpl>{true,
|
||||
shard_parent(shard_),
|
||||
std::max(seqno_, x.seqno_),
|
||||
std::max(ts_, x.ts_),
|
||||
false,
|
||||
std::vector<BlockIdExt>{blocks_id_[0], x.blocks_id_[0]}};
|
||||
}
|
||||
|
||||
td::Result<std::pair<td::Ref<ShardState>, td::Ref<ShardState>>> ShardStateImpl::split() const {
|
||||
if (!before_split_) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "split flag not raised");
|
||||
}
|
||||
CHECK(blocks_id_.size() == 1);
|
||||
|
||||
auto L = td::Ref<ShardStateImpl>{
|
||||
true, shard_child(shard_, true), seqno_, ts_, false, std::vector<BlockIdExt>{blocks_id_[0]}};
|
||||
auto R = td::Ref<ShardStateImpl>{
|
||||
true, shard_child(shard_, false), seqno_, ts_, false, std::vector<BlockIdExt>{blocks_id_[0]}};
|
||||
|
||||
return std::pair<td::Ref<ShardState>, td::Ref<ShardState>>{L, R};
|
||||
}
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,224 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "interfaces/validator-manager.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
class McShardHashImpl : public McShardHash {
|
||||
public:
|
||||
BlockIdExt top_block_id() const override {
|
||||
return id_;
|
||||
}
|
||||
LogicalTime start_lt() const override {
|
||||
return 0;
|
||||
}
|
||||
LogicalTime end_lt() const override {
|
||||
return 0;
|
||||
}
|
||||
UnixTime fsm_utime() const override {
|
||||
return 0;
|
||||
}
|
||||
FsmState fsm_state() const override {
|
||||
return split_ ? FsmState::fsm_split : merge_ ? FsmState::fsm_merge : FsmState::fsm_none;
|
||||
}
|
||||
bool before_split() const override {
|
||||
return split_;
|
||||
}
|
||||
bool before_merge() const override {
|
||||
return merge_;
|
||||
}
|
||||
ShardIdFull shard() const override {
|
||||
return id_.shard_full();
|
||||
}
|
||||
|
||||
McShardHashImpl(BlockIdExt id, bool split, bool merge) : id_{id}, split_(split), merge_(merge) {
|
||||
}
|
||||
|
||||
private:
|
||||
BlockIdExt id_;
|
||||
bool split_;
|
||||
bool merge_;
|
||||
};
|
||||
|
||||
class ShardStateImpl : virtual public ShardState {
|
||||
public:
|
||||
virtual ~ShardStateImpl() = default;
|
||||
static td::Result<td::Ref<ShardState>> fetch(BlockIdExt block_id, td::BufferSlice data);
|
||||
|
||||
bool disable_boc() const override {
|
||||
return true;
|
||||
}
|
||||
UnixTime get_unix_time() const override {
|
||||
return ts_;
|
||||
}
|
||||
LogicalTime get_logical_time() const override {
|
||||
return lt_;
|
||||
}
|
||||
ShardIdFull get_shard() const override {
|
||||
return shard_;
|
||||
}
|
||||
BlockSeqno get_seqno() const override {
|
||||
return seqno_;
|
||||
}
|
||||
BlockIdExt get_block_id() const override {
|
||||
CHECK(blocks_id_.size() == 1);
|
||||
return blocks_id_[0];
|
||||
}
|
||||
bool before_split() const override {
|
||||
return before_split_;
|
||||
}
|
||||
RootHash root_hash() const override;
|
||||
td::Ref<vm::Cell> root_cell() const override {
|
||||
UNREACHABLE();
|
||||
}
|
||||
td::Result<td::Ref<MessageQueue>> message_queue() const override {
|
||||
UNREACHABLE();
|
||||
}
|
||||
td::Status apply_block(BlockIdExt id, td::Ref<BlockData> block) override;
|
||||
td::Result<td::Ref<ShardState>> merge_with(const ShardState &with) const override;
|
||||
td::Result<std::pair<td::Ref<ShardState>, td::Ref<ShardState>>> split() const override;
|
||||
td::Status validate_deep() const override {
|
||||
return td::Status::OK();
|
||||
}
|
||||
td::Result<td::BufferSlice> serialize() const override;
|
||||
ShardStateImpl *make_copy() const override {
|
||||
return new ShardStateImpl{shard_, seqno_, ts_, before_split_, blocks_id_};
|
||||
}
|
||||
|
||||
ShardStateImpl(ShardIdFull shard, BlockSeqno seqno, UnixTime ts, bool split, std::vector<BlockIdExt> block_id)
|
||||
: shard_(shard), seqno_(seqno), ts_(ts), before_split_(split), blocks_id_(block_id) {
|
||||
}
|
||||
ShardStateImpl(const tl_object_ptr<ton_api::test0_shardchain_state> &state, BlockIdExt block_id);
|
||||
|
||||
private:
|
||||
ShardIdFull shard_;
|
||||
BlockSeqno seqno_;
|
||||
UnixTime ts_;
|
||||
LogicalTime lt_ = 0;
|
||||
|
||||
bool before_split_;
|
||||
|
||||
std::vector<BlockIdExt> blocks_id_;
|
||||
};
|
||||
|
||||
class MasterchainStateImpl : public MasterchainState, public ShardStateImpl {
|
||||
public:
|
||||
struct ShardDescr {
|
||||
BlockIdExt top_block;
|
||||
bool before_split;
|
||||
bool before_merge;
|
||||
bool after_split;
|
||||
bool after_merge;
|
||||
ShardDescr(const tl_object_ptr<ton_api::test0_masterchain_shardInfo> &from);
|
||||
tl_object_ptr<ton_api::test0_masterchain_shardInfo> tl() const;
|
||||
td::Ref<McShardHash> mc_shard() const;
|
||||
bool operator<(const ShardDescr &with) const {
|
||||
return top_block.shard_full() < with.top_block.shard_full();
|
||||
}
|
||||
};
|
||||
|
||||
td::Ref<ValidatorSet> get_validator_set(ShardIdFull shard) const override;
|
||||
td::Ref<ValidatorSet> get_next_validator_set(ShardIdFull shard) const override;
|
||||
td::Ref<ValidatorSet> get_validator_set(ShardIdFull shard, UnixTime ts) const;
|
||||
bool rotated_all_shards() const override {
|
||||
return get_seqno() == 0;
|
||||
}
|
||||
UnixTime next_validator_rotate_at() const {
|
||||
return next_validator_rotate_at_;
|
||||
}
|
||||
std::vector<td::Ref<McShardHash>> get_shards() const override;
|
||||
bool ancestor_is_valid(BlockIdExt id) const override;
|
||||
|
||||
td::Status apply_block(BlockIdExt id, td::Ref<BlockData> block) override;
|
||||
td::Result<td::Ref<ShardState>> merge_with(const ShardState &with) const override {
|
||||
UNREACHABLE();
|
||||
}
|
||||
td::Result<std::pair<td::Ref<ShardState>, td::Ref<ShardState>>> split() const override {
|
||||
UNREACHABLE();
|
||||
}
|
||||
td::Status validate_deep() const override {
|
||||
return td::Status::OK();
|
||||
}
|
||||
td::Ref<McShardHash> get_shard_from_config(ShardIdFull shard) const override {
|
||||
auto v = get_shards();
|
||||
for (auto &x : v) {
|
||||
if (x->shard() == shard) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
return td::Ref<McShardHash>{};
|
||||
}
|
||||
td::Result<td::BufferSlice> serialize() const override;
|
||||
MasterchainStateImpl *make_copy() const override {
|
||||
return new MasterchainStateImpl{get_shard(),
|
||||
get_seqno(),
|
||||
get_unix_time(),
|
||||
cur_validator_ts_,
|
||||
cur_randseed_,
|
||||
next_randseed_,
|
||||
next_validator_rotate_at_,
|
||||
validators_,
|
||||
prev_blocks_,
|
||||
shards_,
|
||||
get_block_id()};
|
||||
}
|
||||
static td::Result<td::Ref<MasterchainState>> fetch(BlockIdExt block_id, td::BufferSlice data);
|
||||
|
||||
MasterchainStateImpl(ShardIdFull shard, BlockSeqno seqno, UnixTime ts, UnixTime cur_validator_ts,
|
||||
td::uint32 cur_randseed, td::uint32 next_randseed, UnixTime next_validator_rotate_at,
|
||||
std::vector<ValidatorFullId> validators, std::vector<BlockIdExt> prev_blocks,
|
||||
std::set<ShardDescr> shards, BlockIdExt block_id)
|
||||
: ShardStateImpl{shard, seqno, ts, false, {block_id}}
|
||||
, cur_validator_ts_(cur_validator_ts)
|
||||
, cur_randseed_(cur_randseed)
|
||||
, next_randseed_(next_randseed)
|
||||
, next_validator_rotate_at_(next_validator_rotate_at)
|
||||
, validators_(std::move(validators))
|
||||
, prev_blocks_(std::move(prev_blocks))
|
||||
, shards_(std::move(shards)) {
|
||||
}
|
||||
MasterchainStateImpl(const tl_object_ptr<ton_api::test0_shardchain_state> &state, BlockIdExt block_id);
|
||||
|
||||
private:
|
||||
td::Ref<ValidatorSet> calculate_validator_set(ShardIdFull shard, td::uint32 cnt, UnixTime ts,
|
||||
td::uint32 randseed) const;
|
||||
|
||||
UnixTime cur_validator_ts_;
|
||||
td::uint32 cur_randseed_;
|
||||
td::uint32 next_randseed_;
|
||||
UnixTime next_validator_rotate_at_;
|
||||
|
||||
std::vector<ValidatorFullId> validators_;
|
||||
std::vector<BlockIdExt> prev_blocks_;
|
||||
std::set<ShardDescr> shards_;
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "signature-set.hpp"
|
||||
#include "auto/tl/ton_api.hpp"
|
||||
#include "adnl/utils.hpp"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
td::BufferSlice BlockSignatureSetImpl::serialize() const {
|
||||
std::vector<tl_object_ptr<ton_api::tonNode_blockSignature>> sigs;
|
||||
for (auto &s : signatures()) {
|
||||
sigs.emplace_back(
|
||||
create_tl_object<ton_api::tonNode_blockSignature>(Bits256_2_UInt256(s.node), s.signature.clone()));
|
||||
}
|
||||
auto obj = create_tl_object<ton_api::test0_blockSignatures>(std::move(sigs));
|
||||
return serialize_tl_object(obj, true);
|
||||
}
|
||||
|
||||
td::Ref<BlockSignatureSet> BlockSignatureSetImpl::fetch(td::BufferSlice data) {
|
||||
auto F = fetch_tl_object<ton_api::test0_blockSignatures>(std::move(data), true);
|
||||
auto obj = F.move_as_ok();
|
||||
|
||||
std::vector<BlockSignature> sigs;
|
||||
for (auto &s : obj->signatures_) {
|
||||
sigs.emplace_back(BlockSignature{UInt256_2_Bits256(s->who_), std::move(s->signature_)});
|
||||
}
|
||||
|
||||
return td::Ref<BlockSignatureSetImpl>{true, std::move(sigs)};
|
||||
}
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ton/ton-types.h"
|
||||
#include "validator/interfaces/signature-set.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
class BlockSignatureSetImpl : public BlockSignatureSet {
|
||||
public:
|
||||
BlockSignatureSetImpl(std::vector<BlockSignature> signatures) : BlockSignatureSet{std::move(signatures)} {
|
||||
}
|
||||
|
||||
BlockSignatureSetImpl *make_copy() const override {
|
||||
std::vector<BlockSignature> vec;
|
||||
auto &sigs = signatures();
|
||||
for (auto &s : sigs) {
|
||||
vec.emplace_back(BlockSignature{s.node, s.signature.clone()});
|
||||
}
|
||||
|
||||
return new BlockSignatureSetImpl{std::move(vec)};
|
||||
}
|
||||
|
||||
td::BufferSlice serialize() const override;
|
||||
static td::Ref<BlockSignatureSet> fetch(td::BufferSlice data);
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,168 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "top-shard-description.hpp"
|
||||
#include "ton/ton-tl.hpp"
|
||||
#include "tl-utils/tl-utils.hpp"
|
||||
#include "common/errorcode.h"
|
||||
#include "validator/fabric.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
bool ShardTopBlockDescriptionImpl::may_be_valid(BlockHandle last_masterchain_block_handle,
|
||||
td::Ref<MasterchainState> last_masterchain_block_state) const {
|
||||
if (after_split_ && after_merge_) {
|
||||
return false;
|
||||
}
|
||||
if (!after_split_ && !after_merge_) {
|
||||
auto s = last_masterchain_block_state->get_shard_from_config(block_id_.shard_full());
|
||||
if (s.is_null()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s->fsm_state() != McShardHash::FsmState::fsm_none) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s->top_block_id().id.seqno >= block_id_.id.seqno) {
|
||||
return false;
|
||||
}
|
||||
} else if (after_split_) {
|
||||
auto s = last_masterchain_block_state->get_shard_from_config(shard_parent(block_id_.shard_full()));
|
||||
if (s.is_null()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s->fsm_state() != McShardHash::FsmState::fsm_split) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s->top_block_id().id.seqno + 1 != block_id_.id.seqno) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
auto s1 = last_masterchain_block_state->get_shard_from_config(shard_child(block_id_.shard_full(), true));
|
||||
if (s1.is_null()) {
|
||||
return false;
|
||||
}
|
||||
auto s2 = last_masterchain_block_state->get_shard_from_config(shard_child(block_id_.shard_full(), false));
|
||||
if (s2.is_null()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s1->fsm_state() != McShardHash::FsmState::fsm_merge || s2->fsm_state() != McShardHash::FsmState::fsm_merge) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (std::max(s1->top_block_id().id.seqno, s2->top_block_id().id.seqno) + 1 != block_id_.id.seqno) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
auto val_set = last_masterchain_block_state->get_validator_set(block_id_.shard_full());
|
||||
if (val_set->get_catchain_seqno() != catchain_seqno_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
td::BufferSlice ShardTopBlockDescriptionImpl::serialize() const {
|
||||
return serialize_tl_object(create_tl_object<ton_api::test0_topShardBlockDescription>(
|
||||
create_tl_block_id(block_id_), after_split_, after_merge_, before_split_,
|
||||
catchain_seqno_, validator_set_hash_, signatures_.clone()),
|
||||
true);
|
||||
}
|
||||
|
||||
td::Result<td::Ref<ShardTopBlockDescription>> ShardTopBlockDescriptionImpl::fetch(td::BufferSlice data) {
|
||||
TRY_RESULT(F, fetch_tl_object<ton_api::test0_topShardBlockDescription>(std::move(data), true));
|
||||
|
||||
return td::Ref<ShardTopBlockDescriptionImpl>{true,
|
||||
create_block_id(F->block_id_),
|
||||
F->after_split_,
|
||||
F->after_merge_,
|
||||
F->before_split_,
|
||||
F->catchain_seqno_,
|
||||
F->validator_set_hash_,
|
||||
F->signatures_.clone()};
|
||||
}
|
||||
|
||||
void ValidateShardTopBlockDescription::finish_query() {
|
||||
if (promise_) {
|
||||
promise_.set_value(ShardTopBlockDescriptionImpl::fetch(data_.clone()).move_as_ok());
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void ValidateShardTopBlockDescription::abort_query(td::Status reason) {
|
||||
if (promise_) {
|
||||
promise_.set_error(std::move(reason));
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void ValidateShardTopBlockDescription::alarm() {
|
||||
abort_query(td::Status::Error(ErrorCode::timeout, "timeout"));
|
||||
}
|
||||
|
||||
void ValidateShardTopBlockDescription::start_up() {
|
||||
alarm_timestamp() = timeout_;
|
||||
|
||||
auto F = fetch_tl_object<ton_api::test0_topShardBlockDescription>(data_.clone(), true);
|
||||
if (F.is_error()) {
|
||||
abort_query(F.move_as_error());
|
||||
return;
|
||||
}
|
||||
unserialized_ = F.move_as_ok();
|
||||
|
||||
auto id = create_block_id(unserialized_->block_id_);
|
||||
|
||||
auto val_set = state_->get_validator_set(id.shard_full());
|
||||
if (val_set->get_catchain_seqno() != static_cast<CatchainSeqno>(unserialized_->catchain_seqno_)) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "bad validator set ts"));
|
||||
return;
|
||||
}
|
||||
if (val_set->get_validator_set_hash() != static_cast<td::uint32>(unserialized_->validator_set_hash_)) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "bad validator set hash"));
|
||||
return;
|
||||
}
|
||||
|
||||
auto sig_setR = create_signature_set(unserialized_->signatures_.clone());
|
||||
if (sig_setR.is_error()) {
|
||||
abort_query(sig_setR.move_as_error());
|
||||
return;
|
||||
}
|
||||
|
||||
auto S = val_set->check_signatures(id.root_hash, id.file_hash, sig_setR.move_as_ok());
|
||||
if (S.is_error()) {
|
||||
abort_query(S.move_as_error());
|
||||
return;
|
||||
}
|
||||
|
||||
finish_query();
|
||||
}
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,118 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "interfaces/shard-block.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
class ShardTopBlockDescriptionImpl : public ShardTopBlockDescription {
|
||||
public:
|
||||
ShardIdFull shard() const override {
|
||||
return block_id_.shard_full();
|
||||
}
|
||||
BlockIdExt block_id() const override {
|
||||
return block_id_;
|
||||
}
|
||||
|
||||
bool may_be_valid(BlockHandle last_masterchain_block_handle,
|
||||
td::Ref<MasterchainState> last_masterchain_block_state) const override;
|
||||
|
||||
td::BufferSlice serialize() const override;
|
||||
|
||||
bool before_split() const override {
|
||||
return before_split_;
|
||||
}
|
||||
bool after_split() const override {
|
||||
return after_split_;
|
||||
}
|
||||
bool after_merge() const override {
|
||||
return after_merge_;
|
||||
}
|
||||
|
||||
ShardTopBlockDescriptionImpl(BlockIdExt block_id, bool after_split, bool after_merge, bool before_split,
|
||||
CatchainSeqno catchain_seqno, td::uint32 validator_set_hash, td::BufferSlice signatures)
|
||||
: block_id_(block_id)
|
||||
, after_split_(after_split)
|
||||
, after_merge_(after_merge)
|
||||
, before_split_(before_split)
|
||||
, catchain_seqno_(catchain_seqno)
|
||||
, validator_set_hash_(validator_set_hash)
|
||||
, signatures_(std::move(signatures)) {
|
||||
}
|
||||
|
||||
ShardTopBlockDescriptionImpl *make_copy() const override {
|
||||
return new ShardTopBlockDescriptionImpl{block_id_, after_split_, after_merge_, before_split_,
|
||||
catchain_seqno_, validator_set_hash_, signatures_.clone()};
|
||||
}
|
||||
|
||||
static td::Result<td::Ref<ShardTopBlockDescription>> fetch(td::BufferSlice data);
|
||||
|
||||
private:
|
||||
BlockIdExt block_id_;
|
||||
bool after_split_;
|
||||
bool after_merge_;
|
||||
bool before_split_;
|
||||
|
||||
CatchainSeqno catchain_seqno_;
|
||||
td::uint32 validator_set_hash_;
|
||||
td::BufferSlice signatures_;
|
||||
};
|
||||
|
||||
class ValidateShardTopBlockDescription : public td::actor::Actor {
|
||||
public:
|
||||
ValidateShardTopBlockDescription(td::BufferSlice data, BlockHandle masterchain_handle,
|
||||
td::Ref<MasterchainState> masterchain_state,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
td::Promise<td::Ref<ShardTopBlockDescription>> promise)
|
||||
: data_(std::move(data))
|
||||
, handle_(std::move(masterchain_handle))
|
||||
, state_(std::move(masterchain_state))
|
||||
, manager_(manager)
|
||||
, timeout_(timeout)
|
||||
, promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void finish_query();
|
||||
void abort_query(td::Status reason);
|
||||
void alarm() override;
|
||||
|
||||
void start_up() override;
|
||||
|
||||
private:
|
||||
td::BufferSlice data_;
|
||||
tl_object_ptr<ton_api::test0_topShardBlockDescription> unserialized_;
|
||||
|
||||
BlockHandle handle_;
|
||||
td::Ref<MasterchainState> state_;
|
||||
|
||||
td::actor::ActorId<ValidatorManager> manager_;
|
||||
td::Timestamp timeout_;
|
||||
td::Promise<td::Ref<ShardTopBlockDescription>> promise_;
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,164 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "validate-query.hpp"
|
||||
#include "adnl/utils.hpp"
|
||||
#include "ton/ton-tl.hpp"
|
||||
#include "ton/ton-io.hpp"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
void ValidateQuery::alarm() {
|
||||
abort_query(td::Status::Error(ErrorCode::timeout, "timeout"));
|
||||
}
|
||||
|
||||
void ValidateQuery::abort_query(td::Status reason) {
|
||||
if (promise_) {
|
||||
LOG(WARNING) << "aborting validate block candidate query: " << reason;
|
||||
promise_.set_error(std::move(reason));
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void ValidateQuery::reject_query(std::string reason, td::BufferSlice proof) {
|
||||
if (promise_) {
|
||||
LOG(WARNING) << "rejecting validate block candidate query: " << reason;
|
||||
promise_.set_value(CandidateReject{std::move(reason), std::move(proof)});
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void ValidateQuery::finish_query() {
|
||||
if (promise_) {
|
||||
promise_.set_result(block_ts_);
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
void ValidateQuery::start_up() {
|
||||
alarm_timestamp() = timeout_;
|
||||
|
||||
auto F = fetch_tl_object<ton_api::test0_shardchain_block>(candidate_.data.clone(), true);
|
||||
if (F.is_error()) {
|
||||
abort_query(F.move_as_error());
|
||||
return;
|
||||
}
|
||||
unserialized_block_ = F.move_as_ok();
|
||||
block_ts_ = unserialized_block_->ts_;
|
||||
|
||||
if (unserialized_block_->workchain_ != shard_.workchain) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "bad workchain"));
|
||||
return;
|
||||
}
|
||||
if (static_cast<ShardId>(unserialized_block_->shard_) != shard_.shard) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "bad shard"));
|
||||
return;
|
||||
}
|
||||
|
||||
BlockSeqno max_seqno = 0;
|
||||
if (prev_.size() != unserialized_block_->prev_.size()) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "wrong prev block count"));
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < prev_.size(); i++) {
|
||||
if (prev_[i].id.seqno > max_seqno) {
|
||||
max_seqno = prev_[i].id.seqno;
|
||||
}
|
||||
auto p = create_block_id(unserialized_block_->prev_[i]);
|
||||
if (p != prev_[i]) {
|
||||
LOG(WARNING) << p << " " << prev_[i];
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "wrong prev block"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (static_cast<BlockSeqno>(unserialized_block_->seqno_) != max_seqno + 1) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "wrong block seqno"));
|
||||
return;
|
||||
}
|
||||
if (static_cast<CatchainSeqno>(unserialized_block_->catchain_seqno_) != catchain_seqno_) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "wrong validator set ts"));
|
||||
return;
|
||||
}
|
||||
if (static_cast<td::uint32>(unserialized_block_->validator_set_hash_) != validator_set_hash_) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "wrong validator set hash"));
|
||||
return;
|
||||
}
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &ValidateQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &ValidateQuery::got_prev_state, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
if (prev_.size() == 1) {
|
||||
td::actor::send_closure(manager_, &ValidatorManager::wait_block_state_short, prev_[0], timeout_, std::move(P));
|
||||
} else {
|
||||
td::actor::send_closure(manager_, &ValidatorManager::wait_block_state_merge, prev_[0], prev_[1], timeout_,
|
||||
std::move(P));
|
||||
}
|
||||
}
|
||||
|
||||
void ValidateQuery::got_prev_state(td::Ref<ShardState> R) {
|
||||
if (R->get_unix_time() >= static_cast<UnixTime>(unserialized_block_->ts_)) {
|
||||
abort_query(td::Status::Error(ErrorCode::protoviolation, "too small ts"));
|
||||
return;
|
||||
}
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &ValidateQuery::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &ValidateQuery::written_candidate);
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(manager_, &ValidatorManager::set_block_candidate, candidate_.id, candidate_.clone(),
|
||||
std::move(P));
|
||||
}
|
||||
|
||||
void ValidateQuery::written_candidate() {
|
||||
finish_query();
|
||||
}
|
||||
|
||||
ValidateQuery::ValidateQuery(ShardIdFull shard, UnixTime min_ts, BlockIdExt min_masterchain_block_id,
|
||||
std::vector<BlockIdExt> prev, BlockCandidate candidate, CatchainSeqno catchain_seqno,
|
||||
td::uint32 validator_set_hash, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Timestamp timeout, td::Promise<ValidateCandidateResult> promise)
|
||||
: shard_(shard)
|
||||
, min_ts_(min_ts)
|
||||
, min_masterchain_block_id_(min_masterchain_block_id)
|
||||
, prev_(std::move(prev))
|
||||
, candidate_(std::move(candidate))
|
||||
, catchain_seqno_(catchain_seqno)
|
||||
, validator_set_hash_(validator_set_hash)
|
||||
, manager_(manager)
|
||||
, timeout_(timeout)
|
||||
, promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "interfaces/validator-manager.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
class ValidateQuery : public td::actor::Actor {
|
||||
public:
|
||||
ValidateQuery(ShardIdFull shard, UnixTime min_ts, BlockIdExt min_masterchain_block_id, std::vector<BlockIdExt> prev,
|
||||
BlockCandidate candidate, CatchainSeqno catchain_seqno, td::uint32 validator_set_hash,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
td::Promise<ValidateCandidateResult> promise);
|
||||
|
||||
void abort_query(td::Status reason);
|
||||
void reject_query(std::string reason, td::BufferSlice proof);
|
||||
void finish_query();
|
||||
void alarm() override;
|
||||
|
||||
void start_up() override;
|
||||
void got_prev_state(td::Ref<ShardState> state);
|
||||
void got_masterchain_handle(BlockHandle masterchain_handle);
|
||||
void got_masterchain_state(td::Ref<ShardState> masterchain_state);
|
||||
void written_candidate();
|
||||
|
||||
private:
|
||||
ShardIdFull shard_;
|
||||
UnixTime min_ts_;
|
||||
BlockIdExt min_masterchain_block_id_;
|
||||
std::vector<BlockIdExt> prev_;
|
||||
BlockCandidate candidate_;
|
||||
CatchainSeqno catchain_seqno_;
|
||||
td::uint32 validator_set_hash_;
|
||||
td::actor::ActorId<ValidatorManager> manager_;
|
||||
td::Timestamp timeout_;
|
||||
td::Promise<ValidateCandidateResult> promise_;
|
||||
|
||||
UnixTime block_ts_;
|
||||
tl_object_ptr<ton_api::test0_shardchain_block> unserialized_block_;
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#include "validator-set.hpp"
|
||||
#include "auto/tl/ton_api.h"
|
||||
#include "adnl/utils.hpp"
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
bool ValidatorSetImpl::is_validator(NodeIdShort id) const {
|
||||
return ids_map_.count(id) > 0;
|
||||
}
|
||||
|
||||
td::Result<ValidatorWeight> ValidatorSetImpl::check_signatures(RootHash root_hash, FileHash file_hash,
|
||||
td::Ref<BlockSignatureSet> signatures) const {
|
||||
auto &sigs = signatures->signatures();
|
||||
|
||||
auto b = create_tl_object<ton_api::ton_blockId>(Bits256_2_UInt256(root_hash), Bits256_2_UInt256(file_hash));
|
||||
auto block = serialize_tl_object(b, true);
|
||||
|
||||
ValidatorWeight weight = 0;
|
||||
|
||||
std::set<NodeIdShort> nodes;
|
||||
for (auto &sig : sigs) {
|
||||
if (nodes.count(sig.node) == 1) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "duplicate node to sign");
|
||||
}
|
||||
nodes.insert(sig.node);
|
||||
|
||||
auto it = ids_map_.find(sig.node);
|
||||
if (it == ids_map_.end()) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "unknown node to sign");
|
||||
}
|
||||
|
||||
auto idx = it->second;
|
||||
TRY_STATUS(ids_[idx].encryptor->check_signature(block.as_slice(), sig.signature.as_slice()));
|
||||
weight += ids_[idx].weight;
|
||||
}
|
||||
|
||||
if (weight * 3 <= total_weight_ * 2) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "too small sig weight");
|
||||
}
|
||||
return weight;
|
||||
}
|
||||
|
||||
ValidatorSetImpl::ValidatorSetImpl(CatchainSeqno cc_seqno, ShardId from,
|
||||
std::vector<std::pair<ValidatorFullId, ValidatorWeight>> nodes)
|
||||
: cc_seqno_(cc_seqno), from_(from) {
|
||||
total_weight_ = 0;
|
||||
|
||||
std::vector<tl_object_ptr<ton_api::test0_validatorSetItem>> s_vec;
|
||||
|
||||
for (auto &n : nodes) {
|
||||
auto idx = ids_.size();
|
||||
auto id = n.first.short_id();
|
||||
s_vec.emplace_back(create_tl_object<ton_api::test0_validatorSetItem>(Bits256_2_UInt256(id), n.second));
|
||||
CHECK(ids_map_.count(id) == 0);
|
||||
total_weight_ += n.second;
|
||||
auto E = n.first.create_encryptor().move_as_ok();
|
||||
ids_.emplace_back(ValidatorSetMember{n.first, n.second, std::move(E)});
|
||||
ids_map_.emplace(id, idx);
|
||||
}
|
||||
|
||||
auto obj = create_tl_object<ton_api::test0_validatorSet>(cc_seqno_, std::move(s_vec));
|
||||
auto B = serialize_tl_object(obj, true);
|
||||
hash_ = td::crc32c(B.as_slice());
|
||||
}
|
||||
|
||||
ValidatorSetImpl *ValidatorSetImpl::make_copy() const {
|
||||
return new ValidatorSetImpl{cc_seqno_, from_, export_vector()};
|
||||
}
|
||||
|
||||
std::vector<std::pair<PublicKey, ValidatorWeight>> ValidatorSetImpl::export_tl_vector() const {
|
||||
std::vector<std::pair<PublicKey, ValidatorWeight>> vec;
|
||||
for (auto &v : ids_) {
|
||||
vec.emplace_back(v.id, v.weight);
|
||||
}
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
std::vector<std::pair<ValidatorFullId, ValidatorWeight>> ValidatorSetImpl::export_vector() const {
|
||||
std::vector<std::pair<ValidatorFullId, ValidatorWeight>> vec;
|
||||
for (auto &v : ids_) {
|
||||
vec.emplace_back(v.id, v.weight);
|
||||
}
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "validator/interfaces/validator-set.h"
|
||||
#include "validator/interfaces/signature-set.h"
|
||||
#include "keys/encryptor.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace dummy0 {
|
||||
|
||||
class ValidatorSetImpl : public ValidatorSet {
|
||||
private:
|
||||
struct ValidatorSetMember {
|
||||
ValidatorFullId id;
|
||||
ValidatorWeight weight;
|
||||
std::unique_ptr<Encryptor> encryptor;
|
||||
};
|
||||
|
||||
public:
|
||||
bool is_validator(NodeIdShort id) const override;
|
||||
CatchainSeqno get_catchain_seqno() const override {
|
||||
return cc_seqno_;
|
||||
}
|
||||
td::uint32 get_validator_set_hash() const override {
|
||||
return hash_;
|
||||
}
|
||||
ShardId get_validator_set_from() const override {
|
||||
return from_;
|
||||
}
|
||||
std::vector<std::pair<ValidatorFullId, ValidatorWeight>> export_vector() const override;
|
||||
std::vector<std::pair<PublicKey, ValidatorWeight>> export_tl_vector() const override;
|
||||
td::Result<ValidatorWeight> check_signatures(RootHash root_hash, FileHash file_hash,
|
||||
td::Ref<BlockSignatureSet> signatures) const override;
|
||||
|
||||
ValidatorSetImpl *make_copy() const override;
|
||||
|
||||
ValidatorSetImpl(UnixTime ts, ShardId from_, std::vector<std::pair<ValidatorFullId, ValidatorWeight>> nodes);
|
||||
|
||||
private:
|
||||
CatchainSeqno cc_seqno_;
|
||||
ShardId from_;
|
||||
td::uint32 hash_;
|
||||
ValidatorWeight total_weight_;
|
||||
std::vector<ValidatorSetMember> ids_;
|
||||
std::map<NodeIdShort, size_t> ids_map_;
|
||||
};
|
||||
|
||||
} // namespace dummy0
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
|
@ -3782,11 +3782,9 @@ bool ValidateQuery::check_neighbor_outbound_message(Ref<vm::CellSlice> enq_msg,
|
|||
return reject_query("unpack ext_message_deq OutMsg record for already processed EnqueuedMsg with key "s +
|
||||
key.to_hex(352) + " of old outbound queue contains a different MsgEnvelope");
|
||||
}
|
||||
} else if (out_entry.not_null()) {
|
||||
return reject_query(
|
||||
"have an OutMsg entry for exporting (or even dequeuing) already processed EnqueuedMsg with key "s +
|
||||
key.to_hex(352) + " of neighbor " + nb.blk_.to_str());
|
||||
}
|
||||
// NB. we might have a non-trivial dequeueing out_entry with this message hash, but another envelope (for transit messages)
|
||||
// (so we cannot assert that out_entry is null)
|
||||
if (claimed_proc_lt_ && (claimed_proc_lt_ < lt || (claimed_proc_lt_ == lt && claimed_proc_hash_ < enq.hash_))) {
|
||||
LOG(FATAL) << "internal inconsistency: new ProcessedInfo claims to have processed all messages up to ("
|
||||
<< claimed_proc_lt_ << "," << claimed_proc_hash_.to_hex()
|
||||
|
|
Loading…
Reference in a new issue