1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

Merge branch 'testnet' into block-generation

This commit is contained in:
SpyCheese 2024-02-01 19:29:25 +03:00
commit f4fd3ff3be
246 changed files with 7895 additions and 5430 deletions

View file

@ -30,6 +30,7 @@
#include "smc-envelope/GenericAccount.h"
#include "smc-envelope/ManualDns.h"
#include "smc-envelope/WalletV3.h"
#include "smc-envelope/WalletV4.h"
#include "smc-envelope/HighloadWallet.h"
#include "smc-envelope/HighloadWalletV2.h"
#include "smc-envelope/PaymentChannel.h"
@ -227,6 +228,14 @@ td::Result<ton::WalletV3::InitData> to_init_data(const tonlib_api::wallet_v3_ini
return std::move(init_data);
}
td::Result<ton::WalletV4::InitData> to_init_data(const tonlib_api::wallet_v4_initialAccountState& wallet_state) {
TRY_RESULT(key_bytes, get_public_key(wallet_state.public_key_));
ton::WalletV4::InitData init_data;
init_data.public_key = td::SecureString(key_bytes.key);
init_data.wallet_id = static_cast<td::uint32>(wallet_state.wallet_id_);
return std::move(init_data);
}
td::Result<ton::RestrictedWallet::InitData> to_init_data(const tonlib_api::rwallet_initialAccountState& rwallet_state) {
TRY_RESULT(init_key_bytes, get_public_key(rwallet_state.init_public_key_));
TRY_RESULT(key_bytes, get_public_key(rwallet_state.public_key_));
@ -318,6 +327,16 @@ class AccountState {
return tonlib_api::make_object<tonlib_api::wallet_v3_accountState>(static_cast<td::uint32>(wallet_id),
static_cast<td::uint32>(seqno));
}
td::Result<tonlib_api::object_ptr<tonlib_api::wallet_v4_accountState>> to_wallet_v4_accountState() const {
if (wallet_type_ != WalletV4) {
return TonlibError::AccountTypeUnexpected("WalletV4");
}
auto wallet = ton::WalletV4(get_smc_state());
TRY_RESULT(seqno, wallet.get_seqno());
TRY_RESULT(wallet_id, wallet.get_wallet_id());
return tonlib_api::make_object<tonlib_api::wallet_v4_accountState>(static_cast<td::uint32>(wallet_id),
static_cast<td::uint32>(seqno));
}
td::Result<tonlib_api::object_ptr<tonlib_api::wallet_highload_v1_accountState>> to_wallet_highload_v1_accountState()
const {
if (wallet_type_ != HighloadWalletV1) {
@ -419,6 +438,8 @@ class AccountState {
return f(to_dns_accountState());
case PaymentChannel:
return f(to_payment_channel_accountState());
case WalletV4:
return f(to_wallet_v4_accountState());
}
UNREACHABLE();
}
@ -457,7 +478,8 @@ class AccountState {
HighloadWalletV2,
ManualDns,
PaymentChannel,
RestrictedWallet
RestrictedWallet,
WalletV4
};
WalletType get_wallet_type() const {
return wallet_type_;
@ -476,6 +498,7 @@ class AccountState {
case AccountState::HighloadWalletV1:
case AccountState::HighloadWalletV2:
case AccountState::RestrictedWallet:
case AccountState::WalletV4:
return true;
}
UNREACHABLE();
@ -496,6 +519,8 @@ class AccountState {
return td::make_unique<ton::HighloadWalletV2>(get_smc_state());
case AccountState::RestrictedWallet:
return td::make_unique<ton::RestrictedWallet>(get_smc_state());
case AccountState::WalletV4:
return td::make_unique<ton::WalletV4>(get_smc_state());
}
UNREACHABLE();
return {};
@ -553,6 +578,23 @@ class AccountState {
break;
}
},
[&](tonlib_api::wallet_v4_initialAccountState& v4wallet) {
for (auto revision : ton::SmartContractCode::get_revisions(ton::SmartContractCode::WalletV4)) {
auto init_data = to_init_data(v4wallet);
if (init_data.is_error()) {
continue;
}
auto wallet = ton::WalletV4::create(init_data.move_as_ok(), revision);
if (!(wallet->get_address(ton::masterchainId) == address_ ||
wallet->get_address(ton::basechainId) == address_)) {
continue;
}
wallet_type_ = WalletType::WalletV4;
wallet_revision_ = revision;
set_new_state(wallet->get_state());
break;
}
},
[&](tonlib_api::rwallet_initialAccountState& rwallet) {
for (auto revision : ton::SmartContractCode::get_revisions(ton::SmartContractCode::RestrictedWallet)) {
auto r_init_data = to_init_data(rwallet);
@ -596,7 +638,7 @@ class AccountState {
return wallet_type_;
}
auto wallet_id = static_cast<td::uint32>(address_.workchain + wallet_id_);
ton::WalletV3::InitData init_data{key.as_octet_string(), wallet_id};
ton::WalletInterface::DefaultInitData init_data{key.as_octet_string(), wallet_id};
auto o_revision = ton::WalletV3::guess_revision(address_, init_data);
if (o_revision) {
wallet_type_ = WalletType::WalletV3;
@ -604,6 +646,13 @@ class AccountState {
set_new_state(ton::WalletV3::get_init_state(wallet_revision_, init_data));
return wallet_type_;
}
o_revision = ton::WalletV4::guess_revision(address_, init_data);
if (o_revision) {
wallet_type_ = WalletType::WalletV4;
wallet_revision_ = o_revision.value();
set_new_state(ton::WalletV4::get_init_state(wallet_revision_, init_data));
return wallet_type_;
}
o_revision = ton::HighloadWalletV2::guess_revision(address_, init_data);
if (o_revision) {
wallet_type_ = WalletType::HighloadWalletV2;
@ -681,6 +730,12 @@ class AccountState {
wallet_revision_ = o_revision.value();
return wallet_type_;
}
o_revision = ton::WalletV4::guess_revision(code_hash);
if (o_revision) {
wallet_type_ = WalletType::WalletV4;
wallet_revision_ = o_revision.value();
return wallet_type_;
}
o_revision = ton::HighloadWalletV2::guess_revision(code_hash);
if (o_revision) {
wallet_type_ = WalletType::HighloadWalletV2;
@ -1916,7 +1971,7 @@ class RunEmulator : public TonlibQueryActor {
ton::UnixTime now = account_state_->get_sync_time();
bool is_special = address.workchain == ton::masterchainId && config->is_special_smartcontract(address.addr);
block::Account account(address.workchain, address.addr.bits());
if (!account.unpack(std::move(shard_account), td::Ref<vm::CellSlice>(), now, is_special)) {
if (!account.unpack(std::move(shard_account), now, is_special)) {
check(td::Status::Error("Can't unpack shard account"));
return;
}
@ -2253,6 +2308,13 @@ td::Result<block::StdAddress> get_account_address(const tonlib_api::wallet_v3_in
->get_address(workchain_id);
}
td::Result<block::StdAddress> get_account_address(const tonlib_api::wallet_v4_initialAccountState& test_wallet_state,
td::int32 revision, ton::WorkchainId workchain_id) {
TRY_RESULT(key_bytes, get_public_key(test_wallet_state.public_key_));
return ton::WalletV4::create({key_bytes.key, static_cast<td::uint32>(test_wallet_state.wallet_id_)}, revision)
->get_address(workchain_id);
}
td::Result<block::StdAddress> get_account_address(
const tonlib_api::wallet_highload_v1_initialAccountState& test_wallet_state, td::int32 revision,
ton::WorkchainId workchain_id) {
@ -2300,6 +2362,7 @@ static td::optional<ton::SmartContractCode::Type> get_wallet_type(tonlib_api::In
td::overloaded(
[](const tonlib_api::raw_initialAccountState&) { return td::optional<ton::SmartContractCode::Type>(); },
[](const tonlib_api::wallet_v3_initialAccountState&) { return ton::SmartContractCode::WalletV3; },
[](const tonlib_api::wallet_v4_initialAccountState&) { return ton::SmartContractCode::WalletV4; },
[](const tonlib_api::wallet_highload_v1_initialAccountState&) {
return ton::SmartContractCode::HighloadWalletV1;
},
@ -2389,6 +2452,12 @@ td::Status TonlibClient::do_request(tonlib_api::guessAccount& request,
sources.push_back(Source{tonlib_api::make_object<tonlib_api::wallet_v3_initialAccountState>(
request.public_key_, wallet_id_ + ton::basechainId),
ton::basechainId});
sources.push_back(Source{tonlib_api::make_object<tonlib_api::wallet_v4_initialAccountState>(
request.public_key_, wallet_id_ + ton::masterchainId),
ton::masterchainId});
sources.push_back(Source{tonlib_api::make_object<tonlib_api::wallet_v4_initialAccountState>(
request.public_key_, wallet_id_ + ton::basechainId),
ton::basechainId});
for (Source& source : sources) {
auto o_type = get_wallet_type(*source.init_state);
if (!o_type) {
@ -2900,7 +2969,7 @@ struct ToRawTransactions {
if (type == 0 || type == 0x2167da4b) {
td::Status status;
auto r_body_message = vm::CellString::load(body.write());
auto r_body_message = TRY_VM(vm::CellString::load(body.write()));
LOG_IF(WARNING, r_body_message.is_error()) << "Failed to parse a message: " << r_body_message.error();
if (r_body_message.is_ok()) {
@ -4921,6 +4990,8 @@ td::Status TonlibClient::do_request(const tonlib_api::importKey& request,
if (!request.exported_key_) {
return TonlibError::EmptyField("exported_key");
}
// Note: the mnemonic is considered valid if a certain hash starts with zero byte (see Mnemonic::is_basic_seed())
// Therefore, importKey with invalid password has 1/256 chance to return OK
TRY_RESULT(key, key_storage_.import_key(std::move(request.local_password_), std::move(request.mnemonic_password_),
KeyStorage::ExportedKey{std::move(request.exported_key_->word_list_)}));
TRY_RESULT(key_bytes, public_key_from_bytes(key.public_key.as_slice()));