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:
parent
2d722c3431
commit
a4a3ea2b77
5 changed files with 69 additions and 37 deletions
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
@ -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());
|
||||
|
|
Loading…
Reference in a new issue