mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Add checks for external messages
This commit is contained in:
parent
69d0472510
commit
3384d204d2
11 changed files with 396 additions and 119 deletions
|
@ -46,6 +46,8 @@ td::Result<std::vector<td::Ref<ShardTopBlockDescription>>> create_new_shard_bloc
|
|||
|
||||
td::Ref<BlockSignatureSet> create_signature_set(std::vector<BlockSignature> sig_set);
|
||||
|
||||
void run_check_external_message(td::BufferSlice data, td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise);
|
||||
|
||||
void run_accept_block_query(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
|
||||
td::Ref<ValidatorSet> validator_set, td::Ref<BlockSignatureSet> signatures,
|
||||
td::Ref<BlockSignatureSet> approve_signatures, bool send_broadcast,
|
||||
|
@ -81,6 +83,8 @@ void run_collate_hardfork(ShardIdFull shard, const BlockIdExt& min_masterchain_b
|
|||
td::Promise<BlockCandidate> promise);
|
||||
void run_liteserver_query(td::BufferSlice data, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::actor::ActorId<LiteServerCache> cache, td::Promise<td::BufferSlice> promise);
|
||||
void run_fetch_account_state(WorkchainId wc, StdSmcAddress addr, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Promise<std::tuple<td::Ref<vm::CellSlice>,UnixTime,LogicalTime,std::unique_ptr<block::ConfigInfo>>> promise);
|
||||
void run_validate_shard_block_description(td::BufferSlice data, BlockHandle masterchain_block,
|
||||
td::Ref<MasterchainState> masterchain_state,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
|
|
|
@ -103,6 +103,27 @@ class Collator final : public td::actor::Actor {
|
|||
return 2;
|
||||
}
|
||||
|
||||
static td::Result<std::unique_ptr<block::ConfigInfo>>
|
||||
impl_fetch_config_params(std::unique_ptr<block::ConfigInfo> config,
|
||||
Ref<vm::Cell>* old_mparams,
|
||||
std::vector<block::StoragePrices>* storage_prices,
|
||||
block::StoragePhaseConfig* storage_phase_cfg,
|
||||
td::BitArray<256>* rand_seed,
|
||||
block::ComputePhaseConfig* compute_phase_cfg,
|
||||
block::ActionPhaseConfig* action_phase_cfg,
|
||||
td::RefInt256* masterchain_create_fee,
|
||||
td::RefInt256* basechain_create_fee,
|
||||
WorkchainId wc);
|
||||
|
||||
static td::Result<std::unique_ptr<block::Transaction>>
|
||||
impl_create_ordinary_transaction(Ref<vm::Cell> msg_root,
|
||||
block::Account* acc,
|
||||
UnixTime utime, LogicalTime lt,
|
||||
block::StoragePhaseConfig* storage_phase_cfg,
|
||||
block::ComputePhaseConfig* compute_phase_cfg,
|
||||
block::ActionPhaseConfig* action_phase_cfg,
|
||||
bool external, LogicalTime after_lt);
|
||||
|
||||
private:
|
||||
void start_up() override;
|
||||
void alarm() override;
|
||||
|
|
|
@ -1556,68 +1556,92 @@ bool Collator::init_lt() {
|
|||
}
|
||||
|
||||
bool Collator::fetch_config_params() {
|
||||
old_mparams_ = config_->get_config_param(9);
|
||||
{
|
||||
auto res = config_->get_storage_prices();
|
||||
if (res.is_error()) {
|
||||
auto res = impl_fetch_config_params(std::move(config_),
|
||||
&old_mparams_, &storage_prices_, &storage_phase_cfg_,
|
||||
&rand_seed_, &compute_phase_cfg_, &action_phase_cfg_,
|
||||
&masterchain_create_fee_, &basechain_create_fee_,
|
||||
workchain()
|
||||
);
|
||||
if (res.is_error()) {
|
||||
return fatal_error(res.move_as_error());
|
||||
}
|
||||
config_ = res.move_as_ok();
|
||||
return true;
|
||||
}
|
||||
|
||||
td::Result<std::unique_ptr<block::ConfigInfo>>
|
||||
Collator::impl_fetch_config_params(std::unique_ptr<block::ConfigInfo> config,
|
||||
Ref<vm::Cell>* old_mparams,
|
||||
std::vector<block::StoragePrices>* storage_prices,
|
||||
block::StoragePhaseConfig* storage_phase_cfg,
|
||||
td::BitArray<256>* rand_seed,
|
||||
block::ComputePhaseConfig* compute_phase_cfg,
|
||||
block::ActionPhaseConfig* action_phase_cfg,
|
||||
td::RefInt256* masterchain_create_fee,
|
||||
td::RefInt256* basechain_create_fee,
|
||||
WorkchainId wc) {
|
||||
*old_mparams = config->get_config_param(9);
|
||||
{
|
||||
auto res = config->get_storage_prices();
|
||||
if (res.is_error()) {
|
||||
return res.move_as_error();
|
||||
}
|
||||
storage_prices_ = res.move_as_ok();
|
||||
*storage_prices = res.move_as_ok();
|
||||
}
|
||||
{
|
||||
// generate rand seed
|
||||
prng::rand_gen().strong_rand_bytes(rand_seed_.data(), 32);
|
||||
LOG(DEBUG) << "block random seed set to " << rand_seed_.to_hex();
|
||||
prng::rand_gen().strong_rand_bytes(rand_seed->data(), 32);
|
||||
LOG(DEBUG) << "block random seed set to " << rand_seed->to_hex();
|
||||
}
|
||||
{
|
||||
// compute compute_phase_cfg / storage_phase_cfg
|
||||
auto cell = config_->get_config_param(is_masterchain() ? 20 : 21);
|
||||
auto cell = config->get_config_param(wc == ton::masterchainId ? 20 : 21);
|
||||
if (cell.is_null()) {
|
||||
return fatal_error("cannot fetch current gas prices and limits from masterchain configuration");
|
||||
return td::Status::Error(-668, "cannot fetch current gas prices and limits from masterchain configuration");
|
||||
}
|
||||
if (!compute_phase_cfg_.parse_GasLimitsPrices(std::move(cell), storage_phase_cfg_.freeze_due_limit,
|
||||
storage_phase_cfg_.delete_due_limit)) {
|
||||
return fatal_error("cannot unpack current gas prices and limits from masterchain configuration");
|
||||
if (!compute_phase_cfg->parse_GasLimitsPrices(std::move(cell), storage_phase_cfg->freeze_due_limit,
|
||||
storage_phase_cfg->delete_due_limit)) {
|
||||
return td::Status::Error(-668, "cannot unpack current gas prices and limits from masterchain configuration");
|
||||
}
|
||||
compute_phase_cfg_.block_rand_seed = rand_seed_;
|
||||
compute_phase_cfg_.libraries = std::make_unique<vm::Dictionary>(config_->get_libraries_root(), 256);
|
||||
compute_phase_cfg_.global_config = config_->get_root_cell();
|
||||
compute_phase_cfg->block_rand_seed = *rand_seed;
|
||||
compute_phase_cfg->libraries = std::make_unique<vm::Dictionary>(config->get_libraries_root(), 256);
|
||||
compute_phase_cfg->global_config = config->get_root_cell();
|
||||
}
|
||||
{
|
||||
// compute action_phase_cfg
|
||||
block::gen::MsgForwardPrices::Record rec;
|
||||
auto cell = config_->get_config_param(24);
|
||||
auto cell = config->get_config_param(24);
|
||||
if (cell.is_null() || !tlb::unpack_cell(std::move(cell), rec)) {
|
||||
return fatal_error("cannot fetch masterchain message transfer prices from masterchain configuration");
|
||||
return td::Status::Error(-668, "cannot fetch masterchain message transfer prices from masterchain configuration");
|
||||
}
|
||||
action_phase_cfg_.fwd_mc =
|
||||
action_phase_cfg->fwd_mc =
|
||||
block::MsgPrices{rec.lump_price, rec.bit_price, rec.cell_price, rec.ihr_price_factor,
|
||||
(unsigned)rec.first_frac, (unsigned)rec.next_frac};
|
||||
cell = config_->get_config_param(25);
|
||||
cell = config->get_config_param(25);
|
||||
if (cell.is_null() || !tlb::unpack_cell(std::move(cell), rec)) {
|
||||
return fatal_error("cannot fetch standard message transfer prices from masterchain configuration");
|
||||
return td::Status::Error(-668, "cannot fetch standard message transfer prices from masterchain configuration");
|
||||
}
|
||||
action_phase_cfg_.fwd_std =
|
||||
action_phase_cfg->fwd_std =
|
||||
block::MsgPrices{rec.lump_price, rec.bit_price, rec.cell_price, rec.ihr_price_factor,
|
||||
(unsigned)rec.first_frac, (unsigned)rec.next_frac};
|
||||
action_phase_cfg_.workchains = &config_->get_workchain_list();
|
||||
action_phase_cfg_.bounce_msg_body = (config_->has_capability(ton::capBounceMsgBody) ? 256 : 0);
|
||||
action_phase_cfg->workchains = &config->get_workchain_list();
|
||||
action_phase_cfg->bounce_msg_body = (config->has_capability(ton::capBounceMsgBody) ? 256 : 0);
|
||||
}
|
||||
{
|
||||
// fetch block_grams_created
|
||||
auto cell = config_->get_config_param(14);
|
||||
auto cell = config->get_config_param(14);
|
||||
if (cell.is_null()) {
|
||||
basechain_create_fee_ = masterchain_create_fee_ = td::zero_refint();
|
||||
*basechain_create_fee = *masterchain_create_fee = td::zero_refint();
|
||||
} else {
|
||||
block::gen::BlockCreateFees::Record create_fees;
|
||||
if (!(tlb::unpack_cell(cell, create_fees) &&
|
||||
block::tlb::t_Grams.as_integer_to(create_fees.masterchain_block_fee, masterchain_create_fee_) &&
|
||||
block::tlb::t_Grams.as_integer_to(create_fees.basechain_block_fee, basechain_create_fee_))) {
|
||||
return fatal_error("cannot unpack BlockCreateFees from configuration parameter #14");
|
||||
block::tlb::t_Grams.as_integer_to(create_fees.masterchain_block_fee, *masterchain_create_fee) &&
|
||||
block::tlb::t_Grams.as_integer_to(create_fees.basechain_block_fee, *basechain_create_fee))) {
|
||||
return td::Status::Error(-668, "cannot unpack BlockCreateFees from configuration parameter #14");
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return std::move(config);
|
||||
}
|
||||
|
||||
bool Collator::compute_minted_amount(block::CurrencyCollection& to_mint) {
|
||||
|
@ -2218,75 +2242,25 @@ Ref<vm::Cell> Collator::create_ordinary_transaction(Ref<vm::Cell> msg_root) {
|
|||
}
|
||||
block::Account* acc = acc_res.move_as_ok();
|
||||
assert(acc);
|
||||
if (acc->last_trans_end_lt_ >= start_lt && acc->transactions.empty()) {
|
||||
fatal_error(PSTRING() << "last transaction time in the state of account " << workchain() << ":" << addr.to_hex()
|
||||
<< " is too large");
|
||||
return {};
|
||||
}
|
||||
auto trans_min_lt = start_lt;
|
||||
if (external) {
|
||||
// transactions processing external messages must have lt larger than all processed internal messages
|
||||
trans_min_lt = std::max(trans_min_lt, last_proc_int_msg_.first);
|
||||
}
|
||||
std::unique_ptr<block::Transaction> trans =
|
||||
std::make_unique<block::Transaction>(*acc, block::Transaction::tr_ord, trans_min_lt + 1, now_, msg_root);
|
||||
bool ihr_delivered = false; // FIXME
|
||||
if (!trans->unpack_input_msg(ihr_delivered, &action_phase_cfg_)) {
|
||||
if (external) {
|
||||
// inbound external message was not accepted
|
||||
LOG(DEBUG) << "inbound external message rejected by account " << addr.to_hex()
|
||||
<< " before smart-contract execution";
|
||||
|
||||
|
||||
auto res = impl_create_ordinary_transaction(msg_root, acc, now_, start_lt,
|
||||
&storage_phase_cfg_, &compute_phase_cfg_,
|
||||
&action_phase_cfg_,
|
||||
external, last_proc_int_msg_.first
|
||||
);
|
||||
if(res.is_error()) {
|
||||
auto error = res.move_as_error();
|
||||
if(error.code() == -701) {
|
||||
// ignorable errors
|
||||
LOG(DEBUG) << error.message();
|
||||
return {};
|
||||
}
|
||||
fatal_error("cannot unpack input message for a new transaction");
|
||||
return {};
|
||||
}
|
||||
if (trans->bounce_enabled) {
|
||||
if (!trans->prepare_storage_phase(storage_phase_cfg_, true)) {
|
||||
fatal_error("cannot create storage phase of a new transaction for smart contract "s + addr.to_hex());
|
||||
return {};
|
||||
}
|
||||
if (!external && !trans->prepare_credit_phase()) {
|
||||
fatal_error("cannot create credit phase of a new transaction for smart contract "s + addr.to_hex());
|
||||
return {};
|
||||
}
|
||||
} else {
|
||||
if (!external && !trans->prepare_credit_phase()) {
|
||||
fatal_error("cannot create credit phase of a new transaction for smart contract "s + addr.to_hex());
|
||||
return {};
|
||||
}
|
||||
if (!trans->prepare_storage_phase(storage_phase_cfg_, true, true)) {
|
||||
fatal_error("cannot create storage phase of a new transaction for smart contract "s + addr.to_hex());
|
||||
return {};
|
||||
}
|
||||
}
|
||||
if (!trans->prepare_compute_phase(compute_phase_cfg_)) {
|
||||
fatal_error("cannot create compute phase of a new transaction for smart contract "s + addr.to_hex());
|
||||
return {};
|
||||
}
|
||||
if (!trans->compute_phase->accepted) {
|
||||
if (external) {
|
||||
// inbound external message was not accepted
|
||||
LOG(DEBUG) << "inbound external message rejected by transaction " << addr.to_hex();
|
||||
return {};
|
||||
} else if (trans->compute_phase->skip_reason == block::ComputePhase::sk_none) {
|
||||
fatal_error("new ordinary transaction for smart contract "s + addr.to_hex() +
|
||||
" has not been accepted by the smart contract (?)");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
if (trans->compute_phase->success && !trans->prepare_action_phase(action_phase_cfg_)) {
|
||||
fatal_error("cannot create action phase of a new transaction for smart contract "s + addr.to_hex());
|
||||
return {};
|
||||
}
|
||||
if (trans->bounce_enabled && !trans->compute_phase->success && !trans->prepare_bounce_phase(action_phase_cfg_)) {
|
||||
fatal_error("cannot create bounce phase of a new transaction for smart contract "s + addr.to_hex());
|
||||
return {};
|
||||
}
|
||||
if (!trans->serialize()) {
|
||||
fatal_error("cannot serialize new transaction for smart contract "s + addr.to_hex());
|
||||
fatal_error(std::move(error));
|
||||
return {};
|
||||
}
|
||||
std::unique_ptr<block::Transaction> trans = res.move_as_ok();
|
||||
|
||||
if (!trans->update_limits(*block_limit_status_)) {
|
||||
fatal_error("cannot update block limit status to include the new transaction");
|
||||
return {};
|
||||
|
@ -2296,6 +2270,7 @@ Ref<vm::Cell> Collator::create_ordinary_transaction(Ref<vm::Cell> msg_root) {
|
|||
fatal_error("cannot commit new transaction for smart contract "s + addr.to_hex());
|
||||
return {};
|
||||
}
|
||||
|
||||
register_new_msgs(*trans);
|
||||
update_max_lt(acc->last_trans_end_lt_);
|
||||
// temporary patch to stop producing dangerous block
|
||||
|
@ -2305,6 +2280,75 @@ Ref<vm::Cell> Collator::create_ordinary_transaction(Ref<vm::Cell> msg_root) {
|
|||
return trans_root;
|
||||
}
|
||||
|
||||
// If td::status::error_code == 669 - Fatal Error block can not be produced
|
||||
// if td::status::error_code == 701 - Transaction can not be included into block, but it's ok (external or too early internal)
|
||||
td::Result<std::unique_ptr<block::Transaction>> Collator::impl_create_ordinary_transaction(Ref<vm::Cell> msg_root,
|
||||
block::Account* acc,
|
||||
UnixTime utime, LogicalTime lt,
|
||||
block::StoragePhaseConfig* storage_phase_cfg,
|
||||
block::ComputePhaseConfig* compute_phase_cfg,
|
||||
block::ActionPhaseConfig* action_phase_cfg,
|
||||
bool external, LogicalTime after_lt) {
|
||||
if (acc->last_trans_end_lt_ >= lt && acc->transactions.empty()) {
|
||||
return td::Status::Error(-669, PSTRING() << "last transaction time in the state of account " << acc->workchain << ":" << acc->addr.to_hex()
|
||||
<< " is too large");
|
||||
}
|
||||
auto trans_min_lt = lt;
|
||||
if (external) {
|
||||
// transactions processing external messages must have lt larger than all processed internal messages
|
||||
trans_min_lt = std::max(trans_min_lt, after_lt);
|
||||
}
|
||||
|
||||
std::unique_ptr<block::Transaction> trans =
|
||||
std::make_unique<block::Transaction>(*acc, block::Transaction::tr_ord, trans_min_lt + 1, utime, msg_root);
|
||||
bool ihr_delivered = false; // FIXME
|
||||
if (!trans->unpack_input_msg(ihr_delivered, action_phase_cfg)) {
|
||||
if (external) {
|
||||
// inbound external message was not accepted
|
||||
return td::Status::Error(-701,"inbound external message rejected by account "s + acc->addr.to_hex() +
|
||||
" before smart-contract execution");
|
||||
}
|
||||
return td::Status::Error(-669,"cannot unpack input message for a new transaction");
|
||||
}
|
||||
if (trans->bounce_enabled) {
|
||||
if (!trans->prepare_storage_phase(*storage_phase_cfg, true)) {
|
||||
return td::Status::Error(-669,"cannot create storage phase of a new transaction for smart contract "s + acc->addr.to_hex());
|
||||
}
|
||||
if (!external && !trans->prepare_credit_phase()) {
|
||||
return td::Status::Error(-669,"cannot create credit phase of a new transaction for smart contract "s + acc->addr.to_hex());
|
||||
}
|
||||
} else {
|
||||
if (!external && !trans->prepare_credit_phase()) {
|
||||
return td::Status::Error(-669,"cannot create credit phase of a new transaction for smart contract "s + acc->addr.to_hex());
|
||||
}
|
||||
if (!trans->prepare_storage_phase(*storage_phase_cfg, true, true)) {
|
||||
return td::Status::Error(-669,"cannot create storage phase of a new transaction for smart contract "s + acc->addr.to_hex());
|
||||
}
|
||||
}
|
||||
if (!trans->prepare_compute_phase(*compute_phase_cfg)) {
|
||||
return td::Status::Error(-669,"cannot create compute phase of a new transaction for smart contract "s + acc->addr.to_hex());
|
||||
}
|
||||
if (!trans->compute_phase->accepted) {
|
||||
if (external) {
|
||||
// inbound external message was not accepted
|
||||
return td::Status::Error(-701,"inbound external message rejected by transaction "s + acc->addr.to_hex());
|
||||
} else if (trans->compute_phase->skip_reason == block::ComputePhase::sk_none) {
|
||||
return td::Status::Error(-669,"new ordinary transaction for smart contract "s + acc->addr.to_hex() +
|
||||
" has not been accepted by the smart contract (?)");
|
||||
}
|
||||
}
|
||||
if (trans->compute_phase->success && !trans->prepare_action_phase(*action_phase_cfg)) {
|
||||
return td::Status::Error(-669,"cannot create action phase of a new transaction for smart contract "s + acc->addr.to_hex());
|
||||
}
|
||||
if (trans->bounce_enabled && !trans->compute_phase->success && !trans->prepare_bounce_phase(*action_phase_cfg)) {
|
||||
return td::Status::Error(-669,"cannot create bounce phase of a new transaction for smart contract "s + acc->addr.to_hex());
|
||||
}
|
||||
if (!trans->serialize()) {
|
||||
return td::Status::Error(-669,"cannot serialize new transaction for smart contract "s + acc->addr.to_hex());
|
||||
}
|
||||
return std::move(trans);
|
||||
}
|
||||
|
||||
void Collator::update_max_lt(ton::LogicalTime lt) {
|
||||
CHECK(lt >= start_lt);
|
||||
if (lt > max_lt) {
|
||||
|
|
|
@ -16,19 +16,25 @@
|
|||
|
||||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
|
||||
#include "external-message.hpp"
|
||||
#include "collator-impl.h"
|
||||
#include "vm/boc.h"
|
||||
#include "block/block-parse.h"
|
||||
#include "block/block-auto.h"
|
||||
#include "block/block-db.h"
|
||||
#include "fabric.h"
|
||||
#include "td/actor/actor.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "crypto/openssl/rand.hpp"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace validator {
|
||||
using td::Ref;
|
||||
|
||||
ExtMessageQ::ExtMessageQ(td::BufferSlice data, td::Ref<vm::Cell> root, AccountIdPrefixFull addr_prefix)
|
||||
: root_(std::move(root)), addr_prefix_(addr_prefix), data_(std::move(data)) {
|
||||
ExtMessageQ::ExtMessageQ(td::BufferSlice data, td::Ref<vm::Cell> root, AccountIdPrefixFull addr_prefix, ton::WorkchainId wc, ton::StdSmcAddress addr)
|
||||
: root_(std::move(root)), addr_prefix_(addr_prefix), data_(std::move(data)), wc_(wc), addr_(addr) {
|
||||
hash_ = block::compute_file_hash(data_);
|
||||
}
|
||||
|
||||
|
@ -70,7 +76,95 @@ td::Result<Ref<ExtMessageQ>> ExtMessageQ::create_ext_message(td::BufferSlice dat
|
|||
if (!dest_prefix.is_valid()) {
|
||||
return td::Status::Error("destination of an inbound external message is an invalid blockchain address");
|
||||
}
|
||||
return Ref<ExtMessageQ>{true, std::move(data), std::move(ext_msg), dest_prefix};
|
||||
ton::StdSmcAddress addr;
|
||||
ton::WorkchainId wc;
|
||||
if(!block::tlb::t_MsgAddressInt.extract_std_address(info.dest, wc, addr)) {
|
||||
return td::Status::Error(PSLICE() << "Can't parse destination address");
|
||||
}
|
||||
|
||||
return Ref<ExtMessageQ>{true, std::move(data), std::move(ext_msg), dest_prefix, wc, addr};
|
||||
}
|
||||
|
||||
void ExtMessageQ::run_message(td::BufferSlice data, td::actor::ActorId<ton::validator::ValidatorManager> manager,
|
||||
td::Promise<td::Unit> promise) {
|
||||
auto R = create_ext_message(std::move(data));
|
||||
if (R.is_error()) {
|
||||
return promise.set_error(R.move_as_error_prefix("failed to parse external message "));
|
||||
}
|
||||
auto M = R.move_as_ok();
|
||||
auto root = M->root_cell();
|
||||
block::gen::CommonMsgInfo::Record_ext_in_msg_info info;
|
||||
tlb::unpack_cell_inexact(root, info); // checked in create message
|
||||
ton::StdSmcAddress addr = M->addr();
|
||||
ton::WorkchainId wc = M->wc();
|
||||
|
||||
run_fetch_account_state(wc, addr, manager,
|
||||
[promise = std::move(promise), msg_root = root, wc = wc](td::Result<std::tuple<td::Ref<vm::CellSlice>,UnixTime,LogicalTime,std::unique_ptr<block::ConfigInfo>>> res) mutable {
|
||||
if (res.is_error()) {
|
||||
promise.set_error(td::Status::Error(PSLICE() << "Failed to get account state"));
|
||||
} else {
|
||||
auto tuple = res.move_as_ok();
|
||||
block::Account acc;
|
||||
auto shard_acc = std::move(std::get<0>(tuple));
|
||||
auto utime = std::get<1>(tuple);
|
||||
auto lt = std::get<2>(tuple);
|
||||
auto config = std::move(std::get<3>(tuple));
|
||||
if(!acc.unpack(shard_acc, {}, utime, false)) {
|
||||
promise.set_error(td::Status::Error(PSLICE() << "Failed to unpack account state"));
|
||||
} else {
|
||||
if(run_message_on_account(wc, &acc, utime, lt + 1, msg_root, std::move(config))) {
|
||||
promise.set_value(td::Unit());
|
||||
} else {
|
||||
promise.set_error(td::Status::Error(PSLICE() << "External message was not accepted"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
bool ExtMessageQ::run_message_on_account(ton::WorkchainId wc,
|
||||
block::Account* acc,
|
||||
UnixTime utime, LogicalTime lt,
|
||||
td::Ref<vm::Cell> msg_root,
|
||||
std::unique_ptr<block::ConfigInfo> config) {
|
||||
|
||||
Ref<vm::Cell> old_mparams;
|
||||
std::vector<block::StoragePrices> storage_prices_;
|
||||
block::StoragePhaseConfig storage_phase_cfg_{&storage_prices_};
|
||||
td::BitArray<256> rand_seed_;
|
||||
block::ComputePhaseConfig compute_phase_cfg_;
|
||||
block::ActionPhaseConfig action_phase_cfg_;
|
||||
td::RefInt256 masterchain_create_fee, basechain_create_fee;
|
||||
|
||||
auto fetch_res = Collator::impl_fetch_config_params(std::move(config), &old_mparams,
|
||||
&storage_prices_, &storage_phase_cfg_,
|
||||
&rand_seed_, &compute_phase_cfg_,
|
||||
&action_phase_cfg_, &masterchain_create_fee,
|
||||
&basechain_create_fee, wc);
|
||||
if(fetch_res.is_error()) {
|
||||
auto error = fetch_res.move_as_error();
|
||||
LOG(DEBUG) << "Cannot fetch config params" << error.message();
|
||||
return false;
|
||||
}
|
||||
|
||||
auto res = Collator::impl_create_ordinary_transaction(msg_root, acc, utime, lt,
|
||||
&storage_phase_cfg_, &compute_phase_cfg_,
|
||||
&action_phase_cfg_,
|
||||
true, lt);
|
||||
if(res.is_error()) {
|
||||
auto error = res.move_as_error();
|
||||
LOG(DEBUG) << "Cannot run message on account" << error.message();
|
||||
return false;
|
||||
}
|
||||
std::unique_ptr<block::Transaction> trans = res.move_as_ok();
|
||||
|
||||
auto trans_root = trans->commit(*acc);
|
||||
if (trans_root.is_null()) {
|
||||
LOG(DEBUG) << "cannot commit new transaction for smart contract ";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace validator
|
||||
|
|
|
@ -18,9 +18,11 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "interfaces/validator-manager.h"
|
||||
#include "validator/interfaces/external-message.h"
|
||||
#include "auto/tl/ton_api.h"
|
||||
#include "adnl/utils.hpp"
|
||||
#include "block/transaction.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
|
@ -31,6 +33,8 @@ class ExtMessageQ : public ExtMessage {
|
|||
AccountIdPrefixFull addr_prefix_;
|
||||
td::BufferSlice data_;
|
||||
Hash hash_;
|
||||
ton::WorkchainId wc_;
|
||||
ton::StdSmcAddress addr_;
|
||||
|
||||
public:
|
||||
static constexpr unsigned max_ext_msg_size = 65535;
|
||||
|
@ -47,8 +51,23 @@ class ExtMessageQ : public ExtMessage {
|
|||
Hash hash() const override {
|
||||
return hash_;
|
||||
}
|
||||
ExtMessageQ(td::BufferSlice data, td::Ref<vm::Cell> root, AccountIdPrefixFull shard);
|
||||
ton::WorkchainId wc() const override {
|
||||
return wc_;
|
||||
}
|
||||
|
||||
ton::StdSmcAddress addr() const override {
|
||||
return addr_;
|
||||
}
|
||||
|
||||
ExtMessageQ(td::BufferSlice data, td::Ref<vm::Cell> root, AccountIdPrefixFull shard, ton::WorkchainId wc, ton::StdSmcAddress addr);
|
||||
static td::Result<td::Ref<ExtMessageQ>> create_ext_message(td::BufferSlice data);
|
||||
static void run_message(td::BufferSlice data, td::actor::ActorId<ton::validator::ValidatorManager> manager,
|
||||
td::Promise<td::Unit> promise);
|
||||
static bool run_message_on_account(ton::WorkchainId wc,
|
||||
block::Account* acc,
|
||||
UnixTime utime, LogicalTime lt,
|
||||
td::Ref<vm::Cell> msg_root,
|
||||
std::unique_ptr<block::ConfigInfo> config);
|
||||
};
|
||||
|
||||
} // namespace validator
|
||||
|
|
|
@ -116,6 +116,10 @@ td::Result<td::Ref<ExtMessage>> create_ext_message(td::BufferSlice data) {
|
|||
return std::move(res);
|
||||
}
|
||||
|
||||
void run_check_external_message(td::BufferSlice data, td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise) {
|
||||
ExtMessageQ::run_message(std::move(data), std::move(manager), std::move(promise));
|
||||
}
|
||||
|
||||
td::Result<td::Ref<IhrMessage>> create_ihr_message(td::BufferSlice data) {
|
||||
TRY_RESULT(res, IhrMessageQ::create_ihr_message(std::move(data)));
|
||||
return std::move(res);
|
||||
|
@ -237,6 +241,11 @@ void run_liteserver_query(td::BufferSlice data, td::actor::ActorId<ValidatorMana
|
|||
LiteQuery::run_query(std::move(data), std::move(manager), std::move(promise));
|
||||
}
|
||||
|
||||
void run_fetch_account_state(WorkchainId wc, StdSmcAddress addr, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Promise<std::tuple<td::Ref<vm::CellSlice>,UnixTime,LogicalTime,std::unique_ptr<block::ConfigInfo>>> promise) {
|
||||
LiteQuery::fetch_account_state(wc, addr, std::move(manager), std::move(promise));
|
||||
}
|
||||
|
||||
void run_validate_shard_block_description(td::BufferSlice data, BlockHandle masterchain_block,
|
||||
td::Ref<MasterchainState> masterchain_state,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
|
|
|
@ -58,15 +58,28 @@ void LiteQuery::run_query(td::BufferSlice data, td::actor::ActorId<ValidatorMana
|
|||
td::actor::create_actor<LiteQuery>("litequery", std::move(data), std::move(manager), std::move(promise)).release();
|
||||
}
|
||||
|
||||
void LiteQuery::fetch_account_state(WorkchainId wc, StdSmcAddress acc_addr, td::actor::ActorId<ton::validator::ValidatorManager> manager,
|
||||
td::Promise<std::tuple<td::Ref<vm::CellSlice>,UnixTime,LogicalTime,std::unique_ptr<block::ConfigInfo>>> promise) {
|
||||
td::actor::create_actor<LiteQuery>("litequery", wc, acc_addr, std::move(manager), std::move(promise)).release();
|
||||
}
|
||||
|
||||
LiteQuery::LiteQuery(td::BufferSlice data, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Promise<td::BufferSlice> promise)
|
||||
: query_(std::move(data)), manager_(std::move(manager)), promise_(std::move(promise)) {
|
||||
timeout_ = td::Timestamp::in(default_timeout_msec * 0.001);
|
||||
}
|
||||
|
||||
LiteQuery::LiteQuery(WorkchainId wc, StdSmcAddress acc_addr, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Promise<std::tuple<td::Ref<vm::CellSlice>,UnixTime,LogicalTime,std::unique_ptr<block::ConfigInfo>>> promise)
|
||||
: manager_(std::move(manager)), acc_state_promise_(std::move(promise)), acc_workchain_(wc), acc_addr_(acc_addr) {
|
||||
timeout_ = td::Timestamp::in(default_timeout_msec * 0.001);
|
||||
}
|
||||
|
||||
void LiteQuery::abort_query(td::Status reason) {
|
||||
LOG(INFO) << "aborted liteserver query: " << reason.to_string();
|
||||
if (promise_) {
|
||||
if (acc_state_promise_) {
|
||||
acc_state_promise_.set_error(std::move(reason));
|
||||
} else if (promise_) {
|
||||
promise_.set_error(std::move(reason));
|
||||
}
|
||||
stop();
|
||||
|
@ -111,6 +124,11 @@ bool LiteQuery::finish_query(td::BufferSlice result) {
|
|||
void LiteQuery::start_up() {
|
||||
alarm_timestamp() = timeout_;
|
||||
|
||||
if(acc_state_promise_) {
|
||||
td::actor::send_closure_later(actor_id(this),&LiteQuery::perform_fetchAccountState);
|
||||
return;
|
||||
}
|
||||
|
||||
auto F = fetch_tl_object<ton::lite_api::Function>(std::move(query_), true);
|
||||
if (F.is_error()) {
|
||||
abort_query(F.move_as_error());
|
||||
|
@ -205,17 +223,23 @@ void LiteQuery::perform_getMasterchainInfo(int mode) {
|
|||
}
|
||||
td::actor::send_closure_later(
|
||||
manager_, &ton::validator::ValidatorManager::get_top_masterchain_state_block,
|
||||
[Self = actor_id(this), mode](td::Result<std::pair<Ref<ton::validator::MasterchainState>, BlockIdExt>> res) {
|
||||
[Self = actor_id(this), return_state = bool(acc_state_promise_), mode](td::Result<std::pair<Ref<ton::validator::MasterchainState>, BlockIdExt>> res) {
|
||||
if (res.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query, res.move_as_error());
|
||||
} else {
|
||||
auto pair = res.move_as_ok();
|
||||
td::actor::send_closure_later(Self, &LiteQuery::continue_getMasterchainInfo, std::move(pair.first),
|
||||
auto func = return_state ? &LiteQuery::gotMasterchainInfoForAccountState : &LiteQuery::continue_getMasterchainInfo;
|
||||
td::actor::send_closure_later(Self, func, std::move(pair.first),
|
||||
pair.second, mode);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void LiteQuery::gotMasterchainInfoForAccountState(Ref<ton::validator::MasterchainState> mc_state, BlockIdExt blkid,
|
||||
int mode) {
|
||||
perform_getAccountState(blkid, acc_workchain_, acc_addr_, 0x80000000);
|
||||
}
|
||||
|
||||
void LiteQuery::continue_getMasterchainInfo(Ref<ton::validator::MasterchainState> mc_state, BlockIdExt blkid,
|
||||
int mode) {
|
||||
LOG(INFO) << "obtained data for getMasterchainInfo() : last block = " << blkid.to_str();
|
||||
|
@ -431,15 +455,25 @@ void LiteQuery::continue_getZeroState(BlockIdExt blkid, td::BufferSlice state) {
|
|||
|
||||
void LiteQuery::perform_sendMessage(td::BufferSlice data) {
|
||||
LOG(INFO) << "started a sendMessage(<" << data.size() << " bytes>) liteserver query";
|
||||
auto res = ton::validator::create_ext_message(std::move(data));
|
||||
if (res.is_error()) {
|
||||
abort_query(res.move_as_error());
|
||||
return;
|
||||
}
|
||||
LOG(INFO) << "sending an external message to validator manager";
|
||||
td::actor::send_closure_later(manager_, &ValidatorManager::send_external_message, res.move_as_ok());
|
||||
auto b = ton::create_serialize_tl_object<ton::lite_api::liteServer_sendMsgStatus>(1);
|
||||
finish_query(std::move(b));
|
||||
td::actor::send_closure_later(
|
||||
manager_, &ValidatorManager::check_external_message, data.clone(),
|
||||
[Self = actor_id(this), data = std::move(data), manager = manager_](td::Result<td::Unit> res) {
|
||||
if(res.is_error()) {
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query,
|
||||
res.move_as_error_prefix("cannot apply external message to current state : "s));
|
||||
} else {
|
||||
auto crm = ton::validator::create_ext_message(data.clone());
|
||||
if (crm.is_error()) {
|
||||
//UNREACHABLE, checks in check_external_message,
|
||||
td::actor::send_closure(Self, &LiteQuery::abort_query,
|
||||
crm.move_as_error());
|
||||
}
|
||||
LOG(INFO) << "sending an external message to validator manager";
|
||||
td::actor::send_closure_later(manager, &ValidatorManager::send_external_message, crm.move_as_ok());
|
||||
auto b = ton::create_serialize_tl_object<ton::lite_api::liteServer_sendMsgStatus>(1);
|
||||
td::actor::send_closure(Self, &LiteQuery::finish_query, std::move(b));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool LiteQuery::request_mc_block_data(BlockIdExt blkid) {
|
||||
|
@ -702,6 +736,10 @@ void LiteQuery::continue_getAccountState_0(Ref<ton::validator::MasterchainState>
|
|||
request_mc_block_data(blkid);
|
||||
}
|
||||
|
||||
void LiteQuery::perform_fetchAccountState() {
|
||||
perform_getMasterchainInfo(-1);
|
||||
}
|
||||
|
||||
void LiteQuery::perform_runSmcMethod(BlockIdExt blkid, WorkchainId workchain, StdSmcAddress addr, int mode,
|
||||
td::int64 method_id, td::BufferSlice params) {
|
||||
LOG(INFO) << "started a runSmcMethod(" << blkid.to_str() << ", " << workchain << ", " << addr.to_hex() << ", "
|
||||
|
@ -1010,6 +1048,19 @@ void LiteQuery::finish_getAccountState(td::BufferSlice shard_proof) {
|
|||
}
|
||||
vm::AugmentedDictionary accounts_dict{vm::load_cell_slice_ref(sstate.accounts), 256, block::tlb::aug_ShardAccounts};
|
||||
auto acc_csr = accounts_dict.lookup(acc_addr_);
|
||||
if (mode_ & 0x80000000) {
|
||||
auto config = block::ConfigInfo::extract_config(mc_state_->root_cell(), 0xFFFF);
|
||||
if (config.is_error()) {
|
||||
fatal_error(config.move_as_error());
|
||||
return;
|
||||
}
|
||||
auto rconfig = config.move_as_ok();
|
||||
acc_state_promise_.set_value(std::make_tuple(
|
||||
std::move(acc_csr), sstate.gen_utime, sstate.gen_lt, std::move(rconfig)
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<vm::Cell> acc_root;
|
||||
if (acc_csr.not_null()) {
|
||||
acc_root = acc_csr->prefetch_ref();
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include "block.hpp"
|
||||
#include "shard.hpp"
|
||||
#include "proof.hpp"
|
||||
#include "block/block-auto.h"
|
||||
|
||||
|
||||
namespace ton {
|
||||
|
||||
|
@ -37,6 +39,9 @@ class LiteQuery : public td::actor::Actor {
|
|||
td::actor::ActorId<ton::validator::ValidatorManager> manager_;
|
||||
td::Timestamp timeout_;
|
||||
td::Promise<td::BufferSlice> promise_;
|
||||
|
||||
td::Promise<std::tuple<td::Ref<vm::CellSlice>,UnixTime,LogicalTime,std::unique_ptr<block::ConfigInfo>>> acc_state_promise_;
|
||||
|
||||
int pending_{0};
|
||||
int mode_{0};
|
||||
WorkchainId acc_workchain_;
|
||||
|
@ -71,9 +76,14 @@ class LiteQuery : public td::actor::Actor {
|
|||
}; // version 1.1; +1 = build block proof chains, +2 = masterchainInfoExt, +4 = runSmcMethod
|
||||
LiteQuery(td::BufferSlice data, td::actor::ActorId<ton::validator::ValidatorManager> manager,
|
||||
td::Promise<td::BufferSlice> promise);
|
||||
LiteQuery(WorkchainId wc, StdSmcAddress acc_addr, td::actor::ActorId<ton::validator::ValidatorManager> manager,
|
||||
td::Promise<std::tuple<td::Ref<vm::CellSlice>,UnixTime,LogicalTime,std::unique_ptr<block::ConfigInfo>>> promise);
|
||||
static void run_query(td::BufferSlice data, td::actor::ActorId<ton::validator::ValidatorManager> manager,
|
||||
td::Promise<td::BufferSlice> promise);
|
||||
|
||||
static void fetch_account_state(WorkchainId wc, StdSmcAddress acc_addr, td::actor::ActorId<ton::validator::ValidatorManager> manager,
|
||||
td::Promise<std::tuple<td::Ref<vm::CellSlice>,UnixTime,LogicalTime,std::unique_ptr<block::ConfigInfo>>> promise);
|
||||
|
||||
private:
|
||||
bool fatal_error(td::Status error);
|
||||
bool fatal_error(std::string err_msg, int err_code = -400);
|
||||
|
@ -87,6 +97,7 @@ class LiteQuery : public td::actor::Actor {
|
|||
void perform_getVersion();
|
||||
void perform_getMasterchainInfo(int mode);
|
||||
void continue_getMasterchainInfo(Ref<MasterchainState> mc_state, BlockIdExt blkid, int mode);
|
||||
void gotMasterchainInfoForAccountState(Ref<MasterchainState> mc_state, BlockIdExt blkid, int mode);
|
||||
void perform_getBlock(BlockIdExt blkid);
|
||||
void continue_getBlock(BlockIdExt blkid, Ref<BlockData> block);
|
||||
void perform_getBlockHeader(BlockIdExt blkid, int mode);
|
||||
|
@ -99,6 +110,7 @@ class LiteQuery : public td::actor::Actor {
|
|||
void continue_getAccountState_0(Ref<MasterchainState> mc_state, BlockIdExt blkid);
|
||||
void continue_getAccountState();
|
||||
void finish_getAccountState(td::BufferSlice shard_proof);
|
||||
void perform_fetchAccountState();
|
||||
void perform_runSmcMethod(BlockIdExt blkid, WorkchainId workchain, StdSmcAddress addr, int mode, td::int64 method_id,
|
||||
td::BufferSlice params);
|
||||
void finish_runSmcMethod(td::BufferSlice shard_proof, td::BufferSlice state_proof, Ref<vm::Cell> acc_root,
|
||||
|
|
|
@ -35,6 +35,8 @@ class ExtMessage : public td::CntObject {
|
|||
virtual td::BufferSlice serialize() const = 0;
|
||||
virtual td::Ref<vm::Cell> root_cell() const = 0;
|
||||
virtual Hash hash() const = 0;
|
||||
virtual ton::WorkchainId wc() const = 0;
|
||||
virtual ton::StdSmcAddress addr() const = 0;
|
||||
};
|
||||
|
||||
} // namespace validator
|
||||
|
|
|
@ -374,13 +374,25 @@ void ValidatorManagerImpl::new_external_message(td::BufferSlice data) {
|
|||
VLOG(VALIDATOR_NOTICE) << "dropping bad ihr message: " << R.move_as_error();
|
||||
return;
|
||||
}
|
||||
auto M = std::make_unique<MessageExt<ExtMessage>>(R.move_as_ok());
|
||||
auto id = M->ext_id();
|
||||
if (ext_messages_hashes_.count(id.hash) == 0) {
|
||||
ext_messages_.emplace(id, std::move(M));
|
||||
ext_messages_hashes_.emplace(id.hash, id);
|
||||
add_external_message(R.move_as_ok());
|
||||
}
|
||||
|
||||
void ValidatorManagerImpl::add_external_message(td::Ref<ExtMessage> msg) {
|
||||
auto message = std::make_unique<MessageExt<ExtMessage>>(msg);
|
||||
auto id = message->ext_id();
|
||||
auto address = message->address();
|
||||
unsigned long per_address_limit = 256;
|
||||
if(ext_addr_messages_.count(address) < per_address_limit) {
|
||||
if (ext_messages_hashes_.count(id.hash) == 0) {
|
||||
ext_messages_.emplace(id, std::move(message));
|
||||
ext_messages_hashes_.emplace(id.hash, id);
|
||||
ext_addr_messages_[address].emplace(id.hash, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
void ValidatorManagerImpl::check_external_message(td::BufferSlice data, td::Promise<td::Unit> promise) {
|
||||
run_check_external_message(std::move(data), actor_id(this), std::move(promise));
|
||||
}
|
||||
|
||||
void ValidatorManagerImpl::new_ihr_message(td::BufferSlice data) {
|
||||
if (!is_validator()) {
|
||||
|
@ -759,6 +771,7 @@ void ValidatorManagerImpl::get_external_messages(ShardIdFull shard,
|
|||
break;
|
||||
}
|
||||
if (it->second->expired()) {
|
||||
ext_addr_messages_[it->second->address()].erase(it->first.hash);
|
||||
ext_messages_hashes_.erase(it->first.hash);
|
||||
it = ext_messages_.erase(it);
|
||||
continue;
|
||||
|
@ -807,17 +820,20 @@ void ValidatorManagerImpl::complete_external_messages(std::vector<ExtMessage::Ha
|
|||
for (auto &hash : to_delete) {
|
||||
auto it = ext_messages_hashes_.find(hash);
|
||||
if (it != ext_messages_hashes_.end()) {
|
||||
ext_addr_messages_[ext_messages_[it->second]->address()].erase(it->first);
|
||||
CHECK(ext_messages_.erase(it->second));
|
||||
ext_messages_hashes_.erase(it);
|
||||
}
|
||||
}
|
||||
unsigned long soft_mempool_limit = 1024;
|
||||
for (auto &hash : to_delay) {
|
||||
auto it = ext_messages_hashes_.find(hash);
|
||||
if (it != ext_messages_hashes_.end()) {
|
||||
auto it2 = ext_messages_.find(it->second);
|
||||
if (it2->second->can_postpone()) {
|
||||
if ((ext_messages_.size() < soft_mempool_limit) && it2->second->can_postpone()) {
|
||||
it2->second->postpone();
|
||||
} else {
|
||||
ext_addr_messages_[it2->second->address()].erase(it2->first.hash);
|
||||
ext_messages_.erase(it2);
|
||||
ext_messages_hashes_.erase(it);
|
||||
}
|
||||
|
@ -1352,6 +1368,7 @@ void ValidatorManagerImpl::send_get_next_key_blocks_request(BlockIdExt block_id,
|
|||
|
||||
void ValidatorManagerImpl::send_external_message(td::Ref<ExtMessage> message) {
|
||||
callback_->send_ext_message(message->shard(), message->serialize());
|
||||
add_external_message(std::move(message));
|
||||
}
|
||||
|
||||
void ValidatorManagerImpl::send_ihr_message(td::Ref<IhrMessage> message) {
|
||||
|
|
|
@ -74,6 +74,9 @@ class MessageExt {
|
|||
auto hash() const {
|
||||
return message_->hash();
|
||||
}
|
||||
auto address() const {
|
||||
return std::make_pair(message_->wc(), message_->addr());
|
||||
}
|
||||
bool is_active() {
|
||||
if (!active_) {
|
||||
if (reactivate_at_.is_in_past()) {
|
||||
|
@ -210,6 +213,7 @@ class ValidatorManagerImpl : public ValidatorManager {
|
|||
// DATA FOR COLLATOR
|
||||
std::map<ShardTopBlockDescriptionId, td::Ref<ShardTopBlockDescription>> shard_blocks_;
|
||||
std::map<MessageId<ExtMessage>, std::unique_ptr<MessageExt<ExtMessage>>> ext_messages_;
|
||||
std::map<std::pair<ton::WorkchainId,ton::StdSmcAddress>, std::map<ExtMessage::Hash, MessageId<ExtMessage>>> ext_addr_messages_;
|
||||
std::map<ExtMessage::Hash, MessageId<ExtMessage>> ext_messages_hashes_;
|
||||
// IHR ?
|
||||
std::map<MessageId<IhrMessage>, std::unique_ptr<MessageExt<IhrMessage>>> ihr_messages_;
|
||||
|
@ -327,9 +331,9 @@ class ValidatorManagerImpl : public ValidatorManager {
|
|||
//void get_block_description(BlockIdExt block_id, td::Promise<BlockDescription> promise) override;
|
||||
|
||||
void new_external_message(td::BufferSlice data) override;
|
||||
void check_external_message(td::BufferSlice data, td::Promise<td::Unit> promise) override {
|
||||
promise.set_value(td::Unit());
|
||||
}
|
||||
void add_external_message(td::Ref<ExtMessage> message);
|
||||
void check_external_message(td::BufferSlice data, td::Promise<td::Unit> promise) override;
|
||||
|
||||
void new_ihr_message(td::BufferSlice data) override;
|
||||
void new_shard_block(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data) override;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue