|
18 | 18 | */ |
19 | 19 | #pragma once |
20 | 20 |
|
| 21 | +#include <atomic> |
21 | 22 | #include <map> |
| 23 | +#include <optional> |
22 | 24 | #include <string> |
23 | 25 | #include <vector> |
24 | 26 |
|
@@ -103,9 +105,9 @@ inline ErrorCtxSet ErrorCtx::set_guard(std::vector<std::string> str_list) { |
103 | 105 | /* |
104 | 106 | * |
105 | 107 | * must write candidate to disk, if accepted |
106 | | - * can reject block only if it is invalid (i.e. in case of |
| 108 | + * can reject block only if it is invalid (i.e. in case of |
107 | 109 | * internal errors must retry or crash) |
108 | | - * only exception: block can be rejected, if it is known from |
| 110 | + * only exception: block can be rejected, if it is known from |
109 | 111 | * masterchain, that it will not be part of shardchain finalized |
110 | 112 | * state |
111 | 113 | * |
@@ -150,6 +152,13 @@ class ValidateQuery : public td::actor::Actor { |
150 | 152 | bool prev_key_block_exists_{false}; |
151 | 153 | bool debug_checks_{false}; |
152 | 154 | bool outq_cleanup_partial_{false}; |
| 155 | + bool parallel_accounts_validation_{false}; |
| 156 | + bool parallel_accounts_validation_pending_{false}; |
| 157 | + bool check_account_failed_{false}; |
| 158 | + td::RealCpuTimer parallel_work_timer_{/*is_paused=*/true}; |
| 159 | + std::optional<td::Status> check_account_fatal_error_ = std::nullopt; |
| 160 | + std::optional<std::string> check_account_reject_error_ = std::nullopt; |
| 161 | + std::optional<td::BufferSlice> check_account_reject_reason_ = std::nullopt; |
153 | 162 | BlockSeqno prev_key_seqno_{~0u}; |
154 | 163 | int stage_{0}; |
155 | 164 | td::BitArray<64> shard_pfx_; |
@@ -201,8 +210,7 @@ class ValidateQuery : public td::actor::Actor { |
201 | 210 | ton::BlockIdExt prev_key_block_; |
202 | 211 | ton::LogicalTime prev_key_block_lt_; |
203 | 212 | std::unique_ptr<block::BlockLimits> block_limits_; |
204 | | - std::unique_ptr<block::BlockLimitStatus> block_limit_status_; |
205 | | - td::uint64 total_gas_used_{0}, total_special_gas_used_{0}; |
| 213 | + mutable std::atomic_uint64_t total_gas_used_{0}, total_special_gas_used_{0}; |
206 | 214 |
|
207 | 215 | LogicalTime start_lt_, end_lt_; |
208 | 216 | UnixTime prev_now_{~0u}, now_{~0u}; |
@@ -330,6 +338,7 @@ class ValidateQuery : public td::actor::Actor { |
330 | 338 | bool unpack_block_candidate(); |
331 | 339 | bool extract_collated_data_from(Ref<vm::Cell> croot, int idx); |
332 | 340 | bool extract_collated_data(); |
| 341 | + bool check_account_failures(); |
333 | 342 | bool try_validate(); |
334 | 343 | bool compute_prev_state(); |
335 | 344 | bool compute_next_state(); |
@@ -395,13 +404,56 @@ class ValidateQuery : public td::actor::Actor { |
395 | 404 | td::Bits256& msg_hash); |
396 | 405 | bool check_in_queue(); |
397 | 406 | bool check_delivered_dequeued(); |
398 | | - std::unique_ptr<block::Account> make_account_from(td::ConstBitPtr addr, Ref<vm::CellSlice> account); |
399 | | - std::unique_ptr<block::Account> unpack_account(td::ConstBitPtr addr); |
400 | | - bool check_one_transaction(block::Account& account, LogicalTime lt, Ref<vm::Cell> trans_root, bool is_first, |
401 | | - bool is_last); |
402 | | - bool check_account_transactions(const StdSmcAddress& acc_addr, Ref<vm::CellSlice> acc_tr); |
| 407 | + |
| 408 | + class CheckAccountTxs : public Actor { |
| 409 | + public: |
| 410 | + struct Context { |
| 411 | + std::vector<std::tuple<Bits256, LogicalTime, LogicalTime>> msg_proc_lt{}; |
| 412 | + block::CurrencyCollection total_burned{0}; |
| 413 | + std::vector<std::tuple<Bits256, Bits256, bool>> lib_publishers{}; |
| 414 | + bool defer_all_messages = false; |
| 415 | + std::vector<std::pair<td::Ref<vm::Cell>, td::uint32>> storage_stat_cache_update{}; |
| 416 | + ValidationStats::WorkTimeStats work_time{}; |
| 417 | + |
| 418 | + std::optional<td::Status> fatal_error; |
| 419 | + std::optional<std::string> reject_error; |
| 420 | + std::optional<td::BufferSlice> reject_reason; |
| 421 | + }; |
| 422 | + |
| 423 | + CheckAccountTxs(const ValidateQuery& vq, td::actor::ActorId<ValidateQuery> vq_id, StdSmcAddress address, |
| 424 | + Ref<vm::CellSlice> acc_tr, Context ctx); |
| 425 | + |
| 426 | + bool try_check(); |
| 427 | + Context extract_context(); |
| 428 | + |
| 429 | + private: |
| 430 | + void start_up() override; |
| 431 | + |
| 432 | + void abort_query(td::Status error); |
| 433 | + bool reject_query(std::string error, td::BufferSlice reason = {}); |
| 434 | + bool reject_query(std::string err_msg, td::Status error, td::BufferSlice reason = {}); |
| 435 | + bool fatal_error(td::Status error); |
| 436 | + bool fatal_error(std::string err_msg, int err_code = -666); |
| 437 | + |
| 438 | + std::unique_ptr<block::Account> make_account_from(td::ConstBitPtr addr, Ref<vm::CellSlice> account); |
| 439 | + std::unique_ptr<block::Account> unpack_account(td::ConstBitPtr addr); |
| 440 | + bool check_one_transaction(block::Account& account, LogicalTime lt, Ref<vm::Cell> trans_root, bool is_first, |
| 441 | + bool is_last); |
| 442 | + bool scan_account_libraries(Ref<vm::Cell> orig_libs, Ref<vm::Cell> final_libs, const td::Bits256& addr); |
| 443 | + |
| 444 | + const ValidateQuery& vq_; |
| 445 | + td::actor::ActorId<ValidateQuery> vq_id_; |
| 446 | + StdSmcAddress address_; |
| 447 | + Ref<vm::CellSlice> acc_tr_; |
| 448 | + Context ctx_; |
| 449 | + }; |
| 450 | + friend CheckAccountTxs; |
| 451 | + |
| 452 | + CheckAccountTxs::Context load_check_account_transactions_context(const StdSmcAddress& address); |
| 453 | + void save_account_transactions_context(const StdSmcAddress& address, CheckAccountTxs::Context ctx); |
| 454 | + |
| 455 | + void after_check_account_finished(StdSmcAddress address, CheckAccountTxs::Context context); |
403 | 456 | bool check_transactions(); |
404 | | - bool scan_account_libraries(Ref<vm::Cell> orig_libs, Ref<vm::Cell> final_libs, const td::Bits256& addr); |
405 | 457 | bool check_all_ticktock_processed(); |
406 | 458 | bool check_message_processing_order(); |
407 | 459 | bool check_special_message(Ref<vm::Cell> in_msg_root, const block::CurrencyCollection& amount, |
|
0 commit comments