diff --git a/Share/Info.plist b/Share/Info.plist
index 4a41e4c130..22f812c112 100644
--- a/Share/Info.plist
+++ b/Share/Info.plist
@@ -31,15 +31,15 @@
SUBQUERY (
$extensionItem.attachments,
$attachment,
- ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.file-url" ||
- ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.movie" ||
- ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.image" ||
- ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.url" ||
- ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.text" ||
- ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.audio" ||
- ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.data" ||
- ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.vcard" ||
- ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.apple.pkpass"
+ ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.file-url" ||
+ ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.movie" ||
+ ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.image" ||
+ ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.url" ||
+ ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.text" ||
+ ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.audio" ||
+ ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.data" ||
+ ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.vcard" ||
+ ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.apple.pkpass"
).@count == $extensionItem.attachments.@count
).@count > 0
diff --git a/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+IntentsExtension.xcscheme b/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+IntentsExtension.xcscheme
index a48bce0372..6d8563cd6c 100644
--- a/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+IntentsExtension.xcscheme
+++ b/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+IntentsExtension.xcscheme
@@ -1,97 +1 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+NotificationContentExtension.xcscheme b/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+NotificationContentExtension.xcscheme
index e49afaf107..08fc8c1eb4 100644
--- a/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+NotificationContentExtension.xcscheme
+++ b/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+NotificationContentExtension.xcscheme
@@ -1,97 +1 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+NotificationServiceExtension.xcscheme b/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+NotificationServiceExtension.xcscheme
index 749f43806b..c3e465a825 100644
--- a/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+NotificationServiceExtension.xcscheme
+++ b/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+NotificationServiceExtension.xcscheme
@@ -1,97 +1 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+ShareExtension.xcscheme b/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+ShareExtension.xcscheme
index df5967d397..22e9d40515 100644
--- a/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+ShareExtension.xcscheme
+++ b/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+ShareExtension.xcscheme
@@ -1,97 +1 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+WidgetExtension.xcscheme b/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+WidgetExtension.xcscheme
index e1435ba40b..b53d54939b 100644
--- a/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+WidgetExtension.xcscheme
+++ b/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck+WidgetExtension.xcscheme
@@ -1,97 +1 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck.xcscheme b/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck.xcscheme
index e009a59b64..a58b71fc1a 100644
--- a/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck.xcscheme
+++ b/Telegram_Buck.xcworkspace/xcshareddata/xcschemes/Telegram_Buck.xcscheme
@@ -1,2602 +1 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/buildbox/build-telegram.sh b/buildbox/build-telegram.sh
index bed9a6da0d..e56f68170d 100644
--- a/buildbox/build-telegram.sh
+++ b/buildbox/build-telegram.sh
@@ -106,6 +106,10 @@ if [ "$BUILD_CONFIGURATION" == "hockeyapp" ] || [ "$BUILD_CONFIGURATION" == "app
echo "TELEGRAM_BUILD_APPSTORE_TEAM_NAME is not set"
exit 1
fi
+ if [ -z "$TELEGRAM_BUILD_APPSTORE_USERNAME" ]; then
+ echo "TELEGRAM_BUILD_APPSTORE_USERNAME is not set"
+ exit 1
+ fi
fi
fi
@@ -166,7 +170,7 @@ else
fi
scp -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -pr "$BUILDBOX_DIR/guest-build-telegram.sh" "$BUILDBOX_DIR/transient-data/source.tar" telegram@"$VM_IP":
-ssh -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null telegram@"$VM_IP" -o ServerAliveInterval=60 -t "export TELEGRAM_BUILD_APPSTORE_PASSWORD=\"$TELEGRAM_BUILD_APPSTORE_PASSWORD\"; export TELEGRAM_BUILD_APPSTORE_TEAM_NAME=\"$TELEGRAM_BUILD_APPSTORE_TEAM_NAME\"; export BUILD_NUMBER=\"$BUILD_NUMBER\"; export COMMIT_ID=\"$COMMIT_ID\"; export COMMIT_AUTHOR=\"$COMMIT_AUTHOR\"; export BUCK_HTTP_CACHE=\"$BUCK_HTTP_CACHE\"; bash -l guest-build-telegram.sh $BUILD_CONFIGURATION" || true
+ssh -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null telegram@"$VM_IP" -o ServerAliveInterval=60 -t "export TELEGRAM_BUILD_APPSTORE_PASSWORD=\"$TELEGRAM_BUILD_APPSTORE_PASSWORD\"; export TELEGRAM_BUILD_APPSTORE_TEAM_NAME=\"$TELEGRAM_BUILD_APPSTORE_TEAM_NAME\"; export TELEGRAM_BUILD_APPSTORE_USERNAME=\"$TELEGRAM_BUILD_APPSTORE_USERNAME\"; export BUILD_NUMBER=\"$BUILD_NUMBER\"; export COMMIT_ID=\"$COMMIT_ID\"; export COMMIT_AUTHOR=\"$COMMIT_AUTHOR\"; export BUCK_HTTP_CACHE=\"$BUCK_HTTP_CACHE\"; bash -l guest-build-telegram.sh $BUILD_CONFIGURATION" || true
if [ "$BUILD_CONFIGURATION" == "appstore" ]; then
ARCHIVE_PATH="$HOME/telegram-builds-archive"
diff --git a/buildbox/guest-build-telegram.sh b/buildbox/guest-build-telegram.sh
index eba6b956c5..06c3ab2335 100644
--- a/buildbox/guest-build-telegram.sh
+++ b/buildbox/guest-build-telegram.sh
@@ -30,6 +30,7 @@ elif [ "$1" == "appstore" ]; then
echo "TELEGRAM_BUILD_APPSTORE_TEAM_NAME is not set"
exit 1
fi
+ FASTLANE_ITC_USERNAME="$TELEGRAM_BUILD_APPSTORE_USERNAME"
FASTLANE_PASSWORD="$TELEGRAM_BUILD_APPSTORE_PASSWORD"
FASTLANE_ITC_TEAM_NAME="$TELEGRAM_BUILD_APPSTORE_TEAM_NAME"
CERTS_PATH="codesigning_data/certs"
@@ -129,7 +130,11 @@ else
cp "build/DSYMs.zip" "./$RESULT_DSYM_NAME"
export DELIVER_ITMSTRANSPORTER_ADDITIONAL_UPLOAD_PARAMETERS="-t DAV"
- FASTLANE_PASSWORD="$FASTLANE_PASSWORD" FASTLANE_ITC_TEAM_NAME="$FASTLANE_ITC_TEAM_NAME" fastlane "$FASTLANE_BUILD_CONFIGURATION" build_number:"$BUILD_NUMBER" commit_hash:"$COMMIT_ID" commit_author:"$COMMIT_AUTHOR" skip_build:1
+ if [ "$1" == "appstore" ]; then
+ xcrun altool --upload-app --type ios --file "$RESULT_IPA_NAME" --username "$FASTLANE_ITC_USERNAME" --password "$FASTLANE_PASSWORD"
+ else
+ FASTLANE_PASSWORD="$FASTLANE_PASSWORD" FASTLANE_ITC_TEAM_NAME="$FASTLANE_ITC_TEAM_NAME" fastlane "$FASTLANE_BUILD_CONFIGURATION" build_number:"$BUILD_NUMBER" commit_hash:"$COMMIT_ID" commit_author:"$COMMIT_AUTHOR" skip_build:1
+ fi
cd "$BASE_DIR"
fi
diff --git a/submodules/SSignalKit/SwiftSignalKit/SwiftSignalKit.xcodeproj/xcshareddata/xcschemes/SwiftSignalKit.xcscheme b/submodules/SSignalKit/SwiftSignalKit/SwiftSignalKit.xcodeproj/xcshareddata/xcschemes/SwiftSignalKit.xcscheme
index c82fe8764f..6eae9bf611 100644
--- a/submodules/SSignalKit/SwiftSignalKit/SwiftSignalKit.xcodeproj/xcshareddata/xcschemes/SwiftSignalKit.xcscheme
+++ b/submodules/SSignalKit/SwiftSignalKit/SwiftSignalKit.xcodeproj/xcshareddata/xcschemes/SwiftSignalKit.xcscheme
@@ -1,71 +1 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/submodules/ton/tonlib-src/crypto/block/transaction.cpp b/submodules/ton/tonlib-src/crypto/block/transaction.cpp
index 77f3ad0756..11f118d4d3 100644
--- a/submodules/ton/tonlib-src/crypto/block/transaction.cpp
+++ b/submodules/ton/tonlib-src/crypto/block/transaction.cpp
@@ -1027,6 +1027,12 @@ bool Transaction::prepare_action_phase(const ActionPhaseConfig& cfg) {
break;
case block::gen::OutAction::action_send_msg:
err_code = try_action_send_msg(cs, ap, cfg);
+ if (err_code == -2) {
+ err_code = try_action_send_msg(cs, ap, cfg, 1);
+ if (err_code == -2) {
+ err_code = try_action_send_msg(cs, ap, cfg, 2);
+ }
+ }
break;
case block::gen::OutAction::action_reserve_currency:
err_code = try_action_reserve_currency(cs, ap, cfg);
@@ -1240,22 +1246,60 @@ bool Transaction::check_rewrite_dest_addr(Ref& dest_addr, const A
return true;
}
-int Transaction::try_action_send_msg(vm::CellSlice& cs, ActionPhase& ap, const ActionPhaseConfig& cfg) {
+int Transaction::try_action_send_msg(const vm::CellSlice& cs0, ActionPhase& ap, const ActionPhaseConfig& cfg,
+ int redoing) {
block::gen::OutAction::Record_action_send_msg act_rec;
// mode: +128 = attach all remaining balance, +64 = attach all remaining balance of the inbound message, +1 = pay message fees, +2 = skip if message cannot be sent
+ vm::CellSlice cs{cs0};
if (!tlb::unpack_exact(cs, act_rec) || (act_rec.mode & ~0xc3) || (act_rec.mode & 0xc0) == 0xc0) {
return -1;
}
bool skip_invalid = (act_rec.mode & 2);
- auto cs2 = vm::load_cell_slice(act_rec.out_msg);
- // try to parse suggested message in cs2
+ // try to parse suggested message in act_rec.out_msg
td::RefInt256 fwd_fee, ihr_fee;
- bool ext_msg = cs2.prefetch_ulong(1);
+ block::gen::MessageRelaxed::Record msg;
+ if (!tlb::type_unpack_cell(act_rec.out_msg, block::gen::t_MessageRelaxed_Any, msg)) {
+ return -1;
+ }
+ if (redoing >= 1) {
+ if (msg.init->size_refs() >= 2) {
+ LOG(DEBUG) << "moving the StateInit of a suggested outbound message into a separate cell";
+ // init:(Maybe (Either StateInit ^StateInit))
+ // transform (just (left z:StateInit)) into (just (right z:^StateInit))
+ CHECK(msg.init.write().fetch_ulong(2) == 2);
+ vm::CellBuilder cb;
+ Ref cell;
+ CHECK(cb.append_cellslice_bool(std::move(msg.init)) // StateInit
+ && cb.finalize_to(cell) // -> ^StateInit
+ && cb.store_long_bool(3, 2) // (just (right ... ))
+ && cb.store_ref_bool(std::move(cell)) // z:^StateInit
+ && cb.finalize_to(cell));
+ msg.init = vm::load_cell_slice_ref(std::move(cell));
+ } else {
+ redoing = 2;
+ }
+ }
+ if (redoing >= 2 && msg.body->size_ext() > 1 && msg.body->prefetch_ulong(1) == 0) {
+ LOG(DEBUG) << "moving the body of a suggested outbound message into a separate cell";
+ // body:(Either X ^X)
+ // transform (left x:X) into (right x:^X)
+ CHECK(msg.body.write().fetch_ulong(1) == 0);
+ vm::CellBuilder cb;
+ Ref cell;
+ CHECK(cb.append_cellslice_bool(std::move(msg.body)) // X
+ && cb.finalize_to(cell) // -> ^X
+ && cb.store_long_bool(1, 1) // (right ... )
+ && cb.store_ref_bool(std::move(cell)) // x:^X
+ && cb.finalize_to(cell));
+ msg.body = vm::load_cell_slice_ref(std::move(cell));
+ }
+
block::gen::CommonMsgInfoRelaxed::Record_int_msg_info info;
+ bool ext_msg = msg.info->prefetch_ulong(1);
if (ext_msg) {
// ext_out_msg_info$11 constructor of CommonMsgInfoRelaxed
block::gen::CommonMsgInfoRelaxed::Record_ext_out_msg_info erec;
- if (!tlb::unpack(cs2, erec)) {
+ if (!tlb::csr_unpack(msg.info, erec)) {
return -1;
}
info.src = std::move(erec.src);
@@ -1267,7 +1311,7 @@ int Transaction::try_action_send_msg(vm::CellSlice& cs, ActionPhase& ap, const A
fwd_fee = ihr_fee = td::RefInt256{true, 0};
} else {
// int_msg_info$0 constructor
- if (!tlb::unpack(cs2, info) || !block::tlb::t_CurrencyCollection.validate_csr(info.value)) {
+ if (!tlb::csr_unpack(msg.info, info) || !block::tlb::t_CurrencyCollection.validate_csr(info.value)) {
return -1;
}
fwd_fee = block::tlb::t_Grams.as_integer(info.fwd_fee);
@@ -1295,12 +1339,11 @@ int Transaction::try_action_send_msg(vm::CellSlice& cs, ActionPhase& ap, const A
// compute size of message
vm::CellStorageStat sstat; // for message size
// preliminary storage estimation of the resulting message
- sstat.compute_used_storage(cs2); // message body
+ sstat.add_used_storage(msg.init, true, 3); // message init
+ sstat.add_used_storage(msg.body, true, 3); // message body (the root cell itself is not counted)
if (!ext_msg) {
sstat.add_used_storage(info.value->prefetch_ref());
}
- sstat.bits -= cs2.size(); // bits in the root cells are free
- sstat.cells--; // the root cell itself is not counted as a cell
LOG(DEBUG) << "storage paid for a message: " << sstat.cells << " cells, " << sstat.bits << " bits";
if (sstat.bits > max_msg_bits || sstat.cells > max_msg_cells) {
LOG(DEBUG) << "message too large, invalid";
@@ -1397,17 +1440,15 @@ int Transaction::try_action_send_msg(vm::CellSlice& cs, ActionPhase& ap, const A
// re-pack message value
CHECK(req.pack_to(info.value));
- vm::CellBuilder cb;
- CHECK(block::tlb::t_Grams.store_integer_ref(cb, fwd_fee_remain) &&
- (info.fwd_fee = load_cell_slice_ref(cb.finalize())).not_null());
- CHECK(block::tlb::t_Grams.store_integer_ref(cb, ihr_fee) &&
- (info.ihr_fee = load_cell_slice_ref(cb.finalize())).not_null());
+ CHECK(block::tlb::t_Grams.pack_integer(info.fwd_fee, fwd_fee_remain));
+ CHECK(block::tlb::t_Grams.pack_integer(info.ihr_fee, ihr_fee));
// serialize message
- CHECK(tlb::pack(cb, info));
- if (!cb.append_cellslice_bool(cs2)) {
+ CHECK(tlb::csr_pack(msg.info, info));
+ vm::CellBuilder cb;
+ if (!tlb::type_pack(cb, block::gen::t_MessageRelaxed_Any, msg)) {
LOG(DEBUG) << "outbound message does not fit into a cell after rewriting";
- return 39;
+ return redoing < 2 ? -2 : (skip_invalid ? 0 : 39);
}
new_msg_bits = cb.size();
@@ -1438,11 +1479,11 @@ int Transaction::try_action_send_msg(vm::CellSlice& cs, ActionPhase& ap, const A
erec.dest = info.dest;
erec.created_at = info.created_at;
erec.created_lt = info.created_lt;
+ CHECK(tlb::csr_pack(msg.info, erec));
vm::CellBuilder cb;
- CHECK(tlb::pack(cb, erec));
- if (!cb.append_cellslice_bool(cs2)) {
+ if (!tlb::type_pack(cb, block::gen::t_MessageRelaxed_Any, msg)) {
LOG(DEBUG) << "outbound message does not fit into a cell after rewriting";
- return 39;
+ return redoing < 2 ? -2 : (skip_invalid ? 0 : 39);
}
new_msg_bits = cb.size();
@@ -1461,6 +1502,8 @@ int Transaction::try_action_send_msg(vm::CellSlice& cs, ActionPhase& ap, const A
}
if (!block::gen::t_Message_Any.validate_ref(new_msg)) {
LOG(ERROR) << "generated outbound message is not a valid (Message Any) according to automated check";
+ block::gen::t_Message_Any.print_ref(std::cerr, new_msg);
+ vm::load_cell_slice(new_msg).print_rec(std::cerr);
return -1;
}
if (verbosity > 2) {
diff --git a/submodules/ton/tonlib-src/crypto/block/transaction.h b/submodules/ton/tonlib-src/crypto/block/transaction.h
index 94b2a85300..45e824c1e8 100644
--- a/submodules/ton/tonlib-src/crypto/block/transaction.h
+++ b/submodules/ton/tonlib-src/crypto/block/transaction.h
@@ -390,7 +390,7 @@ struct Transaction {
Ref prepare_vm_c7(const ComputePhaseConfig& cfg) const;
bool prepare_rand_seed(td::BitArray<256>& rand_seed, const ComputePhaseConfig& cfg) const;
int try_action_set_code(vm::CellSlice& cs, ActionPhase& ap, const ActionPhaseConfig& cfg);
- int try_action_send_msg(vm::CellSlice& cs, ActionPhase& ap, const ActionPhaseConfig& cfg);
+ int try_action_send_msg(const vm::CellSlice& cs, ActionPhase& ap, const ActionPhaseConfig& cfg, int redoing = 0);
int try_action_reserve_currency(vm::CellSlice& cs, ActionPhase& ap, const ActionPhaseConfig& cfg);
bool check_replace_src_addr(Ref& src_addr) const;
bool check_rewrite_dest_addr(Ref& dest_addr, const ActionPhaseConfig& cfg,
diff --git a/submodules/ton/tonlib-src/crypto/tl/tlblib.hpp b/submodules/ton/tonlib-src/crypto/tl/tlblib.hpp
index 1e4f458c4e..b5d51c3154 100644
--- a/submodules/ton/tonlib-src/crypto/tl/tlblib.hpp
+++ b/submodules/ton/tonlib-src/crypto/tl/tlblib.hpp
@@ -176,6 +176,10 @@ class TLB {
virtual bool store_integer_ref(vm::CellBuilder& cb, td::RefInt256 value) const {
return value.not_null() && store_integer_value(cb, *value);
}
+ bool pack_integer(Ref& csr, td::RefInt256 value) const {
+ vm::CellBuilder cb;
+ return store_integer_ref(cb, value) && (csr = vm::load_cell_slice_ref(cb.finalize())).not_null();
+ }
virtual bool add_values(vm::CellBuilder& cb, vm::CellSlice& cs1, vm::CellSlice& cs2) const {
td::RefInt256 x = as_integer_skip(cs1), y = as_integer_skip(cs2);
return x.not_null() && y.not_null() && store_integer_ref(cb, x += std::move(y));
diff --git a/submodules/ton/tonlib-src/crypto/vm/boc.cpp b/submodules/ton/tonlib-src/crypto/vm/boc.cpp
index 0ea69f3b80..9b60884d10 100644
--- a/submodules/ton/tonlib-src/crypto/vm/boc.cpp
+++ b/submodules/ton/tonlib-src/crypto/vm/boc.cpp
@@ -988,27 +988,27 @@ td::Result std_boc_serialize_multi(std::vector[> roots
*
*/
-bool CellStorageStat::compute_used_storage(Ref cs_ref, bool kill_dup, bool skip_count_root) {
+bool CellStorageStat::compute_used_storage(Ref cs_ref, bool kill_dup, unsigned skip_count_root) {
clear();
return add_used_storage(std::move(cs_ref), kill_dup, skip_count_root) && clear_seen();
}
-bool CellStorageStat::compute_used_storage(const CellSlice& cs, bool kill_dup, bool skip_count_root) {
+bool CellStorageStat::compute_used_storage(const CellSlice& cs, bool kill_dup, unsigned skip_count_root) {
clear();
return add_used_storage(cs, kill_dup, skip_count_root) && clear_seen();
}
-bool CellStorageStat::compute_used_storage(CellSlice&& cs, bool kill_dup, bool skip_count_root) {
+bool CellStorageStat::compute_used_storage(CellSlice&& cs, bool kill_dup, unsigned skip_count_root) {
clear();
return add_used_storage(std::move(cs), kill_dup, skip_count_root) && clear_seen();
}
-bool CellStorageStat::compute_used_storage(Ref cell, bool kill_dup, bool skip_count_root) {
+bool CellStorageStat::compute_used_storage(Ref cell, bool kill_dup, unsigned skip_count_root) {
clear();
return add_used_storage(std::move(cell), kill_dup, skip_count_root) && clear_seen();
}
-bool CellStorageStat::add_used_storage(Ref cs_ref, bool kill_dup, bool skip_count_root) {
+bool CellStorageStat::add_used_storage(Ref cs_ref, bool kill_dup, unsigned skip_count_root) {
if (cs_ref->is_unique()) {
return add_used_storage(std::move(cs_ref.unique_write()), kill_dup, skip_count_root);
} else {
@@ -1016,11 +1016,13 @@ bool CellStorageStat::add_used_storage(Ref cs_ref, bool kill_dup,
}
}
-bool CellStorageStat::add_used_storage(const CellSlice& cs, bool kill_dup, bool skip_count_root) {
- if (!skip_count_root) {
+bool CellStorageStat::add_used_storage(const CellSlice& cs, bool kill_dup, unsigned skip_count_root) {
+ if (!(skip_count_root & 1)) {
++cells;
}
- bits += cs.size();
+ if (!(skip_count_root & 2)) {
+ bits += cs.size();
+ }
for (unsigned i = 0; i < cs.size_refs(); i++) {
if (!add_used_storage(cs.prefetch_ref(i), kill_dup)) {
return false;
@@ -1029,11 +1031,13 @@ bool CellStorageStat::add_used_storage(const CellSlice& cs, bool kill_dup, bool
return true;
}
-bool CellStorageStat::add_used_storage(CellSlice&& cs, bool kill_dup, bool skip_count_root) {
- if (!skip_count_root) {
+bool CellStorageStat::add_used_storage(CellSlice&& cs, bool kill_dup, unsigned skip_count_root) {
+ if (!(skip_count_root & 1)) {
++cells;
}
- bits += cs.size();
+ if (!(skip_count_root & 2)) {
+ bits += cs.size();
+ }
while (cs.size_refs()) {
if (!add_used_storage(cs.fetch_ref(), kill_dup)) {
return false;
@@ -1042,7 +1046,7 @@ bool CellStorageStat::add_used_storage(CellSlice&& cs, bool kill_dup, bool skip_
return true;
}
-bool CellStorageStat::add_used_storage(Ref cell, bool kill_dup, bool skip_count_root) {
+bool CellStorageStat::add_used_storage(Ref cell, bool kill_dup, unsigned skip_count_root) {
if (cell.is_null()) {
return false;
}
diff --git a/submodules/ton/tonlib-src/crypto/vm/boc.h b/submodules/ton/tonlib-src/crypto/vm/boc.h
index 5b4e4e2c4b..29f582be70 100644
--- a/submodules/ton/tonlib-src/crypto/vm/boc.h
+++ b/submodules/ton/tonlib-src/crypto/vm/boc.h
@@ -122,15 +122,15 @@ struct CellStorageStat {
cells = bits = public_cells = 0;
clear_seen();
}
- bool compute_used_storage(Ref cs_ref, bool kill_dup = true, bool skip_count_root = false);
- bool compute_used_storage(const CellSlice& cs, bool kill_dup = true, bool skip_count_root = false);
- bool compute_used_storage(CellSlice&& cs, bool kill_dup = true, bool skip_count_root = false);
- bool compute_used_storage(Ref cell, bool kill_dup = true, bool skip_count_root = false);
+ bool compute_used_storage(Ref cs_ref, bool kill_dup = true, unsigned skip_count_root = 0);
+ bool compute_used_storage(const CellSlice& cs, bool kill_dup = true, unsigned skip_count_root = 0);
+ bool compute_used_storage(CellSlice&& cs, bool kill_dup = true, unsigned skip_count_root = 0);
+ bool compute_used_storage(Ref cell, bool kill_dup = true, unsigned skip_count_root = 0);
- bool add_used_storage(Ref cs_ref, bool kill_dup = true, bool skip_count_root = false);
- bool add_used_storage(const CellSlice& cs, bool kill_dup = true, bool skip_count_root = false);
- bool add_used_storage(CellSlice&& cs, bool kill_dup = true, bool skip_count_root = false);
- bool add_used_storage(Ref cell, bool kill_dup = true, bool skip_count_root = false);
+ bool add_used_storage(Ref cs_ref, bool kill_dup = true, unsigned skip_count_root = 0);
+ bool add_used_storage(const CellSlice& cs, bool kill_dup = true, unsigned skip_count_root = 0);
+ bool add_used_storage(CellSlice&& cs, bool kill_dup = true, unsigned skip_count_root = 0);
+ bool add_used_storage(Ref cell, bool kill_dup = true, unsigned skip_count_root = 0);
};
struct CellSerializationInfo {
diff --git a/submodules/ton/tonlib-src/crypto/vm/cells/CellBuilder.cpp b/submodules/ton/tonlib-src/crypto/vm/cells/CellBuilder.cpp
index ec933c071b..37940f718a 100644
--- a/submodules/ton/tonlib-src/crypto/vm/cells/CellBuilder.cpp
+++ b/submodules/ton/tonlib-src/crypto/vm/cells/CellBuilder.cpp
@@ -207,9 +207,8 @@ bool CellBuilder::store_bits_bool(const unsigned char* str, std::size_t bit_coun
CellBuilder& CellBuilder::store_bits(const unsigned char* str, std::size_t bit_count, int bit_offset) {
unsigned pos = bits;
- if (prepare_reserve(bit_count)) {
- td::bitstring::bits_memcpy(data, pos, str, bit_offset, bit_count);
- }
+ ensure_throw(prepare_reserve(bit_count));
+ td::bitstring::bits_memcpy(data, pos, str, bit_offset, bit_count);
return *this;
}
diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.cpp b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.cpp
index a937cb69bf..3a3e034c82 100644
--- a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.cpp
+++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.cpp
@@ -331,6 +331,33 @@ void sendGramsResult::store(td::TlStorerToString &s, const char *field_name) con
}
}
+unpackedAccountAddress::unpackedAccountAddress()
+ : workchain_id_()
+ , bounceable_()
+ , testnet_()
+ , addr_()
+{}
+
+unpackedAccountAddress::unpackedAccountAddress(std::int32_t workchain_id_, bool bounceable_, bool testnet_, std::string const &addr_)
+ : workchain_id_(workchain_id_)
+ , bounceable_(bounceable_)
+ , testnet_(testnet_)
+ , addr_(std::move(addr_))
+{}
+
+const std::int32_t unpackedAccountAddress::ID;
+
+void unpackedAccountAddress::store(td::TlStorerToString &s, const char *field_name) const {
+ if (!LOG_IS_STRIPPED(ERROR)) {
+ s.store_class_begin(field_name, "unpackedAccountAddress");
+ s.store_field("workchain_id", workchain_id_);
+ s.store_field("bounceable", bounceable_);
+ s.store_field("testnet", testnet_);
+ s.store_bytes_field("addr", addr_);
+ s.store_class_end();
+ }
+}
+
updateSendLiteServerQuery::updateSendLiteServerQuery()
: id_()
, data_()
@@ -1168,6 +1195,24 @@ void options_setConfig::store(td::TlStorerToString &s, const char *field_name) c
}
}
+packAccountAddress::packAccountAddress()
+ : account_address_()
+{}
+
+packAccountAddress::packAccountAddress(object_ptr &&account_address_)
+ : account_address_(std::move(account_address_))
+{}
+
+const std::int32_t packAccountAddress::ID;
+
+void packAccountAddress::store(td::TlStorerToString &s, const char *field_name) const {
+ if (!LOG_IS_STRIPPED(ERROR)) {
+ s.store_class_begin(field_name, "packAccountAddress");
+ if (account_address_ == nullptr) { s.store_field("account_address", "null"); } else { account_address_->store(s, "account_address"); }
+ s.store_class_end();
+ }
+}
+
raw_getAccountAddress::raw_getAccountAddress()
: initital_account_state_()
{}
@@ -1459,6 +1504,24 @@ void testWallet_sendGrams::store(td::TlStorerToString &s, const char *field_name
}
}
+unpackAccountAddress::unpackAccountAddress()
+ : account_address_()
+{}
+
+unpackAccountAddress::unpackAccountAddress(std::string const &account_address_)
+ : account_address_(std::move(account_address_))
+{}
+
+const std::int32_t unpackAccountAddress::ID;
+
+void unpackAccountAddress::store(td::TlStorerToString &s, const char *field_name) const {
+ if (!LOG_IS_STRIPPED(ERROR)) {
+ s.store_class_begin(field_name, "unpackAccountAddress");
+ s.store_field("account_address", account_address_);
+ s.store_class_end();
+ }
+}
+
wallet_getAccountAddress::wallet_getAccountAddress()
: initital_account_state_()
{}
diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.h b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.h
index 70e426294a..c4a9fa6d15 100644
--- a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.h
+++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.h
@@ -74,6 +74,8 @@ class options;
class sendGramsResult;
+class unpackedAccountAddress;
+
class updateSendLiteServerQuery;
class generic_AccountState;
@@ -387,6 +389,25 @@ class sendGramsResult final : public Object {
void store(td::TlStorerToString &s, const char *field_name) const final;
};
+class unpackedAccountAddress final : public Object {
+ public:
+ std::int32_t workchain_id_;
+ bool bounceable_;
+ bool testnet_;
+ std::string addr_;
+
+ unpackedAccountAddress();
+
+ unpackedAccountAddress(std::int32_t workchain_id_, bool bounceable_, bool testnet_, std::string const &addr_);
+
+ static const std::int32_t ID = 1892946998;
+ std::int32_t get_id() const final {
+ return ID;
+ }
+
+ void store(td::TlStorerToString &s, const char *field_name) const final;
+};
+
class updateSendLiteServerQuery final : public Object {
public:
std::int64_t id_;
@@ -1110,6 +1131,24 @@ class options_setConfig final : public Function {
void store(td::TlStorerToString &s, const char *field_name) const final;
};
+class packAccountAddress final : public Function {
+ public:
+ object_ptr account_address_;
+
+ packAccountAddress();
+
+ explicit packAccountAddress(object_ptr &&account_address_);
+
+ static const std::int32_t ID = -1388561940;
+ std::int32_t get_id() const final {
+ return ID;
+ }
+
+ using ReturnType = object_ptr;
+
+ void store(td::TlStorerToString &s, const char *field_name) const final;
+};
+
class raw_getAccountAddress final : public Function {
public:
object_ptr initital_account_state_;
@@ -1385,6 +1424,24 @@ class testWallet_sendGrams final : public Function {
void store(td::TlStorerToString &s, const char *field_name) const final;
};
+class unpackAccountAddress final : public Function {
+ public:
+ std::string account_address_;
+
+ unpackAccountAddress();
+
+ explicit unpackAccountAddress(std::string const &account_address_);
+
+ static const std::int32_t ID = -682459063;
+ std::int32_t get_id() const final {
+ return ID;
+ }
+
+ using ReturnType = object_ptr;
+
+ void store(td::TlStorerToString &s, const char *field_name) const final;
+};
+
class wallet_getAccountAddress final : public Function {
public:
object_ptr initital_account_state_;
diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.hpp b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.hpp
index 6fcd2e321b..920df0e9eb 100644
--- a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.hpp
+++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.hpp
@@ -65,6 +65,9 @@ bool downcast_call(Object &obj, const T &func) {
case sendGramsResult::ID:
func(static_cast(obj));
return true;
+ case unpackedAccountAddress::ID:
+ func(static_cast(obj));
+ return true;
case updateSendLiteServerQuery::ID:
func(static_cast(obj));
return true;
@@ -199,6 +202,9 @@ bool downcast_call(Function &obj, const T &func) {
case options_setConfig::ID:
func(static_cast(obj));
return true;
+ case packAccountAddress::ID:
+ func(static_cast(obj));
+ return true;
case raw_getAccountAddress::ID:
func(static_cast(obj));
return true;
@@ -244,6 +250,9 @@ bool downcast_call(Function &obj, const T &func) {
case testWallet_sendGrams::ID:
func(static_cast(obj));
return true;
+ case unpackAccountAddress::ID:
+ func(static_cast(obj));
+ return true;
case wallet_getAccountAddress::ID:
func(static_cast(obj));
return true;
diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api_json.cpp b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api_json.cpp
index a3748d7db0..29ee340f62 100644
--- a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api_json.cpp
+++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api_json.cpp
@@ -59,6 +59,7 @@ Result tl_constructor_from_string(tonlib_api::Object *object, const std::
{"ok", -722616727},
{"options", 789823302},
{"sendGramsResult", -858318471},
+ {"unpackedAccountAddress", 1892946998},
{"updateSendLiteServerQuery", -1555130916},
{"generic.accountStateRaw", -1387096685},
{"generic.accountStateTestWallet", -1041955397},
@@ -108,6 +109,7 @@ Result tl_constructor_from_string(tonlib_api::Function *object, const std
{"onLiteServerQueryError", -677427533},
{"onLiteServerQueryResult", 2056444510},
{"options.setConfig", 646497241},
+ {"packAccountAddress", -1388561940},
{"raw.getAccountAddress", -521283849},
{"raw.getAccountState", 663706721},
{"raw.getTransactions", 935377269},
@@ -123,6 +125,7 @@ Result tl_constructor_from_string(tonlib_api::Function *object, const std
{"testWallet.getAccountState", 654082364},
{"testWallet.init", 419055225},
{"testWallet.sendGrams", 1290131585},
+ {"unpackAccountAddress", -682459063},
{"wallet.getAccountAddress", -1004103180},
{"wallet.getAccountState", 462294850},
{"wallet.init", 1528056782},
@@ -317,6 +320,33 @@ Status from_json(tonlib_api::sendGramsResult &to, JsonObject &from) {
}
return Status::OK();
}
+Status from_json(tonlib_api::unpackedAccountAddress &to, JsonObject &from) {
+ {
+ TRY_RESULT(value, get_json_object_field(from, "workchain_id", JsonValue::Type::Null, true));
+ if (value.type() != JsonValue::Type::Null) {
+ TRY_STATUS(from_json(to.workchain_id_, value));
+ }
+ }
+ {
+ TRY_RESULT(value, get_json_object_field(from, "bounceable", JsonValue::Type::Null, true));
+ if (value.type() != JsonValue::Type::Null) {
+ TRY_STATUS(from_json(to.bounceable_, value));
+ }
+ }
+ {
+ TRY_RESULT(value, get_json_object_field(from, "testnet", JsonValue::Type::Null, true));
+ if (value.type() != JsonValue::Type::Null) {
+ TRY_STATUS(from_json(to.testnet_, value));
+ }
+ }
+ {
+ TRY_RESULT(value, get_json_object_field(from, "addr", JsonValue::Type::Null, true));
+ if (value.type() != JsonValue::Type::Null) {
+ TRY_STATUS(from_json_bytes(to.addr_, value));
+ }
+ }
+ return Status::OK();
+}
Status from_json(tonlib_api::updateSendLiteServerQuery &to, JsonObject &from) {
{
TRY_RESULT(value, get_json_object_field(from, "id", JsonValue::Type::Null, true));
@@ -935,6 +965,15 @@ Status from_json(tonlib_api::options_setConfig &to, JsonObject &from) {
}
return Status::OK();
}
+Status from_json(tonlib_api::packAccountAddress &to, JsonObject &from) {
+ {
+ TRY_RESULT(value, get_json_object_field(from, "account_address", JsonValue::Type::Null, true));
+ if (value.type() != JsonValue::Type::Null) {
+ TRY_STATUS(from_json(to.account_address_, value));
+ }
+ }
+ return Status::OK();
+}
Status from_json(tonlib_api::raw_getAccountAddress &to, JsonObject &from) {
{
TRY_RESULT(value, get_json_object_field(from, "initital_account_state", JsonValue::Type::Null, true));
@@ -1124,6 +1163,15 @@ Status from_json(tonlib_api::testWallet_sendGrams &to, JsonObject &from) {
}
return Status::OK();
}
+Status from_json(tonlib_api::unpackAccountAddress &to, JsonObject &from) {
+ {
+ TRY_RESULT(value, get_json_object_field(from, "account_address", JsonValue::Type::Null, true));
+ if (value.type() != JsonValue::Type::Null) {
+ TRY_STATUS(from_json(to.account_address_, value));
+ }
+ }
+ return Status::OK();
+}
Status from_json(tonlib_api::wallet_getAccountAddress &to, JsonObject &from) {
{
TRY_RESULT(value, get_json_object_field(from, "initital_account_state", JsonValue::Type::Null, true));
@@ -1287,6 +1335,14 @@ void to_json(JsonValueScope &jv, const tonlib_api::sendGramsResult &object) {
jo << ctie("@type", "sendGramsResult");
jo << ctie("sent_until", ToJson(object.sent_until_));
}
+void to_json(JsonValueScope &jv, const tonlib_api::unpackedAccountAddress &object) {
+ auto jo = jv.enter_object();
+ jo << ctie("@type", "unpackedAccountAddress");
+ jo << ctie("workchain_id", ToJson(object.workchain_id_));
+ jo << ctie("bounceable", ToJson(object.bounceable_));
+ jo << ctie("testnet", ToJson(object.testnet_));
+ jo << ctie("addr", ToJson(JsonBytes{object.addr_}));
+}
void to_json(JsonValueScope &jv, const tonlib_api::updateSendLiteServerQuery &object) {
auto jo = jv.enter_object();
jo << ctie("@type", "updateSendLiteServerQuery");
@@ -1589,6 +1645,13 @@ void to_json(JsonValueScope &jv, const tonlib_api::options_setConfig &object) {
jo << ctie("config", ToJson(object.config_));
}
}
+void to_json(JsonValueScope &jv, const tonlib_api::packAccountAddress &object) {
+ auto jo = jv.enter_object();
+ jo << ctie("@type", "packAccountAddress");
+ if (object.account_address_) {
+ jo << ctie("account_address", ToJson(object.account_address_));
+ }
+}
void to_json(JsonValueScope &jv, const tonlib_api::raw_getAccountAddress &object) {
auto jo = jv.enter_object();
jo << ctie("@type", "raw.getAccountAddress");
@@ -1697,6 +1760,11 @@ void to_json(JsonValueScope &jv, const tonlib_api::testWallet_sendGrams &object)
jo << ctie("amount", ToJson(JsonInt64{object.amount_}));
jo << ctie("message", ToJson(JsonBytes{object.message_}));
}
+void to_json(JsonValueScope &jv, const tonlib_api::unpackAccountAddress &object) {
+ auto jo = jv.enter_object();
+ jo << ctie("@type", "unpackAccountAddress");
+ jo << ctie("account_address", ToJson(object.account_address_));
+}
void to_json(JsonValueScope &jv, const tonlib_api::wallet_getAccountAddress &object) {
auto jo = jv.enter_object();
jo << ctie("@type", "wallet.getAccountAddress");
diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api_json.h b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api_json.h
index ebccc0aa13..ebe3a9cfd7 100644
--- a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api_json.h
+++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api_json.h
@@ -32,6 +32,7 @@ Status from_json(tonlib_api::logVerbosityLevel &to, JsonObject &from);
Status from_json(tonlib_api::ok &to, JsonObject &from);
Status from_json(tonlib_api::options &to, JsonObject &from);
Status from_json(tonlib_api::sendGramsResult &to, JsonObject &from);
+Status from_json(tonlib_api::unpackedAccountAddress &to, JsonObject &from);
Status from_json(tonlib_api::updateSendLiteServerQuery &to, JsonObject &from);
Status from_json(tonlib_api::generic_accountStateRaw &to, JsonObject &from);
Status from_json(tonlib_api::generic_accountStateTestWallet &to, JsonObject &from);
@@ -72,6 +73,7 @@ Status from_json(tonlib_api::init &to, JsonObject &from);
Status from_json(tonlib_api::onLiteServerQueryError &to, JsonObject &from);
Status from_json(tonlib_api::onLiteServerQueryResult &to, JsonObject &from);
Status from_json(tonlib_api::options_setConfig &to, JsonObject &from);
+Status from_json(tonlib_api::packAccountAddress &to, JsonObject &from);
Status from_json(tonlib_api::raw_getAccountAddress &to, JsonObject &from);
Status from_json(tonlib_api::raw_getAccountState &to, JsonObject &from);
Status from_json(tonlib_api::raw_getTransactions &to, JsonObject &from);
@@ -87,6 +89,7 @@ Status from_json(tonlib_api::testWallet_getAccountAddress &to, JsonObject &from)
Status from_json(tonlib_api::testWallet_getAccountState &to, JsonObject &from);
Status from_json(tonlib_api::testWallet_init &to, JsonObject &from);
Status from_json(tonlib_api::testWallet_sendGrams &to, JsonObject &from);
+Status from_json(tonlib_api::unpackAccountAddress &to, JsonObject &from);
Status from_json(tonlib_api::wallet_getAccountAddress &to, JsonObject &from);
Status from_json(tonlib_api::wallet_getAccountState &to, JsonObject &from);
Status from_json(tonlib_api::wallet_init &to, JsonObject &from);
@@ -109,6 +112,7 @@ void to_json(JsonValueScope &jv, const tonlib_api::logVerbosityLevel &object);
void to_json(JsonValueScope &jv, const tonlib_api::ok &object);
void to_json(JsonValueScope &jv, const tonlib_api::options &object);
void to_json(JsonValueScope &jv, const tonlib_api::sendGramsResult &object);
+void to_json(JsonValueScope &jv, const tonlib_api::unpackedAccountAddress &object);
void to_json(JsonValueScope &jv, const tonlib_api::updateSendLiteServerQuery &object);
void to_json(JsonValueScope &jv, const tonlib_api::generic_AccountState &object);
void to_json(JsonValueScope &jv, const tonlib_api::generic_accountStateRaw &object);
@@ -150,6 +154,7 @@ void to_json(JsonValueScope &jv, const tonlib_api::init &object);
void to_json(JsonValueScope &jv, const tonlib_api::onLiteServerQueryError &object);
void to_json(JsonValueScope &jv, const tonlib_api::onLiteServerQueryResult &object);
void to_json(JsonValueScope &jv, const tonlib_api::options_setConfig &object);
+void to_json(JsonValueScope &jv, const tonlib_api::packAccountAddress &object);
void to_json(JsonValueScope &jv, const tonlib_api::raw_getAccountAddress &object);
void to_json(JsonValueScope &jv, const tonlib_api::raw_getAccountState &object);
void to_json(JsonValueScope &jv, const tonlib_api::raw_getTransactions &object);
@@ -165,6 +170,7 @@ void to_json(JsonValueScope &jv, const tonlib_api::testWallet_getAccountAddress
void to_json(JsonValueScope &jv, const tonlib_api::testWallet_getAccountState &object);
void to_json(JsonValueScope &jv, const tonlib_api::testWallet_init &object);
void to_json(JsonValueScope &jv, const tonlib_api::testWallet_sendGrams &object);
+void to_json(JsonValueScope &jv, const tonlib_api::unpackAccountAddress &object);
void to_json(JsonValueScope &jv, const tonlib_api::wallet_getAccountAddress &object);
void to_json(JsonValueScope &jv, const tonlib_api::wallet_getAccountState &object);
void to_json(JsonValueScope &jv, const tonlib_api::wallet_init &object);
diff --git a/submodules/ton/tonlib-src/tl/generate/scheme/tonlib_api.tl b/submodules/ton/tonlib-src/tl/generate/scheme/tonlib_api.tl
index a3d33b9dd2..07a2f32c14 100644
--- a/submodules/ton/tonlib-src/tl/generate/scheme/tonlib_api.tl
+++ b/submodules/ton/tonlib-src/tl/generate/scheme/tonlib_api.tl
@@ -29,6 +29,8 @@ bip39Hints words:vector = Bip39Hints;
accountAddress account_address:string = AccountAddress;
+unpackedAccountAddress workchain_id:int32 bounceable:Bool testnet:Bool addr:bytes = UnpackedAccountAddress;
+
internal.transactionId lt:int64 hash:bytes = internal.TransactionId;
raw.initialAccountState code:bytes data:bytes = raw.InitialAccountState;
@@ -96,6 +98,9 @@ importPemKey local_password:secureBytes key_password:secureBytes exported_key:ex
importEncryptedKey local_password:secureBytes key_password:secureBytes exported_encrypted_key:exportedEncryptedKey = Key;
changeLocalPassword input_key:inputKey new_local_password:secureBytes = Key;
+unpackAccountAddress account_address:string = UnpackedAccountAddress;
+packAccountAddress account_address:unpackedAccountAddress = AccountAddress;
+
getBip39Hints prefix:string = Bip39Hints;
//raw.init initial_account_state:raw.initialAccountState = Ok;
diff --git a/submodules/ton/tonlib-src/tl/generate/scheme/tonlib_api.tlo b/submodules/ton/tonlib-src/tl/generate/scheme/tonlib_api.tlo
index 7909f15e64..b77565e03e 100644
Binary files a/submodules/ton/tonlib-src/tl/generate/scheme/tonlib_api.tlo and b/submodules/ton/tonlib-src/tl/generate/scheme/tonlib_api.tlo differ
diff --git a/submodules/ton/tonlib-src/tonlib/test/offline.cpp b/submodules/ton/tonlib-src/tonlib/test/offline.cpp
index 5a67b42183..63a52fae39 100644
--- a/submodules/ton/tonlib-src/tonlib/test/offline.cpp
+++ b/submodules/ton/tonlib-src/tonlib/test/offline.cpp
@@ -384,6 +384,26 @@ TEST(Tonlib, Keys) {
CHECK(decrypted_key.private_key.as_octet_string() == other_decrypted_key.private_key.as_octet_string());
}
+TEST(Tonlib, ParseAddres) {
+ using tonlib_api::make_object;
+ Client client;
+
+ // init
+ sync_send(client, make_object(make_object(nullptr, "."))).ensure();
+
+ sync_send(client, make_object("hello")).ensure_error();
+ auto addr =
+ sync_send(client,
+ make_object("Ef9Tj6fMJP-OqhAdhKXxq36DL-HYSzCc3-9O6UNzqsgPfYFX"))
+ .move_as_ok();
+ ASSERT_EQ(-1, addr->workchain_id_);
+ ASSERT_EQ(true, addr->bounceable_);
+ ASSERT_EQ(false, addr->testnet_);
+
+ auto addr_str = sync_send(client, make_object(std::move(addr))).move_as_ok();
+ ASSERT_EQ("Ef9Tj6fMJP-OqhAdhKXxq36DL-HYSzCc3-9O6UNzqsgPfYFX", addr_str->account_address_);
+}
+
TEST(Tonlib, KeysApi) {
using tonlib_api::make_object;
Client client;
diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/.TonlibClient.cpp.swp b/submodules/ton/tonlib-src/tonlib/tonlib/.TonlibClient.cpp.swp
new file mode 100644
index 0000000000..a3dd3f30b9
Binary files /dev/null and b/submodules/ton/tonlib-src/tonlib/tonlib/.TonlibClient.cpp.swp differ
diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/.GenericAccount.cpp.swp b/submodules/ton/tonlib-src/tonlib/tonlib/.Wallet.cpp.swp
similarity index 52%
rename from submodules/ton/tonlib-src/tonlib/tonlib/.GenericAccount.cpp.swp
rename to submodules/ton/tonlib-src/tonlib/tonlib/.Wallet.cpp.swp
index 09dd290f1d..61ab3cfd77 100644
Binary files a/submodules/ton/tonlib-src/tonlib/tonlib/.GenericAccount.cpp.swp and b/submodules/ton/tonlib-src/tonlib/tonlib/.Wallet.cpp.swp differ
diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/LastBlock.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/LastBlock.cpp
index e8f8caab82..7c4cda5dd3 100644
--- a/submodules/ton/tonlib-src/tonlib/tonlib/LastBlock.cpp
+++ b/submodules/ton/tonlib-src/tonlib/tonlib/LastBlock.cpp
@@ -134,7 +134,7 @@ td::Result> LastBlock::process_block_pro
if (is_changed) {
callback_->on_state_changed(state_);
}
- return chain;
+ return std::move(chain);
}
void LastBlock::on_block_proof(
diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.cpp
index df43fdd4f3..d0a9cba7d9 100644
--- a/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.cpp
+++ b/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.cpp
@@ -425,6 +425,8 @@ bool TonlibClient::is_static_request(td::int32 id) {
case tonlib_api::testWallet_getAccountAddress::ID:
case tonlib_api::wallet_getAccountAddress::ID:
case tonlib_api::testGiver_getAccountAddress::ID:
+ case tonlib_api::packAccountAddress::ID:
+ case tonlib_api::unpackAccountAddress::ID:
case tonlib_api::getBip39Hints::ID:
case tonlib_api::setLogStream::ID:
case tonlib_api::getLogStream::ID:
@@ -504,6 +506,34 @@ tonlib_api::object_ptr TonlibClient::do_static_request(
return tonlib_api::make_object(TestGiver::address().rserialize(true));
}
+tonlib_api::object_ptr TonlibClient::do_static_request(
+ const tonlib_api::unpackAccountAddress& request) {
+ auto r_account_address = block::StdAddress::parse(request.account_address_);
+ if (r_account_address.is_error()) {
+ return status_to_tonlib_api(r_account_address.move_as_error());
+ }
+ auto account_address = r_account_address.move_as_ok();
+ return tonlib_api::make_object(
+ account_address.workchain, account_address.bounceable, account_address.testnet,
+ account_address.addr.as_slice().str());
+}
+
+tonlib_api::object_ptr TonlibClient::do_static_request(
+ const tonlib_api::packAccountAddress& request) {
+ if (!request.account_address_) {
+ return status_to_tonlib_api(td::Status::Error(400, "Field account_address must not be empty"));
+ }
+ if (request.account_address_->addr_.size() != 32) {
+ return status_to_tonlib_api(td::Status::Error(400, "Field account_address.addr must not be exactly 32 bytes"));
+ }
+ block::StdAddress addr;
+ addr.workchain = request.account_address_->workchain_id_;
+ addr.bounceable = request.account_address_->bounceable_;
+ addr.testnet = request.account_address_->testnet_;
+ addr.addr.as_slice().copy_from(request.account_address_->addr_);
+ return tonlib_api::make_object(addr.rserialize(true));
+}
+
tonlib_api::object_ptr TonlibClient::do_static_request(tonlib_api::getBip39Hints& request) {
return tonlib_api::make_object(
td::transform(Mnemonic::word_hints(td::trim(td::to_lower_inplace(request.prefix_))), [](auto& x) { return x; }));
@@ -925,7 +955,7 @@ td::Status TonlibClient::do_request(const tonlib_api::testWallet_sendGrams& requ
if (!request.private_key_) {
return td::Status::Error(400, "Field private_key must not be empty");
}
- if (request.message_.size() > 124) {
+ if (request.message_.size() > 70) {
return td::Status::Error(400, "Message is too long");
}
TRY_RESULT(account_address, block::StdAddress::parse(request.destination_->account_address_));
@@ -1003,7 +1033,7 @@ td::Status TonlibClient::do_request(const tonlib_api::wallet_sendGrams& request,
if (!request.private_key_) {
return td::Status::Error(400, "Field private_key must not be empty");
}
- if (request.message_.size() > 124) {
+ if (request.message_.size() > 70) {
return td::Status::Error(400, "Message is too long");
}
TRY_RESULT(valid_until, td::narrow_cast_safe(request.valid_until_));
@@ -1062,7 +1092,7 @@ td::Status TonlibClient::do_request(const tonlib_api::testGiver_sendGrams& reque
if (!request.destination_) {
return td::Status::Error(400, "Field destination must not be empty");
}
- if (request.message_.size() > 124) {
+ if (request.message_.size() > 70) {
return td::Status::Error(400, "Message is too long");
}
TRY_RESULT(account_address, block::StdAddress::parse(request.destination_->account_address_));
@@ -1219,12 +1249,16 @@ class GenericSendGrams : public TonlibQueryActor {
auto key = td::Ed25519::PublicKey(td::SecureString(key_bytes.key));
if (GenericAccount::get_address(0 /*zerochain*/, TestWallet::get_init_state(key)).addr == source_address_.addr) {
+ auto state = ton::move_tl_object_as(source_state_);
source_state_ = tonlib_api::make_object(
- tonlib_api::make_object(-1, 0, nullptr, 0));
+ tonlib_api::make_object(-1, 0, nullptr,
+ state->account_state_->sync_utime_));
} else if (GenericAccount::get_address(0 /*zerochain*/, Wallet::get_init_state(key)).addr ==
source_address_.addr) {
+ auto state = ton::move_tl_object_as(source_state_);
source_state_ = tonlib_api::make_object(
- tonlib_api::make_object(-1, 0, nullptr, 0));
+ tonlib_api::make_object(-1, 0, nullptr,
+ state->account_state_->sync_utime_));
}
}
return do_loop();
diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.h b/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.h
index 0130e8254e..9e7ecdafea 100644
--- a/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.h
+++ b/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.h
@@ -101,6 +101,8 @@ class TonlibClient : public td::actor::Actor {
static object_ptr do_static_request(const tonlib_api::testWallet_getAccountAddress& request);
static object_ptr do_static_request(const tonlib_api::wallet_getAccountAddress& request);
static object_ptr do_static_request(const tonlib_api::testGiver_getAccountAddress& request);
+ static object_ptr do_static_request(const tonlib_api::packAccountAddress& request);
+ static object_ptr do_static_request(const tonlib_api::unpackAccountAddress& request);
static object_ptr do_static_request(tonlib_api::getBip39Hints& request);
static object_ptr do_static_request(tonlib_api::setLogStream& request);
diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/tonlib-cli.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/tonlib-cli.cpp
index 55a1023de1..ce8d5f481f 100644
--- a/submodules/ton/tonlib-src/tonlib/tonlib/tonlib-cli.cpp
+++ b/submodules/ton/tonlib-src/tonlib/tonlib/tonlib-cli.cpp
@@ -182,6 +182,7 @@ class TonlibCli : public td::actor::Actor {
td::TerminalIO::out() << "help - show this help\n";
td::TerminalIO::out() << "genkey - generate new secret key\n";
td::TerminalIO::out() << "keys - show all stored keys\n";
+ td::TerminalIO::out() << "unpackaddress - validate and parse address\n";
td::TerminalIO::out() << "importkey - import key\n";
td::TerminalIO::out() << "exportkey [] - export key\n";
td::TerminalIO::out() << "setconfig [] [] [] - set lite server config\n";
@@ -237,6 +238,8 @@ class TonlibCli : public td::actor::Actor {
transfer(from, to, grams, message, cmd == "transferf");
} else if (cmd == "hint") {
get_hints(parser.read_word());
+ } else if (cmd == "unpackaddress") {
+ unpack_address(parser.read_word());
}
}
@@ -300,6 +303,17 @@ class TonlibCli : public td::actor::Actor {
};
}
+ void unpack_address(td::Slice addr) {
+ send_query(tonlib_api::make_object(addr.str()),
+ [addr = addr.str()](auto r_parsed_addr) mutable {
+ if (r_parsed_addr.is_error()) {
+ LOG(ERROR) << "Failed to parse address: " << r_parsed_addr.error();
+ return;
+ }
+ LOG(ERROR) << to_string(r_parsed_addr.ok());
+ });
+ }
+
void generate_key(td::SecureString entropy = {}) {
if (entropy.size() < 20) {
td::TerminalIO::out() << "Enter some entropy";
@@ -324,6 +338,7 @@ class TonlibCli : public td::actor::Actor {
[this, password = std::move(password)](auto r_key) mutable {
if (r_key.is_error()) {
LOG(ERROR) << "Failed to create new key: " << r_key.error();
+ return;
}
auto key = r_key.move_as_ok();
LOG(ERROR) << to_string(key);
@@ -368,6 +383,7 @@ class TonlibCli : public td::actor::Actor {
auto r_secret = td::base64_decode_secure(secret_b64);
if (r_secret.is_error()) {
LOG(ERROR) << "Invalid secret database at " << key_db_path();
+ return;
}
KeyInfo info;
]