mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Merge branch 'tonproxy-v1' into block-generation
# Conflicts: # adnl/adnl-query.cpp # adnl/adnl-query.h
This commit is contained in:
commit
eb9d601d4e
27 changed files with 217 additions and 106 deletions
|
@ -80,6 +80,9 @@ class AdnlExtClientImpl : public AdnlExtClient {
|
||||||
if (!conn_.empty() && conn_.get() == conn) {
|
if (!conn_.empty() && conn_.get() == conn) {
|
||||||
callback_->on_stop_ready();
|
callback_->on_stop_ready();
|
||||||
conn_ = {};
|
conn_ = {};
|
||||||
|
for (auto& q : out_queries_) {
|
||||||
|
td::actor::send_closure(q.second, &AdnlQuery::set_error, td::Status::Error(ErrorCode::cancelled));
|
||||||
|
}
|
||||||
alarm_timestamp() = next_create_at_;
|
alarm_timestamp() = next_create_at_;
|
||||||
try_stop();
|
try_stop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,15 +25,14 @@ namespace ton {
|
||||||
namespace adnl {
|
namespace adnl {
|
||||||
|
|
||||||
void AdnlQuery::alarm() {
|
void AdnlQuery::alarm() {
|
||||||
promise_.set_error(td::Status::Error(ErrorCode::timeout, PSTRING() << "timeout for adnl query " << name_));
|
set_error(td::Status::Error(ErrorCode::timeout, PSTRING() << "timeout for adnl query " << name_));
|
||||||
stop();
|
|
||||||
}
|
}
|
||||||
void AdnlQuery::result(td::BufferSlice data) {
|
void AdnlQuery::result(td::BufferSlice data) {
|
||||||
promise_.set_value(std::move(data));
|
promise_.set_value(std::move(data));
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
void AdnlQuery::reject_query() {
|
void AdnlQuery::set_error(td::Status error) {
|
||||||
promise_.set_error(td::Status::Error(ErrorCode::timeout, PSTRING() << "rejected adnl query " << name_));
|
promise_.set_error(std::move(error));
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ class AdnlQuery : public td::actor::Actor {
|
||||||
}
|
}
|
||||||
void alarm() override;
|
void alarm() override;
|
||||||
void result(td::BufferSlice data);
|
void result(td::BufferSlice data);
|
||||||
void reject_query();
|
void set_error(td::Status error);
|
||||||
void start_up() override {
|
void start_up() override {
|
||||||
alarm_timestamp() = timeout_;
|
alarm_timestamp() = timeout_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,12 +43,12 @@ $# 4 > need-params <> abort"extra parameters, or no parameters for chosen main o
|
||||||
variable Values dictnew Values !
|
variable Values dictnew Values !
|
||||||
// ( i c -- )
|
// ( i c -- )
|
||||||
{ over 0= abort"category cannot be zero"
|
{ over 0= abort"category cannot be zero"
|
||||||
<b swap ref, swap Values @ 16 b>idict!+ not abort"duplicate category id"
|
<b swap ref, swap Values @ 256 b>udict!+ not abort"duplicate category id"
|
||||||
Values !
|
Values !
|
||||||
} : register-value
|
} : register-value
|
||||||
|
|
||||||
{ @end? abort"category number expected" @next (number) 1 <> abort"category must be integer"
|
{ @end? abort"category number expected" @next (number) 1 <> abort"category must be integer"
|
||||||
dup 16 fits not abort"category does not fit into 16 bit integer"
|
dup 256 fits not abort"category does not fit into 256 bit integer"
|
||||||
dup 0= abort"category must be non-zero"
|
dup 0= abort"category must be non-zero"
|
||||||
} : parse-cat-num
|
} : parse-cat-num
|
||||||
{ @end? abort"smart contract address expected"
|
{ @end? abort"smart contract address expected"
|
||||||
|
|
|
@ -7,8 +7,15 @@
|
||||||
| Author: Oleksandr Murzin (tg: @skydev / em: alexhacker64@gmail.com) |
|
| Author: Oleksandr Murzin (tg: @skydev / em: alexhacker64@gmail.com) |
|
||||||
| October 2019 |
|
| October 2019 |
|
||||||
\------------------------------------------------------------------------/
|
\------------------------------------------------------------------------/
|
||||||
|
Updated to actual DNS standard version by starlightduck in 2022
|
||||||
-}
|
-}
|
||||||
|
|
||||||
|
;;===========================================================================;;
|
||||||
|
;; Custom ASM instructions ;;
|
||||||
|
;;===========================================================================;;
|
||||||
|
|
||||||
|
cell udict_get_ref_(cell dict, int key_len, int index) asm(index dict key_len) "DICTUGETOPTREF";
|
||||||
|
|
||||||
;;===========================================================================;;
|
;;===========================================================================;;
|
||||||
;; Utility functions ;;
|
;; Utility functions ;;
|
||||||
;;===========================================================================;;
|
;;===========================================================================;;
|
||||||
|
@ -19,7 +26,7 @@
|
||||||
[OptRef<1b+1r?>:Hashmap<UInt<160b>(Time|Hash128)->Slice(DomName)>:gc]
|
[OptRef<1b+1r?>:Hashmap<UInt<160b>(Time|Hash128)->Slice(DomName)>:gc]
|
||||||
[UInt<32b>:stdperiod] [Gram:PPReg] [Gram:PPCell] [Gram:PPBit]
|
[UInt<32b>:stdperiod] [Gram:PPReg] [Gram:PPCell] [Gram:PPBit]
|
||||||
[UInt<32b>:lasthousekeeping]
|
[UInt<32b>:lasthousekeeping]
|
||||||
<CatTable> := HashmapE 16 ^DNSRecord
|
<CatTable> := HashmapE 256 (~~16~~) ^DNSRecord
|
||||||
|
|
||||||
STORED DOMAIN NAME SLICE FORMAT: (#ZeroChars<7b>) (Domain name value)
|
STORED DOMAIN NAME SLICE FORMAT: (#ZeroChars<7b>) (Domain name value)
|
||||||
#Zeros allows to simultaneously store, for example, com\0 and com\0google\0
|
#Zeros allows to simultaneously store, for example, com\0 and com\0google\0
|
||||||
|
@ -189,6 +196,7 @@ int check_owner(cell cat_table, cell owner_info, int src_wc, int src_addr, int s
|
||||||
store_data(ctl, domdata, gc, [stdper, ppr, ppc, ppb], nhk, lhk);
|
store_data(ctl, domdata, gc, [stdper, ppr, ppc, ppb], nhk, lhk);
|
||||||
return send_ok(0);
|
return send_ok(0);
|
||||||
}
|
}
|
||||||
|
var (addr, query_id, op) = query_info;
|
||||||
if (op == 0x4344656c) { ;; CDel = destroy smart contract
|
if (op == 0x4344656c) { ;; CDel = destroy smart contract
|
||||||
ifnot (domdata.null?()) {
|
ifnot (domdata.null?()) {
|
||||||
;; domain dictionary not empty, force gc
|
;; domain dictionary not empty, force gc
|
||||||
|
@ -199,9 +207,12 @@ int check_owner(cell cat_table, cell owner_info, int src_wc, int src_addr, int s
|
||||||
;; domain dictionary still not empty, error
|
;; domain dictionary still not empty, error
|
||||||
return send_error(0xee74656d);
|
return send_error(0xee74656d);
|
||||||
}
|
}
|
||||||
var (addr, query_id, op) = query_info;
|
|
||||||
return send_message(addr, 0xef6b6179, query_id, op, 0, 128 + 32);
|
return send_message(addr, 0xef6b6179, query_id, op, 0, 128 + 32);
|
||||||
}
|
}
|
||||||
|
if (op == 0x54616b65) { ;; Take = take grams from the contract
|
||||||
|
var amount = in_msg~load_grams();
|
||||||
|
return send_message(addr, 0xef6b6179, query_id, op, amount, 64);
|
||||||
|
}
|
||||||
return send_error(0xffffffff);
|
return send_error(0xffffffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +300,8 @@ int check_owner(cell cat_table, cell owner_info, int src_wc, int src_addr, int s
|
||||||
if (exp >= n) { ;; entry not expired
|
if (exp >= n) { ;; entry not expired
|
||||||
cell cat_table = val~load_ref();
|
cell cat_table = val~load_ref();
|
||||||
val.end_parse();
|
val.end_parse();
|
||||||
var (cown, ok) = cat_table.idict_get_ref?(16, -2);
|
;; update: category length now u256 instead of i16, owner index is now 0 instead of -2
|
||||||
|
var (cown, ok) = cat_table.udict_get_ref?(256, 0);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
owner_info = cown;
|
owner_info = cown;
|
||||||
}
|
}
|
||||||
|
@ -318,14 +330,15 @@ int check_owner(cell cat_table, cell owner_info, int src_wc, int src_addr, int s
|
||||||
data = in_msg~load_ref();
|
data = in_msg~load_ref();
|
||||||
;; basic integrity check of (client-provided) dictionary
|
;; basic integrity check of (client-provided) dictionary
|
||||||
ifnot (data.dict_empty?()) { ;; 1000 gas!
|
ifnot (data.dict_empty?()) { ;; 1000 gas!
|
||||||
var (oinfo, ok) = data.idict_get_ref?(16, -2);
|
;; update: category length now u256 instead of i16, owner index is now 0 instead of -2
|
||||||
|
var (oinfo, ok) = data.udict_get_ref?(256, 0);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
var cs = oinfo.begin_parse();
|
var cs = oinfo.begin_parse();
|
||||||
throw_unless(31, cs.slice_bits() >= 16 + 3 + 8 + 256);
|
throw_unless(31, cs.slice_bits() >= 16 + 3 + 8 + 256);
|
||||||
throw_unless(31, cs.preload_uint(19) == 0x9fd3 * 8 + 4);
|
throw_unless(31, cs.preload_uint(19) == 0x9fd3 * 8 + 4);
|
||||||
}
|
}
|
||||||
(_, _, int minok) = data.idict_get_min?(16);
|
(_, _, int minok) = data.udict_get_min?(256); ;; update: category length now u256 instead of i16
|
||||||
(_, _, int maxok) = data.idict_get_max?(16);
|
(_, _, int maxok) = data.udict_get_max?(256); ;; update: category length now u256 instead of i16
|
||||||
throw_unless(31, minok & maxok);
|
throw_unless(31, minok & maxok);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -410,7 +423,8 @@ int check_owner(cell cat_table, cell owner_info, int src_wc, int src_addr, int s
|
||||||
(int bits, int refs) = domain.slice_bits_refs();
|
(int bits, int refs) = domain.slice_bits_refs();
|
||||||
throw_if(30, refs | (bits & 7)); ;; malformed input (~ 8n-bit)
|
throw_if(30, refs | (bits & 7)); ;; malformed input (~ 8n-bit)
|
||||||
ifnot (bits) {
|
ifnot (bits) {
|
||||||
return (0, null(), 0, null()); ;; zero-length input
|
;; return (0, null(), 0, null()); ;; zero-length input
|
||||||
|
throw(30); ;; update: throw exception for empty input
|
||||||
}
|
}
|
||||||
|
|
||||||
int domain_last_byte = domain.slice_last(8).preload_uint(8);
|
int domain_last_byte = domain.slice_last(8).preload_uint(8);
|
||||||
|
@ -420,7 +434,14 @@ int check_owner(cell cat_table, cell owner_info, int src_wc, int src_addr, int s
|
||||||
bits += 8;
|
bits += 8;
|
||||||
}
|
}
|
||||||
if (bits == 8) {
|
if (bits == 8) {
|
||||||
return (0, null(), 0, null()); ;; zero-length input, but with zero byte
|
return (0, null(), 8, null()); ;; zero-length input, but with zero byte
|
||||||
|
;; update: return 8 as resolved, but with no data
|
||||||
|
}
|
||||||
|
int domain_first_byte = domain.preload_uint(8);
|
||||||
|
if (domain_first_byte == 0) {
|
||||||
|
;; update: remove prefix \0
|
||||||
|
domain~load_uint(8);
|
||||||
|
bits -= 8;
|
||||||
}
|
}
|
||||||
var ds = get_data().begin_parse();
|
var ds = get_data().begin_parse();
|
||||||
(_, cell root) = (ds~load_ref(), ds~load_dict());
|
(_, cell root) = (ds~load_ref(), ds~load_dict());
|
||||||
|
@ -453,10 +474,11 @@ int check_owner(cell cat_table, cell owner_info, int src_wc, int src_addr, int s
|
||||||
(int, cell) dnsresolve(slice domain, int category) method_id {
|
(int, cell) dnsresolve(slice domain, int category) method_id {
|
||||||
(int exp, cell cat_table, int exact?, slice pfx) = dnsdictlookup(domain, now());
|
(int exp, cell cat_table, int exact?, slice pfx) = dnsdictlookup(domain, now());
|
||||||
ifnot (exp) {
|
ifnot (exp) {
|
||||||
return (0, null());
|
return (exact?, null()); ;; update: reuse exact? to return 8 for \0
|
||||||
}
|
}
|
||||||
ifnot (exact?) { ;; incomplete subdomain found, must return next resolver (-1)
|
ifnot (exact?) { ;; incomplete subdomain found, must return next resolver (-1)
|
||||||
category = -1;
|
category = "dns_next_resolver"H; ;; 0x19f02441ee588fdb26ee24b2568dd035c3c9206e11ab979be62e55558a1d17ff
|
||||||
|
;; update: next resolver is now sha256("dns_next_resolver") instead of -1
|
||||||
}
|
}
|
||||||
|
|
||||||
int pfx_bits = pfx.slice_bits();
|
int pfx_bits = pfx.slice_bits();
|
||||||
|
@ -467,7 +489,7 @@ int check_owner(cell cat_table, cell owner_info, int src_wc, int src_addr, int s
|
||||||
ifnot (category) {
|
ifnot (category) {
|
||||||
return (pfx_bits, cat_table); ;; return cell with entire dictionary for 0
|
return (pfx_bits, cat_table); ;; return cell with entire dictionary for 0
|
||||||
} else {
|
} else {
|
||||||
cell cat_found = cat_table.idict_get_ref(16, category);
|
cell cat_found = cat_table.udict_get_ref_(256, category); ;; update: category length now u256 instead of i16
|
||||||
return (pfx_bits, cat_found);
|
return (pfx_bits, cat_found);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,15 @@
|
||||||
| Author: Oleksandr Murzin (tg: @skydev / em: alexhacker64@gmail.com) |
|
| Author: Oleksandr Murzin (tg: @skydev / em: alexhacker64@gmail.com) |
|
||||||
| October 2019 |
|
| October 2019 |
|
||||||
\------------------------------------------------------------------------/
|
\------------------------------------------------------------------------/
|
||||||
|
Updated to actual DNS standard version by starlightduck in 2022
|
||||||
-}
|
-}
|
||||||
|
|
||||||
;;===========================================================================;;
|
;;===========================================================================;;
|
||||||
;; Custom ASM instructions ;;
|
;; Custom ASM instructions ;;
|
||||||
;;===========================================================================;;
|
;;===========================================================================;;
|
||||||
|
|
||||||
|
cell udict_get_ref_(cell dict, int key_len, int index) asm(index dict key_len) "DICTUGETOPTREF";
|
||||||
|
|
||||||
(cell, ()) pfxdict_set_ref(cell dict, int key_len, slice key, cell value) {
|
(cell, ()) pfxdict_set_ref(cell dict, int key_len, slice key, cell value) {
|
||||||
throw_unless(33, dict~pfxdict_set?(key_len, key, begin_cell().store_maybe_ref(value).end_cell().begin_parse()));
|
throw_unless(33, dict~pfxdict_set?(key_len, key, begin_cell().store_maybe_ref(value).end_cell().begin_parse()));
|
||||||
return (dict, ());
|
return (dict, ());
|
||||||
|
@ -67,9 +70,9 @@
|
||||||
Operations (continuation of message):
|
Operations (continuation of message):
|
||||||
00 Contract initialization message (only if seqno = 0) (x=-)
|
00 Contract initialization message (only if seqno = 0) (x=-)
|
||||||
11 VSet: set specified value to specified subdomain->category (x=2)
|
11 VSet: set specified value to specified subdomain->category (x=2)
|
||||||
[Int<16b>:category] [Name<?>:subdomain] [Cell<1r>:value]
|
[UInt<256b>:category] [Name<?>:subdomain] [Cell<1r>:value]
|
||||||
12 VDel: delete specified subdomain->category (x=2)
|
12 VDel: delete specified subdomain->category (x=2)
|
||||||
[Int<16b>:category] [Name<?>:subdomain]
|
[UInt<256b>:category] [Name<?>:subdomain]
|
||||||
21 DSet: replace entire category dictionary of domain with provided (x=0)
|
21 DSet: replace entire category dictionary of domain with provided (x=0)
|
||||||
[Name<?>:subdomain] [Cell<1r>:new_cat_table]
|
[Name<?>:subdomain] [Cell<1r>:new_cat_table]
|
||||||
22 DDel: delete entire category dictionary of specified domain (x=0)
|
22 DDel: delete entire category dictionary of specified domain (x=0)
|
||||||
|
@ -112,7 +115,7 @@
|
||||||
int cat = 0;
|
int cat = 0;
|
||||||
if (op < 20) {
|
if (op < 20) {
|
||||||
;; for operations with codes 10..19 category is required
|
;; for operations with codes 10..19 category is required
|
||||||
cat = ops~load_int(16);
|
cat = ops~load_uint(256); ;; update: category length now u256 instead of i16
|
||||||
}
|
}
|
||||||
slice name = null(); ;; any slice value
|
slice name = null(); ;; any slice value
|
||||||
cell cat_table = null();
|
cell cat_table = null();
|
||||||
|
@ -159,13 +162,13 @@
|
||||||
;; 11 VSet: set specified value to specified subdomain->category
|
;; 11 VSet: set specified value to specified subdomain->category
|
||||||
if (op == 11) {
|
if (op == 11) {
|
||||||
cell new_value = ops~load_maybe_ref();
|
cell new_value = ops~load_maybe_ref();
|
||||||
cat_table~idict_set_get_ref(16, cat, new_value);
|
cat_table~udict_set_get_ref(256, cat, new_value); ;; update: category length now u256 instead of i16
|
||||||
root~pfxdict_set_ref(1023, name, cat_table);
|
root~pfxdict_set_ref(1023, name, cat_table);
|
||||||
return (root, ops);
|
return (root, ops);
|
||||||
}
|
}
|
||||||
;; 12 VDel: delete specified subdomain->category value
|
;; 12 VDel: delete specified subdomain->category value
|
||||||
if (op == 12) {
|
if (op == 12) {
|
||||||
if (cat_table~idict_delete?(16, cat)) {
|
if (cat_table~udict_delete?(256, cat)) { ;; update: category length now u256 instead of i16
|
||||||
root~pfxdict_set_ref(1023, name, cat_table);
|
root~pfxdict_set_ref(1023, name, cat_table);
|
||||||
}
|
}
|
||||||
return (root, ops);
|
return (root, ops);
|
||||||
|
@ -261,7 +264,7 @@ cell process_ops(cell root, slice ops) inline_ref {
|
||||||
Data structure:
|
Data structure:
|
||||||
Root cell: [UInt<32b>:seqno] [UInt<256b>:owner_public_key]
|
Root cell: [UInt<32b>:seqno] [UInt<256b>:owner_public_key]
|
||||||
[OptRef<1b+1r?>:Hashmap<PfxDict:Slice->CatTable>:domains]
|
[OptRef<1b+1r?>:Hashmap<PfxDict:Slice->CatTable>:domains]
|
||||||
<CatTable> := HashmapE 16 ^DNSRecord
|
<CatTable> := HashmapE 256 (~~16~~) ^DNSRecord
|
||||||
|
|
||||||
STORED DOMAIN NAME SLICE FORMAT: (#ZeroChars<7b>) (Domain name value)
|
STORED DOMAIN NAME SLICE FORMAT: (#ZeroChars<7b>) (Domain name value)
|
||||||
#Zeros allows to simultaneously store, for example, com\0 and com\0google\0
|
#Zeros allows to simultaneously store, for example, com\0 and com\0google\0
|
||||||
|
@ -291,7 +294,8 @@ int get_public_key() method_id {
|
||||||
(int, cell) dnsresolve(slice subdomain, int category) method_id {
|
(int, cell) dnsresolve(slice subdomain, int category) method_id {
|
||||||
int bits = subdomain.slice_bits();
|
int bits = subdomain.slice_bits();
|
||||||
ifnot (bits) {
|
ifnot (bits) {
|
||||||
return (0, null()); ;; zero-length input
|
;; return (0, null()); ;; zero-length input
|
||||||
|
throw(30); ;; update: throw exception for empty input
|
||||||
}
|
}
|
||||||
throw_if(30, bits & 7); ;; malformed input (~ 8n-bit)
|
throw_if(30, bits & 7); ;; malformed input (~ 8n-bit)
|
||||||
|
|
||||||
|
@ -302,7 +306,14 @@ int get_public_key() method_id {
|
||||||
bits += 8;
|
bits += 8;
|
||||||
}
|
}
|
||||||
if (bits == 8) {
|
if (bits == 8) {
|
||||||
return (0, null()); ;; zero-length input, but with zero byte
|
return (8, null()); ;; zero-length input, but with zero byte
|
||||||
|
;; update: return 8 as resolved, but with no data
|
||||||
|
}
|
||||||
|
int name_first_byte = subdomain.preload_uint(8);
|
||||||
|
if (name_first_byte == 0) {
|
||||||
|
;; update: remove prefix \0
|
||||||
|
subdomain~load_uint(8);
|
||||||
|
bits -= 8;
|
||||||
}
|
}
|
||||||
(_, _, _, cell root, _) = load_data();
|
(_, _, _, cell root, _) = load_data();
|
||||||
|
|
||||||
|
@ -332,7 +343,9 @@ int get_public_key() method_id {
|
||||||
zeros = - zeros;
|
zeros = - zeros;
|
||||||
|
|
||||||
ifnot (tail.slice_empty?()) { ;; if we have tail then len(pfx) < len(subdomain)
|
ifnot (tail.slice_empty?()) { ;; if we have tail then len(pfx) < len(subdomain)
|
||||||
category = -1; ;; incomplete subdomain found, must return next resolver (-1)
|
;; incomplete subdomain found, must return next resolver
|
||||||
|
category = "dns_next_resolver"H; ;; 0x19f02441ee588fdb26ee24b2568dd035c3c9206e11ab979be62e55558a1d17ff
|
||||||
|
;; update: next resolver is now sha256("dns_next_resolver") instead of -1
|
||||||
}
|
}
|
||||||
int pfx_bits = pfx.slice_bits() - 7;
|
int pfx_bits = pfx.slice_bits() - 7;
|
||||||
cell cat_table = val;
|
cell cat_table = val;
|
||||||
|
@ -342,7 +355,7 @@ int get_public_key() method_id {
|
||||||
if (category == 0) {
|
if (category == 0) {
|
||||||
return (pfx_bits, cat_table); ;; return cell with entire dictionary for 0
|
return (pfx_bits, cat_table); ;; return cell with entire dictionary for 0
|
||||||
} else {
|
} else {
|
||||||
cell cat_found = cat_table.idict_get_ref(16, category);
|
cell cat_found = cat_table.udict_get_ref_(256, category); ;; update: category length now u256 instead of i16
|
||||||
return (pfx_bits, cat_found);
|
return (pfx_bits, cat_found);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ variable Actions
|
||||||
{ @end? abort"subdomain name expected" @next dup $len 127 > abort"subdomain name too long"
|
{ @end? abort"subdomain name expected" @next dup $len 127 > abort"subdomain name too long"
|
||||||
} : parse-domain
|
} : parse-domain
|
||||||
{ @end? abort"category number expected" @next (number) 1 <> abort"category must be integer"
|
{ @end? abort"category number expected" @next (number) 1 <> abort"category must be integer"
|
||||||
dup 16 fits not abort"category does not fit into 16 bit integer"
|
dup 256 fits not abort"category does not fit into 256 bit integer"
|
||||||
dup 0= abort"category must be non-zero"
|
dup 0= abort"category must be non-zero"
|
||||||
} : parse-cat-num
|
} : parse-cat-num
|
||||||
{ @end? abort"`cat` expected" @next "cat" $= not abort"`cat` expected" parse-cat-num
|
{ @end? abort"`cat` expected" @next "cat" $= not abort"`cat` expected" parse-cat-num
|
||||||
|
@ -107,11 +107,11 @@ file-base +"-dns" +contractid +".addr" load-address
|
||||||
{ dup first
|
{ dup first
|
||||||
dup `add eq? {
|
dup `add eq? {
|
||||||
drop 4 untuple <b swap value, b> -rot
|
drop 4 untuple <b swap value, b> -rot
|
||||||
<b 11 6 u, swap 16 i, swap subdomain,
|
<b 11 6 u, swap 256 u, swap subdomain,
|
||||||
swap dict, nip } {
|
swap dict, nip } {
|
||||||
dup `delete eq? {
|
dup `delete eq? {
|
||||||
drop untriple rot drop
|
drop untriple rot drop
|
||||||
<b 12 6 u, swap 16 i, swap subdomain, } {
|
<b 12 6 u, swap 256 u, swap subdomain, } {
|
||||||
dup `drop eq? {
|
dup `drop eq? {
|
||||||
drop second <b 22 6 u, swap subdomain, } {
|
drop second <b 22 6 u, swap subdomain, } {
|
||||||
dup `upgrade eq? {
|
dup `upgrade eq? {
|
||||||
|
|
|
@ -79,10 +79,10 @@ td::Status HttpInboundConnection::receive(td::ChainBufferReader &input) {
|
||||||
send_client_error();
|
send_client_error();
|
||||||
return td::Status::OK();
|
return td::Status::OK();
|
||||||
}
|
}
|
||||||
|
cur_request_ = R.move_as_ok();
|
||||||
if (exit_loop) {
|
if (exit_loop) {
|
||||||
return td::Status::OK();
|
return td::Status::OK();
|
||||||
}
|
}
|
||||||
cur_request_ = R.move_as_ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto payload = cur_request_->create_empty_payload().move_as_ok();
|
auto payload = cur_request_->create_empty_payload().move_as_ok();
|
||||||
|
|
|
@ -42,10 +42,10 @@ td::Status HttpOutboundConnection::receive(td::ChainBufferReader &input) {
|
||||||
answer_error(HttpStatusCode::status_bad_request, "", std::move(promise_));
|
answer_error(HttpStatusCode::status_bad_request, "", std::move(promise_));
|
||||||
return td::Status::OK();
|
return td::Status::OK();
|
||||||
}
|
}
|
||||||
|
cur_response_ = R.move_as_ok();
|
||||||
if (exit_loop) {
|
if (exit_loop) {
|
||||||
return td::Status::OK();
|
return td::Status::OK();
|
||||||
}
|
}
|
||||||
cur_response_ = R.move_as_ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur_response_->code() == 100) {
|
if (cur_response_->code() == 100) {
|
||||||
|
|
|
@ -279,25 +279,20 @@ td::Status HttpPayload::parse(td::ChainBufferReader &input) {
|
||||||
} break;
|
} break;
|
||||||
case ParseState::reading_chunk_data: {
|
case ParseState::reading_chunk_data: {
|
||||||
if (cur_chunk_size_ == 0) {
|
if (cur_chunk_size_ == 0) {
|
||||||
switch (type_) {
|
if (type_ == PayloadType::pt_eof || type_ == PayloadType::pt_tunnel) {
|
||||||
case PayloadType::pt_empty:
|
|
||||||
UNREACHABLE();
|
|
||||||
case PayloadType::pt_eof:
|
|
||||||
case PayloadType::pt_tunnel:
|
|
||||||
cur_chunk_size_ = 1LL << 60;
|
cur_chunk_size_ = 1LL << 60;
|
||||||
break;
|
} else if (type_ == PayloadType::pt_chunked) {
|
||||||
case PayloadType::pt_chunked:
|
|
||||||
state_ = ParseState::reading_crlf;
|
state_ = ParseState::reading_crlf;
|
||||||
break;
|
break;
|
||||||
case PayloadType::pt_content_length: {
|
} else if (type_ == PayloadType::pt_content_length) {
|
||||||
LOG(INFO) << "payload parse success";
|
LOG(INFO) << "payload parse success";
|
||||||
const std::lock_guard<std::mutex> lock{mutex_};
|
const std::lock_guard<std::mutex> lock{mutex_};
|
||||||
state_ = ParseState::completed;
|
state_ = ParseState::completed;
|
||||||
run_callbacks();
|
run_callbacks();
|
||||||
return td::Status::OK();
|
return td::Status::OK();
|
||||||
} break;
|
} else {
|
||||||
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (input.size() == 0) {
|
if (input.size() == 0) {
|
||||||
return td::Status::OK();
|
return td::Status::OK();
|
||||||
|
@ -502,7 +497,7 @@ bool HttpPayload::store_http(td::ChainBufferWriter &output, size_t max_size, Htt
|
||||||
char buf[64];
|
char buf[64];
|
||||||
::sprintf(buf, "%lx\r\n", s.size());
|
::sprintf(buf, "%lx\r\n", s.size());
|
||||||
auto slice = td::Slice(buf, strlen(buf));
|
auto slice = td::Slice(buf, strlen(buf));
|
||||||
wrote |= !slice.empty();
|
wrote = true;
|
||||||
output.append(slice);
|
output.append(slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,7 +509,8 @@ bool HttpPayload::store_http(td::ChainBufferWriter &output, size_t max_size, Htt
|
||||||
wrote = true;
|
wrote = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chunks_.size() != 0 || !parse_completed()) {
|
auto cur_state = state_.load(std::memory_order_consume);
|
||||||
|
if (chunks_.size() != 0 || (cur_state != ParseState::reading_trailer && cur_state != ParseState::completed)) {
|
||||||
return wrote;
|
return wrote;
|
||||||
}
|
}
|
||||||
if (!written_zero_chunk_) {
|
if (!written_zero_chunk_) {
|
||||||
|
@ -531,7 +527,7 @@ bool HttpPayload::store_http(td::ChainBufferWriter &output, size_t max_size, Htt
|
||||||
}
|
}
|
||||||
|
|
||||||
while (max_size > 0) {
|
while (max_size > 0) {
|
||||||
auto cur_state = state_.load(std::memory_order_consume);
|
cur_state = state_.load(std::memory_order_consume);
|
||||||
HttpHeader h = get_header();
|
HttpHeader h = get_header();
|
||||||
if (h.empty()) {
|
if (h.empty()) {
|
||||||
if (cur_state != ParseState::completed) {
|
if (cur_state != ParseState::completed) {
|
||||||
|
@ -587,7 +583,8 @@ tl_object_ptr<ton_api::http_payloadPart> HttpPayload::store_tl(size_t max_size)
|
||||||
max_size -= s.size();
|
max_size -= s.size();
|
||||||
}
|
}
|
||||||
obj->data_.truncate(obj->data_.size() - S.size());
|
obj->data_.truncate(obj->data_.size() - S.size());
|
||||||
if (chunks_.size() != 0) {
|
auto cur_state = state_.load(std::memory_order_consume);
|
||||||
|
if (chunks_.size() != 0 || (cur_state != ParseState::reading_trailer && cur_state != ParseState::completed)) {
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
if (!written_zero_chunk_) {
|
if (!written_zero_chunk_) {
|
||||||
|
@ -597,7 +594,7 @@ tl_object_ptr<ton_api::http_payloadPart> HttpPayload::store_tl(size_t max_size)
|
||||||
LOG(INFO) << "data completed";
|
LOG(INFO) << "data completed";
|
||||||
|
|
||||||
while (max_size > 0) {
|
while (max_size > 0) {
|
||||||
auto cur_state = state_.load(std::memory_order_consume);
|
cur_state = state_.load(std::memory_order_consume);
|
||||||
HttpHeader h = get_header();
|
HttpHeader h = get_header();
|
||||||
if (h.empty()) {
|
if (h.empty()) {
|
||||||
if (cur_state != ParseState::completed) {
|
if (cur_state != ParseState::completed) {
|
||||||
|
@ -869,7 +866,7 @@ td::Status HttpHeader::basic_check() {
|
||||||
}
|
}
|
||||||
for (auto &c : value) {
|
for (auto &c : value) {
|
||||||
if (c == '\r' || c == '\n') {
|
if (c == '\r' || c == '\n') {
|
||||||
return td::Status::Error("bad character in header name");
|
return td::Status::Error("bad character in header value");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return td::Status::OK();
|
return td::Status::OK();
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
*/
|
*/
|
||||||
#include "DNSResolver.h"
|
#include "DNSResolver.h"
|
||||||
#include "td/utils/overloaded.h"
|
#include "td/utils/overloaded.h"
|
||||||
|
#include "common/delay.h"
|
||||||
|
|
||||||
static const double CACHE_TIMEOUT_HARD = 300.0;
|
static const double CACHE_TIMEOUT_HARD = 300.0;
|
||||||
static const double CACHE_TIMEOUT_SOFT = 270.0;
|
static const double CACHE_TIMEOUT_SOFT = 270.0;
|
||||||
|
@ -33,8 +34,18 @@ DNSResolver::DNSResolver(td::actor::ActorId<TonlibClient> tonlib_client) : tonli
|
||||||
}
|
}
|
||||||
|
|
||||||
void DNSResolver::start_up() {
|
void DNSResolver::start_up() {
|
||||||
|
sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DNSResolver::sync() {
|
||||||
auto obj = tonlib_api::make_object<tonlib_api::sync>();
|
auto obj = tonlib_api::make_object<tonlib_api::sync>();
|
||||||
auto P = td::PromiseCreator::lambda([](td::Result<tonlib_api::object_ptr<tonlib_api::Object>>) {});
|
auto P = td::PromiseCreator::lambda([SelfId =
|
||||||
|
actor_id(this)](td::Result<tonlib_api::object_ptr<tonlib_api::Object>> R) {
|
||||||
|
if (R.is_error()) {
|
||||||
|
LOG(WARNING) << "Sync error: " << R.move_as_error();
|
||||||
|
ton::delay_action([SelfId]() { td::actor::send_closure(SelfId, &DNSResolver::sync); }, td::Timestamp::in(5.0));
|
||||||
|
}
|
||||||
|
});
|
||||||
td::actor::send_closure(tonlib_client_, &TonlibClient::send_request, std::move(obj), std::move(P));
|
td::actor::send_closure(tonlib_client_, &TonlibClient::send_request, std::move(obj), std::move(P));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ class DNSResolver : public td::actor::Actor {
|
||||||
void resolve(std::string host, td::Promise<ton::adnl::AdnlNodeIdShort> promise);
|
void resolve(std::string host, td::Promise<ton::adnl::AdnlNodeIdShort> promise);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void sync();
|
||||||
void save_to_cache(std::string host, ton::adnl::AdnlNodeIdShort id);
|
void save_to_cache(std::string host, ton::adnl::AdnlNodeIdShort id);
|
||||||
|
|
||||||
td::actor::ActorId<TonlibClient> tonlib_client_;
|
td::actor::ActorId<TonlibClient> tonlib_client_;
|
||||||
|
|
|
@ -117,7 +117,7 @@ class HttpRemote : public td::actor::Actor {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
td::actor::send_closure(client_, &ton::http::HttpClient::send_request, std::move(request), std::move(payload),
|
td::actor::send_closure(client_, &ton::http::HttpClient::send_request, std::move(request), std::move(payload),
|
||||||
td::Timestamp::in(30.0), std::move(P));
|
td::Timestamp::never(), std::move(P));
|
||||||
} else {
|
} else {
|
||||||
ton::http::answer_error(ton::http::HttpStatusCode::status_bad_request, "", std::move(promise));
|
ton::http::answer_error(ton::http::HttpStatusCode::status_bad_request, "", std::move(promise));
|
||||||
}
|
}
|
||||||
|
@ -801,6 +801,7 @@ class RldpToTcpRequestSender : public td::actor::Actor {
|
||||||
, dst_(dst)
|
, dst_(dst)
|
||||||
, request_(std::move(request))
|
, request_(std::move(request))
|
||||||
, request_payload_(std::move(request_payload))
|
, request_payload_(std::move(request_payload))
|
||||||
|
, proto_version_(request_->proto_version())
|
||||||
, promise_(std::move(promise))
|
, promise_(std::move(promise))
|
||||||
, adnl_(adnl)
|
, adnl_(adnl)
|
||||||
, rldp_(rldp)
|
, rldp_(rldp)
|
||||||
|
@ -824,11 +825,9 @@ class RldpToTcpRequestSender : public td::actor::Actor {
|
||||||
}
|
}
|
||||||
|
|
||||||
void got_result(std::pair<std::unique_ptr<ton::http::HttpResponse>, std::shared_ptr<ton::http::HttpPayload>> R) {
|
void got_result(std::pair<std::unique_ptr<ton::http::HttpResponse>, std::shared_ptr<ton::http::HttpPayload>> R) {
|
||||||
if (R.first->need_payload()) {
|
|
||||||
td::actor::create_actor<HttpRldpPayloadSender>("HttpPayloadSender(R)", std::move(R.second), id_, local_id_, adnl_,
|
td::actor::create_actor<HttpRldpPayloadSender>("HttpPayloadSender(R)", std::move(R.second), id_, local_id_, adnl_,
|
||||||
rldp_)
|
rldp_)
|
||||||
.release();
|
.release();
|
||||||
}
|
|
||||||
auto f = ton::serialize_tl_object(R.first->store_tl(), true);
|
auto f = ton::serialize_tl_object(R.first->store_tl(), true);
|
||||||
promise_.set_value(std::move(f));
|
promise_.set_value(std::move(f));
|
||||||
stop();
|
stop();
|
||||||
|
@ -836,7 +835,7 @@ class RldpToTcpRequestSender : public td::actor::Actor {
|
||||||
|
|
||||||
void abort_query(td::Status error) {
|
void abort_query(td::Status error) {
|
||||||
LOG(INFO) << "aborting http over rldp query: " << error;
|
LOG(INFO) << "aborting http over rldp query: " << error;
|
||||||
promise_.set_result(create_error_response(request_->proto_version(), 502, "Bad Gateway"));
|
promise_.set_result(create_error_response(proto_version_, 502, "Bad Gateway"));
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -848,6 +847,7 @@ class RldpToTcpRequestSender : public td::actor::Actor {
|
||||||
|
|
||||||
std::unique_ptr<ton::http::HttpRequest> request_;
|
std::unique_ptr<ton::http::HttpRequest> request_;
|
||||||
std::shared_ptr<ton::http::HttpPayload> request_payload_;
|
std::shared_ptr<ton::http::HttpPayload> request_payload_;
|
||||||
|
std::string proto_version_;
|
||||||
|
|
||||||
td::Promise<td::BufferSlice> promise_;
|
td::Promise<td::BufferSlice> promise_;
|
||||||
|
|
||||||
|
@ -1090,6 +1090,7 @@ class RldpHttpProxy : public td::actor::Actor {
|
||||||
}
|
}
|
||||||
|
|
||||||
rldp_ = ton::rldp::Rldp::create(adnl_.get());
|
rldp_ = ton::rldp::Rldp::create(adnl_.get());
|
||||||
|
td::actor::send_closure(rldp_, &ton::rldp::Rldp::set_default_mtu, 16 << 10);
|
||||||
td::actor::send_closure(rldp_, &ton::rldp::Rldp::add_id, local_id_);
|
td::actor::send_closure(rldp_, &ton::rldp::Rldp::add_id, local_id_);
|
||||||
for (auto &serv_id : server_ids_) {
|
for (auto &serv_id : server_ids_) {
|
||||||
td::actor::send_closure(rldp_, &ton::rldp::Rldp::add_id, serv_id);
|
td::actor::send_closure(rldp_, &ton::rldp::Rldp::add_id, serv_id);
|
||||||
|
|
|
@ -71,7 +71,7 @@ class RldpIn : public RldpImpl {
|
||||||
|
|
||||||
void send_query(adnl::AdnlNodeIdShort src, adnl::AdnlNodeIdShort dst, std::string name,
|
void send_query(adnl::AdnlNodeIdShort src, adnl::AdnlNodeIdShort dst, std::string name,
|
||||||
td::Promise<td::BufferSlice> promise, td::Timestamp timeout, td::BufferSlice data) override {
|
td::Promise<td::BufferSlice> promise, td::Timestamp timeout, td::BufferSlice data) override {
|
||||||
send_query_ex(src, dst, name, std::move(promise), timeout, std::move(data), default_mtu());
|
send_query_ex(src, dst, name, std::move(promise), timeout, std::move(data), default_mtu_);
|
||||||
}
|
}
|
||||||
void send_query_ex(adnl::AdnlNodeIdShort src, adnl::AdnlNodeIdShort dst, std::string name,
|
void send_query_ex(adnl::AdnlNodeIdShort src, adnl::AdnlNodeIdShort dst, std::string name,
|
||||||
td::Promise<td::BufferSlice> promise, td::Timestamp timeout, td::BufferSlice data,
|
td::Promise<td::BufferSlice> promise, td::Timestamp timeout, td::BufferSlice data,
|
||||||
|
@ -105,6 +105,10 @@ class RldpIn : public RldpImpl {
|
||||||
void add_id(adnl::AdnlNodeIdShort local_id) override;
|
void add_id(adnl::AdnlNodeIdShort local_id) override;
|
||||||
void get_conn_ip_str(adnl::AdnlNodeIdShort l_id, adnl::AdnlNodeIdShort p_id, td::Promise<td::string> promise) override;
|
void get_conn_ip_str(adnl::AdnlNodeIdShort l_id, adnl::AdnlNodeIdShort p_id, td::Promise<td::string> promise) override;
|
||||||
|
|
||||||
|
void set_default_mtu(td::uint64 mtu) override {
|
||||||
|
default_mtu_ = mtu;
|
||||||
|
}
|
||||||
|
|
||||||
RldpIn(td::actor::ActorId<adnl::AdnlPeerTable> adnl) : adnl_(adnl) {
|
RldpIn(td::actor::ActorId<adnl::AdnlPeerTable> adnl) : adnl_(adnl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,6 +124,7 @@ class RldpIn : public RldpImpl {
|
||||||
std::set<TransferId> lru_set_;
|
std::set<TransferId> lru_set_;
|
||||||
RldpLru lru_;
|
RldpLru lru_;
|
||||||
td::uint32 lru_size_ = 0;
|
td::uint32 lru_size_ = 0;
|
||||||
|
td::uint64 default_mtu_ = adnl::Adnl::get_mtu();
|
||||||
|
|
||||||
std::map<TransferId, td::uint64> max_size_;
|
std::map<TransferId, td::uint64> max_size_;
|
||||||
|
|
||||||
|
|
|
@ -123,9 +123,9 @@ void RldpIn::process_message_part(adnl::AdnlNodeIdShort source, adnl::AdnlNodeId
|
||||||
}
|
}
|
||||||
auto ite = max_size_.find(part.transfer_id_);
|
auto ite = max_size_.find(part.transfer_id_);
|
||||||
if (ite == max_size_.end()) {
|
if (ite == max_size_.end()) {
|
||||||
if (static_cast<td::uint64>(part.total_size_) > default_mtu()) {
|
if (static_cast<td::uint64>(part.total_size_) > default_mtu_) {
|
||||||
VLOG(RLDP_NOTICE) << "dropping too big rldp packet of size=" << part.total_size_
|
VLOG(RLDP_NOTICE) << "dropping too big rldp packet of size=" << part.total_size_
|
||||||
<< " default_mtu=" << default_mtu();
|
<< " default_mtu=" << default_mtu_;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -28,15 +28,13 @@ class Rldp : public adnl::AdnlSenderInterface {
|
||||||
public:
|
public:
|
||||||
virtual ~Rldp() = default;
|
virtual ~Rldp() = default;
|
||||||
|
|
||||||
static constexpr td::uint64 default_mtu() {
|
|
||||||
return adnl::Adnl::get_mtu();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void add_id(adnl::AdnlNodeIdShort local_id) = 0;
|
virtual void add_id(adnl::AdnlNodeIdShort local_id) = 0;
|
||||||
|
|
||||||
virtual void send_message_ex(adnl::AdnlNodeIdShort src, adnl::AdnlNodeIdShort dst, td::Timestamp timeout,
|
virtual void send_message_ex(adnl::AdnlNodeIdShort src, adnl::AdnlNodeIdShort dst, td::Timestamp timeout,
|
||||||
td::BufferSlice data) = 0;
|
td::BufferSlice data) = 0;
|
||||||
|
|
||||||
|
virtual void set_default_mtu(td::uint64 mtu) = 0;
|
||||||
|
|
||||||
static td::actor::ActorOwn<Rldp> create(td::actor::ActorId<adnl::Adnl> adnl);
|
static td::actor::ActorOwn<Rldp> create(td::actor::ActorId<adnl::Adnl> adnl);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ void ExtClient::with_last_config(td::Promise<LastConfigState> promise) {
|
||||||
self->last_config_queries_.extract(query_id).set_result(std::move(result));
|
self->last_config_queries_.extract(query_id).set_result(std::move(result));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
if (client_.last_block_actor_.empty()) {
|
if (client_.last_config_actor_.empty()) {
|
||||||
return P.set_error(TonlibError::NoLiteServers());
|
return P.set_error(TonlibError::NoLiteServers());
|
||||||
}
|
}
|
||||||
td::actor::send_closure(client_.last_config_actor_, &LastConfig::get_last_config, std::move(P));
|
td::actor::send_closure(client_.last_config_actor_, &LastConfig::get_last_config, std::move(P));
|
||||||
|
@ -62,10 +62,10 @@ void ExtClient::send_raw_query(td::BufferSlice query, td::Promise<td::BufferSlic
|
||||||
self->queries_.extract(query_id).set_result(std::move(result));
|
self->queries_.extract(query_id).set_result(std::move(result));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
if (client_.andl_ext_client_.empty()) {
|
if (client_.adnl_ext_client_.empty()) {
|
||||||
return P.set_error(TonlibError::NoLiteServers());
|
return P.set_error(TonlibError::NoLiteServers());
|
||||||
}
|
}
|
||||||
td::actor::send_closure(client_.andl_ext_client_, &ton::adnl::AdnlExtClient::send_query, "query", std::move(query),
|
td::actor::send_closure(client_.adnl_ext_client_, &ton::adnl::AdnlExtClient::send_query, "query", std::move(query),
|
||||||
td::Timestamp::in(10.0), std::move(P));
|
td::Timestamp::in(10.0), std::move(P));
|
||||||
}
|
}
|
||||||
} // namespace tonlib
|
} // namespace tonlib
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "td/utils/Container.h"
|
#include "td/utils/Container.h"
|
||||||
#include "td/utils/Random.h"
|
#include "td/utils/Random.h"
|
||||||
|
|
||||||
|
#include "ExtClientLazy.h"
|
||||||
#include "TonlibError.h"
|
#include "TonlibError.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
@ -37,7 +38,7 @@ class LastConfig;
|
||||||
struct LastBlockState;
|
struct LastBlockState;
|
||||||
struct LastConfigState;
|
struct LastConfigState;
|
||||||
struct ExtClientRef {
|
struct ExtClientRef {
|
||||||
td::actor::ActorId<ton::adnl::AdnlExtClient> andl_ext_client_;
|
td::actor::ActorId<ExtClientLazy> adnl_ext_client_;
|
||||||
td::actor::ActorId<LastBlock> last_block_actor_;
|
td::actor::ActorId<LastBlock> last_block_actor_;
|
||||||
td::actor::ActorId<LastConfig> last_config_actor_;
|
td::actor::ActorId<LastConfig> last_config_actor_;
|
||||||
};
|
};
|
||||||
|
@ -94,6 +95,12 @@ class ExtClient {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void force_change_liteserver() {
|
||||||
|
if (!client_.adnl_ext_client_.empty()) {
|
||||||
|
td::actor::send_closure(client_.adnl_ext_client_, &ExtClientLazy::force_change_liteserver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ExtClientRef client_;
|
ExtClientRef client_;
|
||||||
td::Container<td::Promise<td::BufferSlice>> queries_;
|
td::Container<td::Promise<td::BufferSlice>> queries_;
|
||||||
|
|
|
@ -18,13 +18,20 @@
|
||||||
*/
|
*/
|
||||||
#include "ExtClientLazy.h"
|
#include "ExtClientLazy.h"
|
||||||
#include "TonlibError.h"
|
#include "TonlibError.h"
|
||||||
|
#include "td/utils/Random.h"
|
||||||
namespace tonlib {
|
namespace tonlib {
|
||||||
|
|
||||||
class ExtClientLazyImp : public ton::adnl::AdnlExtClient {
|
class ExtClientLazyImp : public ExtClientLazy {
|
||||||
public:
|
public:
|
||||||
ExtClientLazyImp(ton::adnl::AdnlNodeIdFull dst, td::IPAddress dst_addr,
|
ExtClientLazyImp(std::vector<std::pair<ton::adnl::AdnlNodeIdFull, td::IPAddress>> servers,
|
||||||
td::unique_ptr<ExtClientLazy::Callback> callback)
|
td::unique_ptr<ExtClientLazy::Callback> callback)
|
||||||
: dst_(std::move(dst)), dst_addr_(std::move(dst_addr)), callback_(std::move(callback)) {
|
: servers_(std::move(servers)), callback_(std::move(callback)) {
|
||||||
|
CHECK(!servers_.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
void start_up() override {
|
||||||
|
td::Random::Fast rnd;
|
||||||
|
td::random_shuffle(td::as_mutable_span(servers_), rnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_ready(td::Promise<td::Unit> promise) override {
|
void check_ready(td::Promise<td::Unit> promise) override {
|
||||||
|
@ -41,37 +48,66 @@ class ExtClientLazyImp : public ton::adnl::AdnlExtClient {
|
||||||
if (client_.empty()) {
|
if (client_.empty()) {
|
||||||
return promise.set_error(TonlibError::Cancelled());
|
return promise.set_error(TonlibError::Cancelled());
|
||||||
}
|
}
|
||||||
|
td::Promise<td::BufferSlice> P = [SelfId = actor_id(this), idx = cur_server_idx_,
|
||||||
|
promise = std::move(promise)](td::Result<td::BufferSlice> R) mutable {
|
||||||
|
if (R.is_error() &&
|
||||||
|
(R.error().code() == ton::ErrorCode::timeout || R.error().code() == ton::ErrorCode::cancelled)) {
|
||||||
|
td::actor::send_closure(SelfId, &ExtClientLazyImp::set_server_bad, idx, true);
|
||||||
|
}
|
||||||
|
promise.set_result(std::move(R));
|
||||||
|
};
|
||||||
send_closure(client_, &ton::adnl::AdnlExtClient::send_query, std::move(name), std::move(data), timeout,
|
send_closure(client_, &ton::adnl::AdnlExtClient::send_query, std::move(name), std::move(data), timeout,
|
||||||
std::move(promise));
|
std::move(P));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void force_change_liteserver() override {
|
||||||
|
if (servers_.size() == 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cur_server_bad_ = cur_server_bad_force_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
void before_query() {
|
void before_query() {
|
||||||
if (is_closing_) {
|
if (is_closing_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!client_.empty()) {
|
|
||||||
alarm_timestamp() = td::Timestamp::in(MAX_NO_QUERIES_TIMEOUT);
|
alarm_timestamp() = td::Timestamp::in(MAX_NO_QUERIES_TIMEOUT);
|
||||||
|
if (cur_server_bad_) {
|
||||||
|
++cur_server_idx_;
|
||||||
|
} else if (!client_.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
class Callback : public ton::adnl::AdnlExtClient::Callback {
|
class Callback : public ton::adnl::AdnlExtClient::Callback {
|
||||||
public:
|
public:
|
||||||
explicit Callback(td::actor::ActorShared<> parent) : parent_(std::move(parent)) {
|
explicit Callback(td::actor::ActorShared<ExtClientLazyImp> parent, size_t idx)
|
||||||
|
: parent_(std::move(parent)), idx_(idx) {
|
||||||
}
|
}
|
||||||
void on_ready() override {
|
void on_ready() override {
|
||||||
|
td::actor::send_closure(parent_, &ExtClientLazyImp::set_server_bad, idx_, false);
|
||||||
}
|
}
|
||||||
void on_stop_ready() override {
|
void on_stop_ready() override {
|
||||||
|
td::actor::send_closure(parent_, &ExtClientLazyImp::set_server_bad, idx_, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
td::actor::ActorShared<> parent_;
|
td::actor::ActorShared<ExtClientLazyImp> parent_;
|
||||||
|
size_t idx_;
|
||||||
};
|
};
|
||||||
ref_cnt_++;
|
ref_cnt_++;
|
||||||
client_ = ton::adnl::AdnlExtClient::create(dst_, dst_addr_, std::make_unique<Callback>(td::actor::actor_shared()));
|
cur_server_bad_ = false;
|
||||||
|
cur_server_bad_force_ = false;
|
||||||
|
const auto& s = servers_[cur_server_idx_ % servers_.size()];
|
||||||
|
LOG(INFO) << "Connecting to liteserver " << s.second;
|
||||||
|
client_ = ton::adnl::AdnlExtClient::create(
|
||||||
|
s.first, s.second, std::make_unique<Callback>(td::actor::actor_shared(this), cur_server_idx_));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
std::vector<std::pair<ton::adnl::AdnlNodeIdFull, td::IPAddress>> servers_;
|
||||||
ton::adnl::AdnlNodeIdFull dst_;
|
size_t cur_server_idx_ = 0;
|
||||||
td::IPAddress dst_addr_;
|
bool cur_server_bad_ = false;
|
||||||
|
bool cur_server_bad_force_ = false;
|
||||||
|
|
||||||
td::actor::ActorOwn<ton::adnl::AdnlExtClient> client_;
|
td::actor::ActorOwn<ton::adnl::AdnlExtClient> client_;
|
||||||
td::unique_ptr<ExtClientLazy::Callback> callback_;
|
td::unique_ptr<ExtClientLazy::Callback> callback_;
|
||||||
static constexpr double MAX_NO_QUERIES_TIMEOUT = 100;
|
static constexpr double MAX_NO_QUERIES_TIMEOUT = 100;
|
||||||
|
@ -79,6 +115,11 @@ class ExtClientLazyImp : public ton::adnl::AdnlExtClient {
|
||||||
bool is_closing_{false};
|
bool is_closing_{false};
|
||||||
td::uint32 ref_cnt_{1};
|
td::uint32 ref_cnt_{1};
|
||||||
|
|
||||||
|
void set_server_bad(size_t idx, bool bad) {
|
||||||
|
if (idx == cur_server_idx_ && servers_.size() > 1 && !cur_server_bad_force_) {
|
||||||
|
cur_server_bad_ = bad;
|
||||||
|
}
|
||||||
|
}
|
||||||
void alarm() override {
|
void alarm() override {
|
||||||
client_.reset();
|
client_.reset();
|
||||||
}
|
}
|
||||||
|
@ -99,9 +140,13 @@ class ExtClientLazyImp : public ton::adnl::AdnlExtClient {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
td::actor::ActorOwn<ton::adnl::AdnlExtClient> ExtClientLazy::create(ton::adnl::AdnlNodeIdFull dst,
|
td::actor::ActorOwn<ExtClientLazy> ExtClientLazy::create(ton::adnl::AdnlNodeIdFull dst, td::IPAddress dst_addr,
|
||||||
td::IPAddress dst_addr,
|
|
||||||
td::unique_ptr<Callback> callback) {
|
td::unique_ptr<Callback> callback) {
|
||||||
return td::actor::create_actor<ExtClientLazyImp>("ExtClientLazy", dst, dst_addr, std::move(callback));
|
return create({std::make_pair(dst, dst_addr)}, std::move(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
td::actor::ActorOwn<ExtClientLazy> ExtClientLazy::create(
|
||||||
|
std::vector<std::pair<ton::adnl::AdnlNodeIdFull, td::IPAddress>> servers, td::unique_ptr<Callback> callback) {
|
||||||
|
return td::actor::create_actor<ExtClientLazyImp>("ExtClientLazy", std::move(servers), std::move(callback));
|
||||||
}
|
}
|
||||||
} // namespace tonlib
|
} // namespace tonlib
|
||||||
|
|
|
@ -22,15 +22,20 @@
|
||||||
#include "adnl/adnl-ext-client.h"
|
#include "adnl/adnl-ext-client.h"
|
||||||
|
|
||||||
namespace tonlib {
|
namespace tonlib {
|
||||||
class ExtClientLazy {
|
class ExtClientLazy : public ton::adnl::AdnlExtClient {
|
||||||
public:
|
public:
|
||||||
class Callback {
|
class Callback {
|
||||||
public:
|
public:
|
||||||
virtual ~Callback() {
|
virtual ~Callback() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static td::actor::ActorOwn<ton::adnl::AdnlExtClient> create(ton::adnl::AdnlNodeIdFull dst, td::IPAddress dst_addr,
|
|
||||||
|
virtual void force_change_liteserver() = 0;
|
||||||
|
|
||||||
|
static td::actor::ActorOwn<ExtClientLazy> create(ton::adnl::AdnlNodeIdFull dst, td::IPAddress dst_addr,
|
||||||
td::unique_ptr<Callback> callback);
|
td::unique_ptr<Callback> callback);
|
||||||
|
static td::actor::ActorOwn<ExtClientLazy> create(
|
||||||
|
std::vector<std::pair<ton::adnl::AdnlNodeIdFull, td::IPAddress>> servers, td::unique_ptr<Callback> callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tonlib
|
} // namespace tonlib
|
||||||
|
|
|
@ -38,6 +38,9 @@ class ExtClientOutboundImp : public ExtClientOutbound {
|
||||||
callback_->request(query_id, data.as_slice().str());
|
callback_->request(query_id, data.as_slice().str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void force_change_liteserver() override {
|
||||||
|
}
|
||||||
|
|
||||||
void on_query_result(td::int64 id, td::Result<td::BufferSlice> r_data, td::Promise<td::Unit> promise) override {
|
void on_query_result(td::int64 id, td::Result<td::BufferSlice> r_data, td::Promise<td::Unit> promise) override {
|
||||||
auto it = queries_.find(id);
|
auto it = queries_.find(id);
|
||||||
if (it == queries_.end()) {
|
if (it == queries_.end()) {
|
||||||
|
|
|
@ -19,10 +19,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "td/actor/actor.h"
|
#include "td/actor/actor.h"
|
||||||
|
|
||||||
#include "adnl/adnl-ext-client.h"
|
#include "ExtClientLazy.h"
|
||||||
|
|
||||||
namespace tonlib {
|
namespace tonlib {
|
||||||
class ExtClientOutbound : public ton::adnl::AdnlExtClient {
|
class ExtClientOutbound : public ExtClientLazy {
|
||||||
public:
|
public:
|
||||||
class Callback {
|
class Callback {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -374,6 +374,7 @@ void LastBlock::on_sync_error(td::Status status) {
|
||||||
promise.set_error(status.clone());
|
promise.set_error(status.clone());
|
||||||
}
|
}
|
||||||
promises_.clear();
|
promises_.clear();
|
||||||
|
client_.force_change_liteserver();
|
||||||
}
|
}
|
||||||
void LastBlock::on_fatal_error(td::Status status) {
|
void LastBlock::on_fatal_error(td::Status status) {
|
||||||
VLOG(last_block) << "sync: fatal error " << status;
|
VLOG(last_block) << "sync: fatal error " << status;
|
||||||
|
|
|
@ -141,6 +141,7 @@ void LastConfig::on_error(td::Status status) {
|
||||||
promise.set_error(status.clone());
|
promise.set_error(status.clone());
|
||||||
}
|
}
|
||||||
promises_.clear();
|
promises_.clear();
|
||||||
|
get_config_state_ = QueryState::Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LastConfig::tear_down() {
|
void LastConfig::tear_down() {
|
||||||
|
|
|
@ -1649,7 +1649,7 @@ void TonlibClient::hangup() {
|
||||||
|
|
||||||
ExtClientRef TonlibClient::get_client_ref() {
|
ExtClientRef TonlibClient::get_client_ref() {
|
||||||
ExtClientRef ref;
|
ExtClientRef ref;
|
||||||
ref.andl_ext_client_ = raw_client_.get();
|
ref.adnl_ext_client_ = raw_client_.get();
|
||||||
ref.last_block_actor_ = raw_last_block_.get();
|
ref.last_block_actor_ = raw_last_block_.get();
|
||||||
ref.last_config_actor_ = raw_last_config_.get();
|
ref.last_config_actor_ = raw_last_config_.get();
|
||||||
|
|
||||||
|
@ -1683,10 +1683,10 @@ void TonlibClient::init_ext_client() {
|
||||||
ext_client_outbound_ = client.get();
|
ext_client_outbound_ = client.get();
|
||||||
raw_client_ = std::move(client);
|
raw_client_ = std::move(client);
|
||||||
} else {
|
} else {
|
||||||
auto lite_clients_size = config_.lite_clients.size();
|
std::vector<std::pair<ton::adnl::AdnlNodeIdFull, td::IPAddress>> servers;
|
||||||
CHECK(lite_clients_size != 0);
|
for (const auto& s : config_.lite_clients) {
|
||||||
auto lite_client_id = td::Random::fast(0, td::narrow_cast<int>(lite_clients_size) - 1);
|
servers.emplace_back(s.adnl_id, s.address);
|
||||||
auto& lite_client = config_.lite_clients[lite_client_id];
|
}
|
||||||
class Callback : public ExtClientLazy::Callback {
|
class Callback : public ExtClientLazy::Callback {
|
||||||
public:
|
public:
|
||||||
explicit Callback(td::actor::ActorShared<> parent) : parent_(std::move(parent)) {
|
explicit Callback(td::actor::ActorShared<> parent) : parent_(std::move(parent)) {
|
||||||
|
@ -1697,8 +1697,7 @@ void TonlibClient::init_ext_client() {
|
||||||
};
|
};
|
||||||
ext_client_outbound_ = {};
|
ext_client_outbound_ = {};
|
||||||
ref_cnt_++;
|
ref_cnt_++;
|
||||||
raw_client_ = ExtClientLazy::create(lite_client.adnl_id, lite_client.address,
|
raw_client_ = ExtClientLazy::create(std::move(servers), td::make_unique<Callback>(td::actor::actor_shared()));
|
||||||
td::make_unique<Callback>(td::actor::actor_shared()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,7 @@ class TonlibClient : public td::actor::Actor {
|
||||||
vm::Dictionary libraries{256};
|
vm::Dictionary libraries{256};
|
||||||
|
|
||||||
// network
|
// network
|
||||||
td::actor::ActorOwn<ton::adnl::AdnlExtClient> raw_client_;
|
td::actor::ActorOwn<ExtClientLazy> raw_client_;
|
||||||
td::actor::ActorId<ExtClientOutbound> ext_client_outbound_;
|
td::actor::ActorId<ExtClientOutbound> ext_client_outbound_;
|
||||||
td::actor::ActorOwn<LastBlock> raw_last_block_;
|
td::actor::ActorOwn<LastBlock> raw_last_block_;
|
||||||
td::actor::ActorOwn<LastConfig> raw_last_config_;
|
td::actor::ActorOwn<LastConfig> raw_last_config_;
|
||||||
|
|
|
@ -174,7 +174,7 @@ class TonlibCli : public td::actor::Actor {
|
||||||
|
|
||||||
std::map<std::uint64_t, td::Promise<tonlib_api::object_ptr<tonlib_api::Object>>> query_handlers_;
|
std::map<std::uint64_t, td::Promise<tonlib_api::object_ptr<tonlib_api::Object>>> query_handlers_;
|
||||||
|
|
||||||
td::actor::ActorOwn<ton::adnl::AdnlExtClient> raw_client_;
|
td::actor::ActorOwn<tonlib::ExtClientLazy> raw_client_;
|
||||||
|
|
||||||
bool is_closing_{false};
|
bool is_closing_{false};
|
||||||
td::uint32 ref_cnt_{1};
|
td::uint32 ref_cnt_{1};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue