mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
updated tonlib + fixes in vm
This commit is contained in:
parent
28735ddc9e
commit
efd47af432
42 changed files with 750 additions and 307 deletions
|
|
@ -1329,11 +1329,36 @@ td::Result<td::Bits256> get_adnl_address(td::Slice adnl_address) {
|
|||
return address;
|
||||
}
|
||||
|
||||
static td::optional<ton::SmartContractCode::Type> get_wallet_type(tonlib_api::InitialAccountState& state) {
|
||||
return downcast_call2<td::optional<ton::SmartContractCode::Type>>(
|
||||
state,
|
||||
td::overloaded(
|
||||
[](const tonlib_api::raw_initialAccountState&) { return td::optional<ton::SmartContractCode::Type>(); },
|
||||
[](const tonlib_api::testGiver_initialAccountState&) { return td::optional<ton::SmartContractCode::Type>(); },
|
||||
[](const tonlib_api::testWallet_initialAccountState&) { return ton::SmartContractCode::WalletV1; },
|
||||
[](const tonlib_api::wallet_initialAccountState&) { return ton::SmartContractCode::WalletV2; },
|
||||
[](const tonlib_api::wallet_v3_initialAccountState&) { return ton::SmartContractCode::WalletV3; },
|
||||
[](const tonlib_api::wallet_highload_v1_initialAccountState&) {
|
||||
return ton::SmartContractCode::HighloadWalletV1;
|
||||
},
|
||||
[](const tonlib_api::wallet_highload_v2_initialAccountState&) {
|
||||
return ton::SmartContractCode::HighloadWalletV2;
|
||||
},
|
||||
[](const tonlib_api::dns_initialAccountState&) { return ton::SmartContractCode::ManualDns; }));
|
||||
}
|
||||
|
||||
tonlib_api::object_ptr<tonlib_api::Object> TonlibClient::do_static_request(
|
||||
const tonlib_api::getAccountAddress& request) {
|
||||
if (!request.initial_account_state_) {
|
||||
return status_to_tonlib_api(TonlibError::EmptyField("initial_account_state"));
|
||||
}
|
||||
auto o_type = get_wallet_type(*request.initial_account_state_);
|
||||
if (o_type) {
|
||||
auto status = ton::SmartContractCode::validate_revision(o_type.value(), request.revision_);
|
||||
if (status.is_error()) {
|
||||
return status_to_tonlib_api(TonlibError::InvalidRevision());
|
||||
}
|
||||
}
|
||||
auto r_account_address = downcast_call2<td::Result<block::StdAddress>>(
|
||||
*request.initial_account_state_,
|
||||
[&request](auto&& state) { return get_account_address(state, request.revision_); });
|
||||
|
|
@ -1343,6 +1368,72 @@ tonlib_api::object_ptr<tonlib_api::Object> TonlibClient::do_static_request(
|
|||
return tonlib_api::make_object<tonlib_api::accountAddress>(r_account_address.ok().rserialize(true));
|
||||
}
|
||||
|
||||
td::Status TonlibClient::do_request(const tonlib_api::guessAccountRevision& request,
|
||||
td::Promise<object_ptr<tonlib_api::accountRevisionList>>&& promise) {
|
||||
if (!request.initial_account_state_) {
|
||||
return TonlibError::EmptyField("initial_account_state");
|
||||
}
|
||||
auto o_type = get_wallet_type(*request.initial_account_state_);
|
||||
if (!o_type) {
|
||||
promise.set_value(tonlib_api::make_object<tonlib_api::accountRevisionList>(std::vector<td::int32>{0}));
|
||||
return td::Status::OK();
|
||||
}
|
||||
auto revisions = ton::SmartContractCode::get_revisions(o_type.value());
|
||||
|
||||
std::vector<std::pair<int, block::StdAddress>> addresses;
|
||||
TRY_STATUS(downcast_call2<td::Status>(*request.initial_account_state_, [&revisions, &addresses](const auto& state) {
|
||||
for (auto revision : revisions) {
|
||||
TRY_RESULT(address, get_account_address(state, revision));
|
||||
addresses.push_back(std::make_pair(revision, address));
|
||||
}
|
||||
return td::Status::OK();
|
||||
}));
|
||||
|
||||
auto actor_id = actor_id_++;
|
||||
class GuessRevisions : public TonlibQueryActor {
|
||||
public:
|
||||
GuessRevisions(td::actor::ActorShared<TonlibClient> client, td::optional<ton::BlockIdExt> block_id,
|
||||
std::vector<std::pair<int, block::StdAddress>> addresses, td::Promise<std::vector<int>> promise)
|
||||
: TonlibQueryActor(std::move(client))
|
||||
, block_id_(std::move(block_id))
|
||||
, addresses_(std::move(addresses))
|
||||
, promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
private:
|
||||
td::optional<ton::BlockIdExt> block_id_;
|
||||
std::vector<std::pair<int, block::StdAddress>> addresses_;
|
||||
td::Promise<std::vector<int>> promise_;
|
||||
|
||||
size_t left_{0};
|
||||
std::vector<int> res;
|
||||
|
||||
void start_up() {
|
||||
left_ += addresses_.size();
|
||||
for (auto& p : addresses_) {
|
||||
send_query(int_api::GetAccountState{p.second, block_id_.copy()},
|
||||
promise_send_closure(td::actor::actor_id(this), &GuessRevisions::on_account_state, p.first));
|
||||
}
|
||||
}
|
||||
void on_account_state(int revision, td::Result<td::unique_ptr<AccountState>> r_state) {
|
||||
if (r_state.is_ok() && r_state.ok()->get_wallet_type() != AccountState::WalletType::Empty) {
|
||||
res.push_back(revision);
|
||||
}
|
||||
left_--;
|
||||
if (left_ == 0) {
|
||||
promise_.set_value(std::move(res));
|
||||
stop();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
actors_[actor_id] = td::actor::create_actor<GuessRevisions>(
|
||||
"GuessRevisions", actor_shared(this, actor_id), query_context_.block_id.copy(), std::move(addresses),
|
||||
promise.wrap(
|
||||
[](auto&& x) mutable { return tonlib_api::make_object<tonlib_api::accountRevisionList>(std::move(x)); }));
|
||||
return td::Status::OK();
|
||||
}
|
||||
|
||||
tonlib_api::object_ptr<tonlib_api::Object> TonlibClient::do_static_request(
|
||||
const tonlib_api::unpackAccountAddress& request) {
|
||||
auto r_account_address = get_account_address(request.account_address_);
|
||||
|
|
|
|||
|
|
@ -226,6 +226,8 @@ class TonlibClient : public td::actor::Actor {
|
|||
|
||||
td::Status do_request(const tonlib_api::getAccountState& request,
|
||||
td::Promise<object_ptr<tonlib_api::fullAccountState>>&& promise);
|
||||
td::Status do_request(const tonlib_api::guessAccountRevision& request,
|
||||
td::Promise<object_ptr<tonlib_api::accountRevisionList>>&& promise);
|
||||
|
||||
td::Status do_request(tonlib_api::sync& request, td::Promise<object_ptr<tonlib_api::ton_blockIdExt>>&& promise);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
// INVALID_ACCOUNT_ADDRESS
|
||||
// INVALID_CONFIG
|
||||
// INVALID_PEM_KEY
|
||||
// INVALID_REVISION
|
||||
// MESSAGE_TOO_LONG
|
||||
// EMPTY_FIELD
|
||||
// INVALID_FIELD
|
||||
|
|
@ -80,6 +81,9 @@ struct TonlibError {
|
|||
static td::Status InvalidPemKey() {
|
||||
return td::Status::Error(400, "INVALID_PEM_KEY");
|
||||
}
|
||||
static td::Status InvalidRevision() {
|
||||
return td::Status::Error(400, "INVALID_REVISION");
|
||||
}
|
||||
static td::Status NeedConfig() {
|
||||
return td::Status::Error(400, "NeedConfig");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -311,6 +311,7 @@ class TonlibCli : public td::actor::Actor {
|
|||
td::TerminalIO::out() << "runmethod <addr> <method-id> <params>...\tRuns GET method <method-id> of account "
|
||||
"<addr> with specified parameters\n";
|
||||
td::TerminalIO::out() << "getstate <key_id>\tget state of wallet with requested key\n";
|
||||
td::TerminalIO::out() << "guessrevision <key_id>\tsearch of existing accounts corresponding to the given key\n";
|
||||
td::TerminalIO::out() << "getaddress <key_id>\tget address of wallet with requested key\n";
|
||||
td::TerminalIO::out() << "dns resolve (<addr> | root) <name> <category>\n";
|
||||
td::TerminalIO::out() << "dns cmd <key_id> <dns_cmd>\n";
|
||||
|
|
@ -416,6 +417,8 @@ class TonlibCli : public td::actor::Actor {
|
|||
run_dns_cmd(parser, std::move(cmd_promise));
|
||||
} else if (cmd == "gethistory") {
|
||||
get_history(parser.read_word(), std::move(cmd_promise));
|
||||
} else if (cmd == "guessrevision") {
|
||||
guess_revision(parser.read_word(), std::move(cmd_promise));
|
||||
} else {
|
||||
cmd_promise.set_error(td::Status::Error(PSLICE() << "Unkwnown query `" << cmd << "`"));
|
||||
}
|
||||
|
|
@ -1091,6 +1094,27 @@ class TonlibCli : public td::actor::Actor {
|
|||
td::SecureString secret;
|
||||
};
|
||||
|
||||
template <class F>
|
||||
auto with_account_state(int version, std::string public_key, td::uint32 wallet_id, F&& f) {
|
||||
using tonlib_api::make_object;
|
||||
if (version == 1) {
|
||||
return f(make_object<tonlib_api::testWallet_initialAccountState>(public_key));
|
||||
}
|
||||
if (version == 2) {
|
||||
return f(make_object<tonlib_api::wallet_initialAccountState>(public_key));
|
||||
}
|
||||
if (version == 4) {
|
||||
return f(make_object<tonlib_api::wallet_highload_v1_initialAccountState>(public_key, wallet_id));
|
||||
}
|
||||
if (version == 5) {
|
||||
return f(make_object<tonlib_api::wallet_highload_v2_initialAccountState>(public_key, wallet_id));
|
||||
}
|
||||
if (version == 6) {
|
||||
return f(make_object<tonlib_api::dns_initialAccountState>(public_key, wallet_id));
|
||||
}
|
||||
return f(make_object<tonlib_api::wallet_v3_initialAccountState>(public_key, wallet_id));
|
||||
}
|
||||
|
||||
td::Result<Address> to_account_address(td::Slice key, bool need_private_key) {
|
||||
if (key.empty()) {
|
||||
return td::Status::Error("account address is empty");
|
||||
|
|
@ -1106,27 +1130,7 @@ class TonlibCli : public td::actor::Actor {
|
|||
return tonlib::TonlibClient::static_request(
|
||||
make_object<tonlib_api::getAccountAddress>(std::move(x), revision));
|
||||
};
|
||||
if (version == 1) {
|
||||
return do_request(make_object<tonlib_api::testWallet_initialAccountState>(keys_[r_key_i.ok()].public_key));
|
||||
}
|
||||
if (version == 2) {
|
||||
return do_request(make_object<tonlib_api::wallet_initialAccountState>(keys_[r_key_i.ok()].public_key));
|
||||
}
|
||||
if (version == 4) {
|
||||
return do_request(make_object<tonlib_api::wallet_highload_v1_initialAccountState>(
|
||||
keys_[r_key_i.ok()].public_key, wallet_id_));
|
||||
}
|
||||
if (version == 5) {
|
||||
return do_request(make_object<tonlib_api::wallet_highload_v2_initialAccountState>(
|
||||
keys_[r_key_i.ok()].public_key, wallet_id_));
|
||||
}
|
||||
if (version == 6) {
|
||||
return do_request(
|
||||
make_object<tonlib_api::dns_initialAccountState>(keys_[r_key_i.ok()].public_key, wallet_id_));
|
||||
}
|
||||
return do_request(
|
||||
make_object<tonlib_api::wallet_v3_initialAccountState>(keys_[r_key_i.ok()].public_key, wallet_id_));
|
||||
UNREACHABLE();
|
||||
return with_account_state(version, keys_[r_key_i.ok()].public_key, wallet_id_, do_request);
|
||||
}(options_.wallet_version, options_.wallet_revision);
|
||||
if (obj->get_id() != tonlib_api::error::ID) {
|
||||
Address res;
|
||||
|
|
@ -1336,6 +1340,17 @@ class TonlibCli : public td::actor::Actor {
|
|||
promise.send_closure(td::actor::actor_id(this), &TonlibCli::get_history2, key.str()));
|
||||
}
|
||||
|
||||
void guess_revision(td::Slice key, td::Promise<td::Unit> promise) {
|
||||
TRY_RESULT_PROMISE(promise, key_i, to_key_i(key));
|
||||
with_account_state(options_.wallet_version, keys_[key_i].public_key, wallet_id_, [&](auto state) {
|
||||
using tonlib_api::make_object;
|
||||
send_query(make_object<tonlib_api::guessAccountRevision>(std::move(state)), promise.wrap([](auto revisions) {
|
||||
td::TerminalIO::out() << to_string(revisions);
|
||||
return td::Unit();
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
void get_history2(td::Slice key, td::Result<tonlib_api::object_ptr<tonlib_api::fullAccountState>> r_state,
|
||||
td::Promise<td::Unit> promise) {
|
||||
TRY_RESULT_PROMISE(promise, state, std::move(r_state));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue