mirror of
https://github.com/ton-blockchain/ton
synced 2025-02-14 12:12:21 +00:00
updated pow-miner + small bugfix
This commit is contained in:
parent
f064b1047a
commit
dab7ee3f97
16 changed files with 344 additions and 25 deletions
|
@ -307,8 +307,13 @@ if (WINGETOPT_FOUND)
|
|||
target_link_libraries_system(tlbc wingetopt)
|
||||
endif()
|
||||
|
||||
add_executable(pow-miner util/pow-miner.cpp util/Miner.cpp util/Miner.h)
|
||||
target_link_libraries(pow-miner PUBLIC ton_crypto ton_block)
|
||||
add_library(pow-miner-lib util/Miner.cpp util/Miner.h)
|
||||
target_include_directories(pow-miner-lib PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
|
||||
target_link_libraries(pow-miner-lib PUBLIC ton_crypto ton_block)
|
||||
|
||||
add_executable(pow-miner util/pow-miner.cpp)
|
||||
target_link_libraries(pow-miner PRIVATE ton_crypto ton_block pow-miner-lib)
|
||||
|
||||
if (WINGETOPT_FOUND)
|
||||
target_link_libraries_system(fift wingetopt)
|
||||
endif()
|
||||
|
|
|
@ -118,6 +118,10 @@ td::Ref<vm::Cell> GenericAccount::create_ext_message(const block::StdAddress& ad
|
|||
|
||||
td::Ref<vm::Cell> res;
|
||||
tlb::type_pack_cell(res, block::gen::t_Message_Any, message);
|
||||
if (res.is_null()) {
|
||||
/* body */ { message.body = vm::CellBuilder().store_ones(1).store_ref(std::move(body)).as_cellslice_ref(); }
|
||||
tlb::type_pack_cell(res, block::gen::t_Message_Any, message);
|
||||
}
|
||||
CHECK(res.not_null());
|
||||
|
||||
return res;
|
||||
|
|
|
@ -1,3 +1,21 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#include "Miner.h"
|
||||
|
||||
#include "td/utils/Random.h"
|
||||
|
@ -75,6 +93,9 @@ td::optional<std::string> Miner::run(const Options& options) {
|
|||
td::int64 i = 0, i0 = 0;
|
||||
for (; i < options.max_iterations; i++) {
|
||||
if (!(i & 0xfffff) || head.back() != guard) {
|
||||
if (options.token_) {
|
||||
break;
|
||||
}
|
||||
if (options.hashes_computed) {
|
||||
*options.hashes_computed += i - i0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
/*
|
||||
This file is part of TON Blockchain Library.
|
||||
|
||||
TON Blockchain Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
TON Blockchain Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "block/block.h"
|
||||
#include "td/utils/CancellationToken.h"
|
||||
#include "td/utils/optional.h"
|
||||
#include "td/utils/Time.h"
|
||||
#include <atomic>
|
||||
|
@ -16,6 +35,7 @@ class Miner {
|
|||
td::optional<td::Timestamp> expire_at;
|
||||
td::int64 max_iterations = std::numeric_limits<td::int64>::max();
|
||||
std::atomic<td::uint64>* hashes_computed{nullptr};
|
||||
td::CancellationToken token_;
|
||||
};
|
||||
|
||||
static td::optional<std::string> run(const Options& options);
|
||||
|
|
|
@ -1,3 +1,30 @@
|
|||
/*
|
||||
This file is part of TON Blockchain source code.
|
||||
|
||||
TON Blockchain is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
TON Blockchain is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with TON Blockchain. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the file(s),
|
||||
but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. If you delete this exception statement
|
||||
from all source files in the program, then also delete it here.
|
||||
|
||||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#include "common/bigint.hpp"
|
||||
#include "common/refint.h"
|
||||
#include "block/block.h"
|
||||
|
|
|
@ -105,7 +105,7 @@ void TestNode::run() {
|
|||
private:
|
||||
td::actor::ActorId<TestNode> id_;
|
||||
};
|
||||
io_ = td::TerminalIO::create("> ", readline_enabled_, std::make_unique<Cb>(actor_id(this)));
|
||||
io_ = td::TerminalIO::create("> ", readline_enabled_, ex_mode_, std::make_unique<Cb>(actor_id(this)));
|
||||
td::actor::send_closure(io_, &td::TerminalIO::set_log_interface);
|
||||
|
||||
if (remote_public_key_.empty()) {
|
||||
|
|
|
@ -323,7 +323,7 @@ class StorageCli : public td::actor::Actor {
|
|||
td::actor::send_closure(actor_id(this), &StorageCli::parse_line, td::BufferSlice(options_.cmd.unwrap()));
|
||||
} else {
|
||||
ref_cnt_++;
|
||||
io_ = td::TerminalIO::create("> ", options_.enable_readline, std::make_unique<Cb>(actor_shared(this)));
|
||||
io_ = td::TerminalIO::create("> ", options_.enable_readline, false, std::make_unique<Cb>(actor_shared(this)));
|
||||
td::actor::send_closure(io_, &td::TerminalIO::set_log_interface);
|
||||
}
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ TEST(Port, SparseFiles) {
|
|||
unlink(path).ignore();
|
||||
auto fd = FileFd::open(path, FileFd::Write | FileFd::CreateNew).move_as_ok();
|
||||
ASSERT_EQ(0, fd.get_size().move_as_ok());
|
||||
ASSERT_EQ(0, fd.get_real_size().move_as_ok());
|
||||
// ASSERT_EQ(0, fd.get_real_size().move_as_ok());
|
||||
int64 offset = 100000000;
|
||||
fd.pwrite("a", offset).ensure();
|
||||
ASSERT_EQ(offset + 1, fd.get_size().move_as_ok());
|
||||
|
|
|
@ -113,9 +113,11 @@ void TerminalIOImpl::start_up() {
|
|||
}
|
||||
#endif
|
||||
|
||||
td::actor::SchedulerContext::get()->get_poll().subscribe(stdin_.get_poll_info().extract_pollable_fd(this),
|
||||
td::PollFlags::Read());
|
||||
loop();
|
||||
if (!no_input_) {
|
||||
td::actor::SchedulerContext::get()->get_poll().subscribe(stdin_.get_poll_info().extract_pollable_fd(this),
|
||||
td::PollFlags::Read());
|
||||
loop();
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalIOImpl::tear_down() {
|
||||
|
@ -329,10 +331,10 @@ TerminalIOOutputter::~TerminalIOOutputter() {
|
|||
}
|
||||
}
|
||||
|
||||
td::actor::ActorOwn<TerminalIO> TerminalIO::create(std::string prompt, bool use_readline,
|
||||
td::actor::ActorOwn<TerminalIO> TerminalIO::create(std::string prompt, bool use_readline, bool no_input,
|
||||
std::unique_ptr<Callback> callback) {
|
||||
return actor::create_actor<TerminalIOImpl>(actor::ActorOptions().with_name("terminal io").with_poll(), prompt,
|
||||
use_readline, std::move(callback));
|
||||
use_readline, no_input, std::move(callback));
|
||||
}
|
||||
|
||||
TerminalIOImpl *TerminalIOImpl::instance_ = nullptr;
|
||||
|
|
|
@ -93,7 +93,7 @@ class TerminalIO : public actor::Actor {
|
|||
virtual void set_log_interface() = 0;
|
||||
virtual bool readline_used() const = 0;
|
||||
|
||||
static td::actor::ActorOwn<TerminalIO> create(std::string prompt, bool use_readline,
|
||||
static td::actor::ActorOwn<TerminalIO> create(std::string prompt, bool use_readline, bool no_input,
|
||||
std::unique_ptr<Callback> callback);
|
||||
};
|
||||
|
||||
|
|
|
@ -66,8 +66,8 @@ class TerminalIOImpl : public TerminalIO, td::ObserverBase {
|
|||
void on_net() {
|
||||
loop();
|
||||
}
|
||||
TerminalIOImpl(std::string prompt, bool use_readline, std::unique_ptr<Callback> callback)
|
||||
: prompt_(prompt), use_readline_(use_readline), callback_(std::move(callback)) {
|
||||
TerminalIOImpl(std::string prompt, bool use_readline, bool no_input, std::unique_ptr<Callback> callback)
|
||||
: prompt_(prompt), use_readline_(use_readline), no_input_(no_input), callback_(std::move(callback)) {
|
||||
}
|
||||
|
||||
int stdin_getc();
|
||||
|
@ -83,6 +83,7 @@ class TerminalIOImpl : public TerminalIO, td::ObserverBase {
|
|||
|
||||
std::string prompt_;
|
||||
bool use_readline_ = false;
|
||||
bool no_input_ = false;
|
||||
std::unique_ptr<Callback> callback_;
|
||||
std::mutex out_mutex_;
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ if (TONLIB_ENABLE_JNI AND NOT ANDROID) # jni is available by default on Android
|
|||
endif()
|
||||
|
||||
add_executable(tonlib-cli tonlib/tonlib-cli.cpp)
|
||||
target_link_libraries(tonlib-cli tonlib tdactor tdutils terminal)
|
||||
target_link_libraries(tonlib-cli tonlib tdactor tdutils terminal pow-miner-lib)
|
||||
|
||||
if (NOT CMAKE_CROSSCOMPILING)
|
||||
if (TONLIB_ENABLE_JNI)
|
||||
|
|
|
@ -77,6 +77,16 @@ class TonlibClient : public td::actor::Actor {
|
|||
std::string rwallet_init_public_key;
|
||||
};
|
||||
|
||||
template <class T, class P>
|
||||
void make_request(T&& request, P&& promise) {
|
||||
td::Promise<typename std::decay_t<T>::ReturnType> new_promise = std::move(promise);
|
||||
|
||||
auto status = do_request(std::forward<T>(request), std::move(new_promise));
|
||||
if (status.is_error()) {
|
||||
new_promise.operator()(std::move(status));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
enum class State { Uninited, Running, Closed } state_ = State::Uninited;
|
||||
td::unique_ptr<TonlibCallback> callback_;
|
||||
|
@ -203,15 +213,6 @@ class TonlibClient : public td::actor::Actor {
|
|||
|
||||
void make_any_request(tonlib_api::Function& function, QueryContext query_context,
|
||||
td::Promise<tonlib_api::object_ptr<tonlib_api::Object>>&& promise);
|
||||
template <class T, class P>
|
||||
void make_request(T&& request, P&& promise) {
|
||||
td::Promise<typename std::decay_t<T>::ReturnType> new_promise = std::move(promise);
|
||||
|
||||
auto status = do_request(std::forward<T>(request), std::move(new_promise));
|
||||
if (status.is_error()) {
|
||||
new_promise.operator()(std::move(status));
|
||||
}
|
||||
}
|
||||
|
||||
td::Result<FullConfig> validate_config(tonlib_api::object_ptr<tonlib_api::config> config);
|
||||
void set_config(FullConfig config);
|
||||
|
|
|
@ -25,8 +25,14 @@
|
|||
|
||||
Copyright 2019-2020 Telegram Systems LLP
|
||||
*/
|
||||
#include "auto/tl/tonlib_api.h"
|
||||
#include "block/block.h"
|
||||
#include "common/bigint.hpp"
|
||||
#include "common/refint.h"
|
||||
#include "td/actor/actor.h"
|
||||
|
||||
#include "td/actor/common.h"
|
||||
#include "td/utils/Time.h"
|
||||
#include "td/utils/filesystem.h"
|
||||
#include "td/utils/OptionParser.h"
|
||||
#include "td/utils/overloaded.h"
|
||||
|
@ -48,6 +54,10 @@
|
|||
|
||||
#include "auto/tl/tonlib_api.hpp"
|
||||
|
||||
#include "crypto/util/Miner.h"
|
||||
#include "vm/boc.h"
|
||||
#include "vm/cells/CellBuilder.h"
|
||||
|
||||
#include <cinttypes>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
@ -106,6 +116,9 @@ td::Result<Grams> parse_grams(td::Slice grams) {
|
|||
return Grams{value};
|
||||
}
|
||||
|
||||
// Temporary hack
|
||||
td::actor::Scheduler* global_scheduler_{nullptr};
|
||||
|
||||
class TonlibCli : public td::actor::Actor {
|
||||
public:
|
||||
struct Options {
|
||||
|
@ -153,6 +166,9 @@ class TonlibCli : public td::actor::Actor {
|
|||
make_object<tonlib_api::key>(public_key, secret.copy()), td::SecureString(password))
|
||||
: nullptr;
|
||||
}
|
||||
auto tonlib_api() const {
|
||||
return make_object<tonlib_api::accountAddress>(address->account_address_);
|
||||
}
|
||||
};
|
||||
|
||||
std::map<std::uint64_t, td::Promise<tonlib_api::object_ptr<tonlib_api::Object>>> query_handlers_;
|
||||
|
@ -179,7 +195,7 @@ class TonlibCli : public td::actor::Actor {
|
|||
};
|
||||
if (!options_.one_shot) {
|
||||
ref_cnt_++;
|
||||
io_ = td::TerminalIO::create("> ", options_.enable_readline, std::make_unique<Cb>(actor_shared(this)));
|
||||
io_ = td::TerminalIO::create("> ", options_.enable_readline, false, std::make_unique<Cb>(actor_shared(this)));
|
||||
td::actor::send_closure(io_, &td::TerminalIO::set_log_interface);
|
||||
}
|
||||
|
||||
|
@ -317,6 +333,11 @@ class TonlibCli : public td::actor::Actor {
|
|||
td::TerminalIO::out() << "rwallet address <key_id> <public_key>\n";
|
||||
td::TerminalIO::out() << "rwallet init <key_id> <public_key> <start_at> [<seconds>:<value> ...]\n";
|
||||
}
|
||||
void pminer_help() {
|
||||
td::TerminalIO::out() << "pminer help\n";
|
||||
td::TerminalIO::out() << "pminer start <giver_addess> <my_address>\n";
|
||||
td::TerminalIO::out() << "pminer stop\n";
|
||||
}
|
||||
|
||||
void parse_line(td::BufferSlice line) {
|
||||
if (is_closing_) {
|
||||
|
@ -374,6 +395,7 @@ class TonlibCli : public td::actor::Actor {
|
|||
dns_help();
|
||||
pchan_help();
|
||||
rwallet_help();
|
||||
pminer_help();
|
||||
|
||||
td::TerminalIO::out()
|
||||
<< "blockmode auto|manual\tWith auto mode, all queries will be executed with respect to the latest block. "
|
||||
|
@ -477,6 +499,8 @@ class TonlibCli : public td::actor::Actor {
|
|||
run_pchan_cmd(parser, std::move(cmd_promise));
|
||||
} else if (cmd == "rwallet") {
|
||||
run_rwallet_cmd(parser, std::move(cmd_promise));
|
||||
} else if (cmd == "pminer") {
|
||||
run_pminer_cmd(parser, std::move(cmd_promise));
|
||||
} else if (cmd == "gethistory") {
|
||||
get_history(parser.read_word(), std::move(cmd_promise));
|
||||
} else if (cmd == "guessrevision") {
|
||||
|
@ -556,6 +580,216 @@ class TonlibCli : public td::actor::Actor {
|
|||
promise.set_error(td::Status::Error("Unknown command"));
|
||||
}
|
||||
|
||||
class PowMiner : public td::actor::Actor {
|
||||
public:
|
||||
class Callback {
|
||||
public:
|
||||
};
|
||||
struct Options {
|
||||
Address giver_address;
|
||||
Address my_address;
|
||||
};
|
||||
|
||||
PowMiner(Options options, td::actor::ActorId<tonlib::TonlibClient> client)
|
||||
: options_(std::move(options)), client_(std::move(client)) {
|
||||
}
|
||||
|
||||
private:
|
||||
Options options_;
|
||||
td::actor::ActorId<tonlib::TonlibClient> client_;
|
||||
|
||||
td::optional<ton::Miner::Options> miner_options_;
|
||||
static constexpr double QUERY_EACH = 5.0;
|
||||
td::Timestamp next_options_query_at_;
|
||||
|
||||
bool need_run_miners_{false};
|
||||
td::CancellationTokenSource source_;
|
||||
ton::Miner::Options miner_options_copy_;
|
||||
std::size_t threads_alive_{0};
|
||||
std::vector<td::thread> threads_;
|
||||
|
||||
bool close_flag_{false};
|
||||
|
||||
template <class QueryT>
|
||||
void send_query(QueryT query, td::Promise<typename QueryT::ReturnType> promise) {
|
||||
td::actor::send_lambda(client_,
|
||||
[self = client_, query = std::move(query), promise = std::move(promise)]() mutable {
|
||||
self.get_actor_unsafe().make_request(std::move(query), std::move(promise));
|
||||
});
|
||||
}
|
||||
|
||||
void start_up() override {
|
||||
next_options_query_at_ = td::Timestamp::now();
|
||||
loop();
|
||||
}
|
||||
void hangup() override {
|
||||
close_flag_ = true;
|
||||
source_.cancel();
|
||||
try_stop();
|
||||
}
|
||||
void try_stop() {
|
||||
if (threads_alive_ == 0) {
|
||||
td::TerminalIO::out() << "pminer: stopped\n";
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
void loop() override {
|
||||
if (close_flag_) {
|
||||
try_stop();
|
||||
return;
|
||||
}
|
||||
if (next_options_query_at_ && next_options_query_at_.is_in_past()) {
|
||||
send_query(tonlib_api::smc_load(options_.giver_address.tonlib_api()),
|
||||
promise_send_closure(td::actor::actor_id(this), &PowMiner::with_giver_state));
|
||||
next_options_query_at_ = {};
|
||||
}
|
||||
|
||||
if (miner_options_ && threads_.empty() && need_run_miners_) {
|
||||
td::TerminalIO::out() << "pminer: start workers\n";
|
||||
need_run_miners_ = false;
|
||||
miner_options_copy_ = miner_options_.value();
|
||||
miner_options_copy_.token_ = source_.get_cancellation_token();
|
||||
auto n = td::thread::hardware_concurrency();
|
||||
threads_alive_ = n;
|
||||
for (td::uint32 i = 0; i < n; i++) {
|
||||
threads_.emplace_back([this, actor_id = actor_id(this)] {
|
||||
auto res = ton::Miner::run(miner_options_copy_);
|
||||
global_scheduler_->run_in_context_external(
|
||||
[&] { send_closure(actor_id, &PowMiner::got_answer, std::move(res)); });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
alarm_timestamp().relax(next_options_query_at_);
|
||||
}
|
||||
|
||||
void got_answer(td::optional<std::string> answer) {
|
||||
source_.cancel();
|
||||
if (--threads_alive_ == 0) {
|
||||
threads_.clear();
|
||||
}
|
||||
if (answer) {
|
||||
td::TerminalIO::out() << "pminer: got some result - sending query to the giver\n";
|
||||
vm::CellBuilder cb;
|
||||
cb.store_bytes(answer.unwrap());
|
||||
send_query(tonlib_api::raw_createAndSendMessage(
|
||||
options_.giver_address.tonlib_api(), "",
|
||||
vm::std_boc_serialize(cb.finalize_novm()).move_as_ok().as_slice().str()),
|
||||
promise_send_closure(td::actor::actor_id(this), &PowMiner::on_query_sent));
|
||||
}
|
||||
loop();
|
||||
}
|
||||
|
||||
void on_query_sent(td::Result<tonlib_api::object_ptr<tonlib_api::ok>> r_ok) {
|
||||
LOG_IF(ERROR, r_ok.is_error()) << "pminer: " << r_ok.error();
|
||||
}
|
||||
|
||||
void with_giver_state(td::Result<tonlib_api::object_ptr<tonlib_api::smc_info>> r_info) {
|
||||
if (r_info.is_error()) {
|
||||
return with_giver_info(r_info.move_as_error());
|
||||
}
|
||||
send_query(tonlib_api::smc_runGetMethod(r_info.ok()->id_,
|
||||
make_object<tonlib_api::smc_methodIdName>("get_pow_params"), {}),
|
||||
promise_send_closure(td::actor::actor_id(this), &PowMiner::with_giver_info));
|
||||
}
|
||||
|
||||
void with_giver_info(td::Result<tonlib_api::object_ptr<tonlib_api::smc_runResult>> r_info) {
|
||||
auto status = do_with_giver_info(std::move(r_info));
|
||||
LOG_IF(ERROR, status.is_error()) << "pminer: " << status;
|
||||
next_options_query_at_ = td::Timestamp::in(QUERY_EACH);
|
||||
return loop();
|
||||
}
|
||||
|
||||
td::Result<td::RefInt256> to_number(const tonlib_api::object_ptr<tonlib_api::tvm_StackEntry>& entry,
|
||||
td::int32 bits) {
|
||||
if (entry->get_id() != tonlib_api::tvm_stackEntryNumber::ID) {
|
||||
return td::Status::Error("Expected stackEntryNumber");
|
||||
}
|
||||
auto& number_str = static_cast<const tonlib_api::tvm_stackEntryNumber&>(*entry.get()).number_->number_;
|
||||
auto num = td::make_refint();
|
||||
if (num.write().parse_dec(number_str.data(), (int)number_str.size()) < (int)number_str.size()) {
|
||||
return td::Status::Error("Failed to parse a number");
|
||||
}
|
||||
if (!num->unsigned_fits_bits(bits)) {
|
||||
return td::Status::Error(PSLICE() << "Number is too big " << num->to_dec_string() << " " << bits);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
td::Status do_with_giver_info(td::Result<tonlib_api::object_ptr<tonlib_api::smc_runResult>> r_info) {
|
||||
TRY_RESULT(info, std::move(r_info));
|
||||
if (info->stack_.size() < 2) {
|
||||
return td::Status::Error("Unexpected `get_pow_params` result format");
|
||||
}
|
||||
TRY_RESULT(seed, to_number(info->stack_[0], 128));
|
||||
TRY_RESULT(complexity, to_number(info->stack_[1], 256));
|
||||
ton::Miner::Options options;
|
||||
seed->export_bytes(options.seed.data(), 16, false);
|
||||
complexity->export_bytes(options.complexity.data(), 32, false);
|
||||
|
||||
TRY_RESULT(address, block::StdAddress::parse(options_.my_address.address->account_address_));
|
||||
options.my_address = std::move(address);
|
||||
options.token_ = source_.get_cancellation_token();
|
||||
|
||||
if (miner_options_ && miner_options_.value().seed == options.seed) {
|
||||
return td::Status::OK();
|
||||
}
|
||||
|
||||
td::TerminalIO::out() << "pminer: got new options\n";
|
||||
td::BigInt256 bigpower, hrate;
|
||||
bigpower.set_pow2(256).mod_div(*complexity, hrate);
|
||||
long long hash_rate = hrate.to_long();
|
||||
td::TerminalIO::out() << "[ expected required hashes for success: " << hash_rate << " ]\n";
|
||||
miner_options_ = std::move(options);
|
||||
need_run_miners_ = true;
|
||||
source_.cancel();
|
||||
|
||||
return td::Status::OK();
|
||||
}
|
||||
};
|
||||
|
||||
td::uint64 pow_miner_id_{0};
|
||||
std::map<td::uint64, td::actor::ActorOwn<PowMiner>> pow_miners_;
|
||||
|
||||
void pminer_start(td::ConstParser& parser, td::Promise<td::Unit> promise) {
|
||||
if (!pow_miners_.empty()) {
|
||||
promise.set_error(td::Status::Error("One pminer is already running"));
|
||||
}
|
||||
TRY_RESULT_PROMISE_PREFIX(promise, giver_address, to_account_address(parser.read_word(), false), "giver address");
|
||||
TRY_RESULT_PROMISE_PREFIX(promise, my_address, to_account_address(parser.read_word(), false), "my address");
|
||||
|
||||
auto id = ++pow_miner_id_;
|
||||
|
||||
PowMiner::Options options;
|
||||
options.giver_address = std::move(giver_address);
|
||||
options.my_address = std::move(my_address);
|
||||
pow_miners_.emplace(id, td::actor::create_actor<PowMiner>("PowMiner", std::move(options), client_.get()));
|
||||
td::TerminalIO::out() << "Miner #" << id << " created";
|
||||
promise.set_value({});
|
||||
}
|
||||
|
||||
void pminer_stop(td::ConstParser& parser, td::Promise<td::Unit> promise) {
|
||||
pow_miners_.clear();
|
||||
promise.set_value({});
|
||||
}
|
||||
|
||||
void run_pminer_cmd(td::ConstParser& parser, td::Promise<td::Unit> promise) {
|
||||
auto cmd = parser.read_word();
|
||||
if (cmd == "help") {
|
||||
pminer_help();
|
||||
return promise.set_value(td::Unit());
|
||||
}
|
||||
|
||||
if (cmd == "start") {
|
||||
return pminer_start(parser, std::move(promise));
|
||||
}
|
||||
if (cmd == "stop") {
|
||||
return pminer_stop(parser, std::move(promise));
|
||||
}
|
||||
promise.set_error(td::Status::Error("Unknown command"));
|
||||
}
|
||||
|
||||
void run_pchan_cmd(td::ConstParser& parser, td::Promise<td::Unit> promise) {
|
||||
auto cmd = parser.read_word();
|
||||
if (cmd == "help") {
|
||||
|
@ -2121,6 +2355,8 @@ int main(int argc, char* argv[]) {
|
|||
}
|
||||
|
||||
td::actor::Scheduler scheduler({2});
|
||||
// temporaty hack
|
||||
global_scheduler_ = &scheduler;
|
||||
scheduler.run_in_context([&] { td::actor::create_actor<TonlibCli>("console", options).release(); });
|
||||
scheduler.run();
|
||||
return 0;
|
||||
|
|
|
@ -92,7 +92,7 @@ void ValidatorEngineConsole::run() {
|
|||
private:
|
||||
td::actor::ActorId<ValidatorEngineConsole> id_;
|
||||
};
|
||||
io_ = td::TerminalIO::create("> ", readline_enabled_, std::make_unique<Cb>(actor_id(this)));
|
||||
io_ = td::TerminalIO::create("> ", readline_enabled_, ex_mode_, std::make_unique<Cb>(actor_id(this)));
|
||||
td::actor::send_closure(io_, &td::TerminalIO::set_log_interface);
|
||||
|
||||
td::TerminalIO::out() << "connecting to " << remote_addr_ << "\n";
|
||||
|
|
|
@ -1958,6 +1958,7 @@ void ValidatorManagerImpl::add_handle_to_lru(BlockHandle handle) {
|
|||
auto it = handle_lru_map_.find(handle->id());
|
||||
if (it != handle_lru_map_.end()) {
|
||||
CHECK(it->second->handle() == handle);
|
||||
it->second->remove();
|
||||
handle_lru_.put(it->second.get());
|
||||
} else {
|
||||
auto id = handle->id();
|
||||
|
@ -1978,6 +1979,7 @@ void ValidatorManagerImpl::add_handle_to_lru(BlockHandle handle) {
|
|||
BlockHandle ValidatorManagerImpl::get_handle_from_lru(BlockIdExt id) {
|
||||
auto it = handle_lru_map_.find(id);
|
||||
if (it != handle_lru_map_.end()) {
|
||||
it->second->remove();
|
||||
handle_lru_.put(it->second.get());
|
||||
auto handle = it->second->handle();
|
||||
CHECK(handle->id() == id);
|
||||
|
|
Loading…
Reference in a new issue