Incorrect Cell <-> CellSlice conversion in to_tonlib_api/from_tonlib_api in TonlibClient.cpp
I guess two fragments below work incorrectly because such transformation loses information about value type. CellSlice becomes just Cell.
https://github.com/ton-blockchain/ton/blob/d2b418bb703ed6ccd89b7d40f9f1e44686012014/tonlib/tonlib/TonlibClient.cpp#L4272-L4274
https://github.com/ton-blockchain/ton/blob/d2b418bb703ed6ccd89b7d40f9f1e44686012014/tonlib/tonlib/TonlibClient.cpp#L4311-L4314
Is this behavior intentional? In case if not I have a fix for that:
template<class Type>
using lite_api_ptr = nil::lite_api::object_ptr<Type>;
@@ -4212,8 +4213,8 @@ namespace nil {
return tonlib_api::make_object<tonlib_api::tvm_stackEntryNumber>(
tonlib_api::make_object<tonlib_api::tvm_numberDecimal>(dec_string(entry.as_int())));
case vm::StackEntry::Type::t_slice:
- return tonlib_api::make_object<tonlib_api::tvm_stackEntryCell>(
- tonlib_api::make_object<tonlib_api::tvm_cell>(
+ return tonlib_api::make_object<tonlib_api::tvm_stackEntrySlice>(
+ tonlib_api::make_object<tonlib_api::tvm_slice>(
to_bytes(vm::CellBuilder().append_cellslice(entry.as_slice()).finalize())));
case vm::StackEntry::Type::t_cell:
return tonlib_api::make_object<tonlib_api::tvm_stackEntryCell>(
@@ -4255,7 +4256,7 @@ namespace nil {
},
[&](tonlib_api::tvm_stackEntrySlice &cell) -> td::Result<vm::StackEntry> {
TRY_RESULT(res, vm::std_boc_deserialize(cell.slice_->bytes_));
- return vm::StackEntry {std::move(res)};
+ return vm::StackEntry {vm::load_cell_slice_ref(std::move(res))};
},
[&](tonlib_api::tvm_stackEntryCell &cell) -> td::Result<vm::StackEntry> {
TRY_RESULT(res, vm::std_boc_deserialize(cell.cell_->bytes_));
What is downside of current behavior?
I tested SpeCheese's fixed version and found that tonlibjson still serialize this value as BOC:
{"@type":"smc.runResult","gas_used":2961,"stack":[
{"@type":"tvm.stackEntrySlice","slice":{"@type":"tvm.slice","bytes":"te6cckEBAQEAJAAAQ4AXfBdM5qaEFVxNtpVylIujKB50Y0bD3ULeLzuKo241nNDe5qD0"}
}],"exit_code":0}
But now it has different @type and this can break existing tonlib-powered SDKs, where "high-level" classes/methods exist that parse data into own structures.
Maybe leave it as-is?
Any value will be serialized as BOC but the question is a source or destination type of such serialization.
There was a such fix: https://github.com/ton-blockchain/ton/commit/179415f815241be1965de0adea73f829f5b2eae8 that solved a half of a problem. I don't see any reasons to keep the second part of this problem.
Yes, of course, it can lead to some compatibility issues but or nobody really cares about that or it was just API misuse when you want to work with some entry type but for some another reasons got wrong type and didn't notice that.
As soon as tonlib_api.tl uses tvm.StackEntry everywhere without specifying it as Cell/Slice - I thought it's "fine" that I always receive it as Cell, even when smartcontract defines type as Slice (because Slice transfers as Cell and has no own serialization).
So for me it was a "feature" of tonlib that it always gives me Cell. If you have usecases where this behavior is a real problem (for example automatic js/ts/... code generation based on FunC/... method definition) - I'm OK with that, no problem. Fixing "reading" part by looking into @type first and then switching to one of two converters is relatively easy on SDK-level, without rewriting client apps.
But... do you know something about current "writing" behavior? When app calls tonlib to send some Cell/Slice into blockchain - does somebody check types now? I'm curios if all existing apps now already use correct types, or maybe some of them misuse StackEntryCell instead of StackEntrySlice and don't know it because "it works", and will stop working when this issue will be fixed?