1
0
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:
ton 2019-09-19 23:15:32 +04:00
parent bfa166d66c
commit f40822b58a
50 changed files with 1109 additions and 244 deletions

View File

@ -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

View File

@ -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})

View File

@ -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];

View File

@ -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();

View File

@ -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? )

View 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

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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
~~~~~~~~~~~~~~~~~~~~~

View File

@ -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

View File

@ -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

View File

@ -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");

View File

@ -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()

View File

@ -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

View File

@ -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();

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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));
}());
});
}

View File

@ -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,

View File

@ -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);

View File

@ -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();
}

View File

@ -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;

View File

@ -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

View 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

View 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

View 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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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_;

View File

@ -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));

View File

@ -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});

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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) {

View File

@ -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_;

View File

@ -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();
}

View File

@ -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();

View File

@ -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"));

View File

@ -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_;

View File

@ -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) {

View File

@ -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_;

View File

@ -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();
}

View File

@ -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_;

View File

@ -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;