mirror of
https://github.com/danog/ton.git
synced 2024-11-26 12:04:48 +01:00
fullnode: support for TCP master/slave replication
This commit is contained in:
parent
bfa166d66c
commit
f40822b58a
@ -70,8 +70,14 @@ else()
|
||||
endif()
|
||||
|
||||
#BEGIN internal
|
||||
option(TON_USE_ROCKSDB "Use \"ON\" to enable RocksDb." ON)
|
||||
option(TON_USE_ABSEIL "Use \"ON\" to enable Abseil." ON)
|
||||
option(TON_ONLY_TONLIB "Use \"ON\" to build only tonlib." OFF)
|
||||
if (TON_ONLY_TONBLIB)
|
||||
set(NOT_TON_ONLY_TONLIB false)
|
||||
else()
|
||||
set(NOT_TON_ONLY_TONLIB true)
|
||||
endif()
|
||||
option(TON_USE_ROCKSDB "Use \"ON\" to enable RocksDb." ${NOT_TON_ONLY_TONLIB})
|
||||
option(TON_USE_ABSEIL "Use \"ON\" to enable Abseil." ${NOT_TON_ONLY_TONLIB})
|
||||
option(TON_USE_JEMALLOC "Use \"ON\" to enable JeMalloc." OFF)
|
||||
#END internal
|
||||
|
||||
@ -328,6 +334,7 @@ function(target_link_libraries_system target)
|
||||
endforeach(lib)
|
||||
endfunction(target_link_libraries_system)
|
||||
|
||||
set(TDUTILS_MIME_TYPE OFF CACHE BOOL "Generate mime type conversion")
|
||||
add_subdirectory(tdutils)
|
||||
add_subdirectory(memprof)
|
||||
add_subdirectory(tdactor)
|
||||
@ -350,6 +357,7 @@ add_subdirectory(tonlib)
|
||||
#END tonlib
|
||||
|
||||
#BEGIN internal
|
||||
if (NOT TON_ONLY_TONLIB)
|
||||
add_subdirectory(common)
|
||||
add_subdirectory(tdfec)
|
||||
add_subdirectory(keyring)
|
||||
@ -365,10 +373,14 @@ add_subdirectory(validator-engine)
|
||||
add_subdirectory(validator-engine-console)
|
||||
add_subdirectory(dht-server)
|
||||
add_subdirectory(utils)
|
||||
endif()
|
||||
#END internal
|
||||
|
||||
if (NOT CMAKE_CROSSCOMPILING)
|
||||
add_custom_target(prepare_cross_compiling DEPENDS tl_generate_common tdmime_auto tlb_generate_block)
|
||||
if (TDUTILS_MIME_TYPE)
|
||||
set(TDMIME_AUTO tdmime_auto)
|
||||
endif()
|
||||
add_custom_target(prepare_cross_compiling DEPENDS tl_generate_common tlb_generate_block ${TDMIME_AUTO})
|
||||
endif()
|
||||
|
||||
#TESTS
|
||||
@ -406,6 +418,7 @@ target_link_libraries(test-tonlib-offline tdutils tdactor adnllite tl_api ton_cr
|
||||
#END tonlib
|
||||
|
||||
#BEGIN internal
|
||||
if (NOT TON_ONLY_TONLIB)
|
||||
add_executable(test-db test/test-td-main.cpp ${TONDB_TEST_SOURCE})
|
||||
target_link_libraries(test-db PRIVATE ton_db memprof)
|
||||
|
||||
@ -467,6 +480,7 @@ if (HAS_PARENT)
|
||||
endif()
|
||||
add_library(all_tests INTERFACE)
|
||||
target_link_libraries(all_tests INTERFACE tdutils tdactor tdnet tdfec ton_db ton_crypto fift-lib)
|
||||
endif()
|
||||
#END internal
|
||||
|
||||
enable_testing()
|
||||
@ -485,8 +499,10 @@ add_test(test-tonlib-offline test-tonlib-offline)
|
||||
#END tonlib
|
||||
|
||||
#BEGIN internal
|
||||
if (NOT TON_ONLY_TONLIB)
|
||||
add_test(test-fec test-fec)
|
||||
add_test(test-tddb test-tddb ${TEST_OPTIONS})
|
||||
add_test(test-db test-db ${TEST_OPTIONS})
|
||||
endif()
|
||||
#END internal
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
|
||||
|
||||
#BEGIN internal
|
||||
if (NOT TON_ONLY_TONLIB)
|
||||
set(ADNL_HEADERS
|
||||
adnl-address-list.h
|
||||
adnl-address-list.hpp
|
||||
@ -66,6 +67,7 @@ set(ADNL_PROXY_SOURCE
|
||||
|
||||
#FIXME
|
||||
set(ADNL_LITE_HEADERS ${ADNL_HEADERS})
|
||||
endif()
|
||||
#END internal
|
||||
|
||||
set(ADNL_LITE_SOURCE
|
||||
@ -77,6 +79,7 @@ set(ADNL_LITE_SOURCE
|
||||
)
|
||||
|
||||
#BEGIN internal
|
||||
if (NOT TON_ONLY_TONLIB)
|
||||
add_library(adnl STATIC ${ADNL_SOURCE})
|
||||
|
||||
target_include_directories(adnl PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>)
|
||||
@ -95,6 +98,7 @@ target_link_libraries(adnl-pong PUBLIC tdactor ton_crypto tl_api tdnet common
|
||||
add_library(adnltest STATIC ${ADNL_TEST_SOURCE})
|
||||
target_include_directories(adnltest PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>)
|
||||
target_link_libraries(adnltest PUBLIC adnl )
|
||||
endif()
|
||||
#END internal
|
||||
|
||||
add_library(adnllite STATIC ${ADNL_LITE_SOURCE})
|
||||
|
@ -209,7 +209,8 @@ Bignum& Bignum::import_lsb(const unsigned char* buffer, std::size_t size) {
|
||||
size--;
|
||||
}
|
||||
if (!size) {
|
||||
bn_assert(BN_zero(val));
|
||||
// Use BN_set_word, because from 1.1.0 BN_zero may return void
|
||||
bn_assert(BN_set_word(val, 0));
|
||||
return *this;
|
||||
}
|
||||
unsigned char tmp_buff[1024];
|
||||
|
@ -79,7 +79,7 @@ class Bignum {
|
||||
}
|
||||
Bignum(const bin_string& bs) {
|
||||
val = BN_new();
|
||||
set_dec_str(bs.str);
|
||||
set_raw_bytes(bs.str);
|
||||
}
|
||||
Bignum(const dec_string& ds) {
|
||||
val = BN_new();
|
||||
|
@ -66,9 +66,10 @@ Masterchain over
|
||||
|
||||
// SmartContract #2 (Simple money giver for test network)
|
||||
<{ SETCP0 DUP IFNOTRET // return if recv_internal
|
||||
DUP 85143 INT EQUAL IFJMP:<{ // "seqno" get-method
|
||||
DUP 85143 INT EQUAL IFJMP:<{ // "seqno" get-method
|
||||
DROP c4 PUSHCTR CTOS 32 PLDU // cnt
|
||||
}>
|
||||
INC 32 THROWIF // fail unless recv_external
|
||||
32 LDU SWAP // cs cnt
|
||||
c4 PUSHCTR CTOS 32 LDU ENDS // cs cnt cnt'
|
||||
TUCK EQUAL 33 THROWIFNOT // ( seqno mismatch? )
|
||||
|
50
crypto/smartcont/new-testgiver.fif
Normal file
50
crypto/smartcont/new-testgiver.fif
Normal file
@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env fift -s
|
||||
"TonUtil.fif" include
|
||||
"Asm.fif" include
|
||||
|
||||
{ ."usage: " @' $0 type ." <workchain-id> [<filename-base>]" cr
|
||||
."Creates a new money giver in specified workchain, with address saved to <filename-base>.addr" cr
|
||||
."('new-testgiver.addr' by default)" cr 1 halt
|
||||
} : usage
|
||||
$# 1- -2 and ' usage if
|
||||
|
||||
$1 parse-workchain-id =: wc // set workchain id from command line argument
|
||||
def? $2 { @' $2 } { "new-testgiver" } cond constant file-base
|
||||
|
||||
."Creating new money giver in workchain " wc . cr
|
||||
0 constant init_seqno
|
||||
|
||||
// Create new simple money giver
|
||||
<{ 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
|
||||
32 LDU SWAP // cs cnt
|
||||
c4 PUSHCTR CTOS 32 LDU ENDS // cs cnt cnt'
|
||||
TUCK EQUAL 33 THROWIFNOT // ( seqno mismatch? )
|
||||
ACCEPT // cs cnt'
|
||||
SWAP DUP SREFS // cnt' cs msg?
|
||||
IF:<{
|
||||
8 LDU LDREF -ROT // cnt'' cs mode msg
|
||||
GR$20 INT 3 INT RAWRESERVE // reserve all but 20 Grams from the balance
|
||||
SWAP SENDRAWMSG
|
||||
}>
|
||||
ENDS INC NEWC 32 STU ENDC c4 POPCTR // store cnt''
|
||||
}>c
|
||||
// code
|
||||
<b init_seqno 32 u, b> // data
|
||||
null // no libraries
|
||||
<b b{0011} s, 3 roll ref, rot ref, swap dict, b> // create StateInit
|
||||
dup ."StateInit: " <s csr. cr
|
||||
dup hash wc swap 2dup 2constant wallet_addr
|
||||
."new money giver address = " 2dup .addr cr
|
||||
2dup file-base +".addr" save-address-verbose
|
||||
."Non-bounceable address (for init): " 2dup 7 .Addr cr
|
||||
."Bounceable address (for later access): " 6 .Addr cr
|
||||
// ???
|
||||
<b b{1000100} s, wallet_addr addr, b{000010} s, swap <s s, b{0} s, init_seqno 32 u, b>
|
||||
dup ."External message for initialization is " <s csr. cr
|
||||
2 boc+>B dup Bx. cr
|
||||
file-base +"-query.boc" tuck B>file
|
||||
."(Saved money giver creating query to file " type .")" cr
|
@ -9,7 +9,7 @@
|
||||
$# 3 - -2 and ' usage if
|
||||
|
||||
// "testgiver.addr" load-address
|
||||
Masterchain 0x8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d
|
||||
Masterchain 0xfcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260
|
||||
2constant giver_addr
|
||||
."Test giver address = " giver_addr 2dup .addr cr 6 .Addr cr
|
||||
|
||||
|
@ -572,7 +572,7 @@ TEST(bits256_scan, main) {
|
||||
}
|
||||
|
||||
bool check_exp(std::ostream& stream, const td::NegExpBinTable& tab, double x) {
|
||||
long long xx = lround(x * (1LL << 52));
|
||||
long long xx = llround(x * (1LL << 52));
|
||||
td::BigInt256 yy;
|
||||
if (!tab.nexpf(yy, -xx, 52)) {
|
||||
stream << "cannot compute exp(" << x << ") = exp(" << xx << " * 2^(-52))" << std::endl;
|
||||
|
@ -139,6 +139,9 @@ ton::tl_object_ptr<ton::ton_api::engine_validator_config> Config::tl() const {
|
||||
|
||||
std::vector<ton::tl_object_ptr<ton::ton_api::engine_validator>> val_vec;
|
||||
|
||||
ton::tl_object_ptr<ton::ton_api::engine_validator_fullNodeSlave> full_node_slave_ = nullptr;
|
||||
std::vector<ton::tl_object_ptr<ton::ton_api::engine_validator_fullNodeMaster>> full_node_masters_;
|
||||
|
||||
std::vector<ton::tl_object_ptr<ton::ton_api::engine_liteServer>> liteserver_vec;
|
||||
|
||||
std::vector<ton::tl_object_ptr<ton::ton_api::engine_controlInterface>> control_vec;
|
||||
@ -157,7 +160,8 @@ ton::tl_object_ptr<ton::ton_api::engine_validator_config> Config::tl() const {
|
||||
}
|
||||
return ton::create_tl_object<ton::ton_api::engine_validator_config>(
|
||||
out_port, std::move(addrs_vec), std::move(adnl_vec), std::move(dht_vec), std::move(val_vec),
|
||||
ton::PublicKeyHash::zero().tl(), std::move(liteserver_vec), std::move(control_vec), std::move(gc_vec));
|
||||
ton::PublicKeyHash::zero().tl(), std::move(full_node_slave_), std::move(full_node_masters_),
|
||||
std::move(liteserver_vec), std::move(control_vec), std::move(gc_vec));
|
||||
}
|
||||
|
||||
td::Result<bool> Config::config_add_network_addr(td::IPAddress in_ip, td::IPAddress out_ip,
|
||||
|
@ -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; 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).
|
||||
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 sources from public GitHub repository https://github.com/ton-blockchain/ton (e.g., by running `git clone https://github.com/ton-blockchain/ton`) instead of downloading 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
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -22,14 +22,14 @@ Example:
|
||||
|
||||
The "test giver" (a special smart contract residing in the masterchain of the Test Network that gives up to 20 test Grams to anybody who asks) has the address
|
||||
|
||||
-1:8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d
|
||||
-1:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260
|
||||
|
||||
in the "raw" form (notice that uppercase Latin letters 'A'..'F' may be used instead of 'a'..'f')
|
||||
|
||||
and
|
||||
|
||||
Ef+BVndbeTJeXWLnQtm5bDC2UVpc0vH2TF2ksZPAPwcODSkb (base64) or
|
||||
Ef-BVndbeTJeXWLnQtm5bDC2UVpc0vH2TF2ksZPAPwcODSkb (base64url)
|
||||
kf/8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15-KsQHFLbKSMiYIny (base64)
|
||||
kf_8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15-KsQHFLbKSMiYIny (base64url)
|
||||
|
||||
in the "user-friendly" form (to be displayed by user-friendly clients). Notice that both forms (base64 and base64url) are valid and must be accepted.
|
||||
|
||||
@ -50,27 +50,27 @@ Inspecting the state of smart contracts with the aid of the TON Lite Client is e
|
||||
|
||||
> last
|
||||
...
|
||||
> getaccount -1:8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d
|
||||
> getaccount -1:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260
|
||||
or
|
||||
> getaccount Ef-BVndbeTJeXWLnQtm5bDC2UVpc0vH2TF2ksZPAPwcODSkb
|
||||
> getaccount kf_8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15-KsQHFLbKSMiYIny
|
||||
|
||||
You will see something like this:
|
||||
|
||||
------------------------------------
|
||||
got account state for -1:8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D with respect to blocks (-1,8000000000000000,1645):4D5E1B928490BE34A4F03C9BC996661B8AD4E988F1460DB69BE3634B1E843DAF:9D85BB116D1DA4BFD999E9092BBD43B3A9F96EC9C9ED7AFDC81B27B08D3861A0 and (-1,8000000000000000,1645):4D5E1B928490BE34A4F03C9BC996661B8AD4E988F1460DB69BE3634B1E843DAF:9D85BB116D1DA4BFD999E9092BBD43B3A9F96EC9C9ED7AFDC81B27B08D3861A0
|
||||
got account state for -1 : FCB91A3A3816D0F7B8C2C76108B8A9BC5A6B7A55BD79F8AB101C52DB29232260 with respect to blocks (-1,8000000000000000,2075):BFE876CE2085274FEDAF1BD80F3ACE50F42B5A027DF230AD66DCED1F09FB39A7:522C027A721FABCB32574E3A809ABFBEE6A71DE929C1FA2B1CD0DDECF3056505
|
||||
account state is (account
|
||||
addr:(addr_std
|
||||
anycast:nothing workchain_id:-1 address:x8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D)
|
||||
anycast:nothing workchain_id:-1 address:xFCB91A3A3816D0F7B8C2C76108B8A9BC5A6B7A55BD79F8AB101C52DB29232260)
|
||||
storage_stat:(storage_info
|
||||
used:(storage_used
|
||||
cells:(var_uint len:1 value:3)
|
||||
bits:(var_uint len:2 value:539)
|
||||
public_cells:(var_uint len:0 value:0)) last_paid:0
|
||||
bits:(var_uint len:2 value:707)
|
||||
public_cells:(var_uint len:0 value:0)) last_paid:1568899526
|
||||
due_payment:nothing)
|
||||
storage:(account_storage last_trans_lt:0
|
||||
storage:(account_storage last_trans_lt:2310000003
|
||||
balance:(currencies
|
||||
grams:(nanograms
|
||||
amount:(var_uint len:7 value:1000000000000000))
|
||||
amount:(var_uint len:6 value:9998859500889))
|
||||
other:(extra_currencies
|
||||
dict:hme_empty))
|
||||
state:(account_active
|
||||
@ -80,7 +80,7 @@ account state is (account
|
||||
code:(just
|
||||
value:(raw@^Cell
|
||||
x{}
|
||||
x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54}
|
||||
x{FF0020DD2082014C97BA9730ED44D0D70B1FE0A4F260D31F01ED44D0D31FD166BAF2A1F8000120D74A8E11D307D459821804A817C80073FB0201FB00DED1A4C8CB1FC9ED54}
|
||||
))
|
||||
data:(just
|
||||
value:(raw@^Cell
|
||||
@ -88,9 +88,10 @@ account state is (account
|
||||
x{00009A15}
|
||||
))
|
||||
library:hme_empty))))
|
||||
x{CFF8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D2068086C0000000000000000000000001C0E35FA931A000134_}
|
||||
x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54}
|
||||
x{00000000}
|
||||
x{CFFFCB91A3A3816D0F7B8C2C76108B8A9BC5A6B7A55BD79F8AB101C52DB2923226020680B0C2EC1C0E300000000226BF360D8246029DFF56534_}
|
||||
x{FF0020DD2082014C97BA9730ED44D0D70B1FE0A4F260D31F01ED44D0D31FD166BAF2A1F8000120D74A8E11D307D459821804A817C80073FB0201FB00DED1A4C8CB1FC9ED54}
|
||||
x{00000003}
|
||||
last transaction lt = 2310000001 hash = 73F89C6F8910F598AD84504A777E5945C798AC8C847FF861C090109665EAC6BA
|
||||
------------------------------------
|
||||
|
||||
The first information line "got account state ... for ..." shows the account address and the masterchain block identifier with respect to which the account state has been dumped. Notice that even if the account state changes in a subsequent block, the `getaccount xxx` command will return the same result until the reference block is updated to a newer value by a `last` command. In this way one can study the state of all accounts and obtain consistent results.
|
||||
@ -99,7 +100,7 @@ The "account state is (account ... " line begins the pretty-printed deserialized
|
||||
|
||||
Finally, the last several lines beginning with x{CFF538... (the "raw dump") contain the same information displayed as a tree of cells. In this case, we have one root cell containing the data bits CFF...134_ (the underscore means that the last binary one and all subsequent binary zeroes are to be removed, so hexadecimal "4_" corresponds to binary "0"), and two cells that are its children (displayed with one-space indentation).
|
||||
|
||||
We can see that x{FF0020DDA4F260...} is the code of this smart contract. If we consult the Appendix A of the TON Virtual Machine documentation, we can even disassemble this code: FF00 is SETCP 0, 20 is DUP, DD is IFNOTRET, A4 is INC, F260 is THROWIF 32, and so on. (Incidentally, you can find the source code of this smartcontract in the source file crypto/block/mc0.fif .)
|
||||
We can see that x{FF0020DD20...} is the code of this smart contract. If we consult the Appendix A of the TON Virtual Machine documentation, we can even disassemble this code: FF00 is SETCP 0, 20 is DUP, DD is IFNOTRET, 20 is DUP, and so on. (Incidentally, you can find the source code of this smartcontract in the source file crypto/block/new-testgiver.fif .)
|
||||
|
||||
We can also see that x{00009A15} (the actual value you see may be different) is the persistent data of this smart contract. It is actually an unsigned 32-bit integer, used by the smart contract as the counter of operations performed so far. Notice that this value is big-endian (i.e., 3 is encoded as x{00000003}, not as x{03000000}), as are all integers inside the TON Blockchain. In this case the counter is equal to 0x9A15 = 39445.
|
||||
|
||||
@ -246,12 +247,26 @@ In the Test Network, you have another option: you can ask the "test giver" to gi
|
||||
5. Using the test giver smart contract
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You need to know the address of the test giver smart contract. We'll assume that it is -1:8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d, or, equivalently, Ef-BVndbeTJeXWLnQtm5bDC2UVpc0vH2TF2ksZPAPwcODSkb, as indicated in one of the previous examples. You inspect the state of this smart contract in the Lite Client by typing
|
||||
You need to know the address of the test giver smart contract. We'll assume that it is -1:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260, or, equivalently, kf_8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15-KsQHFLbKSMiYIny, as indicated in one of the previous examples. You inspect the state of this smart contract in the Lite Client by typing
|
||||
|
||||
> last
|
||||
> getaccount Ef-BVndbeTJeXWLnQtm5bDC2UVpc0vH2TF2ksZPAPwcODSkb
|
||||
> getaccount kf_8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15-KsQHFLbKSMiYIny
|
||||
|
||||
as explained above in Section 2. The only number you need from the output is the 32-bit sequence number stored in the smart contract data (it is zero in the example above, but generally it will be non-zero).
|
||||
as explained above in Section 2. The only number you need from the output is the 32-bit sequence number stored in the smart contract data (it is 0x9A15 in the example above, but generally it will be different). A simpler way of obtaining the current value of this sequence number is by typing
|
||||
|
||||
> last
|
||||
> runmethod kf_8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15-KsQHFLbKSMiYIny seqno
|
||||
|
||||
producing the correct value 39445 = 0x9A15:
|
||||
|
||||
--------------------------------------------
|
||||
got account state for -1 : FCB91A3A3816D0F7B8C2C76108B8A9BC5A6B7A55BD79F8AB101C52DB29232260 with respect to blocks (-1,8000000000000000,2240):18E6DA7707191E76C71EABBC5277650666B7E2CFA2AEF2CE607EAFE8657A3820:4EFA2540C5D1E4A1BA2B529EE0B65415DF46BFFBD27A8EB74C4C0E17770D03B1
|
||||
creating VM
|
||||
starting VM to run method `seqno` (85143) of smart contract -1:FCB91A3A3816D0F7B8C2C76108B8A9BC5A6B7A55BD79F8AB101C52DB29232260
|
||||
...
|
||||
arguments: [ 85143 ]
|
||||
result: [ 39445 ]
|
||||
--------------------------------------------
|
||||
|
||||
Next, you create an external message to the test giver asking it to send another message to your (uninitialized) smart contract carrying a specified amount of test Grams. There is a special Fift script for generating this external message located at crypto/smartcont/testgiver.fif:
|
||||
|
||||
@ -267,7 +282,7 @@ Next, you create an external message to the test giver asking it to send another
|
||||
$# 3 - -2 and ' usage if
|
||||
|
||||
// "testgiver.addr" load-address
|
||||
Masterchain 0x8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d
|
||||
Masterchain 0xfcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260
|
||||
2constant giver_addr
|
||||
."Test giver address = " giver_addr 2dup .addr cr 6 .Addr cr
|
||||
|
||||
@ -314,8 +329,8 @@ This Fift code creates an internal message from the test giver smart contract to
|
||||
The external message is serialized and saved into the file `wallet-query.boc`. Some output is generated in the process:
|
||||
|
||||
---------------------------------------------
|
||||
Test giver address = -1:8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d
|
||||
kf-BVndbeTJeXWLnQtm5bDC2UVpc0vH2TF2ksZPAPwcODZKR
|
||||
Test giver address = -1:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260
|
||||
kf_8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15-KsQHFLbKSMiYIny
|
||||
Requesting GR$6.666 to account 0QAu6bT9Twd8myIygMNXY9-e2rC0GsINNvQAlnfflcOv4uVb = 0:2ee9b4fd4f077c9b223280c35763df9edab0b41ac20d36f4009677df95c3afe2 seqno=0x9a15 bounce=0
|
||||
enveloping message: x{00009A1501}
|
||||
x{42001774DA7EA783BE4D91194061ABB1EFCF6D585A0D61069B7A004B3BEFCAE1D7F1280C6A98B4000000000000000000000000000047494654}
|
||||
@ -340,19 +355,19 @@ We will see some output:
|
||||
which means that the external message has been delivered to the collator pool. Afterwards one of the collators might choose to include this external message in a block, creating a transaction for the test giver smart contract to process this external message. We can check whether the state of the test giver has changed:
|
||||
|
||||
> last
|
||||
> getaccount Ef-BVndbeTJeXWLnQtm5bDC2UVpc0vH2TF2ksZPAPwcODSkb
|
||||
> getaccount kf_8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15-KsQHFLbKSMiYIny
|
||||
|
||||
(If you forget to type `last`, you are likely to see the unchanged state of the test giver smart contract.) The resulting output would be:
|
||||
|
||||
---------------------------------------------
|
||||
got account state for -1:8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D with respect to blocks (-1,8000000000000000,10441):2DCFB7F734913261B85B8866DFF7CBEF07205EAA0769F4EE15E242AB520A2CC5:4F96F417BCD74D5DAE0CC3CCC285E513B85652002D9AD8CC884781D8465E3591 and (-1,8000000000000000,10441):2DCFB7F734913261B85B8866DFF7CBEF07205EAA0769F4EE15E242AB520A2CC5:4F96F417BCD74D5DAE0CC3CCC285E513B85652002D9AD8CC884781D8465E3591
|
||||
got account state for -1 : FCB91A3A3816D0F7B8C2C76108B8A9BC5A6B7A55BD79F8AB101C52DB29232260 with respect to blocks (-1,8000000000000000,2240):18E6DA7707191E76C71EABBC5277650666B7E2CFA2AEF2CE607EAFE8657A3820:4EFA2540C5D1E4A1BA2B529EE0B65415DF46BFFBD27A8EB74C4C0E17770D03B1
|
||||
account state is (account
|
||||
addr:(addr_std
|
||||
anycast:nothing workchain_id:-1 address:x8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D)
|
||||
anycast:nothing workchain_id:-1 address:xFCB91A3A3816D0F7B8C2C76108B8A9BC5A6B7A55BD79F8AB101C52DB29232260)
|
||||
storage_stat:(storage_info
|
||||
used:(storage_used
|
||||
cells:(var_uint len:1 value:3)
|
||||
bits:(var_uint len:2 value:539)
|
||||
bits:(var_uint len:2 value:707)
|
||||
public_cells:(var_uint len:0 value:0)) last_paid:0
|
||||
due_payment:nothing)
|
||||
storage:(account_storage last_trans_lt:10697000003
|
||||
|
@ -33,10 +33,8 @@ class ClientKotlin {
|
||||
@SmallTest
|
||||
class TonTest {
|
||||
val config = """{
|
||||
"@type": "config.global",
|
||||
"liteclients": [
|
||||
"liteservers": [
|
||||
{
|
||||
"@type": "liteclient.config.global",
|
||||
"ip": 1137658550,
|
||||
"port": 4924,
|
||||
"id": {
|
||||
@ -44,7 +42,17 @@ class TonTest {
|
||||
"key": "peJTw/arlRfssgTuf9BMypJzqOi7SXEqSPSWiEw2U1M="
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
"validator": {
|
||||
"@type": "validator.config.global",
|
||||
"zero_state": {
|
||||
"workchain": -1,
|
||||
"shard": -9223372036854775808,
|
||||
"seqno": 0,
|
||||
"root_hash": "VCSXxDHhTALFxReyTZRd8E4Ya3ySOmpOWAS4rBX9XBY=",
|
||||
"file_hash": "eh9yveSz1qMdJ7mOsO+I+H77jkLr9NpAuEkoJuseXBo="
|
||||
}
|
||||
}
|
||||
}"""
|
||||
@Test
|
||||
fun createTestWallet() {
|
||||
@ -52,7 +60,7 @@ class TonTest {
|
||||
val dir = getContext().getExternalFilesDir(null).toString() + "/";
|
||||
runBlocking {
|
||||
client.send(TonApi.Init(TonApi.Options(config, dir)))
|
||||
val key = client.send(TonApi.CreateNewKey("local password".toByteArray(), "mnemonic password".toByteArray())) as TonApi.Key
|
||||
val key = client.send(TonApi.CreateNewKey("local password".toByteArray(), "mnemonic password".toByteArray(), "".toByteArray())) as TonApi.Key
|
||||
val walletAddress = client.send(TonApi.TestWalletGetAccountAddress(TonApi.TestWalletInitialAccountState(key.publicKey))) as TonApi.AccountAddress;
|
||||
val testGiverState = client.send(TonApi.TestGiverGetAccountState()) as TonApi.TestGiverAccountState
|
||||
|
||||
|
@ -54,21 +54,28 @@ public class TonTestJava {
|
||||
}
|
||||
}
|
||||
|
||||
String config =
|
||||
"{" +
|
||||
"\"@type\": \"config.global\"," +
|
||||
"\"liteclients\": [" +
|
||||
"{" +
|
||||
"\"@type\": \"liteclient.config.global\"," +
|
||||
"\"ip\": 1137658550," +
|
||||
"\"port\": 4924," +
|
||||
"\"id\": {" +
|
||||
"\"@type\": \"pub.ed25519\"," +
|
||||
"\"key\": \"peJTw/arlRfssgTuf9BMypJzqOi7SXEqSPSWiEw2U1M=\"" +
|
||||
"}" +
|
||||
"}" +
|
||||
"]" +
|
||||
"}";
|
||||
String config = "{\n" +
|
||||
" \"liteservers\": [\n" +
|
||||
" {\n" +
|
||||
" \"ip\": 1137658550,\n" +
|
||||
" \"port\": 4924,\n" +
|
||||
" \"id\": {\n" +
|
||||
" \"@type\": \"pub.ed25519\",\n" +
|
||||
" \"key\": \"peJTw/arlRfssgTuf9BMypJzqOi7SXEqSPSWiEw2U1M=\"\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" ],\n" +
|
||||
" \"validator\": {\n" +
|
||||
" \"@type\": \"validator.config.global\",\n" +
|
||||
" \"zero_state\": {\n" +
|
||||
" \"workchain\": -1,\n" +
|
||||
" \"shard\": -9223372036854775808,\n" +
|
||||
" \"seqno\": 0,\n" +
|
||||
" \"root_hash\": \"VCSXxDHhTALFxReyTZRd8E4Ya3ySOmpOWAS4rBX9XBY=\",\n" +
|
||||
" \"file_hash\": \"eh9yveSz1qMdJ7mOsO+I+H77jkLr9NpAuEkoJuseXBo=\"\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
private void appendLog(String log) {
|
||||
Log.w("XX", log);
|
||||
@ -85,7 +92,7 @@ public class TonTestJava {
|
||||
return;
|
||||
}
|
||||
appendLog("config set ok");
|
||||
TonApi.Key key = (TonApi.Key) client.send(new TonApi.CreateNewKey("local password".getBytes(), "mnemonic password".getBytes()));
|
||||
TonApi.Key key = (TonApi.Key) client.send(new TonApi.CreateNewKey("local password".getBytes(), "mnemonic password".getBytes(), "".getBytes()));
|
||||
appendLog("got private key");
|
||||
TonApi.AccountAddress walletAddress = (TonApi.AccountAddress) client.send(new TonApi.TestWalletGetAccountAddress(new TonApi.TestWalletInitialAccountState(key.publicKey)));
|
||||
appendLog("got account address");
|
||||
|
@ -1,5 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
|
||||
|
||||
option(TDUTILS_MIME_TYPE "Generate mime types conversion (gperf is required)" ON)
|
||||
|
||||
if (WIN32)
|
||||
if (WINGETOPT_FOUND)
|
||||
set(TD_HAVE_GETOPT 1)
|
||||
@ -96,7 +98,6 @@ set(TDUTILS_SOURCE
|
||||
td/utils/JsonBuilder.cpp
|
||||
td/utils/logging.cpp
|
||||
td/utils/misc.cpp
|
||||
td/utils/MimeType.cpp
|
||||
td/utils/MpmcQueue.cpp
|
||||
td/utils/OptionsParser.cpp
|
||||
td/utils/Random.cpp
|
||||
@ -202,7 +203,6 @@ set(TDUTILS_SOURCE
|
||||
td/utils/List.h
|
||||
td/utils/logging.h
|
||||
td/utils/MemoryLog.h
|
||||
td/utils/MimeType.h
|
||||
td/utils/misc.h
|
||||
td/utils/MovableValue.h
|
||||
td/utils/MpmcQueue.h
|
||||
@ -251,6 +251,14 @@ set(TDUTILS_SOURCE
|
||||
td/utils/VectorQueue.h
|
||||
)
|
||||
|
||||
if (TDUTILS_MIME_TYPE)
|
||||
set(TDUTILS_SOURCE
|
||||
${TDUTILS_SOURCE}
|
||||
td/utils/MimeType.cpp
|
||||
td/utils/MimeType.h
|
||||
)
|
||||
endif()
|
||||
|
||||
set(TDUTILS_TEST_SOURCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/buffer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/ConcurrentHashMap.cpp
|
||||
@ -284,7 +292,7 @@ if (WIN32)
|
||||
# target_link_libraries(tdutils PRIVATE ${WS2_32_LIBRARY} ${MSWSOCK_LIBRARY})
|
||||
target_link_libraries(tdutils PRIVATE ws2_32 Mswsock Normaliz)
|
||||
endif()
|
||||
if (NOT CMAKE_CROSSCOMPILING)
|
||||
if (NOT CMAKE_CROSSCOMPILING AND TDUTILS_MIME_TYPE)
|
||||
add_dependencies(tdutils tdmime_auto)
|
||||
endif()
|
||||
|
||||
|
@ -3,6 +3,10 @@ cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
|
||||
# Generates files for MIME type <-> extension conversions
|
||||
# DEPENDS ON: gperf grep bash/powershell
|
||||
|
||||
if (NOT TDUTILS_MIME_TYPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
file(MAKE_DIRECTORY auto)
|
||||
|
||||
set(TDMIME_SOURCE
|
||||
|
@ -168,8 +168,9 @@ class TlParser {
|
||||
data += sizeof(int32);
|
||||
} else {
|
||||
check_len(sizeof(int32));
|
||||
result_len = data[1] + (data[2] << 8) + (data[3] << 16) + (data[4] << 24) + (static_cast<uint64>(data[5]) << 32) +
|
||||
(static_cast<uint64>(data[6]) << 40) + (static_cast<uint64>(data[7]) << 48);
|
||||
result_len = narrow_cast<size_t>(data[1] + (data[2] << 8) + (data[3] << 16) + (data[4] << 24) +
|
||||
(static_cast<uint64>(data[5]) << 32) + (static_cast<uint64>(data[6]) << 40) +
|
||||
(static_cast<uint64>(data[7]) << 48));
|
||||
if (result_len > std::numeric_limits<size_t>::max() - 3) {
|
||||
set_error("Too big string found");
|
||||
return T();
|
||||
|
@ -367,6 +367,10 @@ tonNode.downloadZeroState block:tonNode.blockIdExt = tonNode.Data;
|
||||
tonNode.downloadBlockProof block:tonNode.blockIdExt = tonNode.Data;
|
||||
tonNode.downloadBlockProofLink block:tonNode.blockIdExt = tonNode.Data;
|
||||
|
||||
tonNode.slave.sendExtMessage message:tonNode.externalMessage = True;
|
||||
|
||||
tonNode.query = Object;
|
||||
|
||||
---types---
|
||||
|
||||
// bit 0 - started
|
||||
@ -482,9 +486,12 @@ engine.controlInterface id:int256 port:int allowed:(vector engine.controlProcess
|
||||
engine.gc ids:(vector int256) = engine.Gc;
|
||||
|
||||
engine.dht.config dht:(vector engine.dht) gc:engine.gc = engine.dht.Config;
|
||||
engine.validator.fullNodeMaster port:int adnl:int256 = engine.validator.FullNodeMaster;
|
||||
engine.validator.fullNodeSlave ip:int port:int adnl:PublicKey = engine.validator.FullNodeSlave;
|
||||
engine.validator.config out_port:int addrs:(vector engine.Addr) adnl:(vector engine.adnl)
|
||||
dht:(vector engine.dht)
|
||||
validators:(vector engine.validator) fullnode:int256
|
||||
validators:(vector engine.validator) fullnode:int256 fullnodeslave:engine.validator.fullNodeSlave
|
||||
fullnodemasters:(vector engine.validator.fullNodeMaster)
|
||||
liteservers:(vector engine.liteServer) control:(vector engine.controlInterface)
|
||||
gc:engine.gc = engine.validator.Config;
|
||||
|
||||
|
Binary file not shown.
@ -366,6 +366,16 @@ struct Ed25519_PublicKey {
|
||||
bool operator==(const Ed25519_PublicKey& other) const {
|
||||
return _pubkey == other._pubkey;
|
||||
}
|
||||
bool clear() {
|
||||
_pubkey.set_zero();
|
||||
return true;
|
||||
}
|
||||
bool is_zero() const {
|
||||
return _pubkey.is_zero();
|
||||
}
|
||||
bool non_zero() const {
|
||||
return !is_zero();
|
||||
}
|
||||
};
|
||||
|
||||
// represents (the contents of) a block
|
||||
|
@ -119,7 +119,10 @@ install(TARGETS tonlibjson TonlibJson EXPORT Tonlib
|
||||
)
|
||||
|
||||
if (NOT TON_USE_ABSEIL)
|
||||
install(TARGETS tdnet keys crc32c tdactor adnllite tl_api tl-utils tl_lite_api tl-lite-utils ton_crypto ton_block
|
||||
if (WIN32)
|
||||
set(WINGETOPT_TARGET wingetopt)
|
||||
endif()
|
||||
install(TARGETS tdnet keys crc32c tdactor adnllite tl_api tl-utils tl_lite_api tl-lite-utils ton_crypto ton_block ${WINGETOPT_TARGET}
|
||||
tdutils tl_tonlib_api tonlib lite-client-common Tonlib EXPORT Tonlib
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
|
@ -66,8 +66,7 @@ class ExtClient {
|
||||
auto f = r_error.move_as_ok();
|
||||
return td::Status::Error(f->code_, f->message_);
|
||||
}
|
||||
auto res = ton::fetch_result<QueryT>(std::move(data));
|
||||
return std::move(res);
|
||||
return ton::fetch_result<QueryT>(std::move(data));
|
||||
}());
|
||||
});
|
||||
}
|
||||
|
@ -24,12 +24,12 @@
|
||||
namespace tonlib {
|
||||
const block::StdAddress& TestGiver::address() {
|
||||
static block::StdAddress res =
|
||||
block::StdAddress::parse("-1:8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d").move_as_ok();
|
||||
block::StdAddress::parse("kf_8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15-KsQHFLbKSMiYIny").move_as_ok();
|
||||
return res;
|
||||
}
|
||||
|
||||
vm::CellHash TestGiver::get_init_code_hash() {
|
||||
return vm::CellHash::from_slice(td::base64_decode("s7RouN9wfJ4Avx8h0uw6X3ZEJfN3MYOUmzrC8JXfMAw=").move_as_ok());
|
||||
return vm::CellHash::from_slice(td::base64_decode("wDkZp0yR4xo+9+BnuAPfGVjBzK6FPzqdv2DwRq3z3KE=").move_as_ok());
|
||||
}
|
||||
|
||||
td::Ref<vm::Cell> TestGiver::make_a_gift_message(td::uint32 seqno, td::uint64 gramms,
|
||||
|
@ -48,7 +48,7 @@ struct RawDecryptedKey {
|
||||
|
||||
struct EncryptedKey;
|
||||
struct DecryptedKey {
|
||||
DecryptedKey() = default;
|
||||
DecryptedKey() = delete;
|
||||
explicit DecryptedKey(const Mnemonic &mnemonic);
|
||||
DecryptedKey(std::vector<td::SecureString> mnemonic_words, td::Ed25519::PrivateKey key);
|
||||
DecryptedKey(RawDecryptedKey key);
|
||||
|
@ -121,6 +121,18 @@ Config::Config(ton::ton_api::engine_validator_config &config) {
|
||||
}
|
||||
config_add_full_node_adnl_id(ton::PublicKeyHash{config.fullnode_}).ensure();
|
||||
|
||||
if (config.fullnodeslave_) {
|
||||
td::IPAddress ip;
|
||||
ip.init_ipv4_port(td::IPAddress::ipv4_to_str(config.fullnodeslave_->ip_),
|
||||
static_cast<td::uint16>(config.fullnodeslave_->port_))
|
||||
.ensure();
|
||||
config_add_full_node_slave(ip, ton::PublicKey{config.fullnodeslave_->adnl_}).ensure();
|
||||
}
|
||||
|
||||
for (auto &s : config.fullnodemasters_) {
|
||||
config_add_full_node_master(s->port_, ton::PublicKeyHash{s->adnl_}).ensure();
|
||||
}
|
||||
|
||||
for (auto &serv : config.liteservers_) {
|
||||
config_add_lite_server(ton::PublicKeyHash{serv->id_}, serv->port_).ensure();
|
||||
}
|
||||
@ -180,6 +192,17 @@ ton::tl_object_ptr<ton::ton_api::engine_validator_config> Config::tl() const {
|
||||
val.first.tl(), std::move(temp_vec), std::move(adnl_val_vec), val.second.election_date, val.second.expire_at));
|
||||
}
|
||||
|
||||
ton::tl_object_ptr<ton::ton_api::engine_validator_fullNodeSlave> full_node_slave = nullptr;
|
||||
if (!full_node_slave_adnl_id.empty()) {
|
||||
full_node_slave = ton::create_tl_object<ton::ton_api::engine_validator_fullNodeSlave>(
|
||||
full_node_slave_addr.get_ipv4(), full_node_slave_addr.get_port(), full_node_slave_adnl_id.tl());
|
||||
}
|
||||
std::vector<ton::tl_object_ptr<ton::ton_api::engine_validator_fullNodeMaster>> full_node_masters_vec;
|
||||
for (auto &x : full_node_masters) {
|
||||
full_node_masters_vec.push_back(
|
||||
ton::create_tl_object<ton::ton_api::engine_validator_fullNodeMaster>(x.first, x.second.tl()));
|
||||
}
|
||||
|
||||
std::vector<ton::tl_object_ptr<ton::ton_api::engine_liteServer>> liteserver_vec;
|
||||
for (auto &x : liteservers) {
|
||||
liteserver_vec.push_back(ton::create_tl_object<ton::ton_api::engine_liteServer>(x.second.tl(), x.first));
|
||||
@ -201,7 +224,8 @@ ton::tl_object_ptr<ton::ton_api::engine_validator_config> Config::tl() const {
|
||||
}
|
||||
return ton::create_tl_object<ton::ton_api::engine_validator_config>(
|
||||
out_port, std::move(addrs_vec), std::move(adnl_vec), std::move(dht_vec), std::move(val_vec), full_node.tl(),
|
||||
std::move(liteserver_vec), std::move(control_vec), std::move(gc_vec));
|
||||
std::move(full_node_slave), std::move(full_node_masters_vec), std::move(liteserver_vec), std::move(control_vec),
|
||||
std::move(gc_vec));
|
||||
}
|
||||
|
||||
td::Result<bool> Config::config_add_network_addr(td::IPAddress in_ip, td::IPAddress out_ip,
|
||||
@ -362,6 +386,36 @@ td::Result<bool> Config::config_add_full_node_adnl_id(ton::PublicKeyHash id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
td::Result<bool> Config::config_add_full_node_slave(td::IPAddress addr, ton::PublicKey id) {
|
||||
if (full_node_slave_adnl_id == id && addr == full_node_slave_addr) {
|
||||
return false;
|
||||
}
|
||||
full_node_slave_adnl_id = id;
|
||||
full_node_slave_addr = addr;
|
||||
return true;
|
||||
}
|
||||
|
||||
td::Result<bool> Config::config_add_full_node_master(td::int32 port, ton::PublicKeyHash id) {
|
||||
if (adnl_ids.count(id) == 0) {
|
||||
return td::Status::Error(ton::ErrorCode::notready,
|
||||
"to-be-added full node master adnl address not in adnl nodes list");
|
||||
}
|
||||
auto it = full_node_masters.find(port);
|
||||
if (it != full_node_masters.end()) {
|
||||
if (it->second == id) {
|
||||
return false;
|
||||
} else {
|
||||
return td::Status::Error("duplicate master port");
|
||||
}
|
||||
}
|
||||
if (liteservers.count(port) > 0 || controls.count(port) > 0) {
|
||||
return td::Status::Error("duplicate master port");
|
||||
}
|
||||
incref(id);
|
||||
full_node_masters.emplace(port, id);
|
||||
return true;
|
||||
}
|
||||
|
||||
td::Result<bool> Config::config_add_lite_server(ton::PublicKeyHash key, td::int32 port) {
|
||||
if (controls.count(port) > 0) {
|
||||
return td::Status::Error(ton::ErrorCode::error, "duplicate port");
|
||||
@ -1351,8 +1405,11 @@ void ValidatorEngine::start_dht() {
|
||||
add_dht(dht);
|
||||
}
|
||||
|
||||
CHECK(!default_dht_node_.is_zero());
|
||||
td::actor::send_closure(adnl_, &ton::adnl::Adnl::register_dht_node, dht_nodes_[default_dht_node_].get());
|
||||
if (default_dht_node_.is_zero()) {
|
||||
LOG(ERROR) << "trying to work without DHT";
|
||||
} else {
|
||||
td::actor::send_closure(adnl_, &ton::adnl::Adnl::register_dht_node, dht_nodes_[default_dht_node_].get());
|
||||
}
|
||||
|
||||
started_dht();
|
||||
}
|
||||
@ -1371,8 +1428,10 @@ void ValidatorEngine::started_rldp() {
|
||||
}
|
||||
|
||||
void ValidatorEngine::start_overlays() {
|
||||
overlay_manager_ =
|
||||
ton::overlay::Overlays::create(db_root_, keyring_.get(), adnl_.get(), dht_nodes_[default_dht_node_].get());
|
||||
if (!default_dht_node_.is_zero()) {
|
||||
overlay_manager_ =
|
||||
ton::overlay::Overlays::create(db_root_, keyring_.get(), adnl_.get(), dht_nodes_[default_dht_node_].get());
|
||||
}
|
||||
started_overlays();
|
||||
}
|
||||
|
||||
@ -1403,14 +1462,26 @@ void ValidatorEngine::started_validator() {
|
||||
}
|
||||
|
||||
void ValidatorEngine::start_full_node() {
|
||||
if (!config_.full_node.is_zero()) {
|
||||
if (!config_.full_node.is_zero() || !config_.full_node_slave_adnl_id.empty()) {
|
||||
auto pk = ton::PrivateKey{ton::privkeys::Ed25519::random()};
|
||||
auto short_id = pk.compute_short_id();
|
||||
td::actor::send_closure(keyring_, &ton::keyring::Keyring::add_key, std::move(pk), true, [](td::Unit) {});
|
||||
if (!config_.full_node_slave_adnl_id.empty()) {
|
||||
class Cb : public ton::adnl::AdnlExtClient::Callback {
|
||||
public:
|
||||
void on_ready() override {
|
||||
}
|
||||
void on_stop_ready() override {
|
||||
}
|
||||
};
|
||||
full_node_client_ = ton::adnl::AdnlExtClient::create(ton::adnl::AdnlNodeIdFull{config_.full_node_slave_adnl_id},
|
||||
config_.full_node_slave_addr, std::make_unique<Cb>());
|
||||
}
|
||||
full_node_ = ton::validator::fullnode::FullNode::create(
|
||||
short_id, ton::adnl::AdnlNodeIdShort{config_.full_node}, validator_options_->zero_block_id().file_hash,
|
||||
keyring_.get(), adnl_.get(), rldp_.get(), dht_nodes_[default_dht_node_].get(), overlay_manager_.get(),
|
||||
validator_manager_.get(), db_root_);
|
||||
keyring_.get(), adnl_.get(), rldp_.get(),
|
||||
default_dht_node_.is_zero() ? td::actor::ActorId<ton::dht::Dht>{} : dht_nodes_[default_dht_node_].get(),
|
||||
overlay_manager_.get(), validator_manager_.get(), full_node_client_.get(), db_root_);
|
||||
}
|
||||
|
||||
for (auto &v : config_.validators) {
|
||||
@ -1499,6 +1570,21 @@ void ValidatorEngine::started_control_interface(td::actor::ActorOwn<ton::adnl::A
|
||||
add_control_process(s.second.key, static_cast<td::uint16>(s.first), p.first, p.second);
|
||||
}
|
||||
}
|
||||
start_full_node_masters();
|
||||
}
|
||||
|
||||
void ValidatorEngine::start_full_node_masters() {
|
||||
for (auto &x : config_.full_node_masters) {
|
||||
full_node_masters_.emplace(
|
||||
static_cast<td::uint16>(x.first),
|
||||
ton::validator::fullnode::FullNodeMaster::create(
|
||||
ton::adnl::AdnlNodeIdShort{x.second}, static_cast<td::uint16>(x.first),
|
||||
validator_options_->zero_block_id().file_hash, keyring_.get(), adnl_.get(), validator_manager_.get()));
|
||||
}
|
||||
started_full_node_masters();
|
||||
}
|
||||
|
||||
void ValidatorEngine::started_full_node_masters() {
|
||||
started();
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,8 @@
|
||||
#include "validator/manager.h"
|
||||
#include "validator/validator.h"
|
||||
#include "validator/full-node.h"
|
||||
#include "validator/full-node-master.h"
|
||||
#include "adnl/adnl-ext-client.h"
|
||||
|
||||
#include "td/actor/MultiPromise.h"
|
||||
|
||||
@ -74,7 +76,10 @@ struct Config {
|
||||
std::map<ton::PublicKeyHash, AdnlCategory> adnl_ids;
|
||||
std::set<ton::PublicKeyHash> dht_ids;
|
||||
std::map<ton::PublicKeyHash, Validator> validators;
|
||||
ton::PublicKeyHash full_node;
|
||||
ton::PublicKeyHash full_node = ton::PublicKeyHash::zero();
|
||||
td::IPAddress full_node_slave_addr;
|
||||
ton::PublicKey full_node_slave_adnl_id;
|
||||
std::map<td::int32, ton::PublicKeyHash> full_node_masters;
|
||||
std::map<td::int32, ton::PublicKeyHash> liteservers;
|
||||
std::map<td::int32, Control> controls;
|
||||
std::set<ton::PublicKeyHash> gc;
|
||||
@ -96,6 +101,8 @@ struct Config {
|
||||
td::Result<bool> config_add_validator_adnl_id(ton::PublicKeyHash perm_key, ton::PublicKeyHash adnl_id,
|
||||
ton::UnixTime expire_at);
|
||||
td::Result<bool> config_add_full_node_adnl_id(ton::PublicKeyHash id);
|
||||
td::Result<bool> config_add_full_node_slave(td::IPAddress addr, ton::PublicKey id);
|
||||
td::Result<bool> config_add_full_node_master(td::int32 port, ton::PublicKeyHash id);
|
||||
td::Result<bool> config_add_lite_server(ton::PublicKeyHash key, td::int32 port);
|
||||
td::Result<bool> config_add_control_interface(ton::PublicKeyHash key, td::int32 port);
|
||||
td::Result<bool> config_add_control_process(ton::PublicKeyHash key, td::int32 port, ton::PublicKeyHash id,
|
||||
@ -130,7 +137,9 @@ class ValidatorEngine : public td::actor::Actor {
|
||||
ton::PublicKeyHash default_dht_node_ = ton::PublicKeyHash::zero();
|
||||
td::actor::ActorOwn<ton::overlay::Overlays> overlay_manager_;
|
||||
td::actor::ActorOwn<ton::validator::ValidatorManagerInterface> validator_manager_;
|
||||
td::actor::ActorOwn<ton::adnl::AdnlExtClient> full_node_client_;
|
||||
td::actor::ActorOwn<ton::validator::fullnode::FullNode> full_node_;
|
||||
std::map<td::uint16, td::actor::ActorOwn<ton::validator::fullnode::FullNodeMaster>> full_node_masters_;
|
||||
td::actor::ActorOwn<ton::adnl::AdnlExtServer> control_ext_server_;
|
||||
|
||||
std::string local_config_ = "";
|
||||
@ -266,6 +275,9 @@ class ValidatorEngine : public td::actor::Actor {
|
||||
void start_control_interface();
|
||||
void started_control_interface(td::actor::ActorOwn<ton::adnl::AdnlExtServer> control_ext_server);
|
||||
|
||||
void start_full_node_masters();
|
||||
void started_full_node_masters();
|
||||
|
||||
void started();
|
||||
|
||||
void alarm() override;
|
||||
|
@ -111,6 +111,9 @@ set(FULL_NODE_SOURCE
|
||||
full-node-shard.h
|
||||
full-node-shard.hpp
|
||||
full-node-shard.cpp
|
||||
full-node-master.h
|
||||
full-node-master.hpp
|
||||
full-node-master.cpp
|
||||
|
||||
net/download-block.hpp
|
||||
net/download-block.cpp
|
||||
|
357
validator/full-node-master.cpp
Normal file
357
validator/full-node-master.cpp
Normal file
@ -0,0 +1,357 @@
|
||||
/*
|
||||
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 "td/utils/SharedSlice.h"
|
||||
#include "full-node-master.hpp"
|
||||
|
||||
#include "ton/ton-shard.h"
|
||||
#include "ton/ton-tl.hpp"
|
||||
|
||||
#include "adnl/utils.hpp"
|
||||
|
||||
#include "common/delay.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace fullnode {
|
||||
|
||||
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getNextBlockDescription &query,
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
auto P = td::PromiseCreator::lambda([promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
|
||||
if (R.is_error()) {
|
||||
auto x = create_serialize_tl_object<ton_api::tonNode_blockDescriptionEmpty>();
|
||||
promise.set_value(std::move(x));
|
||||
} else {
|
||||
auto B = R.move_as_ok();
|
||||
if (!B->received() || !B->inited_proof()) {
|
||||
auto x = create_serialize_tl_object<ton_api::tonNode_blockDescriptionEmpty>();
|
||||
promise.set_value(std::move(x));
|
||||
} else {
|
||||
auto x = create_serialize_tl_object<ton_api::tonNode_blockDescription>(create_tl_block_id(B->id()));
|
||||
promise.set_value(std::move(x));
|
||||
}
|
||||
}
|
||||
});
|
||||
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_next_block,
|
||||
create_block_id(query.prev_block_), std::move(P));
|
||||
}
|
||||
|
||||
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareBlock &query,
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
auto P = td::PromiseCreator::lambda([promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
|
||||
if (R.is_error()) {
|
||||
auto x = create_serialize_tl_object<ton_api::tonNode_notFound>();
|
||||
promise.set_value(std::move(x));
|
||||
} else {
|
||||
auto B = R.move_as_ok();
|
||||
if (!B->received()) {
|
||||
auto x = create_serialize_tl_object<ton_api::tonNode_notFound>();
|
||||
promise.set_value(std::move(x));
|
||||
} else {
|
||||
auto x = create_serialize_tl_object<ton_api::tonNode_prepared>();
|
||||
promise.set_value(std::move(x));
|
||||
}
|
||||
}
|
||||
});
|
||||
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_block_handle,
|
||||
create_block_id(query.block_), false, std::move(P));
|
||||
}
|
||||
|
||||
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlock &query,
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
auto P = td::PromiseCreator::lambda([validator_manager = validator_manager_,
|
||||
promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
|
||||
if (R.is_error()) {
|
||||
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "unknown block"));
|
||||
} else {
|
||||
auto B = R.move_as_ok();
|
||||
if (!B->received()) {
|
||||
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "unknown block"));
|
||||
} else {
|
||||
td::actor::send_closure(validator_manager, &ValidatorManagerInterface::get_block_data, B, std::move(promise));
|
||||
}
|
||||
}
|
||||
});
|
||||
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_block_handle,
|
||||
create_block_id(query.block_), false, std::move(P));
|
||||
}
|
||||
|
||||
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareBlockProof &query,
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
if (query.block_->seqno_ == 0) {
|
||||
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "cannot download proof for zero state"));
|
||||
return;
|
||||
}
|
||||
auto P = td::PromiseCreator::lambda([allow_partial = query.allow_partial_, promise = std::move(promise),
|
||||
validator_manager = validator_manager_](td::Result<BlockHandle> R) mutable {
|
||||
if (R.is_error()) {
|
||||
auto x = create_serialize_tl_object<ton_api::tonNode_preparedProofEmpty>();
|
||||
promise.set_value(std::move(x));
|
||||
return;
|
||||
} else {
|
||||
auto handle = R.move_as_ok();
|
||||
if (!handle || (!handle->inited_proof() && (!allow_partial || !handle->inited_proof_link()))) {
|
||||
auto x = create_serialize_tl_object<ton_api::tonNode_preparedProofEmpty>();
|
||||
promise.set_value(std::move(x));
|
||||
return;
|
||||
}
|
||||
if (handle->inited_proof() && handle->id().is_masterchain()) {
|
||||
auto x = create_serialize_tl_object<ton_api::tonNode_preparedProof>();
|
||||
promise.set_value(std::move(x));
|
||||
} else {
|
||||
auto x = create_serialize_tl_object<ton_api::tonNode_preparedProofLink>();
|
||||
promise.set_value(std::move(x));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_block_handle,
|
||||
create_block_id(query.block_), false, std::move(P));
|
||||
}
|
||||
|
||||
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlockProof &query,
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
auto P = td::PromiseCreator::lambda(
|
||||
[promise = std::move(promise), validator_manager = validator_manager_](td::Result<BlockHandle> R) mutable {
|
||||
if (R.is_error()) {
|
||||
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "unknown block proof"));
|
||||
return;
|
||||
} else {
|
||||
auto handle = R.move_as_ok();
|
||||
if (!handle || !handle->inited_proof()) {
|
||||
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "unknown block proof"));
|
||||
return;
|
||||
}
|
||||
|
||||
td::actor::send_closure(validator_manager, &ValidatorManagerInterface::get_block_proof, handle,
|
||||
std::move(promise));
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_block_handle,
|
||||
create_block_id(query.block_), false, std::move(P));
|
||||
}
|
||||
|
||||
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlockProofLink &query,
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
auto P = td::PromiseCreator::lambda(
|
||||
[promise = std::move(promise), validator_manager = validator_manager_](td::Result<BlockHandle> R) mutable {
|
||||
if (R.is_error()) {
|
||||
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "unknown block proof"));
|
||||
return;
|
||||
} else {
|
||||
auto handle = R.move_as_ok();
|
||||
if (!handle || !handle->inited_proof_link()) {
|
||||
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "unknown block proof"));
|
||||
return;
|
||||
}
|
||||
|
||||
td::actor::send_closure(validator_manager, &ValidatorManagerInterface::get_block_proof_link, handle,
|
||||
std::move(promise));
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_block_handle,
|
||||
create_block_id(query.block_), false, std::move(P));
|
||||
}
|
||||
|
||||
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareZeroState &query,
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
auto P =
|
||||
td::PromiseCreator::lambda([SelfId = actor_id(this), promise = std::move(promise)](td::Result<bool> R) mutable {
|
||||
if (R.is_error() || !R.move_as_ok()) {
|
||||
auto x = create_serialize_tl_object<ton_api::tonNode_notFoundState>();
|
||||
promise.set_value(std::move(x));
|
||||
return;
|
||||
}
|
||||
|
||||
auto x = create_serialize_tl_object<ton_api::tonNode_preparedState>();
|
||||
promise.set_value(std::move(x));
|
||||
});
|
||||
auto block_id = create_block_id(query.block_);
|
||||
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::check_zero_state_exists, block_id,
|
||||
std::move(P));
|
||||
}
|
||||
|
||||
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_preparePersistentState &query,
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
auto P =
|
||||
td::PromiseCreator::lambda([SelfId = actor_id(this), promise = std::move(promise)](td::Result<bool> R) mutable {
|
||||
if (R.is_error() || !R.move_as_ok()) {
|
||||
auto x = create_serialize_tl_object<ton_api::tonNode_notFoundState>();
|
||||
promise.set_value(std::move(x));
|
||||
return;
|
||||
}
|
||||
|
||||
auto x = create_serialize_tl_object<ton_api::tonNode_preparedState>();
|
||||
promise.set_value(std::move(x));
|
||||
});
|
||||
auto block_id = create_block_id(query.block_);
|
||||
auto masterchain_block_id = create_block_id(query.masterchain_block_);
|
||||
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::check_persistent_state_exists, block_id,
|
||||
masterchain_block_id, std::move(P));
|
||||
}
|
||||
|
||||
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getNextKeyBlockIds &query,
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
auto cnt = static_cast<td::uint32>(query.max_size_);
|
||||
if (cnt > 8) {
|
||||
cnt = 8;
|
||||
}
|
||||
auto P =
|
||||
td::PromiseCreator::lambda([promise = std::move(promise), cnt](td::Result<std::vector<BlockIdExt>> R) mutable {
|
||||
if (R.is_error()) {
|
||||
LOG(WARNING) << "getnextkey: " << R.move_as_error();
|
||||
auto x = create_serialize_tl_object<ton_api::tonNode_keyBlocks>(
|
||||
std::vector<tl_object_ptr<ton_api::tonNode_blockIdExt>>{}, false, true);
|
||||
promise.set_value(std::move(x));
|
||||
return;
|
||||
}
|
||||
auto res = R.move_as_ok();
|
||||
std::vector<tl_object_ptr<ton_api::tonNode_blockIdExt>> v;
|
||||
for (auto &b : res) {
|
||||
v.emplace_back(create_tl_block_id(b));
|
||||
}
|
||||
auto x = create_serialize_tl_object<ton_api::tonNode_keyBlocks>(std::move(v), res.size() < cnt, false);
|
||||
promise.set_value(std::move(x));
|
||||
});
|
||||
auto block_id = create_block_id(query.block_);
|
||||
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_next_key_blocks, block_id, cnt,
|
||||
std::move(P));
|
||||
}
|
||||
|
||||
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadZeroState &query,
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
auto P = td::PromiseCreator::lambda(
|
||||
[SelfId = actor_id(this), promise = std::move(promise)](td::Result<td::BufferSlice> R) mutable {
|
||||
if (R.is_error()) {
|
||||
promise.set_error(R.move_as_error_prefix("failed to get state from db: "));
|
||||
return;
|
||||
}
|
||||
|
||||
promise.set_value(R.move_as_ok());
|
||||
});
|
||||
auto block_id = create_block_id(query.block_);
|
||||
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_zero_state, block_id, std::move(P));
|
||||
}
|
||||
|
||||
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadPersistentState &query,
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
auto P = td::PromiseCreator::lambda(
|
||||
[SelfId = actor_id(this), promise = std::move(promise)](td::Result<td::BufferSlice> R) mutable {
|
||||
if (R.is_error()) {
|
||||
promise.set_error(R.move_as_error_prefix("failed to get state from db: "));
|
||||
return;
|
||||
}
|
||||
|
||||
promise.set_value(R.move_as_ok());
|
||||
});
|
||||
auto block_id = create_block_id(query.block_);
|
||||
auto masterchain_block_id = create_block_id(query.masterchain_block_);
|
||||
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_persistent_state, block_id,
|
||||
masterchain_block_id, std::move(P));
|
||||
}
|
||||
|
||||
void FullNodeMasterImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadPersistentStateSlice &query,
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
auto P = td::PromiseCreator::lambda(
|
||||
[SelfId = actor_id(this), promise = std::move(promise)](td::Result<td::BufferSlice> R) mutable {
|
||||
if (R.is_error()) {
|
||||
promise.set_error(R.move_as_error_prefix("failed to get state from db: "));
|
||||
return;
|
||||
}
|
||||
|
||||
promise.set_value(R.move_as_ok());
|
||||
});
|
||||
auto block_id = create_block_id(query.block_);
|
||||
auto masterchain_block_id = create_block_id(query.masterchain_block_);
|
||||
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_persistent_state_slice, block_id,
|
||||
masterchain_block_id, query.offset_, query.max_size_, std::move(P));
|
||||
}
|
||||
|
||||
void FullNodeMasterImpl::receive_query(adnl::AdnlNodeIdShort src, td::BufferSlice query,
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
auto BX = fetch_tl_prefix<ton_api::tonNode_query>(query, true);
|
||||
if (BX.is_error()) {
|
||||
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "cannot parse tonnode query"));
|
||||
return;
|
||||
}
|
||||
auto B = fetch_tl_object<ton_api::Function>(std::move(query), true);
|
||||
if (B.is_error()) {
|
||||
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "cannot parse tonnode query"));
|
||||
return;
|
||||
}
|
||||
ton_api::downcast_call(*B.move_as_ok().get(), [&](auto &obj) { this->process_query(src, obj, std::move(promise)); });
|
||||
}
|
||||
|
||||
void FullNodeMasterImpl::start_up() {
|
||||
class Cb : public adnl::Adnl::Callback {
|
||||
public:
|
||||
Cb(td::actor::ActorId<FullNodeMasterImpl> id) : id_(std::move(id)) {
|
||||
}
|
||||
void receive_message(adnl::AdnlNodeIdShort src, adnl::AdnlNodeIdShort dst, td::BufferSlice data) override {
|
||||
}
|
||||
void receive_query(adnl::AdnlNodeIdShort src, adnl::AdnlNodeIdShort dst, td::BufferSlice data,
|
||||
td::Promise<td::BufferSlice> promise) override {
|
||||
td::actor::send_closure(id_, &FullNodeMasterImpl::receive_query, src, std::move(data), std::move(promise));
|
||||
}
|
||||
|
||||
private:
|
||||
td::actor::ActorId<FullNodeMasterImpl> id_;
|
||||
};
|
||||
|
||||
td::actor::send_closure(adnl_, &adnl::Adnl::subscribe, adnl_id_,
|
||||
adnl::Adnl::int_to_bytestring(ton_api::tonNode_query::ID),
|
||||
std::make_unique<Cb>(actor_id(this)));
|
||||
|
||||
auto P =
|
||||
td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::actor::ActorOwn<adnl::AdnlExtServer>> R) {
|
||||
R.ensure();
|
||||
R.move_as_ok().release();
|
||||
});
|
||||
td::actor::send_closure(adnl_, &adnl::Adnl::create_ext_server, std::vector<adnl::AdnlNodeIdShort>{adnl_id_},
|
||||
std::vector<td::uint16>{port_}, std::move(P));
|
||||
}
|
||||
|
||||
FullNodeMasterImpl::FullNodeMasterImpl(adnl::AdnlNodeIdShort adnl_id, td::uint16 port, FileHash zero_state_file_hash,
|
||||
td::actor::ActorId<keyring::Keyring> keyring,
|
||||
td::actor::ActorId<adnl::Adnl> adnl,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager)
|
||||
: adnl_id_(adnl_id)
|
||||
, port_(port)
|
||||
, zero_state_file_hash_(zero_state_file_hash)
|
||||
, keyring_(keyring)
|
||||
, adnl_(adnl)
|
||||
, validator_manager_(validator_manager) {
|
||||
}
|
||||
|
||||
td::actor::ActorOwn<FullNodeMaster> FullNodeMaster::create(
|
||||
adnl::AdnlNodeIdShort adnl_id, td::uint16 port, FileHash zero_state_file_hash,
|
||||
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager) {
|
||||
return td::actor::create_actor<FullNodeMasterImpl>("tonnode", adnl_id, port, zero_state_file_hash, keyring, adnl,
|
||||
validator_manager);
|
||||
}
|
||||
|
||||
} // namespace fullnode
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
45
validator/full-node-master.h
Normal file
45
validator/full-node-master.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
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 "full-node.h"
|
||||
#include "validator/interfaces/block-handle.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace fullnode {
|
||||
|
||||
class FullNodeMaster : public td::actor::Actor {
|
||||
public:
|
||||
virtual ~FullNodeMaster() = default;
|
||||
|
||||
static td::actor::ActorOwn<FullNodeMaster> create(adnl::AdnlNodeIdShort adnl_id, td::uint16 port,
|
||||
FileHash zero_state_file_hash,
|
||||
td::actor::ActorId<keyring::Keyring> keyring,
|
||||
td::actor::ActorId<adnl::Adnl> adnl,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager);
|
||||
};
|
||||
|
||||
} // namespace fullnode
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
83
validator/full-node-master.hpp
Normal file
83
validator/full-node-master.hpp
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
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 "full-node-master.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
|
||||
namespace fullnode {
|
||||
|
||||
class FullNodeMasterImpl : public FullNodeMaster {
|
||||
public:
|
||||
void start_up() override;
|
||||
|
||||
template <class T>
|
||||
void process_query(adnl::AdnlNodeIdShort src, T &query, td::Promise<td::BufferSlice> promise) {
|
||||
promise.set_error(td::Status::Error(ErrorCode::error, "unknown query"));
|
||||
}
|
||||
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getNextBlockDescription &query,
|
||||
td::Promise<td::BufferSlice> promise);
|
||||
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareBlockProof &query,
|
||||
td::Promise<td::BufferSlice> promise);
|
||||
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlockProof &query,
|
||||
td::Promise<td::BufferSlice> promise);
|
||||
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlockProofLink &query,
|
||||
td::Promise<td::BufferSlice> promise);
|
||||
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareBlock &query,
|
||||
td::Promise<td::BufferSlice> promise);
|
||||
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadBlock &query,
|
||||
td::Promise<td::BufferSlice> promise);
|
||||
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareZeroState &query,
|
||||
td::Promise<td::BufferSlice> promise);
|
||||
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_preparePersistentState &query,
|
||||
td::Promise<td::BufferSlice> promise);
|
||||
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getNextKeyBlockIds &query,
|
||||
td::Promise<td::BufferSlice> promise);
|
||||
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadZeroState &query,
|
||||
td::Promise<td::BufferSlice> promise);
|
||||
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadPersistentState &query,
|
||||
td::Promise<td::BufferSlice> promise);
|
||||
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_downloadPersistentStateSlice &query,
|
||||
td::Promise<td::BufferSlice> promise);
|
||||
// void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareNextKeyBlockProof &query,
|
||||
// td::Promise<td::BufferSlice> promise);
|
||||
void receive_query(adnl::AdnlNodeIdShort src, td::BufferSlice query, td::Promise<td::BufferSlice> promise);
|
||||
|
||||
FullNodeMasterImpl(adnl::AdnlNodeIdShort adnl_id, td::uint16 port, FileHash zero_state_file_hash,
|
||||
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager);
|
||||
|
||||
private:
|
||||
adnl::AdnlNodeIdShort adnl_id_;
|
||||
td::uint16 port_;
|
||||
FileHash zero_state_file_hash_;
|
||||
|
||||
td::actor::ActorId<keyring::Keyring> keyring_;
|
||||
td::actor::ActorId<adnl::Adnl> adnl_;
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager_;
|
||||
};
|
||||
|
||||
} // namespace fullnode
|
||||
|
||||
} // namespace validator
|
||||
|
||||
} // namespace ton
|
@ -78,7 +78,8 @@ void FullNodeShardImpl::try_get_next_block(td::Timestamp timeout, td::Promise<Re
|
||||
return;
|
||||
}
|
||||
td::actor::create_actor<DownloadNextBlock>("downloadnext", adnl_id_, overlay_id_, handle_, download_next_priority(),
|
||||
timeout, validator_manager_, rldp_, overlays_, adnl_, std::move(promise))
|
||||
timeout, validator_manager_, rldp_, overlays_, adnl_, client_,
|
||||
std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
@ -446,6 +447,10 @@ void FullNodeShardImpl::receive_broadcast(PublicKeyHash src, td::BufferSlice bro
|
||||
}
|
||||
|
||||
void FullNodeShardImpl::send_ihr_message(td::BufferSlice data) {
|
||||
if (!client_.empty()) {
|
||||
UNREACHABLE();
|
||||
return;
|
||||
}
|
||||
auto B = create_serialize_tl_object<ton_api::tonNode_ihrMessageBroadcast>(
|
||||
create_tl_object<ton_api::tonNode_ihrMessage>(std::move(data)));
|
||||
if (B.size() <= overlay::Overlays::max_simple_broadcast_size()) {
|
||||
@ -458,6 +463,18 @@ void FullNodeShardImpl::send_ihr_message(td::BufferSlice data) {
|
||||
}
|
||||
|
||||
void FullNodeShardImpl::send_external_message(td::BufferSlice data) {
|
||||
if (!client_.empty()) {
|
||||
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "send_ext_query",
|
||||
create_serialize_tl_object_suffix<ton_api::tonNode_query>(
|
||||
create_serialize_tl_object<ton_api::tonNode_slave_sendExtMessage>(
|
||||
create_tl_object<ton_api::tonNode_externalMessage>(std::move(data)))),
|
||||
td::Timestamp::in(1.0), [](td::Result<td::BufferSlice> R) {
|
||||
if (R.is_error()) {
|
||||
VLOG(FULL_NODE_WARNING) << "failed to send ext message: " << R.move_as_error();
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
auto B = create_serialize_tl_object<ton_api::tonNode_externalMessageBroadcast>(
|
||||
create_tl_object<ton_api::tonNode_externalMessage>(std::move(data)));
|
||||
if (B.size() <= overlay::Overlays::max_simple_broadcast_size()) {
|
||||
@ -470,6 +487,10 @@ void FullNodeShardImpl::send_external_message(td::BufferSlice data) {
|
||||
}
|
||||
|
||||
void FullNodeShardImpl::send_shard_block_info(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data) {
|
||||
if (!client_.empty()) {
|
||||
UNREACHABLE();
|
||||
return;
|
||||
}
|
||||
auto B = create_serialize_tl_object<ton_api::tonNode_newShardBlockBroadcast>(
|
||||
create_tl_object<ton_api::tonNode_newShardBlock>(create_tl_block_id(block_id), cc_seqno, std::move(data)));
|
||||
if (B.size() <= overlay::Overlays::max_simple_broadcast_size()) {
|
||||
@ -482,6 +503,10 @@ void FullNodeShardImpl::send_shard_block_info(BlockIdExt block_id, CatchainSeqno
|
||||
}
|
||||
|
||||
void FullNodeShardImpl::send_broadcast(BlockBroadcast broadcast) {
|
||||
if (!client_.empty()) {
|
||||
UNREACHABLE();
|
||||
return;
|
||||
}
|
||||
std::vector<tl_object_ptr<ton_api::tonNode_blockSignature>> sigs;
|
||||
for (auto &sig : broadcast.signatures) {
|
||||
sigs.emplace_back(create_tl_object<ton_api::tonNode_blockSignature>(sig.node, sig.signature.clone()));
|
||||
@ -496,7 +521,7 @@ void FullNodeShardImpl::send_broadcast(BlockBroadcast broadcast) {
|
||||
void FullNodeShardImpl::download_block(BlockIdExt id, td::uint32 priority, td::Timestamp timeout,
|
||||
td::Promise<ReceivedBlock> promise) {
|
||||
td::actor::create_actor<DownloadBlock>("downloadreq", id, adnl_id_, overlay_id_, adnl::AdnlNodeIdShort::zero(),
|
||||
priority, timeout, validator_manager_, rldp_, overlays_, adnl_,
|
||||
priority, timeout, validator_manager_, rldp_, overlays_, adnl_, client_,
|
||||
std::move(promise))
|
||||
.release();
|
||||
}
|
||||
@ -505,7 +530,7 @@ void FullNodeShardImpl::download_zero_state(BlockIdExt id, td::uint32 priority,
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
td::actor::create_actor<DownloadState>("downloadstatereq", id, BlockIdExt{}, adnl_id_, overlay_id_,
|
||||
adnl::AdnlNodeIdShort::zero(), priority, timeout, validator_manager_, rldp_,
|
||||
overlays_, adnl_, std::move(promise))
|
||||
overlays_, adnl_, client_, std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
@ -513,7 +538,7 @@ void FullNodeShardImpl::download_persistent_state(BlockIdExt id, BlockIdExt mast
|
||||
td::Timestamp timeout, td::Promise<td::BufferSlice> promise) {
|
||||
td::actor::create_actor<DownloadState>("downloadstatereq", id, masterchain_block_id, adnl_id_, overlay_id_,
|
||||
adnl::AdnlNodeIdShort::zero(), priority, timeout, validator_manager_, rldp_,
|
||||
overlays_, adnl_, std::move(promise))
|
||||
overlays_, adnl_, client_, std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
@ -521,7 +546,7 @@ void FullNodeShardImpl::download_block_proof(BlockIdExt block_id, td::uint32 pri
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
td::actor::create_actor<DownloadProof>("downloadproofreq", block_id, false, adnl_id_, overlay_id_,
|
||||
adnl::AdnlNodeIdShort::zero(), priority, timeout, validator_manager_, rldp_,
|
||||
overlays_, adnl_, std::move(promise))
|
||||
overlays_, adnl_, client_, std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
@ -529,14 +554,15 @@ void FullNodeShardImpl::download_block_proof_link(BlockIdExt block_id, td::uint3
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
td::actor::create_actor<DownloadProof>("downloadproofreq", block_id, true, adnl_id_, overlay_id_,
|
||||
adnl::AdnlNodeIdShort::zero(), priority, timeout, validator_manager_, rldp_,
|
||||
overlays_, adnl_, std::move(promise))
|
||||
overlays_, adnl_, client_, std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
void FullNodeShardImpl::get_next_key_blocks(BlockIdExt block_id, td::Timestamp timeout,
|
||||
td::Promise<std::vector<BlockIdExt>> promise) {
|
||||
td::actor::create_actor<GetNextKeyBlocks>("next", block_id, 16, adnl_id_, overlay_id_, adnl::AdnlNodeIdShort::zero(),
|
||||
1, timeout, validator_manager_, rldp_, overlays_, adnl_, std::move(promise))
|
||||
1, timeout, validator_manager_, rldp_, overlays_, adnl_, client_,
|
||||
std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
@ -570,15 +596,17 @@ void FullNodeShardImpl::alarm() {
|
||||
}
|
||||
|
||||
void FullNodeShardImpl::start_up() {
|
||||
auto X =
|
||||
create_hash_tl_object<ton_api::tonNode_shardPublicOverlayId>(get_workchain(), get_shard(), zero_state_file_hash_);
|
||||
td::BufferSlice b{32};
|
||||
b.as_slice().copy_from(as_slice(X));
|
||||
overlay_id_full_ = overlay::OverlayIdFull{std::move(b)};
|
||||
overlay_id_ = overlay_id_full_.compute_short_id();
|
||||
rules_ = overlay::OverlayPrivacyRules{overlay::Overlays::max_fec_broadcast_size()};
|
||||
if (client_.empty()) {
|
||||
auto X = create_hash_tl_object<ton_api::tonNode_shardPublicOverlayId>(get_workchain(), get_shard(),
|
||||
zero_state_file_hash_);
|
||||
td::BufferSlice b{32};
|
||||
b.as_slice().copy_from(as_slice(X));
|
||||
overlay_id_full_ = overlay::OverlayIdFull{std::move(b)};
|
||||
overlay_id_ = overlay_id_full_.compute_short_id();
|
||||
rules_ = overlay::OverlayPrivacyRules{overlay::Overlays::max_fec_broadcast_size()};
|
||||
|
||||
create_overlay();
|
||||
create_overlay();
|
||||
}
|
||||
}
|
||||
|
||||
void FullNodeShardImpl::sign_new_certificate(PublicKeyHash sign_by) {
|
||||
@ -613,6 +641,9 @@ void FullNodeShardImpl::signed_new_certificate(ton::overlay::Certificate cert) {
|
||||
}
|
||||
|
||||
void FullNodeShardImpl::update_validators(std::vector<PublicKeyHash> public_key_hashes, PublicKeyHash local_hash) {
|
||||
if (!client_.empty()) {
|
||||
return;
|
||||
}
|
||||
bool update_cert = false;
|
||||
if (!local_hash.is_zero() && local_hash != sign_cert_by_) {
|
||||
update_cert = true;
|
||||
@ -638,7 +669,8 @@ FullNodeShardImpl::FullNodeShardImpl(ShardIdFull shard, PublicKeyHash local_id,
|
||||
FileHash zero_state_file_hash, td::actor::ActorId<keyring::Keyring> keyring,
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<rldp::Rldp> rldp,
|
||||
td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager)
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client)
|
||||
: shard_(shard)
|
||||
, local_id_(local_id)
|
||||
, adnl_id_(adnl_id)
|
||||
@ -647,16 +679,17 @@ FullNodeShardImpl::FullNodeShardImpl(ShardIdFull shard, PublicKeyHash local_id,
|
||||
, adnl_(adnl)
|
||||
, rldp_(rldp)
|
||||
, overlays_(overlays)
|
||||
, validator_manager_(validator_manager) {
|
||||
, validator_manager_(validator_manager)
|
||||
, client_(client) {
|
||||
}
|
||||
|
||||
td::actor::ActorOwn<FullNodeShard> FullNodeShard::create(
|
||||
ShardIdFull shard, PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash,
|
||||
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
|
||||
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager) {
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager, td::actor::ActorId<adnl::AdnlExtClient> client) {
|
||||
return td::actor::create_actor<FullNodeShardImpl>("tonnode", shard, local_id, adnl_id, zero_state_file_hash, keyring,
|
||||
adnl, rldp, overlays, validator_manager);
|
||||
adnl, rldp, overlays, validator_manager, client);
|
||||
}
|
||||
|
||||
} // namespace fullnode
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "full-node.h"
|
||||
#include "validator/interfaces/block-handle.h"
|
||||
#include "adnl/adnl-ext-client.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
@ -59,13 +60,11 @@ class FullNodeShard : public td::actor::Actor {
|
||||
|
||||
virtual void update_validators(std::vector<PublicKeyHash> public_key_hashes, PublicKeyHash local_hash) = 0;
|
||||
|
||||
static td::actor::ActorOwn<FullNodeShard> create(ShardIdFull shard, PublicKeyHash local_id,
|
||||
adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash,
|
||||
td::actor::ActorId<keyring::Keyring> keyring,
|
||||
td::actor::ActorId<adnl::Adnl> adnl,
|
||||
td::actor::ActorId<rldp::Rldp> rldp,
|
||||
td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager);
|
||||
static td::actor::ActorOwn<FullNodeShard> create(
|
||||
ShardIdFull shard, PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash,
|
||||
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
|
||||
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager, td::actor::ActorId<adnl::AdnlExtClient> client);
|
||||
};
|
||||
|
||||
} // namespace fullnode
|
||||
|
@ -54,7 +54,7 @@ class FullNodeShardImpl : public FullNodeShard {
|
||||
|
||||
template <class T>
|
||||
void process_query(adnl::AdnlNodeIdShort src, T &query, td::Promise<td::BufferSlice> promise) {
|
||||
UNREACHABLE();
|
||||
promise.set_error(td::Status::Error(ErrorCode::error, "unknown query"));
|
||||
}
|
||||
void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getNextBlockDescription &query,
|
||||
td::Promise<td::BufferSlice> promise);
|
||||
@ -122,7 +122,8 @@ class FullNodeShardImpl : public FullNodeShard {
|
||||
FileHash zero_state_file_hash, td::actor::ActorId<keyring::Keyring> keyring,
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<rldp::Rldp> rldp,
|
||||
td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager);
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client);
|
||||
|
||||
private:
|
||||
ShardIdFull shard_;
|
||||
@ -138,6 +139,7 @@ class FullNodeShardImpl : public FullNodeShard {
|
||||
td::actor::ActorId<rldp::Rldp> rldp_;
|
||||
td::actor::ActorId<overlay::Overlays> overlays_;
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager_;
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client_;
|
||||
|
||||
td::uint32 attempt_ = 0;
|
||||
|
||||
|
@ -103,7 +103,7 @@ void FullNodeImpl::add_shard(ShardIdFull shard) {
|
||||
while (true) {
|
||||
if (shards_.count(shard) == 0) {
|
||||
shards_.emplace(shard, FullNodeShard::create(shard, local_id_, adnl_id_, zero_state_file_hash_, keyring_, adnl_,
|
||||
rldp_, overlays_, validator_manager_));
|
||||
rldp_, overlays_, validator_manager_, client_));
|
||||
if (all_validators_.size() > 0) {
|
||||
td::actor::send_closure(shards_[shard], &FullNodeShard::update_validators, all_validators_, sign_cert_by_);
|
||||
}
|
||||
@ -413,7 +413,8 @@ FullNodeImpl::FullNodeImpl(PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id
|
||||
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
|
||||
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<dht::Dht> dht,
|
||||
td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager, std::string db_root)
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client, std::string db_root)
|
||||
: local_id_(local_id)
|
||||
, adnl_id_(adnl_id)
|
||||
, zero_state_file_hash_(zero_state_file_hash)
|
||||
@ -423,6 +424,7 @@ FullNodeImpl::FullNodeImpl(PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id
|
||||
, dht_(dht)
|
||||
, overlays_(overlays)
|
||||
, validator_manager_(validator_manager)
|
||||
, client_(client)
|
||||
, db_root_(db_root) {
|
||||
add_shard(ShardIdFull{masterchainId});
|
||||
}
|
||||
@ -434,9 +436,9 @@ td::actor::ActorOwn<FullNode> FullNode::create(ton::PublicKeyHash local_id, adnl
|
||||
td::actor::ActorId<dht::Dht> dht,
|
||||
td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||
std::string db_root) {
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client, std::string db_root) {
|
||||
return td::actor::create_actor<FullNodeImpl>("fullnode", local_id, adnl_id, zero_state_file_hash, keyring, adnl, rldp,
|
||||
dht, overlays, validator_manager, db_root);
|
||||
dht, overlays, validator_manager, client, db_root);
|
||||
}
|
||||
|
||||
} // namespace fullnode
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "dht/dht.h"
|
||||
#include "overlay/overlays.h"
|
||||
#include "validator/validator.h"
|
||||
#include "adnl/adnl-ext-client.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
@ -71,7 +72,7 @@ class FullNode : public td::actor::Actor {
|
||||
td::actor::ActorId<dht::Dht> dht,
|
||||
td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||
std::string db_root);
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client, std::string db_root);
|
||||
};
|
||||
|
||||
} // namespace fullnode
|
||||
|
@ -75,7 +75,8 @@ class FullNodeImpl : public FullNode {
|
||||
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
|
||||
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<dht::Dht> dht,
|
||||
td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager, std::string db_root);
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client, std::string db_root);
|
||||
|
||||
private:
|
||||
PublicKeyHash local_id_;
|
||||
@ -93,6 +94,7 @@ class FullNodeImpl : public FullNode {
|
||||
td::actor::ActorId<dht::Dht> dht_;
|
||||
td::actor::ActorId<overlay::Overlays> overlays_;
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager_;
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client_;
|
||||
|
||||
std::string db_root_;
|
||||
|
||||
|
@ -74,10 +74,6 @@ void Collator::start_up() {
|
||||
if (prev_blocks.size() > 1) {
|
||||
LOG(DEBUG) << "Previous block #2 is " << prev_blocks.at(1).to_str();
|
||||
}
|
||||
//if (created_by_.is_zero()) {
|
||||
// !!FIXME!! remove this debug later
|
||||
//td::as<td::uint32>(created_by_.data() + 32 - 4) = ((unsigned)std::time(nullptr) >> 8);
|
||||
//}
|
||||
// 1. check validity of parameters, especially prev_blocks, shard and min_mc_block_id
|
||||
if (shard.workchain != ton::masterchainId && shard.workchain != ton::basechainId) {
|
||||
fatal_error(-667, "can create block candidates only for masterchain (-1) and base workchain (0)");
|
||||
@ -180,7 +176,7 @@ void Collator::start_up() {
|
||||
LOG(DEBUG) << "sending wait_block_state() query #" << i << " for " << prev_blocks[i].to_str() << " to Manager";
|
||||
++pending;
|
||||
td::actor::send_closure_later(manager, &ValidatorManager::wait_block_state_short, prev_blocks[i], priority(),
|
||||
timeout, [self = get_self(), i](td::Result<Ref<ShardState>> res) {
|
||||
timeout, [ self = get_self(), i ](td::Result<Ref<ShardState>> res) {
|
||||
LOG(DEBUG) << "got answer to wait_block_state query #" << i;
|
||||
td::actor::send_closure_later(std::move(self), &Collator::after_get_shard_state, i,
|
||||
std::move(res));
|
||||
@ -191,7 +187,7 @@ void Collator::start_up() {
|
||||
LOG(DEBUG) << "sending wait_block_data() query #" << i << " for " << prev_blocks[i].to_str() << " to Manager";
|
||||
++pending;
|
||||
td::actor::send_closure_later(manager, &ValidatorManager::wait_block_data_short, prev_blocks[i], priority(),
|
||||
timeout, [self = get_self(), i](td::Result<Ref<BlockData>> res) {
|
||||
timeout, [ self = get_self(), i ](td::Result<Ref<BlockData>> res) {
|
||||
LOG(DEBUG) << "got answer to wait_block_data query #" << i;
|
||||
td::actor::send_closure_later(std::move(self), &Collator::after_get_block_data, i,
|
||||
std::move(res));
|
||||
@ -201,8 +197,8 @@ void Collator::start_up() {
|
||||
// 4. load external messages
|
||||
LOG(DEBUG) << "sending get_external_messages() query to Manager";
|
||||
++pending;
|
||||
td::actor::send_closure_later(manager, &ValidatorManager::get_external_messages, shard,
|
||||
[self = get_self()](td::Result<std::vector<Ref<ExtMessage>>> res) -> void {
|
||||
td::actor::send_closure_later(manager, &ValidatorManager::get_external_messages,
|
||||
shard, [self = get_self()](td::Result<std::vector<Ref<ExtMessage>>> res)->void {
|
||||
LOG(DEBUG) << "got answer to get_external_messages() query";
|
||||
td::actor::send_closure_later(std::move(self), &Collator::after_get_external_messages,
|
||||
std::move(res));
|
||||
@ -212,8 +208,8 @@ void Collator::start_up() {
|
||||
LOG(DEBUG) << "sending get_shard_blocks() query to Manager";
|
||||
++pending;
|
||||
td::actor::send_closure_later(
|
||||
manager, &ValidatorManager::get_shard_blocks, prev_blocks[0],
|
||||
[self = get_self()](td::Result<std::vector<Ref<ShardTopBlockDescription>>> res) -> void {
|
||||
manager, &ValidatorManager::get_shard_blocks,
|
||||
prev_blocks[0], [self = get_self()](td::Result<std::vector<Ref<ShardTopBlockDescription>>> res)->void {
|
||||
LOG(DEBUG) << "got answer to get_shard_blocks() query";
|
||||
td::actor::send_closure_later(std::move(self), &Collator::after_get_shard_blocks, std::move(res));
|
||||
});
|
||||
@ -330,7 +326,7 @@ bool Collator::request_aux_mc_state(BlockSeqno seqno, Ref<MasterchainStateQ>& st
|
||||
LOG(DEBUG) << "sending auxiliary wait_block_state() query for " << blkid.to_str() << " to Manager";
|
||||
++pending;
|
||||
td::actor::send_closure_later(manager, &ValidatorManager::wait_block_state_short, blkid, priority(), timeout,
|
||||
[self = get_self(), blkid](td::Result<Ref<ShardState>> res) {
|
||||
[ self = get_self(), blkid ](td::Result<Ref<ShardState>> res) {
|
||||
LOG(DEBUG) << "got answer to wait_block_state query for " << blkid.to_str();
|
||||
td::actor::send_closure_later(std::move(self), &Collator::after_get_aux_shard_state,
|
||||
blkid, std::move(res));
|
||||
@ -418,8 +414,8 @@ void Collator::after_get_mc_state(td::Result<std::pair<Ref<MasterchainState>, Bl
|
||||
// NB. it is needed only for creating a correct ExtBlkRef reference to it, which requires start_lt and end_lt
|
||||
LOG(DEBUG) << "sending wait_block_data() query #-1 for " << mc_block_id_.to_str() << " to Manager";
|
||||
++pending;
|
||||
td::actor::send_closure_later(manager, &ValidatorManager::wait_block_data_short, mc_block_id_, priority(), timeout,
|
||||
[self = get_self()](td::Result<Ref<BlockData>> res) {
|
||||
td::actor::send_closure_later(manager, &ValidatorManager::wait_block_data_short, mc_block_id_, priority(),
|
||||
timeout, [self = get_self()](td::Result<Ref<BlockData>> res) {
|
||||
LOG(DEBUG) << "got answer to wait_block_data query #-1";
|
||||
td::actor::send_closure_later(std::move(self), &Collator::after_get_block_data, -1,
|
||||
std::move(res));
|
||||
@ -558,7 +554,7 @@ bool Collator::request_neighbor_msg_queues() {
|
||||
LOG(DEBUG) << "neighbor #" << i << " : " << descr.blk_.to_str();
|
||||
++pending;
|
||||
send_closure_later(manager, &ValidatorManager::wait_block_message_queue_short, descr.blk_, priority(), timeout,
|
||||
[self = get_self(), i](td::Result<Ref<MessageQueue>> res) {
|
||||
[ self = get_self(), i ](td::Result<Ref<MessageQueue>> res) {
|
||||
td::actor::send_closure(std::move(self), &Collator::got_neighbor_out_queue, i, std::move(res));
|
||||
});
|
||||
++i;
|
||||
@ -2936,24 +2932,24 @@ bool Collator::update_shard_config(const block::WorkchainSet& wc_set, const bloc
|
||||
WorkchainId wc_id{ton::workchainInvalid};
|
||||
Ref<block::WorkchainInfo> wc_info;
|
||||
ton::BlockSeqno& min_seqno = min_ref_mc_seqno_;
|
||||
return shard_conf_->process_sibling_shard_hashes(
|
||||
[&wc_set, &wc_id, &wc_info, &ccvc, &min_seqno, now = now_, update_cc](block::McShardHash& cur,
|
||||
const block::McShardHash* sibling) {
|
||||
if (!cur.is_valid()) {
|
||||
return -2;
|
||||
}
|
||||
if (wc_id != cur.workchain()) {
|
||||
wc_id = cur.workchain();
|
||||
auto it = wc_set.find(wc_id);
|
||||
if (it == wc_set.end()) {
|
||||
wc_info.clear();
|
||||
} else {
|
||||
wc_info = it->second;
|
||||
}
|
||||
}
|
||||
min_seqno = std::min(min_seqno, cur.min_ref_mc_seqno_);
|
||||
return update_one_shard(cur, sibling, wc_info.get(), now, ccvc, update_cc);
|
||||
});
|
||||
return shard_conf_->process_sibling_shard_hashes([
|
||||
&wc_set, &wc_id, &wc_info, &ccvc, &min_seqno, now = now_, update_cc
|
||||
](block::McShardHash & cur, const block::McShardHash* sibling) {
|
||||
if (!cur.is_valid()) {
|
||||
return -2;
|
||||
}
|
||||
if (wc_id != cur.workchain()) {
|
||||
wc_id = cur.workchain();
|
||||
auto it = wc_set.find(wc_id);
|
||||
if (it == wc_set.end()) {
|
||||
wc_info.clear();
|
||||
} else {
|
||||
wc_info = it->second;
|
||||
}
|
||||
}
|
||||
min_seqno = std::min(min_seqno, cur.min_ref_mc_seqno_);
|
||||
return update_one_shard(cur, sibling, wc_info.get(), now, ccvc, update_cc);
|
||||
});
|
||||
}
|
||||
|
||||
bool Collator::create_mc_state_extra() {
|
||||
@ -3198,10 +3194,10 @@ bool Collator::update_block_creator_stats() {
|
||||
return fatal_error("cannot update CreatorStats for "s + p.first.to_hex());
|
||||
}
|
||||
}
|
||||
if (/*!created_by_.is_zero() &&*/ !update_block_creator_count(created_by_.as_bits256().bits(), 0, 1)) {
|
||||
if (!created_by_.is_zero() && !update_block_creator_count(created_by_.as_bits256().bits(), 0, 1)) {
|
||||
return fatal_error("cannot update CreatorStats for "s + created_by_.as_bits256().to_hex());
|
||||
}
|
||||
if (!update_block_creator_count(td::Bits256::zero().bits(), block_create_total_, 1)) {
|
||||
if (!update_block_creator_count(td::Bits256::zero().bits(), block_create_total_, !created_by_.is_zero())) {
|
||||
return fatal_error("cannot update CreatorStats with zero index (representing the sum of other CreatorStats)");
|
||||
}
|
||||
int cnt = block_create_stats_->filter([this](vm::CellSlice& cs, td::ConstBitPtr key, int key_len) {
|
||||
@ -3766,7 +3762,7 @@ bool Collator::create_block_candidate() {
|
||||
// 4. save block candidate
|
||||
LOG(INFO) << "saving new BlockCandidate";
|
||||
td::actor::send_closure_later(manager, &ValidatorManager::set_block_candidate, block_candidate->id,
|
||||
block_candidate->clone(), [self = get_self()](td::Result<td::Unit> saved) -> void {
|
||||
block_candidate->clone(), [self = get_self()](td::Result<td::Unit> saved)->void {
|
||||
LOG(DEBUG) << "got answer to set_block_candidate";
|
||||
td::actor::send_closure_later(std::move(self), &Collator::return_block_candidate,
|
||||
std::move(saved));
|
||||
|
@ -151,12 +151,7 @@ void ValidateQuery::start_up() {
|
||||
LOG(INFO) << "validate query for " << block_candidate.id.to_str() << " started";
|
||||
alarm_timestamp() = timeout;
|
||||
rand_seed_.set_zero();
|
||||
|
||||
created_by_ = block_candidate.pubkey;
|
||||
if (created_by_.is_zero()) {
|
||||
// !!FIXME!! remove this debug later
|
||||
td::as<td::uint32>(created_by_.data() + 32 - 4) = ((unsigned)std::time(nullptr) >> 8);
|
||||
}
|
||||
|
||||
CHECK(id_ == block_candidate.id);
|
||||
if (ShardIdFull(id_) != shard_) {
|
||||
@ -5179,7 +5174,7 @@ bool ValidateQuery::check_one_block_creator_update(td::ConstBitPtr key, Ref<vm::
|
||||
unsigned mc_incr = (created_by_ == key);
|
||||
unsigned shard_incr = 0;
|
||||
if (key.is_zero(256)) {
|
||||
mc_incr = 1;
|
||||
mc_incr = !created_by_.is_zero();
|
||||
shard_incr = block_create_total_;
|
||||
} else {
|
||||
auto it = block_create_count_.find(td::Bits256{key});
|
||||
|
@ -96,7 +96,7 @@ void ValidatorManagerMasterchainReiniter::downloaded_proof_link(td::BufferSlice
|
||||
LOG(WARNING) << "downloaded proof link failed: " << R.move_as_error();
|
||||
td::actor::send_closure(SelfId, &ValidatorManagerMasterchainReiniter::download_proof_link);
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &ValidatorManagerMasterchainReiniter::try_download_key_blocks);
|
||||
td::actor::send_closure(SelfId, &ValidatorManagerMasterchainReiniter::try_download_key_blocks, false);
|
||||
}
|
||||
});
|
||||
|
||||
@ -104,10 +104,10 @@ void ValidatorManagerMasterchainReiniter::downloaded_proof_link(td::BufferSlice
|
||||
}
|
||||
|
||||
void ValidatorManagerMasterchainReiniter::downloaded_zero_state() {
|
||||
try_download_key_blocks();
|
||||
try_download_key_blocks(false);
|
||||
}
|
||||
|
||||
void ValidatorManagerMasterchainReiniter::try_download_key_blocks() {
|
||||
void ValidatorManagerMasterchainReiniter::try_download_key_blocks(bool try_start) {
|
||||
if (!download_new_key_blocks_until_) {
|
||||
if (opts_->allow_blockchain_init()) {
|
||||
download_new_key_blocks_until_ = td::Timestamp::in(60.0);
|
||||
@ -115,15 +115,18 @@ void ValidatorManagerMasterchainReiniter::try_download_key_blocks() {
|
||||
download_new_key_blocks_until_ = td::Timestamp::in(600.0);
|
||||
}
|
||||
}
|
||||
if (key_blocks_.size() > 0) {
|
||||
if (key_blocks_.size() > 0 && try_start) {
|
||||
auto h = *key_blocks_.rbegin();
|
||||
CHECK(h->inited_unix_time());
|
||||
if (h->unix_time() + opts_->sync_blocks_before() > td::Clocks::system()) {
|
||||
choose_masterchain_state();
|
||||
return;
|
||||
}
|
||||
if ((opts_->allow_blockchain_init() || h->unix_time() + 2 * 86400 > td::Clocks::system()) &&
|
||||
download_new_key_blocks_until_.is_in_past()) {
|
||||
if (h->unix_time() + 2 * opts_->key_block_utime_step() > td::Clocks::system()) {
|
||||
choose_masterchain_state();
|
||||
return;
|
||||
}
|
||||
if (opts_->allow_blockchain_init() && download_new_key_blocks_until_.is_in_past()) {
|
||||
choose_masterchain_state();
|
||||
return;
|
||||
}
|
||||
@ -146,7 +149,7 @@ void ValidatorManagerMasterchainReiniter::got_next_key_blocks(std::vector<BlockI
|
||||
if (!vec.size()) {
|
||||
delay_action(
|
||||
[SelfId = actor_id(this)]() {
|
||||
td::actor::send_closure(SelfId, &ValidatorManagerMasterchainReiniter::try_download_key_blocks);
|
||||
td::actor::send_closure(SelfId, &ValidatorManagerMasterchainReiniter::try_download_key_blocks, true);
|
||||
},
|
||||
td::Timestamp::in(1.0));
|
||||
return;
|
||||
@ -181,7 +184,7 @@ void ValidatorManagerMasterchainReiniter::got_key_block_handle(td::uint32 idx, B
|
||||
key_blocks_[idx] = std::move(handle);
|
||||
CHECK(pending_ > 0);
|
||||
if (!--pending_) {
|
||||
try_download_key_blocks();
|
||||
try_download_key_blocks(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ class ValidatorManagerMasterchainReiniter : public td::actor::Actor {
|
||||
void downloaded_proof_link(td::BufferSlice data);
|
||||
void downloaded_zero_state();
|
||||
|
||||
void try_download_key_blocks();
|
||||
void try_download_key_blocks(bool try_start);
|
||||
void got_next_key_blocks(std::vector<BlockIdExt> vec);
|
||||
void got_key_block_handle(td::uint32 idx, BlockHandle handle);
|
||||
|
||||
|
@ -34,7 +34,8 @@ DownloadBlock::DownloadBlock(BlockIdExt block_id, adnl::AdnlNodeIdShort local_id
|
||||
adnl::AdnlNodeIdShort download_from, td::uint32 priority, td::Timestamp timeout,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<ReceivedBlock> promise)
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::AdnlExtClient> client,
|
||||
td::Promise<ReceivedBlock> promise)
|
||||
: block_id_(block_id)
|
||||
, local_id_(local_id)
|
||||
, overlay_id_(overlay_id)
|
||||
@ -45,6 +46,7 @@ DownloadBlock::DownloadBlock(BlockIdExt block_id, adnl::AdnlNodeIdShort local_id
|
||||
, rldp_(rldp)
|
||||
, overlays_(overlays)
|
||||
, adnl_(adnl)
|
||||
, client_(client)
|
||||
, promise_(std::move(promise))
|
||||
, block_{block_id, td::BufferSlice()}
|
||||
, allow_partial_proof_{!block_id_.is_masterchain()} {
|
||||
@ -54,7 +56,8 @@ DownloadBlock::DownloadBlock(BlockIdExt block_id, adnl::AdnlNodeIdShort local_id
|
||||
BlockHandle prev, adnl::AdnlNodeIdShort download_from, td::uint32 priority,
|
||||
td::Timestamp timeout, td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<ReceivedBlock> promise)
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::AdnlExtClient> client,
|
||||
td::Promise<ReceivedBlock> promise)
|
||||
: block_id_(block_id)
|
||||
, local_id_(local_id)
|
||||
, overlay_id_(overlay_id)
|
||||
@ -66,6 +69,7 @@ DownloadBlock::DownloadBlock(BlockIdExt block_id, adnl::AdnlNodeIdShort local_id
|
||||
, rldp_(rldp)
|
||||
, overlays_(overlays)
|
||||
, adnl_(adnl)
|
||||
, client_(client)
|
||||
, promise_(std::move(promise))
|
||||
, block_{block_id, td::BufferSlice()} {
|
||||
}
|
||||
@ -139,7 +143,7 @@ void DownloadBlock::got_block_handle(BlockHandle handle) {
|
||||
void DownloadBlock::got_download_token(std::unique_ptr<DownloadToken> token) {
|
||||
token_ = std::move(token);
|
||||
|
||||
if (download_from_.is_zero() && !short_) {
|
||||
if (download_from_.is_zero() && !short_ && client_.empty()) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<std::vector<adnl::AdnlNodeIdShort>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &DownloadBlock::abort_query, R.move_as_error());
|
||||
@ -179,10 +183,16 @@ void DownloadBlock::got_node_to_download(adnl::AdnlNodeIdShort node) {
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
|
||||
"get_prepare", std::move(P), td::Timestamp::in(1.0),
|
||||
create_serialize_tl_object<ton_api::tonNode_prepareBlockProof>(create_tl_block_id(block_id_),
|
||||
allow_partial_proof_));
|
||||
auto q = create_serialize_tl_object<ton_api::tonNode_prepareBlockProof>(create_tl_block_id(block_id_),
|
||||
allow_partial_proof_);
|
||||
if (client_.empty()) {
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
|
||||
"get_prepare", std::move(P), td::Timestamp::in(1.0), std::move(q));
|
||||
} else {
|
||||
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_prepare",
|
||||
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(q)),
|
||||
td::Timestamp::in(1.0), std::move(P));
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadBlock::got_block_proof_description(td::BufferSlice proof_description) {
|
||||
@ -207,11 +217,16 @@ void DownloadBlock::got_block_proof_description(td::BufferSlice proof_descriptio
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(
|
||||
overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_, overlay_id_,
|
||||
"download block proof", std::move(P), td::Timestamp::in(3.0),
|
||||
create_serialize_tl_object<ton_api::tonNode_downloadBlockProof>(create_tl_block_id(block_id_)),
|
||||
FullNode::max_proof_size(), rldp_);
|
||||
auto q = create_serialize_tl_object<ton_api::tonNode_downloadBlockProof>(create_tl_block_id(block_id_));
|
||||
if (client_.empty()) {
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_,
|
||||
overlay_id_, "get_proof", std::move(P), td::Timestamp::in(3.0), std::move(q),
|
||||
FullNode::max_proof_size(), rldp_);
|
||||
} else {
|
||||
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_proof",
|
||||
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(q)),
|
||||
td::Timestamp::in(3.0), std::move(P));
|
||||
}
|
||||
},
|
||||
[&](ton_api::tonNode_preparedProofLink &obj) {
|
||||
if (!allow_partial_proof_) {
|
||||
@ -226,11 +241,16 @@ void DownloadBlock::got_block_proof_description(td::BufferSlice proof_descriptio
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(
|
||||
overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_, overlay_id_,
|
||||
"download block proof link", std::move(P), td::Timestamp::in(3.0),
|
||||
create_serialize_tl_object<ton_api::tonNode_downloadBlockProofLink>(create_tl_block_id(block_id_)),
|
||||
FullNode::max_proof_size(), rldp_);
|
||||
auto q = create_serialize_tl_object<ton_api::tonNode_downloadBlockProofLink>(create_tl_block_id(block_id_));
|
||||
if (client_.empty()) {
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_,
|
||||
overlay_id_, "get_proof_link", std::move(P), td::Timestamp::in(3.0), std::move(q),
|
||||
FullNode::max_proof_size(), rldp_);
|
||||
} else {
|
||||
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_proof_link",
|
||||
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(q)),
|
||||
td::Timestamp::in(3.0), std::move(P));
|
||||
}
|
||||
},
|
||||
[&](ton_api::tonNode_preparedProofEmpty &obj) {
|
||||
abort_query(td::Status::Error(ErrorCode::notready, "proof not found"));
|
||||
@ -317,9 +337,15 @@ void DownloadBlock::got_block_handle_2(BlockHandle handle) {
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
|
||||
"get_prepare", std::move(P), td::Timestamp::in(1.0),
|
||||
create_serialize_tl_object<ton_api::tonNode_prepareBlock>(create_tl_block_id(block_id_)));
|
||||
auto q = create_serialize_tl_object<ton_api::tonNode_prepareBlock>(create_tl_block_id(block_id_));
|
||||
if (client_.empty()) {
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
|
||||
"get_prepare_block", std::move(P), td::Timestamp::in(1.0), std::move(q));
|
||||
} else {
|
||||
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_prepare_block",
|
||||
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(q)),
|
||||
td::Timestamp::in(1.0), std::move(P));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -333,25 +359,31 @@ void DownloadBlock::got_block_data_description(td::BufferSlice data_description)
|
||||
auto f = F.move_as_ok();
|
||||
|
||||
ton_api::downcast_call(
|
||||
*f.get(), td::overloaded(
|
||||
[&, self = this](ton_api::tonNode_prepared &val) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(self)](td::Result<td::BufferSlice> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &DownloadBlock::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &DownloadBlock::got_block_data, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
*f.get(),
|
||||
td::overloaded(
|
||||
[&, self = this](ton_api::tonNode_prepared &val) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(self)](td::Result<td::BufferSlice> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &DownloadBlock::abort_query, R.move_as_error());
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &DownloadBlock::got_block_data, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(
|
||||
overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_, overlay_id_,
|
||||
"download block", std::move(P), td::Timestamp::in(3.0),
|
||||
create_serialize_tl_object<ton_api::tonNode_downloadBlock>(create_tl_block_id(block_id_)),
|
||||
FullNode::max_block_size(), rldp_);
|
||||
},
|
||||
[&](ton_api::tonNode_notFound &val) {
|
||||
abort_query(td::Status::Error(ErrorCode::notready, "dst node does not have block"));
|
||||
}));
|
||||
auto q = create_serialize_tl_object<ton_api::tonNode_downloadBlock>(create_tl_block_id(block_id_));
|
||||
if (client_.empty()) {
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_,
|
||||
overlay_id_, "get_block", std::move(P), td::Timestamp::in(3.0), std::move(q),
|
||||
FullNode::max_block_size(), rldp_);
|
||||
} else {
|
||||
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_block",
|
||||
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(q)),
|
||||
td::Timestamp::in(3.0), std::move(P));
|
||||
}
|
||||
},
|
||||
[&](ton_api::tonNode_notFound &val) {
|
||||
abort_query(td::Status::Error(ErrorCode::notready, "dst node does not have block"));
|
||||
}));
|
||||
}
|
||||
|
||||
void DownloadBlock::got_block_data(td::BufferSlice data) {
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "ton/ton-types.h"
|
||||
#include "validator/validator.h"
|
||||
#include "rldp/rldp.h"
|
||||
#include "adnl/adnl-ext-client.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
@ -35,12 +36,12 @@ class DownloadBlock : public td::actor::Actor {
|
||||
adnl::AdnlNodeIdShort download_from, td::uint32 priority, td::Timestamp timeout,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager, td::actor::ActorId<rldp::Rldp> rldp,
|
||||
td::actor::ActorId<overlay::Overlays> overlays, td::actor::ActorId<adnl::Adnl> adnl,
|
||||
td::Promise<ReceivedBlock> promise);
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client, td::Promise<ReceivedBlock> promise);
|
||||
DownloadBlock(BlockIdExt block_id, adnl::AdnlNodeIdShort local_id, overlay::OverlayIdShort overlay_id,
|
||||
BlockHandle prev, adnl::AdnlNodeIdShort download_from, td::uint32 priority, td::Timestamp timeout,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager, td::actor::ActorId<rldp::Rldp> rldp,
|
||||
td::actor::ActorId<overlay::Overlays> overlays, td::actor::ActorId<adnl::Adnl> adnl,
|
||||
td::Promise<ReceivedBlock> promise);
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client, td::Promise<ReceivedBlock> promise);
|
||||
|
||||
void abort_query(td::Status reason);
|
||||
void alarm() override;
|
||||
@ -75,6 +76,7 @@ class DownloadBlock : public td::actor::Actor {
|
||||
td::actor::ActorId<rldp::Rldp> rldp_;
|
||||
td::actor::ActorId<overlay::Overlays> overlays_;
|
||||
td::actor::ActorId<adnl::Adnl> adnl_;
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client_;
|
||||
td::Promise<ReceivedBlock> promise_;
|
||||
|
||||
BlockHandle handle_;
|
||||
|
@ -33,7 +33,8 @@ DownloadNextBlock::DownloadNextBlock(adnl::AdnlNodeIdShort local_id, overlay::Ov
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||
td::actor::ActorId<rldp::Rldp> rldp,
|
||||
td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<ReceivedBlock> promise)
|
||||
td::actor::ActorId<adnl::Adnl> adnl,
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client, td::Promise<ReceivedBlock> promise)
|
||||
: local_id_(local_id)
|
||||
, overlay_id_(overlay_id)
|
||||
, prev_(prev)
|
||||
@ -43,6 +44,7 @@ DownloadNextBlock::DownloadNextBlock(adnl::AdnlNodeIdShort local_id, overlay::Ov
|
||||
, rldp_(rldp)
|
||||
, overlays_(overlays)
|
||||
, adnl_(adnl)
|
||||
, client_(client)
|
||||
, promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
@ -76,6 +78,10 @@ void DownloadNextBlock::start_up() {
|
||||
false, std::move(P));
|
||||
return;
|
||||
}
|
||||
if (!client_.empty()) {
|
||||
got_node(node_);
|
||||
return;
|
||||
}
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<std::vector<adnl::AdnlNodeIdShort>> R) {
|
||||
if (R.is_error()) {
|
||||
@ -107,8 +113,14 @@ void DownloadNextBlock::got_node(adnl::AdnlNodeIdShort id) {
|
||||
});
|
||||
|
||||
auto query = create_serialize_tl_object<ton_api::tonNode_getNextBlockDescription>(create_tl_block_id(prev_->id()));
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, id, local_id_, overlay_id_, "get_prepare",
|
||||
std::move(P), td::Timestamp::in(1.0), std::move(query));
|
||||
if (client_.empty()) {
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, id, local_id_, overlay_id_, "get_prepare",
|
||||
std::move(P), td::Timestamp::in(1.0), std::move(query));
|
||||
} else {
|
||||
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_prepare",
|
||||
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(query)),
|
||||
td::Timestamp::in(1.0), std::move(P));
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadNextBlock::got_next_node(td::BufferSlice data) {
|
||||
@ -138,7 +150,7 @@ void DownloadNextBlock::got_next_node_handle(BlockHandle handle) {
|
||||
void DownloadNextBlock::finish_query() {
|
||||
if (promise_) {
|
||||
td::actor::create_actor<DownloadBlock>("downloadnext", next_block_id_, local_id_, overlay_id_, prev_, node_,
|
||||
priority_, timeout_, validator_manager_, rldp_, overlays_, adnl_,
|
||||
priority_, timeout_, validator_manager_, rldp_, overlays_, adnl_, client_,
|
||||
std::move(promise_))
|
||||
.release();
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "validator/validator.h"
|
||||
#include "rldp/rldp.h"
|
||||
#include "ton/ton-io.hpp"
|
||||
#include "adnl/adnl-ext-client.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
@ -36,7 +37,8 @@ class DownloadNextBlock : public td::actor::Actor {
|
||||
td::uint32 priority, td::Timestamp timeout,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<ReceivedBlock> promise);
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::AdnlExtClient> client,
|
||||
td::Promise<ReceivedBlock> promise);
|
||||
|
||||
void abort_query(td::Status reason);
|
||||
void finish_query();
|
||||
@ -62,6 +64,7 @@ class DownloadNextBlock : public td::actor::Actor {
|
||||
td::actor::ActorId<rldp::Rldp> rldp_;
|
||||
td::actor::ActorId<overlay::Overlays> overlays_;
|
||||
td::actor::ActorId<adnl::Adnl> adnl_;
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client_;
|
||||
td::Promise<ReceivedBlock> promise_;
|
||||
|
||||
adnl::AdnlNodeIdShort node_ = adnl::AdnlNodeIdShort::zero();
|
||||
|
@ -35,7 +35,8 @@ DownloadProof::DownloadProof(BlockIdExt block_id, bool allow_partial_proof, adnl
|
||||
td::uint32 priority, td::Timestamp timeout,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<td::BufferSlice> promise)
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::AdnlExtClient> client,
|
||||
td::Promise<td::BufferSlice> promise)
|
||||
: block_id_(block_id)
|
||||
, allow_partial_proof_(allow_partial_proof)
|
||||
, local_id_(local_id)
|
||||
@ -47,6 +48,7 @@ DownloadProof::DownloadProof(BlockIdExt block_id, bool allow_partial_proof, adnl
|
||||
, rldp_(rldp)
|
||||
, overlays_(overlays)
|
||||
, adnl_(adnl)
|
||||
, client_(client)
|
||||
, promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
@ -92,7 +94,7 @@ void DownloadProof::start_up() {
|
||||
void DownloadProof::got_download_token(std::unique_ptr<DownloadToken> token) {
|
||||
token_ = std::move(token);
|
||||
|
||||
if (download_from_.is_zero()) {
|
||||
if (download_from_.is_zero() && client_.empty()) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<std::vector<adnl::AdnlNodeIdShort>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &DownloadProof::abort_query, R.move_as_error());
|
||||
@ -126,10 +128,17 @@ void DownloadProof::got_node_to_download(adnl::AdnlNodeIdShort node) {
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
|
||||
"get_prepare", std::move(P), td::Timestamp::in(1.0),
|
||||
create_serialize_tl_object<ton_api::tonNode_prepareBlockProof>(create_tl_block_id(block_id_),
|
||||
allow_partial_proof_));
|
||||
auto query = create_serialize_tl_object<ton_api::tonNode_prepareBlockProof>(create_tl_block_id(block_id_),
|
||||
allow_partial_proof_);
|
||||
|
||||
if (client_.empty()) {
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
|
||||
"get_prepare", std::move(P), td::Timestamp::in(1.0), std::move(query));
|
||||
} else {
|
||||
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_prepare",
|
||||
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(query)),
|
||||
td::Timestamp::in(1.0), std::move(P));
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadProof::got_block_proof_description(td::BufferSlice proof_description) {
|
||||
@ -154,11 +163,16 @@ void DownloadProof::got_block_proof_description(td::BufferSlice proof_descriptio
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(
|
||||
overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_, overlay_id_,
|
||||
"download block proof", std::move(P), td::Timestamp::in(3.0),
|
||||
create_serialize_tl_object<ton_api::tonNode_downloadBlockProof>(create_tl_block_id(block_id_)),
|
||||
FullNode::max_proof_size(), rldp_);
|
||||
auto query = create_serialize_tl_object<ton_api::tonNode_downloadBlockProof>(create_tl_block_id(block_id_));
|
||||
if (client_.empty()) {
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_,
|
||||
overlay_id_, "download block proof", std::move(P), td::Timestamp::in(3.0),
|
||||
std::move(query), FullNode::max_proof_size(), rldp_);
|
||||
} else {
|
||||
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_prepare",
|
||||
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(query)),
|
||||
td::Timestamp::in(3.0), std::move(P));
|
||||
}
|
||||
},
|
||||
[&](ton_api::tonNode_preparedProofLink &obj) {
|
||||
if (!allow_partial_proof_) {
|
||||
@ -173,11 +187,17 @@ void DownloadProof::got_block_proof_description(td::BufferSlice proof_descriptio
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(
|
||||
overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_, overlay_id_,
|
||||
"download block proof link", std::move(P), td::Timestamp::in(3.0),
|
||||
create_serialize_tl_object<ton_api::tonNode_downloadBlockProofLink>(create_tl_block_id(block_id_)),
|
||||
FullNode::max_proof_size(), rldp_);
|
||||
auto query =
|
||||
create_serialize_tl_object<ton_api::tonNode_downloadBlockProofLink>(create_tl_block_id(block_id_));
|
||||
if (client_.empty()) {
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_,
|
||||
overlay_id_, "download block proof link", std::move(P), td::Timestamp::in(3.0),
|
||||
std::move(query), FullNode::max_proof_size(), rldp_);
|
||||
} else {
|
||||
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "download block proof link",
|
||||
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(query)),
|
||||
td::Timestamp::in(3.0), std::move(P));
|
||||
}
|
||||
},
|
||||
[&](ton_api::tonNode_preparedProofEmpty &obj) {
|
||||
abort_query(td::Status::Error(ErrorCode::notready, "proof not found"));
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "ton/ton-types.h"
|
||||
#include "validator/validator.h"
|
||||
#include "rldp/rldp.h"
|
||||
#include "adnl/adnl-ext-client.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
@ -35,7 +36,8 @@ class DownloadProof : public td::actor::Actor {
|
||||
overlay::OverlayIdShort overlay_id, adnl::AdnlNodeIdShort download_from, td::uint32 priority,
|
||||
td::Timestamp timeout, td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<td::BufferSlice> promise);
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::AdnlExtClient> client,
|
||||
td::Promise<td::BufferSlice> promise);
|
||||
|
||||
void abort_query(td::Status reason);
|
||||
void alarm() override;
|
||||
@ -63,6 +65,7 @@ class DownloadProof : public td::actor::Actor {
|
||||
td::actor::ActorId<rldp::Rldp> rldp_;
|
||||
td::actor::ActorId<overlay::Overlays> overlays_;
|
||||
td::actor::ActorId<adnl::Adnl> adnl_;
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client_;
|
||||
td::Promise<td::BufferSlice> promise_;
|
||||
|
||||
td::BufferSlice data_;
|
||||
|
@ -33,7 +33,8 @@ DownloadState::DownloadState(BlockIdExt block_id, BlockIdExt masterchain_block_i
|
||||
td::uint32 priority, td::Timestamp timeout,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<td::BufferSlice> promise)
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::AdnlExtClient> client,
|
||||
td::Promise<td::BufferSlice> promise)
|
||||
: block_id_(block_id)
|
||||
, masterchain_block_id_(masterchain_block_id)
|
||||
, local_id_(local_id)
|
||||
@ -45,6 +46,7 @@ DownloadState::DownloadState(BlockIdExt block_id, BlockIdExt masterchain_block_i
|
||||
, rldp_(rldp)
|
||||
, overlays_(overlays)
|
||||
, adnl_(adnl)
|
||||
, client_(client)
|
||||
, promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
@ -89,7 +91,7 @@ void DownloadState::start_up() {
|
||||
|
||||
void DownloadState::got_block_handle(BlockHandle handle) {
|
||||
handle_ = std::move(handle);
|
||||
if (!download_from_.is_zero()) {
|
||||
if (!download_from_.is_zero() || !client_.empty()) {
|
||||
got_node_to_download(download_from_);
|
||||
} else {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<std::vector<adnl::AdnlNodeIdShort>> R) {
|
||||
@ -130,8 +132,14 @@ void DownloadState::got_node_to_download(adnl::AdnlNodeIdShort node) {
|
||||
query = create_serialize_tl_object<ton_api::tonNode_prepareZeroState>(create_tl_block_id(block_id_));
|
||||
}
|
||||
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
|
||||
"get_prepare", std::move(P), td::Timestamp::in(1.0), std::move(query));
|
||||
if (client_.empty()) {
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
|
||||
"get_prepare", std::move(P), td::Timestamp::in(1.0), std::move(query));
|
||||
} else {
|
||||
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_prepare",
|
||||
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(query)),
|
||||
td::Timestamp::in(1.0), std::move(P));
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadState::got_block_state_description(td::BufferSlice data) {
|
||||
@ -162,9 +170,15 @@ void DownloadState::got_block_state_description(td::BufferSlice data) {
|
||||
|
||||
td::BufferSlice query =
|
||||
create_serialize_tl_object<ton_api::tonNode_downloadZeroState>(create_tl_block_id(block_id_));
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_,
|
||||
overlay_id_, "download state", std::move(P), timeout_, std::move(query),
|
||||
FullNode::max_state_size(), rldp_);
|
||||
if (client_.empty()) {
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_,
|
||||
overlay_id_, "download state", std::move(P), timeout_, std::move(query),
|
||||
FullNode::max_state_size(), rldp_);
|
||||
} else {
|
||||
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "download state",
|
||||
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(query)),
|
||||
timeout_, std::move(P));
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@ -197,9 +211,15 @@ void DownloadState::got_block_state_part(td::BufferSlice data, td::uint32 reques
|
||||
|
||||
td::BufferSlice query = create_serialize_tl_object<ton_api::tonNode_downloadPersistentStateSlice>(
|
||||
create_tl_block_id(block_id_), create_tl_block_id(masterchain_block_id_), sum_, part_size);
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_, overlay_id_,
|
||||
"download state", std::move(P), timeout_, std::move(query), FullNode::max_state_size(),
|
||||
rldp_);
|
||||
if (client_.empty()) {
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_, overlay_id_,
|
||||
"download state", std::move(P), timeout_, std::move(query), FullNode::max_state_size(),
|
||||
rldp_);
|
||||
} else {
|
||||
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "download state",
|
||||
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(query)), timeout_,
|
||||
std::move(P));
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadState::got_block_state(td::BufferSlice data) {
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "ton/ton-types.h"
|
||||
#include "validator/validator.h"
|
||||
#include "rldp/rldp.h"
|
||||
#include "adnl/adnl-ext-client.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
@ -35,7 +36,8 @@ class DownloadState : public td::actor::Actor {
|
||||
overlay::OverlayIdShort overlay_id, adnl::AdnlNodeIdShort download_from, td::uint32 priority,
|
||||
td::Timestamp timeout, td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<td::BufferSlice> promise);
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::AdnlExtClient> client,
|
||||
td::Promise<td::BufferSlice> promise);
|
||||
|
||||
void abort_query(td::Status reason);
|
||||
void alarm() override;
|
||||
@ -63,6 +65,7 @@ class DownloadState : public td::actor::Actor {
|
||||
td::actor::ActorId<rldp::Rldp> rldp_;
|
||||
td::actor::ActorId<overlay::Overlays> overlays_;
|
||||
td::actor::ActorId<adnl::Adnl> adnl_;
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client_;
|
||||
td::Promise<td::BufferSlice> promise_;
|
||||
|
||||
BlockHandle handle_;
|
||||
|
@ -36,7 +36,8 @@ GetNextKeyBlocks::GetNextKeyBlocks(BlockIdExt block_id, td::uint32 limit, adnl::
|
||||
td::uint32 priority, td::Timestamp timeout,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<std::vector<BlockIdExt>> promise)
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::AdnlExtClient> client,
|
||||
td::Promise<std::vector<BlockIdExt>> promise)
|
||||
: block_id_(block_id)
|
||||
, limit_(limit)
|
||||
, local_id_(local_id)
|
||||
@ -48,6 +49,7 @@ GetNextKeyBlocks::GetNextKeyBlocks(BlockIdExt block_id, td::uint32 limit, adnl::
|
||||
, rldp_(rldp)
|
||||
, overlays_(overlays)
|
||||
, adnl_(adnl)
|
||||
, client_(client)
|
||||
, promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
@ -97,7 +99,7 @@ void GetNextKeyBlocks::start_up() {
|
||||
void GetNextKeyBlocks::got_download_token(std::unique_ptr<DownloadToken> token) {
|
||||
token_ = std::move(token);
|
||||
|
||||
if (download_from_.is_zero()) {
|
||||
if (download_from_.is_zero() && client_.empty()) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<std::vector<adnl::AdnlNodeIdShort>> R) {
|
||||
if (R.is_error()) {
|
||||
td::actor::send_closure(SelfId, &GetNextKeyBlocks::abort_query, R.move_as_error());
|
||||
@ -130,11 +132,15 @@ void GetNextKeyBlocks::got_node_to_download(adnl::AdnlNodeIdShort node) {
|
||||
td::actor::send_closure(SelfId, &GetNextKeyBlocks::got_result, R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
td::actor::send_closure(
|
||||
overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_, "get_prepare", std::move(P),
|
||||
td::Timestamp::in(1.0),
|
||||
create_serialize_tl_object<ton_api::tonNode_getNextKeyBlockIds>(create_tl_block_id(block_id_), limit_));
|
||||
auto query = create_serialize_tl_object<ton_api::tonNode_getNextKeyBlockIds>(create_tl_block_id(block_id_), limit_);
|
||||
if (client_.empty()) {
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
|
||||
"get_prepare", std::move(P), td::Timestamp::in(1.0), std::move(query));
|
||||
} else {
|
||||
td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_prepare",
|
||||
create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(query)),
|
||||
td::Timestamp::in(1.0), std::move(P));
|
||||
}
|
||||
}
|
||||
|
||||
void GetNextKeyBlocks::got_result(td::BufferSlice data) {
|
||||
@ -173,7 +179,8 @@ void GetNextKeyBlocks::download_next_proof() {
|
||||
});
|
||||
|
||||
td::actor::create_actor<DownloadProof>("downloadproofreq", block_id, false, local_id_, overlay_id_, download_from_,
|
||||
priority_, timeout_, validator_manager_, rldp_, overlays_, adnl_, std::move(P))
|
||||
priority_, timeout_, validator_manager_, rldp_, overlays_, adnl_, client_,
|
||||
std::move(P))
|
||||
.release();
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "ton/ton-types.h"
|
||||
#include "validator/validator.h"
|
||||
#include "rldp/rldp.h"
|
||||
#include "adnl/adnl-ext-client.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
@ -35,7 +36,8 @@ class GetNextKeyBlocks : public td::actor::Actor {
|
||||
overlay::OverlayIdShort overlay_id, adnl::AdnlNodeIdShort download_from, td::uint32 priority,
|
||||
td::Timestamp timeout, td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::Promise<std::vector<BlockIdExt>> promise);
|
||||
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::AdnlExtClient> client,
|
||||
td::Promise<std::vector<BlockIdExt>> promise);
|
||||
|
||||
void abort_query(td::Status reason);
|
||||
void alarm() override;
|
||||
@ -67,6 +69,7 @@ class GetNextKeyBlocks : public td::actor::Actor {
|
||||
td::actor::ActorId<rldp::Rldp> rldp_;
|
||||
td::actor::ActorId<overlay::Overlays> overlays_;
|
||||
td::actor::ActorId<adnl::Adnl> adnl_;
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client_;
|
||||
td::Promise<std::vector<BlockIdExt>> promise_;
|
||||
|
||||
std::vector<BlockIdExt> pending_;
|
||||
|
@ -59,6 +59,9 @@ struct ValidatorManagerOptions : public td::CntObject {
|
||||
virtual bool is_hardfork(BlockIdExt block_id) const = 0;
|
||||
virtual td::uint32 get_vertical_height(BlockSeqno seqno) const = 0;
|
||||
virtual td::uint32 get_filedb_depth() const = 0;
|
||||
virtual td::uint32 key_block_utime_step() const {
|
||||
return 86400;
|
||||
}
|
||||
|
||||
virtual void set_zero_block_id(BlockIdExt block_id) = 0;
|
||||
virtual void set_init_block_id(BlockIdExt block_id) = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user