1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-02-14 20:22:19 +00:00

liteServer.getAccountStatePrunned method (#534)

This commit is contained in:
SpyCheese 2022-11-30 08:39:32 +03:00 committed by GitHub
parent 2d722c3431
commit a4a3ea2b77
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 69 additions and 37 deletions

View file

@ -1005,11 +1005,12 @@ bool TestNode::do_parse_line() {
return eoln() && get_server_mc_block_id();
} else if (word == "sendfile") {
return !eoln() && set_error(send_ext_msg_from_filename(get_line_tail()));
} else if (word == "getaccount") {
} else if (word == "getaccount" || word == "getaccountprunned") {
bool prunned = word == "getaccountprunned";
return parse_account_addr_ext(workchain, addr, addr_ext) &&
(seekeoln()
? get_account_state(workchain, addr, mc_last_id_, addr_ext)
: parse_block_id_ext(blkid) && seekeoln() && get_account_state(workchain, addr, blkid, addr_ext));
(seekeoln() ? get_account_state(workchain, addr, mc_last_id_, addr_ext, "", -1, prunned)
: parse_block_id_ext(blkid) && seekeoln() &&
get_account_state(workchain, addr, blkid, addr_ext, "", -1, prunned));
} else if (word == "saveaccount" || word == "saveaccountcode" || word == "saveaccountdata") {
std::string filename;
int mode = ((word.c_str()[11] >> 1) & 3);
@ -1173,7 +1174,7 @@ td::Status TestNode::send_ext_msg_from_filename(std::string filename) {
}
bool TestNode::get_account_state(ton::WorkchainId workchain, ton::StdSmcAddress addr, ton::BlockIdExt ref_blkid,
int addr_ext, std::string filename, int mode) {
int addr_ext, std::string filename, int mode, bool prunned) {
if (!ref_blkid.is_valid()) {
return set_error("must obtain last block information before making other queries");
}
@ -1181,35 +1182,44 @@ bool TestNode::get_account_state(ton::WorkchainId workchain, ton::StdSmcAddress
return set_error("server connection not ready");
}
if (addr_ext) {
return get_special_smc_addr(addr_ext, [this, ref_blkid, filename, mode](td::Result<ton::StdSmcAddress> res) {
if (res.is_error()) {
LOG(ERROR) << "cannot resolve special smart contract address: " << res.move_as_error();
} else {
get_account_state(ton::masterchainId, res.move_as_ok(), ref_blkid, 0, filename, mode);
}
});
return get_special_smc_addr(
addr_ext, [this, ref_blkid, filename, mode, prunned](td::Result<ton::StdSmcAddress> res) {
if (res.is_error()) {
LOG(ERROR) << "cannot resolve special smart contract address: " << res.move_as_error();
} else {
get_account_state(ton::masterchainId, res.move_as_ok(), ref_blkid, 0, filename, mode, prunned);
}
});
}
auto a = ton::create_tl_object<ton::lite_api::liteServer_accountId>(workchain, addr);
auto b = ton::serialize_tl_object(ton::create_tl_object<ton::lite_api::liteServer_getAccountState>(
ton::create_tl_lite_block_id(ref_blkid), std::move(a)),
true);
LOG(INFO) << "requesting account state for " << workchain << ":" << addr.to_hex() << " with respect to "
<< ref_blkid.to_str() << " with savefile `" << filename << "` and mode " << mode;
return envelope_send_query(
std::move(b), [Self = actor_id(this), workchain, addr, ref_blkid, filename, mode](td::Result<td::BufferSlice> R) {
if (R.is_error()) {
return;
}
auto F = ton::fetch_tl_object<ton::lite_api::liteServer_accountState>(R.move_as_ok(), true);
if (F.is_error()) {
LOG(ERROR) << "cannot parse answer to liteServer.getAccountState";
} else {
auto f = F.move_as_ok();
td::actor::send_closure_later(Self, &TestNode::got_account_state, ref_blkid, ton::create_block_id(f->id_),
ton::create_block_id(f->shardblk_), std::move(f->shard_proof_),
std::move(f->proof_), std::move(f->state_), workchain, addr, filename, mode);
}
});
td::BufferSlice b;
if (prunned) {
b = ton::serialize_tl_object(ton::create_tl_object<ton::lite_api::liteServer_getAccountStatePrunned>(
ton::create_tl_lite_block_id(ref_blkid), std::move(a)),
true);
} else {
b = ton::serialize_tl_object(ton::create_tl_object<ton::lite_api::liteServer_getAccountState>(
ton::create_tl_lite_block_id(ref_blkid), std::move(a)),
true);
}
LOG(INFO) << "requesting " << (prunned ? "prunned " : "") << "account state for " << workchain << ":" << addr.to_hex()
<< " with respect to " << ref_blkid.to_str() << " with savefile `" << filename << "` and mode " << mode;
return envelope_send_query(std::move(b), [Self = actor_id(this), workchain, addr, ref_blkid, filename, mode,
prunned](td::Result<td::BufferSlice> R) {
if (R.is_error()) {
return;
}
auto F = ton::fetch_tl_object<ton::lite_api::liteServer_accountState>(R.move_as_ok(), true);
if (F.is_error()) {
LOG(ERROR) << "cannot parse answer to liteServer.getAccountState";
} else {
auto f = F.move_as_ok();
td::actor::send_closure_later(Self, &TestNode::got_account_state, ref_blkid, ton::create_block_id(f->id_),
ton::create_block_id(f->shardblk_), std::move(f->shard_proof_),
std::move(f->proof_), std::move(f->state_), workchain, addr, filename, mode,
prunned);
}
});
}
td::int64 TestNode::compute_method_id(std::string method) {
@ -1901,15 +1911,18 @@ bool TestNode::get_last_transactions(ton::WorkchainId workchain, ton::StdSmcAddr
void TestNode::got_account_state(ton::BlockIdExt ref_blk, ton::BlockIdExt blk, ton::BlockIdExt shard_blk,
td::BufferSlice shard_proof, td::BufferSlice proof, td::BufferSlice state,
ton::WorkchainId workchain, ton::StdSmcAddress addr, std::string filename, int mode) {
LOG(INFO) << "got account state for " << workchain << ":" << addr.to_hex() << " with respect to blocks "
<< blk.to_str() << (shard_blk == blk ? "" : std::string{" and "} + shard_blk.to_str());
ton::WorkchainId workchain, ton::StdSmcAddress addr, std::string filename, int mode,
bool prunned) {
LOG(INFO) << "got " << (prunned ? "prunned " : "") << "account state for " << workchain << ":" << addr.to_hex()
<< " with respect to blocks " << blk.to_str()
<< (shard_blk == blk ? "" : std::string{" and "} + shard_blk.to_str());
block::AccountState account_state;
account_state.blk = blk;
account_state.shard_blk = shard_blk;
account_state.shard_proof = std::move(shard_proof);
account_state.proof = std::move(proof);
account_state.state = std::move(state);
account_state.is_virtualized = prunned;
auto r_info = account_state.validate(ref_blk, block::StdAddress(workchain, addr));
if (r_info.is_error()) {
LOG(ERROR) << r_info.error().message();

View file

@ -191,10 +191,11 @@ class TestNode : public td::actor::Actor {
td::Status send_ext_msg_from_filename(std::string filename);
td::Status save_db_file(ton::FileHash file_hash, td::BufferSlice data);
bool get_account_state(ton::WorkchainId workchain, ton::StdSmcAddress addr, ton::BlockIdExt ref_blkid,
int addr_ext = 0, std::string filename = "", int mode = -1);
int addr_ext = 0, std::string filename = "", int mode = -1, bool prunned = false);
void got_account_state(ton::BlockIdExt ref_blk, ton::BlockIdExt blk, ton::BlockIdExt shard_blk,
td::BufferSlice shard_proof, td::BufferSlice proof, td::BufferSlice state,
ton::WorkchainId workchain, ton::StdSmcAddress addr, std::string filename, int mode);
ton::WorkchainId workchain, ton::StdSmcAddress addr, std::string filename, int mode,
bool prunned);
bool parse_run_method(ton::WorkchainId workchain, ton::StdSmcAddress addr, ton::BlockIdExt ref_blkid, int addr_ext,
std::string method_name, bool ext_mode);
bool after_parse_run_method(ton::WorkchainId workchain, ton::StdSmcAddress addr, ton::BlockIdExt ref_blkid,

View file

@ -68,6 +68,7 @@ liteServer.getState id:tonNode.blockIdExt = liteServer.BlockState;
liteServer.getBlockHeader id:tonNode.blockIdExt mode:# = liteServer.BlockHeader;
liteServer.sendMessage body:bytes = liteServer.SendMsgStatus;
liteServer.getAccountState id:tonNode.blockIdExt account:liteServer.accountId = liteServer.AccountState;
liteServer.getAccountStatePrunned id:tonNode.blockIdExt account:liteServer.accountId = liteServer.AccountState;
liteServer.runSmcMethod mode:# id:tonNode.blockIdExt account:liteServer.accountId method_id:long params:bytes = liteServer.RunMethodResult;
liteServer.getShardInfo id:tonNode.blockIdExt workchain:int shard:long exact:Bool = liteServer.ShardInfo;
liteServer.getAllShardsInfo id:tonNode.blockIdExt = liteServer.AllShardsInfo;

Binary file not shown.

View file

@ -153,6 +153,10 @@ void LiteQuery::start_up() {
this->perform_getAccountState(ton::create_block_id(q.id_), static_cast<WorkchainId>(q.account_->workchain_),
q.account_->id_, 0);
},
[&](lite_api::liteServer_getAccountStatePrunned& q) {
this->perform_getAccountState(ton::create_block_id(q.id_), static_cast<WorkchainId>(q.account_->workchain_),
q.account_->id_, 0x40000000);
},
[&](lite_api::liteServer_getOneTransaction& q) {
this->perform_getOneTransaction(ton::create_block_id(q.id_),
static_cast<WorkchainId>(q.account_->workchain_), q.account_->id_,
@ -1206,6 +1210,19 @@ void LiteQuery::finish_getAccountState(td::BufferSlice shard_proof) {
}
td::BufferSlice data;
if (acc_root.not_null()) {
if (mode_ & 0x40000000) {
vm::MerkleProofBuilder mpb{acc_root};
// account_none$0 = Account;
// account$1 addr:MsgAddressInt storage_stat:StorageInfo storage:AccountStorage = Account;
// account_storage$_ last_trans_lt:uint64 balance:CurrencyCollection state:AccountState = AccountStorage;
// account_active$1 _:StateInit = AccountState;
auto S = mpb.root()->load_cell();
if (S.is_error()) {
fatal_error(S.move_as_error_prefix("Failed to load account: "));
return;
}
acc_root = mpb.extract_proof();
}
auto res = vm::std_boc_serialize(std::move(acc_root));
if (res.is_error()) {
fatal_error(res.move_as_error());