Skip to content
This repository has been archived by the owner on May 16, 2024. It is now read-only.

Add method listBlockTransactionExt to lite server and tonlib. #91

Open
wants to merge 6 commits into
base: safer_overlay_plus
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions crypto/block/check-proof.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,41 @@ td::Result<TransactionList::Info> TransactionList::validate() const {
return std::move(res);
}

td::Result<BlockTransaction::Info> BlockTransaction::validate() {
if (root.is_null()) {
return td::Status::Error("transactions are expected to be non-empty");
}
block::gen::Transaction::Record trans;
if (!tlb::unpack_cell(root, trans)) {
return td::Status::Error("cannot unpack transaction #");
}
Info res;
res.blkid = blkid;
res.now = trans.now;
res.lt = trans.lt;
res.hash = root->get_hash().bits();
res.transaction = root;
return std::move(res);
}

td::Result<BlockTransactionList::Info> BlockTransactionList::validate() const {
auto R = vm::std_boc_deserialize_multi(std::move(transactions_boc));
if (R.is_error()) {
return td::Status::Error("cannot deserialize transactions BoC");
}
auto list = R.move_as_ok();
size_t c = 0;
Info res;
for (auto& root : list) {
BlockTransaction transaction;
transaction.root = root;
transaction.blkid = blkid;
TRY_RESULT(info, transaction.validate());
res.transactions.push_back(std::move(info));
}
return std::move(res);
}

td::Status BlockProofLink::validate(td::uint32* save_utime) const {
if (save_utime) {
*save_utime = 0;
Expand Down
26 changes: 26 additions & 0 deletions crypto/block/check-proof.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,30 @@ struct TransactionList {
td::Result<Info> validate() const;
};

struct BlockTransaction {
ton::BlockIdExt blkid;
td::Ref<vm::Cell> root;

struct Info {
ton::BlockIdExt blkid;
td::uint32 now;
ton::LogicalTime lt;
ton::Bits256 hash;
td::Ref<vm::Cell> transaction;
};
td::Result<Info> validate();
};

struct BlockTransactionList {
ton::BlockIdExt blkid;
td::BufferSlice transactions_boc;

struct Info {
ton::BlockIdExt blkid;
std::vector<BlockTransaction::Info> transactions;
};

td::Result<Info> validate() const;
};

} // namespace block
2 changes: 2 additions & 0 deletions tl/generate/scheme/lite_api.tl
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ liteServer.transactionList ids:(vector tonNode.blockIdExt) transactions:bytes =
liteServer.transactionId mode:# account:mode.0?int256 lt:mode.1?long hash:mode.2?int256 = liteServer.TransactionId;
liteServer.transactionId3 account:int256 lt:long = liteServer.TransactionId3;
liteServer.blockTransactions id:tonNode.blockIdExt req_count:# incomplete:Bool ids:(vector liteServer.transactionId) proof:bytes = liteServer.BlockTransactions;
liteServer.blockTransactionsExt id:tonNode.blockIdExt req_count:# incomplete:Bool transactions:liteServer.transactionList proof:bytes = liteServer.BlockTransactionsExt;
liteServer.signature node_id_short:int256 signature:bytes = liteServer.Signature;
liteServer.signatureSet validator_set_hash:int catchain_seqno:int signatures:(vector liteServer.signature) = liteServer.SignatureSet;
liteServer.blockLinkBack to_key_block:Bool from:tonNode.blockIdExt to:tonNode.blockIdExt dest_proof:bytes proof:bytes state_proof:bytes = liteServer.BlockLink;
Expand Down Expand Up @@ -73,6 +74,7 @@ liteServer.getOneTransaction id:tonNode.blockIdExt account:liteServer.accountId
liteServer.getTransactions count:# account:liteServer.accountId lt:long hash:int256 = liteServer.TransactionList;
liteServer.lookupBlock mode:# id:tonNode.blockId lt:mode.1?long utime:mode.2?int = liteServer.BlockHeader;
liteServer.listBlockTransactions id:tonNode.blockIdExt mode:# count:# after:mode.7?liteServer.transactionId3 reverse_order:mode.6?true want_proof:mode.5?true = liteServer.BlockTransactions;
liteServer.listBlockTransactionsExt id:tonNode.blockIdExt mode:# count:# after:mode.7?liteServer.transactionId3 reverse_order:mode.6?true want_proof:mode.5?true = liteServer.BlockTransactionsExt;
liteServer.getBlockProof mode:# known_block:tonNode.blockIdExt target_block:mode.0?tonNode.blockIdExt = liteServer.PartialBlockProof;
liteServer.getConfigAll mode:# id:tonNode.blockIdExt = liteServer.ConfigInfo;
liteServer.getConfigParams mode:# id:tonNode.blockIdExt param_list:(vector int) = liteServer.ConfigInfo;
Expand Down
Binary file modified tl/generate/scheme/lite_api.tlo
Binary file not shown.
4 changes: 3 additions & 1 deletion tl/generate/scheme/tonlib_api.tl
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ ton.blockIdExt workchain:int32 shard:int64 seqno:int32 root_hash:bytes file_hash

raw.fullAccountState balance:int64 code:bytes data:bytes last_transaction_id:internal.transactionId block_id:ton.blockIdExt frozen_hash:bytes sync_utime:int53 = raw.FullAccountState;
raw.message source:accountAddress destination:accountAddress value:int64 fwd_fee:int64 ihr_fee:int64 created_lt:int64 body_hash:bytes msg_data:msg.Data = raw.Message;
raw.transaction utime:int53 data:bytes transaction_id:internal.transactionId fee:int64 storage_fee:int64 other_fee:int64 in_msg:raw.message out_msgs:vector<raw.message> = raw.Transaction;
raw.transaction address:accountAddress utime:int53 data:bytes transaction_id:internal.transactionId fee:int64 storage_fee:int64 other_fee:int64 in_msg:raw.message out_msgs:vector<raw.message> = raw.Transaction;
raw.transactions transactions:vector<raw.transaction> previous_transaction_id:internal.transactionId = raw.Transactions;

pchan.config alice_public_key:string alice_address:accountAddress bob_public_key:string bob_address:accountAddress init_timeout:int32 close_timeout:int32 channel_id:int64 = pchan.Config;
Expand Down Expand Up @@ -208,6 +208,7 @@ blocks.shards shards:vector<ton.BlockIdExt> = blocks.Shards;
blocks.accountTransactionId account:bytes lt:int64 = blocks.AccountTransactionId;
blocks.shortTxId mode:# account:mode.0?bytes lt:mode.1?int64 hash:mode.2?bytes = liteServer.TransactionId;
blocks.transactions id:ton.blockIdExt req_count:int32 incomplete:Bool transactions:vector<blocks.shortTxId> = blocks.Transactions;
blocks.transactionsExt id:ton.blockIdExt req_count:int32 incomplete:Bool transactions:vector<raw.transaction> = blocks.TransactionsExt;
blocks.header id:ton.blockIdExt global_id:int32 version:int32 flags:# after_merge:Bool after_split:Bool before_split:Bool want_merge:Bool want_split:Bool validator_list_hash_short:int32 catchain_seqno:int32 min_ref_mc_seqno:int32 is_key_block:Bool prev_key_block_seqno:int32 start_lt:int64 end_lt:int64 gen_utime:int53 vert_seqno:# prev_blocks:vector<ton.blockIdExt> = blocks.Header;
//blocks.shortData header:blocks.Header transactions:blocks.Header = blocks.BlockData;

Expand Down Expand Up @@ -296,6 +297,7 @@ blocks.getMasterchainInfo = blocks.MasterchainInfo;
blocks.getShards id:ton.blockIdExt = blocks.Shards;
blocks.lookupBlock mode:int32 id:ton.blockId lt:int64 utime:int32 = ton.BlockIdExt;
blocks.getTransactions id:ton.blockIdExt mode:# count:# after:blocks.accountTransactionId = blocks.Transactions;
blocks.getTransactionsExt id:ton.blockIdExt mode:# count:# after:blocks.accountTransactionId = blocks.TransactionsExt;
blocks.getBlockHeader id:ton.blockIdExt = blocks.Header;

onLiteServerQueryResult id:int64 bytes:bytes = Ok;
Expand Down
Binary file modified tl/generate/scheme/tonlib_api.tlo
Binary file not shown.
114 changes: 114 additions & 0 deletions tonlib/tonlib/TonlibClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2324,6 +2324,7 @@ struct ToRawTransactions {
std::vector<tonlib_api::object_ptr<tonlib_api::raw_message>> out_msgs;
td::int64 fees = 0;
td::int64 storage_fee = 0;
td::string address;
if (info.transaction.not_null()) {
data = to_bytes(info.transaction);
block::gen::Transaction::Record trans;
Expand Down Expand Up @@ -2362,8 +2363,11 @@ struct ToRawTransactions {
return td::Status::Error("Failed to fetch storage fee from transaction");
}
storage_fee = storage_fees->to_long();
auto std_address = block::StdAddress(info.blkid.id.workchain, trans.account_addr);
address = std_address.rserialize(true);
}
return tonlib_api::make_object<tonlib_api::raw_transaction>(
tonlib_api::make_object<tonlib_api::accountAddress>(std::move(address)),
info.now, data,
tonlib_api::make_object<tonlib_api::internal_transactionId>(info.prev_trans_lt,
info.prev_trans_hash.as_slice().str()),
Expand All @@ -2390,6 +2394,79 @@ struct ToRawTransactions {

return tonlib_api::make_object<tonlib_api::raw_transactions>(std::move(transactions), std::move(transaction_id));
}

td::Result<tonlib_api::object_ptr<tonlib_api::raw_transaction>> to_raw_transaction_or_throw(
block::BlockTransaction::Info&& info) {
std::string data;

tonlib_api::object_ptr<tonlib_api::raw_message> in_msg;
std::vector<tonlib_api::object_ptr<tonlib_api::raw_message>> out_msgs;
td::int64 fees = 0;
td::int64 storage_fee = 0;
td::string address;
if (info.transaction.not_null()) {
data = to_bytes(info.transaction);
block::gen::Transaction::Record trans;
if (!tlb::unpack_cell(info.transaction, trans)) {
return td::Status::Error("Failed to unpack Transaction");
}

TRY_RESULT_ASSIGN(fees, to_balance(trans.total_fees));
//LOG(ERROR) << fees;

//std::ostringstream outp;
//block::gen::t_Transaction.print_ref(outp, info.transaction);
//LOG(INFO) << outp.str();

auto is_just = trans.r1.in_msg->prefetch_long(1);
if (is_just == trans.r1.in_msg->fetch_long_eof) {
return td::Status::Error("Failed to parse long");
}
if (is_just == -1) {
auto msg = trans.r1.in_msg->prefetch_ref();
TRY_RESULT(in_msg_copy, to_raw_message(trans.r1.in_msg->prefetch_ref()));
in_msg = std::move(in_msg_copy);
}

if (trans.outmsg_cnt != 0) {
vm::Dictionary dict{trans.r1.out_msgs, 15};
for (int x = 0; x < trans.outmsg_cnt; x++) {
TRY_RESULT(out_msg, to_raw_message(dict.lookup_ref(td::BitArray<15>{x})));
fees += out_msg->fwd_fee_;
fees += out_msg->ihr_fee_;
out_msgs.push_back(std::move(out_msg));
}
}
td::RefInt256 storage_fees;
if (!block::tlb::t_TransactionDescr.get_storage_fees(trans.description, storage_fees)) {
return td::Status::Error("Failed to fetch storage fee from transaction");
}
storage_fee = storage_fees->to_long();
auto std_address = block::StdAddress(info.blkid.id.workchain, trans.account_addr);
address = std_address.rserialize(true);
}
return tonlib_api::make_object<tonlib_api::raw_transaction>(
tonlib_api::make_object<tonlib_api::accountAddress>(std::move(address)),
info.now, data,
tonlib_api::make_object<tonlib_api::internal_transactionId>(info.lt,
info.hash.as_slice().str()),
fees, storage_fee, fees - storage_fee, std::move(in_msg), std::move(out_msgs));
}

td::Result<tonlib_api::object_ptr<tonlib_api::raw_transaction>> to_raw_transaction(block::BlockTransaction::Info&& info) {
return TRY_VM(to_raw_transaction_or_throw(std::move(info)));
}

td::Result<std::vector<tonlib_api::object_ptr<tonlib_api::raw_transaction>>> to_raw_transactions(
block::BlockTransactionList::Info&& info) {
std::vector<tonlib_api::object_ptr<tonlib_api::raw_transaction>> transactions;
for (auto& transaction : info.transactions) {
TRY_RESULT(raw_transaction, to_raw_transaction(std::move(transaction)));
transactions.push_back(std::move(raw_transaction));
}

return std::move(transactions);
}
};

// Raw
Expand Down Expand Up @@ -4316,6 +4393,43 @@ td::Status TonlibClient::do_request(const tonlib_api::blocks_getTransactions& re
return td::Status::OK();
}

td::Status TonlibClient::do_request(const tonlib_api::blocks_getTransactionsExt& request,
td::Promise<object_ptr<tonlib_api::blocks_transactionsExt>>&& promise) {
TRY_RESULT(block, to_lite_api(*request.id_))
TRY_RESULT(account, to_bits256((*request.after_).account_, "account"));
auto after = ton::lite_api::make_object<ton::lite_api::liteServer_transactionId3>(account, (*request.after_).lt_);
client_.send_query(ton::lite_api::liteServer_listBlockTransactionsExt(
std::move(block),
request.mode_,
request.count_,
std::move(after),
false,
false),
promise.wrap([](lite_api_ptr<ton::lite_api::liteServer_blockTransactionsExt>&& bTxes) {
const auto& id = bTxes->id_;
tonlib_api::blocks_transactionsExt r;
r.id_ = to_tonlib_api(*id);
r.req_count_ = bTxes->req_count_;
r.incomplete_ = bTxes->incomplete_;
// bTxes->transactions to block::BlockTransactionList::Info
block::BlockTransactionList list;
list.blkid = create_block_id(id);
list.transactions_boc = std::move(bTxes->transactions_->transactions_);
auto info = list.validate();
if (info.is_error()) {
LOG(ERROR) << "info.is_error()";
}
// block::BlockTransactionList::Info to vector<raw_transaction>
auto raw_transactions = ToRawTransactions(td::optional<td::Ed25519::PrivateKey>()).to_raw_transactions(info.move_as_ok());
if (raw_transactions.is_error()) {
LOG(ERROR) << "raw_transactions.is_error()";
}
r.transactions_ = raw_transactions.move_as_ok();
return tonlib_api::make_object<tonlib_api::blocks_transactionsExt>(std::move(r));
}));
return td::Status::OK();
}

td::Status TonlibClient::do_request(const tonlib_api::blocks_getBlockHeader& request,
td::Promise<object_ptr<tonlib_api::blocks_header>>&& promise) {
TRY_RESULT(block, to_lite_api(*request.id_))
Expand Down
2 changes: 2 additions & 0 deletions tonlib/tonlib/TonlibClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,8 @@ class TonlibClient : public td::actor::Actor {
td::Promise<object_ptr<tonlib_api::ton_blockIdExt>>&& promise);
td::Status do_request(const tonlib_api::blocks_getTransactions& block_data,
td::Promise<object_ptr<tonlib_api::blocks_transactions>>&& promise);
td::Status do_request(const tonlib_api::blocks_getTransactionsExt& request,
td::Promise<object_ptr<tonlib_api::blocks_transactionsExt>>&& promise);
td::Status do_request(const tonlib_api::blocks_getBlockHeader& request,
td::Promise<object_ptr<tonlib_api::blocks_header>>&& promise);

Expand Down
Loading